achery-ui 0.1.0 → 0.5.2

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
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- var chunkSSWJ4EPA_cjs = require('./chunk-SSWJ4EPA.cjs');
3
+ var chunkLJ24EJ3N_cjs = require('./chunk-LJ24EJ3N.cjs');
4
4
  var react = require('react');
5
5
  var jsxRuntime = require('react/jsx-runtime');
6
6
  var createRuntimeFn = require('@vanilla-extract/recipes/createRuntimeFn');
@@ -9,6 +9,8 @@ var RadixTabs = require('@radix-ui/react-tabs');
9
9
  var RadixTooltip = require('@radix-ui/react-tooltip');
10
10
  var RadixDialog = require('@radix-ui/react-dialog');
11
11
  var reactDom = require('react-dom');
12
+ var RadixCheckbox = require('@radix-ui/react-checkbox');
13
+ var RadixDropdownMenu = require('@radix-ui/react-dropdown-menu');
12
14
 
13
15
  function _interopNamespace(e) {
14
16
  if (e && e.__esModule) return e;
@@ -32,23 +34,61 @@ var RadixToggle__namespace = /*#__PURE__*/_interopNamespace(RadixToggle);
32
34
  var RadixTabs__namespace = /*#__PURE__*/_interopNamespace(RadixTabs);
33
35
  var RadixTooltip__namespace = /*#__PURE__*/_interopNamespace(RadixTooltip);
34
36
  var RadixDialog__namespace = /*#__PURE__*/_interopNamespace(RadixDialog);
37
+ var RadixCheckbox__namespace = /*#__PURE__*/_interopNamespace(RadixCheckbox);
38
+ var RadixDropdownMenu__namespace = /*#__PURE__*/_interopNamespace(RadixDropdownMenu);
35
39
 
40
+ var STORAGE_KEY = "achery-theme-mode";
36
41
  var ThemeContext = react.createContext(null);
42
+ function getSystemTheme() {
43
+ if (typeof window === "undefined") return "light";
44
+ return window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light";
45
+ }
46
+ function resolveTheme(mode) {
47
+ return mode === "system" ? getSystemTheme() : mode;
48
+ }
49
+ function readStoredMode(fallback) {
50
+ try {
51
+ const stored = localStorage.getItem(STORAGE_KEY);
52
+ if (stored === "light" || stored === "dark" || stored === "system") return stored;
53
+ } catch {
54
+ }
55
+ return fallback;
56
+ }
37
57
  function AcheryProvider({
38
58
  children,
39
- defaultTheme = "light",
59
+ defaultTheme = "system",
40
60
  defaultAccent = "terracotta",
41
61
  className,
42
62
  style
43
63
  }) {
44
- const [theme, setThemeState] = react.useState(defaultTheme);
64
+ const [mode, setModeState] = react.useState(() => readStoredMode(defaultTheme));
45
65
  const [accent, setAccentState] = react.useState(defaultAccent);
46
- const setTheme = (next) => setThemeState(next);
47
- const toggleTheme = () => setThemeState((t) => t === "light" ? "dark" : "light");
48
- const setAccent = (next) => setAccentState(next);
66
+ const [resolvedTheme, setResolvedTheme] = react.useState(() => resolveTheme(readStoredMode(defaultTheme)));
67
+ const setTheme = react.useCallback((next) => {
68
+ setModeState(next);
69
+ setResolvedTheme(resolveTheme(next));
70
+ try {
71
+ localStorage.setItem(STORAGE_KEY, next);
72
+ } catch {
73
+ }
74
+ }, []);
75
+ const toggleTheme = react.useCallback(() => {
76
+ setTheme(resolvedTheme === "light" ? "dark" : "light");
77
+ }, [resolvedTheme, setTheme]);
78
+ const setAccent = react.useCallback((next) => setAccentState(next), []);
79
+ react.useEffect(() => {
80
+ if (mode !== "system") return;
81
+ const mq = window.matchMedia("(prefers-color-scheme: dark)");
82
+ const handler = (e) => {
83
+ setResolvedTheme(e.matches ? "dark" : "light");
84
+ };
85
+ mq.addEventListener("change", handler);
86
+ setResolvedTheme(mq.matches ? "dark" : "light");
87
+ return () => mq.removeEventListener("change", handler);
88
+ }, [mode]);
49
89
  react.useEffect(() => {
50
90
  const html = document.documentElement;
51
- html.dataset["theme"] = theme;
91
+ html.dataset["theme"] = resolvedTheme;
52
92
  html.dataset["accent"] = accent;
53
93
  html.dataset["acheryRoot"] = "";
54
94
  return () => {
@@ -56,12 +96,12 @@ function AcheryProvider({
56
96
  delete html.dataset["accent"];
57
97
  delete html.dataset["acheryRoot"];
58
98
  };
59
- }, [theme, accent]);
60
- return /* @__PURE__ */ jsxRuntime.jsx(ThemeContext.Provider, { value: { theme, setTheme, toggleTheme, accent, setAccent }, children: /* @__PURE__ */ jsxRuntime.jsx(
99
+ }, [resolvedTheme, accent]);
100
+ return /* @__PURE__ */ jsxRuntime.jsx(ThemeContext.Provider, { value: { mode, theme: resolvedTheme, setTheme, toggleTheme, accent, setAccent }, children: /* @__PURE__ */ jsxRuntime.jsx(
61
101
  "div",
62
102
  {
63
103
  "data-achery-root": "",
64
- "data-theme": theme,
104
+ "data-theme": resolvedTheme,
65
105
  "data-accent": accent,
66
106
  className,
67
107
  style,
@@ -286,6 +326,13 @@ function Wordmark(props) {
286
326
  /* @__PURE__ */ jsxRuntime.jsx("g", { transform: "translate(82,72)", fontFamily: "'Space Grotesk', sansSerif", fontWeight: "600", fontSize: "10", letterSpacing: "6", stroke: "none", children: /* @__PURE__ */ jsxRuntime.jsx("text", { x: "2", y: "0", children: "\u2014 W O R K S H O P \u2014" }) })
287
327
  ] });
288
328
  }
329
+ function Menu(props) {
330
+ return /* @__PURE__ */ jsxRuntime.jsxs("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "1.8", strokeLinecap: "round", ...props, children: [
331
+ /* @__PURE__ */ jsxRuntime.jsx("line", { x1: "3", y1: "7", x2: "21", y2: "7" }),
332
+ /* @__PURE__ */ jsxRuntime.jsx("line", { x1: "3", y1: "12", x2: "21", y2: "12" }),
333
+ /* @__PURE__ */ jsxRuntime.jsx("line", { x1: "3", y1: "17", x2: "21", y2: "17" })
334
+ ] });
335
+ }
289
336
  var glyphMap = {
290
337
  "arrow-right": ArrowRight,
291
338
  "arrow-up": ArrowUp,
@@ -304,6 +351,7 @@ var glyphMap = {
304
351
  "key": Key,
305
352
  "leaf": Leaf,
306
353
  "mark": Mark,
354
+ "menu": Menu,
307
355
  "mercury": Mercury,
308
356
  "minus": Minus,
309
357
  "moon": Moon,
@@ -457,7 +505,7 @@ function Toggle({
457
505
  defaultPressed,
458
506
  onPressedChange,
459
507
  disabled,
460
- label: label3,
508
+ label: label4,
461
509
  className,
462
510
  "aria-label": ariaLabel
463
511
  }) {
@@ -474,7 +522,7 @@ function Toggle({
474
522
  children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: thumb })
475
523
  }
476
524
  ),
477
- label3 && /* @__PURE__ */ jsxRuntime.jsx("span", { className: label, children: label3 })
525
+ label4 && /* @__PURE__ */ jsxRuntime.jsx("span", { className: label, children: label4 })
478
526
  ] });
479
527
  }
480
528
 
@@ -511,9 +559,9 @@ var searchInput = "Input_searchInput__6w3tiea Input_inputBase__6w3tie4";
511
559
  var searchWrapper = "Input_searchWrapper__6w3tie8";
512
560
  var selectInput = "Input_selectInput__6w3tie7 Input_inputBase__6w3tie4";
513
561
  var textarea = "Input_textarea__6w3tie6 Input_inputBase__6w3tie4";
514
- function Field({ label: label3, hint: hint2, error, children, className }) {
562
+ function Field({ label: label4, hint: hint2, error, children, className }) {
515
563
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: [fieldRoot, className].filter(Boolean).join(" "), children: [
516
- label3 && /* @__PURE__ */ jsxRuntime.jsx("label", { className: label2, children: label3 }),
564
+ label4 && /* @__PURE__ */ jsxRuntime.jsx("label", { className: label2, children: label4 }),
517
565
  children,
518
566
  error && /* @__PURE__ */ jsxRuntime.jsx("span", { className: errorText, children: error }),
519
567
  !error && hint2 && /* @__PURE__ */ jsxRuntime.jsx("span", { className: hint, children: hint2 })
@@ -590,34 +638,34 @@ function Card({
590
638
  var tab = "Tabs_tab__1b0xj9v1";
591
639
  var tabList = "Tabs_tabList__1b0xj9v0";
592
640
  var tabPanel = "Tabs_tabPanel__1b0xj9v2";
593
- function Tabs({ items, value, defaultValue, onValueChange, className }) {
641
+ function Tabs({ items, value: value2, defaultValue, onValueChange, className }) {
594
642
  const resolvedDefault = defaultValue ?? items[0]?.value;
595
643
  return /* @__PURE__ */ jsxRuntime.jsxs(
596
644
  RadixTabs__namespace.Root,
597
645
  {
598
- ...value !== void 0 ? { value } : {},
646
+ ...value2 !== void 0 ? { value: value2 } : {},
599
647
  ...resolvedDefault != null ? { defaultValue: resolvedDefault } : {},
600
648
  ...onValueChange !== void 0 ? { onValueChange } : {},
601
649
  ...className !== void 0 ? { className } : {},
602
650
  children: [
603
- /* @__PURE__ */ jsxRuntime.jsx(RadixTabs__namespace.List, { className: tabList, children: items.map((item) => /* @__PURE__ */ jsxRuntime.jsx(
651
+ /* @__PURE__ */ jsxRuntime.jsx(RadixTabs__namespace.List, { className: tabList, children: items.map((item2) => /* @__PURE__ */ jsxRuntime.jsx(
604
652
  RadixTabs__namespace.Trigger,
605
653
  {
606
- value: item.value,
607
- disabled: item.disabled,
654
+ value: item2.value,
655
+ disabled: item2.disabled,
608
656
  className: tab,
609
- children: item.label
657
+ children: item2.label
610
658
  },
611
- item.value
659
+ item2.value
612
660
  )) }),
613
- items.map((item) => /* @__PURE__ */ jsxRuntime.jsx(
661
+ items.map((item2) => /* @__PURE__ */ jsxRuntime.jsx(
614
662
  RadixTabs__namespace.Content,
615
663
  {
616
- value: item.value,
664
+ value: item2.value,
617
665
  className: tabPanel,
618
- children: item.content
666
+ children: item2.content
619
667
  },
620
- item.value
668
+ item2.value
621
669
  ))
622
670
  ]
623
671
  }
@@ -658,71 +706,167 @@ function Tooltip({
658
706
  }
659
707
 
660
708
  // src/components/Sidebar/Sidebar.css.ts
661
- var footer = "Sidebar_footer__1n0xxfc5";
662
- var group = "Sidebar_group__1n0xxfc1";
663
- var groupLabel = "Sidebar_groupLabel__1n0xxfc2";
664
- var navItem = "Sidebar_navItem__1n0xxfc3";
665
- var navItemCount = "Sidebar_navItemCount__1n0xxfc4";
709
+ var backdrop = "Sidebar_backdrop__1n0xxfc2";
710
+ var collapseToggle = "Sidebar_collapseToggle__1n0xxfc3";
711
+ var countAccent = "Sidebar_countAccent__1n0xxfc9";
712
+ var footer = "Sidebar_footer__1n0xxfc8";
713
+ var group = "Sidebar_group__1n0xxfc4";
714
+ var groupLabel = "Sidebar_groupLabel__1n0xxfc5";
715
+ var navItem = "Sidebar_navItem__1n0xxfc6";
716
+ var navItemCount = "Sidebar_navItemCount__1n0xxfc7";
666
717
  var sidebar = "Sidebar_sidebar__1n0xxfc0";
667
- function Sidebar({ groups, activeId, onItemClick, footer: footer3, className }) {
668
- return /* @__PURE__ */ jsxRuntime.jsxs("nav", { className: [sidebar, className].filter(Boolean).join(" "), children: [
669
- groups.map((group2, i) => /* @__PURE__ */ jsxRuntime.jsx(
670
- NavGroup,
671
- {
672
- label: group2.label,
673
- items: group2.items,
674
- activeId,
675
- onItemClick
676
- },
677
- i
678
- )),
679
- footer3 && /* @__PURE__ */ jsxRuntime.jsx("div", { className: footer, children: footer3 })
680
- ] });
718
+ var sidebarMobile = "Sidebar_sidebarMobile__1n0xxfc1";
719
+ function Sidebar({
720
+ groups,
721
+ activeId,
722
+ onItemClick,
723
+ renderLink,
724
+ footer: footer3,
725
+ collapsed,
726
+ onCollapsedChange,
727
+ mobileOpen,
728
+ onMobileOpenChange,
729
+ className
730
+ }) {
731
+ const isMobileMode = mobileOpen !== void 0;
732
+ const nav = /* @__PURE__ */ jsxRuntime.jsxs(
733
+ "nav",
734
+ {
735
+ className: [
736
+ sidebar,
737
+ isMobileMode ? sidebarMobile : void 0,
738
+ className
739
+ ].filter(Boolean).join(" "),
740
+ "data-collapsed": collapsed ?? false,
741
+ "data-mobile-open": isMobileMode ? String(mobileOpen) : void 0,
742
+ children: [
743
+ /* @__PURE__ */ jsxRuntime.jsx(
744
+ "button",
745
+ {
746
+ className: collapseToggle,
747
+ onClick: () => onCollapsedChange?.(!collapsed),
748
+ "aria-label": collapsed ? "Expand sidebar" : "Collapse sidebar",
749
+ title: collapsed ? "Expand" : "Collapse",
750
+ children: collapsed ? "\u203A" : "\u2039"
751
+ }
752
+ ),
753
+ groups.map((group2, i) => /* @__PURE__ */ jsxRuntime.jsx(
754
+ NavGroup,
755
+ {
756
+ label: group2.label,
757
+ items: group2.items,
758
+ activeId,
759
+ onItemClick,
760
+ renderLink,
761
+ collapsed: collapsed ?? false
762
+ },
763
+ i
764
+ )),
765
+ footer3 && /* @__PURE__ */ jsxRuntime.jsx("div", { className: footer, children: footer3 })
766
+ ]
767
+ }
768
+ );
769
+ if (isMobileMode) {
770
+ return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
771
+ mobileOpen && /* @__PURE__ */ jsxRuntime.jsx(
772
+ "div",
773
+ {
774
+ className: backdrop,
775
+ onClick: () => onMobileOpenChange?.(false),
776
+ "aria-hidden": "true"
777
+ }
778
+ ),
779
+ nav
780
+ ] });
781
+ }
782
+ return nav;
681
783
  }
682
- function NavGroup({ label: label3, items, activeId, onItemClick }) {
784
+ function NavGroup({ label: label4, items, activeId, onItemClick, renderLink, collapsed }) {
683
785
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: group, children: [
684
- label3 && /* @__PURE__ */ jsxRuntime.jsx("span", { className: groupLabel, children: label3 }),
685
- items.map((item) => /* @__PURE__ */ jsxRuntime.jsx(
786
+ label4 && !collapsed && /* @__PURE__ */ jsxRuntime.jsx("span", { className: groupLabel, children: label4 }),
787
+ items.map((item2) => /* @__PURE__ */ jsxRuntime.jsx(
686
788
  NavItem,
687
789
  {
688
- item,
689
- active: item.id === activeId,
690
- onClick: () => onItemClick?.(item.id)
790
+ item: item2,
791
+ active: item2.id === activeId,
792
+ onClick: () => onItemClick?.(item2.id),
793
+ renderLink,
794
+ collapsed
691
795
  },
692
- item.id
796
+ item2.id
693
797
  ))
694
798
  ] });
695
799
  }
696
- function NavItem({ item, active, onClick }) {
800
+ function NavItem({ item: item2, active, onClick, renderLink, collapsed }) {
697
801
  const glyphStyle = active ? { filter: "invert(1)" } : void 0;
698
- if (item.href) {
699
- return /* @__PURE__ */ jsxRuntime.jsxs(
700
- "a",
802
+ const content3 = /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
803
+ item2.glyph ? /* @__PURE__ */ jsxRuntime.jsx(Glyph, { name: item2.glyph, size: 14, style: glyphStyle, "aria-hidden": "true" }) : /* @__PURE__ */ jsxRuntime.jsx("span", {}),
804
+ !collapsed && /* @__PURE__ */ jsxRuntime.jsx("span", { children: item2.label }),
805
+ !collapsed && item2.count !== void 0 && /* @__PURE__ */ jsxRuntime.jsx("span", { className: item2.countTone === "accent" ? countAccent : navItemCount, children: item2.count })
806
+ ] });
807
+ const titleProp = collapsed ? { title: item2.label } : {};
808
+ if (item2.href) {
809
+ const LinkComponent = renderLink ?? "a";
810
+ return /* @__PURE__ */ jsxRuntime.jsx(
811
+ LinkComponent,
701
812
  {
702
- href: item.href,
813
+ href: item2.href,
703
814
  className: navItem,
704
815
  "data-active": active,
705
816
  "aria-current": active ? "page" : void 0,
706
- children: [
707
- item.glyph ? /* @__PURE__ */ jsxRuntime.jsx(Glyph, { name: item.glyph, size: 14, style: glyphStyle, "aria-hidden": "true" }) : /* @__PURE__ */ jsxRuntime.jsx("span", {}),
708
- /* @__PURE__ */ jsxRuntime.jsx("span", { children: item.label }),
709
- item.count !== void 0 && /* @__PURE__ */ jsxRuntime.jsx("span", { className: navItemCount, children: item.count })
710
- ]
817
+ ...titleProp,
818
+ children: content3
711
819
  }
712
820
  );
713
821
  }
714
- return /* @__PURE__ */ jsxRuntime.jsxs(
822
+ return /* @__PURE__ */ jsxRuntime.jsx(
715
823
  "button",
716
824
  {
717
825
  className: navItem,
718
826
  "data-active": active,
719
827
  onClick,
720
828
  "aria-current": active ? "page" : void 0,
721
- children: [
722
- item.glyph ? /* @__PURE__ */ jsxRuntime.jsx(Glyph, { name: item.glyph, size: 14, style: glyphStyle, "aria-hidden": "true" }) : /* @__PURE__ */ jsxRuntime.jsx("span", {}),
723
- /* @__PURE__ */ jsxRuntime.jsx("span", { children: item.label }),
724
- item.count !== void 0 && /* @__PURE__ */ jsxRuntime.jsx("span", { className: navItemCount, children: item.count })
725
- ]
829
+ ...titleProp,
830
+ children: content3
831
+ }
832
+ );
833
+ }
834
+
835
+ // src/components/ProgressBar/ProgressBar.css.ts
836
+ var fill = "ProgressBar_fill__1686i1k3";
837
+ var fillTone = { neutral: "ProgressBar_fillTone_neutral__1686i1k4", accent: "ProgressBar_fillTone_accent__1686i1k5" };
838
+ var track2 = "ProgressBar_track__1686i1k0";
839
+ var trackSize = { sm: "ProgressBar_trackSize_sm__1686i1k1", md: "ProgressBar_trackSize_md__1686i1k2" };
840
+ function ProgressBar({ value: value2, size = "md", tone = "neutral", className }) {
841
+ const pct = Math.min(100, Math.max(0, value2));
842
+ return /* @__PURE__ */ jsxRuntime.jsx(
843
+ "div",
844
+ {
845
+ className: [track2, trackSize[size], className].filter(Boolean).join(" "),
846
+ role: "progressbar",
847
+ "aria-valuenow": pct,
848
+ "aria-valuemin": 0,
849
+ "aria-valuemax": 100,
850
+ children: /* @__PURE__ */ jsxRuntime.jsx(
851
+ "div",
852
+ {
853
+ className: [fill, fillTone[tone]].join(" "),
854
+ style: { width: `${pct}%` }
855
+ }
856
+ )
857
+ }
858
+ );
859
+ }
860
+ var avatar = createRuntimeFn.createRuntimeFn({ defaultClassName: "Avatar_avatar__16f6qlf0", variantClassNames: { size: { sm: "Avatar_avatar_size_sm__16f6qlf1", md: "Avatar_avatar_size_md__16f6qlf2", lg: "Avatar_avatar_size_lg__16f6qlf3" }, tone: { moss: "Avatar_avatar_tone_moss__16f6qlf4", neutral: "Avatar_avatar_tone_neutral__16f6qlf5" } }, defaultVariants: { size: "md", tone: "neutral" }, compoundVariants: [] });
861
+ var initials = "Avatar_initials__16f6qlf6";
862
+ function Avatar({ initials: initials2, size = "md", tone = "neutral", className }) {
863
+ const display2 = initials2.slice(0, 2).toUpperCase();
864
+ return /* @__PURE__ */ jsxRuntime.jsx(
865
+ "span",
866
+ {
867
+ className: [avatar({ size, tone }), className].filter(Boolean).join(" "),
868
+ "aria-label": `User: ${display2}`,
869
+ children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: initials, children: display2 })
726
870
  }
727
871
  );
728
872
  }
@@ -732,7 +876,6 @@ var accentPicker = "AppBar_accentPicker__uqki999";
732
876
  var accentSwatch = "AppBar_accentSwatch__uqki99a";
733
877
  var actions = "AppBar_actions__uqki998";
734
878
  var appBar = "AppBar_appBar__uqki990";
735
- var avatar = "AppBar_avatar__uqki99b";
736
879
  var brand = "AppBar_brand__uqki991";
737
880
  var brandDivider = "AppBar_brandDivider__uqki993";
738
881
  var brandName = "AppBar_brandName__uqki992";
@@ -753,9 +896,22 @@ function AppBar({
753
896
  isDark,
754
897
  avatarInitials,
755
898
  onNewClick,
899
+ onMenuClick,
900
+ onSearch,
901
+ onSearchFocus,
756
902
  className
757
903
  }) {
758
904
  return /* @__PURE__ */ jsxRuntime.jsxs("header", { className: [appBar, className].filter(Boolean).join(" "), children: [
905
+ onMenuClick && /* @__PURE__ */ jsxRuntime.jsx(
906
+ Button,
907
+ {
908
+ variant: "ghost",
909
+ size: "sm",
910
+ glyph: "menu",
911
+ onClick: onMenuClick,
912
+ "aria-label": "Open navigation menu"
913
+ }
914
+ ),
759
915
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: brand, children: [
760
916
  /* @__PURE__ */ jsxRuntime.jsx(Glyph, { name: "hex", size: 20, "aria-hidden": "true" }),
761
917
  /* @__PURE__ */ jsxRuntime.jsx("span", { className: brandName, children: brandName2 }),
@@ -772,13 +928,17 @@ function AppBar({
772
928
  type: "search",
773
929
  placeholder: searchPlaceholder,
774
930
  className: searchInput2,
775
- "aria-label": "Search"
931
+ "aria-label": "Search",
932
+ onFocus: () => onSearchFocus?.(),
933
+ onKeyDown: (e) => {
934
+ if (e.key === "Enter") onSearch?.(e.target.value);
935
+ }
776
936
  }
777
937
  ),
778
938
  searchKbd2 && /* @__PURE__ */ jsxRuntime.jsx("span", { className: searchKbd, children: searchKbd2 })
779
939
  ] }),
780
940
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: actions, children: [
781
- onAccentChange && /* @__PURE__ */ jsxRuntime.jsx("div", { className: accentPicker, role: "group", "aria-label": "Brand colour", children: chunkSSWJ4EPA_cjs.accentColorNames.map((name) => /* @__PURE__ */ jsxRuntime.jsx(
941
+ onAccentChange && /* @__PURE__ */ jsxRuntime.jsx("div", { className: accentPicker, role: "group", "aria-label": "Brand colour", children: chunkLJ24EJ3N_cjs.accentColorNames.map((name) => /* @__PURE__ */ jsxRuntime.jsx(
782
942
  "button",
783
943
  {
784
944
  className: accentSwatch,
@@ -786,7 +946,7 @@ function AppBar({
786
946
  onClick: () => onAccentChange(name),
787
947
  "aria-label": name,
788
948
  "aria-pressed": name === accent,
789
- style: { background: chunkSSWJ4EPA_cjs.accentColors[name].main }
949
+ style: { background: chunkLJ24EJ3N_cjs.accentColors[name].main }
790
950
  },
791
951
  name
792
952
  )) }),
@@ -802,12 +962,14 @@ function AppBar({
802
962
  ),
803
963
  onNewClick && /* @__PURE__ */ jsxRuntime.jsx(Button, { variant: "accent", size: "sm", glyph: "plus", onClick: onNewClick, children: "New" }),
804
964
  actions2,
805
- avatarInitials && /* @__PURE__ */ jsxRuntime.jsx("div", { className: avatar, "aria-label": `User: ${avatarInitials}`, children: avatarInitials.slice(0, 2).toUpperCase() })
965
+ avatarInitials && /* @__PURE__ */ jsxRuntime.jsx(Avatar, { initials: avatarInitials, size: "sm", tone: "neutral" })
806
966
  ] })
807
967
  ] });
808
968
  }
809
969
 
810
970
  // src/components/Table/Table.css.ts
971
+ var emptyState = "Table_emptyState__1a2tbysa";
972
+ var pagination = "Table_pagination__1a2tbysb";
811
973
  var sortIndicator = "Table_sortIndicator__1a2tbys5";
812
974
  var table = "Table_table__1a2tbys1";
813
975
  var tableWrapper = "Table_tableWrapper__1a2tbys0";
@@ -816,6 +978,7 @@ var tdMono = "Table_tdMono__1a2tbys8 Table_td__1a2tbys7";
816
978
  var th = "Table_th__1a2tbys3";
817
979
  var thSortable = "Table_thSortable__1a2tbys4 Table_th__1a2tbys3";
818
980
  var thead = "Table_thead__1a2tbys2";
981
+ var toolbar = "Table_toolbar__1a2tbys9";
819
982
  var tr = "Table_tr__1a2tbys6";
820
983
  function Table({
821
984
  columns,
@@ -828,6 +991,12 @@ function Table({
828
991
  defaultSortKey,
829
992
  defaultSortDir = null,
830
993
  onSortChange,
994
+ pageIndex = 0,
995
+ pageSize,
996
+ totalRows,
997
+ onPageChange,
998
+ toolbar: toolbar2,
999
+ emptyState: emptyState2,
831
1000
  className
832
1001
  }) {
833
1002
  const [internalSortKey, setInternalSortKey] = react.useState(defaultSortKey ?? null);
@@ -858,43 +1027,79 @@ function Table({
858
1027
  return activeSortDir === "asc" ? cmp : -cmp;
859
1028
  });
860
1029
  }, [data, activeSortKey, activeSortDir]);
861
- return /* @__PURE__ */ jsxRuntime.jsx("div", { className: [tableWrapper, className].filter(Boolean).join(" "), children: /* @__PURE__ */ jsxRuntime.jsxs("table", { className: table, children: [
862
- /* @__PURE__ */ jsxRuntime.jsx("thead", { className: thead, children: /* @__PURE__ */ jsxRuntime.jsx("tr", { children: columns.map((col) => /* @__PURE__ */ jsxRuntime.jsxs(
863
- "th",
864
- {
865
- className: col.sortable ? thSortable : th,
866
- style: col.width ? { width: col.width } : void 0,
867
- onClick: col.sortable ? () => handleSort(col.key) : void 0,
868
- "aria-sort": activeSortKey === col.key ? activeSortDir === "asc" ? "ascending" : "descending" : void 0,
869
- children: [
870
- col.label,
871
- col.sortable && activeSortKey === col.key && activeSortDir && /* @__PURE__ */ jsxRuntime.jsx("span", { className: sortIndicator, "aria-hidden": "true", children: /* @__PURE__ */ jsxRuntime.jsx(Glyph, { name: activeSortDir === "asc" ? "arrow-up" : "arrow-right", size: 10 }) })
872
- ]
873
- },
874
- col.key
875
- )) }) }),
876
- /* @__PURE__ */ jsxRuntime.jsx("tbody", { children: sortedData.map((row) => {
877
- const key = rowKey(row);
878
- const isSelected = selectedKeys?.includes(key) ?? false;
879
- return /* @__PURE__ */ jsxRuntime.jsx(
880
- "tr",
1030
+ const totalPages = pageSize && totalRows ? Math.ceil(totalRows / pageSize) : null;
1031
+ const isFirstPage = pageIndex === 0;
1032
+ const isLastPage = totalPages !== null ? pageIndex >= totalPages - 1 : true;
1033
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: [tableWrapper, className].filter(Boolean).join(" "), children: [
1034
+ toolbar2 && /* @__PURE__ */ jsxRuntime.jsx("div", { className: toolbar, children: toolbar2 }),
1035
+ /* @__PURE__ */ jsxRuntime.jsxs("table", { className: table, children: [
1036
+ /* @__PURE__ */ jsxRuntime.jsx("thead", { className: thead, children: /* @__PURE__ */ jsxRuntime.jsx("tr", { children: columns.map((col) => /* @__PURE__ */ jsxRuntime.jsxs(
1037
+ "th",
881
1038
  {
882
- className: tr,
883
- "data-selected": isSelected,
884
- onClick: onRowClick ? () => onRowClick(key, row) : void 0,
885
- style: onRowClick ? { cursor: "pointer" } : void 0,
886
- children: columns.map((col) => /* @__PURE__ */ jsxRuntime.jsx("td", { className: col.mono ? tdMono : td, children: col.render ? col.render(row) : String(row[col.key] ?? "") }, col.key))
1039
+ className: col.sortable ? thSortable : th,
1040
+ style: col.width ? { width: col.width } : void 0,
1041
+ onClick: col.sortable ? () => handleSort(col.key) : void 0,
1042
+ "aria-sort": activeSortKey === col.key ? activeSortDir === "asc" ? "ascending" : "descending" : void 0,
1043
+ children: [
1044
+ col.label,
1045
+ col.sortable && activeSortKey === col.key && activeSortDir && /* @__PURE__ */ jsxRuntime.jsx("span", { className: sortIndicator, "aria-hidden": "true", children: /* @__PURE__ */ jsxRuntime.jsx(Glyph, { name: activeSortDir === "asc" ? "arrow-up" : "arrow-right", size: 10 }) })
1046
+ ]
887
1047
  },
888
- key
889
- );
890
- }) })
891
- ] }) });
1048
+ col.key
1049
+ )) }) }),
1050
+ /* @__PURE__ */ jsxRuntime.jsx("tbody", { children: data.length === 0 ? /* @__PURE__ */ jsxRuntime.jsx("tr", { children: /* @__PURE__ */ jsxRuntime.jsx("td", { colSpan: columns.length, children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: emptyState, children: emptyState2 ?? "No data." }) }) }) : sortedData.map((row) => {
1051
+ const key = rowKey(row);
1052
+ const isSelected = selectedKeys?.includes(key) ?? false;
1053
+ return /* @__PURE__ */ jsxRuntime.jsx(
1054
+ "tr",
1055
+ {
1056
+ className: tr,
1057
+ "data-selected": isSelected,
1058
+ onClick: onRowClick ? () => onRowClick(key, row) : void 0,
1059
+ style: onRowClick ? { cursor: "pointer" } : void 0,
1060
+ children: columns.map((col) => /* @__PURE__ */ jsxRuntime.jsx("td", { className: col.mono ? tdMono : td, children: col.render ? col.render(row) : String(row[col.key] ?? "") }, col.key))
1061
+ },
1062
+ key
1063
+ );
1064
+ }) })
1065
+ ] }),
1066
+ pageSize && totalPages !== null && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: pagination, children: [
1067
+ /* @__PURE__ */ jsxRuntime.jsx(
1068
+ Button,
1069
+ {
1070
+ variant: "ghost",
1071
+ size: "sm",
1072
+ glyph: "arrow-right",
1073
+ onClick: () => onPageChange?.(pageIndex - 1),
1074
+ disabled: isFirstPage,
1075
+ "aria-label": "Previous page",
1076
+ style: { transform: "rotate(180deg)" }
1077
+ }
1078
+ ),
1079
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { children: [
1080
+ "Page ",
1081
+ pageIndex + 1,
1082
+ " of ",
1083
+ totalPages
1084
+ ] }),
1085
+ /* @__PURE__ */ jsxRuntime.jsx(
1086
+ Button,
1087
+ {
1088
+ variant: "ghost",
1089
+ size: "sm",
1090
+ glyph: "arrow-right",
1091
+ onClick: () => onPageChange?.(pageIndex + 1),
1092
+ disabled: isLastPage,
1093
+ "aria-label": "Next page"
1094
+ }
1095
+ )
1096
+ ] })
1097
+ ] });
892
1098
  }
893
-
894
- // src/components/Modal/Modal.css.ts
895
1099
  var body2 = "Modal_body__1kcb5si8";
1100
+ var bodyScrollable = "Modal_bodyScrollable__1kcb5sie";
896
1101
  var closeButton = "Modal_closeButton__1kcb5si7";
897
- var content2 = "Modal_content__1kcb5si3";
1102
+ var contentSized = createRuntimeFn.createRuntimeFn({ defaultClassName: "Modal_contentSized__1kcb5sia", variantClassNames: { size: { sm: "Modal_contentSized_size_sm__1kcb5sib", md: "Modal_contentSized_size_md__1kcb5sic", lg: "Modal_contentSized_size_lg__1kcb5sid" } }, defaultVariants: { size: "sm" }, compoundVariants: [] });
898
1103
  var description = "Modal_description__1kcb5si6";
899
1104
  var footer2 = "Modal_footer__1kcb5si9";
900
1105
  var header = "Modal_header__1kcb5si4";
@@ -908,7 +1113,9 @@ function Modal({
908
1113
  description: description2,
909
1114
  children,
910
1115
  footer: footer3,
911
- trigger,
1116
+ trigger: trigger2,
1117
+ size = "sm",
1118
+ scrollable = false,
912
1119
  className
913
1120
  }) {
914
1121
  return /* @__PURE__ */ jsxRuntime.jsxs(
@@ -918,13 +1125,13 @@ function Modal({
918
1125
  ...defaultOpen !== void 0 ? { defaultOpen } : {},
919
1126
  ...onOpenChange !== void 0 ? { onOpenChange } : {},
920
1127
  children: [
921
- trigger && /* @__PURE__ */ jsxRuntime.jsx(RadixDialog__namespace.Trigger, { asChild: true, children: trigger }),
1128
+ trigger2 && /* @__PURE__ */ jsxRuntime.jsx(RadixDialog__namespace.Trigger, { asChild: true, children: trigger2 }),
922
1129
  /* @__PURE__ */ jsxRuntime.jsxs(RadixDialog__namespace.Portal, { children: [
923
1130
  /* @__PURE__ */ jsxRuntime.jsx(RadixDialog__namespace.Overlay, { className: overlay }),
924
1131
  /* @__PURE__ */ jsxRuntime.jsxs(
925
1132
  RadixDialog__namespace.Content,
926
1133
  {
927
- className: [content2, className].filter(Boolean).join(" "),
1134
+ className: [contentSized({ size }), className].filter(Boolean).join(" "),
928
1135
  "aria-describedby": description2 ? "modal-description" : void 0,
929
1136
  children: [
930
1137
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: header, children: [
@@ -934,7 +1141,7 @@ function Modal({
934
1141
  ] }),
935
1142
  /* @__PURE__ */ jsxRuntime.jsx(RadixDialog__namespace.Close, { className: closeButton, "aria-label": "Close", children: /* @__PURE__ */ jsxRuntime.jsx(Glyph, { name: "cross", size: 14, "aria-hidden": "true" }) })
936
1143
  ] }),
937
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: body2, children }),
1144
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: scrollable ? bodyScrollable : body2, children }),
938
1145
  footer3 && /* @__PURE__ */ jsxRuntime.jsx("div", { className: footer2, children: footer3 })
939
1146
  ]
940
1147
  }
@@ -995,30 +1202,621 @@ function ToastProvider({ children }) {
995
1202
  ] });
996
1203
  }
997
1204
 
1205
+ // src/components/Checkbox/Checkbox.css.ts
1206
+ var indicator = "Checkbox_indicator__nnmycq2";
1207
+ var label3 = "Checkbox_label__nnmycq3";
1208
+ var root = "Checkbox_root__nnmycq1";
1209
+ var wrapper2 = "Checkbox_wrapper__nnmycq0";
1210
+ function Checkbox({
1211
+ checked,
1212
+ defaultChecked,
1213
+ onChange,
1214
+ disabled,
1215
+ label: label4,
1216
+ id,
1217
+ className,
1218
+ "aria-label": ariaLabel
1219
+ }) {
1220
+ const resolvedId = id ?? (label4 ? `checkbox-${Math.random().toString(36).slice(2, 7)}` : void 0);
1221
+ return /* @__PURE__ */ jsxRuntime.jsxs("span", { className: [wrapper2, className].filter(Boolean).join(" "), "data-disabled": disabled || void 0, children: [
1222
+ /* @__PURE__ */ jsxRuntime.jsx(
1223
+ RadixCheckbox__namespace.Root,
1224
+ {
1225
+ ...checked !== void 0 ? { checked } : {},
1226
+ ...defaultChecked !== void 0 ? { defaultChecked } : {},
1227
+ ...onChange !== void 0 ? { onCheckedChange: onChange } : {},
1228
+ ...disabled !== void 0 ? { disabled } : {},
1229
+ ...ariaLabel !== void 0 ? { "aria-label": ariaLabel } : {},
1230
+ ...resolvedId !== void 0 ? { id: resolvedId } : {},
1231
+ className: root,
1232
+ children: /* @__PURE__ */ jsxRuntime.jsx(RadixCheckbox__namespace.Indicator, { className: indicator, children: checked === "indeterminate" ? /* @__PURE__ */ jsxRuntime.jsx("svg", { width: "10", height: "2", viewBox: "0 0 10 2", fill: "currentColor", children: /* @__PURE__ */ jsxRuntime.jsx("rect", { width: "10", height: "2", rx: "1" }) }) : /* @__PURE__ */ jsxRuntime.jsx("svg", { width: "10", height: "8", viewBox: "0 0 10 8", fill: "none", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round", children: /* @__PURE__ */ jsxRuntime.jsx("polyline", { points: "1,4 4,7 9,1" }) }) })
1233
+ }
1234
+ ),
1235
+ label4 && /* @__PURE__ */ jsxRuntime.jsx("label", { htmlFor: resolvedId, className: label3, style: { cursor: disabled ? "not-allowed" : "pointer" }, children: label4 })
1236
+ ] });
1237
+ }
1238
+
1239
+ // src/components/Menu/Menu.css.ts
1240
+ var content2 = "Menu_content__wszp3g0";
1241
+ var item = "Menu_item__wszp3g1";
1242
+ var itemDanger = "Menu_itemDanger__wszp3g2";
1243
+ var itemGlyph = "Menu_itemGlyph__wszp3g4";
1244
+ var separator = "Menu_separator__wszp3g3";
1245
+ function Menu2({ trigger: trigger2, items, side = "bottom", align = "end", className }) {
1246
+ return /* @__PURE__ */ jsxRuntime.jsxs(RadixDropdownMenu__namespace.Root, { children: [
1247
+ /* @__PURE__ */ jsxRuntime.jsx(RadixDropdownMenu__namespace.Trigger, { asChild: true, children: trigger2 }),
1248
+ /* @__PURE__ */ jsxRuntime.jsx(RadixDropdownMenu__namespace.Portal, { children: /* @__PURE__ */ jsxRuntime.jsx(
1249
+ RadixDropdownMenu__namespace.Content,
1250
+ {
1251
+ side,
1252
+ align,
1253
+ sideOffset: 6,
1254
+ className: [content2, className].filter(Boolean).join(" "),
1255
+ children: items.map((item2) => {
1256
+ if ("type" in item2 && item2.type === "separator") {
1257
+ return /* @__PURE__ */ jsxRuntime.jsx(RadixDropdownMenu__namespace.Separator, { className: separator }, item2.id);
1258
+ }
1259
+ const def = item2;
1260
+ return /* @__PURE__ */ jsxRuntime.jsxs(
1261
+ RadixDropdownMenu__namespace.Item,
1262
+ {
1263
+ ...def.disabled !== void 0 ? { disabled: def.disabled } : {},
1264
+ onSelect: def.onSelect,
1265
+ className: [item, def.danger ? itemDanger : ""].filter(Boolean).join(" "),
1266
+ children: [
1267
+ def.glyph && /* @__PURE__ */ jsxRuntime.jsx(Glyph, { name: def.glyph, size: 14, className: itemGlyph }),
1268
+ def.label
1269
+ ]
1270
+ },
1271
+ def.id
1272
+ );
1273
+ })
1274
+ }
1275
+ ) })
1276
+ ] });
1277
+ }
1278
+
1279
+ // src/components/DatePicker/DatePicker.css.ts
1280
+ var input = "DatePicker_input__1etdrw70";
1281
+ function DatePicker({
1282
+ type = "date",
1283
+ value: value2,
1284
+ onChange,
1285
+ min,
1286
+ max,
1287
+ disabled,
1288
+ error,
1289
+ placeholder,
1290
+ className,
1291
+ ...rest
1292
+ }) {
1293
+ return /* @__PURE__ */ jsxRuntime.jsx(
1294
+ "input",
1295
+ {
1296
+ type,
1297
+ value: value2,
1298
+ onChange,
1299
+ min,
1300
+ max,
1301
+ disabled,
1302
+ placeholder,
1303
+ "data-error": error || void 0,
1304
+ className: [input, className].filter(Boolean).join(" "),
1305
+ ...rest
1306
+ }
1307
+ );
1308
+ }
1309
+
1310
+ // src/components/Combobox/Combobox.css.ts
1311
+ var chip = "Combobox_chip__1irfr5o2";
1312
+ var chipRemove = "Combobox_chipRemove__1irfr5o3";
1313
+ var input2 = "Combobox_input__1irfr5o4";
1314
+ var option = "Combobox_option__1irfr5o7";
1315
+ var optionCheck = "Combobox_optionCheck__1irfr5o8";
1316
+ var popover = "Combobox_popover__1irfr5o6";
1317
+ var trigger = "Combobox_trigger__1irfr5o1";
1318
+ var wrapper3 = "Combobox_wrapper__1irfr5o0";
1319
+ function Combobox({
1320
+ value: value2,
1321
+ onChange,
1322
+ options = [],
1323
+ allowCustom = false,
1324
+ placeholder,
1325
+ disabled,
1326
+ error,
1327
+ className
1328
+ }) {
1329
+ const [inputValue, setInputValue] = react.useState("");
1330
+ const [open, setOpen] = react.useState(false);
1331
+ const [activeIndex, setActiveIndex] = react.useState(-1);
1332
+ const inputRef = react.useRef(null);
1333
+ const id = react.useId();
1334
+ const filteredOptions = options.filter((opt) => {
1335
+ const lower = inputValue.toLowerCase();
1336
+ return opt.toLowerCase().includes(lower) && !value2.includes(opt);
1337
+ });
1338
+ const customOption = allowCustom && inputValue.trim() && !options.includes(inputValue.trim()) && !value2.includes(inputValue.trim()) ? inputValue.trim() : null;
1339
+ const visibleOptions = [...filteredOptions, ...customOption ? [customOption] : []];
1340
+ const showDropdown = open && visibleOptions.length > 0;
1341
+ function addValue(v) {
1342
+ const trimmed = v.trim();
1343
+ if (trimmed && !value2.includes(trimmed)) {
1344
+ onChange([...value2, trimmed]);
1345
+ }
1346
+ setInputValue("");
1347
+ setActiveIndex(-1);
1348
+ }
1349
+ function removeValue(v) {
1350
+ onChange(value2.filter((x) => x !== v));
1351
+ }
1352
+ function handleKeyDown(e) {
1353
+ if ((e.key === "Enter" || e.key === ",") && inputValue.trim()) {
1354
+ e.preventDefault();
1355
+ const active = activeIndex >= 0 ? visibleOptions[activeIndex] : void 0;
1356
+ if (active) {
1357
+ addValue(active);
1358
+ } else if (allowCustom) {
1359
+ addValue(inputValue);
1360
+ } else if (filteredOptions[0]) {
1361
+ addValue(filteredOptions[0]);
1362
+ }
1363
+ return;
1364
+ }
1365
+ if (e.key === "Backspace" && !inputValue && value2.length > 0) {
1366
+ const last = value2[value2.length - 1];
1367
+ if (last) removeValue(last);
1368
+ return;
1369
+ }
1370
+ if (e.key === "ArrowDown") {
1371
+ e.preventDefault();
1372
+ setActiveIndex((i) => Math.min(i + 1, visibleOptions.length - 1));
1373
+ return;
1374
+ }
1375
+ if (e.key === "ArrowUp") {
1376
+ e.preventDefault();
1377
+ setActiveIndex((i) => Math.max(i - 1, -1));
1378
+ return;
1379
+ }
1380
+ if (e.key === "Escape") {
1381
+ setOpen(false);
1382
+ setActiveIndex(-1);
1383
+ }
1384
+ }
1385
+ return /* @__PURE__ */ jsxRuntime.jsxs(
1386
+ "div",
1387
+ {
1388
+ className: [wrapper3, className].filter(Boolean).join(" "),
1389
+ onClick: () => {
1390
+ if (!disabled) inputRef.current?.focus();
1391
+ },
1392
+ children: [
1393
+ /* @__PURE__ */ jsxRuntime.jsxs(
1394
+ "div",
1395
+ {
1396
+ className: trigger,
1397
+ "data-open": showDropdown || void 0,
1398
+ "data-error": error || void 0,
1399
+ children: [
1400
+ value2.map((v) => /* @__PURE__ */ jsxRuntime.jsxs("span", { className: chip, children: [
1401
+ v,
1402
+ !disabled && /* @__PURE__ */ jsxRuntime.jsx(
1403
+ "button",
1404
+ {
1405
+ type: "button",
1406
+ className: chipRemove,
1407
+ onClick: (e) => {
1408
+ e.stopPropagation();
1409
+ removeValue(v);
1410
+ },
1411
+ "aria-label": `Remove ${v}`,
1412
+ children: "\xD7"
1413
+ }
1414
+ )
1415
+ ] }, v)),
1416
+ /* @__PURE__ */ jsxRuntime.jsx(
1417
+ "input",
1418
+ {
1419
+ ref: inputRef,
1420
+ id,
1421
+ className: input2,
1422
+ value: inputValue,
1423
+ disabled,
1424
+ placeholder: value2.length === 0 ? placeholder : void 0,
1425
+ autoComplete: "off",
1426
+ onChange: (e) => {
1427
+ setInputValue(e.target.value);
1428
+ setOpen(true);
1429
+ setActiveIndex(-1);
1430
+ },
1431
+ onFocus: () => setOpen(true),
1432
+ onBlur: () => {
1433
+ setTimeout(() => setOpen(false), 150);
1434
+ },
1435
+ onKeyDown: handleKeyDown,
1436
+ "aria-autocomplete": "list",
1437
+ "aria-expanded": showDropdown,
1438
+ "aria-controls": showDropdown ? `${id}-list` : void 0,
1439
+ "aria-activedescendant": activeIndex >= 0 ? `${id}-opt-${activeIndex}` : void 0
1440
+ }
1441
+ )
1442
+ ]
1443
+ }
1444
+ ),
1445
+ showDropdown && /* @__PURE__ */ jsxRuntime.jsx("div", { id: `${id}-list`, role: "listbox", className: popover, children: visibleOptions.map((opt, i) => {
1446
+ const isSelected = value2.includes(opt);
1447
+ const isCustom = opt === customOption;
1448
+ return /* @__PURE__ */ jsxRuntime.jsxs(
1449
+ "div",
1450
+ {
1451
+ id: `${id}-opt-${i}`,
1452
+ role: "option",
1453
+ "aria-selected": isSelected,
1454
+ className: option,
1455
+ "data-active": activeIndex === i || void 0,
1456
+ "data-selected": isSelected || void 0,
1457
+ onMouseDown: (e) => {
1458
+ e.preventDefault();
1459
+ addValue(opt);
1460
+ },
1461
+ onMouseEnter: () => setActiveIndex(i),
1462
+ children: [
1463
+ /* @__PURE__ */ jsxRuntime.jsx("span", { children: isCustom ? `Add "${opt}"` : opt }),
1464
+ isSelected && /* @__PURE__ */ jsxRuntime.jsx("span", { className: optionCheck, children: "\u2713" })
1465
+ ]
1466
+ },
1467
+ opt
1468
+ );
1469
+ }) })
1470
+ ]
1471
+ }
1472
+ );
1473
+ }
1474
+ function SingleCombobox({
1475
+ value: value2,
1476
+ onChange,
1477
+ options = [],
1478
+ allowCustom = false,
1479
+ placeholder,
1480
+ disabled,
1481
+ error,
1482
+ className
1483
+ }) {
1484
+ const [inputValue, setInputValue] = react.useState(value2 ?? "");
1485
+ const [open, setOpen] = react.useState(false);
1486
+ const [activeIndex, setActiveIndex] = react.useState(-1);
1487
+ const inputRef = react.useRef(null);
1488
+ const id = react.useId();
1489
+ const filteredOptions = options.filter(
1490
+ (opt) => opt.toLowerCase().includes(inputValue.toLowerCase())
1491
+ );
1492
+ const customOption = allowCustom && inputValue.trim() && !options.includes(inputValue.trim()) ? inputValue.trim() : null;
1493
+ const visibleOptions = [...filteredOptions, ...customOption ? [customOption] : []];
1494
+ const showDropdown = open && visibleOptions.length > 0;
1495
+ function selectValue(v) {
1496
+ onChange(v);
1497
+ setInputValue(v);
1498
+ setOpen(false);
1499
+ setActiveIndex(-1);
1500
+ }
1501
+ function handleKeyDown(e) {
1502
+ if (e.key === "Enter") {
1503
+ e.preventDefault();
1504
+ const active = activeIndex >= 0 ? visibleOptions[activeIndex] : void 0;
1505
+ if (active) {
1506
+ selectValue(active);
1507
+ } else if (allowCustom && inputValue.trim()) {
1508
+ selectValue(inputValue.trim());
1509
+ } else if (filteredOptions[0]) {
1510
+ selectValue(filteredOptions[0]);
1511
+ }
1512
+ return;
1513
+ }
1514
+ if ((e.key === "Backspace" || e.key === "Delete") && !inputValue) {
1515
+ onChange(null);
1516
+ return;
1517
+ }
1518
+ if (e.key === "ArrowDown") {
1519
+ e.preventDefault();
1520
+ setActiveIndex((i) => Math.min(i + 1, visibleOptions.length - 1));
1521
+ return;
1522
+ }
1523
+ if (e.key === "ArrowUp") {
1524
+ e.preventDefault();
1525
+ setActiveIndex((i) => Math.max(i - 1, -1));
1526
+ return;
1527
+ }
1528
+ if (e.key === "Escape") {
1529
+ setOpen(false);
1530
+ setActiveIndex(-1);
1531
+ }
1532
+ }
1533
+ return /* @__PURE__ */ jsxRuntime.jsxs(
1534
+ "div",
1535
+ {
1536
+ className: [wrapper3, className].filter(Boolean).join(" "),
1537
+ onClick: () => {
1538
+ if (!disabled) inputRef.current?.focus();
1539
+ },
1540
+ children: [
1541
+ /* @__PURE__ */ jsxRuntime.jsx(
1542
+ "div",
1543
+ {
1544
+ className: trigger,
1545
+ "data-open": showDropdown || void 0,
1546
+ "data-error": error || void 0,
1547
+ children: /* @__PURE__ */ jsxRuntime.jsx(
1548
+ "input",
1549
+ {
1550
+ ref: inputRef,
1551
+ id,
1552
+ className: input2,
1553
+ value: inputValue,
1554
+ disabled,
1555
+ placeholder,
1556
+ autoComplete: "off",
1557
+ onChange: (e) => {
1558
+ setInputValue(e.target.value);
1559
+ onChange(null);
1560
+ setOpen(true);
1561
+ setActiveIndex(-1);
1562
+ },
1563
+ onFocus: () => setOpen(true),
1564
+ onBlur: () => {
1565
+ setTimeout(() => {
1566
+ setOpen(false);
1567
+ setInputValue(value2 ?? "");
1568
+ }, 150);
1569
+ },
1570
+ onKeyDown: handleKeyDown,
1571
+ "aria-autocomplete": "list",
1572
+ "aria-expanded": showDropdown,
1573
+ "aria-controls": showDropdown ? `${id}-list` : void 0,
1574
+ "aria-activedescendant": activeIndex >= 0 ? `${id}-opt-${activeIndex}` : void 0
1575
+ }
1576
+ )
1577
+ }
1578
+ ),
1579
+ showDropdown && /* @__PURE__ */ jsxRuntime.jsx("div", { id: `${id}-list`, role: "listbox", className: popover, children: visibleOptions.map((opt, i) => {
1580
+ const isSelected = value2 === opt;
1581
+ const isCustom = opt === customOption;
1582
+ return /* @__PURE__ */ jsxRuntime.jsxs(
1583
+ "div",
1584
+ {
1585
+ id: `${id}-opt-${i}`,
1586
+ role: "option",
1587
+ "aria-selected": isSelected,
1588
+ className: option,
1589
+ "data-active": activeIndex === i || void 0,
1590
+ "data-selected": isSelected || void 0,
1591
+ onMouseDown: (e) => {
1592
+ e.preventDefault();
1593
+ selectValue(opt);
1594
+ },
1595
+ onMouseEnter: () => setActiveIndex(i),
1596
+ children: [
1597
+ /* @__PURE__ */ jsxRuntime.jsx("span", { children: isCustom ? `Add "${opt}"` : opt }),
1598
+ isSelected && /* @__PURE__ */ jsxRuntime.jsx("span", { className: optionCheck, children: "\u2713" })
1599
+ ]
1600
+ },
1601
+ opt
1602
+ );
1603
+ }) })
1604
+ ]
1605
+ }
1606
+ );
1607
+ }
1608
+ var letter = "LetterStamp_letter__dy83u5c";
1609
+ var stamp = createRuntimeFn.createRuntimeFn({ defaultClassName: "LetterStamp_stamp__dy83u50", variantClassNames: { tone: { moss: "LetterStamp_stamp_tone_moss__dy83u51", rust: "LetterStamp_stamp_tone_rust__dy83u52", ochre: "LetterStamp_stamp_tone_ochre__dy83u53", plum: "LetterStamp_stamp_tone_plum__dy83u54", copper: "LetterStamp_stamp_tone_copper__dy83u55", neutral: "LetterStamp_stamp_tone_neutral__dy83u56" }, size: { "14": "LetterStamp_stamp_size_14__dy83u57", "20": "LetterStamp_stamp_size_20__dy83u58", "28": "LetterStamp_stamp_size_28__dy83u59", "36": "LetterStamp_stamp_size_36__dy83u5a", "48": "LetterStamp_stamp_size_48__dy83u5b" } }, defaultVariants: { tone: "neutral", size: 28 }, compoundVariants: [] });
1610
+ function LetterStamp({
1611
+ letter: letter2,
1612
+ glyph: glyph2,
1613
+ size = 28,
1614
+ tone = "neutral",
1615
+ colour,
1616
+ className
1617
+ }) {
1618
+ const style = colour ? { background: colour } : {};
1619
+ return /* @__PURE__ */ jsxRuntime.jsx(
1620
+ "span",
1621
+ {
1622
+ className: [stamp({ tone, size }), className].filter(Boolean).join(" "),
1623
+ style,
1624
+ "aria-hidden": "true",
1625
+ children: glyph2 ? /* @__PURE__ */ jsxRuntime.jsx(Glyph, { name: glyph2, size: Math.round(size * 0.55) }) : letter2 ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: letter, style: { fontSize: `${Math.round(size / 2)}px` }, children: letter2.slice(0, 1).toUpperCase() }) : null
1626
+ }
1627
+ );
1628
+ }
1629
+ var labelMd = "EntityPill_labelMd__59j8ted EntityPill_label__59j8teb";
1630
+ var labelSm = "EntityPill_labelSm__59j8tec EntityPill_label__59j8teb";
1631
+ var pill = createRuntimeFn.createRuntimeFn({ defaultClassName: "EntityPill_pill__59j8te0", variantClassNames: { tone: { moss: "EntityPill_pill_tone_moss__59j8te1", rust: "EntityPill_pill_tone_rust__59j8te2", ochre: "EntityPill_pill_tone_ochre__59j8te3", plum: "EntityPill_pill_tone_plum__59j8te4", copper: "EntityPill_pill_tone_copper__59j8te5", neutral: "EntityPill_pill_tone_neutral__59j8te6" }, size: { sm: "EntityPill_pill_size_sm__59j8te7", md: "EntityPill_pill_size_md__59j8te8" }, interactive: { true: "EntityPill_pill_interactive_true__59j8te9", false: "EntityPill_pill_interactive_false__59j8tea" } }, defaultVariants: { tone: "neutral", size: "md", interactive: false }, compoundVariants: [] });
1632
+ function EntityPill({
1633
+ label: label4,
1634
+ letter: letter2,
1635
+ glyph: glyph2,
1636
+ tone = "neutral",
1637
+ colour,
1638
+ size = "md",
1639
+ onClick,
1640
+ href,
1641
+ className
1642
+ }) {
1643
+ const stampSize = size === "sm" ? 20 : 28;
1644
+ const isInteractive = Boolean(onClick || href);
1645
+ const pillClass = [
1646
+ pill({ tone, size, interactive: isInteractive }),
1647
+ className
1648
+ ].filter(Boolean).join(" ");
1649
+ const labelClass = size === "sm" ? labelSm : labelMd;
1650
+ const content3 = /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
1651
+ /* @__PURE__ */ jsxRuntime.jsx(
1652
+ LetterStamp,
1653
+ {
1654
+ ...letter2 !== void 0 ? { letter: letter2 } : {},
1655
+ ...glyph2 !== void 0 ? { glyph: glyph2 } : {},
1656
+ ...colour !== void 0 ? { colour } : {},
1657
+ tone,
1658
+ size: stampSize
1659
+ }
1660
+ ),
1661
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: labelClass, children: label4 })
1662
+ ] });
1663
+ if (href) {
1664
+ return /* @__PURE__ */ jsxRuntime.jsx("a", { href, className: pillClass, children: content3 });
1665
+ }
1666
+ if (onClick) {
1667
+ return /* @__PURE__ */ jsxRuntime.jsx("button", { type: "button", onClick, className: pillClass, children: content3 });
1668
+ }
1669
+ return /* @__PURE__ */ jsxRuntime.jsx("span", { className: pillClass, children: content3 });
1670
+ }
1671
+
1672
+ // src/components/Sparkline/Sparkline.css.ts
1673
+ var root2 = "Sparkline_root__3i35240";
1674
+ var TONE_COLORS = {
1675
+ positive: "var(--achery-color-success, #6ba03d)",
1676
+ negative: "var(--achery-color-danger, #8a3a22)",
1677
+ neutral: "var(--achery-color-accent, #c46a3a)"
1678
+ };
1679
+ function Sparkline({
1680
+ data,
1681
+ width = 80,
1682
+ height = 28,
1683
+ tone = "neutral",
1684
+ className
1685
+ }) {
1686
+ const PADDING = 2;
1687
+ if (data.length < 2) {
1688
+ return /* @__PURE__ */ jsxRuntime.jsx(
1689
+ "svg",
1690
+ {
1691
+ viewBox: `0 0 ${width} ${height}`,
1692
+ width,
1693
+ height,
1694
+ className: [root2, className].filter(Boolean).join(" "),
1695
+ "aria-hidden": "true"
1696
+ }
1697
+ );
1698
+ }
1699
+ const min = Math.min(...data);
1700
+ const max = Math.max(...data);
1701
+ const range = max - min || 1;
1702
+ const xStep = (width - PADDING * 2) / (data.length - 1);
1703
+ const yScale = (height - PADDING * 2) / range;
1704
+ const points = data.map((v, i) => {
1705
+ const x = PADDING + i * xStep;
1706
+ const y = height - PADDING - (v - min) * yScale;
1707
+ return `${x.toFixed(2)},${y.toFixed(2)}`;
1708
+ }).join(" ");
1709
+ return /* @__PURE__ */ jsxRuntime.jsx(
1710
+ "svg",
1711
+ {
1712
+ viewBox: `0 0 ${width} ${height}`,
1713
+ width,
1714
+ height,
1715
+ className: [root2, className].filter(Boolean).join(" "),
1716
+ "aria-hidden": "true",
1717
+ children: /* @__PURE__ */ jsxRuntime.jsx(
1718
+ "polyline",
1719
+ {
1720
+ points,
1721
+ fill: "none",
1722
+ stroke: TONE_COLORS[tone],
1723
+ strokeWidth: 1.4,
1724
+ strokeLinejoin: "round",
1725
+ strokeLinecap: "round"
1726
+ }
1727
+ )
1728
+ }
1729
+ );
1730
+ }
1731
+
1732
+ // src/components/KpiTile/KpiTile.css.ts
1733
+ var inner = "KpiTile_inner__1yi98c61";
1734
+ var value = "KpiTile_value__1yi98c62";
1735
+ var wrapper4 = "KpiTile_wrapper__1yi98c60";
1736
+ var deltaToneToBadge = {
1737
+ positive: "saved",
1738
+ negative: "stopped",
1739
+ neutral: "neutral"
1740
+ };
1741
+ function KpiTile({
1742
+ label: label4,
1743
+ value: value2,
1744
+ delta,
1745
+ deltaTone = "neutral",
1746
+ sparkData,
1747
+ onClick,
1748
+ className
1749
+ }) {
1750
+ const inner2 = /* @__PURE__ */ jsxRuntime.jsx(Card, { variant: "stamp", padding: "md", ...className !== void 0 ? { className } : {}, children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: inner, children: [
1751
+ /* @__PURE__ */ jsxRuntime.jsx(Eyebrow, { children: label4 }),
1752
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: value, children: value2 }),
1753
+ delta && /* @__PURE__ */ jsxRuntime.jsx(Badge, { tone: deltaToneToBadge[deltaTone], dot: true, children: delta }),
1754
+ sparkData && sparkData.length >= 2 && /* @__PURE__ */ jsxRuntime.jsx(Sparkline, { data: sparkData, tone: deltaTone, width: 80, height: 24 })
1755
+ ] }) });
1756
+ if (onClick) {
1757
+ return /* @__PURE__ */ jsxRuntime.jsx("button", { type: "button", onClick, className: wrapper4, children: inner2 });
1758
+ }
1759
+ return inner2;
1760
+ }
1761
+ var stateMap = {
1762
+ "stable": { tone: "neutral", label: "Stable" },
1763
+ "drift-up": { tone: "stopped", label: "Drift up" },
1764
+ "drift-down": { tone: "saved", label: "Drift down" },
1765
+ "new-price": { tone: "drafting", label: "New price" },
1766
+ "renewing": { tone: "drafting", label: "Renewing soon" }
1767
+ };
1768
+ function StatePill({ state, className }) {
1769
+ const { tone, label: label4 } = stateMap[state];
1770
+ return /* @__PURE__ */ jsxRuntime.jsx(Badge, { tone, dot: true, ...className !== void 0 ? { className } : {}, children: label4 });
1771
+ }
1772
+ var tag = createRuntimeFn.createRuntimeFn({ defaultClassName: "TypeTag_tag__1nf2zhb0", variantClassNames: { type: { basic: "TypeTag_tag_type_basic__1nf2zhb1", internal: "TypeTag_tag_type_internal__1nf2zhb2", exceptional: "TypeTag_tag_type_exceptional__1nf2zhb3", fee: "TypeTag_tag_type_fee__1nf2zhb4" } }, defaultVariants: { type: "basic" }, compoundVariants: [] });
1773
+ var labels = {
1774
+ basic: "basic",
1775
+ internal: "internal",
1776
+ exceptional: "exceptional",
1777
+ fee: "fee"
1778
+ };
1779
+ function TypeTag({ type, className }) {
1780
+ return /* @__PURE__ */ jsxRuntime.jsx("span", { className: [tag({ type }), className].filter(Boolean).join(" "), children: labels[type] });
1781
+ }
1782
+
998
1783
  exports.AcheryProvider = AcheryProvider;
999
1784
  exports.AppBar = AppBar;
1785
+ exports.Avatar = Avatar;
1000
1786
  exports.Badge = Badge;
1001
1787
  exports.Body = Body;
1002
1788
  exports.Button = Button;
1003
1789
  exports.Card = Card;
1790
+ exports.Checkbox = Checkbox;
1791
+ exports.Combobox = Combobox;
1792
+ exports.DatePicker = DatePicker;
1004
1793
  exports.Display = Display;
1794
+ exports.EntityPill = EntityPill;
1005
1795
  exports.Eyebrow = Eyebrow;
1006
1796
  exports.Field = Field;
1007
1797
  exports.Glyph = Glyph;
1008
1798
  exports.Heading = Heading;
1009
1799
  exports.Input = Input;
1800
+ exports.KpiTile = KpiTile;
1801
+ exports.LetterStamp = LetterStamp;
1010
1802
  exports.Marginalia = Marginalia;
1803
+ exports.Menu = Menu2;
1011
1804
  exports.Modal = Modal;
1012
1805
  exports.Mono = Mono;
1806
+ exports.ProgressBar = ProgressBar;
1013
1807
  exports.SearchInput = SearchInput;
1014
1808
  exports.Select = Select;
1015
1809
  exports.Sidebar = Sidebar;
1810
+ exports.SingleCombobox = SingleCombobox;
1811
+ exports.Sparkline = Sparkline;
1812
+ exports.StatePill = StatePill;
1016
1813
  exports.Table = Table;
1017
1814
  exports.Tabs = Tabs;
1018
1815
  exports.Textarea = Textarea;
1019
1816
  exports.ToastProvider = ToastProvider;
1020
1817
  exports.Toggle = Toggle;
1021
1818
  exports.Tooltip = Tooltip;
1819
+ exports.TypeTag = TypeTag;
1022
1820
  exports.useTheme = useTheme;
1023
1821
  exports.useToast = useToast;
1024
1822
  exports.vars = vars;