cursedbelt 5.28.0 → 5.30.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 (153) hide show
  1. package/dist/react/components/ColorField.d.ts.map +1 -1
  2. package/dist/react/components/ColorField.js +2 -1
  3. package/dist/react/components/ColorField.js.map +1 -1
  4. package/dist/react/components/ComboboxField.d.ts.map +1 -1
  5. package/dist/react/components/ComboboxField.js +2 -1
  6. package/dist/react/components/ComboboxField.js.map +1 -1
  7. package/dist/react/components/DataTable/DataTable.d.ts +39 -2
  8. package/dist/react/components/DataTable/DataTable.d.ts.map +1 -1
  9. package/dist/react/components/DataTable/DataTable.js +92 -22
  10. package/dist/react/components/DataTable/DataTable.js.map +1 -1
  11. package/dist/react/components/DataTable/ViewOptionsMenu.d.ts.map +1 -1
  12. package/dist/react/components/DataTable/ViewOptionsMenu.js +20 -7
  13. package/dist/react/components/DataTable/ViewOptionsMenu.js.map +1 -1
  14. package/dist/react/components/DataTable/types.d.ts +11 -1
  15. package/dist/react/components/DataTable/types.d.ts.map +1 -1
  16. package/dist/react/components/DataTable/types.js +6 -0
  17. package/dist/react/components/DataTable/types.js.map +1 -1
  18. package/dist/react/components/DatePicker.d.ts.map +1 -1
  19. package/dist/react/components/DatePicker.js +2 -1
  20. package/dist/react/components/DatePicker.js.map +1 -1
  21. package/dist/react/components/DateTimeField.d.ts.map +1 -1
  22. package/dist/react/components/DateTimeField.js +2 -1
  23. package/dist/react/components/DateTimeField.js.map +1 -1
  24. package/dist/react/components/ExpandableRow.d.ts +56 -0
  25. package/dist/react/components/ExpandableRow.d.ts.map +1 -0
  26. package/dist/react/components/ExpandableRow.js +54 -0
  27. package/dist/react/components/ExpandableRow.js.map +1 -0
  28. package/dist/react/components/Field.d.ts +20 -1
  29. package/dist/react/components/Field.d.ts.map +1 -1
  30. package/dist/react/components/Field.js +24 -11
  31. package/dist/react/components/Field.js.map +1 -1
  32. package/dist/react/components/FieldInput.d.ts +15 -0
  33. package/dist/react/components/FieldInput.d.ts.map +1 -1
  34. package/dist/react/components/FieldInput.js +20 -0
  35. package/dist/react/components/FieldInput.js.map +1 -1
  36. package/dist/react/components/FileDropZone.d.ts +23 -1
  37. package/dist/react/components/FileDropZone.d.ts.map +1 -1
  38. package/dist/react/components/FileDropZone.js +56 -8
  39. package/dist/react/components/FileDropZone.js.map +1 -1
  40. package/dist/react/components/FormPreviewLayout.d.ts +49 -0
  41. package/dist/react/components/FormPreviewLayout.d.ts.map +1 -0
  42. package/dist/react/components/FormPreviewLayout.js +36 -0
  43. package/dist/react/components/FormPreviewLayout.js.map +1 -0
  44. package/dist/react/components/Input.d.ts.map +1 -1
  45. package/dist/react/components/Input.js +3 -1
  46. package/dist/react/components/Input.js.map +1 -1
  47. package/dist/react/components/KeyBadge.d.ts +34 -0
  48. package/dist/react/components/KeyBadge.d.ts.map +1 -0
  49. package/dist/react/components/KeyBadge.js +24 -0
  50. package/dist/react/components/KeyBadge.js.map +1 -0
  51. package/dist/react/components/Modal.d.ts.map +1 -1
  52. package/dist/react/components/Modal.js +35 -9
  53. package/dist/react/components/Modal.js.map +1 -1
  54. package/dist/react/components/NativeSelect.d.ts.map +1 -1
  55. package/dist/react/components/NativeSelect.js +2 -1
  56. package/dist/react/components/NativeSelect.js.map +1 -1
  57. package/dist/react/components/RenderField.d.ts.map +1 -1
  58. package/dist/react/components/RenderField.js +2 -2
  59. package/dist/react/components/RenderField.js.map +1 -1
  60. package/dist/react/components/RevealAction.d.ts +33 -0
  61. package/dist/react/components/RevealAction.d.ts.map +1 -0
  62. package/dist/react/components/RevealAction.js +45 -0
  63. package/dist/react/components/RevealAction.js.map +1 -0
  64. package/dist/react/components/SecretInput.d.ts.map +1 -1
  65. package/dist/react/components/SecretInput.js +2 -1
  66. package/dist/react/components/SecretInput.js.map +1 -1
  67. package/dist/react/components/SelectField.d.ts.map +1 -1
  68. package/dist/react/components/SelectField.js +2 -1
  69. package/dist/react/components/SelectField.js.map +1 -1
  70. package/dist/react/components/SettingsStrip.d.ts +22 -0
  71. package/dist/react/components/SettingsStrip.d.ts.map +1 -0
  72. package/dist/react/components/SettingsStrip.js +18 -0
  73. package/dist/react/components/SettingsStrip.js.map +1 -0
  74. package/dist/react/components/formKit.css +555 -0
  75. package/dist/react/components/formKit.d.ts +12 -0
  76. package/dist/react/components/formKit.d.ts.map +1 -0
  77. package/dist/react/components/formKit.js +14 -0
  78. package/dist/react/components/formKit.js.map +1 -0
  79. package/dist/react/filter-rail/RailSection.d.ts +2 -2
  80. package/dist/react/filter-rail/RailSection.d.ts.map +1 -1
  81. package/dist/react/filter-rail/RailSection.js +6 -61
  82. package/dist/react/filter-rail/RailSection.js.map +1 -1
  83. package/dist/react/index.d.ts +8 -3
  84. package/dist/react/index.d.ts.map +1 -1
  85. package/dist/react/index.js +8 -3
  86. package/dist/react/index.js.map +1 -1
  87. package/dist/react/lib/field.d.ts +43 -0
  88. package/dist/react/lib/field.d.ts.map +1 -1
  89. package/dist/react/lib/field.js +68 -0
  90. package/dist/react/lib/field.js.map +1 -1
  91. package/dist/react/media/PlayerStrip.d.ts +9 -1
  92. package/dist/react/media/PlayerStrip.d.ts.map +1 -1
  93. package/dist/react/media/PlayerStrip.js +29 -2
  94. package/dist/react/media/PlayerStrip.js.map +1 -1
  95. package/dist/react/media-gallery/rememberedPreference.d.ts +2 -0
  96. package/dist/react/media-gallery/rememberedPreference.d.ts.map +1 -0
  97. package/dist/react/media-gallery/rememberedPreference.js +75 -0
  98. package/dist/react/media-gallery/rememberedPreference.js.map +1 -0
  99. package/dist/styles-areas/analytics.css +2 -2
  100. package/dist/styles-areas/core.css +34 -28
  101. package/dist/styles-areas/data-table.css +2 -2
  102. package/dist/styles-areas/fields.css +3 -3
  103. package/dist/styles-areas/layout-engine.css +2 -2
  104. package/dist/styles-areas/nav.css +3 -3
  105. package/dist/styles-areas/wizard.css +2 -2
  106. package/dist/styles-areas/workbench.css +2 -2
  107. package/dist/styles-utilities.css +111 -9
  108. package/package.json +14 -1
  109. package/scripts/styleAreas.ts +2 -0
  110. package/src/react/components/ColorField.tsx +3 -1
  111. package/src/react/components/ComboboxField.tsx +3 -1
  112. package/src/react/components/DataTable/DataTable.spec.tsx +18 -0
  113. package/src/react/components/DataTable/DataTable.tsx +136 -22
  114. package/src/react/components/DataTable/ViewOptionsMenu.tsx +24 -9
  115. package/src/react/components/DataTable/selection.spec.tsx +57 -1
  116. package/src/react/components/DataTable/types.ts +12 -1
  117. package/src/react/components/DataTable/virtualize.spec.tsx +20 -0
  118. package/src/react/components/DatePicker.tsx +3 -1
  119. package/src/react/components/DateTimeField.tsx +3 -1
  120. package/src/react/components/ExpandableRow.tsx +146 -0
  121. package/src/react/components/Field.tsx +89 -13
  122. package/src/react/components/Field.width.spec.tsx +162 -0
  123. package/src/react/components/FieldInput.tsx +30 -0
  124. package/src/react/components/FileDropZone.spec.tsx +65 -0
  125. package/src/react/components/FileDropZone.tsx +83 -5
  126. package/src/react/components/FormPreviewLayout.tsx +94 -0
  127. package/src/react/components/Input.tsx +4 -1
  128. package/src/react/components/KeyBadge.tsx +52 -0
  129. package/src/react/components/Modal.tsx +58 -14
  130. package/src/react/components/NativeSelect.tsx +3 -1
  131. package/src/react/components/RenderField.tsx +2 -1
  132. package/src/react/components/RevealAction.tsx +83 -0
  133. package/src/react/components/SecretInput.tsx +3 -1
  134. package/src/react/components/SelectField.tsx +3 -1
  135. package/src/react/components/SettingsStrip.tsx +37 -0
  136. package/src/react/components/formKit.css +555 -0
  137. package/src/react/components/formKit.spec.tsx +138 -0
  138. package/src/react/components/formKit.ts +19 -0
  139. package/src/react/filter-rail/RailSection.tsx +6 -65
  140. package/src/react/index.ts +20 -2
  141. package/src/react/lib/field.ts +93 -0
  142. package/src/react/media/PlayerStrip.tsx +65 -20
  143. package/src/react/media/playerStrip.spec.tsx +23 -0
  144. package/src/react/media-gallery/rememberedPreference.ts +79 -0
  145. package/src/styles-areas/analytics.css +2 -2
  146. package/src/styles-areas/core.css +34 -28
  147. package/src/styles-areas/data-table.css +2 -2
  148. package/src/styles-areas/fields.css +3 -3
  149. package/src/styles-areas/layout-engine.css +2 -2
  150. package/src/styles-areas/nav.css +3 -3
  151. package/src/styles-areas/wizard.css +2 -2
  152. package/src/styles-areas/workbench.css +2 -2
  153. package/src/styles-utilities.css +111 -9
