@traky-app/ui 0.0.0-stage → 1.0.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/README.md +30 -2
- package/package.json +26 -4
- package/registry/registry.json +6 -0
- package/registry/traky/hooks/use-mobile.ts +19 -0
- package/registry/traky/json/accordion.json +18 -0
- package/registry/traky/json/alert-dialog.json +20 -0
- package/registry/traky/json/alert.json +17 -0
- package/registry/traky/json/animated-beam.json +14 -0
- package/registry/traky/json/animated-list.json +14 -0
- package/registry/traky/json/avatar.json +17 -0
- package/registry/traky/json/badge.json +18 -0
- package/registry/traky/json/bento-grid.json +20 -0
- package/registry/traky/json/breadcrumb.json +18 -0
- package/registry/traky/json/bubble.json +18 -0
- package/registry/traky/json/button-group.json +21 -0
- package/registry/traky/json/button.json +18 -0
- package/registry/traky/json/calendar.json +21 -0
- package/registry/traky/json/card.json +14 -0
- package/registry/traky/json/carousel.json +21 -0
- package/registry/traky/json/chart.json +17 -0
- package/registry/traky/json/checkbox.json +18 -0
- package/registry/traky/json/checkpoint.json +22 -0
- package/registry/traky/json/code-block.json +21 -0
- package/registry/traky/json/collapsible.json +17 -0
- package/registry/traky/json/command.json +22 -0
- package/registry/traky/json/context-menu.json +18 -0
- package/registry/traky/json/dialog.json +18 -0
- package/registry/traky/json/drawer.json +17 -0
- package/registry/traky/json/dropdown-menu.json +18 -0
- package/registry/traky/json/empty.json +17 -0
- package/registry/traky/json/field.json +21 -0
- package/registry/traky/json/globe.json +17 -0
- package/registry/traky/json/hook-use-mobile.json +14 -0
- package/registry/traky/json/hover-card.json +17 -0
- package/registry/traky/json/input-group.json +22 -0
- package/registry/traky/json/input-otp.json +18 -0
- package/registry/traky/json/input.json +17 -0
- package/registry/traky/json/item.json +21 -0
- package/registry/traky/json/kbd.json +14 -0
- package/registry/traky/json/label.json +17 -0
- package/registry/traky/json/lib-disable-input-autofill.json +14 -0
- package/registry/traky/json/lib-sidebar-persistence.json +14 -0
- package/registry/traky/json/lib-utils.json +18 -0
- package/registry/traky/json/map.json +19 -0
- package/registry/traky/json/marker.json +18 -0
- package/registry/traky/json/marquee.json +14 -0
- package/registry/traky/json/message.json +14 -0
- package/registry/traky/json/navigation-menu.json +19 -0
- package/registry/traky/json/number-ticker.json +14 -0
- package/registry/traky/json/pagination.json +20 -0
- package/registry/traky/json/popover.json +17 -0
- package/registry/traky/json/progress.json +17 -0
- package/registry/traky/json/select.json +18 -0
- package/registry/traky/json/separator.json +17 -0
- package/registry/traky/json/sheet.json +18 -0
- package/registry/traky/json/sidebar.json +29 -0
- package/registry/traky/json/skeleton.json +14 -0
- package/registry/traky/json/sonner.json +18 -0
- package/registry/traky/json/spinner.json +17 -0
- package/registry/traky/json/switch.json +17 -0
- package/registry/traky/json/table.json +14 -0
- package/registry/traky/json/tabs.json +17 -0
- package/registry/traky/json/textarea.json +17 -0
- package/registry/traky/json/toggle-group.json +21 -0
- package/registry/traky/json/toggle.json +18 -0
- package/registry/traky/json/tooltip.json +17 -0
- package/registry/traky/json/trace.json +20 -0
- package/registry/traky/lib/disable-input-autofill.ts +23 -0
- package/registry/traky/lib/sidebar-persistence.ts +76 -0
- package/registry/traky/lib/utils.ts +6 -0
- package/registry/traky/registry.json +637 -0
- package/registry/traky/ui/accordion.tsx +65 -0
- package/registry/traky/ui/alert-dialog.tsx +163 -0
- package/registry/traky/ui/alert.tsx +66 -0
- package/registry/traky/ui/animated-beam.tsx +185 -0
- package/registry/traky/ui/animated-list.tsx +71 -0
- package/registry/traky/ui/avatar.tsx +53 -0
- package/registry/traky/ui/badge.tsx +46 -0
- package/registry/traky/ui/bento-grid.tsx +109 -0
- package/registry/traky/ui/breadcrumb.tsx +108 -0
- package/registry/traky/ui/bubble.tsx +125 -0
- package/registry/traky/ui/button-group.tsx +83 -0
- package/registry/traky/ui/button.tsx +64 -0
- package/registry/traky/ui/calendar.tsx +213 -0
- package/registry/traky/ui/card.tsx +92 -0
- package/registry/traky/ui/carousel.tsx +240 -0
- package/registry/traky/ui/chart.tsx +380 -0
- package/registry/traky/ui/checkbox.tsx +31 -0
- package/registry/traky/ui/checkpoint.tsx +94 -0
- package/registry/traky/ui/code-block.tsx +232 -0
- package/registry/traky/ui/collapsible.tsx +33 -0
- package/registry/traky/ui/command.tsx +190 -0
- package/registry/traky/ui/context-menu.tsx +251 -0
- package/registry/traky/ui/dialog.tsx +142 -0
- package/registry/traky/ui/drawer.tsx +135 -0
- package/registry/traky/ui/dropdown-menu.tsx +256 -0
- package/registry/traky/ui/empty.tsx +104 -0
- package/registry/traky/ui/field.tsx +248 -0
- package/registry/traky/ui/globe.tsx +234 -0
- package/registry/traky/ui/hover-card.tsx +44 -0
- package/registry/traky/ui/input-group.tsx +170 -0
- package/registry/traky/ui/input-otp.tsx +77 -0
- package/registry/traky/ui/input.tsx +24 -0
- package/registry/traky/ui/item.tsx +193 -0
- package/registry/traky/ui/kbd.tsx +28 -0
- package/registry/traky/ui/label.tsx +24 -0
- package/registry/traky/ui/map.tsx +2226 -0
- package/registry/traky/ui/marker.tsx +69 -0
- package/registry/traky/ui/marquee.tsx +74 -0
- package/registry/traky/ui/message.tsx +92 -0
- package/registry/traky/ui/navigation-menu.tsx +169 -0
- package/registry/traky/ui/number-ticker.tsx +90 -0
- package/registry/traky/ui/pagination.tsx +122 -0
- package/registry/traky/ui/popover.tsx +48 -0
- package/registry/traky/ui/progress.tsx +31 -0
- package/registry/traky/ui/select.tsx +193 -0
- package/registry/traky/ui/separator.tsx +28 -0
- package/registry/traky/ui/sheet.tsx +143 -0
- package/registry/traky/ui/sidebar.tsx +764 -0
- package/registry/traky/ui/skeleton.tsx +13 -0
- package/registry/traky/ui/sonner.tsx +71 -0
- package/registry/traky/ui/spinner.tsx +15 -0
- package/registry/traky/ui/switch.tsx +41 -0
- package/registry/traky/ui/table.tsx +116 -0
- package/registry/traky/ui/tabs.tsx +66 -0
- package/registry/traky/ui/textarea.tsx +20 -0
- package/registry/traky/ui/toggle-group.tsx +83 -0
- package/registry/traky/ui/toggle.tsx +47 -0
- package/registry/traky/ui/tooltip.tsx +61 -0
- package/registry/traky/ui/trace.tsx +165 -0
- package/schema/components.json +24 -0
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
"use client"
|
|
2
|
+
|
|
3
|
+
import * as React from "react"
|
|
4
|
+
import { IconBookmark } from "@tabler/icons-react"
|
|
5
|
+
|
|
6
|
+
import { Button } from "@/components/ui/button"
|
|
7
|
+
import { Marker, MarkerContent, MarkerIcon } from "@/components/ui/marker"
|
|
8
|
+
import {
|
|
9
|
+
Tooltip,
|
|
10
|
+
TooltipContent,
|
|
11
|
+
TooltipProvider,
|
|
12
|
+
TooltipTrigger,
|
|
13
|
+
} from "@/components/ui/tooltip"
|
|
14
|
+
import { cn } from "@/lib/utils"
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Checkpoint (AI Element): punto de restauración en un hilo.
|
|
18
|
+
* Compuesto con Marker + Button — https://ui.shadcn.com/docs/ai-elements/base/checkpoint
|
|
19
|
+
*/
|
|
20
|
+
function Checkpoint({
|
|
21
|
+
className,
|
|
22
|
+
...props
|
|
23
|
+
}: React.ComponentProps<typeof Marker>) {
|
|
24
|
+
return (
|
|
25
|
+
<Marker
|
|
26
|
+
data-slot="checkpoint"
|
|
27
|
+
variant="separator"
|
|
28
|
+
className={cn(className)}
|
|
29
|
+
{...props}
|
|
30
|
+
/>
|
|
31
|
+
)
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
function CheckpointIcon({
|
|
35
|
+
className,
|
|
36
|
+
children,
|
|
37
|
+
...props
|
|
38
|
+
}: React.ComponentProps<typeof MarkerIcon>) {
|
|
39
|
+
return (
|
|
40
|
+
<MarkerIcon data-slot="checkpoint-icon" className={className} {...props}>
|
|
41
|
+
{children ?? <IconBookmark />}
|
|
42
|
+
</MarkerIcon>
|
|
43
|
+
)
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
function CheckpointTrigger({
|
|
47
|
+
className,
|
|
48
|
+
children = "Restore",
|
|
49
|
+
tooltip,
|
|
50
|
+
...props
|
|
51
|
+
}: React.ComponentProps<typeof Button> & {
|
|
52
|
+
tooltip?: string
|
|
53
|
+
}) {
|
|
54
|
+
const button = (
|
|
55
|
+
<Button
|
|
56
|
+
data-slot="checkpoint-trigger"
|
|
57
|
+
type="button"
|
|
58
|
+
size="xs"
|
|
59
|
+
variant="outline"
|
|
60
|
+
className={cn(className)}
|
|
61
|
+
{...props}
|
|
62
|
+
>
|
|
63
|
+
{children}
|
|
64
|
+
</Button>
|
|
65
|
+
)
|
|
66
|
+
|
|
67
|
+
if (!tooltip) {
|
|
68
|
+
return button
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
return (
|
|
72
|
+
<TooltipProvider>
|
|
73
|
+
<Tooltip>
|
|
74
|
+
<TooltipTrigger asChild>{button}</TooltipTrigger>
|
|
75
|
+
<TooltipContent>{tooltip}</TooltipContent>
|
|
76
|
+
</Tooltip>
|
|
77
|
+
</TooltipProvider>
|
|
78
|
+
)
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
function CheckpointContent({
|
|
82
|
+
className,
|
|
83
|
+
...props
|
|
84
|
+
}: React.ComponentProps<typeof MarkerContent>) {
|
|
85
|
+
return (
|
|
86
|
+
<MarkerContent
|
|
87
|
+
data-slot="checkpoint-content"
|
|
88
|
+
className={cn("inline-flex items-center gap-2", className)}
|
|
89
|
+
{...props}
|
|
90
|
+
/>
|
|
91
|
+
)
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
export { Checkpoint, CheckpointIcon, CheckpointContent, CheckpointTrigger }
|
|
@@ -0,0 +1,232 @@
|
|
|
1
|
+
"use client"
|
|
2
|
+
|
|
3
|
+
import * as React from "react"
|
|
4
|
+
import { IconCheck, IconCopy } from "@tabler/icons-react"
|
|
5
|
+
import { cva, type VariantProps } from "class-variance-authority"
|
|
6
|
+
|
|
7
|
+
import { cn } from "@/lib/utils"
|
|
8
|
+
import { Button } from "@/components/ui/button"
|
|
9
|
+
|
|
10
|
+
const codeBlockVariants = cva(
|
|
11
|
+
"group/code-block relative flex w-full min-w-0 flex-col overflow-hidden rounded-lg text-sm has-[>[data-slot=code-block-content]:focus-visible]:ring-3 has-[>[data-slot=code-block-content]:focus-visible]:ring-ring/50 data-[size=sm]:text-xs",
|
|
12
|
+
{
|
|
13
|
+
variants: {
|
|
14
|
+
variant: {
|
|
15
|
+
default:
|
|
16
|
+
"border border-input bg-background text-foreground has-[>[data-slot=code-block-content]:focus-visible]:border-ring dark:bg-input/30",
|
|
17
|
+
destructive:
|
|
18
|
+
"border border-destructive/30 bg-background text-destructive dark:border-destructive/40",
|
|
19
|
+
},
|
|
20
|
+
},
|
|
21
|
+
defaultVariants: {
|
|
22
|
+
variant: "default",
|
|
23
|
+
},
|
|
24
|
+
}
|
|
25
|
+
)
|
|
26
|
+
|
|
27
|
+
function CodeBlock({
|
|
28
|
+
className,
|
|
29
|
+
variant = "default",
|
|
30
|
+
size = "default",
|
|
31
|
+
...props
|
|
32
|
+
}: React.ComponentProps<"div"> &
|
|
33
|
+
VariantProps<typeof codeBlockVariants> & { size?: "default" | "sm" }) {
|
|
34
|
+
return (
|
|
35
|
+
<div
|
|
36
|
+
data-slot="code-block"
|
|
37
|
+
data-variant={variant}
|
|
38
|
+
data-size={size}
|
|
39
|
+
className={cn(codeBlockVariants({ variant }), className)}
|
|
40
|
+
{...props}
|
|
41
|
+
/>
|
|
42
|
+
)
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
function CodeBlockHeader({ className, ...props }: React.ComponentProps<"div">) {
|
|
46
|
+
return (
|
|
47
|
+
<div
|
|
48
|
+
data-slot="code-block-header"
|
|
49
|
+
className={cn(
|
|
50
|
+
"flex min-w-0 shrink-0 items-center gap-2 px-3 pt-3 text-muted-foreground group-data-[size=sm]/code-block:px-2.5 group-data-[size=sm]/code-block:pt-2.5 group-data-[variant=destructive]/code-block:text-destructive *:has-[>[data-slot=code-block-title]]:min-w-0",
|
|
51
|
+
className
|
|
52
|
+
)}
|
|
53
|
+
{...props}
|
|
54
|
+
/>
|
|
55
|
+
)
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
function CodeBlockTitle({ className, ...props }: React.ComponentProps<"div">) {
|
|
59
|
+
return (
|
|
60
|
+
<div
|
|
61
|
+
data-slot="code-block-title"
|
|
62
|
+
className={cn(
|
|
63
|
+
"min-w-0 truncate font-sans text-sm font-medium text-foreground group-data-[size=sm]/code-block:text-xs group-data-[variant=destructive]/code-block:text-destructive [&_svg]:pointer-events-none [&_svg]:inline-block [&_svg]:align-middle [&_svg:not([class*='size-'])]:size-3.5 *:[svg]:me-1.5",
|
|
64
|
+
className
|
|
65
|
+
)}
|
|
66
|
+
{...props}
|
|
67
|
+
/>
|
|
68
|
+
)
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
function CodeBlockActions({
|
|
72
|
+
className,
|
|
73
|
+
...props
|
|
74
|
+
}: React.ComponentProps<"div">) {
|
|
75
|
+
return (
|
|
76
|
+
<div
|
|
77
|
+
data-slot="code-block-actions"
|
|
78
|
+
className={cn(
|
|
79
|
+
"-my-1 ms-auto -me-1.5 flex shrink-0 items-center gap-1 [[data-slot=code-block]>&]:absolute [[data-slot=code-block]>&]:end-2 [[data-slot=code-block]>&]:top-2 [[data-slot=code-block]>&]:z-10 [[data-slot=code-block]>&]:m-0 [[data-slot=code-block]>&]:opacity-0 [[data-slot=code-block]>&]:transition-opacity [[data-slot=code-block]>&]:group-focus-within/code-block:opacity-100 [[data-slot=code-block]>&]:group-hover/code-block:opacity-100 group-data-[size=sm]/code-block:-me-1",
|
|
80
|
+
className
|
|
81
|
+
)}
|
|
82
|
+
{...props}
|
|
83
|
+
/>
|
|
84
|
+
)
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
function CodeBlockCopyButton({
|
|
88
|
+
value,
|
|
89
|
+
className,
|
|
90
|
+
...props
|
|
91
|
+
}: Omit<React.ComponentProps<typeof Button>, "children" | "onClick"> & {
|
|
92
|
+
value: string
|
|
93
|
+
}) {
|
|
94
|
+
const [copied, setCopied] = React.useState(false)
|
|
95
|
+
|
|
96
|
+
return (
|
|
97
|
+
<>
|
|
98
|
+
<Button
|
|
99
|
+
type="button"
|
|
100
|
+
variant="ghost"
|
|
101
|
+
size="icon-xs"
|
|
102
|
+
className={cn("text-muted-foreground", className)}
|
|
103
|
+
onClick={async () => {
|
|
104
|
+
try {
|
|
105
|
+
await navigator.clipboard.writeText(value)
|
|
106
|
+
setCopied(true)
|
|
107
|
+
window.setTimeout(() => setCopied(false), 1500)
|
|
108
|
+
} catch {
|
|
109
|
+
// ignore
|
|
110
|
+
}
|
|
111
|
+
}}
|
|
112
|
+
{...props}
|
|
113
|
+
>
|
|
114
|
+
{copied ? <IconCheck /> : <IconCopy />}
|
|
115
|
+
</Button>
|
|
116
|
+
<span aria-live="polite" className="sr-only">
|
|
117
|
+
{copied ? "Copied" : ""}
|
|
118
|
+
</span>
|
|
119
|
+
</>
|
|
120
|
+
)
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
function CodeBlockContent({
|
|
124
|
+
className,
|
|
125
|
+
children,
|
|
126
|
+
style,
|
|
127
|
+
wrap = false,
|
|
128
|
+
lineNumbers = false,
|
|
129
|
+
startLine = 1,
|
|
130
|
+
...props
|
|
131
|
+
}: React.ComponentProps<"pre"> & {
|
|
132
|
+
wrap?: boolean
|
|
133
|
+
lineNumbers?: boolean
|
|
134
|
+
startLine?: number
|
|
135
|
+
}) {
|
|
136
|
+
return (
|
|
137
|
+
<pre
|
|
138
|
+
data-slot="code-block-content"
|
|
139
|
+
data-wrap={wrap || undefined}
|
|
140
|
+
data-numbered={lineNumbers || undefined}
|
|
141
|
+
dir="ltr"
|
|
142
|
+
tabIndex={0}
|
|
143
|
+
style={{ counterReset: `line ${startLine - 1}`, ...style }}
|
|
144
|
+
className={cn(
|
|
145
|
+
"min-h-0 min-w-0 overflow-auto px-3 py-3 text-start font-mono leading-relaxed outline-none group-has-data-[slot=code-block-footer]/code-block:pb-2 group-has-data-[slot=code-block-header]/code-block:pt-2 group-data-[size=sm]/code-block:px-2.5 group-data-[size=sm]/code-block:py-2.5 group-data-[size=sm]/code-block:group-has-data-[slot=code-block-header]/code-block:pt-1.5 data-wrap:wrap-break-word data-wrap:whitespace-pre-wrap",
|
|
146
|
+
className
|
|
147
|
+
)}
|
|
148
|
+
{...props}
|
|
149
|
+
>
|
|
150
|
+
<code
|
|
151
|
+
data-slot="code-block-code"
|
|
152
|
+
className="grid min-h-lh min-w-max content-start in-data-wrap:min-w-0"
|
|
153
|
+
>
|
|
154
|
+
{lineNumbers && typeof children === "string"
|
|
155
|
+
? children
|
|
156
|
+
.replace(/\n$/, "")
|
|
157
|
+
.split("\n")
|
|
158
|
+
.map((line, index) => (
|
|
159
|
+
<CodeBlockLine key={index}>{line}</CodeBlockLine>
|
|
160
|
+
))
|
|
161
|
+
: children}
|
|
162
|
+
</code>
|
|
163
|
+
</pre>
|
|
164
|
+
)
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
const codeBlockLineVariants = cva(
|
|
168
|
+
"relative -mx-3 block min-h-lh px-3 group-data-[size=sm]/code-block:-mx-2.5 group-data-[size=sm]/code-block:px-2.5 before:min-w-6 before:text-end before:text-muted-foreground after:absolute after:start-1 after:top-0 after:text-muted-foreground after:select-none in-data-numbered:col-span-2 in-data-numbered:grid in-data-numbered:grid-cols-subgrid in-data-numbered:gap-x-3 in-data-numbered:[counter-increment:line] in-data-numbered:before:content-[counter(line)] in-data-numbered:before:select-none",
|
|
169
|
+
{
|
|
170
|
+
variants: {
|
|
171
|
+
variant: {
|
|
172
|
+
default: "",
|
|
173
|
+
added: "bg-muted after:content-['+']",
|
|
174
|
+
removed: "bg-destructive/10 after:text-destructive after:content-['−']",
|
|
175
|
+
highlighted: "bg-muted",
|
|
176
|
+
},
|
|
177
|
+
},
|
|
178
|
+
defaultVariants: {
|
|
179
|
+
variant: "default",
|
|
180
|
+
},
|
|
181
|
+
}
|
|
182
|
+
)
|
|
183
|
+
|
|
184
|
+
function CodeBlockLine({
|
|
185
|
+
className,
|
|
186
|
+
variant = "default",
|
|
187
|
+
children,
|
|
188
|
+
...props
|
|
189
|
+
}: React.ComponentProps<"span"> & VariantProps<typeof codeBlockLineVariants>) {
|
|
190
|
+
const empty =
|
|
191
|
+
children === undefined ||
|
|
192
|
+
children === null ||
|
|
193
|
+
children === "" ||
|
|
194
|
+
(Array.isArray(children) && children.length === 0)
|
|
195
|
+
|
|
196
|
+
return (
|
|
197
|
+
<span
|
|
198
|
+
data-slot="code-block-line"
|
|
199
|
+
data-variant={variant}
|
|
200
|
+
className={cn(codeBlockLineVariants({ variant }), className)}
|
|
201
|
+
{...props}
|
|
202
|
+
>
|
|
203
|
+
<span data-slot="code-block-line-content" className="min-w-0">
|
|
204
|
+
{empty ? "\n" : children}
|
|
205
|
+
</span>
|
|
206
|
+
</span>
|
|
207
|
+
)
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
function CodeBlockFooter({ className, ...props }: React.ComponentProps<"div">) {
|
|
211
|
+
return (
|
|
212
|
+
<div
|
|
213
|
+
data-slot="code-block-footer"
|
|
214
|
+
className={cn(
|
|
215
|
+
"flex min-w-0 shrink-0 items-center gap-2 px-3 pb-3 text-muted-foreground group-data-[size=sm]/code-block:px-2.5 group-data-[size=sm]/code-block:pb-2.5",
|
|
216
|
+
className
|
|
217
|
+
)}
|
|
218
|
+
{...props}
|
|
219
|
+
/>
|
|
220
|
+
)
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
export {
|
|
224
|
+
CodeBlock,
|
|
225
|
+
CodeBlockHeader,
|
|
226
|
+
CodeBlockTitle,
|
|
227
|
+
CodeBlockActions,
|
|
228
|
+
CodeBlockCopyButton,
|
|
229
|
+
CodeBlockContent,
|
|
230
|
+
CodeBlockLine,
|
|
231
|
+
CodeBlockFooter,
|
|
232
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
"use client"
|
|
2
|
+
|
|
3
|
+
import * as CollapsiblePrimitive from "@radix-ui/react-collapsible"
|
|
4
|
+
|
|
5
|
+
function Collapsible({
|
|
6
|
+
...props
|
|
7
|
+
}: React.ComponentProps<typeof CollapsiblePrimitive.Root>) {
|
|
8
|
+
return <CollapsiblePrimitive.Root data-slot="collapsible" {...props} />
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
function CollapsibleTrigger({
|
|
12
|
+
...props
|
|
13
|
+
}: React.ComponentProps<typeof CollapsiblePrimitive.CollapsibleTrigger>) {
|
|
14
|
+
return (
|
|
15
|
+
<CollapsiblePrimitive.CollapsibleTrigger
|
|
16
|
+
data-slot="collapsible-trigger"
|
|
17
|
+
{...props}
|
|
18
|
+
/>
|
|
19
|
+
)
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
function CollapsibleContent({
|
|
23
|
+
...props
|
|
24
|
+
}: React.ComponentProps<typeof CollapsiblePrimitive.CollapsibleContent>) {
|
|
25
|
+
return (
|
|
26
|
+
<CollapsiblePrimitive.CollapsibleContent
|
|
27
|
+
data-slot="collapsible-content"
|
|
28
|
+
{...props}
|
|
29
|
+
/>
|
|
30
|
+
)
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export { Collapsible, CollapsibleTrigger, CollapsibleContent }
|
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
"use client"
|
|
2
|
+
|
|
3
|
+
import { IconSearch } from "@tabler/icons-react";
|
|
4
|
+
import * as React from "react"
|
|
5
|
+
import { Command as CommandPrimitive } from "cmdk"
|
|
6
|
+
import { DISABLE_INPUT_AUTOFILL } from "@/lib/disable-input-autofill"
|
|
7
|
+
import { cn } from "@/lib/utils"
|
|
8
|
+
import {
|
|
9
|
+
Dialog,
|
|
10
|
+
DialogContent,
|
|
11
|
+
DialogDescription,
|
|
12
|
+
DialogHeader,
|
|
13
|
+
DialogTitle,
|
|
14
|
+
} from "@/components/ui/dialog"
|
|
15
|
+
|
|
16
|
+
function Command({
|
|
17
|
+
className,
|
|
18
|
+
...props
|
|
19
|
+
}: React.ComponentProps<typeof CommandPrimitive>) {
|
|
20
|
+
return (
|
|
21
|
+
<CommandPrimitive
|
|
22
|
+
data-slot="command"
|
|
23
|
+
className={cn(
|
|
24
|
+
"bg-popover text-popover-foreground flex h-full w-full flex-col overflow-hidden rounded-md",
|
|
25
|
+
className
|
|
26
|
+
)}
|
|
27
|
+
{...props}
|
|
28
|
+
/>
|
|
29
|
+
)
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
function CommandDialog({
|
|
33
|
+
title = "Command Palette",
|
|
34
|
+
description = "Search for a command to run...",
|
|
35
|
+
children,
|
|
36
|
+
className,
|
|
37
|
+
showCloseButton = true,
|
|
38
|
+
...props
|
|
39
|
+
}: React.ComponentProps<typeof Dialog> & {
|
|
40
|
+
title?: string
|
|
41
|
+
description?: string
|
|
42
|
+
className?: string
|
|
43
|
+
showCloseButton?: boolean
|
|
44
|
+
}) {
|
|
45
|
+
return (
|
|
46
|
+
<Dialog {...props}>
|
|
47
|
+
<DialogHeader className="sr-only">
|
|
48
|
+
<DialogTitle>{title}</DialogTitle>
|
|
49
|
+
<DialogDescription>{description}</DialogDescription>
|
|
50
|
+
</DialogHeader>
|
|
51
|
+
<DialogContent
|
|
52
|
+
className={cn("overflow-hidden p-0", className)}
|
|
53
|
+
showCloseButton={showCloseButton}
|
|
54
|
+
>
|
|
55
|
+
<Command className="[&_[cmdk-group-heading]]:text-muted-foreground **:data-[slot=command-input-wrapper]:h-12 [&_[cmdk-group-heading]]:px-2 [&_[cmdk-group-heading]]:font-medium [&_[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">
|
|
56
|
+
{children}
|
|
57
|
+
</Command>
|
|
58
|
+
</DialogContent>
|
|
59
|
+
</Dialog>
|
|
60
|
+
)
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
function CommandInput({
|
|
64
|
+
className,
|
|
65
|
+
name,
|
|
66
|
+
...props
|
|
67
|
+
}: React.ComponentProps<typeof CommandPrimitive.Input>) {
|
|
68
|
+
return (
|
|
69
|
+
<div
|
|
70
|
+
data-slot="command-input-wrapper"
|
|
71
|
+
className="flex h-9 items-center gap-2 border-b px-3"
|
|
72
|
+
>
|
|
73
|
+
<IconSearch className="size-4 shrink-0 opacity-50" />
|
|
74
|
+
<CommandPrimitive.Input
|
|
75
|
+
data-slot="command-input"
|
|
76
|
+
// type=search + anti-autofill: evita iCloud Password / gestores
|
|
77
|
+
// en “Buscar usuario”, “Buscar dirección”, etc.
|
|
78
|
+
{...DISABLE_INPUT_AUTOFILL}
|
|
79
|
+
enterKeyHint="search"
|
|
80
|
+
name={name ?? "traky-command-search"}
|
|
81
|
+
className={cn(
|
|
82
|
+
"placeholder:text-muted-foreground flex h-10 w-full rounded-md bg-transparent py-3 text-sm outline-hidden disabled:cursor-not-allowed disabled:opacity-50",
|
|
83
|
+
className
|
|
84
|
+
)}
|
|
85
|
+
{...props}
|
|
86
|
+
/>
|
|
87
|
+
</div>
|
|
88
|
+
)
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
function CommandList({
|
|
92
|
+
className,
|
|
93
|
+
...props
|
|
94
|
+
}: React.ComponentProps<typeof CommandPrimitive.List>) {
|
|
95
|
+
return (
|
|
96
|
+
<CommandPrimitive.List
|
|
97
|
+
data-slot="command-list"
|
|
98
|
+
className={cn(
|
|
99
|
+
"max-h-[300px] scroll-py-1 overflow-x-hidden overflow-y-auto",
|
|
100
|
+
className
|
|
101
|
+
)}
|
|
102
|
+
{...props}
|
|
103
|
+
/>
|
|
104
|
+
)
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
function CommandEmpty({
|
|
108
|
+
...props
|
|
109
|
+
}: React.ComponentProps<typeof CommandPrimitive.Empty>) {
|
|
110
|
+
return (
|
|
111
|
+
<CommandPrimitive.Empty
|
|
112
|
+
data-slot="command-empty"
|
|
113
|
+
className="py-6 text-center text-sm"
|
|
114
|
+
{...props}
|
|
115
|
+
/>
|
|
116
|
+
)
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
function CommandGroup({
|
|
120
|
+
className,
|
|
121
|
+
...props
|
|
122
|
+
}: React.ComponentProps<typeof CommandPrimitive.Group>) {
|
|
123
|
+
return (
|
|
124
|
+
<CommandPrimitive.Group
|
|
125
|
+
data-slot="command-group"
|
|
126
|
+
className={cn(
|
|
127
|
+
"text-foreground [&_[cmdk-group-heading]]:text-muted-foreground overflow-hidden p-1 [&_[cmdk-group-heading]]:px-2 [&_[cmdk-group-heading]]:py-1.5 [&_[cmdk-group-heading]]:text-xs [&_[cmdk-group-heading]]:font-medium",
|
|
128
|
+
className
|
|
129
|
+
)}
|
|
130
|
+
{...props}
|
|
131
|
+
/>
|
|
132
|
+
)
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
function CommandSeparator({
|
|
136
|
+
className,
|
|
137
|
+
...props
|
|
138
|
+
}: React.ComponentProps<typeof CommandPrimitive.Separator>) {
|
|
139
|
+
return (
|
|
140
|
+
<CommandPrimitive.Separator
|
|
141
|
+
data-slot="command-separator"
|
|
142
|
+
className={cn("bg-border -mx-1 h-px", className)}
|
|
143
|
+
{...props}
|
|
144
|
+
/>
|
|
145
|
+
)
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
function CommandItem({
|
|
149
|
+
className,
|
|
150
|
+
...props
|
|
151
|
+
}: React.ComponentProps<typeof CommandPrimitive.Item>) {
|
|
152
|
+
return (
|
|
153
|
+
<CommandPrimitive.Item
|
|
154
|
+
data-slot="command-item"
|
|
155
|
+
className={cn(
|
|
156
|
+
"data-[selected=true]:bg-accent data-[selected=true]:text-accent-foreground [&_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=true]:pointer-events-none data-[disabled=true]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
|
|
157
|
+
className
|
|
158
|
+
)}
|
|
159
|
+
{...props}
|
|
160
|
+
/>
|
|
161
|
+
)
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
function CommandShortcut({
|
|
165
|
+
className,
|
|
166
|
+
...props
|
|
167
|
+
}: React.ComponentProps<"span">) {
|
|
168
|
+
return (
|
|
169
|
+
<span
|
|
170
|
+
data-slot="command-shortcut"
|
|
171
|
+
className={cn(
|
|
172
|
+
"text-muted-foreground ml-auto text-xs tracking-widest",
|
|
173
|
+
className
|
|
174
|
+
)}
|
|
175
|
+
{...props}
|
|
176
|
+
/>
|
|
177
|
+
)
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
export {
|
|
181
|
+
Command,
|
|
182
|
+
CommandDialog,
|
|
183
|
+
CommandInput,
|
|
184
|
+
CommandList,
|
|
185
|
+
CommandEmpty,
|
|
186
|
+
CommandGroup,
|
|
187
|
+
CommandItem,
|
|
188
|
+
CommandShortcut,
|
|
189
|
+
CommandSeparator,
|
|
190
|
+
}
|