@adea-ai/ui 0.85.0 → 0.87.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 (229) hide show
  1. package/README.md +11 -1
  2. package/dist/NOTICE +34 -0
  3. package/dist/components/composites/action-button/action-button.d.ts.map +1 -1
  4. package/dist/components/composites/action-button/action-button.js +2 -2
  5. package/dist/components/composites/action-button/action-button.js.map +1 -1
  6. package/dist/components/composites/list-row/list-row.d.ts +6 -3
  7. package/dist/components/composites/list-row/list-row.d.ts.map +1 -1
  8. package/dist/components/composites/list-row/list-row.js +69 -7
  9. package/dist/components/composites/list-row/list-row.js.map +1 -1
  10. package/dist/components/composites/settings/settings.d.ts +9 -11
  11. package/dist/components/composites/settings/settings.d.ts.map +1 -1
  12. package/dist/components/composites/settings/settings.js +48 -33
  13. package/dist/components/composites/settings/settings.js.map +1 -1
  14. package/dist/components/conversation/message-composer.js +1 -1
  15. package/dist/components/conversation/scroll-follow.d.ts.map +1 -1
  16. package/dist/components/conversation/scroll-follow.js +95 -15
  17. package/dist/components/conversation/scroll-follow.js.map +1 -1
  18. package/dist/components/layout/app-shell/index.d.ts +1 -0
  19. package/dist/components/layout/app-shell/index.d.ts.map +1 -1
  20. package/dist/components/layout/app-shell/index.js +2 -1
  21. package/dist/components/layout/app-shell/skip-link.d.ts +11 -0
  22. package/dist/components/layout/app-shell/skip-link.d.ts.map +1 -0
  23. package/dist/components/layout/app-shell/skip-link.js +44 -0
  24. package/dist/components/layout/app-shell/skip-link.js.map +1 -0
  25. package/dist/components/layout/floating-preview/floating-preview.d.ts +12 -0
  26. package/dist/components/layout/floating-preview/floating-preview.d.ts.map +1 -0
  27. package/dist/components/layout/floating-preview/floating-preview.js +283 -0
  28. package/dist/components/layout/floating-preview/floating-preview.js.map +1 -0
  29. package/dist/components/layout/floating-preview/index.d.ts +3 -0
  30. package/dist/components/layout/floating-preview/index.d.ts.map +1 -0
  31. package/dist/components/layout/floating-preview/index.js +3 -0
  32. package/dist/components/layout/floating-preview/model.d.ts +74 -0
  33. package/dist/components/layout/floating-preview/model.d.ts.map +1 -0
  34. package/dist/components/layout/floating-preview/model.js +146 -0
  35. package/dist/components/layout/floating-preview/model.js.map +1 -0
  36. package/dist/components/theme/index.d.ts +1 -0
  37. package/dist/components/theme/index.d.ts.map +1 -1
  38. package/dist/components/theme/index.js +2 -1
  39. package/dist/components/theme/theme-mode-toggle.d.ts +10 -0
  40. package/dist/components/theme/theme-mode-toggle.d.ts.map +1 -0
  41. package/dist/components/theme/theme-mode-toggle.js +82 -0
  42. package/dist/components/theme/theme-mode-toggle.js.map +1 -0
  43. package/dist/components/ui/checkbox/checkbox.d.ts +2 -0
  44. package/dist/components/ui/checkbox/checkbox.d.ts.map +1 -1
  45. package/dist/components/ui/checkbox/checkbox.js +24 -3
  46. package/dist/components/ui/checkbox/checkbox.js.map +1 -1
  47. package/dist/components/ui/combobox/combobox.d.ts.map +1 -1
  48. package/dist/components/ui/combobox/combobox.js +41 -4
  49. package/dist/components/ui/combobox/combobox.js.map +1 -1
  50. package/dist/components/ui/combobox/index.d.ts +1 -0
  51. package/dist/components/ui/combobox/index.d.ts.map +1 -1
  52. package/dist/components/ui/combobox/index.js +2 -1
  53. package/dist/components/ui/combobox/value-combobox.d.ts +19 -0
  54. package/dist/components/ui/combobox/value-combobox.d.ts.map +1 -0
  55. package/dist/components/ui/combobox/value-combobox.js +42 -0
  56. package/dist/components/ui/combobox/value-combobox.js.map +1 -0
  57. package/dist/components/ui/empty/empty-state.d.ts +15 -0
  58. package/dist/components/ui/empty/empty-state.d.ts.map +1 -0
  59. package/dist/components/ui/empty/empty-state.js +96 -0
  60. package/dist/components/ui/empty/empty-state.js.map +1 -0
  61. package/dist/components/ui/empty/index.d.ts +1 -0
  62. package/dist/components/ui/empty/index.d.ts.map +1 -1
  63. package/dist/components/ui/empty/index.js +2 -1
  64. package/dist/components/ui/entity-icon/entity-icon.d.ts +4 -1
  65. package/dist/components/ui/entity-icon/entity-icon.d.ts.map +1 -1
  66. package/dist/components/ui/entity-icon/entity-icon.js +37 -13
  67. package/dist/components/ui/entity-icon/entity-icon.js.map +1 -1
  68. package/dist/components/ui/field/field.d.ts +36 -13
  69. package/dist/components/ui/field/field.d.ts.map +1 -1
  70. package/dist/components/ui/field/field.js +146 -24
  71. package/dist/components/ui/field/field.js.map +1 -1
  72. package/dist/components/ui/field/index.d.ts +3 -1
  73. package/dist/components/ui/field/index.d.ts.map +1 -1
  74. package/dist/components/ui/field/index.js +3 -2
  75. package/dist/components/ui/field/number-field.d.ts +19 -0
  76. package/dist/components/ui/field/number-field.d.ts.map +1 -0
  77. package/dist/components/ui/field/number-field.js +76 -0
  78. package/dist/components/ui/field/number-field.js.map +1 -0
  79. package/dist/components/ui/input/index.d.ts +1 -0
  80. package/dist/components/ui/input/index.d.ts.map +1 -1
  81. package/dist/components/ui/input/index.js +2 -1
  82. package/dist/components/ui/input/input-control.d.ts +11 -0
  83. package/dist/components/ui/input/input-control.d.ts.map +1 -0
  84. package/dist/components/ui/input/input-control.js +24 -0
  85. package/dist/components/ui/input/input-control.js.map +1 -0
  86. package/dist/components/ui/input/input.d.ts.map +1 -1
  87. package/dist/components/ui/input/input.js +56 -28
  88. package/dist/components/ui/input/input.js.map +1 -1
  89. package/dist/components/ui/input-group/index.d.ts +1 -0
  90. package/dist/components/ui/input-group/index.d.ts.map +1 -1
  91. package/dist/components/ui/input-group/index.js +2 -1
  92. package/dist/components/ui/input-group/input-group.d.ts.map +1 -1
  93. package/dist/components/ui/input-group/input-group.js +42 -5
  94. package/dist/components/ui/input-group/input-group.js.map +1 -1
  95. package/dist/components/ui/input-group/secret-input-group.d.ts +11 -0
  96. package/dist/components/ui/input-group/secret-input-group.d.ts.map +1 -0
  97. package/dist/components/ui/input-group/secret-input-group.js +67 -0
  98. package/dist/components/ui/input-group/secret-input-group.js.map +1 -0
  99. package/dist/components/ui/native-select/native-select.d.ts.map +1 -1
  100. package/dist/components/ui/native-select/native-select.js +39 -4
  101. package/dist/components/ui/native-select/native-select.js.map +1 -1
  102. package/dist/components/ui/progress/progress.d.ts.map +1 -1
  103. package/dist/components/ui/progress/progress.js +30 -18
  104. package/dist/components/ui/progress/progress.js.map +1 -1
  105. package/dist/components/ui/radio-group/radio-group.d.ts.map +1 -1
  106. package/dist/components/ui/radio-group/radio-group.js +41 -4
  107. package/dist/components/ui/radio-group/radio-group.js.map +1 -1
  108. package/dist/components/ui/switch/switch.d.ts +2 -0
  109. package/dist/components/ui/switch/switch.d.ts.map +1 -1
  110. package/dist/components/ui/switch/switch.js +24 -3
  111. package/dist/components/ui/switch/switch.js.map +1 -1
  112. package/dist/components/ui/tabs/tabs.js +1 -1
  113. package/dist/components/ui/tabs/tabs.js.map +1 -1
  114. package/dist/components/ui/text-link/index.d.ts +2 -0
  115. package/dist/components/ui/text-link/index.d.ts.map +1 -0
  116. package/dist/components/ui/text-link/index.js +2 -0
  117. package/dist/components/ui/text-link/text-link.d.ts +9 -0
  118. package/dist/components/ui/text-link/text-link.d.ts.map +1 -0
  119. package/dist/components/ui/text-link/text-link.js +30 -0
  120. package/dist/components/ui/text-link/text-link.js.map +1 -0
  121. package/dist/components/ui/textarea/textarea.d.ts.map +1 -1
  122. package/dist/components/ui/textarea/textarea.js +41 -4
  123. package/dist/components/ui/textarea/textarea.js.map +1 -1
  124. package/dist/index.d.ts +3 -0
  125. package/dist/index.d.ts.map +1 -1
  126. package/dist/index.js +18 -7
  127. package/dist/lib/clipboard.d.ts +3 -0
  128. package/dist/lib/clipboard.d.ts.map +1 -0
  129. package/dist/lib/clipboard.js +35 -0
  130. package/dist/lib/clipboard.js.map +1 -0
  131. package/dist/lib/download.d.ts +3 -0
  132. package/dist/lib/download.d.ts.map +1 -0
  133. package/dist/lib/download.js +31 -0
  134. package/dist/lib/download.js.map +1 -0
  135. package/dist/lib/form-field.d.ts +37 -0
  136. package/dist/lib/form-field.d.ts.map +1 -0
  137. package/dist/lib/form-field.js +47 -0
  138. package/dist/lib/form-field.js.map +1 -0
  139. package/dist/r/app-shell.json +5 -0
  140. package/dist/r/combobox.json +5 -0
  141. package/dist/r/empty.json +10 -1
  142. package/dist/r/field.json +7 -0
  143. package/dist/r/floating-preview.json +30 -0
  144. package/dist/r/input-group.json +6 -0
  145. package/dist/r/input.json +5 -0
  146. package/dist/r/lib.json +15 -0
  147. package/dist/r/list-row.json +1 -0
  148. package/dist/r/registry.json +112 -1
  149. package/dist/r/src/components/composites/action-button/action-button.tsx +5 -1
  150. package/dist/r/src/components/composites/list-row/list-row.tsx +81 -8
  151. package/dist/r/src/components/composites/settings/settings.tsx +67 -37
  152. package/dist/r/src/components/conversation/scroll-follow.ts +109 -15
  153. package/dist/r/src/components/layout/app-shell/index.ts +1 -0
  154. package/dist/r/src/components/layout/app-shell/skip-link.tsx +35 -0
  155. package/dist/r/src/components/layout/floating-preview/floating-preview.tsx +260 -0
  156. package/dist/r/src/components/layout/floating-preview/index.ts +2 -0
  157. package/dist/r/src/components/layout/floating-preview/model.ts +285 -0
  158. package/dist/r/src/components/theme/index.ts +1 -0
  159. package/dist/r/src/components/theme/theme-mode-toggle.tsx +56 -0
  160. package/dist/r/src/components/ui/checkbox/checkbox.tsx +20 -3
  161. package/dist/r/src/components/ui/combobox/combobox.tsx +24 -1
  162. package/dist/r/src/components/ui/combobox/index.ts +1 -0
  163. package/dist/r/src/components/ui/combobox/value-combobox.tsx +38 -0
  164. package/dist/r/src/components/ui/empty/empty-state.tsx +71 -0
  165. package/dist/r/src/components/ui/empty/index.ts +1 -0
  166. package/dist/r/src/components/ui/entity-icon/entity-icon.tsx +33 -2
  167. package/dist/r/src/components/ui/field/field.tsx +102 -5
  168. package/dist/r/src/components/ui/field/index.ts +5 -0
  169. package/dist/r/src/components/ui/field/number-field.tsx +71 -0
  170. package/dist/r/src/components/ui/input/index.ts +1 -0
  171. package/dist/r/src/components/ui/input/input-control.tsx +38 -0
  172. package/dist/r/src/components/ui/input/input.tsx +32 -20
  173. package/dist/r/src/components/ui/input-group/index.ts +1 -0
  174. package/dist/r/src/components/ui/input-group/input-group.tsx +25 -2
  175. package/dist/r/src/components/ui/input-group/secret-input-group.tsx +58 -0
  176. package/dist/r/src/components/ui/native-select/native-select.tsx +27 -1
  177. package/dist/r/src/components/ui/progress/progress.tsx +12 -8
  178. package/dist/r/src/components/ui/radio-group/radio-group.tsx +30 -2
  179. package/dist/r/src/components/ui/switch/switch.tsx +20 -3
  180. package/dist/r/src/components/ui/tabs/tabs.tsx +1 -1
  181. package/dist/r/src/components/ui/text-link/index.ts +2 -0
  182. package/dist/r/src/components/ui/text-link/text-link.tsx +28 -0
  183. package/dist/r/src/components/ui/textarea/textarea.tsx +24 -1
  184. package/dist/r/src/lib/clipboard.ts +41 -0
  185. package/dist/r/src/lib/download.ts +29 -0
  186. package/dist/r/src/lib/form-field.ts +93 -0
  187. package/dist/r/text-link.json +22 -0
  188. package/dist/r/theming.json +6 -0
  189. package/package.json +1 -1
  190. package/registry.json +112 -1
  191. package/src/components/composites/action-button/action-button.tsx +5 -1
  192. package/src/components/composites/list-row/list-row.tsx +81 -8
  193. package/src/components/composites/settings/settings.tsx +67 -37
  194. package/src/components/conversation/scroll-follow.ts +109 -15
  195. package/src/components/layout/app-shell/index.ts +1 -0
  196. package/src/components/layout/app-shell/skip-link.tsx +35 -0
  197. package/src/components/layout/floating-preview/floating-preview.tsx +260 -0
  198. package/src/components/layout/floating-preview/index.ts +2 -0
  199. package/src/components/layout/floating-preview/model.ts +285 -0
  200. package/src/components/theme/index.ts +1 -0
  201. package/src/components/theme/theme-mode-toggle.tsx +56 -0
  202. package/src/components/ui/checkbox/checkbox.tsx +20 -3
  203. package/src/components/ui/combobox/combobox.tsx +24 -1
  204. package/src/components/ui/combobox/index.ts +1 -0
  205. package/src/components/ui/combobox/value-combobox.tsx +38 -0
  206. package/src/components/ui/empty/empty-state.tsx +71 -0
  207. package/src/components/ui/empty/index.ts +1 -0
  208. package/src/components/ui/entity-icon/entity-icon.tsx +33 -2
  209. package/src/components/ui/field/field.tsx +102 -5
  210. package/src/components/ui/field/index.ts +5 -0
  211. package/src/components/ui/field/number-field.tsx +71 -0
  212. package/src/components/ui/input/index.ts +1 -0
  213. package/src/components/ui/input/input-control.tsx +38 -0
  214. package/src/components/ui/input/input.tsx +32 -20
  215. package/src/components/ui/input-group/index.ts +1 -0
  216. package/src/components/ui/input-group/input-group.tsx +25 -2
  217. package/src/components/ui/input-group/secret-input-group.tsx +58 -0
  218. package/src/components/ui/native-select/native-select.tsx +27 -1
  219. package/src/components/ui/progress/progress.tsx +12 -8
  220. package/src/components/ui/radio-group/radio-group.tsx +30 -2
  221. package/src/components/ui/switch/switch.tsx +20 -3
  222. package/src/components/ui/tabs/tabs.tsx +1 -1
  223. package/src/components/ui/text-link/index.ts +2 -0
  224. package/src/components/ui/text-link/text-link.tsx +28 -0
  225. package/src/components/ui/textarea/textarea.tsx +24 -1
  226. package/src/index.ts +3 -0
  227. package/src/lib/clipboard.ts +41 -0
  228. package/src/lib/download.ts +29 -0
  229. package/src/lib/form-field.ts +93 -0