@@ -0,0 +1,75 @@
1
+ /**
2
+ * One remembered string preference: `localStorage` under `key`, re-read when the app SEEDS it from
3
+ * its server (`seedPreferences`), written and ANNOUNCED on the preference bus on every change so
4
+ * the app can carry it to other devices. `key === undefined` remembers nothing and returns `null`.
5
+ *
6
+ * Extracted from `RailSection` (its open state was the first reader) when `DataTable`'s column
7
+ * visibility became the second — owner, 2026-09-30, music: *"Allow hiding any column"*. A hidden
8
+ * column that is back on the next reload, or on the phone, was never hidden. Two copies of the
9
+ * seed/storage/page-memory dance would be two chances for one of them to forget a case.
10
+ */
11
+ import { useCallback, useSyncExternalStore } from 'react';
12
+ import { announcePreference, onPreferenceSeed } from './preferenceBus.js';
13
+ /** Every mounted reader, so a write re-renders the others sharing its key. */
14
+ const local = new Set();
15
+ /** Where a value goes when `localStorage` throws (Safari private mode, a sandboxed iframe). */
16
+ const memory = new Map();
17
+ /** Page memory first (a value `localStorage` refused to keep), then `localStorage`. */
18
+ function readStored(key) {
19
+ const kept = memory.get(key);
20
+ if (kept !== undefined)
21
+ return kept;
22
+ try {
23
+ return globalThis.localStorage?.getItem(key) ?? null;
24
+ }
25
+ catch {
26
+ return null;
27
+ }
28
+ }
29
+ export function useRememberedPreference(key) {
30
+ const subscribe = useCallback((changed) => {
31
+ if (!key)
32
+ return () => { };
33
+ const offSeed = onPreferenceSeed((keys) => {
34
+ if (!keys.includes(key))
35
+ return;
36
+ // The seed is the authority now; a value parked in page memory must not shadow it.
37
+ memory.delete(key);
38
+ changed();
39
+ });
40
+ // Another tab on the same origin changed it.
41
+ const onStorage = (event) => {
42
+ if (event.key === key)
43
+ changed();
44
+ };
45
+ globalThis.addEventListener?.('storage', onStorage);
46
+ local.add(changed);
47
+ return () => {
48
+ offSeed();
49
+ globalThis.removeEventListener?.('storage', onStorage);
50
+ local.delete(changed);
51
+ };
52
+ }, [key]);
53
+ const value = useSyncExternalStore(subscribe, () => (key ? readStored(key) : null), () => null);
54
+ const setValue = useCallback((next) => {
55
+ if (!key)
56
+ return;
57
+ try {
58
+ if (next === null)
59
+ globalThis.localStorage?.removeItem(key);
60
+ else
61
+ globalThis.localStorage?.setItem(key, next);
62
+ memory.delete(key);
63
+ }
64
+ catch {
65
+ // Unremembered across reloads, but it must still CHANGE: keep it in page memory, which
66
+ // `readStored` answers from first.
67
+ memory.set(key, next);
68
+ }
69
+ for (const changed of [...local])
70
+ changed();
71
+ announcePreference(key, next);
72
+ }, [key]);
73
+ return [value, setValue];
74
+ }
75
+ //# sourceMappingURL=rememberedPreference.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rememberedPreference.js","sourceRoot":"","sources":["../../../src/react/media-gallery/rememberedPreference.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,OAAO,EAAE,WAAW,EAAE,oBAAoB,EAAE,MAAM,OAAO,CAAC;AAC1D,OAAO,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAE1E,8EAA8E;AAC9E,MAAM,KAAK,GAAG,IAAI,GAAG,EAAc,CAAC;AACpC,+FAA+F;AAC/F,MAAM,MAAM,GAAG,IAAI,GAAG,EAAyB,CAAC;AAEhD,uFAAuF;AACvF,SAAS,UAAU,CAAC,GAAW;IAC7B,MAAM,IAAI,GAAG,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IAC7B,IAAI,IAAI,KAAK,SAAS;QAAE,OAAO,IAAI,CAAC;IACpC,IAAI,CAAC;QACH,OAAO,UAAU,CAAC,YAAY,EAAE,OAAO,CAAC,GAAG,CAAC,IAAI,IAAI,CAAC;IACvD,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED,MAAM,UAAU,uBAAuB,CACrC,GAAuB;IAEvB,MAAM,SAAS,GAAG,WAAW,CAC3B,CAAC,OAAmB,EAAE,EAAE;QACtB,IAAI,CAAC,GAAG;YAAE,OAAO,GAAG,EAAE,GAAE,CAAC,CAAC;QAC1B,MAAM,OAAO,GAAG,gBAAgB,CAAC,CAAC,IAAI,EAAE,EAAE;YACxC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC;gBAAE,OAAO;YAChC,mFAAmF;YACnF,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YACnB,OAAO,EAAE,CAAC;QACZ,CAAC,CAAC,CAAC;QACH,6CAA6C;QAC7C,MAAM,SAAS,GAAG,CAAC,KAAmB,EAAE,EAAE;YACxC,IAAI,KAAK,CAAC,GAAG,KAAK,GAAG;gBAAE,OAAO,EAAE,CAAC;QACnC,CAAC,CAAC;QACF,UAAU,CAAC,gBAAgB,EAAE,CAAC,SAAS,EAAE,SAAS,CAAC,CAAC;QACpD,KAAK,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;QACnB,OAAO,GAAG,EAAE;YACV,OAAO,EAAE,CAAC;YACV,UAAU,CAAC,mBAAmB,EAAE,CAAC,SAAS,EAAE,SAAS,CAAC,CAAC;YACvD,KAAK,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;QACxB,CAAC,CAAC;IACJ,CAAC,EACD,CAAC,GAAG,CAAC,CACN,CAAC;IACF,MAAM,KAAK,GAAG,oBAAoB,CAChC,SAAS,EACT,GAAG,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,EACpC,GAAG,EAAE,CAAC,IAAI,CACX,CAAC;IACF,MAAM,QAAQ,GAAG,WAAW,CAC1B,CAAC,IAAmB,EAAE,EAAE;QACtB,IAAI,CAAC,GAAG;YAAE,OAAO;QACjB,IAAI,CAAC;YACH,IAAI,IAAI,KAAK,IAAI;gBAAE,UAAU,CAAC,YAAY,EAAE,UAAU,CAAC,GAAG,CAAC,CAAC;;gBACvD,UAAU,CAAC,YAAY,EAAE,OAAO,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;YACjD,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QACrB,CAAC;QAAC,MAAM,CAAC;YACP,uFAAuF;YACvF,mCAAmC;YACnC,MAAM,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;QACxB,CAAC;QACD,KAAK,MAAM,OAAO,IAAI,CAAC,GAAG,KAAK,CAAC;YAAE,OAAO,EAAE,CAAC;QAC5C,kBAAkB,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;IAChC,CAAC,EACD,CAAC,GAAG,CAAC,CACN,CAAC;IACF,OAAO,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;AAC3B,CAAC"}
@@ -18,7 +18,7 @@
18
18
  * after an app's responsive variant (task 2124). An app that imports every area gets exactly
