torch-glare 2.4.4 → 2.5.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.
Files changed (147) hide show
  1. package/apps/lib/components/DataViews/{badgeAdapter.ts → badge.ts} +2 -2
  2. package/apps/lib/components/DataViews/cell.tsx +324 -0
  3. package/apps/lib/components/DataViews/context.ts +144 -0
  4. package/apps/lib/components/DataViews/data-views.tsx +383 -0
  5. package/apps/lib/components/DataViews/filters/children.tsx +98 -0
  6. package/apps/lib/components/DataViews/filters/custom.tsx +34 -0
  7. package/apps/lib/components/DataViews/filters/filters.tsx +163 -0
  8. package/apps/lib/components/DataViews/filters/index.ts +4 -0
  9. package/apps/lib/components/DataViews/filters/labelled.tsx +20 -0
  10. package/apps/lib/components/DataViews/filters/presets.tsx +65 -0
  11. package/apps/lib/components/DataViews/filters/summary.tsx +65 -0
  12. package/apps/lib/components/DataViews/filters/sync.tsx +35 -0
  13. package/apps/lib/components/DataViews/filters/values.ts +173 -0
  14. package/apps/lib/components/DataViews/header.tsx +217 -0
  15. package/apps/lib/components/DataViews/hooks/index.ts +5 -0
  16. package/apps/lib/components/DataViews/hooks/useActiveRow.ts +22 -0
  17. package/apps/lib/components/DataViews/hooks/useControllable.ts +52 -0
  18. package/apps/lib/components/DataViews/index.ts +74 -26
  19. package/apps/lib/components/DataViews/panel/columns.tsx +153 -0
  20. package/apps/lib/components/DataViews/panel/controls.tsx +106 -0
  21. package/apps/lib/components/DataViews/panel/index.ts +3 -0
  22. package/apps/lib/components/DataViews/panel/panel.tsx +164 -0
  23. package/apps/lib/components/DataViews/panel/saved-views.tsx +67 -0
  24. package/apps/lib/components/DataViews/panel/section.tsx +79 -0
  25. package/apps/lib/components/DataViews/panel/sort.tsx +42 -0
  26. package/apps/lib/components/DataViews/panel/tab.tsx +31 -0
  27. package/apps/lib/components/DataViews/slots.ts +63 -0
  28. package/apps/lib/components/DataViews/states.tsx +38 -0
  29. package/apps/lib/components/DataViews/types.ts +485 -178
  30. package/apps/lib/components/DataViews/views/board-view.tsx +379 -0
  31. package/apps/lib/components/DataViews/views/card-rows.tsx +36 -0
  32. package/apps/lib/components/DataViews/views/inbox-view.tsx +257 -0
  33. package/apps/lib/components/DataViews/views/pane-views.tsx +192 -0
  34. package/apps/lib/components/DataViews/views/table-view.tsx +426 -0
  35. package/apps/lib/components/DataViews/views/tree-view.tsx +365 -0
  36. package/apps/lib/components/FormBuilder/context.ts +20 -6
  37. package/apps/lib/components/FormBuilder/field-kind.ts +28 -0
  38. package/apps/lib/components/FormBuilder/fields/DateField.tsx +3 -3
  39. package/apps/lib/components/FormBuilder/fields/FieldShell.tsx +7 -6
  40. package/apps/lib/components/FormBuilder/fields/PhoneField.tsx +30 -4
  41. package/apps/lib/components/FormBuilder/fields/SelectField.tsx +7 -7
  42. package/apps/lib/components/FormBuilder/fields/TableField.tsx +80 -52
  43. package/apps/lib/components/FormBuilder/fields/TextField.tsx +9 -9
  44. package/apps/lib/components/FormBuilder/form-builder.tsx +66 -6
  45. package/apps/lib/components/FormBuilder/index.ts +3 -1
  46. package/apps/lib/components/FormBuilder/types.ts +40 -0
  47. package/apps/lib/components/Input.tsx +3 -0
  48. package/apps/lib/components/SearchableTable.tsx +5 -4
  49. package/apps/lib/components/SectionBlock.tsx +58 -11
  50. package/apps/lib/components/Select.tsx +3 -1
  51. package/apps/lib/components/TabSwitch.tsx +16 -4
  52. package/apps/lib/components/Table.tsx +265 -67
  53. package/apps/lib/components/TreeFolder/TreeFolder.tsx +6 -3
  54. package/apps/lib/components/TreeFolder/TreeFolderRow.tsx +16 -14
  55. package/apps/lib/components/TreeFolder/index.ts +1 -1
  56. package/apps/lib/components/TreeFolder/useTreeFolderDnD.ts +70 -207
  57. package/apps/lib/hooks/useDragDrop.tsx +365 -0
  58. package/apps/lib/hooks/useInfiniteScroll.ts +108 -0
  59. package/apps/lib/registry.json +159 -4
  60. package/apps/lib/tsconfig.tsbuildinfo +1 -1
  61. package/apps/lib/utils/dataViews/path.ts +67 -0
  62. package/apps/lib/utils/dataViews/query.ts +73 -0
  63. package/apps/lib/utils/dataViews/types.ts +187 -0
  64. package/docs/components/breadcrumb.md +1 -1
  65. package/docs/components/button-group.md +1 -1
  66. package/docs/components/button.md +1 -1
  67. package/docs/components/card.md +1 -1
  68. package/docs/components/checkbox.md +1 -1
  69. package/docs/components/data-views/backend-response.md +324 -0
  70. package/docs/components/data-views/examples/a11y-rtl.md +250 -0
  71. package/docs/components/data-views/examples/api-orders-route.md +130 -0
  72. package/docs/components/data-views/examples/fields.md +362 -0
  73. package/docs/components/data-views/examples/filters.md +308 -0
  74. package/docs/components/data-views/examples/inbox-routing.md +218 -0
  75. package/docs/components/data-views/examples/index.md +29 -0
  76. package/docs/components/data-views/examples/overview.md +244 -0
  77. package/docs/components/data-views/examples/panel.md +212 -0
  78. package/docs/components/data-views/examples/scale.md +231 -0
  79. package/docs/components/data-views/examples/server-side.md +210 -0
  80. package/docs/components/data-views/examples/state.md +250 -0
  81. package/docs/components/data-views/examples/tree-custom.md +388 -0
  82. package/docs/components/data-views/examples/view-registry.md +313 -0
  83. package/docs/components/data-views/examples/views.md +534 -0
  84. package/docs/components/data-views/guide.md +405 -0
  85. package/docs/components/data-views/index.md +1504 -0
  86. package/docs/components/data-views/migration.md +79 -0
  87. package/docs/components/date-picker.md +0 -1
  88. package/docs/components/form-builder.md +19 -8
  89. package/docs/components/form-renderer.md +2 -1
  90. package/docs/components/form.md +1 -1
  91. package/docs/components/input-field.md +1 -1
  92. package/docs/components/input-otp.md +1 -1
  93. package/docs/components/input.md +1 -1
  94. package/docs/components/labeled-check-box.md +1 -1
  95. package/docs/components/labeled-radio.md +1 -1
  96. package/docs/components/radio-card.md +1 -1
  97. package/docs/components/radio.md +1 -1
  98. package/docs/components/search-field.md +1 -1
  99. package/docs/components/section-block.md +79 -3
  100. package/docs/components/select.md +1 -1
  101. package/docs/components/simple-select.md +1 -1
  102. package/docs/components/switch.md +1 -1
  103. package/docs/components/tab-switch.md +1 -1
  104. package/docs/components/table.md +45 -8
  105. package/docs/components/text-editor.md +1 -1
  106. package/docs/components/textarea.md +1 -1
  107. package/docs/components/toggle-button.md +1 -1
  108. package/docs/components/toggle.md +1 -1
  109. package/docs/components/tree-folder.md +110 -0
  110. package/docs/how-to/forms-with-form-builder.md +6 -4
  111. package/docs/reference/components.md +16 -6
  112. package/docs/tutorials/component-composition.md +11 -13
  113. package/package.json +3 -2
  114. package/apps/lib/components/DataViews/DataViewRadio.tsx +0 -49
  115. package/apps/lib/components/DataViews/DataViewsConfigPanel.tsx +0 -393
  116. package/apps/lib/components/DataViews/DataViewsHeader.tsx +0 -207
  117. package/apps/lib/components/DataViews/DataViewsLayout.tsx +0 -332
  118. package/apps/lib/components/DataViews/FilterPanel.tsx +0 -493
  119. package/apps/lib/components/DataViews/HeaderSearch.tsx +0 -93
  120. package/apps/lib/components/DataViews/InboxView.tsx +0 -463
  121. package/apps/lib/components/DataViews/InboxViewCard.tsx +0 -127
  122. package/apps/lib/components/DataViews/KanbanView.tsx +0 -336
  123. package/apps/lib/components/DataViews/PanelControls.tsx +0 -39
  124. package/apps/lib/components/DataViews/SettingsPanel.tsx +0 -279
  125. package/apps/lib/components/DataViews/TableView.tsx +0 -212
  126. package/apps/lib/components/DataViews/TreeView.tsx +0 -364
  127. package/apps/lib/components/DataViews/fieldRenderers.tsx +0 -299
  128. package/apps/lib/components/DataViews/filters/DatePickerRangeFilter.tsx +0 -87
  129. package/apps/lib/components/DataViews/filters/DateRangePopover.tsx +0 -120
  130. package/apps/lib/components/DataViews/filters/PresetChips.tsx +0 -45
  131. package/apps/lib/components/DataViews/filters/RangeSliderWithInputs.tsx +0 -165
  132. package/apps/lib/components/DataViews/tree/TreeDrawer.tsx +0 -50
  133. package/apps/lib/components/DataViews/tree/TreeSidebar.tsx +0 -74
  134. package/apps/lib/hooks/useDataViewsState.ts +0 -175
  135. package/apps/lib/utils/dataViews/columnUtils.ts +0 -132
  136. package/apps/lib/utils/dataViews/fieldUtils.ts +0 -197
  137. package/apps/lib/utils/dataViews/nestedDataUtils.tsx +0 -371
  138. package/apps/lib/utils/dataViews/pathUtils.ts +0 -139
  139. package/apps/lib/utils/dataViews/rangeUtils.ts +0 -234
  140. package/apps/lib/utils/dataViews/treeUtils.ts +0 -396
  141. package/docs/components/data-views-config-panel.md +0 -208
  142. package/docs/components/data-views-layout.md +0 -291
  143. package/docs/components/inbox-view.md +0 -170
  144. package/docs/components/kanban-view.md +0 -135
  145. package/docs/components/table-view.md +0 -141
  146. package/docs/components/tree-view.md +0 -147
  147. package/docs/how-to/data-views-from-backend-response.md +0 -194
