@floegence/floe-webapp-core 0.24.4 → 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.
@@ -1,4 +1,5 @@
1
1
  import { type Component } from 'solid-js';
2
+ import { type ActivityBarCollapseBehavior } from './activityBarBehavior';
2
3
  export interface ActivityBarItem {
3
4
  id: string;
4
5
  icon: Component<{
@@ -7,12 +8,21 @@ export interface ActivityBarItem {
7
8
  label: string;
8
9
  badge?: number | string | (() => number | string | undefined);
9
10
  onClick?: () => void;
11
+ /**
12
+ * How this item should affect the sidebar collapsed state when clicked.
13
+ *
14
+ * - `toggle` (default): VSCode-style behavior (change tab, open sidebar; click active tab to collapse).
15
+ * - `preserve`: change tab without mutating the collapsed state (useful for fullScreen pages).
16
+ */
17
+ collapseBehavior?: ActivityBarCollapseBehavior;
10
18
  }
11
19
  export interface ActivityBarProps {
12
20
  items: ActivityBarItem[];
13
21
  bottomItems?: ActivityBarItem[];
14
22
  activeId: string;
15
- onActiveChange: (id: string) => void;
23
+ onActiveChange: (id: string, opts?: {
24
+ openSidebar?: boolean;
25
+ }) => void;
16
26
  collapsed?: boolean;
17
27
  onCollapsedChange?: (collapsed: boolean) => void;
18
28
  class?: string;
@@ -1,91 +1,95 @@
1
- import { insert as o, createComponent as r, effect as f, className as g, template as d, Dynamic as w, memo as A, setAttribute as y, delegateEvents as k } from "solid-js/web";
2
- import { createMemo as s, For as x, Show as m } from "solid-js";
3
- import { cn as b } from "../../utils/cn.js";
4
- import { deferNonBlocking as $ } from "../../utils/defer.js";
5
- import { Tooltip as _ } from "../ui/Tooltip.js";
6
- var I = /* @__PURE__ */ d('<div class="flex flex-col">'), B = /* @__PURE__ */ d('<div><div class="flex flex-col">'), j = /* @__PURE__ */ d('<div class="absolute left-0 top-0 w-1 h-full bg-primary rounded-r">'), N = /* @__PURE__ */ d("<span>"), q = /* @__PURE__ */ d("<button type=button>");
7
- function T(e) {
8
- const c = s(() => e.activeId), n = s(() => e.collapsed ?? !1), t = s(() => e.onActiveChange), a = s(() => e.onCollapsedChange), u = (i) => {
1
+ import { insert as a, createComponent as l, effect as f, className as b, template as s, Dynamic as A, memo as k, setAttribute as x, delegateEvents as w } from "solid-js/web";
2
+ import { createMemo as v, For as y, Show as m } from "solid-js";
3
+ import { cn as g } from "../../utils/cn.js";
4
+ import { deferNonBlocking as I } from "../../utils/defer.js";
5
+ import { Tooltip as $ } from "../ui/Tooltip.js";
6
+ import { resolveActivityBarClick as _ } from "./activityBarBehavior.js";
7
+ var B = /* @__PURE__ */ s('<div class="flex flex-col">'), p = /* @__PURE__ */ s('<div><div class="flex flex-col">'), S = /* @__PURE__ */ s('<div class="absolute left-0 top-0 w-1 h-full bg-primary rounded-r">'), j = /* @__PURE__ */ s("<span>"), N = /* @__PURE__ */ s("<button type=button>");
8
+ function V(e) {
9
+ const o = v(() => e.activeId), n = v(() => e.collapsed ?? !1), t = v(() => e.onActiveChange), c = v(() => e.onCollapsedChange), u = (i) => {
9
10
  if (i.onClick) {
10
- $(() => i.onClick());
11
+ I(() => i.onClick());
11
12
  return;
12
13
  }
13
- const v = c() === i.id, l = n();
14
- if (v && !l) {
15
- a()?.(!0);
16
- return;
17
- }
18
- t()(i.id), a()?.(!1);
14
+ const r = _({
15
+ clickedId: i.id,
16
+ activeId: o(),
17
+ collapsed: n(),
18
+ behavior: i.collapseBehavior
19
+ });
20
+ r.nextActiveId !== o() && (typeof r.openSidebar == "boolean" ? t()(r.nextActiveId, {
21
+ openSidebar: r.openSidebar
22
+ }) : t()(r.nextActiveId)), typeof r.nextCollapsed == "boolean" && c()?.(r.nextCollapsed);
19
23
  };
20
24
  return (() => {
21
- var i = B(), v = i.firstChild;
22
- return o(v, r(x, {
25
+ var i = p(), r = i.firstChild;
26
+ return a(r, l(y, {
23
27
  get each() {
24
28
  return e.items;
25
29
  },
26
- children: (l) => r(C, {
27
- item: l,
30
+ children: (d) => l(C, {
31
+ item: d,
28
32
  get isActive() {
29
- return c() === l.id;
33
+ return o() === d.id;
30
34
  },
31
- onClick: () => u(l)
35
+ onClick: () => u(d)
32
36
  })
33
- })), o(i, r(m, {
37
+ })), a(i, l(m, {
34
38
  get when() {
35
39
  return e.bottomItems?.length;
36
40
  },
37
41
  get children() {
38
- var l = I();
39
- return o(l, r(x, {
42
+ var d = B();
43
+ return a(d, l(y, {
40
44
  get each() {
41
45
  return e.bottomItems;
42
46
  },
43
- children: (h) => r(C, {
47
+ children: (h) => l(C, {
44
48
  item: h,
45
49
  isActive: !1,
46
50
  onClick: () => u(h)
47
51
  })
48
- })), l;
52
+ })), d;
49
53
  }
50
- }), null), f(() => g(i, b("w-10 md:w-12 flex flex-col justify-between shrink-0 min-h-0", "bg-activity-bar border-r border-border", e.class))), i;
54
+ }), null), f(() => b(i, g("w-10 md:w-12 flex flex-col justify-between shrink-0 min-h-0", "bg-activity-bar border-r border-border", e.class))), i;
51
55
  })();
52
56
  }
53
57
  function C(e) {
54
- const c = () => typeof e.item.badge == "function" ? e.item.badge() : e.item.badge;
55
- return r(_, {
58
+ const o = () => typeof e.item.badge == "function" ? e.item.badge() : e.item.badge;
59
+ return l($, {
56
60
  get content() {
57
61
  return e.item.label;
58
62
  },
59
63
  placement: "right",
60
64
  delay: 0,
61
65
  get children() {
62
- var n = q();
63
- return n.$$click = () => e.onClick(), o(n, r(m, {
66
+ var n = N();
67
+ return n.$$click = () => e.onClick(), a(n, l(m, {
64
68
  get when() {
65
69
  return e.isActive;
66
70
  },
67
71
  get children() {
68
- return j();
72
+ return S();
69
73
  }
70
- }), null), o(n, r(w, {
74
+ }), null), a(n, l(A, {
71
75
  get component() {
72
76
  return e.item.icon;
73
77
  },
74
78
  class: "w-5 h-5"
75
- }), null), o(n, r(m, {
79
+ }), null), a(n, l(m, {
76
80
  get when() {
77
- return c();
81
+ return o();
78
82
  },
79
83
  get children() {
80
- var t = N();
81
- return o(t, (() => {
82
- var a = A(() => typeof c() == "number" && c() > 99);
83
- return () => a() ? "99+" : c();
84
- })()), f(() => g(t, b("absolute top-0.5 right-0.5 min-w-3.5 h-3.5 px-1", "flex items-center justify-center", "text-[9px] font-medium rounded-full", "bg-activity-bar-badge text-activity-bar-badge-foreground"))), t;
84
+ var t = j();
85
+ return a(t, (() => {
86
+ var c = k(() => typeof o() == "number" && o() > 99);
87
+ return () => c() ? "99+" : o();
88
+ })()), f(() => b(t, g("absolute top-0.5 right-0.5 min-w-3.5 h-3.5 px-1", "flex items-center justify-center", "text-[9px] font-medium rounded-full", "bg-activity-bar-badge text-activity-bar-badge-foreground"))), t;
85
89
  }
86
90
  }), null), f((t) => {
87
- var a = b("relative w-full aspect-square flex items-center justify-center cursor-pointer", "transition-all duration-100", "focus:outline-none focus-visible:ring-1 focus-visible:ring-ring focus-visible:ring-inset", e.isActive ? "text-activity-bar-foreground-active bg-accent/80" : "text-activity-bar-foreground hover:text-activity-bar-foreground-active hover:bg-accent/40"), u = e.item.label, i = e.isActive;
88
- return a !== t.e && g(n, t.e = a), u !== t.t && y(n, "aria-label", t.t = u), i !== t.a && y(n, "aria-pressed", t.a = i), t;
91
+ var c = g("relative w-full aspect-square flex items-center justify-center cursor-pointer", "transition-all duration-100", "focus:outline-none focus-visible:ring-1 focus-visible:ring-ring focus-visible:ring-inset", e.isActive ? "text-activity-bar-foreground-active bg-accent/80" : "text-activity-bar-foreground hover:text-activity-bar-foreground-active hover:bg-accent/40"), u = e.item.label, i = e.isActive;
92
+ return c !== t.e && b(n, t.e = c), u !== t.t && x(n, "aria-label", t.t = u), i !== t.a && x(n, "aria-pressed", t.a = i), t;
89
93
  }, {
90
94
  e: void 0,
91
95
  t: void 0,
@@ -94,7 +98,7 @@ function C(e) {
94
98
  }
95
99
  });
96
100
  }
97
- k(["click"]);
101
+ w(["click"]);
98
102
  export {
99
- T as ActivityBar
103
+ V as ActivityBar
100
104
  };
@@ -1,5 +1,5 @@
1
- import { createComponent as r, Dynamic as $, insert as l, memo as p, effect as x, className as A, setStyleProperty as R, template as g, delegateEvents as P } from "solid-js/web";
2
- import { createSignal as W, createEffect as v, createMemo as S, For as T, Show as u } from "solid-js";
1
+ import { createComponent as r, Dynamic as $, insert as l, memo as p, effect as x, className as A, setStyleProperty as R, template as v, delegateEvents as P } from "solid-js/web";
2
+ import { createSignal as W, createEffect as g, createMemo as S, For as T, Show as u } from "solid-js";
3
3
  import { useLayout as E } from "../../context/LayoutContext.js";
4
4
  import { useResolvedFloeConfig as Q } from "../../context/FloeConfigContext.js";
5
5
  import { useMediaQuery as D } from "../../hooks/useMediaQuery.js";
@@ -13,31 +13,35 @@ import { ActivityBar as q } from "./ActivityBar.js";
13
13
  import { ResizeHandle as M } from "./ResizeHandle.js";
14
14
  import { resolveMobileTabActiveId as G, resolveMobileTabSelect as J } from "./mobileTabs.js";
15
15
  import { KeepAliveStack as U } from "./KeepAliveStack.js";
16
- var B = /* @__PURE__ */ g('<div class="flex items-center gap-2">'), X = /* @__PURE__ */ g('<div class="absolute inset-0 z-40 bg-black/30 cursor-pointer">'), Y = /* @__PURE__ */ g('<div><div class="h-full overflow-auto overscroll-contain">'), Z = /* @__PURE__ */ g('<div class="relative shrink-0 border-t border-border bg-terminal-background overflow-hidden">'), ee = /* @__PURE__ */ g('<div><div class="flex-1 min-h-0 flex overflow-hidden relative"><div class="flex-1 min-w-0 flex flex-col overflow-hidden"><main class="flex-1 min-h-0 overflow-auto overscroll-contain">');
17
- function ge(n) {
18
- const t = E(), k = Q(), a = D(k.config.layout.mobileQuery), [w, b] = W(!1), s = () => n.sidebarMode === "hidden", C = (e) => t.setSidebarActiveTab(e, {
19
- openSidebar: !s()
20
- }), d = (() => {
16
+ var B = /* @__PURE__ */ v('<div class="flex items-center gap-2">'), X = /* @__PURE__ */ v('<div class="absolute inset-0 z-40 bg-black/30 cursor-pointer">'), Y = /* @__PURE__ */ v('<div><div class="h-full overflow-auto overscroll-contain">'), Z = /* @__PURE__ */ v('<div class="relative shrink-0 border-t border-border bg-terminal-background overflow-hidden">'), ee = /* @__PURE__ */ v('<div><div class="flex-1 min-h-0 flex overflow-hidden relative"><div class="flex-1 min-w-0 flex flex-col overflow-hidden"><main class="flex-1 min-h-0 overflow-auto overscroll-contain">');
17
+ function ve(o) {
18
+ const t = E(), k = Q(), c = D(k.config.layout.mobileQuery), [w, b] = W(!1), m = () => o.sidebarMode === "hidden", a = (() => {
21
19
  try {
22
20
  return K();
23
21
  } catch {
24
22
  return null;
25
23
  }
26
- })();
27
- v(() => {
28
- s() && b(!1);
29
- }), v(() => {
30
- const e = a();
24
+ })(), C = (e, s) => {
25
+ const d = a?.getComponent(e)?.sidebar?.fullScreen ?? !1, n = m() ? !1 : s?.openSidebar ?? !d;
26
+ t.setSidebarActiveTab(e, {
27
+ openSidebar: n
28
+ });
29
+ };
30
+ g(() => {
31
+ m() && b(!1);
32
+ }), g(() => {
33
+ const e = c();
31
34
  t.isMobile() !== e && t.setIsMobile(e);
32
- }), v(() => {
33
- a() || b(!1);
35
+ }), g(() => {
36
+ c() || b(!1);
34
37
  });
35
- const f = S(() => n.activityItems ? n.activityItems : d ? d.sidebarItems().filter((e) => !!e.icon).filter((e) => !(a() && e.sidebar?.hiddenOnMobile)).map((e) => ({
38
+ const f = S(() => o.activityItems ? o.activityItems : a ? a.sidebarItems().filter((e) => !!e.icon).filter((e) => !(c() && e.sidebar?.hiddenOnMobile)).map((e) => ({
36
39
  id: e.id,
37
40
  icon: e.icon,
38
41
  label: e.name,
39
- badge: e.sidebar?.badge
40
- })) : []), O = S(() => s() ? [] : n.sidebarContent ? [] : d ? d.sidebarItems().filter((e) => !(a() && e.sidebar?.hiddenOnMobile)).filter((e) => !e.sidebar?.fullScreen).map((e) => ({
42
+ badge: e.sidebar?.badge,
43
+ collapseBehavior: e.sidebar?.fullScreen ? "preserve" : "toggle"
44
+ })) : []), O = S(() => m() ? [] : o.sidebarContent ? [] : a ? a.sidebarItems().filter((e) => !(c() && e.sidebar?.hiddenOnMobile)).filter((e) => !e.sidebar?.fullScreen).map((e) => ({
41
45
  id: e.id,
42
46
  render: () => r($, {
43
47
  get component() {
@@ -45,9 +49,9 @@ function ge(n) {
45
49
  }
46
50
  })
47
51
  })) : []), y = (e) => {
48
- if (!s()) {
49
- if (n.sidebarContent) return n.sidebarContent(e);
50
- if (d)
52
+ if (!m()) {
53
+ if (o.sidebarContent) return o.sidebarContent(e);
54
+ if (a)
51
55
  return r(U, {
52
56
  get views() {
53
57
  return O();
@@ -55,65 +59,65 @@ function ge(n) {
55
59
  activeId: e
56
60
  });
57
61
  }
58
- }, I = S(() => s() ? !0 : d ? d.getComponent(t.sidebarActiveTab())?.sidebar?.fullScreen ?? !1 : !1);
59
- v(() => {
60
- a() && I() && b(!1);
62
+ }, I = S(() => m() ? !0 : a ? a.getComponent(t.sidebarActiveTab())?.sidebar?.fullScreen ?? !1 : !1);
63
+ g(() => {
64
+ c() && I() && b(!1);
61
65
  });
62
66
  const z = S(() => {
63
- if (n.bottomBarItems) return n.bottomBarItems;
64
- if (!d) return;
65
- const e = [...d.statusBarItems()].sort((o, i) => (o.order ?? 100) - (i.order ?? 100)), c = e.filter((o) => o.position === "left"), m = e.filter((o) => o.position === "right");
67
+ if (o.bottomBarItems) return o.bottomBarItems;
68
+ if (!a) return;
69
+ const e = [...a.statusBarItems()].sort((n, i) => (n.order ?? 100) - (i.order ?? 100)), s = e.filter((n) => n.position === "left"), d = e.filter((n) => n.position === "right");
66
70
  return [(() => {
67
- var o = B();
68
- return l(o, r(T, {
69
- each: c,
71
+ var n = B();
72
+ return l(n, r(T, {
73
+ each: s,
70
74
  children: (i) => r($, {
71
75
  get component() {
72
76
  return i.component;
73
77
  }
74
78
  })
75
- })), o;
79
+ })), n;
76
80
  })(), (() => {
77
- var o = B();
78
- return l(o, r(T, {
79
- each: m,
81
+ var n = B();
82
+ return l(n, r(T, {
83
+ each: d,
80
84
  children: (i) => r($, {
81
85
  get component() {
82
86
  return i.component;
83
87
  }
84
88
  })
85
- })), o;
89
+ })), n;
86
90
  })()];
87
91
  });
88
- v(() => {
92
+ g(() => {
89
93
  const e = f();
90
94
  if (!e.length) return;
91
95
  t.sidebarActiveTab() || C(e[0].id);
92
96
  });
93
97
  const F = (e) => {
94
- const c = s() ? !0 : d?.getComponent(e)?.sidebar?.fullScreen ?? !1, {
95
- nextActiveId: m,
96
- nextMobileSidebarOpen: o
98
+ const s = m() ? !0 : a?.getComponent(e)?.sidebar?.fullScreen ?? !1, {
99
+ nextActiveId: d,
100
+ nextMobileSidebarOpen: n
97
101
  } = J({
98
102
  clickedId: e,
99
103
  activeId: t.sidebarActiveTab(),
100
104
  mobileSidebarOpen: w(),
101
- clickedIsFullScreen: c
105
+ clickedIsFullScreen: s
102
106
  });
103
- t.sidebarActiveTab() !== m && C(m), b(o);
104
- }, H = () => s() ? !0 : t.sidebarCollapsed();
107
+ t.sidebarActiveTab() !== d && C(d), b(n);
108
+ }, H = () => m() ? !0 : t.sidebarCollapsed();
105
109
  return (() => {
106
- var e = ee(), c = e.firstChild, m = c.firstChild, o = m.firstChild;
110
+ var e = ee(), s = e.firstChild, d = s.firstChild, n = d.firstChild;
107
111
  return l(e, r(N, {
108
112
  get logo() {
109
- return n.logo;
113
+ return o.logo;
110
114
  },
111
115
  get actions() {
112
- return n.topBarActions;
116
+ return o.topBarActions;
113
117
  }
114
- }), c), l(c, r(u, {
118
+ }), s), l(s, r(u, {
115
119
  get when() {
116
- return !a();
120
+ return !c();
117
121
  },
118
122
  get children() {
119
123
  return [r(u, {
@@ -126,7 +130,7 @@ function ge(n) {
126
130
  return f();
127
131
  },
128
132
  get bottomItems() {
129
- return n.activityBottomItems;
133
+ return o.activityBottomItems;
130
134
  },
131
135
  get activeId() {
132
136
  return t.sidebarActiveTab();
@@ -136,13 +140,13 @@ function ge(n) {
136
140
  return H();
137
141
  },
138
142
  get onCollapsedChange() {
139
- return p(() => !!s())() ? void 0 : t.setSidebarCollapsed;
143
+ return p(() => !!m())() ? void 0 : t.setSidebarCollapsed;
140
144
  }
141
145
  });
142
146
  }
143
147
  }), r(u, {
144
148
  get when() {
145
- return !s();
149
+ return !m();
146
150
  },
147
151
  get children() {
148
152
  return r(L, {
@@ -165,9 +169,9 @@ function ge(n) {
165
169
  }
166
170
  })];
167
171
  }
168
- }), m), l(c, r(u, {
172
+ }), d), l(s, r(u, {
169
173
  get when() {
170
- return p(() => !!(a() && w()))() && !s();
174
+ return p(() => !!(c() && w()))() && !m();
171
175
  },
172
176
  get children() {
173
177
  return [(() => {
@@ -178,20 +182,20 @@ function ge(n) {
178
182
  return l(h, () => y(t.sidebarActiveTab())), x(() => A(i, _("absolute left-0 top-0 bottom-0 z-50", "w-72 max-w-[80vw]", "bg-sidebar border-r border-sidebar-border", "shadow-xl", "animate-in slide-in-from-left duration-200"))), i;
179
183
  })()];
180
184
  }
181
- }), m), l(o, () => n.children), l(m, r(u, {
185
+ }), d), l(n, () => o.children), l(d, r(u, {
182
186
  get when() {
183
- return p(() => !!(!a() && t.terminalOpened()))() && n.terminalPanel;
187
+ return p(() => !!(!c() && t.terminalOpened()))() && o.terminalPanel;
184
188
  },
185
189
  get children() {
186
190
  var i = Z();
187
191
  return l(i, r(M, {
188
192
  direction: "vertical",
189
193
  onResize: (h) => t.setTerminalHeight(t.terminalHeight() - h)
190
- }), null), l(i, () => n.terminalPanel, null), x((h) => R(i, "height", `${t.terminalHeight()}px`)), i;
194
+ }), null), l(i, () => o.terminalPanel, null), x((h) => R(i, "height", `${t.terminalHeight()}px`)), i;
191
195
  }
192
196
  }), null), l(e, r(u, {
193
197
  get when() {
194
- return !a();
198
+ return !c();
195
199
  },
196
200
  get children() {
197
201
  return r(V, {
@@ -202,7 +206,7 @@ function ge(n) {
202
206
  }
203
207
  }), null), l(e, r(u, {
204
208
  get when() {
205
- return p(() => !!a())() && f().length > 0;
209
+ return p(() => !!c())() && f().length > 0;
206
210
  },
207
211
  get children() {
208
212
  return r(j, {
@@ -225,11 +229,11 @@ function ge(n) {
225
229
  "bg-background text-foreground",
226
230
  // Prevent overscroll on the shell container
227
231
  "overscroll-none",
228
- n.class
232
+ o.class
229
233
  ))), e;
230
234
  })();
231
235
  }
232
236
  P(["click"]);
233
237
  export {
234
- ge as Shell
238
+ ve as Shell
235
239
  };
@@ -0,0 +1,24 @@
1
+ export type ActivityBarCollapseBehavior = 'toggle' | 'preserve';
2
+ export interface ResolveActivityBarClickArgs {
3
+ clickedId: string;
4
+ activeId: string;
5
+ collapsed: boolean;
6
+ /**
7
+ * How the clicked item should affect the sidebar collapsed state.
8
+ *
9
+ * - `toggle` (default): VSCode-like behavior for sidebar-backed tabs.
10
+ * - `preserve`: navigate without mutating the collapsed state (useful for fullScreen pages).
11
+ */
12
+ behavior?: ActivityBarCollapseBehavior;
13
+ }
14
+ export interface ResolveActivityBarClickResult {
15
+ nextActiveId: string;
16
+ /** When undefined, the click should not change the collapsed state. */
17
+ nextCollapsed?: boolean;
18
+ /**
19
+ * Hint for LayoutContext.setSidebarActiveTab({ openSidebar }).
20
+ * Only meaningful when the click causes a tab change.
21
+ */
22
+ openSidebar?: boolean;
23
+ }
24
+ export declare function resolveActivityBarClick(args: ResolveActivityBarClickArgs): ResolveActivityBarClickResult;
@@ -0,0 +1,6 @@
1
+ function c(e) {
2
+ return (e.behavior ?? "toggle") === "preserve" ? e.clickedId === e.activeId ? { nextActiveId: e.activeId } : { nextActiveId: e.clickedId, openSidebar: !1 } : e.clickedId === e.activeId && !e.collapsed ? { nextActiveId: e.activeId, nextCollapsed: !0 } : { nextActiveId: e.clickedId, nextCollapsed: !1, openSidebar: !0 };
3
+ }
4
+ export {
5
+ c as resolveActivityBarClick
6
+ };
@@ -0,0 +1,47 @@
1
+ import { type JSX, type Component } from 'solid-js';
2
+ export type SegmentedControlSize = 'sm' | 'md' | 'lg';
3
+ export interface SegmentedControlOption {
4
+ /** Unique value for this option */
5
+ value: string;
6
+ /** Display label */
7
+ label: string;
8
+ /** Optional icon component */
9
+ icon?: Component<{
10
+ class?: string;
11
+ }>;
12
+ /** Whether this option is disabled */
13
+ disabled?: boolean;
14
+ }
15
+ export interface SegmentedControlProps extends Omit<JSX.HTMLAttributes<HTMLDivElement>, 'onChange'> {
16
+ /** Currently selected value */
17
+ value: string;
18
+ /** Callback when selection changes */
19
+ onChange: (value: string) => void;
20
+ /** Available options */
21
+ options: SegmentedControlOption[];
22
+ /** Size variant */
23
+ size?: SegmentedControlSize;
24
+ /** Whether the entire control is disabled */
25
+ disabled?: boolean;
26
+ }
27
+ /**
28
+ * SegmentedControl - A toggle button group for switching between options
29
+ *
30
+ * Common use cases:
31
+ * - View mode switching (e.g., UI/JSON, List/Grid)
32
+ * - Tab-like navigation within a section
33
+ * - Filter toggles
34
+ *
35
+ * @example
36
+ * ```tsx
37
+ * <SegmentedControl
38
+ * value={viewMode()}
39
+ * onChange={setViewMode}
40
+ * options={[
41
+ * { value: 'ui', label: 'UI' },
42
+ * { value: 'json', label: 'JSON' },
43
+ * ]}
44
+ * />
45
+ * ```
46
+ */
47
+ export declare function SegmentedControl(props: SegmentedControlProps): JSX.Element;
@@ -0,0 +1,63 @@
1
+ import { spread as y, mergeProps as C, insert as i, createComponent as m, memo as k, effect as w, setAttribute as $, className as z, template as v, delegateEvents as S } from "solid-js/web";
2
+ import { splitProps as _, For as P } from "solid-js";
3
+ import { cn as g } from "../../utils/cn.js";
4
+ var A = /* @__PURE__ */ v("<div role=group>"), D = /* @__PURE__ */ v('<button type=button role=radio><span class="inline-flex items-center gap-1.5">');
5
+ const E = {
6
+ sm: {
7
+ container: "p-0.5 gap-0.5",
8
+ button: "px-2 py-1 text-[11px]",
9
+ icon: "w-3 h-3"
10
+ },
11
+ md: {
12
+ container: "p-0.5 gap-0.5",
13
+ button: "px-3 py-1.5 text-xs",
14
+ icon: "w-3.5 h-3.5"
15
+ },
16
+ lg: {
17
+ container: "p-1 gap-1",
18
+ button: "px-4 py-2 text-sm",
19
+ icon: "w-4 h-4"
20
+ }
21
+ };
22
+ function q(p) {
23
+ const [e, f] = _(p, ["value", "onChange", "options", "size", "disabled", "class"]), x = () => e.size ?? "md", s = () => E[x()], h = (n, r) => {
24
+ e.disabled || r || n !== e.value && e.onChange(n);
25
+ };
26
+ return (() => {
27
+ var n = A();
28
+ return y(n, C({
29
+ get class() {
30
+ return g("inline-flex items-center rounded-lg border border-border bg-muted/40", s().container, e.disabled && "opacity-50 pointer-events-none", e.class);
31
+ }
32
+ }, f), !1, !0), i(n, m(P, {
33
+ get each() {
34
+ return e.options;
35
+ },
36
+ children: (r) => {
37
+ const l = () => e.value === r.value, a = () => e.disabled || r.disabled;
38
+ return (() => {
39
+ var o = D(), d = o.firstChild;
40
+ return o.$$click = () => h(r.value, r.disabled), i(d, (() => {
41
+ var t = k(() => !!r.icon);
42
+ return () => t() && m(r.icon, {
43
+ get class() {
44
+ return s().icon;
45
+ }
46
+ });
47
+ })(), null), i(d, () => r.label, null), w((t) => {
48
+ var c = l(), u = a(), b = g("font-medium rounded-md transition-all duration-150 cursor-pointer", "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-1", s().button, l() ? "bg-background text-foreground shadow-sm border border-border" : "text-muted-foreground hover:text-foreground hover:bg-muted/50 border border-transparent", a() && "cursor-not-allowed opacity-50");
49
+ return c !== t.e && $(o, "aria-checked", t.e = c), u !== t.t && (o.disabled = t.t = u), b !== t.a && z(o, t.a = b), t;
50
+ }, {
51
+ e: void 0,
52
+ t: void 0,
53
+ a: void 0
54
+ }), o;
55
+ })();
56
+ }
57
+ })), n;
58
+ })();
59
+ }
60
+ S(["click"]);
61
+ export {
62
+ q as SegmentedControl
63
+ };
@@ -19,6 +19,7 @@ export { LineChart, AreaChart, DataBarChart, DataPieChart, MonitoringChart, type
19
19
  export { Stepper, Wizard, useWizard, type StepItem, type StepperProps, type StepperVariant, type StepperOrientation, type StepperSize, type WizardProps, type WizardStepContent, type UseWizardOptions, type UseWizardReturn, } from './Stepper';
20
20
  export { RadioGroup, RadioOption, RadioList, type RadioGroupProps, type RadioOptionProps, type RadioListProps, type RadioSize, type RadioOrientation, type RadioVariant, } from './Radio';
21
21
  export { Switch, type SwitchProps, type SwitchSize } from './Switch';
22
+ export { SegmentedControl, type SegmentedControlProps, type SegmentedControlOption, type SegmentedControlSize, } from './SegmentedControl';
22
23
  export { Checkbox, CheckboxGroup, CheckboxList, type CheckboxProps, type CheckboxGroupProps, type CheckboxListProps, type CheckboxSize, type CheckboxVariant, } from './Checkbox';
23
24
  export { Pagination, type PaginationProps, type PaginationSize, type PaginationVariant, } from './Pagination';
24
25
  export { LinearProgress, CircularProgress, SegmentedProgress, StepsProgress, type LinearProgressProps, type CircularProgressProps, type SegmentedProgressProps, type StepsProgressProps, type ProgressSize, type ProgressColor, } from './Progress';