@present-day/reveal-row 0.1.0 → 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 +133 -17
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +131 -17
- 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) {
|
|
@@ -80,6 +92,7 @@ function DefaultHandleIcon() {
|
|
|
80
92
|
fill: "currentColor",
|
|
81
93
|
"aria-hidden": true,
|
|
82
94
|
children: [
|
|
95
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("title", { children: "Drag handle" }),
|
|
83
96
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("circle", { cx: "6", cy: "4", r: "1.2" }),
|
|
84
97
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("circle", { cx: "10", cy: "4", r: "1.2" }),
|
|
85
98
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("circle", { cx: "6", cy: "8", r: "1.2" }),
|
|
@@ -105,6 +118,18 @@ function resolveMode(left, right, mode) {
|
|
|
105
118
|
if (left != null) return REVEAL_MODE.left;
|
|
106
119
|
return REVEAL_MODE.right;
|
|
107
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
|
+
}
|
|
108
133
|
var SCROLL_REVEAL_DEBOUNCE_MS = 64;
|
|
109
134
|
var restEpsilon = 2;
|
|
110
135
|
var rootScrollStyle = {
|
|
@@ -116,6 +141,11 @@ var rootScrollStyle = {
|
|
|
116
141
|
overscrollBehaviorX: "contain",
|
|
117
142
|
touchAction: "pan-x pan-y"
|
|
118
143
|
};
|
|
144
|
+
var rootScrollStyleDisabled = {
|
|
145
|
+
...rootScrollStyle,
|
|
146
|
+
overflowX: "hidden",
|
|
147
|
+
touchAction: "pan-y"
|
|
148
|
+
};
|
|
119
149
|
var snapStart = { scrollSnapAlign: "start" };
|
|
120
150
|
var snapEnd = { scrollSnapAlign: "end" };
|
|
121
151
|
function RevealRowInner({
|
|
@@ -138,6 +168,8 @@ function RevealRowInner({
|
|
|
138
168
|
isActive = false,
|
|
139
169
|
className,
|
|
140
170
|
style,
|
|
171
|
+
animationPreset = ANIMATION_PRESET.quick,
|
|
172
|
+
animationConfig,
|
|
141
173
|
forwardedRef
|
|
142
174
|
}) {
|
|
143
175
|
const mode = resolveMode(left, right, modeProp);
|
|
@@ -153,6 +185,7 @@ function RevealRowInner({
|
|
|
153
185
|
const swipedRef = (0, import_react.useRef)(false);
|
|
154
186
|
const debounceTimer = (0, import_react.useRef)(null);
|
|
155
187
|
const hasAppliedInitialScroll = (0, import_react.useRef)(false);
|
|
188
|
+
const isAnimatingRef = (0, import_react.useRef)(false);
|
|
156
189
|
const readPosition = (0, import_react.useCallback)(() => {
|
|
157
190
|
const el = containerRef.current;
|
|
158
191
|
if (!el) return REVEAL_POSITION.center;
|
|
@@ -173,36 +206,112 @@ function RevealRowInner({
|
|
|
173
206
|
const closed = getScrollClosed(wL, wR, m, mode);
|
|
174
207
|
el.scrollLeft = closed;
|
|
175
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
|
+
);
|
|
176
254
|
(0, import_react.useImperativeHandle)(
|
|
177
255
|
forwardedRef,
|
|
178
256
|
() => ({
|
|
179
|
-
close: () => {
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
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);
|
|
186
276
|
},
|
|
187
|
-
reveal: (position) => {
|
|
277
|
+
reveal: (position, animated) => {
|
|
188
278
|
const el = containerRef.current;
|
|
189
279
|
if (!el) return;
|
|
190
280
|
const max = getMaxScroll(el);
|
|
281
|
+
let targetScroll;
|
|
191
282
|
if (position === REVEAL_POSITION.center) {
|
|
192
|
-
|
|
283
|
+
targetScroll = getScrollClosed(wL, wR, max, mode);
|
|
193
284
|
} else if (position === REVEAL_POSITION.left && (mode === REVEAL_MODE.left || mode === REVEAL_MODE.both)) {
|
|
194
|
-
|
|
285
|
+
targetScroll = 0;
|
|
195
286
|
} else if (position === REVEAL_POSITION.right && (mode === REVEAL_MODE.right || mode === REVEAL_MODE.both)) {
|
|
196
|
-
|
|
287
|
+
targetScroll = max;
|
|
197
288
|
} else {
|
|
198
289
|
return;
|
|
199
290
|
}
|
|
200
|
-
const
|
|
201
|
-
|
|
202
|
-
|
|
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);
|
|
203
303
|
}
|
|
204
304
|
}),
|
|
205
|
-
[
|
|
305
|
+
[
|
|
306
|
+
mode,
|
|
307
|
+
onRevealChange,
|
|
308
|
+
readPosition,
|
|
309
|
+
scrollToPosition,
|
|
310
|
+
wL,
|
|
311
|
+
wR,
|
|
312
|
+
animationPreset,
|
|
313
|
+
animationConfig
|
|
314
|
+
]
|
|
206
315
|
);
|
|
207
316
|
(0, import_react.useLayoutEffect)(() => {
|
|
208
317
|
if (mode === REVEAL_MODE.right) {
|
|
@@ -298,7 +407,12 @@ function RevealRowInner({
|
|
|
298
407
|
role: "presentation",
|
|
299
408
|
className: classNames.handleContainer,
|
|
300
409
|
"data-reveal-row-handle": true,
|
|
301
|
-
style: {
|
|
410
|
+
style: {
|
|
411
|
+
flexShrink: 0,
|
|
412
|
+
alignSelf: "stretch",
|
|
413
|
+
display: "flex",
|
|
414
|
+
alignItems: "center"
|
|
415
|
+
},
|
|
302
416
|
title: handleOverride === void 0 ? handleTitle : void 0,
|
|
303
417
|
children: handleContent
|
|
304
418
|
}
|
|
@@ -343,7 +457,7 @@ function RevealRowInner({
|
|
|
343
457
|
onScroll: handleScroll,
|
|
344
458
|
onClickCapture,
|
|
345
459
|
style: {
|
|
346
|
-
...rootScrollStyle,
|
|
460
|
+
...disabled ? rootScrollStyleDisabled : rootScrollStyle,
|
|
347
461
|
...style,
|
|
348
462
|
gridTemplateColumns
|
|
349
463
|
},
|
|
@@ -380,6 +494,8 @@ var RevealRow = (0, import_react.forwardRef)(
|
|
|
380
494
|
);
|
|
381
495
|
// Annotate the CommonJS export names for ESM import in node:
|
|
382
496
|
0 && (module.exports = {
|
|
497
|
+
ANIMATION_PRESET,
|
|
498
|
+
ANIMATION_PRESETS,
|
|
383
499
|
REVEAL_HANDLE_POSITION,
|
|
384
500
|
REVEAL_MODE,
|
|
385
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={{ flexShrink: 0, alignSelf: 'stretch', display: 'flex', alignItems: 'center' }}\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 <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":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACEO,IAAM,cAAc;AAAA,EACzB,MAAM;AAAA,EACN,OAAO;AAAA,EACP,MAAM;AACR;AAIO,IAAM,kBAAkB;AAAA,EAC7B,MAAM;AAAA,EACN,QAAQ;AAAA,EACR,OAAO;AACT;AAKO,IAAM,yBAAyB;AAAA,EACpC,OAAO;AAAA,EACP,KAAK;AACP;;;ACVO,SAAS,oBACd,YACA,WACA,IACA,IACA,MACgB;AAChB,MAAI,SAAS,YAAY,OAAO;AAC9B,QAAI,aAAa,EAAG,QAAO,gBAAgB;AAC3C,WAAO,aAAa,KAAK,IAAI,gBAAgB,SAAS,gBAAgB;AAAA,EACxE;AACA,MAAI,SAAS,YAAY,MAAM;AAC7B,QAAI,aAAa,EAAG,QAAO,gBAAgB;AAC3C,WAAO,aAAa,KAAK,IAAI,gBAAgB,OAAO,gBAAgB;AAAA,EACtE;AACA,MAAI,aAAa,EAAG,QAAO,gBAAgB;AAC3C,MAAI,aAAa,KAAK,EAAG,QAAO,gBAAgB;AAChD,MAAI,aAAa,YAAY,KAAK,EAAG,QAAO,gBAAgB;AAC5D,SAAO,gBAAgB;AACzB;AAGO,SAAS,gBACd,IACA,KACA,YACA,MACQ;AACR,MAAI,SAAS,YAAY,MAAO,QAAO;AACvC,SAAO;AACT;;;ACvCA,mBAOO;;;ACPH;AAFG,SAAS,oBAAoB;AAClC,SACE;AAAA,IAAC;AAAA;AAAA,MACC,OAAO;AAAA,MACP,QAAQ;AAAA,MACR,SAAQ;AAAA,MACR,MAAK;AAAA,MACL,eAAW;AAAA,MAEX;AAAA,oDAAC,YAAO,IAAG,KAAI,IAAG,KAAI,GAAE,OAAM;AAAA,QAC9B,4CAAC,YAAO,IAAG,MAAK,IAAG,KAAI,GAAE,OAAM;AAAA,QAC/B,4CAAC,YAAO,IAAG,KAAI,IAAG,KAAI,GAAE,OAAM;AAAA,QAC9B,4CAAC,YAAO,IAAG,MAAK,IAAG,KAAI,GAAE,OAAM;AAAA,QAC/B,4CAAC,YAAO,IAAG,KAAI,IAAG,MAAK,GAAE,OAAM;AAAA,QAC/B,4CAAC,YAAO,IAAG,MAAK,IAAG,MAAK,GAAE,OAAM;AAAA;AAAA;AAAA,EAClC;AAEJ;;;AD4OM,IAAAA,sBAAA;AApON,SAAS,MAAM,OAA+B;AAC5C,SAAO,MAAM,OAAO,OAAO,EAAE,KAAK,GAAG;AACvC;AAEA,SAAS,aAAa,IAAoB;AACxC,SAAO,KAAK,IAAI,GAAG,GAAG,cAAc,GAAG,WAAW;AACpD;AAEA,SAAS,YACP,MACA,OACA,MACY;AACZ,MAAI,KAAM,QAAO;AACjB,MAAI,QAAQ,QAAQ,SAAS,KAAM,QAAO,YAAY;AACtD,MAAI,QAAQ,KAAM,QAAO,YAAY;AACrC,SAAO,YAAY;AACrB;AAEA,IAAM,4BAA4B;AAClC,IAAM,cAAc;AAEpB,IAAM,kBAAiC;AAAA,EACrC,SAAS;AAAA,EACT,WAAW;AAAA,EACX,gBAAgB;AAAA,EAChB,gBAAgB;AAAA,EAChB,yBAAyB;AAAA,EACzB,qBAAqB;AAAA,EACrB,aAAa;AACf;AAEA,IAAM,YAA2B,EAAE,iBAAiB,QAAQ;AAC5D,IAAM,UAAyB,EAAE,iBAAiB,MAAM;AAMxD,SAAS,eAAe;AAAA,EACtB;AAAA,EACA;AAAA,EACA;AAAA,EACA,MAAM;AAAA,EACN,iBAAiB;AAAA,EACjB,kBAAkB;AAAA,EAClB,aAAa,CAAC;AAAA,EACd,aAAa;AAAA,EACb,QAAQ;AAAA,EACR,gBAAgB;AAAA,EAChB,cAAc;AAAA,EACd,kBAAkB;AAAA,EAClB;AAAA,EACA,UAAU;AAAA,EACV,oBAAoB;AAAA,EACpB,WAAW;AAAA,EACX,WAAW;AAAA,EACX;AAAA,EACA;AAAA,EACA;AACF,GAAe;AACb,QAAM,OAAO,YAAY,MAAM,OAAO,QAAQ;AAC9C,QAAM,OAAO,SAAS,YAAY,QAAQ,SAAS,YAAY;AAC/D,QAAM,OAAO,SAAS,YAAY,SAAS,SAAS,YAAY;AAChE,QAAM,KAAK,OAAQ,QAAQ,KAAM;AACjC,QAAM,KAAK,OAAQ,QAAQ,KAAM;AAEjC,QAAM,iBACJ,uBACC,SAAS,YAAY,OAClB,uBAAuB,QACvB,uBAAuB;AAE7B,QAAM,mBAAe,qBAAuB,IAAI;AAChD,QAAM,cAAU,qBAAuB,IAAI;AAC3C,QAAM,eAAW,qBAAuB,IAAI;AAC5C,QAAM,kBAAc,qBAA8B,IAAI;AACtD,QAAM,gBAAY,qBAAO,KAAK;AAC9B,QAAM,oBAAgB,qBAA6C,IAAI;AACvE,QAAM,8BAA0B,qBAAO,KAAK;AAE5C,QAAM,mBAAe,0BAAY,MAAsB;AACrD,UAAM,KAAK,aAAa;AACxB,QAAI,CAAC,GAAI,QAAO,gBAAgB;AAChC,WAAO,oBAAoB,GAAG,YAAY,aAAa,EAAE,GAAG,IAAI,IAAI,IAAI;AAAA,EAC1E,GAAG,CAAC,IAAI,IAAI,IAAI,CAAC;AAEjB,QAAM,iBAAa;AAAA,IACjB,CAAC,aAA6B;AAC5B,UAAI,YAAY,YAAY,SAAU;AACtC,kBAAY,UAAU;AACtB,uBAAiB,QAAQ;AAAA,IAC3B;AAAA,IACA,CAAC,cAAc;AAAA,EACjB;AAEA,QAAM,qBAAiB,0BAAY,MAAM;AACvC,UAAM,KAAK,aAAa;AACxB,QAAI,CAAC,GAAI;AACT,UAAM,IAAI,aAAa,EAAE;AACzB,UAAM,SAAS,gBAAgB,IAAI,IAAI,GAAG,IAAI;AAC9C,OAAG,aAAa;AAAA,EAClB,GAAG,CAAC,IAAI,IAAI,IAAI,CAAC;AAEjB;AAAA,IACE;AAAA,IACA,OAAO;AAAA,MACL,OAAO,MAAM;AACX,uBAAe;AACf,cAAM,IAAI,aAAa;AACvB,YAAI,YAAY,YAAY,GAAG;AAC7B,sBAAY,UAAU;AACtB,2BAAiB,CAAC;AAAA,QACpB;AAAA,MACF;AAAA,MACA,QAAQ,CAAC,aAA6B;AACpC,cAAM,KAAK,aAAa;AACxB,YAAI,CAAC,GAAI;AACT,cAAM,MAAM,aAAa,EAAE;AAC3B,YAAI,aAAa,gBAAgB,QAAQ;AACvC,aAAG,aAAa,gBAAgB,IAAI,IAAI,KAAK,IAAI;AAAA,QACnD,WACE,aAAa,gBAAgB,SAC5B,SAAS,YAAY,QAAQ,SAAS,YAAY,OACnD;AACA,aAAG,aAAa;AAAA,QAClB,WACE,aAAa,gBAAgB,UAC5B,SAAS,YAAY,SAAS,SAAS,YAAY,OACpD;AACA,aAAG,aAAa;AAAA,QAClB,OAAO;AACL;AAAA,QACF;AACA,cAAM,IAAI,oBAAoB,GAAG,YAAY,KAAK,IAAI,IAAI,IAAI;AAC9D,oBAAY,UAAU;AACtB,yBAAiB,CAAC;AAAA,MACpB;AAAA,IACF;AAAA,IACA,CAAC,MAAM,gBAAgB,cAAc,gBAAgB,IAAI,EAAE;AAAA,EAC7D;AAEA,oCAAgB,MAAM;AACpB,QAAI,SAAS,YAAY,OAAO;AAC9B;AAAA,IACF;AACA,UAAM,KAAK,aAAa;AACxB,QAAI,CAAC,GAAI;AACT,QAAI,CAAC,wBAAwB,SAAS;AACpC,SAAG,aAAa;AAChB,8BAAwB,UAAU;AAAA,IACpC;AAAA,EACF,GAAG,CAAC,MAAM,EAAE,CAAC;AAEb,8BAAU,MAAM;AACd,QAAI,YAAY,mBAAmB;AACjC,8BAAwB,UAAU;AAClC,qBAAe;AACf,iBAAW,aAAa,CAAC;AAAA,IAC3B;AAAA,EACF,GAAG,CAAC,UAAU,YAAY,cAAc,mBAAmB,cAAc,CAAC;AAE1E,8BAAU,MAAM;AACd,QAAI,UAAU;AACZ,8BAAwB,UAAU;AAClC,qBAAe;AACf,iBAAW,aAAa,CAAC;AAAA,IAC3B;AAAA,EACF,GAAG,CAAC,YAAY,UAAU,cAAc,cAAc,CAAC;AAEvD;AAAA,IACE,MAAM,MAAM;AACV,UAAI,cAAc,SAAS;AACzB,qBAAa,cAAc,OAAO;AAAA,MACpC;AAAA,IACF;AAAA,IACA,CAAC;AAAA,EACH;AAEA,QAAM,mBAAe;AAAA,IACnB,CAAC,MAA+B;AAC9B,qBAAe,CAAC;AAChB,YAAM,KAAK,aAAa;AACxB,UAAI,CAAC,GAAI;AACT,YAAM,IAAI,aAAa,EAAE;AACzB,YAAM,MAAM,oBAAoB,GAAG,YAAY,GAAG,IAAI,IAAI,IAAI;AAC9D,YAAM,SAAS,gBAAgB,IAAI,IAAI,GAAG,IAAI;AAC9C,UAAI,KAAK,IAAI,GAAG,aAAa,MAAM,IAAI,aAAa;AAClD,kBAAU,UAAU;AAAA,MACtB;AACA,UAAI,cAAc,SAAS;AACzB,qBAAa,cAAc,OAAO;AAAA,MACpC;AACA,oBAAc,UAAU,WAAW,MAAM;AACvC,sBAAc,UAAU;AACxB,mBAAW,GAAG;AAAA,MAChB,GAAG,yBAAyB;AAAA,IAC9B;AAAA,IACA,CAAC,YAAY,MAAM,cAAc,IAAI,EAAE;AAAA,EACzC;AAEA,QAAM,qBAAiB,0BAAY,CAAC,MAAkB;AACpD,UAAM,IAAI,EAAE;AACZ,QAAI,GAAG;AACL,UAAI,QAAQ,SAAS,SAAS,CAAC,KAAK,SAAS,SAAS,SAAS,CAAC,GAAG;AACjE;AAAA,MACF;AAAA,IACF;AACA,QAAI,UAAU,SAAS;AACrB,QAAE,eAAe;AACjB,QAAE,gBAAgB;AAClB,gBAAU,UAAU;AAAA,IACtB;AAAA,EACF,GAAG,CAAC,CAAC;AAIL,QAAM,sBACJ,SAAS,YAAY,QACjB,QAAQ,EAAE,OACV,SAAS,YAAY,OACnB,GAAG,EAAE,YACL,GAAG,EAAE,WAAW,EAAE;AAE1B,QAAM,gBAAgB,aACpB,mBAAmB,SACjB,iBAEA,8EACE;AAAA;AAAA,MAAC;AAAA;AAAA,QACC,WAAU;AAAA,QACV,OAAO;AAAA,UACL,UAAU;AAAA,UACV,OAAO;AAAA,UACP,QAAQ;AAAA,UACR,SAAS;AAAA,UACT,QAAQ;AAAA,UACR,UAAU;AAAA,UACV,MAAM;AAAA,UACN,QAAQ;AAAA,QACV;AAAA,QAEC;AAAA;AAAA,IACH;AAAA,IACA,6CAAC,UAAK,WAAW,WAAW,YAAY,eAAW,MACjD,uDAAC,qBAAkB,GACrB;AAAA,KACF,IAEA;AAEJ,QAAM,cAAc,aAClB;AAAA,IAAC;AAAA;AAAA,MACC,MAAK;AAAA,MACL,WAAW,WAAW;AAAA,MACtB,0BAAsB;AAAA,MACtB,OAAO,EAAE,YAAY,GAAG,WAAW,WAAW,SAAS,QAAQ,YAAY,SAAS;AAAA,MACpF,OAAO,mBAAmB,SAAY,cAAc;AAAA,MAEnD;AAAA;AAAA,EACH,IACE;AAEJ,QAAM,aACJ;AAAA,IAAC;AAAA;AAAA,MACC,WAAW,WAAW;AAAA,MACtB,wBAAoB;AAAA,MACpB,OAAO;AAAA,QACL,GAAG;AAAA,QACH,UAAU;AAAA,QACV,OAAO;AAAA,QACP,UAAU;AAAA,QACV,WAAW;AAAA,MACb;AAAA,MAEA;AAAA,QAAC;AAAA;AAAA,UACC,WAAW,WAAW;AAAA,UACtB,OAAO;AAAA,YACL,SAAS;AAAA,YACT,UAAU;AAAA,YACV,OAAO;AAAA,YACP,YAAY;AAAA,UACd;AAAA,UAEC;AAAA,+BAAmB,uBAAuB,SAAS;AAAA,YACpD,6CAAC,SAAI,OAAO,EAAE,UAAU,GAAG,MAAM,GAAG,WAAW,EAAE,GAAI,UAAS;AAAA,YAC7D,mBAAmB,uBAAuB,OAAO;AAAA;AAAA;AAAA,MACpD;AAAA;AAAA,EACF;AAGF,SACE;AAAA,IAAC;AAAA;AAAA,MACC,KAAK;AAAA,MACL,oBAAkB;AAAA,MAClB,WAAW,GAAG,WAAW,MAAM,SAAS;AAAA,MACxC,UAAU;AAAA,MACV;AAAA,MACA,OAAO;AAAA,QACL,GAAG;AAAA,QACH,GAAG;AAAA,QACH;AAAA,MACF;AAAA,MAEC;AAAA,eACC;AAAA,UAAC;AAAA;AAAA,YACC,KAAK;AAAA,YACL,WAAW,WAAW;AAAA,YACtB,wBAAoB;AAAA,YACpB,OAAO,EAAE,GAAG,WAAW,UAAU,GAAG,OAAO,GAAG;AAAA,YAE7C;AAAA;AAAA,QACH,IACE;AAAA,QACH;AAAA,QACA,OACC;AAAA,UAAC;AAAA;AAAA,YACC,KAAK;AAAA,YACL,WAAW,WAAW;AAAA,YACtB,yBAAqB;AAAA,YACrB,OAAO,EAAE,GAAG,SAAS,UAAU,GAAG,OAAO,GAAG;AAAA,YAE3C;AAAA;AAAA,QACH,IACE;AAAA;AAAA;AAAA,EACN;AAEJ;AAEO,IAAM,gBAAY;AAAA,EACvB,SAASC,WAAU,OAAO,KAAK;AAC7B,WAAO,6CAAC,kBAAgB,GAAG,OAAO,cAAc,KAAK;AAAA,EACvD;AACF;","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) {
|
|
@@ -56,6 +66,7 @@ function DefaultHandleIcon() {
|
|
|
56
66
|
fill: "currentColor",
|
|
57
67
|
"aria-hidden": true,
|
|
58
68
|
children: [
|
|
69
|
+
/* @__PURE__ */ jsx("title", { children: "Drag handle" }),
|
|
59
70
|
/* @__PURE__ */ jsx("circle", { cx: "6", cy: "4", r: "1.2" }),
|
|
60
71
|
/* @__PURE__ */ jsx("circle", { cx: "10", cy: "4", r: "1.2" }),
|
|
61
72
|
/* @__PURE__ */ jsx("circle", { cx: "6", cy: "8", r: "1.2" }),
|
|
@@ -81,6 +92,18 @@ function resolveMode(left, right, mode) {
|
|
|
81
92
|
if (left != null) return REVEAL_MODE.left;
|
|
82
93
|
return REVEAL_MODE.right;
|
|
83
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
|
+
}
|
|
84
107
|
var SCROLL_REVEAL_DEBOUNCE_MS = 64;
|
|
85
108
|
var restEpsilon = 2;
|
|
86
109
|
var rootScrollStyle = {
|
|
@@ -92,6 +115,11 @@ var rootScrollStyle = {
|
|
|
92
115
|
overscrollBehaviorX: "contain",
|
|
93
116
|
touchAction: "pan-x pan-y"
|
|
94
117
|
};
|
|
118
|
+
var rootScrollStyleDisabled = {
|
|
119
|
+
...rootScrollStyle,
|
|
120
|
+
overflowX: "hidden",
|
|
121
|
+
touchAction: "pan-y"
|
|
122
|
+
};
|
|
95
123
|
var snapStart = { scrollSnapAlign: "start" };
|
|
96
124
|
var snapEnd = { scrollSnapAlign: "end" };
|
|
97
125
|
function RevealRowInner({
|
|
@@ -114,6 +142,8 @@ function RevealRowInner({
|
|
|
114
142
|
isActive = false,
|
|
115
143
|
className,
|
|
116
144
|
style,
|
|
145
|
+
animationPreset = ANIMATION_PRESET.quick,
|
|
146
|
+
animationConfig,
|
|
117
147
|
forwardedRef
|
|
118
148
|
}) {
|
|
119
149
|
const mode = resolveMode(left, right, modeProp);
|
|
@@ -129,6 +159,7 @@ function RevealRowInner({
|
|
|
129
159
|
const swipedRef = useRef(false);
|
|
130
160
|
const debounceTimer = useRef(null);
|
|
131
161
|
const hasAppliedInitialScroll = useRef(false);
|
|
162
|
+
const isAnimatingRef = useRef(false);
|
|
132
163
|
const readPosition = useCallback(() => {
|
|
133
164
|
const el = containerRef.current;
|
|
134
165
|
if (!el) return REVEAL_POSITION.center;
|
|
@@ -149,36 +180,112 @@ function RevealRowInner({
|
|
|
149
180
|
const closed = getScrollClosed(wL, wR, m, mode);
|
|
150
181
|
el.scrollLeft = closed;
|
|
151
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
|
+
);
|
|
152
228
|
useImperativeHandle(
|
|
153
229
|
forwardedRef,
|
|
154
230
|
() => ({
|
|
155
|
-
close: () => {
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
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);
|
|
162
250
|
},
|
|
163
|
-
reveal: (position) => {
|
|
251
|
+
reveal: (position, animated) => {
|
|
164
252
|
const el = containerRef.current;
|
|
165
253
|
if (!el) return;
|
|
166
254
|
const max = getMaxScroll(el);
|
|
255
|
+
let targetScroll;
|
|
167
256
|
if (position === REVEAL_POSITION.center) {
|
|
168
|
-
|
|
257
|
+
targetScroll = getScrollClosed(wL, wR, max, mode);
|
|
169
258
|
} else if (position === REVEAL_POSITION.left && (mode === REVEAL_MODE.left || mode === REVEAL_MODE.both)) {
|
|
170
|
-
|
|
259
|
+
targetScroll = 0;
|
|
171
260
|
} else if (position === REVEAL_POSITION.right && (mode === REVEAL_MODE.right || mode === REVEAL_MODE.both)) {
|
|
172
|
-
|
|
261
|
+
targetScroll = max;
|
|
173
262
|
} else {
|
|
174
263
|
return;
|
|
175
264
|
}
|
|
176
|
-
const
|
|
177
|
-
|
|
178
|
-
|
|
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);
|
|
179
277
|
}
|
|
180
278
|
}),
|
|
181
|
-
[
|
|
279
|
+
[
|
|
280
|
+
mode,
|
|
281
|
+
onRevealChange,
|
|
282
|
+
readPosition,
|
|
283
|
+
scrollToPosition,
|
|
284
|
+
wL,
|
|
285
|
+
wR,
|
|
286
|
+
animationPreset,
|
|
287
|
+
animationConfig
|
|
288
|
+
]
|
|
182
289
|
);
|
|
183
290
|
useLayoutEffect(() => {
|
|
184
291
|
if (mode === REVEAL_MODE.right) {
|
|
@@ -274,7 +381,12 @@ function RevealRowInner({
|
|
|
274
381
|
role: "presentation",
|
|
275
382
|
className: classNames.handleContainer,
|
|
276
383
|
"data-reveal-row-handle": true,
|
|
277
|
-
style: {
|
|
384
|
+
style: {
|
|
385
|
+
flexShrink: 0,
|
|
386
|
+
alignSelf: "stretch",
|
|
387
|
+
display: "flex",
|
|
388
|
+
alignItems: "center"
|
|
389
|
+
},
|
|
278
390
|
title: handleOverride === void 0 ? handleTitle : void 0,
|
|
279
391
|
children: handleContent
|
|
280
392
|
}
|
|
@@ -319,7 +431,7 @@ function RevealRowInner({
|
|
|
319
431
|
onScroll: handleScroll,
|
|
320
432
|
onClickCapture,
|
|
321
433
|
style: {
|
|
322
|
-
...rootScrollStyle,
|
|
434
|
+
...disabled ? rootScrollStyleDisabled : rootScrollStyle,
|
|
323
435
|
...style,
|
|
324
436
|
gridTemplateColumns
|
|
325
437
|
},
|
|
@@ -355,6 +467,8 @@ var RevealRow = forwardRef(
|
|
|
355
467
|
}
|
|
356
468
|
);
|
|
357
469
|
export {
|
|
470
|
+
ANIMATION_PRESET,
|
|
471
|
+
ANIMATION_PRESETS,
|
|
358
472
|
REVEAL_HANDLE_POSITION,
|
|
359
473
|
REVEAL_MODE,
|
|
360
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={{ flexShrink: 0, alignSelf: 'stretch', display: 'flex', alignItems: 'center' }}\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 <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"]}
|