@usefidel/design-system 0.24.0 → 0.25.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/dist/index.cjs CHANGED
@@ -21,9 +21,12 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
21
21
  var index_exports = {};
22
22
  __export(index_exports, {
23
23
  Accordion: () => Accordion,
24
+ AppLayout: () => AppLayout,
24
25
  AppNav: () => AppNav,
25
26
  Avatar: () => Avatar,
27
+ AvatarLabelGroup: () => AvatarLabelGroup,
26
28
  Badge: () => Badge,
29
+ BrandButton: () => BrandButton,
27
30
  Button: () => Button,
28
31
  ButtonLink: () => ButtonLink,
29
32
  Callout: () => Callout,
@@ -31,13 +34,16 @@ __export(index_exports, {
31
34
  Checkbox: () => Checkbox,
32
35
  DiffPropertyList: () => DiffPropertyList,
33
36
  DiffSection: () => DiffSection,
37
+ Divider: () => Divider,
34
38
  EmptyState: () => EmptyState,
35
39
  IconButton: () => IconButton,
36
40
  Input: () => Input,
41
+ ListLabel: () => ListLabel,
37
42
  Menu: () => Menu,
38
43
  MismatchCard: () => MismatchCard,
39
44
  Modal: () => Modal,
40
45
  MultiSelect: () => MultiSelect,
46
+ PageHeader: () => PageHeader,
41
47
  Pagination: () => Pagination,
42
48
  PricingCard: () => PricingCard,
43
49
  Radio: () => Radio,
@@ -47,19 +53,28 @@ __export(index_exports, {
47
53
  SegmentedControl: () => SegmentedControl,
48
54
  Select: () => Select,
49
55
  SettingsSection: () => SettingsSection,
56
+ Sidebar: () => Sidebar,
57
+ SidebarItem: () => SidebarItem,
50
58
  Skeleton: () => Skeleton,
51
59
  SkeletonGroup: () => SkeletonGroup,
52
60
  Spinner: () => Spinner,
53
61
  Split: () => Split,
54
62
  StackedCardsIllustration: () => StackedCardsIllustration,
55
63
  Stat: () => Stat,
64
+ StatusDot: () => StatusDot,
56
65
  StepList: () => StepList,
57
66
  Swatch: () => Swatch,
58
67
  TabNav: () => TabNav,
59
68
  Table: () => Table,
60
69
  Tag: () => Tag,
70
+ Toast: () => Toast,
71
+ ToastRegion: () => ToastRegion,
61
72
  Toggle: () => Toggle,
62
- breakpoints: () => breakpoints
73
+ Tooltip: () => Tooltip,
74
+ WorkspaceAvatar: () => WorkspaceAvatar,
75
+ WorkspaceSwitcher: () => WorkspaceSwitcher,
76
+ breakpoints: () => breakpoints,
77
+ useSidebar: () => useSidebar
63
78
  });
64
79
  module.exports = __toCommonJS(index_exports);
65
80
 
@@ -1682,21 +1697,66 @@ function IconButton({
1682
1697
 
1683
1698
  // src/components/Menu/Menu.tsx
1684
1699
  var import_react17 = require("react");
1700
+ var import_lucide_react = require("lucide-react");
1685
1701
  var import_jsx_runtime34 = require("react/jsx-runtime");
1686
- function Menu({ trigger, items, align = "end", className }) {
1702
+ var isItem = (e) => !("type" in e);
1703
+ function searchText(it) {
1704
+ if (it.keywords) return it.keywords;
1705
+ return typeof it.label === "string" ? it.label : "";
1706
+ }
1707
+ function visibleEntries(items, query) {
1708
+ const q = query.trim().toLowerCase();
1709
+ if (!q) return items.map((_, i) => i);
1710
+ const matches = (i) => {
1711
+ const e = items[i];
1712
+ return isItem(e) && searchText(e).toLowerCase().includes(q);
1713
+ };
1714
+ const out = [];
1715
+ items.forEach((e, i) => {
1716
+ if (isItem(e)) {
1717
+ if (matches(i)) out.push(i);
1718
+ } else if (e.type === "label") {
1719
+ for (let j = i + 1; j < items.length && isItem(items[j]); j++) {
1720
+ if (matches(j)) {
1721
+ out.push(i);
1722
+ break;
1723
+ }
1724
+ }
1725
+ }
1726
+ });
1727
+ return out;
1728
+ }
1729
+ function Menu({
1730
+ trigger,
1731
+ items,
1732
+ align = "end",
1733
+ placement = "bottom",
1734
+ search,
1735
+ width = "auto",
1736
+ block = false,
1737
+ className
1738
+ }) {
1687
1739
  const listId = (0, import_react17.useId)();
1688
1740
  const rootRef = (0, import_react17.useRef)(null);
1689
1741
  const listRef = (0, import_react17.useRef)(null);
1742
+ const searchRef = (0, import_react17.useRef)(null);
1690
1743
  const [open, setOpen] = (0, import_react17.useState)(false);
1691
- const [active, setActive] = (0, import_react17.useState)(0);
1692
- const enabled = items.map((it, i) => it.disabled ? -1 : i).filter((i) => i >= 0);
1744
+ const [query, setQuery] = (0, import_react17.useState)("");
1745
+ const [active, setActive] = (0, import_react17.useState)(-1);
1746
+ const shown = visibleEntries(items, query);
1747
+ const enabled = shown.filter((i) => {
1748
+ const e = items[i];
1749
+ return isItem(e) && !e.disabled;
1750
+ });
1693
1751
  (0, import_react17.useEffect)(() => {
1694
1752
  if (!open) return;
1695
1753
  const onDown = (e) => {
1696
1754
  if (rootRef.current && !rootRef.current.contains(e.target)) setOpen(false);
1697
1755
  };
1698
1756
  document.addEventListener("mousedown", onDown);
1699
- const raf = requestAnimationFrame(() => listRef.current?.focus());
1757
+ const raf = requestAnimationFrame(
1758
+ () => (searchRef.current && !searchRef.current.disabled ? searchRef.current : listRef.current)?.focus()
1759
+ );
1700
1760
  return () => {
1701
1761
  document.removeEventListener("mousedown", onDown);
1702
1762
  cancelAnimationFrame(raf);
@@ -1707,20 +1767,26 @@ function Menu({ trigger, items, align = "end", className }) {
1707
1767
  setOpen(false);
1708
1768
  triggerEl()?.focus();
1709
1769
  };
1710
- const openAt = (index) => {
1711
- setActive(index);
1770
+ const openAt = (which) => {
1771
+ setQuery("");
1772
+ const all = visibleEntries(items, "").filter((i) => {
1773
+ const e = items[i];
1774
+ return isItem(e) && !e.disabled;
1775
+ });
1776
+ setActive((which === "first" ? all[0] : all[all.length - 1]) ?? -1);
1712
1777
  setOpen(true);
1713
1778
  };
1714
1779
  const choose = (i) => {
1715
- const it = items[i];
1716
- if (!it || it.disabled) return;
1780
+ const e = items[i];
1781
+ if (!e || !isItem(e) || e.disabled) return;
1717
1782
  close();
1718
- it.onSelect();
1783
+ e.onSelect();
1719
1784
  };
1720
1785
  const step = (dir) => {
1721
1786
  if (enabled.length === 0) return;
1722
1787
  const at = enabled.indexOf(active);
1723
- setActive(enabled[(at + dir + enabled.length) % enabled.length]);
1788
+ const next = at === -1 ? dir === 1 ? 0 : enabled.length - 1 : (at + dir + enabled.length) % enabled.length;
1789
+ setActive(enabled[next]);
1724
1790
  };
1725
1791
  const onListKeyDown = (e) => {
1726
1792
  if (e.key === "ArrowDown") {
@@ -1729,13 +1795,13 @@ function Menu({ trigger, items, align = "end", className }) {
1729
1795
  } else if (e.key === "ArrowUp") {
1730
1796
  e.preventDefault();
1731
1797
  step(-1);
1732
- } else if (e.key === "Home") {
1798
+ } else if (e.key === "Home" && !search) {
1733
1799
  e.preventDefault();
1734
- setActive(enabled[0] ?? 0);
1735
- } else if (e.key === "End") {
1800
+ setActive(enabled[0] ?? -1);
1801
+ } else if (e.key === "End" && !search) {
1736
1802
  e.preventDefault();
1737
- setActive(enabled[enabled.length - 1] ?? 0);
1738
- } else if (e.key === "Enter" || e.key === " ") {
1803
+ setActive(enabled[enabled.length - 1] ?? -1);
1804
+ } else if (e.key === "Enter" || e.key === " " && !search) {
1739
1805
  e.preventDefault();
1740
1806
  choose(active);
1741
1807
  } else if (e.key === "Escape") {
@@ -1743,6 +1809,14 @@ function Menu({ trigger, items, align = "end", className }) {
1743
1809
  close();
1744
1810
  } else if (e.key === "Tab") setOpen(false);
1745
1811
  };
1812
+ const onQuery = (value) => {
1813
+ setQuery(value);
1814
+ const first = visibleEntries(items, value).find((i) => {
1815
+ const e = items[i];
1816
+ return isItem(e) && !e.disabled;
1817
+ });
1818
+ setActive(first ?? -1);
1819
+ };
1746
1820
  const own = trigger.props;
1747
1821
  const wired = (0, import_react17.cloneElement)(trigger, {
1748
1822
  "aria-haspopup": "menu",
@@ -1751,56 +1825,103 @@ function Menu({ trigger, items, align = "end", className }) {
1751
1825
  onClick: (e) => {
1752
1826
  own.onClick?.(e);
1753
1827
  if (open) setOpen(false);
1754
- else openAt(enabled[0] ?? 0);
1828
+ else openAt("first");
1755
1829
  },
1756
1830
  onKeyDown: (e) => {
1757
1831
  own.onKeyDown?.(e);
1758
1832
  if (!open && (e.key === "ArrowDown" || e.key === "Enter" || e.key === " ")) {
1759
1833
  e.preventDefault();
1760
- openAt(enabled[0] ?? 0);
1834
+ openAt("first");
1761
1835
  } else if (!open && e.key === "ArrowUp") {
1762
1836
  e.preventDefault();
1763
- openAt(enabled[enabled.length - 1] ?? 0);
1837
+ openAt("last");
1764
1838
  }
1765
1839
  }
1766
1840
  });
1767
- return /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)("div", { ref: rootRef, className: ["fds-menu", className].filter(Boolean).join(" "), children: [
1768
- wired,
1769
- open && /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
1770
- "div",
1771
- {
1772
- ref: listRef,
1773
- id: listId,
1774
- role: "menu",
1775
- tabIndex: -1,
1776
- className: `fds-menu__list fds-menu__list--${align}`,
1777
- "aria-activedescendant": `${listId}-item-${active}`,
1778
- onKeyDown: onListKeyDown,
1779
- children: items.map((it, i) => /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)(
1780
- "div",
1781
- {
1782
- id: `${listId}-item-${i}`,
1783
- role: "menuitem",
1784
- "aria-disabled": it.disabled || void 0,
1785
- className: [
1786
- "fds-menu__item",
1787
- it.tone === "danger" ? "fds-menu__item--danger" : "",
1788
- i === active ? "fds-menu__item--active" : "",
1789
- it.disabled ? "fds-menu__item--disabled" : ""
1790
- ].filter(Boolean).join(" "),
1791
- onMouseEnter: () => !it.disabled && setActive(i),
1792
- onMouseDown: (e) => e.preventDefault(),
1793
- onClick: () => choose(i),
1794
- children: [
1795
- it.icon != null && /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("span", { className: "fds-menu__icon", "aria-hidden": "true", children: it.icon }),
1796
- it.label
1797
- ]
1798
- },
1799
- i
1800
- ))
1801
- }
1802
- )
1803
- ] });
1841
+ const listClasses = [
1842
+ "fds-menu__list",
1843
+ `fds-menu__list--${placement}`,
1844
+ placement === "right" ? "" : `fds-menu__list--${align}`,
1845
+ width === "wide" ? "fds-menu__list--wide" : ""
1846
+ ].filter(Boolean).join(" ");
1847
+ return /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)(
1848
+ "div",
1849
+ {
1850
+ ref: rootRef,
1851
+ className: ["fds-menu", block ? "fds-menu--block" : "", className].filter(Boolean).join(" "),
1852
+ children: [
1853
+ wired,
1854
+ open && /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)("div", { className: listClasses, onKeyDown: onListKeyDown, children: [
1855
+ search && /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)("div", { className: "fds-menu__search", children: [
1856
+ /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(import_lucide_react.Search, { "aria-hidden": "true" }),
1857
+ /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
1858
+ "input",
1859
+ {
1860
+ ref: searchRef,
1861
+ type: "text",
1862
+ value: query,
1863
+ placeholder: search.placeholder,
1864
+ disabled: search.disabled,
1865
+ "aria-label": search.placeholder,
1866
+ "aria-controls": listId,
1867
+ "aria-activedescendant": active >= 0 ? `${listId}-item-${active}` : void 0,
1868
+ onChange: (e) => onQuery(e.target.value)
1869
+ }
1870
+ )
1871
+ ] }),
1872
+ /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)(
1873
+ "div",
1874
+ {
1875
+ ref: listRef,
1876
+ id: listId,
1877
+ role: "menu",
1878
+ tabIndex: -1,
1879
+ className: "fds-menu__items",
1880
+ "aria-activedescendant": (!search || search.disabled) && active >= 0 ? `${listId}-item-${active}` : void 0,
1881
+ children: [
1882
+ shown.length === 0 && search && /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("div", { className: "fds-menu__empty", children: search.emptyLabel }),
1883
+ shown.map((i) => {
1884
+ const e = items[i];
1885
+ if (!isItem(e)) {
1886
+ return e.type === "label" ? /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("div", { className: "fds-menu__label", role: "presentation", children: e.label }, i) : /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("div", { className: "fds-menu__divider", role: "separator" }, i);
1887
+ }
1888
+ return /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)(
1889
+ "div",
1890
+ {
1891
+ id: `${listId}-item-${i}`,
1892
+ role: "menuitem",
1893
+ "aria-disabled": e.disabled || void 0,
1894
+ "aria-current": e.selected || void 0,
1895
+ className: [
1896
+ "fds-menu__item",
1897
+ e.tone === "danger" ? "fds-menu__item--danger" : "",
1898
+ i === active ? "fds-menu__item--active" : "",
1899
+ e.disabled ? "fds-menu__item--disabled" : ""
1900
+ ].filter(Boolean).join(" "),
1901
+ onMouseEnter: () => !e.disabled && setActive(i),
1902
+ onMouseDown: (ev) => ev.preventDefault(),
1903
+ onClick: () => choose(i),
1904
+ children: [
1905
+ e.avatar != null && /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("span", { className: "fds-menu__avatar", "aria-hidden": "true", children: e.avatar }),
1906
+ e.icon != null && /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("span", { className: "fds-menu__icon", "aria-hidden": "true", children: e.icon }),
1907
+ /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)("span", { className: "fds-menu__text", children: [
1908
+ /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("span", { className: "fds-menu__title", children: e.label }),
1909
+ e.description != null && /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("span", { className: "fds-menu__description", children: e.description })
1910
+ ] }),
1911
+ e.trailing != null && /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("span", { className: "fds-menu__trailing", children: e.trailing }),
1912
+ e.selected && /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(import_lucide_react.Check, { className: "fds-menu__check", "aria-hidden": "true" })
1913
+ ]
1914
+ },
1915
+ i
1916
+ );
1917
+ })
1918
+ ]
1919
+ }
1920
+ )
1921
+ ] })
1922
+ ]
1923
+ }
1924
+ );
1804
1925
  }
1805
1926
 
1806
1927
  // src/components/Table/Table.tsx
@@ -1869,12 +1990,391 @@ function PricingCard({
1869
1990
  ] })
1870
1991
  ] });
