@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
|
@@ -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 { DragEvent as ReactDragEvent, useEffect, useRef, useState } from 'react';
|
|
11
11
|
import {
|
|
@@ -323,15 +323,15 @@ function useDraggableBlockMenu(editor: LexicalEditor, anchorElem: HTMLElement, i
|
|
|
323
323
|
return createPortal(
|
|
324
324
|
<>
|
|
325
325
|
<div
|
|
326
|
-
className="
|
|
326
|
+
className="c-rte-draggable-block-menu"
|
|
327
327
|
ref={menuRef}
|
|
328
328
|
draggable={true}
|
|
329
329
|
onDragStart={onDragStart}
|
|
330
330
|
onDragEnd={onDragEnd}
|
|
331
331
|
>
|
|
332
|
-
<div className={isEditable ? '
|
|
332
|
+
<div className={isEditable ? 'c-rte-draggable-block-menu__icon' : ''} />
|
|
333
333
|
</div>
|
|
334
|
-
<div className="draggable-block-target-line" ref={targetLineRef} />
|
|
334
|
+
<div className="c-rte-draggable-block-target-line" ref={targetLineRef} />
|
|
335
335
|
</>,
|
|
336
336
|
anchorElem,
|
|
337
337
|
);
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
.link-editor {
|
|
1
|
+
.c-rte-link-editor {
|
|
2
2
|
position: absolute;
|
|
3
3
|
top: 0;
|
|
4
4
|
left: 0;
|
|
@@ -11,30 +11,96 @@
|
|
|
11
11
|
border-radius: 8px;
|
|
12
12
|
transition: opacity 0.5s;
|
|
13
13
|
will-change: transform;
|
|
14
|
+
@apply !rounded-lg border border-solid border-gray-100-800 !shadow-lg;
|
|
14
15
|
}
|
|
15
16
|
|
|
16
|
-
.link-editor
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
17
|
+
.c-rte-link-editor-link-input {
|
|
18
|
+
@apply my-2 flex max-w-full flex-nowrap items-center justify-between gap-4 border-gray px-6 py-2 text-sm text-s-blue-600-300;
|
|
19
|
+
|
|
20
|
+
a {
|
|
21
|
+
@apply block overflow-hidden text-ellipsis whitespace-nowrap text-s-blue-600-300 no-underline;
|
|
22
|
+
|
|
23
|
+
&:hover {
|
|
24
|
+
@apply underline;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
.c-rte-link-editor-link-preview {
|
|
30
|
+
text-overflow: ellipsis;
|
|
31
|
+
white-space: nowrap;
|
|
32
|
+
overflow: hidden;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
.c-rte-link-editor-input-group {
|
|
36
|
+
@apply border-0 border-b border-solid border-gray-100-800 px-3;
|
|
24
37
|
}
|
|
25
38
|
|
|
26
|
-
.link-editor
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
39
|
+
.c-rte-link-editor-button-wrap {
|
|
40
|
+
@apply flex justify-end px-6 py-2;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
.c-rte-link-editor-preview-attrs {
|
|
44
|
+
@apply mt-1 flex gap-1;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
.c-rte-link-editor-preview-attr {
|
|
48
|
+
@apply rounded-md bg-purple-50-900 px-1 py-0.5 text-[10px] text-gray-600-300;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
53
|
+
*
|
|
54
|
+
* This source code is licensed under the MIT license found in the
|
|
55
|
+
* LICENSE file in the root directory of this source tree.
|
|
56
|
+
*
|
|
57
|
+
*
|
|
58
|
+
*/
|
|
59
|
+
|
|
60
|
+
@keyframes c-rte-glimmer-animation {
|
|
61
|
+
0% {
|
|
62
|
+
background: #f9f9f9;
|
|
63
|
+
}
|
|
64
|
+
.50% {
|
|
65
|
+
background: #eeeeee;
|
|
66
|
+
}
|
|
67
|
+
.100% {
|
|
68
|
+
background: #f9f9f9;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
.c-rte-link-preview {
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
.c-rte-link-preview-image-wrapper {
|
|
76
|
+
@apply bg-purple-50-900 text-center;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
.c-rte-link-preview-image {
|
|
80
|
+
@apply m-auto block max-h-[250px] max-w-full;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
.c-rte-link-preview-title {
|
|
84
|
+
@apply mx-6 mt-4 font-semibold leading-5 text-gray-700-200;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
.c-rte-link-preview-description {
|
|
88
|
+
@apply mx-6 mb-4 mt-2 text-sm leading-5;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
.c-rte-link-preview-glimmer {
|
|
92
|
+
background: #f9f9f9;
|
|
93
|
+
border-radius: 8px;
|
|
94
|
+
height: 18px;
|
|
95
|
+
margin-bottom: 8px;
|
|
96
|
+
margin-left: 12px;
|
|
97
|
+
margin-right: 12px;
|
|
98
|
+
animation-duration: 3s;
|
|
99
|
+
animation-iteration-count: infinite;
|
|
100
|
+
animation-timing-function: linear;
|
|
101
|
+
animation-name: c-rte-glimmer-animation;
|
|
31
102
|
}
|
|
32
103
|
|
|
33
|
-
.link-
|
|
34
|
-
|
|
35
|
-
background-size: contain;
|
|
36
|
-
display: inline-block;
|
|
37
|
-
height: 20px;
|
|
38
|
-
width: 20px;
|
|
39
|
-
vertical-align: -0.25em;
|
|
104
|
+
.c-rte-link-preview__replace-text-btn {
|
|
105
|
+
@apply mb-4 ml-5;
|
|
40
106
|
}
|
|
@@ -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 { Dispatch, useCallback, useEffect, useRef, useState } from 'react';
|
|
10
10
|
import * as React from 'react';
|
|
11
11
|
import {
|
|
@@ -185,10 +185,10 @@ function FloatingLinkEditor({
|
|
|
185
185
|
}, [isEditMode]);
|
|
186
186
|
|
|
187
187
|
return (
|
|
188
|
-
<div ref={editorRef} className="link-editor">
|
|
188
|
+
<div ref={editorRef} className="c-rte-link-editor">
|
|
189
189
|
{isEditMode ? (
|
|
190
190
|
<div>
|
|
191
|
-
<div className="
|
|
191
|
+
<div className="c-rte-link-editor-input-group">
|
|
192
192
|
<InputWithLabel
|
|
193
193
|
label={tr('linkEditorLink')}
|
|
194
194
|
type="text"
|
|
@@ -197,7 +197,7 @@ function FloatingLinkEditor({
|
|
|
197
197
|
/>
|
|
198
198
|
</div>
|
|
199
199
|
|
|
200
|
-
<div className="
|
|
200
|
+
<div className="c-rte-link-editor-input-group">
|
|
201
201
|
<InputWithLabel
|
|
202
202
|
label={tr('linkEditorRel')}
|
|
203
203
|
type="text"
|
|
@@ -205,7 +205,7 @@ function FloatingLinkEditor({
|
|
|
205
205
|
onChange={e => setRel(e.target.value)}
|
|
206
206
|
/>
|
|
207
207
|
</div>
|
|
208
|
-
<div className="
|
|
208
|
+
<div className="c-rte-link-editor-input-group">
|
|
209
209
|
<InputWithLabel
|
|
210
210
|
label={tr('linkEditorTarget')}
|
|
211
211
|
type="text"
|
|
@@ -213,7 +213,7 @@ function FloatingLinkEditor({
|
|
|
213
213
|
onChange={e => setTarget(e.target.value)}
|
|
214
214
|
/>
|
|
215
215
|
</div>
|
|
216
|
-
<div className="
|
|
216
|
+
<div className="c-rte-link-editor-button-wrap">
|
|
217
217
|
<Button
|
|
218
218
|
onClick={() => {
|
|
219
219
|
if (lastSelection !== null) {
|
|
@@ -234,21 +234,15 @@ function FloatingLinkEditor({
|
|
|
234
234
|
</div>
|
|
235
235
|
) : (
|
|
236
236
|
<>
|
|
237
|
-
<div className="
|
|
238
|
-
<div className="
|
|
237
|
+
<div className="c-rte-link-editor-link-input">
|
|
238
|
+
<div className="c-rte-link-editor-link-preview">
|
|
239
239
|
<a href={linkUrl} target="_blank" rel="noopener noreferrer">
|
|
240
240
|
{linkUrl}
|
|
241
241
|
</a>
|
|
242
242
|
{rel || target ? (
|
|
243
|
-
<div className="
|
|
244
|
-
{rel &&
|
|
245
|
-
|
|
246
|
-
)}
|
|
247
|
-
{target && (
|
|
248
|
-
<div className="text-[10px] text-gray-600-300 px-1 bg-purple-50-900 rounded-md py-0.5">
|
|
249
|
-
{target}
|
|
250
|
-
</div>
|
|
251
|
-
)}
|
|
243
|
+
<div className="c-rte-link-editor-preview-attrs">
|
|
244
|
+
{rel && <div className="c-rte-link-editor-preview-attr">{rel}</div>}
|
|
245
|
+
{target && <div className="c-rte-link-editor-preview-attr">{target}</div>}
|
|
252
246
|
</div>
|
|
253
247
|
) : null}
|
|
254
248
|
</div>
|
|
@@ -1,11 +1,19 @@
|
|
|
1
|
-
.c-floating-text-format-
|
|
1
|
+
.c-rte-floating-text-format-tb-plugin {
|
|
2
2
|
vertical-align: middle;
|
|
3
3
|
background-color: #fff;
|
|
4
4
|
transition: opacity 0.5s;
|
|
5
5
|
height: 43px;
|
|
6
6
|
will-change: transform;
|
|
7
7
|
box-sizing: border-box;
|
|
8
|
-
@apply absolute left-0 top-0 z-10 flex rounded-md bg-elevate p-1 opacity-0 shadow-md;
|
|
8
|
+
@apply absolute left-0 top-0 z-10 flex gap-0.5 rounded-md bg-elevate p-1 opacity-0 shadow-md;
|
|
9
|
+
|
|
10
|
+
&__format-icon {
|
|
11
|
+
@apply h-full w-full bg-[length:18px_18px] bg-center bg-no-repeat opacity-60;
|
|
12
|
+
|
|
13
|
+
&.selected {
|
|
14
|
+
@apply bg-purple-50-900 opacity-100;
|
|
15
|
+
}
|
|
16
|
+
}
|
|
9
17
|
}
|
|
10
18
|
|
|
11
19
|
.c-floating-text-format-popup button.popup-item {
|
|
@@ -134,7 +134,7 @@ function TextFormatFloatingToolbar({
|
|
|
134
134
|
}, [editor, updateTextFormatFloatingToolbar]);
|
|
135
135
|
|
|
136
136
|
return (
|
|
137
|
-
<div ref={popupCharStylesEditorRef} className="c-floating-text-format-
|
|
137
|
+
<div ref={popupCharStylesEditorRef} className="c-rte-floating-text-format-tb-plugin">
|
|
138
138
|
{editor.isEditable() && (
|
|
139
139
|
<>
|
|
140
140
|
<IconButton
|
|
@@ -146,8 +146,8 @@ function TextFormatFloatingToolbar({
|
|
|
146
146
|
aria-label={tr('actionFormatAsStrongLabel')}
|
|
147
147
|
>
|
|
148
148
|
<i
|
|
149
|
-
className={`
|
|
150
|
-
isBold ? '
|
|
149
|
+
className={`c-rte-icon-bold c-rte-floating-text-format-tb-plugin__format-icon ${
|
|
150
|
+
isBold ? 'selected' : ''
|
|
151
151
|
}`}
|
|
152
152
|
/>
|
|
153
153
|
</IconButton>
|
|
@@ -160,8 +160,8 @@ function TextFormatFloatingToolbar({
|
|
|
160
160
|
aria-label={tr('actionFormatAsEmphasizedLabel')}
|
|
161
161
|
>
|
|
162
162
|
<i
|
|
163
|
-
className={`
|
|
164
|
-
isItalic ? '
|
|
163
|
+
className={`c-rte-icon-italic c-rte-floating-text-format-tb-plugin__format-icon ${
|
|
164
|
+
isItalic ? 'selected' : ''
|
|
165
165
|
}`}
|
|
166
166
|
/>
|
|
167
167
|
</IconButton>
|
|
@@ -174,8 +174,8 @@ function TextFormatFloatingToolbar({
|
|
|
174
174
|
aria-label={tr('actionFormatAsUnderlinedLabel')}
|
|
175
175
|
>
|
|
176
176
|
<i
|
|
177
|
-
className={`
|
|
178
|
-
isUnderline ? '
|
|
177
|
+
className={`c-rte-icon-underline c-rte-floating-text-format-tb-plugin__format-icon ${
|
|
178
|
+
isUnderline ? 'selected' : ''
|
|
179
179
|
}`}
|
|
180
180
|
/>
|
|
181
181
|
</IconButton>
|
|
@@ -188,8 +188,8 @@ function TextFormatFloatingToolbar({
|
|
|
188
188
|
aria-label={tr('actionFormatWithStrikethroughLabel')}
|
|
189
189
|
>
|
|
190
190
|
<i
|
|
191
|
-
className={`
|
|
192
|
-
isStrikethrough ? '
|
|
191
|
+
className={`c-rte-icon-strikethrough c-rte-floating-text-format-tb-plugin__format-icon ${
|
|
192
|
+
isStrikethrough ? 'selected' : ''
|
|
193
193
|
}`}
|
|
194
194
|
/>
|
|
195
195
|
</IconButton>
|
|
@@ -202,8 +202,8 @@ function TextFormatFloatingToolbar({
|
|
|
202
202
|
aria-label={tr('actionFormatWithSubscriptLabel')}
|
|
203
203
|
>
|
|
204
204
|
<i
|
|
205
|
-
className={`
|
|
206
|
-
isSubscript ? '
|
|
205
|
+
className={`c-rte-icon-subscript c-rte-floating-text-format-tb-plugin__format-icon ${
|
|
206
|
+
isSubscript ? 'selected' : ''
|
|
207
207
|
}`}
|
|
208
208
|
/>
|
|
209
209
|
</IconButton>
|
|
@@ -216,8 +216,8 @@ function TextFormatFloatingToolbar({
|
|
|
216
216
|
aria-label={tr('actionFormatWithSuperscriptLabel')}
|
|
217
217
|
>
|
|
218
218
|
<i
|
|
219
|
-
className={`
|
|
220
|
-
isSuperscript ? '
|
|
219
|
+
className={`c-rte-icon-superscript c-rte-floating-text-format-tb-plugin__format-icon ${
|
|
220
|
+
isSuperscript ? 'selected' : ''
|
|
221
221
|
}`}
|
|
222
222
|
/>
|
|
223
223
|
</IconButton>
|
|
@@ -229,8 +229,8 @@ function TextFormatFloatingToolbar({
|
|
|
229
229
|
aria-label={tr('actionInsertCodeBlock')}
|
|
230
230
|
>
|
|
231
231
|
<i
|
|
232
|
-
className={`
|
|
233
|
-
isCode ? '
|
|
232
|
+
className={`c-rte-icon-code c-rte-floating-text-format-tb-plugin__format-icon ${
|
|
233
|
+
isCode ? 'selected' : ''
|
|
234
234
|
}`}
|
|
235
235
|
/>
|
|
236
236
|
</IconButton>
|
|
@@ -240,8 +240,8 @@ function TextFormatFloatingToolbar({
|
|
|
240
240
|
aria-label={tr('actionInsertlink')}
|
|
241
241
|
>
|
|
242
242
|
<i
|
|
243
|
-
className={`
|
|
244
|
-
isLink ? '
|
|
243
|
+
className={`c-rte-icon-link c-rte-floating-text-format-tb-plugin__format-icon ${
|
|
244
|
+
isLink ? 'selected' : ''
|
|
245
245
|
}`}
|
|
246
246
|
/>
|
|
247
247
|
</IconButton>
|
|
@@ -6,8 +6,8 @@
|
|
|
6
6
|
*
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
|
-
import { LinkPlugin as LexicalLinkPlugin } from '@lexical/react/LexicalLinkPlugin';
|
|
10
9
|
import * as React from 'react';
|
|
10
|
+
import { LinkPlugin as LexicalLinkPlugin } from '@lexical/react/LexicalLinkPlugin';
|
|
11
11
|
|
|
12
12
|
import { validateUrl } from '../../utils/url';
|
|
13
13
|
|
|
@@ -6,10 +6,7 @@
|
|
|
6
6
|
*
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
|
-
import
|
|
10
|
-
|
|
11
|
-
import {$getListDepth, $isListItemNode, $isListNode} from '@lexical/list';
|
|
12
|
-
import {useLexicalComposerContext} from '@lexical/react/LexicalComposerContext';
|
|
9
|
+
import { useEffect } from 'react';
|
|
13
10
|
import {
|
|
14
11
|
$getSelection,
|
|
15
12
|
$isElementNode,
|
|
@@ -17,28 +14,23 @@ import {
|
|
|
17
14
|
COMMAND_PRIORITY_CRITICAL,
|
|
18
15
|
ElementNode,
|
|
19
16
|
INDENT_CONTENT_COMMAND,
|
|
17
|
+
type RangeSelection,
|
|
20
18
|
} from 'lexical';
|
|
21
|
-
import {
|
|
19
|
+
import { $getListDepth, $isListItemNode, $isListNode } from '@lexical/list';
|
|
20
|
+
import { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext';
|
|
22
21
|
|
|
23
22
|
type Props = Readonly<{
|
|
24
23
|
maxDepth: number | null | undefined;
|
|
25
24
|
}>;
|
|
26
25
|
|
|
27
|
-
function getElementNodesInSelection(
|
|
28
|
-
selection: RangeSelection,
|
|
29
|
-
): Set<ElementNode> {
|
|
26
|
+
function getElementNodesInSelection(selection: RangeSelection): Set<ElementNode> {
|
|
30
27
|
const nodesInSelection = selection.getNodes();
|
|
31
28
|
|
|
32
29
|
if (nodesInSelection.length === 0) {
|
|
33
|
-
return new Set([
|
|
34
|
-
selection.anchor.getNode().getParentOrThrow(),
|
|
35
|
-
selection.focus.getNode().getParentOrThrow(),
|
|
36
|
-
]);
|
|
30
|
+
return new Set([selection.anchor.getNode().getParentOrThrow(), selection.focus.getNode().getParentOrThrow()]);
|
|
37
31
|
}
|
|
38
32
|
|
|
39
|
-
return new Set(
|
|
40
|
-
nodesInSelection.map((n) => ($isElementNode(n) ? n : n.getParentOrThrow())),
|
|
41
|
-
);
|
|
33
|
+
return new Set(nodesInSelection.map(n => ($isElementNode(n) ? n : n.getParentOrThrow())));
|
|
42
34
|
}
|
|
43
35
|
|
|
44
36
|
function isIndentPermitted(maxDepth: number): boolean {
|
|
@@ -48,8 +40,7 @@ function isIndentPermitted(maxDepth: number): boolean {
|
|
|
48
40
|
return false;
|
|
49
41
|
}
|
|
50
42
|
|
|
51
|
-
const elementNodesInSelection: Set<ElementNode> =
|
|
52
|
-
getElementNodesInSelection(selection);
|
|
43
|
+
const elementNodesInSelection: Set<ElementNode> = getElementNodesInSelection(selection);
|
|
53
44
|
|
|
54
45
|
let totalDepth = 0;
|
|
55
46
|
|
|
@@ -60,9 +51,7 @@ function isIndentPermitted(maxDepth: number): boolean {
|
|
|
60
51
|
const parent = elementNode.getParent();
|
|
61
52
|
|
|
62
53
|
if (!$isListNode(parent)) {
|
|
63
|
-
throw new Error(
|
|
64
|
-
'ListMaxIndentLevelPlugin: A ListItemNode must have a ListNode for a parent.',
|
|
65
|
-
);
|
|
54
|
+
throw new Error('ListMaxIndentLevelPlugin: A ListItemNode must have a ListNode for a parent.');
|
|
66
55
|
}
|
|
67
56
|
|
|
68
57
|
totalDepth = Math.max($getListDepth(parent) + 1, totalDepth);
|
|
@@ -72,7 +61,7 @@ function isIndentPermitted(maxDepth: number): boolean {
|
|
|
72
61
|
return totalDepth <= maxDepth;
|
|
73
62
|
}
|
|
74
63
|
|
|
75
|
-
export default function ListMaxIndentLevelPlugin({maxDepth}: Props): null {
|
|
64
|
+
export default function ListMaxIndentLevelPlugin({ maxDepth }: Props): null {
|
|
76
65
|
const [editor] = useLexicalComposerContext();
|
|
77
66
|
|
|
78
67
|
useEffect(() => {
|
|
@@ -396,13 +396,13 @@ function TableCellActionMenuContainer({ anchorElem }: { anchorElem: HTMLElement
|
|
|
396
396
|
}, [menuButtonRef, tableCellNode, editor, anchorElem]);
|
|
397
397
|
|
|
398
398
|
return (
|
|
399
|
-
<div className="table-cell-action-button-container" ref={menuButtonRef}>
|
|
399
|
+
<div className="c-rte-table-cell-action-button-container" ref={menuButtonRef}>
|
|
400
400
|
{tableCellNode != null && (
|
|
401
401
|
<DropdownMenu.Root
|
|
402
402
|
onOpenChange={isOpen => setIsMenuOpen(isOpen)}
|
|
403
403
|
content={<TableActionMenu tableCellNode={tableCellNode} tableStats={tableStats} />}
|
|
404
404
|
>
|
|
405
|
-
<IconButton size="xs"
|
|
405
|
+
<IconButton size="xs" aria-label={tr('actionTableOpenOptions')}>
|
|
406
406
|
<Icon.Arrow />
|
|
407
407
|
</IconButton>
|
|
408
408
|
</DropdownMenu.Root>
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
.c-rte-toolbar {
|
|
2
|
+
@apply flex h-12 w-full justify-between overflow-auto rounded-tl-md rounded-tr-md py-1 pl-4 pr-2 align-middle;
|
|
3
|
+
|
|
4
|
+
&__inner {
|
|
5
|
+
@apply flex;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
&__icon {
|
|
9
|
+
@apply h-6 w-4 border bg-[length:17px_17px] bg-center bg-no-repeat;
|
|
10
|
+
|
|
11
|
+
&.disabled {
|
|
12
|
+
@apply opacity-30;
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
&__block-format__icon {
|
|
17
|
+
@apply h-6 w-6 rounded-md border bg-[length:18px_18px] bg-center bg-no-repeat opacity-60;
|
|
18
|
+
|
|
19
|
+
&.selected {
|
|
20
|
+
@apply bg-purple-50-900 opacity-100;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
&__block-format__text {
|
|
25
|
+
@apply min-w-[150px] px-3 text-sm font-normal;
|
|
26
|
+
|
|
27
|
+
&.selected {
|
|
28
|
+
@apply font-bold;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
&__toggle-icon {
|
|
33
|
+
@apply h-6 w-6 border bg-[length:18px_18px] bg-center bg-no-repeat;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
&__code-lang {
|
|
37
|
+
&__button-text {
|
|
38
|
+
@apply text-sm font-medium;
|
|
39
|
+
}
|
|
40
|
+
&__sel-item {
|
|
41
|
+
@apply block min-w-[200px] px-3 text-sm font-normal opacity-80;
|
|
42
|
+
|
|
43
|
+
&.selected {
|
|
44
|
+
@apply font-bold opacity-100;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
&__divider {
|
|
50
|
+
width: 1px;
|
|
51
|
+
background-color: #eee;
|
|
52
|
+
margin: 0 4px;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
&__actions-rest {
|
|
56
|
+
@apply flex gap-1;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
&__icon-btn {
|
|
60
|
+
@apply opacity-60;
|
|
61
|
+
|
|
62
|
+
&.selected {
|
|
63
|
+
@apply !bg-purple-50-900 opacity-100;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
&__icon {
|
|
67
|
+
@apply h-full w-full border bg-[length:18px_18px] bg-center bg-no-repeat;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
&__dd-item {
|
|
72
|
+
&__icon {
|
|
73
|
+
@apply h-6 w-6 rounded-sm border bg-[length:16px_16px] bg-center bg-no-repeat opacity-60;
|
|
74
|
+
|
|
75
|
+
&.selected {
|
|
76
|
+
@apply !bg-purple-50-900 opacity-100;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
&__text {
|
|
80
|
+
@apply px-3 font-sans text-sm font-normal;
|
|
81
|
+
|
|
82
|
+
&.selected {
|
|
83
|
+
@apply font-medium;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
&--clear {
|
|
87
|
+
@apply ml-3 text-pink-600-300;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
&--table {
|
|
92
|
+
@apply flex items-center font-sans font-normal;
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
&__plus {
|
|
97
|
+
@apply h-full w-full border bg-[length:20px_20px] bg-center bg-no-repeat;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
.c-rte-insert-table {
|
|
102
|
+
@apply items-center justify-between;
|
|
103
|
+
|
|
104
|
+
&__dimensions {
|
|
105
|
+
@apply grid grid-cols-[1fr_1px_1fr] rounded-md border border-solid border-gray-100-800 shadow-sm;
|
|
106
|
+
|
|
107
|
+
&__separator {
|
|
108
|
+
@apply h-full bg-gray-100-800;
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
&__actions {
|
|
113
|
+
@apply mt-3 flex justify-end;
|
|
114
|
+
}
|
|
115
|
+
}
|