@yewdiel21/motion-kit 0.15.0 → 0.16.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (48) hide show
  1. package/README.md +4 -0
  2. package/dist/auto/index.d.ts +3 -3
  3. package/dist/auto/index.js +2 -2
  4. package/dist/{chunk-6IRJYXJU.js → chunk-NFZIX3IA.js} +2 -2
  5. package/dist/{chunk-JXRS3OEA.js → chunk-RBEKR5UZ.js} +29 -7
  6. package/dist/chunk-RBEKR5UZ.js.map +1 -0
  7. package/dist/{chunk-A6QQCF6V.js → chunk-SDQ776LG.js} +129 -17
  8. package/dist/chunk-SDQ776LG.js.map +1 -0
  9. package/dist/css/components/chart.css +7 -0
  10. package/dist/css/components/heatmap-chart.css +7 -0
  11. package/dist/css/components/pie-chart.css +7 -0
  12. package/dist/css/components/radar-chart.css +7 -0
  13. package/dist/css/components/radial-chart.css +16 -2
  14. package/dist/css/components/sankey-chart.css +7 -0
  15. package/dist/css/components/scroll-island.css +3 -0
  16. package/dist/elements/index.d.ts +3 -3
  17. package/dist/elements/index.js +11 -6
  18. package/dist/elements/index.js.map +1 -1
  19. package/dist/index.css +19 -2
  20. package/dist/index.d.ts +3 -3
  21. package/dist/index.js +3 -3
  22. package/dist/react/index.d.ts +9 -9
  23. package/dist/react/index.js +16 -10
  24. package/dist/react/index.js.map +1 -1
  25. package/dist/{reduced-6X_bns60.d.ts → reduced-DQwVXQYb.d.ts} +1 -1
  26. package/dist/{reveal-BfyKKsw4.d.ts → reveal-DRpNO4KP.d.ts} +12 -0
  27. package/dist/{store-CA2Qcun_.d.ts → store-Da3zSh8Z.d.ts} +5 -1
  28. package/package.json +1 -1
  29. package/src/components/add-to-cart/README.md +49 -34
  30. package/src/components/add-to-cart/react.tsx +4 -0
  31. package/src/components/chart/README.md +49 -34
  32. package/src/components/chart/chart.css +7 -0
  33. package/src/components/chart/element.ts +2 -1
  34. package/src/components/chart/engine.ts +105 -13
  35. package/src/components/chart/react.tsx +2 -2
  36. package/src/components/radial-chart/README.md +10 -0
  37. package/src/components/radial-chart/element.ts +2 -2
  38. package/src/components/radial-chart/engine.ts +33 -6
  39. package/src/components/radial-chart/radial-chart.css +9 -2
  40. package/src/components/radial-chart/react.tsx +2 -2
  41. package/src/components/scroll-island/README.md +44 -34
  42. package/src/components/scroll-island/element.ts +1 -1
  43. package/src/components/scroll-island/engine.ts +25 -3
  44. package/src/components/scroll-island/react.tsx +3 -3
  45. package/src/components/scroll-island/scroll-island.css +3 -0
  46. package/dist/chunk-A6QQCF6V.js.map +0 -1
  47. package/dist/chunk-JXRS3OEA.js.map +0 -1
  48. /package/dist/{chunk-6IRJYXJU.js.map → chunk-NFZIX3IA.js.map} +0 -0
@@ -3,7 +3,7 @@ import { reduced } from '../../core/reduced';
3
3
  import { createScope } from '../../core/scope';
4
4
  import { inert, type Instance } from '../../core/types';
5
5
  import { blurIn, rollDigits } from '../../motion/micro';
6
- import { chartFrame, finite, formatNumber, onWidth, polar, round, slotColor, svg } from '../chart/parts';
6
+ import { arcPath, chartFrame, finite, formatNumber, onWidth, polar, round, slotColor, svg } from '../chart/parts';
7
7
 
8
8
  /*
9
9
  * Radial chart: totals as rings, one inside the other, each filling its track
@@ -33,6 +33,10 @@ export interface RadialChartOptions {
33
33
  size?: number;
34
34
  /** Ring thickness in px (default: what fits, up to 16). */
35
35
  thickness?: number;
36
+ /** Discrete sectors per ring (0: continuous, default). */
37
+ segments?: number;
38
+ /** Show values (default) or progress toward the goals in the middle. */
39
+ center?: 'value' | 'percent';
36
40
  label?: string;