1871
1992
  }
1993
+
1994
+ // src/components/StatusDot/StatusDot.tsx
1995
+ var import_jsx_runtime37 = require("react/jsx-runtime");
1996
+ function StatusDot({ status, label, className, ...rest }) {
1997
+ return /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
1998
+ "span",
1999
+ {
2000
+ className: ["fds-status-dot", `fds-status-dot--${status}`, className].filter(Boolean).join(" "),
2001
+ role: label ? "img" : void 0,
2002
+ "aria-label": label,
2003
+ "aria-hidden": label ? void 0 : true,
2004
+ ...rest
2005
+ }
2006
+ );
2007
+ }
2008
+
2009
+ // src/components/ListLabel/ListLabel.tsx
2010
+ var import_jsx_runtime38 = require("react/jsx-runtime");
2011
+ function ListLabel({ className, children, ...rest }) {
2012
+ return /* @__PURE__ */ (0, import_jsx_runtime38.jsx)("div", { className: ["fds-list-label", className].filter(Boolean).join(" "), ...rest, children });
2013
+ }
2014
+
2015
+ // src/components/Divider/Divider.tsx
2016
+ var import_jsx_runtime39 = require("react/jsx-runtime");
2017
+ function Divider({ orientation = "horizontal", className, ...rest }) {
2018
+ return /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(
2019
+ "hr",
2020
+ {
2021
+ className: ["fds-divider", `fds-divider--${orientation}`, className].filter(Boolean).join(" "),
2022
+ "aria-orientation": orientation,
2023
+ ...rest
2024
+ }
2025
+ );
2026
+ }
2027
+
2028
+ // src/components/Tooltip/Tooltip.tsx
2029
+ var import_react18 = require("react");
2030
+ var import_react_dom2 = require("react-dom");
2031
+ var import_jsx_runtime40 = require("react/jsx-runtime");
2032
+ var GAP = 8;
2033
+ function place(rect, side) {
2034
+ switch (side) {
2035
+ case "right":
2036
+ return { top: rect.top + rect.height / 2, left: rect.right + GAP };
2037
+ case "left":
2038
+ return { top: rect.top + rect.height / 2, left: rect.left - GAP };
2039
+ case "top":
2040
+ return { top: rect.top - GAP, left: rect.left + rect.width / 2 };
2041
+ case "bottom":
2042
+ return { top: rect.bottom + GAP, left: rect.left + rect.width / 2 };
2043
+ }
2044
+ }
2045
+ function Tooltip({ content, children, side = "right", delay = 400, disabled = false }) {
2046
+ const id = (0, import_react18.useId)();
2047
+ const timer = (0, import_react18.useRef)();
2048
+ const [pos, setPos] = (0, import_react18.useState)(null);
2049
+ (0, import_react18.useEffect)(() => () => window.clearTimeout(timer.current), []);
2050
+ (0, import_react18.useEffect)(() => {
2051
+ if (disabled) setPos(null);
2052
+ }, [disabled]);
2053
+ const show = (el, wait) => {
2054
+ window.clearTimeout(timer.current);
2055
+ timer.current = window.setTimeout(() => setPos(place(el.getBoundingClientRect(), side)), wait);
2056
+ };
2057
+ const hide = () => {
2058
+ window.clearTimeout(timer.current);
2059
+ setPos(null);
2060
+ };
2061
+ if (disabled) return children;
2062
+ const own = children.props;
2063
+ const trigger = (0, import_react18.cloneElement)(children, {
2064
+ "aria-describedby": pos ? id : own["aria-describedby"],
2065
+ onMouseEnter: (e) => {
2066
+ own.onMouseEnter?.(e);
2067
+ show(e.currentTarget, delay);
2068
+ },
2069
+ onMouseLeave: (e) => {
2070
+ own.onMouseLeave?.(e);
2071
+ hide();
2072
+ },
2073
+ onFocus: (e) => {
2074
+ own.onFocus?.(e);
2075
+ if (e.currentTarget.matches(":focus-visible")) show(e.currentTarget, 0);
2076
+ },
2077
+ onBlur: (e) => {
2078
+ own.onBlur?.(e);
2079
+ hide();
2080
+ }
2081
+ });
2082
+ return /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)(import_jsx_runtime40.Fragment, { children: [
2083
+ trigger,
2084
+ pos && (0, import_react_dom2.createPortal)(
2085
+ /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(
2086
+ "div",
2087
+ {
2088
+ id,
2089
+ role: "tooltip",
2090
+ className: `fds-tooltip fds-tooltip--${side}`,
2091
+ style: { top: pos.top, left: pos.left },
2092
+ children: content
2093
+ }
2094
+ ),
2095
+ document.body
2096
+ )
2097
+ ] });
2098
+ }
2099
+
2100
+ // src/components/BrandButton/BrandButton.tsx
2101
+ var import_lucide_react2 = require("lucide-react");
2102
+ var import_jsx_runtime41 = require("react/jsx-runtime");
2103
+ function BrandButton({ mark, hoverIcon, type = "button", className, ...rest }) {
2104
+ return /* @__PURE__ */ (0, import_jsx_runtime41.jsxs)("button", { type, className: ["fds-brand-button", className].filter(Boolean).join(" "), ...rest, children: [
2105
+ /* @__PURE__ */ (0, import_jsx_runtime41.jsx)("span", { className: "fds-brand-button__mark", "aria-hidden": "true", children: mark }),
2106
+ /* @__PURE__ */ (0, import_jsx_runtime41.jsx)("span", { className: "fds-brand-button__hover", "aria-hidden": "true", children: hoverIcon ?? /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(import_lucide_react2.PanelLeftOpen, {}) })
2107
+ ] });
2108
+ }
2109
+
2110
+ // src/components/Sidebar/SidebarContext.ts
2111
+ var import_react19 = require("react");
2112
+ var SidebarContext = (0, import_react19.createContext)(null);
2113
+ function useSidebar() {
2114
+ return (0, import_react19.useContext)(SidebarContext);
2115
+ }
2116
+
2117
+ // src/components/SidebarItem/SidebarItem.tsx
2118
+ var import_jsx_runtime42 = require("react/jsx-runtime");
2119
+ function SidebarItem({
2120
+ as,
2121
+ icon,
2122
+ leading,
2123
+ active = false,
2124
+ iconOnly,
2125
+ className,
2126
+ children,
2127
+ ...rest
2128
+ }) {
2129
+ const sidebar = useSidebar();
2130
+ const compact = iconOnly ?? sidebar?.collapsed ?? false;
2131
+ const Component = as ?? "a";
2132
+ const classes = [
2133
+ "fds-sidebar-item",
2134
+ active ? "fds-sidebar-item--active" : "",
2135
+ compact ? "fds-sidebar-item--icon-only" : "",
2136
+ className
2137
+ ].filter(Boolean).join(" ");
2138
+ return /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(Tooltip, { content: children, disabled: !compact, children: /* @__PURE__ */ (0, import_jsx_runtime42.jsxs)(Component, { className: classes, "aria-current": active ? "page" : void 0, ...rest, children: [
2139
+ (leading ?? icon) != null && /* @__PURE__ */ (0, import_jsx_runtime42.jsx)("span", { className: leading != null ? "fds-sidebar-item__leading" : "fds-sidebar-item__icon", "aria-hidden": "true", children: leading ?? icon }),
2140
+ /* @__PURE__ */ (0, import_jsx_runtime42.jsx)("span", { className: "fds-sidebar-item__label", children })
2141
+ ] }) });
2142
+ }
2143
+
2144
+ // src/components/Sidebar/Sidebar.tsx
2145
+ var import_react20 = require("react");
2146
+ var import_lucide_react3 = require("lucide-react");
2147
+ var import_jsx_runtime43 = require("react/jsx-runtime");
2148
+ function SidebarRoot({
2149
+ collapsed: controlled,
2150
+ defaultCollapsed = false,
2151
+ onCollapsedChange,
2152
+ shortcut = true,
2153
+ className,
2154
+ children,
2155
+ "aria-label": ariaLabel = "Main",
2156
+ ...rest
2157
+ }) {
2158
+ const [own, setOwn] = (0, import_react20.useState)(defaultCollapsed);
2159
+ const collapsed = controlled ?? own;
2160
+ const setCollapsed = (0, import_react20.useCallback)(
2161
+ (next) => {
2162
+ if (controlled === void 0) setOwn(next);
2163
+ onCollapsedChange?.(next);
2164
+ },
2165
+ [controlled, onCollapsedChange]
2166
+ );
2167
+ const toggle = (0, import_react20.useCallback)(() => setCollapsed(!collapsed), [collapsed, setCollapsed]);
2168
+ (0, import_react20.useEffect)(() => {
2169
+ if (!shortcut) return;
2170
+ const onKey = (e) => {
2171
+ if ((e.metaKey || e.ctrlKey) && e.key === "\\") {
2172
+ e.preventDefault();
2173
+ toggle();
2174
+ }
2175
+ };
2176
+ window.addEventListener("keydown", onKey);
2177
+ return () => window.removeEventListener("keydown", onKey);
2178
+ }, [shortcut, toggle]);
2179
+ const state = (0, import_react20.useMemo)(() => ({ collapsed, setCollapsed, toggle }), [collapsed, setCollapsed, toggle]);
2180
+ return /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(SidebarContext.Provider, { value: state, children: /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(
2181
+ "nav",
2182
+ {
2183
+ className: ["fds-sidebar", collapsed ? "fds-sidebar--collapsed" : "", className].filter(Boolean).join(" "),
2184
+ "aria-label": ariaLabel,
2185
+ "data-collapsed": collapsed || void 0,
2186
+ ...rest,
2187
+ children
2188
+ }
2189
+ ) });
2190
+ }
2191
+ function useInert(on) {
2192
+ const ref = (0, import_react20.useRef)(null);
2193
+ (0, import_react20.useEffect)(() => {
2194
+ if (ref.current) ref.current.inert = on;
2195
+ }, [on]);
2196
+ return ref;
2197
+ }
2198
+ function SidebarBrand({
2199
+ logo,
2200
+ mark,
2201
+ collapseLabel = "Collapse sidebar",
2202
+ expandLabel = "Expand sidebar"
2203
+ }) {
2204
+ const sidebar = useSidebar();
2205
+ const collapsed = sidebar?.collapsed ?? false;
2206
+ const collapseRef = useInert(collapsed);
2207
+ const expandRef = useInert(!collapsed);
2208
+ return /* @__PURE__ */ (0, import_jsx_runtime43.jsxs)("div", { className: "fds-sidebar__brand", children: [
2209
+ /* @__PURE__ */ (0, import_jsx_runtime43.jsx)("span", { className: "fds-sidebar__logo", "aria-hidden": collapsed || void 0, children: logo }),
2210
+ /* @__PURE__ */ (0, import_jsx_runtime43.jsx)("span", { ref: collapseRef, className: "fds-sidebar__collapse", children: /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(Tooltip, { content: collapseLabel, side: "bottom", children: /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(
2211
+ IconButton,
2212
+ {
2213
+ variant: "ghost",
2214
+ size: "small",
2215
+ icon: /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(import_lucide_react3.PanelLeftClose, {}),
2216
+ "aria-label": collapseLabel,
2217
+ "aria-keyshortcuts": "Meta+Backslash Control+Backslash",
2218
+ onClick: () => sidebar?.setCollapsed(true)
2219
+ }
2220
+ ) }) }),
2221
+ /* @__PURE__ */ (0, import_jsx_runtime43.jsx)("span", { ref: expandRef, className: "fds-sidebar__expand", children: /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(Tooltip, { content: expandLabel, children: /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(BrandButton, { mark, "aria-label": expandLabel, onClick: () => sidebar?.setCollapsed(false) }) }) })
2222
+ ] });
2223
+ }
2224
+ function SidebarAction({ icon, label, type = "button", className, ...rest }) {
2225
+ const sidebar = useSidebar();
2226
+ const collapsed = sidebar?.collapsed ?? false;
2227
+ return /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(Tooltip, { content: label, disabled: !collapsed, children: /* @__PURE__ */ (0, import_jsx_runtime43.jsxs)(
2228
+ "button",
2229
+ {
2230
+ type,
2231
+ className: ["fds-sidebar__action", className].filter(Boolean).join(" "),
2232
+ "aria-label": collapsed ? label : void 0,
2233
+ ...rest,
2234
+ children: [
2235
+ /* @__PURE__ */ (0, import_jsx_runtime43.jsx)("span", { className: "fds-sidebar__action-icon", "aria-hidden": "true", children: icon }),
2236
+ /* @__PURE__ */ (0, import_jsx_runtime43.jsx)("span", { className: "fds-sidebar__action-label", children: label })
2237
+ ]
2238
+ }
2239
+ ) });
2240
+ }
2241
+ function SidebarSection({ hideWhenCollapsed = false, className, children, ...rest }) {
2242
+ const sidebar = useSidebar();
2243
+ const hidden = hideWhenCollapsed && (sidebar?.collapsed ?? false);
2244
+ const ref = useInert(hidden);
2245
+ return /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(
2246
+ "div",
2247
+ {
2248
+ ref,
2249
+ className: ["fds-sidebar__section", hidden ? "fds-sidebar__section--hidden" : "", className].filter(Boolean).join(" "),
2250
+ "aria-hidden": hidden || void 0,
2251
+ ...rest,
2252
+ children
2253
+ }
2254
+ );
2255
+ }
2256
+ function SidebarHeader({ className, children, ...rest }) {
2257
+ return /* @__PURE__ */ (0, import_jsx_runtime43.jsx)("div", { className: ["fds-sidebar__header", className].filter(Boolean).join(" "), ...rest, children });
2258
+ }
2259
+ function SidebarFooter({ className, children, ...rest }) {
2260
+ return /* @__PURE__ */ (0, import_jsx_runtime43.jsx)("div", { className: ["fds-sidebar__footer", className].filter(Boolean).join(" "), ...rest, children });
2261
+ }
2262
+ var Sidebar = Object.assign(SidebarRoot, {
2263
+ Header: SidebarHeader,
2264
+ Brand: SidebarBrand,
2265
+ Action: SidebarAction,
2266
+ Section: SidebarSection,
2267
+ Item: SidebarItem,
2268
+ Footer: SidebarFooter
2269
+ });
2270
+
2271
+ // src/components/WorkspaceSwitcher/WorkspaceSwitcher.tsx
2272
+ var import_react21 = require("react");
2273
+ var import_lucide_react4 = require("lucide-react");
2274
+ var import_jsx_runtime44 = require("react/jsx-runtime");
2275
+ function WorkspaceAvatar({ name }) {
2276
+ return /* @__PURE__ */ (0, import_jsx_runtime44.jsx)("span", { className: "fds-workspace-avatar", "aria-hidden": "true", children: name.trim().charAt(0).toUpperCase() || "?" });
2277
+ }
2278
+ var WorkspaceSwitcher = (0, import_react21.forwardRef)(function WorkspaceSwitcher2({ name, plan, avatar, compact, type = "button", className, ...rest }, ref) {
2279
+ const sidebar = useSidebar();
2280
+ const iconOnly = compact ?? sidebar?.collapsed ?? false;
2281
+ return /* @__PURE__ */ (0, import_jsx_runtime44.jsxs)(
2282
+ "button",
2283
+ {
2284
+ ref,
2285
+ type,
2286
+ className: ["fds-workspace-switcher", iconOnly ? "fds-workspace-switcher--compact" : "", className].filter(Boolean).join(" "),
2287
+ "aria-label": iconOnly ? `Workspace: ${name}` : void 0,
2288
+ ...rest,
2289
+ children: [
2290
+ avatar ?? /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(WorkspaceAvatar, { name }),
2291
+ /* @__PURE__ */ (0, import_jsx_runtime44.jsxs)("span", { className: "fds-workspace-switcher__text", "aria-hidden": iconOnly || void 0, children: [
2292
+ /* @__PURE__ */ (0, import_jsx_runtime44.jsx)("span", { className: "fds-workspace-switcher__name", children: name }),
2293
+ plan && /* @__PURE__ */ (0, import_jsx_runtime44.jsx)("span", { className: "fds-workspace-switcher__plan", children: plan }),
2294
+ /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(import_lucide_react4.ChevronDown, { className: "fds-workspace-switcher__chevron", "aria-hidden": "true" })
2295
+ ] })
2296
+ ]
2297
+ }
2298
+ );
2299
+ });
2300
+
2301
+ // src/components/AvatarLabelGroup/AvatarLabelGroup.tsx
2302
+ var import_react22 = require("react");
2303
+ var import_jsx_runtime45 = require("react/jsx-runtime");
2304
+ var AvatarLabelGroup = (0, import_react22.forwardRef)(function AvatarLabelGroup2({ name, detail, src, compact = false, type = "button", className, ...rest }, ref) {
2305
+ return /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)(
2306
+ "button",
2307
+ {
2308
+ ref,
2309
+ type,
2310
+ className: ["fds-avatar-label-group", compact ? "fds-avatar-label-group--compact" : "", className].filter(Boolean).join(" "),
2311
+ "aria-label": compact ? name : void 0,
2312
+ ...rest,
2313
+ children: [
2314
+ /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(Avatar, { name, src, size: "small" }),
2315
+ /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)("span", { className: "fds-avatar-label-group__text", "aria-hidden": compact || void 0, children: [
2316
+ /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("span", { className: "fds-avatar-label-group__name", children: name }),
2317
+ detail && /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("span", { className: "fds-avatar-label-group__detail", children: detail })
2318
+ ] })
2319
+ ]
2320
+ }
2321
+ );
2322
+ });
2323
+
2324
+ // src/components/AppLayout/AppLayout.tsx
2325
+ var import_jsx_runtime46 = require("react/jsx-runtime");
2326
+ function AppLayoutRoot({ className, children, ...rest }) {
2327
+ return /* @__PURE__ */ (0, import_jsx_runtime46.jsx)("div", { className: ["fds-app-layout", className].filter(Boolean).join(" "), ...rest, children });
2328
+ }
2329
+ function AppLayoutPanel({ className, children, ...rest }) {
2330
+ return /* @__PURE__ */ (0, import_jsx_runtime46.jsx)("main", { className: ["fds-app-layout__panel", className].filter(Boolean).join(" "), ...rest, children });
2331
+ }
2332
+ var AppLayout = Object.assign(AppLayoutRoot, { Panel: AppLayoutPanel });
2333
+
2334
+ // src/components/PageHeader/PageHeader.tsx
2335
+ var import_jsx_runtime47 = require("react/jsx-runtime");
2336
+ function PageHeader({ title, description, breadcrumb, actions, className, children, ...rest }) {
2337
+ return /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)("header", { className: ["fds-page-header", className].filter(Boolean).join(" "), ...rest, children: [
2338
+ /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)("div", { className: "fds-page-header__row", children: [
2339
+ /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)("div", { className: "fds-page-header__text", children: [
2340
+ breadcrumb != null && /* @__PURE__ */ (0, import_jsx_runtime47.jsx)("div", { className: "fds-page-header__breadcrumb", children: breadcrumb }),
2341
+ /* @__PURE__ */ (0, import_jsx_runtime47.jsx)("h1", { className: "fds-page-header__title", children: title }),
2342
+ description != null && /* @__PURE__ */ (0, import_jsx_runtime47.jsx)("p", { className: "fds-page-header__description", children: description })
2343
+ ] }),
2344
+ actions != null && /* @__PURE__ */ (0, import_jsx_runtime47.jsx)("div", { className: "fds-page-header__actions", children: actions })
2345
+ ] }),
2346
+ children
2347
+ ] });
2348
+ }
2349
+
2350
+ // src/components/Toast/Toast.tsx
2351
+ var import_react23 = require("react");
2352
+ var import_lucide_react5 = require("lucide-react");
2353
+ var import_jsx_runtime48 = require("react/jsx-runtime");
2354
+ function ToastRegion({ className, children, ...rest }) {
2355
+ return /* @__PURE__ */ (0, import_jsx_runtime48.jsx)("div", { className: ["fds-toast-region", className].filter(Boolean).join(" "), "aria-live": "polite", ...rest, children });
2356
+ }
2357
+ function Toast({ children, action, onDismiss, duration, className, ...rest }) {
2358
+ (0, import_react23.useEffect)(() => {
2359
+ if (!duration || !onDismiss) return;
2360
+ const t = window.setTimeout(onDismiss, duration);
2361
+ return () => window.clearTimeout(t);
2362
+ }, [duration, onDismiss]);
2363
+ return /* @__PURE__ */ (0, import_jsx_runtime48.jsxs)("div", { role: "status", className: ["fds-toast", className].filter(Boolean).join(" "), ...rest, children: [
2364
+ /* @__PURE__ */ (0, import_jsx_runtime48.jsx)("span", { className: "fds-toast__message", children }),
2365
+ action && /* @__PURE__ */ (0, import_jsx_runtime48.jsx)("button", { type: "button", className: "fds-toast__action", onClick: action.onClick, children: action.label }),
2366
+ onDismiss && /* @__PURE__ */ (0, import_jsx_runtime48.jsx)("button", { type: "button", className: "fds-toast__close", "aria-label": "Dismiss", onClick: onDismiss, children: /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(import_lucide_react5.X, { "aria-hidden": "true" }) })
2367
+ ] });
2368
+ }
1872
2369
  // Annotate the CommonJS export names for ESM import in node:
