@present-day/reveal-row 0.1.4 → 0.2.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.
package/dist/index.mjs CHANGED
@@ -13,6 +13,17 @@ var REVEAL_HANDLE_POSITION = {
13
13
  start: "start",
14
14
  end: "end"
15
15
  };
16
+ var REVEAL_ROW_ELEMENTS = {
17
+ div: "div",
18
+ section: "section",
19
+ article: "article",
20
+ main: "main",
21
+ aside: "aside",
22
+ header: "header",
23
+ footer: "footer",
24
+ nav: "nav",
25
+ li: "li"
26
+ };
16
27
  var ANIMATION_PRESET = {
17
28
  none: "none",
18
29
  quick: "quick",
@@ -51,7 +62,8 @@ import {
51
62
  useEffect,
52
63
  useImperativeHandle,
53
64
  useLayoutEffect,
54
- useRef
65
+ useRef,
66
+ useState
55
67
  } from "react";
56
68
 
57
69
  // src/DefaultHandleIcon.tsx
@@ -92,23 +104,46 @@ function resolveMode(left, right, mode) {
92
104
  if (left != null) return REVEAL_MODE.left;
93
105
  return REVEAL_MODE.right;
94
106
  }
107
+ function prefersReducedMotion() {
108
+ return typeof window !== "undefined" && typeof window.matchMedia === "function" && window.matchMedia("(prefers-reduced-motion: reduce)").matches;
109
+ }
95
110
  function resolveAnimationConfig(animated, defaultPreset, customConfig) {
111
+ let config;
112
+ let explicit = false;
96
113
  if (animated === false) {
97
- return ANIMATION_PRESETS[ANIMATION_PRESET.none];
98
- }
99
- if (animated === true || animated === void 0) {
100
- return customConfig || ANIMATION_PRESETS[defaultPreset];
114
+ config = ANIMATION_PRESETS[ANIMATION_PRESET.none];
115
+ } else if (animated === true || animated === void 0) {
116
+ if (customConfig) {
117
+ config = customConfig;
118
+ explicit = true;
119
+ } else {
120
+ config = ANIMATION_PRESETS[defaultPreset];
121
+ }
122
+ } else if (typeof animated === "string") {
123
+ config = ANIMATION_PRESETS[animated];
124
+ } else {
125
+ config = animated;
126
+ explicit = true;
101
127
  }
102
- if (typeof animated === "string") {
103
- return ANIMATION_PRESETS[animated];
128
+ if (!explicit && prefersReducedMotion()) {
129
+ return { ...config, duration: 0 };
104
130
  }
105
- return animated;
131
+ return {
132
+ ...config,
133
+ duration: Math.max(
134
+ 0,
135
+ Number.isFinite(config.duration) ? config.duration : 0
136
+ )
137
+ };
106
138
  }
107
139
  var SCROLL_REVEAL_DEBOUNCE_MS = 64;
108
140
  var restEpsilon = 2;
109
141
  var rootScrollStyle = {
110
142
  display: "grid",
111
143
  overflowX: "auto",
144
+ // `overflow-x: auto` would otherwise force `overflow-y` to compute to
145
+ // `auto` — pin it so rows only ever scroll on one axis.
146
+ overflowY: "hidden",
112
147
  scrollSnapType: "x mandatory",
113
148
  scrollbarWidth: "none",
114
149
  WebkitOverflowScrolling: "touch",
@@ -126,6 +161,7 @@ function RevealRowInner({
126
161
  children,
127
162
  left,
128
163
  right,
164
+ as: Element = "div",
129
165
  mode: modeProp,
130
166
  actionWidthLeft: wLIn,
131
167
  actionWidthRight: wRIn,
@@ -149,24 +185,45 @@ function RevealRowInner({
149
185
  const mode = resolveMode(left, right, modeProp);
150
186
  const hasL = mode === REVEAL_MODE.left || mode === REVEAL_MODE.both;
151
187
  const hasR = mode === REVEAL_MODE.right || mode === REVEAL_MODE.both;
152
- const wL = hasL ? wLIn ?? 88 : 0;
153
- const wR = hasR ? wRIn ?? 88 : 0;
154
188
  const handlePosition = handlePositionProp ?? (mode === REVEAL_MODE.left ? REVEAL_HANDLE_POSITION.start : REVEAL_HANDLE_POSITION.end);
155
189
  const containerRef = useRef(null);
156
190
  const leftRef = useRef(null);
157
191
  const rightRef = useRef(null);
158
192
  const lastEmitted = useRef(null);
159
193
  const swipedRef = useRef(false);
194
+ const focusRevealedRef = useRef(false);
195
+ const [settledPosition, setSettledPosition] = useState(
196
+ REVEAL_POSITION.center
197
+ );
198
+ const getWL = useCallback(
199
+ () => hasL ? wLIn ?? (leftRef.current?.offsetWidth || 88) : 0,
200
+ [hasL, wLIn]
201
+ );
202
+ const getWR = useCallback(
203
+ () => hasR ? wRIn ?? (rightRef.current?.offsetWidth || 88) : 0,
204
+ [hasR, wRIn]
205
+ );
160
206
  const debounceTimer = useRef(null);
161
207
  const hasAppliedInitialScroll = useRef(false);
162
208
  const isAnimatingRef = useRef(false);
209
+ const rafIdRef = useRef(null);
210
+ const settleTimerRef = useRef(null);
211
+ const finalizeTimerRef = useRef(null);
212
+ const originalSnapRef = useRef("");
163
213
  const readPosition = useCallback(() => {
164
214
  const el = containerRef.current;
165
215
  if (!el) return REVEAL_POSITION.center;
166
- return getRevealFromScroll(el.scrollLeft, getMaxScroll(el), wL, wR, mode);
167
- }, [wL, wR, mode]);
216
+ return getRevealFromScroll(
217
+ el.scrollLeft,
218
+ getMaxScroll(el),
219
+ getWL(),
220
+ getWR(),
221
+ mode
222
+ );
223
+ }, [getWL, getWR, mode]);
168
224
  const emitReveal = useCallback(
169
225
  (position) => {
226
+ setSettledPosition(position);
170
227
  if (lastEmitted.current === position) return;
171
228
  lastEmitted.current = position;
172
229
  onRevealChange?.(position);
@@ -177,9 +234,9 @@ function RevealRowInner({
177
234
  const el = containerRef.current;
178
235
  if (!el) return;
179
236
  const m = getMaxScroll(el);
180
- const closed = getScrollClosed(wL, wR, m, mode);
237
+ const closed = getScrollClosed(getWL(), getWR(), m, mode);
181
238
  el.scrollLeft = closed;
182
- }, [wL, wR, mode]);
239
+ }, [getWL, getWR, mode]);
183
240
  const scrollToPosition = useCallback(
184
241
  (targetScrollLeft, animationOptions) => {
185
242
  const el = containerRef.current;
@@ -189,9 +246,37 @@ function RevealRowInner({
189
246
  el.scrollLeft = targetScrollLeft;
190
247
  return;
191
248
  }
249
+ if (rafIdRef.current !== null) {
250
+ cancelAnimationFrame(rafIdRef.current);
251
+ rafIdRef.current = null;
252
+ }
253
+ if (settleTimerRef.current !== null) {
254
+ clearTimeout(settleTimerRef.current);
255
+ settleTimerRef.current = null;
256
+ }
257
+ if (finalizeTimerRef.current !== null) {
258
+ clearTimeout(finalizeTimerRef.current);
259
+ finalizeTimerRef.current = null;
260
+ }
261
+ if (!isAnimatingRef.current) {
262
+ originalSnapRef.current = el.style.scrollSnapType;
263
+ }
192
264
  isAnimatingRef.current = true;
193
- const originalScrollSnapType = el.style.scrollSnapType;
194
265
  el.style.scrollSnapType = "none";
266
+ const finish = () => {
267
+ el.scrollLeft = targetScrollLeft;
268
+ el.style.scrollSnapType = originalSnapRef.current || "x mandatory";
269
+ isAnimatingRef.current = false;
270
+ if (rafIdRef.current !== null) {
271
+ cancelAnimationFrame(rafIdRef.current);
272
+ rafIdRef.current = null;
273
+ }
274
+ if (finalizeTimerRef.current !== null) {
275
+ clearTimeout(finalizeTimerRef.current);
276
+ finalizeTimerRef.current = null;
277
+ }
278
+ };
279
+ finalizeTimerRef.current = setTimeout(finish, duration + 100);
195
280
  const startScrollLeft = el.scrollLeft;
196
281
  const distance = targetScrollLeft - startScrollLeft;
197
282
  const startTime = performance.now();
@@ -214,79 +299,119 @@ function RevealRowInner({
214
299
  }
215
300
  el.scrollLeft = startScrollLeft + distance * easedProgress;
216
301
  if (progress < 1) {
217
- requestAnimationFrame(animate);
302
+ rafIdRef.current = requestAnimationFrame(animate);
218
303
  } else {
219
- el.scrollLeft = targetScrollLeft;
220
- el.style.scrollSnapType = originalScrollSnapType || "x mandatory";
221
- isAnimatingRef.current = false;
304
+ rafIdRef.current = null;
305
+ finish();
222
306
  }
223
307
  };
224
- requestAnimationFrame(animate);
308
+ rafIdRef.current = requestAnimationFrame(animate);
225
309
  },
226
310
  []
227
311
  );
228
- useImperativeHandle(
229
- forwardedRef,
230
- () => ({
231
- close: (animated) => {
232
- const el = containerRef.current;
233
- if (!el) return;
234
- const m = getMaxScroll(el);
235
- const closed = getScrollClosed(wL, wR, m, mode);
236
- const animConfig = resolveAnimationConfig(
237
- animated,
238
- animationPreset,
239
- animationConfig
240
- );
241
- scrollToPosition(closed, animConfig);
242
- const delay = animConfig.duration > 0 ? animConfig.duration : 0;
243
- setTimeout(() => {
244
- const p = readPosition();
245
- if (lastEmitted.current !== p) {
246
- lastEmitted.current = p;
247
- onRevealChange?.(p);
248
- }
249
- }, delay);
250
- },
251
- reveal: (position, animated) => {
252
- const el = containerRef.current;
253
- if (!el) return;
254
- const max = getMaxScroll(el);
255
- let targetScroll;
256
- if (position === REVEAL_POSITION.center) {
257
- targetScroll = getScrollClosed(wL, wR, max, mode);
258
- } else if (position === REVEAL_POSITION.left && (mode === REVEAL_MODE.left || mode === REVEAL_MODE.both)) {
259
- targetScroll = 0;
260
- } else if (position === REVEAL_POSITION.right && (mode === REVEAL_MODE.right || mode === REVEAL_MODE.both)) {
261
- targetScroll = max;
262
- } else {
263
- return;
264
- }
265
- const animConfig = resolveAnimationConfig(
266
- animated,
267
- animationPreset,
268
- animationConfig
269
- );
270
- scrollToPosition(targetScroll, animConfig);
271
- const delay = animConfig.duration > 0 ? animConfig.duration : 0;
272
- setTimeout(() => {
273
- const p = getRevealFromScroll(targetScroll, max, wL, wR, mode);
274
- lastEmitted.current = p;
275
- onRevealChange?.(p);
276
- }, delay);
312
+ const closeRow = useCallback(
313
+ (animated) => {
314
+ const el = containerRef.current;
315
+ if (!el) return;
316
+ const m = getMaxScroll(el);
317
+ const closed = getScrollClosed(getWL(), getWR(), m, mode);
318
+ const animConfig = resolveAnimationConfig(
319
+ animated,
320
+ animationPreset,
321
+ animationConfig
322
+ );
323
+ scrollToPosition(closed, animConfig);
324
+ const delay = animConfig.duration > 0 ? animConfig.duration : 0;
325
+ if (settleTimerRef.current !== null) {
326
+ clearTimeout(settleTimerRef.current);
277
327
  }
278
- }),
328
+ settleTimerRef.current = setTimeout(() => {
329
+ emitReveal(readPosition());
330
+ settleTimerRef.current = null;
331
+ }, delay);
332
+ },
279
333
  [
334
+ animationConfig,
335
+ animationPreset,
336
+ emitReveal,
337
+ getWL,
338
+ getWR,
280
339
  mode,
281
- onRevealChange,
282
340
  readPosition,
283
- scrollToPosition,
284
- wL,
285
- wR,
341
+ scrollToPosition
342
+ ]
343
+ );
344
+ const revealRow = useCallback(
345
+ (position, animated) => {
346
+ const el = containerRef.current;
347
+ if (!el) return;
348
+ const max = getMaxScroll(el);
349
+ const wL = getWL();
350
+ const wR = getWR();
351
+ let targetScroll;
352
+ if (position === REVEAL_POSITION.center) {
353
+ targetScroll = getScrollClosed(wL, wR, max, mode);
354
+ } else if (position === REVEAL_POSITION.left && (mode === REVEAL_MODE.left || mode === REVEAL_MODE.both)) {
355
+ targetScroll = 0;
356
+ } else if (position === REVEAL_POSITION.right && (mode === REVEAL_MODE.right || mode === REVEAL_MODE.both)) {
357
+ targetScroll = max;
358
+ } else {
359
+ return;
360
+ }
361
+ const animConfig = resolveAnimationConfig(
362
+ animated,
363
+ animationPreset,
364
+ animationConfig
365
+ );
366
+ scrollToPosition(targetScroll, animConfig);
367
+ const delay = animConfig.duration > 0 ? animConfig.duration : 0;
368
+ if (settleTimerRef.current !== null) {
369
+ clearTimeout(settleTimerRef.current);
370
+ }
371
+ settleTimerRef.current = setTimeout(() => {
372
+ emitReveal(getRevealFromScroll(targetScroll, max, wL, wR, mode));
373
+ settleTimerRef.current = null;
374
+ }, delay);
375
+ },
376
+ [
377
+ animationConfig,
286
378
  animationPreset,
287
- animationConfig
379
+ emitReveal,
380
+ getWL,
381
+ getWR,
382
+ mode,
383
+ scrollToPosition
288
384
  ]
289
385
  );
386
+ useImperativeHandle(
387
+ forwardedRef,
388
+ () => ({ close: closeRow, reveal: revealRow }),
389
+ [closeRow, revealRow]
390
+ );
391
+ const handleRootFocus = useCallback(
392
+ (e) => {
393
+ const t = e.target;
394
+ if (!t) return;
395
+ if (leftRef.current?.contains(t)) {
396
+ focusRevealedRef.current = true;
397
+ revealRow(REVEAL_POSITION.left);
398
+ } else if (rightRef.current?.contains(t)) {
399
+ focusRevealedRef.current = true;
400
+ revealRow(REVEAL_POSITION.right);
401
+ }
402
+ },
403
+ [revealRow]
404
+ );
405
+ const handleRootBlur = useCallback(
406
+ (e) => {
407
+ if (!focusRevealedRef.current) return;
408
+ const next = e.relatedTarget;
409
+ if (next && containerRef.current?.contains(next)) return;
410
+ focusRevealedRef.current = false;
411
+ closeRow();
412
+ },
413
+ [closeRow]
414
+ );
290
415
  useLayoutEffect(() => {
291
416
  if (mode === REVEAL_MODE.right) {
292
417
  return;
@@ -294,10 +419,10 @@ function RevealRowInner({
294
419
  const el = containerRef.current;
295
420
  if (!el) return;
296
421
  if (!hasAppliedInitialScroll.current) {
297
- el.scrollLeft = wL;
422
+ el.scrollLeft = getWL();
298
423
  hasAppliedInitialScroll.current = true;
299
424
  }
300
- }, [mode, wL]);
425
+ }, [mode, getWL]);
301
426
  useEffect(() => {
302
427
  if (disabled && resetWhenDisabled) {
303
428
  hasAppliedInitialScroll.current = true;
@@ -317,6 +442,15 @@ function RevealRowInner({
317
442
  if (debounceTimer.current) {
318
443
  clearTimeout(debounceTimer.current);
319
444
  }
445
+ if (rafIdRef.current !== null) {
446
+ cancelAnimationFrame(rafIdRef.current);
447
+ }
448
+ if (settleTimerRef.current !== null) {
449
+ clearTimeout(settleTimerRef.current);
450
+ }
451
+ if (finalizeTimerRef.current !== null) {
452
+ clearTimeout(finalizeTimerRef.current);
453
+ }
320
454
  },
321
455
  []
322
456
  );
@@ -326,6 +460,8 @@ function RevealRowInner({
326
460
  const el = containerRef.current;
327
461
  if (!el) return;
328
462
  const m = getMaxScroll(el);
463
+ const wL = getWL();
464
+ const wR = getWR();
329
465
  const pos = getRevealFromScroll(el.scrollLeft, m, wL, wR, mode);
330
466
  const closed = getScrollClosed(wL, wR, m, mode);
331
467
  if (Math.abs(el.scrollLeft - closed) > restEpsilon) {
@@ -339,7 +475,7 @@ function RevealRowInner({
339
475
  emitReveal(pos);
340
476
  }, SCROLL_REVEAL_DEBOUNCE_MS);
341
477
  },
342
- [emitReveal, mode, onScrollProp, wL, wR]
478
+ [emitReveal, getWL, getWR, mode, onScrollProp]
343
479
  );
344
480
  const onClickCapture = useCallback((e) => {
345
481
  const t = e.target;
@@ -354,7 +490,9 @@ function RevealRowInner({
354
490
  swipedRef.current = false;
355
491
  }
356
492
  }, []);
357
- const gridTemplateColumns = mode === REVEAL_MODE.right ? `100% ${wR}px` : mode === REVEAL_MODE.left ? `${wL}px 100%` : `${wL}px 100% ${wR}px`;
493
+ const trackL = wLIn != null ? `${wLIn}px` : "max-content";
494
+ const trackR = wRIn != null ? `${wRIn}px` : "max-content";
495
+ const gridTemplateColumns = mode === REVEAL_MODE.right ? `100% ${trackR}` : mode === REVEAL_MODE.left ? `${trackL} 100%` : `${trackL} 100% ${trackR}`;
358
496
  const handleContent = showHandle ? handleOverride !== void 0 ? handleOverride : /* @__PURE__ */ jsxs2(Fragment, { children: [
359
497
  /* @__PURE__ */ jsx2(
360
498
  "span",
@@ -423,13 +561,16 @@ function RevealRowInner({
423
561
  }
424
562
  );
425
563
  return /* @__PURE__ */ jsxs2(
426
- "div",
564
+ Element,
427
565
  {
428
566
  ref: containerRef,
429
567
  "data-reveal-mode": mode,
568
+ "data-reveal-position": settledPosition,
430
569
  className: cx(classNames.root, className),
431
570
  onScroll: handleScroll,
432
571
  onClickCapture,
572
+ onFocus: handleRootFocus,
573
+ onBlur: handleRootBlur,
433
574
  style: {
434
575
  ...disabled ? rootScrollStyleDisabled : rootScrollStyle,
435
576
  ...style,
@@ -442,7 +583,10 @@ function RevealRowInner({
442
583
  ref: leftRef,
443
584
  className: classNames.left,
444
585
  "data-reveal-row-left": true,
445
- style: { ...snapStart, minWidth: 0, width: wL },
586
+ style: {
587
+ ...snapStart,
588
+ ...wLIn != null ? { minWidth: 0, width: wLIn } : { minWidth: "var(--reveal-row-action-min-width, 88px)" }
589
+ },
446
590
  children: left
447
591
  }
448
592
  ) : null,
@@ -453,7 +597,10 @@ function RevealRowInner({
453
597
  ref: rightRef,
454
598
  className: classNames.right,
455
599
  "data-reveal-row-right": true,
456
- style: { ...snapEnd, minWidth: 0, width: wR },
600
+ style: {
601
+ ...snapEnd,
602
+ ...wRIn != null ? { minWidth: 0, width: wRIn } : { minWidth: "var(--reveal-row-action-min-width, 88px)" }
603
+ },
457
604
  children: right
458
605
  }
459
606
  ) : null
@@ -472,6 +619,7 @@ export {
472
619
  REVEAL_HANDLE_POSITION,
473
620
  REVEAL_MODE,
474
621
  REVEAL_POSITION,
622
+ REVEAL_ROW_ELEMENTS,
475
623
  RevealRow,
476
624
  getRevealFromScroll,
477
625
  getScrollClosed
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/types.ts","../src/getRevealFromScroll.ts","../src/RevealRow.tsx","../src/DefaultHandleIcon.tsx"],"sourcesContent":["import type { CSSProperties, ReactNode, UIEvent } from 'react'\n\nexport const REVEAL_MODE = {\n left: 'left',\n right: 'right',\n both: 'both',\n} as const\n\nexport type RevealMode = (typeof REVEAL_MODE)[keyof typeof REVEAL_MODE]\n\nexport const REVEAL_POSITION = {\n left: 'left',\n center: 'center',\n right: 'right',\n} as const\n\nexport type RevealPosition =\n (typeof REVEAL_POSITION)[keyof typeof REVEAL_POSITION]\n\nexport const REVEAL_HANDLE_POSITION = {\n start: 'start',\n end: 'end',\n} as const\n\nexport type RevealHandlePosition =\n (typeof REVEAL_HANDLE_POSITION)[keyof typeof REVEAL_HANDLE_POSITION]\n\nexport const ANIMATION_PRESET = {\n none: 'none',\n quick: 'quick',\n smooth: 'smooth',\n} as const\n\nexport type AnimationPreset =\n (typeof ANIMATION_PRESET)[keyof typeof ANIMATION_PRESET]\n\nexport type AnimationConfig = {\n duration: number\n easing: string\n}\n\nexport const ANIMATION_PRESETS: Record<AnimationPreset, AnimationConfig> = {\n [ANIMATION_PRESET.none]: { duration: 0, easing: 'linear' },\n [ANIMATION_PRESET.quick]: { duration: 200, easing: 'ease-out' },\n [ANIMATION_PRESET.smooth]: { duration: 400, easing: 'ease-in-out' },\n}\n\nexport type RevealRowClassNames = {\n root?: string\n main?: string\n mainInner?: string\n left?: string\n right?: string\n handleContainer?: string\n handleIcon?: string\n}\n\nexport type RevealRowHandle = {\n close: (animated?: boolean | AnimationPreset | AnimationConfig) => void\n reveal: (\n position: RevealPosition,\n animated?: boolean | AnimationPreset | AnimationConfig,\n ) => void\n}\n\nexport type RevealRowProps = {\n /** Primary row content (e.g. title, subtitle). */\n children: ReactNode\n /** Optional leading action column (e.g. delete). Omitted in `right` mode. */\n left?: ReactNode\n /**\n * Trailing action column (e.g. add). Omitted in `left` mode.\n */\n right?: ReactNode\n /**\n * If both `left` and `right` are set, defaults to `both`. If only one side,\n * mode is derived unless overridden.\n */\n mode?: RevealMode\n actionWidthLeft?: number\n actionWidthRight?: number\n classNames?: RevealRowClassNames\n /** @default true */\n showHandle?: boolean\n /** Replaces the built-in drag affordance. */\n handle?: ReactNode\n /**\n * Where the handle sits in the main row. Default: `start` in `left` mode,\n * `end` otherwise.\n */\n handlePosition?: RevealHandlePosition\n handleTitle?: string\n /** Shown in screen-reader text when using the default drag handle. */\n handleAriaLabel?: string\n /** Fires when the settled position changes. */\n onRevealChange?: (position: RevealPosition) => void\n onScroll?: (event: UIEvent<HTMLDivElement>) => void\n /** Resets to closed; default true. */\n resetWhenDisabled?: boolean\n disabled?: boolean\n /**\n * When true, snaps back to the closed position (e.g. row became active/selected\n * elsewhere in the list).\n */\n isActive?: boolean\n className?: string\n style?: CSSProperties\n /**\n * Default animation preset for close/reveal animations when action buttons are clicked.\n * @default 'quick'\n */\n animationPreset?: AnimationPreset\n /**\n * Custom animation configuration overriding the preset.\n */\n animationConfig?: AnimationConfig\n}\n","import {\n REVEAL_MODE,\n REVEAL_POSITION,\n type RevealMode,\n type RevealPosition,\n} from './types'\n\n/**\n * Map horizontal scroll position to a logical \"revealed\" state.\n * `wL` / `wR` are the fixed action column widths; `maxScroll` is\n * `Math.max(0, scrollWidth - clientWidth)`.\n */\nexport function getRevealFromScroll(\n scrollLeft: number,\n maxScroll: number,\n wL: number,\n wR: number,\n mode: RevealMode,\n): RevealPosition {\n if (mode === REVEAL_MODE.right) {\n if (maxScroll <= 0) return REVEAL_POSITION.center\n return scrollLeft < wR / 2 ? REVEAL_POSITION.center : REVEAL_POSITION.right\n }\n if (mode === REVEAL_MODE.left) {\n if (maxScroll <= 0) return REVEAL_POSITION.center\n return scrollLeft < wL / 2 ? REVEAL_POSITION.left : REVEAL_POSITION.center\n }\n if (maxScroll <= 0) return REVEAL_POSITION.center\n if (scrollLeft < wL / 2) return REVEAL_POSITION.left\n if (scrollLeft > maxScroll - wR / 2) return REVEAL_POSITION.right\n return REVEAL_POSITION.center\n}\n\n/** \"Closed\" / resting scrollLeft for a mode (main panel only). */\nexport function getScrollClosed(\n wL: number,\n _wR: number,\n _maxScroll: number,\n mode: RevealMode,\n): number {\n if (mode === REVEAL_MODE.right) return 0\n return wL\n}\n","'use client'\n\nimport type { CSSProperties, ForwardedRef, MouseEvent, UIEvent } from 'react'\nimport {\n forwardRef,\n useCallback,\n useEffect,\n useImperativeHandle,\n useLayoutEffect,\n useRef,\n} from 'react'\n\nimport { DefaultHandleIcon } from './DefaultHandleIcon'\nimport { getRevealFromScroll, getScrollClosed } from './getRevealFromScroll'\nimport {\n ANIMATION_PRESET,\n ANIMATION_PRESETS,\n type AnimationConfig,\n type AnimationPreset,\n REVEAL_HANDLE_POSITION,\n REVEAL_MODE,\n REVEAL_POSITION,\n type RevealHandlePosition,\n type RevealMode,\n type RevealPosition,\n type RevealRowClassNames,\n type RevealRowHandle,\n type RevealRowProps,\n} from './types'\n\nfunction cx(...parts: (string | undefined)[]) {\n return parts.filter(Boolean).join(' ')\n}\n\nfunction getMaxScroll(el: HTMLDivElement) {\n return Math.max(0, el.scrollWidth - el.clientWidth)\n}\n\nfunction resolveMode(\n left: RevealRowProps['left'],\n right: RevealRowProps['right'],\n mode: RevealMode | undefined,\n): RevealMode {\n if (mode) return mode\n if (left != null && right != null) return REVEAL_MODE.both\n if (left != null) return REVEAL_MODE.left\n return REVEAL_MODE.right\n}\n\nfunction resolveAnimationConfig(\n animated: boolean | AnimationPreset | AnimationConfig | undefined,\n defaultPreset: AnimationPreset,\n customConfig?: AnimationConfig,\n): AnimationConfig {\n if (animated === false) {\n return ANIMATION_PRESETS[ANIMATION_PRESET.none]\n }\n if (animated === true || animated === undefined) {\n return customConfig || ANIMATION_PRESETS[defaultPreset]\n }\n if (typeof animated === 'string') {\n return ANIMATION_PRESETS[animated]\n }\n return animated\n}\n\nconst SCROLL_REVEAL_DEBOUNCE_MS = 64\nconst restEpsilon = 2\n\nconst rootScrollStyle: CSSProperties = {\n display: 'grid',\n overflowX: 'auto',\n scrollSnapType: 'x mandatory',\n scrollbarWidth: 'none',\n WebkitOverflowScrolling: 'touch',\n overscrollBehaviorX: 'contain',\n touchAction: 'pan-x pan-y',\n}\n\nconst rootScrollStyleDisabled: CSSProperties = {\n ...rootScrollStyle,\n overflowX: 'hidden',\n touchAction: 'pan-y',\n}\n\nconst snapStart: CSSProperties = { scrollSnapAlign: 'start' }\nconst snapEnd: CSSProperties = { scrollSnapAlign: 'end' }\n\ntype InnerProps = RevealRowProps & {\n forwardedRef: ForwardedRef<RevealRowHandle>\n}\n\nfunction RevealRowInner({\n children,\n left,\n right,\n mode: modeProp,\n actionWidthLeft: wLIn,\n actionWidthRight: wRIn,\n classNames = {} as RevealRowClassNames,\n showHandle = true,\n handle: handleOverride,\n handlePosition: handlePositionProp,\n handleTitle = 'Drag horizontally to show actions',\n handleAriaLabel = 'Drag horizontally to show actions',\n onRevealChange,\n onScroll: onScrollProp,\n resetWhenDisabled = true,\n disabled = false,\n isActive = false,\n className,\n style,\n animationPreset = ANIMATION_PRESET.quick,\n animationConfig,\n forwardedRef,\n}: InnerProps) {\n const mode = resolveMode(left, right, modeProp)\n const hasL = mode === REVEAL_MODE.left || mode === REVEAL_MODE.both\n const hasR = mode === REVEAL_MODE.right || mode === REVEAL_MODE.both\n const wL = hasL ? (wLIn ?? 88) : 0\n const wR = hasR ? (wRIn ?? 88) : 0\n\n const handlePosition: RevealHandlePosition =\n handlePositionProp ??\n (mode === REVEAL_MODE.left\n ? REVEAL_HANDLE_POSITION.start\n : REVEAL_HANDLE_POSITION.end)\n\n const containerRef = useRef<HTMLDivElement>(null)\n const leftRef = useRef<HTMLDivElement>(null)\n const rightRef = useRef<HTMLDivElement>(null)\n const lastEmitted = useRef<RevealPosition | null>(null)\n const swipedRef = useRef(false)\n const debounceTimer = useRef<ReturnType<typeof setTimeout> | null>(null)\n const hasAppliedInitialScroll = useRef(false)\n const isAnimatingRef = useRef(false)\n\n const readPosition = useCallback((): RevealPosition => {\n const el = containerRef.current\n if (!el) return REVEAL_POSITION.center\n return getRevealFromScroll(el.scrollLeft, getMaxScroll(el), wL, wR, mode)\n }, [wL, wR, mode])\n\n const emitReveal = useCallback(\n (position: RevealPosition) => {\n if (lastEmitted.current === position) return\n lastEmitted.current = position\n onRevealChange?.(position)\n },\n [onRevealChange],\n )\n\n const scrollToClosed = useCallback(() => {\n const el = containerRef.current\n if (!el) return\n const m = getMaxScroll(el)\n const closed = getScrollClosed(wL, wR, m, mode)\n\n // For immediate scroll, we can use the default behavior\n // CSS scroll snap will handle the final positioning\n el.scrollLeft = closed\n }, [wL, wR, mode])\n\n const scrollToPosition = useCallback(\n (targetScrollLeft: number, animationOptions: AnimationConfig) => {\n const el = containerRef.current\n if (!el) return\n\n const { duration, easing } = animationOptions\n\n if (duration === 0) {\n el.scrollLeft = targetScrollLeft\n return\n }\n\n // Disable scroll snap during animation\n isAnimatingRef.current = true\n const originalScrollSnapType = el.style.scrollSnapType\n el.style.scrollSnapType = 'none'\n\n const startScrollLeft = el.scrollLeft\n const distance = targetScrollLeft - startScrollLeft\n const startTime = performance.now()\n\n const animate = (currentTime: number) => {\n const elapsed = currentTime - startTime\n const progress = Math.min(elapsed / duration, 1)\n\n let easedProgress = progress\n if (easing === 'ease-out') {\n easedProgress = 1 - (1 - progress) ** 2\n } else if (easing === 'ease-in-out') {\n easedProgress =\n progress < 0.5\n ? 2 * progress * progress\n : 1 - (-2 * progress + 2) ** 2 / 2\n } else if (easing.startsWith('cubic-bezier')) {\n // For the bounce effect, we'll use a simplified approximation\n easedProgress = progress * progress * (3 - 2 * progress)\n if (easing.includes('-0.55')) {\n // Bounce effect approximation\n easedProgress =\n progress < 0.5\n ? 4 * progress * progress * progress\n : 1 - (-2 * progress + 2) ** 3 / 2\n // Add overshoot for bounce\n if (progress > 0.7 && progress < 1) {\n easedProgress +=\n Math.sin((progress - 0.7) * Math.PI * 10) * 0.1 * (1 - progress)\n }\n }\n }\n\n el.scrollLeft = startScrollLeft + distance * easedProgress\n\n if (progress < 1) {\n requestAnimationFrame(animate)\n } else {\n el.scrollLeft = targetScrollLeft\n // Re-enable scroll snap after animation completes\n el.style.scrollSnapType = originalScrollSnapType || 'x mandatory'\n isAnimatingRef.current = false\n }\n }\n\n requestAnimationFrame(animate)\n },\n [],\n )\n\n useImperativeHandle(\n forwardedRef,\n () => ({\n close: (animated?: boolean | AnimationPreset | AnimationConfig) => {\n const el = containerRef.current\n if (!el) return\n\n const m = getMaxScroll(el)\n const closed = getScrollClosed(wL, wR, m, mode)\n const animConfig = resolveAnimationConfig(\n animated,\n animationPreset,\n animationConfig,\n )\n\n scrollToPosition(closed, animConfig)\n\n // Update position after animation or immediately if no animation\n const delay = animConfig.duration > 0 ? animConfig.duration : 0\n setTimeout(() => {\n const p = readPosition()\n if (lastEmitted.current !== p) {\n lastEmitted.current = p\n onRevealChange?.(p)\n }\n }, delay)\n },\n reveal: (\n position: RevealPosition,\n animated?: boolean | AnimationPreset | AnimationConfig,\n ) => {\n const el = containerRef.current\n if (!el) return\n const max = getMaxScroll(el)\n\n let targetScroll: number\n if (position === REVEAL_POSITION.center) {\n targetScroll = getScrollClosed(wL, wR, max, mode)\n } else if (\n position === REVEAL_POSITION.left &&\n (mode === REVEAL_MODE.left || mode === REVEAL_MODE.both)\n ) {\n targetScroll = 0\n } else if (\n position === REVEAL_POSITION.right &&\n (mode === REVEAL_MODE.right || mode === REVEAL_MODE.both)\n ) {\n targetScroll = max\n } else {\n return\n }\n\n const animConfig = resolveAnimationConfig(\n animated,\n animationPreset,\n animationConfig,\n )\n scrollToPosition(targetScroll, animConfig)\n\n // Update position after animation or immediately if no animation\n const delay = animConfig.duration > 0 ? animConfig.duration : 0\n setTimeout(() => {\n const p = getRevealFromScroll(targetScroll, max, wL, wR, mode)\n lastEmitted.current = p\n onRevealChange?.(p)\n }, delay)\n },\n }),\n [\n mode,\n onRevealChange,\n readPosition,\n scrollToPosition,\n wL,\n wR,\n animationPreset,\n animationConfig,\n ],\n )\n\n useLayoutEffect(() => {\n if (mode === REVEAL_MODE.right) {\n return\n }\n const el = containerRef.current\n if (!el) return\n if (!hasAppliedInitialScroll.current) {\n el.scrollLeft = wL\n hasAppliedInitialScroll.current = true\n }\n }, [mode, wL])\n\n useEffect(() => {\n if (disabled && resetWhenDisabled) {\n hasAppliedInitialScroll.current = true\n scrollToClosed()\n emitReveal(readPosition())\n }\n }, [disabled, emitReveal, readPosition, resetWhenDisabled, scrollToClosed])\n\n useEffect(() => {\n if (isActive) {\n hasAppliedInitialScroll.current = true\n scrollToClosed()\n emitReveal(readPosition())\n }\n }, [emitReveal, isActive, readPosition, scrollToClosed])\n\n useEffect(\n () => () => {\n if (debounceTimer.current) {\n clearTimeout(debounceTimer.current)\n }\n },\n [],\n )\n\n const handleScroll = useCallback(\n (e: UIEvent<HTMLDivElement>) => {\n onScrollProp?.(e)\n const el = containerRef.current\n if (!el) return\n const m = getMaxScroll(el)\n const pos = getRevealFromScroll(el.scrollLeft, m, wL, wR, mode)\n const closed = getScrollClosed(wL, wR, m, mode)\n if (Math.abs(el.scrollLeft - closed) > restEpsilon) {\n swipedRef.current = true\n }\n if (debounceTimer.current) {\n clearTimeout(debounceTimer.current)\n }\n debounceTimer.current = setTimeout(() => {\n debounceTimer.current = null\n emitReveal(pos)\n }, SCROLL_REVEAL_DEBOUNCE_MS)\n },\n [emitReveal, mode, onScrollProp, wL, wR],\n )\n\n const onClickCapture = useCallback((e: MouseEvent) => {\n const t = e.target as Node | null\n if (t) {\n if (leftRef.current?.contains(t) || rightRef.current?.contains(t)) {\n return\n }\n }\n if (swipedRef.current) {\n e.preventDefault()\n e.stopPropagation()\n swipedRef.current = false\n }\n }, [])\n\n // `100%` for the main track (not `1fr`) so total row width > viewport: otherwise both\n // columns can shrink to fit with no overflow and the action stays visible.\n const gridTemplateColumns =\n mode === REVEAL_MODE.right\n ? `100% ${wR}px`\n : mode === REVEAL_MODE.left\n ? `${wL}px 100%`\n : `${wL}px 100% ${wR}px`\n\n const handleContent = showHandle ? (\n handleOverride !== undefined ? (\n handleOverride\n ) : (\n <>\n <span\n className=\"sr-only\"\n style={{\n position: 'absolute',\n width: 1,\n height: 1,\n padding: 0,\n margin: -1,\n overflow: 'hidden',\n clip: 'rect(0,0,0,0)',\n border: 0,\n }}\n >\n {handleAriaLabel}\n </span>\n <span className={classNames.handleIcon} aria-hidden>\n <DefaultHandleIcon />\n </span>\n </>\n )\n ) : null\n\n const handleStrip = showHandle ? (\n <div\n role=\"presentation\"\n className={classNames.handleContainer}\n data-reveal-row-handle\n style={{\n flexShrink: 0,\n alignSelf: 'stretch',\n display: 'flex',\n alignItems: 'center',\n }}\n title={handleOverride === undefined ? handleTitle : undefined}\n >\n {handleContent}\n </div>\n ) : null\n\n const mainColumn = (\n <div\n className={classNames.main}\n data-reveal-row-main\n style={{\n ...snapStart,\n minWidth: 0,\n width: '100%',\n maxWidth: '100%',\n boxSizing: 'border-box',\n }}\n >\n <div\n className={classNames.mainInner}\n style={{\n display: 'flex',\n minWidth: 0,\n width: '100%',\n alignItems: 'flex-start',\n }}\n >\n {handlePosition === REVEAL_HANDLE_POSITION.start && handleStrip}\n <div style={{ minWidth: 0, flex: 1, flexBasis: 0 }}>{children}</div>\n {handlePosition === REVEAL_HANDLE_POSITION.end && handleStrip}\n </div>\n </div>\n )\n\n return (\n <div\n ref={containerRef}\n data-reveal-mode={mode}\n className={cx(classNames.root, className)}\n onScroll={handleScroll}\n onClickCapture={onClickCapture}\n style={{\n ...(disabled ? rootScrollStyleDisabled : rootScrollStyle),\n ...style,\n gridTemplateColumns,\n }}\n >\n {hasL ? (\n <div\n ref={leftRef}\n className={classNames.left}\n data-reveal-row-left\n style={{ ...snapStart, minWidth: 0, width: wL }}\n >\n {left}\n </div>\n ) : null}\n {mainColumn}\n {hasR ? (\n <div\n ref={rightRef}\n className={classNames.right}\n data-reveal-row-right\n style={{ ...snapEnd, minWidth: 0, width: wR }}\n >\n {right}\n </div>\n ) : null}\n </div>\n )\n}\n\nexport const RevealRow = forwardRef<RevealRowHandle, RevealRowProps>(\n function RevealRow(props, ref) {\n return <RevealRowInner {...props} forwardedRef={ref} />\n },\n)\n","/** Minimal 6-dot grip, no icon library dependency. */\nexport function DefaultHandleIcon() {\n return (\n <svg\n width={16}\n height={16}\n viewBox=\"0 0 16 16\"\n fill=\"currentColor\"\n aria-hidden\n >\n <title>Drag handle</title>\n <circle cx=\"6\" cy=\"4\" r=\"1.2\" />\n <circle cx=\"10\" cy=\"4\" r=\"1.2\" />\n <circle cx=\"6\" cy=\"8\" r=\"1.2\" />\n <circle cx=\"10\" cy=\"8\" r=\"1.2\" />\n <circle cx=\"6\" cy=\"12\" r=\"1.2\" />\n <circle cx=\"10\" cy=\"12\" r=\"1.2\" />\n </svg>\n )\n}\n"],"mappings":"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","names":["jsx","jsxs","RevealRow"]}
1
+ {"version":3,"sources":["../src/types.ts","../src/getRevealFromScroll.ts","../src/RevealRow.tsx","../src/DefaultHandleIcon.tsx"],"sourcesContent":["import type { CSSProperties, ReactNode, UIEvent } from 'react'\n\nexport const REVEAL_MODE = {\n left: 'left',\n right: 'right',\n both: 'both',\n} as const\n\nexport type RevealMode = (typeof REVEAL_MODE)[keyof typeof REVEAL_MODE]\n\nexport const REVEAL_POSITION = {\n left: 'left',\n center: 'center',\n right: 'right',\n} as const\n\nexport type RevealPosition =\n (typeof REVEAL_POSITION)[keyof typeof REVEAL_POSITION]\n\nexport const REVEAL_HANDLE_POSITION = {\n start: 'start',\n end: 'end',\n} as const\n\nexport type RevealHandlePosition =\n (typeof REVEAL_HANDLE_POSITION)[keyof typeof REVEAL_HANDLE_POSITION]\n\nexport const REVEAL_ROW_ELEMENTS = {\n div: 'div',\n section: 'section',\n article: 'article',\n main: 'main',\n aside: 'aside',\n header: 'header',\n footer: 'footer',\n nav: 'nav',\n li: 'li',\n} as const\n\nexport type RevealRowElement =\n (typeof REVEAL_ROW_ELEMENTS)[keyof typeof REVEAL_ROW_ELEMENTS]\n\nexport const ANIMATION_PRESET = {\n none: 'none',\n quick: 'quick',\n smooth: 'smooth',\n} as const\n\nexport type AnimationPreset =\n (typeof ANIMATION_PRESET)[keyof typeof ANIMATION_PRESET]\n\nexport type AnimationConfig = {\n duration: number\n easing: string\n}\n\nexport const ANIMATION_PRESETS: Record<AnimationPreset, AnimationConfig> = {\n [ANIMATION_PRESET.none]: { duration: 0, easing: 'linear' },\n [ANIMATION_PRESET.quick]: { duration: 200, easing: 'ease-out' },\n [ANIMATION_PRESET.smooth]: { duration: 400, easing: 'ease-in-out' },\n}\n\nexport type RevealRowClassNames = {\n root?: string\n main?: string\n mainInner?: string\n left?: string\n right?: string\n handleContainer?: string\n handleIcon?: string\n}\n\nexport type RevealRowHandle = {\n close: (animated?: boolean | AnimationPreset | AnimationConfig) => void\n reveal: (\n position: RevealPosition,\n animated?: boolean | AnimationPreset | AnimationConfig,\n ) => void\n}\n\nexport type RevealRowProps = {\n /** Primary row content (e.g. title, subtitle). */\n children: ReactNode\n /** Optional leading action column (e.g. delete). Omitted in `right` mode. */\n left?: ReactNode\n /**\n * Trailing action column (e.g. add). Omitted in `left` mode.\n */\n right?: ReactNode\n /**\n * The HTML element to use for the root container.\n * @default 'div'\n */\n as?: RevealRowElement\n /**\n * If both `left` and `right` are set, defaults to `both`. If only one side,\n * mode is derived unless overridden.\n */\n mode?: RevealMode\n /**\n * Fixed width (px) of the left action column. Omit to size the column to\n * its content with an 88px floor (`minmax(88px, max-content)`).\n */\n actionWidthLeft?: number\n /**\n * Fixed width (px) of the right action column. Omit to size the column to\n * its content with an 88px floor (`minmax(88px, max-content)`).\n */\n actionWidthRight?: number\n classNames?: RevealRowClassNames\n /** @default true */\n showHandle?: boolean\n /** Replaces the built-in drag affordance. */\n handle?: ReactNode\n /**\n * Where the handle sits in the main row. Default: `start` in `left` mode,\n * `end` otherwise.\n */\n handlePosition?: RevealHandlePosition\n handleTitle?: string\n /** Shown in screen-reader text when using the default drag handle. */\n handleAriaLabel?: string\n /** Fires when the settled position changes. */\n onRevealChange?: (position: RevealPosition) => void\n onScroll?: (event: UIEvent<HTMLElement>) => void\n /** Resets to closed; default true. */\n resetWhenDisabled?: boolean\n disabled?: boolean\n /**\n * When true, snaps back to the closed position (e.g. row became active/selected\n * elsewhere in the list).\n */\n isActive?: boolean\n className?: string\n style?: CSSProperties\n /**\n * Default animation preset for close/reveal animations when action buttons are clicked.\n * @default 'quick'\n */\n animationPreset?: AnimationPreset\n /**\n * Custom animation configuration overriding the preset.\n */\n animationConfig?: AnimationConfig\n}\n","import {\n REVEAL_MODE,\n REVEAL_POSITION,\n type RevealMode,\n type RevealPosition,\n} from './types'\n\n/**\n * Map horizontal scroll position to a logical \"revealed\" state.\n * `wL` / `wR` are the fixed action column widths; `maxScroll` is\n * `Math.max(0, scrollWidth - clientWidth)`.\n */\nexport function getRevealFromScroll(\n scrollLeft: number,\n maxScroll: number,\n wL: number,\n wR: number,\n mode: RevealMode,\n): RevealPosition {\n if (mode === REVEAL_MODE.right) {\n if (maxScroll <= 0) return REVEAL_POSITION.center\n return scrollLeft < wR / 2 ? REVEAL_POSITION.center : REVEAL_POSITION.right\n }\n if (mode === REVEAL_MODE.left) {\n if (maxScroll <= 0) return REVEAL_POSITION.center\n return scrollLeft < wL / 2 ? REVEAL_POSITION.left : REVEAL_POSITION.center\n }\n if (maxScroll <= 0) return REVEAL_POSITION.center\n if (scrollLeft < wL / 2) return REVEAL_POSITION.left\n if (scrollLeft > maxScroll - wR / 2) return REVEAL_POSITION.right\n return REVEAL_POSITION.center\n}\n\n/** \"Closed\" / resting scrollLeft for a mode (main panel only). */\nexport function getScrollClosed(\n wL: number,\n _wR: number,\n _maxScroll: number,\n mode: RevealMode,\n): number {\n if (mode === REVEAL_MODE.right) return 0\n return wL\n}\n","'use client'\n\nimport type {\n CSSProperties,\n FocusEvent,\n ForwardedRef,\n MouseEvent,\n UIEvent,\n} from 'react'\nimport {\n forwardRef,\n useCallback,\n useEffect,\n useImperativeHandle,\n useLayoutEffect,\n useRef,\n useState,\n} from 'react'\n\nimport { DefaultHandleIcon } from './DefaultHandleIcon'\nimport { getRevealFromScroll, getScrollClosed } from './getRevealFromScroll'\nimport {\n ANIMATION_PRESET,\n ANIMATION_PRESETS,\n type AnimationConfig,\n type AnimationPreset,\n REVEAL_HANDLE_POSITION,\n REVEAL_MODE,\n REVEAL_POSITION,\n type RevealHandlePosition,\n type RevealMode,\n type RevealPosition,\n type RevealRowClassNames,\n type RevealRowHandle,\n type RevealRowProps,\n} from './types'\n\nfunction cx(...parts: (string | undefined)[]) {\n return parts.filter(Boolean).join(' ')\n}\n\nfunction getMaxScroll(el: HTMLElement) {\n return Math.max(0, el.scrollWidth - el.clientWidth)\n}\n\nfunction resolveMode(\n left: RevealRowProps['left'],\n right: RevealRowProps['right'],\n mode: RevealMode | undefined,\n): RevealMode {\n if (mode) return mode\n if (left != null && right != null) return REVEAL_MODE.both\n if (left != null) return REVEAL_MODE.left\n return REVEAL_MODE.right\n}\n\nfunction prefersReducedMotion(): boolean {\n return (\n typeof window !== 'undefined' &&\n typeof window.matchMedia === 'function' &&\n window.matchMedia('(prefers-reduced-motion: reduce)').matches\n )\n}\n\nfunction resolveAnimationConfig(\n animated: boolean | AnimationPreset | AnimationConfig | undefined,\n defaultPreset: AnimationPreset,\n customConfig?: AnimationConfig,\n): AnimationConfig {\n let config: AnimationConfig\n // An explicit AnimationConfig object is an intentional override and is not\n // reduced; booleans and presets defer to the OS reduced-motion setting.\n let explicit = false\n\n if (animated === false) {\n config = ANIMATION_PRESETS[ANIMATION_PRESET.none]\n } else if (animated === true || animated === undefined) {\n if (customConfig) {\n config = customConfig\n explicit = true\n } else {\n config = ANIMATION_PRESETS[defaultPreset]\n }\n } else if (typeof animated === 'string') {\n config = ANIMATION_PRESETS[animated]\n } else {\n config = animated\n explicit = true\n }\n\n if (!explicit && prefersReducedMotion()) {\n return { ...config, duration: 0 }\n }\n\n // Validate and clamp duration to be >= 0\n return {\n ...config,\n duration: Math.max(\n 0,\n Number.isFinite(config.duration) ? config.duration : 0,\n ),\n }\n}\n\nconst SCROLL_REVEAL_DEBOUNCE_MS = 64\nconst restEpsilon = 2\n\nconst rootScrollStyle: CSSProperties = {\n display: 'grid',\n overflowX: 'auto',\n // `overflow-x: auto` would otherwise force `overflow-y` to compute to\n // `auto` — pin it so rows only ever scroll on one axis.\n overflowY: 'hidden',\n scrollSnapType: 'x mandatory',\n scrollbarWidth: 'none',\n WebkitOverflowScrolling: 'touch',\n overscrollBehaviorX: 'contain',\n touchAction: 'pan-x pan-y',\n}\n\nconst rootScrollStyleDisabled: CSSProperties = {\n ...rootScrollStyle,\n overflowX: 'hidden',\n touchAction: 'pan-y',\n}\n\nconst snapStart: CSSProperties = { scrollSnapAlign: 'start' }\nconst snapEnd: CSSProperties = { scrollSnapAlign: 'end' }\n\ntype InnerProps = RevealRowProps & {\n forwardedRef: ForwardedRef<RevealRowHandle>\n}\n\nfunction RevealRowInner({\n children,\n left,\n right,\n as: Element = 'div',\n mode: modeProp,\n actionWidthLeft: wLIn,\n actionWidthRight: wRIn,\n classNames = {} as RevealRowClassNames,\n showHandle = true,\n handle: handleOverride,\n handlePosition: handlePositionProp,\n handleTitle = 'Drag horizontally to show actions',\n handleAriaLabel = 'Drag horizontally to show actions',\n onRevealChange,\n onScroll: onScrollProp,\n resetWhenDisabled = true,\n disabled = false,\n isActive = false,\n className,\n style,\n animationPreset = ANIMATION_PRESET.quick,\n animationConfig,\n forwardedRef,\n}: InnerProps) {\n const mode = resolveMode(left, right, modeProp)\n const hasL = mode === REVEAL_MODE.left || mode === REVEAL_MODE.both\n const hasR = mode === REVEAL_MODE.right || mode === REVEAL_MODE.both\n\n const handlePosition: RevealHandlePosition =\n handlePositionProp ??\n (mode === REVEAL_MODE.left\n ? REVEAL_HANDLE_POSITION.start\n : REVEAL_HANDLE_POSITION.end)\n\n const containerRef = useRef<HTMLElement>(null)\n const leftRef = useRef<HTMLDivElement>(null)\n const rightRef = useRef<HTMLDivElement>(null)\n const lastEmitted = useRef<RevealPosition | null>(null)\n const swipedRef = useRef(false)\n const focusRevealedRef = useRef(false)\n const [settledPosition, setSettledPosition] = useState<RevealPosition>(\n REVEAL_POSITION.center,\n )\n\n // Effective action-column widths. With an explicit prop this is a constant;\n // without one the column is content-sized (minmax(88px, max-content) track)\n // and the rendered width is read live — only ever inside handlers that\n // already read layout, so no extra reflow cost. `|| 88` covers pre-mount\n // and environments without layout.\n const getWL = useCallback(\n () => (hasL ? (wLIn ?? (leftRef.current?.offsetWidth || 88)) : 0),\n [hasL, wLIn],\n )\n const getWR = useCallback(\n () => (hasR ? (wRIn ?? (rightRef.current?.offsetWidth || 88)) : 0),\n [hasR, wRIn],\n )\n const debounceTimer = useRef<ReturnType<typeof setTimeout> | null>(null)\n const hasAppliedInitialScroll = useRef(false)\n const isAnimatingRef = useRef(false)\n const rafIdRef = useRef<number | null>(null)\n const settleTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null)\n const finalizeTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null)\n const originalSnapRef = useRef('')\n\n const readPosition = useCallback((): RevealPosition => {\n const el = containerRef.current\n if (!el) return REVEAL_POSITION.center\n return getRevealFromScroll(\n el.scrollLeft,\n getMaxScroll(el),\n getWL(),\n getWR(),\n mode,\n )\n }, [getWL, getWR, mode])\n\n const emitReveal = useCallback(\n (position: RevealPosition) => {\n setSettledPosition(position)\n if (lastEmitted.current === position) return\n lastEmitted.current = position\n onRevealChange?.(position)\n },\n [onRevealChange],\n )\n\n const scrollToClosed = useCallback(() => {\n const el = containerRef.current\n if (!el) return\n const m = getMaxScroll(el)\n const closed = getScrollClosed(getWL(), getWR(), m, mode)\n\n // For immediate scroll, we can use the default behavior\n // CSS scroll snap will handle the final positioning\n el.scrollLeft = closed\n }, [getWL, getWR, mode])\n\n const scrollToPosition = useCallback(\n (targetScrollLeft: number, animationOptions: AnimationConfig) => {\n const el = containerRef.current\n if (!el) return\n\n const { duration, easing } = animationOptions\n\n if (duration === 0) {\n el.scrollLeft = targetScrollLeft\n return\n }\n\n // Cancel any existing animation\n if (rafIdRef.current !== null) {\n cancelAnimationFrame(rafIdRef.current)\n rafIdRef.current = null\n }\n if (settleTimerRef.current !== null) {\n clearTimeout(settleTimerRef.current)\n settleTimerRef.current = null\n }\n if (finalizeTimerRef.current !== null) {\n clearTimeout(finalizeTimerRef.current)\n finalizeTimerRef.current = null\n }\n\n // Disable scroll snap during animation. Only capture the original value\n // when no animation is in flight — mid-animation it reads back our own\n // 'none' and would get restored permanently.\n if (!isAnimatingRef.current) {\n originalSnapRef.current = el.style.scrollSnapType\n }\n isAnimatingRef.current = true\n el.style.scrollSnapType = 'none'\n\n const finish = () => {\n el.scrollLeft = targetScrollLeft\n el.style.scrollSnapType = originalSnapRef.current || 'x mandatory'\n isAnimatingRef.current = false\n if (rafIdRef.current !== null) {\n cancelAnimationFrame(rafIdRef.current)\n rafIdRef.current = null\n }\n if (finalizeTimerRef.current !== null) {\n clearTimeout(finalizeTimerRef.current)\n finalizeTimerRef.current = null\n }\n }\n\n // rAF is frozen on hidden/occluded pages — guarantee the animation\n // completes (and snap is restored) via a timer fallback.\n finalizeTimerRef.current = setTimeout(finish, duration + 100)\n\n const startScrollLeft = el.scrollLeft\n const distance = targetScrollLeft - startScrollLeft\n const startTime = performance.now()\n\n const animate = (currentTime: number) => {\n const elapsed = currentTime - startTime\n const progress = Math.min(elapsed / duration, 1)\n\n let easedProgress = progress\n if (easing === 'ease-out') {\n easedProgress = 1 - (1 - progress) ** 2\n } else if (easing === 'ease-in-out') {\n easedProgress =\n progress < 0.5\n ? 2 * progress * progress\n : 1 - (-2 * progress + 2) ** 2 / 2\n } else if (easing.startsWith('cubic-bezier')) {\n // For the bounce effect, we'll use a simplified approximation\n easedProgress = progress * progress * (3 - 2 * progress)\n if (easing.includes('-0.55')) {\n // Bounce effect approximation\n easedProgress =\n progress < 0.5\n ? 4 * progress * progress * progress\n : 1 - (-2 * progress + 2) ** 3 / 2\n // Add overshoot for bounce\n if (progress > 0.7 && progress < 1) {\n easedProgress +=\n Math.sin((progress - 0.7) * Math.PI * 10) * 0.1 * (1 - progress)\n }\n }\n }\n\n el.scrollLeft = startScrollLeft + distance * easedProgress\n\n if (progress < 1) {\n rafIdRef.current = requestAnimationFrame(animate)\n } else {\n rafIdRef.current = null\n finish()\n }\n }\n\n rafIdRef.current = requestAnimationFrame(animate)\n },\n [],\n )\n\n const closeRow = useCallback(\n (animated?: boolean | AnimationPreset | AnimationConfig) => {\n const el = containerRef.current\n if (!el) return\n\n const m = getMaxScroll(el)\n const closed = getScrollClosed(getWL(), getWR(), m, mode)\n const animConfig = resolveAnimationConfig(\n animated,\n animationPreset,\n animationConfig,\n )\n\n scrollToPosition(closed, animConfig)\n\n // Update position after animation or immediately if no animation\n const delay = animConfig.duration > 0 ? animConfig.duration : 0\n if (settleTimerRef.current !== null) {\n clearTimeout(settleTimerRef.current)\n }\n settleTimerRef.current = setTimeout(() => {\n emitReveal(readPosition())\n settleTimerRef.current = null\n }, delay)\n },\n [\n animationConfig,\n animationPreset,\n emitReveal,\n getWL,\n getWR,\n mode,\n readPosition,\n scrollToPosition,\n ],\n )\n\n const revealRow = useCallback(\n (\n position: RevealPosition,\n animated?: boolean | AnimationPreset | AnimationConfig,\n ) => {\n const el = containerRef.current\n if (!el) return\n const max = getMaxScroll(el)\n const wL = getWL()\n const wR = getWR()\n\n let targetScroll: number\n if (position === REVEAL_POSITION.center) {\n targetScroll = getScrollClosed(wL, wR, max, mode)\n } else if (\n position === REVEAL_POSITION.left &&\n (mode === REVEAL_MODE.left || mode === REVEAL_MODE.both)\n ) {\n targetScroll = 0\n } else if (\n position === REVEAL_POSITION.right &&\n (mode === REVEAL_MODE.right || mode === REVEAL_MODE.both)\n ) {\n targetScroll = max\n } else {\n return\n }\n\n const animConfig = resolveAnimationConfig(\n animated,\n animationPreset,\n animationConfig,\n )\n scrollToPosition(targetScroll, animConfig)\n\n // Update position after animation or immediately if no animation\n const delay = animConfig.duration > 0 ? animConfig.duration : 0\n if (settleTimerRef.current !== null) {\n clearTimeout(settleTimerRef.current)\n }\n settleTimerRef.current = setTimeout(() => {\n emitReveal(getRevealFromScroll(targetScroll, max, wL, wR, mode))\n settleTimerRef.current = null\n }, delay)\n },\n [\n animationConfig,\n animationPreset,\n emitReveal,\n getWL,\n getWR,\n mode,\n scrollToPosition,\n ],\n )\n\n useImperativeHandle(\n forwardedRef,\n () => ({ close: closeRow, reveal: revealRow }),\n [closeRow, revealRow],\n )\n\n // Keyboard support: tabbing into an off-screen action column snaps it\n // cleanly into view (instead of the browser's un-snapped scroll-into-view),\n // and a focus-initiated reveal closes again once focus leaves the row.\n // Swipe-opened rows are untouched by focus loss.\n const handleRootFocus = useCallback(\n (e: FocusEvent<HTMLElement>) => {\n const t = e.target as Node | null\n if (!t) return\n if (leftRef.current?.contains(t)) {\n focusRevealedRef.current = true\n revealRow(REVEAL_POSITION.left)\n } else if (rightRef.current?.contains(t)) {\n focusRevealedRef.current = true\n revealRow(REVEAL_POSITION.right)\n }\n },\n [revealRow],\n )\n\n const handleRootBlur = useCallback(\n (e: FocusEvent<HTMLElement>) => {\n if (!focusRevealedRef.current) return\n const next = e.relatedTarget as Node | null\n if (next && containerRef.current?.contains(next)) return\n focusRevealedRef.current = false\n closeRow()\n },\n [closeRow],\n )\n\n useLayoutEffect(() => {\n if (mode === REVEAL_MODE.right) {\n return\n }\n const el = containerRef.current\n if (!el) return\n if (!hasAppliedInitialScroll.current) {\n el.scrollLeft = getWL()\n hasAppliedInitialScroll.current = true\n }\n }, [mode, getWL])\n\n useEffect(() => {\n if (disabled && resetWhenDisabled) {\n hasAppliedInitialScroll.current = true\n scrollToClosed()\n emitReveal(readPosition())\n }\n }, [disabled, emitReveal, readPosition, resetWhenDisabled, scrollToClosed])\n\n useEffect(() => {\n if (isActive) {\n hasAppliedInitialScroll.current = true\n scrollToClosed()\n emitReveal(readPosition())\n }\n }, [emitReveal, isActive, readPosition, scrollToClosed])\n\n useEffect(\n () => () => {\n if (debounceTimer.current) {\n clearTimeout(debounceTimer.current)\n }\n if (rafIdRef.current !== null) {\n cancelAnimationFrame(rafIdRef.current)\n }\n if (settleTimerRef.current !== null) {\n clearTimeout(settleTimerRef.current)\n }\n if (finalizeTimerRef.current !== null) {\n clearTimeout(finalizeTimerRef.current)\n }\n },\n [],\n )\n\n const handleScroll = useCallback(\n (e: UIEvent<HTMLElement>) => {\n onScrollProp?.(e)\n const el = containerRef.current\n if (!el) return\n const m = getMaxScroll(el)\n const wL = getWL()\n const wR = getWR()\n const pos = getRevealFromScroll(el.scrollLeft, m, wL, wR, mode)\n const closed = getScrollClosed(wL, wR, m, mode)\n if (Math.abs(el.scrollLeft - closed) > restEpsilon) {\n swipedRef.current = true\n }\n if (debounceTimer.current) {\n clearTimeout(debounceTimer.current)\n }\n debounceTimer.current = setTimeout(() => {\n debounceTimer.current = null\n emitReveal(pos)\n }, SCROLL_REVEAL_DEBOUNCE_MS)\n },\n [emitReveal, getWL, getWR, mode, onScrollProp],\n )\n\n const onClickCapture = useCallback((e: MouseEvent) => {\n const t = e.target as Node | null\n if (t) {\n if (leftRef.current?.contains(t) || rightRef.current?.contains(t)) {\n return\n }\n }\n if (swipedRef.current) {\n e.preventDefault()\n e.stopPropagation()\n swipedRef.current = false\n }\n }, [])\n\n // `100%` for the main track (not `1fr`) so total row width > viewport: otherwise both\n // columns can shrink to fit with no overflow and the action stays visible.\n // Without an explicit width the column is content-sized via a `max-content`\n // track — `minmax(88px, max-content)` would never grow, because the `100%`\n // main track leaves no free space for minmax growth. The 88px floor for\n // stretchy content lives on the column element's `minWidth` instead, which\n // floors its sizing contribution to the track.\n const trackL = wLIn != null ? `${wLIn}px` : 'max-content'\n const trackR = wRIn != null ? `${wRIn}px` : 'max-content'\n const gridTemplateColumns =\n mode === REVEAL_MODE.right\n ? `100% ${trackR}`\n : mode === REVEAL_MODE.left\n ? `${trackL} 100%`\n : `${trackL} 100% ${trackR}`\n\n const handleContent = showHandle ? (\n handleOverride !== undefined ? (\n handleOverride\n ) : (\n <>\n <span\n className=\"sr-only\"\n style={{\n position: 'absolute',\n width: 1,\n height: 1,\n padding: 0,\n margin: -1,\n overflow: 'hidden',\n clip: 'rect(0,0,0,0)',\n border: 0,\n }}\n >\n {handleAriaLabel}\n </span>\n <span className={classNames.handleIcon} aria-hidden>\n <DefaultHandleIcon />\n </span>\n </>\n )\n ) : null\n\n const handleStrip = showHandle ? (\n <div\n role=\"presentation\"\n className={classNames.handleContainer}\n data-reveal-row-handle\n style={{\n flexShrink: 0,\n alignSelf: 'stretch',\n display: 'flex',\n alignItems: 'center',\n }}\n title={handleOverride === undefined ? handleTitle : undefined}\n >\n {handleContent}\n </div>\n ) : null\n\n const mainColumn = (\n <div\n className={classNames.main}\n data-reveal-row-main\n style={{\n ...snapStart,\n minWidth: 0,\n width: '100%',\n maxWidth: '100%',\n boxSizing: 'border-box',\n }}\n >\n <div\n className={classNames.mainInner}\n style={{\n display: 'flex',\n minWidth: 0,\n width: '100%',\n alignItems: 'flex-start',\n }}\n >\n {handlePosition === REVEAL_HANDLE_POSITION.start && handleStrip}\n <div style={{ minWidth: 0, flex: 1, flexBasis: 0 }}>{children}</div>\n {handlePosition === REVEAL_HANDLE_POSITION.end && handleStrip}\n </div>\n </div>\n )\n\n return (\n <Element\n // biome-ignore lint/suspicious/noExplicitAny: Required for polymorphic ref compatibility\n ref={containerRef as any}\n data-reveal-mode={mode}\n data-reveal-position={settledPosition}\n className={cx(classNames.root, className)}\n onScroll={handleScroll}\n onClickCapture={onClickCapture}\n onFocus={handleRootFocus}\n onBlur={handleRootBlur}\n style={{\n ...(disabled ? rootScrollStyleDisabled : rootScrollStyle),\n ...style,\n gridTemplateColumns,\n }}\n >\n {hasL ? (\n <div\n ref={leftRef}\n className={classNames.left}\n data-reveal-row-left\n style={{\n ...snapStart,\n ...(wLIn != null\n ? { minWidth: 0, width: wLIn }\n : { minWidth: 'var(--reveal-row-action-min-width, 88px)' }),\n }}\n >\n {left}\n </div>\n ) : null}\n {mainColumn}\n {hasR ? (\n <div\n ref={rightRef}\n className={classNames.right}\n data-reveal-row-right\n style={{\n ...snapEnd,\n ...(wRIn != null\n ? { minWidth: 0, width: wRIn }\n : { minWidth: 'var(--reveal-row-action-min-width, 88px)' }),\n }}\n >\n {right}\n </div>\n ) : null}\n </Element>\n )\n}\n\nexport const RevealRow = forwardRef<RevealRowHandle, RevealRowProps>(\n function RevealRow(props, ref) {\n return <RevealRowInner {...props} forwardedRef={ref} />\n },\n)\n","/** Minimal 6-dot grip, no icon library dependency. */\nexport function DefaultHandleIcon() {\n return (\n <svg\n width={16}\n height={16}\n viewBox=\"0 0 16 16\"\n fill=\"currentColor\"\n aria-hidden\n >\n <title>Drag handle</title>\n <circle cx=\"6\" cy=\"4\" r=\"1.2\" />\n <circle cx=\"10\" cy=\"4\" r=\"1.2\" />\n <circle cx=\"6\" cy=\"8\" r=\"1.2\" />\n <circle cx=\"10\" cy=\"8\" r=\"1.2\" />\n <circle cx=\"6\" cy=\"12\" r=\"1.2\" />\n <circle cx=\"10\" cy=\"12\" r=\"1.2\" />\n </svg>\n )\n}\n"],"mappings":"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","names":["jsx","jsxs","RevealRow"]}