@soul-refiner/design-system 0.1.25 → 0.1.27

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (28) hide show
  1. package/package.json +7 -6
  2. package/src/components/actions/dropdown/dropdown.tsx +14 -11
  3. package/src/components/atoms/typography/typography.tsx +1 -1
  4. package/src/components/editor/constants.ts +181 -0
  5. package/src/components/editor/editor.tsx +95 -0
  6. package/src/components/editor/index.ts +2 -0
  7. package/src/components/editor/navbar/alignment_dropdown.tsx +142 -0
  8. package/src/components/editor/navbar/button_modal.tsx +146 -0
  9. package/src/components/editor/navbar/index.ts +2 -0
  10. package/src/components/editor/navbar/navbar.tsx +350 -0
  11. package/src/components/editor/navbar/style_dropdown.tsx +107 -0
  12. package/src/components/editor/plate.ts +37 -0
  13. package/src/components/editor/plugins/blockquote.tsx +25 -0
  14. package/src/components/editor/plugins/buttons.tsx +140 -0
  15. package/src/components/editor/plugins/exitBreak.ts +39 -0
  16. package/src/components/editor/plugins/image.tsx +80 -0
  17. package/src/components/editor/plugins/index.ts +165 -0
  18. package/src/components/editor/plugins/link.tsx +144 -0
  19. package/src/components/editor/plugins/list.tsx +34 -0
  20. package/src/components/editor/plugins/resetBlockType.ts +29 -0
  21. package/src/components/editor/plugins/selectOnBackspace.ts +7 -0
  22. package/src/components/editor/plugins/softBreak.ts +19 -0
  23. package/src/components/editor/plugins/text.tsx +142 -0
  24. package/src/components/index.ts +1 -0
  25. package/src/components/input/radio/radio.tsx +2 -2
  26. package/src/components/surfaces/modal/modal.tsx +6 -2
  27. package/src/icons/text/align_justified.tsx +1 -1
  28. package/tsconfig.json +1 -1
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@soul-refiner/design-system",
3
- "version": "0.1.25",
3
+ "version": "0.1.27",
4
4
  "main": "src/index.ts",
5
5
  "license": "MIT",
6
6
  "publishConfig": {
@@ -47,7 +47,7 @@
47
47
  },
48
48
  "dependencies": {
49
49
  "@emoji-mart/react": "^1.1.1",
50
- "@udecode/plate": "^21.1.2",
50
+ "@udecode/plate": "^22.0.1",
51
51
  "emoji-mart": "^5.5.2",
52
52
  "react": "^18.2.0",
53
53
  "react-dnd": "^16.0.1",
@@ -59,23 +59,24 @@
59
59
  "slate": "^0.94.1",
60
60
  "slate-history": "^0.93.0",
61
61
  "slate-hyperscript": "^0.77.0",
62
- "slate-react": "^0.94.0",
62
+ "slate-react": "^0.97.1",
63
63
  "styled-components": "^6.0.0-rc.3"
64
64
  },
65
65
  "peerDependencies": {
66
66
  "@emoji-mart/react": "^1.1.1",
67
- "@udecode/plate": "^21.1.2",
67
+ "@udecode/plate": "^22.0.1",
68
68
  "emoji-mart": "^5.5.2",
69
69
  "react": "^18.2.0",
70
70
  "react-dnd": "^16.0.1",
71
71
  "react-dnd-html5-backend": "^16.0.1",
72
72
  "react-dom": "^18.2.0",
73
73
  "react-is": "^18.2.0",
74
+ "react-tooltip": "^5.18.0",
74
75
  "scheduler": "^0.23.0",
75
76
  "slate": "^0.94.1",
76
77
  "slate-history": "^0.93.0",
77
78
  "slate-hyperscript": "^0.77.0",
78
- "slate-react": "^0.94.0",
79
- "styled-components": "^6.0.0-rc.1"
79
+ "slate-react": "^0.97.1",
80
+ "styled-components": "^6.0.0-rc.3"
80
81
  }
81
82
  }