@@ -0,0 +1,108 @@
1
+ "use client";
2
+
3
+ import { useCallback, useEffect, useRef } from "react";
4
+
5
+ /**
6
+ * Ask for the next page when the user scrolls near the end.
7
+ *
8
+ * Lives here rather than in a view because three of them need it — the table, the board's columns
9
+ * and the inbox list — and "near the end" has to mean the same thing in all three.
10
+ *
11
+ * It is an `IntersectionObserver` on a sentinel element, not a scroll listener. A scroll handler
12
+ * has to be throttled, reads layout on every frame to work out how close the bottom is, and stops
13
+ * being correct the moment the container resizes. The observer is told once and answers all three
14
+ * for free.
15
+ *
16
+ * Like everything else here it only *asks*. Nothing loads until you hand back more rows.
17
+ */
18
+ export interface UseInfiniteScrollOptions {
19
+ /** Fetch the next page and append it. */
20
+ onLoadMore?: () => void;
21
+ /** Whether there is a next page at all. */
22
+ hasMore: boolean;
23
+ /** True while a page is in flight. */
24
+ loading?: boolean;
25
+ /**
26
+ * How far before the end to fire, in px. The default aims to have the next page arriving before
27
+ * the user reaches the gap, rather than after they have already stopped at it.
28
+ */
29
+ rootMargin?: number;
30
+ }
31
+
32
+ /**
33
+ * The element the sentinel actually scrolls inside, or `null` for the viewport.
34
+ *
35
+ * Walks up looking at `overflow-y` rather than at class names, so it keeps working whatever a
36
+ * view calls its container — the table, the board's columns and the inbox list all differ.
37
+ */
38
+ function scrollParentOf(el: HTMLElement): HTMLElement | null {
39
+ let node = el.parentElement;
40
+ while (node) {
41
+ const overflow = getComputedStyle(node).overflowY;
42
+ if (overflow === "auto" || overflow === "scroll") return node;
43
+ node = node.parentElement;
44
+ }
45
+ return null;
46
+ }
47
+
48
+ export function useInfiniteScroll({
49
+ onLoadMore,
50
+ hasMore,
51
+ loading = false,
52
+ rootMargin = 400,
53
+ }: UseInfiniteScrollOptions) {
54
+ const sentinelRef = useRef<HTMLElement | null>(null);
55
+
56
+ /**
57
+ * The guard against asking twice for the same page.
58
+ *
59
+ * The observer fires on intersection, but the rows that answer it do not arrive for a round
60
+ * trip — and until they do, the sentinel is still on screen. Reading `loading` alone is not
61
+ * enough either: a caller that sets it a tick late leaves a window where a second fire gets
62
+ * through. So the hook latches when it asks, and only unlatches once the sentinel has actually
63
+ * left the viewport again.
64
+ */
65
+ const askedRef = useRef(false);
66
+
67
+ const ready = Boolean(onLoadMore) && hasMore && !loading;
68
+
69
+ const handle = useCallback(
70
+ (entries: IntersectionObserverEntry[]) => {
71
+ const visible = entries.some((e) => e.isIntersecting);
72
+ if (!visible) {
73
+ askedRef.current = false;
74
+ return;
75
+ }
76
+ if (askedRef.current || !ready) return;
77
+ askedRef.current = true;
78
+ onLoadMore?.();
79
+ },
80
+ [ready, onLoadMore],
81
+ );
82
+
83
+ useEffect(() => {
84
+ const el = sentinelRef.current;
85
+ if (!el || typeof IntersectionObserver === "undefined") return;
86
+
87
+ const observer = new IntersectionObserver(handle, {
88
+ // The scroller has to be named. `root: null` means the *viewport*, not the nearest
89
+ // scrollable ancestor — so inside a scrolling panel the sentinel is clipped away and
90
+ // `rootMargin` expands the wrong box, which reads as "infinite scroll simply never fires".
91
+ // Finding it here rather than asking for it keeps the call sites free of plumbing.
92
+ root: scrollParentOf(el),
93
+ rootMargin: `0px 0px ${rootMargin}px 0px`,
94
+ });
95
+ observer.observe(el);
96
+ return () => observer.disconnect();
97
+ }, [handle, rootMargin]);
98
+
99
+ // The latch is released by the sentinel leaving, and by nothing else.
100
+ //
101
+ // Releasing it when `loading` went false instead — which is the obvious thing to write — burns
102
+ // several pages on one flick to the bottom: the flag drops before the new rows have painted, so
103
+ // the sentinel is still on screen and the next observer callback asks again, and again. Tying
104
+ // the release to visibility makes one arrival at the end cost exactly one page, because the
105
+ // rows that arrive are what push the sentinel out of view.
106
+
107
+ return { sentinelRef };
108
+ }
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "2.4.4",
2
+ "version": "2.5.0",
3
3
  "generatedBy": "scripts/bin/generateRegistry",
