@present-day/reveal-row 0.1.2 → 0.1.4
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/README.md +3 -0
- package/dist/index.d.mts +23 -3
- package/dist/index.d.ts +23 -3
- package/dist/index.js +126 -16
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +124 -16
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -2,6 +2,9 @@
|
|
|
2
2
|
|
|
3
3
|
Horizontally scrollable row that reveals one or two action columns — **right**, **left**, or **both** sides. Three snap positions: left · center · right. Styling is entirely via `classNames` props (no bundled CSS). Scroll physics use inline `style` on the scroll track so the component works with zero external CSS.
|
|
4
4
|
|
|
5
|
+
<img width="295" height="640" alt="Simulator Screen Recording - iPhone 15 - 2026-04-25 at 22 26 41" src="https://github.com/user-attachments/assets/932021d4-5224-479f-9df9-c7045bf12afb" style="float:right" />
|
|
6
|
+
|
|
7
|
+
|
|
5
8
|
## Install
|
|
6
9
|
|
|
7
10
|
```bash
|
package/dist/index.d.mts
CHANGED
|
@@ -18,6 +18,17 @@ declare const REVEAL_HANDLE_POSITION: {
|
|
|
18
18
|
readonly end: "end";
|
|
19
19
|
};
|
|
20
20
|
type RevealHandlePosition = (typeof REVEAL_HANDLE_POSITION)[keyof typeof REVEAL_HANDLE_POSITION];
|
|
21
|
+
declare const ANIMATION_PRESET: {
|
|
22
|
+
readonly none: "none";
|
|
23
|
+
readonly quick: "quick";
|
|
24
|
+
readonly smooth: "smooth";
|
|
25
|
+
};
|
|
26
|
+
type AnimationPreset = (typeof ANIMATION_PRESET)[keyof typeof ANIMATION_PRESET];
|
|
27
|
+
type AnimationConfig = {
|
|
28
|
+
duration: number;
|
|
29
|
+
easing: string;
|
|
30
|
+
};
|
|
31
|
+
declare const ANIMATION_PRESETS: Record<AnimationPreset, AnimationConfig>;
|
|
21
32
|
type RevealRowClassNames = {
|
|
22
33
|
root?: string;
|
|
23
34
|
main?: string;
|
|
@@ -28,8 +39,8 @@ type RevealRowClassNames = {
|
|
|
28
39
|
handleIcon?: string;
|
|
29
40
|
};
|
|
30
41
|
type RevealRowHandle = {
|
|
31
|
-
close: () => void;
|
|
32
|
-
reveal: (position: RevealPosition) => void;
|
|
42
|
+
close: (animated?: boolean | AnimationPreset | AnimationConfig) => void;
|
|
43
|
+
reveal: (position: RevealPosition, animated?: boolean | AnimationPreset | AnimationConfig) => void;
|
|
33
44
|
};
|
|
34
45
|
type RevealRowProps = {
|
|
35
46
|
/** Primary row content (e.g. title, subtitle). */
|
|
@@ -73,6 +84,15 @@ type RevealRowProps = {
|
|
|
73
84
|
isActive?: boolean;
|
|
74
85
|
className?: string;
|
|
75
86
|
style?: CSSProperties;
|
|
87
|
+
/**
|
|
88
|
+
* Default animation preset for close/reveal animations when action buttons are clicked.
|
|
89
|
+
* @default 'quick'
|
|
90
|
+
*/
|
|
91
|
+
animationPreset?: AnimationPreset;
|
|
92
|
+
/**
|
|
93
|
+
* Custom animation configuration overriding the preset.
|
|
94
|
+
*/
|
|
95
|
+
animationConfig?: AnimationConfig;
|
|
76
96
|
};
|
|
77
97
|
|
|
78
98
|
/**
|
|
@@ -86,4 +106,4 @@ declare function getScrollClosed(wL: number, _wR: number, _maxScroll: number, mo
|
|
|
86
106
|
|
|
87
107
|
declare const RevealRow: react.ForwardRefExoticComponent<RevealRowProps & react.RefAttributes<RevealRowHandle>>;
|
|
88
108
|
|
|
89
|
-
export { REVEAL_HANDLE_POSITION, REVEAL_MODE, REVEAL_POSITION, type RevealHandlePosition, type RevealMode, type RevealPosition, RevealRow, type RevealRowClassNames, type RevealRowHandle, type RevealRowProps, getRevealFromScroll, getScrollClosed };
|
|
109
|
+
export { ANIMATION_PRESET, ANIMATION_PRESETS, type AnimationConfig, type AnimationPreset, REVEAL_HANDLE_POSITION, REVEAL_MODE, REVEAL_POSITION, type RevealHandlePosition, type RevealMode, type RevealPosition, RevealRow, type RevealRowClassNames, type RevealRowHandle, type RevealRowProps, getRevealFromScroll, getScrollClosed };
|
package/dist/index.d.ts
CHANGED
|
@@ -18,6 +18,17 @@ declare const REVEAL_HANDLE_POSITION: {
|
|
|
18
18
|
readonly end: "end";
|
|
19
19
|
};
|
|
20
20
|
type RevealHandlePosition = (typeof REVEAL_HANDLE_POSITION)[keyof typeof REVEAL_HANDLE_POSITION];
|
|
21
|
+
declare const ANIMATION_PRESET: {
|
|
22
|
+
readonly none: "none";
|
|
23
|
+
readonly quick: "quick";
|
|
24
|
+
readonly smooth: "smooth";
|
|
25
|
+
};
|
|
26
|
+
type AnimationPreset = (typeof ANIMATION_PRESET)[keyof typeof ANIMATION_PRESET];
|
|
27
|
+
type AnimationConfig = {
|
|
28
|
+
duration: number;
|
|
29
|
+
easing: string;
|
|
30
|
+
};
|
|
31
|
+
declare const ANIMATION_PRESETS: Record<AnimationPreset, AnimationConfig>;
|
|
21
32
|
type RevealRowClassNames = {
|
|
22
33
|
root?: string;
|
|
23
34
|
main?: string;
|
|
@@ -28,8 +39,8 @@ type RevealRowClassNames = {
|
|
|
28
39
|
handleIcon?: string;
|
|
29
40
|
};
|
|
30
41
|
type RevealRowHandle = {
|
|
31
|
-
close: () => void;
|
|
32
|
-
reveal: (position: RevealPosition) => void;
|
|
42
|
+
close: (animated?: boolean | AnimationPreset | AnimationConfig) => void;
|
|
43
|
+
reveal: (position: RevealPosition, animated?: boolean | AnimationPreset | AnimationConfig) => void;
|
|
33
44
|
};
|
|
34
45
|
type RevealRowProps = {
|
|
35
46
|
/** Primary row content (e.g. title, subtitle). */
|
|
@@ -73,6 +84,15 @@ type RevealRowProps = {
|
|
|
73
84
|
isActive?: boolean;
|
|
74
85
|
className?: string;
|
|
75
86
|
style?: CSSProperties;
|
|
87
|
+
/**
|
|
88
|
+
* Default animation preset for close/reveal animations when action buttons are clicked.
|
|
89
|
+
* @default 'quick'
|
|
90
|
+
*/
|
|
91
|
+
animationPreset?: AnimationPreset;
|
|
92
|
+
/**
|
|
93
|
+
* Custom animation configuration overriding the preset.
|
|
94
|
+
*/
|
|
95
|
+
animationConfig?: AnimationConfig;
|
|
76
96
|
};
|
|
77
97
|
|
|
78
98
|
/**
|
|
@@ -86,4 +106,4 @@ declare function getScrollClosed(wL: number, _wR: number, _maxScroll: number, mo
|
|
|
86
106
|
|
|
87
107
|
declare const RevealRow: react.ForwardRefExoticComponent<RevealRowProps & react.RefAttributes<RevealRowHandle>>;
|
|
88
108
|
|
|
89
|
-
export { REVEAL_HANDLE_POSITION, REVEAL_MODE, REVEAL_POSITION, type RevealHandlePosition, type RevealMode, type RevealPosition, RevealRow, type RevealRowClassNames, type RevealRowHandle, type RevealRowProps, getRevealFromScroll, getScrollClosed };
|
|
109
|
+
export { ANIMATION_PRESET, ANIMATION_PRESETS, type AnimationConfig, type AnimationPreset, REVEAL_HANDLE_POSITION, REVEAL_MODE, REVEAL_POSITION, type RevealHandlePosition, type RevealMode, type RevealPosition, RevealRow, type RevealRowClassNames, type RevealRowHandle, type RevealRowProps, getRevealFromScroll, getScrollClosed };
|
package/dist/index.js
CHANGED
|
@@ -20,6 +20,8 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
20
20
|
// src/index.ts
|
|
21
21
|
var index_exports = {};
|
|
22
22
|
__export(index_exports, {
|
|
23
|
+
ANIMATION_PRESET: () => ANIMATION_PRESET,
|
|
24
|
+
ANIMATION_PRESETS: () => ANIMATION_PRESETS,
|
|
23
25
|
REVEAL_HANDLE_POSITION: () => REVEAL_HANDLE_POSITION,
|
|
24
26
|
REVEAL_MODE: () => REVEAL_MODE,
|
|
25
27
|
REVEAL_POSITION: () => REVEAL_POSITION,
|
|
@@ -44,6 +46,16 @@ var REVEAL_HANDLE_POSITION = {
|
|
|
44
46
|
start: "start",
|
|
45
47
|
end: "end"
|
|
46
48
|
};
|
|
49
|
+
var ANIMATION_PRESET = {
|
|
50
|
+
none: "none",
|
|
51
|
+
quick: "quick",
|
|
52
|
+
smooth: "smooth"
|
|
53
|
+
};
|
|
54
|
+
var ANIMATION_PRESETS = {
|
|
55
|
+
[ANIMATION_PRESET.none]: { duration: 0, easing: "linear" },
|
|
56
|
+
[ANIMATION_PRESET.quick]: { duration: 200, easing: "ease-out" },
|
|
57
|
+
[ANIMATION_PRESET.smooth]: { duration: 400, easing: "ease-in-out" }
|
|
58
|
+
};
|
|
47
59
|
|
|
48
60
|
// src/getRevealFromScroll.ts
|
|
49
61
|
function getRevealFromScroll(scrollLeft, maxScroll, wL, wR, mode) {
|
|
@@ -106,6 +118,18 @@ function resolveMode(left, right, mode) {
|
|
|
106
118
|
if (left != null) return REVEAL_MODE.left;
|
|
107
119
|
return REVEAL_MODE.right;
|
|
108
120
|
}
|
|
121
|
+
function resolveAnimationConfig(animated, defaultPreset, customConfig) {
|
|
122
|
+
if (animated === false) {
|
|
123
|
+
return ANIMATION_PRESETS[ANIMATION_PRESET.none];
|
|
124
|
+
}
|
|
125
|
+
if (animated === true || animated === void 0) {
|
|
126
|
+
return customConfig || ANIMATION_PRESETS[defaultPreset];
|
|
127
|
+
}
|
|
128
|
+
if (typeof animated === "string") {
|
|
129
|
+
return ANIMATION_PRESETS[animated];
|
|
130
|
+
}
|
|
131
|
+
return animated;
|
|
132
|
+
}
|
|
109
133
|
var SCROLL_REVEAL_DEBOUNCE_MS = 64;
|
|
110
134
|
var restEpsilon = 2;
|
|
111
135
|
var rootScrollStyle = {
|
|
@@ -117,6 +141,11 @@ var rootScrollStyle = {
|
|
|
117
141
|
overscrollBehaviorX: "contain",
|
|
118
142
|
touchAction: "pan-x pan-y"
|
|
119
143
|
};
|
|
144
|
+
var rootScrollStyleDisabled = {
|
|
145
|
+
...rootScrollStyle,
|
|
146
|
+
overflowX: "hidden",
|
|
147
|
+
touchAction: "pan-y"
|
|
148
|
+
};
|
|
120
149
|
var snapStart = { scrollSnapAlign: "start" };
|
|
121
150
|
var snapEnd = { scrollSnapAlign: "end" };
|
|
122
151
|
function RevealRowInner({
|
|
@@ -139,6 +168,8 @@ function RevealRowInner({
|
|
|
139
168
|
isActive = false,
|
|
140
169
|
className,
|
|
141
170
|
style,
|
|
171
|
+
animationPreset = ANIMATION_PRESET.quick,
|
|
172
|
+
animationConfig,
|
|
142
173
|
forwardedRef
|
|
143
174
|
}) {
|
|
144
175
|
const mode = resolveMode(left, right, modeProp);
|
|
@@ -154,6 +185,7 @@ function RevealRowInner({
|
|
|
154
185
|
const swipedRef = (0, import_react.useRef)(false);
|
|
155
186
|
const debounceTimer = (0, import_react.useRef)(null);
|
|
156
187
|
const hasAppliedInitialScroll = (0, import_react.useRef)(false);
|
|
188
|
+
const isAnimatingRef = (0, import_react.useRef)(false);
|
|
157
189
|
const readPosition = (0, import_react.useCallback)(() => {
|
|
158
190
|
const el = containerRef.current;
|
|
159
191
|
if (!el) return REVEAL_POSITION.center;
|
|
@@ -174,36 +206,112 @@ function RevealRowInner({
|
|
|
174
206
|
const closed = getScrollClosed(wL, wR, m, mode);
|
|
175
207
|
el.scrollLeft = closed;
|
|
176
208
|
}, [wL, wR, mode]);
|
|
209
|
+
const scrollToPosition = (0, import_react.useCallback)(
|
|
210
|
+
(targetScrollLeft, animationOptions) => {
|
|
211
|
+
const el = containerRef.current;
|
|
212
|
+
if (!el) return;
|
|
213
|
+
const { duration, easing } = animationOptions;
|
|
214
|
+
if (duration === 0) {
|
|
215
|
+
el.scrollLeft = targetScrollLeft;
|
|
216
|
+
return;
|
|
217
|
+
}
|
|
218
|
+
isAnimatingRef.current = true;
|
|
219
|
+
const originalScrollSnapType = el.style.scrollSnapType;
|
|
220
|
+
el.style.scrollSnapType = "none";
|
|
221
|
+
const startScrollLeft = el.scrollLeft;
|
|
222
|
+
const distance = targetScrollLeft - startScrollLeft;
|
|
223
|
+
const startTime = performance.now();
|
|
224
|
+
const animate = (currentTime) => {
|
|
225
|
+
const elapsed = currentTime - startTime;
|
|
226
|
+
const progress = Math.min(elapsed / duration, 1);
|
|
227
|
+
let easedProgress = progress;
|
|
228
|
+
if (easing === "ease-out") {
|
|
229
|
+
easedProgress = 1 - (1 - progress) ** 2;
|
|
230
|
+
} else if (easing === "ease-in-out") {
|
|
231
|
+
easedProgress = progress < 0.5 ? 2 * progress * progress : 1 - (-2 * progress + 2) ** 2 / 2;
|
|
232
|
+
} else if (easing.startsWith("cubic-bezier")) {
|
|
233
|
+
easedProgress = progress * progress * (3 - 2 * progress);
|
|
234
|
+
if (easing.includes("-0.55")) {
|
|
235
|
+
easedProgress = progress < 0.5 ? 4 * progress * progress * progress : 1 - (-2 * progress + 2) ** 3 / 2;
|
|
236
|
+
if (progress > 0.7 && progress < 1) {
|
|
237
|
+
easedProgress += Math.sin((progress - 0.7) * Math.PI * 10) * 0.1 * (1 - progress);
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
el.scrollLeft = startScrollLeft + distance * easedProgress;
|
|
242
|
+
if (progress < 1) {
|
|
243
|
+
requestAnimationFrame(animate);
|
|
244
|
+
} else {
|
|
245
|
+
el.scrollLeft = targetScrollLeft;
|
|
246
|
+
el.style.scrollSnapType = originalScrollSnapType || "x mandatory";
|
|
247
|
+
isAnimatingRef.current = false;
|
|
248
|
+
}
|
|
249
|
+
};
|
|
250
|
+
requestAnimationFrame(animate);
|
|
251
|
+
},
|
|
252
|
+
[]
|
|
253
|
+
);
|
|
177
254
|
(0, import_react.useImperativeHandle)(
|
|
178
255
|
forwardedRef,
|
|
179
256
|
() => ({
|
|
180
|
-
close: () => {
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
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);
|
|
187
276
|
},
|
|
188
|
-
reveal: (position) => {
|
|
277
|
+
reveal: (position, animated) => {
|
|
189
278
|
const el = containerRef.current;
|
|
190
279
|
if (!el) return;
|
|
191
280
|
const max = getMaxScroll(el);
|
|
281
|
+
let targetScroll;
|
|
192
282
|
if (position === REVEAL_POSITION.center) {
|
|
193
|
-
|
|
283
|
+
targetScroll = getScrollClosed(wL, wR, max, mode);
|
|
194
284
|
} else if (position === REVEAL_POSITION.left && (mode === REVEAL_MODE.left || mode === REVEAL_MODE.both)) {
|
|
195
|
-
|
|
285
|
+
targetScroll = 0;
|
|
196
286
|
} else if (position === REVEAL_POSITION.right && (mode === REVEAL_MODE.right || mode === REVEAL_MODE.both)) {
|
|
197
|
-
|
|
287
|
+
targetScroll = max;
|
|
198
288
|
} else {
|
|
199
289
|
return;
|
|
200
290
|
}
|
|
201
|
-
const
|
|
202
|
-
|
|
203
|
-
|
|
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);
|
|
204
303
|
}
|
|
205
304
|
}),
|
|
206
|
-
[
|
|
305
|
+
[
|
|
306
|
+
mode,
|
|
307
|
+
onRevealChange,
|
|
308
|
+
readPosition,
|
|
309
|
+
scrollToPosition,
|
|
310
|
+
wL,
|
|
311
|
+
wR,
|
|
312
|
+
animationPreset,
|
|
313
|
+
animationConfig
|
|
314
|
+
]
|
|
207
315
|
);
|
|
208
316
|
(0, import_react.useLayoutEffect)(() => {
|
|
209
317
|
if (mode === REVEAL_MODE.right) {
|
|
@@ -349,7 +457,7 @@ function RevealRowInner({
|
|
|
349
457
|
onScroll: handleScroll,
|
|
350
458
|
onClickCapture,
|
|
351
459
|
style: {
|
|
352
|
-
...rootScrollStyle,
|
|
460
|
+
...disabled ? rootScrollStyleDisabled : rootScrollStyle,
|
|
353
461
|
...style,
|
|
354
462
|
gridTemplateColumns
|
|
355
463
|
},
|
|
@@ -386,6 +494,8 @@ var RevealRow = (0, import_react.forwardRef)(
|
|
|
386
494
|
);
|
|
387
495
|
// Annotate the CommonJS export names for ESM import in node:
|
|
388
496
|
0 && (module.exports = {
|
|
497
|
+
ANIMATION_PRESET,
|
|
498
|
+
ANIMATION_PRESETS,
|
|
389
499
|
REVEAL_HANDLE_POSITION,
|
|
390
500
|
REVEAL_MODE,
|
|
391
501
|
REVEAL_POSITION,
|
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 RevealHandlePosition,\n RevealMode,\n RevealPosition,\n RevealRowClassNames,\n RevealRowHandle,\n RevealRowProps,\n} from './types'\nexport {\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 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: () => void\n reveal: (position: RevealPosition) => 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","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 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\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 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 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\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 el.scrollLeft = closed\n }, [wL, wR, mode])\n\n useImperativeHandle(\n forwardedRef,\n () => ({\n close: () => {\n scrollToClosed()\n const p = readPosition()\n if (lastEmitted.current !== p) {\n lastEmitted.current = p\n onRevealChange?.(p)\n }\n },\n reveal: (position: RevealPosition) => {\n const el = containerRef.current\n if (!el) return\n const max = getMaxScroll(el)\n if (position === REVEAL_POSITION.center) {\n el.scrollLeft = getScrollClosed(wL, wR, max, mode)\n } else if (\n position === REVEAL_POSITION.left &&\n (mode === REVEAL_MODE.left || mode === REVEAL_MODE.both)\n ) {\n el.scrollLeft = 0\n } else if (\n position === REVEAL_POSITION.right &&\n (mode === REVEAL_MODE.right || mode === REVEAL_MODE.both)\n ) {\n el.scrollLeft = max\n } else {\n return\n }\n const p = getRevealFromScroll(el.scrollLeft, max, wL, wR, mode)\n lastEmitted.current = p\n onRevealChange?.(p)\n },\n }),\n [mode, onRevealChange, readPosition, scrollToClosed, wL, wR],\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 ...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 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"]}
|
package/dist/index.mjs
CHANGED
|
@@ -13,6 +13,16 @@ var REVEAL_HANDLE_POSITION = {
|
|
|
13
13
|
start: "start",
|
|
14
14
|
end: "end"
|
|
15
15
|
};
|
|
16
|
+
var ANIMATION_PRESET = {
|
|
17
|
+
none: "none",
|
|
18
|
+
quick: "quick",
|
|
19
|
+
smooth: "smooth"
|
|
20
|
+
};
|
|
21
|
+
var ANIMATION_PRESETS = {
|
|
22
|
+
[ANIMATION_PRESET.none]: { duration: 0, easing: "linear" },
|
|
23
|
+
[ANIMATION_PRESET.quick]: { duration: 200, easing: "ease-out" },
|
|
24
|
+
[ANIMATION_PRESET.smooth]: { duration: 400, easing: "ease-in-out" }
|
|
25
|
+
};
|
|
16
26
|
|
|
17
27
|
// src/getRevealFromScroll.ts
|
|
18
28
|
function getRevealFromScroll(scrollLeft, maxScroll, wL, wR, mode) {
|
|
@@ -82,6 +92,18 @@ function resolveMode(left, right, mode) {
|
|
|
82
92
|
if (left != null) return REVEAL_MODE.left;
|
|
83
93
|
return REVEAL_MODE.right;
|
|
84
94
|
}
|
|
95
|
+
function resolveAnimationConfig(animated, defaultPreset, customConfig) {
|
|
96
|
+
if (animated === false) {
|
|
97
|
+
return ANIMATION_PRESETS[ANIMATION_PRESET.none];
|
|
98
|
+
}
|
|
99
|
+
if (animated === true || animated === void 0) {
|
|
100
|
+
return customConfig || ANIMATION_PRESETS[defaultPreset];
|
|
101
|
+
}
|
|
102
|
+
if (typeof animated === "string") {
|
|
103
|
+
return ANIMATION_PRESETS[animated];
|
|
104
|
+
}
|
|
105
|
+
return animated;
|
|
106
|
+
}
|
|
85
107
|
var SCROLL_REVEAL_DEBOUNCE_MS = 64;
|
|
86
108
|
var restEpsilon = 2;
|
|
87
109
|
var rootScrollStyle = {
|
|
@@ -93,6 +115,11 @@ var rootScrollStyle = {
|
|
|
93
115
|
overscrollBehaviorX: "contain",
|
|
94
116
|
touchAction: "pan-x pan-y"
|
|
95
117
|
};
|
|
118
|
+
var rootScrollStyleDisabled = {
|
|
119
|
+
...rootScrollStyle,
|
|
120
|
+
overflowX: "hidden",
|
|
121
|
+
touchAction: "pan-y"
|
|
122
|
+
};
|
|
96
123
|
var snapStart = { scrollSnapAlign: "start" };
|
|
97
124
|
var snapEnd = { scrollSnapAlign: "end" };
|
|
98
125
|
function RevealRowInner({
|
|
@@ -115,6 +142,8 @@ function RevealRowInner({
|
|
|
115
142
|
isActive = false,
|
|
116
143
|
className,
|
|
117
144
|
style,
|
|
145
|
+
animationPreset = ANIMATION_PRESET.quick,
|
|
146
|
+
animationConfig,
|
|
118
147
|
forwardedRef
|
|
119
148
|
}) {
|
|
120
149
|
const mode = resolveMode(left, right, modeProp);
|
|
@@ -130,6 +159,7 @@ function RevealRowInner({
|
|
|
130
159
|
const swipedRef = useRef(false);
|
|
131
160
|
const debounceTimer = useRef(null);
|
|
132
161
|
const hasAppliedInitialScroll = useRef(false);
|
|
162
|
+
const isAnimatingRef = useRef(false);
|
|
133
163
|
const readPosition = useCallback(() => {
|
|
134
164
|
const el = containerRef.current;
|
|
135
165
|
if (!el) return REVEAL_POSITION.center;
|
|
@@ -150,36 +180,112 @@ function RevealRowInner({
|
|
|
150
180
|
const closed = getScrollClosed(wL, wR, m, mode);
|
|
151
181
|
el.scrollLeft = closed;
|
|
152
182
|
}, [wL, wR, mode]);
|
|
183
|
+
const scrollToPosition = useCallback(
|
|
184
|
+
(targetScrollLeft, animationOptions) => {
|
|
185
|
+
const el = containerRef.current;
|
|
186
|
+
if (!el) return;
|
|
187
|
+
const { duration, easing } = animationOptions;
|
|
188
|
+
if (duration === 0) {
|
|
189
|
+
el.scrollLeft = targetScrollLeft;
|
|
190
|
+
return;
|
|
191
|
+
}
|
|
192
|
+
isAnimatingRef.current = true;
|
|
193
|
+
const originalScrollSnapType = el.style.scrollSnapType;
|
|
194
|
+
el.style.scrollSnapType = "none";
|
|
195
|
+
const startScrollLeft = el.scrollLeft;
|
|
196
|
+
const distance = targetScrollLeft - startScrollLeft;
|
|
197
|
+
const startTime = performance.now();
|
|
198
|
+
const animate = (currentTime) => {
|
|
199
|
+
const elapsed = currentTime - startTime;
|
|
200
|
+
const progress = Math.min(elapsed / duration, 1);
|
|
201
|
+
let easedProgress = progress;
|
|
202
|
+
if (easing === "ease-out") {
|
|
203
|
+
easedProgress = 1 - (1 - progress) ** 2;
|
|
204
|
+
} else if (easing === "ease-in-out") {
|
|
205
|
+
easedProgress = progress < 0.5 ? 2 * progress * progress : 1 - (-2 * progress + 2) ** 2 / 2;
|
|
206
|
+
} else if (easing.startsWith("cubic-bezier")) {
|
|
207
|
+
easedProgress = progress * progress * (3 - 2 * progress);
|
|
208
|
+
if (easing.includes("-0.55")) {
|
|
209
|
+
easedProgress = progress < 0.5 ? 4 * progress * progress * progress : 1 - (-2 * progress + 2) ** 3 / 2;
|
|
210
|
+
if (progress > 0.7 && progress < 1) {
|
|
211
|
+
easedProgress += Math.sin((progress - 0.7) * Math.PI * 10) * 0.1 * (1 - progress);
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
el.scrollLeft = startScrollLeft + distance * easedProgress;
|
|
216
|
+
if (progress < 1) {
|
|
217
|
+
requestAnimationFrame(animate);
|
|
218
|
+
} else {
|
|
219
|
+
el.scrollLeft = targetScrollLeft;
|
|
220
|
+
el.style.scrollSnapType = originalScrollSnapType || "x mandatory";
|
|
221
|
+
isAnimatingRef.current = false;
|
|
222
|
+
}
|
|
223
|
+
};
|
|
224
|
+
requestAnimationFrame(animate);
|
|
225
|
+
},
|
|
226
|
+
[]
|
|
227
|
+
);
|
|
153
228
|
useImperativeHandle(
|
|
154
229
|
forwardedRef,
|
|
155
230
|
() => ({
|
|
156
|
-
close: () => {
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
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);
|
|
163
250
|
},
|
|
164
|
-
reveal: (position) => {
|
|
251
|
+
reveal: (position, animated) => {
|
|
165
252
|
const el = containerRef.current;
|
|
166
253
|
if (!el) return;
|
|
167
254
|
const max = getMaxScroll(el);
|
|
255
|
+
let targetScroll;
|
|
168
256
|
if (position === REVEAL_POSITION.center) {
|
|
169
|
-
|
|
257
|
+
targetScroll = getScrollClosed(wL, wR, max, mode);
|
|
170
258
|
} else if (position === REVEAL_POSITION.left && (mode === REVEAL_MODE.left || mode === REVEAL_MODE.both)) {
|
|
171
|
-
|
|
259
|
+
targetScroll = 0;
|
|
172
260
|
} else if (position === REVEAL_POSITION.right && (mode === REVEAL_MODE.right || mode === REVEAL_MODE.both)) {
|
|
173
|
-
|
|
261
|
+
targetScroll = max;
|
|
174
262
|
} else {
|
|
175
263
|
return;
|
|
176
264
|
}
|
|
177
|
-
const
|
|
178
|
-
|
|
179
|
-
|
|
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);
|
|
180
277
|
}
|
|
181
278
|
}),
|
|
182
|
-
[
|
|
279
|
+
[
|
|
280
|
+
mode,
|
|
281
|
+
onRevealChange,
|
|
282
|
+
readPosition,
|
|
283
|
+
scrollToPosition,
|
|
284
|
+
wL,
|
|
285
|
+
wR,
|
|
286
|
+
animationPreset,
|
|
287
|
+
animationConfig
|
|
288
|
+
]
|
|
183
289
|
);
|
|
184
290
|
useLayoutEffect(() => {
|
|
185
291
|
if (mode === REVEAL_MODE.right) {
|
|
@@ -325,7 +431,7 @@ function RevealRowInner({
|
|
|
325
431
|
onScroll: handleScroll,
|
|
326
432
|
onClickCapture,
|
|
327
433
|
style: {
|
|
328
|
-
...rootScrollStyle,
|
|
434
|
+
...disabled ? rootScrollStyleDisabled : rootScrollStyle,
|
|
329
435
|
...style,
|
|
330
436
|
gridTemplateColumns
|
|
331
437
|
},
|
|
@@ -361,6 +467,8 @@ var RevealRow = forwardRef(
|
|
|
361
467
|
}
|
|
362
468
|
);
|
|
363
469
|
export {
|
|
470
|
+
ANIMATION_PRESET,
|
|
471
|
+
ANIMATION_PRESETS,
|
|
364
472
|
REVEAL_HANDLE_POSITION,
|
|
365
473
|
REVEAL_MODE,
|
|
366
474
|
REVEAL_POSITION,
|
package/dist/index.mjs.map
CHANGED
|
@@ -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 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: () => void\n reveal: (position: RevealPosition) => 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","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 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\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 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 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\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 el.scrollLeft = closed\n }, [wL, wR, mode])\n\n useImperativeHandle(\n forwardedRef,\n () => ({\n close: () => {\n scrollToClosed()\n const p = readPosition()\n if (lastEmitted.current !== p) {\n lastEmitted.current = p\n onRevealChange?.(p)\n }\n },\n reveal: (position: RevealPosition) => {\n const el = containerRef.current\n if (!el) return\n const max = getMaxScroll(el)\n if (position === REVEAL_POSITION.center) {\n el.scrollLeft = getScrollClosed(wL, wR, max, mode)\n } else if (\n position === REVEAL_POSITION.left &&\n (mode === REVEAL_MODE.left || mode === REVEAL_MODE.both)\n ) {\n el.scrollLeft = 0\n } else if (\n position === REVEAL_POSITION.right &&\n (mode === REVEAL_MODE.right || mode === REVEAL_MODE.both)\n ) {\n el.scrollLeft = max\n } else {\n return\n }\n const p = getRevealFromScroll(el.scrollLeft, max, wL, wR, mode)\n lastEmitted.current = p\n onRevealChange?.(p)\n },\n }),\n [mode, onRevealChange, readPosition, scrollToClosed, wL, wR],\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 ...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 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"]}
|