@mt-gloss/ui 0.1.104 → 0.1.105

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,56 +1,117 @@
1
- import { jsx as s, jsxs as C } from "react/jsx-runtime";
2
- import { useSyncExternalStore as h, createContext as _, useContext as g, useReducer as P, useRef as d, useEffect as u, useMemo as v, useCallback as m, useLayoutEffect as y, useState as b } from "react";
3
- import { z as f } from "zod";
4
- const O = "(prefers-reduced-motion: reduce)";
5
- function I() {
6
- return typeof window > "u" || typeof window.matchMedia != "function" ? null : window.matchMedia(O);
1
+ import { jsx as c, jsxs as C } from "react/jsx-runtime";
2
+ import { motion as L } from "framer-motion";
3
+ import { useSyncExternalStore as O, createContext as T, useContext as S, useReducer as w, useRef as g, useEffect as d, useMemo as m, useCallback as I, useLayoutEffect as _, useState as N } from "react";
4
+ import { z as v } from "zod";
5
+ const x = "(prefers-reduced-motion: reduce)";
6
+ function b() {
7
+ return typeof window > "u" || typeof window.matchMedia != "function" ? null : window.matchMedia(x);
7
8
  }
8
- function L(e) {
9
- const n = I();
9
+ function H(e) {
10
+ const n = b();
10
11
  return n ? (n.addEventListener("change", e), () => {
11
12
  n.removeEventListener("change", e);
12
13
  }) : () => {
13
14
  };
14
15
  }
15
- function T() {
16
- const e = I();
16
+ function A() {
17
+ const e = b();
17
18
  return e ? e.matches : !1;
18
19
  }
19
- function D() {
20
+ function F() {
20
21
  return !1;
21
22
  }
22
- function w() {
23
- return h(L, T, D);
23
+ function P() {
24
+ return O(H, A, F);
24
25
  }
25
- const p = _(null);
26
- function N() {
27
- const e = g(p);
26
+ const R = {
27
+ threshold: "Threshold",
28
+ timeframe: "Timeframe",
29
+ slots: "Slots",
30
+ color: "Color"
31
+ };
32
+ function k({
33
+ dimensions: e,
34
+ activeTab: n,
35
+ onSelect: t,
36
+ reduced: r,
37
+ labels: l,
38
+ ariaLabel: a = "Settings dimensions"
39
+ }) {
40
+ const s = P(), i = r ?? s;
41
+ if (e.length < 2) return null;
42
+ const u = (o) => l?.[o] ?? R[o], E = (o, f) => {
43
+ o.key === "ArrowRight" ? (o.preventDefault(), t(e[(f + 1) % e.length])) : o.key === "ArrowLeft" ? (o.preventDefault(), t(e[(f - 1 + e.length) % e.length])) : o.key === "Home" ? (o.preventDefault(), t(e[0])) : o.key === "End" && (o.preventDefault(), t(e[e.length - 1]));
44
+ };
45
+ return /* @__PURE__ */ c(
46
+ "div",
47
+ {
48
+ role: "tablist",
49
+ "aria-label": a,
50
+ className: "settings-tab-strip",
51
+ children: e.map((o, f) => {
52
+ const p = n === o;
53
+ return /* @__PURE__ */ C(
54
+ "button",
55
+ {
56
+ role: "tab",
57
+ type: "button",
58
+ id: `settings-tab-${o}`,
59
+ "aria-selected": p,
60
+ "aria-controls": `settings-tabpanel-${o}`,
61
+ tabIndex: p ? 0 : -1,
62
+ className: `settings-tab-strip__tab${p ? " settings-tab-strip__tab--active" : ""}`,
63
+ onClick: () => t(o),
64
+ onKeyDown: (D) => E(D, f),
65
+ children: [
66
+ /* @__PURE__ */ c("span", { className: "settings-tab-strip__label", children: u(o) }),
67
+ p && !i && /* @__PURE__ */ c(
68
+ L.span,
69
+ {
70
+ layoutId: "settings-active-tab-indicator",
71
+ "data-layout-id": "settings-active-tab-indicator",
72
+ className: "settings-tab-strip__indicator",
73
+ "aria-hidden": "true",
74
+ transition: { type: "spring", stiffness: 380, damping: 30 }
75
+ }
76
+ )
77
+ ]
78
+ },
79
+ o
80
+ );
81
+ })
82
+ }
83
+ );
84
+ }
85
+ k.displayName = "SettingsTabStrip";
86
+ const h = T(null);
87
+ function B() {
88
+ const e = S(h);
28
89
  if (!e)
29
90
  throw new Error(
30
91
  "[panels] usePanelContext must be used inside <PanelProvider>. See @mt-gloss/ui/composites/panels."
31
92
  );
32
93
  return e;
33
94
  }
34
- function J() {
35
- return g(p);
95
+ function ie() {
96
+ return S(h);
36
97
  }
37
- const x = f.number().min(0).max(100), H = f.number().min(7).max(90), F = f.enum(["#1d6fd8", "#10b981", "#f59e0b", "#ef4444", "#8b5cf6"]);
38
- function B(e, n) {
98
+ const M = v.number().min(0).max(100), U = v.number().min(7).max(90), V = v.enum(["#1d6fd8", "#10b981", "#f59e0b", "#ef4444", "#8b5cf6"]);
99
+ function K(e, n) {
39
100
  if (e === "threshold") {
40
- const t = x.safeParse(n);
101
+ const t = M.safeParse(n);
41
102
  return t.success ? t.data : 80;
42
103
  }
43
104
  if (e === "timeframe") {
44
- const t = H.safeParse(n);
105
+ const t = U.safeParse(n);
45
106
  return t.success ? t.data : 30;
46
107
  }
47
108
  if (e === "accent") {
48
- const t = F.safeParse(n);
109
+ const t = V.safeParse(n);
49
110
  return t.success ? t.data : null;
50
111
  }
51
112
  return n;
52
113
  }
53
- const R = {
114
+ const j = {
54
115
  activePanelId: null,
55
116
  activeTrigger: null,
56
117
  bellCutoutOpen: !1,
@@ -60,8 +121,8 @@ const R = {
60
121
  bufferByCard: {},
61
122
  lastClose: null,
62
123
  pendingSideEffects: []
63
- }, E = /* @__PURE__ */ new Set(["settings"]);
64
- function A(e, n) {
124
+ }, y = /* @__PURE__ */ new Set(["settings"]);
125
+ function q(e, n) {
65
126
  if (e == null || e.kind !== n.kind) return !1;
66
127
  switch (e.kind) {
67
128
  case "bell":
@@ -76,7 +137,7 @@ function A(e, n) {
76
137
  return e.action === n.action && e.blockedCardId === n.blockedCardId && e.activeCardId === n.activeCardId;
77
138
  }
78
139
  }
79
- function k(e, n) {
140
+ function z(e, n) {
80
141
  switch (n.type) {
81
142
  case "OPEN_PANEL": {
82
143
  if (e.activePanelId && e.isDirty)
@@ -94,7 +155,7 @@ function k(e, n) {
94
155
  }
95
156
  ]
96
157
  };
97
- if (e.activePanelId === n.panelId && A(e.activeTrigger, n.trigger))
158
+ if (e.activePanelId === n.panelId && q(e.activeTrigger, n.trigger))
98
159
  return e;
99
160
  const t = e.activePanelId != null ? [
100
161
  {
@@ -119,12 +180,12 @@ function k(e, n) {
119
180
  case "CLOSE_PANEL": {
120
181
  if (e.activePanelId == null)
121
182
  return e;
122
- const t = e.activePanelId, r = e.activeTrigger?.cardId ?? null, l = r != null ? e.bufferByCard[r] : void 0, o = e.isDirty ? n.reason === "apply-button" ? r != null && l != null ? [
183
+ const t = e.activePanelId, r = e.activeTrigger?.cardId ?? null, l = r != null ? e.bufferByCard[r] : void 0, a = e.isDirty ? n.reason === "apply-button" ? r != null && l != null ? [
123
184
  {
124
185
  type: "COMMIT_BUFFER",
125
186
  payload: { cardId: r, delta: l }
126
187
  }
127
- ] : [{ type: "COMMIT_BUFFER" }] : [{ type: "DISCARD_BUFFER" }] : [], c = r != null && l != null ? (() => {
188
+ ] : [{ type: "COMMIT_BUFFER" }] : [{ type: "DISCARD_BUFFER" }] : [], s = r != null && l != null ? (() => {
128
189
  const i = { ...e.bufferByCard };
129
190
  return delete i[r], i;
130
191
  })() : e.bufferByCard;
@@ -137,9 +198,9 @@ function k(e, n) {
137
198
  // Phase 16 P2 CC-17 — session ends on panel close (apply or discard)
138
199
  lockHint: null,
139
200
  // closing clears any active lockHint (dirty-buffer condition gone)
140
- bufferByCard: c,
201
+ bufferByCard: s,
141
202
  lastClose: { panelId: t, reason: n.reason },
142
- pendingSideEffects: [...e.pendingSideEffects, ...o]
203
+ pendingSideEffects: [...e.pendingSideEffects, ...a]
143
204
  };
144
205
  }
145
206
  case "OPEN_BELL_CUTOUT":
@@ -156,7 +217,7 @@ function k(e, n) {
156
217
  case "CLOSE_BELL_CUTOUT":
157
218
  return e.bellCutoutOpen ? { ...e, bellCutoutOpen: !1 } : e;
158
219
  case "SET_BUFFER_VALUE": {
159
- if (e.activePanelId == null || !E.has(e.activePanelId))
220
+ if (e.activePanelId == null || !y.has(e.activePanelId))
160
221
  return {
161
222
  ...e,
162
223
  pendingSideEffects: [
@@ -164,13 +225,13 @@ function k(e, n) {
164
225
  { type: "INVALID_DISPATCH", reason: "no-buffer-panel" }
165
226
  ]
166
227
  };
167
- const t = e.bufferByCard[n.cardId], r = t == null, l = B(n.key, n.value);
228
+ const t = e.bufferByCard[n.cardId], r = t == null, l = K(n.key, n.value);
168
229
  if (!r && t.changes[n.key] === l)
169
230
  return e;
170
- const c = { kind: "settings", changes: {
231
+ const s = { kind: "settings", changes: {
171
232
  ...t?.kind === "settings" ? t.changes : {},
172
233
  [n.key]: l
173
- } }, i = { ...e.bufferByCard, [n.cardId]: c }, a = r ? [
234
+ } }, i = { ...e.bufferByCard, [n.cardId]: s }, u = r ? [
174
235
  {
175
236
  type: "SCHEDULE_TIMER",
176
237
  ms: 0,
@@ -180,7 +241,7 @@ function k(e, n) {
180
241
  return {
181
242
  ...e,
182
243
  bufferByCard: i,
183
- pendingSideEffects: [...e.pendingSideEffects, ...a]
244
+ pendingSideEffects: [...e.pendingSideEffects, ...u]
184
245
  };
185
246
  }
186
247
  case "CLEAR_BUFFER": {
@@ -188,7 +249,7 @@ function k(e, n) {
188
249
  return e;
189
250
  const r = Object.keys(e.bufferByCard).length === 1, l = { ...e.bufferByCard };
190
251
  delete l[n.cardId];
191
- const o = r && e.isDirty ? [
252
+ const a = r && e.isDirty ? [
192
253
  {
193
254
  type: "SCHEDULE_TIMER",
194
255
  ms: 0,
@@ -198,11 +259,11 @@ function k(e, n) {
198
259
  return {
199
260
  ...e,
200
261
  bufferByCard: l,
201
- pendingSideEffects: [...e.pendingSideEffects, ...o]
262
+ pendingSideEffects: [...e.pendingSideEffects, ...a]
202
263
  };
203
264
  }
204
265
  case "BUFFER_BECOMES_DIRTY":
205
- return e.activePanelId == null || !E.has(e.activePanelId) ? {
266
+ return e.activePanelId == null || !y.has(e.activePanelId) ? {
206
267
  ...e,
207
268
  pendingSideEffects: [
208
269
  ...e.pendingSideEffects,
@@ -238,16 +299,16 @@ function k(e, n) {
238
299
  return e;
239
300
  }
240
301
  }
241
- function M(e) {
302
+ function Y(e) {
242
303
  return e.activePanelId === "notification-center" ? "notif-center" : e.activePanelId != null && e.bellCutoutOpen ? e.isDirty ? "panel-dirty+cutout" : "panel-clean+cutout" : e.activePanelId != null ? e.isDirty ? "panel-dirty" : "panel-clean" : e.bellCutoutOpen ? "bell-cutout-only" : "idle";
243
304
  }
244
- function U() {
245
- const [e, n] = P(k, R), t = d([]), r = d(null);
246
- u(() => () => {
305
+ function $() {
306
+ const [e, n] = w(z, j), t = g([]), r = g(null);
307
+ d(() => () => {
247
308
  r.current != null && (window.clearTimeout(r.current), r.current = null);
248
- }, []), u(() => {
249
- const c = e.pendingSideEffects.length;
250
- if (c !== 0) {
309
+ }, []), d(() => {
310
+ const s = e.pendingSideEffects.length;
311
+ if (s !== 0) {
251
312
  for (const i of e.pendingSideEffects)
252
313
  i.type === "SCHEDULE_TIMER" ? (r.current != null && window.clearTimeout(r.current), r.current = window.setTimeout(() => {
253
314
  r.current = null, n(i.action);
@@ -260,11 +321,11 @@ function U() {
260
321
  note: "F22: mutex-handoff synthetic close-log entry"
261
322
  }
262
323
  ] : i.type === "INVALID_DISPATCH" && process.env.NODE_ENV !== "production" && console.warn("[panels] INVALID_DISPATCH:", i.reason);
263
- n({ type: "DRAIN_SIDE_EFFECTS", count: c });
324
+ n({ type: "DRAIN_SIDE_EFFECTS", count: s });
264
325
  }
265
- }, [e.pendingSideEffects, n]), u(() => {
326
+ }, [e.pendingSideEffects, n]), d(() => {
266
327
  if (!e.lastClose) return;
267
- const c = {
328
+ const s = {
268
329
  panelId: e.lastClose.panelId,
269
330
  reason: e.lastClose.reason,
270
331
  at: Date.now(),
@@ -272,29 +333,29 @@ function U() {
272
333
  };
273
334
  t.current = [
274
335
  ...t.current.slice(-99),
275
- c
336
+ s
276
337
  ];
277
338
  }, [e.lastClose]);
278
- const l = v(
279
- () => M(e),
339
+ const l = m(
340
+ () => Y(e),
280
341
  [e.activePanelId, e.bellCutoutOpen, e.isDirty]
281
- ), o = m(() => t.current.slice(), []);
282
- return { state: e, surfaceState: l, dispatch: n, getCloseLog: o };
342
+ ), a = I(() => t.current.slice(), []);
343
+ return { state: e, surfaceState: l, dispatch: n, getCloseLog: a };
283
344
  }
284
- function X({ children: e }) {
285
- const n = U(), t = v(
345
+ function le({ children: e }) {
346
+ const n = $(), t = m(
286
347
  () => n,
287
348
  // Re-publish only when one of the four coordinator fields changes identity.
288
349
  // dispatch + getCloseLog are stable. state + surfaceState change on dispatch.
289
350
  [n.state, n.surfaceState, n.dispatch, n.getCloseLog]
290
351
  );
291
- return /* @__PURE__ */ s(p.Provider, { value: t, children: e });
352
+ return /* @__PURE__ */ c(h.Provider, { value: t, children: e });
292
353
  }
293
- const V = {
354
+ const Q = {
294
355
  position: "relative",
295
356
  pointerEvents: "auto"
296
357
  };
297
- function K({ children: e, onClose: n, footer: t }) {
358
+ function W({ children: e, onClose: n, footer: t }) {
298
359
  return /* @__PURE__ */ C(
299
360
  "div",
300
361
  {
@@ -302,9 +363,9 @@ function K({ children: e, onClose: n, footer: t }) {
302
363
  role: "dialog",
303
364
  "aria-modal": "true",
304
365
  className: "gloss-panel-chrome",
305
- style: V,
366
+ style: Q,
306
367
  children: [
307
- /* @__PURE__ */ s("div", { className: "gloss-panel-chrome__header", children: /* @__PURE__ */ s(
368
+ /* @__PURE__ */ c("div", { className: "gloss-panel-chrome__header", children: /* @__PURE__ */ c(
308
369
  "button",
309
370
  {
310
371
  id: "panel-close",
@@ -315,13 +376,13 @@ function K({ children: e, onClose: n, footer: t }) {
315
376
  children: "×"
316
377
  }
317
378
  ) }),
318
- /* @__PURE__ */ s("div", { className: "gloss-panel-chrome__body", children: e }),
319
- t != null && /* @__PURE__ */ s("div", { className: "gloss-panel-chrome__footer", children: t })
379
+ /* @__PURE__ */ c("div", { className: "gloss-panel-chrome__body", children: e }),
380
+ t != null && /* @__PURE__ */ c("div", { className: "gloss-panel-chrome__footer", children: t })
320
381
  ]
321
382
  }
322
383
  );
323
384
  }
324
- function j(e) {
385
+ function G(e) {
325
386
  if (process.env.NODE_ENV === "production" || !e || !e.parentElement) return;
326
387
  const n = e.parentElement, t = window.getComputedStyle(n);
327
388
  t.perspective === "none" && console.warn(
@@ -332,37 +393,37 @@ function j(e) {
332
393
  n
333
394
  );
334
395
  }
335
- function q({ isOpen: e, children: n }) {
336
- const t = w(), r = d(null);
337
- y(() => {
338
- j(r.current);
396
+ function J({ isOpen: e, children: n }) {
397
+ const t = P(), r = g(null);
398
+ _(() => {
399
+ G(r.current);
339
400
  }, []);
340
- const [l, o] = b(!1);
341
- u(() => {
401
+ const [l, a] = N(!1);
402
+ d(() => {
342
403
  if (!e) {
343
- o(!1);
404
+ a(!1);
344
405
  return;
345
406
  }
346
- const i = requestAnimationFrame(() => o(!0));
407
+ const i = requestAnimationFrame(() => a(!0));
347
408
  return () => cancelAnimationFrame(i);
348
409
  }, [e]);
349
- const c = [
410
+ const s = [
350
411
  "gloss-panel-mount",
351
412
  l ? "has-panel" : "",
352
413
  t ? "reduced-motion" : ""
353
414
  ].filter(Boolean).join(" ");
354
- return /* @__PURE__ */ s(
415
+ return /* @__PURE__ */ c(
355
416
  "div",
356
417
  {
357
418
  ref: r,
358
- className: c,
419
+ className: s,
359
420
  "data-mount": "panel",
360
421
  "data-open": e ? "true" : "false",
361
422
  children: n
362
423
  }
363
424
  );
364
425
  }
365
- const z = {
426
+ const X = {
366
427
  position: "fixed",
367
428
  top: 0,
368
429
  left: 0,
@@ -373,7 +434,7 @@ const z = {
373
434
  overflow: "visible",
374
435
  pointerEvents: "none",
375
436
  zIndex: 55
376
- }, Y = {
437
+ }, Z = {
377
438
  position: "fixed",
378
439
  top: "var(--tb-h, 60px)",
379
440
  left: 0,
@@ -389,57 +450,57 @@ const z = {
389
450
  pointerEvents: "none",
390
451
  background: "rgba(0, 0, 0, 0.04)"
391
452
  };
392
- function Z({ panelComponents: e }) {
393
- const { state: n, dispatch: t, getCloseLog: r } = N(), l = n.activePanelId ? e[n.activePanelId] : null;
453
+ function oe({ panelComponents: e }) {
454
+ const { state: n, dispatch: t, getCloseLog: r } = B(), l = n.activePanelId ? e[n.activePanelId] : null;
394
455
  n.activePanelId && !l && process.env.NODE_ENV !== "production" && console.error(
395
456
  "[panels] No panel component registered for activePanelId:",
396
457
  n.activePanelId
397
- ), u(() => {
458
+ ), d(() => {
398
459
  if (n.activePanelId == null) return;
399
- function a(S) {
400
- S.key === "Escape" && t({ type: "CLOSE_PANEL", reason: "escape-key" });
460
+ function u(E) {
461
+ E.key === "Escape" && t({ type: "CLOSE_PANEL", reason: "escape-key" });
401
462
  }
402
- return document.addEventListener("keydown", a), () => {
403
- document.removeEventListener("keydown", a);
463
+ return document.addEventListener("keydown", u), () => {
464
+ document.removeEventListener("keydown", u);
404
465
  };
405
466
  }, [n.activePanelId, t]);
406
- const o = d(n);
407
- y(() => {
408
- o.current = n;
409
- }), u(() => {
467
+ const a = g(n);
468
+ _(() => {
469
+ a.current = n;
470
+ }), d(() => {
410
471
  if (process.env.NODE_ENV === "production") return;
411
- const a = window;
412
- return a.__panelsHostHandle && console.warn("[panels] multiple PanelHost/PanelHostShell instances mounted; dev handle is unreliable"), a.__panelsHostHandle = {
472
+ const u = window;
473
+ return u.__panelsHostHandle && console.warn("[panels] multiple PanelHost/PanelHostShell instances mounted; dev handle is unreliable"), u.__panelsHostHandle = {
413
474
  dispatch: t,
414
- getState: () => o.current,
475
+ getState: () => a.current,
415
476
  getCloseLog: r
416
477
  }, () => {
417
- a.__panelsHostHandle?.dispatch === t && delete a.__panelsHostHandle;
478
+ u.__panelsHostHandle?.dispatch === t && delete u.__panelsHostHandle;
418
479
  };
419
480
  }, [t, r]);
420
- const c = m(() => {
481
+ const s = I(() => {
421
482
  t({ type: "CLOSE_PANEL", reason: "nav-escape-hatch" });
422
483
  }, [t]), i = n.activePanelId != null && l != null;
423
- return /* @__PURE__ */ C("div", { "data-panel-host": "true", style: z, children: [
424
- i && /* @__PURE__ */ s(
484
+ return /* @__PURE__ */ C("div", { "data-panel-host": "true", style: X, children: [
485
+ i && /* @__PURE__ */ c(
425
486
  "div",
426
487
  {
427
488
  "data-panel-scrim": "true",
428
- style: Y,
429
- onClick: c
489
+ style: Z,
490
+ onClick: s
430
491
  }
431
492
  ),
432
- /* @__PURE__ */ s(q, { isOpen: i, children: i && /* @__PURE__ */ s(
433
- K,
493
+ /* @__PURE__ */ c(J, { isOpen: i, children: i && /* @__PURE__ */ c(
494
+ W,
434
495
  {
435
496
  isOpen: !0,
436
497
  onClose: () => t({ type: "CLOSE_PANEL", reason: "header-x" }),
437
- children: /* @__PURE__ */ s(l, { isOpen: !0 })
498
+ children: /* @__PURE__ */ c(l, { isOpen: !0 })
438
499
  }
439
500
  ) })
440
501
  ] });
441
502
  }
442
- const $ = {
503
+ const ae = {
443
504
  "apply-button": !0,
444
505
  // the ONLY commit reason
445
506
  "cancel-button": !1,
@@ -453,16 +514,17 @@ const $ = {
453
514
  "nav-escape-hatch": !1
454
515
  };
455
516
  export {
456
- $ as C,
457
- X as P,
458
- J as a,
459
- N as b,
460
- Z as c,
461
- K as d,
462
- U as e,
463
- M as f,
464
- q as g,
465
- R as i,
466
- k as r,
467
- w as u
517
+ ae as C,
518
+ le as P,
519
+ k as S,
520
+ B as a,
521
+ oe as b,
522
+ W as c,
523
+ $ as d,
524
+ Y as e,
525
+ P as f,
526
+ J as g,
527
+ j as i,
528
+ z as r,
529
+ ie as u
468
530
  };