4
4
  "items": [
5
5
  {
@@ -224,6 +224,37 @@
224
224
  "components/Table"
225
225
  ]
226
226
  },
227
+ {
228
+ "name": "DataViews",
229
+ "type": "components",
230
+ "path": "components/DataViews",
231
+ "npmDependencies": [
232
+ "@radix-ui/react-radio-group",
233
+ "@tanstack/react-virtual",
234
+ "lucide-react",
235
+ "react-hook-form"
236
+ ],
237
+ "registryDependencies": [
238
+ "components/Avatar",
239
+ "components/Badge",
240
+ "components/Button",
241
+ "components/Checkbox",
242
+ "components/ConclusionHeader",
243
+ "components/Divider",
244
+ "components/FormBuilder",
245
+ "components/Skeleton",
246
+ "components/Switch",
247
+ "components/TabSwitch",
248
+ "components/Table",
249
+ "components/TreeFolder",
250
+ "hooks/useDragDrop",
251
+ "hooks/useInfiniteScroll",
252
+ "layouts/DataViewCard",
253
+ "utils/cn",
254
+ "utils/dataViews",
255
+ "utils/types"
256
+ ]
257
+ },
227
258
  {
228
259
  "name": "DatePicker",
229
260
  "type": "components",
@@ -282,7 +313,6 @@
282
313
  "class-variance-authority"
283
314
  ],
