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
@@ -1,12 +1,6 @@
1
1
  "use client";
2
2
 
3
- import {
4
- useEffect,
5
- useMemo,
6
- useState,
7
- type ElementType,
8
- type ReactNode,
9
- } from "react";
3
+ import { useEffect, useMemo, useState, type ElementType, type ReactNode } from "react";
10
4
  import { Badge } from "../Badge";
11
5
  import { FilterPanel } from "./FilterPanel";
12
6
  import {
@@ -37,16 +31,9 @@ import { Avatar, AvatarFallback } from "../Avatar";
37
31
  import { Card } from "../Card";
38
32
  import { Divider } from "../Divider";
39
33
  import { renderDetailView } from "../../utils/dataViews/nestedDataUtils";
40
- import {
41
- getByPath,
42
- setByPath,
43
- matchesFilterValues,
44
- } from "../../utils/dataViews/pathUtils";
34
+ import { getByPath, setByPath, matchesFilterValues } from "../../utils/dataViews/pathUtils";
45
35
  import { renderField } from "./fieldRenderers";
46
- import {
47
- resolveInboxConfig,
48
- visibleFields,
49
- } from "../../utils/dataViews/fieldUtils";
36
+ import { resolveInboxConfig, visibleFields } from "../../utils/dataViews/fieldUtils";
50
37
  import { useIsMobile } from "../../hooks/useIsMobile";
51
38
  import { resolveBadgeVariant } from "./badgeAdapter";
52
39
  import { InboxViewCard } from "./InboxViewCard";
@@ -62,24 +49,20 @@ export type InboxViewProps = {
62
49
  filterState?: FilterState;
63
50
  onFilterChange?: (filters: FilterState) => void;
64
51
  showFilters?: boolean;
65
- itemHref?: (item: DynamicRecord, id: any) => string;
52
+ itemHref?: (item: DynamicRecord, id: unknown) => string;
66
53
  /**
67
54
  * Component used to render each item's link when `itemHref` is set. Defaults
68
55
  * to a plain `<a>` (full-page navigation). Pass your router's link
69
56
  * (e.g. Next.js `Link`, React Router `Link`) for client-side navigation.
70
57
  */
71
58
  linkComponent?: ElementType;
72
- selectedItemId?: any;
59
+ selectedItemId?: unknown;
73
60
  renderDetail?: (item: DynamicRecord | null) => ReactNode;
74
61
  };
75
62
 
76
63
  type InboxFilter = "all" | "starred" | "priority";
77
64
 
78
- function getId(
79
- item: DynamicRecord,
80
- fallbackPath: string | undefined,
81
- idx: number,
82
- ): any {
65
+ function getId(item: DynamicRecord, fallbackPath: string | undefined, idx: number): unknown {
83
66
  if (item?.id != null) return item.id;
84
67
  if (fallbackPath) {
85
68
  const v = getByPath(item, fallbackPath);
@@ -88,7 +71,7 @@ function getId(
88
71
  return idx;
89
72
  }
90
73
 
91
- function getInitials(name: any): string {
74
+ function getInitials(name: unknown): string {
92
75
  const s = String(name ?? "?").trim();
93
76
  if (!s) return "?";
94
77
  return (
@@ -117,9 +100,7 @@ export function InboxView({
117
100
  renderDetail,
118
101
  }: InboxViewProps) {
119
102
  const isMobile = useIsMobile();
120
- const [selectedItem, setSelectedItem] = useState<DynamicRecord | null>(
121
- data[0] || null,
122
- );
103
+ const [selectedItem, setSelectedItem] = useState<DynamicRecord | null>(data[0] || null);
123
104
  const [inboxFilter, setInboxFilter] = useState<InboxFilter>("all");
124
105
  const [internalFilters, setInternalFilters] = useState<FilterState>({});
125
106
 
@@ -186,7 +167,7 @@ export function InboxView({
186
167
  return String(v).toLowerCase() === "high";
187
168
  };
188
169
 
189
- const toggleStar = (itemId: any) => {
170
+ const toggleStar = (itemId: unknown) => {
190
171
  if (!inboxCfg.starredField) return;
191
172
  const updatedData = data.map((item, idx) => {
192
173
  const cur = getId(item, idPath, idx);
@@ -201,11 +182,7 @@ export function InboxView({
201
182
  if (selectedItem && getId(selectedItem, idPath, -1) === itemId) {
202
183
  setSelectedItem((prev) =>
203
184
  prev && inboxCfg.starredField
204
- ? setByPath(
205
- prev,
206
- inboxCfg.starredField,
207
- !getByPath(prev, inboxCfg.starredField),
208
- )
185
+ ? setByPath(prev, inboxCfg.starredField, !getByPath(prev, inboxCfg.starredField))
209
186
  : prev,
210
187
  );
211
188
  }
@@ -233,8 +210,8 @@ export function InboxView({
233
210
  (inboxFilter === "starred" && isStarred(item)) ||
234
211
  (inboxFilter === "priority" && isHighPriority(item));
235
212
 
236
- const matchesFilters = Object.entries(activeFilters).every(
237
- ([path, filterValues]) => matchesFilterValues(item, path, filterValues),
213
+ const matchesFilters = Object.entries(activeFilters).every(([path, filterValues]) =>
214
+ matchesFilterValues(item, path, filterValues),
238
215
  );
239
216
 
240
217
  return matchesInboxFilter && matchesFilters;
@@ -242,12 +219,8 @@ export function InboxView({
242
219
  // eslint-disable-next-line react-hooks/exhaustive-deps
243
220
  }, [data, inboxFilter, activeFilters, inboxCfg]);
244
221
 
245
- const starredCount = inboxCfg.starredField
246
- ? data.filter((i) => isStarred(i)).length
247
- : 0;
248
- const priorityCount = inboxCfg.priorityField
249
- ? data.filter((i) => isHighPriority(i)).length
250
- : 0;
222
+ const starredCount = inboxCfg.starredField ? data.filter((i) => isStarred(i)).length : 0;
223
+ const priorityCount = inboxCfg.priorityField ? data.filter((i) => isHighPriority(i)).length : 0;
251
224
 
252
225
  const filtersEnabled = showFilters && config.showFilters !== false;
253
226
  const countBadge = resolveBadgeVariant("gray");
@@ -272,12 +245,7 @@ export function InboxView({
272
245
  >
273
246
  <InboxIcon className="h-4 w-4" />
274
247
  All Items
275
- <Badge
276
- {...countBadge}
277
- label={String(data.length)}
278
- className="ml-auto"
279
- size="XS"
280
- />
248
+ <Badge {...countBadge} label={String(data.length)} className="ml-auto" size="XS" />
281
249
  </TabFormItem>
282
250
  {inboxCfg.starredField && (
283
251
  <TabFormItem
@@ -350,14 +318,12 @@ export function InboxView({
350
318
  {filteredData.map((item, idx) => {
351
319
  const itemId = getId(item, idPath, idx);
352
320
  const selected =
353
- (selectedItemId != null &&
354
- String(selectedItemId) === String(itemId)) ||
355
- (selectedItem != null &&
356
- getId(selectedItem, idPath, -1) === itemId);
321
+ (selectedItemId != null && String(selectedItemId) === String(itemId)) ||
322
+ (selectedItem != null && getId(selectedItem, idPath, -1) === itemId);
357
323
 
358
324
  return (
359
325
  <InboxViewCard
360
- key={itemId}
326
+ key={itemId as string | number}
361
327
  item={item}
362
328
  rowFields={displayFields}
363
329
  selected={selected}
@@ -396,22 +362,14 @@ export function InboxView({
396
362
  <div className="flex items-start gap-4 mb-6">
397
363
  <Avatar className="h-12 w-12">
398
364
  <AvatarFallback className="bg-background-presentation-action-primary text-content-presentation-action-primary">
399
- {getInitials(
400
- previewField
401
- ? getByPath(selectedItem, previewField.path)
402
- : "",
403
- )}
365
+ {getInitials(previewField ? getByPath(selectedItem, previewField.path) : "")}
404
366
  </AvatarFallback>
405
367
  </Avatar>
406
368
  <div className="flex-1">
407
369
  <div className="flex items-start justify-between gap-4 mb-2">
408
370
  <div>
409
371
  <h2 className="text-xl font-semibold text-content-presentation-global-primary mb-1">
410
- {String(
411
- titleField
412
- ? getByPath(selectedItem, titleField.path)
413
- : "",
414
- )}
372
+ {String(titleField ? getByPath(selectedItem, titleField.path) : "")}
415
373
  </h2>
416
374
  {previewField && (
417
375
  <p className="text-sm text-content-presentation-global-tertiary">
@@ -424,9 +382,7 @@ export function InboxView({
424
382
  </div>
425
383
  {inboxCfg.starredField && (
426
384
  <button
427
- onClick={() =>
428
- toggleStar(getId(selectedItem, idPath, -1))
429
- }
385
+ onClick={() => toggleStar(getId(selectedItem, idPath, -1))}
430
386
  className="hover:text-content-presentation-badge-yellow transition-colors"
431
387
  aria-label="Toggle star"
432
388
  >
@@ -446,9 +402,7 @@ export function InboxView({
446
402
  const value = getByPath(selectedItem, field.path);
447
403
  if (value == null) return null;
448
404
  return (
449
- <span key={field.path}>
450
- {renderField(value, field, selectedItem)}
451
- </span>
405
+ <span key={field.path}>{renderField(value, field, selectedItem)}</span>
452
406
  );
453
407
  })}
454
408
  </div>
@@ -40,97 +40,88 @@ function pickRowFields(props: InboxViewCardProps): FieldConfig[] {
40
40
  return collected;
41
41
  }
42
42
 
43
- function pickDateField(
44
- rowFields: FieldConfig[],
45
- explicit?: FieldConfig,
46
- ): FieldConfig | undefined {
43
+ function pickDateField(rowFields: FieldConfig[], explicit?: FieldConfig): FieldConfig | undefined {
47
44
  if (explicit) return explicit;
48
45
  return rowFields.find((f) => f.type === "date");
49
46
  }
50
47
 
51
- export const InboxViewCard = forwardRef<HTMLDivElement, InboxViewCardProps>(
52
- (props, ref) => {
53
- const { item, selected = false, onSelect, href, linkComponent, className } =
54
- props;
55
- const allRowFields = pickRowFields(props);
56
- const dateField = pickDateField(allRowFields, props.dateField);
57
- const rowFields = dateField
58
- ? allRowFields.filter((f) => f.path !== dateField.path)
59
- : allRowFields;
60
- const dateLabel = props.dateLabel ?? "Created at:";
48
+ export const InboxViewCard = forwardRef<HTMLDivElement, InboxViewCardProps>((props, ref) => {
49
+ const { item, selected = false, onSelect, href, linkComponent, className } = props;
50
+ const allRowFields = pickRowFields(props);
51
+ const dateField = pickDateField(allRowFields, props.dateField);
52
+ const rowFields = dateField
53
+ ? allRowFields.filter((f) => f.path !== dateField.path)
54
+ : allRowFields;
55
+ const dateLabel = props.dateLabel ?? "Created at:";
61
56
 
62
- const cardClass = cn(
63
- "flex flex-col gap-2 p-3 cursor-pointer transition-colors",
64
- "bg-background-presentation-form-base",
65
- "border-y-2 border-transparent",
66
- !selected &&
67
- "hover:bg-[image:linear-gradient(0deg,rgba(151,72,255,0.05)_0%,rgba(151,72,255,0.05)_100%)] hover:border-y-[#AE71FF]",
68
- selected &&
69
- "bg-[image:linear-gradient(0deg,rgba(0,117,255,0.05)_0%,rgba(0,117,255,0.05)_100%)] border-y-border-presentation-state-focus",
70
- className,
71
- );
72
-
73
- const content: ReactNode = (
74
- <>
75
- <div className="flex flex-col gap-1 w-full">
76
- {rowFields.map((field, idx) => {
77
- const value = getByPath(item, field.path);
78
- return (
79
- <div key={field.path ?? idx} className="flex flex-col">
80
- <div className="flex items-center gap-2">
81
- <span className="w-[100px] shrink-0 typography-body-large-semibold text-content-presentation-global-secondary">
82
- {field.label ?? field.path}:
83
- </span>
84
- <span className="h-full py-0.5 flex items-center">
85
- <span className="block h-full w-px bg-black-alpha-15" />
86
- </span>
87
- <span className="flex-1 min-w-0 truncate typography-body-large-medium text-content-presentation-global-primary">
88
- {renderField(value, field, item)}
89
- </span>
90
- </div>
91
- {idx < rowFields.length - 1 && <Divider className="mt-1" />}
92
- </div>
93
- );
94
- })}
95
- </div>
57
+ const cardClass = cn(
58
+ "flex flex-col gap-2 p-3 cursor-pointer transition-colors",
59
+ "bg-background-presentation-form-base",
60
+ "border-y-2 border-transparent",
61
+ !selected &&
62
+ "hover:bg-[image:linear-gradient(0deg,rgba(151,72,255,0.05)_0%,rgba(151,72,255,0.05)_100%)] hover:border-y-[#AE71FF]",
63
+ selected &&
64
+ "bg-[image:linear-gradient(0deg,rgba(0,117,255,0.05)_0%,rgba(0,117,255,0.05)_100%)] border-y-border-presentation-state-focus",
65
+ className,
66
+ );
96
67
 
97
- {dateField && (
98
- <div className="flex items-center justify-end">
99
- <div className="inline-flex items-center gap-0.5 p-0.5 rounded-md bg-black-alpha-10">
100
- <div className="px-1 rounded-sm">
101
- <span className="typography-labels-medium-semibold text-content-presentation-global-primary">
102
- {dateLabel}
68
+ const content: ReactNode = (
69
+ <>
70
+ <div className="flex flex-col gap-1 w-full">
71
+ {rowFields.map((field, idx) => {
72
+ const value = getByPath(item, field.path);
73
+ return (
74
+ <div key={field.path ?? idx} className="flex flex-col">
75
+ <div className="flex items-center gap-2">
76
+ <span className="w-[100px] shrink-0 typography-body-large-semibold text-content-presentation-global-secondary">
77
+ {field.label ?? field.path}:
103
78
  </span>
104
- </div>
105
- <div className="px-1 rounded-sm bg-black-alpha-075">
106
- <span className="typography-labels-medium-semibold text-content-presentation-global-primary">
107
- {renderField(getByPath(item, dateField.path), dateField, item)}
79
+ <span className="h-full py-0.5 flex items-center">
80
+ <span className="block h-full w-px bg-black-alpha-15" />
81
+ </span>
82
+ <span className="flex-1 min-w-0 truncate typography-body-large-medium text-content-presentation-global-primary">
83
+ {renderField(value, field, item)}
108
84
  </span>
109
85
  </div>
86
+ {idx < rowFields.length - 1 && <Divider className="mt-1" />}
110
87
  </div>
111
- </div>
112
- )}
113
- </>
114
- );
88
+ );
89
+ })}
90
+ </div>
115
91
 
116
- if (href) {
117
- const LinkTag = (linkComponent ?? "a") as ElementType;
118
- return (
119
- <LinkTag
120
- href={href}
121
- className={cn(cardClass, "no-underline text-inherit")}
122
- >
123
- {content}
124
- </LinkTag>
125
- );
126
- }
92
+ {dateField && (
93
+ <div className="flex items-center justify-end">
94
+ <div className="inline-flex items-center gap-0.5 p-0.5 rounded-md bg-black-alpha-10">
95
+ <div className="px-1 rounded-sm">
96
+ <span className="typography-labels-medium-semibold text-content-presentation-global-primary">
97
+ {dateLabel}
98
+ </span>
99
+ </div>
100
+ <div className="px-1 rounded-sm bg-black-alpha-075">
101
+ <span className="typography-labels-medium-semibold text-content-presentation-global-primary">
102
+ {renderField(getByPath(item, dateField.path), dateField, item)}
103
+ </span>
104
+ </div>
105
+ </div>
106
+ </div>
107
+ )}
108
+ </>
109
+ );
127
110
 
111
+ if (href) {
112
+ const LinkTag = (linkComponent ?? "a") as ElementType;
128
113
  return (
129
- <div ref={ref} onClick={onSelect} className={cardClass}>
114
+ <LinkTag href={href} className={cn(cardClass, "no-underline text-inherit")}>
130
115
  {content}
131
- </div>
116
+ </LinkTag>
132
117
  );
133
- },
134
- );
118
+ }
119
+
120
+ return (
121
+ <div ref={ref} onClick={onSelect} className={cardClass}>
122
+ {content}
123
+ </div>
124
+ );
125
+ });
135
126
 
136
127
  InboxViewCard.displayName = "InboxViewCard";
@@ -70,11 +70,7 @@ type KanbanColumn = {
70
70
  items: DynamicRecord[];
71
71
  };
72
72
 
73
- function getId(
74
- item: DynamicRecord,
75
- fallbackPath: string | undefined,
76
- idx: number,
77
- ): any {
73
+ function getId(item: DynamicRecord, fallbackPath: string | undefined, idx: number): unknown {
78
74
  if (item?.id != null) return item.id;
79
75
  if (fallbackPath) {
80
76
  const v = getByPath(item, fallbackPath);
@@ -117,9 +113,7 @@ export function KanbanView({
117
113
  // palette rotation.
118
114
  const resolve = (key: string, paletteIdx: number) => ({
119
115
  title: overrides?.[key]?.label ?? key,
120
- color:
121
- overrides?.[key]?.color ??
122
- COLUMN_PALETTE[paletteIdx % COLUMN_PALETTE.length],
116
+ color: overrides?.[key]?.color ?? COLUMN_PALETTE[paletteIdx % COLUMN_PALETTE.length],
123
117
  });
124
118
 
125
119
  if (groupField?.variants) {
@@ -200,12 +194,9 @@ export function KanbanView({
200
194
 
201
195
  const renderCard = (item: DynamicRecord, idx: number) => {
202
196
  const itemId = getId(item, idPath, idx);
203
- const isDraggingThis =
204
- draggedItem != null && getId(draggedItem.item, idPath, -1) === itemId;
197
+ const isDraggingThis = draggedItem != null && getId(draggedItem.item, idPath, -1) === itemId;
205
198
  const titleFieldResolved = resolvedTitleField;
206
- const titleValue = titleFieldResolved
207
- ? getByPath(item, titleFieldResolved.path)
208
- : "";
199
+ const titleValue = titleFieldResolved ? getByPath(item, titleFieldResolved.path) : "";
209
200
  const bodyFields = displayFields.filter(
210
201
  (f) => f.path !== groupByField && f.path !== titleFieldResolved?.path,
211
202
  );
@@ -240,15 +231,11 @@ export function KanbanView({
240
231
 
241
232
  return (
242
233
  <DataViewCard
243
- key={itemId}
234
+ key={itemId as string | number}
244
235
  draggable={!isMobile}
245
236
  onDragStart={
246
237
  !isMobile
247
- ? () =>
248
- handleDragStart(
249
- item,
250
- String(getByPath(item, groupByField) ?? "Uncategorized"),
251
- )
238
+ ? () => handleDragStart(item, String(getByPath(item, groupByField) ?? "Uncategorized"))
252
239
  : undefined
253
240
  }
254
241
  onDragEnd={!isMobile ? handleDragEnd : undefined}
@@ -258,10 +245,7 @@ export function KanbanView({
258
245
  : "cursor-grab active:cursor-grabbing hover:shadow-md transition-shadow",
259
246
  !isMobile && isDraggingThis && "opacity-40",
260
247
  )}
261
- title={
262
- titleFieldResolved &&
263
- renderField(titleValue, titleFieldResolved, item)
264
- }
248
+ title={titleFieldResolved && renderField(titleValue, titleFieldResolved, item)}
265
249
  rows={rows}
266
250
  />
267
251
  );
@@ -288,8 +272,7 @@ export function KanbanView({
288
272
  <div className="h-full overflow-x-auto p-2 bg-background-presentation-body-primary">
289
273
  <div className="flex h-full gap-4" style={{ minWidth: "max-content" }}>
290
274
  {kanbanColumns.map((column, i) => {
291
- const isDropTarget =
292
- draggedItem != null && dragOverColumnId === column.id;
275
+ const isDropTarget = draggedItem != null && dragOverColumnId === column.id;
293
276
  return (
294
277
  <Fragment key={column.id}>
295
278
  <div
@@ -25,8 +25,7 @@ export function RadioRow({ value, label }: { value: string; label: string }) {
25
25
 
26
26
  // Shared <Switch> with the bright-green checked track (#0AC713) from the Figma
27
27
  // Switcher-1.0 "On" state, applied regardless of the panel's dark theme scope.
28
- const SWITCH_GREEN =
29
- "data-[state=checked]:bg-[#0AC713] data-[state=checked]:border-[#0AC713]";
28
+ const SWITCH_GREEN = "data-[state=checked]:bg-[#0AC713] data-[state=checked]:border-[#0AC713]";
30
29
 
31
30
  type DataViewsSwitchProps = {
32
31
  checked: boolean;
@@ -35,15 +34,6 @@ type DataViewsSwitchProps = {
35
34
 
36
35
  /** Column show/hide toggle: the library <Switch> pre-styled to the panel's
37
36
  * Figma green-checked spec. */
38
- export function DataViewsSwitch({
39
- checked,
40
- onCheckedChange,
41
- }: DataViewsSwitchProps) {
42
- return (
43
- <Switch
44
- checked={checked}
45
- onCheckedChange={onCheckedChange}
46
- className={SWITCH_GREEN}
47
- />
48
- );
37
+ export function DataViewsSwitch({ checked, onCheckedChange }: DataViewsSwitchProps) {
38
+ return <Switch checked={checked} onCheckedChange={onCheckedChange} className={SWITCH_GREEN} />;
49
39
  }