19
19
  * what `cursedbelt/styles-utilities.css` emits — proved rule by rule in
20
20
  * src/stylesAreas.spec.ts, which is also what fails when this file is stale.
21
- * 148 candidate(s).
21
+ * 147 candidate(s).
22
22
  *
23
23
  * Written by scripts/generateAreaStyles.ts (`bun run styles:areas`), which
24
24
  * `bun run build` runs. The map of what is in which area, and why the areas are
@@ -48,5 +48,5 @@
48
48
  @source inline("resize-none resize-y right-3 ring-field-error/30 rounded-l-xl rounded-r-xl rounded-t-xl");
49
49
  @source inline("self-center self-stretch shadow-[1px_0_0_0_var(--color-border)] shrink-[2] size-2 size-7");
50
50
  @source inline("slide-in-from-top-1 table-fixed text-accent-solid-foreground text-field-placeholder");
51
- @source inline("text-muted-foreground/60 text-right text-success text-warning text-xl to-transparent top-2 top-3");
51
+ @source inline("text-muted-foreground/60 text-right text-success text-warning text-xl to-transparent top-3");
52
52
  @source inline("tracking-wider transition-[transform,opacity] w-11 w-20 w-28 w-36 w-40 w-[352px]");
@@ -15,7 +15,7 @@
15
15
  * after an app's responsive variant (task 2124). An app that imports every area gets exactly
16
16
  * what `cursedbelt/styles-utilities.css` emits — proved rule by rule in
17
17
  * src/stylesAreas.spec.ts, which is also what fails when this file is stale.
18
- * 718 candidate(s).
18
+ * 751 candidate(s).
19
19
  *
20
20
  * Written by scripts/generateAreaStyles.ts (`bun run styles:areas`), which
21
21
  * `bun run build` runs. The map of what is in which area, and why the areas are
@@ -35,8 +35,8 @@
35
35
  @source inline("[&_.alert-icon]:text-muted-foreground [&_.alert-icon]:text-success [&_.alert-icon]:text-warning");
36
36
  @source inline("[&_[data-icon]]:text-accent [&_[data-icon]]:text-destructive [&_[data-icon]]:text-success");
37
37
  @source inline("[&_[data-icon]]:text-warning [&_svg]:shrink-0 [&_svg]:size-12 [&_svg]:size-4 [&_svg]:size-5");
38
- @source inline("[&_svg]:size-6 a absolute act active active:bg-accent alert alert-icon align align-middle an");
39
- @source inline("animate-in animate-progress-indeterminate animate-pulse animate-spin aria");
38
+ @source inline("[&_svg]:size-6 [--cbfk-sticky-top:-1rem] a absolute act active active:bg-accent alert alert-icon");
39
+ @source inline("align align-middle an animate-in animate-progress-indeterminate animate-pulse animate-spin aria");
40
40
  @source inline("aria-[invalid=true]:border-field-error aria-[invalid=true]:ring-field-error/30");
41
41
  @source inline("aria-disabled:opacity-30 aria-disabled:pointer-events-none b back backdrop backdrop-blur");
