@usefidel/design-system 0.24.0 → 0.25.1

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