@kerfjs/ui 5.0.0-beta.49 → 5.0.0-beta.51

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 (319) hide show
  1. package/README.md +69 -15
  2. package/ai/catalog-authoring.json +12 -1
  3. package/ai/catalog-authoring.schema.json +49 -1
  4. package/ai/compile-time-contracts-v1.json +19 -2
  5. package/ai/compile-time-contracts-v1.schema.json +1 -0
  6. package/ai/component-catalog-v2-overrides.json +7 -0
  7. package/ai/component-catalog-v2.d.ts +19 -1
  8. package/ai/component-catalog-v2.json +920 -149
  9. package/ai/component-catalog-v2.schema.json +33 -1
  10. package/ai/component-catalog.json +689 -153
  11. package/ai/component-catalog.schema.json +21 -1
  12. package/ai/public-api-signatures-v1.md +404 -184
  13. package/ai/skill.md +31 -14
  14. package/ai/webawesome-jsx-signatures-v1.md +1 -1
  15. package/analyzer/index.mjs +105 -35
  16. package/dist/app-tab.d.ts +3 -1
  17. package/dist/app-tab.js +1 -1
  18. package/dist/badge.d.ts +24 -0
  19. package/dist/badge.js +3 -0
  20. package/dist/badge.js.map +1 -0
  21. package/dist/browser/badge.js +3 -0
  22. package/dist/browser/list-header.js +1 -0
  23. package/dist/browser/state-banner.js +1 -0
  24. package/dist/catalog-resources.d.ts +2 -2
  25. package/dist/catalog.d.ts +47 -125
  26. package/dist/catalog.js +429 -262
  27. package/dist/catalog.js.map +1 -1
  28. package/dist/{chunk-W2FK7ZNY.js → chunk-4R777DUZ.js} +10 -2
  29. package/dist/chunk-4R777DUZ.js.map +1 -0
  30. package/dist/{chunk-OMSRSL3B.js → chunk-5FZZMIMD.js} +6 -4
  31. package/dist/chunk-5FZZMIMD.js.map +1 -0
  32. package/dist/{chunk-AQFWBG23.js → chunk-5PMGQDG7.js} +5 -3
  33. package/dist/chunk-5PMGQDG7.js.map +1 -0
  34. package/dist/{chunk-SOK5EUF7.js → chunk-6ZXOQEAN.js} +4 -2
  35. package/dist/chunk-6ZXOQEAN.js.map +1 -0
  36. package/dist/{chunk-I4V3UDSA.js → chunk-7GUQYHKA.js} +25 -6
  37. package/dist/chunk-7GUQYHKA.js.map +1 -0
  38. package/dist/{chunk-XKFRMGMW.js → chunk-7IUSV4XG.js} +3 -1
  39. package/dist/chunk-7IUSV4XG.js.map +1 -0
  40. package/dist/{chunk-IU4QUY5I.js → chunk-AEPXGCNF.js} +20 -3
  41. package/dist/chunk-AEPXGCNF.js.map +1 -0
  42. package/dist/{chunk-VDUJZF5G.js → chunk-CMUIXJZM.js} +2 -2
  43. package/dist/{chunk-VDUJZF5G.js.map → chunk-CMUIXJZM.js.map} +1 -1
  44. package/dist/{chunk-DAO2VFTT.js → chunk-D547PH4L.js} +7 -5
  45. package/dist/chunk-D547PH4L.js.map +1 -0
  46. package/dist/{chunk-2TYUFZUC.js → chunk-D7GWXIAS.js} +4 -2
  47. package/dist/chunk-D7GWXIAS.js.map +1 -0
  48. package/dist/{chunk-E34TE2ZI.js → chunk-DVZCMMB3.js} +6 -4
  49. package/dist/chunk-DVZCMMB3.js.map +1 -0
  50. package/dist/{chunk-6NDBE2OK.js → chunk-E36EVCKG.js} +5 -3
  51. package/dist/chunk-E36EVCKG.js.map +1 -0
  52. package/dist/chunk-EKYZCRCX.js +256 -0
  53. package/dist/chunk-EKYZCRCX.js.map +1 -0
  54. package/dist/{chunk-TIGSG6BX.js → chunk-HJKRCKDR.js} +7 -3
  55. package/dist/chunk-HJKRCKDR.js.map +1 -0
  56. package/dist/{chunk-Y6LYKFXY.js → chunk-HMQ2ZDGG.js} +5 -3
  57. package/dist/chunk-HMQ2ZDGG.js.map +1 -0
  58. package/dist/{chunk-UDHHKZWO.js → chunk-JM53SMVF.js} +9 -5
  59. package/dist/chunk-JM53SMVF.js.map +1 -0
  60. package/dist/{chunk-OGTJNHRG.js → chunk-JMGKM7RK.js} +6 -4
  61. package/dist/chunk-JMGKM7RK.js.map +1 -0
  62. package/dist/{chunk-GYGM363P.js → chunk-KX7DP2GO.js} +17 -7
  63. package/dist/chunk-KX7DP2GO.js.map +1 -0
  64. package/dist/{chunk-OL4TC3U2.js → chunk-MO56ZZLG.js} +6 -2
  65. package/dist/chunk-MO56ZZLG.js.map +1 -0
  66. package/dist/{chunk-VXFGMDA7.js → chunk-MTM43SJO.js} +16 -2
  67. package/dist/chunk-MTM43SJO.js.map +1 -0
  68. package/dist/{chunk-ZPWZIVI6.js → chunk-N3GKMPDW.js} +7 -3
  69. package/dist/chunk-N3GKMPDW.js.map +1 -0
  70. package/dist/{chunk-DYBPI5O2.js → chunk-NDUGJ4TU.js} +4 -2
  71. package/dist/chunk-NDUGJ4TU.js.map +1 -0
  72. package/dist/{chunk-I45QO2IZ.js → chunk-NMGTHYW3.js} +7 -5
  73. package/dist/chunk-NMGTHYW3.js.map +1 -0
  74. package/dist/{chunk-WSXUPSID.js → chunk-NN6GYOA2.js} +7 -3
  75. package/dist/chunk-NN6GYOA2.js.map +1 -0
  76. package/dist/{chunk-OGNE3OFT.js → chunk-NZXWU4R5.js} +24 -3
  77. package/dist/chunk-NZXWU4R5.js.map +1 -0
  78. package/dist/{chunk-V6GQKOX2.js → chunk-O3RCCSQJ.js} +6 -4
  79. package/dist/chunk-O3RCCSQJ.js.map +1 -0
  80. package/dist/{chunk-WVLMZ5SG.js → chunk-S4QRSBFI.js} +25 -3
  81. package/dist/chunk-S4QRSBFI.js.map +1 -0
  82. package/dist/{chunk-CK6P5AUK.js → chunk-UBH743HV.js} +10 -7
  83. package/dist/chunk-UBH743HV.js.map +1 -0
  84. package/dist/{chunk-T7DOWS6T.js → chunk-ULCDZTWL.js} +7 -4
  85. package/dist/chunk-ULCDZTWL.js.map +1 -0
  86. package/dist/{chunk-V6HCTCVD.js → chunk-UPZ6EEJN.js} +9 -5
  87. package/dist/chunk-UPZ6EEJN.js.map +1 -0
  88. package/dist/{chunk-CAB6NQ2T.js → chunk-VOCPXGQN.js} +3 -1
  89. package/dist/chunk-VOCPXGQN.js.map +1 -0
  90. package/dist/chunk-XD7DWYXG.js +34 -0
  91. package/dist/chunk-XD7DWYXG.js.map +1 -0
  92. package/dist/{chunk-B6JYRX3P.js → chunk-ZIYOJFZD.js} +43 -4
  93. package/dist/chunk-ZIYOJFZD.js.map +1 -0
  94. package/dist/{chunk-EYALJQQD.js → chunk-ZK5EGVFP.js} +4 -2
  95. package/dist/chunk-ZK5EGVFP.js.map +1 -0
  96. package/dist/{chunk-6WTETUZ6.js → chunk-ZLWQZUGF.js} +8 -2
  97. package/dist/chunk-ZLWQZUGF.js.map +1 -0
  98. package/dist/collapsible-panel.d.ts +4 -2
  99. package/dist/collapsible-panel.js +4 -2
  100. package/dist/collapsible-panel.js.map +1 -1
  101. package/dist/css-values.d.ts +39 -3
  102. package/dist/css-values.js +1 -1
  103. package/dist/disclosure-arrow.d.ts +3 -1
  104. package/dist/disclosure-arrow.js +1 -1
  105. package/dist/empty-state.d.ts +3 -1
  106. package/dist/empty-state.js +1 -1
  107. package/dist/floating-toolbar.d.ts +3 -1
  108. package/dist/floating-toolbar.js +1 -1
  109. package/dist/grid.d.ts +17 -1
  110. package/dist/grid.js +2 -1
  111. package/dist/index.d.ts +4 -3
  112. package/dist/index.js +34 -33
  113. package/dist/list-action-row.d.ts +3 -1
  114. package/dist/list-action-row.js +1 -1
  115. package/dist/list-header.d.ts +6 -1
  116. package/dist/list-header.js +2 -1
  117. package/dist/list-inset-control.d.ts +3 -1
  118. package/dist/list-inset-control.js +1 -1
  119. package/dist/list-inset-text.d.ts +3 -1
  120. package/dist/list-inset-text.js +1 -1
  121. package/dist/list-item.d.ts +3 -1
  122. package/dist/list-item.js +1 -1
  123. package/dist/list.d.ts +23 -2
  124. package/dist/list.js +2 -1
  125. package/dist/loading-spinner.d.ts +3 -1
  126. package/dist/loading-spinner.js +1 -1
  127. package/dist/lucide-icon.d.ts +3 -1
  128. package/dist/lucide-icon.js +1 -1
  129. package/dist/nav-stack.d.ts +3 -1
  130. package/dist/nav-stack.js +1 -1
  131. package/dist/pane.d.ts +19 -2
  132. package/dist/pane.js +1 -1
  133. package/dist/resizable-region.d.ts +5 -2
  134. package/dist/resizable-region.js +1 -1
  135. package/dist/row.d.ts +21 -1
  136. package/dist/row.js +2 -1
  137. package/dist/segmented-control.d.ts +3 -1
  138. package/dist/segmented-control.js +1 -1
  139. package/dist/select.d.ts +16 -4
  140. package/dist/select.js +1 -1
  141. package/dist/skeleton.d.ts +3 -1
  142. package/dist/skeleton.js +1 -1
  143. package/dist/spacer.d.ts +3 -1
  144. package/dist/spacer.js +1 -1
  145. package/dist/split-view.d.ts +3 -1
  146. package/dist/split-view.js +24 -5
  147. package/dist/split-view.js.map +1 -1
  148. package/dist/state-banner.d.ts +3 -1
  149. package/dist/state-banner.js +2 -1
  150. package/dist/styles/badge.css +86 -0
  151. package/dist/styles/catalog/components/catalog-detail.css +35 -0
  152. package/dist/styles/catalog/components/catalog-example-stack.css +9 -0
  153. package/dist/styles/catalog/components/catalog-example.css +180 -0
  154. package/dist/styles/catalog/components/catalog-resource-footer.css +37 -0
  155. package/dist/styles/catalog/components/catalog-secondary-sections.css +38 -0
  156. package/dist/styles/catalog/components/catalog-section-list.css +22 -0
  157. package/dist/styles/catalog/components/catalog-sidebar.css +82 -0
  158. package/dist/styles/catalog/components/catalog-stage.css +60 -0
  159. package/dist/styles/catalog/components/catalog.css +22 -0
  160. package/dist/styles/catalog.css +10 -587
  161. package/dist/styles/collapsible-panel.css +132 -4
  162. package/dist/styles/document.css +23 -0
  163. package/dist/styles/foundation.css +21 -7
  164. package/dist/styles/grid.css +10 -0
  165. package/dist/styles/list-header.css +49 -60
  166. package/dist/styles/list-inset-control.css +8 -1
  167. package/dist/styles/list-item.css +6 -0
  168. package/dist/styles/list.css +11 -0
  169. package/dist/styles/nav-stack.css +89 -2
  170. package/dist/styles/pane.css +86 -1
  171. package/dist/styles/resizable-region.css +117 -5
  172. package/dist/styles/row.css +10 -0
  173. package/dist/styles/select.css +39 -7
  174. package/dist/styles/split-view.css +108 -2
  175. package/dist/styles/state-banner.css +0 -27
  176. package/dist/styles/styles.css +1 -0
  177. package/dist/styles/tab-bar.css +6 -1
  178. package/dist/styles/tab-scaffold.css +64 -1
  179. package/dist/styles/text.css +10 -0
  180. package/dist/styles/token-search-field.css +5 -40
  181. package/dist/styles/toolbar-control-group.css +198 -25
  182. package/dist/styles/toolbar-text.css +8 -1
  183. package/dist/styles/toolbar.css +169 -5
  184. package/dist/styles/webawesome.css +70 -9
  185. package/dist/styles/workbench.css +136 -4
  186. package/dist/sunken-panel.d.ts +3 -1
  187. package/dist/sunken-panel.js +1 -1
  188. package/dist/surface-scaffold.d.ts +6 -2
  189. package/dist/surface-scaffold.js +1 -1
  190. package/dist/tab-bar.d.ts +8 -1
  191. package/dist/tab-bar.js +1 -1
  192. package/dist/tab-scaffold.d.ts +3 -1
  193. package/dist/tab-scaffold.js +3 -1
  194. package/dist/tab-scaffold.js.map +1 -1
  195. package/dist/text.d.ts +9 -5
  196. package/dist/text.js +1 -1
  197. package/dist/token-search-field.d.ts +5 -1
  198. package/dist/token-search-field.js +1 -1
  199. package/dist/toolbar-control-group.d.ts +33 -3
  200. package/dist/toolbar-control-group.js +1 -1
  201. package/dist/toolbar-text.d.ts +3 -1
  202. package/dist/toolbar-text.js +1 -1
  203. package/dist/toolbar.d.ts +30 -1
  204. package/dist/toolbar.js +1 -1
  205. package/dist/types-CEsieBZi.d.ts +69 -0
  206. package/dist/value-table.d.ts +6 -2
  207. package/dist/value-table.js +1 -1
  208. package/dist/wire-resizable-regions.js +1 -1
  209. package/dist/wire-sidebar.d.ts +18 -3
  210. package/dist/wire-sidebar.js +95 -14
  211. package/dist/wire-sidebar.js.map +1 -1
  212. package/dist/wire-token-search-fields.js +1 -1
  213. package/dist/workbench.d.ts +3 -1
  214. package/dist/workbench.js +3 -1
  215. package/dist/workbench.js.map +1 -1
  216. package/docs/accessibility.md +56 -9
  217. package/docs/app-layouts.md +73 -0
  218. package/docs/catalog.md +48 -9
  219. package/docs/collapsible-panel.md +81 -8
  220. package/docs/component-contract.md +96 -28
  221. package/docs/component-integration.md +9 -4
  222. package/docs/component-selection.md +36 -15
  223. package/docs/design/templates/list/stack-dark.svg +1 -1
  224. package/docs/design/templates/list/stack.svg +1 -1
  225. package/docs/design/templates/list-dark.svg +1 -1
  226. package/docs/design/templates/list-header/action-dark.svg +1 -1
  227. package/docs/design/templates/list-header/action.svg +1 -1
  228. package/docs/design/templates/list-header/count-dark.svg +1 -1
  229. package/docs/design/templates/list-header/count.svg +1 -1
  230. package/docs/design/templates/list-header/inline-action-dark.svg +1 -1
  231. package/docs/design/templates/list-header/inline-action.svg +1 -1
  232. package/docs/design/templates/list-header/toggle-expanded-dark.svg +1 -1
  233. package/docs/design/templates/list-header/toggle-expanded.svg +1 -1
  234. package/docs/design/templates/list-header-dark.svg +1 -1
  235. package/docs/design/templates/list-header.svg +1 -1
  236. package/docs/design/templates/list.svg +1 -1
  237. package/docs/design/templates/state-banner/info-badge-dark.svg +1 -1
  238. package/docs/design/templates/state-banner/info-badge.svg +1 -1
  239. package/docs/design/templates/state-banner-dark.svg +1 -1
  240. package/docs/design/templates/state-banner.svg +1 -1
  241. package/docs/design/templates/toolbar/title-and-actions-dark.svg +1 -1
  242. package/docs/design/templates/toolbar/title-and-actions.svg +1 -1
  243. package/docs/design/templates/toolbar-control-group/with-text-dark.svg +1 -1
  244. package/docs/design/templates/toolbar-control-group/with-text.svg +1 -1
  245. package/docs/design/templates/toolbar-control-group-dark.svg +1 -1
  246. package/docs/design/templates/toolbar-control-group.svg +1 -1
  247. package/docs/design/templates/toolbar-dark.svg +1 -1
  248. package/docs/design/templates/toolbar-text/default-dark.svg +1 -1
  249. package/docs/design/templates/toolbar-text/default.svg +1 -1
  250. package/docs/design/templates/toolbar-text/large-dark.svg +1 -1
  251. package/docs/design/templates/toolbar-text/large.svg +1 -1
  252. package/docs/design/templates/toolbar-text/small-dark.svg +1 -1
  253. package/docs/design/templates/toolbar-text/small.svg +1 -1
  254. package/docs/design/templates/toolbar-text-dark.svg +1 -1
  255. package/docs/design/templates/toolbar-text.svg +1 -1
  256. package/docs/design/templates/toolbar.svg +1 -1
  257. package/docs/design-philosophy.md +6 -5
  258. package/docs/document-baseline.md +31 -0
  259. package/docs/layout.md +86 -21
  260. package/docs/nav-stack.md +8 -0
  261. package/docs/recipes.md +78 -43
  262. package/docs/split-view.md +8 -0
  263. package/docs/tab-scaffold.md +4 -2
  264. package/docs/type-contracts.md +21 -16
  265. package/docs/ui-analyzer.md +19 -0
  266. package/docs/ui-evaluator.md +17 -0
  267. package/docs/ux-demo.md +8 -8
  268. package/docs/webawesome-theme.md +25 -6
  269. package/docs/workbench.md +20 -1
  270. package/evaluator/index.mjs +73 -8
  271. package/llms.txt +61 -23
  272. package/package.json +12 -3
  273. package/ux-demo/recipes/app-shell.tsx +244 -184
  274. package/ux-demo/recipes/collapsible-sidebar.tsx +175 -116
  275. package/ux-demo/recipes/compact-toolbar.tsx +119 -102
  276. package/ux-demo/recipes/composer-form.tsx +79 -69
  277. package/ux-demo/recipes/list-detail-dialog.tsx +120 -136
  278. package/ux-demo/recipes/list-workspace-states.tsx +85 -79
  279. package/ux-demo/recipes/loaders.ts +5 -2
  280. package/ux-demo/recipes/loading-inspector.tsx +151 -134
  281. package/ux-demo/recipes/navigation-sidebar.tsx +93 -80
  282. package/ux-demo/recipes/navigation-stack.tsx +33 -22
  283. package/ux-demo/recipes/types.ts +14 -0
  284. package/ux-demo/recipes/workspace-header.tsx +73 -57
  285. package/dist/chunk-2TYUFZUC.js.map +0 -1
  286. package/dist/chunk-6NDBE2OK.js.map +0 -1
  287. package/dist/chunk-6WTETUZ6.js.map +0 -1
  288. package/dist/chunk-AQFWBG23.js.map +0 -1
  289. package/dist/chunk-B6JYRX3P.js.map +0 -1
  290. package/dist/chunk-CAB6NQ2T.js.map +0 -1
  291. package/dist/chunk-CK6P5AUK.js.map +0 -1
  292. package/dist/chunk-DAO2VFTT.js.map +0 -1
  293. package/dist/chunk-DYBPI5O2.js.map +0 -1
  294. package/dist/chunk-E34TE2ZI.js.map +0 -1
  295. package/dist/chunk-EYALJQQD.js.map +0 -1
  296. package/dist/chunk-GYGM363P.js.map +0 -1
  297. package/dist/chunk-I45QO2IZ.js.map +0 -1
  298. package/dist/chunk-I4V3UDSA.js.map +0 -1
  299. package/dist/chunk-IU4QUY5I.js.map +0 -1
  300. package/dist/chunk-OGNE3OFT.js.map +0 -1
  301. package/dist/chunk-OGTJNHRG.js.map +0 -1
  302. package/dist/chunk-OL4TC3U2.js.map +0 -1
  303. package/dist/chunk-OMSRSL3B.js.map +0 -1
  304. package/dist/chunk-SOK5EUF7.js.map +0 -1
  305. package/dist/chunk-T7DOWS6T.js.map +0 -1
  306. package/dist/chunk-TIGSG6BX.js.map +0 -1
  307. package/dist/chunk-UDHHKZWO.js.map +0 -1
  308. package/dist/chunk-V6GQKOX2.js.map +0 -1
  309. package/dist/chunk-V6HCTCVD.js.map +0 -1
  310. package/dist/chunk-VXFGMDA7.js.map +0 -1
  311. package/dist/chunk-W2FK7ZNY.js.map +0 -1
  312. package/dist/chunk-WN52USHV.js +0 -115
  313. package/dist/chunk-WN52USHV.js.map +0 -1
  314. package/dist/chunk-WSXUPSID.js.map +0 -1
  315. package/dist/chunk-WVLMZ5SG.js.map +0 -1
  316. package/dist/chunk-XKFRMGMW.js.map +0 -1
  317. package/dist/chunk-Y6LYKFXY.js.map +0 -1
  318. package/dist/chunk-ZPWZIVI6.js.map +0 -1
  319. package/ux-demo/recipes/recipes.css +0 -453