@@ -180,7 +180,8 @@ const Dropdown = ({
180
180
  >
181
181
  {React.cloneElement(
182
182
  trigger,
183
- typeof trigger.type === 'string'
183
+ typeof trigger.type === 'string' ||
184
+ (trigger.type as any)?.displayName !== 'Button'
184
185
  ? { onClick: handleOpen }
185
186
  : { isDropdownOpen: open, onClick: handleOpen }
186
187
  )}
@@ -254,7 +255,7 @@ export interface DropdownOptionProps {
254
255
  color?: string;
255
256
  disabled?: boolean;
256
257
  icon?: React.ReactElement;
257
- label: React.ReactNode;
258
+ label?: React.ReactNode;
258
259
  onClick?: (event: React.MouseEvent<HTMLDivElement>) => void | undefined;
259
260
  selected: boolean;
260
261
  sublabel?: string;
@@ -285,15 +286,17 @@ const Option = ({
285
286
  >
286
287
  {checkbox ? <Checkbox selected={selected} /> : icon}
287
288
  <Box $dir="column" $display="flex">
288
- <P
289
- $color="grey-4"
290
- $fontSize={14}
291
- $lineHeight={20}
292
- $mediumBold
293
- $textClampLines={1}
294
- >
295
- {label}
296
- </P>
289
+ {label && (
290
+ <P
291
+ $color="grey-4"
292
+ $fontSize={14}
293
+ $lineHeight={20}
294
+ $mediumBold
295
+ $textClampLines={1}
296
+ >
297
+ {label}
298
+ </P>
299
+ )}
297
300
  {sublabel && (
298
301
  <P
299
302
  $color="grey-4"
@@ -42,6 +42,6 @@ export const Typography = styled.p<TypographyProps>`
42
42
  ${Styles.color}
43
43
  ${Styles.weight}
44
44
  ${Styles.typography}
45
- ${Styles.textClamp}
46
45
  ${Styles.styleable}
46
+ ${({ $textClampLines }) => ($textClampLines ? Styles.textClamp : '')}
47
47
  `;
@@ -0,0 +1,181 @@
1
+ export {
2
+ ELEMENT_BLOCKQUOTE,
3
+ ELEMENT_CODE_LINE,
4
+ ELEMENT_CODE_SYNTAX,
5
+ ELEMENT_DEFAULT,
6
+ ELEMENT_H1,
7
+ ELEMENT_H2,
8
+ ELEMENT_H3,
9
+ ELEMENT_H4,
10
+ ELEMENT_H5,
11
+ ELEMENT_H6,
12
+ ELEMENT_HR,
13
+ ELEMENT_IMAGE,
14
+ ELEMENT_LI,
15
+ ELEMENT_LIC,
16
+ ELEMENT_LINK,
17
+ ELEMENT_MEDIA,
18
+ ELEMENT_MEDIA_EMBED,
19
+ ELEMENT_MENTION,
20
+ ELEMENT_MENTION_INPUT,
21
+ ELEMENT_OL,
22
+ ELEMENT_PARAGRAPH,
23
+ ELEMENT_TABLE,
24
+ ELEMENT_TD,
25
+ ELEMENT_TH,
26
+ ELEMENT_TODO_LI,
27
+ ELEMENT_TR,
28
+ ELEMENT_UL,
29
+ MARK_BG_COLOR,
30
+ MARK_BOLD,
31
+ MARK_CODE,
32
+ MARK_COLOR,
33
+ MARK_FONT_FAMILY,
34
+ MARK_FONT_SIZE,
35
+ MARK_FONT_WEIGHT,
36
+ MARK_HIGHLIGHT,
37
+ MARK_ITALIC,
38
+ MARK_KBD,
39
+ MARK_SEARCH_HIGHLIGHT,
40
+ MARK_STRIKETHROUGH,
41
+ MARK_SUBSCRIPT,
42
+ MARK_SUPERSCRIPT,
43
+ MARK_UNDERLINE,
44
+ } from '@udecode/plate';
45
+
46
+ export const ELEMENT_AUDIO = 'audio';
47
+ export const ELEMENT_BIBLE_QUOTE = 'bible-quote';
48
+ export const ELEMENT_BUTTON = 'button';
49
+ export const ELEMENT_EXAMPLE = 'example';
50
+ export const ELEMENT_FOOTNOTE = 'footnote';
51
+ export const ELEMENT_PAYWALL = 'paywall';
52
+ export const ELEMENT_POLL = 'poll';
53
+ export const ELEMENT_QA = 'q-n-a';
54
+ export const ELEMENT_RECIPE = 'recipe';
55
+ export const ELEMENT_VIDEO = 'video';
56
+
57
+ // export const BUTTON_COMMENT = 'button-comment';
58
+ // export const BUTTON_GIFT_SUBSCRIPTION = 'button-gift-subscription';
59
+ // export const BUTTON_SHARE = 'button-share';
60
+ // export const BUTTON_SHARE_PAGE = 'button-share-page';
61
+ // export const BUTTON_SIGNUP = 'signup';
62
+ // export const BUTTON_SPECIAL_OFFER = 'button-special-offer';
63
+ export const BUTTON_LINK = 'button-link';
64
+ export const BUTTON_SUBSCRIBE = 'button-subscribe';
65
+
66
+ export const COLORS = [
67
+ 'var(--color-turquoise-5)',
68
+ 'var(--color-green-5)',
69
+ 'var(--color-blue-5)',
70
+ 'var(--color-purple-5)',
71
+ 'var(--color-yellow-5)',
72
+ 'var(--color-orange-5)',
73
+ 'var(--color-red-5)',
74
+ ];
75
+
76
+ export const PLACEHOLDER = 'This is a placeholder';
77
+
78
+ export const DEFAULT_CONTENT = [
79
+ {
80
+ type: 'h1',
81
+ children: [
82
+ {
83
+ text: 'Module 1: The Warrior Identity',
84
+ bold: true,
85
+ },
86
+ ],
87
+ },
88
+ {
89
+ type: 'p',
90
+ children: [
91
+ {
92
+ text: 'Welcome to Warpath. You’re about to embark on a journey towards lifelong healing, freedom and victory. This is a season of training. It’s sanctification on steroids, not for the faint-hearted, but for those who truly desire to live the rest of their lives for Jesus. No reserves, no retreats, no regrets.',
93
+ },
94
+ {
95
+ text: ' What was once your deepest, darkest secret will now become the word of your testimony that heals and liberates others.',
96
+ },
97
+ ],
98
+ },
99
+ {
100
+ type: 'p',
101
+ children: [
102
+ {
103
+ text: 'In this new season, God is calling you up. He’s calling you to a higher level, a place where you’re no longer part of the problem but are becoming a part of the solution.',
104
+ },
105
+ {
106
+ text: '',
107
+ },
108
+ ],
109
+ },
110
+ {
111
+ type: 'blockquote',
112
+ children: [
113
+ {
114
+ text: '"Warpath isn’t about just winning for you; that’s the beginning. Warpath is about you taking the battle and winning for others so they can have their families, and their marriages, and their destinies." \n— ',
115
+ },
116
+ {
117
+ text: 'Dr. Doug Weiss',
118
+ italic: true,
119
+ },
120
+ ],
121
+ },
122
+ // {
123
+ // type: 'hr',
124
+ // children: [
125
+ // {
126
+ // text: '',
127
+ // },
128
+ // ],
129
+ // },
130
+ {
131
+ type: 'h3',
132
+ align: 'center',
133
+ children: [
134
+ {
135
+ text: 'THE WARRIOR IDENTITY',
136
+ bold: true,
137
+ },
138
+ ],
139
+ },
140
+ // {
141
+ // type: 'hr',
142
+ // children: [
143
+ // {
144
+ // text: '',
145
+ // },
146
+ // ],
147
+ // },
148
+ {
149
+ type: 'img',
150
+ url: 'https://source.unsplash.com/1600x900/?christian',
151
+ children: [
152
+ {
153
+ text: '',
154
+ },
155
+ ],
156
+ },
157
+ {
158
+ type: 'p',
159
+ children: [
160
+ {
161
+ text: 'Identity: You will have to grasp your true identity in Christ. You cannot look at this as a “what”, but instead about a “who”. We must become more like Christ, because He is a warrior.',
162
+ },
163
+ ],
164
+ },
165
+ {
166
+ type: 'p',
167
+ children: [
168
+ {
169
+ text: 'A different DNA: As a warrior, your spiritual genetic code will be different from those who haven’t tasted the victory and grace you’ve experienced from this battle. You’ve experienced truth as a person: Jesus; and it has forever changed you. You’ve been set apart as a “fighting man”, no longer a civilian idly consumed by the cares of this world, but a warrior who’s passionate about the Kingdom and craving some sweet revenge.',
170
+ },
171
+ ],
172
+ },
173
+ {
174
+ type: 'p',
175
+ children: [
176
+ {
177
+ text: '',
178
+ },
179
+ ],
180
+ },
181
+ ];
@@ -0,0 +1,95 @@
1
+ import React from 'react';
2
+ import styled from 'styled-components';
3
+ import { createPlugins, Plate, PlateProvider, TElement } from '@udecode/plate';
4
+ import { DEFAULT_CONTENT, PLACEHOLDER } from './constants';
5
+ import { EditorBar } from './navbar';
6
+ import { plateUI } from './plate';
7
+ import { blocks, inline, marks, utils } from './plugins';
8
+
9
+ const plugins = createPlugins([...blocks, ...inline, ...marks, ...utils], {
10
+ components: plateUI,
11
+ });
12
+
13
+ export interface EditorProps {
14
+ communityName: string;
15
+ editable: boolean;
16
+ handleUploadImage: (dataURL: File) => Promise<string>;
17
+ onChange: (newNodes: TElement[]) => void;
18
+ }
19
+
20
+ export const Editor = ({
21
+ editable,
22
+ handleUploadImage,
23
+ onChange,
24
+ }: EditorProps) => {
25
+ return (
26
+ <PlateProvider
27
+ id="main"
28
+ initialValue={DEFAULT_CONTENT}
29
+ onChange={onChange}
30
+ plugins={plugins}
31
+ >
32
+ <Wrapper>
33
+ <EditorBar handleUploadImage={handleUploadImage} />
34
+ <Plate
35
+ id="main"
36
+ editableProps={{
37
+ readOnly: !editable,
38
+ spellCheck: true,
39
+ autoFocus: true,
40
+ placeholder: PLACEHOLDER,
41
+ }}
42
+ />
43
+ </Wrapper>
44
+ </PlateProvider>
45
+ );
46
+ };
47
+
48
+ const Wrapper = styled.div`
49
+ * {
50
+ font-family: Inter;
51
+ outline: none;
52
+ }
53
+
54
+ .slate-bold {
55
+ font-weight: 700;
56
+ }
57
+
58
+ .slate-italic {
59
+ font-style: italic;
60
+ }
61
+
62
+ .slate-strikethrough {
63
+ text-decoration: line-through;
64
+ }
65
+
66
+ .slate-underline {
67
+ text-decoration: underline;
68
+ }
69
+
70
+ .slate-code {
71
+ & > * {
72
+ font-family: 'Roboto Mono';
73
+ & > * {
74
+ font-family: 'Roboto Mono';
75
+ & > * {
76
+ font-family: 'Roboto Mono';
77
+ }
78
+ }
79
+ }
80
+
81
+ background-color: var(--color-grey-9);
82
+ padding: 0.4em 0.4em;
83
+ font-size: 0.8em;
84
+ line-height: 0.8em;
85
+ }
86
+
87
+ & > [data-slate-editor='true'] > * {
88
+ margin: 24px 0px;
89
+ }
90
+
91
+ position: relative;
92
+ padding: 24px;
93
+ max-width: 1200px;
94
+ margin: 98px auto 0px;
95
+ `;
@@ -0,0 +1,2 @@
1
+ export { Editor } from './editor';
2
+ export type { EditorProps } from './editor';
@@ -0,0 +1,142 @@
1
+ import React from 'react';
2
+ import {
3
+ Alignment,
4
+ // isCollapsed,
5
+ PlateEditor,
6
+ setAlign,
7
+ } from '@udecode/plate';
8
+ import {
9
+ useAlignDropdownMenu,
10
+ useAlignDropdownMenuState,
11
+ } from '@udecode/plate-alignment';
12
+ import { Dropdown } from 'components';
13
+ import {
14
+ PlayerListPlay,
15
+ AlignCenter,
16
+ AlignJustified,
17
+ AlignLeft,
18
+ AlignRight,
19
+ } from 'icons';
20
+ import { MenuButton } from './navbar';
21
+
22
+ export interface AlignmentDropdownProps {
23
+ editorRef: PlateEditor;
24
+ }
25
+
26
+ const items = [
27
+ {
28
+ value: 'left',
29
+ icon: AlignLeft,
30
+ },
31
+ {
32
+ value: 'center',
33
+ icon: AlignCenter,
34
+ },
35
+ {
36
+ value: 'right',
37
+ icon: AlignRight,
38
+ },
39
+ {
40
+ value: 'justify',
41
+ icon: AlignJustified,
42
+ },
43
+ ];
44
+
45
+ export const AlignmentDropdown = ({ editorRef }: AlignmentDropdownProps) => {
46
+ const alignState = useAlignDropdownMenuState();
47
+ const { radioGroupProps } = useAlignDropdownMenu(alignState);
48
+
49
+ const current = radioGroupProps.value;
50
+
51
+ const IconValue =
52
+ items.find((item) => item.value === radioGroupProps.value)?.icon ??
53
+ PlayerListPlay;
54
+
55
+ const handleAlign = (event: React.FormEvent) => {
56
+ const value = (event.target as HTMLElement)?.getAttribute(
57
+ 'data-value'
58
+ ) as Alignment | null;
59
+
60
+ if (!value) return;
61
+
62
+ setAlign(editorRef, {
63
+ value: value,
64
+ });
65
+ };
66
+
67
+ return (
68
+ <Dropdown
69
+ onChange={handleAlign}
70
+ offset={[0, 0]}
71
+ options={[
72
+ {
73
+ icon: (
74
+ <MenuButton $active={current === 'left'}>
75
+ <AlignLeft size={24} color="grey-5" />
76
+ </MenuButton>
77
+ ),
78
+ sx: 'gap: 0px; padding: 4px;',
79
+ value: 'left',
80
+ },
81
+ {
82
+ icon: (
83
+ <MenuButton $active={current === 'center'}>
84
+ <AlignCenter size={24} color="grey-5" />
85
+ </MenuButton>
86
+ ),
87
+ sx: 'gap: 0px; padding: 4px;',
88
+ value: 'center',
89
+ },
90
+ {
91
+ icon: (
92
+ <MenuButton $active={current === 'right'}>
93
+ <AlignRight size={24} color="grey-5" />
94
+ </MenuButton>
95
+ ),
96
+ sx: 'gap: 0px; padding: 4px;',
97
+ value: 'right',
98
+ },
99
+ {
100
+ icon: (
101
+ <MenuButton $active={current === 'justify'}>
102
+ <AlignJustified size={24} color="grey-5" />
103
+ </MenuButton>
104
+ ),
105
+ sx: 'gap: 0px; padding: 4px;',
106
+ value: 'justify',
107
+ },
108
+ ]}
109
+ maintainState={false}
110
+ trigger={<IconValue size={24} color="grey-5" />}
111
+ />
112
+ );
113
+ };
114
+
115
+ // <AlignToolbarButton
116
+ // as="div"
117
+ // active={alignment === 'left' ? true : undefined}
118
+ // data-value="left"
119
+ // value="left"
120
+ // icon={<AlignLeft size={24} color="grey-5" />}
121
+ // />
122
+ // <AlignToolbarButton
123
+ // as="div"
124
+ // active={alignment === 'center' ? true : undefined}
125
+ // data-value="center"
126
+ // value="center"
127
+ // icon={<AlignCenter size={24} color="grey-5" />}
128
+ // />
129
+ // <AlignToolbarButton
130
+ // as="div"
131
+ // active={alignment === 'right' ? true : undefined}
132
+ // data-value="right"
133
+ // value="right"
134
+ // icon={<AlignRight size={24} color="grey-5" />}
135
+ // />
136
+ // <AlignToolbarButton
137
+ // as="div"
138
+ // active={alignment === 'justify' ? true : undefined}
139
+ // data-value="justify"
140
+ // value="justify"
141
+ // icon={<AlignJustified size={24} color="grey-5" />}
142
+ // />
@@ -0,0 +1,146 @@
1
+ import React from 'react';
2
+ import styled from 'styled-components';
3
+ import { Box, Button, H, Modal, P, Radio } from 'components';
4
+ import { Close, InsertButton } from 'icons';
5
+ import { MenuButton } from './navbar';
6
+ import { BUTTON_LINK, BUTTON_SUBSCRIBE } from '../constants';
7
+
8
+ interface ButtonModalProps {
9
+ onButtonInsert: (type: string) => void;
10
+ }
11
+
12
+ export const ButtonModal = ({ onButtonInsert }: ButtonModalProps) => {
13
+ const [buttonType, setButtonType] = React.useState<string | undefined>();
14
+
15
+ const handleButtonInsert = () => {
16
+ buttonType && onButtonInsert(buttonType);
17
+ setButtonType(undefined);
18
+ };
19
+
20
+ return (
21
+ <Modal>
22
+ <Modal.Trigger>
23
+ <MenuButton>
24
+ <InsertButton size={24} color="grey-5" />
25
+ </MenuButton>
26
+ </Modal.Trigger>
27
+ <Modal.Content sx="border-radius: 16px; max-width: 782px; width: 100%; margin: 24px; padding: 0px;">
28
+ <Box $dir="column">
29
+ <Box
30
+ $align="center"
31
+ $justify="space-between"
32
+ sx="padding: 24px; box-shadow: var(--elevation-2);"
33
+ >
34
+ <Box $align="center" $gap={32}>
35
+ <IconWrapper>
36
+ <InsertButton size={24} color="hue-blue-1" />
37
+ </IconWrapper>
38
+ <H $bold $color="hue-blue-1" $fontSize={20} $lineHeight={28}>
39
+ Insert Button
40
+ </H>
41
+ </Box>
42
+ <Close
43
+ size={24}
44
+ sx="&:hover { cursor: pointer; border-radius: 50%; background-color: var(--color-grey-9); }"
45
+ />
46
+ </Box>
47
+ <Box $dir="column" $gap={24} sx="padding: 24px 48px 24px 24px;">
48
+ <ButtonItem
49
+ active={buttonType === BUTTON_SUBSCRIBE}
50
+ description="A button encouraging the reader to purchase a paid subscription to your community"
51
+ onClick={() => setButtonType(BUTTON_SUBSCRIBE)}
52
+ title="Subscribe Now"
53
+ >
54
+ <Button size="small" sx="width: 130px;">
55
+ Subscribe
56
+ </Button>
57
+ </ButtonItem>
58
+ <ButtonItem
59
+ active={buttonType === BUTTON_LINK}
60
+ description="A button that links to a URL"
61
+ onClick={() => setButtonType(BUTTON_LINK)}
62
+ title="Link Button"
63
+ >
64
+ <Button size="small" sx="width: 130px;">
65
+ Link
66
+ </Button>
67
+ </ButtonItem>
68
+ </Box>
69
+ <Box
70
+ $padding={24}
71
+ $gap={16}
72
+ sx="padding: 24px; background-color: var(--color-white); border-top: 1px solid var(--color-grey-8);"
73
+ >
74
+ <Modal.Dismiss>
75
+ <Button
76
+ size="small"
77
+ sx="flex: 1;"
78
+ type="outlined"
79
+ onClick={() => setButtonType(undefined)}
80
+ >
81
+ Cancel
82
+ </Button>
83
+ </Modal.Dismiss>
84
+ <Modal.Dismiss>
85
+ <Button size="small" sx="flex: 1;" onClick={handleButtonInsert}>
86
+ Confirm
87
+ </Button>
88
+ </Modal.Dismiss>
89
+ </Box>
90
+ </Box>
91
+ </Modal.Content>
92
+ </Modal>
93
+ );
94
+ };
95
+
96
+ const IconWrapper = styled.div`
97
+ height: 48px;
98
+ width: 48px;
99
+ box-sizing: border-box;
100
+ padding: 12px;
101
+ border-radius: 8px;
102
+ background-color: var(--color-hue-blue-2);
103
+ `;
104
+
105
+ interface ButtonItemProps extends React.PropsWithChildren {
106
+ active?: boolean;
107
+ description: string;
108
+ onClick: () => void;
109
+ title: string;
110
+ }
111
+
112
+ const ButtonItem = ({
113
+ active,
114
+ children,
115
+ description,
116
+ onClick,
117
+ title,
118
+ }: ButtonItemProps) => (
119
+ <Box
120
+ $dir="column"
121
+ onClick={onClick}
122
+ sx="border-radius: 16px; box-shadow: var(--elevation-2); cursor: pointer;"
123
+ >
124
+ <Box
125
+ sx={`
126
+ padding: 24px;
127
+ background-color: var(--color-blue-10);
128
+ border-radius: 8px 8px 0px 0px;
129
+ border-bottom: 1px solid var(--color-grey-9);
130
+ `}
131
+ >
132
+ <Radio checked={!!active} sx="align-items: flex-start;" value={title} />
133
+ <Box $dir="column">
134
+ <P $semiBold>{title}</P>
135
+ <P>{description}</P>
136
+ </Box>
137
+ </Box>
138
+ <Box
139
+ $align="center"
140
+ $justify="center"
141
+ sx="border-radius: 0px 0px 8px 8px; padding: 24px;"
142
+ >
143
+ {children}
144
+ </Box>
145
+ </Box>
146
+ );
@@ -0,0 +1,2 @@
1
+ export { EditorBar } from './navbar';
2
+ export type { EditorBarProps } from './navbar';