@blakesteve/roster 5.11.0 → 5.12.0

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.
Files changed (43) hide show
  1. package/README.md +37 -8
  2. package/dist/components/atoms/Chip/chip-variants.cjs +1 -1
  3. package/dist/components/atoms/Chip/chip-variants.js +8 -2
  4. package/dist/components/atoms/Combobox/Combobox.cjs +1 -1
  5. package/dist/components/atoms/Combobox/Combobox.js +20 -18
  6. package/dist/components/atoms/MultiSelect/MultiSelect.cjs +1 -1
  7. package/dist/components/atoms/MultiSelect/MultiSelect.js +22 -20
  8. package/dist/components/atoms/Select/Select.cjs +1 -1
  9. package/dist/components/atoms/Select/Select.js +19 -17
  10. package/dist/components/molecules/Carousel/Carousel.cjs +1 -1
  11. package/dist/components/molecules/Carousel/Carousel.js +31 -29
  12. package/dist/components/molecules/FileUpload/FileUpload.cjs +1 -1
  13. package/dist/components/molecules/FileUpload/FileUpload.js +21 -19
  14. package/dist/components/molecules/LiquidTabs/LiquidTabs.cjs +1 -1
  15. package/dist/components/molecules/LiquidTabs/LiquidTabs.js +22 -20
  16. package/dist/components/molecules/Menu/Menu.cjs +1 -1
  17. package/dist/components/molecules/Menu/Menu.js +104 -102
  18. package/dist/components/molecules/RadioGroup/RadioGroup.cjs +1 -1
  19. package/dist/components/molecules/RadioGroup/RadioGroup.js +23 -21
  20. package/dist/components/molecules/RangeSlider/RangeSlider.cjs +1 -1
  21. package/dist/components/molecules/RangeSlider/RangeSlider.d.ts +8 -3
  22. package/dist/components/molecules/RangeSlider/RangeSlider.js +38 -36
  23. package/dist/components/molecules/Slider/Slider.cjs +1 -1
  24. package/dist/components/molecules/Slider/Slider.d.ts +7 -3
  25. package/dist/components/molecules/Slider/Slider.js +30 -28
  26. package/dist/components/molecules/Slider/track-parts.d.ts +2 -1
  27. package/dist/components/organisms/Dialog/Dialog.cjs +1 -1
  28. package/dist/components/organisms/Dialog/Dialog.js +19 -17
  29. package/dist/components/organisms/ModerationQueue/ModerationQueue.cjs +1 -1
  30. package/dist/components/organisms/ModerationQueue/ModerationQueue.js +45 -43
  31. package/dist/components/organisms/Navbar/Navbar.cjs +1 -1
  32. package/dist/components/organisms/Navbar/Navbar.js +24 -22
  33. package/dist/components/organisms/Sheet/Sheet.cjs +1 -1
  34. package/dist/components/organisms/Sheet/Sheet.js +25 -23
  35. package/dist/internal/key-focus.cjs +1 -0
  36. package/dist/internal/key-focus.d.ts +7 -0
  37. package/dist/internal/key-focus.js +60 -0
  38. package/dist/internal/popup.cjs +1 -1
  39. package/dist/internal/popup.d.ts +15 -1
  40. package/dist/internal/popup.js +17 -12
  41. package/dist/meta.json +3 -3
  42. package/dist/roster.css +1 -1
  43. package/package.json +1 -1
@@ -11,28 +11,29 @@ import { useReducedMotion as nt } from "../../../internal/motion.js";
11
11
  import { lockPage as ot } from "../../../internal/page-inert.js";
12
12
  import { sheetDragOutcome as at, sheetReleaseVelocity as it, exceedsSheetTapSlop as ct } from "./sheet-drag.js";
13
13
  import { titleSignature as ut } from "./sheet-title.js";