@@ -177,8 +177,8 @@
177
177
  --wa-form-control-activated-color: var(--wa-color-brand-fill-loud);
178
178
  /* Field inset: a 1px border with 8px inside it, the same content-item
179
179
  geometry the Kerf primitives use (docs/layout.md). WA's defaults are a
180
- larger 0.75em/1em pad; this brings every form field onto our 8px rhythm
181
- (and a ~40px single-line control height). */
180
+ larger 0.75em/1em pad; this brings every form field onto our 8px rhythm.
181
+ The single-line control height is set on the controls below. */
182
182
  --wa-form-control-border-width: var(--kui-layout-item-border-width, 1px);
183
183
  --wa-form-control-padding-block: var(
184
184
  --kui-layout-item-padding,
@@ -193,6 +193,18 @@
193
193
  --wa-tooltip-content-color: var(--wa-color-neutral-on-loud);
194
194
  --wa-tooltip-arrow-size: 0px;
195
195
  --kui-wa-popover-arrow-size: 0px;
196
+ /* Web Awesome's own `ui-monospace, monospace` renders the generic face
197
+ (Courier) in Chromium; use Kerf's named code stack for its components. */
198
+ --wa-font-family-code: var(
199
+ --kui-font-mono,
200
+ ui-monospace,
201
+ SFMono-Regular,
202
+ "SF Mono",
203
+ Menlo,
204
+ Consolas,
205
+ "Liberation Mono",
206
+ monospace
207
+ );
196
208
  --kui-wa-carousel-dot-size: 7px;
197
209
  --kui-wa-carousel-dot-hit-size: 20px;
198
210
  --kui-wa-carousel-control-size: 28px;
@@ -336,22 +348,37 @@
336
348
  box-shadow: none;
337
349
  }
