@stackone/malachite 2.37.0 → 2.37.1

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,20 +1,20 @@
1
1
  import { jsxs as U, jsx as h } from "react/jsx-runtime";
2
- import C, { useRef as O, useState as nt, useLayoutEffect as w, useCallback as S } from "react";
3
- import re from "./CustomIcons/ArrowLeftIcon.js";
4
- import ne from "./CustomIcons/ForwardArrowIcon.js";
5
- import oe from "./CustomIcons/PlusIcon.js";
6
- import { CONTENT_INSET as $t } from "./PageLayout/constants.js";
7
- import { STRIP_RULE_PX as ae, CARD_FLARE_TIP_PX as ct, CARD_WIDTH_PX as ce, FLARE_CLASS as se, CARD_FLARE_PX as q } from "./SelectableCard.js";
8
- import { revealTargetFor as Dt, pageTargetFor as ie, EDGE_EPSILON_PX as ot, isCardInView as le } from "./cardStripGeometry.js";
9
- import { CardStripSlotContext as yt, PINNED_SLOT as de, SCROLLED_SLOT as ue } from "./cardStripSlot.js";
10
- import { FOCUS_RING as fe } from "./focusRing.js";
11
- import { useAdoptedStyleSheet as Ot } from "./useAdoptedStyleSheet.js";
12
- const pe = /* @__PURE__ */ new Set(["ArrowLeft", "ArrowRight", "ArrowUp", "ArrowDown", "Home", "End"]), G = '[role="radio"]', he = "data-card-strip-scroller", me = "data-card-strip-trough", K = "malachite-card-strip", g = "malachite-card-strip-scroller", Xt = "malachite-card-strip-fade", R = "malachite-card-strip-add-tile", st = "data-card-strip-add-slot", Wt = "[data-selectable-card-actions]", be = 'a[href], area[href], button, input, select, textarea, iframe, [contenteditable="true"], [tabindex]', B = "data-card-strip-prev-tabindex", ge = 80, vt = 11, H = 12, zt = "var(--malachite-shadow-default)", Re = "var(--malachite-card-strip-arrow-background, var(--malachite-card-background, #ffffff))", _e = "var(--malachite-card-strip-arrow-border, #e8e8e8)", it = "var(--malachite-card-strip-background, #f1f1f1)", wt = "var(--malachite-radius-xxl, 14px)", Ae = `${wt} ${wt} 0 0`, Ct = "var(--malachite-radius-xxxl, 16px)", Se = `${Ct} ${Ct} 0 0`, v = 4, xe = H + v, Yt = H, It = ge + (Yt - v), dt = ce, Le = 2 * (H + v) + dt, Ee = "var(--malachite-card-strip-divider, #dddddd)", Pt = "var(--malachite-card-strip-fade, transparent)", Te = "var(--malachite-selectable-card-hover-background, #e8e8e8)", $e = "var(--malachite-card-strip-arrow-border, #e8e8e8)", kt = "var(--malachite-selectable-card-hover-rule, #bbbbbb)", Nt = "0px 1px 0px 0px rgba(0, 0, 0, 0.4)", De = "var(--malachite-card-background, #ffffff)", ye = "var(--malachite-text-primary, #0a0a0a)", Oe = "var(--malachite-card-strip-add-primary-background, var(--malachite-text-primary, #0a0a0a))", ve = "var(--malachite-card-strip-add-primary-foreground, var(--malachite-card-background, #ffffff))", we = "0px 1px 0px 0px rgba(10, 10, 10, 0.7)", ut = ae, Ft = 16, M = 9999, Ce = 4, Ie = `
13
- .${K} {
14
- clip-path: inset(-${M}px -${M}px 0);
2
+ import C, { useRef as T, useState as M, useLayoutEffect as v, useCallback as x } from "react";
3
+ import ae from "./CustomIcons/ArrowLeftIcon.js";
4
+ import ce from "./CustomIcons/ForwardArrowIcon.js";
5
+ import se from "./CustomIcons/PlusIcon.js";
6
+ import { CONTENT_INSET as Dt } from "./PageLayout/constants.js";
7
+ import { STRIP_RULE_PX as ie, CARD_FLARE_TIP_PX as st, CARD_WIDTH_PX as le, FLARE_CLASS as de, CARD_FLARE_PX as K } from "./SelectableCard.js";
8
+ import { revealTargetFor as Ot, pageTargetFor as ue, EDGE_EPSILON_PX as at, isCardInView as fe } from "./cardStripGeometry.js";
9
+ import { CardStripSlotContext as vt, PINNED_SLOT as pe, SCROLLED_SLOT as he } from "./cardStripSlot.js";
10
+ import { FOCUS_RING as me } from "./focusRing.js";
11
+ import { useAdoptedStyleSheet as wt } from "./useAdoptedStyleSheet.js";
12
+ const be = /* @__PURE__ */ new Set(["ArrowLeft", "ArrowRight", "ArrowUp", "ArrowDown", "Home", "End"]), G = '[role="radio"]', ge = "data-card-strip-scroller", Re = "data-card-strip-trough", j = "malachite-card-strip", g = "malachite-card-strip-scroller", zt = "malachite-card-strip-fade", R = "malachite-card-strip-add-tile", it = "data-card-strip-add-slot", Yt = "[data-selectable-card-actions]", _e = 'a[href], area[href], button, input, select, textarea, iframe, [contenteditable="true"], [tabindex]', B = "data-card-strip-prev-tabindex", Ae = 80, Ct = 11, H = 12, Vt = "var(--malachite-shadow-default)", Se = "var(--malachite-card-strip-arrow-background, var(--malachite-card-background, #ffffff))", xe = "var(--malachite-card-strip-arrow-border, #e8e8e8)", lt = "var(--malachite-card-strip-background, #f1f1f1)", It = "var(--malachite-radius-xxl, 14px)", Le = `${It} ${It} 0 0`, Pt = "var(--malachite-radius-xxxl, 16px)", Ee = `${Pt} ${Pt} 0 0`, w = 4, Te = H + w, Mt = H, kt = Ae + (Mt - w), ut = le, $e = 2 * (H + w) + ut, ye = "var(--malachite-card-strip-divider, #dddddd)", Nt = "var(--malachite-card-strip-fade, transparent)", De = "var(--malachite-selectable-card-hover-background, #e8e8e8)", Oe = "var(--malachite-card-strip-arrow-border, #e8e8e8)", Ft = "var(--malachite-selectable-card-hover-rule, #bbbbbb)", Ut = "0px 1px 0px 0px rgba(0, 0, 0, 0.4)", ve = "var(--malachite-card-background, #ffffff)", we = "var(--malachite-text-primary, #0a0a0a)", Ce = "var(--malachite-card-strip-add-primary-background, var(--malachite-text-primary, #0a0a0a))", Ie = "var(--malachite-card-strip-add-primary-foreground, var(--malachite-card-background, #ffffff))", Pe = "0px 1px 0px 0px rgba(10, 10, 10, 0.7)", ft = ie, Bt = 16, q = 9999, ke = 4, Ne = `
13
+ .${j} {
14
+ clip-path: inset(-${q}px -${q}px 0);
15
15
  }