14
- const lt = { close: "Close" }, dt = "rst:transition-transform rst:duration-(--roster-sheet-enter-duration) rst:ease-(--roster-sheet-enter-easing) rst:data-leave:duration-(--roster-sheet-leave-duration) rst:data-leave:ease-(--roster-sheet-leave-easing) rst:data-closed:translate-y-full", ft = "rst:transition-opacity rst:duration-(--roster-sheet-fade-duration) rst:ease-out rst:data-closed:opacity-0", pt = "rst:transition-opacity rst:duration-(--roster-sheet-enter-duration) rst:ease-out rst:data-leave:duration-(--roster-sheet-leave-duration) rst:data-closed:opacity-0", mt = "rst:transition-opacity rst:duration-(--roster-sheet-fade-duration) rst:ease-out rst:data-closed:opacity-0", ht = [
14
+ import { useKeyFocus as lt } from "../../../internal/key-focus.js";
15
+ const dt = { close: "Close" }, ft = "rst:transition-transform rst:duration-(--roster-sheet-enter-duration) rst:ease-(--roster-sheet-enter-easing) rst:data-leave:duration-(--roster-sheet-leave-duration) rst:data-leave:ease-(--roster-sheet-leave-easing) rst:data-closed:translate-y-full", pt = "rst:transition-opacity rst:duration-(--roster-sheet-fade-duration) rst:ease-out rst:data-closed:opacity-0", mt = "rst:transition-opacity rst:duration-(--roster-sheet-enter-duration) rst:ease-out rst:data-leave:duration-(--roster-sheet-leave-duration) rst:data-closed:opacity-0", ht = "rst:transition-opacity rst:duration-(--roster-sheet-fade-duration) rst:ease-out rst:data-closed:opacity-0", gt = [
15
16
  "input:not([type=checkbox]):not([type=radio]):not([type=button]):not([type=submit]):not([type=reset]):not([type=range]):not([type=color]):not([type=file]):not([type=image])",
16
17
  "textarea",
17
18
  "select",
18
19
  "[contenteditable]:not([contenteditable=false])"
19
20
  ].join(",");
20
- function gt(r) {
21
+ function yt(r) {
21
22
  return r ? "current" in r ? r.current : r : null;
22
23
  }
23
- function yt({ target: r }) {
24
+ function bt({ target: r }) {
24
25
  const u = s.useRef(r), f = s.useRef(!1);
25
26
  return s.useEffect(() => {
26
27
  u.current = r;
27
28
  }), s.useEffect(() => (f.current = !1, () => {
28
29
  f.current = !0, queueMicrotask(() => {
29
30
  if (!f.current) return;
30
- const p = gt(u.current);
31
+ const p = yt(u.current);
31
32
  p?.isConnected && p.focus();
32
33
  });
33
34
  }), []), null;
34
35
  }
35
- function bt() {
36
+ function vt() {
36
37
  return /* @__PURE__ */ n(
37
38
  "svg",
38
39
  {
@@ -48,7 +49,7 @@ function bt() {
48
49
  }
49
50
  );
50
51
  }
51
- const St = ({
52
+ const Mt = ({
52
53
  isOpen: r,
53
54
  onClose: u,
54
55
  onAfterClose: f,
@@ -66,7 +67,8 @@ const St = ({
66
67
  className: T,
67
68
  children: _
68
69
  }) => {
69
- const q = rt(lt, Y), { ref: R, inDarkScope: $ } = st(), D = nt();
70
+ lt();
71
+ const q = rt(dt, Y), { ref: R, inDarkScope: $ } = st(), D = nt();
70
72
  s.useLayoutEffect(() => {
71
73
  if (r)
72
74
  return ot(R.current);
@@ -91,7 +93,7 @@ const St = ({
91
93
  const t = window.visualViewport;
92
94
  if (!t) return;
93
95
  const e = () => {
94
- const o = document.activeElement, c = !!o && !!i.current?.contains(o) && o.matches(ht);
96
+ const o = document.activeElement, c = !!o && !!i.current?.contains(o) && o.matches(gt);
95
97
  A(c ? Math.round(t.height) : null);
96
98
  };
97
99
  return t.addEventListener("resize", e), document.addEventListener("focusin", e), document.addEventListener("focusout", e), () => {
@@ -113,7 +115,7 @@ const St = ({
113
115
  s.useEffect(() => {
114
116
  !r && a.current && (a.current = null, i.current && delete i.current.dataset.dragging), r && !a.current && b(0);
115
117
  }, [r]);
116
- const U = (t) => {
118
+ const K = (t) => {
117
119
  a.current || (y.current = !1, !(!E || !r) && (t.pointerType === "mouse" && (t.button !== 0 || !I.current?.contains(t.target)) || (a.current = {
118
120
  pointerId: t.pointerId,
119
121
  x0: t.clientX,
@@ -122,7 +124,7 @@ const St = ({
122
124
  phase: "pending",
123
125
  samples: [{ t: t.timeStamp, y: t.clientY }]
124
126
  })));
125
- }, V = (t) => {
127
+ }, U = (t) => {
126
128
  const e = a.current;
127
129
  if (!e || t.pointerId !== e.pointerId) return;
128
130
  const o = t.clientX - e.x0, c = t.clientY - e.y0;
@@ -140,7 +142,7 @@ const St = ({
140
142
  i.current && (i.current.dataset.dragging = "");
141
143
  }
142
144
  e.phase === "dragging" && (e.dy = c, e.samples.push({ t: t.timeStamp, y: t.clientY }), e.samples.length > 32 && e.samples.shift(), b(Math.max(0, c)));
143
- }, X = (t) => {
145
+ }, V = (t) => {
144
146
  const e = a.current;
145
147
  if (!e || t.pointerId !== e.pointerId) return;
146
148
  if (e.phase !== "dragging") {
@@ -150,10 +152,10 @@ const St = ({
150
152
  e.samples.push({ t: t.timeStamp, y: t.clientY });
151
153
  const o = t.clientY - e.y0, c = i.current?.getBoundingClientRect().height ?? 0;
152
154
  j(at(o, c, it(e.samples)));
153
- }, G = (t) => {
155
+ }, X = (t) => {
154
156
  const e = a.current;
155
157
  !e || t.pointerId !== e.pointerId || (e.phase === "dragging" ? j("stay") : a.current = null);
156
- }, K = (t) => {
158
+ }, G = (t) => {
157
159
  !y.current || t.detail === 0 || (y.current = !1, t.preventDefault(), t.stopPropagation());
158
160
  }, Q = {
159
161
  "--rst-sheet-max-width": typeof v == "number" ? `${v}px` : v,
@@ -180,7 +182,7 @@ const St = ({
180
182
  "data-testid": "sheet-backdrop",
181
183
  className: d(
182
184
  "rst:fixed rst:inset-0 rst:bg-[var(--roster-backdrop,var(--roster-sheet-backdrop))]",
183
- D ? mt : pt
185
+ D ? ht : mt
184
186
  )
185
187
  }
186
188
  ),
@@ -202,7 +204,7 @@ const St = ({
202
204
  "rst:[--roster-ring-offset:var(--roster-popover-bg)]",
203
205
  "rst:pb-[env(safe-area-inset-bottom)]",
204
206
  "rst:translate-y-[var(--rst-sheet-drag,0px)]",
205
- D ? ft : dt,
207
+ D ? pt : ft,
206
208
  "rst:data-dragging:transition-none",
207
209
  T
208
210
  ),
@@ -212,11 +214,11 @@ const St = ({
212
214
  {
213
215
  "data-testid": "sheet-drag-zone",
214
216
  className: d("rst:shrink-0", E && "rst:touch-none"),
215
- onPointerDown: U,
216
- onPointerMove: V,
217
- onPointerUp: X,
218
- onPointerCancel: G,
219
- onClickCapture: K,
217
+ onPointerDown: K,
218
+ onPointerMove: U,
219
+ onPointerUp: V,
220
+ onPointerCancel: X,
221
+ onClickCapture: G,
220
222
  children: [
221
223
  /* @__PURE__ */ n(
222
224
  "div",
@@ -272,7 +274,7 @@ const St = ({
272
274
  onClick: u,
273
275
  "aria-label": q.close,
274
276
  className: "rst:inline-flex rst:size-11 rst:shrink-0 rst:-mr-2 rst:cursor-pointer rst:items-center rst:justify-center rst:rounded-md rst:bg-transparent rst:text-inherit rst:opacity-60 rst:transition-opacity rst:hover:opacity-100 rst:focus:outline-hidden rst:focus-visible:opacity-100 rst:focus-visible:ring-2 rst:focus-visible:ring-ring rst:focus-visible:ring-offset-2 rst:ring-offset-background",
275
- children: /* @__PURE__ */ n(bt, {})
277
+ children: /* @__PURE__ */ n(vt, {})
276
278
  }
277
279
  )
278
280
  ] })
@@ -292,7 +294,7 @@ const St = ({
292
294
  children: _
293
295
  }
294
296
  ),
295
- /* @__PURE__ */ n(yt, { target: B })
297
+ /* @__PURE__ */ n(bt, { target: B })
296
298
  ]
297
299
  }
298
300
  ) }) })
@@ -302,5 +304,5 @@ const St = ({
302
304
  ] });
303
305
  };
304
306
  export {
305
- St as Sheet
307
+ Mt as Sheet
306
308
  };
@@ -0,0 +1 @@
1
+ "use client";"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const l=require("react");function f(e){const t=Object.create(null,{[Symbol.toStringTag]:{value:"Module"}});if(e){for(const c in e)if(c!=="default"){const i=Object.getOwnPropertyDescriptor(e,c);Object.defineProperty(t,c,i.get?i:{enumerable:!0,get:()=>e[c]})}}return t.default=e,Object.freeze(t)}const y=f(l),d=new Set(["Tab","Enter"," ","Escape","ArrowUp","ArrowDown","ArrowLeft","ArrowRight","Home","End","PageUp","PageDown"]),o="data-key-focus";let u=0,r=!1,n=null;const s=()=>{for(const e of document.querySelectorAll(`[${o}]`))e.removeAttribute(o)};function m(e){e.ctrlKey||e.metaKey||e.altKey&&e.key!=="Tab"||d.has(e.key)&&(r=!0)}function p(e){n=[e.clientX,e.clientY],r=!1,s()}function b(e){const t=!n||n[0]!==e.clientX||n[1]!==e.clientY;n=[e.clientX,e.clientY],t&&(r=!1)}function g(e){r&&e.target instanceof Element&&e.target.setAttribute(o,"")}function w(e){e.target instanceof Element&&e.target.removeAttribute(o)}const a=[["keydown",m],["pointerdown",p],["pointermove",b],["focusin",g],["focusout",w]];function E(){if(u+=1,!(u>1))for(const[e,t]of a)document.addEventListener(e,t,{capture:!0,passive:!0})}function A(){if(u-=1,!(u>0)){for(const[e,t]of a)document.removeEventListener(e,t,{capture:!0});r=!1,n=null,s()}}function O(){y.useEffect(()=>(E(),A),[])}exports.KEY_FOCUS=o;exports.useKeyFocus=O;
@@ -0,0 +1,7 @@
1
+ export declare const KEY_FOCUS = "data-key-focus";
2
+ /**
3
+ * Keeps the keyboard-mode listeners installed while the calling component is
4
+ * mounted. Every component that moves focus by script, or opens something
5
+ * that does, calls it.
6
+ */
7
+ export declare function useKeyFocus(): void;
@@ -0,0 +1,60 @@
1
+ "use client";
2
+ import * as s from "react";
3
+ const f = /* @__PURE__ */ new Set([
4
+ "Tab",
5
+ "Enter",
6
+ " ",
7
+ "Escape",
8
+ "ArrowUp",
9
+ "ArrowDown",
10
+ "ArrowLeft",
11
+ "ArrowRight",
12
+ "Home",
13
+ "End",
14
+ "PageUp",
15
+ "PageDown"
16
+ ]), r = "data-key-focus";
17
+ let c = 0, o = !1, e = null;
18
+ const i = () => {
19
+ for (const t of document.querySelectorAll(`[${r}]`)) t.removeAttribute(r);
20
+ };
21
+ function l(t) {
22
+ t.ctrlKey || t.metaKey || t.altKey && t.key !== "Tab" || f.has(t.key) && (o = !0);
23
+ }
24
+ function a(t) {
25
+ e = [t.clientX, t.clientY], o = !1, i();
26
+ }
27
+ function m(t) {
28
+ const n = !e || e[0] !== t.clientX || e[1] !== t.clientY;
29
+ e = [t.clientX, t.clientY], n && (o = !1);
30
+ }
31
+ function y(t) {
32
+ o && t.target instanceof Element && t.target.setAttribute(r, "");
33
+ }
34
+ function p(t) {
35
+ t.target instanceof Element && t.target.removeAttribute(r);
36
+ }
37
+ const u = [
38
+ ["keydown", l],
39
+ ["pointerdown", a],
40
+ ["pointermove", m],
41
+ ["focusin", y],
42
+ ["focusout", p]
43
+ ];
44
+ function d() {
45
+ if (c += 1, !(c > 1))
46
+ for (const [t, n] of u) document.addEventListener(t, n, { capture: !0, passive: !0 });
47
+ }
48
+ function w() {
49
+ if (c -= 1, !(c > 0)) {
50
+ for (const [t, n] of u) document.removeEventListener(t, n, { capture: !0 });
51
+ o = !1, e = null, i();
52
+ }
53
+ }
54
+ function E() {
55
+ s.useEffect(() => (d(), w), []);
56
+ }
57
+ export {
58
+ r as KEY_FOCUS,
59
+ E as useKeyFocus
60
+ };
@@ -1 +1 @@
1
- "use client";"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const s=require("react");function c(t){const e=Object.create(null,{[Symbol.toStringTag]:{value:"Module"}});if(t){for(const r in t)if(r!=="default"){const n=Object.getOwnPropertyDescriptor(t,r);Object.defineProperty(e,r,n.get?n:{enumerable:!0,get:()=>t[r]})}}return e.default=t,Object.freeze(e)}const o=c(s);function a(){const t=o.useRef(null),[e,r]=o.useState(!1);return o.useLayoutEffect(()=>{r(!!t.current?.closest(".dark"))},[]),{ref:t,inDarkScope:e}}const u=["rst:font-ui","rst:z-50 rst:rounded-md rst:py-1 rst:elevation-anchored rst:ring rst:focus:outline-hidden","rst:bg-[var(--roster-popover-bg)] rst:text-[var(--roster-popover-text)] rst:ring-[var(--roster-popover-border)]","rst:[--anchor-gap:4px]"].join(" ");function P(t,e){return t||e==="slate"}const p="rst:w-(--button-width)",i="rst:w-(--input-width)",l="bottom start";exports.POPUP_ANCHOR=l;exports.POPUP_PANEL=u;exports.POPUP_WIDTH_OF_BUTTON=p;exports.POPUP_WIDTH_OF_INPUT=i;exports.popupInDarkPalette=P;exports.useDarkScope=a;
1
+ "use client";"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const c=require("react");function a(t){const e=Object.create(null,{[Symbol.toStringTag]:{value:"Module"}});if(t){for(const r in t)if(r!=="default"){const n=Object.getOwnPropertyDescriptor(t,r);Object.defineProperty(e,r,n.get?n:{enumerable:!0,get:()=>t[r]})}}return e.default=t,Object.freeze(e)}const o=a(c);function s(t){const e=t?.closest(".dark");return!!e&&!e.contains(document.body)}function u(){const t=o.useRef(null),[e,r]=o.useState(!1);return o.useLayoutEffect(()=>{r(s(t.current))},[]),{ref:t,inDarkScope:e}}const P=["rst:font-ui","rst:z-50 rst:rounded-md rst:py-1 rst:elevation-anchored rst:ring rst:focus:outline-hidden","rst:bg-[var(--roster-popover-bg)] rst:text-[var(--roster-popover-text)] rst:ring-[var(--roster-popover-border)]","rst:[--anchor-gap:4px]"].join(" ");function i(t,e){return t||e==="slate"}const p="rst:w-(--button-width)",l="rst:w-(--input-width)",O="bottom start";exports.POPUP_ANCHOR=O;exports.POPUP_PANEL=P;exports.POPUP_WIDTH_OF_BUTTON=p;exports.POPUP_WIDTH_OF_INPUT=l;exports.carriesDark=s;exports.popupInDarkPalette=i;exports.useDarkScope=u;
@@ -29,13 +29,27 @@ import * as React from "react";
29
29
  * `@custom-variant dark (&:where(.dark, .dark *))` matches, so this reproduces
30
30
  * the cascade rather than second-guessing it. Applying the class to the panel
31
31
  * covers the panel itself through the `&:where(.dark, …)` half, and its
32
- * options through `.dark *`. Idempotent when `.dark` is already on the root.
32
+ * options through `.dark *`.
33
+ *
34
+ * **Only when the portal leaves the scope.** When `.dark` is on `<html>` or
35
+ * `<body>`, the panel is already inside it and needs nothing. The class isn't
36
+ * harmless there either: it carries Roster's own `.dark` token block, which
37
+ * declares the default palette on the panel itself, over whatever the page set
38
+ * above it. A consumer's `--roster-*` set inline on `<html>`, or under
39
+ * `html.dark`, stopped at every panel, which drew Roster's grays under the
40
+ * consumer's trigger.
33
41
  *
34
42
  * Read once, on mount. A theme TOGGLE does not need this at all: it flips
35
43
  * `.dark` on `<html>`, and the portal is already a descendant of `<html>`. The
36
44
  * only case this covers is a scoped `.dark`, which is part of a page's
37
45
  * structure rather than something that changes at runtime.
38
46
  */
47
+ /**
48
+ * Whether a panel portaled out from beside `el` must carry `.dark` itself:
49
+ * `el` is in a `.dark` scope, and the scope doesn't contain `<body>`, where
50
+ * the portal lands. See `useDarkScope` for why carrying it otherwise is wrong.
51
+ */
52
+ export declare function carriesDark(el: Element | null | undefined): boolean;
39
53
  export declare function useDarkScope<T extends HTMLElement>(): {
40
54
  ref: React.RefObject<T | null>;
41
55
  inDarkScope: boolean;
@@ -1,12 +1,16 @@
1
1
  "use client";
2
- import * as e from "react";
3
- function s() {
4
- const t = e.useRef(null), [r, o] = e.useState(!1);
5
- return e.useLayoutEffect(() => {
6
- o(!!t.current?.closest(".dark"));
2
+ import * as o from "react";
3
+ function s(t) {
4
+ const r = t?.closest(".dark");
5
+ return !!r && !r.contains(document.body);
6
+ }
7
+ function n() {
8
+ const t = o.useRef(null), [r, e] = o.useState(!1);
9
+ return o.useLayoutEffect(() => {
10
+ e(s(t.current));
7
11
  }, []), { ref: t, inDarkScope: r };
8
12
  }
9
- const n = [
13
+ const c = [
10
14
  /* `font-ui` on the panel, not on each row. Put on the rows it is missed by
11
15
  anything else in the panel — the empty message rendered in the host's
12
16
  prose face while the options beside it did not. */
@@ -18,12 +22,13 @@ const n = [
18
22
  function a(t, r) {
19
23
  return t || r === "slate";
20
24
  }
21
- const c = "rst:w-(--button-width)", u = "rst:w-(--input-width)", p = "bottom start";
25
+ const u = "rst:w-(--button-width)", p = "rst:w-(--input-width)", i = "bottom start";
22
26
  export {
23
- p as POPUP_ANCHOR,
24
- n as POPUP_PANEL,
25
- c as POPUP_WIDTH_OF_BUTTON,
26
- u as POPUP_WIDTH_OF_INPUT,
27
+ i as POPUP_ANCHOR,
28
+ c as POPUP_PANEL,
29
+ u as POPUP_WIDTH_OF_BUTTON,
30
+ p as POPUP_WIDTH_OF_INPUT,
31
+ s as carriesDark,
27
32
  a as popupInDarkPalette,
28
- s as useDarkScope
33
+ n as useDarkScope
29
34
  };
package/dist/meta.json CHANGED
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "5.11.0",
3
- "tests": 2361,
4
- "testFiles": 579
2
+ "version": "5.12.0",
3
+ "tests": 2399,
4
+ "testFiles": 594
5
5
  }