@microlight/core 0.10.0 → 0.11.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/dist/scripts/prepareServer.js +26 -1
- package/dist/server/app/layout.js +2 -18
- package/dist/server/app/library/[[...f_path]]/ViewFolder.js +37 -66
- package/dist/server/app/monitoring/MonitoringDashboard.js +167 -215
- package/dist/server/app/tasks/[slug]/ViewTask.js +81 -173
- package/dist/server/app/tasks/[slug]/runs/[r_id]/ViewRun.js +68 -164
- package/dist/server/app/tasks/[slug]/runs/[r_id]/_components/DropdownActions/DropdownActions.js +19 -25
- package/dist/server/components/Link.js +6 -15
- package/dist/server/components/MLInput.js +19 -22
- package/dist/server/components/Navbar/Navbar.js +14 -51
- package/dist/server/components/Navbar/NavbarContainer.js +7 -20
- package/dist/server/components/PageHeader.js +22 -54
- package/dist/server/components/StatusChip.js +5 -5
- package/dist/server/components/ui/alert.js +61 -0
- package/dist/server/components/ui/badge.js +37 -0
- package/dist/server/components/ui/breadcrumb.js +82 -0
- package/dist/server/components/ui/button.js +65 -0
- package/dist/server/components/ui/card.js +81 -0
- package/dist/server/components/ui/dropdown-menu.js +222 -0
- package/dist/server/components/ui/input.js +21 -0
- package/dist/server/components/ui/label.js +20 -0
- package/dist/server/components/ui/select.js +165 -0
- package/dist/server/components/ui/stack.js +104 -0
- package/dist/server/components/ui/table.js +77 -0
- package/dist/server/components/ui/tabs.js +59 -0
- package/dist/server/components/ui/typography.js +229 -0
- package/dist/server/utils/css/cn.js +11 -0
- package/package.json +15 -3
- package/dist/server/components/Icon.js +0 -22
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
// @ts-check
|
|
2
|
+
import * as React from "react";
|
|
3
|
+
import { cn } from "../../utils/css/cn";
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* @param {{ className?: string } & React.HTMLAttributes<HTMLDivElement>} props
|
|
7
|
+
* @returns {React.JSX.Element}
|
|
8
|
+
*/
|
|
9
|
+
function Card({
|
|
10
|
+
className,
|
|
11
|
+
...props
|
|
12
|
+
}) {
|
|
13
|
+
return <div data-slot="card" className={cn("bg-card text-card-foreground flex flex-col gap-4 rounded-md border py-4 px-3 shadow-sm", className)} {...props} />;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* @param {{ className?: string } & React.HTMLAttributes<HTMLDivElement>} props
|
|
18
|
+
* @returns {React.JSX.Element}
|
|
19
|
+
*/
|
|
20
|
+
function CardHeader({
|
|
21
|
+
className,
|
|
22
|
+
...props
|
|
23
|
+
}) {
|
|
24
|
+
return <div data-slot="card-header" className={cn("@container/card-header grid auto-rows-min grid-rows-[auto_auto] items-start gap-1.5 px-4 has-data-[slot=card-action]:grid-cols-[1fr_auto] [.border-b]:pb-4", className)} {...props} />;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* @param {{ className?: string } & React.HTMLAttributes<HTMLDivElement>} props
|
|
29
|
+
* @returns {React.JSX.Element}
|
|
30
|
+
*/
|
|
31
|
+
function CardTitle({
|
|
32
|
+
className,
|
|
33
|
+
...props
|
|
34
|
+
}) {
|
|
35
|
+
return <div data-slot="card-title" className={cn("leading-none font-semibold", className)} {...props} />;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* @param {{ className?: string } & React.HTMLAttributes<HTMLDivElement>} props
|
|
40
|
+
* @returns {React.JSX.Element}
|
|
41
|
+
*/
|
|
42
|
+
function CardDescription({
|
|
43
|
+
className,
|
|
44
|
+
...props
|
|
45
|
+
}) {
|
|
46
|
+
return <div data-slot="card-description" className={cn("text-muted-foreground text-sm", className)} {...props} />;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* @param {{ className?: string } & React.HTMLAttributes<HTMLDivElement>} props
|
|
51
|
+
* @returns {React.JSX.Element}
|
|
52
|
+
*/
|
|
53
|
+
function CardAction({
|
|
54
|
+
className,
|
|
55
|
+
...props
|
|
56
|
+
}) {
|
|
57
|
+
return <div data-slot="card-action" className={cn("col-start-2 row-span-2 row-start-1 self-start justify-self-end", className)} {...props} />;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* @param {{ className?: string } & React.HTMLAttributes<HTMLDivElement>} props
|
|
62
|
+
* @returns {React.JSX.Element}
|
|
63
|
+
*/
|
|
64
|
+
function CardContent({
|
|
65
|
+
className,
|
|
66
|
+
...props
|
|
67
|
+
}) {
|
|
68
|
+
return <div data-slot="card-content" className={cn("px-4", className)} {...props} />;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* @param {{ className?: string } & React.HTMLAttributes<HTMLDivElement>} props
|
|
73
|
+
* @returns {React.JSX.Element}
|
|
74
|
+
*/
|
|
75
|
+
function CardFooter({
|
|
76
|
+
className,
|
|
77
|
+
...props
|
|
78
|
+
}) {
|
|
79
|
+
return <div data-slot="card-footer" className={cn("flex items-center px-4 [.border-t]:pt-4", className)} {...props} />;
|
|
80
|
+
}
|
|
81
|
+
export { Card, CardHeader, CardFooter, CardTitle, CardAction, CardDescription, CardContent };
|
|
@@ -0,0 +1,222 @@
|
|
|
1
|
+
// @ts-check
|
|
2
|
+
"use client";
|
|
3
|
+
|
|
4
|
+
import * as React from "react";
|
|
5
|
+
import * as DropdownMenuPrimitive from "@radix-ui/react-dropdown-menu";
|
|
6
|
+
import { CheckIcon, ChevronRightIcon, CircleIcon } from "lucide-react";
|
|
7
|
+
import { cn } from "../../utils/css/cn";
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* @param {React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Root>} props
|
|
11
|
+
* @returns {React.JSX.Element}
|
|
12
|
+
*/
|
|
13
|
+
function DropdownMenu({
|
|
14
|
+
...props
|
|
15
|
+
}) {
|
|
16
|
+
return <DropdownMenuPrimitive.Root data-slot="dropdown-menu" {...props} />;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* @param {React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Portal>} props
|
|
21
|
+
* @returns {React.JSX.Element}
|
|
22
|
+
*/
|
|
23
|
+
function DropdownMenuPortal({
|
|
24
|
+
...props
|
|
25
|
+
}) {
|
|
26
|
+
return <DropdownMenuPrimitive.Portal data-slot="dropdown-menu-portal" {...props} />;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* @param {React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Trigger>} props
|
|
31
|
+
* @returns {React.JSX.Element}
|
|
32
|
+
*/
|
|
33
|
+
function DropdownMenuTrigger({
|
|
34
|
+
...props
|
|
35
|
+
}) {
|
|
36
|
+
return <DropdownMenuPrimitive.Trigger data-slot="dropdown-menu-trigger" {...props} />;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* @param {{
|
|
41
|
+
* className?: string,
|
|
42
|
+
* sideOffset?: number
|
|
43
|
+
* } & React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Content>} props
|
|
44
|
+
* @returns {React.JSX.Element}
|
|
45
|
+
*/
|
|
46
|
+
function DropdownMenuContent({
|
|
47
|
+
className,
|
|
48
|
+
sideOffset = 4,
|
|
49
|
+
...props
|
|
50
|
+
}) {
|
|
51
|
+
return <DropdownMenuPrimitive.Portal>
|
|
52
|
+
<DropdownMenuPrimitive.Content data-slot="dropdown-menu-content" sideOffset={sideOffset} className={cn("bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 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 z-50 max-h-(--radix-dropdown-menu-content-available-height) min-w-[8rem] origin-(--radix-dropdown-menu-content-transform-origin) overflow-x-hidden overflow-y-auto rounded-md border p-1 shadow-md", className)} {...props} />
|
|
53
|
+
</DropdownMenuPrimitive.Portal>;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* @param {React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Group>} props
|
|
58
|
+
* @returns {React.JSX.Element}
|
|
59
|
+
*/
|
|
60
|
+
function DropdownMenuGroup({
|
|
61
|
+
...props
|
|
62
|
+
}) {
|
|
63
|
+
return <DropdownMenuPrimitive.Group data-slot="dropdown-menu-group" {...props} />;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* @param {{
|
|
68
|
+
* className?: string,
|
|
69
|
+
* inset?: boolean,
|
|
70
|
+
* variant?: 'default' | 'destructive'
|
|
71
|
+
* } & React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Item>} props
|
|
72
|
+
* @returns {React.JSX.Element}
|
|
73
|
+
*/
|
|
74
|
+
function DropdownMenuItem({
|
|
75
|
+
className,
|
|
76
|
+
inset,
|
|
77
|
+
variant = "default",
|
|
78
|
+
...props
|
|
79
|
+
}) {
|
|
80
|
+
return <DropdownMenuPrimitive.Item data-slot="dropdown-menu-item" data-inset={inset} data-variant={variant} className={cn("focus:bg-accent focus:text-accent-foreground data-[variant=destructive]:text-destructive data-[variant=destructive]:focus:bg-destructive/10 dark:data-[variant=destructive]:focus:bg-destructive/20 data-[variant=destructive]:focus:text-destructive data-[variant=destructive]:*:[svg]:!text-destructive [&_svg:not([class*='text-'])]:text-muted-foreground relative flex cursor-default items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 data-[inset]:pl-8 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4", className)} {...props} />;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* @param {{
|
|
85
|
+
* className?: string,
|
|
86
|
+
* children?: React.ReactNode,
|
|
87
|
+
* checked?: boolean
|
|
88
|
+
* } & React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.CheckboxItem>} props
|
|
89
|
+
* @returns {React.JSX.Element}
|
|
90
|
+
*/
|
|
91
|
+
function DropdownMenuCheckboxItem({
|
|
92
|
+
className,
|
|
93
|
+
children,
|
|
94
|
+
checked,
|
|
95
|
+
...props
|
|
96
|
+
}) {
|
|
97
|
+
return <DropdownMenuPrimitive.CheckboxItem data-slot="dropdown-menu-checkbox-item" className={cn("focus:bg-accent focus:text-accent-foreground relative flex cursor-default items-center gap-2 rounded-sm py-1.5 pr-2 pl-8 text-sm outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4", className)} checked={checked} {...props}>
|
|
98
|
+
<span className="pointer-events-none absolute left-2 flex size-3.5 items-center justify-center">
|
|
99
|
+
<DropdownMenuPrimitive.ItemIndicator>
|
|
100
|
+
<CheckIcon className="size-4" />
|
|
101
|
+
</DropdownMenuPrimitive.ItemIndicator>
|
|
102
|
+
</span>
|
|
103
|
+
{children}
|
|
104
|
+
</DropdownMenuPrimitive.CheckboxItem>;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* @param {React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.RadioGroup>} props
|
|
109
|
+
* @returns {React.JSX.Element}
|
|
110
|
+
*/
|
|
111
|
+
function DropdownMenuRadioGroup({
|
|
112
|
+
...props
|
|
113
|
+
}) {
|
|
114
|
+
return <DropdownMenuPrimitive.RadioGroup data-slot="dropdown-menu-radio-group" {...props} />;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
/**
|
|
118
|
+
* @param {{
|
|
119
|
+
* className?: string,
|
|
120
|
+
* children?: React.ReactNode
|
|
121
|
+
* } & React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.RadioItem>} props
|
|
122
|
+
* @returns {React.JSX.Element}
|
|
123
|
+
*/
|
|
124
|
+
function DropdownMenuRadioItem({
|
|
125
|
+
className,
|
|
126
|
+
children,
|
|
127
|
+
...props
|
|
128
|
+
}) {
|
|
129
|
+
return <DropdownMenuPrimitive.RadioItem data-slot="dropdown-menu-radio-item" className={cn("focus:bg-accent focus:text-accent-foreground relative flex cursor-default items-center gap-2 rounded-sm py-1.5 pr-2 pl-8 text-sm outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4", className)} {...props}>
|
|
130
|
+
<span className="pointer-events-none absolute left-2 flex size-3.5 items-center justify-center">
|
|
131
|
+
<DropdownMenuPrimitive.ItemIndicator>
|
|
132
|
+
<CircleIcon className="size-2 fill-current" />
|
|
133
|
+
</DropdownMenuPrimitive.ItemIndicator>
|
|
134
|
+
</span>
|
|
135
|
+
{children}
|
|
136
|
+
</DropdownMenuPrimitive.RadioItem>;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
/**
|
|
140
|
+
* @param {{
|
|
141
|
+
* className?: string,
|
|
142
|
+
* inset?: boolean
|
|
143
|
+
* } & React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Label>} props
|
|
144
|
+
* @returns {React.JSX.Element}
|
|
145
|
+
*/
|
|
146
|
+
function DropdownMenuLabel({
|
|
147
|
+
className,
|
|
148
|
+
inset,
|
|
149
|
+
...props
|
|
150
|
+
}) {
|
|
151
|
+
return <DropdownMenuPrimitive.Label data-slot="dropdown-menu-label" data-inset={inset} className={cn("px-2 py-1.5 text-sm font-medium data-[inset]:pl-8", className)} {...props} />;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
/**
|
|
155
|
+
* @param {{
|
|
156
|
+
* className?: string
|
|
157
|
+
* } & React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Separator>} props
|
|
158
|
+
* @returns {React.JSX.Element}
|
|
159
|
+
*/
|
|
160
|
+
function DropdownMenuSeparator({
|
|
161
|
+
className,
|
|
162
|
+
...props
|
|
163
|
+
}) {
|
|
164
|
+
return <DropdownMenuPrimitive.Separator data-slot="dropdown-menu-separator" className={cn("bg-border -mx-1 my-1 h-px", className)} {...props} />;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
/**
|
|
168
|
+
* @param {{
|
|
169
|
+
* className?: string
|
|
170
|
+
* } & React.HTMLAttributes<HTMLSpanElement>} props
|
|
171
|
+
* @returns {React.JSX.Element}
|
|
172
|
+
*/
|
|
173
|
+
function DropdownMenuShortcut({
|
|
174
|
+
className,
|
|
175
|
+
...props
|
|
176
|
+
}) {
|
|
177
|
+
return <span data-slot="dropdown-menu-shortcut" className={cn("text-muted-foreground ml-auto text-xs tracking-widest", className)} {...props} />;
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
/**
|
|
181
|
+
* @param {React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Sub>} props
|
|
182
|
+
* @returns {React.JSX.Element}
|
|
183
|
+
*/
|
|
184
|
+
function DropdownMenuSub({
|
|
185
|
+
...props
|
|
186
|
+
}) {
|
|
187
|
+
return <DropdownMenuPrimitive.Sub data-slot="dropdown-menu-sub" {...props} />;
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
/**
|
|
191
|
+
* @param {{
|
|
192
|
+
* className?: string,
|
|
193
|
+
* inset?: boolean,
|
|
194
|
+
* children?: React.ReactNode
|
|
195
|
+
* } & React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.SubTrigger>} props
|
|
196
|
+
* @returns {React.JSX.Element}
|
|
197
|
+
*/
|
|
198
|
+
function DropdownMenuSubTrigger({
|
|
199
|
+
className,
|
|
200
|
+
inset,
|
|
201
|
+
children,
|
|
202
|
+
...props
|
|
203
|
+
}) {
|
|
204
|
+
return <DropdownMenuPrimitive.SubTrigger data-slot="dropdown-menu-sub-trigger" data-inset={inset} className={cn("focus:bg-accent focus:text-accent-foreground data-[state=open]:bg-accent data-[state=open]:text-accent-foreground flex cursor-default items-center rounded-sm px-2 py-1.5 text-sm outline-hidden select-none data-[inset]:pl-8", className)} {...props}>
|
|
205
|
+
{children}
|
|
206
|
+
<ChevronRightIcon className="ml-auto size-4" />
|
|
207
|
+
</DropdownMenuPrimitive.SubTrigger>;
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
/**
|
|
211
|
+
* @param {{
|
|
212
|
+
* className?: string
|
|
213
|
+
* } & React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.SubContent>} props
|
|
214
|
+
* @returns {React.JSX.Element}
|
|
215
|
+
*/
|
|
216
|
+
function DropdownMenuSubContent({
|
|
217
|
+
className,
|
|
218
|
+
...props
|
|
219
|
+
}) {
|
|
220
|
+
return <DropdownMenuPrimitive.SubContent data-slot="dropdown-menu-sub-content" className={cn("bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 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 z-50 min-w-[8rem] origin-(--radix-dropdown-menu-content-transform-origin) overflow-hidden rounded-md border p-1 shadow-lg", className)} {...props} />;
|
|
221
|
+
}
|
|
222
|
+
export { DropdownMenu, DropdownMenuPortal, DropdownMenuTrigger, DropdownMenuContent, DropdownMenuGroup, DropdownMenuLabel, DropdownMenuItem, DropdownMenuCheckboxItem, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuSeparator, DropdownMenuShortcut, DropdownMenuSub, DropdownMenuSubTrigger, DropdownMenuSubContent };
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
// @ts-check
|
|
2
|
+
import * as React from "react";
|
|
3
|
+
import { cn } from "../../utils/css/cn";
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* @param {{
|
|
7
|
+
* className?: string,
|
|
8
|
+
* type?: string,
|
|
9
|
+
* size?: 'default' | 'sm'
|
|
10
|
+
* } & Omit<React.InputHTMLAttributes<HTMLInputElement>, 'size'>} props
|
|
11
|
+
* @returns {React.JSX.Element}
|
|
12
|
+
*/
|
|
13
|
+
function Input({
|
|
14
|
+
className,
|
|
15
|
+
type,
|
|
16
|
+
size = "default",
|
|
17
|
+
...props
|
|
18
|
+
}) {
|
|
19
|
+
return <input type={type} data-slot="input" data-size={size} className={cn("file:text-foreground placeholder:text-muted-foreground selection:bg-primary selection:text-primary-foreground dark:bg-input/30 border-input flex w-full min-w-0 rounded-md border bg-transparent px-3 py-1 text-base shadow-xs transition-[color,box-shadow] outline-none file:inline-flex file:h-7 file:border-0 file:bg-transparent file:text-sm file:font-medium disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50 md:text-sm", "focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px]", "aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive", "data-[size=default]:h-9 data-[size=sm]:h-8", className)} {...props} />;
|
|
20
|
+
}
|
|
21
|
+
export { Input };
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
// @ts-check
|
|
2
|
+
"use client";
|
|
3
|
+
|
|
4
|
+
import * as React from "react";
|
|
5
|
+
import * as LabelPrimitive from "@radix-ui/react-label";
|
|
6
|
+
import { cn } from "../../utils/css/cn";
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* @param {{
|
|
10
|
+
* className?: string
|
|
11
|
+
* } & React.ComponentPropsWithoutRef<typeof LabelPrimitive.Root>} props
|
|
12
|
+
* @returns {React.JSX.Element}
|
|
13
|
+
*/
|
|
14
|
+
function Label({
|
|
15
|
+
className,
|
|
16
|
+
...props
|
|
17
|
+
}) {
|
|
18
|
+
return <LabelPrimitive.Root data-slot="label" className={cn("flex items-center gap-2 text-sm leading-none font-medium select-none group-data-[disabled=true]:pointer-events-none group-data-[disabled=true]:opacity-50 peer-disabled:cursor-not-allowed peer-disabled:opacity-50", className)} {...props} />;
|
|
19
|
+
}
|
|
20
|
+
export { Label };
|
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
// @ts-check
|
|
2
|
+
"use client";
|
|
3
|
+
|
|
4
|
+
import * as React from "react";
|
|
5
|
+
import * as SelectPrimitive from "@radix-ui/react-select";
|
|
6
|
+
import { CheckIcon, ChevronDownIcon, ChevronUpIcon } from "lucide-react";
|
|
7
|
+
import { cn } from "../../utils/css/cn";
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* @param {React.ComponentPropsWithoutRef<typeof SelectPrimitive.Root>} props
|
|
11
|
+
* @returns {React.JSX.Element}
|
|
12
|
+
*/
|
|
13
|
+
function Select({
|
|
14
|
+
...props
|
|
15
|
+
}) {
|
|
16
|
+
return <SelectPrimitive.Root data-slot="select" {...props} />;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* @param {React.ComponentPropsWithoutRef<typeof SelectPrimitive.Group>} props
|
|
21
|
+
* @returns {React.JSX.Element}
|
|
22
|
+
*/
|
|
23
|
+
function SelectGroup({
|
|
24
|
+
...props
|
|
25
|
+
}) {
|
|
26
|
+
return <SelectPrimitive.Group data-slot="select-group" {...props} />;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* @param {React.ComponentPropsWithoutRef<typeof SelectPrimitive.Value>} props
|
|
31
|
+
* @returns {React.JSX.Element}
|
|
32
|
+
*/
|
|
33
|
+
function SelectValue({
|
|
34
|
+
...props
|
|
35
|
+
}) {
|
|
36
|
+
return <SelectPrimitive.Value data-slot="select-value" {...props} />;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* @param {{
|
|
41
|
+
* className?: string,
|
|
42
|
+
* size?: 'default' | 'sm',
|
|
43
|
+
* children?: React.ReactNode
|
|
44
|
+
* } & React.ComponentPropsWithoutRef<typeof SelectPrimitive.Trigger>} props
|
|
45
|
+
* @returns {React.JSX.Element}
|
|
46
|
+
*/
|
|
47
|
+
function SelectTrigger({
|
|
48
|
+
className,
|
|
49
|
+
size = "default",
|
|
50
|
+
children,
|
|
51
|
+
...props
|
|
52
|
+
}) {
|
|
53
|
+
return <SelectPrimitive.Trigger data-slot="select-trigger" data-size={size} className={cn("border-input data-[placeholder]:text-muted-foreground [&_svg:not([class*='text-'])]:text-muted-foreground focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:bg-input/30 dark:hover:bg-input/50 flex w-fit items-center justify-between gap-2 rounded-md border bg-transparent px-3 py-2 text-sm whitespace-nowrap shadow-xs transition-[color,box-shadow] outline-none focus-visible:ring-[3px] disabled:cursor-not-allowed disabled:opacity-50 data-[size=default]:h-9 data-[size=sm]:h-8 *:data-[slot=select-value]:line-clamp-1 *:data-[slot=select-value]:flex *:data-[slot=select-value]:items-center *:data-[slot=select-value]:gap-2 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4", className)} {...props}>
|
|
54
|
+
{children}
|
|
55
|
+
<SelectPrimitive.Icon asChild>
|
|
56
|
+
<ChevronDownIcon className="size-4 opacity-50" />
|
|
57
|
+
</SelectPrimitive.Icon>
|
|
58
|
+
</SelectPrimitive.Trigger>;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* @param {{
|
|
63
|
+
* className?: string,
|
|
64
|
+
* children?: React.ReactNode,
|
|
65
|
+
* position?: 'popper' | 'item-aligned'
|
|
66
|
+
* } & React.ComponentPropsWithoutRef<typeof SelectPrimitive.Content>} props
|
|
67
|
+
* @returns {React.JSX.Element}
|
|
68
|
+
*/
|
|
69
|
+
function SelectContent({
|
|
70
|
+
className,
|
|
71
|
+
children,
|
|
72
|
+
position = "popper",
|
|
73
|
+
...props
|
|
74
|
+
}) {
|
|
75
|
+
return <SelectPrimitive.Portal>
|
|
76
|
+
<SelectPrimitive.Content data-slot="select-content" className={cn("bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 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 relative z-50 max-h-(--radix-select-content-available-height) min-w-[8rem] origin-(--radix-select-content-transform-origin) overflow-x-hidden overflow-y-auto rounded-md border shadow-md", 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", className)} position={position} {...props}>
|
|
77
|
+
<SelectScrollUpButton />
|
|
78
|
+
<SelectPrimitive.Viewport className={cn("p-1", position === "popper" && "h-[var(--radix-select-trigger-height)] w-full min-w-[var(--radix-select-trigger-width)] scroll-my-1")}>
|
|
79
|
+
{children}
|
|
80
|
+
</SelectPrimitive.Viewport>
|
|
81
|
+
<SelectScrollDownButton />
|
|
82
|
+
</SelectPrimitive.Content>
|
|
83
|
+
</SelectPrimitive.Portal>;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* @param {{
|
|
88
|
+
* className?: string
|
|
89
|
+
* } & React.ComponentPropsWithoutRef<typeof SelectPrimitive.Label>} props
|
|
90
|
+
* @returns {React.JSX.Element}
|
|
91
|
+
*/
|
|
92
|
+
function SelectLabel({
|
|
93
|
+
className,
|
|
94
|
+
...props
|
|
95
|
+
}) {
|
|
96
|
+
return <SelectPrimitive.Label data-slot="select-label" className={cn("text-muted-foreground px-2 py-1.5 text-xs", className)} {...props} />;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* @param {{
|
|
101
|
+
* className?: string,
|
|
102
|
+
* children?: React.ReactNode,
|
|
103
|
+
* value?: string | number
|
|
104
|
+
* } & Omit<React.ComponentPropsWithoutRef<typeof SelectPrimitive.Item>, 'value'>} props
|
|
105
|
+
* @returns {React.JSX.Element}
|
|
106
|
+
*/
|
|
107
|
+
function SelectItem({
|
|
108
|
+
className,
|
|
109
|
+
children,
|
|
110
|
+
value,
|
|
111
|
+
...props
|
|
112
|
+
}) {
|
|
113
|
+
return <SelectPrimitive.Item data-slot="select-item" className={cn("focus:bg-accent focus:text-accent-foreground [&_svg:not([class*='text-'])]:text-muted-foreground relative flex w-full cursor-default items-center gap-2 rounded-sm py-1.5 pr-8 pl-2 text-sm outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4 *:[span]:last:flex *:[span]:last:items-center *:[span]:last:gap-2", className)} value={value !== undefined ? String(value) : undefined} {...props}>
|
|
114
|
+
<span className="absolute right-2 flex size-3.5 items-center justify-center">
|
|
115
|
+
<SelectPrimitive.ItemIndicator>
|
|
116
|
+
<CheckIcon className="size-4" />
|
|
117
|
+
</SelectPrimitive.ItemIndicator>
|
|
118
|
+
</span>
|
|
119
|
+
<SelectPrimitive.ItemText>{children}</SelectPrimitive.ItemText>
|
|
120
|
+
</SelectPrimitive.Item>;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
/**
|
|
124
|
+
* @param {{
|
|
125
|
+
* className?: string
|
|
126
|
+
* } & React.ComponentPropsWithoutRef<typeof SelectPrimitive.Separator>} props
|
|
127
|
+
* @returns {React.JSX.Element}
|
|
128
|
+
*/
|
|
129
|
+
function SelectSeparator({
|
|
130
|
+
className,
|
|
131
|
+
...props
|
|
132
|
+
}) {
|
|
133
|
+
return <SelectPrimitive.Separator data-slot="select-separator" className={cn("bg-border pointer-events-none -mx-1 my-1 h-px", className)} {...props} />;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
/**
|
|
137
|
+
* @param {{
|
|
138
|
+
* className?: string
|
|
139
|
+
* } & React.ComponentPropsWithoutRef<typeof SelectPrimitive.ScrollUpButton>} props
|
|
140
|
+
* @returns {React.JSX.Element}
|
|
141
|
+
*/
|
|
142
|
+
function SelectScrollUpButton({
|
|
143
|
+
className,
|
|
144
|
+
...props
|
|
145
|
+
}) {
|
|
146
|
+
return <SelectPrimitive.ScrollUpButton data-slot="select-scroll-up-button" className={cn("flex cursor-default items-center justify-center py-1", className)} {...props}>
|
|
147
|
+
<ChevronUpIcon className="size-4" />
|
|
148
|
+
</SelectPrimitive.ScrollUpButton>;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
/**
|
|
152
|
+
* @param {{
|
|
153
|
+
* className?: string
|
|
154
|
+
* } & React.ComponentPropsWithoutRef<typeof SelectPrimitive.ScrollDownButton>} props
|
|
155
|
+
* @returns {React.JSX.Element}
|
|
156
|
+
*/
|
|
157
|
+
function SelectScrollDownButton({
|
|
158
|
+
className,
|
|
159
|
+
...props
|
|
160
|
+
}) {
|
|
161
|
+
return <SelectPrimitive.ScrollDownButton data-slot="select-scroll-down-button" className={cn("flex cursor-default items-center justify-center py-1", className)} {...props}>
|
|
162
|
+
<ChevronDownIcon className="size-4" />
|
|
163
|
+
</SelectPrimitive.ScrollDownButton>;
|
|
164
|
+
}
|
|
165
|
+
export { Select, SelectContent, SelectGroup, SelectItem, SelectLabel, SelectScrollDownButton, SelectScrollUpButton, SelectSeparator, SelectTrigger, SelectValue };
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
import { cn } from "../../utils/css/cn";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* @typedef {Object} StackOwnProps
|
|
6
|
+
* @property {'row' | 'column' | 'row-reverse' | 'column-reverse'} [direction]
|
|
7
|
+
* @property {number | string} [spacing]
|
|
8
|
+
* @property {'start' | 'center' | 'end' | 'stretch' | 'baseline'} [align]
|
|
9
|
+
* @property {'start' | 'center' | 'end' | 'between' | 'around' | 'evenly'} [justify]
|
|
10
|
+
* @property {boolean} [wrap]
|
|
11
|
+
* @property {React.ReactNode} [divider]
|
|
12
|
+
* @property {React.ReactNode} [children]
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
/** @type {React.ForwardRefExoticComponent<StackOwnProps & React.HTMLAttributes<HTMLDivElement> & React.RefAttributes<HTMLDivElement>>} */
|
|
16
|
+
const Stack = React.forwardRef(({
|
|
17
|
+
className,
|
|
18
|
+
direction = "column",
|
|
19
|
+
spacing = 1,
|
|
20
|
+
align,
|
|
21
|
+
justify,
|
|
22
|
+
wrap = false,
|
|
23
|
+
divider,
|
|
24
|
+
children,
|
|
25
|
+
...restProps
|
|
26
|
+
}, ref) => {
|
|
27
|
+
// Remove any non-DOM props that might have been passed
|
|
28
|
+
const {
|
|
29
|
+
alignItems,
|
|
30
|
+
justifyContent,
|
|
31
|
+
flexDirection,
|
|
32
|
+
...domProps
|
|
33
|
+
} = restProps;
|
|
34
|
+
const directionClasses = {
|
|
35
|
+
row: "flex-row",
|
|
36
|
+
column: "flex-col",
|
|
37
|
+
"row-reverse": "flex-row-reverse",
|
|
38
|
+
"column-reverse": "flex-col-reverse"
|
|
39
|
+
};
|
|
40
|
+
const alignClasses = {
|
|
41
|
+
start: "items-start",
|
|
42
|
+
center: "items-center",
|
|
43
|
+
end: "items-end",
|
|
44
|
+
stretch: "items-stretch",
|
|
45
|
+
baseline: "items-baseline"
|
|
46
|
+
};
|
|
47
|
+
const justifyClasses = {
|
|
48
|
+
start: "justify-start",
|
|
49
|
+
center: "justify-center",
|
|
50
|
+
end: "justify-end",
|
|
51
|
+
between: "justify-between",
|
|
52
|
+
around: "justify-around",
|
|
53
|
+
evenly: "justify-evenly"
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
// Convert spacing to Tailwind gap classes
|
|
57
|
+
const getSpacingClass = spacing => {
|
|
58
|
+
if (typeof spacing === "string") return spacing;
|
|
59
|
+
|
|
60
|
+
// Map numbers to Tailwind spacing scale
|
|
61
|
+
const spacingMap = {
|
|
62
|
+
0: "gap-0",
|
|
63
|
+
0.5: "gap-0.5",
|
|
64
|
+
1: "gap-1",
|
|
65
|
+
1.5: "gap-1.5",
|
|
66
|
+
2: "gap-2",
|
|
67
|
+
2.5: "gap-2.5",
|
|
68
|
+
3: "gap-3",
|
|
69
|
+
4: "gap-4",
|
|
70
|
+
5: "gap-5",
|
|
71
|
+
6: "gap-6",
|
|
72
|
+
8: "gap-8",
|
|
73
|
+
10: "gap-10",
|
|
74
|
+
12: "gap-12",
|
|
75
|
+
16: "gap-16",
|
|
76
|
+
20: "gap-20",
|
|
77
|
+
24: "gap-24"
|
|
78
|
+
};
|
|
79
|
+
return spacingMap[spacing] || "gap-4";
|
|
80
|
+
};
|
|
81
|
+
const stackClasses = cn("flex", directionClasses[direction], getSpacingClass(spacing), align && alignClasses[align], justify && justifyClasses[justify], wrap && "flex-wrap", className);
|
|
82
|
+
|
|
83
|
+
// Handle divider rendering
|
|
84
|
+
if (divider && React.Children.count(children) > 1) {
|
|
85
|
+
const childrenArray = React.Children.toArray(children);
|
|
86
|
+
const childrenWithDividers = [];
|
|
87
|
+
childrenArray.forEach((child, index) => {
|
|
88
|
+
childrenWithDividers.push(child);
|
|
89
|
+
if (index < childrenArray.length - 1) {
|
|
90
|
+
childrenWithDividers.push(<div key={`divider-${index}`} className="flex-shrink-0">
|
|
91
|
+
{divider}
|
|
92
|
+
</div>);
|
|
93
|
+
}
|
|
94
|
+
});
|
|
95
|
+
return <div ref={ref} className={stackClasses} {...domProps}>
|
|
96
|
+
{childrenWithDividers}
|
|
97
|
+
</div>;
|
|
98
|
+
}
|
|
99
|
+
return <div ref={ref} className={stackClasses} {...domProps}>
|
|
100
|
+
{children}
|
|
101
|
+
</div>;
|
|
102
|
+
});
|
|
103
|
+
Stack.displayName = "Stack";
|
|
104
|
+
export { Stack };
|