42
42
  @source inline("backdrop-blur-md backdrop-blur-sm bg bg-accent bg-accent-solid bg-accent/10 bg-accent/5");
@@ -105,14 +105,17 @@
105
105
  @source inline("inline-flex inset inset-0 inset-x-0 inset-y-0 invisible is iso isolate it item items");
106
106
  @source inline("items-baseline items-center items-end items-start just justify-between justify-center");
107
107
  @source inline("justify-end l leading leading-none leading-relaxed leading-snug left left-1/2 left-2 lg lg:px-8");
108
- @source inline("lower lowercase m m-0 max max-h max-h-[80vh] max-h-[calc(100dvh-2rem)]");
108
+ @source inline("lower lowercase m m-0 max max-h max-h-[80vh]");
109
109
  @source inline("max-h-[calc(var(--radix-popper-available-height,100dvh)-1rem)]");
110
- @source inline("max-h-[min(90dvh,calc(100dvh-2rem))] max-h-[var(--radix-select-content-available-height)]");
111
- @source inline("max-w-2xl max-w-4xl max-w-5xl max-w-[10rem] max-w-[calc(100vw-2rem)]");
112
- @source inline("max-w-[var(--reading-width)] max-w-full max-w-lg max-w-sm max-w-xl max-w-xs mb-0.5 mb-1 md");
113
- @source inline("md:divide-border md:divide-x md:flex-none md:flex-row md:inline md:w-1/3 md:w-2/5 min min-h-0");
114
- @source inline("min-h-11 min-h-[1lh] min-h-[var(--control-h-lg)] min-h-[var(--control-h-md)]");
115
- @source inline("min-h-[var(--control-h-sm)] min-w-0 min-w-11 min-w-[8rem]");
110
+ @source inline("max-h-[var(--radix-select-content-available-height)] max-sm:border-b-0 max-sm:border-x-0");
111
+ @source inline("max-sm:bottom-0 max-sm:data-[state=closed]:slide-out-to-bottom");
112
+ @source inline("max-sm:data-[state=open]:slide-in-from-bottom max-sm:h-dvh max-sm:hidden max-sm:inset-x-0");
113
+ @source inline("max-sm:max-h-[92dvh] max-sm:max-h-dvh max-sm:max-w-none max-sm:pt-6 max-sm:rounded-b-none");
114
+ @source inline("max-sm:rounded-none max-sm:rounded-t-2xl max-sm:touch-none max-sm:w-full max-w-2xl max-w-40");
115
+ @source inline("max-w-5xl max-w-[10rem] max-w-[var(--reading-width)] max-w-full max-w-lg max-w-md max-w-sm");
116
+ @source inline("max-w-xl max-w-xs mb-0.5 mb-1 md md:divide-border md:divide-x md:flex-none md:flex-row md:inline");
117
+ @source inline("md:w-1/3 md:w-2/5 min min-h-0 min-h-11 min-h-[1lh] min-h-[var(--control-h-lg)]");
118
+ @source inline("min-h-[var(--control-h-md)] min-h-[var(--control-h-sm)] min-w-0 min-w-11 min-w-[8rem]");
116
119
  @source inline("min-w-[var(--radix-select-trigger-width)] ml-1 ml-auto motion motion-reduce:animate-none mt-0.5");
117
120
  @source inline("mt-1 mt-2 mx-auto my my-1 object object-cover opacity opacity-0 opacity-30 opacity-40 opacity-50");
118
121
  @source inline("opacity-60 opacity-70 out outline outline-none over overflow overflow-auto overflow-hidden");
@@ -130,24 +133,27 @@
130
133
  @source inline("rounded-md rounded-none rounded-r-full rounded-sm rounded-xl ru run running s select select-all");
131
134
  @source inline("select-none shadow shadow-[var(--shadow-overlay)] shadow-[var(--shadow-popover)] shadow-none");
132
135
  @source inline("shadow-overlay shadow-raised shadow-sm shrink shrink-0 size size-0 size-1.5 size-10 size-12");
133
- @source inline("size-14 size-2.5 size-20 size-3 size-3.5 size-4 size-5 size-6 size-8 sm sm:block sm:p-4 sm:p-5");
134
- @source inline("sm:p-8 sm:px-6 sm:text-sm space space-y-1 space-y-3 sr-only static sticky stroke");
135
- @source inline("stroke-accent-solid stroke-destructive stroke-muted stroke-warning t ta tab table tabular-nums");
136
- @source inline("text text-2xl text-[0.6em] text-[10px] text-accent text-accent-strong text-base text-caption");
137
- @source inline("text-center text-current text-data text-destructive text-destructive-foreground");
138
- @source inline("text-destructive-strong text-emerald-700 text-field-error text-field-fg text-foreground text-h1");
139
- @source inline("text-h3 text-left text-lg text-meta text-muted-foreground text-popover-foreground text-sm");
140
- @source inline("text-success-strong text-tone-amber-fg text-tone-cyan-fg text-tone-emerald-fg");
141
- @source inline("text-tone-fuchsia-fg text-tone-lime-fg text-tone-orange-fg text-tone-purple-fg text-tone-rose-fg");
142
- @source inline("text-tone-sky-fg text-tone-slate-fg text-tone-teal-fg text-tone-violet-fg text-warning-strong");
143
- @source inline("text-white text-xs to top top-0 top-1/2 touch touch-manipulation touch-none track tracking");
144
- @source inline("tracking-tight tracking-wide transform transition transition-[stroke-dashoffset]");
145
- @source inline("transition-[width] transition-all transition-colors transition-opacity transition-transform");
146
- @source inline("translate-x-1/2 translate-y-1/2 truncate under underline underline-offset-4 up uppercase v");
147
- @source inline("visible w-1 w-1/3 w-10 w-16 w-2.5 w-24 w-3/4 w-4 w-6 w-7 w-8 w-9 w-[3px] w-[calc(100vw-2rem)]");
148
- @source inline("w-[var(--control-h-lg)] w-[var(--control-h-md)] w-[var(--control-h-sm)] w-auto w-full w-px white");
149
- @source inline("whitespace-nowrap whitespace-pre-wrap wrap wrap-anywhere wrap-break-word z z-10 z-20 z-30 z-40");
150
- @source inline("z-50 z-[var(--z-popover)]");
136
+ @source inline("size-14 size-2.5 size-20 size-3 size-3.5 size-4 size-5 size-6 size-8 sm sm:-translate-x-1/2");
137
+ @source inline("sm:-translate-y-1/2 sm:block sm:data-[state=closed]:zoom-out-95 sm:data-[state=open]:zoom-in-95");
138
+ @source inline("sm:hidden sm:left-1/2 sm:max-h-[calc(100dvh-2rem)] sm:max-h-[min(90dvh,calc(100dvh-2rem))]");
139
+ @source inline("sm:max-w-2xl sm:max-w-4xl sm:max-w-[calc(100vw-2rem)] sm:max-w-lg sm:max-w-sm sm:p-4 sm:p-5");
140
+ @source inline("sm:p-8 sm:px-6 sm:rounded-xl sm:text-sm sm:top-1/2 sm:w-[calc(100vw-2rem)] space space-y-1");
141
+ @source inline("space-y-3 sr-only static sticky stroke stroke-accent-solid stroke-destructive stroke-muted");
142
+ @source inline("stroke-warning t ta tab table tabular-nums text text-2xl text-[0.6em] text-[10px] text-accent");
143
+ @source inline("text-accent-strong text-base text-caption text-center text-current text-data text-destructive");
144
+ @source inline("text-destructive-foreground text-destructive-strong text-emerald-700 text-field-error");
145
+ @source inline("text-field-fg text-foreground text-h1 text-h3 text-left text-lg text-meta text-muted-foreground");
146
+ @source inline("text-popover-foreground text-sm text-success-strong text-tone-amber-fg text-tone-cyan-fg");
147
+ @source inline("text-tone-emerald-fg text-tone-fuchsia-fg text-tone-lime-fg text-tone-orange-fg");
148
+ @source inline("text-tone-purple-fg text-tone-rose-fg text-tone-sky-fg text-tone-slate-fg text-tone-teal-fg");
149
+ @source inline("text-tone-violet-fg text-warning-strong text-white text-xs to top top-0 top-1/2 top-2 touch");
150
+ @source inline("touch-manipulation touch-none track tracking tracking-tight tracking-wide transform transition");
151
+ @source inline("transition-[stroke-dashoffset] transition-[width] transition-all transition-colors");
152
+ @source inline("transition-opacity transition-transform translate-x-1/2 translate-y-1/2 truncate under underline");
153
+ @source inline("underline-offset-4 up uppercase v visible w-1 w-1/3 w-10 w-16 w-2.5 w-24 w-3/4 w-4 w-6 w-7 w-8");
154
+ @source inline("w-9 w-[3px] w-[calc(100vw-2rem)] w-[var(--control-h-lg)] w-[var(--control-h-md)]");
155
+ @source inline("w-[var(--control-h-sm)] w-auto w-full w-px white whitespace-nowrap whitespace-pre-wrap wrap");
156
+ @source inline("wrap-anywhere wrap-break-word z z-10 z-20 z-30 z-40 z-50 z-[var(--z-popover)]");
151
157
 
