Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion .nvmrc

This file was deleted.

1 change: 0 additions & 1 deletion .yarnrc.yml

This file was deleted.

10 changes: 5 additions & 5 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,26 +1,26 @@
FROM node:22.20-alpine3.22 as build-step
FROM oven/bun:latest as build-step

WORKDIR /app

# Env setup

COPY package.json yarn.lock .yarnrc.yml /app/
COPY package.json bun.lock /app/
COPY components-sdk/package.json /app/components-sdk/
COPY website/package.json /app/website/

RUN <<EOF
corepack enable
yarn install --immutable
bun install --immutable
EOF

COPY components-sdk /app/components-sdk
COPY website /app/website

#EXPOSE 8080
#ENTRYPOINT ["yarn"]
#ENTRYPOINT ["bun"]
#CMD ["dev", "--host", "0.0.0.0", "--port", "8080", "--strictPort"]

CMD ["yarn", "build"]
CMD ["bun", "build"]

FROM nginx
COPY --from=build-step /app/website/dist /usr/share/nginx/html
Expand Down
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,19 +11,19 @@ This monorepo contains two main packages:
First, install the dependencies of the monorepo:

```bash
yarn install
bun install
```

Build the components library:

```bash
cd components-sdk && yarn build
cd components-sdk && bun build
```

Run the development server of the website:

```bash
cd website && yarn dev
cd website && bun dev
```

