@kushagradhawan/kookie-ui 0.1.125 → 0.1.127
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/components.css +124 -0
- package/dist/cjs/components/_internal/base-menu.props.d.ts +52 -1
- package/dist/cjs/components/_internal/base-menu.props.d.ts.map +1 -1
- package/dist/cjs/components/_internal/base-menu.props.js +1 -1
- package/dist/cjs/components/_internal/base-menu.props.js.map +3 -3
- package/dist/cjs/components/_internal/dropdown-menu-drill-down.d.ts +63 -0
- package/dist/cjs/components/_internal/dropdown-menu-drill-down.d.ts.map +1 -0
- package/dist/cjs/components/_internal/dropdown-menu-drill-down.js +2 -0
- package/dist/cjs/components/_internal/dropdown-menu-drill-down.js.map +7 -0
- package/dist/cjs/components/dropdown-menu.d.ts +28 -7
- package/dist/cjs/components/dropdown-menu.d.ts.map +1 -1
- package/dist/cjs/components/dropdown-menu.js +1 -1
- package/dist/cjs/components/dropdown-menu.js.map +3 -3
- package/dist/cjs/components/dropdown-menu.props.d.ts +1 -1
- package/dist/cjs/components/dropdown-menu.props.d.ts.map +1 -1
- package/dist/cjs/components/dropdown-menu.props.js +1 -1
- package/dist/cjs/components/dropdown-menu.props.js.map +2 -2
- package/dist/cjs/components/icons.d.ts +2 -1
- package/dist/cjs/components/icons.d.ts.map +1 -1
- package/dist/cjs/components/icons.js +1 -1
- package/dist/cjs/components/icons.js.map +3 -3
- package/dist/cjs/components/schemas/shell.schema.d.ts +2 -2
- package/dist/esm/components/_internal/base-menu.props.d.ts +52 -1
- package/dist/esm/components/_internal/base-menu.props.d.ts.map +1 -1
- package/dist/esm/components/_internal/base-menu.props.js +1 -1
- package/dist/esm/components/_internal/base-menu.props.js.map +3 -3
- package/dist/esm/components/_internal/dropdown-menu-drill-down.d.ts +63 -0
- package/dist/esm/components/_internal/dropdown-menu-drill-down.d.ts.map +1 -0
- package/dist/esm/components/_internal/dropdown-menu-drill-down.js +2 -0
- package/dist/esm/components/_internal/dropdown-menu-drill-down.js.map +7 -0
- package/dist/esm/components/dropdown-menu.d.ts +28 -7
- package/dist/esm/components/dropdown-menu.d.ts.map +1 -1
- package/dist/esm/components/dropdown-menu.js +1 -1
- package/dist/esm/components/dropdown-menu.js.map +3 -3
- package/dist/esm/components/dropdown-menu.props.d.ts +1 -1
- package/dist/esm/components/dropdown-menu.props.d.ts.map +1 -1
- package/dist/esm/components/dropdown-menu.props.js +1 -1
- package/dist/esm/components/dropdown-menu.props.js.map +3 -3
- package/dist/esm/components/icons.d.ts +2 -1
- package/dist/esm/components/icons.d.ts.map +1 -1
- package/dist/esm/components/icons.js +1 -1
- package/dist/esm/components/icons.js.map +3 -3
- package/dist/esm/components/schemas/shell.schema.d.ts +2 -2
- package/package.json +2 -2
- package/schemas/base-button.json +1 -1
- package/schemas/button.json +1 -1
- package/schemas/icon-button.json +1 -1
- package/schemas/index.json +6 -6
- package/schemas/toggle-button.json +1 -1
- package/schemas/toggle-icon-button.json +1 -1
- package/src/components/_internal/base-menu.props.ts +31 -1
- package/src/components/_internal/dropdown-menu-drill-down.tsx +252 -0
- package/src/components/animations.css +11 -0
- package/src/components/dropdown-menu.css +141 -0
- package/src/components/dropdown-menu.props.tsx +2 -0
- package/src/components/dropdown-menu.tsx +219 -27
- package/src/components/icons.tsx +14 -1
- package/styles.css +124 -0
|
@@ -7,19 +7,28 @@ import { DropdownMenu as DropdownMenuPrimitive, Slot } from 'radix-ui';
|
|
|
7
7
|
import { ScrollArea } from './scroll-area.js';
|
|
8
8
|
import {
|
|
9
9
|
dropdownMenuContentPropDefs,
|
|
10
|
+
dropdownMenuSubContentPropDefs,
|
|
10
11
|
dropdownMenuItemPropDefs,
|
|
11
12
|
dropdownMenuCheckboxItemPropDefs,
|
|
12
13
|
dropdownMenuRadioItemPropDefs,
|
|
13
14
|
} from './dropdown-menu.props.js';
|
|
14
15
|
import { Theme, useThemeContext } from './theme.js';
|
|
15
|
-
import { ChevronDownIcon, ThickCheckIcon, ThickChevronRightIcon, ThickDotIcon } from './icons.js';
|
|
16
|
+
import { ChevronDownIcon, ThickCheckIcon, ThickChevronLeftIcon, ThickChevronRightIcon, ThickDotIcon } from './icons.js';
|
|
16
17
|
import { extractProps } from '../helpers/extract-props.js';
|
|
18
|
+
import {
|
|
19
|
+
DrillDownProvider,
|
|
20
|
+
SubContext,
|
|
21
|
+
useDrillDown,
|
|
22
|
+
useDrillDownOptional,
|
|
23
|
+
useSubContext,
|
|
24
|
+
} from './_internal/dropdown-menu-drill-down.js';
|
|
25
|
+
import type { SubmenuBehavior } from './_internal/dropdown-menu-drill-down.js';
|
|
17
26
|
import { requireReactElement } from '../helpers/require-react-element.js';
|
|
18
27
|
import { Kbd } from './kbd.js';
|
|
19
28
|
|
|
20
29
|
import type { IconProps } from './icons.js';
|
|
21
30
|
import type { ComponentPropsWithout, RemovedProps } from '../helpers/component-props.js';
|
|
22
|
-
import type { GetPropDefTypes } from '../props/prop-def.js';
|
|
31
|
+
import type { GetPropDefTypes, Responsive } from '../props/prop-def.js';
|
|
23
32
|
|
|
24
33
|
interface DropdownMenuRootProps
|
|
25
34
|
extends React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Root> {}
|
|
@@ -40,14 +49,53 @@ const DropdownMenuTrigger = React.forwardRef<DropdownMenuTriggerElement, Dropdow
|
|
|
40
49
|
);
|
|
41
50
|
DropdownMenuTrigger.displayName = 'DropdownMenu.Trigger';
|
|
42
51
|
|
|
43
|
-
|
|
44
|
-
|
|
52
|
+
/**
|
|
53
|
+
* Internal component that wraps root menu items and handles visibility in drill-down mode.
|
|
54
|
+
* In drill-down mode, this hides when a submenu is active.
|
|
55
|
+
*/
|
|
56
|
+
function DrillDownRoot({ children }: { children: React.ReactNode }) {
|
|
57
|
+
const drillDown = useDrillDownOptional();
|
|
58
|
+
|
|
59
|
+
// In cascade mode or when no drill-down context, always show
|
|
60
|
+
if (!drillDown || drillDown.behavior === 'cascade') {
|
|
61
|
+
return <>{children}</>;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
// In drill-down mode, hide root when a submenu is active
|
|
65
|
+
return (
|
|
66
|
+
<div
|
|
67
|
+
className="rt-DropdownMenuDrillDownRoot"
|
|
68
|
+
data-drill-down-active={drillDown.isRoot ? undefined : true}
|
|
69
|
+
data-animation-direction={drillDown.animationDirection ?? undefined}
|
|
70
|
+
>
|
|
71
|
+
{children}
|
|
72
|
+
</div>
|
|
73
|
+
);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
type DropdownMenuContentOwnProps = GetPropDefTypes<typeof dropdownMenuContentPropDefs> & {
|
|
77
|
+
/**
|
|
78
|
+
* Controls how submenus behave.
|
|
79
|
+
* - `cascade`: Default cascading behavior where submenus open to the side (portal-based)
|
|
80
|
+
* - `drill-down`: Mobile-friendly behavior where submenus replace the content inline
|
|
81
|
+
* Supports responsive values: `{ initial: 'drill-down', md: 'cascade' }`
|
|
82
|
+
*/
|
|
83
|
+
submenuBehavior?: Responsive<SubmenuBehavior>;
|
|
84
|
+
};
|
|
85
|
+
type DropdownMenuContentContextValue = Omit<DropdownMenuContentOwnProps, 'submenuBehavior'>;
|
|
45
86
|
const DropdownMenuContentContext = React.createContext<DropdownMenuContentContextValue>({});
|
|
46
87
|
type DropdownMenuContentElement = React.ElementRef<typeof DropdownMenuPrimitive.Content>;
|
|
47
88
|
interface DropdownMenuContentProps
|
|
48
89
|
extends ComponentPropsWithout<typeof DropdownMenuPrimitive.Content, RemovedProps>,
|
|
49
90
|
DropdownMenuContentContextValue {
|
|
50
91
|
container?: React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Portal>['container'];
|
|
92
|
+
/**
|
|
93
|
+
* Controls how submenus behave.
|
|
94
|
+
* - `cascade`: Default cascading behavior where submenus open to the side (portal-based)
|
|
95
|
+
* - `drill-down`: Mobile-friendly behavior where submenus replace the content inline
|
|
96
|
+
* Supports responsive values: `{ initial: 'drill-down', md: 'cascade' }`
|
|
97
|
+
*/
|
|
98
|
+
submenuBehavior?: Responsive<SubmenuBehavior>;
|
|
51
99
|
}
|
|
52
100
|
const DropdownMenuContent = React.forwardRef<DropdownMenuContentElement, DropdownMenuContentProps>(
|
|
53
101
|
(props, forwardedRef) => {
|
|
@@ -80,6 +128,7 @@ const DropdownMenuContent = React.forwardRef<DropdownMenuContentElement, Dropdow
|
|
|
80
128
|
variant = dropdownMenuContentPropDefs.variant.default,
|
|
81
129
|
highContrast = dropdownMenuContentPropDefs.highContrast.default,
|
|
82
130
|
material = memoizedThemeContext.material,
|
|
131
|
+
submenuBehavior,
|
|
83
132
|
} = props;
|
|
84
133
|
const {
|
|
85
134
|
className,
|
|
@@ -89,6 +138,7 @@ const DropdownMenuContent = React.forwardRef<DropdownMenuContentElement, Dropdow
|
|
|
89
138
|
forceMount,
|
|
90
139
|
material: _,
|
|
91
140
|
panelBackground: __,
|
|
141
|
+
submenuBehavior: ___,
|
|
92
142
|
...contentProps
|
|
93
143
|
} = extractProps(props, dropdownMenuContentPropDefs);
|
|
94
144
|
|
|
@@ -125,7 +175,9 @@ const DropdownMenuContent = React.forwardRef<DropdownMenuContentElement, Dropdow
|
|
|
125
175
|
[size, variant, resolvedColor, highContrast, material],
|
|
126
176
|
)}
|
|
127
177
|
>
|
|
128
|
-
{
|
|
178
|
+
<DrillDownProvider submenuBehavior={submenuBehavior}>
|
|
179
|
+
<DrillDownRoot>{children}</DrillDownRoot>
|
|
180
|
+
</DrillDownProvider>
|
|
129
181
|
</DropdownMenuContentContext.Provider>
|
|
130
182
|
</div>
|
|
131
183
|
</ScrollArea>
|
|
@@ -298,11 +350,46 @@ const DropdownMenuCheckboxItem = React.forwardRef<
|
|
|
298
350
|
});
|
|
299
351
|
DropdownMenuCheckboxItem.displayName = 'DropdownMenu.CheckboxItem';
|
|
300
352
|
|
|
353
|
+
// Generate unique submenu IDs using React 18's useId for SSR safety
|
|
354
|
+
function useSubId() {
|
|
355
|
+
return React.useId();
|
|
356
|
+
}
|
|
357
|
+
|
|
301
358
|
interface DropdownMenuSubProps
|
|
302
|
-
extends React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Sub> {
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
359
|
+
extends React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Sub> {
|
|
360
|
+
/**
|
|
361
|
+
* Label displayed in the back button when using drill-down mode.
|
|
362
|
+
* If not provided, defaults to "Back".
|
|
363
|
+
*/
|
|
364
|
+
label?: React.ReactNode;
|
|
365
|
+
}
|
|
366
|
+
const DropdownMenuSub: React.FC<DropdownMenuSubProps> = ({ label = 'Back', ...props }) => {
|
|
367
|
+
const drillDown = useDrillDownOptional();
|
|
368
|
+
const subId = useSubId();
|
|
369
|
+
|
|
370
|
+
// Create context value for SubContent and SubTrigger
|
|
371
|
+
const subContextValue = React.useMemo(
|
|
372
|
+
() => ({ id: subId, label }),
|
|
373
|
+
[subId, label]
|
|
374
|
+
);
|
|
375
|
+
|
|
376
|
+
// In drill-down mode, we don't use Radix's Sub component
|
|
377
|
+
// We just provide the SubContext and render children
|
|
378
|
+
if (drillDown?.behavior === 'drill-down') {
|
|
379
|
+
return (
|
|
380
|
+
<SubContext.Provider value={subContextValue}>
|
|
381
|
+
{props.children}
|
|
382
|
+
</SubContext.Provider>
|
|
383
|
+
);
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
// In cascade mode, use Radix's Sub component normally
|
|
387
|
+
return (
|
|
388
|
+
<SubContext.Provider value={subContextValue}>
|
|
389
|
+
<DropdownMenuPrimitive.Sub {...props} />
|
|
390
|
+
</SubContext.Provider>
|
|
391
|
+
);
|
|
392
|
+
};
|
|
306
393
|
DropdownMenuSub.displayName = 'DropdownMenu.Sub';
|
|
307
394
|
|
|
308
395
|
type DropdownMenuSubTriggerElement = React.ElementRef<typeof DropdownMenuPrimitive.SubTrigger>;
|
|
@@ -312,10 +399,53 @@ const DropdownMenuSubTrigger = React.forwardRef<
|
|
|
312
399
|
DropdownMenuSubTriggerElement,
|
|
313
400
|
DropdownMenuSubTriggerProps
|
|
314
401
|
>((props, forwardedRef) => {
|
|
315
|
-
const { className, children, ...subTriggerProps } = props;
|
|
402
|
+
const { className, children, onClick, ...subTriggerProps } = props;
|
|
403
|
+
const drillDown = useDrillDownOptional();
|
|
404
|
+
const subContext = useSubContext();
|
|
405
|
+
|
|
406
|
+
// In drill-down mode, render a button that navigates to the submenu
|
|
407
|
+
if (drillDown?.behavior === 'drill-down' && subContext) {
|
|
408
|
+
const handleClick = (e: React.MouseEvent<HTMLDivElement>) => {
|
|
409
|
+
e.preventDefault();
|
|
410
|
+
drillDown.push(subContext.id);
|
|
411
|
+
(onClick as React.MouseEventHandler<HTMLDivElement> | undefined)?.(e);
|
|
412
|
+
};
|
|
413
|
+
|
|
414
|
+
return (
|
|
415
|
+
<div
|
|
416
|
+
role="menuitem"
|
|
417
|
+
tabIndex={0}
|
|
418
|
+
ref={forwardedRef as React.Ref<HTMLDivElement>}
|
|
419
|
+
onClick={handleClick}
|
|
420
|
+
onKeyDown={(e) => {
|
|
421
|
+
if (e.key === 'Enter' || e.key === ' ') {
|
|
422
|
+
e.preventDefault();
|
|
423
|
+
drillDown.push(subContext.id);
|
|
424
|
+
}
|
|
425
|
+
}}
|
|
426
|
+
className={classNames(
|
|
427
|
+
'rt-reset',
|
|
428
|
+
'rt-BaseMenuItem',
|
|
429
|
+
'rt-BaseMenuSubTrigger',
|
|
430
|
+
'rt-DropdownMenuItem',
|
|
431
|
+
'rt-DropdownMenuSubTrigger',
|
|
432
|
+
'rt-DropdownMenuDrillDownSubTrigger',
|
|
433
|
+
className,
|
|
434
|
+
)}
|
|
435
|
+
>
|
|
436
|
+
{children}
|
|
437
|
+
<div className="rt-BaseMenuShortcut rt-DropdownMenuShortcut">
|
|
438
|
+
<ThickChevronRightIcon className="rt-BaseMenuSubTriggerIcon rt-DropdownMenuSubtriggerIcon" />
|
|
439
|
+
</div>
|
|
440
|
+
</div>
|
|
441
|
+
);
|
|
442
|
+
}
|
|
443
|
+
|
|
444
|
+
// In cascade mode, use Radix's SubTrigger
|
|
316
445
|
return (
|
|
317
446
|
<DropdownMenuPrimitive.SubTrigger
|
|
318
447
|
{...subTriggerProps}
|
|
448
|
+
onClick={onClick as React.MouseEventHandler<HTMLDivElement> | undefined}
|
|
319
449
|
asChild={false}
|
|
320
450
|
ref={forwardedRef}
|
|
321
451
|
className={classNames(
|
|
@@ -335,6 +465,56 @@ const DropdownMenuSubTrigger = React.forwardRef<
|
|
|
335
465
|
});
|
|
336
466
|
DropdownMenuSubTrigger.displayName = 'DropdownMenu.SubTrigger';
|
|
337
467
|
|
|
468
|
+
// Separator is defined here (before SubContent) because it's used in drill-down mode
|
|
469
|
+
type DropdownMenuSeparatorElement = React.ElementRef<typeof DropdownMenuPrimitive.Separator>;
|
|
470
|
+
interface DropdownMenuSeparatorProps
|
|
471
|
+
extends ComponentPropsWithout<typeof DropdownMenuPrimitive.Separator, RemovedProps> {}
|
|
472
|
+
const DropdownMenuSeparator = React.forwardRef<
|
|
473
|
+
DropdownMenuSeparatorElement,
|
|
474
|
+
DropdownMenuSeparatorProps
|
|
475
|
+
>(({ className, ...props }, forwardedRef) => (
|
|
476
|
+
<DropdownMenuPrimitive.Separator
|
|
477
|
+
{...props}
|
|
478
|
+
asChild={false}
|
|
479
|
+
ref={forwardedRef}
|
|
480
|
+
className={classNames('rt-BaseMenuSeparator', 'rt-DropdownMenuSeparator', className)}
|
|
481
|
+
/>
|
|
482
|
+
));
|
|
483
|
+
DropdownMenuSeparator.displayName = 'DropdownMenu.Separator';
|
|
484
|
+
|
|
485
|
+
/**
|
|
486
|
+
* Internal component for the drill-down back button.
|
|
487
|
+
*/
|
|
488
|
+
function DrillDownBackItem({ label }: { label: React.ReactNode }) {
|
|
489
|
+
const drillDown = useDrillDown();
|
|
490
|
+
|
|
491
|
+
return (
|
|
492
|
+
<div
|
|
493
|
+
role="menuitem"
|
|
494
|
+
tabIndex={0}
|
|
495
|
+
onClick={(e) => {
|
|
496
|
+
e.preventDefault();
|
|
497
|
+
drillDown.pop();
|
|
498
|
+
}}
|
|
499
|
+
onKeyDown={(e) => {
|
|
500
|
+
if (e.key === 'Enter' || e.key === ' ') {
|
|
501
|
+
e.preventDefault();
|
|
502
|
+
drillDown.pop();
|
|
503
|
+
}
|
|
504
|
+
}}
|
|
505
|
+
className={classNames(
|
|
506
|
+
'rt-reset',
|
|
507
|
+
'rt-BaseMenuItem',
|
|
508
|
+
'rt-DropdownMenuItem',
|
|
509
|
+
'rt-DropdownMenuDrillDownBackItem',
|
|
510
|
+
)}
|
|
511
|
+
>
|
|
512
|
+
<ThickChevronLeftIcon className="rt-DropdownMenuDrillDownBackIcon" />
|
|
513
|
+
<span className="rt-DropdownMenuDrillDownBackLabel">{label}</span>
|
|
514
|
+
</div>
|
|
515
|
+
);
|
|
516
|
+
}
|
|
517
|
+
|
|
338
518
|
type DropdownMenuSubContentElement = React.ElementRef<typeof DropdownMenuPrimitive.SubContent>;
|
|
339
519
|
interface DropdownMenuSubContentProps
|
|
340
520
|
extends ComponentPropsWithout<typeof DropdownMenuPrimitive.SubContent, RemovedProps>,
|
|
@@ -351,6 +531,8 @@ const DropdownMenuSubContent = React.forwardRef<
|
|
|
351
531
|
() => contextValue,
|
|
352
532
|
[contextValue],
|
|
353
533
|
);
|
|
534
|
+
const drillDown = useDrillDownOptional();
|
|
535
|
+
const subContext = useSubContext();
|
|
354
536
|
|
|
355
537
|
const {
|
|
356
538
|
className,
|
|
@@ -362,8 +544,33 @@ const DropdownMenuSubContent = React.forwardRef<
|
|
|
362
544
|
...subContentProps
|
|
363
545
|
} = extractProps(
|
|
364
546
|
{ size, variant, color, highContrast, material, ...props },
|
|
365
|
-
|
|
547
|
+
dropdownMenuSubContentPropDefs,
|
|
366
548
|
);
|
|
549
|
+
|
|
550
|
+
// In drill-down mode, render inline instead of in a portal
|
|
551
|
+
if (drillDown?.behavior === 'drill-down' && subContext) {
|
|
552
|
+
const isActive = drillDown.isActive(subContext.id);
|
|
553
|
+
|
|
554
|
+
return (
|
|
555
|
+
<div
|
|
556
|
+
ref={forwardedRef as React.Ref<HTMLDivElement>}
|
|
557
|
+
role="menu"
|
|
558
|
+
aria-label={typeof subContext.label === 'string' ? subContext.label : undefined}
|
|
559
|
+
data-drill-down-active={isActive ? true : undefined}
|
|
560
|
+
data-animation-direction={drillDown.animationDirection ?? undefined}
|
|
561
|
+
className={classNames(
|
|
562
|
+
'rt-DropdownMenuDrillDownPanel',
|
|
563
|
+
className,
|
|
564
|
+
)}
|
|
565
|
+
>
|
|
566
|
+
<DrillDownBackItem label={subContext.label} />
|
|
567
|
+
<DropdownMenuSeparator />
|
|
568
|
+
{children}
|
|
569
|
+
</div>
|
|
570
|
+
);
|
|
571
|
+
}
|
|
572
|
+
|
|
573
|
+
// In cascade mode, use Portal and Radix's SubContent
|
|
367
574
|
return (
|
|
368
575
|
<DropdownMenuPrimitive.Portal container={container} forceMount={forceMount}>
|
|
369
576
|
<Theme asChild>
|
|
@@ -399,22 +606,6 @@ const DropdownMenuSubContent = React.forwardRef<
|
|
|
399
606
|
});
|
|
400
607
|
DropdownMenuSubContent.displayName = 'DropdownMenu.SubContent';
|
|
401
608
|
|
|
402
|
-
type DropdownMenuSeparatorElement = React.ElementRef<typeof DropdownMenuPrimitive.Separator>;
|
|
403
|
-
interface DropdownMenuSeparatorProps
|
|
404
|
-
extends ComponentPropsWithout<typeof DropdownMenuPrimitive.Separator, RemovedProps> {}
|
|
405
|
-
const DropdownMenuSeparator = React.forwardRef<
|
|
406
|
-
DropdownMenuSeparatorElement,
|
|
407
|
-
DropdownMenuSeparatorProps
|
|
408
|
-
>(({ className, ...props }, forwardedRef) => (
|
|
409
|
-
<DropdownMenuPrimitive.Separator
|
|
410
|
-
{...props}
|
|
411
|
-
asChild={false}
|
|
412
|
-
ref={forwardedRef}
|
|
413
|
-
className={classNames('rt-BaseMenuSeparator', 'rt-DropdownMenuSeparator', className)}
|
|
414
|
-
/>
|
|
415
|
-
));
|
|
416
|
-
DropdownMenuSeparator.displayName = 'DropdownMenu.Separator';
|
|
417
|
-
|
|
418
609
|
type DropdownMenuTriggerIconElement = React.ElementRef<'svg'>;
|
|
419
610
|
interface DropdownMenuTriggerIconProps extends IconProps {}
|
|
420
611
|
const DropdownMenuTriggerIcon = React.forwardRef<
|
|
@@ -457,4 +648,5 @@ export type {
|
|
|
457
648
|
DropdownMenuSubTriggerProps as SubTriggerProps,
|
|
458
649
|
DropdownMenuSubContentProps as SubContentProps,
|
|
459
650
|
DropdownMenuSeparatorProps as SeparatorProps,
|
|
651
|
+
SubmenuBehavior,
|
|
460
652
|
};
|
package/src/components/icons.tsx
CHANGED
|
@@ -54,6 +54,19 @@ const ThickChevronRightIcon = React.forwardRef<IconElement, IconProps>((props, f
|
|
|
54
54
|
});
|
|
55
55
|
ThickChevronRightIcon.displayName = 'ThickChevronRightIcon';
|
|
56
56
|
|
|
57
|
+
const ThickChevronLeftIcon = React.forwardRef<IconElement, IconProps>((props, forwardedRef) => {
|
|
58
|
+
return (
|
|
59
|
+
<svg width="9" height="9" viewBox="0 0 9 9" fill="currentcolor" xmlns="http://www.w3.org/2000/svg" {...props} ref={forwardedRef}>
|
|
60
|
+
<path
|
|
61
|
+
fillRule="evenodd"
|
|
62
|
+
clipRule="evenodd"
|
|
63
|
+
d="M5.76174 0.201711C5.45892 -0.0809141 4.98433 -0.0645489 4.70171 0.238264L1.20171 3.98826C0.932757 4.27642 0.932757 4.72359 1.20171 5.01174L4.70171 8.76174C4.98433 9.06455 5.45892 9.08092 5.76174 8.79829C6.06455 8.51567 6.08091 8.04108 5.79829 7.73826L2.77591 4.5L5.79829 1.26174C6.08091 0.958928 6.06455 0.484337 5.76174 0.201711Z"
|
|
64
|
+
/>
|
|
65
|
+
</svg>
|
|
66
|
+
);
|
|
67
|
+
});
|
|
68
|
+
ThickChevronLeftIcon.displayName = 'ThickChevronLeftIcon';
|
|
69
|
+
|
|
57
70
|
const ThickDotIcon = React.forwardRef<IconElement, IconProps>((props, forwardedRef) => {
|
|
58
71
|
return (
|
|
59
72
|
<svg width="9" height="9" viewBox="0 0 9 9" fill="currentcolor" xmlns="http://www.w3.org/2000/svg" {...props} ref={forwardedRef}>
|
|
@@ -63,7 +76,7 @@ const ThickDotIcon = React.forwardRef<IconElement, IconProps>((props, forwardedR
|
|
|
63
76
|
});
|
|
64
77
|
ThickDotIcon.displayName = 'ThickDotIcon';
|
|
65
78
|
|
|
66
|
-
export { ChevronDownIcon, ThickCheckIcon, ThickChevronRightIcon, ThickDividerHorizontalIcon, ThickDotIcon };
|
|
79
|
+
export { ChevronDownIcon, ThickCheckIcon, ThickChevronLeftIcon, ThickChevronRightIcon, ThickDividerHorizontalIcon, ThickDotIcon };
|
|
67
80
|
export type { IconProps };
|
|
68
81
|
|
|
69
82
|
// Additional minimal icons
|
package/styles.css
CHANGED
|
@@ -5422,6 +5422,26 @@
|
|
|
5422
5422
|
animation: rt-tab-indicator-appear var(--motion-duration-small) var(--motion-spring-snappy);
|
|
5423
5423
|
}
|
|
5424
5424
|
}
|
|
5425
|
+
@keyframes rt-drill-down-enter-from-right {
|
|
5426
|
+
from{
|
|
5427
|
+
opacity: 0;
|
|
5428
|
+
transform: translateX(30%);
|
|
5429
|
+
}
|
|
5430
|
+
to{
|
|
5431
|
+
opacity: 1;
|
|
5432
|
+
transform: translateX(0);
|
|
5433
|
+
}
|
|
5434
|
+
}
|
|
5435
|
+
@keyframes rt-drill-down-enter-from-left {
|
|
5436
|
+
from{
|
|
5437
|
+
opacity: 0;
|
|
5438
|
+
transform: translateX(-30%);
|
|
5439
|
+
}
|
|
5440
|
+
to{
|
|
5441
|
+
opacity: 1;
|
|
5442
|
+
transform: translateX(0);
|
|
5443
|
+
}
|
|
5444
|
+
}
|
|
5425
5445
|
@keyframes rt-dialog-overlay-no-op {
|
|
5426
5446
|
from{
|
|
5427
5447
|
opacity: 1;
|
|
@@ -13680,6 +13700,110 @@
|
|
|
13680
13700
|
height: var(--trigger-icon-size-4);
|
|
13681
13701
|
}
|
|
13682
13702
|
}
|
|
13703
|
+
.rt-DropdownMenuDrillDownRoot{
|
|
13704
|
+
display: contents;
|
|
13705
|
+
}
|
|
13706
|
+
.rt-DropdownMenuDrillDownRoot:where([data-drill-down-active]) > *{
|
|
13707
|
+
display: none !important;
|
|
13708
|
+
}
|
|
13709
|
+
.rt-DropdownMenuDrillDownRoot:where([data-drill-down-active]) > :where(.rt-DropdownMenuDrillDownPanel){
|
|
13710
|
+
display: contents !important;
|
|
13711
|
+
}
|
|
13712
|
+
.rt-DropdownMenuDrillDownPanel{
|
|
13713
|
+
display: contents;
|
|
13714
|
+
}
|
|
13715
|
+
.rt-DropdownMenuDrillDownPanel:where(:not([data-drill-down-active])) > *{
|
|
13716
|
+
display: none !important;
|
|
13717
|
+
}
|
|
13718
|
+
.rt-DropdownMenuDrillDownPanel:where(:not([data-drill-down-active])) > :where(.rt-DropdownMenuDrillDownPanel){
|
|
13719
|
+
display: contents !important;
|
|
13720
|
+
}
|
|
13721
|
+
.rt-DropdownMenuDrillDownBackItem{
|
|
13722
|
+
display: flex;
|
|
13723
|
+
align-items: center;
|
|
13724
|
+
gap: var(--space-2);
|
|
13725
|
+
min-height: var(--base-menu-item-height);
|
|
13726
|
+
padding-top: var(--base-menu-item-padding-y);
|
|
13727
|
+
padding-bottom: var(--base-menu-item-padding-y);
|
|
13728
|
+
padding-inline-start: var(--base-menu-item-padding-left);
|
|
13729
|
+
padding-inline-end: var(--base-menu-item-padding-right);
|
|
13730
|
+
box-sizing: border-box;
|
|
13731
|
+
outline: none;
|
|
13732
|
+
cursor: var(--cursor-menu-item);
|
|
13733
|
+
-webkit-user-select: none;
|
|
13734
|
+
-moz-user-select: none;
|
|
13735
|
+
user-select: none;
|
|
13736
|
+
transition: var(--transition-menu);
|
|
13737
|
+
font-weight: 500;
|
|
13738
|
+
}
|
|
13739
|
+
.rt-DropdownMenuDrillDownBackItem:where(:focus-visible){
|
|
13740
|
+
outline: 2px solid var(--focus-8);
|
|
13741
|
+
outline-offset: -2px;
|
|
13742
|
+
}
|
|
13743
|
+
@media (prefers-reduced-motion: reduce) {
|
|
13744
|
+
.rt-DropdownMenuDrillDownBackItem{
|
|
13745
|
+
transition: none;
|
|
13746
|
+
}
|
|
13747
|
+
}
|
|
13748
|
+
.rt-DropdownMenuDrillDownBackIcon{
|
|
13749
|
+
width: var(--indicator-icon-size-2);
|
|
13750
|
+
height: var(--indicator-icon-size-2);
|
|
13751
|
+
flex-shrink: 0;
|
|
13752
|
+
color: var(--gray-12);
|
|
13753
|
+
}
|
|
13754
|
+
.rt-DropdownMenuDrillDownBackLabel{
|
|
13755
|
+
color: var(--gray-12);
|
|
13756
|
+
}
|
|
13757
|
+
.rt-BaseMenuContent:where(.rt-variant-solid) :where(.rt-DropdownMenuDrillDownBackItem:hover),
|
|
13758
|
+
.rt-BaseMenuContent:where(.rt-variant-solid) :where(.rt-DropdownMenuDrillDownBackItem:focus-visible),
|
|
13759
|
+
.rt-BaseMenuContent:where(.rt-variant-solid) :where(.rt-DropdownMenuDrillDownSubTrigger:hover),
|
|
13760
|
+
.rt-BaseMenuContent:where(.rt-variant-solid) :where(.rt-DropdownMenuDrillDownSubTrigger:focus-visible){
|
|
13761
|
+
background-color: var(--accent-9);
|
|
13762
|
+
color: var(--accent-contrast);
|
|
13763
|
+
}
|
|
13764
|
+
.rt-BaseMenuContent:where(.rt-variant-solid) :where(.rt-DropdownMenuDrillDownBackItem:hover) :where(.rt-DropdownMenuDrillDownBackIcon),
|
|
13765
|
+
.rt-BaseMenuContent:where(.rt-variant-solid) :where(.rt-DropdownMenuDrillDownBackItem:focus-visible) :where(.rt-DropdownMenuDrillDownBackIcon),
|
|
13766
|
+
.rt-BaseMenuContent:where(.rt-variant-solid) :where(.rt-DropdownMenuDrillDownSubTrigger:hover) :where(.rt-DropdownMenuDrillDownBackIcon),
|
|
13767
|
+
.rt-BaseMenuContent:where(.rt-variant-solid) :where(.rt-DropdownMenuDrillDownSubTrigger:focus-visible) :where(.rt-DropdownMenuDrillDownBackIcon),
|
|
13768
|
+
.rt-BaseMenuContent:where(.rt-variant-solid) :where(.rt-DropdownMenuDrillDownBackItem:hover) :where(.rt-DropdownMenuDrillDownBackLabel),
|
|
13769
|
+
.rt-BaseMenuContent:where(.rt-variant-solid) :where(.rt-DropdownMenuDrillDownBackItem:focus-visible) :where(.rt-DropdownMenuDrillDownBackLabel),
|
|
13770
|
+
.rt-BaseMenuContent:where(.rt-variant-solid) :where(.rt-DropdownMenuDrillDownSubTrigger:hover) :where(.rt-DropdownMenuDrillDownBackLabel),
|
|
13771
|
+
.rt-BaseMenuContent:where(.rt-variant-solid) :where(.rt-DropdownMenuDrillDownSubTrigger:focus-visible) :where(.rt-DropdownMenuDrillDownBackLabel),
|
|
13772
|
+
.rt-BaseMenuContent:where(.rt-variant-solid) :where(.rt-DropdownMenuDrillDownBackItem:hover) :where(.rt-BaseMenuSubTriggerIcon),
|
|
13773
|
+
.rt-BaseMenuContent:where(.rt-variant-solid) :where(.rt-DropdownMenuDrillDownBackItem:focus-visible) :where(.rt-BaseMenuSubTriggerIcon),
|
|
13774
|
+
.rt-BaseMenuContent:where(.rt-variant-solid) :where(.rt-DropdownMenuDrillDownSubTrigger:hover) :where(.rt-BaseMenuSubTriggerIcon),
|
|
13775
|
+
.rt-BaseMenuContent:where(.rt-variant-solid) :where(.rt-DropdownMenuDrillDownSubTrigger:focus-visible) :where(.rt-BaseMenuSubTriggerIcon){
|
|
13776
|
+
color: var(--accent-contrast);
|
|
13777
|
+
}
|
|
13778
|
+
.rt-BaseMenuContent:where(.rt-variant-soft) :where(.rt-DropdownMenuDrillDownBackItem:hover),
|
|
13779
|
+
.rt-BaseMenuContent:where(.rt-variant-soft) :where(.rt-DropdownMenuDrillDownBackItem:focus-visible),
|
|
13780
|
+
.rt-BaseMenuContent:where(.rt-variant-soft) :where(.rt-DropdownMenuDrillDownSubTrigger:hover),
|
|
13781
|
+
.rt-BaseMenuContent:where(.rt-variant-soft) :where(.rt-DropdownMenuDrillDownSubTrigger:focus-visible){
|
|
13782
|
+
background-color: var(--accent-4);
|
|
13783
|
+
}
|
|
13784
|
+
:where([data-panel-background='translucent']) .rt-BaseMenuContent:where(.rt-variant-soft) :where(.rt-DropdownMenuDrillDownBackItem:hover),
|
|
13785
|
+
:where([data-panel-background='translucent']) .rt-BaseMenuContent:where(.rt-variant-soft) :where(.rt-DropdownMenuDrillDownBackItem:focus-visible),
|
|
13786
|
+
:where([data-panel-background='translucent']) .rt-BaseMenuContent:where(.rt-variant-soft) :where(.rt-DropdownMenuDrillDownSubTrigger:hover),
|
|
13787
|
+
:where([data-panel-background='translucent']) .rt-BaseMenuContent:where(.rt-variant-soft) :where(.rt-DropdownMenuDrillDownSubTrigger:focus-visible){
|
|
13788
|
+
background-color: var(--accent-a4);
|
|
13789
|
+
}
|
|
13790
|
+
@media (forced-colors: active) {
|
|
13791
|
+
.rt-DropdownMenuDrillDownBackItem:where(:focus-visible){
|
|
13792
|
+
outline: 2px solid Highlight;
|
|
13793
|
+
outline-offset: 2px;
|
|
13794
|
+
}
|
|
13795
|
+
}
|
|
13796
|
+
@media (prefers-reduced-motion: no-preference) {
|
|
13797
|
+
.rt-DropdownMenuDrillDownPanel:where([data-drill-down-active][data-animation-direction='forward']) > :where(*:not(.rt-DropdownMenuDrillDownPanel)){
|
|
13798
|
+
animation: rt-drill-down-enter-from-right var(--motion-duration-small) var(--motion-ease-smooth);
|
|
13799
|
+
}
|
|
13800
|
+
.rt-DropdownMenuDrillDownPanel:where([data-drill-down-active][data-animation-direction='backward']) > :where(*:not(.rt-DropdownMenuDrillDownPanel)){
|
|
13801
|
+
animation: rt-drill-down-enter-from-left var(--motion-duration-small) var(--motion-ease-smooth);
|
|
13802
|
+
}
|
|
13803
|
+
.rt-DropdownMenuDrillDownRoot:where(:not([data-drill-down-active])[data-animation-direction='backward']) > :where(*:not(.rt-DropdownMenuDrillDownPanel)){
|
|
13804
|
+
animation: rt-drill-down-enter-from-left var(--motion-duration-small) var(--motion-ease-smooth);
|
|
13805
|
+
}
|
|
13806
|
+
}
|
|
13683
13807
|
:where([data-panel-background='translucent'], [data-material='translucent']) .rt-TextFieldRoot{
|
|
13684
13808
|
-webkit-backdrop-filter: var(--backdrop-filter-components);
|
|
13685
13809
|
backdrop-filter: var(--backdrop-filter-components);
|