@soul-refiner/design-system 0.2.18 → 0.2.19
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.
- package/dist/components/editor/index.d.ts +2 -0
- package/dist/components/editor/index.js +1 -0
- package/dist/components/editor/plugins/text.js +2 -1
- package/dist/components/editor/simple_editor/index.d.ts +2 -0
- package/dist/components/editor/simple_editor/index.js +1 -0
- package/dist/components/editor/simple_editor/navbar.d.ts +8 -0
- package/dist/components/editor/simple_editor/navbar.js +128 -0
- package/dist/components/editor/simple_editor/plugins.d.ts +1 -0
- package/dist/components/editor/simple_editor/plugins.js +90 -0
- package/dist/components/editor/simple_editor/simple_editor.d.ts +10 -0
- package/dist/components/editor/simple_editor/simple_editor.js +85 -0
- package/dist/components/input/text_input/text_input.js +1 -0
- package/package.json +1 -1
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import { createPluginFactory, PlateElement, } from '@udecode/plate';
|
|
3
|
-
import {
|
|
3
|
+
import { P } from '../../atoms/typography/paragraph';
|
|
4
|
+
import { H } from '../../atoms/typography/heading';
|
|
4
5
|
import * as Elements from '../constants';
|
|
5
6
|
export const ParagraphElement = React.forwardRef(({ children, ...props }, ref) => {
|
|
6
7
|
const textAlign = props?.style?.textAlign;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { SimpleEditor } from './simple_editor';
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
export interface EditorBarProps {
|
|
3
|
+
handleUploadImage: (dataURL: File) => Promise<string>;
|
|
4
|
+
}
|
|
5
|
+
export declare const EditorBar: ({ handleUploadImage }: EditorBarProps) => React.JSX.Element;
|
|
6
|
+
export declare const MenuButton: import("styled-components").IStyledComponent<"web", "button", {
|
|
7
|
+
$active?: boolean | undefined;
|
|
8
|
+
}, never>;
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import styled from 'styled-components';
|
|
3
|
+
import { insertImage, useLinkToolbarButton, useLinkToolbarButtonState, useListToolbarButton, useListToolbarButtonState, useMarkToolbarButton, useMarkToolbarButtonState, usePlateEditorRef, usePlateEditorState, } from '@udecode/plate';
|
|
4
|
+
import { Tooltip } from '../../';
|
|
5
|
+
import { Bold, Image, Italic, Link, ListOrdered, ListUnordered, Redo, Underline, Undo, } from '../../../icons';
|
|
6
|
+
import { ELEMENT_OL, ELEMENT_UL, MARK_BOLD, MARK_ITALIC, MARK_UNDERLINE, } from '../constants';
|
|
7
|
+
export const EditorBar = ({ handleUploadImage }) => {
|
|
8
|
+
const editorRef = usePlateEditorRef('main');
|
|
9
|
+
const stateEditor = usePlateEditorState();
|
|
10
|
+
const imageRef = React.useRef(null);
|
|
11
|
+
const boldState = useMarkToolbarButtonState({ nodeType: MARK_BOLD });
|
|
12
|
+
const { props: { pressed: currBold, onClick: handleBold }, } = useMarkToolbarButton(boldState);
|
|
13
|
+
const italicState = useMarkToolbarButtonState({ nodeType: MARK_ITALIC });
|
|
14
|
+
const { props: { pressed: currItalic, onClick: handleItalic }, } = useMarkToolbarButton(italicState);
|
|
15
|
+
const underlineState = useMarkToolbarButtonState({
|
|
16
|
+
nodeType: MARK_UNDERLINE,
|
|
17
|
+
});
|
|
18
|
+
const { props: { pressed: currUnderline, onClick: handleUnderline }, } = useMarkToolbarButton(underlineState);
|
|
19
|
+
const linkState = useLinkToolbarButtonState();
|
|
20
|
+
const { props: { pressed: currLink, onClick: handleLink }, } = useLinkToolbarButton(linkState);
|
|
21
|
+
const orderedListState = useListToolbarButtonState({ nodeType: ELEMENT_OL });
|
|
22
|
+
const { props: { pressed: currOrderedList, onClick: handleOrderedList }, } = useListToolbarButton(orderedListState);
|
|
23
|
+
const unorderedListState = useListToolbarButtonState({
|
|
24
|
+
nodeType: ELEMENT_UL,
|
|
25
|
+
});
|
|
26
|
+
const { props: { pressed: currUnorderedList, onClick: handleUnorderedList }, } = useListToolbarButton(unorderedListState);
|
|
27
|
+
const handleImageChange = async (event) => {
|
|
28
|
+
const file = event.target?.files?.[0];
|
|
29
|
+
if (!file)
|
|
30
|
+
return;
|
|
31
|
+
const imageurl = await handleUploadImage(file);
|
|
32
|
+
if (imageurl) {
|
|
33
|
+
insertImage(editorRef, imageurl);
|
|
34
|
+
}
|
|
35
|
+
};
|
|
36
|
+
const handleRedo = () => editorRef.redo();
|
|
37
|
+
const handleUndo = () => editorRef.undo();
|
|
38
|
+
return (React.createElement(Menu, { "aria-label": "editor-navigation" },
|
|
39
|
+
React.createElement(MenuSection, null,
|
|
40
|
+
React.createElement(Tooltip, { content: "Undo", place: "top" },
|
|
41
|
+
React.createElement(MenuButton, { "$active": false, onClick: handleUndo },
|
|
42
|
+
React.createElement(Undo, { size: 24, color: "grey-5" }))),
|
|
43
|
+
React.createElement(Tooltip, { content: "Redo", place: "top" },
|
|
44
|
+
React.createElement(MenuButton, { "$active": false, onClick: handleRedo },
|
|
45
|
+
React.createElement(Redo, { size: 24, color: "grey-5" })))),
|
|
46
|
+
React.createElement(Divider, null),
|
|
47
|
+
React.createElement(MenuSection, null,
|
|
48
|
+
React.createElement(Tooltip, { content: "Bold", place: "top" },
|
|
49
|
+
React.createElement(MenuButton, { "$active": currBold, onClick: handleBold },
|
|
50
|
+
React.createElement(Bold, { size: 24, color: "grey-5" }))),
|
|
51
|
+
React.createElement(Tooltip, { content: "Italic", place: "top" },
|
|
52
|
+
React.createElement(MenuButton, { "$active": currItalic, onClick: handleItalic },
|
|
53
|
+
React.createElement(Italic, { size: 24, color: "grey-5" }))),
|
|
54
|
+
React.createElement(Tooltip, { content: "Underline", place: "top" },
|
|
55
|
+
React.createElement(MenuButton, { "$active": currUnderline, onClick: handleUnderline },
|
|
56
|
+
React.createElement(Underline, { size: 24, color: "grey-5" })))),
|
|
57
|
+
React.createElement(Divider, null),
|
|
58
|
+
React.createElement(MenuSection, null,
|
|
59
|
+
React.createElement(Tooltip, { content: "Link", place: "top" },
|
|
60
|
+
React.createElement(MenuButton, { "$active": currLink, onClick: handleLink },
|
|
61
|
+
React.createElement(Link, { size: 24, color: "grey-5" }))),
|
|
62
|
+
React.createElement(Tooltip, { content: "Image", place: "top" },
|
|
63
|
+
React.createElement(MenuButton, { "$active": false, as: "label", onChange: handleImageChange },
|
|
64
|
+
React.createElement("div", { onClick: () => imageRef.current?.click() },
|
|
65
|
+
React.createElement("input", { accept: "image/*", ref: imageRef, style: { display: 'none' }, type: "file" }),
|
|
66
|
+
React.createElement(Image, { size: 24, color: "grey-5" }))))),
|
|
67
|
+
React.createElement(Divider, null),
|
|
68
|
+
React.createElement(MenuSection, null,
|
|
69
|
+
React.createElement(Tooltip, { content: "Unordered List", place: "top" },
|
|
70
|
+
React.createElement(MenuButton, { "$active": currUnorderedList, onClick: handleUnorderedList },
|
|
71
|
+
React.createElement(ListUnordered, { size: 24, color: "grey-5" }))),
|
|
72
|
+
React.createElement(Tooltip, { content: "Ordered List", place: "top" },
|
|
73
|
+
React.createElement(MenuButton, { "$active": currOrderedList, onClick: handleOrderedList },
|
|
74
|
+
React.createElement(ListOrdered, { size: 24, color: "grey-5" }))))));
|
|
75
|
+
};
|
|
76
|
+
const Menu = styled.nav `
|
|
77
|
+
display: flex;
|
|
78
|
+
gap: 12px;
|
|
79
|
+
justify-content: center;
|
|
80
|
+
max-width: 1200px;
|
|
81
|
+
margin: 0;
|
|
82
|
+
padding: 14px 24px;
|
|
83
|
+
background-color: var(--color-white);
|
|
84
|
+
box-sizing: border-box;
|
|
85
|
+
border-radius: 8px 8px 0px 0px;
|
|
86
|
+
box-shadow: var(--elevation-1);
|
|
87
|
+
`;
|
|
88
|
+
const MenuSection = styled.div `
|
|
89
|
+
display: flex;
|
|
90
|
+
gap: 16px;
|
|
91
|
+
align-items: center;
|
|
92
|
+
width: fit-content;
|
|
93
|
+
flex-shrink: 0;
|
|
94
|
+
`;
|
|
95
|
+
export const MenuButton = styled.button `
|
|
96
|
+
padding: 2px;
|
|
97
|
+
border: none;
|
|
98
|
+
outline: none;
|
|
99
|
+
cursor: pointer;
|
|
100
|
+
box-sizing: border-box;
|
|
101
|
+
height: 28px;
|
|
102
|
+
width: 28px;
|
|
103
|
+
border-radius: 2px;
|
|
104
|
+
|
|
105
|
+
&:hover:not(:disabled) {
|
|
106
|
+
padding: 1px;
|
|
107
|
+
border: 1px solid var(--color-grey-8);
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
&:active:not(:disabled) {
|
|
111
|
+
background-color: var(--color-grey-9);
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
&:disabled {
|
|
115
|
+
background-color: var(--color-white) !important;
|
|
116
|
+
cursor: initial;
|
|
117
|
+
svg {
|
|
118
|
+
fill: var(--color-grey-7) !important;
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
background-color: ${({ $active }) => $active ? 'var(--color-grey-9)' : 'transparent'};
|
|
123
|
+
`;
|
|
124
|
+
const Divider = styled.div `
|
|
125
|
+
width: 1px;
|
|
126
|
+
height: 28px;
|
|
127
|
+
background-color: var(--color-grey-9);
|
|
128
|
+
`;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const plugins: import("@udecode/plate").PlatePlugin<any, import("@udecode/plate").Value, import("@udecode/plate").PlateEditor<import("@udecode/plate").Value>>[];
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import { createPlugins, createHeadingPlugin, createIndentListPlugin, createImagePlugin, createTextIndentPlugin, createListPlugin, createMediaEmbedPlugin, createResetNodePlugin, createBoldPlugin, createCodePlugin, createFontBackgroundColorPlugin, createFontSizePlugin, createFontFamilyPlugin, createItalicPlugin, createStrikethroughPlugin, createSubscriptPlugin, createSuperscriptPlugin, createUnderlinePlugin, createAlignPlugin, createIndentPlugin, createLineHeightPlugin, createLinkPlugin, createExitBreakPlugin, createHistoryPlugin, createSelectOnBackspacePlugin, createSoftBreakPlugin, } from '@udecode/plate';
|
|
2
|
+
import { createParagraphPlugin, createHOnePlugin, createHTwoPlugin, createHThreePlugin, createHFourPlugin, createHFivePlugin, createHSixPlugin, } from '../plugins/text';
|
|
3
|
+
import { ELEMENT_PARAGRAPH, ELEMENT_H1, ELEMENT_H2, ELEMENT_H3, ELEMENT_H4, ELEMENT_H5, ELEMENT_H6, ELEMENT_OL, ELEMENT_UL, } from '../constants';
|
|
4
|
+
import { exitBreakPlugin } from '../plugins/exitBreak';
|
|
5
|
+
import { LinkFloatingMenu } from '../plugins/link';
|
|
6
|
+
import { resetBlockTypePlugin } from '../plugins/resetBlockType';
|
|
7
|
+
import { selectOnBackspace } from '../plugins/selectOnBackspace';
|
|
8
|
+
import { softBreakPlugin } from '../plugins/softBreak';
|
|
9
|
+
import { plateUI } from '../plate';
|
|
10
|
+
export const plugins = createPlugins([
|
|
11
|
+
createHeadingPlugin(),
|
|
12
|
+
createImagePlugin({
|
|
13
|
+
options: {
|
|
14
|
+
disableUploadInsert: true,
|
|
15
|
+
disableCaption: true,
|
|
16
|
+
disableEmbedInsert: true,
|
|
17
|
+
},
|
|
18
|
+
}),
|
|
19
|
+
createTextIndentPlugin(),
|
|
20
|
+
createIndentListPlugin({
|
|
21
|
+
inject: {
|
|
22
|
+
props: {
|
|
23
|
+
validTypes: [
|
|
24
|
+
ELEMENT_PARAGRAPH,
|
|
25
|
+
ELEMENT_H1,
|
|
26
|
+
ELEMENT_H2,
|
|
27
|
+
ELEMENT_H3,
|
|
28
|
+
ELEMENT_H4,
|
|
29
|
+
ELEMENT_H5,
|
|
30
|
+
ELEMENT_H6,
|
|
31
|
+
ELEMENT_OL,
|
|
32
|
+
ELEMENT_UL,
|
|
33
|
+
],
|
|
34
|
+
},
|
|
35
|
+
},
|
|
36
|
+
}),
|
|
37
|
+
createListPlugin(),
|
|
38
|
+
createMediaEmbedPlugin(),
|
|
39
|
+
createParagraphPlugin(),
|
|
40
|
+
createHOnePlugin(),
|
|
41
|
+
createHTwoPlugin(),
|
|
42
|
+
createHThreePlugin(),
|
|
43
|
+
createHFourPlugin(),
|
|
44
|
+
createHFivePlugin(),
|
|
45
|
+
createHSixPlugin(),
|
|
46
|
+
createResetNodePlugin(),
|
|
47
|
+
createBoldPlugin(),
|
|
48
|
+
createCodePlugin(),
|
|
49
|
+
createFontBackgroundColorPlugin(),
|
|
50
|
+
createFontSizePlugin(),
|
|
51
|
+
createFontFamilyPlugin(),
|
|
52
|
+
createItalicPlugin(),
|
|
53
|
+
createStrikethroughPlugin(),
|
|
54
|
+
createSubscriptPlugin(),
|
|
55
|
+
createSuperscriptPlugin(),
|
|
56
|
+
createUnderlinePlugin(),
|
|
57
|
+
createAlignPlugin({
|
|
58
|
+
inject: {
|
|
59
|
+
props: {
|
|
60
|
+
validTypes: [
|
|
61
|
+
ELEMENT_PARAGRAPH,
|
|
62
|
+
ELEMENT_H1,
|
|
63
|
+
ELEMENT_H2,
|
|
64
|
+
ELEMENT_H3,
|
|
65
|
+
ELEMENT_H4,
|
|
66
|
+
ELEMENT_H5,
|
|
67
|
+
ELEMENT_H6,
|
|
68
|
+
],
|
|
69
|
+
},
|
|
70
|
+
},
|
|
71
|
+
}),
|
|
72
|
+
createIndentPlugin({
|
|
73
|
+
inject: {
|
|
74
|
+
props: {
|
|
75
|
+
validTypes: [ELEMENT_PARAGRAPH, ELEMENT_H1],
|
|
76
|
+
},
|
|
77
|
+
},
|
|
78
|
+
}),
|
|
79
|
+
createLineHeightPlugin(),
|
|
80
|
+
createLinkPlugin({
|
|
81
|
+
renderAfterEditable: LinkFloatingMenu,
|
|
82
|
+
}),
|
|
83
|
+
createExitBreakPlugin(exitBreakPlugin),
|
|
84
|
+
createHistoryPlugin(),
|
|
85
|
+
createResetNodePlugin(resetBlockTypePlugin),
|
|
86
|
+
createSelectOnBackspacePlugin(selectOnBackspace),
|
|
87
|
+
createSoftBreakPlugin(softBreakPlugin),
|
|
88
|
+
], {
|
|
89
|
+
components: plateUI,
|
|
90
|
+
});
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { TElement } from '@udecode/plate';
|
|
3
|
+
export interface SimpleEditorProps {
|
|
4
|
+
communityName: string;
|
|
5
|
+
editable: boolean;
|
|
6
|
+
handleUploadImage: (dataURL: File) => Promise<string>;
|
|
7
|
+
onChange: (newNodes: TElement[]) => void;
|
|
8
|
+
placeholder?: string;
|
|
9
|
+
}
|
|
10
|
+
export declare const SimpleEditor: ({ editable, handleUploadImage, onChange, placeholder, }: SimpleEditorProps) => React.JSX.Element;
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import React from 'react';
|
|
3
|
+
import styled from 'styled-components';
|
|
4
|
+
import { Plate, PlateProvider } from '@udecode/plate';
|
|
5
|
+
import { plugins } from './plugins';
|
|
6
|
+
import { EditorBar } from './navbar';
|
|
7
|
+
export const SimpleEditor = ({ editable, handleUploadImage, onChange, placeholder = '', }) => {
|
|
8
|
+
return (React.createElement(PlateProvider, { id: "main", initialValue: [
|
|
9
|
+
{
|
|
10
|
+
type: 'p',
|
|
11
|
+
children: [
|
|
12
|
+
{
|
|
13
|
+
text: '',
|
|
14
|
+
},
|
|
15
|
+
],
|
|
16
|
+
},
|
|
17
|
+
], onChange: onChange, plugins: plugins },
|
|
18
|
+
React.createElement(Wrapper, null,
|
|
19
|
+
React.createElement(EditorBar, { handleUploadImage: handleUploadImage }),
|
|
20
|
+
React.createElement(InnerWrapper, null,
|
|
21
|
+
React.createElement(Plate, { id: "main", editableProps: {
|
|
22
|
+
readOnly: !editable,
|
|
23
|
+
spellCheck: true,
|
|
24
|
+
autoFocus: true,
|
|
25
|
+
placeholder: placeholder,
|
|
26
|
+
} })))));
|
|
27
|
+
};
|
|
28
|
+
const InnerWrapper = styled.div `
|
|
29
|
+
padding: 24px;
|
|
30
|
+
`;
|
|
31
|
+
const Wrapper = styled.div `
|
|
32
|
+
position: relative;
|
|
33
|
+
max-width: 1200px;
|
|
34
|
+
width: 100%;
|
|
35
|
+
min-height: 224px;
|
|
36
|
+
border: 1px solid var(--color-grey-8);
|
|
37
|
+
border-radius: 8px;
|
|
38
|
+
background-color: var(--color-white);
|
|
39
|
+
|
|
40
|
+
* {
|
|
41
|
+
font-family: Inter;
|
|
42
|
+
outline: none;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
.slate-bold {
|
|
46
|
+
font-weight: 700;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
.slate-italic {
|
|
50
|
+
font-style: italic;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
.slate-strikethrough {
|
|
54
|
+
text-decoration: line-through;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
.slate-underline {
|
|
58
|
+
text-decoration: underline;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
li {
|
|
62
|
+
color: var(--color-grey-3);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
.slate-code {
|
|
66
|
+
& > * {
|
|
67
|
+
font-family: 'Roboto Mono';
|
|
68
|
+
& > * {
|
|
69
|
+
font-family: 'Roboto Mono';
|
|
70
|
+
& > * {
|
|
71
|
+
font-family: 'Roboto Mono';
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
background-color: var(--color-grey-9);
|
|
77
|
+
padding: 0.4em 0.4em;
|
|
78
|
+
font-size: 0.8em;
|
|
79
|
+
line-height: 0.8em;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
& > [data-slate-editor='true'] > * {
|
|
83
|
+
margin: 24px 0px;
|
|
84
|
+
}
|
|
85
|
+
`;
|
|
@@ -62,6 +62,7 @@ const InputWrapper = styled.div `
|
|
|
62
62
|
${({ $warning }) => $warning ? 'border-color: var(--color-red-4) !important;' : ''}
|
|
63
63
|
`;
|
|
64
64
|
const Input = styled.input `
|
|
65
|
+
padding: 0px;
|
|
65
66
|
flex: 1;
|
|
66
67
|
font-family: Inter;
|
|
67
68
|
font-size: ${({ $size }) => ($size === 'small' ? 14 : 16)}px;
|