sherick-ui 2.7.1 → 2.9.0
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/dist/cjs/components/Accordion.cjs +1 -1
- package/dist/cjs/components/Accordion.cjs.map +1 -1
- package/dist/cjs/components/Alert.cjs +8 -4
- package/dist/cjs/components/Alert.cjs.map +1 -1
- package/dist/cjs/components/Badge.cjs +2 -2
- package/dist/cjs/components/Badge.cjs.map +1 -1
- package/dist/cjs/components/Breadcrumb.cjs +2 -2
- package/dist/cjs/components/Breadcrumb.cjs.map +1 -1
- package/dist/cjs/components/Calendar.cjs +1 -1
- package/dist/cjs/components/Calendar.cjs.map +1 -1
- package/dist/cjs/components/Card.cjs +10 -2
- package/dist/cjs/components/Card.cjs.map +1 -1
- package/dist/cjs/components/Checkbox.cjs +1 -1
- package/dist/cjs/components/Checkbox.cjs.map +1 -1
- package/dist/cjs/components/CheckboxGroup.cjs +2 -2
- package/dist/cjs/components/CheckboxGroup.cjs.map +1 -1
- package/dist/cjs/components/Chip.cjs +1 -1
- package/dist/cjs/components/Chip.cjs.map +1 -1
- package/dist/cjs/components/Collapsible.cjs +1 -1
- package/dist/cjs/components/Collapsible.cjs.map +1 -1
- package/dist/cjs/components/Combobox.cjs +4 -4
- package/dist/cjs/components/Combobox.cjs.map +1 -1
- package/dist/cjs/components/Command.cjs +2 -2
- package/dist/cjs/components/Command.cjs.map +1 -1
- package/dist/cjs/components/DateRangePicker.cjs +1 -1
- package/dist/cjs/components/DateRangePicker.cjs.map +1 -1
- package/dist/cjs/components/DateTimePicker.cjs +1 -1
- package/dist/cjs/components/DateTimePicker.cjs.map +1 -1
- package/dist/cjs/components/DialogContent.cjs +1 -1
- package/dist/cjs/components/DialogContent.cjs.map +1 -1
- package/dist/cjs/components/DialogDescription.cjs +1 -1
- package/dist/cjs/components/DialogDescription.cjs.map +1 -1
- package/dist/cjs/components/DialogSurface.cjs +1 -1
- package/dist/cjs/components/DialogSurface.cjs.map +1 -1
- package/dist/cjs/components/Drawer.cjs +6 -3
- package/dist/cjs/components/Drawer.cjs.map +1 -1
- package/dist/cjs/components/Field.cjs +1 -1
- package/dist/cjs/components/Field.cjs.map +1 -1
- package/dist/cjs/components/FileUpload.cjs +4 -4
- package/dist/cjs/components/FileUpload.cjs.map +1 -1
- package/dist/cjs/components/IconButton.cjs +5 -1
- package/dist/cjs/components/IconButton.cjs.map +1 -1
- package/dist/cjs/components/Input.cjs +2 -2
- package/dist/cjs/components/Input.cjs.map +1 -1
- package/dist/cjs/components/Menu.cjs +1 -1
- package/dist/cjs/components/Menu.cjs.map +1 -1
- package/dist/cjs/components/NavGroup.cjs +1 -1
- package/dist/cjs/components/NavGroup.cjs.map +1 -1
- package/dist/cjs/components/NavItem.cjs +1 -1
- package/dist/cjs/components/NavItem.cjs.map +1 -1
- package/dist/cjs/components/NumberField.cjs +2 -2
- package/dist/cjs/components/NumberField.cjs.map +1 -1
- package/dist/cjs/components/Pagination.cjs +5 -4
- package/dist/cjs/components/Pagination.cjs.map +1 -1
- package/dist/cjs/components/Popover.cjs +6 -0
- package/dist/cjs/components/Popover.cjs.map +1 -1
- package/dist/cjs/components/Progress.cjs +1 -1
- package/dist/cjs/components/Progress.cjs.map +1 -1
- package/dist/cjs/components/RadioGroup.cjs +1 -1
- package/dist/cjs/components/RadioGroup.cjs.map +1 -1
- package/dist/cjs/components/Search.cjs +1 -1
- package/dist/cjs/components/Search.cjs.map +1 -1
- package/dist/cjs/components/Select.cjs +2 -2
- package/dist/cjs/components/Select.cjs.map +1 -1
- package/dist/cjs/components/Slider.cjs +1 -1
- package/dist/cjs/components/Slider.cjs.map +1 -1
- package/dist/cjs/components/Spinner.cjs +2 -1
- package/dist/cjs/components/Spinner.cjs.map +1 -1
- package/dist/cjs/components/Stepper.cjs +7 -4
- package/dist/cjs/components/Stepper.cjs.map +1 -1
- package/dist/cjs/components/Table.cjs +1 -1
- package/dist/cjs/components/Table.cjs.map +1 -1
- package/dist/cjs/components/Textarea.cjs +2 -2
- package/dist/cjs/components/Textarea.cjs.map +1 -1
- package/dist/cjs/components/Toast.cjs +5 -5
- package/dist/cjs/components/Toast.cjs.map +1 -1
- package/dist/cjs/components/TreeView.cjs +1 -1
- package/dist/cjs/components/TreeView.cjs.map +1 -1
- package/dist/cjs/components/choice-row.cjs +1 -1
- package/dist/cjs/components/choice-row.cjs.map +1 -1
- package/dist/cjs/components/date-field.cjs +1 -1
- package/dist/cjs/components/date-field.cjs.map +1 -1
- package/dist/cjs/components/time-panel.cjs +1 -1
- package/dist/cjs/components/time-panel.cjs.map +1 -1
- package/dist/cjs/components/ui.common.cjs +131 -70
- package/dist/cjs/components/ui.common.cjs.map +1 -1
- package/dist/cjs/components/ui.motion.cjs +7 -2
- package/dist/cjs/components/ui.motion.cjs.map +1 -1
- package/dist/cjs/dev.cjs +4 -0
- package/dist/cjs/dev.cjs.map +1 -1
- package/dist/esm/components/Accordion.js +2 -2
- package/dist/esm/components/Accordion.js.map +1 -1
- package/dist/esm/components/Alert.js +10 -6
- package/dist/esm/components/Alert.js.map +1 -1
- package/dist/esm/components/Badge.js +3 -3
- package/dist/esm/components/Badge.js.map +1 -1
- package/dist/esm/components/Breadcrumb.js +3 -3
- package/dist/esm/components/Breadcrumb.js.map +1 -1
- package/dist/esm/components/Calendar.js +3 -3
- package/dist/esm/components/Calendar.js.map +1 -1
- package/dist/esm/components/Card.js +11 -3
- package/dist/esm/components/Card.js.map +1 -1
- package/dist/esm/components/Checkbox.js +2 -2
- package/dist/esm/components/Checkbox.js.map +1 -1
- package/dist/esm/components/CheckboxGroup.js +3 -3
- package/dist/esm/components/CheckboxGroup.js.map +1 -1
- package/dist/esm/components/Chip.js +2 -2
- package/dist/esm/components/Chip.js.map +1 -1
- package/dist/esm/components/CodeBlock.js +3 -3
- package/dist/esm/components/CodeBlock.js.map +1 -1
- package/dist/esm/components/Collapsible.js +2 -2
- package/dist/esm/components/Collapsible.js.map +1 -1
- package/dist/esm/components/Combobox.js +5 -5
- package/dist/esm/components/Combobox.js.map +1 -1
- package/dist/esm/components/Command.js +3 -3
- package/dist/esm/components/Command.js.map +1 -1
- package/dist/esm/components/DateRangePicker.js +2 -2
- package/dist/esm/components/DateRangePicker.js.map +1 -1
- package/dist/esm/components/DateTimePicker.js +2 -2
- package/dist/esm/components/DateTimePicker.js.map +1 -1
- package/dist/esm/components/DialogContent.js +2 -2
- package/dist/esm/components/DialogContent.js.map +1 -1
- package/dist/esm/components/DialogDescription.js +2 -2
- package/dist/esm/components/DialogDescription.js.map +1 -1
- package/dist/esm/components/DialogSurface.js +2 -2
- package/dist/esm/components/DialogSurface.js.map +1 -1
- package/dist/esm/components/Drawer.js +6 -3
- package/dist/esm/components/Drawer.js.map +1 -1
- package/dist/esm/components/Field.js +2 -2
- package/dist/esm/components/Field.js.map +1 -1
- package/dist/esm/components/FileUpload.js +5 -5
- package/dist/esm/components/FileUpload.js.map +1 -1
- package/dist/esm/components/IconButton.js +6 -2
- package/dist/esm/components/IconButton.js.map +1 -1
- package/dist/esm/components/Input.js +3 -3
- package/dist/esm/components/Input.js.map +1 -1
- package/dist/esm/components/Markdown.js +3 -3
- package/dist/esm/components/Markdown.js.map +1 -1
- package/dist/esm/components/Menu.js +1 -1
- package/dist/esm/components/Menu.js.map +1 -1
- package/dist/esm/components/NavGroup.js +2 -2
- package/dist/esm/components/NavGroup.js.map +1 -1
- package/dist/esm/components/NavItem.js +1 -1
- package/dist/esm/components/NavItem.js.map +1 -1
- package/dist/esm/components/NumberField.js +3 -3
- package/dist/esm/components/NumberField.js.map +1 -1
- package/dist/esm/components/Pagination.js +7 -6
- package/dist/esm/components/Pagination.js.map +1 -1
- package/dist/esm/components/Popover.js +7 -1
- package/dist/esm/components/Popover.js.map +1 -1
- package/dist/esm/components/Progress.js +2 -2
- package/dist/esm/components/Progress.js.map +1 -1
- package/dist/esm/components/RadioGroup.js +2 -2
- package/dist/esm/components/RadioGroup.js.map +1 -1
- package/dist/esm/components/Search.js +2 -2
- package/dist/esm/components/Search.js.map +1 -1
- package/dist/esm/components/Select.js +3 -3
- package/dist/esm/components/Select.js.map +1 -1
- package/dist/esm/components/Slider.js +2 -2
- package/dist/esm/components/Slider.js.map +1 -1
- package/dist/esm/components/Spinner.js +2 -1
- package/dist/esm/components/Spinner.js.map +1 -1
- package/dist/esm/components/Stepper.js +8 -5
- package/dist/esm/components/Stepper.js.map +1 -1
- package/dist/esm/components/Table.js +2 -2
- package/dist/esm/components/Table.js.map +1 -1
- package/dist/esm/components/Textarea.js +3 -3
- package/dist/esm/components/Textarea.js.map +1 -1
- package/dist/esm/components/Toast.js +6 -6
- package/dist/esm/components/Toast.js.map +1 -1
- package/dist/esm/components/TreeView.js +2 -2
- package/dist/esm/components/TreeView.js.map +1 -1
- package/dist/esm/components/choice-row.js +1 -1
- package/dist/esm/components/choice-row.js.map +1 -1
- package/dist/esm/components/date-field.js +2 -2
- package/dist/esm/components/date-field.js.map +1 -1
- package/dist/esm/components/time-panel.js +1 -1
- package/dist/esm/components/time-panel.js.map +1 -1
- package/dist/esm/components/ui.common.js +128 -71
- package/dist/esm/components/ui.common.js.map +1 -1
- package/dist/esm/components/ui.motion.js +7 -2
- package/dist/esm/components/ui.motion.js.map +1 -1
- package/dist/esm/dev.js +1 -1
- package/dist/styles.css +53 -67
- package/dist/theme.css +3 -0
- package/dist/types/dev.d.cts +33 -19
- package/dist/types/dev.d.ts +33 -19
- package/dist/types/index.d.cts +24 -2
- package/dist/types/index.d.ts +24 -2
- package/package.json +1 -1
|
@@ -11,16 +11,18 @@ var ui_motion = require('./ui.motion.cjs');
|
|
|
11
11
|
|
|
12
12
|
material what a surface is made of (canvas, matte, control, acrylic)
|
|
13
13
|
elevation how far it sits off the page (flat, raised, floating, control, recessed)
|
|
14
|
-
shape its corner role (control, prominent, surface, expressive, pill, circle)
|
|
14
|
+
shape its corner role (mark, row, control, prominent, surface, sheet, expressive, pill, circle)
|
|
15
15
|
edge the hairline between stacked parts (row, header, rule)
|
|
16
16
|
state how it responds (rest, hover, pressed, selected, disabled, focus)
|
|
17
|
-
stateLayer the composited hover/press overlay (quiet, tonal, filled, track, activeRow)
|
|
17
|
+
stateLayer the composited hover/press overlay (quiet, tonal, filled, track, mark, activeRow, fieldPart)
|
|
18
18
|
disclosure one expandable region and its row (trigger, panel)
|
|
19
19
|
tone its color role (text, soft, tonal, selected, strong)
|
|
20
20
|
text the readable emphasis ladder (high, medium)
|
|
21
|
-
|
|
21
|
+
type the recurring kinds of copy (control, label, body, supporting, caption, title, heading, numeric)
|
|
22
|
+
density how tightly it is packed (compact, normal, prominent, target, part)
|
|
23
|
+
iconStroke the one rendered stroke of a glyph (glyph, mark)
|
|
22
24
|
overlay floating shells (menu, tooltip, popup, toast, sheet, dialog)
|
|
23
|
-
|
|
25
|
+
focusRing the one focus language (focusRing, focusRingInset, focusRingHeld, focusRingWithin, groupFocusRing)
|
|
24
26
|
|
|
25
27
|
Temporal behavior is deliberately not here: `ui.motion.ts` owns every transition,
|
|
26
28
|
duration, curve and reduced-motion rule, and a recipe below names one of its recipes
|
|
@@ -127,8 +129,8 @@ const recessedTop = "shadow-sherick-recessed-top";
|
|
|
127
129
|
an almost-button beside a real one. Nested roles stay concentric: an inner corner is the outer
|
|
128
130
|
corner minus the inset between them (a 16px track around a 12px indicator at 4px, a 20px list
|
|
129
131
|
sheet around 12px options at 8px).
|
|
130
|
-
- control: ordinary
|
|
131
|
-
|
|
132
|
+
- control: ordinary containers and dense data regions — fields, alerts, tables, segment
|
|
133
|
+
tracks and full-width option rows. Chips and badges are capsules (`pill`).
|
|
132
134
|
- mark: a compact square selection mark — a 20px checkbox box. `control` is a role
|
|
133
135
|
for objects the size of a field; its radius exceeds the half-extent of a
|
|
134
136
|
20px square, so a mark needs a step of its own — a corner under a third of
|
|
@@ -177,27 +179,27 @@ const edgeTone = {
|
|
|
177
179
|
header: "border-sherick-edge/[0.10]",
|
|
178
180
|
rule: "border-sherick-edge/[0.075]",
|
|
179
181
|
};
|
|
180
|
-
/* Rim — the boundary of a *hollow* control:
|
|
181
|
-
inside such a control says what it is — an empty
|
|
182
|
-
|
|
182
|
+
/* Rim — the boundary of a *hollow* control: the file drop target, or an empty checkbox or radio.
|
|
183
|
+
Nothing inside such a control says what it is — an empty mark holds nothing, a drop target only
|
|
184
|
+
an invitation — and it still has to be identifiable at 3:1, which no neutral fill step and no
|
|
183
185
|
depth the light model can draw achieves on its own. So a hollow control carries one rim in the
|
|
184
186
|
`rim` tone, tuned to clear 3:1 by a small margin and no more, and that rim is the only border a
|
|
185
187
|
control has. A filled control — a button, a chip, a selected mark — is identified by its fill and
|
|
186
188
|
never carries one.
|
|
187
|
-
A text field
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
border on all four sides
|
|
192
|
-
a field there keeps its whole outline
|
|
193
|
-
|
|
189
|
+
A text field is not hollow: its label names it, and its value or placeholder and its parts — a
|
|
190
|
+
chevron, a calendar glyph, a stepper — show what it is and where it is, which is how WCAG 1.4.11
|
|
191
|
+
lets a control be identified without a 3:1 edge. Its tray says "something goes here", and its
|
|
192
|
+
states ride on the tray and the focus ring (`state.field`). `rim.field` is therefore no visible
|
|
193
|
+
line: it is a transparent border on all four sides, because forced colors repaints even a
|
|
194
|
+
transparent border in a system colour, so a field there keeps its whole outline where the tray is
|
|
195
|
+
discarded; the scoped baseline sizes boxes by their border edge, so it never changes a field's
|
|
196
|
+
footprint. An invalid field takes the same transparent border.
|
|
194
197
|
A drop target's rim is dashed, and the dashes are a mask over an overlay rather than the native
|
|
195
198
|
`dashed` style, whose dash length and corner joins the platform decides: the mask fixes the dash
|
|
196
199
|
rhythm and follows the `control` corner exactly. The mask is authored in `tokens.ts`. */
|
|
197
200
|
const dashedRimMask = "after:[mask-image:var(--sui-rim-dashed)] after:[mask-size:100%_100%] after:[mask-repeat:no-repeat]";
|
|
198
201
|
const rim = {
|
|
199
|
-
field: "border-[1.5px] border-transparent
|
|
200
|
-
fieldError: "border-[1.5px] border-transparent border-b-sherick-danger",
|
|
202
|
+
field: "border-[1.5px] border-transparent",
|
|
201
203
|
dashed: /* @__PURE__ */ utils.cx("after:pointer-events-none after:absolute after:inset-0 after:rounded-[inherit] after:content-['']", "after:bg-sherick-rim", dashedRimMask, ui_motion.motionRim),
|
|
202
204
|
/* The dashes step up under the pointer and take the primary tone while a file is held over them. */
|
|
203
205
|
dashedHover: "hover:after:bg-sherick-ink-muted",
|
|
@@ -252,34 +254,35 @@ const state = {
|
|
|
252
254
|
text: "cursor-text",
|
|
253
255
|
/* Quiet scan feedback for non-interactive data rows: tonality only. */
|
|
254
256
|
rowHover: "hover:bg-sherick-ink/[0.05]",
|
|
255
|
-
/* The
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
soft surface
|
|
266
|
-
|
|
257
|
+
/* The field family — one tray, one deeper step, no visible rims. Hover and engagement share the
|
|
258
|
+
deep step; a composite field engages its outer surface while the input inside stays borderless;
|
|
259
|
+
an expanded control holds the engaged step while its popup is open. Tonality and the focus ring
|
|
260
|
+
carry the state, so no border appears and disappears. */
|
|
261
|
+
/* A field is a tray in the `surface-high` tone, so it reads as a quiet recess in light and a
|
|
262
|
+
quiet step up in dark. It draws no line: its label and content identify it (see `rim`), so the
|
|
263
|
+
tray is laid at full strength to say "something goes here" on a card and on the page alike.
|
|
264
|
+
The pointer sinks it to the deep tray, and so does engagement — focus or an open popup — where
|
|
265
|
+
the focus ring is what says "this one is engaged"; an engaged field never falls back under the
|
|
266
|
+
pointer, because both states share the step. An invalid field is the danger tray — the role's
|
|
267
|
+
soft surface, at full strength like the neutral tray — and it holds still under the pointer:
|
|
268
|
+
its colour is already what it has to say, and the danger placeholder and the field's message
|
|
269
|
+
carry the error in words. */
|
|
267
270
|
field: {
|
|
268
|
-
hover: "hover:bg-sherick-
|
|
269
|
-
focus: "focus:bg-sherick-
|
|
271
|
+
hover: "hover:bg-sherick-tray-deep",
|
|
272
|
+
focus: "focus:bg-sherick-tray-deep",
|
|
270
273
|
/* A composite's engaged tone outranks hover, independent of variant emission order. */
|
|
271
|
-
focusWithin: "[&&]:focus-within:bg-sherick-
|
|
272
|
-
engaged: "bg-sherick-
|
|
273
|
-
errorHover: "hover:bg-sherick-danger-soft
|
|
274
|
-
errorFocus: "focus:bg-sherick-danger-soft
|
|
275
|
-
errorEngaged: "bg-sherick-danger-soft
|
|
274
|
+
focusWithin: "[&&]:focus-within:bg-sherick-tray-deep",
|
|
275
|
+
engaged: "bg-sherick-tray-deep",
|
|
276
|
+
errorHover: "hover:bg-sherick-danger-soft",
|
|
277
|
+
errorFocus: "focus:bg-sherick-danger-soft",
|
|
278
|
+
errorEngaged: "bg-sherick-danger-soft",
|
|
276
279
|
/* The error ladder again, keyed on Base UI's validity attribute for a part that learns its
|
|
277
280
|
validity from the field it sits in. Two variants outrank the single-variant ladder above,
|
|
278
281
|
so neither ladder has to be conditional. */
|
|
279
|
-
invalid: "data-[invalid]:bg-sherick-danger-soft
|
|
280
|
-
invalidHover: "data-[invalid]:hover:bg-sherick-danger-soft
|
|
281
|
-
invalidEngaged: "data-[invalid]:bg-sherick-danger-soft
|
|
282
|
-
invalidFocusWithin: "[&&]:data-[invalid]:focus-within:bg-sherick-danger-soft
|
|
282
|
+
invalid: "data-[invalid]:bg-sherick-danger-soft",
|
|
283
|
+
invalidHover: "data-[invalid]:hover:bg-sherick-danger-soft",
|
|
284
|
+
invalidEngaged: "data-[invalid]:bg-sherick-danger-soft",
|
|
285
|
+
invalidFocusWithin: "[&&]:data-[invalid]:focus-within:bg-sherick-danger-soft",
|
|
283
286
|
},
|
|
284
287
|
};
|
|
285
288
|
/* State layers.
|
|
@@ -387,10 +390,9 @@ const hitArea = "relative after:pointer-events-auto after:absolute after:inset-[
|
|
|
387
390
|
- matteHigh: the second matte step, for nesting inside another matte surface.
|
|
388
391
|
- matteInset: a passive sheet tucked under a stronger control; subdued without
|
|
389
392
|
blending into the canvas or needing a drawn rim.
|
|
390
|
-
- control: the fill every text control shares, plus its placeholder tone
|
|
391
|
-
the `
|
|
392
|
-
|
|
393
|
-
3:1 boundary (see `rim`).
|
|
393
|
+
- control: the fill every text control shares, plus its placeholder tone: an opaque tray
|
|
394
|
+
in the `surface-high` tone. The tray says "something goes here"; the field's
|
|
395
|
+
label and content, not a drawn edge, are what identify it (see `rim`).
|
|
394
396
|
- handle: the fill of a small part the user has to find — a value control's handle.
|
|
395
397
|
Surface steps sit within a few percent of their neighbours, so this role
|
|
396
398
|
takes the mid-emphasis tone, which inverts with the theme and separates in
|
|
@@ -423,15 +425,15 @@ const material = {
|
|
|
423
425
|
matteQuiet: "bg-sherick-surface/[0.42] text-sherick-ink",
|
|
424
426
|
matte: "bg-sherick-surface/[0.78] text-sherick-ink",
|
|
425
427
|
matteHigh: "bg-sherick-surface-high/[0.72] text-sherick-ink",
|
|
426
|
-
control: "bg-sherick-surface-high
|
|
428
|
+
control: "bg-sherick-surface-high text-sherick-ink placeholder:text-sherick-ink-muted",
|
|
427
429
|
/* The invalid fill carries its placeholder at the *full* danger tone, not at a fraction of it. A
|
|
428
430
|
placeholder is text, so it answers to the same 4.5:1 the copy beside it does, and a partial
|
|
429
431
|
opacity of an accent is a different colour from the accent: the 72%-opacity placeholder
|
|
430
|
-
measured 2.8–3.0:1 light and 3.4–3.9:1 dark on
|
|
432
|
+
measured 2.8–3.0:1 light and 3.4–3.9:1 dark on the half-strength danger tray, while the token it was mixed from
|
|
431
433
|
measures 4.1–4.7:1 light and 5.2–6.2:1 dark on it. There is no dimmer step of a semantic tone
|
|
432
434
|
that is still readable, and a normal field's placeholder is `ink-muted` at full strength
|
|
433
435
|
already — so the error form is the same rule, in the tone the field is in. */
|
|
434
|
-
controlError: "bg-sherick-danger-soft
|
|
436
|
+
controlError: "bg-sherick-danger-soft text-sherick-ink placeholder:text-sherick-danger",
|
|
435
437
|
handle: "bg-sherick-ink-muted text-sherick-canvas",
|
|
436
438
|
acrylic: "bg-sherick-surface-float/[var(--sui-glass-fill)] bg-[image:var(--sui-glass-gradient)] text-sherick-ink backdrop-blur-[var(--sui-glass-blur)] backdrop-saturate-[var(--sui-glass-saturation)] backdrop-brightness-[var(--sui-glass-brightness)]",
|
|
437
439
|
acrylicDense: "bg-sherick-surface-float/[var(--sui-glass-dense-fill)] bg-[image:var(--sui-glass-gradient-dense)] text-sherick-ink backdrop-blur-[var(--sui-glass-dense-blur)] backdrop-saturate-[var(--sui-glass-dense-saturation)] backdrop-brightness-[var(--sui-glass-dense-brightness)]",
|
|
@@ -445,9 +447,17 @@ const matteInset = "bg-sherick-surface-high/[0.35] text-sherick-ink";
|
|
|
445
447
|
where the role owns it, one weight. A component still owns copy that only it renders; these are
|
|
446
448
|
the roles that recur across families and have to agree wherever they appear:
|
|
447
449
|
- control: the type step of a control, owned through `density` below.
|
|
450
|
+
- label: the name above a control — a field's label, a progress label, a column header. It is
|
|
451
|
+
the medium weight of the compact step, so a label leads the value beneath it without
|
|
452
|
+
being as large as it.
|
|
453
|
+
- body: a sentence or a paragraph set inside a component — an alert, a toast's description, a
|
|
454
|
+
dialog's description and content, an open disclosure panel. Long-form Markdown keeps
|
|
455
|
+
its own reading rhythm; this is the rhythm of copy *in* an interface.
|
|
448
456
|
- supporting: a field's description, hint and error, and the secondary line under a row's label.
|
|
449
457
|
- caption: compact labels — a badge, a tooltip, a group label, a calendar weekday.
|
|
450
|
-
- title: the heading of a compact surface — a popover, a toast, a command palette.
|
|
458
|
+
- title: the heading of a compact surface — a card, a popover, a toast, a command palette. It
|
|
459
|
+
is one step above the 15px control text it usually sits over, so a heading reads as a
|
|
460
|
+
heading by size and not by weight alone.
|
|
451
461
|
- heading: the title of a surface that owns the viewport — a dialog, an alert dialog, a drawer.
|
|
452
462
|
- numeric: figures that are compared down a column or updated in place.
|
|
453
463
|
Every size lands on a whole-pixel line box, so stacked rows keep one rhythm. */
|
|
@@ -457,9 +467,11 @@ const type = {
|
|
|
457
467
|
normal: "text-[0.9375rem] leading-[1.375rem]",
|
|
458
468
|
prominent: "text-lg",
|
|
459
469
|
},
|
|
470
|
+
label: "text-sm leading-5 font-medium",
|
|
471
|
+
body: "text-sm leading-6",
|
|
460
472
|
supporting: "text-[0.8125rem] leading-5",
|
|
461
473
|
caption: "text-xs leading-4",
|
|
462
|
-
title: "text-
|
|
474
|
+
title: "text-base leading-6 font-semibold tracking-[-0.011em]",
|
|
463
475
|
heading: "text-xl leading-7 font-semibold tracking-[-0.02em]",
|
|
464
476
|
numeric: "tabular-nums",
|
|
465
477
|
};
|
|
@@ -498,6 +510,19 @@ const iconSlot = {
|
|
|
498
510
|
normal: "inline-flex size-5 shrink-0 items-center justify-center [&>svg]:size-5",
|
|
499
511
|
prominent: "inline-flex size-6 shrink-0 items-center justify-center [&>svg]:size-6",
|
|
500
512
|
};
|
|
513
|
+
/* Icon stroke — the one rendered weight of a library glyph. The artwork is drawn on a 24-unit grid,
|
|
514
|
+
so a stroke written in the artwork's own units renders thinner at 16px and thicker at 24px: the
|
|
515
|
+
same set read 1.0px in a dismiss and 1.75px in a tick. A glyph the library draws holds its stroke
|
|
516
|
+
in screen pixels instead, so a 14px chevron and a 20px close mark have one weight, close to the
|
|
517
|
+
stem of the medium label beside them. A selection mark — the tick or minus inside a filled
|
|
518
|
+
checkbox — is the one deliberately heavier glyph: it sits on the strong accent and has to read as
|
|
519
|
+
the mark itself, not as a hairline drawn on it.
|
|
520
|
+
Apply it to the `svg` a component renders. It is not applied to artwork a consumer hands into a
|
|
521
|
+
slot: that artwork's weight is the consumer's choice. */
|
|
522
|
+
const iconStroke = {
|
|
523
|
+
glyph: "[&_*]:[vector-effect:non-scaling-stroke] [&_*]:[stroke-width:1.5px]",
|
|
524
|
+
mark: "[&_*]:[vector-effect:non-scaling-stroke] [&_*]:[stroke-width:1.75px]",
|
|
525
|
+
};
|
|
501
526
|
/* Stacking level — where anything that floats sits relative to the application.
|
|
502
527
|
|
|
503
528
|
One interaction level, deliberately. Base UI nests a popup's portal *inside* the portal of the surface it
|
|
@@ -613,14 +638,17 @@ const list = {
|
|
|
613
638
|
both, a selected row keeps its selection tint under the ring, and a disabled-but-navigable
|
|
614
639
|
row still shows where the navigation is while saying it cannot be used. The ring is inset
|
|
615
640
|
because the row lives inside the sheet it belongs to, as a segment does in its track. */
|
|
616
|
-
|
|
641
|
+
/* The option's start inset is the field's: a sheet's 8px inset plus the row's 12px puts every
|
|
642
|
+
option label on the same 20px edge as the value in the trigger that opened it, so the list
|
|
643
|
+
reads as the field opening rather than a second surface beside it. */
|
|
644
|
+
option: /* @__PURE__ */ utils.cx("flex w-full items-center justify-between gap-4 px-3 py-3 text-start outline-none", type.control.normal, shape.control, ui_motion.motionFeedback, focusRingInset, text.high, stateLayer.quiet, stateLayer.activeRow, ui_motion.motionRowLayer, state.effectiveDisabled),
|
|
617
645
|
/* The heading of a group of options — a category above the channels filed under it. It is a
|
|
618
646
|
caption, not a row: it takes no state layer, no highlight and no focus, because the reader never
|
|
619
647
|
lands on it; the primitive names the group from it, so a screen reader hears the category as it
|
|
620
648
|
enters the group. Its inline padding is the option's, so a heading and the labels beneath it
|
|
621
649
|
share one start edge, and the space above it is what separates one group from the last: a
|
|
622
650
|
group inside a sheet is grouped by spacing and a type role, never by a rule or a nested card. */
|
|
623
|
-
groupLabel: /* @__PURE__ */ utils.cx("px-
|
|
651
|
+
groupLabel: /* @__PURE__ */ utils.cx("px-3 pb-1 pt-3 font-medium", type.caption, text.medium),
|
|
624
652
|
/* The same object at the density a list of short actions wants, where the row is scanned
|
|
625
653
|
rather than read and the list is a control rather than a page. `shape.row` keeps the
|
|
626
654
|
command's corner proportional to its own height, so its highlight nests in the tighter
|
|
@@ -634,13 +662,15 @@ const list = {
|
|
|
634
662
|
component maps its own primitive's panel variable onto, because the measured geometry is
|
|
635
663
|
anatomy and only the interpolation is temporal. */
|
|
636
664
|
const disclosure = {
|
|
637
|
-
/* The row: a full-width row in a stacked group, activated like a selectable row.
|
|
665
|
+
/* The row: a full-width row in a stacked group, activated like a selectable row. It is an option
|
|
666
|
+
row at the 16px inset of the surface it usually sits on directly — no sheet inset precedes it —
|
|
667
|
+
so its label shares an edge with the panel copy beneath it. Its own focus
|
|
638
668
|
indicator is the shared inset ring, because an offset one drawn outside the row would land on
|
|
639
669
|
the divider or the panel beside it rather than around the row it belongs to — which is the same
|
|
640
670
|
reason a segment inside a track takes the inset form. The chevron the component puts in the
|
|
641
671
|
row is the disclosure's own affordance and turns in place under `motionOrient`. */
|
|
642
|
-
trigger: /* @__PURE__ */ utils.cx("group [overflow-wrap:anywhere]",
|
|
643
|
-
panel: /* @__PURE__ */ utils.cx("h-[var(--sui-disclose-height)] overflow-hidden
|
|
672
|
+
trigger: /* @__PURE__ */ utils.cx("group flex w-full items-center justify-between gap-4 px-4 py-3 text-start outline-none [overflow-wrap:anywhere]", type.control.normal, shape.control, ui_motion.motionFeedback, focusRingInset, text.high, stateLayer.quiet, stateLayer.activeRow, ui_motion.motionRowLayer, state.effectiveDisabled, state.enabled),
|
|
673
|
+
panel: /* @__PURE__ */ utils.cx("h-[var(--sui-disclose-height)] overflow-hidden [overflow-wrap:anywhere]", type.body, text.medium, ui_motion.motionDisclose),
|
|
644
674
|
};
|
|
645
675
|
/* Tone hierarchy — the color roles a surface can take, in rising strength:
|
|
646
676
|
text foreground only, for quiet rows and links.
|
|
@@ -703,11 +733,17 @@ const tone = {
|
|
|
703
733
|
success: "group-data-[checked]:bg-sherick-success group-data-[checked]:text-sherick-on-success",
|
|
704
734
|
},
|
|
705
735
|
};
|
|
706
|
-
/* Current location — where the reader is, as opposed to a value they chose.
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
736
|
+
/* Current location — where the reader is, as opposed to a value they chose. Both forms stay flat:
|
|
737
|
+
depth belongs to held values (`tone.selected` with `elevation.control`).
|
|
738
|
+
- row: a navigation row on a sheet — the role's soft container, full ink and a touch of weight.
|
|
739
|
+
- inTrack: a destination inside a recessed track, or the mark of a track's current stage — a
|
|
740
|
+
pagination's current page, a Stepper's current step. The soft step is the groove's own
|
|
741
|
+
lightness (1.00:1 in light), so there the fill steps up to `selected` and the label
|
|
742
|
+
takes the accent: the label, not the fill, says "you are here". */
|
|
743
|
+
const currentDestination = {
|
|
744
|
+
row: "bg-sherick-primary-soft text-sherick-ink font-medium",
|
|
745
|
+
inTrack: "bg-sherick-primary-selected text-sherick-primary font-semibold",
|
|
746
|
+
};
|
|
711
747
|
/* Selectable surface — the recessed surface of a control that fills once it is selected: a
|
|
712
748
|
switch track, a checkbox box, a radio circle, a slider groove. Selection is keyed on the
|
|
713
749
|
primitive's own `data-checked` / `data-indeterminate`, so an uncontrolled control is styled
|
|
@@ -723,12 +759,18 @@ const currentDestination = "bg-sherick-primary-soft text-sherick-ink font-medium
|
|
|
723
759
|
an option, a tree row, a date — keeps `tone.selected`, because a list sheet is already the
|
|
724
760
|
brightest surface and a white row on it would vanish. */
|
|
725
761
|
const puck = "bg-sherick-puck";
|
|
726
|
-
/* A choice row
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
762
|
+
/* A choice row — an opt-in `surface` row in a RadioGroup or CheckboxGroup — rests on the
|
|
763
|
+
`matteHigh` tray, so every choice in the group reads as a target before any is chosen; it stays
|
|
764
|
+
light enough that the empty mark's rim still clears 3:1 against it. The row that holds the
|
|
765
|
+
selection takes the role's *soft* surface and the accent **selection rim**, and stays flat. The
|
|
766
|
+
soft surface is lighter than the resting tray, so the tint alone would make the chosen row the
|
|
767
|
+
quieter of the two; the rim is what says "this one". It is the row's selection mark, not an
|
|
768
|
+
outline drawn to separate a surface, and it belongs to the selected state only. Like an empty
|
|
769
|
+
mark's rim it is an overlay rather than a border, so the fill and the hover layer reach the row's
|
|
770
|
+
real edge, and it is transparent rather than absent at rest, so forced colors keeps every row's
|
|
771
|
+
outline. The selected step and a lift turned a whole card into an accent block, which outshouted
|
|
772
|
+
the priority action on the same view. */
|
|
773
|
+
const selectableRowSurface = /* @__PURE__ */ utils.cx("has-[[data-checked]]:bg-sherick-primary-soft has-[[data-checked]]:text-sherick-ink", "after:pointer-events-none after:absolute after:inset-0 after:box-border after:rounded-[inherit] after:border-[1.5px] after:border-transparent after:content-['']", "has-[[data-checked]]:after:border-sherick-primary", ui_motion.motionRim);
|
|
732
774
|
/* Supporting copy inside such a row — a choice's description. `text.medium` clears 4.5:1 on the
|
|
733
775
|
soft step at rest (5.7:1 light, 6.2:1 dark), but the row's press layer composites toward the label
|
|
734
776
|
and takes that margin away, so while the row holds the selection its supporting line takes full
|
|
@@ -790,8 +832,11 @@ const toneAlpha = (tone) => (recipe, label) => {
|
|
|
790
832
|
throw new Error(`recipe alpha missing for ${label}`);
|
|
791
833
|
return match[1] === undefined ? 1 : Number(match[1]);
|
|
792
834
|
};
|
|
793
|
-
/* A field tray's `surface-high` step, and the canvas step an empty
|
|
835
|
+
/* A field tray's `surface-high` step, its deep step, its danger step, and the canvas step an empty
|
|
836
|
+
mark's interior holds. */
|
|
794
837
|
const trayAlpha = toneAlpha("surface-high");
|
|
838
|
+
const deepTrayAlpha = toneAlpha("tray-deep");
|
|
839
|
+
const dangerTrayAlpha = toneAlpha("danger-soft");
|
|
795
840
|
const markAlpha = toneAlpha("canvas");
|
|
796
841
|
const recipeAlphas = {
|
|
797
842
|
state: {
|
|
@@ -810,10 +855,10 @@ const recipeAlphas = {
|
|
|
810
855
|
card: fillAlpha(material.matte, "field.card"),
|
|
811
856
|
groove: fillAlpha(material.matteHigh, "field.groove"),
|
|
812
857
|
control: trayAlpha(material.control, "field.control"),
|
|
813
|
-
hover:
|
|
814
|
-
engaged:
|
|
858
|
+
hover: deepTrayAlpha(state.field.hover, "field.hover"),
|
|
859
|
+
engaged: deepTrayAlpha(state.field.engaged, "field.engaged"),
|
|
815
860
|
mark: markAlpha(markWellFill, "field.mark"),
|
|
816
|
-
error:
|
|
861
|
+
error: dangerTrayAlpha(material.controlError, "field.error"),
|
|
817
862
|
},
|
|
818
863
|
};
|
|
819
864
|
/* A labelled field is a shrinkable column. Its explanatory copy wraps, including identifiers;
|
|
@@ -821,11 +866,24 @@ const recipeAlphas = {
|
|
|
821
866
|
const fieldLayout = "flex min-w-0 w-full flex-col [overflow-wrap:anywhere]";
|
|
822
867
|
/* The messages under a field: its description or hint, and its error. One role for every field in
|
|
823
868
|
the family, so a hint reads the same under a text field, a date range and a file chooser. */
|
|
869
|
+
/* The label above a field: the `label` role at full ink, with the one gap every field family keeps
|
|
870
|
+
between its name and its control. */
|
|
871
|
+
const fieldLabel = /* @__PURE__ */ utils.cx("mb-2", type.label, text.high);
|
|
824
872
|
const fieldMessage = {
|
|
825
873
|
description: /* @__PURE__ */ utils.cx("mt-2", type.supporting, text.medium),
|
|
826
874
|
error: /* @__PURE__ */ utils.cx("mt-2", type.supporting, tone.text.danger),
|
|
827
875
|
};
|
|
876
|
+
/* The code well — the quiet recess a code block's lines sit in. It is the canvas showing through the
|
|
877
|
+
block's own matte shell, so a well reads as sunk into the block on a card and on the page alike. */
|
|
878
|
+
const codeWell = "bg-sherick-canvas/[0.28]";
|
|
879
|
+
/* Rich-text accents — content-level emphasis in rendered prose, not structural edges: a quote's rule
|
|
880
|
+
on its start edge, and a link's underline at rest and under the pointer. */
|
|
881
|
+
const richText = {
|
|
882
|
+
quoteRule: "border-sherick-primary/[0.45]",
|
|
883
|
+
linkUnderline: "decoration-sherick-primary/[0.35] hover:decoration-sherick-primary",
|
|
884
|
+
};
|
|
828
885
|
|
|
886
|
+
exports.codeWell = codeWell;
|
|
829
887
|
exports.currentDestination = currentDestination;
|
|
830
888
|
exports.density = density;
|
|
831
889
|
exports.detail = detail;
|
|
@@ -833,6 +891,7 @@ exports.disclosure = disclosure;
|
|
|
833
891
|
exports.edge = edge;
|
|
834
892
|
exports.edgeTone = edgeTone;
|
|
835
893
|
exports.elevation = elevation;
|
|
894
|
+
exports.fieldLabel = fieldLabel;
|
|
836
895
|
exports.fieldLayout = fieldLayout;
|
|
837
896
|
exports.fieldMessage = fieldMessage;
|
|
838
897
|
exports.focusRing = focusRing;
|
|
@@ -843,6 +902,7 @@ exports.focusRingWithin = focusRingWithin;
|
|
|
843
902
|
exports.groupFocusRing = groupFocusRing;
|
|
844
903
|
exports.hitArea = hitArea;
|
|
845
904
|
exports.iconSlot = iconSlot;
|
|
905
|
+
exports.iconStroke = iconStroke;
|
|
846
906
|
exports.list = list;
|
|
847
907
|
exports.material = material;
|
|
848
908
|
exports.matteInset = matteInset;
|
|
@@ -852,6 +912,7 @@ exports.parentFocusRingInset = parentFocusRingInset;
|
|
|
852
912
|
exports.puck = puck;
|
|
853
913
|
exports.recessedTop = recessedTop;
|
|
854
914
|
exports.recipeAlphas = recipeAlphas;
|
|
915
|
+
exports.richText = richText;
|
|
855
916
|
exports.rim = rim;
|
|
856
917
|
exports.selectable = selectable;
|
|
857
918
|
exports.selectableRowSupporting = selectableRowSupporting;
|