@mt-gloss/ui 0.1.102 → 0.1.104

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,28 +1,67 @@
1
- import { jsx as a, jsxs as E } from "react/jsx-runtime";
2
- import { createContext as S, useContext as g, useReducer as m, useRef as d, useEffect as u, useMemo as C, useCallback as v, useSyncExternalStore as _, useLayoutEffect as I, useState as P } from "react";
3
- const f = S(null);
4
- function O() {
5
- const e = g(f);
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);
7
+ }
8
+ function L(e) {
9
+ const n = I();
10
+ return n ? (n.addEventListener("change", e), () => {
11
+ n.removeEventListener("change", e);
12
+ }) : () => {
13
+ };
14
+ }
15
+ function T() {
16
+ const e = I();
17
+ return e ? e.matches : !1;
18
+ }
19
+ function D() {
20
+ return !1;
21
+ }
22
+ function w() {
23
+ return h(L, T, D);
24
+ }
25
+ const p = _(null);
26
+ function N() {
27
+ const e = g(p);
6
28
  if (!e)
7
29
  throw new Error(
8
30
  "[panels] usePanelContext must be used inside <PanelProvider>. See @mt-gloss/ui/composites/panels."
9
31
  );
10
32
  return e;
11
33
  }
12
- function q() {
13
- return g(f);
34
+ function J() {
35
+ return g(p);
36
+ }
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) {
39
+ if (e === "threshold") {
40
+ const t = x.safeParse(n);
41
+ return t.success ? t.data : 80;
42
+ }
43
+ if (e === "timeframe") {
44
+ const t = H.safeParse(n);
45
+ return t.success ? t.data : 30;
46
+ }
47
+ if (e === "accent") {
48
+ const t = F.safeParse(n);
49
+ return t.success ? t.data : null;
50
+ }
51
+ return n;
14
52
  }