284
315
  "registryDependencies": [
285
- "components/DropdownMenu",
286
316
  "utils/cn",
287
317
  "utils/types"
288
318
  ]
@@ -314,6 +344,67 @@
314
344
  "utils/types"
315
345
  ]
316
346
  },
347
+ {
348
+ "name": "FormBuilder",
349
+ "type": "components",
350
+ "path": "components/FormBuilder",
351
+ "npmDependencies": [
352
+ "@dnd-kit/core",
353
+ "@dnd-kit/sortable",
354
+ "@dnd-kit/utilities",
355
+ "@editorjs/editorjs",
356
+ "@radix-ui/react-slider",
357
+ "react-hook-form"
358
+ ],
359
+ "registryDependencies": [
360
+ "components/BadgeField",
361
+ "components/Button",
362
+ "components/Card",
363
+ "components/Checkbox",
364
+ "components/ColorPicker",
365
+ "components/DatePicker",
366
+ "components/FieldHint",
367
+ "components/Form",
368
+ "components/FormStepper",
369
+ "components/HeaderBar",
370
+ "components/ImageAttachment",
371
+ "components/Input",
372
+ "components/InputField",
373
+ "components/InputOTP",
374
+ "components/Label",
375
+ "components/LabeledCheckBox",
376
+ "components/PasswordLevel",
377
+ "components/Radio",
378
+ "components/RadioCard",
379
+ "components/SearchableSelect",
380
+ "components/SearchableTree",
381
+ "components/SectionBlock",
382
+ "components/Select",
383
+ "components/Switch",
384
+ "components/Table",
385
+ "components/TextEditor",
386
+ "components/Textarea",
387
+ "components/Tooltip",
388
+ "hooks/useTagSelection",
389
+ "layouts/FieldSection",
390
+ "utils/cn"
391
+ ]
392
+ },
393
+ {
394
+ "name": "FormRenderer",
395
+ "type": "components",
396
+ "path": "components/FormRenderer",
397
+ "npmDependencies": [
398
+ "@radix-ui/react-tabs",
399
+ "react-hook-form"
400
+ ],
401
+ "registryDependencies": [
402
+ "components/Drawer",
403
+ "components/FormBuilder",
404
+ "components/TabFormItem",
405
+ "utils/cn"
406
+ ]
407
+ },
317
408
  {
318
409
  "name": "FormStepper",
319
410
  "type": "components",
@@ -770,6 +861,39 @@
770
861
  "utils/cn"
771
862
  ]
