dslinter 0.0.6
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/CHANGELOG.md +76 -0
- package/LICENSE +201 -0
- package/README.md +104 -0
- package/bin/dslinter.mjs +29 -0
- package/components.json +20 -0
- package/package.json +90 -0
- package/src/components/InlineCode.tsx +5 -0
- package/src/components/icons.tsx +121 -0
- package/src/components/ui/badge.tsx +52 -0
- package/src/components/ui/button.tsx +57 -0
- package/src/components/ui/checkbox.tsx +25 -0
- package/src/components/ui/command.tsx +183 -0
- package/src/components/ui/dialog.tsx +156 -0
- package/src/components/ui/hover-card.tsx +42 -0
- package/src/components/ui/input.tsx +22 -0
- package/src/components/ui/label.tsx +19 -0
- package/src/components/ui/select.tsx +149 -0
- package/src/components/ui/table.tsx +118 -0
- package/src/components/ui/toggle-group.tsx +83 -0
- package/src/components/ui/toggle.tsx +45 -0
- package/src/dashboard/ComponentCatalog.tsx +210 -0
- package/src/dashboard/ComponentUsageDetails.tsx +109 -0
- package/src/dashboard/DashboardBody.tsx +71 -0
- package/src/dashboard/FindingsList.tsx +151 -0
- package/src/dashboard/ScoreStrip.tsx +28 -0
- package/src/dashboard/TokenWall.tsx +241 -0
- package/src/dashboard/aggregate.ts +73 -0
- package/src/dashboard/paths.ts +10 -0
- package/src/dashboard/useWorkspaceReport.ts +136 -0
- package/src/index.ts +67 -0
- package/src/lib/utils.ts +6 -0
- package/src/playground/definePlayground.tsx +99 -0
- package/src/playground/enumerateControlCombinations.test.ts +112 -0
- package/src/playground/enumerateControlCombinations.ts +74 -0
- package/src/report/a11yForModule.ts +35 -0
- package/src/report/codeScoreForModule.ts +41 -0
- package/src/report/modulePathMatch.ts +27 -0
- package/src/report/tokenStyleFindingsForModule.ts +24 -0
- package/src/shell/ComponentPlaygroundPane.tsx +438 -0
- package/src/shell/DashboardCommandPalette.tsx +134 -0
- package/src/shell/DashboardLayout.tsx +230 -0
- package/src/shell/EmptyCard.tsx +21 -0
- package/src/shell/GovernancePane.tsx +77 -0
- package/src/shell/PlaygroundA11yAndCode.tsx +387 -0
- package/src/shell/PlaygroundControlField.tsx +213 -0
- package/src/shell/PlaygroundControls.tsx +66 -0
- package/src/shell/PlaygroundUsageCode.tsx +51 -0
- package/src/shell/PlaygroundVariantMatrix.tsx +68 -0
- package/src/shell/Section.tsx +34 -0
- package/src/shell/Sidebar.tsx +203 -0
- package/src/shell/TokensPane.tsx +26 -0
- package/src/shell/controlApiTable.ts +53 -0
- package/src/shell/hashRoute.ts +49 -0
- package/src/shell/playgroundUsageHighlight.ts +53 -0
- package/src/shell/playgroundUsageTwoslash.ts +69 -0
- package/src/shell/useHashRoute.ts +29 -0
- package/src/styles/dashboard-theme.css +188 -0
- package/src/types/controls.ts +62 -0
- package/src/types/defaultTailwindTypography.ts +55 -0
- package/src/types/playground.ts +21 -0
- package/src/types/preview.ts +8 -0
- package/src/types/report.ts +116 -0
- package/src/types/tokenCatalog.ts +54 -0
|
@@ -0,0 +1,52 @@
|
|
|
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
|
+
|
|
7
|
+
const badgeVariants = cva(
|
|
8
|
+
"inline-flex items-center justify-center border font-semibold transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2",
|
|
9
|
+
{
|
|
10
|
+
variants: {
|
|
11
|
+
variant: {
|
|
12
|
+
default:
|
|
13
|
+
"border-transparent bg-primary text-primary-foreground shadow hover:bg-primary/80",
|
|
14
|
+
secondary:
|
|
15
|
+
"border-transparent bg-secondary text-secondary-foreground hover:bg-secondary/80",
|
|
16
|
+
destructive:
|
|
17
|
+
"border-transparent bg-destructive text-destructive-foreground shadow hover:bg-destructive/80",
|
|
18
|
+
outline: "text-foreground",
|
|
19
|
+
},
|
|
20
|
+
size: {
|
|
21
|
+
default: "px-2.5 py-0.5 text-xs rounded-sm",
|
|
22
|
+
sm: "px-1.5 py-0.5 font-mono text-[10px] font-normal leading-tight rounded-sm",
|
|
23
|
+
},
|
|
24
|
+
},
|
|
25
|
+
defaultVariants: {
|
|
26
|
+
variant: "default",
|
|
27
|
+
size: "default",
|
|
28
|
+
},
|
|
29
|
+
},
|
|
30
|
+
);
|
|
31
|
+
|
|
32
|
+
export interface BadgeProps
|
|
33
|
+
extends React.ComponentProps<"span">, VariantProps<typeof badgeVariants> {
|
|
34
|
+
asChild?: boolean;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
const Badge = React.forwardRef<HTMLSpanElement, BadgeProps>(
|
|
38
|
+
({ className, variant, size, asChild = false, ...props }, ref) => {
|
|
39
|
+
const Comp = asChild ? Slot : "span";
|
|
40
|
+
return (
|
|
41
|
+
<Comp
|
|
42
|
+
data-slot="badge"
|
|
43
|
+
className={cn(badgeVariants({ variant, size }), className)}
|
|
44
|
+
ref={ref}
|
|
45
|
+
{...props}
|
|
46
|
+
/>
|
|
47
|
+
);
|
|
48
|
+
},
|
|
49
|
+
);
|
|
50
|
+
Badge.displayName = "Badge";
|
|
51
|
+
|
|
52
|
+
export { Badge, badgeVariants };
|
|
@@ -0,0 +1,57 @@
|
|
|
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
|
+
|
|
7
|
+
const buttonVariants = cva(
|
|
8
|
+
"inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0",
|
|
9
|
+
{
|
|
10
|
+
variants: {
|
|
11
|
+
variant: {
|
|
12
|
+
default: "bg-primary text-primary-foreground hover:bg-primary/90",
|
|
13
|
+
destructive:
|
|
14
|
+
"bg-destructive text-destructive-foreground shadow-xs hover:bg-destructive/90",
|
|
15
|
+
outline:
|
|
16
|
+
"border border-input bg-background shadow-xs hover:bg-accent hover:text-accent-foreground",
|
|
17
|
+
secondary:
|
|
18
|
+
"bg-secondary text-secondary-foreground shadow-xs hover:bg-secondary/80",
|
|
19
|
+
ghost: "hover:bg-accent hover:text-accent-foreground",
|
|
20
|
+
link: "text-primary underline-offset-4 hover:underline",
|
|
21
|
+
},
|
|
22
|
+
size: {
|
|
23
|
+
default: "h-9 px-4 py-2",
|
|
24
|
+
sm: "h-7 rounded-md px-3 text-xs",
|
|
25
|
+
lg: "h-10 rounded-md px-8",
|
|
26
|
+
icon: "h-9 w-9",
|
|
27
|
+
},
|
|
28
|
+
},
|
|
29
|
+
defaultVariants: {
|
|
30
|
+
variant: "default",
|
|
31
|
+
size: "default",
|
|
32
|
+
},
|
|
33
|
+
},
|
|
34
|
+
);
|
|
35
|
+
|
|
36
|
+
export interface ButtonProps
|
|
37
|
+
extends
|
|
38
|
+
React.ButtonHTMLAttributes<HTMLButtonElement>,
|
|
39
|
+
VariantProps<typeof buttonVariants> {
|
|
40
|
+
asChild?: boolean;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(
|
|
44
|
+
({ className, variant, size, asChild = false, ...props }, ref) => {
|
|
45
|
+
const Comp = asChild ? Slot : "button";
|
|
46
|
+
return (
|
|
47
|
+
<Comp
|
|
48
|
+
className={cn(buttonVariants({ variant, size }), className)}
|
|
49
|
+
ref={ref}
|
|
50
|
+
{...props}
|
|
51
|
+
/>
|
|
52
|
+
);
|
|
53
|
+
},
|
|
54
|
+
);
|
|
55
|
+
Button.displayName = "Button";
|
|
56
|
+
|
|
57
|
+
export { Button, buttonVariants };
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
import * as CheckboxPrimitive from "@radix-ui/react-checkbox";
|
|
3
|
+
import { cn } from "../../lib/utils";
|
|
4
|
+
import { IconCheck } from "../icons";
|
|
5
|
+
|
|
6
|
+
const Checkbox = React.forwardRef<
|
|
7
|
+
React.ElementRef<typeof CheckboxPrimitive.Root>,
|
|
8
|
+
React.ComponentPropsWithoutRef<typeof CheckboxPrimitive.Root>
|
|
9
|
+
>(({ className, ...props }, ref) => (
|
|
10
|
+
<CheckboxPrimitive.Root
|
|
11
|
+
ref={ref}
|
|
12
|
+
className={cn(
|
|
13
|
+
"peer grid size-4 shrink-0 place-content-center rounded-sm border border-primary shadow focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50 data-[state=checked]:bg-primary data-[state=checked]:text-primary-foreground",
|
|
14
|
+
className,
|
|
15
|
+
)}
|
|
16
|
+
{...props}
|
|
17
|
+
>
|
|
18
|
+
<CheckboxPrimitive.Indicator className={cn("grid place-content-center text-current")}>
|
|
19
|
+
<IconCheck className="size-4" />
|
|
20
|
+
</CheckboxPrimitive.Indicator>
|
|
21
|
+
</CheckboxPrimitive.Root>
|
|
22
|
+
));
|
|
23
|
+
Checkbox.displayName = CheckboxPrimitive.Root.displayName;
|
|
24
|
+
|
|
25
|
+
export { Checkbox };
|
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
"use client"
|
|
2
|
+
|
|
3
|
+
import * as React from "react"
|
|
4
|
+
import { Command as CommandPrimitive } from "cmdk"
|
|
5
|
+
import { cn } from "../../lib/utils"
|
|
6
|
+
import { IconSearch } from "../icons"
|
|
7
|
+
import {
|
|
8
|
+
Dialog,
|
|
9
|
+
DialogContent,
|
|
10
|
+
DialogDescription,
|
|
11
|
+
DialogHeader,
|
|
12
|
+
DialogTitle,
|
|
13
|
+
} from "./dialog"
|
|
14
|
+
|
|
15
|
+
function Command({
|
|
16
|
+
className,
|
|
17
|
+
...props
|
|
18
|
+
}: React.ComponentProps<typeof CommandPrimitive>) {
|
|
19
|
+
return (
|
|
20
|
+
<CommandPrimitive
|
|
21
|
+
data-slot="command"
|
|
22
|
+
className={cn(
|
|
23
|
+
"flex h-full w-full flex-col overflow-hidden rounded-md bg-popover text-popover-foreground",
|
|
24
|
+
className
|
|
25
|
+
)}
|
|
26
|
+
{...props}
|
|
27
|
+
/>
|
|
28
|
+
)
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
function CommandDialog({
|
|
32
|
+
title = "Command Palette",
|
|
33
|
+
description = "Search for a command to run...",
|
|
34
|
+
children,
|
|
35
|
+
className,
|
|
36
|
+
showCloseButton = true,
|
|
37
|
+
...props
|
|
38
|
+
}: React.ComponentProps<typeof Dialog> & {
|
|
39
|
+
title?: string
|
|
40
|
+
description?: string
|
|
41
|
+
className?: string
|
|
42
|
+
showCloseButton?: boolean
|
|
43
|
+
}) {
|
|
44
|
+
return (
|
|
45
|
+
<Dialog {...props}>
|
|
46
|
+
<DialogHeader className="sr-only">
|
|
47
|
+
<DialogTitle>{title}</DialogTitle>
|
|
48
|
+
<DialogDescription>{description}</DialogDescription>
|
|
49
|
+
</DialogHeader>
|
|
50
|
+
<DialogContent
|
|
51
|
+
className={cn("overflow-hidden p-0", className)}
|
|
52
|
+
showCloseButton={showCloseButton}
|
|
53
|
+
>
|
|
54
|
+
<Command className="**:data-[slot=command-input-wrapper]:h-12 [&_[cmdk-group-heading]]:px-2 [&_[cmdk-group-heading]]:font-medium [&_[cmdk-group-heading]]:text-muted-foreground [&_[cmdk-group]]:px-2 [&_[cmdk-group]:not([hidden])_~[cmdk-group]]:pt-0 [&_[cmdk-input-wrapper]_svg]:h-5 [&_[cmdk-input-wrapper]_svg]:w-5 [&_[cmdk-input]]:h-12 [&_[cmdk-item]]:px-2 [&_[cmdk-item]]:py-3 [&_[cmdk-item]_svg]:h-5 [&_[cmdk-item]_svg]:w-5">
|
|
55
|
+
{children}
|
|
56
|
+
</Command>
|
|
57
|
+
</DialogContent>
|
|
58
|
+
</Dialog>
|
|
59
|
+
)
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
function CommandInput({
|
|
63
|
+
className,
|
|
64
|
+
...props
|
|
65
|
+
}: React.ComponentProps<typeof CommandPrimitive.Input>) {
|
|
66
|
+
return (
|
|
67
|
+
<div
|
|
68
|
+
data-slot="command-input-wrapper"
|
|
69
|
+
className="flex h-9 items-center gap-2 border-b px-3"
|
|
70
|
+
>
|
|
71
|
+
<IconSearch className="size-4 shrink-0 opacity-50" aria-hidden />
|
|
72
|
+
<CommandPrimitive.Input
|
|
73
|
+
data-slot="command-input"
|
|
74
|
+
className={cn(
|
|
75
|
+
"flex h-10 w-full rounded-md bg-transparent py-3 text-sm outline-hidden placeholder:text-muted-foreground disabled:cursor-not-allowed disabled:opacity-50",
|
|
76
|
+
className
|
|
77
|
+
)}
|
|
78
|
+
{...props}
|
|
79
|
+
/>
|
|
80
|
+
</div>
|
|
81
|
+
)
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
function CommandList({
|
|
85
|
+
className,
|
|
86
|
+
...props
|
|
87
|
+
}: React.ComponentProps<typeof CommandPrimitive.List>) {
|
|
88
|
+
return (
|
|
89
|
+
<CommandPrimitive.List
|
|
90
|
+
data-slot="command-list"
|
|
91
|
+
className={cn(
|
|
92
|
+
"max-h-[300px] scroll-py-1 overflow-x-hidden overflow-y-auto",
|
|
93
|
+
className
|
|
94
|
+
)}
|
|
95
|
+
{...props}
|
|
96
|
+
/>
|
|
97
|
+
)
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
function CommandEmpty({
|
|
101
|
+
...props
|
|
102
|
+
}: React.ComponentProps<typeof CommandPrimitive.Empty>) {
|
|
103
|
+
return (
|
|
104
|
+
<CommandPrimitive.Empty
|
|
105
|
+
data-slot="command-empty"
|
|
106
|
+
className="py-6 text-center text-sm"
|
|
107
|
+
{...props}
|
|
108
|
+
/>
|
|
109
|
+
)
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
function CommandGroup({
|
|
113
|
+
className,
|
|
114
|
+
...props
|
|
115
|
+
}: React.ComponentProps<typeof CommandPrimitive.Group>) {
|
|
116
|
+
return (
|
|
117
|
+
<CommandPrimitive.Group
|
|
118
|
+
data-slot="command-group"
|
|
119
|
+
className={cn(
|
|
120
|
+
"overflow-hidden p-1 text-foreground [&_[cmdk-group-heading]]:px-2 [&_[cmdk-group-heading]]:py-1.5 [&_[cmdk-group-heading]]:text-xs [&_[cmdk-group-heading]]:font-medium [&_[cmdk-group-heading]]:text-muted-foreground",
|
|
121
|
+
className
|
|
122
|
+
)}
|
|
123
|
+
{...props}
|
|
124
|
+
/>
|
|
125
|
+
)
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
function CommandSeparator({
|
|
129
|
+
className,
|
|
130
|
+
...props
|
|
131
|
+
}: React.ComponentProps<typeof CommandPrimitive.Separator>) {
|
|
132
|
+
return (
|
|
133
|
+
<CommandPrimitive.Separator
|
|
134
|
+
data-slot="command-separator"
|
|
135
|
+
className={cn("-mx-1 h-px bg-border", className)}
|
|
136
|
+
{...props}
|
|
137
|
+
/>
|
|
138
|
+
)
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
function CommandItem({
|
|
142
|
+
className,
|
|
143
|
+
...props
|
|
144
|
+
}: React.ComponentProps<typeof CommandPrimitive.Item>) {
|
|
145
|
+
return (
|
|
146
|
+
<CommandPrimitive.Item
|
|
147
|
+
data-slot="command-item"
|
|
148
|
+
className={cn(
|
|
149
|
+
"relative flex cursor-default items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-hidden select-none data-[disabled=true]:pointer-events-none data-[disabled=true]:opacity-50 data-[selected=true]:bg-accent data-[selected=true]:text-accent-foreground [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4 [&_svg:not([class*='text-'])]:text-muted-foreground",
|
|
150
|
+
className
|
|
151
|
+
)}
|
|
152
|
+
{...props}
|
|
153
|
+
/>
|
|
154
|
+
)
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
function CommandShortcut({
|
|
158
|
+
className,
|
|
159
|
+
...props
|
|
160
|
+
}: React.ComponentProps<"span">) {
|
|
161
|
+
return (
|
|
162
|
+
<span
|
|
163
|
+
data-slot="command-shortcut"
|
|
164
|
+
className={cn(
|
|
165
|
+
"ml-auto text-xs tracking-widest text-muted-foreground",
|
|
166
|
+
className
|
|
167
|
+
)}
|
|
168
|
+
{...props}
|
|
169
|
+
/>
|
|
170
|
+
)
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
export {
|
|
174
|
+
Command,
|
|
175
|
+
CommandDialog,
|
|
176
|
+
CommandInput,
|
|
177
|
+
CommandList,
|
|
178
|
+
CommandEmpty,
|
|
179
|
+
CommandGroup,
|
|
180
|
+
CommandItem,
|
|
181
|
+
CommandShortcut,
|
|
182
|
+
CommandSeparator,
|
|
183
|
+
}
|
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
import * as React from "react"
|
|
2
|
+
import { Dialog as DialogPrimitive } from "radix-ui"
|
|
3
|
+
|
|
4
|
+
import { cn } from "../../lib/utils"
|
|
5
|
+
import { IconX } from "../icons"
|
|
6
|
+
import { Button } from "./button"
|
|
7
|
+
|
|
8
|
+
function Dialog({
|
|
9
|
+
...props
|
|
10
|
+
}: React.ComponentProps<typeof DialogPrimitive.Root>) {
|
|
11
|
+
return <DialogPrimitive.Root data-slot="dialog" {...props} />
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
function DialogTrigger({
|
|
15
|
+
...props
|
|
16
|
+
}: React.ComponentProps<typeof DialogPrimitive.Trigger>) {
|
|
17
|
+
return <DialogPrimitive.Trigger data-slot="dialog-trigger" {...props} />
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
function DialogPortal({
|
|
21
|
+
...props
|
|
22
|
+
}: React.ComponentProps<typeof DialogPrimitive.Portal>) {
|
|
23
|
+
return <DialogPrimitive.Portal data-slot="dialog-portal" {...props} />
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
function DialogClose({
|
|
27
|
+
...props
|
|
28
|
+
}: React.ComponentProps<typeof DialogPrimitive.Close>) {
|
|
29
|
+
return <DialogPrimitive.Close data-slot="dialog-close" {...props} />
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
function DialogOverlay({
|
|
33
|
+
className,
|
|
34
|
+
...props
|
|
35
|
+
}: React.ComponentProps<typeof DialogPrimitive.Overlay>) {
|
|
36
|
+
return (
|
|
37
|
+
<DialogPrimitive.Overlay
|
|
38
|
+
data-slot="dialog-overlay"
|
|
39
|
+
className={cn(
|
|
40
|
+
"fixed inset-0 z-50 bg-black/50 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:animate-in data-[state=open]:fade-in-0",
|
|
41
|
+
className
|
|
42
|
+
)}
|
|
43
|
+
{...props}
|
|
44
|
+
/>
|
|
45
|
+
)
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
function DialogContent({
|
|
49
|
+
className,
|
|
50
|
+
children,
|
|
51
|
+
showCloseButton = true,
|
|
52
|
+
...props
|
|
53
|
+
}: React.ComponentProps<typeof DialogPrimitive.Content> & {
|
|
54
|
+
showCloseButton?: boolean
|
|
55
|
+
}) {
|
|
56
|
+
return (
|
|
57
|
+
<DialogPortal data-slot="dialog-portal">
|
|
58
|
+
<DialogOverlay />
|
|
59
|
+
<DialogPrimitive.Content
|
|
60
|
+
data-slot="dialog-content"
|
|
61
|
+
className={cn(
|
|
62
|
+
"fixed top-[50%] left-[50%] z-50 grid w-full max-w-[calc(100%-2rem)] translate-x-[-50%] translate-y-[-50%] gap-4 rounded-lg border bg-background p-6 shadow-lg duration-200 outline-none data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[state=open]:animate-in data-[state=open]:fade-in-0 data-[state=open]:zoom-in-95 sm:max-w-lg",
|
|
63
|
+
className
|
|
64
|
+
)}
|
|
65
|
+
{...props}
|
|
66
|
+
>
|
|
67
|
+
{children}
|
|
68
|
+
{showCloseButton && (
|
|
69
|
+
<DialogPrimitive.Close
|
|
70
|
+
data-slot="dialog-close"
|
|
71
|
+
className="absolute top-4 right-4 rounded-xs opacity-70 ring-offset-background transition-opacity hover:opacity-100 focus:ring-2 focus:ring-ring focus:ring-offset-2 focus:outline-hidden disabled:pointer-events-none data-[state=open]:bg-accent data-[state=open]:text-muted-foreground [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4"
|
|
72
|
+
>
|
|
73
|
+
<IconX />
|
|
74
|
+
<span className="sr-only">Close</span>
|
|
75
|
+
</DialogPrimitive.Close>
|
|
76
|
+
)}
|
|
77
|
+
</DialogPrimitive.Content>
|
|
78
|
+
</DialogPortal>
|
|
79
|
+
)
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
function DialogHeader({ className, ...props }: React.ComponentProps<"div">) {
|
|
83
|
+
return (
|
|
84
|
+
<div
|
|
85
|
+
data-slot="dialog-header"
|
|
86
|
+
className={cn("flex flex-col gap-2 text-center sm:text-left", className)}
|
|
87
|
+
{...props}
|
|
88
|
+
/>
|
|
89
|
+
)
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
function DialogFooter({
|
|
93
|
+
className,
|
|
94
|
+
showCloseButton = false,
|
|
95
|
+
children,
|
|
96
|
+
...props
|
|
97
|
+
}: React.ComponentProps<"div"> & {
|
|
98
|
+
showCloseButton?: boolean
|
|
99
|
+
}) {
|
|
100
|
+
return (
|
|
101
|
+
<div
|
|
102
|
+
data-slot="dialog-footer"
|
|
103
|
+
className={cn(
|
|
104
|
+
"flex flex-col-reverse gap-2 sm:flex-row sm:justify-end",
|
|
105
|
+
className
|
|
106
|
+
)}
|
|
107
|
+
{...props}
|
|
108
|
+
>
|
|
109
|
+
{children}
|
|
110
|
+
{showCloseButton && (
|
|
111
|
+
<DialogPrimitive.Close asChild>
|
|
112
|
+
<Button variant="outline">Close</Button>
|
|
113
|
+
</DialogPrimitive.Close>
|
|
114
|
+
)}
|
|
115
|
+
</div>
|
|
116
|
+
)
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
function DialogTitle({
|
|
120
|
+
className,
|
|
121
|
+
...props
|
|
122
|
+
}: React.ComponentProps<typeof DialogPrimitive.Title>) {
|
|
123
|
+
return (
|
|
124
|
+
<DialogPrimitive.Title
|
|
125
|
+
data-slot="dialog-title"
|
|
126
|
+
className={cn("text-lg leading-none font-semibold", className)}
|
|
127
|
+
{...props}
|
|
128
|
+
/>
|
|
129
|
+
)
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
function DialogDescription({
|
|
133
|
+
className,
|
|
134
|
+
...props
|
|
135
|
+
}: React.ComponentProps<typeof DialogPrimitive.Description>) {
|
|
136
|
+
return (
|
|
137
|
+
<DialogPrimitive.Description
|
|
138
|
+
data-slot="dialog-description"
|
|
139
|
+
className={cn("text-sm text-muted-foreground", className)}
|
|
140
|
+
{...props}
|
|
141
|
+
/>
|
|
142
|
+
)
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
export {
|
|
146
|
+
Dialog,
|
|
147
|
+
DialogClose,
|
|
148
|
+
DialogContent,
|
|
149
|
+
DialogDescription,
|
|
150
|
+
DialogFooter,
|
|
151
|
+
DialogHeader,
|
|
152
|
+
DialogOverlay,
|
|
153
|
+
DialogPortal,
|
|
154
|
+
DialogTitle,
|
|
155
|
+
DialogTrigger,
|
|
156
|
+
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
import { HoverCard as HoverCardPrimitive } from "radix-ui";
|
|
3
|
+
|
|
4
|
+
import { cn } from "../../lib/utils";
|
|
5
|
+
|
|
6
|
+
function HoverCard({
|
|
7
|
+
...props
|
|
8
|
+
}: React.ComponentProps<typeof HoverCardPrimitive.Root>) {
|
|
9
|
+
return <HoverCardPrimitive.Root data-slot="hover-card" {...props} />;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
function HoverCardTrigger({
|
|
13
|
+
...props
|
|
14
|
+
}: React.ComponentProps<typeof HoverCardPrimitive.Trigger>) {
|
|
15
|
+
return (
|
|
16
|
+
<HoverCardPrimitive.Trigger data-slot="hover-card-trigger" {...props} />
|
|
17
|
+
);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
function HoverCardContent({
|
|
21
|
+
className,
|
|
22
|
+
align = "center",
|
|
23
|
+
sideOffset = 4,
|
|
24
|
+
...props
|
|
25
|
+
}: React.ComponentProps<typeof HoverCardPrimitive.Content>) {
|
|
26
|
+
return (
|
|
27
|
+
<HoverCardPrimitive.Portal data-slot="hover-card-portal">
|
|
28
|
+
<HoverCardPrimitive.Content
|
|
29
|
+
data-slot="hover-card-content"
|
|
30
|
+
align={align}
|
|
31
|
+
sideOffset={sideOffset}
|
|
32
|
+
className={cn(
|
|
33
|
+
"z-50 w-64 origin-(--radix-hover-card-content-transform-origin) rounded-md border bg-popover p-4 text-popover-foreground shadow-md outline-hidden data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[state=open]:animate-in data-[state=open]:fade-in-0 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",
|
|
34
|
+
className,
|
|
35
|
+
)}
|
|
36
|
+
{...props}
|
|
37
|
+
/>
|
|
38
|
+
</HoverCardPrimitive.Portal>
|
|
39
|
+
);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export { HoverCard, HoverCardTrigger, HoverCardContent };
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
|
|
3
|
+
import { cn } from "../../lib/utils";
|
|
4
|
+
|
|
5
|
+
const Input = React.forwardRef<HTMLInputElement, React.ComponentProps<"input">>(
|
|
6
|
+
({ className, type, ...props }, ref) => {
|
|
7
|
+
return (
|
|
8
|
+
<input
|
|
9
|
+
type={type}
|
|
10
|
+
className={cn(
|
|
11
|
+
"flex h-9 w-full rounded-md border border-input bg-transparent px-3 py-1 text-base shadow-xs transition-colors file:border-0 file:bg-transparent file:text-sm file:font-medium file:text-foreground placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50 md:text-sm",
|
|
12
|
+
className,
|
|
13
|
+
)}
|
|
14
|
+
ref={ref}
|
|
15
|
+
{...props}
|
|
16
|
+
/>
|
|
17
|
+
);
|
|
18
|
+
},
|
|
19
|
+
);
|
|
20
|
+
Input.displayName = "Input";
|
|
21
|
+
|
|
22
|
+
export { Input };
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
import * as LabelPrimitive from "@radix-ui/react-label";
|
|
3
|
+
import { cva, type VariantProps } from "class-variance-authority";
|
|
4
|
+
|
|
5
|
+
import { cn } from "../../lib/utils";
|
|
6
|
+
|
|
7
|
+
const labelVariants = cva(
|
|
8
|
+
"text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70",
|
|
9
|
+
);
|
|
10
|
+
|
|
11
|
+
const Label = React.forwardRef<
|
|
12
|
+
React.ElementRef<typeof LabelPrimitive.Root>,
|
|
13
|
+
React.ComponentPropsWithoutRef<typeof LabelPrimitive.Root> & VariantProps<typeof labelVariants>
|
|
14
|
+
>(({ className, ...props }, ref) => (
|
|
15
|
+
<LabelPrimitive.Root ref={ref} className={cn(labelVariants(), className)} {...props} />
|
|
16
|
+
));
|
|
17
|
+
Label.displayName = LabelPrimitive.Root.displayName;
|
|
18
|
+
|
|
19
|
+
export { Label };
|