datool 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +218 -0
- package/client-dist/assets/geist-cyrillic-wght-normal-CHSlOQsW.woff2 +0 -0
- package/client-dist/assets/geist-latin-ext-wght-normal-DMtmJ5ZE.woff2 +0 -0
- package/client-dist/assets/geist-latin-wght-normal-Dm3htQBi.woff2 +0 -0
- package/client-dist/assets/index-BeRNeRUq.css +1 -0
- package/client-dist/assets/index-uoZ4c_I8.js +164 -0
- package/client-dist/index.html +13 -0
- package/index.html +12 -0
- package/package.json +55 -0
- package/src/client/App.tsx +885 -0
- package/src/client/components/connection-status.tsx +43 -0
- package/src/client/components/data-table-cell.tsx +235 -0
- package/src/client/components/data-table-col-icon.tsx +73 -0
- package/src/client/components/data-table-header-col.tsx +225 -0
- package/src/client/components/data-table-search-input.tsx +729 -0
- package/src/client/components/data-table.tsx +2014 -0
- package/src/client/components/stream-controls.tsx +157 -0
- package/src/client/components/theme-provider.tsx +230 -0
- package/src/client/components/ui/button.tsx +68 -0
- package/src/client/components/ui/combobox.tsx +308 -0
- package/src/client/components/ui/context-menu.tsx +261 -0
- package/src/client/components/ui/dropdown-menu.tsx +267 -0
- package/src/client/components/ui/input-group.tsx +153 -0
- package/src/client/components/ui/input.tsx +19 -0
- package/src/client/components/ui/textarea.tsx +18 -0
- package/src/client/components/viewer-settings.tsx +185 -0
- package/src/client/index.css +192 -0
- package/src/client/lib/data-table-search.ts +750 -0
- package/src/client/lib/datool-icons.ts +37 -0
- package/src/client/lib/datool-url-state.ts +159 -0
- package/src/client/lib/filterable-table.ts +146 -0
- package/src/client/lib/table-search-persistence.ts +94 -0
- package/src/client/lib/utils.ts +6 -0
- package/src/client/main.tsx +14 -0
- package/src/index.ts +19 -0
- package/src/node/cli.ts +54 -0
- package/src/node/config.ts +231 -0
- package/src/node/lines.ts +82 -0
- package/src/node/runtime.ts +102 -0
- package/src/node/server.ts +403 -0
- package/src/node/sources/command.ts +82 -0
- package/src/node/sources/file.ts +116 -0
- package/src/node/sources/ssh.ts +59 -0
- package/src/shared/columns.ts +41 -0
- package/src/shared/types.ts +188 -0
|
@@ -0,0 +1,308 @@
|
|
|
1
|
+
"use client"
|
|
2
|
+
|
|
3
|
+
import * as React from "react"
|
|
4
|
+
import { Combobox as ComboboxPrimitive } from "@base-ui/react"
|
|
5
|
+
|
|
6
|
+
import { cn } from "@/lib/utils"
|
|
7
|
+
import { Button } from "@/components/ui/button"
|
|
8
|
+
import {
|
|
9
|
+
InputGroup,
|
|
10
|
+
InputGroupAddon,
|
|
11
|
+
InputGroupButton,
|
|
12
|
+
InputGroupInput,
|
|
13
|
+
} from "@/components/ui/input-group"
|
|
14
|
+
import { ChevronDownIcon, XIcon, CheckIcon } from "lucide-react"
|
|
15
|
+
|
|
16
|
+
const Combobox = ComboboxPrimitive.Root
|
|
17
|
+
|
|
18
|
+
function ComboboxValue({ ...props }: ComboboxPrimitive.Value.Props) {
|
|
19
|
+
return <ComboboxPrimitive.Value data-slot="combobox-value" {...props} />
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
function ComboboxTrigger({
|
|
23
|
+
className,
|
|
24
|
+
children,
|
|
25
|
+
...props
|
|
26
|
+
}: ComboboxPrimitive.Trigger.Props) {
|
|
27
|
+
return (
|
|
28
|
+
<ComboboxPrimitive.Trigger
|
|
29
|
+
data-slot="combobox-trigger"
|
|
30
|
+
className={cn("[&_svg:not([class*='size-'])]:size-3.5", className)}
|
|
31
|
+
{...props}
|
|
32
|
+
>
|
|
33
|
+
{children}
|
|
34
|
+
<ChevronDownIcon className="pointer-events-none size-3.5 text-muted-foreground" />
|
|
35
|
+
</ComboboxPrimitive.Trigger>
|
|
36
|
+
)
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
function ComboboxClear({ className, ...props }: ComboboxPrimitive.Clear.Props) {
|
|
40
|
+
return (
|
|
41
|
+
<ComboboxPrimitive.Clear
|
|
42
|
+
data-slot="combobox-clear"
|
|
43
|
+
render={<InputGroupButton variant="ghost" size="icon-xs" />}
|
|
44
|
+
className={cn(className)}
|
|
45
|
+
{...props}
|
|
46
|
+
>
|
|
47
|
+
<XIcon className="pointer-events-none" />
|
|
48
|
+
</ComboboxPrimitive.Clear>
|
|
49
|
+
)
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
function ComboboxInput({
|
|
53
|
+
className,
|
|
54
|
+
children,
|
|
55
|
+
containerRef,
|
|
56
|
+
disabled = false,
|
|
57
|
+
startAdornment,
|
|
58
|
+
showTrigger = true,
|
|
59
|
+
showClear = false,
|
|
60
|
+
inputClassName,
|
|
61
|
+
...props
|
|
62
|
+
}: ComboboxPrimitive.Input.Props & {
|
|
63
|
+
containerRef?: React.Ref<HTMLDivElement>
|
|
64
|
+
startAdornment?: React.ReactNode
|
|
65
|
+
showTrigger?: boolean
|
|
66
|
+
showClear?: boolean
|
|
67
|
+
inputClassName?: string
|
|
68
|
+
}) {
|
|
69
|
+
return (
|
|
70
|
+
<InputGroup ref={containerRef} className={cn("w-auto", className)}>
|
|
71
|
+
{startAdornment ? (
|
|
72
|
+
<InputGroupAddon align="inline-start">{startAdornment}</InputGroupAddon>
|
|
73
|
+
) : null}
|
|
74
|
+
<ComboboxPrimitive.Input
|
|
75
|
+
render={
|
|
76
|
+
<InputGroupInput disabled={disabled} className={inputClassName} />
|
|
77
|
+
}
|
|
78
|
+
{...props}
|
|
79
|
+
/>
|
|
80
|
+
<InputGroupAddon align="inline-end">
|
|
81
|
+
{showTrigger && (
|
|
82
|
+
<InputGroupButton
|
|
83
|
+
size="icon-xs"
|
|
84
|
+
variant="ghost"
|
|
85
|
+
asChild
|
|
86
|
+
data-slot="input-group-button"
|
|
87
|
+
className="group-has-data-[slot=combobox-clear]/input-group:hidden data-pressed:bg-transparent"
|
|
88
|
+
disabled={disabled}
|
|
89
|
+
>
|
|
90
|
+
<ComboboxTrigger />
|
|
91
|
+
</InputGroupButton>
|
|
92
|
+
)}
|
|
93
|
+
{showClear && <ComboboxClear disabled={disabled} />}
|
|
94
|
+
</InputGroupAddon>
|
|
95
|
+
{children}
|
|
96
|
+
</InputGroup>
|
|
97
|
+
)
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
function ComboboxContent({
|
|
101
|
+
className,
|
|
102
|
+
side = "bottom",
|
|
103
|
+
sideOffset = 6,
|
|
104
|
+
align = "start",
|
|
105
|
+
alignOffset = 0,
|
|
106
|
+
anchor,
|
|
107
|
+
...props
|
|
108
|
+
}: ComboboxPrimitive.Popup.Props &
|
|
109
|
+
Pick<
|
|
110
|
+
ComboboxPrimitive.Positioner.Props,
|
|
111
|
+
"side" | "align" | "sideOffset" | "alignOffset" | "anchor"
|
|
112
|
+
>) {
|
|
113
|
+
return (
|
|
114
|
+
<ComboboxPrimitive.Portal>
|
|
115
|
+
<ComboboxPrimitive.Positioner
|
|
116
|
+
side={side}
|
|
117
|
+
sideOffset={sideOffset}
|
|
118
|
+
align={align}
|
|
119
|
+
alignOffset={alignOffset}
|
|
120
|
+
anchor={anchor}
|
|
121
|
+
className="isolate z-50"
|
|
122
|
+
>
|
|
123
|
+
<ComboboxPrimitive.Popup
|
|
124
|
+
data-slot="combobox-content"
|
|
125
|
+
data-chips={!!anchor}
|
|
126
|
+
className={cn(
|
|
127
|
+
"group/combobox-content relative max-h-(--available-height) w-(--anchor-width) max-w-(--available-width) min-w-[calc(var(--anchor-width)+--spacing(7))] origin-(--transform-origin) overflow-hidden rounded-lg bg-popover text-popover-foreground shadow-md ring-1 ring-foreground/10 duration-100 data-[chips=true]:min-w-(--anchor-width) data-[side=bottom]:slide-in-from-top-2 data-[side=inline-end]:slide-in-from-left-2 data-[side=inline-start]:slide-in-from-right-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 *:data-[slot=input-group]:m-1 *:data-[slot=input-group]:mb-0 *:data-[slot=input-group]:h-7 *:data-[slot=input-group]:border-none *:data-[slot=input-group]:bg-input/20 *:data-[slot=input-group]:shadow-none dark:bg-popover data-open:animate-in data-open:fade-in-0 data-open:zoom-in-95 data-closed:animate-out data-closed:fade-out-0 data-closed:zoom-out-95",
|
|
128
|
+
className
|
|
129
|
+
)}
|
|
130
|
+
{...props}
|
|
131
|
+
/>
|
|
132
|
+
</ComboboxPrimitive.Positioner>
|
|
133
|
+
</ComboboxPrimitive.Portal>
|
|
134
|
+
)
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
function ComboboxList({ className, ...props }: ComboboxPrimitive.List.Props) {
|
|
138
|
+
return (
|
|
139
|
+
<ComboboxPrimitive.List
|
|
140
|
+
data-slot="combobox-list"
|
|
141
|
+
className={cn(
|
|
142
|
+
"no-scrollbar max-h-[min(calc(--spacing(72)---spacing(9)),calc(var(--available-height)---spacing(9)))] scroll-py-1 overflow-y-auto overscroll-contain p-1 data-empty:p-0",
|
|
143
|
+
className
|
|
144
|
+
)}
|
|
145
|
+
{...props}
|
|
146
|
+
/>
|
|
147
|
+
)
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
function ComboboxItem({
|
|
151
|
+
className,
|
|
152
|
+
children,
|
|
153
|
+
...props
|
|
154
|
+
}: ComboboxPrimitive.Item.Props) {
|
|
155
|
+
return (
|
|
156
|
+
<ComboboxPrimitive.Item
|
|
157
|
+
data-slot="combobox-item"
|
|
158
|
+
className={cn(
|
|
159
|
+
"relative flex min-h-7 w-full cursor-default items-center gap-2 rounded-md px-2 py-1 text-xs/relaxed outline-hidden select-none data-highlighted:bg-accent data-highlighted:text-accent-foreground not-data-[variant=destructive]:data-highlighted:**:text-accent-foreground data-disabled:pointer-events-none data-disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-3.5",
|
|
160
|
+
className
|
|
161
|
+
)}
|
|
162
|
+
{...props}
|
|
163
|
+
>
|
|
164
|
+
{children}
|
|
165
|
+
<ComboboxPrimitive.ItemIndicator
|
|
166
|
+
render={
|
|
167
|
+
<span className="pointer-events-none absolute right-2 flex items-center justify-center" />
|
|
168
|
+
}
|
|
169
|
+
>
|
|
170
|
+
<CheckIcon className="pointer-events-none" />
|
|
171
|
+
</ComboboxPrimitive.ItemIndicator>
|
|
172
|
+
</ComboboxPrimitive.Item>
|
|
173
|
+
)
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
function ComboboxGroup({ className, ...props }: ComboboxPrimitive.Group.Props) {
|
|
177
|
+
return (
|
|
178
|
+
<ComboboxPrimitive.Group
|
|
179
|
+
data-slot="combobox-group"
|
|
180
|
+
className={cn(className)}
|
|
181
|
+
{...props}
|
|
182
|
+
/>
|
|
183
|
+
)
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
function ComboboxLabel({
|
|
187
|
+
className,
|
|
188
|
+
...props
|
|
189
|
+
}: ComboboxPrimitive.GroupLabel.Props) {
|
|
190
|
+
return (
|
|
191
|
+
<ComboboxPrimitive.GroupLabel
|
|
192
|
+
data-slot="combobox-label"
|
|
193
|
+
className={cn("px-2 py-1.5 text-xs text-muted-foreground", className)}
|
|
194
|
+
{...props}
|
|
195
|
+
/>
|
|
196
|
+
)
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
function ComboboxCollection({ ...props }: ComboboxPrimitive.Collection.Props) {
|
|
200
|
+
return (
|
|
201
|
+
<ComboboxPrimitive.Collection data-slot="combobox-collection" {...props} />
|
|
202
|
+
)
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
function ComboboxEmpty({ className, ...props }: ComboboxPrimitive.Empty.Props) {
|
|
206
|
+
return (
|
|
207
|
+
<ComboboxPrimitive.Empty
|
|
208
|
+
data-slot="combobox-empty"
|
|
209
|
+
className={cn(
|
|
210
|
+
"hidden w-full justify-center py-2 text-center text-xs/relaxed text-muted-foreground group-data-empty/combobox-content:flex",
|
|
211
|
+
className
|
|
212
|
+
)}
|
|
213
|
+
{...props}
|
|
214
|
+
/>
|
|
215
|
+
)
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
function ComboboxSeparator({
|
|
219
|
+
className,
|
|
220
|
+
...props
|
|
221
|
+
}: ComboboxPrimitive.Separator.Props) {
|
|
222
|
+
return (
|
|
223
|
+
<ComboboxPrimitive.Separator
|
|
224
|
+
data-slot="combobox-separator"
|
|
225
|
+
className={cn("-mx-1 my-1 h-px bg-border/50", className)}
|
|
226
|
+
{...props}
|
|
227
|
+
/>
|
|
228
|
+
)
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
function ComboboxChips({
|
|
232
|
+
className,
|
|
233
|
+
...props
|
|
234
|
+
}: React.ComponentPropsWithRef<typeof ComboboxPrimitive.Chips> &
|
|
235
|
+
ComboboxPrimitive.Chips.Props) {
|
|
236
|
+
return (
|
|
237
|
+
<ComboboxPrimitive.Chips
|
|
238
|
+
data-slot="combobox-chips"
|
|
239
|
+
className={cn(
|
|
240
|
+
"flex min-h-7 flex-wrap items-center gap-1 rounded-md border border-input bg-input/20 bg-clip-padding px-2 py-0.5 text-xs/relaxed transition-colors focus-within:border-ring focus-within:ring-2 focus-within:ring-ring/30 has-aria-invalid:border-destructive has-aria-invalid:ring-2 has-aria-invalid:ring-destructive/20 has-data-[slot=combobox-chip]:px-1 dark:bg-input/30 dark:has-aria-invalid:border-destructive/50 dark:has-aria-invalid:ring-destructive/40",
|
|
241
|
+
className
|
|
242
|
+
)}
|
|
243
|
+
{...props}
|
|
244
|
+
/>
|
|
245
|
+
)
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
function ComboboxChip({
|
|
249
|
+
className,
|
|
250
|
+
children,
|
|
251
|
+
showRemove = true,
|
|
252
|
+
...props
|
|
253
|
+
}: ComboboxPrimitive.Chip.Props & {
|
|
254
|
+
showRemove?: boolean
|
|
255
|
+
}) {
|
|
256
|
+
return (
|
|
257
|
+
<ComboboxPrimitive.Chip
|
|
258
|
+
data-slot="combobox-chip"
|
|
259
|
+
className={cn(
|
|
260
|
+
"flex h-[calc(--spacing(4.75))] w-fit items-center justify-center gap-1 rounded-[calc(var(--radius-sm)-2px)] bg-muted-foreground/10 px-1.5 text-xs/relaxed font-medium whitespace-nowrap text-foreground has-disabled:pointer-events-none has-disabled:cursor-not-allowed has-disabled:opacity-50 has-data-[slot=combobox-chip-remove]:pr-0",
|
|
261
|
+
className
|
|
262
|
+
)}
|
|
263
|
+
{...props}
|
|
264
|
+
>
|
|
265
|
+
{children}
|
|
266
|
+
{showRemove && (
|
|
267
|
+
<ComboboxPrimitive.ChipRemove
|
|
268
|
+
render={<Button variant="ghost" size="icon-xs" />}
|
|
269
|
+
className="-ml-1 opacity-50 hover:opacity-100"
|
|
270
|
+
data-slot="combobox-chip-remove"
|
|
271
|
+
>
|
|
272
|
+
<XIcon className="pointer-events-none" />
|
|
273
|
+
</ComboboxPrimitive.ChipRemove>
|
|
274
|
+
)}
|
|
275
|
+
</ComboboxPrimitive.Chip>
|
|
276
|
+
)
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
function ComboboxChipsInput({
|
|
280
|
+
className,
|
|
281
|
+
...props
|
|
282
|
+
}: ComboboxPrimitive.Input.Props) {
|
|
283
|
+
return (
|
|
284
|
+
<ComboboxPrimitive.Input
|
|
285
|
+
data-slot="combobox-chip-input"
|
|
286
|
+
className={cn("min-w-16 flex-1 outline-none", className)}
|
|
287
|
+
{...props}
|
|
288
|
+
/>
|
|
289
|
+
)
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
export {
|
|
293
|
+
Combobox,
|
|
294
|
+
ComboboxInput,
|
|
295
|
+
ComboboxContent,
|
|
296
|
+
ComboboxList,
|
|
297
|
+
ComboboxItem,
|
|
298
|
+
ComboboxGroup,
|
|
299
|
+
ComboboxLabel,
|
|
300
|
+
ComboboxCollection,
|
|
301
|
+
ComboboxEmpty,
|
|
302
|
+
ComboboxSeparator,
|
|
303
|
+
ComboboxChips,
|
|
304
|
+
ComboboxChip,
|
|
305
|
+
ComboboxChipsInput,
|
|
306
|
+
ComboboxTrigger,
|
|
307
|
+
ComboboxValue,
|
|
308
|
+
}
|
|
@@ -0,0 +1,261 @@
|
|
|
1
|
+
import * as React from "react"
|
|
2
|
+
import { ContextMenu as ContextMenuPrimitive } from "radix-ui"
|
|
3
|
+
|
|
4
|
+
import { cn } from "@/lib/utils"
|
|
5
|
+
import { ChevronRightIcon, CheckIcon } from "lucide-react"
|
|
6
|
+
|
|
7
|
+
function ContextMenu({
|
|
8
|
+
...props
|
|
9
|
+
}: React.ComponentProps<typeof ContextMenuPrimitive.Root>) {
|
|
10
|
+
return <ContextMenuPrimitive.Root data-slot="context-menu" {...props} />
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
function ContextMenuTrigger({
|
|
14
|
+
className,
|
|
15
|
+
...props
|
|
16
|
+
}: React.ComponentProps<typeof ContextMenuPrimitive.Trigger>) {
|
|
17
|
+
return (
|
|
18
|
+
<ContextMenuPrimitive.Trigger
|
|
19
|
+
data-slot="context-menu-trigger"
|
|
20
|
+
className={cn("select-none", className)}
|
|
21
|
+
{...props}
|
|
22
|
+
/>
|
|
23
|
+
)
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
function ContextMenuGroup({
|
|
27
|
+
...props
|
|
28
|
+
}: React.ComponentProps<typeof ContextMenuPrimitive.Group>) {
|
|
29
|
+
return (
|
|
30
|
+
<ContextMenuPrimitive.Group data-slot="context-menu-group" {...props} />
|
|
31
|
+
)
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
function ContextMenuPortal({
|
|
35
|
+
...props
|
|
36
|
+
}: React.ComponentProps<typeof ContextMenuPrimitive.Portal>) {
|
|
37
|
+
return (
|
|
38
|
+
<ContextMenuPrimitive.Portal data-slot="context-menu-portal" {...props} />
|
|
39
|
+
)
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
function ContextMenuSub({
|
|
43
|
+
...props
|
|
44
|
+
}: React.ComponentProps<typeof ContextMenuPrimitive.Sub>) {
|
|
45
|
+
return <ContextMenuPrimitive.Sub data-slot="context-menu-sub" {...props} />
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
function ContextMenuRadioGroup({
|
|
49
|
+
...props
|
|
50
|
+
}: React.ComponentProps<typeof ContextMenuPrimitive.RadioGroup>) {
|
|
51
|
+
return (
|
|
52
|
+
<ContextMenuPrimitive.RadioGroup
|
|
53
|
+
data-slot="context-menu-radio-group"
|
|
54
|
+
{...props}
|
|
55
|
+
/>
|
|
56
|
+
)
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
function ContextMenuContent({
|
|
60
|
+
className,
|
|
61
|
+
...props
|
|
62
|
+
}: React.ComponentProps<typeof ContextMenuPrimitive.Content> & {
|
|
63
|
+
side?: "top" | "right" | "bottom" | "left"
|
|
64
|
+
}) {
|
|
65
|
+
return (
|
|
66
|
+
<ContextMenuPrimitive.Portal>
|
|
67
|
+
<ContextMenuPrimitive.Content
|
|
68
|
+
data-slot="context-menu-content"
|
|
69
|
+
className={cn("z-50 max-h-(--radix-context-menu-content-available-height) min-w-32 origin-(--radix-context-menu-content-transform-origin) overflow-x-hidden overflow-y-auto rounded-lg bg-popover p-1 text-popover-foreground shadow-md ring-1 ring-foreground/10 duration-100 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 data-open:animate-in data-open:fade-in-0 data-open:zoom-in-95 data-closed:animate-out data-closed:fade-out-0 data-closed:zoom-out-95", className )}
|
|
70
|
+
{...props}
|
|
71
|
+
/>
|
|
72
|
+
</ContextMenuPrimitive.Portal>
|
|
73
|
+
)
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
function ContextMenuItem({
|
|
77
|
+
className,
|
|
78
|
+
inset,
|
|
79
|
+
variant = "default",
|
|
80
|
+
...props
|
|
81
|
+
}: React.ComponentProps<typeof ContextMenuPrimitive.Item> & {
|
|
82
|
+
inset?: boolean
|
|
83
|
+
variant?: "default" | "destructive"
|
|
84
|
+
}) {
|
|
85
|
+
return (
|
|
86
|
+
<ContextMenuPrimitive.Item
|
|
87
|
+
data-slot="context-menu-item"
|
|
88
|
+
data-inset={inset}
|
|
89
|
+
data-variant={variant}
|
|
90
|
+
className={cn(
|
|
91
|
+
"group/context-menu-item relative flex min-h-7 cursor-default items-center gap-2 rounded-md px-2 py-1 text-xs/relaxed outline-hidden select-none focus:bg-accent focus:text-accent-foreground not-data-[variant=destructive]:focus:**:text-accent-foreground data-inset:pl-7.5 data-[variant=destructive]:text-destructive data-[variant=destructive]:focus:bg-destructive/10 data-[variant=destructive]:focus:text-destructive dark:data-[variant=destructive]:focus:bg-destructive/20 data-disabled:pointer-events-none data-disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-3.5 data-[variant=destructive]:*:[svg]:text-destructive",
|
|
92
|
+
className
|
|
93
|
+
)}
|
|
94
|
+
{...props}
|
|
95
|
+
/>
|
|
96
|
+
)
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
function ContextMenuSubTrigger({
|
|
100
|
+
className,
|
|
101
|
+
inset,
|
|
102
|
+
children,
|
|
103
|
+
...props
|
|
104
|
+
}: React.ComponentProps<typeof ContextMenuPrimitive.SubTrigger> & {
|
|
105
|
+
inset?: boolean
|
|
106
|
+
}) {
|
|
107
|
+
return (
|
|
108
|
+
<ContextMenuPrimitive.SubTrigger
|
|
109
|
+
data-slot="context-menu-sub-trigger"
|
|
110
|
+
data-inset={inset}
|
|
111
|
+
className={cn(
|
|
112
|
+
"flex min-h-7 cursor-default items-center gap-2 rounded-md px-2 py-1 text-xs outline-hidden select-none focus:bg-accent focus:text-accent-foreground not-data-[variant=destructive]:focus:**:text-accent-foreground data-inset:pl-7.5 data-open:bg-accent data-open:text-accent-foreground [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-3.5",
|
|
113
|
+
className
|
|
114
|
+
)}
|
|
115
|
+
{...props}
|
|
116
|
+
>
|
|
117
|
+
{children}
|
|
118
|
+
<ChevronRightIcon className="ml-auto" />
|
|
119
|
+
</ContextMenuPrimitive.SubTrigger>
|
|
120
|
+
)
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
function ContextMenuSubContent({
|
|
124
|
+
className,
|
|
125
|
+
...props
|
|
126
|
+
}: React.ComponentProps<typeof ContextMenuPrimitive.SubContent>) {
|
|
127
|
+
return (
|
|
128
|
+
<ContextMenuPrimitive.SubContent
|
|
129
|
+
data-slot="context-menu-sub-content"
|
|
130
|
+
className={cn("z-50 min-w-32 origin-(--radix-context-menu-content-transform-origin) overflow-hidden rounded-lg bg-popover p-1 text-popover-foreground shadow-md ring-1 ring-foreground/10 duration-100 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 data-open:animate-in data-open:fade-in-0 data-open:zoom-in-95 data-closed:animate-out data-closed:fade-out-0 data-closed:zoom-out-95", className )}
|
|
131
|
+
{...props}
|
|
132
|
+
/>
|
|
133
|
+
)
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
function ContextMenuCheckboxItem({
|
|
137
|
+
className,
|
|
138
|
+
children,
|
|
139
|
+
checked,
|
|
140
|
+
inset,
|
|
141
|
+
...props
|
|
142
|
+
}: React.ComponentProps<typeof ContextMenuPrimitive.CheckboxItem> & {
|
|
143
|
+
inset?: boolean
|
|
144
|
+
}) {
|
|
145
|
+
return (
|
|
146
|
+
<ContextMenuPrimitive.CheckboxItem
|
|
147
|
+
data-slot="context-menu-checkbox-item"
|
|
148
|
+
data-inset={inset}
|
|
149
|
+
className={cn(
|
|
150
|
+
"relative flex min-h-7 cursor-default items-center gap-2 rounded-md py-1.5 pr-8 pl-2 text-xs outline-hidden select-none focus:bg-accent focus:text-accent-foreground focus:**:text-accent-foreground data-inset:pl-7.5 data-disabled:pointer-events-none data-disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-3.5",
|
|
151
|
+
className
|
|
152
|
+
)}
|
|
153
|
+
checked={checked}
|
|
154
|
+
{...props}
|
|
155
|
+
>
|
|
156
|
+
<span className="pointer-events-none absolute right-2 flex items-center justify-center">
|
|
157
|
+
<ContextMenuPrimitive.ItemIndicator>
|
|
158
|
+
<CheckIcon
|
|
159
|
+
/>
|
|
160
|
+
</ContextMenuPrimitive.ItemIndicator>
|
|
161
|
+
</span>
|
|
162
|
+
{children}
|
|
163
|
+
</ContextMenuPrimitive.CheckboxItem>
|
|
164
|
+
)
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
function ContextMenuRadioItem({
|
|
168
|
+
className,
|
|
169
|
+
children,
|
|
170
|
+
inset,
|
|
171
|
+
...props
|
|
172
|
+
}: React.ComponentProps<typeof ContextMenuPrimitive.RadioItem> & {
|
|
173
|
+
inset?: boolean
|
|
174
|
+
}) {
|
|
175
|
+
return (
|
|
176
|
+
<ContextMenuPrimitive.RadioItem
|
|
177
|
+
data-slot="context-menu-radio-item"
|
|
178
|
+
data-inset={inset}
|
|
179
|
+
className={cn(
|
|
180
|
+
"relative flex min-h-7 cursor-default items-center gap-2 rounded-md py-1.5 pr-8 pl-2 text-xs outline-hidden select-none focus:bg-accent focus:text-accent-foreground focus:**:text-accent-foreground data-inset:pl-7.5 data-disabled:pointer-events-none data-disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-3.5",
|
|
181
|
+
className
|
|
182
|
+
)}
|
|
183
|
+
{...props}
|
|
184
|
+
>
|
|
185
|
+
<span className="pointer-events-none absolute right-2 flex items-center justify-center">
|
|
186
|
+
<ContextMenuPrimitive.ItemIndicator>
|
|
187
|
+
<CheckIcon
|
|
188
|
+
/>
|
|
189
|
+
</ContextMenuPrimitive.ItemIndicator>
|
|
190
|
+
</span>
|
|
191
|
+
{children}
|
|
192
|
+
</ContextMenuPrimitive.RadioItem>
|
|
193
|
+
)
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
function ContextMenuLabel({
|
|
197
|
+
className,
|
|
198
|
+
inset,
|
|
199
|
+
...props
|
|
200
|
+
}: React.ComponentProps<typeof ContextMenuPrimitive.Label> & {
|
|
201
|
+
inset?: boolean
|
|
202
|
+
}) {
|
|
203
|
+
return (
|
|
204
|
+
<ContextMenuPrimitive.Label
|
|
205
|
+
data-slot="context-menu-label"
|
|
206
|
+
data-inset={inset}
|
|
207
|
+
className={cn(
|
|
208
|
+
"px-2 py-1.5 text-xs text-muted-foreground data-inset:pl-7.5",
|
|
209
|
+
className
|
|
210
|
+
)}
|
|
211
|
+
{...props}
|
|
212
|
+
/>
|
|
213
|
+
)
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
function ContextMenuSeparator({
|
|
217
|
+
className,
|
|
218
|
+
...props
|
|
219
|
+
}: React.ComponentProps<typeof ContextMenuPrimitive.Separator>) {
|
|
220
|
+
return (
|
|
221
|
+
<ContextMenuPrimitive.Separator
|
|
222
|
+
data-slot="context-menu-separator"
|
|
223
|
+
className={cn("-mx-1 my-1 h-px bg-border/50", className)}
|
|
224
|
+
{...props}
|
|
225
|
+
/>
|
|
226
|
+
)
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
function ContextMenuShortcut({
|
|
230
|
+
className,
|
|
231
|
+
...props
|
|
232
|
+
}: React.ComponentProps<"span">) {
|
|
233
|
+
return (
|
|
234
|
+
<span
|
|
235
|
+
data-slot="context-menu-shortcut"
|
|
236
|
+
className={cn(
|
|
237
|
+
"ml-auto text-[0.625rem] tracking-widest text-muted-foreground group-focus/context-menu-item:text-accent-foreground",
|
|
238
|
+
className
|
|
239
|
+
)}
|
|
240
|
+
{...props}
|
|
241
|
+
/>
|
|
242
|
+
)
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
export {
|
|
246
|
+
ContextMenu,
|
|
247
|
+
ContextMenuTrigger,
|
|
248
|
+
ContextMenuContent,
|
|
249
|
+
ContextMenuItem,
|
|
250
|
+
ContextMenuCheckboxItem,
|
|
251
|
+
ContextMenuRadioItem,
|
|
252
|
+
ContextMenuLabel,
|
|
253
|
+
ContextMenuSeparator,
|
|
254
|
+
ContextMenuShortcut,
|
|
255
|
+
ContextMenuGroup,
|
|
256
|
+
ContextMenuPortal,
|
|
257
|
+
ContextMenuSub,
|
|
258
|
+
ContextMenuSubContent,
|
|
259
|
+
ContextMenuSubTrigger,
|
|
260
|
+
ContextMenuRadioGroup,
|
|
261
|
+
}
|