@vvedantb/ui 0.17.1 → 0.18.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 +251 -3
- package/package.json +13 -5
- package/shell/src/SidebarResize.tsx +1 -4
- package/src/ai-elements/__snapshots__/queue.test.tsx.snap +11 -0
- package/src/ai-elements/activity-question-utils.ts +26 -0
- package/src/ai-elements/activity-question.tsx +159 -0
- package/src/ai-elements/activity-shared.tsx +459 -0
- package/src/ai-elements/activity-step-detail.tsx +115 -0
- package/src/ai-elements/activity-step-label.ts +981 -0
- package/src/ai-elements/activity-tasks-utils.ts +199 -0
- package/src/ai-elements/activity-tasks.tsx +770 -0
- package/src/ai-elements/artifact.tsx +162 -52
- package/src/ai-elements/attachments.tsx +62 -32
- package/src/ai-elements/code-block.tsx +76 -22
- package/src/ai-elements/context.tsx +370 -0
- package/src/ai-elements/conversation.tsx +186 -62
- package/src/ai-elements/file-chip.tsx +53 -0
- package/src/ai-elements/message.tsx +161 -50
- package/src/ai-elements/model-picker-content.tsx +505 -0
- package/src/ai-elements/model-picker-types.ts +56 -0
- package/src/ai-elements/model-picker.tsx +301 -0
- package/src/ai-elements/model-selector.tsx +102 -21
- package/src/ai-elements/plan.tsx +130 -0
- package/src/ai-elements/prompt-input-settings.tsx +144 -0
- package/src/ai-elements/prompt-input-speech.tsx +189 -0
- package/src/ai-elements/prompt-input-traits.tsx +281 -0
- package/src/ai-elements/prompt-input.tsx +320 -134
- package/src/ai-elements/provider-icon.tsx +133 -0
- package/src/ai-elements/queue.tsx +293 -9
- package/src/ai-elements/shimmer.tsx +72 -1
- package/src/ai-elements/simple-model-ladder.tsx +108 -0
- package/src/ai-elements/speech-input.tsx +5 -3
- package/src/ai-elements/test-results.tsx +510 -0
- package/src/ai-elements/trace.tsx +243 -0
- package/src/ai-elements/use-streaming-disclosure.ts +50 -0
- package/src/ai-elements/web-preview.tsx +349 -0
- package/src/composer/input-area/ComposerSlashMenu.tsx +1 -1
- package/src/index.ts +66 -12
- package/src/kibo/avatar-stack.tsx +40 -0
- package/src/kibo/contribution-graph.tsx +539 -0
- package/src/kibo/cursor.tsx +72 -0
- package/src/kibo/gantt-features.tsx +439 -0
- package/src/kibo/gantt-header.tsx +181 -0
- package/src/kibo/gantt-provider.tsx +657 -0
- package/src/kibo/gantt-sidebar.tsx +157 -0
- package/src/kibo/gantt-timeline.tsx +154 -0
- package/src/kibo/index.ts +151 -0
- package/src/kibo/kanban.tsx +338 -0
- package/src/kibo/kanbanDropTarget.ts +25 -0
- package/src/kibo/list.tsx +162 -0
- package/src/kibo/theme-switcher.tsx +109 -0
- package/src/kibo/video-player.tsx +237 -0
- package/src/markdown/Markdown.tsx +112 -0
- package/src/markdown/MarkdownBlockquote.tsx +45 -0
- package/src/markdown/MarkdownCodeBlock.tsx +197 -0
- package/src/markdown/MarkdownInlineCode.tsx +40 -0
- package/src/markdown/MarkdownLink.tsx +92 -0
- package/src/markdown/codeFence.ts +57 -0
- package/src/markdown/codeHighlight.ts +138 -0
- package/src/markdown/incrementalBlocks.ts +182 -0
- package/src/markdown/index.ts +3 -0
- package/src/markdown/markdownClipboard.ts +178 -0
- package/src/markdown/mermaid.ts +155 -0
- package/src/markdown/rehypeGithubAlerts.ts +80 -0
- package/src/motion/presets.ts +24 -0
- package/src/ui/__snapshots__/alt-wrappers.test.tsx.snap +19 -0
- package/src/ui/__snapshots__/sonner-dom.test.tsx.snap +5 -0
- package/src/ui/_menu-parts.tsx +29 -0
- package/src/ui/accordion.alt.tsx +46 -53
- package/src/ui/accordion.tsx +59 -10
- package/src/ui/avatar.tsx +56 -0
- package/src/ui/badge.tsx +45 -21
- package/src/ui/border-beam.tsx +97 -0
- package/src/ui/button-group.tsx +50 -21
- package/src/ui/button.tsx +67 -45
- package/src/ui/calendar.tsx +48 -5
- package/src/ui/card.tsx +77 -8
- package/src/ui/carousel.tsx +60 -0
- package/src/ui/centered-spinner.tsx +30 -0
- package/src/ui/checkbox.tsx +34 -16
- package/src/ui/clear-input.alt.tsx +33 -75
- package/src/ui/clear-input.tsx +140 -15
- package/src/ui/collapsible.tsx +40 -2
- package/src/ui/command.tsx +143 -70
- package/src/ui/context-menu.tsx +159 -93
- package/src/ui/crossfade-icon.tsx +123 -0
- package/src/ui/dialog.tsx +154 -70
- package/src/ui/dropdown-menu.tsx +177 -117
- package/src/ui/hover-card.tsx +59 -17
- package/src/ui/input-group.alt.tsx +83 -83
- package/src/ui/input-group.tsx +129 -58
- package/src/ui/input.tsx +13 -4
- package/src/ui/label.tsx +11 -8
- package/src/ui/list-row.tsx +232 -0
- package/src/ui/loading-state.tsx +215 -0
- package/src/ui/popover.tsx +56 -23
- package/src/ui/progress.tsx +28 -16
- package/src/ui/refresh-spin-icon.tsx +41 -0
- package/src/ui/search-input.tsx +66 -15
- package/src/ui/select.tsx +171 -100
- package/src/ui/separator.tsx +23 -14
- package/src/ui/slider.tsx +21 -7
- package/src/ui/sonner.tsx +68 -30
- package/src/ui/spinner.tsx +229 -11
- package/src/ui/status-dot.tsx +84 -0
- package/src/ui/surface.tsx +49 -0
- package/src/ui/switch.tsx +29 -15
- package/src/ui/table.tsx +38 -16
- package/src/ui/tabs.tsx +123 -35
- package/src/ui/tabsSliding.ts +33 -1
- package/src/ui/textarea.tsx +13 -4
- package/src/ui/tooltip.tsx +50 -14
- package/src/ui/ui-config.tsx +149 -0
- package/src/utils/cat-color.ts +123 -0
- package/src/utils/dayjs.ts +6 -0
- package/src/utils/gesture.ts +59 -0
- package/src/utils/runtimeVisibility.ts +167 -0
- package/src/utils/sharedClock.ts +96 -0
- package/src/utils/surface-radius.ts +16 -0
- package/src/utils/useDragSensors.ts +58 -0
- package/tokens/examples/tokens-moved/Fixture.tsx +283 -0
- package/tokens/examples/tokens-moved/README.md +20 -0
- package/tokens/examples/tokens-moved/index.html +12 -0
- package/tokens/examples/tokens-moved/main.tsx +6 -0
- package/tokens/examples/tokens-moved/package.json +14 -0
- package/tokens/examples/tokens-moved/styles.css +12 -0
- package/tokens/examples/tokens-moved/tsconfig.json +14 -0
- package/tokens/examples/tokens-moved/vite.config.ts +11 -0
- package/tokens/src/css/border-beam.css +116 -0
- package/tokens/src/css/markdown.css +318 -0
package/src/ui/dropdown-menu.tsx
CHANGED
|
@@ -5,7 +5,6 @@ import {
|
|
|
5
5
|
IconChevronRight,
|
|
6
6
|
IconCircleFilled,
|
|
7
7
|
} from "@tabler/icons-react";
|
|
8
|
-
import { cn } from "../utils/cn";
|
|
9
8
|
import {
|
|
10
9
|
menuCheckboxRadioItemClass,
|
|
11
10
|
menuContentClass,
|
|
@@ -17,14 +16,35 @@ import {
|
|
|
17
16
|
} from "./_menu-classes";
|
|
18
17
|
import {
|
|
19
18
|
fitViewportClass,
|
|
19
|
+
type MenuConfig,
|
|
20
20
|
MenuItemRow,
|
|
21
21
|
SubTriggerRow,
|
|
22
22
|
suppressAltKeyDown,
|
|
23
23
|
} from "./_menu-parts";
|
|
24
24
|
import { restoreModalScrollLock } from "./overlay-a11y";
|
|
25
|
+
import { useCn, useUiConfig } from "./ui-config";
|
|
26
|
+
|
|
27
|
+
/** App defaults for `DropdownMenu*` (see `UiConfigProvider`). */
|
|
28
|
+
export interface DropdownMenuConfig extends MenuConfig {
|
|
29
|
+
/** Default for `DropdownMenuContent` `sideOffset`. */
|
|
30
|
+
sideOffset?: number;
|
|
31
|
+
}
|
|
25
32
|
|
|
26
33
|
const DropdownMenu = DropdownMenuPrimitive.Root;
|
|
27
|
-
|
|
34
|
+
|
|
35
|
+
const DropdownMenuTrigger = React.forwardRef<
|
|
36
|
+
React.ComponentRef<typeof DropdownMenuPrimitive.Trigger>,
|
|
37
|
+
React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Trigger>
|
|
38
|
+
>((props, ref) => {
|
|
39
|
+
const trigger = useUiConfig("DropdownMenu")?.classes?.trigger;
|
|
40
|
+
const merge = useCn();
|
|
41
|
+
// Without config, pass props untouched: Radix's Slot turns an explicit
|
|
42
|
+
// `className={undefined}` into `class=""`.
|
|
43
|
+
if (trigger === undefined) return <DropdownMenuPrimitive.Trigger ref={ref} {...props} />;
|
|
44
|
+
const { className, ...rest } = props;
|
|
45
|
+
return <DropdownMenuPrimitive.Trigger ref={ref} className={merge(trigger, className)} {...rest} />;
|
|
46
|
+
});
|
|
47
|
+
DropdownMenuTrigger.displayName = DropdownMenuPrimitive.Trigger.displayName;
|
|
28
48
|
const DropdownMenuGroup = DropdownMenuPrimitive.Group;
|
|
29
49
|
const DropdownMenuPortal = DropdownMenuPrimitive.Portal;
|
|
30
50
|
const DropdownMenuSub = DropdownMenuPrimitive.Sub;
|
|
@@ -37,33 +57,41 @@ const DropdownMenuSubTrigger = React.forwardRef<
|
|
|
37
57
|
/** Leading icon or mark. The label then fills the row. */
|
|
38
58
|
startContent?: React.ReactNode;
|
|
39
59
|
}
|
|
40
|
-
>(({ className, inset, startContent, children, ...props }, ref) =>
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
)
|
|
60
|
+
>(({ className, inset, startContent, children, ...props }, ref) => {
|
|
61
|
+
const classes = useUiConfig("DropdownMenu")?.classes;
|
|
62
|
+
const merge = useCn();
|
|
63
|
+
return (
|
|
64
|
+
<DropdownMenuPrimitive.SubTrigger
|
|
65
|
+
ref={ref}
|
|
66
|
+
className={merge(classes?.subTrigger ?? menuSubTriggerClass, inset && "pl-8", className)}
|
|
67
|
+
{...props}
|
|
68
|
+
>
|
|
69
|
+
{startContent === undefined ? children : (
|
|
70
|
+
<SubTriggerRow startContent={startContent}>{children}</SubTriggerRow>
|
|
71
|
+
)}
|
|
72
|
+
<IconChevronRight className="ml-auto" />
|
|
73
|
+
</DropdownMenuPrimitive.SubTrigger>
|
|
74
|
+
);
|
|
75
|
+
});
|
|
52
76
|
DropdownMenuSubTrigger.displayName =
|
|
53
77
|
DropdownMenuPrimitive.SubTrigger.displayName;
|
|
54
78
|
|
|
55
79
|
const DropdownMenuSubContent = React.forwardRef<
|
|
56
80
|
React.ComponentRef<typeof DropdownMenuPrimitive.SubContent>,
|
|
57
81
|
React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.SubContent>
|
|
58
|
-
>(({ className, ...props }, ref) =>
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
82
|
+
>(({ className, ...props }, ref) => {
|
|
83
|
+
const classes = useUiConfig("DropdownMenu")?.classes;
|
|
84
|
+
const merge = useCn();
|
|
85
|
+
return (
|
|
86
|
+
<DropdownMenuPrimitive.Portal>
|
|
87
|
+
<DropdownMenuPrimitive.SubContent
|
|
88
|
+
ref={ref}
|
|
89
|
+
className={merge(classes?.subContent ?? menuContentClass, className)}
|
|
90
|
+
{...props}
|
|
91
|
+
/>
|
|
92
|
+
</DropdownMenuPrimitive.Portal>
|
|
93
|
+
);
|
|
94
|
+
});
|
|
67
95
|
DropdownMenuSubContent.displayName =
|
|
68
96
|
DropdownMenuPrimitive.SubContent.displayName;
|
|
69
97
|
|
|
@@ -81,7 +109,8 @@ const DropdownMenuContent = React.forwardRef<
|
|
|
81
109
|
(
|
|
82
110
|
{
|
|
83
111
|
className,
|
|
84
|
-
sideOffset
|
|
112
|
+
sideOffset,
|
|
113
|
+
collisionPadding,
|
|
85
114
|
fitViewport,
|
|
86
115
|
suppressAltKey,
|
|
87
116
|
restoreScrollLockOnClose,
|
|
@@ -90,26 +119,35 @@ const DropdownMenuContent = React.forwardRef<
|
|
|
90
119
|
...props
|
|
91
120
|
},
|
|
92
121
|
ref,
|
|
93
|
-
) =>
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
122
|
+
) => {
|
|
123
|
+
const config = useUiConfig("DropdownMenu");
|
|
124
|
+
const merge = useCn();
|
|
125
|
+
return (
|
|
126
|
+
<DropdownMenuPrimitive.Portal>
|
|
127
|
+
<DropdownMenuPrimitive.Content
|
|
128
|
+
ref={ref}
|
|
129
|
+
sideOffset={sideOffset ?? config?.sideOffset ?? 4}
|
|
130
|
+
collisionPadding={collisionPadding ?? config?.collisionPadding}
|
|
131
|
+
className={merge(
|
|
132
|
+
config?.classes?.content ?? menuContentClass,
|
|
133
|
+
fitViewport && fitViewportClass,
|
|
134
|
+
className,
|
|
135
|
+
)}
|
|
136
|
+
onKeyDown={suppressAltKey ? suppressAltKeyDown(onKeyDown) : onKeyDown}
|
|
137
|
+
onCloseAutoFocus={
|
|
138
|
+
restoreScrollLockOnClose
|
|
139
|
+
? (event) => {
|
|
140
|
+
restoreModalScrollLock();
|
|
141
|
+
window.setTimeout(restoreModalScrollLock, 0);
|
|
142
|
+
onCloseAutoFocus?.(event);
|
|
143
|
+
}
|
|
144
|
+
: onCloseAutoFocus
|
|
145
|
+
}
|
|
146
|
+
{...props}
|
|
147
|
+
/>
|
|
148
|
+
</DropdownMenuPrimitive.Portal>
|
|
149
|
+
);
|
|
150
|
+
},
|
|
113
151
|
);
|
|
114
152
|
DropdownMenuContent.displayName = DropdownMenuPrimitive.Content.displayName;
|
|
115
153
|
|
|
@@ -128,77 +166,89 @@ const DropdownMenuItem = React.forwardRef<
|
|
|
128
166
|
(
|
|
129
167
|
{ className, inset, startContent, description, endContent, children, asChild, ...props },
|
|
130
168
|
ref,
|
|
131
|
-
) =>
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
169
|
+
) => {
|
|
170
|
+
const item = useUiConfig("DropdownMenu")?.classes?.item;
|
|
171
|
+
const merge = useCn();
|
|
172
|
+
return (
|
|
173
|
+
<DropdownMenuPrimitive.Item
|
|
174
|
+
ref={ref}
|
|
175
|
+
asChild={asChild}
|
|
176
|
+
className={merge(item ?? menuItemClass, inset && "pl-8", className)}
|
|
177
|
+
{...props}
|
|
178
|
+
>
|
|
179
|
+
{asChild || (startContent === undefined && description === undefined && endContent === undefined) ? (
|
|
180
|
+
children
|
|
181
|
+
) : endContent !== undefined ? (
|
|
182
|
+
<MenuItemRow startContent={startContent} description={description} endContent={endContent}>
|
|
183
|
+
{children}
|
|
184
|
+
</MenuItemRow>
|
|
185
|
+
) : (
|
|
186
|
+
<>
|
|
187
|
+
{startContent}
|
|
188
|
+
{description === undefined ? (
|
|
189
|
+
children
|
|
190
|
+
) : (
|
|
191
|
+
<span className="flex min-w-0 flex-col">
|
|
192
|
+
<span>{children}</span>
|
|
193
|
+
<span className="text-xs text-muted-foreground">
|
|
194
|
+
{description}
|
|
195
|
+
</span>
|
|
154
196
|
</span>
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
197
|
+
)}
|
|
198
|
+
</>
|
|
199
|
+
)}
|
|
200
|
+
</DropdownMenuPrimitive.Item>
|
|
201
|
+
);
|
|
202
|
+
},
|
|
161
203
|
);
|
|
162
204
|
DropdownMenuItem.displayName = DropdownMenuPrimitive.Item.displayName;
|
|
163
205
|
|
|
164
206
|
const DropdownMenuCheckboxItem = React.forwardRef<
|
|
165
207
|
React.ComponentRef<typeof DropdownMenuPrimitive.CheckboxItem>,
|
|
166
208
|
React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.CheckboxItem>
|
|
167
|
-
>(({ className, children, checked, ...props }, ref) =>
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
209
|
+
>(({ className, children, checked, ...props }, ref) => {
|
|
210
|
+
const config = useUiConfig("DropdownMenu");
|
|
211
|
+
const merge = useCn();
|
|
212
|
+
return (
|
|
213
|
+
<DropdownMenuPrimitive.CheckboxItem
|
|
214
|
+
ref={ref}
|
|
215
|
+
className={merge(config?.classes?.checkboxItem ?? menuCheckboxRadioItemClass, className)}
|
|
216
|
+
checked={checked}
|
|
217
|
+
{...props}
|
|
218
|
+
>
|
|
219
|
+
<span className="absolute left-2.5 flex h-3.5 w-3.5 items-center justify-center">
|
|
220
|
+
<DropdownMenuPrimitive.ItemIndicator>
|
|
221
|
+
{config?.icons?.check ?? <IconCheck className="h-4 w-4" />}
|
|
222
|
+
</DropdownMenuPrimitive.ItemIndicator>
|
|
223
|
+
</span>
|
|
224
|
+
{children}
|
|
225
|
+
</DropdownMenuPrimitive.CheckboxItem>
|
|
226
|
+
);
|
|
227
|
+
});
|
|
182
228
|
DropdownMenuCheckboxItem.displayName =
|
|
183
229
|
DropdownMenuPrimitive.CheckboxItem.displayName;
|
|
184
230
|
|
|
185
231
|
const DropdownMenuRadioItem = React.forwardRef<
|
|
186
232
|
React.ComponentRef<typeof DropdownMenuPrimitive.RadioItem>,
|
|
187
233
|
React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.RadioItem>
|
|
188
|
-
>(({ className, children, ...props }, ref) =>
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
234
|
+
>(({ className, children, ...props }, ref) => {
|
|
235
|
+
const config = useUiConfig("DropdownMenu");
|
|
236
|
+
const merge = useCn();
|
|
237
|
+
return (
|
|
238
|
+
<DropdownMenuPrimitive.RadioItem
|
|
239
|
+
ref={ref}
|
|
240
|
+
className={merge(config?.classes?.radioItem ?? menuCheckboxRadioItemClass, className)}
|
|
241
|
+
{...props}
|
|
242
|
+
>
|
|
243
|
+
<span className="absolute left-2.5 flex h-3.5 w-3.5 items-center justify-center">
|
|
244
|
+
<DropdownMenuPrimitive.ItemIndicator>
|
|
245
|
+
{config?.icons?.radio ?? <IconCircleFilled className="h-2 w-2 fill-current" />}
|
|
246
|
+
</DropdownMenuPrimitive.ItemIndicator>
|
|
247
|
+
</span>
|
|
248
|
+
{children}
|
|
249
|
+
</DropdownMenuPrimitive.RadioItem>
|
|
250
|
+
);
|
|
251
|
+
});
|
|
202
252
|
DropdownMenuRadioItem.displayName = DropdownMenuPrimitive.RadioItem.displayName;
|
|
203
253
|
|
|
204
254
|
const DropdownMenuLabel = React.forwardRef<
|
|
@@ -206,32 +256,42 @@ const DropdownMenuLabel = React.forwardRef<
|
|
|
206
256
|
React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Label> & {
|
|
207
257
|
inset?: boolean;
|
|
208
258
|
}
|
|
209
|
-
>(({ className, inset, ...props }, ref) =>
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
)
|
|
259
|
+
>(({ className, inset, ...props }, ref) => {
|
|
260
|
+
const label = useUiConfig("DropdownMenu")?.classes?.label;
|
|
261
|
+
const merge = useCn();
|
|
262
|
+
return (
|
|
263
|
+
<DropdownMenuPrimitive.Label
|
|
264
|
+
ref={ref}
|
|
265
|
+
className={merge(label ?? menuLabelClass, inset && "pl-8", className)}
|
|
266
|
+
{...props}
|
|
267
|
+
/>
|
|
268
|
+
);
|
|
269
|
+
});
|
|
216
270
|
DropdownMenuLabel.displayName = DropdownMenuPrimitive.Label.displayName;
|
|
217
271
|
|
|
218
272
|
const DropdownMenuSeparator = React.forwardRef<
|
|
219
273
|
React.ComponentRef<typeof DropdownMenuPrimitive.Separator>,
|
|
220
274
|
React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Separator>
|
|
221
|
-
>(({ className, ...props }, ref) =>
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
)
|
|
275
|
+
>(({ className, ...props }, ref) => {
|
|
276
|
+
const separator = useUiConfig("DropdownMenu")?.classes?.separator;
|
|
277
|
+
const merge = useCn();
|
|
278
|
+
return (
|
|
279
|
+
<DropdownMenuPrimitive.Separator
|
|
280
|
+
ref={ref}
|
|
281
|
+
className={merge(separator ?? menuSeparatorClass, className)}
|
|
282
|
+
{...props}
|
|
283
|
+
/>
|
|
284
|
+
);
|
|
285
|
+
});
|
|
228
286
|
DropdownMenuSeparator.displayName = DropdownMenuPrimitive.Separator.displayName;
|
|
229
287
|
|
|
230
288
|
const DropdownMenuShortcut = ({
|
|
231
289
|
className,
|
|
232
290
|
...props
|
|
233
291
|
}: React.HTMLAttributes<HTMLSpanElement>) => {
|
|
234
|
-
|
|
292
|
+
const shortcut = useUiConfig("DropdownMenu")?.classes?.shortcut;
|
|
293
|
+
const merge = useCn();
|
|
294
|
+
return <span className={merge(shortcut ?? menuShortcutClass, className)} {...props} />;
|
|
235
295
|
};
|
|
236
296
|
DropdownMenuShortcut.displayName = "DropdownMenuShortcut";
|
|
237
297
|
|
package/src/ui/hover-card.tsx
CHANGED
|
@@ -1,31 +1,73 @@
|
|
|
1
1
|
import * as React from "react";
|
|
2
2
|
import * as HoverCardPrimitive from "@radix-ui/react-hover-card";
|
|
3
|
-
import { cn } from "../utils/cn";
|
|
4
3
|
import {
|
|
5
4
|
floatingSurfaceAnimateClass,
|
|
6
5
|
floatingSurfaceClass,
|
|
7
6
|
} from "./_menu-classes";
|
|
7
|
+
import { useCn, useUiConfig } from "./ui-config";
|
|
8
|
+
|
|
9
|
+
/** App defaults for `HoverCard*` (see `UiConfigProvider`). */
|
|
10
|
+
export interface HoverCardConfig {
|
|
11
|
+
/** Replaces the built-in classes of a part. */
|
|
12
|
+
classes?: { content?: string };
|
|
13
|
+
/** Default for `HoverCard` `openDelay` (Radix: 700ms). */
|
|
14
|
+
openDelay?: number;
|
|
15
|
+
/** Default for `HoverCard` `closeDelay` (Radix: 300ms). */
|
|
16
|
+
closeDelay?: number;
|
|
17
|
+
/** Default for `HoverCardContent` `sideOffset`. */
|
|
18
|
+
sideOffset?: number;
|
|
19
|
+
/** Default for `HoverCardContent` `portal`. */
|
|
20
|
+
portal?: boolean;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
function HoverCard({
|
|
24
|
+
openDelay,
|
|
25
|
+
closeDelay,
|
|
26
|
+
...props
|
|
27
|
+
}: React.ComponentProps<typeof HoverCardPrimitive.Root>) {
|
|
28
|
+
const config = useUiConfig("HoverCard");
|
|
29
|
+
return (
|
|
30
|
+
<HoverCardPrimitive.Root
|
|
31
|
+
openDelay={openDelay ?? config?.openDelay}
|
|
32
|
+
closeDelay={closeDelay ?? config?.closeDelay}
|
|
33
|
+
{...props}
|
|
34
|
+
/>
|
|
35
|
+
);
|
|
36
|
+
}
|
|
8
37
|
|
|
9
|
-
const HoverCard = HoverCardPrimitive.Root;
|
|
10
38
|
const HoverCardTrigger = HoverCardPrimitive.Trigger;
|
|
11
39
|
|
|
12
40
|
const HoverCardContent = React.forwardRef<
|
|
13
41
|
React.ComponentRef<typeof HoverCardPrimitive.Content>,
|
|
14
|
-
React.ComponentPropsWithoutRef<typeof HoverCardPrimitive.Content>
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
)
|
|
42
|
+
React.ComponentPropsWithoutRef<typeof HoverCardPrimitive.Content> & {
|
|
43
|
+
/** Render into `document.body` so a clipping parent cannot cut it off. */
|
|
44
|
+
portal?: boolean;
|
|
45
|
+
}
|
|
46
|
+
>(({ className, align = "center", sideOffset, portal, ...props }, ref) => {
|
|
47
|
+
const merge = useCn();
|
|
48
|
+
const config = useUiConfig("HoverCard");
|
|
49
|
+
const content = (
|
|
50
|
+
<HoverCardPrimitive.Content
|
|
51
|
+
ref={ref}
|
|
52
|
+
align={align}
|
|
53
|
+
sideOffset={sideOffset ?? config?.sideOffset ?? 4}
|
|
54
|
+
className={merge(
|
|
55
|
+
config?.classes?.content ?? [
|
|
56
|
+
"z-50 w-72 max-sm:max-w-[calc(100vw-2rem)] max-sm:max-h-[85dvh] max-sm:overflow-y-auto p-4 outline-none",
|
|
57
|
+
floatingSurfaceClass,
|
|
58
|
+
floatingSurfaceAnimateClass,
|
|
59
|
+
],
|
|
60
|
+
className,
|
|
61
|
+
)}
|
|
62
|
+
{...props}
|
|
63
|
+
/>
|
|
64
|
+
);
|
|
65
|
+
return (portal ?? config?.portal) ? (
|
|
66
|
+
<HoverCardPrimitive.Portal>{content}</HoverCardPrimitive.Portal>
|
|
67
|
+
) : (
|
|
68
|
+
content
|
|
69
|
+
);
|
|
70
|
+
});
|
|
29
71
|
HoverCardContent.displayName = HoverCardPrimitive.Content.displayName;
|
|
30
72
|
|
|
31
73
|
export { HoverCard, HoverCardTrigger, HoverCardContent };
|