@godxjp/ui 18.15.3 → 19.0.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/app/date-format-labels.d.ts +1 -1
- package/dist/app/time-format-labels.d.ts +1 -1
- package/dist/components/data-display/badge.d.ts +1 -1
- package/dist/components/data-display/card.d.ts +4 -13
- package/dist/components/data-display/card.js +2 -15
- package/dist/components/data-display/data-table.d.ts +3 -8
- package/dist/components/data-display/data-table.js +106 -68
- package/dist/components/data-display/descriptions.js +34 -5
- package/dist/components/data-display/empty-state.js +1 -1
- package/dist/components/data-display/permission-matrix.js +7 -7
- package/dist/components/data-display/popover.js +2 -9
- package/dist/components/data-display/qr-code.d.ts +1 -1
- package/dist/components/data-display/scroll-area.d.ts +3 -1
- package/dist/components/data-display/scroll-area.js +150 -16
- package/dist/components/data-display/table.js +12 -3
- package/dist/components/data-entry/branch-scope-picker.js +4 -4
- package/dist/components/data-entry/calendar.js +15 -24
- package/dist/components/data-entry/cascader.js +67 -71
- package/dist/components/data-entry/checkbox.js +9 -1
- package/dist/components/data-entry/command.d.ts +6 -6
- package/dist/components/data-entry/date-picker.js +28 -15
- package/dist/components/data-entry/date-range-picker.js +10 -10
- package/dist/components/data-entry/form-field.js +7 -3
- package/dist/components/data-entry/index.d.ts +2 -1
- package/dist/components/data-entry/input.js +8 -19
- package/dist/components/data-entry/label.js +4 -2
- package/dist/components/data-entry/month-picker.js +16 -15
- package/dist/components/data-entry/month-range-picker.js +17 -16
- package/dist/components/data-entry/radio.js +6 -1
- package/dist/components/data-entry/search-select.js +29 -29
- package/dist/components/data-entry/select.js +15 -18
- package/dist/components/data-entry/switch.js +7 -1
- package/dist/components/data-entry/textarea.d.ts +56 -0
- package/dist/components/data-entry/textarea.js +103 -40
- package/dist/components/data-entry/time-picker.js +52 -52
- package/dist/components/data-entry/toggle-group.d.ts +1 -0
- package/dist/components/data-entry/toggle.d.ts +1 -1
- package/dist/components/data-entry/transfer.js +14 -15
- package/dist/components/data-entry/tree-select.js +16 -22
- package/dist/components/data-entry/upload-crop-dialog.js +4 -4
- package/dist/components/data-entry/upload.d.ts +1 -1
- package/dist/components/data-entry/upload.js +46 -46
- package/dist/components/feedback/alert.js +7 -14
- package/dist/components/feedback/dialog.d.ts +23 -32
- package/dist/components/feedback/dialog.js +16 -13
- package/dist/components/feedback/sheet.d.ts +1 -1
- package/dist/components/feedback/sheet.js +14 -14
- package/dist/components/feedback/skeleton.js +13 -10
- package/dist/components/feedback/sonner.d.ts +1 -1
- package/dist/components/feedback/sonner.js +17 -8
- package/dist/components/feedback/tooltip.js +1 -1
- package/dist/components/general/activity.d.ts +44 -0
- package/dist/components/general/activity.js +65 -0
- package/dist/components/general/button.d.ts +2 -2
- package/dist/components/general/button.js +11 -24
- package/dist/components/general/index.d.ts +2 -0
- package/dist/components/general/index.js +2 -0
- package/dist/components/layout/app-shell.js +5 -3
- package/dist/components/layout/auth-divider.d.ts +9 -2
- package/dist/components/layout/auth-divider.js +7 -11
- package/dist/components/layout/index.d.ts +1 -0
- package/dist/components/layout/page-container.d.ts +1 -1
- package/dist/components/layout/page-container.js +32 -20
- package/dist/components/layout/resizable.d.ts +12 -12
- package/dist/components/layout/separator.d.ts +1 -0
- package/dist/components/layout/service-role-panel.js +47 -42
- package/dist/components/layout/sidebar.js +13 -1
- package/dist/components/layout/split-pane.d.ts +12 -1
- package/dist/components/layout/split-pane.js +13 -4
- package/dist/components/navigation/app-setting-picker.js +5 -14
- package/dist/components/navigation/dropdown-menu.js +10 -16
- package/dist/components/navigation/menubar.d.ts +3 -6
- package/dist/components/navigation/pagination-utils.d.ts +15 -2
- package/dist/components/navigation/pagination-utils.js +27 -21
- package/dist/components/navigation/pagination.d.ts +4 -4
- package/dist/components/navigation/pagination.js +2 -2
- package/dist/components/navigation/steps.js +31 -67
- package/dist/components/navigation/tabs.js +17 -5
- package/dist/components/query/infinite-query-state.js +2 -2
- package/dist/components/ui/accordion.d.ts +1 -1
- package/dist/components/ui/avatar.d.ts +1 -1
- package/dist/components/ui/avatar.js +29 -10
- package/dist/components/ui/input-otp.d.ts +8 -6
- package/dist/components/ui/rating.js +1 -1
- package/dist/components/ui/separator.d.ts +27 -2
- package/dist/components/ui/separator.js +42 -11
- package/dist/components/ui/toggle-group.d.ts +15 -5
- package/dist/components/ui/toggle-group.js +43 -18
- package/dist/components/ui/toggle.d.ts +66 -5
- package/dist/components/ui/toggle.js +64 -9
- package/dist/i18n/messages/en.json +8 -0
- package/dist/i18n/messages/ja.json +8 -0
- package/dist/i18n/messages/vi.json +8 -0
- package/dist/lib/control-styles.d.ts +14 -0
- package/dist/lib/control-styles.js +2 -0
- package/dist/props/components/data-display.prop.d.ts +85 -3
- package/dist/props/components/data-entry.prop.d.ts +17 -0
- package/dist/props/components/general.prop.d.ts +52 -1
- package/dist/props/components/layout.prop.d.ts +137 -2
- package/dist/props/registry.d.ts +116 -5
- package/dist/props/registry.js +165 -4
- package/dist/props/vocabulary/index.d.ts +2 -2
- package/dist/props/vocabulary/interaction.prop.d.ts +15 -0
- package/dist/props/vocabulary/layout.prop.d.ts +8 -0
- package/dist/styles/alert-layout.css +69 -3
- package/dist/styles/badge-layout.css +2 -2
- package/dist/styles/base.css +6 -0
- package/dist/styles/card-layout.css +27 -7
- package/dist/styles/control.css +1150 -29
- package/dist/styles/data-display-layout.css +185 -11
- package/dist/styles/data-entry-layout.css +352 -1
- package/dist/styles/density.css +2 -2
- package/dist/styles/dialog-layout.css +203 -4
- package/dist/styles/focus-ring.css +155 -0
- package/dist/styles/form-layout.css +50 -5
- package/dist/styles/index.css +1 -0
- package/dist/styles/layout.css +412 -23
- package/dist/styles/motion.css +178 -0
- package/dist/styles/navigation-layout.css +398 -22
- package/dist/styles/shell-layout.css +137 -39
- package/dist/styles/table-layout.css +153 -22
- package/dist/styles/toggle.css +59 -0
- package/dist/tokens/base.css +5 -0
- package/dist/tokens/components/activity.css +64 -0
- package/dist/tokens/components/badge.css +7 -0
- package/dist/tokens/components/card.css +14 -10
- package/dist/tokens/components/chart.css +1 -1
- package/dist/tokens/components/control.css +358 -8
- package/dist/tokens/components/data-display.css +75 -0
- package/dist/tokens/components/data-entry.css +25 -0
- package/dist/tokens/components/descriptions.css +22 -0
- package/dist/tokens/components/feedback.css +143 -4
- package/dist/tokens/components/form.css +16 -0
- package/dist/tokens/components/legal-document.css +5 -1
- package/dist/tokens/components/navigation.css +109 -0
- package/dist/tokens/components/scroll-area.css +21 -0
- package/dist/tokens/components/separator.css +52 -0
- package/dist/tokens/components/shell.css +132 -20
- package/dist/tokens/components/table.css +52 -3
- package/dist/tokens/components/toggle.css +82 -0
- package/dist/tokens/components/upload.css +107 -0
- package/dist/tokens/foundation.css +171 -10
- package/dist/tokens/semantic/layout.css +120 -1
- package/package.json +84 -68
- package/scripts/ui-audit.mjs +51 -2
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
3
3
|
import * as React from "react";
|
|
4
|
-
import { CalendarIcon } from "lucide-react";
|
|
4
|
+
import { CalendarIcon, X } from "lucide-react";
|
|
5
5
|
import { usePickerLocales, useTranslation } from "../../i18n/use-translation.js";
|
|
6
6
|
import { parseDateInput, toIsoDate } from "../../lib/datetime/parse.js";
|
|
7
7
|
import { useControlledLatch } from "../../lib/hooks.js";
|
|
@@ -48,6 +48,7 @@ function DatePicker({
|
|
|
48
48
|
emit(void 0);
|
|
49
49
|
setText("");
|
|
50
50
|
};
|
|
51
|
+
const showClear = allowClear && text !== "" && !disabled;
|
|
51
52
|
const commit = (raw) => {
|
|
52
53
|
const trimmed = raw.trim();
|
|
53
54
|
if (trimmed === "") {
|
|
@@ -76,19 +77,31 @@ function DatePicker({
|
|
|
76
77
|
"aria-haspopup": "dialog",
|
|
77
78
|
"aria-controls": open ? dialogId : void 0,
|
|
78
79
|
...fieldA11y,
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
80
|
+
className: showClear ? "ui-control-inline-affix-pair-affixed" : void 0,
|
|
81
|
+
trailingIcon: /* @__PURE__ */ jsxs("span", { className: "ui-time-picker-affix", children: [
|
|
82
|
+
showClear ? /* @__PURE__ */ jsx(
|
|
83
|
+
"button",
|
|
84
|
+
{
|
|
85
|
+
type: "button",
|
|
86
|
+
tabIndex: -1,
|
|
87
|
+
"aria-label": t("common.clear") ?? "Clear",
|
|
88
|
+
onClick: clear,
|
|
89
|
+
className: "ui-control-inline-affix-action",
|
|
90
|
+
children: /* @__PURE__ */ jsx(X, { className: "ui-control-inline-affix-icon", "aria-hidden": "true" })
|
|
91
|
+
}
|
|
92
|
+
) : null,
|
|
93
|
+
/* @__PURE__ */ jsx(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsx(
|
|
94
|
+
"button",
|
|
95
|
+
{
|
|
96
|
+
type: "button",
|
|
97
|
+
disabled,
|
|
98
|
+
tabIndex: -1,
|
|
99
|
+
"aria-label": t("dataEntry.datePicker.openCalendar") ?? "Open calendar",
|
|
100
|
+
className: "ui-control-inline-affix-action",
|
|
101
|
+
children: /* @__PURE__ */ jsx(CalendarIcon, { className: "ui-control-inline-affix-icon", "aria-hidden": "true" })
|
|
102
|
+
}
|
|
103
|
+
) })
|
|
104
|
+
] }),
|
|
92
105
|
onClick: () => {
|
|
93
106
|
if (!disabled) setOpen(true);
|
|
94
107
|
},
|
|
@@ -116,7 +129,7 @@ function DatePicker({
|
|
|
116
129
|
id: dialogId,
|
|
117
130
|
role: "dialog",
|
|
118
131
|
"aria-label": t("dataEntry.datePicker.openCalendar") ?? "Calendar",
|
|
119
|
-
className: "
|
|
132
|
+
className: "ui-control-panel-flush",
|
|
120
133
|
align: "start",
|
|
121
134
|
onOpenAutoFocus: (event) => event.preventDefault(),
|
|
122
135
|
children: /* @__PURE__ */ jsx(
|
|
@@ -70,7 +70,7 @@ function DateRangePicker({
|
|
|
70
70
|
}
|
|
71
71
|
}
|
|
72
72
|
};
|
|
73
|
-
const innerInputClass = "
|
|
73
|
+
const innerInputClass = "ui-month-picker-input";
|
|
74
74
|
return /* @__PURE__ */ jsx(Popover, { open, onOpenChange: setOpen, children: /* @__PURE__ */ jsx(PopoverAnchor, { asChild: true, children: /* @__PURE__ */ jsxs(
|
|
75
75
|
"div",
|
|
76
76
|
{
|
|
@@ -79,12 +79,11 @@ function DateRangePicker({
|
|
|
79
79
|
...groupA11y,
|
|
80
80
|
"aria-disabled": disabled ? true : void 0,
|
|
81
81
|
className: cn(
|
|
82
|
-
// One input-styled shell for the whole range —
|
|
83
|
-
//
|
|
84
|
-
"ui-control
|
|
82
|
+
// One input-styled shell for the whole range — the shared composite-field box, so
|
|
83
|
+
// this and the month range picker cannot drift into two slightly different fields.
|
|
84
|
+
"ui-control ui-control-composite-field",
|
|
85
85
|
"focus-within:border-ring focus-within:ring-ring/50 focus-within:ring-[3px]",
|
|
86
86
|
open && "border-ring ring-ring/50 ring-[3px]",
|
|
87
|
-
disabled && "pointer-events-none cursor-not-allowed opacity-50",
|
|
88
87
|
className
|
|
89
88
|
),
|
|
90
89
|
onClick: () => {
|
|
@@ -114,7 +113,7 @@ function DateRangePicker({
|
|
|
114
113
|
}
|
|
115
114
|
}
|
|
116
115
|
),
|
|
117
|
-
/* @__PURE__ */ jsx(ArrowRight, { className: "
|
|
116
|
+
/* @__PURE__ */ jsx(ArrowRight, { className: "ui-month-picker-separator-icon", "aria-hidden": "true" }),
|
|
118
117
|
/* @__PURE__ */ jsx(
|
|
119
118
|
"input",
|
|
120
119
|
{
|
|
@@ -149,9 +148,10 @@ function DateRangePicker({
|
|
|
149
148
|
event.stopPropagation();
|
|
150
149
|
clear();
|
|
151
150
|
},
|
|
152
|
-
children: /* @__PURE__ */ jsx(X, { className: "
|
|
151
|
+
children: /* @__PURE__ */ jsx(X, { className: "ui-month-picker-icon", "aria-hidden": "true" })
|
|
153
152
|
}
|
|
154
|
-
) :
|
|
153
|
+
) : null,
|
|
154
|
+
/* @__PURE__ */ jsx(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsx(
|
|
155
155
|
"button",
|
|
156
156
|
{
|
|
157
157
|
type: "button",
|
|
@@ -159,13 +159,13 @@ function DateRangePicker({
|
|
|
159
159
|
tabIndex: -1,
|
|
160
160
|
"aria-label": t("dataEntry.dateRangePicker.openCalendar") ?? "Open calendar",
|
|
161
161
|
className: "text-muted-foreground hover:text-foreground shrink-0",
|
|
162
|
-
children: /* @__PURE__ */ jsx(CalendarIcon, { className: "
|
|
162
|
+
children: /* @__PURE__ */ jsx(CalendarIcon, { className: "ui-month-picker-icon", "aria-hidden": "true" })
|
|
163
163
|
}
|
|
164
164
|
) }),
|
|
165
165
|
/* @__PURE__ */ jsx(
|
|
166
166
|
PopoverContent,
|
|
167
167
|
{
|
|
168
|
-
className: "
|
|
168
|
+
className: "ui-control-panel-flush",
|
|
169
169
|
align: "start",
|
|
170
170
|
onOpenAutoFocus: (event) => event.preventDefault(),
|
|
171
171
|
children: /* @__PURE__ */ jsx(
|
|
@@ -52,8 +52,12 @@ function FormField({
|
|
|
52
52
|
const mergeIds = mergeAriaIds;
|
|
53
53
|
const childWithA11y = isStatic ? (
|
|
54
54
|
// Byte-for-byte the same value typography as `Descriptions.Item`'s `dd` (gh#294), so a
|
|
55
|
-
// read-only FormField row and a Descriptions value are indistinguishable when mixed.
|
|
56
|
-
|
|
55
|
+
// read-only FormField row and a Descriptions value are indistinguishable when mixed. That
|
|
56
|
+
// used to be two copies of the literal `text-sm` kept in sync by this comment; both call sites
|
|
57
|
+
// now read the SAME token pair (#319), so a service retunes both from one place and they
|
|
58
|
+
// cannot drift. --descriptions-value-line-height is the mandatory companion: `text-sm` also
|
|
59
|
+
// set Tailwind's `--text-sm--line-height`, which the theme never remaps (the gh#260 bug).
|
|
60
|
+
/* @__PURE__ */ jsx("span", { className: "text-[length:var(--descriptions-value-font-size)] leading-[var(--descriptions-value-line-height)] break-all", children: staticText })
|
|
57
61
|
) : React.isValidElement(children) ? React.cloneElement(children, {
|
|
58
62
|
// The label is associated via aria-labelledby (not <label for>): composite
|
|
59
63
|
// controls (Radio.Group, checkbox lists, range pairs) have no labelable root,
|
|
@@ -83,7 +87,7 @@ function FormField({
|
|
|
83
87
|
style["--form-label-width"] = toCssLength(labelWidth);
|
|
84
88
|
if (controlWidth != null)
|
|
85
89
|
style["--form-control-width"] = toCssLength(controlWidth);
|
|
86
|
-
if (colSpan != null) style
|
|
90
|
+
if (colSpan != null) style["--form-field-col-span"] = String(colSpan);
|
|
87
91
|
return /* @__PURE__ */ jsxs(
|
|
88
92
|
"div",
|
|
89
93
|
{
|
|
@@ -21,8 +21,9 @@ export { SearchInput } from "./search-input.js";
|
|
|
21
21
|
export { Switch } from "./switch.js";
|
|
22
22
|
export type { SwitchProps } from "./switch.js";
|
|
23
23
|
export { Toggle } from "./toggle.js";
|
|
24
|
-
export type { ToggleProps } from "./toggle.js";
|
|
24
|
+
export type { ToggleProp, ToggleProps } from "./toggle.js";
|
|
25
25
|
export { ToggleGroup, ToggleGroupItem } from "./toggle-group.js";
|
|
26
|
+
export type { ToggleGroupItemProp, ToggleGroupItemProps } from "./toggle-group.js";
|
|
26
27
|
export { Slider } from "./slider.js";
|
|
27
28
|
export type { SliderProps } from "./slider.js";
|
|
28
29
|
export { Calendar } from "./calendar.js";
|
|
@@ -6,12 +6,9 @@ import { useTranslation } from "../../i18n/use-translation.js";
|
|
|
6
6
|
import { useFieldNameFallback } from "../../lib/field-a11y.js";
|
|
7
7
|
import { cn } from "../../lib/utils.js";
|
|
8
8
|
const inputBaseClass = [
|
|
9
|
-
"ui-control border-input bg-background w-full
|
|
9
|
+
"ui-control ui-input border-input bg-background w-full rounded-[var(--control-radius)] transition-[color,box-shadow] outline-none",
|
|
10
10
|
"selection:bg-primary selection:text-primary-foreground",
|
|
11
|
-
"file:text-foreground file:inline-flex file:h-7 file:border-0 file:bg-transparent file:text-sm file:font-medium",
|
|
12
11
|
"placeholder:text-muted-foreground",
|
|
13
|
-
"focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px]",
|
|
14
|
-
"disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50",
|
|
15
12
|
"aria-invalid:border-destructive aria-invalid:ring-destructive/20"
|
|
16
13
|
];
|
|
17
14
|
const Input = React.forwardRef(
|
|
@@ -89,20 +86,12 @@ const Input = React.forwardRef(
|
|
|
89
86
|
tabIndex: -1,
|
|
90
87
|
"aria-label": t("common.clear") ?? "Clear",
|
|
91
88
|
onClick: clear,
|
|
92
|
-
className: "
|
|
93
|
-
children: /* @__PURE__ */ jsx(X, { className: "
|
|
89
|
+
className: "ui-control-inline-affix-action",
|
|
90
|
+
children: /* @__PURE__ */ jsx(X, { className: "ui-control-inline-affix-icon", "aria-hidden": "true" })
|
|
94
91
|
}
|
|
95
92
|
) : trailingIcon;
|
|
96
|
-
return /* @__PURE__ */ jsxs("span", { "data-slot": "input-affix-wrapper", className: "
|
|
97
|
-
leadingIcon != null ? /* @__PURE__ */ jsx(
|
|
98
|
-
"span",
|
|
99
|
-
{
|
|
100
|
-
"data-slot": "input-leading",
|
|
101
|
-
"aria-hidden": "true",
|
|
102
|
-
className: "text-muted-foreground pointer-events-none absolute inset-y-0 start-2 inline-flex items-center",
|
|
103
|
-
children: leadingIcon
|
|
104
|
-
}
|
|
105
|
-
) : null,
|
|
93
|
+
return /* @__PURE__ */ jsxs("span", { "data-slot": "input-affix-wrapper", className: "ui-input-affix-wrapper", children: [
|
|
94
|
+
leadingIcon != null ? /* @__PURE__ */ jsx("span", { "data-slot": "input-leading", "aria-hidden": "true", className: "ui-input-leading", children: leadingIcon }) : null,
|
|
106
95
|
/* @__PURE__ */ jsx(
|
|
107
96
|
"input",
|
|
108
97
|
{
|
|
@@ -114,15 +103,15 @@ const Input = React.forwardRef(
|
|
|
114
103
|
onChange: handleChange,
|
|
115
104
|
className: cn(
|
|
116
105
|
inputBaseClass,
|
|
117
|
-
leadingIcon != null && "
|
|
118
|
-
(showClear || trailingIcon != null) && "
|
|
106
|
+
leadingIcon != null && "ui-input--leading-affix",
|
|
107
|
+
(showClear || trailingIcon != null) && "ui-input--trailing-affix",
|
|
119
108
|
className
|
|
120
109
|
),
|
|
121
110
|
...props,
|
|
122
111
|
...nameFallback
|
|
123
112
|
}
|
|
124
113
|
),
|
|
125
|
-
trailing != null ? /* @__PURE__ */ jsx("span", { className: "
|
|
114
|
+
trailing != null ? /* @__PURE__ */ jsx("span", { className: "ui-input-trailing", children: trailing }) : null
|
|
126
115
|
] });
|
|
127
116
|
}
|
|
128
117
|
);
|
|
@@ -5,7 +5,7 @@ import * as LabelPrimitive from "@radix-ui/react-label";
|
|
|
5
5
|
import { cva } from "class-variance-authority";
|
|
6
6
|
import { cn } from "../../lib/utils.js";
|
|
7
7
|
const labelVariants = cva(
|
|
8
|
-
"
|
|
8
|
+
"font-medium leading-[var(--control-label-line-height)] peer-disabled:cursor-not-allowed peer-disabled:opacity-[var(--control-label-disabled-alpha)]"
|
|
9
9
|
);
|
|
10
10
|
const Label = React.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
11
11
|
LabelPrimitive.Root,
|
|
@@ -13,7 +13,9 @@ const Label = React.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */
|
|
|
13
13
|
ref,
|
|
14
14
|
"data-slot": "label",
|
|
15
15
|
className: cn(
|
|
16
|
-
|
|
16
|
+
// A label inside a disabled group reads at the SYSTEM disabled alpha (--disabled-opacity),
|
|
17
|
+
// the same one .ui-checkbox/.ui-radio/.ui-switch:disabled use — one knob, not a second one.
|
|
18
|
+
"ui-label group-data-[disabled=true]:pointer-events-none group-data-[disabled=true]:opacity-[var(--disabled-opacity)]",
|
|
17
19
|
labelVariants(),
|
|
18
20
|
className
|
|
19
21
|
),
|
|
@@ -61,11 +61,11 @@ function MonthPicker({
|
|
|
61
61
|
return /* @__PURE__ */ jsx(Popover, { open, onOpenChange: setOpen, children: /* @__PURE__ */ jsx(PopoverAnchor, { asChild: true, children: /* @__PURE__ */ jsxs(
|
|
62
62
|
"div",
|
|
63
63
|
{
|
|
64
|
+
"data-disabled": disabled ? "" : void 0,
|
|
64
65
|
className: cn(
|
|
65
|
-
"ui-control
|
|
66
|
+
"ui-control ui-control-composite-field",
|
|
66
67
|
"focus-within:border-ring focus-within:ring-ring/50 focus-within:ring-[3px]",
|
|
67
68
|
open && "border-ring ring-ring/50 ring-[3px]",
|
|
68
|
-
disabled && "pointer-events-none cursor-not-allowed opacity-50",
|
|
69
69
|
className
|
|
70
70
|
),
|
|
71
71
|
onClick: () => {
|
|
@@ -87,7 +87,7 @@ function MonthPicker({
|
|
|
87
87
|
"aria-haspopup": "dialog",
|
|
88
88
|
"aria-controls": open ? dialogId : void 0,
|
|
89
89
|
...fieldA11y,
|
|
90
|
-
className: "
|
|
90
|
+
className: "ui-month-picker-input",
|
|
91
91
|
onKeyDown: (event) => {
|
|
92
92
|
if (event.key === "ArrowDown") {
|
|
93
93
|
event.preventDefault();
|
|
@@ -117,9 +117,10 @@ function MonthPicker({
|
|
|
117
117
|
emit(void 0);
|
|
118
118
|
setText("");
|
|
119
119
|
},
|
|
120
|
-
children: /* @__PURE__ */ jsx(X, { className: "
|
|
120
|
+
children: /* @__PURE__ */ jsx(X, { className: "ui-month-picker-icon", "aria-hidden": "true" })
|
|
121
121
|
}
|
|
122
|
-
) :
|
|
122
|
+
) : null,
|
|
123
|
+
/* @__PURE__ */ jsx(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsx(
|
|
123
124
|
"button",
|
|
124
125
|
{
|
|
125
126
|
type: "button",
|
|
@@ -127,7 +128,7 @@ function MonthPicker({
|
|
|
127
128
|
tabIndex: -1,
|
|
128
129
|
"aria-label": t("dataEntry.monthPicker.openGrid") ?? "Open month grid",
|
|
129
130
|
className: "text-muted-foreground hover:text-foreground shrink-0",
|
|
130
|
-
children: /* @__PURE__ */ jsx(CalendarIcon, { className: "
|
|
131
|
+
children: /* @__PURE__ */ jsx(CalendarIcon, { className: "ui-month-picker-icon", "aria-hidden": "true" })
|
|
131
132
|
}
|
|
132
133
|
) }),
|
|
133
134
|
/* @__PURE__ */ jsxs(
|
|
@@ -136,12 +137,12 @@ function MonthPicker({
|
|
|
136
137
|
id: dialogId,
|
|
137
138
|
role: "dialog",
|
|
138
139
|
"aria-label": t("dataEntry.monthPicker.openGrid") ?? "Month grid",
|
|
139
|
-
className: "
|
|
140
|
+
className: "ui-month-picker-panel",
|
|
140
141
|
align: "start",
|
|
141
142
|
onOpenAutoFocus: (event) => event.preventDefault(),
|
|
142
143
|
onClick: (event) => event.stopPropagation(),
|
|
143
144
|
children: [
|
|
144
|
-
/* @__PURE__ */ jsxs("div", { className: "
|
|
145
|
+
/* @__PURE__ */ jsxs("div", { className: "ui-month-picker-nav", children: [
|
|
145
146
|
/* @__PURE__ */ jsx(
|
|
146
147
|
Button,
|
|
147
148
|
{
|
|
@@ -150,12 +151,12 @@ function MonthPicker({
|
|
|
150
151
|
size: "icon-sm",
|
|
151
152
|
disabled: prevDisabled,
|
|
152
153
|
"aria-label": t("dataEntry.monthPicker.previousYear") ?? "Previous year",
|
|
153
|
-
className: "
|
|
154
|
+
className: "ui-month-picker-nav-button",
|
|
154
155
|
onClick: () => setViewYear((y) => y - 1),
|
|
155
|
-
children: /* @__PURE__ */ jsx(ChevronLeft, { className: "
|
|
156
|
+
children: /* @__PURE__ */ jsx(ChevronLeft, { className: "ui-month-picker-icon", "aria-hidden": "true" })
|
|
156
157
|
}
|
|
157
158
|
),
|
|
158
|
-
/* @__PURE__ */ jsx("span", { className: "
|
|
159
|
+
/* @__PURE__ */ jsx("span", { className: "ui-month-picker-nav-label", "aria-live": "polite", children: viewYear }),
|
|
159
160
|
/* @__PURE__ */ jsx(
|
|
160
161
|
Button,
|
|
161
162
|
{
|
|
@@ -164,13 +165,13 @@ function MonthPicker({
|
|
|
164
165
|
size: "icon-sm",
|
|
165
166
|
disabled: nextDisabled,
|
|
166
167
|
"aria-label": t("dataEntry.monthPicker.nextYear") ?? "Next year",
|
|
167
|
-
className: "
|
|
168
|
+
className: "ui-month-picker-nav-button",
|
|
168
169
|
onClick: () => setViewYear((y) => y + 1),
|
|
169
|
-
children: /* @__PURE__ */ jsx(ChevronRight, { className: "
|
|
170
|
+
children: /* @__PURE__ */ jsx(ChevronRight, { className: "ui-month-picker-icon", "aria-hidden": "true" })
|
|
170
171
|
}
|
|
171
172
|
)
|
|
172
173
|
] }),
|
|
173
|
-
/* @__PURE__ */ jsx("div", { role: "grid", "aria-label": String(viewYear), className: "
|
|
174
|
+
/* @__PURE__ */ jsx("div", { role: "grid", "aria-label": String(viewYear), className: "ui-month-picker-grid", children: monthLabels.map((label, i) => {
|
|
174
175
|
const selected = value?.getFullYear() === viewYear && value?.getMonth() === i;
|
|
175
176
|
return /* @__PURE__ */ jsx(
|
|
176
177
|
Button,
|
|
@@ -179,7 +180,7 @@ function MonthPicker({
|
|
|
179
180
|
variant: selected ? "default" : "ghost",
|
|
180
181
|
size: "sm",
|
|
181
182
|
"aria-pressed": selected,
|
|
182
|
-
className: "
|
|
183
|
+
className: "ui-month-picker-cell",
|
|
183
184
|
onClick: () => {
|
|
184
185
|
emit(new Date(viewYear, i, 1));
|
|
185
186
|
setOpen(false);
|
|
@@ -99,7 +99,7 @@ function MonthRangePicker({
|
|
|
99
99
|
}
|
|
100
100
|
}
|
|
101
101
|
};
|
|
102
|
-
const innerInputClass = "
|
|
102
|
+
const innerInputClass = "ui-month-picker-input";
|
|
103
103
|
const resolvedPlaceholder = placeholder ?? t("dataEntry.monthPicker.placeholder") ?? YM_HINT;
|
|
104
104
|
return /* @__PURE__ */ jsx(Popover, { open, onOpenChange: setOpen, children: /* @__PURE__ */ jsx(PopoverAnchor, { asChild: true, children: /* @__PURE__ */ jsxs(
|
|
105
105
|
"div",
|
|
@@ -108,11 +108,11 @@ function MonthRangePicker({
|
|
|
108
108
|
id: groupId,
|
|
109
109
|
...groupA11y,
|
|
110
110
|
"aria-disabled": disabled ? true : void 0,
|
|
111
|
+
"data-disabled": disabled ? "" : void 0,
|
|
111
112
|
className: cn(
|
|
112
|
-
"ui-control
|
|
113
|
+
"ui-control ui-control-composite-field",
|
|
113
114
|
"focus-within:border-ring focus-within:ring-ring/50 focus-within:ring-[3px]",
|
|
114
115
|
open && "border-ring ring-ring/50 ring-[3px]",
|
|
115
|
-
disabled && "pointer-events-none cursor-not-allowed opacity-50",
|
|
116
116
|
className
|
|
117
117
|
),
|
|
118
118
|
onClick: () => {
|
|
@@ -139,7 +139,7 @@ function MonthRangePicker({
|
|
|
139
139
|
onBlur: () => setFromText(toYmText(value?.from))
|
|
140
140
|
}
|
|
141
141
|
),
|
|
142
|
-
/* @__PURE__ */ jsx(ArrowRight, { className: "
|
|
142
|
+
/* @__PURE__ */ jsx(ArrowRight, { className: "ui-month-picker-separator-icon", "aria-hidden": "true" }),
|
|
143
143
|
/* @__PURE__ */ jsx(
|
|
144
144
|
"input",
|
|
145
145
|
{
|
|
@@ -171,9 +171,10 @@ function MonthRangePicker({
|
|
|
171
171
|
event.stopPropagation();
|
|
172
172
|
clear();
|
|
173
173
|
},
|
|
174
|
-
children: /* @__PURE__ */ jsx(X, { className: "
|
|
174
|
+
children: /* @__PURE__ */ jsx(X, { className: "ui-month-picker-icon", "aria-hidden": "true" })
|
|
175
175
|
}
|
|
176
|
-
) :
|
|
176
|
+
) : null,
|
|
177
|
+
/* @__PURE__ */ jsx(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsx(
|
|
177
178
|
"button",
|
|
178
179
|
{
|
|
179
180
|
type: "button",
|
|
@@ -181,18 +182,18 @@ function MonthRangePicker({
|
|
|
181
182
|
tabIndex: -1,
|
|
182
183
|
"aria-label": t("dataEntry.monthPicker.openGrid") ?? "Open month grid",
|
|
183
184
|
className: "text-muted-foreground hover:text-foreground shrink-0",
|
|
184
|
-
children: /* @__PURE__ */ jsx(CalendarIcon, { className: "
|
|
185
|
+
children: /* @__PURE__ */ jsx(CalendarIcon, { className: "ui-month-picker-icon", "aria-hidden": "true" })
|
|
185
186
|
}
|
|
186
187
|
) }),
|
|
187
188
|
/* @__PURE__ */ jsxs(
|
|
188
189
|
PopoverContent,
|
|
189
190
|
{
|
|
190
|
-
className: "
|
|
191
|
+
className: "ui-month-picker-panel",
|
|
191
192
|
align: "start",
|
|
192
193
|
onOpenAutoFocus: (event) => event.preventDefault(),
|
|
193
194
|
onClick: (event) => event.stopPropagation(),
|
|
194
195
|
children: [
|
|
195
|
-
/* @__PURE__ */ jsxs("div", { className: "
|
|
196
|
+
/* @__PURE__ */ jsxs("div", { className: "ui-month-picker-nav", children: [
|
|
196
197
|
/* @__PURE__ */ jsx(
|
|
197
198
|
Button,
|
|
198
199
|
{
|
|
@@ -201,12 +202,12 @@ function MonthRangePicker({
|
|
|
201
202
|
size: "icon-sm",
|
|
202
203
|
disabled: prevDisabled,
|
|
203
204
|
"aria-label": t("dataEntry.monthPicker.previousYear") ?? "Previous year",
|
|
204
|
-
className: "
|
|
205
|
+
className: "ui-month-picker-nav-button",
|
|
205
206
|
onClick: () => setViewYear((y) => y - 1),
|
|
206
|
-
children: /* @__PURE__ */ jsx(ChevronLeft, { className: "
|
|
207
|
+
children: /* @__PURE__ */ jsx(ChevronLeft, { className: "ui-month-picker-icon", "aria-hidden": "true" })
|
|
207
208
|
}
|
|
208
209
|
),
|
|
209
|
-
/* @__PURE__ */ jsx("span", { className: "
|
|
210
|
+
/* @__PURE__ */ jsx("span", { className: "ui-month-picker-nav-label", "aria-live": "polite", children: viewYear }),
|
|
210
211
|
/* @__PURE__ */ jsx(
|
|
211
212
|
Button,
|
|
212
213
|
{
|
|
@@ -215,13 +216,13 @@ function MonthRangePicker({
|
|
|
215
216
|
size: "icon-sm",
|
|
216
217
|
disabled: nextDisabled,
|
|
217
218
|
"aria-label": t("dataEntry.monthPicker.nextYear") ?? "Next year",
|
|
218
|
-
className: "
|
|
219
|
+
className: "ui-month-picker-nav-button",
|
|
219
220
|
onClick: () => setViewYear((y) => y + 1),
|
|
220
|
-
children: /* @__PURE__ */ jsx(ChevronRight, { className: "
|
|
221
|
+
children: /* @__PURE__ */ jsx(ChevronRight, { className: "ui-month-picker-icon", "aria-hidden": "true" })
|
|
221
222
|
}
|
|
222
223
|
)
|
|
223
224
|
] }),
|
|
224
|
-
/* @__PURE__ */ jsx("div", { role: "grid", "aria-label": String(viewYear), className: "
|
|
225
|
+
/* @__PURE__ */ jsx("div", { role: "grid", "aria-label": String(viewYear), className: "ui-month-picker-grid", children: monthLabels.map((label, i) => {
|
|
225
226
|
const cell = new Date(viewYear, i, 1);
|
|
226
227
|
const cellIdx = ymIndex(cell);
|
|
227
228
|
const fromIdx = value?.from ? ymIndex(value.from) : void 0;
|
|
@@ -235,7 +236,7 @@ function MonthRangePicker({
|
|
|
235
236
|
variant: isEdge ? "default" : inRange ? "secondary" : "ghost",
|
|
236
237
|
size: "sm",
|
|
237
238
|
"aria-pressed": isEdge,
|
|
238
|
-
className: "
|
|
239
|
+
className: "ui-month-picker-cell",
|
|
239
240
|
onClick: () => pickMonth(cell),
|
|
240
241
|
children: label
|
|
241
242
|
},
|
|
@@ -23,7 +23,12 @@ const RadioItem = React.forwardRef(({ className, ...props }, ref) => /* @__PURE_
|
|
|
23
23
|
ref,
|
|
24
24
|
"data-slot": "radio-group-item",
|
|
25
25
|
className: cn(
|
|
26
|
-
|
|
26
|
+
// `disabled:cursor-not-allowed disabled:opacity-50` DELETED, not moved (#319):
|
|
27
|
+
// `.ui-radio:disabled, .ui-radio[data-disabled]` in styles/control.css already declares both
|
|
28
|
+
// and reads --disabled-opacity. The utility was layered after components, so it silently
|
|
29
|
+
// outranked that token — a service theme's --disabled-opacity never reached a radio.
|
|
30
|
+
// Byte-identical: --disabled-opacity defaults to 0.5.
|
|
31
|
+
"ui-radio aria-invalid:border-destructive aria-invalid:ring-destructive/20 shrink-0 shadow-xs transition-shadow outline-none",
|
|
27
32
|
className
|
|
28
33
|
),
|
|
29
34
|
...props,
|
|
@@ -258,13 +258,13 @@ function SearchSelect({
|
|
|
258
258
|
"w-full justify-start font-normal",
|
|
259
259
|
controlOpenRingClass,
|
|
260
260
|
// Reserve trailing room for the single clear-or-chevron overlay rendered below.
|
|
261
|
-
"
|
|
261
|
+
"ui-control-trigger-affixed"
|
|
262
262
|
),
|
|
263
263
|
children: /* @__PURE__ */ jsx(
|
|
264
264
|
"span",
|
|
265
265
|
{
|
|
266
266
|
className: cn(
|
|
267
|
-
"
|
|
267
|
+
"ui-search-select-option-body text-start",
|
|
268
268
|
!value && "text-muted-foreground"
|
|
269
269
|
),
|
|
270
270
|
children: value && labelRender ? labelRender({ value, label: currentLabel, option: selectedOption ?? void 0 }) : /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
@@ -284,9 +284,9 @@ function SearchSelect({
|
|
|
284
284
|
align: "start",
|
|
285
285
|
sideOffset: 4,
|
|
286
286
|
collisionPadding: 12,
|
|
287
|
-
className: "
|
|
288
|
-
children: /* @__PURE__ */ jsxs(Command, { value, shouldFilter: false, className: "
|
|
289
|
-
/* @__PURE__ */ jsx("div", { className: "
|
|
287
|
+
className: "ui-search-select-panel",
|
|
288
|
+
children: /* @__PURE__ */ jsxs(Command, { value, shouldFilter: false, className: "ui-search-select-command", children: [
|
|
289
|
+
/* @__PURE__ */ jsx("div", { className: "ui-search-select-search", children: /* @__PURE__ */ jsx(
|
|
290
290
|
Input,
|
|
291
291
|
{
|
|
292
292
|
autoFocus: true,
|
|
@@ -298,7 +298,7 @@ function SearchSelect({
|
|
|
298
298
|
onChange: (event) => setQuery(event.target.value),
|
|
299
299
|
onKeyDown,
|
|
300
300
|
placeholder: searchPlaceholder ?? t("dataEntry.searchSelect.search"),
|
|
301
|
-
className: "
|
|
301
|
+
className: "ui-search-select-search-input"
|
|
302
302
|
}
|
|
303
303
|
) }),
|
|
304
304
|
/* @__PURE__ */ jsxs(
|
|
@@ -307,7 +307,7 @@ function SearchSelect({
|
|
|
307
307
|
id: listId,
|
|
308
308
|
role: "listbox",
|
|
309
309
|
"aria-busy": loading,
|
|
310
|
-
className: "
|
|
310
|
+
className: "ui-search-select-list",
|
|
311
311
|
onScroll,
|
|
312
312
|
children: [
|
|
313
313
|
grouped.map((group) => {
|
|
@@ -331,11 +331,11 @@ function SearchSelect({
|
|
|
331
331
|
onMouseEnter: () => !option.disabled && setActiveIndex(index),
|
|
332
332
|
onMouseDown: (event) => event.preventDefault(),
|
|
333
333
|
onClick: () => select(option),
|
|
334
|
-
children: renderOption ? /* @__PURE__ */ jsx("div", { className: "
|
|
334
|
+
children: renderOption ? /* @__PURE__ */ jsx("div", { className: "ui-search-select-option-slot", children: renderOption(option) }) : /* @__PURE__ */ jsxs("div", { className: "ui-search-select-option-body", children: [
|
|
335
335
|
option.icon ? /* @__PURE__ */ jsx("span", { className: "flex shrink-0 items-center", "aria-hidden": "true", children: option.icon }) : null,
|
|
336
|
-
/* @__PURE__ */ jsxs("div", { className: "
|
|
337
|
-
/* @__PURE__ */ jsx("span", { className: "
|
|
338
|
-
option.sublabel ? /* @__PURE__ */ jsx("span", { className: "
|
|
336
|
+
/* @__PURE__ */ jsxs("div", { className: "ui-search-select-option-text", children: [
|
|
337
|
+
/* @__PURE__ */ jsx("span", { className: "ui-search-select-option-label", children: option.label }),
|
|
338
|
+
option.sublabel ? /* @__PURE__ */ jsx("span", { className: "ui-search-select-option-sublabel", children: option.sublabel }) : null
|
|
339
339
|
] })
|
|
340
340
|
] })
|
|
341
341
|
},
|
|
@@ -343,17 +343,10 @@ function SearchSelect({
|
|
|
343
343
|
));
|
|
344
344
|
return group.heading ? /* @__PURE__ */ jsx(CommandGroup, { heading: group.heading, children: rows }, group.heading) : /* @__PURE__ */ jsx(React.Fragment, { children: rows }, "__ungrouped");
|
|
345
345
|
}),
|
|
346
|
-
loading ? /* @__PURE__ */ jsxs(
|
|
347
|
-
"
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
className: "text-muted-foreground flex items-center gap-2 px-2 py-3 text-sm",
|
|
351
|
-
children: [
|
|
352
|
-
/* @__PURE__ */ jsx(Loader2, { className: "size-4 animate-spin", "aria-hidden": "true" }),
|
|
353
|
-
loadingMessage ?? t("dataEntry.searchSelect.loading")
|
|
354
|
-
]
|
|
355
|
-
}
|
|
356
|
-
) : error ? renderError ? renderError({
|
|
346
|
+
loading ? /* @__PURE__ */ jsxs("div", { role: "status", className: "ui-search-select-status", children: [
|
|
347
|
+
/* @__PURE__ */ jsx(Loader2, { className: "ui-search-select-spinner animate-spin", "aria-hidden": "true" }),
|
|
348
|
+
loadingMessage ?? t("dataEntry.searchSelect.loading")
|
|
349
|
+
] }) : error ? renderError ? renderError({
|
|
357
350
|
message: errorMessage ?? t("dataEntry.searchSelect.error"),
|
|
358
351
|
// Retry always reloads from the first page (a defined, predictable recovery —
|
|
359
352
|
// NOT a resume of a failed page-N append, which would need to re-derive state).
|
|
@@ -364,7 +357,8 @@ function SearchSelect({
|
|
|
364
357
|
role: "option",
|
|
365
358
|
"aria-disabled": "true",
|
|
366
359
|
"aria-selected": false,
|
|
367
|
-
className: "
|
|
360
|
+
className: "ui-search-select-placeholder",
|
|
361
|
+
"data-tone": "destructive",
|
|
368
362
|
children: errorMessage ?? t("dataEntry.searchSelect.error")
|
|
369
363
|
}
|
|
370
364
|
) : loaded.length === 0 ? /* @__PURE__ */ jsx(
|
|
@@ -373,7 +367,7 @@ function SearchSelect({
|
|
|
373
367
|
role: "option",
|
|
374
368
|
"aria-disabled": "true",
|
|
375
369
|
"aria-selected": false,
|
|
376
|
-
className: "
|
|
370
|
+
className: "ui-search-select-placeholder",
|
|
377
371
|
children: emptyMessage ?? t("dataEntry.searchSelect.empty")
|
|
378
372
|
}
|
|
379
373
|
) : null
|
|
@@ -383,7 +377,7 @@ function SearchSelect({
|
|
|
383
377
|
renderLoadMore && hasMore ? /* @__PURE__ */ jsx(
|
|
384
378
|
"div",
|
|
385
379
|
{
|
|
386
|
-
className: "
|
|
380
|
+
className: "ui-search-select-footer",
|
|
387
381
|
onKeyDown: (event) => event.stopPropagation(),
|
|
388
382
|
children: renderLoadMore({
|
|
389
383
|
hasMore,
|
|
@@ -400,17 +394,23 @@ function SearchSelect({
|
|
|
400
394
|
]
|
|
401
395
|
}
|
|
402
396
|
),
|
|
403
|
-
/* @__PURE__ */ jsx("div", { className: "
|
|
397
|
+
/* @__PURE__ */ jsx("div", { className: "ui-control-affix", children: showClear ? /* @__PURE__ */ jsx(
|
|
404
398
|
"button",
|
|
405
399
|
{
|
|
406
400
|
type: "button",
|
|
407
401
|
"aria-label": clearLabel ?? t("dataEntry.searchSelect.clear"),
|
|
408
402
|
"data-testid": optionTestId("clear"),
|
|
409
|
-
className: "
|
|
403
|
+
className: "ui-control-affix-action",
|
|
410
404
|
onClick: clear,
|
|
411
|
-
children: /* @__PURE__ */ jsx(X, { className: "
|
|
405
|
+
children: /* @__PURE__ */ jsx(X, { className: "ui-control-affix-icon", "aria-hidden": "true" })
|
|
406
|
+
}
|
|
407
|
+
) : /* @__PURE__ */ jsx(
|
|
408
|
+
ChevronsUpDown,
|
|
409
|
+
{
|
|
410
|
+
className: "ui-control-affix-icon ui-control-affix-indicator",
|
|
411
|
+
"aria-hidden": "true"
|
|
412
412
|
}
|
|
413
|
-
)
|
|
413
|
+
) })
|
|
414
414
|
] });
|
|
415
415
|
}
|
|
416
416
|
export {
|