@kerfjs/ui 5.0.0-beta.54 → 5.0.0-beta.56

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 (274) hide show
  1. package/README.md +14 -11
  2. package/ai/compile-time-contracts-v1.json +2 -2
  3. package/ai/component-catalog-v2.json +206 -39
  4. package/ai/component-catalog.json +306 -58
  5. package/ai/public-api-signatures-v1.md +671 -92
  6. package/ai/skill.md +43 -38
  7. package/ai/webawesome-jsx-signatures-v1.md +8 -2
  8. package/dist/app-tab.js +1 -1
  9. package/dist/badge.d.ts +35 -7
  10. package/dist/badge.js +1 -1
  11. package/dist/browser/content-item.js +3 -0
  12. package/dist/browser/popup-menu.js +3 -0
  13. package/dist/browser/select.js +1 -0
  14. package/dist/catalog-resources.d.ts +12 -1
  15. package/dist/catalog.d.ts +21 -4
  16. package/dist/catalog.js +260 -308
  17. package/dist/catalog.js.map +1 -1
  18. package/dist/{chunk-7IUSV4XG.js → chunk-24PHKUR3.js} +2 -2
  19. package/dist/chunk-24PHKUR3.js.map +1 -0
  20. package/dist/{chunk-WZ2GLEY4.js → chunk-2G2ZJQYK.js} +2 -14
  21. package/dist/chunk-2G2ZJQYK.js.map +1 -0
  22. package/dist/{chunk-D7GWXIAS.js → chunk-5I7QGQVT.js} +1 -1
  23. package/dist/chunk-5I7QGQVT.js.map +1 -0
  24. package/dist/{chunk-HJKRCKDR.js → chunk-63ZWBGE3.js} +6 -3
  25. package/dist/chunk-63ZWBGE3.js.map +1 -0
  26. package/dist/{chunk-44IG7PFV.js → chunk-6CINWX2E.js} +3 -3
  27. package/dist/{chunk-44IG7PFV.js.map → chunk-6CINWX2E.js.map} +1 -1
  28. package/dist/{chunk-C2FAYFDE.js → chunk-AGXQQFKZ.js} +2 -2
  29. package/dist/{chunk-C2FAYFDE.js.map → chunk-AGXQQFKZ.js.map} +1 -1
  30. package/dist/{chunk-ATHXW6RP.js → chunk-AHEG27M7.js} +2 -2
  31. package/dist/{chunk-ATHXW6RP.js.map → chunk-AHEG27M7.js.map} +1 -1
  32. package/dist/{chunk-7GUQYHKA.js → chunk-AK67F6QN.js} +4 -1
  33. package/dist/chunk-AK67F6QN.js.map +1 -0
  34. package/dist/chunk-BFPBS5Y4.js +250 -0
  35. package/dist/chunk-BFPBS5Y4.js.map +1 -0
  36. package/dist/chunk-DG6G5EPF.js +35 -0
  37. package/dist/chunk-DG6G5EPF.js.map +1 -0
  38. package/dist/{chunk-MTM43SJO.js → chunk-G33XC2NB.js} +1 -1
  39. package/dist/chunk-G33XC2NB.js.map +1 -0
  40. package/dist/{chunk-TZ5IHWB2.js → chunk-K6UNVKDK.js} +3 -3
  41. package/dist/{chunk-TZ5IHWB2.js.map → chunk-K6UNVKDK.js.map} +1 -1
  42. package/dist/chunk-KH6VUGHU.js +399 -0
  43. package/dist/chunk-KH6VUGHU.js.map +1 -0
  44. package/dist/{chunk-HMQ2ZDGG.js → chunk-KROD7KZK.js} +3 -2
  45. package/dist/chunk-KROD7KZK.js.map +1 -0
  46. package/dist/{chunk-5NDQABWK.js → chunk-M7QV3IHH.js} +3 -1
  47. package/dist/chunk-M7QV3IHH.js.map +1 -0
  48. package/dist/{chunk-RNZAKSME.js → chunk-MA6Z6EIM.js} +3 -3
  49. package/dist/{chunk-RNZAKSME.js.map → chunk-MA6Z6EIM.js.map} +1 -1
  50. package/dist/chunk-MA73TA6D.js +42 -0
  51. package/dist/chunk-MA73TA6D.js.map +1 -0
  52. package/dist/{chunk-ZMBU522F.js → chunk-MEY33VWB.js} +2 -2
  53. package/dist/{chunk-ZMBU522F.js.map → chunk-MEY33VWB.js.map} +1 -1
  54. package/dist/{chunk-T22EM4ET.js → chunk-MOBRFZH3.js} +81 -31
  55. package/dist/chunk-MOBRFZH3.js.map +1 -0
  56. package/dist/chunk-MP2GDBQZ.js +50 -0
  57. package/dist/chunk-MP2GDBQZ.js.map +1 -0
  58. package/dist/{chunk-3NBL3OUQ.js → chunk-NAPE7WUS.js} +2 -2
  59. package/dist/chunk-NAPE7WUS.js.map +1 -0
  60. package/dist/{chunk-CMUIXJZM.js → chunk-NBYTIVHS.js} +2 -2
  61. package/dist/{chunk-CMUIXJZM.js.map → chunk-NBYTIVHS.js.map} +1 -1
  62. package/dist/chunk-O3EXIBEZ.js +114 -0
  63. package/dist/chunk-O3EXIBEZ.js.map +1 -0
  64. package/dist/{chunk-KPNTVB7A.js → chunk-PK4N5QTO.js} +8 -7
  65. package/dist/chunk-PK4N5QTO.js.map +1 -0
  66. package/dist/chunk-QQOTQTDD.js +415 -0
  67. package/dist/chunk-QQOTQTDD.js.map +1 -0
  68. package/dist/{chunk-BJJKFVWW.js → chunk-T4UZTNZ4.js} +5 -5
  69. package/dist/chunk-T4UZTNZ4.js.map +1 -0
  70. package/dist/chunk-V65EOWNF.js +83 -0
  71. package/dist/chunk-V65EOWNF.js.map +1 -0
  72. package/dist/{chunk-GUIHMIT2.js → chunk-VNPQDCQZ.js} +3 -3
  73. package/dist/{chunk-GUIHMIT2.js.map → chunk-VNPQDCQZ.js.map} +1 -1
  74. package/dist/{chunk-5I22LMCV.js → chunk-VZOFZPSO.js} +2 -2
  75. package/dist/chunk-VZOFZPSO.js.map +1 -0
  76. package/dist/chunk-WLG6SSNT.js +94 -0
  77. package/dist/chunk-WLG6SSNT.js.map +1 -0
  78. package/dist/{chunk-NE5JAOQS.js → chunk-WOUF7YXM.js} +3 -3
  79. package/dist/{chunk-NE5JAOQS.js.map → chunk-WOUF7YXM.js.map} +1 -1
  80. package/dist/collapsible-panel.d.ts +51 -13
  81. package/dist/collapsible-panel.js +38 -10
  82. package/dist/collapsible-panel.js.map +1 -1
  83. package/dist/content-item.d.ts +46 -0
  84. package/dist/content-item.js +4 -0
  85. package/dist/content-item.js.map +1 -0
  86. package/dist/css-values.d.ts +5 -11
  87. package/dist/css-values.js +1 -1
  88. package/dist/disclosure-arrow.d.ts +4 -1
  89. package/dist/disclosure-arrow.js +1 -1
  90. package/dist/floating-toolbar.d.ts +17 -6
  91. package/dist/floating-toolbar.js +1 -1
  92. package/dist/grid.js +1 -1
  93. package/dist/help-tags-register.d.ts +13 -0
  94. package/dist/help-tags-register.js +9 -0
  95. package/dist/help-tags-register.js.map +1 -0
  96. package/dist/index.d.ts +7 -5
  97. package/dist/index.js +31 -29
  98. package/dist/list-action-row.js +1 -1
  99. package/dist/list-header.d.ts +14 -1
  100. package/dist/list-header.js +1 -1
  101. package/dist/list-inset-control.d.ts +1 -1
  102. package/dist/list-inset-control.js +1 -1
  103. package/dist/list-inset-text.d.ts +9 -10
  104. package/dist/list-inset-text.js +2 -1
  105. package/dist/list-item.js +1 -1
  106. package/dist/list.d.ts +10 -3
  107. package/dist/list.js +1 -1
  108. package/dist/nav-stack.d.ts +38 -5
  109. package/dist/nav-stack.js +4 -1
  110. package/dist/pane.d.ts +20 -2
  111. package/dist/pane.js +1 -1
  112. package/dist/panel-toolbar-C8sF-YZC.d.ts +63 -0
  113. package/dist/popup-menu-register.d.ts +9 -0
  114. package/dist/popup-menu-register.js +31 -0
  115. package/dist/popup-menu-register.js.map +1 -0
  116. package/dist/popup-menu.d.ts +71 -0
  117. package/dist/popup-menu.js +3 -0
  118. package/dist/popup-menu.js.map +1 -0
  119. package/dist/row.d.ts +1 -1
  120. package/dist/row.js +1 -1
  121. package/dist/select-register.js +70 -3
  122. package/dist/select-register.js.map +1 -1
  123. package/dist/select.d.ts +46 -8
  124. package/dist/select.js +2 -1
  125. package/dist/{divider-sides-BzB6rphT.d.ts → sides-BPSWde0A.d.ts} +1 -3
  126. package/dist/skeleton.js +1 -1
  127. package/dist/spacer.js +1 -1
  128. package/dist/split-view.d.ts +31 -3
  129. package/dist/split-view.js +33 -5
  130. package/dist/split-view.js.map +1 -1
  131. package/dist/state-banner.js +1 -1
  132. package/dist/styles/badge.css +13 -0
  133. package/dist/styles/catalog/components/catalog-example.css +1 -17
  134. package/dist/styles/catalog/components/catalog-stage.css +9 -14
  135. package/dist/styles/catalog/components/catalog.css +8 -18
  136. package/dist/styles/catalog.css +0 -5
  137. package/dist/styles/collapsible-panel.css +192 -39
  138. package/dist/styles/content-item.css +30 -0
  139. package/dist/styles/floating-toolbar.css +5 -0
  140. package/dist/styles/foundation.css +28 -19
  141. package/dist/styles/layout.css +1 -21
  142. package/dist/styles/list-action-row.css +13 -1
  143. package/dist/styles/list-inset-text.css +1 -2
  144. package/dist/styles/list-item.css +14 -1
  145. package/dist/styles/list.css +1 -1
  146. package/dist/styles/nav-stack.css +29 -64
  147. package/dist/styles/pane.css +33 -1
  148. package/dist/styles/popup-menu.css +90 -0
  149. package/dist/styles/resizable-region.css +53 -10
  150. package/dist/styles/select.css +39 -12
  151. package/dist/styles/split-view.css +21 -25
  152. package/dist/styles/state-banner.css +13 -4
  153. package/dist/styles/styles.css +1 -0
  154. package/dist/styles/tab-bar.css +31 -3
  155. package/dist/styles/tab-scaffold.css +36 -14
  156. package/dist/styles/text.css +1 -1
  157. package/dist/styles/token-search-field.css +4 -4
  158. package/dist/styles/toolbar-control-group.css +44 -12
  159. package/dist/styles/toolbar.css +57 -7
  160. package/dist/styles/value-table.css +19 -2
  161. package/dist/styles/webawesome.css +3 -1
  162. package/dist/styles/workbench.css +165 -31
  163. package/dist/tab-scaffold.d.ts +35 -1
  164. package/dist/tab-scaffold.js +50 -16
  165. package/dist/tab-scaffold.js.map +1 -1
  166. package/dist/text.js +1 -1
  167. package/dist/token-search-field.d.ts +13 -2
  168. package/dist/token-search-field.js +1 -1
  169. package/dist/toolbar-text.js +1 -1
  170. package/dist/toolbar.d.ts +12 -4
  171. package/dist/toolbar.js +1 -1
  172. package/dist/{types-CEsieBZi.d.ts → types-DXAGogOS.d.ts} +48 -0
  173. package/dist/value-table.js +1 -1
  174. package/dist/webawesome.d.ts +7 -1
  175. package/dist/wire-catalog.d.ts +24 -1
  176. package/dist/wire-catalog.js +26 -3
  177. package/dist/wire-catalog.js.map +1 -1
  178. package/dist/wire-sidebar.js +6 -3
  179. package/dist/wire-sidebar.js.map +1 -1
  180. package/dist/wire-token-search-fields.js +1 -1
  181. package/dist/wire-workbench.js +1 -350
  182. package/dist/wire-workbench.js.map +1 -1
  183. package/dist/workbench.d.ts +144 -6
  184. package/dist/workbench.js +11 -208
  185. package/dist/workbench.js.map +1 -1
  186. package/docs/accessibility.md +126 -6
  187. package/docs/app-layouts.md +9 -7
  188. package/docs/catalog.md +41 -9
  189. package/docs/collapsible-panel.md +79 -5
  190. package/docs/component-contract.md +38 -12
  191. package/docs/component-selection.md +64 -55
  192. package/docs/design/templates/empty-state/with-action-dark.svg +1 -1
  193. package/docs/design/templates/empty-state/with-action.svg +1 -1
  194. package/docs/design/templates/empty-state-dark.svg +1 -1
  195. package/docs/design/templates/empty-state.svg +1 -1
  196. package/docs/design/templates/list/compact-dark.svg +1 -1
  197. package/docs/design/templates/list/compact.svg +1 -1
  198. package/docs/design/templates/list/stack-dark.svg +1 -1
  199. package/docs/design/templates/list/stack.svg +1 -1
  200. package/docs/design/templates/list-action-row/default-dark.svg +1 -1
  201. package/docs/design/templates/list-action-row/default.svg +1 -1
  202. package/docs/design/templates/list-action-row/selected-dark.svg +1 -1
  203. package/docs/design/templates/list-action-row/selected.svg +1 -1
  204. package/docs/design/templates/list-action-row-dark.svg +1 -1
  205. package/docs/design/templates/list-action-row.svg +1 -1
  206. package/docs/design/templates/list-dark.svg +1 -1
  207. package/docs/design/templates/list-item/default-dark.svg +1 -1
  208. package/docs/design/templates/list-item/default.svg +1 -1
  209. package/docs/design/templates/list-item/selected-dark.svg +1 -1
  210. package/docs/design/templates/list-item/selected.svg +1 -1
  211. package/docs/design/templates/list-item/trailing-dark.svg +1 -1
  212. package/docs/design/templates/list-item/trailing.svg +1 -1
  213. package/docs/design/templates/list-item-dark.svg +1 -1
  214. package/docs/design/templates/list-item.svg +1 -1
  215. package/docs/design/templates/list.svg +1 -1
  216. package/docs/design/templates/state-banner/danger-dark.svg +1 -1
  217. package/docs/design/templates/state-banner/danger.svg +1 -1
  218. package/docs/design/templates/state-banner/info-dark.svg +1 -1
  219. package/docs/design/templates/state-banner/info.svg +1 -1
  220. package/docs/design/templates/state-banner/success-dark.svg +1 -1
  221. package/docs/design/templates/state-banner/success.svg +1 -1
  222. package/docs/design/templates/state-banner/warning-dark.svg +1 -1
  223. package/docs/design/templates/state-banner/warning.svg +1 -1
  224. package/docs/design/templates/state-banner-dark.svg +1 -1
  225. package/docs/design/templates/state-banner.svg +1 -1
  226. package/docs/design/templates/value-table/details-dark.svg +1 -1
  227. package/docs/design/templates/value-table/details.svg +1 -1
  228. package/docs/design/templates/value-table-dark.svg +1 -1
  229. package/docs/design/templates/value-table.svg +1 -1
  230. package/docs/design-philosophy.md +1 -1
  231. package/docs/examples/command-palette-adapter.tsx +3 -2
  232. package/docs/layout.md +74 -29
  233. package/docs/nav-stack.md +45 -1
  234. package/docs/recipes.md +48 -40
  235. package/docs/split-view.md +46 -2
  236. package/docs/surface-scaffold.md +1 -1
  237. package/docs/tab-scaffold.md +50 -1
  238. package/docs/type-contracts.md +17 -17
  239. package/docs/ux-demo.md +8 -4
  240. package/docs/webawesome-theme.md +1 -2
  241. package/docs/workbench.md +131 -10
  242. package/llms.txt +38 -9
  243. package/package.json +24 -2
  244. package/ux-demo/recipes/app-shell.tsx +141 -223
  245. package/ux-demo/recipes/collapsible-sidebar.tsx +47 -77
  246. package/ux-demo/recipes/list-detail-dialog.tsx +150 -54
  247. package/ux-demo/recipes/mount-recipe.ts +0 -5
  248. package/ux-demo/recipes/navigation-sidebar.tsx +3 -2
  249. package/ux-demo/recipes/navigation-stack.tsx +3 -2
  250. package/ux-demo/recipes/types.ts +0 -1
  251. package/dist/chunk-3NBL3OUQ.js.map +0 -1
  252. package/dist/chunk-5I22LMCV.js.map +0 -1
  253. package/dist/chunk-5NDQABWK.js.map +0 -1
  254. package/dist/chunk-7GUQYHKA.js.map +0 -1
  255. package/dist/chunk-7IUSV4XG.js.map +0 -1
  256. package/dist/chunk-BJJKFVWW.js.map +0 -1
  257. package/dist/chunk-D7GWXIAS.js.map +0 -1
  258. package/dist/chunk-DQA5FMOX.js +0 -85
  259. package/dist/chunk-DQA5FMOX.js.map +0 -1
  260. package/dist/chunk-HJKRCKDR.js.map +0 -1
  261. package/dist/chunk-HMQ2ZDGG.js.map +0 -1
  262. package/dist/chunk-KPNTVB7A.js.map +0 -1
  263. package/dist/chunk-MTM43SJO.js.map +0 -1
  264. package/dist/chunk-T22EM4ET.js.map +0 -1
  265. package/dist/chunk-WZ2GLEY4.js.map +0 -1
  266. package/dist/chunk-XD7DWYXG.js +0 -34
  267. package/dist/chunk-XD7DWYXG.js.map +0 -1
  268. package/dist/chunk-ZK5EGVFP.js +0 -27
  269. package/dist/chunk-ZK5EGVFP.js.map +0 -1
  270. package/dist/styles/catalog/components/catalog-detail.css +0 -35
  271. package/dist/styles/catalog/components/catalog-resource-footer.css +0 -37
  272. package/dist/styles/catalog/components/catalog-secondary-sections.css +0 -38
  273. package/dist/styles/catalog/components/catalog-section-list.css +0 -22
  274. package/dist/styles/catalog/components/catalog-sidebar.css +0 -82