1873
2370
  0 && (module.exports = {
1874
2371
  Accordion,
2372
+ AppLayout,
1875
2373
  AppNav,
1876
2374
  Avatar,
2375
+ AvatarLabelGroup,
1877
2376
  Badge,
2377
+ BrandButton,
1878
2378
  Button,
1879
2379
  ButtonLink,
1880
2380
  Callout,
@@ -1882,13 +2382,16 @@ function PricingCard({
1882
2382
  Checkbox,
1883
2383
  DiffPropertyList,
1884
2384
  DiffSection,
2385
+ Divider,
1885
2386
  EmptyState,
1886
2387
  IconButton,
1887
2388
  Input,
2389
+ ListLabel,
1888
2390
  Menu,
1889
2391
  MismatchCard,
1890
2392
  Modal,
1891
2393
  MultiSelect,
2394
+ PageHeader,
1892
2395
  Pagination,
1893
2396
  PricingCard,
1894
2397
  Radio,
@@ -1898,17 +2401,26 @@ function PricingCard({
1898
2401
  SegmentedControl,
1899
2402
  Select,
1900
2403
  SettingsSection,
2404
+ Sidebar,
2405
+ SidebarItem,
1901
2406
  Skeleton,
1902
2407
  SkeletonGroup,
1903
2408
  Spinner,
1904
2409
  Split,
1905
2410
  StackedCardsIllustration,
1906
2411
  Stat,
2412
+ StatusDot,
1907
2413
  StepList,
1908
2414
  Swatch,
1909
2415
  TabNav,
1910
2416
  Table,
1911
2417
  Tag,
2418
+ Toast,
2419
+ ToastRegion,
1912
2420
  Toggle,
1913
- breakpoints
2421
+ Tooltip,
2422
+ WorkspaceAvatar,
2423
+ WorkspaceSwitcher,
2424
+ breakpoints,
2425
+ useSidebar
1914
2426
  });