@crystallize/design-system 1.16.6 → 1.17.1
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/CHANGELOG.md +12 -0
- package/dist/index.css +34 -7
- package/dist/index.d.ts +22 -7
- package/dist/index.js +1684 -1418
- package/dist/index.mjs +1642 -1377
- package/package.json +1 -1
- package/src/action-menu/action-item.tsx +4 -4
- package/src/iconography/check.tsx +22 -0
- package/src/iconography/clock.tsx +38 -0
- package/src/iconography/download.tsx +33 -0
- package/src/iconography/drag-handle.tsx +20 -0
- package/src/iconography/error-white.tsx +14 -0
- package/src/iconography/error.tsx +13 -28
- package/src/iconography/index.ts +14 -0
- package/src/iconography/lifebouy.tsx +58 -0
- package/src/iconography/wand.tsx +45 -0
- package/src/iconography/warning.tsx +1 -9
- package/src/index.ts +1 -0
- package/src/rich-text-editor/i18n/translations/en.ts +1 -0
- package/src/rich-text-editor/i18n/types.ts +1 -0
- package/src/rich-text-editor/plugins/ActionsPlugin/index.tsx +34 -38
- package/src/rich-text-editor/plugins/FloatingLinkEditorPlugin/index.tsx +3 -1
- package/src/rich-text-editor/plugins/FloatingTextFormatToolbarPlugin/index.tsx +16 -16
- package/src/rich-text-editor/plugins/ToolbarPlugin/index.css +9 -0
- package/src/rich-text-editor/plugins/ToolbarPlugin/index.tsx +11 -11
- package/src/rich-text-editor/rich-text-editor.css +0 -1
- package/src/rich-text-editor/rich-text-editor.tsx +5 -14
- package/src/rich-text-editor/types/crystallize-rich-text-types/index.ts +1 -1
- package/src/stack-icon/index.ts +1 -0
- package/src/stack-icon/stack-icon.stories.tsx +24 -0
- package/src/stack-icon/stack-icon.tsx +23 -0
- package/src/rich-text-editor/plugins/ActionsPlugin/index.css +0 -3
- package/src/rich-text-editor/plugins/DimensionsDetectorPlugin/index.tsx +0 -49
|
@@ -456,6 +456,7 @@ export default function ToolbarPlugin({
|
|
|
456
456
|
type="button"
|
|
457
457
|
title={tr(IS_APPLE ? 'actionUndoTitleApple' : 'actionUndoTitle')}
|
|
458
458
|
aria-label={tr('actionUndoLabel')}
|
|
459
|
+
data-testid="rich-text-undo-button"
|
|
459
460
|
>
|
|
460
461
|
<i
|
|
461
462
|
className={`c-rte-icon-undo c-rte-toolbar__icon ${!canUndo ? 'disabled' : ''}
|
|
@@ -563,6 +564,7 @@ export default function ToolbarPlugin({
|
|
|
563
564
|
type="button"
|
|
564
565
|
title={tr('actionInsertCodeBlock')}
|
|
565
566
|
aria-label={tr('actionInsertCodeBlock')}
|
|
567
|
+
data-testid="toggle-format-code"
|
|
566
568
|
>
|
|
567
569
|
<i className={`c-rte-toolbar__icon-btn__icon c-rte-icon-code`} />
|
|
568
570
|
</IconButton>
|
|
@@ -582,9 +584,8 @@ export default function ToolbarPlugin({
|
|
|
582
584
|
content={
|
|
583
585
|
<>
|
|
584
586
|
<DropdownMenu.Item
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
}}
|
|
587
|
+
disabled={!isEditable}
|
|
588
|
+
onClick={() => activeEditor.dispatchCommand(FORMAT_TEXT_COMMAND, 'strikethrough')}
|
|
588
589
|
title={tr('actionFormatWithStrikethroughTitle')}
|
|
589
590
|
aria-label={tr('actionFormatWithStrikethroughLabel')}
|
|
590
591
|
>
|
|
@@ -594,13 +595,12 @@ export default function ToolbarPlugin({
|
|
|
594
595
|
}`}
|
|
595
596
|
/>
|
|
596
597
|
<span className={`c-rte-toolbar__dd-item__text ${isStrikethrough ? 'selected' : ''}`}>
|
|
597
|
-
{tr('
|
|
598
|
+
{tr('actionFormatWithStrikethroughTitle')}
|
|
598
599
|
</span>
|
|
599
600
|
</DropdownMenu.Item>
|
|
600
601
|
<DropdownMenu.Item
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
}}
|
|
602
|
+
disabled={!isEditable}
|
|
603
|
+
onClick={() => activeEditor.dispatchCommand(FORMAT_TEXT_COMMAND, 'subscript')}
|
|
604
604
|
title={tr('actionFormatWithSubscriptTitle')}
|
|
605
605
|
aria-label={tr('actionFormatWithSubscriptLabel')}
|
|
606
606
|
>
|
|
@@ -612,9 +612,8 @@ export default function ToolbarPlugin({
|
|
|
612
612
|
</span>
|
|
613
613
|
</DropdownMenu.Item>
|
|
614
614
|
<DropdownMenu.Item
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
}}
|
|
615
|
+
disabled={!isEditable}
|
|
616
|
+
onClick={() => activeEditor.dispatchCommand(FORMAT_TEXT_COMMAND, 'superscript')}
|
|
618
617
|
title={tr('actionFormatWithSuperscriptTitle')}
|
|
619
618
|
aria-label={tr('actionFormatWithSuperscriptLabel')}
|
|
620
619
|
>
|
|
@@ -628,13 +627,14 @@ export default function ToolbarPlugin({
|
|
|
628
627
|
</span>
|
|
629
628
|
</DropdownMenu.Item>
|
|
630
629
|
<DropdownMenu.Item
|
|
630
|
+
disabled={!isEditable}
|
|
631
631
|
onClick={clearFormatting}
|
|
632
632
|
className="item"
|
|
633
633
|
title={tr('actionClearTextFormatting')}
|
|
634
634
|
aria-label={tr('actionClearTextFormatting')}
|
|
635
635
|
>
|
|
636
636
|
<i className="c-rte-icon-clear c-rte-toolbar__dd-item__icon" />
|
|
637
|
-
<span className="c-rte-toolbar__dd-item__text--clear">
|
|
637
|
+
<span className="c-rte-toolbar__dd-item__text--clear">{tr('actionFormatClear')}</span>
|
|
638
638
|
</DropdownMenu.Item>
|
|
639
639
|
</>
|
|
640
640
|
}
|
|
@@ -26,7 +26,6 @@ import { BaseNodes } from './nodes/BaseNodes';
|
|
|
26
26
|
import AutoLinkPlugin from './plugins/AutoLinkPlugin';
|
|
27
27
|
import CodeActionMenuPlugin from './plugins/CodeActionMenuPlugin';
|
|
28
28
|
import CodeHighlightPlugin from './plugins/CodeHighlightPlugin';
|
|
29
|
-
import { DimensionDetectorPlugin } from './plugins/DimensionsDetectorPlugin';
|
|
30
29
|
import FloatingLinkEditorPlugin from './plugins/FloatingLinkEditorPlugin';
|
|
31
30
|
import FloatingTextFormatToolbarPlugin from './plugins/FloatingTextFormatToolbarPlugin';
|
|
32
31
|
import LinkPlugin from './plugins/LinkPlugin';
|
|
@@ -71,7 +70,7 @@ export function RichTextEditor({
|
|
|
71
70
|
labelTranslations,
|
|
72
71
|
...rest
|
|
73
72
|
}: TRichTextBase & {
|
|
74
|
-
initialData?: CrystallizeRichText;
|
|
73
|
+
initialData?: CrystallizeRichText | null;
|
|
75
74
|
}) {
|
|
76
75
|
return (
|
|
77
76
|
<LexicalComposer
|
|
@@ -79,15 +78,11 @@ export function RichTextEditor({
|
|
|
79
78
|
editable: !rest.disabled,
|
|
80
79
|
namespace: 'crystallize-rich-text-editor',
|
|
81
80
|
nodes: [...BaseNodes],
|
|
81
|
+
theme: CrystallizeRTEditorTheme,
|
|
82
|
+
editorState: initialData ? composeInitialState({ richText: initialData }) : undefined,
|
|
82
83
|
onError: (error: Error) => {
|
|
83
84
|
throw error;
|
|
84
85
|
},
|
|
85
|
-
theme: CrystallizeRTEditorTheme,
|
|
86
|
-
editorState: initialData
|
|
87
|
-
? composeInitialState({
|
|
88
|
-
richText: initialData,
|
|
89
|
-
})
|
|
90
|
-
: undefined,
|
|
91
86
|
}}
|
|
92
87
|
>
|
|
93
88
|
<I18nProvider language={language} labelTranslations={labelTranslations}>
|
|
@@ -119,7 +114,6 @@ function RichTextEditorWithoutContext({
|
|
|
119
114
|
|
|
120
115
|
const [editor] = useLexicalComposerContext();
|
|
121
116
|
const [floatingAnchorElem, setFloatingAnchorElem] = useState<HTMLDivElement | null>(null);
|
|
122
|
-
const [isSmallWidthViewport, setIsSmallWidthViewport] = useState<boolean>(false);
|
|
123
117
|
const firstOnChangeTriggeredRef = useRef(!autoFocus);
|
|
124
118
|
|
|
125
119
|
const onRef = (_floatingAnchorElem: HTMLDivElement) => {
|
|
@@ -146,10 +140,7 @@ function RichTextEditorWithoutContext({
|
|
|
146
140
|
return (
|
|
147
141
|
<>
|
|
148
142
|
<OnChangePlugin onChange={onLocalChange} ignoreSelectionChange />
|
|
149
|
-
<
|
|
150
|
-
{isSmallWidthViewport ? null : (
|
|
151
|
-
<ToolbarPlugin actionsMenuPrepend={actionsMenuPrepend} actionsMenuAppend={actionsMenuAppend} />
|
|
152
|
-
)}
|
|
143
|
+
<ToolbarPlugin actionsMenuPrepend={actionsMenuPrepend} actionsMenuAppend={actionsMenuAppend} />
|
|
153
144
|
{slotPreContent}
|
|
154
145
|
<div className={`c-rte-editor-container ${disabled ? 'disabled' : ''}`}>
|
|
155
146
|
{maxLength != null ? <MaxLengthPlugin maxLength={maxLength} /> : null}
|
|
@@ -178,7 +169,7 @@ function RichTextEditorWithoutContext({
|
|
|
178
169
|
<HorizontalRulePlugin />
|
|
179
170
|
<TabFocusPlugin />
|
|
180
171
|
<TabIndentationPlugin />
|
|
181
|
-
{floatingAnchorElem &&
|
|
172
|
+
{floatingAnchorElem && (
|
|
182
173
|
<>
|
|
183
174
|
{/* <DraggableBlockPlugin anchorElem={floatingAnchorElem} /> */}
|
|
184
175
|
<CodeActionMenuPlugin anchorElem={floatingAnchorElem} />
|
|
@@ -6,7 +6,7 @@ import type { CrystallizeRichTextTableNodes } from './table';
|
|
|
6
6
|
export type { CrystallizeRichTextCodeNodes } from './code';
|
|
7
7
|
export type { CrystallizeRichTextHeadingNodes } from './headings';
|
|
8
8
|
|
|
9
|
-
export type CrystallizeRichText = CrystallizeRichTextNode
|
|
9
|
+
export type CrystallizeRichText = CrystallizeRichTextNode[];
|
|
10
10
|
|
|
11
11
|
type CrystallizeRichTextNodeBase = {
|
|
12
12
|
textContent?: string;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { StackIcon } from './stack-icon';
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { StoryObj, Meta } from '@storybook/react';
|
|
2
|
+
|
|
3
|
+
import { StackIcon } from '.';
|
|
4
|
+
import { Icon } from '../iconography';
|
|
5
|
+
|
|
6
|
+
const meta: Meta<typeof StackIcon> = {
|
|
7
|
+
title: 'Components/StackIcon',
|
|
8
|
+
component: StackIcon,
|
|
9
|
+
argTypes: {},
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
export default meta;
|
|
13
|
+
type Story = StoryObj<typeof StackIcon>;
|
|
14
|
+
|
|
15
|
+
export const WithTypeCreate: Story = {
|
|
16
|
+
name: 'With type create',
|
|
17
|
+
render: () => (
|
|
18
|
+
<div>
|
|
19
|
+
<StackIcon type="create">
|
|
20
|
+
<Icon.Catalogue width={24} height={24} />
|
|
21
|
+
</StackIcon>
|
|
22
|
+
</div>
|
|
23
|
+
),
|
|
24
|
+
};
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { Icon } from '../iconography';
|
|
2
|
+
|
|
3
|
+
type StackIconProps = {
|
|
4
|
+
type: 'create';
|
|
5
|
+
children: React.ReactNode;
|
|
6
|
+
size?: number;
|
|
7
|
+
};
|
|
8
|
+
|
|
9
|
+
export function StackIcon({ type, children, size = 18 }: StackIconProps) {
|
|
10
|
+
return (
|
|
11
|
+
<span className="relative leading-[0] inline-block">
|
|
12
|
+
{type === 'create' && (
|
|
13
|
+
<span
|
|
14
|
+
style={{ width: size, height: size }}
|
|
15
|
+
className="absolute right-0 top-0 flex -translate-y-1/3 translate-x-1/3 items-center justify-center rounded border border-solid border-white bg-gray-50-900"
|
|
16
|
+
>
|
|
17
|
+
<Icon.Add width={size - 4} height={size - 4} />
|
|
18
|
+
</span>
|
|
19
|
+
)}
|
|
20
|
+
{children}
|
|
21
|
+
</span>
|
|
22
|
+
);
|
|
23
|
+
}
|
|
@@ -1,49 +0,0 @@
|
|
|
1
|
-
import { useEffect, useRef, useState } from 'react';
|
|
2
|
-
|
|
3
|
-
type Dimensions = {
|
|
4
|
-
isSmallWidth: boolean;
|
|
5
|
-
width: number;
|
|
6
|
-
};
|
|
7
|
-
|
|
8
|
-
type DimensionDetectorPluginProps = {
|
|
9
|
-
onChange: (p: Dimensions) => void;
|
|
10
|
-
};
|
|
11
|
-
|
|
12
|
-
export function DimensionDetectorPlugin({ onChange }: DimensionDetectorPluginProps) {
|
|
13
|
-
const [dimensions, setDimensions] = useState<Dimensions>();
|
|
14
|
-
const ref = useRef<HTMLDivElement | null>(null);
|
|
15
|
-
|
|
16
|
-
useEffect(() => {
|
|
17
|
-
if (ref.current) {
|
|
18
|
-
const el = ref.current;
|
|
19
|
-
const resizeObserver = new ResizeObserver(entries => {
|
|
20
|
-
const [first] = entries;
|
|
21
|
-
if (first) {
|
|
22
|
-
const [contentBox] = first.contentBoxSize;
|
|
23
|
-
if (contentBox) {
|
|
24
|
-
const width = contentBox.inlineSize;
|
|
25
|
-
setDimensions({
|
|
26
|
-
width,
|
|
27
|
-
/**
|
|
28
|
-
* 600 is (currently) the point before action button crashes with
|
|
29
|
-
* the rest of the toolbar buttons.
|
|
30
|
-
*/
|
|
31
|
-
isSmallWidth: width < 600,
|
|
32
|
-
});
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
|
-
});
|
|
36
|
-
resizeObserver.observe(el);
|
|
37
|
-
|
|
38
|
-
return () => resizeObserver.disconnect();
|
|
39
|
-
}
|
|
40
|
-
}, []);
|
|
41
|
-
|
|
42
|
-
useEffect(() => {
|
|
43
|
-
if (dimensions) {
|
|
44
|
-
onChange(dimensions);
|
|
45
|
-
}
|
|
46
|
-
}, [dimensions, onChange]);
|
|
47
|
-
|
|
48
|
-
return <div ref={ref} style={{ height: 1, marginTop: -1 }} />;
|
|
49
|
-
}
|