338
350
 
339
- /* Unframed disclosures align directly with their surrounding content.
340
- Framed disclosure headers use the roomier container tier so the trigger
341
- reads as the surface heading while the body keeps its compact inset. */
342
- wa-details[appearance="plain"]::part(header),
343
- wa-details[appearance="plain"]::part(content),
351
+ wa-details[appearance="plain"]::part(header) {
352
+ padding-inline: var(--kui-wa-surface-inset);
353
+ }
354
+
355
+ wa-details[appearance="plain"]::part(content) {
356
+ padding-inline: 0;
357
+ }
358
+
359
+ wa-details:is([appearance="outlined"], [appearance="sunken"])::part(header) {
360
+ padding-inline: var(--kui-wa-container-inset);
361
+ }
362
+
363
+ wa-details:is([appearance="outlined"], [appearance="sunken"])::part(content) {
364
+ padding-inline: var(--kui-wa-surface-inset);
365
+ }
366
+
344
367
  wa-accordion[appearance="plain"] > wa-accordion-item::part(button),
345
368
  wa-accordion[appearance="plain"] > wa-accordion-item::part(content) {
346
- padding-inline: 0;
369
+ padding-inline: var(--kui-wa-surface-inset);
347
370
  }
348
371
 
349
- wa-details:is([appearance="outlined"], [appearance="sunken"])::part(header),
350
372
  wa-accordion:is([appearance="outlined"], [appearance="sunken"])
351
373
  > wa-accordion-item::part(button) {
352
374
  padding-inline: var(--kui-wa-container-inset);
353
375
  }
354
376
 
377
+ wa-accordion:is([appearance="outlined"], [appearance="sunken"])
378
+ > wa-accordion-item::part(content) {
379
+ padding-inline: var(--kui-wa-container-inset);
380
+ }
381
+
355
382
  wa-card,
356
383
  wa-details,