152
158
  /*
153
159
  * Theme variables cursedbelt's components read BY NAME (`var(--color-card)` in a style prop).
@@ -18,7 +18,7 @@
18
18
  * after an app's responsive variant (task 2124). An app that imports every area gets exactly
19
19
  * what `cursedbelt/styles-utilities.css` emits — proved rule by rule in
20
20
  * src/stylesAreas.spec.ts, which is also what fails when this file is stale.
21
- * 144 candidate(s).
21
+ * 143 candidate(s).
22
22
  *
23
23
  * Written by scripts/generateAreaStyles.ts (`bun run styles:areas`), which
24
24
  * `bun run build` runs. The map of what is in which area, and why the areas are
@@ -48,5 +48,5 @@
48
48
  @source inline("ring-field-error/30 rounded-l-xl rounded-r-xl rounded-t-xl self-center self-stretch");
49
49
  @source inline("shadow-[1px_0_0_0_var(--color-border)] size-2 size-7 slide-in-from-top-1 table-fixed");
50
50
  @source inline("text-accent-solid-foreground text-field-placeholder text-muted-foreground/60 text-right");
51
- @source inline("text-success text-warning text-xl to-transparent top-2 top-3 tracking-wider");
51
+ @source inline("text-success text-warning text-xl to-transparent top-3 tracking-wider");
52
52
  @source inline("transition-[transform,opacity] w-11 w-20 w-28 w-36 w-40 w-[352px]");
@@ -18,7 +18,7 @@
18
18
  * after an app's responsive variant (task 2124). An app that imports every area gets exactly
19
19
  * what `cursedbelt/styles-utilities.css` emits — proved rule by rule in
20
20
  * src/stylesAreas.spec.ts, which is also what fails when this file is stale.
21
- * 116 candidate(s).
21
+ * 115 candidate(s).
22
22
  *
23
23
  * Written by scripts/generateAreaStyles.ts (`bun run styles:areas`), which
24
24
  * `bun run build` runs. The map of what is in which area, and why the areas are
@@ -39,13 +39,13 @@
39
39
  @source inline("group-focus-within:opacity-100 h-12 h-3.5 h-5 h-[420px]");
40
40
  @source inline("has-[[aria-invalid=true]]:border-field-error hover:bg-border hover:bg-destructive/10");
41
41
  @source inline("hover:bg-muted/50 hover:border-field-ring hover:scale-110 hover:text-warning italic leading-5");
42
- @source inline("left-0 left-2.5 list-none max-h-64 max-h-[40dvh] max-h-[65dvh] max-h-[85dvh] max-w-40 min-h-20");
42
+ @source inline("left-0 left-2.5 li list-none max-h-64 max-h-[40dvh] max-h-[65dvh] max-h-[85dvh] min-h-20");
43
43
  @source inline("min-w-24 min-w-64 min-w-[var(--anchor-width)] min-w-max mix-blend-difference mr-2 p-1.5 pl-1.5");
44
44
  @source inline("pl-2 pl-2.5 pointer-coarse:before:absolute pointer-coarse:before:bottom-[-10px]");
45
45
  @source inline("pointer-coarse:before:left-[-4px] pointer-coarse:before:right-[-4px]");
46
46
  @source inline("pointer-coarse:before:top-[-10px] pointer-coarse:items-center pr-1 pr-16 pr-2 pr-3 pr-9");
47
47
  @source inline("resize-none resize-y right-1.5 right-3 ring-accent/30 ring-field-error/30 rounded-l-xl");
48
48
  @source inline("rounded-r-xl rounded-t-xl self-stretch size-2 size-7 size-9 sm:w-11 sm:w-56");
49
- @source inline("text-field-placeholder text-right text-success text-warning text-xl top-1.5 top-2");
49
+ @source inline("text-field-placeholder text-right text-success text-warning text-xl top-1.5");
50
50
  @source inline("transition-[transform,opacity] w-20 w-28 w-40 w-[352px] w-fit w-max whitespace-pre");
51
51
  @source inline('pointer-coarse:before:content-[""]');
@@ -18,7 +18,7 @@
18
18
  * after an app's responsive variant (task 2124). An app that imports every area gets exactly
19
19
  * what `cursedbelt/styles-utilities.css` emits — proved rule by rule in
20
20
  * src/stylesAreas.spec.ts, which is also what fails when this file is stale.
21
- * 30 candidate(s).
21
+ * 29 candidate(s).
22
22
  *
23
23
  * Written by scripts/generateAreaStyles.ts (`bun run styles:areas`), which
24
24
  * `bun run build` runs. The map of what is in which area, and why the areas are
@@ -27,5 +27,5 @@
27
27
  @source inline("border-0 border-accent border-dashed collapse focus:border-accent focus:ring-1 focus:ring-ring");
28
28
  @source inline("gap-x-4 gap-y-3 grid-cols-1 grid-cols-12 hover:bg-accent/5 hover:border-border-strong");
29
29
  @source inline("justify-start lg:flex-row lg:inset-8 lg:items-start lg:w-72 mb-3 pt-1 ring-1 ring-accent");
30
- @source inline("ring-accent/40 self-start self-stretch sm:border sm:border-border sm:inset-4 sm:rounded-xl");
30
+ @source inline("ring-accent/40 self-start self-stretch sm:border sm:border-border sm:inset-4");
31
31
  @source inline("text-muted-foreground/60");
@@ -18,7 +18,7 @@
18
18
  * after an app's responsive variant (task 2124). An app that imports every area gets exactly
19
19
  * what `cursedbelt/styles-utilities.css` emits — proved rule by rule in
20
20
  * src/stylesAreas.spec.ts, which is also what fails when this file is stale.
21
- * 107 candidate(s).
21
+ * 106 candidate(s).
22
22
  *
23
23
  * Written by scripts/generateAreaStyles.ts (`bun run styles:areas`), which
24
24
  * `bun run build` runs. The map of what is in which area, and why the areas are
@@ -41,5 +41,5 @@
41
41
  @source inline("md:px-6 md:shrink-0 min-h-12 min-h-dvh min-w-3.5 min-w-8 min-w-9 mix-blend-difference mt-auto");
42
42
  @source inline("opacity-55 opacity-80 pb-1 pb-2 pb-[env(safe-area-inset-bottom,0px)] pl-9 place-items-center");
43
43
  @source inline("pr-9 pt-1 px-0.5 right-1 rounded-l-xl rounded-r-xl rounded-t-xl shadow-lg size-7 size-9");
44
- @source inline("sm:inline sm:inline-flex sm:pointer-coarse:w-auto space-y-0.5 space-y-2 text-[0.625rem] top-2");
45
- @source inline("w-0.5 w-52 w-56 w-60 w-max");
44
+ @source inline("sm:inline sm:inline-flex sm:pointer-coarse:w-auto space-y-0.5 space-y-2 text-[0.625rem] w-0.5");
45
+ @source inline("w-52 w-56 w-60 w-max");
@@ -18,7 +18,7 @@
18
18
  * after an app's responsive variant (task 2124). An app that imports every area gets exactly
19
19
  * what `cursedbelt/styles-utilities.css` emits — proved rule by rule in
20
20
  * src/stylesAreas.spec.ts, which is also what fails when this file is stale.
21
- * 64 candidate(s).
21
+ * 63 candidate(s).
22
22
  *
23
23
  * Written by scripts/generateAreaStyles.ts (`bun run styles:areas`), which
24
24
  * `bun run build` runs. The map of what is in which area, and why the areas are
@@ -37,4 +37,4 @@
37
37
  @source inline("hover:text-warning left-0 max-h-64 max-h-[40dvh] max-h-[65dvh] max-h-[85dvh] min-h-20 min-w-24");
38
38
  @source inline("min-w-[var(--anchor-width)] mr-1.5 mr-2 pl-1.5 pl-2 pr-1 pr-16 pr-3 resize-none resize-y");
39
39
  @source inline("ring-field-error/30 rounded-l-xl rounded-r-xl rounded-t-xl self-stretch size-2 size-7 sm:inline");
40
- @source inline("text-field-placeholder text-warning text-xl top-2 transition-[transform,opacity] w-28 w-[352px]");
40
+ @source inline("text-field-placeholder text-warning text-xl transition-[transform,opacity] w-28 w-[352px]");
@@ -18,7 +18,7 @@
18
18
  * after an app's responsive variant (task 2124). An app that imports every area gets exactly
19
19
  * what `cursedbelt/styles-utilities.css` emits — proved rule by rule in
20
20
  * src/stylesAreas.spec.ts, which is also what fails when this file is stale.
21
- * 105 candidate(s).
21
+ * 106 candidate(s).
22
22
  *
23
23
  * Written by scripts/generateAreaStyles.ts (`bun run styles:areas`), which
24
24
  * `bun run build` runs. The map of what is in which area, and why the areas are
@@ -34,7 +34,7 @@
34
34
  @source inline("h-3.5 h-40 h-[420px] hover:bg-card-overlay hover:bg-muted-foreground/10 hover:bg-muted/80");
35
35
  @source inline("hover:border-border-strong hover:border-field-ring hover:shadow-popover italic left-0");
36
36
  @source inline("max-h-[40dvh] max-h-[65dvh] max-h-[85dvh] max-h-full min-h min-h-20 min-h-[2.25rem] min-h-[44px]");
37
- @source inline("min-h-dvh min-h-full min-w-40 min-w-[5rem] opacity-100 pb-0.5");
37
+ @source inline("min-h-dvh min-h-full min-w-40 min-w-[5rem] opacity-100 pb-0.5 pb-4");
38
38
  @source inline("pb-[max(env(safe-area-inset-bottom,0px),0.5rem)] peer-focus peer-focus:outline-none");
39
39
  @source inline("peer-focus:ring-2 peer-focus:ring-field-ring/40 peer-focus:rounded-lg pl-1 pl-3");
40
40
  @source inline("pointer-coarse:h-12 pointer-coarse:w-12 resize-none right-4 ring-1 ring-4 ring-accent/20");
@@ -84,6 +84,7 @@
84
84
  --spacing: 0.25rem;
85
85
  --container-xs: 20rem;
86
86
  --container-sm: 24rem;
87
+ --container-md: 28rem;
87
88
  --container-lg: 32rem;
88
89
  --container-xl: 36rem;
89
90
  --container-2xl: 42rem;
@@ -736,9 +737,6 @@
736
737
  .max-h-\[inherit\] {
737
738
  max-height: inherit;
738
739
  }
739
- .max-h-\[min\(90dvh\,calc\(100dvh-2rem\)\)\] {
740
- max-height: min(90dvh, calc(100dvh - 2rem));
741
- }
742
740
  .max-h-\[var\(--radix-popover-content-available-height\)\] {
743
741
  max-height: var(--radix-popover-content-available-height);
744
742
  }
@@ -931,9 +929,6 @@
931
929
  .max-w-2xl {
932
930
  max-width: var(--container-2xl);
933
931
  }
934
- .max-w-4xl {
935
- max-width: var(--container-4xl);
936
- }
937
932
  .max-w-5xl {
938
933
  max-width: var(--container-5xl);
939
934
  }
@@ -985,9 +980,6 @@
985
980
  .max-w-\[240px\] {
986
981
  max-width: 240px;
987
982
  }
988
- .max-w-\[calc\(100vw-2rem\)\] {
989
- max-width: calc(100vw - 2rem);
990
- }
991
983
  .max-w-\[var\(--reading-width\)\] {
992
984
  max-width: var(--reading-width);
993
985
  }
@@ -997,6 +989,9 @@
997
989
  .max-w-lg {
998
990
  max-width: var(--container-lg);
999
991
  }
992
+ .max-w-md {
993
+ max-width: var(--container-md);
994
+ }
1000
995
  .max-w-sm {
1001
996
  max-width: var(--container-sm);
1002
997
  }
@@ -3175,6 +3170,9 @@
3175
3170
  -webkit-user-select: text;
3176
3171
  user-select: text;
3177
3172
  }
3173
+ .\[--cbfk-sticky-top\:-1rem\] {
3174
+ --cbfk-sticky-top: -1rem;
3175
+ }
3178
3176
  .fade-in {
3179
3177
  --tw-enter-opacity: 0;
3180
3178
  }
@@ -3995,23 +3993,84 @@
3995
3993
  }
3996
3994
  }
3997
3995
  @media (width < 40rem) {
3996
+ .max-sm\:inset-x-0 {
3997
+ inset-inline: 0px;
3998
+ }
3999
+ .max-sm\:bottom-0 {
4000
+ bottom: 0px;
4001
+ }
4002
+ .max-sm\:hidden {
4003
+ display: none;
4004
+ }
4005
+ .max-sm\:h-dvh {
4006
+ height: 100dvh;
4007
+ }
4008
+ .max-sm\:max-h-\[92dvh\] {
4009
+ max-height: 92dvh;
4010
+ }
4011
+ .max-sm\:max-h-dvh {
4012
+ max-height: 100dvh;
4013
+ }
3998
4014
  .max-sm\:w-10 {
3999
4015
  width: calc(var(--spacing) * 10);
4000
4016
  }
4017
+ .max-sm\:w-full {
4018
+ width: 100%;
4019
+ }
4020
+ .max-sm\:max-w-none {
4021
+ max-width: none;
4022
+ }
4001
4023
  .max-sm\:flex-none {
4002
4024
  flex: none;
4003
4025
  }
4026
+ .max-sm\:touch-none {
4027
+ touch-action: none;
4028
+ }
4004
4029
  .max-sm\:justify-center {
4005
4030
  justify-content: center;
4006
4031
  }
4032
+ .max-sm\:rounded-none {
4033
+ border-radius: 0;
4034
+ }
4035
+ .max-sm\:rounded-t-2xl {
4036
+ border-top-left-radius: var(--radius-2xl);
4037
+ border-top-right-radius: var(--radius-2xl);
4038
+ }
4039
+ .max-sm\:rounded-b-none {
4040
+ border-bottom-right-radius: 0;
4041
+ border-bottom-left-radius: 0;
4042
+ }
4043
+ .max-sm\:border-x-0 {
4044
+ border-inline-style: var(--tw-border-style);
4045
+ border-inline-width: 0px;
4046
+ }
4047
+ .max-sm\:border-b-0 {
4048
+ border-bottom-style: var(--tw-border-style);
4049
+ border-bottom-width: 0px;
4050
+ }
4007
4051
  .max-sm\:px-0 {
4008
4052
  padding-inline: 0px;
4009
4053
  }
4054
+ .max-sm\:pt-6 {
4055
+ padding-top: calc(var(--spacing) * 6);
4056
+ }
4057
+ .max-sm\:data-\[state\=closed\]\:slide-out-to-bottom[data-state="closed"] {
4058
+ --tw-exit-translate-y: 100%;
4059
+ }
4060
+ .max-sm\:data-\[state\=open\]\:slide-in-from-bottom[data-state="open"] {
4061
+ --tw-enter-translate-y: 100%;
4062
+ }
4010
4063
  }
4011
4064
  @media (width >= 40rem) {
4012
4065
  .sm\:inset-4 {
4013
4066
  inset: calc(var(--spacing) * 4);
4014
4067
  }
4068
+ .sm\:top-1\/2 {
4069
+ top: calc(1 / 2 * 100%);
4070
+ }
4071
+ .sm\:left-1\/2 {
4072
+ left: calc(1 / 2 * 100%);
4073
+ }
4015
4074
  .sm\:col-auto {
4016
4075
  grid-column: auto;
4017
4076
  }
@@ -4024,6 +4083,9 @@
4024
4083
  .sm\:block {
4025
4084
  display: block;
4026
4085
  }
4086
+ .sm\:hidden {
4087
+ display: none;
4088
+ }
4027
4089
  .sm\:inline {
4028
4090
  display: inline;
4029
4091
  }
@@ -4033,6 +4095,12 @@
4033
4095
  .sm\:inline-flex {
4034
4096
  display: inline-flex;
4035
4097
  }
4098
+ .sm\:max-h-\[calc\(100dvh-2rem\)\] {
4099
+ max-height: calc(100dvh - 2rem);
4100
+ }
4101
+ .sm\:max-h-\[min\(90dvh\,calc\(100dvh-2rem\)\)\] {
4102
+ max-height: min(90dvh, calc(100dvh - 2rem));
4103
+ }
4036
4104
  .sm\:min-h-0 {
4037
4105
  min-height: 0px;
4038
4106
  }
@@ -4045,6 +4113,32 @@
4045
4113
  .sm\:w-56 {
4046
4114
  width: calc(var(--spacing) * 56);
4047
4115
  }
4116
+ .sm\:w-\[calc\(100vw-2rem\)\] {
4117
+ width: calc(100vw - 2rem);
4118
+ }
4119
+ .sm\:max-w-2xl {
4120
+ max-width: var(--container-2xl);
4121
+ }
4122
+ .sm\:max-w-4xl {
4123
+ max-width: var(--container-4xl);
4124
+ }
4125
+ .sm\:max-w-\[calc\(100vw-2rem\)\] {
4126
+ max-width: calc(100vw - 2rem);
4127
+ }
4128
+ .sm\:max-w-lg {
4129
+ max-width: var(--container-lg);
4130
+ }
4131
+ .sm\:max-w-sm {
4132
+ max-width: var(--container-sm);
4133
+ }
4134
+ .sm\:-translate-x-1\/2 {
4135
+ --tw-translate-x: calc(calc(1 / 2 * 100%) * -1);
4136
+ translate: var(--tw-translate-x) var(--tw-translate-y);
4137
+ }
4138
+ .sm\:-translate-y-1\/2 {
4139
+ --tw-translate-y: calc(calc(1 / 2 * 100%) * -1);
4140
+ translate: var(--tw-translate-x) var(--tw-translate-y);
4141
+ }
4048
4142
  .sm\:grid-cols-2 {
4049
4143
  grid-template-columns: repeat(2, minmax(0, 1fr));
4050
4144
  }
@@ -4102,6 +4196,14 @@
4102
4196
  font-size: var(--text-xs);
4103
4197
  line-height: var(--tw-leading, var(--text-xs--line-height));
4104
4198
  }
4199
+ .sm\:data-\[state\=closed\]\:zoom-out-95[data-state="closed"] {
4200
+ --tw-exit-scale: calc(95*1%);
4201
+ --tw-exit-scale: .95;
4202
+ }
4203
+ .sm\:data-\[state\=open\]\:zoom-in-95[data-state="open"] {
4204
+ --tw-enter-scale: calc(95*1%);
4205
+ --tw-enter-scale: .95;
4206
+ }
4105
4207
  }
4106
4208
  @media (width >= 48rem) {
4107
4209
  .md\:flex {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cursedbelt",
3
- "version": "5.28.0",
3
+ "version": "5.30.0",
4
4
  "license": "ISC",
5
5
  "type": "module",
6
6
  "description": "The React design system of the cursedbelt split — components, styles, theme. cursedbelt-core below it; server tier in cursedbelt-server.",
@@ -24,6 +24,7 @@
24
24
  "./react/dashboard-grid",
25
25
  "./react/diff-viewer",
26
26
  "./react/file-tree",
27
+ "./react/form-kit",
27
28
  "./react/markdown-doc",
28
29
  "./react/media",
29
30
  "./react/media-gallery",
@@ -229,6 +230,12 @@
229
230
  "source": "./src/react/folder-tree/index.ts",
230
231
  "import": "./dist/react/folder-tree/index.js"
231
232
  },
233
+ "./react/form-kit": {
234
+ "types": "./dist/react/components/formKit.d.ts",
235
+ "bun": "./src/react/components/formKit.ts",
236
+ "source": "./src/react/components/formKit.ts",
237
+ "import": "./dist/react/components/formKit.js"
238
+ },
232
239
  "./react/icon-button": {
233
240
  "types": "./dist/react/components/IconButton.d.ts",
234
241
  "bun": "./src/react/components/IconButton.tsx",
@@ -379,6 +386,12 @@
379
386
  "source": "./src/react/hooks/useListSelection.ts",
380
387
  "import": "./dist/react/hooks/useListSelection.js"
381
388
  },
389
+ "./react/swipe-to-dismiss": {
390
+ "types": "./dist/react/hooks/useSwipeToDismiss.d.ts",
391
+ "bun": "./src/react/hooks/useSwipeToDismiss.ts",
392
+ "source": "./src/react/hooks/useSwipeToDismiss.ts",
393
+ "import": "./dist/react/hooks/useSwipeToDismiss.js"
394
+ },
382
395
  "./react/table-sort": {
383
396
  "types": "./dist/react/hooks/useTableSort.d.ts",
384
397
  "bun": "./src/react/hooks/useTableSort.ts",
@@ -245,6 +245,8 @@ export const AREAS: readonly Area[] = [
245
245
  'components/ComboboxField.tsx',
246
246
  'components/EnvCompare.tsx',
247
247
  'components/EnvEditor.tsx',
248
+ // The builder-form kit — plain-CSS components, but each module's closure is scanned.
249
+ 'components/formKit.ts',
248
250
  'components/InlineEditableText.tsx',
249
251
  'components/JsonEditor.tsx',
250
252
  'components/MultiSelectField.tsx',
@@ -1,5 +1,5 @@
1
1
  import { cn } from '../lib/cn.js';
2
- import { CONTROL_HEIGHT_CLASS, type ControlSize } from '../lib/field.js';
2
+ import { CONTROL_HEIGHT_CLASS, type ControlSize, declareFieldWidth } from '../lib/field.js';
3
3
 
4
4
  export interface ColorFieldProps {
5
5
  /** The current color as a hex string (e.g. `#3b82f6`). */
