@kerfjs/ui 5.0.0-beta.24 → 5.0.0-beta.26
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.
- package/README.md +44 -23
- package/ai/application-ui-diagnostic-ids-v1.json +3 -0
- package/ai/application-ui-profile.defaults.json +1 -1
- package/ai/compile-time-contracts-v1.json +3 -11
- package/ai/component-catalog-v2-overrides.json +7 -37
- package/ai/component-catalog-v2.d.ts +1 -0
- package/ai/component-catalog-v2.json +415 -91
- package/ai/component-catalog-v2.schema.json +2 -1
- package/ai/component-catalog.json +602 -158
- package/ai/public-api-signatures-v1.md +132 -65
- package/ai/skill.md +20 -20
- package/ai/webawesome-jsx-signatures-v1.md +2 -1
- package/analyzer/cli.mjs +5 -2
- package/analyzer/index.d.mts +1 -0
- package/analyzer/index.mjs +117 -10
- package/dist/app-tab.d.ts +10 -2
- package/dist/app-tab.js +1 -1
- package/dist/browser/list-action-row.js +1 -0
- package/dist/browser/list-item.js +1 -0
- package/dist/browser/surface-scaffold.js +3 -0
- package/dist/catalog.js +5 -4
- package/dist/catalog.js.map +1 -1
- package/dist/{chunk-FEAMR7S4.js → chunk-4EF2CMYS.js} +24 -5
- package/dist/chunk-4EF2CMYS.js.map +1 -0
- package/dist/{chunk-NWSEP5RT.js → chunk-FRVS5RFM.js} +23 -5
- package/dist/chunk-FRVS5RFM.js.map +1 -0
- package/dist/{chunk-PSKN344N.js → chunk-GWEAPEZI.js} +15 -2
- package/dist/chunk-GWEAPEZI.js.map +1 -0
- package/dist/chunk-HP2B2L26.js +102 -0
- package/dist/chunk-HP2B2L26.js.map +1 -0
- package/dist/{chunk-OJWWHFH3.js → chunk-JFGXQBIP.js} +49 -23
- package/dist/chunk-JFGXQBIP.js.map +1 -0
- package/dist/chunk-OBLTAKSX.js +43 -0
- package/dist/chunk-OBLTAKSX.js.map +1 -0
- package/dist/{chunk-Y45PPBDV.js → chunk-OT6RPYAP.js} +16 -2
- package/dist/chunk-OT6RPYAP.js.map +1 -0
- package/dist/{chunk-UFZKLBCF.js → chunk-VCE4MPVE.js} +25 -3
- package/dist/chunk-VCE4MPVE.js.map +1 -0
- package/dist/{chunk-5VTB2BKP.js → chunk-WNWD54GR.js} +16 -2
- package/dist/chunk-WNWD54GR.js.map +1 -0
- package/dist/{chunk-M7JBER5U.js → chunk-X2U3QJCJ.js} +8 -2
- package/dist/chunk-X2U3QJCJ.js.map +1 -0
- package/dist/{chunk-DPDBVKNA.js → chunk-YMKH5XTF.js} +5 -3
- package/dist/chunk-YMKH5XTF.js.map +1 -0
- package/dist/collapsible-panel.d.ts +9 -1
- package/dist/collapsible-panel.js +36 -15
- package/dist/collapsible-panel.js.map +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.js +12 -12
- package/dist/list-action-row.d.ts +11 -1
- package/dist/list-action-row.js +2 -1
- package/dist/list-header.d.ts +15 -2
- package/dist/list-header.js +1 -1
- package/dist/list-item.d.ts +12 -1
- package/dist/list-item.js +2 -1
- package/dist/resizable-region.d.ts +19 -2
- package/dist/resizable-region.js +1 -1
- package/dist/select.d.ts +12 -1
- package/dist/select.js +1 -1
- package/dist/split-view.js +1 -1
- package/dist/styles/app-tab.css +26 -0
- package/dist/styles/collapsible-panel.css +66 -4
- package/dist/styles/list-action-row.css +64 -0
- package/dist/styles/list-header.css +32 -0
- package/dist/styles/list-item.css +39 -0
- package/dist/styles/resizable-region.css +132 -0
- package/dist/styles/select.css +68 -0
- package/dist/styles/styles.css +1 -1
- package/dist/styles/surface-scaffold.css +51 -0
- package/dist/styles/tab-bar.css +24 -0
- package/dist/styles/toolbar-control-group.css +73 -1
- package/dist/styles/toolbar-text.css +1 -1
- package/dist/styles/webawesome.css +12 -0
- package/dist/styles/workbench.css +89 -0
- package/dist/surface-scaffold.d.ts +25 -0
- package/dist/surface-scaffold.js +3 -0
- package/dist/surface-scaffold.js.map +1 -0
- package/dist/tab-bar.d.ts +11 -2
- package/dist/tab-bar.js +1 -1
- package/dist/toolbar-control-group.d.ts +16 -2
- package/dist/toolbar-control-group.js +1 -1
- package/dist/webawesome.d.ts +1 -0
- package/dist/wire-resizable-regions.js +1 -1
- package/dist/wire-sidebar.d.ts +6 -1
- package/dist/wire-sidebar.js +27 -8
- package/dist/wire-sidebar.js.map +1 -1
- package/dist/wire-token-search-fields.js +1 -1
- package/dist/workbench.d.ts +8 -0
- package/dist/workbench.js +42 -0
- package/dist/workbench.js.map +1 -1
- package/docs/accessibility.md +55 -12
- package/docs/collapsible-panel.md +7 -0
- package/docs/component-contract.md +5 -8
- package/docs/component-selection.md +63 -33
- package/docs/design/templates.md +5 -7
- package/docs/examples/component-catalog-extension-v2.json +3 -6
- package/docs/examples/component-catalog-extension.json +1 -1
- package/docs/layout.md +7 -9
- package/docs/recipes.md +8 -7
- package/docs/surface-scaffold.md +17 -0
- package/docs/type-contracts.md +6 -8
- package/docs/ui-analyzer.md +19 -1
- package/docs/ui-doctor.md +1 -1
- package/docs/ux-demo.md +6 -3
- package/docs/webawesome-theme.md +4 -1
- package/docs/workbench.md +49 -2
- package/doctor/eslint-diagnostics.d.mts +16 -0
- package/doctor/eslint-diagnostics.mjs +17 -0
- package/doctor/index.mjs +16 -1
- package/llms.txt +19 -9
- package/package.json +7 -7
- package/ux-demo/recipes/app-shell.tsx +36 -23
- package/ux-demo/recipes/collapsible-sidebar.tsx +22 -16
- package/ux-demo/recipes/composer-form.tsx +15 -6
- package/ux-demo/recipes/list-detail-dialog.tsx +31 -15
- package/ux-demo/recipes/list-workspace-states.tsx +16 -7
- package/ux-demo/recipes/loading-inspector.tsx +39 -18
- package/ux-demo/recipes/recipes.css +7 -2
- package/ux-demo/recipes/workspace-header.tsx +17 -7
- package/dist/browser/panel-header.js +0 -7
- package/dist/chunk-5VTB2BKP.js.map +0 -1
- package/dist/chunk-7XRDUG4Y.js +0 -58
- package/dist/chunk-7XRDUG4Y.js.map +0 -1
- package/dist/chunk-DPDBVKNA.js.map +0 -1
- package/dist/chunk-FEAMR7S4.js.map +0 -1
- package/dist/chunk-M7JBER5U.js.map +0 -1
- package/dist/chunk-NENBUYX5.js +0 -79
- package/dist/chunk-NENBUYX5.js.map +0 -1
- package/dist/chunk-NWSEP5RT.js.map +0 -1
- package/dist/chunk-OJWWHFH3.js.map +0 -1
- package/dist/chunk-PSKN344N.js.map +0 -1
- package/dist/chunk-UFZKLBCF.js.map +0 -1
- package/dist/chunk-Y45PPBDV.js.map +0 -1
- package/dist/panel-header.d.ts +0 -42
- package/dist/panel-header.js +0 -7
- package/dist/panel-header.js.map +0 -1
- package/dist/styles/panel-header.css +0 -64
- package/docs/design/templates/panel-header/icon-actions-dark.svg +0 -1
- package/docs/design/templates/panel-header/icon-actions.svg +0 -1
- package/docs/design/templates/panel-header/icon-summary-actions-dark.svg +0 -1
- package/docs/design/templates/panel-header/icon-summary-actions.svg +0 -1
- package/docs/design/templates/panel-header/no-icon-dark.svg +0 -1
- package/docs/design/templates/panel-header/no-icon.svg +0 -1
- package/docs/design/templates/panel-header/page-heading-dark.svg +0 -1
- package/docs/design/templates/panel-header/page-heading.svg +0 -1
- package/docs/design/templates/panel-header/title-only-dark.svg +0 -1
- package/docs/design/templates/panel-header/title-only.svg +0 -1
- package/docs/design/templates/panel-header-dark.svg +0 -1
- package/docs/design/templates/panel-header.svg +0 -1
package/docs/type-contracts.md
CHANGED
|
@@ -19,11 +19,10 @@ public-signature artifact.
|
|
|
19
19
|
| `KUI-T004` | A literal `SegmentedControl.value` belongs to its literal `choices`. |
|
|
20
20
|
| `KUI-T005` | `expanded`, `expandAction`, and `expandLabel` exist only on `TokenSearchField({ collapsible: true })`. |
|
|
21
21
|
| `KUI-T006` | `TokenSearchEditorAttributes` accepts application `data-*` metadata but rejects component-owned identity, morph, count, and placeholder attributes. |
|
|
22
|
-
| `KUI-T007` | `
|
|
23
|
-
| `KUI-T008` | `
|
|
24
|
-
| `KUI-T009` |
|
|
25
|
-
| `KUI-T010` |
|
|
26
|
-
| `KUI-T011` | Finite public variants have named exported union types, including divider sides, tab activation, banner urgency, and all ToolbarControlGroup presentation axes. |
|
|
22
|
+
| `KUI-T007` | `ToolbarText.maxLines` requires `wrap: true`; it is never silently ignored in typed code. |
|
|
23
|
+
| `KUI-T008` | A literal `TabScaffold.active` id belongs to its literal `tabs`. |
|
|
24
|
+
| `KUI-T009` | Adjacent-token keyboard removal requires `onRemoveToken`; disabling removal rejects the now-meaningless callback. |
|
|
25
|
+
| `KUI-T010` | Finite public variants have named exported union types, including divider sides, tab activation, banner urgency, and all ToolbarControlGroup presentation axes. |
|
|
27
26
|
|
|
28
27
|
Literal identity inference is intentionally additive for dynamic applications.
|
|
29
28
|
When choices or ids arrive at runtime and the state signal is correctly typed as
|
|
@@ -45,7 +44,7 @@ ordinary source/type gates:
|
|
|
45
44
|
|
|
46
45
|
- required identity or accessible-name inputs on `AppTab`, `FloatingToolbar`,
|
|
47
46
|
`NavStack`, `SplitView`, `Workbench`, `TabBar`, `ResizableRegion`,
|
|
48
|
-
`SegmentedControl`, `TokenSearchField`,
|
|
47
|
+
`SegmentedControl`, `TokenSearchField`, and `ValueTable`;
|
|
49
48
|
- finite variants exported or represented as literal props on `DisclosureArrow`,
|
|
50
49
|
`FloatingToolbar`, `Pane`, `ResizableRegion`, `SegmentedControl`, `StateBanner`,
|
|
51
50
|
`SunkenPanel`, `ToolbarText`, `CollapsiblePanel`, `Catalog`, and the wire helpers;
|
|
@@ -92,8 +91,7 @@ move errors into casts without making the integration safer.
|
|
|
92
91
|
`{ keyboard: { onRemoveToken } }` or
|
|
93
92
|
`{ keyboard: { removeAdjacentToken: false } }` when only caret navigation is
|
|
94
93
|
wanted.
|
|
95
|
-
-
|
|
96
|
-
`wrap: true` anywhere `ToolbarText.maxLines` is used.
|
|
94
|
+
- Add `wrap: true` anywhere `ToolbarText.maxLines` is used.
|
|
97
95
|
- Replace `Toolbar({ divider: false })` with `dividerSides: ''`; the default
|
|
98
96
|
remains a bottom divider, while canonical combinations such as `tr` and
|
|
99
97
|
`trbl` select more physical edges.
|
package/docs/ui-analyzer.md
CHANGED
|
@@ -46,6 +46,9 @@ policy, or analysis inputs to the containing application.
|
|
|
46
46
|
| `KUI-L007` | error | A declared scroll owner is nested inside another scroll owner. |
|
|
47
47
|
| `KUI-L008` | review | A dynamic class expression cannot be classified soundly. |
|
|
48
48
|
| `KUI-L009` | error | A stylesheet cannot be parsed. |
|
|
49
|
+
| `KUI-L010` | error | A selector reaches a private Kerf descendant from a public root. |
|
|
50
|
+
| `KUI-L011` | error | A `::part()` target is not cataloged as a public extension point. |
|
|
51
|
+
| `KUI-L012` | error | CSS assigns a Kerf token without a public configuration contract. |
|
|
49
52
|
|
|
50
53
|
Errors are provable contract violations and make the command exit 1. Review
|
|
51
54
|
findings are deliberately heuristic and do not fail by default; pass
|
|
@@ -53,6 +56,20 @@ findings are deliberately heuristic and do not fail by default; pass
|
|
|
53
56
|
gate CI. Text, versioned JSON, and SARIF carry the same stable rule ids,
|
|
54
57
|
source locations, evidence, and ownership chain.
|
|
55
58
|
|
|
59
|
+
For staged adoption, pass `--adoption`. Ownership-boundary diagnostics are
|
|
60
|
+
reported as review findings so a team can inventory and migrate its baseline;
|
|
61
|
+
combine it with the exact file-and-rule exceptions below for intentional legacy
|
|
62
|
+
integrations. Remove `--adoption` to make unsupported overrides blocking.
|
|
63
|
+
|
|
64
|
+
Catalog `boundaries.publicClasses` and `boundaries.publicTokens` are explicit
|
|
65
|
+
CSS extension points. A component catalog may additionally list shadow-part
|
|
66
|
+
names in `boundaries.publicParts`; all other `::part()` targets are private.
|
|
67
|
+
Part names are scoped to that entry's `boundaries.rootClass`, so an extension
|
|
68
|
+
point on one component does not authorize the same-named part on another.
|
|
69
|
+
Parent-owned placement and selectors for application-owned content remain
|
|
70
|
+
allowed because the analyzer only reserves `.kui-*`, `--kui-*`, and cataloged
|
|
71
|
+
shadow boundaries.
|
|
72
|
+
|
|
56
73
|
The JSON report schema is exported as
|
|
57
74
|
`@kerfjs/ui/analyzer/report.schema.json`.
|
|
58
75
|
|
|
@@ -82,5 +99,6 @@ validator.
|
|
|
82
99
|
```
|
|
83
100
|
|
|
84
101
|
Review findings remain visible until explicitly suppressed. Avoid suppressing
|
|
85
|
-
`KUI-L001`, `KUI-L002`, `KUI-L003`, `KUI-L007`,
|
|
102
|
+
`KUI-L001`, `KUI-L002`, `KUI-L003`, `KUI-L007`, `KUI-L009`, `KUI-L010`,
|
|
103
|
+
`KUI-L011`, or `KUI-L012`: those indicate a
|
|
86
104
|
definite boundary or parsing failure rather than an aesthetic judgment.
|
package/docs/ui-doctor.md
CHANGED
|
@@ -15,7 +15,7 @@ The default terminal output is short and repair-oriented. `--format json` emits
|
|
|
15
15
|
|
|
16
16
|
The catalog stage discovers the package-default application UI profile and workspace/root-to-leaf directory layers. It validates referenced selection/composition catalogs and, when a workspace declares `package.json#kerfComponentCatalog`, invokes the installed `create-kerf-component` catalog checker to validate metadata, source exports, schema conformance, and generated-output drift. This checker reads source text; it does not import application modules.
|
|
17
17
|
|
|
18
|
-
TypeScript uses the compiler API with `noEmit`. ESLint loads the installed `eslint-plugin-kerfjs` `recommended-ui` preset (`--eslint strict-ui` opts into advisory rules as errors). This is deliberately an isolated Kerf lint pass rather than the consumer's complete ESLint configuration.
|
|
18
|
+
TypeScript uses the compiler API with `noEmit`. ESLint loads the installed `eslint-plugin-kerfjs` `recommended-ui` preset (`--eslint strict-ui` opts into advisory rules as errors). This is deliberately an isolated Kerf lint pass rather than the consumer's complete ESLint configuration. For each file, the doctor projects the applicable core ESLint rules and `linterOptions` from the consumer configuration so core-rule suppression directives retain the same used/unused semantics as the application's normal lint command. Consumer plugin rules are not executed, and inline directives for plugins such as `@typescript-eslint` therefore do not produce false "rule definition not found" diagnostics; the consumer's normal ESLint command remains authoritative for those rules. Unknown `kerfjs/*` directives still fail the doctor pass. Stable KUI identifiers come from the packaged `application-ui-diagnostic-ids-v1.json` registry; the doctor also reads installed ESLint message metadata for semantic conflict detection instead of duplicating rule definitions. The analyzer calls the public `@kerfjs/ui/analyzer` contract. None of these stages executes generated application code.
|
|
19
19
|
|
|
20
20
|
The browser evaluator is different: it runs the application and is disabled by default. It only runs when configuration supplies `browser.url` or the command receives `--browser-url`. Start and authorize the target application separately.
|
|
21
21
|
|
package/docs/ux-demo.md
CHANGED
|
@@ -13,15 +13,18 @@ deterministic state, and semantic layout owners from the [recipe guide](./recipe
|
|
|
13
13
|
- `ai/component-catalog.json` is the canonical catalog metadata. A deterministic checked-in projection supplies the demo's unique id, category, kind (`component`, `composition`, or `recipe`), source (`kerf` or `webawesome`), name, description, recommendation, direct `uses` dependencies, existing documentation path, and demo-source path; first-party, recipe, and Web Awesome renderer maps are exhaustively typed against its generated id unions. Non-supported Web Awesome recommendations project to a visible `Discouraged` sidebar tag, with Popup as the deliberate conditional exception. Demo paths resolve to the matching `ui/ux-demo/demos/<id>.tsx` or `ui/ux-demo/recipes/*.tsx` file, or to `ui/ux-demo/webawesome-demos.tsx` for Web Awesome entries. `ui/ux-demo/main.tsx` owns only the catalog shell, shared state, routing, and interaction wiring. First-party component entries additionally derive `ui/src/<public-subpath>.tsx` from their canonical `delivery.browserImport` or opt-in `delivery.moduleImport`.
|
|
14
14
|
- Every detail footer groups compact `Demo source` and `Guidance` actions; first-party component details also expose `Component source`. Web Awesome details say `Integration guidance` to distinguish the local integration contract from the upstream component implementation. Each button retains its repository-relative path in the DOM for verification and uses a deploy-safe absolute GitHub blob URL with a contextual new-tab name; the demo does not depend on a local source server or add a package runtime export. At phone widths, the resource group and related-component selector stack as full-width rows, with any resource overflow contained locally so labels cannot overlap the selector or widen the document.
|
|
15
15
|
- The master/detail shell groups first-party routes by category with production `ListHeader` and `ListItem` components. Catalog entries can supply short reusable trailing tags; the Web Awesome projection uses them to label exactly the 15 discouraged choices. The 70 ecosystem components live in a separate `Web Awesome` disclosure with seven subgroups, so they remain discoverable without being presented as first-class `@kerfjs/ui` exports. Direct Web Awesome routes open the disclosure and reveal the selected row at wide sizes; narrow layouts keep the expanded list in document flow rather than introducing a competing nested scroller.
|
|
16
|
-
- The shell itself uses `@kerfjs/ui/layout.css`: sidebars, details, previews, dialogs, and resize specimens share unpadded panes plus self-contained content items. Its sidebar identity uses the Kerf logo beside a vertically centered title, with
|
|
17
|
-
- The composer-form recipe demonstrates one coherent visible form surface with
|
|
16
|
+
- The shell itself uses `@kerfjs/ui/layout.css`: sidebars, details, previews, dialogs, and resize specimens share unpadded panes plus self-contained content items. Its sidebar identity uses the Kerf logo beside a vertically centered title, with supporting copy in its own aligned row; the current-view heading is also a toolbar. Collapsing the catalog removes the pane completely and moves its restore action to the main toolbar's leading edge instead of leaving an icon-only rail. The selected view description remains inset below the page toolbar. The checkerboard belongs to the complete scrollable preview region rather than a nested card. A lightly separated footer keeps live status above compact source, guidance, and relationship groups. The focused `ResizableRegion` specimen stretches its surface through the available stage height and reports committed width in that shared status footer; narrow layouts retain local horizontal access when the pane is resized wider than the stage, and the split remains readable at 200% root scaling. Geometry coverage checks wide, intermediate, narrow, and 200% zoom layouts.
|
|
17
|
+
- The composer-form recipe demonstrates one coherent visible form surface with toolbar title/supporting-copy hierarchy, fields and actions on the shared 8px control gutter, and 24px major rhythm. Its conditional error or success `StateBanner` is the only nested semantic surface. Reset synchronizes the upgraded Web Awesome fields' live value properties with their empty controlled attributes and announces `Draft reset`; browser coverage preserves behavior and verifies wide, narrow, dark, validation, success, reset, 200% zoom, and forced-colors states.
|
|
18
18
|
- The list-detail dialog recipe places its header directly on the dialog edge while preserving the header's internal inset, gives the selected project title the complete outer-plus-inner content gutter, lets the value table fill the available detail column between the shared outer margins, and keeps record actions on one outer gutter without an extra content-item inset. Browser geometry coverage protects those relationships at wide and narrow widths.
|
|
19
19
|
- Catalog-only brand marks, preview dimensions, checkerboard tiles, and the compound display-settings control retain local geometry because they are specimen chrome or intrinsic control anatomy rather than reusable application spacing roles.
|
|
20
20
|
- The menu composition route demonstrates toolbar/content/footer anatomy, 24px major gaps, 8/1/8 child geometry, the full-width `ListHeader` count-or-badge/action split, logical-end 44px action targets with 18px visuals, and 44px row/header/toolbar targets. Its one chevron is a production 18px `DisclosureArrow` inside a controlled Tools header that actually reveals and hides content; ordinary Projects navigation has no false disclosure affordance. Browser assertions cover stable naming, expanded/content transitions, visual rotation, node identity, reduced motion, RTL alignment and containment, and wide, narrow, dark, and 200% layouts. The focused ListHeader route separately shows the shared neutral count pill for Attachments, Notes (including zero), and Duplicates plus a non-count legacy badge, full-width logical-end actions, and no disclosure without content.
|
|
21
21
|
- The `DisclosureArrow` route renders the production 18px root-scaled default without a catalog-only size override. Its two native buttons independently control the default right-to-down chevron and a recognizable right-facing replacement arrow with left-to-up custom directions; both use shortest-path rotation and their names stay stable while `aria-expanded` communicates state. Browser coverage verifies the custom clockwise path, pointer and native keyboard activation, focus, narrow and 200%-zoom stacking with contained labels, consumer sizing, and the independent `.5` Web Awesome glyph scale retained by Kerf `Select`.
|
|
22
22
|
- A detail with relationships renders one grouped footer selector: `Uses` links to direct dependencies and `Used by` links to reverse dependents. Choosing either navigates to that component's demo. The relationship group is absent when both sets are empty; no duplicate summary is rendered.
|
|
23
23
|
- Demo-only CSS supplies only the catalog shell and stages; component appearance stays in package CSS. Decorative chrome and Web Awesome controls share the same semantic system palette instead of carrying a separate demo identity.
|
|
24
|
-
- Scenarios use deterministic data and cover real variants, long content, disabled state, selection, progress, feedback, overlays, media, helpers, and stateful interactions. The Web Awesome theme route remains the broad system view, while individual action, form, layout, navigation, feedback, media, and helper routes provide focused specimens; ListItem and ListHeader demonstrate typed domain metadata, protected native button/disclosure semantics, and a native popover trigger relationship without product props;
|
|
24
|
+
- Scenarios use deterministic data and cover real variants, long content, disabled state, selection, progress, feedback, overlays, media, helpers, and stateful interactions. The Web Awesome theme route remains the broad system view, while individual action, form, layout, navigation, feedback, media, and helper routes provide focused specimens; ListItem and ListHeader demonstrate typed domain metadata, protected native button/disclosure semantics, and a native popover trigger relationship without product props; the Headers composition demonstrates direct toolbar headings with an extra-large title, optional supporting copy, and grouped icon/actions; the Select route verifies that option icons survive unrelated Kerf rerenders and selected slot content follows value changes; the Animation route exposes preset, easing, duration, playback-rate, and transport controls with live lifecycle status; observer routes provide user-driven intersection, mutation, and resize events with live results; ToolbarControlGroup exposes all eight Hot Sheet 2 variants, loads the Web Awesome registrations needed by its popup specimen, and preserves the upgraded dropdown's managed light-DOM children across Kerf rerenders; the Toolbar route composes a collapsible TokenSearchField inside a group, animates between the empty iconic and complete field states, stays open while populated, and focuses the revealed editor; SegmentedControl covers toolbar, rounded-rectangle, pill, equal-width, and disabled presentations; TokenSearchField covers editable ordered chips, pointer and keyboard removal, caret-preserving controlled deletion, editing, clearing, free text, disabled state, and fixed first-line alignment while content wraps; StateBanner exposes every built-in tone with tone-tinted badges plus a scoped override; TabBar demonstrates overflow, edge autoscroll, and controlled pointer/keyboard reordering.
|
|
25
|
+
- The ToolbarControlGroup route also demonstrates the public compact/tight,
|
|
26
|
+
mixed-content, filled-selection, nested-dropdown, and avatar/scrim contracts
|
|
27
|
+
added for consumers that previously restyled group descendants.
|
|
25
28
|
- Recipe ownership notes are hidden by default. A page-toolbar toggle reveals them as floating warning-toned notes with a folded corner, keeping instructional copy visually distinct and removable from the specimen flow.
|
|
26
29
|
- Settings exercise light/dark, increased contrast, and reduced motion without changing component code. The theme action starts from the operating system's effective color scheme, always names the appearance it will switch to, and installs an explicit light or dark override when activated; contrast and reduced motion expose their independent preferences through `aria-pressed`.
|
|
27
30
|
- The footer action log is an `aria-live` region, making interactions visible to both people and browser tests.
|
package/docs/webawesome-theme.md
CHANGED
|
@@ -98,7 +98,10 @@ tiers:
|
|
|
98
98
|
once to the group rather than separating connected items; Card's header,
|
|
99
99
|
body, and footer all receive the full inset.
|
|
100
100
|
- `--kui-wa-container-inset` defaults to the 16px homogeneous-group step. Tab
|
|
101
|
-
Panel retains this roomier tier for unframed panel content.
|
|
101
|
+
Panel retains this roomier tier for unframed panel content. Dialog body uses
|
|
102
|
+
the 8px surface inset, while its footer uses the 16px container inset so
|
|
103
|
+
content stays compact and the action group has a clearer boundary. These two
|
|
104
|
+
parts do not inherit the dialog's shared `--spacing` value.
|
|
102
105
|
|
|
103
106
|
Badge remains intentionally compact at Web Awesome's intrinsic `0.375em` block /
|
|
104
107
|
`0.625em` inline padding (4.5px / 7.5px at its default 12px text size): it is a
|
package/docs/workbench.md
CHANGED
|
@@ -47,7 +47,54 @@ const navCollapsed = signal(false);
|
|
|
47
47
|
Each `WorkbenchPanel` takes `content`, an optional `collapsed`, an optional
|
|
48
48
|
`size` (rail width or drawer height in px, overriding the CSS default —
|
|
49
49
|
`--kui-workbench-rail-width` 280px, `--kui-workbench-drawer-height` 220px), and
|
|
50
|
-
an optional `label`.
|
|
50
|
+
an optional `label`. Common shell behavior is configured rather than restyled:
|
|
51
|
+
|
|
52
|
+
- `separator: "auto" | "hidden"` controls the owned dock-edge separator;
|
|
53
|
+
- `collapseMotion: "slide" | "fade-slide" | "none"` keeps the track change
|
|
54
|
+
instant while choosing composited content motion;
|
|
55
|
+
- `contentOverflow: "clip" | "auto" | "visible"` lets a drawer temporarily
|
|
56
|
+
expose an open popup without a descendant override;
|
|
57
|
+
- `presentation: "inline" | "overlay" | "hidden"` supports compact overlays
|
|
58
|
+
or a responsive replacement;
|
|
59
|
+
- `restoreControl` places an application-owned restore affordance in a
|
|
60
|
+
safe-area-aware viewport corner (`restorePosition` chooses the corner).
|
|
61
|
+
|
|
62
|
+
The same policy props are available on `ResizableRegion` and
|
|
63
|
+
`CollapsiblePanel`, so a resizable application shell does not need to reach
|
|
64
|
+
into `.kui-resizable-region__content`.
|
|
65
|
+
|
|
66
|
+
## Resizable application-shell migration
|
|
67
|
+
|
|
68
|
+
An application such as Hot Sheet can replace its shell descendant overrides
|
|
69
|
+
with state-derived props:
|
|
70
|
+
|
|
71
|
+
```tsx
|
|
72
|
+
<ResizableRegion
|
|
73
|
+
id="terminal-drawer"
|
|
74
|
+
label="Terminal drawer"
|
|
75
|
+
axis="vertical"
|
|
76
|
+
edge="start"
|
|
77
|
+
size={drawerSize.value}
|
|
78
|
+
min={180}
|
|
79
|
+
max={520}
|
|
80
|
+
collapsed={!drawerVisible.value}
|
|
81
|
+
separator={magnified.value ? "hidden" : "auto"}
|
|
82
|
+
collapseMotion="fade-slide"
|
|
83
|
+
contentOverflow={createMenuOpen.value ? "visible" : "clip"}
|
|
84
|
+
presentation={mobile.value ? "overlay" : "inline"}
|
|
85
|
+
restoreControl={<button data-action="show-drawer">Show terminals</button>}
|
|
86
|
+
>
|
|
87
|
+
<TerminalDrawer />
|
|
88
|
+
</ResizableRegion>
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
`wireResizableRegions` marks the active region with `data-resizing` and the
|
|
92
|
+
package CSS suppresses content motion during pointer resize. A collapsed,
|
|
93
|
+
overlay, or hidden region is not resizeable. Together these policies replace
|
|
94
|
+
app CSS for separator suppression, instant-track/composited-content collapse,
|
|
95
|
+
popup overflow, mobile overlay/hidden replacement, resize-transition guards,
|
|
96
|
+
and safe-area restore placement. The app still owns the signals and decides
|
|
97
|
+
when each policy applies.
|
|
51
98
|
|
|
52
99
|
## Public styling boundary
|
|
53
100
|
|
|
@@ -57,7 +104,7 @@ Workbench instance. The supported composition classes are `.kui-workbench`,
|
|
|
57
104
|
`.kui-workbench__rail`, `.kui-workbench__rail--left`,
|
|
58
105
|
`.kui-workbench__rail--right`, `.kui-workbench__center`,
|
|
59
106
|
`.kui-workbench__main`, `.kui-workbench__drawer`, and
|
|
60
|
-
`.kui-workbench__panel-content`; these exact hooks are cataloged for tools that
|
|
107
|
+
`.kui-workbench__panel-content`, and `.kui-workbench__restore`; these exact hooks are cataloged for tools that
|
|
61
108
|
must classify public application selectors. Prefer the component props and two
|
|
62
109
|
size tokens before selecting internal anatomy, and do not target its data
|
|
63
110
|
attributes or descendant tags as styling contracts.
|
|
@@ -6,3 +6,19 @@ export interface EslintDiagnosticLike {
|
|
|
6
6
|
export function isForeignRuleDefinitionDiagnostic(
|
|
7
7
|
item: EslintDiagnosticLike,
|
|
8
8
|
): boolean;
|
|
9
|
+
|
|
10
|
+
export interface ConsumerEslintConfigLike {
|
|
11
|
+
rules?: Record<string, unknown>;
|
|
12
|
+
linterOptions?: Record<string, unknown>;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export interface ProjectedConsumerCoreConfig {
|
|
16
|
+
files: string[];
|
|
17
|
+
rules?: Record<string, unknown>;
|
|
18
|
+
linterOptions?: Record<string, unknown>;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export function projectConsumerCoreConfig(
|
|
22
|
+
config: ConsumerEslintConfigLike | undefined,
|
|
23
|
+
file: string,
|
|
24
|
+
): ProjectedConsumerCoreConfig | undefined;
|
|
@@ -5,3 +5,20 @@ export function isForeignRuleDefinitionDiagnostic(item) {
|
|
|
5
5
|
item.message === `Definition for rule '${item.ruleId}' was not found.`
|
|
6
6
|
);
|
|
7
7
|
}
|
|
8
|
+
|
|
9
|
+
export function projectConsumerCoreConfig(config, file) {
|
|
10
|
+
const rules = Object.fromEntries(
|
|
11
|
+
Object.entries(config?.rules ?? {}).filter(
|
|
12
|
+
([ruleId]) => !ruleId.includes('/'),
|
|
13
|
+
),
|
|
14
|
+
);
|
|
15
|
+
const linterOptions = config?.linterOptions
|
|
16
|
+
? { ...config.linterOptions }
|
|
17
|
+
: undefined;
|
|
18
|
+
if (Object.keys(rules).length === 0 && !linterOptions) return undefined;
|
|
19
|
+
return {
|
|
20
|
+
files: [file],
|
|
21
|
+
...(Object.keys(rules).length > 0 ? { rules } : {}),
|
|
22
|
+
...(linterOptions ? { linterOptions } : {}),
|
|
23
|
+
};
|
|
24
|
+
}
|
package/doctor/index.mjs
CHANGED
|
@@ -23,7 +23,10 @@ import { createRequire } from 'node:module';
|
|
|
23
23
|
import { loadApplicationUiProfile } from '../ai/application-ui-profile.mjs';
|
|
24
24
|
import { analyzeUiProject, UI_ANALYSIS_RULES } from '../analyzer/index.mjs';
|
|
25
25
|
import { evaluateUi, UI_EVALUATION_RULES } from '../evaluator/index.mjs';
|
|
26
|
-
import {
|
|
26
|
+
import {
|
|
27
|
+
isForeignRuleDefinitionDiagnostic,
|
|
28
|
+
projectConsumerCoreConfig,
|
|
29
|
+
} from './eslint-diagnostics.mjs';
|
|
27
30
|
import {
|
|
28
31
|
isUiTraversalExcluded,
|
|
29
32
|
UI_TRAVERSAL_ESLINT_IGNORES,
|
|
@@ -869,6 +872,18 @@ async function runEslint({
|
|
|
869
872
|
});
|
|
870
873
|
}
|
|
871
874
|
configs.push(preset);
|
|
875
|
+
const consumerEslint = new ESLint({ cwd: packageRoot });
|
|
876
|
+
if (await consumerEslint.findConfigFile()) {
|
|
877
|
+
const consumerCoreConfigs = await Promise.all(
|
|
878
|
+
inputs.map(async (file) =>
|
|
879
|
+
projectConsumerCoreConfig(
|
|
880
|
+
await consumerEslint.calculateConfigForFile(file),
|
|
881
|
+
portablePath(packageRoot, file),
|
|
882
|
+
),
|
|
883
|
+
),
|
|
884
|
+
);
|
|
885
|
+
configs.push(...consumerCoreConfigs.filter(Boolean));
|
|
886
|
+
}
|
|
872
887
|
const eslint = new ESLint({
|
|
873
888
|
cwd: packageRoot,
|
|
874
889
|
overrideConfigFile: true,
|
package/llms.txt
CHANGED
|
@@ -86,8 +86,10 @@ maintain a central style list. Configure JSX with `"jsxImportSource": "kerfjs"`.
|
|
|
86
86
|
`--kui-wa-control-inset` (8px controls/items) and
|
|
87
87
|
`--kui-wa-surface-margin` / `--kui-wa-surface-inset` (8px around/inside
|
|
88
88
|
Accordion, Card, Details, Callout, and Include), while
|
|
89
|
-
`--kui-wa-container-inset` keeps Tab Panel at 16px.
|
|
90
|
-
|
|
89
|
+
`--kui-wa-container-inset` keeps Tab Panel at 16px. Dialog body and footer use
|
|
90
|
+
the surface (8px) and container (16px) tiers respectively, independent of the
|
|
91
|
+
dialog's shared `--spacing`. Override the tier at the narrowest useful scope
|
|
92
|
+
instead of restyling individual shadow parts.
|
|
91
93
|
Checkbox and Radio Group option regions also receive the shared 8px inline
|
|
92
94
|
outer inset because those groups have no bordered field shell. The Color
|
|
93
95
|
Picker trigger receives the same inset for the same unbordered geometry.
|
|
@@ -97,6 +99,11 @@ maintain a central style list. Configure JSX with `"jsxImportSource": "kerfjs"`.
|
|
|
97
99
|
with field values at the shared 9px border-plus-padding inset. OTP Input's
|
|
98
100
|
label uses the same uppercase xs/650 treatment and its label and hint share
|
|
99
101
|
that 9px alignment.
|
|
102
|
+
- `Select` requires a visible `label` or an `ariaLabel` for a visually hidden
|
|
103
|
+
accessible name. The package names the internal combobox, including custom
|
|
104
|
+
selected content; consumers do not need shadow-DOM naming workarounds.
|
|
105
|
+
Use `hint` for supporting text below the control and `placeholderText` only
|
|
106
|
+
for the empty value inside it; loading placeholders retain the visible hint.
|
|
100
107
|
- **Trust the defaults.** Render a control at its natural size and color (a
|
|
101
108
|
`LucideIcon` is 24px); if it looks wrong, fix the surrounding layout, not the
|
|
102
109
|
control. Never force a component's width/height to size it — that leaves a halo
|
|
@@ -111,10 +118,11 @@ maintain a central style list. Configure JSX with `"jsxImportSource": "kerfjs"`.
|
|
|
111
118
|
popup menu. A toolbar popup menu is a `single` `ToolbarControlGroup` around a
|
|
112
119
|
`wa-dropdown` (its `slot="trigger"` `wa-button` is the toolbar button, kept under
|
|
113
120
|
`data-morph-skip-children`).
|
|
114
|
-
-
|
|
115
|
-
optional
|
|
116
|
-
|
|
117
|
-
|
|
121
|
+
- **Use one direct toolbar composition for panel/dialog/page headings.** Put an
|
|
122
|
+
optional icon in a `ToolbarControlGroup`, an extra-large `ToolbarText` directly
|
|
123
|
+
in the leading zone, and actions in a trailing group. Supporting copy is
|
|
124
|
+
app-owned content below. Do not create a private heading wrapper or restyle the
|
|
125
|
+
toolbar.
|
|
118
126
|
- **Space by the five-step scale, by relationship not by eye.** `0`
|
|
119
127
|
`--kui-space-none`, `4px` `--kui-space-2xs`, `8px` `--kui-space-xs` (inside a
|
|
120
128
|
group), `16px` `--kui-space-m`, `24px` `--kui-space-l` (between major differing
|
|
@@ -137,7 +145,9 @@ maintain a central style list. Configure JSX with `"jsxImportSource": "kerfjs"`.
|
|
|
137
145
|
replacement focus after controlled automatic tab activation,
|
|
138
146
|
`wireResizableRegions` the live drag preview; they report committed changes via
|
|
139
147
|
callbacks. Managed TokenSearchField clear also preserves open state and replacement
|
|
140
|
-
editor focus for continued typing.
|
|
148
|
+
editor focus for continued typing. Select All deletion does the same; deletion
|
|
149
|
+
restoration finishes before the next keystroke rather than on a delayed frame.
|
|
150
|
+
Persist both query and remaining tokens read from an edited field. The one richer case is `wireTokenSearchFields`, which manages the
|
|
141
151
|
collapsible field's expand/collapse/focus by default (on, per-behavior opt-out) and
|
|
142
152
|
exposes the `expanded` signal on its handle — bind it in render or hand in your own
|
|
143
153
|
via `collapsible.signals`. Do not hand-roll open/collapse/focus that helper
|
|
@@ -151,7 +161,7 @@ maintain a central style list. Configure JSX with `"jsxImportSource": "kerfjs"`.
|
|
|
151
161
|
boilerplate while still owning parsing and controlled token state.
|
|
152
162
|
- **Placeholder loading state, don't rebuild it.** For a value or component that is
|
|
153
163
|
still loading, set `placeholder` on the component (`Select`, `ListHeader`,
|
|
154
|
-
`ListItem`, `ValueTableRow`, `
|
|
164
|
+
`ListItem`, `ValueTableRow`, `SegmentedControl`, `StateBanner`,
|
|
155
165
|
`AppTab`, `ToolbarText`, `ListActionRow`): it renders its real chrome with value
|
|
156
166
|
slots as subtle **unanimated** skeleton blocks and interactivity disabled, so a
|
|
157
167
|
parent composes a faithful loading view (e.g. an inspector) without hand-rebuilding
|
|
@@ -166,7 +176,7 @@ maintain a central style list. Configure JSX with `"jsxImportSource": "kerfjs"`.
|
|
|
166
176
|
## Public exports
|
|
167
177
|
|
|
168
178
|
`LucideIcon`, `DisclosureArrow`, `Toolbar`, `ToolbarControlGroup`, `FloatingToolbar`, `ToolbarText`,
|
|
169
|
-
`
|
|
179
|
+
`ListItem`, `ListActionRow`, `ListHeader`, `ListInsetControl`,
|
|
170
180
|
`ListInsetText`, `SegmentedControl`,
|
|
171
181
|
`Select`, `TokenSearchField` (+ `readTokenSearchField`, `placeTokenSearchCaret`,
|
|
172
182
|
`wireTokenSearchFields`), `AppTab`, `TabBar` (+ `wireTabBars`, `reorderTabs`),
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kerfjs/ui",
|
|
3
|
-
"version": "5.0.0-beta.
|
|
3
|
+
"version": "5.0.0-beta.26",
|
|
4
4
|
"description": "Accessible, composable UI primitives for kerf applications.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -64,6 +64,11 @@
|
|
|
64
64
|
"browser": "./dist/browser/toolbar-control-group.js",
|
|
65
65
|
"import": "./dist/toolbar-control-group.js"
|
|
66
66
|
},
|
|
67
|
+
"./surface-scaffold": {
|
|
68
|
+
"types": "./dist/surface-scaffold.d.ts",
|
|
69
|
+
"browser": "./dist/browser/surface-scaffold.js",
|
|
70
|
+
"import": "./dist/surface-scaffold.js"
|
|
71
|
+
},
|
|
67
72
|
"./floating-toolbar": {
|
|
68
73
|
"types": "./dist/floating-toolbar.d.ts",
|
|
69
74
|
"browser": "./dist/browser/floating-toolbar.js",
|
|
@@ -248,11 +253,6 @@
|
|
|
248
253
|
"browser": "./dist/browser/empty-state.js",
|
|
249
254
|
"import": "./dist/empty-state.js"
|
|
250
255
|
},
|
|
251
|
-
"./panel-header": {
|
|
252
|
-
"types": "./dist/panel-header.d.ts",
|
|
253
|
-
"browser": "./dist/browser/panel-header.js",
|
|
254
|
-
"import": "./dist/panel-header.js"
|
|
255
|
-
},
|
|
256
256
|
"./value-table": {
|
|
257
257
|
"types": "./dist/value-table.d.ts",
|
|
258
258
|
"browser": "./dist/browser/value-table.js",
|
|
@@ -270,6 +270,7 @@
|
|
|
270
270
|
"./disclosure-arrow.css": "./dist/styles/disclosure-arrow.css",
|
|
271
271
|
"./toolbar.css": "./dist/styles/toolbar.css",
|
|
272
272
|
"./toolbar-control-group.css": "./dist/styles/toolbar-control-group.css",
|
|
273
|
+
"./surface-scaffold.css": "./dist/styles/surface-scaffold.css",
|
|
273
274
|
"./floating-toolbar.css": "./dist/styles/floating-toolbar.css",
|
|
274
275
|
"./toolbar-text.css": "./dist/styles/toolbar-text.css",
|
|
275
276
|
"./list.css": "./dist/styles/list.css",
|
|
@@ -296,7 +297,6 @@
|
|
|
296
297
|
"./token-search-field.css": "./dist/styles/token-search-field.css",
|
|
297
298
|
"./state-banner.css": "./dist/styles/state-banner.css",
|
|
298
299
|
"./empty-state.css": "./dist/styles/empty-state.css",
|
|
299
|
-
"./panel-header.css": "./dist/styles/panel-header.css",
|
|
300
300
|
"./value-table.css": "./dist/styles/value-table.css",
|
|
301
301
|
"./ai/*": "./ai/*",
|
|
302
302
|
"./docs/*": "./docs/*"
|
|
@@ -4,7 +4,6 @@ import './recipes.css';
|
|
|
4
4
|
import { ListHeader } from '@kerfjs/ui/list-header';
|
|
5
5
|
import { ListItem } from '@kerfjs/ui/list-item';
|
|
6
6
|
import { LucideIcon } from '@kerfjs/ui/lucide-icon';
|
|
7
|
-
import { PanelHeader } from '@kerfjs/ui/panel-header';
|
|
8
7
|
import { ResizableRegion } from '@kerfjs/ui/resizable-region';
|
|
9
8
|
import { Toolbar } from '@kerfjs/ui/toolbar';
|
|
10
9
|
import { ToolbarControlGroup } from '@kerfjs/ui/toolbar-control-group';
|
|
@@ -30,11 +29,7 @@ export const createRecipe: RecipeFactory = (announce) => {
|
|
|
30
29
|
>
|
|
31
30
|
<Toolbar
|
|
32
31
|
label="Atlas workspace"
|
|
33
|
-
leading={
|
|
34
|
-
<ToolbarControlGroup appearance="borderless" single>
|
|
35
|
-
<ToolbarText text="Atlas" />
|
|
36
|
-
</ToolbarControlGroup>
|
|
37
|
-
}
|
|
32
|
+
leading={<ToolbarText text="Atlas" />}
|
|
38
33
|
trailing={
|
|
39
34
|
<div class="recipe-shell__toolbar-actions">
|
|
40
35
|
<ToolbarControlGroup
|
|
@@ -134,21 +129,32 @@ export const createRecipe: RecipeFactory = (announce) => {
|
|
|
134
129
|
</ResizableRegion>
|
|
135
130
|
</div>
|
|
136
131
|
<main id="recipe-shell-content" class="recipe-shell__main kui-pane">
|
|
137
|
-
<
|
|
138
|
-
|
|
139
|
-
|
|
132
|
+
<Toolbar
|
|
133
|
+
label="Current workspace view"
|
|
134
|
+
dividerSides=""
|
|
135
|
+
leading={
|
|
136
|
+
<ToolbarText
|
|
137
|
+
text={
|
|
138
|
+
selected.value === 'inbox'
|
|
139
|
+
? 'Inbox triage'
|
|
140
|
+
: 'Active projects'
|
|
141
|
+
}
|
|
142
|
+
size="xlarge"
|
|
143
|
+
id="recipe-shell-main-title"
|
|
144
|
+
/>
|
|
140
145
|
}
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
146
|
+
trailing={
|
|
147
|
+
<ToolbarControlGroup appearance="borderless" single>
|
|
148
|
+
<button
|
|
149
|
+
class="kui-recipe__button"
|
|
150
|
+
data-primary="true"
|
|
151
|
+
type="button"
|
|
152
|
+
data-action="recipe-action"
|
|
153
|
+
data-recipe-command="new"
|
|
154
|
+
>
|
|
155
|
+
New task
|
|
156
|
+
</button>
|
|
157
|
+
</ToolbarControlGroup>
|
|
152
158
|
}
|
|
153
159
|
/>
|
|
154
160
|
<div class="recipe-shell__main-body kui-pane__content kui-content">
|
|
@@ -183,9 +189,16 @@ export const createRecipe: RecipeFactory = (announce) => {
|
|
|
183
189
|
edge="start"
|
|
184
190
|
>
|
|
185
191
|
<aside class="recipe-shell__inspector kui-pane">
|
|
186
|
-
<
|
|
187
|
-
|
|
188
|
-
|
|
192
|
+
<Toolbar
|
|
193
|
+
label="Inspector"
|
|
194
|
+
dividerSides=""
|
|
195
|
+
leading={
|
|
196
|
+
<ToolbarText
|
|
197
|
+
text="Inspector"
|
|
198
|
+
size="xlarge"
|
|
199
|
+
id="recipe-shell-inspector-title"
|
|
200
|
+
/>
|
|
201
|
+
}
|
|
189
202
|
/>
|
|
190
203
|
<div class="recipe-shell__inspector-body kui-pane__content kui-content">
|
|
191
204
|
<ValueTable label="Selected task">
|
|
@@ -10,7 +10,6 @@ import { deviceClass } from '@kerfjs/ui/device-class';
|
|
|
10
10
|
import { ListHeader } from '@kerfjs/ui/list-header';
|
|
11
11
|
import { ListItem } from '@kerfjs/ui/list-item';
|
|
12
12
|
import { LucideIcon } from '@kerfjs/ui/lucide-icon';
|
|
13
|
-
import { PanelHeader } from '@kerfjs/ui/panel-header';
|
|
14
13
|
import { Toolbar } from '@kerfjs/ui/toolbar';
|
|
15
14
|
import { ToolbarControlGroup } from '@kerfjs/ui/toolbar-control-group';
|
|
16
15
|
import { ToolbarText } from '@kerfjs/ui/toolbar-text';
|
|
@@ -119,17 +118,28 @@ export const createRecipe: RecipeFactory = (announce) => {
|
|
|
119
118
|
</nav>
|
|
120
119
|
</CollapsiblePanel>
|
|
121
120
|
<main class="recipe-collapsible-sidebar__main kui-pane">
|
|
122
|
-
<
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
121
|
+
<Toolbar
|
|
122
|
+
label="Current navigation view"
|
|
123
|
+
dividerSides=""
|
|
124
|
+
leading={
|
|
125
|
+
<>
|
|
126
|
+
<ToolbarControlGroup appearance="borderless" single>
|
|
127
|
+
{railToggle(false)}
|
|
128
|
+
</ToolbarControlGroup>
|
|
129
|
+
<ToolbarText
|
|
130
|
+
text={
|
|
131
|
+
selected.value === 'projects'
|
|
132
|
+
? 'Projects'
|
|
133
|
+
: selected.value === 'shared'
|
|
134
|
+
? 'Shared with me'
|
|
135
|
+
: 'Inbox'
|
|
136
|
+
}
|
|
137
|
+
size="xlarge"
|
|
138
|
+
id="recipe-collapsible-main-title"
|
|
139
|
+
/>
|
|
140
|
+
</>
|
|
129
141
|
}
|
|
130
|
-
|
|
131
|
-
icon={railToggle(false)}
|
|
132
|
-
actions={
|
|
142
|
+
trailing={
|
|
133
143
|
<ToolbarControlGroup appearance="borderless" single>
|
|
134
144
|
{drawerToggle()}
|
|
135
145
|
</ToolbarControlGroup>
|
|
@@ -161,11 +171,7 @@ export const createRecipe: RecipeFactory = (announce) => {
|
|
|
161
171
|
<Toolbar
|
|
162
172
|
label="Activity"
|
|
163
173
|
dividerSides="b"
|
|
164
|
-
leading={
|
|
165
|
-
<ToolbarControlGroup appearance="borderless" single>
|
|
166
|
-
<ToolbarText text="Activity" size="small" />
|
|
167
|
-
</ToolbarControlGroup>
|
|
168
|
-
}
|
|
174
|
+
leading={<ToolbarText text="Activity" size="small" />}
|
|
169
175
|
trailing={
|
|
170
176
|
<ToolbarControlGroup appearance="borderless" single>
|
|
171
177
|
{drawerToggle()}
|
|
@@ -6,9 +6,10 @@ import '@awesome.me/webawesome/dist/components/input/input.js';
|
|
|
6
6
|
import '@awesome.me/webawesome/dist/components/textarea/textarea.js';
|
|
7
7
|
import './recipes.css';
|
|
8
8
|
|
|
9
|
-
import { PanelHeader } from '@kerfjs/ui/panel-header';
|
|
10
9
|
import { Select } from '@kerfjs/ui/select';
|
|
11
10
|
import { StateBanner } from '@kerfjs/ui/state-banner';
|
|
11
|
+
import { Toolbar } from '@kerfjs/ui/toolbar';
|
|
12
|
+
import { ToolbarText } from '@kerfjs/ui/toolbar-text';
|
|
12
13
|
import { signal } from 'kerfjs';
|
|
13
14
|
|
|
14
15
|
import type { RecipeFactory } from './types.js';
|
|
@@ -44,12 +45,20 @@ export const createRecipe: RecipeFactory = (announce) => {
|
|
|
44
45
|
aria-describedby="recipe-composer-summary"
|
|
45
46
|
noValidate
|
|
46
47
|
>
|
|
47
|
-
<
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
48
|
+
<Toolbar
|
|
49
|
+
label="Publish workspace update"
|
|
50
|
+
dividerSides=""
|
|
51
|
+
leading={
|
|
52
|
+
<ToolbarText
|
|
53
|
+
text="Publish workspace update"
|
|
54
|
+
size="xlarge"
|
|
55
|
+
id="recipe-composer-title"
|
|
56
|
+
/>
|
|
57
|
+
}
|
|
52
58
|
/>
|
|
59
|
+
<p class="kui-recipe__heading-summary" id="recipe-composer-summary">
|
|
60
|
+
Share a concise, actionable update with collaborators.
|
|
61
|
+
</p>
|
|
53
62
|
{status.value === 'error' && (
|
|
54
63
|
<StateBanner
|
|
55
64
|
title="Add a title before publishing"
|