react-material-expressive 1.0.0 → 1.1.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/CHANGELOG.md +54 -1
- package/README.md +28 -23
- package/dist/index.cjs +1241 -491
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +110 -9
- package/dist/index.d.ts +110 -9
- package/dist/index.js +1240 -492
- package/dist/index.js.map +1 -1
- package/dist/styles.css +1 -1
- package/dist/theme.css +5 -0
- package/docs/components/Combobox.md +119 -0
- package/docs/components/DatePicker.md +14 -2
- package/docs/components/Dropdown.md +4 -0
- package/docs/components/Layers.md +3 -0
- package/docs/components/Menu.md +4 -0
- package/docs/components/NavigationRail.md +3 -0
- package/docs/components/OverflowMenu.md +5 -1
- package/docs/components/Search.md +9 -1
- package/docs/components/SplitButton.md +3 -1
- package/docs/components/TextElement.md +15 -0
- package/llms.txt +64 -59
- package/package.json +5 -2
package/dist/index.js
CHANGED
|
@@ -561,7 +561,8 @@ function useOutsideClose(ref, onClose, enabled = true) {
|
|
|
561
561
|
const target = event.target;
|
|
562
562
|
if (!element || !(target instanceof Node)) return;
|
|
563
563
|
if (element.contains(target)) return;
|
|
564
|
-
if (target instanceof Element && target.closest('[role="menu"]'))
|
|
564
|
+
if (target instanceof Element && target.closest('[role="menu"],[role="listbox"]'))
|
|
565
|
+
return;
|
|
565
566
|
onClose();
|
|
566
567
|
};
|
|
567
568
|
document.addEventListener("pointerdown", handler);
|
|
@@ -796,6 +797,83 @@ function IconButton({
|
|
|
796
797
|
}
|
|
797
798
|
);
|
|
798
799
|
}
|
|
800
|
+
var useIsomorphicLayoutEffect = typeof window === "undefined" ? useEffect : useLayoutEffect;
|
|
801
|
+
|
|
802
|
+
// src/components/_usePopoverPosition.ts
|
|
803
|
+
var MARGIN = 8;
|
|
804
|
+
var FALLBACK_WIDTH = 224;
|
|
805
|
+
function usePopoverPosition(anchor, floating, open, options = {}) {
|
|
806
|
+
const { gap = 0, matchWidth = false, placement = "bottom-start" } = options;
|
|
807
|
+
const [pos, setPos] = useState({
|
|
808
|
+
flippedVertically: false,
|
|
809
|
+
left: 0,
|
|
810
|
+
top: 0
|
|
811
|
+
});
|
|
812
|
+
useIsomorphicLayoutEffect(() => {
|
|
813
|
+
if (!open) return;
|
|
814
|
+
const compute = () => {
|
|
815
|
+
const a = anchor.current?.getBoundingClientRect();
|
|
816
|
+
if (!a) return;
|
|
817
|
+
const f = floating.current?.getBoundingClientRect();
|
|
818
|
+
const width = matchWidth ? a.width : f?.width || FALLBACK_WIDTH;
|
|
819
|
+
const height = f?.height || 0;
|
|
820
|
+
const vw = window.innerWidth;
|
|
821
|
+
const vh = window.innerHeight;
|
|
822
|
+
const dash = placement.indexOf("-");
|
|
823
|
+
const side = placement.slice(0, dash);
|
|
824
|
+
const align = placement.slice(dash + 1);
|
|
825
|
+
let left;
|
|
826
|
+
let top;
|
|
827
|
+
let flippedVertically = false;
|
|
828
|
+
if (side === "right") {
|
|
829
|
+
left = a.right + gap;
|
|
830
|
+
if (left + width > vw - MARGIN) {
|
|
831
|
+
const flipped = a.left - width - gap;
|
|
832
|
+
left = flipped >= MARGIN ? flipped : Math.max(MARGIN, vw - MARGIN - width);
|
|
833
|
+
}
|
|
834
|
+
top = a.top;
|
|
835
|
+
if (top + height > vh - MARGIN) {
|
|
836
|
+
top = Math.max(MARGIN, vh - MARGIN - height);
|
|
837
|
+
}
|
|
838
|
+
} else {
|
|
839
|
+
left = align === "end" ? a.right - width : a.left;
|
|
840
|
+
if (left + width > vw - MARGIN) left = vw - MARGIN - width;
|
|
841
|
+
if (left < MARGIN) left = MARGIN;
|
|
842
|
+
const below = a.bottom + gap;
|
|
843
|
+
const above = a.top - height - gap;
|
|
844
|
+
const roomBelow = vh - MARGIN - a.bottom;
|
|
845
|
+
const roomAbove = a.top - MARGIN;
|
|
846
|
+
if (side === "bottom") {
|
|
847
|
+
if (height > roomBelow && roomAbove > roomBelow) {
|
|
848
|
+
top = Math.max(MARGIN, above);
|
|
849
|
+
flippedVertically = true;
|
|
850
|
+
} else {
|
|
851
|
+
top = below;
|
|
852
|
+
}
|
|
853
|
+
} else if (height > roomAbove && roomBelow > roomAbove) {
|
|
854
|
+
top = below;
|
|
855
|
+
flippedVertically = true;
|
|
856
|
+
} else {
|
|
857
|
+
top = Math.max(MARGIN, above);
|
|
858
|
+
}
|
|
859
|
+
}
|
|
860
|
+
setPos({
|
|
861
|
+
flippedVertically,
|
|
862
|
+
left,
|
|
863
|
+
top,
|
|
864
|
+
width: matchWidth ? a.width : void 0
|
|
865
|
+
});
|
|
866
|
+
};
|
|
867
|
+
compute();
|
|
868
|
+
window.addEventListener("scroll", compute, true);
|
|
869
|
+
window.addEventListener("resize", compute);
|
|
870
|
+
return () => {
|
|
871
|
+
window.removeEventListener("scroll", compute, true);
|
|
872
|
+
window.removeEventListener("resize", compute);
|
|
873
|
+
};
|
|
874
|
+
}, [anchor, floating, open, gap, matchWidth, placement]);
|
|
875
|
+
return pos;
|
|
876
|
+
}
|
|
799
877
|
var MENU_NOOP = () => {
|
|
800
878
|
};
|
|
801
879
|
var MenuContext = createContext({
|
|
@@ -918,41 +996,6 @@ function MenuLabel({ children, className, leftElement }) {
|
|
|
918
996
|
}
|
|
919
997
|
);
|
|
920
998
|
}
|
|
921
|
-
var useIsomorphicLayoutEffect = typeof window === "undefined" ? useEffect : useLayoutEffect;
|
|
922
|
-
|
|
923
|
-
// src/components/menu/_useSubmenu.ts
|
|
924
|
-
var MARGIN = 8;
|
|
925
|
-
function useSubmenuPosition(anchor, floating, open) {
|
|
926
|
-
const [pos, setPos] = useState({ left: 0, top: 0 });
|
|
927
|
-
useIsomorphicLayoutEffect(() => {
|
|
928
|
-
if (!open) return;
|
|
929
|
-
const compute = () => {
|
|
930
|
-
const a = anchor.current?.getBoundingClientRect();
|
|
931
|
-
if (!a) return;
|
|
932
|
-
const f = floating.current?.getBoundingClientRect();
|
|
933
|
-
const width = f?.width || 224;
|
|
934
|
-
const height = f?.height || 0;
|
|
935
|
-
let left = a.right;
|
|
936
|
-
if (left + width > window.innerWidth - MARGIN) {
|
|
937
|
-
const flipped = a.left - width;
|
|
938
|
-
left = flipped >= MARGIN ? flipped : Math.max(MARGIN, window.innerWidth - MARGIN - width);
|
|
939
|
-
}
|
|
940
|
-
let top = a.top;
|
|
941
|
-
if (top + height > window.innerHeight - MARGIN) {
|
|
942
|
-
top = Math.max(MARGIN, window.innerHeight - MARGIN - height);
|
|
943
|
-
}
|
|
944
|
-
setPos({ left, top });
|
|
945
|
-
};
|
|
946
|
-
compute();
|
|
947
|
-
window.addEventListener("scroll", compute, true);
|
|
948
|
-
window.addEventListener("resize", compute);
|
|
949
|
-
return () => {
|
|
950
|
-
window.removeEventListener("scroll", compute, true);
|
|
951
|
-
window.removeEventListener("resize", compute);
|
|
952
|
-
};
|
|
953
|
-
}, [anchor, floating, open]);
|
|
954
|
-
return pos;
|
|
955
|
-
}
|
|
956
999
|
var HOVER_OPEN_MS = 120;
|
|
957
1000
|
var HOVER_CLOSE_MS = 220;
|
|
958
1001
|
function ChevronRight() {
|
|
@@ -982,7 +1025,9 @@ function MenuSub({
|
|
|
982
1025
|
const trigger = useRef(null);
|
|
983
1026
|
const floating = useRef(null);
|
|
984
1027
|
const timer = useRef(void 0);
|
|
985
|
-
const pos =
|
|
1028
|
+
const pos = usePopoverPosition(trigger, floating, open, {
|
|
1029
|
+
placement: "right-start"
|
|
1030
|
+
});
|
|
986
1031
|
const clear = () => timer.current && clearTimeout(timer.current);
|
|
987
1032
|
const hoverOpen = () => {
|
|
988
1033
|
clear();
|
|
@@ -1063,7 +1108,7 @@ function MenuSub({
|
|
|
1063
1108
|
/* @__PURE__ */ jsx(
|
|
1064
1109
|
"div",
|
|
1065
1110
|
{
|
|
1066
|
-
className: "fixed z-
|
|
1111
|
+
className: "fixed z-[var(--md-sys-z-menu)]",
|
|
1067
1112
|
onMouseEnter: clear,
|
|
1068
1113
|
onMouseLeave: hoverClose,
|
|
1069
1114
|
ref: floating,
|
|
@@ -1178,7 +1223,7 @@ function Menu({
|
|
|
1178
1223
|
// outline-none: the surface is focusable (tabIndex -1) so a
|
|
1179
1224
|
// root menu can focus it on open without highlighting any
|
|
1180
1225
|
// item — it must never show a focus ring of its own.
|
|
1181
|
-
"z-
|
|
1226
|
+
"z-[var(--md-sys-z-menu)] flex w-max min-w-[112px] max-w-[280px] flex-col outline-none [--menu-clip-bleed:-24px]",
|
|
1182
1227
|
grouped ? (
|
|
1183
1228
|
// Transparent stack: each Menu.Group is its own
|
|
1184
1229
|
// surface, separated by a 2dp gap. overflow-visible
|
|
@@ -1286,8 +1331,13 @@ function SplitButton({
|
|
|
1286
1331
|
const [isOpen, setIsOpen] = useState(false);
|
|
1287
1332
|
const wrapper = useRef(null);
|
|
1288
1333
|
const trailing = useRef(null);
|
|
1334
|
+
const floating = useRef(null);
|
|
1289
1335
|
const wasOpen = useRef(false);
|
|
1290
1336
|
const { exiting, mounted } = useDismissable(isOpen, 150);
|
|
1337
|
+
const pos = usePopoverPosition(wrapper, floating, mounted, {
|
|
1338
|
+
gap: 8,
|
|
1339
|
+
placement: "bottom-end"
|
|
1340
|
+
});
|
|
1291
1341
|
const config = SIZES4[size];
|
|
1292
1342
|
const corners = (classes) => disabled ? classes.replace(/ (?:hover|focus-visible|active):\S+/g, "") : classes;
|
|
1293
1343
|
useOutsideClose(wrapper, () => setIsOpen(false), isOpen);
|
|
@@ -1361,15 +1411,27 @@ function SplitButton({
|
|
|
1361
1411
|
)
|
|
1362
1412
|
}
|
|
1363
1413
|
),
|
|
1364
|
-
mounted
|
|
1365
|
-
|
|
1366
|
-
|
|
1367
|
-
|
|
1368
|
-
|
|
1369
|
-
|
|
1370
|
-
|
|
1371
|
-
|
|
1372
|
-
|
|
1414
|
+
mounted && typeof document !== "undefined" ? createPortal(
|
|
1415
|
+
/* @__PURE__ */ jsx(
|
|
1416
|
+
"div",
|
|
1417
|
+
{
|
|
1418
|
+
className: "fixed z-[var(--md-sys-z-menu)]",
|
|
1419
|
+
ref: floating,
|
|
1420
|
+
style: { left: pos.left, top: pos.top },
|
|
1421
|
+
children: /* @__PURE__ */ jsx(
|
|
1422
|
+
Menu,
|
|
1423
|
+
{
|
|
1424
|
+
className: menuClassName,
|
|
1425
|
+
exiting,
|
|
1426
|
+
onClose: () => setIsOpen(false),
|
|
1427
|
+
up: pos.flippedVertically,
|
|
1428
|
+
children: menu
|
|
1429
|
+
}
|
|
1430
|
+
)
|
|
1431
|
+
}
|
|
1432
|
+
),
|
|
1433
|
+
document.body
|
|
1434
|
+
) : null
|
|
1373
1435
|
]
|
|
1374
1436
|
}
|
|
1375
1437
|
);
|
|
@@ -1548,37 +1610,981 @@ function Chips({
|
|
|
1548
1610
|
children: /* @__PURE__ */ jsx(CheckIcon, { selected })
|
|
1549
1611
|
}
|
|
1550
1612
|
),
|
|
1551
|
-
/* @__PURE__ */ jsx(
|
|
1552
|
-
"span",
|
|
1613
|
+
/* @__PURE__ */ jsx(
|
|
1614
|
+
"span",
|
|
1615
|
+
{
|
|
1616
|
+
className: cn(
|
|
1617
|
+
"absolute inset-0 flex items-center justify-center",
|
|
1618
|
+
selected ? "ease-md-linear opacity-0 transition-opacity duration-[50ms]" : "ease-legacy opacity-100 transition-opacity delay-[50ms] duration-150",
|
|
1619
|
+
accentIcon && !disabled && "text-primary"
|
|
1620
|
+
),
|
|
1621
|
+
children: leftElement
|
|
1622
|
+
}
|
|
1623
|
+
)
|
|
1624
|
+
] })
|
|
1625
|
+
) : /* @__PURE__ */ jsx(
|
|
1626
|
+
Icon,
|
|
1627
|
+
{
|
|
1628
|
+
className: cn(
|
|
1629
|
+
accentIcon && !disabled && !hasAvatar && "text-primary"
|
|
1630
|
+
),
|
|
1631
|
+
iconLeft: leftElement,
|
|
1632
|
+
size: hasAvatar ? 24 : 18
|
|
1633
|
+
}
|
|
1634
|
+
) : null,
|
|
1635
|
+
children ?? text,
|
|
1636
|
+
rightElement ? /* @__PURE__ */ jsx(Icon, { iconRight: rightElement, size: 18 }) : null
|
|
1637
|
+
]
|
|
1638
|
+
}
|
|
1639
|
+
);
|
|
1640
|
+
return removeButton ? /* @__PURE__ */ jsxs("span", { className: "relative inline-flex w-fit align-middle", children: [
|
|
1641
|
+
chip,
|
|
1642
|
+
removeButton
|
|
1643
|
+
] }) : chip;
|
|
1644
|
+
}
|
|
1645
|
+
function FloatingLabel({
|
|
1646
|
+
children,
|
|
1647
|
+
className,
|
|
1648
|
+
floating,
|
|
1649
|
+
floatingClassName,
|
|
1650
|
+
htmlFor,
|
|
1651
|
+
restingClassName
|
|
1652
|
+
}) {
|
|
1653
|
+
const floatingRef = useRef(null);
|
|
1654
|
+
const restingRef = useRef(null);
|
|
1655
|
+
const animationRef = useRef(null);
|
|
1656
|
+
const prevFloating = useRef(floating);
|
|
1657
|
+
const [animating, setAnimating] = useState(false);
|
|
1658
|
+
useIsomorphicLayoutEffect(() => {
|
|
1659
|
+
if (prevFloating.current === floating) return;
|
|
1660
|
+
prevFloating.current = floating;
|
|
1661
|
+
const floatingEl = floatingRef.current;
|
|
1662
|
+
const restingEl = restingRef.current;
|
|
1663
|
+
if (!floatingEl || !restingEl) return;
|
|
1664
|
+
const f = floatingEl.getBoundingClientRect();
|
|
1665
|
+
const r = restingEl.getBoundingClientRect();
|
|
1666
|
+
if (!f.width || !r.width) return;
|
|
1667
|
+
const scale = r.width / f.width;
|
|
1668
|
+
const xDelta = r.x - f.x;
|
|
1669
|
+
const yDelta = r.y - f.y + Math.round((r.height - f.height * scale) / 2);
|
|
1670
|
+
const rest = `translateX(${xDelta}px) translateY(${yDelta}px) scale(${scale})`;
|
|
1671
|
+
const float = `translateX(0) translateY(0) scale(1)`;
|
|
1672
|
+
animationRef.current?.cancel();
|
|
1673
|
+
setAnimating(true);
|
|
1674
|
+
const animation = floatingEl.animate(
|
|
1675
|
+
{ transform: floating ? [rest, float] : [float, rest] },
|
|
1676
|
+
{
|
|
1677
|
+
duration: 150,
|
|
1678
|
+
easing: "cubic-bezier(0.2, 0, 0, 1)",
|
|
1679
|
+
fill: "forwards"
|
|
1680
|
+
}
|
|
1681
|
+
);
|
|
1682
|
+
animationRef.current = animation;
|
|
1683
|
+
const done = () => {
|
|
1684
|
+
if (animationRef.current === animation) setAnimating(false);
|
|
1685
|
+
};
|
|
1686
|
+
animation.addEventListener("finish", done);
|
|
1687
|
+
animation.addEventListener("cancel", done);
|
|
1688
|
+
}, [floating]);
|
|
1689
|
+
useIsomorphicLayoutEffect(() => {
|
|
1690
|
+
if (animating || !animationRef.current) return;
|
|
1691
|
+
animationRef.current.cancel();
|
|
1692
|
+
animationRef.current = null;
|
|
1693
|
+
}, [animating]);
|
|
1694
|
+
const showFloating = floating || animating;
|
|
1695
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
1696
|
+
/* @__PURE__ */ jsx(
|
|
1697
|
+
"label",
|
|
1698
|
+
{
|
|
1699
|
+
"aria-hidden": true,
|
|
1700
|
+
className: cn(
|
|
1701
|
+
"pointer-events-none absolute",
|
|
1702
|
+
floatingClassName,
|
|
1703
|
+
className,
|
|
1704
|
+
!showFloating && "opacity-0"
|
|
1705
|
+
),
|
|
1706
|
+
children: /* @__PURE__ */ jsx("span", { className: "inline-block origin-top-left", ref: floatingRef, children })
|
|
1707
|
+
}
|
|
1708
|
+
),
|
|
1709
|
+
/* @__PURE__ */ jsx(
|
|
1710
|
+
"label",
|
|
1711
|
+
{
|
|
1712
|
+
className: cn(
|
|
1713
|
+
"pointer-events-none absolute",
|
|
1714
|
+
restingClassName,
|
|
1715
|
+
className,
|
|
1716
|
+
showFloating && "opacity-0"
|
|
1717
|
+
),
|
|
1718
|
+
htmlFor,
|
|
1719
|
+
children: /* @__PURE__ */ jsx("span", { className: "inline-block", ref: restingRef, children })
|
|
1720
|
+
}
|
|
1721
|
+
)
|
|
1722
|
+
] });
|
|
1723
|
+
}
|
|
1724
|
+
function useFieldState(value, defaultValue, disabled) {
|
|
1725
|
+
const [focused, setFocusedState] = useState(false);
|
|
1726
|
+
const [internalHasValue, setInternalHasValue] = useState(
|
|
1727
|
+
defaultValue !== void 0 && defaultValue !== null && String(defaultValue).length > 0
|
|
1728
|
+
);
|
|
1729
|
+
const hasValue = value !== void 0 && value !== null ? String(value).length > 0 : internalHasValue;
|
|
1730
|
+
return {
|
|
1731
|
+
focused: focused && !disabled,
|
|
1732
|
+
hasValue,
|
|
1733
|
+
setFocused: setFocusedState,
|
|
1734
|
+
setInternalHasValue
|
|
1735
|
+
};
|
|
1736
|
+
}
|
|
1737
|
+
function labelColor(opts) {
|
|
1738
|
+
if (opts.disabled) return "text-on-surface/38";
|
|
1739
|
+
if (opts.error) return "text-error";
|
|
1740
|
+
if (opts.focused) return "text-primary";
|
|
1741
|
+
return "text-on-surface-variant";
|
|
1742
|
+
}
|
|
1743
|
+
function SupportingText({
|
|
1744
|
+
error,
|
|
1745
|
+
errorText,
|
|
1746
|
+
id,
|
|
1747
|
+
supportingText
|
|
1748
|
+
}) {
|
|
1749
|
+
const isError = !!(error && errorText);
|
|
1750
|
+
const text = isError ? errorText : supportingText;
|
|
1751
|
+
if (!text) return null;
|
|
1752
|
+
return /* @__PURE__ */ jsx(
|
|
1753
|
+
"p",
|
|
1754
|
+
{
|
|
1755
|
+
role: isError ? "alert" : void 0,
|
|
1756
|
+
id,
|
|
1757
|
+
className: cn(
|
|
1758
|
+
"px-4 pt-1 text-body-small",
|
|
1759
|
+
error ? "text-error" : "text-on-surface-variant"
|
|
1760
|
+
),
|
|
1761
|
+
children: text
|
|
1762
|
+
}
|
|
1763
|
+
);
|
|
1764
|
+
}
|
|
1765
|
+
function FieldIcon({
|
|
1766
|
+
children,
|
|
1767
|
+
className
|
|
1768
|
+
}) {
|
|
1769
|
+
return /* @__PURE__ */ jsx(
|
|
1770
|
+
"span",
|
|
1771
|
+
{
|
|
1772
|
+
className: cn(
|
|
1773
|
+
"pointer-events-auto absolute flex h-6 w-6 items-center justify-center leading-none text-on-surface-variant",
|
|
1774
|
+
className
|
|
1775
|
+
),
|
|
1776
|
+
children
|
|
1777
|
+
}
|
|
1778
|
+
);
|
|
1779
|
+
}
|
|
1780
|
+
function useControlled(controlled, defaultValue) {
|
|
1781
|
+
const isControlled = useRef(controlled !== void 0).current;
|
|
1782
|
+
const [internal, setInternal] = useState(defaultValue);
|
|
1783
|
+
const value = isControlled && controlled !== void 0 ? controlled : internal;
|
|
1784
|
+
const setValue = useCallback(
|
|
1785
|
+
(next) => {
|
|
1786
|
+
if (!isControlled) setInternal(next);
|
|
1787
|
+
},
|
|
1788
|
+
[isControlled]
|
|
1789
|
+
);
|
|
1790
|
+
return [value, setValue];
|
|
1791
|
+
}
|
|
1792
|
+
var TYPEAHEAD_BUFFER_MS = 200;
|
|
1793
|
+
function optionText(option) {
|
|
1794
|
+
return typeof option.label === "string" ? option.label : option.value;
|
|
1795
|
+
}
|
|
1796
|
+
function useSelect({
|
|
1797
|
+
defaultValue,
|
|
1798
|
+
disabled,
|
|
1799
|
+
onChange,
|
|
1800
|
+
options,
|
|
1801
|
+
value: valueProp
|
|
1802
|
+
}) {
|
|
1803
|
+
const [value, setValue] = useControlled(valueProp, defaultValue ?? "");
|
|
1804
|
+
const [isOpen, setIsOpen] = useState(false);
|
|
1805
|
+
const [focused, setFocused] = useState(false);
|
|
1806
|
+
const [highlighted, setHighlighted] = useState(-1);
|
|
1807
|
+
const wrapper = useRef(null);
|
|
1808
|
+
const typeahead = useRef({ buffer: "", time: 0 });
|
|
1809
|
+
const { exiting, mounted } = useDismissable(isOpen, 150);
|
|
1810
|
+
useOutsideClose(wrapper, () => setIsOpen(false), isOpen);
|
|
1811
|
+
const selectedIndex = options.findIndex((option) => option.value === value);
|
|
1812
|
+
const move = (start, delta) => {
|
|
1813
|
+
for (let step = 1; step <= options.length; step += 1) {
|
|
1814
|
+
const index = (start + delta * step + options.length * step) % options.length;
|
|
1815
|
+
if (!options[index]?.disabled) return index;
|
|
1816
|
+
}
|
|
1817
|
+
return -1;
|
|
1818
|
+
};
|
|
1819
|
+
const openMenu = () => {
|
|
1820
|
+
if (disabled) return;
|
|
1821
|
+
setHighlighted(
|
|
1822
|
+
selectedIndex >= 0 && !options[selectedIndex]?.disabled ? selectedIndex : move(-1, 1)
|
|
1823
|
+
);
|
|
1824
|
+
setIsOpen(true);
|
|
1825
|
+
};
|
|
1826
|
+
const commit = (next) => {
|
|
1827
|
+
setValue(next);
|
|
1828
|
+
onChange?.(next);
|
|
1829
|
+
setIsOpen(false);
|
|
1830
|
+
};
|
|
1831
|
+
const typeaheadFind = (char) => {
|
|
1832
|
+
const now = Date.now();
|
|
1833
|
+
const stale = now - typeahead.current.time > TYPEAHEAD_BUFFER_MS;
|
|
1834
|
+
typeahead.current = {
|
|
1835
|
+
buffer: (stale ? "" : typeahead.current.buffer) + char.toLowerCase(),
|
|
1836
|
+
time: now
|
|
1837
|
+
};
|
|
1838
|
+
return options.findIndex(
|
|
1839
|
+
(option) => !option.disabled && optionText(option).toLowerCase().startsWith(typeahead.current.buffer)
|
|
1840
|
+
);
|
|
1841
|
+
};
|
|
1842
|
+
const handleKeyDown = (event) => {
|
|
1843
|
+
if (disabled) return;
|
|
1844
|
+
const { key } = event;
|
|
1845
|
+
const printable = key.length === 1 && key !== " " && !event.altKey && !event.ctrlKey && !event.metaKey;
|
|
1846
|
+
if (!isOpen) {
|
|
1847
|
+
if (["ArrowDown", "ArrowUp", "Enter", " "].includes(key)) {
|
|
1848
|
+
event.preventDefault();
|
|
1849
|
+
openMenu();
|
|
1850
|
+
} else if (printable) {
|
|
1851
|
+
const index = typeaheadFind(key);
|
|
1852
|
+
if (index >= 0) {
|
|
1853
|
+
setValue(options[index].value);
|
|
1854
|
+
onChange?.(options[index].value);
|
|
1855
|
+
}
|
|
1856
|
+
}
|
|
1857
|
+
return;
|
|
1858
|
+
}
|
|
1859
|
+
switch (key) {
|
|
1860
|
+
case "ArrowDown":
|
|
1861
|
+
event.preventDefault();
|
|
1862
|
+
setHighlighted((current) => move(current, 1));
|
|
1863
|
+
break;
|
|
1864
|
+
case "ArrowUp":
|
|
1865
|
+
event.preventDefault();
|
|
1866
|
+
setHighlighted((current) => move(current, -1));
|
|
1867
|
+
break;
|
|
1868
|
+
case "Home":
|
|
1869
|
+
event.preventDefault();
|
|
1870
|
+
setHighlighted(move(-1, 1));
|
|
1871
|
+
break;
|
|
1872
|
+
case "End":
|
|
1873
|
+
event.preventDefault();
|
|
1874
|
+
setHighlighted(move(options.length, -1));
|
|
1875
|
+
break;
|
|
1876
|
+
case "Enter":
|
|
1877
|
+
case " ": {
|
|
1878
|
+
event.preventDefault();
|
|
1879
|
+
const option = options[highlighted];
|
|
1880
|
+
if (option && !option.disabled) commit(option.value);
|
|
1881
|
+
break;
|
|
1882
|
+
}
|
|
1883
|
+
case "Escape":
|
|
1884
|
+
event.preventDefault();
|
|
1885
|
+
setIsOpen(false);
|
|
1886
|
+
break;
|
|
1887
|
+
case "Tab":
|
|
1888
|
+
setIsOpen(false);
|
|
1889
|
+
break;
|
|
1890
|
+
default:
|
|
1891
|
+
if (printable) {
|
|
1892
|
+
const index = typeaheadFind(key);
|
|
1893
|
+
if (index >= 0) setHighlighted(index);
|
|
1894
|
+
}
|
|
1895
|
+
}
|
|
1896
|
+
};
|
|
1897
|
+
return {
|
|
1898
|
+
commit,
|
|
1899
|
+
exiting,
|
|
1900
|
+
focused: focused && !disabled,
|
|
1901
|
+
handleKeyDown,
|
|
1902
|
+
highlighted,
|
|
1903
|
+
isOpen,
|
|
1904
|
+
mounted,
|
|
1905
|
+
openMenu,
|
|
1906
|
+
selectedIndex,
|
|
1907
|
+
setFocused,
|
|
1908
|
+
setHighlighted,
|
|
1909
|
+
setIsOpen,
|
|
1910
|
+
value,
|
|
1911
|
+
wrapper
|
|
1912
|
+
};
|
|
1913
|
+
}
|
|
1914
|
+
function SelectMenu({
|
|
1915
|
+
baseId,
|
|
1916
|
+
exiting,
|
|
1917
|
+
highlighted,
|
|
1918
|
+
onHighlight,
|
|
1919
|
+
onSelect,
|
|
1920
|
+
options,
|
|
1921
|
+
value
|
|
1922
|
+
}) {
|
|
1923
|
+
useEffect(() => {
|
|
1924
|
+
if (highlighted < 0) return;
|
|
1925
|
+
document.getElementById(`${baseId}-opt-${highlighted}`)?.scrollIntoView({ block: "nearest" });
|
|
1926
|
+
}, [baseId, highlighted]);
|
|
1927
|
+
return /* @__PURE__ */ jsx(
|
|
1928
|
+
"ul",
|
|
1929
|
+
{
|
|
1930
|
+
className: cn(
|
|
1931
|
+
"absolute top-full left-0 z-[var(--md-sys-z-dropdown)] mt-1 flex max-h-[280px] w-full min-w-max flex-col overflow-hidden overflow-y-auto rounded-large bg-surface-container-low py-0.5 shadow-mm-3 [--menu-clip-bleed:-24px]",
|
|
1932
|
+
exiting ? "animate-menu-out" : "animate-menu-in"
|
|
1933
|
+
),
|
|
1934
|
+
id: `${baseId}-listbox`,
|
|
1935
|
+
role: "listbox",
|
|
1936
|
+
children: options.map((option, index) => {
|
|
1937
|
+
const isSelected = option.value === value;
|
|
1938
|
+
return /* @__PURE__ */ jsx(
|
|
1939
|
+
"li",
|
|
1940
|
+
{
|
|
1941
|
+
"aria-disabled": option.disabled || void 0,
|
|
1942
|
+
"aria-selected": isSelected,
|
|
1943
|
+
className: cn(
|
|
1944
|
+
"mx-1 my-0.5 flex h-11 shrink-0 cursor-pointer items-center rounded-extra-small px-3 text-label-large first:rounded-t-medium last:rounded-b-medium",
|
|
1945
|
+
isSelected ? "rounded-medium bg-tertiary-container text-on-tertiary-container" : "text-on-surface",
|
|
1946
|
+
highlighted === index && !isSelected && "bg-on-surface/8",
|
|
1947
|
+
option.disabled && "cursor-not-allowed text-on-surface/38"
|
|
1948
|
+
),
|
|
1949
|
+
id: `${baseId}-opt-${index}`,
|
|
1950
|
+
onClick: () => {
|
|
1951
|
+
if (!option.disabled) onSelect(option.value);
|
|
1952
|
+
},
|
|
1953
|
+
onMouseDown: (event) => event.preventDefault(),
|
|
1954
|
+
onMouseEnter: () => {
|
|
1955
|
+
if (!option.disabled) onHighlight(index);
|
|
1956
|
+
},
|
|
1957
|
+
role: "option",
|
|
1958
|
+
children: /* @__PURE__ */ jsx("span", { className: "truncate", children: option.label ?? option.value })
|
|
1959
|
+
},
|
|
1960
|
+
option.value
|
|
1961
|
+
);
|
|
1962
|
+
})
|
|
1963
|
+
}
|
|
1964
|
+
);
|
|
1965
|
+
}
|
|
1966
|
+
function SelectCaret({ open = false }) {
|
|
1967
|
+
const fade = "ease-md-linear transition-opacity delay-75 duration-75";
|
|
1968
|
+
return /* @__PURE__ */ jsxs(
|
|
1969
|
+
"svg",
|
|
1970
|
+
{
|
|
1971
|
+
"aria-hidden": true,
|
|
1972
|
+
fill: "currentColor",
|
|
1973
|
+
height: 24,
|
|
1974
|
+
viewBox: "0 0 24 24",
|
|
1975
|
+
width: 24,
|
|
1976
|
+
children: [
|
|
1977
|
+
/* @__PURE__ */ jsx(
|
|
1978
|
+
"path",
|
|
1979
|
+
{
|
|
1980
|
+
className: cn(fade, open ? "opacity-0" : "opacity-100"),
|
|
1981
|
+
d: "M7 10l5 5 5-5z"
|
|
1982
|
+
}
|
|
1983
|
+
),
|
|
1984
|
+
/* @__PURE__ */ jsx(
|
|
1985
|
+
"path",
|
|
1986
|
+
{
|
|
1987
|
+
className: cn(fade, open ? "opacity-100" : "opacity-0"),
|
|
1988
|
+
d: "M7 15l5-5 5 5z"
|
|
1989
|
+
}
|
|
1990
|
+
)
|
|
1991
|
+
]
|
|
1992
|
+
}
|
|
1993
|
+
);
|
|
1994
|
+
}
|
|
1995
|
+
var COMBOBOX_LABELS = {
|
|
1996
|
+
clear: "Clear",
|
|
1997
|
+
empty: "No results",
|
|
1998
|
+
loading: "Loading\u2026"
|
|
1999
|
+
};
|
|
2000
|
+
function useCombobox({
|
|
2001
|
+
defaultValue,
|
|
2002
|
+
disabled,
|
|
2003
|
+
onChange,
|
|
2004
|
+
onInputChange,
|
|
2005
|
+
options,
|
|
2006
|
+
value: valueProp
|
|
2007
|
+
}) {
|
|
2008
|
+
const [value, setValue] = useControlled(valueProp, defaultValue ?? "");
|
|
2009
|
+
const labelFor = (next) => options.find((option) => option.value === next)?.label ?? next;
|
|
2010
|
+
const [query, setQuery] = useState(() => value ? labelFor(value) : "");
|
|
2011
|
+
const [isOpen, setIsOpen] = useState(false);
|
|
2012
|
+
const [focused, setFocused] = useState(false);
|
|
2013
|
+
const [highlighted, setHighlighted] = useState(-1);
|
|
2014
|
+
const wrapper = useRef(null);
|
|
2015
|
+
const input = useRef(null);
|
|
2016
|
+
const { exiting, mounted } = useDismissable(isOpen, 150);
|
|
2017
|
+
useEffect(() => {
|
|
2018
|
+
if (!isOpen) setQuery(value ? labelFor(value) : "");
|
|
2019
|
+
}, [isOpen, value]);
|
|
2020
|
+
const move = (start, delta) => {
|
|
2021
|
+
if (options.length === 0) return -1;
|
|
2022
|
+
for (let step = 1; step <= options.length; step += 1) {
|
|
2023
|
+
const index = (start + delta * step + options.length * step) % options.length;
|
|
2024
|
+
if (!options[index]?.disabled) return index;
|
|
2025
|
+
}
|
|
2026
|
+
return -1;
|
|
2027
|
+
};
|
|
2028
|
+
const open = () => {
|
|
2029
|
+
if (disabled) return;
|
|
2030
|
+
const selectedIndex = options.findIndex((option) => option.value === value);
|
|
2031
|
+
setHighlighted(
|
|
2032
|
+
selectedIndex >= 0 && !options[selectedIndex]?.disabled ? selectedIndex : move(-1, 1)
|
|
2033
|
+
);
|
|
2034
|
+
setIsOpen(true);
|
|
2035
|
+
};
|
|
2036
|
+
const closeAndRevert = () => {
|
|
2037
|
+
setIsOpen(false);
|
|
2038
|
+
setHighlighted(-1);
|
|
2039
|
+
setQuery(value ? labelFor(value) : "");
|
|
2040
|
+
};
|
|
2041
|
+
useOutsideClose(wrapper, closeAndRevert, isOpen);
|
|
2042
|
+
const onType = (next) => {
|
|
2043
|
+
setQuery(next);
|
|
2044
|
+
setIsOpen(true);
|
|
2045
|
+
setHighlighted(-1);
|
|
2046
|
+
onInputChange?.(next);
|
|
2047
|
+
};
|
|
2048
|
+
const commit = (next) => {
|
|
2049
|
+
setValue(next);
|
|
2050
|
+
onChange?.(next);
|
|
2051
|
+
setQuery(labelFor(next));
|
|
2052
|
+
setIsOpen(false);
|
|
2053
|
+
setHighlighted(-1);
|
|
2054
|
+
};
|
|
2055
|
+
const clear = () => {
|
|
2056
|
+
setValue("");
|
|
2057
|
+
onChange?.("");
|
|
2058
|
+
setQuery("");
|
|
2059
|
+
setHighlighted(-1);
|
|
2060
|
+
onInputChange?.("");
|
|
2061
|
+
input.current?.focus();
|
|
2062
|
+
};
|
|
2063
|
+
const handleKeyDown = (event) => {
|
|
2064
|
+
if (disabled) return;
|
|
2065
|
+
switch (event.key) {
|
|
2066
|
+
case "ArrowDown":
|
|
2067
|
+
event.preventDefault();
|
|
2068
|
+
if (isOpen) setHighlighted((current) => move(current, 1));
|
|
2069
|
+
else open();
|
|
2070
|
+
break;
|
|
2071
|
+
case "ArrowUp":
|
|
2072
|
+
event.preventDefault();
|
|
2073
|
+
if (isOpen) setHighlighted((current) => move(current, -1));
|
|
2074
|
+
else open();
|
|
2075
|
+
break;
|
|
2076
|
+
case "Home":
|
|
2077
|
+
if (isOpen) {
|
|
2078
|
+
event.preventDefault();
|
|
2079
|
+
setHighlighted(move(-1, 1));
|
|
2080
|
+
}
|
|
2081
|
+
break;
|
|
2082
|
+
case "End":
|
|
2083
|
+
if (isOpen) {
|
|
2084
|
+
event.preventDefault();
|
|
2085
|
+
setHighlighted(move(options.length, -1));
|
|
2086
|
+
}
|
|
2087
|
+
break;
|
|
2088
|
+
case "Enter":
|
|
2089
|
+
if (isOpen && highlighted >= 0) {
|
|
2090
|
+
event.preventDefault();
|
|
2091
|
+
const option = options[highlighted];
|
|
2092
|
+
if (option && !option.disabled) commit(option.value);
|
|
2093
|
+
}
|
|
2094
|
+
break;
|
|
2095
|
+
case "Escape":
|
|
2096
|
+
if (isOpen) {
|
|
2097
|
+
event.preventDefault();
|
|
2098
|
+
closeAndRevert();
|
|
2099
|
+
}
|
|
2100
|
+
break;
|
|
2101
|
+
case "Tab":
|
|
2102
|
+
if (isOpen) closeAndRevert();
|
|
2103
|
+
break;
|
|
2104
|
+
}
|
|
2105
|
+
};
|
|
2106
|
+
return {
|
|
2107
|
+
clear,
|
|
2108
|
+
commit,
|
|
2109
|
+
exiting,
|
|
2110
|
+
focused: focused && !disabled,
|
|
2111
|
+
handleKeyDown,
|
|
2112
|
+
highlighted,
|
|
2113
|
+
input,
|
|
2114
|
+
isOpen,
|
|
2115
|
+
mounted,
|
|
2116
|
+
onType,
|
|
2117
|
+
query,
|
|
2118
|
+
setFocused,
|
|
2119
|
+
setHighlighted,
|
|
2120
|
+
setIsOpen,
|
|
2121
|
+
value,
|
|
2122
|
+
wrapper
|
|
2123
|
+
};
|
|
2124
|
+
}
|
|
2125
|
+
function CloseGlyph() {
|
|
2126
|
+
return /* @__PURE__ */ jsx("svg", { "aria-hidden": true, fill: "currentColor", height: 18, viewBox: "0 0 24 24", width: 18, children: /* @__PURE__ */ jsx("path", { d: "M19 6.41 17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12 19 6.41z" }) });
|
|
2127
|
+
}
|
|
2128
|
+
function ComboboxTrailing({
|
|
2129
|
+
clearLabel,
|
|
2130
|
+
disabled,
|
|
2131
|
+
error,
|
|
2132
|
+
isOpen,
|
|
2133
|
+
onClear,
|
|
2134
|
+
showClear
|
|
2135
|
+
}) {
|
|
2136
|
+
return /* @__PURE__ */ jsxs("div", { className: "pointer-events-none absolute top-1/2 right-2 flex -translate-y-1/2 items-center gap-1", children: [
|
|
2137
|
+
showClear ? /* @__PURE__ */ jsx(
|
|
2138
|
+
"button",
|
|
2139
|
+
{
|
|
2140
|
+
"aria-label": clearLabel,
|
|
2141
|
+
className: "state-layer pointer-events-auto flex h-6 w-6 cursor-pointer items-center justify-center rounded-full text-on-surface-variant",
|
|
2142
|
+
onMouseDown: (event) => event.preventDefault(),
|
|
2143
|
+
onClick: onClear,
|
|
2144
|
+
type: "button",
|
|
2145
|
+
children: /* @__PURE__ */ jsx(CloseGlyph, {})
|
|
2146
|
+
}
|
|
2147
|
+
) : null,
|
|
2148
|
+
/* @__PURE__ */ jsx(
|
|
2149
|
+
"span",
|
|
2150
|
+
{
|
|
2151
|
+
className: cn(
|
|
2152
|
+
"flex h-6 w-6 items-center justify-center text-on-surface-variant",
|
|
2153
|
+
error && "text-error",
|
|
2154
|
+
disabled && "text-on-surface/38"
|
|
2155
|
+
),
|
|
2156
|
+
children: /* @__PURE__ */ jsx(SelectCaret, { open: isOpen })
|
|
2157
|
+
}
|
|
2158
|
+
)
|
|
2159
|
+
] });
|
|
2160
|
+
}
|
|
2161
|
+
function ComboboxListbox({
|
|
2162
|
+
anchorRef,
|
|
2163
|
+
baseId,
|
|
2164
|
+
emptyText,
|
|
2165
|
+
exiting,
|
|
2166
|
+
highlighted,
|
|
2167
|
+
listboxClassName,
|
|
2168
|
+
loading,
|
|
2169
|
+
loadingText,
|
|
2170
|
+
onHighlight,
|
|
2171
|
+
onSelect,
|
|
2172
|
+
options,
|
|
2173
|
+
value
|
|
2174
|
+
}) {
|
|
2175
|
+
const floating = useRef(null);
|
|
2176
|
+
const pos = usePopoverPosition(anchorRef, floating, true, {
|
|
2177
|
+
gap: 4,
|
|
2178
|
+
matchWidth: true,
|
|
2179
|
+
placement: "bottom-start"
|
|
2180
|
+
});
|
|
2181
|
+
useEffect(() => {
|
|
2182
|
+
if (highlighted < 0) return;
|
|
2183
|
+
document.getElementById(`${baseId}-opt-${highlighted}`)?.scrollIntoView?.({ block: "nearest" });
|
|
2184
|
+
}, [baseId, highlighted]);
|
|
2185
|
+
if (typeof document === "undefined") return null;
|
|
2186
|
+
const anim = exiting ? "animate-menu-out" : "animate-menu-in";
|
|
2187
|
+
const surface = "max-h-[280px] w-full overflow-hidden overflow-y-auto rounded-large bg-surface-container-low py-0.5 shadow-mm-3 [--menu-clip-bleed:-24px]";
|
|
2188
|
+
return createPortal(
|
|
2189
|
+
/* @__PURE__ */ jsx(
|
|
2190
|
+
"div",
|
|
2191
|
+
{
|
|
2192
|
+
className: "fixed z-[var(--md-sys-z-menu)]",
|
|
2193
|
+
ref: floating,
|
|
2194
|
+
style: { left: pos.left, top: pos.top, width: pos.width },
|
|
2195
|
+
children: loading || options.length === 0 ? (
|
|
2196
|
+
// An empty listbox is an a11y violation — show a status row instead.
|
|
2197
|
+
/* @__PURE__ */ jsx(
|
|
2198
|
+
"div",
|
|
2199
|
+
{
|
|
2200
|
+
"aria-live": "polite",
|
|
2201
|
+
className: cn(
|
|
2202
|
+
surface,
|
|
2203
|
+
anim,
|
|
2204
|
+
"px-4 py-3 text-body-medium text-on-surface-variant",
|
|
2205
|
+
listboxClassName
|
|
2206
|
+
),
|
|
2207
|
+
role: "status",
|
|
2208
|
+
children: loading ? loadingText : emptyText
|
|
2209
|
+
}
|
|
2210
|
+
)
|
|
2211
|
+
) : /* @__PURE__ */ jsx(
|
|
2212
|
+
"ul",
|
|
2213
|
+
{
|
|
2214
|
+
className: cn("flex flex-col", surface, anim, listboxClassName),
|
|
2215
|
+
id: `${baseId}-listbox`,
|
|
2216
|
+
role: "listbox",
|
|
2217
|
+
children: options.map((option, index) => {
|
|
2218
|
+
const isSelected = option.value === value;
|
|
2219
|
+
return /* @__PURE__ */ jsx(
|
|
2220
|
+
"li",
|
|
2221
|
+
{
|
|
2222
|
+
"aria-disabled": option.disabled || void 0,
|
|
2223
|
+
"aria-selected": isSelected,
|
|
2224
|
+
className: cn(
|
|
2225
|
+
"mx-1 my-0.5 flex h-11 shrink-0 cursor-pointer items-center rounded-extra-small px-3 text-label-large first:rounded-t-medium last:rounded-b-medium",
|
|
2226
|
+
isSelected ? "rounded-medium bg-tertiary-container text-on-tertiary-container" : "text-on-surface",
|
|
2227
|
+
highlighted === index && !isSelected && "bg-on-surface/8",
|
|
2228
|
+
option.disabled && "cursor-not-allowed text-on-surface/38"
|
|
2229
|
+
),
|
|
2230
|
+
id: `${baseId}-opt-${index}`,
|
|
2231
|
+
onClick: () => {
|
|
2232
|
+
if (!option.disabled) onSelect(option.value);
|
|
2233
|
+
},
|
|
2234
|
+
onMouseDown: (event) => event.preventDefault(),
|
|
2235
|
+
onMouseEnter: () => {
|
|
2236
|
+
if (!option.disabled) onHighlight(index);
|
|
2237
|
+
},
|
|
2238
|
+
role: "option",
|
|
2239
|
+
children: /* @__PURE__ */ jsx("span", { className: "truncate", children: option.label ?? option.value })
|
|
2240
|
+
},
|
|
2241
|
+
option.value
|
|
2242
|
+
);
|
|
2243
|
+
})
|
|
2244
|
+
}
|
|
2245
|
+
)
|
|
2246
|
+
}
|
|
2247
|
+
),
|
|
2248
|
+
document.body
|
|
2249
|
+
);
|
|
2250
|
+
}
|
|
2251
|
+
function ComboboxFilled({
|
|
2252
|
+
className,
|
|
2253
|
+
clearable = true,
|
|
2254
|
+
defaultValue,
|
|
2255
|
+
disabled,
|
|
2256
|
+
error,
|
|
2257
|
+
errorText,
|
|
2258
|
+
id,
|
|
2259
|
+
inputClassName,
|
|
2260
|
+
label,
|
|
2261
|
+
labels,
|
|
2262
|
+
leftElement,
|
|
2263
|
+
listboxClassName,
|
|
2264
|
+
loading,
|
|
2265
|
+
name,
|
|
2266
|
+
onChange,
|
|
2267
|
+
onInputChange,
|
|
2268
|
+
options,
|
|
2269
|
+
supportingText,
|
|
2270
|
+
value: valueProp,
|
|
2271
|
+
...inputProps
|
|
2272
|
+
}) {
|
|
2273
|
+
const l = { ...COMBOBOX_LABELS, ...labels };
|
|
2274
|
+
const autoId = useId();
|
|
2275
|
+
const inputId = id ?? `${autoId}-input`;
|
|
2276
|
+
const {
|
|
2277
|
+
clear,
|
|
2278
|
+
commit,
|
|
2279
|
+
exiting,
|
|
2280
|
+
focused,
|
|
2281
|
+
handleKeyDown,
|
|
2282
|
+
highlighted,
|
|
2283
|
+
input,
|
|
2284
|
+
isOpen,
|
|
2285
|
+
mounted,
|
|
2286
|
+
onType,
|
|
2287
|
+
query,
|
|
2288
|
+
setFocused,
|
|
2289
|
+
setHighlighted,
|
|
2290
|
+
setIsOpen,
|
|
2291
|
+
value,
|
|
2292
|
+
wrapper
|
|
2293
|
+
} = useCombobox({
|
|
2294
|
+
defaultValue,
|
|
2295
|
+
disabled,
|
|
2296
|
+
onChange,
|
|
2297
|
+
onInputChange,
|
|
2298
|
+
options,
|
|
2299
|
+
value: valueProp
|
|
2300
|
+
});
|
|
2301
|
+
const active = focused || isOpen;
|
|
2302
|
+
const floating = active || query.length > 0;
|
|
2303
|
+
const showClear = clearable && query.length > 0 && !disabled;
|
|
2304
|
+
const hasOptions = !loading && options.length > 0;
|
|
2305
|
+
const describedById = error && errorText || supportingText ? `${autoId}-support` : void 0;
|
|
2306
|
+
return /* @__PURE__ */ jsxs("div", { className: cn("w-full", className), children: [
|
|
2307
|
+
/* @__PURE__ */ jsxs("div", { className: "relative", ref: wrapper, children: [
|
|
2308
|
+
/* @__PURE__ */ jsxs("div", { className: "group relative flex h-14 w-full overflow-hidden rounded-t-small", children: [
|
|
2309
|
+
leftElement ? /* @__PURE__ */ jsx(FieldIcon, { className: "top-1/2 left-3 z-10 -translate-y-1/2", children: leftElement }) : null,
|
|
2310
|
+
/* @__PURE__ */ jsx(
|
|
2311
|
+
"input",
|
|
2312
|
+
{
|
|
2313
|
+
...inputProps,
|
|
2314
|
+
"aria-activedescendant": isOpen && hasOptions && highlighted >= 0 ? `${autoId}-opt-${highlighted}` : void 0,
|
|
2315
|
+
"aria-autocomplete": onInputChange ? "list" : "none",
|
|
2316
|
+
"aria-controls": mounted && hasOptions ? `${autoId}-listbox` : void 0,
|
|
2317
|
+
"aria-describedby": describedById,
|
|
2318
|
+
"aria-expanded": isOpen,
|
|
2319
|
+
"aria-invalid": error || void 0,
|
|
2320
|
+
autoComplete: "off",
|
|
2321
|
+
className: cn(
|
|
2322
|
+
"h-14 w-full bg-surface-container-highest text-body-large text-on-surface outline-none disabled:cursor-not-allowed disabled:bg-on-surface/4 disabled:text-on-surface/38",
|
|
2323
|
+
label ? "pt-5 pb-1" : "",
|
|
2324
|
+
leftElement ? "pl-12" : "pl-4",
|
|
2325
|
+
showClear ? "pr-20" : "pr-12",
|
|
2326
|
+
inputClassName
|
|
2327
|
+
),
|
|
2328
|
+
disabled,
|
|
2329
|
+
id: inputId,
|
|
2330
|
+
onBlur: () => setFocused(false),
|
|
2331
|
+
onChange: (event) => onType(event.target.value),
|
|
2332
|
+
onClick: () => {
|
|
2333
|
+
if (!disabled) setIsOpen(true);
|
|
2334
|
+
},
|
|
2335
|
+
onFocus: () => setFocused(true),
|
|
2336
|
+
onKeyDown: handleKeyDown,
|
|
2337
|
+
ref: input,
|
|
2338
|
+
role: "combobox",
|
|
2339
|
+
type: "text",
|
|
2340
|
+
value: query
|
|
2341
|
+
}
|
|
2342
|
+
),
|
|
2343
|
+
!disabled ? /* @__PURE__ */ jsx(
|
|
2344
|
+
"span",
|
|
2345
|
+
{
|
|
2346
|
+
"aria-hidden": true,
|
|
2347
|
+
className: "ease-md-linear pointer-events-none absolute inset-0 bg-on-surface opacity-0 transition-opacity duration-[15ms] group-hover:opacity-8"
|
|
2348
|
+
}
|
|
2349
|
+
) : null,
|
|
2350
|
+
/* @__PURE__ */ jsx(
|
|
2351
|
+
"span",
|
|
2352
|
+
{
|
|
2353
|
+
"aria-hidden": true,
|
|
2354
|
+
className: cn(
|
|
2355
|
+
"pointer-events-none absolute inset-x-0 bottom-0 transition-all",
|
|
2356
|
+
error ? "bg-error" : active ? "bg-primary" : "bg-on-surface-variant",
|
|
2357
|
+
active || error ? "h-0.5" : "h-px",
|
|
2358
|
+
disabled && "bg-on-surface/38"
|
|
2359
|
+
)
|
|
2360
|
+
}
|
|
2361
|
+
),
|
|
2362
|
+
label ? /* @__PURE__ */ jsx(
|
|
2363
|
+
FloatingLabel,
|
|
2364
|
+
{
|
|
2365
|
+
className: labelColor({ disabled, error, focused: active }),
|
|
2366
|
+
floating,
|
|
2367
|
+
floatingClassName: cn(
|
|
2368
|
+
"top-2 text-body-small",
|
|
2369
|
+
leftElement ? "left-12" : "left-4"
|
|
2370
|
+
),
|
|
2371
|
+
htmlFor: inputId,
|
|
2372
|
+
restingClassName: cn(
|
|
2373
|
+
"top-1/2 -translate-y-1/2 text-body-large",
|
|
2374
|
+
leftElement ? "left-12" : "left-4"
|
|
2375
|
+
),
|
|
2376
|
+
children: label
|
|
2377
|
+
}
|
|
2378
|
+
) : null,
|
|
2379
|
+
/* @__PURE__ */ jsx(
|
|
2380
|
+
ComboboxTrailing,
|
|
2381
|
+
{
|
|
2382
|
+
clearLabel: l.clear,
|
|
2383
|
+
disabled,
|
|
2384
|
+
error,
|
|
2385
|
+
isOpen,
|
|
2386
|
+
onClear: clear,
|
|
2387
|
+
showClear
|
|
2388
|
+
}
|
|
2389
|
+
)
|
|
2390
|
+
] }),
|
|
2391
|
+
mounted ? /* @__PURE__ */ jsx(
|
|
2392
|
+
ComboboxListbox,
|
|
2393
|
+
{
|
|
2394
|
+
anchorRef: wrapper,
|
|
2395
|
+
baseId: autoId,
|
|
2396
|
+
emptyText: l.empty,
|
|
2397
|
+
exiting,
|
|
2398
|
+
highlighted,
|
|
2399
|
+
listboxClassName,
|
|
2400
|
+
loading,
|
|
2401
|
+
loadingText: l.loading,
|
|
2402
|
+
onHighlight: setHighlighted,
|
|
2403
|
+
onSelect: commit,
|
|
2404
|
+
options,
|
|
2405
|
+
value
|
|
2406
|
+
}
|
|
2407
|
+
) : null
|
|
2408
|
+
] }),
|
|
2409
|
+
name ? /* @__PURE__ */ jsx("input", { name, type: "hidden", value }) : null,
|
|
2410
|
+
/* @__PURE__ */ jsx(
|
|
2411
|
+
SupportingText,
|
|
2412
|
+
{
|
|
2413
|
+
error,
|
|
2414
|
+
errorText,
|
|
2415
|
+
id: describedById,
|
|
2416
|
+
supportingText
|
|
2417
|
+
}
|
|
2418
|
+
)
|
|
2419
|
+
] });
|
|
2420
|
+
}
|
|
2421
|
+
function ComboboxOutlined({
|
|
2422
|
+
className,
|
|
2423
|
+
clearable = true,
|
|
2424
|
+
defaultValue,
|
|
2425
|
+
disabled,
|
|
2426
|
+
error,
|
|
2427
|
+
errorText,
|
|
2428
|
+
id,
|
|
2429
|
+
inputClassName,
|
|
2430
|
+
label,
|
|
2431
|
+
labels,
|
|
2432
|
+
leftElement,
|
|
2433
|
+
listboxClassName,
|
|
2434
|
+
loading,
|
|
2435
|
+
name,
|
|
2436
|
+
onChange,
|
|
2437
|
+
onInputChange,
|
|
2438
|
+
options,
|
|
2439
|
+
supportingText,
|
|
2440
|
+
value: valueProp,
|
|
2441
|
+
...inputProps
|
|
2442
|
+
}) {
|
|
2443
|
+
const l = { ...COMBOBOX_LABELS, ...labels };
|
|
2444
|
+
const autoId = useId();
|
|
2445
|
+
const inputId = id ?? `${autoId}-input`;
|
|
2446
|
+
const {
|
|
2447
|
+
clear,
|
|
2448
|
+
commit,
|
|
2449
|
+
exiting,
|
|
2450
|
+
focused,
|
|
2451
|
+
handleKeyDown,
|
|
2452
|
+
highlighted,
|
|
2453
|
+
input,
|
|
2454
|
+
isOpen,
|
|
2455
|
+
mounted,
|
|
2456
|
+
onType,
|
|
2457
|
+
query,
|
|
2458
|
+
setFocused,
|
|
2459
|
+
setHighlighted,
|
|
2460
|
+
setIsOpen,
|
|
2461
|
+
value,
|
|
2462
|
+
wrapper
|
|
2463
|
+
} = useCombobox({
|
|
2464
|
+
defaultValue,
|
|
2465
|
+
disabled,
|
|
2466
|
+
onChange,
|
|
2467
|
+
onInputChange,
|
|
2468
|
+
options,
|
|
2469
|
+
value: valueProp
|
|
2470
|
+
});
|
|
2471
|
+
const active = focused || isOpen;
|
|
2472
|
+
const floating = active || query.length > 0;
|
|
2473
|
+
const showClear = clearable && query.length > 0 && !disabled;
|
|
2474
|
+
const hasOptions = !loading && options.length > 0;
|
|
2475
|
+
const describedById = error && errorText || supportingText ? `${autoId}-support` : void 0;
|
|
2476
|
+
return /* @__PURE__ */ jsxs("div", { className: cn("w-full", className), children: [
|
|
2477
|
+
/* @__PURE__ */ jsxs("div", { className: "relative", ref: wrapper, children: [
|
|
2478
|
+
/* @__PURE__ */ jsxs("div", { className: "group relative flex h-14 w-full", children: [
|
|
2479
|
+
leftElement ? /* @__PURE__ */ jsx(FieldIcon, { className: "top-1/2 left-3 -translate-y-1/2", children: leftElement }) : null,
|
|
2480
|
+
/* @__PURE__ */ jsx(
|
|
2481
|
+
"input",
|
|
2482
|
+
{
|
|
2483
|
+
...inputProps,
|
|
2484
|
+
"aria-activedescendant": isOpen && hasOptions && highlighted >= 0 ? `${autoId}-opt-${highlighted}` : void 0,
|
|
2485
|
+
"aria-autocomplete": onInputChange ? "list" : "none",
|
|
2486
|
+
"aria-controls": mounted && hasOptions ? `${autoId}-listbox` : void 0,
|
|
2487
|
+
"aria-describedby": describedById,
|
|
2488
|
+
"aria-expanded": isOpen,
|
|
2489
|
+
"aria-invalid": error || void 0,
|
|
2490
|
+
autoComplete: "off",
|
|
2491
|
+
className: cn(
|
|
2492
|
+
"h-14 w-full bg-transparent text-body-large text-on-surface outline-none disabled:cursor-not-allowed disabled:text-on-surface/38",
|
|
2493
|
+
leftElement ? "pl-12" : "pl-4",
|
|
2494
|
+
showClear ? "pr-20" : "pr-12",
|
|
2495
|
+
inputClassName
|
|
2496
|
+
),
|
|
2497
|
+
disabled,
|
|
2498
|
+
id: inputId,
|
|
2499
|
+
onBlur: () => setFocused(false),
|
|
2500
|
+
onChange: (event) => onType(event.target.value),
|
|
2501
|
+
onClick: () => {
|
|
2502
|
+
if (!disabled) setIsOpen(true);
|
|
2503
|
+
},
|
|
2504
|
+
onFocus: () => setFocused(true),
|
|
2505
|
+
onKeyDown: handleKeyDown,
|
|
2506
|
+
ref: input,
|
|
2507
|
+
role: "combobox",
|
|
2508
|
+
type: "text",
|
|
2509
|
+
value: query
|
|
2510
|
+
}
|
|
2511
|
+
),
|
|
2512
|
+
/* @__PURE__ */ jsx(
|
|
2513
|
+
"fieldset",
|
|
2514
|
+
{
|
|
2515
|
+
"aria-hidden": true,
|
|
2516
|
+
className: cn(
|
|
2517
|
+
"pointer-events-none absolute inset-0 m-0 min-w-0 rounded-small px-2 transition-colors",
|
|
2518
|
+
error ? active ? "border-2 border-error" : "border border-error" : active ? "border-2 border-primary" : "border border-outline group-hover:border-on-surface",
|
|
2519
|
+
disabled && "border-on-surface/12 group-hover:border-on-surface/12"
|
|
2520
|
+
),
|
|
2521
|
+
children: label ? /* @__PURE__ */ jsx(
|
|
2522
|
+
"legend",
|
|
1553
2523
|
{
|
|
1554
2524
|
className: cn(
|
|
1555
|
-
"
|
|
1556
|
-
|
|
1557
|
-
accentIcon && !disabled && "text-primary"
|
|
2525
|
+
"invisible h-0 px-0 text-body-small whitespace-nowrap transition-all",
|
|
2526
|
+
floating ? "max-w-full px-1" : "max-w-0"
|
|
1558
2527
|
),
|
|
1559
|
-
children:
|
|
2528
|
+
children: label
|
|
1560
2529
|
}
|
|
1561
|
-
)
|
|
1562
|
-
|
|
1563
|
-
)
|
|
1564
|
-
|
|
2530
|
+
) : null
|
|
2531
|
+
}
|
|
2532
|
+
),
|
|
2533
|
+
label ? /* @__PURE__ */ jsx(
|
|
2534
|
+
FloatingLabel,
|
|
1565
2535
|
{
|
|
1566
|
-
className:
|
|
1567
|
-
|
|
2536
|
+
className: labelColor({ disabled, error, focused: active }),
|
|
2537
|
+
floating,
|
|
2538
|
+
floatingClassName: "top-0 left-3 -translate-y-1/2 px-1 text-body-small",
|
|
2539
|
+
htmlFor: inputId,
|
|
2540
|
+
restingClassName: cn(
|
|
2541
|
+
"top-1/2 -translate-y-1/2 text-body-large",
|
|
2542
|
+
leftElement ? "left-12" : "left-4"
|
|
1568
2543
|
),
|
|
1569
|
-
|
|
1570
|
-
size: hasAvatar ? 24 : 18
|
|
2544
|
+
children: label
|
|
1571
2545
|
}
|
|
1572
2546
|
) : null,
|
|
1573
|
-
|
|
1574
|
-
|
|
1575
|
-
|
|
1576
|
-
|
|
1577
|
-
|
|
1578
|
-
|
|
1579
|
-
|
|
1580
|
-
|
|
1581
|
-
|
|
2547
|
+
/* @__PURE__ */ jsx(
|
|
2548
|
+
ComboboxTrailing,
|
|
2549
|
+
{
|
|
2550
|
+
clearLabel: l.clear,
|
|
2551
|
+
disabled,
|
|
2552
|
+
error,
|
|
2553
|
+
isOpen,
|
|
2554
|
+
onClear: clear,
|
|
2555
|
+
showClear
|
|
2556
|
+
}
|
|
2557
|
+
)
|
|
2558
|
+
] }),
|
|
2559
|
+
mounted ? /* @__PURE__ */ jsx(
|
|
2560
|
+
ComboboxListbox,
|
|
2561
|
+
{
|
|
2562
|
+
anchorRef: wrapper,
|
|
2563
|
+
baseId: autoId,
|
|
2564
|
+
emptyText: l.empty,
|
|
2565
|
+
exiting,
|
|
2566
|
+
highlighted,
|
|
2567
|
+
listboxClassName,
|
|
2568
|
+
loading,
|
|
2569
|
+
loadingText: l.loading,
|
|
2570
|
+
onHighlight: setHighlighted,
|
|
2571
|
+
onSelect: commit,
|
|
2572
|
+
options,
|
|
2573
|
+
value
|
|
2574
|
+
}
|
|
2575
|
+
) : null
|
|
2576
|
+
] }),
|
|
2577
|
+
name ? /* @__PURE__ */ jsx("input", { name, type: "hidden", value }) : null,
|
|
2578
|
+
/* @__PURE__ */ jsx(
|
|
2579
|
+
SupportingText,
|
|
2580
|
+
{
|
|
2581
|
+
error,
|
|
2582
|
+
errorText,
|
|
2583
|
+
id: describedById,
|
|
2584
|
+
supportingText
|
|
2585
|
+
}
|
|
2586
|
+
)
|
|
2587
|
+
] });
|
|
1582
2588
|
}
|
|
1583
2589
|
function TableBody({ children, className, ...props }) {
|
|
1584
2590
|
return /* @__PURE__ */ jsx("tbody", { className: cn("text-body-medium", className), ...props, children });
|
|
@@ -1754,7 +2760,7 @@ function Dialog({
|
|
|
1754
2760
|
"div",
|
|
1755
2761
|
{
|
|
1756
2762
|
className: cn(
|
|
1757
|
-
"fixed inset-0 z-
|
|
2763
|
+
"fixed inset-0 z-[var(--md-sys-z-modal)] flex items-center justify-center bg-scrim/32 p-4",
|
|
1758
2764
|
exiting ? "animate-scrim-out" : "animate-scrim-in"
|
|
1759
2765
|
),
|
|
1760
2766
|
onClick: handleScrim,
|
|
@@ -1783,141 +2789,6 @@ function Dialog({
|
|
|
1783
2789
|
Dialog.Header = DialogHeader;
|
|
1784
2790
|
Dialog.Body = DialogBody;
|
|
1785
2791
|
Dialog.Footer = DialogFooter;
|
|
1786
|
-
function FloatingLabel({
|
|
1787
|
-
children,
|
|
1788
|
-
className,
|
|
1789
|
-
floating,
|
|
1790
|
-
floatingClassName,
|
|
1791
|
-
htmlFor,
|
|
1792
|
-
restingClassName
|
|
1793
|
-
}) {
|
|
1794
|
-
const floatingRef = useRef(null);
|
|
1795
|
-
const restingRef = useRef(null);
|
|
1796
|
-
const animationRef = useRef(null);
|
|
1797
|
-
const prevFloating = useRef(floating);
|
|
1798
|
-
const [animating, setAnimating] = useState(false);
|
|
1799
|
-
useIsomorphicLayoutEffect(() => {
|
|
1800
|
-
if (prevFloating.current === floating) return;
|
|
1801
|
-
prevFloating.current = floating;
|
|
1802
|
-
const floatingEl = floatingRef.current;
|
|
1803
|
-
const restingEl = restingRef.current;
|
|
1804
|
-
if (!floatingEl || !restingEl) return;
|
|
1805
|
-
const f = floatingEl.getBoundingClientRect();
|
|
1806
|
-
const r = restingEl.getBoundingClientRect();
|
|
1807
|
-
if (!f.width || !r.width) return;
|
|
1808
|
-
const scale = r.width / f.width;
|
|
1809
|
-
const xDelta = r.x - f.x;
|
|
1810
|
-
const yDelta = r.y - f.y + Math.round((r.height - f.height * scale) / 2);
|
|
1811
|
-
const rest = `translateX(${xDelta}px) translateY(${yDelta}px) scale(${scale})`;
|
|
1812
|
-
const float = `translateX(0) translateY(0) scale(1)`;
|
|
1813
|
-
animationRef.current?.cancel();
|
|
1814
|
-
setAnimating(true);
|
|
1815
|
-
const animation = floatingEl.animate(
|
|
1816
|
-
{ transform: floating ? [rest, float] : [float, rest] },
|
|
1817
|
-
{
|
|
1818
|
-
duration: 150,
|
|
1819
|
-
easing: "cubic-bezier(0.2, 0, 0, 1)",
|
|
1820
|
-
fill: "forwards"
|
|
1821
|
-
}
|
|
1822
|
-
);
|
|
1823
|
-
animationRef.current = animation;
|
|
1824
|
-
const done = () => {
|
|
1825
|
-
if (animationRef.current === animation) setAnimating(false);
|
|
1826
|
-
};
|
|
1827
|
-
animation.addEventListener("finish", done);
|
|
1828
|
-
animation.addEventListener("cancel", done);
|
|
1829
|
-
}, [floating]);
|
|
1830
|
-
useIsomorphicLayoutEffect(() => {
|
|
1831
|
-
if (animating || !animationRef.current) return;
|
|
1832
|
-
animationRef.current.cancel();
|
|
1833
|
-
animationRef.current = null;
|
|
1834
|
-
}, [animating]);
|
|
1835
|
-
const showFloating = floating || animating;
|
|
1836
|
-
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
1837
|
-
/* @__PURE__ */ jsx(
|
|
1838
|
-
"label",
|
|
1839
|
-
{
|
|
1840
|
-
"aria-hidden": true,
|
|
1841
|
-
className: cn(
|
|
1842
|
-
"pointer-events-none absolute",
|
|
1843
|
-
floatingClassName,
|
|
1844
|
-
className,
|
|
1845
|
-
!showFloating && "opacity-0"
|
|
1846
|
-
),
|
|
1847
|
-
children: /* @__PURE__ */ jsx("span", { className: "inline-block origin-top-left", ref: floatingRef, children })
|
|
1848
|
-
}
|
|
1849
|
-
),
|
|
1850
|
-
/* @__PURE__ */ jsx(
|
|
1851
|
-
"label",
|
|
1852
|
-
{
|
|
1853
|
-
className: cn(
|
|
1854
|
-
"pointer-events-none absolute",
|
|
1855
|
-
restingClassName,
|
|
1856
|
-
className,
|
|
1857
|
-
showFloating && "opacity-0"
|
|
1858
|
-
),
|
|
1859
|
-
htmlFor,
|
|
1860
|
-
children: /* @__PURE__ */ jsx("span", { className: "inline-block", ref: restingRef, children })
|
|
1861
|
-
}
|
|
1862
|
-
)
|
|
1863
|
-
] });
|
|
1864
|
-
}
|
|
1865
|
-
function useFieldState(value, defaultValue, disabled) {
|
|
1866
|
-
const [focused, setFocusedState] = useState(false);
|
|
1867
|
-
const [internalHasValue, setInternalHasValue] = useState(
|
|
1868
|
-
defaultValue !== void 0 && defaultValue !== null && String(defaultValue).length > 0
|
|
1869
|
-
);
|
|
1870
|
-
const hasValue = value !== void 0 && value !== null ? String(value).length > 0 : internalHasValue;
|
|
1871
|
-
return {
|
|
1872
|
-
focused: focused && !disabled,
|
|
1873
|
-
hasValue,
|
|
1874
|
-
setFocused: setFocusedState,
|
|
1875
|
-
setInternalHasValue
|
|
1876
|
-
};
|
|
1877
|
-
}
|
|
1878
|
-
function labelColor(opts) {
|
|
1879
|
-
if (opts.disabled) return "text-on-surface/38";
|
|
1880
|
-
if (opts.error) return "text-error";
|
|
1881
|
-
if (opts.focused) return "text-primary";
|
|
1882
|
-
return "text-on-surface-variant";
|
|
1883
|
-
}
|
|
1884
|
-
function SupportingText({
|
|
1885
|
-
error,
|
|
1886
|
-
errorText,
|
|
1887
|
-
id,
|
|
1888
|
-
supportingText
|
|
1889
|
-
}) {
|
|
1890
|
-
const isError = !!(error && errorText);
|
|
1891
|
-
const text = isError ? errorText : supportingText;
|
|
1892
|
-
if (!text) return null;
|
|
1893
|
-
return /* @__PURE__ */ jsx(
|
|
1894
|
-
"p",
|
|
1895
|
-
{
|
|
1896
|
-
role: isError ? "alert" : void 0,
|
|
1897
|
-
id,
|
|
1898
|
-
className: cn(
|
|
1899
|
-
"px-4 pt-1 text-body-small",
|
|
1900
|
-
error ? "text-error" : "text-on-surface-variant"
|
|
1901
|
-
),
|
|
1902
|
-
children: text
|
|
1903
|
-
}
|
|
1904
|
-
);
|
|
1905
|
-
}
|
|
1906
|
-
function FieldIcon({
|
|
1907
|
-
children,
|
|
1908
|
-
className
|
|
1909
|
-
}) {
|
|
1910
|
-
return /* @__PURE__ */ jsx(
|
|
1911
|
-
"span",
|
|
1912
|
-
{
|
|
1913
|
-
className: cn(
|
|
1914
|
-
"pointer-events-auto absolute flex h-6 w-6 items-center justify-center leading-none text-on-surface-variant",
|
|
1915
|
-
className
|
|
1916
|
-
),
|
|
1917
|
-
children
|
|
1918
|
-
}
|
|
1919
|
-
);
|
|
1920
|
-
}
|
|
1921
2792
|
function InputOutlined({
|
|
1922
2793
|
"aria-describedby": ariaDescribedBy,
|
|
1923
2794
|
"aria-invalid": ariaInvalid,
|
|
@@ -2382,11 +3253,14 @@ var DOCKED_LABELS = {
|
|
|
2382
3253
|
};
|
|
2383
3254
|
function DatePickerDocked({
|
|
2384
3255
|
className,
|
|
3256
|
+
error,
|
|
3257
|
+
errorText,
|
|
2385
3258
|
labels,
|
|
2386
3259
|
locale,
|
|
2387
3260
|
max,
|
|
2388
3261
|
min,
|
|
2389
3262
|
onChange,
|
|
3263
|
+
supportingText,
|
|
2390
3264
|
value = null,
|
|
2391
3265
|
weekStartsOn
|
|
2392
3266
|
}) {
|
|
@@ -2399,6 +3273,8 @@ function DatePickerDocked({
|
|
|
2399
3273
|
/* @__PURE__ */ jsx(
|
|
2400
3274
|
InputOutlined,
|
|
2401
3275
|
{
|
|
3276
|
+
error,
|
|
3277
|
+
errorText,
|
|
2402
3278
|
inputClassName: "cursor-pointer",
|
|
2403
3279
|
label: l.field,
|
|
2404
3280
|
onFocus: () => setOpen(true),
|
|
@@ -2416,6 +3292,7 @@ function DatePickerDocked({
|
|
|
2416
3292
|
children: calendarIcon
|
|
2417
3293
|
}
|
|
2418
3294
|
),
|
|
3295
|
+
supportingText,
|
|
2419
3296
|
value: formatShort(value, locale)
|
|
2420
3297
|
}
|
|
2421
3298
|
),
|
|
@@ -2423,7 +3300,7 @@ function DatePickerDocked({
|
|
|
2423
3300
|
"div",
|
|
2424
3301
|
{
|
|
2425
3302
|
"aria-label": l.field,
|
|
2426
|
-
className: "animate-menu-in absolute top-full left-0 z-
|
|
3303
|
+
className: "animate-menu-in absolute top-full left-0 z-[var(--md-sys-z-dropdown)] mt-1 w-90 max-w-[calc(100vw-2rem)] overflow-hidden rounded-large bg-surface-container-high py-2 shadow-mm-3 [--menu-clip-bleed:-24px]",
|
|
2427
3304
|
id: popupId,
|
|
2428
3305
|
role: "dialog",
|
|
2429
3306
|
children: /* @__PURE__ */ jsx(
|
|
@@ -2572,9 +3449,14 @@ function Dropdown({
|
|
|
2572
3449
|
const [open, setOpen] = useState(false);
|
|
2573
3450
|
const wrapper = useRef(null);
|
|
2574
3451
|
const trigger = useRef(null);
|
|
3452
|
+
const floating = useRef(null);
|
|
2575
3453
|
const wasOpen = useRef(false);
|
|
2576
3454
|
const menuId = useId();
|
|
2577
3455
|
const { exiting, mounted } = useDismissable(open, 150);
|
|
3456
|
+
const pos = usePopoverPosition(wrapper, floating, mounted, {
|
|
3457
|
+
gap: apart ? 4 : 0,
|
|
3458
|
+
placement: "bottom-start"
|
|
3459
|
+
});
|
|
2578
3460
|
useOutsideClose(wrapper, () => setOpen(false), open);
|
|
2579
3461
|
const triggerNode = isValidElement(children) ? cloneElement(
|
|
2580
3462
|
children,
|
|
@@ -2605,17 +3487,29 @@ function Dropdown({
|
|
|
2605
3487
|
children: triggerNode
|
|
2606
3488
|
}
|
|
2607
3489
|
),
|
|
2608
|
-
mounted
|
|
2609
|
-
|
|
2610
|
-
|
|
2611
|
-
|
|
2612
|
-
|
|
2613
|
-
|
|
2614
|
-
|
|
2615
|
-
|
|
2616
|
-
|
|
2617
|
-
|
|
2618
|
-
|
|
3490
|
+
mounted && typeof document !== "undefined" ? createPortal(
|
|
3491
|
+
/* @__PURE__ */ jsx(
|
|
3492
|
+
"div",
|
|
3493
|
+
{
|
|
3494
|
+
className: "fixed z-[var(--md-sys-z-menu)]",
|
|
3495
|
+
ref: floating,
|
|
3496
|
+
style: { left: pos.left, top: pos.top },
|
|
3497
|
+
children: /* @__PURE__ */ jsx(
|
|
3498
|
+
Menu,
|
|
3499
|
+
{
|
|
3500
|
+
className: menuClassName,
|
|
3501
|
+
exiting,
|
|
3502
|
+
id: menuId,
|
|
3503
|
+
onClose: () => setOpen(false),
|
|
3504
|
+
up: pos.flippedVertically,
|
|
3505
|
+
vibrant,
|
|
3506
|
+
children: menu
|
|
3507
|
+
}
|
|
3508
|
+
)
|
|
3509
|
+
}
|
|
3510
|
+
),
|
|
3511
|
+
document.body
|
|
3512
|
+
) : null
|
|
2619
3513
|
]
|
|
2620
3514
|
}
|
|
2621
3515
|
);
|
|
@@ -2998,7 +3892,7 @@ function NavigationRail({
|
|
|
2998
3892
|
"div",
|
|
2999
3893
|
{
|
|
3000
3894
|
className: cn(
|
|
3001
|
-
"fixed inset-0 z-
|
|
3895
|
+
"fixed inset-0 z-[var(--md-sys-z-modal)] bg-scrim/32",
|
|
3002
3896
|
scrim.exiting ? "animate-scrim-drawer-out" : "animate-scrim-drawer-in"
|
|
3003
3897
|
),
|
|
3004
3898
|
onClick: onClose
|
|
@@ -3023,11 +3917,16 @@ function OverflowMenu({
|
|
|
3023
3917
|
const [open, setOpen] = useState(false);
|
|
3024
3918
|
const wrapper = useRef(null);
|
|
3025
3919
|
const trigger = useRef(null);
|
|
3920
|
+
const floating = useRef(null);
|
|
3026
3921
|
const wasOpen = useRef(false);
|
|
3027
3922
|
const menuId = useId();
|
|
3028
|
-
const
|
|
3029
|
-
const opensUp = Boolean(topLeft || topRight);
|
|
3923
|
+
const placement = topRight ? "top-end" : topLeft ? "top-start" : bottomLeft ? "bottom-start" : bottomRight ? "bottom-end" : "bottom-end";
|
|
3030
3924
|
const { exiting, mounted } = useDismissable(open, 150);
|
|
3925
|
+
const pos = usePopoverPosition(wrapper, floating, mounted, {
|
|
3926
|
+
gap: 8,
|
|
3927
|
+
placement
|
|
3928
|
+
});
|
|
3929
|
+
const up = placement.startsWith("top") !== pos.flippedVertically;
|
|
3031
3930
|
useOutsideClose(wrapper, () => setOpen(false), open);
|
|
3032
3931
|
const triggerNode = isValidElement(children) ? cloneElement(
|
|
3033
3932
|
children,
|
|
@@ -3058,29 +3957,28 @@ function OverflowMenu({
|
|
|
3058
3957
|
children: triggerNode
|
|
3059
3958
|
}
|
|
3060
3959
|
),
|
|
3061
|
-
mounted
|
|
3062
|
-
|
|
3063
|
-
|
|
3064
|
-
|
|
3065
|
-
"
|
|
3066
|
-
|
|
3067
|
-
|
|
3068
|
-
|
|
3069
|
-
|
|
3070
|
-
|
|
3071
|
-
|
|
3072
|
-
|
|
3073
|
-
|
|
3074
|
-
|
|
3075
|
-
|
|
3076
|
-
|
|
3077
|
-
|
|
3078
|
-
|
|
3079
|
-
|
|
3080
|
-
|
|
3081
|
-
|
|
3082
|
-
|
|
3083
|
-
}
|
|
3960
|
+
mounted && typeof document !== "undefined" ? createPortal(
|
|
3961
|
+
/* @__PURE__ */ jsx(
|
|
3962
|
+
"div",
|
|
3963
|
+
{
|
|
3964
|
+
className: "fixed z-[var(--md-sys-z-menu)]",
|
|
3965
|
+
ref: floating,
|
|
3966
|
+
style: { left: pos.left, top: pos.top },
|
|
3967
|
+
children: /* @__PURE__ */ jsx(
|
|
3968
|
+
Menu,
|
|
3969
|
+
{
|
|
3970
|
+
className: menuClassName,
|
|
3971
|
+
exiting,
|
|
3972
|
+
id: menuId,
|
|
3973
|
+
onClose: () => setOpen(false),
|
|
3974
|
+
up,
|
|
3975
|
+
vibrant,
|
|
3976
|
+
children: menu
|
|
3977
|
+
}
|
|
3978
|
+
)
|
|
3979
|
+
}
|
|
3980
|
+
),
|
|
3981
|
+
document.body
|
|
3084
3982
|
) : null
|
|
3085
3983
|
]
|
|
3086
3984
|
}
|
|
@@ -3609,17 +4507,54 @@ function SearchItem({
|
|
|
3609
4507
|
);
|
|
3610
4508
|
}
|
|
3611
4509
|
var SEARCH_INPUT_LABELS = {
|
|
4510
|
+
clear: "Clear",
|
|
3612
4511
|
placeholder: "Search"
|
|
3613
4512
|
};
|
|
4513
|
+
function CloseIcon2() {
|
|
4514
|
+
return /* @__PURE__ */ jsx("svg", { "aria-hidden": true, className: "h-6 w-6 fill-current", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx("path", { d: "M19 6.41 17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12 19 6.41z" }) });
|
|
4515
|
+
}
|
|
3614
4516
|
function SearchInput({
|
|
3615
4517
|
className,
|
|
4518
|
+
clearable,
|
|
4519
|
+
defaultValue,
|
|
3616
4520
|
inputClassName,
|
|
3617
4521
|
labels,
|
|
3618
4522
|
leftElement,
|
|
4523
|
+
onChange,
|
|
4524
|
+
onClear,
|
|
3619
4525
|
rightElement,
|
|
4526
|
+
value: valueProp,
|
|
3620
4527
|
...inputProps
|
|
3621
4528
|
}) {
|
|
3622
4529
|
const l = { ...SEARCH_INPUT_LABELS, ...labels };
|
|
4530
|
+
const input = useRef(null);
|
|
4531
|
+
const [value, setValue] = useControlled(
|
|
4532
|
+
valueProp,
|
|
4533
|
+
typeof defaultValue === "string" ? defaultValue : ""
|
|
4534
|
+
);
|
|
4535
|
+
const hasValue = value.length > 0;
|
|
4536
|
+
const showClear = Boolean(
|
|
4537
|
+
clearable && hasValue && !inputProps.disabled && !rightElement
|
|
4538
|
+
);
|
|
4539
|
+
const handleChange = (event) => {
|
|
4540
|
+
setValue(event.target.value);
|
|
4541
|
+
onChange?.(event);
|
|
4542
|
+
};
|
|
4543
|
+
const clear = () => {
|
|
4544
|
+
const el = input.current;
|
|
4545
|
+
if (el) {
|
|
4546
|
+
const setter = Object.getOwnPropertyDescriptor(
|
|
4547
|
+
HTMLInputElement.prototype,
|
|
4548
|
+
"value"
|
|
4549
|
+
)?.set;
|
|
4550
|
+
setter?.call(el, "");
|
|
4551
|
+
el.dispatchEvent(new Event("input", { bubbles: true }));
|
|
4552
|
+
el.focus();
|
|
4553
|
+
} else {
|
|
4554
|
+
setValue("");
|
|
4555
|
+
}
|
|
4556
|
+
onClear?.();
|
|
4557
|
+
};
|
|
3623
4558
|
return /* @__PURE__ */ jsxs("div", { className: cn("relative flex h-14 w-full", className), children: [
|
|
3624
4559
|
leftElement ? /* @__PURE__ */ jsx("div", { className: "absolute left-0 flex h-14 w-14 items-center justify-center text-on-surface", children: leftElement }) : null,
|
|
3625
4560
|
/* @__PURE__ */ jsx(
|
|
@@ -3629,15 +4564,29 @@ function SearchInput({
|
|
|
3629
4564
|
className: cn(
|
|
3630
4565
|
"h-14 w-full bg-transparent text-body-large text-on-surface outline-none placeholder:text-on-surface-variant",
|
|
3631
4566
|
leftElement ? "pl-14" : "pl-4",
|
|
3632
|
-
rightElement ? "pr-14" : "pr-4",
|
|
4567
|
+
rightElement || showClear ? "pr-14" : "pr-4",
|
|
4568
|
+
// Hide the inconsistent native clear when we render our own.
|
|
4569
|
+
showClear && "[&::-webkit-search-cancel-button]:hidden",
|
|
3633
4570
|
inputClassName
|
|
3634
4571
|
),
|
|
3635
4572
|
type: "search",
|
|
3636
4573
|
...inputProps,
|
|
3637
|
-
|
|
4574
|
+
onChange: handleChange,
|
|
4575
|
+
placeholder: l.placeholder,
|
|
4576
|
+
ref: input,
|
|
4577
|
+
value
|
|
3638
4578
|
}
|
|
3639
4579
|
),
|
|
3640
|
-
rightElement ? /* @__PURE__ */ jsx("div", { className: "absolute right-0 flex h-14 w-14 items-center justify-center text-on-surface-variant", children: rightElement }) :
|
|
4580
|
+
rightElement ? /* @__PURE__ */ jsx("div", { className: "absolute right-0 flex h-14 w-14 items-center justify-center text-on-surface-variant", children: rightElement }) : showClear ? /* @__PURE__ */ jsx("div", { className: "absolute right-0 flex h-14 w-14 items-center justify-center", children: /* @__PURE__ */ jsx(
|
|
4581
|
+
"button",
|
|
4582
|
+
{
|
|
4583
|
+
"aria-label": l.clear,
|
|
4584
|
+
className: "state-layer flex h-12 w-12 cursor-pointer items-center justify-center rounded-full text-on-surface-variant",
|
|
4585
|
+
onClick: clear,
|
|
4586
|
+
type: "button",
|
|
4587
|
+
children: /* @__PURE__ */ jsx(CloseIcon2, {})
|
|
4588
|
+
}
|
|
4589
|
+
) }) : null
|
|
3641
4590
|
] });
|
|
3642
4591
|
}
|
|
3643
4592
|
function Search({
|
|
@@ -3656,7 +4605,7 @@ function Search({
|
|
|
3656
4605
|
"div",
|
|
3657
4606
|
{
|
|
3658
4607
|
className: cn(
|
|
3659
|
-
"relative z-
|
|
4608
|
+
"relative z-[var(--md-sys-z-dropdown)] flex h-fit w-full min-w-[360px] max-w-[720px] cursor-pointer bg-surface-container-high text-on-surface",
|
|
3660
4609
|
// Contained (M3 Expressive): the bar stays a persistent 28px
|
|
3661
4610
|
// pill (real px — corner-full would snap instead of morphing).
|
|
3662
4611
|
// Divided (baseline): its bottom corners square off in step
|
|
@@ -3707,221 +4656,6 @@ function Search({
|
|
|
3707
4656
|
}
|
|
3708
4657
|
Search.Item = SearchItem;
|
|
3709
4658
|
Search.Input = SearchInput;
|
|
3710
|
-
function useControlled(controlled, defaultValue) {
|
|
3711
|
-
const isControlled = useRef(controlled !== void 0).current;
|
|
3712
|
-
const [internal, setInternal] = useState(defaultValue);
|
|
3713
|
-
const value = isControlled && controlled !== void 0 ? controlled : internal;
|
|
3714
|
-
const setValue = useCallback(
|
|
3715
|
-
(next) => {
|
|
3716
|
-
if (!isControlled) setInternal(next);
|
|
3717
|
-
},
|
|
3718
|
-
[isControlled]
|
|
3719
|
-
);
|
|
3720
|
-
return [value, setValue];
|
|
3721
|
-
}
|
|
3722
|
-
var TYPEAHEAD_BUFFER_MS = 200;
|
|
3723
|
-
function optionText(option) {
|
|
3724
|
-
return typeof option.label === "string" ? option.label : option.value;
|
|
3725
|
-
}
|
|
3726
|
-
function useSelect({
|
|
3727
|
-
defaultValue,
|
|
3728
|
-
disabled,
|
|
3729
|
-
onChange,
|
|
3730
|
-
options,
|
|
3731
|
-
value: valueProp
|
|
3732
|
-
}) {
|
|
3733
|
-
const [value, setValue] = useControlled(valueProp, defaultValue ?? "");
|
|
3734
|
-
const [isOpen, setIsOpen] = useState(false);
|
|
3735
|
-
const [focused, setFocused] = useState(false);
|
|
3736
|
-
const [highlighted, setHighlighted] = useState(-1);
|
|
3737
|
-
const wrapper = useRef(null);
|
|
3738
|
-
const typeahead = useRef({ buffer: "", time: 0 });
|
|
3739
|
-
const { exiting, mounted } = useDismissable(isOpen, 150);
|
|
3740
|
-
useOutsideClose(wrapper, () => setIsOpen(false), isOpen);
|
|
3741
|
-
const selectedIndex = options.findIndex((option) => option.value === value);
|
|
3742
|
-
const move = (start, delta) => {
|
|
3743
|
-
for (let step = 1; step <= options.length; step += 1) {
|
|
3744
|
-
const index = (start + delta * step + options.length * step) % options.length;
|
|
3745
|
-
if (!options[index]?.disabled) return index;
|
|
3746
|
-
}
|
|
3747
|
-
return -1;
|
|
3748
|
-
};
|
|
3749
|
-
const openMenu = () => {
|
|
3750
|
-
if (disabled) return;
|
|
3751
|
-
setHighlighted(
|
|
3752
|
-
selectedIndex >= 0 && !options[selectedIndex]?.disabled ? selectedIndex : move(-1, 1)
|
|
3753
|
-
);
|
|
3754
|
-
setIsOpen(true);
|
|
3755
|
-
};
|
|
3756
|
-
const commit = (next) => {
|
|
3757
|
-
setValue(next);
|
|
3758
|
-
onChange?.(next);
|
|
3759
|
-
setIsOpen(false);
|
|
3760
|
-
};
|
|
3761
|
-
const typeaheadFind = (char) => {
|
|
3762
|
-
const now = Date.now();
|
|
3763
|
-
const stale = now - typeahead.current.time > TYPEAHEAD_BUFFER_MS;
|
|
3764
|
-
typeahead.current = {
|
|
3765
|
-
buffer: (stale ? "" : typeahead.current.buffer) + char.toLowerCase(),
|
|
3766
|
-
time: now
|
|
3767
|
-
};
|
|
3768
|
-
return options.findIndex(
|
|
3769
|
-
(option) => !option.disabled && optionText(option).toLowerCase().startsWith(typeahead.current.buffer)
|
|
3770
|
-
);
|
|
3771
|
-
};
|
|
3772
|
-
const handleKeyDown = (event) => {
|
|
3773
|
-
if (disabled) return;
|
|
3774
|
-
const { key } = event;
|
|
3775
|
-
const printable = key.length === 1 && key !== " " && !event.altKey && !event.ctrlKey && !event.metaKey;
|
|
3776
|
-
if (!isOpen) {
|
|
3777
|
-
if (["ArrowDown", "ArrowUp", "Enter", " "].includes(key)) {
|
|
3778
|
-
event.preventDefault();
|
|
3779
|
-
openMenu();
|
|
3780
|
-
} else if (printable) {
|
|
3781
|
-
const index = typeaheadFind(key);
|
|
3782
|
-
if (index >= 0) {
|
|
3783
|
-
setValue(options[index].value);
|
|
3784
|
-
onChange?.(options[index].value);
|
|
3785
|
-
}
|
|
3786
|
-
}
|
|
3787
|
-
return;
|
|
3788
|
-
}
|
|
3789
|
-
switch (key) {
|
|
3790
|
-
case "ArrowDown":
|
|
3791
|
-
event.preventDefault();
|
|
3792
|
-
setHighlighted((current) => move(current, 1));
|
|
3793
|
-
break;
|
|
3794
|
-
case "ArrowUp":
|
|
3795
|
-
event.preventDefault();
|
|
3796
|
-
setHighlighted((current) => move(current, -1));
|
|
3797
|
-
break;
|
|
3798
|
-
case "Home":
|
|
3799
|
-
event.preventDefault();
|
|
3800
|
-
setHighlighted(move(-1, 1));
|
|
3801
|
-
break;
|
|
3802
|
-
case "End":
|
|
3803
|
-
event.preventDefault();
|
|
3804
|
-
setHighlighted(move(options.length, -1));
|
|
3805
|
-
break;
|
|
3806
|
-
case "Enter":
|
|
3807
|
-
case " ": {
|
|
3808
|
-
event.preventDefault();
|
|
3809
|
-
const option = options[highlighted];
|
|
3810
|
-
if (option && !option.disabled) commit(option.value);
|
|
3811
|
-
break;
|
|
3812
|
-
}
|
|
3813
|
-
case "Escape":
|
|
3814
|
-
event.preventDefault();
|
|
3815
|
-
setIsOpen(false);
|
|
3816
|
-
break;
|
|
3817
|
-
case "Tab":
|
|
3818
|
-
setIsOpen(false);
|
|
3819
|
-
break;
|
|
3820
|
-
default:
|
|
3821
|
-
if (printable) {
|
|
3822
|
-
const index = typeaheadFind(key);
|
|
3823
|
-
if (index >= 0) setHighlighted(index);
|
|
3824
|
-
}
|
|
3825
|
-
}
|
|
3826
|
-
};
|
|
3827
|
-
return {
|
|
3828
|
-
commit,
|
|
3829
|
-
exiting,
|
|
3830
|
-
focused: focused && !disabled,
|
|
3831
|
-
handleKeyDown,
|
|
3832
|
-
highlighted,
|
|
3833
|
-
isOpen,
|
|
3834
|
-
mounted,
|
|
3835
|
-
openMenu,
|
|
3836
|
-
selectedIndex,
|
|
3837
|
-
setFocused,
|
|
3838
|
-
setHighlighted,
|
|
3839
|
-
setIsOpen,
|
|
3840
|
-
value,
|
|
3841
|
-
wrapper
|
|
3842
|
-
};
|
|
3843
|
-
}
|
|
3844
|
-
function SelectMenu({
|
|
3845
|
-
baseId,
|
|
3846
|
-
exiting,
|
|
3847
|
-
highlighted,
|
|
3848
|
-
onHighlight,
|
|
3849
|
-
onSelect,
|
|
3850
|
-
options,
|
|
3851
|
-
value
|
|
3852
|
-
}) {
|
|
3853
|
-
useEffect(() => {
|
|
3854
|
-
if (highlighted < 0) return;
|
|
3855
|
-
document.getElementById(`${baseId}-opt-${highlighted}`)?.scrollIntoView({ block: "nearest" });
|
|
3856
|
-
}, [baseId, highlighted]);
|
|
3857
|
-
return /* @__PURE__ */ jsx(
|
|
3858
|
-
"ul",
|
|
3859
|
-
{
|
|
3860
|
-
className: cn(
|
|
3861
|
-
"absolute top-full left-0 z-30 mt-1 flex max-h-[280px] w-full min-w-max flex-col overflow-hidden overflow-y-auto rounded-large bg-surface-container-low py-0.5 shadow-mm-3 [--menu-clip-bleed:-24px]",
|
|
3862
|
-
exiting ? "animate-menu-out" : "animate-menu-in"
|
|
3863
|
-
),
|
|
3864
|
-
id: `${baseId}-listbox`,
|
|
3865
|
-
role: "listbox",
|
|
3866
|
-
children: options.map((option, index) => {
|
|
3867
|
-
const isSelected = option.value === value;
|
|
3868
|
-
return /* @__PURE__ */ jsx(
|
|
3869
|
-
"li",
|
|
3870
|
-
{
|
|
3871
|
-
"aria-disabled": option.disabled || void 0,
|
|
3872
|
-
"aria-selected": isSelected,
|
|
3873
|
-
className: cn(
|
|
3874
|
-
"mx-1 my-0.5 flex h-11 shrink-0 cursor-pointer items-center rounded-extra-small px-3 text-label-large first:rounded-t-medium last:rounded-b-medium",
|
|
3875
|
-
isSelected ? "rounded-medium bg-tertiary-container text-on-tertiary-container" : "text-on-surface",
|
|
3876
|
-
highlighted === index && !isSelected && "bg-on-surface/8",
|
|
3877
|
-
option.disabled && "cursor-not-allowed text-on-surface/38"
|
|
3878
|
-
),
|
|
3879
|
-
id: `${baseId}-opt-${index}`,
|
|
3880
|
-
onClick: () => {
|
|
3881
|
-
if (!option.disabled) onSelect(option.value);
|
|
3882
|
-
},
|
|
3883
|
-
onMouseDown: (event) => event.preventDefault(),
|
|
3884
|
-
onMouseEnter: () => {
|
|
3885
|
-
if (!option.disabled) onHighlight(index);
|
|
3886
|
-
},
|
|
3887
|
-
role: "option",
|
|
3888
|
-
children: /* @__PURE__ */ jsx("span", { className: "truncate", children: option.label ?? option.value })
|
|
3889
|
-
},
|
|
3890
|
-
option.value
|
|
3891
|
-
);
|
|
3892
|
-
})
|
|
3893
|
-
}
|
|
3894
|
-
);
|
|
3895
|
-
}
|
|
3896
|
-
function SelectCaret({ open = false }) {
|
|
3897
|
-
const fade = "ease-md-linear transition-opacity delay-75 duration-75";
|
|
3898
|
-
return /* @__PURE__ */ jsxs(
|
|
3899
|
-
"svg",
|
|
3900
|
-
{
|
|
3901
|
-
"aria-hidden": true,
|
|
3902
|
-
fill: "currentColor",
|
|
3903
|
-
height: 24,
|
|
3904
|
-
viewBox: "0 0 24 24",
|
|
3905
|
-
width: 24,
|
|
3906
|
-
children: [
|
|
3907
|
-
/* @__PURE__ */ jsx(
|
|
3908
|
-
"path",
|
|
3909
|
-
{
|
|
3910
|
-
className: cn(fade, open ? "opacity-0" : "opacity-100"),
|
|
3911
|
-
d: "M7 10l5 5 5-5z"
|
|
3912
|
-
}
|
|
3913
|
-
),
|
|
3914
|
-
/* @__PURE__ */ jsx(
|
|
3915
|
-
"path",
|
|
3916
|
-
{
|
|
3917
|
-
className: cn(fade, open ? "opacity-100" : "opacity-0"),
|
|
3918
|
-
d: "M7 15l5-5 5 5z"
|
|
3919
|
-
}
|
|
3920
|
-
)
|
|
3921
|
-
]
|
|
3922
|
-
}
|
|
3923
|
-
);
|
|
3924
|
-
}
|
|
3925
4659
|
function SelectFilled({
|
|
3926
4660
|
className,
|
|
3927
4661
|
defaultValue,
|
|
@@ -4250,7 +4984,7 @@ function BottomSheet({
|
|
|
4250
4984
|
"div",
|
|
4251
4985
|
{
|
|
4252
4986
|
className: cn(
|
|
4253
|
-
"fixed inset-0 z-
|
|
4987
|
+
"fixed inset-0 z-[var(--md-sys-z-modal)] flex items-end justify-center bg-scrim/32",
|
|
4254
4988
|
exiting ? "animate-scrim-sheet-out" : "animate-scrim-sheet-in"
|
|
4255
4989
|
),
|
|
4256
4990
|
onClick: onClose,
|
|
@@ -4292,7 +5026,7 @@ var SIDE_SHEET_LABELS = {
|
|
|
4292
5026
|
close: "Close",
|
|
4293
5027
|
label: "Side sheet"
|
|
4294
5028
|
};
|
|
4295
|
-
function
|
|
5029
|
+
function CloseIcon3() {
|
|
4296
5030
|
return /* @__PURE__ */ jsx("svg", { "aria-hidden": true, fill: "none", height: 24, viewBox: "0 0 24 24", width: 24, children: /* @__PURE__ */ jsx(
|
|
4297
5031
|
"path",
|
|
4298
5032
|
{
|
|
@@ -4338,7 +5072,7 @@ function SideSheet({
|
|
|
4338
5072
|
"div",
|
|
4339
5073
|
{
|
|
4340
5074
|
className: cn(
|
|
4341
|
-
"fixed inset-0 z-
|
|
5075
|
+
"fixed inset-0 z-[var(--md-sys-z-modal)] flex justify-end bg-scrim/32",
|
|
4342
5076
|
exiting ? "animate-scrim-sheet-out" : "animate-scrim-sheet-in"
|
|
4343
5077
|
),
|
|
4344
5078
|
onClick: onClose,
|
|
@@ -4372,7 +5106,7 @@ function SideSheet({
|
|
|
4372
5106
|
IconButton,
|
|
4373
5107
|
{
|
|
4374
5108
|
"aria-label": l.close,
|
|
4375
|
-
icon: /* @__PURE__ */ jsx(
|
|
5109
|
+
icon: /* @__PURE__ */ jsx(CloseIcon3, {}),
|
|
4376
5110
|
onClick: onClose,
|
|
4377
5111
|
variant: "standard"
|
|
4378
5112
|
}
|
|
@@ -4769,7 +5503,7 @@ function SliderDual({
|
|
|
4769
5503
|
);
|
|
4770
5504
|
}
|
|
4771
5505
|
var SNACKBAR_LABELS = { dismiss: "Dismiss" };
|
|
4772
|
-
function
|
|
5506
|
+
function CloseIcon4() {
|
|
4773
5507
|
return /* @__PURE__ */ jsx("svg", { "aria-hidden": true, fill: "none", height: 24, viewBox: "0 0 24 24", width: 24, children: /* @__PURE__ */ jsx(
|
|
4774
5508
|
"path",
|
|
4775
5509
|
{
|
|
@@ -4848,7 +5582,7 @@ function Snackbar({
|
|
|
4848
5582
|
className: "iconBtn standard text-inverse-on-surface",
|
|
4849
5583
|
onClick: onClose,
|
|
4850
5584
|
type: "button",
|
|
4851
|
-
children: /* @__PURE__ */ jsx("span", { className: "flex h-6 w-6 items-center justify-center leading-none", children: closeIcon ?? /* @__PURE__ */ jsx(
|
|
5585
|
+
children: /* @__PURE__ */ jsx("span", { className: "flex h-6 w-6 items-center justify-center leading-none", children: closeIcon ?? /* @__PURE__ */ jsx(CloseIcon4, {}) })
|
|
4852
5586
|
}
|
|
4853
5587
|
) : null
|
|
4854
5588
|
] })
|
|
@@ -4862,7 +5596,7 @@ function SnackbarWrapper({ children, className }) {
|
|
|
4862
5596
|
useEffect(() => setMounted(true), []);
|
|
4863
5597
|
if (!mounted) return null;
|
|
4864
5598
|
return createPortal(
|
|
4865
|
-
/* @__PURE__ */ jsx("div", { className: "pointer-events-none fixed inset-x-4 top-auto bottom-0 z-
|
|
5599
|
+
/* @__PURE__ */ jsx("div", { className: "pointer-events-none fixed inset-x-4 top-auto bottom-0 z-[var(--md-sys-z-snackbar)] flex justify-center", children: /* @__PURE__ */ jsx(
|
|
4866
5600
|
"div",
|
|
4867
5601
|
{
|
|
4868
5602
|
className: cn(
|
|
@@ -6175,7 +6909,7 @@ function Tooltip({
|
|
|
6175
6909
|
{
|
|
6176
6910
|
id: tooltipId,
|
|
6177
6911
|
className: cn(
|
|
6178
|
-
"tooltip absolute z-
|
|
6912
|
+
"tooltip absolute z-[var(--md-sys-z-tooltip)] my-1",
|
|
6179
6913
|
rich ? "pointer-events-none w-max max-w-[320px] rounded-medium bg-surface-container px-4 pt-3 pb-2 shadow-mm-2 group-hover:pointer-events-auto group-focus-within:pointer-events-auto" : "pointer-events-none max-w-[200px] rounded-extra-small bg-inverse-surface px-2 py-1",
|
|
6180
6914
|
topRight && "right-0 bottom-full",
|
|
6181
6915
|
topLeft && "bottom-full left-0",
|
|
@@ -6867,40 +7601,54 @@ function Switch({
|
|
|
6867
7601
|
);
|
|
6868
7602
|
}
|
|
6869
7603
|
function TextElement({
|
|
7604
|
+
as: Wrapper = "div",
|
|
6870
7605
|
body,
|
|
7606
|
+
bodyAs: Body = "p",
|
|
6871
7607
|
bodyStyle,
|
|
6872
7608
|
className,
|
|
6873
7609
|
label,
|
|
7610
|
+
labelAs: Label = "p",
|
|
6874
7611
|
labelStyle,
|
|
6875
7612
|
title,
|
|
7613
|
+
titleAs: Title = "h2",
|
|
6876
7614
|
titleStyle
|
|
6877
7615
|
}) {
|
|
7616
|
+
const bare = [label, title, body].filter(Boolean).length === 1;
|
|
7617
|
+
const labelNode = label ? /* @__PURE__ */ jsx(
|
|
7618
|
+
Label,
|
|
7619
|
+
{
|
|
7620
|
+
className: cn(
|
|
7621
|
+
"text-label-medium text-on-surface-variant",
|
|
7622
|
+
labelStyle,
|
|
7623
|
+
bare && className
|
|
7624
|
+
),
|
|
7625
|
+
children: label
|
|
7626
|
+
}
|
|
7627
|
+
) : null;
|
|
7628
|
+
const titleNode = title ? /* @__PURE__ */ jsx(Title, { className: cn("text-title-medium text-on-surface", titleStyle, bare && className), children: title }) : null;
|
|
7629
|
+
const bodyNode = body ? /* @__PURE__ */ jsx(
|
|
7630
|
+
Body,
|
|
7631
|
+
{
|
|
7632
|
+
className: cn(
|
|
7633
|
+
"text-body-medium text-on-surface-variant",
|
|
7634
|
+
bodyStyle,
|
|
7635
|
+
bare && className
|
|
7636
|
+
),
|
|
7637
|
+
children: body
|
|
7638
|
+
}
|
|
7639
|
+
) : null;
|
|
7640
|
+
if (bare) return labelNode ?? titleNode ?? bodyNode;
|
|
6878
7641
|
return /* @__PURE__ */ jsxs(
|
|
6879
|
-
|
|
7642
|
+
Wrapper,
|
|
6880
7643
|
{
|
|
6881
7644
|
className: cn(
|
|
6882
7645
|
"flex flex-col items-start justify-center text-on-surface",
|
|
6883
7646
|
className
|
|
6884
7647
|
),
|
|
6885
7648
|
children: [
|
|
6886
|
-
|
|
6887
|
-
|
|
6888
|
-
|
|
6889
|
-
className: cn(
|
|
6890
|
-
"text-label-medium text-on-surface-variant",
|
|
6891
|
-
labelStyle
|
|
6892
|
-
),
|
|
6893
|
-
children: label
|
|
6894
|
-
}
|
|
6895
|
-
) : null,
|
|
6896
|
-
title ? /* @__PURE__ */ jsx("h2", { className: cn("text-title-medium", titleStyle), children: title }) : null,
|
|
6897
|
-
body ? /* @__PURE__ */ jsx(
|
|
6898
|
-
"p",
|
|
6899
|
-
{
|
|
6900
|
-
className: cn("text-body-medium text-on-surface-variant", bodyStyle),
|
|
6901
|
-
children: body
|
|
6902
|
-
}
|
|
6903
|
-
) : null
|
|
7649
|
+
labelNode,
|
|
7650
|
+
titleNode,
|
|
7651
|
+
bodyNode
|
|
6904
7652
|
]
|
|
6905
7653
|
}
|
|
6906
7654
|
);
|
|
@@ -6936,6 +7684,6 @@ function Section({ children, className }) {
|
|
|
6936
7684
|
);
|
|
6937
7685
|
}
|
|
6938
7686
|
|
|
6939
|
-
export { Amount, Avatar, AvatarStack, Badge, Blob, BottomSheet, Button, ButtonGroup, ButtonGroupConnected, Card, Checkbox, Chips, Circle, Container, DatePicker, DateRangePicker, Dialog, Divider, DockedToolbar, DotBadge, Dropdown, ExtendedFAB, FAB, FABMenu, FloatingToolbar, Gallery, Icon, IconButton, Img, InputFilled, InputOutlined, LinkBox, LinkContainer, List, Loading, LoadingIndicator, MaterialSymbol, MediaFrame, Menu, NavigationBar, NavigationRail, OnIconBadge, OverflowMenu, PerspectiveCard, PerspectiveImage, Progress, Radio, Search, SearchInput, Section, SelectFilled, SelectOutlined, SideSheet, Slider, SliderDual, Snackbar, SnackbarWrapper, SplitButton, Stories, Switch, Table, TabsPrimary, TabsSecondary, TextElement, TextFieldFilled, TextFieldOutlined, TimePicker, ToggleTheme, ToggleThemeMenu, Tooltip, TopAppBar, Video };
|
|
7687
|
+
export { Amount, Avatar, AvatarStack, Badge, Blob, BottomSheet, Button, ButtonGroup, ButtonGroupConnected, Card, Checkbox, Chips, Circle, ComboboxFilled, ComboboxOutlined, Container, DatePicker, DateRangePicker, Dialog, Divider, DockedToolbar, DotBadge, Dropdown, ExtendedFAB, FAB, FABMenu, FloatingToolbar, Gallery, Icon, IconButton, Img, InputFilled, InputOutlined, LinkBox, LinkContainer, List, Loading, LoadingIndicator, MaterialSymbol, MediaFrame, Menu, NavigationBar, NavigationRail, OnIconBadge, OverflowMenu, PerspectiveCard, PerspectiveImage, Progress, Radio, Search, SearchInput, Section, SelectFilled, SelectOutlined, SideSheet, Slider, SliderDual, Snackbar, SnackbarWrapper, SplitButton, Stories, Switch, Table, TabsPrimary, TabsSecondary, TextElement, TextFieldFilled, TextFieldOutlined, TimePicker, ToggleTheme, ToggleThemeMenu, Tooltip, TopAppBar, Video };
|
|
6940
7688
|
//# sourceMappingURL=index.js.map
|
|
6941
7689
|
//# sourceMappingURL=index.js.map
|