@tutti-os/ui-system 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +146 -0
- package/LICENSE +202 -0
- package/README.md +97 -0
- package/agent/install-skill.mjs +241 -0
- package/agent/nextop-ui-system/SKILL.md +227 -0
- package/agent/nextop-ui-system/references/extract-base-component.md +87 -0
- package/agent/nextop-ui-system/references/maintain-inventory.md +45 -0
- package/agent/nextop-ui-system/references/promote-business-component.md +316 -0
- package/agent/nextop-ui-system/references/use-existing-component.md +37 -0
- package/agent/nextop-ui-system/scripts/create-business-preview.mjs +658 -0
- package/dist/chunk-2AUYRRDG.js +3078 -0
- package/dist/chunk-2AUYRRDG.js.map +1 -0
- package/dist/chunk-DGPY4WP3.js +11 -0
- package/dist/chunk-DGPY4WP3.js.map +1 -0
- package/dist/chunk-GX3U3V36.js +70 -0
- package/dist/chunk-GX3U3V36.js.map +1 -0
- package/dist/chunk-UTUVPSKL.js +873 -0
- package/dist/chunk-UTUVPSKL.js.map +1 -0
- package/dist/chunk-XHA7R2WC.js +292 -0
- package/dist/chunk-XHA7R2WC.js.map +1 -0
- package/dist/components/index.d.ts +360 -0
- package/dist/components/index.js +221 -0
- package/dist/components/index.js.map +1 -0
- package/dist/date-format.d.ts +6 -0
- package/dist/date-format.js +11 -0
- package/dist/date-format.js.map +1 -0
- package/dist/dev-vite.d.ts +9 -0
- package/dist/dev-vite.js +583 -0
- package/dist/dev-vite.js.map +1 -0
- package/dist/icons/index.d.ts +112 -0
- package/dist/icons/index.js +191 -0
- package/dist/icons/index.js.map +1 -0
- package/dist/index.d.ts +13 -0
- package/dist/index.js +419 -0
- package/dist/index.js.map +1 -0
- package/dist/metadata/components.json +2819 -0
- package/dist/metadata/components.schema.json +110 -0
- package/dist/metadata/index.d.ts +27 -0
- package/dist/metadata/index.js +2827 -0
- package/dist/metadata/index.js.map +1 -0
- package/dist/styles/base.css +170 -0
- package/dist/styles/index.css +4 -0
- package/dist/styles/semantic.css +50 -0
- package/dist/styles/theme.css +366 -0
- package/dist/utils.d.ts +5 -0
- package/dist/utils.js +7 -0
- package/dist/utils.js.map +1 -0
- package/package.json +118 -0
- package/ui-system.md +671 -0
|
@@ -0,0 +1,3078 @@
|
|
|
1
|
+
import {
|
|
2
|
+
AgentSessionsIcon,
|
|
3
|
+
AppWindowIcon,
|
|
4
|
+
ArrowLeftIcon,
|
|
5
|
+
ArrowRightIcon,
|
|
6
|
+
CheckIcon,
|
|
7
|
+
ChevronDownIcon,
|
|
8
|
+
ChevronUpIcon,
|
|
9
|
+
CloseIcon,
|
|
10
|
+
FailedFilledIcon,
|
|
11
|
+
FileIcon,
|
|
12
|
+
FolderFilledIcon,
|
|
13
|
+
IssueIcon,
|
|
14
|
+
LoadingIcon,
|
|
15
|
+
SuccessFilledIcon,
|
|
16
|
+
WarningFilledIcon,
|
|
17
|
+
WarningLinedIcon
|
|
18
|
+
} from "./chunk-UTUVPSKL.js";
|
|
19
|
+
import {
|
|
20
|
+
cn
|
|
21
|
+
} from "./chunk-DGPY4WP3.js";
|
|
22
|
+
|
|
23
|
+
// src/components/badge/badge.tsx
|
|
24
|
+
import { cva } from "class-variance-authority";
|
|
25
|
+
import { Slot } from "radix-ui";
|
|
26
|
+
import { jsx } from "react/jsx-runtime";
|
|
27
|
+
var badgeVariants = cva(
|
|
28
|
+
"group/badge inline-flex h-5 w-fit shrink-0 items-center justify-center gap-1 overflow-hidden rounded-[4px] border border-transparent px-1 py-0.5 text-[0.72rem] font-normal whitespace-nowrap transition-[background-color,border-color,color,box-shadow] focus-visible:border-ring focus-visible:ring-2 focus-visible:ring-ring/35 has-data-[icon=inline-end]:pr-1.5 has-data-[icon=inline-start]:pl-1.5 aria-invalid:border-destructive aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 [&>svg]:pointer-events-none [&>svg]:size-3!",
|
|
29
|
+
{
|
|
30
|
+
variants: {
|
|
31
|
+
variant: {
|
|
32
|
+
default: "bg-[var(--transparency-block)] text-[var(--text-secondary)] [a]:hover:bg-[var(--transparency-hover)]",
|
|
33
|
+
accent: "bg-[var(--accent-bg)] text-[var(--accent)] [a]:hover:bg-[var(--accent-bg)]",
|
|
34
|
+
success: "bg-[color-mix(in_srgb,var(--state-success)_10%,transparent)] text-[var(--state-success)] [a]:hover:bg-[color-mix(in_srgb,var(--state-success)_14%,transparent)]",
|
|
35
|
+
warning: "bg-[color-mix(in_srgb,var(--state-warning)_12%,transparent)] text-[var(--state-warning)] [a]:hover:bg-[color-mix(in_srgb,var(--state-warning)_16%,transparent)]",
|
|
36
|
+
pending: "bg-[color-mix(in_srgb,var(--rich-text-mention-issue)_12%,transparent)] text-[var(--rich-text-mention-issue)] [a]:hover:bg-[color-mix(in_srgb,var(--rich-text-mention-issue)_16%,transparent)]",
|
|
37
|
+
muted: "bg-[color-mix(in_srgb,var(--transparency-block)_72%,transparent)] text-[var(--text-tertiary)] [a]:hover:bg-[var(--transparency-hover)]",
|
|
38
|
+
secondary: "bg-[var(--transparency-block)] text-[var(--text-secondary)] [a]:hover:bg-[var(--transparency-hover)]",
|
|
39
|
+
destructive: "bg-[var(--on-danger)] text-[var(--state-danger)] focus-visible:ring-[color-mix(in_srgb,var(--state-danger)_20%,transparent)] [a]:hover:bg-[var(--on-danger-hover)]",
|
|
40
|
+
outline: "border-border bg-card/90 text-foreground [a]:hover:bg-muted [a]:hover:text-foreground",
|
|
41
|
+
ghost: "hover:bg-accent/80 hover:text-accent-foreground dark:hover:bg-muted/50",
|
|
42
|
+
link: "text-primary underline-offset-4 hover:underline"
|
|
43
|
+
}
|
|
44
|
+
},
|
|
45
|
+
defaultVariants: {
|
|
46
|
+
variant: "default"
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
);
|
|
50
|
+
function Badge({
|
|
51
|
+
className,
|
|
52
|
+
variant = "default",
|
|
53
|
+
asChild = false,
|
|
54
|
+
...props
|
|
55
|
+
}) {
|
|
56
|
+
const Comp = asChild ? Slot.Root : "span";
|
|
57
|
+
return /* @__PURE__ */ jsx(
|
|
58
|
+
Comp,
|
|
59
|
+
{
|
|
60
|
+
"data-slot": "badge",
|
|
61
|
+
"data-variant": variant,
|
|
62
|
+
className: cn(badgeVariants({ variant }), className),
|
|
63
|
+
...props
|
|
64
|
+
}
|
|
65
|
+
);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
// src/components/bare-icon-button/bare-icon-button.tsx
|
|
69
|
+
import { cva as cva2 } from "class-variance-authority";
|
|
70
|
+
import { Slot as Slot2 } from "radix-ui";
|
|
71
|
+
import { jsx as jsx2 } from "react/jsx-runtime";
|
|
72
|
+
var bareIconButtonVariants = cva2(
|
|
73
|
+
"inline-flex shrink-0 cursor-pointer items-center justify-center border border-transparent bg-transparent p-0 text-[var(--text-tertiary)] transition-[color,opacity,box-shadow] duration-150 outline-none select-none hover:border-transparent hover:bg-transparent hover:text-[var(--text-primary)] active:bg-transparent active:text-[var(--text-primary)] aria-expanded:bg-transparent aria-expanded:text-[var(--text-primary)] focus-visible:border-transparent focus-visible:bg-transparent focus-visible:text-[var(--text-primary)] focus-visible:ring-2 focus-visible:ring-[var(--border-focus)] disabled:pointer-events-none disabled:cursor-not-allowed disabled:bg-transparent disabled:text-[var(--text-disabled)] disabled:opacity-100 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
|
|
74
|
+
{
|
|
75
|
+
variants: {
|
|
76
|
+
size: {
|
|
77
|
+
md: "size-6 rounded-[4px] [&_svg:not([class*='size-'])]:size-4",
|
|
78
|
+
sm: "size-5 rounded-[3px] [&_svg:not([class*='size-'])]:size-3.5"
|
|
79
|
+
}
|
|
80
|
+
},
|
|
81
|
+
defaultVariants: {
|
|
82
|
+
size: "md"
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
);
|
|
86
|
+
function BareIconButton({
|
|
87
|
+
className,
|
|
88
|
+
size = "md",
|
|
89
|
+
asChild = false,
|
|
90
|
+
type = "button",
|
|
91
|
+
...props
|
|
92
|
+
}) {
|
|
93
|
+
const Comp = asChild ? Slot2.Root : "button";
|
|
94
|
+
return /* @__PURE__ */ jsx2(
|
|
95
|
+
Comp,
|
|
96
|
+
{
|
|
97
|
+
"data-slot": "bare-icon-button",
|
|
98
|
+
"data-size": size,
|
|
99
|
+
type,
|
|
100
|
+
className: cn(bareIconButtonVariants({ size, className })),
|
|
101
|
+
...props
|
|
102
|
+
}
|
|
103
|
+
);
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
// src/components/button/button.tsx
|
|
107
|
+
import { cva as cva3 } from "class-variance-authority";
|
|
108
|
+
import { Slot as Slot3 } from "radix-ui";
|
|
109
|
+
import { jsx as jsx3 } from "react/jsx-runtime";
|
|
110
|
+
var buttonVariants = cva3(
|
|
111
|
+
"group/button inline-flex shrink-0 cursor-pointer items-center justify-center rounded-md border border-transparent bg-clip-padding text-sm font-normal whitespace-nowrap transition-[background-color,border-color,color,box-shadow,transform] outline-none select-none focus-visible:border-ring focus-visible:ring-2 focus-visible:ring-ring/35 active:not-aria-[haspopup]:translate-y-px disabled:pointer-events-none disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-2 aria-invalid:ring-destructive/20 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
|
|
112
|
+
{
|
|
113
|
+
variants: {
|
|
114
|
+
variant: {
|
|
115
|
+
default: "bg-[var(--text-primary)] text-[var(--text-inverted)] shadow-none hover:bg-[var(--text-primary-hover)]",
|
|
116
|
+
outline: "border-border bg-card text-foreground hover:bg-muted/80 hover:text-foreground aria-expanded:bg-muted aria-expanded:text-foreground dark:border-input dark:bg-input/30 dark:hover:bg-input/50",
|
|
117
|
+
secondary: "bg-transparency-block text-[var(--text-primary)] hover:bg-transparency-hover aria-expanded:bg-transparency-hover aria-expanded:text-[var(--text-primary)]",
|
|
118
|
+
ghost: "bg-transparent text-[var(--text-primary)] hover:bg-transparency-hover aria-expanded:bg-transparency-hover aria-expanded:text-[var(--text-primary)]",
|
|
119
|
+
chrome: "border border-transparent bg-transparent text-[var(--text-tertiary)] shadow-none hover:border-transparent hover:bg-[var(--transparency-hover)] hover:text-[var(--text-primary)] active:bg-[var(--transparency-active)] active:text-[var(--text-primary)] aria-expanded:border-transparent aria-expanded:bg-[var(--transparency-block)] aria-expanded:text-[var(--text-primary)] disabled:pointer-events-auto disabled:cursor-not-allowed disabled:opacity-45",
|
|
120
|
+
destructive: "bg-[var(--state-danger)] text-[var(--white-stationary)] hover:bg-[var(--state-danger-hover)] focus-visible:border-[var(--state-danger)] focus-visible:ring-[color-mix(in_srgb,var(--state-danger)_25%,transparent)]",
|
|
121
|
+
link: "text-primary underline-offset-4 hover:underline"
|
|
122
|
+
},
|
|
123
|
+
size: {
|
|
124
|
+
default: "h-8 gap-[6px] px-2.5 has-data-[icon=inline-end]:pr-2 has-data-[icon=inline-start]:pl-2",
|
|
125
|
+
dialog: "h-8 gap-[6px] rounded-md px-3 text-sm font-normal leading-5 has-data-[icon=inline-end]:pr-2.5 has-data-[icon=inline-start]:pl-2.5",
|
|
126
|
+
xs: "h-6 gap-1 rounded-sm px-2 text-xs in-data-[slot=button-group]:rounded-md has-data-[icon=inline-end]:pr-1.5 has-data-[icon=inline-start]:pl-1.5 [&_svg:not([class*='size-'])]:size-3",
|
|
127
|
+
sm: "h-7 gap-1 rounded-sm px-2.5 text-[0.8rem] in-data-[slot=button-group]:rounded-md has-data-[icon=inline-end]:pr-1.5 has-data-[icon=inline-start]:pl-1.5 [&_svg:not([class*='size-'])]:size-3.5",
|
|
128
|
+
lg: "h-9 gap-2 px-3 has-data-[icon=inline-end]:pr-2.5 has-data-[icon=inline-start]:pl-2.5",
|
|
129
|
+
icon: "size-8",
|
|
130
|
+
"icon-xs": "size-6 rounded-sm in-data-[slot=button-group]:rounded-md [&_svg:not([class*='size-'])]:size-3",
|
|
131
|
+
"icon-sm": "size-7 rounded-sm in-data-[slot=button-group]:rounded-md",
|
|
132
|
+
"icon-lg": "size-9"
|
|
133
|
+
}
|
|
134
|
+
},
|
|
135
|
+
defaultVariants: {
|
|
136
|
+
variant: "default",
|
|
137
|
+
size: "default"
|
|
138
|
+
},
|
|
139
|
+
compoundVariants: [
|
|
140
|
+
{
|
|
141
|
+
variant: "chrome",
|
|
142
|
+
size: "icon-sm",
|
|
143
|
+
class: "rounded-[4px]"
|
|
144
|
+
}
|
|
145
|
+
]
|
|
146
|
+
}
|
|
147
|
+
);
|
|
148
|
+
function Button({
|
|
149
|
+
className,
|
|
150
|
+
variant = "default",
|
|
151
|
+
size = "default",
|
|
152
|
+
asChild = false,
|
|
153
|
+
...props
|
|
154
|
+
}) {
|
|
155
|
+
const Comp = asChild ? Slot3.Root : "button";
|
|
156
|
+
return /* @__PURE__ */ jsx3(
|
|
157
|
+
Comp,
|
|
158
|
+
{
|
|
159
|
+
"data-slot": "button",
|
|
160
|
+
"data-variant": variant,
|
|
161
|
+
"data-size": size,
|
|
162
|
+
className: cn(buttonVariants({ variant, size, className })),
|
|
163
|
+
...props
|
|
164
|
+
}
|
|
165
|
+
);
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
// src/components/card/card.tsx
|
|
169
|
+
import { jsx as jsx4 } from "react/jsx-runtime";
|
|
170
|
+
function Card({
|
|
171
|
+
className,
|
|
172
|
+
size = "default",
|
|
173
|
+
...props
|
|
174
|
+
}) {
|
|
175
|
+
return /* @__PURE__ */ jsx4(
|
|
176
|
+
"div",
|
|
177
|
+
{
|
|
178
|
+
"data-slot": "card",
|
|
179
|
+
"data-size": size,
|
|
180
|
+
className: cn(
|
|
181
|
+
"group/card flex flex-col gap-4 overflow-hidden rounded-lg border border-border/70 bg-card py-4 text-sm text-card-foreground shadow-none has-data-[slot=card-footer]:pb-0 has-[>img:first-child]:pt-0 data-[size=sm]:gap-3 data-[size=sm]:py-3 data-[size=sm]:has-data-[slot=card-footer]:pb-0 *:[img:first-child]:rounded-t-lg *:[img:last-child]:rounded-b-lg",
|
|
182
|
+
className
|
|
183
|
+
),
|
|
184
|
+
...props
|
|
185
|
+
}
|
|
186
|
+
);
|
|
187
|
+
}
|
|
188
|
+
function CardHeader({ className, ...props }) {
|
|
189
|
+
return /* @__PURE__ */ jsx4(
|
|
190
|
+
"div",
|
|
191
|
+
{
|
|
192
|
+
"data-slot": "card-header",
|
|
193
|
+
className: cn(
|
|
194
|
+
"group/card-header @container/card-header grid auto-rows-min items-start gap-1 rounded-t-lg px-4 group-data-[size=sm]/card:px-3 has-data-[slot=card-action]:grid-cols-[1fr_auto] has-data-[slot=card-description]:grid-rows-[auto_auto] [.border-b]:border-border/70 [.border-b]:pb-4 group-data-[size=sm]/card:[.border-b]:pb-3",
|
|
195
|
+
className
|
|
196
|
+
),
|
|
197
|
+
...props
|
|
198
|
+
}
|
|
199
|
+
);
|
|
200
|
+
}
|
|
201
|
+
function CardTitle({ className, ...props }) {
|
|
202
|
+
return /* @__PURE__ */ jsx4(
|
|
203
|
+
"div",
|
|
204
|
+
{
|
|
205
|
+
"data-slot": "card-title",
|
|
206
|
+
className: cn(
|
|
207
|
+
"text-base leading-snug font-medium group-data-[size=sm]/card:text-sm",
|
|
208
|
+
className
|
|
209
|
+
),
|
|
210
|
+
...props
|
|
211
|
+
}
|
|
212
|
+
);
|
|
213
|
+
}
|
|
214
|
+
function CardDescription({ className, ...props }) {
|
|
215
|
+
return /* @__PURE__ */ jsx4(
|
|
216
|
+
"div",
|
|
217
|
+
{
|
|
218
|
+
"data-slot": "card-description",
|
|
219
|
+
className: cn("text-sm leading-[1.3] text-muted-foreground", className),
|
|
220
|
+
...props
|
|
221
|
+
}
|
|
222
|
+
);
|
|
223
|
+
}
|
|
224
|
+
function CardAction({ className, ...props }) {
|
|
225
|
+
return /* @__PURE__ */ jsx4(
|
|
226
|
+
"div",
|
|
227
|
+
{
|
|
228
|
+
"data-slot": "card-action",
|
|
229
|
+
className: cn(
|
|
230
|
+
"col-start-2 row-span-2 row-start-1 self-start justify-self-end",
|
|
231
|
+
className
|
|
232
|
+
),
|
|
233
|
+
...props
|
|
234
|
+
}
|
|
235
|
+
);
|
|
236
|
+
}
|
|
237
|
+
function CardContent({ className, ...props }) {
|
|
238
|
+
return /* @__PURE__ */ jsx4(
|
|
239
|
+
"div",
|
|
240
|
+
{
|
|
241
|
+
"data-slot": "card-content",
|
|
242
|
+
className: cn("px-4 group-data-[size=sm]/card:px-3", className),
|
|
243
|
+
...props
|
|
244
|
+
}
|
|
245
|
+
);
|
|
246
|
+
}
|
|
247
|
+
function CardFooter({ className, ...props }) {
|
|
248
|
+
return /* @__PURE__ */ jsx4(
|
|
249
|
+
"div",
|
|
250
|
+
{
|
|
251
|
+
"data-slot": "card-footer",
|
|
252
|
+
className: cn(
|
|
253
|
+
"flex items-center rounded-b-lg border-t border-border/70 bg-muted/50 p-4 group-data-[size=sm]/card:p-3",
|
|
254
|
+
className
|
|
255
|
+
),
|
|
256
|
+
...props
|
|
257
|
+
}
|
|
258
|
+
);
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
// src/components/checkbox/checkbox.tsx
|
|
262
|
+
import { Checkbox as CheckboxPrimitive } from "radix-ui";
|
|
263
|
+
import { jsx as jsx5 } from "react/jsx-runtime";
|
|
264
|
+
function Checkbox({
|
|
265
|
+
className,
|
|
266
|
+
...props
|
|
267
|
+
}) {
|
|
268
|
+
return /* @__PURE__ */ jsx5(
|
|
269
|
+
CheckboxPrimitive.Root,
|
|
270
|
+
{
|
|
271
|
+
"data-slot": "checkbox",
|
|
272
|
+
className: cn(
|
|
273
|
+
"peer inline-flex size-4 shrink-0 items-center justify-center rounded-[4px] border border-[var(--border-1)] bg-[var(--transparency-block)] text-[var(--text-inverted)] transition-[background-color,border-color,color,box-shadow] outline-none focus-visible:border-[var(--border-focus)] focus-visible:ring-2 focus-visible:ring-[color-mix(in_srgb,var(--border-focus)_30%,transparent)] disabled:cursor-not-allowed disabled:border-[var(--border-1)] disabled:bg-[var(--transparency-block)] disabled:text-[var(--text-inverted)] disabled:opacity-100 data-disabled:border-[var(--border-1)] aria-invalid:border-[var(--state-danger)] aria-invalid:ring-2 aria-invalid:ring-[color-mix(in_srgb,var(--state-danger)_20%,transparent)] data-[state=checked]:border-[var(--text-primary)] data-[state=checked]:bg-[var(--text-primary)] data-[state=unchecked]:hover:border-[color-mix(in_srgb,var(--text-primary)_40%,transparent)] disabled:data-[state=checked]:border-[var(--border-1)] disabled:data-[state=checked]:bg-[var(--text-disabled)] data-disabled:data-[state=checked]:border-[var(--border-1)]",
|
|
274
|
+
className
|
|
275
|
+
),
|
|
276
|
+
...props,
|
|
277
|
+
children: /* @__PURE__ */ jsx5(
|
|
278
|
+
CheckboxPrimitive.Indicator,
|
|
279
|
+
{
|
|
280
|
+
"data-slot": "checkbox-indicator",
|
|
281
|
+
className: "grid place-content-center text-current transition-none [&>svg]:size-3",
|
|
282
|
+
children: /* @__PURE__ */ jsx5(CheckIcon, { size: 14 })
|
|
283
|
+
}
|
|
284
|
+
)
|
|
285
|
+
}
|
|
286
|
+
);
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
// src/components/dialog/dialog.tsx
|
|
290
|
+
import * as React from "react";
|
|
291
|
+
import { Dialog as DialogPrimitive } from "radix-ui";
|
|
292
|
+
import { Fragment, jsx as jsx6, jsxs } from "react/jsx-runtime";
|
|
293
|
+
var dialogCloseDurationMs = 150;
|
|
294
|
+
var DialogMotionContext = React.createContext({
|
|
295
|
+
open: false
|
|
296
|
+
});
|
|
297
|
+
function Dialog({
|
|
298
|
+
defaultOpen,
|
|
299
|
+
onOpenChange,
|
|
300
|
+
open,
|
|
301
|
+
...props
|
|
302
|
+
}) {
|
|
303
|
+
const [uncontrolledOpen, setUncontrolledOpen] = React.useState(
|
|
304
|
+
defaultOpen ?? false
|
|
305
|
+
);
|
|
306
|
+
const currentOpen = open ?? uncontrolledOpen;
|
|
307
|
+
const handleOpenChange = React.useCallback(
|
|
308
|
+
(nextOpen) => {
|
|
309
|
+
if (open === void 0) {
|
|
310
|
+
setUncontrolledOpen(nextOpen);
|
|
311
|
+
}
|
|
312
|
+
onOpenChange?.(nextOpen);
|
|
313
|
+
},
|
|
314
|
+
[onOpenChange, open]
|
|
315
|
+
);
|
|
316
|
+
return /* @__PURE__ */ jsx6(DialogMotionContext.Provider, { value: { open: currentOpen }, children: /* @__PURE__ */ jsx6(
|
|
317
|
+
DialogPrimitive.Root,
|
|
318
|
+
{
|
|
319
|
+
"data-slot": "dialog",
|
|
320
|
+
open: currentOpen,
|
|
321
|
+
onOpenChange: handleOpenChange,
|
|
322
|
+
...props
|
|
323
|
+
}
|
|
324
|
+
) });
|
|
325
|
+
}
|
|
326
|
+
function DialogTrigger({
|
|
327
|
+
...props
|
|
328
|
+
}) {
|
|
329
|
+
return /* @__PURE__ */ jsx6(DialogPrimitive.Trigger, { "data-slot": "dialog-trigger", ...props });
|
|
330
|
+
}
|
|
331
|
+
function DialogPortal({
|
|
332
|
+
...props
|
|
333
|
+
}) {
|
|
334
|
+
return /* @__PURE__ */ jsx6(DialogPrimitive.Portal, { "data-slot": "dialog-portal", ...props });
|
|
335
|
+
}
|
|
336
|
+
function DialogClose({
|
|
337
|
+
...props
|
|
338
|
+
}) {
|
|
339
|
+
return /* @__PURE__ */ jsx6(DialogPrimitive.Close, { "data-slot": "dialog-close", ...props });
|
|
340
|
+
}
|
|
341
|
+
function DialogOverlay({
|
|
342
|
+
className,
|
|
343
|
+
style,
|
|
344
|
+
...props
|
|
345
|
+
}) {
|
|
346
|
+
return /* @__PURE__ */ jsx6(
|
|
347
|
+
DialogPrimitive.Overlay,
|
|
348
|
+
{
|
|
349
|
+
"data-slot": "dialog-overlay",
|
|
350
|
+
className: cn(
|
|
351
|
+
"fixed inset-0 isolate bg-[var(--backdrop)] duration-150 supports-backdrop-filter:backdrop-blur-sm data-open:animate-in data-open:fade-in-0 data-closed:animate-out data-closed:fade-out-0",
|
|
352
|
+
className
|
|
353
|
+
),
|
|
354
|
+
style: { zIndex: "var(--z-dialog-overlay)", ...style },
|
|
355
|
+
...props
|
|
356
|
+
}
|
|
357
|
+
);
|
|
358
|
+
}
|
|
359
|
+
function DialogContent({
|
|
360
|
+
className,
|
|
361
|
+
children,
|
|
362
|
+
overlayClassName,
|
|
363
|
+
portaled = true,
|
|
364
|
+
showCloseButton = true,
|
|
365
|
+
style,
|
|
366
|
+
...props
|
|
367
|
+
}) {
|
|
368
|
+
const { open } = React.useContext(DialogMotionContext);
|
|
369
|
+
const [mounted, setMounted] = React.useState(open);
|
|
370
|
+
React.useEffect(() => {
|
|
371
|
+
if (open) {
|
|
372
|
+
setMounted(true);
|
|
373
|
+
return void 0;
|
|
374
|
+
}
|
|
375
|
+
const timeout = window.setTimeout(() => {
|
|
376
|
+
setMounted(false);
|
|
377
|
+
}, dialogCloseDurationMs);
|
|
378
|
+
return () => {
|
|
379
|
+
window.clearTimeout(timeout);
|
|
380
|
+
};
|
|
381
|
+
}, [open]);
|
|
382
|
+
if (!mounted) {
|
|
383
|
+
return null;
|
|
384
|
+
}
|
|
385
|
+
const content = /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
386
|
+
/* @__PURE__ */ jsx6(DialogOverlay, { className: overlayClassName, forceMount: true }),
|
|
387
|
+
/* @__PURE__ */ jsxs(
|
|
388
|
+
DialogPrimitive.Content,
|
|
389
|
+
{
|
|
390
|
+
"data-slot": "dialog-content",
|
|
391
|
+
forceMount: true,
|
|
392
|
+
className: cn(
|
|
393
|
+
portaled ? "fixed" : "absolute",
|
|
394
|
+
"pointer-events-none top-1/2 left-1/2 grid w-full max-w-[calc(100%-2rem)] -translate-x-1/2 -translate-y-1/2 origin-center gap-3 rounded-[16px] border border-border-1 bg-[var(--background-panel)] p-[18px] text-sm text-foreground shadow-panel outline-none ease-[cubic-bezier(0.22,1,0.36,1)] will-change-[transform,opacity] sm:max-w-[360px] data-[state=closed]:!pointer-events-none data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-[0.96] data-[state=closed]:duration-[150ms] data-[state=open]:pointer-events-auto data-[state=open]:animate-in data-[state=open]:fade-in-0 data-[state=open]:zoom-in-[0.96] data-[state=open]:duration-[250ms] motion-reduce:animate-none",
|
|
395
|
+
className
|
|
396
|
+
),
|
|
397
|
+
style: { zIndex: "var(--z-dialog)", ...style },
|
|
398
|
+
...props,
|
|
399
|
+
children: [
|
|
400
|
+
children,
|
|
401
|
+
showCloseButton && /* @__PURE__ */ jsx6(DialogPrimitive.Close, { "data-slot": "dialog-close", asChild: true, children: /* @__PURE__ */ jsxs(
|
|
402
|
+
Button,
|
|
403
|
+
{
|
|
404
|
+
variant: "ghost",
|
|
405
|
+
className: "absolute top-3 right-3",
|
|
406
|
+
size: "icon-sm",
|
|
407
|
+
children: [
|
|
408
|
+
/* @__PURE__ */ jsx6(CloseIcon, {}),
|
|
409
|
+
/* @__PURE__ */ jsx6("span", { className: "sr-only", children: "Close" })
|
|
410
|
+
]
|
|
411
|
+
}
|
|
412
|
+
) })
|
|
413
|
+
]
|
|
414
|
+
}
|
|
415
|
+
)
|
|
416
|
+
] });
|
|
417
|
+
if (!portaled) {
|
|
418
|
+
return content;
|
|
419
|
+
}
|
|
420
|
+
return /* @__PURE__ */ jsx6(DialogPortal, { forceMount: true, children: content });
|
|
421
|
+
}
|
|
422
|
+
function DialogHeader({ className, ...props }) {
|
|
423
|
+
return /* @__PURE__ */ jsx6(
|
|
424
|
+
"div",
|
|
425
|
+
{
|
|
426
|
+
"data-slot": "dialog-header",
|
|
427
|
+
className: cn("flex flex-col gap-2 pr-8", className),
|
|
428
|
+
...props
|
|
429
|
+
}
|
|
430
|
+
);
|
|
431
|
+
}
|
|
432
|
+
function DialogFooter({
|
|
433
|
+
className,
|
|
434
|
+
showCloseButton = false,
|
|
435
|
+
children,
|
|
436
|
+
...props
|
|
437
|
+
}) {
|
|
438
|
+
return /* @__PURE__ */ jsxs(
|
|
439
|
+
"div",
|
|
440
|
+
{
|
|
441
|
+
"data-slot": "dialog-footer",
|
|
442
|
+
className: cn(
|
|
443
|
+
"flex flex-col-reverse gap-2 pt-1 sm:flex-row sm:justify-end sm:gap-2.5",
|
|
444
|
+
className
|
|
445
|
+
),
|
|
446
|
+
...props,
|
|
447
|
+
children: [
|
|
448
|
+
children,
|
|
449
|
+
showCloseButton && /* @__PURE__ */ jsx6(DialogPrimitive.Close, { asChild: true, children: /* @__PURE__ */ jsx6(Button, { variant: "ghost", size: "dialog", children: "Close" }) })
|
|
450
|
+
]
|
|
451
|
+
}
|
|
452
|
+
);
|
|
453
|
+
}
|
|
454
|
+
function DialogTitle({
|
|
455
|
+
className,
|
|
456
|
+
...props
|
|
457
|
+
}) {
|
|
458
|
+
return /* @__PURE__ */ jsx6(
|
|
459
|
+
DialogPrimitive.Title,
|
|
460
|
+
{
|
|
461
|
+
"data-slot": "dialog-title",
|
|
462
|
+
className: cn(
|
|
463
|
+
"text-base leading-[1.35] font-semibold tracking-normal text-foreground",
|
|
464
|
+
className
|
|
465
|
+
),
|
|
466
|
+
...props
|
|
467
|
+
}
|
|
468
|
+
);
|
|
469
|
+
}
|
|
470
|
+
function DialogDescription({
|
|
471
|
+
className,
|
|
472
|
+
...props
|
|
473
|
+
}) {
|
|
474
|
+
return /* @__PURE__ */ jsx6(
|
|
475
|
+
DialogPrimitive.Description,
|
|
476
|
+
{
|
|
477
|
+
"data-slot": "dialog-description",
|
|
478
|
+
className: cn(
|
|
479
|
+
"text-sm font-[400] leading-[1.3] text-text-secondary *:[a]:underline *:[a]:underline-offset-3 *:[a]:hover:text-foreground",
|
|
480
|
+
className
|
|
481
|
+
),
|
|
482
|
+
...props
|
|
483
|
+
}
|
|
484
|
+
);
|
|
485
|
+
}
|
|
486
|
+
|
|
487
|
+
// src/components/confirmation-dialog/confirmation-dialog.tsx
|
|
488
|
+
import { jsx as jsx7, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
489
|
+
function confirmToneClassName(tone) {
|
|
490
|
+
if (tone === "destructive") {
|
|
491
|
+
return "shadow-none";
|
|
492
|
+
}
|
|
493
|
+
return void 0;
|
|
494
|
+
}
|
|
495
|
+
function ConfirmationDialog({
|
|
496
|
+
cancelLabel,
|
|
497
|
+
children,
|
|
498
|
+
className,
|
|
499
|
+
confirmBusy = false,
|
|
500
|
+
confirmDisabled = false,
|
|
501
|
+
confirmLabel,
|
|
502
|
+
description,
|
|
503
|
+
disableCloseWhileBusy = true,
|
|
504
|
+
footer,
|
|
505
|
+
hideConfirmButton = false,
|
|
506
|
+
onCancel,
|
|
507
|
+
onConfirm,
|
|
508
|
+
onOpenChange,
|
|
509
|
+
open,
|
|
510
|
+
overlayClassName,
|
|
511
|
+
portaled = true,
|
|
512
|
+
tone = "default",
|
|
513
|
+
title
|
|
514
|
+
}) {
|
|
515
|
+
const isCloseDisabled = disableCloseWhileBusy && confirmBusy;
|
|
516
|
+
return /* @__PURE__ */ jsx7(Dialog, { open, onOpenChange, children: /* @__PURE__ */ jsxs2(
|
|
517
|
+
DialogContent,
|
|
518
|
+
{
|
|
519
|
+
className: cn(
|
|
520
|
+
"max-w-[calc(100%-2rem)] text-left sm:max-w-[360px]",
|
|
521
|
+
className
|
|
522
|
+
),
|
|
523
|
+
overlayClassName: cn(overlayClassName),
|
|
524
|
+
portaled,
|
|
525
|
+
showCloseButton: false,
|
|
526
|
+
onEscapeKeyDown: (event) => {
|
|
527
|
+
if (isCloseDisabled) {
|
|
528
|
+
event.preventDefault();
|
|
529
|
+
}
|
|
530
|
+
},
|
|
531
|
+
onInteractOutside: (event) => {
|
|
532
|
+
if (isCloseDisabled) {
|
|
533
|
+
event.preventDefault();
|
|
534
|
+
}
|
|
535
|
+
},
|
|
536
|
+
children: [
|
|
537
|
+
/* @__PURE__ */ jsxs2(DialogHeader, { children: [
|
|
538
|
+
/* @__PURE__ */ jsx7(DialogTitle, { children: title }),
|
|
539
|
+
description ? /* @__PURE__ */ jsx7(DialogDescription, { children: description }) : null
|
|
540
|
+
] }),
|
|
541
|
+
children ? /* @__PURE__ */ jsx7("div", { className: "text-sm leading-[1.3] text-text-secondary", children }) : null,
|
|
542
|
+
footer ?? /* @__PURE__ */ jsxs2(DialogFooter, { children: [
|
|
543
|
+
/* @__PURE__ */ jsx7(
|
|
544
|
+
Button,
|
|
545
|
+
{
|
|
546
|
+
disabled: confirmBusy,
|
|
547
|
+
size: "dialog",
|
|
548
|
+
type: "button",
|
|
549
|
+
variant: "ghost",
|
|
550
|
+
onClick: () => {
|
|
551
|
+
onCancel?.();
|
|
552
|
+
onOpenChange(false);
|
|
553
|
+
},
|
|
554
|
+
children: cancelLabel
|
|
555
|
+
}
|
|
556
|
+
),
|
|
557
|
+
hideConfirmButton ? null : /* @__PURE__ */ jsx7(
|
|
558
|
+
Button,
|
|
559
|
+
{
|
|
560
|
+
disabled: confirmBusy || confirmDisabled,
|
|
561
|
+
size: "dialog",
|
|
562
|
+
type: "button",
|
|
563
|
+
variant: tone === "default" ? "default" : "destructive",
|
|
564
|
+
className: cn("shadow-none", confirmToneClassName(tone)),
|
|
565
|
+
onClick: () => {
|
|
566
|
+
onConfirm?.();
|
|
567
|
+
},
|
|
568
|
+
children: confirmLabel
|
|
569
|
+
}
|
|
570
|
+
)
|
|
571
|
+
] })
|
|
572
|
+
]
|
|
573
|
+
}
|
|
574
|
+
) });
|
|
575
|
+
}
|
|
576
|
+
|
|
577
|
+
// src/components/date-picker/date-picker.tsx
|
|
578
|
+
import * as React2 from "react";
|
|
579
|
+
import { createPortal } from "react-dom";
|
|
580
|
+
import { Fragment as Fragment2, jsx as jsx8, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
581
|
+
var defaultLabels = {
|
|
582
|
+
placeholder: "Year / Month / Day",
|
|
583
|
+
previousMonth: "Previous month",
|
|
584
|
+
nextMonth: "Next month",
|
|
585
|
+
clear: "Clear",
|
|
586
|
+
today: "Today",
|
|
587
|
+
weekdayLabels: ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"]
|
|
588
|
+
};
|
|
589
|
+
var DATE_PICKER_POPOVER_WIDTH_PX = 264;
|
|
590
|
+
var DATE_PICKER_POPOVER_HEIGHT_PX = 336;
|
|
591
|
+
var DATE_PICKER_POPOVER_GAP_PX = 6;
|
|
592
|
+
var DATE_PICKER_VIEWPORT_MARGIN_PX = 8;
|
|
593
|
+
function parseDateValue(value) {
|
|
594
|
+
if (!value) {
|
|
595
|
+
return null;
|
|
596
|
+
}
|
|
597
|
+
const [year, month, day] = value.split("-").map(Number);
|
|
598
|
+
if (!year || !month || !day) {
|
|
599
|
+
return null;
|
|
600
|
+
}
|
|
601
|
+
return new Date(year, month - 1, day);
|
|
602
|
+
}
|
|
603
|
+
function formatDateValue(date) {
|
|
604
|
+
const year = date.getFullYear();
|
|
605
|
+
const month = `${date.getMonth() + 1}`.padStart(2, "0");
|
|
606
|
+
const day = `${date.getDate()}`.padStart(2, "0");
|
|
607
|
+
return `${year}-${month}-${day}`;
|
|
608
|
+
}
|
|
609
|
+
function defaultDisplayValueFormatter(date) {
|
|
610
|
+
return new Intl.DateTimeFormat(void 0, {
|
|
611
|
+
year: "numeric",
|
|
612
|
+
month: "2-digit",
|
|
613
|
+
day: "2-digit"
|
|
614
|
+
}).format(date);
|
|
615
|
+
}
|
|
616
|
+
function defaultMonthLabelFormatter(date) {
|
|
617
|
+
return new Intl.DateTimeFormat(void 0, {
|
|
618
|
+
year: "numeric",
|
|
619
|
+
month: "long"
|
|
620
|
+
}).format(date);
|
|
621
|
+
}
|
|
622
|
+
function isSameDate(left, right) {
|
|
623
|
+
return Boolean(
|
|
624
|
+
left && right && left.getFullYear() === right.getFullYear() && left.getMonth() === right.getMonth() && left.getDate() === right.getDate()
|
|
625
|
+
);
|
|
626
|
+
}
|
|
627
|
+
function buildMonthGrid(monthDate) {
|
|
628
|
+
const firstOfMonth = new Date(
|
|
629
|
+
monthDate.getFullYear(),
|
|
630
|
+
monthDate.getMonth(),
|
|
631
|
+
1
|
|
632
|
+
);
|
|
633
|
+
const gridStart = new Date(firstOfMonth);
|
|
634
|
+
gridStart.setDate(firstOfMonth.getDate() - firstOfMonth.getDay());
|
|
635
|
+
return Array.from({ length: 42 }, (_, index) => {
|
|
636
|
+
const date = new Date(gridStart);
|
|
637
|
+
date.setDate(gridStart.getDate() + index);
|
|
638
|
+
return date;
|
|
639
|
+
});
|
|
640
|
+
}
|
|
641
|
+
function resolvePopoverPosition(rect) {
|
|
642
|
+
const width = Math.max(rect.width, DATE_PICKER_POPOVER_WIDTH_PX);
|
|
643
|
+
const maxLeft = window.innerWidth - width - DATE_PICKER_VIEWPORT_MARGIN_PX;
|
|
644
|
+
const left = Math.max(
|
|
645
|
+
DATE_PICKER_VIEWPORT_MARGIN_PX,
|
|
646
|
+
Math.min(rect.left, Math.max(DATE_PICKER_VIEWPORT_MARGIN_PX, maxLeft))
|
|
647
|
+
);
|
|
648
|
+
const belowTop = rect.bottom + DATE_PICKER_POPOVER_GAP_PX;
|
|
649
|
+
const aboveTop = rect.top - DATE_PICKER_POPOVER_GAP_PX - DATE_PICKER_POPOVER_HEIGHT_PX;
|
|
650
|
+
const canOpenBelow = belowTop + DATE_PICKER_POPOVER_HEIGHT_PX <= window.innerHeight - DATE_PICKER_VIEWPORT_MARGIN_PX;
|
|
651
|
+
const top = canOpenBelow ? belowTop : Math.max(DATE_PICKER_VIEWPORT_MARGIN_PX, aboveTop);
|
|
652
|
+
return { top, left, width };
|
|
653
|
+
}
|
|
654
|
+
function subscribeScrollableAncestors(trigger, onScrollLike) {
|
|
655
|
+
const cleanups = [];
|
|
656
|
+
let element = trigger.parentElement;
|
|
657
|
+
while (element && element !== document.documentElement) {
|
|
658
|
+
const { overflowX, overflowY } = window.getComputedStyle(element);
|
|
659
|
+
if (overflowY === "auto" || overflowY === "scroll" || overflowY === "overlay" || overflowX === "auto" || overflowX === "scroll" || overflowX === "overlay") {
|
|
660
|
+
element.addEventListener("scroll", onScrollLike, { passive: true });
|
|
661
|
+
const current = element;
|
|
662
|
+
cleanups.push(() => current.removeEventListener("scroll", onScrollLike));
|
|
663
|
+
}
|
|
664
|
+
element = element.parentElement;
|
|
665
|
+
}
|
|
666
|
+
return () => cleanups.forEach((dispose) => dispose());
|
|
667
|
+
}
|
|
668
|
+
var DatePicker = React2.forwardRef(
|
|
669
|
+
({
|
|
670
|
+
className,
|
|
671
|
+
value,
|
|
672
|
+
onValueChange,
|
|
673
|
+
onClick,
|
|
674
|
+
disabled,
|
|
675
|
+
labels,
|
|
676
|
+
formatDisplayValue = defaultDisplayValueFormatter,
|
|
677
|
+
formatMonthLabel = defaultMonthLabelFormatter,
|
|
678
|
+
...props
|
|
679
|
+
}, ref) => {
|
|
680
|
+
const resolvedLabels = {
|
|
681
|
+
...defaultLabels,
|
|
682
|
+
...labels,
|
|
683
|
+
weekdayLabels: labels?.weekdayLabels ?? defaultLabels.weekdayLabels
|
|
684
|
+
};
|
|
685
|
+
const triggerRef = React2.useRef(null);
|
|
686
|
+
const popoverRef = React2.useRef(null);
|
|
687
|
+
const selectedDate = React2.useMemo(() => parseDateValue(value), [value]);
|
|
688
|
+
const [isOpen, setIsOpen] = React2.useState(false);
|
|
689
|
+
const [visibleMonth, setVisibleMonth] = React2.useState(
|
|
690
|
+
() => selectedDate ?? /* @__PURE__ */ new Date()
|
|
691
|
+
);
|
|
692
|
+
const [popoverPosition, setPopoverPosition] = React2.useState(null);
|
|
693
|
+
React2.useEffect(() => {
|
|
694
|
+
if (selectedDate) {
|
|
695
|
+
setVisibleMonth(selectedDate);
|
|
696
|
+
}
|
|
697
|
+
}, [selectedDate]);
|
|
698
|
+
const openPopover = React2.useCallback(() => {
|
|
699
|
+
const trigger = triggerRef.current;
|
|
700
|
+
if (!trigger) {
|
|
701
|
+
return;
|
|
702
|
+
}
|
|
703
|
+
setPopoverPosition(
|
|
704
|
+
resolvePopoverPosition(trigger.getBoundingClientRect())
|
|
705
|
+
);
|
|
706
|
+
setIsOpen(true);
|
|
707
|
+
}, []);
|
|
708
|
+
React2.useLayoutEffect(() => {
|
|
709
|
+
if (!isOpen) {
|
|
710
|
+
return;
|
|
711
|
+
}
|
|
712
|
+
const sync = () => {
|
|
713
|
+
const element = triggerRef.current;
|
|
714
|
+
if (!element) {
|
|
715
|
+
return;
|
|
716
|
+
}
|
|
717
|
+
setPopoverPosition(
|
|
718
|
+
resolvePopoverPosition(element.getBoundingClientRect())
|
|
719
|
+
);
|
|
720
|
+
};
|
|
721
|
+
sync();
|
|
722
|
+
const rafId = window.requestAnimationFrame(sync);
|
|
723
|
+
return () => window.cancelAnimationFrame(rafId);
|
|
724
|
+
}, [isOpen]);
|
|
725
|
+
React2.useEffect(() => {
|
|
726
|
+
if (!isOpen) {
|
|
727
|
+
return void 0;
|
|
728
|
+
}
|
|
729
|
+
const ac = new AbortController();
|
|
730
|
+
const { signal } = ac;
|
|
731
|
+
const handlePointerDown = (event) => {
|
|
732
|
+
const target = event.target;
|
|
733
|
+
if (target && (triggerRef.current?.contains(target) || popoverRef.current?.contains(target))) {
|
|
734
|
+
return;
|
|
735
|
+
}
|
|
736
|
+
setIsOpen(false);
|
|
737
|
+
};
|
|
738
|
+
const handleKeyDown = (event) => {
|
|
739
|
+
if (event.key === "Escape") {
|
|
740
|
+
setIsOpen(false);
|
|
741
|
+
triggerRef.current?.focus();
|
|
742
|
+
}
|
|
743
|
+
};
|
|
744
|
+
const updatePosition = () => {
|
|
745
|
+
const element = triggerRef.current;
|
|
746
|
+
if (!element) {
|
|
747
|
+
return;
|
|
748
|
+
}
|
|
749
|
+
setPopoverPosition(
|
|
750
|
+
resolvePopoverPosition(element.getBoundingClientRect())
|
|
751
|
+
);
|
|
752
|
+
};
|
|
753
|
+
document.addEventListener("pointerdown", handlePointerDown, { signal });
|
|
754
|
+
document.addEventListener("keydown", handleKeyDown, { signal });
|
|
755
|
+
window.addEventListener("resize", updatePosition, { signal });
|
|
756
|
+
document.addEventListener(
|
|
757
|
+
"wheel",
|
|
758
|
+
() => window.requestAnimationFrame(updatePosition),
|
|
759
|
+
{
|
|
760
|
+
capture: true,
|
|
761
|
+
passive: true,
|
|
762
|
+
signal
|
|
763
|
+
}
|
|
764
|
+
);
|
|
765
|
+
const unsubAncestors = triggerRef.current ? subscribeScrollableAncestors(triggerRef.current, updatePosition) : () => {
|
|
766
|
+
};
|
|
767
|
+
return () => {
|
|
768
|
+
ac.abort();
|
|
769
|
+
unsubAncestors();
|
|
770
|
+
};
|
|
771
|
+
}, [isOpen]);
|
|
772
|
+
const today = React2.useMemo(() => /* @__PURE__ */ new Date(), []);
|
|
773
|
+
const monthGrid = React2.useMemo(
|
|
774
|
+
() => buildMonthGrid(visibleMonth),
|
|
775
|
+
[visibleMonth]
|
|
776
|
+
);
|
|
777
|
+
const displayValue = selectedDate ? formatDisplayValue(selectedDate) : resolvedLabels.placeholder;
|
|
778
|
+
const selectDate = (date) => {
|
|
779
|
+
onValueChange?.(formatDateValue(date));
|
|
780
|
+
setIsOpen(false);
|
|
781
|
+
triggerRef.current?.focus();
|
|
782
|
+
};
|
|
783
|
+
return /* @__PURE__ */ jsxs3(Fragment2, { children: [
|
|
784
|
+
/* @__PURE__ */ jsx8(
|
|
785
|
+
"button",
|
|
786
|
+
{
|
|
787
|
+
ref: (node) => {
|
|
788
|
+
triggerRef.current = node;
|
|
789
|
+
if (typeof ref === "function") {
|
|
790
|
+
ref(node);
|
|
791
|
+
} else if (ref) {
|
|
792
|
+
ref.current = node;
|
|
793
|
+
}
|
|
794
|
+
},
|
|
795
|
+
"data-slot": "date-picker",
|
|
796
|
+
disabled,
|
|
797
|
+
type: "button",
|
|
798
|
+
className: cn(
|
|
799
|
+
"inline-flex h-8 min-h-8 w-full items-center justify-start rounded-md border border-transparent bg-[var(--workbench-field-bg)] px-3 text-left text-sm text-foreground transition-[background-color,border-color,box-shadow,color] outline-none hover:bg-muted/60 focus-visible:border-border focus-visible:ring-2 focus-visible:ring-ring/30 disabled:cursor-not-allowed disabled:bg-muted disabled:text-muted-foreground disabled:opacity-100",
|
|
800
|
+
!selectedDate && "text-muted-foreground",
|
|
801
|
+
className
|
|
802
|
+
),
|
|
803
|
+
onClick: (event) => {
|
|
804
|
+
onClick?.(event);
|
|
805
|
+
if (disabled) {
|
|
806
|
+
return;
|
|
807
|
+
}
|
|
808
|
+
if (isOpen) {
|
|
809
|
+
setIsOpen(false);
|
|
810
|
+
} else {
|
|
811
|
+
openPopover();
|
|
812
|
+
}
|
|
813
|
+
},
|
|
814
|
+
...props,
|
|
815
|
+
children: /* @__PURE__ */ jsx8("span", { className: "min-w-0 truncate", children: displayValue })
|
|
816
|
+
}
|
|
817
|
+
),
|
|
818
|
+
isOpen && popoverPosition ? createPortal(
|
|
819
|
+
/* @__PURE__ */ jsxs3(
|
|
820
|
+
"div",
|
|
821
|
+
{
|
|
822
|
+
ref: popoverRef,
|
|
823
|
+
"data-slot": "date-picker-content",
|
|
824
|
+
className: "fixed z-50 flex min-w-[264px] max-w-[min(100vw-16px,320px)] flex-col overflow-hidden rounded-xl border border-border/70 bg-popover p-3 text-popover-foreground shadow-soft",
|
|
825
|
+
style: {
|
|
826
|
+
top: popoverPosition.top,
|
|
827
|
+
left: popoverPosition.left,
|
|
828
|
+
width: popoverPosition.width,
|
|
829
|
+
zIndex: "var(--z-popover)"
|
|
830
|
+
},
|
|
831
|
+
children: [
|
|
832
|
+
/* @__PURE__ */ jsxs3("div", { className: "mb-3 flex items-center justify-between gap-2", children: [
|
|
833
|
+
/* @__PURE__ */ jsx8("div", { className: "text-sm font-semibold text-foreground", children: formatMonthLabel(visibleMonth) }),
|
|
834
|
+
/* @__PURE__ */ jsxs3("div", { className: "flex items-center gap-1", children: [
|
|
835
|
+
/* @__PURE__ */ jsx8(
|
|
836
|
+
"button",
|
|
837
|
+
{
|
|
838
|
+
"aria-label": resolvedLabels.previousMonth,
|
|
839
|
+
className: "inline-flex h-7 w-7 items-center justify-center rounded-sm text-muted-foreground transition-colors hover:bg-muted hover:text-foreground",
|
|
840
|
+
type: "button",
|
|
841
|
+
onClick: () => setVisibleMonth(
|
|
842
|
+
(current) => new Date(
|
|
843
|
+
current.getFullYear(),
|
|
844
|
+
current.getMonth() - 1,
|
|
845
|
+
1
|
|
846
|
+
)
|
|
847
|
+
),
|
|
848
|
+
children: /* @__PURE__ */ jsx8(ArrowLeftIcon, { size: 16 })
|
|
849
|
+
}
|
|
850
|
+
),
|
|
851
|
+
/* @__PURE__ */ jsx8(
|
|
852
|
+
"button",
|
|
853
|
+
{
|
|
854
|
+
"aria-label": resolvedLabels.nextMonth,
|
|
855
|
+
className: "inline-flex h-7 w-7 items-center justify-center rounded-sm text-muted-foreground transition-colors hover:bg-muted hover:text-foreground",
|
|
856
|
+
type: "button",
|
|
857
|
+
onClick: () => setVisibleMonth(
|
|
858
|
+
(current) => new Date(
|
|
859
|
+
current.getFullYear(),
|
|
860
|
+
current.getMonth() + 1,
|
|
861
|
+
1
|
|
862
|
+
)
|
|
863
|
+
),
|
|
864
|
+
children: /* @__PURE__ */ jsx8(ArrowRightIcon, { size: 16 })
|
|
865
|
+
}
|
|
866
|
+
)
|
|
867
|
+
] })
|
|
868
|
+
] }),
|
|
869
|
+
/* @__PURE__ */ jsx8("div", { className: "grid grid-cols-7 gap-1 text-center text-xs font-semibold text-muted-foreground", children: resolvedLabels.weekdayLabels.map((day) => /* @__PURE__ */ jsx8("div", { className: "py-1", children: day }, day)) }),
|
|
870
|
+
/* @__PURE__ */ jsx8(
|
|
871
|
+
"div",
|
|
872
|
+
{
|
|
873
|
+
className: "mt-1 grid grid-cols-7 justify-items-center gap-1",
|
|
874
|
+
role: "grid",
|
|
875
|
+
children: monthGrid.map((date) => {
|
|
876
|
+
const isSelected = isSameDate(date, selectedDate);
|
|
877
|
+
const isToday = isSameDate(date, today);
|
|
878
|
+
const inCurrentMonth = date.getMonth() === visibleMonth.getMonth();
|
|
879
|
+
return /* @__PURE__ */ jsx8(
|
|
880
|
+
"button",
|
|
881
|
+
{
|
|
882
|
+
"aria-pressed": isSelected,
|
|
883
|
+
className: cn(
|
|
884
|
+
"inline-flex h-8 w-8 items-center justify-center rounded-sm text-sm transition-[background-color,color,box-shadow] hover:bg-muted focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring/30",
|
|
885
|
+
inCurrentMonth ? "text-foreground" : "text-muted-foreground",
|
|
886
|
+
isToday && "bg-primary/10 text-primary shadow-[inset_0_0_0_1px_color-mix(in_srgb,var(--color-primary)_20%,transparent)]",
|
|
887
|
+
isSelected && "bg-primary text-primary-foreground hover:bg-primary"
|
|
888
|
+
),
|
|
889
|
+
role: "gridcell",
|
|
890
|
+
type: "button",
|
|
891
|
+
onClick: () => selectDate(date),
|
|
892
|
+
children: date.getDate()
|
|
893
|
+
},
|
|
894
|
+
formatDateValue(date)
|
|
895
|
+
);
|
|
896
|
+
})
|
|
897
|
+
}
|
|
898
|
+
),
|
|
899
|
+
/* @__PURE__ */ jsxs3("div", { className: "mt-3 flex items-center justify-between gap-2 border-t border-border/70 pt-3", children: [
|
|
900
|
+
/* @__PURE__ */ jsx8(
|
|
901
|
+
"button",
|
|
902
|
+
{
|
|
903
|
+
className: "inline-flex min-h-8 items-center justify-center rounded-sm px-3 text-sm font-medium text-muted-foreground transition-colors hover:bg-muted hover:text-foreground",
|
|
904
|
+
type: "button",
|
|
905
|
+
onClick: () => {
|
|
906
|
+
onValueChange?.("");
|
|
907
|
+
setIsOpen(false);
|
|
908
|
+
triggerRef.current?.focus();
|
|
909
|
+
},
|
|
910
|
+
children: resolvedLabels.clear
|
|
911
|
+
}
|
|
912
|
+
),
|
|
913
|
+
/* @__PURE__ */ jsx8(
|
|
914
|
+
"button",
|
|
915
|
+
{
|
|
916
|
+
className: "inline-flex min-h-8 items-center justify-center rounded-sm bg-primary px-3 text-sm font-medium text-primary-foreground transition-opacity hover:opacity-90",
|
|
917
|
+
type: "button",
|
|
918
|
+
onClick: () => selectDate(today),
|
|
919
|
+
children: resolvedLabels.today
|
|
920
|
+
}
|
|
921
|
+
)
|
|
922
|
+
] })
|
|
923
|
+
]
|
|
924
|
+
}
|
|
925
|
+
),
|
|
926
|
+
document.body
|
|
927
|
+
) : null
|
|
928
|
+
] });
|
|
929
|
+
}
|
|
930
|
+
);
|
|
931
|
+
DatePicker.displayName = "DatePicker";
|
|
932
|
+
|
|
933
|
+
// src/components/drawer/drawer.tsx
|
|
934
|
+
import { Drawer as DrawerPrimitive } from "vaul";
|
|
935
|
+
import { jsx as jsx9, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
936
|
+
function Drawer({
|
|
937
|
+
...props
|
|
938
|
+
}) {
|
|
939
|
+
return /* @__PURE__ */ jsx9(DrawerPrimitive.Root, { "data-slot": "drawer", ...props });
|
|
940
|
+
}
|
|
941
|
+
function DrawerTrigger({
|
|
942
|
+
...props
|
|
943
|
+
}) {
|
|
944
|
+
return /* @__PURE__ */ jsx9(DrawerPrimitive.Trigger, { "data-slot": "drawer-trigger", ...props });
|
|
945
|
+
}
|
|
946
|
+
function DrawerPortal({
|
|
947
|
+
...props
|
|
948
|
+
}) {
|
|
949
|
+
return /* @__PURE__ */ jsx9(DrawerPrimitive.Portal, { "data-slot": "drawer-portal", ...props });
|
|
950
|
+
}
|
|
951
|
+
function DrawerClose({
|
|
952
|
+
...props
|
|
953
|
+
}) {
|
|
954
|
+
return /* @__PURE__ */ jsx9(DrawerPrimitive.Close, { "data-slot": "drawer-close", ...props });
|
|
955
|
+
}
|
|
956
|
+
function DrawerOverlay({
|
|
957
|
+
className,
|
|
958
|
+
style,
|
|
959
|
+
...props
|
|
960
|
+
}) {
|
|
961
|
+
return /* @__PURE__ */ jsx9(
|
|
962
|
+
DrawerPrimitive.Overlay,
|
|
963
|
+
{
|
|
964
|
+
"data-slot": "drawer-overlay",
|
|
965
|
+
className: cn(
|
|
966
|
+
"fixed inset-0 isolate bg-[var(--backdrop)] duration-150 supports-backdrop-filter:backdrop-blur-sm data-closed:animate-out data-closed:fade-out-0 data-open:animate-in data-open:fade-in-0",
|
|
967
|
+
className
|
|
968
|
+
),
|
|
969
|
+
style: { zIndex: "var(--z-dialog-overlay)", ...style },
|
|
970
|
+
...props
|
|
971
|
+
}
|
|
972
|
+
);
|
|
973
|
+
}
|
|
974
|
+
function DrawerContent({
|
|
975
|
+
className,
|
|
976
|
+
children,
|
|
977
|
+
portalContainer,
|
|
978
|
+
showOverlay = true,
|
|
979
|
+
style,
|
|
980
|
+
...props
|
|
981
|
+
}) {
|
|
982
|
+
return /* @__PURE__ */ jsxs4(DrawerPortal, { "data-slot": "drawer-portal", container: portalContainer, children: [
|
|
983
|
+
showOverlay ? /* @__PURE__ */ jsx9(DrawerOverlay, {}) : null,
|
|
984
|
+
/* @__PURE__ */ jsxs4(
|
|
985
|
+
DrawerPrimitive.Content,
|
|
986
|
+
{
|
|
987
|
+
"data-slot": "drawer-content",
|
|
988
|
+
className: cn(
|
|
989
|
+
"group/drawer-content fixed flex h-auto flex-col border-[var(--border-1)] bg-background-fronted text-sm text-foreground shadow-panel outline-none",
|
|
990
|
+
"data-[vaul-drawer-direction=bottom]:inset-x-0 data-[vaul-drawer-direction=bottom]:bottom-0 data-[vaul-drawer-direction=bottom]:mt-24 data-[vaul-drawer-direction=bottom]:max-h-[80vh] data-[vaul-drawer-direction=bottom]:rounded-t-xl data-[vaul-drawer-direction=bottom]:border-t",
|
|
991
|
+
"data-[vaul-drawer-direction=left]:inset-y-0 data-[vaul-drawer-direction=left]:left-0 data-[vaul-drawer-direction=left]:w-3/4 data-[vaul-drawer-direction=left]:rounded-r-xl data-[vaul-drawer-direction=left]:border-r data-[vaul-drawer-direction=left]:sm:max-w-sm",
|
|
992
|
+
"data-[vaul-drawer-direction=right]:inset-y-0 data-[vaul-drawer-direction=right]:right-0 data-[vaul-drawer-direction=right]:w-3/4 data-[vaul-drawer-direction=right]:rounded-l-xl data-[vaul-drawer-direction=right]:border-l data-[vaul-drawer-direction=right]:sm:max-w-sm",
|
|
993
|
+
"data-[vaul-drawer-direction=top]:inset-x-0 data-[vaul-drawer-direction=top]:top-0 data-[vaul-drawer-direction=top]:mb-24 data-[vaul-drawer-direction=top]:max-h-[80vh] data-[vaul-drawer-direction=top]:rounded-b-xl data-[vaul-drawer-direction=top]:border-b",
|
|
994
|
+
className
|
|
995
|
+
),
|
|
996
|
+
style: { zIndex: "var(--z-dialog)", ...style },
|
|
997
|
+
...props,
|
|
998
|
+
children: [
|
|
999
|
+
/* @__PURE__ */ jsx9("div", { className: "mx-auto mt-4 hidden h-1 w-[100px] shrink-0 rounded-full bg-muted group-data-[vaul-drawer-direction=bottom]/drawer-content:block" }),
|
|
1000
|
+
children
|
|
1001
|
+
]
|
|
1002
|
+
}
|
|
1003
|
+
)
|
|
1004
|
+
] });
|
|
1005
|
+
}
|
|
1006
|
+
function DrawerHeader({ className, ...props }) {
|
|
1007
|
+
return /* @__PURE__ */ jsx9(
|
|
1008
|
+
"div",
|
|
1009
|
+
{
|
|
1010
|
+
"data-slot": "drawer-header",
|
|
1011
|
+
className: cn(
|
|
1012
|
+
"flex flex-col gap-0.5 p-4 group-data-[vaul-drawer-direction=bottom]/drawer-content:text-center group-data-[vaul-drawer-direction=top]/drawer-content:text-center md:gap-0.5 md:text-left",
|
|
1013
|
+
className
|
|
1014
|
+
),
|
|
1015
|
+
...props
|
|
1016
|
+
}
|
|
1017
|
+
);
|
|
1018
|
+
}
|
|
1019
|
+
function DrawerFooter({ className, ...props }) {
|
|
1020
|
+
return /* @__PURE__ */ jsx9(
|
|
1021
|
+
"div",
|
|
1022
|
+
{
|
|
1023
|
+
"data-slot": "drawer-footer",
|
|
1024
|
+
className: cn("mt-auto flex flex-col gap-2 p-4", className),
|
|
1025
|
+
...props
|
|
1026
|
+
}
|
|
1027
|
+
);
|
|
1028
|
+
}
|
|
1029
|
+
function DrawerTitle({
|
|
1030
|
+
className,
|
|
1031
|
+
...props
|
|
1032
|
+
}) {
|
|
1033
|
+
return /* @__PURE__ */ jsx9(
|
|
1034
|
+
DrawerPrimitive.Title,
|
|
1035
|
+
{
|
|
1036
|
+
"data-slot": "drawer-title",
|
|
1037
|
+
className: cn(
|
|
1038
|
+
"text-base font-medium leading-[1.35] text-foreground",
|
|
1039
|
+
className
|
|
1040
|
+
),
|
|
1041
|
+
...props
|
|
1042
|
+
}
|
|
1043
|
+
);
|
|
1044
|
+
}
|
|
1045
|
+
function DrawerDescription({
|
|
1046
|
+
className,
|
|
1047
|
+
...props
|
|
1048
|
+
}) {
|
|
1049
|
+
return /* @__PURE__ */ jsx9(
|
|
1050
|
+
DrawerPrimitive.Description,
|
|
1051
|
+
{
|
|
1052
|
+
"data-slot": "drawer-description",
|
|
1053
|
+
className: cn("text-sm text-muted-foreground", className),
|
|
1054
|
+
...props
|
|
1055
|
+
}
|
|
1056
|
+
);
|
|
1057
|
+
}
|
|
1058
|
+
|
|
1059
|
+
// src/components/dropdown-menu/dropdown-menu.tsx
|
|
1060
|
+
import { DropdownMenu as DropdownMenuPrimitive } from "radix-ui";
|
|
1061
|
+
|
|
1062
|
+
// src/components/menu-surface/menu-surface.tsx
|
|
1063
|
+
import * as React3 from "react";
|
|
1064
|
+
import { Slot as Slot4 } from "radix-ui";
|
|
1065
|
+
import { jsx as jsx10 } from "react/jsx-runtime";
|
|
1066
|
+
var menuSurfaceClassName = "t-dropdown flex flex-col gap-0.5 rounded-[8px] border border-[var(--border-1)] bg-[var(--background-fronted)] p-1 text-sm text-[var(--text-primary)] shadow-panel outline-none";
|
|
1067
|
+
var menuItemClassName = "relative flex cursor-pointer items-center gap-1.5 rounded-sm px-2 py-1 text-sm text-[var(--text-primary)] outline-hidden transition-colors duration-200 select-none hover:bg-[var(--transparency-hover)] hover:text-[var(--text-primary)] focus:bg-[var(--transparency-hover)] focus:text-[var(--text-primary)] data-[highlighted]:bg-[var(--transparency-hover)] data-[highlighted]:text-[var(--text-primary)] data-disabled:pointer-events-none data-disabled:text-[var(--text-disabled)] [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4 *:[span]:last:flex *:[span]:last:items-center *:[span]:last:gap-2";
|
|
1068
|
+
var menuItemWithIndicatorClassName = `${menuItemClassName} pr-8`;
|
|
1069
|
+
var menuItemIndicatorClassName = "pointer-events-none absolute right-2 flex size-4 items-center justify-center text-[var(--accent)]";
|
|
1070
|
+
var MenuSurface = React3.forwardRef(
|
|
1071
|
+
({
|
|
1072
|
+
asChild = false,
|
|
1073
|
+
className,
|
|
1074
|
+
"data-state": dataState,
|
|
1075
|
+
state = "open",
|
|
1076
|
+
...props
|
|
1077
|
+
}, ref) => {
|
|
1078
|
+
const Comp = asChild ? Slot4.Root : "div";
|
|
1079
|
+
return /* @__PURE__ */ jsx10(
|
|
1080
|
+
Comp,
|
|
1081
|
+
{
|
|
1082
|
+
...props,
|
|
1083
|
+
ref,
|
|
1084
|
+
className: cn(menuSurfaceClassName, className),
|
|
1085
|
+
"data-state": dataState ?? state
|
|
1086
|
+
}
|
|
1087
|
+
);
|
|
1088
|
+
}
|
|
1089
|
+
);
|
|
1090
|
+
MenuSurface.displayName = "MenuSurface";
|
|
1091
|
+
|
|
1092
|
+
// src/components/dropdown-menu/dropdown-menu.tsx
|
|
1093
|
+
import { jsx as jsx11, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
1094
|
+
function DropdownMenu({
|
|
1095
|
+
...props
|
|
1096
|
+
}) {
|
|
1097
|
+
return /* @__PURE__ */ jsx11(DropdownMenuPrimitive.Root, { "data-slot": "dropdown-menu", ...props });
|
|
1098
|
+
}
|
|
1099
|
+
function DropdownMenuPortal({
|
|
1100
|
+
...props
|
|
1101
|
+
}) {
|
|
1102
|
+
return /* @__PURE__ */ jsx11(DropdownMenuPrimitive.Portal, { "data-slot": "dropdown-menu-portal", ...props });
|
|
1103
|
+
}
|
|
1104
|
+
function DropdownMenuTrigger({
|
|
1105
|
+
...props
|
|
1106
|
+
}) {
|
|
1107
|
+
return /* @__PURE__ */ jsx11(
|
|
1108
|
+
DropdownMenuPrimitive.Trigger,
|
|
1109
|
+
{
|
|
1110
|
+
"data-slot": "dropdown-menu-trigger",
|
|
1111
|
+
...props
|
|
1112
|
+
}
|
|
1113
|
+
);
|
|
1114
|
+
}
|
|
1115
|
+
function DropdownMenuContent({
|
|
1116
|
+
className,
|
|
1117
|
+
children,
|
|
1118
|
+
align = "start",
|
|
1119
|
+
sideOffset = 4,
|
|
1120
|
+
style,
|
|
1121
|
+
...props
|
|
1122
|
+
}) {
|
|
1123
|
+
return /* @__PURE__ */ jsx11(DropdownMenuPrimitive.Portal, { children: /* @__PURE__ */ jsx11(
|
|
1124
|
+
DropdownMenuPrimitive.Content,
|
|
1125
|
+
{
|
|
1126
|
+
asChild: true,
|
|
1127
|
+
"data-slot": "dropdown-menu-content",
|
|
1128
|
+
align,
|
|
1129
|
+
sideOffset,
|
|
1130
|
+
...props,
|
|
1131
|
+
children: /* @__PURE__ */ jsx11(
|
|
1132
|
+
MenuSurface,
|
|
1133
|
+
{
|
|
1134
|
+
"data-slot": "dropdown-menu-content",
|
|
1135
|
+
className: cn(
|
|
1136
|
+
"z-50 max-h-(--radix-dropdown-menu-content-available-height) w-(--radix-dropdown-menu-trigger-width) min-w-32 origin-(--radix-dropdown-menu-content-transform-origin) overflow-x-hidden overflow-y-auto",
|
|
1137
|
+
className
|
|
1138
|
+
),
|
|
1139
|
+
style: { zIndex: "var(--z-popover)", ...style },
|
|
1140
|
+
children
|
|
1141
|
+
}
|
|
1142
|
+
)
|
|
1143
|
+
}
|
|
1144
|
+
) });
|
|
1145
|
+
}
|
|
1146
|
+
function DropdownMenuGroup({
|
|
1147
|
+
className,
|
|
1148
|
+
...props
|
|
1149
|
+
}) {
|
|
1150
|
+
return /* @__PURE__ */ jsx11(
|
|
1151
|
+
DropdownMenuPrimitive.Group,
|
|
1152
|
+
{
|
|
1153
|
+
"data-slot": "dropdown-menu-group",
|
|
1154
|
+
className: cn("flex flex-col gap-0.5", className),
|
|
1155
|
+
...props
|
|
1156
|
+
}
|
|
1157
|
+
);
|
|
1158
|
+
}
|
|
1159
|
+
function DropdownMenuItem({
|
|
1160
|
+
className,
|
|
1161
|
+
inset,
|
|
1162
|
+
variant = "default",
|
|
1163
|
+
...props
|
|
1164
|
+
}) {
|
|
1165
|
+
return /* @__PURE__ */ jsx11(
|
|
1166
|
+
DropdownMenuPrimitive.Item,
|
|
1167
|
+
{
|
|
1168
|
+
"data-inset": inset,
|
|
1169
|
+
"data-slot": "dropdown-menu-item",
|
|
1170
|
+
"data-variant": variant,
|
|
1171
|
+
className: cn(
|
|
1172
|
+
"group/dropdown-menu-item",
|
|
1173
|
+
menuItemClassName,
|
|
1174
|
+
"data-inset:pl-7 data-[variant=destructive]:text-[var(--state-danger)] data-[variant=destructive]:focus:bg-[color-mix(in_srgb,var(--state-danger)_10%,transparent)] data-[variant=destructive]:focus:text-[var(--state-danger)] data-[variant=destructive]:hover:bg-[color-mix(in_srgb,var(--state-danger)_10%,transparent)] data-[variant=destructive]:hover:text-[var(--state-danger)] data-[variant=destructive]:*:[svg]:text-[var(--state-danger)]",
|
|
1175
|
+
className
|
|
1176
|
+
),
|
|
1177
|
+
...props
|
|
1178
|
+
}
|
|
1179
|
+
);
|
|
1180
|
+
}
|
|
1181
|
+
function DropdownMenuCheckboxItem({
|
|
1182
|
+
className,
|
|
1183
|
+
children,
|
|
1184
|
+
checked,
|
|
1185
|
+
inset,
|
|
1186
|
+
...props
|
|
1187
|
+
}) {
|
|
1188
|
+
return /* @__PURE__ */ jsxs5(
|
|
1189
|
+
DropdownMenuPrimitive.CheckboxItem,
|
|
1190
|
+
{
|
|
1191
|
+
checked,
|
|
1192
|
+
"data-inset": inset,
|
|
1193
|
+
"data-slot": "dropdown-menu-checkbox-item",
|
|
1194
|
+
className: cn(
|
|
1195
|
+
menuItemWithIndicatorClassName,
|
|
1196
|
+
"data-inset:pl-7",
|
|
1197
|
+
className
|
|
1198
|
+
),
|
|
1199
|
+
...props,
|
|
1200
|
+
children: [
|
|
1201
|
+
/* @__PURE__ */ jsx11(
|
|
1202
|
+
"span",
|
|
1203
|
+
{
|
|
1204
|
+
className: menuItemIndicatorClassName,
|
|
1205
|
+
"data-slot": "dropdown-menu-checkbox-item-indicator",
|
|
1206
|
+
children: /* @__PURE__ */ jsx11(DropdownMenuPrimitive.ItemIndicator, { children: /* @__PURE__ */ jsx11(CheckIcon, {}) })
|
|
1207
|
+
}
|
|
1208
|
+
),
|
|
1209
|
+
children
|
|
1210
|
+
]
|
|
1211
|
+
}
|
|
1212
|
+
);
|
|
1213
|
+
}
|
|
1214
|
+
function DropdownMenuRadioGroup({
|
|
1215
|
+
className,
|
|
1216
|
+
...props
|
|
1217
|
+
}) {
|
|
1218
|
+
return /* @__PURE__ */ jsx11(
|
|
1219
|
+
DropdownMenuPrimitive.RadioGroup,
|
|
1220
|
+
{
|
|
1221
|
+
"data-slot": "dropdown-menu-radio-group",
|
|
1222
|
+
className: cn("flex flex-col gap-0.5", className),
|
|
1223
|
+
...props
|
|
1224
|
+
}
|
|
1225
|
+
);
|
|
1226
|
+
}
|
|
1227
|
+
function DropdownMenuRadioItem({
|
|
1228
|
+
className,
|
|
1229
|
+
children,
|
|
1230
|
+
inset,
|
|
1231
|
+
...props
|
|
1232
|
+
}) {
|
|
1233
|
+
return /* @__PURE__ */ jsxs5(
|
|
1234
|
+
DropdownMenuPrimitive.RadioItem,
|
|
1235
|
+
{
|
|
1236
|
+
"data-inset": inset,
|
|
1237
|
+
"data-slot": "dropdown-menu-radio-item",
|
|
1238
|
+
className: cn(
|
|
1239
|
+
menuItemWithIndicatorClassName,
|
|
1240
|
+
"data-inset:pl-7",
|
|
1241
|
+
className
|
|
1242
|
+
),
|
|
1243
|
+
...props,
|
|
1244
|
+
children: [
|
|
1245
|
+
/* @__PURE__ */ jsx11(
|
|
1246
|
+
"span",
|
|
1247
|
+
{
|
|
1248
|
+
className: menuItemIndicatorClassName,
|
|
1249
|
+
"data-slot": "dropdown-menu-radio-item-indicator",
|
|
1250
|
+
children: /* @__PURE__ */ jsx11(DropdownMenuPrimitive.ItemIndicator, { children: /* @__PURE__ */ jsx11(CheckIcon, {}) })
|
|
1251
|
+
}
|
|
1252
|
+
),
|
|
1253
|
+
children
|
|
1254
|
+
]
|
|
1255
|
+
}
|
|
1256
|
+
);
|
|
1257
|
+
}
|
|
1258
|
+
function DropdownMenuLabel({
|
|
1259
|
+
className,
|
|
1260
|
+
inset,
|
|
1261
|
+
...props
|
|
1262
|
+
}) {
|
|
1263
|
+
return /* @__PURE__ */ jsx11(
|
|
1264
|
+
DropdownMenuPrimitive.Label,
|
|
1265
|
+
{
|
|
1266
|
+
"data-inset": inset,
|
|
1267
|
+
"data-slot": "dropdown-menu-label",
|
|
1268
|
+
className: cn(
|
|
1269
|
+
"px-1.5 py-1 text-xs font-medium text-[var(--text-secondary)] data-inset:pl-7",
|
|
1270
|
+
className
|
|
1271
|
+
),
|
|
1272
|
+
...props
|
|
1273
|
+
}
|
|
1274
|
+
);
|
|
1275
|
+
}
|
|
1276
|
+
function DropdownMenuSeparator({
|
|
1277
|
+
className,
|
|
1278
|
+
...props
|
|
1279
|
+
}) {
|
|
1280
|
+
return /* @__PURE__ */ jsx11(
|
|
1281
|
+
DropdownMenuPrimitive.Separator,
|
|
1282
|
+
{
|
|
1283
|
+
"data-slot": "dropdown-menu-separator",
|
|
1284
|
+
className: cn("mx-2 my-0.5 h-px bg-[var(--border-1)]", className),
|
|
1285
|
+
...props
|
|
1286
|
+
}
|
|
1287
|
+
);
|
|
1288
|
+
}
|
|
1289
|
+
function DropdownMenuShortcut({
|
|
1290
|
+
className,
|
|
1291
|
+
...props
|
|
1292
|
+
}) {
|
|
1293
|
+
return /* @__PURE__ */ jsx11(
|
|
1294
|
+
"span",
|
|
1295
|
+
{
|
|
1296
|
+
"data-slot": "dropdown-menu-shortcut",
|
|
1297
|
+
className: cn(
|
|
1298
|
+
"ml-auto text-xs tracking-widest text-[var(--text-secondary)] group-focus/dropdown-menu-item:text-[var(--text-primary)]",
|
|
1299
|
+
className
|
|
1300
|
+
),
|
|
1301
|
+
...props
|
|
1302
|
+
}
|
|
1303
|
+
);
|
|
1304
|
+
}
|
|
1305
|
+
function DropdownMenuSub({
|
|
1306
|
+
...props
|
|
1307
|
+
}) {
|
|
1308
|
+
return /* @__PURE__ */ jsx11(DropdownMenuPrimitive.Sub, { "data-slot": "dropdown-menu-sub", ...props });
|
|
1309
|
+
}
|
|
1310
|
+
function DropdownMenuSubTrigger({
|
|
1311
|
+
className,
|
|
1312
|
+
inset,
|
|
1313
|
+
children,
|
|
1314
|
+
...props
|
|
1315
|
+
}) {
|
|
1316
|
+
return /* @__PURE__ */ jsxs5(
|
|
1317
|
+
DropdownMenuPrimitive.SubTrigger,
|
|
1318
|
+
{
|
|
1319
|
+
"data-inset": inset,
|
|
1320
|
+
"data-slot": "dropdown-menu-sub-trigger",
|
|
1321
|
+
className: cn(
|
|
1322
|
+
menuItemClassName,
|
|
1323
|
+
"data-inset:pl-7 data-open:bg-[var(--transparency-block)] data-open:text-[var(--text-primary)]",
|
|
1324
|
+
className
|
|
1325
|
+
),
|
|
1326
|
+
...props,
|
|
1327
|
+
children: [
|
|
1328
|
+
children,
|
|
1329
|
+
/* @__PURE__ */ jsx11(ArrowRightIcon, { className: "ml-auto" })
|
|
1330
|
+
]
|
|
1331
|
+
}
|
|
1332
|
+
);
|
|
1333
|
+
}
|
|
1334
|
+
function DropdownMenuSubContent({
|
|
1335
|
+
className,
|
|
1336
|
+
children,
|
|
1337
|
+
style,
|
|
1338
|
+
...props
|
|
1339
|
+
}) {
|
|
1340
|
+
return /* @__PURE__ */ jsx11(
|
|
1341
|
+
DropdownMenuPrimitive.SubContent,
|
|
1342
|
+
{
|
|
1343
|
+
asChild: true,
|
|
1344
|
+
"data-slot": "dropdown-menu-sub-content",
|
|
1345
|
+
...props,
|
|
1346
|
+
children: /* @__PURE__ */ jsx11(
|
|
1347
|
+
MenuSurface,
|
|
1348
|
+
{
|
|
1349
|
+
"data-slot": "dropdown-menu-sub-content",
|
|
1350
|
+
className: cn(
|
|
1351
|
+
"z-50 min-w-[96px] origin-(--radix-dropdown-menu-content-transform-origin) overflow-hidden",
|
|
1352
|
+
className
|
|
1353
|
+
),
|
|
1354
|
+
style: { zIndex: "var(--z-popover)", ...style },
|
|
1355
|
+
children
|
|
1356
|
+
}
|
|
1357
|
+
)
|
|
1358
|
+
}
|
|
1359
|
+
);
|
|
1360
|
+
}
|
|
1361
|
+
|
|
1362
|
+
// src/components/input/input.tsx
|
|
1363
|
+
import { jsx as jsx12 } from "react/jsx-runtime";
|
|
1364
|
+
var inputVariantClassNames = {
|
|
1365
|
+
default: "h-8 rounded-[6px] px-3 py-0 text-sm leading-[1.3]",
|
|
1366
|
+
lg: "h-12 rounded-[8px] px-4 py-3 text-base leading-[1.3]",
|
|
1367
|
+
md: "h-8 rounded-[6px] px-3 py-0 text-sm leading-[1.3]",
|
|
1368
|
+
sm: "h-8 rounded-[6px] px-3 py-0 text-sm leading-[1.3]",
|
|
1369
|
+
otp: "h-12 w-12 rounded-[4px] px-0 text-center text-xl font-medium sm:h-14 sm:w-14 sm:text-2xl"
|
|
1370
|
+
};
|
|
1371
|
+
function Input({
|
|
1372
|
+
className,
|
|
1373
|
+
size = "default",
|
|
1374
|
+
type,
|
|
1375
|
+
variant,
|
|
1376
|
+
...props
|
|
1377
|
+
}) {
|
|
1378
|
+
const resolvedVariant = variant ?? (size === "sm" ? "sm" : "default");
|
|
1379
|
+
return /* @__PURE__ */ jsx12(
|
|
1380
|
+
"input",
|
|
1381
|
+
{
|
|
1382
|
+
type,
|
|
1383
|
+
"data-slot": "input",
|
|
1384
|
+
"data-size": size,
|
|
1385
|
+
"data-variant": resolvedVariant,
|
|
1386
|
+
className: cn(
|
|
1387
|
+
"w-full min-w-0 border border-transparent bg-[var(--transparency-block)] font-normal text-[var(--text-primary)] shadow-none transition-colors duration-200 outline-none file:inline-flex file:h-6 file:border-0 file:bg-transparent file:text-sm file:font-medium file:text-[var(--text-primary)] placeholder:text-[var(--text-placeholder)] hover:bg-[var(--transparency-hover)] focus:bg-[var(--transparency-hover)] focus-visible:border-transparent focus-visible:bg-[var(--transparency-hover)] focus-visible:ring-0 disabled:pointer-events-none disabled:cursor-not-allowed disabled:bg-[var(--transparency-block)] disabled:text-[var(--text-disabled)] disabled:opacity-100 aria-invalid:border-[var(--state-danger)] aria-invalid:bg-[var(--transparency-block)] aria-invalid:hover:bg-[var(--transparency-hover)] aria-invalid:focus:bg-[var(--transparency-hover)] aria-invalid:focus-visible:bg-[var(--transparency-hover)] aria-invalid:ring-0 aria-invalid:shadow-none",
|
|
1388
|
+
inputVariantClassNames[resolvedVariant],
|
|
1389
|
+
!variant && size === "sm" && "h-7 rounded-[4px] px-2 text-xs",
|
|
1390
|
+
className
|
|
1391
|
+
),
|
|
1392
|
+
...props
|
|
1393
|
+
}
|
|
1394
|
+
);
|
|
1395
|
+
}
|
|
1396
|
+
|
|
1397
|
+
// src/components/mention-pill/mention-pill.tsx
|
|
1398
|
+
import { jsx as jsx13, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
1399
|
+
var mentionPillTokenByKind = {
|
|
1400
|
+
app: "var(--rich-text-folder)",
|
|
1401
|
+
issue: "var(--rich-text-mention-issue)",
|
|
1402
|
+
session: "var(--rich-text-mention-session)",
|
|
1403
|
+
file: "var(--folder)"
|
|
1404
|
+
};
|
|
1405
|
+
var mentionPillDataKindByKind = {
|
|
1406
|
+
app: "app",
|
|
1407
|
+
issue: "task",
|
|
1408
|
+
session: "session",
|
|
1409
|
+
file: "file"
|
|
1410
|
+
};
|
|
1411
|
+
function MentionPill({
|
|
1412
|
+
className,
|
|
1413
|
+
fileKind = "file",
|
|
1414
|
+
iconUrl,
|
|
1415
|
+
kind,
|
|
1416
|
+
label,
|
|
1417
|
+
removable = kind === "file",
|
|
1418
|
+
removeButtonProps,
|
|
1419
|
+
style,
|
|
1420
|
+
summary,
|
|
1421
|
+
...props
|
|
1422
|
+
}) {
|
|
1423
|
+
const isFile = kind === "file";
|
|
1424
|
+
const Icon = isFile ? fileKind === "folder" ? FolderFilledIcon : FileIcon : kind === "app" ? AppWindowIcon : kind === "issue" ? IssueIcon : AgentSessionsIcon;
|
|
1425
|
+
const color = isFile && fileKind === "folder" ? "var(--folder)" : mentionPillTokenByKind[kind];
|
|
1426
|
+
const dataKind = mentionPillDataKindByKind[kind];
|
|
1427
|
+
const normalizedIconUrl = iconUrl?.trim() ?? "";
|
|
1428
|
+
const iconSizeClassName = "size-4";
|
|
1429
|
+
const iconShellClassName = isFile ? "size-4" : "size-[18px]";
|
|
1430
|
+
return /* @__PURE__ */ jsxs6(
|
|
1431
|
+
"span",
|
|
1432
|
+
{
|
|
1433
|
+
className: cn(
|
|
1434
|
+
"group relative top-[3px] inline-flex max-w-full cursor-default items-center overflow-hidden rounded-[4px] border border-transparent bg-transparent py-0.5 align-baseline text-sm font-medium leading-5 no-underline transition-colors hover:border-transparent hover:bg-[color-mix(in_srgb,currentColor_12%,transparent)]",
|
|
1435
|
+
isFile ? "gap-1.5 px-1.5" : "gap-1 px-1",
|
|
1436
|
+
className
|
|
1437
|
+
),
|
|
1438
|
+
"data-agent-file-mention": "true",
|
|
1439
|
+
"data-agent-mention-kind": dataKind,
|
|
1440
|
+
"data-slot": "mention-pill",
|
|
1441
|
+
style: {
|
|
1442
|
+
color,
|
|
1443
|
+
...style
|
|
1444
|
+
},
|
|
1445
|
+
...props,
|
|
1446
|
+
children: [
|
|
1447
|
+
/* @__PURE__ */ jsxs6(
|
|
1448
|
+
"span",
|
|
1449
|
+
{
|
|
1450
|
+
"aria-hidden": removable ? void 0 : true,
|
|
1451
|
+
className: cn(
|
|
1452
|
+
"relative grid shrink-0 place-items-center",
|
|
1453
|
+
iconShellClassName
|
|
1454
|
+
),
|
|
1455
|
+
children: [
|
|
1456
|
+
normalizedIconUrl ? /* @__PURE__ */ jsx13(
|
|
1457
|
+
"img",
|
|
1458
|
+
{
|
|
1459
|
+
src: normalizedIconUrl,
|
|
1460
|
+
alt: "",
|
|
1461
|
+
className: cn(
|
|
1462
|
+
"size-full rounded-[3px] object-cover transition-opacity",
|
|
1463
|
+
removable && "group-hover:opacity-0 group-focus-within:opacity-0"
|
|
1464
|
+
),
|
|
1465
|
+
decoding: "async",
|
|
1466
|
+
loading: "lazy",
|
|
1467
|
+
draggable: false
|
|
1468
|
+
}
|
|
1469
|
+
) : /* @__PURE__ */ jsx13(
|
|
1470
|
+
Icon,
|
|
1471
|
+
{
|
|
1472
|
+
className: cn(
|
|
1473
|
+
"text-current transition-opacity",
|
|
1474
|
+
removable && "group-hover:opacity-0 group-focus-within:opacity-0",
|
|
1475
|
+
iconSizeClassName
|
|
1476
|
+
)
|
|
1477
|
+
}
|
|
1478
|
+
),
|
|
1479
|
+
removable ? /* @__PURE__ */ jsx13(
|
|
1480
|
+
"button",
|
|
1481
|
+
{
|
|
1482
|
+
"aria-label": removeButtonProps?.["aria-label"],
|
|
1483
|
+
type: "button",
|
|
1484
|
+
...removeButtonProps,
|
|
1485
|
+
className: cn(
|
|
1486
|
+
"absolute top-1/2 left-1/2 inline-flex size-5 -translate-x-1/2 -translate-y-1/2 items-center justify-center rounded-sm text-[var(--text-secondary)] opacity-0 transition-opacity group-hover:opacity-100 hover:bg-transparency-block hover:text-[var(--text-primary)] focus-visible:opacity-100",
|
|
1487
|
+
removeButtonProps?.className
|
|
1488
|
+
),
|
|
1489
|
+
children: /* @__PURE__ */ jsx13(CloseIcon, { className: "size-3.5" })
|
|
1490
|
+
}
|
|
1491
|
+
) : null
|
|
1492
|
+
]
|
|
1493
|
+
}
|
|
1494
|
+
),
|
|
1495
|
+
/* @__PURE__ */ jsxs6("span", { className: "min-w-0 overflow-hidden text-ellipsis whitespace-nowrap", children: [
|
|
1496
|
+
/* @__PURE__ */ jsx13("span", { children: label }),
|
|
1497
|
+
summary ? /* @__PURE__ */ jsxs6("span", { className: "text-current", children: [
|
|
1498
|
+
" ",
|
|
1499
|
+
summary
|
|
1500
|
+
] }) : null
|
|
1501
|
+
] })
|
|
1502
|
+
]
|
|
1503
|
+
}
|
|
1504
|
+
);
|
|
1505
|
+
}
|
|
1506
|
+
|
|
1507
|
+
// src/components/popover/popover.tsx
|
|
1508
|
+
import { Popover as PopoverPrimitive } from "radix-ui";
|
|
1509
|
+
import { jsx as jsx14 } from "react/jsx-runtime";
|
|
1510
|
+
function Popover({
|
|
1511
|
+
...props
|
|
1512
|
+
}) {
|
|
1513
|
+
return /* @__PURE__ */ jsx14(PopoverPrimitive.Root, { "data-slot": "popover", ...props });
|
|
1514
|
+
}
|
|
1515
|
+
function PopoverTrigger({
|
|
1516
|
+
...props
|
|
1517
|
+
}) {
|
|
1518
|
+
return /* @__PURE__ */ jsx14(PopoverPrimitive.Trigger, { "data-slot": "popover-trigger", ...props });
|
|
1519
|
+
}
|
|
1520
|
+
function PopoverPortal({
|
|
1521
|
+
...props
|
|
1522
|
+
}) {
|
|
1523
|
+
return /* @__PURE__ */ jsx14(PopoverPrimitive.Portal, { "data-slot": "popover-portal", ...props });
|
|
1524
|
+
}
|
|
1525
|
+
function PopoverClose({
|
|
1526
|
+
...props
|
|
1527
|
+
}) {
|
|
1528
|
+
return /* @__PURE__ */ jsx14(PopoverPrimitive.Close, { "data-slot": "popover-close", ...props });
|
|
1529
|
+
}
|
|
1530
|
+
function PopoverContent({
|
|
1531
|
+
className,
|
|
1532
|
+
align = "center",
|
|
1533
|
+
sideOffset = 4,
|
|
1534
|
+
...props
|
|
1535
|
+
}) {
|
|
1536
|
+
return /* @__PURE__ */ jsx14(PopoverPortal, { children: /* @__PURE__ */ jsx14(
|
|
1537
|
+
PopoverPrimitive.Content,
|
|
1538
|
+
{
|
|
1539
|
+
"data-slot": "popover-content",
|
|
1540
|
+
align,
|
|
1541
|
+
sideOffset,
|
|
1542
|
+
className: cn(
|
|
1543
|
+
"t-dropdown z-50 flex w-72 origin-(--radix-popover-content-transform-origin) flex-col gap-2.5 rounded-lg border border-[var(--border-1)] bg-[var(--background-fronted)] p-3 text-sm text-popover-foreground shadow-soft outline-hidden",
|
|
1544
|
+
className
|
|
1545
|
+
),
|
|
1546
|
+
style: { zIndex: "var(--z-popover)" },
|
|
1547
|
+
...props
|
|
1548
|
+
}
|
|
1549
|
+
) });
|
|
1550
|
+
}
|
|
1551
|
+
function PopoverAnchor({
|
|
1552
|
+
...props
|
|
1553
|
+
}) {
|
|
1554
|
+
return /* @__PURE__ */ jsx14(PopoverPrimitive.Anchor, { "data-slot": "popover-anchor", ...props });
|
|
1555
|
+
}
|
|
1556
|
+
|
|
1557
|
+
// src/components/resizable/resizable.tsx
|
|
1558
|
+
import * as ResizablePrimitive from "react-resizable-panels";
|
|
1559
|
+
import { jsx as jsx15 } from "react/jsx-runtime";
|
|
1560
|
+
function ResizablePanelGroup({
|
|
1561
|
+
className,
|
|
1562
|
+
orientation = "horizontal",
|
|
1563
|
+
...props
|
|
1564
|
+
}) {
|
|
1565
|
+
return /* @__PURE__ */ jsx15(
|
|
1566
|
+
ResizablePrimitive.Group,
|
|
1567
|
+
{
|
|
1568
|
+
"data-orientation": orientation,
|
|
1569
|
+
"data-slot": "resizable-panel-group",
|
|
1570
|
+
className: cn(
|
|
1571
|
+
"flex h-full w-full data-[orientation=vertical]:flex-col",
|
|
1572
|
+
className
|
|
1573
|
+
),
|
|
1574
|
+
...props,
|
|
1575
|
+
orientation
|
|
1576
|
+
}
|
|
1577
|
+
);
|
|
1578
|
+
}
|
|
1579
|
+
function ResizablePanel(props) {
|
|
1580
|
+
return /* @__PURE__ */ jsx15(ResizablePrimitive.Panel, { "data-slot": "resizable-panel", ...props });
|
|
1581
|
+
}
|
|
1582
|
+
function ResizableHandle({
|
|
1583
|
+
className,
|
|
1584
|
+
withHandle,
|
|
1585
|
+
...props
|
|
1586
|
+
}) {
|
|
1587
|
+
return /* @__PURE__ */ jsx15(
|
|
1588
|
+
ResizablePrimitive.Separator,
|
|
1589
|
+
{
|
|
1590
|
+
"data-slot": "resizable-handle",
|
|
1591
|
+
className: cn(
|
|
1592
|
+
"group relative flex items-center justify-center bg-transparent outline-none after:absolute after:bg-border/70 after:transition-colors hover:after:bg-border focus-visible:after:bg-ring aria-[orientation=horizontal]:h-px aria-[orientation=horizontal]:w-full aria-[orientation=horizontal]:cursor-row-resize aria-[orientation=horizontal]:after:inset-x-0 aria-[orientation=horizontal]:after:top-1/2 aria-[orientation=horizontal]:after:h-px aria-[orientation=horizontal]:after:-translate-y-1/2 aria-[orientation=vertical]:h-full aria-[orientation=vertical]:w-px aria-[orientation=vertical]:cursor-col-resize aria-[orientation=vertical]:after:inset-y-0 aria-[orientation=vertical]:after:left-1/2 aria-[orientation=vertical]:after:w-px aria-[orientation=vertical]:after:-translate-x-1/2",
|
|
1593
|
+
className
|
|
1594
|
+
),
|
|
1595
|
+
...props,
|
|
1596
|
+
children: withHandle ? /* @__PURE__ */ jsx15("div", { className: "z-10 flex items-center justify-center rounded-full bg-border/85 opacity-0 transition-[background-color,opacity] group-hover:bg-border group-hover:opacity-100 group-focus-visible:bg-border group-focus-visible:opacity-100 group-aria-[orientation=horizontal]:h-[3px] group-aria-[orientation=horizontal]:w-10 group-aria-[orientation=vertical]:h-10 group-aria-[orientation=vertical]:w-[3px]" }) : null
|
|
1597
|
+
}
|
|
1598
|
+
);
|
|
1599
|
+
}
|
|
1600
|
+
|
|
1601
|
+
// src/components/scroll-area/scroll-area.tsx
|
|
1602
|
+
import * as React4 from "react";
|
|
1603
|
+
import { ScrollArea as ScrollAreaPrimitive } from "radix-ui";
|
|
1604
|
+
import { jsx as jsx16, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
1605
|
+
function ScrollArea({
|
|
1606
|
+
className,
|
|
1607
|
+
children,
|
|
1608
|
+
viewportClassName,
|
|
1609
|
+
viewportContentStyle,
|
|
1610
|
+
viewportProps,
|
|
1611
|
+
viewportRef,
|
|
1612
|
+
viewportTestId,
|
|
1613
|
+
...props
|
|
1614
|
+
}) {
|
|
1615
|
+
return /* @__PURE__ */ jsxs7(
|
|
1616
|
+
ScrollAreaPrimitive.Root,
|
|
1617
|
+
{
|
|
1618
|
+
"data-slot": "scroll-area",
|
|
1619
|
+
className: cn("group/scroll-area relative", className),
|
|
1620
|
+
...props,
|
|
1621
|
+
children: [
|
|
1622
|
+
/* @__PURE__ */ jsxs7(
|
|
1623
|
+
ScrollAreaPrimitive.Viewport,
|
|
1624
|
+
{
|
|
1625
|
+
...viewportProps,
|
|
1626
|
+
"data-slot": "scroll-area-viewport",
|
|
1627
|
+
"data-testid": viewportTestId,
|
|
1628
|
+
ref: viewportRef,
|
|
1629
|
+
className: cn(
|
|
1630
|
+
"size-full rounded-[inherit] transition-[color,box-shadow] outline-none focus-visible:ring-[3px] focus-visible:ring-ring/50 focus-visible:outline-1",
|
|
1631
|
+
viewportClassName
|
|
1632
|
+
),
|
|
1633
|
+
children: [
|
|
1634
|
+
viewportContentStyle ? /* @__PURE__ */ jsx16(ScrollAreaViewportContentStyleBridge, { style: viewportContentStyle }) : null,
|
|
1635
|
+
children
|
|
1636
|
+
]
|
|
1637
|
+
}
|
|
1638
|
+
),
|
|
1639
|
+
/* @__PURE__ */ jsx16(ScrollBar, {}),
|
|
1640
|
+
/* @__PURE__ */ jsx16(ScrollAreaPrimitive.Corner, {})
|
|
1641
|
+
]
|
|
1642
|
+
}
|
|
1643
|
+
);
|
|
1644
|
+
}
|
|
1645
|
+
function ScrollAreaViewportContentStyleBridge({
|
|
1646
|
+
style
|
|
1647
|
+
}) {
|
|
1648
|
+
const markerRef = React4.useRef(null);
|
|
1649
|
+
React4.useLayoutEffect(() => {
|
|
1650
|
+
const contentElement = markerRef.current?.parentElement;
|
|
1651
|
+
if (!contentElement) {
|
|
1652
|
+
return;
|
|
1653
|
+
}
|
|
1654
|
+
const previousValues = /* @__PURE__ */ new Map();
|
|
1655
|
+
for (const [property, value] of Object.entries(style)) {
|
|
1656
|
+
const cssProperty = toCssPropertyName(property);
|
|
1657
|
+
previousValues.set(cssProperty, {
|
|
1658
|
+
value: contentElement.style.getPropertyValue(cssProperty),
|
|
1659
|
+
priority: contentElement.style.getPropertyPriority(cssProperty)
|
|
1660
|
+
});
|
|
1661
|
+
if (value === void 0 || value === null) {
|
|
1662
|
+
contentElement.style.removeProperty(cssProperty);
|
|
1663
|
+
} else {
|
|
1664
|
+
contentElement.style.setProperty(cssProperty, String(value));
|
|
1665
|
+
}
|
|
1666
|
+
}
|
|
1667
|
+
return () => {
|
|
1668
|
+
for (const [cssProperty, previous] of previousValues) {
|
|
1669
|
+
if (previous.value) {
|
|
1670
|
+
contentElement.style.setProperty(
|
|
1671
|
+
cssProperty,
|
|
1672
|
+
previous.value,
|
|
1673
|
+
previous.priority
|
|
1674
|
+
);
|
|
1675
|
+
} else {
|
|
1676
|
+
contentElement.style.removeProperty(cssProperty);
|
|
1677
|
+
}
|
|
1678
|
+
}
|
|
1679
|
+
};
|
|
1680
|
+
}, [style]);
|
|
1681
|
+
return /* @__PURE__ */ jsx16("span", { ref: markerRef, "data-slot": "scroll-area-content-style-bridge", hidden: true });
|
|
1682
|
+
}
|
|
1683
|
+
function toCssPropertyName(property) {
|
|
1684
|
+
return property.startsWith("--") ? property : property.replace(/[A-Z]/g, (letter) => `-${letter.toLowerCase()}`);
|
|
1685
|
+
}
|
|
1686
|
+
function ScrollBar({
|
|
1687
|
+
className,
|
|
1688
|
+
orientation = "vertical",
|
|
1689
|
+
...props
|
|
1690
|
+
}) {
|
|
1691
|
+
return /* @__PURE__ */ jsx16(
|
|
1692
|
+
ScrollAreaPrimitive.ScrollAreaScrollbar,
|
|
1693
|
+
{
|
|
1694
|
+
"data-slot": "scroll-area-scrollbar",
|
|
1695
|
+
"data-orientation": orientation,
|
|
1696
|
+
orientation,
|
|
1697
|
+
className: cn(
|
|
1698
|
+
"group/scrollbar absolute z-10 flex touch-none p-[2px] opacity-0 transition-opacity duration-150 select-none group-hover/scroll-area:opacity-100 group-focus-within/scroll-area:opacity-100 data-[orientation=horizontal]:right-0 data-[orientation=horizontal]:bottom-0 data-[orientation=horizontal]:left-0 data-[orientation=horizontal]:h-2 data-[orientation=horizontal]:flex-col data-[orientation=vertical]:top-0 data-[orientation=vertical]:right-0 data-[orientation=vertical]:bottom-0 data-[orientation=vertical]:w-2",
|
|
1699
|
+
className
|
|
1700
|
+
),
|
|
1701
|
+
...props,
|
|
1702
|
+
children: /* @__PURE__ */ jsx16(
|
|
1703
|
+
ScrollAreaPrimitive.ScrollAreaThumb,
|
|
1704
|
+
{
|
|
1705
|
+
"data-slot": "scroll-area-thumb",
|
|
1706
|
+
className: "relative flex-1 rounded-full bg-[var(--transparency-block)] transition-colors duration-150 group-hover/scrollbar:bg-[var(--transparency-hover)]"
|
|
1707
|
+
}
|
|
1708
|
+
)
|
|
1709
|
+
}
|
|
1710
|
+
);
|
|
1711
|
+
}
|
|
1712
|
+
|
|
1713
|
+
// src/components/select/select.tsx
|
|
1714
|
+
import { Select as SelectPrimitive } from "radix-ui";
|
|
1715
|
+
import { jsx as jsx17, jsxs as jsxs8 } from "react/jsx-runtime";
|
|
1716
|
+
function Select({
|
|
1717
|
+
...props
|
|
1718
|
+
}) {
|
|
1719
|
+
return /* @__PURE__ */ jsx17(SelectPrimitive.Root, { "data-slot": "select", ...props });
|
|
1720
|
+
}
|
|
1721
|
+
function SelectGroup({
|
|
1722
|
+
className,
|
|
1723
|
+
...props
|
|
1724
|
+
}) {
|
|
1725
|
+
return /* @__PURE__ */ jsx17(
|
|
1726
|
+
SelectPrimitive.Group,
|
|
1727
|
+
{
|
|
1728
|
+
"data-slot": "select-group",
|
|
1729
|
+
className: cn("flex flex-col gap-0.5 scroll-my-1 p-1", className),
|
|
1730
|
+
...props
|
|
1731
|
+
}
|
|
1732
|
+
);
|
|
1733
|
+
}
|
|
1734
|
+
function SelectValue({
|
|
1735
|
+
...props
|
|
1736
|
+
}) {
|
|
1737
|
+
return /* @__PURE__ */ jsx17(SelectPrimitive.Value, { "data-slot": "select-value", ...props });
|
|
1738
|
+
}
|
|
1739
|
+
function SelectTrigger({
|
|
1740
|
+
className,
|
|
1741
|
+
size = "default",
|
|
1742
|
+
variant = "default",
|
|
1743
|
+
children,
|
|
1744
|
+
...props
|
|
1745
|
+
}) {
|
|
1746
|
+
return /* @__PURE__ */ jsxs8(
|
|
1747
|
+
SelectPrimitive.Trigger,
|
|
1748
|
+
{
|
|
1749
|
+
"data-slot": "select-trigger",
|
|
1750
|
+
"data-size": size,
|
|
1751
|
+
"data-variant": variant,
|
|
1752
|
+
className: cn(
|
|
1753
|
+
variant === "button" ? buttonVariants({ variant: "default", size }) : "flex w-fit cursor-pointer items-center justify-between gap-1.5 rounded-lg border border-transparent bg-[var(--transparency-block)] py-2 pr-2 pl-2.5 text-sm text-[var(--text-primary)] whitespace-nowrap transition-colors outline-none select-none hover:bg-[var(--transparency-hover)] focus:bg-[var(--transparency-hover)] focus-visible:border-transparent focus-visible:bg-[var(--transparency-hover)] focus-visible:ring-0 disabled:cursor-not-allowed disabled:bg-[var(--transparency-block)] disabled:text-[var(--text-disabled)] disabled:opacity-100 aria-invalid:border-[var(--state-danger)] aria-invalid:bg-[var(--transparency-block)] aria-invalid:hover:bg-[var(--transparency-hover)] aria-invalid:focus:bg-[var(--transparency-hover)] aria-invalid:focus-visible:bg-[var(--transparency-hover)] aria-invalid:ring-0 aria-invalid:shadow-none data-placeholder:text-[var(--text-placeholder)] data-[size=default]:h-8 data-[size=sm]:h-7 data-[size=sm]:rounded-[min(var(--radius-md),10px)] *:data-[slot=select-value]:line-clamp-1 *:data-[slot=select-value]:flex *:data-[slot=select-value]:items-center *:data-[slot=select-value]:gap-1.5 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
|
|
1754
|
+
"[&[data-state=open]>svg]:rotate-180 [&>svg]:transition-transform [&>svg]:duration-200",
|
|
1755
|
+
className
|
|
1756
|
+
),
|
|
1757
|
+
...props,
|
|
1758
|
+
children: [
|
|
1759
|
+
children,
|
|
1760
|
+
/* @__PURE__ */ jsx17(SelectPrimitive.Icon, { asChild: true, children: /* @__PURE__ */ jsx17(
|
|
1761
|
+
ChevronDownIcon,
|
|
1762
|
+
{
|
|
1763
|
+
className: cn("pointer-events-none size-4", "text-current")
|
|
1764
|
+
}
|
|
1765
|
+
) })
|
|
1766
|
+
]
|
|
1767
|
+
}
|
|
1768
|
+
);
|
|
1769
|
+
}
|
|
1770
|
+
function SelectContent({
|
|
1771
|
+
className,
|
|
1772
|
+
children,
|
|
1773
|
+
position = "popper",
|
|
1774
|
+
align = "center",
|
|
1775
|
+
style,
|
|
1776
|
+
...props
|
|
1777
|
+
}) {
|
|
1778
|
+
return /* @__PURE__ */ jsx17(SelectPrimitive.Portal, { children: /* @__PURE__ */ jsx17(
|
|
1779
|
+
SelectPrimitive.Content,
|
|
1780
|
+
{
|
|
1781
|
+
asChild: true,
|
|
1782
|
+
"data-slot": "select-content",
|
|
1783
|
+
"data-align-trigger": position === "item-aligned",
|
|
1784
|
+
position,
|
|
1785
|
+
align,
|
|
1786
|
+
...props,
|
|
1787
|
+
children: /* @__PURE__ */ jsxs8(
|
|
1788
|
+
MenuSurface,
|
|
1789
|
+
{
|
|
1790
|
+
"data-slot": "select-content",
|
|
1791
|
+
className: cn(
|
|
1792
|
+
"relative z-50 max-h-(--radix-select-content-available-height) min-w-36 origin-(--radix-select-content-transform-origin) overflow-x-hidden overflow-y-auto",
|
|
1793
|
+
position === "popper" && "data-[side=bottom]:translate-y-1 data-[side=left]:-translate-x-1 data-[side=right]:translate-x-1 data-[side=top]:-translate-y-1",
|
|
1794
|
+
className
|
|
1795
|
+
),
|
|
1796
|
+
style: { zIndex: "var(--z-popover)", ...style },
|
|
1797
|
+
children: [
|
|
1798
|
+
/* @__PURE__ */ jsx17(SelectScrollUpButton, {}),
|
|
1799
|
+
/* @__PURE__ */ jsx17(
|
|
1800
|
+
SelectPrimitive.Viewport,
|
|
1801
|
+
{
|
|
1802
|
+
"data-position": position,
|
|
1803
|
+
className: cn(
|
|
1804
|
+
"flex flex-col gap-0.5 data-[position=popper]:w-full data-[position=popper]:[min-width:var(--nextop-select-content-min-width,var(--radix-select-trigger-width))]"
|
|
1805
|
+
),
|
|
1806
|
+
children
|
|
1807
|
+
}
|
|
1808
|
+
),
|
|
1809
|
+
/* @__PURE__ */ jsx17(SelectScrollDownButton, {})
|
|
1810
|
+
]
|
|
1811
|
+
}
|
|
1812
|
+
)
|
|
1813
|
+
}
|
|
1814
|
+
) });
|
|
1815
|
+
}
|
|
1816
|
+
function SelectLabel({
|
|
1817
|
+
className,
|
|
1818
|
+
...props
|
|
1819
|
+
}) {
|
|
1820
|
+
return /* @__PURE__ */ jsx17(
|
|
1821
|
+
SelectPrimitive.Label,
|
|
1822
|
+
{
|
|
1823
|
+
"data-slot": "select-label",
|
|
1824
|
+
className: cn(
|
|
1825
|
+
"px-1.5 py-1 text-xs font-normal text-[var(--text-secondary)]",
|
|
1826
|
+
className
|
|
1827
|
+
),
|
|
1828
|
+
...props
|
|
1829
|
+
}
|
|
1830
|
+
);
|
|
1831
|
+
}
|
|
1832
|
+
function SelectSplitLayout({
|
|
1833
|
+
className,
|
|
1834
|
+
...props
|
|
1835
|
+
}) {
|
|
1836
|
+
return /* @__PURE__ */ jsx17(
|
|
1837
|
+
"div",
|
|
1838
|
+
{
|
|
1839
|
+
"data-slot": "select-split-layout",
|
|
1840
|
+
className: cn(
|
|
1841
|
+
"grid h-full min-h-0 grid-cols-[minmax(0,1fr)_1px_minmax(104px,132px)] gap-1 overflow-hidden",
|
|
1842
|
+
className
|
|
1843
|
+
),
|
|
1844
|
+
...props
|
|
1845
|
+
}
|
|
1846
|
+
);
|
|
1847
|
+
}
|
|
1848
|
+
function SelectSplitColumn({
|
|
1849
|
+
className,
|
|
1850
|
+
...props
|
|
1851
|
+
}) {
|
|
1852
|
+
return /* @__PURE__ */ jsx17(
|
|
1853
|
+
"div",
|
|
1854
|
+
{
|
|
1855
|
+
"data-slot": "select-split-column",
|
|
1856
|
+
className: cn("flex h-full min-h-0 min-w-0 flex-col", className),
|
|
1857
|
+
...props
|
|
1858
|
+
}
|
|
1859
|
+
);
|
|
1860
|
+
}
|
|
1861
|
+
function SelectSplitColumnLabel({
|
|
1862
|
+
className,
|
|
1863
|
+
...props
|
|
1864
|
+
}) {
|
|
1865
|
+
return /* @__PURE__ */ jsx17(
|
|
1866
|
+
"div",
|
|
1867
|
+
{
|
|
1868
|
+
"data-slot": "select-split-column-label",
|
|
1869
|
+
className: cn(
|
|
1870
|
+
"shrink-0 px-2 pt-1 pb-2 text-xs font-normal leading-[18px] text-[var(--text-secondary)]",
|
|
1871
|
+
className
|
|
1872
|
+
),
|
|
1873
|
+
...props
|
|
1874
|
+
}
|
|
1875
|
+
);
|
|
1876
|
+
}
|
|
1877
|
+
function SelectSplitColumnItems({
|
|
1878
|
+
className,
|
|
1879
|
+
...props
|
|
1880
|
+
}) {
|
|
1881
|
+
return /* @__PURE__ */ jsx17(
|
|
1882
|
+
"div",
|
|
1883
|
+
{
|
|
1884
|
+
"data-slot": "select-split-column-items",
|
|
1885
|
+
className: cn(
|
|
1886
|
+
"flex min-h-0 flex-1 flex-col gap-0.5 overflow-y-auto overscroll-contain",
|
|
1887
|
+
className
|
|
1888
|
+
),
|
|
1889
|
+
...props
|
|
1890
|
+
}
|
|
1891
|
+
);
|
|
1892
|
+
}
|
|
1893
|
+
function SelectSplitDivider({
|
|
1894
|
+
className,
|
|
1895
|
+
...props
|
|
1896
|
+
}) {
|
|
1897
|
+
return /* @__PURE__ */ jsx17(
|
|
1898
|
+
"div",
|
|
1899
|
+
{
|
|
1900
|
+
"aria-hidden": "true",
|
|
1901
|
+
"data-slot": "select-split-divider",
|
|
1902
|
+
className: cn(
|
|
1903
|
+
"self-stretch bg-[var(--border-2,var(--border-1))]",
|
|
1904
|
+
className
|
|
1905
|
+
),
|
|
1906
|
+
...props
|
|
1907
|
+
}
|
|
1908
|
+
);
|
|
1909
|
+
}
|
|
1910
|
+
function SelectItem({
|
|
1911
|
+
className,
|
|
1912
|
+
children,
|
|
1913
|
+
forceSelectedIndicator = false,
|
|
1914
|
+
...props
|
|
1915
|
+
}) {
|
|
1916
|
+
return /* @__PURE__ */ jsxs8(
|
|
1917
|
+
SelectPrimitive.Item,
|
|
1918
|
+
{
|
|
1919
|
+
"data-slot": "select-item",
|
|
1920
|
+
className: cn("w-full", menuItemWithIndicatorClassName, className),
|
|
1921
|
+
...props,
|
|
1922
|
+
children: [
|
|
1923
|
+
/* @__PURE__ */ jsx17("span", { className: menuItemIndicatorClassName, children: forceSelectedIndicator ? /* @__PURE__ */ jsx17(
|
|
1924
|
+
CheckIcon,
|
|
1925
|
+
{
|
|
1926
|
+
className: "pointer-events-none",
|
|
1927
|
+
"data-slot": "select-item-forced-indicator"
|
|
1928
|
+
}
|
|
1929
|
+
) : /* @__PURE__ */ jsx17(SelectPrimitive.ItemIndicator, { children: /* @__PURE__ */ jsx17(CheckIcon, { className: "pointer-events-none" }) }) }),
|
|
1930
|
+
/* @__PURE__ */ jsx17(SelectPrimitive.ItemText, { children })
|
|
1931
|
+
]
|
|
1932
|
+
}
|
|
1933
|
+
);
|
|
1934
|
+
}
|
|
1935
|
+
function SelectSeparator({
|
|
1936
|
+
className,
|
|
1937
|
+
...props
|
|
1938
|
+
}) {
|
|
1939
|
+
return /* @__PURE__ */ jsx17(
|
|
1940
|
+
SelectPrimitive.Separator,
|
|
1941
|
+
{
|
|
1942
|
+
"data-slot": "select-separator",
|
|
1943
|
+
className: cn(
|
|
1944
|
+
"pointer-events-none mx-2 my-0.5 h-px bg-[var(--border-1)]",
|
|
1945
|
+
className
|
|
1946
|
+
),
|
|
1947
|
+
...props
|
|
1948
|
+
}
|
|
1949
|
+
);
|
|
1950
|
+
}
|
|
1951
|
+
function SelectScrollUpButton({
|
|
1952
|
+
className,
|
|
1953
|
+
...props
|
|
1954
|
+
}) {
|
|
1955
|
+
return /* @__PURE__ */ jsx17(
|
|
1956
|
+
SelectPrimitive.ScrollUpButton,
|
|
1957
|
+
{
|
|
1958
|
+
"data-slot": "select-scroll-up-button",
|
|
1959
|
+
className: cn(
|
|
1960
|
+
"z-10 flex cursor-pointer items-center justify-center bg-[var(--background-fronted)] py-1 [&_svg:not([class*='size-'])]:size-4",
|
|
1961
|
+
className
|
|
1962
|
+
),
|
|
1963
|
+
...props,
|
|
1964
|
+
children: /* @__PURE__ */ jsx17(ChevronUpIcon, {})
|
|
1965
|
+
}
|
|
1966
|
+
);
|
|
1967
|
+
}
|
|
1968
|
+
function SelectScrollDownButton({
|
|
1969
|
+
className,
|
|
1970
|
+
...props
|
|
1971
|
+
}) {
|
|
1972
|
+
return /* @__PURE__ */ jsx17(
|
|
1973
|
+
SelectPrimitive.ScrollDownButton,
|
|
1974
|
+
{
|
|
1975
|
+
"data-slot": "select-scroll-down-button",
|
|
1976
|
+
className: cn(
|
|
1977
|
+
"z-10 flex cursor-pointer items-center justify-center bg-[var(--background-fronted)] py-1 [&_svg:not([class*='size-'])]:size-4",
|
|
1978
|
+
className
|
|
1979
|
+
),
|
|
1980
|
+
...props,
|
|
1981
|
+
children: /* @__PURE__ */ jsx17(ChevronDownIcon, {})
|
|
1982
|
+
}
|
|
1983
|
+
);
|
|
1984
|
+
}
|
|
1985
|
+
|
|
1986
|
+
// src/components/separator/separator.tsx
|
|
1987
|
+
import { Separator as SeparatorPrimitive } from "radix-ui";
|
|
1988
|
+
import { jsx as jsx18 } from "react/jsx-runtime";
|
|
1989
|
+
function Separator2({
|
|
1990
|
+
className,
|
|
1991
|
+
orientation = "horizontal",
|
|
1992
|
+
decorative = true,
|
|
1993
|
+
...props
|
|
1994
|
+
}) {
|
|
1995
|
+
return /* @__PURE__ */ jsx18(
|
|
1996
|
+
SeparatorPrimitive.Root,
|
|
1997
|
+
{
|
|
1998
|
+
"data-slot": "separator",
|
|
1999
|
+
decorative,
|
|
2000
|
+
orientation,
|
|
2001
|
+
className: cn(
|
|
2002
|
+
"shrink-0 bg-border data-horizontal:h-px data-horizontal:w-full data-vertical:w-px data-vertical:self-stretch",
|
|
2003
|
+
className
|
|
2004
|
+
),
|
|
2005
|
+
...props
|
|
2006
|
+
}
|
|
2007
|
+
);
|
|
2008
|
+
}
|
|
2009
|
+
|
|
2010
|
+
// src/components/section-tabs/section-tabs.tsx
|
|
2011
|
+
import { jsx as jsx19, jsxs as jsxs9 } from "react/jsx-runtime";
|
|
2012
|
+
function SectionTabs({
|
|
2013
|
+
tabs,
|
|
2014
|
+
value,
|
|
2015
|
+
onValueChange,
|
|
2016
|
+
ariaLabel,
|
|
2017
|
+
className,
|
|
2018
|
+
testId
|
|
2019
|
+
}) {
|
|
2020
|
+
return /* @__PURE__ */ jsx19(
|
|
2021
|
+
"div",
|
|
2022
|
+
{
|
|
2023
|
+
"aria-label": ariaLabel,
|
|
2024
|
+
className: cn("flex min-w-0 items-center gap-5", className),
|
|
2025
|
+
"data-slot": "section-tabs",
|
|
2026
|
+
"data-testid": testId,
|
|
2027
|
+
role: "tablist",
|
|
2028
|
+
children: tabs.map((tab) => {
|
|
2029
|
+
const isActive = value === tab.value;
|
|
2030
|
+
return /* @__PURE__ */ jsxs9(
|
|
2031
|
+
"button",
|
|
2032
|
+
{
|
|
2033
|
+
"aria-selected": isActive,
|
|
2034
|
+
className: cn(
|
|
2035
|
+
"relative inline-flex h-5 shrink-0 items-center gap-1.5 whitespace-nowrap border-0 bg-transparent p-0 text-[15px] font-semibold leading-5 tracking-[0] text-[var(--text-secondary)] transition-colors duration-150 hover:text-[var(--text-primary)] focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-[var(--border-focus)]",
|
|
2036
|
+
isActive && "text-[var(--text-primary)]"
|
|
2037
|
+
),
|
|
2038
|
+
"data-active": isActive ? "true" : "false",
|
|
2039
|
+
"data-slot": "section-tabs-tab",
|
|
2040
|
+
"data-testid": tab.testId,
|
|
2041
|
+
role: "tab",
|
|
2042
|
+
type: "button",
|
|
2043
|
+
onClick: () => onValueChange(tab.value),
|
|
2044
|
+
children: [
|
|
2045
|
+
/* @__PURE__ */ jsx19("span", { className: "min-w-0 truncate", children: tab.label }),
|
|
2046
|
+
tab.count !== void 0 ? /* @__PURE__ */ jsx19("span", { className: "text-[15px] font-semibold leading-5 text-[inherit]", children: tab.count }) : null
|
|
2047
|
+
]
|
|
2048
|
+
},
|
|
2049
|
+
tab.value
|
|
2050
|
+
);
|
|
2051
|
+
})
|
|
2052
|
+
}
|
|
2053
|
+
);
|
|
2054
|
+
}
|
|
2055
|
+
|
|
2056
|
+
// src/components/shortcut-badge/shortcut-badge.tsx
|
|
2057
|
+
import { jsx as jsx20 } from "react/jsx-runtime";
|
|
2058
|
+
function ShortcutBadge({ className, ...props }) {
|
|
2059
|
+
return /* @__PURE__ */ jsx20(
|
|
2060
|
+
"kbd",
|
|
2061
|
+
{
|
|
2062
|
+
"data-slot": "shortcut-badge",
|
|
2063
|
+
className: cn(
|
|
2064
|
+
"inline-flex h-5 min-w-0 max-w-full shrink-0 items-center justify-center overflow-hidden rounded-[4px] bg-[color-mix(in_srgb,var(--transparency-block)_72%,transparent)] px-1.5 py-1 font-[inherit] text-[11px] leading-none font-semibold whitespace-nowrap text-[var(--text-tertiary)] not-italic [font-variant:normal] [text-overflow:ellipsis]",
|
|
2065
|
+
className
|
|
2066
|
+
),
|
|
2067
|
+
...props
|
|
2068
|
+
}
|
|
2069
|
+
);
|
|
2070
|
+
}
|
|
2071
|
+
|
|
2072
|
+
// src/components/sonner/sonner.tsx
|
|
2073
|
+
import {
|
|
2074
|
+
Toaster as SonnerToaster,
|
|
2075
|
+
toast
|
|
2076
|
+
} from "sonner";
|
|
2077
|
+
import { jsx as jsx21 } from "react/jsx-runtime";
|
|
2078
|
+
function Toaster({ toastOptions, style, ...props }) {
|
|
2079
|
+
return /* @__PURE__ */ jsx21(
|
|
2080
|
+
SonnerToaster,
|
|
2081
|
+
{
|
|
2082
|
+
closeButton: true,
|
|
2083
|
+
expand: false,
|
|
2084
|
+
gap: 8,
|
|
2085
|
+
position: "top-right",
|
|
2086
|
+
visibleToasts: 4,
|
|
2087
|
+
icons: {
|
|
2088
|
+
error: /* @__PURE__ */ jsx21(FailedFilledIcon, { className: "size-4" }),
|
|
2089
|
+
info: /* @__PURE__ */ jsx21(WarningLinedIcon, { className: "size-4" }),
|
|
2090
|
+
loading: /* @__PURE__ */ jsx21(LoadingIcon, { className: "size-4 animate-spin" }),
|
|
2091
|
+
success: /* @__PURE__ */ jsx21(SuccessFilledIcon, { className: "size-4" }),
|
|
2092
|
+
warning: /* @__PURE__ */ jsx21(WarningFilledIcon, { className: "size-4" })
|
|
2093
|
+
},
|
|
2094
|
+
style: {
|
|
2095
|
+
"--normal-bg": "var(--background-fronted)",
|
|
2096
|
+
"--normal-border": "var(--line-2)",
|
|
2097
|
+
"--normal-text": "var(--text-primary)",
|
|
2098
|
+
"--border-radius": "8px",
|
|
2099
|
+
zIndex: "var(--z-toast)",
|
|
2100
|
+
...style
|
|
2101
|
+
},
|
|
2102
|
+
toastOptions: {
|
|
2103
|
+
...toastOptions,
|
|
2104
|
+
classNames: {
|
|
2105
|
+
toast: "group pointer-events-auto min-h-14 rounded-[8px] border border-[var(--line-2)] bg-[var(--background-fronted)] px-3.5 py-3 text-[var(--text-primary)] shadow-[0_14px_40px_var(--shadow-elevated)]",
|
|
2106
|
+
title: "text-sm font-semibold leading-5 text-[var(--text-primary)]",
|
|
2107
|
+
description: "mt-0.5 text-xs leading-5 text-[var(--text-secondary)]",
|
|
2108
|
+
actionButton: "h-7 rounded-[6px] bg-[var(--text-primary)] px-2.5 text-xs font-normal text-[var(--text-inverted)] transition-colors hover:bg-[var(--text-primary-hover)]",
|
|
2109
|
+
cancelButton: "h-7 rounded-[6px] bg-[var(--transparency-block)] px-2.5 text-xs font-normal text-[var(--text-primary)] transition-colors hover:bg-[var(--transparency-hover)]",
|
|
2110
|
+
closeButton: "border-[var(--line-2)] bg-[var(--background-fronted)] text-[var(--text-secondary)] hover:bg-[var(--transparency-hover)] hover:text-[var(--text-primary)]",
|
|
2111
|
+
icon: "text-[var(--accent)]",
|
|
2112
|
+
...toastOptions?.classNames
|
|
2113
|
+
}
|
|
2114
|
+
},
|
|
2115
|
+
...props
|
|
2116
|
+
}
|
|
2117
|
+
);
|
|
2118
|
+
}
|
|
2119
|
+
|
|
2120
|
+
// src/components/spinner/spinner.tsx
|
|
2121
|
+
import { jsx as jsx22 } from "react/jsx-runtime";
|
|
2122
|
+
function Spinner({
|
|
2123
|
+
className,
|
|
2124
|
+
size = 16,
|
|
2125
|
+
strokeWidth = 2,
|
|
2126
|
+
style,
|
|
2127
|
+
testId,
|
|
2128
|
+
trackColor
|
|
2129
|
+
}) {
|
|
2130
|
+
return /* @__PURE__ */ jsx22(
|
|
2131
|
+
LoadingIcon,
|
|
2132
|
+
{
|
|
2133
|
+
"data-slot": "spinner",
|
|
2134
|
+
"data-testid": testId,
|
|
2135
|
+
"aria-hidden": "true",
|
|
2136
|
+
className: cn(
|
|
2137
|
+
"inline-block shrink-0 animate-spin text-primary",
|
|
2138
|
+
className
|
|
2139
|
+
),
|
|
2140
|
+
size,
|
|
2141
|
+
style,
|
|
2142
|
+
strokeWidth,
|
|
2143
|
+
trackColor
|
|
2144
|
+
}
|
|
2145
|
+
);
|
|
2146
|
+
}
|
|
2147
|
+
|
|
2148
|
+
// src/components/status-dot/status-dot.tsx
|
|
2149
|
+
import { cva as cva4 } from "class-variance-authority";
|
|
2150
|
+
import { jsx as jsx23 } from "react/jsx-runtime";
|
|
2151
|
+
var statusDotVariants = cva4("inline-flex shrink-0 rounded-full", {
|
|
2152
|
+
variants: {
|
|
2153
|
+
tone: {
|
|
2154
|
+
neutral: "bg-muted-foreground/70",
|
|
2155
|
+
green: "bg-emerald-500",
|
|
2156
|
+
blue: "bg-sky-500",
|
|
2157
|
+
amber: "bg-amber-500",
|
|
2158
|
+
red: "bg-destructive"
|
|
2159
|
+
},
|
|
2160
|
+
size: {
|
|
2161
|
+
xs: "size-1.5",
|
|
2162
|
+
sm: "size-2",
|
|
2163
|
+
md: "size-2.5"
|
|
2164
|
+
},
|
|
2165
|
+
pulse: {
|
|
2166
|
+
true: "animate-pulse",
|
|
2167
|
+
false: ""
|
|
2168
|
+
}
|
|
2169
|
+
},
|
|
2170
|
+
defaultVariants: {
|
|
2171
|
+
tone: "neutral",
|
|
2172
|
+
size: "sm",
|
|
2173
|
+
pulse: false
|
|
2174
|
+
}
|
|
2175
|
+
});
|
|
2176
|
+
function StatusDot({
|
|
2177
|
+
tone = "neutral",
|
|
2178
|
+
size = "sm",
|
|
2179
|
+
pulse = false,
|
|
2180
|
+
ariaLabel,
|
|
2181
|
+
title,
|
|
2182
|
+
className
|
|
2183
|
+
}) {
|
|
2184
|
+
return /* @__PURE__ */ jsx23(
|
|
2185
|
+
"span",
|
|
2186
|
+
{
|
|
2187
|
+
"aria-hidden": ariaLabel ? void 0 : true,
|
|
2188
|
+
"aria-label": ariaLabel,
|
|
2189
|
+
className: cn(statusDotVariants({ tone, size, pulse }), className),
|
|
2190
|
+
"data-pulse": pulse ? "true" : void 0,
|
|
2191
|
+
"data-size": size,
|
|
2192
|
+
"data-slot": "status-dot",
|
|
2193
|
+
"data-tone": tone,
|
|
2194
|
+
role: ariaLabel ? "img" : void 0,
|
|
2195
|
+
title
|
|
2196
|
+
}
|
|
2197
|
+
);
|
|
2198
|
+
}
|
|
2199
|
+
|
|
2200
|
+
// src/components/switch/switch.tsx
|
|
2201
|
+
import { Switch as SwitchPrimitive } from "radix-ui";
|
|
2202
|
+
import { jsx as jsx24 } from "react/jsx-runtime";
|
|
2203
|
+
function Switch({
|
|
2204
|
+
className,
|
|
2205
|
+
size = "default",
|
|
2206
|
+
...props
|
|
2207
|
+
}) {
|
|
2208
|
+
return /* @__PURE__ */ jsx24(
|
|
2209
|
+
SwitchPrimitive.Root,
|
|
2210
|
+
{
|
|
2211
|
+
"data-slot": "switch",
|
|
2212
|
+
"data-size": size,
|
|
2213
|
+
className: cn(
|
|
2214
|
+
"peer group/switch relative inline-flex shrink-0 items-center rounded-full border border-transparent transition-[background-color,border-color,box-shadow] outline-none focus-visible:border-[var(--border-focus)] focus-visible:ring-2 focus-visible:ring-[color-mix(in_srgb,var(--border-focus)_30%,transparent)] aria-invalid:border-[var(--state-danger)] aria-invalid:ring-2 aria-invalid:ring-[color-mix(in_srgb,var(--state-danger)_20%,transparent)] data-[size=default]:h-[18px] data-[size=default]:w-[32px] data-[size=sm]:h-[14px] data-[size=sm]:w-[24px] data-[state=checked]:bg-[var(--accent)] data-[state=unchecked]:bg-[var(--text-disabled)] data-disabled:cursor-not-allowed data-disabled:opacity-100",
|
|
2215
|
+
className
|
|
2216
|
+
),
|
|
2217
|
+
...props,
|
|
2218
|
+
children: /* @__PURE__ */ jsx24(
|
|
2219
|
+
SwitchPrimitive.Thumb,
|
|
2220
|
+
{
|
|
2221
|
+
"data-slot": "switch-thumb",
|
|
2222
|
+
className: "pointer-events-none block rounded-full bg-[var(--white-stationary)] ring-0 transition-transform group-data-[size=default]/switch:size-4 group-data-[size=sm]/switch:size-3 group-data-[size=default]/switch:data-[state=checked]:translate-x-[14px] group-data-[size=sm]/switch:data-[state=checked]:translate-x-[10px] group-data-[size=default]/switch:data-[state=unchecked]:translate-x-0 group-data-[size=sm]/switch:data-[state=unchecked]:translate-x-0"
|
|
2223
|
+
}
|
|
2224
|
+
)
|
|
2225
|
+
}
|
|
2226
|
+
);
|
|
2227
|
+
}
|
|
2228
|
+
|
|
2229
|
+
// src/components/textarea/textarea.tsx
|
|
2230
|
+
import { jsx as jsx25 } from "react/jsx-runtime";
|
|
2231
|
+
function Textarea({ className, ...props }) {
|
|
2232
|
+
return /* @__PURE__ */ jsx25(
|
|
2233
|
+
"textarea",
|
|
2234
|
+
{
|
|
2235
|
+
"data-slot": "textarea",
|
|
2236
|
+
className: cn(
|
|
2237
|
+
"flex field-sizing-content min-h-20 w-full rounded-[6px] border border-transparent bg-[var(--transparency-block)] px-3 py-3 text-sm font-normal leading-[1.3] text-[var(--text-primary)] transition-[background-color,border-color,color] outline-none shadow-none placeholder:text-[var(--text-placeholder)] hover:bg-[var(--transparency-hover)] focus:bg-[var(--transparency-hover)] focus-visible:border-transparent focus-visible:bg-[var(--transparency-hover)] focus-visible:ring-0 disabled:cursor-not-allowed disabled:bg-[var(--transparency-block)] disabled:text-[var(--text-disabled)] disabled:opacity-100 aria-invalid:border-[var(--state-danger)] aria-invalid:bg-[var(--transparency-block)] aria-invalid:hover:bg-[var(--transparency-hover)] aria-invalid:focus:bg-[var(--transparency-hover)] aria-invalid:focus-visible:bg-[var(--transparency-hover)] aria-invalid:ring-0 aria-invalid:shadow-none",
|
|
2238
|
+
className
|
|
2239
|
+
),
|
|
2240
|
+
...props
|
|
2241
|
+
}
|
|
2242
|
+
);
|
|
2243
|
+
}
|
|
2244
|
+
|
|
2245
|
+
// src/components/toast/toast.tsx
|
|
2246
|
+
import * as React5 from "react";
|
|
2247
|
+
import { Toast as ToastPrimitive } from "radix-ui";
|
|
2248
|
+
import { cva as cva5 } from "class-variance-authority";
|
|
2249
|
+
import { jsx as jsx26, jsxs as jsxs10 } from "react/jsx-runtime";
|
|
2250
|
+
var toastDefaultDurationMs = 3e3;
|
|
2251
|
+
function ToastProvider({
|
|
2252
|
+
duration = toastDefaultDurationMs,
|
|
2253
|
+
...props
|
|
2254
|
+
}) {
|
|
2255
|
+
return /* @__PURE__ */ jsx26(ToastPrimitive.Provider, { duration, ...props });
|
|
2256
|
+
}
|
|
2257
|
+
var ToastVisualContext = React5.createContext(null);
|
|
2258
|
+
var toastStatusIconByVariant = {
|
|
2259
|
+
destructive: FailedFilledIcon,
|
|
2260
|
+
success: SuccessFilledIcon
|
|
2261
|
+
};
|
|
2262
|
+
function hasToastStatusIcon(variant) {
|
|
2263
|
+
return variant === "destructive" || variant === "success";
|
|
2264
|
+
}
|
|
2265
|
+
function stripToastTrailingSentencePunctuation(value) {
|
|
2266
|
+
let nextValue = value.replace(/\s+$/u, "");
|
|
2267
|
+
while (nextValue.length > 0) {
|
|
2268
|
+
const last = nextValue.at(-1);
|
|
2269
|
+
if (last === "." || last === "\u3002" || last === "\uFF0E") {
|
|
2270
|
+
nextValue = nextValue.slice(0, -1).replace(/\s+$/u, "");
|
|
2271
|
+
} else {
|
|
2272
|
+
break;
|
|
2273
|
+
}
|
|
2274
|
+
}
|
|
2275
|
+
return nextValue;
|
|
2276
|
+
}
|
|
2277
|
+
function formatToastText(children) {
|
|
2278
|
+
if (typeof children === "string") {
|
|
2279
|
+
return stripToastTrailingSentencePunctuation(children);
|
|
2280
|
+
}
|
|
2281
|
+
const flatChildren = React5.Children.toArray(children);
|
|
2282
|
+
if (flatChildren.length === 1 && typeof flatChildren[0] === "string") {
|
|
2283
|
+
return stripToastTrailingSentencePunctuation(flatChildren[0]);
|
|
2284
|
+
}
|
|
2285
|
+
return children;
|
|
2286
|
+
}
|
|
2287
|
+
var toastVariants = cva5(
|
|
2288
|
+
"group pointer-events-auto relative flex min-h-8 min-w-0 max-w-[min(92vw,420px)] items-center justify-center rounded-[8px] px-3 py-1.5 text-center text-sm font-normal leading-normal shadow-none transition-all data-closed:fade-out-80 data-closed:slide-out-to-top-full data-open:slide-in-from-top-full data-[swipe=cancel]:translate-x-0 data-[swipe=end]:translate-x-[var(--radix-toast-swipe-end-x)] data-[swipe=move]:translate-x-[var(--radix-toast-swipe-move-x)] data-[swipe=move]:transition-none",
|
|
2289
|
+
{
|
|
2290
|
+
variants: {
|
|
2291
|
+
variant: {
|
|
2292
|
+
default: "border border-[var(--toast-neutral-border)] bg-[var(--toast-neutral-bg)] text-[var(--toast-neutral-fg)]",
|
|
2293
|
+
destructive: "border-0 bg-[var(--state-danger)] text-[var(--white-stationary)]",
|
|
2294
|
+
success: "border-0 bg-[var(--state-success)] text-[var(--text-inverted)]"
|
|
2295
|
+
}
|
|
2296
|
+
},
|
|
2297
|
+
defaultVariants: {
|
|
2298
|
+
variant: "default"
|
|
2299
|
+
}
|
|
2300
|
+
}
|
|
2301
|
+
);
|
|
2302
|
+
function ToastRoot({
|
|
2303
|
+
className,
|
|
2304
|
+
variant,
|
|
2305
|
+
busy = false,
|
|
2306
|
+
anchor = "viewport",
|
|
2307
|
+
nodeInsetTopPx = 16,
|
|
2308
|
+
children,
|
|
2309
|
+
style,
|
|
2310
|
+
...props
|
|
2311
|
+
}) {
|
|
2312
|
+
const isDestructive = variant === "destructive";
|
|
2313
|
+
return /* @__PURE__ */ jsx26(
|
|
2314
|
+
ToastPrimitive.Root,
|
|
2315
|
+
{
|
|
2316
|
+
"aria-busy": busy,
|
|
2317
|
+
"aria-live": isDestructive ? "assertive" : "polite",
|
|
2318
|
+
"data-slot": "toast",
|
|
2319
|
+
className: cn(
|
|
2320
|
+
toastVariants({ variant }),
|
|
2321
|
+
anchor === "node" && "absolute left-1/2 -translate-x-1/2",
|
|
2322
|
+
className
|
|
2323
|
+
),
|
|
2324
|
+
role: isDestructive ? "alert" : "status",
|
|
2325
|
+
style: {
|
|
2326
|
+
...anchor === "node" ? { top: `${nodeInsetTopPx}px` } : {},
|
|
2327
|
+
...style
|
|
2328
|
+
},
|
|
2329
|
+
...props,
|
|
2330
|
+
children: /* @__PURE__ */ jsx26(ToastVisualContext.Provider, { value: { busy, variant }, children: /* @__PURE__ */ jsx26("span", { className: "flex min-w-0 max-w-full flex-col items-center justify-center whitespace-normal break-words text-center", children }) })
|
|
2331
|
+
}
|
|
2332
|
+
);
|
|
2333
|
+
}
|
|
2334
|
+
function ToastTitle({
|
|
2335
|
+
className,
|
|
2336
|
+
children,
|
|
2337
|
+
...props
|
|
2338
|
+
}) {
|
|
2339
|
+
const toastVisual = React5.useContext(ToastVisualContext);
|
|
2340
|
+
const StatusIcon = toastVisual?.variant && hasToastStatusIcon(toastVisual.variant) ? toastStatusIconByVariant[toastVisual.variant] : null;
|
|
2341
|
+
return /* @__PURE__ */ jsxs10(
|
|
2342
|
+
ToastPrimitive.Title,
|
|
2343
|
+
{
|
|
2344
|
+
"data-slot": "toast-title",
|
|
2345
|
+
className: cn(
|
|
2346
|
+
"inline-flex max-w-full items-center justify-center gap-[6px] text-center text-sm font-normal leading-normal",
|
|
2347
|
+
className
|
|
2348
|
+
),
|
|
2349
|
+
...props,
|
|
2350
|
+
children: [
|
|
2351
|
+
toastVisual?.busy ? /* @__PURE__ */ jsx26(
|
|
2352
|
+
Spinner,
|
|
2353
|
+
{
|
|
2354
|
+
className: "shrink-0 text-current",
|
|
2355
|
+
size: 16,
|
|
2356
|
+
strokeWidth: 2,
|
|
2357
|
+
trackColor: "color-mix(in srgb, currentColor 28%, transparent)"
|
|
2358
|
+
}
|
|
2359
|
+
) : StatusIcon ? /* @__PURE__ */ jsx26(StatusIcon, { className: "size-4 shrink-0 text-current" }) : null,
|
|
2360
|
+
/* @__PURE__ */ jsx26("span", { className: "min-w-0 break-words", children: formatToastText(children) })
|
|
2361
|
+
]
|
|
2362
|
+
}
|
|
2363
|
+
);
|
|
2364
|
+
}
|
|
2365
|
+
function ToastDescription({
|
|
2366
|
+
className,
|
|
2367
|
+
...props
|
|
2368
|
+
}) {
|
|
2369
|
+
return /* @__PURE__ */ jsx26(
|
|
2370
|
+
ToastPrimitive.Description,
|
|
2371
|
+
{
|
|
2372
|
+
"data-slot": "toast-description",
|
|
2373
|
+
className: cn(
|
|
2374
|
+
"box-border w-full px-2 text-xs font-normal leading-[1.3] text-current opacity-75 [overflow-wrap:anywhere]",
|
|
2375
|
+
className
|
|
2376
|
+
),
|
|
2377
|
+
...props
|
|
2378
|
+
}
|
|
2379
|
+
);
|
|
2380
|
+
}
|
|
2381
|
+
function ToastClose({
|
|
2382
|
+
className,
|
|
2383
|
+
...props
|
|
2384
|
+
}) {
|
|
2385
|
+
return /* @__PURE__ */ jsx26(
|
|
2386
|
+
ToastPrimitive.Close,
|
|
2387
|
+
{
|
|
2388
|
+
"data-slot": "toast-close",
|
|
2389
|
+
className: cn(
|
|
2390
|
+
"absolute right-1.5 top-1.5 inline-flex size-5 items-center justify-center rounded-[4px] text-current opacity-65 transition-[background-color,opacity] hover:bg-[color-mix(in_srgb,currentColor_10%,transparent)] hover:opacity-100 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[color-mix(in_srgb,currentColor_28%,transparent)]",
|
|
2391
|
+
className
|
|
2392
|
+
),
|
|
2393
|
+
...props,
|
|
2394
|
+
children: /* @__PURE__ */ jsx26(CloseIcon, { className: "size-4" })
|
|
2395
|
+
}
|
|
2396
|
+
);
|
|
2397
|
+
}
|
|
2398
|
+
function ToastViewport({
|
|
2399
|
+
className,
|
|
2400
|
+
style,
|
|
2401
|
+
...props
|
|
2402
|
+
}) {
|
|
2403
|
+
return /* @__PURE__ */ jsx26(
|
|
2404
|
+
ToastPrimitive.Viewport,
|
|
2405
|
+
{
|
|
2406
|
+
"data-slot": "toast-viewport",
|
|
2407
|
+
className: cn(
|
|
2408
|
+
"fixed left-1/2 top-3 flex max-h-screen w-auto -translate-x-1/2 flex-col items-center gap-2 p-0",
|
|
2409
|
+
className
|
|
2410
|
+
),
|
|
2411
|
+
style: { zIndex: "var(--z-toast)", ...style },
|
|
2412
|
+
...props
|
|
2413
|
+
}
|
|
2414
|
+
);
|
|
2415
|
+
}
|
|
2416
|
+
|
|
2417
|
+
// src/components/tooltip/tooltip.tsx
|
|
2418
|
+
import { Tooltip as TooltipPrimitive } from "radix-ui";
|
|
2419
|
+
import { jsx as jsx27 } from "react/jsx-runtime";
|
|
2420
|
+
function TooltipProvider({
|
|
2421
|
+
delayDuration = 0,
|
|
2422
|
+
...props
|
|
2423
|
+
}) {
|
|
2424
|
+
return /* @__PURE__ */ jsx27(
|
|
2425
|
+
TooltipPrimitive.Provider,
|
|
2426
|
+
{
|
|
2427
|
+
"data-slot": "tooltip-provider",
|
|
2428
|
+
delayDuration,
|
|
2429
|
+
...props
|
|
2430
|
+
}
|
|
2431
|
+
);
|
|
2432
|
+
}
|
|
2433
|
+
function Tooltip({
|
|
2434
|
+
...props
|
|
2435
|
+
}) {
|
|
2436
|
+
return /* @__PURE__ */ jsx27(TooltipPrimitive.Root, { "data-slot": "tooltip", ...props });
|
|
2437
|
+
}
|
|
2438
|
+
function TooltipTrigger({
|
|
2439
|
+
...props
|
|
2440
|
+
}) {
|
|
2441
|
+
return /* @__PURE__ */ jsx27(TooltipPrimitive.Trigger, { "data-slot": "tooltip-trigger", ...props });
|
|
2442
|
+
}
|
|
2443
|
+
function TooltipPortal({
|
|
2444
|
+
...props
|
|
2445
|
+
}) {
|
|
2446
|
+
return /* @__PURE__ */ jsx27(TooltipPrimitive.Portal, { "data-slot": "tooltip-portal", ...props });
|
|
2447
|
+
}
|
|
2448
|
+
function TooltipContent({
|
|
2449
|
+
className,
|
|
2450
|
+
sideOffset = 8,
|
|
2451
|
+
children,
|
|
2452
|
+
style,
|
|
2453
|
+
...props
|
|
2454
|
+
}) {
|
|
2455
|
+
return /* @__PURE__ */ jsx27(TooltipPortal, { children: /* @__PURE__ */ jsx27(
|
|
2456
|
+
TooltipPrimitive.Content,
|
|
2457
|
+
{
|
|
2458
|
+
"data-slot": "tooltip-content",
|
|
2459
|
+
sideOffset,
|
|
2460
|
+
className: cn(
|
|
2461
|
+
"inline-flex w-fit max-w-xs origin-(--radix-tooltip-content-transform-origin) items-center gap-2 rounded-md border border-[var(--border-1)] bg-[var(--background-fronted)] px-2 py-1 text-sm leading-[1.3] text-popover-foreground shadow-soft outline-none data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 data-[state=delayed-open]:animate-in data-[state=delayed-open]:fade-in-0 data-[state=delayed-open]:zoom-in-95 data-open:animate-in data-open:fade-in-0 data-open:zoom-in-95 data-closed:animate-out data-closed:fade-out-0 data-closed:zoom-out-95",
|
|
2462
|
+
className
|
|
2463
|
+
),
|
|
2464
|
+
style: { zIndex: "var(--z-tooltip, 100700)", ...style },
|
|
2465
|
+
...props,
|
|
2466
|
+
children
|
|
2467
|
+
}
|
|
2468
|
+
) });
|
|
2469
|
+
}
|
|
2470
|
+
|
|
2471
|
+
// src/components/underline-tabs/underline-tabs.tsx
|
|
2472
|
+
import { useEffect as useEffect3, useLayoutEffect as useLayoutEffect3, useRef as useRef3, useState as useState3 } from "react";
|
|
2473
|
+
import { jsx as jsx28, jsxs as jsxs11 } from "react/jsx-runtime";
|
|
2474
|
+
function UnderlineTabs({
|
|
2475
|
+
tabs,
|
|
2476
|
+
value,
|
|
2477
|
+
onValueChange,
|
|
2478
|
+
ariaLabel,
|
|
2479
|
+
className,
|
|
2480
|
+
testId,
|
|
2481
|
+
viewportTestId,
|
|
2482
|
+
scrollLeftLabel = "Scroll left",
|
|
2483
|
+
scrollRightLabel = "Scroll right",
|
|
2484
|
+
scrollLeftTestId,
|
|
2485
|
+
scrollRightTestId,
|
|
2486
|
+
preventMouseDownDefault = false
|
|
2487
|
+
}) {
|
|
2488
|
+
const viewportRef = useRef3(null);
|
|
2489
|
+
const rowRef = useRef3(null);
|
|
2490
|
+
const buttonRefs = useRef3({});
|
|
2491
|
+
const [indicatorStyle, setIndicatorStyle] = useState3({ left: 0, width: 0 });
|
|
2492
|
+
const [overflow, setOverflow] = useState3({
|
|
2493
|
+
canScrollLeft: false,
|
|
2494
|
+
canScrollRight: false
|
|
2495
|
+
});
|
|
2496
|
+
useLayoutEffect3(() => {
|
|
2497
|
+
const row = rowRef.current;
|
|
2498
|
+
const button = buttonRefs.current[value];
|
|
2499
|
+
if (!row || !button) {
|
|
2500
|
+
setIndicatorStyle(
|
|
2501
|
+
(current) => current.left === 0 && current.width === 0 ? current : { left: 0, width: 0 }
|
|
2502
|
+
);
|
|
2503
|
+
return;
|
|
2504
|
+
}
|
|
2505
|
+
const nextStyle = {
|
|
2506
|
+
left: button.offsetLeft,
|
|
2507
|
+
width: button.offsetWidth
|
|
2508
|
+
};
|
|
2509
|
+
setIndicatorStyle(
|
|
2510
|
+
(current) => current.left === nextStyle.left && current.width === nextStyle.width ? current : nextStyle
|
|
2511
|
+
);
|
|
2512
|
+
}, [tabs, value]);
|
|
2513
|
+
useEffect3(() => {
|
|
2514
|
+
const viewport = viewportRef.current;
|
|
2515
|
+
if (!viewport) {
|
|
2516
|
+
return;
|
|
2517
|
+
}
|
|
2518
|
+
const syncOverflow = () => {
|
|
2519
|
+
const maxScrollLeft = viewport.scrollWidth - viewport.clientWidth;
|
|
2520
|
+
setOverflow((current) => {
|
|
2521
|
+
const next = {
|
|
2522
|
+
canScrollLeft: viewport.scrollLeft > 1,
|
|
2523
|
+
canScrollRight: viewport.scrollLeft < maxScrollLeft - 1
|
|
2524
|
+
};
|
|
2525
|
+
return current.canScrollLeft === next.canScrollLeft && current.canScrollRight === next.canScrollRight ? current : next;
|
|
2526
|
+
});
|
|
2527
|
+
};
|
|
2528
|
+
syncOverflow();
|
|
2529
|
+
viewport.addEventListener("scroll", syncOverflow, { passive: true });
|
|
2530
|
+
let resizeObserver = null;
|
|
2531
|
+
if (typeof ResizeObserver !== "undefined") {
|
|
2532
|
+
resizeObserver = new ResizeObserver(syncOverflow);
|
|
2533
|
+
resizeObserver.observe(viewport);
|
|
2534
|
+
if (rowRef.current) {
|
|
2535
|
+
resizeObserver.observe(rowRef.current);
|
|
2536
|
+
}
|
|
2537
|
+
}
|
|
2538
|
+
window.addEventListener("resize", syncOverflow);
|
|
2539
|
+
return () => {
|
|
2540
|
+
viewport.removeEventListener("scroll", syncOverflow);
|
|
2541
|
+
window.removeEventListener("resize", syncOverflow);
|
|
2542
|
+
resizeObserver?.disconnect();
|
|
2543
|
+
};
|
|
2544
|
+
}, [tabs]);
|
|
2545
|
+
const scrollTabs = (direction) => {
|
|
2546
|
+
const viewport = viewportRef.current;
|
|
2547
|
+
if (!viewport) {
|
|
2548
|
+
return;
|
|
2549
|
+
}
|
|
2550
|
+
const delta = Math.max(120, viewport.clientWidth * 0.72);
|
|
2551
|
+
viewport.scrollBy({
|
|
2552
|
+
left: direction === "left" ? -delta : delta,
|
|
2553
|
+
behavior: "smooth"
|
|
2554
|
+
});
|
|
2555
|
+
};
|
|
2556
|
+
return /* @__PURE__ */ jsxs11(
|
|
2557
|
+
"div",
|
|
2558
|
+
{
|
|
2559
|
+
"aria-label": ariaLabel,
|
|
2560
|
+
className: cn(
|
|
2561
|
+
"group relative box-border h-[33px] min-w-0 border-b border-[var(--border-1)] px-4",
|
|
2562
|
+
className
|
|
2563
|
+
),
|
|
2564
|
+
"data-slot": "underline-tabs",
|
|
2565
|
+
"data-testid": testId,
|
|
2566
|
+
role: "tablist",
|
|
2567
|
+
children: [
|
|
2568
|
+
/* @__PURE__ */ jsx28(
|
|
2569
|
+
"div",
|
|
2570
|
+
{
|
|
2571
|
+
ref: viewportRef,
|
|
2572
|
+
className: cn(
|
|
2573
|
+
"h-8 overflow-x-auto overflow-y-hidden [scrollbar-gutter:stable] [scrollbar-width:none] [&::-webkit-scrollbar]:hidden",
|
|
2574
|
+
overflow.canScrollLeft && !overflow.canScrollRight && "[mask-image:linear-gradient(90deg,transparent_0,black_28px,black_100%)] [-webkit-mask-image:linear-gradient(90deg,transparent_0,black_28px,black_100%)]",
|
|
2575
|
+
!overflow.canScrollLeft && overflow.canScrollRight && "[mask-image:linear-gradient(90deg,black_0,black_calc(100%_-_28px),transparent_100%)] [-webkit-mask-image:linear-gradient(90deg,black_0,black_calc(100%_-_28px),transparent_100%)]",
|
|
2576
|
+
overflow.canScrollLeft && overflow.canScrollRight && "[mask-image:linear-gradient(90deg,transparent_0,black_28px,black_calc(100%_-_28px),transparent_100%)] [-webkit-mask-image:linear-gradient(90deg,transparent_0,black_28px,black_calc(100%_-_28px),transparent_100%)]"
|
|
2577
|
+
),
|
|
2578
|
+
"data-can-scroll-left": overflow.canScrollLeft ? "true" : "false",
|
|
2579
|
+
"data-can-scroll-right": overflow.canScrollRight ? "true" : "false",
|
|
2580
|
+
"data-slot": "underline-tabs-viewport",
|
|
2581
|
+
"data-testid": viewportTestId,
|
|
2582
|
+
children: /* @__PURE__ */ jsxs11(
|
|
2583
|
+
"div",
|
|
2584
|
+
{
|
|
2585
|
+
ref: rowRef,
|
|
2586
|
+
className: "relative flex h-8 w-max min-w-full items-center gap-[14px] pb-2",
|
|
2587
|
+
children: [
|
|
2588
|
+
tabs.map((tab) => {
|
|
2589
|
+
const isActive = value === tab.value;
|
|
2590
|
+
return /* @__PURE__ */ jsxs11(
|
|
2591
|
+
"button",
|
|
2592
|
+
{
|
|
2593
|
+
ref: (element) => {
|
|
2594
|
+
if (element) {
|
|
2595
|
+
buttonRefs.current[tab.value] = element;
|
|
2596
|
+
} else {
|
|
2597
|
+
delete buttonRefs.current[tab.value];
|
|
2598
|
+
}
|
|
2599
|
+
},
|
|
2600
|
+
"aria-selected": isActive,
|
|
2601
|
+
className: cn(
|
|
2602
|
+
"relative inline-flex h-6 shrink-0 items-center gap-1.5 whitespace-nowrap border-0 bg-transparent p-0 text-[13px] font-semibold leading-6 text-[var(--text-secondary)] transition-colors hover:text-[var(--text-primary)] focus-visible:outline-none",
|
|
2603
|
+
isActive && "text-[var(--accent)]"
|
|
2604
|
+
),
|
|
2605
|
+
"data-active": isActive ? "true" : "false",
|
|
2606
|
+
"data-slot": "underline-tabs-tab",
|
|
2607
|
+
"data-testid": tab.testId,
|
|
2608
|
+
role: "tab",
|
|
2609
|
+
type: "button",
|
|
2610
|
+
onClick: () => onValueChange(tab.value),
|
|
2611
|
+
onMouseDown: preventMouseDownDefault ? (event) => event.preventDefault() : void 0,
|
|
2612
|
+
children: [
|
|
2613
|
+
/* @__PURE__ */ jsx28("span", { children: tab.label }),
|
|
2614
|
+
tab.count !== void 0 ? /* @__PURE__ */ jsx28("span", { className: "text-xs font-semibold leading-6 text-[inherit]", children: tab.count }) : null
|
|
2615
|
+
]
|
|
2616
|
+
},
|
|
2617
|
+
tab.value
|
|
2618
|
+
);
|
|
2619
|
+
}),
|
|
2620
|
+
/* @__PURE__ */ jsx28(
|
|
2621
|
+
"div",
|
|
2622
|
+
{
|
|
2623
|
+
"aria-hidden": true,
|
|
2624
|
+
className: "absolute bottom-0 left-0 z-[1] h-0.5 rounded-[1px] bg-[var(--accent)] transition-[transform,width] duration-[220ms] ease-[cubic-bezier(0.4,0,0.2,1)] motion-reduce:transition-none",
|
|
2625
|
+
"data-slot": "underline-tabs-indicator",
|
|
2626
|
+
style: {
|
|
2627
|
+
transform: `translateX(${indicatorStyle.left}px)`,
|
|
2628
|
+
width: indicatorStyle.width
|
|
2629
|
+
}
|
|
2630
|
+
}
|
|
2631
|
+
)
|
|
2632
|
+
]
|
|
2633
|
+
}
|
|
2634
|
+
)
|
|
2635
|
+
}
|
|
2636
|
+
),
|
|
2637
|
+
/* @__PURE__ */ jsx28(
|
|
2638
|
+
"button",
|
|
2639
|
+
{
|
|
2640
|
+
"aria-label": scrollLeftLabel,
|
|
2641
|
+
className: "pointer-events-none absolute left-4 top-3 z-[3] inline-flex size-6 translate-y-[-50%] scale-[0.94] items-center justify-center rounded-full border-0 bg-[var(--background-fronted)] p-0 text-[var(--text-secondary)] opacity-0 shadow-[0_4px_16px_rgba(15,23,42,0.12)] transition-[opacity,transform,background-color,color] duration-[160ms] ease-in-out hover:bg-[var(--background-fronted)] hover:text-[var(--text-primary)] focus-visible:bg-[var(--background-fronted)] focus-visible:text-[var(--text-primary)] group-hover:data-[visible=true]:pointer-events-auto group-hover:data-[visible=true]:scale-100 group-hover:data-[visible=true]:opacity-100 group-focus-within:data-[visible=true]:pointer-events-auto group-focus-within:data-[visible=true]:scale-100 group-focus-within:data-[visible=true]:opacity-100 disabled:pointer-events-none",
|
|
2642
|
+
"data-slot": "underline-tabs-scroll-left",
|
|
2643
|
+
"data-testid": scrollLeftTestId,
|
|
2644
|
+
"data-visible": overflow.canScrollLeft ? "true" : "false",
|
|
2645
|
+
disabled: !overflow.canScrollLeft,
|
|
2646
|
+
type: "button",
|
|
2647
|
+
onClick: () => scrollTabs("left"),
|
|
2648
|
+
children: /* @__PURE__ */ jsx28(ArrowLeftIcon, { size: 16 })
|
|
2649
|
+
}
|
|
2650
|
+
),
|
|
2651
|
+
/* @__PURE__ */ jsx28(
|
|
2652
|
+
"button",
|
|
2653
|
+
{
|
|
2654
|
+
"aria-label": scrollRightLabel,
|
|
2655
|
+
className: "pointer-events-none absolute right-4 top-3 z-[3] inline-flex size-6 translate-y-[-50%] scale-[0.94] items-center justify-center rounded-full border-0 bg-[var(--background-fronted)] p-0 text-[var(--text-secondary)] opacity-0 shadow-[0_4px_16px_rgba(15,23,42,0.12)] transition-[opacity,transform,background-color,color] duration-[160ms] ease-in-out hover:bg-[var(--background-fronted)] hover:text-[var(--text-primary)] focus-visible:bg-[var(--background-fronted)] focus-visible:text-[var(--text-primary)] group-hover:data-[visible=true]:pointer-events-auto group-hover:data-[visible=true]:scale-100 group-hover:data-[visible=true]:opacity-100 group-focus-within:data-[visible=true]:pointer-events-auto group-focus-within:data-[visible=true]:scale-100 group-focus-within:data-[visible=true]:opacity-100 disabled:pointer-events-none",
|
|
2656
|
+
"data-slot": "underline-tabs-scroll-right",
|
|
2657
|
+
"data-testid": scrollRightTestId,
|
|
2658
|
+
"data-visible": overflow.canScrollRight ? "true" : "false",
|
|
2659
|
+
disabled: !overflow.canScrollRight,
|
|
2660
|
+
type: "button",
|
|
2661
|
+
onClick: () => scrollTabs("right"),
|
|
2662
|
+
children: /* @__PURE__ */ jsx28(ArrowRightIcon, { size: 16 })
|
|
2663
|
+
}
|
|
2664
|
+
)
|
|
2665
|
+
]
|
|
2666
|
+
}
|
|
2667
|
+
);
|
|
2668
|
+
}
|
|
2669
|
+
|
|
2670
|
+
// src/components/viewport-menu-surface/viewport-menu-surface.tsx
|
|
2671
|
+
import * as React6 from "react";
|
|
2672
|
+
import { createPortal as createPortal2 } from "react-dom";
|
|
2673
|
+
import { jsx as jsx29 } from "react/jsx-runtime";
|
|
2674
|
+
var VIEWPORT_MENU_PADDING = 12;
|
|
2675
|
+
var MENU_BOUNDARY_PADDING = 8;
|
|
2676
|
+
function clampMenuCoordinate(origin, size, viewportExtent, padding) {
|
|
2677
|
+
return Math.max(
|
|
2678
|
+
padding,
|
|
2679
|
+
Math.min(origin, Math.max(padding, viewportExtent - padding - size))
|
|
2680
|
+
);
|
|
2681
|
+
}
|
|
2682
|
+
function resolveAlignedCoordinate(options) {
|
|
2683
|
+
const { origin, size, viewportExtent, padding, alignment } = options;
|
|
2684
|
+
const startCoordinate = origin;
|
|
2685
|
+
const endCoordinate = origin - size;
|
|
2686
|
+
if (alignment === "start") {
|
|
2687
|
+
return clampMenuCoordinate(startCoordinate, size, viewportExtent, padding);
|
|
2688
|
+
}
|
|
2689
|
+
if (alignment === "end") {
|
|
2690
|
+
return clampMenuCoordinate(endCoordinate, size, viewportExtent, padding);
|
|
2691
|
+
}
|
|
2692
|
+
const startFits = startCoordinate + size <= viewportExtent - padding;
|
|
2693
|
+
const endFits = endCoordinate >= padding;
|
|
2694
|
+
if (startFits || !endFits) {
|
|
2695
|
+
return clampMenuCoordinate(startCoordinate, size, viewportExtent, padding);
|
|
2696
|
+
}
|
|
2697
|
+
return clampMenuCoordinate(endCoordinate, size, viewportExtent, padding);
|
|
2698
|
+
}
|
|
2699
|
+
function placeViewportMenuAtPoint(options) {
|
|
2700
|
+
const padding = options.padding ?? VIEWPORT_MENU_PADDING;
|
|
2701
|
+
return {
|
|
2702
|
+
left: resolveAlignedCoordinate({
|
|
2703
|
+
origin: options.point.x,
|
|
2704
|
+
size: options.menuSize.width,
|
|
2705
|
+
viewportExtent: options.viewport.width,
|
|
2706
|
+
padding,
|
|
2707
|
+
alignment: options.alignX ?? "start"
|
|
2708
|
+
}),
|
|
2709
|
+
top: resolveAlignedCoordinate({
|
|
2710
|
+
origin: options.point.y,
|
|
2711
|
+
size: options.menuSize.height,
|
|
2712
|
+
viewportExtent: options.viewport.height,
|
|
2713
|
+
padding,
|
|
2714
|
+
alignment: options.alignY ?? "start"
|
|
2715
|
+
})
|
|
2716
|
+
};
|
|
2717
|
+
}
|
|
2718
|
+
function viewportBoundary() {
|
|
2719
|
+
return {
|
|
2720
|
+
left: 0,
|
|
2721
|
+
top: 0,
|
|
2722
|
+
width: typeof window === "undefined" ? 1280 : window.innerWidth,
|
|
2723
|
+
height: typeof window === "undefined" ? 720 : window.innerHeight
|
|
2724
|
+
};
|
|
2725
|
+
}
|
|
2726
|
+
function rectToBoundary(rect) {
|
|
2727
|
+
return {
|
|
2728
|
+
left: rect.left,
|
|
2729
|
+
top: rect.top,
|
|
2730
|
+
width: rect.width,
|
|
2731
|
+
height: rect.height
|
|
2732
|
+
};
|
|
2733
|
+
}
|
|
2734
|
+
function resolveMenuBoundaryFromPoint(point) {
|
|
2735
|
+
if (typeof document === "undefined" || !document.elementsFromPoint) {
|
|
2736
|
+
return {
|
|
2737
|
+
element: null,
|
|
2738
|
+
rect: viewportBoundary()
|
|
2739
|
+
};
|
|
2740
|
+
}
|
|
2741
|
+
const selector = '[data-slot="viewport-menu-boundary"]';
|
|
2742
|
+
for (const element of document.elementsFromPoint(point.x, point.y)) {
|
|
2743
|
+
const boundaryElement = element.closest(selector);
|
|
2744
|
+
if (boundaryElement) {
|
|
2745
|
+
return {
|
|
2746
|
+
element: boundaryElement,
|
|
2747
|
+
rect: rectToBoundary(boundaryElement.getBoundingClientRect())
|
|
2748
|
+
};
|
|
2749
|
+
}
|
|
2750
|
+
}
|
|
2751
|
+
return {
|
|
2752
|
+
element: null,
|
|
2753
|
+
rect: viewportBoundary()
|
|
2754
|
+
};
|
|
2755
|
+
}
|
|
2756
|
+
function clampMenuPositionToBoundary(options) {
|
|
2757
|
+
const padding = options.padding ?? MENU_BOUNDARY_PADDING;
|
|
2758
|
+
const minLeft = options.boundary.left + padding;
|
|
2759
|
+
const minTop = options.boundary.top + padding;
|
|
2760
|
+
const maxLeft = Math.max(
|
|
2761
|
+
minLeft,
|
|
2762
|
+
options.boundary.left + options.boundary.width - padding - options.width
|
|
2763
|
+
);
|
|
2764
|
+
const maxTop = Math.max(
|
|
2765
|
+
minTop,
|
|
2766
|
+
options.boundary.top + options.boundary.height - padding - options.height
|
|
2767
|
+
);
|
|
2768
|
+
return {
|
|
2769
|
+
left: Math.max(minLeft, Math.min(options.left, maxLeft)),
|
|
2770
|
+
top: Math.max(minTop, Math.min(options.top, maxTop))
|
|
2771
|
+
};
|
|
2772
|
+
}
|
|
2773
|
+
function assignRef(ref, value) {
|
|
2774
|
+
if (typeof ref === "function") {
|
|
2775
|
+
ref(value);
|
|
2776
|
+
return;
|
|
2777
|
+
}
|
|
2778
|
+
if (ref) {
|
|
2779
|
+
ref.current = value;
|
|
2780
|
+
}
|
|
2781
|
+
}
|
|
2782
|
+
function callHandler(handler, event) {
|
|
2783
|
+
handler?.(event);
|
|
2784
|
+
}
|
|
2785
|
+
var ViewportMenuSurface = React6.forwardRef(function ViewportMenuSurface2({
|
|
2786
|
+
open,
|
|
2787
|
+
placement,
|
|
2788
|
+
children,
|
|
2789
|
+
onDismiss,
|
|
2790
|
+
dismissOnPointerDownOutside = false,
|
|
2791
|
+
dismissOnEscape = false,
|
|
2792
|
+
dismissOnScroll = false,
|
|
2793
|
+
dismissIgnoreRefs = [],
|
|
2794
|
+
stopEventPropagation = true,
|
|
2795
|
+
style,
|
|
2796
|
+
onMouseDown,
|
|
2797
|
+
onClick,
|
|
2798
|
+
className,
|
|
2799
|
+
...rest
|
|
2800
|
+
}, forwardedRef) {
|
|
2801
|
+
const surfaceRef = React6.useRef(null);
|
|
2802
|
+
const [measuredSize, setMeasuredSize] = React6.useState(null);
|
|
2803
|
+
const setRefs = React6.useCallback(
|
|
2804
|
+
(node) => {
|
|
2805
|
+
surfaceRef.current = node;
|
|
2806
|
+
assignRef(forwardedRef, node);
|
|
2807
|
+
},
|
|
2808
|
+
[forwardedRef]
|
|
2809
|
+
);
|
|
2810
|
+
React6.useLayoutEffect(() => {
|
|
2811
|
+
if (!open) {
|
|
2812
|
+
setMeasuredSize(null);
|
|
2813
|
+
return;
|
|
2814
|
+
}
|
|
2815
|
+
const element = surfaceRef.current;
|
|
2816
|
+
if (!element) {
|
|
2817
|
+
setMeasuredSize(null);
|
|
2818
|
+
return;
|
|
2819
|
+
}
|
|
2820
|
+
const updateMeasuredSize = () => {
|
|
2821
|
+
const rect = element.getBoundingClientRect();
|
|
2822
|
+
setMeasuredSize(
|
|
2823
|
+
(previous) => previous && Math.abs(previous.width - rect.width) < 0.5 && Math.abs(previous.height - rect.height) < 0.5 ? previous : { width: rect.width, height: rect.height }
|
|
2824
|
+
);
|
|
2825
|
+
};
|
|
2826
|
+
updateMeasuredSize();
|
|
2827
|
+
if (typeof ResizeObserver === "undefined") {
|
|
2828
|
+
return;
|
|
2829
|
+
}
|
|
2830
|
+
const observer = new ResizeObserver(updateMeasuredSize);
|
|
2831
|
+
observer.observe(element);
|
|
2832
|
+
return () => observer.disconnect();
|
|
2833
|
+
}, [open, placement]);
|
|
2834
|
+
React6.useEffect(() => {
|
|
2835
|
+
if (!open) {
|
|
2836
|
+
return;
|
|
2837
|
+
}
|
|
2838
|
+
if (!onDismiss || !dismissOnPointerDownOutside && !dismissOnEscape && !dismissOnScroll) {
|
|
2839
|
+
return;
|
|
2840
|
+
}
|
|
2841
|
+
const shouldIgnoreTarget = (target) => {
|
|
2842
|
+
if (!(target instanceof Node)) {
|
|
2843
|
+
return false;
|
|
2844
|
+
}
|
|
2845
|
+
if (surfaceRef.current?.contains(target)) {
|
|
2846
|
+
return true;
|
|
2847
|
+
}
|
|
2848
|
+
return dismissIgnoreRefs.some(
|
|
2849
|
+
(ref) => ref.current?.contains(target) ?? false
|
|
2850
|
+
);
|
|
2851
|
+
};
|
|
2852
|
+
const handlePointerDown = (event) => {
|
|
2853
|
+
if (!dismissOnPointerDownOutside) {
|
|
2854
|
+
return;
|
|
2855
|
+
}
|
|
2856
|
+
if (shouldIgnoreTarget(event.target)) {
|
|
2857
|
+
return;
|
|
2858
|
+
}
|
|
2859
|
+
onDismiss();
|
|
2860
|
+
};
|
|
2861
|
+
const handleKeyDown = (event) => {
|
|
2862
|
+
if (!dismissOnEscape || event.key !== "Escape") {
|
|
2863
|
+
return;
|
|
2864
|
+
}
|
|
2865
|
+
onDismiss();
|
|
2866
|
+
};
|
|
2867
|
+
const handleScroll = () => {
|
|
2868
|
+
if (dismissOnScroll) {
|
|
2869
|
+
onDismiss();
|
|
2870
|
+
}
|
|
2871
|
+
};
|
|
2872
|
+
document.addEventListener("pointerdown", handlePointerDown, true);
|
|
2873
|
+
window.addEventListener("keydown", handleKeyDown, true);
|
|
2874
|
+
window.addEventListener("scroll", handleScroll, {
|
|
2875
|
+
capture: true,
|
|
2876
|
+
passive: true
|
|
2877
|
+
});
|
|
2878
|
+
return () => {
|
|
2879
|
+
document.removeEventListener("pointerdown", handlePointerDown, true);
|
|
2880
|
+
window.removeEventListener("keydown", handleKeyDown, true);
|
|
2881
|
+
window.removeEventListener("scroll", handleScroll, true);
|
|
2882
|
+
};
|
|
2883
|
+
}, [
|
|
2884
|
+
dismissIgnoreRefs,
|
|
2885
|
+
dismissOnEscape,
|
|
2886
|
+
dismissOnPointerDownOutside,
|
|
2887
|
+
dismissOnScroll,
|
|
2888
|
+
onDismiss,
|
|
2889
|
+
open
|
|
2890
|
+
]);
|
|
2891
|
+
const resolvedPlacement = React6.useMemo(() => {
|
|
2892
|
+
if (placement.type === "absolute") {
|
|
2893
|
+
const boundary2 = resolveMenuBoundaryFromPoint({
|
|
2894
|
+
x: placement.left,
|
|
2895
|
+
y: placement.top
|
|
2896
|
+
});
|
|
2897
|
+
const menuSize2 = measuredSize ?? { width: 0, height: 0 };
|
|
2898
|
+
return {
|
|
2899
|
+
portalTarget: boundary2.element,
|
|
2900
|
+
position: clampMenuPositionToBoundary({
|
|
2901
|
+
left: placement.left,
|
|
2902
|
+
top: placement.top,
|
|
2903
|
+
width: menuSize2.width,
|
|
2904
|
+
height: menuSize2.height,
|
|
2905
|
+
boundary: boundary2.rect
|
|
2906
|
+
})
|
|
2907
|
+
};
|
|
2908
|
+
}
|
|
2909
|
+
const boundary = resolveMenuBoundaryFromPoint(placement.point);
|
|
2910
|
+
const menuSize = measuredSize ?? placement.estimatedSize ?? { width: 0, height: 0 };
|
|
2911
|
+
const relativePoint = {
|
|
2912
|
+
x: placement.point.x - boundary.rect.left,
|
|
2913
|
+
y: placement.point.y - boundary.rect.top
|
|
2914
|
+
};
|
|
2915
|
+
const relativePosition = placeViewportMenuAtPoint({
|
|
2916
|
+
point: relativePoint,
|
|
2917
|
+
menuSize,
|
|
2918
|
+
viewport: { width: boundary.rect.width, height: boundary.rect.height },
|
|
2919
|
+
padding: placement.padding,
|
|
2920
|
+
alignX: placement.alignX,
|
|
2921
|
+
alignY: placement.alignY
|
|
2922
|
+
});
|
|
2923
|
+
return {
|
|
2924
|
+
portalTarget: boundary.element,
|
|
2925
|
+
position: {
|
|
2926
|
+
left: boundary.rect.left + relativePosition.left,
|
|
2927
|
+
top: boundary.rect.top + relativePosition.top
|
|
2928
|
+
}
|
|
2929
|
+
};
|
|
2930
|
+
}, [measuredSize, placement]);
|
|
2931
|
+
if (!open || typeof document === "undefined" || !document.body) {
|
|
2932
|
+
return null;
|
|
2933
|
+
}
|
|
2934
|
+
const portalTarget = resolvedPlacement.portalTarget ?? document.body;
|
|
2935
|
+
return createPortal2(
|
|
2936
|
+
/* @__PURE__ */ jsx29(
|
|
2937
|
+
MenuSurface,
|
|
2938
|
+
{
|
|
2939
|
+
...rest,
|
|
2940
|
+
ref: setRefs,
|
|
2941
|
+
className,
|
|
2942
|
+
"data-slot": "viewport-menu-surface",
|
|
2943
|
+
style: {
|
|
2944
|
+
...style,
|
|
2945
|
+
position: "fixed",
|
|
2946
|
+
top: resolvedPlacement.position.top,
|
|
2947
|
+
left: resolvedPlacement.position.left,
|
|
2948
|
+
zIndex: "var(--z-popover)"
|
|
2949
|
+
},
|
|
2950
|
+
onClick: (event) => {
|
|
2951
|
+
if (stopEventPropagation) {
|
|
2952
|
+
event.stopPropagation();
|
|
2953
|
+
}
|
|
2954
|
+
callHandler(onClick, event);
|
|
2955
|
+
},
|
|
2956
|
+
onMouseDown: (event) => {
|
|
2957
|
+
if (stopEventPropagation) {
|
|
2958
|
+
event.stopPropagation();
|
|
2959
|
+
}
|
|
2960
|
+
callHandler(onMouseDown, event);
|
|
2961
|
+
},
|
|
2962
|
+
children
|
|
2963
|
+
}
|
|
2964
|
+
),
|
|
2965
|
+
portalTarget
|
|
2966
|
+
);
|
|
2967
|
+
});
|
|
2968
|
+
|
|
2969
|
+
export {
|
|
2970
|
+
badgeVariants,
|
|
2971
|
+
Badge,
|
|
2972
|
+
BareIconButton,
|
|
2973
|
+
buttonVariants,
|
|
2974
|
+
Button,
|
|
2975
|
+
Card,
|
|
2976
|
+
CardHeader,
|
|
2977
|
+
CardTitle,
|
|
2978
|
+
CardDescription,
|
|
2979
|
+
CardAction,
|
|
2980
|
+
CardContent,
|
|
2981
|
+
CardFooter,
|
|
2982
|
+
Checkbox,
|
|
2983
|
+
Dialog,
|
|
2984
|
+
DialogTrigger,
|
|
2985
|
+
DialogPortal,
|
|
2986
|
+
DialogClose,
|
|
2987
|
+
DialogOverlay,
|
|
2988
|
+
DialogContent,
|
|
2989
|
+
DialogHeader,
|
|
2990
|
+
DialogFooter,
|
|
2991
|
+
DialogTitle,
|
|
2992
|
+
DialogDescription,
|
|
2993
|
+
ConfirmationDialog,
|
|
2994
|
+
DatePicker,
|
|
2995
|
+
Drawer,
|
|
2996
|
+
DrawerTrigger,
|
|
2997
|
+
DrawerPortal,
|
|
2998
|
+
DrawerClose,
|
|
2999
|
+
DrawerOverlay,
|
|
3000
|
+
DrawerContent,
|
|
3001
|
+
DrawerHeader,
|
|
3002
|
+
DrawerFooter,
|
|
3003
|
+
DrawerTitle,
|
|
3004
|
+
DrawerDescription,
|
|
3005
|
+
menuSurfaceClassName,
|
|
3006
|
+
menuItemClassName,
|
|
3007
|
+
menuItemWithIndicatorClassName,
|
|
3008
|
+
menuItemIndicatorClassName,
|
|
3009
|
+
MenuSurface,
|
|
3010
|
+
DropdownMenu,
|
|
3011
|
+
DropdownMenuPortal,
|
|
3012
|
+
DropdownMenuTrigger,
|
|
3013
|
+
DropdownMenuContent,
|
|
3014
|
+
DropdownMenuGroup,
|
|
3015
|
+
DropdownMenuItem,
|
|
3016
|
+
DropdownMenuCheckboxItem,
|
|
3017
|
+
DropdownMenuRadioGroup,
|
|
3018
|
+
DropdownMenuRadioItem,
|
|
3019
|
+
DropdownMenuLabel,
|
|
3020
|
+
DropdownMenuSeparator,
|
|
3021
|
+
DropdownMenuShortcut,
|
|
3022
|
+
DropdownMenuSub,
|
|
3023
|
+
DropdownMenuSubTrigger,
|
|
3024
|
+
DropdownMenuSubContent,
|
|
3025
|
+
Input,
|
|
3026
|
+
MentionPill,
|
|
3027
|
+
Popover,
|
|
3028
|
+
PopoverTrigger,
|
|
3029
|
+
PopoverPortal,
|
|
3030
|
+
PopoverClose,
|
|
3031
|
+
PopoverContent,
|
|
3032
|
+
PopoverAnchor,
|
|
3033
|
+
ResizablePanelGroup,
|
|
3034
|
+
ResizablePanel,
|
|
3035
|
+
ResizableHandle,
|
|
3036
|
+
ScrollArea,
|
|
3037
|
+
ScrollBar,
|
|
3038
|
+
Select,
|
|
3039
|
+
SelectGroup,
|
|
3040
|
+
SelectValue,
|
|
3041
|
+
SelectTrigger,
|
|
3042
|
+
SelectContent,
|
|
3043
|
+
SelectLabel,
|
|
3044
|
+
SelectSplitLayout,
|
|
3045
|
+
SelectSplitColumn,
|
|
3046
|
+
SelectSplitColumnLabel,
|
|
3047
|
+
SelectSplitColumnItems,
|
|
3048
|
+
SelectSplitDivider,
|
|
3049
|
+
SelectItem,
|
|
3050
|
+
SelectSeparator,
|
|
3051
|
+
SelectScrollUpButton,
|
|
3052
|
+
SelectScrollDownButton,
|
|
3053
|
+
Separator2 as Separator,
|
|
3054
|
+
SectionTabs,
|
|
3055
|
+
ShortcutBadge,
|
|
3056
|
+
toast,
|
|
3057
|
+
Toaster,
|
|
3058
|
+
Spinner,
|
|
3059
|
+
statusDotVariants,
|
|
3060
|
+
StatusDot,
|
|
3061
|
+
Switch,
|
|
3062
|
+
Textarea,
|
|
3063
|
+
ToastProvider,
|
|
3064
|
+
toastVariants,
|
|
3065
|
+
ToastRoot,
|
|
3066
|
+
ToastTitle,
|
|
3067
|
+
ToastDescription,
|
|
3068
|
+
ToastClose,
|
|
3069
|
+
ToastViewport,
|
|
3070
|
+
TooltipProvider,
|
|
3071
|
+
Tooltip,
|
|
3072
|
+
TooltipTrigger,
|
|
3073
|
+
TooltipPortal,
|
|
3074
|
+
TooltipContent,
|
|
3075
|
+
UnderlineTabs,
|
|
3076
|
+
ViewportMenuSurface
|
|
3077
|
+
};
|
|
3078
|
+
//# sourceMappingURL=chunk-2AUYRRDG.js.map
|