@hanzo/ui 4.5.4 → 4.6.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-MCP.md +3 -3
- package/README.md +229 -0
- package/assets/ai-icons.tsx +207 -0
- package/assets/crypto.tsx +33 -0
- package/assets/file-type-icon.tsx +66 -0
- package/assets/file.tsx +45 -0
- package/assets/general.tsx +2318 -0
- package/assets/hanzo-logo.svg +9 -0
- package/assets/hanzo-logo.tsx +15 -0
- package/assets/index.ts +8 -0
- package/assets/index.tsx +4 -0
- package/assets/llm-provider.tsx +1094 -0
- package/bin/create-registry.js +1 -1
- package/bin/test-mcp.sh +1 -1
- package/bin/update-registry.js +2 -2
- package/blocks/components/content.tsx +1 -1
- package/blocks/components/grid-block/index.tsx +1 -1
- package/blocks/components/screenful-block/content.tsx +1 -1
- package/blocks/components/screenful-block/poster-background.tsx +1 -1
- package/components/index.ts +56 -0
- package/dist/button.d.ts +1 -0
- package/dist/button.js +1 -0
- package/dist/hooks/index.d.ts +7 -0
- package/dist/hooks/index.js +7 -0
- package/dist/hooks/use-click-away.d.ts +2 -0
- package/dist/hooks/use-click-away.js +23 -0
- package/dist/hooks/use-combined-refs.d.ts +3 -0
- package/dist/hooks/use-combined-refs.js +18 -0
- package/dist/hooks/use-copy-clipboard.d.ts +9 -0
- package/dist/hooks/use-copy-clipboard.js +21 -0
- package/dist/hooks/use-debounce.d.ts +1 -0
- package/dist/hooks/use-debounce.js +13 -0
- package/dist/hooks/use-fill-ids.d.ts +8 -0
- package/dist/hooks/use-fill-ids.js +20 -0
- package/dist/hooks/use-map.d.ts +1 -0
- package/dist/hooks/use-map.js +20 -0
- package/dist/hooks/use-measure.d.ts +8 -0
- package/dist/hooks/use-measure.js +25 -0
- package/dist/hooks/use-reverse-video-playback.d.ts +1 -0
- package/dist/hooks/use-reverse-video-playback.js +41 -0
- package/dist/hooks/use-scroll-restoration.d.ts +8 -0
- package/dist/hooks/use-scroll-restoration.js +36 -0
- package/dist/mcp/enhanced-server.js +2 -2
- package/dist/registry/api.d.ts +1 -1
- package/dist/registry/api.js +3 -3
- package/dist/registry/index.d.ts +48 -48
- package/dist/registry/index.js +3 -3
- package/dist/utils.d.ts +1 -0
- package/dist/utils.js +1 -0
- package/helpers/file.ts +33 -0
- package/helpers/memoization.ts +40 -0
- package/package.json +27 -6
- package/primitives/accordion.tsx +53 -45
- package/primitives/alert-dialog.tsx +185 -0
- package/primitives/alert.tsx +74 -0
- package/primitives/apply-typography.tsx +1 -1
- package/primitives/avatar.tsx +37 -29
- package/primitives/background-beams.tsx +142 -0
- package/primitives/badge.tsx +27 -19
- package/primitives/breadcrumb.tsx +77 -62
- package/primitives/button.tsx +69 -72
- package/primitives/card.tsx +73 -59
- package/primitives/chat/chat-input-area.tsx +87 -0
- package/primitives/chat/chat-input.tsx +71 -0
- package/primitives/chat/files-preview.tsx +330 -0
- package/primitives/chat/index.ts +6 -0
- package/primitives/chat/json-form.tsx +8 -0
- package/primitives/chat/message-list.tsx +307 -0
- package/primitives/chat/message.tsx +569 -0
- package/primitives/chat/sqlite-preview.tsx +215 -0
- package/primitives/checkbox.tsx +18 -19
- package/primitives/collapsible.tsx +9 -0
- package/primitives/command.tsx +75 -83
- package/primitives/context-menu.tsx +115 -109
- package/primitives/copy-to-clipboard-icon.tsx +60 -0
- package/primitives/dialog-video-controller.tsx +1 -1
- package/primitives/dialog.tsx +111 -145
- package/primitives/dot-pattern.tsx +57 -0
- package/primitives/dots-loader.tsx +13 -0
- package/primitives/drawer.tsx +59 -87
- package/primitives/dropdown-menu.tsx +199 -0
- package/primitives/error-message.tsx +19 -0
- package/primitives/file-uploader.tsx +200 -0
- package/primitives/form.tsx +92 -87
- package/primitives/hover-card.tsx +28 -0
- package/primitives/icons/github.tsx +1 -1
- package/primitives/icons/youtube-logo.tsx +1 -1
- package/primitives/index-common.ts +121 -42
- package/primitives/index-next.ts +3 -1
- package/primitives/input.tsx +115 -20
- package/primitives/label.tsx +15 -23
- package/primitives/loading-spinner.tsx +1 -1
- package/primitives/markdown-preview.tsx +609 -0
- package/primitives/mermaid.tsx +196 -0
- package/primitives/next/link-element.tsx +1 -1
- package/primitives/next/mdx-link.tsx +1 -1
- package/primitives/pagination.tsx +117 -0
- package/primitives/popover.tsx +20 -25
- package/primitives/pretty-json-print.tsx +28 -0
- package/primitives/progress.tsx +14 -15
- package/primitives/prompt-textarea.tsx +72 -0
- package/primitives/qr-code.tsx +112 -0
- package/primitives/radio-group.tsx +25 -39
- package/primitives/resizable.tsx +47 -0
- package/primitives/scroll-area.tsx +35 -25
- package/primitives/search-input.tsx +66 -0
- package/primitives/select.tsx +62 -109
- package/primitives/separator.tsx +22 -26
- package/primitives/sheet.tsx +78 -117
- package/primitives/skeleton.tsx +13 -16
- package/primitives/slider.tsx +50 -60
- package/primitives/stepper.tsx +272 -0
- package/primitives/switch.tsx +14 -23
- package/primitives/table.tsx +65 -77
- package/primitives/tabs.tsx +29 -39
- package/primitives/text-link.tsx +25 -0
- package/primitives/textarea.tsx +61 -0
- package/primitives/textfield.tsx +75 -0
- package/primitives/toast.tsx +30 -0
- package/primitives/toggle-group.tsx +33 -33
- package/primitives/toggle.tsx +22 -51
- package/primitives/tooltip.tsx +37 -38
- package/registry.json +1 -1
- package/src/button.ts +1 -0
- package/src/hooks/index.ts +7 -0
- package/src/hooks/use-click-away.ts +31 -0
- package/src/hooks/use-combined-refs.ts +22 -0
- package/src/hooks/use-copy-clipboard.ts +30 -0
- package/src/hooks/use-debounce.ts +17 -0
- package/src/hooks/use-fill-ids.ts +25 -0
- package/src/hooks/use-map.ts +26 -0
- package/src/hooks/use-measure.ts +42 -0
- package/src/hooks/use-reverse-video-playback.ts +43 -0
- package/src/hooks/use-scroll-restoration.ts +50 -0
- package/src/mcp/README.md +1 -1
- package/src/mcp/enhanced-server.ts +2 -2
- package/src/registry/api.ts +3 -3
- package/src/registry/index.ts +3 -3
- package/src/utils.ts +1 -0
- package/style/theme-provider.tsx +1 -1
- package/test-imports.mjs +19 -0
- package/types/animation-def.ts +1 -1
- package/types/button-def.ts +1 -1
- package/types/index.ts +1 -1
- package/util/blob.ts +28 -0
- package/util/copy-to-clipboard.ts +17 -0
- package/util/create-shadow-root.ts +22 -0
- package/util/date.ts +83 -0
- package/util/debounce.ts +11 -0
- package/util/file.ts +15 -0
- package/util/format-and-abbreviate-as-currency.ts +1 -1
- package/util/format-text.ts +33 -0
- package/util/index.ts +9 -78
- package/util/timing.ts +3 -0
- package/util/toasts.tsx +17 -0
- package/utils.ts +9 -0
|
@@ -1,105 +1,112 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
import * as React from
|
|
4
|
-
|
|
5
|
-
import {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
const
|
|
10
|
-
|
|
11
|
-
const ContextMenuGroup = ContextMenuPrimitive.Group
|
|
12
|
-
|
|
13
|
-
const
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
>
|
|
1
|
+
import * as ContextMenuPrimitive from '@radix-ui/react-context-menu';
|
|
2
|
+
import { Check, ChevronRight, Circle } from 'lucide-react';
|
|
3
|
+
import * as React from 'react';
|
|
4
|
+
|
|
5
|
+
import { cn } from '../src/utils';
|
|
6
|
+
|
|
7
|
+
const ContextMenu = ContextMenuPrimitive.Root;
|
|
8
|
+
|
|
9
|
+
const ContextMenuTrigger = ContextMenuPrimitive.Trigger;
|
|
10
|
+
|
|
11
|
+
const ContextMenuGroup = ContextMenuPrimitive.Group;
|
|
12
|
+
|
|
13
|
+
const ContextMenuPortal = ContextMenuPrimitive.Portal;
|
|
14
|
+
|
|
15
|
+
const ContextMenuSub = ContextMenuPrimitive.Sub;
|
|
16
|
+
|
|
17
|
+
const ContextMenuRadioGroup = ContextMenuPrimitive.RadioGroup;
|
|
18
|
+
|
|
19
|
+
type ContextMenuSubTriggerProps = React.ComponentPropsWithoutRef<
|
|
20
|
+
typeof ContextMenuPrimitive.SubTrigger
|
|
21
|
+
> & {
|
|
22
|
+
inset?: boolean;
|
|
23
|
+
ref?: React.RefObject<
|
|
24
|
+
React.ComponentRef<typeof ContextMenuPrimitive.SubTrigger>
|
|
25
|
+
>;
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
const ContextMenuSubTrigger = ({
|
|
29
|
+
className,
|
|
30
|
+
inset,
|
|
31
|
+
children,
|
|
32
|
+
ref,
|
|
33
|
+
...props
|
|
34
|
+
}: ContextMenuSubTriggerProps) => (
|
|
22
35
|
<ContextMenuPrimitive.SubTrigger
|
|
23
|
-
ref={ref}
|
|
24
36
|
className={cn(
|
|
25
|
-
'flex cursor-default
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
className
|
|
37
|
+
'focus:bg-accent data-[state=open]:bg-accent data-[state=open]:text-accent-foreground flex cursor-default items-center rounded-xs px-2 py-1.5 text-sm outline-hidden select-none focus:text-white',
|
|
38
|
+
inset && 'pl-8',
|
|
39
|
+
className,
|
|
29
40
|
)}
|
|
41
|
+
ref={ref}
|
|
30
42
|
{...props}
|
|
31
43
|
>
|
|
32
44
|
{children}
|
|
33
45
|
<ChevronRight className="ml-auto h-4 w-4" />
|
|
34
46
|
</ContextMenuPrimitive.SubTrigger>
|
|
35
|
-
)
|
|
36
|
-
ContextMenuSubTrigger.displayName = ContextMenuPrimitive.SubTrigger.displayName
|
|
47
|
+
);
|
|
48
|
+
ContextMenuSubTrigger.displayName = ContextMenuPrimitive.SubTrigger.displayName;
|
|
37
49
|
|
|
38
|
-
const ContextMenuSubContent =
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
50
|
+
const ContextMenuSubContent = ({
|
|
51
|
+
className,
|
|
52
|
+
...props
|
|
53
|
+
}: React.ComponentProps<typeof ContextMenuPrimitive.SubContent>) => (
|
|
42
54
|
<ContextMenuPrimitive.SubContent
|
|
43
|
-
ref={ref}
|
|
44
55
|
className={cn(
|
|
45
|
-
'z-
|
|
46
|
-
|
|
47
|
-
'data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 ' +
|
|
48
|
-
'data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 ' +
|
|
49
|
-
'data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2',
|
|
50
|
-
className
|
|
56
|
+
'data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 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 z-50 min-w-[8rem] overflow-hidden rounded-md border bg-gray-300 p-1 text-white shadow-md',
|
|
57
|
+
className,
|
|
51
58
|
)}
|
|
52
59
|
{...props}
|
|
53
60
|
/>
|
|
54
|
-
)
|
|
55
|
-
ContextMenuSubContent.displayName = ContextMenuPrimitive.SubContent.displayName
|
|
61
|
+
);
|
|
62
|
+
ContextMenuSubContent.displayName = ContextMenuPrimitive.SubContent.displayName;
|
|
56
63
|
|
|
57
|
-
const ContextMenuContent =
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
64
|
+
const ContextMenuContent = ({
|
|
65
|
+
className,
|
|
66
|
+
...props
|
|
67
|
+
}: React.ComponentProps<typeof ContextMenuPrimitive.Content>) => (
|
|
61
68
|
<ContextMenuPrimitive.Portal>
|
|
62
69
|
<ContextMenuPrimitive.Content
|
|
63
|
-
ref={ref}
|
|
64
70
|
className={cn(
|
|
65
|
-
|
|
66
|
-
className
|
|
71
|
+
'animate-in fade-in-80 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 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 z-50 min-w-[8rem] overflow-hidden rounded-md border border-gray-600 bg-gray-300 p-1 text-gray-50 shadow-md',
|
|
72
|
+
className,
|
|
67
73
|
)}
|
|
68
74
|
{...props}
|
|
69
75
|
/>
|
|
70
76
|
</ContextMenuPrimitive.Portal>
|
|
71
|
-
)
|
|
72
|
-
ContextMenuContent.displayName = ContextMenuPrimitive.Content.displayName
|
|
73
|
-
|
|
74
|
-
const ContextMenuItem =
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
77
|
+
);
|
|
78
|
+
ContextMenuContent.displayName = ContextMenuPrimitive.Content.displayName;
|
|
79
|
+
|
|
80
|
+
const ContextMenuItem = ({
|
|
81
|
+
className,
|
|
82
|
+
inset,
|
|
83
|
+
...props
|
|
84
|
+
}: React.ComponentProps<typeof ContextMenuPrimitive.Item> & {
|
|
85
|
+
inset?: boolean;
|
|
86
|
+
}) => (
|
|
80
87
|
<ContextMenuPrimitive.Item
|
|
81
|
-
ref={ref}
|
|
82
88
|
className={cn(
|
|
83
|
-
|
|
84
|
-
inset &&
|
|
85
|
-
className
|
|
89
|
+
'relative flex cursor-default items-center rounded-xs px-2 py-1.5 text-sm outline-hidden select-none focus:bg-gray-200 focus:text-white data-[disabled]:pointer-events-none data-[disabled]:opacity-50',
|
|
90
|
+
inset && 'pl-8',
|
|
91
|
+
className,
|
|
86
92
|
)}
|
|
87
93
|
{...props}
|
|
88
94
|
/>
|
|
89
|
-
)
|
|
90
|
-
ContextMenuItem.displayName = ContextMenuPrimitive.Item.displayName
|
|
95
|
+
);
|
|
96
|
+
ContextMenuItem.displayName = ContextMenuPrimitive.Item.displayName;
|
|
91
97
|
|
|
92
|
-
const ContextMenuCheckboxItem =
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
98
|
+
const ContextMenuCheckboxItem = ({
|
|
99
|
+
className,
|
|
100
|
+
children,
|
|
101
|
+
checked,
|
|
102
|
+
...props
|
|
103
|
+
}: React.ComponentProps<typeof ContextMenuPrimitive.CheckboxItem>) => (
|
|
96
104
|
<ContextMenuPrimitive.CheckboxItem
|
|
97
|
-
|
|
105
|
+
checked={checked}
|
|
98
106
|
className={cn(
|
|
99
|
-
|
|
100
|
-
className
|
|
107
|
+
'focus:bg-accent focus:text-accent-foreground relative flex cursor-default items-center rounded-xs py-1.5 pr-2 pl-8 text-sm outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50',
|
|
108
|
+
className,
|
|
101
109
|
)}
|
|
102
|
-
checked={checked}
|
|
103
110
|
{...props}
|
|
104
111
|
>
|
|
105
112
|
<span className="absolute left-2 flex h-3.5 w-3.5 items-center justify-center">
|
|
@@ -109,19 +116,19 @@ const ContextMenuCheckboxItem = React.forwardRef<
|
|
|
109
116
|
</span>
|
|
110
117
|
{children}
|
|
111
118
|
</ContextMenuPrimitive.CheckboxItem>
|
|
112
|
-
)
|
|
119
|
+
);
|
|
113
120
|
ContextMenuCheckboxItem.displayName =
|
|
114
|
-
ContextMenuPrimitive.CheckboxItem.displayName
|
|
121
|
+
ContextMenuPrimitive.CheckboxItem.displayName;
|
|
115
122
|
|
|
116
|
-
const ContextMenuRadioItem =
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
123
|
+
const ContextMenuRadioItem = ({
|
|
124
|
+
className,
|
|
125
|
+
children,
|
|
126
|
+
...props
|
|
127
|
+
}: React.ComponentProps<typeof ContextMenuPrimitive.RadioItem>) => (
|
|
120
128
|
<ContextMenuPrimitive.RadioItem
|
|
121
|
-
ref={ref}
|
|
122
129
|
className={cn(
|
|
123
|
-
|
|
124
|
-
className
|
|
130
|
+
'focus:bg-accent focus:text-accent-foreground relative flex cursor-default items-center rounded-xs py-1.5 pr-2 pl-8 text-sm outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50',
|
|
131
|
+
className,
|
|
125
132
|
)}
|
|
126
133
|
{...props}
|
|
127
134
|
>
|
|
@@ -132,38 +139,37 @@ const ContextMenuRadioItem = React.forwardRef<
|
|
|
132
139
|
</span>
|
|
133
140
|
{children}
|
|
134
141
|
</ContextMenuPrimitive.RadioItem>
|
|
135
|
-
)
|
|
136
|
-
ContextMenuRadioItem.displayName = ContextMenuPrimitive.RadioItem.displayName
|
|
137
|
-
|
|
138
|
-
const ContextMenuLabel =
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
142
|
+
);
|
|
143
|
+
ContextMenuRadioItem.displayName = ContextMenuPrimitive.RadioItem.displayName;
|
|
144
|
+
|
|
145
|
+
const ContextMenuLabel = ({
|
|
146
|
+
className,
|
|
147
|
+
inset,
|
|
148
|
+
...props
|
|
149
|
+
}: React.ComponentProps<typeof ContextMenuPrimitive.Label> & {
|
|
150
|
+
inset?: boolean;
|
|
151
|
+
}) => (
|
|
144
152
|
<ContextMenuPrimitive.Label
|
|
145
|
-
ref={ref}
|
|
146
153
|
className={cn(
|
|
147
|
-
|
|
148
|
-
inset &&
|
|
149
|
-
className
|
|
154
|
+
'text-text-default px-2 py-1.5 text-sm font-semibold',
|
|
155
|
+
inset && 'pl-8',
|
|
156
|
+
className,
|
|
150
157
|
)}
|
|
151
158
|
{...props}
|
|
152
159
|
/>
|
|
153
|
-
)
|
|
154
|
-
ContextMenuLabel.displayName = ContextMenuPrimitive.Label.displayName
|
|
160
|
+
);
|
|
161
|
+
ContextMenuLabel.displayName = ContextMenuPrimitive.Label.displayName;
|
|
155
162
|
|
|
156
|
-
const ContextMenuSeparator =
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
163
|
+
const ContextMenuSeparator = ({
|
|
164
|
+
className,
|
|
165
|
+
...props
|
|
166
|
+
}: React.ComponentProps<typeof ContextMenuPrimitive.Separator>) => (
|
|
160
167
|
<ContextMenuPrimitive.Separator
|
|
161
|
-
|
|
162
|
-
className={cn("-mx-1 my-1 h-px bg-border", className)}
|
|
168
|
+
className={cn('bg-border -mx-1 my-1 h-px', className)}
|
|
163
169
|
{...props}
|
|
164
170
|
/>
|
|
165
|
-
)
|
|
166
|
-
ContextMenuSeparator.displayName = ContextMenuPrimitive.Separator.displayName
|
|
171
|
+
);
|
|
172
|
+
ContextMenuSeparator.displayName = ContextMenuPrimitive.Separator.displayName;
|
|
167
173
|
|
|
168
174
|
const ContextMenuShortcut = ({
|
|
169
175
|
className,
|
|
@@ -172,14 +178,14 @@ const ContextMenuShortcut = ({
|
|
|
172
178
|
return (
|
|
173
179
|
<span
|
|
174
180
|
className={cn(
|
|
175
|
-
|
|
176
|
-
className
|
|
181
|
+
'text-text-secondary ml-auto text-xs tracking-widest',
|
|
182
|
+
className,
|
|
177
183
|
)}
|
|
178
184
|
{...props}
|
|
179
185
|
/>
|
|
180
|
-
)
|
|
181
|
-
}
|
|
182
|
-
ContextMenuShortcut.displayName =
|
|
186
|
+
);
|
|
187
|
+
};
|
|
188
|
+
ContextMenuShortcut.displayName = 'ContextMenuShortcut';
|
|
183
189
|
|
|
184
190
|
export {
|
|
185
191
|
ContextMenu,
|
|
@@ -197,4 +203,4 @@ export {
|
|
|
197
203
|
ContextMenuSubContent,
|
|
198
204
|
ContextMenuSubTrigger,
|
|
199
205
|
ContextMenuRadioGroup,
|
|
200
|
-
}
|
|
206
|
+
};
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { CheckCircle2, CopyIcon } from 'lucide-react';
|
|
2
|
+
import React, { cloneElement, type ReactElement } from 'react';
|
|
3
|
+
|
|
4
|
+
import { useCopyClipboard } from '../src/hooks';
|
|
5
|
+
import { cn } from '../src/utils';
|
|
6
|
+
import { Button } from './button';
|
|
7
|
+
|
|
8
|
+
type CopyToClipboardIconProps = {
|
|
9
|
+
string?: string;
|
|
10
|
+
children?: ReactElement<{
|
|
11
|
+
className?: string;
|
|
12
|
+
onClick?: () => void;
|
|
13
|
+
}>;
|
|
14
|
+
className?: string;
|
|
15
|
+
onCopyClipboard?: () => void;
|
|
16
|
+
asChild?: boolean;
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
const CopyToClipboardIcon = ({
|
|
20
|
+
string,
|
|
21
|
+
children,
|
|
22
|
+
className,
|
|
23
|
+
onCopyClipboard,
|
|
24
|
+
asChild = false,
|
|
25
|
+
}: CopyToClipboardIconProps) => {
|
|
26
|
+
const { isCopied, onCopy } = useCopyClipboard({
|
|
27
|
+
string,
|
|
28
|
+
onCopyClipboard,
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
const ClipboardIcon = isCopied ? CheckCircle2 : CopyIcon;
|
|
32
|
+
|
|
33
|
+
if (asChild && children) {
|
|
34
|
+
return cloneElement(children, {
|
|
35
|
+
onClick: onCopy,
|
|
36
|
+
className: cn(children.props?.className, className),
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
return (
|
|
41
|
+
<Button
|
|
42
|
+
className={cn(
|
|
43
|
+
'text-text-secondary hover:bg-bg-tertiary bg-bg-tertiary flex h-8 w-8 gap-2 rounded-lg text-xs font-normal transition-colors hover:text-white',
|
|
44
|
+
className,
|
|
45
|
+
)}
|
|
46
|
+
disabled={!string}
|
|
47
|
+
onClick={onCopy}
|
|
48
|
+
size={'icon'}
|
|
49
|
+
type="button"
|
|
50
|
+
variant="tertiary"
|
|
51
|
+
>
|
|
52
|
+
<ClipboardIcon
|
|
53
|
+
className={cn('h-3.5 w-3.5', isCopied && 'text-green-500')}
|
|
54
|
+
/>
|
|
55
|
+
{children}
|
|
56
|
+
</Button>
|
|
57
|
+
);
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
export { CopyToClipboardIcon, useCopyClipboard };
|
package/primitives/dialog.tsx
CHANGED
|
@@ -1,157 +1,123 @@
|
|
|
1
|
-
|
|
2
|
-
import
|
|
3
|
-
import * as
|
|
4
|
-
|
|
5
|
-
import { cn } from
|
|
6
|
-
|
|
7
|
-
const Dialog = DialogPrimitive.Root
|
|
8
|
-
|
|
9
|
-
const DialogTrigger = DialogPrimitive.Trigger
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
)
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
interface DialogCloseProps extends React.PropsWithChildren<React.ComponentPropsWithoutRef<typeof DialogPrimitive.Close>> {
|
|
48
|
-
className?: string;
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
const DialogClose = React.forwardRef<
|
|
52
|
-
React.ElementRef<typeof DialogPrimitive.Close>,
|
|
53
|
-
DialogCloseProps
|
|
54
|
-
>(({ className, ...props }, ref) => (
|
|
55
|
-
<DialogPrimitive.Close
|
|
56
|
-
ref={ref}
|
|
1
|
+
import * as DialogPrimitive from '@radix-ui/react-dialog';
|
|
2
|
+
import { X } from 'lucide-react';
|
|
3
|
+
import * as React from 'react';
|
|
4
|
+
|
|
5
|
+
import { cn } from '../src/utils';
|
|
6
|
+
|
|
7
|
+
const Dialog = DialogPrimitive.Root;
|
|
8
|
+
|
|
9
|
+
const DialogTrigger = DialogPrimitive.Trigger;
|
|
10
|
+
|
|
11
|
+
const DialogPortal = DialogPrimitive.Portal;
|
|
12
|
+
|
|
13
|
+
const DialogOverlay = ({
|
|
14
|
+
className,
|
|
15
|
+
...props
|
|
16
|
+
}: React.ComponentProps<typeof DialogPrimitive.Overlay>) => (
|
|
17
|
+
<DialogPrimitive.Overlay
|
|
18
|
+
className={cn(
|
|
19
|
+
'data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 fixed inset-0 z-50',
|
|
20
|
+
'bg-bg-dark/90',
|
|
21
|
+
className,
|
|
22
|
+
)}
|
|
23
|
+
{...props}
|
|
24
|
+
/>
|
|
25
|
+
);
|
|
26
|
+
DialogOverlay.displayName = DialogPrimitive.Overlay.displayName;
|
|
27
|
+
|
|
28
|
+
const DialogContent = ({
|
|
29
|
+
className,
|
|
30
|
+
children,
|
|
31
|
+
showCloseButton = false,
|
|
32
|
+
...props
|
|
33
|
+
}: React.ComponentProps<typeof DialogPrimitive.Content> & {
|
|
34
|
+
showCloseButton?: boolean;
|
|
35
|
+
}) => (
|
|
36
|
+
<DialogPortal>
|
|
37
|
+
<DialogOverlay />
|
|
38
|
+
<DialogPrimitive.Content
|
|
39
|
+
className={cn(
|
|
40
|
+
'bg-bg-default data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 border-divider fixed top-[50%] left-[50%] z-50 grid w-full max-w-[calc(100%-2rem)] max-w-lg translate-x-[-50%] translate-y-[-50%] gap-4 rounded-lg border p-6 shadow-lg duration-200 sm:rounded-lg md:w-full',
|
|
41
|
+
className,
|
|
42
|
+
)}
|
|
43
|
+
{...props}
|
|
44
|
+
>
|
|
45
|
+
{children}
|
|
46
|
+
<DialogPrimitive.Close
|
|
57
47
|
className={cn(
|
|
58
|
-
|
|
59
|
-
|
|
48
|
+
'ring-offset-background focus:ring-ring data-[state=open]:bg-accent data-[state=open]:text-text-secondary absolute top-4 right-4 rounded-xs opacity-70 transition-opacity hover:opacity-100 focus:ring-2 focus:ring-offset-2 focus:outline-hidden disabled:pointer-events-none',
|
|
49
|
+
!showCloseButton && 'hidden',
|
|
60
50
|
)}
|
|
61
|
-
|
|
62
|
-
>
|
|
51
|
+
>
|
|
63
52
|
<X className="h-4 w-4" />
|
|
64
53
|
<span className="sr-only">Close</span>
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
const DialogContent = React.forwardRef<
|
|
71
|
-
React.ElementRef<typeof DialogPrimitive.Content>,
|
|
72
|
-
React.ComponentPropsWithoutRef<typeof DialogPrimitive.Content>
|
|
73
|
-
>(({ className, children, ...props }, ref) => (
|
|
74
|
-
<DialogPortal>
|
|
75
|
-
<DialogOverlay />
|
|
76
|
-
<DialogPrimitive.Content
|
|
77
|
-
ref={ref}
|
|
78
|
-
className={cn(
|
|
79
|
-
"fixed z-50 grid w-full gap-4 rounded-t-lg bg-level-1 p-6 shadow-lg animate-in data-[state=open]:fade-in-90 data-[state=open]:slide-in-from-bottom-10 sm:max-w-lg sm:rounded-lg sm:zoom-in-90 data-[state=open]:sm:slide-in-from-bottom-0",
|
|
80
|
-
className
|
|
81
|
-
)}
|
|
82
|
-
{...props}
|
|
83
|
-
>
|
|
84
|
-
{children}
|
|
85
|
-
<DialogClose />
|
|
86
|
-
</DialogPrimitive.Content>
|
|
87
|
-
</DialogPortal>
|
|
88
|
-
))
|
|
89
|
-
DialogContent.displayName = DialogPrimitive.Content.displayName
|
|
54
|
+
</DialogPrimitive.Close>
|
|
55
|
+
</DialogPrimitive.Content>
|
|
56
|
+
</DialogPortal>
|
|
57
|
+
);
|
|
58
|
+
DialogContent.displayName = DialogPrimitive.Content.displayName;
|
|
90
59
|
|
|
91
60
|
const DialogHeader = ({
|
|
92
|
-
|
|
93
|
-
|
|
61
|
+
className,
|
|
62
|
+
...props
|
|
94
63
|
}: React.HTMLAttributes<HTMLDivElement>) => (
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
)
|
|
103
|
-
DialogHeader.displayName =
|
|
64
|
+
<div
|
|
65
|
+
className={cn(
|
|
66
|
+
'flex flex-col space-y-1.5 text-center sm:text-left',
|
|
67
|
+
className,
|
|
68
|
+
)}
|
|
69
|
+
{...props}
|
|
70
|
+
/>
|
|
71
|
+
);
|
|
72
|
+
DialogHeader.displayName = 'DialogHeader';
|
|
104
73
|
|
|
105
74
|
const DialogFooter = ({
|
|
106
|
-
|
|
107
|
-
|
|
75
|
+
className,
|
|
76
|
+
...props
|
|
108
77
|
}: React.HTMLAttributes<HTMLDivElement>) => (
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
)
|
|
117
|
-
DialogFooter.displayName =
|
|
118
|
-
|
|
119
|
-
const DialogTitle =
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
))
|
|
144
|
-
DialogDescription.displayName = DialogPrimitive.Description.displayName
|
|
78
|
+
<div
|
|
79
|
+
className={cn(
|
|
80
|
+
'flex flex-col-reverse sm:flex-row sm:justify-end sm:space-x-2',
|
|
81
|
+
className,
|
|
82
|
+
)}
|
|
83
|
+
{...props}
|
|
84
|
+
/>
|
|
85
|
+
);
|
|
86
|
+
DialogFooter.displayName = 'DialogFooter';
|
|
87
|
+
|
|
88
|
+
const DialogTitle = ({
|
|
89
|
+
className,
|
|
90
|
+
...props
|
|
91
|
+
}: React.ComponentProps<typeof DialogPrimitive.Title>) => (
|
|
92
|
+
<DialogPrimitive.Title
|
|
93
|
+
className={cn(
|
|
94
|
+
'text-lg leading-none font-semibold tracking-tight',
|
|
95
|
+
className,
|
|
96
|
+
)}
|
|
97
|
+
{...props}
|
|
98
|
+
/>
|
|
99
|
+
);
|
|
100
|
+
DialogTitle.displayName = DialogPrimitive.Title.displayName;
|
|
101
|
+
|
|
102
|
+
const DialogDescription = ({
|
|
103
|
+
className,
|
|
104
|
+
...props
|
|
105
|
+
}: React.ComponentProps<typeof DialogPrimitive.Description>) => (
|
|
106
|
+
<DialogPrimitive.Description
|
|
107
|
+
className={cn('text-text-secondary text-sm', className)}
|
|
108
|
+
{...props}
|
|
109
|
+
/>
|
|
110
|
+
);
|
|
111
|
+
DialogDescription.displayName = DialogPrimitive.Description.displayName;
|
|
145
112
|
|
|
146
113
|
export {
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
}
|
|
114
|
+
Dialog,
|
|
115
|
+
DialogPortal,
|
|
116
|
+
DialogOverlay,
|
|
117
|
+
DialogTrigger,
|
|
118
|
+
DialogContent,
|
|
119
|
+
DialogHeader,
|
|
120
|
+
DialogFooter,
|
|
121
|
+
DialogTitle,
|
|
122
|
+
DialogDescription,
|
|
123
|
+
};
|