@muten/shadcn 0.2.2 → 0.2.3

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.
package/kit.css CHANGED
@@ -370,8 +370,10 @@ button.cn-item { width: 100%; font: inherit; text-align: left; cursor: pointer;
370
370
  shows nothing: the agenda behind is the context */
371
371
  .cx-modal[data-mode="anchor"] { width: min(24rem, calc(100% - 2rem)); max-height: min(38rem, calc(100dvh - 2rem)); border-radius: calc(var(--radius) * 1.4); overflow: hidden;
372
372
  box-shadow: 0 0 0 1px color-mix(in srgb, var(--foreground) 10%, transparent), 0 24px 60px -20px rgb(20 16 40 / .38);
373
- transform: scale(.96); opacity: 0; transition: transform calc(var(--t-modal) * .5) ease, opacity calc(var(--t-modal) * .4) ease; }
374
- .cx-modal-root[data-open="true"] > .cx-modal[data-mode="anchor"] { transform: none; opacity: 1; transition: transform var(--t-pop, 180ms) var(--ease-out), opacity var(--t-pop, 180ms) var(--ease-out); }
373
+ transform: none; scale: .96; opacity: 0; transition: scale calc(var(--t-modal) * .5) ease, opacity calc(var(--t-modal) * .4) ease; }
374
+ /* it grows in place with `scale`, never `transform`: a modal that was a sheet sits off-screen by its transform, and
375
+ animating that would fly the card in from the side */
376
+ .cx-modal-root[data-open="true"] > .cx-modal[data-mode="anchor"] { scale: 1; opacity: 1; transition: scale var(--t-pop, 180ms) var(--ease-out), opacity var(--t-pop, 180ms) var(--ease-out); }
375
377
  .cx-modal-root:has(> .cx-modal[data-mode="anchor"]) > .cx-overlay { background: transparent; backdrop-filter: none; }
376
378
  /* teléfono = Drawer desde abajo, arrastrable */
377
379
  .cx-modal[data-mode="drawer"] { left: 0; right: 0; bottom: 0; margin-inline: auto; width: min(100%, 34rem); max-height: calc(100dvh - 3rem); border-radius: calc(var(--radius) * 1.8) calc(var(--radius) * 1.8) 0 0; overflow: hidden;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@muten/shadcn",
3
- "version": "0.2.2",
3
+ "version": "0.2.3",
4
4
  "description": "shadcn-style component registry for muten - own-the-source parts you add with `muten add`.",
5
5
  "repository": {
6
6
  "type": "git",
@@ -72,9 +72,17 @@ export function mount(el, inputs, on) {
72
72
  };
73
73
  map = data;
74
74
  const send = (name, value) => on[name]?.(typeof value === 'string' ? value : JSON.stringify(value));
75
- // WHERE A CITA IS ON SCREEN ("x,y,w,h"), so the app can open it beside itself (Modal mode "anchor"): the shown chip
76
- // or row that carries its id ('' when none is visible, e.g. opened from a command)
77
- const whereIs = (id) => { const box = [...el.querySelectorAll(`[data-ev="${CSS.escape(String(id))}"]`)].map((x) => x.getBoundingClientRect()).find((r) => r.width > 0 && r.height > 0); return box ? [box.left, box.top, box.width, box.height].map(Math.round).join(',') : ''; };
75
+ // WHERE A CITA IS ON SCREEN ("x,y,w,h"), so the app can open it beside itself (Modal mode "anchor"): the very chip,
76
+ // or row that was tapped; else its chip or row (never the «now» card: a band as wide as the agenda, nothing to sit by);
77
+ // '' when none is visible (opened from a command)
78
+ let tapped = null;
79
+ el.addEventListener('click', (e) => { tapped = e.target.closest?.('[data-ev]') ?? null; }, true);
80
+ const boxOf = (x) => { const r = x?.getBoundingClientRect(); return r && r.width > 0 && r.height > 0 ? [r.left, r.top, r.width, r.height].map(Math.round).join(',') : ''; };
81
+ const whereIs = (id) => {
82
+ if (tapped?.isConnected && !tapped.matches('.cx-ag-nowcard') && tapped.dataset.ev === String(id) && boxOf(tapped)) return boxOf(tapped);
83
+ const own = [...el.querySelectorAll(`.cx-ag-ev[data-ev="${CSS.escape(String(id))}"], .cx-ag-row[data-ev="${CSS.escape(String(id))}"]`)].map(boxOf).find(Boolean);
84
+ return own ?? '';
85
+ };
78
86
  const day1 = (x) => ({ ...x, day: x.day instanceof Date ? iso(x.day) : x.day });
79
87
  el.innerHTML = '';
80
88
  api = kit.agenda(el, {
@@ -21,9 +21,11 @@ export function mount(el, inputs, on) {
21
21
  let anchor = String(inputs.anchor || '');
22
22
  // `want` is the mode the page asked for; `mode` is what it is now (an anchor with nothing to hold on to is a dialog)
23
23
  const wantsAnchor = () => mdl.dataset.want === 'anchor';
24
+ // what an earlier opening as a card left on the element: a sheet or a dialog opened next must not keep it
25
+ const unplace = () => { mdl.style.left = ''; mdl.style.top = ''; mdl.style.transformOrigin = ''; };
24
26
  const place = () => {
25
27
  const at = anchor.split(',').map(Number);
26
- if (!wantsAnchor() || phone.matches || at.length !== 4 || at.some((n) => !Number.isFinite(n))) { if (wantsAnchor()) mdl.dataset.mode = phone.matches ? 'drawer' : 'dialog'; return; }
28
+ if (!wantsAnchor() || phone.matches || at.length !== 4 || at.some((n) => !Number.isFinite(n))) { unplace(); if (wantsAnchor()) mdl.dataset.mode = phone.matches ? 'drawer' : 'dialog'; return; }
27
29
  mdl.dataset.mode = 'anchor';
28
30
  const [x, y, w] = at, gap = 12, edge = 16;
29
31
  const width = mdl.offsetWidth, height = Math.min(mdl.scrollHeight, innerHeight - edge * 2);
@@ -36,7 +38,7 @@ export function mount(el, inputs, on) {
36
38
  const open = () => {
37
39
  if (isOpen) return; isOpen = true; placeFooter();
38
40
  if (auto) mdl.dataset.mode = phone.matches ? 'drawer' : 'dialog';
39
- if (wantsAnchor()) place();
41
+ if (wantsAnchor()) place(); else unplace();
40
42
  lastFocus = document.activeElement;
41
43
  document.documentElement.classList.add('cx-locked');
42
44
  // on the phone, focusing a field would throw the keyboard over the sheet: focus the sheet itself