16
- .${K}:has(:focus-visible) {
17
- clip-path: inset(-${M}px -${M}px -${Ce}px);
16
+ .${j}:has(:focus-visible) {
17
+ clip-path: inset(-${q}px -${q}px -${ke}px);
18
18
  }
19
19
  .${g} {
20
20
  display: flex;
@@ -24,16 +24,16 @@ const pe = /* @__PURE__ */ new Set(["ArrowLeft", "ArrowRight", "ArrowUp", "Arrow
24
24
  scroll-behavior: smooth;
25
25
  scrollbar-width: none;
26
26
  -ms-overflow-style: none;
27
- padding-block: ${Ft}px;
28
- margin-block: -${Ft}px;
27
+ padding-block: ${Bt}px;
28
+ margin-block: -${Bt}px;
29
29
  /* overflow-x clips both axes, so the end cards would lose a flare; the negative margin trades
30
30
  the padding back out and scroll-padding keeps the rest position at zero. */
31
- padding-inline: ${q}px;
32
- margin-inline: -${q}px;
33
- scroll-padding-inline: ${q}px;
31
+ padding-inline: ${K}px;
32
+ margin-inline: -${K}px;
33
+ scroll-padding-inline: ${K}px;
34
34
  }
35
35
  /* A card focused at a faded edge has to stay readable, so the fade lifts entirely. */
36
- .${K}:has(:focus-visible) .${Xt} {
36
+ .${j}:has(:focus-visible) .${zt} {
37
37
  display: none;
38
38
  }
39
39
  .${g}::-webkit-scrollbar {
@@ -41,40 +41,40 @@ const pe = /* @__PURE__ */ new Set(["ArrowLeft", "ArrowRight", "ArrowUp", "Arrow
41
41
  }
42
42
  /* No bottom edge: the strip's rule is the baseline for the add tile as much as for a card. */
43
43
  .${R} > * {
44
- background: ${it};
45
- border-radius: ${Ae};
44
+ background: ${lt};
45
+ border-radius: ${Le};
46
46
  }
47
47
  .${R}:hover:not(:has(button:disabled)) > * {
48
- background: ${Te};
48
+ background: ${De};
49
49
  }
50
50
  .${R} button:active:not(:disabled) {
51
51
  opacity: 0.8;
52
52
  }
53
53
  .${R}:has(button:active) > * {
54
- background: ${it};
54
+ background: ${lt};
55
55
  }
56
56
  .${R}[data-emphasis='secondary'] button {
57
- border-color: ${$e};
58
- box-shadow: ${zt};
57
+ border-color: ${Oe};
58
+ box-shadow: ${Vt};
59
59
  }
60
60
  .${R}[data-emphasis='secondary']:hover:not(:has(button:disabled)) button {
61
- border-color: ${kt};
62
- box-shadow: ${Nt};
61
+ border-color: ${Ft};
62
+ box-shadow: ${Ut};
63
63
  }
64
64
  .${R}[data-emphasis='secondary'] button:active:not(:disabled) {
65
- border-color: ${kt};
66
- box-shadow: ${Nt};
65
+ border-color: ${Ft};
66
+ box-shadow: ${Ut};
67
67
  }
68
68
  .${R}[data-emphasis='primary'] button {
69
69
  border-color: transparent;
70
- box-shadow: ${we};
70
+ box-shadow: ${Pe};
71
71
  }
72
72
  .${g} > * {
73
73
  flex: 0 0 auto;
74
74
  min-width: 0;
75
75
  }
76
76
  .${g} > * + * {
77
- border-left: 1px solid ${Ee};
77
+ border-left: 1px solid ${ye};
78
78
  }
79
79
  .${g}[data-snap='true'] {
80
80
  scroll-snap-type: x proximity;
@@ -92,23 +92,23 @@ const pe = /* @__PURE__ */ new Set(["ArrowLeft", "ArrowRight", "ArrowUp", "Arrow
92
92
  .${g}[data-snap='true'] > * {
93
93
  scroll-snap-align: none;
94
94
  }
95
- }`, Pe = "malachite-card-strip-style", ke = "malachite-card-strip-add-slot", Ne = `
96
- .${g} > [${st}] {
95
+ }`, Fe = "malachite-card-strip-style", Ue = "malachite-card-strip-add-slot", Be = `
96
+ .${g} > [${it}] {
97
97
  display: flex;
98
98
  border-left: none;
99
99
  }
100
- [${st}] > .${R} {
100
+ [${it}] > .${R} {
101
101
  height: 100% !important;
102
102
  padding: 0 !important;
103
103
  }
104
- `, Ut = () => typeof window > "u" || typeof window.matchMedia != "function" ? !0 : window.matchMedia("(prefers-reduced-motion: reduce)").matches, x = (e) => e.dataset.value ?? e.getAttribute("value"), at = (e) => e.hasAttribute("disabled") || e.getAttribute("aria-disabled") === "true", Fe = (e) => {
104
+ `, Gt = () => typeof window > "u" || typeof window.matchMedia != "function" ? !0 : window.matchMedia("(prefers-reduced-motion: reduce)").matches, S = (e) => e.dataset.value ?? e.getAttribute("value"), ct = (e) => e.hasAttribute("disabled") || e.getAttribute("aria-disabled") === "true", Ge = (e) => {
105
105
  const a = e.parentElement;
106
- return !a || a.querySelectorAll(G).length !== 1 ? null : a.querySelector(Wt);
107
- }, Ue = (e, a) => {
106
+ return !a || a.querySelectorAll(G).length !== 1 ? null : a.querySelector(Yt);
107
+ }, He = (e, a) => {
108
108
  const l = e.closest(G);
109
109
  if (l)
110
110
  return l;
111
- if (e.closest(Wt))
111
+ if (e.closest(Yt))
112
112
  return null;
113
113
  let u = e;
114
114
  for (; u && a.contains(u); ) {
@@ -118,71 +118,71 @@ const pe = /* @__PURE__ */ new Set(["ArrowLeft", "ArrowRight", "ArrowUp", "Arrow
118
118
  u = u.parentElement;
119
119
  }
120
120
  return null;
121
- }, Be = (e) => {
122
- const a = Fe(e);
123
- return a ? Array.from(a.querySelectorAll(be)) : [];
124
- }, Ge = (e) => {
121
+ }, Xe = (e) => {
122
+ const a = Ge(e);
123
+ return a ? Array.from(a.querySelectorAll(_e)) : [];
124
+ }, We = (e) => {
125
125
  e.hasAttribute(B) || e.setAttribute(B, e.getAttribute("tabindex") ?? ""), e.setAttribute("tabindex", "-1");
126
- }, He = (e) => {
126
+ }, ze = (e) => {
127
127
  if (!e.hasAttribute(B))
128
128
  return;
129
129
  const a = e.getAttribute(B);
130
130
  e.removeAttribute(B), a ? e.setAttribute("tabindex", a) : e.removeAttribute("tabindex");
131
- }, Xe = {
131
+ }, Ye = {
132
132
  profile: "var(--malachite-selectable-card-selected-border, #047b43)",
133
133
  library: "var(--malachite-selectable-card-library-selected-border, #bbbbbb)",
134
134
  editing: "var(--malachite-selectable-card-pending-foreground, #96580a)"
135
- }, We = {
135
+ }, Ve = {
136
136
  backgroundRepeat: "no-repeat",
137
137
  backgroundPosition: "left bottom",
138
- backgroundSize: `100% ${ut}px`
139
- }, Bt = 0.5, Gt = q - ct, ze = (e) => {
140
- const a = e.querySelector(`:scope > .${se}`);
138
+ backgroundSize: `100% ${ft}px`
139
+ }, Ht = 0.5, Xt = K - st, Me = (e) => {
140
+ const a = e.querySelector(`:scope > .${de}`);
141
141
  if (!a)
142
142
  return null;
143
143
  const { left: l, right: u } = a.getBoundingClientRect();
144
- return { left: l + Gt, right: u - Gt };
145
- }, Ye = (e, a, l, u) => {
144
+ return { left: l + Xt, right: u - Xt };
145
+ }, qe = (e, a, l, u) => {
146
146
  if (!e)
147
147
  return;
148
- const f = Xe[u], T = e.getBoundingClientRect(), I = T.left, _ = l && (a != null && a.contains(l)) ? a.getBoundingClientRect() : T, L = l == null ? void 0 : l.getBoundingClientRect(), m = l ? ze(l) : null, j = (m == null ? void 0 : m.left) ?? (L ? L.left - ct : 0), J = (m == null ? void 0 : m.right) ?? (L ? L.right + ct : 0), P = L ? Math.max(j, _.left) + Bt - I : 0, b = L ? Math.min(J, _.right) - Bt - I : 0;
148
+ const f = Ye[u], $ = e.getBoundingClientRect(), I = $.left, _ = l && (a != null && a.contains(l)) ? a.getBoundingClientRect() : $, L = l == null ? void 0 : l.getBoundingClientRect(), m = l ? Me(l) : null, J = (m == null ? void 0 : m.left) ?? (L ? L.left - st : 0), Q = (m == null ? void 0 : m.right) ?? (L ? L.right + st : 0), P = L ? Math.max(J, _.left) + Ht - I : 0, b = L ? Math.min(Q, _.right) - Ht - I : 0;
149
149
  e.style.backgroundImage = b > P ? `linear-gradient(to right, ${f} 0 ${P}px, transparent ${P}px ${b}px, ${f} ${b}px 100%)` : `linear-gradient(to right, ${f} 0 100%)`;
150
- }, Ve = {
151
- marginInline: `calc(${$t} * -1)`,
152
- paddingInline: $t
153
- }, ft = {
154
- background: it,
155
- borderRadius: Se,
156
- paddingTop: `${v}px`,
157
- paddingInline: `${v}px`,
158
- marginBottom: `${ut}px`
159
- }, Me = {
160
- ...ft,
150
+ }, Ke = {
151
+ marginInline: `calc(${Dt} * -1)`,
152
+ paddingInline: Dt
153
+ }, pt = {
154
+ background: lt,
155
+ borderRadius: Ee,
156
+ paddingTop: `${w}px`,
157
+ paddingInline: `${w}px`,
158
+ marginBottom: `${ft}px`
159
+ }, je = {
160
+ ...pt,
161
161
  marginInline: `${H}px`
162
- }, qe = ft, Ke = ft, je = {
162
+ }, Je = pt, Qe = pt, Ze = {
163
163
  marginInlineStart: `${H}px`
164
- }, Je = {
164
+ }, tr = {
165
165
  primary: {
166
- backgroundColor: Oe,
167
- color: ve
166
+ backgroundColor: Ce,
167
+ color: Ie
168
168
  },
169
- secondary: { backgroundColor: De, color: ye }
170
- }, Vt = ({
169
+ secondary: { backgroundColor: ve, color: we }
170
+ }, qt = ({
171
171
  label: e,
172
172
  icon: a,
173
173
  onClick: l,
174
174
  disabled: u = !1,
175
175
  emphasis: f = "secondary",
176
- className: T = ""
176
+ className: $ = ""
177
177
  }) => /* @__PURE__ */ h(
178
178
  "div",
179
179
  {
180
180
  className: R,
181
181
  "data-emphasis": f,
182
182
  style: {
183
- ...qe,
184
- width: `${dt}px`,
185
- height: `calc(100% - ${ut}px)`
183
+ ...Je,
184
+ width: `${ut}px`,
185
+ height: `calc(100% - ${ft}px)`
186
186
  },
187
187
  children: /* @__PURE__ */ h("div", { className: "flex h-full items-center justify-center px-4", children: /* @__PURE__ */ U(
188
188
  "button",
@@ -190,16 +190,16 @@ const pe = /* @__PURE__ */ new Set(["ArrowLeft", "ArrowRight", "ArrowUp", "Arrow
190
190
  type: "button",
191
191
  onClick: l,
192
192
  disabled: u,
193
- style: Je[f],
194
- className: `${fe} inline-flex items-center justify-center gap-1.5 h-[var(--malachite-control-height-medium,32px)] w-[108px] px-2.5 rounded-xl border border-solid text-[length:var(--malachite-font-size-small,13px)] font-medium whitespace-nowrap ${u ? "opacity-50 cursor-not-allowed" : "cursor-pointer"} ${T}`,
193
+ style: tr[f],
194
+ className: `${me} inline-flex items-center justify-center gap-1.5 h-[var(--malachite-control-height-medium,32px)] w-[108px] px-2.5 rounded-xl border border-solid text-[length:var(--malachite-font-size-small,13px)] font-medium whitespace-nowrap ${u ? "opacity-50 cursor-not-allowed" : "cursor-pointer"} ${$}`,
195
195
  children: [
196
- /* @__PURE__ */ h("span", { className: "inline-flex h-[13px] w-[13px] shrink-0 items-center justify-center", children: a ?? /* @__PURE__ */ h(oe, { size: 13 }) }),
196
+ /* @__PURE__ */ h("span", { className: "inline-flex h-[13px] w-[13px] shrink-0 items-center justify-center", children: a ?? /* @__PURE__ */ h(se, { size: 13 }) }),
197
197
  e
198
198
  ]
199
199
  }
200
200
  ) })
201
201
  }
202
- ), lt = (e) => C.isValidElement(e) && e.type === Vt, Qe = (e) => C.isValidElement(e) && e.type === C.Fragment && C.Children.toArray(e.props.children).some(lt), Ht = ({ side: e, onClick: a }) => /* @__PURE__ */ h(
202
+ ), dt = (e) => C.isValidElement(e) && e.type === qt, er = (e) => C.isValidElement(e) && e.type === C.Fragment && C.Children.toArray(e.props.children).some(dt), Wt = ({ side: e, onClick: a }) => /* @__PURE__ */ h(
203
203
  "button",
204
204
  {
205
205
  type: "button",
@@ -209,85 +209,90 @@ const pe = /* @__PURE__ */ new Set(["ArrowLeft", "ArrowRight", "ArrowUp", "Arrow
209
209
  onClick: a,
210
210
  className: "absolute top-1/2 -translate-y-1/2 z-10 inline-flex items-center justify-center w-5 h-5 rounded-lg cursor-pointer text-[var(--malachite-text-secondary)]",
211
211
  style: {
212
- [e]: `-${xe}px`,
213
- background: Re,
214
- border: `1px solid ${_e}`,
215
- boxShadow: zt
212
+ [e]: `-${Te}px`,
213
+ background: Se,
214
+ border: `1px solid ${xe}`,
215
+ boxShadow: Vt
216
216
  },
217
- children: e === "left" ? /* @__PURE__ */ h(re, { size: vt }) : /* @__PURE__ */ h(ne, { size: vt })
217
+ children: e === "left" ? /* @__PURE__ */ h(ae, { size: Ct }) : /* @__PURE__ */ h(ce, { size: Ct })
218
218
  }
219
- ), Ze = ({
219
+ ), rr = ({
220
220
  value: e,
221
221
  tone: a,
222
222
  onChange: l,
223
223
  children: u,
224
224
  leading: f,
225
- arrows: T = !0,
225
+ arrows: $ = !0,
226
226
  fadeEdges: I = !0,
227
227
  snap: _ = !0,
228
228
  bleed: L = !1,
229
229
  scrollSelectedIntoView: m = !0,
230
- "aria-label": j,
231
- "aria-labelledby": J,
230
+ "aria-label": J,
231
+ "aria-labelledby": Q,
232
232
  className: P = "",
233
233
  style: b
234
234
  }) => {
235
- const $ = O(null), pt = O(null), k = O(null), ht = O(!1), [X, Mt] = nt({ canScrollLeft: !1, canScrollRight: !1 }), [qt, mt] = nt(!1), W = O(null), bt = O(!1);
236
- Ot($, Ie, Pe), Ot($, Ne, ke);
237
- const Q = C.Children.toArray(u), Z = Q.filter((t) => !lt(t)), Kt = Z.some(Qe), D = Z.length > 0, z = Q.filter(lt).map(
235
+ const y = T(null), ht = T(null), k = T(null), mt = T(!1), [X, Kt] = M({ canScrollLeft: !1, canScrollRight: !1 }), [jt, bt] = M(!1), W = T(null), gt = T(!1);
236
+ wt(y, Ne, Fe), wt(y, Be, Ue);
237
+ const Z = C.Children.toArray(u), tt = Z.filter((t) => !dt(t)), Jt = tt.some(er), D = tt.length > 0, z = Z.filter(dt).map(
238
238
  (t) => t.props.emphasis === void 0 ? C.cloneElement(t, { emphasis: D ? "secondary" : "primary" }) : t
239
- ), gt = Q.length, tt = z.length;
240
- w(() => {
241
- const t = $.current;
242
- if (!t || !D || tt === 0) {
243
- mt(!1);
239
+ ), Rt = Z.length, et = z.length;
240
+ v(() => {
241
+ const t = y.current;
242
+ if (!t || !D || et === 0) {
243
+ bt(!1);
244
244
  return;
245
245
  }
246
- const r = pt.current, { paddingLeft: o, paddingRight: s } = getComputedStyle(t), i = (parseFloat(o) || 0) + (parseFloat(s) || 0);
246
+ const r = ht.current, { paddingLeft: o, paddingRight: s } = getComputedStyle(t), i = (parseFloat(o) || 0) + (parseFloat(s) || 0);
247
247
  let d = t.clientWidth - i, p = (r == null ? void 0 : r.offsetWidth) ?? 0;
248
248
  const n = () => {
249
- const y = p + tt * dt + Le;
250
- mt(d > 0 && d < y);
249
+ const O = p + et * ut + $e;
250
+ bt(d > 0 && d < O);
251
251
  };
252
252
  n();
253
- const c = typeof ResizeObserver < "u" ? new ResizeObserver((y) => {
254
- var E, Tt;
255
- for (const V of y ?? [])
256
- V.target === t ? d = V.contentRect.width : p = ((Tt = (E = V.borderBoxSize) == null ? void 0 : E[0]) == null ? void 0 : Tt.inlineSize) ?? V.contentRect.width + 2 * v;
253
+ const c = typeof ResizeObserver < "u" ? new ResizeObserver((O) => {
254
+ var E, yt;
255
+ for (const V of O ?? [])
256
+ V.target === t ? d = V.contentRect.width : p = ((yt = (E = V.borderBoxSize) == null ? void 0 : E[0]) == null ? void 0 : yt.inlineSize) ?? V.contentRect.width + 2 * w;
257
257
  n();
258
258
  }) : null;
259
259
  return c == null || c.observe(t), r && (c == null || c.observe(r)), () => c == null ? void 0 : c.disconnect();
260
- }, [D, tt, !!f]);
261
- const et = qt && D, Rt = S((t) => {
260
+ }, [D, et, !!f]);
261
+ const rt = jt && D, _t = x((t) => {
262
262
  var o;
263
263
  const r = t.type === "focus" ? t.target : t.relatedTarget;
264
- bt.current = !!(r instanceof Node && ((o = W.current) != null && o.contains(r)));
264
+ gt.current = !!(r instanceof Node && ((o = W.current) != null && o.contains(r)));
265
265
  }, []);
266
- w(() => {
266
+ v(() => {
267
267
  var o;
268
268
  const t = W.current, r = t ? t.getRootNode().activeElement : null;
269
- bt.current && t && !(r && t.contains(r)) && ((o = t.querySelector("button")) == null || o.focus({ preventScroll: !0 }));
270
- }, [et]);
271
- const A = S(() => {
272
- const t = $.current;
269
+ gt.current && t && !(r && t.contains(r)) && ((o = t.querySelector("button")) == null || o.focus({ preventScroll: !0 }));
270
+ }, [rt]);
271
+ const A = x(() => {
272
+ const t = y.current;
273
273
  return t ? Array.from(t.querySelectorAll(G)) : [];
274
- }, []), rt = S(
275
- () => A().filter((t) => x(t) !== null),
274
+ }, []), nt = T(null), [At, Qt] = M(0);
275
+ v(() => {
276
+ const t = JSON.stringify(A().map(S));
277
+ nt.current !== null && nt.current !== t && Qt((r) => r + 1), nt.current = t;
278
+ });
279
+ const ot = x(
280
+ () => A().filter((t) => S(t) !== null),
276
281
  [A]
277
- ), _t = O(/* @__PURE__ */ new Set()), N = S((t, r) => {
278
- _t.current.has(t) || (_t.current.add(t), console.warn(r));
279
- }, []), [jt, Jt] = nt("profile");
280
- w(() => {
282
+ ), St = T(/* @__PURE__ */ new Set()), N = x((t, r) => {
283
+ St.current.has(t) || (St.current.add(t), console.warn(r));
284
+ }, []), [Zt, te] = M("profile");
285
+ v(() => {
281
286
  var r, o;
282
- const t = (o = (r = A().find((s) => x(s) === e)) == null ? void 0 : r.parentElement) == null ? void 0 : o.getAttribute("data-variant");
283
- (t === "profile" || t === "library" || t === "editing") && Jt(t);
284
- }, [A, e]), w(() => {
285
- const t = A(), r = rt(), s = r.find((n) => x(n) === e) ?? r.find((n) => !at(n)) ?? null;
287
+ const t = (o = (r = A().find((s) => S(s) === e)) == null ? void 0 : r.parentElement) == null ? void 0 : o.getAttribute("data-variant");
288
+ (t === "profile" || t === "library" || t === "editing") && te(t);
289
+ }, [A, e]), v(() => {
290
+ const t = A(), r = ot(), s = r.find((n) => S(n) === e) ?? r.find((n) => !ct(n)) ?? null;
286
291
  if (t.forEach((n) => {
287
- const c = n === s, y = c ? 0 : -1;
288
- n.tabIndex !== y && (n.tabIndex = y);
289
- for (const E of Be(n))
290
- c ? He(E) : Ge(E);
292
+ const c = n === s, O = c ? 0 : -1;
293
+ n.tabIndex !== O && (n.tabIndex = O);
294
+ for (const E of Xe(n))
295
+ c ? ze(E) : We(E);
291
296
  }), process.env.NODE_ENV === "production")
292
297
  return;
293
298
  r.length !== t.length && N(
@@ -296,7 +301,7 @@ const pe = /* @__PURE__ */ new Set(["ArrowLeft", "ArrowRight", "ArrowUp", "Arrow
296
301
  );
297
302
  const i = /* @__PURE__ */ new Set();
298
303
  for (const n of r) {
299
- const c = x(n);
304
+ const c = S(n);
300
305
  c !== null && (i.has(c) && N(
301
306
  `duplicate:${c}`,
302
307
  `CardStrip: two cards share the data-value "${c}". Both will read as checked and only the first is selectable — data-value must be unique.`
@@ -313,55 +318,55 @@ const pe = /* @__PURE__ */ new Set(["ArrowLeft", "ArrowRight", "ArrowUp", "Arrow
313
318
  t.length > 0 && d && p !== 1 && N(
314
319
  `checked:${p}`,
315
320
  `CardStrip: ${p} cards are aria-checked, but a radiogroup has exactly one. Drive each card's checked state from the strip's \`value\`.`
316
- ), Kt && N(
321
+ ), Jt && N(
317
322
  "wrapped-add-tile",
318
323
  "CardStrip: a CardStrip.AddTile inside a fragment is treated as a card and scrolls with them. The add tile must be a direct child of CardStrip."
319
324
  );
320
325
  });
321
- const F = S(() => {
322
- const t = A().find((r) => x(r) === e);
326
+ const F = x(() => {
327
+ const t = A().find((r) => S(r) === e);
323
328
  return t ? t.closest('[role="radio"]') ?? t : null;
324
329
  }, [A, e]);
325
- w(() => {
330
+ v(() => {
326
331
  if (!m)
327
332
  return;
328
333
  const t = k.current, r = F();
329
334
  if (!t || !r || typeof t.scrollTo != "function")
330
335
  return;
331
- const o = ht.current;
332
- ht.current = !0;
333
- const s = Dt(t, r, _);
336
+ const o = mt.current;
337
+ mt.current = !0;
338
+ const s = Ot(t, r, _);
334
339
  s !== null && t.scrollTo({
335
340
  left: s,
336
- behavior: o && !Ut() ? "smooth" : "instant"
341
+ behavior: o && !Gt() ? "smooth" : "instant"
337
342
  });
338
- }, [F, m, _, gt]);
339
- const At = a ?? jt, St = (b == null ? void 0 : b.background) !== void 0 || (b == null ? void 0 : b.backgroundImage) !== void 0, Y = S(() => {
343
+ }, [F, m, _, Rt, At]);
344
+ const xt = a ?? Zt, Lt = (b == null ? void 0 : b.background) !== void 0 || (b == null ? void 0 : b.backgroundImage) !== void 0, Y = x(() => {
340
345
  var p;
341
346
  const t = k.current;
342
- if (St || Ye(
343
- $.current,
347
+ if (Lt || qe(
348
+ y.current,
344
349
  t,
345
- (p = A().find((n) => x(n) === e)) == null ? void 0 : p.parentElement,
346
- At
350
+ (p = A().find((n) => S(n) === e)) == null ? void 0 : p.parentElement,
351
+ xt
347
352
  ), !t)
348
353
  return;
349
- const { scrollWidth: r, clientWidth: o, scrollLeft: s } = t, i = r > o + ot, d = {
350
- canScrollLeft: i && s > ot,
351
- canScrollRight: i && s + o < r - ot
354
+ const { scrollWidth: r, clientWidth: o, scrollLeft: s } = t, i = r > o + at, d = {
355
+ canScrollLeft: i && s > at,
356
+ canScrollRight: i && s + o < r - at
352
357
  };
353
- Mt(
358
+ Kt(
354
359
  (n) => n.canScrollLeft === d.canScrollLeft && n.canScrollRight === d.canScrollRight ? n : d
355
360
  );
356
- }, [St, A, At, e]);
357
- w(() => {
361
+ }, [Lt, A, xt, e]);
362
+ v(() => {
358
363
  Y();
359
364
  const t = k.current;
360
365
  if (!t)
361
366
  return;
362
367
  const r = () => {
363
368
  const c = F();
364
- return c !== null && le(t, c);
369
+ return c !== null && fe(t, c);
365
370
  };
366
371
  let o = r();
367
372
  const s = () => {
@@ -370,7 +375,7 @@ const pe = /* @__PURE__ */ new Set(["ArrowLeft", "ArrowRight", "ArrowUp", "Arrow
370
375
  t.addEventListener("scroll", s, { passive: !0 });
371
376
  let i = 0;
372
377
  const d = () => {
373
- const c = F(), E = m && o && typeof t.scrollTo == "function" && c ? Dt(t, c, _) : null;
378
+ const c = F(), E = m && o && typeof t.scrollTo == "function" && c ? Ot(t, c, _) : null;
374
379
  E !== null && t.scrollTo({ left: E, behavior: "instant" }), o = r();
375
380
  }, p = () => {
376
381
  if (Y(), typeof requestAnimationFrame != "function") {
@@ -382,28 +387,28 @@ const pe = /* @__PURE__ */ new Set(["ArrowLeft", "ArrowRight", "ArrowUp", "Arrow
382
387
  return n == null || n.observe(t), () => {
383
388
  t.removeEventListener("scroll", s), n == null || n.disconnect(), typeof cancelAnimationFrame == "function" && cancelAnimationFrame(i);
384
389
  };
385
- }, [Y, F, m, _, gt]);
386
- const xt = S(
390
+ }, [Y, F, m, _, Rt, At]);
391
+ const Et = x(
387
392
  (t) => {
388
393
  const r = k.current;
389
394
  !r || typeof r.scrollBy != "function" || r.scrollBy({
390
- left: ie(r, t, _) - r.scrollLeft,
391
- behavior: Ut() ? "auto" : "smooth"
395
+ left: ue(r, t, _) - r.scrollLeft,
396
+ behavior: Gt() ? "auto" : "smooth"
392
397
  });
393
398
  },
394
399
  [_]
395
- ), Qt = S(
400
+ ), ee = x(
396
401
  (t) => {
397
- if (!pe.has(t.key))
402
+ if (!be.has(t.key))
398
403
  return;
399
404
  const r = t.target;
400
405
  if (!(r instanceof Element) || !r.closest(G))
401
406
  return;
402
- const o = rt().filter((n) => !at(n));
407
+ const o = ot().filter((n) => !ct(n));
403
408
  if (o.length === 0)
404
409
  return;
405
410
  t.preventDefault();
406
- const s = o.findIndex((n) => x(n) === e);
411
+ const s = o.findIndex((n) => S(n) === e);
407
412
  let i;
408
413
  if (t.key === "Home")
409
414
  i = 0;
@@ -413,38 +418,38 @@ const pe = /* @__PURE__ */ new Set(["ArrowLeft", "ArrowRight", "ArrowUp", "Arrow
413
418
  const n = t.key === "ArrowLeft" || t.key === "ArrowUp" ? -1 : 1;
414
419
  i = ((s === -1 ? 0 : s) + n + o.length) % o.length;
415
420
  }
416
- const d = o[i], p = x(d);
421
+ const d = o[i], p = S(d);
417
422
  p !== null && p !== e && l(p), d.focus();
418
423
  },
419
- [rt, l, e]
420
- ), Zt = S(
424
+ [ot, l, e]
425
+ ), re = x(
421
426
  (t) => {
422
427
  const r = t.target;
423
428
  if (!(r instanceof Element) || r.closest(`.${R}`))
424
429
  return;
425
- const o = $.current;
430
+ const o = y.current;
426
431
  if (!o)
427
432
  return;
428
- const s = Ue(r, o);
429
- if (!s || at(s))
433
+ const s = He(r, o);
434
+ if (!s || ct(s))
430
435
  return;
431
- const i = x(s);
436
+ const i = S(s);
432
437
  i !== null && i !== e && l(i);
433
438
  },
434
439
  [l, e]
435
- ), te = T && X.canScrollLeft, ee = T && X.canScrollRight, Lt = I && X.canScrollLeft, Et = I && X.canScrollRight;
440
+ ), ne = $ && X.canScrollLeft, oe = $ && X.canScrollRight, Tt = I && X.canScrollLeft, $t = I && X.canScrollRight;
436
441
  return /* @__PURE__ */ U(
437
442
  "div",
438
443
  {
439
- ref: $,
440
- onKeyDown: Qt,
441
- onFocus: Rt,
442
- onBlur: Rt,
443
- onClick: Zt,
444
- className: `${K} flex items-stretch ${P}`,
444
+ ref: y,
445
+ onKeyDown: ee,
446
+ onFocus: _t,
447
+ onBlur: _t,
448
+ onClick: re,
449
+ className: `${j} flex items-stretch ${P}`,
445
450
  style: {
446
- ...We,
447
- ...L ? Ve : null,
451
+ ...Ve,
452
+ ...L ? Ke : null,
448
453
  ...b
449
454
  },
450
455
  children: [
@@ -452,43 +457,43 @@ const pe = /* @__PURE__ */ new Set(["ArrowLeft", "ArrowRight", "ArrowUp", "Arrow
452
457
  "div",
453
458
  {
454
459
  role: "radiogroup",
455
- "aria-label": j,
456
- "aria-labelledby": J,
460
+ "aria-label": J,
461
+ "aria-labelledby": Q,
457
462
  className: D ? "flex items-stretch min-w-0" : "flex items-stretch",
458
463
  children: [
459
- f ? /* @__PURE__ */ h(yt.Provider, { value: de, children: /* @__PURE__ */ h("div", { ref: pt, className: "shrink-0", style: Ke, children: f }) }) : null,
464
+ f ? /* @__PURE__ */ h(vt.Provider, { value: pe, children: /* @__PURE__ */ h("div", { ref: ht, className: "shrink-0", style: Qe, children: f }) }) : null,
460
465
  D ? /* @__PURE__ */ U(
461
466
  "div",
462
467
  {
463
- [me]: "",
468
+ [Re]: "",
464
469
  className: "relative min-w-0 shrink basis-auto",
465
- style: Me,
470
+ style: je,
466
471
  children: [
467
472
  /* @__PURE__ */ U(
468
473
  "div",
469
474
  {
470
475
  ref: k,
471
476
  tabIndex: -1,
472
- [he]: "",
477
+ [ge]: "",
473
478
  "data-snap": _ ? "true" : "false",
474
479
  className: g,
475
480
  children: [
476
- /* @__PURE__ */ h(yt.Provider, { value: ue, children: Z }),
477
- et ? /* @__PURE__ */ h("div", { ref: W, [st]: "", children: z }) : null
481
+ /* @__PURE__ */ h(vt.Provider, { value: he, children: tt }),
482
+ rt ? /* @__PURE__ */ h("div", { ref: W, [it]: "", children: z }) : null
478
483
  ]
479
484
  }
480
485
  ),
481
- te ? /* @__PURE__ */ h(Ht, { side: "left", onClick: () => xt(-1) }) : null,
482
- ee ? /* @__PURE__ */ h(Ht, { side: "right", onClick: () => xt(1) }) : null,
483
- Lt || Et ? /* @__PURE__ */ h(
486
+ ne ? /* @__PURE__ */ h(Wt, { side: "left", onClick: () => Et(-1) }) : null,
487
+ oe ? /* @__PURE__ */ h(Wt, { side: "right", onClick: () => Et(1) }) : null,
488
+ Tt || $t ? /* @__PURE__ */ h(
484
489
  "div",
485
490
  {
486
491
  "aria-hidden": !0,
487
492
  "data-card-strip-fade": "",
488
- className: `${Xt} absolute pointer-events-none`,
493
+ className: `${zt} absolute pointer-events-none`,
489
494
  style: {
490
- inset: `-${v}px -${Yt}px 0`,
491
- background: `linear-gradient(to right, ${Lt ? Pt : "transparent"} 0, transparent ${It}px, transparent calc(100% - ${It}px), ${Et ? Pt : "transparent"} 100%)`
495
+ inset: `-${w}px -${Mt}px 0`,
496
+ background: `linear-gradient(to right, ${Tt ? Nt : "transparent"} 0, transparent ${kt}px, transparent calc(100% - ${kt}px), ${$t ? Nt : "transparent"} 100%)`
492
497
  }
493
498
  }
494
499
  ) : null
@@ -498,12 +503,12 @@ const pe = /* @__PURE__ */ new Set(["ArrowLeft", "ArrowRight", "ArrowUp", "Arrow
498
503
  ]
499
504
  }
500
505
  ),
501
- z.length > 0 && !et ? /* @__PURE__ */ h(
506
+ z.length > 0 && !rt ? /* @__PURE__ */ h(
502
507
  "div",
503
508
  {
504
509
  ref: W,
505
510
  className: "shrink-0",
506
- style: !D && f ? je : void 0,
511
+ style: !D && f ? Ze : void 0,
507
512
  children: z
508
513
  }
509
514
  ) : null
@@ -511,9 +516,9 @@ const pe = /* @__PURE__ */ new Set(["ArrowLeft", "ArrowRight", "ArrowUp", "Arrow
511
516
  }
512
517
  );
513
518
  };
514
- Ze.AddTile = Vt;
519
+ rr.AddTile = qt;
515
520
  export {
516
- Ze as CardStrip,
517
- Ze as default
521
+ rr as CardStrip,
522
+ rr as default
518
523
  };
519
524
  //# sourceMappingURL=CardStrip.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"CardStrip.js","sources":["../../src/components/CardStrip.tsx"],"sourcesContent":["import React, { useCallback, useLayoutEffect, useRef, useState } from 'react';\nimport ArrowLeftIcon from './CustomIcons/ArrowLeftIcon';\nimport ForwardArrowIcon from './CustomIcons/ForwardArrowIcon';\nimport PlusIcon from './CustomIcons/PlusIcon';\nimport { CONTENT_INSET } from './PageLayout/constants';\nimport {\n CARD_FLARE_PX,\n CARD_FLARE_TIP_PX,\n CARD_WIDTH_PX,\n FLARE_CLASS,\n STRIP_RULE_PX,\n} from './SelectableCard';\nimport {\n EDGE_EPSILON_PX,\n isCardInView,\n pageTargetFor,\n revealTargetFor,\n} from './cardStripGeometry';\nimport { CardStripSlotContext, PINNED_SLOT, SCROLLED_SLOT } from './cardStripSlot';\nimport { FOCUS_RING } from './focusRing';\nimport { useAdoptedStyleSheet } from './useAdoptedStyleSheet';\n\nexport type CardStripAddTileEmphasis = 'primary' | 'secondary';\n\nexport interface CardStripAddTileProps {\n /** Visible label, e.g. \"Add Profile\". Also names the button for assistive tech. */\n label: string;\n /** Defaults to a plus. */\n icon?: React.ReactNode;\n onClick: () => void;\n disabled?: boolean;\n /** Leave unset: CardStrip picks `primary` while the strip is empty and `secondary` once cards exist. */\n emphasis?: CardStripAddTileEmphasis;\n className?: string;\n}\n\n/** Palette for the strip's rule. Pass the tone of whatever card is selected. */\nexport type CardStripTone = 'profile' | 'library' | 'editing';\n\nexport interface CardStripProps {\n /** The selected card's value, matched against each radio child's `data-value`. */\n value: string;\n /** Overrides the palette the strip reads off the selected card. See `CardStripTone`. */\n tone?: CardStripTone;\n onChange: (value: string) => void;\n /** Cards. Any element with `role=\"radio\"` and a `data-value` joins the group; an\n * add tile must be a direct child or it scrolls with the cards. */\n children: React.ReactNode;\n /** Pinned, non-scrolling slot before the cards (the Library card in the profile picker). */\n leading?: React.ReactNode;\n /** Circular scroll affordances, shown only on an edge that can actually scroll. */\n arrows?: boolean;\n /** Fade the cards out at any edge they scroll past. */\n fadeEdges?: boolean;\n /** Snap cards to the leading edge as the strip scrolls. */\n snap?: boolean;\n /** Run the bottom rule the full width of the page card while the cards stay on the gutter.\n * Only has an effect inside a layout that publishes its inset (`PageLayout`). */\n bleed?: boolean;\n /** Whether a selection change scrolls the selected card into view. The strip's opening\n * selection is placed instantly; later ones slide, unless motion is reduced. Set `false`\n * when the value comes from a URL, or a deep-linked strip below the fold jumps the page\n * on load. */\n scrollSelectedIntoView?: boolean;\n 'aria-label'?: string;\n 'aria-labelledby'?: string;\n className?: string;\n style?: React.CSSProperties;\n}\n\n/** Arrow keys move AND select, per the WAI-ARIA radiogroup pattern. */\nconst NAV_KEYS = new Set(['ArrowLeft', 'ArrowRight', 'ArrowUp', 'ArrowDown', 'Home', 'End']);\n\nconst RADIO_SELECTOR = '[role=\"radio\"]';\nconst SCROLLER_ATTR = 'data-card-strip-scroller';\nconst TROUGH_ATTR = 'data-card-strip-trough';\nconst ROOT_CLASS = 'malachite-card-strip';\nconst SCROLLER_CLASS = 'malachite-card-strip-scroller';\nconst FADE_CLASS = 'malachite-card-strip-fade';\nconst ADD_TILE_CLASS = 'malachite-card-strip-add-tile';\nconst ADD_SLOT_ATTR = 'data-card-strip-add-slot';\n\nconst ACTIONS_SELECTOR = '[data-selectable-card-actions]';\nconst FOCUSABLE_SELECTOR =\n 'a[href], area[href], button, input, select, textarea, iframe, [contenteditable=\"true\"], [tabindex]';\nconst PREV_TABINDEX_ATTR = 'data-card-strip-prev-tabindex';\n\nconst FADE_WIDTH_PX = 80;\n\nconst ARROW_GLYPH_PX = 11;\nconst GUTTER_REST_PX = 12;\n\nconst LIP_SHADOW = 'var(--malachite-shadow-default)';\nconst ARROW_BACKGROUND =\n 'var(--malachite-card-strip-arrow-background, var(--malachite-card-background, #ffffff))';\nconst ARROW_BORDER = 'var(--malachite-card-strip-arrow-border, #e8e8e8)';\nconst TROUGH_BACKGROUND = 'var(--malachite-card-strip-background, #f1f1f1)';\nconst CARD_CORNER = 'var(--malachite-radius-xxl, 14px)';\nconst CARD_RADIUS = `${CARD_CORNER} ${CARD_CORNER} 0 0`;\nconst TROUGH_CORNER = 'var(--malachite-radius-xxxl, 16px)';\nconst TROUGH_RADIUS = `${TROUGH_CORNER} ${TROUGH_CORNER} 0 0`;\nconst TROUGH_SHOULDER_PX = 4;\n// Fills the gap between the edge card and its neighbour, covering neither.\nconst ARROW_OFFSET_PX = GUTTER_REST_PX + TROUGH_SHOULDER_PX;\n// Any wider and the fade paints over the neighbouring slot.\nconst FADE_OVERHANG_PX = GUTTER_REST_PX;\nconst FADE_RAMP_PX = FADE_WIDTH_PX + (FADE_OVERHANG_PX - TROUGH_SHOULDER_PX);\nconst SLOT_WIDTH_PX = CARD_WIDTH_PX;\nconst TROUGH_FLOOR_PX = 2 * (GUTTER_REST_PX + TROUGH_SHOULDER_PX) + SLOT_WIDTH_PX;\nconst DIVIDER_COLOR = 'var(--malachite-card-strip-divider, #dddddd)';\nconst FADE_COLOR = 'var(--malachite-card-strip-fade, transparent)';\nconst ADD_HOVER_BACKGROUND = 'var(--malachite-selectable-card-hover-background, #e8e8e8)';\nconst ADD_PILL_BORDER = 'var(--malachite-card-strip-arrow-border, #e8e8e8)';\nconst ADD_PILL_BORDER_ACTIVE = 'var(--malachite-selectable-card-hover-rule, #bbbbbb)';\nconst ADD_PILL_SHADOW_DEEP = '0px 1px 0px 0px rgba(0, 0, 0, 0.4)';\nconst ADD_PILL_BACKGROUND = 'var(--malachite-card-background, #ffffff)';\nconst ADD_PILL_FOREGROUND = 'var(--malachite-text-primary, #0a0a0a)';\nconst ADD_PILL_PRIMARY_BACKGROUND =\n 'var(--malachite-card-strip-add-primary-background, var(--malachite-text-primary, #0a0a0a))';\nconst ADD_PILL_PRIMARY_FOREGROUND =\n 'var(--malachite-card-strip-add-primary-foreground, var(--malachite-card-background, #ffffff))';\nconst ADD_PILL_PRIMARY_SHADOW = '0px 1px 0px 0px rgba(10, 10, 10, 0.7)';\n\nconst BOTTOM_RULE_WEIGHT_PX = STRIP_RULE_PX;\n\nconst OVERFLOW_INSET_PX = 16;\n\nconst CLIP_SLACK_PX = 9999;\nconst FOCUS_RING_REACH_PX = 4;\n\n/** A sheet, not inline styles: these rules have to reach children this component does not render. */\nconst SCROLLER_CSS = `\n.${ROOT_CLASS} {\n clip-path: inset(-${CLIP_SLACK_PX}px -${CLIP_SLACK_PX}px 0);\n}\n.${ROOT_CLASS}:has(:focus-visible) {\n clip-path: inset(-${CLIP_SLACK_PX}px -${CLIP_SLACK_PX}px -${FOCUS_RING_REACH_PX}px);\n}\n.${SCROLLER_CLASS} {\n display: flex;\n flex-wrap: nowrap;\n overflow-x: auto;\n overflow-y: hidden;\n scroll-behavior: smooth;\n scrollbar-width: none;\n -ms-overflow-style: none;\n padding-block: ${OVERFLOW_INSET_PX}px;\n margin-block: -${OVERFLOW_INSET_PX}px;\n /* overflow-x clips both axes, so the end cards would lose a flare; the negative margin trades\n the padding back out and scroll-padding keeps the rest position at zero. */\n padding-inline: ${CARD_FLARE_PX}px;\n margin-inline: -${CARD_FLARE_PX}px;\n scroll-padding-inline: ${CARD_FLARE_PX}px;\n}\n/* A card focused at a faded edge has to stay readable, so the fade lifts entirely. */\n.${ROOT_CLASS}:has(:focus-visible) .${FADE_CLASS} {\n display: none;\n}\n.${SCROLLER_CLASS}::-webkit-scrollbar {\n display: none;\n}\n/* No bottom edge: the strip's rule is the baseline for the add tile as much as for a card. */\n.${ADD_TILE_CLASS} > * {\n background: ${TROUGH_BACKGROUND};\n border-radius: ${CARD_RADIUS};\n}\n.${ADD_TILE_CLASS}:hover:not(:has(button:disabled)) > * {\n background: ${ADD_HOVER_BACKGROUND};\n}\n.${ADD_TILE_CLASS} button:active:not(:disabled) {\n opacity: 0.8;\n}\n.${ADD_TILE_CLASS}:has(button:active) > * {\n background: ${TROUGH_BACKGROUND};\n}\n.${ADD_TILE_CLASS}[data-emphasis='secondary'] button {\n border-color: ${ADD_PILL_BORDER};\n box-shadow: ${LIP_SHADOW};\n}\n.${ADD_TILE_CLASS}[data-emphasis='secondary']:hover:not(:has(button:disabled)) button {\n border-color: ${ADD_PILL_BORDER_ACTIVE};\n box-shadow: ${ADD_PILL_SHADOW_DEEP};\n}\n.${ADD_TILE_CLASS}[data-emphasis='secondary'] button:active:not(:disabled) {\n border-color: ${ADD_PILL_BORDER_ACTIVE};\n box-shadow: ${ADD_PILL_SHADOW_DEEP};\n}\n.${ADD_TILE_CLASS}[data-emphasis='primary'] button {\n border-color: transparent;\n box-shadow: ${ADD_PILL_PRIMARY_SHADOW};\n}\n.${SCROLLER_CLASS} > * {\n flex: 0 0 auto;\n min-width: 0;\n}\n.${SCROLLER_CLASS} > * + * {\n border-left: 1px solid ${DIVIDER_COLOR};\n}\n.${SCROLLER_CLASS}[data-snap='true'] {\n scroll-snap-type: x proximity;\n}\n.${SCROLLER_CLASS}[data-snap='true'] > * {\n scroll-snap-align: start;\n}\n@media (prefers-reduced-motion: reduce) {\n .${SCROLLER_CLASS} {\n scroll-behavior: auto;\n }\n .${SCROLLER_CLASS}[data-snap='true'] {\n scroll-snap-type: none;\n }\n .${SCROLLER_CLASS}[data-snap='true'] > * {\n scroll-snap-align: none;\n }\n}`;\n\nconst STYLE_ID = 'malachite-card-strip-style';\n// Its own id: an older malachite copy on the page may already own STYLE_ID without these rules.\nconst ADD_SLOT_STYLE_ID = 'malachite-card-strip-add-slot';\n// In the track the trough is already the tile's shoulder, and it is no card to rule off.\nconst ADD_SLOT_CSS = `\n.${SCROLLER_CLASS} > [${ADD_SLOT_ATTR}] {\n display: flex;\n border-left: none;\n}\n[${ADD_SLOT_ATTR}] > .${ADD_TILE_CLASS} {\n height: 100% !important;\n padding: 0 !important;\n}\n`;\n\n/** `window.matchMedia` is absent under SSR and in older test environments. */\nconst prefersReducedMotion = (): boolean => {\n if (typeof window === 'undefined' || typeof window.matchMedia !== 'function') {\n return true;\n }\n return window.matchMedia('(prefers-reduced-motion: reduce)').matches;\n};\n\nconst radioValue = (radio: HTMLElement): string | null =>\n radio.dataset.value ?? radio.getAttribute('value');\n\nconst isRadioDisabled = (radio: HTMLElement): boolean =>\n radio.hasAttribute('disabled') || radio.getAttribute('aria-disabled') === 'true';\n\nconst actionsFor = (radio: HTMLElement): HTMLElement | null => {\n const card = radio.parentElement;\n if (!card || card.querySelectorAll(RADIO_SELECTOR).length !== 1) {\n return null;\n }\n return card.querySelector<HTMLElement>(ACTIONS_SELECTOR);\n};\n\n/** A card is wider than its radio, so `closest` misses clicks on the count row. */\nconst radioForClick = (target: Element, root: Element): HTMLElement | null => {\n const direct = target.closest<HTMLElement>(RADIO_SELECTOR);\n if (direct) {\n return direct;\n }\n if (target.closest(ACTIONS_SELECTOR)) {\n return null;\n }\n let node: Element | null = target;\n while (node && root.contains(node)) {\n const radios: NodeListOf<HTMLElement> = node.querySelectorAll(RADIO_SELECTOR);\n if (radios.length === 1 && radios[0].parentElement === node) {\n return radios[0];\n }\n node = node.parentElement;\n }\n return null;\n};\n\nconst actionControls = (radio: HTMLElement): HTMLElement[] => {\n const actions = actionsFor(radio);\n return actions ? Array.from(actions.querySelectorAll<HTMLElement>(FOCUSABLE_SELECTOR)) : [];\n};\n\nconst suppressTabStop = (element: HTMLElement): void => {\n if (!element.hasAttribute(PREV_TABINDEX_ATTR)) {\n element.setAttribute(PREV_TABINDEX_ATTR, element.getAttribute('tabindex') ?? '');\n }\n element.setAttribute('tabindex', '-1');\n};\n\nconst restoreTabStop = (element: HTMLElement): void => {\n if (!element.hasAttribute(PREV_TABINDEX_ATTR)) {\n return;\n }\n const previous = element.getAttribute(PREV_TABINDEX_ATTR);\n element.removeAttribute(PREV_TABINDEX_ATTR);\n if (previous) {\n element.setAttribute('tabindex', previous);\n } else {\n element.removeAttribute('tabindex');\n }\n};\n\nconst TONE_RULE: Record<CardStripTone, string> = {\n profile: 'var(--malachite-selectable-card-selected-border, #047b43)',\n library: 'var(--malachite-selectable-card-library-selected-border, #bbbbbb)',\n editing: 'var(--malachite-selectable-card-pending-foreground, #96580a)',\n};\nconst RULE_ROW_STYLE: React.CSSProperties = {\n backgroundRepeat: 'no-repeat',\n backgroundPosition: 'left bottom',\n backgroundSize: `100% ${BOTTOM_RULE_WEIGHT_PX}px`,\n};\n\n/** The rule runs under the flare's tip rather than butting against it, so antialiasing\n * cannot open the junction into a gap. */\nconst RULE_GAP_OVERLAP_PX = 0.5;\n\nconst FLARE_TIP_INSET_PX = CARD_FLARE_PX - CARD_FLARE_TIP_PX;\n\nconst flareTips = (card: HTMLElement): { left: number; right: number } | null => {\n const flare = card.querySelector(`:scope > .${FLARE_CLASS}`);\n if (!flare) {\n return null;\n }\n const { left, right } = flare.getBoundingClientRect();\n return { left: left + FLARE_TIP_INSET_PX, right: right - FLARE_TIP_INSET_PX };\n};\n\n/** The rule is cut where the selected card stands, never covered: the strip's clip lands on the\n * rule's own edge, so a cover takes the same partial alpha and the rule bleeds through it. */\nconst paintRule = (\n root: HTMLElement | null,\n scroller: HTMLElement | null,\n card: HTMLElement | null | undefined,\n tone: CardStripTone,\n): void => {\n if (!root) {\n return;\n }\n const colour = TONE_RULE[tone];\n const rootRect = root.getBoundingClientRect();\n const rootLeft = rootRect.left;\n const clip = card && scroller?.contains(card) ? scroller.getBoundingClientRect() : rootRect;\n const cardRect = card?.getBoundingClientRect();\n const tips = card ? flareTips(card) : null;\n const tipLeft = tips?.left ?? (cardRect ? cardRect.left - CARD_FLARE_TIP_PX : 0);\n const tipRight = tips?.right ?? (cardRect ? cardRect.right + CARD_FLARE_TIP_PX : 0);\n const from = cardRect ? Math.max(tipLeft, clip.left) + RULE_GAP_OVERLAP_PX - rootLeft : 0;\n const to = cardRect ? Math.min(tipRight, clip.right) - RULE_GAP_OVERLAP_PX - rootLeft : 0;\n\n root.style.backgroundImage =\n to > from\n ? `linear-gradient(to right, ${colour} 0 ${from}px, transparent ${from}px ${to}px, ${colour} ${to}px 100%)`\n : `linear-gradient(to right, ${colour} 0 100%)`;\n};\n\nconst BLEED_STYLE: React.CSSProperties = {\n marginInline: `calc(${CONTENT_INSET} * -1)`,\n paddingInline: CONTENT_INSET,\n};\n\n/** The rule's row is a margin, never padding: a background paints under its own padding, which\n * would hide the very line the troughs stand on. */\nconst TROUGH_SURFACE: React.CSSProperties = {\n background: TROUGH_BACKGROUND,\n borderRadius: TROUGH_RADIUS,\n paddingTop: `${TROUGH_SHOULDER_PX}px`,\n paddingInline: `${TROUGH_SHOULDER_PX}px`,\n marginBottom: `${BOTTOM_RULE_WEIGHT_PX}px`,\n};\nconst TROUGH_STYLE: React.CSSProperties = {\n ...TROUGH_SURFACE,\n marginInline: `${GUTTER_REST_PX}px`,\n};\nconst ADD_TILE_SHAPE_STYLE: React.CSSProperties = TROUGH_SURFACE;\n\nconst PINNED_SLOT_STYLE: React.CSSProperties = TROUGH_SURFACE;\n\nconst EMPTY_ADD_SLOT_STYLE: React.CSSProperties = {\n marginInlineStart: `${GUTTER_REST_PX}px`,\n};\n\nconst ADD_PILL_FILL: Record<CardStripAddTileEmphasis, React.CSSProperties> = {\n primary: {\n backgroundColor: ADD_PILL_PRIMARY_BACKGROUND,\n color: ADD_PILL_PRIMARY_FOREGROUND,\n },\n secondary: { backgroundColor: ADD_PILL_BACKGROUND, color: ADD_PILL_FOREGROUND },\n};\n\nconst AddTile: React.FC<CardStripAddTileProps> = ({\n label,\n icon,\n onClick,\n disabled = false,\n emphasis = 'secondary',\n className = '',\n}) => (\n <div\n className={ADD_TILE_CLASS}\n data-emphasis={emphasis}\n style={{\n ...ADD_TILE_SHAPE_STYLE,\n width: `${SLOT_WIDTH_PX}px`,\n height: `calc(100% - ${BOTTOM_RULE_WEIGHT_PX}px)`,\n }}\n >\n <div className=\"flex h-full items-center justify-center px-4\">\n <button\n type=\"button\"\n onClick={onClick}\n disabled={disabled}\n style={ADD_PILL_FILL[emphasis]}\n className={`${FOCUS_RING} inline-flex items-center justify-center gap-1.5 h-[var(--malachite-control-height-medium,32px)] w-[108px] px-2.5 rounded-xl border border-solid text-[length:var(--malachite-font-size-small,13px)] font-medium whitespace-nowrap ${\n disabled ? 'opacity-50 cursor-not-allowed' : 'cursor-pointer'\n } ${className}`}\n >\n <span className=\"inline-flex h-[13px] w-[13px] shrink-0 items-center justify-center\">\n {icon ?? <PlusIcon size={13} />}\n </span>\n {label}\n </button>\n </div>\n </div>\n);\n\nconst isAddTile = (node: React.ReactNode): node is React.ReactElement<CardStripAddTileProps> =>\n React.isValidElement(node) && node.type === AddTile;\n\nconst hidesAddTile = (child: React.ReactNode): boolean =>\n React.isValidElement<{ children?: React.ReactNode }>(child) &&\n child.type === React.Fragment &&\n React.Children.toArray(child.props.children).some(isAddTile);\n\ninterface ArrowButtonProps {\n side: 'left' | 'right';\n onClick: () => void;\n}\n\nconst ArrowButton: React.FC<ArrowButtonProps> = ({ side, onClick }) => (\n <button\n type=\"button\"\n tabIndex={-1}\n aria-hidden=\"true\"\n aria-label={side === 'left' ? 'Scroll left' : 'Scroll right'}\n onClick={onClick}\n className=\"absolute top-1/2 -translate-y-1/2 z-10 inline-flex items-center justify-center w-5 h-5 rounded-lg cursor-pointer text-[var(--malachite-text-secondary)]\"\n style={{\n [side]: `-${ARROW_OFFSET_PX}px`,\n background: ARROW_BACKGROUND,\n border: `1px solid ${ARROW_BORDER}`,\n boxShadow: LIP_SHADOW,\n }}\n >\n {side === 'left' ? (\n <ArrowLeftIcon size={ARROW_GLYPH_PX} />\n ) : (\n <ForwardArrowIcon size={ARROW_GLYPH_PX} />\n )}\n </button>\n);\n\n/** A horizontally scrolling radiogroup of cards — the \"pick one of these\" strip. */\nconst CardStrip: React.FC<CardStripProps> & { AddTile: React.FC<CardStripAddTileProps> } = ({\n value,\n tone,\n onChange,\n children,\n leading,\n arrows = true,\n fadeEdges = true,\n snap = true,\n bleed = false,\n scrollSelectedIntoView = true,\n 'aria-label': ariaLabel,\n 'aria-labelledby': ariaLabelledBy,\n className = '',\n style,\n}) => {\n const rootRef = useRef<HTMLDivElement>(null);\n const pinnedRef = useRef<HTMLDivElement>(null);\n const scrollerRef = useRef<HTMLDivElement>(null);\n const hasPositioned = useRef(false);\n const [edges, setEdges] = useState({ canScrollLeft: false, canScrollRight: false });\n const [cramped, setCramped] = useState(false);\n const addHostRef = useRef<HTMLDivElement>(null);\n const addTileFocused = useRef(false);\n\n useAdoptedStyleSheet(rootRef, SCROLLER_CSS, STYLE_ID);\n useAdoptedStyleSheet(rootRef, ADD_SLOT_CSS, ADD_SLOT_STYLE_ID);\n\n const childList = React.Children.toArray(children);\n const cards = childList.filter((child) => !isAddTile(child));\n const wrappedAddTile = cards.some(hidesAddTile);\n const hasCards = cards.length > 0;\n\n const addTiles = childList\n .filter(isAddTile)\n .map((tile) =>\n tile.props.emphasis === undefined\n ? React.cloneElement(tile, { emphasis: hasCards ? 'secondary' : 'primary' })\n : tile,\n );\n\n const childCount = childList.length;\n const addTileCount = addTiles.length;\n const hasLeading = Boolean(leading);\n\n // With no room for a card between the pinned tiles, the add tile scrolls with the cards.\n // biome-ignore lint/correctness/useExhaustiveDependencies: a new pinned slot needs observing\n useLayoutEffect(() => {\n const root = rootRef.current;\n if (!root || !hasCards || addTileCount === 0) {\n setCramped(false);\n return;\n }\n const pinnedSlot = pinnedRef.current;\n const { paddingLeft, paddingRight } = getComputedStyle(root);\n const inset = (parseFloat(paddingLeft) || 0) + (parseFloat(paddingRight) || 0);\n let content = root.clientWidth - inset;\n let pinned = pinnedSlot?.offsetWidth ?? 0;\n const decide = (): void => {\n const needs = pinned + addTileCount * SLOT_WIDTH_PX + TROUGH_FLOOR_PX;\n setCramped(content > 0 && content < needs);\n };\n decide();\n // Sizes from the entries: reading layout here would force the layout the observer spares.\n const observer =\n typeof ResizeObserver !== 'undefined'\n ? new ResizeObserver((entries) => {\n for (const entry of entries ?? []) {\n if (entry.target === root) {\n content = entry.contentRect.width;\n } else {\n pinned =\n entry.borderBoxSize?.[0]?.inlineSize ??\n entry.contentRect.width + 2 * TROUGH_SHOULDER_PX;\n }\n }\n decide();\n })\n : null;\n observer?.observe(root);\n if (pinnedSlot) {\n observer?.observe(pinnedSlot);\n }\n return () => observer?.disconnect();\n }, [hasCards, addTileCount, hasLeading]);\n\n const addInTrack = cramped && hasCards;\n const trackAddTileFocus = useCallback((event: React.FocusEvent) => {\n const focused = event.type === 'focus' ? event.target : event.relatedTarget;\n addTileFocused.current = Boolean(\n focused instanceof Node && addHostRef.current?.contains(focused),\n );\n }, []);\n\n // The tile remounts wherever it moves, so focus has to follow it there. Removing a focused\n // element fires no blur, so the flag survives the move.\n // biome-ignore lint/correctness/useExhaustiveDependencies: the tile moving is the signal\n useLayoutEffect(() => {\n const host = addHostRef.current;\n const active = host ? (host.getRootNode() as Document | ShadowRoot).activeElement : null;\n if (addTileFocused.current && host && !(active && host.contains(active))) {\n host.querySelector('button')?.focus({ preventScroll: true });\n }\n }, [addInTrack]);\n\n const getRadios = useCallback((): HTMLElement[] => {\n const root = rootRef.current;\n if (!root) {\n return [];\n }\n return Array.from(root.querySelectorAll<HTMLElement>(RADIO_SELECTOR));\n }, []);\n\n const getNavigableRadios = useCallback(\n (): HTMLElement[] => getRadios().filter((radio) => radioValue(radio) !== null),\n [getRadios],\n );\n\n const warned = useRef(new Set<string>());\n const warnOnce = useCallback((key: string, message: string): void => {\n if (warned.current.has(key)) {\n return;\n }\n warned.current.add(key);\n console.warn(message);\n }, []);\n\n const [derivedTone, setDerivedTone] = useState<CardStripTone>('profile');\n\n useLayoutEffect(() => {\n const selectedCard = getRadios()\n .find((radio) => radioValue(radio) === value)\n ?.parentElement?.getAttribute('data-variant');\n if (\n selectedCard === 'profile' ||\n selectedCard === 'library' ||\n selectedCard === 'editing'\n ) {\n setDerivedTone(selectedCard);\n }\n }, [getRadios, value]);\n\n useLayoutEffect(() => {\n const radios = getRadios();\n const navigable = getNavigableRadios();\n const selected = navigable.find((radio) => radioValue(radio) === value);\n const tabStop = selected ?? navigable.find((radio) => !isRadioDisabled(radio)) ?? null;\n\n radios.forEach((radio) => {\n const holdsTabStop = radio === tabStop;\n const nextTabIndex = holdsTabStop ? 0 : -1;\n if (radio.tabIndex !== nextTabIndex) {\n radio.tabIndex = nextTabIndex;\n }\n for (const control of actionControls(radio)) {\n if (holdsTabStop) {\n restoreTabStop(control);\n } else {\n suppressTabStop(control);\n }\n }\n });\n\n if (process.env.NODE_ENV === 'production') {\n return;\n }\n\n if (navigable.length !== radios.length) {\n warnOnce(\n 'missing-value',\n 'CardStrip: a child with role=\"radio\" has no `data-value`. It cannot be selected or reached by arrow keys, so it is excluded from the radio set. Give every card a `data-value`.',\n );\n }\n\n const values = new Set<string>();\n for (const radio of navigable) {\n const current = radioValue(radio);\n if (current === null) {\n continue;\n }\n if (values.has(current)) {\n warnOnce(\n `duplicate:${current}`,\n `CardStrip: two cards share the data-value \"${current}\". Both will read as checked and only the first is selectable — data-value must be unique.`,\n );\n }\n values.add(current);\n }\n\n const selectionSettled = value !== '';\n\n if (radios.length > 0 && selectionSettled && !values.has(value)) {\n warnOnce(\n `unmatched:${value}`,\n `CardStrip: value \"${value}\" matches no card's data-value, so the group reports no selection.`,\n );\n }\n\n const checked = radios.filter(\n (radio) => radio.getAttribute('aria-checked') === 'true',\n ).length;\n if (radios.length > 0 && selectionSettled && checked !== 1) {\n warnOnce(\n `checked:${checked}`,\n `CardStrip: ${checked} cards are aria-checked, but a radiogroup has exactly one. Drive each card's checked state from the strip's \\`value\\`.`,\n );\n }\n\n if (wrappedAddTile) {\n warnOnce(\n 'wrapped-add-tile',\n 'CardStrip: a CardStrip.AddTile inside a fragment is treated as a card and scrolls with them. The add tile must be a direct child of CardStrip.',\n );\n }\n });\n\n const selectedCard = useCallback((): HTMLElement | null => {\n const selected = getRadios().find((radio) => radioValue(radio) === value);\n return selected ? ((selected.closest('[role=\"radio\"]') ?? selected) as HTMLElement) : null;\n }, [getRadios, value]);\n\n // biome-ignore lint/correctness/useExhaustiveDependencies: cards arriving is the signal\n useLayoutEffect(() => {\n if (!scrollSelectedIntoView) {\n return;\n }\n const scroller = scrollerRef.current;\n const card = selectedCard();\n // jsdom implements neither, and a strip that cannot scroll has nothing to bring into view.\n if (!scroller || !card || typeof scroller.scrollTo !== 'function') {\n return;\n }\n\n // The first placement is where the strip opens — a deep link, not a move — so it is\n // instant. Every later one is the selection travelling, and travel is legible only if\n // you can see it happen.\n const wasPositioned = hasPositioned.current;\n hasPositioned.current = true;\n\n const target = revealTargetFor(scroller, card, snap);\n if (target !== null) {\n scroller.scrollTo({\n left: target,\n behavior: wasPositioned && !prefersReducedMotion() ? 'smooth' : 'instant',\n });\n }\n }, [selectedCard, scrollSelectedIntoView, snap, childCount]);\n\n const ruleTone = tone ?? derivedTone;\n const callerPaintsBackground =\n style?.background !== undefined || style?.backgroundImage !== undefined;\n\n const measure = useCallback(() => {\n const scroller = scrollerRef.current;\n if (!callerPaintsBackground) {\n paintRule(\n rootRef.current,\n scroller,\n getRadios().find((radio) => radioValue(radio) === value)?.parentElement,\n ruleTone,\n );\n }\n if (!scroller) {\n return;\n }\n const { scrollWidth, clientWidth, scrollLeft } = scroller;\n const overflows = scrollWidth > clientWidth + EDGE_EPSILON_PX;\n const next = {\n canScrollLeft: overflows && scrollLeft > EDGE_EPSILON_PX,\n canScrollRight: overflows && scrollLeft + clientWidth < scrollWidth - EDGE_EPSILON_PX,\n };\n setEdges((previous) =>\n previous.canScrollLeft === next.canScrollLeft &&\n previous.canScrollRight === next.canScrollRight\n ? previous\n : next,\n );\n }, [callerPaintsBackground, getRadios, ruleTone, value]);\n\n // biome-ignore lint/correctness/useExhaustiveDependencies: adding or removing a card changes the scroll width, so re-measure on the count\n useLayoutEffect(() => {\n measure();\n\n const scroller = scrollerRef.current;\n if (!scroller) {\n return;\n }\n\n const selectedInView = (): boolean => {\n const card = selectedCard();\n return card !== null && isCardInView(scroller, card);\n };\n let wasInView = selectedInView();\n\n const onScroll = (): void => {\n measure();\n wasInView = selectedInView();\n };\n scroller.addEventListener('scroll', onScroll, { passive: true });\n\n // Bring back a selected card the resize cut off, unless the reader scrolled it away.\n // Next frame rather than in the callback, whose layout reads would force a layout.\n let frame = 0;\n const reveal = (): void => {\n const card = selectedCard();\n const canReveal =\n scrollSelectedIntoView && wasInView && typeof scroller.scrollTo === 'function';\n const target = canReveal && card ? revealTargetFor(scroller, card, snap) : null;\n if (target !== null) {\n scroller.scrollTo({ left: target, behavior: 'instant' });\n }\n wasInView = selectedInView();\n };\n const onResize = (): void => {\n measure();\n if (typeof requestAnimationFrame !== 'function') {\n reveal();\n return;\n }\n cancelAnimationFrame(frame);\n frame = requestAnimationFrame(reveal);\n };\n const observer =\n typeof ResizeObserver !== 'undefined' ? new ResizeObserver(onResize) : null;\n observer?.observe(scroller);\n\n return () => {\n scroller.removeEventListener('scroll', onScroll);\n observer?.disconnect();\n if (typeof cancelAnimationFrame === 'function') {\n cancelAnimationFrame(frame);\n }\n };\n }, [measure, selectedCard, scrollSelectedIntoView, snap, childCount]);\n\n const scrollByStep = useCallback(\n (direction: -1 | 1) => {\n const scroller = scrollerRef.current;\n if (!scroller || typeof scroller.scrollBy !== 'function') {\n return;\n }\n scroller.scrollBy({\n left: pageTargetFor(scroller, direction, snap) - scroller.scrollLeft,\n behavior: prefersReducedMotion() ? 'auto' : 'smooth',\n });\n },\n [snap],\n );\n\n const handleKeyDown = useCallback(\n (event: React.KeyboardEvent) => {\n if (!NAV_KEYS.has(event.key)) {\n return;\n }\n\n const target = event.target;\n if (!(target instanceof Element) || !target.closest(RADIO_SELECTOR)) {\n return;\n }\n\n const enabled = getNavigableRadios().filter((radio) => !isRadioDisabled(radio));\n if (enabled.length === 0) {\n return;\n }\n\n event.preventDefault();\n\n const currentPosition = enabled.findIndex((radio) => radioValue(radio) === value);\n let nextPosition: number;\n if (event.key === 'Home') {\n nextPosition = 0;\n } else if (event.key === 'End') {\n nextPosition = enabled.length - 1;\n } else {\n const delta = event.key === 'ArrowLeft' || event.key === 'ArrowUp' ? -1 : 1;\n const from = currentPosition === -1 ? 0 : currentPosition;\n nextPosition = (from + delta + enabled.length) % enabled.length;\n }\n\n const next = enabled[nextPosition];\n const nextValue = radioValue(next);\n if (nextValue !== null && nextValue !== value) {\n onChange(nextValue);\n }\n next.focus();\n },\n [getNavigableRadios, onChange, value],\n );\n\n const handleClick = useCallback(\n (event: React.MouseEvent) => {\n const target = event.target;\n if (!(target instanceof Element) || target.closest(`.${ADD_TILE_CLASS}`)) {\n return;\n }\n const root = rootRef.current;\n if (!root) {\n return;\n }\n const radio = radioForClick(target, root);\n if (!radio || isRadioDisabled(radio)) {\n return;\n }\n const clicked = radioValue(radio);\n if (clicked !== null && clicked !== value) {\n onChange(clicked);\n }\n },\n [onChange, value],\n );\n\n const showLeftArrow = arrows && edges.canScrollLeft;\n const showRightArrow = arrows && edges.canScrollRight;\n\n const fadeLeft = fadeEdges && edges.canScrollLeft;\n const fadeRight = fadeEdges && edges.canScrollRight;\n\n return (\n <div\n ref={rootRef}\n onKeyDown={handleKeyDown}\n onFocus={trackAddTileFocus}\n onBlur={trackAddTileFocus}\n onClick={handleClick}\n className={`${ROOT_CLASS} flex items-stretch ${className}`}\n style={{\n ...RULE_ROW_STYLE,\n ...(bleed ? BLEED_STYLE : null),\n ...style,\n }}\n >\n <div\n role=\"radiogroup\"\n aria-label={ariaLabel}\n aria-labelledby={ariaLabelledBy}\n className={hasCards ? 'flex items-stretch min-w-0' : 'flex items-stretch'}\n >\n {leading ? (\n <CardStripSlotContext.Provider value={PINNED_SLOT}>\n <div ref={pinnedRef} className=\"shrink-0\" style={PINNED_SLOT_STYLE}>\n {leading}\n </div>\n </CardStripSlotContext.Provider>\n ) : null}\n {hasCards ? (\n <div\n {...{ [TROUGH_ATTR]: '' }}\n className=\"relative min-w-0 shrink basis-auto\"\n style={TROUGH_STYLE}\n >\n <div\n ref={scrollerRef}\n tabIndex={-1}\n {...{ [SCROLLER_ATTR]: '' }}\n data-snap={snap ? 'true' : 'false'}\n className={SCROLLER_CLASS}\n >\n <CardStripSlotContext.Provider value={SCROLLED_SLOT}>\n {cards}\n </CardStripSlotContext.Provider>\n {addInTrack ? (\n <div ref={addHostRef} {...{ [ADD_SLOT_ATTR]: '' }}>\n {addTiles}\n </div>\n ) : null}\n </div>\n {showLeftArrow ? (\n <ArrowButton side=\"left\" onClick={() => scrollByStep(-1)} />\n ) : null}\n {showRightArrow ? (\n <ArrowButton side=\"right\" onClick={() => scrollByStep(1)} />\n ) : null}\n {fadeLeft || fadeRight ? (\n <div\n aria-hidden\n data-card-strip-fade=\"\"\n className={`${FADE_CLASS} absolute pointer-events-none`}\n style={{\n inset: `-${TROUGH_SHOULDER_PX}px -${FADE_OVERHANG_PX}px 0`,\n background: `linear-gradient(to right, ${fadeLeft ? FADE_COLOR : 'transparent'} 0, transparent ${FADE_RAMP_PX}px, transparent calc(100% - ${FADE_RAMP_PX}px), ${fadeRight ? FADE_COLOR : 'transparent'} 100%)`,\n }}\n />\n ) : null}\n </div>\n ) : null}\n </div>\n {addTiles.length > 0 && !addInTrack ? (\n <div\n ref={addHostRef}\n className=\"shrink-0\"\n style={!hasCards && leading ? EMPTY_ADD_SLOT_STYLE : undefined}\n >\n {addTiles}\n </div>\n ) : null}\n </div>\n );\n};\n\nCardStrip.AddTile = AddTile;\n\nexport default CardStrip;\nexport { CardStrip };\n"],"names":["NAV_KEYS","RADIO_SELECTOR","SCROLLER_ATTR","TROUGH_ATTR","ROOT_CLASS","SCROLLER_CLASS","FADE_CLASS","ADD_TILE_CLASS","ADD_SLOT_ATTR","ACTIONS_SELECTOR","FOCUSABLE_SELECTOR","PREV_TABINDEX_ATTR","FADE_WIDTH_PX","ARROW_GLYPH_PX","GUTTER_REST_PX","LIP_SHADOW","ARROW_BACKGROUND","ARROW_BORDER","TROUGH_BACKGROUND","CARD_CORNER","CARD_RADIUS","TROUGH_CORNER","TROUGH_RADIUS","TROUGH_SHOULDER_PX","ARROW_OFFSET_PX","FADE_OVERHANG_PX","FADE_RAMP_PX","SLOT_WIDTH_PX","CARD_WIDTH_PX","TROUGH_FLOOR_PX","DIVIDER_COLOR","FADE_COLOR","ADD_HOVER_BACKGROUND","ADD_PILL_BORDER","ADD_PILL_BORDER_ACTIVE","ADD_PILL_SHADOW_DEEP","ADD_PILL_BACKGROUND","ADD_PILL_FOREGROUND","ADD_PILL_PRIMARY_BACKGROUND","ADD_PILL_PRIMARY_FOREGROUND","ADD_PILL_PRIMARY_SHADOW","BOTTOM_RULE_WEIGHT_PX","STRIP_RULE_PX","OVERFLOW_INSET_PX","CLIP_SLACK_PX","FOCUS_RING_REACH_PX","SCROLLER_CSS","CARD_FLARE_PX","STYLE_ID","ADD_SLOT_STYLE_ID","ADD_SLOT_CSS","prefersReducedMotion","radioValue","radio","isRadioDisabled","actionsFor","card","radioForClick","target","root","direct","node","radios","actionControls","actions","suppressTabStop","element","restoreTabStop","previous","TONE_RULE","RULE_ROW_STYLE","RULE_GAP_OVERLAP_PX","FLARE_TIP_INSET_PX","CARD_FLARE_TIP_PX","flareTips","flare","FLARE_CLASS","left","right","paintRule","scroller","tone","colour","rootRect","rootLeft","clip","cardRect","tips","tipLeft","tipRight","from","to","BLEED_STYLE","CONTENT_INSET","TROUGH_SURFACE","TROUGH_STYLE","ADD_TILE_SHAPE_STYLE","PINNED_SLOT_STYLE","EMPTY_ADD_SLOT_STYLE","ADD_PILL_FILL","AddTile","label","icon","onClick","disabled","emphasis","className","jsx","jsxs","FOCUS_RING","PlusIcon","isAddTile","React","hidesAddTile","child","ArrowButton","side","ArrowLeftIcon","ForwardArrowIcon","CardStrip","value","onChange","children","leading","arrows","fadeEdges","snap","bleed","scrollSelectedIntoView","ariaLabel","ariaLabelledBy","style","rootRef","useRef","pinnedRef","scrollerRef","hasPositioned","edges","setEdges","useState","cramped","setCramped","addHostRef","addTileFocused","useAdoptedStyleSheet","childList","cards","wrappedAddTile","hasCards","addTiles","tile","childCount","addTileCount","useLayoutEffect","pinnedSlot","paddingLeft","paddingRight","inset","content","pinned","decide","needs","observer","entries","entry","_b","_a","addInTrack","trackAddTileFocus","useCallback","event","focused","host","active","getRadios","getNavigableRadios","warned","warnOnce","key","message","derivedTone","setDerivedTone","selectedCard","navigable","tabStop","holdsTabStop","nextTabIndex","control","values","current","selectionSettled","checked","selected","wasPositioned","revealTargetFor","ruleTone","callerPaintsBackground","measure","scrollWidth","clientWidth","scrollLeft","overflows","EDGE_EPSILON_PX","next","selectedInView","isCardInView","wasInView","onScroll","frame","reveal","onResize","scrollByStep","direction","pageTargetFor","handleKeyDown","enabled","currentPosition","nextPosition","delta","nextValue","handleClick","clicked","showLeftArrow","showRightArrow","fadeLeft","fadeRight","CardStripSlotContext","PINNED_SLOT","SCROLLED_SLOT"],"mappings":"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"}
1
+ {"version":3,"file":"CardStrip.js","sources":["../../src/components/CardStrip.tsx"],"sourcesContent":["import React, { useCallback, useLayoutEffect, useRef, useState } from 'react';\nimport ArrowLeftIcon from './CustomIcons/ArrowLeftIcon';\nimport ForwardArrowIcon from './CustomIcons/ForwardArrowIcon';\nimport PlusIcon from './CustomIcons/PlusIcon';\nimport { CONTENT_INSET } from './PageLayout/constants';\nimport {\n CARD_FLARE_PX,\n CARD_FLARE_TIP_PX,\n CARD_WIDTH_PX,\n FLARE_CLASS,\n STRIP_RULE_PX,\n} from './SelectableCard';\nimport {\n EDGE_EPSILON_PX,\n isCardInView,\n pageTargetFor,\n revealTargetFor,\n} from './cardStripGeometry';\nimport { CardStripSlotContext, PINNED_SLOT, SCROLLED_SLOT } from './cardStripSlot';\nimport { FOCUS_RING } from './focusRing';\nimport { useAdoptedStyleSheet } from './useAdoptedStyleSheet';\n\nexport type CardStripAddTileEmphasis = 'primary' | 'secondary';\n\nexport interface CardStripAddTileProps {\n /** Visible label, e.g. \"Add Profile\". Also names the button for assistive tech. */\n label: string;\n /** Defaults to a plus. */\n icon?: React.ReactNode;\n onClick: () => void;\n disabled?: boolean;\n /** Leave unset: CardStrip picks `primary` while the strip is empty and `secondary` once cards exist. */\n emphasis?: CardStripAddTileEmphasis;\n className?: string;\n}\n\n/** Palette for the strip's rule. Pass the tone of whatever card is selected. */\nexport type CardStripTone = 'profile' | 'library' | 'editing';\n\nexport interface CardStripProps {\n /** The selected card's value, matched against each radio child's `data-value`. */\n value: string;\n /** Overrides the palette the strip reads off the selected card. See `CardStripTone`. */\n tone?: CardStripTone;\n onChange: (value: string) => void;\n /** Cards. Any element with `role=\"radio\"` and a `data-value` joins the group; an\n * add tile must be a direct child or it scrolls with the cards. */\n children: React.ReactNode;\n /** Pinned, non-scrolling slot before the cards (the Library card in the profile picker). */\n leading?: React.ReactNode;\n /** Circular scroll affordances, shown only on an edge that can actually scroll. */\n arrows?: boolean;\n /** Fade the cards out at any edge they scroll past. */\n fadeEdges?: boolean;\n /** Snap cards to the leading edge as the strip scrolls. */\n snap?: boolean;\n /** Run the bottom rule the full width of the page card while the cards stay on the gutter.\n * Only has an effect inside a layout that publishes its inset (`PageLayout`). */\n bleed?: boolean;\n /** Whether a selection change scrolls the selected card into view. The strip's opening\n * selection is placed instantly; later ones slide, unless motion is reduced. Set `false`\n * when the value comes from a URL, or a deep-linked strip below the fold jumps the page\n * on load. */\n scrollSelectedIntoView?: boolean;\n 'aria-label'?: string;\n 'aria-labelledby'?: string;\n className?: string;\n style?: React.CSSProperties;\n}\n\n/** Arrow keys move AND select, per the WAI-ARIA radiogroup pattern. */\nconst NAV_KEYS = new Set(['ArrowLeft', 'ArrowRight', 'ArrowUp', 'ArrowDown', 'Home', 'End']);\n\nconst RADIO_SELECTOR = '[role=\"radio\"]';\nconst SCROLLER_ATTR = 'data-card-strip-scroller';\nconst TROUGH_ATTR = 'data-card-strip-trough';\nconst ROOT_CLASS = 'malachite-card-strip';\nconst SCROLLER_CLASS = 'malachite-card-strip-scroller';\nconst FADE_CLASS = 'malachite-card-strip-fade';\nconst ADD_TILE_CLASS = 'malachite-card-strip-add-tile';\nconst ADD_SLOT_ATTR = 'data-card-strip-add-slot';\n\nconst ACTIONS_SELECTOR = '[data-selectable-card-actions]';\nconst FOCUSABLE_SELECTOR =\n 'a[href], area[href], button, input, select, textarea, iframe, [contenteditable=\"true\"], [tabindex]';\nconst PREV_TABINDEX_ATTR = 'data-card-strip-prev-tabindex';\n\nconst FADE_WIDTH_PX = 80;\n\nconst ARROW_GLYPH_PX = 11;\nconst GUTTER_REST_PX = 12;\n\nconst LIP_SHADOW = 'var(--malachite-shadow-default)';\nconst ARROW_BACKGROUND =\n 'var(--malachite-card-strip-arrow-background, var(--malachite-card-background, #ffffff))';\nconst ARROW_BORDER = 'var(--malachite-card-strip-arrow-border, #e8e8e8)';\nconst TROUGH_BACKGROUND = 'var(--malachite-card-strip-background, #f1f1f1)';\nconst CARD_CORNER = 'var(--malachite-radius-xxl, 14px)';\nconst CARD_RADIUS = `${CARD_CORNER} ${CARD_CORNER} 0 0`;\nconst TROUGH_CORNER = 'var(--malachite-radius-xxxl, 16px)';\nconst TROUGH_RADIUS = `${TROUGH_CORNER} ${TROUGH_CORNER} 0 0`;\nconst TROUGH_SHOULDER_PX = 4;\n// Fills the gap between the edge card and its neighbour, covering neither.\nconst ARROW_OFFSET_PX = GUTTER_REST_PX + TROUGH_SHOULDER_PX;\n// Any wider and the fade paints over the neighbouring slot.\nconst FADE_OVERHANG_PX = GUTTER_REST_PX;\nconst FADE_RAMP_PX = FADE_WIDTH_PX + (FADE_OVERHANG_PX - TROUGH_SHOULDER_PX);\nconst SLOT_WIDTH_PX = CARD_WIDTH_PX;\nconst TROUGH_FLOOR_PX = 2 * (GUTTER_REST_PX + TROUGH_SHOULDER_PX) + SLOT_WIDTH_PX;\nconst DIVIDER_COLOR = 'var(--malachite-card-strip-divider, #dddddd)';\nconst FADE_COLOR = 'var(--malachite-card-strip-fade, transparent)';\nconst ADD_HOVER_BACKGROUND = 'var(--malachite-selectable-card-hover-background, #e8e8e8)';\nconst ADD_PILL_BORDER = 'var(--malachite-card-strip-arrow-border, #e8e8e8)';\nconst ADD_PILL_BORDER_ACTIVE = 'var(--malachite-selectable-card-hover-rule, #bbbbbb)';\nconst ADD_PILL_SHADOW_DEEP = '0px 1px 0px 0px rgba(0, 0, 0, 0.4)';\nconst ADD_PILL_BACKGROUND = 'var(--malachite-card-background, #ffffff)';\nconst ADD_PILL_FOREGROUND = 'var(--malachite-text-primary, #0a0a0a)';\nconst ADD_PILL_PRIMARY_BACKGROUND =\n 'var(--malachite-card-strip-add-primary-background, var(--malachite-text-primary, #0a0a0a))';\nconst ADD_PILL_PRIMARY_FOREGROUND =\n 'var(--malachite-card-strip-add-primary-foreground, var(--malachite-card-background, #ffffff))';\nconst ADD_PILL_PRIMARY_SHADOW = '0px 1px 0px 0px rgba(10, 10, 10, 0.7)';\n\nconst BOTTOM_RULE_WEIGHT_PX = STRIP_RULE_PX;\n\nconst OVERFLOW_INSET_PX = 16;\n\nconst CLIP_SLACK_PX = 9999;\nconst FOCUS_RING_REACH_PX = 4;\n\n/** A sheet, not inline styles: these rules have to reach children this component does not render. */\nconst SCROLLER_CSS = `\n.${ROOT_CLASS} {\n clip-path: inset(-${CLIP_SLACK_PX}px -${CLIP_SLACK_PX}px 0);\n}\n.${ROOT_CLASS}:has(:focus-visible) {\n clip-path: inset(-${CLIP_SLACK_PX}px -${CLIP_SLACK_PX}px -${FOCUS_RING_REACH_PX}px);\n}\n.${SCROLLER_CLASS} {\n display: flex;\n flex-wrap: nowrap;\n overflow-x: auto;\n overflow-y: hidden;\n scroll-behavior: smooth;\n scrollbar-width: none;\n -ms-overflow-style: none;\n padding-block: ${OVERFLOW_INSET_PX}px;\n margin-block: -${OVERFLOW_INSET_PX}px;\n /* overflow-x clips both axes, so the end cards would lose a flare; the negative margin trades\n the padding back out and scroll-padding keeps the rest position at zero. */\n padding-inline: ${CARD_FLARE_PX}px;\n margin-inline: -${CARD_FLARE_PX}px;\n scroll-padding-inline: ${CARD_FLARE_PX}px;\n}\n/* A card focused at a faded edge has to stay readable, so the fade lifts entirely. */\n.${ROOT_CLASS}:has(:focus-visible) .${FADE_CLASS} {\n display: none;\n}\n.${SCROLLER_CLASS}::-webkit-scrollbar {\n display: none;\n}\n/* No bottom edge: the strip's rule is the baseline for the add tile as much as for a card. */\n.${ADD_TILE_CLASS} > * {\n background: ${TROUGH_BACKGROUND};\n border-radius: ${CARD_RADIUS};\n}\n.${ADD_TILE_CLASS}:hover:not(:has(button:disabled)) > * {\n background: ${ADD_HOVER_BACKGROUND};\n}\n.${ADD_TILE_CLASS} button:active:not(:disabled) {\n opacity: 0.8;\n}\n.${ADD_TILE_CLASS}:has(button:active) > * {\n background: ${TROUGH_BACKGROUND};\n}\n.${ADD_TILE_CLASS}[data-emphasis='secondary'] button {\n border-color: ${ADD_PILL_BORDER};\n box-shadow: ${LIP_SHADOW};\n}\n.${ADD_TILE_CLASS}[data-emphasis='secondary']:hover:not(:has(button:disabled)) button {\n border-color: ${ADD_PILL_BORDER_ACTIVE};\n box-shadow: ${ADD_PILL_SHADOW_DEEP};\n}\n.${ADD_TILE_CLASS}[data-emphasis='secondary'] button:active:not(:disabled) {\n border-color: ${ADD_PILL_BORDER_ACTIVE};\n box-shadow: ${ADD_PILL_SHADOW_DEEP};\n}\n.${ADD_TILE_CLASS}[data-emphasis='primary'] button {\n border-color: transparent;\n box-shadow: ${ADD_PILL_PRIMARY_SHADOW};\n}\n.${SCROLLER_CLASS} > * {\n flex: 0 0 auto;\n min-width: 0;\n}\n.${SCROLLER_CLASS} > * + * {\n border-left: 1px solid ${DIVIDER_COLOR};\n}\n.${SCROLLER_CLASS}[data-snap='true'] {\n scroll-snap-type: x proximity;\n}\n.${SCROLLER_CLASS}[data-snap='true'] > * {\n scroll-snap-align: start;\n}\n@media (prefers-reduced-motion: reduce) {\n .${SCROLLER_CLASS} {\n scroll-behavior: auto;\n }\n .${SCROLLER_CLASS}[data-snap='true'] {\n scroll-snap-type: none;\n }\n .${SCROLLER_CLASS}[data-snap='true'] > * {\n scroll-snap-align: none;\n }\n}`;\n\nconst STYLE_ID = 'malachite-card-strip-style';\n// Its own id: an older malachite copy on the page may already own STYLE_ID without these rules.\nconst ADD_SLOT_STYLE_ID = 'malachite-card-strip-add-slot';\n// In the track the trough is already the tile's shoulder, and it is no card to rule off.\nconst ADD_SLOT_CSS = `\n.${SCROLLER_CLASS} > [${ADD_SLOT_ATTR}] {\n display: flex;\n border-left: none;\n}\n[${ADD_SLOT_ATTR}] > .${ADD_TILE_CLASS} {\n height: 100% !important;\n padding: 0 !important;\n}\n`;\n\n/** `window.matchMedia` is absent under SSR and in older test environments. */\nconst prefersReducedMotion = (): boolean => {\n if (typeof window === 'undefined' || typeof window.matchMedia !== 'function') {\n return true;\n }\n return window.matchMedia('(prefers-reduced-motion: reduce)').matches;\n};\n\nconst radioValue = (radio: HTMLElement): string | null =>\n radio.dataset.value ?? radio.getAttribute('value');\n\nconst isRadioDisabled = (radio: HTMLElement): boolean =>\n radio.hasAttribute('disabled') || radio.getAttribute('aria-disabled') === 'true';\n\nconst actionsFor = (radio: HTMLElement): HTMLElement | null => {\n const card = radio.parentElement;\n if (!card || card.querySelectorAll(RADIO_SELECTOR).length !== 1) {\n return null;\n }\n return card.querySelector<HTMLElement>(ACTIONS_SELECTOR);\n};\n\n/** A card is wider than its radio, so `closest` misses clicks on the count row. */\nconst radioForClick = (target: Element, root: Element): HTMLElement | null => {\n const direct = target.closest<HTMLElement>(RADIO_SELECTOR);\n if (direct) {\n return direct;\n }\n if (target.closest(ACTIONS_SELECTOR)) {\n return null;\n }\n let node: Element | null = target;\n while (node && root.contains(node)) {\n const radios: NodeListOf<HTMLElement> = node.querySelectorAll(RADIO_SELECTOR);\n if (radios.length === 1 && radios[0].parentElement === node) {\n return radios[0];\n }\n node = node.parentElement;\n }\n return null;\n};\n\nconst actionControls = (radio: HTMLElement): HTMLElement[] => {\n const actions = actionsFor(radio);\n return actions ? Array.from(actions.querySelectorAll<HTMLElement>(FOCUSABLE_SELECTOR)) : [];\n};\n\nconst suppressTabStop = (element: HTMLElement): void => {\n if (!element.hasAttribute(PREV_TABINDEX_ATTR)) {\n element.setAttribute(PREV_TABINDEX_ATTR, element.getAttribute('tabindex') ?? '');\n }\n element.setAttribute('tabindex', '-1');\n};\n\nconst restoreTabStop = (element: HTMLElement): void => {\n if (!element.hasAttribute(PREV_TABINDEX_ATTR)) {\n return;\n }\n const previous = element.getAttribute(PREV_TABINDEX_ATTR);\n element.removeAttribute(PREV_TABINDEX_ATTR);\n if (previous) {\n element.setAttribute('tabindex', previous);\n } else {\n element.removeAttribute('tabindex');\n }\n};\n\nconst TONE_RULE: Record<CardStripTone, string> = {\n profile: 'var(--malachite-selectable-card-selected-border, #047b43)',\n library: 'var(--malachite-selectable-card-library-selected-border, #bbbbbb)',\n editing: 'var(--malachite-selectable-card-pending-foreground, #96580a)',\n};\nconst RULE_ROW_STYLE: React.CSSProperties = {\n backgroundRepeat: 'no-repeat',\n backgroundPosition: 'left bottom',\n backgroundSize: `100% ${BOTTOM_RULE_WEIGHT_PX}px`,\n};\n\n/** The rule runs under the flare's tip rather than butting against it, so antialiasing\n * cannot open the junction into a gap. */\nconst RULE_GAP_OVERLAP_PX = 0.5;\n\nconst FLARE_TIP_INSET_PX = CARD_FLARE_PX - CARD_FLARE_TIP_PX;\n\nconst flareTips = (card: HTMLElement): { left: number; right: number } | null => {\n const flare = card.querySelector(`:scope > .${FLARE_CLASS}`);\n if (!flare) {\n return null;\n }\n const { left, right } = flare.getBoundingClientRect();\n return { left: left + FLARE_TIP_INSET_PX, right: right - FLARE_TIP_INSET_PX };\n};\n\n/** The rule is cut where the selected card stands, never covered: the strip's clip lands on the\n * rule's own edge, so a cover takes the same partial alpha and the rule bleeds through it. */\nconst paintRule = (\n root: HTMLElement | null,\n scroller: HTMLElement | null,\n card: HTMLElement | null | undefined,\n tone: CardStripTone,\n): void => {\n if (!root) {\n return;\n }\n const colour = TONE_RULE[tone];\n const rootRect = root.getBoundingClientRect();\n const rootLeft = rootRect.left;\n const clip = card && scroller?.contains(card) ? scroller.getBoundingClientRect() : rootRect;\n const cardRect = card?.getBoundingClientRect();\n const tips = card ? flareTips(card) : null;\n const tipLeft = tips?.left ?? (cardRect ? cardRect.left - CARD_FLARE_TIP_PX : 0);\n const tipRight = tips?.right ?? (cardRect ? cardRect.right + CARD_FLARE_TIP_PX : 0);\n const from = cardRect ? Math.max(tipLeft, clip.left) + RULE_GAP_OVERLAP_PX - rootLeft : 0;\n const to = cardRect ? Math.min(tipRight, clip.right) - RULE_GAP_OVERLAP_PX - rootLeft : 0;\n\n root.style.backgroundImage =\n to > from\n ? `linear-gradient(to right, ${colour} 0 ${from}px, transparent ${from}px ${to}px, ${colour} ${to}px 100%)`\n : `linear-gradient(to right, ${colour} 0 100%)`;\n};\n\nconst BLEED_STYLE: React.CSSProperties = {\n marginInline: `calc(${CONTENT_INSET} * -1)`,\n paddingInline: CONTENT_INSET,\n};\n\n/** The rule's row is a margin, never padding: a background paints under its own padding, which\n * would hide the very line the troughs stand on. */\nconst TROUGH_SURFACE: React.CSSProperties = {\n background: TROUGH_BACKGROUND,\n borderRadius: TROUGH_RADIUS,\n paddingTop: `${TROUGH_SHOULDER_PX}px`,\n paddingInline: `${TROUGH_SHOULDER_PX}px`,\n marginBottom: `${BOTTOM_RULE_WEIGHT_PX}px`,\n};\nconst TROUGH_STYLE: React.CSSProperties = {\n ...TROUGH_SURFACE,\n marginInline: `${GUTTER_REST_PX}px`,\n};\nconst ADD_TILE_SHAPE_STYLE: React.CSSProperties = TROUGH_SURFACE;\n\nconst PINNED_SLOT_STYLE: React.CSSProperties = TROUGH_SURFACE;\n\nconst EMPTY_ADD_SLOT_STYLE: React.CSSProperties = {\n marginInlineStart: `${GUTTER_REST_PX}px`,\n};\n\nconst ADD_PILL_FILL: Record<CardStripAddTileEmphasis, React.CSSProperties> = {\n primary: {\n backgroundColor: ADD_PILL_PRIMARY_BACKGROUND,\n color: ADD_PILL_PRIMARY_FOREGROUND,\n },\n secondary: { backgroundColor: ADD_PILL_BACKGROUND, color: ADD_PILL_FOREGROUND },\n};\n\nconst AddTile: React.FC<CardStripAddTileProps> = ({\n label,\n icon,\n onClick,\n disabled = false,\n emphasis = 'secondary',\n className = '',\n}) => (\n <div\n className={ADD_TILE_CLASS}\n data-emphasis={emphasis}\n style={{\n ...ADD_TILE_SHAPE_STYLE,\n width: `${SLOT_WIDTH_PX}px`,\n height: `calc(100% - ${BOTTOM_RULE_WEIGHT_PX}px)`,\n }}\n >\n <div className=\"flex h-full items-center justify-center px-4\">\n <button\n type=\"button\"\n onClick={onClick}\n disabled={disabled}\n style={ADD_PILL_FILL[emphasis]}\n className={`${FOCUS_RING} inline-flex items-center justify-center gap-1.5 h-[var(--malachite-control-height-medium,32px)] w-[108px] px-2.5 rounded-xl border border-solid text-[length:var(--malachite-font-size-small,13px)] font-medium whitespace-nowrap ${\n disabled ? 'opacity-50 cursor-not-allowed' : 'cursor-pointer'\n } ${className}`}\n >\n <span className=\"inline-flex h-[13px] w-[13px] shrink-0 items-center justify-center\">\n {icon ?? <PlusIcon size={13} />}\n </span>\n {label}\n </button>\n </div>\n </div>\n);\n\nconst isAddTile = (node: React.ReactNode): node is React.ReactElement<CardStripAddTileProps> =>\n React.isValidElement(node) && node.type === AddTile;\n\nconst hidesAddTile = (child: React.ReactNode): boolean =>\n React.isValidElement<{ children?: React.ReactNode }>(child) &&\n child.type === React.Fragment &&\n React.Children.toArray(child.props.children).some(isAddTile);\n\ninterface ArrowButtonProps {\n side: 'left' | 'right';\n onClick: () => void;\n}\n\nconst ArrowButton: React.FC<ArrowButtonProps> = ({ side, onClick }) => (\n <button\n type=\"button\"\n tabIndex={-1}\n aria-hidden=\"true\"\n aria-label={side === 'left' ? 'Scroll left' : 'Scroll right'}\n onClick={onClick}\n className=\"absolute top-1/2 -translate-y-1/2 z-10 inline-flex items-center justify-center w-5 h-5 rounded-lg cursor-pointer text-[var(--malachite-text-secondary)]\"\n style={{\n [side]: `-${ARROW_OFFSET_PX}px`,\n background: ARROW_BACKGROUND,\n border: `1px solid ${ARROW_BORDER}`,\n boxShadow: LIP_SHADOW,\n }}\n >\n {side === 'left' ? (\n <ArrowLeftIcon size={ARROW_GLYPH_PX} />\n ) : (\n <ForwardArrowIcon size={ARROW_GLYPH_PX} />\n )}\n </button>\n);\n\n/** A horizontally scrolling radiogroup of cards — the \"pick one of these\" strip. */\nconst CardStrip: React.FC<CardStripProps> & { AddTile: React.FC<CardStripAddTileProps> } = ({\n value,\n tone,\n onChange,\n children,\n leading,\n arrows = true,\n fadeEdges = true,\n snap = true,\n bleed = false,\n scrollSelectedIntoView = true,\n 'aria-label': ariaLabel,\n 'aria-labelledby': ariaLabelledBy,\n className = '',\n style,\n}) => {\n const rootRef = useRef<HTMLDivElement>(null);\n const pinnedRef = useRef<HTMLDivElement>(null);\n const scrollerRef = useRef<HTMLDivElement>(null);\n const hasPositioned = useRef(false);\n const [edges, setEdges] = useState({ canScrollLeft: false, canScrollRight: false });\n const [cramped, setCramped] = useState(false);\n const addHostRef = useRef<HTMLDivElement>(null);\n const addTileFocused = useRef(false);\n\n useAdoptedStyleSheet(rootRef, SCROLLER_CSS, STYLE_ID);\n useAdoptedStyleSheet(rootRef, ADD_SLOT_CSS, ADD_SLOT_STYLE_ID);\n\n const childList = React.Children.toArray(children);\n const cards = childList.filter((child) => !isAddTile(child));\n const wrappedAddTile = cards.some(hidesAddTile);\n const hasCards = cards.length > 0;\n\n const addTiles = childList\n .filter(isAddTile)\n .map((tile) =>\n tile.props.emphasis === undefined\n ? React.cloneElement(tile, { emphasis: hasCards ? 'secondary' : 'primary' })\n : tile,\n );\n\n const childCount = childList.length;\n const addTileCount = addTiles.length;\n const hasLeading = Boolean(leading);\n\n // With no room for a card between the pinned tiles, the add tile scrolls with the cards.\n // biome-ignore lint/correctness/useExhaustiveDependencies: a new pinned slot needs observing\n useLayoutEffect(() => {\n const root = rootRef.current;\n if (!root || !hasCards || addTileCount === 0) {\n setCramped(false);\n return;\n }\n const pinnedSlot = pinnedRef.current;\n const { paddingLeft, paddingRight } = getComputedStyle(root);\n const inset = (parseFloat(paddingLeft) || 0) + (parseFloat(paddingRight) || 0);\n let content = root.clientWidth - inset;\n let pinned = pinnedSlot?.offsetWidth ?? 0;\n const decide = (): void => {\n const needs = pinned + addTileCount * SLOT_WIDTH_PX + TROUGH_FLOOR_PX;\n setCramped(content > 0 && content < needs);\n };\n decide();\n // Sizes from the entries: reading layout here would force the layout the observer spares.\n const observer =\n typeof ResizeObserver !== 'undefined'\n ? new ResizeObserver((entries) => {\n for (const entry of entries ?? []) {\n if (entry.target === root) {\n content = entry.contentRect.width;\n } else {\n pinned =\n entry.borderBoxSize?.[0]?.inlineSize ??\n entry.contentRect.width + 2 * TROUGH_SHOULDER_PX;\n }\n }\n decide();\n })\n : null;\n observer?.observe(root);\n if (pinnedSlot) {\n observer?.observe(pinnedSlot);\n }\n return () => observer?.disconnect();\n }, [hasCards, addTileCount, hasLeading]);\n\n const addInTrack = cramped && hasCards;\n const trackAddTileFocus = useCallback((event: React.FocusEvent) => {\n const focused = event.type === 'focus' ? event.target : event.relatedTarget;\n addTileFocused.current = Boolean(\n focused instanceof Node && addHostRef.current?.contains(focused),\n );\n }, []);\n\n // The tile remounts wherever it moves, so focus has to follow it there. Removing a focused\n // element fires no blur, so the flag survives the move.\n // biome-ignore lint/correctness/useExhaustiveDependencies: the tile moving is the signal\n useLayoutEffect(() => {\n const host = addHostRef.current;\n const active = host ? (host.getRootNode() as Document | ShadowRoot).activeElement : null;\n if (addTileFocused.current && host && !(active && host.contains(active))) {\n host.querySelector('button')?.focus({ preventScroll: true });\n }\n }, [addInTrack]);\n\n const getRadios = useCallback((): HTMLElement[] => {\n const root = rootRef.current;\n if (!root) {\n return [];\n }\n return Array.from(root.querySelectorAll<HTMLElement>(RADIO_SELECTOR));\n }, []);\n\n // Read off the DOM rather than the children's keys: unkeyed cards reorder under positional\n // keys that never change. Attribute reads only, so this forces no layout.\n const radioOrder = useRef<string | null>(null);\n const [reorders, setReorders] = useState(0);\n useLayoutEffect(() => {\n const next = JSON.stringify(getRadios().map(radioValue));\n if (radioOrder.current !== null && radioOrder.current !== next) {\n setReorders((count) => count + 1);\n }\n radioOrder.current = next;\n });\n\n const getNavigableRadios = useCallback(\n (): HTMLElement[] => getRadios().filter((radio) => radioValue(radio) !== null),\n [getRadios],\n );\n\n const warned = useRef(new Set<string>());\n const warnOnce = useCallback((key: string, message: string): void => {\n if (warned.current.has(key)) {\n return;\n }\n warned.current.add(key);\n console.warn(message);\n }, []);\n\n const [derivedTone, setDerivedTone] = useState<CardStripTone>('profile');\n\n useLayoutEffect(() => {\n const selectedCard = getRadios()\n .find((radio) => radioValue(radio) === value)\n ?.parentElement?.getAttribute('data-variant');\n if (\n selectedCard === 'profile' ||\n selectedCard === 'library' ||\n selectedCard === 'editing'\n ) {\n setDerivedTone(selectedCard);\n }\n }, [getRadios, value]);\n\n useLayoutEffect(() => {\n const radios = getRadios();\n const navigable = getNavigableRadios();\n const selected = navigable.find((radio) => radioValue(radio) === value);\n const tabStop = selected ?? navigable.find((radio) => !isRadioDisabled(radio)) ?? null;\n\n radios.forEach((radio) => {\n const holdsTabStop = radio === tabStop;\n const nextTabIndex = holdsTabStop ? 0 : -1;\n if (radio.tabIndex !== nextTabIndex) {\n radio.tabIndex = nextTabIndex;\n }\n for (const control of actionControls(radio)) {\n if (holdsTabStop) {\n restoreTabStop(control);\n } else {\n suppressTabStop(control);\n }\n }\n });\n\n if (process.env.NODE_ENV === 'production') {\n return;\n }\n\n if (navigable.length !== radios.length) {\n warnOnce(\n 'missing-value',\n 'CardStrip: a child with role=\"radio\" has no `data-value`. It cannot be selected or reached by arrow keys, so it is excluded from the radio set. Give every card a `data-value`.',\n );\n }\n\n const values = new Set<string>();\n for (const radio of navigable) {\n const current = radioValue(radio);\n if (current === null) {\n continue;\n }\n if (values.has(current)) {\n warnOnce(\n `duplicate:${current}`,\n `CardStrip: two cards share the data-value \"${current}\". Both will read as checked and only the first is selectable — data-value must be unique.`,\n );\n }\n values.add(current);\n }\n\n const selectionSettled = value !== '';\n\n if (radios.length > 0 && selectionSettled && !values.has(value)) {\n warnOnce(\n `unmatched:${value}`,\n `CardStrip: value \"${value}\" matches no card's data-value, so the group reports no selection.`,\n );\n }\n\n const checked = radios.filter(\n (radio) => radio.getAttribute('aria-checked') === 'true',\n ).length;\n if (radios.length > 0 && selectionSettled && checked !== 1) {\n warnOnce(\n `checked:${checked}`,\n `CardStrip: ${checked} cards are aria-checked, but a radiogroup has exactly one. Drive each card's checked state from the strip's \\`value\\`.`,\n );\n }\n\n if (wrappedAddTile) {\n warnOnce(\n 'wrapped-add-tile',\n 'CardStrip: a CardStrip.AddTile inside a fragment is treated as a card and scrolls with them. The add tile must be a direct child of CardStrip.',\n );\n }\n });\n\n const selectedCard = useCallback((): HTMLElement | null => {\n const selected = getRadios().find((radio) => radioValue(radio) === value);\n return selected ? ((selected.closest('[role=\"radio\"]') ?? selected) as HTMLElement) : null;\n }, [getRadios, value]);\n\n // biome-ignore lint/correctness/useExhaustiveDependencies: cards arriving is the signal\n useLayoutEffect(() => {\n if (!scrollSelectedIntoView) {\n return;\n }\n const scroller = scrollerRef.current;\n const card = selectedCard();\n // jsdom implements neither, and a strip that cannot scroll has nothing to bring into view.\n if (!scroller || !card || typeof scroller.scrollTo !== 'function') {\n return;\n }\n\n // The first placement is where the strip opens — a deep link, not a move — so it is\n // instant. Every later one is the selection travelling, and travel is legible only if\n // you can see it happen.\n const wasPositioned = hasPositioned.current;\n hasPositioned.current = true;\n\n const target = revealTargetFor(scroller, card, snap);\n if (target !== null) {\n scroller.scrollTo({\n left: target,\n behavior: wasPositioned && !prefersReducedMotion() ? 'smooth' : 'instant',\n });\n }\n }, [selectedCard, scrollSelectedIntoView, snap, childCount, reorders]);\n\n const ruleTone = tone ?? derivedTone;\n const callerPaintsBackground =\n style?.background !== undefined || style?.backgroundImage !== undefined;\n\n const measure = useCallback(() => {\n const scroller = scrollerRef.current;\n if (!callerPaintsBackground) {\n paintRule(\n rootRef.current,\n scroller,\n getRadios().find((radio) => radioValue(radio) === value)?.parentElement,\n ruleTone,\n );\n }\n if (!scroller) {\n return;\n }\n const { scrollWidth, clientWidth, scrollLeft } = scroller;\n const overflows = scrollWidth > clientWidth + EDGE_EPSILON_PX;\n const next = {\n canScrollLeft: overflows && scrollLeft > EDGE_EPSILON_PX,\n canScrollRight: overflows && scrollLeft + clientWidth < scrollWidth - EDGE_EPSILON_PX,\n };\n setEdges((previous) =>\n previous.canScrollLeft === next.canScrollLeft &&\n previous.canScrollRight === next.canScrollRight\n ? previous\n : next,\n );\n }, [callerPaintsBackground, getRadios, ruleTone, value]);\n\n // biome-ignore lint/correctness/useExhaustiveDependencies: adding, removing or reordering cards moves the selected card, so re-measure on the order\n useLayoutEffect(() => {\n measure();\n\n const scroller = scrollerRef.current;\n if (!scroller) {\n return;\n }\n\n const selectedInView = (): boolean => {\n const card = selectedCard();\n return card !== null && isCardInView(scroller, card);\n };\n let wasInView = selectedInView();\n\n const onScroll = (): void => {\n measure();\n wasInView = selectedInView();\n };\n scroller.addEventListener('scroll', onScroll, { passive: true });\n\n // Bring back a selected card the resize cut off, unless the reader scrolled it away.\n // Next frame rather than in the callback, whose layout reads would force a layout.\n let frame = 0;\n const reveal = (): void => {\n const card = selectedCard();\n const canReveal =\n scrollSelectedIntoView && wasInView && typeof scroller.scrollTo === 'function';\n const target = canReveal && card ? revealTargetFor(scroller, card, snap) : null;\n if (target !== null) {\n scroller.scrollTo({ left: target, behavior: 'instant' });\n }\n wasInView = selectedInView();\n };\n const onResize = (): void => {\n measure();\n if (typeof requestAnimationFrame !== 'function') {\n reveal();\n return;\n }\n cancelAnimationFrame(frame);\n frame = requestAnimationFrame(reveal);\n };\n const observer =\n typeof ResizeObserver !== 'undefined' ? new ResizeObserver(onResize) : null;\n observer?.observe(scroller);\n\n return () => {\n scroller.removeEventListener('scroll', onScroll);\n observer?.disconnect();\n if (typeof cancelAnimationFrame === 'function') {\n cancelAnimationFrame(frame);\n }\n };\n }, [measure, selectedCard, scrollSelectedIntoView, snap, childCount, reorders]);\n\n const scrollByStep = useCallback(\n (direction: -1 | 1) => {\n const scroller = scrollerRef.current;\n if (!scroller || typeof scroller.scrollBy !== 'function') {\n return;\n }\n scroller.scrollBy({\n left: pageTargetFor(scroller, direction, snap) - scroller.scrollLeft,\n behavior: prefersReducedMotion() ? 'auto' : 'smooth',\n });\n },\n [snap],\n );\n\n const handleKeyDown = useCallback(\n (event: React.KeyboardEvent) => {\n if (!NAV_KEYS.has(event.key)) {\n return;\n }\n\n const target = event.target;\n if (!(target instanceof Element) || !target.closest(RADIO_SELECTOR)) {\n return;\n }\n\n const enabled = getNavigableRadios().filter((radio) => !isRadioDisabled(radio));\n if (enabled.length === 0) {\n return;\n }\n\n event.preventDefault();\n\n const currentPosition = enabled.findIndex((radio) => radioValue(radio) === value);\n let nextPosition: number;\n if (event.key === 'Home') {\n nextPosition = 0;\n } else if (event.key === 'End') {\n nextPosition = enabled.length - 1;\n } else {\n const delta = event.key === 'ArrowLeft' || event.key === 'ArrowUp' ? -1 : 1;\n const from = currentPosition === -1 ? 0 : currentPosition;\n nextPosition = (from + delta + enabled.length) % enabled.length;\n }\n\n const next = enabled[nextPosition];\n const nextValue = radioValue(next);\n if (nextValue !== null && nextValue !== value) {\n onChange(nextValue);\n }\n next.focus();\n },\n [getNavigableRadios, onChange, value],\n );\n\n const handleClick = useCallback(\n (event: React.MouseEvent) => {\n const target = event.target;\n if (!(target instanceof Element) || target.closest(`.${ADD_TILE_CLASS}`)) {\n return;\n }\n const root = rootRef.current;\n if (!root) {\n return;\n }\n const radio = radioForClick(target, root);\n if (!radio || isRadioDisabled(radio)) {\n return;\n }\n const clicked = radioValue(radio);\n if (clicked !== null && clicked !== value) {\n onChange(clicked);\n }\n },\n [onChange, value],\n );\n\n const showLeftArrow = arrows && edges.canScrollLeft;\n const showRightArrow = arrows && edges.canScrollRight;\n\n const fadeLeft = fadeEdges && edges.canScrollLeft;\n const fadeRight = fadeEdges && edges.canScrollRight;\n\n return (\n <div\n ref={rootRef}\n onKeyDown={handleKeyDown}\n onFocus={trackAddTileFocus}\n onBlur={trackAddTileFocus}\n onClick={handleClick}\n className={`${ROOT_CLASS} flex items-stretch ${className}`}\n style={{\n ...RULE_ROW_STYLE,\n ...(bleed ? BLEED_STYLE : null),\n ...style,\n }}\n >\n <div\n role=\"radiogroup\"\n aria-label={ariaLabel}\n aria-labelledby={ariaLabelledBy}\n className={hasCards ? 'flex items-stretch min-w-0' : 'flex items-stretch'}\n >\n {leading ? (\n <CardStripSlotContext.Provider value={PINNED_SLOT}>\n <div ref={pinnedRef} className=\"shrink-0\" style={PINNED_SLOT_STYLE}>\n {leading}\n </div>\n </CardStripSlotContext.Provider>\n ) : null}\n {hasCards ? (\n <div\n {...{ [TROUGH_ATTR]: '' }}\n className=\"relative min-w-0 shrink basis-auto\"\n style={TROUGH_STYLE}\n >\n <div\n ref={scrollerRef}\n tabIndex={-1}\n {...{ [SCROLLER_ATTR]: '' }}\n data-snap={snap ? 'true' : 'false'}\n className={SCROLLER_CLASS}\n >\n <CardStripSlotContext.Provider value={SCROLLED_SLOT}>\n {cards}\n </CardStripSlotContext.Provider>\n {addInTrack ? (\n <div ref={addHostRef} {...{ [ADD_SLOT_ATTR]: '' }}>\n {addTiles}\n </div>\n ) : null}\n </div>\n {showLeftArrow ? (\n <ArrowButton side=\"left\" onClick={() => scrollByStep(-1)} />\n ) : null}\n {showRightArrow ? (\n <ArrowButton side=\"right\" onClick={() => scrollByStep(1)} />\n ) : null}\n {fadeLeft || fadeRight ? (\n <div\n aria-hidden\n data-card-strip-fade=\"\"\n className={`${FADE_CLASS} absolute pointer-events-none`}\n style={{\n inset: `-${TROUGH_SHOULDER_PX}px -${FADE_OVERHANG_PX}px 0`,\n background: `linear-gradient(to right, ${fadeLeft ? FADE_COLOR : 'transparent'} 0, transparent ${FADE_RAMP_PX}px, transparent calc(100% - ${FADE_RAMP_PX}px), ${fadeRight ? FADE_COLOR : 'transparent'} 100%)`,\n }}\n />\n ) : null}\n </div>\n ) : null}\n </div>\n {addTiles.length > 0 && !addInTrack ? (\n <div\n ref={addHostRef}\n className=\"shrink-0\"\n style={!hasCards && leading ? EMPTY_ADD_SLOT_STYLE : undefined}\n >\n {addTiles}\n </div>\n ) : null}\n </div>\n );\n};\n\nCardStrip.AddTile = AddTile;\n\nexport default CardStrip;\nexport { CardStrip };\n"],"names":["NAV_KEYS","RADIO_SELECTOR","SCROLLER_ATTR","TROUGH_ATTR","ROOT_CLASS","SCROLLER_CLASS","FADE_CLASS","ADD_TILE_CLASS","ADD_SLOT_ATTR","ACTIONS_SELECTOR","FOCUSABLE_SELECTOR","PREV_TABINDEX_ATTR","FADE_WIDTH_PX","ARROW_GLYPH_PX","GUTTER_REST_PX","LIP_SHADOW","ARROW_BACKGROUND","ARROW_BORDER","TROUGH_BACKGROUND","CARD_CORNER","CARD_RADIUS","TROUGH_CORNER","TROUGH_RADIUS","TROUGH_SHOULDER_PX","ARROW_OFFSET_PX","FADE_OVERHANG_PX","FADE_RAMP_PX","SLOT_WIDTH_PX","CARD_WIDTH_PX","TROUGH_FLOOR_PX","DIVIDER_COLOR","FADE_COLOR","ADD_HOVER_BACKGROUND","ADD_PILL_BORDER","ADD_PILL_BORDER_ACTIVE","ADD_PILL_SHADOW_DEEP","ADD_PILL_BACKGROUND","ADD_PILL_FOREGROUND","ADD_PILL_PRIMARY_BACKGROUND","ADD_PILL_PRIMARY_FOREGROUND","ADD_PILL_PRIMARY_SHADOW","BOTTOM_RULE_WEIGHT_PX","STRIP_RULE_PX","OVERFLOW_INSET_PX","CLIP_SLACK_PX","FOCUS_RING_REACH_PX","SCROLLER_CSS","CARD_FLARE_PX","STYLE_ID","ADD_SLOT_STYLE_ID","ADD_SLOT_CSS","prefersReducedMotion","radioValue","radio","isRadioDisabled","actionsFor","card","radioForClick","target","root","direct","node","radios","actionControls","actions","suppressTabStop","element","restoreTabStop","previous","TONE_RULE","RULE_ROW_STYLE","RULE_GAP_OVERLAP_PX","FLARE_TIP_INSET_PX","CARD_FLARE_TIP_PX","flareTips","flare","FLARE_CLASS","left","right","paintRule","scroller","tone","colour","rootRect","rootLeft","clip","cardRect","tips","tipLeft","tipRight","from","to","BLEED_STYLE","CONTENT_INSET","TROUGH_SURFACE","TROUGH_STYLE","ADD_TILE_SHAPE_STYLE","PINNED_SLOT_STYLE","EMPTY_ADD_SLOT_STYLE","ADD_PILL_FILL","AddTile","label","icon","onClick","disabled","emphasis","className","jsx","jsxs","FOCUS_RING","PlusIcon","isAddTile","React","hidesAddTile","child","ArrowButton","side","ArrowLeftIcon","ForwardArrowIcon","CardStrip","value","onChange","children","leading","arrows","fadeEdges","snap","bleed","scrollSelectedIntoView","ariaLabel","ariaLabelledBy","style","rootRef","useRef","pinnedRef","scrollerRef","hasPositioned","edges","setEdges","useState","cramped","setCramped","addHostRef","addTileFocused","useAdoptedStyleSheet","childList","cards","wrappedAddTile","hasCards","addTiles","tile","childCount","addTileCount","useLayoutEffect","pinnedSlot","paddingLeft","paddingRight","inset","content","pinned","decide","needs","observer","entries","entry","_b","_a","addInTrack","trackAddTileFocus","useCallback","event","focused","host","active","getRadios","radioOrder","reorders","setReorders","next","count","getNavigableRadios","warned","warnOnce","key","message","derivedTone","setDerivedTone","selectedCard","navigable","tabStop","holdsTabStop","nextTabIndex","control","values","current","selectionSettled","checked","selected","wasPositioned","revealTargetFor","ruleTone","callerPaintsBackground","measure","scrollWidth","clientWidth","scrollLeft","overflows","EDGE_EPSILON_PX","selectedInView","isCardInView","wasInView","onScroll","frame","reveal","onResize","scrollByStep","direction","pageTargetFor","handleKeyDown","enabled","currentPosition","nextPosition","delta","nextValue","handleClick","clicked","showLeftArrow","showRightArrow","fadeLeft","fadeRight","CardStripSlotContext","PINNED_SLOT","SCROLLED_SLOT"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@stackone/malachite",
3
- "version": "2.37.0",
3
+ "version": "2.37.1",
4
4
  "description": "StackOne's themeable React component library — Shadow DOM isolated, scoped Tailwind, theme-token driven.",
5
5
  "license": "MIT",
6
6
  "author": "StackOne",