@kerfjs/ui 5.0.0-beta.82 → 5.0.0-beta.84

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (153) hide show
  1. package/README.md +1 -0
  2. package/ai/catalog-authoring.json +1 -3
  3. package/ai/catalog-authoring.schema.json +3 -7
  4. package/ai/component-catalog.json +73 -2
  5. package/ai/component-composition.json +64 -1
  6. package/ai/components/README.md +1 -0
  7. package/ai/components/anchored-surface.md +86 -0
  8. package/ai/components/tab-navigator.md +3 -2
  9. package/ai/public-api-signatures-v1.md +79 -35
  10. package/ai/skill.md +2 -2
  11. package/ai/webawesome-jsx-signatures-v1.md +1 -1
  12. package/dist/anchored-surface.d.ts +30 -0
  13. package/dist/anchored-surface.js +3 -0
  14. package/dist/anchored-surface.js.map +1 -0
  15. package/dist/app-tab.js +1 -1
  16. package/dist/browser/anchored-surface.js +3 -0
  17. package/dist/browser/catalog.js +1 -1
  18. package/dist/catalog-resources.d.ts +2 -2
  19. package/dist/catalog.d.ts +4 -4
  20. package/dist/catalog.js +34 -31
  21. package/dist/catalog.js.map +1 -1
  22. package/dist/{chunk-I4SDIMFA.js → chunk-2YPPNFYT.js} +2 -2
  23. package/dist/{chunk-I4SDIMFA.js.map → chunk-2YPPNFYT.js.map} +1 -1
  24. package/dist/{chunk-VHXHLZ6R.js → chunk-3DXHNLME.js} +3 -3
  25. package/dist/{chunk-VHXHLZ6R.js.map → chunk-3DXHNLME.js.map} +1 -1
  26. package/dist/{chunk-HFQDSSED.js → chunk-3PO7JEK7.js} +4 -4
  27. package/dist/{chunk-HFQDSSED.js.map → chunk-3PO7JEK7.js.map} +1 -1
  28. package/dist/chunk-6IVNMC6R.js +19 -0
  29. package/dist/chunk-6IVNMC6R.js.map +1 -0
  30. package/dist/{chunk-VR7MWD2X.js → chunk-CD5TOO22.js} +4 -13
  31. package/dist/chunk-CD5TOO22.js.map +1 -0
  32. package/dist/{chunk-H7ZJEI3H.js → chunk-DL55BSQX.js} +3 -3
  33. package/dist/{chunk-H7ZJEI3H.js.map → chunk-DL55BSQX.js.map} +1 -1
  34. package/dist/{chunk-VIGVNDXZ.js → chunk-GPCAXYMT.js} +4 -4
  35. package/dist/{chunk-VIGVNDXZ.js.map → chunk-GPCAXYMT.js.map} +1 -1
  36. package/dist/chunk-IOS2NXW7.js +53 -0
  37. package/dist/chunk-IOS2NXW7.js.map +1 -0
  38. package/dist/{chunk-HFLGWMG3.js → chunk-KAJVVN7Q.js} +3 -3
  39. package/dist/{chunk-HFLGWMG3.js.map → chunk-KAJVVN7Q.js.map} +1 -1
  40. package/dist/{chunk-LQKY5S4F.js → chunk-KL3W6FUN.js} +4 -4
  41. package/dist/{chunk-LQKY5S4F.js.map → chunk-KL3W6FUN.js.map} +1 -1
  42. package/dist/{chunk-NVKRZ5DI.js → chunk-LFPW4YC6.js} +4 -4
  43. package/dist/{chunk-NVKRZ5DI.js.map → chunk-LFPW4YC6.js.map} +1 -1
  44. package/dist/{chunk-75I3SNUJ.js → chunk-MN3POJFN.js} +2 -2
  45. package/dist/{chunk-75I3SNUJ.js.map → chunk-MN3POJFN.js.map} +1 -1
  46. package/dist/{chunk-5D3WDMIK.js → chunk-MORVLMDG.js} +4 -16
  47. package/dist/chunk-MORVLMDG.js.map +1 -0
  48. package/dist/{chunk-RRCD3A6G.js → chunk-MTCTX25G.js} +2 -2
  49. package/dist/{chunk-RRCD3A6G.js.map → chunk-MTCTX25G.js.map} +1 -1
  50. package/dist/{chunk-PQQQXJGV.js → chunk-NP3FSLNX.js} +2 -2
  51. package/dist/{chunk-PQQQXJGV.js.map → chunk-NP3FSLNX.js.map} +1 -1
  52. package/dist/{chunk-ARZ4RSQO.js → chunk-PGL6TXFW.js} +3 -3
  53. package/dist/{chunk-ARZ4RSQO.js.map → chunk-PGL6TXFW.js.map} +1 -1
  54. package/dist/{chunk-NVRJ7C3W.js → chunk-QQICWWNX.js} +4 -16
  55. package/dist/chunk-QQICWWNX.js.map +1 -0
  56. package/dist/{chunk-CVKIADIS.js → chunk-SJW5BCEQ.js} +7 -5
  57. package/dist/chunk-SJW5BCEQ.js.map +1 -0
  58. package/dist/{chunk-JZM3G6RT.js → chunk-TTGIHMDR.js} +4 -4
  59. package/dist/{chunk-JZM3G6RT.js.map → chunk-TTGIHMDR.js.map} +1 -1
  60. package/dist/{chunk-LRAIS3YB.js → chunk-U657IHFB.js} +1 -1
  61. package/dist/chunk-U657IHFB.js.map +1 -0
  62. package/dist/{chunk-3SXWV2IR.js → chunk-VLGQIYZ5.js} +2 -2
  63. package/dist/{chunk-3SXWV2IR.js.map → chunk-VLGQIYZ5.js.map} +1 -1
  64. package/dist/{chunk-YLJ6X3AC.js → chunk-XK4E225T.js} +2 -2
  65. package/dist/{chunk-YLJ6X3AC.js.map → chunk-XK4E225T.js.map} +1 -1
  66. package/dist/{chunk-BJLXE56E.js → chunk-XKZPBRU7.js} +4 -4
  67. package/dist/{chunk-BJLXE56E.js.map → chunk-XKZPBRU7.js.map} +1 -1
  68. package/dist/{chunk-62VMNBV2.js → chunk-XNXKIPU5.js} +2 -2
  69. package/dist/{chunk-62VMNBV2.js.map → chunk-XNXKIPU5.js.map} +1 -1
  70. package/dist/{chunk-EFDCALR3.js → chunk-Y43B6DS3.js} +2 -2
  71. package/dist/{chunk-EFDCALR3.js.map → chunk-Y43B6DS3.js.map} +1 -1
  72. package/dist/{chunk-3RE2JMZU.js → chunk-YOKEL75M.js} +2 -2
  73. package/dist/{chunk-3RE2JMZU.js.map → chunk-YOKEL75M.js.map} +1 -1
  74. package/dist/collapsible-panel.js +4 -3
  75. package/dist/collapsible-panel.js.map +1 -1
  76. package/dist/css-values.d.ts +8 -1
  77. package/dist/css-values.js +1 -1
  78. package/dist/disclosure-arrow.js +1 -1
  79. package/dist/empty-state.js +1 -1
  80. package/dist/grid.d.ts +5 -4
  81. package/dist/grid.js +2 -1
  82. package/dist/index.d.ts +2 -0
  83. package/dist/index.js +26 -24
  84. package/dist/list-action-row.js +1 -1
  85. package/dist/list-header.js +1 -1
  86. package/dist/list-item.js +1 -1
  87. package/dist/list.d.ts +5 -4
  88. package/dist/list.js +2 -1
  89. package/dist/loading-spinner.js +1 -1
  90. package/dist/lucide-icon.js +1 -1
  91. package/dist/{nav-stack-B1Qc2e5q.d.ts → nav-stack-BvSKY448.d.ts} +10 -2
  92. package/dist/nav-stack.d.ts +1 -1
  93. package/dist/nav-stack.js +2 -1
  94. package/dist/row.d.ts +5 -4
  95. package/dist/row.js +2 -1
  96. package/dist/select.js +1 -1
  97. package/dist/skeleton.js +1 -1
  98. package/dist/spacer.js +1 -1
  99. package/dist/split-view.d.ts +1 -1
  100. package/dist/split-view.js +2 -1
  101. package/dist/split-view.js.map +1 -1
  102. package/dist/state-banner.js +1 -1
  103. package/dist/styles/anchored-surface.css +15 -0
  104. package/dist/styles/catalog/components/catalog-example.css +1 -2
  105. package/dist/styles/catalog/components/catalog-stage.css +40 -42
  106. package/dist/styles/catalog/components/catalog.css +0 -11
  107. package/dist/styles/components/collections/list/list.css +4 -1
  108. package/dist/styles/components/feedback/anchored-surface/anchored-surface.css +15 -0
  109. package/dist/styles/components/layout/grid/grid.css +4 -1
  110. package/dist/styles/components/layout/pane/pane.css +15 -0
  111. package/dist/styles/components/layout/row/row.css +4 -1
  112. package/dist/styles/components/layout/workbench/workbench.css +17 -0
  113. package/dist/styles/components/navigation/nav-stack/nav-stack.css +21 -5
  114. package/dist/styles/components/navigation/tab-navigator/tab-navigator.css +25 -9
  115. package/dist/styles/grid.css +4 -1
  116. package/dist/styles/list.css +4 -1
  117. package/dist/styles/nav-stack.css +21 -5
  118. package/dist/styles/pane.css +15 -0
  119. package/dist/styles/row.css +4 -1
  120. package/dist/styles/styles.css +1 -0
  121. package/dist/styles/tab-navigator.css +25 -9
  122. package/dist/styles/workbench.css +17 -0
  123. package/dist/tab-navigator.d.ts +10 -3
  124. package/dist/tab-navigator.js +2 -0
  125. package/dist/tab-navigator.js.map +1 -1
  126. package/dist/token-search-field.js +1 -1
  127. package/dist/toolbar-control-group.js +1 -1
  128. package/dist/toolbar-text.js +1 -1
  129. package/dist/{types-C9BubXfz.d.ts → types-Bn-dXLcs.d.ts} +6 -2
  130. package/dist/value-table.js +1 -1
  131. package/dist/wire-catalog.d.ts +1 -9
  132. package/dist/wire-catalog.js +2 -200
  133. package/dist/wire-catalog.js.map +1 -1
  134. package/dist/wire-token-search-fields.js +1 -1
  135. package/dist/workbench.d.ts +1 -1
  136. package/dist/workbench.js +2 -1
  137. package/docs/anchored-surface.md +51 -0
  138. package/docs/catalog.md +38 -82
  139. package/docs/component-contract.md +3 -1
  140. package/docs/component-selection.md +19 -1
  141. package/docs/layout.md +19 -2
  142. package/docs/nav-stack.md +13 -4
  143. package/docs/tab-navigator.md +12 -4
  144. package/docs/type-contracts.md +2 -0
  145. package/docs/ux-demo.md +4 -4
  146. package/docs/workbench.md +2 -0
  147. package/llms.txt +8 -3
  148. package/package.json +7 -1
  149. package/dist/chunk-5D3WDMIK.js.map +0 -1
  150. package/dist/chunk-CVKIADIS.js.map +0 -1
  151. package/dist/chunk-LRAIS3YB.js.map +0 -1
  152. package/dist/chunk-NVRJ7C3W.js.map +0 -1
  153. package/dist/chunk-VR7MWD2X.js.map +0 -1