15
- const L = {
53
+ const R = {
16
54
  activePanelId: null,
17
55
  activeTrigger: null,
18
56
  bellCutoutOpen: !1,
19
57
  isDirty: !1,
58
+ dirtySessionCount: 0,
20
59
  lockHint: null,
21
60
  bufferByCard: {},
22
61
  lastClose: null,
23
62
  pendingSideEffects: []
24
- }, p = /* @__PURE__ */ new Set(["settings"]);
25
- function b(e, n) {
63
+ }, E = /* @__PURE__ */ new Set(["settings"]);
64
+ function A(e, n) {
26
65
  if (e == null || e.kind !== n.kind) return !1;
27
66
  switch (e.kind) {
28
67
  case "bell":
@@ -33,9 +72,11 @@ function b(e, n) {
33
72
  return e.sectionIndex === n.sectionIndex && e.cellPosition.row === n.cellPosition.row && e.cellPosition.col === n.cellPosition.col;
34
73
  case "manage-pages-action":
35
74
  return e.global === n.global && e.align === n.align;
75
+ case "layout-action-blocked":
76
+ return e.action === n.action && e.blockedCardId === n.blockedCardId && e.activeCardId === n.activeCardId;
36
77
  }
37
78
  }
38
- function T(e, n) {
79
+ function k(e, n) {
39
80
  switch (n.type) {
40
81
  case "OPEN_PANEL": {
41
82
  if (e.activePanelId && e.isDirty)
@@ -53,7 +94,7 @@ function T(e, n) {
53
94
  }
54
95
  ]
55
96
  };
56
- if (e.activePanelId === n.panelId && b(e.activeTrigger, n.trigger))
97
+ if (e.activePanelId === n.panelId && A(e.activeTrigger, n.trigger))
57
98
  return e;
58
99
  const t = e.activePanelId != null ? [
59
100
  {
@@ -67,6 +108,8 @@ function T(e, n) {
67
108
  activePanelId: n.panelId,
68
109
  activeTrigger: n.trigger,
69
110
  isDirty: !1,
111
+ dirtySessionCount: 0,
112
+ // Phase 16 P2 CC-17 — fresh open starts a clean session
70
113
  bellCutoutOpen: r ? !1 : e.bellCutoutOpen,
71
114
  lastClose: null,
72
115
  // reset on fresh open
@@ -76,20 +119,22 @@ function T(e, n) {
76
119
  case "CLOSE_PANEL": {
77
120
  if (e.activePanelId == null)
78
121
  return e;
79
- const t = e.activePanelId, r = e.activeTrigger?.cardId ?? null, i = r != null ? e.bufferByCard[r] : void 0, o = e.isDirty ? n.reason === "apply-button" ? r != null && i != null ? [
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 ? [
80
123
  {
81
124
  type: "COMMIT_BUFFER",
82
- payload: { cardId: r, delta: i }
125
+ payload: { cardId: r, delta: l }
83
126
  }
84
- ] : [{ type: "COMMIT_BUFFER" }] : [{ type: "DISCARD_BUFFER" }] : [], c = r != null && i != null ? (() => {
85
- const l = { ...e.bufferByCard };
86
- return delete l[r], l;
127
+ ] : [{ type: "COMMIT_BUFFER" }] : [{ type: "DISCARD_BUFFER" }] : [], c = r != null && l != null ? (() => {
128
+ const i = { ...e.bufferByCard };
129
+ return delete i[r], i;
87
130
  })() : e.bufferByCard;
88
131
  return {
89
132
  ...e,
90
133
  activePanelId: null,
91
134
  activeTrigger: null,
92
135
  isDirty: !1,
136
+ dirtySessionCount: 0,
137
+ // Phase 16 P2 CC-17 — session ends on panel close (apply or discard)
93
138
  lockHint: null,
94
139
  // closing clears any active lockHint (dirty-buffer condition gone)
95
140
  bufferByCard: c,
@@ -111,7 +156,7 @@ function T(e, n) {
111
156
  case "CLOSE_BELL_CUTOUT":
112
157
  return e.bellCutoutOpen ? { ...e, bellCutoutOpen: !1 } : e;
113
158
  case "SET_BUFFER_VALUE": {
114
- if (e.activePanelId == null || !p.has(e.activePanelId))
159
+ if (e.activePanelId == null || !E.has(e.activePanelId))
115
160
  return {
116
161
  ...e,
117
162
  pendingSideEffects: [
@@ -119,13 +164,13 @@ function T(e, n) {
119
164
  { type: "INVALID_DISPATCH", reason: "no-buffer-panel" }
120
165
  ]
121
166
  };
122
- const t = e.bufferByCard[n.cardId], r = t == null;
123
- if (!r && t.changes[n.key] === n.value)
167
+ const t = e.bufferByCard[n.cardId], r = t == null, l = B(n.key, n.value);
168
+ if (!r && t.changes[n.key] === l)
124
169
  return e;
125
- const o = { kind: "settings", changes: {
170
+ const c = { kind: "settings", changes: {
126
171
  ...t?.kind === "settings" ? t.changes : {},
127
- [n.key]: n.value
128
- } }, c = { ...e.bufferByCard, [n.cardId]: o }, l = r ? [
172
+ [n.key]: l
173
+ } }, i = { ...e.bufferByCard, [n.cardId]: c }, a = r ? [
129
174
  {
130
175
  type: "SCHEDULE_TIMER",
131
176
  ms: 0,
@@ -134,15 +179,15 @@ function T(e, n) {
134
179
  ] : [];
135
180
  return {
136
181
  ...e,
137
- bufferByCard: c,
138
- pendingSideEffects: [...e.pendingSideEffects, ...l]
182
+ bufferByCard: i,
183
+ pendingSideEffects: [...e.pendingSideEffects, ...a]
139
184
  };
140
185
  }
141
186
  case "CLEAR_BUFFER": {
142
187
  if (e.bufferByCard[n.cardId] == null)
143
188
  return e;
144
- const r = Object.keys(e.bufferByCard).length === 1, i = { ...e.bufferByCard };
145
- delete i[n.cardId];
189
+ const r = Object.keys(e.bufferByCard).length === 1, l = { ...e.bufferByCard };
190
+ delete l[n.cardId];
146
191
  const o = r && e.isDirty ? [
147
192
  {
148
193
  type: "SCHEDULE_TIMER",
@@ -152,20 +197,20 @@ function T(e, n) {
152
197
  ] : [];
153
198
  return {
154
199
  ...e,
155
- bufferByCard: i,
200
+ bufferByCard: l,
156
201
  pendingSideEffects: [...e.pendingSideEffects, ...o]
157
202
  };
158
203
  }
159
204
  case "BUFFER_BECOMES_DIRTY":
160
- return e.activePanelId == null || !p.has(e.activePanelId) ? {
205
+ return e.activePanelId == null || !E.has(e.activePanelId) ? {
161
206
  ...e,
162
207
  pendingSideEffects: [
163
208
  ...e.pendingSideEffects,
164
209
  { type: "INVALID_DISPATCH", reason: "no-buffer-panel" }
165
210
  ]
166
- } : e.isDirty ? e : { ...e, isDirty: !0 };
211
+ } : e.isDirty ? e : { ...e, isDirty: !0, dirtySessionCount: e.dirtySessionCount + 1 };
167
212
  case "BUFFER_BECOMES_CLEAN":
168
- return e.isDirty ? { ...e, isDirty: !1 } : e;
213
+ return e.isDirty ? { ...e, isDirty: !1, dirtySessionCount: 0 } : e;
169
214
  case "SET_LOCK_HINT":
170
215
  return {
171
216
  ...e,
@@ -193,28 +238,28 @@ function T(e, n) {
193
238
  return e;
194
239
  }
195
240
  }
196
- function D(e) {
241
+ function M(e) {
197
242
  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";
198
243
  }
199
- function w() {
200
- const [e, n] = m(T, L), t = d([]), r = d(null);
244
+ function U() {
245
+ const [e, n] = P(k, R), t = d([]), r = d(null);
201
246
  u(() => () => {
202
247
  r.current != null && (window.clearTimeout(r.current), r.current = null);
203
248
  }, []), u(() => {
204
249
  const c = e.pendingSideEffects.length;
205
250
  if (c !== 0) {
206
- for (const l of e.pendingSideEffects)
207
- l.type === "SCHEDULE_TIMER" ? (r.current != null && window.clearTimeout(r.current), r.current = window.setTimeout(() => {
208
- r.current = null, n(l.action);
209
- }, Math.max(0, l.ms))) : l.type === "SET_LOCK_HINT" ? n({ type: "SET_LOCK_HINT", hint: l.hint }) : l.type === "HANDOFF_CLOSE" ? t.current = [
251
+ for (const i of e.pendingSideEffects)
252
+ i.type === "SCHEDULE_TIMER" ? (r.current != null && window.clearTimeout(r.current), r.current = window.setTimeout(() => {
253
+ r.current = null, n(i.action);
254
+ }, Math.max(0, i.ms))) : i.type === "SET_LOCK_HINT" ? n({ type: "SET_LOCK_HINT", hint: i.hint }) : i.type === "HANDOFF_CLOSE" ? t.current = [
210
255
  ...t.current.slice(-99),
211
256
  {
212
- panelId: l.previousPanelId,
257
+ panelId: i.previousPanelId,
213
258
  reason: "mutex-handoff",
214
259
  at: Date.now(),
215
260
  note: "F22: mutex-handoff synthetic close-log entry"
216
261
  }
217
- ] : l.type === "INVALID_DISPATCH" && process.env.NODE_ENV !== "production" && console.warn("[panels] INVALID_DISPATCH:", l.reason);
262
+ ] : i.type === "INVALID_DISPATCH" && process.env.NODE_ENV !== "production" && console.warn("[panels] INVALID_DISPATCH:", i.reason);
218
263
  n({ type: "DRAIN_SIDE_EFFECTS", count: c });
219
264
  }
220
265
  }, [e.pendingSideEffects, n]), u(() => {
@@ -230,57 +275,36 @@ function w() {
230
275
  c
231
276
  ];
232
277
  }, [e.lastClose]);
233
- const i = C(
234
- () => D(e),
278
+ const l = v(
279
+ () => M(e),
235
280
  [e.activePanelId, e.bellCutoutOpen, e.isDirty]
236
- ), o = v(() => t.current.slice(), []);
237
- return { state: e, surfaceState: i, dispatch: n, getCloseLog: o };
281
+ ), o = m(() => t.current.slice(), []);
282
+ return { state: e, surfaceState: l, dispatch: n, getCloseLog: o };
238
283
  }
239
- function Y({ children: e }) {
240
- const n = w(), t = C(
284
+ function X({ children: e }) {
285
+ const n = U(), t = v(
241
286
  () => n,
242
287
  // Re-publish only when one of the four coordinator fields changes identity.
243
288
  // dispatch + getCloseLog are stable. state + surfaceState change on dispatch.
244
289
  [n.state, n.surfaceState, n.dispatch, n.getCloseLog]
245
290
  );
246
- return /* @__PURE__ */ a(f.Provider, { value: t, children: e });
247
- }
248
- const N = "(prefers-reduced-motion: reduce)";
249
- function y() {
250
- return typeof window > "u" || typeof window.matchMedia != "function" ? null : window.matchMedia(N);
251
- }
252
- function x(e) {
253
- const n = y();
254
- return n ? (n.addEventListener("change", e), () => {
255
- n.removeEventListener("change", e);
256
- }) : () => {
257
- };
258
- }
259
- function H() {
260
- const e = y();
261
- return e ? e.matches : !1;
262
- }
263
- function F() {
264
- return !1;
265
- }
266
- function R() {
267
- return _(x, H, F);
291
+ return /* @__PURE__ */ s(p.Provider, { value: t, children: e });
268
292
  }
269
- const B = {
293
+ const V = {
270
294
  position: "relative",
271
295
  pointerEvents: "auto"
272
296
  };
273
- function A({ children: e, onClose: n, footer: t }) {
274
- return /* @__PURE__ */ E(
297
+ function K({ children: e, onClose: n, footer: t }) {
298
+ return /* @__PURE__ */ C(
275
299
  "div",
276
300
  {
277
301
  "data-chrome": "panel",
278
302
  role: "dialog",
279
303
  "aria-modal": "true",
280
304
  className: "gloss-panel-chrome",
281
- style: B,
305
+ style: V,
282
306
  children: [
283
- /* @__PURE__ */ a("div", { className: "gloss-panel-chrome__header", children: /* @__PURE__ */ a(
307
+ /* @__PURE__ */ s("div", { className: "gloss-panel-chrome__header", children: /* @__PURE__ */ s(
284
308
  "button",
285
309
  {
286
310
  id: "panel-close",
@@ -291,13 +315,13 @@ function A({ children: e, onClose: n, footer: t }) {
291
315
  children: "×"
292
316
  }
293
317
  ) }),
294
- /* @__PURE__ */ a("div", { className: "gloss-panel-chrome__body", children: e }),
295
- t != null && /* @__PURE__ */ a("div", { className: "gloss-panel-chrome__footer", children: t })
318
+ /* @__PURE__ */ s("div", { className: "gloss-panel-chrome__body", children: e }),
319
+ t != null && /* @__PURE__ */ s("div", { className: "gloss-panel-chrome__footer", children: t })
296
320
  ]
297
321
  }
298
322
  );
299
323
  }
300
- function k(e) {
324
+ function j(e) {
301
325
  if (process.env.NODE_ENV === "production" || !e || !e.parentElement) return;
302
326
  const n = e.parentElement, t = window.getComputedStyle(n);
303
327
  t.perspective === "none" && console.warn(
@@ -308,26 +332,26 @@ function k(e) {
308
332
  n
309
333
  );
310
334
  }
311
- function M({ isOpen: e, children: n }) {
312
- const t = R(), r = d(null);
313
- I(() => {
314
- k(r.current);
335
+ function q({ isOpen: e, children: n }) {
336
+ const t = w(), r = d(null);
337
+ y(() => {
338
+ j(r.current);
315
339
  }, []);
316
- const [i, o] = P(!1);
340
+ const [l, o] = b(!1);
317
341
  u(() => {
318
342
  if (!e) {
319
343
  o(!1);
320
344
  return;
321
345
  }
322
- const l = requestAnimationFrame(() => o(!0));
323
- return () => cancelAnimationFrame(l);
346
+ const i = requestAnimationFrame(() => o(!0));
347
+ return () => cancelAnimationFrame(i);
324
348
  }, [e]);
325
349
  const c = [
326
350
  "gloss-panel-mount",
327
- i ? "has-panel" : "",
351
+ l ? "has-panel" : "",
328
352
  t ? "reduced-motion" : ""
329
353
  ].filter(Boolean).join(" ");
330
- return /* @__PURE__ */ a(
354
+ return /* @__PURE__ */ s(
331
355
  "div",
332
356
  {
333
357
  ref: r,
@@ -338,7 +362,7 @@ function M({ isOpen: e, children: n }) {
338
362
  }
339
363
  );
340
364
  }
341
- const U = {
365
+ const z = {
342
366
  position: "fixed",
343
367
  top: 0,
344
368
  left: 0,
@@ -349,7 +373,7 @@ const U = {
349
373
  overflow: "visible",
350
374
  pointerEvents: "none",
351
375
  zIndex: 55
352
- }, V = {
376
+ }, Y = {
353
377
  position: "fixed",
354
378
  top: "var(--tb-h, 60px)",
355
379
  left: 0,
@@ -365,57 +389,57 @@ const U = {
365
389
  pointerEvents: "none",
366
390
  background: "rgba(0, 0, 0, 0.04)"
367
391
  };
368
- function z({ panelComponents: e }) {
369
- const { state: n, dispatch: t, getCloseLog: r } = O(), i = n.activePanelId ? e[n.activePanelId] : null;
370
- n.activePanelId && !i && process.env.NODE_ENV !== "production" && console.error(
392
+ function Z({ panelComponents: e }) {
393
+ const { state: n, dispatch: t, getCloseLog: r } = N(), l = n.activePanelId ? e[n.activePanelId] : null;
394
+ n.activePanelId && !l && process.env.NODE_ENV !== "production" && console.error(
371
395
  "[panels] No panel component registered for activePanelId:",
372
396
  n.activePanelId
373
397
  ), u(() => {
374
398
  if (n.activePanelId == null) return;
375
- function s(h) {
376
- h.key === "Escape" && t({ type: "CLOSE_PANEL", reason: "escape-key" });
399
+ function a(S) {
400
+ S.key === "Escape" && t({ type: "CLOSE_PANEL", reason: "escape-key" });
377
401
  }
378
- return document.addEventListener("keydown", s), () => {
379
- document.removeEventListener("keydown", s);
402
+ return document.addEventListener("keydown", a), () => {
403
+ document.removeEventListener("keydown", a);
380
404
  };
381
405
  }, [n.activePanelId, t]);
382
406
  const o = d(n);
383
- I(() => {
407
+ y(() => {
384
408
  o.current = n;
385
409
  }), u(() => {
386
410
  if (process.env.NODE_ENV === "production") return;
387
- const s = window;
388
- return s.__panelsHostHandle && console.warn("[panels] multiple PanelHost/PanelHostShell instances mounted; dev handle is unreliable"), s.__panelsHostHandle = {
411
+ const a = window;
412
+ return a.__panelsHostHandle && console.warn("[panels] multiple PanelHost/PanelHostShell instances mounted; dev handle is unreliable"), a.__panelsHostHandle = {
389
413
  dispatch: t,
390
414
  getState: () => o.current,
391
415
  getCloseLog: r
392
416
  }, () => {
393
- s.__panelsHostHandle?.dispatch === t && delete s.__panelsHostHandle;
417
+ a.__panelsHostHandle?.dispatch === t && delete a.__panelsHostHandle;
394
418
  };
395
419
  }, [t, r]);
396
- const c = v(() => {
420
+ const c = m(() => {
397
421
  t({ type: "CLOSE_PANEL", reason: "nav-escape-hatch" });
398
- }, [t]), l = n.activePanelId != null && i != null;
399
- return /* @__PURE__ */ E("div", { "data-panel-host": "true", style: U, children: [
400
- l && /* @__PURE__ */ a(
422
+ }, [t]), i = n.activePanelId != null && l != null;
423
+ return /* @__PURE__ */ C("div", { "data-panel-host": "true", style: z, children: [
424
+ i && /* @__PURE__ */ s(
401
425
  "div",
402
426
  {
403
427
  "data-panel-scrim": "true",
404
- style: V,
428
+ style: Y,
405
429
  onClick: c
406
430
  }
407
431
  ),
408
- /* @__PURE__ */ a(M, { isOpen: l, children: l && /* @__PURE__ */ a(
409
- A,
432
+ /* @__PURE__ */ s(q, { isOpen: i, children: i && /* @__PURE__ */ s(
433
+ K,
410
434
  {
411
435
  isOpen: !0,
412
436
  onClose: () => t({ type: "CLOSE_PANEL", reason: "header-x" }),
413
- children: /* @__PURE__ */ a(i, { isOpen: !0 })
437
+ children: /* @__PURE__ */ s(l, { isOpen: !0 })
414
438
  }
415
439
  ) })
416
440
  ] });
417
441
  }
418
- const Q = {
442
+ const $ = {
419
443
  "apply-button": !0,
420
444
  // the ONLY commit reason
421
445
  "cancel-button": !1,
@@ -429,16 +453,16 @@ const Q = {
429
453
  "nav-escape-hatch": !1
430
454
  };
431
455
  export {
432
- Q as C,
433
- Y as P,
434
- O as a,
435
- z as b,
436
- A as c,
437
- w as d,
438
- D as e,
439
- R as f,
440
- M as g,
441
- L as i,
442
- T as r,
443
- q as u
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
444
468
  };
@@ -1,5 +1,5 @@
1
- import { u as I, f as q, a as Z, g as N, c as w } from "./COMMITS-Dm8qIHaq.js";
2
- import { C as Ve, b as qe, P as Be, e as He, i as Ue, r as Ye, d as Ke } from "./COMMITS-Dm8qIHaq.js";
1
+ import { a as I, u as q, b as Z, g as N, d as w } from "./COMMITS-BEa-B4Oc.js";
2
+ import { C as Ve, c as qe, P as Be, f as He, i as Ue, r as Ye, e as Ke } from "./COMMITS-BEa-B4Oc.js";
3
3
  import { jsx as s, jsxs as h, Fragment as ee } from "react/jsx-runtime";
4
4
  import { useState as y, useRef as B, createContext as H, useContext as U, useEffect as F, useLayoutEffect as te, useCallback as Y } from "react";
5
5
  function ne({ children: e }) {