357
384
  wa-accordion-item {
@@ -388,6 +415,17 @@
388
415
  padding: var(--kui-wa-surface-inset);
389
416
  }
390
417
 
418
+ /* A plain-string `label` renders straight into the title part, so it would
419
+ sit at the bare surface inset while body content (list-inset text, Text)
420
+ starts one bordered item further in. Inset the default title by that item
421
+ step so the header label lines up with the body's text and icons. A
422
+ slotted label element owns its own geometry and is left alone. */
423
+ wa-dialog:not(:has(> [slot="label"]))::part(title) {
424
+ padding-inline: calc(
425
+ var(--kui-layout-item-padding, 0.5rem) + 0.0625rem
426
+ );
427
+ }
428
+
391
429
  wa-dialog::part(body) {
392
430
  padding: var(--kui-wa-surface-inset);
393
431
  }
@@ -442,6 +480,29 @@
442
480
  --arrow-size: var(--kui-wa-popover-arrow-size);
443
481
  }
444
482
 
483
+ /* Default-size single-line controls share Kerf's 44px control height (the
484
+ Select field, toolbar groups, and list rows), so a Web Awesome field,
485
+ button, or button radio sits flush beside a Kerf Select instead of 9px
486
+ shorter. The height is 2.75em of the control's own font size (44px at the
487
+ 16px default), so size="large" grows proportionally; size="small" stays
488
+ Web Awesome's deliberately compact secondary control. It is scoped to the
489
+ controls rather than the root because Web Awesome also derives tag, copy
490
+ button, and toast geometry from this token. A ToolbarControlGroup still
491
+ sizes its own nested buttons. */
492
+ :is(
493
+ wa-button,
494
+ wa-color-picker,
495
+ wa-input,
496
+ wa-known-date,
497
+ wa-number-input,
498
+ wa-radio-group,
499
+ wa-select,
500
+ wa-textarea,
501
+ wa-time-input
502
+ ):not([size="small"]) {
503
+ --wa-form-control-height: round(2.75em, 1px);
504
+ }
505
+
445
506
  /* A form field's top label is inset by the field's own border + inline padding
446
507
  (1px + 8px = 9px) so the label text lines up with the value inside the field,
447
508
  and it is styled exactly like a ListHeader label: uppercase, xs, quiet. */
@@ -6,23 +6,56 @@
6
6
  height: 100%;
7
7
  overflow: hidden;
8
8
  background: var(--kui-color-surface);
9
+ /* Safe areas: every track paints through the unsafe area it reaches (a rail
10
+ or drawer grows by that inset), and each region's content compensates only
11
+ for the edges the region still touches. An expanded inline rail takes its
12
+ edge away from the center; collapsing it hands the edge back. See pane.css
13
+ for the `--kui-edge-inset-*` edge context. */
14
+ --_kui-workbench-safe-block-start: var(
15
+ --kui-edge-inset-block-start,
16
+ var(--kui-safe-area-block-start, env(safe-area-inset-top, 0px))
17
+ );
18
+ --_kui-workbench-safe-block-end: var(
19
+ --kui-edge-inset-block-end,
20
+ var(--kui-safe-area-block-end, env(safe-area-inset-bottom, 0px))
21
+ );
22
+ --_kui-workbench-safe-inline-start: var(
23
+ --kui-edge-inset-inline-start,
24
+ var(--kui-safe-area-inline-start, env(safe-area-inset-left, 0px))
25
+ );
26
+ --_kui-workbench-safe-inline-end: var(
27
+ --kui-edge-inset-inline-end,
28
+ var(--kui-safe-area-inline-end, env(safe-area-inset-right, 0px))
29
+ );
9
30
  }
10
31
 
11
32
  /* Side rails. Collapsing snaps the flex track to zero (one reflow) while the
12
33
  fixed-width content slides out via transform (composited, clipped) — never a
13
34
  per-frame width animation. See docs/18 / the KF-7QKJRK catalog sidebar. */
14
35
  .kui-workbench__rail {
15
- flex: 0 0 var(--kui-workbench-rail-width, 17.5rem);
36
+ --kui-edge-inset-block-start: var(--_kui-workbench-safe-block-start);
37
+ --kui-edge-inset-block-end: var(--_kui-workbench-safe-block-end);
38
+ --_kui-workbench-rail-extent: calc(
39
+ var(--kui-workbench-rail-width, 17.5rem) +
40
+ var(--_kui-workbench-rail-safe-inset)
41
+ );
42
+ flex: 0 0 var(--_kui-workbench-rail-extent);
16
43
  min-width: 0;
17
44
  overflow: hidden;
18
45
  background: var(--kui-color-surface);
19
46
  }
20
47
 
21
48
  .kui-workbench__rail--left {
49
+ --_kui-workbench-rail-safe-inset: var(--_kui-workbench-safe-inline-start);
50
+ --kui-edge-inset-inline-start: var(--_kui-workbench-safe-inline-start);
51
+ --kui-edge-inset-inline-end: 0px;
22
52
  border-inline-end: 1px solid var(--kui-color-border);
23
53
  }
24
54
 
25
55
  .kui-workbench__rail--right {
56
+ --_kui-workbench-rail-safe-inset: var(--_kui-workbench-safe-inline-end);
57
+ --kui-edge-inset-inline-start: 0px;
58
+ --kui-edge-inset-inline-end: var(--_kui-workbench-safe-inline-end);
26
59
  border-inline-start: 1px solid var(--kui-color-border);
27
60
  }
28
61
 
@@ -37,6 +70,10 @@
37
70
  }
38
71
 
39
72
  .kui-workbench__center {
73
+ --kui-edge-inset-block-start: var(--_kui-workbench-safe-block-start);
74
+ --kui-edge-inset-block-end: var(--_kui-workbench-safe-block-end);
75
+ --kui-edge-inset-inline-start: var(--_kui-workbench-safe-inline-start);
76
+ --kui-edge-inset-inline-end: var(--_kui-workbench-safe-inline-end);
40
77
  display: flex;
41
78
  flex: 1;
42
79
  min-width: 0;
@@ -45,16 +82,111 @@
45
82
  flex-direction: column;
46
83
  }
47
84
 
85
+ .kui-workbench:has(
86
+ > .kui-workbench__rail--left[data-presentation="inline"]:not(
87
+ [data-collapsed="true"]
88
+ )
89
+ )
90
+ > .kui-workbench__center {
91
+ --kui-edge-inset-inline-start: 0px;
92
+ }
93
+
94
+ .kui-workbench:has(
95
+ > .kui-workbench__rail--right[data-presentation="inline"]:not(
96
+ [data-collapsed="true"]
97
+ )
98
+ )
99
+ > .kui-workbench__center {
100
+ --kui-edge-inset-inline-end: 0px;
101
+ }
102
+
48
103
  .kui-workbench__main {
49
104
  flex: 1;
50
105
  min-height: 0;
51
106
  overflow: auto;
52
107
  }
53
108
 
109
+ .kui-workbench__main:has(
110
+ ~ .kui-workbench__drawer[data-presentation="inline"]:not(
111
+ [data-collapsed="true"]
112
+ )
113
+ ) {
114
+ --kui-edge-inset-block-end: 0px;
115
+ }
116
+
117
+ /* The main area and each panel's content are the consumers: they pad for the
118
+ edges their region still touches, the main area inside its scroller so
119
+ content scrolls under an unsafe edge but can always be scrolled clear. A
120
+ region whose only child is a Pane or layout lets that child own the insets. */
121
+ .kui-workbench__main:not(
122
+ :has(
123
+ > :is(
124
+ [data-component="pane"],
125
+ [data-component="nav-stack"],
126
+ [data-component="split-view"],
127
+ [data-component="workbench"],
128
+ [data-component="tab-scaffold"]
129
+ ):only-child
130
+ )
131
+ ),
132
+ .kui-workbench__panel-content:not(
133
+ :has(
134
+ > :is(
135
+ [data-component="pane"],
136
+ [data-component="nav-stack"],
137
+ [data-component="split-view"],
138
+ [data-component="workbench"],
139
+ [data-component="tab-scaffold"]
140
+ ):only-child
141
+ )
142
+ ) {
143
+ padding-block: var(--kui-edge-inset-block-start)
144
+ var(--kui-edge-inset-block-end);
145
+ padding-inline: var(--kui-edge-inset-inline-start)
146
+ var(--kui-edge-inset-inline-end);
147
+ scroll-padding-block: var(--kui-edge-inset-block-start)
148
+ var(--kui-edge-inset-block-end);
149
+ }
150
+
151
+ .kui-workbench__main:not(
152
+ :has(
153
+ > :is(
154
+ [data-component="pane"],
155
+ [data-component="nav-stack"],
156
+ [data-component="split-view"],
157
+ [data-component="workbench"],
158
+ [data-component="tab-scaffold"]
159
+ ):only-child
160
+ )
161
+ )
162
+ > *,
163
+ .kui-workbench__panel-content:not(
164
+ :has(
165
+ > :is(
166
+ [data-component="pane"],
167
+ [data-component="nav-stack"],
168
+ [data-component="split-view"],
169
+ [data-component="workbench"],
170
+ [data-component="tab-scaffold"]
171
+ ):only-child
172
+ )
173
+ )
174
+ > * {
175
+ --kui-edge-inset-block-start: 0px;
176
+ --kui-edge-inset-block-end: 0px;
177
+ --kui-edge-inset-inline-start: 0px;
178
+ --kui-edge-inset-inline-end: 0px;
179
+ }
180
+
54
181
  /* Bottom drawer — the vertical analogue of a rail. */