@@ -1,6 +1,6 @@
1
1
  # Public API signatures for the UI authoring corpus
2
2
 
3
- Generated from emitted declarations for `@kerfjs/ui@5.0.0-beta.82` and `kerfjs@5.0.0-beta.82`. This bounded reference covers only APIs used by the seven-task corpus. It is interface evidence, not an implementation or runtime guarantee.
3
+ Generated from emitted declarations for `@kerfjs/ui@5.0.0-beta.84` and `kerfjs@5.0.0-beta.84`. This bounded reference covers only APIs used by the seven-task corpus. It is interface evidence, not an implementation or runtime guarantee.
4
4
 
5
5
  ## `@kerfjs/ui/css-values`
6
6
 
@@ -66,6 +66,13 @@ type UiColorName = (typeof uiColorNames)[number];
66
66
  type UiForegroundColorName = Extract<UiColorName, `${string}-on-${string}` | 'text' | 'text-quiet' | 'text-link'>;
67
67
  /** Kerf UI's complete spacing-token vocabulary. `s` and `xl` are exceptions. */
68
68
  type UiSpaceName = 'none' | '2xs' | 'xs' | 's' | 'm' | 'l' | 'xl';
69
+ /** A token or complete typed length for one gap axis. */
70
+ type UiGapValue = UiSpaceName | CssLength;
71
+ /** A shared gap or independent column and row gaps. */
72
+ type UiGap = UiGapValue | Readonly<{
73
+ column: UiGapValue;
74
+ row: UiGapValue;
75
+ }>;
69
76
  /** Create a complete pixel length. */
70
77
  declare function px(value: number): CssLength;
71
78
  /** Create a complete root-font-relative length. */
