@crystallize/design-system 1.11.7 → 1.13.0
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 +17 -0
- package/dist/draggable-block-menu-KKHDNKJA.svg +1 -0
- package/dist/index.css +565 -1025
- package/dist/index.d.ts +1 -0
- package/dist/index.js +538 -517
- package/dist/index.mjs +419 -398
- package/package.json +22 -23
- package/src/button/Button.stories.tsx +1 -0
- package/src/card/card.stories.tsx +1 -0
- package/src/checkbox/checkbox.stories.tsx +1 -1
- package/src/checkbox/checkbox.tsx +1 -1
- package/src/colors/Colors.stories.tsx +3 -3
- package/src/dialog/config.tsx +1 -1
- package/src/dialog/index.tsx +1 -1
- package/src/dropdown-menu/dropdown-menu-item.tsx +2 -2
- package/src/dropdown-menu/dropdown-menu-label.tsx +1 -1
- package/src/icon-button/IconButton.stories.tsx +1 -0
- package/src/iconography/Icon.stories.tsx +1 -0
- package/src/inline-radio/inline-radio.stories.tsx +3 -3
- package/src/inline-radio/inline-radio.tsx +2 -2
- package/src/input/input.tsx +1 -1
- package/src/input-with-label/input-with-label.tsx +1 -1
- package/src/label/label.stories.tsx +1 -0
- package/src/progress/Progress.stories.tsx +2 -1
- package/src/progress/progress.tsx +1 -1
- package/src/radio/radio.stories.tsx +1 -1
- package/src/radio/radio.tsx +1 -1
- package/src/rich-text-editor/model/crystallize-to-lexical.ts +4 -3
- package/src/rich-text-editor/model/parse-initial-state.test.ts +48 -0
- package/src/rich-text-editor/model/parse-initial-state.ts +20 -0
- package/src/rich-text-editor/plugins/ActionsPlugin/index.css +3 -0
- package/src/rich-text-editor/plugins/ActionsPlugin/index.tsx +1 -2
- package/src/rich-text-editor/plugins/AutoLinkPlugin/index.tsx +1 -1
- package/src/rich-text-editor/plugins/CodeActionMenuPlugin/components/CopyButton/index.tsx +6 -2
- package/src/rich-text-editor/plugins/CodeActionMenuPlugin/components/PrettierButton/index.tsx +10 -6
- package/src/rich-text-editor/plugins/CodeActionMenuPlugin/index.css +32 -17
- package/src/rich-text-editor/plugins/CodeActionMenuPlugin/index.tsx +3 -4
- package/src/rich-text-editor/plugins/DimensionsDetectorPlugin/index.tsx +49 -0
- package/src/rich-text-editor/plugins/DraggableBlockPlugin/index.css +14 -14
- package/src/rich-text-editor/plugins/DraggableBlockPlugin/index.tsx +4 -4
- package/src/rich-text-editor/plugins/FloatingLinkEditorPlugin/index.css +87 -21
- package/src/rich-text-editor/plugins/FloatingLinkEditorPlugin/index.tsx +11 -17
- package/src/rich-text-editor/plugins/FloatingTextFormatToolbarPlugin/index.css +10 -2
- package/src/rich-text-editor/plugins/FloatingTextFormatToolbarPlugin/index.tsx +17 -17
- package/src/rich-text-editor/plugins/LinkPlugin/index.tsx +1 -1
- package/src/rich-text-editor/plugins/ListMaxIndentLevelPlugin/index.ts +10 -21
- package/src/rich-text-editor/plugins/TableActionMenuPlugin/index.css +6 -0
- package/src/rich-text-editor/plugins/TableActionMenuPlugin/index.tsx +2 -2
- package/src/rich-text-editor/plugins/ToolbarPlugin/index.css +115 -0
- package/src/rich-text-editor/plugins/ToolbarPlugin/index.tsx +57 -78
- package/src/rich-text-editor/plugins/ToolbarPlugin/insert-table.tsx +5 -5
- package/src/rich-text-editor/rich-text-editor-icons.css +213 -0
- package/src/rich-text-editor/rich-text-editor.css +33 -913
- package/src/rich-text-editor/rich-text-editor.stories.tsx +24 -0
- package/src/rich-text-editor/rich-text-editor.tsx +13 -27
- package/src/rich-text-editor/themes/CrystallizeRTEditorTheme.ts +1 -1
- package/src/rich-text-editor/ui/LinkPreview.tsx +7 -8
- package/src/rich-text-editor/utils/getSelectedNode.ts +4 -5
- package/src/rich-text-editor/utils/point.ts +4 -7
- package/src/rich-text-editor/utils/rect.ts +18 -41
- package/src/rich-text-editor/utils/url.ts +1 -2
- package/src/select/select-root.tsx +1 -1
- package/src/select/select.stories.tsx +1 -1
- package/src/select/select.ts +0 -1
- package/src/slider/Slider.stories.tsx +2 -1
- package/src/slider/slider.tsx +2 -2
- package/src/spinner/Spinner.stories.tsx +1 -0
- package/src/spinner/index.tsx +1 -1
- package/src/tag/Tag.stories.tsx +1 -0
- package/dist/camera-CR7D2PNH.svg +0 -1
- package/dist/clipboard-OSEFDF25.svg +0 -1
- package/dist/gear-ICMT4NTP.svg +0 -1
- package/dist/journal-code-XUT44HDV.svg +0 -1
- package/dist/lock-WCYOZOHW.svg +0 -1
- package/dist/lock-fill-JZSKOSHK.svg +0 -1
- package/dist/pencil-fill-STFSC26F.svg +0 -1
- package/dist/plug-HGGGEVS3.svg +0 -1
- package/dist/plug-fill-OTG3U4TN.svg +0 -1
- package/src/rich-text-editor/hooks/useReport.ts +0 -64
- package/src/rich-text-editor/plugins/CodeActionMenuPlugin/components/PrettierButton/index.css +0 -14
- package/src/rich-text-editor/ui/LinkPreview.css +0 -57
- package/src/rich-text-editor/utils/isMobileWidth.ts +0 -7
- package/src/rich-text-editor/utils/joinClasses.ts +0 -13
- package/src/rich-text-editor/utils/swipe.ts +0 -127
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@crystallize/design-system",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.13.0",
|
|
4
4
|
"types": "./dist/index.d.ts",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"module": "./dist/index.mjs",
|
|
@@ -58,39 +58,38 @@
|
|
|
58
58
|
"@faker-js/faker": "7.6.0",
|
|
59
59
|
"@ianvs/prettier-plugin-sort-imports": "^3.7.1",
|
|
60
60
|
"@mdx-js/react": "^2.2.1",
|
|
61
|
-
"@storybook/addon-actions": "7.0.
|
|
62
|
-
"@storybook/addon-backgrounds": "7.0.
|
|
63
|
-
"@storybook/addon-docs": "7.0.
|
|
64
|
-
"@storybook/addon-essentials": "7.0.
|
|
65
|
-
"@storybook/addon-highlight": "7.0.
|
|
66
|
-
"@storybook/addon-interactions": "7.0.
|
|
67
|
-
"@storybook/addon-links": "7.0.
|
|
68
|
-
"@storybook/addon-measure": "7.0.
|
|
69
|
-
"@storybook/addon-outline": "7.0.
|
|
61
|
+
"@storybook/addon-actions": "7.0.7",
|
|
62
|
+
"@storybook/addon-backgrounds": "7.0.7",
|
|
63
|
+
"@storybook/addon-docs": "7.0.7",
|
|
64
|
+
"@storybook/addon-essentials": "7.0.7",
|
|
65
|
+
"@storybook/addon-highlight": "7.0.7",
|
|
66
|
+
"@storybook/addon-interactions": "7.0.7",
|
|
67
|
+
"@storybook/addon-links": "7.0.7",
|
|
68
|
+
"@storybook/addon-measure": "7.0.7",
|
|
69
|
+
"@storybook/addon-outline": "7.0.7",
|
|
70
70
|
"@storybook/addons": "^6.5.15",
|
|
71
|
-
"@storybook/react": "7.0.
|
|
72
|
-
"@storybook/react-vite": "7.0.
|
|
73
|
-
"@storybook/
|
|
74
|
-
"@
|
|
75
|
-
"@testing-library/
|
|
76
|
-
"@testing-library/
|
|
77
|
-
"@testing-library/user-event": "^14.4.3",
|
|
71
|
+
"@storybook/react": "7.0.7",
|
|
72
|
+
"@storybook/react-vite": "7.0.7",
|
|
73
|
+
"@storybook/theming": "7.0.7",
|
|
74
|
+
"@testing-library/jest-dom": "5.16.4",
|
|
75
|
+
"@testing-library/react": "12.0.0",
|
|
76
|
+
"@testing-library/user-event": "14.4.3",
|
|
78
77
|
"@types/prettier": "2.7.2",
|
|
79
78
|
"@types/react": "17.0.1",
|
|
80
79
|
"@types/react-dom": "17.0.1",
|
|
81
|
-
"@types/testing-library__jest-dom": "
|
|
80
|
+
"@types/testing-library__jest-dom": "5.14.5",
|
|
82
81
|
"@vitejs/plugin-react": "^3.0.1",
|
|
83
82
|
"concurrently": "^7.6.0",
|
|
84
83
|
"hex-rgb": "4.3.0",
|
|
85
84
|
"postcss": "^8.4.21",
|
|
86
|
-
"storybook": "7.0.
|
|
85
|
+
"storybook": "7.0.7",
|
|
87
86
|
"storybook-addon-designs": "^6.3.1",
|
|
88
87
|
"storybook-dark-mode": "^2.0.5",
|
|
89
88
|
"tailwindcss": "^3.3.0",
|
|
90
89
|
"tsup": "^6.5.0",
|
|
91
|
-
"typescript": "
|
|
92
|
-
"vite": "
|
|
93
|
-
"vitest": "
|
|
90
|
+
"typescript": "4.9.4",
|
|
91
|
+
"vite": "4.3.4",
|
|
92
|
+
"vitest": "0.30.1",
|
|
94
93
|
"tsconfig": "0.0.0"
|
|
95
94
|
},
|
|
96
95
|
"keywords": [
|
|
@@ -116,7 +115,7 @@
|
|
|
116
115
|
"build:storybook": "storybook build -s public",
|
|
117
116
|
"build:tw": "tailwindcss --content ./src/**/*.tsx,!./src/**/*.stories.tsx -c ./tailwind.config.cjs -i src/index.css -o dist/index.css --minify",
|
|
118
117
|
"build:tsup": "tsup src/index.ts --format esm,cjs --dts",
|
|
119
|
-
"build": "pnpm build:tw && pnpm build:tsup
|
|
118
|
+
"build": "pnpm build:tw && pnpm build:tsup",
|
|
120
119
|
"dev:tw": "tailwindcss --content ./src/**/*.tsx,!./src/**/*.stories.tsx -c ./tailwind.config.cjs -i src/index.css -o dist/index.css --watch & tsup src/index.ts --format esm --dts --watch",
|
|
121
120
|
"dev:tsup": "tsup src/index.ts --format esm --dts --watch",
|
|
122
121
|
"dev:storybook": "storybook dev -p 6006 --no-open -s public",
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import type { Meta, StoryObj } from '@storybook/react';
|
|
2
1
|
import { cx } from 'class-variance-authority';
|
|
3
2
|
import { useDarkMode } from 'storybook-dark-mode';
|
|
3
|
+
import type { Meta, StoryObj } from '@storybook/react';
|
|
4
4
|
|
|
5
|
-
import rawColors from './colors.json';
|
|
6
|
-
import colorPairing from './color-pairing.json';
|
|
7
5
|
import colorDefaults from './color-defaults.json';
|
|
6
|
+
import colorPairing from './color-pairing.json';
|
|
7
|
+
import rawColors from './colors.json';
|
|
8
8
|
import type { Color, ColorName, Colors } from './types';
|
|
9
9
|
|
|
10
10
|
const meta: Meta = {
|
package/src/dialog/config.tsx
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { unmountComponentAtNode, render as DOMRender } from 'react-dom';
|
|
2
|
-
import { ConfirmDialog } from './confirm-dialog';
|
|
3
2
|
|
|
3
|
+
import { ConfirmDialog } from './confirm-dialog';
|
|
4
4
|
import { destroyFns } from './destroyFns';
|
|
5
5
|
import type { ConfigUpdate, DialogFuncProps } from './types';
|
|
6
6
|
|
package/src/dialog/index.tsx
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
+
import { confirm, withWarning, withConfirm, withDialog, withError, withInfo } from './config';
|
|
1
2
|
import { destroyFns } from './destroyFns';
|
|
2
3
|
import { DialogBase } from './dialog';
|
|
3
4
|
import type { DialogFuncProps } from './types';
|
|
4
|
-
import { confirm, withWarning, withConfirm, withDialog, withError, withInfo } from './config';
|
|
5
5
|
|
|
6
6
|
type DialogType = typeof DialogBase & DialogFuncProps;
|
|
7
7
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import * as DropdownMenuPrimitive from '@radix-ui/react-dropdown-menu';
|
|
2
|
-
import { cx } from 'class-variance-authority';
|
|
3
1
|
import type { ReactNode } from 'react';
|
|
2
|
+
import { cx } from 'class-variance-authority';
|
|
3
|
+
import * as DropdownMenuPrimitive from '@radix-ui/react-dropdown-menu';
|
|
4
4
|
|
|
5
5
|
type DropdownMenuItemProps = DropdownMenuPrimitive.MenuItemProps & {
|
|
6
6
|
children: ReactNode;
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { useState } from 'react';
|
|
2
|
-
import { InlineRadio } from './inline-radio';
|
|
3
|
-
import { Icon } from '../iconography';
|
|
4
|
-
|
|
5
2
|
import type { Meta, StoryObj } from '@storybook/react';
|
|
6
3
|
|
|
4
|
+
import { Icon } from '../iconography';
|
|
5
|
+
import { InlineRadio } from './inline-radio';
|
|
6
|
+
|
|
7
7
|
const meta: Meta<typeof InlineRadio.Group> = {
|
|
8
8
|
title: 'Components/InlineRadio',
|
|
9
9
|
component: InlineRadio.Group,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import * as RadioGroupPrimitive from '@radix-ui/react-radio-group';
|
|
2
|
-
import { cx, cva, VariantProps } from 'class-variance-authority';
|
|
3
1
|
import type { ComponentProps } from 'react';
|
|
2
|
+
import { cx, cva, VariantProps } from 'class-variance-authority';
|
|
3
|
+
import * as RadioGroupPrimitive from '@radix-ui/react-radio-group';
|
|
4
4
|
|
|
5
5
|
import './inline-radio.css';
|
|
6
6
|
|
package/src/input/input.tsx
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { ComponentPropsWithoutRef, ComponentPropsWithRef, forwardRef, ReactNode } from 'react';
|
|
2
2
|
import { cva, cx, VariantProps } from 'class-variance-authority';
|
|
3
3
|
|
|
4
|
+
import { Triangle } from '../iconography/triangle';
|
|
4
5
|
import { Input } from '../input';
|
|
5
6
|
import { Label } from '../label';
|
|
6
|
-
import { Triangle } from '../iconography/triangle';
|
|
7
7
|
|
|
8
8
|
const inputWithLabelStyles = cva(['c-input-with-label'], {
|
|
9
9
|
variants: {
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { useState } from 'react';
|
|
2
2
|
import type { Meta, StoryObj } from '@storybook/react';
|
|
3
3
|
|
|
4
|
-
import { Radio } from './radio';
|
|
5
4
|
import { Label } from '../label';
|
|
5
|
+
import { Radio } from './radio';
|
|
6
6
|
|
|
7
7
|
const meta: Meta<typeof Radio.Group> = {
|
|
8
8
|
title: 'Components/Radio',
|
package/src/radio/radio.tsx
CHANGED
|
@@ -15,13 +15,12 @@ import { $createHeadingNode, $createQuoteNode } from '@lexical/rich-text';
|
|
|
15
15
|
import { $createTableCellNode, $createTableNode, $createTableRowNode } from '@lexical/table';
|
|
16
16
|
|
|
17
17
|
import type { CrystallizeRichTextNode, CrystallizeRichText } from '../types/crystallize-rich-text-types';
|
|
18
|
+
import { parseInitialState } from './parse-initial-state';
|
|
18
19
|
|
|
19
20
|
export function composeInitialState({ richText }: { richText: CrystallizeRichText }) {
|
|
20
21
|
return function setLexicalState() {
|
|
21
22
|
const root = $getRoot();
|
|
22
23
|
|
|
23
|
-
const richTextArray = Array.isArray(richText) ? richText : [richText];
|
|
24
|
-
|
|
25
24
|
function handleNode({
|
|
26
25
|
crystallizeContentNode,
|
|
27
26
|
lexicalParent,
|
|
@@ -196,7 +195,9 @@ export function composeInitialState({ richText }: { richText: CrystallizeRichTex
|
|
|
196
195
|
}
|
|
197
196
|
}
|
|
198
197
|
|
|
199
|
-
|
|
198
|
+
parseInitialState({ richText }).forEach(crystallizeContentNode =>
|
|
199
|
+
handleNode({ crystallizeContentNode, lexicalParent: root }),
|
|
200
|
+
);
|
|
200
201
|
};
|
|
201
202
|
}
|
|
202
203
|
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/* eslint-disable no-console */
|
|
2
|
+
|
|
3
|
+
import type { CrystallizeRichText } from '../rich-text-editor';
|
|
4
|
+
import { parseInitialState } from './parse-initial-state';
|
|
5
|
+
|
|
6
|
+
describe('RichTextEditor parseInitialState', () => {
|
|
7
|
+
it('ensures that the initial state is an array', async () => {
|
|
8
|
+
expect(
|
|
9
|
+
parseInitialState({
|
|
10
|
+
richText: {
|
|
11
|
+
kind: 'block',
|
|
12
|
+
type: 'paragraph',
|
|
13
|
+
textContent: 'hello',
|
|
14
|
+
},
|
|
15
|
+
}),
|
|
16
|
+
).toEqual([
|
|
17
|
+
{
|
|
18
|
+
kind: 'block',
|
|
19
|
+
type: 'paragraph',
|
|
20
|
+
textContent: 'hello',
|
|
21
|
+
},
|
|
22
|
+
]);
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
it('ensures that all root nodes are block elements', async () => {
|
|
26
|
+
expect(
|
|
27
|
+
parseInitialState({
|
|
28
|
+
richText: [
|
|
29
|
+
{
|
|
30
|
+
kind: 'inline',
|
|
31
|
+
textContent: 'hello',
|
|
32
|
+
},
|
|
33
|
+
],
|
|
34
|
+
}),
|
|
35
|
+
).toEqual([
|
|
36
|
+
{
|
|
37
|
+
kind: 'block',
|
|
38
|
+
type: 'paragraph',
|
|
39
|
+
children: [
|
|
40
|
+
{
|
|
41
|
+
kind: 'inline',
|
|
42
|
+
textContent: 'hello',
|
|
43
|
+
},
|
|
44
|
+
],
|
|
45
|
+
} as CrystallizeRichText,
|
|
46
|
+
]);
|
|
47
|
+
});
|
|
48
|
+
});
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { CrystallizeRichText, CrystallizeRichTextNode } from '../types/crystallize-rich-text-types';
|
|
2
|
+
|
|
3
|
+
export function parseInitialState({ richText }: { richText: CrystallizeRichText }): CrystallizeRichTextNode[] {
|
|
4
|
+
let richTextArray = Array.isArray(richText) ? richText : [richText];
|
|
5
|
+
|
|
6
|
+
// Ensure all root items are block elements
|
|
7
|
+
richTextArray = richTextArray.map(rootNode => {
|
|
8
|
+
if (!rootNode.kind || rootNode.kind === 'inline') {
|
|
9
|
+
return {
|
|
10
|
+
type: 'paragraph',
|
|
11
|
+
kind: 'block',
|
|
12
|
+
children: [rootNode],
|
|
13
|
+
};
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
return rootNode;
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
return richTextArray;
|
|
20
|
+
}
|
|
@@ -38,8 +38,7 @@ export default function ActionsPlugin({
|
|
|
38
38
|
const actionMenuAnchorRef = useRef<HTMLDivElement>(null);
|
|
39
39
|
|
|
40
40
|
return (
|
|
41
|
-
<div ref={actionMenuAnchorRef} className="
|
|
42
|
-
<div></div>
|
|
41
|
+
<div ref={actionMenuAnchorRef} className="c-rte-actions-plugin">
|
|
43
42
|
<ActionMenu container={actionMenuAnchorRef.current}>
|
|
44
43
|
{!prepend
|
|
45
44
|
? null
|
|
@@ -6,8 +6,8 @@
|
|
|
6
6
|
*
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
|
-
import { AutoLinkPlugin } from '@lexical/react/LexicalAutoLinkPlugin';
|
|
10
9
|
import * as React from 'react';
|
|
10
|
+
import { AutoLinkPlugin } from '@lexical/react/LexicalAutoLinkPlugin';
|
|
11
11
|
|
|
12
12
|
const URL_MATCHER =
|
|
13
13
|
/((https?:\/\/(www\.)?)|(www\.))[-a-zA-Z0-9@:%._+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}\b([-a-zA-Z0-9()@:%_+.~#?&//=]*)/;
|
|
@@ -57,8 +57,12 @@ export function CopyButton({ editor, getCodeDOMNode }: Props) {
|
|
|
57
57
|
}
|
|
58
58
|
|
|
59
59
|
return (
|
|
60
|
-
<button className="
|
|
61
|
-
{isCopyCompleted ?
|
|
60
|
+
<button className="c-rte-code-button" onClick={handleClick} aria-label={tr('actionCopyCode')}>
|
|
61
|
+
{isCopyCompleted ? (
|
|
62
|
+
<i className="c-rte-code-button__icon c-rte-icon-success" />
|
|
63
|
+
) : (
|
|
64
|
+
<i className="c-rte-code-button__icon c-rte-icon-copy" />
|
|
65
|
+
)}
|
|
62
66
|
</button>
|
|
63
67
|
);
|
|
64
68
|
}
|
package/src/rich-text-editor/plugins/CodeActionMenuPlugin/components/PrettierButton/index.tsx
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
* LICENSE file in the root directory of this source tree.
|
|
6
6
|
*
|
|
7
7
|
*/
|
|
8
|
-
|
|
8
|
+
|
|
9
9
|
import * as React from 'react';
|
|
10
10
|
import { useState } from 'react';
|
|
11
11
|
import { $getNearestNodeFromDOMNode, LexicalEditor } from 'lexical';
|
|
@@ -98,7 +98,7 @@ export function PrettierButton({ lang, editor, getCodeDOMNode }: Props) {
|
|
|
98
98
|
/**
|
|
99
99
|
* Remove EOF from prettier output. This is useful when
|
|
100
100
|
* using prettier on files, but becomes weird when the code
|
|
101
|
-
* is embedded within a larger portion of text
|
|
101
|
+
* is embedded within a larger portion of text (like we do)
|
|
102
102
|
*/
|
|
103
103
|
parsed = parsed.replace(/[\r\n]+$/, '');
|
|
104
104
|
|
|
@@ -133,17 +133,21 @@ export function PrettierButton({ lang, editor, getCodeDOMNode }: Props) {
|
|
|
133
133
|
}
|
|
134
134
|
|
|
135
135
|
return (
|
|
136
|
-
<div className="prettier-wrapper">
|
|
136
|
+
<div className="c-rte-prettier-wrapper">
|
|
137
137
|
<button
|
|
138
|
-
className="
|
|
138
|
+
className="c-rte-code-button"
|
|
139
139
|
onClick={handleClick}
|
|
140
140
|
onMouseEnter={handleMouseEnter}
|
|
141
141
|
onMouseLeave={handleMouseLeave}
|
|
142
142
|
aria-label={tr('actionFormatCode')}
|
|
143
143
|
>
|
|
144
|
-
{syntaxError ?
|
|
144
|
+
{syntaxError ? (
|
|
145
|
+
<i className="c-rte-code-button__icon c-rte-icon-prettier-error" />
|
|
146
|
+
) : (
|
|
147
|
+
<i className="c-rte-code-button__icon c-rte-icon-prettier" />
|
|
148
|
+
)}
|
|
145
149
|
</button>
|
|
146
|
-
{tipsVisible ? <pre className="code-error-tips">{syntaxError}</pre> : null}
|
|
150
|
+
{tipsVisible ? <pre className="c-rte-code-error-tips">{syntaxError}</pre> : null}
|
|
147
151
|
</div>
|
|
148
152
|
);
|
|
149
153
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
.code-action-menu-container {
|
|
1
|
+
.c-rte-code-action-menu-container {
|
|
2
2
|
height: 35.8px;
|
|
3
3
|
font-size: 10px;
|
|
4
4
|
color: rgba(0, 0, 0, 0.5);
|
|
@@ -9,11 +9,11 @@
|
|
|
9
9
|
user-select: none;
|
|
10
10
|
}
|
|
11
11
|
|
|
12
|
-
.
|
|
12
|
+
.c-rte-code-highlight-language {
|
|
13
13
|
margin-right: 4px;
|
|
14
14
|
}
|
|
15
15
|
|
|
16
|
-
.
|
|
16
|
+
.c-rte-code-button {
|
|
17
17
|
border: 1px solid transparent;
|
|
18
18
|
border-radius: 4px;
|
|
19
19
|
padding: 4px;
|
|
@@ -24,23 +24,38 @@
|
|
|
24
24
|
align-items: center;
|
|
25
25
|
color: rgba(0, 0, 0, 0.5);
|
|
26
26
|
text-transform: uppercase;
|
|
27
|
-
}
|
|
28
27
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
28
|
+
&:hover {
|
|
29
|
+
border: 1px solid rgba(0, 0, 0, 0.3);
|
|
30
|
+
opacity: 0.9;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
&:active {
|
|
34
|
+
background-color: rgba(223, 232, 250);
|
|
35
|
+
border: 1px solid rgba(0, 0, 0, 0.45);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
&__icon {
|
|
39
|
+
height: 16px;
|
|
40
|
+
width: 16px;
|
|
41
|
+
opacity: 0.6;
|
|
42
|
+
display: flex;
|
|
43
|
+
color: rgba(0, 0, 0, 0.5);
|
|
44
|
+
background-size: contain;
|
|
45
|
+
}
|
|
36
46
|
}
|
|
37
47
|
|
|
38
|
-
.
|
|
39
|
-
|
|
40
|
-
opacity: 0.9;
|
|
48
|
+
.c-rte-prettier-wrapper {
|
|
49
|
+
position: relative;
|
|
41
50
|
}
|
|
42
51
|
|
|
43
|
-
.
|
|
44
|
-
|
|
45
|
-
border:
|
|
52
|
+
.c-rte-code-error-tips {
|
|
53
|
+
padding: 5px;
|
|
54
|
+
border-radius: 4px;
|
|
55
|
+
color: #fff;
|
|
56
|
+
background: #222;
|
|
57
|
+
margin-top: 4px;
|
|
58
|
+
position: absolute;
|
|
59
|
+
top: 26px;
|
|
60
|
+
right: 0;
|
|
46
61
|
}
|
|
@@ -6,7 +6,6 @@
|
|
|
6
6
|
*
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
|
-
import './index.css';
|
|
10
9
|
import { useEffect, useRef, useState } from 'react';
|
|
11
10
|
import { $getNearestNodeFromDOMNode } from 'lexical';
|
|
12
11
|
import { createPortal } from 'react-dom';
|
|
@@ -119,8 +118,8 @@ function CodeActionMenuContainer({ anchorElem }: { anchorElem: HTMLElement }): J
|
|
|
119
118
|
return (
|
|
120
119
|
<>
|
|
121
120
|
{isShown ? (
|
|
122
|
-
<div className="code-action-menu-container" style={{ ...position }}>
|
|
123
|
-
<div className="code-highlight-language">{codeFriendlyName}</div>
|
|
121
|
+
<div className="c-rte-code-action-menu-container" style={{ ...position }}>
|
|
122
|
+
<div className="c-rte-code-highlight-language">{codeFriendlyName}</div>
|
|
124
123
|
<CopyButton editor={editor} getCodeDOMNode={getCodeDOMNode} />
|
|
125
124
|
{canBePrettier(normalizedLang) ? (
|
|
126
125
|
<PrettierButton editor={editor} getCodeDOMNode={getCodeDOMNode} lang={normalizedLang} />
|
|
@@ -139,7 +138,7 @@ function getMouseInfo(event: MouseEvent): {
|
|
|
139
138
|
|
|
140
139
|
if (target && target instanceof HTMLElement) {
|
|
141
140
|
const codeDOMNode = target.closest<HTMLElement>('code.CrystallizeRTEditorTheme__code');
|
|
142
|
-
const isOutside = !(codeDOMNode || target.closest<HTMLElement>('div.code-action-menu-container'));
|
|
141
|
+
const isOutside = !(codeDOMNode || target.closest<HTMLElement>('div.c-rte-code-action-menu-container'));
|
|
143
142
|
|
|
144
143
|
return { codeDOMNode, isOutside };
|
|
145
144
|
} else {
|
|
@@ -0,0 +1,49 @@
|
|
|
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
|
+
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
.draggable-block-menu {
|
|
1
|
+
.c-rte-draggable-block-menu {
|
|
2
2
|
border-radius: 4px;
|
|
3
3
|
padding: 2px 1px;
|
|
4
4
|
cursor: grab;
|
|
@@ -7,24 +7,24 @@
|
|
|
7
7
|
left: 0;
|
|
8
8
|
top: 0;
|
|
9
9
|
will-change: transform;
|
|
10
|
-
}
|
|
11
10
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
opacity: 0.3;
|
|
16
|
-
background-image: url(../../images/icons/draggable-block-menu.svg);
|
|
17
|
-
}
|
|
11
|
+
&:active {
|
|
12
|
+
cursor: grabbing;
|
|
13
|
+
}
|
|
18
14
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
}
|
|
15
|
+
&:hover {
|
|
16
|
+
background-color: #efefef;
|
|
17
|
+
}
|
|
22
18
|
|
|
23
|
-
|
|
24
|
-
|
|
19
|
+
&__icon {
|
|
20
|
+
width: 16px;
|
|
21
|
+
height: 16px;
|
|
22
|
+
opacity: 0.3;
|
|
23
|
+
background-image: url(../../images/icons/draggable-block-menu.svg);
|
|
24
|
+
}
|
|
25
25
|
}
|
|
26
26
|
|
|
27
|
-
.draggable-block-target-line {
|
|
27
|
+
.c-rte-draggable-block-target-line {
|
|
28
28
|
pointer-events: none;
|
|
29
29
|
background: deepskyblue;
|
|
30
30
|
height: 4px;
|