package/README.md CHANGED
@@ -67,7 +67,9 @@ through. Use `value` with `onChange` for a controlled selection, or `defaultValu
67
67
  to initialize an uncontrolled one. Use `Select` for searchable, runtime, or
68
68
  longer lists that need a custom popover.
69
69
 
70
- For free-form text with native suggestions, pass `suggestions` to `Input`.
70
+ `InputControl` is the styled native input without suggestion-list behavior. Use
71
+ `Input` when a form should offer native datalist suggestions; custom values
72
+ remain valid and submit unchanged.
71
73
  The library owns the datalist and unique association; a suggestion does not
72
74
  restrict the submitted value. Native `required`, `pattern`, form, event, and
73
75
  ref props still apply to the input.
@@ -707,3 +709,11 @@ keyboard disclosure, visible actions and automated accessibility. This is shared
707
709
  composition evidence; bounded runtime projection, storage and production chat
708
710
  integration remain application acceptance gates. Attribution for the selected
709
711
  KiroCrew source contracts is recorded in the issue-specific `NOTICE` entry.
712
+
713
+ ### Controlled appearance mode
714
+
715
+ `ThemeModeToggle` provides the shared light/dark/system selector for hosts that
716
+ own their preference provider and storage. Pass `mode` and `onModeChange`; the
717
+ control owns roving keyboard focus, pressed state and explanatory tooltips. It
718
+ does not require or mount the shared `ThemeProvider`. `ThemeToggle` retains its
719
+ existing provider-bound API.
package/dist/NOTICE CHANGED
@@ -391,6 +391,40 @@ Redux and Framer Motion ownership. Relevant test contracts come from
391
391
  exercised in headless Chromium, WebKit and native Node SSR. Full runtime projection,
392
392
  durable application storage and production Chat adoption remain host-owned gates.
393
393
 
394
+ ## Floating preview geometry translated from t3code
395
+
396
+ `packages/ui/src/components/layout/floating-preview/model.ts` translates the
397
+ host-independent fitting, clamping, obstacle-avoidance and aspect-preserving
398
+ resize behavior from `apps/web/src/components/preview/previewMiniPlayerLayout.ts`
399
+ and its tests in t3code, issue #422, pinned at revision
400
+ `77bca8b2d76a1f42552e5eee7d277fcb1160347a`.
401
+
402
+ MIT License
403
+
404
+ Copyright (c) 2026 T3 Tools Inc.
405
+
406
+ Permission is hereby granted, free of charge, to any person obtaining a copy
407
+ of this software and associated documentation files (the "Software"), to deal
408
+ in the Software without restriction, including without limitation the rights
409
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
410
+ copies of the Software, and to permit persons to whom the Software is
411
+ furnished to do so, subject to the following conditions:
412
+
413
+ The above copyright notice and this permission notice shall be included in all
414
+ copies or substantial portions of the Software.
415
+
416
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
417
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
418
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
419
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
420
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
421
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
422
+ SOFTWARE.
423
+
424
+ The shared component owns reusable geometry and pointer/keyboard controls only.
425
+ T3 runtime state, streaming, Electron services, native picture-in-picture,
426
+ notifications and content rendering are not included.
427
+
394
428
  ## Catalog browser translated from KiroCrew (issue #425 selected unit)
395
429
 
396
430
  `packages/ui/src/components/composites/catalog-browser/` translates the
@@ -1 +1 @@
1
- {"version":3,"file":"action-button.d.ts","sourceRoot":"","sources":["../../../../src/components/composites/action-button/action-button.tsx"],"names":[],"mappings":"AAAA,OAAO,EAKL,KAAK,GAAG,EACR,KAAK,cAAc,EACpB,MAAM,UAAU,CAAA;AACjB,OAAO,EAAU,KAAK,WAAW,EAAE,MAAM,iBAAiB,CAAA;AAI1D;;;;;;;;;;;;;GAaG;AACH,MAAM,MAAM,iBAAiB,CAAC,CAAC,SAAS,cAAc,GAAG,QAAQ,IAAI,WAAW,CAAC,CAAC,CAAC,GAAG;IACpF,8FAA8F;IAC9F,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,WAAW,CAAC,EAAE,KAAK,GAAG,OAAO,GAAG,QAAQ,GAAG,MAAM,CAAA;IACjD,uFAAuF;IACvF,IAAI,CAAC,EAAE,OAAO,CAAA;IACd,uFAAuF;IACvF,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB,CAAA;AA+CD,wBAAgB,YAAY,CAAC,CAAC,SAAS,cAAc,GAAG,QAAQ,EAAE,KAAK,EAAE,iBAAiB,CAAC,CAAC,CAAC,eAkG5F"}
1
+ {"version":3,"file":"action-button.d.ts","sourceRoot":"","sources":["../../../../src/components/composites/action-button/action-button.tsx"],"names":[],"mappings":"AAAA,OAAO,EAKL,KAAK,GAAG,EACR,KAAK,cAAc,EACpB,MAAM,UAAU,CAAA;AACjB,OAAO,EAAU,KAAK,WAAW,EAAE,MAAM,iBAAiB,CAAA;AAI1D;;;;;;;;;;;;;GAaG;AACH,MAAM,MAAM,iBAAiB,CAAC,CAAC,SAAS,cAAc,GAAG,QAAQ,IAAI,WAAW,CAAC,CAAC,CAAC,GAAG;IACpF,8FAA8F;IAC9F,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,WAAW,CAAC,EAAE,KAAK,GAAG,OAAO,GAAG,QAAQ,GAAG,MAAM,CAAA;IACjD,uFAAuF;IACvF,IAAI,CAAC,EAAE,OAAO,CAAA;IACd,uFAAuF;IACvF,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB,CAAA;AA+CD,wBAAgB,YAAY,CAAC,CAAC,SAAS,cAAc,GAAG,QAAQ,EAAE,KAAK,EAAE,iBAAiB,CAAC,CAAC,CAAC,eAsG5F"}
@@ -1,6 +1,6 @@
1
1
  import { Button } from "../../ui/button/button.js";
2
- import { Tooltip, TooltipContent, TooltipTrigger } from "../../ui/tooltip/tooltip.js";
3
2
  import { Spinner } from "../../ui/spinner/spinner.js";
3
+ import { Tooltip, TooltipContent, TooltipTrigger } from "../../ui/tooltip/tooltip.js";
4
4
  import { createComponent, insert, memo, mergeProps, template } from "solid-js/web";
5
5
  import { Show, createSignal, splitProps } from "solid-js";
6
6
  //#region src/components/composites/action-button/action-button.tsx
@@ -64,7 +64,7 @@ function ActionButton(props) {
64
64
  class: [local.class, local.tooltip && disabled() && "aria-disabled:pointer-events-auto"].filter(Boolean).join(" "),
65
65
  disabled: disabled() && !local.tooltip,
66
66
  "aria-disabled": disabled() ? true : rest["aria-disabled"],
67
- tabIndex: local.as === "a" && disabled() ? local.tooltip ? 0 : -1 : rest.tabIndex,
67
+ tabIndex: rest.tabIndex ?? (local.as === "a" && disabled() ? local.tooltip ? 0 : -1 : local.tooltip ? 0 : void 0),
68
68
  role: local.as === "a" && disabled() ? "link" : rest.role,
69
69
  href: local.as === "a" && disabled() ? void 0 : rest.href,
70
70
  "aria-busy": busy() || local["aria-busy"],
@@ -1 +1 @@
1
- {"version":3,"file":"action-button.js","names":["Show","createSignal","splitProps","ComponentProps","JSX","ValidComponent","Button","ButtonProps","Spinner","Tooltip","TooltipContent","TooltipTrigger","ActionButtonProps","T","tooltip","tooltipSide","busy","busyLabel","invokeHandler","handler","event","Event","Array","isArray","callback","data","chainedHandler","before","guardedClick","disabled","onActivate","MouseEvent","preventDefault","stopImmediatePropagation","ButtonTargetProps","Omit","actionAs","ButtonTarget","props","local","rest","PolymorphicButton","targetProps","Element","_$createComponent","_$mergeProps","as","ActionButton","busyStatus","tooltipOpen","setTooltipOpen","tooltipSuppression","setTooltipSuppression","onClickCapture","buttonProps","PolymorphicButtonTarget","variant","size","class","filter","Boolean","join","tabIndex","role","href","undefined","onClick","detail","onPointerLeave","onBlur","Record","contents","when","children","label","_$memo","fallback","open","onOpenChange","side","_el$","_tmpl$","_$insert","_$createComponent","PolymorphicButton","_$mergeProps","_$memo"],"sources":["../../../../src/components/composites/action-button/action-button.tsx"],"sourcesContent":["import {\n Show,\n createSignal,\n splitProps,\n type ComponentProps,\n type JSX,\n type ValidComponent,\n} from 'solid-js'\nimport { Button, type ButtonProps } from '../../ui/button'\nimport { Spinner } from '../../ui/spinner'\nimport { Tooltip, TooltipContent, TooltipTrigger } from '../../ui/tooltip'\n\n/**\n * ActionButton.\n *\n * A Button with optional explanatory tooltip and busy feedback. Use it for a\n * simple action that needs these states; actions with product-specific rules\n * should compose Button directly.\n *\n * The tooltip trigger renders the polymorphic Button itself. A disabled native\n * control cannot receive pointer or keyboard events. When a tooltip is set,\n * disabled actions therefore use focusable `aria-disabled` semantics and guard\n * activation; without a tooltip, native buttons retain native disabling.\n * Custom polymorphic components must forward aria, event, and href props for\n * these guarantees to apply.\n */\nexport type ActionButtonProps<T extends ValidComponent = 'button'> = ButtonProps<T> & {\n /** A short explanation, also shown on keyboard focus. The Button still needs its own name. */\n tooltip?: string\n tooltipSide?: 'top' | 'right' | 'bottom' | 'left'\n /** Disables the action and announces the busy label through a polite status region. */\n busy?: boolean\n /** The activity announced while busy. The Button's accessible name stays unchanged. */\n busyLabel?: string\n}\n\nfunction invokeHandler(handler: unknown, event: Event) {\n if (Array.isArray(handler)) {\n const [callback, data] = handler as [(data: unknown, event: Event) => void, unknown]\n callback(data, event)\n } else if (typeof handler === 'function') {\n const callback = handler as (event: Event) => void\n callback(event)\n }\n}\n\nfunction chainedHandler(handler: unknown, before: (event: Event) => void) {\n return (event: Event) => {\n before(event)\n invokeHandler(handler, event)\n }\n}\n\nfunction guardedClick(\n handler: unknown,\n disabled: () => boolean,\n onActivate: (event: MouseEvent) => void = () => {}\n) {\n return (event: MouseEvent) => {\n if (disabled()) {\n event.preventDefault()\n event.stopImmediatePropagation()\n return\n }\n\n onActivate(event)\n invokeHandler(handler, event)\n }\n}\n\ntype ButtonTargetProps<T extends ValidComponent = 'button'> = Omit<ButtonProps<T>, 'as'> & {\n actionAs?: T\n}\n\n/** Adapter keeps TooltipTrigger's `as` separate from Button's polymorphic `as`. */\nfunction ButtonTarget<T extends ValidComponent = 'button'>(props: ButtonTargetProps<T>) {\n const [local, rest] = splitProps(props as ButtonTargetProps, ['actionAs'])\n const PolymorphicButton = Button as (targetProps: ButtonProps<T>) => JSX.Element\n return <PolymorphicButton as={(local.actionAs ?? 'button') as T} {...(rest as ButtonProps<T>)} />\n}\n\nexport function ActionButton<T extends ValidComponent = 'button'>(props: ActionButtonProps<T>) {\n const [local, rest] = splitProps(props as ActionButtonProps, [\n 'as',\n 'variant',\n 'size',\n 'class',\n 'children',\n 'disabled',\n 'aria-busy',\n 'tooltip',\n 'tooltipSide',\n 'busy',\n 'busyLabel',\n ])\n const busy = () => local.busy ?? false\n const disabled = () => busy() || !!local.disabled\n const busyStatus = () => local.busyLabel ?? 'Working'\n const [tooltipOpen, setTooltipOpen] = createSignal(false)\n const [tooltipSuppression, setTooltipSuppression] = createSignal<'pointer' | 'focus' | null>(null)\n const onClickCapture = (rest as { onClickCapture?: unknown }).onClickCapture\n const PolymorphicButton = Button as (buttonProps: ButtonProps<T>) => JSX.Element\n const PolymorphicButtonTarget = ButtonTarget as (targetProps: ButtonTargetProps<T>) => JSX.Element\n\n const buttonProps = () => ({\n ...rest,\n variant: local.variant,\n size: local.size,\n class: [local.class, local.tooltip && disabled() && 'aria-disabled:pointer-events-auto']\n .filter(Boolean)\n .join(' '),\n disabled: disabled() && !local.tooltip,\n 'aria-disabled': disabled() ? true : rest['aria-disabled'],\n tabIndex: local.as === 'a' && disabled() ? (local.tooltip ? 0 : -1) : rest.tabIndex,\n role: local.as === 'a' && disabled() ? 'link' : rest.role,\n href: local.as === 'a' && disabled() ? undefined : (rest as { href?: string }).href,\n 'aria-busy': busy() || local['aria-busy'],\n onClick: guardedClick(rest.onClick, disabled, (event) => {\n if (!local.tooltip) return\n setTooltipSuppression(event.detail > 0 ? 'pointer' : 'focus')\n setTooltipOpen(false)\n }),\n onPointerLeave: chainedHandler(rest.onPointerLeave, () => {\n if (tooltipSuppression() === 'pointer') setTooltipSuppression(null)\n }),\n onBlur: chainedHandler(rest.onBlur, () => {\n if (tooltipSuppression() === 'focus') setTooltipSuppression(null)\n }),\n onClickCapture: onClickCapture ? guardedClick(onClickCapture, disabled) : undefined,\n 'on:click': guardedClick((rest as Record<string, unknown>)['on:click'], disabled),\n 'oncapture:click': guardedClick((rest as Record<string, unknown>)['oncapture:click'], disabled),\n })\n\n const contents = () => (\n <>\n <Show when={busy()}>\n <Spinner size=\"sm\" label={false} aria-hidden=\"true\" data-icon=\"inline-start\" />\n </Show>\n {local.children}\n </>\n )\n\n return (\n <>\n <Show\n when={local.tooltip}\n fallback={\n <PolymorphicButton\n as={(local.as ?? 'button') as T}\n {...(buttonProps() as unknown as ButtonProps<T>)}\n >\n {contents()}\n </PolymorphicButton>\n }\n >\n <Tooltip\n open={tooltipOpen()}\n onOpenChange={(open) => {\n if (open && tooltipSuppression()) return\n setTooltipOpen(open)\n }}\n >\n <TooltipTrigger\n as={PolymorphicButtonTarget}\n {...(buttonProps() as unknown as ComponentProps<typeof PolymorphicButtonTarget>)}\n actionAs={(local.as ?? 'button') as T}\n >\n {contents()}\n </TooltipTrigger>\n <TooltipContent side={local.tooltipSide}>{local.tooltip}</TooltipContent>\n </Tooltip>\n </Show>\n <Show when={busy()}>\n <span role=\"status\" aria-live=\"polite\" class=\"visually-hidden\">\n {busyStatus()}\n </span>\n </Show>\n </>\n )\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"action-button.js","names":["Show","createSignal","splitProps","ComponentProps","JSX","ValidComponent","Button","ButtonProps","Spinner","Tooltip","TooltipContent","TooltipTrigger","ActionButtonProps","T","tooltip","tooltipSide","busy","busyLabel","invokeHandler","handler","event","Event","Array","isArray","callback","data","chainedHandler","before","guardedClick","disabled","onActivate","MouseEvent","preventDefault","stopImmediatePropagation","ButtonTargetProps","Omit","actionAs","ButtonTarget","props","local","rest","PolymorphicButton","targetProps","Element","_$createComponent","_$mergeProps","as","ActionButton","busyStatus","tooltipOpen","setTooltipOpen","tooltipSuppression","setTooltipSuppression","onClickCapture","buttonProps","PolymorphicButtonTarget","variant","size","class","filter","Boolean","join","tabIndex","undefined","role","href","onClick","detail","onPointerLeave","onBlur","Record","contents","when","children","label","_$memo","fallback","open","onOpenChange","side","_el$","_tmpl$","_$insert","_$createComponent","PolymorphicButton","_$mergeProps","_$memo"],"sources":["../../../../src/components/composites/action-button/action-button.tsx"],"sourcesContent":["import {\n Show,\n createSignal,\n splitProps,\n type ComponentProps,\n type JSX,\n type ValidComponent,\n} from 'solid-js'\nimport { Button, type ButtonProps } from '../../ui/button'\nimport { Spinner } from '../../ui/spinner'\nimport { Tooltip, TooltipContent, TooltipTrigger } from '../../ui/tooltip'\n\n/**\n * ActionButton.\n *\n * A Button with optional explanatory tooltip and busy feedback. Use it for a\n * simple action that needs these states; actions with product-specific rules\n * should compose Button directly.\n *\n * The tooltip trigger renders the polymorphic Button itself. A disabled native\n * control cannot receive pointer or keyboard events. When a tooltip is set,\n * disabled actions therefore use focusable `aria-disabled` semantics and guard\n * activation; without a tooltip, native buttons retain native disabling.\n * Custom polymorphic components must forward aria, event, and href props for\n * these guarantees to apply.\n */\nexport type ActionButtonProps<T extends ValidComponent = 'button'> = ButtonProps<T> & {\n /** A short explanation, also shown on keyboard focus. The Button still needs its own name. */\n tooltip?: string\n tooltipSide?: 'top' | 'right' | 'bottom' | 'left'\n /** Disables the action and announces the busy label through a polite status region. */\n busy?: boolean\n /** The activity announced while busy. The Button's accessible name stays unchanged. */\n busyLabel?: string\n}\n\nfunction invokeHandler(handler: unknown, event: Event) {\n if (Array.isArray(handler)) {\n const [callback, data] = handler as [(data: unknown, event: Event) => void, unknown]\n callback(data, event)\n } else if (typeof handler === 'function') {\n const callback = handler as (event: Event) => void\n callback(event)\n }\n}\n\nfunction chainedHandler(handler: unknown, before: (event: Event) => void) {\n return (event: Event) => {\n before(event)\n invokeHandler(handler, event)\n }\n}\n\nfunction guardedClick(\n handler: unknown,\n disabled: () => boolean,\n onActivate: (event: MouseEvent) => void = () => {}\n) {\n return (event: MouseEvent) => {\n if (disabled()) {\n event.preventDefault()\n event.stopImmediatePropagation()\n return\n }\n\n onActivate(event)\n invokeHandler(handler, event)\n }\n}\n\ntype ButtonTargetProps<T extends ValidComponent = 'button'> = Omit<ButtonProps<T>, 'as'> & {\n actionAs?: T\n}\n\n/** Adapter keeps TooltipTrigger's `as` separate from Button's polymorphic `as`. */\nfunction ButtonTarget<T extends ValidComponent = 'button'>(props: ButtonTargetProps<T>) {\n const [local, rest] = splitProps(props as ButtonTargetProps, ['actionAs'])\n const PolymorphicButton = Button as (targetProps: ButtonProps<T>) => JSX.Element\n return <PolymorphicButton as={(local.actionAs ?? 'button') as T} {...(rest as ButtonProps<T>)} />\n}\n\nexport function ActionButton<T extends ValidComponent = 'button'>(props: ActionButtonProps<T>) {\n const [local, rest] = splitProps(props as ActionButtonProps, [\n 'as',\n 'variant',\n 'size',\n 'class',\n 'children',\n 'disabled',\n 'aria-busy',\n 'tooltip',\n 'tooltipSide',\n 'busy',\n 'busyLabel',\n ])\n const busy = () => local.busy ?? false\n const disabled = () => busy() || !!local.disabled\n const busyStatus = () => local.busyLabel ?? 'Working'\n const [tooltipOpen, setTooltipOpen] = createSignal(false)\n const [tooltipSuppression, setTooltipSuppression] = createSignal<'pointer' | 'focus' | null>(null)\n const onClickCapture = (rest as { onClickCapture?: unknown }).onClickCapture\n const PolymorphicButton = Button as (buttonProps: ButtonProps<T>) => JSX.Element\n const PolymorphicButtonTarget = ButtonTarget as (targetProps: ButtonTargetProps<T>) => JSX.Element\n\n const buttonProps = () => ({\n ...rest,\n variant: local.variant,\n size: local.size,\n class: [local.class, local.tooltip && disabled() && 'aria-disabled:pointer-events-auto']\n .filter(Boolean)\n .join(' '),\n disabled: disabled() && !local.tooltip,\n 'aria-disabled': disabled() ? true : rest['aria-disabled'],\n // Make tooltip-bearing native controls explicit tab stops in WebKit configurations that\n // otherwise skip implicit button stops. A caller's tabIndex remains authoritative.\n tabIndex:\n rest.tabIndex ??\n (local.as === 'a' && disabled() ? (local.tooltip ? 0 : -1) : local.tooltip ? 0 : undefined),\n role: local.as === 'a' && disabled() ? 'link' : rest.role,\n href: local.as === 'a' && disabled() ? undefined : (rest as { href?: string }).href,\n 'aria-busy': busy() || local['aria-busy'],\n onClick: guardedClick(rest.onClick, disabled, (event) => {\n if (!local.tooltip) return\n setTooltipSuppression(event.detail > 0 ? 'pointer' : 'focus')\n setTooltipOpen(false)\n }),\n onPointerLeave: chainedHandler(rest.onPointerLeave, () => {\n if (tooltipSuppression() === 'pointer') setTooltipSuppression(null)\n }),\n onBlur: chainedHandler(rest.onBlur, () => {\n if (tooltipSuppression() === 'focus') setTooltipSuppression(null)\n }),\n onClickCapture: onClickCapture ? guardedClick(onClickCapture, disabled) : undefined,\n 'on:click': guardedClick((rest as Record<string, unknown>)['on:click'], disabled),\n 'oncapture:click': guardedClick((rest as Record<string, unknown>)['oncapture:click'], disabled),\n })\n\n const contents = () => (\n <>\n <Show when={busy()}>\n <Spinner size=\"sm\" label={false} aria-hidden=\"true\" data-icon=\"inline-start\" />\n </Show>\n {local.children}\n </>\n )\n\n return (\n <>\n <Show\n when={local.tooltip}\n fallback={\n <PolymorphicButton\n as={(local.as ?? 'button') as T}\n {...(buttonProps() as unknown as ButtonProps<T>)}\n >\n {contents()}\n </PolymorphicButton>\n }\n >\n <Tooltip\n open={tooltipOpen()}\n onOpenChange={(open) => {\n if (open && tooltipSuppression()) return\n setTooltipOpen(open)\n }}\n >\n <TooltipTrigger\n as={PolymorphicButtonTarget}\n {...(buttonProps() as unknown as ComponentProps<typeof PolymorphicButtonTarget>)}\n actionAs={(local.as ?? 'button') as T}\n >\n {contents()}\n </TooltipTrigger>\n <TooltipContent side={local.tooltipSide}>{local.tooltip}</TooltipContent>\n </Tooltip>\n </Show>\n <Show when={busy()}>\n <span role=\"status\" aria-live=\"polite\" class=\"visually-hidden\">\n {busyStatus()}\n </span>\n </Show>\n </>\n )\n}\n"],"mappings":"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"}
@@ -14,9 +14,8 @@ import type { ComponentProps, JSX, ValidComponent } from 'solid-js';
14
14
  * arithmetic.
15
15
  *
16
16
  * A row is only interactive when it is given an `as` that can be activated
17
- * (an anchor, a button) or an `onClick`. Without either it renders as a
18
- * `div` with no hover treatment, because a hover state on something that does
19
- * nothing is a lie.
17
+ * (an anchor, a button) or an `onClick`. Click handlers default to a native
18
+ * button; a row without either remains a `div` with no hover treatment.
20
19
  */
21
20
  export type ListRowProps<T extends ValidComponent = 'div'> = PolymorphicProps<T, {
22
21
  class?: string;
@@ -30,6 +29,10 @@ export type ListRowProps<T extends ValidComponent = 'div'> = PolymorphicProps<T,
30
29
  trailing?: JSX.Element;
31
30
  /** A dimmed second line under the main content. */
32
31
  description?: string;
32
+ /** A short explanation shown on pointer hover and keyboard focus. */
33
+ tooltip?: string;
34
+ /** Native button type; defaults to `button` for button rows. */
35
+ type?: ComponentProps<'button'>['type'];
33
36
  }>;
34
37
  export declare function ListRow<T extends ValidComponent = 'div'>(props: ListRowProps<T>): JSX.Element;
35
38
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"list-row.d.ts","sourceRoot":"","sources":["../../../../src/components/composites/list-row/list-row.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAA;AAEjE,OAAO,KAAK,EAAE,cAAc,EAAE,GAAG,EAAE,cAAc,EAAE,MAAM,UAAU,CAAA;AAInE;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,MAAM,YAAY,CAAC,CAAC,SAAS,cAAc,GAAG,KAAK,IAAI,gBAAgB,CAC3E,CAAC,EACD;IACE,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,oEAAoE;IACpE,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,0CAA0C;IAC1C,KAAK,CAAC,EAAE,OAAO,CAAA;IACf,oDAAoD;IACpD,OAAO,CAAC,EAAE,GAAG,CAAC,OAAO,CAAA;IACrB,2DAA2D;IAC3D,QAAQ,CAAC,EAAE,GAAG,CAAC,OAAO,CAAA;IACtB,mDAAmD;IACnD,WAAW,CAAC,EAAE,MAAM,CAAA;CACrB,CACF,CAAA;AAED,wBAAgB,OAAO,CAAC,CAAC,SAAS,cAAc,GAAG,KAAK,EAAE,KAAK,EAAE,YAAY,CAAC,CAAC,CAAC,eA+C/E;AAED;;;;GAIG;AACH,wBAAgB,SAAS,CAAC,KAAK,EAAE,cAAc,CAAC,KAAK,CAAC,GAAG;IAAE,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,GAAG,CAAC,OAAO,CAAA;CAAE,eAoBhG"}
1
+ {"version":3,"file":"list-row.d.ts","sourceRoot":"","sources":["../../../../src/components/composites/list-row/list-row.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAA;AAEjE,OAAO,KAAK,EAAE,cAAc,EAAE,GAAG,EAAE,cAAc,EAAE,MAAM,UAAU,CAAA;AAKnE;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,MAAM,YAAY,CAAC,CAAC,SAAS,cAAc,GAAG,KAAK,IAAI,gBAAgB,CAC3E,CAAC,EACD;IACE,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,oEAAoE;IACpE,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,0CAA0C;IAC1C,KAAK,CAAC,EAAE,OAAO,CAAA;IACf,oDAAoD;IACpD,OAAO,CAAC,EAAE,GAAG,CAAC,OAAO,CAAA;IACrB,2DAA2D;IAC3D,QAAQ,CAAC,EAAE,GAAG,CAAC,OAAO,CAAA;IACtB,mDAAmD;IACnD,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,qEAAqE;IACrE,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,gEAAgE;IAChE,IAAI,CAAC,EAAE,cAAc,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,CAAA;CACxC,CACF,CAAA;AA8FD,wBAAgB,OAAO,CAAC,CAAC,SAAS,cAAc,GAAG,KAAK,EAAE,KAAK,EAAE,YAAY,CAAC,CAAC,CAAC,eAwB/E;AAED;;;;GAIG;AACH,wBAAgB,SAAS,CAAC,KAAK,EAAE,cAAc,CAAC,KAAK,CAAC,GAAG;IAAE,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,GAAG,CAAC,OAAO,CAAA;CAAE,eAoBhG"}
@@ -1,27 +1,40 @@
1
1
  import { cn } from "../../../lib/utils.js";
2
- import { createComponent, insert, mergeProps, spread, template } from "solid-js/web";
2
+ import { Tooltip, TooltipContent, TooltipTrigger } from "../../ui/tooltip/tooltip.js";
3
+ import { className, createComponent, effect, insert, memo, mergeProps, spread, template } from "solid-js/web";
3
4
  import { Show, splitProps } from "solid-js";
4
5
  import { Polymorphic } from "@kobalte/core/polymorphic";
5
6
  //#region src/components/composites/list-row/list-row.tsx
6
7
  var _tmpl$ = /*#__PURE__*/ template(`<span class="flex size-4 shrink-0 items-center justify-center [&amp;_svg]:size-4">`);
7
- var _tmpl$2 = /*#__PURE__*/ template(`<span class="text-muted-foreground truncate text-xs">`);
8
+ var _tmpl$2 = /*#__PURE__*/ template(`<span data-slot=list-row-description>`);
8
9
  var _tmpl$3 = /*#__PURE__*/ template(`<span class="flex min-w-0 flex-1 flex-col"><span class=truncate>`);
9
- var _tmpl$4 = /*#__PURE__*/ template(`<span class="ms-auto flex shrink-0 items-center gap-1 text-muted-foreground">`);
10
+ var _tmpl$4 = /*#__PURE__*/ template(`<span data-slot=list-row-trailing>`);
10
11
  var _tmpl$5 = /*#__PURE__*/ template(`<span class="shrink-0 opacity-0 transition-opacity ease-out group-hover/list-header:opacity-100 focus-within:opacity-100">`);
11
12
  var _tmpl$6 = /*#__PURE__*/ template(`<div class="group/list-header flex items-center gap-1 px-2 py-1"><span class="min-w-0 flex-1 truncate text-2xs font-medium tracking-wide text-muted-foreground uppercase">`);
12
13
  var _tmpl$7 = /*#__PURE__*/ template(`<div data-slot=list-group><div class="flex flex-col gap-0.5">`);
13
- function ListRow(props) {
14
+ function ListRowBase(props) {
14
15
  const [local, rest] = splitProps(props, [
16
+ "as",
15
17
  "class",
16
18
  "selected",
17
19
  "dense",
18
20
  "leading",
19
21
  "trailing",
20
22
  "description",
23
+ "tooltip",
24
+ "type",
25
+ "tabIndex",
21
26
  "children"
22
27
  ]);
23
28
  return createComponent(Polymorphic, mergeProps({
24
- as: "div",
29
+ get as() {
30
+ return local.as ?? "div";
31
+ },
32
+ get type() {
33
+ return memo(() => local.as === "button")() ? local.type ?? "button" : local.type;
34
+ },
35
+ get tabIndex() {
36
+ return local.tabIndex ?? (local.as === "button" || local.as === "a" ? 0 : void 0);
37
+ },
25
38
  get ["aria-current"]() {
26
39
  return local.selected ? "true" : void 0;
27
40
  },
@@ -30,8 +43,10 @@ function ListRow(props) {
30
43
  },
31
44
  get ["class"]() {
32
45
  return cn("group/row flex min-w-0 items-center gap-2.5 rounded-md px-2 text-sm", "transition-colors ease-out outline-none", "focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-primary-subtle", {
33
- "h-row-sm": local.dense,
34
- "h-row-md": !local.dense
46
+ "h-row-sm": local.dense && !local.description,
47
+ "h-row-md": !local.dense && !local.description,
48
+ "min-h-row-sm py-1": local.dense && local.description,
49
+ "min-h-row-md py-1.5": !local.dense && local.description
35
50
  }, {
36
51
  "bg-primary-subtle text-foreground": local.selected,
37
52
  "hover:bg-surface-hover": !local.selected
@@ -59,6 +74,7 @@ function ListRow(props) {
59
74
  get children() {
60
75
  var _el$4 = _tmpl$2();
61
76
  insert(_el$4, () => local.description);
77
+ effect(() => className(_el$4, cn("truncate text-xs", local.selected ? "text-foreground" : "text-muted-foreground")));
62
78
  return _el$4;
63
79
  }
64
80
  }), null);
@@ -71,12 +87,58 @@ function ListRow(props) {
71
87
  get children() {
72
88
  var _el$5 = _tmpl$4();
73
89
  insert(_el$5, () => local.trailing);
90
+ effect(() => className(_el$5, cn("ms-auto flex shrink-0 items-center gap-1", local.selected ? "text-foreground" : "text-muted-foreground")));
74
91
  return _el$5;
75
92
  }
76
93
  })
77
94
  ];
78
95
  } }));
79
96
  }
97
+ /** Adapts TooltipTrigger's polymorphic target to ListRow's semantic element. */
98
+ function ListRowTooltipTarget(props) {
99
+ const [local, rest] = splitProps(props, ["rowAs"]);
100
+ return createComponent(ListRowBase, mergeProps({ get as() {
101
+ return local.rowAs;
102
+ } }, rest));
103
+ }
104
+ function ListRow(props) {
105
+ const [local, rest] = splitProps(props, ["as", "tooltip"]);
106
+ const hasClickHandler = () => Boolean(rest.onClick || rest["on:click"]);
107
+ const rowAs = () => local.as ?? (hasClickHandler() ? "button" : "div");
108
+ const rowType = () => rowAs() === "button" ? rest.type ?? "button" : rest.type;
109
+ return createComponent(Show, {
110
+ get when() {
111
+ return local.tooltip;
112
+ },
113
+ get fallback() {
114
+ return createComponent(ListRowBase, mergeProps({
115
+ get as() {
116
+ return rowAs();
117
+ },
118
+ get type() {
119
+ return rowType();
120
+ }
121
+ }, rest));
122
+ },
123
+ get children() {
124
+ return createComponent(Tooltip, { get children() {
125
+ return [createComponent(TooltipTrigger, mergeProps({
126
+ as: ListRowTooltipTarget,
127
+ get rowAs() {
128
+ return rowAs();
129
+ },
130
+ get type() {
131
+ return rowType();
132
+ }
133
+ }, rest, { get children() {
134
+ return rest.children;
135
+ } })), createComponent(TooltipContent, { get children() {
136
+ return local.tooltip;
137
+ } })];
138
+ } });
139
+ }
140
+ });
141
+ }
80
142
  /**
81
143
  * A group of rows with an optional heading and a scrolling body. The heading is
82
144
  * a plain label rather than a control: grouping is for reading, and a
@@ -1 +1 @@
1
- {"version":3,"file":"list-row.js","names":["PolymorphicProps","Polymorphic","ComponentProps","JSX","ValidComponent","Show","splitProps","cn","ListRowProps","T","class","selected","dense","leading","Element","trailing","description","ListRow","props","local","rest","_$createComponent","_$mergeProps","as","aria-current","undefined","data-selected","children","when","_el$","_tmpl$","_$insert","_el$2","_tmpl$3","_el$3","firstChild","_el$4","_tmpl$2","_el$5","_tmpl$4","ListGroup","label","action","_el$6","_tmpl$7","_el$0","_$spread","_el$7","_tmpl$6","_el$8","_el$9","_tmpl$5","_$createComponent","_$mergeProps"],"sources":["../../../../src/components/composites/list-row/list-row.tsx"],"sourcesContent":["import type { PolymorphicProps } from '@kobalte/core/polymorphic'\nimport { Polymorphic } from '@kobalte/core/polymorphic'\nimport type { ComponentProps, JSX, ValidComponent } from 'solid-js'\nimport { Show, splitProps } from 'solid-js'\nimport { cn } from '#lib/utils'\n\n/**\n * ListRow.\n *\n * One row in a list of like things: a project, a session, a file, a person. It\n * is the highest-frequency component in an application of this shape, and the\n * one where a half-pixel of drift is most visible — twenty rows of a sidebar\n * make any inconsistency in height or padding obvious.\n *\n * The structure is fixed at four slots — `leading`, `children`, `meta`,\n * `trailing` — so rows that show an avatar, an icon, a status dot, a timestamp\n * and an overflow menu all sit at the same height without the caller doing\n * arithmetic.\n *\n * A row is only interactive when it is given an `as` that can be activated\n * (an anchor, a button) or an `onClick`. Without either it renders as a\n * `div` with no hover treatment, because a hover state on something that does\n * nothing is a lie.\n */\nexport type ListRowProps<T extends ValidComponent = 'div'> = PolymorphicProps<\n T,\n {\n class?: string\n /** Marks the row as current. Sets `aria-current` for a link row. */\n selected?: boolean\n /** Draw the row at the compact height. */\n dense?: boolean\n /** Leading slot: an avatar, an icon, a checkbox. */\n leading?: JSX.Element\n /** Trailing slot: a count, a menu trigger, a timestamp. */\n trailing?: JSX.Element\n /** A dimmed second line under the main content. */\n description?: string\n }\n>\n\nexport function ListRow<T extends ValidComponent = 'div'>(props: ListRowProps<T>) {\n const [local, rest] = splitProps(props as ListRowProps, [\n 'class',\n 'selected',\n 'dense',\n 'leading',\n 'trailing',\n 'description',\n 'children',\n ])\n\n return (\n <Polymorphic\n as=\"div\"\n aria-current={local.selected ? 'true' : undefined}\n data-selected={local.selected ? '' : undefined}\n class={cn(\n 'group/row flex min-w-0 items-center gap-2.5 rounded-md px-2 text-sm',\n 'transition-colors ease-out outline-none',\n 'focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-primary-subtle',\n { 'h-row-sm': local.dense, 'h-row-md': !local.dense },\n {\n 'bg-primary-subtle text-foreground': local.selected,\n 'hover:bg-surface-hover': !local.selected,\n },\n local.class\n )}\n {...(rest as ComponentProps<'div'>)}\n >\n <Show when={local.leading}>\n <span class=\"flex size-4 shrink-0 items-center justify-center [&_svg]:size-4\">\n {local.leading}\n </span>\n </Show>\n <span class=\"flex min-w-0 flex-1 flex-col\">\n <span class=\"truncate\">{local.children}</span>\n <Show when={local.description}>\n <span class=\"text-muted-foreground truncate text-xs\">{local.description}</span>\n </Show>\n </span>\n <Show when={local.trailing}>\n <span class=\"ms-auto flex shrink-0 items-center gap-1 text-muted-foreground\">\n {local.trailing}\n </span>\n </Show>\n </Polymorphic>\n )\n}\n\n/**\n * A group of rows with an optional heading and a scrolling body. The heading is\n * a plain label rather than a control: grouping is for reading, and a\n * disclosure on a list of five rows costs more attention than it saves.\n */\nexport function ListGroup(props: ComponentProps<'div'> & { label?: string; action?: JSX.Element }) {\n const [local, rest] = splitProps(props, ['class', 'label', 'action', 'children'])\n\n return (\n <div data-slot=\"list-group\" class={cn('flex flex-col gap-0.5', local.class)} {...rest}>\n <Show when={local.label}>\n <div class=\"group/list-header flex items-center gap-1 px-2 py-1\">\n <span class=\"min-w-0 flex-1 truncate text-2xs font-medium tracking-wide text-muted-foreground uppercase\">\n {local.label}\n </span>\n <Show when={local.action}>\n <span class=\"shrink-0 opacity-0 transition-opacity ease-out group-hover/list-header:opacity-100 focus-within:opacity-100\">\n {local.action}\n </span>\n </Show>\n </div>\n </Show>\n <div class=\"flex flex-col gap-0.5\">{local.children}</div>\n </div>\n )\n}\n"],"mappings":";;;;;;;;;;;;AAyCA,SAAgBiB,QAA0CC,OAAwB;CAChF,MAAM,CAACC,OAAOC,QAAQd,WAAWY,OAAuB;EACtD;EACA;EACA;EACA;EACA;EACA;EACA;CAAU,CACX;CAED,OAAAG,gBACGpB,aAAWqB,WAAA;EACVC,IAAE;EAAA,KAAA,kBAAA;GAAA,OACYJ,MAAMR,WAAW,SAASc,KAAAA;EAAS;EAAA,KAAA,mBAAA;GAAA,OAClCN,MAAMR,WAAW,KAAKc,KAAAA;EAAS;EAAA,KAAA,WAAA;GAAA,OACvClB,GACL,uEACA,2CACA,oFACA;IAAE,YAAYY,MAAMP;IAAO,YAAY,CAACO,MAAMP;GAAM,GACpD;IACE,qCAAqCO,MAAMR;IAC3C,0BAA0B,CAACQ,MAAMR;GACnC,GACAQ,MAAMT,KACR;EAAC;CAAA,GACIU,MAA6B,EAAA,IAAAO,WAAA;EAAA,OAAA;GAAAN,gBAEjChB,MAAI;IAAA,IAACuB,OAAI;KAAA,OAAET,MAAMN;IAAO;IAAA,IAAAc,WAAA;KAAA,IAAAE,OAAAC,OAAA;KAAAC,OAAAF,YAEpBV,MAAMN,OAAO;KAAA,OAAAgB;IAAA;GAAA,CAAA;UAAA;IAAA,IAAAG,QAAAC,QAAA,GAAAC,QAAAF,MAAAG;IAAAJ,OAAAG,aAIQf,MAAMQ,QAAQ;IAAAI,OAAAC,OAAAX,gBACrChB,MAAI;KAAA,IAACuB,OAAI;MAAA,OAAET,MAAMH;KAAW;KAAA,IAAAW,WAAA;MAAA,IAAAS,QAAAC,QAAA;MAAAN,OAAAK,aAC2BjB,MAAMH,WAAW;MAAA,OAAAoB;KAAA;IAAA,CAAA,GAAA,IAAA;IAAA,OAAAJ;GAAA,EAAA,CAAA;GAAAX,gBAG1EhB,MAAI;IAAA,IAACuB,OAAI;KAAA,OAAET,MAAMJ;IAAQ;IAAA,IAAAY,WAAA;KAAA,IAAAW,QAAAC,QAAA;KAAAR,OAAAO,aAErBnB,MAAMJ,QAAQ;KAAA,OAAAuB;IAAA;GAAA,CAAA;EAAA;CAAA,EAAA,CAAA,CAAA;AAKzB;;;;;;AAOA,SAAgBE,UAAUtB,OAAyE;CACjG,MAAM,CAACC,OAAOC,QAAQd,WAAWY,OAAO;EAAC;EAAS;EAAS;EAAU;CAAU,CAAC;CAEhF,cAAA;EAAA,IAAAyB,QAAAC,QAAA,GAAAC,QAAAF,MAAAR;EAAAW,OAAAH,OAAArB,WAAA,EAAA,KAAA,WAAA;GAAA,OACqCf,GAAG,yBAAyBY,MAAMT,KAAK;EAAC,EAAA,GAAMU,IAAI,GAAA,OAAA,IAAA;EAAAW,OAAAY,OAAAtB,gBAClFhB,MAAI;GAAA,IAACuB,OAAI;IAAA,OAAET,MAAMsB;GAAK;GAAA,IAAAd,WAAA;IAAA,IAAAoB,QAAAC,QAAA,GAAAC,QAAAF,MAAAZ;IAAAJ,OAAAkB,aAGhB9B,MAAMsB,KAAK;IAAAV,OAAAgB,OAAA1B,gBAEbhB,MAAI;KAAA,IAACuB,OAAI;MAAA,OAAET,MAAMuB;KAAM;KAAA,IAAAf,WAAA;MAAA,IAAAuB,QAAAC,QAAA;MAAApB,OAAAmB,aAEnB/B,MAAMuB,MAAM;MAAA,OAAAQ;KAAA;IAAA,CAAA,GAAA,IAAA;IAAA,OAAAH;GAAA;EAAA,CAAA,GAAAF,KAAA;EAAAd,OAAAc,aAKe1B,MAAMQ,QAAQ;EAAA,OAAAgB;CAAA,EAAA,CAAA;AAGxD"}
1
+ {"version":3,"file":"list-row.js","names":["PolymorphicProps","Polymorphic","ComponentProps","JSX","ValidComponent","Show","splitProps","Tooltip","TooltipContent","TooltipTrigger","cn","ListRowProps","T","class","selected","dense","leading","Element","trailing","description","tooltip","type","ListRowBaseProps","as","ListRowBase","props","local","rest","_$createComponent","_$mergeProps","_$memo","tabIndex","undefined","aria-current","data-selected","children","when","_el$","_tmpl$","_$insert","_el$2","_tmpl$3","_el$3","firstChild","_el$4","_tmpl$2","_$effect","_$className","_el$5","_tmpl$4","ListRowTooltipTargetProps","Omit","rowAs","ListRowTooltipTarget","ListRow","hasClickHandler","Boolean","onClick","rowType","fallback","ListGroup","label","action","_el$6","_tmpl$7","_el$0","_$spread","_el$7","_tmpl$6","_el$8","_el$9","_tmpl$5","_$createComponent","_$mergeProps","_$memo","_$className"],"sources":["../../../../src/components/composites/list-row/list-row.tsx"],"sourcesContent":["import type { PolymorphicProps } from '@kobalte/core/polymorphic'\nimport { Polymorphic } from '@kobalte/core/polymorphic'\nimport type { ComponentProps, JSX, ValidComponent } from 'solid-js'\nimport { Show, splitProps } from 'solid-js'\nimport { Tooltip, TooltipContent, TooltipTrigger } from '../../ui/tooltip'\nimport { cn } from '#lib/utils'\n\n/**\n * ListRow.\n *\n * One row in a list of like things: a project, a session, a file, a person. It\n * is the highest-frequency component in an application of this shape, and the\n * one where a half-pixel of drift is most visible — twenty rows of a sidebar\n * make any inconsistency in height or padding obvious.\n *\n * The structure is fixed at four slots — `leading`, `children`, `meta`,\n * `trailing` — so rows that show an avatar, an icon, a status dot, a timestamp\n * and an overflow menu all sit at the same height without the caller doing\n * arithmetic.\n *\n * A row is only interactive when it is given an `as` that can be activated\n * (an anchor, a button) or an `onClick`. Click handlers default to a native\n * button; a row without either remains a `div` with no hover treatment.\n */\nexport type ListRowProps<T extends ValidComponent = 'div'> = PolymorphicProps<\n T,\n {\n class?: string\n /** Marks the row as current. Sets `aria-current` for a link row. */\n selected?: boolean\n /** Draw the row at the compact height. */\n dense?: boolean\n /** Leading slot: an avatar, an icon, a checkbox. */\n leading?: JSX.Element\n /** Trailing slot: a count, a menu trigger, a timestamp. */\n trailing?: JSX.Element\n /** A dimmed second line under the main content. */\n description?: string\n /** A short explanation shown on pointer hover and keyboard focus. */\n tooltip?: string\n /** Native button type; defaults to `button` for button rows. */\n type?: ComponentProps<'button'>['type']\n }\n>\n\ntype ListRowBaseProps<T extends ValidComponent = 'div'> = ListRowProps<T> & {\n as?: T\n type?: ComponentProps<'button'>['type']\n}\n\nfunction ListRowBase<T extends ValidComponent = 'div'>(props: ListRowBaseProps<T>) {\n const [local, rest] = splitProps(props as ListRowProps, [\n 'as',\n 'class',\n 'selected',\n 'dense',\n 'leading',\n 'trailing',\n 'description',\n 'tooltip',\n 'type',\n 'tabIndex',\n 'children',\n ])\n\n return (\n <Polymorphic\n as={(local.as ?? 'div') as T}\n type={local.as === 'button' ? (local.type ?? 'button') : local.type}\n tabIndex={local.tabIndex ?? (local.as === 'button' || local.as === 'a' ? 0 : undefined)}\n aria-current={local.selected ? 'true' : undefined}\n data-selected={local.selected ? '' : undefined}\n class={cn(\n 'group/row flex min-w-0 items-center gap-2.5 rounded-md px-2 text-sm',\n 'transition-colors ease-out outline-none',\n 'focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-primary-subtle',\n {\n 'h-row-sm': local.dense && !local.description,\n 'h-row-md': !local.dense && !local.description,\n 'min-h-row-sm py-1': local.dense && local.description,\n 'min-h-row-md py-1.5': !local.dense && local.description,\n },\n {\n 'bg-primary-subtle text-foreground': local.selected,\n 'hover:bg-surface-hover': !local.selected,\n },\n local.class\n )}\n {...(rest as ComponentProps<'div'>)}\n >\n <Show when={local.leading}>\n <span class=\"flex size-4 shrink-0 items-center justify-center [&_svg]:size-4\">\n {local.leading}\n </span>\n </Show>\n <span class=\"flex min-w-0 flex-1 flex-col\">\n <span class=\"truncate\">{local.children}</span>\n <Show when={local.description}>\n <span\n data-slot=\"list-row-description\"\n class={cn(\n 'truncate text-xs',\n local.selected ? 'text-foreground' : 'text-muted-foreground'\n )}\n >\n {local.description}\n </span>\n </Show>\n </span>\n <Show when={local.trailing}>\n <span\n data-slot=\"list-row-trailing\"\n class={cn(\n 'ms-auto flex shrink-0 items-center gap-1',\n local.selected ? 'text-foreground' : 'text-muted-foreground'\n )}\n >\n {local.trailing}\n </span>\n </Show>\n </Polymorphic>\n )\n}\n\ntype ListRowTooltipTargetProps<T extends ValidComponent = 'div'> = Omit<\n ListRowBaseProps<T>,\n 'as'\n> & { rowAs?: T }\n\n/** Adapts TooltipTrigger's polymorphic target to ListRow's semantic element. */\nfunction ListRowTooltipTarget<T extends ValidComponent = 'div'>(\n props: ListRowTooltipTargetProps<T>\n) {\n const [local, rest] = splitProps(props as ListRowTooltipTargetProps, ['rowAs'])\n return <ListRowBase as={local.rowAs} {...(rest as ListRowBaseProps<T>)} />\n}\n\nexport function ListRow<T extends ValidComponent = 'div'>(props: ListRowProps<T>) {\n const [local, rest] = splitProps(props as ListRowProps, ['as', 'tooltip'])\n const hasClickHandler = () => Boolean(rest.onClick || rest['on:click'])\n const rowAs = () => (local.as ?? (hasClickHandler() ? 'button' : 'div')) as T\n const rowType = () => (rowAs() === 'button' ? (rest.type ?? 'button') : rest.type)\n\n return (\n <Show\n when={local.tooltip}\n fallback={<ListRowBase as={rowAs()} type={rowType()} {...(rest as ListRowBaseProps<T>)} />}\n >\n <Tooltip>\n <TooltipTrigger\n as={ListRowTooltipTarget}\n rowAs={rowAs()}\n type={rowType()}\n {...(rest as ListRowTooltipTargetProps<T>)}\n >\n {rest.children}\n </TooltipTrigger>\n <TooltipContent>{local.tooltip}</TooltipContent>\n </Tooltip>\n </Show>\n )\n}\n\n/**\n * A group of rows with an optional heading and a scrolling body. The heading is\n * a plain label rather than a control: grouping is for reading, and a\n * disclosure on a list of five rows costs more attention than it saves.\n */\nexport function ListGroup(props: ComponentProps<'div'> & { label?: string; action?: JSX.Element }) {\n const [local, rest] = splitProps(props, ['class', 'label', 'action', 'children'])\n\n return (\n <div data-slot=\"list-group\" class={cn('flex flex-col gap-0.5', local.class)} {...rest}>\n <Show when={local.label}>\n <div class=\"group/list-header flex items-center gap-1 px-2 py-1\">\n <span class=\"min-w-0 flex-1 truncate text-2xs font-medium tracking-wide text-muted-foreground uppercase\">\n {local.label}\n </span>\n <Show when={local.action}>\n <span class=\"shrink-0 opacity-0 transition-opacity ease-out group-hover/list-header:opacity-100 focus-within:opacity-100\">\n {local.action}\n </span>\n </Show>\n </div>\n </Show>\n <div class=\"flex flex-col gap-0.5\">{local.children}</div>\n </div>\n )\n}\n"],"mappings":"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"}
@@ -7,28 +7,26 @@ import type { ComponentProps, JSX } from 'solid-js';
7
7
  * placement all wander unless something fixes them.
8
8
  *
9
9
  * The row is a two-column layout at a fixed label width, so controls line up
10
- * down the page regardless of how long the labels are. That alignment is the
11
- * difference between a settings page that reads as designed and one that reads
12
- * as a form.
13
- *
14
- * `SettingsRow` puts the control on the trailing side and the label leading;
15
- * `SettingsField` stacks them for a control too wide for a row (a textarea, a
16
- * list). Both share the same label and description treatment.
10
+ * down the page regardless of how long the labels are. `SettingsRow` also
11
+ * exposes its label and description through the shared form-field context to
12
+ * the first control inside it. `SettingsField` is the visual stacked layout;
13
+ * use `FormField` when the control needs label, help, or validation wiring.
17
14
  */
18
15
  export declare function SettingsSection(props: ComponentProps<'section'> & {
19
16
  title: string;
20
17
  description?: string;
21
18
  /** A control for the section as a whole, e.g. a master toggle. */
22
19
  action?: JSX.Element;
20
+ /** Use a spaced content stack for fields, alerts, and cards instead of divided rows. */
21
+ bodyLayout?: 'rows' | 'content';
23
22
  }): JSX.Element;
24
23
  /**
25
24
  * One setting: a label and description on the leading side, a control on the
26
25
  * trailing side.
27
26
  *
28
- * `label` is wired to the control through `aria-labelledby` when the control is
29
- * not already labelled, so a caller can pass a bare `Switch` and still get an
30
- * accessible name. The row does not invent an id per render — it derives one
31
- * from the label, which is stable across renders and readable in a snapshot.
27
+ * The label and description are linked to a shared control through field
28
+ * context. An explicit `aria-label` or `aria-labelledby` on the control keeps
29
+ * precedence; otherwise the visible row label names it.
32
30
  */
33
31
  export declare function SettingsRow(props: ComponentProps<'div'> & {
34
32
  label: string;
@@ -1 +1 @@
1
- {"version":3,"file":"settings.d.ts","sourceRoot":"","sources":["../../../../src/components/composites/settings/settings.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,GAAG,EAAE,MAAM,UAAU,CAAA;AAInD;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,eAAe,CAC7B,KAAK,EAAE,cAAc,CAAC,SAAS,CAAC,GAAG;IACjC,KAAK,EAAE,MAAM,CAAA;IACb,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,kEAAkE;IAClE,MAAM,CAAC,EAAE,GAAG,CAAC,OAAO,CAAA;CACrB,eAwBF;AAED;;;;;;;;GAQG;AACH,wBAAgB,WAAW,CACzB,KAAK,EAAE,cAAc,CAAC,KAAK,CAAC,GAAG;IAC7B,KAAK,EAAE,MAAM,CAAA;IACb,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,qEAAqE;IACrE,WAAW,CAAC,EAAE,YAAY,GAAG,UAAU,CAAA;IACvC,4DAA4D;IAC5D,IAAI,CAAC,EAAE,OAAO,CAAA;CACf,eAuCF;AAED,0EAA0E;AAC1E,wBAAgB,aAAa,CAC3B,KAAK,EAAE,cAAc,CAAC,KAAK,CAAC,GAAG;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAA;CAAE,eAiBzF;AAED,2EAA2E;AAC3E,wBAAgB,YAAY,CAAC,KAAK,EAAE,cAAc,CAAC,KAAK,CAAC,eASxD"}
1
+ {"version":3,"file":"settings.d.ts","sourceRoot":"","sources":["../../../../src/components/composites/settings/settings.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,GAAG,EAAE,MAAM,UAAU,CAAA;AAKnD;;;;;;;;;;;;GAYG;AACH,wBAAgB,eAAe,CAC7B,KAAK,EAAE,cAAc,CAAC,SAAS,CAAC,GAAG;IACjC,KAAK,EAAE,MAAM,CAAA;IACb,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,kEAAkE;IAClE,MAAM,CAAC,EAAE,GAAG,CAAC,OAAO,CAAA;IACpB,wFAAwF;IACxF,UAAU,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;CAChC,eAwCF;AAED;;;;;;;GAOG;AACH,wBAAgB,WAAW,CACzB,KAAK,EAAE,cAAc,CAAC,KAAK,CAAC,GAAG;IAC7B,KAAK,EAAE,MAAM,CAAA;IACb,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,qEAAqE;IACrE,WAAW,CAAC,EAAE,YAAY,GAAG,UAAU,CAAA;IACvC,4DAA4D;IAC5D,IAAI,CAAC,EAAE,OAAO,CAAA;CACf,eAsDF;AAED,0EAA0E;AAC1E,wBAAgB,aAAa,CAC3B,KAAK,EAAE,cAAc,CAAC,KAAK,CAAC,GAAG;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAA;CAAE,eAiBzF;AAED,2EAA2E;AAC3E,wBAAgB,YAAY,CAAC,KAAK,EAAE,cAAc,CAAC,KAAK,CAAC,eASxD"}
@@ -1,10 +1,11 @@
1
1
  import { cn } from "../../../lib/utils.js";
2
+ import { FormFieldContext, createFormFieldContext } from "../../../lib/form-field.js";
2
3
  import { className, createComponent, effect, insert, mergeProps, setAttribute, spread, template } from "solid-js/web";
3
- import { Show, splitProps } from "solid-js";
4
+ import { Show, createUniqueId, splitProps } from "solid-js";
4
5
  //#region src/components/composites/settings/settings.tsx
5
6
  var _tmpl$ = /*#__PURE__*/ template(`<p class="max-w-prose text-sm text-muted-foreground text-pretty">`);
6
7
  var _tmpl$2 = /*#__PURE__*/ template(`<div class="flex shrink-0 items-center gap-2">`);
7
- var _tmpl$3 = /*#__PURE__*/ template(`<section data-slot=settings-section><div class="flex items-start justify-between gap-4"><div class="flex min-w-0 flex-col gap-0.5"><h2 class="text-base font-semibold tracking-tight"></h2></div></div><div class="divide-y divide-border rounded-xl border border-border">`);
8
+ var _tmpl$3 = /*#__PURE__*/ template(`<section data-slot=settings-section><div class="flex items-start justify-between gap-4"><div class="flex min-w-0 flex-col gap-0.5"><h2 class="text-base font-semibold tracking-tight"></h2></div></div><div data-slot=settings-section-body>`);
8
9
  var _tmpl$4 = /*#__PURE__*/ template(`<div data-slot=settings-row><div class="flex min-w-0 flex-col gap-0.5"><div data-slot=settings-row-label class="text-sm font-medium"></div></div><div data-slot=settings-row-control>`);
9
10
  var _tmpl$5 = /*#__PURE__*/ template(`<div data-slot=settings-field><div class="flex flex-col gap-0.5"><label class="text-sm font-medium"></label></div><div>`);
10
11
  var _tmpl$6 = /*#__PURE__*/ template(`<div data-slot=settings-page>`);
@@ -16,13 +17,10 @@ var _tmpl$6 = /*#__PURE__*/ template(`<div data-slot=settings-page>`);
16
17
  * placement all wander unless something fixes them.
17
18
  *
18
19
  * The row is a two-column layout at a fixed label width, so controls line up
19
- * down the page regardless of how long the labels are. That alignment is the
20
- * difference between a settings page that reads as designed and one that reads
21
- * as a form.
22
- *
23
- * `SettingsRow` puts the control on the trailing side and the label leading;
24
- * `SettingsField` stacks them for a control too wide for a row (a textarea, a
25
- * list). Both share the same label and description treatment.
20
+ * down the page regardless of how long the labels are. `SettingsRow` also
21
+ * exposes its label and description through the shared form-field context to
22
+ * the first control inside it. `SettingsField` is the visual stacked layout;
23
+ * use `FormField` when the control needs label, help, or validation wiring.
26
24
  */
27
25
  function SettingsSection(props) {
28
26
  const [local, rest] = splitProps(props, [
@@ -30,6 +28,7 @@ function SettingsSection(props) {
30
28
  "title",
31
29
  "description",
32
30
  "action",
31
+ "bodyLayout",
33
32
  "children"
34
33
  ]);
35
34
  return (() => {
@@ -59,6 +58,7 @@ function SettingsSection(props) {
59
58
  }
60
59
  }), null);
61
60
  insert(_el$7, () => local.children);
61
+ effect(() => className(_el$7, cn(local.bodyLayout === "content" ? "flex flex-col gap-4" : "divide-y divide-border rounded-xl border border-border")));
62
62
  return _el$;
63
63
  })();
64
64
  }
@@ -66,10 +66,9 @@ function SettingsSection(props) {
66
66
  * One setting: a label and description on the leading side, a control on the
67
67
  * trailing side.
68
68
  *
69
- * `label` is wired to the control through `aria-labelledby` when the control is
70
- * not already labelled, so a caller can pass a bare `Switch` and still get an
71
- * accessible name. The row does not invent an id per render — it derives one
72
- * from the label, which is stable across renders and readable in a snapshot.
69
+ * The label and description are linked to a shared control through field
70
+ * context. An explicit `aria-label` or `aria-labelledby` on the control keeps
71
+ * precedence; otherwise the visible row label names it.
73
72
  */
74
73
  function SettingsRow(props) {
75
74
  const [local, rest] = splitProps(props, [
@@ -80,26 +79,42 @@ function SettingsRow(props) {
80
79
  "bare",
81
80
  "children"
82
81
  ]);
83
- return (() => {
84
- var _el$8 = _tmpl$4(), _el$9 = _el$8.firstChild, _el$0 = _el$9.firstChild, _el$10 = _el$9.nextSibling;
85
- spread(_el$8, mergeProps({ get ["class"]() {
86
- return cn("flex gap-4 p-4", local.orientation === "vertical" ? "flex-col" : "flex-col sm:flex-row sm:items-center sm:justify-between", local.class);
87
- } }, rest), false, true);
88
- insert(_el$0, () => local.label);
89
- insert(_el$9, createComponent(Show, {
90
- get when() {
91
- return local.description;
92
- },
93
- get children() {
94
- var _el$1 = _tmpl$();
95
- insert(_el$1, () => local.description);
96
- return _el$1;
97
- }
98
- }), null);
99
- insert(_el$10, () => local.children);
100
- effect(() => className(_el$10, cn("shrink-0", local.orientation === "vertical" && "w-full")));
101
- return _el$8;
102
- })();
82
+ const rowId = createUniqueId();
83
+ const labelId = `${rowId}-label`;
84
+ const descriptionId = `${rowId}-description`;
85
+ const field = createFormFieldContext({
86
+ defaultControlId: rowId,
87
+ labelId,
88
+ descriptionId,
89
+ hint: () => local.description,
90
+ error: () => void 0,
91
+ group: () => false
92
+ });
93
+ return createComponent(FormFieldContext.Provider, {
94
+ value: field,
95
+ get children() {
96
+ var _el$8 = _tmpl$4(), _el$9 = _el$8.firstChild, _el$0 = _el$9.firstChild, _el$10 = _el$9.nextSibling;
97
+ spread(_el$8, mergeProps({ get ["class"]() {
98
+ return cn("flex gap-4 p-4", local.orientation === "vertical" ? "flex-col" : "flex-col sm:flex-row sm:items-center sm:justify-between", local.class);
99
+ } }, rest), false, true);
100
+ setAttribute(_el$0, "id", labelId);
101
+ insert(_el$0, () => local.label);
102
+ insert(_el$9, createComponent(Show, {
103
+ get when() {
104
+ return local.description;
105
+ },
106
+ get children() {
107
+ var _el$1 = _tmpl$();
108
+ setAttribute(_el$1, "id", descriptionId);
109
+ insert(_el$1, () => local.description);
110
+ return _el$1;
111
+ }
112
+ }), null);
113
+ insert(_el$10, () => local.children);
114
+ effect(() => className(_el$10, cn("shrink-0", local.orientation === "vertical" && "w-full")));
115
+ return _el$8;
116
+ }
117
+ });
103
118
  }
104
119
  /** A stacked label-and-control pair, for a control too wide for a row. */
105
120
  function SettingsField(props) {
@@ -1 +1 @@
1
- {"version":3,"file":"settings.js","names":["ComponentProps","JSX","Show","splitProps","cn","SettingsSection","props","title","description","action","Element","local","rest","_el$","_tmpl$3","_el$2","firstChild","_el$3","_el$4","_el$7","nextSibling","_$spread","_$mergeProps","class","_$insert","_$createComponent","when","children","_el$5","_tmpl$","_el$6","_tmpl$2","SettingsRow","label","orientation","bare","_el$8","_tmpl$4","_el$9","_el$0","_el$10","_el$1","_$effect","_$className","SettingsField","htmlFor","_el$11","_tmpl$5","_el$12","_el$13","_el$15","_el$14","_$setAttribute","SettingsPage","_el$16","_tmpl$6","_$mergeProps","_$createComponent","_$className","_$setAttribute"],"sources":["../../../../src/components/composites/settings/settings.tsx"],"sourcesContent":["import type { ComponentProps, JSX } from 'solid-js'\nimport { Show, splitProps } from 'solid-js'\nimport { cn } from '#lib/utils'\n\n/**\n * SettingsSection and SettingsRow.\n *\n * A settings page is the most repetitive surface in any application, and the\n * one where drift is most visible: label sizes, control widths and description\n * placement all wander unless something fixes them.\n *\n * The row is a two-column layout at a fixed label width, so controls line up\n * down the page regardless of how long the labels are. That alignment is the\n * difference between a settings page that reads as designed and one that reads\n * as a form.\n *\n * `SettingsRow` puts the control on the trailing side and the label leading;\n * `SettingsField` stacks them for a control too wide for a row (a textarea, a\n * list). Both share the same label and description treatment.\n */\nexport function SettingsSection(\n props: ComponentProps<'section'> & {\n title: string\n description?: string\n /** A control for the section as a whole, e.g. a master toggle. */\n action?: JSX.Element\n }\n) {\n const [local, rest] = splitProps(props, ['class', 'title', 'description', 'action', 'children'])\n\n return (\n <section\n data-slot=\"settings-section\"\n class={cn('flex flex-col gap-4 px-5 py-5', local.class)}\n {...rest}\n >\n <div class=\"flex items-start justify-between gap-4\">\n <div class=\"flex min-w-0 flex-col gap-0.5\">\n <h2 class=\"text-base font-semibold tracking-tight\">{local.title}</h2>\n <Show when={local.description}>\n <p class=\"max-w-prose text-sm text-muted-foreground text-pretty\">{local.description}</p>\n </Show>\n </div>\n <Show when={local.action}>\n <div class=\"flex shrink-0 items-center gap-2\">{local.action}</div>\n </Show>\n </div>\n <div class=\"divide-y divide-border rounded-xl border border-border\">{local.children}</div>\n </section>\n )\n}\n\n/**\n * One setting: a label and description on the leading side, a control on the\n * trailing side.\n *\n * `label` is wired to the control through `aria-labelledby` when the control is\n * not already labelled, so a caller can pass a bare `Switch` and still get an\n * accessible name. The row does not invent an id per render — it derives one\n * from the label, which is stable across renders and readable in a snapshot.\n */\nexport function SettingsRow(\n props: ComponentProps<'div'> & {\n label: string\n description?: string\n /** Render a vertical stack when the control needs the full width. */\n orientation?: 'horizontal' | 'vertical'\n /** Hide the divider this row would otherwise contribute. */\n bare?: boolean\n }\n) {\n const [local, rest] = splitProps(props, [\n 'class',\n 'label',\n 'description',\n 'orientation',\n 'bare',\n 'children',\n ])\n\n return (\n <div\n data-slot=\"settings-row\"\n class={cn(\n 'flex gap-4 p-4',\n local.orientation === 'vertical'\n ? 'flex-col'\n : 'flex-col sm:flex-row sm:items-center sm:justify-between',\n local.class\n )}\n {...rest}\n >\n <div class=\"flex min-w-0 flex-col gap-0.5\">\n <div data-slot=\"settings-row-label\" class=\"text-sm font-medium\">\n {local.label}\n </div>\n <Show when={local.description}>\n <p class=\"max-w-prose text-sm text-muted-foreground text-pretty\">{local.description}</p>\n </Show>\n </div>\n <div\n data-slot=\"settings-row-control\"\n class={cn('shrink-0', local.orientation === 'vertical' && 'w-full')}\n >\n {local.children}\n </div>\n </div>\n )\n}\n\n/** A stacked label-and-control pair, for a control too wide for a row. */\nexport function SettingsField(\n props: ComponentProps<'div'> & { label: string; description?: string; htmlFor?: string }\n) {\n const [local, rest] = splitProps(props, ['class', 'label', 'description', 'htmlFor', 'children'])\n\n return (\n <div data-slot=\"settings-field\" class={cn('flex flex-col gap-2 p-4', local.class)} {...rest}>\n <div class=\"flex flex-col gap-0.5\">\n <label for={local.htmlFor} class=\"text-sm font-medium\">\n {local.label}\n </label>\n <Show when={local.description}>\n <p class=\"max-w-prose text-sm text-muted-foreground text-pretty\">{local.description}</p>\n </Show>\n </div>\n <div>{local.children}</div>\n </div>\n )\n}\n\n/** A settings page's scrolling body, with the header sticky at the top. */\nexport function SettingsPage(props: ComponentProps<'div'>) {\n const [local, rest] = splitProps(props, ['class'])\n return (\n <div\n data-slot=\"settings-page\"\n class={cn('flex min-h-0 flex-1 flex-col overflow-y-auto', local.class)}\n {...rest}\n />\n )\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"settings.js","names":["ComponentProps","JSX","createUniqueId","Show","splitProps","createFormFieldContext","FormFieldContext","cn","SettingsSection","props","title","description","action","Element","bodyLayout","local","rest","_el$","_tmpl$3","_el$2","firstChild","_el$3","_el$4","_el$7","nextSibling","_$spread","_$mergeProps","class","_$insert","_$createComponent","when","children","_el$5","_tmpl$","_el$6","_tmpl$2","_$effect","_$className","SettingsRow","label","orientation","bare","rowId","labelId","descriptionId","field","defaultControlId","hint","error","undefined","group","Provider","value","_el$8","_tmpl$4","_el$9","_el$0","_el$10","_$setAttribute","_el$1","SettingsField","htmlFor","_el$11","_tmpl$5","_el$12","_el$13","_el$15","_el$14","SettingsPage","_el$16","_tmpl$6","_$mergeProps","_$createComponent","_$className","_$setAttribute"],"sources":["../../../../src/components/composites/settings/settings.tsx"],"sourcesContent":["import type { ComponentProps, JSX } from 'solid-js'\nimport { createUniqueId, Show, splitProps } from 'solid-js'\nimport { createFormFieldContext, FormFieldContext } from '#lib/form-field'\nimport { cn } from '#lib/utils'\n\n/**\n * SettingsSection and SettingsRow.\n *\n * A settings page is the most repetitive surface in any application, and the\n * one where drift is most visible: label sizes, control widths and description\n * placement all wander unless something fixes them.\n *\n * The row is a two-column layout at a fixed label width, so controls line up\n * down the page regardless of how long the labels are. `SettingsRow` also\n * exposes its label and description through the shared form-field context to\n * the first control inside it. `SettingsField` is the visual stacked layout;\n * use `FormField` when the control needs label, help, or validation wiring.\n */\nexport function SettingsSection(\n props: ComponentProps<'section'> & {\n title: string\n description?: string\n /** A control for the section as a whole, e.g. a master toggle. */\n action?: JSX.Element\n /** Use a spaced content stack for fields, alerts, and cards instead of divided rows. */\n bodyLayout?: 'rows' | 'content'\n }\n) {\n const [local, rest] = splitProps(props, [\n 'class',\n 'title',\n 'description',\n 'action',\n 'bodyLayout',\n 'children',\n ])\n\n return (\n <section\n data-slot=\"settings-section\"\n class={cn('flex flex-col gap-4 px-5 py-5', local.class)}\n {...rest}\n >\n <div class=\"flex items-start justify-between gap-4\">\n <div class=\"flex min-w-0 flex-col gap-0.5\">\n <h2 class=\"text-base font-semibold tracking-tight\">{local.title}</h2>\n <Show when={local.description}>\n <p class=\"max-w-prose text-sm text-muted-foreground text-pretty\">{local.description}</p>\n </Show>\n </div>\n <Show when={local.action}>\n <div class=\"flex shrink-0 items-center gap-2\">{local.action}</div>\n </Show>\n </div>\n <div\n data-slot=\"settings-section-body\"\n class={cn(\n local.bodyLayout === 'content'\n ? 'flex flex-col gap-4'\n : 'divide-y divide-border rounded-xl border border-border'\n )}\n >\n {local.children}\n </div>\n </section>\n )\n}\n\n/**\n * One setting: a label and description on the leading side, a control on the\n * trailing side.\n *\n * The label and description are linked to a shared control through field\n * context. An explicit `aria-label` or `aria-labelledby` on the control keeps\n * precedence; otherwise the visible row label names it.\n */\nexport function SettingsRow(\n props: ComponentProps<'div'> & {\n label: string\n description?: string\n /** Render a vertical stack when the control needs the full width. */\n orientation?: 'horizontal' | 'vertical'\n /** Hide the divider this row would otherwise contribute. */\n bare?: boolean\n }\n) {\n const [local, rest] = splitProps(props, [\n 'class',\n 'label',\n 'description',\n 'orientation',\n 'bare',\n 'children',\n ])\n const rowId = createUniqueId()\n const labelId = `${rowId}-label`\n const descriptionId = `${rowId}-description`\n const field = createFormFieldContext({\n defaultControlId: rowId,\n labelId,\n descriptionId,\n hint: () => local.description,\n error: () => undefined,\n group: () => false,\n })\n\n return (\n <FormFieldContext.Provider value={field}>\n <div\n data-slot=\"settings-row\"\n class={cn(\n 'flex gap-4 p-4',\n local.orientation === 'vertical'\n ? 'flex-col'\n : 'flex-col sm:flex-row sm:items-center sm:justify-between',\n local.class\n )}\n {...rest}\n >\n <div class=\"flex min-w-0 flex-col gap-0.5\">\n <div id={labelId} data-slot=\"settings-row-label\" class=\"text-sm font-medium\">\n {local.label}\n </div>\n <Show when={local.description}>\n <p id={descriptionId} class=\"max-w-prose text-sm text-muted-foreground text-pretty\">\n {local.description}\n </p>\n </Show>\n </div>\n <div\n data-slot=\"settings-row-control\"\n class={cn('shrink-0', local.orientation === 'vertical' && 'w-full')}\n >\n {local.children}\n </div>\n </div>\n </FormFieldContext.Provider>\n )\n}\n\n/** A stacked label-and-control pair, for a control too wide for a row. */\nexport function SettingsField(\n props: ComponentProps<'div'> & { label: string; description?: string; htmlFor?: string }\n) {\n const [local, rest] = splitProps(props, ['class', 'label', 'description', 'htmlFor', 'children'])\n\n return (\n <div data-slot=\"settings-field\" class={cn('flex flex-col gap-2 p-4', local.class)} {...rest}>\n <div class=\"flex flex-col gap-0.5\">\n <label for={local.htmlFor} class=\"text-sm font-medium\">\n {local.label}\n </label>\n <Show when={local.description}>\n <p class=\"max-w-prose text-sm text-muted-foreground text-pretty\">{local.description}</p>\n </Show>\n </div>\n <div>{local.children}</div>\n </div>\n )\n}\n\n/** A settings page's scrolling body, with the header sticky at the top. */\nexport function SettingsPage(props: ComponentProps<'div'>) {\n const [local, rest] = splitProps(props, ['class'])\n return (\n <div\n data-slot=\"settings-page\"\n class={cn('flex min-h-0 flex-1 flex-col overflow-y-auto', local.class)}\n {...rest}\n />\n )\n}\n"],"mappings":"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"}
@@ -1,7 +1,7 @@
1
1
  import { cn } from "../../lib/utils.js";
2
2
  import { Button } from "../ui/button/button.js";
3
- import { Kbd } from "../ui/kbd/kbd.js";
4
3
  import { Spinner } from "../ui/spinner/spinner.js";
4
+ import { Kbd } from "../ui/kbd/kbd.js";
5
5
  import { Textarea } from "../ui/textarea/textarea.js";
6
6
  import { createComposerImeGuard } from "./ime-guard.js";
7
7
  import { className, createComponent, effect, insert, memo, mergeProps, spread, template } from "solid-js/web";
@@ -1 +1 @@
1
- {"version":3,"file":"scroll-follow.d.ts","sourceRoot":"","sources":["../../../src/components/conversation/scroll-follow.ts"],"names":[],"mappings":"AAgBA,OAAO,KAAK,EAAE,2BAA2B,EAAE,MAAM,wBAAwB,CAAA;AAezE,kFAAkF;AAClF,wBAAgB,kBAAkB,CAAC,OAAO,EAAE;IAC1C,OAAO,EAAE,MAAM,OAAO,CAAA;IACtB,QAAQ,EAAE,MAAM,MAAM,GAAG,SAAS,CAAA;IAClC,SAAS,EAAE,MAAM,MAAM,CAAA;IACvB,eAAe,CAAC,EAAE,MAAM,2BAA2B,GAAG,SAAS,CAAA;IAC/D,gBAAgB,CAAC,EAAE,CAAC,QAAQ,EAAE,2BAA2B,KAAK,IAAI,CAAA;CACnE;;;;4BAsH2B,cAAc;2BAGf,cAAc;EAIxC"}
1
+ {"version":3,"file":"scroll-follow.d.ts","sourceRoot":"","sources":["../../../src/components/conversation/scroll-follow.ts"],"names":[],"mappings":"AAgBA,OAAO,KAAK,EAAE,2BAA2B,EAAE,MAAM,wBAAwB,CAAA;AAgBzE,kFAAkF;AAClF,wBAAgB,kBAAkB,CAAC,OAAO,EAAE;IAC1C,OAAO,EAAE,MAAM,OAAO,CAAA;IACtB,QAAQ,EAAE,MAAM,MAAM,GAAG,SAAS,CAAA;IAClC,SAAS,EAAE,MAAM,MAAM,CAAA;IACvB,eAAe,CAAC,EAAE,MAAM,2BAA2B,GAAG,SAAS,CAAA;IAC/D,gBAAgB,CAAC,EAAE,CAAC,QAAQ,EAAE,2BAA2B,KAAK,IAAI,CAAA;CACnE;;;;4BAmN2B,cAAc;2BAGf,cAAc;EAIxC"}