55
182
  .kui-workbench__drawer {
183
+ --kui-edge-inset-block-start: 0px;
184
+ --_kui-workbench-drawer-extent: calc(
185
+ var(--kui-workbench-drawer-height, 13.75rem) +
186
+ var(--_kui-workbench-safe-block-end)
187
+ );
56
188
  position: relative;
57
- flex: 0 0 var(--kui-workbench-drawer-height, 13.75rem);
189
+ flex: 0 0 var(--_kui-workbench-drawer-extent);
58
190
  min-height: 0;
59
191
  overflow: hidden;
60
192
  border-block-start: 1px solid var(--kui-color-border);
@@ -80,7 +212,7 @@
80
212
  /* The fixed-size sliding content. The rail/drawer keeps a definite size on its
81
213
  content so the transform reads as a slide, not a squeeze. */
82
214
  .kui-workbench__rail .kui-workbench__panel-content {
83
- width: var(--kui-workbench-rail-width, 17.5rem);
215
+ width: var(--_kui-workbench-rail-extent);
84
216
  height: 100%;
85
217
  transition: transform 200ms ease;
86
218
  }
@@ -90,7 +222,7 @@
90
222
  inset-inline: 0;
91
223
  inset-block-end: 0;
92
224
  width: 100%;
93
- height: var(--kui-workbench-drawer-height, 13.75rem);
225
+ height: var(--_kui-workbench-drawer-extent);
94
226
  transition: transform 200ms ease;
95
227
  }
96
228
 
@@ -9,12 +9,14 @@ interface SunkenPanelProps {
9
9
  /** Corner shape: a rounded rectangle (default) or square corners. */
10
10
  shape?: SunkenPanelShape;
11
11
  className?: string;
12
+ /** Native named-slot assignment when composed inside a web component. */
13
+ slot?: string;
12
14
  }
13
15
  /**
14
16
  * A lowered application surface with one compact inset and a vertical content
15
17
  * stack. The panel owns its background and padding; children own their own
16
18
  * borders and internal geometry.
17
19
  */
18
- declare function SunkenPanel({ children, ariaLabel, shape, className, }: SunkenPanelProps): kerfjs.SafeHtml;
20
+ declare function SunkenPanel({ children, ariaLabel, shape, className, slot, }: SunkenPanelProps): kerfjs.SafeHtml;
19
21
 
20
22
  export { SunkenPanel, type SunkenPanelProps, type SunkenPanelShape };
@@ -1,3 +1,3 @@
1
- export { SunkenPanel } from './chunk-SOK5EUF7.js';
1
+ export { SunkenPanel } from './chunk-6ZXOQEAN.js';
2
2
 
3
3
  //# sourceMappingURL=sunken-panel.js.map
@@ -11,16 +11,20 @@ interface DialogSurfaceProps {
11
11
  bodyInset?: SurfaceInset;
12
12
  footerInset?: SurfaceInset;
13
13
  className?: string;
14
+ /** Native named-slot assignment when composed inside a web component. */
15
+ slot?: string;
14
16
  }
15
17
  /** Configure recurring Web Awesome dialog geometry without consumer ::part() CSS. */
16
- declare function DialogSurface({ children, size, presentation, bodyInset, footerInset, className, }: DialogSurfaceProps): kerfjs.SafeHtml;
18
+ declare function DialogSurface({ children, size, presentation, bodyInset, footerInset, className, slot, }: DialogSurfaceProps): kerfjs.SafeHtml;
17
19
  type PopupSurfaceInset = 'standard' | 'compact' | 'list-zero';
18
20
  interface PopupSurfaceProps {
19
21
  children: KerfUiContent;
20
22
  inset?: PopupSurfaceInset;
21
23
  className?: string;
24
+ /** Native named-slot assignment when composed inside a web component. */
25
+ slot?: string;
22
26
  }
23
27
  /** Configure recurring Web Awesome dropdown-menu geometry without consumer ::part() CSS. */
24
- declare function PopupSurface({ children, inset, className, }: PopupSurfaceProps): kerfjs.SafeHtml;
28
+ declare function PopupSurface({ children, inset, className, slot, }: PopupSurfaceProps): kerfjs.SafeHtml;
25
29
 
26
30
  export { DialogSurface, type DialogSurfacePresentation, type DialogSurfaceProps, type DialogSurfaceSize, PopupSurface, type PopupSurfaceInset, type PopupSurfaceProps, type SurfaceInset };
@@ -1,3 +1,3 @@
1
- export { DialogSurface, PopupSurface } from './chunk-WSXUPSID.js';
1
+ export { DialogSurface, PopupSurface } from './chunk-NN6GYOA2.js';
2
2
 
3
3
  //# sourceMappingURL=surface-scaffold.js.map
package/dist/tab-bar.d.ts CHANGED
@@ -11,6 +11,11 @@ interface TabBarProps {
11
11
  children: KerfUiContent;
12
12
  leading?: KerfUiContent;
13
13
  trailing?: KerfUiContent;
14
+ /**
15
+ * Action pinned to the far edge of the bar. Combine with an adjacent `trailing`
16
+ * action when the tab-local and workspace-level actions must remain distinct.
17
+ */
18
+ end?: KerfUiContent;
14
19
  className?: string;
15
20
  /**
16
21
  * Keyboard activation mode for this strip, emitted as `data-tab-activation` for
@@ -25,8 +30,10 @@ interface TabBarProps {
25
30
  presentation?: TabBarPresentation;
26
31
  /** Keep a trailing action beside the final tab or at the far edge of the bar. */
27
32
  trailingPlacement?: TabBarTrailingPlacement;
33
+ /** Native named-slot assignment when composed inside a web component. */
34
+ slot?: string;
28
35
  }
29
36
  /** Render a controlled tab strip. The application owns selection, order, and persistence. */
30
- declare function TabBar({ id, label, children, leading, trailing, className, activation, allocation, presentation, trailingPlacement, }: TabBarProps): kerfjs.SafeHtml;
37
+ declare function TabBar({ id, label, children, leading, trailing, end, className, activation, allocation, presentation, trailingPlacement, slot, }: TabBarProps): kerfjs.SafeHtml;
31
38
 
32
39
  export { type TabActivation, TabBar, type TabBarAllocation, type TabBarPresentation, type TabBarProps, type TabBarTrailingPlacement };
package/dist/tab-bar.js CHANGED
@@ -1,3 +1,3 @@
1
- export { TabBar } from './chunk-ZPWZIVI6.js';
1
+ export { TabBar } from './chunk-N3GKMPDW.js';
2
2
 
3
3
  //# sourceMappingURL=tab-bar.js.map
@@ -17,6 +17,8 @@ interface TabScaffoldProps<Id extends string = string> {
17
17
  /** The controlled active tab id (the app owns selection). */
18
18
  active: NoInfer<Id>;
19
19
  className?: string;
20
+ /** Native named-slot assignment when composed inside a web component. */
21
+ slot?: string;
20
22
  }
21
23
  /**
22
24
  * A mobile-first, iOS-like bottom tab scaffold: a bottom tab bar that switches
@@ -26,6 +28,6 @@ interface TabScaffoldProps<Id extends string = string> {
26
28
  * On larger classes, promote the tabs to a `Workbench` rail or sidebar instead of
27
29
  * a bottom bar. See `docs/23-app-layouts.md` §3.4.
28
30
  */
29
- declare function TabScaffold<Id extends string>({ id, label, tabs, active, className, }: TabScaffoldProps<Id>): SafeHtml;
31
+ declare function TabScaffold<Id extends string>({ id, label, tabs, active, className, slot, }: TabScaffoldProps<Id>): SafeHtml;
30
32
 