772
863
  },
864
+ {
865
+ "name": "TextEditor",
866
+ "type": "components",
867
+ "path": "components/TextEditor",
868
+ "npmDependencies": [
869
+ "@editorjs/checklist",
870
+ "@editorjs/code",
871
+ "@editorjs/delimiter",
872
+ "@editorjs/editorjs",
873
+ "@editorjs/embed",
874
+ "@editorjs/header",
875
+ "@editorjs/inline-code",
876
+ "@editorjs/link",
877
+ "@editorjs/list",
878
+ "@editorjs/marker",
879
+ "@editorjs/nested-list",
880
+ "@editorjs/quote",
881
+ "@editorjs/raw",
882
+ "@editorjs/simple-image",
883
+ "@editorjs/table",
884
+ "@editorjs/text-variant-tune",
885
+ "@editorjs/underline",
886
+ "@editorjs/warning",
887
+ "chart.js",
888
+ "class-variance-authority",
889
+ "editorjs-undo"
890
+ ],
891
+ "registryDependencies": [
892
+ "components/DropdownMenu",
893
+ "utils/cn",
894
+ "utils/types"
895
+ ]
896
+ },
773
897
  {
774
898
  "name": "Timeline",
775
899
  "type": "components",
@@ -851,6 +975,19 @@
851
975
  "utils/cn"
852
976
  ]
853
977
  },
978
+ {
979
+ "name": "TreeFolder",
980
+ "type": "components",
981
+ "path": "components/TreeFolder",
982
+ "npmDependencies": [
983
+ "lucide-react"
984
+ ],
985
+ "registryDependencies": [
986
+ "hooks/useDragDrop",
987
+ "utils/cn",
988
+ "utils/types"
989
+ ]
990
+ },
854
991
  {
855
992
  "name": "useActiveTreeItem",
856
993
  "type": "hooks",
@@ -866,9 +1003,20 @@
866
1003
  "registryDependencies": []
867
1004
  },
868
1005
  {
869
- "name": "useDataViewsState",
1006
+ "name": "useDragDrop",
1007
+ "type": "hooks",
1008
+ "path": "hooks/useDragDrop.tsx",
1009
+ "npmDependencies": [
1010
+ "@dnd-kit/core",
1011
+ "@dnd-kit/sortable",
1012
+ "@dnd-kit/utilities"
1013
+ ],
1014
+ "registryDependencies": []
1015
+ },
1016
+ {
1017
+ "name": "useInfiniteScroll",
870
1018
  "type": "hooks",
871
- "path": "hooks/useDataViewsState.ts",
1019
+ "path": "hooks/useInfiniteScroll.ts",
872
1020
  "npmDependencies": [],
873
1021
  "registryDependencies": []
874
1022
  },
@@ -969,6 +1117,13 @@
969
1117
  "npmDependencies": [],
970
1118
  "registryDependencies": []
971
1119
  },
1120
+ {
1121
+ "name": "dataViews",
1122
+ "type": "utils",
1123
+ "path": "utils/dataViews",
1124
+ "npmDependencies": [],
1125
+ "registryDependencies": []
1126
+ },
972
1127
  {
973
1128
  "name": "dateFormat",
974
1129
  "type": "utils",