@mt-gloss/ui 0.1.98 → 0.1.100

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