@@ -82,3 +82,5 @@ export function ColorField({
82
82
  </div>
83
83
  );
84
84
  }
85
+
86
+ declareFieldWidth(ColorField, 'sm');
@@ -4,7 +4,7 @@ import { Combobox } from '@base-ui/react/combobox';
4
4
  import { Check, ChevronDown, Loader2, Plus, X } from 'lucide-react';
5
5
  import { useCallback, useEffect, useRef, useState } from 'react';
6
6
  import { cn } from '../lib/cn.js';
7
- import { CONTROL_HEIGHT_CLASS, CONTROL_MIN_HEIGHT_CLASS, type ControlSize } from '../lib/field.js';
7
+ import { CONTROL_HEIGHT_CLASS, CONTROL_MIN_HEIGHT_CLASS, type ControlSize, declareFieldWidth } from '../lib/field.js';
8
8
  import { FLOATING_COLLISION_PADDING,
9
9
  FLOATING_CONTENT_BASE, FLOATING_ITEM_BASE } from '../lib/floatingStyles.js';
10
10
  import { TAP_TARGET } from '../lib/tapTarget.js';
@@ -319,3 +319,5 @@ export function ComboboxField(props: ComboboxFieldProps) {
319
319
  </Combobox.Root>
320
320
  );
321
321
  }
