@microlight/core 0.9.9 → 0.11.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/server/app/layout.js +2 -18
- package/dist/server/app/library/[[...f_path]]/ViewFolder.js +37 -66
- package/dist/server/app/monitoring/MonitoringDashboard.js +329 -0
- package/dist/server/app/monitoring/action.js +147 -0
- package/dist/server/app/monitoring/page.js +8 -0
- 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 +25 -31
- 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 -4
- package/dist/server/components/Icon.js +0 -22
|
@@ -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 };
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
import { cva } from "class-variance-authority";
|
|
3
|
+
import { cn } from "../../utils/css/cn";
|
|
4
|
+
const tableVariants = cva("w-full caption-bottom text-sm", {
|
|
5
|
+
variants: {
|
|
6
|
+
variant: {
|
|
7
|
+
default: "",
|
|
8
|
+
compact: "[&_td]:py-2 [&_th]:py-2 [&_td]:px-2 [&_th]:px-2 [&_td]:text-sm [&_th]:text-xs"
|
|
9
|
+
}
|
|
10
|
+
},
|
|
11
|
+
defaultVariants: {
|
|
12
|
+
variant: "default"
|
|
13
|
+
}
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
/** @type {React.ForwardRefExoticComponent<React.HTMLAttributes<HTMLTableElement> & { variant?: 'default' | 'compact' } & React.RefAttributes<HTMLTableElement>>} */
|
|
17
|
+
const Table = React.forwardRef(({
|
|
18
|
+
className,
|
|
19
|
+
variant,
|
|
20
|
+
...props
|
|
21
|
+
}, ref) => <div className="relative w-full overflow-auto">
|
|
22
|
+
<table ref={ref} className={cn(tableVariants({
|
|
23
|
+
variant,
|
|
24
|
+
className
|
|
25
|
+
}))} {...props} />
|
|
26
|
+
</div>);
|
|
27
|
+
Table.displayName = "Table";
|
|
28
|
+
|
|
29
|
+
/** @type {React.ForwardRefExoticComponent<React.HTMLAttributes<HTMLTableSectionElement> & React.RefAttributes<HTMLTableSectionElement>>} */
|
|
30
|
+
const TableHeader = React.forwardRef(({
|
|
31
|
+
className,
|
|
32
|
+
...props
|
|
33
|
+
}, ref) => <thead ref={ref} className={cn("[&_tr]:border-b", className)} {...props} />);
|
|
34
|
+
TableHeader.displayName = "TableHeader";
|
|
35
|
+
|
|
36
|
+
/** @type {React.ForwardRefExoticComponent<React.HTMLAttributes<HTMLTableSectionElement> & React.RefAttributes<HTMLTableSectionElement>>} */
|
|
37
|
+
const TableBody = React.forwardRef(({
|
|
38
|
+
className,
|
|
39
|
+
...props
|
|
40
|
+
}, ref) => <tbody ref={ref} className={cn("[&_tr:last-child]:border-0", className)} {...props} />);
|
|
41
|
+
TableBody.displayName = "TableBody";
|
|
42
|
+
|
|
43
|
+
/** @type {React.ForwardRefExoticComponent<React.HTMLAttributes<HTMLTableSectionElement> & React.RefAttributes<HTMLTableSectionElement>>} */
|
|
44
|
+
const TableFooter = React.forwardRef(({
|
|
45
|
+
className,
|
|
46
|
+
...props
|
|
47
|
+
}, ref) => <tfoot ref={ref} className={cn("border-t bg-muted/50 font-medium [&>tr]:last:border-b-0", className)} {...props} />);
|
|
48
|
+
TableFooter.displayName = "TableFooter";
|
|
49
|
+
|
|
50
|
+
/** @type {React.ForwardRefExoticComponent<React.HTMLAttributes<HTMLTableRowElement> & React.RefAttributes<HTMLTableRowElement>>} */
|
|
51
|
+
const TableRow = React.forwardRef(({
|
|
52
|
+
className,
|
|
53
|
+
...props
|
|
54
|
+
}, ref) => <tr ref={ref} className={cn("border-b transition-colors hover:bg-muted/50 data-[state=selected]:bg-muted", className)} {...props} />);
|
|
55
|
+
TableRow.displayName = "TableRow";
|
|
56
|
+
|
|
57
|
+
/** @type {React.ForwardRefExoticComponent<React.ThHTMLAttributes<HTMLTableCellElement> & React.RefAttributes<HTMLTableCellElement>>} */
|
|
58
|
+
const TableHead = React.forwardRef(({
|
|
59
|
+
className,
|
|
60
|
+
...props
|
|
61
|
+
}, ref) => <th ref={ref} className={cn("h-12 px-4 text-left align-middle font-medium text-muted-foreground [&:has([role=checkbox])]:pr-0", className)} {...props} />);
|
|
62
|
+
TableHead.displayName = "TableHead";
|
|
63
|
+
|
|
64
|
+
/** @type {React.ForwardRefExoticComponent<React.TdHTMLAttributes<HTMLTableCellElement> & React.RefAttributes<HTMLTableCellElement>>} */
|
|
65
|
+
const TableCell = React.forwardRef(({
|
|
66
|
+
className,
|
|
67
|
+
...props
|
|
68
|
+
}, ref) => <td ref={ref} className={cn("p-4 align-middle [&:has([role=checkbox])]:pr-0", className)} {...props} />);
|
|
69
|
+
TableCell.displayName = "TableCell";
|
|
70
|
+
|
|
71
|
+
/** @type {React.ForwardRefExoticComponent<React.HTMLAttributes<HTMLTableCaptionElement> & React.RefAttributes<HTMLTableCaptionElement>>} */
|
|
72
|
+
const TableCaption = React.forwardRef(({
|
|
73
|
+
className,
|
|
74
|
+
...props
|
|
75
|
+
}, ref) => <caption ref={ref} className={cn("mt-4 text-sm text-muted-foreground", className)} {...props} />);
|
|
76
|
+
TableCaption.displayName = "TableCaption";
|
|
77
|
+
export { Table, TableHeader, TableBody, TableFooter, TableHead, TableRow, TableCell, TableCaption, tableVariants };
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
// @ts-check
|
|
2
|
+
"use client";
|
|
3
|
+
|
|
4
|
+
import * as React from "react";
|
|
5
|
+
import * as TabsPrimitive from "@radix-ui/react-tabs";
|
|
6
|
+
import { cn } from "../../utils/css/cn";
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* @param {{
|
|
10
|
+
* className?: string
|
|
11
|
+
* } & React.ComponentPropsWithoutRef<typeof TabsPrimitive.Root>} props
|
|
12
|
+
* @returns {React.JSX.Element}
|
|
13
|
+
*/
|
|
14
|
+
function Tabs({
|
|
15
|
+
className,
|
|
16
|
+
...props
|
|
17
|
+
}) {
|
|
18
|
+
return <TabsPrimitive.Root data-slot="tabs" className={cn("flex flex-col gap-2", className)} {...props} />;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* @param {{
|
|
23
|
+
* className?: string
|
|
24
|
+
* } & React.ComponentPropsWithoutRef<typeof TabsPrimitive.List>} props
|
|
25
|
+
* @returns {React.JSX.Element}
|
|
26
|
+
*/
|
|
27
|
+
function TabsList({
|
|
28
|
+
className,
|
|
29
|
+
...props
|
|
30
|
+
}) {
|
|
31
|
+
return <TabsPrimitive.List data-slot="tabs-list" className={cn("bg-muted text-muted-foreground inline-flex h-9 w-fit items-center justify-center rounded-lg p-[3px]", className)} {...props} />;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* @param {{
|
|
36
|
+
* className?: string
|
|
37
|
+
* } & React.ComponentPropsWithoutRef<typeof TabsPrimitive.Trigger>} props
|
|
38
|
+
* @returns {React.JSX.Element}
|
|
39
|
+
*/
|
|
40
|
+
function TabsTrigger({
|
|
41
|
+
className,
|
|
42
|
+
...props
|
|
43
|
+
}) {
|
|
44
|
+
return <TabsPrimitive.Trigger data-slot="tabs-trigger" className={cn("data-[state=active]:bg-background dark:data-[state=active]:text-foreground focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:outline-ring dark:data-[state=active]:border-input dark:data-[state=active]:bg-input/30 text-foreground dark:text-muted-foreground inline-flex h-[calc(100%-1px)] flex-1 items-center justify-center gap-1.5 rounded-md border border-transparent px-2 py-1 text-sm font-medium whitespace-nowrap transition-[color,box-shadow] focus-visible:ring-[3px] focus-visible:outline-1 disabled:pointer-events-none disabled:opacity-50 data-[state=active]:shadow-sm [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4", className)} {...props} />;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* @param {{
|
|
49
|
+
* className?: string
|
|
50
|
+
* } & React.ComponentPropsWithoutRef<typeof TabsPrimitive.Content>} props
|
|
51
|
+
* @returns {React.JSX.Element}
|
|
52
|
+
*/
|
|
53
|
+
function TabsContent({
|
|
54
|
+
className,
|
|
55
|
+
...props
|
|
56
|
+
}) {
|
|
57
|
+
return <TabsPrimitive.Content data-slot="tabs-content" className={cn("flex-1 outline-none", className)} {...props} />;
|
|
58
|
+
}
|
|
59
|
+
export { Tabs, TabsList, TabsTrigger, TabsContent };
|