@lark-apaas/coding-template-react-standard-webapp 0.1.0-alpha.20260827082008
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/LICENSE +13 -0
- package/README.md +25 -0
- package/hooks/after-install.mjs +3 -0
- package/hooks/after-render.mjs +3 -0
- package/hooks/before-render.mjs +3 -0
- package/package.json +35 -0
- package/template/README.md +105 -0
- package/template/_gitignore +64 -0
- package/template/_npmrc +1 -0
- package/template/components.json +21 -0
- package/template/eslint.config.mjs +27 -0
- package/template/index.html +13 -0
- package/template/miaoda.json +11 -0
- package/template/package-lock.json +7685 -0
- package/template/package.json +89 -0
- package/template/public/favicon.svg +1 -0
- package/template/public/icons.svg +24 -0
- package/template/src/app.tsx +15 -0
- package/template/src/components/ErrorFallback.tsx +19 -0
- package/template/src/components/Layout.tsx +7 -0
- package/template/src/components/ui/accordion.tsx +66 -0
- package/template/src/components/ui/alert-dialog.tsx +157 -0
- package/template/src/components/ui/alert.tsx +71 -0
- package/template/src/components/ui/aspect-ratio.tsx +11 -0
- package/template/src/components/ui/avatar.tsx +53 -0
- package/template/src/components/ui/badge.tsx +42 -0
- package/template/src/components/ui/breadcrumb.tsx +109 -0
- package/template/src/components/ui/button-group.tsx +83 -0
- package/template/src/components/ui/button.tsx +69 -0
- package/template/src/components/ui/calendar.tsx +213 -0
- package/template/src/components/ui/card.tsx +82 -0
- package/template/src/components/ui/carousel.tsx +241 -0
- package/template/src/components/ui/chart.tsx +357 -0
- package/template/src/components/ui/checkbox.tsx +32 -0
- package/template/src/components/ui/collapsible.tsx +33 -0
- package/template/src/components/ui/command.tsx +208 -0
- package/template/src/components/ui/context-menu.tsx +324 -0
- package/template/src/components/ui/dialog.tsx +143 -0
- package/template/src/components/ui/drawer.tsx +135 -0
- package/template/src/components/ui/dropdown-menu.tsx +329 -0
- package/template/src/components/ui/empty.tsx +104 -0
- package/template/src/components/ui/field.tsx +248 -0
- package/template/src/components/ui/form.tsx +167 -0
- package/template/src/components/ui/hover-card.tsx +44 -0
- package/template/src/components/ui/image.tsx +183 -0
- package/template/src/components/ui/input-group.tsx +166 -0
- package/template/src/components/ui/input-otp.tsx +77 -0
- package/template/src/components/ui/input.tsx +21 -0
- package/template/src/components/ui/item.tsx +193 -0
- package/template/src/components/ui/kbd.tsx +28 -0
- package/template/src/components/ui/label.tsx +24 -0
- package/template/src/components/ui/menubar.tsx +348 -0
- package/template/src/components/ui/native-select.tsx +48 -0
- package/template/src/components/ui/navigation-menu.tsx +168 -0
- package/template/src/components/ui/pagination.tsx +127 -0
- package/template/src/components/ui/popover.tsx +48 -0
- package/template/src/components/ui/progress.tsx +31 -0
- package/template/src/components/ui/radio-group.tsx +45 -0
- package/template/src/components/ui/resizable.tsx +56 -0
- package/template/src/components/ui/scroll-area.tsx +58 -0
- package/template/src/components/ui/select.tsx +243 -0
- package/template/src/components/ui/separator.tsx +28 -0
- package/template/src/components/ui/sheet.tsx +139 -0
- package/template/src/components/ui/sidebar.tsx +727 -0
- package/template/src/components/ui/skeleton.tsx +13 -0
- package/template/src/components/ui/slider.tsx +87 -0
- package/template/src/components/ui/sonner.tsx +67 -0
- package/template/src/components/ui/spinner.tsx +16 -0
- package/template/src/components/ui/switch.tsx +31 -0
- package/template/src/components/ui/table.tsx +116 -0
- package/template/src/components/ui/tabs.tsx +66 -0
- package/template/src/components/ui/textarea.tsx +18 -0
- package/template/src/components/ui/toggle-group.tsx +83 -0
- package/template/src/components/ui/toggle.tsx +47 -0
- package/template/src/components/ui/tooltip.tsx +61 -0
- package/template/src/hooks/use-mobile.ts +20 -0
- package/template/src/index.css +4 -0
- package/template/src/index.tsx +17 -0
- package/template/src/lib/utils.ts +6 -0
- package/template/src/pages/ExamplePage/ExamplePage.tsx +37 -0
- package/template/src/pages/HomePage/HomePage.tsx +10 -0
- package/template/src/pages/NotFoundPage/NotFoundPage.tsx +11 -0
- package/template/src/tailwind-theme.css +258 -0
- package/template/src/typography.css +41 -0
- package/template/src/vite-env.d.ts +5 -0
- package/template/tsconfig.app.json +29 -0
- package/template/tsconfig.json +10 -0
- package/template/tsconfig.node.json +26 -0
- package/template/vite.config.ts +97 -0
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
"use client"
|
|
2
|
+
|
|
3
|
+
import * as React from "react"
|
|
4
|
+
import { cva, type VariantProps } from "class-variance-authority"
|
|
5
|
+
|
|
6
|
+
import { cn } from "@/lib/utils"
|
|
7
|
+
import { Button } from "@/components/ui/button"
|
|
8
|
+
import { Input } from "@/components/ui/input"
|
|
9
|
+
import { Textarea } from "@/components/ui/textarea"
|
|
10
|
+
|
|
11
|
+
function InputGroup({ className, ...props }: React.ComponentProps<"div">) {
|
|
12
|
+
return (
|
|
13
|
+
<div
|
|
14
|
+
data-slot="input-group"
|
|
15
|
+
role="group"
|
|
16
|
+
className={cn(
|
|
17
|
+
"group/input-group border-input dark:bg-input/30 relative flex w-full items-center rounded-md border transition-[color,box-shadow] outline-none",
|
|
18
|
+
"h-9 min-w-0 has-[>textarea]:h-auto",
|
|
19
|
+
|
|
20
|
+
// Variants based on alignment.
|
|
21
|
+
"has-[>[data-align=inline-start]]:[&>input]:pl-2",
|
|
22
|
+
"has-[>[data-align=inline-end]]:[&>input]:pr-2",
|
|
23
|
+
"has-[>[data-align=block-start]]:h-auto has-[>[data-align=block-start]]:flex-col has-[>[data-align=block-start]]:[&>input]:pb-3",
|
|
24
|
+
"has-[>[data-align=block-end]]:h-auto has-[>[data-align=block-end]]:flex-col has-[>[data-align=block-end]]:[&>input]:pt-3",
|
|
25
|
+
|
|
26
|
+
// Focus state.
|
|
27
|
+
"has-[[data-slot=input-group-control]:focus-visible]:border-ring has-[[data-slot=input-group-control]:focus-visible]:ring-ring/20 has-[[data-slot=input-group-control]:focus-visible]:ring-[3px]",
|
|
28
|
+
|
|
29
|
+
// Error state.
|
|
30
|
+
"has-[[data-slot][aria-invalid=true]]:ring-destructive/20 has-[[data-slot][aria-invalid=true]]:border-destructive dark:has-[[data-slot][aria-invalid=true]]:ring-destructive/40",
|
|
31
|
+
|
|
32
|
+
className
|
|
33
|
+
)}
|
|
34
|
+
{...props}
|
|
35
|
+
/>
|
|
36
|
+
)
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
const inputGroupAddonVariants = cva(
|
|
40
|
+
"text-muted-foreground flex h-auto cursor-text items-center justify-center gap-2 py-1.5 text-sm font-medium select-none [&>svg:not([class*='size-'])]:size-4 [&>kbd]:rounded-[calc(var(--radius)-5px)] group-data-[disabled=true]/input-group:opacity-50",
|
|
41
|
+
{
|
|
42
|
+
variants: {
|
|
43
|
+
align: {
|
|
44
|
+
"inline-start":
|
|
45
|
+
"order-first pl-3 has-[>button]:ml-[-0.45rem] has-[>kbd]:ml-[-0.35rem]",
|
|
46
|
+
"inline-end":
|
|
47
|
+
"order-last pr-3 has-[>button]:mr-[-0.45rem] has-[>kbd]:mr-[-0.35rem]",
|
|
48
|
+
"block-start":
|
|
49
|
+
"order-first w-full justify-start px-3 pt-3 [.border-b]:pb-3 group-has-[>input]/input-group:pt-2.5",
|
|
50
|
+
"block-end":
|
|
51
|
+
"order-last w-full justify-start px-3 pb-3 [.border-t]:pt-3 group-has-[>input]/input-group:pb-2.5",
|
|
52
|
+
},
|
|
53
|
+
},
|
|
54
|
+
defaultVariants: {
|
|
55
|
+
align: "inline-start",
|
|
56
|
+
},
|
|
57
|
+
}
|
|
58
|
+
)
|
|
59
|
+
|
|
60
|
+
function InputGroupAddon({
|
|
61
|
+
className,
|
|
62
|
+
align = "inline-start",
|
|
63
|
+
...props
|
|
64
|
+
}: React.ComponentProps<"div"> & VariantProps<typeof inputGroupAddonVariants>) {
|
|
65
|
+
return (
|
|
66
|
+
<div
|
|
67
|
+
role="group"
|
|
68
|
+
data-slot="input-group-addon"
|
|
69
|
+
data-align={align}
|
|
70
|
+
className={cn(inputGroupAddonVariants({ align }), className)}
|
|
71
|
+
onClick={(e) => {
|
|
72
|
+
if ((e.target as HTMLElement).closest("button")) {
|
|
73
|
+
return
|
|
74
|
+
}
|
|
75
|
+
e.currentTarget.parentElement?.querySelector("input")?.focus()
|
|
76
|
+
}}
|
|
77
|
+
{...props}
|
|
78
|
+
/>
|
|
79
|
+
)
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
const inputGroupButtonVariants = cva("text-sm flex gap-2 items-center", {
|
|
83
|
+
variants: {
|
|
84
|
+
size: {
|
|
85
|
+
xs: "h-6 gap-1 px-2 rounded-[calc(var(--radius)-5px)] [&>svg:not([class*='size-'])]:size-3.5 has-[>svg]:px-2",
|
|
86
|
+
sm: "h-8 px-2.5 gap-1.5 rounded-md has-[>svg]:px-2.5",
|
|
87
|
+
"icon-xs": "size-6 rounded-[calc(var(--radius)-5px)] p-0 has-[>svg]:p-0",
|
|
88
|
+
"icon-sm": "size-8 p-0 has-[>svg]:p-0",
|
|
89
|
+
},
|
|
90
|
+
},
|
|
91
|
+
defaultVariants: {
|
|
92
|
+
size: "xs",
|
|
93
|
+
},
|
|
94
|
+
})
|
|
95
|
+
|
|
96
|
+
function InputGroupButton({
|
|
97
|
+
className,
|
|
98
|
+
type = "button",
|
|
99
|
+
variant = "ghost",
|
|
100
|
+
size = "xs",
|
|
101
|
+
...props
|
|
102
|
+
}: Omit<React.ComponentProps<typeof Button>, "size"> &
|
|
103
|
+
VariantProps<typeof inputGroupButtonVariants>) {
|
|
104
|
+
return (
|
|
105
|
+
<Button
|
|
106
|
+
type={type}
|
|
107
|
+
data-size={size}
|
|
108
|
+
variant={variant}
|
|
109
|
+
className={cn(inputGroupButtonVariants({ size }), className)}
|
|
110
|
+
{...props}
|
|
111
|
+
/>
|
|
112
|
+
)
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
function InputGroupText({ className, ...props }: React.ComponentProps<"span">) {
|
|
116
|
+
return (
|
|
117
|
+
<span
|
|
118
|
+
className={cn(
|
|
119
|
+
"text-muted-foreground flex items-center gap-2 text-sm [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4",
|
|
120
|
+
className
|
|
121
|
+
)}
|
|
122
|
+
{...props}
|
|
123
|
+
/>
|
|
124
|
+
)
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
function InputGroupInput({
|
|
128
|
+
className,
|
|
129
|
+
...props
|
|
130
|
+
}: React.ComponentProps<"input">) {
|
|
131
|
+
return (
|
|
132
|
+
<Input
|
|
133
|
+
data-slot="input-group-control"
|
|
134
|
+
className={cn(
|
|
135
|
+
"flex-1 rounded-none border-0 bg-transparent focus-visible:ring-0 dark:bg-transparent",
|
|
136
|
+
className
|
|
137
|
+
)}
|
|
138
|
+
{...props}
|
|
139
|
+
/>
|
|
140
|
+
)
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
function InputGroupTextarea({
|
|
144
|
+
className,
|
|
145
|
+
...props
|
|
146
|
+
}: React.ComponentProps<"textarea">) {
|
|
147
|
+
return (
|
|
148
|
+
<Textarea
|
|
149
|
+
data-slot="input-group-control"
|
|
150
|
+
className={cn(
|
|
151
|
+
"flex-1 resize-none rounded-none border-0 bg-transparent py-3 focus-visible:ring-0 dark:bg-transparent",
|
|
152
|
+
className
|
|
153
|
+
)}
|
|
154
|
+
{...props}
|
|
155
|
+
/>
|
|
156
|
+
)
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
export {
|
|
160
|
+
InputGroup,
|
|
161
|
+
InputGroupAddon,
|
|
162
|
+
InputGroupButton,
|
|
163
|
+
InputGroupText,
|
|
164
|
+
InputGroupInput,
|
|
165
|
+
InputGroupTextarea,
|
|
166
|
+
}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
"use client"
|
|
2
|
+
|
|
3
|
+
import * as React from "react"
|
|
4
|
+
import { OTPInput, OTPInputContext } from "input-otp"
|
|
5
|
+
import { MinusIcon } from "lucide-react"
|
|
6
|
+
|
|
7
|
+
import { cn } from "@/lib/utils"
|
|
8
|
+
|
|
9
|
+
function InputOTP({
|
|
10
|
+
className,
|
|
11
|
+
containerClassName,
|
|
12
|
+
...props
|
|
13
|
+
}: React.ComponentProps<typeof OTPInput> & {
|
|
14
|
+
containerClassName?: string
|
|
15
|
+
}) {
|
|
16
|
+
return (
|
|
17
|
+
<OTPInput
|
|
18
|
+
data-slot="input-otp"
|
|
19
|
+
containerClassName={cn(
|
|
20
|
+
"flex items-center gap-2 has-disabled:opacity-50",
|
|
21
|
+
containerClassName
|
|
22
|
+
)}
|
|
23
|
+
className={cn("disabled:cursor-not-allowed", className)}
|
|
24
|
+
{...props}
|
|
25
|
+
/>
|
|
26
|
+
)
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
function InputOTPGroup({ className, ...props }: React.ComponentProps<"div">) {
|
|
30
|
+
return (
|
|
31
|
+
<div
|
|
32
|
+
data-slot="input-otp-group"
|
|
33
|
+
className={cn("flex items-center", className)}
|
|
34
|
+
{...props}
|
|
35
|
+
/>
|
|
36
|
+
)
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
function InputOTPSlot({
|
|
40
|
+
index,
|
|
41
|
+
className,
|
|
42
|
+
...props
|
|
43
|
+
}: React.ComponentProps<"div"> & {
|
|
44
|
+
index: number
|
|
45
|
+
}) {
|
|
46
|
+
const inputOTPContext = React.useContext(OTPInputContext)
|
|
47
|
+
const { char, hasFakeCaret, isActive } = inputOTPContext?.slots[index] ?? {}
|
|
48
|
+
|
|
49
|
+
return (
|
|
50
|
+
<div
|
|
51
|
+
data-slot="input-otp-slot"
|
|
52
|
+
data-active={isActive}
|
|
53
|
+
className={cn(
|
|
54
|
+
"data-[active=true]:border-ring data-[active=true]:ring-ring/20 data-[active=true]:aria-invalid:ring-destructive/20 dark:data-[active=true]:aria-invalid:ring-destructive/40 aria-invalid:border-destructive data-[active=true]:aria-invalid:border-destructive dark:bg-input/30 border-input relative flex h-9 w-9 items-center justify-center border-y border-r text-sm transition-all outline-none first:rounded-l-md first:border-l last:rounded-r-md data-[active=true]:z-10 data-[active=true]:ring-[3px]",
|
|
55
|
+
className
|
|
56
|
+
)}
|
|
57
|
+
{...props}
|
|
58
|
+
>
|
|
59
|
+
{char}
|
|
60
|
+
{hasFakeCaret && (
|
|
61
|
+
<div className="pointer-events-none absolute inset-0 flex items-center justify-center">
|
|
62
|
+
<div className="animate-caret-blink bg-foreground h-4 w-px duration-1000" />
|
|
63
|
+
</div>
|
|
64
|
+
)}
|
|
65
|
+
</div>
|
|
66
|
+
)
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
function InputOTPSeparator({ ...props }: React.ComponentProps<"div">) {
|
|
70
|
+
return (
|
|
71
|
+
<div data-slot="input-otp-separator" role="separator" {...props}>
|
|
72
|
+
<MinusIcon />
|
|
73
|
+
</div>
|
|
74
|
+
)
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
export { InputOTP, InputOTPGroup, InputOTPSlot, InputOTPSeparator }
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import * as React from "react"
|
|
2
|
+
|
|
3
|
+
import { cn } from "@/lib/utils"
|
|
4
|
+
|
|
5
|
+
function Input({ className, type, ...props }: React.ComponentProps<"input">) {
|
|
6
|
+
return (
|
|
7
|
+
<input
|
|
8
|
+
type={type}
|
|
9
|
+
data-slot="input"
|
|
10
|
+
className={cn(
|
|
11
|
+
"file:text-foreground placeholder:text-muted-foreground selection:bg-primary selection:text-primary-foreground dark:bg-input/30 border-input h-9 w-full min-w-0 rounded-md border bg-transparent px-3 py-1 text-base 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:cursor-not-allowed disabled:opacity-50 md:text-sm",
|
|
12
|
+
"enabled:hover:border-ring focus-visible:border-ring focus-visible:ring-ring/20 focus-visible:ring-[3px]",
|
|
13
|
+
"aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive",
|
|
14
|
+
className
|
|
15
|
+
)}
|
|
16
|
+
{...props}
|
|
17
|
+
/>
|
|
18
|
+
)
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export { Input }
|
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
import * as React from "react"
|
|
2
|
+
import { Slot } from "@radix-ui/react-slot"
|
|
3
|
+
import { cva, type VariantProps } from "class-variance-authority"
|
|
4
|
+
|
|
5
|
+
import { cn } from "@/lib/utils"
|
|
6
|
+
import { Separator } from "@/components/ui/separator"
|
|
7
|
+
|
|
8
|
+
function ItemGroup({ className, ...props }: React.ComponentProps<"div">) {
|
|
9
|
+
return (
|
|
10
|
+
<div
|
|
11
|
+
role="list"
|
|
12
|
+
data-slot="item-group"
|
|
13
|
+
className={cn("group/item-group flex flex-col", className)}
|
|
14
|
+
{...props}
|
|
15
|
+
/>
|
|
16
|
+
)
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
function ItemSeparator({
|
|
20
|
+
className,
|
|
21
|
+
...props
|
|
22
|
+
}: React.ComponentProps<typeof Separator>) {
|
|
23
|
+
return (
|
|
24
|
+
<Separator
|
|
25
|
+
data-slot="item-separator"
|
|
26
|
+
orientation="horizontal"
|
|
27
|
+
className={cn("my-0", className)}
|
|
28
|
+
{...props}
|
|
29
|
+
/>
|
|
30
|
+
)
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
const itemVariants = cva(
|
|
34
|
+
"group/item flex items-center border border-transparent text-sm rounded-md transition-colors [a]:hover:bg-accent/50 [a]:transition-colors duration-100 flex-wrap outline-none focus-visible:border-ring focus-visible:ring-ring/20 focus-visible:ring-[3px]",
|
|
35
|
+
{
|
|
36
|
+
variants: {
|
|
37
|
+
variant: {
|
|
38
|
+
default: "bg-transparent",
|
|
39
|
+
outline: "border-border",
|
|
40
|
+
muted: "bg-muted/50",
|
|
41
|
+
},
|
|
42
|
+
size: {
|
|
43
|
+
default: "p-4 gap-4 ",
|
|
44
|
+
sm: "py-3 px-4 gap-2.5",
|
|
45
|
+
},
|
|
46
|
+
},
|
|
47
|
+
defaultVariants: {
|
|
48
|
+
variant: "default",
|
|
49
|
+
size: "default",
|
|
50
|
+
},
|
|
51
|
+
}
|
|
52
|
+
)
|
|
53
|
+
|
|
54
|
+
function Item({
|
|
55
|
+
className,
|
|
56
|
+
variant = "default",
|
|
57
|
+
size = "default",
|
|
58
|
+
asChild = false,
|
|
59
|
+
...props
|
|
60
|
+
}: React.ComponentProps<"div"> &
|
|
61
|
+
VariantProps<typeof itemVariants> & { asChild?: boolean }) {
|
|
62
|
+
const Comp = asChild ? Slot : "div"
|
|
63
|
+
return (
|
|
64
|
+
<Comp
|
|
65
|
+
data-slot="item"
|
|
66
|
+
data-variant={variant}
|
|
67
|
+
data-size={size}
|
|
68
|
+
className={cn(itemVariants({ variant, size, className }))}
|
|
69
|
+
{...props}
|
|
70
|
+
/>
|
|
71
|
+
)
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
const itemMediaVariants = cva(
|
|
75
|
+
"flex shrink-0 items-center justify-center gap-2 group-has-[[data-slot=item-description]]/item:self-start [&_svg]:pointer-events-none group-has-[[data-slot=item-description]]/item:translate-y-0.5",
|
|
76
|
+
{
|
|
77
|
+
variants: {
|
|
78
|
+
variant: {
|
|
79
|
+
default: "bg-transparent",
|
|
80
|
+
icon: "size-8 border rounded-sm bg-muted [&_svg:not([class*='size-'])]:size-4",
|
|
81
|
+
image:
|
|
82
|
+
"size-10 rounded-sm overflow-hidden [&_img]:size-full [&_img]:object-cover",
|
|
83
|
+
},
|
|
84
|
+
},
|
|
85
|
+
defaultVariants: {
|
|
86
|
+
variant: "default",
|
|
87
|
+
},
|
|
88
|
+
}
|
|
89
|
+
)
|
|
90
|
+
|
|
91
|
+
function ItemMedia({
|
|
92
|
+
className,
|
|
93
|
+
variant = "default",
|
|
94
|
+
...props
|
|
95
|
+
}: React.ComponentProps<"div"> & VariantProps<typeof itemMediaVariants>) {
|
|
96
|
+
return (
|
|
97
|
+
<div
|
|
98
|
+
data-slot="item-media"
|
|
99
|
+
data-variant={variant}
|
|
100
|
+
className={cn(itemMediaVariants({ variant, className }))}
|
|
101
|
+
{...props}
|
|
102
|
+
/>
|
|
103
|
+
)
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
function ItemContent({ className, ...props }: React.ComponentProps<"div">) {
|
|
107
|
+
return (
|
|
108
|
+
<div
|
|
109
|
+
data-slot="item-content"
|
|
110
|
+
className={cn(
|
|
111
|
+
"flex flex-1 flex-col gap-1 [&+[data-slot=item-content]]:flex-none",
|
|
112
|
+
className
|
|
113
|
+
)}
|
|
114
|
+
{...props}
|
|
115
|
+
/>
|
|
116
|
+
)
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
function ItemTitle({ className, ...props }: React.ComponentProps<"div">) {
|
|
120
|
+
return (
|
|
121
|
+
<div
|
|
122
|
+
data-slot="item-title"
|
|
123
|
+
className={cn(
|
|
124
|
+
"flex w-fit items-center gap-2 text-sm leading-snug font-medium",
|
|
125
|
+
className
|
|
126
|
+
)}
|
|
127
|
+
{...props}
|
|
128
|
+
/>
|
|
129
|
+
)
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
function ItemDescription({ className, ...props }: React.ComponentProps<"p">) {
|
|
133
|
+
return (
|
|
134
|
+
<p
|
|
135
|
+
data-slot="item-description"
|
|
136
|
+
className={cn(
|
|
137
|
+
"text-muted-foreground line-clamp-2 text-sm leading-normal font-normal text-balance",
|
|
138
|
+
"[&>a:hover]:text-primary [&>a]:underline [&>a]:underline-offset-4",
|
|
139
|
+
className
|
|
140
|
+
)}
|
|
141
|
+
{...props}
|
|
142
|
+
/>
|
|
143
|
+
)
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
function ItemActions({ className, ...props }: React.ComponentProps<"div">) {
|
|
147
|
+
return (
|
|
148
|
+
<div
|
|
149
|
+
data-slot="item-actions"
|
|
150
|
+
className={cn("flex items-center gap-2", className)}
|
|
151
|
+
{...props}
|
|
152
|
+
/>
|
|
153
|
+
)
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
function ItemHeader({ className, ...props }: React.ComponentProps<"div">) {
|
|
157
|
+
return (
|
|
158
|
+
<div
|
|
159
|
+
data-slot="item-header"
|
|
160
|
+
className={cn(
|
|
161
|
+
"flex basis-full items-center justify-between gap-2",
|
|
162
|
+
className
|
|
163
|
+
)}
|
|
164
|
+
{...props}
|
|
165
|
+
/>
|
|
166
|
+
)
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
function ItemFooter({ className, ...props }: React.ComponentProps<"div">) {
|
|
170
|
+
return (
|
|
171
|
+
<div
|
|
172
|
+
data-slot="item-footer"
|
|
173
|
+
className={cn(
|
|
174
|
+
"flex basis-full items-center justify-between gap-2",
|
|
175
|
+
className
|
|
176
|
+
)}
|
|
177
|
+
{...props}
|
|
178
|
+
/>
|
|
179
|
+
)
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
export {
|
|
183
|
+
Item,
|
|
184
|
+
ItemMedia,
|
|
185
|
+
ItemContent,
|
|
186
|
+
ItemActions,
|
|
187
|
+
ItemGroup,
|
|
188
|
+
ItemSeparator,
|
|
189
|
+
ItemTitle,
|
|
190
|
+
ItemDescription,
|
|
191
|
+
ItemHeader,
|
|
192
|
+
ItemFooter,
|
|
193
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { cn } from "@/lib/utils"
|
|
2
|
+
|
|
3
|
+
function Kbd({ className, ...props }: React.ComponentProps<"kbd">) {
|
|
4
|
+
return (
|
|
5
|
+
<kbd
|
|
6
|
+
data-slot="kbd"
|
|
7
|
+
className={cn(
|
|
8
|
+
"bg-muted text-muted-foreground pointer-events-none inline-flex h-5 w-fit min-w-5 items-center justify-center gap-1 rounded-sm px-1 font-sans text-xs font-medium select-none",
|
|
9
|
+
"[&_svg:not([class*='size-'])]:size-3",
|
|
10
|
+
"[[data-slot=tooltip-content]_&]:bg-background/20 [[data-slot=tooltip-content]_&]:text-background dark:[[data-slot=tooltip-content]_&]:bg-background/10",
|
|
11
|
+
className
|
|
12
|
+
)}
|
|
13
|
+
{...props}
|
|
14
|
+
/>
|
|
15
|
+
)
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
function KbdGroup({ className, ...props }: React.ComponentProps<"div">) {
|
|
19
|
+
return (
|
|
20
|
+
<kbd
|
|
21
|
+
data-slot="kbd-group"
|
|
22
|
+
className={cn("inline-flex items-center gap-1", className)}
|
|
23
|
+
{...props}
|
|
24
|
+
/>
|
|
25
|
+
)
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export { Kbd, KbdGroup }
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
"use client"
|
|
2
|
+
|
|
3
|
+
import * as React from "react"
|
|
4
|
+
import * as LabelPrimitive from "@radix-ui/react-label"
|
|
5
|
+
|
|
6
|
+
import { cn } from "@/lib/utils"
|
|
7
|
+
|
|
8
|
+
function Label({
|
|
9
|
+
className,
|
|
10
|
+
...props
|
|
11
|
+
}: React.ComponentProps<typeof LabelPrimitive.Root>) {
|
|
12
|
+
return (
|
|
13
|
+
<LabelPrimitive.Root
|
|
14
|
+
data-slot="label"
|
|
15
|
+
className={cn(
|
|
16
|
+
"flex items-center gap-2 text-sm leading-none font-normal select-none group-data-[disabled=true]:cursor-not-allowed group-data-[disabled=true]:opacity-50 peer-disabled:cursor-not-allowed peer-disabled:opacity-50",
|
|
17
|
+
className
|
|
18
|
+
)}
|
|
19
|
+
{...props}
|
|
20
|
+
/>
|
|
21
|
+
)
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export { Label }
|