@theruntime/components 0.0.0 → 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/LICENSE +21 -0
- package/package.json +113 -4
- package/src/accordion.tsx +62 -0
- package/src/alert-dialog.tsx +177 -0
- package/src/alert.tsx +60 -0
- package/src/aspect-ratio.tsx +7 -0
- package/src/attachment.tsx +192 -0
- package/src/avatar.tsx +94 -0
- package/src/badge.tsx +46 -0
- package/src/breadcrumb.tsx +102 -0
- package/src/bubble.tsx +125 -0
- package/src/button-group.tsx +82 -0
- package/src/button.tsx +62 -0
- package/src/calendar.tsx +178 -0
- package/src/card.tsx +75 -0
- package/src/carousel.tsx +228 -0
- package/src/chart/container.tsx +72 -0
- package/src/chart/context.tsx +39 -0
- package/src/chart/index.ts +4 -0
- package/src/chart/legend.tsx +63 -0
- package/src/chart/payload.ts +31 -0
- package/src/chart/tooltip.tsx +149 -0
- package/src/checkbox.tsx +27 -0
- package/src/cn.ts +36 -0
- package/src/collapsible.tsx +19 -0
- package/src/combobox/chips.tsx +71 -0
- package/src/combobox/content.tsx +123 -0
- package/src/combobox/index.ts +13 -0
- package/src/combobox/input.tsx +39 -0
- package/src/combobox/trigger.tsx +44 -0
- package/src/command.tsx +153 -0
- package/src/context-menu.tsx +222 -0
- package/src/dialog.tsx +142 -0
- package/src/direction.tsx +18 -0
- package/src/drawer.tsx +122 -0
- package/src/dropdown-menu.tsx +226 -0
- package/src/empty.tsx +94 -0
- package/src/field.tsx +232 -0
- package/src/form.tsx +153 -0
- package/src/hover-card.tsx +36 -0
- package/src/index.ts +90 -0
- package/src/input-group.tsx +156 -0
- package/src/input-otp.tsx +68 -0
- package/src/input.tsx +21 -0
- package/src/item.tsx +172 -0
- package/src/kbd.tsx +28 -0
- package/src/label.tsx +19 -0
- package/src/marker.tsx +66 -0
- package/src/menubar.tsx +250 -0
- package/src/message-scroller.tsx +128 -0
- package/src/message.tsx +85 -0
- package/src/native-select.tsx +56 -0
- package/src/navigation-menu.tsx +161 -0
- package/src/pagination.tsx +106 -0
- package/src/popover.tsx +72 -0
- package/src/progress.tsx +26 -0
- package/src/questionnaire/actions.tsx +118 -0
- package/src/questionnaire/choices.tsx +113 -0
- package/src/questionnaire/index.ts +21 -0
- package/src/questionnaire/root.tsx +75 -0
- package/src/radio-group.tsx +43 -0
- package/src/resizable.tsx +45 -0
- package/src/scroll-area.tsx +54 -0
- package/src/select.tsx +173 -0
- package/src/separator.tsx +26 -0
- package/src/sheet.tsx +132 -0
- package/src/shell/app-tab.tsx +67 -0
- package/src/shell/entry-row.tsx +137 -0
- package/src/shell/field.tsx +83 -0
- package/src/shell/group-head.tsx +19 -0
- package/src/shell/scope-chip.tsx +32 -0
- package/src/shell/suggest-panel.tsx +92 -0
- package/src/sidebar/context.tsx +128 -0
- package/src/sidebar/index.ts +23 -0
- package/src/sidebar/menu.tsx +239 -0
- package/src/sidebar/sections.tsx +118 -0
- package/src/sidebar/sidebar.tsx +183 -0
- package/src/skeleton.tsx +13 -0
- package/src/slider.tsx +56 -0
- package/src/sonner.tsx +41 -0
- package/src/spinner.tsx +16 -0
- package/src/styles.css +149 -0
- package/src/switch.tsx +33 -0
- package/src/table.tsx +90 -0
- package/src/tabs.tsx +79 -0
- package/src/textarea.tsx +18 -0
- package/src/toggle-group.tsx +81 -0
- package/src/toggle.tsx +44 -0
- package/src/tooltip.tsx +51 -0
- package/src/use-mobile.ts +21 -0
- package/README.md +0 -3
package/src/cn.ts
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
// cn, the shadcn class-merge helper. clsx resolves conditional/array class inputs.
|
|
2
|
+
// tailwind-merge dedupes conflicting Tailwind utilities (last-wins on the same property),
|
|
3
|
+
// so a consumer's `className` override actually beats the component's base classes.
|
|
4
|
+
import type { CSSProperties } from "react";
|
|
5
|
+
import { clsx, type ClassValue } from "clsx";
|
|
6
|
+
import { extendTailwindMerge } from "tailwind-merge";
|
|
7
|
+
|
|
8
|
+
/** A `style` object that also sets custom CSS properties (`--foo`). `CSSProperties` has no index
|
|
9
|
+
* signature for them, so an inline `style={{ "--foo": x }}` needs this type to typecheck without
|
|
10
|
+
* a cast. */
|
|
11
|
+
export type CSSVarStyle = CSSProperties & Record<`--${string}`, string | number>;
|
|
12
|
+
|
|
13
|
+
// The register's Tier-3 SCALE utilities (text-title/body/caption/meta/control) are custom
|
|
14
|
+
// font-size theme keys, and tailwind-merge cannot know that: its default `text-*` heuristic
|
|
15
|
+
// accepts the built-in sizes plus arbitrary lengths and files EVERYTHING ELSE as a text
|
|
16
|
+
// COLOR. Unregistered, `text-control` on a Button therefore (a) knocked out the base
|
|
17
|
+
// `text-primary-foreground`, ink text on an ink fill, a literally invisible label, and
|
|
18
|
+
// (b) failed to dedupe the base `text-sm`, which then won the cascade, so the utility set
|
|
19
|
+
// the size of nothing. Measured on the sampler board before this was registered:
|
|
20
|
+
// twMerge("bg-primary text-primary-foreground … text-control")
|
|
21
|
+
// → "bg-primary … text-control" (color gone)
|
|
22
|
+
// twMerge("text-sm text-muted-foreground text-caption")
|
|
23
|
+
// → "text-sm text-caption" (muted gone, and 14px beat the 12px caption)
|
|
24
|
+
// Registering them in the font-size group fixes both at once. Keep this list in sync with
|
|
25
|
+
// the `--text-*` keys in styles.css's `@theme inline` block.
|
|
26
|
+
const twMerge = extendTailwindMerge({
|
|
27
|
+
extend: {
|
|
28
|
+
classGroups: {
|
|
29
|
+
"font-size": [{ text: ["title", "body", "caption", "meta", "control"] }],
|
|
30
|
+
},
|
|
31
|
+
},
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
export function cn(...inputs: ClassValue[]) {
|
|
35
|
+
return twMerge(clsx(inputs));
|
|
36
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { Collapsible as CollapsiblePrimitive } from "radix-ui";
|
|
2
|
+
|
|
3
|
+
function Collapsible({ ...props }: React.ComponentProps<typeof CollapsiblePrimitive.Root>) {
|
|
4
|
+
return <CollapsiblePrimitive.Root data-slot="collapsible" {...props} />;
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
function CollapsibleTrigger({
|
|
8
|
+
...props
|
|
9
|
+
}: React.ComponentProps<typeof CollapsiblePrimitive.CollapsibleTrigger>) {
|
|
10
|
+
return <CollapsiblePrimitive.CollapsibleTrigger data-slot="collapsible-trigger" {...props} />;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
function CollapsibleContent({
|
|
14
|
+
...props
|
|
15
|
+
}: React.ComponentProps<typeof CollapsiblePrimitive.CollapsibleContent>) {
|
|
16
|
+
return <CollapsiblePrimitive.CollapsibleContent data-slot="collapsible-content" {...props} />;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export { Collapsible, CollapsibleTrigger, CollapsibleContent };
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
import { Combobox as ComboboxPrimitive } from "@base-ui/react";
|
|
3
|
+
import { XIcon } from "@phosphor-icons/react";
|
|
4
|
+
|
|
5
|
+
import { cn } from "../cn";
|
|
6
|
+
import { Button } from "../button";
|
|
7
|
+
|
|
8
|
+
export function ComboboxChips({
|
|
9
|
+
className,
|
|
10
|
+
...props
|
|
11
|
+
}: React.ComponentPropsWithRef<typeof ComboboxPrimitive.Chips> & ComboboxPrimitive.Chips.Props) {
|
|
12
|
+
return (
|
|
13
|
+
<ComboboxPrimitive.Chips
|
|
14
|
+
data-slot="combobox-chips"
|
|
15
|
+
className={cn(
|
|
16
|
+
"flex min-h-9 flex-wrap items-center gap-1.5 rounded-md border border-input bg-transparent bg-clip-padding px-2.5 py-1.5 text-sm shadow-xs transition-[color,box-shadow] focus-within:border-ring focus-within:ring-[3px] focus-within:ring-ring/50 has-aria-invalid:border-destructive has-aria-invalid:ring-[3px] has-aria-invalid:ring-destructive/20 has-data-[slot=combobox-chip]:px-1.5 dark:bg-input/30 dark:has-aria-invalid:border-destructive/50 dark:has-aria-invalid:ring-destructive/40",
|
|
17
|
+
className,
|
|
18
|
+
)}
|
|
19
|
+
{...props}
|
|
20
|
+
/>
|
|
21
|
+
);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export function ComboboxChip({
|
|
25
|
+
className,
|
|
26
|
+
children,
|
|
27
|
+
showRemove = true,
|
|
28
|
+
...props
|
|
29
|
+
}: ComboboxPrimitive.Chip.Props & {
|
|
30
|
+
showRemove?: boolean;
|
|
31
|
+
}) {
|
|
32
|
+
return (
|
|
33
|
+
<ComboboxPrimitive.Chip
|
|
34
|
+
data-slot="combobox-chip"
|
|
35
|
+
className={cn(
|
|
36
|
+
"flex h-[calc(--spacing(5.5))] w-fit items-center justify-center gap-1 rounded-sm bg-muted px-1.5 text-xs 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",
|
|
37
|
+
className,
|
|
38
|
+
)}
|
|
39
|
+
{...props}
|
|
40
|
+
>
|
|
41
|
+
{children}
|
|
42
|
+
{showRemove && (
|
|
43
|
+
<ComboboxPrimitive.ChipRemove
|
|
44
|
+
render={<Button variant="ghost" size="icon-xs" />}
|
|
45
|
+
className="-ml-1 opacity-50 hover:opacity-100"
|
|
46
|
+
data-slot="combobox-chip-remove"
|
|
47
|
+
>
|
|
48
|
+
<XIcon className="pointer-events-none" />
|
|
49
|
+
</ComboboxPrimitive.ChipRemove>
|
|
50
|
+
)}
|
|
51
|
+
</ComboboxPrimitive.Chip>
|
|
52
|
+
);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
export function ComboboxChipsInput({
|
|
56
|
+
className,
|
|
57
|
+
children: _children,
|
|
58
|
+
...props
|
|
59
|
+
}: ComboboxPrimitive.Input.Props) {
|
|
60
|
+
return (
|
|
61
|
+
<ComboboxPrimitive.Input
|
|
62
|
+
data-slot="combobox-chip-input"
|
|
63
|
+
className={cn("min-w-16 flex-1 outline-none", className)}
|
|
64
|
+
{...props}
|
|
65
|
+
/>
|
|
66
|
+
);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
export function useComboboxAnchor() {
|
|
70
|
+
return React.useRef<HTMLDivElement | null>(null);
|
|
71
|
+
}
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
import { Combobox as ComboboxPrimitive } from "@base-ui/react";
|
|
2
|
+
import { CheckIcon } from "@phosphor-icons/react";
|
|
3
|
+
|
|
4
|
+
import { cn } from "../cn";
|
|
5
|
+
|
|
6
|
+
export function ComboboxContent({
|
|
7
|
+
className,
|
|
8
|
+
side = "bottom",
|
|
9
|
+
sideOffset = 6,
|
|
10
|
+
align = "start",
|
|
11
|
+
alignOffset = 0,
|
|
12
|
+
anchor,
|
|
13
|
+
...props
|
|
14
|
+
}: ComboboxPrimitive.Popup.Props &
|
|
15
|
+
Pick<
|
|
16
|
+
ComboboxPrimitive.Positioner.Props,
|
|
17
|
+
"side" | "align" | "sideOffset" | "alignOffset" | "anchor"
|
|
18
|
+
>) {
|
|
19
|
+
return (
|
|
20
|
+
<ComboboxPrimitive.Portal>
|
|
21
|
+
<ComboboxPrimitive.Positioner
|
|
22
|
+
side={side}
|
|
23
|
+
sideOffset={sideOffset}
|
|
24
|
+
align={align}
|
|
25
|
+
alignOffset={alignOffset}
|
|
26
|
+
anchor={anchor}
|
|
27
|
+
className="isolate z-50"
|
|
28
|
+
>
|
|
29
|
+
<ComboboxPrimitive.Popup
|
|
30
|
+
data-slot="combobox-content"
|
|
31
|
+
data-chips={!!anchor}
|
|
32
|
+
className={cn(
|
|
33
|
+
"group/combobox-content relative max-h-96 w-(--anchor-width) max-w-(--available-width) min-w-[calc(var(--anchor-width)+--spacing(7))] origin-(--transform-origin) overflow-hidden rounded-md 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=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-8 *:data-[slot=input-group]:border-input/30 *:data-[slot=input-group]:bg-input/30 *:data-[slot=input-group]:shadow-none 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",
|
|
34
|
+
className,
|
|
35
|
+
)}
|
|
36
|
+
{...props}
|
|
37
|
+
/>
|
|
38
|
+
</ComboboxPrimitive.Positioner>
|
|
39
|
+
</ComboboxPrimitive.Portal>
|
|
40
|
+
);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
export function ComboboxList({ className, ...props }: ComboboxPrimitive.List.Props) {
|
|
44
|
+
return (
|
|
45
|
+
<ComboboxPrimitive.List
|
|
46
|
+
data-slot="combobox-list"
|
|
47
|
+
className={cn(
|
|
48
|
+
"max-h-[min(calc(--spacing(96)---spacing(9)),calc(var(--available-height)---spacing(9)))] scroll-py-1 overflow-y-auto p-1 data-empty:p-0",
|
|
49
|
+
className,
|
|
50
|
+
)}
|
|
51
|
+
{...props}
|
|
52
|
+
/>
|
|
53
|
+
);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
export function ComboboxItem({ className, children, ...props }: ComboboxPrimitive.Item.Props) {
|
|
57
|
+
return (
|
|
58
|
+
<ComboboxPrimitive.Item
|
|
59
|
+
data-slot="combobox-item"
|
|
60
|
+
className={cn(
|
|
61
|
+
"relative flex w-full cursor-default items-center gap-2 rounded-sm py-1.5 pr-8 pl-2 text-sm outline-hidden select-none data-highlighted:bg-accent 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-4",
|
|
62
|
+
className,
|
|
63
|
+
)}
|
|
64
|
+
{...props}
|
|
65
|
+
>
|
|
66
|
+
{children}
|
|
67
|
+
<ComboboxPrimitive.ItemIndicator
|
|
68
|
+
data-slot="combobox-item-indicator"
|
|
69
|
+
render={
|
|
70
|
+
<span className="pointer-events-none absolute right-2 flex size-4 items-center justify-center" />
|
|
71
|
+
}
|
|
72
|
+
>
|
|
73
|
+
<CheckIcon className="pointer-events-none size-4 pointer-coarse:size-5" />
|
|
74
|
+
</ComboboxPrimitive.ItemIndicator>
|
|
75
|
+
</ComboboxPrimitive.Item>
|
|
76
|
+
);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
export function ComboboxGroup({ className, ...props }: ComboboxPrimitive.Group.Props) {
|
|
80
|
+
return (
|
|
81
|
+
<ComboboxPrimitive.Group data-slot="combobox-group" className={cn(className)} {...props} />
|
|
82
|
+
);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
export function ComboboxLabel({ className, ...props }: ComboboxPrimitive.GroupLabel.Props) {
|
|
86
|
+
return (
|
|
87
|
+
<ComboboxPrimitive.GroupLabel
|
|
88
|
+
data-slot="combobox-label"
|
|
89
|
+
className={cn(
|
|
90
|
+
"px-2 py-1.5 text-xs text-muted-foreground pointer-coarse:px-3 pointer-coarse:py-2 pointer-coarse:text-sm",
|
|
91
|
+
className,
|
|
92
|
+
)}
|
|
93
|
+
{...props}
|
|
94
|
+
/>
|
|
95
|
+
);
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
export function ComboboxCollection({ ...props }: ComboboxPrimitive.Collection.Props) {
|
|
99
|
+
return <ComboboxPrimitive.Collection data-slot="combobox-collection" {...props} />;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
export function ComboboxEmpty({ className, ...props }: ComboboxPrimitive.Empty.Props) {
|
|
103
|
+
return (
|
|
104
|
+
<ComboboxPrimitive.Empty
|
|
105
|
+
data-slot="combobox-empty"
|
|
106
|
+
className={cn(
|
|
107
|
+
"hidden w-full justify-center py-2 text-center text-sm text-muted-foreground group-data-empty/combobox-content:flex",
|
|
108
|
+
className,
|
|
109
|
+
)}
|
|
110
|
+
{...props}
|
|
111
|
+
/>
|
|
112
|
+
);
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
export function ComboboxSeparator({ className, ...props }: ComboboxPrimitive.Separator.Props) {
|
|
116
|
+
return (
|
|
117
|
+
<ComboboxPrimitive.Separator
|
|
118
|
+
data-slot="combobox-separator"
|
|
119
|
+
className={cn("-mx-1 my-1 h-px bg-border", className)}
|
|
120
|
+
{...props}
|
|
121
|
+
/>
|
|
122
|
+
);
|
|
123
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export { Combobox, ComboboxClear, ComboboxTrigger, ComboboxValue } from "./trigger";
|
|
2
|
+
export { ComboboxInput } from "./input";
|
|
3
|
+
export {
|
|
4
|
+
ComboboxCollection,
|
|
5
|
+
ComboboxContent,
|
|
6
|
+
ComboboxEmpty,
|
|
7
|
+
ComboboxGroup,
|
|
8
|
+
ComboboxItem,
|
|
9
|
+
ComboboxLabel,
|
|
10
|
+
ComboboxList,
|
|
11
|
+
ComboboxSeparator,
|
|
12
|
+
} from "./content";
|
|
13
|
+
export { ComboboxChip, ComboboxChips, ComboboxChipsInput, useComboboxAnchor } from "./chips";
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { Combobox as ComboboxPrimitive } from "@base-ui/react";
|
|
2
|
+
|
|
3
|
+
import { cn } from "../cn";
|
|
4
|
+
import { InputGroup, InputGroupAddon, InputGroupButton, InputGroupInput } from "../input-group";
|
|
5
|
+
import { ComboboxClear, ComboboxTrigger } from "./trigger";
|
|
6
|
+
|
|
7
|
+
export function ComboboxInput({
|
|
8
|
+
className,
|
|
9
|
+
children,
|
|
10
|
+
disabled = false,
|
|
11
|
+
showTrigger = true,
|
|
12
|
+
showClear = false,
|
|
13
|
+
...props
|
|
14
|
+
}: ComboboxPrimitive.Input.Props & {
|
|
15
|
+
showTrigger?: boolean;
|
|
16
|
+
showClear?: boolean;
|
|
17
|
+
}) {
|
|
18
|
+
return (
|
|
19
|
+
<InputGroup className={cn("w-auto", className)}>
|
|
20
|
+
<ComboboxPrimitive.Input render={<InputGroupInput disabled={disabled} />} {...props} />
|
|
21
|
+
<InputGroupAddon align="inline-end">
|
|
22
|
+
{showTrigger && (
|
|
23
|
+
<InputGroupButton
|
|
24
|
+
size="icon-xs"
|
|
25
|
+
variant="ghost"
|
|
26
|
+
asChild
|
|
27
|
+
data-slot="input-group-button"
|
|
28
|
+
className="group-has-data-[slot=combobox-clear]/input-group:hidden data-pressed:bg-transparent"
|
|
29
|
+
disabled={disabled}
|
|
30
|
+
>
|
|
31
|
+
<ComboboxTrigger />
|
|
32
|
+
</InputGroupButton>
|
|
33
|
+
)}
|
|
34
|
+
{showClear && <ComboboxClear disabled={disabled} />}
|
|
35
|
+
</InputGroupAddon>
|
|
36
|
+
{children}
|
|
37
|
+
</InputGroup>
|
|
38
|
+
);
|
|
39
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { Combobox as ComboboxPrimitive } from "@base-ui/react";
|
|
2
|
+
import { CaretDownIcon, XIcon } from "@phosphor-icons/react";
|
|
3
|
+
|
|
4
|
+
import { cn } from "../cn";
|
|
5
|
+
import { InputGroupButton } from "../input-group";
|
|
6
|
+
|
|
7
|
+
export const Combobox = ComboboxPrimitive.Root;
|
|
8
|
+
|
|
9
|
+
export function ComboboxValue({ ...props }: ComboboxPrimitive.Value.Props) {
|
|
10
|
+
return <ComboboxPrimitive.Value data-slot="combobox-value" {...props} />;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export function ComboboxTrigger({
|
|
14
|
+
className,
|
|
15
|
+
children,
|
|
16
|
+
...props
|
|
17
|
+
}: ComboboxPrimitive.Trigger.Props) {
|
|
18
|
+
return (
|
|
19
|
+
<ComboboxPrimitive.Trigger
|
|
20
|
+
data-slot="combobox-trigger"
|
|
21
|
+
className={cn("[&_svg:not([class*='size-'])]:size-4", className)}
|
|
22
|
+
{...props}
|
|
23
|
+
>
|
|
24
|
+
{children}
|
|
25
|
+
<CaretDownIcon
|
|
26
|
+
data-slot="combobox-trigger-icon"
|
|
27
|
+
className="pointer-events-none size-4 text-muted-foreground"
|
|
28
|
+
/>
|
|
29
|
+
</ComboboxPrimitive.Trigger>
|
|
30
|
+
);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export function ComboboxClear({ className, ...props }: ComboboxPrimitive.Clear.Props) {
|
|
34
|
+
return (
|
|
35
|
+
<ComboboxPrimitive.Clear
|
|
36
|
+
data-slot="combobox-clear"
|
|
37
|
+
render={<InputGroupButton variant="ghost" size="icon-xs" />}
|
|
38
|
+
className={cn(className)}
|
|
39
|
+
{...props}
|
|
40
|
+
>
|
|
41
|
+
<XIcon className="pointer-events-none" />
|
|
42
|
+
</ComboboxPrimitive.Clear>
|
|
43
|
+
);
|
|
44
|
+
}
|
package/src/command.tsx
ADDED
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
import { Command as CommandPrimitive } from "cmdk";
|
|
3
|
+
import { MagnifyingGlassIcon } from "@phosphor-icons/react";
|
|
4
|
+
|
|
5
|
+
import { cn } from "./cn";
|
|
6
|
+
import { Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle } from "./dialog";
|
|
7
|
+
|
|
8
|
+
function Command({ className, ...props }: React.ComponentProps<typeof CommandPrimitive>) {
|
|
9
|
+
return (
|
|
10
|
+
<CommandPrimitive
|
|
11
|
+
data-slot="command"
|
|
12
|
+
className={cn(
|
|
13
|
+
"flex h-full w-full flex-col overflow-hidden rounded-md bg-popover text-popover-foreground",
|
|
14
|
+
className,
|
|
15
|
+
)}
|
|
16
|
+
{...props}
|
|
17
|
+
/>
|
|
18
|
+
);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
function CommandDialog({
|
|
22
|
+
title = "Command Palette",
|
|
23
|
+
description = "Search for a command to run...",
|
|
24
|
+
children,
|
|
25
|
+
className,
|
|
26
|
+
showCloseButton = true,
|
|
27
|
+
...props
|
|
28
|
+
}: React.ComponentProps<typeof Dialog> & {
|
|
29
|
+
title?: string;
|
|
30
|
+
description?: string;
|
|
31
|
+
className?: string;
|
|
32
|
+
showCloseButton?: boolean;
|
|
33
|
+
}) {
|
|
34
|
+
return (
|
|
35
|
+
<Dialog {...props}>
|
|
36
|
+
<DialogHeader className="sr-only">
|
|
37
|
+
<DialogTitle>{title}</DialogTitle>
|
|
38
|
+
<DialogDescription>{description}</DialogDescription>
|
|
39
|
+
</DialogHeader>
|
|
40
|
+
<DialogContent
|
|
41
|
+
className={cn("overflow-hidden p-0", className)}
|
|
42
|
+
showCloseButton={showCloseButton}
|
|
43
|
+
>
|
|
44
|
+
<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">
|
|
45
|
+
{children}
|
|
46
|
+
</Command>
|
|
47
|
+
</DialogContent>
|
|
48
|
+
</Dialog>
|
|
49
|
+
);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
function CommandInput({
|
|
53
|
+
className,
|
|
54
|
+
...props
|
|
55
|
+
}: React.ComponentProps<typeof CommandPrimitive.Input>) {
|
|
56
|
+
return (
|
|
57
|
+
<div data-slot="command-input-wrapper" className="flex h-9 items-center gap-2 border-b px-3">
|
|
58
|
+
<MagnifyingGlassIcon className="size-4 shrink-0 opacity-50" />
|
|
59
|
+
<CommandPrimitive.Input
|
|
60
|
+
data-slot="command-input"
|
|
61
|
+
className={cn(
|
|
62
|
+
"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",
|
|
63
|
+
className,
|
|
64
|
+
)}
|
|
65
|
+
{...props}
|
|
66
|
+
/>
|
|
67
|
+
</div>
|
|
68
|
+
);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
function CommandList({ className, ...props }: React.ComponentProps<typeof CommandPrimitive.List>) {
|
|
72
|
+
return (
|
|
73
|
+
<CommandPrimitive.List
|
|
74
|
+
data-slot="command-list"
|
|
75
|
+
className={cn("max-h-[300px] scroll-py-1 overflow-x-hidden overflow-y-auto", className)}
|
|
76
|
+
{...props}
|
|
77
|
+
/>
|
|
78
|
+
);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
function CommandEmpty({ ...props }: React.ComponentProps<typeof CommandPrimitive.Empty>) {
|
|
82
|
+
return (
|
|
83
|
+
<CommandPrimitive.Empty
|
|
84
|
+
data-slot="command-empty"
|
|
85
|
+
className="py-6 text-center text-sm"
|
|
86
|
+
{...props}
|
|
87
|
+
/>
|
|
88
|
+
);
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
function CommandGroup({
|
|
92
|
+
className,
|
|
93
|
+
...props
|
|
94
|
+
}: React.ComponentProps<typeof CommandPrimitive.Group>) {
|
|
95
|
+
return (
|
|
96
|
+
<CommandPrimitive.Group
|
|
97
|
+
data-slot="command-group"
|
|
98
|
+
className={cn(
|
|
99
|
+
"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",
|
|
100
|
+
className,
|
|
101
|
+
)}
|
|
102
|
+
{...props}
|
|
103
|
+
/>
|
|
104
|
+
);
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
function CommandSeparator({
|
|
108
|
+
className,
|
|
109
|
+
...props
|
|
110
|
+
}: React.ComponentProps<typeof CommandPrimitive.Separator>) {
|
|
111
|
+
return (
|
|
112
|
+
<CommandPrimitive.Separator
|
|
113
|
+
data-slot="command-separator"
|
|
114
|
+
className={cn("-mx-1 h-px bg-border", className)}
|
|
115
|
+
{...props}
|
|
116
|
+
/>
|
|
117
|
+
);
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
function CommandItem({ className, ...props }: React.ComponentProps<typeof CommandPrimitive.Item>) {
|
|
121
|
+
return (
|
|
122
|
+
<CommandPrimitive.Item
|
|
123
|
+
data-slot="command-item"
|
|
124
|
+
className={cn(
|
|
125
|
+
"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",
|
|
126
|
+
className,
|
|
127
|
+
)}
|
|
128
|
+
{...props}
|
|
129
|
+
/>
|
|
130
|
+
);
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
function CommandShortcut({ className, ...props }: React.ComponentProps<"span">) {
|
|
134
|
+
return (
|
|
135
|
+
<span
|
|
136
|
+
data-slot="command-shortcut"
|
|
137
|
+
className={cn("ml-auto text-xs tracking-widest text-muted-foreground", className)}
|
|
138
|
+
{...props}
|
|
139
|
+
/>
|
|
140
|
+
);
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
export {
|
|
144
|
+
Command,
|
|
145
|
+
CommandDialog,
|
|
146
|
+
CommandInput,
|
|
147
|
+
CommandList,
|
|
148
|
+
CommandEmpty,
|
|
149
|
+
CommandGroup,
|
|
150
|
+
CommandItem,
|
|
151
|
+
CommandShortcut,
|
|
152
|
+
CommandSeparator,
|
|
153
|
+
};
|