322
+
323
+ declareFieldWidth(ComboboxField, (props) => (props.multiple ? 'full' : 'md'));
@@ -110,6 +110,24 @@ describe('DataTable', () => {
110
110
  expect(firstCell(container)).toBe('Row 11');
111
111
  });
112
112
 
113
+ test('a columns rebuild keeps the cells — the same DOM nodes, not a remount (music, 2026-09-29)', () => {
114
+ // A consumer's `columns` memo keyed on something that changes often (music's player: every
115
+ // play, pause and track) rebuilt the header/cell templates, and `flexRender` mounts a
116
+ // template as a component — so every rebuild remounted every cell and every cover <img>.
117
+ const withColumns = () => [
118
+ { ...COLUMNS[0], render: (p: Person) => <img alt={p.name} data-testid={`art-${p.name}`} src='/x.png' /> },
119
+ COLUMNS[1],
120
+ ] as ColDef<Person>[];
121
+ const { getByTestId, getAllByRole, rerender } = render(<DataTable columns={withColumns()} data={PEOPLE} mobileCards={false} />);
122
+ const img = getByTestId('art-Alice');
123
+ const header = getAllByRole('columnheader').find((h) => h.textContent?.includes('Name'));
124
+ const sortButton = header?.querySelector('button');
125
+ rerender(<DataTable columns={withColumns()} data={PEOPLE} mobileCards={false} />);
126
+ expect(getByTestId('art-Alice'), 'a new columns array remounted the cell').toBe(img);
127
+ const headerAfter = getAllByRole('columnheader').find((h) => h.textContent?.includes('Name'));
128
+ expect(headerAfter?.querySelector('button') ?? null, 'a new columns array remounted the header').toBe(sortButton ?? null);
129
+ });
130
+
113
131
  test('column visibility: hiding a column removes it from the table AND the card layer', () => {
114
132
  let table: Table<Person> | undefined;
115
133
  const { queryAllByText } = render(