@@ -1,13 +1,18 @@
1
+ /* The preview stage fills the work area's scroller — and grows with a taller
2
+ specimen, never shrinking under it — behind a transparency checkerboard,
3
+ so a specimen's own surface (or lack of one) stays visible. */
1
4
  .kui-catalog__stage {
2
- width: 100%;
3
- min-height: 0;
4
5
  flex: 1 0 auto;
6
+ background-color: var(--kui-color-surface-lowered);
7
+ background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath fill='%238e8e93' fill-opacity='.12' d='M0 0h12v12H0zM12 12h12v12H12z'/%3E%3C/svg%3E");
8
+ background-size: 1.5rem 1.5rem;
5
9
  }
6
10
 
11
+ /* The centered specimen canvas, at the catalog's reading measure. */
7
12
  .kui-catalog__canvas {
8
13
  position: relative;
9
14
  display: grid;
10
- width: min(100%, var(--kui-catalog-content-measure, 70rem));
15
+ width: min(100%, 70rem);
11
16
  min-width: 0;
12
17
  min-height: 100%;
13
18
  margin-inline: auto;
@@ -42,19 +47,9 @@
42
47
 
43
48
  .kui-catalog__geometry-border {
44
49
  border: 0 solid
45
- color-mix(in srgb, var(--kui-color-accent-text) 72%, transparent);
50
+ color-mix(in srgb, var(--kui-color-brand-on-quiet) 72%, transparent);
46
51
  }
47
52
 
48
53
  .kui-catalog__geometry-margin {
49
54
  background: color-mix(in srgb, #f6a94c 55%, transparent);
50
55
  }
51
-
52
- @media (max-width: 52rem) {
53
- .kui-catalog__stage {
54
- min-height: 24rem;
55
- }
56
-
57
- .kui-catalog__canvas {
58
- min-height: 16rem;
59
- }
60
- }
@@ -1,22 +1,12 @@
1
+ /* The catalog fills its container, which must have a definite height (the
2
+ `document.css` baseline's `.kui-app-root`, as for any Workbench). */
1
3
  .kui-catalog {
2
- --kui-catalog-sidebar-width: 18rem;
3
- --kui-catalog-content-measure: 70rem;
4
-
5
- display: grid;
6
- height: 100vh;
7
- grid-template-columns: var(--kui-catalog-sidebar-width) minmax(0, 1fr);
8
- overflow: hidden;
9
- }
10
-
11
- .kui-catalog[data-sidebar-collapsed="true"] {
12
- grid-template-columns: 0 minmax(0, 1fr);
4
+ height: 100%;
13
5
  }
14
6
 
15
- @media (max-width: 52rem) {
16
- .kui-catalog,
17
- .kui-catalog[data-sidebar-collapsed="true"] {
18
- height: auto;
19
- min-height: 100vh;
20
- grid-template-columns: 1fr;
21
- }
7
+ /* The brand mark, sized to sit inside a toolbar group. */
8
+ .kui-catalog__mark {
9
+ display: block;
10
+ width: 2.125rem;
11
+ height: 2.125rem;
22
12
  }
@@ -1,10 +1,5 @@
1
1
  /* Public compatibility entrypoint. Each catalog component owns its styles. */
2
2
  @import "./catalog/components/catalog.css";
3
- @import "./catalog/components/catalog-sidebar.css";
4
- @import "./catalog/components/catalog-section-list.css";
5
- @import "./catalog/components/catalog-secondary-sections.css";
6
- @import "./catalog/components/catalog-detail.css";
7
3
  @import "./catalog/components/catalog-stage.css";
8
- @import "./catalog/components/catalog-resource-footer.css";
9
4
  @import "./catalog/components/catalog-example.css";
10
5
  @import "./catalog/components/catalog-example-stack.css";
@@ -47,7 +47,7 @@
47
47
  var(--kui-collapsible-panel-width, 17.5rem) +
48
48
  var(--_kui-collapsible-panel-safe-inline-start)
49
49
  );
50
- border-inline-end: 1px solid var(--kui-color-border);
50
+ border-inline-end: 1px solid var(--kui-color-neutral-border-normal);
51
51
  }
52
52
 
53
53
  .kui-collapsible-panel--right {
@@ -55,7 +55,7 @@
55
55
  var(--kui-collapsible-panel-width, 17.5rem) +
56
56
  var(--_kui-collapsible-panel-safe-inline-end)
57
57
  );
58
- border-inline-start: 1px solid var(--kui-color-border);
58
+ border-inline-start: 1px solid var(--kui-color-neutral-border-normal);
59
59
  }
