@godxjp/ui 33.10.1 → 33.12.1
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/DESIGN.md +1 -0
- package/README.md +3 -3
- package/agent/DESIGN.md +1 -0
- package/agent/START-HERE.md +7 -7
- package/agent/components/Anchor.json +1 -1
- package/agent/components/AppShell.json +1 -1
- package/agent/components/Cascader.json +1 -0
- package/agent/components/DataTable.json +1 -1
- package/agent/components/DatePicker.json +1 -0
- package/agent/components/Input.json +1 -0
- package/agent/components/NumberInput.json +1 -0
- package/agent/components/Pagination.json +1 -1
- package/agent/components/PasswordInput.json +1 -0
- package/agent/components/ResizablePanel.json +1 -1
- package/agent/components/ScrollArea.json +1 -1
- package/agent/components/SearchInput.json +1 -0
- package/agent/components/Select.json +1 -0
- package/agent/components/Table.json +1 -1
- package/agent/components/TimePicker.json +1 -0
- package/agent/components/Topbar.json +8 -2
- package/agent/components/TopbarItem.json +7 -1
- package/agent/components/TreeSelect.json +1 -0
- package/agent/components-index.json +7 -7
- package/agent/components.json +31 -10
- package/agent/index.json +6 -6
- package/agent/llms.txt +6 -6
- package/agent/tokens.json +39 -3
- package/dist/components/data-display/data-table.js +2 -0
- package/dist/components/data-display/table.js +3 -0
- package/dist/components/data-entry/input.js +16 -1
- package/dist/components/data-entry/search-input.js +1 -1
- package/dist/components/layout/app-shell.js +16 -6
- package/dist/components/layout/topbar-item.d.ts +1 -0
- package/dist/components/layout/topbar-item.js +9 -4
- package/dist/components/layout/topbar.d.ts +1 -1
- package/dist/components/layout/topbar.js +32 -3
- package/dist/components/navigation/pagination.js +4 -0
- package/dist/contracts/measurement.json +1 -1
- package/dist/lab/anchor.js +11 -1
- package/dist/lib/focus-reveal.d.ts +5 -0
- package/dist/lib/focus-reveal.js +19 -0
- package/dist/lib/hooks.js +5 -2
- package/dist/props/components/layout.prop.d.ts +13 -0
- package/dist/props/registry.d.ts +9 -1
- package/dist/props/registry.js +10 -0
- package/dist/styles/control.css +131 -3
- package/dist/styles/focus-ring.css +79 -19
- package/dist/styles/layers.json +1 -1
- package/dist/styles/layout.css +4 -4
- package/dist/styles/shell-layout.css +48 -0
- package/dist/styles.css +1 -1
- package/dist/tokens/base.css +2 -0
- package/dist/tokens/components/control.css +4 -1
- package/dist/tokens/components/resizable.css +4 -0
- package/dist/tokens/components/shell.css +3 -0
- package/dist/tokens/foundation.css +4 -1
- package/docs/TOKENS.md +52 -23
- package/package.json +2 -2
- package/scripts/visual-audit.mjs +33 -3
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { revealKeyboardFocus } from "../../lib/focus-reveal.js";
|
|
3
4
|
import { MoreHorizontal } from "lucide-react";
|
|
4
5
|
import * as React from "react";
|
|
5
6
|
import { useTranslation } from "../../i18n/use-translation.js";
|
|
@@ -11,17 +12,21 @@ function Topbar({
|
|
|
11
12
|
start,
|
|
12
13
|
center,
|
|
13
14
|
end,
|
|
15
|
+
identity,
|
|
14
16
|
className,
|
|
15
17
|
children,
|
|
16
18
|
height,
|
|
17
19
|
overflow = "scroll",
|
|
18
20
|
pad,
|
|
19
21
|
style,
|
|
22
|
+
onFocusCapture,
|
|
20
23
|
...props
|
|
21
24
|
}) {
|
|
22
25
|
const barRef = React.useRef(null);
|
|
26
|
+
const controlsRef = React.useRef(null);
|
|
27
|
+
const hasIdentity = identity != null && children == null;
|
|
23
28
|
const foldable = overflow === "menu" && children == null;
|
|
24
|
-
const collapsed = useCollapsesToMenu(barRef, foldable);
|
|
29
|
+
const collapsed = useCollapsesToMenu(hasIdentity ? controlsRef : barRef, foldable);
|
|
25
30
|
const clusters = /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
26
31
|
start != null ? /* @__PURE__ */ jsx("div", { "data-slot": "topbar-start", className: "ui-topbar-start", children: start }) : null,
|
|
27
32
|
center != null ? /* @__PURE__ */ jsx("div", { "data-slot": "topbar-center", className: "ui-topbar-center", children: center }) : null,
|
|
@@ -31,14 +36,32 @@ function Topbar({
|
|
|
31
36
|
"div",
|
|
32
37
|
{
|
|
33
38
|
ref: barRef,
|
|
39
|
+
onFocusCapture: (event) => {
|
|
40
|
+
onFocusCapture?.(event);
|
|
41
|
+
if (!event.defaultPrevented) revealKeyboardFocus(event);
|
|
42
|
+
},
|
|
34
43
|
"data-height": height,
|
|
44
|
+
"data-identity": hasIdentity ? "true" : void 0,
|
|
35
45
|
"data-overflow": overflow,
|
|
36
46
|
"data-collapsed": foldable ? String(collapsed) : void 0,
|
|
37
47
|
style: { ...style, ...padStyle(pad, void 0) },
|
|
38
48
|
"data-slot": "topbar",
|
|
39
49
|
className: cn("ui-topbar", className),
|
|
40
50
|
...props,
|
|
41
|
-
children: children ?? (
|
|
51
|
+
children: children ?? (hasIdentity ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
52
|
+
/* @__PURE__ */ jsx(
|
|
53
|
+
"div",
|
|
54
|
+
{
|
|
55
|
+
ref: controlsRef,
|
|
56
|
+
onFocusCapture: revealKeyboardFocus,
|
|
57
|
+
"data-slot": "topbar-controls",
|
|
58
|
+
"data-overflow": overflow,
|
|
59
|
+
className: "ui-topbar ui-topbar-controls",
|
|
60
|
+
children: collapsed ? /* @__PURE__ */ jsx(TopbarOverflowMenu, { children: clusters }) : clusters
|
|
61
|
+
}
|
|
62
|
+
),
|
|
63
|
+
/* @__PURE__ */ jsx("div", { "data-slot": "topbar-identity", className: "ui-topbar-identity", children: identity })
|
|
64
|
+
] }) : collapsed ? /* @__PURE__ */ jsx(TopbarOverflowMenu, { children: clusters }) : clusters)
|
|
42
65
|
}
|
|
43
66
|
);
|
|
44
67
|
}
|
|
@@ -69,7 +92,13 @@ function useCollapsesToMenu(ref, enabled) {
|
|
|
69
92
|
if (typeof ResizeObserver === "undefined") return void 0;
|
|
70
93
|
const observer = new ResizeObserver(update);
|
|
71
94
|
observer.observe(bar);
|
|
72
|
-
if (!collapsed)
|
|
95
|
+
if (!collapsed)
|
|
96
|
+
for (const cluster of bar.children) {
|
|
97
|
+
observer.observe(cluster);
|
|
98
|
+
if (cluster.getAttribute("data-slot") === "topbar-start") {
|
|
99
|
+
for (const cell of cluster.children) observer.observe(cell);
|
|
100
|
+
}
|
|
101
|
+
}
|
|
73
102
|
return () => observer.disconnect();
|
|
74
103
|
}, [ref, enabled, collapsed]);
|
|
75
104
|
return enabled && collapsed;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { revealKeyboardFocus } from "../../lib/focus-reveal.js";
|
|
3
4
|
import * as React from "react";
|
|
4
5
|
import { ChevronLeft, ChevronRight, MoreHorizontal } from "lucide-react";
|
|
5
6
|
import { useTranslation } from "../../i18n/use-translation.js";
|
|
@@ -33,6 +34,7 @@ const PaginationContent = React.forwardRef(({ className, ...props }, ref) => {
|
|
|
33
34
|
"ul",
|
|
34
35
|
{
|
|
35
36
|
ref: setListElement,
|
|
37
|
+
onFocusCapture: revealKeyboardFocus,
|
|
36
38
|
className: cn("ui-pagination-list", className),
|
|
37
39
|
role: "list",
|
|
38
40
|
...props
|
|
@@ -186,6 +188,7 @@ function Pagination({
|
|
|
186
188
|
return /* @__PURE__ */ jsxs(
|
|
187
189
|
"nav",
|
|
188
190
|
{
|
|
191
|
+
onFocusCapture: revealKeyboardFocus,
|
|
189
192
|
"aria-label": navLabel,
|
|
190
193
|
"data-simple": "true",
|
|
191
194
|
"data-size": size,
|
|
@@ -230,6 +233,7 @@ function Pagination({
|
|
|
230
233
|
return /* @__PURE__ */ jsxs(
|
|
231
234
|
"nav",
|
|
232
235
|
{
|
|
236
|
+
onFocusCapture: revealKeyboardFocus,
|
|
233
237
|
"aria-label": navLabel,
|
|
234
238
|
"data-size": size,
|
|
235
239
|
"data-align": align,
|
|
@@ -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": "33.
|
|
3
|
+
"version": "33.12.1",
|
|
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,
|
package/dist/lab/anchor.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { revealKeyboardFocus } from "../lib/focus-reveal.js";
|
|
3
4
|
import * as React from "react";
|
|
4
5
|
import { useTranslation } from "../i18n/use-translation.js";
|
|
5
6
|
import { isDevelopment } from "../lib/dev.js";
|
|
@@ -264,7 +265,16 @@ function Anchor({
|
|
|
264
265
|
} : void 0
|
|
265
266
|
}
|
|
266
267
|
),
|
|
267
|
-
/* @__PURE__ */ jsx(
|
|
268
|
+
/* @__PURE__ */ jsx(
|
|
269
|
+
"ul",
|
|
270
|
+
{
|
|
271
|
+
onFocusCapture: revealKeyboardFocus,
|
|
272
|
+
ref: listRef,
|
|
273
|
+
"data-slot": "anchor-list",
|
|
274
|
+
className: "ui-anchor-list",
|
|
275
|
+
children: renderItems(items ?? [], false)
|
|
276
|
+
}
|
|
277
|
+
)
|
|
268
278
|
] })
|
|
269
279
|
}
|
|
270
280
|
);
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { FocusEvent } from "react";
|
|
2
|
+
/** Native Tab scrolling can leave a partially visible control clipped (Chromium).
|
|
3
|
+
* Reveal keyboard targets that fit inside a scroll viewport, without moving oversized
|
|
4
|
+
* rows, changing layout, or scrolling on pointer focus. */
|
|
5
|
+
export declare function revealKeyboardFocus(event: FocusEvent<HTMLElement>): void;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
function revealKeyboardFocus(event) {
|
|
2
|
+
const viewport = event.currentTarget;
|
|
3
|
+
const target = event.target;
|
|
4
|
+
if (!(target instanceof HTMLElement) || target === viewport || !viewport.contains(target) || !target.matches(":focus-visible"))
|
|
5
|
+
return;
|
|
6
|
+
const carrier = target.closest(".ui-tag-input,.ui-control-composite-field") ?? target;
|
|
7
|
+
const box = carrier.getBoundingClientRect();
|
|
8
|
+
const frame = viewport.getBoundingClientRect();
|
|
9
|
+
const left = frame.left + viewport.clientLeft;
|
|
10
|
+
const top = frame.top + viewport.clientTop;
|
|
11
|
+
const style = getComputedStyle(viewport);
|
|
12
|
+
const outsideX = /auto|scroll/.test(style.overflowX) && box.width <= viewport.clientWidth && (box.left < left || box.right > left + viewport.clientWidth);
|
|
13
|
+
const outsideY = /auto|scroll/.test(style.overflowY) && box.height <= viewport.clientHeight && (box.top < top || box.bottom > top + viewport.clientHeight);
|
|
14
|
+
if (outsideX || outsideY)
|
|
15
|
+
carrier.scrollIntoView?.({ block: "nearest", inline: "nearest", behavior: "instant" });
|
|
16
|
+
}
|
|
17
|
+
export {
|
|
18
|
+
revealKeyboardFocus
|
|
19
|
+
};
|
package/dist/lib/hooks.js
CHANGED
|
@@ -77,9 +77,12 @@ function useScrollableRegionTabIndex(element) {
|
|
|
77
77
|
const sync = () => {
|
|
78
78
|
const scrolls = element.scrollHeight > element.clientHeight || element.scrollWidth > element.clientWidth;
|
|
79
79
|
const hasFocusableContent = element.querySelector(SCROLLABLE_REGION_FOCUSABLE_SELECTOR) !== null;
|
|
80
|
-
|
|
80
|
+
const hasVisibleBox = element.clientWidth > 0 && element.clientHeight > 0;
|
|
81
|
+
if (!hasVisibleBox) {
|
|
82
|
+
if (element.getAttribute("tabindex") !== "-1") element.setAttribute("tabindex", "-1");
|
|
83
|
+
} else if (scrolls && !hasFocusableContent) {
|
|
81
84
|
if (element.getAttribute("tabindex") !== "0") element.setAttribute("tabindex", "0");
|
|
82
|
-
} else if (element.getAttribute("tabindex")
|
|
85
|
+
} else if (["0", "-1"].includes(element.getAttribute("tabindex") ?? "")) {
|
|
83
86
|
element.removeAttribute("tabindex");
|
|
84
87
|
}
|
|
85
88
|
};
|
|
@@ -1545,6 +1545,14 @@ export type TopbarProp = Omit<React.HTMLAttributes<HTMLDivElement>, "children">
|
|
|
1545
1545
|
center?: ReactNode;
|
|
1546
1546
|
/** Inline-end cluster — settings pickers, notifications, the user menu. */
|
|
1547
1547
|
end?: ReactNode;
|
|
1548
|
+
/**
|
|
1549
|
+
* Opt-in shared-device identity, pinned outside scrolling/overflow menus. Pass one
|
|
1550
|
+
* TopbarItem with `truncate` and an Avatar in `icon`; use a plain string name so its full
|
|
1551
|
+
* title is automatic. Never combine with hideBelow/labelHideBelow/iconHideFrom.
|
|
1552
|
+
* Capped by --topbar-identity-max-inline-size (40%); primary controls retain their floors.
|
|
1553
|
+
* At extreme widths only the other clusters scroll or move to the menu. Ignored with children.
|
|
1554
|
+
*/
|
|
1555
|
+
identity?: ReactNode;
|
|
1548
1556
|
/**
|
|
1549
1557
|
* What a bar that does not fit does with the cells that do not fit (gh#728).
|
|
1550
1558
|
*
|
|
@@ -1643,6 +1651,11 @@ export type TopbarItemProp = Omit<React.ButtonHTMLAttributes<HTMLButtonElement>,
|
|
|
1643
1651
|
* accessible name. Under `asChild` the child element's own children are the label.
|
|
1644
1652
|
*/
|
|
1645
1653
|
labelHideBelow?: BreakpointProp;
|
|
1654
|
+
/** Ellipse the label in the available width, keeping the icon and control minimum.
|
|
1655
|
+
* Same boolean vocabulary as Text.truncate. Overrides labelHideBelow; the complete text
|
|
1656
|
+
* remains the accessible name. String children automatically supply title (asChild too).
|
|
1657
|
+
*/
|
|
1658
|
+
truncate?: boolean;
|
|
1646
1659
|
/**
|
|
1647
1660
|
* Unread count OVERLAID on the cell's glyph — the notification-bell affordance the cell's own use
|
|
1648
1661
|
* cases name (gh#398). Pass the CONTENT ONLY, exactly like `SidebarItemProp.badge`: a number, a
|
package/dist/props/registry.d.ts
CHANGED
|
@@ -1433,7 +1433,11 @@ export declare const COMPONENT_PROP_REGISTRY: {
|
|
|
1433
1433
|
readonly TopbarProp: {
|
|
1434
1434
|
readonly group: "layout";
|
|
1435
1435
|
readonly file: "components/layout.prop.ts";
|
|
1436
|
-
readonly vocabulary: readonly [
|
|
1436
|
+
readonly vocabulary: readonly [{
|
|
1437
|
+
readonly field: "identity";
|
|
1438
|
+
readonly local: true;
|
|
1439
|
+
readonly reason: "Reserved shared-device account slot; bounded and outside the overflow policy.";
|
|
1440
|
+
}, "ChildrenProp", {
|
|
1437
1441
|
readonly field: "overflow";
|
|
1438
1442
|
readonly local: true;
|
|
1439
1443
|
readonly reason: "The bar's overflow contract — `scroll` (default) keeps every cell reachable, `clip` is the pre-gh#728 slicing.";
|
|
@@ -1443,6 +1447,10 @@ export declare const COMPONENT_PROP_REGISTRY: {
|
|
|
1443
1447
|
readonly group: "layout";
|
|
1444
1448
|
readonly file: "components/layout.prop.ts";
|
|
1445
1449
|
readonly vocabulary: readonly ["ChildrenProp", "ClassNameProp", {
|
|
1450
|
+
readonly field: "truncate";
|
|
1451
|
+
readonly local: true;
|
|
1452
|
+
readonly reason: "Text.truncate boolean vocabulary applied to the bar cell label.";
|
|
1453
|
+
}, {
|
|
1446
1454
|
readonly field: "asChild";
|
|
1447
1455
|
readonly local: true;
|
|
1448
1456
|
readonly reason: "Radix Slot passthrough — merges onto the child";
|
package/dist/props/registry.js
CHANGED
|
@@ -1551,6 +1551,11 @@ const COMPONENT_PROP_REGISTRY = {
|
|
|
1551
1551
|
group: "layout",
|
|
1552
1552
|
file: "components/layout.prop.ts",
|
|
1553
1553
|
vocabulary: [
|
|
1554
|
+
{
|
|
1555
|
+
field: "identity",
|
|
1556
|
+
local: true,
|
|
1557
|
+
reason: "Reserved shared-device account slot; bounded and outside the overflow policy."
|
|
1558
|
+
},
|
|
1554
1559
|
"ChildrenProp",
|
|
1555
1560
|
{
|
|
1556
1561
|
field: "overflow",
|
|
@@ -1565,6 +1570,11 @@ const COMPONENT_PROP_REGISTRY = {
|
|
|
1565
1570
|
vocabulary: [
|
|
1566
1571
|
"ChildrenProp",
|
|
1567
1572
|
"ClassNameProp",
|
|
1573
|
+
{
|
|
1574
|
+
field: "truncate",
|
|
1575
|
+
local: true,
|
|
1576
|
+
reason: "Text.truncate boolean vocabulary applied to the bar cell label."
|
|
1577
|
+
},
|
|
1568
1578
|
{ field: "asChild", local: true, reason: "Radix Slot passthrough \u2014 merges onto the child" },
|
|
1569
1579
|
"BreakpointProp",
|
|
1570
1580
|
{
|
package/dist/styles/control.css
CHANGED
|
@@ -1232,7 +1232,10 @@
|
|
|
1232
1232
|
|
|
1233
1233
|
.ui-search-input-control {
|
|
1234
1234
|
padding-inline-start: var(--search-input-start-padding);
|
|
1235
|
-
padding-inline-end:
|
|
1235
|
+
padding-inline-end: max(
|
|
1236
|
+
var(--search-input-end-padding),
|
|
1237
|
+
var(--search-input-affix-min-padding, 0px)
|
|
1238
|
+
);
|
|
1236
1239
|
}
|
|
1237
1240
|
|
|
1238
1241
|
.ui-search-input-clear {
|
|
@@ -1263,8 +1266,8 @@
|
|
|
1263
1266
|
.ui-search-input-clear::after {
|
|
1264
1267
|
content: "";
|
|
1265
1268
|
position: absolute;
|
|
1266
|
-
inset-block: min(0px, calc((100% - var(--control-
|
|
1267
|
-
inset-inline: min(0px, calc((100% - var(--control-
|
|
1269
|
+
inset-block: min(0px, calc((100% - var(--control-affix-touch-target-size)) / 2));
|
|
1270
|
+
inset-inline: min(0px, calc((100% - var(--control-affix-touch-target-size)) / 2));
|
|
1268
1271
|
}
|
|
1269
1272
|
}
|
|
1270
1273
|
|
|
@@ -3767,3 +3770,128 @@
|
|
|
3767
3770
|
min-inline-size: var(--control-height-touch);
|
|
3768
3771
|
}
|
|
3769
3772
|
}
|
|
3773
|
+
|
|
3774
|
+
@layer components {
|
|
3775
|
+
@media (pointer: coarse) {
|
|
3776
|
+
.ui-control-inline-affix-action:not(.ui-badge-remove),
|
|
3777
|
+
.ui-control-affix-action,
|
|
3778
|
+
.ui-tree-select-clear,
|
|
3779
|
+
.ui-password-input-toggle,
|
|
3780
|
+
.ui-search-input-clear,
|
|
3781
|
+
.ui-number-input-step {
|
|
3782
|
+
min-inline-size: var(--control-affix-touch-target-size);
|
|
3783
|
+
min-block-size: var(--control-affix-touch-target-size);
|
|
3784
|
+
flex-shrink: 0;
|
|
3785
|
+
}
|
|
3786
|
+
|
|
3787
|
+
.ui-control-inline-affix-action:not(.ui-badge-remove)::after {
|
|
3788
|
+
inset: 0;
|
|
3789
|
+
translate: none;
|
|
3790
|
+
}
|
|
3791
|
+
|
|
3792
|
+
.ui-input-affix-wrapper:has(.ui-control-inline-affix-action) > .ui-input {
|
|
3793
|
+
min-block-size: var(--control-affix-touch-target-size);
|
|
3794
|
+
}
|
|
3795
|
+
|
|
3796
|
+
.ui-input--trailing-affix {
|
|
3797
|
+
padding-inline-end: max(
|
|
3798
|
+
var(--control-inline-affix-space-inline-end),
|
|
3799
|
+
calc(
|
|
3800
|
+
var(--input-trailing-measured-size, var(--control-affix-touch-target-size)) +
|
|
3801
|
+
var(--control-inline-affix-inset-inline) + var(--control-inline-affix-space-gap)
|
|
3802
|
+
)
|
|
3803
|
+
);
|
|
3804
|
+
}
|
|
3805
|
+
|
|
3806
|
+
.ui-control-trigger-affixed {
|
|
3807
|
+
min-block-size: var(--control-affix-touch-target-size);
|
|
3808
|
+
padding-inline-end: max(
|
|
3809
|
+
var(--control-trigger-space-inline-end),
|
|
3810
|
+
calc(
|
|
3811
|
+
var(--control-affix-touch-target-size) + var(--control-affix-inset-inline-end) +
|
|
3812
|
+
var(--control-inline-affix-space-gap)
|
|
3813
|
+
)
|
|
3814
|
+
);
|
|
3815
|
+
}
|
|
3816
|
+
|
|
3817
|
+
.ui-tree-select-trigger-affixed {
|
|
3818
|
+
min-block-size: var(--control-affix-touch-target-size);
|
|
3819
|
+
padding-inline-end: calc(
|
|
3820
|
+
var(--control-affix-touch-target-size) + var(--space-3) +
|
|
3821
|
+
var(--control-inline-affix-space-gap)
|
|
3822
|
+
);
|
|
3823
|
+
}
|
|
3824
|
+
|
|
3825
|
+
.ui-password-input-field {
|
|
3826
|
+
min-block-size: var(--control-affix-touch-target-size);
|
|
3827
|
+
padding-inline-end: calc(
|
|
3828
|
+
var(--control-affix-touch-target-size) + var(--control-inline-affix-space-gap)
|
|
3829
|
+
);
|
|
3830
|
+
}
|
|
3831
|
+
|
|
3832
|
+
.ui-number-input-steppers {
|
|
3833
|
+
flex-direction: row;
|
|
3834
|
+
align-items: center;
|
|
3835
|
+
inset-block: var(--control-border-width, var(--stroke-hairline));
|
|
3836
|
+
}
|
|
3837
|
+
|
|
3838
|
+
.ui-number-input-step {
|
|
3839
|
+
border: 0;
|
|
3840
|
+
background: transparent;
|
|
3841
|
+
box-shadow: none;
|
|
3842
|
+
}
|
|
3843
|
+
.ui-number-input-step:hover {
|
|
3844
|
+
background: hsl(var(--accent));
|
|
3845
|
+
color: hsl(var(--accent-foreground));
|
|
3846
|
+
}
|
|
3847
|
+
.ui-number-input-step::after {
|
|
3848
|
+
inset-block: calc((100% - var(--control-affix-touch-target-size)) / 2) auto;
|
|
3849
|
+
inset-inline: calc((100% - var(--control-affix-touch-target-size)) / 2) auto;
|
|
3850
|
+
inline-size: var(--control-affix-touch-target-size);
|
|
3851
|
+
block-size: var(--control-affix-touch-target-size);
|
|
3852
|
+
translate: none;
|
|
3853
|
+
}
|
|
3854
|
+
.ui-search-input-control {
|
|
3855
|
+
min-block-size: var(--control-affix-touch-target-size);
|
|
3856
|
+
|
|
3857
|
+
--search-input-affix-min-padding: max(
|
|
3858
|
+
var(--control-affix-touch-target-size),
|
|
3859
|
+
calc(
|
|
3860
|
+
var(--search-input-edge-inset) + var(--touch-target-min) / 2 +
|
|
3861
|
+
var(--control-affix-touch-target-size) / 2
|
|
3862
|
+
)
|
|
3863
|
+
);
|
|
3864
|
+
}
|
|
3865
|
+
[data-slot="textarea-affix-wrapper"]:has(.ui-textarea-clear) > textarea {
|
|
3866
|
+
min-block-size: calc(
|
|
3867
|
+
var(--control-affix-touch-target-size) + 2 * var(--textarea-clear-inset-block-start)
|
|
3868
|
+
);
|
|
3869
|
+
}
|
|
3870
|
+
.ui-search-input-clear {
|
|
3871
|
+
inset-inline-end: max(
|
|
3872
|
+
0px,
|
|
3873
|
+
calc(
|
|
3874
|
+
var(--search-input-edge-inset) + var(--touch-target-min) / 2 -
|
|
3875
|
+
var(--control-affix-touch-target-size) / 2
|
|
3876
|
+
)
|
|
3877
|
+
);
|
|
3878
|
+
}
|
|
3879
|
+
.ui-number-input-field {
|
|
3880
|
+
min-block-size: calc(
|
|
3881
|
+
var(--control-affix-touch-target-size) + 2 *
|
|
3882
|
+
var(--control-border-width, var(--stroke-hairline))
|
|
3883
|
+
);
|
|
3884
|
+
padding-inline-end: calc(2 * var(--control-affix-touch-target-size) + var(--space-2));
|
|
3885
|
+
}
|
|
3886
|
+
.ui-number-input:not([data-controls="off"]) [data-slot="number-input-suffix"] {
|
|
3887
|
+
inset-inline-end: calc(2 * var(--control-affix-touch-target-size) + var(--space-2));
|
|
3888
|
+
}
|
|
3889
|
+
.ui-number-input:not([data-controls="off"]):has([data-slot="number-input-suffix"])
|
|
3890
|
+
.ui-number-input-field {
|
|
3891
|
+
padding-inline-end: calc(
|
|
3892
|
+
2 * var(--control-affix-touch-target-size) + var(--space-2) +
|
|
3893
|
+
var(--control-inline-affix-size)
|
|
3894
|
+
);
|
|
3895
|
+
}
|
|
3896
|
+
}
|
|
3897
|
+
}
|
|
@@ -4,6 +4,34 @@
|
|
|
4
4
|
:is(
|
|
5
5
|
.ui-focus-ring,
|
|
6
6
|
.ui-focus-ring-outline,
|
|
7
|
+
.ui-flex,
|
|
8
|
+
.ui-table-scroll,
|
|
9
|
+
.ui-pagination-list,
|
|
10
|
+
.react-aria-Menu,
|
|
11
|
+
.ui-chart [tabindex],
|
|
12
|
+
.ui-prose input,
|
|
13
|
+
.ui-auth-legal-footer a[href],
|
|
14
|
+
.ui-auth-shell a[href],
|
|
15
|
+
.app-main a[href],
|
|
16
|
+
.ui-breadcrumb a[href],
|
|
17
|
+
.ui-breadcrumb-link,
|
|
18
|
+
.ui-password-input-toggle,
|
|
19
|
+
.ui-search-select-value-remove,
|
|
20
|
+
.ui-tabs-overflow,
|
|
21
|
+
.ui-resizable-handle,
|
|
22
|
+
.ui-scroll-area,
|
|
23
|
+
.ui-data-table-scroll,
|
|
24
|
+
.ui-resizable-panel,
|
|
25
|
+
.ui-master-detail-master,
|
|
26
|
+
.ui-branch-scope-picker-list,
|
|
27
|
+
.ui-tag-input-chip,
|
|
28
|
+
.ui-attachments-placeholder,
|
|
29
|
+
.ui-block-editor-content,
|
|
30
|
+
.ui-range-timeline,
|
|
31
|
+
.sb-product,
|
|
32
|
+
.ui-logo,
|
|
33
|
+
.ui-logo-lockup,
|
|
34
|
+
[data-slot="anchor-link"],
|
|
7
35
|
[data-interactive] > [data-slot="table-cell"] a[href],
|
|
8
36
|
[data-interactive] > [data-slot="table-cell"] button,
|
|
9
37
|
.ui-data-table-ellipsis[data-truncated],
|
|
@@ -51,6 +79,8 @@
|
|
|
51
79
|
.tb-icon-btn
|
|
52
80
|
):focus-visible,
|
|
53
81
|
|
|
82
|
+
.ui-command-input-wrapper:has(.ui-command-input:focus-visible),
|
|
83
|
+
.ui-attachments:has(.ui-attachments-input:focus-visible),
|
|
54
84
|
.ui-calendar-dropdown-root:has(.ui-calendar-dropdown:focus-visible),
|
|
55
85
|
.ui-checkbox[data-focus-visible],
|
|
56
86
|
.ui-radio[data-focus-visible],
|
|
@@ -70,17 +100,20 @@
|
|
|
70
100
|
var(--focus-outline-color, var(--focus-ring-color, var(--ring))) /
|
|
71
101
|
var(--focus-ring-opacity, 1)
|
|
72
102
|
);
|
|
73
|
-
outline-offset: var(--focus-ring-offset);
|
|
103
|
+
outline-offset: var(--focus-ring-contained-offset, var(--focus-ring-offset));
|
|
74
104
|
|
|
75
105
|
transition:
|
|
76
106
|
outline-offset 0s,
|
|
77
107
|
outline 0s;
|
|
78
108
|
}
|
|
79
109
|
|
|
80
|
-
:root[data-focus-outline="
|
|
110
|
+
:root:not([data-focus-outline="off"])
|
|
81
111
|
:is(
|
|
82
112
|
.ui-focus-ring,
|
|
83
113
|
.ui-focus-ring-outline,
|
|
114
|
+
.ui-logo,
|
|
115
|
+
.ui-logo-lockup,
|
|
116
|
+
[data-slot="anchor-link"],
|
|
84
117
|
.ui-input,
|
|
85
118
|
.ui-control,
|
|
86
119
|
.ui-control-multiline,
|
|
@@ -123,21 +156,22 @@
|
|
|
123
156
|
.tb-icon-btn
|
|
124
157
|
):focus-visible,
|
|
125
158
|
|
|
126
|
-
:root[data-focus-outline="
|
|
127
|
-
:root[data-focus-outline="
|
|
128
|
-
:root[data-focus-outline="
|
|
129
|
-
:root[data-focus-outline="
|
|
130
|
-
:root[data-focus-outline="
|
|
131
|
-
:root[data-focus-outline="
|
|
132
|
-
:root[data-focus-outline="
|
|
133
|
-
:root[data-focus-outline="
|
|
134
|
-
:root[data-focus-outline="
|
|
135
|
-
:root[data-focus-outline="
|
|
136
|
-
:root[data-focus-outline="
|
|
159
|
+
:root:not([data-focus-outline="off"]) .ui-checkbox[data-focus-visible],
|
|
160
|
+
:root:not([data-focus-outline="off"]) .ui-radio[data-focus-visible],
|
|
161
|
+
:root:not([data-focus-outline="off"]) .ui-switch[data-focus-visible],
|
|
162
|
+
:root:not([data-focus-outline="off"]) .ui-slider-thumb[data-focus-visible],
|
|
163
|
+
:root:not([data-focus-outline="off"]) .ui-focus-ring[data-focus-visible],
|
|
164
|
+
:root:not([data-focus-outline="off"]) .ui-control-trigger[data-state="open"],
|
|
165
|
+
:root:not([data-focus-outline="off"]) .ui-tag-input:focus-within,
|
|
166
|
+
:root:not([data-focus-outline="off"]) .ui-control-composite-field:focus-within,
|
|
167
|
+
:root:not([data-focus-outline="off"]) .ui-control-composite-field[data-state="open"],
|
|
168
|
+
:root:not([data-focus-outline="off"]) .ui-otp-slot[data-active="true"],
|
|
169
|
+
:root:not([data-focus-outline="off"])
|
|
137
170
|
.ui-otp-group[data-appearance="grouped"]:has(.ui-otp-slot[data-active="true"]) {
|
|
138
171
|
|
|
139
172
|
--tw-ring-shadow: var(
|
|
140
173
|
--focus-field-shadow,
|
|
174
|
+
inset 0 0 0 calc(-1 * var(--focus-ring-contained-offset, 0px)) hsl(var(--background)),
|
|
141
175
|
0 0 0 var(--focus-ring-glow-width)
|
|
142
176
|
hsl(
|
|
143
177
|
var(
|
|
@@ -149,6 +183,7 @@
|
|
|
149
183
|
);
|
|
150
184
|
box-shadow: var(
|
|
151
185
|
--focus-field-shadow,
|
|
186
|
+
inset 0 0 0 calc(-1 * var(--focus-ring-contained-offset, 0px)) hsl(var(--background)),
|
|
152
187
|
0 0 0 var(--focus-ring-glow-width)
|
|
153
188
|
hsl(
|
|
154
189
|
var(
|
|
@@ -160,7 +195,7 @@
|
|
|
160
195
|
);
|
|
161
196
|
}
|
|
162
197
|
|
|
163
|
-
:root[data-focus-outline="
|
|
198
|
+
:root:not([data-focus-outline="off"])
|
|
164
199
|
:is(
|
|
165
200
|
.ui-input,
|
|
166
201
|
.ui-control,
|
|
@@ -168,10 +203,10 @@
|
|
|
168
203
|
.ui-control-trigger,
|
|
169
204
|
.ui-tag-input
|
|
170
205
|
):focus-visible,
|
|
171
|
-
:root[data-focus-outline="
|
|
172
|
-
:root[data-focus-outline="
|
|
173
|
-
:root[data-focus-outline="
|
|
174
|
-
:root[data-focus-outline="
|
|
206
|
+
:root:not([data-focus-outline="off"]) .ui-control-trigger[data-state="open"],
|
|
207
|
+
:root:not([data-focus-outline="off"]) .ui-tag-input:focus-within,
|
|
208
|
+
:root:not([data-focus-outline="off"]) .ui-control-composite-field:focus-within,
|
|
209
|
+
:root:not([data-focus-outline="off"]) .ui-control-composite-field[data-state="open"] {
|
|
175
210
|
--input: var(--focus-ring-color, var(--ring));
|
|
176
211
|
}
|
|
177
212
|
|
|
@@ -191,10 +226,35 @@
|
|
|
191
226
|
|
|
192
227
|
a.ui-list-row,
|
|
193
228
|
tr.ui-focus-ring,
|
|
194
|
-
.sb-nav-item
|
|
229
|
+
.sb-nav-item,
|
|
230
|
+
.ui-app-setting-picker-icon[data-appearance="bar"],
|
|
231
|
+
.ui-legal-document-toc-link,
|
|
232
|
+
[data-slot="anchor-link"] {
|
|
195
233
|
--focus-ring-offset: calc(-1 * var(--focus-ring-width));
|
|
196
234
|
}
|
|
197
235
|
|
|
236
|
+
:is(
|
|
237
|
+
.ui-pagination,
|
|
238
|
+
.ui-pagination-list,
|
|
239
|
+
[data-slot="card"],
|
|
240
|
+
[data-slot="tabs-list"],
|
|
241
|
+
.ui-topbar,
|
|
242
|
+
.app-topbar,
|
|
243
|
+
.ui-anchor-list,
|
|
244
|
+
.app-main,
|
|
245
|
+
.ui-data-table-scroll,
|
|
246
|
+
.ui-scroll-area,
|
|
247
|
+
.ui-table-scroll,
|
|
248
|
+
.ui-mobile-shell,
|
|
249
|
+
.ui-resizable-panel-group,
|
|
250
|
+
.ui-legal-document-rail,
|
|
251
|
+
.ui-command-input-wrapper,
|
|
252
|
+
.ui-attachments
|
|
253
|
+
) {
|
|
254
|
+
--focus-ring-contained-offset: var(--focus-ring-inset-offset);
|
|
255
|
+
|
|
256
|
+
}
|
|
257
|
+
|
|
198
258
|
.ui-accordion-trigger {
|
|
199
259
|
--focus-ring-offset: var(--accordion-focus-ring-offset);
|
|
200
260
|
}
|
package/dist/styles/layers.json
CHANGED
package/dist/styles/layout.css
CHANGED
|
@@ -647,7 +647,7 @@
|
|
|
647
647
|
}
|
|
648
648
|
|
|
649
649
|
.ui-resizable-handle {
|
|
650
|
-
|
|
650
|
+
inline-size: var(--resizable-handle-size);
|
|
651
651
|
background: hsl(var(--border));
|
|
652
652
|
position: relative;
|
|
653
653
|
flex-shrink: 0;
|
|
@@ -657,9 +657,9 @@
|
|
|
657
657
|
color: hsl(var(--muted-foreground));
|
|
658
658
|
}
|
|
659
659
|
|
|
660
|
-
.ui-resizable-handle[aria-orientation="
|
|
661
|
-
|
|
662
|
-
|
|
660
|
+
.ui-resizable-handle[aria-orientation="horizontal"] {
|
|
661
|
+
inline-size: auto;
|
|
662
|
+
block-size: var(--resizable-handle-size);
|
|
663
663
|
}
|
|
664
664
|
|
|
665
665
|
.ui-resizable-handle:hover,
|