@kerfjs/ui 5.0.0-beta.107 → 5.0.0-beta.109
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/ai/component-catalog.json +26 -13
- package/ai/component-composition-rules.json +2 -2
- package/ai/component-composition.json +10 -4
- package/ai/components/button.md +5 -5
- package/ai/components/chip.md +1 -0
- package/ai/components/foundation.md +1 -1
- package/ai/components/list.md +1 -1
- package/ai/components/segmented-control.md +1 -0
- package/ai/components/surface-scaffold.md +1 -0
- package/ai/components/tab-bar.md +5 -5
- package/ai/components/text-field.md +3 -1
- package/ai/components/toolbar-control-group.md +1 -0
- package/ai/components/toolbar.md +1 -1
- package/ai/public-api-signatures-v1.md +66 -15
- package/ai/skill.md +13 -7
- package/ai/webawesome-jsx-signatures-v1.md +1 -1
- package/dist/button.d.ts +3 -3
- package/dist/button.js +1 -1
- package/dist/catalog.js +4 -4
- package/dist/chip.d.ts +20 -2
- package/dist/chip.js +2 -1
- package/dist/{chunk-23PPPNH6.js → chunk-4OV272LF.js} +2 -2
- package/dist/{chunk-23PPPNH6.js.map → chunk-4OV272LF.js.map} +1 -1
- package/dist/{chunk-2PXZBFEC.js → chunk-5J6Z4BWY.js} +1 -1
- package/dist/{chunk-2PXZBFEC.js.map → chunk-5J6Z4BWY.js.map} +1 -1
- package/dist/{chunk-G4DRH4A5.js → chunk-6CDILXF4.js} +3 -1
- package/dist/chunk-6CDILXF4.js.map +1 -0
- package/dist/{chunk-RFLW4FPL.js → chunk-7AK5I7U7.js} +1 -1
- package/dist/chunk-7AK5I7U7.js.map +1 -0
- package/dist/{chunk-NLMEDZRM.js → chunk-CPSGUGAY.js} +5 -5
- package/dist/{chunk-NLMEDZRM.js.map → chunk-CPSGUGAY.js.map} +1 -1
- package/dist/{chunk-TXRKCGT3.js → chunk-KPINJHIC.js} +1 -1
- package/dist/chunk-KPINJHIC.js.map +1 -0
- package/dist/{chunk-N7MBGONH.js → chunk-LMHN2TJL.js} +22 -2
- package/dist/chunk-LMHN2TJL.js.map +1 -0
- package/dist/{chunk-NS2TBYM4.js → chunk-LZUUUHNH.js} +7 -3
- package/dist/chunk-LZUUUHNH.js.map +1 -0
- package/dist/{chunk-OY2MXIBB.js → chunk-NB6POCFH.js} +3 -1
- package/dist/chunk-NB6POCFH.js.map +1 -0
- package/dist/{chunk-AZ3WT77F.js → chunk-P7EJ4CAD.js} +2 -2
- package/dist/{chunk-AZ3WT77F.js.map → chunk-P7EJ4CAD.js.map} +1 -1
- package/dist/{chunk-Z4DS77U2.js → chunk-SOFPUW3O.js} +4 -4
- package/dist/{chunk-Z4DS77U2.js.map → chunk-SOFPUW3O.js.map} +1 -1
- package/dist/{chunk-QLA25V2K.js → chunk-WPNIKZMJ.js} +15 -1
- package/dist/chunk-WPNIKZMJ.js.map +1 -0
- package/dist/{chunk-DNWWF6UN.js → chunk-WSEJ2FDE.js} +4 -4
- package/dist/{chunk-DNWWF6UN.js.map → chunk-WSEJ2FDE.js.map} +1 -1
- package/dist/{chunk-WU57BYYM.js → chunk-YVZCKXR3.js} +8 -2
- package/dist/chunk-YVZCKXR3.js.map +1 -0
- package/dist/{chunk-CMLPFIC5.js → chunk-ZN7KUMPY.js} +3 -1
- package/dist/chunk-ZN7KUMPY.js.map +1 -0
- package/dist/collapsible-panel.js +2 -2
- package/dist/index.js +10 -10
- package/dist/list-detail-dialog.js +4 -4
- package/dist/list.d.ts +7 -1
- package/dist/list.js +1 -1
- package/dist/message-composer.js +1 -1
- package/dist/nav-stack.js +1 -1
- package/dist/segmented-control.d.ts +3 -1
- package/dist/segmented-control.js +1 -1
- package/dist/split-view.js +1 -1
- package/dist/styles/button.css +28 -2
- package/dist/styles/components/actions/button/button.css +28 -2
- package/dist/styles/components/actions/toolbar/toolbar.css +9 -0
- package/dist/styles/components/actions/toolbar-control-group/toolbar-control-group.css +29 -1
- package/dist/styles/components/collections/framed-list/framed-list.css +2 -0
- package/dist/styles/components/layout/pane/pane.css +15 -0
- package/dist/styles/components/navigation/nav-stack/nav-stack.css +13 -0
- package/dist/styles/components/navigation/tab-bar/tab-bar.css +6 -0
- package/dist/styles/components/navigation/tab-navigator/tab-navigator.css +16 -0
- package/dist/styles/components/surfaces/surface-scaffold/surface-scaffold.css +2 -0
- package/dist/styles/foundation.css +63 -19
- package/dist/styles/framed-list.css +2 -0
- package/dist/styles/nav-stack.css +13 -0
- package/dist/styles/pane.css +15 -0
- package/dist/styles/surface-scaffold.css +2 -0
- package/dist/styles/tab-bar.css +6 -0
- package/dist/styles/tab-navigator.css +16 -0
- package/dist/styles/toolbar-control-group.css +29 -1
- package/dist/styles/toolbar.css +9 -0
- package/dist/styles/webawesome.css +11 -3
- package/dist/surface-scaffold.d.ts +9 -1
- package/dist/surface-scaffold.js +1 -1
- package/dist/tab-bar.d.ts +2 -2
- package/dist/tab-bar.js +1 -1
- package/dist/text-field.d.ts +7 -1
- package/dist/text-field.js +1 -1
- package/dist/toolbar-control-group.d.ts +8 -2
- package/dist/toolbar-control-group.js +1 -1
- package/dist/toolbar.d.ts +6 -1
- package/dist/toolbar.js +1 -1
- package/dist/wire-catalog.js +1 -1
- package/dist/wire-workbench.js +1 -1
- package/dist/workbench-dialog.js +3 -3
- package/dist/workbench.js +1 -1
- package/docs/accessibility.md +29 -11
- package/docs/component-contract.md +19 -6
- package/docs/component-selection.md +38 -12
- package/docs/design/templates/button/tones-dark.svg +1 -1
- package/docs/design/templates/button/tones.svg +1 -1
- package/docs/design/templates/button-dark.svg +1 -1
- package/docs/design/templates/button.svg +1 -1
- package/docs/design/templates/split-button/states-dark.svg +1 -1
- package/docs/design/templates/split-button/states.svg +1 -1
- package/docs/design/templates/split-button-dark.svg +1 -1
- package/docs/design/templates/split-button.svg +1 -1
- package/docs/design/templates/text-field/number-dark.svg +1 -0
- package/docs/design/templates/text-field/number.svg +1 -0
- package/docs/design/templates/text-field-dark.svg +1 -1
- package/docs/design/templates/text-field.svg +1 -1
- package/docs/layout.md +16 -5
- package/docs/webawesome-migration.md +2 -0
- package/docs/webawesome-theme.md +8 -2
- package/docs/workbench.md +7 -1
- package/llms.txt +19 -7
- package/package.json +1 -1
- package/dist/chunk-CMLPFIC5.js.map +0 -1
- package/dist/chunk-G4DRH4A5.js.map +0 -1
- package/dist/chunk-N7MBGONH.js.map +0 -1
- package/dist/chunk-NS2TBYM4.js.map +0 -1
- package/dist/chunk-OY2MXIBB.js.map +0 -1
- package/dist/chunk-QLA25V2K.js.map +0 -1
- package/dist/chunk-RFLW4FPL.js.map +0 -1
- package/dist/chunk-TXRKCGT3.js.map +0 -1
- package/dist/chunk-WU57BYYM.js.map +0 -1
package/dist/index.js
CHANGED
|
@@ -16,21 +16,21 @@ export { ValueTable, ValueTableRow } from './chunk-DZJ4GBSP.js';
|
|
|
16
16
|
export { wireScrollDividers } from './chunk-OZ6X76G5.js';
|
|
17
17
|
export { wireCheckboxes } from './chunk-CNM6ZWP2.js';
|
|
18
18
|
export { TabBarItem } from './chunk-ZCDRLN3B.js';
|
|
19
|
-
export { TabBar } from './chunk-
|
|
20
|
-
export { TextField } from './chunk-
|
|
19
|
+
export { TabBar } from './chunk-7AK5I7U7.js';
|
|
20
|
+
export { TextField } from './chunk-YVZCKXR3.js';
|
|
21
21
|
export { Spacer } from './chunk-YMUIQRWK.js';
|
|
22
22
|
export { SplitButton } from './chunk-TI2GV36S.js';
|
|
23
23
|
export { StateBanner } from './chunk-2FW7D4IG.js';
|
|
24
24
|
export { SummaryRow } from './chunk-4UB5Z3ZZ.js';
|
|
25
25
|
export { SunkenPanel } from './chunk-D5RGM3XA.js';
|
|
26
26
|
export { createSearchFieldModel } from './chunk-CIAUILRR.js';
|
|
27
|
-
export { SegmentedControl } from './chunk-
|
|
27
|
+
export { SegmentedControl } from './chunk-LZUUUHNH.js';
|
|
28
28
|
export { Select } from './chunk-ZX2QQJXD.js';
|
|
29
29
|
|
|
30
30
|
export { applySelection, isApplePlatform, selectionGesture } from './chunk-GXSX6Q6O.js';
|
|
31
|
-
export { MessageComposer } from './chunk-
|
|
31
|
+
export { MessageComposer } from './chunk-4OV272LF.js';
|
|
32
32
|
export { RadioGroup } from './chunk-OHPYT2BH.js';
|
|
33
|
-
export { DialogSurface, PopoverDialogSurface, PopupSurface } from './chunk-
|
|
33
|
+
export { DialogSurface, PopoverDialogSurface, PopupSurface } from './chunk-6CDILXF4.js';
|
|
34
34
|
export { closeDialog, openDialog } from './chunk-ATGAJVZ6.js';
|
|
35
35
|
|
|
36
36
|
export { EmptyState } from './chunk-B53PS2LE.js';
|
|
@@ -43,13 +43,13 @@ export { ContentItem } from './chunk-5USKCWGL.js';
|
|
|
43
43
|
export { ContentSwap } from './chunk-EIET4QLK.js';
|
|
44
44
|
export { CornerStatus } from './chunk-G3J7JDP6.js';
|
|
45
45
|
export { EdgeActivityIndicator } from './chunk-QH5KOFNS.js';
|
|
46
|
-
export { Chip } from './chunk-
|
|
46
|
+
export { Chip } from './chunk-LMHN2TJL.js';
|
|
47
47
|
export { ChoiceChips } from './chunk-ITUQC4FW.js';
|
|
48
48
|
export { ColumnTrack } from './chunk-QYMJHS4K.js';
|
|
49
49
|
export { Combobox } from './chunk-BKUMG2KB.js';
|
|
50
50
|
export { openAnchoredSurface, openAnchoredSurfaceAt } from './chunk-3WYREXW4.js';
|
|
51
51
|
export { BackdropImage } from './chunk-SCDWURBO.js';
|
|
52
|
-
export { Button } from './chunk-
|
|
52
|
+
export { Button } from './chunk-KPINJHIC.js';
|
|
53
53
|
export { Switch } from './chunk-LTBVP6VN.js';
|
|
54
54
|
export { Row } from './chunk-AMIHGFLP.js';
|
|
55
55
|
export { SearchField, placeSearchFieldCaret, readSearchField } from './chunk-VEME3D7K.js';
|
|
@@ -67,12 +67,12 @@ export { PopupMenu, closePopupMenu, openPopupMenu, openPopupMenuAt } from './chu
|
|
|
67
67
|
|
|
68
68
|
export { Skeleton } from './chunk-CVD5IZGB.js';
|
|
69
69
|
export { DisclosureArrow } from './chunk-TKNVL53O.js';
|
|
70
|
-
export { ToolbarActionLink, ToolbarControlGroup } from './chunk-
|
|
71
|
-
export { Toolbar } from './chunk-
|
|
70
|
+
export { ToolbarActionLink, ToolbarControlGroup } from './chunk-5J6Z4BWY.js';
|
|
71
|
+
export { Toolbar } from './chunk-ZN7KUMPY.js';
|
|
72
72
|
export { Pane } from './chunk-HQZG3OFL.js';
|
|
73
73
|
|
|
74
74
|
export { ensureSunkenTexture } from './chunk-IKS72C6P.js';
|
|
75
|
-
export { List } from './chunk-
|
|
75
|
+
export { List } from './chunk-NB6POCFH.js';
|
|
76
76
|
|
|
77
77
|
|
|
78
78
|
export { LoadingSpinner } from './chunk-WVS6CUCT.js';
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { SplitView } from './chunk-
|
|
2
|
-
import { DialogSurface } from './chunk-
|
|
1
|
+
import { SplitView } from './chunk-P7EJ4CAD.js';
|
|
2
|
+
import { DialogSurface } from './chunk-6CDILXF4.js';
|
|
3
3
|
export { closeDialog, openDialog } from './chunk-ATGAJVZ6.js';
|
|
4
4
|
|
|
5
5
|
|
|
@@ -7,8 +7,8 @@ export { closeDialog, openDialog } from './chunk-ATGAJVZ6.js';
|
|
|
7
7
|
import { ToolbarText } from './chunk-EKHDLBRP.js';
|
|
8
8
|
|
|
9
9
|
|
|
10
|
-
import { ToolbarControlGroup } from './chunk-
|
|
11
|
-
import { Toolbar } from './chunk-
|
|
10
|
+
import { ToolbarControlGroup } from './chunk-5J6Z4BWY.js';
|
|
11
|
+
import { Toolbar } from './chunk-ZN7KUMPY.js';
|
|
12
12
|
import { Pane } from './chunk-HQZG3OFL.js';
|
|
13
13
|
|
|
14
14
|
|
package/dist/list.d.ts
CHANGED
|
@@ -121,6 +121,12 @@ interface ListProps {
|
|
|
121
121
|
/** Physical sides that receive the standard 8px control inset. Text insets win on overlap. */
|
|
122
122
|
controlInsets?: Sides;
|
|
123
123
|
className?: string;
|
|
124
|
+
/**
|
|
125
|
+
* The list's id, so app code can address it: name it as a
|
|
126
|
+
* `wireScrollDividers` scroller (with a `Toolbar` above it as its chrome),
|
|
127
|
+
* or find it in tests.
|
|
128
|
+
*/
|
|
129
|
+
id?: string;
|
|
124
130
|
/**
|
|
125
131
|
* Safe `data-*`, `aria-*`, and structural `role` metadata (a named drop
|
|
126
132
|
* `region`, `aria-busy`); List-owned structural attributes remain
|
|
@@ -138,6 +144,6 @@ interface ListProps {
|
|
|
138
144
|
*/
|
|
139
145
|
type ListConfig = Pick<ListProps, 'gap' | 'hAlign' | 'vAlign' | 'dividerSides' | 'textInsets' | 'controlInsets'>;
|
|
140
146
|
/** A stretch-aligned vertical stack with optional gap, flex, fill, scroll, and dividers. */
|
|
141
|
-
declare function List({ children, selectionMode, ariaLabel, gap, flex, fill, hAlign, vAlign, scrollable, scrollClearance, frame, maxHeight, minHeight, surface, inset, contentWidth, contentAlign, dividerSides, textInsets, controlInsets, className, rootAttributes, slot, }: ListProps): kerfjs.SafeHtml;
|
|
147
|
+
declare function List({ children, selectionMode, ariaLabel, gap, flex, fill, hAlign, vAlign, scrollable, scrollClearance, frame, maxHeight, minHeight, surface, inset, contentWidth, contentAlign, dividerSides, textInsets, controlInsets, className, id, rootAttributes, slot, }: ListProps): kerfjs.SafeHtml;
|
|
142
148
|
|
|
143
149
|
export { CssFlex, CssFlexKeyword, CssLength, HorizontalAlignment, List, type ListConfig, type ListContentWidth, type ListInset, type ListProps, type ListSurface, ListVerticalAlignment, ScrollClearance, Sides, UiGap };
|
package/dist/list.js
CHANGED
package/dist/message-composer.js
CHANGED
package/dist/nav-stack.js
CHANGED
|
@@ -25,9 +25,11 @@ interface SegmentedControlProps<Value extends string = string> {
|
|
|
25
25
|
className?: string;
|
|
26
26
|
/** Render as a loading placeholder: every choice keeps its live label or icon, none is selected, and every segment is disabled. */
|
|
27
27
|
placeholder?: boolean;
|
|
28
|
+
/** Disable the whole control: every segment is disabled and dimmed, the selection stays visible, and the group reports `aria-disabled`. A choice's own `disabled` still disables just that segment. */
|
|
29
|
+
disabled?: boolean;
|
|
28
30
|
/** Native named-slot assignment when composed inside a web component. */
|
|
29
31
|
slot?: string;
|
|
30
32
|
}
|
|
31
|
-
declare function SegmentedControl<Value extends string>({ id, label, value, choices, action, appearance, shape, size, layout, className, placeholder, slot, }: SegmentedControlProps<Value>): kerfjs.SafeHtml;
|
|
33
|
+
declare function SegmentedControl<Value extends string>({ id, label, value, choices, action, appearance, shape, size, layout, className, placeholder, disabled, slot, }: SegmentedControlProps<Value>): kerfjs.SafeHtml;
|
|
32
34
|
|
|
33
35
|
export { SegmentedControl, type SegmentedControlAppearance, type SegmentedControlChoice, type SegmentedControlLayout, type SegmentedControlProps, type SegmentedControlShape, type SegmentedControlSize };
|
package/dist/split-view.js
CHANGED
package/dist/styles/button.css
CHANGED
|
@@ -47,6 +47,13 @@
|
|
|
47
47
|
--_kui-button-on-quiet: var(--kui-color-brand-on-quiet);
|
|
48
48
|
--_kui-button-outline: var(--kui-color-brand-border-loud);
|
|
49
49
|
}
|
|
50
|
+
.kui-button[data-tone="success"] {
|
|
51
|
+
--_kui-button-fill: var(--kui-color-success-fill-loud);
|
|
52
|
+
--_kui-button-text: var(--kui-color-success-on-loud);
|
|
53
|
+
--_kui-button-quiet: var(--kui-color-success-fill-quiet);
|
|
54
|
+
--_kui-button-on-quiet: var(--kui-color-success-on-fill);
|
|
55
|
+
--_kui-button-outline: var(--kui-color-success-border-loud);
|
|
56
|
+
}
|
|
50
57
|
.kui-button[data-tone="danger"] {
|
|
51
58
|
--_kui-button-fill: var(--kui-color-danger-fill-loud);
|
|
52
59
|
--_kui-button-text: var(--kui-color-danger-on-loud);
|
|
@@ -92,9 +99,10 @@
|
|
|
92
99
|
border-radius: var(--kui-layout-pill-radius, calc(1px + 1.3125rem));
|
|
93
100
|
}
|
|
94
101
|
/* A pressed neutral toggle takes the brand accent, as a pressed toolbar group
|
|
95
|
-
control and a selected chip do;
|
|
102
|
+
control and a selected chip do; semantic tones keep their own color. */
|
|
96
103
|
.kui-button[aria-pressed="true"]:not(
|
|
97
104
|
[data-tone="brand"],
|
|
105
|
+
[data-tone="success"],
|
|
98
106
|
[data-tone="danger"]
|
|
99
107
|
) {
|
|
100
108
|
--_kui-button-fill: var(--kui-color-brand-fill-loud);
|
|
@@ -105,7 +113,7 @@
|
|
|
105
113
|
}
|
|
106
114
|
/* A pressed toggle draws on top of its tone and emphasis. Secondary and plain
|
|
107
115
|
take the tone's quiet fill with a doubled tone outline; primary keeps its
|
|
108
|
-
loud fill (darkened for
|
|
116
|
+
loud fill (darkened for semantic tones) with an inset ring. The second pixel of outline marks
|
|
109
117
|
the state without relying on hue. */
|
|
110
118
|
.kui-button[aria-pressed="true"]:is(
|
|
111
119
|
[data-emphasis="secondary"],
|
|
@@ -133,6 +141,16 @@
|
|
|
133
141
|
light-dark(#000, #fff) 18%
|
|
134
142
|
);
|
|
135
143
|
}
|
|
144
|
+
.kui-button[data-tone="success"][aria-pressed="true"]:not(
|
|
145
|
+
[data-emphasis="secondary"],
|
|
146
|
+
[data-emphasis="plain"]
|
|
147
|
+
) {
|
|
148
|
+
--_kui-button-fill: color-mix(
|
|
149
|
+
in oklab,
|
|
150
|
+
var(--kui-color-success-fill-loud),
|
|
151
|
+
light-dark(#000, #fff) 18%
|
|
152
|
+
);
|
|
153
|
+
}
|
|
136
154
|
.kui-button[data-tone="danger"][aria-pressed="true"]:not(
|
|
137
155
|
[data-emphasis="secondary"],
|
|
138
156
|
[data-emphasis="plain"]
|
|
@@ -230,6 +248,14 @@
|
|
|
230
248
|
cursor: not-allowed;
|
|
231
249
|
opacity: 0.5;
|
|
232
250
|
}
|
|
251
|
+
/* Keep a disabled positive action quiet without fading its label below text
|
|
252
|
+
contrast. The subdued fill and border mark it unavailable. */
|
|
253
|
+
.kui-button[data-tone="success"]:is(:disabled, [aria-disabled="true"]) {
|
|
254
|
+
--_kui-button-fill: var(--kui-color-success-fill-quiet);
|
|
255
|
+
--_kui-button-text: var(--kui-color-success-on-fill);
|
|
256
|
+
--_kui-button-border: var(--kui-color-success-border-quiet);
|
|
257
|
+
opacity: 1;
|
|
258
|
+
}
|
|
233
259
|
.kui-button__icon {
|
|
234
260
|
display: inline-flex;
|
|
235
261
|
flex: none;
|
|
@@ -47,6 +47,13 @@
|
|
|
47
47
|
--_kui-button-on-quiet: var(--kui-color-brand-on-quiet);
|
|
48
48
|
--_kui-button-outline: var(--kui-color-brand-border-loud);
|
|
49
49
|
}
|
|
50
|
+
.kui-button[data-tone="success"] {
|
|
51
|
+
--_kui-button-fill: var(--kui-color-success-fill-loud);
|
|
52
|
+
--_kui-button-text: var(--kui-color-success-on-loud);
|
|
53
|
+
--_kui-button-quiet: var(--kui-color-success-fill-quiet);
|
|
54
|
+
--_kui-button-on-quiet: var(--kui-color-success-on-fill);
|
|
55
|
+
--_kui-button-outline: var(--kui-color-success-border-loud);
|
|
56
|
+
}
|
|
50
57
|
.kui-button[data-tone="danger"] {
|
|
51
58
|
--_kui-button-fill: var(--kui-color-danger-fill-loud);
|
|
52
59
|
--_kui-button-text: var(--kui-color-danger-on-loud);
|
|
@@ -92,9 +99,10 @@
|
|
|
92
99
|
border-radius: var(--kui-layout-pill-radius, calc(1px + 1.3125rem));
|
|
93
100
|
}
|
|
94
101
|
/* A pressed neutral toggle takes the brand accent, as a pressed toolbar group
|
|
95
|
-
control and a selected chip do;
|
|
102
|
+
control and a selected chip do; semantic tones keep their own color. */
|
|
96
103
|
.kui-button[aria-pressed="true"]:not(
|
|
97
104
|
[data-tone="brand"],
|
|
105
|
+
[data-tone="success"],
|
|
98
106
|
[data-tone="danger"]
|
|
99
107
|
) {
|
|
100
108
|
--_kui-button-fill: var(--kui-color-brand-fill-loud);
|
|
@@ -105,7 +113,7 @@
|
|
|
105
113
|
}
|
|
106
114
|
/* A pressed toggle draws on top of its tone and emphasis. Secondary and plain
|
|
107
115
|
take the tone's quiet fill with a doubled tone outline; primary keeps its
|
|
108
|
-
loud fill (darkened for
|
|
116
|
+
loud fill (darkened for semantic tones) with an inset ring. The second pixel of outline marks
|
|
109
117
|
the state without relying on hue. */
|
|
110
118
|
.kui-button[aria-pressed="true"]:is(
|
|
111
119
|
[data-emphasis="secondary"],
|
|
@@ -133,6 +141,16 @@
|
|
|
133
141
|
light-dark(#000, #fff) 18%
|
|
134
142
|
);
|
|
135
143
|
}
|
|
144
|
+
.kui-button[data-tone="success"][aria-pressed="true"]:not(
|
|
145
|
+
[data-emphasis="secondary"],
|
|
146
|
+
[data-emphasis="plain"]
|
|
147
|
+
) {
|
|
148
|
+
--_kui-button-fill: color-mix(
|
|
149
|
+
in oklab,
|
|
150
|
+
var(--kui-color-success-fill-loud),
|
|
151
|
+
light-dark(#000, #fff) 18%
|
|
152
|
+
);
|
|
153
|
+
}
|
|
136
154
|
.kui-button[data-tone="danger"][aria-pressed="true"]:not(
|
|
137
155
|
[data-emphasis="secondary"],
|
|
138
156
|
[data-emphasis="plain"]
|
|
@@ -230,6 +248,14 @@
|
|
|
230
248
|
cursor: not-allowed;
|
|
231
249
|
opacity: 0.5;
|
|
232
250
|
}
|
|
251
|
+
/* Keep a disabled positive action quiet without fading its label below text
|
|
252
|
+
contrast. The subdued fill and border mark it unavailable. */
|
|
253
|
+
.kui-button[data-tone="success"]:is(:disabled, [aria-disabled="true"]) {
|
|
254
|
+
--_kui-button-fill: var(--kui-color-success-fill-quiet);
|
|
255
|
+
--_kui-button-text: var(--kui-color-success-on-fill);
|
|
256
|
+
--_kui-button-border: var(--kui-color-success-border-quiet);
|
|
257
|
+
opacity: 1;
|
|
258
|
+
}
|
|
233
259
|
.kui-button__icon {
|
|
234
260
|
display: inline-flex;
|
|
235
261
|
flex: none;
|
|
@@ -16,6 +16,15 @@
|
|
|
16
16
|
font-family: var(--kui-font-sans);
|
|
17
17
|
}
|
|
18
18
|
|
|
19
|
+
/* In a List, a vertical stack, the toolbar is chrome and keeps its whole
|
|
20
|
+
natural height. Its explicit one-band min-height (below) replaces the flex
|
|
21
|
+
item's automatic content minimum, so a column shrinking toward a long
|
|
22
|
+
flex scroller beside it would otherwise squeeze a wrapped or stacked
|
|
23
|
+
toolbar onto its first row and clip the rest. */
|
|
24
|
+
.kui-list > .kui-toolbar {
|
|
25
|
+
flex-shrink: 0;
|
|
26
|
+
}
|
|
27
|
+
|
|
19
28
|
/* Safe areas: a toolbar compensates only for the inline edges its owner hands
|
|
20
29
|
it through `--kui-edge-inset-inline-*` (a Pane header or footer does), so its
|
|
21
30
|
box and dividers keep reaching the edge while its zones clear the unsafe
|
|
@@ -132,6 +132,31 @@
|
|
|
132
132
|
}
|
|
133
133
|
}
|
|
134
134
|
|
|
135
|
+
/* A sibling of an expanded trailing control yields to the trailing-priority
|
|
136
|
+
row the Toolbar moves that control onto: the same container queries and
|
|
137
|
+
responsiveAt keys as the Toolbar's own row (toolbar.css), so the group
|
|
138
|
+
hides exactly while the row is active and never wraps onto a third row at
|
|
139
|
+
a threshold restated with hideBelow. */
|
|
140
|
+
@container kui-toolbar (max-width: 52rem) {
|
|
141
|
+
.kui-toolbar[data-responsive="trailing-priority"][data-responsive-at="narrow"]
|
|
142
|
+
> .kui-toolbar__trailing:has(> [data-expanded="true"])
|
|
143
|
+
> .kui-toolbar-control-group[data-visibility="yield-to-priority-row"]:not(
|
|
144
|
+
[data-expanded="true"]
|
|
145
|
+
) {
|
|
146
|
+
display: none;
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
@container kui-toolbar (max-width: 44rem) {
|
|
151
|
+
.kui-toolbar[data-responsive="trailing-priority"][data-responsive-at="compact"]
|
|
152
|
+
> .kui-toolbar__trailing:has(> [data-expanded="true"])
|
|
153
|
+
> .kui-toolbar-control-group[data-visibility="yield-to-priority-row"]:not(
|
|
154
|
+
[data-expanded="true"]
|
|
155
|
+
) {
|
|
156
|
+
display: none;
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
|
|
135
160
|
/* `shape="rounded"` swaps the default pill radius for the design system's softer
|
|
136
161
|
rounded rectangle. The shared highlight contract derives every inner hover or
|
|
137
162
|
selected surface from this outer radius and the group's full inset. */
|
|
@@ -206,7 +231,10 @@
|
|
|
206
231
|
border-color 0.2s ease;
|
|
207
232
|
}
|
|
208
233
|
|
|
209
|
-
|
|
234
|
+
/* A fill search spans a content-sized group's line. A `sizing="grow"` group
|
|
235
|
+
keeps its own grow basis instead (below): taking the whole line would make
|
|
236
|
+
it the line's hypothetical size and wrap every sibling group. */
|
|
237
|
+
.kui-toolbar-control-group[data-content="search"]:not([data-sizing="grow"]):has(
|
|
210
238
|
> .kui-search-field[data-expanded="true"][data-fill="true"]
|
|
211
239
|
) {
|
|
212
240
|
width: 100%;
|
|
@@ -76,11 +76,16 @@
|
|
|
76
76
|
surface instead. */
|
|
77
77
|
.kui-pane[data-background] {
|
|
78
78
|
background: var(--_kui-pane-background);
|
|
79
|
+
--kui-color-surface-current-region: var(--_kui-pane-background);
|
|
79
80
|
}
|
|
80
81
|
|
|
82
|
+
/* The transparent slots keep the root's surface context. */
|
|
81
83
|
.kui-pane[data-background][data-appearance="sunken"] > .kui-pane__content,
|
|
82
84
|
.kui-pane[data-background][data-appearance="sunken"][data-chrome-placement="auto"]
|
|
83
85
|
> :is(.kui-pane__header, .kui-pane__footer) {
|
|
86
|
+
--kui-color-surface-current: inherit;
|
|
87
|
+
--kui-color-surface-current-region: inherit;
|
|
88
|
+
--kui-color-surface-current-tint: inherit;
|
|
84
89
|
background: transparent;
|
|
85
90
|
}
|
|
86
91
|
|
|
@@ -266,6 +271,16 @@
|
|
|
266
271
|
background: var(--kui-chrome-material);
|
|
267
272
|
}
|
|
268
273
|
|
|
274
|
+
/* The material has no single color over scrolling content; the surface
|
|
275
|
+
context takes it at rest, as a tint over the region it covers. A clear
|
|
276
|
+
header paints nothing and keeps the inherited context. */
|
|
277
|
+
.kui-pane[data-header-presentation="overlay"]:not(
|
|
278
|
+
[data-header-material="clear"]
|
|
279
|
+
)
|
|
280
|
+
> .kui-pane__header {
|
|
281
|
+
--kui-color-surface-current-tint: var(--kui-chrome-material);
|
|
282
|
+
}
|
|
283
|
+
|
|
269
284
|
.kui-pane[data-header-presentation="overlay"][data-header-overlay="measured"]:not(
|
|
270
285
|
[data-chrome-placement="auto"]
|
|
271
286
|
)
|
|
@@ -224,6 +224,19 @@
|
|
|
224
224
|
background: var(--kui-chrome-material);
|
|
225
225
|
}
|
|
226
226
|
|
|
227
|
+
/* The material's surface context at rest (see pane.css); clear chrome keeps
|
|
228
|
+
the inherited context. */
|
|
229
|
+
.kui-nav-stack[data-chrome-presentation="overlay"]:not(
|
|
230
|
+
[data-chrome-material="clear"]
|
|
231
|
+
)
|
|
232
|
+
> .kui-nav-stack__chrome,
|
|
233
|
+
.kui-nav-stack[data-bottom-toolbar-presentation="overlay"]:not(
|
|
234
|
+
[data-bottom-toolbar-material="clear"]
|
|
235
|
+
)
|
|
236
|
+
> .kui-nav-stack__bottom {
|
|
237
|
+
--kui-color-surface-current-tint: var(--kui-chrome-material);
|
|
238
|
+
}
|
|
239
|
+
|
|
227
240
|
.kui-nav-stack[data-chrome-presentation="overlay"][data-chrome-overlay="measured"]
|
|
228
241
|
> .kui-nav-stack__chrome:not(.kui-nav-stack__chrome-copy) {
|
|
229
242
|
position: absolute;
|
|
@@ -38,6 +38,12 @@
|
|
|
38
38
|
--kui-tab-bar-strip-background,
|
|
39
39
|
var(--kui-tab-bar-background)
|
|
40
40
|
);
|
|
41
|
+
/* The surface context (foundation.css): the strip's fill is a tint over
|
|
42
|
+
whatever the bar sits on. */
|
|
43
|
+
--kui-color-surface-current-tint: var(
|
|
44
|
+
--kui-tab-bar-strip-background,
|
|
45
|
+
var(--kui-tab-bar-background)
|
|
46
|
+
);
|
|
41
47
|
scrollbar-width: none;
|
|
42
48
|
align-items: center;
|
|
43
49
|
flex: var(--kui-tab-bar-strip-flex, 1 1 auto);
|
|
@@ -70,6 +70,13 @@
|
|
|
70
70
|
|
|
71
71
|
.kui-tab-scaffold__scene[data-background] {
|
|
72
72
|
background: var(--_kui-tab-scaffold-scene-background);
|
|
73
|
+
--kui-color-surface-current-region: var(--_kui-tab-scaffold-scene-background);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/* The navigator's color paints its root and a docked bar over whatever holds
|
|
77
|
+
the navigator: a region in the surface context. */
|
|
78
|
+
.kui-tab-scaffold[data-background] {
|
|
79
|
+
--kui-color-surface-current-region: var(--_kui-tab-scaffold-background);
|
|
73
80
|
}
|
|
74
81
|
|
|
75
82
|
@media (forced-colors: active) {
|
|
@@ -213,6 +220,15 @@
|
|
|
213
220
|
background: var(--kui-chrome-material);
|
|
214
221
|
}
|
|
215
222
|
|
|
223
|
+
/* The material's surface context at rest (see pane.css); a clear bar keeps
|
|
224
|
+
the inherited context. */
|
|
225
|
+
.kui-tab-scaffold[data-bar-presentation="overlay"]:not(
|
|
226
|
+
[data-bar-material="clear"]
|
|
227
|
+
)
|
|
228
|
+
> .kui-tab-scaffold__bar {
|
|
229
|
+
--kui-color-surface-current-tint: var(--kui-chrome-material);
|
|
230
|
+
}
|
|
231
|
+
|
|
216
232
|
.kui-tab-scaffold[data-bar-presentation="overlay"][data-bar-overlay="measured"] {
|
|
217
233
|
position: relative;
|
|
218
234
|
}
|
|
@@ -337,6 +337,8 @@ h2.kui-dialog-surface__title {
|
|
|
337
337
|
-webkit-backdrop-filter: var(--kui-chrome-material-filter);
|
|
338
338
|
backdrop-filter: var(--kui-chrome-material-filter);
|
|
339
339
|
background: var(--kui-chrome-material-raised);
|
|
340
|
+
/* The material's surface context at rest, over the raised panel. */
|
|
341
|
+
--kui-color-surface-current-tint: var(--kui-chrome-material-raised);
|
|
340
342
|
/* The divider is scroll state: the register publishes it only while
|
|
341
343
|
content is scrolled beneath the header. An inset shadow, so showing it
|
|
342
344
|
never moves the header or the content. */
|
|
@@ -184,12 +184,15 @@
|
|
|
184
184
|
--kui-color-surface-current: the opaque surface beneath (default
|
|
185
185
|
--kui-color-surface); an opaque surface (a raised dialog or popup, a
|
|
186
186
|
base or raised List) sets it and clears the tint.
|
|
187
|
-
--kui-color-surface-current-region: a layout region's
|
|
188
|
-
|
|
189
|
-
default transparent).
|
|
190
|
-
--kui-color-surface-current-tint: a content surface's
|
|
191
|
-
|
|
192
|
-
|
|
187
|
+
--kui-color-surface-current-region: a layout region's fill over it
|
|
188
|
+
(a sunken Pane, Workbench area, or TabNavigator scene; a Pane's or
|
|
189
|
+
TabNavigator's app `background`; default transparent).
|
|
190
|
+
--kui-color-surface-current-tint: a content surface's fill over that
|
|
191
|
+
(a SunkenPanel, a sunken Disclosure, a lowered FramedList or its
|
|
192
|
+
highlighted row, a quiet ContentItem, a TabBar strip, and glass
|
|
193
|
+
chrome at rest: a Pane overlay header, NavStack overlay chrome, a
|
|
194
|
+
TabNavigator overlay bar, a dialog's floating header; default
|
|
195
|
+
transparent).
|
|
193
196
|
A reader layers the tint over the region over the color, so a content
|
|
194
197
|
surface inside a sunken region (the common nesting) composes exactly;
|
|
195
198
|
custom properties cannot fold an inherited value into a new one, so a
|
|
@@ -264,9 +267,11 @@
|
|
|
264
267
|
var(--kui-color-surface)
|
|
265
268
|
);
|
|
266
269
|
|
|
270
|
+
/* Each brand token below falls back to its tuned literal unless the app
|
|
271
|
+
sets the opt-in --kui-color-brand (see the brand ramp after this block). */
|
|
267
272
|
--kui-color-brand-fill-loud: var(
|
|
268
273
|
--wa-color-brand-fill-loud,
|
|
269
|
-
light-dark(#0075db, #64d2ff)
|
|
274
|
+
var(--_kui-brand-fill-loud, light-dark(#0075db, #64d2ff))
|
|
270
275
|
);
|
|
271
276
|
--kui-color-brand-fill-quiet: var(
|
|
272
277
|
--wa-color-brand-fill-quiet,
|
|
@@ -312,7 +317,7 @@
|
|
|
312
317
|
4.65:1 on the page (5.2:1 on white). */
|
|
313
318
|
--kui-color-brand-on-quiet: var(
|
|
314
319
|
--wa-color-brand-on-quiet,
|
|
315
|
-
light-dark(#0c62f3, #8acbff)
|
|
320
|
+
var(--_kui-brand-on-quiet, light-dark(#0c62f3, #8acbff))
|
|
316
321
|
);
|
|
317
322
|
--kui-color-brand-on-normal: var(
|
|
318
323
|
--wa-color-brand-on-normal,
|
|
@@ -328,7 +333,10 @@
|
|
|
328
333
|
4.26:1 over brand-fill-normal (#d6ecff), while #1a5dcf (same hue) clears
|
|
329
334
|
~4.9:1 there and ~5.5:1 over brand-fill-quiet (#ebf6ff). The dark value
|
|
330
335
|
matches brand-on-quiet, which already passes over the dark fills. */
|
|
331
|
-
--kui-color-brand-on-fill:
|
|
336
|
+
--kui-color-brand-on-fill: var(
|
|
337
|
+
--_kui-brand-on-fill,
|
|
338
|
+
light-dark(#1a5dcf, #8acbff)
|
|
339
|
+
);
|
|
332
340
|
|
|
333
341
|
/* Pop is attractive emphasis without status meaning: use it for featured,
|
|
334
342
|
novel, or celebratory content, never as a success/danger substitute. */
|
|
@@ -538,7 +546,11 @@
|
|
|
538
546
|
|
|
539
547
|
--kui-focus-ring: var(
|
|
540
548
|
--wa-focus-ring,
|
|
541
|
-
3px solid
|
|
549
|
+
3px solid
|
|
550
|
+
var(
|
|
551
|
+
--wa-color-focus,
|
|
552
|
+
var(--_kui-brand-focus, light-dark(#007aff, #64d2ff))
|
|
553
|
+
)
|
|
542
554
|
);
|
|
543
555
|
/* Elevation mirrors webawesome.css's scheme-aware shadows: dark raises the
|
|
544
556
|
alpha so a raised surface still separates from a near-black page. */
|
|
@@ -596,6 +608,37 @@
|
|
|
596
608
|
--kui-color-surface-current-tint: initial;
|
|
597
609
|
}
|
|
598
610
|
|
|
611
|
+
/* The opt-in brand, left undeclared so the tuned literals apply:
|
|
612
|
+
--kui-color-brand: any color an app sets on :root;
|
|
613
|
+
the whole brand ramp follows it, the way a scoped tint's accent re-derives
|
|
614
|
+
its ramp: the loud fill (and the quiet/normal fills and borders mixed from
|
|
615
|
+
it), brand text and links, brand text on brand fills, and the focus ring.
|
|
616
|
+
Lightness is clamped per scheme so every pair keeps WCAG AA for any hue
|
|
617
|
+
and chroma (the brand-ramp browser test sweeps them): a light fill stays
|
|
618
|
+
dark enough for white text and a dark one light enough for near-black
|
|
619
|
+
text; brand text stays dark enough for the page, the surface, and the
|
|
620
|
+
brand fills in light, and light enough in dark. Unset, each private
|
|
621
|
+
derivation references an undefined variable, is invalid, and the tokens
|
|
622
|
+
above keep their tuned literals exactly. Web Awesome's theme reads the
|
|
623
|
+
same derivations (webawesome.css). */
|
|
624
|
+
@supports (color: oklch(from red l c h)) {
|
|
625
|
+
:root {
|
|
626
|
+
--_kui-brand-fill-loud: light-dark(
|
|
627
|
+
oklch(from var(--kui-color-brand) min(l, 0.46) c h),
|
|
628
|
+
oklch(from var(--kui-color-brand) clamp(0.74, l, 0.86) c h)
|
|
629
|
+
);
|
|
630
|
+
--_kui-brand-on-quiet: light-dark(
|
|
631
|
+
oklch(from var(--kui-color-brand) min(l, 0.43) c h),
|
|
632
|
+
oklch(from var(--kui-color-brand) max(l, 0.86) c h)
|
|
633
|
+
);
|
|
634
|
+
--_kui-brand-on-fill: light-dark(
|
|
635
|
+
oklch(from var(--kui-color-brand) min(l, 0.38) c h),
|
|
636
|
+
oklch(from var(--kui-color-brand) max(l, 0.9) c h)
|
|
637
|
+
);
|
|
638
|
+
--_kui-brand-focus: var(--_kui-brand-fill-loud);
|
|
639
|
+
}
|
|
640
|
+
}
|
|
641
|
+
|
|
599
642
|
@supports (color: oklch(from red l c h)) {
|
|
600
643
|
@media not (prefers-contrast: more) {
|
|
601
644
|
[data-kui-tint="light"] {
|
|
@@ -646,21 +689,22 @@
|
|
|
646
689
|
scope: the loud fill (buttons, the current row, checked controls), its
|
|
647
690
|
on-loud text, brand text and links, text on brand fills, and the focus
|
|
648
691
|
ring. Lightness is clamped so each pair keeps WCAG AA for any accent:
|
|
649
|
-
a light scope's fill stays at or below
|
|
692
|
+
a light scope's fill stays at or below 46% under white text, a dark
|
|
650
693
|
scope's between 72% and 85% under near-black text, and brand text at
|
|
651
|
-
most
|
|
694
|
+
most 36% (light) or at least 94% (dark). Dark on-fill text also caps
|
|
695
|
+
chroma so a vivid red stays light after gamut clipping. */
|
|
652
696
|
[data-kui-tint="light"][data-kui-tint-accent] {
|
|
653
697
|
--wa-color-brand-fill-loud: oklch(
|
|
654
|
-
from var(--_kui-tint-accent) min(l, 0.
|
|
698
|
+
from var(--_kui-tint-accent) min(l, 0.46) c h
|
|
655
699
|
);
|
|
656
700
|
--wa-color-brand-on-loud: #fff;
|
|
657
701
|
--wa-color-brand-on-quiet: oklch(
|
|
658
|
-
from var(--_kui-tint-accent) min(l, 0.
|
|
702
|
+
from var(--_kui-tint-accent) min(l, 0.36) c h
|
|
659
703
|
);
|
|
660
704
|
--kui-color-brand-on-fill: oklch(
|
|
661
|
-
from var(--_kui-tint-accent) min(l, 0.
|
|
705
|
+
from var(--_kui-tint-accent) min(l, 0.3) c h
|
|
662
706
|
);
|
|
663
|
-
--wa-color-focus: oklch(from var(--_kui-tint-accent) min(l, 0.
|
|
707
|
+
--wa-color-focus: oklch(from var(--_kui-tint-accent) min(l, 0.46) c h);
|
|
664
708
|
}
|
|
665
709
|
|
|
666
710
|
[data-kui-tint="dark"][data-kui-tint-accent] {
|
|
@@ -669,13 +713,13 @@
|
|
|
669
713
|
);
|
|
670
714
|
--wa-color-brand-on-loud: #111113;
|
|
671
715
|
--wa-color-brand-on-quiet: oklch(
|
|
672
|
-
from var(--_kui-tint-accent) max(l, 0.
|
|
716
|
+
from var(--_kui-tint-accent) max(l, 0.94) c h
|
|
673
717
|
);
|
|
674
718
|
--kui-color-brand-on-fill: oklch(
|
|
675
|
-
from var(--_kui-tint-accent) max(l, 0.
|
|
719
|
+
from var(--_kui-tint-accent) max(l, 0.95) min(c, 0.12) h
|
|
676
720
|
);
|
|
677
721
|
--wa-color-focus: oklch(
|
|
678
|
-
from var(--_kui-tint-accent) clamp(0.
|
|
722
|
+
from var(--_kui-tint-accent) clamp(0.78, l, 0.85) c h
|
|
679
723
|
);
|
|
680
724
|
}
|
|
681
725
|
}
|
|
@@ -224,6 +224,19 @@
|
|
|
224
224
|
background: var(--kui-chrome-material);
|
|
225
225
|
}
|
|
226
226
|
|
|
227
|
+
/* The material's surface context at rest (see pane.css); clear chrome keeps
|
|
228
|
+
the inherited context. */
|
|
229
|
+
.kui-nav-stack[data-chrome-presentation="overlay"]:not(
|
|
230
|
+
[data-chrome-material="clear"]
|
|
231
|
+
)
|
|
232
|
+
> .kui-nav-stack__chrome,
|
|
233
|
+
.kui-nav-stack[data-bottom-toolbar-presentation="overlay"]:not(
|
|
234
|
+
[data-bottom-toolbar-material="clear"]
|
|
235
|
+
)
|
|
236
|
+
> .kui-nav-stack__bottom {
|
|
237
|
+
--kui-color-surface-current-tint: var(--kui-chrome-material);
|
|
238
|
+
}
|
|
239
|
+
|
|
227
240
|
.kui-nav-stack[data-chrome-presentation="overlay"][data-chrome-overlay="measured"]
|
|
228
241
|
> .kui-nav-stack__chrome:not(.kui-nav-stack__chrome-copy) {
|
|
229
242
|
position: absolute;
|