@burdenoff/fe-libs 2026.1027.7 → 2026.1027.8

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,23 +1,23 @@
1
1
  import { cn as e } from "../lib/utils.js";
2
2
  import { BottomSheet as t, BottomSheetContent as n, BottomSheetHeader as r, BottomSheetTitle as i } from "../ui/bottom-sheet.js";
3
3
  import { getNativeBridge as a } from "../shared/native/bridge.js";
4
- import { useShellLabel as ee } from "../shared/providers/shell/useShellLabel.js";
5
- import { appendContextToPath as o, useCurrentContextSearchParams as s } from "../shared/hooks/useCurrentContextSearchParams.js";
4
+ import { useShellLabel as o } from "../shared/providers/shell/useShellLabel.js";
5
+ import { appendContextToPath as s, useCurrentContextSearchParams as c } from "../shared/hooks/useCurrentContextSearchParams.js";
6
6
  import "./sideNavigation/navVisibility.js";
7
- import { useVisibleNavItems as c } from "./mobileTabBar/useVisibleNavItems.js";
8
- import { isItemOrChildActive as l } from "./sideNavigation/helpers.js";
9
- import { resolveTabPath as u, selectMobileTabs as d } from "./mobileTabBar/selectTabs.js";
7
+ import { useVisibleNavItems as l } from "./mobileTabBar/useVisibleNavItems.js";
8
+ import { findAncestorIds as u, isItemOrChildActive as d } from "./sideNavigation/helpers.js";
9
+ import { resolveTabPath as f, selectMobileTabs as p } from "./mobileTabBar/selectTabs.js";
10
10
  import "./mobileTabBar/useMobileTabBarVisible.js";
11
- import { useCallback as f, useEffect as p, useLayoutEffect as m, useMemo as h, useRef as g, useState as te } from "react";
12
- import { MoreHorizontal as _ } from "lucide-react";
13
- import { Fragment as v, jsx as y, jsxs as b } from "react/jsx-runtime";
14
- import { useLocation as x, useNavigate as S } from "react-router";
11
+ import { useCallback as m, useEffect as h, useLayoutEffect as g, useMemo as _, useRef as v, useState as y } from "react";
12
+ import { ChevronDown as b, ChevronRight as x, MoreHorizontal as S } from "lucide-react";
13
+ import { Fragment as C, jsx as w, jsxs as T } from "react/jsx-runtime";
14
+ import { useLocation as E, useNavigate as ee } from "react-router";
15
15
  //#region src/chrome/MobileTabBar.tsx
