@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.js CHANGED
@@ -25,6 +25,7 @@ __export(index_exports, {
25
25
  REVEAL_HANDLE_POSITION: () => REVEAL_HANDLE_POSITION,
26
26
  REVEAL_MODE: () => REVEAL_MODE,
27
27
  REVEAL_POSITION: () => REVEAL_POSITION,
28
+ REVEAL_ROW_ELEMENTS: () => REVEAL_ROW_ELEMENTS,
28
29
  RevealRow: () => RevealRow,
29
30
  getRevealFromScroll: () => getRevealFromScroll,
30
31
  getScrollClosed: () => getScrollClosed
@@ -46,6 +47,17 @@ var REVEAL_HANDLE_POSITION = {
46
47
  start: "start",
47
48
  end: "end"
48
49
  };
50
+ var REVEAL_ROW_ELEMENTS = {
51
+ div: "div",
52
+ section: "section",
53
+ article: "article",
54
+ main: "main",
55
+ aside: "aside",
56
+ header: "header",
57
+ footer: "footer",
58
+ nav: "nav",
59
+ li: "li"
60
+ };
49
61
  var ANIMATION_PRESET = {
50
62
  none: "none",
51
63
  quick: "quick",
@@ -118,23 +130,46 @@ function resolveMode(left, right, mode) {
118
130
  if (left != null) return REVEAL_MODE.left;
119
131
  return REVEAL_MODE.right;
120
132
  }
133
+ function prefersReducedMotion() {
134
+ return typeof window !== "undefined" && typeof window.matchMedia === "function" && window.matchMedia("(prefers-reduced-motion: reduce)").matches;
135
+ }
121
136
  function resolveAnimationConfig(animated, defaultPreset, customConfig) {
137
+ let config;
138
+ let explicit = false;
122
139
  if (animated === false) {
123
- return ANIMATION_PRESETS[ANIMATION_PRESET.none];
124
- }
125
- if (animated === true || animated === void 0) {
126
- return customConfig || ANIMATION_PRESETS[defaultPreset];
140
+ config = ANIMATION_PRESETS[ANIMATION_PRESET.none];
141
+ } else if (animated === true || animated === void 0) {
142
+ if (customConfig) {
143
+ config = customConfig;
144
+ explicit = true;
145
+ } else {
146
+ config = ANIMATION_PRESETS[defaultPreset];
147
+ }
148
+ } else if (typeof animated === "string") {
149
+ config = ANIMATION_PRESETS[animated];
150
+ } else {
151
+ config = animated;
152
+ explicit = true;
127
153
  }
128
- if (typeof animated === "string") {
129
- return ANIMATION_PRESETS[animated];
154
+ if (!explicit && prefersReducedMotion()) {
155
+ return { ...config, duration: 0 };
130
156
  }
131
- return animated;
157
+ return {
158
+ ...config,
159
+ duration: Math.max(
160
+ 0,
161
+ Number.isFinite(config.duration) ? config.duration : 0
162
+ )
163
+ };
132
164
  }
133
165
  var SCROLL_REVEAL_DEBOUNCE_MS = 64;
134
166
  var restEpsilon = 2;
135
167
  var rootScrollStyle = {
136
168
  display: "grid",
137
169
  overflowX: "auto",
170
+ // `overflow-x: auto` would otherwise force `overflow-y` to compute to
171
+ // `auto` — pin it so rows only ever scroll on one axis.
172
+ overflowY: "hidden",
138
173
  scrollSnapType: "x mandatory",
139
174
  scrollbarWidth: "none",
140
175
  WebkitOverflowScrolling: "touch",
@@ -152,6 +187,7 @@ function RevealRowInner({
152
187
  children,
153
188
  left,
154
189
  right,
190
+ as: Element = "div",
155
191
  mode: modeProp,
156
192
  actionWidthLeft: wLIn,
157
193
  actionWidthRight: wRIn,
@@ -175,24 +211,45 @@ function RevealRowInner({
175
211
  const mode = resolveMode(left, right, modeProp);
176
212
  const hasL = mode === REVEAL_MODE.left || mode === REVEAL_MODE.both;
177
213
  const hasR = mode === REVEAL_MODE.right || mode === REVEAL_MODE.both;
178
- const wL = hasL ? wLIn ?? 88 : 0;
179
- const wR = hasR ? wRIn ?? 88 : 0;
180
214
  const handlePosition = handlePositionProp ?? (mode === REVEAL_MODE.left ? REVEAL_HANDLE_POSITION.start : REVEAL_HANDLE_POSITION.end);
181
215
  const containerRef = (0, import_react.useRef)(null);
182
216
  const leftRef = (0, import_react.useRef)(null);
183
217
  const rightRef = (0, import_react.useRef)(null);
184
218
  const lastEmitted = (0, import_react.useRef)(null);
185
219
  const swipedRef = (0, import_react.useRef)(false);
220
+ const focusRevealedRef = (0, import_react.useRef)(false);
221
+ const [settledPosition, setSettledPosition] = (0, import_react.useState)(
222
+ REVEAL_POSITION.center
223
+ );
224
+ const getWL = (0, import_react.useCallback)(
225
+ () => hasL ? wLIn ?? (leftRef.current?.offsetWidth || 88) : 0,
226
+ [hasL, wLIn]
227
+ );
228
+ const getWR = (0, import_react.useCallback)(
229
+ () => hasR ? wRIn ?? (rightRef.current?.offsetWidth || 88) : 0,
230
+ [hasR, wRIn]
231
+ );
186
232
  const debounceTimer = (0, import_react.useRef)(null);
187
233
  const hasAppliedInitialScroll = (0, import_react.useRef)(false);
188
234
  const isAnimatingRef = (0, import_react.useRef)(false);
235
+ const rafIdRef = (0, import_react.useRef)(null);
236
+ const settleTimerRef = (0, import_react.useRef)(null);
237
+ const finalizeTimerRef = (0, import_react.useRef)(null);
238
+ const originalSnapRef = (0, import_react.useRef)("");
189
239
  const readPosition = (0, import_react.useCallback)(() => {
190
240
  const el = containerRef.current;
191
241
  if (!el) return REVEAL_POSITION.center;
192
- return getRevealFromScroll(el.scrollLeft, getMaxScroll(el), wL, wR, mode);
193
- }, [wL, wR, mode]);
242
+ return getRevealFromScroll(
243
+ el.scrollLeft,
244
+ getMaxScroll(el),
245
+ getWL(),
246
+ getWR(),
247
+ mode
248
+ );
249
+ }, [getWL, getWR, mode]);
194
250
  const emitReveal = (0, import_react.useCallback)(
195
251
  (position) => {
252
+ setSettledPosition(position);
196
253
  if (lastEmitted.current === position) return;
197
254
  lastEmitted.current = position;
198
255
  onRevealChange?.(position);
@@ -203,9 +260,9 @@ function RevealRowInner({
203
260
  const el = containerRef.current;
204
261
  if (!el) return;
205
262
  const m = getMaxScroll(el);
206
- const closed = getScrollClosed(wL, wR, m, mode);
263
+ const closed = getScrollClosed(getWL(), getWR(), m, mode);
207
264
  el.scrollLeft = closed;
208
- }, [wL, wR, mode]);
265
+ }, [getWL, getWR, mode]);
209
266
  const scrollToPosition = (0, import_react.useCallback)(
210
267
  (targetScrollLeft, animationOptions) => {
211
268
  const el = containerRef.current;
@@ -215,9 +272,37 @@ function RevealRowInner({
215
272
  el.scrollLeft = targetScrollLeft;
216
273
  return;
217
274
  }
275
+ if (rafIdRef.current !== null) {
276
+ cancelAnimationFrame(rafIdRef.current);
277
+ rafIdRef.current = null;
278
+ }
279
+ if (settleTimerRef.current !== null) {
280
+ clearTimeout(settleTimerRef.current);
281
+ settleTimerRef.current = null;
282
+ }
283
+ if (finalizeTimerRef.current !== null) {
284
+ clearTimeout(finalizeTimerRef.current);
285
+ finalizeTimerRef.current = null;
286
+ }
287
+ if (!isAnimatingRef.current) {
288
+ originalSnapRef.current = el.style.scrollSnapType;
289
+ }
218
290
  isAnimatingRef.current = true;
219
- const originalScrollSnapType = el.style.scrollSnapType;
220
291
  el.style.scrollSnapType = "none";
292
+ const finish = () => {
293
+ el.scrollLeft = targetScrollLeft;
294
+ el.style.scrollSnapType = originalSnapRef.current || "x mandatory";
295
+ isAnimatingRef.current = false;
296
+ if (rafIdRef.current !== null) {
297
+ cancelAnimationFrame(rafIdRef.current);
298
+ rafIdRef.current = null;
299
+ }
300
+ if (finalizeTimerRef.current !== null) {
301
+ clearTimeout(finalizeTimerRef.current);
302
+ finalizeTimerRef.current = null;
303
+ }
304
+ };
305
+ finalizeTimerRef.current = setTimeout(finish, duration + 100);
221
306
  const startScrollLeft = el.scrollLeft;
222
307
  const distance = targetScrollLeft - startScrollLeft;
223
308
  const startTime = performance.now();
@@ -240,79 +325,119 @@ function RevealRowInner({
240
325
  }
241
326
  el.scrollLeft = startScrollLeft + distance * easedProgress;
242
327
  if (progress < 1) {
243
- requestAnimationFrame(animate);
328
+ rafIdRef.current = requestAnimationFrame(animate);
244
329
  } else {
245
- el.scrollLeft = targetScrollLeft;
246
- el.style.scrollSnapType = originalScrollSnapType || "x mandatory";
247
- isAnimatingRef.current = false;
330
+ rafIdRef.current = null;
331
+ finish();
248
332
  }
249
333
  };
250
- requestAnimationFrame(animate);
334
+ rafIdRef.current = requestAnimationFrame(animate);
251
335
  },
252
336
  []
253
337
  );
254
- (0, import_react.useImperativeHandle)(
255
- forwardedRef,
256
- () => ({
257
- close: (animated) => {
258
- const el = containerRef.current;
259
- if (!el) return;
260
- const m = getMaxScroll(el);
261
- const closed = getScrollClosed(wL, wR, m, mode);
262
- const animConfig = resolveAnimationConfig(
263
- animated,
264
- animationPreset,
265
- animationConfig
266
- );
267
- scrollToPosition(closed, animConfig);
268
- const delay = animConfig.duration > 0 ? animConfig.duration : 0;
269
- setTimeout(() => {
270
- const p = readPosition();
271
- if (lastEmitted.current !== p) {
272
- lastEmitted.current = p;
273
- onRevealChange?.(p);
274
- }
275
- }, delay);
276
- },
277
- reveal: (position, animated) => {
278
- const el = containerRef.current;
279
- if (!el) return;
280
- const max = getMaxScroll(el);
281
- let targetScroll;
282
- if (position === REVEAL_POSITION.center) {
283
- targetScroll = getScrollClosed(wL, wR, max, mode);
284
- } else if (position === REVEAL_POSITION.left && (mode === REVEAL_MODE.left || mode === REVEAL_MODE.both)) {
285
- targetScroll = 0;
286
- } else if (position === REVEAL_POSITION.right && (mode === REVEAL_MODE.right || mode === REVEAL_MODE.both)) {
287
- targetScroll = max;
288
- } else {
289
- return;
290
- }
291
- const animConfig = resolveAnimationConfig(
292
- animated,
293
- animationPreset,
294
- animationConfig
295
- );
296
- scrollToPosition(targetScroll, animConfig);
297
- const delay = animConfig.duration > 0 ? animConfig.duration : 0;
298
- setTimeout(() => {
299
- const p = getRevealFromScroll(targetScroll, max, wL, wR, mode);
300
- lastEmitted.current = p;
301
- onRevealChange?.(p);
302
- }, delay);
338
+ const closeRow = (0, import_react.useCallback)(
339
+ (animated) => {
340
+ const el = containerRef.current;
341
+ if (!el) return;
342
+ const m = getMaxScroll(el);
343
+ const closed = getScrollClosed(getWL(), getWR(), m, mode);
344
+ const animConfig = resolveAnimationConfig(
345
+ animated,
346
+ animationPreset,
347
+ animationConfig
348
+ );
349
+ scrollToPosition(closed, animConfig);
350
+ const delay = animConfig.duration > 0 ? animConfig.duration : 0;
351
+ if (settleTimerRef.current !== null) {
352
+ clearTimeout(settleTimerRef.current);
303
353
  }
304
- }),
354
+ settleTimerRef.current = setTimeout(() => {
355
+ emitReveal(readPosition());
356
+ settleTimerRef.current = null;
357
+ }, delay);
358
+ },
305
359
  [
360
+ animationConfig,
361
+ animationPreset,
362
+ emitReveal,
363
+ getWL,
364
+ getWR,
306
365
  mode,
307
- onRevealChange,
308
366
  readPosition,
309
- scrollToPosition,
310
- wL,
311
- wR,
367
+ scrollToPosition
368
+ ]
369
+ );
370
+ const revealRow = (0, import_react.useCallback)(
371
+ (position, animated) => {
372
+ const el = containerRef.current;
373
+ if (!el) return;
374
+ const max = getMaxScroll(el);
375
+ const wL = getWL();
376
+ const wR = getWR();
377
+ let targetScroll;
378
+ if (position === REVEAL_POSITION.center) {
379
+ targetScroll = getScrollClosed(wL, wR, max, mode);
380
+ } else if (position === REVEAL_POSITION.left && (mode === REVEAL_MODE.left || mode === REVEAL_MODE.both)) {
381
+ targetScroll = 0;
382
+ } else if (position === REVEAL_POSITION.right && (mode === REVEAL_MODE.right || mode === REVEAL_MODE.both)) {
383
+ targetScroll = max;
384
+ } else {
385
+ return;
386
+ }
387
+ const animConfig = resolveAnimationConfig(
388
+ animated,
389
+ animationPreset,
390
+ animationConfig
391
+ );
392
+ scrollToPosition(targetScroll, animConfig);
393
+ const delay = animConfig.duration > 0 ? animConfig.duration : 0;
394
+ if (settleTimerRef.current !== null) {
395
+ clearTimeout(settleTimerRef.current);
396
+ }
397
+ settleTimerRef.current = setTimeout(() => {
398
+ emitReveal(getRevealFromScroll(targetScroll, max, wL, wR, mode));
399
+ settleTimerRef.current = null;
400
+ }, delay);
401
+ },
402
+ [
403
+ animationConfig,
312
404
  animationPreset,
313
- animationConfig
405
+ emitReveal,
406
+ getWL,
407
+ getWR,
408
+ mode,
409
+ scrollToPosition
314
410
  ]
315
411
  );
412
+ (0, import_react.useImperativeHandle)(
413
+ forwardedRef,
414
+ () => ({ close: closeRow, reveal: revealRow }),
415
+ [closeRow, revealRow]
416
+ );
417
+ const handleRootFocus = (0, import_react.useCallback)(
418
+ (e) => {
419
+ const t = e.target;
420
+ if (!t) return;
421
+ if (leftRef.current?.contains(t)) {
422
+ focusRevealedRef.current = true;
423
+ revealRow(REVEAL_POSITION.left);
424
+ } else if (rightRef.current?.contains(t)) {
425
+ focusRevealedRef.current = true;
426
+ revealRow(REVEAL_POSITION.right);
427
+ }
428
+ },
429
+ [revealRow]
430
+ );
431
+ const handleRootBlur = (0, import_react.useCallback)(
432
+ (e) => {
433
+ if (!focusRevealedRef.current) return;
434
+ const next = e.relatedTarget;
435
+ if (next && containerRef.current?.contains(next)) return;
436
+ focusRevealedRef.current = false;
437
+ closeRow();
438
+ },
439
+ [closeRow]
440
+ );
316
441
  (0, import_react.useLayoutEffect)(() => {
317
442
  if (mode === REVEAL_MODE.right) {
318
443
  return;
@@ -320,10 +445,10 @@ function RevealRowInner({
320
445
  const el = containerRef.current;
321
446
  if (!el) return;
322
447
  if (!hasAppliedInitialScroll.current) {
323
- el.scrollLeft = wL;
448
+ el.scrollLeft = getWL();
324
449
  hasAppliedInitialScroll.current = true;
325
450
  }
326
- }, [mode, wL]);
451
+ }, [mode, getWL]);
327
452
  (0, import_react.useEffect)(() => {
328
453
  if (disabled && resetWhenDisabled) {
329
454
  hasAppliedInitialScroll.current = true;
@@ -343,6 +468,15 @@ function RevealRowInner({
343
468
  if (debounceTimer.current) {
344
469
  clearTimeout(debounceTimer.current);
345
470
  }
471
+ if (rafIdRef.current !== null) {
472
+ cancelAnimationFrame(rafIdRef.current);
473
+ }
474
+ if (settleTimerRef.current !== null) {
475
+ clearTimeout(settleTimerRef.current);
476
+ }
477
+ if (finalizeTimerRef.current !== null) {
478
+ clearTimeout(finalizeTimerRef.current);
479
+ }
346
480
  },
347
481
  []
348
482
  );
@@ -352,6 +486,8 @@ function RevealRowInner({
352
486
  const el = containerRef.current;
353
487
  if (!el) return;
354
488
  const m = getMaxScroll(el);
489
+ const wL = getWL();
490
+ const wR = getWR();
355
491
  const pos = getRevealFromScroll(el.scrollLeft, m, wL, wR, mode);
356
492
  const closed = getScrollClosed(wL, wR, m, mode);
357
493
  if (Math.abs(el.scrollLeft - closed) > restEpsilon) {
@@ -365,7 +501,7 @@ function RevealRowInner({
365
501
  emitReveal(pos);
366
502
  }, SCROLL_REVEAL_DEBOUNCE_MS);
367
503
  },
368
- [emitReveal, mode, onScrollProp, wL, wR]
504
+ [emitReveal, getWL, getWR, mode, onScrollProp]
369
505
  );
370
506
  const onClickCapture = (0, import_react.useCallback)((e) => {
371
507
  const t = e.target;
@@ -380,7 +516,9 @@ function RevealRowInner({
380
516
  swipedRef.current = false;
381
517
  }
382
518
  }, []);
383
- const gridTemplateColumns = mode === REVEAL_MODE.right ? `100% ${wR}px` : mode === REVEAL_MODE.left ? `${wL}px 100%` : `${wL}px 100% ${wR}px`;
519
+ const trackL = wLIn != null ? `${wLIn}px` : "max-content";
520
+ const trackR = wRIn != null ? `${wRIn}px` : "max-content";
521
+ const gridTemplateColumns = mode === REVEAL_MODE.right ? `100% ${trackR}` : mode === REVEAL_MODE.left ? `${trackL} 100%` : `${trackL} 100% ${trackR}`;
384
522
  const handleContent = showHandle ? handleOverride !== void 0 ? handleOverride : /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_jsx_runtime2.Fragment, { children: [
385
523
  /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
386
524
  "span",
@@ -449,13 +587,16 @@ function RevealRowInner({
449
587
  }
450
588
  );
451
589
  return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
452
- "div",
590
+ Element,
453
591
  {
454
592
  ref: containerRef,
455
593
  "data-reveal-mode": mode,
594
+ "data-reveal-position": settledPosition,
456
595
  className: cx(classNames.root, className),
457
596
  onScroll: handleScroll,
458
597
  onClickCapture,
598
+ onFocus: handleRootFocus,
599
+ onBlur: handleRootBlur,
459
600
  style: {
460
601
  ...disabled ? rootScrollStyleDisabled : rootScrollStyle,
461
602
  ...style,
@@ -468,7 +609,10 @@ function RevealRowInner({
468
609
  ref: leftRef,
469
610
  className: classNames.left,
470
611
  "data-reveal-row-left": true,
471
- style: { ...snapStart, minWidth: 0, width: wL },
612
+ style: {
613
+ ...snapStart,
614
+ ...wLIn != null ? { minWidth: 0, width: wLIn } : { minWidth: "var(--reveal-row-action-min-width, 88px)" }
615
+ },
472
616
  children: left
473
617
  }
474
618
  ) : null,
@@ -479,7 +623,10 @@ function RevealRowInner({
479
623
  ref: rightRef,
480
624
  className: classNames.right,
481
625
  "data-reveal-row-right": true,
482
- style: { ...snapEnd, minWidth: 0, width: wR },
626
+ style: {
627
+ ...snapEnd,
628
+ ...wRIn != null ? { minWidth: 0, width: wRIn } : { minWidth: "var(--reveal-row-action-min-width, 88px)" }
629
+ },
483
630
  children: right
484
631
  }
485
632
  ) : null
@@ -499,6 +646,7 @@ var RevealRow = (0, import_react.forwardRef)(
499
646
  REVEAL_HANDLE_POSITION,
500
647
  REVEAL_MODE,
501
648
  REVEAL_POSITION,
649
+ REVEAL_ROW_ELEMENTS,
502
650
  RevealRow,
503
651
  getRevealFromScroll,
504
652
  getScrollClosed
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/types.ts","../src/getRevealFromScroll.ts","../src/RevealRow.tsx","../src/DefaultHandleIcon.tsx"],"sourcesContent":["export { getRevealFromScroll, getScrollClosed } from './getRevealFromScroll'\nexport { RevealRow } from './RevealRow'\nexport type {\n AnimationConfig,\n AnimationPreset,\n RevealHandlePosition,\n RevealMode,\n RevealPosition,\n RevealRowClassNames,\n RevealRowHandle,\n RevealRowProps,\n} from './types'\nexport {\n ANIMATION_PRESET,\n ANIMATION_PRESETS,\n REVEAL_HANDLE_POSITION,\n REVEAL_MODE,\n REVEAL_POSITION,\n} from './types'\n","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":["import_jsx_runtime","RevealRow"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/types.ts","../src/getRevealFromScroll.ts","../src/RevealRow.tsx","../src/DefaultHandleIcon.tsx"],"sourcesContent":["export { getRevealFromScroll, getScrollClosed } from './getRevealFromScroll'\nexport { RevealRow } from './RevealRow'\nexport type {\n AnimationConfig,\n AnimationPreset,\n RevealHandlePosition,\n RevealMode,\n RevealPosition,\n RevealRowClassNames,\n RevealRowElement,\n RevealRowHandle,\n RevealRowProps,\n} from './types'\nexport {\n ANIMATION_PRESET,\n ANIMATION_PRESETS,\n REVEAL_HANDLE_POSITION,\n REVEAL_MODE,\n REVEAL_POSITION,\n REVEAL_ROW_ELEMENTS,\n} from './types'\n","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":["import_jsx_runtime","RevealRow"]}