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.
Files changed (264) hide show
  1. package/README.md +8 -0
  2. package/apps/lib/components/ActionButton.tsx +7 -12
  3. package/apps/lib/components/ActionsGroup.tsx +4 -15
  4. package/apps/lib/components/AlertDialog.tsx +173 -191
  5. package/apps/lib/components/Avatar.tsx +13 -16
  6. package/apps/lib/components/Badge.tsx +1 -3
  7. package/apps/lib/components/BadgeField.tsx +76 -71
  8. package/apps/lib/components/Breadcrumb.tsx +49 -85
  9. package/apps/lib/components/Button.tsx +20 -19
  10. package/apps/lib/components/ButtonGroup.tsx +31 -41
  11. package/apps/lib/components/Calendar.tsx +51 -29
  12. package/apps/lib/components/Card.tsx +2 -13
  13. package/apps/lib/components/ChartBlockTool.ts +17 -52
  14. package/apps/lib/components/Checkbox.tsx +9 -16
  15. package/apps/lib/components/ContextMenu.tsx +97 -96
  16. package/apps/lib/components/CountBadge.tsx +4 -6
  17. package/apps/lib/components/DataTable.tsx +196 -216
  18. package/apps/lib/components/DataViews/DataViewRadio.tsx +1 -6
  19. package/apps/lib/components/DataViews/DataViewsConfigPanel.tsx +13 -47
  20. package/apps/lib/components/DataViews/DataViewsHeader.tsx +1 -3
  21. package/apps/lib/components/DataViews/DataViewsLayout.tsx +5 -12
  22. package/apps/lib/components/DataViews/FilterPanel.tsx +155 -149
  23. package/apps/lib/components/DataViews/HeaderSearch.tsx +1 -5
  24. package/apps/lib/components/DataViews/InboxView.tsx +22 -68
  25. package/apps/lib/components/DataViews/InboxViewCard.tsx +68 -77
  26. package/apps/lib/components/DataViews/KanbanView.tsx +8 -25
  27. package/apps/lib/components/DataViews/PanelControls.tsx +3 -13
  28. package/apps/lib/components/DataViews/SettingsPanel.tsx +83 -89
  29. package/apps/lib/components/DataViews/TableView.tsx +8 -28
  30. package/apps/lib/components/DataViews/TreeView.tsx +12 -40
  31. package/apps/lib/components/DataViews/badgeAdapter.ts +32 -28
  32. package/apps/lib/components/DataViews/fieldRenderers.tsx +106 -141
  33. package/apps/lib/components/DataViews/filters/DatePickerRangeFilter.tsx +30 -23
  34. package/apps/lib/components/DataViews/filters/DateRangePopover.tsx +39 -32
  35. package/apps/lib/components/DataViews/filters/PresetChips.tsx +15 -15
  36. package/apps/lib/components/DataViews/filters/RangeSliderWithInputs.tsx +69 -58
  37. package/apps/lib/components/DataViews/index.ts +26 -26
  38. package/apps/lib/components/DataViews/tree/TreeDrawer.tsx +12 -16
  39. package/apps/lib/components/DataViews/tree/TreeSidebar.tsx +28 -31
  40. package/apps/lib/components/DataViews/types.ts +104 -115
  41. package/apps/lib/components/DatePicker.tsx +198 -196
  42. package/apps/lib/components/Dialog.tsx +92 -105
  43. package/apps/lib/components/Divider.tsx +21 -24
  44. package/apps/lib/components/Drawer.tsx +79 -139
  45. package/apps/lib/components/DropdownMenu.tsx +131 -171
  46. package/apps/lib/components/FieldHint.tsx +4 -11
  47. package/apps/lib/components/Form.tsx +146 -155
  48. package/apps/lib/components/FormStepper.tsx +9 -39
  49. package/apps/lib/components/HeaderBar.tsx +1 -9
  50. package/apps/lib/components/ImageAttachment.tsx +111 -73
  51. package/apps/lib/components/InnerLabelField.tsx +20 -16
  52. package/apps/lib/components/Input.tsx +171 -172
  53. package/apps/lib/components/InputField.tsx +44 -45
  54. package/apps/lib/components/InputOTP.tsx +68 -69
  55. package/apps/lib/components/Label.tsx +31 -35
  56. package/apps/lib/components/LabelField.tsx +4 -5
  57. package/apps/lib/components/LabeledCheckBox.tsx +8 -12
  58. package/apps/lib/components/LabeledRadio.tsx +7 -5
  59. package/apps/lib/components/LinkButton.tsx +2 -9
  60. package/apps/lib/components/LoginButton.tsx +4 -9
  61. package/apps/lib/components/PasswordLevel.tsx +5 -5
  62. package/apps/lib/components/Popover.tsx +15 -33
  63. package/apps/lib/components/ProfileMenu.tsx +67 -72
  64. package/apps/lib/components/Radio.tsx +1 -5
  65. package/apps/lib/components/RadioCard.tsx +9 -28
  66. package/apps/lib/components/ScrollArea.tsx +45 -43
  67. package/apps/lib/components/SearchField.tsx +49 -39
  68. package/apps/lib/components/SearchableSelect.tsx +8 -14
  69. package/apps/lib/components/SearchableTable.tsx +108 -118
  70. package/apps/lib/components/SearchableTree.tsx +469 -0
  71. package/apps/lib/components/SearchableTreeDialog.tsx +493 -0
  72. package/apps/lib/components/SectionBlock.tsx +4 -16
  73. package/apps/lib/components/Select.tsx +53 -80
  74. package/apps/lib/components/SimpleSelect.tsx +196 -187
  75. package/apps/lib/components/Skeleton.tsx +9 -12
  76. package/apps/lib/components/SlideDatePicker.tsx +215 -166
  77. package/apps/lib/components/SpinLoading.tsx +33 -49
  78. package/apps/lib/components/Stepper.tsx +13 -56
  79. package/apps/lib/components/Switch.tsx +8 -10
  80. package/apps/lib/components/TabFormItem.tsx +3 -12
  81. package/apps/lib/components/TabSwitch.tsx +7 -34
  82. package/apps/lib/components/Table.tsx +60 -75
  83. package/apps/lib/components/TableDnDWrapper.ts +15 -48
  84. package/apps/lib/components/TextEditor.tsx +93 -104
  85. package/apps/lib/components/Textarea.tsx +8 -12
  86. package/apps/lib/components/Timeline.tsx +21 -41
  87. package/apps/lib/components/Toast.tsx +83 -83
  88. package/apps/lib/components/Toggle.tsx +112 -114
  89. package/apps/lib/components/ToggleButton.tsx +1 -1
  90. package/apps/lib/components/Tooltip.tsx +24 -19
  91. package/apps/lib/components/TransparentLabel.tsx +61 -62
  92. package/apps/lib/components/TreeDropDown.tsx +86 -52
  93. package/apps/lib/components/TreeFolder/TreeFolder.tsx +15 -48
  94. package/apps/lib/components/TreeFolder/TreeFolderBreadcrumb.tsx +16 -21
  95. package/apps/lib/components/TreeFolder/TreeFolderRow.tsx +9 -20
  96. package/apps/lib/components/TreeFolder/TreeFolderStyles.tsx +3 -3
  97. package/apps/lib/components/TreeFolder/icons.tsx +14 -17
  98. package/apps/lib/components/TreeFolder/index.ts +15 -8
  99. package/apps/lib/components/TreeFolder/treeFolderUtils.ts +47 -52
  100. package/apps/lib/components/TreeFolder/types.ts +32 -32
  101. package/apps/lib/components/TreeFolder/useTreeFolderDnD.ts +117 -123
  102. package/apps/lib/hooks/useActiveTreeItem.ts +52 -55
  103. package/apps/lib/hooks/useClickOutside.ts +21 -20
  104. package/apps/lib/hooks/useDataViewsState.ts +86 -80
  105. package/apps/lib/hooks/useIsMobile.ts +12 -12
  106. package/apps/lib/hooks/useResize.ts +54 -65
  107. package/apps/lib/hooks/useTagSelection.ts +201 -201
  108. package/apps/lib/layouts/CNLayout.tsx +181 -140
  109. package/apps/lib/layouts/DataViewCard.tsx +4 -18
  110. package/apps/lib/layouts/FieldSection.tsx +2 -6
  111. package/apps/lib/layouts/TreeSubLayout.tsx +24 -38
  112. package/apps/lib/providers/ThemeProvider.tsx +8 -23
  113. package/apps/lib/registry.json +1004 -0
  114. package/apps/lib/tsconfig.json +9 -0
  115. package/apps/lib/utils/cn.ts +1 -1
  116. package/apps/lib/utils/dataViews/columnUtils.ts +46 -44
  117. package/apps/lib/utils/dataViews/fieldUtils.ts +70 -71
  118. package/apps/lib/utils/dataViews/nestedDataUtils.tsx +129 -122
  119. package/apps/lib/utils/dataViews/pathUtils.ts +74 -67
  120. package/apps/lib/utils/dataViews/rangeUtils.ts +121 -112
  121. package/apps/lib/utils/dataViews/treeUtils.ts +204 -211
  122. package/apps/lib/utils/dateFormat.ts +64 -54
  123. package/apps/lib/utils/markdownParser.ts +2 -7
  124. package/apps/lib/utils/resize.ts +21 -25
  125. package/apps/lib/utils/types.ts +13 -13
  126. package/dist/bin/index.js +8 -2
  127. package/dist/bin/index.js.map +1 -1
  128. package/dist/src/shared/getAvailableFiles.d.ts.map +1 -1
  129. package/dist/src/shared/getAvailableFiles.js +6 -1
  130. package/dist/src/shared/getAvailableFiles.js.map +1 -1
  131. package/dist/src/shared/loadRegistry.d.ts +7 -0
  132. package/dist/src/shared/loadRegistry.d.ts.map +1 -0
  133. package/dist/src/shared/loadRegistry.js +31 -0
  134. package/dist/src/shared/loadRegistry.js.map +1 -0
  135. package/dist/src/shared/resolveInstallPlan.d.ts +12 -0
  136. package/dist/src/shared/resolveInstallPlan.d.ts.map +1 -0
  137. package/dist/src/shared/resolveInstallPlan.js +39 -0
  138. package/dist/src/shared/resolveInstallPlan.js.map +1 -0
  139. package/dist/src/types/main.d.ts +24 -0
  140. package/dist/src/types/main.d.ts.map +1 -1
  141. package/docs/README.md +10 -2
  142. package/docs/components/action-button.md +30 -24
  143. package/docs/components/actions-group.md +26 -20
  144. package/docs/components/alert-dialog.md +45 -45
  145. package/docs/components/avatar.md +6 -2
  146. package/docs/components/badge-field.md +6 -2
  147. package/docs/components/badge.md +7 -1
  148. package/docs/components/breadcrumb.md +15 -40
  149. package/docs/components/button-group.md +13 -10
  150. package/docs/components/button.md +58 -33
  151. package/docs/components/calendar.md +26 -19
  152. package/docs/components/card.md +19 -16
  153. package/docs/components/chart-block-tool.md +128 -0
  154. package/docs/components/checkbox.md +16 -8
  155. package/docs/components/cn-layout.md +7 -1
  156. package/docs/components/context-menu.md +18 -25
  157. package/docs/components/count-badge.md +7 -1
  158. package/docs/components/data-table.md +45 -33
  159. package/docs/components/data-views-config-panel.md +15 -11
  160. package/docs/components/data-views-layout.md +13 -16
  161. package/docs/components/date-picker.md +30 -23
  162. package/docs/components/dialog.md +43 -42
  163. package/docs/components/divider.md +10 -4
  164. package/docs/components/drawer.md +8 -33
  165. package/docs/components/dropdown-menu.md +25 -34
  166. package/docs/components/field-hint.md +37 -25
  167. package/docs/components/field-section.md +9 -3
  168. package/docs/components/form-stepper.md +6 -0
  169. package/docs/components/form.md +17 -20
  170. package/docs/components/header-bar.md +6 -0
  171. package/docs/components/image-attachment.md +33 -41
  172. package/docs/components/inbox-view.md +16 -5
  173. package/docs/components/inner-label-field.md +34 -24
  174. package/docs/components/input-field.md +18 -10
  175. package/docs/components/input-otp.md +14 -11
  176. package/docs/components/input.md +22 -16
  177. package/docs/components/kanban-view.md +15 -5
  178. package/docs/components/label-field.md +32 -22
  179. package/docs/components/label.md +43 -32
  180. package/docs/components/labeled-check-box.md +16 -8
  181. package/docs/components/labeled-radio.md +18 -11
  182. package/docs/components/link-button.md +7 -1
  183. package/docs/components/login-button.md +8 -2
  184. package/docs/components/password-level.md +37 -24
  185. package/docs/components/popover.md +26 -23
  186. package/docs/components/profile-menu.md +38 -27
  187. package/docs/components/radio-card.md +16 -9
  188. package/docs/components/radio.md +16 -8
  189. package/docs/components/scroll-area.md +6 -2
  190. package/docs/components/search-field.md +14 -6
  191. package/docs/components/searchable-select.md +19 -14
  192. package/docs/components/searchable-table.md +18 -13
  193. package/docs/components/searchable-tree-dialog.md +190 -0
  194. package/docs/components/searchable-tree.md +200 -0
  195. package/docs/components/section-block.md +12 -4
  196. package/docs/components/select.md +23 -18
  197. package/docs/components/simple-select.md +14 -10
  198. package/docs/components/skeleton.md +43 -33
  199. package/docs/components/slide-date-picker.md +37 -29
  200. package/docs/components/spin-loading.md +32 -23
  201. package/docs/components/stepper.md +6 -0
  202. package/docs/components/switch.md +14 -6
  203. package/docs/components/tab-form-item.md +7 -1
  204. package/docs/components/tab-switch.md +13 -6
  205. package/docs/components/table-dnd-wrapper.md +105 -0
  206. package/docs/components/table-view.md +15 -5
  207. package/docs/components/table.md +28 -28
  208. package/docs/components/text-editor.md +19 -13
  209. package/docs/components/textarea.md +15 -7
  210. package/docs/components/timeline.md +6 -0
  211. package/docs/components/toast.md +35 -26
  212. package/docs/components/toggle-button.md +24 -21
  213. package/docs/components/toggle.md +23 -15
  214. package/docs/components/tooltip.md +42 -30
  215. package/docs/components/transparent-label.md +29 -20
  216. package/docs/components/tree-drop-down.md +31 -23
  217. package/docs/components/tree-sub-layout.md +6 -2
  218. package/docs/components/tree-view.md +16 -5
  219. package/docs/explanation/architecture.md +54 -0
  220. package/docs/explanation/design-system.md +52 -0
  221. package/docs/how-to/data-views-from-backend-response.md +6 -4
  222. package/docs/how-to/guides.md +24 -18
  223. package/docs/migration/changelog.md +38 -0
  224. package/docs/reference/cli.md +87 -0
  225. package/docs/reference/components.md +11 -12
  226. package/docs/reference/hooks.md +8 -8
  227. package/docs/reference/providers.md +22 -22
  228. package/docs/reference/tailwind-plugins.md +2 -2
  229. package/docs/reference/theme.md +85 -0
  230. package/docs/reference/types.md +4 -4
  231. package/docs/reference/utilities.md +19 -26
  232. package/docs/tutorials/building-first-form.md +20 -13
  233. package/docs/tutorials/component-composition.md +34 -50
  234. package/docs/tutorials/getting-started.md +2 -2
  235. package/docs/tutorials/theming-basics.md +13 -10
  236. package/package.json +31 -3
  237. package/dist/src/commands/block.d.ts +0 -5
  238. package/dist/src/commands/block.d.ts.map +0 -1
  239. package/dist/src/commands/block.js +0 -255
  240. package/dist/src/commands/block.js.map +0 -1
  241. package/dist/src/shared/configureFonts.d.ts +0 -6
  242. package/dist/src/shared/configureFonts.d.ts.map +0 -1
  243. package/dist/src/shared/configureFonts.js +0 -106
  244. package/dist/src/shared/configureFonts.js.map +0 -1
  245. package/dist/src/shared/configureGlobalCss.d.ts +0 -6
  246. package/dist/src/shared/configureGlobalCss.d.ts.map +0 -1
  247. package/dist/src/shared/configureGlobalCss.js +0 -154
  248. package/dist/src/shared/configureGlobalCss.js.map +0 -1
  249. package/dist/src/shared/configureTailwind.d.ts +0 -7
  250. package/dist/src/shared/configureTailwind.d.ts.map +0 -1
  251. package/dist/src/shared/configureTailwind.js +0 -163
  252. package/dist/src/shared/configureTailwind.js.map +0 -1
  253. package/dist/src/shared/detectFramework.d.ts +0 -23
  254. package/dist/src/shared/detectFramework.d.ts.map +0 -1
  255. package/dist/src/shared/detectFramework.js +0 -119
  256. package/dist/src/shared/detectFramework.js.map +0 -1
  257. package/dist/src/shared/installBaseUtils.d.ts +0 -5
  258. package/dist/src/shared/installBaseUtils.d.ts.map +0 -1
  259. package/dist/src/shared/installBaseUtils.js +0 -79
  260. package/dist/src/shared/installBaseUtils.js.map +0 -1
  261. package/dist/src/shared/resolveAliases.d.ts +0 -24
  262. package/dist/src/shared/resolveAliases.d.ts.map +0 -1
  263. package/dist/src/shared/resolveAliases.js +0 -98
  264. 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(block: HTMLElement, fallbackDir: "rtl" | "ltr" = "ltr"): "rtl" | "ltr" {
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 as any },
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
- (holderEl: HTMLElement) => {
844
- const handler = async (e: ClipboardEvent) => {
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
- const plain = e.clipboardData?.getData("text/plain") || "";
841
+ const plain = e.clipboardData?.getData("text/plain") || "";
848
842
 
849
- // Only intercept if the plain text is markdown
850
- if (!isMarkdown(plain)) return;
843
+ // Only intercept if the plain text is markdown
844
+ if (!isMarkdown(plain)) return;
851
845
 
852
- e.preventDefault();
853
- e.stopPropagation();
846
+ e.preventDefault();
847
+ e.stopPropagation();
854
848
 
855
- const parsedBlocks = parseMarkdownToBlocks(plain);
856
- if (parsedBlocks.length === 0) return;
849
+ const parsedBlocks = parseMarkdownToBlocks(plain);
850
+ if (parsedBlocks.length === 0) return;
857
851
 
858
- const editor = editorRef.current;
852
+ const editor = editorRef.current;
859
853
 
860
- // Save existing content, merge new blocks at cursor, render once
861
- // This avoids per-block insert which freezes the editor on large pastes
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
- const existingData = await editor.save();
864
- const existingBlocks = existingData.blocks || [];
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
- // Convert parsed blocks to OutputData block format
879
- const newBlocks = parsedBlocks.map((block) => ({
880
- type: block.type,
881
- data: block.data,
882
- }));
883
-
884
- // Remove empty paragraph at cursor if it's the only content there
885
- const filteredExisting = [...existingBlocks];
886
- if (insertIdx > 0) {
887
- const cursorBlock = filteredExisting[insertIdx - 1];
888
- if (
889
- cursorBlock &&
890
- cursorBlock.type === "paragraph" &&
891
- (!cursorBlock.data.text ||
892
- cursorBlock.data.text.trim() === "" ||
893
- cursorBlock.data.text === "<br>")
894
- ) {
895
- filteredExisting.splice(insertIdx - 1, 1);
896
- insertIdx = Math.max(0, insertIdx - 1);
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
- // Merge: existing blocks before cursor + new blocks + existing blocks after cursor
901
- const mergedBlocks = [
902
- ...filteredExisting.slice(0, insertIdx),
903
- ...newBlocks,
904
- ...filteredExisting.slice(insertIdx),
905
- ];
906
-
907
- // Pause MutationObserver during bulk render to prevent O(n^2) direction checks
908
- observerRef.current?.disconnect();
909
-
910
- // Single render pass — no per-block DOM thrashing
911
- await editor.render({
912
- time: Date.now(),
913
- version: existingData.version,
914
- blocks: mergedBlocks,
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
- // Reconnect observer on the redactor element
918
- if (observerRef.current) {
919
- const redactor = holderEl.querySelector(".codex-editor__redactor") || holderEl;
920
- observerRef.current.observe(redactor, {
921
- childList: true,
922
- subtree: false,
923
- });
924
- }
925
- // Defer direction scan to next frame — let the browser paint first
926
- requestAnimationFrame(() => applyAutoDirection(holderEl));
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
- // Trigger onChange with merged data
929
- if (onChangeRef.current) {
930
- const savedData = await editor.save();
931
- onChangeRef.current(savedData);
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
- holderEl.addEventListener("paste", handler as unknown as EventListener, true);
939
- pasteHandlerRef.current = handler;
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
- theme,
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
- ref={ref}
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
- ? "flex-col"
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 'react'
2
- import { Toaster as ToasterComponent, toast } from 'react-hot-toast'
3
-
1
+ import React from "react";
2
+ import { Toaster as ToasterComponent, toast } from "react-hot-toast";
4
3
 
5
4
  const Toaster = ({
6
- position = 'top-left',
7
- reverseOrder = false,
8
- gutter = 8,
9
- containerClassName = '',
10
- containerStyle = {},
11
- toastOptions = {},
12
- ...props }: 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
- },
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
- // 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
- }
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 };