@assure-one/design-system 1.39.0 → 1.41.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 +48 -28
- package/codemods/README.md +24 -7
- package/codemods/lib/registry.mjs +27 -0
- package/codemods/lib/runner.mjs +8 -3
- package/codemods/run.mjs +27 -5
- package/codemods/transforms/cm-15-dom-selectors.mjs +16 -9
- package/dist/brand-scope-BOHId6BY.d.ts +58 -0
- package/dist/{brand-theme-B6rem2II.d.ts → brand-theme-ZYM867Jz.d.ts} +1 -1
- package/dist/chunk-CPOGSNXS.js +389 -0
- package/dist/chunk-CPOGSNXS.js.map +1 -0
- package/dist/chunk-EUHGZA6Q.js +313 -0
- package/dist/chunk-EUHGZA6Q.js.map +1 -0
- package/dist/chunk-KUSY7BLL.js +441 -0
- package/dist/chunk-KUSY7BLL.js.map +1 -0
- package/dist/chunk-NBI7E3VT.js +3754 -0
- package/dist/chunk-NBI7E3VT.js.map +1 -0
- package/dist/chunk-PTI4B2OI.js +5527 -0
- package/dist/chunk-PTI4B2OI.js.map +1 -0
- package/dist/chunk-X76J4QSJ.js +164 -0
- package/dist/chunk-X76J4QSJ.js.map +1 -0
- package/dist/chunk-XV2VSEA5.js +4339 -0
- package/dist/chunk-XV2VSEA5.js.map +1 -0
- package/dist/css/components.css +1 -1
- package/dist/css/legacy-aliases.css +2 -0
- package/dist/css/tailwind.css +2 -0
- package/dist/css/tokens.css +2 -0
- package/dist/data-table-view-ep8al7P9.d.ts +1132 -0
- package/dist/{design-system-provider-BM_F1C13.d.ts → design-system-provider-CfD2g2lY.d.ts} +11 -12
- package/dist/icons/index.d.ts +189 -140
- package/dist/icons/index.js +2 -1835
- package/dist/icons/index.js.map +1 -1
- package/dist/index.d.ts +374 -389
- package/dist/index.js +8688 -24271
- package/dist/index.js.map +1 -1
- package/dist/legacy/index.d.ts +1462 -7
- package/dist/legacy/index.js +5 -1
- package/dist/legacy/index.js.map +1 -1
- package/dist/next/index.d.ts +2 -2
- package/dist/styles.css +2 -1
- package/dist/suite/index.d.ts +991 -4
- package/dist/suite/index.js +6 -1
- package/dist/suite/index.js.map +1 -1
- package/dist/testing/index.cjs +3 -2
- package/dist/testing/index.js +3 -2
- package/dist/tokens/index.d.ts +1 -1
- package/dist/tokens/index.js +3 -856
- package/dist/tokens/index.js.map +1 -1
- package/dist/{types-k_kjwipx.d.ts → types-Coqw8iaS.d.ts} +28 -1
- package/docs/components.md +56 -56
- package/docs/components.registry.json +7 -7
- package/docs/for-ai-agents.md +12 -6
- package/package.json +8 -5
- package/dist/index-BAAuIQqP.d.ts +0 -2579
- package/dist/index-DxBjmBBp.d.ts +0 -1038
|
@@ -0,0 +1,3754 @@
|
|
|
1
|
+
import { cn, LoaderIcon, ChevronDownIcon, ChevronUpIcon, CheckIcon, MinusIcon, ChevronRightIcon, CircleIcon, FileTextIcon, EyeOffIcon, EyeIcon, XIcon, AlertTriangleIcon, UploadIcon } from './chunk-KUSY7BLL.js';
|
|
2
|
+
import * as React7 from 'react';
|
|
3
|
+
import { createContext, forwardRef, useMemo, useState, useRef, useCallback, useEffect, useContext, useId as useId$1, useLayoutEffect } from 'react';
|
|
4
|
+
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
5
|
+
import { cva } from 'class-variance-authority';
|
|
6
|
+
import { Slot, Slottable } from '@radix-ui/react-slot';
|
|
7
|
+
export { Slot } from '@radix-ui/react-slot';
|
|
8
|
+
import * as AvatarPrimitive from '@radix-ui/react-avatar';
|
|
9
|
+
import * as TooltipPrimitive from '@radix-ui/react-tooltip';
|
|
10
|
+
import { createPortal } from 'react-dom';
|
|
11
|
+
import * as SelectPrimitive from '@radix-ui/react-select';
|
|
12
|
+
import * as CheckboxPrimitive from '@radix-ui/react-checkbox';
|
|
13
|
+
import * as PopoverPrimitive from '@radix-ui/react-popover';
|
|
14
|
+
import * as DialogPrimitive from '@radix-ui/react-dialog';
|
|
15
|
+
import * as DropdownMenuPrimitive from '@radix-ui/react-dropdown-menu';
|
|
16
|
+
|
|
17
|
+
var ThemeScopeContext = createContext(null);
|
|
18
|
+
function useThemeScope() {
|
|
19
|
+
return useContext(ThemeScopeContext);
|
|
20
|
+
}
|
|
21
|
+
function mergeScopes(parent, own) {
|
|
22
|
+
const merged = { ...parent };
|
|
23
|
+
if (own.scheme !== void 0) merged.scheme = own.scheme;
|
|
24
|
+
if (own.brand !== void 0) merged.brand = own.brand;
|
|
25
|
+
if (own.density !== void 0) merged.density = own.density;
|
|
26
|
+
if (own.dir !== void 0) merged.dir = own.dir;
|
|
27
|
+
if (own.brandTheme !== void 0) merged.brandTheme = own.brandTheme;
|
|
28
|
+
return merged;
|
|
29
|
+
}
|
|
30
|
+
function themeScopeAttributes(scope) {
|
|
31
|
+
return {
|
|
32
|
+
"data-ds-scheme": scope.scheme,
|
|
33
|
+
"data-ds-brand": scope.brand,
|
|
34
|
+
"data-ds-density": scope.density,
|
|
35
|
+
dir: scope.dir
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
function ThemeScopeProvider({
|
|
39
|
+
value,
|
|
40
|
+
children
|
|
41
|
+
}) {
|
|
42
|
+
const parent = useThemeScope();
|
|
43
|
+
const merged = useMemo(() => mergeScopes(parent, value), [parent, value]);
|
|
44
|
+
return /* @__PURE__ */ jsx(ThemeScopeContext, { value: merged, children });
|
|
45
|
+
}
|
|
46
|
+
var ThemeScope = forwardRef(function ThemeScope2({ scheme, brand, density, dir, brandTheme, style, children, ...props }, ref) {
|
|
47
|
+
const value = useMemo(
|
|
48
|
+
() => ({ scheme, brand, density, dir, brandTheme }),
|
|
49
|
+
[scheme, brand, density, dir, brandTheme]
|
|
50
|
+
);
|
|
51
|
+
return /* @__PURE__ */ jsx(ThemeScopeProvider, { value, children: /* @__PURE__ */ jsx(
|
|
52
|
+
"div",
|
|
53
|
+
{
|
|
54
|
+
ref,
|
|
55
|
+
...themeScopeAttributes(value),
|
|
56
|
+
style: brandTheme ? { ...brandTheme, ...style } : style,
|
|
57
|
+
...props,
|
|
58
|
+
children
|
|
59
|
+
}
|
|
60
|
+
) });
|
|
61
|
+
});
|
|
62
|
+
ThemeScope.displayName = "ThemeScope";
|
|
63
|
+
|
|
64
|
+
// src/lib/micro-interactions.ts
|
|
65
|
+
var microInteractions = {
|
|
66
|
+
control: "ds:transition-[color,background-color,border-color,box-shadow] ds:duration-[var(--motion-duration-feedback)] ds:ease-[var(--motion-ease-enter)] ds:motion-reduce:transition-none",
|
|
67
|
+
pressable: "ds:transition-[color,background-color,border-color,box-shadow,transform] ds:[transition-duration:var(--motion-duration-feedback),var(--motion-duration-feedback),var(--motion-duration-feedback),var(--motion-duration-feedback),var(--motion-duration-press)] ds:ease-[var(--motion-ease-enter)] ds:active:scale-[0.98] ds:motion-reduce:transform-none ds:motion-reduce:transition-none",
|
|
68
|
+
selection: "ds:transition-[color,background-color,border-color,box-shadow] ds:duration-[var(--motion-duration-press)] ds:ease-[var(--motion-ease-enter)] ds:motion-reduce:transition-none",
|
|
69
|
+
disclosure: "ds:transition-[grid-template-rows,opacity,transform] ds:duration-[var(--motion-duration-spatial)] ds:ease-[var(--motion-ease-move)] ds:motion-reduce:transform-none ds:motion-reduce:transition-none",
|
|
70
|
+
overlay: "ds:transition-[opacity,transform] ds:duration-[var(--motion-duration-overlay)] ds:ease-[var(--motion-ease-enter)] ds:motion-reduce:transform-none ds:motion-reduce:transition-none",
|
|
71
|
+
progress: "ds:transition-[width,height,stroke-dashoffset,background-color] ds:duration-[var(--motion-duration-deliberate)] ds:ease-[var(--motion-ease-enter)] ds:motion-reduce:transition-none",
|
|
72
|
+
reveal: "ds:transition-[opacity,transform] ds:duration-[var(--motion-duration-feedback)] ds:ease-[var(--motion-ease-enter)] ds:motion-reduce:transform-none ds:motion-reduce:transition-none"
|
|
73
|
+
};
|
|
74
|
+
|
|
75
|
+
// src/primitives/behavior/button-base.ts
|
|
76
|
+
var LEGACY_BUTTON_VARIANTS = {
|
|
77
|
+
primary: { variant: "solid", intent: "brand" },
|
|
78
|
+
secondary: { variant: "soft", intent: "neutral" },
|
|
79
|
+
destructive: { variant: "solid", intent: "danger" },
|
|
80
|
+
success: { variant: "solid", intent: "success" },
|
|
81
|
+
dashed: { variant: "outline", intent: "neutral", look: "dashed" }
|
|
82
|
+
};
|
|
83
|
+
var DEFAULT_BUTTON_INTENT = {
|
|
84
|
+
solid: "brand",
|
|
85
|
+
soft: "neutral",
|
|
86
|
+
outline: "neutral",
|
|
87
|
+
ghost: "neutral",
|
|
88
|
+
link: "brand"
|
|
89
|
+
};
|
|
90
|
+
var isLegacyVariant = (value) => Object.hasOwn(LEGACY_BUTTON_VARIANTS, value);
|
|
91
|
+
function resolveButtonStyle({
|
|
92
|
+
variant,
|
|
93
|
+
intent
|
|
94
|
+
}) {
|
|
95
|
+
const requested = intent === "destructive" ? "danger" : intent ?? void 0;
|
|
96
|
+
const word = variant ?? "primary";
|
|
97
|
+
if (isLegacyVariant(word)) {
|
|
98
|
+
const legacy = LEGACY_BUTTON_VARIANTS[word];
|
|
99
|
+
const resolvedIntent2 = requested ?? legacy.intent;
|
|
100
|
+
const look = legacy.look && resolvedIntent2 === legacy.intent ? legacy.look : `${legacy.variant}/${resolvedIntent2}`;
|
|
101
|
+
return { variant: legacy.variant, intent: resolvedIntent2, look };
|
|
102
|
+
}
|
|
103
|
+
const resolvedIntent = requested ?? DEFAULT_BUTTON_INTENT[word];
|
|
104
|
+
return { variant: word, intent: resolvedIntent, look: `${word}/${resolvedIntent}` };
|
|
105
|
+
}
|
|
106
|
+
var BUTTON_LOOKS = {
|
|
107
|
+
// solid — filled with the intent colour, contrasting foreground
|
|
108
|
+
"solid/brand": "ds:bg-brand ds:text-fg-on-brand ds:hover:bg-brand-hover ds:active:bg-brand-active",
|
|
109
|
+
"solid/neutral": "ds:bg-fg-2 ds:text-bg ds:hover:bg-fg ds:active:bg-fg",
|
|
110
|
+
"solid/success": "ds:bg-success-fg ds:text-fg-on-success ds:hover:bg-success-fg-hover ds:active:bg-success-fg-active",
|
|
111
|
+
"solid/danger": "ds:bg-danger-fg ds:text-fg-on-danger ds:hover:bg-danger-fg-hover ds:active:bg-danger-fg-active",
|
|
112
|
+
// soft — tinted background, intent-coloured foreground, a hairline that shows on hover
|
|
113
|
+
"soft/brand": "ds:bg-brand-bg ds:text-brand ds:border ds:border-transparent ds:hover:bg-brand-bg-hover ds:hover:border-brand-line",
|
|
114
|
+
"soft/neutral": "ds:bg-control-secondary-bg ds:text-control-fg ds:border ds:border-control-border ds:hover:bg-control-active-bg ds:hover:border-control-border-strong",
|
|
115
|
+
"soft/success": "ds:bg-success-bg ds:text-success-fg ds:border ds:border-transparent ds:hover:border-success-line",
|
|
116
|
+
"soft/danger": "ds:bg-danger-bg ds:text-danger-fg ds:border ds:border-transparent ds:hover:border-danger-line",
|
|
117
|
+
// outline — border only, transparent background
|
|
118
|
+
"outline/brand": "ds:border ds:border-brand-line ds:bg-control-bg ds:text-brand ds:hover:bg-brand-bg",
|
|
119
|
+
"outline/neutral": "ds:border ds:border-control-border-strong ds:bg-control-bg ds:text-control-fg ds:hover:bg-control-hover-bg ds:hover:border-control-border-hover",
|
|
120
|
+
"outline/success": "ds:border ds:border-success-line ds:bg-control-bg ds:text-success-fg ds:hover:bg-success-bg",
|
|
121
|
+
"outline/danger": "ds:border ds:border-danger-line ds:bg-control-bg ds:text-danger-fg ds:hover:bg-danger-bg",
|
|
122
|
+
// ghost — nothing until hovered
|
|
123
|
+
"ghost/brand": "ds:bg-control-bg ds:text-brand ds:hover:bg-brand-bg",
|
|
124
|
+
"ghost/neutral": "ds:bg-control-bg ds:text-control-fg ds:hover:bg-control-hover-bg ds:hover:text-control-hover-fg",
|
|
125
|
+
"ghost/success": "ds:bg-control-bg ds:text-success-fg ds:hover:bg-success-bg",
|
|
126
|
+
"ghost/danger": "ds:bg-control-bg ds:text-control-destructive-fg ds:hover:bg-control-destructive-hover-bg",
|
|
127
|
+
// link — inline text, underlined on hover; no box of its own
|
|
128
|
+
"link/brand": "ds:bg-transparent ds:text-accent ds:underline-offset-4 ds:hover:underline ds:p-0 ds:h-auto ds:active:scale-100",
|
|
129
|
+
"link/neutral": "ds:bg-transparent ds:text-fg ds:underline-offset-4 ds:hover:underline ds:p-0 ds:h-auto ds:active:scale-100",
|
|
130
|
+
"link/success": "ds:bg-transparent ds:text-success-fg ds:underline-offset-4 ds:hover:underline ds:p-0 ds:h-auto ds:active:scale-100",
|
|
131
|
+
"link/danger": "ds:bg-transparent ds:text-danger-fg ds:underline-offset-4 ds:hover:underline ds:p-0 ds:h-auto ds:active:scale-100",
|
|
132
|
+
// legacy-only look (ADR-007 §4)
|
|
133
|
+
dashed: "ds:border-2 ds:border-dashed ds:border-control-border ds:bg-control-bg ds:text-control-muted-fg ds:hover:border-control-border-hover ds:hover:bg-control-hover-bg ds:hover:text-control-hover-fg"
|
|
134
|
+
};
|
|
135
|
+
var BUTTON_SIZES = {
|
|
136
|
+
// Shared scale rows (A1): height, horizontal padding, label size, gap and
|
|
137
|
+
// glyph size all from `--control-*-<size>`.
|
|
138
|
+
xs: "ds:h-(--control-height-xs) ds:px-(--control-padding-x-xs) ds:text-(length:--control-font-size-xs) ds:gap-(--control-gap-xs) ds:[&_svg]:size-(--control-icon-xs)",
|
|
139
|
+
// `sm` renders 16px glyphs today (the base `[&_svg]:size-4`), not the
|
|
140
|
+
// scale's 14, so the glyph column is left to the base until D5.
|
|
141
|
+
sm: "ds:h-(--control-height-sm) ds:px-(--control-padding-x-sm) ds:text-(length:--control-font-size-sm) ds:gap-(--control-gap-sm)",
|
|
142
|
+
xl: "ds:h-(--control-height-xl) ds:px-(--control-padding-x-xl) ds:text-(length:--control-font-size-xl) ds:gap-(--control-gap-xl) ds:[&_svg]:size-(--control-icon-xl)",
|
|
143
|
+
// A1 mismatches (D5): today's pixels through the compat height tokens.
|
|
144
|
+
md: "ds:h-(--button-height-md) ds:px-4 ds:text-sm ds:gap-2",
|
|
145
|
+
lg: "ds:h-(--button-height-lg) ds:px-6 ds:text-base ds:gap-2",
|
|
146
|
+
// Icon-only sizes: square, today's pixels through the compat tokens
|
|
147
|
+
// (C-BTN-SIZE-ICON). Hit target ≥ 24px (WCAG 2.5.5 floor); `icon-xs` /
|
|
148
|
+
// `icon-sm` are for dense in-row action stacks where `icon` (40×40) would
|
|
149
|
+
// visually crowd the row. `IconButton` (W3-09) takes over the geometry.
|
|
150
|
+
"icon-xs": "ds:size-(--button-height-icon-xs) ds:[&_svg]:size-3.5",
|
|
151
|
+
"icon-sm": "ds:size-(--button-height-icon-sm) ds:[&_svg]:size-4",
|
|
152
|
+
icon: "ds:size-(--button-height-icon)"
|
|
153
|
+
};
|
|
154
|
+
var buttonBase = cva(
|
|
155
|
+
cn(
|
|
156
|
+
"ds:inline-flex ds:items-center ds:justify-center ds:rounded-btn ds:font-medium ds:whitespace-nowrap ds:cursor-pointer",
|
|
157
|
+
microInteractions.pressable,
|
|
158
|
+
"ds:focus-visible:outline-none ds:focus-visible:[box-shadow:var(--shadow-focus-ring)]",
|
|
159
|
+
"ds:disabled:pointer-events-none ds:[&:disabled:not([data-loading=true])]:bg-bg-disabled ds:[&:disabled:not([data-loading=true])]:text-fg-disabled",
|
|
160
|
+
"ds:data-[loading=true]:cursor-wait",
|
|
161
|
+
"ds:[&_svg]:size-4 ds:[&_svg]:shrink-0"
|
|
162
|
+
),
|
|
163
|
+
{
|
|
164
|
+
variants: {
|
|
165
|
+
look: BUTTON_LOOKS,
|
|
166
|
+
size: BUTTON_SIZES
|
|
167
|
+
},
|
|
168
|
+
defaultVariants: {
|
|
169
|
+
look: "solid/brand",
|
|
170
|
+
size: "md"
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
);
|
|
174
|
+
function buttonVariants({
|
|
175
|
+
variant,
|
|
176
|
+
intent,
|
|
177
|
+
size,
|
|
178
|
+
class: classProp,
|
|
179
|
+
className
|
|
180
|
+
} = {}) {
|
|
181
|
+
const { look } = resolveButtonStyle({ variant, intent });
|
|
182
|
+
return buttonBase({ look, size, class: cn(classProp, className) || void 0 });
|
|
183
|
+
}
|
|
184
|
+
function resolveButtonIcons({ iconStart, iconEnd, iconLeft, iconRight }, component = "Button") {
|
|
185
|
+
if (process.env.NODE_ENV !== "production") {
|
|
186
|
+
if (iconStart !== void 0 && iconLeft !== void 0) {
|
|
187
|
+
throw new Error(
|
|
188
|
+
`[${component}] \`iconStart\` and \`iconLeft\` are the same slot; pass one of them (\`iconLeft\` is the deprecated alias).`
|
|
189
|
+
);
|
|
190
|
+
}
|
|
191
|
+
if (iconEnd !== void 0 && iconRight !== void 0) {
|
|
192
|
+
throw new Error(
|
|
193
|
+
`[${component}] \`iconEnd\` and \`iconRight\` are the same slot; pass one of them (\`iconRight\` is the deprecated alias).`
|
|
194
|
+
);
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
return { start: iconStart ?? iconLeft, end: iconEnd ?? iconRight };
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
// src/foundation/messages/en.ts
|
|
201
|
+
var EN_MESSAGES = {
|
|
202
|
+
select: { clear: "Clear selection", placeholder: "Select..." },
|
|
203
|
+
searchInput: { clear: "Clear search", placeholder: "Search..." },
|
|
204
|
+
combobox: {
|
|
205
|
+
empty: "No results",
|
|
206
|
+
loading: "Loading\u2026",
|
|
207
|
+
create: (query) => `Create \u201C${query}\u201D`,
|
|
208
|
+
clear: "Clear",
|
|
209
|
+
toggle: "Show options",
|
|
210
|
+
remove: (label) => `Remove ${label}`
|
|
211
|
+
},
|
|
212
|
+
field: { optional: "optional" },
|
|
213
|
+
fileUpload: {
|
|
214
|
+
prompt: "Click to upload",
|
|
215
|
+
dragHint: " or drag and drop",
|
|
216
|
+
accepted: (accept) => `Accepted: ${accept}`,
|
|
217
|
+
maxSize: (size) => `Max size: ${size}`
|
|
218
|
+
},
|
|
219
|
+
confirm: {
|
|
220
|
+
confirm: "Confirm",
|
|
221
|
+
cancel: "Cancel",
|
|
222
|
+
failed: "Something went wrong. Please try again."
|
|
223
|
+
},
|
|
224
|
+
overlay: { close: "Close" },
|
|
225
|
+
toast: { region: "Notifications", dismiss: "Dismiss" },
|
|
226
|
+
commandPalette: {
|
|
227
|
+
name: "Command palette",
|
|
228
|
+
instructions: "Search and run commands",
|
|
229
|
+
search: "Type a command or search...",
|
|
230
|
+
empty: "No results found.",
|
|
231
|
+
navigate: "Navigate",
|
|
232
|
+
select: "Select",
|
|
233
|
+
close: "Close",
|
|
234
|
+
escapeKey: "esc"
|
|
235
|
+
},
|
|
236
|
+
keyboardShortcuts: {
|
|
237
|
+
name: "Keyboard Shortcuts",
|
|
238
|
+
general: "General",
|
|
239
|
+
commandPalette: "Command palette",
|
|
240
|
+
focusSearch: "Focus search",
|
|
241
|
+
keyboardShortcuts: "Keyboard shortcuts",
|
|
242
|
+
closeOrBack: "Close / go back",
|
|
243
|
+
then: "then",
|
|
244
|
+
hintPrefix: "Press",
|
|
245
|
+
hintSuffix: "anytime to toggle this dialog"
|
|
246
|
+
},
|
|
247
|
+
pagination: {
|
|
248
|
+
region: (page, total) => `Pagination, page ${page} of ${total}`,
|
|
249
|
+
range: (start, end, total) => `${start}\u2013${end} of ${total}`,
|
|
250
|
+
page: (page, total) => `Page ${page} of ${total}`,
|
|
251
|
+
previous: "Previous page",
|
|
252
|
+
next: "Next page",
|
|
253
|
+
rowsPerPage: "Rows per page"
|
|
254
|
+
},
|
|
255
|
+
copyButton: { copy: "Copy to clipboard", copied: "Copied" },
|
|
256
|
+
loadingRows: { loading: "Loading" },
|
|
257
|
+
progress: { progress: "Progress" },
|
|
258
|
+
segmentedProgress: { step: (filled, steps) => `Step ${filled} of ${steps}` },
|
|
259
|
+
breadcrumb: { region: "Breadcrumb" },
|
|
260
|
+
input: { showPassword: "Show password", hidePassword: "Hide password" },
|
|
261
|
+
avatar: {
|
|
262
|
+
image: "Avatar",
|
|
263
|
+
unknownUser: "Unknown user",
|
|
264
|
+
status: (status) => `${status} status`
|
|
265
|
+
},
|
|
266
|
+
avatarGroup: {
|
|
267
|
+
overflow: (count) => `+${count}`,
|
|
268
|
+
overflowLabel: (count) => `${count} more`
|
|
269
|
+
},
|
|
270
|
+
otpInput: { name: "One-time password" },
|
|
271
|
+
datePicker: {
|
|
272
|
+
openCalendar: "Open calendar",
|
|
273
|
+
pickYear: "Pick a year",
|
|
274
|
+
previousDecade: "Previous decade",
|
|
275
|
+
nextDecade: "Next decade"
|
|
276
|
+
},
|
|
277
|
+
dateRangePicker: { name: "Date range", placeholder: "Select date range" },
|
|
278
|
+
dismissibleChip: {
|
|
279
|
+
remove: "Remove filter",
|
|
280
|
+
removeNamed: (label) => `Remove ${label} filter`
|
|
281
|
+
},
|
|
282
|
+
multiFilterPill: {
|
|
283
|
+
clear: (label) => `Clear ${label} filter`,
|
|
284
|
+
clearSelection: "Clear selection"
|
|
285
|
+
},
|
|
286
|
+
searchSelect: {
|
|
287
|
+
placeholder: "Search...",
|
|
288
|
+
createNew: "Create new",
|
|
289
|
+
all: "All",
|
|
290
|
+
remove: (label) => `Remove ${label}`,
|
|
291
|
+
empty: "No results found.",
|
|
292
|
+
noOptions: "No options available.",
|
|
293
|
+
clear: "Clear",
|
|
294
|
+
clearNamed: (label) => `Clear ${label}`,
|
|
295
|
+
toggle: "Show options",
|
|
296
|
+
changeNamed: (label) => `Change ${label}`
|
|
297
|
+
},
|
|
298
|
+
phoneField: {
|
|
299
|
+
country: "Country",
|
|
300
|
+
searchCountries: "Search countries",
|
|
301
|
+
noCountries: "No countries found"
|
|
302
|
+
},
|
|
303
|
+
phoneCountryInput: {
|
|
304
|
+
selectCountry: "Select country code",
|
|
305
|
+
searchCountries: "Search country or code...",
|
|
306
|
+
noCountries: "No countries found"
|
|
307
|
+
},
|
|
308
|
+
starRating: {
|
|
309
|
+
rating: (rating, max) => `${rating} out of ${max} stars`,
|
|
310
|
+
half: "half"
|
|
311
|
+
},
|
|
312
|
+
fileTypeBadge: { file: (code) => `${code} file` },
|
|
313
|
+
attachmentChip: {
|
|
314
|
+
view: (name) => `View ${name}`,
|
|
315
|
+
download: (name) => `Download ${name}`
|
|
316
|
+
},
|
|
317
|
+
masterDetailLayout: { back: "Back" },
|
|
318
|
+
sidebar: {
|
|
319
|
+
collapse: "Collapse sidebar",
|
|
320
|
+
expand: "Expand sidebar",
|
|
321
|
+
pin: "Pin sidebar",
|
|
322
|
+
unpin: "Unpin sidebar",
|
|
323
|
+
collapseSection: "Collapse section",
|
|
324
|
+
expandSection: "Expand section",
|
|
325
|
+
navigation: "Navigation"
|
|
326
|
+
},
|
|
327
|
+
shell: { content: "Page content" },
|
|
328
|
+
bottomNav: { region: "Primary" },
|
|
329
|
+
dashGrid: { reorder: "Reorder widget" },
|
|
330
|
+
folderTree: {
|
|
331
|
+
collapse: (name) => `Collapse ${name}`,
|
|
332
|
+
expand: (name) => `Expand ${name}`
|
|
333
|
+
},
|
|
334
|
+
appHeader: { search: "Search\u2026" },
|
|
335
|
+
bulkActionBar: { clearSelection: "Clear selection" },
|
|
336
|
+
errorState: {
|
|
337
|
+
title: "Something went wrong",
|
|
338
|
+
retry: "Try again",
|
|
339
|
+
showDetails: "Show details",
|
|
340
|
+
hideDetails: "Hide details"
|
|
341
|
+
},
|
|
342
|
+
dataTable: {
|
|
343
|
+
search: "Search\u2026",
|
|
344
|
+
of: "of",
|
|
345
|
+
searchLabel: "Search",
|
|
346
|
+
columns: "Columns",
|
|
347
|
+
filterAll: "All",
|
|
348
|
+
selectAll: "Select all rows",
|
|
349
|
+
selectRow: "Select row"
|
|
350
|
+
},
|
|
351
|
+
tableStates: { loading: "Loading", empty: "No results" },
|
|
352
|
+
table: { region: "Scrollable table" },
|
|
353
|
+
stackedBarChart: { region: "Scrollable chart" },
|
|
354
|
+
pdfPreview: { region: "PDF preview" },
|
|
355
|
+
spreadsheetPreview: { region: "Spreadsheet preview" },
|
|
356
|
+
peoplePicker: { assignToMe: "Assign to me" },
|
|
357
|
+
comingSoon: { eyebrow: "Coming soon", badge: "In Development" }
|
|
358
|
+
};
|
|
359
|
+
|
|
360
|
+
// src/foundation/provider/context.tsx
|
|
361
|
+
var DesignSystemContext = createContext(null);
|
|
362
|
+
function useDsMessages(namespace, override) {
|
|
363
|
+
const provided = useContext(DesignSystemContext)?.messages?.[namespace];
|
|
364
|
+
return useMemo(
|
|
365
|
+
() => ({ ...EN_MESSAGES[namespace], ...stripUndefined(provided), ...stripUndefined(override) }),
|
|
366
|
+
[namespace, provided, override]
|
|
367
|
+
);
|
|
368
|
+
}
|
|
369
|
+
function stripUndefined(value) {
|
|
370
|
+
if (!value) return {};
|
|
371
|
+
const out = {};
|
|
372
|
+
for (const key of Object.keys(value)) {
|
|
373
|
+
if (value[key] !== void 0) out[key] = value[key];
|
|
374
|
+
}
|
|
375
|
+
return out;
|
|
376
|
+
}
|
|
377
|
+
function useLinkComponent() {
|
|
378
|
+
return useContext(DesignSystemContext)?.linkComponent;
|
|
379
|
+
}
|
|
380
|
+
function useImageComponent() {
|
|
381
|
+
return useContext(DesignSystemContext)?.imageComponent;
|
|
382
|
+
}
|
|
383
|
+
var TOOLTIP_DEFAULT_DELAY_MS = 300;
|
|
384
|
+
function useSharedTooltipProvider() {
|
|
385
|
+
return useContext(DesignSystemContext)?.sharedTooltipProvider ?? false;
|
|
386
|
+
}
|
|
387
|
+
var SPINNER_TONE_TO_INTENT = {
|
|
388
|
+
current: void 0,
|
|
389
|
+
muted: "neutral",
|
|
390
|
+
accent: "info",
|
|
391
|
+
success: "success",
|
|
392
|
+
warning: "warning",
|
|
393
|
+
destructive: "danger"
|
|
394
|
+
};
|
|
395
|
+
var spinnerCva = cva(
|
|
396
|
+
"ds:inline-flex ds:shrink-0 ds:items-center ds:justify-center ds:[&_svg]:motion-reduce:animate-none",
|
|
397
|
+
{
|
|
398
|
+
variants: {
|
|
399
|
+
size: {
|
|
400
|
+
xs: "ds:[&_svg]:size-3",
|
|
401
|
+
sm: "ds:[&_svg]:size-4",
|
|
402
|
+
md: "ds:[&_svg]:size-5",
|
|
403
|
+
lg: "ds:[&_svg]:size-6"
|
|
404
|
+
},
|
|
405
|
+
// The six intents plus the inherit case; `intent` (public) never says `current`.
|
|
406
|
+
ink: {
|
|
407
|
+
// No `intent` inherits `currentColor` (what `tone="current"` rendered).
|
|
408
|
+
current: "ds:text-current",
|
|
409
|
+
neutral: "ds:text-fg-3",
|
|
410
|
+
brand: "ds:text-brand",
|
|
411
|
+
info: "ds:text-accent",
|
|
412
|
+
success: "ds:text-success-fg",
|
|
413
|
+
warning: "ds:text-warning-fg",
|
|
414
|
+
danger: "ds:text-danger-fg"
|
|
415
|
+
}
|
|
416
|
+
},
|
|
417
|
+
defaultVariants: {
|
|
418
|
+
size: "md",
|
|
419
|
+
ink: "current"
|
|
420
|
+
}
|
|
421
|
+
}
|
|
422
|
+
);
|
|
423
|
+
var resolveSpinnerIntent = (intent, tone) => intent ?? (tone ? SPINNER_TONE_TO_INTENT[tone] : void 0);
|
|
424
|
+
function spinnerVariants({ intent, tone, size } = {}) {
|
|
425
|
+
return spinnerCva({ ink: resolveSpinnerIntent(intent, tone), size });
|
|
426
|
+
}
|
|
427
|
+
var Spinner = forwardRef(function Spinner2({ intent, tone, size, label, className, ...props }, ref) {
|
|
428
|
+
return /* @__PURE__ */ jsxs(
|
|
429
|
+
"span",
|
|
430
|
+
{
|
|
431
|
+
ref,
|
|
432
|
+
role: label ? "status" : void 0,
|
|
433
|
+
"aria-live": label ? "polite" : void 0,
|
|
434
|
+
className: cn(spinnerVariants({ intent, tone, size }), className),
|
|
435
|
+
...props,
|
|
436
|
+
children: [
|
|
437
|
+
/* @__PURE__ */ jsx(LoaderIcon, { className: "ds:animate-spinner", "aria-hidden": "true" }),
|
|
438
|
+
label && /* @__PURE__ */ jsx("span", { className: "ds:sr-only", children: label })
|
|
439
|
+
]
|
|
440
|
+
}
|
|
441
|
+
);
|
|
442
|
+
});
|
|
443
|
+
Spinner.displayName = "Spinner";
|
|
444
|
+
|
|
445
|
+
// src/foundation/anatomy/define.ts
|
|
446
|
+
var ROOT_PART = "root";
|
|
447
|
+
var NAME_PATTERN = /^[a-z][a-z0-9]*(?:-[a-z0-9]+)*$/;
|
|
448
|
+
var registry = /* @__PURE__ */ new Map();
|
|
449
|
+
function assertName(value, what) {
|
|
450
|
+
if (!NAME_PATTERN.test(value)) {
|
|
451
|
+
throw new TypeError(
|
|
452
|
+
`anatomy: ${what} must be lower-case kebab-case, received ${JSON.stringify(value)}`
|
|
453
|
+
);
|
|
454
|
+
}
|
|
455
|
+
}
|
|
456
|
+
function defineAnatomy(name, parts) {
|
|
457
|
+
assertName(name, "component name");
|
|
458
|
+
if (parts.length === 0) {
|
|
459
|
+
throw new TypeError(`anatomy: ${name} must declare at least one part`);
|
|
460
|
+
}
|
|
461
|
+
const seen = /* @__PURE__ */ new Set();
|
|
462
|
+
for (const part of parts) {
|
|
463
|
+
assertName(part, `part name of ${name}`);
|
|
464
|
+
if (seen.has(part)) {
|
|
465
|
+
throw new TypeError(`anatomy: ${name} declares the part ${JSON.stringify(part)} twice`);
|
|
466
|
+
}
|
|
467
|
+
seen.add(part);
|
|
468
|
+
}
|
|
469
|
+
if (registry.has(name)) {
|
|
470
|
+
throw new TypeError(`anatomy: ${name} is already registered`);
|
|
471
|
+
}
|
|
472
|
+
const attr = (part) => part === ROOT_PART ? name : `${name}-${String(part)}`;
|
|
473
|
+
const anatomy = {
|
|
474
|
+
name,
|
|
475
|
+
parts: [...parts],
|
|
476
|
+
attrs: parts.map((part) => attr(part)),
|
|
477
|
+
attr,
|
|
478
|
+
has: (part) => seen.has(part)
|
|
479
|
+
};
|
|
480
|
+
registry.set(name, anatomy);
|
|
481
|
+
return anatomy;
|
|
482
|
+
}
|
|
483
|
+
|
|
484
|
+
// src/foundation/anatomy/slots.ts
|
|
485
|
+
defineAnatomy("agreement-viewer", ["root"]);
|
|
486
|
+
defineAnatomy("message-composer", [
|
|
487
|
+
"root",
|
|
488
|
+
"header",
|
|
489
|
+
"chips",
|
|
490
|
+
"editor",
|
|
491
|
+
"below-editor",
|
|
492
|
+
"footer"
|
|
493
|
+
]);
|
|
494
|
+
var codeAnatomy = defineAnatomy("code", ["root", "content"]);
|
|
495
|
+
var kbdAnatomy = defineAnatomy("kbd", ["root"]);
|
|
496
|
+
var pressableAnatomy = defineAnatomy("pressable", ["root"]);
|
|
497
|
+
var buttonAnatomy = defineAnatomy("button", ["root", "icon-start", "icon-end", "spinner"]);
|
|
498
|
+
var linkButtonAnatomy = defineAnatomy("link-button", ["root", "icon-start", "icon-end"]);
|
|
499
|
+
var badgeAnatomy = defineAnatomy("badge", ["root", "dot", "icon"]);
|
|
500
|
+
var inputAnatomy = defineAnatomy("input", [
|
|
501
|
+
"root",
|
|
502
|
+
"label",
|
|
503
|
+
"icon-start",
|
|
504
|
+
"icon-end",
|
|
505
|
+
"password-toggle",
|
|
506
|
+
"description",
|
|
507
|
+
"error"
|
|
508
|
+
]);
|
|
509
|
+
var textareaAnatomy = defineAnatomy("textarea", [
|
|
510
|
+
"root",
|
|
511
|
+
"label",
|
|
512
|
+
"description",
|
|
513
|
+
"error",
|
|
514
|
+
"count"
|
|
515
|
+
]);
|
|
516
|
+
var searchInputAnatomy = defineAnatomy("search-input", [
|
|
517
|
+
"root",
|
|
518
|
+
"control",
|
|
519
|
+
"icon",
|
|
520
|
+
"clear"
|
|
521
|
+
]);
|
|
522
|
+
var selectAnatomy = defineAnatomy("select", [
|
|
523
|
+
"root",
|
|
524
|
+
"trigger",
|
|
525
|
+
"value",
|
|
526
|
+
"icon",
|
|
527
|
+
"clear",
|
|
528
|
+
"content",
|
|
529
|
+
"viewport",
|
|
530
|
+
"item",
|
|
531
|
+
"item-indicator",
|
|
532
|
+
"label",
|
|
533
|
+
"separator",
|
|
534
|
+
"scroll-up-button",
|
|
535
|
+
"scroll-down-button"
|
|
536
|
+
]);
|
|
537
|
+
var checkboxAnatomy = defineAnatomy("checkbox", ["root", "indicator", "label"]);
|
|
538
|
+
var radioGroupAnatomy = defineAnatomy("radio-group", [
|
|
539
|
+
"root",
|
|
540
|
+
"item",
|
|
541
|
+
"indicator",
|
|
542
|
+
"label",
|
|
543
|
+
"card",
|
|
544
|
+
"description"
|
|
545
|
+
]);
|
|
546
|
+
var switchAnatomy = defineAnatomy("switch", ["root", "thumb", "label"]);
|
|
547
|
+
var labelAnatomy = defineAnatomy("label", ["root", "required"]);
|
|
548
|
+
var numberInputAnatomy = defineAnatomy("number-input", ["root"]);
|
|
549
|
+
var phoneFieldAnatomy = defineAnatomy("phone-field", [
|
|
550
|
+
"root",
|
|
551
|
+
"country",
|
|
552
|
+
"number",
|
|
553
|
+
"flag"
|
|
554
|
+
]);
|
|
555
|
+
var fileUploadAnatomy = defineAnatomy("file-upload", [
|
|
556
|
+
"root",
|
|
557
|
+
"dropzone",
|
|
558
|
+
"input",
|
|
559
|
+
"error"
|
|
560
|
+
]);
|
|
561
|
+
var commandAnatomy = defineAnatomy("command", [
|
|
562
|
+
"overlay",
|
|
563
|
+
"content",
|
|
564
|
+
"title",
|
|
565
|
+
"description",
|
|
566
|
+
"root",
|
|
567
|
+
"input",
|
|
568
|
+
"list",
|
|
569
|
+
"empty",
|
|
570
|
+
"group",
|
|
571
|
+
"item",
|
|
572
|
+
"footer"
|
|
573
|
+
]);
|
|
574
|
+
var dialogAnatomy = defineAnatomy("dialog", [
|
|
575
|
+
"overlay",
|
|
576
|
+
"content",
|
|
577
|
+
"header",
|
|
578
|
+
"title",
|
|
579
|
+
"description",
|
|
580
|
+
"body",
|
|
581
|
+
"footer",
|
|
582
|
+
"close"
|
|
583
|
+
]);
|
|
584
|
+
var alertDialogAnatomy = defineAnatomy("alert-dialog", [
|
|
585
|
+
"overlay",
|
|
586
|
+
"content",
|
|
587
|
+
"header",
|
|
588
|
+
"title",
|
|
589
|
+
"description",
|
|
590
|
+
"footer",
|
|
591
|
+
"action",
|
|
592
|
+
"cancel"
|
|
593
|
+
]);
|
|
594
|
+
var sheetAnatomy = defineAnatomy("sheet", [
|
|
595
|
+
"overlay",
|
|
596
|
+
"content",
|
|
597
|
+
"header",
|
|
598
|
+
"title",
|
|
599
|
+
"description",
|
|
600
|
+
"body",
|
|
601
|
+
"footer",
|
|
602
|
+
"close"
|
|
603
|
+
]);
|
|
604
|
+
var sideDrawerAnatomy = defineAnatomy("side-drawer", [
|
|
605
|
+
"overlay",
|
|
606
|
+
"root",
|
|
607
|
+
"header",
|
|
608
|
+
"heading",
|
|
609
|
+
"subtitle",
|
|
610
|
+
"close",
|
|
611
|
+
"body",
|
|
612
|
+
"footer"
|
|
613
|
+
]);
|
|
614
|
+
var popoverAnatomy = defineAnatomy("popover", ["content"]);
|
|
615
|
+
var dropdownMenuAnatomy = defineAnatomy("dropdown-menu", [
|
|
616
|
+
"content",
|
|
617
|
+
"item",
|
|
618
|
+
"checkbox-item",
|
|
619
|
+
"radio-item",
|
|
620
|
+
"item-indicator",
|
|
621
|
+
"label",
|
|
622
|
+
"separator",
|
|
623
|
+
"shortcut",
|
|
624
|
+
"sub-trigger",
|
|
625
|
+
"sub-content"
|
|
626
|
+
]);
|
|
627
|
+
var contextMenuAnatomy = defineAnatomy("context-menu", [
|
|
628
|
+
"content",
|
|
629
|
+
"item",
|
|
630
|
+
"checkbox-item",
|
|
631
|
+
"radio-item",
|
|
632
|
+
"item-indicator",
|
|
633
|
+
"label",
|
|
634
|
+
"separator",
|
|
635
|
+
"shortcut",
|
|
636
|
+
"sub-trigger",
|
|
637
|
+
"sub-content"
|
|
638
|
+
]);
|
|
639
|
+
var tooltipAnatomy = defineAnatomy("tooltip", ["content"]);
|
|
640
|
+
var toastAnatomy = defineAnatomy("toast", [
|
|
641
|
+
"region",
|
|
642
|
+
"root",
|
|
643
|
+
"icon",
|
|
644
|
+
"title",
|
|
645
|
+
"description",
|
|
646
|
+
"action",
|
|
647
|
+
"close"
|
|
648
|
+
]);
|
|
649
|
+
var tableAnatomy = defineAnatomy("table", [
|
|
650
|
+
"root",
|
|
651
|
+
"wrapper",
|
|
652
|
+
"header",
|
|
653
|
+
"body",
|
|
654
|
+
"footer",
|
|
655
|
+
"row",
|
|
656
|
+
"head",
|
|
657
|
+
"cell",
|
|
658
|
+
"caption",
|
|
659
|
+
"sort",
|
|
660
|
+
"sort-indicator"
|
|
661
|
+
]);
|
|
662
|
+
var dataTableAnatomy = defineAnatomy("data-table", [
|
|
663
|
+
"root",
|
|
664
|
+
"toolbar",
|
|
665
|
+
"spacer",
|
|
666
|
+
"results-count",
|
|
667
|
+
"header",
|
|
668
|
+
"body",
|
|
669
|
+
"row",
|
|
670
|
+
"head",
|
|
671
|
+
"head-button",
|
|
672
|
+
"head-indicator",
|
|
673
|
+
"cell",
|
|
674
|
+
"checkbox-cell",
|
|
675
|
+
"search",
|
|
676
|
+
"filters",
|
|
677
|
+
"columns-menu",
|
|
678
|
+
"content",
|
|
679
|
+
"bulk-actions",
|
|
680
|
+
"pagination"
|
|
681
|
+
]);
|
|
682
|
+
var paginationAnatomy = defineAnatomy("pagination", [
|
|
683
|
+
"root",
|
|
684
|
+
"label",
|
|
685
|
+
"page-size",
|
|
686
|
+
"pages",
|
|
687
|
+
"previous",
|
|
688
|
+
"next",
|
|
689
|
+
"page",
|
|
690
|
+
"ellipsis"
|
|
691
|
+
]);
|
|
692
|
+
var shellAnatomy = defineAnatomy("shell", ["root", "main", "content"]);
|
|
693
|
+
var sidebarAnatomy = defineAnatomy("sidebar", [
|
|
694
|
+
"root",
|
|
695
|
+
"trigger",
|
|
696
|
+
"pin",
|
|
697
|
+
"brand",
|
|
698
|
+
"brand-text",
|
|
699
|
+
"section",
|
|
700
|
+
"section-header",
|
|
701
|
+
"section-label",
|
|
702
|
+
"link",
|
|
703
|
+
"link-label",
|
|
704
|
+
"link-action",
|
|
705
|
+
"link-badge",
|
|
706
|
+
"group",
|
|
707
|
+
"group-link",
|
|
708
|
+
"group-trigger",
|
|
709
|
+
"group-content",
|
|
710
|
+
"footer",
|
|
711
|
+
"user",
|
|
712
|
+
"user-name",
|
|
713
|
+
"user-subtitle"
|
|
714
|
+
]);
|
|
715
|
+
var sidebarBrandSwitcherAnatomy = defineAnatomy("sidebar-brand-switcher", [
|
|
716
|
+
"root",
|
|
717
|
+
"trigger",
|
|
718
|
+
"icon"
|
|
719
|
+
]);
|
|
720
|
+
var textAnatomy = defineAnatomy("text", ["root"]);
|
|
721
|
+
var headingAnatomy = defineAnatomy("heading", ["root"]);
|
|
722
|
+
var stackAnatomy = defineAnatomy("stack", ["root"]);
|
|
723
|
+
var inlineAnatomy = defineAnatomy("inline", ["root"]);
|
|
724
|
+
var surfaceAnatomy = defineAnatomy("surface", ["root"]);
|
|
725
|
+
var avatarAnatomy = defineAnatomy("avatar", [
|
|
726
|
+
"root",
|
|
727
|
+
"frame",
|
|
728
|
+
"image",
|
|
729
|
+
"fallback",
|
|
730
|
+
"status"
|
|
731
|
+
]);
|
|
732
|
+
var cardAnatomy = defineAnatomy("card", [
|
|
733
|
+
"root",
|
|
734
|
+
"header",
|
|
735
|
+
"title",
|
|
736
|
+
"description",
|
|
737
|
+
"action",
|
|
738
|
+
"content",
|
|
739
|
+
"footer"
|
|
740
|
+
]);
|
|
741
|
+
var statusBadgeAnatomy = defineAnatomy("status-badge", ["root", "indicator", "label"]);
|
|
742
|
+
var iconButtonAnatomy = defineAnatomy("icon-button", ["root", "icon", "spinner"]);
|
|
743
|
+
var chipAnatomy = defineAnatomy("chip", ["root", "icon", "label", "count", "remove"]);
|
|
744
|
+
var fieldAnatomy = defineAnatomy("field", [
|
|
745
|
+
"root",
|
|
746
|
+
"label",
|
|
747
|
+
"required",
|
|
748
|
+
"optional",
|
|
749
|
+
"description",
|
|
750
|
+
"error"
|
|
751
|
+
]);
|
|
752
|
+
var fieldsetAnatomy = defineAnatomy("fieldset", ["root", "legend"]);
|
|
753
|
+
var comboboxAnatomy = defineAnatomy("combobox", [
|
|
754
|
+
"root",
|
|
755
|
+
"control",
|
|
756
|
+
"value",
|
|
757
|
+
"chips",
|
|
758
|
+
"input",
|
|
759
|
+
"icon",
|
|
760
|
+
"clear",
|
|
761
|
+
"toggle",
|
|
762
|
+
"content",
|
|
763
|
+
"header",
|
|
764
|
+
"list",
|
|
765
|
+
"group",
|
|
766
|
+
"group-heading",
|
|
767
|
+
"item",
|
|
768
|
+
"item-indicator",
|
|
769
|
+
"create",
|
|
770
|
+
"empty",
|
|
771
|
+
"loading",
|
|
772
|
+
"footer"
|
|
773
|
+
]);
|
|
774
|
+
|
|
775
|
+
// src/foundation/anatomy/slot.ts
|
|
776
|
+
function slot(anatomy, part) {
|
|
777
|
+
return { "data-slot": anatomy.attr(part) };
|
|
778
|
+
}
|
|
779
|
+
var BOOLEAN_STATES = ["disabled", "invalid", "loading", "selected", "pressed"];
|
|
780
|
+
var VALUE_STATES = ["state", "size", "variant", "intent", "orientation"];
|
|
781
|
+
function stateAttributes(input) {
|
|
782
|
+
const attributes = {};
|
|
783
|
+
for (const key of BOOLEAN_STATES) {
|
|
784
|
+
if (input[key]) attributes[`data-${key}`] = "";
|
|
785
|
+
}
|
|
786
|
+
for (const key of VALUE_STATES) {
|
|
787
|
+
const value = input[key];
|
|
788
|
+
if (value !== void 0) attributes[`data-${key}`] = value;
|
|
789
|
+
}
|
|
790
|
+
return attributes;
|
|
791
|
+
}
|
|
792
|
+
|
|
793
|
+
// src/foundation/deprecate.ts
|
|
794
|
+
var PREFIX = "[@assure-one/design-system]";
|
|
795
|
+
var warned = /* @__PURE__ */ new Set();
|
|
796
|
+
function devWarningsEnabled() {
|
|
797
|
+
return process.env.NODE_ENV !== "production" && process.env.NODE_ENV !== "test";
|
|
798
|
+
}
|
|
799
|
+
function warnOnce(id, key, message) {
|
|
800
|
+
return printOnce("warn", id, key, message);
|
|
801
|
+
}
|
|
802
|
+
function errorOnce(id, key, message) {
|
|
803
|
+
return printOnce("error", id, key, message);
|
|
804
|
+
}
|
|
805
|
+
function printOnce(level, id, key, message) {
|
|
806
|
+
if (!devWarningsEnabled()) return false;
|
|
807
|
+
const dedupeKey = `${id}:${key}`;
|
|
808
|
+
if (warned.has(dedupeKey)) return false;
|
|
809
|
+
warned.add(dedupeKey);
|
|
810
|
+
console[level](`${PREFIX} ${id}: ${message}`);
|
|
811
|
+
return true;
|
|
812
|
+
}
|
|
813
|
+
function deprecate(id, key, message) {
|
|
814
|
+
return false;
|
|
815
|
+
}
|
|
816
|
+
var ICON_SIZES = /* @__PURE__ */ new Set(["icon-xs", "icon-sm", "icon"]);
|
|
817
|
+
function warnLegacyButtonProps(component, { variant, size, iconLeft, iconRight }) {
|
|
818
|
+
if (size && ICON_SIZES.has(size)) ;
|
|
819
|
+
}
|
|
820
|
+
|
|
821
|
+
// src/primitives/behavior/inert.ts
|
|
822
|
+
var INERT_ATTRIBUTES = { "aria-disabled": true, tabIndex: -1 };
|
|
823
|
+
var INERT_CLASSES = "ds:pointer-events-none";
|
|
824
|
+
var DISABLED_LOOK_CLASSES = "ds:bg-bg-disabled ds:text-fg-disabled";
|
|
825
|
+
var isActivationKey = (key) => key === "Enter" || key === " ";
|
|
826
|
+
function inertHandlers(inert, handlers) {
|
|
827
|
+
return {
|
|
828
|
+
onClick(event) {
|
|
829
|
+
if (inert) {
|
|
830
|
+
event.preventDefault();
|
|
831
|
+
event.stopPropagation();
|
|
832
|
+
return;
|
|
833
|
+
}
|
|
834
|
+
handlers.onClick?.(event);
|
|
835
|
+
},
|
|
836
|
+
onKeyDown(event) {
|
|
837
|
+
if (inert) {
|
|
838
|
+
if (isActivationKey(event.key)) {
|
|
839
|
+
event.preventDefault();
|
|
840
|
+
event.stopPropagation();
|
|
841
|
+
}
|
|
842
|
+
return;
|
|
843
|
+
}
|
|
844
|
+
handlers.onKeyDown?.(event);
|
|
845
|
+
}
|
|
846
|
+
};
|
|
847
|
+
}
|
|
848
|
+
var Button = forwardRef(function Button2({
|
|
849
|
+
variant,
|
|
850
|
+
intent,
|
|
851
|
+
size,
|
|
852
|
+
asChild = false,
|
|
853
|
+
loading,
|
|
854
|
+
fullWidth,
|
|
855
|
+
pressed,
|
|
856
|
+
iconStart,
|
|
857
|
+
iconEnd,
|
|
858
|
+
iconLeft,
|
|
859
|
+
iconRight,
|
|
860
|
+
disabled,
|
|
861
|
+
onClick,
|
|
862
|
+
onKeyDown,
|
|
863
|
+
children,
|
|
864
|
+
className,
|
|
865
|
+
...props
|
|
866
|
+
}, ref) {
|
|
867
|
+
warnLegacyButtonProps("Button", { variant, size, iconLeft, iconRight });
|
|
868
|
+
const icons = resolveButtonIcons({ iconStart, iconEnd, iconLeft, iconRight });
|
|
869
|
+
const inert = Boolean(disabled || loading);
|
|
870
|
+
const resolvedVariant = variant ?? "primary";
|
|
871
|
+
const resolvedSize = size ?? "md";
|
|
872
|
+
const state = stateAttributes({
|
|
873
|
+
variant: resolvedVariant,
|
|
874
|
+
intent: intent ?? void 0,
|
|
875
|
+
size: resolvedSize,
|
|
876
|
+
disabled: inert,
|
|
877
|
+
pressed
|
|
878
|
+
});
|
|
879
|
+
const start = loading ? /* @__PURE__ */ jsx(Spinner, { size: "sm", ...slot(buttonAnatomy, "spinner") }) : icons.start && /* @__PURE__ */ jsx(
|
|
880
|
+
"span",
|
|
881
|
+
{
|
|
882
|
+
...slot(buttonAnatomy, "icon-start"),
|
|
883
|
+
className: "ds:inline-flex ds:shrink-0",
|
|
884
|
+
"aria-hidden": "true",
|
|
885
|
+
children: icons.start
|
|
886
|
+
}
|
|
887
|
+
);
|
|
888
|
+
const end = icons.end && !loading && /* @__PURE__ */ jsx(
|
|
889
|
+
"span",
|
|
890
|
+
{
|
|
891
|
+
...slot(buttonAnatomy, "icon-end"),
|
|
892
|
+
className: "ds:inline-flex ds:shrink-0",
|
|
893
|
+
"aria-hidden": "true",
|
|
894
|
+
children: icons.end
|
|
895
|
+
}
|
|
896
|
+
);
|
|
897
|
+
if (asChild) {
|
|
898
|
+
const guarded = inertHandlers(inert, { onClick, onKeyDown });
|
|
899
|
+
const root = {
|
|
900
|
+
ref,
|
|
901
|
+
...slot(buttonAnatomy, "root"),
|
|
902
|
+
...state,
|
|
903
|
+
"aria-pressed": pressed,
|
|
904
|
+
"aria-busy": loading || void 0,
|
|
905
|
+
"data-loading": loading || void 0,
|
|
906
|
+
...inert ? INERT_ATTRIBUTES : {},
|
|
907
|
+
className: cn(
|
|
908
|
+
buttonVariants({ variant, intent, size }),
|
|
909
|
+
fullWidth && "ds:w-full",
|
|
910
|
+
inert && INERT_CLASSES,
|
|
911
|
+
disabled && !loading && DISABLED_LOOK_CLASSES,
|
|
912
|
+
className
|
|
913
|
+
),
|
|
914
|
+
...props,
|
|
915
|
+
...guarded
|
|
916
|
+
};
|
|
917
|
+
if (!start && !end) return /* @__PURE__ */ jsx(Slot, { ...root, children });
|
|
918
|
+
return /* @__PURE__ */ jsxs(Slot, { ...root, children: [
|
|
919
|
+
start,
|
|
920
|
+
/* @__PURE__ */ jsx(Slottable, { children }),
|
|
921
|
+
end
|
|
922
|
+
] });
|
|
923
|
+
}
|
|
924
|
+
return /* @__PURE__ */ jsxs(
|
|
925
|
+
"button",
|
|
926
|
+
{
|
|
927
|
+
ref,
|
|
928
|
+
disabled: disabled || loading,
|
|
929
|
+
"aria-busy": loading || void 0,
|
|
930
|
+
"data-loading": loading || void 0,
|
|
931
|
+
...slot(buttonAnatomy, "root"),
|
|
932
|
+
...state,
|
|
933
|
+
"aria-pressed": pressed,
|
|
934
|
+
className: cn(buttonVariants({ variant, intent, size }), fullWidth && "ds:w-full", className),
|
|
935
|
+
onClick,
|
|
936
|
+
onKeyDown,
|
|
937
|
+
...props,
|
|
938
|
+
type: props.type ?? "button",
|
|
939
|
+
children: [
|
|
940
|
+
start,
|
|
941
|
+
children,
|
|
942
|
+
end
|
|
943
|
+
]
|
|
944
|
+
}
|
|
945
|
+
);
|
|
946
|
+
});
|
|
947
|
+
Button.displayName = "Button";
|
|
948
|
+
|
|
949
|
+
// src/foundation/anatomy/class-names.ts
|
|
950
|
+
function slotClassName(classNames, part) {
|
|
951
|
+
return classNames?.[part];
|
|
952
|
+
}
|
|
953
|
+
var avatarVariants = cva(
|
|
954
|
+
cn(
|
|
955
|
+
"ds:relative ds:inline-flex ds:shrink-0 ds:items-center ds:justify-center ds:overflow-hidden ds:rounded-full",
|
|
956
|
+
"ds:font-mono ds:font-medium"
|
|
957
|
+
),
|
|
958
|
+
{
|
|
959
|
+
variants: {
|
|
960
|
+
size: {
|
|
961
|
+
xs: "ds:size-(--avatar-size-xs) ds:text-[9px]",
|
|
962
|
+
sm: "ds:size-(--avatar-size-sm) ds:text-[10px]",
|
|
963
|
+
md: "ds:size-(--avatar-size-md) ds:text-[11px]",
|
|
964
|
+
lg: "ds:size-(--avatar-size-lg) ds:text-sm",
|
|
965
|
+
xl: "ds:size-(--avatar-size-xl) ds:text-base"
|
|
966
|
+
},
|
|
967
|
+
variant: {
|
|
968
|
+
initials: "ds:bg-bg-3 ds:text-fg-2",
|
|
969
|
+
branded: "ds:border ds:border-[#D8CFFF] ds:bg-pro-bg ds:text-pro-fg"
|
|
970
|
+
}
|
|
971
|
+
},
|
|
972
|
+
defaultVariants: {
|
|
973
|
+
size: "md",
|
|
974
|
+
variant: "initials"
|
|
975
|
+
}
|
|
976
|
+
}
|
|
977
|
+
);
|
|
978
|
+
var statusStyles = {
|
|
979
|
+
online: "ds:bg-success-fg",
|
|
980
|
+
away: "ds:bg-warning-fg",
|
|
981
|
+
busy: "ds:bg-danger-fg",
|
|
982
|
+
offline: "ds:bg-fg-4"
|
|
983
|
+
};
|
|
984
|
+
var statusDotSizes = {
|
|
985
|
+
xs: "ds:size-1.5",
|
|
986
|
+
sm: "ds:size-2",
|
|
987
|
+
md: "ds:size-2.5",
|
|
988
|
+
lg: "ds:size-3",
|
|
989
|
+
xl: "ds:size-3.5"
|
|
990
|
+
};
|
|
991
|
+
function getInitials(name) {
|
|
992
|
+
return name.split(" ").map((part) => part[0]).filter(Boolean).slice(0, 2).join("").toUpperCase();
|
|
993
|
+
}
|
|
994
|
+
var Avatar = React7.forwardRef(
|
|
995
|
+
function Avatar2({ src, alt, name, size = "md", variant = "initials", status, className, classNames, ...props }, ref) {
|
|
996
|
+
const messages = useDsMessages("avatar");
|
|
997
|
+
const initials = name ? getInitials(name) : "?";
|
|
998
|
+
const resolvedSize = size ?? "md";
|
|
999
|
+
const resolvedVariant = variant ?? "initials";
|
|
1000
|
+
return /* @__PURE__ */ jsxs(
|
|
1001
|
+
"span",
|
|
1002
|
+
{
|
|
1003
|
+
...slot(avatarAnatomy, "root"),
|
|
1004
|
+
...stateAttributes({ size: resolvedSize, variant: resolvedVariant }),
|
|
1005
|
+
className: cn("ds:relative ds:inline-flex", slotClassName(classNames, "root")),
|
|
1006
|
+
children: [
|
|
1007
|
+
/* @__PURE__ */ jsxs(
|
|
1008
|
+
AvatarPrimitive.Root,
|
|
1009
|
+
{
|
|
1010
|
+
ref,
|
|
1011
|
+
...slot(avatarAnatomy, "frame"),
|
|
1012
|
+
className: cn(
|
|
1013
|
+
avatarVariants({ size: resolvedSize, variant: resolvedVariant }),
|
|
1014
|
+
slotClassName(classNames, "frame"),
|
|
1015
|
+
className
|
|
1016
|
+
),
|
|
1017
|
+
...props,
|
|
1018
|
+
children: [
|
|
1019
|
+
src ? /* @__PURE__ */ jsx(
|
|
1020
|
+
AvatarPrimitive.Image,
|
|
1021
|
+
{
|
|
1022
|
+
...slot(avatarAnatomy, "image"),
|
|
1023
|
+
src,
|
|
1024
|
+
alt: alt ?? name ?? messages.image,
|
|
1025
|
+
className: cn(
|
|
1026
|
+
"ds:aspect-square ds:size-full ds:object-cover",
|
|
1027
|
+
slotClassName(classNames, "image")
|
|
1028
|
+
)
|
|
1029
|
+
}
|
|
1030
|
+
) : null,
|
|
1031
|
+
/* @__PURE__ */ jsx(
|
|
1032
|
+
AvatarPrimitive.Fallback,
|
|
1033
|
+
{
|
|
1034
|
+
...slot(avatarAnatomy, "fallback"),
|
|
1035
|
+
delayMs: src ? 200 : 0,
|
|
1036
|
+
className: cn(
|
|
1037
|
+
"ds:flex ds:size-full ds:items-center ds:justify-center",
|
|
1038
|
+
slotClassName(classNames, "fallback")
|
|
1039
|
+
),
|
|
1040
|
+
"aria-label": name || messages.unknownUser,
|
|
1041
|
+
children: initials
|
|
1042
|
+
}
|
|
1043
|
+
)
|
|
1044
|
+
]
|
|
1045
|
+
}
|
|
1046
|
+
),
|
|
1047
|
+
status && /* @__PURE__ */ jsx(
|
|
1048
|
+
"span",
|
|
1049
|
+
{
|
|
1050
|
+
...slot(avatarAnatomy, "status"),
|
|
1051
|
+
className: cn(
|
|
1052
|
+
"ds:ring-bg ds:absolute ds:right-0 ds:bottom-0 ds:block ds:rounded-full ds:ring-2",
|
|
1053
|
+
statusDotSizes[resolvedSize],
|
|
1054
|
+
statusStyles[status],
|
|
1055
|
+
slotClassName(classNames, "status")
|
|
1056
|
+
),
|
|
1057
|
+
role: "img",
|
|
1058
|
+
"aria-label": messages.status(status)
|
|
1059
|
+
}
|
|
1060
|
+
)
|
|
1061
|
+
]
|
|
1062
|
+
}
|
|
1063
|
+
);
|
|
1064
|
+
}
|
|
1065
|
+
);
|
|
1066
|
+
Avatar.displayName = AvatarPrimitive.Root.displayName;
|
|
1067
|
+
function useId(explicit, prefix = "ds") {
|
|
1068
|
+
const generated = useId$1();
|
|
1069
|
+
return explicit ? explicit : `${prefix}-${generated}`;
|
|
1070
|
+
}
|
|
1071
|
+
function partId(base, part) {
|
|
1072
|
+
return `${base}-${part}`;
|
|
1073
|
+
}
|
|
1074
|
+
function joinIds(...ids) {
|
|
1075
|
+
const seen = /* @__PURE__ */ new Set();
|
|
1076
|
+
for (const value of ids) {
|
|
1077
|
+
if (!value) continue;
|
|
1078
|
+
for (const id of value.split(/\s+/)) {
|
|
1079
|
+
if (id) seen.add(id);
|
|
1080
|
+
}
|
|
1081
|
+
}
|
|
1082
|
+
return seen.size > 0 ? [...seen].join(" ") : void 0;
|
|
1083
|
+
}
|
|
1084
|
+
|
|
1085
|
+
// src/primitives/field/internal/accessible-name.ts
|
|
1086
|
+
var LABELABLE = "button, input, meter, output, progress, select, textarea";
|
|
1087
|
+
var NAMED_FROM_CONTENT = /* @__PURE__ */ new Set([
|
|
1088
|
+
"button",
|
|
1089
|
+
"checkbox",
|
|
1090
|
+
"link",
|
|
1091
|
+
"menuitem",
|
|
1092
|
+
"menuitemcheckbox",
|
|
1093
|
+
"menuitemradio",
|
|
1094
|
+
"option",
|
|
1095
|
+
"radio",
|
|
1096
|
+
"switch",
|
|
1097
|
+
"tab",
|
|
1098
|
+
"treeitem"
|
|
1099
|
+
]);
|
|
1100
|
+
function text(value) {
|
|
1101
|
+
return typeof value === "string" && value.trim().length > 0;
|
|
1102
|
+
}
|
|
1103
|
+
function contributesText(element) {
|
|
1104
|
+
if (text(element.getAttribute("aria-label"))) return true;
|
|
1105
|
+
if (text(element.textContent)) return true;
|
|
1106
|
+
const value = element.value;
|
|
1107
|
+
return typeof value === "string" && text(value);
|
|
1108
|
+
}
|
|
1109
|
+
function isLabelable(element) {
|
|
1110
|
+
if (!element.matches(LABELABLE)) return false;
|
|
1111
|
+
return !(element instanceof HTMLInputElement && element.type === "hidden");
|
|
1112
|
+
}
|
|
1113
|
+
function isHiddenFromAssistiveTech(element) {
|
|
1114
|
+
if (element.closest('[aria-hidden="true"]')) return true;
|
|
1115
|
+
if (element.closest("[hidden]")) return true;
|
|
1116
|
+
return element instanceof HTMLInputElement && element.type === "hidden";
|
|
1117
|
+
}
|
|
1118
|
+
function hasAccessibleName(element) {
|
|
1119
|
+
const labelledBy = element.getAttribute("aria-labelledby");
|
|
1120
|
+
if (text(labelledBy)) {
|
|
1121
|
+
const root = element.ownerDocument;
|
|
1122
|
+
const named = labelledBy.split(/\s+/).filter(Boolean).some((id) => {
|
|
1123
|
+
const target = root.getElementById(id);
|
|
1124
|
+
return target !== null && contributesText(target);
|
|
1125
|
+
});
|
|
1126
|
+
if (named) return true;
|
|
1127
|
+
}
|
|
1128
|
+
if (text(element.getAttribute("aria-label"))) return true;
|
|
1129
|
+
const labels = element.labels;
|
|
1130
|
+
if (labels && labels.length > 0) {
|
|
1131
|
+
for (const label of Array.from(labels)) {
|
|
1132
|
+
if (text(label.textContent)) return true;
|
|
1133
|
+
}
|
|
1134
|
+
}
|
|
1135
|
+
const wrapping = element.closest("label");
|
|
1136
|
+
if (wrapping && text(wrapping.textContent)) return true;
|
|
1137
|
+
if (text(element.getAttribute("title"))) return true;
|
|
1138
|
+
if (text(element.getAttribute("placeholder"))) return true;
|
|
1139
|
+
const role = element.getAttribute("role") ?? implicitRole(element);
|
|
1140
|
+
if (role === "listbox" && element.id && isComboboxPopup(element)) return true;
|
|
1141
|
+
if (role && NAMED_FROM_CONTENT.has(role)) {
|
|
1142
|
+
if (text(element.textContent)) return true;
|
|
1143
|
+
if (element instanceof HTMLInputElement && text(element.value)) return true;
|
|
1144
|
+
}
|
|
1145
|
+
return false;
|
|
1146
|
+
}
|
|
1147
|
+
function isComboboxPopup(listbox) {
|
|
1148
|
+
const id = listbox.id;
|
|
1149
|
+
return Array.from(
|
|
1150
|
+
listbox.ownerDocument.querySelectorAll(
|
|
1151
|
+
"[role=combobox][aria-controls], [role=combobox][aria-owns]"
|
|
1152
|
+
)
|
|
1153
|
+
).some((combobox) => {
|
|
1154
|
+
const refs = `${combobox.getAttribute("aria-controls") ?? ""} ${combobox.getAttribute("aria-owns") ?? ""}`;
|
|
1155
|
+
return refs.split(/\s+/).includes(id);
|
|
1156
|
+
});
|
|
1157
|
+
}
|
|
1158
|
+
function implicitRole(element) {
|
|
1159
|
+
const tag = element.tagName.toLowerCase();
|
|
1160
|
+
if (tag === "button") return "button";
|
|
1161
|
+
if (tag === "a" && element.hasAttribute("href")) return "link";
|
|
1162
|
+
if (tag === "input") {
|
|
1163
|
+
const type = element.type;
|
|
1164
|
+
if (type === "checkbox" || type === "radio") return type;
|
|
1165
|
+
if (type === "button" || type === "submit" || type === "reset") return "button";
|
|
1166
|
+
}
|
|
1167
|
+
return null;
|
|
1168
|
+
}
|
|
1169
|
+
var FIELD_PARTS = ["label", "description", "error"];
|
|
1170
|
+
var FieldContext = createContext(null);
|
|
1171
|
+
function useFieldContext() {
|
|
1172
|
+
return useContext(FieldContext);
|
|
1173
|
+
}
|
|
1174
|
+
|
|
1175
|
+
// src/primitives/field/use-field-control.ts
|
|
1176
|
+
function useFieldControl(props = {}) {
|
|
1177
|
+
const field = useFieldContext();
|
|
1178
|
+
const generatedId = useId(props.id, "ds-control");
|
|
1179
|
+
const native = props.native ?? true;
|
|
1180
|
+
const id = props.id ?? field?.ids.control ?? generatedId;
|
|
1181
|
+
const invalid = props.invalid ?? field?.invalid ?? false;
|
|
1182
|
+
const required = props.required ?? field?.required ?? false;
|
|
1183
|
+
const disabled = props.disabled ?? field?.disabled;
|
|
1184
|
+
const readOnly = props.readOnly ?? field?.readOnly;
|
|
1185
|
+
const describedBy = joinIds(
|
|
1186
|
+
field?.mounted.description && field.ids.description,
|
|
1187
|
+
field?.mounted.error && field.ids.error,
|
|
1188
|
+
props["aria-describedby"]
|
|
1189
|
+
);
|
|
1190
|
+
const labelledBy = props["aria-labelledby"] ?? (!native && field?.mounted.label ? field.ids.label : void 0);
|
|
1191
|
+
const element = useRef(null);
|
|
1192
|
+
const ref = useCallback((node) => {
|
|
1193
|
+
element.current = node;
|
|
1194
|
+
}, []);
|
|
1195
|
+
useEffect(() => {
|
|
1196
|
+
if (process.env.NODE_ENV === "production" || process.env.NODE_ENV === "test") return;
|
|
1197
|
+
const timer = setTimeout(() => {
|
|
1198
|
+
const node = element.current;
|
|
1199
|
+
if (!node || !node.isConnected || isHiddenFromAssistiveTech(node)) return;
|
|
1200
|
+
if (hasAccessibleName(node)) return;
|
|
1201
|
+
const tag = node.tagName.toLowerCase();
|
|
1202
|
+
const key = `${tag}#${node.getAttribute("name") ?? id}`;
|
|
1203
|
+
errorOnce(
|
|
1204
|
+
"Field",
|
|
1205
|
+
key,
|
|
1206
|
+
`the <${tag}${node.id ? ` id="${node.id}"` : ""}> control has no accessible name. Put it inside a <Field> with a <Label>, or give it aria-label / aria-labelledby.`
|
|
1207
|
+
);
|
|
1208
|
+
}, 0);
|
|
1209
|
+
return () => clearTimeout(timer);
|
|
1210
|
+
}, [id, labelledBy, native]);
|
|
1211
|
+
return {
|
|
1212
|
+
id,
|
|
1213
|
+
name: props.name ?? field?.name,
|
|
1214
|
+
"aria-labelledby": labelledBy,
|
|
1215
|
+
"aria-describedby": describedBy,
|
|
1216
|
+
"aria-invalid": invalid ? true : void 0,
|
|
1217
|
+
// Native controls express it with the `required` attribute; the rest mirror
|
|
1218
|
+
// it in ARIA because a button cannot be `required`.
|
|
1219
|
+
"aria-required": required && !native ? true : void 0,
|
|
1220
|
+
required: required && native ? true : void 0,
|
|
1221
|
+
disabled,
|
|
1222
|
+
readOnly,
|
|
1223
|
+
"data-invalid": invalid ? "" : void 0,
|
|
1224
|
+
"data-disabled": disabled ? "" : void 0,
|
|
1225
|
+
ref
|
|
1226
|
+
};
|
|
1227
|
+
}
|
|
1228
|
+
var PortalContainerContext = createContext(void 0);
|
|
1229
|
+
function usePortalContainerContext() {
|
|
1230
|
+
return useContext(PortalContainerContext) ?? void 0;
|
|
1231
|
+
}
|
|
1232
|
+
var WRAPPER_ATTRIBUTE = "data-ds-portal";
|
|
1233
|
+
function stampScope(wrapper, scope) {
|
|
1234
|
+
const attributes = themeScopeAttributes(scope);
|
|
1235
|
+
for (const [name, value] of Object.entries(attributes)) {
|
|
1236
|
+
if (value === void 0) wrapper.removeAttribute(name);
|
|
1237
|
+
else wrapper.setAttribute(name, value);
|
|
1238
|
+
}
|
|
1239
|
+
wrapper.removeAttribute("style");
|
|
1240
|
+
wrapper.style.display = "contents";
|
|
1241
|
+
if (scope.brandTheme) {
|
|
1242
|
+
for (const [property, value] of Object.entries(scope.brandTheme)) {
|
|
1243
|
+
wrapper.style.setProperty(property, value);
|
|
1244
|
+
}
|
|
1245
|
+
}
|
|
1246
|
+
}
|
|
1247
|
+
function usePortalContainer(container) {
|
|
1248
|
+
const provided = usePortalContainerContext();
|
|
1249
|
+
const scope = useThemeScope();
|
|
1250
|
+
const wrap = container === void 0 && scope !== null;
|
|
1251
|
+
const [wrapper, setWrapper] = useState(null);
|
|
1252
|
+
useLayoutEffect(() => {
|
|
1253
|
+
if (!wrap || !scope) {
|
|
1254
|
+
setWrapper(null);
|
|
1255
|
+
return;
|
|
1256
|
+
}
|
|
1257
|
+
const element = document.createElement("div");
|
|
1258
|
+
element.setAttribute(WRAPPER_ATTRIBUTE, "");
|
|
1259
|
+
stampScope(element, scope);
|
|
1260
|
+
(provided ?? document.body).appendChild(element);
|
|
1261
|
+
setWrapper(element);
|
|
1262
|
+
return () => element.remove();
|
|
1263
|
+
}, [wrap, scope, provided]);
|
|
1264
|
+
if (container !== void 0) return container ?? void 0;
|
|
1265
|
+
if (wrap) return wrapper ?? void 0;
|
|
1266
|
+
return provided;
|
|
1267
|
+
}
|
|
1268
|
+
function withPortalContainer(RadixPortal) {
|
|
1269
|
+
function Portal7(props) {
|
|
1270
|
+
const container = usePortalContainer(props.container);
|
|
1271
|
+
const merged = { ...props, container };
|
|
1272
|
+
return /* @__PURE__ */ jsx(RadixPortal, { ...merged });
|
|
1273
|
+
}
|
|
1274
|
+
Portal7.displayName = RadixPortal.displayName ?? "Portal";
|
|
1275
|
+
return Portal7;
|
|
1276
|
+
}
|
|
1277
|
+
function Portal({ children, container }) {
|
|
1278
|
+
const resolved = usePortalContainer(container);
|
|
1279
|
+
const [mounted, setMounted] = useState(false);
|
|
1280
|
+
useLayoutEffect(() => setMounted(true), []);
|
|
1281
|
+
const target = resolved ?? (mounted ? document.body : null);
|
|
1282
|
+
return target ? createPortal(children, target) : null;
|
|
1283
|
+
}
|
|
1284
|
+
var PRESENCE_ATTRIBUTE = "data-ds-presence";
|
|
1285
|
+
function presence(motion) {
|
|
1286
|
+
return { [PRESENCE_ATTRIBUTE]: motion };
|
|
1287
|
+
}
|
|
1288
|
+
function useExitPresence(ref, open, onExited) {
|
|
1289
|
+
const onExitedRef = React7.useRef(onExited);
|
|
1290
|
+
onExitedRef.current = onExited;
|
|
1291
|
+
React7.useLayoutEffect(() => {
|
|
1292
|
+
if (open) return void 0;
|
|
1293
|
+
const node = ref.current;
|
|
1294
|
+
const running = node && typeof node.getAnimations === "function" ? node.getAnimations().filter((animation) => animation.playState !== "finished") : [];
|
|
1295
|
+
if (running.length === 0) {
|
|
1296
|
+
onExitedRef.current();
|
|
1297
|
+
return void 0;
|
|
1298
|
+
}
|
|
1299
|
+
let active = true;
|
|
1300
|
+
const exit = () => {
|
|
1301
|
+
if (!active) return;
|
|
1302
|
+
active = false;
|
|
1303
|
+
onExitedRef.current();
|
|
1304
|
+
};
|
|
1305
|
+
Promise.allSettled(running.map((animation) => animation.finished)).then(exit);
|
|
1306
|
+
const guard = setTimeout(exit, remainingTime(running) + EXIT_GUARD_GRACE_MS);
|
|
1307
|
+
return () => {
|
|
1308
|
+
active = false;
|
|
1309
|
+
clearTimeout(guard);
|
|
1310
|
+
};
|
|
1311
|
+
}, [open, ref]);
|
|
1312
|
+
}
|
|
1313
|
+
var EXIT_GUARD_GRACE_MS = 50;
|
|
1314
|
+
function remainingTime(animations) {
|
|
1315
|
+
let longest = 0;
|
|
1316
|
+
for (const animation of animations) {
|
|
1317
|
+
const timing = animation.effect?.getComputedTiming();
|
|
1318
|
+
const end = typeof timing?.endTime === "number" ? timing.endTime : 0;
|
|
1319
|
+
const current = typeof animation.currentTime === "number" ? animation.currentTime : 0;
|
|
1320
|
+
longest = Math.max(longest, end - current);
|
|
1321
|
+
}
|
|
1322
|
+
return Number.isFinite(longest) ? longest : 0;
|
|
1323
|
+
}
|
|
1324
|
+
var TooltipProvider = TooltipPrimitive.Provider;
|
|
1325
|
+
var TooltipTrigger = TooltipPrimitive.Trigger;
|
|
1326
|
+
var TooltipPortal = withPortalContainer(TooltipPrimitive.Portal);
|
|
1327
|
+
var Tooltip = ({ delayMs, delayDuration, children, ...props }) => {
|
|
1328
|
+
const shared = useSharedTooltipProvider();
|
|
1329
|
+
const requested = delayDuration ?? delayMs;
|
|
1330
|
+
if (shared) {
|
|
1331
|
+
return /* @__PURE__ */ jsx(
|
|
1332
|
+
TooltipPrimitive.Root,
|
|
1333
|
+
{
|
|
1334
|
+
...requested !== void 0 && { delayDuration: requested },
|
|
1335
|
+
...props,
|
|
1336
|
+
children
|
|
1337
|
+
}
|
|
1338
|
+
);
|
|
1339
|
+
}
|
|
1340
|
+
const resolvedDelay = requested ?? TOOLTIP_DEFAULT_DELAY_MS;
|
|
1341
|
+
return /* @__PURE__ */ jsx(TooltipPrimitive.Provider, { delayDuration: resolvedDelay, children: /* @__PURE__ */ jsx(TooltipPrimitive.Root, { delayDuration: resolvedDelay, ...props, children }) });
|
|
1342
|
+
};
|
|
1343
|
+
Tooltip.displayName = "Tooltip";
|
|
1344
|
+
var TOOLTIP_MAX_WIDTH = {
|
|
1345
|
+
xs: "ds:max-w-xs",
|
|
1346
|
+
sm: "ds:max-w-sm",
|
|
1347
|
+
md: "ds:max-w-md",
|
|
1348
|
+
none: "ds:max-w-none"
|
|
1349
|
+
};
|
|
1350
|
+
var TooltipContent = React7.forwardRef(({ className, sideOffset = 6, maxWidth = "xs", ...props }, ref) => /* @__PURE__ */ jsx(TooltipPortal, { children: /* @__PURE__ */ jsx(
|
|
1351
|
+
TooltipPrimitive.Content,
|
|
1352
|
+
{
|
|
1353
|
+
ref,
|
|
1354
|
+
sideOffset,
|
|
1355
|
+
...slot(tooltipAnatomy, "content"),
|
|
1356
|
+
...presence("floating"),
|
|
1357
|
+
className: cn(
|
|
1358
|
+
"ds:rounded-input ds:border-rule-strong ds:bg-surface ds:z-[var(--z-tooltip)]",
|
|
1359
|
+
TOOLTIP_MAX_WIDTH[maxWidth],
|
|
1360
|
+
"ds:border ds:px-2.5 ds:py-1.5",
|
|
1361
|
+
"ds:font-body ds:text-fg ds:shadow-pop ds:text-xs ds:leading-tight",
|
|
1362
|
+
className
|
|
1363
|
+
),
|
|
1364
|
+
...props
|
|
1365
|
+
}
|
|
1366
|
+
) }));
|
|
1367
|
+
TooltipContent.displayName = TooltipPrimitive.Content.displayName;
|
|
1368
|
+
|
|
1369
|
+
// src/primitives/behavior/control-size.ts
|
|
1370
|
+
var CONTROL_SIZE_CLASSES = {
|
|
1371
|
+
xs: "ds:h-(--control-height-xs) ds:px-(--control-padding-x-xs) ds:text-(length:--control-font-size-xs) ds:gap-(--control-gap-xs) ds:[&_svg]:size-(--control-icon-xs)",
|
|
1372
|
+
sm: "ds:h-(--control-height-sm) ds:px-(--control-padding-x-sm) ds:text-(length:--control-font-size-sm) ds:gap-(--control-gap-sm) ds:[&_svg]:size-(--control-icon-sm)",
|
|
1373
|
+
md: "ds:h-(--control-height-md) ds:px-(--control-padding-x-md) ds:text-(length:--control-font-size-md) ds:gap-(--control-gap-md) ds:[&_svg]:size-(--control-icon-md)",
|
|
1374
|
+
lg: "ds:h-(--control-height-lg) ds:px-(--control-padding-x-lg) ds:text-(length:--control-font-size-lg) ds:gap-(--control-gap-lg) ds:[&_svg]:size-(--control-icon-lg)",
|
|
1375
|
+
xl: "ds:h-(--control-height-xl) ds:px-(--control-padding-x-xl) ds:text-(length:--control-font-size-xl) ds:gap-(--control-gap-xl) ds:[&_svg]:size-(--control-icon-xl)"
|
|
1376
|
+
};
|
|
1377
|
+
var SQUARE_CONTROL_SIZE_CLASSES = {
|
|
1378
|
+
xs: "ds:size-(--control-height-xs) ds:[&_svg]:size-(--control-icon-xs)",
|
|
1379
|
+
sm: "ds:size-(--control-height-sm) ds:[&_svg]:size-(--control-icon-sm)",
|
|
1380
|
+
md: "ds:size-(--control-height-md) ds:[&_svg]:size-(--control-icon-md)",
|
|
1381
|
+
lg: "ds:size-(--control-height-lg) ds:[&_svg]:size-(--control-icon-lg)",
|
|
1382
|
+
xl: "ds:size-(--control-height-xl) ds:[&_svg]:size-(--control-icon-xl)"
|
|
1383
|
+
};
|
|
1384
|
+
var CONTROL_GAP_CLASSES = {
|
|
1385
|
+
xs: "ds:gap-(--control-gap-xs)",
|
|
1386
|
+
sm: "ds:gap-(--control-gap-sm)",
|
|
1387
|
+
md: "ds:gap-(--control-gap-md)",
|
|
1388
|
+
lg: "ds:gap-(--control-gap-lg)",
|
|
1389
|
+
xl: "ds:gap-(--control-gap-xl)"
|
|
1390
|
+
};
|
|
1391
|
+
function iconButtonVariants({
|
|
1392
|
+
variant,
|
|
1393
|
+
intent,
|
|
1394
|
+
size = "md",
|
|
1395
|
+
className
|
|
1396
|
+
} = {}) {
|
|
1397
|
+
const { look } = resolveButtonStyle({ variant, intent });
|
|
1398
|
+
return cn(
|
|
1399
|
+
buttonBase({ look, size: null }),
|
|
1400
|
+
"ds:shrink-0 ds:p-0",
|
|
1401
|
+
SQUARE_CONTROL_SIZE_CLASSES[size ?? "md"],
|
|
1402
|
+
className
|
|
1403
|
+
);
|
|
1404
|
+
}
|
|
1405
|
+
var IconButton = forwardRef(function IconButton2({
|
|
1406
|
+
label,
|
|
1407
|
+
icon,
|
|
1408
|
+
children,
|
|
1409
|
+
variant,
|
|
1410
|
+
intent,
|
|
1411
|
+
size = "md",
|
|
1412
|
+
tooltip = true,
|
|
1413
|
+
tooltipSide,
|
|
1414
|
+
asChild = false,
|
|
1415
|
+
loading,
|
|
1416
|
+
pressed,
|
|
1417
|
+
disabled,
|
|
1418
|
+
className,
|
|
1419
|
+
...props
|
|
1420
|
+
}, ref) {
|
|
1421
|
+
if (process.env.NODE_ENV !== "production" && typeof label !== "string") {
|
|
1422
|
+
throw new Error(
|
|
1423
|
+
"[IconButton] `label` is required: it is the accessible name of an icon-only control (and its default tooltip)."
|
|
1424
|
+
);
|
|
1425
|
+
}
|
|
1426
|
+
const style = resolveButtonStyle({ variant, intent });
|
|
1427
|
+
const state = stateAttributes({
|
|
1428
|
+
variant: style.variant,
|
|
1429
|
+
intent: style.intent,
|
|
1430
|
+
size,
|
|
1431
|
+
disabled: asChild ? void 0 : disabled || loading,
|
|
1432
|
+
loading: asChild ? void 0 : loading,
|
|
1433
|
+
pressed
|
|
1434
|
+
});
|
|
1435
|
+
const classes = iconButtonVariants({ variant, intent, size, className });
|
|
1436
|
+
const glyph = icon ?? children;
|
|
1437
|
+
const control = asChild ? /* @__PURE__ */ jsx(
|
|
1438
|
+
Slot,
|
|
1439
|
+
{
|
|
1440
|
+
ref,
|
|
1441
|
+
"aria-label": label,
|
|
1442
|
+
"aria-pressed": pressed,
|
|
1443
|
+
...slot(iconButtonAnatomy, "root"),
|
|
1444
|
+
...state,
|
|
1445
|
+
className: classes,
|
|
1446
|
+
...props,
|
|
1447
|
+
children: glyph
|
|
1448
|
+
}
|
|
1449
|
+
) : /* @__PURE__ */ jsx(
|
|
1450
|
+
"button",
|
|
1451
|
+
{
|
|
1452
|
+
ref,
|
|
1453
|
+
type: "button",
|
|
1454
|
+
"aria-label": label,
|
|
1455
|
+
"aria-pressed": pressed,
|
|
1456
|
+
"aria-busy": loading || void 0,
|
|
1457
|
+
disabled: disabled || loading,
|
|
1458
|
+
...slot(iconButtonAnatomy, "root"),
|
|
1459
|
+
...state,
|
|
1460
|
+
className: classes,
|
|
1461
|
+
...props,
|
|
1462
|
+
children: loading ? (
|
|
1463
|
+
// `size={null}`: the glyph box is the button's `--ds-control-icon-*`.
|
|
1464
|
+
/* @__PURE__ */ jsx(Spinner, { size: null, ...slot(iconButtonAnatomy, "spinner") })
|
|
1465
|
+
) : /* @__PURE__ */ jsx(
|
|
1466
|
+
"span",
|
|
1467
|
+
{
|
|
1468
|
+
...slot(iconButtonAnatomy, "icon"),
|
|
1469
|
+
className: "ds:inline-flex ds:shrink-0",
|
|
1470
|
+
"aria-hidden": "true",
|
|
1471
|
+
children: glyph
|
|
1472
|
+
}
|
|
1473
|
+
)
|
|
1474
|
+
}
|
|
1475
|
+
);
|
|
1476
|
+
if (tooltip === false || tooltip === null || tooltip === void 0) return control;
|
|
1477
|
+
return /* @__PURE__ */ jsxs(Tooltip, { children: [
|
|
1478
|
+
/* @__PURE__ */ jsx(TooltipTrigger, { asChild: true, children: control }),
|
|
1479
|
+
/* @__PURE__ */ jsx(TooltipContent, { ...tooltipSide !== void 0 && { side: tooltipSide }, children: tooltip === true ? label : tooltip })
|
|
1480
|
+
] });
|
|
1481
|
+
});
|
|
1482
|
+
IconButton.displayName = "IconButton";
|
|
1483
|
+
function useControllableState({
|
|
1484
|
+
prop,
|
|
1485
|
+
defaultProp,
|
|
1486
|
+
onChange
|
|
1487
|
+
}) {
|
|
1488
|
+
const [uncontrolled, setUncontrolled] = useState(defaultProp);
|
|
1489
|
+
const isControlled = prop !== void 0;
|
|
1490
|
+
const value = isControlled ? prop : uncontrolled;
|
|
1491
|
+
const latest = useRef({ value, isControlled, onChange });
|
|
1492
|
+
latest.current = { value, isControlled, onChange };
|
|
1493
|
+
const setValue = useCallback((next) => {
|
|
1494
|
+
const current = latest.current;
|
|
1495
|
+
const resolved = typeof next === "function" ? next(current.value) : next;
|
|
1496
|
+
if (Object.is(resolved, current.value)) return;
|
|
1497
|
+
if (!current.isControlled) setUncontrolled(resolved);
|
|
1498
|
+
latest.current = { ...current, value: resolved };
|
|
1499
|
+
current.onChange?.(resolved);
|
|
1500
|
+
}, []);
|
|
1501
|
+
return [value, setValue];
|
|
1502
|
+
}
|
|
1503
|
+
|
|
1504
|
+
// src/primitives/behavior/collection/item-attributes.ts
|
|
1505
|
+
function itemSlot(anatomy) {
|
|
1506
|
+
return slot(anatomy, "item");
|
|
1507
|
+
}
|
|
1508
|
+
function listItemAttributes(anatomy, { id, highlighted, selected, disabled, cmdkCompat } = {}) {
|
|
1509
|
+
const attributes = {
|
|
1510
|
+
...itemSlot(anatomy),
|
|
1511
|
+
role: "option",
|
|
1512
|
+
"aria-selected": selected === true
|
|
1513
|
+
};
|
|
1514
|
+
if (id !== void 0) attributes.id = id;
|
|
1515
|
+
if (disabled) attributes["aria-disabled"] = true;
|
|
1516
|
+
if (highlighted) attributes["data-highlighted"] = "";
|
|
1517
|
+
if (selected) attributes["data-selected"] = "";
|
|
1518
|
+
if (disabled) attributes["data-disabled"] = "";
|
|
1519
|
+
if (cmdkCompat) attributes["cmdk-item"] = "";
|
|
1520
|
+
return attributes;
|
|
1521
|
+
}
|
|
1522
|
+
function optionElementId(listId, value) {
|
|
1523
|
+
return `${listId}-option-${encodeURIComponent(value)}`;
|
|
1524
|
+
}
|
|
1525
|
+
|
|
1526
|
+
// src/primitives/behavior/collection/item-recipe.ts
|
|
1527
|
+
var LIST_ITEM_BOX = {
|
|
1528
|
+
select: "ds:rounded-surface-sm ds:relative ds:flex ds:w-full ds:cursor-default ds:items-center ds:gap-2 ds:py-1.5 ds:pr-8 ds:pl-2",
|
|
1529
|
+
menu: "ds:rounded-surface-sm ds:relative ds:flex ds:cursor-default ds:items-center ds:gap-2 ds:px-2 ds:py-1.5",
|
|
1530
|
+
"menu-indicator": "ds:rounded-surface-sm ds:relative ds:flex ds:cursor-default ds:items-center ds:gap-2 ds:py-1.5 ds:pr-2 ds:pl-8"
|
|
1531
|
+
};
|
|
1532
|
+
var LIST_ITEM_INTERACTION = "ds:outline-none ds:select-none";
|
|
1533
|
+
var LIST_ITEM_INK = {
|
|
1534
|
+
neutral: "ds:text-fg-2",
|
|
1535
|
+
menu: "ds:text-menu-item-fg"
|
|
1536
|
+
};
|
|
1537
|
+
var LIST_ITEM_MOTION = "ds:transition-colors ds:duration-[var(--duration-fast)] ds:ease-[var(--ease-out-quart)] ds:motion-reduce:transition-none";
|
|
1538
|
+
var LIST_ITEM_HIGHLIGHTED = {
|
|
1539
|
+
neutral: {
|
|
1540
|
+
focus: "ds:focus:bg-bg-2 ds:focus:text-fg",
|
|
1541
|
+
cmdk: "ds:data-[selected=true]:bg-bg-2 ds:data-[selected=true]:text-fg",
|
|
1542
|
+
"data-highlighted": "ds:data-[highlighted]:bg-bg-2 ds:data-[highlighted]:text-fg"
|
|
1543
|
+
},
|
|
1544
|
+
menu: {
|
|
1545
|
+
focus: "ds:focus:bg-menu-item-hover-bg ds:focus:text-menu-item-hover-fg"
|
|
1546
|
+
}
|
|
1547
|
+
};
|
|
1548
|
+
var LIST_ITEM_SELECTED = {
|
|
1549
|
+
"radix-checked": "ds:data-[state=checked]:bg-brand-bg ds:data-[state=checked]:text-brand",
|
|
1550
|
+
"aria-selected": "ds:aria-selected:bg-brand-bg ds:aria-selected:text-brand",
|
|
1551
|
+
none: ""
|
|
1552
|
+
};
|
|
1553
|
+
var LIST_ITEM_DISABLED = "ds:data-[disabled]:text-fg-disabled ds:data-[disabled]:pointer-events-none";
|
|
1554
|
+
var LIST_ITEM_GLYPH = "ds:[&_svg]:size-4 ds:[&_svg]:shrink-0";
|
|
1555
|
+
var LIST_ITEM_INDICATOR_WELL = {
|
|
1556
|
+
end: "ds:absolute ds:right-2 ds:flex ds:size-4 ds:items-center ds:justify-center",
|
|
1557
|
+
start: "ds:absolute ds:left-2 ds:flex ds:size-4 ds:items-center ds:justify-center"
|
|
1558
|
+
};
|
|
1559
|
+
var LIST_GROUP_HEADING_INK = {
|
|
1560
|
+
neutral: "ds:text-fg-3",
|
|
1561
|
+
menu: "ds:text-menu-label-fg"
|
|
1562
|
+
};
|
|
1563
|
+
var LIST_GROUP_HEADING_BOX = "ds:px-2 ds:py-1.5 ds:font-mono";
|
|
1564
|
+
var LIST_GROUP_HEADING_TYPE = "ds:tracking-wider ds:uppercase";
|
|
1565
|
+
function groupHeadingClasses({
|
|
1566
|
+
palette,
|
|
1567
|
+
labelSize
|
|
1568
|
+
}) {
|
|
1569
|
+
return [
|
|
1570
|
+
LIST_GROUP_HEADING_INK[palette],
|
|
1571
|
+
LIST_GROUP_HEADING_BOX,
|
|
1572
|
+
labelSize,
|
|
1573
|
+
LIST_GROUP_HEADING_TYPE
|
|
1574
|
+
].join(" ");
|
|
1575
|
+
}
|
|
1576
|
+
var LIST_SEPARATOR = {
|
|
1577
|
+
neutral: "ds:bg-rule ds:-mx-1 ds:my-1 ds:h-px",
|
|
1578
|
+
menu: "ds:bg-menu-border ds:-mx-1 ds:my-1 ds:h-px"
|
|
1579
|
+
};
|
|
1580
|
+
function listItemClasses({
|
|
1581
|
+
frame,
|
|
1582
|
+
labelSize,
|
|
1583
|
+
palette,
|
|
1584
|
+
highlight,
|
|
1585
|
+
selected,
|
|
1586
|
+
glyph = true
|
|
1587
|
+
}) {
|
|
1588
|
+
const highlighted = LIST_ITEM_HIGHLIGHTED[palette][highlight];
|
|
1589
|
+
if (highlighted === void 0) {
|
|
1590
|
+
throw new TypeError(
|
|
1591
|
+
`collection: no highlighted row for palette ${JSON.stringify(palette)} with ${JSON.stringify(highlight)}; write the literal in item-recipe.ts`
|
|
1592
|
+
);
|
|
1593
|
+
}
|
|
1594
|
+
return [
|
|
1595
|
+
LIST_ITEM_BOX[frame],
|
|
1596
|
+
labelSize,
|
|
1597
|
+
LIST_ITEM_INTERACTION,
|
|
1598
|
+
LIST_ITEM_INK[palette],
|
|
1599
|
+
LIST_ITEM_MOTION,
|
|
1600
|
+
highlighted,
|
|
1601
|
+
LIST_ITEM_SELECTED[selected],
|
|
1602
|
+
LIST_ITEM_DISABLED,
|
|
1603
|
+
glyph ? LIST_ITEM_GLYPH : ""
|
|
1604
|
+
].filter(Boolean).join(" ");
|
|
1605
|
+
}
|
|
1606
|
+
|
|
1607
|
+
// src/primitives/behavior/button-type.ts
|
|
1608
|
+
function describeForm(form) {
|
|
1609
|
+
const id = form.getAttribute("id");
|
|
1610
|
+
if (id) return `form#${id}`;
|
|
1611
|
+
const name = form.getAttribute("name");
|
|
1612
|
+
if (name) return `form[name="${name}"]`;
|
|
1613
|
+
const label = form.getAttribute("aria-label");
|
|
1614
|
+
if (label) return `form[aria-label="${label}"]`;
|
|
1615
|
+
const action = form.getAttribute("action");
|
|
1616
|
+
if (action) return `form[action="${action}"]`;
|
|
1617
|
+
return "form";
|
|
1618
|
+
}
|
|
1619
|
+
var FORM_BRIDGE_DUPLICATE_ID = "C-HIDDEN-MIRRORS";
|
|
1620
|
+
function serializeFormValue(value, { submitEmpty = true } = {}) {
|
|
1621
|
+
if (Array.isArray(value)) return [...value];
|
|
1622
|
+
if (value == null || value === "") return submitEmpty ? [""] : [];
|
|
1623
|
+
return [value];
|
|
1624
|
+
}
|
|
1625
|
+
var PROXY_STYLE = {
|
|
1626
|
+
position: "absolute",
|
|
1627
|
+
width: 1,
|
|
1628
|
+
height: 1,
|
|
1629
|
+
padding: 0,
|
|
1630
|
+
margin: -1,
|
|
1631
|
+
overflow: "hidden",
|
|
1632
|
+
clip: "rect(0, 0, 0, 0)",
|
|
1633
|
+
whiteSpace: "nowrap",
|
|
1634
|
+
border: 0,
|
|
1635
|
+
opacity: 0,
|
|
1636
|
+
pointerEvents: "none"
|
|
1637
|
+
};
|
|
1638
|
+
var noop = () => {
|
|
1639
|
+
};
|
|
1640
|
+
var forwardFocus = (target) => {
|
|
1641
|
+
const element = target?.current;
|
|
1642
|
+
if (element && element.ownerDocument.activeElement !== element) element.focus();
|
|
1643
|
+
};
|
|
1644
|
+
function FormBridge({
|
|
1645
|
+
name,
|
|
1646
|
+
value,
|
|
1647
|
+
submitEmpty = true,
|
|
1648
|
+
form,
|
|
1649
|
+
disabled = false,
|
|
1650
|
+
required = false,
|
|
1651
|
+
focusTarget,
|
|
1652
|
+
onReset
|
|
1653
|
+
}) {
|
|
1654
|
+
const instance = useId$1();
|
|
1655
|
+
const anchorRef = useRef(null);
|
|
1656
|
+
const values = name ? serializeFormValue(value, { submitEmpty }) : [];
|
|
1657
|
+
const filled = values.some((entry) => entry !== "");
|
|
1658
|
+
useFormReset(anchorRef, onReset, name, form);
|
|
1659
|
+
useDuplicateNameWarning(anchorRef, instance, name, form, disabled ? 0 : values.length);
|
|
1660
|
+
if (!name) return null;
|
|
1661
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
1662
|
+
values.map((entry, index) => /* @__PURE__ */ jsx(
|
|
1663
|
+
"input",
|
|
1664
|
+
{
|
|
1665
|
+
ref: index === 0 ? anchorRef : void 0,
|
|
1666
|
+
type: "hidden",
|
|
1667
|
+
name,
|
|
1668
|
+
value: entry,
|
|
1669
|
+
form,
|
|
1670
|
+
disabled,
|
|
1671
|
+
"data-form-bridge": instance
|
|
1672
|
+
},
|
|
1673
|
+
index
|
|
1674
|
+
)),
|
|
1675
|
+
values.length === 0 && // Resolves the form for the reset listener and the duplicate check;
|
|
1676
|
+
// disabled and unnamed, so it is never submitted.
|
|
1677
|
+
/* @__PURE__ */ jsx("input", { ref: anchorRef, type: "hidden", form, disabled: true, "data-form-bridge": instance }),
|
|
1678
|
+
required && !disabled && /* @__PURE__ */ jsx(
|
|
1679
|
+
"input",
|
|
1680
|
+
{
|
|
1681
|
+
type: "text",
|
|
1682
|
+
"aria-hidden": "true",
|
|
1683
|
+
tabIndex: -1,
|
|
1684
|
+
required: true,
|
|
1685
|
+
form,
|
|
1686
|
+
value: filled ? "filled" : "",
|
|
1687
|
+
onChange: noop,
|
|
1688
|
+
onInvalid: () => forwardFocus(focusTarget),
|
|
1689
|
+
onFocus: () => forwardFocus(focusTarget),
|
|
1690
|
+
style: PROXY_STYLE,
|
|
1691
|
+
"data-form-bridge-validation": instance
|
|
1692
|
+
}
|
|
1693
|
+
)
|
|
1694
|
+
] });
|
|
1695
|
+
}
|
|
1696
|
+
function useFormReset(anchorRef, onReset, name, form) {
|
|
1697
|
+
const latest = useRef(onReset);
|
|
1698
|
+
latest.current = onReset;
|
|
1699
|
+
useEffect(() => {
|
|
1700
|
+
const owner = anchorRef.current?.form;
|
|
1701
|
+
if (!owner || !name) return;
|
|
1702
|
+
const handle = () => latest.current?.();
|
|
1703
|
+
owner.addEventListener("reset", handle);
|
|
1704
|
+
return () => owner.removeEventListener("reset", handle);
|
|
1705
|
+
}, [anchorRef, name, form]);
|
|
1706
|
+
}
|
|
1707
|
+
function useDuplicateNameWarning(anchorRef, instance, name, form, ownCount) {
|
|
1708
|
+
useEffect(() => {
|
|
1709
|
+
if (!name || ownCount === 0 || !devWarningsEnabled()) return;
|
|
1710
|
+
const owner = anchorRef.current?.form;
|
|
1711
|
+
if (!owner) return;
|
|
1712
|
+
const others = Array.from(owner.elements).filter((element) => {
|
|
1713
|
+
const control = element;
|
|
1714
|
+
return control.name === name && control.getAttribute("data-form-bridge") !== instance && !control.matches(":disabled");
|
|
1715
|
+
});
|
|
1716
|
+
if (others.length === 0) return;
|
|
1717
|
+
const where = describeForm(owner);
|
|
1718
|
+
warnOnce(
|
|
1719
|
+
FORM_BRIDGE_DUPLICATE_ID,
|
|
1720
|
+
`${where}::${name}`,
|
|
1721
|
+
`field "${name}" in ${where} is also submitted by ${others.length} other control${others.length === 1 ? "" : "s"} with the same name (a hidden <input> mirror, most likely), so FormData carries it twice and formData.get("${name}") returns whichever comes first in DOM order. Remove the mirror, or drop \`name\` from the design-system control.`
|
|
1722
|
+
);
|
|
1723
|
+
}, [anchorRef, instance, name, form, ownCount]);
|
|
1724
|
+
}
|
|
1725
|
+
var SelectRoot = SelectPrimitive.Root;
|
|
1726
|
+
var SelectGroup = SelectPrimitive.Group;
|
|
1727
|
+
var SelectValue = SelectPrimitive.Value;
|
|
1728
|
+
function useTriggerOpen(node) {
|
|
1729
|
+
const [open, setOpen] = React7.useState(false);
|
|
1730
|
+
React7.useEffect(() => {
|
|
1731
|
+
if (!node) return;
|
|
1732
|
+
const sync = () => setOpen(node.getAttribute("data-state") === "open");
|
|
1733
|
+
sync();
|
|
1734
|
+
const observer = new MutationObserver(sync);
|
|
1735
|
+
observer.observe(node, { attributes: true, attributeFilter: ["data-state"] });
|
|
1736
|
+
return () => observer.disconnect();
|
|
1737
|
+
}, [node]);
|
|
1738
|
+
return open;
|
|
1739
|
+
}
|
|
1740
|
+
var SelectTrigger = React7.forwardRef(({ className, children, tabIndex, size, classNames, ...props }, ref) => {
|
|
1741
|
+
const [node, setNode] = React7.useState(null);
|
|
1742
|
+
const open = useTriggerOpen(node);
|
|
1743
|
+
const composedRef = React7.useCallback(
|
|
1744
|
+
(element) => {
|
|
1745
|
+
setNode(element);
|
|
1746
|
+
if (typeof ref === "function") ref(element);
|
|
1747
|
+
else if (ref) ref.current = element;
|
|
1748
|
+
},
|
|
1749
|
+
[ref]
|
|
1750
|
+
);
|
|
1751
|
+
return /* @__PURE__ */ jsxs(
|
|
1752
|
+
SelectPrimitive.Trigger,
|
|
1753
|
+
{
|
|
1754
|
+
ref: composedRef,
|
|
1755
|
+
tabIndex: open ? -1 : tabIndex,
|
|
1756
|
+
...slot(selectAnatomy, "trigger"),
|
|
1757
|
+
...stateAttributes({ size: size ?? void 0 }),
|
|
1758
|
+
className: cn(
|
|
1759
|
+
// The legacy geometry row (`h-9 gap-2 px-3 py-2 text-[13px]`) is the
|
|
1760
|
+
// scale's `md` in pixels; it stays inline, byte for byte, until D5
|
|
1761
|
+
// settles the size numbers. A `size` swaps it for the token row.
|
|
1762
|
+
size == null ? "ds:rounded-input ds:border-field-border ds:bg-surface ds:font-body ds:text-fg ds:flex ds:h-9 ds:w-full ds:items-center ds:justify-between ds:gap-2 ds:border ds:px-3 ds:py-2 ds:text-[13px]" : cn(
|
|
1763
|
+
"ds:rounded-input ds:border-field-border ds:bg-surface ds:font-body ds:text-fg ds:flex ds:w-full ds:items-center ds:justify-between ds:border ds:py-2",
|
|
1764
|
+
CONTROL_SIZE_CLASSES[size]
|
|
1765
|
+
),
|
|
1766
|
+
"ds:transition-[color,background-color,border-color,box-shadow] ds:duration-[var(--duration-fast)] ds:ease-[var(--ease-out-quart)]",
|
|
1767
|
+
"ds:motion-reduce:transition-none",
|
|
1768
|
+
"ds:placeholder:text-fg-4",
|
|
1769
|
+
"ds:not-disabled:hover:border-field-border-hover",
|
|
1770
|
+
"ds:focus-visible:[border-color:var(--focus-ring-border)] ds:focus-visible:[box-shadow:var(--shadow-focus-ring-field)] ds:focus-visible:outline-none",
|
|
1771
|
+
"ds:disabled:bg-bg-disabled ds:disabled:text-fg-disabled ds:disabled:cursor-not-allowed",
|
|
1772
|
+
"ds:data-[placeholder]:text-fg-4",
|
|
1773
|
+
"ds:aria-[invalid=true]:border-field-border-invalid ds:aria-[invalid=true]:focus-visible:border-danger-fg",
|
|
1774
|
+
"ds:aria-[invalid=true]:focus-visible:[box-shadow:0_0_0_2px_var(--color-danger-bg)]",
|
|
1775
|
+
"ds:[&>span]:line-clamp-1 ds:[&>span]:text-left",
|
|
1776
|
+
className
|
|
1777
|
+
),
|
|
1778
|
+
...props,
|
|
1779
|
+
children: [
|
|
1780
|
+
classNames?.value !== void 0 ? /* @__PURE__ */ jsx("span", { ...slot(selectAnatomy, "value"), className: classNames.value, children }) : children,
|
|
1781
|
+
/* @__PURE__ */ jsx(SelectPrimitive.Icon, { asChild: true, children: /* @__PURE__ */ jsx(
|
|
1782
|
+
ChevronDownIcon,
|
|
1783
|
+
{
|
|
1784
|
+
...slot(selectAnatomy, "icon"),
|
|
1785
|
+
className: cn(
|
|
1786
|
+
"ds:text-fg-3 ds:size-4 ds:shrink-0 ds:translate-y-px ds:transition-transform ds:duration-[var(--duration-fast)] ds:ease-[var(--ease-out-quart)] ds:data-[state=open]:rotate-180 ds:motion-reduce:transition-none",
|
|
1787
|
+
classNames?.icon
|
|
1788
|
+
),
|
|
1789
|
+
"aria-hidden": "true"
|
|
1790
|
+
}
|
|
1791
|
+
) })
|
|
1792
|
+
]
|
|
1793
|
+
}
|
|
1794
|
+
);
|
|
1795
|
+
});
|
|
1796
|
+
SelectTrigger.displayName = SelectPrimitive.Trigger.displayName;
|
|
1797
|
+
var SelectScrollUpButton = React7.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
1798
|
+
SelectPrimitive.ScrollUpButton,
|
|
1799
|
+
{
|
|
1800
|
+
ref,
|
|
1801
|
+
...slot(selectAnatomy, "scroll-up-button"),
|
|
1802
|
+
className: cn(
|
|
1803
|
+
"ds:text-fg-3 ds:flex ds:cursor-default ds:items-center ds:justify-center ds:py-1",
|
|
1804
|
+
className
|
|
1805
|
+
),
|
|
1806
|
+
...props,
|
|
1807
|
+
children: /* @__PURE__ */ jsx(ChevronUpIcon, { className: "ds:size-4", "aria-hidden": "true" })
|
|
1808
|
+
}
|
|
1809
|
+
));
|
|
1810
|
+
SelectScrollUpButton.displayName = SelectPrimitive.ScrollUpButton.displayName;
|
|
1811
|
+
var SelectScrollDownButton = React7.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
1812
|
+
SelectPrimitive.ScrollDownButton,
|
|
1813
|
+
{
|
|
1814
|
+
ref,
|
|
1815
|
+
...slot(selectAnatomy, "scroll-down-button"),
|
|
1816
|
+
className: cn(
|
|
1817
|
+
"ds:text-fg-3 ds:flex ds:cursor-default ds:items-center ds:justify-center ds:py-1",
|
|
1818
|
+
className
|
|
1819
|
+
),
|
|
1820
|
+
...props,
|
|
1821
|
+
children: /* @__PURE__ */ jsx(ChevronDownIcon, { className: "ds:size-4", "aria-hidden": "true" })
|
|
1822
|
+
}
|
|
1823
|
+
));
|
|
1824
|
+
SelectScrollDownButton.displayName = SelectPrimitive.ScrollDownButton.displayName;
|
|
1825
|
+
var SelectPortal = withPortalContainer(SelectPrimitive.Portal);
|
|
1826
|
+
var SelectContent = React7.forwardRef(({ className, children, position = "popper", classNames, ...props }, ref) => /* @__PURE__ */ jsx(SelectPortal, { children: /* @__PURE__ */ jsxs(
|
|
1827
|
+
SelectPrimitive.Content,
|
|
1828
|
+
{
|
|
1829
|
+
ref,
|
|
1830
|
+
position,
|
|
1831
|
+
...slot(selectAnatomy, "content"),
|
|
1832
|
+
className: cn(
|
|
1833
|
+
"ds:rounded-card ds:border-rule ds:bg-surface ds:text-fg ds:shadow-pop ds:relative ds:z-[var(--z-dropdown)] ds:max-h-(--radix-select-content-available-height) ds:min-w-[8rem] ds:overflow-hidden ds:border",
|
|
1834
|
+
"ds:data-[state=open]:animate-in ds:data-[state=closed]:animate-out",
|
|
1835
|
+
"ds:data-[state=closed]:fade-out-0 ds:data-[state=open]:fade-in-0",
|
|
1836
|
+
"ds:data-[state=closed]:zoom-out-95 ds:data-[state=open]:zoom-in-95",
|
|
1837
|
+
"ds:data-[side=bottom]:slide-in-from-top-2 ds:data-[side=left]:slide-in-from-right-2",
|
|
1838
|
+
"ds:data-[side=right]:slide-in-from-left-2 ds:data-[side=top]:slide-in-from-bottom-2",
|
|
1839
|
+
"ds:motion-reduce:transition-none",
|
|
1840
|
+
position === "popper" && "ds:data-[side=bottom]:translate-y-1 ds:data-[side=left]:-translate-x-1 ds:data-[side=right]:translate-x-1 ds:data-[side=top]:-translate-y-1",
|
|
1841
|
+
className
|
|
1842
|
+
),
|
|
1843
|
+
...props,
|
|
1844
|
+
children: [
|
|
1845
|
+
/* @__PURE__ */ jsx(SelectScrollUpButton, {}),
|
|
1846
|
+
/* @__PURE__ */ jsx(
|
|
1847
|
+
SelectPrimitive.Viewport,
|
|
1848
|
+
{
|
|
1849
|
+
...slot(selectAnatomy, "viewport"),
|
|
1850
|
+
className: cn(
|
|
1851
|
+
"ds:p-1",
|
|
1852
|
+
position === "popper" && "ds:h-(--radix-select-trigger-height) ds:w-full ds:min-w-(--radix-select-trigger-width)",
|
|
1853
|
+
classNames?.viewport
|
|
1854
|
+
),
|
|
1855
|
+
children
|
|
1856
|
+
}
|
|
1857
|
+
),
|
|
1858
|
+
/* @__PURE__ */ jsx(SelectScrollDownButton, {})
|
|
1859
|
+
]
|
|
1860
|
+
}
|
|
1861
|
+
) }));
|
|
1862
|
+
SelectContent.displayName = SelectPrimitive.Content.displayName;
|
|
1863
|
+
var SelectLabel = React7.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
1864
|
+
SelectPrimitive.Label,
|
|
1865
|
+
{
|
|
1866
|
+
ref,
|
|
1867
|
+
...slot(selectAnatomy, "label"),
|
|
1868
|
+
className: cn(
|
|
1869
|
+
groupHeadingClasses({ palette: "neutral", labelSize: "ds:text-[11px]" }),
|
|
1870
|
+
className
|
|
1871
|
+
),
|
|
1872
|
+
...props
|
|
1873
|
+
}
|
|
1874
|
+
));
|
|
1875
|
+
SelectLabel.displayName = SelectPrimitive.Label.displayName;
|
|
1876
|
+
var SelectItem = React7.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ jsxs(
|
|
1877
|
+
SelectPrimitive.Item,
|
|
1878
|
+
{
|
|
1879
|
+
ref,
|
|
1880
|
+
...itemSlot(selectAnatomy),
|
|
1881
|
+
className: cn(
|
|
1882
|
+
// Radix focuses the highlighted row and stamps `data-state="checked"`
|
|
1883
|
+
// on the selected one, so those are the selectors the rows read. The
|
|
1884
|
+
// label size is the scale's `md` (13px, the row's size since 1.0):
|
|
1885
|
+
// W4-08 took it from the control tokens with zero diff
|
|
1886
|
+
// (`tests/browser/select-form.test.tsx`).
|
|
1887
|
+
listItemClasses({
|
|
1888
|
+
frame: "select",
|
|
1889
|
+
labelSize: "ds:text-(length:--control-font-size-md)",
|
|
1890
|
+
palette: "neutral",
|
|
1891
|
+
highlight: "focus",
|
|
1892
|
+
selected: "radix-checked"
|
|
1893
|
+
}),
|
|
1894
|
+
className
|
|
1895
|
+
),
|
|
1896
|
+
...props,
|
|
1897
|
+
children: [
|
|
1898
|
+
/* @__PURE__ */ jsx(SelectPrimitive.ItemText, { children }),
|
|
1899
|
+
/* @__PURE__ */ jsx("span", { className: LIST_ITEM_INDICATOR_WELL.end, children: /* @__PURE__ */ jsx(SelectPrimitive.ItemIndicator, { ...slot(selectAnatomy, "item-indicator"), children: /* @__PURE__ */ jsx(CheckIcon, { className: "ds:size-3.5", "aria-hidden": "true" }) }) })
|
|
1900
|
+
]
|
|
1901
|
+
}
|
|
1902
|
+
));
|
|
1903
|
+
SelectItem.displayName = SelectPrimitive.Item.displayName;
|
|
1904
|
+
var SelectSeparator = React7.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
1905
|
+
SelectPrimitive.Separator,
|
|
1906
|
+
{
|
|
1907
|
+
ref,
|
|
1908
|
+
...slot(selectAnatomy, "separator"),
|
|
1909
|
+
className: cn(LIST_SEPARATOR.neutral, className),
|
|
1910
|
+
...props
|
|
1911
|
+
}
|
|
1912
|
+
));
|
|
1913
|
+
SelectSeparator.displayName = SelectPrimitive.Separator.displayName;
|
|
1914
|
+
var CONTROL_SIZES = /* @__PURE__ */ new Set(["xs", "sm", "md", "lg", "xl"]);
|
|
1915
|
+
function fieldControlSize(size) {
|
|
1916
|
+
return size !== void 0 && CONTROL_SIZES.has(size) ? size : void 0;
|
|
1917
|
+
}
|
|
1918
|
+
function Select({
|
|
1919
|
+
options,
|
|
1920
|
+
value: valueProp,
|
|
1921
|
+
defaultValue: defaultValueProp,
|
|
1922
|
+
onValueChange,
|
|
1923
|
+
placeholder: placeholderProp,
|
|
1924
|
+
disabled: disabledProp,
|
|
1925
|
+
name: nameProp,
|
|
1926
|
+
required: requiredProp,
|
|
1927
|
+
form,
|
|
1928
|
+
id: idProp,
|
|
1929
|
+
size: sizeProp,
|
|
1930
|
+
clearable = false,
|
|
1931
|
+
className,
|
|
1932
|
+
classNames,
|
|
1933
|
+
messages,
|
|
1934
|
+
triggerClassName,
|
|
1935
|
+
contentClassName,
|
|
1936
|
+
"aria-invalid": ariaInvalid,
|
|
1937
|
+
"aria-label": ariaLabel,
|
|
1938
|
+
"aria-labelledby": ariaLabelledBy,
|
|
1939
|
+
"aria-describedby": ariaDescribedBy
|
|
1940
|
+
}) {
|
|
1941
|
+
const resolvedMessages = useDsMessages("select", messages);
|
|
1942
|
+
const placeholder = placeholderProp ?? resolvedMessages.placeholder;
|
|
1943
|
+
const defaultValue = defaultValueProp ?? "";
|
|
1944
|
+
const [value, setValue] = useControllableState({
|
|
1945
|
+
prop: valueProp === null ? "" : valueProp,
|
|
1946
|
+
defaultProp: defaultValue,
|
|
1947
|
+
onChange: onValueChange
|
|
1948
|
+
});
|
|
1949
|
+
const field = useFieldContext();
|
|
1950
|
+
const wiring = useFieldControl({
|
|
1951
|
+
id: idProp,
|
|
1952
|
+
name: nameProp,
|
|
1953
|
+
invalid: ariaInvalid,
|
|
1954
|
+
required: requiredProp,
|
|
1955
|
+
disabled: disabledProp,
|
|
1956
|
+
"aria-labelledby": ariaLabelledBy,
|
|
1957
|
+
"aria-describedby": ariaDescribedBy,
|
|
1958
|
+
native: false
|
|
1959
|
+
});
|
|
1960
|
+
const disabled = wiring.disabled ?? false;
|
|
1961
|
+
const required = wiring["aria-required"] === true;
|
|
1962
|
+
const size = sizeProp ?? fieldControlSize(field?.size);
|
|
1963
|
+
const triggerRef = React7.useRef(null);
|
|
1964
|
+
const fieldRef = wiring.ref;
|
|
1965
|
+
const composedTriggerRef = React7.useCallback(
|
|
1966
|
+
(node) => {
|
|
1967
|
+
triggerRef.current = node;
|
|
1968
|
+
fieldRef(node);
|
|
1969
|
+
},
|
|
1970
|
+
[fieldRef]
|
|
1971
|
+
);
|
|
1972
|
+
const clear = () => {
|
|
1973
|
+
setValue("");
|
|
1974
|
+
triggerRef.current?.focus();
|
|
1975
|
+
};
|
|
1976
|
+
const showClear = clearable && value !== "" && !disabled;
|
|
1977
|
+
const wrapValue = clearable || classNames?.value !== void 0;
|
|
1978
|
+
const trigger = /* @__PURE__ */ jsx(
|
|
1979
|
+
SelectTrigger,
|
|
1980
|
+
{
|
|
1981
|
+
ref: composedTriggerRef,
|
|
1982
|
+
id: wiring.id,
|
|
1983
|
+
size,
|
|
1984
|
+
"aria-invalid": wiring["aria-invalid"],
|
|
1985
|
+
"aria-required": wiring["aria-required"],
|
|
1986
|
+
"aria-labelledby": wiring["aria-labelledby"],
|
|
1987
|
+
"aria-describedby": wiring["aria-describedby"],
|
|
1988
|
+
"aria-label": ariaLabel ?? (wiring["aria-labelledby"] ? void 0 : placeholder),
|
|
1989
|
+
"data-invalid": wiring["data-invalid"],
|
|
1990
|
+
className: cn(triggerClassName, classNames?.trigger, clearable ? void 0 : className),
|
|
1991
|
+
classNames: classNames?.icon !== void 0 ? { icon: classNames.icon } : void 0,
|
|
1992
|
+
children: wrapValue ? /* @__PURE__ */ jsx(
|
|
1993
|
+
"span",
|
|
1994
|
+
{
|
|
1995
|
+
...slot(selectAnatomy, "value"),
|
|
1996
|
+
className: cn(clearable && "ds:mr-8", classNames?.value),
|
|
1997
|
+
children: /* @__PURE__ */ jsx(SelectValue, { placeholder })
|
|
1998
|
+
}
|
|
1999
|
+
) : /* @__PURE__ */ jsx(SelectValue, { placeholder })
|
|
2000
|
+
}
|
|
2001
|
+
);
|
|
2002
|
+
return /* @__PURE__ */ jsxs(
|
|
2003
|
+
SelectRoot,
|
|
2004
|
+
{
|
|
2005
|
+
value,
|
|
2006
|
+
onValueChange: setValue,
|
|
2007
|
+
disabled,
|
|
2008
|
+
...form !== void 0 && { form },
|
|
2009
|
+
children: [
|
|
2010
|
+
clearable ? /* @__PURE__ */ jsxs(
|
|
2011
|
+
"span",
|
|
2012
|
+
{
|
|
2013
|
+
...slot(selectAnatomy, "root"),
|
|
2014
|
+
className: cn("ds:relative ds:flex ds:w-full", classNames?.root, className),
|
|
2015
|
+
children: [
|
|
2016
|
+
trigger,
|
|
2017
|
+
showClear && /* @__PURE__ */ jsx(
|
|
2018
|
+
IconButton,
|
|
2019
|
+
{
|
|
2020
|
+
label: resolvedMessages.clear,
|
|
2021
|
+
icon: /* @__PURE__ */ jsx(XIcon, {}),
|
|
2022
|
+
variant: "ghost",
|
|
2023
|
+
intent: "neutral",
|
|
2024
|
+
size: "xs",
|
|
2025
|
+
tooltip: false,
|
|
2026
|
+
onClick: clear,
|
|
2027
|
+
...slot(selectAnatomy, "clear"),
|
|
2028
|
+
className: cn(
|
|
2029
|
+
// Left of the chevron box (1px border + 12px padding + 16px glyph), 3px of air.
|
|
2030
|
+
"ds:absolute ds:top-1/2 ds:right-8 ds:-translate-y-1/2 ds:text-fg-4 ds:hover:text-fg",
|
|
2031
|
+
classNames?.clear
|
|
2032
|
+
)
|
|
2033
|
+
}
|
|
2034
|
+
)
|
|
2035
|
+
]
|
|
2036
|
+
}
|
|
2037
|
+
) : trigger,
|
|
2038
|
+
/* @__PURE__ */ jsx(
|
|
2039
|
+
SelectContent,
|
|
2040
|
+
{
|
|
2041
|
+
className: cn(contentClassName, classNames?.content),
|
|
2042
|
+
classNames: classNames?.viewport !== void 0 ? { viewport: classNames.viewport } : void 0,
|
|
2043
|
+
children: options.map((opt) => /* @__PURE__ */ jsx(
|
|
2044
|
+
SelectItem,
|
|
2045
|
+
{
|
|
2046
|
+
value: opt.value,
|
|
2047
|
+
...opt.disabled !== void 0 && { disabled: opt.disabled },
|
|
2048
|
+
className: classNames?.item,
|
|
2049
|
+
children: /* @__PURE__ */ jsxs("span", { className: "ds:flex ds:min-w-0 ds:items-center ds:gap-1.5", children: [
|
|
2050
|
+
/* @__PURE__ */ jsx("span", { className: "ds:line-clamp-1", children: opt.label }),
|
|
2051
|
+
opt.labelSuffix
|
|
2052
|
+
] })
|
|
2053
|
+
},
|
|
2054
|
+
opt.value
|
|
2055
|
+
))
|
|
2056
|
+
}
|
|
2057
|
+
),
|
|
2058
|
+
/* @__PURE__ */ jsx(
|
|
2059
|
+
FormBridge,
|
|
2060
|
+
{
|
|
2061
|
+
name: wiring.name,
|
|
2062
|
+
value,
|
|
2063
|
+
form,
|
|
2064
|
+
disabled,
|
|
2065
|
+
required,
|
|
2066
|
+
focusTarget: triggerRef,
|
|
2067
|
+
onReset: () => setValue(defaultValue)
|
|
2068
|
+
}
|
|
2069
|
+
)
|
|
2070
|
+
]
|
|
2071
|
+
}
|
|
2072
|
+
);
|
|
2073
|
+
}
|
|
2074
|
+
Select.displayName = "Select";
|
|
2075
|
+
function setRef(ref, value) {
|
|
2076
|
+
if (typeof ref === "function") {
|
|
2077
|
+
const result = ref(value);
|
|
2078
|
+
return typeof result === "function" ? result : void 0;
|
|
2079
|
+
}
|
|
2080
|
+
if (ref !== null && ref !== void 0) {
|
|
2081
|
+
ref.current = value;
|
|
2082
|
+
}
|
|
2083
|
+
return void 0;
|
|
2084
|
+
}
|
|
2085
|
+
function mergeRefs(...refs) {
|
|
2086
|
+
return (value) => {
|
|
2087
|
+
const cleanups = refs.map((ref) => setRef(ref, value));
|
|
2088
|
+
return () => {
|
|
2089
|
+
refs.forEach((ref, index) => {
|
|
2090
|
+
const cleanup = cleanups[index];
|
|
2091
|
+
if (cleanup) cleanup();
|
|
2092
|
+
else setRef(ref, null);
|
|
2093
|
+
});
|
|
2094
|
+
};
|
|
2095
|
+
};
|
|
2096
|
+
}
|
|
2097
|
+
function useMergedRefs(...refs) {
|
|
2098
|
+
return useMemo(() => mergeRefs(...refs), refs);
|
|
2099
|
+
}
|
|
2100
|
+
var FieldsetContext = createContext(null);
|
|
2101
|
+
function useFieldsetContext() {
|
|
2102
|
+
return useContext(FieldsetContext);
|
|
2103
|
+
}
|
|
2104
|
+
function useFieldsetState({
|
|
2105
|
+
id,
|
|
2106
|
+
disabled = false,
|
|
2107
|
+
invalid = false
|
|
2108
|
+
}) {
|
|
2109
|
+
const base = useId(id, "ds-fieldset");
|
|
2110
|
+
const [legends, setLegends] = useState(0);
|
|
2111
|
+
const registerLegend = useCallback(() => {
|
|
2112
|
+
setLegends((count) => count + 1);
|
|
2113
|
+
let released = false;
|
|
2114
|
+
return () => {
|
|
2115
|
+
if (released) return;
|
|
2116
|
+
released = true;
|
|
2117
|
+
setLegends((count) => Math.max(0, count - 1));
|
|
2118
|
+
};
|
|
2119
|
+
}, []);
|
|
2120
|
+
return useMemo(
|
|
2121
|
+
() => ({
|
|
2122
|
+
legendId: partId(base, "legend"),
|
|
2123
|
+
legendMounted: legends > 0,
|
|
2124
|
+
registerLegend,
|
|
2125
|
+
disabled,
|
|
2126
|
+
invalid
|
|
2127
|
+
}),
|
|
2128
|
+
[base, legends, registerLegend, disabled, invalid]
|
|
2129
|
+
);
|
|
2130
|
+
}
|
|
2131
|
+
function useFieldsetLegend(explicitId) {
|
|
2132
|
+
const fieldset = useFieldsetContext();
|
|
2133
|
+
const registerLegend = fieldset?.registerLegend;
|
|
2134
|
+
useEffect(() => {
|
|
2135
|
+
if (!registerLegend) return;
|
|
2136
|
+
return registerLegend();
|
|
2137
|
+
}, [registerLegend]);
|
|
2138
|
+
return explicitId ?? fieldset?.legendId;
|
|
2139
|
+
}
|
|
2140
|
+
var Checkbox = React7.forwardRef(function Checkbox2({
|
|
2141
|
+
label,
|
|
2142
|
+
indeterminate,
|
|
2143
|
+
checked,
|
|
2144
|
+
defaultChecked,
|
|
2145
|
+
shape = "square",
|
|
2146
|
+
className,
|
|
2147
|
+
id,
|
|
2148
|
+
name,
|
|
2149
|
+
invalid,
|
|
2150
|
+
required,
|
|
2151
|
+
disabled,
|
|
2152
|
+
"aria-labelledby": ariaLabelledBy,
|
|
2153
|
+
"aria-describedby": ariaDescribedBy,
|
|
2154
|
+
"aria-invalid": ariaInvalid,
|
|
2155
|
+
...props
|
|
2156
|
+
}, ref) {
|
|
2157
|
+
const fieldset = useFieldsetContext();
|
|
2158
|
+
const wiring = useFieldControl({
|
|
2159
|
+
id,
|
|
2160
|
+
name,
|
|
2161
|
+
invalid,
|
|
2162
|
+
required,
|
|
2163
|
+
disabled: disabled ?? (fieldset?.disabled ? true : void 0),
|
|
2164
|
+
"aria-labelledby": ariaLabelledBy,
|
|
2165
|
+
"aria-describedby": ariaDescribedBy
|
|
2166
|
+
});
|
|
2167
|
+
const rootRef = useMergedRefs(ref, wiring.ref);
|
|
2168
|
+
const resolvedChecked = indeterminate ? "indeterminate" : checked;
|
|
2169
|
+
return /* @__PURE__ */ jsxs("div", { className: "ds:inline-flex ds:items-center ds:gap-2", children: [
|
|
2170
|
+
/* @__PURE__ */ jsx(
|
|
2171
|
+
CheckboxPrimitive.Root,
|
|
2172
|
+
{
|
|
2173
|
+
ref: rootRef,
|
|
2174
|
+
id: wiring.id,
|
|
2175
|
+
name: wiring.name,
|
|
2176
|
+
...wiring.required !== void 0 && { required: wiring.required },
|
|
2177
|
+
disabled: wiring.disabled,
|
|
2178
|
+
...resolvedChecked !== void 0 && { checked: resolvedChecked },
|
|
2179
|
+
...defaultChecked !== void 0 && { defaultChecked },
|
|
2180
|
+
"aria-labelledby": wiring["aria-labelledby"],
|
|
2181
|
+
"aria-describedby": wiring["aria-describedby"],
|
|
2182
|
+
"aria-invalid": ariaInvalid ?? wiring["aria-invalid"],
|
|
2183
|
+
"data-invalid": wiring["data-invalid"],
|
|
2184
|
+
...slot(checkboxAnatomy, "root"),
|
|
2185
|
+
className: cn(
|
|
2186
|
+
"ds:peer ds:border-rule-strong ds:bg-surface ds:text-brand ds:flex ds:size-4 ds:shrink-0 ds:items-center ds:justify-center ds:border",
|
|
2187
|
+
shape === "circle" ? "ds:rounded-full" : "ds:rounded-[4px]",
|
|
2188
|
+
microInteractions.selection,
|
|
2189
|
+
"ds:hover:border-fg-4",
|
|
2190
|
+
"ds:focus-visible:[border-color:var(--focus-ring-border)] ds:focus-visible:[box-shadow:var(--shadow-focus-ring-field)] ds:focus-visible:outline-none",
|
|
2191
|
+
"ds:data-[state=checked]:border-brand ds:data-[state=checked]:bg-brand-bg",
|
|
2192
|
+
"ds:data-[state=indeterminate]:border-brand ds:data-[state=indeterminate]:bg-brand-bg",
|
|
2193
|
+
"ds:disabled:bg-bg-disabled ds:disabled:border-rule ds:disabled:text-fg-disabled ds:disabled:cursor-not-allowed",
|
|
2194
|
+
"ds:aria-[invalid=true]:border-danger-line",
|
|
2195
|
+
className
|
|
2196
|
+
),
|
|
2197
|
+
...props,
|
|
2198
|
+
children: /* @__PURE__ */ jsx(
|
|
2199
|
+
CheckboxPrimitive.Indicator,
|
|
2200
|
+
{
|
|
2201
|
+
...slot(checkboxAnatomy, "indicator"),
|
|
2202
|
+
className: "ds:flex ds:items-center ds:justify-center ds:text-current",
|
|
2203
|
+
children: resolvedChecked === "indeterminate" ? /* @__PURE__ */ jsx(MinusIcon, { className: "ds:size-3", strokeWidth: 3, "aria-hidden": "true" }) : shape === "circle" ? /* @__PURE__ */ jsx("span", { className: "ds:size-1.5 ds:rounded-full ds:bg-current", "aria-hidden": "true" }) : /* @__PURE__ */ jsx(CheckIcon, { className: "ds:size-3", strokeWidth: 3, "aria-hidden": "true" })
|
|
2204
|
+
}
|
|
2205
|
+
)
|
|
2206
|
+
}
|
|
2207
|
+
),
|
|
2208
|
+
label && /* @__PURE__ */ jsx(
|
|
2209
|
+
"label",
|
|
2210
|
+
{
|
|
2211
|
+
htmlFor: wiring.id,
|
|
2212
|
+
...slot(checkboxAnatomy, "label"),
|
|
2213
|
+
className: "ds:text-fg ds:peer-disabled:text-fg-disabled ds:cursor-pointer ds:text-[13px] ds:leading-none ds:select-none ds:peer-disabled:cursor-not-allowed",
|
|
2214
|
+
children: label
|
|
2215
|
+
}
|
|
2216
|
+
)
|
|
2217
|
+
] });
|
|
2218
|
+
});
|
|
2219
|
+
Checkbox.displayName = CheckboxPrimitive.Root.displayName;
|
|
2220
|
+
var Pressable = forwardRef(function Pressable2({
|
|
2221
|
+
asChild = false,
|
|
2222
|
+
pressed,
|
|
2223
|
+
disabled,
|
|
2224
|
+
type,
|
|
2225
|
+
className,
|
|
2226
|
+
onClick,
|
|
2227
|
+
onKeyDown,
|
|
2228
|
+
onKeyUp,
|
|
2229
|
+
children,
|
|
2230
|
+
...props
|
|
2231
|
+
}, ref) {
|
|
2232
|
+
const state = stateAttributes({ disabled, pressed });
|
|
2233
|
+
const handleClick = (event) => {
|
|
2234
|
+
if (disabled) {
|
|
2235
|
+
event.preventDefault();
|
|
2236
|
+
event.stopPropagation();
|
|
2237
|
+
return;
|
|
2238
|
+
}
|
|
2239
|
+
onClick?.(event);
|
|
2240
|
+
};
|
|
2241
|
+
const handleKeyDown = (event) => {
|
|
2242
|
+
onKeyDown?.(event);
|
|
2243
|
+
if (event.defaultPrevented) return;
|
|
2244
|
+
const element = event.currentTarget;
|
|
2245
|
+
if (disabled) {
|
|
2246
|
+
if (event.key === "Enter" || event.key === " ") event.preventDefault();
|
|
2247
|
+
return;
|
|
2248
|
+
}
|
|
2249
|
+
if (isNativeButton(element)) return;
|
|
2250
|
+
if (event.key === " ") {
|
|
2251
|
+
event.preventDefault();
|
|
2252
|
+
return;
|
|
2253
|
+
}
|
|
2254
|
+
if (event.key === "Enter" && !isLink(element)) {
|
|
2255
|
+
event.preventDefault();
|
|
2256
|
+
element.click();
|
|
2257
|
+
}
|
|
2258
|
+
};
|
|
2259
|
+
const handleKeyUp = (event) => {
|
|
2260
|
+
onKeyUp?.(event);
|
|
2261
|
+
if (event.defaultPrevented || disabled) return;
|
|
2262
|
+
const element = event.currentTarget;
|
|
2263
|
+
if (event.key === " " && !isNativeButton(element)) {
|
|
2264
|
+
event.preventDefault();
|
|
2265
|
+
element.click();
|
|
2266
|
+
}
|
|
2267
|
+
};
|
|
2268
|
+
const shared = {
|
|
2269
|
+
...slot(pressableAnatomy, "root"),
|
|
2270
|
+
...state,
|
|
2271
|
+
"aria-pressed": pressed,
|
|
2272
|
+
className: cn(PRESSABLE_CLASSES, className),
|
|
2273
|
+
onClick: handleClick,
|
|
2274
|
+
onKeyDown: handleKeyDown,
|
|
2275
|
+
onKeyUp: handleKeyUp
|
|
2276
|
+
};
|
|
2277
|
+
if (asChild) {
|
|
2278
|
+
return /* @__PURE__ */ jsx(
|
|
2279
|
+
Slot,
|
|
2280
|
+
{
|
|
2281
|
+
ref,
|
|
2282
|
+
...shared,
|
|
2283
|
+
...disabled ? { "aria-disabled": true, tabIndex: -1 } : {},
|
|
2284
|
+
...type === void 0 ? {} : { type },
|
|
2285
|
+
...props,
|
|
2286
|
+
children
|
|
2287
|
+
}
|
|
2288
|
+
);
|
|
2289
|
+
}
|
|
2290
|
+
return /* @__PURE__ */ jsx(
|
|
2291
|
+
"button",
|
|
2292
|
+
{
|
|
2293
|
+
ref,
|
|
2294
|
+
type: type ?? "button",
|
|
2295
|
+
disabled,
|
|
2296
|
+
...shared,
|
|
2297
|
+
...props,
|
|
2298
|
+
children
|
|
2299
|
+
}
|
|
2300
|
+
);
|
|
2301
|
+
});
|
|
2302
|
+
Pressable.displayName = "Pressable";
|
|
2303
|
+
var PRESSABLE_CLASSES = "ds:cursor-pointer ds:focus-visible:outline-none ds:focus-visible:[box-shadow:var(--shadow-focus-ring)] ds:data-[disabled]:pointer-events-none";
|
|
2304
|
+
function isNativeButton(element) {
|
|
2305
|
+
if (element.tagName === "BUTTON") return true;
|
|
2306
|
+
if (element.tagName !== "INPUT") return false;
|
|
2307
|
+
const type = element.type;
|
|
2308
|
+
return type === "button" || type === "submit" || type === "reset";
|
|
2309
|
+
}
|
|
2310
|
+
function isLink(element) {
|
|
2311
|
+
return element.tagName === "A" && element.hasAttribute("href");
|
|
2312
|
+
}
|
|
2313
|
+
|
|
2314
|
+
// src/primitives/behavior/overlay/recipes.ts
|
|
2315
|
+
var BACKDROP_BOX = "ds:bg-overlay ds:fixed ds:inset-0 ds:z-[var(--z-overlay)] ds:backdrop-blur-[4px]";
|
|
2316
|
+
function backdropClasses(_motion, className) {
|
|
2317
|
+
return cn(BACKDROP_BOX, className);
|
|
2318
|
+
}
|
|
2319
|
+
var CENTER_BOX = "ds:fixed ds:top-1/2 ds:left-1/2 ds:z-[var(--z-modal)] ds:w-full";
|
|
2320
|
+
var CENTER_SCROLL = "ds:scrollbar-thin ds:max-h-[calc(100vh-6rem)] ds:overflow-y-auto";
|
|
2321
|
+
var CENTER_CHROME = "ds:rounded-card ds:border-rule ds:bg-surface ds:shadow-overlay ds:border ds:p-6";
|
|
2322
|
+
var CENTER_INK = "ds:font-body ds:text-fg";
|
|
2323
|
+
var CENTER_PLACE = "ds:-translate-x-1/2 ds:-translate-y-1/2";
|
|
2324
|
+
var PANEL_BASE = "ds:fixed ds:z-[var(--z-modal)] ds:flex ds:flex-col ds:gap-4 ds:bg-surface ds:text-fg ds:shadow-overlay";
|
|
2325
|
+
var SPOTLIGHT_BOX = "ds:fixed ds:top-[20vh] ds:left-1/2 ds:z-[var(--z-modal)] ds:w-full";
|
|
2326
|
+
var SPOTLIGHT_SHIFT = "ds:-translate-x-1/2";
|
|
2327
|
+
var SPOTLIGHT_CHROME = "ds:rounded-card ds:border-rule ds:bg-surface ds:shadow-overlay ds:overflow-hidden ds:border";
|
|
2328
|
+
var PANEL_SIDE = {
|
|
2329
|
+
top: "ds:inset-x-0 ds:top-0 ds:border-b ds:border-rule",
|
|
2330
|
+
bottom: "ds:inset-x-0 ds:bottom-0 ds:border-t ds:border-rule ds:max-h-[85vh] ds:pb-[env(safe-area-inset-bottom)]",
|
|
2331
|
+
left: "ds:inset-y-0 ds:left-0 ds:h-full ds:w-[var(--ds-sheet-width,75%)] ds:max-w-[min(var(--ds-sheet-width,24rem),95vw)] ds:border-r ds:border-rule",
|
|
2332
|
+
right: "ds:inset-y-0 ds:right-0 ds:h-full ds:w-[var(--ds-sheet-width,75%)] ds:max-w-[min(var(--ds-sheet-width,24rem),95vw)] ds:border-l ds:border-rule"
|
|
2333
|
+
};
|
|
2334
|
+
var RESPONSIVE_BOX = cn(
|
|
2335
|
+
"ds:fixed ds:inset-x-0 ds:bottom-0 ds:z-[var(--z-modal)] ds:w-full",
|
|
2336
|
+
"ds:sm:top-1/2 ds:sm:right-auto ds:sm:bottom-auto ds:sm:left-1/2"
|
|
2337
|
+
);
|
|
2338
|
+
var RESPONSIVE_SCROLL = "ds:scrollbar-thin ds:max-h-[85vh] ds:overflow-y-auto ds:sm:max-h-[calc(100vh-6rem)]";
|
|
2339
|
+
var RESPONSIVE_CHROME = cn(
|
|
2340
|
+
"ds:rounded-t-card ds:border-rule ds:bg-surface ds:shadow-overlay ds:border-t ds:p-6",
|
|
2341
|
+
"ds:pb-[calc(1.5rem+env(safe-area-inset-bottom))]",
|
|
2342
|
+
"ds:sm:rounded-card ds:sm:border ds:sm:pb-6"
|
|
2343
|
+
);
|
|
2344
|
+
var RESPONSIVE_PLACE = "ds:sm:-translate-x-1/2 ds:sm:-translate-y-1/2";
|
|
2345
|
+
function overlaySurfaceClasses(placement, _motion, { width, rows = [] } = {}, className) {
|
|
2346
|
+
if (placement === "center") {
|
|
2347
|
+
return cn(
|
|
2348
|
+
CENTER_BOX,
|
|
2349
|
+
width,
|
|
2350
|
+
CENTER_SCROLL,
|
|
2351
|
+
CENTER_CHROME,
|
|
2352
|
+
CENTER_INK,
|
|
2353
|
+
CENTER_PLACE,
|
|
2354
|
+
...rows,
|
|
2355
|
+
className
|
|
2356
|
+
);
|
|
2357
|
+
}
|
|
2358
|
+
if (placement === "responsive") {
|
|
2359
|
+
return cn(
|
|
2360
|
+
RESPONSIVE_BOX,
|
|
2361
|
+
width,
|
|
2362
|
+
RESPONSIVE_SCROLL,
|
|
2363
|
+
RESPONSIVE_CHROME,
|
|
2364
|
+
CENTER_INK,
|
|
2365
|
+
RESPONSIVE_PLACE,
|
|
2366
|
+
...rows,
|
|
2367
|
+
className
|
|
2368
|
+
);
|
|
2369
|
+
}
|
|
2370
|
+
if (placement === "spotlight") {
|
|
2371
|
+
return cn(SPOTLIGHT_BOX, width, SPOTLIGHT_SHIFT, SPOTLIGHT_CHROME, CENTER_INK, ...rows, className);
|
|
2372
|
+
}
|
|
2373
|
+
return cn(PANEL_BASE, PANEL_SIDE[placement], ...rows, className);
|
|
2374
|
+
}
|
|
2375
|
+
var FLOATING_CHROME = "ds:rounded-card ds:border-rule ds:bg-surface ds:text-fg ds:shadow-pop ds:z-[var(--z-dropdown)]";
|
|
2376
|
+
var FLOATING_WIDTH = {
|
|
2377
|
+
popover: {
|
|
2378
|
+
auto: "",
|
|
2379
|
+
trigger: "ds:w-(--radix-popover-trigger-width)",
|
|
2380
|
+
sm: "ds:w-64",
|
|
2381
|
+
md: "ds:w-72",
|
|
2382
|
+
lg: "ds:w-96"
|
|
2383
|
+
},
|
|
2384
|
+
"hover-card": {
|
|
2385
|
+
auto: "",
|
|
2386
|
+
trigger: "ds:w-(--radix-hover-card-trigger-width)",
|
|
2387
|
+
sm: "ds:w-64",
|
|
2388
|
+
md: "ds:w-72",
|
|
2389
|
+
lg: "ds:w-96"
|
|
2390
|
+
}
|
|
2391
|
+
};
|
|
2392
|
+
var FLOATING_PADDING = {
|
|
2393
|
+
none: "",
|
|
2394
|
+
sm: "ds:p-3",
|
|
2395
|
+
md: "ds:p-4"
|
|
2396
|
+
};
|
|
2397
|
+
function floatingSurfaceClasses(_motion, { width, padding, rows = [] } = {}, className) {
|
|
2398
|
+
return cn(FLOATING_CHROME, width, "ds:border", padding, "ds:outline-none", ...rows, className);
|
|
2399
|
+
}
|
|
2400
|
+
var DISMISS_BUTTON_CLASSES = cn(
|
|
2401
|
+
"ds:absolute ds:top-4 ds:right-4 ds:inline-flex ds:size-7 ds:items-center ds:justify-center",
|
|
2402
|
+
"ds:rounded-icon ds:text-fg-4 ds:transition-colors ds:duration-[var(--duration-fast)] ds:ease-[var(--ease-out-quart)] ds:motion-reduce:transition-none",
|
|
2403
|
+
"ds:hover:bg-overlay-hover ds:hover:text-fg",
|
|
2404
|
+
"ds:focus-visible:[box-shadow:var(--shadow-focus-ring)] ds:focus-visible:outline-none",
|
|
2405
|
+
"ds:disabled:pointer-events-none"
|
|
2406
|
+
);
|
|
2407
|
+
var DISMISS_GLYPH_CLASSES = "ds:size-4";
|
|
2408
|
+
var HEADER_COLUMN = "ds:flex ds:flex-col ds:gap-1.5";
|
|
2409
|
+
function overlayHeaderClasses(layout, dismissGutter, className) {
|
|
2410
|
+
return layout === "inset" ? cn("ds:mb-4", HEADER_COLUMN, dismissGutter && "ds:pr-8", className) : cn(HEADER_COLUMN, "ds:p-6", dismissGutter && "ds:pr-12", "ds:pb-0", className);
|
|
2411
|
+
}
|
|
2412
|
+
var OVERLAY_TITLE_CLASSES = "ds:font-display ds:text-fg ds:text-base ds:leading-tight ds:font-medium ds:tracking-tight";
|
|
2413
|
+
var OVERLAY_DESCRIPTION_CLASSES = "ds:text-fg-3 ds:text-sm";
|
|
2414
|
+
var FOOTER_ROW = "ds:flex ds:flex-col-reverse ds:gap-2";
|
|
2415
|
+
var FOOTER_RESPONSIVE = "ds:sm:flex-row ds:sm:items-center ds:sm:justify-end";
|
|
2416
|
+
function overlayFooterClasses(layout, className) {
|
|
2417
|
+
return layout === "inset" ? cn("ds:mt-6", FOOTER_ROW, FOOTER_RESPONSIVE, className) : cn(
|
|
2418
|
+
"ds:border-rule ds:mt-auto",
|
|
2419
|
+
FOOTER_ROW,
|
|
2420
|
+
"ds:border-t ds:p-6",
|
|
2421
|
+
FOOTER_RESPONSIVE,
|
|
2422
|
+
className
|
|
2423
|
+
);
|
|
2424
|
+
}
|
|
2425
|
+
var BODY_SCROLL = "ds:scrollbar-thin ds:min-h-0 ds:flex-1 ds:overflow-y-auto";
|
|
2426
|
+
var BODY_PADDING = {
|
|
2427
|
+
inset: {
|
|
2428
|
+
none: "",
|
|
2429
|
+
sm: "ds:p-4",
|
|
2430
|
+
md: "ds:p-6",
|
|
2431
|
+
lg: "ds:p-8"
|
|
2432
|
+
},
|
|
2433
|
+
padded: {
|
|
2434
|
+
none: "",
|
|
2435
|
+
sm: "ds:px-4",
|
|
2436
|
+
md: "ds:px-6",
|
|
2437
|
+
lg: "ds:px-8"
|
|
2438
|
+
}
|
|
2439
|
+
};
|
|
2440
|
+
function overlayBodyClasses(layout, padding, className) {
|
|
2441
|
+
return cn(BODY_SCROLL, BODY_PADDING[layout][padding], className);
|
|
2442
|
+
}
|
|
2443
|
+
function Backdrop({
|
|
2444
|
+
as: Component,
|
|
2445
|
+
anatomy,
|
|
2446
|
+
motion,
|
|
2447
|
+
className,
|
|
2448
|
+
...props
|
|
2449
|
+
}) {
|
|
2450
|
+
return /* @__PURE__ */ jsx(
|
|
2451
|
+
Component,
|
|
2452
|
+
{
|
|
2453
|
+
...slot(anatomy, "overlay"),
|
|
2454
|
+
...presence("fade"),
|
|
2455
|
+
className: backdropClasses(motion, className),
|
|
2456
|
+
...props
|
|
2457
|
+
}
|
|
2458
|
+
);
|
|
2459
|
+
}
|
|
2460
|
+
var SURFACE_PRESENCE = {
|
|
2461
|
+
center: "modal",
|
|
2462
|
+
top: "sheet-top",
|
|
2463
|
+
right: "sheet-right",
|
|
2464
|
+
bottom: "sheet-bottom",
|
|
2465
|
+
left: "sheet-left",
|
|
2466
|
+
responsive: "responsive",
|
|
2467
|
+
spotlight: "spotlight"
|
|
2468
|
+
};
|
|
2469
|
+
function OverlaySurface({
|
|
2470
|
+
as: Component,
|
|
2471
|
+
anatomy,
|
|
2472
|
+
placement,
|
|
2473
|
+
motion,
|
|
2474
|
+
width,
|
|
2475
|
+
rows,
|
|
2476
|
+
className,
|
|
2477
|
+
...props
|
|
2478
|
+
}) {
|
|
2479
|
+
return /* @__PURE__ */ jsx(
|
|
2480
|
+
Component,
|
|
2481
|
+
{
|
|
2482
|
+
...slot(anatomy, "content"),
|
|
2483
|
+
...presence(SURFACE_PRESENCE[placement]),
|
|
2484
|
+
className: overlaySurfaceClasses(placement, motion, { width, rows }, className),
|
|
2485
|
+
...props
|
|
2486
|
+
}
|
|
2487
|
+
);
|
|
2488
|
+
}
|
|
2489
|
+
var DEFAULT_OVERLAY_MESSAGES = EN_MESSAGES.overlay;
|
|
2490
|
+
function DismissButton({
|
|
2491
|
+
as: Component,
|
|
2492
|
+
anatomy,
|
|
2493
|
+
label,
|
|
2494
|
+
className,
|
|
2495
|
+
children,
|
|
2496
|
+
...props
|
|
2497
|
+
}) {
|
|
2498
|
+
return /* @__PURE__ */ jsx(
|
|
2499
|
+
Component,
|
|
2500
|
+
{
|
|
2501
|
+
...slot(anatomy, "close"),
|
|
2502
|
+
className: cn(DISMISS_BUTTON_CLASSES, className),
|
|
2503
|
+
"aria-label": label,
|
|
2504
|
+
...props,
|
|
2505
|
+
children
|
|
2506
|
+
}
|
|
2507
|
+
);
|
|
2508
|
+
}
|
|
2509
|
+
function OverlayHeader({
|
|
2510
|
+
as: Component = "div",
|
|
2511
|
+
anatomy,
|
|
2512
|
+
layout,
|
|
2513
|
+
dismissGutter,
|
|
2514
|
+
className,
|
|
2515
|
+
...props
|
|
2516
|
+
}) {
|
|
2517
|
+
return /* @__PURE__ */ jsx(
|
|
2518
|
+
Component,
|
|
2519
|
+
{
|
|
2520
|
+
...slot(anatomy, "header"),
|
|
2521
|
+
className: overlayHeaderClasses(layout, dismissGutter, className),
|
|
2522
|
+
...props
|
|
2523
|
+
}
|
|
2524
|
+
);
|
|
2525
|
+
}
|
|
2526
|
+
function OverlayTitle({ as: Component, anatomy, className, ...props }) {
|
|
2527
|
+
return /* @__PURE__ */ jsx(
|
|
2528
|
+
Component,
|
|
2529
|
+
{
|
|
2530
|
+
...slot(anatomy, "title"),
|
|
2531
|
+
className: cn(OVERLAY_TITLE_CLASSES, className),
|
|
2532
|
+
...props
|
|
2533
|
+
}
|
|
2534
|
+
);
|
|
2535
|
+
}
|
|
2536
|
+
function OverlayDescription({ as: Component, anatomy, className, ...props }) {
|
|
2537
|
+
return /* @__PURE__ */ jsx(
|
|
2538
|
+
Component,
|
|
2539
|
+
{
|
|
2540
|
+
...slot(anatomy, "description"),
|
|
2541
|
+
className: cn(OVERLAY_DESCRIPTION_CLASSES, className),
|
|
2542
|
+
...props
|
|
2543
|
+
}
|
|
2544
|
+
);
|
|
2545
|
+
}
|
|
2546
|
+
function OverlayBody({
|
|
2547
|
+
as: Component = "div",
|
|
2548
|
+
anatomy,
|
|
2549
|
+
layout,
|
|
2550
|
+
padding,
|
|
2551
|
+
className,
|
|
2552
|
+
...props
|
|
2553
|
+
}) {
|
|
2554
|
+
return /* @__PURE__ */ jsx(
|
|
2555
|
+
Component,
|
|
2556
|
+
{
|
|
2557
|
+
...slot(anatomy, "body"),
|
|
2558
|
+
className: overlayBodyClasses(layout, padding, className),
|
|
2559
|
+
...props
|
|
2560
|
+
}
|
|
2561
|
+
);
|
|
2562
|
+
}
|
|
2563
|
+
function OverlayFooter({
|
|
2564
|
+
as: Component = "div",
|
|
2565
|
+
anatomy,
|
|
2566
|
+
layout,
|
|
2567
|
+
className,
|
|
2568
|
+
...props
|
|
2569
|
+
}) {
|
|
2570
|
+
return /* @__PURE__ */ jsx(
|
|
2571
|
+
Component,
|
|
2572
|
+
{
|
|
2573
|
+
...slot(anatomy, "footer"),
|
|
2574
|
+
className: overlayFooterClasses(layout, className),
|
|
2575
|
+
...props
|
|
2576
|
+
}
|
|
2577
|
+
);
|
|
2578
|
+
}
|
|
2579
|
+
var ModalRoot = DialogPrimitive.Root;
|
|
2580
|
+
var ModalPortal = DialogPrimitive.Portal;
|
|
2581
|
+
var ModalOverlay = DialogPrimitive.Overlay;
|
|
2582
|
+
var ModalContent = DialogPrimitive.Content;
|
|
2583
|
+
var ModalTitle = DialogPrimitive.Title;
|
|
2584
|
+
var ModalDescription = DialogPrimitive.Description;
|
|
2585
|
+
var PopoverTriggerIdContext = React7.createContext(null);
|
|
2586
|
+
var Popover = ({
|
|
2587
|
+
open: openProp,
|
|
2588
|
+
defaultOpen,
|
|
2589
|
+
onOpenChange,
|
|
2590
|
+
...props
|
|
2591
|
+
}) => {
|
|
2592
|
+
const [uncontrolledOpen, setUncontrolledOpen] = React7.useState(defaultOpen ?? false);
|
|
2593
|
+
const open = openProp ?? uncontrolledOpen;
|
|
2594
|
+
const handleOpenChange = React7.useCallback(
|
|
2595
|
+
(next) => {
|
|
2596
|
+
setUncontrolledOpen(next);
|
|
2597
|
+
onOpenChange?.(next);
|
|
2598
|
+
},
|
|
2599
|
+
[onOpenChange]
|
|
2600
|
+
);
|
|
2601
|
+
const [triggerId, setTriggerId] = React7.useState(void 0);
|
|
2602
|
+
const value = React7.useMemo(() => ({ open, triggerId, setTriggerId }), [open, triggerId]);
|
|
2603
|
+
return /* @__PURE__ */ jsx(PopoverTriggerIdContext.Provider, { value, children: /* @__PURE__ */ jsx(
|
|
2604
|
+
PopoverPrimitive.Root,
|
|
2605
|
+
{
|
|
2606
|
+
...openProp !== void 0 ? { open: openProp } : {},
|
|
2607
|
+
...defaultOpen !== void 0 ? { defaultOpen } : {},
|
|
2608
|
+
onOpenChange: handleOpenChange,
|
|
2609
|
+
...props
|
|
2610
|
+
}
|
|
2611
|
+
) });
|
|
2612
|
+
};
|
|
2613
|
+
Popover.displayName = "Popover";
|
|
2614
|
+
var PopoverTrigger = React7.forwardRef(({ id, ...props }, forwardedRef) => {
|
|
2615
|
+
const context = React7.useContext(PopoverTriggerIdContext);
|
|
2616
|
+
const generatedId = React7.useId();
|
|
2617
|
+
const node = React7.useRef(null);
|
|
2618
|
+
const ref = React7.useCallback(
|
|
2619
|
+
(element) => {
|
|
2620
|
+
node.current = element;
|
|
2621
|
+
if (typeof forwardedRef === "function") forwardedRef(element);
|
|
2622
|
+
else if (forwardedRef) forwardedRef.current = element;
|
|
2623
|
+
},
|
|
2624
|
+
[forwardedRef]
|
|
2625
|
+
);
|
|
2626
|
+
const setTriggerId = context?.setTriggerId;
|
|
2627
|
+
React7.useEffect(() => {
|
|
2628
|
+
setTriggerId?.(node.current?.id || void 0);
|
|
2629
|
+
});
|
|
2630
|
+
React7.useEffect(() => () => setTriggerId?.(void 0), [setTriggerId]);
|
|
2631
|
+
return /* @__PURE__ */ jsx(
|
|
2632
|
+
PopoverPrimitive.Trigger,
|
|
2633
|
+
{
|
|
2634
|
+
ref,
|
|
2635
|
+
id: id ?? (context?.open ? generatedId : void 0),
|
|
2636
|
+
...props
|
|
2637
|
+
}
|
|
2638
|
+
);
|
|
2639
|
+
});
|
|
2640
|
+
PopoverTrigger.displayName = PopoverPrimitive.Trigger.displayName;
|
|
2641
|
+
var PopoverAnchor = PopoverPrimitive.Anchor;
|
|
2642
|
+
var PopoverPortal = withPortalContainer(PopoverPrimitive.Portal);
|
|
2643
|
+
var PopoverClose = PopoverPrimitive.Close;
|
|
2644
|
+
var PopoverContent = React7.forwardRef(
|
|
2645
|
+
({
|
|
2646
|
+
className,
|
|
2647
|
+
align = "center",
|
|
2648
|
+
side = "bottom",
|
|
2649
|
+
sideOffset = 8,
|
|
2650
|
+
width = "md",
|
|
2651
|
+
padding = "md",
|
|
2652
|
+
...props
|
|
2653
|
+
}, ref) => {
|
|
2654
|
+
const triggerId = React7.useContext(PopoverTriggerIdContext)?.triggerId;
|
|
2655
|
+
const named = Boolean(props["aria-label"] || props["aria-labelledby"]);
|
|
2656
|
+
return /* @__PURE__ */ jsx(PopoverPortal, { children: /* @__PURE__ */ jsx(
|
|
2657
|
+
PopoverPrimitive.Content,
|
|
2658
|
+
{
|
|
2659
|
+
ref,
|
|
2660
|
+
"aria-labelledby": named ? void 0 : triggerId,
|
|
2661
|
+
align,
|
|
2662
|
+
side,
|
|
2663
|
+
sideOffset,
|
|
2664
|
+
...slot(popoverAnatomy, "content"),
|
|
2665
|
+
...presence("floating"),
|
|
2666
|
+
className: floatingSurfaceClasses(
|
|
2667
|
+
"tokens",
|
|
2668
|
+
{ width: FLOATING_WIDTH.popover[width], padding: FLOATING_PADDING[padding] },
|
|
2669
|
+
className
|
|
2670
|
+
),
|
|
2671
|
+
...props
|
|
2672
|
+
}
|
|
2673
|
+
) });
|
|
2674
|
+
}
|
|
2675
|
+
);
|
|
2676
|
+
PopoverContent.displayName = PopoverPrimitive.Content.displayName;
|
|
2677
|
+
|
|
2678
|
+
// src/primitives/behavior/menu/content.ts
|
|
2679
|
+
var DROPDOWN_MENU_WIDTH = {
|
|
2680
|
+
auto: "",
|
|
2681
|
+
trigger: "ds:w-(--radix-dropdown-menu-trigger-width)",
|
|
2682
|
+
sm: "ds:w-48",
|
|
2683
|
+
md: "ds:w-64"
|
|
2684
|
+
};
|
|
2685
|
+
|
|
2686
|
+
// src/primitives/behavior/menu/item-recipe.ts
|
|
2687
|
+
var MENU_ITEM_LABEL_SIZE = "ds:text-sm";
|
|
2688
|
+
var MENU_INSET = "ds:pl-8";
|
|
2689
|
+
var MENU_ITEM_DANGER = {
|
|
2690
|
+
menu: "ds:text-menu-item-destructive-fg ds:focus:bg-menu-item-destructive-hover-bg ds:focus:text-menu-item-destructive-hover-fg",
|
|
2691
|
+
neutral: "ds:text-danger-fg ds:focus:bg-danger-bg ds:focus:text-danger-fg"
|
|
2692
|
+
};
|
|
2693
|
+
var MENU_SUB_TRIGGER_OPEN = {
|
|
2694
|
+
menu: "ds:data-[state=open]:bg-menu-item-hover-bg ds:data-[state=open]:text-menu-item-hover-fg",
|
|
2695
|
+
neutral: "ds:data-[state=open]:bg-bg-2 ds:data-[state=open]:text-fg"
|
|
2696
|
+
};
|
|
2697
|
+
var MENU_SUB_TRIGGER_BOX = "ds:rounded-surface-sm ds:flex ds:cursor-default ds:items-center ds:gap-2 ds:px-2 ds:py-1.5";
|
|
2698
|
+
var MENU_SUB_TRIGGER_CHEVRON = "ds:text-fg-3 ds:ml-auto ds:size-4 ds:-translate-x-px";
|
|
2699
|
+
var MENU_INDICATOR_WELL = LIST_ITEM_INDICATOR_WELL.start;
|
|
2700
|
+
var MENU_CHECK_GLYPH = "ds:size-3.5!";
|
|
2701
|
+
var MENU_RADIO_GLYPH = "ds:size-2! ds:fill-current!";
|
|
2702
|
+
var MENU_SHORTCUT_INK = {
|
|
2703
|
+
menu: "ds:text-menu-shortcut-fg",
|
|
2704
|
+
neutral: "ds:text-fg-4"
|
|
2705
|
+
};
|
|
2706
|
+
var MENU_SHORTCUT_BOX = "ds:ml-auto ds:font-mono";
|
|
2707
|
+
var MENU_SHORTCUT_TYPE = "ds:tracking-wider";
|
|
2708
|
+
function menuItemClasses(palette) {
|
|
2709
|
+
return listItemClasses({
|
|
2710
|
+
frame: "menu",
|
|
2711
|
+
labelSize: MENU_ITEM_LABEL_SIZE,
|
|
2712
|
+
palette,
|
|
2713
|
+
highlight: "focus",
|
|
2714
|
+
selected: "none"
|
|
2715
|
+
});
|
|
2716
|
+
}
|
|
2717
|
+
function menuIndicatorItemClasses(palette) {
|
|
2718
|
+
return listItemClasses({
|
|
2719
|
+
frame: "menu-indicator",
|
|
2720
|
+
labelSize: MENU_ITEM_LABEL_SIZE,
|
|
2721
|
+
palette,
|
|
2722
|
+
highlight: "focus",
|
|
2723
|
+
selected: "none",
|
|
2724
|
+
glyph: false
|
|
2725
|
+
});
|
|
2726
|
+
}
|
|
2727
|
+
function menuSubTriggerClasses(palette) {
|
|
2728
|
+
const highlighted = LIST_ITEM_HIGHLIGHTED[palette].focus;
|
|
2729
|
+
if (highlighted === void 0) {
|
|
2730
|
+
throw new TypeError(
|
|
2731
|
+
`menu: no focus row for palette ${JSON.stringify(palette)}; write the literal in collection/item-recipe.ts`
|
|
2732
|
+
);
|
|
2733
|
+
}
|
|
2734
|
+
return [
|
|
2735
|
+
MENU_SUB_TRIGGER_BOX,
|
|
2736
|
+
MENU_ITEM_LABEL_SIZE,
|
|
2737
|
+
LIST_ITEM_INTERACTION,
|
|
2738
|
+
LIST_ITEM_INK[palette],
|
|
2739
|
+
LIST_ITEM_MOTION,
|
|
2740
|
+
highlighted,
|
|
2741
|
+
MENU_SUB_TRIGGER_OPEN[palette],
|
|
2742
|
+
LIST_ITEM_DISABLED
|
|
2743
|
+
].join(" ");
|
|
2744
|
+
}
|
|
2745
|
+
function menuLabelClasses(palette, labelSize) {
|
|
2746
|
+
return groupHeadingClasses({ palette, labelSize });
|
|
2747
|
+
}
|
|
2748
|
+
function menuSeparatorClasses(palette) {
|
|
2749
|
+
return LIST_SEPARATOR[palette];
|
|
2750
|
+
}
|
|
2751
|
+
function menuShortcutClasses(palette, labelSize) {
|
|
2752
|
+
return [MENU_SHORTCUT_INK[palette], MENU_SHORTCUT_BOX, labelSize, MENU_SHORTCUT_TYPE].join(" ");
|
|
2753
|
+
}
|
|
2754
|
+
var PALETTE = "menu";
|
|
2755
|
+
var DropdownMenu = DropdownMenuPrimitive.Root;
|
|
2756
|
+
var DropdownMenuTrigger = DropdownMenuPrimitive.Trigger;
|
|
2757
|
+
var DropdownMenuGroup = DropdownMenuPrimitive.Group;
|
|
2758
|
+
var DropdownMenuPortal = withPortalContainer(DropdownMenuPrimitive.Portal);
|
|
2759
|
+
var DropdownMenuSub = DropdownMenuPrimitive.Sub;
|
|
2760
|
+
var DropdownMenuRadioGroup = DropdownMenuPrimitive.RadioGroup;
|
|
2761
|
+
var DropdownMenuSubTrigger = React7.forwardRef(({ className, inset, children, ...props }, ref) => /* @__PURE__ */ jsxs(
|
|
2762
|
+
DropdownMenuPrimitive.SubTrigger,
|
|
2763
|
+
{
|
|
2764
|
+
ref,
|
|
2765
|
+
...slot(dropdownMenuAnatomy, "sub-trigger"),
|
|
2766
|
+
className: cn(menuSubTriggerClasses(PALETTE), inset && MENU_INSET, className),
|
|
2767
|
+
...props,
|
|
2768
|
+
children: [
|
|
2769
|
+
children,
|
|
2770
|
+
/* @__PURE__ */ jsx(ChevronRightIcon, { className: MENU_SUB_TRIGGER_CHEVRON, "aria-hidden": "true" })
|
|
2771
|
+
]
|
|
2772
|
+
}
|
|
2773
|
+
));
|
|
2774
|
+
DropdownMenuSubTrigger.displayName = DropdownMenuPrimitive.SubTrigger.displayName;
|
|
2775
|
+
var DropdownMenuSubContent = React7.forwardRef(({ className, ...props }, ref) => (
|
|
2776
|
+
// Portal the sub-content to the body. The parent Content is transformed
|
|
2777
|
+
// while its presence keyframes run, which makes it the containing block for
|
|
2778
|
+
// `position: fixed` descendants — and its `overflow-hidden` would then clip
|
|
2779
|
+
// this Popper-positioned flyout to nothing. Portaling escapes both.
|
|
2780
|
+
/* @__PURE__ */ jsx(DropdownMenuPortal, { children: /* @__PURE__ */ jsx(
|
|
2781
|
+
DropdownMenuPrimitive.SubContent,
|
|
2782
|
+
{
|
|
2783
|
+
ref,
|
|
2784
|
+
...slot(dropdownMenuAnatomy, "sub-content"),
|
|
2785
|
+
...presence("floating"),
|
|
2786
|
+
className: cn(
|
|
2787
|
+
"ds:rounded-card ds:border-menu-border ds:bg-menu-bg ds:text-menu-fg ds:shadow-pop ds:z-[var(--z-dropdown)] ds:min-w-[8rem] ds:overflow-hidden ds:border ds:p-1",
|
|
2788
|
+
className
|
|
2789
|
+
),
|
|
2790
|
+
...props
|
|
2791
|
+
}
|
|
2792
|
+
) })
|
|
2793
|
+
));
|
|
2794
|
+
DropdownMenuSubContent.displayName = DropdownMenuPrimitive.SubContent.displayName;
|
|
2795
|
+
var DropdownMenuContent = React7.forwardRef(({ className, sideOffset = 6, align = "start", width = "auto", ...props }, ref) => /* @__PURE__ */ jsx(DropdownMenuPortal, { children: /* @__PURE__ */ jsx(
|
|
2796
|
+
DropdownMenuPrimitive.Content,
|
|
2797
|
+
{
|
|
2798
|
+
ref,
|
|
2799
|
+
...slot(dropdownMenuAnatomy, "content"),
|
|
2800
|
+
...presence("floating"),
|
|
2801
|
+
sideOffset,
|
|
2802
|
+
align,
|
|
2803
|
+
className: cn(
|
|
2804
|
+
"ds:rounded-card ds:border-menu-border ds:bg-menu-bg ds:text-menu-fg ds:shadow-pop ds:z-[var(--z-dropdown)] ds:min-w-[10rem] ds:overflow-hidden ds:border ds:p-1",
|
|
2805
|
+
DROPDOWN_MENU_WIDTH[width],
|
|
2806
|
+
className
|
|
2807
|
+
),
|
|
2808
|
+
...props
|
|
2809
|
+
}
|
|
2810
|
+
) }));
|
|
2811
|
+
DropdownMenuContent.displayName = DropdownMenuPrimitive.Content.displayName;
|
|
2812
|
+
var DropdownMenuItem = React7.forwardRef(({ className, destructive, inset, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
2813
|
+
DropdownMenuPrimitive.Item,
|
|
2814
|
+
{
|
|
2815
|
+
ref,
|
|
2816
|
+
...slot(dropdownMenuAnatomy, "item"),
|
|
2817
|
+
className: cn(
|
|
2818
|
+
menuItemClasses(PALETTE),
|
|
2819
|
+
inset && MENU_INSET,
|
|
2820
|
+
destructive && MENU_ITEM_DANGER[PALETTE],
|
|
2821
|
+
className
|
|
2822
|
+
),
|
|
2823
|
+
...props
|
|
2824
|
+
}
|
|
2825
|
+
));
|
|
2826
|
+
DropdownMenuItem.displayName = DropdownMenuPrimitive.Item.displayName;
|
|
2827
|
+
var DropdownMenuCheckboxItem = React7.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ jsxs(
|
|
2828
|
+
DropdownMenuPrimitive.CheckboxItem,
|
|
2829
|
+
{
|
|
2830
|
+
ref,
|
|
2831
|
+
...slot(dropdownMenuAnatomy, "checkbox-item"),
|
|
2832
|
+
className: cn(menuIndicatorItemClasses(PALETTE), className),
|
|
2833
|
+
...props,
|
|
2834
|
+
children: [
|
|
2835
|
+
/* @__PURE__ */ jsx("span", { className: MENU_INDICATOR_WELL, children: /* @__PURE__ */ jsx(DropdownMenuPrimitive.ItemIndicator, { ...slot(dropdownMenuAnatomy, "item-indicator"), children: /* @__PURE__ */ jsx(CheckIcon, { className: MENU_CHECK_GLYPH, "aria-hidden": "true" }) }) }),
|
|
2836
|
+
children
|
|
2837
|
+
]
|
|
2838
|
+
}
|
|
2839
|
+
));
|
|
2840
|
+
DropdownMenuCheckboxItem.displayName = DropdownMenuPrimitive.CheckboxItem.displayName;
|
|
2841
|
+
var DropdownMenuRadioItem = React7.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ jsxs(
|
|
2842
|
+
DropdownMenuPrimitive.RadioItem,
|
|
2843
|
+
{
|
|
2844
|
+
ref,
|
|
2845
|
+
...slot(dropdownMenuAnatomy, "radio-item"),
|
|
2846
|
+
className: cn(menuIndicatorItemClasses(PALETTE), className),
|
|
2847
|
+
...props,
|
|
2848
|
+
children: [
|
|
2849
|
+
/* @__PURE__ */ jsx("span", { className: MENU_INDICATOR_WELL, children: /* @__PURE__ */ jsx(DropdownMenuPrimitive.ItemIndicator, { ...slot(dropdownMenuAnatomy, "item-indicator"), children: /* @__PURE__ */ jsx(CircleIcon, { className: MENU_RADIO_GLYPH, "aria-hidden": "true" }) }) }),
|
|
2850
|
+
children
|
|
2851
|
+
]
|
|
2852
|
+
}
|
|
2853
|
+
));
|
|
2854
|
+
DropdownMenuRadioItem.displayName = DropdownMenuPrimitive.RadioItem.displayName;
|
|
2855
|
+
var DropdownMenuLabel = React7.forwardRef(({ className, inset, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
2856
|
+
DropdownMenuPrimitive.Label,
|
|
2857
|
+
{
|
|
2858
|
+
ref,
|
|
2859
|
+
...slot(dropdownMenuAnatomy, "label"),
|
|
2860
|
+
className: cn(menuLabelClasses(PALETTE, "ds:text-[11px]"), inset && MENU_INSET, className),
|
|
2861
|
+
...props
|
|
2862
|
+
}
|
|
2863
|
+
));
|
|
2864
|
+
DropdownMenuLabel.displayName = DropdownMenuPrimitive.Label.displayName;
|
|
2865
|
+
var DropdownMenuSeparator = React7.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
2866
|
+
DropdownMenuPrimitive.Separator,
|
|
2867
|
+
{
|
|
2868
|
+
ref,
|
|
2869
|
+
...slot(dropdownMenuAnatomy, "separator"),
|
|
2870
|
+
className: cn(menuSeparatorClasses(PALETTE), className),
|
|
2871
|
+
...props
|
|
2872
|
+
}
|
|
2873
|
+
));
|
|
2874
|
+
DropdownMenuSeparator.displayName = DropdownMenuPrimitive.Separator.displayName;
|
|
2875
|
+
var DropdownMenuShortcut = ({ className, ...props }) => /* @__PURE__ */ jsx(
|
|
2876
|
+
"span",
|
|
2877
|
+
{
|
|
2878
|
+
...slot(dropdownMenuAnatomy, "shortcut"),
|
|
2879
|
+
className: cn(menuShortcutClasses(PALETTE, "ds:text-[11px]"), className),
|
|
2880
|
+
...props
|
|
2881
|
+
}
|
|
2882
|
+
);
|
|
2883
|
+
DropdownMenuShortcut.displayName = "DropdownMenuShortcut";
|
|
2884
|
+
var kindTile = {
|
|
2885
|
+
doc: "ds:bg-danger-bg ds:text-danger-fg",
|
|
2886
|
+
sheet: "ds:bg-success-bg ds:text-success-fg",
|
|
2887
|
+
image: "ds:bg-accent-tint ds:text-accent",
|
|
2888
|
+
generic: "ds:bg-bg-3 ds:text-fg-3"
|
|
2889
|
+
};
|
|
2890
|
+
var FileChip = forwardRef(function FileChip2({ name, meta, kind = "doc", icon, action, className, ...props }, ref) {
|
|
2891
|
+
return /* @__PURE__ */ jsxs(
|
|
2892
|
+
"div",
|
|
2893
|
+
{
|
|
2894
|
+
ref,
|
|
2895
|
+
className: cn(
|
|
2896
|
+
"ds:border-rule ds:bg-surface ds:flex ds:items-center ds:gap-3 ds:rounded-[var(--radius-input)] ds:border ds:p-2.5",
|
|
2897
|
+
className
|
|
2898
|
+
),
|
|
2899
|
+
...props,
|
|
2900
|
+
children: [
|
|
2901
|
+
/* @__PURE__ */ jsx(
|
|
2902
|
+
"span",
|
|
2903
|
+
{
|
|
2904
|
+
"aria-hidden": "true",
|
|
2905
|
+
className: cn(
|
|
2906
|
+
"ds:flex ds:size-9 ds:shrink-0 ds:items-center ds:justify-center ds:rounded-[var(--radius-icon)] ds:[&_svg]:size-4.5",
|
|
2907
|
+
kindTile[kind]
|
|
2908
|
+
),
|
|
2909
|
+
children: icon ?? /* @__PURE__ */ jsx(FileTextIcon, {})
|
|
2910
|
+
}
|
|
2911
|
+
),
|
|
2912
|
+
/* @__PURE__ */ jsxs("div", { className: "ds:min-w-0 ds:flex-1", children: [
|
|
2913
|
+
/* @__PURE__ */ jsx("p", { className: "ds:text-fg ds:truncate ds:text-sm ds:font-medium", children: name }),
|
|
2914
|
+
meta != null && /* @__PURE__ */ jsx("p", { className: "ds:text-fg-3 ds:truncate ds:text-xs", children: meta })
|
|
2915
|
+
] }),
|
|
2916
|
+
action && /* @__PURE__ */ jsx("div", { className: "ds:shrink-0", children: action })
|
|
2917
|
+
]
|
|
2918
|
+
}
|
|
2919
|
+
);
|
|
2920
|
+
});
|
|
2921
|
+
FileChip.displayName = "FileChip";
|
|
2922
|
+
var DROPZONE_LAYOUT = {
|
|
2923
|
+
default: "ds:flex ds:flex-col ds:items-center ds:justify-center ds:gap-2",
|
|
2924
|
+
compact: "ds:flex ds:flex-row ds:items-center ds:justify-start ds:gap-3"
|
|
2925
|
+
};
|
|
2926
|
+
var DROPZONE_SPACING = {
|
|
2927
|
+
default: "ds:font-body ds:p-8 ds:text-center",
|
|
2928
|
+
compact: "ds:font-body ds:p-3 ds:text-left"
|
|
2929
|
+
};
|
|
2930
|
+
function assignFiles(input, files) {
|
|
2931
|
+
try {
|
|
2932
|
+
const transfer = new DataTransfer();
|
|
2933
|
+
for (const file of files) transfer.items.add(file);
|
|
2934
|
+
input.files = transfer.files;
|
|
2935
|
+
} catch {
|
|
2936
|
+
input.value = "";
|
|
2937
|
+
}
|
|
2938
|
+
}
|
|
2939
|
+
function FileUpload({
|
|
2940
|
+
accept,
|
|
2941
|
+
maxSize,
|
|
2942
|
+
multiple,
|
|
2943
|
+
onFilesSelected,
|
|
2944
|
+
disabled,
|
|
2945
|
+
name,
|
|
2946
|
+
form,
|
|
2947
|
+
required,
|
|
2948
|
+
variant = "default",
|
|
2949
|
+
classNames,
|
|
2950
|
+
inputRef: inputRefProp,
|
|
2951
|
+
messages: messagesProp,
|
|
2952
|
+
className,
|
|
2953
|
+
children,
|
|
2954
|
+
...props
|
|
2955
|
+
}) {
|
|
2956
|
+
const messages = useDsMessages("fileUpload", messagesProp);
|
|
2957
|
+
const inputRef = useRef(null);
|
|
2958
|
+
const [isDragOver, setIsDragOver] = useState(false);
|
|
2959
|
+
const [error, setError] = useState(null);
|
|
2960
|
+
const wiring = useFieldControl({
|
|
2961
|
+
name,
|
|
2962
|
+
required,
|
|
2963
|
+
disabled,
|
|
2964
|
+
invalid: error ? true : void 0,
|
|
2965
|
+
"aria-describedby": props["aria-describedby"]
|
|
2966
|
+
});
|
|
2967
|
+
const inputId = wiring.id;
|
|
2968
|
+
const isDisabled = wiring.disabled;
|
|
2969
|
+
const ownsFiles = wiring.name !== void 0;
|
|
2970
|
+
const wrapperOwnsFocus = props.tabIndex !== void 0 || props.role !== void 0;
|
|
2971
|
+
const validateFiles = useCallback(
|
|
2972
|
+
(files) => {
|
|
2973
|
+
setError(null);
|
|
2974
|
+
const acceptTypes = accept ? accept.split(",").map((t) => t.trim()) : null;
|
|
2975
|
+
const valid = files.filter((file) => {
|
|
2976
|
+
if (acceptTypes) {
|
|
2977
|
+
const ext = `.${file.name.split(".").pop()?.toLowerCase()}`;
|
|
2978
|
+
const matchesType = acceptTypes.some(
|
|
2979
|
+
(type) => type === ext || type === file.type || type.endsWith("/*") && file.type.startsWith(type.replace("/*", "/"))
|
|
2980
|
+
);
|
|
2981
|
+
if (!matchesType) {
|
|
2982
|
+
setError(`File type not accepted: ${file.name}`);
|
|
2983
|
+
return false;
|
|
2984
|
+
}
|
|
2985
|
+
}
|
|
2986
|
+
if (maxSize && file.size > maxSize) {
|
|
2987
|
+
setError(`File too large: ${file.name} (max ${formatBytes(maxSize)})`);
|
|
2988
|
+
return false;
|
|
2989
|
+
}
|
|
2990
|
+
return true;
|
|
2991
|
+
});
|
|
2992
|
+
return valid;
|
|
2993
|
+
},
|
|
2994
|
+
[accept, maxSize]
|
|
2995
|
+
);
|
|
2996
|
+
function handleFiles(fileList, source) {
|
|
2997
|
+
const files = Array.from(fileList);
|
|
2998
|
+
const considered = multiple ? files : files.slice(0, 1);
|
|
2999
|
+
const valid = validateFiles(considered);
|
|
3000
|
+
const input = inputRef.current;
|
|
3001
|
+
if (input) {
|
|
3002
|
+
if (!ownsFiles) {
|
|
3003
|
+
input.value = "";
|
|
3004
|
+
} else if (source === "drop" || valid.length !== files.length) {
|
|
3005
|
+
assignFiles(input, valid);
|
|
3006
|
+
}
|
|
3007
|
+
}
|
|
3008
|
+
if (valid.length > 0) onFilesSelected?.(valid);
|
|
3009
|
+
}
|
|
3010
|
+
function handleDrop(e) {
|
|
3011
|
+
e.preventDefault();
|
|
3012
|
+
setIsDragOver(false);
|
|
3013
|
+
if (isDisabled) return;
|
|
3014
|
+
handleFiles(e.dataTransfer.files, "drop");
|
|
3015
|
+
}
|
|
3016
|
+
const defaultCopy = /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
3017
|
+
/* @__PURE__ */ jsxs("div", { className: "ds:text-fg-3 ds:text-sm", children: [
|
|
3018
|
+
/* @__PURE__ */ jsx("span", { className: "ds:text-fg ds:font-medium", children: messages.prompt }),
|
|
3019
|
+
messages.dragHint
|
|
3020
|
+
] }),
|
|
3021
|
+
accept && /* @__PURE__ */ jsx("p", { className: "ds:text-fg-4 ds:font-mono ds:text-[10.5px]", children: messages.accepted(accept) }),
|
|
3022
|
+
maxSize && /* @__PURE__ */ jsx("p", { className: "ds:text-fg-4 ds:font-mono ds:text-[10.5px]", children: messages.maxSize(formatBytes(maxSize)) })
|
|
3023
|
+
] });
|
|
3024
|
+
return /* @__PURE__ */ jsxs(
|
|
3025
|
+
"div",
|
|
3026
|
+
{
|
|
3027
|
+
...slot(fileUploadAnatomy, "root"),
|
|
3028
|
+
...stateAttributes({
|
|
3029
|
+
disabled: isDisabled,
|
|
3030
|
+
invalid: !!error,
|
|
3031
|
+
// Only when it is not the default: the default DOM is frozen (C-DOM-04).
|
|
3032
|
+
variant: variant === "default" ? void 0 : variant
|
|
3033
|
+
}),
|
|
3034
|
+
className: cn("ds:w-full", className),
|
|
3035
|
+
...props,
|
|
3036
|
+
children: [
|
|
3037
|
+
/* @__PURE__ */ jsxs(
|
|
3038
|
+
"label",
|
|
3039
|
+
{
|
|
3040
|
+
htmlFor: inputId,
|
|
3041
|
+
...slot(fileUploadAnatomy, "dropzone"),
|
|
3042
|
+
...stateAttributes({ disabled: isDisabled, state: isDragOver ? "drag-over" : void 0 }),
|
|
3043
|
+
onDragOver: (e) => {
|
|
3044
|
+
e.preventDefault();
|
|
3045
|
+
if (!isDisabled) setIsDragOver(true);
|
|
3046
|
+
},
|
|
3047
|
+
onDragLeave: () => setIsDragOver(false),
|
|
3048
|
+
onDrop: handleDrop,
|
|
3049
|
+
className: cn(
|
|
3050
|
+
DROPZONE_LAYOUT[variant],
|
|
3051
|
+
"ds:rounded-card ds:border-rule-strong ds:bg-surface ds:border ds:border-dashed",
|
|
3052
|
+
DROPZONE_SPACING[variant],
|
|
3053
|
+
"ds:transition-colors ds:duration-[var(--duration-fast)] ds:ease-[var(--ease-out-quart)]",
|
|
3054
|
+
"ds:motion-reduce:transition-none",
|
|
3055
|
+
// Hover (when not disabled)
|
|
3056
|
+
!isDisabled && "ds:hover:border-brand-line ds:hover:bg-brand-bg/40",
|
|
3057
|
+
// Drag-over → Pro purple highlight
|
|
3058
|
+
isDragOver && "ds:border-brand-line ds:bg-brand-bg",
|
|
3059
|
+
isDisabled && "ds:border-rule ds:bg-bg-disabled ds:text-fg-disabled ds:cursor-not-allowed",
|
|
3060
|
+
!isDisabled && "ds:cursor-pointer",
|
|
3061
|
+
// Keyboard focus lands on the (visually hidden) file input.
|
|
3062
|
+
"ds:has-[input:focus-visible]:[box-shadow:var(--shadow-focus-ring)]",
|
|
3063
|
+
slotClassName(classNames, "dropzone")
|
|
3064
|
+
),
|
|
3065
|
+
children: [
|
|
3066
|
+
/* @__PURE__ */ jsx(
|
|
3067
|
+
"input",
|
|
3068
|
+
{
|
|
3069
|
+
ref: mergeRefs(inputRef, inputRefProp, wiring.ref),
|
|
3070
|
+
id: inputId,
|
|
3071
|
+
name: wiring.name,
|
|
3072
|
+
form,
|
|
3073
|
+
type: "file",
|
|
3074
|
+
...slot(fileUploadAnatomy, "input"),
|
|
3075
|
+
accept,
|
|
3076
|
+
multiple,
|
|
3077
|
+
onChange: (e) => {
|
|
3078
|
+
if (e.target.files) handleFiles(e.target.files, "input");
|
|
3079
|
+
},
|
|
3080
|
+
className: cn(
|
|
3081
|
+
"ds:fixed ds:-top-[9999px] ds:-left-[9999px] ds:opacity-0",
|
|
3082
|
+
slotClassName(classNames, "input")
|
|
3083
|
+
),
|
|
3084
|
+
onKeyDown: (e) => {
|
|
3085
|
+
if (e.key !== "Enter" && e.key !== " ") return;
|
|
3086
|
+
e.preventDefault();
|
|
3087
|
+
e.currentTarget.click();
|
|
3088
|
+
},
|
|
3089
|
+
disabled: isDisabled,
|
|
3090
|
+
required: wiring.required,
|
|
3091
|
+
"aria-invalid": wiring["aria-invalid"],
|
|
3092
|
+
"aria-describedby": wiring["aria-describedby"],
|
|
3093
|
+
tabIndex: wrapperOwnsFocus ? -1 : void 0
|
|
3094
|
+
}
|
|
3095
|
+
),
|
|
3096
|
+
children ?? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
3097
|
+
/* @__PURE__ */ jsx(
|
|
3098
|
+
"div",
|
|
3099
|
+
{
|
|
3100
|
+
className: cn(
|
|
3101
|
+
"ds:rounded-icon ds:flex ds:size-10 ds:items-center ds:justify-center ds:transition-colors ds:duration-[var(--duration-fast)] ds:ease-[var(--ease-out-quart)] ds:motion-reduce:transition-none",
|
|
3102
|
+
variant === "compact" && "ds:shrink-0",
|
|
3103
|
+
isDragOver ? "ds:bg-brand ds:text-fg-on-brand" : "ds:bg-brand-bg ds:text-brand"
|
|
3104
|
+
),
|
|
3105
|
+
"aria-hidden": "true",
|
|
3106
|
+
children: /* @__PURE__ */ jsx(UploadIcon, { className: "ds:size-5" })
|
|
3107
|
+
}
|
|
3108
|
+
),
|
|
3109
|
+
variant === "compact" ? /* @__PURE__ */ jsx("div", { className: "ds:flex ds:min-w-0 ds:flex-col ds:gap-0.5", children: defaultCopy }) : defaultCopy
|
|
3110
|
+
] })
|
|
3111
|
+
]
|
|
3112
|
+
}
|
|
3113
|
+
),
|
|
3114
|
+
error && /* @__PURE__ */ jsx(
|
|
3115
|
+
"p",
|
|
3116
|
+
{
|
|
3117
|
+
role: "alert",
|
|
3118
|
+
...slot(fileUploadAnatomy, "error"),
|
|
3119
|
+
className: cn("ds:text-danger-fg ds:mt-2 ds:text-sm", slotClassName(classNames, "error")),
|
|
3120
|
+
children: error
|
|
3121
|
+
}
|
|
3122
|
+
)
|
|
3123
|
+
]
|
|
3124
|
+
}
|
|
3125
|
+
);
|
|
3126
|
+
}
|
|
3127
|
+
function formatBytes(bytes) {
|
|
3128
|
+
if (bytes < 1024) return `${bytes} B`;
|
|
3129
|
+
if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`;
|
|
3130
|
+
return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;
|
|
3131
|
+
}
|
|
3132
|
+
var CONTROL_CHROME = [
|
|
3133
|
+
"ds:flex ds:w-full ds:rounded-input ds:border ds:bg-surface ds:font-body ds:text-fg",
|
|
3134
|
+
microInteractions.control,
|
|
3135
|
+
"ds:placeholder:text-fg-4",
|
|
3136
|
+
"ds:focus-visible:outline-none ds:focus-visible:[border-color:var(--focus-ring-border)]",
|
|
3137
|
+
"ds:focus-visible:[box-shadow:var(--shadow-focus-ring-field)]",
|
|
3138
|
+
"ds:disabled:cursor-not-allowed ds:disabled:bg-bg-disabled ds:disabled:text-fg-disabled",
|
|
3139
|
+
"ds:aria-[invalid=true]:border-field-border-invalid ds:aria-[invalid=true]:focus-visible:border-danger-fg",
|
|
3140
|
+
"ds:aria-[invalid=true]:focus-visible:[box-shadow:0_0_0_2px_var(--color-danger-bg)]"
|
|
3141
|
+
].join(" ");
|
|
3142
|
+
var CONTROL_CHROME_VARIANTS = {
|
|
3143
|
+
default: "ds:border-field-border ds:not-disabled:hover:border-field-border-hover",
|
|
3144
|
+
ghost: "ds:border-transparent ds:bg-transparent ds:focus-visible:bg-surface"
|
|
3145
|
+
};
|
|
3146
|
+
var controlChrome = cva(CONTROL_CHROME, {
|
|
3147
|
+
variants: {
|
|
3148
|
+
variant: CONTROL_CHROME_VARIANTS,
|
|
3149
|
+
size: CONTROL_SIZE_CLASSES
|
|
3150
|
+
},
|
|
3151
|
+
defaultVariants: {
|
|
3152
|
+
variant: "default",
|
|
3153
|
+
size: "md"
|
|
3154
|
+
}
|
|
3155
|
+
});
|
|
3156
|
+
var INPUT_FILE_RESET = "ds:file:border-0 ds:file:bg-transparent ds:file:text-sm ds:file:font-medium";
|
|
3157
|
+
var isScaleRowSize = (size) => size === "xs" || size === "xl";
|
|
3158
|
+
var INPUT_SIZE_ROWS = {
|
|
3159
|
+
sm: "ds:h-(--control-height-sm) ds:px-2.5 ds:py-1 ds:text-xs",
|
|
3160
|
+
md: "ds:h-(--control-height-md) ds:px-3 ds:py-2 ds:text-(length:--control-font-size-md)",
|
|
3161
|
+
lg: "ds:h-(--input-height-lg) ds:px-3.5 ds:py-2.5 ds:text-sm",
|
|
3162
|
+
compact: "ds:h-(--control-height-sm) ds:px-2.5 ds:py-1 ds:text-(length:--control-font-size-md)",
|
|
3163
|
+
default: "ds:h-(--control-height-lg) ds:px-3 ds:py-2 ds:text-sm",
|
|
3164
|
+
comfortable: "ds:h-(--control-height-xl) ds:px-3.5 ds:py-2.5 ds:text-base"
|
|
3165
|
+
};
|
|
3166
|
+
function inputVariants({
|
|
3167
|
+
variant,
|
|
3168
|
+
size,
|
|
3169
|
+
inputSize,
|
|
3170
|
+
class: classProp,
|
|
3171
|
+
className
|
|
3172
|
+
} = {}) {
|
|
3173
|
+
const LEGACY_ROWS = {
|
|
3174
|
+
// The `inputSize` rows: today's classes, byte for byte (W2-03 compat).
|
|
3175
|
+
sm: "ds:h-8 ds:px-2.5 ds:py-1 ds:text-xs",
|
|
3176
|
+
md: "ds:h-9 ds:px-3 ds:py-2 ds:text-[13px]",
|
|
3177
|
+
lg: "ds:h-11 ds:px-3.5 ds:py-2.5 ds:text-sm",
|
|
3178
|
+
compact: "ds:h-8 ds:px-2.5 ds:py-1 ds:text-[13px]",
|
|
3179
|
+
default: "ds:h-10 ds:px-3 ds:py-2 ds:text-sm",
|
|
3180
|
+
comfortable: "ds:h-12 ds:px-3.5 ds:py-2.5 ds:text-base"
|
|
3181
|
+
};
|
|
3182
|
+
const resolved = size ?? inputSize ?? "md";
|
|
3183
|
+
const scale = isScaleRowSize(resolved);
|
|
3184
|
+
const row = scale ? null : size ? INPUT_SIZE_ROWS[resolved] : LEGACY_ROWS[resolved];
|
|
3185
|
+
return controlChrome({
|
|
3186
|
+
variant,
|
|
3187
|
+
size: scale ? resolved : null,
|
|
3188
|
+
class: cn(INPUT_FILE_RESET, row, classProp, className) || void 0
|
|
3189
|
+
});
|
|
3190
|
+
}
|
|
3191
|
+
var floatingLabelSize = {
|
|
3192
|
+
sm: "ds:text-xs",
|
|
3193
|
+
md: "ds:text-[13px]",
|
|
3194
|
+
lg: "ds:text-sm",
|
|
3195
|
+
compact: "ds:text-[13px]",
|
|
3196
|
+
default: "ds:text-sm",
|
|
3197
|
+
comfortable: "ds:text-base",
|
|
3198
|
+
xs: "ds:text-(length:--control-font-size-xs)",
|
|
3199
|
+
xl: "ds:text-(length:--control-font-size-xl)"
|
|
3200
|
+
};
|
|
3201
|
+
var Input = forwardRef(function Input2({
|
|
3202
|
+
label,
|
|
3203
|
+
floatingLabel,
|
|
3204
|
+
description,
|
|
3205
|
+
error,
|
|
3206
|
+
invalid,
|
|
3207
|
+
prefixIcon,
|
|
3208
|
+
suffixIcon,
|
|
3209
|
+
variant,
|
|
3210
|
+
size,
|
|
3211
|
+
inputSize,
|
|
3212
|
+
type = "text",
|
|
3213
|
+
className,
|
|
3214
|
+
classNames,
|
|
3215
|
+
rootClassName,
|
|
3216
|
+
id: providedId,
|
|
3217
|
+
name,
|
|
3218
|
+
required,
|
|
3219
|
+
disabled,
|
|
3220
|
+
readOnly,
|
|
3221
|
+
placeholder,
|
|
3222
|
+
onChange,
|
|
3223
|
+
onValueChange,
|
|
3224
|
+
onWheel,
|
|
3225
|
+
"aria-describedby": ariaDescribedBy,
|
|
3226
|
+
"aria-labelledby": ariaLabelledBy,
|
|
3227
|
+
...props
|
|
3228
|
+
}, ref) {
|
|
3229
|
+
const field = useFieldContext();
|
|
3230
|
+
const wiring = useFieldControl({
|
|
3231
|
+
id: providedId,
|
|
3232
|
+
name,
|
|
3233
|
+
invalid: error ? true : invalid,
|
|
3234
|
+
required,
|
|
3235
|
+
disabled,
|
|
3236
|
+
readOnly,
|
|
3237
|
+
"aria-labelledby": ariaLabelledBy,
|
|
3238
|
+
"aria-describedby": ariaDescribedBy
|
|
3239
|
+
});
|
|
3240
|
+
const { ref: wiringRef, "aria-describedby": wiredDescribedBy, ...control } = wiring;
|
|
3241
|
+
const id = control.id;
|
|
3242
|
+
const isInvalid = control["aria-invalid"] === true;
|
|
3243
|
+
const descriptionId = partId(id, "description");
|
|
3244
|
+
const errorId = partId(id, "error");
|
|
3245
|
+
const describedBy = joinIds(description && descriptionId, error && errorId, wiredDescribedBy);
|
|
3246
|
+
const inputRef = useMergedRefs(ref, wiringRef);
|
|
3247
|
+
const messages = useDsMessages("input");
|
|
3248
|
+
const [showPassword, setShowPassword] = useState(false);
|
|
3249
|
+
const isPassword = type === "password";
|
|
3250
|
+
const inputType = isPassword && showPassword ? "text" : type;
|
|
3251
|
+
const isFloating = !!floatingLabel && !!label;
|
|
3252
|
+
const fieldSize = field?.size;
|
|
3253
|
+
const recipe = size ? { variant, size } : inputSize ? { variant, inputSize } : fieldSize ? { variant, size: fieldSize } : { variant, inputSize: "md" };
|
|
3254
|
+
const resolvedSize = size ?? inputSize ?? fieldSize ?? "md";
|
|
3255
|
+
const resolvedPlaceholder = isFloating ? placeholder ?? " " : placeholder;
|
|
3256
|
+
const handleWheel = inputType === "number" ? (event) => {
|
|
3257
|
+
onWheel?.(event);
|
|
3258
|
+
if (!event.defaultPrevented) event.currentTarget.blur();
|
|
3259
|
+
} : onWheel;
|
|
3260
|
+
const handleChange = onValueChange ? (event) => {
|
|
3261
|
+
onChange?.(event);
|
|
3262
|
+
onValueChange(event.target.value);
|
|
3263
|
+
} : onChange;
|
|
3264
|
+
return /* @__PURE__ */ jsxs("div", { className: cn("ds:w-full", rootClassName), children: [
|
|
3265
|
+
label && !isFloating && /* @__PURE__ */ jsx(
|
|
3266
|
+
"label",
|
|
3267
|
+
{
|
|
3268
|
+
htmlFor: id,
|
|
3269
|
+
id: partId(id, "label"),
|
|
3270
|
+
...slot(inputAnatomy, "label"),
|
|
3271
|
+
className: cn(
|
|
3272
|
+
"ds:text-fg ds:mb-1.5 ds:block ds:text-[13px] ds:leading-none ds:font-medium",
|
|
3273
|
+
classNames?.label
|
|
3274
|
+
),
|
|
3275
|
+
children: label
|
|
3276
|
+
}
|
|
3277
|
+
),
|
|
3278
|
+
/* @__PURE__ */ jsxs("div", { className: "ds:relative", children: [
|
|
3279
|
+
prefixIcon && /* @__PURE__ */ jsx(
|
|
3280
|
+
"span",
|
|
3281
|
+
{
|
|
3282
|
+
...slot(inputAnatomy, "icon-start"),
|
|
3283
|
+
className: cn(
|
|
3284
|
+
"ds:text-fg-4 ds:pointer-events-none ds:absolute ds:top-1/2 ds:left-3 ds:-translate-y-1/2 ds:[&>svg]:size-4",
|
|
3285
|
+
classNames?.["icon-start"]
|
|
3286
|
+
),
|
|
3287
|
+
"aria-hidden": "true",
|
|
3288
|
+
children: prefixIcon
|
|
3289
|
+
}
|
|
3290
|
+
),
|
|
3291
|
+
/* @__PURE__ */ jsx(
|
|
3292
|
+
"input",
|
|
3293
|
+
{
|
|
3294
|
+
ref: inputRef,
|
|
3295
|
+
type: inputType,
|
|
3296
|
+
placeholder: resolvedPlaceholder,
|
|
3297
|
+
...control,
|
|
3298
|
+
"aria-describedby": describedBy,
|
|
3299
|
+
...slot(inputAnatomy, "root"),
|
|
3300
|
+
...stateAttributes({
|
|
3301
|
+
variant: variant ?? "default",
|
|
3302
|
+
size: resolvedSize,
|
|
3303
|
+
disabled: control.disabled,
|
|
3304
|
+
invalid: isInvalid
|
|
3305
|
+
}),
|
|
3306
|
+
className: cn(
|
|
3307
|
+
inputVariants(recipe),
|
|
3308
|
+
prefixIcon && "ds:pl-9",
|
|
3309
|
+
(suffixIcon || isPassword) && "ds:pr-9",
|
|
3310
|
+
isFloating && "ds:peer ds:focus:placeholder:text-fg-4 ds:placeholder:text-transparent",
|
|
3311
|
+
className
|
|
3312
|
+
),
|
|
3313
|
+
onWheel: handleWheel,
|
|
3314
|
+
onChange: handleChange,
|
|
3315
|
+
...props
|
|
3316
|
+
}
|
|
3317
|
+
),
|
|
3318
|
+
isFloating && // Rendered after the input because `peer-*` compiles to a sibling
|
|
3319
|
+
// combinator; absolute positioning keeps the visual order intact.
|
|
3320
|
+
/* @__PURE__ */ jsx(
|
|
3321
|
+
"label",
|
|
3322
|
+
{
|
|
3323
|
+
htmlFor: id,
|
|
3324
|
+
id: partId(id, "label"),
|
|
3325
|
+
...slot(inputAnatomy, "label"),
|
|
3326
|
+
className: cn(
|
|
3327
|
+
"ds:pointer-events-none ds:absolute ds:left-3 ds:origin-left ds:px-1 ds:leading-none",
|
|
3328
|
+
"ds:bg-surface ds:text-fg-4",
|
|
3329
|
+
"ds:top-1/2 ds:-translate-y-1/2",
|
|
3330
|
+
"ds:transition-[top,transform,color] ds:duration-[var(--duration-fast)] ds:ease-[var(--ease-out-quart)]",
|
|
3331
|
+
"ds:motion-reduce:transition-none",
|
|
3332
|
+
// Floated by focus or by content. Both branches declare the same
|
|
3333
|
+
// values, so their relative order in the emitted CSS is moot.
|
|
3334
|
+
"ds:peer-focus:top-0 ds:peer-focus:scale-[0.85]",
|
|
3335
|
+
"ds:peer-[:not(:placeholder-shown)]:top-0 ds:peer-[:not(:placeholder-shown)]:scale-[0.85]",
|
|
3336
|
+
// Colours are split on `:not(:focus)` so the two rules can never
|
|
3337
|
+
// both match, which would otherwise be an ordering coin flip.
|
|
3338
|
+
"ds:peer-focus:text-brand",
|
|
3339
|
+
"ds:peer-[:not(:placeholder-shown):not(:focus)]:text-fg-3",
|
|
3340
|
+
floatingLabelSize[resolvedSize],
|
|
3341
|
+
prefixIcon && "ds:left-9",
|
|
3342
|
+
classNames?.label
|
|
3343
|
+
),
|
|
3344
|
+
children: label
|
|
3345
|
+
}
|
|
3346
|
+
),
|
|
3347
|
+
isPassword && /* @__PURE__ */ jsx(
|
|
3348
|
+
"button",
|
|
3349
|
+
{
|
|
3350
|
+
type: "button",
|
|
3351
|
+
onClick: () => setShowPassword((prev) => !prev),
|
|
3352
|
+
...slot(inputAnatomy, "password-toggle"),
|
|
3353
|
+
className: cn(
|
|
3354
|
+
"ds:text-fg-4 ds:hover:text-fg ds:absolute ds:top-1/2 ds:right-2.5 ds:-translate-y-1/2 ds:transition-colors ds:duration-[var(--duration-fast)] ds:ease-[var(--ease-out-quart)] ds:focus-visible:[box-shadow:var(--shadow-focus-ring)] ds:focus-visible:outline-none ds:motion-reduce:transition-none",
|
|
3355
|
+
classNames?.["password-toggle"]
|
|
3356
|
+
),
|
|
3357
|
+
"aria-label": showPassword ? messages.hidePassword : messages.showPassword,
|
|
3358
|
+
children: showPassword ? /* @__PURE__ */ jsx(EyeOffIcon, { className: "ds:size-4", "aria-hidden": "true" }) : /* @__PURE__ */ jsx(EyeIcon, { className: "ds:size-4", "aria-hidden": "true" })
|
|
3359
|
+
}
|
|
3360
|
+
),
|
|
3361
|
+
suffixIcon && !isPassword && /* @__PURE__ */ jsx(
|
|
3362
|
+
"span",
|
|
3363
|
+
{
|
|
3364
|
+
...slot(inputAnatomy, "icon-end"),
|
|
3365
|
+
className: cn(
|
|
3366
|
+
"ds:text-fg-4 ds:pointer-events-none ds:absolute ds:top-1/2 ds:right-3 ds:-translate-y-1/2 ds:[&>svg]:size-4",
|
|
3367
|
+
classNames?.["icon-end"]
|
|
3368
|
+
),
|
|
3369
|
+
"aria-hidden": "true",
|
|
3370
|
+
children: suffixIcon
|
|
3371
|
+
}
|
|
3372
|
+
)
|
|
3373
|
+
] }),
|
|
3374
|
+
description && /* @__PURE__ */ jsx(
|
|
3375
|
+
"p",
|
|
3376
|
+
{
|
|
3377
|
+
id: descriptionId,
|
|
3378
|
+
...slot(inputAnatomy, "description"),
|
|
3379
|
+
className: cn("ds:text-fg-3 ds:mt-1.5 ds:text-xs", classNames?.description),
|
|
3380
|
+
children: description
|
|
3381
|
+
}
|
|
3382
|
+
),
|
|
3383
|
+
error && /* @__PURE__ */ jsx(
|
|
3384
|
+
"p",
|
|
3385
|
+
{
|
|
3386
|
+
id: errorId,
|
|
3387
|
+
role: "alert",
|
|
3388
|
+
...slot(inputAnatomy, "error"),
|
|
3389
|
+
className: cn("ds:text-danger-fg ds:mt-1.5 ds:text-xs", classNames?.error),
|
|
3390
|
+
children: error
|
|
3391
|
+
}
|
|
3392
|
+
)
|
|
3393
|
+
] });
|
|
3394
|
+
});
|
|
3395
|
+
Input.displayName = "Input";
|
|
3396
|
+
var TEXTAREA_SIZE_ROWS = {
|
|
3397
|
+
sm: "ds:min-h-(--textarea-min-height-sm) ds:px-2.5 ds:py-1.5 ds:text-xs",
|
|
3398
|
+
md: "ds:min-h-(--textarea-min-height-md) ds:px-3 ds:py-2 ds:text-(length:--control-font-size-md)",
|
|
3399
|
+
lg: "ds:min-h-(--textarea-min-height-lg) ds:px-3.5 ds:py-2.5 ds:text-sm"
|
|
3400
|
+
};
|
|
3401
|
+
function textareaVariants({
|
|
3402
|
+
variant,
|
|
3403
|
+
size,
|
|
3404
|
+
inputSize,
|
|
3405
|
+
class: classProp,
|
|
3406
|
+
className
|
|
3407
|
+
} = {}) {
|
|
3408
|
+
const LEGACY_ROWS = {
|
|
3409
|
+
sm: "ds:min-h-16 ds:px-2.5 ds:py-1.5 ds:text-xs",
|
|
3410
|
+
md: "ds:min-h-20 ds:px-3 ds:py-2 ds:text-[13px]",
|
|
3411
|
+
lg: "ds:min-h-24 ds:px-3.5 ds:py-2.5 ds:text-sm"
|
|
3412
|
+
};
|
|
3413
|
+
const row = size ? TEXTAREA_SIZE_ROWS[size] : LEGACY_ROWS[inputSize ?? "md"];
|
|
3414
|
+
return controlChrome({
|
|
3415
|
+
variant,
|
|
3416
|
+
size: null,
|
|
3417
|
+
class: cn(row, classProp, className) || void 0
|
|
3418
|
+
});
|
|
3419
|
+
}
|
|
3420
|
+
var Textarea = forwardRef(function Textarea2({
|
|
3421
|
+
label,
|
|
3422
|
+
description,
|
|
3423
|
+
error,
|
|
3424
|
+
invalid,
|
|
3425
|
+
showCount,
|
|
3426
|
+
autoResize,
|
|
3427
|
+
variant,
|
|
3428
|
+
size,
|
|
3429
|
+
inputSize,
|
|
3430
|
+
maxLength,
|
|
3431
|
+
value,
|
|
3432
|
+
defaultValue,
|
|
3433
|
+
className,
|
|
3434
|
+
classNames,
|
|
3435
|
+
rootClassName,
|
|
3436
|
+
id: providedId,
|
|
3437
|
+
name,
|
|
3438
|
+
required,
|
|
3439
|
+
disabled,
|
|
3440
|
+
readOnly,
|
|
3441
|
+
onChange,
|
|
3442
|
+
onValueChange,
|
|
3443
|
+
"aria-describedby": ariaDescribedBy,
|
|
3444
|
+
"aria-labelledby": ariaLabelledBy,
|
|
3445
|
+
...props
|
|
3446
|
+
}, ref) {
|
|
3447
|
+
const field = useFieldContext();
|
|
3448
|
+
const wiring = useFieldControl({
|
|
3449
|
+
id: providedId,
|
|
3450
|
+
name,
|
|
3451
|
+
invalid: error ? true : invalid,
|
|
3452
|
+
required,
|
|
3453
|
+
disabled,
|
|
3454
|
+
readOnly,
|
|
3455
|
+
"aria-labelledby": ariaLabelledBy,
|
|
3456
|
+
"aria-describedby": ariaDescribedBy
|
|
3457
|
+
});
|
|
3458
|
+
const { ref: wiringRef, "aria-describedby": wiredDescribedBy, ...control } = wiring;
|
|
3459
|
+
const id = control.id;
|
|
3460
|
+
const isInvalid = control["aria-invalid"] === true;
|
|
3461
|
+
const descriptionId = partId(id, "description");
|
|
3462
|
+
const errorId = partId(id, "error");
|
|
3463
|
+
const describedBy = joinIds(description && descriptionId, error && errorId, wiredDescribedBy);
|
|
3464
|
+
const internalRef = useRef(null);
|
|
3465
|
+
const setRefs = useMergedRefs(ref, wiringRef, internalRef);
|
|
3466
|
+
const adjustHeight = useCallback(() => {
|
|
3467
|
+
if (!autoResize || !internalRef.current) return;
|
|
3468
|
+
const el = internalRef.current;
|
|
3469
|
+
el.style.height = "auto";
|
|
3470
|
+
el.style.height = `${el.scrollHeight}px`;
|
|
3471
|
+
}, [autoResize]);
|
|
3472
|
+
useEffect(() => {
|
|
3473
|
+
adjustHeight();
|
|
3474
|
+
}, [value, adjustHeight]);
|
|
3475
|
+
const fieldSize = field?.size;
|
|
3476
|
+
const recipe = size ? { variant, size } : inputSize ? { variant, inputSize } : fieldSize && fieldSize in TEXTAREA_SIZE_ROWS ? { variant, size: fieldSize } : { variant, inputSize: "md" };
|
|
3477
|
+
const resolvedSize = recipe.size ?? recipe.inputSize ?? "md";
|
|
3478
|
+
const currentLength = typeof value === "string" ? value.length : typeof defaultValue === "string" ? defaultValue.length : 0;
|
|
3479
|
+
return /* @__PURE__ */ jsxs("div", { className: cn("ds:w-full", rootClassName), children: [
|
|
3480
|
+
label && /* @__PURE__ */ jsx(
|
|
3481
|
+
"label",
|
|
3482
|
+
{
|
|
3483
|
+
htmlFor: id,
|
|
3484
|
+
id: partId(id, "label"),
|
|
3485
|
+
...slot(textareaAnatomy, "label"),
|
|
3486
|
+
className: cn(
|
|
3487
|
+
"ds:text-fg ds:mb-1.5 ds:block ds:text-[13px] ds:leading-none ds:font-medium",
|
|
3488
|
+
classNames?.label
|
|
3489
|
+
),
|
|
3490
|
+
children: label
|
|
3491
|
+
}
|
|
3492
|
+
),
|
|
3493
|
+
/* @__PURE__ */ jsx(
|
|
3494
|
+
"textarea",
|
|
3495
|
+
{
|
|
3496
|
+
ref: setRefs,
|
|
3497
|
+
value,
|
|
3498
|
+
defaultValue,
|
|
3499
|
+
maxLength,
|
|
3500
|
+
...control,
|
|
3501
|
+
"aria-describedby": describedBy,
|
|
3502
|
+
...slot(textareaAnatomy, "root"),
|
|
3503
|
+
...stateAttributes({
|
|
3504
|
+
variant: variant ?? "default",
|
|
3505
|
+
size: resolvedSize,
|
|
3506
|
+
disabled: control.disabled,
|
|
3507
|
+
invalid: isInvalid
|
|
3508
|
+
}),
|
|
3509
|
+
onChange: (e) => {
|
|
3510
|
+
onChange?.(e);
|
|
3511
|
+
onValueChange?.(e.target.value);
|
|
3512
|
+
adjustHeight();
|
|
3513
|
+
},
|
|
3514
|
+
className: cn(
|
|
3515
|
+
textareaVariants(recipe),
|
|
3516
|
+
autoResize && "ds:resize-none ds:overflow-hidden",
|
|
3517
|
+
className
|
|
3518
|
+
),
|
|
3519
|
+
...props
|
|
3520
|
+
}
|
|
3521
|
+
),
|
|
3522
|
+
description && /* @__PURE__ */ jsx(
|
|
3523
|
+
"p",
|
|
3524
|
+
{
|
|
3525
|
+
id: descriptionId,
|
|
3526
|
+
...slot(textareaAnatomy, "description"),
|
|
3527
|
+
className: cn("ds:text-fg-3 ds:mt-1.5 ds:text-xs", classNames?.description),
|
|
3528
|
+
children: description
|
|
3529
|
+
}
|
|
3530
|
+
),
|
|
3531
|
+
(error || showCount && maxLength) && /* @__PURE__ */ jsxs("div", { className: "ds:mt-1.5 ds:flex ds:items-center ds:justify-between ds:gap-2", children: [
|
|
3532
|
+
error ? /* @__PURE__ */ jsx(
|
|
3533
|
+
"p",
|
|
3534
|
+
{
|
|
3535
|
+
id: errorId,
|
|
3536
|
+
role: "alert",
|
|
3537
|
+
...slot(textareaAnatomy, "error"),
|
|
3538
|
+
className: cn("ds:text-danger-fg ds:text-xs", classNames?.error),
|
|
3539
|
+
children: error
|
|
3540
|
+
}
|
|
3541
|
+
) : /* @__PURE__ */ jsx("span", {}),
|
|
3542
|
+
showCount && maxLength && /* @__PURE__ */ jsxs(
|
|
3543
|
+
"span",
|
|
3544
|
+
{
|
|
3545
|
+
...slot(textareaAnatomy, "count"),
|
|
3546
|
+
className: cn(
|
|
3547
|
+
"ds:text-fg-4 ds:ml-auto ds:font-mono ds:text-[11px]",
|
|
3548
|
+
classNames?.count
|
|
3549
|
+
),
|
|
3550
|
+
children: [
|
|
3551
|
+
currentLength,
|
|
3552
|
+
"/",
|
|
3553
|
+
maxLength
|
|
3554
|
+
]
|
|
3555
|
+
}
|
|
3556
|
+
)
|
|
3557
|
+
] })
|
|
3558
|
+
] });
|
|
3559
|
+
});
|
|
3560
|
+
Textarea.displayName = "Textarea";
|
|
3561
|
+
var DocumentDetailPanel = forwardRef(
|
|
3562
|
+
function DocumentDetailPanel2({ className, ...props }, ref) {
|
|
3563
|
+
return /* @__PURE__ */ jsx(
|
|
3564
|
+
"aside",
|
|
3565
|
+
{
|
|
3566
|
+
ref,
|
|
3567
|
+
className: cn(
|
|
3568
|
+
"ds:bg-surface ds:text-fg ds:border-rule ds:flex ds:h-full ds:min-h-0 ds:flex-col ds:border-l",
|
|
3569
|
+
className
|
|
3570
|
+
),
|
|
3571
|
+
...props
|
|
3572
|
+
}
|
|
3573
|
+
);
|
|
3574
|
+
}
|
|
3575
|
+
);
|
|
3576
|
+
DocumentDetailPanel.displayName = "DocumentDetailPanel";
|
|
3577
|
+
var DocumentDetailHeader = forwardRef(
|
|
3578
|
+
function DocumentDetailHeader2({ tags, status, onClose, className, children, ...props }, ref) {
|
|
3579
|
+
const showControls = Boolean(status || onClose);
|
|
3580
|
+
const tagsClearance = !showControls ? void 0 : status ? "ds:pr-32" : "ds:pr-12";
|
|
3581
|
+
const titleClearance = !showControls || tags ? void 0 : status ? "ds:[&>:first-child]:pr-32" : "ds:[&>:first-child]:pr-12";
|
|
3582
|
+
return /* @__PURE__ */ jsxs(
|
|
3583
|
+
"div",
|
|
3584
|
+
{
|
|
3585
|
+
ref,
|
|
3586
|
+
className: cn("ds:border-rule ds:relative ds:shrink-0 ds:space-y-3 ds:border-b ds:px-5 ds:py-4", className),
|
|
3587
|
+
...props,
|
|
3588
|
+
children: [
|
|
3589
|
+
showControls && /* @__PURE__ */ jsxs("div", { className: "ds:absolute ds:top-4 ds:right-5 ds:z-[calc(var(--z-base)+10)] ds:flex ds:shrink-0 ds:items-center ds:gap-2", children: [
|
|
3590
|
+
status,
|
|
3591
|
+
onClose && /* @__PURE__ */ jsx(
|
|
3592
|
+
"button",
|
|
3593
|
+
{
|
|
3594
|
+
type: "button",
|
|
3595
|
+
onClick: onClose,
|
|
3596
|
+
"aria-label": "Close",
|
|
3597
|
+
className: cn(
|
|
3598
|
+
"ds:inline-flex ds:size-7 ds:shrink-0 ds:items-center ds:justify-center",
|
|
3599
|
+
"ds:rounded-icon ds:text-fg-4 ds:transition-colors ds:duration-[var(--duration-fast)] ds:ease-[var(--ease-out-quart)] ds:motion-reduce:transition-none",
|
|
3600
|
+
"ds:hover:bg-overlay-hover ds:hover:text-fg",
|
|
3601
|
+
"ds:focus-visible:[box-shadow:var(--shadow-focus-ring)] ds:focus-visible:outline-none"
|
|
3602
|
+
),
|
|
3603
|
+
children: /* @__PURE__ */ jsx(XIcon, { className: "ds:size-4", "aria-hidden": "true" })
|
|
3604
|
+
}
|
|
3605
|
+
)
|
|
3606
|
+
] }),
|
|
3607
|
+
tags && /* @__PURE__ */ jsx("div", { className: cn("ds:flex ds:min-w-0 ds:flex-wrap ds:items-center ds:gap-1.5", tagsClearance), children: tags }),
|
|
3608
|
+
/* @__PURE__ */ jsx("div", { className: cn("ds:space-y-3", titleClearance), children })
|
|
3609
|
+
]
|
|
3610
|
+
}
|
|
3611
|
+
);
|
|
3612
|
+
}
|
|
3613
|
+
);
|
|
3614
|
+
DocumentDetailHeader.displayName = "DocumentDetailHeader";
|
|
3615
|
+
var DocumentDetailTitle = forwardRef(
|
|
3616
|
+
function DocumentDetailTitle2({ className, children, ...props }, ref) {
|
|
3617
|
+
return /* @__PURE__ */ jsx(
|
|
3618
|
+
"h2",
|
|
3619
|
+
{
|
|
3620
|
+
ref,
|
|
3621
|
+
className: cn(
|
|
3622
|
+
"ds:font-display ds:text-fg ds:text-lg ds:leading-snug ds:font-semibold ds:tracking-tight",
|
|
3623
|
+
className
|
|
3624
|
+
),
|
|
3625
|
+
...props,
|
|
3626
|
+
children
|
|
3627
|
+
}
|
|
3628
|
+
);
|
|
3629
|
+
}
|
|
3630
|
+
);
|
|
3631
|
+
DocumentDetailTitle.displayName = "DocumentDetailTitle";
|
|
3632
|
+
var DocumentDetailRequester = forwardRef(
|
|
3633
|
+
function DocumentDetailRequester2({ avatar, org, requestedBy, time, className, ...props }, ref) {
|
|
3634
|
+
const isImageSrc = /^(https?:|data:|\/)/i.test(avatar);
|
|
3635
|
+
return /* @__PURE__ */ jsxs("div", { ref, className: cn("ds:flex ds:items-center ds:gap-2.5", className), ...props, children: [
|
|
3636
|
+
/* @__PURE__ */ jsx(Avatar, { size: "sm", src: isImageSrc ? avatar : void 0, name: isImageSrc ? org : avatar }),
|
|
3637
|
+
/* @__PURE__ */ jsxs("div", { className: "ds:min-w-0", children: [
|
|
3638
|
+
/* @__PURE__ */ jsx("div", { className: "ds:text-fg ds:line-clamp-1 ds:text-sm ds:font-medium", children: org }),
|
|
3639
|
+
/* @__PURE__ */ jsxs("div", { className: "ds:text-fg-4 ds:text-xs", children: [
|
|
3640
|
+
"Requested by ",
|
|
3641
|
+
requestedBy,
|
|
3642
|
+
" \xB7 ",
|
|
3643
|
+
time
|
|
3644
|
+
] })
|
|
3645
|
+
] })
|
|
3646
|
+
] });
|
|
3647
|
+
}
|
|
3648
|
+
);
|
|
3649
|
+
DocumentDetailRequester.displayName = "DocumentDetailRequester";
|
|
3650
|
+
var DocumentDetailMetaRow = forwardRef(
|
|
3651
|
+
function DocumentDetailMetaRow2({ className, ...props }, ref) {
|
|
3652
|
+
return /* @__PURE__ */ jsx(
|
|
3653
|
+
"div",
|
|
3654
|
+
{
|
|
3655
|
+
ref,
|
|
3656
|
+
className: cn("ds:flex ds:items-center ds:justify-between ds:gap-3", className),
|
|
3657
|
+
...props
|
|
3658
|
+
}
|
|
3659
|
+
);
|
|
3660
|
+
}
|
|
3661
|
+
);
|
|
3662
|
+
DocumentDetailMetaRow.displayName = "DocumentDetailMetaRow";
|
|
3663
|
+
var DocumentDetailActions = forwardRef(
|
|
3664
|
+
function DocumentDetailActions2({ className, ...props }, ref) {
|
|
3665
|
+
return /* @__PURE__ */ jsx(
|
|
3666
|
+
"div",
|
|
3667
|
+
{
|
|
3668
|
+
ref,
|
|
3669
|
+
className: cn("ds:flex ds:flex-wrap ds:items-center ds:gap-2 ds:[&>*]:flex-1", className),
|
|
3670
|
+
...props
|
|
3671
|
+
}
|
|
3672
|
+
);
|
|
3673
|
+
}
|
|
3674
|
+
);
|
|
3675
|
+
DocumentDetailActions.displayName = "DocumentDetailActions";
|
|
3676
|
+
var DocumentDetailBody = forwardRef(
|
|
3677
|
+
function DocumentDetailBody2({ className, ...props }, ref) {
|
|
3678
|
+
return /* @__PURE__ */ jsx(
|
|
3679
|
+
"div",
|
|
3680
|
+
{
|
|
3681
|
+
ref,
|
|
3682
|
+
className: cn("ds:scrollbar-thin ds:min-h-0 ds:flex-1 ds:overflow-y-auto ds:px-5 ds:py-4", className),
|
|
3683
|
+
...props
|
|
3684
|
+
}
|
|
3685
|
+
);
|
|
3686
|
+
}
|
|
3687
|
+
);
|
|
3688
|
+
DocumentDetailBody.displayName = "DocumentDetailBody";
|
|
3689
|
+
var DocumentList = forwardRef(function DocumentList2({ className, ...props }, ref) {
|
|
3690
|
+
return /* @__PURE__ */ jsx("div", { ref, className: cn("ds:space-y-5", className), ...props });
|
|
3691
|
+
});
|
|
3692
|
+
DocumentList.displayName = "DocumentList";
|
|
3693
|
+
var DocumentListSection = forwardRef(
|
|
3694
|
+
function DocumentListSection2({ label, count, action, className, children, ...props }, ref) {
|
|
3695
|
+
return /* @__PURE__ */ jsxs("section", { ref, className: cn("ds:space-y-1", className), ...props, children: [
|
|
3696
|
+
/* @__PURE__ */ jsxs("div", { className: "ds:flex ds:items-center ds:justify-between ds:gap-2 ds:px-2.5 ds:py-1", children: [
|
|
3697
|
+
/* @__PURE__ */ jsxs("div", { className: "ds:text-fg-3 ds:flex ds:items-center ds:gap-1.5 ds:text-xs ds:font-medium", children: [
|
|
3698
|
+
/* @__PURE__ */ jsx("span", { children: label }),
|
|
3699
|
+
count != null && /* @__PURE__ */ jsx("span", { className: "ds:text-fg-4 ds:tabular-nums", children: count })
|
|
3700
|
+
] }),
|
|
3701
|
+
action
|
|
3702
|
+
] }),
|
|
3703
|
+
/* @__PURE__ */ jsx("div", { className: "ds:space-y-0.5", children })
|
|
3704
|
+
] });
|
|
3705
|
+
}
|
|
3706
|
+
);
|
|
3707
|
+
DocumentListSection.displayName = "DocumentListSection";
|
|
3708
|
+
var DocumentRow = forwardRef(function DocumentRow2({ fileName, meta, icon, approved, rejected, actions, className, ...props }, ref) {
|
|
3709
|
+
return /* @__PURE__ */ jsxs(
|
|
3710
|
+
"div",
|
|
3711
|
+
{
|
|
3712
|
+
ref,
|
|
3713
|
+
className: cn(
|
|
3714
|
+
"ds:group/row ds:rounded-card ds:flex ds:items-center ds:gap-3 ds:px-2.5 ds:py-2",
|
|
3715
|
+
"ds:transition-colors ds:duration-[var(--duration-fast)] ds:ease-[var(--ease-out-quart)] ds:motion-reduce:transition-none",
|
|
3716
|
+
"ds:hover:bg-overlay-hover",
|
|
3717
|
+
className
|
|
3718
|
+
),
|
|
3719
|
+
...props,
|
|
3720
|
+
children: [
|
|
3721
|
+
/* @__PURE__ */ jsx(
|
|
3722
|
+
"span",
|
|
3723
|
+
{
|
|
3724
|
+
"aria-hidden": "true",
|
|
3725
|
+
className: cn(
|
|
3726
|
+
"ds:rounded-icon ds:inline-flex ds:size-9 ds:shrink-0 ds:items-center ds:justify-center",
|
|
3727
|
+
approved ? "ds:bg-success-bg ds:text-success-fg" : rejected ? "ds:bg-danger-bg ds:text-danger-fg" : "ds:bg-bg-2 ds:text-fg-3"
|
|
3728
|
+
),
|
|
3729
|
+
children: icon ?? /* @__PURE__ */ jsx(FileTextIcon, { className: "ds:size-4.5" })
|
|
3730
|
+
}
|
|
3731
|
+
),
|
|
3732
|
+
/* @__PURE__ */ jsxs("div", { className: "ds:min-w-0 ds:flex-1", children: [
|
|
3733
|
+
/* @__PURE__ */ jsxs("div", { className: "ds:flex ds:min-w-0 ds:items-center ds:gap-1.5", children: [
|
|
3734
|
+
/* @__PURE__ */ jsx("span", { className: "ds:text-fg ds:line-clamp-1 ds:min-w-0 ds:text-sm ds:font-medium", children: fileName }),
|
|
3735
|
+
approved ? /* @__PURE__ */ jsxs("span", { className: "ds:bg-success-bg ds:text-success-fg ds:inline-flex ds:shrink-0 ds:items-center ds:gap-1 ds:rounded-md ds:px-1.5 ds:py-0.5 ds:text-[10.5px] ds:font-semibold", children: [
|
|
3736
|
+
/* @__PURE__ */ jsx(CheckIcon, { className: "ds:size-3", "aria-hidden": "true" }),
|
|
3737
|
+
"Approved"
|
|
3738
|
+
] }) : rejected ? /* @__PURE__ */ jsxs("span", { className: "ds:bg-danger-bg ds:text-danger-fg ds:inline-flex ds:shrink-0 ds:items-center ds:gap-1 ds:rounded-md ds:px-1.5 ds:py-0.5 ds:text-[10.5px] ds:font-semibold", children: [
|
|
3739
|
+
/* @__PURE__ */ jsx(AlertTriangleIcon, { className: "ds:size-3", "aria-hidden": "true" }),
|
|
3740
|
+
"Rejected"
|
|
3741
|
+
] }) : null
|
|
3742
|
+
] }),
|
|
3743
|
+
meta && /* @__PURE__ */ jsx("div", { className: "ds:text-fg-4 ds:line-clamp-1 ds:text-xs", children: meta })
|
|
3744
|
+
] }),
|
|
3745
|
+
actions && /* @__PURE__ */ jsx("div", { className: "ds:flex ds:shrink-0 ds:items-center ds:gap-0.5", children: actions })
|
|
3746
|
+
]
|
|
3747
|
+
}
|
|
3748
|
+
);
|
|
3749
|
+
});
|
|
3750
|
+
DocumentRow.displayName = "DocumentRow";
|
|
3751
|
+
|
|
3752
|
+
export { Avatar, Backdrop, Button, CONTROL_GAP_CLASSES, CONTROL_SIZE_CLASSES, Checkbox, DEFAULT_OVERLAY_MESSAGES, DISABLED_LOOK_CLASSES, DISMISS_GLYPH_CLASSES, DesignSystemContext, DismissButton, DocumentDetailActions, DocumentDetailBody, DocumentDetailHeader, DocumentDetailMetaRow, DocumentDetailPanel, DocumentDetailRequester, DocumentDetailTitle, DocumentList, DocumentListSection, DocumentRow, DropdownMenu, DropdownMenuCheckboxItem, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel, DropdownMenuPortal, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuSeparator, DropdownMenuShortcut, DropdownMenuSub, DropdownMenuSubContent, DropdownMenuSubTrigger, DropdownMenuTrigger, EN_MESSAGES, FIELD_PARTS, FLOATING_PADDING, FLOATING_WIDTH, FieldContext, FieldsetContext, FileChip, FileUpload, FormBridge, INERT_ATTRIBUTES, INERT_CLASSES, IconButton, Input, LIST_ITEM_INDICATOR_WELL, LIST_SEPARATOR, MENU_CHECK_GLYPH, MENU_INDICATOR_WELL, MENU_INSET, MENU_ITEM_DANGER, MENU_RADIO_GLYPH, MENU_SUB_TRIGGER_CHEVRON, ModalContent, ModalDescription, ModalOverlay, ModalPortal, ModalRoot, ModalTitle, OverlayBody, OverlayDescription, OverlayFooter, OverlayHeader, OverlaySurface, OverlayTitle, Popover, PopoverAnchor, PopoverClose, PopoverContent, PopoverPortal, PopoverTrigger, Portal, PortalContainerContext, Pressable, SPINNER_TONE_TO_INTENT, Select, SelectContent, SelectGroup, SelectItem, SelectLabel, SelectRoot, SelectScrollDownButton, SelectScrollUpButton, SelectSeparator, SelectTrigger, SelectValue, Spinner, TOOLTIP_DEFAULT_DELAY_MS, Textarea, ThemeScope, Tooltip, TooltipContent, TooltipPortal, TooltipProvider, TooltipTrigger, alertDialogAnatomy, badgeAnatomy, buttonBase, buttonVariants, cardAnatomy, chipAnatomy, codeAnatomy, comboboxAnatomy, commandAnatomy, contextMenuAnatomy, controlChrome, dataTableAnatomy, deprecate, dialogAnatomy, errorOnce, fieldAnatomy, fieldsetAnatomy, floatingSurfaceClasses, groupHeadingClasses, headingAnatomy, iconButtonVariants, inertHandlers, inlineAnatomy, inputVariants, isLabelable, joinIds, kbdAnatomy, labelAnatomy, linkButtonAnatomy, listItemAttributes, listItemClasses, menuIndicatorItemClasses, menuItemClasses, menuLabelClasses, menuSeparatorClasses, menuShortcutClasses, menuSubTriggerClasses, mergeRefs, microInteractions, numberInputAnatomy, optionElementId, paginationAnatomy, partId, phoneFieldAnatomy, presence, radioGroupAnatomy, resolveButtonIcons, resolveButtonStyle, searchInputAnatomy, sheetAnatomy, shellAnatomy, sideDrawerAnatomy, sidebarAnatomy, sidebarBrandSwitcherAnatomy, slot, spinnerVariants, stackAnatomy, stateAttributes, statusBadgeAnatomy, surfaceAnatomy, switchAnatomy, tableAnatomy, textAnatomy, textareaVariants, toastAnatomy, useControllableState, useDsMessages, useExitPresence, useFieldContext, useFieldControl, useFieldsetContext, useFieldsetLegend, useFieldsetState, useFormReset, useId, useImageComponent, useLinkComponent, useMergedRefs, warnLegacyButtonProps, withPortalContainer };
|
|
3753
|
+
//# sourceMappingURL=chunk-NBI7E3VT.js.map
|
|
3754
|
+
//# sourceMappingURL=chunk-NBI7E3VT.js.map
|