60
60
 
61
61
  .kui-collapsible-panel--bottom {
@@ -67,7 +67,7 @@
67
67
  width: 100%;
68
68
  height: var(--_kui-collapsible-panel-extent);
69
69
  min-height: 0;
70
- border-block-start: 1px solid var(--kui-color-border);
70
+ border-block-start: 1px solid var(--kui-color-neutral-border-normal);
71
71
  }
72
72
 
73
73
  /* The panel's content sees the edges it touches; its interior edge is clear. */
@@ -111,18 +111,16 @@
111
111
  var(--kui-edge-inset-inline-end);
112
112
  }
113
113
 
114
- .kui-collapsible-panel__content:not(
115
- :has(
116
- > :is(
117
- [data-component="pane"],
118
- [data-component="nav-stack"],
119
- [data-component="split-view"],
120
- [data-component="workbench"],
121
- [data-component="tab-scaffold"]
122
- ):only-child
123
- )
124
- )
125
- > * {
114
+ .kui-collapsible-panel__content
115
+ > :not(
116
+ :is(
117
+ [data-component="pane"],
118
+ [data-component="nav-stack"],
119
+ [data-component="split-view"],
120
+ [data-component="workbench"],
121
+ [data-component="tab-scaffold"]
122
+ ):only-child
123
+ ) {
126
124
  --kui-edge-inset-block-start: 0px;
127
125
  --kui-edge-inset-block-end: 0px;
128
126
  --kui-edge-inset-inline-start: 0px;
@@ -130,34 +128,132 @@
130
128
  }
131
129
 
132
130
  /* An expanded inline panel is the region at its edge, so its direct siblings
133
- no longer reach that edge. */
134
- .kui-collapsible-panel--left[data-presentation="inline"]:not(
135
- [data-collapsed="true"],
136
- [data-collapsible-overlay="true"] *,
137
- [data-collapsible-responsive="hidden"] *
131
+ no longer reach that edge. The container flags the edge it has handed to a
132
+ panel in a non-inheriting property, and a style query zeroes that edge on
133
+ the container's children only; the panel that owns the edge (the first
134
+ left, the last right or bottom) inherits the container's value back.
135
+ Selecting the siblings themselves (`:has(~ panel)`, `panel ~ *`) makes
136
+ every element a sibling-rule candidate, so in Chromium each insertion into
137
+ a long list restyles the list's other rows. The flag is set by a keyed
138
+ `:has(> panel)` on the container and read by a parent style lookup, so a
139
+ list without a panel in it pays nothing. */
140
+ @property --_kui-collapsible-panel-owns-inline-start {
141
+ syntax: "*";
142
+ inherits: false;
143
+ }
144
+
145
+ @property --_kui-collapsible-panel-owns-inline-end {
146
+ syntax: "*";
147
+ inherits: false;
148
+ }
149
+
150
+ @property --_kui-collapsible-panel-owns-block-end {
151
+ syntax: "*";
152
+ inherits: false;
153
+ }
154
+
155
+ :where(
156
+ :has(
157
+ > .kui-collapsible-panel--left[data-presentation="inline"]:not(
158
+ [data-collapsed="true"],
159
+ [data-collapsible-overlay="true"] *,
160
+ [data-collapsible-responsive="hidden"] *
161
+ )
138
162
  )
139
- ~ * {
140
- --kui-edge-inset-inline-start: 0px;
163
+ ) {
164
+ --_kui-collapsible-panel-owns-inline-start: true;
141
165
  }
142
166
 
143
- :has(
144
- ~ .kui-collapsible-panel--right[data-presentation="inline"]:not(
167
+ :where(
168
+ :has(
169
+ > .kui-collapsible-panel--right[data-presentation="inline"]:not(
170
+ [data-collapsed="true"],
171
+ [data-collapsible-overlay="true"] *,
172
+ [data-collapsible-responsive="hidden"] *
173
+ )
174
+ )
175
+ ) {
176
+ --_kui-collapsible-panel-owns-inline-end: true;
177
+ }
178
+
179
+ :where(
180
+ :has(
181
+ > .kui-collapsible-panel--bottom[data-presentation="inline"]:not(
182
+ [data-collapsed="true"],
183
+ [data-collapsible-overlay="true"] *,
184
+ [data-collapsible-responsive="hidden"] *
185
+ )
186
+ )
187
+ ) {
188
+ --_kui-collapsible-panel-owns-block-end: true;
189
+ }
190
+
191
+ @container style(--_kui-collapsible-panel-owns-inline-start: true) {
192
+ :where(*) {
193
+ --kui-edge-inset-inline-start: 0px;
194
+ }
195
+ }
196
+
197
+ @container style(--_kui-collapsible-panel-owns-inline-end: true) {
198
+ :where(*) {
199
+ --kui-edge-inset-inline-end: 0px;
200
+ }
201
+ }
202
+
203
+ @container style(--_kui-collapsible-panel-owns-block-end: true) {
204
+ :where(*) {
205
+ --kui-edge-inset-block-end: 0px;
206
+ }
207
+ }
208
+
209
+ :where(
210
+ .kui-collapsible-panel--left[data-presentation="inline"]:not(
145
211
  [data-collapsed="true"],
146
212
  [data-collapsible-overlay="true"] *,
147
- [data-collapsible-responsive="hidden"] *
213
+ [data-collapsible-responsive="hidden"] *,
214
+ .kui-collapsible-panel--left[data-presentation="inline"]:not(
215
+ [data-collapsed="true"],
216
+ [data-collapsible-overlay="true"] *,
217
+ [data-collapsible-responsive="hidden"] *
218
+ )
219
+ ~ *
148
220
  )
149
221
  ) {
150
- --kui-edge-inset-inline-end: 0px;
222
+ --kui-edge-inset-inline-start: inherit;
151
223
  }
152
224
 
153
- :has(
154
- ~ .kui-collapsible-panel--bottom[data-presentation="inline"]:not(
225
+ :where(
226
+ .kui-collapsible-panel--right[data-presentation="inline"]:not(
155
227
  [data-collapsed="true"],
156
228
  [data-collapsible-overlay="true"] *,
157
- [data-collapsible-responsive="hidden"] *
229
+ [data-collapsible-responsive="hidden"] *,
230
+ :has(
231
+ ~ .kui-collapsible-panel--right[data-presentation="inline"]:not(
232
+ [data-collapsed="true"],
233
+ [data-collapsible-overlay="true"] *,
234
+ [data-collapsible-responsive="hidden"] *
235
+ )
236
+ )
158
237
  )
159
238
  ) {
160
- --kui-edge-inset-block-end: 0px;
239
+ --kui-edge-inset-inline-end: inherit;
240
+ }
241
+
242
+ :where(
243
+ .kui-collapsible-panel--bottom[data-presentation="inline"]:not(
244
+ [data-collapsed="true"],
245
+ [data-collapsible-overlay="true"] *,
246
+ [data-collapsible-responsive="hidden"] *,
247
+ :has(
248
+ ~ .kui-collapsible-panel--bottom[data-presentation="inline"]:not(
249
+ [data-collapsed="true"],
250
+ [data-collapsible-overlay="true"] *,
251
+ [data-collapsible-responsive="hidden"] *
252
+ )
253
+ )
254
+ )
255
+ ) {
256
+ --kui-edge-inset-block-end: inherit;
161
257
  }
162
258
 
163
259
  .kui-collapsible-panel[data-collapsed="true"] {
@@ -292,10 +388,19 @@
292
388
  that container or of one of its direct children (the app's work-area
293
389
  column) — owns the container's bottom, so the corner floats above the
294
390
  drawer's top edge instead of over it. The drawer publishes that edge as an
295
- anchor; a drawer nested deeper, inside the work area's own content, belongs
296
- to another layout and is scoped out. Without anchor positioning the corner
297
- keeps the container's bottom edge. */
298
- .kui-collapsible-panel--bottom[data-presentation="inline"]:not(
391
+ anchor only there, beside a CollapsiblePanel or ResizableRegion restore
392
+ control (matched by their restore attributes); a drawer nested deeper,
393
+ inside the work area's own content, belongs to another layout and
394
+ publishes nothing. The selector ends on the drawer, not on a universal
395
+ `> * > * > *` scope below the container: a universal selector after a
396
+ :has() container restyles every child of every ancestor of a DOM change in
397
+ Chromium. Without anchor positioning the corner keeps the container's
398
+ bottom edge. */
399
+ :where(
400
+ :has(> [data-panel-restore], > [data-region-restore]),
401
+ :has(> [data-panel-restore], > [data-region-restore]) > *
402
+ )
403
+ > .kui-collapsible-panel--bottom[data-presentation="inline"]:not(
299
404
  [data-collapsed="true"],
300
405
  [data-collapsible-overlay="true"] *,
301
406
  [data-collapsible-responsive="hidden"] *
@@ -303,10 +408,6 @@
303
408
  anchor-name: --kui-restore-drawer;
304
409
  }
305
410
 
306
- :where(:has(> .kui-collapsible-panel__restore)) > * > * > * {
307
- anchor-scope: --kui-restore-drawer;
308
- }
309
-
310
411
  .kui-collapsible-panel__restore {
311
412
  --_kui-collapsible-panel-restore-inset: var(
312
413
  --kui-collapsible-panel-restore-inset,
@@ -316,6 +417,8 @@
316
417
  from this point instead of adding its own inset on top. */
317
418
  --kui-floating-toolbar-inset: 0px;
318
419
  position: absolute;
420
+ /* Hidden while an open side overlay covers the content (see below). */
421
+ visibility: var(--_kui-floating-covered, inherit);
319
422
  z-index: var(
320
423
  --kui-collapsible-panel-restore-z,
321
424
  calc(var(--kui-collapsible-panel-overlay-z, 40) - 2)
@@ -361,6 +464,56 @@
361
464
  );
362
465
  }
363
466
 
467
+ /* An open side overlay — the wireSidebar compact overlay or a static
468
+ `presentation="overlay"` panel — covers the content beside it, so that
469
+ content's floating controls (a FloatingToolbar, another panel's restore
470
+ corner) are hidden, not merely stacked beneath it: they never paint over
471
+ the overlay whatever stacking context an app puts them in, and hidden they
472
+ leave the tab order and the accessibility tree. They come back as the
473
+ overlay closes. The flag is read by FloatingToolbar and the
474
+ layouts' restore corners; the overlay panels themselves are exempt, so
475
+ their own floating controls stay. */
476
+ [data-collapsible-overlay="true"]:has(
477
+ .kui-collapsible-panel:is(
478
+ .kui-collapsible-panel--left,
479
+ .kui-collapsible-panel--right
480
+ ):not([data-collapsed="true"])
481
+ ) {
482
+ --_kui-floating-covered: hidden;
483
+ }
484
+
485
+ [data-collapsible-overlay="true"] .kui-collapsible-panel {
486
+ --_kui-floating-covered: initial;
487
+ }
488
+
489
+ /* A static overlay panel sets the flag on its container and clears it again
490
+ on the overlay panels in it, so it reaches the overlay's siblings only —
491
+ never through a universal selector below the :has() container
492
+ (`:has(…) > :not(…)`), which in Chromium restyles every child of every
493
+ ancestor of a DOM change. */
494
+ :where(
495
+ :has(
496
+ > .kui-collapsible-panel:is(
497
+ .kui-collapsible-panel--left,
498
+ .kui-collapsible-panel--right
499
+ )[data-presentation="overlay"]:not([data-collapsed="true"])
500
+ )
501
+ ) {
502
+ --_kui-floating-covered: hidden;
503
+ }
504
+
505
+ :where(
506
+ :has(
507
+ > .kui-collapsible-panel:is(
508
+ .kui-collapsible-panel--left,
509
+ .kui-collapsible-panel--right
510
+ )[data-presentation="overlay"]:not([data-collapsed="true"])
511
+ )
512
+ )
513
+ > .kui-collapsible-panel[data-presentation="overlay"] {
514
+ --_kui-floating-covered: initial;
515
+ }
516
+
364
517
  /* A button does not stretch between its insets the way a div does, so the
365
518
  backdrop sizes itself to its containing block explicitly. It sits one below
366
519
  the overlay z-index, so an app that moves the overlay moves the backdrop
@@ -396,7 +549,7 @@
396
549
  }
397
550
 
398
551
  .kui-collapsible-panel__toggle:hover {
399
- border-color: var(--kui-color-border);
552
+ border-color: var(--kui-color-neutral-border-normal);
400
553
  background: var(--kui-color-neutral-fill-normal);
401
554
  }
402
555
 
@@ -0,0 +1,30 @@
1
+ /* One self-contained content-item: 8px inline margin, a real 1px border
2
+ (transparent unless framed), 8px padding, and a rounded or pill radius.
3
+ Rendered by ContentItem; the classes stay public for other elements. */
4
+
5
+ .kui-content-item {
6
+ min-width: 0;
7
+ margin-inline: var(--kui-layout-inline-margin, 0.5rem);
8
+ padding: var(--kui-layout-item-padding, 0.5rem);
9
+ box-sizing: border-box;
10
+ border: var(--kui-layout-item-border-width, 1px) solid
11
+ var(--kui-content-item-border, transparent);
12
+ border-radius: var(
13
+ --kui-content-item-radius,
14
+ var(--kui-layout-rounded-radius, calc(1px + 0.6875rem))
15
+ );
16
+ background: var(--kui-content-item-background, transparent);
17
+ }
18
+
19
+ .kui-content-item--pill {
20
+ --kui-content-item-radius: var(
21
+ --kui-layout-pill-radius,
22
+ calc(1px + 1.3125rem)
23
+ );
24
+ }
25
+
26
+ /* A visible frame for a content item that marks a real distinction: the
27
+ standard neutral border, same geometry (the border is always reserved). */
28
+ .kui-content-item--framed {
29
+ --kui-content-item-border: var(--kui-color-neutral-border-normal);
30
+ }
@@ -13,6 +13,11 @@
13
13
  dark so the controls read as one distinct floating layer over any theme. */
14
14
  position: absolute;
15
15
  z-index: 4;
16
+ /* A layout whose open side overlay covers this toolbar's region (a
17
+ Workbench rail, a CollapsiblePanel, a ResizableRegion) flags that region,
18
+ and the toolbar hides — out of the tab order and the accessibility tree —
19
+ rather than risk painting over the overlay. */
20
+ visibility: var(--_kui-floating-covered, inherit);
16
21
  display: flex;
17
22
  color-scheme: dark;
18
23
  align-items: center;
@@ -79,6 +79,33 @@
79
79
  --kui-radius-circle: var(--wa-border-radius-circle, 50%);
80
80
  --kui-radius-pill: var(--wa-border-radius-pill, 999px);
81
81
  --kui-disclosure-icon-scale: 0.5;
82
+ /* Private popup-choice contract. A Select's listbox and a PopupMenu's menu
83
+ both read these, so a value list and a command menu draw one surface
84
+ inset, one row geometry (Web Awesome's option metrics plus Kerf's label
85
+ rhythm), one reserved check column, one current-row fill, one group-title
86
+ style, and one disclosure-caret motion. The em values resolve against the
87
+ row that reads them. */
88
+ --_kui-popup-inset: 0.25rem;
89
+ --_kui-popup-row-gap: 0.125rem;
90
+ --_kui-popup-row-padding-block: 0.5em;
91
+ --_kui-popup-row-padding-inline-start: 0.25em;
92
+ --_kui-popup-row-padding-inline-end: 1em;
93
+ --_kui-popup-row-check-width: calc(
94
+ 2 * var(--wa-font-size-smaller, round(calc(1em / 1.125), 1px))
95
+ );
96
+ --_kui-popup-row-icon-size: 1rem;
97
+ --_kui-popup-row-icon-gap: 0.5rem;
98
+ --_kui-popup-row-label-padding-block: 0.35rem;
99
+ --_kui-popup-row-label-line-height: 1.25;
100
+ --_kui-popup-row-current-background: var(--kui-color-brand-fill-normal);
101
+ /* Current row text sits on the brand fill; the darker on-fill accent clears
102
+ WCAG AA there (brand-on-quiet is 4.26:1 over that fill). */
103
+ --_kui-popup-row-current-color: var(--kui-color-brand-on-fill);
104
+ --_kui-popup-group-title-padding: 0.2rem 0.75rem 0.3rem;
105
+ --_kui-popup-group-title-font-weight: 750;
106
+ --_kui-popup-caret-open-rotation: -180deg;
107
+ --_kui-popup-caret-transition: rotate var(--wa-transition-slow, 0.3s)
108
+ var(--wa-transition-easing, ease);
82
109
  /* macOS Tahoe light semantics used by Hot Sheet 2, with a compatible dark extension. */
83
110
  /* Every --kui-color-* token (and the focus-ring color) that reads a --wa-*
84
111
  token falls back to the value src/webawesome.css assigns to that token,
@@ -419,22 +446,6 @@
419
446
  fill; #ffa0a2 matches the other tones' pale dark on-fill values. */
420
447
  --kui-color-danger-on-fill: light-dark(#c20b20, #ffa0a2);
421
448
 
422
- /* Compatibility aliases retained for existing @kerfjs/ui consumers. */
423
- --kui-color-border: var(
424
- --wa-color-surface-border,
425
- var(--kui-color-neutral-border-normal)
426
- );
427
- --kui-color-border-quiet: var(--kui-color-neutral-border-quiet);
428
- --kui-color-accent: var(--kui-color-brand-fill-normal);
429
- --kui-color-accent-text: var(--kui-color-brand-on-quiet);
430
- --kui-color-pop: var(--kui-color-pop-fill-quiet);
431
- --kui-color-pop-text: var(--kui-color-pop-on-fill);
432
- --kui-color-success: var(--kui-color-success-fill-quiet);
433
- --kui-color-success-text: var(--kui-color-success-on-quiet);
434
- --kui-color-warning: var(--kui-color-warning-fill-quiet);
435
- --kui-color-warning-text: var(--kui-color-warning-on-quiet);
436
- --kui-color-danger: var(--kui-color-danger-fill-quiet);
437
- --kui-color-danger-text: var(--kui-color-danger-on-quiet);
438
449
  --kui-focus-ring: var(
439
450
  --wa-focus-ring,
440
451
  3px solid var(--wa-color-focus, light-dark(#007aff, #64d2ff))
@@ -468,9 +479,7 @@
468
479
  --kui-color-pop-on-normal: currentColor;
469
480
  --kui-color-pop-on-loud: HighlightText;
470
481
  --kui-color-pop-on-fill: currentColor;
471
- --kui-color-pop: Canvas;
472
- --kui-color-pop-text: currentColor;
473
- --kui-color-border: currentColor;
482
+ --kui-color-neutral-border-normal: currentColor;
474
483
  --kui-focus-ring: 3px solid currentColor;
475
484
  }
476
485
  }
@@ -1,4 +1,5 @@
1
1
  @import "./pane.css";
2
+ @import "./content-item.css";
2
3
 
3
4
  /* Shared application content geometry for Pane children and standalone stacks. */
4
5
 
@@ -10,27 +11,6 @@
10
11
  gap: var(--kui-layout-content-gap, 1.5rem);
11
12
  }
12
13
 
13
- .kui-content-item {
14
- min-width: 0;
15
- margin-inline: var(--kui-layout-inline-margin, 0.5rem);
16
- padding: var(--kui-layout-item-padding, 0.5rem);
17
- box-sizing: border-box;
18
- border: var(--kui-layout-item-border-width, 1px) solid
19
- var(--kui-content-item-border, transparent);
20
- border-radius: var(
21
- --kui-content-item-radius,
22
- var(--kui-layout-rounded-radius, calc(1px + 0.6875rem))
23
- );
24
- background: var(--kui-content-item-background, transparent);
25
- }
26
-
27
- .kui-content-item--pill {
28
- --kui-content-item-radius: var(
29
- --kui-layout-pill-radius,
30
- calc(1px + 1.3125rem)
31
- );
32
- }
33
-
34
14
  .kui-control-cluster {
35
15
  display: flex;
36
16
  min-width: 0;
@@ -140,7 +140,6 @@
140
140
  2.75rem - (2 * var(--kui-layout-item-padding, 0.5rem))
141
141
  );
142
142
  overflow: hidden;
143
- text-overflow: ellipsis;
144
143
  white-space: nowrap;
145
144
  align-items: center;
146
145
  }
@@ -151,6 +150,14 @@
151
150
  min-width: 0;
152
151
  }
153
152
 
153
+ /* The label is a grid container, and `text-overflow` never reaches a grid
154
+ item's text, so each text line of the stack ellipsizes itself. */
155
+ .kui-list-action-row__primary-label,
156
+ .kui-list-action-row__description {
157
+ overflow: hidden;
158
+ text-overflow: ellipsis;
159
+ }
160
+
154
161
  .kui-list-action-row__description,
155
162
  .kui-list-action-row__status {
156
163
  color: var(--kui-color-neutral-on-quiet);
@@ -181,6 +188,11 @@
181
188
  white-space: normal;
182
189
  }
183
190
 
191
+ .kui-list-action-row[data-multiline="true"]
192
+ :is(.kui-list-action-row__primary-label, .kui-list-action-row__description) {
193
+ overflow: visible;
194
+ }
195
+
184
196
  .kui-list-action-row[data-multiline="true"] .kui-list-action-row__icon {
185
197
  inset-block-start: calc(
186
198
  var(--kui-layout-item-padding, 0.5rem) + (1lh / 2)
@@ -1,5 +1,4 @@
1
- .kui-list-inset-text,
2
- .kui-list-inset-text--horizontal {
1
+ .kui-list-inset-text {
3
2
  margin: 0;
4
3
  border: 0 solid transparent;
5
4
  padding: 0;
@@ -128,13 +128,17 @@
128
128
  display: grid;
129
129
  min-width: 0;
130
130
  overflow: hidden;
131
- text-overflow: ellipsis;
132
131
  white-space: nowrap;
133
132
  }
134
133
 
134
+ /* The label is a grid container, and `text-overflow` never reaches a grid
135
+ item's text, so each line of the stack clips and ellipsizes itself: a long
136
+ label ends in "…" before the trailing slot instead of being cut mid-glyph. */
135
137
  .kui-list-item__primary-label,
136
138
  .kui-list-item__description {
137
139
  min-width: 0;
140
+ overflow: hidden;
141
+ text-overflow: ellipsis;
138
142
  }
139
143
 
140
144
  .kui-list-item__description {
@@ -160,6 +164,15 @@
160
164
  white-space: normal;
161
165
  }
162
166
 
167
+ /* A multiline row shows its whole label, so a single word wider than the
168
+ column (a long component or file name) breaks onto the next line rather
169
+ than running under the trailing slot. */
170
+ .kui-list-item[data-multiline="true"]
171
+ :is(.kui-list-item__primary-label, .kui-list-item__description) {
172
+ overflow: visible;
173
+ overflow-wrap: anywhere;
174
+ }
175
+
163
176
  .kui-list-item[data-multiline="true"] .kui-list-item__icon {
164
177
  align-self: start;
165
178
  margin-block-start: calc((1lh - 1.125rem) / 2);
@@ -1,5 +1,5 @@
1
1
  .kui-list {
2
- --kui-list-divider-color: var(--kui-color-border);
2
+ --kui-list-divider-color: var(--kui-color-neutral-border-normal);
3
3
  --kui-list-gap: var(--kui-layout-item-gap, 0.5rem);
4
4
  /* Private per-instance values are reset on every List so a nested List that
5
5
  omits `gap` or `flex` never inherits its ancestor's; the component's inline