@godxjp/ui 28.3.1 → 28.5.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/README.md +58 -0
- package/dist/app/theme-axes.js +6 -0
- package/dist/components/data-display/scroll-area.js +2 -0
- package/dist/components/data-entry/calendar.d.ts +5 -0
- package/dist/components/data-entry/calendar.js +6 -2
- package/dist/components/data-entry/date-picker.js +12 -0
- package/dist/components/data-entry/index.d.ts +3 -0
- package/dist/components/data-entry/index.js +5 -0
- package/dist/components/data-entry/time-picker.d.ts +1 -1
- package/dist/components/data-entry/time-picker.js +8 -1
- package/dist/contracts/measurement.json +1 -1
- package/dist/props/components/data-display.prop.d.ts +22 -0
- package/dist/props/components/data-entry.prop.d.ts +14 -0
- package/dist/props/registry.d.ts +9 -0
- package/dist/props/registry.js +11 -0
- package/dist/styles/base.css +5 -3
- package/dist/styles/card-layout.css +11 -6
- package/dist/styles/control.css +19 -10
- package/dist/styles/data-display-layout.css +44 -18
- package/dist/styles/data-entry-layout.css +3 -3
- package/dist/styles/table-layout.css +9 -6
- package/dist/styles/text-layout.css +1 -1
- package/dist/theme/famgia.service.css +2 -4
- package/dist/tokens/components/control.css +4 -3
- package/dist/tokens/components/scroll-area.css +3 -0
- package/dist/tokens/derived.css +20 -0
- package/dist/tokens/foundation.css +6 -13
- package/docs/CUSTOMER-THEMING.md +82 -3
- package/docs/FRAME-COVERAGE-REPORT.md +1 -1
- package/docs/data-display/scroll-area.tsx +6 -2
- package/docs/data-entry/upload-crop-dialog.tsx +110 -0
- package/package.json +99 -92
package/README.md
CHANGED
|
@@ -12,6 +12,64 @@ npm i @godxjp/ui
|
|
|
12
12
|
|
|
13
13
|
---
|
|
14
14
|
|
|
15
|
+
## Using this from an AI agent
|
|
16
|
+
|
|
17
|
+
The catalog — 165 components, 1616 tokens, 47 cardinal rules — is published in two forms from one
|
|
18
|
+
source. **Entry point for either: [`AGENTS.md`](AGENTS.md).**
|
|
19
|
+
|
|
20
|
+
### If your agent can run a process
|
|
21
|
+
|
|
22
|
+
Claude Code · Codex CLI · Cursor · any MCP client:
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
npx @godxjp/ui sync-rules
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
Writes `.mcp.json`, `CLAUDE.md` and `.ai/rules/` into the consumer repo and wires
|
|
29
|
+
`@godxjp/ui-mcp`. Prefer this: it is searchable, it drills down instead of dumping, and it is
|
|
30
|
+
**locked to the version on disk** — the failure it prevents is an agent being told a prop does not
|
|
31
|
+
exist because the catalog was two minors behind (gh#789).
|
|
32
|
+
|
|
33
|
+
### If your agent can only fetch URLs
|
|
34
|
+
|
|
35
|
+
ChatGPT on the web, Claude.ai, or any client without a local process. The same data is served as
|
|
36
|
+
static files straight from this public repo — no hosting, no deploy step:
|
|
37
|
+
|
|
38
|
+
| file | size | what it is |
|
|
39
|
+
| ----------------------------------------------------------------------------------------------------------------------- | ------- | ------------------------------------------------------------------------------------------------------ |
|
|
40
|
+
| [`agent/START-HERE.md`](https://raw.githubusercontent.com/godx-jp/godxjp-ui/main/agent/START-HERE.md) | 6 KB | **read first** — self-contained: the four rules, the token override model, a page that passes review |
|
|
41
|
+
| [`agent/llms.txt`](https://raw.githubusercontent.com/godx-jp/godxjp-ui/main/agent/llms.txt) | 2 KB | the [llms.txt](https://llmstxt.org/) entry point |
|
|
42
|
+
| [`agent/index.json`](https://raw.githubusercontent.com/godx-jp/godxjp-ui/main/agent/index.json) | 2 KB | manifest: version, counts, every file's URL |
|
|
43
|
+
| [`agent/components-index.json`](https://raw.githubusercontent.com/godx-jp/godxjp-ui/main/agent/components-index.json) | 42 KB | all 165 as name + group + tagline — **fetch this first** |
|
|
44
|
+
| [`agent/components/<Name>.json`](https://raw.githubusercontent.com/godx-jp/godxjp-ui/main/agent/components/Select.json) | 1–32 KB | one file per component, each with its `importPath` — **this is the route to take** |
|
|
45
|
+
| [`agent/components.json`](https://raw.githubusercontent.com/godx-jp/godxjp-ui/main/agent/components.json) | 1.1 MB | all 165 entries in one file — most URL fetchers truncate this silently; prefer the per-component files |
|
|
46
|
+
| [`agent/tokens.json`](https://raw.githubusercontent.com/godx-jp/godxjp-ui/main/agent/tokens.json) | 0.6 MB | every design token, its value and why it exists |
|
|
47
|
+
| [`agent/vocabulary.json`](https://raw.githubusercontent.com/godx-jp/godxjp-ui/main/agent/vocabulary.json) | 7 KB | the controlled prop vocabulary |
|
|
48
|
+
| [`agent/rules.json`](https://raw.githubusercontent.com/godx-jp/godxjp-ui/main/agent/rules.json) | 17 KB | the 47 cardinal rules |
|
|
49
|
+
|
|
50
|
+
Pasteable bootstrap:
|
|
51
|
+
|
|
52
|
+
> Read https://raw.githubusercontent.com/godx-jp/godxjp-ui/main/agent/START-HERE.md and follow it.
|
|
53
|
+
> Then fetch .../agent/components-index.json to choose components, and
|
|
54
|
+
> .../agent/components/<Name>.json for the props of each one you chose. Tell me which catalog
|
|
55
|
+
> version you read.
|
|
56
|
+
|
|
57
|
+
**Pin to the version you installed.** Every URL above tracks `main`. Swap `main` for the matching
|
|
58
|
+
tag — `https://raw.githubusercontent.com/godx-jp/godxjp-ui/v28.4.0/agent/...` — because a catalog
|
|
59
|
+
newer than your package describes props you do not have, an older one hides props you do, and
|
|
60
|
+
neither failure announces itself. Pinned URLs only resolve for releases whose tag contains
|
|
61
|
+
`agent/`; on a 404 the release predates this catalog, so read `main` and compare
|
|
62
|
+
`index.json` → `version` against what you installed.
|
|
63
|
+
|
|
64
|
+
### Why static files and not a hosted MCP endpoint
|
|
65
|
+
|
|
66
|
+
GitHub serves files; it does not run servers. MCP over the network needs a process handling POST
|
|
67
|
+
requests, which no amount of Pages or raw hosting provides. A hosted HTTP MCP would work and would
|
|
68
|
+
need real hosting, ops and an auth decision — so the static lane ships first, carrying the same
|
|
69
|
+
data at no operational cost. Regenerate both from the one source with `pnpm gen:agent-catalog`.
|
|
70
|
+
|
|
71
|
+
---
|
|
72
|
+
|
|
15
73
|
## Role & boundary — read this first
|
|
16
74
|
|
|
17
75
|
This package is **the single source of UI truth**. It is shared, versioned infrastructure, which means two things are non-negotiable:
|
package/dist/app/theme-axes.js
CHANGED
|
@@ -68,6 +68,12 @@ function applyPrimaryColor(root, color, foreground) {
|
|
|
68
68
|
"--primary-active": "initial",
|
|
69
69
|
"--primary-border": "initial",
|
|
70
70
|
"--control-outline": "initial",
|
|
71
|
+
/* The brand TEXT roles derive from the seed too (gh#664), so they are reset for the same
|
|
72
|
+
* reason: an ancestor theme that pinned a link colour for the previous brand would otherwise
|
|
73
|
+
* outrank the seed just set, and a re-tinted product would keep the old brand's links. */
|
|
74
|
+
"--text-link": "initial",
|
|
75
|
+
"--text-brand": "initial",
|
|
76
|
+
"--text-primary": "initial",
|
|
71
77
|
"--primary-hover-channels": `var(--primary-hover-${polarity}-channels)`,
|
|
72
78
|
"--primary-active-channels": `var(--primary-active-${polarity}-channels)`,
|
|
73
79
|
"--ring": hsl(rgb)
|
|
@@ -120,6 +120,7 @@ const ScrollArea = React.forwardRef(
|
|
|
120
120
|
anchorOffset,
|
|
121
121
|
onAnchoredChange,
|
|
122
122
|
orientation = "vertical",
|
|
123
|
+
scrollbar = "auto",
|
|
123
124
|
...props
|
|
124
125
|
}, ref) => {
|
|
125
126
|
const [viewport, setViewport] = React.useState(null);
|
|
@@ -153,6 +154,7 @@ const ScrollArea = React.forwardRef(
|
|
|
153
154
|
"data-slot": "scroll-area-viewport",
|
|
154
155
|
"data-anchor": anchor,
|
|
155
156
|
"data-orientation": orientation,
|
|
157
|
+
"data-scrollbar": scrollbar,
|
|
156
158
|
className: cn("ui-scroll-area", className),
|
|
157
159
|
...props,
|
|
158
160
|
children: /* @__PURE__ */ jsx("div", { "data-slot": "scroll-area-content", className: "ui-scroll-area-content", children })
|
|
@@ -1,4 +1,9 @@
|
|
|
1
1
|
import * as React from "react";
|
|
2
|
+
import { DayButton, dateMatchModifiers } from "react-day-picker";
|
|
3
|
+
import type { DateRange, Modifiers } from "react-day-picker";
|
|
4
|
+
export { DayButton, dateMatchModifiers };
|
|
5
|
+
export type { DateRange, Modifiers };
|
|
6
|
+
export type { DayPickerProps, DayButtonProps, Matcher, CalendarDay, DateLib, } from "react-day-picker";
|
|
2
7
|
import type { CalendarProp } from "../../props/components/data-entry.prop.js";
|
|
3
8
|
export type { CalendarProp, CalendarProp as CalendarProps, CalendarCellRenderProp, CalendarFooterProp, } from "../../props/components/data-entry.prop.js";
|
|
4
9
|
export declare function Calendar({ className, classNames, showOutsideDays, "aria-label": ariaLabel, labels, showToday, showClose, onClose, footer, width, bordered, cellRender, month: monthProp, onMonthChange, locale: localeProp, ...props }: CalendarProp): React.JSX.Element;
|
|
@@ -187,7 +187,9 @@ function Calendar({
|
|
|
187
187
|
* So the original node is passed in and the consumer decorates around it.
|
|
188
188
|
*/
|
|
189
189
|
...cellRender ? {
|
|
190
|
-
DayButton: (dayButtonProps) => /* @__PURE__ */ jsx(Fragment, { children: cellRender(dayButtonProps.day.date, {
|
|
190
|
+
DayButton: (dayButtonProps) => /* @__PURE__ */ jsx(Fragment, { children: cellRender(dayButtonProps.day.date, {
|
|
191
|
+
originNode: /* @__PURE__ */ jsx(DayButton, { ...dayButtonProps })
|
|
192
|
+
}) })
|
|
191
193
|
} : {},
|
|
192
194
|
/*
|
|
193
195
|
* A consumer's `components` MERGE with ours; they must not replace the object.
|
|
@@ -205,5 +207,7 @@ function Calendar({
|
|
|
205
207
|
);
|
|
206
208
|
}
|
|
207
209
|
export {
|
|
208
|
-
Calendar
|
|
210
|
+
Calendar,
|
|
211
|
+
DayButton,
|
|
212
|
+
dateMatchModifiers
|
|
209
213
|
};
|
|
@@ -70,6 +70,7 @@ function DatePicker(props) {
|
|
|
70
70
|
defaultOpen = false,
|
|
71
71
|
onOpenChange,
|
|
72
72
|
inputReadOnly,
|
|
73
|
+
width,
|
|
73
74
|
preserveInvalidOnBlur,
|
|
74
75
|
placement = "bottom-start",
|
|
75
76
|
renderExtraFooter,
|
|
@@ -580,11 +581,16 @@ function DatePicker(props) {
|
|
|
580
581
|
"data-size": size,
|
|
581
582
|
"data-status": status,
|
|
582
583
|
"data-variant": variant,
|
|
584
|
+
"data-width": width,
|
|
583
585
|
"aria-disabled": allDisabled ? true : void 0,
|
|
584
586
|
"data-disabled": allDisabled ? "" : void 0,
|
|
585
587
|
"data-state": open ? "open" : "closed",
|
|
586
588
|
className: cn(
|
|
587
589
|
"ui-control ui-control-composite-field",
|
|
590
|
+
// `bounded` emits NO utility on purpose — control.css owns it, and a utility here
|
|
591
|
+
// would win the layer order and kill the token (gh#366, gh#375, gh#799).
|
|
592
|
+
width === "auto" && "w-auto",
|
|
593
|
+
width === "full" && "w-full",
|
|
588
594
|
"aria-invalid:border-destructive",
|
|
589
595
|
CONTROL_VARIANT_CHROME_CLASS[variant ?? "outlined"],
|
|
590
596
|
CONTROL_STATUS_CHROME_CLASS,
|
|
@@ -610,6 +616,12 @@ function DatePicker(props) {
|
|
|
610
616
|
/* @__PURE__ */ jsx(
|
|
611
617
|
Input,
|
|
612
618
|
{
|
|
619
|
+
"data-width": width,
|
|
620
|
+
className: cn(
|
|
621
|
+
width === "auto" && "w-auto",
|
|
622
|
+
width === "full" && "w-full",
|
|
623
|
+
width === "bounded" && "w-[var(--control-bounded-width)] max-w-full"
|
|
624
|
+
),
|
|
613
625
|
id: rootId,
|
|
614
626
|
name: displayIsCanonical ? resolvedName : "",
|
|
615
627
|
ref,
|
|
@@ -42,6 +42,7 @@ export type { SelectProp, SelectProp as SelectProps } from "./select.js";
|
|
|
42
42
|
export type { SearchSelectOptionProp as SelectOption, SearchSelectLoadParamsProp as SelectLoadParams, SearchSelectLoadResultProp as SelectLoadResult, } from "./search-select.js";
|
|
43
43
|
export { UPLOAD_LIST_IGNORE, Upload, collectUploadCommitActions, createUploadItem, useUploadDraft, } from "./upload.js";
|
|
44
44
|
export type { UploadProps, UploadFileItem, UploadVariant, UploadCommitAction } from "./upload.js";
|
|
45
|
+
export { UploadCropDialog } from "./upload-crop-dialog.js";
|
|
45
46
|
export { Cascader } from "./cascader.js";
|
|
46
47
|
export type { CascaderProps, TreeOption, TreeFieldNames } from "./cascader.js";
|
|
47
48
|
export { TreeSelect, SHOW_CHILD, SHOW_PARENT, SHOW_ALL } from "./tree-select.js";
|
|
@@ -72,3 +73,5 @@ export type { UploadRequestContext, UploadResult, UploadRejection } from "./uplo
|
|
|
72
73
|
export type { UploadItemActions } from "./upload-types.js";
|
|
73
74
|
export { Attachments } from "./attachments.js";
|
|
74
75
|
export type { AttachmentsProp, AttachmentsProps, AttachmentsItemProp, AttachmentsPlaceholderProp, AttachmentsOverflowProp, AttachmentsRefProp, } from "./attachments.js";
|
|
76
|
+
export { DayButton, dateMatchModifiers } from "./calendar.js";
|
|
77
|
+
export type { DateRange, Modifiers, DayPickerProps, DayButtonProps, Matcher, CalendarDay, DateLib, } from "./calendar.js";
|
|
@@ -39,6 +39,7 @@ import {
|
|
|
39
39
|
createUploadItem,
|
|
40
40
|
useUploadDraft
|
|
41
41
|
} from "./upload.js";
|
|
42
|
+
import { UploadCropDialog } from "./upload-crop-dialog.js";
|
|
42
43
|
import { Cascader } from "./cascader.js";
|
|
43
44
|
import { TreeSelect, SHOW_CHILD, SHOW_PARENT, SHOW_ALL } from "./tree-select.js";
|
|
44
45
|
import { Transfer } from "./transfer.js";
|
|
@@ -60,6 +61,7 @@ import { Segmented } from "./segmented.js";
|
|
|
60
61
|
import { BranchScopePicker } from "./branch-scope-picker.js";
|
|
61
62
|
import { TimeRangePicker } from "./time-range-picker.js";
|
|
62
63
|
import { Attachments } from "./attachments.js";
|
|
64
|
+
import { DayButton, dateMatchModifiers } from "./calendar.js";
|
|
63
65
|
export {
|
|
64
66
|
Attachments,
|
|
65
67
|
BranchScopePicker,
|
|
@@ -78,6 +80,7 @@ export {
|
|
|
78
80
|
CommandList,
|
|
79
81
|
CommandPalette,
|
|
80
82
|
DatePicker,
|
|
83
|
+
DayButton,
|
|
81
84
|
Field,
|
|
82
85
|
Form,
|
|
83
86
|
FormErrors,
|
|
@@ -125,8 +128,10 @@ export {
|
|
|
125
128
|
TreeSelect,
|
|
126
129
|
UPLOAD_LIST_IGNORE,
|
|
127
130
|
Upload,
|
|
131
|
+
UploadCropDialog,
|
|
128
132
|
collectUploadCommitActions,
|
|
129
133
|
createUploadItem,
|
|
134
|
+
dateMatchModifiers,
|
|
130
135
|
useFormLayout,
|
|
131
136
|
usePasswordStrength,
|
|
132
137
|
useUploadDraft
|
|
@@ -6,4 +6,4 @@ export type { TimePickerDisabledTimeProp, TimePickerProp, TimePickerProp as Time
|
|
|
6
6
|
* canonical): form-submittable (give it a `name`), screen-reader friendly, and e2e-testable by
|
|
7
7
|
* filling the input.
|
|
8
8
|
*/
|
|
9
|
-
export declare function TimePicker({ value: controlledValue, defaultValue, onValueChange, placeholder, disabled, className, id, name, minuteStep, hourStep, changeOnScroll, secondStep, showSeconds: showSecondsProp, use12Hours, format, open: openProp, defaultOpen, onOpenChange, inputReadOnly, preserveInvalidOnBlur, placement, renderExtraFooter, size, status, variant, ref, disabledTime, hideDisabledOptions, showNow, needConfirm, allowClear, ...ariaProps }: TimePickerProp): React.JSX.Element;
|
|
9
|
+
export declare function TimePicker({ value: controlledValue, defaultValue, onValueChange, placeholder, disabled, className, id, name, minuteStep, hourStep, changeOnScroll, secondStep, showSeconds: showSecondsProp, use12Hours, format, open: openProp, defaultOpen, onOpenChange, inputReadOnly, width, preserveInvalidOnBlur, placement, renderExtraFooter, size, status, variant, ref, disabledTime, hideDisabledOptions, showNow, needConfirm, allowClear, ...ariaProps }: TimePickerProp): React.JSX.Element;
|
|
@@ -377,6 +377,7 @@ function TimePicker({
|
|
|
377
377
|
defaultOpen = false,
|
|
378
378
|
onOpenChange,
|
|
379
379
|
inputReadOnly,
|
|
380
|
+
width,
|
|
380
381
|
preserveInvalidOnBlur,
|
|
381
382
|
placement = "bottom-end",
|
|
382
383
|
renderExtraFooter,
|
|
@@ -428,6 +429,7 @@ function TimePicker({
|
|
|
428
429
|
/* @__PURE__ */ jsx(PopoverAnchor, { asChild: true, children: /* @__PURE__ */ jsx("div", { className: cn("relative", className), children: /* @__PURE__ */ jsx(
|
|
429
430
|
Input,
|
|
430
431
|
{
|
|
432
|
+
"data-width": width,
|
|
431
433
|
id,
|
|
432
434
|
ref,
|
|
433
435
|
size,
|
|
@@ -445,7 +447,12 @@ function TimePicker({
|
|
|
445
447
|
"aria-haspopup": "dialog",
|
|
446
448
|
"aria-controls": open ? dialogId : void 0,
|
|
447
449
|
...fieldA11y,
|
|
448
|
-
className:
|
|
450
|
+
className: cn(
|
|
451
|
+
"tabular-nums",
|
|
452
|
+
width === "auto" && "w-auto",
|
|
453
|
+
width === "full" && "w-full",
|
|
454
|
+
width === "bounded" && "w-[var(--control-bounded-width)] max-w-full"
|
|
455
|
+
),
|
|
449
456
|
trailingIcon: /* @__PURE__ */ jsx("span", { className: "ui-time-picker-affix", children: showClear ? /* @__PURE__ */ jsx(
|
|
450
457
|
"button",
|
|
451
458
|
{
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"$comment": "AUTO-GENERATED by scripts/gen-measurement-contract.mjs — do not edit. Read this instead of guessing: docs/MEASUREMENT-CONTRACT.md.",
|
|
3
|
-
"version": "28.
|
|
3
|
+
"version": "28.5.0",
|
|
4
4
|
"targetSize": {
|
|
5
5
|
"standard": "WCAG 2.2 SC 2.5.8 Target Size (Minimum), level AA — 24×24 CSS px",
|
|
6
6
|
"min": 24,
|
|
@@ -540,6 +540,11 @@ export type PermissionMatrixProp = {
|
|
|
540
540
|
* live stream (chat, log tail, streaming response, activity feed).
|
|
541
541
|
*/
|
|
542
542
|
export type ScrollAreaAnchorProp = "none" | "bottom";
|
|
543
|
+
/**
|
|
544
|
+
* Whether the scrollbar is always drawn, or left to the platform (gh#798). `auto` is the platform
|
|
545
|
+
* decision and the default; `always` forces a classic, space-occupying bar.
|
|
546
|
+
*/
|
|
547
|
+
export type ScrollAreaScrollbarProp = "auto" | "always";
|
|
543
548
|
/** @see ScrollArea */
|
|
544
549
|
/**
|
|
545
550
|
* @see ScrollArea — which AXES scroll. This is not decoration: it IS the `overflow` the element
|
|
@@ -570,6 +575,23 @@ export type ScrollAreaProp = {
|
|
|
570
575
|
*/
|
|
571
576
|
viewportRef?: React.Ref<HTMLDivElement>;
|
|
572
577
|
/** Edge the viewport sticks to as content grows. Default `none` (inert). */
|
|
578
|
+
/**
|
|
579
|
+
* Whether the scrollbar is drawn ALWAYS or only when the platform feels like it (gh#798).
|
|
580
|
+
*
|
|
581
|
+
* Default `auto` — today's behaviour, unchanged: the browser decides, styled from the
|
|
582
|
+
* `--scroll-area-*` tokens. On macOS/iPadOS with the system default "Show scroll bars: when
|
|
583
|
+
* scrolling", that decision is an OVERLAY bar, which exists only while the reader is already
|
|
584
|
+
* scrolling — so the tokens style a bar nobody sees, and a wide area does not LOOK scrollable.
|
|
585
|
+
* Measured by a consumer: clientWidth 727, scrollWidth 3476, and `offsetHeight - clientHeight`
|
|
586
|
+
* of 2px (the border, twice) — no bar occupies layout at all. A manager reading a 31-column
|
|
587
|
+
* roster said it showed "only five days".
|
|
588
|
+
*
|
|
589
|
+
* `always` forces a classic, space-occupying bar via `::-webkit-scrollbar`, which Chrome and
|
|
590
|
+
* Safari honour even in overlay mode, painted from the same tokens. Reach for it where the
|
|
591
|
+
* affordance IS the information — a wide table, a roster, a board. Leave it `auto` for a chat
|
|
592
|
+
* stream, where a permanent bar is noise (gh#311).
|
|
593
|
+
*/
|
|
594
|
+
scrollbar?: ScrollAreaScrollbarProp;
|
|
573
595
|
anchor?: ScrollAreaAnchorProp;
|
|
574
596
|
/**
|
|
575
597
|
* Distance in px from the bottom edge inside which the reader still counts as "at the bottom"
|
|
@@ -770,6 +770,20 @@ export type CalendarFooterProp = {
|
|
|
770
770
|
};
|
|
771
771
|
/** Shared picker chrome. Placement uses logical start/end so RTL follows the locale. */
|
|
772
772
|
export type PickerChromeProp = {
|
|
773
|
+
/**
|
|
774
|
+
* How the field takes its inline space, exactly as `Select` means it (gh#799).
|
|
775
|
+
*
|
|
776
|
+
* CONSUMER-RULES §5 says a control outside a form takes `width="auto"`, and `Select` has carried
|
|
777
|
+
* `width` since gh#375 — the pickers did not, so the one control in a toolbar with a KNOWN
|
|
778
|
+
* content width was the one that could not be sized. Measured in a consumer toolbar at 1440px:
|
|
779
|
+
* a month picker showing `2026/09` took 275px, against the 144px box it had before the migration,
|
|
780
|
+
* because with no prop it falls to the flex default and stretches.
|
|
781
|
+
*
|
|
782
|
+
* `auto` shrink-wraps to the display format; `full` fills the line; `bounded` holds one width
|
|
783
|
+
* while the value's length varies (its width is owned by the `[data-width="bounded"]` rule in
|
|
784
|
+
* control.css, NOT by a utility — see the note there).
|
|
785
|
+
*/
|
|
786
|
+
width?: ControlWidthProp;
|
|
773
787
|
open?: boolean;
|
|
774
788
|
defaultOpen?: boolean;
|
|
775
789
|
onOpenChange?: (open: boolean) => void;
|
package/dist/props/registry.d.ts
CHANGED
|
@@ -1810,6 +1810,15 @@ export declare const COMPONENT_PROP_REGISTRY: {
|
|
|
1810
1810
|
readonly reason: 'Edge the scrolling viewport sticks to as content grows ("none" | "bottom"). A closed union, not a boolean pair — the third edge ("top", for an inverted feed) is a value, not another flag.';
|
|
1811
1811
|
}];
|
|
1812
1812
|
};
|
|
1813
|
+
readonly ScrollAreaScrollbarProp: {
|
|
1814
|
+
readonly group: "data-display";
|
|
1815
|
+
readonly file: "components/data-display.prop.ts";
|
|
1816
|
+
readonly vocabulary: readonly [{
|
|
1817
|
+
readonly field: "scrollbar";
|
|
1818
|
+
readonly local: true;
|
|
1819
|
+
readonly reason: 'Whether the scrollbar is always drawn or left to the platform ("auto" | "always"). Not a width or a colour — those are the --scroll-area-* tokens; this names WHO decides the bar exists, because on macOS/iPadOS the platform decides "only while scrolling" and a wide area then never looks scrollable (gh#798).';
|
|
1820
|
+
}];
|
|
1821
|
+
};
|
|
1813
1822
|
readonly ScrollAreaOrientationProp: {
|
|
1814
1823
|
readonly group: "data-display";
|
|
1815
1824
|
readonly file: "components/data-display.prop.ts";
|
package/dist/props/registry.js
CHANGED
|
@@ -2203,6 +2203,17 @@ const COMPONENT_PROP_REGISTRY = {
|
|
|
2203
2203
|
}
|
|
2204
2204
|
]
|
|
2205
2205
|
},
|
|
2206
|
+
ScrollAreaScrollbarProp: {
|
|
2207
|
+
group: "data-display",
|
|
2208
|
+
file: "components/data-display.prop.ts",
|
|
2209
|
+
vocabulary: [
|
|
2210
|
+
{
|
|
2211
|
+
field: "scrollbar",
|
|
2212
|
+
local: true,
|
|
2213
|
+
reason: 'Whether the scrollbar is always drawn or left to the platform ("auto" | "always"). Not a width or a colour \u2014 those are the --scroll-area-* tokens; this names WHO decides the bar exists, because on macOS/iPadOS the platform decides "only while scrolling" and a wide area then never looks scrollable (gh#798).'
|
|
2214
|
+
}
|
|
2215
|
+
]
|
|
2216
|
+
},
|
|
2206
2217
|
ScrollAreaOrientationProp: {
|
|
2207
2218
|
group: "data-display",
|
|
2208
2219
|
file: "components/data-display.prop.ts",
|
package/dist/styles/base.css
CHANGED
|
@@ -74,7 +74,9 @@
|
|
|
74
74
|
--color-attention: hsl(var(--attention));
|
|
75
75
|
--color-attention-foreground: hsl(var(--attention-foreground));
|
|
76
76
|
|
|
77
|
-
--color-primary-strong: hsl(
|
|
77
|
+
--color-primary-strong: hsl(
|
|
78
|
+
var(--text-primary, from hsl(var(--primary)) var(--text-primary-channels))
|
|
79
|
+
);
|
|
78
80
|
--color-success-strong: hsl(var(--text-success));
|
|
79
81
|
--color-warning-strong: hsl(var(--text-warning));
|
|
80
82
|
--color-info-strong: hsl(var(--text-info));
|
|
@@ -97,8 +99,8 @@
|
|
|
97
99
|
|
|
98
100
|
--color-foreground-tertiary: hsl(var(--text-tertiary));
|
|
99
101
|
--color-foreground-disabled: hsl(var(--text-disabled));
|
|
100
|
-
--color-link: hsl(var(--text-link));
|
|
101
|
-
--color-brand: hsl(var(--text-brand));
|
|
102
|
+
--color-link: hsl(var(--text-link, from hsl(var(--primary)) var(--text-link-channels)));
|
|
103
|
+
--color-brand: hsl(var(--text-brand, from hsl(var(--primary)) var(--text-brand-channels)));
|
|
102
104
|
|
|
103
105
|
--color-primary-hover: hsl(
|
|
104
106
|
var(--primary-hover, from hsl(var(--primary)) var(--primary-hover-channels))
|
|
@@ -55,27 +55,32 @@
|
|
|
55
55
|
}
|
|
56
56
|
|
|
57
57
|
[data-slot="card"][data-accent="primary"] {
|
|
58
|
-
--card-accent-color: hsl(
|
|
58
|
+
--card-accent-color: hsl(
|
|
59
|
+
var(
|
|
60
|
+
--mark-primary,
|
|
61
|
+
var(--text-primary, from hsl(var(--primary)) var(--text-primary-channels))
|
|
62
|
+
)
|
|
63
|
+
);
|
|
59
64
|
}
|
|
60
65
|
|
|
61
66
|
[data-slot="card"][data-accent="success"] {
|
|
62
|
-
--card-accent-color: hsl(var(--mark-success));
|
|
67
|
+
--card-accent-color: hsl(var(--mark-success, var(--text-success)));
|
|
63
68
|
}
|
|
64
69
|
|
|
65
70
|
[data-slot="card"][data-accent="warning"] {
|
|
66
|
-
--card-accent-color: hsl(var(--mark-warning));
|
|
71
|
+
--card-accent-color: hsl(var(--mark-warning, var(--text-warning)));
|
|
67
72
|
}
|
|
68
73
|
|
|
69
74
|
[data-slot="card"][data-accent="info"] {
|
|
70
|
-
--card-accent-color: hsl(var(--mark-info));
|
|
75
|
+
--card-accent-color: hsl(var(--mark-info, var(--text-info)));
|
|
71
76
|
}
|
|
72
77
|
|
|
73
78
|
[data-slot="card"][data-accent="attention"] {
|
|
74
|
-
--card-accent-color: hsl(var(--mark-attention));
|
|
79
|
+
--card-accent-color: hsl(var(--mark-attention, var(--attention)));
|
|
75
80
|
}
|
|
76
81
|
|
|
77
82
|
[data-slot="card"][data-accent="destructive"] {
|
|
78
|
-
--card-accent-color: hsl(var(--mark-destructive));
|
|
83
|
+
--card-accent-color: hsl(var(--mark-destructive, var(--text-error)));
|
|
79
84
|
}
|
|
80
85
|
|
|
81
86
|
[data-slot="card"][data-accent] {
|
package/dist/styles/control.css
CHANGED
|
@@ -999,7 +999,7 @@
|
|
|
999
999
|
.ui-otp-container:has(.ui-otp-input[data-status="warning"]) .ui-otp-slot,
|
|
1000
1000
|
.ui-otp-container:has(.ui-otp-input[data-status="warning"])
|
|
1001
1001
|
.ui-otp-group[data-appearance="grouped"] {
|
|
1002
|
-
border-color: var(--control-status-warning-border-color);
|
|
1002
|
+
border-color: var(--control-status-warning-border-color, hsl(var(--text-warning)));
|
|
1003
1003
|
}
|
|
1004
1004
|
|
|
1005
1005
|
.ui-otp-container:has(.ui-otp-input[readonly]) .ui-otp-slot {
|
|
@@ -1326,7 +1326,9 @@
|
|
|
1326
1326
|
cursor: not-allowed;
|
|
1327
1327
|
}
|
|
1328
1328
|
|
|
1329
|
-
.ui-control-trigger[data-width="bounded"]
|
|
1329
|
+
.ui-control-trigger[data-width="bounded"],
|
|
1330
|
+
|
|
1331
|
+
.ui-control[data-width="bounded"] {
|
|
1330
1332
|
inline-size: var(--control-bounded-width);
|
|
1331
1333
|
max-inline-size: 100%;
|
|
1332
1334
|
}
|
|
@@ -1369,10 +1371,10 @@
|
|
|
1369
1371
|
}
|
|
1370
1372
|
|
|
1371
1373
|
.ui-control-surface[data-status="warning"] {
|
|
1372
|
-
border-color: var(--control-status-warning-border-color);
|
|
1374
|
+
border-color: var(--control-status-warning-border-color, hsl(var(--text-warning)));
|
|
1373
1375
|
--focus-ring-color: var(--warning);
|
|
1374
1376
|
--focus-outline-color: var(--warning);
|
|
1375
|
-
--focus-ring-glow-color: var(--control-status-warning-outline-color);
|
|
1377
|
+
--focus-ring-glow-color: var(--control-status-warning-outline-color, var(--text-warning));
|
|
1376
1378
|
}
|
|
1377
1379
|
|
|
1378
1380
|
.ui-number-input[data-size="sm"] {
|
|
@@ -2325,8 +2327,15 @@
|
|
|
2325
2327
|
|
|
2326
2328
|
.ui-calendar[data-width="full"] .ui-calendar-day-button {
|
|
2327
2329
|
inline-size: 100%;
|
|
2328
|
-
|
|
2329
2330
|
max-inline-size: none;
|
|
2331
|
+
block-size: auto;
|
|
2332
|
+
min-block-size: var(--control-height);
|
|
2333
|
+
|
|
2334
|
+
flex-direction: column;
|
|
2335
|
+
align-items: stretch;
|
|
2336
|
+
justify-content: flex-start;
|
|
2337
|
+
text-align: start;
|
|
2338
|
+
white-space: normal;
|
|
2330
2339
|
}
|
|
2331
2340
|
|
|
2332
2341
|
.ui-calendar-month {
|
|
@@ -2433,7 +2442,7 @@
|
|
|
2433
2442
|
|
|
2434
2443
|
.ui-calendar .ui-calendar-day.day-today:not(.day-selected) .ui-calendar-day-button {
|
|
2435
2444
|
box-shadow: inset 0 0 0 1px hsl(var(--primary));
|
|
2436
|
-
color: hsl(var(--text-primary));
|
|
2445
|
+
color: hsl(var(--text-primary, from hsl(var(--primary)) var(--text-primary-channels)));
|
|
2437
2446
|
font-weight: var(--font-weight-medium);
|
|
2438
2447
|
}
|
|
2439
2448
|
|
|
@@ -2462,7 +2471,7 @@
|
|
|
2462
2471
|
|
|
2463
2472
|
.ui-calendar .ui-calendar-day.day-today:not(:has(button)) {
|
|
2464
2473
|
box-shadow: inset 0 0 0 1px hsl(var(--primary));
|
|
2465
|
-
color: hsl(var(--text-primary));
|
|
2474
|
+
color: hsl(var(--text-primary, from hsl(var(--primary)) var(--text-primary-channels)));
|
|
2466
2475
|
font-weight: var(--font-weight-medium);
|
|
2467
2476
|
border-radius: var(--calendar-day-radius);
|
|
2468
2477
|
}
|
|
@@ -2797,8 +2806,8 @@
|
|
|
2797
2806
|
|
|
2798
2807
|
.ui-control[data-status="warning"],
|
|
2799
2808
|
.ui-control-multiline[data-status="warning"] {
|
|
2800
|
-
--focus-ring-color: var(--control-status-warning-outline-color);
|
|
2801
|
-
--focus-outline-color: var(--control-status-warning-outline-color);
|
|
2809
|
+
--focus-ring-color: var(--control-status-warning-outline-color, var(--text-warning));
|
|
2810
|
+
--focus-outline-color: var(--control-status-warning-outline-color, var(--text-warning));
|
|
2802
2811
|
--focus-ring-glow-color: var(--control-status-warning-glow-color);
|
|
2803
2812
|
--focus-ring-glow-alpha: var(--control-status-warning-glow-alpha);
|
|
2804
2813
|
}
|
|
@@ -2824,7 +2833,7 @@
|
|
|
2824
2833
|
}
|
|
2825
2834
|
|
|
2826
2835
|
.ui-control-count[data-exceeded="true"] {
|
|
2827
|
-
color: hsl(var(--control-count-exceeded-color));
|
|
2836
|
+
color: hsl(var(--control-count-exceeded-color, var(--text-error)));
|
|
2828
2837
|
}
|
|
2829
2838
|
|
|
2830
2839
|
.ui-textarea-count {
|
|
@@ -182,19 +182,19 @@
|
|
|
182
182
|
.ui-progress-bar {
|
|
183
183
|
height: 100%;
|
|
184
184
|
border-radius: inherit;
|
|
185
|
-
background: var(--progress-fill-background, hsl(var(--mark-success)));
|
|
185
|
+
background: var(--progress-fill-background, hsl(var(--mark-success, var(--text-success))));
|
|
186
186
|
}
|
|
187
187
|
|
|
188
188
|
.ui-progress[data-tone="warning"] .ui-progress-bar {
|
|
189
|
-
background: hsl(var(--mark-warning));
|
|
189
|
+
background: hsl(var(--mark-warning, var(--text-warning)));
|
|
190
190
|
}
|
|
191
191
|
|
|
192
192
|
.ui-progress[data-tone="destructive"] .ui-progress-bar {
|
|
193
|
-
background: hsl(var(--mark-destructive));
|
|
193
|
+
background: hsl(var(--mark-destructive, var(--text-error)));
|
|
194
194
|
}
|
|
195
195
|
|
|
196
196
|
.ui-progress[data-over] .ui-progress-bar {
|
|
197
|
-
background-color: hsl(var(--mark-destructive));
|
|
197
|
+
background-color: hsl(var(--mark-destructive, var(--text-error)));
|
|
198
198
|
background-image: repeating-linear-gradient(
|
|
199
199
|
45deg,
|
|
200
200
|
hsl(var(--destructive-foreground) / 0.4) 0,
|
|
@@ -223,15 +223,15 @@
|
|
|
223
223
|
}
|
|
224
224
|
|
|
225
225
|
.ui-progress-segment[data-tone="success"] {
|
|
226
|
-
background: hsl(var(--mark-success));
|
|
226
|
+
background: hsl(var(--mark-success, var(--text-success)));
|
|
227
227
|
}
|
|
228
228
|
|
|
229
229
|
.ui-progress-segment[data-tone="warning"] {
|
|
230
|
-
background: hsl(var(--mark-warning));
|
|
230
|
+
background: hsl(var(--mark-warning, var(--text-warning)));
|
|
231
231
|
}
|
|
232
232
|
|
|
233
233
|
.ui-progress-segment[data-tone="destructive"] {
|
|
234
|
-
background: hsl(var(--mark-destructive));
|
|
234
|
+
background: hsl(var(--mark-destructive, var(--text-error)));
|
|
235
235
|
}
|
|
236
236
|
|
|
237
237
|
.ui-progress-label {
|
|
@@ -273,17 +273,17 @@
|
|
|
273
273
|
}
|
|
274
274
|
|
|
275
275
|
.ui-progress-ring-indicator {
|
|
276
|
-
stroke: var(--progress-fill-background, hsl(var(--mark-success)));
|
|
276
|
+
stroke: var(--progress-fill-background, hsl(var(--mark-success, var(--text-success))));
|
|
277
277
|
|
|
278
278
|
stroke-linecap: butt;
|
|
279
279
|
}
|
|
280
280
|
|
|
281
281
|
.ui-progress[data-tone="warning"] .ui-progress-ring-indicator {
|
|
282
|
-
stroke: hsl(var(--mark-warning));
|
|
282
|
+
stroke: hsl(var(--mark-warning, var(--text-warning)));
|
|
283
283
|
}
|
|
284
284
|
|
|
285
285
|
.ui-progress[data-tone="destructive"] .ui-progress-ring-indicator {
|
|
286
|
-
stroke: hsl(var(--mark-destructive));
|
|
286
|
+
stroke: hsl(var(--mark-destructive, var(--text-error)));
|
|
287
287
|
}
|
|
288
288
|
|
|
289
289
|
.ui-progress-ring-label {
|
|
@@ -320,23 +320,28 @@
|
|
|
320
320
|
}
|
|
321
321
|
|
|
322
322
|
.ui-legend-swatch[data-tone="default"] {
|
|
323
|
-
background: hsl(
|
|
323
|
+
background: hsl(
|
|
324
|
+
var(
|
|
325
|
+
--mark-primary,
|
|
326
|
+
var(--text-primary, from hsl(var(--primary)) var(--text-primary-channels))
|
|
327
|
+
)
|
|
328
|
+
);
|
|
324
329
|
}
|
|
325
330
|
|
|
326
331
|
.ui-legend-swatch[data-tone="success"] {
|
|
327
|
-
background: hsl(var(--mark-success));
|
|
332
|
+
background: hsl(var(--mark-success, var(--text-success)));
|
|
328
333
|
}
|
|
329
334
|
|
|
330
335
|
.ui-legend-swatch[data-tone="warning"] {
|
|
331
|
-
background: hsl(var(--mark-warning));
|
|
336
|
+
background: hsl(var(--mark-warning, var(--text-warning)));
|
|
332
337
|
}
|
|
333
338
|
|
|
334
339
|
.ui-legend-swatch[data-tone="destructive"] {
|
|
335
|
-
background: hsl(var(--mark-destructive));
|
|
340
|
+
background: hsl(var(--mark-destructive, var(--text-error)));
|
|
336
341
|
}
|
|
337
342
|
|
|
338
343
|
.ui-legend-swatch[data-tone="info"] {
|
|
339
|
-
background: hsl(var(--mark-info));
|
|
344
|
+
background: hsl(var(--mark-info, var(--text-info)));
|
|
340
345
|
}
|
|
341
346
|
|
|
342
347
|
.ui-legend-swatch[data-tone="muted"],
|
|
@@ -386,11 +391,11 @@
|
|
|
386
391
|
}
|
|
387
392
|
|
|
388
393
|
.ui-feature-list-item[data-state="included"] .ui-feature-list-mark {
|
|
389
|
-
color: hsl(var(--mark-success));
|
|
394
|
+
color: hsl(var(--mark-success, var(--text-success)));
|
|
390
395
|
}
|
|
391
396
|
|
|
392
397
|
.ui-feature-list-item[data-state="limited"] .ui-feature-list-mark {
|
|
393
|
-
color: hsl(var(--mark-warning));
|
|
398
|
+
color: hsl(var(--mark-warning, var(--text-warning)));
|
|
394
399
|
}
|
|
395
400
|
|
|
396
401
|
.ui-feature-list-item[data-state="excluded"] .ui-feature-list-label {
|
|
@@ -958,6 +963,24 @@
|
|
|
958
963
|
overflow: auto;
|
|
959
964
|
}
|
|
960
965
|
|
|
966
|
+
.ui-scroll-area[data-scrollbar="always"] {
|
|
967
|
+
scrollbar-width: auto;
|
|
968
|
+
}
|
|
969
|
+
|
|
970
|
+
.ui-scroll-area[data-scrollbar="always"]::-webkit-scrollbar {
|
|
971
|
+
inline-size: var(--scroll-area-always-bar-size);
|
|
972
|
+
block-size: var(--scroll-area-always-bar-size);
|
|
973
|
+
}
|
|
974
|
+
|
|
975
|
+
.ui-scroll-area[data-scrollbar="always"]::-webkit-scrollbar-track {
|
|
976
|
+
background: var(--scroll-area-track-color, transparent);
|
|
977
|
+
}
|
|
978
|
+
|
|
979
|
+
.ui-scroll-area[data-scrollbar="always"]::-webkit-scrollbar-thumb {
|
|
980
|
+
background: var(--scroll-area-thumb-color, hsl(var(--border)));
|
|
981
|
+
border-radius: var(--scroll-area-always-thumb-radius);
|
|
982
|
+
}
|
|
983
|
+
|
|
961
984
|
.ui-scroll-area:is([data-orientation="horizontal"], [data-orientation="both"])
|
|
962
985
|
> .ui-scroll-area-content {
|
|
963
986
|
inline-size: max-content;
|
|
@@ -1051,7 +1074,10 @@
|
|
|
1051
1074
|
|
|
1052
1075
|
.ui-code-block [data-code-token="link"],
|
|
1053
1076
|
.ui-prose pre [data-code-token="link"] {
|
|
1054
|
-
color: var(
|
|
1077
|
+
color: var(
|
|
1078
|
+
--code-block-token-link-color,
|
|
1079
|
+
hsl(var(--text-link, from hsl(var(--primary)) var(--text-link-channels)))
|
|
1080
|
+
);
|
|
1055
1081
|
text-decoration-line: underline;
|
|
1056
1082
|
|
|
1057
1083
|
text-underline-offset: var(--text-link-underline-offset);
|