31
33
  export { TabScaffold, type TabScaffoldProps, type TabScaffoldTab };
@@ -6,7 +6,8 @@ function TabScaffold({
6
6
  label,
7
7
  tabs,
8
8
  active,
9
- className = ""
9
+ className = "",
10
+ slot
10
11
  }) {
11
12
  return /* @__PURE__ */ jsxs(
12
13
  "section",
@@ -15,6 +16,7 @@ function TabScaffold({
15
16
  id,
16
17
  "data-component": "tab-scaffold",
17
18
  "data-tab-scaffold-id": id,
19
+ slot,
18
20
  children: [
19
21
  /* @__PURE__ */ jsx("div", { class: "kui-tab-scaffold__scenes", children: tabs.map((tab) => /* @__PURE__ */ jsx(
20
22
  "div",
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/tab-scaffold.tsx"],"names":[],"mappings":";;;AA+BO,SAAS,WAAA,CAA+B;AAAA,EAC7C,EAAA;AAAA,EACA,KAAA;AAAA,EACA,IAAA;AAAA,EACA,MAAA;AAAA,EACA,SAAA,GAAY;AACd,CAAA,EAAyB;AACvB,EAAA,uBACE,IAAA;AAAA,IAAC,SAAA;AAAA,IAAA;AAAA,MACC,KAAA,EAAO,CAAA,iBAAA,EAAoB,SAAS,CAAA,CAAA,CAAG,IAAA,EAAK;AAAA,MAC5C,EAAA;AAAA,MACA,gBAAA,EAAe,cAAA;AAAA,MACf,sBAAA,EAAsB,EAAA;AAAA,MAEtB,QAAA,EAAA;AAAA,wBAAA,GAAA,CAAC,SAAI,KAAA,EAAM,0BAAA,EACR,QAAA,EAAA,IAAA,CAAK,GAAA,CAAI,CAAC,GAAA,qBACT,GAAA;AAAA,UAAC,KAAA;AAAA,UAAA;AAAA,YACC,KAAA,EAAM,yBAAA;AAAA,YACN,2BAAyB,GAAA,CAAI,EAAA;AAAA,YAC7B,aAAA,EAAa,MAAA,CAAO,GAAA,CAAI,EAAA,KAAO,MAAM,CAAA;AAAA,YACrC,aAAA,EAAa,MAAA,CAAO,GAAA,CAAI,EAAA,KAAO,MAAM,CAAA;AAAA,YAEpC,QAAA,EAAA,GAAA,CAAI;AAAA;AAAA,SAER,CAAA,EACH,CAAA;AAAA,wBACA,GAAA,CAAC,KAAA,EAAA,EAAI,KAAA,EAAM,uBAAA,EAAwB,IAAA,EAAK,SAAA,EAAU,YAAA,EAAY,KAAA,EAC3D,QAAA,EAAA,IAAA,CAAK,GAAA,CAAI,CAAC,GAAA,qBACT,IAAA;AAAA,UAAC,QAAA;AAAA,UAAA;AAAA,YACC,IAAA,EAAK,QAAA;AAAA,YACL,KAAA,EAAM,uBAAA;AAAA,YACN,IAAA,EAAK,KAAA;AAAA,YACL,yBAAuB,GAAA,CAAI,EAAA;AAAA,YAC3B,eAAA,EAAe,MAAA,CAAO,GAAA,CAAI,EAAA,KAAO,MAAM,CAAA;AAAA,YACvC,QAAA,EAAU,GAAA,CAAI,EAAA,KAAO,MAAA,GAAS,GAAA,GAAM,IAAA;AAAA,YAEnC,QAAA,EAAA;AAAA,cAAA,GAAA,CAAI,IAAA,wBACF,MAAA,EAAA,EAAK,KAAA,EAAM,8BAA6B,aAAA,EAAY,MAAA,EAClD,cAAI,IAAA,EACP,CAAA;AAAA,8BAEF,GAAA,CAAC,MAAA,EAAA,EAAK,KAAA,EAAM,6BAAA,EAA+B,cAAI,KAAA,EAAM;AAAA;AAAA;AAAA,SAExD,CAAA,EACH;AAAA;AAAA;AAAA,GACF;AAEJ","file":"tab-scaffold.js","sourcesContent":["import type { SafeHtml } from 'kerfjs';\n\nimport type { KerfUiContent } from './semantic-content.js';\n\nexport interface TabScaffoldTab<Id extends string = string> {\n id: Id;\n label: string;\n /** Decorative icon shown above the label in the bottom bar. */\n icon?: SafeHtml;\n /** The tab's content — typically a `NavStack` so each tab keeps its own stack. */\n content: KerfUiContent;\n}\n\nexport interface TabScaffoldProps<Id extends string = string> {\n id: string;\n /** Accessible name for the tab bar. */\n label: string;\n tabs: readonly TabScaffoldTab<Id>[];\n /** The controlled active tab id (the app owns selection). */\n active: NoInfer<Id>;\n className?: string;\n}\n\n/**\n * A mobile-first, iOS-like bottom tab scaffold: a bottom tab bar that switches\n * between major sections, each tab keeping its own content (usually a `NavStack`)\n * mounted so its stack and scroll survive a switch. Controlled — the app owns\n * `active`; wire selection with `@kerfjs/ui/wire-tab-scaffold`'s `wireTabScaffold`.\n * On larger classes, promote the tabs to a `Workbench` rail or sidebar instead of\n * a bottom bar. See `docs/23-app-layouts.md` §3.4.\n */\nexport function TabScaffold<Id extends string>({\n id,\n label,\n tabs,\n active,\n className = '',\n}: TabScaffoldProps<Id>) {\n return (\n <section\n class={`kui-tab-scaffold ${className}`.trim()}\n id={id}\n data-component=\"tab-scaffold\"\n data-tab-scaffold-id={id}\n >\n <div class=\"kui-tab-scaffold__scenes\">\n {tabs.map((tab) => (\n <div\n class=\"kui-tab-scaffold__scene\"\n data-tab-scaffold-scene={tab.id}\n data-active={String(tab.id === active)}\n aria-hidden={String(tab.id !== active)}\n >\n {tab.content}\n </div>\n ))}\n </div>\n <nav class=\"kui-tab-scaffold__bar\" role=\"tablist\" aria-label={label}>\n {tabs.map((tab) => (\n <button\n type=\"button\"\n class=\"kui-tab-scaffold__tab\"\n role=\"tab\"\n data-tab-scaffold-tab={tab.id}\n aria-selected={String(tab.id === active)}\n tabindex={tab.id === active ? '0' : '-1'}\n >\n {tab.icon && (\n <span class=\"kui-tab-scaffold__tab-icon\" aria-hidden=\"true\">\n {tab.icon}\n </span>\n )}\n <span class=\"kui-tab-scaffold__tab-label\">{tab.label}</span>\n </button>\n ))}\n </nav>\n </section>\n );\n}\n"]}
1
+ {"version":3,"sources":["../src/tab-scaffold.tsx"],"names":[],"mappings":";;;AAiCO,SAAS,WAAA,CAA+B;AAAA,EAC7C,EAAA;AAAA,EACA,KAAA;AAAA,EACA,IAAA;AAAA,EACA,MAAA;AAAA,EACA,SAAA,GAAY,EAAA;AAAA,EACZ;AACF,CAAA,EAAyB;AACvB,EAAA,uBACE,IAAA;AAAA,IAAC,SAAA;AAAA,IAAA;AAAA,MACC,KAAA,EAAO,CAAA,iBAAA,EAAoB,SAAS,CAAA,CAAA,CAAG,IAAA,EAAK;AAAA,MAC5C,EAAA;AAAA,MACA,gBAAA,EAAe,cAAA;AAAA,MACf,sBAAA,EAAsB,EAAA;AAAA,MACtB,IAAA;AAAA,MAEA,QAAA,EAAA;AAAA,wBAAA,GAAA,CAAC,SAAI,KAAA,EAAM,0BAAA,EACR,QAAA,EAAA,IAAA,CAAK,GAAA,CAAI,CAAC,GAAA,qBACT,GAAA;AAAA,UAAC,KAAA;AAAA,UAAA;AAAA,YACC,KAAA,EAAM,yBAAA;AAAA,YACN,2BAAyB,GAAA,CAAI,EAAA;AAAA,YAC7B,aAAA,EAAa,MAAA,CAAO,GAAA,CAAI,EAAA,KAAO,MAAM,CAAA;AAAA,YACrC,aAAA,EAAa,MAAA,CAAO,GAAA,CAAI,EAAA,KAAO,MAAM,CAAA;AAAA,YAEpC,QAAA,EAAA,GAAA,CAAI;AAAA;AAAA,SAER,CAAA,EACH,CAAA;AAAA,wBACA,GAAA,CAAC,KAAA,EAAA,EAAI,KAAA,EAAM,uBAAA,EAAwB,IAAA,EAAK,SAAA,EAAU,YAAA,EAAY,KAAA,EAC3D,QAAA,EAAA,IAAA,CAAK,GAAA,CAAI,CAAC,GAAA,qBACT,IAAA;AAAA,UAAC,QAAA;AAAA,UAAA;AAAA,YACC,IAAA,EAAK,QAAA;AAAA,YACL,KAAA,EAAM,uBAAA;AAAA,YACN,IAAA,EAAK,KAAA;AAAA,YACL,yBAAuB,GAAA,CAAI,EAAA;AAAA,YAC3B,eAAA,EAAe,MAAA,CAAO,GAAA,CAAI,EAAA,KAAO,MAAM,CAAA;AAAA,YACvC,QAAA,EAAU,GAAA,CAAI,EAAA,KAAO,MAAA,GAAS,GAAA,GAAM,IAAA;AAAA,YAEnC,QAAA,EAAA;AAAA,cAAA,GAAA,CAAI,IAAA,wBACF,MAAA,EAAA,EAAK,KAAA,EAAM,8BAA6B,aAAA,EAAY,MAAA,EAClD,cAAI,IAAA,EACP,CAAA;AAAA,8BAEF,GAAA,CAAC,MAAA,EAAA,EAAK,KAAA,EAAM,6BAAA,EAA+B,cAAI,KAAA,EAAM;AAAA;AAAA;AAAA,SAExD,CAAA,EACH;AAAA;AAAA;AAAA,GACF;AAEJ","file":"tab-scaffold.js","sourcesContent":["import type { SafeHtml } from 'kerfjs';\n\nimport type { KerfUiContent } from './semantic-content.js';\n\nexport interface TabScaffoldTab<Id extends string = string> {\n id: Id;\n label: string;\n /** Decorative icon shown above the label in the bottom bar. */\n icon?: SafeHtml;\n /** The tab's content — typically a `NavStack` so each tab keeps its own stack. */\n content: KerfUiContent;\n}\n\nexport interface TabScaffoldProps<Id extends string = string> {\n id: string;\n /** Accessible name for the tab bar. */\n label: string;\n tabs: readonly TabScaffoldTab<Id>[];\n /** The controlled active tab id (the app owns selection). */\n active: NoInfer<Id>;\n className?: string;\n /** Native named-slot assignment when composed inside a web component. */\n slot?: string;\n}\n\n/**\n * A mobile-first, iOS-like bottom tab scaffold: a bottom tab bar that switches\n * between major sections, each tab keeping its own content (usually a `NavStack`)\n * mounted so its stack and scroll survive a switch. Controlled — the app owns\n * `active`; wire selection with `@kerfjs/ui/wire-tab-scaffold`'s `wireTabScaffold`.\n * On larger classes, promote the tabs to a `Workbench` rail or sidebar instead of\n * a bottom bar. See `docs/23-app-layouts.md` §3.4.\n */\nexport function TabScaffold<Id extends string>({\n id,\n label,\n tabs,\n active,\n className = '',\n slot,\n}: TabScaffoldProps<Id>) {\n return (\n <section\n class={`kui-tab-scaffold ${className}`.trim()}\n id={id}\n data-component=\"tab-scaffold\"\n data-tab-scaffold-id={id}\n slot={slot}\n >\n <div class=\"kui-tab-scaffold__scenes\">\n {tabs.map((tab) => (\n <div\n class=\"kui-tab-scaffold__scene\"\n data-tab-scaffold-scene={tab.id}\n data-active={String(tab.id === active)}\n aria-hidden={String(tab.id !== active)}\n >\n {tab.content}\n </div>\n ))}\n </div>\n <nav class=\"kui-tab-scaffold__bar\" role=\"tablist\" aria-label={label}>\n {tabs.map((tab) => (\n <button\n type=\"button\"\n class=\"kui-tab-scaffold__tab\"\n role=\"tab\"\n data-tab-scaffold-tab={tab.id}\n aria-selected={String(tab.id === active)}\n tabindex={tab.id === active ? '0' : '-1'}\n >\n {tab.icon && (\n <span class=\"kui-tab-scaffold__tab-icon\" aria-hidden=\"true\">\n {tab.icon}\n </span>\n )}\n <span class=\"kui-tab-scaffold__tab-label\">{tab.label}</span>\n </button>\n ))}\n </nav>\n </section>\n );\n}\n"]}
package/dist/text.d.ts CHANGED
@@ -2,13 +2,14 @@ import * as kerfjs from 'kerfjs';
2
2
  import { KerfBaseAttrs } from 'kerfjs/jsx-runtime';
3
3
  import { K as KerfUiContent } from './semantic-content-BbzjvSu9.js';
4
4
 
5
- type TextVariant = 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6' | 'p';
5
+ type TextVariant = 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6' | 'p' | 'span';
6
6
  type TextTone = 'default' | 'quiet' | 'danger';
7
7
  type TextSize = 'default' | 'compact';
8
8
  type TextFont = 'default' | 'monospace';
9
+ type TextBorder = 'transparent' | 'none';
9
10
  type TextContent = KerfUiContent | string | number | readonly TextContent[];
10
11
  type TextProps = Omit<KerfBaseAttrs, 'children' | 'class' | 'className'> & {
11
- /** Native heading or paragraph element to render. Defaults to `p`. */
12
+ /** Native heading, paragraph, or inline span element to render. Defaults to `p`. */
12
13
  variant?: TextVariant;
13
14
  /** Semantic foreground treatment. Defaults to the inherited foreground. */
14
15
  tone?: TextTone;
@@ -16,14 +17,17 @@ type TextProps = Omit<KerfBaseAttrs, 'children' | 'class' | 'className'> & {
16
17
  size?: TextSize;
17
18
  /** Font family independent of the native semantic element. */
18
19
  font?: TextFont;
20
+ /** Transparent alignment border or no border when embedded in owner chrome. */
21
+ border?: TextBorder;
19
22
  children: TextContent;
20
23
  class?: string;
21
24
  className?: string;
22
25
  };
23
26
  /**
24
- * Semantic heading or paragraph text with the standard content-item padding.
27
+ * Semantic heading, paragraph, or inline text. Block variants use the standard
28
+ * content-item padding; `span` adds no box geometry.
25
29
  * All ordinary native heading/paragraph attributes pass through to the element.
26
30
  */
27
- declare function Text({ variant: Variant, tone, size, font, children, class: classValue, className, ...attributes }: TextProps): kerfjs.SafeHtml;
31
+ declare function Text({ variant: Variant, tone, size, font, border, children, class: classValue, className, ...attributes }: TextProps): kerfjs.SafeHtml;
28
32
 
29
- export { Text, type TextContent, type TextFont, type TextProps, type TextSize, type TextTone, type TextVariant };
33
+ export { Text, type TextBorder, type TextContent, type TextFont, type TextProps, type TextSize, type TextTone, type TextVariant };
package/dist/text.js CHANGED
@@ -1,3 +1,3 @@
1
- export { Text } from './chunk-XKFRMGMW.js';
1
+ export { Text } from './chunk-7IUSV4XG.js';
2
2
 
3
3
  //# sourceMappingURL=text.js.map
@@ -26,12 +26,16 @@ interface TokenSearchFieldBaseProps {
26
26
  autofocus?: boolean;
27
27
  leading?: KerfUiContent;
28
28
  trailing?: KerfUiContent;
29
+ /** Standalone field chrome or the inset visual layer of a configured toolbar group. */
30
+ presentation?: 'standalone' | 'toolbar-group';
29
31
  editAction?: string;
30
32
  removeAction?: string;
31
33
  clearAction?: string;
32
34
  clearLabel?: string;
33
35
  className?: string;
34
36
  editorAttributes?: TokenSearchEditorAttributes;
37
+ /** Native named-slot assignment when composed inside a web component. */
38
+ slot?: string;
35
39
  }
36
40
  type TokenSearchCollapsibleProps = {
37
41
  /** Allow an empty field to render as one iconic action. */
@@ -51,7 +55,7 @@ interface TokenSearchFieldValue {
51
55
  query: string;
52
56
  tokens: TokenSearchToken[];
53
57
  }
54
- declare function TokenSearchField({ id, label, query, tokens, placeholder, tokenPlaceholder, disabled, autofocus, collapsible, expanded, expandAction, expandLabel, leading, trailing, editAction, removeAction, clearAction, clearLabel, className, editorAttributes, }: TokenSearchFieldProps): kerfjs.SafeHtml;
58
+ declare function TokenSearchField({ id, label, query, tokens, placeholder, tokenPlaceholder, disabled, autofocus, collapsible, expanded, expandAction, expandLabel, leading, trailing, presentation, editAction, removeAction, clearAction, clearLabel, className, editorAttributes, slot, }: TokenSearchFieldProps): kerfjs.SafeHtml;
55
59
  /** Read editable text and ordered token offsets from a rendered TokenSearchField editor. */
56
60
  declare function readTokenSearchField(editor: HTMLElement, knownTokens?: readonly TokenSearchToken[]): TokenSearchFieldValue;
57
61
  /** Focus an editor and place its caret at a text offset, skipping atomic token chips. */
@@ -1,4 +1,4 @@
1
- export { TokenSearchField, placeTokenSearchCaret, readTokenSearchField } from './chunk-TIGSG6BX.js';
1
+ export { TokenSearchField, placeTokenSearchCaret, readTokenSearchField } from './chunk-HJKRCKDR.js';
2
2
 
3
3
 
4
4
  //# sourceMappingURL=token-search-field.js.map
@@ -7,9 +7,29 @@ type ToolbarControlGroupButtonAppearance = 'plain' | 'push';
7
7
  type ToolbarControlGroupShape = 'pill' | 'rounded';
8
8
  type ToolbarControlGroupSize = 'default' | 'compact';
9
9
  type ToolbarControlGroupDensity = 'comfortable' | 'tight';
10
- type ToolbarControlGroupContent = 'icon' | 'text' | 'mixed' | 'avatar';
10
+ type ToolbarControlGroupContent = 'icon' | 'text' | 'mixed' | 'avatar' | 'search';
11
+ type ToolbarControlGroupFocusRing = 'control' | 'outline' | 'halo';
11
12
  type ToolbarControlGroupSelectedChrome = 'raised' | 'filled' | 'outline';
12
13
  type ToolbarControlGroupSelectedTone = 'brand' | 'neutral' | 'pop';
14
+ type ToolbarControlGroupOverflow = 'visible' | 'scroll';
15
+ type ToolbarControlGroupMenuInset = 'standard' | 'compact' | 'list-zero';
16
+ type ToolbarControlGroupVisibility = 'always' | 'compact-only';
17
+ interface ToolbarActionLinkProps {
18
+ href: string;
19
+ label: string;
20
+ icon?: KerfUiContent;
21
+ /** Optional machine-readable detail hidden visually but included in the default accessible name. */
22
+ detail?: string;
23
+ /** Override the accessible name when surrounding context is needed. */
24
+ ariaLabel?: string;
25
+ /** Open in a new tab with a safe rel and announce that behavior. */
26
+ external?: boolean;
27
+ className?: string;
28
+ /** Native named-slot assignment when composed inside a web component. */
29
+ slot?: string;
30
+ }
31
+ /** A semantic anchor with ToolbarControlGroup-owned action geometry. */
32
+ declare function ToolbarActionLink({ href, label, icon, detail, ariaLabel, external, className, slot, }: ToolbarActionLinkProps): kerfjs.SafeHtml;
13
33
  interface ToolbarControlGroupProps {
14
34
  children: KerfUiContent;
15
35
  label?: string;
@@ -24,10 +44,18 @@ interface ToolbarControlGroupProps {
24
44
  size?: ToolbarControlGroupSize;
25
45
  density?: ToolbarControlGroupDensity;
26
46
  content?: ToolbarControlGroupContent;
47
+ /** Whether controls paint focus individually or the group paints an outline/halo on focus-within. */
48
+ focusRing?: ToolbarControlGroupFocusRing;
27
49
  selectedChrome?: ToolbarControlGroupSelectedChrome;
28
50
  selectedTone?: ToolbarControlGroupSelectedTone;
29
51
  /** Size a nested Web Awesome dropdown trigger as part of this group. */
30
52
  nestedDropdown?: boolean;
53
+ /** Configure the nested dropdown menu inset without consumer ::part() CSS. */
54
+ menuInset?: ToolbarControlGroupMenuInset;
55
+ /** Keep an overlong row of actions inside the available width with horizontal scrolling. */
56
+ overflow?: ToolbarControlGroupOverflow;
57
+ /** Responsive visibility owned by the enclosing Toolbar container. */
58
+ visibility?: ToolbarControlGroupVisibility;
31
59
  /** Add contrast behind photo-backed avatar content. */
32
60
  scrim?: boolean;
33
61
  /**
@@ -35,7 +63,9 @@ interface ToolbarControlGroupProps {
35
63
  * multi-control group paints it only on the pressed selection highlight.
36
64
  */
37
65
  avatarImage?: string;
66
+ /** Native named-slot assignment when composed inside a web component. */
67
+ slot?: string;
38
68
  }
39
- declare function ToolbarControlGroup({ children, label, className, expanded, single, appearance, tone, buttonAppearance, shape, size, density, content, selectedChrome, selectedTone, nestedDropdown, scrim, avatarImage, }: ToolbarControlGroupProps): kerfjs.SafeHtml;
69
+ declare function ToolbarControlGroup({ children, label, className, expanded, single, appearance, tone, buttonAppearance, shape, size, density, content, focusRing, selectedChrome, selectedTone, nestedDropdown, menuInset, overflow, visibility, scrim, avatarImage, slot, }: ToolbarControlGroupProps): kerfjs.SafeHtml;
40
70
 
41
- export { ToolbarControlGroup, type ToolbarControlGroupAppearance, type ToolbarControlGroupButtonAppearance, type ToolbarControlGroupContent, type ToolbarControlGroupDensity, type ToolbarControlGroupProps, type ToolbarControlGroupSelectedChrome, type ToolbarControlGroupSelectedTone, type ToolbarControlGroupShape, type ToolbarControlGroupSize, type ToolbarControlGroupTone };
71
+ export { ToolbarActionLink, type ToolbarActionLinkProps, ToolbarControlGroup, type ToolbarControlGroupAppearance, type ToolbarControlGroupButtonAppearance, type ToolbarControlGroupContent, type ToolbarControlGroupDensity, type ToolbarControlGroupFocusRing, type ToolbarControlGroupMenuInset, type ToolbarControlGroupOverflow, type ToolbarControlGroupProps, type ToolbarControlGroupSelectedChrome, type ToolbarControlGroupSelectedTone, type ToolbarControlGroupShape, type ToolbarControlGroupSize, type ToolbarControlGroupTone, type ToolbarControlGroupVisibility };
@@ -1,3 +1,3 @@
1
- export { ToolbarControlGroup } from './chunk-B6JYRX3P.js';
1
+ export { ToolbarActionLink, ToolbarControlGroup } from './chunk-ZIYOJFZD.js';
2
2
 
3
3
  //# sourceMappingURL=toolbar-control-group.js.map
@@ -23,6 +23,8 @@ interface ToolbarTextBaseProps {
23
23
  * instead. Default true.
24
24
  */
25
25
  ellipsis?: boolean;
26
+ /** Native named-slot assignment when composed inside a web component. */
27
+ slot?: string;
26
28
  }
27
29
  type ToolbarTextWrappingProps = {
28
30
  /** Wrap onto multiple lines; combine with `maxLines` to cap them. */
@@ -33,6 +35,6 @@ type ToolbarTextWrappingProps = {
33
35
  maxLines?: never;
34
36
  };
35
37
  type ToolbarTextProps = ToolbarTextBaseProps & ToolbarTextWrappingProps;
36
- declare function ToolbarText({ text, size, className, id, headingLevel, placeholder, wrap, ellipsis, maxLines, }: ToolbarTextProps): kerfjs.SafeHtml;
38
+ declare function ToolbarText({ text, size, className, id, headingLevel, placeholder, wrap, ellipsis, maxLines, slot, }: ToolbarTextProps): kerfjs.SafeHtml;
37
39
 
38
40
  export { type HeadingLevel, ToolbarText, type ToolbarTextProps, type ToolbarTextSize };
@@ -1,4 +1,4 @@
1
- export { ToolbarText } from './chunk-V6GQKOX2.js';
1
+ export { ToolbarText } from './chunk-O3RCCSQJ.js';
2
2
 
3
3
 
4
4