@tinybigui/react 0.21.1 → 0.23.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.md +9 -9
- package/dist/index.cjs +758 -331
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +156 -30
- package/dist/index.d.ts +156 -30
- package/dist/index.js +758 -331
- package/dist/index.js.map +1 -1
- package/dist/styles.css +1 -19
- package/dist/styles.css.map +1 -1
- package/package.json +2 -2
package/dist/index.cjs
CHANGED
|
@@ -472,6 +472,10 @@ var buttonVariants = classVarianceAuthority.cva(
|
|
|
472
472
|
* Filled/Tonal hover→level-1, focus/pressed→level-0
|
|
473
473
|
* Elevated base→level-1, hover→level-2, focus/pressed→level-1
|
|
474
474
|
* Outlined/Text no elevation
|
|
475
|
+
*
|
|
476
|
+
* Self-targeting `data-[x]:` is used for elevation because these classes
|
|
477
|
+
* sit on the root element (the group host) — group-data descendant
|
|
478
|
+
* selectors cannot match an element against itself.
|
|
475
479
|
*/
|
|
476
480
|
variant: {
|
|
477
481
|
/**
|
|
@@ -480,17 +484,17 @@ var buttonVariants = classVarianceAuthority.cva(
|
|
|
480
484
|
* Elevation: 0 base → 1 hover → 0 focus → 0 pressed
|
|
481
485
|
*/
|
|
482
486
|
filled: [
|
|
483
|
-
"
|
|
487
|
+
"text-on-primary shadow-none",
|
|
484
488
|
// Hover: gains level-1 elevation
|
|
485
|
-
"
|
|
489
|
+
"data-[hovered]:shadow-elevation-1",
|
|
486
490
|
// Focus/pressed: shadow must explicitly return to level-0
|
|
487
491
|
// (doubled attribute selector → higher specificity than hover)
|
|
488
|
-
"
|
|
489
|
-
"
|
|
490
|
-
// Disabled overrides
|
|
491
|
-
|
|
492
|
-
"
|
|
493
|
-
"
|
|
492
|
+
"data-[focus-visible]:data-[focus-visible]:shadow-none",
|
|
493
|
+
"data-[pressed]:data-[pressed]:data-[pressed]:shadow-none",
|
|
494
|
+
// Disabled overrides — root owns text color + shadow only;
|
|
495
|
+
// disabled bg override lives on buttonContainerVariants (filled variant)
|
|
496
|
+
"data-[disabled]:text-on-surface/38",
|
|
497
|
+
"data-[disabled]:shadow-none"
|
|
494
498
|
],
|
|
495
499
|
/**
|
|
496
500
|
* Outlined — medium emphasis. Transparent with border.
|
|
@@ -498,10 +502,10 @@ var buttonVariants = classVarianceAuthority.cva(
|
|
|
498
502
|
* Elevation: always 0
|
|
499
503
|
*/
|
|
500
504
|
outlined: [
|
|
501
|
-
"
|
|
505
|
+
"border border-outline text-primary",
|
|
502
506
|
// Disabled overrides
|
|
503
|
-
"
|
|
504
|
-
"
|
|
507
|
+
"data-[disabled]:border-on-surface/12",
|
|
508
|
+
"data-[disabled]:text-on-surface/38"
|
|
505
509
|
],
|
|
506
510
|
/**
|
|
507
511
|
* Tonal — secondary emphasis.
|
|
@@ -509,16 +513,15 @@ var buttonVariants = classVarianceAuthority.cva(
|
|
|
509
513
|
* Elevation: 0 base → 1 hover → 0 focus → 0 pressed
|
|
510
514
|
*/
|
|
511
515
|
tonal: [
|
|
512
|
-
"
|
|
516
|
+
"text-on-secondary-container shadow-none",
|
|
513
517
|
// Hover: gains level-1 elevation (same as filled)
|
|
514
|
-
"
|
|
518
|
+
"data-[hovered]:shadow-elevation-1",
|
|
515
519
|
// Focus/pressed: return to level-0
|
|
516
|
-
"
|
|
517
|
-
"
|
|
520
|
+
"data-[focus-visible]:data-[focus-visible]:shadow-none",
|
|
521
|
+
"data-[pressed]:data-[pressed]:data-[pressed]:shadow-none",
|
|
518
522
|
// Disabled overrides
|
|
519
|
-
"
|
|
520
|
-
"
|
|
521
|
-
"group-data-[disabled]/button:shadow-none"
|
|
523
|
+
"data-[disabled]:text-on-surface/38",
|
|
524
|
+
"data-[disabled]:shadow-none"
|
|
522
525
|
],
|
|
523
526
|
/**
|
|
524
527
|
* Elevated — separation via shadow.
|
|
@@ -526,17 +529,16 @@ var buttonVariants = classVarianceAuthority.cva(
|
|
|
526
529
|
* Elevation: 1 base → 2 hover → 1 focus → 1 pressed
|
|
527
530
|
*/
|
|
528
531
|
elevated: [
|
|
529
|
-
"
|
|
532
|
+
"text-primary shadow-elevation-1",
|
|
530
533
|
// Hover: gains extra elevation
|
|
531
|
-
"
|
|
534
|
+
"data-[hovered]:shadow-elevation-2",
|
|
532
535
|
// Focus/pressed: return to base level-1
|
|
533
536
|
// (doubled selector wins over single hover selector at same cascade position)
|
|
534
|
-
"
|
|
535
|
-
"
|
|
537
|
+
"data-[focus-visible]:data-[focus-visible]:shadow-elevation-1",
|
|
538
|
+
"data-[pressed]:data-[pressed]:data-[pressed]:shadow-elevation-1",
|
|
536
539
|
// Disabled overrides
|
|
537
|
-
"
|
|
538
|
-
"
|
|
539
|
-
"group-data-[disabled]/button:shadow-none"
|
|
540
|
+
"data-[disabled]:text-on-surface/38",
|
|
541
|
+
"data-[disabled]:shadow-none"
|
|
540
542
|
],
|
|
541
543
|
/**
|
|
542
544
|
* Text — lowest emphasis.
|
|
@@ -544,9 +546,9 @@ var buttonVariants = classVarianceAuthority.cva(
|
|
|
544
546
|
* Elevation: always 0
|
|
545
547
|
*/
|
|
546
548
|
text: [
|
|
547
|
-
"
|
|
549
|
+
"text-primary",
|
|
548
550
|
// Disabled overrides
|
|
549
|
-
"
|
|
551
|
+
"data-[disabled]:text-on-surface/38"
|
|
550
552
|
]
|
|
551
553
|
},
|
|
552
554
|
/**
|
|
@@ -584,6 +586,29 @@ var buttonVariants = classVarianceAuthority.cva(
|
|
|
584
586
|
}
|
|
585
587
|
}
|
|
586
588
|
);
|
|
589
|
+
var buttonContainerVariants = classVarianceAuthority.cva(
|
|
590
|
+
[
|
|
591
|
+
"absolute inset-0 rounded-[inherit] pointer-events-none",
|
|
592
|
+
// Effects transition for background-color — no overshoot
|
|
593
|
+
"transition-[background-color] duration-spring-standard-fast-effects ease-spring-standard-fast-effects"
|
|
594
|
+
],
|
|
595
|
+
{
|
|
596
|
+
variants: {
|
|
597
|
+
variant: {
|
|
598
|
+
// MD3 disabled: filled containers replace bg with on-surface/12.
|
|
599
|
+
// group-data descendant selector targets this child span (not the root host).
|
|
600
|
+
filled: "bg-primary group-data-[disabled]/button:bg-on-surface/12",
|
|
601
|
+
// outlined/text: container stays transparent when disabled — only border + label fade.
|
|
602
|
+
outlined: "bg-transparent",
|
|
603
|
+
// MD3 disabled: tonal and elevated containers also replace bg with on-surface/12.
|
|
604
|
+
tonal: "bg-secondary-container group-data-[disabled]/button:bg-on-surface/12",
|
|
605
|
+
elevated: "bg-surface-container-low group-data-[disabled]/button:bg-on-surface/12",
|
|
606
|
+
text: "bg-transparent"
|
|
607
|
+
}
|
|
608
|
+
},
|
|
609
|
+
defaultVariants: { variant: "filled" }
|
|
610
|
+
}
|
|
611
|
+
);
|
|
587
612
|
var buttonStateLayerVariants = classVarianceAuthority.cva(
|
|
588
613
|
[
|
|
589
614
|
"absolute inset-0 rounded-[inherit] overflow-hidden pointer-events-none opacity-0",
|
|
@@ -886,6 +911,7 @@ var Button = React.forwardRef(
|
|
|
886
911
|
className
|
|
887
912
|
),
|
|
888
913
|
children: [
|
|
914
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: cn(buttonContainerVariants({ variant })), "aria-hidden": "true" }),
|
|
889
915
|
ripples,
|
|
890
916
|
/* @__PURE__ */ jsxRuntime.jsx("span", { className: cn(buttonStateLayerVariants({ variant })), "aria-hidden": "true" }),
|
|
891
917
|
/* @__PURE__ */ jsxRuntime.jsx("span", { className: cn(buttonFocusRingVariants()), "aria-hidden": "true" }),
|
|
@@ -5952,293 +5978,526 @@ var CardActions = React.forwardRef(function CardActions2({ children, className }
|
|
|
5952
5978
|
return /* @__PURE__ */ jsxRuntime.jsx("div", { ref, className: cn("flex items-center justify-end gap-2 p-4 pt-0", className), children });
|
|
5953
5979
|
});
|
|
5954
5980
|
CardActions.displayName = "CardActions";
|
|
5955
|
-
var MenuContext = React.createContext(null);
|
|
5956
|
-
function useMenuContext() {
|
|
5957
|
-
return React.useContext(MenuContext);
|
|
5958
|
-
}
|
|
5959
|
-
function TriggerBridge({ children }) {
|
|
5960
|
-
const ctx = reactAriaComponents.useSlottedContext(reactAriaComponents.ButtonContext);
|
|
5961
|
-
const localRef = React.useRef(null);
|
|
5962
|
-
const { ref: contextRef, ...ctxProps } = ctx ?? {};
|
|
5963
|
-
const mergedCallbackRef = React.useCallback(
|
|
5964
|
-
(node) => {
|
|
5965
|
-
localRef.current = node;
|
|
5966
|
-
if (!contextRef) return;
|
|
5967
|
-
if (typeof contextRef === "function") {
|
|
5968
|
-
contextRef(node);
|
|
5969
|
-
} else {
|
|
5970
|
-
contextRef.current = node;
|
|
5971
|
-
}
|
|
5972
|
-
},
|
|
5973
|
-
[contextRef]
|
|
5974
|
-
);
|
|
5975
|
-
const { buttonProps } = reactAria.useButton({ ...ctxProps, elementType: "button" }, localRef);
|
|
5976
|
-
if (!React.isValidElement(children)) return /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children });
|
|
5977
|
-
return React.cloneElement(
|
|
5978
|
-
children,
|
|
5979
|
-
{ ...buttonProps, ref: mergedCallbackRef }
|
|
5980
|
-
);
|
|
5981
|
-
}
|
|
5982
|
-
function HeadlessMenuTrigger({
|
|
5983
|
-
children,
|
|
5984
|
-
placement = "bottom start",
|
|
5985
|
-
shouldFlip = true,
|
|
5986
|
-
...rest
|
|
5987
|
-
}) {
|
|
5988
|
-
const childrenArray = Array.isArray(children) ? children : [children];
|
|
5989
|
-
const [triggerChild, menuChild] = childrenArray;
|
|
5990
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(reactAriaComponents.MenuTrigger, { ...rest, children: [
|
|
5991
|
-
/* @__PURE__ */ jsxRuntime.jsx(TriggerBridge, { children: triggerChild }),
|
|
5992
|
-
/* @__PURE__ */ jsxRuntime.jsx(reactAriaComponents.Popover, { placement, shouldFlip, offset: 4, children: menuChild })
|
|
5993
|
-
] });
|
|
5994
|
-
}
|
|
5995
|
-
function HeadlessMenu({
|
|
5996
|
-
className,
|
|
5997
|
-
children,
|
|
5998
|
-
"aria-label": ariaLabel,
|
|
5999
|
-
...props
|
|
6000
|
-
}) {
|
|
6001
|
-
const menuRef = React.useRef(null);
|
|
6002
|
-
React.useLayoutEffect(() => {
|
|
6003
|
-
if (ariaLabel && menuRef.current) {
|
|
6004
|
-
menuRef.current.removeAttribute("aria-labelledby");
|
|
6005
|
-
}
|
|
6006
|
-
});
|
|
6007
|
-
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
6008
|
-
reactAriaComponents.Menu,
|
|
6009
|
-
{
|
|
6010
|
-
...props,
|
|
6011
|
-
ref: menuRef,
|
|
6012
|
-
...ariaLabel !== void 0 ? { "aria-label": ariaLabel } : {},
|
|
6013
|
-
className: className ?? "",
|
|
6014
|
-
children
|
|
6015
|
-
}
|
|
6016
|
-
);
|
|
6017
|
-
}
|
|
6018
|
-
HeadlessMenuTrigger.Menu = HeadlessMenu;
|
|
6019
|
-
var HeadlessMenuItem = React.forwardRef(
|
|
6020
|
-
function HeadlessMenuItem2({ children, className, ...props }, ref) {
|
|
6021
|
-
return /* @__PURE__ */ jsxRuntime.jsx(reactAriaComponents.MenuItem, { ...props, ref, className: className ?? "", children });
|
|
6022
|
-
}
|
|
6023
|
-
);
|
|
6024
|
-
function HeadlessMenuSection({
|
|
6025
|
-
children,
|
|
6026
|
-
"aria-label": ariaLabel,
|
|
6027
|
-
className
|
|
6028
|
-
}) {
|
|
6029
|
-
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
6030
|
-
reactAriaComponents.MenuSection,
|
|
6031
|
-
{
|
|
6032
|
-
...ariaLabel !== void 0 ? { "aria-label": ariaLabel } : {},
|
|
6033
|
-
className: className ?? "",
|
|
6034
|
-
children
|
|
6035
|
-
}
|
|
6036
|
-
);
|
|
6037
|
-
}
|
|
6038
|
-
function HeadlessMenuDivider({
|
|
6039
|
-
className,
|
|
6040
|
-
...props
|
|
6041
|
-
}) {
|
|
6042
|
-
return /* @__PURE__ */ jsxRuntime.jsx(reactAriaComponents.Separator, { ...props, className: className ?? "" });
|
|
6043
|
-
}
|
|
6044
5981
|
var menuContainerVariants = classVarianceAuthority.cva(
|
|
6045
5982
|
[
|
|
6046
|
-
//
|
|
6047
|
-
"shadow-elevation-2",
|
|
6048
|
-
// Width constraints per MD3 spec (112dp min / 280dp max)
|
|
5983
|
+
// Width constraints: 112dp min / 280dp max per MD3 spec
|
|
6049
5984
|
"min-w-28 max-w-70",
|
|
6050
|
-
|
|
6051
|
-
|
|
6052
|
-
// Scroll: show scrollbar when content overflows; max height avoids clipping
|
|
6053
|
-
"overflow-y-auto",
|
|
5985
|
+
"flex flex-col",
|
|
5986
|
+
// Scroll behaviour
|
|
6054
5987
|
"max-h-[calc(var(--visual-viewport-height,100vh)-2rem)]",
|
|
6055
5988
|
// Stacking
|
|
6056
5989
|
"z-50",
|
|
6057
|
-
|
|
6058
|
-
|
|
6059
|
-
|
|
6060
|
-
// scale + opacity animations run without triggering layout reflow.
|
|
6061
|
-
"will-change-[transform,opacity]",
|
|
6062
|
-
// Pointer events blocked during animation to prevent accidental clicks
|
|
6063
|
-
// on menu items while the panel is still animating in or out.
|
|
6064
|
-
"data-[entering]:pointer-events-none data-[exiting]:pointer-events-none",
|
|
6065
|
-
// ── Enter animation ────────────────────────────────────────────────────
|
|
6066
|
-
// @keyframes menu-enter (defined in styles.css): scale(0.8)+opacity:0 →
|
|
6067
|
-
// scale(1)+opacity:1 in 120ms with cubic-bezier(0,0,0.2,1) (standard
|
|
6068
|
-
// decelerate — matches Angular Material's _mat-menu-enter keyframe).
|
|
6069
|
-
"data-[entering]:animate-[menu-enter_120ms_cubic-bezier(0,0,0.2,1)_both]",
|
|
6070
|
-
// ── Exit animation ─────────────────────────────────────────────────────
|
|
6071
|
-
// @keyframes menu-exit (defined in styles.css): opacity:1 → opacity:0
|
|
6072
|
-
// in 100ms after 25ms delay, linear — matches Angular Material's
|
|
6073
|
-
// _mat-menu-exit keyframe (fade-only, no reverse scale).
|
|
6074
|
-
"data-[exiting]:animate-[menu-exit_100ms_25ms_linear_both]",
|
|
6075
|
-
// ── Transform origin (placement-aware) ────────────────────────────────
|
|
6076
|
-
// RAC sets data-placement="bottom|top|left|right" on the Popover element.
|
|
6077
|
-
// Default (bottom): origin at top edge (menu expands downward).
|
|
6078
|
-
"origin-top",
|
|
6079
|
-
// top: origin at bottom edge (menu expands upward)
|
|
6080
|
-
"data-[placement=top]:origin-bottom",
|
|
6081
|
-
// left: origin at right edge
|
|
6082
|
-
"data-[placement=left]:origin-right",
|
|
6083
|
-
// right: origin at left edge
|
|
6084
|
-
"data-[placement=right]:origin-left",
|
|
6085
|
-
// ── Reduced motion ────────────────────────────────────────────────────
|
|
6086
|
-
// Skip both animations entirely for users who prefer reduced motion.
|
|
6087
|
-
"motion-reduce:data-[entering]:animate-none motion-reduce:data-[exiting]:animate-none"
|
|
5990
|
+
"gap-0.5",
|
|
5991
|
+
// Focus outline delegated to React Aria
|
|
5992
|
+
"outline-none"
|
|
6088
5993
|
],
|
|
6089
5994
|
{
|
|
6090
5995
|
variants: {
|
|
6091
5996
|
/**
|
|
6092
|
-
* Color scheme — drives
|
|
6093
|
-
*
|
|
5997
|
+
* Color scheme — drives item/segment background and content colors.
|
|
5998
|
+
* standard: surface-container-low item background.
|
|
5999
|
+
* vibrant: tertiary-container item background.
|
|
6094
6000
|
*/
|
|
6095
6001
|
colorScheme: {
|
|
6096
6002
|
standard: [],
|
|
6097
6003
|
vibrant: []
|
|
6098
6004
|
},
|
|
6099
6005
|
/**
|
|
6100
|
-
* Visual style — drives corner radius and
|
|
6006
|
+
* Visual style — drives corner radius and container background.
|
|
6007
|
+
*
|
|
6008
|
+
* baseline: solid surface-container, 4dp corners, 8dp vertical padding.
|
|
6009
|
+
* vertical: transparent container, 16dp corners, no container padding —
|
|
6010
|
+
* items own their segment surface, gaps reveal the page background.
|
|
6101
6011
|
*/
|
|
6102
6012
|
menuStyle: {
|
|
6103
|
-
baseline: ["rounded-xs", "bg-surface-container"],
|
|
6104
|
-
vertical: ["
|
|
6013
|
+
baseline: ["rounded-xs", "bg-surface-container", "py-2"],
|
|
6014
|
+
vertical: ["bg-transparent"]
|
|
6105
6015
|
}
|
|
6106
6016
|
},
|
|
6107
|
-
compoundVariants: [
|
|
6108
|
-
// Vertical + vibrant: tertiary container background
|
|
6109
|
-
{
|
|
6110
|
-
menuStyle: "vertical",
|
|
6111
|
-
colorScheme: "vibrant",
|
|
6112
|
-
class: ["bg-tertiary-container"]
|
|
6113
|
-
}
|
|
6114
|
-
],
|
|
6115
6017
|
defaultVariants: {
|
|
6116
6018
|
colorScheme: "standard",
|
|
6117
6019
|
menuStyle: "baseline"
|
|
6118
6020
|
}
|
|
6119
6021
|
}
|
|
6120
6022
|
);
|
|
6023
|
+
var menuPopoverVariants = classVarianceAuthority.cva([
|
|
6024
|
+
"will-change-[transform,opacity]",
|
|
6025
|
+
"data-[entering]:pointer-events-none data-[exiting]:pointer-events-none",
|
|
6026
|
+
"data-[entering]:animate-md-scale-in",
|
|
6027
|
+
"data-[exiting]:animate-md-scale-out",
|
|
6028
|
+
"origin-top",
|
|
6029
|
+
"data-[placement=top]:origin-bottom",
|
|
6030
|
+
"data-[placement=left]:origin-right",
|
|
6031
|
+
"data-[placement=right]:origin-left",
|
|
6032
|
+
"motion-reduce:data-[entering]:animate-none motion-reduce:data-[exiting]:animate-none"
|
|
6033
|
+
]);
|
|
6121
6034
|
var menuItemVariants = classVarianceAuthority.cva(
|
|
6122
6035
|
[
|
|
6123
6036
|
// Layout — height set by density context in MenuItem component
|
|
6037
|
+
// gap is style-specific: baseline = 12dp (gap-3), vertical = 8dp (gap-2)
|
|
6124
6038
|
"relative flex w-full items-center",
|
|
6125
|
-
|
|
6126
|
-
|
|
6127
|
-
"text-body-large",
|
|
6039
|
+
// Typography: Label Large per MD3 menu spec
|
|
6040
|
+
"text-label-large",
|
|
6128
6041
|
// Interaction
|
|
6129
6042
|
"cursor-pointer select-none outline-none",
|
|
6130
|
-
//
|
|
6131
|
-
"
|
|
6132
|
-
|
|
6133
|
-
"
|
|
6134
|
-
// Hover state layer
|
|
6135
|
-
"hover:before:opacity-8",
|
|
6136
|
-
// Focus visible state layer
|
|
6137
|
-
"focus-visible:before:opacity-12",
|
|
6138
|
-
// Active pressed state layer
|
|
6139
|
-
"active:before:opacity-12",
|
|
6140
|
-
// Color transition for selection
|
|
6141
|
-
"transition-colors duration-short2 ease-standard"
|
|
6043
|
+
// Color transition (effects — no overshoot)
|
|
6044
|
+
"transition-colors duration-spring-standard-fast-effects ease-spring-standard-fast-effects",
|
|
6045
|
+
// Disabled — self-targeting data-[x]: selectors (RAC emits data-disabled)
|
|
6046
|
+
"data-[disabled]:pointer-events-none data-[disabled]:cursor-not-allowed"
|
|
6142
6047
|
],
|
|
6143
6048
|
{
|
|
6144
6049
|
variants: {
|
|
6145
6050
|
/**
|
|
6146
|
-
*
|
|
6051
|
+
* Color scheme — drives item bg, default text/icon color, and selection colors.
|
|
6052
|
+
*
|
|
6053
|
+
* standard: surface-container-low bg, on-surface text, on-surface-variant icons.
|
|
6054
|
+
* Selected/open: tertiary-container bg highlight, on-tertiary-container content.
|
|
6055
|
+
* vibrant: tertiary-container bg, on-tertiary-container text AND icons.
|
|
6056
|
+
* Selected/open: tertiary bg highlight, on-tertiary content.
|
|
6147
6057
|
*/
|
|
6148
|
-
|
|
6149
|
-
|
|
6150
|
-
|
|
6058
|
+
colorScheme: {
|
|
6059
|
+
standard: ["text-on-surface"],
|
|
6060
|
+
vibrant: ["text-on-tertiary-container"]
|
|
6151
6061
|
},
|
|
6152
6062
|
/**
|
|
6153
|
-
*
|
|
6063
|
+
* Visual style — drives padding, gap, segment surface, and corner rounding.
|
|
6064
|
+
*
|
|
6065
|
+
* baseline: 12dp h-padding, 12dp icon-to-label gap, no item background (container provides it).
|
|
6066
|
+
* vertical: 12dp h-padding, 8dp icon-to-label gap, item owns segment surface, segmented rounding
|
|
6067
|
+
* via first/last + adjacent-sibling gap selectors.
|
|
6154
6068
|
*/
|
|
6155
|
-
|
|
6156
|
-
|
|
6157
|
-
|
|
6069
|
+
menuStyle: {
|
|
6070
|
+
baseline: ["px-3", "gap-3"],
|
|
6071
|
+
vertical: [
|
|
6072
|
+
"px-3",
|
|
6073
|
+
"gap-2",
|
|
6074
|
+
// Default: inner item (4dp all corners)
|
|
6075
|
+
"rounded-md"
|
|
6076
|
+
// Last item in the whole menu → 16dp bottom corners
|
|
6077
|
+
]
|
|
6078
|
+
}
|
|
6079
|
+
},
|
|
6080
|
+
compoundVariants: [
|
|
6081
|
+
// vertical + standard: selected/open text → on-tertiary-container
|
|
6082
|
+
{
|
|
6083
|
+
menuStyle: "vertical",
|
|
6084
|
+
colorScheme: "standard",
|
|
6085
|
+
class: [
|
|
6086
|
+
"data-[selected]:text-on-tertiary-container",
|
|
6087
|
+
"data-[open]:text-on-tertiary-container"
|
|
6088
|
+
]
|
|
6089
|
+
},
|
|
6090
|
+
// vertical + vibrant: selected/open text → on-tertiary
|
|
6091
|
+
{
|
|
6092
|
+
menuStyle: "vertical",
|
|
6093
|
+
colorScheme: "vibrant",
|
|
6094
|
+
class: ["data-[selected]:text-on-tertiary", "data-[open]:text-on-tertiary"]
|
|
6095
|
+
}
|
|
6096
|
+
],
|
|
6097
|
+
defaultVariants: {
|
|
6098
|
+
colorScheme: "standard",
|
|
6099
|
+
menuStyle: "baseline"
|
|
6100
|
+
}
|
|
6101
|
+
}
|
|
6102
|
+
);
|
|
6103
|
+
var menuItemHighlightVariants = classVarianceAuthority.cva(
|
|
6104
|
+
[
|
|
6105
|
+
"absolute inset-0 pointer-events-none",
|
|
6106
|
+
// Inherit the item's own corner radius (inner 4dp or outer 16dp)
|
|
6107
|
+
"rounded-[inherit]",
|
|
6108
|
+
// Effects transition for background-color — no overshoot
|
|
6109
|
+
"transition-colors duration-spring-standard-fast-effects ease-spring-standard-fast-effects",
|
|
6110
|
+
// z-0: below state layer (z-[1]) and content (z-10)
|
|
6111
|
+
"z-0"
|
|
6112
|
+
],
|
|
6113
|
+
{
|
|
6114
|
+
variants: {
|
|
6115
|
+
menuStyle: {
|
|
6116
|
+
baseline: [],
|
|
6117
|
+
vertical: []
|
|
6158
6118
|
},
|
|
6159
|
-
/**
|
|
6160
|
-
* Color scheme: drives default text and state layer colors.
|
|
6161
|
-
* - standard: on-surface text, on-surface state layer
|
|
6162
|
-
* - vibrant (vertical only): on-tertiary-container text + state layer
|
|
6163
|
-
*/
|
|
6164
6119
|
colorScheme: {
|
|
6165
|
-
standard: [
|
|
6166
|
-
|
|
6120
|
+
standard: [
|
|
6121
|
+
// baseline selected bg
|
|
6122
|
+
"group-data-[selected]/menuitem:bg-surface-container-highest"
|
|
6123
|
+
],
|
|
6124
|
+
vibrant: [
|
|
6125
|
+
// baseline + vibrant: use surface-container-highest as fallback
|
|
6126
|
+
"group-data-[selected]/menuitem:bg-surface-container-highest"
|
|
6127
|
+
]
|
|
6128
|
+
}
|
|
6129
|
+
},
|
|
6130
|
+
compoundVariants: [
|
|
6131
|
+
// vertical + standard: selected/open highlight → tertiary-container
|
|
6132
|
+
{
|
|
6133
|
+
menuStyle: "vertical",
|
|
6134
|
+
colorScheme: "standard",
|
|
6135
|
+
class: [
|
|
6136
|
+
"group-data-[selected]/menuitem:bg-tertiary-container",
|
|
6137
|
+
"group-data-[open]/menuitem:bg-tertiary-container"
|
|
6138
|
+
]
|
|
6139
|
+
},
|
|
6140
|
+
// vertical + vibrant: selected/open highlight → tertiary
|
|
6141
|
+
{
|
|
6142
|
+
menuStyle: "vertical",
|
|
6143
|
+
colorScheme: "vibrant",
|
|
6144
|
+
class: [
|
|
6145
|
+
"group-data-[selected]/menuitem:bg-tertiary",
|
|
6146
|
+
"group-data-[open]/menuitem:bg-tertiary"
|
|
6147
|
+
]
|
|
6148
|
+
}
|
|
6149
|
+
],
|
|
6150
|
+
defaultVariants: {
|
|
6151
|
+
menuStyle: "baseline",
|
|
6152
|
+
colorScheme: "standard"
|
|
6153
|
+
}
|
|
6154
|
+
}
|
|
6155
|
+
);
|
|
6156
|
+
var menuItemStateLayerVariants = classVarianceAuthority.cva(
|
|
6157
|
+
[
|
|
6158
|
+
"absolute inset-0 rounded-[inherit] overflow-hidden pointer-events-none opacity-0",
|
|
6159
|
+
// Effects transition — opacity must NOT overshoot
|
|
6160
|
+
"transition-opacity duration-spring-standard-fast-effects ease-spring-standard-fast-effects",
|
|
6161
|
+
// Hover: 8%
|
|
6162
|
+
"group-data-[hovered]/menuitem:opacity-8",
|
|
6163
|
+
// Pressed: 10%, doubled selector wins over hover at same cascade position
|
|
6164
|
+
"group-data-[pressed]/menuitem:group-data-[pressed]/menuitem:opacity-10",
|
|
6165
|
+
// No state layer when disabled
|
|
6166
|
+
"group-data-[disabled]/menuitem:hidden",
|
|
6167
|
+
// z-[1]: above highlight layer (z-0), below content (z-10)
|
|
6168
|
+
"z-[1]"
|
|
6169
|
+
],
|
|
6170
|
+
{
|
|
6171
|
+
variants: {
|
|
6172
|
+
colorScheme: {
|
|
6173
|
+
standard: ["bg-on-surface"],
|
|
6174
|
+
vibrant: ["bg-on-tertiary-container"]
|
|
6167
6175
|
},
|
|
6168
|
-
/**
|
|
6169
|
-
* Visual style: drives corner radius on items (vertical uses rounded-lg
|
|
6170
|
-
* inherited from container, items stay flat inside).
|
|
6171
|
-
*/
|
|
6172
6176
|
menuStyle: {
|
|
6173
6177
|
baseline: [],
|
|
6174
6178
|
vertical: []
|
|
6175
6179
|
}
|
|
6176
6180
|
},
|
|
6177
6181
|
compoundVariants: [
|
|
6178
|
-
//
|
|
6182
|
+
// vertical + standard: selected/open state layer → on-tertiary-container
|
|
6183
|
+
{
|
|
6184
|
+
menuStyle: "vertical",
|
|
6185
|
+
colorScheme: "standard",
|
|
6186
|
+
class: [
|
|
6187
|
+
"group-data-[selected]/menuitem:bg-on-tertiary-container",
|
|
6188
|
+
"group-data-[open]/menuitem:bg-on-tertiary-container"
|
|
6189
|
+
]
|
|
6190
|
+
},
|
|
6191
|
+
// vertical + vibrant: selected/open state layer → on-tertiary
|
|
6179
6192
|
{
|
|
6180
|
-
|
|
6181
|
-
|
|
6193
|
+
menuStyle: "vertical",
|
|
6194
|
+
colorScheme: "vibrant",
|
|
6182
6195
|
class: [
|
|
6183
|
-
"bg-
|
|
6184
|
-
|
|
6196
|
+
"group-data-[selected]/menuitem:bg-on-tertiary",
|
|
6197
|
+
"group-data-[open]/menuitem:bg-on-tertiary"
|
|
6185
6198
|
]
|
|
6199
|
+
}
|
|
6200
|
+
],
|
|
6201
|
+
defaultVariants: {
|
|
6202
|
+
colorScheme: "standard",
|
|
6203
|
+
menuStyle: "baseline"
|
|
6204
|
+
}
|
|
6205
|
+
}
|
|
6206
|
+
);
|
|
6207
|
+
var menuItemFocusRingVariants = classVarianceAuthority.cva([
|
|
6208
|
+
"pointer-events-none absolute inset-0 rounded-[inherit]",
|
|
6209
|
+
"outline outline-2 -outline-offset-2 outline-secondary",
|
|
6210
|
+
// Effects transition — opacity must not overshoot
|
|
6211
|
+
"transition-opacity duration-spring-standard-fast-effects ease-spring-standard-fast-effects",
|
|
6212
|
+
"opacity-0",
|
|
6213
|
+
"group-data-[focus-visible]/menuitem:opacity-100",
|
|
6214
|
+
// z-[2]: above state layer (z-[1]) and highlight (z-0), below content (z-10)
|
|
6215
|
+
"z-[2]"
|
|
6216
|
+
]);
|
|
6217
|
+
var menuItemIconVariants = classVarianceAuthority.cva(
|
|
6218
|
+
[
|
|
6219
|
+
"relative z-10 shrink-0 flex items-center justify-center",
|
|
6220
|
+
"transition-colors duration-spring-standard-fast-effects ease-spring-standard-fast-effects",
|
|
6221
|
+
// Disabled: 38% opacity on icon color
|
|
6222
|
+
"group-data-[disabled]/menuitem:text-on-surface/38"
|
|
6223
|
+
],
|
|
6224
|
+
{
|
|
6225
|
+
variants: {
|
|
6226
|
+
colorScheme: {
|
|
6227
|
+
standard: ["text-on-surface-variant"],
|
|
6228
|
+
vibrant: ["text-on-tertiary-container"]
|
|
6186
6229
|
},
|
|
6187
|
-
|
|
6230
|
+
menuStyle: {
|
|
6231
|
+
baseline: ["h-6 w-6"],
|
|
6232
|
+
vertical: ["h-5 w-5"]
|
|
6233
|
+
}
|
|
6234
|
+
},
|
|
6235
|
+
compoundVariants: [
|
|
6236
|
+
// vertical + standard: selected/open icon → on-tertiary-container
|
|
6188
6237
|
{
|
|
6189
|
-
isSelected: true,
|
|
6190
6238
|
menuStyle: "vertical",
|
|
6191
6239
|
colorScheme: "standard",
|
|
6192
6240
|
class: [
|
|
6193
|
-
"
|
|
6194
|
-
"text-on-tertiary-container"
|
|
6195
|
-
"before:bg-on-tertiary-container"
|
|
6241
|
+
"group-data-[selected]/menuitem:text-on-tertiary-container",
|
|
6242
|
+
"group-data-[open]/menuitem:text-on-tertiary-container"
|
|
6196
6243
|
]
|
|
6197
6244
|
},
|
|
6198
|
-
//
|
|
6245
|
+
// vertical + vibrant: selected/open icon → on-tertiary
|
|
6199
6246
|
{
|
|
6200
|
-
isSelected: true,
|
|
6201
6247
|
menuStyle: "vertical",
|
|
6202
6248
|
colorScheme: "vibrant",
|
|
6203
|
-
class: [
|
|
6249
|
+
class: [
|
|
6250
|
+
"group-data-[selected]/menuitem:text-on-tertiary",
|
|
6251
|
+
"group-data-[open]/menuitem:text-on-tertiary"
|
|
6252
|
+
]
|
|
6204
6253
|
}
|
|
6205
6254
|
],
|
|
6206
6255
|
defaultVariants: {
|
|
6207
|
-
isDisabled: false,
|
|
6208
|
-
isSelected: false,
|
|
6209
6256
|
colorScheme: "standard",
|
|
6210
6257
|
menuStyle: "baseline"
|
|
6211
6258
|
}
|
|
6212
6259
|
}
|
|
6213
6260
|
);
|
|
6214
6261
|
var menuSectionVariants = classVarianceAuthority.cva(["flex flex-col w-full"]);
|
|
6215
|
-
var menuSectionHeaderVariants = classVarianceAuthority.cva(
|
|
6216
|
-
|
|
6217
|
-
|
|
6218
|
-
|
|
6219
|
-
|
|
6220
|
-
|
|
6221
|
-
|
|
6222
|
-
|
|
6223
|
-
|
|
6224
|
-
|
|
6225
|
-
]
|
|
6226
|
-
|
|
6227
|
-
|
|
6228
|
-
|
|
6229
|
-
|
|
6230
|
-
|
|
6231
|
-
|
|
6232
|
-
|
|
6233
|
-
|
|
6234
|
-
|
|
6235
|
-
|
|
6236
|
-
|
|
6237
|
-
|
|
6238
|
-
|
|
6239
|
-
|
|
6240
|
-
|
|
6241
|
-
|
|
6262
|
+
var menuSectionHeaderVariants = classVarianceAuthority.cva(
|
|
6263
|
+
[
|
|
6264
|
+
// 32dp tall region, content vertically centred, 12dp leading padding aligned with items
|
|
6265
|
+
"px-3 h-8 flex items-center",
|
|
6266
|
+
"text-title-small",
|
|
6267
|
+
"select-none"
|
|
6268
|
+
],
|
|
6269
|
+
{
|
|
6270
|
+
variants: {
|
|
6271
|
+
colorScheme: {
|
|
6272
|
+
standard: ["text-on-surface-variant"],
|
|
6273
|
+
vibrant: ["text-on-tertiary-container"]
|
|
6274
|
+
}
|
|
6275
|
+
},
|
|
6276
|
+
defaultVariants: {
|
|
6277
|
+
colorScheme: "standard"
|
|
6278
|
+
}
|
|
6279
|
+
}
|
|
6280
|
+
);
|
|
6281
|
+
var menuDividerVariants = classVarianceAuthority.cva(["border-t border-outline-variant", "my-0.5 mx-3"]);
|
|
6282
|
+
classVarianceAuthority.cva(["h-0.5 w-full"]);
|
|
6283
|
+
var menuItemTrailingTextVariants = classVarianceAuthority.cva(
|
|
6284
|
+
[
|
|
6285
|
+
"ml-auto shrink-0 text-label-large",
|
|
6286
|
+
"select-none",
|
|
6287
|
+
"group-data-[disabled]/menuitem:text-on-surface/38"
|
|
6288
|
+
],
|
|
6289
|
+
{
|
|
6290
|
+
variants: {
|
|
6291
|
+
colorScheme: {
|
|
6292
|
+
standard: ["text-on-surface-variant"],
|
|
6293
|
+
vibrant: ["text-on-tertiary-container"]
|
|
6294
|
+
},
|
|
6295
|
+
menuStyle: {
|
|
6296
|
+
baseline: [],
|
|
6297
|
+
vertical: [
|
|
6298
|
+
"group-data-[selected]/menuitem:text-on-tertiary-container",
|
|
6299
|
+
"group-data-[open]/menuitem:text-on-tertiary-container"
|
|
6300
|
+
]
|
|
6301
|
+
}
|
|
6302
|
+
},
|
|
6303
|
+
compoundVariants: [
|
|
6304
|
+
// vertical + vibrant: selected/open trailing text → on-tertiary
|
|
6305
|
+
{
|
|
6306
|
+
menuStyle: "vertical",
|
|
6307
|
+
colorScheme: "vibrant",
|
|
6308
|
+
class: [
|
|
6309
|
+
"group-data-[selected]/menuitem:text-on-tertiary",
|
|
6310
|
+
"group-data-[open]/menuitem:text-on-tertiary"
|
|
6311
|
+
]
|
|
6312
|
+
}
|
|
6313
|
+
],
|
|
6314
|
+
defaultVariants: {
|
|
6315
|
+
colorScheme: "standard",
|
|
6316
|
+
menuStyle: "baseline"
|
|
6317
|
+
}
|
|
6318
|
+
}
|
|
6319
|
+
);
|
|
6320
|
+
var menuItemDescriptionVariants = classVarianceAuthority.cva(
|
|
6321
|
+
["text-body-medium", "select-none", "group-data-[disabled]/menuitem:text-on-surface/38"],
|
|
6322
|
+
{
|
|
6323
|
+
variants: {
|
|
6324
|
+
colorScheme: {
|
|
6325
|
+
standard: ["text-on-surface-variant"],
|
|
6326
|
+
vibrant: ["text-on-tertiary-container"]
|
|
6327
|
+
},
|
|
6328
|
+
menuStyle: {
|
|
6329
|
+
baseline: [],
|
|
6330
|
+
vertical: [
|
|
6331
|
+
"group-data-[selected]/menuitem:text-on-tertiary-container",
|
|
6332
|
+
"group-data-[open]/menuitem:text-on-tertiary-container"
|
|
6333
|
+
]
|
|
6334
|
+
}
|
|
6335
|
+
},
|
|
6336
|
+
compoundVariants: [
|
|
6337
|
+
// vertical + vibrant: selected/open description → on-tertiary
|
|
6338
|
+
{
|
|
6339
|
+
menuStyle: "vertical",
|
|
6340
|
+
colorScheme: "vibrant",
|
|
6341
|
+
class: [
|
|
6342
|
+
"group-data-[selected]/menuitem:text-on-tertiary",
|
|
6343
|
+
"group-data-[open]/menuitem:text-on-tertiary"
|
|
6344
|
+
]
|
|
6345
|
+
}
|
|
6346
|
+
],
|
|
6347
|
+
defaultVariants: {
|
|
6348
|
+
colorScheme: "standard",
|
|
6349
|
+
menuStyle: "baseline"
|
|
6350
|
+
}
|
|
6351
|
+
}
|
|
6352
|
+
);
|
|
6353
|
+
classVarianceAuthority.cva(
|
|
6354
|
+
[
|
|
6355
|
+
"flex flex-col w-full",
|
|
6356
|
+
"px-1 py-0.5 gap-0.5",
|
|
6357
|
+
"rounded-lg first:rounded-b-sm last:rounded-t-sm",
|
|
6358
|
+
"shadow-elevation-1"
|
|
6359
|
+
],
|
|
6360
|
+
{
|
|
6361
|
+
variants: {
|
|
6362
|
+
menuStyle: {
|
|
6363
|
+
vertical: ["bg-surface-container-low"],
|
|
6364
|
+
baseline: []
|
|
6365
|
+
},
|
|
6366
|
+
colorScheme: {
|
|
6367
|
+
standard: ["bg-surface-container-low"],
|
|
6368
|
+
vibrant: ["bg-tertiary-container"]
|
|
6369
|
+
}
|
|
6370
|
+
},
|
|
6371
|
+
compoundVariants: [
|
|
6372
|
+
// vertical + standard: item background = surface-container-low
|
|
6373
|
+
{
|
|
6374
|
+
menuStyle: "vertical",
|
|
6375
|
+
colorScheme: "standard",
|
|
6376
|
+
class: ["bg-surface-container-low"]
|
|
6377
|
+
},
|
|
6378
|
+
// vertical + vibrant: item background = tertiary-container
|
|
6379
|
+
{
|
|
6380
|
+
menuStyle: "vertical",
|
|
6381
|
+
colorScheme: "vibrant",
|
|
6382
|
+
class: ["bg-tertiary-container"]
|
|
6383
|
+
}
|
|
6384
|
+
],
|
|
6385
|
+
defaultVariants: {
|
|
6386
|
+
menuStyle: "vertical",
|
|
6387
|
+
colorScheme: "standard"
|
|
6388
|
+
}
|
|
6389
|
+
}
|
|
6390
|
+
);
|
|
6391
|
+
var MenuContext = React.createContext(null);
|
|
6392
|
+
function useMenuContext() {
|
|
6393
|
+
return React.useContext(MenuContext);
|
|
6394
|
+
}
|
|
6395
|
+
function TriggerBridge({ children }) {
|
|
6396
|
+
const ctx = reactAriaComponents.useSlottedContext(reactAriaComponents.ButtonContext);
|
|
6397
|
+
const localRef = React.useRef(null);
|
|
6398
|
+
const { ref: contextRef, ...ctxProps } = ctx ?? {};
|
|
6399
|
+
const mergedCallbackRef = React.useCallback(
|
|
6400
|
+
(node) => {
|
|
6401
|
+
localRef.current = node;
|
|
6402
|
+
if (!contextRef) return;
|
|
6403
|
+
if (typeof contextRef === "function") {
|
|
6404
|
+
contextRef(node);
|
|
6405
|
+
} else {
|
|
6406
|
+
contextRef.current = node;
|
|
6407
|
+
}
|
|
6408
|
+
},
|
|
6409
|
+
[contextRef]
|
|
6410
|
+
);
|
|
6411
|
+
const { buttonProps } = reactAria.useButton({ ...ctxProps, elementType: "button" }, localRef);
|
|
6412
|
+
if (!React.isValidElement(children)) return /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children });
|
|
6413
|
+
return React.cloneElement(
|
|
6414
|
+
children,
|
|
6415
|
+
{ ...buttonProps, ref: mergedCallbackRef }
|
|
6416
|
+
);
|
|
6417
|
+
}
|
|
6418
|
+
function HeadlessMenuTrigger({
|
|
6419
|
+
children,
|
|
6420
|
+
placement = "bottom start",
|
|
6421
|
+
shouldFlip = true,
|
|
6422
|
+
...rest
|
|
6423
|
+
}) {
|
|
6424
|
+
const childrenArray = Array.isArray(children) ? children : [children];
|
|
6425
|
+
const [triggerChild, menuChild] = childrenArray;
|
|
6426
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(reactAriaComponents.MenuTrigger, { ...rest, children: [
|
|
6427
|
+
/* @__PURE__ */ jsxRuntime.jsx(TriggerBridge, { children: triggerChild }),
|
|
6428
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
6429
|
+
reactAriaComponents.Popover,
|
|
6430
|
+
{
|
|
6431
|
+
placement,
|
|
6432
|
+
shouldFlip,
|
|
6433
|
+
offset: 4,
|
|
6434
|
+
className: menuPopoverVariants(),
|
|
6435
|
+
children: menuChild
|
|
6436
|
+
}
|
|
6437
|
+
)
|
|
6438
|
+
] });
|
|
6439
|
+
}
|
|
6440
|
+
function HeadlessMenu({
|
|
6441
|
+
className,
|
|
6442
|
+
children,
|
|
6443
|
+
"aria-label": ariaLabel,
|
|
6444
|
+
...props
|
|
6445
|
+
}) {
|
|
6446
|
+
const menuRef = React.useRef(null);
|
|
6447
|
+
React.useLayoutEffect(() => {
|
|
6448
|
+
if (ariaLabel && menuRef.current) {
|
|
6449
|
+
menuRef.current.removeAttribute("aria-labelledby");
|
|
6450
|
+
}
|
|
6451
|
+
});
|
|
6452
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
6453
|
+
reactAriaComponents.Menu,
|
|
6454
|
+
{
|
|
6455
|
+
...props,
|
|
6456
|
+
ref: menuRef,
|
|
6457
|
+
...ariaLabel !== void 0 ? { "aria-label": ariaLabel } : {},
|
|
6458
|
+
className: className ?? "",
|
|
6459
|
+
children
|
|
6460
|
+
}
|
|
6461
|
+
);
|
|
6462
|
+
}
|
|
6463
|
+
HeadlessMenuTrigger.Menu = HeadlessMenu;
|
|
6464
|
+
var HeadlessMenuItem = React.forwardRef(
|
|
6465
|
+
function HeadlessMenuItem2({ children, className, ...props }, ref) {
|
|
6466
|
+
return /* @__PURE__ */ jsxRuntime.jsx(reactAriaComponents.MenuItem, { ...props, ref, className: className ?? "", children });
|
|
6467
|
+
}
|
|
6468
|
+
);
|
|
6469
|
+
function HeadlessMenuSection({
|
|
6470
|
+
children,
|
|
6471
|
+
"aria-label": ariaLabel,
|
|
6472
|
+
className
|
|
6473
|
+
}) {
|
|
6474
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
6475
|
+
reactAriaComponents.MenuSection,
|
|
6476
|
+
{
|
|
6477
|
+
...ariaLabel !== void 0 ? { "aria-label": ariaLabel } : {},
|
|
6478
|
+
className: className ?? "",
|
|
6479
|
+
children
|
|
6480
|
+
}
|
|
6481
|
+
);
|
|
6482
|
+
}
|
|
6483
|
+
function HeadlessMenuDivider({
|
|
6484
|
+
className,
|
|
6485
|
+
...props
|
|
6486
|
+
}) {
|
|
6487
|
+
return /* @__PURE__ */ jsxRuntime.jsx(reactAriaComponents.Separator, { ...props, className: className ?? "" });
|
|
6488
|
+
}
|
|
6489
|
+
var Menu = React.forwardRef(function Menu2({
|
|
6490
|
+
children,
|
|
6491
|
+
className,
|
|
6492
|
+
colorScheme = "standard",
|
|
6493
|
+
menuStyle = "baseline",
|
|
6494
|
+
density = 0,
|
|
6495
|
+
disableRipple = false,
|
|
6496
|
+
selectionMode,
|
|
6497
|
+
selectedKeys,
|
|
6498
|
+
onSelectionChange,
|
|
6499
|
+
...props
|
|
6500
|
+
}, _ref) {
|
|
6242
6501
|
const close = () => {
|
|
6243
6502
|
};
|
|
6244
6503
|
const contextValue = {
|
|
@@ -6286,7 +6545,13 @@ function CheckIcon() {
|
|
|
6286
6545
|
}
|
|
6287
6546
|
);
|
|
6288
6547
|
}
|
|
6289
|
-
var
|
|
6548
|
+
var BASELINE_DENSITY_HEIGHT = {
|
|
6549
|
+
0: "h-12",
|
|
6550
|
+
[-1]: "h-11",
|
|
6551
|
+
[-2]: "h-10",
|
|
6552
|
+
[-3]: "h-9"
|
|
6553
|
+
};
|
|
6554
|
+
var VERTICAL_DENSITY_HEIGHT = {
|
|
6290
6555
|
0: "h-12",
|
|
6291
6556
|
[-1]: "h-11",
|
|
6292
6557
|
[-2]: "h-10",
|
|
@@ -6309,19 +6574,18 @@ var MenuItem = React.forwardRef(function MenuItem2({
|
|
|
6309
6574
|
const menuStyle = ctx?.menuStyle ?? "baseline";
|
|
6310
6575
|
const density = ctx?.density ?? 0;
|
|
6311
6576
|
const selectionMode = ctx?.selectionMode;
|
|
6312
|
-
const heightClass =
|
|
6577
|
+
const heightClass = menuStyle === "vertical" ? VERTICAL_DENSITY_HEIGHT[density] : BASELINE_DENSITY_HEIGHT[density];
|
|
6313
6578
|
const isSelectionMenu = selectionMode != null;
|
|
6314
6579
|
const { ripples, onMouseDown } = useRipple({ disabled: disableRipple });
|
|
6315
|
-
const computeClassName = ({
|
|
6316
|
-
menuItemVariants({
|
|
6317
|
-
|
|
6318
|
-
|
|
6319
|
-
colorScheme,
|
|
6320
|
-
menuStyle
|
|
6321
|
-
}),
|
|
6580
|
+
const computeClassName = ({ isSelected }) => cn(
|
|
6581
|
+
menuItemVariants({ colorScheme, menuStyle }),
|
|
6582
|
+
// group/menuitem scope: all slot children read state via group-data-[x]/menuitem
|
|
6583
|
+
"group/menuitem",
|
|
6322
6584
|
// Height: auto when description is present (multi-line), otherwise density
|
|
6323
6585
|
description ? "min-h-12 py-2 h-auto items-start" : heightClass,
|
|
6324
|
-
className
|
|
6586
|
+
className,
|
|
6587
|
+
// Silence the isSelected lint — value consumed in render-prop below
|
|
6588
|
+
isSelected ? "" : ""
|
|
6325
6589
|
);
|
|
6326
6590
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
6327
6591
|
HeadlessMenuItem,
|
|
@@ -6331,24 +6595,48 @@ var MenuItem = React.forwardRef(function MenuItem2({
|
|
|
6331
6595
|
className: computeClassName,
|
|
6332
6596
|
onMouseDown,
|
|
6333
6597
|
children: ({ isSelected }) => /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
6334
|
-
|
|
6335
|
-
(leadingIcon != null || isSelectionMenu) && /* @__PURE__ */ jsxRuntime.jsx(
|
|
6598
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
6336
6599
|
"span",
|
|
6337
6600
|
{
|
|
6338
|
-
className: "text-on-surface-variant relative z-10 flex h-6 w-6 shrink-0 items-center justify-center",
|
|
6339
6601
|
"aria-hidden": "true",
|
|
6340
|
-
|
|
6602
|
+
"data-testid": "menuitem-highlight",
|
|
6603
|
+
className: menuItemHighlightVariants({ colorScheme, menuStyle })
|
|
6341
6604
|
}
|
|
6342
6605
|
),
|
|
6606
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
6607
|
+
"span",
|
|
6608
|
+
{
|
|
6609
|
+
"aria-hidden": "true",
|
|
6610
|
+
className: menuItemStateLayerVariants({ colorScheme, menuStyle })
|
|
6611
|
+
}
|
|
6612
|
+
),
|
|
6613
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
6614
|
+
"span",
|
|
6615
|
+
{
|
|
6616
|
+
"aria-hidden": "true",
|
|
6617
|
+
"data-testid": "menuitem-focus-ring",
|
|
6618
|
+
className: menuItemFocusRingVariants()
|
|
6619
|
+
}
|
|
6620
|
+
),
|
|
6621
|
+
!disableRipple && /* @__PURE__ */ jsxRuntime.jsx(
|
|
6622
|
+
"span",
|
|
6623
|
+
{
|
|
6624
|
+
className: cn(
|
|
6625
|
+
"pointer-events-none absolute inset-0 z-[3] overflow-hidden rounded-[inherit]"
|
|
6626
|
+
),
|
|
6627
|
+
children: ripples
|
|
6628
|
+
}
|
|
6629
|
+
),
|
|
6630
|
+
(leadingIcon != null || isSelectionMenu) && /* @__PURE__ */ jsxRuntime.jsx("span", { className: menuItemIconVariants({ colorScheme, menuStyle }), "aria-hidden": "true", children: isSelectionMenu && leadingIcon == null ? isSelected ? /* @__PURE__ */ jsxRuntime.jsx(CheckIcon, {}) : null : leadingIcon }),
|
|
6343
6631
|
description != null ? /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "relative z-10 flex min-w-0 flex-1 flex-col", children: [
|
|
6344
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-
|
|
6345
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className: menuItemDescriptionVariants(), children: description })
|
|
6346
|
-
] }) : /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-
|
|
6632
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-label-large group-data-[disabled]/menuitem:text-on-surface/38", children }),
|
|
6633
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: menuItemDescriptionVariants({ colorScheme, menuStyle }), children: description })
|
|
6634
|
+
] }) : /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-label-large group-data-[disabled]/menuitem:text-on-surface/38 relative z-10 min-w-0 flex-1", children }),
|
|
6347
6635
|
badge != null && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "relative z-10 shrink-0", children: badge }),
|
|
6348
6636
|
trailingIcon != null && trailingText == null && /* @__PURE__ */ jsxRuntime.jsx(
|
|
6349
6637
|
"span",
|
|
6350
6638
|
{
|
|
6351
|
-
className:
|
|
6639
|
+
className: cn(menuItemIconVariants({ colorScheme, menuStyle }), "ml-auto"),
|
|
6352
6640
|
"aria-hidden": "true",
|
|
6353
6641
|
children: trailingIcon
|
|
6354
6642
|
}
|
|
@@ -6356,7 +6644,10 @@ var MenuItem = React.forwardRef(function MenuItem2({
|
|
|
6356
6644
|
trailingText != null && trailingIcon == null && /* @__PURE__ */ jsxRuntime.jsx(
|
|
6357
6645
|
"span",
|
|
6358
6646
|
{
|
|
6359
|
-
className: cn(
|
|
6647
|
+
className: cn(
|
|
6648
|
+
menuItemTrailingTextVariants({ colorScheme, menuStyle }),
|
|
6649
|
+
"relative z-10"
|
|
6650
|
+
),
|
|
6360
6651
|
"aria-keyshortcuts": trailingText,
|
|
6361
6652
|
children: trailingText
|
|
6362
6653
|
}
|
|
@@ -6372,6 +6663,8 @@ function MenuSection({
|
|
|
6372
6663
|
className,
|
|
6373
6664
|
"aria-label": ariaLabel
|
|
6374
6665
|
}) {
|
|
6666
|
+
const ctx = useMenuContext();
|
|
6667
|
+
const colorScheme = ctx?.colorScheme ?? "standard";
|
|
6375
6668
|
const sectionAriaLabel = ariaLabel ?? header;
|
|
6376
6669
|
return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
6377
6670
|
showDivider && /* @__PURE__ */ jsxRuntime.jsx(HeadlessMenuDivider, { className: menuDividerVariants() }),
|
|
@@ -6381,7 +6674,7 @@ function MenuSection({
|
|
|
6381
6674
|
"aria-label": sectionAriaLabel,
|
|
6382
6675
|
className: cn(menuSectionVariants(), className),
|
|
6383
6676
|
children: [
|
|
6384
|
-
header && /* @__PURE__ */ jsxRuntime.jsx(reactAriaComponents.Header, { className: menuSectionHeaderVariants(), "aria-hidden": "true", children: header }),
|
|
6677
|
+
header && /* @__PURE__ */ jsxRuntime.jsx(reactAriaComponents.Header, { className: menuSectionHeaderVariants({ colorScheme }), "aria-hidden": "true", children: header }),
|
|
6385
6678
|
children
|
|
6386
6679
|
]
|
|
6387
6680
|
}
|
|
@@ -7721,13 +8014,14 @@ var DialogPanel = ({
|
|
|
7721
8014
|
headlineId,
|
|
7722
8015
|
contentId,
|
|
7723
8016
|
onClose,
|
|
7724
|
-
|
|
8017
|
+
onAnimationEnd,
|
|
7725
8018
|
variant,
|
|
7726
8019
|
isDismissable,
|
|
7727
8020
|
wrapperClassName,
|
|
7728
8021
|
className,
|
|
7729
8022
|
animationState,
|
|
7730
8023
|
getAnimationClassName,
|
|
8024
|
+
icon,
|
|
7731
8025
|
children
|
|
7732
8026
|
}) => {
|
|
7733
8027
|
const panelRef = React.useRef(null);
|
|
@@ -7750,9 +8044,10 @@ var DialogPanel = ({
|
|
|
7750
8044
|
panelRef
|
|
7751
8045
|
);
|
|
7752
8046
|
const panelClassName = cn(className, getAnimationClassName?.(animationState));
|
|
8047
|
+
const hasIcon = icon !== void 0 && icon !== null && variant === "basic";
|
|
7753
8048
|
return (
|
|
7754
8049
|
// Centering/positioning wrapper — structural only, no ARIA role
|
|
7755
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: wrapperClassName, children: /* @__PURE__ */ jsxRuntime.
|
|
8050
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: wrapperClassName, children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
7756
8051
|
"div",
|
|
7757
8052
|
{
|
|
7758
8053
|
...utils.mergeProps(overlayProps, dialogProps),
|
|
@@ -7761,8 +8056,12 @@ var DialogPanel = ({
|
|
|
7761
8056
|
className: panelClassName,
|
|
7762
8057
|
"data-animation-state": animationState,
|
|
7763
8058
|
"data-variant": variant,
|
|
7764
|
-
|
|
7765
|
-
|
|
8059
|
+
"data-with-icon": hasIcon ? "" : void 0,
|
|
8060
|
+
onAnimationEnd,
|
|
8061
|
+
children: [
|
|
8062
|
+
hasIcon && icon,
|
|
8063
|
+
children
|
|
8064
|
+
]
|
|
7766
8065
|
}
|
|
7767
8066
|
) })
|
|
7768
8067
|
);
|
|
@@ -7775,9 +8074,11 @@ var DialogHeadless = React.forwardRef(
|
|
|
7775
8074
|
defaultOpen = false,
|
|
7776
8075
|
onOpenChange,
|
|
7777
8076
|
"aria-label": ariaLabel,
|
|
8077
|
+
icon,
|
|
7778
8078
|
children,
|
|
7779
8079
|
className,
|
|
7780
|
-
|
|
8080
|
+
wrapperClassName,
|
|
8081
|
+
getScrimClassName,
|
|
7781
8082
|
getAnimationClassName
|
|
7782
8083
|
}, _ref) {
|
|
7783
8084
|
const state = reactStately.useOverlayTriggerState({
|
|
@@ -7811,7 +8112,7 @@ var DialogHeadless = React.forwardRef(
|
|
|
7811
8112
|
closedRef.current = true;
|
|
7812
8113
|
setAnimationState("exited");
|
|
7813
8114
|
}
|
|
7814
|
-
},
|
|
8115
|
+
}, 250);
|
|
7815
8116
|
}
|
|
7816
8117
|
}, [isOpen, animationState]);
|
|
7817
8118
|
React.useEffect(
|
|
@@ -7822,16 +8123,20 @@ var DialogHeadless = React.forwardRef(
|
|
|
7822
8123
|
},
|
|
7823
8124
|
[]
|
|
7824
8125
|
);
|
|
7825
|
-
const
|
|
7826
|
-
|
|
7827
|
-
if (
|
|
7828
|
-
|
|
7829
|
-
exitFallbackRef.current
|
|
8126
|
+
const handleAnimationEnd = React.useCallback(
|
|
8127
|
+
(e) => {
|
|
8128
|
+
if (e.target !== e.currentTarget) return;
|
|
8129
|
+
if (animationState === "exiting" && !closedRef.current) {
|
|
8130
|
+
if (exitFallbackRef.current !== null) {
|
|
8131
|
+
clearTimeout(exitFallbackRef.current);
|
|
8132
|
+
exitFallbackRef.current = null;
|
|
8133
|
+
}
|
|
8134
|
+
closedRef.current = true;
|
|
8135
|
+
setAnimationState("exited");
|
|
7830
8136
|
}
|
|
7831
|
-
|
|
7832
|
-
|
|
7833
|
-
|
|
7834
|
-
}, [animationState]);
|
|
8137
|
+
},
|
|
8138
|
+
[animationState]
|
|
8139
|
+
);
|
|
7835
8140
|
const baseId = React.useId();
|
|
7836
8141
|
const headlineId = `${baseId}-dialog-headline`;
|
|
7837
8142
|
const contentId = `${baseId}-dialog-content`;
|
|
@@ -7846,6 +8151,8 @@ var DialogHeadless = React.forwardRef(
|
|
|
7846
8151
|
close();
|
|
7847
8152
|
}
|
|
7848
8153
|
}, [variant, close]);
|
|
8154
|
+
const resolvedWrapperClass = wrapperClassName ?? (variant === "basic" ? "fixed inset-0 z-50 flex items-center justify-center px-4" : "fixed inset-0 z-50");
|
|
8155
|
+
const resolvedScrimClass = getScrimClassName?.(animationState) ?? "fixed inset-0 z-40 bg-scrim/32";
|
|
7849
8156
|
if (!isOpen && animationState === "exited") {
|
|
7850
8157
|
return null;
|
|
7851
8158
|
}
|
|
@@ -7854,7 +8161,7 @@ var DialogHeadless = React.forwardRef(
|
|
|
7854
8161
|
"div",
|
|
7855
8162
|
{
|
|
7856
8163
|
"data-testid": "dialog-scrim",
|
|
7857
|
-
className:
|
|
8164
|
+
className: resolvedScrimClass,
|
|
7858
8165
|
onClick: handleScrimClick,
|
|
7859
8166
|
"aria-hidden": "true"
|
|
7860
8167
|
}
|
|
@@ -7866,13 +8173,14 @@ var DialogHeadless = React.forwardRef(
|
|
|
7866
8173
|
headlineId,
|
|
7867
8174
|
contentId,
|
|
7868
8175
|
onClose: close,
|
|
7869
|
-
|
|
8176
|
+
onAnimationEnd: handleAnimationEnd,
|
|
7870
8177
|
variant,
|
|
7871
8178
|
isDismissable: variant === "basic",
|
|
7872
|
-
wrapperClassName:
|
|
8179
|
+
wrapperClassName: resolvedWrapperClass,
|
|
7873
8180
|
className,
|
|
7874
8181
|
animationState,
|
|
7875
8182
|
getAnimationClassName,
|
|
8183
|
+
icon,
|
|
7876
8184
|
children
|
|
7877
8185
|
}
|
|
7878
8186
|
) })
|
|
@@ -7882,16 +8190,28 @@ var DialogHeadless = React.forwardRef(
|
|
|
7882
8190
|
}
|
|
7883
8191
|
);
|
|
7884
8192
|
DialogHeadless.displayName = "DialogHeadless";
|
|
7885
|
-
var dialogScrimVariants = classVarianceAuthority.cva(
|
|
7886
|
-
|
|
7887
|
-
|
|
7888
|
-
|
|
7889
|
-
|
|
7890
|
-
|
|
7891
|
-
|
|
7892
|
-
|
|
7893
|
-
|
|
7894
|
-
|
|
8193
|
+
var dialogScrimVariants = classVarianceAuthority.cva(
|
|
8194
|
+
[
|
|
8195
|
+
"fixed",
|
|
8196
|
+
"inset-0",
|
|
8197
|
+
"z-40",
|
|
8198
|
+
// MD3 scrim: bg-scrim at 32% opacity — always set so instant-show works in reduced-motion
|
|
8199
|
+
"bg-scrim/32"
|
|
8200
|
+
],
|
|
8201
|
+
{
|
|
8202
|
+
variants: {
|
|
8203
|
+
animationState: {
|
|
8204
|
+
entering: ["opacity-0"],
|
|
8205
|
+
visible: ["animate-md-fade-in"],
|
|
8206
|
+
exiting: ["animate-md-fade-out"],
|
|
8207
|
+
exited: ["opacity-0", "pointer-events-none"]
|
|
8208
|
+
}
|
|
8209
|
+
},
|
|
8210
|
+
defaultVariants: {
|
|
8211
|
+
animationState: "entering"
|
|
8212
|
+
}
|
|
8213
|
+
}
|
|
8214
|
+
);
|
|
7895
8215
|
var dialogPanelVariants = classVarianceAuthority.cva(
|
|
7896
8216
|
[
|
|
7897
8217
|
// Stacking above scrim
|
|
@@ -7901,9 +8221,10 @@ var dialogPanelVariants = classVarianceAuthority.cva(
|
|
|
7901
8221
|
// Flex column layout for slots
|
|
7902
8222
|
"flex",
|
|
7903
8223
|
"flex-col",
|
|
7904
|
-
//
|
|
7905
|
-
"
|
|
7906
|
-
|
|
8224
|
+
// Compositor hint for keyframe animation
|
|
8225
|
+
"will-change-[opacity,transform]",
|
|
8226
|
+
// group scope — lets child slots consume data-with-icon via group-data-[with-icon]/dialog:
|
|
8227
|
+
"group/dialog"
|
|
7907
8228
|
],
|
|
7908
8229
|
{
|
|
7909
8230
|
variants: {
|
|
@@ -7917,11 +8238,11 @@ var dialogPanelVariants = classVarianceAuthority.cva(
|
|
|
7917
8238
|
"min-w-70",
|
|
7918
8239
|
"max-w-dialog-max",
|
|
7919
8240
|
"w-full",
|
|
7920
|
-
// Internal spacing
|
|
8241
|
+
// Internal spacing: 24dp padding, headline mb-4, content mb-6, actions pt-3
|
|
7921
8242
|
"pt-6",
|
|
7922
8243
|
"pb-3",
|
|
7923
8244
|
"px-6",
|
|
7924
|
-
//
|
|
8245
|
+
// Positioning (centering wrapper handles the viewport centering)
|
|
7925
8246
|
"relative"
|
|
7926
8247
|
],
|
|
7927
8248
|
fullscreen: [
|
|
@@ -7932,7 +8253,6 @@ var dialogPanelVariants = classVarianceAuthority.cva(
|
|
|
7932
8253
|
"rounded-none",
|
|
7933
8254
|
// No elevation shadow on fullscreen
|
|
7934
8255
|
"shadow-none",
|
|
7935
|
-
// Positioned to fill portal
|
|
7936
8256
|
"relative"
|
|
7937
8257
|
]
|
|
7938
8258
|
}
|
|
@@ -7942,7 +8262,7 @@ var dialogPanelVariants = classVarianceAuthority.cva(
|
|
|
7942
8262
|
}
|
|
7943
8263
|
}
|
|
7944
8264
|
);
|
|
7945
|
-
classVarianceAuthority.cva([], {
|
|
8265
|
+
var dialogWrapperVariants = classVarianceAuthority.cva([], {
|
|
7946
8266
|
variants: {
|
|
7947
8267
|
variant: {
|
|
7948
8268
|
basic: ["fixed", "inset-0", "z-50", "flex", "items-center", "justify-center", "px-4"],
|
|
@@ -7956,9 +8276,13 @@ classVarianceAuthority.cva([], {
|
|
|
7956
8276
|
var dialogAnimationVariants = classVarianceAuthority.cva("", {
|
|
7957
8277
|
variants: {
|
|
7958
8278
|
animationState: {
|
|
8279
|
+
// initial mount frame before the animation starts — rendered invisible
|
|
7959
8280
|
entering: [],
|
|
8281
|
+
// entry animation active
|
|
7960
8282
|
visible: [],
|
|
8283
|
+
// exit animation active
|
|
7961
8284
|
exiting: [],
|
|
8285
|
+
// fully dismissed; portal gate will remove the element
|
|
7962
8286
|
exited: []
|
|
7963
8287
|
},
|
|
7964
8288
|
variant: {
|
|
@@ -7967,53 +8291,55 @@ var dialogAnimationVariants = classVarianceAuthority.cva("", {
|
|
|
7967
8291
|
}
|
|
7968
8292
|
},
|
|
7969
8293
|
compoundVariants: [
|
|
7970
|
-
// Basic
|
|
8294
|
+
// ── Basic ────────────────────────────────────────────────────────────────
|
|
8295
|
+
// entering: start invisible (animate-md-scale-in keyframe starts from scale(0.85)/opacity:0)
|
|
7971
8296
|
{
|
|
7972
8297
|
animationState: "entering",
|
|
7973
8298
|
variant: "basic",
|
|
7974
|
-
className: ["
|
|
8299
|
+
className: ["opacity-0"]
|
|
7975
8300
|
},
|
|
7976
|
-
//
|
|
8301
|
+
// visible: composite scale-in keyframe (expressive-fast-spatial 350ms)
|
|
7977
8302
|
{
|
|
7978
8303
|
animationState: "visible",
|
|
7979
8304
|
variant: "basic",
|
|
7980
|
-
className: ["
|
|
8305
|
+
className: ["animate-md-scale-in"]
|
|
7981
8306
|
},
|
|
7982
|
-
//
|
|
8307
|
+
// exiting: composite scale-out keyframe (emphasized-accelerate 200ms)
|
|
7983
8308
|
{
|
|
7984
8309
|
animationState: "exiting",
|
|
7985
8310
|
variant: "basic",
|
|
7986
|
-
className: ["
|
|
8311
|
+
className: ["animate-md-scale-out"]
|
|
7987
8312
|
},
|
|
7988
|
-
//
|
|
8313
|
+
// exited: keep hidden until portal gate removes it
|
|
7989
8314
|
{
|
|
7990
8315
|
animationState: "exited",
|
|
7991
8316
|
variant: "basic",
|
|
7992
|
-
className: ["
|
|
8317
|
+
className: ["opacity-0", "pointer-events-none"]
|
|
7993
8318
|
},
|
|
7994
|
-
// Fullscreen
|
|
8319
|
+
// ── Fullscreen ───────────────────────────────────────────────────────────
|
|
8320
|
+
// entering: start off-screen below (slide-in-bottom starts from translateY(100%)/opacity:0)
|
|
7995
8321
|
{
|
|
7996
8322
|
animationState: "entering",
|
|
7997
8323
|
variant: "fullscreen",
|
|
7998
|
-
className: ["
|
|
8324
|
+
className: ["opacity-0"]
|
|
7999
8325
|
},
|
|
8000
|
-
//
|
|
8326
|
+
// visible: composite slide-in-bottom keyframe (standard-default-spatial 500ms)
|
|
8001
8327
|
{
|
|
8002
8328
|
animationState: "visible",
|
|
8003
8329
|
variant: "fullscreen",
|
|
8004
|
-
className: ["
|
|
8330
|
+
className: ["animate-md-slide-in-bottom"]
|
|
8005
8331
|
},
|
|
8006
|
-
//
|
|
8332
|
+
// exiting: composite slide-out-bottom keyframe (emphasized-accelerate 200ms)
|
|
8007
8333
|
{
|
|
8008
8334
|
animationState: "exiting",
|
|
8009
8335
|
variant: "fullscreen",
|
|
8010
|
-
className: ["
|
|
8336
|
+
className: ["animate-md-slide-out-bottom"]
|
|
8011
8337
|
},
|
|
8012
|
-
//
|
|
8338
|
+
// exited: keep hidden until portal gate removes it
|
|
8013
8339
|
{
|
|
8014
8340
|
animationState: "exited",
|
|
8015
8341
|
variant: "fullscreen",
|
|
8016
|
-
className: ["
|
|
8342
|
+
className: ["opacity-0", "pointer-events-none"]
|
|
8017
8343
|
}
|
|
8018
8344
|
],
|
|
8019
8345
|
defaultVariants: {
|
|
@@ -8021,10 +8347,26 @@ var dialogAnimationVariants = classVarianceAuthority.cva("", {
|
|
|
8021
8347
|
variant: "basic"
|
|
8022
8348
|
}
|
|
8023
8349
|
});
|
|
8350
|
+
classVarianceAuthority.cva([
|
|
8351
|
+
// Center the icon in the panel
|
|
8352
|
+
"flex",
|
|
8353
|
+
"items-center",
|
|
8354
|
+
"justify-center",
|
|
8355
|
+
// Bottom margin separating icon from headline
|
|
8356
|
+
"mb-4",
|
|
8357
|
+
// MD3 spec: icon color = secondary
|
|
8358
|
+
"text-secondary",
|
|
8359
|
+
// 24dp icon size (children — typically an SVG — should be 24×24)
|
|
8360
|
+
"size-6"
|
|
8361
|
+
]);
|
|
8024
8362
|
var dialogHeadlineVariants = classVarianceAuthority.cva(["text-headline-small", "text-on-surface"], {
|
|
8025
8363
|
variants: {
|
|
8026
8364
|
variant: {
|
|
8027
|
-
basic: [
|
|
8365
|
+
basic: [
|
|
8366
|
+
"mb-4",
|
|
8367
|
+
// Center headline text when hero icon is present
|
|
8368
|
+
"group-data-[with-icon]/dialog:text-center"
|
|
8369
|
+
],
|
|
8028
8370
|
fullscreen: [
|
|
8029
8371
|
// Top app bar row in fullscreen: flex, items-center, gap
|
|
8030
8372
|
"flex",
|
|
@@ -8049,7 +8391,19 @@ var dialogHeadlineTitleVariants = classVarianceAuthority.cva([
|
|
|
8049
8391
|
"truncate"
|
|
8050
8392
|
]);
|
|
8051
8393
|
var dialogContentVariants = classVarianceAuthority.cva(
|
|
8052
|
-
[
|
|
8394
|
+
[
|
|
8395
|
+
"text-body-medium",
|
|
8396
|
+
"text-on-surface-variant",
|
|
8397
|
+
"overflow-y-auto",
|
|
8398
|
+
"flex-1",
|
|
8399
|
+
// Center supporting text when hero icon is present
|
|
8400
|
+
"group-data-[with-icon]/dialog:text-center",
|
|
8401
|
+
// Scroll dividers — activated by DialogContent's scroll handler
|
|
8402
|
+
"data-[scroll-divider-top]:border-t",
|
|
8403
|
+
"data-[scroll-divider-top]:border-outline-variant",
|
|
8404
|
+
"data-[scroll-divider-bottom]:border-b",
|
|
8405
|
+
"data-[scroll-divider-bottom]:border-outline-variant"
|
|
8406
|
+
],
|
|
8053
8407
|
{
|
|
8054
8408
|
variants: {
|
|
8055
8409
|
variant: {
|
|
@@ -8076,11 +8430,31 @@ var Dialog = React.forwardRef(function Dialog2({
|
|
|
8076
8430
|
defaultOpen = false,
|
|
8077
8431
|
onOpenChange,
|
|
8078
8432
|
"aria-label": ariaLabel,
|
|
8433
|
+
icon,
|
|
8079
8434
|
children,
|
|
8080
8435
|
className
|
|
8081
8436
|
}, _ref) {
|
|
8082
|
-
const
|
|
8083
|
-
const
|
|
8437
|
+
const reducedMotion = useReducedMotion();
|
|
8438
|
+
const panelClassName = cn(
|
|
8439
|
+
dialogPanelVariants({ variant }),
|
|
8440
|
+
reducedMotion && "transition-none",
|
|
8441
|
+
className
|
|
8442
|
+
);
|
|
8443
|
+
const wrapperClassName = dialogWrapperVariants({ variant });
|
|
8444
|
+
const getScrimClassName = React.useCallback(
|
|
8445
|
+
(state) => {
|
|
8446
|
+
if (reducedMotion) return "fixed inset-0 z-40 bg-scrim/32";
|
|
8447
|
+
return dialogScrimVariants({ animationState: state });
|
|
8448
|
+
},
|
|
8449
|
+
[reducedMotion]
|
|
8450
|
+
);
|
|
8451
|
+
const getAnimationClassName = React.useCallback(
|
|
8452
|
+
(state) => {
|
|
8453
|
+
if (reducedMotion) return "";
|
|
8454
|
+
return dialogAnimationVariants({ animationState: state, variant });
|
|
8455
|
+
},
|
|
8456
|
+
[reducedMotion, variant]
|
|
8457
|
+
);
|
|
8084
8458
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
8085
8459
|
DialogHeadless,
|
|
8086
8460
|
{
|
|
@@ -8089,9 +8463,11 @@ var Dialog = React.forwardRef(function Dialog2({
|
|
|
8089
8463
|
...defaultOpen !== void 0 ? { defaultOpen } : {},
|
|
8090
8464
|
...onOpenChange !== void 0 ? { onOpenChange } : {},
|
|
8091
8465
|
...ariaLabel ? { "aria-label": ariaLabel } : {},
|
|
8466
|
+
...icon !== void 0 ? { icon } : {},
|
|
8092
8467
|
className: panelClassName,
|
|
8093
|
-
|
|
8094
|
-
|
|
8468
|
+
wrapperClassName,
|
|
8469
|
+
getScrimClassName,
|
|
8470
|
+
getAnimationClassName,
|
|
8095
8471
|
children
|
|
8096
8472
|
}
|
|
8097
8473
|
);
|
|
@@ -8102,7 +8478,7 @@ var DialogHeadline = React.forwardRef(
|
|
|
8102
8478
|
const { headlineId, variant } = useDialogContext();
|
|
8103
8479
|
if (variant === "fullscreen") {
|
|
8104
8480
|
return (
|
|
8105
|
-
// Top app bar row for fullscreen variant
|
|
8481
|
+
// Top app bar row for fullscreen variant — always has border-b border-outline-variant
|
|
8106
8482
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn(dialogHeadlineVariants({ variant: "fullscreen" }), className), children: [
|
|
8107
8483
|
closeButton,
|
|
8108
8484
|
/* @__PURE__ */ jsxRuntime.jsx("h2", { id: headlineId, className: dialogHeadlineTitleVariants(), children }),
|
|
@@ -8110,21 +8486,72 @@ var DialogHeadline = React.forwardRef(
|
|
|
8110
8486
|
] })
|
|
8111
8487
|
);
|
|
8112
8488
|
}
|
|
8113
|
-
return
|
|
8114
|
-
|
|
8115
|
-
|
|
8116
|
-
|
|
8117
|
-
|
|
8118
|
-
|
|
8119
|
-
|
|
8120
|
-
|
|
8489
|
+
return (
|
|
8490
|
+
// Basic variant: text-headline-small, text-on-surface, mb-4
|
|
8491
|
+
// group-data-[with-icon]/dialog:text-center is applied via the CVA base classes
|
|
8492
|
+
// when the parent panel root has data-with-icon set by DialogHeadless.
|
|
8493
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
8494
|
+
"h2",
|
|
8495
|
+
{
|
|
8496
|
+
ref,
|
|
8497
|
+
id: headlineId,
|
|
8498
|
+
className: cn(dialogHeadlineVariants({ variant: "basic" }), className),
|
|
8499
|
+
children
|
|
8500
|
+
}
|
|
8501
|
+
)
|
|
8121
8502
|
);
|
|
8122
8503
|
}
|
|
8123
8504
|
);
|
|
8124
8505
|
DialogHeadline.displayName = "DialogHeadline";
|
|
8125
|
-
var DialogContent = React.forwardRef(function DialogContent2({ children, className },
|
|
8506
|
+
var DialogContent = React.forwardRef(function DialogContent2({ children, className }, forwardedRef) {
|
|
8126
8507
|
const { contentId, variant } = useDialogContext();
|
|
8127
|
-
|
|
8508
|
+
const internalRef = React.useRef(null);
|
|
8509
|
+
const setRef = React.useCallback(
|
|
8510
|
+
(node) => {
|
|
8511
|
+
internalRef.current = node;
|
|
8512
|
+
if (typeof forwardedRef === "function") {
|
|
8513
|
+
forwardedRef(node);
|
|
8514
|
+
} else if (forwardedRef !== null && forwardedRef !== void 0) {
|
|
8515
|
+
forwardedRef.current = node;
|
|
8516
|
+
}
|
|
8517
|
+
},
|
|
8518
|
+
[forwardedRef]
|
|
8519
|
+
);
|
|
8520
|
+
const updateDividers = React.useCallback(() => {
|
|
8521
|
+
const el = internalRef.current;
|
|
8522
|
+
if (!el) return;
|
|
8523
|
+
const isScrollable = el.scrollHeight > el.clientHeight;
|
|
8524
|
+
if (!isScrollable) {
|
|
8525
|
+
el.removeAttribute("data-scroll-divider-top");
|
|
8526
|
+
el.removeAttribute("data-scroll-divider-bottom");
|
|
8527
|
+
return;
|
|
8528
|
+
}
|
|
8529
|
+
const scrolledFromTop = el.scrollTop > 1;
|
|
8530
|
+
const scrolledToBottom = el.scrollTop + el.clientHeight >= el.scrollHeight - 1;
|
|
8531
|
+
if (scrolledFromTop) {
|
|
8532
|
+
el.setAttribute("data-scroll-divider-top", "");
|
|
8533
|
+
} else {
|
|
8534
|
+
el.removeAttribute("data-scroll-divider-top");
|
|
8535
|
+
}
|
|
8536
|
+
if (!scrolledToBottom) {
|
|
8537
|
+
el.setAttribute("data-scroll-divider-bottom", "");
|
|
8538
|
+
} else {
|
|
8539
|
+
el.removeAttribute("data-scroll-divider-bottom");
|
|
8540
|
+
}
|
|
8541
|
+
}, []);
|
|
8542
|
+
React.useEffect(() => {
|
|
8543
|
+
const el = internalRef.current;
|
|
8544
|
+
if (!el) return;
|
|
8545
|
+
updateDividers();
|
|
8546
|
+
el.addEventListener("scroll", updateDividers, { passive: true });
|
|
8547
|
+
const observer = new ResizeObserver(updateDividers);
|
|
8548
|
+
observer.observe(el);
|
|
8549
|
+
return () => {
|
|
8550
|
+
el.removeEventListener("scroll", updateDividers);
|
|
8551
|
+
observer.disconnect();
|
|
8552
|
+
};
|
|
8553
|
+
}, [updateDividers]);
|
|
8554
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { ref: setRef, id: contentId, className: cn(dialogContentVariants({ variant }), className), children });
|
|
8128
8555
|
});
|
|
8129
8556
|
DialogContent.displayName = "DialogContent";
|
|
8130
8557
|
var DialogActions = React.forwardRef(function DialogActions2({ children, className }, ref) {
|