16
- var C = "--mobile-tabbar-height";
17
- function w() {
16
+ var D = "--mobile-tabbar-height";
17
+ function O() {
18
18
  a()?.selection?.();
19
19
  }
20
- function T(e, t, n) {
20
+ function k(e, t, n) {
21
21
  let r = /* @__PURE__ */ new Map();
22
22
  for (let t of e) {
23
23
  if (t.id.startsWith("__nav_more__:") && t.children) {
@@ -39,42 +39,57 @@ function T(e, t, n) {
39
39
  items: r.get(e) ?? []
40
40
  }));
41
41
  }
42
- function E({ appName: a, logo: E, groupOrder: O = [], groupLabels: k = {}, maxTabs: A = 4, moreLabel: ne, mobileActions: j, hideWhenKeyboardOpen: re = !0, className: M, open: N, onOpenChange: P }) {
43
- let F = ee(), I = ne ?? F("nav.more", "More"), L = S(), R = x(), z = s(), { items: B } = c(), [V, H] = te(!1), U = N ?? V, W = P ?? H, G = g(null), { tabs: K, more: q, hasMore: J } = h(() => d(B, A), [B, A]), Y = h(() => T(q, O, k), [
42
+ function A({ appName: a, logo: b, groupOrder: x = [], groupLabels: A = {}, maxTabs: M = 4, moreLabel: N, mobileActions: P, hideWhenKeyboardOpen: te = !0, className: ne, open: re, onOpenChange: ie }) {
43
+ let F = o(), I = N ?? F("nav.more", "More"), L = ee(), R = E(), z = c(), { items: B } = l(), [V, H] = y(!1), U = re ?? V, W = ie ?? H, G = v(null), { tabs: K, more: q, hasMore: J } = _(() => p(B, M), [B, M]), ae = _(() => k(q, x, A), [
44
44
  q,
45
- O,
46
- k
47
- ]), X = !!j && j.length > 0, Z = J || X;
48
- m(() => {
45
+ x,
46
+ A
47
+ ]), Y = !!P && P.length > 0, X = J || Y, [oe, Z] = y(/* @__PURE__ */ new Set());
48
+ h(() => {
49
+ let e = u(q, R.pathname);
50
+ e.size !== 0 && Z((t) => {
51
+ let n = new Set(t), r = !1;
52
+ return e.forEach((e) => {
53
+ n.has(e) || (n.add(e), r = !0);
54
+ }), r ? n : t;
55
+ });
56
+ }, [q, R.pathname]);
57
+ let se = m((e) => {
58
+ Z((t) => {
59
+ let n = new Set(t);
60
+ return n.has(e) ? n.delete(e) : n.add(e), n;
61
+ });
62
+ }, []);
63
+ g(() => {
49
64
  let e = G.current;
50
65
  if (!e || typeof window > "u") return;
51
- let t = document.documentElement, n = () => t.style.setProperty(C, `${e.offsetHeight}px`);
66
+ let t = document.documentElement, n = () => t.style.setProperty(D, `${e.offsetHeight}px`);
52
67
  n();
53
68
  let r = typeof ResizeObserver < "u" ? new ResizeObserver(n) : null;
54
69
  return r?.observe(e), () => {
55
- r?.disconnect(), t.style.removeProperty(C);
70
+ r?.disconnect(), t.style.removeProperty(D);
56
71
  };
57
- }, []), p(() => {
72
+ }, []), h(() => {
58
73
  W(!1);
59
74
  }, [R.pathname, W]);
60
- let Q = f((e) => {
61
- w(), L(o(e, z));
62
- }, [L, z]), $ = h(() => !!J && q.some((e) => l(e, R.pathname)), [
75
+ let Q = m((e) => {
76
+ O(), L(s(e, z));
77
+ }, [L, z]), $ = _(() => !!J && q.some((e) => d(e, R.pathname)), [
63
78
  J,
64
79
  q,
65
80
  R.pathname
66
81
  ]);
67
- return /* @__PURE__ */ b(v, { children: [/* @__PURE__ */ b("nav", {
82
+ return /* @__PURE__ */ T(C, { children: [/* @__PURE__ */ T("nav", {
68
83
  ref: G,
69
84
  role: "tablist",
70
85
  "aria-label": F("nav.primaryNavigation", `${a} navigation`),
71
86
  "data-mobile-tabbar": "",
72
87
  "data-shell-chrome": "",
73
- "data-keyboard-keep": re ? void 0 : "",
74
- className: e("fixed inset-x-0 bottom-0 z-[60] flex items-stretch", "bg-bg-surface text-text-primary", M),
88
+ "data-keyboard-keep": te ? void 0 : "",
89
+ className: e("fixed inset-x-0 bottom-0 z-[60] flex items-stretch", "bg-bg-surface text-text-primary", ne),
75
90
  children: [K.map((t) => {
76
- let n = l(t, R.pathname);
77
- return /* @__PURE__ */ b("button", {
91
+ let n = d(t, R.pathname);
92
+ return /* @__PURE__ */ T("button", {
78
93
  type: "button",
79
94
  role: "tab",
80
95
  "aria-selected": n,
@@ -83,21 +98,21 @@ function E({ appName: a, logo: E, groupOrder: O = [], groupLabels: k = {}, maxTa
83
98
  "data-mobile-tab": t.id,
84
99
  className: e("mobile-tab relative flex min-w-0 flex-1 flex-col items-center justify-center gap-0.5", "text-text-muted transition-colors duration-150", n && "text-text-link"),
85
100
  onClick: () => {
86
- n && !t.children?.length || Q(u(t));
101
+ n && !t.children?.length || Q(f(t));
87
102
  },
88
- children: [/* @__PURE__ */ b("span", {
103
+ children: [/* @__PURE__ */ T("span", {
89
104
  className: "mobile-tab__icon relative inline-flex items-center justify-center",
90
105
  "aria-hidden": "true",
91
- children: [t.icon, t.badge ? /* @__PURE__ */ y("span", {
106
+ children: [t.icon, t.badge ? /* @__PURE__ */ w("span", {
92
107
  className: "absolute -top-1 -right-2 min-w-4 rounded-full bg-status-error-bg px-1 text-[10px] font-semibold leading-4 text-status-error-text",
93
108
  children: t.badge > 99 ? "99+" : t.badge
94
109
  }) : null]
95
- }), /* @__PURE__ */ y("span", {
110
+ }), /* @__PURE__ */ w("span", {
96
111
  className: "mobile-tab__label max-w-full truncate",
97
112
  children: t.label
98
113
  })]
99
114
  }, t.id);
100
- }), Z ? /* @__PURE__ */ b("button", {
115
+ }), X ? /* @__PURE__ */ T("button", {
101
116
  type: "button",
102
117
  role: "tab",
103
118
  "aria-selected": $,
@@ -108,66 +123,77 @@ function E({ appName: a, logo: E, groupOrder: O = [], groupLabels: k = {}, maxTa
108
123
  "data-mobile-tab": "__more",
109
124
  className: e("mobile-tab relative flex min-w-0 flex-1 flex-col items-center justify-center gap-0.5", "text-text-muted transition-colors duration-150", $ && "text-text-link"),
110
125
  onClick: () => {
111
- w(), W(!0);
126
+ O(), W(!0);
112
127
  },
113
- children: [/* @__PURE__ */ y("span", {
128
+ children: [/* @__PURE__ */ w("span", {
114
129
  className: "mobile-tab__icon inline-flex items-center justify-center",
115
130
  "aria-hidden": "true",
116
- children: /* @__PURE__ */ y(_, {})
117
- }), /* @__PURE__ */ y("span", {
131
+ children: /* @__PURE__ */ w(S, {})
132
+ }), /* @__PURE__ */ w("span", {
118
133
  className: "mobile-tab__label max-w-full truncate",
119
134
  children: I
120
135
  })]
121
136
  }) : null]
122
- }), Z ? /* @__PURE__ */ y(t, {
137
+ }), X ? /* @__PURE__ */ w(t, {
123
138
  open: U,
124
139
  onOpenChange: W,
125
- children: /* @__PURE__ */ b(n, {
140
+ children: /* @__PURE__ */ T(n, {
126
141
  "aria-label": I,
127
142
  "data-swipe-ignore": "",
128
- children: [/* @__PURE__ */ b(r, { children: [E ? /* @__PURE__ */ b("div", {
143
+ children: [/* @__PURE__ */ T(r, { children: [b ? /* @__PURE__ */ T("div", {
129
144
  className: "mb-1 flex items-center gap-2",
130
- children: [/* @__PURE__ */ y("div", {
145
+ children: [/* @__PURE__ */ w("div", {
131
146
  className: "flex size-8 flex-shrink-0 items-center justify-center",
132
- children: E
133
- }), /* @__PURE__ */ y("span", {
147
+ children: b
148
+ }), /* @__PURE__ */ w("span", {
134
149
  className: "text-heading-h4 font-semibold text-text-primary",
135
150
  children: a
136
151
  })]
137
- }) : null, /* @__PURE__ */ y(i, { children: I })] }), /* @__PURE__ */ b("div", {
152
+ }) : null, /* @__PURE__ */ w(i, { children: I })] }), /* @__PURE__ */ T("div", {
138
153
  className: "flex flex-col gap-4 pb-2",
139
154
  "data-mobile-tabbar-more": "",
140
- children: [Y.map((e) => /* @__PURE__ */ b("section", {
155
+ children: [ae.map((e) => /* @__PURE__ */ T("section", {
141
156
  "aria-label": e.label ?? void 0,
142
- children: [e.label ? /* @__PURE__ */ y("p", {
157
+ children: [e.label ? /* @__PURE__ */ w("p", {
143
158
  className: "mb-1 px-1 text-[11px] font-medium uppercase tracking-wider text-text-muted",
144
159
  children: e.label
145
- }) : null, /* @__PURE__ */ y("ul", {
160
+ }) : null, /* @__PURE__ */ w("ul", {
146
161
  className: "flex flex-col",
147
162
  children: e.items.map((e) => {
148
- let t = l(e, R.pathname);
149
- return /* @__PURE__ */ y("li", { children: /* @__PURE__ */ y(D, {
163
+ let t = d(e, R.pathname), n = !!e.children && e.children.length > 0, r = oe.has(e.id);
164
+ return /* @__PURE__ */ T("li", { children: [/* @__PURE__ */ w(j, {
150
165
  icon: e.icon,
151
166
  label: e.label,
152
167
  badge: e.badge,
153
168
  active: t,
154
- onSelect: () => Q(u(e))
155
- }) }, e.id);
169
+ expandable: n,
170
+ expanded: r,
171
+ onSelect: () => n ? se(e.id) : Q(f(e))
172
+ }), n && r ? /* @__PURE__ */ w("ul", {
173
+ className: "flex flex-col pl-7",
174
+ children: e.children.map((e) => /* @__PURE__ */ w("li", { children: /* @__PURE__ */ w(j, {
175
+ icon: e.icon,
176
+ label: e.label,
177
+ badge: e.badge,
178
+ active: d(e, R.pathname),
179
+ onSelect: () => Q(f(e))
180
+ }) }, e.id))
181
+ }) : null] }, e.id);
156
182
  })
157
183
  })]
158
- }, e.key || "__ungrouped")), X ? /* @__PURE__ */ b("section", {
184
+ }, e.key || "__ungrouped")), Y ? /* @__PURE__ */ T("section", {
159
185
  "aria-label": F("appShell.quickActions", "Quick Actions"),
160
- children: [/* @__PURE__ */ y("p", {
186
+ children: [/* @__PURE__ */ w("p", {
161
187
  className: "mb-1 px-1 text-[11px] font-medium uppercase tracking-wider text-text-muted",
162
188
  children: F("appShell.quickActions", "Quick Actions")
163
- }), /* @__PURE__ */ y("ul", {
189
+ }), /* @__PURE__ */ w("ul", {
164
190
  className: "flex flex-col",
165
- children: j?.map((e) => /* @__PURE__ */ y("li", { children: /* @__PURE__ */ y(D, {
191
+ children: P?.map((e) => /* @__PURE__ */ w("li", { children: /* @__PURE__ */ w(j, {
166
192
  icon: e.icon,
167
193
  label: e.label,
168
194
  active: !!e.isToggle && !!e.isActive,
169
195
  onSelect: () => {
170
- w(), e.onClick(), W(!1);
196
+ O(), e.onClick(), W(!1);
171
197
  }
172
198
  }) }, e.id))
173
199
  })]
@@ -176,23 +202,29 @@ function E({ appName: a, logo: E, groupOrder: O = [], groupLabels: k = {}, maxTa
176
202
  })
177
203
  }) : null] });
178
204
  }
179
- function D({ icon: t, label: n, badge: r, active: i, onSelect: a }) {
180
- return /* @__PURE__ */ b("button", {
205
+ function j({ icon: t, label: n, badge: r, active: i, onSelect: a, expandable: o, expanded: s }) {
206
+ return /* @__PURE__ */ T("button", {
181
207
  type: "button",
182
208
  onClick: a,
183
- "aria-current": i ? "page" : void 0,
209
+ "aria-current": !o && i ? "page" : void 0,
210
+ "aria-expanded": o ? s : void 0,
184
211
  className: e("flex w-full min-h-11 items-center gap-3 rounded-button px-3 py-2 text-left text-body-sm", "transition-colors duration-150", i ? "bg-[var(--color-accent-soft)] text-text-primary font-medium" : "text-text-secondary hover:bg-bg-sunken hover:text-text-primary"),
185
212
  children: [
186
- t ? /* @__PURE__ */ y("span", {
213
+ t ? /* @__PURE__ */ w("span", {
187
214
  className: "inline-flex size-5 shrink-0 items-center justify-center",
188
215
  "aria-hidden": "true",
189
216
  children: t
190
217
  }) : null,
191
- /* @__PURE__ */ y("span", {
218
+ /* @__PURE__ */ w("span", {
192
219
  className: "min-w-0 flex-1 truncate",
193
220
  children: n
194
221
  }),
195
- r ? /* @__PURE__ */ y("span", {
222
+ o ? /* @__PURE__ */ w("span", {
223
+ className: "inline-flex size-4 shrink-0 items-center justify-center text-text-muted",
224
+ "aria-hidden": "true",
225
+ children: w(s ? b : x, { className: "size-4" })
226
+ }) : null,
227
+ r ? /* @__PURE__ */ w("span", {
196
228
  className: "rounded-full bg-status-error-bg px-1.5 text-[10px] font-semibold leading-4 text-status-error-text",
197
229
  children: r > 99 ? "99+" : r
198
230
  }) : null
@@ -200,4 +232,4 @@ function D({ icon: t, label: n, badge: r, active: i, onSelect: a }) {
200
232
  });
201
233
  }
202
234
  //#endregion
203
- export { E as MobileTabBar };
235
+ export { A as MobileTabBar };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@burdenoff/fe-libs",
3
- "version": "2026.1027.7",
3
+ "version": "2026.1027.8",
4
4
  "description": "Burdenoff frontend primitives and domain libraries",
5
5
  "type": "module",
6
6
  "bin": {