@@ -116,7 +123,7 @@ declare function foregroundColorVar(name: `--${string}`, fallback?: CssForegroun
116
123
  */
117
124
  declare function foregroundColor(value: string): CssForegroundColor;
118
125
 
119
- export { type CssColor, type CssFlex, type CssFlexBasis, type CssFlexKeyword, type CssForegroundColor, type CssLength, type CssLengthExpression, type CssSize, type CssSizeKeyword, type CssValue, type UiColor, type UiColorName, type UiForegroundColorName, type UiSpaceName, calc, colorVar, em, flex, foregroundColor, foregroundColorVar, lengthVar, pct, plus, px, rem, remify, space, uiColor };
126
+ export { type CssColor, type CssFlex, type CssFlexBasis, type CssFlexKeyword, type CssForegroundColor, type CssLength, type CssLengthExpression, type CssSize, type CssSizeKeyword, type CssValue, type UiColor, type UiColorName, type UiForegroundColorName, type UiGap, type UiGapValue, type UiSpaceName, calc, colorVar, em, flex, foregroundColor, foregroundColorVar, lengthVar, pct, plus, px, rem, remify, space, uiColor };
120
127
  ```
121
128
 
122
129
  ## `@kerfjs/ui/disclosure-arrow`
@@ -651,7 +658,8 @@ import { K as KerfUiContent } from './semantic-content-BbzjvSu9.js';
651
658
  import { H as HorizontalAlignment, L as ListVerticalAlignment } from './flex-alignment-4ms8ZbV8.js';
652
659
  export { V as VerticalAlignment } from './flex-alignment-4ms8ZbV8.js';
653
660
  import { S as Sides } from './sides-BPSWde0A.js';
654
- import { UiSpaceName, CssLength, CssFlexKeyword, CssFlex } from './css-values.js';
661
+ import { UiGap, CssFlexKeyword, CssFlex } from './css-values.js';
662
+ export { CssLength, UiGapValue, UiSpaceName } from './css-values.js';
655
663
 
656
664
  type ListRootAttributes = Readonly<Record<`data-${string}`, string | undefined> & {
657
665
  'data-component'?: never;
@@ -670,8 +678,8 @@ interface ListProps {
670
678
  selectionMode?: 'multiple';
671
679
  /** Accessible name for the multi-select grid. */
672
680
  ariaLabel?: string;
673
- /** Use the standard item gap, a named UI spacing token, or a typed CSS length. Defaults to no gap. */
674
- gap?: boolean | UiSpaceName | CssLength;
681
+ /** Standard gap (`true`), one spacing value, or separate column and row values. Defaults to no gap. */
682
+ gap?: boolean | UiGap;
675
683
  /** Allow this list to grow/shrink, use a keyword, or supply a typed CSS flex shorthand. */
676
684
  flex?: boolean | CssFlexKeyword | CssFlex;
677
685
  /**
@@ -708,7 +716,7 @@ type ListConfig = Pick<ListProps, 'gap' | 'hAlign' | 'vAlign' | 'dividerSides' |
708
716
  /** A stretch-aligned vertical stack with optional gap, flex, fill, scroll, and dividers. */
709
717
  declare function List({ children, selectionMode, ariaLabel, gap, flex, fill, hAlign, vAlign, scrollable, dividerSides, textInsets, controlInsets, className, rootAttributes, slot, }: ListProps): kerfjs.SafeHtml;
710
718
 
711
- export { CssFlex, CssFlexKeyword, CssLength, HorizontalAlignment, List, type ListConfig, type ListProps, ListVerticalAlignment, Sides, UiSpaceName };
719
+ export { CssFlex, CssFlexKeyword, HorizontalAlignment, List, type ListConfig, type ListProps, ListVerticalAlignment, Sides, UiGap };
712
720
  ```
713
721
 
714
722
  ## `@kerfjs/ui/list-action-row`
@@ -1287,7 +1295,7 @@ export { type ScrollDividerTarget, type WireScrollDividersOptions, wireScrollDiv
1287
1295
  ## `@kerfjs/ui/nav-stack`
1288
1296
 
1289
1297
  ```ts
1290
- export { c as NavStack, N as NavStackProps, d as NavStackToolbarConfig, a as NavStackView, e as NavStackViewBottomToolbar, f as NavStackViewToolbar } from './nav-stack-B1Qc2e5q.js';
1298
+ export { c as NavStack, N as NavStackProps, d as NavStackToolbarConfig, a as NavStackView, e as NavStackViewBottomToolbar, f as NavStackViewToolbar } from './nav-stack-BvSKY448.js';
1291
1299
  import 'kerfjs';
1292
1300
  import './semantic-content-BbzjvSu9.js';
1293
1301
  import './list.js';
@@ -1330,7 +1338,7 @@ export { type WireNavStackOptions, wireNavStack };
1330
1338
  ```ts
1331
1339
  import * as kerfjs from 'kerfjs';
1332
1340
  import { K as KerfUiContent } from './semantic-content-BbzjvSu9.js';
1333
- import { N as NavStackProps, a as NavStackView } from './nav-stack-B1Qc2e5q.js';
1341
+ import { N as NavStackProps, a as NavStackView } from './nav-stack-BvSKY448.js';
1334
1342
  import { ResizableRegionProps } from './resizable-region.js';
1335
1343
  import './list.js';
1336
1344
  import './flex-alignment-4ms8ZbV8.js';
@@ -1535,7 +1543,7 @@ export { Pane, type PaneAppearance, type PaneChromeDividers, type PaneChromePlac
1535
1543
  ```ts
1536
1544
  import { SafeHtml } from 'kerfjs';
1537
1545
  import { K as KerfUiContent } from './semantic-content-BbzjvSu9.js';
1538
- import { b as NavPane, N as NavStackProps } from './nav-stack-B1Qc2e5q.js';
1546
+ import { b as NavPane, N as NavStackProps } from './nav-stack-BvSKY448.js';
1539
1547
  import { ListConfig } from './list.js';
1540
1548
  import { PaneConfig } from './pane.js';
1541
1549
  import { ResizableRegionSeparator, ResizableRegionCollapseMotion, ResizableRegionContentOverflow, ResizableRegionPresentation, ResizableRegionRestorePosition } from './resizable-region.js';
@@ -2200,14 +2208,21 @@ interface TabNavigatorProps<Id extends string = string> {
2200
2208
  tabs: readonly TabNavigatorTab<Id>[];
2201
2209
  /** The controlled active tab id (the app owns selection). */
2202
2210
  active: NoInfer<Id>;
2211
+ /**
2212
+ * The bar's top separator. `auto` (default) draws it against a sunken active
2213
+ * work surface and otherwise follows `chromeDividers`; `hidden` suppresses
2214
+ * the line, including a scroll divider.
2215
+ */
2216
+ separator?: 'auto' | 'hidden';
2203
2217
  /**
2204
2218
  * The line over the tab bar, where it meets the active scene. `scroll`
2205
2219
  * (default) shows it only while more of the scene's content lies below —
2206
2220
  * never at the scroll end or when the content fits — once
2207
2221
  * `wireScrollDividers` (`@kerfjs/ui/wire-scroll-dividers`) is wired above
2208
2222
  * the scaffold; unwired, it does not show. `always` shows it without the
2209
- * wiring; `none` never, even when wired. The line is the bar's own 1px top
2210
- * border, so no state moves the bar or a tab.
2223
+ * wiring; `none` suppresses that scroll divider. A sunken active work
2224
+ * surface still draws the separator unless `separator="hidden"`. The line
2225
+ * is the bar's own 1px top border, so no state moves the bar or a tab.
2211
2226
  */
2212
2227
  chromeDividers?: 'scroll' | 'always' | 'none';
2213
2228
  className?: string;
@@ -2222,7 +2237,7 @@ interface TabNavigatorProps<Id extends string = string> {
2222
2237
  * On larger classes, promote the tabs to a `Workbench` rail or sidebar instead of
2223
2238
  * a bottom bar. See `docs/23-app-layouts.md` §3.4.
2224
2239
  */
2225
- declare function TabNavigator<Id extends string>({ id, label, tabs, active, chromeDividers, className, slot, }: TabNavigatorProps<Id>): SafeHtml;
2240
+ declare function TabNavigator<Id extends string>({ id, label, tabs, active, separator, chromeDividers, className, slot, }: TabNavigatorProps<Id>): SafeHtml;
2226
2241
 
2227
2242
  export { TabNavigator, type TabNavigatorProps, type TabNavigatorTab };
2228
2243
  ```
@@ -2393,14 +2408,14 @@ export { DEFAULT_BREAKPOINTS, type DeviceBreakpoints, type DeviceClass, type Dev
2393
2408
  ```ts
2394
2409
  import * as kerfjs from 'kerfjs';
2395
2410
  import { SafeHtml } from 'kerfjs';
2396
- import { a as CatalogProps } from './types-C9BubXfz.js';
2397
- export { b as CatalogBrand, c as CatalogEntry, d as CatalogRelated, C as CatalogResource, e as CatalogSecondaryGroup, f as CatalogSection, g as CatalogStageRootAttributes } from './types-C9BubXfz.js';
2411
+ import { a as CatalogProps } from './types-Bn-dXLcs.js';
2412
+ export { b as CatalogBackgroundStyle, c as CatalogBrand, d as CatalogEntry, e as CatalogRelated, C as CatalogResource, f as CatalogSecondaryGroup, g as CatalogSection, h as CatalogStageRootAttributes } from './types-Bn-dXLcs.js';
2398
2413
  import { K as KerfUiContent } from './semantic-content-BbzjvSu9.js';
2399
2414
  import './toolbar.js';
2400
2415
  import './sides-BPSWde0A.js';
2401
2416
  import './pane.js';
2402
2417
  import './workbench.js';
2403
- import './nav-stack-B1Qc2e5q.js';
2418
+ import './nav-stack-BvSKY448.js';
2404
2419
  import './list.js';
2405
2420
  import './flex-alignment-4ms8ZbV8.js';
2406
2421
  import './css-values.js';
@@ -2417,7 +2432,7 @@ import './resizable-region.js';
2417
2432
  * standard toggle moves into the entry toolbar while it is collapsed, and on
2418
2433
  * a small screen the sidebar overlays the stage like any Workbench rail.
2419
2434
  */
2420
- declare function Catalog({ id, brand, sections, active, content, collapsed, theme, headerActions, secondarySections, sidebarFooter, status, geometryOverlay, stageRootAttributes, selectAction, toggleSidebarAction, toggleThemeAction, toggleSecondaryAction, headerPlacement, footerPlacement, sidebar, mainToolbar, footerToolbar, className, slot, }: CatalogProps): kerfjs.SafeHtml;
2435
+ declare function Catalog({ id, brand, sections, active, content, collapsed, theme, headerActions, secondarySections, sidebarFooter, status, backgroundStyle, stageRootAttributes, selectAction, toggleSidebarAction, toggleThemeAction, toggleSecondaryAction, headerPlacement, footerPlacement, sidebar, mainToolbar, footerToolbar, className, slot, }: CatalogProps): kerfjs.SafeHtml;
2421
2436
 
2422
2437
  /** How a specimen aligns its visible edge with its `ListHeader` label. */
2423
2438
  type CatalogExampleAlign = 'glyph' | 'inline-control' | 'text-trigger' | 'none';
@@ -2488,14 +2503,14 @@ export { Catalog, CatalogExample, type CatalogExampleAlign, type CatalogExampleP
2488
2503
  ## `@kerfjs/ui/catalog-resources`
2489
2504
 
2490
2505
  ```ts
2491
- import { C as CatalogResource } from './types-C9BubXfz.js';
2506
+ import { C as CatalogResource } from './types-Bn-dXLcs.js';
2492
2507
  import './toolbar.js';
2493
2508
  import 'kerfjs';
2494
2509
  import './semantic-content-BbzjvSu9.js';
2495
2510
  import './sides-BPSWde0A.js';
2496
2511
  import './pane.js';
2497
2512
  import './workbench.js';
2498
- import './nav-stack-B1Qc2e5q.js';
2513
+ import './nav-stack-BvSKY448.js';
2499
2514
  import './list.js';
2500
2515
  import './flex-alignment-4ms8ZbV8.js';
2501
2516
  import './css-values.js';
@@ -2603,14 +2618,6 @@ interface CatalogRevealOptions {
2603
2618
  * moving focus. Returns a cancellation function for rapid selection changes.
2604
2619
  */
2605
2620
  declare function revealCatalogEntry(root: HTMLElement, id: string, { block, inline, behavior, media, }?: CatalogRevealOptions): () => void;
2606
- /**
2607
- * Keep a Catalog's opt-in geometry overlay synchronized with its preview.
2608
- * Specimens receive computed border highlights (or a dashed bound when they
2609
- * have no border and are transparent), while positive computed margins use
2610
- * devtools-style orange bands. CSS/stylesheet-only changes are observed too.
2611
- * Returns a disposer.
2612
- */
2613
- declare function wireCatalogGeometryOverlay(root: HTMLElement): () => void;
2614
2621
  /**
2615
2622
  * Wire a {@link Catalog}'s interactions with one delegated listener set: sidebar
2616
2623
  * item selection (and the related-entry popup menu), the sidebar collapse toggle, and
@@ -2622,7 +2629,7 @@ declare function wireCatalogGeometryOverlay(root: HTMLElement): () => void;
2622
2629
  */
2623
2630
  declare function wireCatalog(root: HTMLElement, { onSelect, onToggleSidebar, onToggleTheme, onToggleSecondary, urlParam, revealSelection, selectAction, toggleSidebarAction, toggleThemeAction, toggleSecondaryAction, collapsed, sidebarSize, sidebarStorageKey, id: catalogId, }: WireCatalogOptions): () => void;
2624
2631
 
2625
- export { type CatalogRevealOptions, type WireCatalogOptions, revealCatalogEntry, wireCatalog, wireCatalogGeometryOverlay };
2632
+ export { type CatalogRevealOptions, type WireCatalogOptions, revealCatalogEntry, wireCatalog };
2626
2633
  ```
2627
2634
 
2628
2635
  ## `@kerfjs/ui/segmented-control`
@@ -3420,7 +3427,8 @@ import * as kerfjs from 'kerfjs';
3420
3427
  import { K as KerfUiContent } from './semantic-content-BbzjvSu9.js';
3421
3428
  import { H as HorizontalAlignment, V as VerticalAlignment } from './flex-alignment-4ms8ZbV8.js';
3422
3429
  import { S as Sides } from './sides-BPSWde0A.js';
3423
- import { UiSpaceName, CssLength, CssFlexKeyword, CssFlex } from './css-values.js';
3430
+ import { UiGap, CssFlexKeyword, CssFlex } from './css-values.js';
3431
+ export { CssLength, UiGapValue, UiSpaceName } from './css-values.js';
3424
3432
 
3425
3433
  type RowRootAttributes = Readonly<Record<`data-${string}`, string | undefined> & {
3426
3434
  'data-component'?: never;
@@ -3438,8 +3446,8 @@ interface RowProps {
3438
3446
  hAlign?: HorizontalAlignment;
3439
3447
  /** Vertical alignment and wrapped-line distribution. Defaults to full. */
3440
3448
  vAlign?: VerticalAlignment;
3441
- /** A named UI spacing token or typed CSS length. Defaults to xs. */
3442
- gap?: UiSpaceName | CssLength;
3449
+ /** One spacing value or separate column and row values. Defaults to xs. */
3450
+ gap?: UiGap;
3443
3451
  /** Allow this row to grow/shrink, use a keyword, or supply a typed CSS flex shorthand. */
3444
3452
  flex?: boolean | CssFlexKeyword | CssFlex;
3445
3453
  /**
@@ -3463,7 +3471,7 @@ interface RowProps {
3463
3471
  /** A horizontal flex row with explicit physical-axis alignment and spacing. */
3464
3472
  declare function Row({ children, hAlign, vAlign, gap, flex, fill, wrap, textInsets, controlInsets, className, rootAttributes, slot, }: RowProps): kerfjs.SafeHtml;
3465
3473
 
3466
- export { CssFlex, CssFlexKeyword, CssLength, HorizontalAlignment, Row, type RowProps, Sides, UiSpaceName, VerticalAlignment };
3474
+ export { CssFlex, CssFlexKeyword, HorizontalAlignment, Row, type RowProps, Sides, UiGap, VerticalAlignment };
3467
3475
  ```
3468
3476
 
3469
3477
  ## `@kerfjs/ui/grid`
@@ -3472,7 +3480,8 @@ export { CssFlex, CssFlexKeyword, CssLength, HorizontalAlignment, Row, type RowP
3472
3480
  import * as kerfjs from 'kerfjs';
3473
3481
  import { K as KerfUiContent } from './semantic-content-BbzjvSu9.js';
3474
3482
  import { S as Sides } from './sides-BPSWde0A.js';
3475
- import { UiSpaceName, CssLength, CssFlexKeyword, CssFlex } from './css-values.js';
3483
+ import { UiGap, CssFlexKeyword, CssFlex, CssLength } from './css-values.js';
3484
+ export { UiGapValue, UiSpaceName } from './css-values.js';
3476
3485
 
3477
3486
  type GridRootAttributes = Readonly<Record<`data-${string}`, string | undefined> & {
3478
3487
  'data-component'?: never;
@@ -3490,8 +3499,8 @@ interface GridCommonProps {
3490
3499
  selectionMode?: 'multiple';
3491
3500
  /** Accessible name for the multi-select grid. */
3492
3501
  ariaLabel?: string;
3493
- /** A named UI spacing token or typed CSS length. Defaults to xs. */
3494
- gap?: UiSpaceName | CssLength;
3502
+ /** One spacing value or separate column and row values. Defaults to xs. */
3503
+ gap?: UiGap;
3495
3504
  /** Allow this grid to grow/shrink, use a keyword, or supply a typed CSS flex shorthand. */
3496
3505
  flex?: boolean | CssFlexKeyword | CssFlex;
3497
3506
  /**
@@ -3525,7 +3534,7 @@ type GridProps = GridCommonProps & ({
3525
3534
  /** Render equal tracks with a fixed count or a responsive minimum width. */
3526
3535
  declare function Grid({ children, selectionMode, ariaLabel, columns, minColumnWidth, autoFill, gap, flex, fill, textInsets, controlInsets, className, rootAttributes, slot, }: GridProps): kerfjs.SafeHtml;
3527
3536
 
3528
- export { CssFlex, CssFlexKeyword, CssLength, Grid, type GridProps, Sides, UiSpaceName };
3537
+ export { CssFlex, CssFlexKeyword, CssLength, Grid, type GridProps, Sides, UiGap };
3529
3538
  ```
3530
3539
 
3531
3540
  ## `@kerfjs/ui/spacer`
@@ -3558,3 +3567,38 @@ export { d as TokenSearchModel, e as TokenSearchModelOptions, f as TokenSearchRe
3558
3567
  import 'kerfjs';
3559
3568
  import './semantic-content-BbzjvSu9.js';
3560
3569
  ```
3570
+
3571
+ ## `@kerfjs/ui/anchored-surface`
3572
+
3573
+ ```ts
3574
+ import { PopoverOptions, OverlayContent, OverlayHandle } from 'kerfjs/overlay';
3575
+
3576
+ /** App-facing options for a non-modal, arbitrary-content help surface. */
3577
+ interface AnchoredSurfaceOptions extends Pick<PopoverOptions, 'placement' | 'align' | 'gap' | 'dismiss' | 'initialFocus' | 'onDismiss' | 'outsideIgnore'> {
3578
+ /** Accessible name for the non-modal dialog. */
3579
+ label: string;
3580
+ }
3581
+ /** A viewport pointer location; `context` is the element under the pointer. */
3582
+ interface AnchoredSurfacePoint {
3583
+ x: number;
3584
+ y: number;
3585
+ /** Pass the event target when opening from inside a modal dialog. */
3586
+ context?: Element;
3587
+ }
3588
+ /**
3589
+ * Open app-owned content beside an element. The surface owns its Kerf UI chrome;
3590
+ * kerfjs/overlay owns positioning, top-layer/modal hosting, focus, and dismissal.
3591
+ * The caller owns content, action policy, and calling `close()` when an action
3592
+ * completes. `initialFocus` defaults to the first focusable descendant; set it
3593
+ * to `false` for read-only help that should leave focus on its trigger.
3594
+ */
3595
+ declare function openAnchoredSurface(anchor: Element, content: OverlayContent, options: AnchoredSurfaceOptions): OverlayHandle;
3596
+ /**
3597
+ * Open the same surface at pointer coordinates. The temporary anchor has no
3598
+ * layout or hit target. `context` keeps a surface opened inside a modal dialog
3599
+ * in that dialog's interactive host slot; it is removed on close or failure.
3600
+ */
3601
+ declare function openAnchoredSurfaceAt(point: AnchoredSurfacePoint, content: OverlayContent, options: AnchoredSurfaceOptions): OverlayHandle;
3602
+
3603
+ export { type AnchoredSurfaceOptions, type AnchoredSurfacePoint, openAnchoredSurface, openAnchoredSurfaceAt };
3604
+ ```
package/ai/skill.md CHANGED
@@ -246,9 +246,9 @@ Hard rules:
246
246
  10. Compose `AppTab` inside controlled `TabBar`; call `wireTabBars()` once and retain its disposer. It owns same-bar drag mechanics, including proximity-based horizontal edge autoscroll, while the app applies `onReorder` and owns order, selection, panels, close policy, routing, and persistence. For a tab-local action followed by a separately pinned workspace action, set `trailingPlacement="adjacent"`, put the local action in `trailing`, and the workspace action in `end`; each action zone accepts one `ToolbarControlGroup` or a standalone `wa-button` when the action needs its own Web Awesome chrome. TabBar owns the shrinking/scrolling tabs and fixed action geometry, so do not add descendant flex overrides. Arrow/Home/End select on move by default and restore focus by bar/tab identity when controlled activation replaces the strip; pass `activation: 'manual'` (or `TabBar activation="manual"` per strip) so arrow keys move focus only and the user selects with Enter/Space/click — use it when selecting a tab is a heavy action. Use runtime-filtered `rootAttributes` for domain metadata and keep an optional `closeIcon` decorative and noninteractive.
247
247
  11. Use token-controlled `TokenSearchField` when free text and removable structured filters share one editor. Editable text stays DOM-owned between token changes; to replace the text programmatically (reseeding a persistent dialog's field on reopen, applying a saved search) change the field's `revision` along with `query` for an unmanaged field, or call `model.replace({ query, tokens })` for a model-managed field; never re-key a wrapper. The leading icon, first text line, clear action, and trailing slot share one fixed row when content wraps. For automatic parsing, chips, suggestions, and evaluation, use createTokenSearchModel with grammar rules, pass it as TokenSearchField.model, and register it in wireTokenSearchFields models; a rule's `suggest(input, state)` receives committed tokens so it can exclude selected values. Otherwise the app owns parsing and suggestions; call `readTokenSearchField()` on input, empty `textContent` on clear, use `placeTokenSearchCaret()` after explicit controlled focus changes, and call `wireTokenSearchFields()` once so Enter submits without inserting a line break and keyboard chip deletion restores focus plus the text-relative caret after controlled replacement. `clearIcon` replaces the clear action's glyph (its `clearLabel` still names it). Enable `collapsible` for an animated iconic closed state, standalone or inside `ToolbarControlGroup`; the field keeps text or tokens expanded, and `wireTokenSearchFields()` manages the transient expand/collapse/focus by default (activate to reveal + focus, Escape or empty blur to collapse). Bind the field's `expanded` to the returned handle's `expanded(id)` signal or adopt your own via `collapsible.signals`; opt a behavior out only when the app must own it. Do not hand-roll the open handler, the focusout collapse, a clear-button mousedown guard, or reopening after controlled clear or Select All deletion — the helper keeps the replacement editor open and focused. Clear and deletion restoration finish at the replacement mutation checkpoint before the next input task, so shortcut-letter typing cannot escape to the page and delayed animation frames cannot overwrite a later selection. Persist both query and tokens returned by the DOM read. For real-app adoption it also provides a focusout keep-open exception (`data-token-search-keep-open` regions or `collapsible.keepOpenOn(target)`, so a sibling suggestions/date/help surface does not collapse an empty field), opt-in atomic-chip keyboard (`keyboard`: Backspace/Delete remove the adjacent chip via `onRemoveToken`, ArrowRight moves the caret past a trailing chip), and an `onEdit({id, editor, event})` input callback (the `InputEvent` lets you gate on `inputType`/`data`) — reach for these instead of re-adding hand-rolled keydown/input handlers around the field.
248
248
  An application helper can call `model.commit(value)` for the active `name:` prefix when it computes a valid value outside suggestions; invalid values and missing prefixes leave the query unchanged.
249
- 12. Demo work uses public production component subpaths and their browser-selected CSS. Focused demos and recipes have no local stylesheet, inline style, or styling-only class; use public components and `CatalogExample.viewport` for unavoidable specimen constraints (a recipe declares its frame through its exported `presentation`). When a recipe needs a capability no component offers, report the component gap instead of adding CSS. Use exactly three demo kinds: a `component` is one component with variants/states, a `composition` is a focused container of components commonly used together, and a `recipe` is the recommended production approach to a task. Organize catalog routes into product-important functional groups; within each group put all components before compositions, order each kind by importance with display-name alphabetical tie-breaking, and put recipes after every component/composition group. Show `Composition` as an entry tag instead of repeating the word in its name. Give every public visual component its own category-grouped catalog route; list themed third-party components under a clearly labeled collapsible ecosystem section, with a focused route for each. For the complete taxonomy, focused/composition decision, `CatalogExample` / `CatalogExampleStack` row/group nesting, exact specimen selection, geometry-overlay legend and exclusions, skip-marker behavior, and metadata ownership, follow the single [Catalog demo authoring contract](../docs/catalog.md#catalog-demo-authoring-contract), discovered machine-readably through [`catalog-authoring.json`](./catalog-authoring.json). Never infer structure from private `kui-catalog-*` classes. Project each component's deterministic repository-relative demo source and existing documentation path so the detail can expose `View demo source` and `Read guidance` links without a runtime export; also derive first-party component implementation paths from their canonical browser imports, and label Web Awesome documentation as Kerf integration guidance. Declare direct `uses` relationships so `Used by` stays derivable, and theme shell chrome through the same semantic tokens as the stage instead of drawing a substitute. Enable `wireCatalog({ revealSelection: true })` for long desktop sidebars so controlled selections remain visible without moving focus; keep its default compact media guard unless compact scrolling is an explicit product behavior, and use `revealCatalogEntry` for an initial deep link.
249
+ 12. Demo work uses public production component subpaths and their browser-selected CSS. Focused demos and recipes have no local stylesheet, inline style, or styling-only class; use public components and `CatalogExample.viewport` for unavoidable specimen constraints (a recipe declares its frame through its exported `presentation`). When a recipe needs a capability no component offers, report the component gap instead of adding CSS. Use exactly three demo kinds: a `component` is one component with variants/states, a `composition` is a focused container of components commonly used together, and a `recipe` is the recommended production approach to a task. Organize catalog routes into product-important functional groups; within each group put all components before compositions, order each kind by importance with display-name alphabetical tie-breaking, and put recipes after every component/composition group. Show `Composition` as an entry tag instead of repeating the word in its name. Give every public visual component its own category-grouped catalog route; list themed third-party components under a clearly labeled collapsible ecosystem section, with a focused route for each. For the complete taxonomy, focused/composition decision, `CatalogExample` / `CatalogExampleStack` row/group nesting, specimen structure and metadata ownership, follow the single [Catalog demo authoring contract](../docs/catalog.md#catalog-demo-authoring-contract), discovered machine-readably through [`catalog-authoring.json`](./catalog-authoring.json). Never infer structure from private `kui-catalog-*` classes. Project each component's deterministic repository-relative demo source and existing documentation path so the detail can expose `View demo source` and `Read guidance` links without a runtime export; also derive first-party component implementation paths from their canonical browser imports, and label Web Awesome documentation as Kerf integration guidance. Declare direct `uses` relationships so `Used by` stays derivable, and theme shell chrome through the same semantic tokens as the stage instead of drawing a substitute. Enable `wireCatalog({ revealSelection: true })` for long desktop sidebars so controlled selections remain visible without moving focus; keep its default compact media guard unless compact scrolling is an explicit product behavior, and use `revealCatalogEntry` for an initial deep link.
250
250
  13. The Web Awesome theme makes Tooltip and Popover arrowless by default. Keep that default unless a pointer materially clarifies the anchor; opt back in with `--wa-tooltip-arrow-size`, `--kui-wa-popover-arrow-size`, or a popover's public `--arrow-size`, and use `without-arrow` when local no-arrow intent should survive theme changes. Its non-field chrome uses `--kui-wa-control-inset` (8px controls/items), `--kui-wa-surface-margin` / `--kui-wa-surface-inset` (8px around/inside Accordion, Card, Details, Callout, and Include), and `--kui-wa-container-inset` (16px Tab Panel content and framed disclosure regions). Plain Details use the 8px surface inset on the trigger and keep the body flush; plain Accordion items use it on both trigger and body. Outlined and sunken Details use the 16px container inset on the trigger and 8px on the body; framed Accordion items use 16px on both. Dialog maps its body to the 8px surface tier and its footer to the 16px container tier independently of `--spacing`. Override those tiers instead of restyling individual parts. Filled badges use each variant's quiet fill with normal text so their compact copy stays WCAG-AA readable; override the pair with `--kui-wa-badge-filled-background` / `--kui-wa-badge-filled-foreground`, not host selectors. When a dialog provides another dismissal affordance, put `hide-actions` on the `wa-dialog` host to hide its directly exported `header-actions` part; never chain `::part()` selectors through internal parts. Checkbox and Radio Group option regions, the Color Picker trigger, and Slider's complete interactive region receive the shared 8px logical inline outer inset because those controls have no bordered field shell. Known Date field captions and bordered text-like field hints align with values at the 9px border-plus-padding inset. OTP Input's label uses the same uppercase xs/650 treatment as other field labels, and both its label and hint use that 9px inset.
251
- 14. Treat the complete Web Awesome catalog as support coverage, not a recommendation list. Its UX sidebar marks superseded and exceptional entries `Discouraged`. Consider Popup when it replaces custom anchored positioning. Prefer Kerf `Select` over direct Dropdown/Dropdown Item/Select/Option composition, `SegmentedControl` over Button Group, `TabBar` or `SegmentedControl` over Web Awesome Tabs, `LucideIcon` over Web Awesome Icon, and `ResizableRegion` over Split Panel. Use Tree/Tree Item, Animated Image, and Comparison only for a specific required behavior; avoid Zoomable Frame. Never render a `Discouraged` element directly in application, demo, or recipe markup; reach it only through the Kerf component that wraps it (`PopupMenu` renders `wa-dropdown`, `Select` renders `wa-select` / `wa-option`), and treat a Kerf component gap as a request to file, not a reason to drop to the raw element.
251
+ 14. Treat the complete Web Awesome catalog as support coverage, not a recommendation list. Its UX sidebar marks superseded and exceptional entries `Discouraged`. Use `openAnchoredSurface` from `@kerfjs/ui/anchored-surface` for arbitrary interactive help or popup content beside a control, or `openAnchoredSurfaceAt` at pointer coordinates; pass an accessible label and let the app own content/actions. Consider Popup only when its lower-level behavior is specifically needed. Prefer Kerf `Select` over direct Dropdown/Dropdown Item/Select/Option composition, `SegmentedControl` over Button Group, `TabBar` or `SegmentedControl` over Web Awesome Tabs, `LucideIcon` over Web Awesome Icon, and `ResizableRegion` over Split Panel. Use Tree/Tree Item, Animated Image, and Comparison only for a specific required behavior; avoid Zoomable Frame. Never render a `Discouraged` element directly in application, demo, or recipe markup; reach it only through the Kerf component that wraps it (`PopupMenu` renders `wa-dropdown`, `Select` renders `wa-select` / `wa-option`), and treat a Kerf component gap as a request to file, not a reason to drop to the raw element.
252
252
  15. Build sidebars, main areas, inspectors, and dialogs by rendering `Pane` (`@kerfjs/ui/pane`): an unpadded `.kui-pane` root, an optional `header`, one scrolling `.kui-pane__content`, and an optional `footer`; pick landmarks with `element` / `contentElement`. Never write a component's anatomy classes (`kui-pane`, `kui-toolbar`, `kui-list-item`, …) onto your own element to recreate it — render the component (`KUI-L103`). Only the catalog's `placeableClasses` (the `.kui-content` / `.kui-scroll-owner` / `.kui-control-cluster` / `.kui-inline-metadata` layout utilities, `.kui-app-root`, and `.kui-content-item` geometry on a non-div carrier) belong on elements you write. Use `Row` instead of a hand-written flex-row wrapper, `List` instead of a hand-written flex-column wrapper, and `Grid` instead of repeated equal-track CSS when children need a fixed positive count of evenly distributed columns. `Row` defaults to left/full with an `xs` gap and no wrapping; Grid defaults to an `xs` gap and keeps each track at `minmax(0, 1fr)`; List retains full/top and zero-gap defaults. The app owns Grid's responsive column-count changes. When a Row, List, or Grid is the layout root of a definite-height parent (an app root or a fixed-height frame), pass `fill` so it takes that full height, and put route/test/recipe `data-*` markers in its `rootAttributes`; never wrap a layout in a frame `Pane` just for height or a root attribute, because its content slot becomes a scroll owner that never scrolls. Inside a flex layout use `flex`, not `fill`. Use `List` when rows or sections also need flex growth, one vertical scroll owner, or physical-edge dividers. `dividerSides`, `textInsets`, and `controlInsets` use canonical physical `t`/`r`/`b`/`l` order; text geometry wins where text and control selections overlap. `ListInsetText` and `ListInsetControl` inset all four sides by default and accept the same `sides` grammar for selective edges. A dialog body is generally a `List`: set `DialogSurface bodyInset="none"` when its list children own geometry, and wrap bare dialog prose in `ListInsetText` so it aligns with bordered siblings without a second inset. Add `.kui-content` for 24px major vertical separation and render each ordinary surface-like child as `ContentItem` (`@kerfjs/ui/content-item`) for a child-owned 8px inline margin, 1px border, 8px padding, and 12px radius. Choose `frame="framed"` (neutral border in the always-reserved 1px, same geometry) only for a real distinction and `shape="pill"` for 22px; do not hand-write `<div class="kui-content-item">` or its modifier classes. There is no filled variant: a lowered filled surface is `SunkenPanel`. Do not pad pane shells, duplicate item geometry in wrappers, or create nested scroll owners. Align text to text and icons to icons across a pane — a title, a row label, and bare prose share the same text column (`ListInsetText` puts bare text on it); a border is decoration and never the alignment anchor, so a bordered surface extends to the pane gutter instead of being indented to line its border up with a heading's text.
253
253
  15a. Use `Text` from `@kerfjs/ui/text` for ordinary headings, paragraphs, and inline secondary text outside toolbar title zones. Omit `variant` for the default `p`, pass `h1`–`h6` according to the document outline, or use `variant="span"` inside a row, label, or table cell; ordinary native attributes pass through. Express supporting, error, compact, or code text with the independent finite `tone="quiet|danger"`, `size="compact"`, and `font="monospace"` props instead of global utility classes or appearance-only heading choices. Block Text variants own a transparent 1px border and the standard item padding; `span` owns no box geometry. Keep toolbar identity/title content on `ToolbarText` and list-aligned bare prose on `ListInsetText`. `ToolbarText` below `xlarge` is intentionally quiet identity text in default tone; a normal-color subsection title is `Text` with an `h2`–`h6` variant (or `ListHeader` for a list or menu section), never a recolored `ToolbarText`. Use `controlMargins` with canonical physical Sides for an exterior 8px control gutter without a Row wrapper; avoid stacking parent insets, and remember spans retain native inline margin behavior.
254
254
 
@@ -1,6 +1,6 @@
1
1
  # Web Awesome JSX signatures for the UI authoring corpus
2
2
 
3
- Generated from the emitted `@kerfjs/ui@5.0.0-beta.82` declaration boundary. Import `@kerfjs/ui/webawesome` for type effects when authoring direct `wa-*` JSX. The module emits no runtime behavior and does not register custom elements.
3
+ Generated from the emitted `@kerfjs/ui@5.0.0-beta.84` declaration boundary. Import `@kerfjs/ui/webawesome` for type effects when authoring direct `wa-*` JSX. The module emits no runtime behavior and does not register custom elements.
4
4
 
5
5
  ```ts
6
6
  import { KerfCustomElement } from 'kerfjs/jsx-runtime';
@@ -0,0 +1,30 @@
1
+ import { PopoverOptions, OverlayContent, OverlayHandle } from 'kerfjs/overlay';
2
+
3
+ /** App-facing options for a non-modal, arbitrary-content help surface. */
4
+ interface AnchoredSurfaceOptions extends Pick<PopoverOptions, 'placement' | 'align' | 'gap' | 'dismiss' | 'initialFocus' | 'onDismiss' | 'outsideIgnore'> {
5
+ /** Accessible name for the non-modal dialog. */
6
+ label: string;
7
+ }
8
+ /** A viewport pointer location; `context` is the element under the pointer. */
9
+ interface AnchoredSurfacePoint {
10
+ x: number;
11
+ y: number;
12
+ /** Pass the event target when opening from inside a modal dialog. */
13
+ context?: Element;
14
+ }
15
+ /**
16
+ * Open app-owned content beside an element. The surface owns its Kerf UI chrome;
17
+ * kerfjs/overlay owns positioning, top-layer/modal hosting, focus, and dismissal.
18
+ * The caller owns content, action policy, and calling `close()` when an action
19
+ * completes. `initialFocus` defaults to the first focusable descendant; set it
20
+ * to `false` for read-only help that should leave focus on its trigger.
21
+ */
22
+ declare function openAnchoredSurface(anchor: Element, content: OverlayContent, options: AnchoredSurfaceOptions): OverlayHandle;
23
+ /**
24
+ * Open the same surface at pointer coordinates. The temporary anchor has no
25
+ * layout or hit target. `context` keeps a surface opened inside a modal dialog
26
+ * in that dialog's interactive host slot; it is removed on close or failure.
27
+ */
28
+ declare function openAnchoredSurfaceAt(point: AnchoredSurfacePoint, content: OverlayContent, options: AnchoredSurfaceOptions): OverlayHandle;
29
+
30
+ export { type AnchoredSurfaceOptions, type AnchoredSurfacePoint, openAnchoredSurface, openAnchoredSurfaceAt };
@@ -0,0 +1,3 @@
1
+ export { openAnchoredSurface, openAnchoredSurfaceAt } from './chunk-IOS2NXW7.js';
2
+
3
+ //# sourceMappingURL=anchored-surface.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"names":[],"mappings":"","file":"anchored-surface.js"}
package/dist/app-tab.js CHANGED
@@ -1,4 +1,4 @@
1
- export { AppTab } from './chunk-HFLGWMG3.js';
1
+ export { AppTab } from './chunk-KAJVVN7Q.js';
2
2
 
3
3
 
4
4
 
@@ -0,0 +1,3 @@
1
+ import '../styles/foundation.css';
2
+ import '../styles/anchored-surface.css';
3
+ export * from '../anchored-surface.js';
@@ -3,13 +3,13 @@ import '../styles/loading-spinner.css';
3
3
  import '../styles/toolbar-control-group.css';
4
4
  import '../styles/skeleton.css';
5
5
  import '../styles/toolbar-text.css';
6
- import '../styles/list.css';
7
6
  import '../styles/list-inset-control.css';
8
7
  import '../styles/list-inset-text.css';
9
8
  import '../styles/lucide-icon.css';
10
9
  import '../styles/token-search-field.css';
11
10
  import '../styles/resizable-region.css';
12
11
  import '../styles/toolbar.css';
12
+ import '../styles/list.css';
13
13
  import '../styles/pane.css';
14
14
  import '../styles/floating-toolbar.css';
15
15
  import '../styles/nav-stack.css';
@@ -1,11 +1,11 @@
1
- import { C as CatalogResource } from './types-C9BubXfz.js';
1
+ import { C as CatalogResource } from './types-Bn-dXLcs.js';
2
2
  import './toolbar.js';
3
3
  import 'kerfjs';
4
4
  import './semantic-content-BbzjvSu9.js';
5
5
  import './sides-BPSWde0A.js';
6
6
  import './pane.js';
7
7
  import './workbench.js';
8
- import './nav-stack-B1Qc2e5q.js';
8
+ import './nav-stack-BvSKY448.js';
9
9
  import './list.js';
10
10
  import './flex-alignment-4ms8ZbV8.js';
11
11
  import './css-values.js';
package/dist/catalog.d.ts CHANGED
@@ -1,13 +1,13 @@
1
1
  import * as kerfjs from 'kerfjs';
2
2
  import { SafeHtml } from 'kerfjs';
3
- import { a as CatalogProps } from './types-C9BubXfz.js';
4
- export { b as CatalogBrand, c as CatalogEntry, d as CatalogRelated, C as CatalogResource, e as CatalogSecondaryGroup, f as CatalogSection, g as CatalogStageRootAttributes } from './types-C9BubXfz.js';
3
+ import { a as CatalogProps } from './types-Bn-dXLcs.js';
4
+ export { b as CatalogBackgroundStyle, c as CatalogBrand, d as CatalogEntry, e as CatalogRelated, C as CatalogResource, f as CatalogSecondaryGroup, g as CatalogSection, h as CatalogStageRootAttributes } from './types-Bn-dXLcs.js';
5
5
  import { K as KerfUiContent } from './semantic-content-BbzjvSu9.js';
6
6
  import './toolbar.js';
7
7
  import './sides-BPSWde0A.js';
8
8
  import './pane.js';
9
9
  import './workbench.js';
10
- import './nav-stack-B1Qc2e5q.js';
10
+ import './nav-stack-BvSKY448.js';
11
11
  import './list.js';
12
12
  import './flex-alignment-4ms8ZbV8.js';
13
13
  import './css-values.js';
@@ -24,7 +24,7 @@ import './resizable-region.js';
24
24
  * standard toggle moves into the entry toolbar while it is collapsed, and on
25
25
  * a small screen the sidebar overlays the stage like any Workbench rail.
26
26
  */
27
- declare function Catalog({ id, brand, sections, active, content, collapsed, theme, headerActions, secondarySections, sidebarFooter, status, geometryOverlay, stageRootAttributes, selectAction, toggleSidebarAction, toggleThemeAction, toggleSecondaryAction, headerPlacement, footerPlacement, sidebar, mainToolbar, footerToolbar, className, slot, }: CatalogProps): kerfjs.SafeHtml;
27
+ declare function Catalog({ id, brand, sections, active, content, collapsed, theme, headerActions, secondarySections, sidebarFooter, status, backgroundStyle, stageRootAttributes, selectAction, toggleSidebarAction, toggleThemeAction, toggleSecondaryAction, headerPlacement, footerPlacement, sidebar, mainToolbar, footerToolbar, className, slot, }: CatalogProps): kerfjs.SafeHtml;
28
28
 
29
29
  /** How a specimen aligns its visible edge with its `ListHeader` label. */
30
30
  type CatalogExampleAlign = 'glyph' | 'inline-control' | 'text-trigger' | 'none';
package/dist/catalog.js CHANGED
@@ -1,31 +1,32 @@
1
- import { Workbench } from './chunk-LQKY5S4F.js';
1
+ import { Workbench } from './chunk-KL3W6FUN.js';
2
2
 
3
3
 
4
- import { TokenSearchField } from './chunk-3SXWV2IR.js';
4
+ import { TokenSearchField } from './chunk-VLGQIYZ5.js';
5
+ import { ToolbarText } from './chunk-3DXHNLME.js';
5
6
  import { PopupMenu } from './chunk-NJZMR7HM.js';
6
7
 
7
- import { Row } from './chunk-5D3WDMIK.js';
8
- import { ListHeader } from './chunk-VIGVNDXZ.js';
8
+ import { Row } from './chunk-MORVLMDG.js';
9
+ import { ListHeader } from './chunk-GPCAXYMT.js';
9
10
  import { Text } from './chunk-4Y4L5YEI.js';
10
11
  import { ListInsetControl } from './chunk-AN5IWMTM.js';
11
12
  import { ListInsetText } from './chunk-NMWDHZVM.js';
12
- import { ListItem } from './chunk-HFQDSSED.js';
13
- import { ToolbarText } from './chunk-VHXHLZ6R.js';
13
+ import { ListItem } from './chunk-3PO7JEK7.js';
14
14
 
15
15
 
16
16
 
17
17
 
18
18
 
19
19
 
20
- import { ToolbarControlGroup, ToolbarActionLink } from './chunk-RRCD3A6G.js';
20
+ import { ToolbarControlGroup, ToolbarActionLink } from './chunk-MTCTX25G.js';
21
21
  import { Toolbar } from './chunk-BYHGRKC3.js';
22
22
 
23
- import { List } from './chunk-NVRJ7C3W.js';
23
+ import { List } from './chunk-QQICWWNX.js';
24
+
25
+ import { LucideIcon } from './chunk-NP3FSLNX.js';
24
26
 
25
- import { LucideIcon } from './chunk-PQQQXJGV.js';
26
27
 
27
- import { filterDataAttributes } from './chunk-LAZLBC2Q.js';
28
28
 
29
+ import { filterDataAttributes } from './chunk-LAZLBC2Q.js';
29
30
  import { Moon, Sun, X, Waypoints, ExternalLink } from 'lucide';
30
31
  import { jsx, jsxs, Fragment } from 'kerfjs/jsx-runtime';
31
32
 
@@ -242,11 +243,14 @@ function CatalogSidebar({
242
243
  footer
243
244
  ] }) });
244
245
  }
245
- var protectedAttributes = /* @__PURE__ */ new Set(["data-catalog-stage"]);
246
+ var protectedAttributes = /* @__PURE__ */ new Set([
247
+ "data-catalog-stage",
248
+ "data-background-style"
249
+ ]);
246
250
  function CatalogStage({
247
251
  name,
248
252
  content,
249
- geometryOverlay,
253
+ backgroundStyle = "checkerboard",
250
254
  rootAttributes = {}
251
255
  }) {
252
256
  const safeRootAttributes = filterDataAttributes(
@@ -259,19 +263,9 @@ function CatalogStage({
259
263
  ...safeRootAttributes,
260
264
  class: "kui-catalog__stage",
261
265
  "data-catalog-stage": true,
266
+ "data-background-style": backgroundStyle,
262
267
  "aria-label": `${name} preview`,
263
- children: /* @__PURE__ */ jsxs("div", { class: "kui-catalog__canvas", children: [
264
- content,
265
- geometryOverlay !== void 0 ? /* @__PURE__ */ jsx(
266
- "div",
267
- {
268
- class: "kui-catalog__geometry-overlay",
269
- "data-catalog-geometry-overlay": true,
270
- "data-morph-skip-children": true,
271
- "aria-hidden": "true"
272
- }
273
- ) : null
274
- ] })
268
+ children: /* @__PURE__ */ jsx("div", { class: "kui-catalog__canvas", children: content })
275
269
  }
276
270
  );
277
271
  }
@@ -293,7 +287,7 @@ function Catalog({
293
287
  secondarySections,
294
288
  sidebarFooter,
295
289
  status,
296
- geometryOverlay,
290
+ backgroundStyle,
297
291
  stageRootAttributes,
298
292
  selectAction = "catalog-select",
299
293
  toggleSidebarAction = "catalog-toggle-sidebar",
@@ -317,7 +311,6 @@ function Catalog({
317
311
  class: `kui-catalog ${className}`.trim(),
318
312
  "data-component": "catalog",
319
313
  "data-sidebar-collapsed": String(collapsed),
320
- "data-geometry-overlay": geometryOverlay === void 0 ? void 0 : String(geometryOverlay),
321
314
  slot,
322
315
  children: /* @__PURE__ */ jsx(
323
316
  Workbench,
@@ -338,7 +331,17 @@ function Catalog({
338
331
  ...sidebar.toolbar,
339
332
  label: `${catalogName} header`,
340
333
  title: /* @__PURE__ */ jsxs(Fragment, { children: [
341
- brand.logoUrl ? /* @__PURE__ */ jsx(ToolbarControlGroup, { appearance: "borderless", single: true, children: /* @__PURE__ */ jsx("img", { class: "kui-catalog__mark", src: brand.logoUrl, alt: "" }) }) : null,
334
+ brand.logoUrl ? /* @__PURE__ */ jsx(
335
+ ToolbarControlGroup,
336
+ {
337
+ appearance: "borderless",
338
+ content: "avatar",
339
+ shape: "rounded",
340
+ single: true,
341
+ avatarImage: brand.logoUrl,
342
+ children: null
343
+ }
344
+ ) : null,
342
345
  /* @__PURE__ */ jsx(ToolbarText, { text: brand.title, size: "large", headingLevel: 1 })
343
346
  ] }),
344
347
  toggle: { action: toggleSidebarAction, name: catalogName }
@@ -349,7 +352,6 @@ function Catalog({
349
352
  id: `${id}-filter`,
350
353
  label: "Filter catalog",
351
354
  placeholder: "Filter items or headings",
352
- className: "kui-catalog__filter",
353
355
  editorAttributes: { "data-catalog-filter": "" },
354
356
  trailingAction: {
355
357
  icon: /* @__PURE__ */ jsx(LucideIcon, { icon: X, name: "x" }),
@@ -403,6 +405,7 @@ function Catalog({
403
405
  ) : null
404
406
  ] })
405
407
  },
408
+ mainPane: { appearance: "sunken" },
406
409
  mainFooter: /* @__PURE__ */ jsx(
407
410
  CatalogResourceFooter,
408
411
  {
@@ -424,15 +427,15 @@ function Catalog({
424
427
  ) : null,
425
428
  mainHeaderPlacement: headerPlacement,
426
429
  mainFooterPlacement: footerPlacement,
427
- main: /* @__PURE__ */ jsx(List, { flex: true, children: /* @__PURE__ */ jsx(
430
+ main: /* @__PURE__ */ jsx(
428
431
  CatalogStage,
429
432
  {
430
433
  name,
431
434
  content,
432
- geometryOverlay,
435
+ backgroundStyle,
433
436
  rootAttributes: stageRootAttributes
434
437
  }
435
- ) })
438
+ )
436
439
  }
437
440
  )
438
441
  }