Open [http://localhost:3000](http://localhost:3000) with your browser to see the result.
Expand Down
1,068 changes: 1,068 additions & 0 deletions bun.lock

Large diffs are not rendered by default.

16 changes: 8 additions & 8 deletions components-sdk/playground/App.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import { Capsule } from '../src/Capsule';
import { Component, TextDisplayComponent } from '../src/utils/componentTypes';
import { useMemo, useState } from 'react';
import { DummyStateManager } from './StateManager.impl';
import { DummyBetterInput } from './BetterInput.impl';
import { DummyEmojiPicker } from './EmojiPicker.impl';
import { DummyEmojiShow } from './EmojiShow.impl';
import { DummyColorPicker } from './ColorPicker.impl';
import {Capsule} from '../src/Capsule';
import {Component, TextDisplayComponent} from '../src/utils/componentTypes';
import {useMemo, useState} from 'react';
import {DummyStateManager} from './StateManager.impl';
import {DummyBetterInput} from './BetterInput.impl';
import {DummyEmojiPicker} from './EmojiPicker.impl';
import {DummyEmojiShow} from './EmojiShow.impl';
import {DummyColorPicker} from './ColorPicker.impl';

function App() {
const stateManager = useMemo(() => new DummyStateManager(), []);
Expand Down
46 changes: 23 additions & 23 deletions components-sdk/src/Capsule.tsx
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
import Styles from './Capsule.module.css';
import { TextDisplay } from './components/TextDisplay';
import { Thumbnail } from './components/Thumbnail';
import { MediaGallery } from './components/MediaGallery';
import { Separator } from './components/Separator';
import { Section } from './components/Section';
import { Container } from './components/Container';
import { Button } from './components/Button';
import { ActionRow } from './components/ActionRow';
import { StringSelect } from './components/StringSelect';
import { File } from './components/File';
import { CapsuleInner } from './CapsuleInner';
import { generateRandomAnimal, randomSentence, uuidv4 } from './utils/randomGen';
import { addKeyType, appendKeyType, deleteKeyType, stateKeyType, StateManager } from './polyfills/StateManager';
import {TextDisplay} from './components/TextDisplay';
import {Thumbnail} from './components/Thumbnail';
import {MediaGallery} from './components/MediaGallery';
import {Separator} from './components/Separator';
import {Section} from './components/Section';
import {Container} from './components/Container';
import {Button} from './components/Button';
import {ActionRow} from './components/ActionRow';
import {StringSelect} from './components/StringSelect';
import {File} from './components/File';
import {CapsuleInner} from './CapsuleInner';
import {generateRandomAnimal, randomSentence, uuidv4} from './utils/randomGen';
import {stateKeyType, StateManager} from './polyfills/StateManager';
import {
ActionRowComponent,
ButtonComponent,
Expand All @@ -30,12 +30,11 @@ import {
ThumbnailComponent,
} from './utils/componentTypes';

import { DragContextProvider } from './dnd/DragContext';
import { DroppableID } from './dnd/components';
import { KeyToDeleteType } from './dnd/types';
import { BoundariesProps } from './dnd/boundaries';
import { RegenerateContextProvider } from './utils/useRegenerate';
import { useMemo } from 'react';
import {DragContextProvider} from './dnd/DragContext';
import {DroppableID} from './dnd/components';
import {KeyToDeleteType} from './dnd/types';
import {BoundariesProps} from './dnd/boundaries';
import {RegenerateContextProvider} from './utils/useRegenerate';

const _Button = {
type: 2,
Expand Down Expand Up @@ -133,7 +132,7 @@ export const default_settings = {
Thumbnail: ThumbnailComponent,
MediaGallery: MediaGalleryComponent,
Separator: SeparatorComponent,
Container:ContainerComponent,
Container: ContainerComponent,
File: FileComponent
}

Expand Down Expand Up @@ -168,18 +167,19 @@ export const SECTIONABLE = [
ComponentType.TEXT_DISPLAY
]

export function Capsule(props : {
export function Capsule(props: {
stateManager: StateManager,
stateKey: stateKeyType,
state: Component[],
className?: string | null,
passProps: PassProps,
errors: Record<string, any> | null,
} & BoundariesProps ) {
} & BoundariesProps) {
const cls = props.className ? ' ' + props.className : '';

return <div className={Styles.preview + cls}>
<RegenerateContextProvider stateManager={props.stateManager}>{stateMng => <DragContextProvider stateManager={stateMng} boundaries={props.boundaries}>
<RegenerateContextProvider stateManager={props.stateManager}>{stateMng => <DragContextProvider
stateManager={stateMng} boundaries={props.boundaries}>
<CapsuleInner
state={props.state}
stateKey={props.stateKey}
Expand Down
107 changes: 57 additions & 50 deletions components-sdk/src/CapsuleButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,11 @@ import SeparatorIcon from './icons/Separator.svg';
import ButtonIcon from './icons/Button.svg';
import LinkButtonIcon from './icons/ButtonLink.svg';
import SelectIcon from './icons/Select.svg';
import { default_settings } from './Capsule';
import { CSSProperties, useRef } from 'react';
import { Component } from './utils/componentTypes';
import { useStateOpen } from './utils/useStateOpen';
import { useTranslation } from 'react-i18next';
import {default_settings} from './Capsule';
import {CSSProperties, useRef} from 'react';
import {Component} from './utils/componentTypes';
import {useStateOpen} from './utils/useStateOpen';
import {useTranslation} from 'react-i18next';

export type capsuleButtonCtx = 'main' | 'container' | 'inline' | 'button-row' | 'frame';

Expand All @@ -24,7 +24,7 @@ type props = {
interactiveDisabled: boolean
};

export function CapsuleButton({context, callback, className, style, interactiveDisabled} : props) {
export function CapsuleButton({context, callback, className, style, interactiveDisabled}: props) {
const {open, setOpen, ignoreRef} = useStateOpen(false);
const cls = className ? " " + className : "";
const btn_select = useRef<HTMLDivElement>(null);
Expand All @@ -34,61 +34,68 @@ export function CapsuleButton({context, callback, className, style, interactiveD
<div style={style} className={Styles.large_button + cls} onClick={(ev) => {
setOpen(!(btn_select.current && btn_select.current.contains(ev.target as HTMLElement)));
}} ref={ignoreRef}>
<img className={Styles.large_button_icon} src={Icons} alt=""/>
<img className={Styles.large_button_icon} src={Icons} alt=""/>
{context === "main" && t('button.add-component')}
{context === "inline" && t('button.add-inline')}
{context === "container" && t('button.add-content')}
{context === "button-row" && t('button.add-button')}

{ open && <div className={Styles.large_button_ctx} ref={btn_select}>
{['main', 'inline', 'container'].includes(context) && <div className={Styles.large_button_ctx_item} onClick={() => {
callback(default_settings.TextDisplay())
}}>
<div className={Styles.large_button_ctx_item_img}><img src={TextDisplayIcon} alt=""/></div>
<div className={Styles.large_button_ctx_item_text}>{t('components.content')}</div>
</div>}
{open && <div className={Styles.large_button_ctx} ref={btn_select}>
{['main', 'inline', 'container'].includes(context) &&
<div className={Styles.large_button_ctx_item} onClick={() => {
callback(default_settings.TextDisplay())
}}>
<div className={Styles.large_button_ctx_item_img}><img src={TextDisplayIcon} alt=""/></div>
<div className={Styles.large_button_ctx_item_text}>{t('components.content')}</div>
</div>}
{['main'].includes(context) && <div className={Styles.large_button_ctx_item} onClick={() => {
callback(default_settings.Container)
}}>
<div className={Styles.large_button_ctx_item_img}><img src={ContainerIcon} alt=""/></div>
<div className={Styles.large_button_ctx_item_text}>{t('components.container')}</div>
</div>}
{['main', 'container'].includes(context) && <div className={Styles.large_button_ctx_item} onClick={() => {
callback(default_settings.MediaGallery)
}}>
<div className={Styles.large_button_ctx_item_img}><img src={MediaGalleryIcon} alt=""/></div>
<div className={Styles.large_button_ctx_item_text}>{t('components.image')}</div>
</div>}
{['main', 'container'].includes(context) && <div className={Styles.large_button_ctx_item} onClick={() => {
callback(default_settings.File)
}}>
<div className={Styles.large_button_ctx_item_img}><img src={UploadIcon} alt=""/></div>
<div className={Styles.large_button_ctx_item_text}>{t('components.file')}</div>
</div>}
{['main', 'container'].includes(context) && <div className={Styles.large_button_ctx_item} onClick={() => {
callback(default_settings.Separator)
}}>
<div className={Styles.large_button_ctx_item_img}><img src={SeparatorIcon} alt=""/></div>
<div className={Styles.large_button_ctx_item_text}>{t('components.separator')}</div>
</div>}
{(['main', 'frame', 'container', 'button-row'].includes(context) && !interactiveDisabled) && <div className={Styles.large_button_ctx_item} onClick={() => {
callback(context==='frame' ? default_settings.Button().components[0] : default_settings.Button())
}}>
<div className={Styles.large_button_ctx_item_img}><img src={ButtonIcon} alt=""/></div>
<div className={Styles.large_button_ctx_item_text}>{t('components.button')}</div>
</div>}
{['main', 'frame', 'container', 'button-row'].includes(context) && <div className={Styles.large_button_ctx_item} onClick={() => {
callback(context==='frame' ? default_settings.LinkButton().components[0] : default_settings.LinkButton())
}}>
<div className={Styles.large_button_ctx_item_img}><img src={LinkButtonIcon} alt=""/></div>
<div className={Styles.large_button_ctx_item_text}>{t('components.button-link')}</div>
</div>}
{(['main', 'container', 'container'].includes(context) && !interactiveDisabled) && <div className={Styles.large_button_ctx_item} onClick={() => {
callback(default_settings.StringSelect())
}}>
<div className={Styles.large_button_ctx_item_img}><img src={SelectIcon} alt=""/></div>
<div className={Styles.large_button_ctx_item_text}>{t('components.select-menu')}</div>
</div>}
{['main', 'container'].includes(context) &&
<div className={Styles.large_button_ctx_item} onClick={() => {
callback(default_settings.MediaGallery)
}}>
<div className={Styles.large_button_ctx_item_img}><img src={MediaGalleryIcon} alt=""/></div>
<div className={Styles.large_button_ctx_item_text}>{t('components.image')}</div>
</div>}
{['main', 'container'].includes(context) &&
<div className={Styles.large_button_ctx_item} onClick={() => {
callback(default_settings.File)
}}>
<div className={Styles.large_button_ctx_item_img}><img src={UploadIcon} alt=""/></div>
<div className={Styles.large_button_ctx_item_text}>{t('components.file')}</div>
</div>}
{['main', 'container'].includes(context) &&
<div className={Styles.large_button_ctx_item} onClick={() => {
callback(default_settings.Separator)
}}>
<div className={Styles.large_button_ctx_item_img}><img src={SeparatorIcon} alt=""/></div>
<div className={Styles.large_button_ctx_item_text}>{t('components.separator')}</div>
</div>}
{(['main', 'frame', 'container', 'button-row'].includes(context) && !interactiveDisabled) &&
<div className={Styles.large_button_ctx_item} onClick={() => {
callback(context === 'frame' ? default_settings.Button().components[0] : default_settings.Button())
}}>
<div className={Styles.large_button_ctx_item_img}><img src={ButtonIcon} alt=""/></div>
<div className={Styles.large_button_ctx_item_text}>{t('components.button')}</div>
</div>}
{['main', 'frame', 'container', 'button-row'].includes(context) &&
<div className={Styles.large_button_ctx_item} onClick={() => {
callback(context === 'frame' ? default_settings.LinkButton().components[0] : default_settings.LinkButton())
}}>
<div className={Styles.large_button_ctx_item_img}><img src={LinkButtonIcon} alt=""/></div>
<div className={Styles.large_button_ctx_item_text}>{t('components.button-link')}</div>
</div>}
{(['main', 'container', 'container'].includes(context) && !interactiveDisabled) &&
<div className={Styles.large_button_ctx_item} onClick={() => {
callback(default_settings.StringSelect())
}}>
<div className={Styles.large_button_ctx_item_img}><img src={SelectIcon} alt=""/></div>
<div className={Styles.large_button_ctx_item_text}>{t('components.select-menu')}</div>
</div>}
{['frame'].includes(context) && <div className={Styles.large_button_ctx_item} onClick={() => {
callback(default_settings.Thumbnail)
}}>
Expand Down
Loading