@kerfjs/ui 5.0.0-beta.56 → 5.0.0-beta.57
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 +63 -32
- package/ai/application-ui-diagnostic-ids-v1.json +9 -1
- package/ai/application-ui-profile-sync.cjs +1 -1
- package/ai/application-ui-profile.defaults.json +63 -8
- package/ai/application-ui-profile.mjs +1 -1
- package/ai/component-catalog.json +208 -32
- package/ai/component-catalog.schema.json +2 -0
- package/ai/component-class-owners.cjs +83 -0
- package/ai/component-composition-extension.d.ts +7 -0
- package/ai/component-composition-extension.schema.json +7 -0
- package/ai/{component-catalog-v2-overrides.json → component-composition-rules.json} +2 -1
- package/ai/{component-catalog-v2.d.ts → component-composition.d.ts} +9 -5
- package/ai/{component-catalog-v2.json → component-composition.json} +155 -24
- package/ai/{component-catalog-v2.schema.json → component-composition.schema.json} +21 -5
- package/ai/components/README.md +170 -0
- package/ai/components/application-tabs.md +65 -0
- package/ai/components/badge.md +72 -0
- package/ai/components/collapsible-panel.md +102 -0
- package/ai/components/content-item.md +90 -0
- package/ai/components/disclosure-arrow.md +77 -0
- package/ai/components/document-baseline.md +75 -0
- package/ai/components/empty-state.md +80 -0
- package/ai/components/feedback.md +71 -0
- package/ai/components/floating-toolbar.md +80 -0
- package/ai/components/foundation.md +65 -0
- package/ai/components/grid.md +93 -0
- package/ai/components/headers.md +63 -0
- package/ai/components/layout.md +75 -0
- package/ai/components/list-action-row.md +91 -0
- package/ai/components/list-header.md +89 -0
- package/ai/components/list-inset-control.md +74 -0
- package/ai/components/list-inset-text.md +72 -0
- package/ai/components/list-item.md +88 -0
- package/ai/components/list.md +103 -0
- package/ai/components/loading-spinner.md +72 -0
- package/ai/components/lucide-icon.md +66 -0
- package/ai/components/nav-stack.md +103 -0
- package/ai/components/pane.md +100 -0
- package/ai/components/popup-menu.md +82 -0
- package/ai/components/recipe-app-shell.md +57 -0
- package/ai/components/recipe-collapsible-sidebar.md +57 -0
- package/ai/components/recipe-compact-toolbar.md +57 -0
- package/ai/components/recipe-composer-form.md +57 -0
- package/ai/components/recipe-list-detail-dialog.md +57 -0
- package/ai/components/recipe-list-workspace-states.md +57 -0
- package/ai/components/recipe-loading-inspector.md +57 -0
- package/ai/components/recipe-navigation-sidebar.md +57 -0
- package/ai/components/recipe-navigation-stack.md +57 -0
- package/ai/components/recipe-workspace-header.md +57 -0
- package/ai/components/resize.md +101 -0
- package/ai/components/row.md +96 -0
- package/ai/components/segmented-control.md +82 -0
- package/ai/components/select.md +107 -0
- package/ai/components/skeleton.md +84 -0
- package/ai/components/spacer.md +86 -0
- package/ai/components/split-view.md +102 -0
- package/ai/components/state-banner.md +92 -0
- package/ai/components/sunken-panel.md +79 -0
- package/ai/components/surface-scaffold.md +78 -0
- package/ai/components/tab-bar.md +112 -0
- package/ai/components/tab-scaffold.md +94 -0
- package/ai/components/tabs.md +90 -0
- package/ai/components/text.md +82 -0
- package/ai/components/token-search-field.md +101 -0
- package/ai/components/toolbar-control-group.md +100 -0
- package/ai/components/toolbar-text.md +76 -0
- package/ai/components/toolbar.md +95 -0
- package/ai/components/value-table.md +72 -0
- package/ai/components/wa-accordion-item.md +55 -0
- package/ai/components/wa-accordion.md +65 -0
- package/ai/components/wa-animated-image.md +55 -0
- package/ai/components/wa-animation.md +55 -0
- package/ai/components/wa-avatar.md +55 -0
- package/ai/components/wa-badge.md +55 -0
- package/ai/components/wa-breadcrumb-item.md +53 -0
- package/ai/components/wa-breadcrumb.md +55 -0
- package/ai/components/wa-button-group.md +59 -0
- package/ai/components/wa-button.md +55 -0
- package/ai/components/wa-callout.md +58 -0
- package/ai/components/wa-card.md +59 -0
- package/ai/components/wa-carousel-item.md +53 -0
- package/ai/components/wa-carousel.md +55 -0
- package/ai/components/wa-checkbox-group.md +55 -0
- package/ai/components/wa-checkbox.md +55 -0
- package/ai/components/wa-color-picker.md +55 -0
- package/ai/components/wa-comparison.md +55 -0
- package/ai/components/wa-copy-button.md +55 -0
- package/ai/components/wa-details.md +61 -0
- package/ai/components/wa-dialog.md +59 -0
- package/ai/components/wa-divider.md +53 -0
- package/ai/components/wa-drawer.md +55 -0
- package/ai/components/wa-dropdown-item.md +60 -0
- package/ai/components/wa-dropdown.md +60 -0
- package/ai/components/wa-format-bytes.md +53 -0
- package/ai/components/wa-format-date.md +53 -0
- package/ai/components/wa-format-number.md +53 -0
- package/ai/components/wa-icon.md +58 -0
- package/ai/components/wa-include.md +53 -0
- package/ai/components/wa-input.md +59 -0
- package/ai/components/wa-intersection-observer.md +53 -0
- package/ai/components/wa-known-date.md +53 -0
- package/ai/components/wa-markdown.md +53 -0
- package/ai/components/wa-mutation-observer.md +53 -0
- package/ai/components/wa-number-input.md +55 -0
- package/ai/components/wa-option.md +59 -0
- package/ai/components/wa-otp-input.md +53 -0
- package/ai/components/wa-page.md +53 -0
- package/ai/components/wa-pagination.md +55 -0
- package/ai/components/wa-popover.md +55 -0
- package/ai/components/wa-popup.md +53 -0
- package/ai/components/wa-progress-bar.md +53 -0
- package/ai/components/wa-progress-ring.md +53 -0
- package/ai/components/wa-qr-code.md +53 -0
- package/ai/components/wa-radio-group.md +59 -0
- package/ai/components/wa-radio.md +55 -0
- package/ai/components/wa-random-content.md +53 -0
- package/ai/components/wa-rating.md +55 -0
- package/ai/components/wa-relative-time.md +53 -0
- package/ai/components/wa-resize-observer.md +53 -0
- package/ai/components/wa-scroller.md +53 -0
- package/ai/components/wa-select.md +63 -0
- package/ai/components/wa-skeleton.md +53 -0
- package/ai/components/wa-slider.md +55 -0
- package/ai/components/wa-spinner.md +58 -0
- package/ai/components/wa-split-panel.md +58 -0
- package/ai/components/wa-switch.md +53 -0
- package/ai/components/wa-tab-group.md +69 -0
- package/ai/components/wa-tab-panel.md +60 -0
- package/ai/components/wa-tab.md +59 -0
- package/ai/components/wa-tag.md +59 -0
- package/ai/components/wa-textarea.md +53 -0
- package/ai/components/wa-time-input.md +55 -0
- package/ai/components/wa-toast-item.md +60 -0
- package/ai/components/wa-toast.md +60 -0
- package/ai/components/wa-tooltip.md +55 -0
- package/ai/components/wa-tree-item.md +55 -0
- package/ai/components/wa-tree.md +55 -0
- package/ai/components/wa-zoomable-frame.md +55 -0
- package/ai/components/workbench.md +114 -0
- package/ai/public-api-signatures-v1.md +161 -32
- package/ai/skill.md +100 -48
- package/ai/webawesome-jsx-signatures-v1.md +1 -1
- package/analyzer/component-ownership.d.mts +56 -0
- package/analyzer/component-ownership.mjs +184 -0
- package/analyzer/index.d.mts +3 -0
- package/analyzer/index.mjs +274 -20
- package/analyzer/selectors.d.mts +21 -0
- package/analyzer/selectors.mjs +212 -0
- package/dist/browser/catalog.js +25 -0
- package/dist/browser/collapsible-panel.js +7 -0
- package/dist/browser/nav-stack.js +8 -0
- package/dist/browser/split-view.js +10 -0
- package/dist/browser/tab-scaffold.js +4 -0
- package/dist/browser/workbench.js +10 -0
- package/dist/catalog-resources.d.ts +2 -2
- package/dist/catalog.d.ts +3 -3
- package/dist/catalog.js +7 -6
- package/dist/catalog.js.map +1 -1
- package/dist/{chunk-PK4N5QTO.js → chunk-553ASUK6.js} +2 -3
- package/dist/chunk-553ASUK6.js.map +1 -0
- package/dist/{chunk-G33XC2NB.js → chunk-6YFHCLHG.js} +2 -2
- package/dist/chunk-6YFHCLHG.js.map +1 -0
- package/dist/{chunk-T4UZTNZ4.js → chunk-EVYKTVBQ.js} +2 -11
- package/dist/chunk-EVYKTVBQ.js.map +1 -0
- package/dist/{chunk-AK67F6QN.js → chunk-EZVNC4J6.js} +4 -1
- package/dist/chunk-EZVNC4J6.js.map +1 -0
- package/dist/{chunk-MA6Z6EIM.js → chunk-F4QMLOXJ.js} +3 -2
- package/dist/chunk-F4QMLOXJ.js.map +1 -0
- package/dist/{chunk-QQOTQTDD.js → chunk-G2RKFVRB.js} +13 -10
- package/dist/chunk-G2RKFVRB.js.map +1 -0
- package/dist/chunk-JCV4GXWB.js +249 -0
- package/dist/chunk-JCV4GXWB.js.map +1 -0
- package/dist/chunk-K47P7QZC.js +17 -0
- package/dist/chunk-K47P7QZC.js.map +1 -0
- package/dist/{chunk-MOBRFZH3.js → chunk-OUK6QRDR.js} +2 -12
- package/dist/chunk-OUK6QRDR.js.map +1 -0
- package/dist/{chunk-O3EXIBEZ.js → chunk-PWXNJS2B.js} +7 -6
- package/dist/chunk-PWXNJS2B.js.map +1 -0
- package/dist/{chunk-VNPQDCQZ.js → chunk-QOWG4ZCL.js} +3 -2
- package/dist/chunk-QOWG4ZCL.js.map +1 -0
- package/dist/{chunk-V65EOWNF.js → chunk-XCO6YCYM.js} +5 -4
- package/dist/chunk-XCO6YCYM.js.map +1 -0
- package/dist/{chunk-K6UNVKDK.js → chunk-XDKAYSVD.js} +3 -1
- package/dist/chunk-XDKAYSVD.js.map +1 -0
- package/dist/collapsible-panel.d.ts +3 -3
- package/dist/collapsible-panel.js +2 -2
- package/dist/collapsible-panel.js.map +1 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.js +10 -8
- package/dist/list-action-row.js +2 -1
- package/dist/list-header.js +1 -1
- package/dist/list-item.js +2 -1
- package/dist/nav-stack.d.ts +13 -1
- package/dist/nav-stack.js +1 -1
- package/dist/pane.d.ts +20 -3
- package/dist/pane.js +1 -1
- package/dist/{panel-toolbar-C8sF-YZC.d.ts → panel-toolbar-BN4x0rth.d.ts} +3 -2
- package/dist/select.js +1 -1
- package/dist/split-view.d.ts +3 -3
- package/dist/split-view.js +3 -2
- package/dist/split-view.js.map +1 -1
- package/dist/state-banner.js +1 -1
- package/dist/styles/app-tab.css +31 -0
- package/dist/styles/badge.css +19 -11
- package/dist/styles/collapsible-panel.css +13 -9
- package/dist/styles/floating-toolbar.css +25 -6
- package/dist/styles/list-header.css +0 -12
- package/dist/styles/list.css +4 -4
- package/dist/styles/nav-stack.css +46 -19
- package/dist/styles/pane.css +50 -0
- package/dist/styles/popup-menu.css +151 -0
- package/dist/styles/resizable-region.css +22 -10
- package/dist/styles/select.css +28 -14
- package/dist/styles/skeleton.css +30 -3
- package/dist/styles/split-view.css +10 -7
- package/dist/styles/state-banner.css +0 -19
- package/dist/styles/surface-scaffold.css +8 -3
- package/dist/styles/tab-bar.css +79 -28
- package/dist/styles/tab-scaffold.css +25 -1
- package/dist/styles/text.css +16 -0
- package/dist/styles/toolbar-control-group.css +121 -66
- package/dist/styles/toolbar-text.css +21 -0
- package/dist/styles/toolbar.css +8 -32
- package/dist/styles/workbench.css +18 -18
- package/dist/tab-scaffold.d.ts +11 -1
- package/dist/tab-scaffold.js +2 -0
- package/dist/tab-scaffold.js.map +1 -1
- package/dist/toolbar-text.d.ts +7 -1
- package/dist/toolbar-text.js +1 -1
- package/dist/toolbar.d.ts +8 -1
- package/dist/toolbar.js +1 -1
- package/dist/{types-DXAGogOS.d.ts → types-BuHELdXR.d.ts} +1 -1
- package/dist/wire-catalog.d.ts +3 -1
- package/dist/wire-catalog.js +2 -0
- package/dist/wire-catalog.js.map +1 -1
- package/dist/wire-scroll-dividers.d.ts +69 -0
- package/dist/wire-scroll-dividers.js +3 -0
- package/dist/wire-scroll-dividers.js.map +1 -0
- package/dist/workbench.d.ts +13 -12
- package/dist/workbench.js +1 -1
- package/docs/app-layouts.md +9 -1
- package/docs/catalog.md +10 -5
- package/docs/collapsible-panel.md +10 -6
- package/docs/component-contract.md +147 -21
- package/docs/component-selection.md +18 -6
- package/docs/design/templates/tab-bar/workspace-tabs-dark.svg +1 -1
- package/docs/design/templates/tab-bar/workspace-tabs.svg +1 -1
- package/docs/design/templates/tab-bar-dark.svg +1 -1
- package/docs/design/templates/tab-bar.svg +1 -1
- package/docs/design-philosophy.md +30 -3
- package/docs/examples/application-ui-profile.json +4 -4
- package/docs/examples/{component-catalog-extension-v2.json → component-composition-extension.json} +3 -3
- package/docs/layout.md +82 -3
- package/docs/nav-stack.md +33 -3
- package/docs/split-view.md +10 -5
- package/docs/tab-scaffold.md +23 -1
- package/docs/type-contracts.md +4 -3
- package/docs/ui-analyzer.md +99 -5
- package/docs/ui-doctor.md +10 -0
- package/docs/workbench.md +19 -9
- package/doctor/index.mjs +6 -1
- package/llms.txt +85 -20
- package/package.json +17 -5
- package/ux-demo/recipes/collapsible-sidebar.tsx +0 -1
- package/ux-demo/recipes/composer-form.tsx +0 -1
- package/ux-demo/recipes/list-detail-dialog.tsx +0 -2
- package/ux-demo/recipes/list-workspace-states.tsx +0 -1
- package/ux-demo/recipes/loading-inspector.tsx +0 -1
- package/ux-demo/recipes/workspace-header.tsx +0 -1
- package/ai/component-catalog-extension-v2.d.ts +0 -7
- package/ai/component-catalog-extension-v2.schema.json +0 -7
- package/dist/chunk-AK67F6QN.js.map +0 -1
- package/dist/chunk-G33XC2NB.js.map +0 -1
- package/dist/chunk-K6UNVKDK.js.map +0 -1
- package/dist/chunk-MA6Z6EIM.js.map +0 -1
- package/dist/chunk-MOBRFZH3.js.map +0 -1
- package/dist/chunk-O3EXIBEZ.js.map +0 -1
- package/dist/chunk-PK4N5QTO.js.map +0 -1
- package/dist/chunk-QQOTQTDD.js.map +0 -1
- package/dist/chunk-T4UZTNZ4.js.map +0 -1
- package/dist/chunk-V65EOWNF.js.map +0 -1
- package/dist/chunk-VNPQDCQZ.js.map +0 -1
package/dist/pane.d.ts
CHANGED
|
@@ -21,9 +21,16 @@ type PaneRootAttributes = Readonly<Record<`data-${string}`, string | undefined>
|
|
|
21
21
|
'data-safe-area-inline-start'?: never;
|
|
22
22
|
'data-safe-area-inline-end'?: never;
|
|
23
23
|
'data-chrome-placement'?: never;
|
|
24
|
+
'data-chrome-dividers'?: never;
|
|
24
25
|
}>;
|
|
25
26
|
/** How a Pane's header and footer relate to its scrolling content. */
|
|
26
27
|
type PaneChromePlacement = 'fixed' | 'auto';
|
|
28
|
+
/**
|
|
29
|
+
* When a Pane draws the divider between its pinned header or footer and its
|
|
30
|
+
* scrolling content: `scroll` while content is scrolled away beneath that
|
|
31
|
+
* chrome, as `wireScrollDividers` reports; `always`; or `none`.
|
|
32
|
+
*/
|
|
33
|
+
type PaneChromeDividers = 'scroll' | 'always' | 'none';
|
|
27
34
|
interface PaneProps {
|
|
28
35
|
/** Optional fixed chrome above the scrolling content, arranged vertically. */
|
|
29
36
|
header?: KerfUiContent;
|
|
@@ -39,6 +46,16 @@ interface PaneProps {
|
|
|
39
46
|
* squeeze the content to nothing.
|
|
40
47
|
*/
|
|
41
48
|
chromePlacement?: PaneChromePlacement;
|
|
49
|
+
/**
|
|
50
|
+
* The divider under the header and over the footer, where they meet the
|
|
51
|
+
* scrolling content. `scroll` (default) shows the header's divider only
|
|
52
|
+
* while the content is scrolled down, and the footer's only while more
|
|
53
|
+
* content lies below — never when the content fits — once
|
|
54
|
+
* `wireScrollDividers` (`@kerfjs/ui/wire-scroll-dividers`) is wired above
|
|
55
|
+
* the pane; unwired, neither shows. `always` shows both; `none` neither.
|
|
56
|
+
* The line is drawn inside the chrome, so no state moves the content.
|
|
57
|
+
*/
|
|
58
|
+
chromeDividers?: PaneChromeDividers;
|
|
42
59
|
/** Root semantics. Defaults to `div`. */
|
|
43
60
|
element?: PaneElement;
|
|
44
61
|
/** Scrolling content semantics. Defaults to `div`. */
|
|
@@ -73,13 +90,13 @@ interface PaneProps {
|
|
|
73
90
|
* or a CollapsiblePanel) forwards, so the app configures that pane instead of
|
|
74
91
|
* styling it. An omitted or `undefined` field keeps the composite's default.
|
|
75
92
|
*/
|
|
76
|
-
type PaneConfig = Pick<PaneProps, 'contentElement' | 'contentLabel' | 'separators' | 'safeAreaEdges'>;
|
|
93
|
+
type PaneConfig = Pick<PaneProps, 'contentElement' | 'contentLabel' | 'separators' | 'safeAreaEdges' | 'chromeDividers'>;
|
|
77
94
|
/**
|
|
78
95
|
* An unpadded application column with optional fixed header/footer slots and one
|
|
79
96
|
* scrolling vertical content owner. Separator lines are independently opt-in on
|
|
80
97
|
* each logical edge, so the same component works as a sidebar, main area,
|
|
81
98
|
* inspector, or dialog column.
|
|
82
99
|
*/
|
|
83
|
-
declare function Pane({ header, children, footer, chromePlacement, element, contentElement, separators, safeAreaEdges, id, label, contentLabel, className, headerClassName, contentClassName, footerClassName, rootAttributes, slot, }: PaneProps): kerfjs.SafeHtml;
|
|
100
|
+
declare function Pane({ header, children, footer, chromePlacement, chromeDividers, element, contentElement, separators, safeAreaEdges, id, label, contentLabel, className, headerClassName, contentClassName, footerClassName, rootAttributes, slot, }: PaneProps): kerfjs.SafeHtml;
|
|
84
101
|
|
|
85
|
-
export { Pane, type PaneChromePlacement, type PaneConfig, type PaneContentElement, type PaneElement, type PaneProps, type PaneSeparatorSide };
|
|
102
|
+
export { Pane, type PaneChromeDividers, type PaneChromePlacement, type PaneConfig, type PaneContentElement, type PaneElement, type PaneProps, type PaneSeparatorSide };
|
package/dist/pane.js
CHANGED
|
@@ -46,8 +46,9 @@ interface PanelToggle {
|
|
|
46
46
|
* panel's copy is inert), so give it no `id`s.
|
|
47
47
|
*
|
|
48
48
|
* The toolbar's configuration (`dividerSides`, `centerAlign`, `responsive`,
|
|
49
|
-
* `responsiveAt`, `safeAreaEdges`) forwards to its `Toolbar
|
|
50
|
-
*
|
|
49
|
+
* `responsiveAt`, `safeAreaEdges`) forwards to its `Toolbar`. It draws no
|
|
50
|
+
* divider of its own: the panel's `Pane` draws the line under it while the
|
|
51
|
+
* content is scrolled (its `chromeDividers`, wired by `wireScrollDividers`).
|
|
51
52
|
*/
|
|
52
53
|
interface PanelToolbar extends ToolbarConfig {
|
|
53
54
|
/** Accessible name of the panel's toolbar. */
|
package/dist/select.js
CHANGED
package/dist/split-view.d.ts
CHANGED
|
@@ -23,10 +23,10 @@ interface SplitViewResizable extends Pick<ResizableRegionProps, 'separator' | 'h
|
|
|
23
23
|
type SplitViewCompactViewToolbars = Pick<NavStackView, 'leading' | 'center' | 'toolbar' | 'bottomToolbar'>;
|
|
24
24
|
/**
|
|
25
25
|
* The compact `NavStack`'s configuration: its toolbar configuration, back
|
|
26
|
-
* control,
|
|
27
|
-
* `detail` give each view its own toolbar groups.
|
|
26
|
+
* control, persistent bottom toolbar, and chrome dividers forward to the
|
|
27
|
+
* stack, and `list` / `detail` give each view its own toolbar groups.
|
|
28
28
|
*/
|
|
29
|
-
interface SplitViewCompactStack extends Pick<NavStackProps, 'toolbarConfig' | 'backIcon' | 'backText' | 'hideToolbar' | 'bottomToolbar'> {
|
|
29
|
+
interface SplitViewCompactStack extends Pick<NavStackProps, 'toolbarConfig' | 'backIcon' | 'backText' | 'hideToolbar' | 'bottomToolbar' | 'chromeDividers'> {
|
|
30
30
|
/** Toolbar content for the list (root) view. */
|
|
31
31
|
list?: SplitViewCompactViewToolbars;
|
|
32
32
|
/** Toolbar content for the pushed detail view. */
|
package/dist/split-view.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { NavStack } from './chunk-
|
|
1
|
+
import { NavStack } from './chunk-PWXNJS2B.js';
|
|
2
2
|
import { ResizableRegion } from './chunk-VHADGP3B.js';
|
|
3
3
|
|
|
4
4
|
|
|
@@ -58,7 +58,8 @@ function SplitView({
|
|
|
58
58
|
backText: compactStack.backText,
|
|
59
59
|
toolbarConfig: compactStack.toolbarConfig,
|
|
60
60
|
hideToolbar: compactStack.hideToolbar,
|
|
61
|
-
bottomToolbar: compactStack.bottomToolbar
|
|
61
|
+
bottomToolbar: compactStack.bottomToolbar,
|
|
62
|
+
chromeDividers: compactStack.chromeDividers
|
|
62
63
|
}
|
|
63
64
|
)
|
|
64
65
|
}
|
package/dist/split-view.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/split-view.tsx"],"names":[],"mappings":";;;;;;;;;;
|
|
1
|
+
{"version":3,"sources":["../src/split-view.tsx"],"names":[],"mappings":"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","file":"split-view.js","sourcesContent":["import {\n NavStack,\n type NavStackProps,\n type NavStackView,\n} from './nav-stack.js';\nimport {\n ResizableRegion,\n type ResizableRegionProps,\n} from './resizable-region.js';\nimport type { KerfUiContent } from './semantic-content.js';\n\n/**\n * The roomy list pane's `ResizableRegion`: its committed `size` and `min` /\n * `max` limits, plus the region configuration that forwards unchanged\n * (`separator`, `handleIcon`, `contentOverflow`, and collapse:\n * `collapsed`, `transitioning`, `collapseMotion`, `restoreControl`,\n * `restorePosition`). Omitted options keep the region's defaults.\n */\nexport interface SplitViewResizable extends Pick<\n ResizableRegionProps,\n | 'separator'\n | 'handleIcon'\n | 'contentOverflow'\n | 'collapsed'\n | 'transitioning'\n | 'collapseMotion'\n | 'restoreControl'\n | 'restorePosition'\n> {\n size: number;\n min: number;\n max: number;\n}\n\n/** One compact view's top- and bottom-toolbar content (see `NavStackView`). */\nexport type SplitViewCompactViewToolbars = Pick<\n NavStackView,\n 'leading' | 'center' | 'toolbar' | 'bottomToolbar'\n>;\n\n/**\n * The compact `NavStack`'s configuration: its toolbar configuration, back\n * control, persistent bottom toolbar, and chrome dividers forward to the\n * stack, and `list` / `detail` give each view its own toolbar groups.\n */\nexport interface SplitViewCompactStack extends Pick<\n NavStackProps,\n | 'toolbarConfig'\n | 'backIcon'\n | 'backText'\n | 'hideToolbar'\n | 'bottomToolbar'\n | 'chromeDividers'\n> {\n /** Toolbar content for the list (root) view. */\n list?: SplitViewCompactViewToolbars;\n /** Toolbar content for the pushed detail view. */\n detail?: SplitViewCompactViewToolbars;\n}\n\nexport interface SplitViewProps {\n id: string;\n label: string;\n /** The list (primary) pane. */\n list: KerfUiContent;\n /** The detail (secondary) pane. */\n detail: KerfUiContent;\n /**\n * Compact (\"one pane at a time\") classes — a handset or portrait tablet.\n * Derive from `deviceClass().value.compact`. When true the split collapses to\n * a `NavStack`: the list is the root and the detail is pushed over it.\n */\n compact?: boolean;\n /** In compact mode, whether the detail is currently pushed over the list. */\n detailActive?: boolean;\n /** Title/label for the list (compact NavStack root + region label). */\n listTitle?: string;\n /** Title/label for the detail (compact NavStack pushed view + region label). */\n detailTitle?: string;\n /** Back label for the compact NavStack (default \"Back\"). */\n backLabel?: string;\n /** Compact NavStack configuration and per-view toolbars. */\n compactStack?: SplitViewCompactStack;\n /** A resizable separator on roomy classes (min/max px). Omit for a fixed split. */\n resizable?: SplitViewResizable;\n className?: string;\n /** Native named-slot assignment when composed inside a web component. */\n slot?: string;\n}\n\n/**\n * A list-detail split. On roomy classes it shows both panes side\n * by side with an optional resizable separator; on compact classes it collapses\n * to a `NavStack` (list → detail). See `docs/23-app-layouts.md` §3.2. Compose the\n * resizable wiring with `wireResizableRegions` and the compact back with\n * `wireNavStack`.\n */\nexport function SplitView({\n id,\n label,\n list,\n detail,\n compact = false,\n detailActive = false,\n listTitle = '',\n detailTitle = '',\n backLabel = 'Back',\n compactStack = {},\n resizable,\n className = '',\n slot,\n}: SplitViewProps) {\n if (compact) {\n const listView: NavStackView = {\n ...compactStack.list,\n key: 'list',\n title: listTitle,\n content: list,\n };\n const views: NavStackView[] = detailActive\n ? [\n listView,\n {\n ...compactStack.detail,\n key: 'detail',\n title: detailTitle,\n content: detail,\n },\n ]\n : [listView];\n return (\n <div\n class={`kui-split-view kui-split-view--compact ${className}`.trim()}\n id={id}\n data-component=\"split-view\"\n data-split-mode=\"compact\"\n slot={slot}\n >\n <NavStack\n id={`${id}-stack`}\n label={label}\n views={views}\n backLabel={backLabel}\n backIcon={compactStack.backIcon}\n backText={compactStack.backText}\n toolbarConfig={compactStack.toolbarConfig}\n hideToolbar={compactStack.hideToolbar}\n bottomToolbar={compactStack.bottomToolbar}\n chromeDividers={compactStack.chromeDividers}\n />\n </div>\n );\n }\n const listPane = resizable ? (\n <ResizableRegion\n id={`${id}-list`}\n label={listTitle || 'List'}\n size={resizable.size}\n min={resizable.min}\n max={resizable.max}\n separator={resizable.separator}\n handleIcon={resizable.handleIcon}\n contentOverflow={resizable.contentOverflow}\n collapsed={resizable.collapsed}\n transitioning={resizable.transitioning}\n collapseMotion={resizable.collapseMotion}\n restoreControl={resizable.restoreControl}\n restorePosition={resizable.restorePosition}\n >\n <div\n class=\"kui-split-view__list kui-pane\"\n data-split-list\n data-resizable=\"true\"\n >\n {list}\n </div>\n </ResizableRegion>\n ) : (\n <div\n class=\"kui-split-view__list kui-pane\"\n data-split-list\n data-resizable=\"false\"\n >\n {list}\n </div>\n );\n return (\n <div\n class={`kui-split-view ${className}`.trim()}\n id={id}\n data-component=\"split-view\"\n data-split-mode=\"split\"\n aria-label={label}\n slot={slot}\n >\n {listPane}\n <div\n class=\"kui-split-view__detail kui-pane\"\n data-split-detail\n aria-label={detailTitle || undefined}\n >\n {detail}\n </div>\n </div>\n );\n}\n"]}
|
package/dist/state-banner.js
CHANGED
package/dist/styles/app-tab.css
CHANGED
|
@@ -124,6 +124,37 @@
|
|
|
124
124
|
width: 2rem;
|
|
125
125
|
min-width: 2rem;
|
|
126
126
|
}
|
|
127
|
+
/* In a TabBar, the tab styles itself in the context of its parent strip. A
|
|
128
|
+
segmented strip's outer ends follow the pill track: the first tab's leading
|
|
129
|
+
corners, and a filled strip's last tab's trailing corners, are pill-rounded
|
|
130
|
+
so each end is concentric with the track (TabBar insets a compact strip's
|
|
131
|
+
tabs to match). Only fill allocation carries the last tab to the track's
|
|
132
|
+
trailing end; an intrinsic strip's last tab stops short of it and keeps the
|
|
133
|
+
segment radius, as do the corners between tabs. */
|
|
134
|
+
.kui-tab-bar[data-presentation="segmented"]
|
|
135
|
+
.kui-tab-bar__tabs
|
|
136
|
+
> .kui-app-tab:first-child {
|
|
137
|
+
border-start-start-radius: var(--kui-radius-pill);
|
|
138
|
+
border-end-start-radius: var(--kui-radius-pill);
|
|
139
|
+
}
|
|
140
|
+
.kui-tab-bar[data-presentation="segmented"][data-allocation="fill"]
|
|
141
|
+
.kui-tab-bar__tabs
|
|
142
|
+
> .kui-app-tab:last-child {
|
|
143
|
+
border-start-end-radius: var(--kui-radius-pill);
|
|
144
|
+
border-end-end-radius: var(--kui-radius-pill);
|
|
145
|
+
}
|
|
146
|
+
/* Fill allocation shares the strip equally and centers each tab's content. */
|
|
147
|
+
.kui-tab-bar[data-allocation="fill"] .kui-tab-bar__tabs > .kui-app-tab {
|
|
148
|
+
min-width: 0;
|
|
149
|
+
flex: 1 1 0;
|
|
150
|
+
}
|
|
151
|
+
.kui-tab-bar[data-allocation="fill"]
|
|
152
|
+
.kui-tab-bar__tabs
|
|
153
|
+
> .kui-app-tab
|
|
154
|
+
> .kui-app-tab__select {
|
|
155
|
+
width: 100%;
|
|
156
|
+
justify-content: center;
|
|
157
|
+
}
|
|
127
158
|
.kui-app-tab__trailing {
|
|
128
159
|
display: grid;
|
|
129
160
|
min-width: 1.275rem;
|
package/dist/styles/badge.css
CHANGED
|
@@ -64,17 +64,6 @@
|
|
|
64
64
|
}
|
|
65
65
|
|
|
66
66
|
.kui-badge[data-appearance="solid"] {
|
|
67
|
-
/* A placeholder's skeleton inside a solid badge: the generic text-color tint
|
|
68
|
-
is nearly invisible on the saturated fill, so derive it from the badge's
|
|
69
|
-
own foreground instead, which contrasts with the fill in every tone and
|
|
70
|
-
color scheme. Quiet and outline badges sit on a pale fill and keep the
|
|
71
|
-
generic tint. */
|
|
72
|
-
--_kui-skeleton-fill: color-mix(
|
|
73
|
-
in srgb,
|
|
74
|
-
var(--_kui-badge-on-solid) 45%,
|
|
75
|
-
transparent
|
|
76
|
-
);
|
|
77
|
-
|
|
78
67
|
color: var(--_kui-badge-on-solid);
|
|
79
68
|
background: var(--_kui-badge-fill-solid);
|
|
80
69
|
}
|
|
@@ -108,3 +97,22 @@
|
|
|
108
97
|
border-radius: 50%;
|
|
109
98
|
background: var(--_kui-badge-fill-solid);
|
|
110
99
|
}
|
|
100
|
+
|
|
101
|
+
/* A multiple icon-only Select's count badge, in the trigger's end slot after
|
|
102
|
+
its fixed icon, sits 4px from the icon (the caret keeps its 12px after it).
|
|
103
|
+
The summary that ends the Select's label (and accessible name) stays inline
|
|
104
|
+
text, so a visible label reads "Labels: Bug, Docs" in place of the hidden
|
|
105
|
+
value. */
|
|
106
|
+
.kui-select > .kui-badge[slot="end"] {
|
|
107
|
+
margin-inline-start: 0.25rem;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
/* A StateBanner's badge follows its title inline and is taller than the
|
|
111
|
+
title's line. Negative block margins keep it out of the line-height
|
|
112
|
+
calculation, so a wrapped title's lines stay evenly spaced whichever line
|
|
113
|
+
the badge lands on. */
|
|
114
|
+
.kui-state-banner__copy > .kui-badge {
|
|
115
|
+
margin-block: -0.5em;
|
|
116
|
+
margin-inline-end: var(--kui-layout-item-gap, 0.5rem);
|
|
117
|
+
vertical-align: baseline;
|
|
118
|
+
}
|
|
@@ -413,12 +413,15 @@
|
|
|
413
413
|
--kui-collapsible-panel-restore-inset,
|
|
414
414
|
1rem
|
|
415
415
|
);
|
|
416
|
-
/* The corner owns the inset, so a FloatingToolbar composed here floats
|
|
417
|
-
from this point instead of adding its own inset on top. */
|
|
418
|
-
--kui-floating-toolbar-inset: 0px;
|
|
419
416
|
position: absolute;
|
|
420
417
|
/* Hidden while an open side overlay covers the content (see below). */
|
|
421
|
-
visibility: var(
|
|
418
|
+
visibility: var(
|
|
419
|
+
--_kui-workbench-covered,
|
|
420
|
+
var(
|
|
421
|
+
--_kui-collapsible-panel-covered,
|
|
422
|
+
var(--_kui-resizable-region-covered, inherit)
|
|
423
|
+
)
|
|
424
|
+
);
|
|
422
425
|
z-index: var(
|
|
423
426
|
--kui-collapsible-panel-restore-z,
|
|
424
427
|
calc(var(--kui-collapsible-panel-overlay-z, 40) - 2)
|
|
@@ -470,7 +473,8 @@
|
|
|
470
473
|
corner) are hidden, not merely stacked beneath it: they never paint over
|
|
471
474
|
the overlay whatever stacking context an app puts them in, and hidden they
|
|
472
475
|
leave the tab order and the accessibility tree. They come back as the
|
|
473
|
-
overlay closes. The
|
|
476
|
+
overlay closes. The CollapsiblePanel's own covered context,
|
|
477
|
+
`--_kui-collapsible-panel-covered`, is read by FloatingToolbar and the
|
|
474
478
|
layouts' restore corners; the overlay panels themselves are exempt, so
|
|
475
479
|
their own floating controls stay. */
|
|
476
480
|
[data-collapsible-overlay="true"]:has(
|
|
@@ -479,11 +483,11 @@
|
|
|
479
483
|
.kui-collapsible-panel--right
|
|
480
484
|
):not([data-collapsed="true"])
|
|
481
485
|
) {
|
|
482
|
-
--_kui-
|
|
486
|
+
--_kui-collapsible-panel-covered: hidden;
|
|
483
487
|
}
|
|
484
488
|
|
|
485
489
|
[data-collapsible-overlay="true"] .kui-collapsible-panel {
|
|
486
|
-
--_kui-
|
|
490
|
+
--_kui-collapsible-panel-covered: initial;
|
|
487
491
|
}
|
|
488
492
|
|
|
489
493
|
/* A static overlay panel sets the flag on its container and clears it again
|
|
@@ -499,7 +503,7 @@
|
|
|
499
503
|
)[data-presentation="overlay"]:not([data-collapsed="true"])
|
|
500
504
|
)
|
|
501
505
|
) {
|
|
502
|
-
--_kui-
|
|
506
|
+
--_kui-collapsible-panel-covered: hidden;
|
|
503
507
|
}
|
|
504
508
|
|
|
505
509
|
:where(
|
|
@@ -511,7 +515,7 @@
|
|
|
511
515
|
)
|
|
512
516
|
)
|
|
513
517
|
> .kui-collapsible-panel[data-presentation="overlay"] {
|
|
514
|
-
--_kui-
|
|
518
|
+
--_kui-collapsible-panel-covered: initial;
|
|
515
519
|
}
|
|
516
520
|
|
|
517
521
|
/* A button does not stretch between its insets the way a div does, so the
|
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
.kui-floating-toolbar {
|
|
2
2
|
/* Inset from the container edges: a top toolbar sits 8px in, so this floats an
|
|
3
3
|
extra 8px past that (--kui-space-m = 16px). Override the token to reposition,
|
|
4
|
-
on the toolbar or on an ancestor composition boundary
|
|
5
|
-
corner sets it to 0 because the corner already owns the inset. */
|
|
4
|
+
on the toolbar or on an ancestor composition boundary. */
|
|
6
5
|
--_kui-floating-toolbar-inset: var(
|
|
7
6
|
--kui-floating-toolbar-inset,
|
|
8
7
|
var(--kui-space-m, 1rem)
|
|
@@ -14,16 +13,36 @@
|
|
|
14
13
|
position: absolute;
|
|
15
14
|
z-index: 4;
|
|
16
15
|
/* A layout whose open side overlay covers this toolbar's region (a
|
|
17
|
-
Workbench rail, a CollapsiblePanel, a ResizableRegion)
|
|
18
|
-
and the toolbar hides — out of the tab
|
|
19
|
-
rather than risk painting over the
|
|
20
|
-
|
|
16
|
+
Workbench rail, a CollapsiblePanel, a ResizableRegion) provides its own
|
|
17
|
+
covered context to that region, and the toolbar hides — out of the tab
|
|
18
|
+
order and the accessibility tree — rather than risk painting over the
|
|
19
|
+
overlay. Any enclosing layout's covered context hides it. */
|
|
20
|
+
visibility: var(
|
|
21
|
+
--_kui-workbench-covered,
|
|
22
|
+
var(
|
|
23
|
+
--_kui-collapsible-panel-covered,
|
|
24
|
+
var(--_kui-resizable-region-covered, inherit)
|
|
25
|
+
)
|
|
26
|
+
);
|
|
21
27
|
display: flex;
|
|
22
28
|
color-scheme: dark;
|
|
23
29
|
align-items: center;
|
|
24
30
|
gap: var(--kui-space-xs, 0.5rem);
|
|
25
31
|
}
|
|
26
32
|
|
|
33
|
+
/* In a layout's restore corner the corner already owns the inset, so the
|
|
34
|
+
toolbar floats from the corner itself. Zero specificity: the toolbar's own
|
|
35
|
+
`inset` (or an app rule on the toolbar) still wins, while a token inherited
|
|
36
|
+
from outside the corner does not. */
|
|
37
|
+
:where(
|
|
38
|
+
.kui-workbench__restore,
|
|
39
|
+
.kui-collapsible-panel__restore,
|
|
40
|
+
.kui-resizable-region__restore
|
|
41
|
+
)
|
|
42
|
+
:where(.kui-floating-toolbar) {
|
|
43
|
+
--kui-floating-toolbar-inset: 0px;
|
|
44
|
+
}
|
|
45
|
+
|
|
27
46
|
.kui-floating-toolbar[data-position^="bottom"] {
|
|
28
47
|
inset-block-end: var(--_kui-floating-toolbar-inset);
|
|
29
48
|
}
|
|
@@ -88,18 +88,6 @@
|
|
|
88
88
|
text-align: start;
|
|
89
89
|
}
|
|
90
90
|
|
|
91
|
-
.kui-list-header__label {
|
|
92
|
-
min-width: 0;
|
|
93
|
-
margin: 0;
|
|
94
|
-
overflow: hidden;
|
|
95
|
-
font-size: var(--kui-font-xs);
|
|
96
|
-
font-weight: 650;
|
|
97
|
-
letter-spacing: 0.04em;
|
|
98
|
-
text-overflow: ellipsis;
|
|
99
|
-
text-transform: uppercase;
|
|
100
|
-
white-space: nowrap;
|
|
101
|
-
}
|
|
102
|
-
|
|
103
91
|
.kui-list-header__action,
|
|
104
92
|
.kui-list-header__action-layer {
|
|
105
93
|
display: grid;
|
package/dist/styles/list.css
CHANGED
|
@@ -110,19 +110,19 @@
|
|
|
110
110
|
overscroll-behavior-y: contain;
|
|
111
111
|
}
|
|
112
112
|
|
|
113
|
-
.kui-list[divider-sides*="t"] {
|
|
113
|
+
.kui-list:is([divider-sides*="t"], [data-scroll-divider*="t"]) {
|
|
114
114
|
--_kui-list-divider-top: var(--kui-list-divider-color);
|
|
115
115
|
}
|
|
116
116
|
|
|
117
|
-
.kui-list[divider-sides*="r"] {
|
|
117
|
+
.kui-list:is([divider-sides*="r"], [data-scroll-divider*="r"]) {
|
|
118
118
|
--_kui-list-divider-right: var(--kui-list-divider-color);
|
|
119
119
|
}
|
|
120
120
|
|
|
121
|
-
.kui-list[divider-sides*="b"] {
|
|
121
|
+
.kui-list:is([divider-sides*="b"], [data-scroll-divider*="b"]) {
|
|
122
122
|
--_kui-list-divider-bottom: var(--kui-list-divider-color);
|
|
123
123
|
}
|
|
124
124
|
|
|
125
|
-
.kui-list[divider-sides*="l"] {
|
|
125
|
+
.kui-list:is([divider-sides*="l"], [data-scroll-divider*="l"]) {
|
|
126
126
|
--_kui-list-divider-left: var(--kui-list-divider-color);
|
|
127
127
|
}
|
|
128
128
|
|
|
@@ -69,24 +69,6 @@
|
|
|
69
69
|
background: var(--kui-color-surface);
|
|
70
70
|
}
|
|
71
71
|
|
|
72
|
-
/* A navigation bar is one control band tall: the toolbar keeps its inline
|
|
73
|
-
padding and any claimed block inset, but drops the block gap so the bar is
|
|
74
|
-
the band height (44px) plus the unsafe inset it clears. */
|
|
75
|
-
.kui-nav-stack__chrome > .kui-nav-stack__toolbar {
|
|
76
|
-
min-height: calc(
|
|
77
|
-
var(--_kui-toolbar-band) + var(--_kui-toolbar-safe-block-start) +
|
|
78
|
-
var(--_kui-toolbar-safe-block-end)
|
|
79
|
-
);
|
|
80
|
-
padding-block: var(--_kui-toolbar-safe-block-start)
|
|
81
|
-
var(--_kui-toolbar-safe-block-end);
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
/* The title fills the leading zone beside the back control and truncates. */
|
|
85
|
-
.kui-nav-stack__title {
|
|
86
|
-
flex: 1 1 auto;
|
|
87
|
-
min-width: 0;
|
|
88
|
-
}
|
|
89
|
-
|
|
90
72
|
.kui-nav-stack__viewport {
|
|
91
73
|
--kui-edge-inset-block-start: var(--_kui-nav-stack-safe-block-start);
|
|
92
74
|
--kui-edge-inset-block-end: var(--_kui-nav-stack-safe-block-end);
|
|
@@ -179,10 +161,45 @@
|
|
|
179
161
|
padding-block-end: var(--_kui-nav-stack-safe-block-end);
|
|
180
162
|
padding-inline: var(--_kui-nav-stack-safe-inline-start)
|
|
181
163
|
var(--_kui-nav-stack-safe-inline-end);
|
|
182
|
-
border-block-start: 1px solid
|
|
164
|
+
border-block-start: 1px solid
|
|
165
|
+
var(--_kui-nav-stack-bottom-divider, transparent);
|
|
183
166
|
background: var(--kui-color-surface);
|
|
184
167
|
}
|
|
185
168
|
|
|
169
|
+
/* The live chrome is the containing block of its scroll divider; a
|
|
170
|
+
cross-fading copy stays absolutely positioned. */
|
|
171
|
+
.kui-nav-stack__chrome:not(.kui-nav-stack__chrome-copy) {
|
|
172
|
+
position: relative;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
/* Chrome dividers: with `chromeDividers="scroll"` (the default, no
|
|
176
|
+
attribute) the top chrome draws a line along its bottom edge while the
|
|
177
|
+
active view's content is scrolled beneath it, and the bottom toolbar
|
|
178
|
+
colors its 1px top border while more content lies below it — never when
|
|
179
|
+
the content fits. `wireScrollDividers` reports that state through
|
|
180
|
+
`data-scroll-divider`; `always` draws both lines without it, and `none`
|
|
181
|
+
neither, whatever it reports. The chrome's line is an overlaid 1px pseudo-element
|
|
182
|
+
(whatever the chrome holds never covers it) and the bottom's border is
|
|
183
|
+
always there, so showing either never moves the chrome, the toolbar, or
|
|
184
|
+
the content. A cross-fading chrome copy keeps the line its snapshot had. */
|
|
185
|
+
.kui-nav-stack:not([data-chrome-dividers])
|
|
186
|
+
> .kui-nav-stack__chrome[data-scroll-divider*="b"]::after,
|
|
187
|
+
.kui-nav-stack[data-chrome-dividers="always"] > .kui-nav-stack__chrome::after {
|
|
188
|
+
position: absolute;
|
|
189
|
+
block-size: 1px;
|
|
190
|
+
background: var(--kui-color-neutral-border-normal);
|
|
191
|
+
content: "";
|
|
192
|
+
inset-block-end: 0;
|
|
193
|
+
inset-inline: 0;
|
|
194
|
+
pointer-events: none;
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
.kui-nav-stack:not([data-chrome-dividers])
|
|
198
|
+
> .kui-nav-stack__bottom[data-scroll-divider*="t"],
|
|
199
|
+
.kui-nav-stack[data-chrome-dividers="always"] > .kui-nav-stack__bottom {
|
|
200
|
+
--_kui-nav-stack-bottom-divider: var(--kui-color-neutral-border-normal);
|
|
201
|
+
}
|
|
202
|
+
|
|
186
203
|
@media (prefers-reduced-motion: reduce) {
|
|
187
204
|
.kui-nav-stack__view,
|
|
188
205
|
.kui-nav-stack__chrome,
|
|
@@ -191,3 +208,13 @@
|
|
|
191
208
|
transition: none;
|
|
192
209
|
}
|
|
193
210
|
}
|
|
211
|
+
|
|
212
|
+
/* As the only child of a Workbench region (its main area or a panel's
|
|
213
|
+
content, which the Workbench marks with `data-workbench-main` /
|
|
214
|
+
`data-workbench-panel-content`), a NavStack fills the region, so a
|
|
215
|
+
composed toolbar's footer (or the app's own) sits at the region's bottom
|
|
216
|
+
edge rather than under short content. */
|
|
217
|
+
:is([data-workbench-main], [data-workbench-panel-content])
|
|
218
|
+
> [data-component="nav-stack"]:only-child {
|
|
219
|
+
height: 100%;
|
|
220
|
+
}
|
package/dist/styles/pane.css
CHANGED
|
@@ -147,6 +147,37 @@
|
|
|
147
147
|
grid-area: footer;
|
|
148
148
|
}
|
|
149
149
|
|
|
150
|
+
/* Chrome dividers: one line under the header and one over the footer, where
|
|
151
|
+
the pinned chrome meets the scrolling content, whatever the chrome holds.
|
|
152
|
+
`chromeDividers="scroll"` (the default, no attribute) draws each only while
|
|
153
|
+
`wireScrollDividers` reports content scrolled away beneath it through
|
|
154
|
+
`data-scroll-divider` on the slot; `always` draws both; `none` neither. The
|
|
155
|
+
line is an inset shadow inside the slot, so showing or hiding it never
|
|
156
|
+
moves the chrome or the content. */
|
|
157
|
+
.kui-pane > :is(.kui-pane__header, .kui-pane__toolbar, .kui-pane__footer) {
|
|
158
|
+
--_kui-pane-chrome-divider: transparent;
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
.kui-pane > :is(.kui-pane__header, .kui-pane__toolbar) {
|
|
162
|
+
box-shadow: inset 0 -1px var(--_kui-pane-chrome-divider);
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
.kui-pane > .kui-pane__footer {
|
|
166
|
+
box-shadow: inset 0 1px var(--_kui-pane-chrome-divider);
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
.kui-pane:not([data-chrome-dividers])
|
|
170
|
+
> :is(.kui-pane__header, .kui-pane__toolbar)[data-scroll-divider*="b"],
|
|
171
|
+
.kui-pane:not([data-chrome-dividers])
|
|
172
|
+
> .kui-pane__footer[data-scroll-divider*="t"],
|
|
173
|
+
.kui-pane[data-chrome-dividers="always"]
|
|
174
|
+
> :is(.kui-pane__header, .kui-pane__toolbar, .kui-pane__footer) {
|
|
175
|
+
--_kui-pane-chrome-divider: var(
|
|
176
|
+
--kui-pane-separator-color,
|
|
177
|
+
var(--kui-color-neutral-border-normal)
|
|
178
|
+
);
|
|
179
|
+
}
|
|
180
|
+
|
|
150
181
|
/* `chromePlacement="auto"`: the header and footer stay pinned while the pane
|
|
151
182
|
is tall enough; below 480px of height (30rem, so it scales with the text
|
|
152
183
|
size) the whole pane scrolls as one column instead, so tall chrome can never
|
|
@@ -177,3 +208,22 @@
|
|
|
177
208
|
overflow: visible;
|
|
178
209
|
}
|
|
179
210
|
}
|
|
211
|
+
|
|
212
|
+
/* As the only child of a Workbench region (its main area or a panel's
|
|
213
|
+
content, which the Workbench marks with `data-workbench-main` /
|
|
214
|
+
`data-workbench-panel-content`), a Pane fills the region, so a
|
|
215
|
+
composed toolbar's footer (or the app's own) sits at the region's bottom
|
|
216
|
+
edge rather than under short content. */
|
|
217
|
+
:is([data-workbench-main], [data-workbench-panel-content])
|
|
218
|
+
> [data-component="pane"]:only-child {
|
|
219
|
+
height: 100%;
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
/* As the only child of a NavStack view or a TabScaffold scene, a Pane fills
|
|
223
|
+
it too, so its content owns the scroll and its header and footer stay
|
|
224
|
+
pinned; the view or scene then never scrolls (it hands the Pane its
|
|
225
|
+
safe-area edge context, which the Pane's slots apply). */
|
|
226
|
+
:is(.kui-nav-stack__view, .kui-tab-scaffold__scene)
|
|
227
|
+
> [data-component="pane"]:only-child {
|
|
228
|
+
height: 100%;
|
|
229
|
+
}
|