Skip to content

Commit 0613631

Browse files
authored
Add radio and dialog components (#1005)
* Add radio group component * Add Command and Dialog * Update lock
1 parent fc9a19a commit 0613631

File tree

8 files changed

+691
-3
lines changed

8 files changed

+691
-3
lines changed

packages/base/package.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,8 +65,10 @@
6565
"@mapbox/vector-tile": "^2.0.3",
6666
"@naisutech/react-tree": "^3.0.1",
6767
"@radix-ui/react-checkbox": "^1.3.2",
68+
"@radix-ui/react-dialog": "^1.1.15",
6869
"@radix-ui/react-dropdown-menu": "^2.1.15",
6970
"@radix-ui/react-popover": "^1.1.14",
71+
"@radix-ui/react-radio-group": "^1.3.8",
7072
"@radix-ui/react-slot": "^1.2.3",
7173
"@radix-ui/react-switch": "^1.2.6",
7274
"@radix-ui/react-tabs": "^1.1.12",
@@ -76,6 +78,7 @@
7678
"ajv": "^8.14.0",
7779
"class-variance-authority": "^0.7.1",
7880
"clsx": "^2.1.1",
81+
"cmdk": "^1.1.1",
7982
"colormap": "^2.3.2",
8083
"d3-color": "^3.1.0",
8184
"date-fns": "^4.1.0",
Lines changed: 182 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,182 @@
1+
import { Command as CommandPrimitive } from 'cmdk';
2+
import { SearchIcon } from 'lucide-react';
3+
import * as React from 'react';
4+
5+
import {
6+
Dialog,
7+
DialogContent,
8+
DialogDescription,
9+
DialogHeader,
10+
DialogTitle,
11+
} from '@/src/shared/components/Dialog';
12+
import { cn } from './utils';
13+
14+
function Command({
15+
className,
16+
...props
17+
}: React.ComponentProps<typeof CommandPrimitive>) {
18+
return (
19+
<CommandPrimitive
20+
data-slot="command"
21+
className={cn(
22+
'bg-popover text-popover-foreground flex h-full w-full flex-col overflow-hidden rounded-md',
23+
className,
24+
)}
25+
{...props}
26+
/>
27+
);
28+
}
29+
30+
function CommandDialog({
31+
title = 'Command Palette',
32+
description = 'Search for a command to run...',
33+
children,
34+
className,
35+
showCloseButton = true,
36+
...props
37+
}: React.ComponentProps<typeof Dialog> & {
38+
title?: string;
39+
description?: string;
40+
className?: string;
41+
showCloseButton?: boolean;
42+
}) {
43+
return (
44+
<Dialog {...props}>
45+
<DialogHeader className="sr-only">
46+
<DialogTitle>{title}</DialogTitle>
47+
<DialogDescription>{description}</DialogDescription>
48+
</DialogHeader>
49+
<DialogContent
50+
className={cn('overflow-hidden p-0', className)}
51+
showCloseButton={showCloseButton}
52+
>
53+
<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">
54+
{children}
55+
</Command>
56+
</DialogContent>
57+
</Dialog>
58+
);
59+
}
60+
61+
function CommandInput({
62+
className,
63+
...props
64+
}: React.ComponentProps<typeof CommandPrimitive.Input>) {
65+
return (
66+
<div
67+
data-slot="command-input-wrapper"
68+
className="flex h-9 items-center gap-2 border-b px-3"
69+
>
70+
<SearchIcon className="size-4 shrink-0 opacity-50" />
71+
<CommandPrimitive.Input
72+
data-slot="command-input"
73+
className={cn(
74+
'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',
75+
className,
76+
)}
77+
{...props}
78+
/>
79+
</div>
80+
);
81+
}
82+
83+
function CommandList({
84+
className,
85+
...props
86+
}: React.ComponentProps<typeof CommandPrimitive.List>) {
87+
return (
88+
<CommandPrimitive.List
89+
data-slot="command-list"
90+
className={cn(
91+
'max-h-[300px] scroll-py-1 overflow-x-hidden overflow-y-auto',
92+
className,
93+
)}
94+
{...props}
95+
/>
96+
);
97+
}
98+
99+
function CommandEmpty({
100+
...props
101+
}: React.ComponentProps<typeof CommandPrimitive.Empty>) {
102+
return (
103+
<CommandPrimitive.Empty
104+
data-slot="command-empty"
105+
className="py-6 text-center text-sm"
106+
{...props}
107+
/>
108+
);
109+
}
110+
111+
function CommandGroup({
112+
className,
113+
...props
114+
}: React.ComponentProps<typeof CommandPrimitive.Group>) {
115+
return (
116+
<CommandPrimitive.Group
117+
data-slot="command-group"
118+
className={cn(
119+
'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',
120+
className,
121+
)}
122+
{...props}
123+
/>
124+
);
125+
}
126+
127+
function CommandSeparator({
128+
className,
129+
...props
130+
}: React.ComponentProps<typeof CommandPrimitive.Separator>) {
131+
return (
132+
<CommandPrimitive.Separator
133+
data-slot="command-separator"
134+
className={cn('bg-border -mx-1 h-px', className)}
135+
{...props}
136+
/>
137+
);
138+
}
139+
140+
function CommandItem({
141+
className,
142+
...props
143+
}: React.ComponentProps<typeof CommandPrimitive.Item>) {
144+
return (
145+
<CommandPrimitive.Item
146+
data-slot="command-item"
147+
className={cn(
148+
"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",
149+
className,
150+
)}
151+
{...props}
152+
/>
153+
);
154+
}
155+
156+
function CommandShortcut({
157+
className,
158+
...props
159+
}: React.ComponentProps<'span'>) {
160+
return (
161+
<span
162+
data-slot="command-shortcut"
163+
className={cn(
164+
'text-muted-foreground ml-auto text-xs tracking-widest',
165+
className,
166+
)}
167+
{...props}
168+
/>
169+
);
170+
}
171+
172+
export {
173+
Command,
174+
CommandDialog,
175+
CommandInput,
176+
CommandList,
177+
CommandEmpty,
178+
CommandGroup,
179+
CommandItem,
180+
CommandShortcut,
181+
CommandSeparator,
182+
};
Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,132 @@
1+
import * as DialogPrimitive from '@radix-ui/react-dialog';
2+
import { XIcon } from 'lucide-react';
3+
import * as React from 'react';
4+
5+
import { cn } from './utils';
6+
7+
function Dialog({
8+
...props
9+
}: React.ComponentProps<typeof DialogPrimitive.Root>) {
10+
return <DialogPrimitive.Root data-slot="dialog" {...props} />;
11+
}
12+
13+
function DialogTrigger({
14+
...props
15+
}: React.ComponentProps<typeof DialogPrimitive.Trigger>) {
16+
return <DialogPrimitive.Trigger data-slot="dialog-trigger" {...props} />;
17+
}
18+
19+
function DialogPortal({
20+
...props
21+
}: React.ComponentProps<typeof DialogPrimitive.Portal>) {
22+
return <DialogPrimitive.Portal data-slot="dialog-portal" {...props} />;
23+
}
24+
25+
function DialogClose({
26+
...props
27+
}: React.ComponentProps<typeof DialogPrimitive.Close>) {
28+
return <DialogPrimitive.Close data-slot="dialog-close" {...props} />;
29+
}
30+
31+
function DialogOverlay({
32+
className,
33+
...props
34+
}: React.ComponentProps<typeof DialogPrimitive.Overlay>) {
35+
return (
36+
<DialogPrimitive.Overlay
37+
data-slot="dialog-overlay"
38+
className={cn('jgis-dialog-overlay', className)}
39+
{...props}
40+
/>
41+
);
42+
}
43+
44+
function DialogContent({
45+
className,
46+
children,
47+
showCloseButton = true,
48+
...props
49+
}: React.ComponentProps<typeof DialogPrimitive.Content> & {
50+
showCloseButton?: boolean;
51+
}) {
52+
return (
53+
<DialogPortal data-slot="dialog-portal">
54+
<DialogOverlay />
55+
<DialogPrimitive.Content
56+
data-slot="dialog-content"
57+
className={cn('jgis-dialog-content', className)}
58+
{...props}
59+
>
60+
{children}
61+
{showCloseButton && (
62+
<DialogPrimitive.Close
63+
data-slot="dialog-close"
64+
className="jgis-dialog-close"
65+
>
66+
<XIcon />
67+
<span className="jgis-sr-only">Close</span>
68+
</DialogPrimitive.Close>
69+
)}
70+
</DialogPrimitive.Content>
71+
</DialogPortal>
72+
);
73+
}
74+
75+
function DialogHeader({ className, ...props }: React.ComponentProps<'div'>) {
76+
return (
77+
<div
78+
data-slot="dialog-header"
79+
className={cn('jgis-dialog-header', className)}
80+
{...props}
81+
/>
82+
);
83+
}
84+
85+
function DialogFooter({ className, ...props }: React.ComponentProps<'div'>) {
86+
return (
87+
<div
88+
data-slot="dialog-footer"
89+
className={cn('jgis-dialog-footer', className)}
90+
{...props}
91+
/>
92+
);
93+
}
94+
95+
function DialogTitle({
96+
className,
97+
...props
98+
}: React.ComponentProps<typeof DialogPrimitive.Title>) {
99+
return (
100+
<DialogPrimitive.Title
101+
data-slot="dialog-title"
102+
className={cn('jgis-dialog-title', className)}
103+
{...props}
104+
/>
105+
);
106+
}
107+
108+
function DialogDescription({
109+
className,
110+
...props
111+
}: React.ComponentProps<typeof DialogPrimitive.Description>) {
112+
return (
113+
<DialogPrimitive.Description
114+
data-slot="dialog-description"
115+
className={cn('jgis-dialog-description', className)}
116+
{...props}
117+
/>
118+
);
119+
}
120+
121+
export {
122+
Dialog,
123+
DialogClose,
124+
DialogContent,
125+
DialogDescription,
126+
DialogFooter,
127+
DialogHeader,
128+
DialogOverlay,
129+
DialogPortal,
130+
DialogTitle,
131+
DialogTrigger,
132+
};
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
import * as RadioGroupPrimitive from '@radix-ui/react-radio-group';
2+
import { CircleIcon } from 'lucide-react';
3+
import * as React from 'react';
4+
5+
import { cn } from './utils';
6+
7+
function RadioGroup({
8+
className,
9+
...props
10+
}: React.ComponentProps<typeof RadioGroupPrimitive.Root>) {
11+
return (
12+
<RadioGroupPrimitive.Root
13+
data-slot="radio-group"
14+
className={cn('jgis-radio-group', className)}
15+
{...props}
16+
/>
17+
);
18+
}
19+
20+
function RadioGroupItem({
21+
className,
22+
...props
23+
}: React.ComponentProps<typeof RadioGroupPrimitive.Item>) {
24+
return (
25+
<RadioGroupPrimitive.Item
26+
data-slot="radio-group-item"
27+
className={cn('jgis-radio-group-item', className)}
28+
{...props}
29+
>
30+
<RadioGroupPrimitive.Indicator
31+
data-slot="radio-group-indicator"
32+
className="jgis-radio-group-indicator"
33+
>
34+
<CircleIcon className="jgis-radio-group-indicator-icon" />
35+
</RadioGroupPrimitive.Indicator>
36+
</RadioGroupPrimitive.Item>
37+
);
38+
}
39+
40+
export { RadioGroup, RadioGroupItem };

packages/base/style/base.css

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@
2121
@import url('./shared/dropdownMenu.css');
2222
@import url('./shared/badge.css');
2323
@import url('./shared/checkbox.css');
24+
@import url('./shared/radioGroup.css');
25+
@import url('./shared/dialog.css');
2426
@import url('./shared/switch.css');
2527

2628
.errors {

0 commit comments

Comments
 (0)