torch-glare 2.4.0 → 2.4.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/README.md +8 -0
- package/apps/lib/components/ActionButton.tsx +7 -12
- package/apps/lib/components/ActionsGroup.tsx +4 -15
- package/apps/lib/components/AlertDialog.tsx +173 -191
- package/apps/lib/components/Avatar.tsx +13 -16
- package/apps/lib/components/Badge.tsx +1 -3
- package/apps/lib/components/BadgeField.tsx +76 -71
- package/apps/lib/components/Breadcrumb.tsx +49 -85
- package/apps/lib/components/Button.tsx +20 -19
- package/apps/lib/components/ButtonGroup.tsx +31 -41
- package/apps/lib/components/Calendar.tsx +51 -29
- package/apps/lib/components/Card.tsx +2 -13
- package/apps/lib/components/ChartBlockTool.ts +17 -52
- package/apps/lib/components/Checkbox.tsx +9 -16
- package/apps/lib/components/ContextMenu.tsx +97 -96
- package/apps/lib/components/CountBadge.tsx +4 -6
- package/apps/lib/components/DataTable.tsx +196 -216
- package/apps/lib/components/DataViews/DataViewRadio.tsx +1 -6
- package/apps/lib/components/DataViews/DataViewsConfigPanel.tsx +13 -47
- package/apps/lib/components/DataViews/DataViewsHeader.tsx +1 -3
- package/apps/lib/components/DataViews/DataViewsLayout.tsx +5 -12
- package/apps/lib/components/DataViews/FilterPanel.tsx +155 -149
- package/apps/lib/components/DataViews/HeaderSearch.tsx +1 -5
- package/apps/lib/components/DataViews/InboxView.tsx +22 -68
- package/apps/lib/components/DataViews/InboxViewCard.tsx +68 -77
- package/apps/lib/components/DataViews/KanbanView.tsx +8 -25
- package/apps/lib/components/DataViews/PanelControls.tsx +3 -13
- package/apps/lib/components/DataViews/SettingsPanel.tsx +83 -89
- package/apps/lib/components/DataViews/TableView.tsx +8 -28
- package/apps/lib/components/DataViews/TreeView.tsx +12 -40
- package/apps/lib/components/DataViews/badgeAdapter.ts +32 -28
- package/apps/lib/components/DataViews/fieldRenderers.tsx +106 -141
- package/apps/lib/components/DataViews/filters/DatePickerRangeFilter.tsx +30 -23
- package/apps/lib/components/DataViews/filters/DateRangePopover.tsx +39 -32
- package/apps/lib/components/DataViews/filters/PresetChips.tsx +15 -15
- package/apps/lib/components/DataViews/filters/RangeSliderWithInputs.tsx +69 -58
- package/apps/lib/components/DataViews/index.ts +26 -26
- package/apps/lib/components/DataViews/tree/TreeDrawer.tsx +12 -16
- package/apps/lib/components/DataViews/tree/TreeSidebar.tsx +28 -31
- package/apps/lib/components/DataViews/types.ts +104 -115
- package/apps/lib/components/DatePicker.tsx +198 -196
- package/apps/lib/components/Dialog.tsx +92 -105
- package/apps/lib/components/Divider.tsx +21 -24
- package/apps/lib/components/Drawer.tsx +79 -139
- package/apps/lib/components/DropdownMenu.tsx +131 -171
- package/apps/lib/components/FieldHint.tsx +4 -11
- package/apps/lib/components/Form.tsx +146 -155
- package/apps/lib/components/FormStepper.tsx +9 -39
- package/apps/lib/components/HeaderBar.tsx +1 -9
- package/apps/lib/components/ImageAttachment.tsx +111 -73
- package/apps/lib/components/InnerLabelField.tsx +20 -16
- package/apps/lib/components/Input.tsx +171 -172
- package/apps/lib/components/InputField.tsx +44 -45
- package/apps/lib/components/InputOTP.tsx +68 -69
- package/apps/lib/components/Label.tsx +31 -35
- package/apps/lib/components/LabelField.tsx +4 -5
- package/apps/lib/components/LabeledCheckBox.tsx +8 -12
- package/apps/lib/components/LabeledRadio.tsx +7 -5
- package/apps/lib/components/LinkButton.tsx +2 -9
- package/apps/lib/components/LoginButton.tsx +4 -9
- package/apps/lib/components/PasswordLevel.tsx +5 -5
- package/apps/lib/components/Popover.tsx +15 -33
- package/apps/lib/components/ProfileMenu.tsx +67 -72
- package/apps/lib/components/Radio.tsx +1 -5
- package/apps/lib/components/RadioCard.tsx +9 -28
- package/apps/lib/components/ScrollArea.tsx +45 -43
- package/apps/lib/components/SearchField.tsx +49 -39
- package/apps/lib/components/SearchableSelect.tsx +8 -14
- package/apps/lib/components/SearchableTable.tsx +108 -118
- package/apps/lib/components/SearchableTree.tsx +469 -0
- package/apps/lib/components/SearchableTreeDialog.tsx +493 -0
- package/apps/lib/components/SectionBlock.tsx +4 -16
- package/apps/lib/components/Select.tsx +53 -80
- package/apps/lib/components/SimpleSelect.tsx +196 -187
- package/apps/lib/components/Skeleton.tsx +9 -12
- package/apps/lib/components/SlideDatePicker.tsx +215 -166
- package/apps/lib/components/SpinLoading.tsx +33 -49
- package/apps/lib/components/Stepper.tsx +13 -56
- package/apps/lib/components/Switch.tsx +8 -10
- package/apps/lib/components/TabFormItem.tsx +3 -12
- package/apps/lib/components/TabSwitch.tsx +7 -34
- package/apps/lib/components/Table.tsx +60 -75
- package/apps/lib/components/TableDnDWrapper.ts +15 -48
- package/apps/lib/components/TextEditor.tsx +93 -104
- package/apps/lib/components/Textarea.tsx +8 -12
- package/apps/lib/components/Timeline.tsx +21 -41
- package/apps/lib/components/Toast.tsx +83 -83
- package/apps/lib/components/Toggle.tsx +112 -114
- package/apps/lib/components/ToggleButton.tsx +1 -1
- package/apps/lib/components/Tooltip.tsx +24 -19
- package/apps/lib/components/TransparentLabel.tsx +61 -62
- package/apps/lib/components/TreeDropDown.tsx +86 -52
- package/apps/lib/components/TreeFolder/TreeFolder.tsx +15 -48
- package/apps/lib/components/TreeFolder/TreeFolderBreadcrumb.tsx +16 -21
- package/apps/lib/components/TreeFolder/TreeFolderRow.tsx +9 -20
- package/apps/lib/components/TreeFolder/TreeFolderStyles.tsx +3 -3
- package/apps/lib/components/TreeFolder/icons.tsx +14 -17
- package/apps/lib/components/TreeFolder/index.ts +15 -8
- package/apps/lib/components/TreeFolder/treeFolderUtils.ts +47 -52
- package/apps/lib/components/TreeFolder/types.ts +32 -32
- package/apps/lib/components/TreeFolder/useTreeFolderDnD.ts +117 -123
- package/apps/lib/hooks/useActiveTreeItem.ts +52 -55
- package/apps/lib/hooks/useClickOutside.ts +21 -20
- package/apps/lib/hooks/useDataViewsState.ts +86 -80
- package/apps/lib/hooks/useIsMobile.ts +12 -12
- package/apps/lib/hooks/useResize.ts +54 -65
- package/apps/lib/hooks/useTagSelection.ts +201 -201
- package/apps/lib/layouts/CNLayout.tsx +181 -140
- package/apps/lib/layouts/DataViewCard.tsx +4 -18
- package/apps/lib/layouts/FieldSection.tsx +2 -6
- package/apps/lib/layouts/TreeSubLayout.tsx +24 -38
- package/apps/lib/providers/ThemeProvider.tsx +8 -23
- package/apps/lib/registry.json +1004 -0
- package/apps/lib/tsconfig.json +9 -0
- package/apps/lib/utils/cn.ts +1 -1
- package/apps/lib/utils/dataViews/columnUtils.ts +46 -44
- package/apps/lib/utils/dataViews/fieldUtils.ts +70 -71
- package/apps/lib/utils/dataViews/nestedDataUtils.tsx +129 -122
- package/apps/lib/utils/dataViews/pathUtils.ts +74 -67
- package/apps/lib/utils/dataViews/rangeUtils.ts +121 -112
- package/apps/lib/utils/dataViews/treeUtils.ts +204 -211
- package/apps/lib/utils/dateFormat.ts +64 -54
- package/apps/lib/utils/markdownParser.ts +2 -7
- package/apps/lib/utils/resize.ts +21 -25
- package/apps/lib/utils/types.ts +13 -13
- package/dist/bin/index.js +8 -2
- package/dist/bin/index.js.map +1 -1
- package/dist/src/shared/getAvailableFiles.d.ts.map +1 -1
- package/dist/src/shared/getAvailableFiles.js +6 -1
- package/dist/src/shared/getAvailableFiles.js.map +1 -1
- package/dist/src/shared/loadRegistry.d.ts +7 -0
- package/dist/src/shared/loadRegistry.d.ts.map +1 -0
- package/dist/src/shared/loadRegistry.js +31 -0
- package/dist/src/shared/loadRegistry.js.map +1 -0
- package/dist/src/shared/resolveInstallPlan.d.ts +12 -0
- package/dist/src/shared/resolveInstallPlan.d.ts.map +1 -0
- package/dist/src/shared/resolveInstallPlan.js +39 -0
- package/dist/src/shared/resolveInstallPlan.js.map +1 -0
- package/dist/src/types/main.d.ts +24 -0
- package/dist/src/types/main.d.ts.map +1 -1
- package/docs/README.md +10 -2
- package/docs/components/action-button.md +30 -24
- package/docs/components/actions-group.md +26 -20
- package/docs/components/alert-dialog.md +45 -45
- package/docs/components/avatar.md +6 -2
- package/docs/components/badge-field.md +6 -2
- package/docs/components/badge.md +7 -1
- package/docs/components/breadcrumb.md +15 -40
- package/docs/components/button-group.md +13 -10
- package/docs/components/button.md +58 -33
- package/docs/components/calendar.md +26 -19
- package/docs/components/card.md +19 -16
- package/docs/components/chart-block-tool.md +128 -0
- package/docs/components/checkbox.md +16 -8
- package/docs/components/cn-layout.md +7 -1
- package/docs/components/context-menu.md +18 -25
- package/docs/components/count-badge.md +7 -1
- package/docs/components/data-table.md +45 -33
- package/docs/components/data-views-config-panel.md +15 -11
- package/docs/components/data-views-layout.md +13 -16
- package/docs/components/date-picker.md +30 -23
- package/docs/components/dialog.md +43 -42
- package/docs/components/divider.md +10 -4
- package/docs/components/drawer.md +8 -33
- package/docs/components/dropdown-menu.md +25 -34
- package/docs/components/field-hint.md +37 -25
- package/docs/components/field-section.md +9 -3
- package/docs/components/form-stepper.md +6 -0
- package/docs/components/form.md +17 -20
- package/docs/components/header-bar.md +6 -0
- package/docs/components/image-attachment.md +33 -41
- package/docs/components/inbox-view.md +16 -5
- package/docs/components/inner-label-field.md +34 -24
- package/docs/components/input-field.md +18 -10
- package/docs/components/input-otp.md +14 -11
- package/docs/components/input.md +22 -16
- package/docs/components/kanban-view.md +15 -5
- package/docs/components/label-field.md +32 -22
- package/docs/components/label.md +43 -32
- package/docs/components/labeled-check-box.md +16 -8
- package/docs/components/labeled-radio.md +18 -11
- package/docs/components/link-button.md +7 -1
- package/docs/components/login-button.md +8 -2
- package/docs/components/password-level.md +37 -24
- package/docs/components/popover.md +26 -23
- package/docs/components/profile-menu.md +38 -27
- package/docs/components/radio-card.md +16 -9
- package/docs/components/radio.md +16 -8
- package/docs/components/scroll-area.md +6 -2
- package/docs/components/search-field.md +14 -6
- package/docs/components/searchable-select.md +19 -14
- package/docs/components/searchable-table.md +18 -13
- package/docs/components/searchable-tree-dialog.md +190 -0
- package/docs/components/searchable-tree.md +200 -0
- package/docs/components/section-block.md +12 -4
- package/docs/components/select.md +23 -18
- package/docs/components/simple-select.md +14 -10
- package/docs/components/skeleton.md +43 -33
- package/docs/components/slide-date-picker.md +37 -29
- package/docs/components/spin-loading.md +32 -23
- package/docs/components/stepper.md +6 -0
- package/docs/components/switch.md +14 -6
- package/docs/components/tab-form-item.md +7 -1
- package/docs/components/tab-switch.md +13 -6
- package/docs/components/table-dnd-wrapper.md +105 -0
- package/docs/components/table-view.md +15 -5
- package/docs/components/table.md +28 -28
- package/docs/components/text-editor.md +19 -13
- package/docs/components/textarea.md +15 -7
- package/docs/components/timeline.md +6 -0
- package/docs/components/toast.md +35 -26
- package/docs/components/toggle-button.md +24 -21
- package/docs/components/toggle.md +23 -15
- package/docs/components/tooltip.md +42 -30
- package/docs/components/transparent-label.md +29 -20
- package/docs/components/tree-drop-down.md +31 -23
- package/docs/components/tree-sub-layout.md +6 -2
- package/docs/components/tree-view.md +16 -5
- package/docs/explanation/architecture.md +54 -0
- package/docs/explanation/design-system.md +52 -0
- package/docs/how-to/data-views-from-backend-response.md +6 -4
- package/docs/how-to/guides.md +24 -18
- package/docs/migration/changelog.md +38 -0
- package/docs/reference/cli.md +87 -0
- package/docs/reference/components.md +11 -12
- package/docs/reference/hooks.md +8 -8
- package/docs/reference/providers.md +22 -22
- package/docs/reference/tailwind-plugins.md +2 -2
- package/docs/reference/theme.md +85 -0
- package/docs/reference/types.md +4 -4
- package/docs/reference/utilities.md +19 -26
- package/docs/tutorials/building-first-form.md +20 -13
- package/docs/tutorials/component-composition.md +34 -50
- package/docs/tutorials/getting-started.md +2 -2
- package/docs/tutorials/theming-basics.md +13 -10
- package/package.json +31 -3
- package/dist/src/commands/block.d.ts +0 -5
- package/dist/src/commands/block.d.ts.map +0 -1
- package/dist/src/commands/block.js +0 -255
- package/dist/src/commands/block.js.map +0 -1
- package/dist/src/shared/configureFonts.d.ts +0 -6
- package/dist/src/shared/configureFonts.d.ts.map +0 -1
- package/dist/src/shared/configureFonts.js +0 -106
- package/dist/src/shared/configureFonts.js.map +0 -1
- package/dist/src/shared/configureGlobalCss.d.ts +0 -6
- package/dist/src/shared/configureGlobalCss.d.ts.map +0 -1
- package/dist/src/shared/configureGlobalCss.js +0 -154
- package/dist/src/shared/configureGlobalCss.js.map +0 -1
- package/dist/src/shared/configureTailwind.d.ts +0 -7
- package/dist/src/shared/configureTailwind.d.ts.map +0 -1
- package/dist/src/shared/configureTailwind.js +0 -163
- package/dist/src/shared/configureTailwind.js.map +0 -1
- package/dist/src/shared/detectFramework.d.ts +0 -23
- package/dist/src/shared/detectFramework.d.ts.map +0 -1
- package/dist/src/shared/detectFramework.js +0 -119
- package/dist/src/shared/detectFramework.js.map +0 -1
- package/dist/src/shared/installBaseUtils.d.ts +0 -5
- package/dist/src/shared/installBaseUtils.d.ts.map +0 -1
- package/dist/src/shared/installBaseUtils.js +0 -79
- package/dist/src/shared/installBaseUtils.js.map +0 -1
- package/dist/src/shared/resolveAliases.d.ts +0 -24
- package/dist/src/shared/resolveAliases.d.ts.map +0 -1
- package/dist/src/shared/resolveAliases.js +0 -98
- package/dist/src/shared/resolveAliases.js.map +0 -1
|
@@ -66,7 +66,10 @@ function setDirIfChanged(el: HTMLElement, dir: "rtl" | "ltr") {
|
|
|
66
66
|
}
|
|
67
67
|
}
|
|
68
68
|
|
|
69
|
-
function applyDirectionToBlock(
|
|
69
|
+
function applyDirectionToBlock(
|
|
70
|
+
block: HTMLElement,
|
|
71
|
+
fallbackDir: "rtl" | "ltr" = "ltr",
|
|
72
|
+
): "rtl" | "ltr" {
|
|
70
73
|
// Skip non-text blocks (delimiters, embeds, code)
|
|
71
74
|
if (block.querySelector(".ce-delimiter, .cdx-embed, .embed-tool")) return fallbackDir;
|
|
72
75
|
|
|
@@ -78,9 +81,7 @@ function applyDirectionToBlock(block: HTMLElement, fallbackDir: "rtl" | "ltr" =
|
|
|
78
81
|
if (listItems.length > 0) {
|
|
79
82
|
let prevDir: "rtl" | "ltr" = fallbackDir;
|
|
80
83
|
listItems.forEach((item) => {
|
|
81
|
-
const editable = item.querySelector<HTMLElement>(
|
|
82
|
-
'[contenteditable="true"]',
|
|
83
|
-
);
|
|
84
|
+
const editable = item.querySelector<HTMLElement>('[contenteditable="true"]');
|
|
84
85
|
if (!editable) return;
|
|
85
86
|
const text = (editable.textContent || "").trim();
|
|
86
87
|
const dir = text ? getTextDirection(text) : prevDir;
|
|
@@ -93,9 +94,7 @@ function applyDirectionToBlock(block: HTMLElement, fallbackDir: "rtl" | "ltr" =
|
|
|
93
94
|
|
|
94
95
|
// Handle regular blocks (paragraph, header, quote, warning, etc.)
|
|
95
96
|
let lastDir = fallbackDir;
|
|
96
|
-
const editables = block.querySelectorAll<HTMLElement>(
|
|
97
|
-
'[contenteditable="true"]',
|
|
98
|
-
);
|
|
97
|
+
const editables = block.querySelectorAll<HTMLElement>('[contenteditable="true"]');
|
|
99
98
|
editables.forEach((el) => {
|
|
100
99
|
const text = (el.textContent || "").trim();
|
|
101
100
|
const dir = text ? getTextDirection(text) : fallbackDir;
|
|
@@ -169,7 +168,7 @@ const getDefaultTools = (): Record<string, any> => ({
|
|
|
169
168
|
linkTool: { class: LinkTool },
|
|
170
169
|
image: { class: SimpleImage },
|
|
171
170
|
raw: { class: RawTool },
|
|
172
|
-
chart: { class: ChartBlockTool
|
|
171
|
+
chart: { class: ChartBlockTool },
|
|
173
172
|
marker: { class: Marker, shortcut: "CMD+SHIFT+M" },
|
|
174
173
|
inlineCode: { class: InlineCode, shortcut: "CMD+SHIFT+I" },
|
|
175
174
|
underline: { class: Underline },
|
|
@@ -754,9 +753,7 @@ export interface TextEditorRef {
|
|
|
754
753
|
}
|
|
755
754
|
|
|
756
755
|
interface TextEditorProps
|
|
757
|
-
extends
|
|
758
|
-
Omit<HTMLAttributes<HTMLDivElement>, "onChange">,
|
|
759
|
-
VariantProps<typeof textEditorStyles> {
|
|
756
|
+
extends Omit<HTMLAttributes<HTMLDivElement>, "onChange">, VariantProps<typeof textEditorStyles> {
|
|
760
757
|
theme?: Themes;
|
|
761
758
|
data?: OutputData;
|
|
762
759
|
onChange?: (data: OutputData) => void;
|
|
@@ -793,9 +790,7 @@ export const TextEditor = forwardRef<TextEditorRef, TextEditorProps>(
|
|
|
793
790
|
const editorRef = useRef<EditorJS | null>(null);
|
|
794
791
|
const holderRef = useRef<HTMLDivElement>(null);
|
|
795
792
|
const observerRef = useRef<MutationObserver | null>(null);
|
|
796
|
-
const [holderId] = useState(
|
|
797
|
-
() => `torch-editor-${Math.random().toString(36).substring(2, 9)}`,
|
|
798
|
-
);
|
|
793
|
+
const [holderId] = useState(() => `torch-editor-${Math.random().toString(36).substring(2, 9)}`);
|
|
799
794
|
const isInitializing = useRef(false);
|
|
800
795
|
const pasteHandlerRef = useRef<((e: ClipboardEvent) => void) | null>(null);
|
|
801
796
|
const saveTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null);
|
|
@@ -839,107 +834,104 @@ export const TextEditor = forwardRef<TextEditorRef, TextEditorProps>(
|
|
|
839
834
|
}, []);
|
|
840
835
|
|
|
841
836
|
// ── Markdown paste handler ──
|
|
842
|
-
const setupMarkdownPaste = useCallback(
|
|
843
|
-
(
|
|
844
|
-
|
|
845
|
-
if (readOnlyRef.current || !editorRef.current) return;
|
|
837
|
+
const setupMarkdownPaste = useCallback((holderEl: HTMLElement) => {
|
|
838
|
+
const handler = async (e: ClipboardEvent) => {
|
|
839
|
+
if (readOnlyRef.current || !editorRef.current) return;
|
|
846
840
|
|
|
847
|
-
|
|
841
|
+
const plain = e.clipboardData?.getData("text/plain") || "";
|
|
848
842
|
|
|
849
|
-
|
|
850
|
-
|
|
843
|
+
// Only intercept if the plain text is markdown
|
|
844
|
+
if (!isMarkdown(plain)) return;
|
|
851
845
|
|
|
852
|
-
|
|
853
|
-
|
|
846
|
+
e.preventDefault();
|
|
847
|
+
e.stopPropagation();
|
|
854
848
|
|
|
855
|
-
|
|
856
|
-
|
|
849
|
+
const parsedBlocks = parseMarkdownToBlocks(plain);
|
|
850
|
+
if (parsedBlocks.length === 0) return;
|
|
857
851
|
|
|
858
|
-
|
|
852
|
+
const editor = editorRef.current;
|
|
859
853
|
|
|
860
|
-
|
|
861
|
-
|
|
854
|
+
// Save existing content, merge new blocks at cursor, render once
|
|
855
|
+
// This avoids per-block insert which freezes the editor on large pastes
|
|
856
|
+
try {
|
|
857
|
+
const existingData = await editor.save();
|
|
858
|
+
const existingBlocks = existingData.blocks || [];
|
|
859
|
+
|
|
860
|
+
// Determine insertion point
|
|
861
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
862
|
+
const blocks = (editor as any).blocks;
|
|
863
|
+
let insertIdx = existingBlocks.length;
|
|
862
864
|
try {
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
// Determine insertion point
|
|
867
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
868
|
-
const blocks = (editor as any).blocks;
|
|
869
|
-
let insertIdx = existingBlocks.length;
|
|
870
|
-
try {
|
|
871
|
-
if (blocks?.getCurrentBlockIndex) {
|
|
872
|
-
insertIdx = blocks.getCurrentBlockIndex() + 1;
|
|
873
|
-
}
|
|
874
|
-
} catch {
|
|
875
|
-
// Use end of document
|
|
865
|
+
if (blocks?.getCurrentBlockIndex) {
|
|
866
|
+
insertIdx = blocks.getCurrentBlockIndex() + 1;
|
|
876
867
|
}
|
|
868
|
+
} catch {
|
|
869
|
+
// Use end of document
|
|
870
|
+
}
|
|
877
871
|
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
}
|
|
872
|
+
// Convert parsed blocks to OutputData block format
|
|
873
|
+
const newBlocks = parsedBlocks.map((block) => ({
|
|
874
|
+
type: block.type,
|
|
875
|
+
data: block.data,
|
|
876
|
+
}));
|
|
877
|
+
|
|
878
|
+
// Remove empty paragraph at cursor if it's the only content there
|
|
879
|
+
const filteredExisting = [...existingBlocks];
|
|
880
|
+
if (insertIdx > 0) {
|
|
881
|
+
const cursorBlock = filteredExisting[insertIdx - 1];
|
|
882
|
+
if (
|
|
883
|
+
cursorBlock &&
|
|
884
|
+
cursorBlock.type === "paragraph" &&
|
|
885
|
+
(!cursorBlock.data.text ||
|
|
886
|
+
cursorBlock.data.text.trim() === "" ||
|
|
887
|
+
cursorBlock.data.text === "<br>")
|
|
888
|
+
) {
|
|
889
|
+
filteredExisting.splice(insertIdx - 1, 1);
|
|
890
|
+
insertIdx = Math.max(0, insertIdx - 1);
|
|
898
891
|
}
|
|
892
|
+
}
|
|
899
893
|
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
894
|
+
// Merge: existing blocks before cursor + new blocks + existing blocks after cursor
|
|
895
|
+
const mergedBlocks = [
|
|
896
|
+
...filteredExisting.slice(0, insertIdx),
|
|
897
|
+
...newBlocks,
|
|
898
|
+
...filteredExisting.slice(insertIdx),
|
|
899
|
+
];
|
|
900
|
+
|
|
901
|
+
// Pause MutationObserver during bulk render to prevent O(n^2) direction checks
|
|
902
|
+
observerRef.current?.disconnect();
|
|
903
|
+
|
|
904
|
+
// Single render pass — no per-block DOM thrashing
|
|
905
|
+
await editor.render({
|
|
906
|
+
time: Date.now(),
|
|
907
|
+
version: existingData.version,
|
|
908
|
+
blocks: mergedBlocks,
|
|
909
|
+
});
|
|
916
910
|
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
911
|
+
// Reconnect observer on the redactor element
|
|
912
|
+
if (observerRef.current) {
|
|
913
|
+
const redactor = holderEl.querySelector(".codex-editor__redactor") || holderEl;
|
|
914
|
+
observerRef.current.observe(redactor, {
|
|
915
|
+
childList: true,
|
|
916
|
+
subtree: false,
|
|
917
|
+
});
|
|
918
|
+
}
|
|
919
|
+
// Defer direction scan to next frame — let the browser paint first
|
|
920
|
+
requestAnimationFrame(() => applyAutoDirection(holderEl));
|
|
927
921
|
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
}
|
|
933
|
-
} catch {
|
|
934
|
-
// Fallback: if render approach fails, do nothing rather than freeze
|
|
922
|
+
// Trigger onChange with merged data
|
|
923
|
+
if (onChangeRef.current) {
|
|
924
|
+
const savedData = await editor.save();
|
|
925
|
+
onChangeRef.current(savedData);
|
|
935
926
|
}
|
|
936
|
-
}
|
|
927
|
+
} catch {
|
|
928
|
+
// Fallback: if render approach fails, do nothing rather than freeze
|
|
929
|
+
}
|
|
930
|
+
};
|
|
937
931
|
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
[],
|
|
942
|
-
);
|
|
932
|
+
holderEl.addEventListener("paste", handler as unknown as EventListener, true);
|
|
933
|
+
pasteHandlerRef.current = handler;
|
|
934
|
+
}, []);
|
|
943
935
|
|
|
944
936
|
// ── Auto-direction: watch for DOM changes & input ──
|
|
945
937
|
const inputHandlerRef = useRef<((e: Event) => void) | null>(null);
|
|
@@ -1052,10 +1044,7 @@ export const TextEditor = forwardRef<TextEditorRef, TextEditorProps>(
|
|
|
1052
1044
|
(window.cancelIdleCallback || clearTimeout)(idleCallbackRef.current);
|
|
1053
1045
|
}
|
|
1054
1046
|
|
|
1055
|
-
if (
|
|
1056
|
-
editorRef.current &&
|
|
1057
|
-
typeof editorRef.current.destroy === "function"
|
|
1058
|
-
) {
|
|
1047
|
+
if (editorRef.current && typeof editorRef.current.destroy === "function") {
|
|
1059
1048
|
editorRef.current.destroy();
|
|
1060
1049
|
editorRef.current = null;
|
|
1061
1050
|
}
|
|
@@ -29,7 +29,7 @@ const textareaStyles = cva(
|
|
|
29
29
|
"disabled:text-border-presentation-action-disabled",
|
|
30
30
|
"disabled:cursor-not-allowed",
|
|
31
31
|
"disabled:placeholder-border-presentation-action-disabled",
|
|
32
|
-
"field-sizing-content w-full min-w-[100px] max-w-[100%]"
|
|
32
|
+
"field-sizing-content w-full min-w-[100px] max-w-[100%]",
|
|
33
33
|
],
|
|
34
34
|
{
|
|
35
35
|
variants: {
|
|
@@ -43,13 +43,12 @@ const textareaStyles = cva(
|
|
|
43
43
|
},
|
|
44
44
|
},
|
|
45
45
|
defaultVariants: {},
|
|
46
|
-
}
|
|
46
|
+
},
|
|
47
47
|
);
|
|
48
48
|
|
|
49
49
|
// Define the prop types for the Textarea component
|
|
50
50
|
interface TextareaProps
|
|
51
|
-
extends React.TextareaHTMLAttributes<HTMLTextAreaElement>,
|
|
52
|
-
VariantProps<typeof textareaStyles> {
|
|
51
|
+
extends React.TextareaHTMLAttributes<HTMLTextAreaElement>, VariantProps<typeof textareaStyles> {
|
|
53
52
|
label?: string; // Optional label text
|
|
54
53
|
requiredLabel?: string; // Text for required field indicator
|
|
55
54
|
secondaryLabel?: string; // Additional label text
|
|
@@ -67,10 +66,11 @@ const Textarea = React.forwardRef<HTMLTextAreaElement, TextareaProps>(
|
|
|
67
66
|
requiredLabel,
|
|
68
67
|
secondaryLabel,
|
|
69
68
|
direction = "row",
|
|
70
|
-
|
|
69
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
70
|
+
theme, // excluded from ...props spread
|
|
71
71
|
...props
|
|
72
72
|
},
|
|
73
|
-
ref
|
|
73
|
+
ref,
|
|
74
74
|
) => {
|
|
75
75
|
return (
|
|
76
76
|
<Label
|
|
@@ -82,14 +82,10 @@ const Textarea = React.forwardRef<HTMLTextAreaElement, TextareaProps>(
|
|
|
82
82
|
size={"M"}
|
|
83
83
|
className={cn(className)}
|
|
84
84
|
>
|
|
85
|
-
<textarea
|
|
86
|
-
className={cn(textareaStyles({ state }))}
|
|
87
|
-
ref={ref}
|
|
88
|
-
{...props}
|
|
89
|
-
/>
|
|
85
|
+
<textarea className={cn(textareaStyles({ state }))} ref={ref} {...props} />
|
|
90
86
|
</Label>
|
|
91
87
|
);
|
|
92
|
-
}
|
|
88
|
+
},
|
|
93
89
|
);
|
|
94
90
|
Textarea.displayName = "Textarea";
|
|
95
91
|
|
|
@@ -18,8 +18,7 @@ const timelineStyles = cva(["flex gap-0"], {
|
|
|
18
18
|
});
|
|
19
19
|
|
|
20
20
|
interface TimelineProps
|
|
21
|
-
extends HTMLAttributes<HTMLDivElement>,
|
|
22
|
-
VariantProps<typeof timelineStyles> {
|
|
21
|
+
extends HTMLAttributes<HTMLDivElement>, VariantProps<typeof timelineStyles> {
|
|
23
22
|
theme?: Themes;
|
|
24
23
|
}
|
|
25
24
|
|
|
@@ -32,7 +31,7 @@ const Timeline = forwardRef<HTMLDivElement, TimelineProps>(
|
|
|
32
31
|
className={cn(timelineStyles({ orientation }), className)}
|
|
33
32
|
{...props}
|
|
34
33
|
/>
|
|
35
|
-
)
|
|
34
|
+
),
|
|
36
35
|
);
|
|
37
36
|
Timeline.displayName = "Timeline";
|
|
38
37
|
|
|
@@ -62,7 +61,7 @@ const TimelineItem = forwardRef<HTMLDivElement, TimelineItemProps>(
|
|
|
62
61
|
className={cn(timelineItemStyles({ orientation }), className)}
|
|
63
62
|
{...props}
|
|
64
63
|
/>
|
|
65
|
-
)
|
|
64
|
+
),
|
|
66
65
|
);
|
|
67
66
|
TimelineItem.displayName = "TimelineItem";
|
|
68
67
|
|
|
@@ -114,12 +113,11 @@ const indicatorStyles = cva(
|
|
|
114
113
|
variant: "default",
|
|
115
114
|
size: "M",
|
|
116
115
|
},
|
|
117
|
-
}
|
|
116
|
+
},
|
|
118
117
|
);
|
|
119
118
|
|
|
120
119
|
interface TimelineIndicatorProps
|
|
121
|
-
extends HTMLAttributes<HTMLDivElement>,
|
|
122
|
-
VariantProps<typeof indicatorStyles> {
|
|
120
|
+
extends HTMLAttributes<HTMLDivElement>, VariantProps<typeof indicatorStyles> {
|
|
123
121
|
icon?: ReactNode;
|
|
124
122
|
}
|
|
125
123
|
|
|
@@ -135,25 +133,18 @@ const TimelineIndicator = forwardRef<HTMLDivElement, TimelineIndicatorProps>(
|
|
|
135
133
|
};
|
|
136
134
|
|
|
137
135
|
return (
|
|
138
|
-
<div
|
|
139
|
-
ref={ref}
|
|
140
|
-
className={cn(indicatorStyles({ variant, size }), className)}
|
|
141
|
-
{...props}
|
|
142
|
-
>
|
|
136
|
+
<div ref={ref} className={cn(indicatorStyles({ variant, size }), className)} {...props}>
|
|
143
137
|
{renderContent()}
|
|
144
138
|
</div>
|
|
145
139
|
);
|
|
146
|
-
}
|
|
140
|
+
},
|
|
147
141
|
);
|
|
148
142
|
TimelineIndicator.displayName = "TimelineIndicator";
|
|
149
143
|
|
|
150
144
|
// ─── Timeline Separator (the connecting line) ────────────────────────────────
|
|
151
145
|
|
|
152
146
|
const separatorStyles = cva(
|
|
153
|
-
[
|
|
154
|
-
"bg-border-presentation-global-primary",
|
|
155
|
-
"transition-all duration-200 ease-in-out",
|
|
156
|
-
],
|
|
147
|
+
["bg-border-presentation-global-primary", "transition-all duration-200 ease-in-out"],
|
|
157
148
|
{
|
|
158
149
|
variants: {
|
|
159
150
|
orientation: {
|
|
@@ -168,21 +159,16 @@ const separatorStyles = cva(
|
|
|
168
159
|
orientation: "vertical",
|
|
169
160
|
active: false,
|
|
170
161
|
},
|
|
171
|
-
}
|
|
162
|
+
},
|
|
172
163
|
);
|
|
173
164
|
|
|
174
165
|
interface TimelineSeparatorProps
|
|
175
|
-
extends HTMLAttributes<HTMLDivElement>,
|
|
176
|
-
VariantProps<typeof separatorStyles> {}
|
|
166
|
+
extends HTMLAttributes<HTMLDivElement>, VariantProps<typeof separatorStyles> {}
|
|
177
167
|
|
|
178
168
|
const TimelineSeparator = forwardRef<HTMLDivElement, TimelineSeparatorProps>(
|
|
179
169
|
({ className, orientation = "vertical", active, ...props }, ref) => (
|
|
180
|
-
<div
|
|
181
|
-
|
|
182
|
-
className={cn(separatorStyles({ orientation, active }), className)}
|
|
183
|
-
{...props}
|
|
184
|
-
/>
|
|
185
|
-
)
|
|
170
|
+
<div ref={ref} className={cn(separatorStyles({ orientation, active }), className)} {...props} />
|
|
171
|
+
),
|
|
186
172
|
);
|
|
187
173
|
TimelineSeparator.displayName = "TimelineSeparator";
|
|
188
174
|
|
|
@@ -198,16 +184,14 @@ const TimelineConnector = forwardRef<HTMLDivElement, TimelineConnectorProps>(
|
|
|
198
184
|
ref={ref}
|
|
199
185
|
className={cn(
|
|
200
186
|
"flex items-center",
|
|
201
|
-
orientation === "vertical"
|
|
202
|
-
|
|
203
|
-
: "flex-row",
|
|
204
|
-
className
|
|
187
|
+
orientation === "vertical" ? "flex-col" : "flex-row",
|
|
188
|
+
className,
|
|
205
189
|
)}
|
|
206
190
|
{...props}
|
|
207
191
|
>
|
|
208
192
|
{children}
|
|
209
193
|
</div>
|
|
210
|
-
)
|
|
194
|
+
),
|
|
211
195
|
);
|
|
212
196
|
TimelineConnector.displayName = "TimelineConnector";
|
|
213
197
|
|
|
@@ -219,14 +203,10 @@ const TimelineContent = forwardRef<HTMLDivElement, TimelineContentProps>(
|
|
|
219
203
|
({ className, ...props }, ref) => (
|
|
220
204
|
<div
|
|
221
205
|
ref={ref}
|
|
222
|
-
className={cn(
|
|
223
|
-
"flex flex-col gap-1 pb-6 pt-[2px]",
|
|
224
|
-
"group-last/item:pb-0",
|
|
225
|
-
className
|
|
226
|
-
)}
|
|
206
|
+
className={cn("flex flex-col gap-1 pb-6 pt-[2px]", "group-last/item:pb-0", className)}
|
|
227
207
|
{...props}
|
|
228
208
|
/>
|
|
229
|
-
)
|
|
209
|
+
),
|
|
230
210
|
);
|
|
231
211
|
TimelineContent.displayName = "TimelineContent";
|
|
232
212
|
|
|
@@ -240,11 +220,11 @@ const TimelineHeading = forwardRef<HTMLDivElement, TimelineHeadingProps>(
|
|
|
240
220
|
ref={ref}
|
|
241
221
|
className={cn(
|
|
242
222
|
"typography-body-medium-medium text-content-presentation-global-primary",
|
|
243
|
-
className
|
|
223
|
+
className,
|
|
244
224
|
)}
|
|
245
225
|
{...props}
|
|
246
226
|
/>
|
|
247
|
-
)
|
|
227
|
+
),
|
|
248
228
|
);
|
|
249
229
|
TimelineHeading.displayName = "TimelineHeading";
|
|
250
230
|
|
|
@@ -258,11 +238,11 @@ const TimelineDescription = forwardRef<HTMLDivElement, TimelineDescriptionProps>
|
|
|
258
238
|
ref={ref}
|
|
259
239
|
className={cn(
|
|
260
240
|
"typography-body-small-regular text-content-presentation-global-secondary",
|
|
261
|
-
className
|
|
241
|
+
className,
|
|
262
242
|
)}
|
|
263
243
|
{...props}
|
|
264
244
|
/>
|
|
265
|
-
)
|
|
245
|
+
),
|
|
266
246
|
);
|
|
267
247
|
TimelineDescription.displayName = "TimelineDescription";
|
|
268
248
|
|
|
@@ -1,87 +1,87 @@
|
|
|
1
|
-
import React from
|
|
2
|
-
import { Toaster as ToasterComponent, toast } from
|
|
3
|
-
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { Toaster as ToasterComponent, toast } from "react-hot-toast";
|
|
4
3
|
|
|
5
4
|
const Toaster = ({
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
5
|
+
position = "top-left",
|
|
6
|
+
reverseOrder = false,
|
|
7
|
+
gutter = 8,
|
|
8
|
+
containerClassName = "",
|
|
9
|
+
containerStyle = {},
|
|
10
|
+
toastOptions = {},
|
|
11
|
+
...props
|
|
12
|
+
}: React.ComponentPropsWithoutRef<typeof ToasterComponent>) => {
|
|
13
|
+
return (
|
|
14
|
+
<ToasterComponent
|
|
15
|
+
position={position}
|
|
16
|
+
reverseOrder={reverseOrder}
|
|
17
|
+
gutter={gutter}
|
|
18
|
+
containerClassName={containerClassName}
|
|
19
|
+
containerStyle={containerStyle}
|
|
20
|
+
{...props}
|
|
21
|
+
toastOptions={{
|
|
22
|
+
// Define default options
|
|
23
|
+
className: "",
|
|
24
|
+
duration: 8000,
|
|
25
|
+
removeDelay: 1000,
|
|
26
|
+
style: {
|
|
27
|
+
background: "var(--background-presentation-state-information-secondary)",
|
|
28
|
+
color: "var(--content-presentation-global-primary)",
|
|
29
|
+
borderRadius: "16px",
|
|
30
|
+
},
|
|
31
31
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
}
|
|
32
|
+
// Default options for specific types
|
|
33
|
+
success: {
|
|
34
|
+
duration: 3000,
|
|
35
|
+
style: {
|
|
36
|
+
background: "var(--background-presentation-state-success-secondary)",
|
|
37
|
+
color: "var(--content-presentation-global-primary)",
|
|
38
|
+
borderRadius: "16px",
|
|
39
|
+
},
|
|
40
|
+
iconTheme: {
|
|
41
|
+
primary: "var(--background-presentation-state-success-primary)",
|
|
42
|
+
secondary: "var(--background-presentation-state-success-secondary)",
|
|
43
|
+
},
|
|
44
|
+
},
|
|
45
|
+
error: {
|
|
46
|
+
duration: 5000,
|
|
47
|
+
style: {
|
|
48
|
+
background: "var(--background-presentation-state-negative-secondary)",
|
|
49
|
+
color: "var(--content-presentation-global-primary)",
|
|
50
|
+
borderRadius: "16px",
|
|
51
|
+
},
|
|
52
|
+
iconTheme: {
|
|
53
|
+
primary: "var(--background-presentation-state-negative-primary)",
|
|
54
|
+
secondary: "var(--background-presentation-state-negative-secondary)",
|
|
55
|
+
},
|
|
56
|
+
},
|
|
57
|
+
loading: {
|
|
58
|
+
duration: 4000,
|
|
59
|
+
style: {
|
|
60
|
+
background: "var(--background-presentation-state-warning-secondary)",
|
|
61
|
+
color: "var(--content-presentation-global-primary)",
|
|
62
|
+
borderRadius: "16px",
|
|
63
|
+
},
|
|
64
|
+
iconTheme: {
|
|
65
|
+
primary: "var(--background-presentation-state-warning-primary)",
|
|
66
|
+
secondary: "var(--background-presentation-state-warning-secondary)",
|
|
67
|
+
},
|
|
68
|
+
},
|
|
69
|
+
blank: {
|
|
70
|
+
duration: 4000,
|
|
71
|
+
style: {
|
|
72
|
+
background: "var(--background-presentation-state-information-secondary)",
|
|
73
|
+
color: "var(--content-presentation-global-primary)",
|
|
74
|
+
borderRadius: "16px",
|
|
75
|
+
},
|
|
76
|
+
iconTheme: {
|
|
77
|
+
primary: "var(--background-presentation-state-information-primary)",
|
|
78
|
+
secondary: "var(--background-presentation-state-information-secondary)",
|
|
79
|
+
},
|
|
80
|
+
},
|
|
81
|
+
...toastOptions,
|
|
82
|
+
}}
|
|
83
|
+
/>
|
|
84
|
+
);
|
|
85
|
+
};
|
|
86
86
|
|
|
87
|
-
export { Toaster, toast }
|
|
87
|
+
export { Toaster, toast };
|