37
41
  /** The middle when nothing is chosen (default 'Total'). */
38
42
  totalLabel?: string;
@@ -90,6 +94,7 @@ export function createRadialChart(root: HTMLElement | null, initial: RadialChart
90
94
  const percent = (ring: { value: number; max: number }) => new Intl.NumberFormat(undefined, { style: 'percent', maximumFractionDigits: 0 }).format(ring.value / ring.max);
91
95
  const sweep = () => (Math.min(360, Math.max(90, finite(options.sweep) ? options.sweep : 360)) * Math.PI) / 180;
92
96
  const startAngle = () => -sweep() / 2 + (sweep() >= Math.PI * 2 - 1e-6 ? Math.PI : 0);
97
+ const segments = () => finite(options.segments) ? Math.max(0, Math.min(80, Math.round(options.segments))) : 0;
93
98
 
94
99
  let geometry = { size: 240, cx: 120, cy: 120, radii: [] as number[], thickness: 12 };
95
100
  let arcs: SVGPathElement[] = [];
@@ -109,17 +114,35 @@ export function createRadialChart(root: HTMLElement | null, initial: RadialChart
109
114
  const thickness = finite(options.thickness) ? options.thickness : Math.max(4, Math.min(16, fit));
110
115
  const spacing = thickness * 1.35;
111
116
  geometry = { size, cx: size / 2, cy: size / 2, thickness, radii: model.map((_, i) => outer - thickness / 2 - i * spacing) };
112
- canvas.setAttribute('viewBox', `0 0 ${size} ${size}`);
117
+ const half = sweep() <= Math.PI + 1e-6;
118
+ const height = half ? size / 2 + 54 : size;
119
+ canvas.setAttribute('viewBox', `0 0 ${size} ${height}`);
113
120
  canvas.setAttribute('width', String(size));
114
- canvas.setAttribute('height', String(size));
121
+ canvas.setAttribute('height', String(height));
115
122
  plot.style.setProperty('--mk-radial-size', `${size}px`);
116
123
  plot.style.setProperty('--mk-radial-thickness', `${thickness}px`);
124
+ plot.style.setProperty('--mk-radial-center-y', half ? `${size / 2}px` : '50%');
125
+ plot.style.setProperty('--mk-radial-center-width', n === 1 ? '0.68' : '0.36');
117
126
  };
118
127
  scope.add(() => {
119
128
  plot.style.removeProperty('--mk-radial-size');
120
129
  plot.style.removeProperty('--mk-radial-thickness');
130
+ plot.style.removeProperty('--mk-radial-center-y');
131
+ plot.style.removeProperty('--mk-radial-center-width');
121
132
  });
122
133
 
134
+ const segmentedPath = (radius: number, share: number) => {
135
+ const count = segments(), step = sweep() / count, a0 = startAngle();
136
+ const gap = Math.min(step * 0.3, 4 / Math.max(1, radius));
137
+ const limit = a0 + sweep() * Math.min(1, Math.max(0, share));
138
+ const outer = radius + geometry.thickness / 2 - 1, inner = Math.max(0, radius - geometry.thickness / 2 + 1);
139
+ return Array.from({ length: count }, (_, index) => {
140
+ const from = a0 + index * step + gap / 2;
141
+ const to = Math.min(a0 + (index + 1) * step - gap / 2, limit);
142
+ return to > from ? arcPath(geometry.cx, geometry.cy, outer, inner, from, to) : '';
143
+ }).join('');
144
+ };
145
+
123
146
  const build = () => {
124
147
  canvas.replaceChildren();
125
148
  const { cx, cy, radii } = geometry;
@@ -127,13 +150,14 @@ export function createRadialChart(root: HTMLElement | null, initial: RadialChart
127
150
  const back = svg('g', { 'data-mk-part': 'tracks' });
128
151
  const front = svg('g', { 'data-mk-part': 'series' });
129
152
  tracks = model.map((_, i) => {
130
- const track = svg('path', { d: strokeArc(cx, cy, radii[i]!, a0, a0 + sweep()), 'data-mk-index': i });
153
+ const track = svg('path', { d: segments() ? segmentedPath(radii[i]!, 1) : strokeArc(cx, cy, radii[i]!, a0, a0 + sweep()), 'data-mk-index': i });
131
154
  back.append(track);
132
155
  return track;
133
156
  });
134
157
  arcs = model.map((ring, i) => {
135
158
  const arc = svg('path', { 'data-mk-index': i, 'data-mk-part': 'ring' });
136
159
  arc.style.stroke = ring.color;
160
+ if (segments()) arc.style.fill = ring.color;
137
161
  front.append(arc);
138
162
  return arc;
139
163
  });
@@ -146,14 +170,16 @@ export function createRadialChart(root: HTMLElement | null, initial: RadialChart
146
170
  const a0 = startAngle();
147
171
  arcs.forEach((arc, i) => {
148
172
  const share = Math.min(1, Math.max(0, (values[i] ?? 0) / model[i]!.max));
149
- arc.setAttribute('d', share > 0.001 ? strokeArc(cx, cy, radii[i]!, a0, a0 + sweep() * share) : '');
173
+ arc.setAttribute('d', share > 0.001 ? segments() ? segmentedPath(radii[i]!, share) : strokeArc(cx, cy, radii[i]!, a0, a0 + sweep() * share) : '');
150
174
  });
151
175
  };
152
176
 
153
177
  const paintCenter = (animate: boolean) => {
154
178
  center.hidden = !model.length;
155
179
  const ring = selected === null ? null : model[selected];
156
- const text = ring ? format(ring.value) : format(total());
180
+ const denominator = ring ? ring.max : model.reduce((sum, each) => sum + each.max, 0);
181
+ const value = ring ? ring.value : total();
182
+ const text = options.center === 'percent' ? new Intl.NumberFormat(undefined, { style: 'percent', maximumFractionDigits: 1 }).format(value / (denominator || 1)) : format(value);
157
183
  const caption = ring ? `${ring.label} · ${percent(ring)}` : (options.totalLabel ?? 'Total');
158
184
  const changed = centerLabel.textContent !== caption;
159
185
  if (centerValue.textContent !== text) {
@@ -178,6 +204,7 @@ export function createRadialChart(root: HTMLElement | null, initial: RadialChart
178
204
 
179
205
  const draw = (animate: boolean) => {
180
206
  glide?.kill();
207
+ scope.attr(root, 'data-mk-segmented', segments() ? '' : null);
181
208
  const name = options.label ?? 'Gráfica radial';
182
209
  canvas.setAttribute('aria-label', model.length ? `${name}. ${model.length} anillos, total ${format(total())}. Usa las flechas para recorrerlos.` : `${name}: ${options.emptyLabel ?? 'sin datos'}`);
183
210
  frame.fillTable(name, ['Anillo', 'Valor', 'Meta', 'Avance'], model.map((ring) => [ring.label, format(ring.value), format(ring.max), percent(ring)]));
@@ -32,6 +32,13 @@ mk-radial-chart {
32
32
  stroke: var(--mk-chart-grid);
33
33
  }
34
34
 
35
+ [data-mk-chart-type='radial'][data-mk-segmented] :is([data-mk-part='tracks'], [data-mk-part='series']) path {
36
+ stroke-width: 1px;
37
+ stroke-linejoin: round;
38
+ }
39
+ [data-mk-chart-type='radial'][data-mk-segmented] [data-mk-part='tracks'] path { fill: var(--mk-chart-track); stroke: var(--mk-chart-track); }
40
+ [data-mk-chart-type='radial'][data-mk-segmented] [data-mk-part='series'] path[data-mk-on] { filter: brightness(1.12); stroke-width: 2px; }
41
+
35
42
  [data-mk-chart-type='radial'] :is([data-mk-part='tracks'], [data-mk-part='series']) path[data-mk-on] {
36
43
  stroke-width: calc(var(--mk-radial-thickness, 12px) + 4px);
37
44
  }
@@ -42,12 +49,12 @@ mk-radial-chart {
42
49
 
43
50
  [data-mk-radial-center] {
44
51
  position: absolute;
45
- top: 50%;
52
+ top: var(--mk-radial-center-y, 50%);
46
53
  left: 50%;
47
54
  display: grid;
48
55
  justify-items: center;
49
56
  gap: 0.15rem;
50
- max-width: calc(var(--mk-radial-size, 240px) * 0.36);
57
+ max-width: calc(var(--mk-radial-size, 240px) * var(--mk-radial-center-width, 0.36));
51
58
  transform: translate(-50%, -50%);
52
59
  text-align: center;
53
60
  pointer-events: none;
@@ -8,7 +8,7 @@ export interface RadialChartProps extends Omit<HTMLAttributes<HTMLDivElement>, '
8
8
  }
9
9
 
10
10
  /** <RadialChart label="Metas" data={[{ label: 'Pasos', value: 7400, max: 10000 }, …]} /> */
11
- export function RadialChart({ data, max, sweep, size, thickness, label, totalLabel, legend, emptyLabel, formatValue, onSelect, instanceRef, className, ...props }: RadialChartProps) {
12
- const ref = useChart(createRadialChart, { data, max, sweep, size, thickness, label, totalLabel, legend, emptyLabel } as RadialChartOptions, { formatValue, onSelect }, instanceRef);
11
+ export function RadialChart({ data, max, sweep, size, thickness, segments, center, label, totalLabel, legend, emptyLabel, formatValue, onSelect, instanceRef, className, ...props }: RadialChartProps) {
12
+ const ref = useChart(createRadialChart, { data, max, sweep, size, thickness, segments, center, label, totalLabel, legend, emptyLabel } as RadialChartOptions, { formatValue, onSelect }, instanceRef);
13
13
  return <div {...props} ref={ref} className={['mk-chart mk-radial-chart', className].filter(Boolean).join(' ')} />;
14
14
  }
@@ -1,34 +1,44 @@
1
- # scroll-island
2
-
3
- Qué hace, en una frase.
4
-
5
- Origen: archivo del kit y parámetros (tiempos, curvas).
6
-
7
- ## HTML / Astro
8
-
9
- ```html
10
- <mk-scroll-island></mk-scroll-island>
11
- <script>
12
- import { defineElements } from '@yewdiel21/motion-kit/elements';
13
- defineElements(['mk-scroll-island']);
14
- </script>
15
- ```
16
-
17
- ## React
18
-
19
- ```tsx
20
- <ScrollIsland />
21
- ```
22
-
23
- ## Opciones
24
-
25
- | Opción | Atributo | Por defecto | Qué hace |
26
- |---|---|---|---|
27
-
28
- ## Variables CSS
29
-
30
- `--mk-scroll-island-radius`
31
-
32
- ## Accesibilidad
33
-
34
- Roles, foco y teclado. Con movimiento reducido…
1
+ # scroll-island
2
+
3
+ Una barra fina que se transforma en una píldora con el porcentaje y la sección actual al acercar el puntero al borde derecho. Arrastra la píldora o pulsa su carril para desplazarte.
4
+
5
+ ## React
6
+
7
+ ```tsx
8
+ import '@yewdiel21/motion-kit/css';
9
+ import { ScrollIsland } from '@yewdiel21/motion-kit/react';
10
+
11
+ <ScrollIsland persistent style={{ height: 360, overflow: 'auto' }}
12
+ tabIndex={0} role="region" aria-label="Guía de diseño">
13
+ <section style={{ minHeight: 400 }}><h3>Introducción</h3>Contenido…</section>
14
+ <section style={{ minHeight: 400 }}><h3>Detalles</h3>Contenido…</section>
15
+ </ScrollIsland>
16
+ ```
17
+
18
+ **El contenedor debe tener altura limitada, overflow y contenido suficiente para desplazarse.** Si todo cabe, la barra se oculta. `persistent` deja visible la barra fina mientras está en reposo; por defecto aparece al desplazarse y desaparece después.
19
+
20
+ ## HTML / Astro
21
+
22
+ ```html
23
+ <mk-scroll-island persistent style="display:block;height:360px;overflow:auto"
24
+ tabindex="0" role="region" aria-label="Guía">
25
+ <section style="min-height:400px"><h3>Introducción</h3>Contenido…</section>
26
+ <section style="min-height:400px"><h3>Detalles</h3>Contenido…</section>
27
+ </mk-scroll-island>
28
+ <script>
29
+ import { defineElements } from '@yewdiel21/motion-kit/elements';
30
+ defineElements(['mk-scroll-island']);
31
+ </script>
32
+ ```
33
+
34
+ ## Opciones
35
+
36
+ - `page`: sigue el scroll de la página en vez del contenedor. En React `<ScrollIsland page />` no dibuja contenedor propio.
37
+ - `sections`: selector de encabezados, `h2, h3` por defecto; `false` omite el nombre de sección en la factory/React.
38
+ - `reach`: distancia del borde que activa la píldora, 56 px.
39
+ - `idle`: demora para ocultarse, 900 ms.
40
+ - `persistent`: mantiene la barra fina visible, false por defecto.
41
+ - `onSection(section)`: cambio de sección, también `mk:section` con `detail.section`.
42
+ - Factory `createScrollIsland(root, options)`; instancia `refresh()` y `destroy()`.
43
+
44
+ El overlay decorativo usa `aria-hidden`; el contenido mantiene su desplazamiento nativo por teclado y tacto. Dale `tabindex="0"` y un nombre al panel. Respeta movimiento reducido, se adapta al tamaño del contenedor y elimina el overlay al desmontarse.
@@ -6,7 +6,7 @@ import { createScrollIsland, type ScrollIslandInstance } from './engine';
6
6
  * or <mk-scroll-island page></mk-scroll-island> for the page. Emits mk:section ({section}).
7
7
  */
8
8
  export class MkScrollIslandElement extends MkElement<ScrollIslandInstance> {
9
- static options: Record<string, OptionType> = { sections: 'string', reach: 'number', idle: 'number', page: 'boolean' };
9
+ static options: Record<string, OptionType> = { sections: 'string', reach: 'number', idle: 'number', persistent: 'boolean', page: 'boolean' };
10
10
 
11
11
  protected create(options: Record<string, unknown>) {
12
12
  return createScrollIsland(options.page ? document.documentElement : this, options);
@@ -23,6 +23,8 @@ export interface ScrollIslandOptions {
23
23
  reach?: number;
24
24
  /** ms the bar stays after scrolling stops (default 900). */
25
25
  idle?: number;
26
+ /** Keep the thin bar visible while idle (default false). */
27
+ persistent?: boolean;
26
28
  /** Follow the page's scroll (default: when the root is <html> or <body>). */
27
29
  page?: boolean;
28
30
  /** The current section changed (its heading's text, or null before the first). */
@@ -52,6 +54,7 @@ export function createScrollIsland(root: HTMLElement | null, options: ScrollIsla
52
54
  const marked = page ? document.documentElement : root;
53
55
  // The scroller's own bar hides (scroll-island.css).
54
56
  scope.attr(marked, 'data-mk-scroll-island-host', '');
57
+ scope.attr(root, 'data-mk-ready', '');
55
58
 
56
59
  const island = document.createElement('div');
57
60
  island.dataset.mkScrollIsland = '';
@@ -99,6 +102,16 @@ export function createScrollIsland(root: HTMLElement | null, options: ScrollIsla
99
102
  let section: string | null | undefined;
100
103
  let hideTimer: ReturnType<typeof setTimeout> | undefined;
101
104
  let dragging: { id: number; offset: number } | null = null;
105
+ let scrollBehavior: { value: string; priority: string; hadStyle: boolean } | null = null;
106
+ const restoreBehavior = () => {
107
+ if (!scrollBehavior) return;
108
+ const previous = scrollBehavior;
109
+ if (previous.value) scroller.style.setProperty('scroll-behavior', previous.value, previous.priority);
110
+ else scroller.style.removeProperty('scroll-behavior');
111
+ if (!previous.hadStyle && !scroller.getAttribute('style')) scroller.removeAttribute('style');
112
+ scrollBehavior = null;
113
+ };
114
+ scope.add(restoreBehavior);
102
115
  scope.add(() => clearTimeout(hideTimer));
103
116
 
104
117
  const headings = () => (options.sections === false ? [] : [...(page ? document.body : root).querySelectorAll<HTMLElement>(options.sections ?? 'h2, h3')]);
@@ -116,7 +129,7 @@ export function createScrollIsland(root: HTMLElement | null, options: ScrollIsla
116
129
  const size = as === 'island' ? ISLAND_HEIGHT : Math.max(MIN_BAR, Math.min(height, height * (scroller.clientHeight / Math.max(1, scroller.scrollHeight))));
117
130
  const top = (height - size) * progress();
118
131
  if (as !== 'island') return { top, height: size, width: BAR_WIDTH, borderRadius: BAR_WIDTH / 2 };
119
- return { top, height: size, width: Math.max(ISLAND_HEIGHT, content.scrollWidth + 28), borderRadius: size / 2 };
132
+ return { top, height: size, width: Math.min(Math.max(ISLAND_HEIGHT, track().right - track().left - INSET * 2), Math.max(ISLAND_HEIGHT, content.scrollWidth + 28)), borderRadius: size / 2 };
120
133
  };
121
134
 
122
135
  const place = () => {
@@ -158,7 +171,7 @@ export function createScrollIsland(root: HTMLElement | null, options: ScrollIsla
158
171
  const settleLater = () => {
159
172
  clearTimeout(hideTimer);
160
173
  hideTimer = setTimeout(() => {
161
- if (state === 'bar' && !dragging) go('hidden');
174
+ if (state === 'bar' && !dragging && !options.persistent) go('hidden');
162
175
  }, idle);
163
176
  };
164
177
 
@@ -213,6 +226,9 @@ export function createScrollIsland(root: HTMLElement | null, options: ScrollIsla
213
226
  if (state !== 'island' || down.button !== 0) return;
214
227
  down.preventDefault();
215
228
  down.stopPropagation();
229
+ if (!scrollBehavior) scrollBehavior = { value: scroller.style.getPropertyValue('scroll-behavior'), priority: scroller.style.getPropertyPriority('scroll-behavior'), hadStyle: scroller.hasAttribute('style') };
230
+ // A drag follows the pointer directly even when the app uses smooth scrolling.
231
+ scroller.style.setProperty('scroll-behavior', 'auto', 'important');
216
232
  const box = thumb.getBoundingClientRect();
217
233
  dragging = { id: down.pointerId, offset: down.clientY - box.top || ISLAND_HEIGHT / 2 };
218
234
  island.setAttribute('data-mk-dragging', '');
@@ -225,6 +241,7 @@ export function createScrollIsland(root: HTMLElement | null, options: ScrollIsla
225
241
  const release = (event: Event) => {
226
242
  if (!dragging || (event as PointerEvent).pointerId !== dragging.id) return;
227
243
  dragging = null;
244
+ restoreBehavior();
228
245
  island.removeAttribute('data-mk-dragging');
229
246
  };
230
247
  scope.on(window, 'pointerup', release);
@@ -240,7 +257,12 @@ export function createScrollIsland(root: HTMLElement | null, options: ScrollIsla
240
257
  });
241
258
 
242
259
  paintText();
243
- go('hidden');
260
+ go(options.persistent ? 'bar' : 'hidden');
261
+ if (typeof ResizeObserver === 'function') {
262
+ const observer = scope.observe(new ResizeObserver(() => { paintText(); go(state, true); }));
263
+ observer.observe(root);
264
+ for (const child of root.children) observer.observe(child);
265
+ }
244
266
 
245
267
  return {
246
268
  refresh: () => {
@@ -9,14 +9,14 @@ export interface ScrollIslandProps extends HTMLAttributes<HTMLDivElement>, Scrol
9
9
  * <ScrollIsland style={{ height: 400, overflow: 'auto' }}>…</ScrollIsland> scrolls its children with the island;
10
10
  * <ScrollIsland page /> puts it on the page (it renders nothing of its own then).
11
11
  */
12
- export function ScrollIsland({ sections, reach, idle, page, onSection, className, children, ...props }: ScrollIslandProps) {
12
+ export function ScrollIsland({ sections, reach, idle, persistent, page, onSection, className, children, ...props }: ScrollIslandProps) {
13
13
  const ref = useRef<HTMLDivElement>(null);
14
14
  const section = useLatest(onSection);
15
15
  useIsomorphicLayoutEffect(() => {
16
- const created = createScrollIsland(page ? document.documentElement : ref.current, { sections, reach, idle, page, onSection: (name) => section.current?.(name) });
16
+ const created = createScrollIsland(page ? document.documentElement : ref.current, { sections, reach, idle, persistent, page, onSection: (name) => section.current?.(name) });
17
17
  return () => created.destroy();
18
18
  // eslint-disable-next-line react-hooks/exhaustive-deps
19
- }, [sections, reach, idle, page]);
19
+ }, [sections, reach, idle, persistent, page]);
20
20
  if (page) return null;
21
21
  return (
22
22
  <div {...props} ref={ref} className={['mk-scroll-island', className].filter(Boolean).join(' ')}>
@@ -73,6 +73,8 @@ mk-scroll-island {
73
73
  [data-mk-island-content] {
74
74
  display: inline-flex;
75
75
  flex: none;
76
+ max-width: 100%;
77
+ min-width: 0;
76
78
  align-items: center;
77
79
  gap: 0.5rem;
78
80
  padding: 0 14px;
@@ -91,6 +93,7 @@ mk-scroll-island {
91
93
  }
92
94
 
93
95
  [data-mk-island-section] {
96
+ min-width: 0;
94
97
  max-width: 12rem;
95
98
  overflow: hidden;
96
99
  color: rgb(255 255 255 / 0.68);