@bug-on/m3-expressive 1.3.0 → 1.3.2
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/CHANGELOG.md +15 -0
- package/README.md +88 -60
- package/dist/buttons.d.mts +3 -3
- package/dist/buttons.d.ts +3 -3
- package/dist/buttons.js +185 -40
- package/dist/buttons.js.map +1 -1
- package/dist/buttons.mjs +186 -41
- package/dist/buttons.mjs.map +1 -1
- package/dist/{core-CAU8g2HY.d.mts → core-D8FdHY6I.d.mts} +1 -1
- package/dist/{core-DRrLnsnJ.d.ts → core-DyEy8H9Z.d.ts} +1 -1
- package/dist/core.d.mts +2 -2
- package/dist/core.d.ts +2 -2
- package/dist/core.js +156 -25
- package/dist/core.js.map +1 -1
- package/dist/core.mjs +157 -26
- package/dist/core.mjs.map +1 -1
- package/dist/feedback.d.mts +20 -0
- package/dist/feedback.d.ts +20 -0
- package/dist/feedback.js +157 -26
- package/dist/feedback.js.map +1 -1
- package/dist/feedback.mjs +158 -27
- package/dist/feedback.mjs.map +1 -1
- package/dist/forms.d.mts +4 -2
- package/dist/forms.d.ts +4 -2
- package/dist/forms.js +5065 -2980
- package/dist/forms.js.map +1 -1
- package/dist/forms.mjs +5064 -2982
- package/dist/forms.mjs.map +1 -1
- package/dist/{icon-button-USJo7AqO.d.mts → icon-button-CxyJv7UV.d.mts} +1 -1
- package/dist/{icon-button-CqdQBsRe.d.ts → icon-button-Di8VX6ou.d.ts} +1 -1
- package/dist/index.d.mts +12 -82
- package/dist/index.d.ts +12 -82
- package/dist/index.js +2875 -1226
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +2723 -1086
- package/dist/index.mjs.map +1 -1
- package/dist/layout.d.mts +481 -33
- package/dist/layout.d.ts +481 -33
- package/dist/layout.js +1653 -243
- package/dist/layout.js.map +1 -1
- package/dist/layout.mjs +1626 -232
- package/dist/layout.mjs.map +1 -1
- package/dist/{md3-D0_Z7IXj.d.mts → md3-BQhRygSi.d.mts} +1 -1
- package/dist/{md3-D0_Z7IXj.d.ts → md3-BQhRygSi.d.ts} +1 -1
- package/dist/menu-types-rZNQFO7Y.d.mts +315 -0
- package/dist/menu-types-rZNQFO7Y.d.ts +315 -0
- package/dist/navigation.d.mts +5 -289
- package/dist/navigation.d.ts +5 -289
- package/dist/navigation.js +575 -271
- package/dist/navigation.js.map +1 -1
- package/dist/navigation.mjs +568 -265
- package/dist/navigation.mjs.map +1 -1
- package/dist/overlays.d.mts +2 -2
- package/dist/overlays.d.ts +2 -2
- package/dist/overlays.js +156 -25
- package/dist/overlays.js.map +1 -1
- package/dist/overlays.mjs +157 -26
- package/dist/overlays.mjs.map +1 -1
- package/dist/pickers.js +156 -25
- package/dist/pickers.js.map +1 -1
- package/dist/pickers.mjs +157 -26
- package/dist/pickers.mjs.map +1 -1
- package/dist/{side-sheet-modal-Dgjt739k.d.mts → side-sheet-modal-64FGhDxL.d.mts} +1 -1
- package/dist/{side-sheet-modal-DdEZR6Vl.d.ts → side-sheet-modal-Bd5Qqvp9.d.ts} +1 -1
- package/dist/{split-button-trailing-uncheckable-26qlZvKT.d.mts → split-button-trailing-uncheckable-CGzk7KcG.d.ts} +3 -1
- package/dist/{split-button-trailing-uncheckable-CXUVrH64.d.ts → split-button-trailing-uncheckable-gAz6OAIi.d.mts} +3 -1
- package/dist/{text-field-DWC7qOvp.d.ts → text-field-4OlT9o8s.d.mts} +206 -55
- package/dist/{text-field-DWC7qOvp.d.mts → text-field-DARNdj14.d.ts} +206 -55
- package/package.json +3 -3
package/dist/layout.mjs
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { Slot } from '@radix-ui/react-slot';
|
|
3
3
|
import { cva } from 'class-variance-authority';
|
|
4
|
-
import { m, LazyMotion, domMax,
|
|
5
|
-
import * as
|
|
4
|
+
import { m, LazyMotion, domMax, useMotionValue, animate, useAnimationFrame, AnimatePresence, useReducedMotion } from 'motion/react';
|
|
5
|
+
import * as React23 from 'react';
|
|
6
6
|
import { createContext, useState, useCallback, useMemo, useEffect, useContext, createElement } from 'react';
|
|
7
7
|
import { clsx } from 'clsx';
|
|
8
8
|
import { twMerge } from 'tailwind-merge';
|
|
@@ -55,7 +55,7 @@ var __privateMethod = (obj, member, method) => (__accessCheck(obj, member, "acce
|
|
|
55
55
|
function cn(...inputs) {
|
|
56
56
|
return twMerge(clsx(inputs));
|
|
57
57
|
}
|
|
58
|
-
var RippleItem =
|
|
58
|
+
var RippleItem = React23.memo(function RippleItem2({
|
|
59
59
|
ripple,
|
|
60
60
|
onDone
|
|
61
61
|
}) {
|
|
@@ -99,8 +99,8 @@ function Ripple({
|
|
|
99
99
|
}
|
|
100
100
|
function useRippleState(options = {}) {
|
|
101
101
|
const { disabled = false } = options;
|
|
102
|
-
const [ripples, setRipples] =
|
|
103
|
-
const onPointerDown =
|
|
102
|
+
const [ripples, setRipples] = React23.useState([]);
|
|
103
|
+
const onPointerDown = React23.useCallback(
|
|
104
104
|
(e) => {
|
|
105
105
|
if (disabled) return;
|
|
106
106
|
const rect = e.currentTarget.getBoundingClientRect();
|
|
@@ -117,21 +117,36 @@ function useRippleState(options = {}) {
|
|
|
117
117
|
},
|
|
118
118
|
[disabled]
|
|
119
119
|
);
|
|
120
|
-
const removeRipple =
|
|
120
|
+
const removeRipple = React23.useCallback((id) => {
|
|
121
121
|
setRipples((prev) => prev.filter((r) => r.id !== id));
|
|
122
122
|
}, []);
|
|
123
123
|
return { ripples, onPointerDown, removeRipple };
|
|
124
124
|
}
|
|
125
|
+
|
|
126
|
+
// src/ui/cards/card/card-tokens.ts
|
|
125
127
|
var SHADOW = {
|
|
126
128
|
level0: "none",
|
|
127
129
|
level1: "0px 1px 2px 0px rgba(0,0,0,.3), 0px 1px 3px 1px rgba(0,0,0,.15)",
|
|
128
|
-
level2: "0px 1px 2px 0px rgba(0,0,0,.3), 0px 2px 6px 2px rgba(0,0,0,.15)"
|
|
130
|
+
level2: "0px 1px 2px 0px rgba(0,0,0,.3), 0px 2px 6px 2px rgba(0,0,0,.15)",
|
|
131
|
+
level3: "0px 4px 8px 3px rgba(0,0,0,.15), 0px 1px 3px 0px rgba(0,0,0,.3)",
|
|
132
|
+
level4: "0px 6px 10px 4px rgba(0,0,0,.15), 0px 2px 3px 0px rgba(0,0,0,.3)",
|
|
133
|
+
level5: "0px 8px 12px 6px rgba(0,0,0,.15), 0px 4px 4px 0px rgba(0,0,0,.3)"
|
|
129
134
|
};
|
|
135
|
+
function resolveElevationShadow(level) {
|
|
136
|
+
var _a;
|
|
137
|
+
if (level === void 0) return void 0;
|
|
138
|
+
if (typeof level === "number") {
|
|
139
|
+
const key = `level${level}`;
|
|
140
|
+
return (_a = SHADOW[key]) != null ? _a : SHADOW.level0;
|
|
141
|
+
}
|
|
142
|
+
return level;
|
|
143
|
+
}
|
|
130
144
|
var VARIANT_ELEVATION = {
|
|
131
145
|
elevated: {
|
|
132
146
|
rest: SHADOW.level1,
|
|
133
147
|
hover: SHADOW.level2,
|
|
134
148
|
pressed: SHADOW.level1,
|
|
149
|
+
dragged: SHADOW.level3,
|
|
135
150
|
disabled: SHADOW.level1
|
|
136
151
|
// ElevatedCardTokens.DisabledContainerElevation = Level1
|
|
137
152
|
},
|
|
@@ -139,78 +154,177 @@ var VARIANT_ELEVATION = {
|
|
|
139
154
|
rest: SHADOW.level0,
|
|
140
155
|
hover: SHADOW.level1,
|
|
141
156
|
pressed: SHADOW.level0,
|
|
157
|
+
dragged: SHADOW.level3,
|
|
142
158
|
disabled: SHADOW.level0
|
|
143
159
|
},
|
|
144
160
|
outlined: {
|
|
145
161
|
rest: SHADOW.level0,
|
|
146
162
|
hover: SHADOW.level1,
|
|
147
163
|
pressed: SHADOW.level0,
|
|
164
|
+
dragged: SHADOW.level3,
|
|
148
165
|
disabled: SHADOW.level0
|
|
149
166
|
}
|
|
150
167
|
};
|
|
168
|
+
function useCardElevation({
|
|
169
|
+
variant = "elevated",
|
|
170
|
+
disabled = false,
|
|
171
|
+
draggable = false,
|
|
172
|
+
elevation,
|
|
173
|
+
disableElevation = false,
|
|
174
|
+
hoverEffect = true
|
|
175
|
+
}) {
|
|
176
|
+
var _a, _b, _c, _d, _e, _f, _g;
|
|
177
|
+
const defaultLevels = VARIANT_ELEVATION[variant] || VARIANT_ELEVATION.elevated;
|
|
178
|
+
let restShadow = defaultLevels.rest;
|
|
179
|
+
let hoverShadow = defaultLevels.hover;
|
|
180
|
+
let pressedShadow = defaultLevels.pressed;
|
|
181
|
+
let draggedShadow = defaultLevels.dragged;
|
|
182
|
+
if (disableElevation) {
|
|
183
|
+
restShadow = SHADOW.level0;
|
|
184
|
+
hoverShadow = SHADOW.level0;
|
|
185
|
+
pressedShadow = SHADOW.level0;
|
|
186
|
+
draggedShadow = SHADOW.level0;
|
|
187
|
+
} else if (typeof elevation === "number") {
|
|
188
|
+
const resolved = (_a = resolveElevationShadow(elevation)) != null ? _a : SHADOW.level0;
|
|
189
|
+
restShadow = resolved;
|
|
190
|
+
const hoverLevel = hoverEffect ? Math.min(elevation + 1, 5) : elevation;
|
|
191
|
+
hoverShadow = (_b = resolveElevationShadow(hoverLevel)) != null ? _b : resolved;
|
|
192
|
+
pressedShadow = resolved;
|
|
193
|
+
draggedShadow = (_c = resolveElevationShadow(
|
|
194
|
+
Math.min(elevation + 2, 5)
|
|
195
|
+
)) != null ? _c : resolved;
|
|
196
|
+
} else if (elevation && typeof elevation === "object") {
|
|
197
|
+
if (elevation.rest !== void 0) {
|
|
198
|
+
restShadow = (_d = resolveElevationShadow(elevation.rest)) != null ? _d : restShadow;
|
|
199
|
+
}
|
|
200
|
+
if (elevation.hover !== void 0) {
|
|
201
|
+
hoverShadow = (_e = resolveElevationShadow(elevation.hover)) != null ? _e : hoverShadow;
|
|
202
|
+
}
|
|
203
|
+
if (elevation.pressed !== void 0) {
|
|
204
|
+
pressedShadow = (_f = resolveElevationShadow(elevation.pressed)) != null ? _f : pressedShadow;
|
|
205
|
+
}
|
|
206
|
+
if (elevation.dragged !== void 0) {
|
|
207
|
+
draggedShadow = (_g = resolveElevationShadow(elevation.dragged)) != null ? _g : draggedShadow;
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
if (!hoverEffect) {
|
|
211
|
+
hoverShadow = restShadow;
|
|
212
|
+
}
|
|
213
|
+
const animateShadow = disabled ? disableElevation ? SHADOW.level0 : defaultLevels.disabled : restShadow;
|
|
214
|
+
return {
|
|
215
|
+
animate: { boxShadow: animateShadow },
|
|
216
|
+
whileHover: disabled || !hoverEffect ? void 0 : { boxShadow: hoverShadow },
|
|
217
|
+
whileTap: disabled ? void 0 : { boxShadow: pressedShadow },
|
|
218
|
+
whileFocus: disabled || !hoverEffect ? void 0 : { boxShadow: hoverShadow },
|
|
219
|
+
whileDrag: !disabled && draggable ? { boxShadow: draggedShadow } : void 0,
|
|
220
|
+
transition: {
|
|
221
|
+
boxShadow: {
|
|
222
|
+
// Incoming: 120ms (from Elevation.kt DefaultIncomingSpec)
|
|
223
|
+
duration: 0.12,
|
|
224
|
+
ease: [0.4, 0, 0.2, 1]
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
};
|
|
228
|
+
}
|
|
151
229
|
var cardVariants = cva(
|
|
152
|
-
"rounded-m3-lg flex flex-col relative overflow-hidden transition-
|
|
230
|
+
"rounded-m3-lg flex flex-col relative overflow-hidden transition-all duration-200",
|
|
153
231
|
{
|
|
154
232
|
variants: {
|
|
155
233
|
variant: {
|
|
156
234
|
// ElevatedCardTokens.ContainerColor = SurfaceContainerLow
|
|
157
|
-
elevated: "bg-m3-surface-container-low",
|
|
235
|
+
elevated: "bg-m3-surface-container-low text-m3-on-surface",
|
|
158
236
|
// FilledCardTokens.ContainerColor = SurfaceContainerHighest
|
|
159
|
-
filled: "bg-m3-surface-container-highest",
|
|
237
|
+
filled: "bg-m3-surface-container-highest text-m3-on-surface",
|
|
160
238
|
// OutlinedCardTokens.ContainerColor = Surface, OutlineColor = OutlineVariant
|
|
161
|
-
outlined: "bg-m3-surface border border-m3-outline-variant"
|
|
239
|
+
outlined: "bg-m3-surface text-m3-on-surface border border-m3-outline-variant"
|
|
162
240
|
}
|
|
163
241
|
},
|
|
164
242
|
defaultVariants: { variant: "elevated" }
|
|
165
243
|
}
|
|
166
244
|
);
|
|
167
|
-
|
|
168
|
-
const levels = VARIANT_ELEVATION[variant];
|
|
169
|
-
return {
|
|
170
|
-
animate: { boxShadow: disabled ? levels.disabled : levels.rest },
|
|
171
|
-
whileHover: disabled ? void 0 : { boxShadow: levels.hover },
|
|
172
|
-
whileTap: disabled ? void 0 : { boxShadow: levels.pressed },
|
|
173
|
-
whileFocus: disabled ? void 0 : { boxShadow: levels.hover },
|
|
174
|
-
transition: {
|
|
175
|
-
boxShadow: {
|
|
176
|
-
// Incoming: 120ms (from Elevation.kt DefaultIncomingSpec)
|
|
177
|
-
duration: 0.12,
|
|
178
|
-
ease: [0.4, 0, 0.2, 1]
|
|
179
|
-
}
|
|
180
|
-
}
|
|
181
|
-
};
|
|
182
|
-
}
|
|
183
|
-
var CardImpl = React18.forwardRef(
|
|
245
|
+
var CardImpl = React23.forwardRef(
|
|
184
246
|
(_a, ref) => {
|
|
185
247
|
var _b = _a, {
|
|
186
248
|
className,
|
|
187
249
|
variant = "elevated",
|
|
250
|
+
elevation,
|
|
251
|
+
disableElevation = false,
|
|
252
|
+
ripple = true,
|
|
253
|
+
disableRipple = false,
|
|
254
|
+
hoverEffect = true,
|
|
255
|
+
disableHoverEffect = false,
|
|
256
|
+
stateLayer = true,
|
|
257
|
+
disableStateLayer = false,
|
|
188
258
|
disabled = false,
|
|
189
259
|
interactive = false,
|
|
260
|
+
draggable = false,
|
|
190
261
|
href,
|
|
191
262
|
target,
|
|
192
263
|
rel: relProp,
|
|
193
264
|
onClick,
|
|
265
|
+
onPointerDown: userOnPointerDown,
|
|
266
|
+
whileHover,
|
|
267
|
+
whileTap,
|
|
268
|
+
whileFocus,
|
|
269
|
+
whileDrag,
|
|
270
|
+
transition,
|
|
194
271
|
asChild = false,
|
|
195
272
|
children
|
|
196
273
|
} = _b, props = __objRest(_b, [
|
|
197
274
|
"className",
|
|
198
275
|
"variant",
|
|
276
|
+
"elevation",
|
|
277
|
+
"disableElevation",
|
|
278
|
+
"ripple",
|
|
279
|
+
"disableRipple",
|
|
280
|
+
"hoverEffect",
|
|
281
|
+
"disableHoverEffect",
|
|
282
|
+
"stateLayer",
|
|
283
|
+
"disableStateLayer",
|
|
199
284
|
"disabled",
|
|
200
285
|
"interactive",
|
|
286
|
+
"draggable",
|
|
201
287
|
"href",
|
|
202
288
|
"target",
|
|
203
289
|
"rel",
|
|
204
290
|
"onClick",
|
|
291
|
+
"onPointerDown",
|
|
292
|
+
"whileHover",
|
|
293
|
+
"whileTap",
|
|
294
|
+
"whileFocus",
|
|
295
|
+
"whileDrag",
|
|
296
|
+
"transition",
|
|
205
297
|
"asChild",
|
|
206
298
|
"children"
|
|
207
299
|
]);
|
|
208
|
-
const safeVariant = variant;
|
|
300
|
+
const safeVariant = variant || "elevated";
|
|
209
301
|
const isInteractive = !!onClick || !!href || interactive || asChild;
|
|
210
|
-
const
|
|
211
|
-
const
|
|
302
|
+
const isHoverEnabled = hoverEffect !== false && !disableHoverEffect;
|
|
303
|
+
const isRippleEnabled = ripple !== false && !disableRipple && isInteractive && !disabled;
|
|
304
|
+
const isStateLayerEnabled = stateLayer !== false && !disableStateLayer && isInteractive && !disabled;
|
|
305
|
+
const elevationProps = useCardElevation({
|
|
306
|
+
variant: safeVariant,
|
|
307
|
+
disabled,
|
|
308
|
+
draggable,
|
|
309
|
+
elevation,
|
|
310
|
+
disableElevation,
|
|
311
|
+
hoverEffect: isHoverEnabled
|
|
312
|
+
});
|
|
313
|
+
const {
|
|
314
|
+
ripples,
|
|
315
|
+
onPointerDown: rippleOnPointerDown,
|
|
316
|
+
removeRipple
|
|
317
|
+
} = useRippleState();
|
|
318
|
+
const handlePointerDown = (event) => {
|
|
319
|
+
if (isRippleEnabled) {
|
|
320
|
+
rippleOnPointerDown(event);
|
|
321
|
+
}
|
|
322
|
+
userOnPointerDown == null ? void 0 : userOnPointerDown(
|
|
323
|
+
event
|
|
324
|
+
);
|
|
325
|
+
};
|
|
212
326
|
const baseClass = cn(
|
|
213
|
-
cardVariants({ variant }),
|
|
327
|
+
cardVariants({ variant: safeVariant }),
|
|
214
328
|
// Disabled state:
|
|
215
329
|
// - pointer-events-none → disable interactions completely
|
|
216
330
|
// - opacity-[0.38] → MD3 DisabledContainerOpacity
|
|
@@ -220,17 +334,25 @@ var CardImpl = React18.forwardRef(
|
|
|
220
334
|
const interactiveClass = cn(
|
|
221
335
|
// Remove default outline, use MD3 state overlay & elevation for focus
|
|
222
336
|
"focus-visible:outline-none focus:outline-none group",
|
|
223
|
-
// Base pseudo-element overlay layer
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
337
|
+
// Base pseudo-element overlay layer (when stateLayer is enabled)
|
|
338
|
+
isStateLayerEnabled && [
|
|
339
|
+
"before:absolute before:inset-0 before:pointer-events-none before:bg-m3-on-surface before:opacity-0 before:transition-opacity before:duration-200",
|
|
340
|
+
isHoverEnabled && "hover:before:opacity-[0.08]",
|
|
341
|
+
"focus-visible:before:opacity-[0.10] active:before:opacity-[0.10]",
|
|
342
|
+
draggable && "active:before:opacity-[0.16]"
|
|
343
|
+
],
|
|
344
|
+
// Outlined interactive card: smooth transition of border color to m3-outline on hover/focus/press
|
|
345
|
+
safeVariant === "outlined" && "transition-colors duration-200 hover:border-m3-outline focus-visible:border-m3-outline active:border-m3-outline"
|
|
229
346
|
);
|
|
347
|
+
const mergedWhileHover = elevationProps.whileHover || whileHover ? __spreadValues(__spreadValues({}, elevationProps.whileHover), typeof whileHover === "object" ? whileHover : {}) : void 0;
|
|
348
|
+
const mergedWhileTap = elevationProps.whileTap || whileTap ? __spreadValues(__spreadValues({}, elevationProps.whileTap), typeof whileTap === "object" ? whileTap : {}) : void 0;
|
|
349
|
+
const mergedWhileFocus = elevationProps.whileFocus || whileFocus ? __spreadValues(__spreadValues({}, elevationProps.whileFocus), typeof whileFocus === "object" ? whileFocus : {}) : void 0;
|
|
350
|
+
const mergedWhileDrag = elevationProps.whileDrag || whileDrag ? __spreadValues(__spreadValues({}, elevationProps.whileDrag), typeof whileDrag === "object" ? whileDrag : {}) : void 0;
|
|
351
|
+
const mergedTransition = elevationProps.transition || transition ? __spreadValues(__spreadValues({}, elevationProps.transition), typeof transition === "object" ? transition : {}) : void 0;
|
|
230
352
|
if (asChild) {
|
|
231
|
-
const child =
|
|
353
|
+
const child = React23.Children.only(children);
|
|
232
354
|
const innerContent = /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
233
|
-
/* @__PURE__ */ jsx(Ripple, { ripples, onRippleDone: removeRipple }),
|
|
355
|
+
isRippleEnabled && /* @__PURE__ */ jsx(Ripple, { ripples, onRippleDone: removeRipple }),
|
|
234
356
|
child.props.children
|
|
235
357
|
] });
|
|
236
358
|
return /* @__PURE__ */ jsx(LazyMotion, { features: domMax, strict: true, children: /* @__PURE__ */ jsx(
|
|
@@ -240,22 +362,26 @@ var CardImpl = React18.forwardRef(
|
|
|
240
362
|
className: cn(baseClass, interactiveClass),
|
|
241
363
|
"aria-disabled": disabled ? true : void 0,
|
|
242
364
|
tabIndex: disabled ? -1 : 0,
|
|
243
|
-
onPointerDown,
|
|
365
|
+
onPointerDown: handlePointerDown,
|
|
244
366
|
onClick
|
|
245
367
|
}, props), {
|
|
246
|
-
children:
|
|
368
|
+
children: React23.cloneElement(child, { children: innerContent })
|
|
247
369
|
})
|
|
248
370
|
) });
|
|
249
371
|
}
|
|
250
372
|
if (!isInteractive) {
|
|
251
373
|
return /* @__PURE__ */ jsx(
|
|
252
374
|
"div",
|
|
253
|
-
{
|
|
375
|
+
__spreadProps(__spreadValues({
|
|
254
376
|
ref,
|
|
255
377
|
className: baseClass,
|
|
256
|
-
|
|
378
|
+
style: __spreadValues({
|
|
379
|
+
boxShadow: elevationProps.animate.boxShadow
|
|
380
|
+
}, props.style || {}),
|
|
381
|
+
"aria-disabled": disabled ? true : void 0
|
|
382
|
+
}, props), {
|
|
257
383
|
children
|
|
258
|
-
}
|
|
384
|
+
})
|
|
259
385
|
);
|
|
260
386
|
}
|
|
261
387
|
const safeRel = href ? relProp != null ? relProp : target === "_blank" ? "noreferrer" : void 0 : void 0;
|
|
@@ -270,10 +396,16 @@ var CardImpl = React18.forwardRef(
|
|
|
270
396
|
className: cn(baseClass, interactiveClass),
|
|
271
397
|
"aria-disabled": disabled ? true : void 0,
|
|
272
398
|
tabIndex: disabled ? -1 : 0,
|
|
273
|
-
onPointerDown
|
|
274
|
-
|
|
399
|
+
onPointerDown: handlePointerDown,
|
|
400
|
+
animate: elevationProps.animate,
|
|
401
|
+
whileHover: mergedWhileHover,
|
|
402
|
+
whileTap: mergedWhileTap,
|
|
403
|
+
whileFocus: mergedWhileFocus,
|
|
404
|
+
whileDrag: mergedWhileDrag,
|
|
405
|
+
transition: mergedTransition
|
|
406
|
+
}, props), {
|
|
275
407
|
children: [
|
|
276
|
-
/* @__PURE__ */ jsx(Ripple, { ripples, onRippleDone: removeRipple }),
|
|
408
|
+
isRippleEnabled && /* @__PURE__ */ jsx(Ripple, { ripples, onRippleDone: removeRipple }),
|
|
277
409
|
children
|
|
278
410
|
]
|
|
279
411
|
})
|
|
@@ -281,7 +413,7 @@ var CardImpl = React18.forwardRef(
|
|
|
281
413
|
}
|
|
282
414
|
return /* @__PURE__ */ jsx(LazyMotion, { features: domMax, strict: true, children: /* @__PURE__ */ jsxs(
|
|
283
415
|
m.button,
|
|
284
|
-
__spreadProps(__spreadValues(
|
|
416
|
+
__spreadProps(__spreadValues({
|
|
285
417
|
ref,
|
|
286
418
|
type: "button",
|
|
287
419
|
disabled,
|
|
@@ -289,10 +421,16 @@ var CardImpl = React18.forwardRef(
|
|
|
289
421
|
className: cn(baseClass, interactiveClass),
|
|
290
422
|
"aria-disabled": disabled ? true : void 0,
|
|
291
423
|
tabIndex: disabled ? -1 : 0,
|
|
292
|
-
onPointerDown
|
|
293
|
-
|
|
424
|
+
onPointerDown: handlePointerDown,
|
|
425
|
+
animate: elevationProps.animate,
|
|
426
|
+
whileHover: mergedWhileHover,
|
|
427
|
+
whileTap: mergedWhileTap,
|
|
428
|
+
whileFocus: mergedWhileFocus,
|
|
429
|
+
whileDrag: mergedWhileDrag,
|
|
430
|
+
transition: mergedTransition
|
|
431
|
+
}, props), {
|
|
294
432
|
children: [
|
|
295
|
-
/* @__PURE__ */ jsx(Ripple, { ripples, onRippleDone: removeRipple }),
|
|
433
|
+
isRippleEnabled && /* @__PURE__ */ jsx(Ripple, { ripples, onRippleDone: removeRipple }),
|
|
296
434
|
children
|
|
297
435
|
]
|
|
298
436
|
})
|
|
@@ -300,7 +438,1132 @@ var CardImpl = React18.forwardRef(
|
|
|
300
438
|
}
|
|
301
439
|
);
|
|
302
440
|
CardImpl.displayName = "Card";
|
|
303
|
-
var Card =
|
|
441
|
+
var Card = React23.memo(CardImpl);
|
|
442
|
+
var CardHeader = React23.forwardRef(
|
|
443
|
+
(_a, ref) => {
|
|
444
|
+
var _b = _a, { className, avatar, title, subheader, action, children } = _b, props = __objRest(_b, ["className", "avatar", "title", "subheader", "action", "children"]);
|
|
445
|
+
return /* @__PURE__ */ jsxs(
|
|
446
|
+
"div",
|
|
447
|
+
__spreadProps(__spreadValues({
|
|
448
|
+
ref,
|
|
449
|
+
className: cn(
|
|
450
|
+
"flex items-center gap-4 px-6 pt-6 pb-2 relative z-1",
|
|
451
|
+
className
|
|
452
|
+
)
|
|
453
|
+
}, props), {
|
|
454
|
+
children: [
|
|
455
|
+
avatar && /* @__PURE__ */ jsx("div", { className: "shrink-0 flex items-center", children: avatar }),
|
|
456
|
+
title || subheader ? /* @__PURE__ */ jsxs("div", { className: "flex-1 min-w-0", children: [
|
|
457
|
+
title && /* @__PURE__ */ jsx("div", { className: "text-base font-medium text-m3-on-surface truncate", children: title }),
|
|
458
|
+
subheader && /* @__PURE__ */ jsx("div", { className: "text-sm text-m3-on-surface-variant truncate", children: subheader })
|
|
459
|
+
] }) : null,
|
|
460
|
+
children,
|
|
461
|
+
action && /* @__PURE__ */ jsx("div", { className: "shrink-0 ml-auto flex items-center", children: action })
|
|
462
|
+
]
|
|
463
|
+
})
|
|
464
|
+
);
|
|
465
|
+
}
|
|
466
|
+
);
|
|
467
|
+
CardHeader.displayName = "CardHeader";
|
|
468
|
+
var ASPECT_RATIO_CLASSES = {
|
|
469
|
+
video: "aspect-video",
|
|
470
|
+
square: "aspect-square",
|
|
471
|
+
wide: "aspect-[21/9]",
|
|
472
|
+
auto: ""
|
|
473
|
+
};
|
|
474
|
+
var CardMedia = React23.forwardRef(
|
|
475
|
+
(_a, ref) => {
|
|
476
|
+
var _b = _a, {
|
|
477
|
+
className,
|
|
478
|
+
src,
|
|
479
|
+
alt = "",
|
|
480
|
+
aspectRatio = "video",
|
|
481
|
+
component,
|
|
482
|
+
children
|
|
483
|
+
} = _b, props = __objRest(_b, [
|
|
484
|
+
"className",
|
|
485
|
+
"src",
|
|
486
|
+
"alt",
|
|
487
|
+
"aspectRatio",
|
|
488
|
+
"component",
|
|
489
|
+
"children"
|
|
490
|
+
]);
|
|
491
|
+
const ratioClass = aspectRatio in ASPECT_RATIO_CLASSES ? ASPECT_RATIO_CLASSES[aspectRatio] : "";
|
|
492
|
+
const Component = component || (src && !children ? "img" : "div");
|
|
493
|
+
return /* @__PURE__ */ jsx(
|
|
494
|
+
"div",
|
|
495
|
+
__spreadProps(__spreadValues({
|
|
496
|
+
ref,
|
|
497
|
+
className: cn(
|
|
498
|
+
"relative w-full overflow-hidden shrink-0",
|
|
499
|
+
ratioClass,
|
|
500
|
+
className
|
|
501
|
+
)
|
|
502
|
+
}, props), {
|
|
503
|
+
children: children ? children : src ? /* @__PURE__ */ jsx(
|
|
504
|
+
Component,
|
|
505
|
+
{
|
|
506
|
+
src,
|
|
507
|
+
alt,
|
|
508
|
+
className: "w-full h-full object-cover"
|
|
509
|
+
}
|
|
510
|
+
) : null
|
|
511
|
+
})
|
|
512
|
+
);
|
|
513
|
+
}
|
|
514
|
+
);
|
|
515
|
+
CardMedia.displayName = "CardMedia";
|
|
516
|
+
var CardContent = React23.forwardRef(
|
|
517
|
+
(_a, ref) => {
|
|
518
|
+
var _b = _a, { className, children } = _b, props = __objRest(_b, ["className", "children"]);
|
|
519
|
+
return /* @__PURE__ */ jsx(
|
|
520
|
+
"div",
|
|
521
|
+
__spreadProps(__spreadValues({
|
|
522
|
+
ref,
|
|
523
|
+
className: cn(
|
|
524
|
+
"px-6 py-4 text-sm text-m3-on-surface-variant flex-1 relative z-1",
|
|
525
|
+
className
|
|
526
|
+
)
|
|
527
|
+
}, props), {
|
|
528
|
+
children
|
|
529
|
+
})
|
|
530
|
+
);
|
|
531
|
+
}
|
|
532
|
+
);
|
|
533
|
+
CardContent.displayName = "CardContent";
|
|
534
|
+
var ALIGN_CLASSES = {
|
|
535
|
+
start: "justify-start",
|
|
536
|
+
center: "justify-center",
|
|
537
|
+
end: "justify-end",
|
|
538
|
+
between: "justify-between"
|
|
539
|
+
};
|
|
540
|
+
var CardFooter = React23.forwardRef(
|
|
541
|
+
(_a, ref) => {
|
|
542
|
+
var _b = _a, { className, align = "end", children } = _b, props = __objRest(_b, ["className", "align", "children"]);
|
|
543
|
+
return /* @__PURE__ */ jsx(
|
|
544
|
+
"div",
|
|
545
|
+
__spreadProps(__spreadValues({
|
|
546
|
+
ref,
|
|
547
|
+
className: cn(
|
|
548
|
+
"flex items-center gap-2 px-6 pb-6 pt-2 relative z-1",
|
|
549
|
+
ALIGN_CLASSES[align],
|
|
550
|
+
className
|
|
551
|
+
)
|
|
552
|
+
}, props), {
|
|
553
|
+
children
|
|
554
|
+
})
|
|
555
|
+
);
|
|
556
|
+
}
|
|
557
|
+
);
|
|
558
|
+
CardFooter.displayName = "CardFooter";
|
|
559
|
+
function CarouselGrid(_a) {
|
|
560
|
+
var _b = _a, {
|
|
561
|
+
children,
|
|
562
|
+
items,
|
|
563
|
+
renderItem,
|
|
564
|
+
preferredItemWidth = 240,
|
|
565
|
+
className,
|
|
566
|
+
style
|
|
567
|
+
} = _b, props = __objRest(_b, [
|
|
568
|
+
"children",
|
|
569
|
+
"items",
|
|
570
|
+
"renderItem",
|
|
571
|
+
"preferredItemWidth",
|
|
572
|
+
"className",
|
|
573
|
+
"style"
|
|
574
|
+
]);
|
|
575
|
+
const gridStyle = __spreadValues({
|
|
576
|
+
display: "grid",
|
|
577
|
+
gridTemplateColumns: `repeat(auto-fill, minmax(${preferredItemWidth}px, 1fr))`,
|
|
578
|
+
gap: "8px",
|
|
579
|
+
padding: "8px 16px",
|
|
580
|
+
width: "100%",
|
|
581
|
+
boxSizing: "border-box"
|
|
582
|
+
}, style);
|
|
583
|
+
const itemStyle = {
|
|
584
|
+
position: "relative",
|
|
585
|
+
width: "100%",
|
|
586
|
+
minHeight: "180px",
|
|
587
|
+
borderRadius: "28px",
|
|
588
|
+
overflow: "hidden"
|
|
589
|
+
};
|
|
590
|
+
if (items && renderItem) {
|
|
591
|
+
return /* @__PURE__ */ jsx(
|
|
592
|
+
"section",
|
|
593
|
+
__spreadProps(__spreadValues({
|
|
594
|
+
className,
|
|
595
|
+
style: gridStyle,
|
|
596
|
+
"aria-label": "Expanded carousel grid"
|
|
597
|
+
}, props), {
|
|
598
|
+
children: items.map((item, index) => {
|
|
599
|
+
const itemKey = typeof item === "object" && item !== null && "id" in item ? item.id : typeof item === "object" && item !== null && "key" in item ? item.key : index;
|
|
600
|
+
return /* @__PURE__ */ jsx("div", { style: itemStyle, children: renderItem(item, index) }, itemKey);
|
|
601
|
+
})
|
|
602
|
+
})
|
|
603
|
+
);
|
|
604
|
+
}
|
|
605
|
+
return /* @__PURE__ */ jsx(
|
|
606
|
+
"section",
|
|
607
|
+
__spreadProps(__spreadValues({
|
|
608
|
+
className,
|
|
609
|
+
style: gridStyle,
|
|
610
|
+
"aria-label": "Expanded carousel grid"
|
|
611
|
+
}, props), {
|
|
612
|
+
children: React23.Children.map(children, (child, index) => {
|
|
613
|
+
const childKey = React23.isValidElement(child) && child.key != null ? child.key : index;
|
|
614
|
+
return /* @__PURE__ */ jsx("div", { style: itemStyle, children: child }, childKey);
|
|
615
|
+
})
|
|
616
|
+
})
|
|
617
|
+
);
|
|
618
|
+
}
|
|
619
|
+
var CarouselItem = React23.forwardRef(
|
|
620
|
+
function CarouselItem2(_a, ref) {
|
|
621
|
+
var _b = _a, {
|
|
622
|
+
index,
|
|
623
|
+
totalItems,
|
|
624
|
+
layout = "multi-browse",
|
|
625
|
+
width,
|
|
626
|
+
minContentWidth,
|
|
627
|
+
maskClipPercent = 0,
|
|
628
|
+
parallaxOffset = 0,
|
|
629
|
+
isFocused = false,
|
|
630
|
+
isScrolling = false,
|
|
631
|
+
disabled = false,
|
|
632
|
+
className,
|
|
633
|
+
style,
|
|
634
|
+
children,
|
|
635
|
+
onClick,
|
|
636
|
+
onPointerDown
|
|
637
|
+
} = _b, props = __objRest(_b, [
|
|
638
|
+
"index",
|
|
639
|
+
"totalItems",
|
|
640
|
+
"layout",
|
|
641
|
+
"width",
|
|
642
|
+
"minContentWidth",
|
|
643
|
+
"maskClipPercent",
|
|
644
|
+
"parallaxOffset",
|
|
645
|
+
"isFocused",
|
|
646
|
+
"isScrolling",
|
|
647
|
+
"disabled",
|
|
648
|
+
"className",
|
|
649
|
+
"style",
|
|
650
|
+
"children",
|
|
651
|
+
"onClick",
|
|
652
|
+
"onPointerDown"
|
|
653
|
+
]);
|
|
654
|
+
const {
|
|
655
|
+
ripples,
|
|
656
|
+
onPointerDown: handleRipplePointerDown,
|
|
657
|
+
removeRipple
|
|
658
|
+
} = useRippleState();
|
|
659
|
+
const itemNumber = index + 1;
|
|
660
|
+
const ariaLabel = props["aria-label"] || `Item ${itemNumber} of ${totalItems}`;
|
|
661
|
+
const isFullScreen = layout === "full-screen";
|
|
662
|
+
const isCenterHero = layout === "center-aligned-hero";
|
|
663
|
+
const combinedStyle = __spreadValues({
|
|
664
|
+
width: isFullScreen ? "100%" : width ? `${width}px` : void 0,
|
|
665
|
+
height: isFullScreen ? "100%" : void 0,
|
|
666
|
+
flexShrink: 0
|
|
667
|
+
}, style);
|
|
668
|
+
const handlePointerDown = (e) => {
|
|
669
|
+
if (!disabled) {
|
|
670
|
+
handleRipplePointerDown(e);
|
|
671
|
+
}
|
|
672
|
+
onPointerDown == null ? void 0 : onPointerDown(e);
|
|
673
|
+
};
|
|
674
|
+
const handleKeyDown = (e) => {
|
|
675
|
+
var _a2;
|
|
676
|
+
if (!disabled && (e.key === "Enter" || e.key === " ")) {
|
|
677
|
+
e.preventDefault();
|
|
678
|
+
onClick == null ? void 0 : onClick(e);
|
|
679
|
+
}
|
|
680
|
+
(_a2 = props.onKeyDown) == null ? void 0 : _a2.call(props, e);
|
|
681
|
+
};
|
|
682
|
+
return (
|
|
683
|
+
// biome-ignore lint/a11y/useSemanticElements: ARIA carousel pattern requires role="group" for slide items
|
|
684
|
+
/* @__PURE__ */ jsxs(
|
|
685
|
+
"div",
|
|
686
|
+
__spreadProps(__spreadValues({
|
|
687
|
+
ref,
|
|
688
|
+
role: "group",
|
|
689
|
+
"aria-roledescription": "slide",
|
|
690
|
+
"aria-label": ariaLabel,
|
|
691
|
+
tabIndex: disabled ? -1 : isFocused ? 0 : -1,
|
|
692
|
+
className: cn(
|
|
693
|
+
// Base item styles: overflow-hidden + rounded 28px acts as MD3 keyline mask
|
|
694
|
+
"relative flex flex-col overflow-hidden rounded-[28px] cursor-pointer select-none box-border outline-none shrink-0",
|
|
695
|
+
// GPU Composition & Layout Containment
|
|
696
|
+
"will-change-[transform,clip-path] contain-[layout_paint_style] [user-select:none] [-webkit-user-drag:none] [&_img]:pointer-events-none [&_img]:select-none [&_img]:[-webkit-user-drag:none]",
|
|
697
|
+
// Scroll snap: center-aligned hero snaps to center, all others snap start
|
|
698
|
+
isCenterHero ? "snap-center" : "snap-start",
|
|
699
|
+
// Full-screen: no rounding, fill height
|
|
700
|
+
isFullScreen && "rounded-none",
|
|
701
|
+
// State layers via ::after pseudo-element
|
|
702
|
+
"after:absolute after:inset-0 after:rounded-[inherit] after:bg-black after:opacity-0 after:pointer-events-none after:z-2 after:transition-opacity after:duration-150 after:motion-reduce:transition-none",
|
|
703
|
+
"hover:after:opacity-[0.08]",
|
|
704
|
+
"active:after:opacity-[0.10]",
|
|
705
|
+
// Focus ring
|
|
706
|
+
"focus-visible:outline-[3px] focus-visible:outline-(--md-sys-color-secondary,#625b71) focus-visible:outline-offset-2 focus-visible:z-3",
|
|
707
|
+
// Disabled
|
|
708
|
+
disabled && "opacity-[0.38] pointer-events-none",
|
|
709
|
+
className
|
|
710
|
+
),
|
|
711
|
+
style: combinedStyle,
|
|
712
|
+
onPointerDown: handlePointerDown,
|
|
713
|
+
onKeyDown: handleKeyDown,
|
|
714
|
+
onClick: disabled ? void 0 : onClick
|
|
715
|
+
}, props), {
|
|
716
|
+
children: [
|
|
717
|
+
/* @__PURE__ */ jsx(
|
|
718
|
+
"div",
|
|
719
|
+
{
|
|
720
|
+
className: "w-full flex-1 flex flex-col will-change-transform select-none",
|
|
721
|
+
style: {
|
|
722
|
+
width: isFullScreen ? "100%" : minContentWidth ? `${minContentWidth}px` : "100%",
|
|
723
|
+
minWidth: isFullScreen ? "100%" : minContentWidth ? `${minContentWidth}px` : void 0,
|
|
724
|
+
transform: parallaxOffset !== 0 ? `translateX(${parallaxOffset}px)` : void 0
|
|
725
|
+
},
|
|
726
|
+
children
|
|
727
|
+
}
|
|
728
|
+
),
|
|
729
|
+
/* @__PURE__ */ jsx(Ripple, { ripples, onRippleDone: removeRipple })
|
|
730
|
+
]
|
|
731
|
+
})
|
|
732
|
+
)
|
|
733
|
+
);
|
|
734
|
+
}
|
|
735
|
+
);
|
|
736
|
+
CarouselItem.displayName = "CarouselItem";
|
|
737
|
+
function useCarouselA11y({
|
|
738
|
+
totalItems,
|
|
739
|
+
onItemSelect,
|
|
740
|
+
onExitNavigation,
|
|
741
|
+
scrollToIndex
|
|
742
|
+
}) {
|
|
743
|
+
const [focusedIndex, setFocusedIndex] = useState(0);
|
|
744
|
+
const handleKeyDown = useCallback(
|
|
745
|
+
(event) => {
|
|
746
|
+
if (totalItems === 0) return;
|
|
747
|
+
switch (event.key) {
|
|
748
|
+
case "ArrowRight":
|
|
749
|
+
case "ArrowDown": {
|
|
750
|
+
if (event.key === "ArrowDown" && onExitNavigation) {
|
|
751
|
+
onExitNavigation();
|
|
752
|
+
return;
|
|
753
|
+
}
|
|
754
|
+
event.preventDefault();
|
|
755
|
+
setFocusedIndex((prev) => {
|
|
756
|
+
const next = Math.min(totalItems - 1, prev + 1);
|
|
757
|
+
scrollToIndex == null ? void 0 : scrollToIndex(next);
|
|
758
|
+
return next;
|
|
759
|
+
});
|
|
760
|
+
break;
|
|
761
|
+
}
|
|
762
|
+
case "ArrowLeft":
|
|
763
|
+
case "ArrowUp": {
|
|
764
|
+
if (event.key === "ArrowUp" && onExitNavigation) {
|
|
765
|
+
onExitNavigation();
|
|
766
|
+
return;
|
|
767
|
+
}
|
|
768
|
+
event.preventDefault();
|
|
769
|
+
setFocusedIndex((prev) => {
|
|
770
|
+
const next = Math.max(0, prev - 1);
|
|
771
|
+
scrollToIndex == null ? void 0 : scrollToIndex(next);
|
|
772
|
+
return next;
|
|
773
|
+
});
|
|
774
|
+
break;
|
|
775
|
+
}
|
|
776
|
+
case "Home": {
|
|
777
|
+
event.preventDefault();
|
|
778
|
+
setFocusedIndex(0);
|
|
779
|
+
scrollToIndex == null ? void 0 : scrollToIndex(0);
|
|
780
|
+
break;
|
|
781
|
+
}
|
|
782
|
+
case "End": {
|
|
783
|
+
event.preventDefault();
|
|
784
|
+
const lastIndex = totalItems - 1;
|
|
785
|
+
setFocusedIndex(lastIndex);
|
|
786
|
+
scrollToIndex == null ? void 0 : scrollToIndex(lastIndex);
|
|
787
|
+
break;
|
|
788
|
+
}
|
|
789
|
+
case " ":
|
|
790
|
+
case "Enter": {
|
|
791
|
+
event.preventDefault();
|
|
792
|
+
onItemSelect == null ? void 0 : onItemSelect(focusedIndex);
|
|
793
|
+
break;
|
|
794
|
+
}
|
|
795
|
+
}
|
|
796
|
+
},
|
|
797
|
+
[totalItems, focusedIndex, onItemSelect, onExitNavigation, scrollToIndex]
|
|
798
|
+
);
|
|
799
|
+
const getItemA11yProps = useCallback(
|
|
800
|
+
(index, customLabel) => {
|
|
801
|
+
const itemNumber = index + 1;
|
|
802
|
+
const defaultLabel = `Item ${itemNumber} of ${totalItems}`;
|
|
803
|
+
return {
|
|
804
|
+
role: "group",
|
|
805
|
+
"aria-roledescription": "slide",
|
|
806
|
+
"aria-label": customLabel ? `${customLabel} (${itemNumber} of ${totalItems})` : defaultLabel,
|
|
807
|
+
tabIndex: index === focusedIndex ? 0 : -1,
|
|
808
|
+
onFocus: () => setFocusedIndex(index)
|
|
809
|
+
};
|
|
810
|
+
},
|
|
811
|
+
[focusedIndex, totalItems]
|
|
812
|
+
);
|
|
813
|
+
return {
|
|
814
|
+
focusedIndex,
|
|
815
|
+
setFocusedIndex,
|
|
816
|
+
handleKeyDown,
|
|
817
|
+
getItemA11yProps
|
|
818
|
+
};
|
|
819
|
+
}
|
|
820
|
+
|
|
821
|
+
// src/ui/carousel/carousel.tokens.ts
|
|
822
|
+
var CarouselTokens = {
|
|
823
|
+
/** Corner radius shape (M3 extraLarge shape: 28dp) */
|
|
824
|
+
containerRadius: 28,
|
|
825
|
+
/** Small item dimension limits (dp) */
|
|
826
|
+
smallItemMin: 40,
|
|
827
|
+
smallItemMax: 56,
|
|
828
|
+
/** Layout defaults (dp) */
|
|
829
|
+
itemSpacing: 8,
|
|
830
|
+
contentPadding: 16,
|
|
831
|
+
verticalPadding: 8,
|
|
832
|
+
/** Interactive state overlays */
|
|
833
|
+
hoverOpacity: 0.08,
|
|
834
|
+
focusOpacity: 0.1,
|
|
835
|
+
pressedOpacity: 0.1,
|
|
836
|
+
disabledOpacity: 0.38,
|
|
837
|
+
/** Focus indicator dimensions */
|
|
838
|
+
focusThickness: 3,
|
|
839
|
+
focusOffset: 2,
|
|
840
|
+
/** Touch target minimum size for accessibility (WCAG 2.1 AAA / M3) */
|
|
841
|
+
minTouchTargetSize: 48,
|
|
842
|
+
/** CSS Custom Property token maps for fallback and runtime injection */
|
|
843
|
+
cssVars: {
|
|
844
|
+
shape: "--carousel-item-shape",
|
|
845
|
+
spacing: "--carousel-item-spacing",
|
|
846
|
+
contentPadding: "--carousel-content-padding",
|
|
847
|
+
verticalPadding: "--carousel-vertical-padding",
|
|
848
|
+
smallMin: "--carousel-small-item-min",
|
|
849
|
+
smallMax: "--carousel-small-item-max",
|
|
850
|
+
hoverOpacity: "--carousel-hover-opacity",
|
|
851
|
+
focusThickness: "--carousel-focus-thickness",
|
|
852
|
+
focusOffset: "--carousel-focus-offset",
|
|
853
|
+
pressedOpacity: "--carousel-pressed-opacity",
|
|
854
|
+
disabledOpacity: "--carousel-disabled-opacity"
|
|
855
|
+
}
|
|
856
|
+
};
|
|
857
|
+
|
|
858
|
+
// src/ui/carousel/hooks/useCarouselKeylines.ts
|
|
859
|
+
function useCarouselKeylines({
|
|
860
|
+
containerWidth,
|
|
861
|
+
preferredItemWidth = 300,
|
|
862
|
+
layout = "multi-browse",
|
|
863
|
+
itemSpacing = CarouselTokens.itemSpacing,
|
|
864
|
+
contentPadding = CarouselTokens.contentPadding,
|
|
865
|
+
totalItems,
|
|
866
|
+
scrollX: _scrollX = 0
|
|
867
|
+
}) {
|
|
868
|
+
return useMemo(() => {
|
|
869
|
+
const safeContainerWidth = Math.max(containerWidth, 100);
|
|
870
|
+
const smallWidth = Math.min(
|
|
871
|
+
Math.max(
|
|
872
|
+
CarouselTokens.smallItemMin,
|
|
873
|
+
Math.round(safeContainerWidth * 0.1)
|
|
874
|
+
),
|
|
875
|
+
CarouselTokens.smallItemMax
|
|
876
|
+
);
|
|
877
|
+
let largeWidth = preferredItemWidth;
|
|
878
|
+
let mediumWidth = Math.round(preferredItemWidth * 0.65);
|
|
879
|
+
switch (layout) {
|
|
880
|
+
case "hero": {
|
|
881
|
+
const availableWidth = safeContainerWidth - contentPadding * 2 - smallWidth - itemSpacing;
|
|
882
|
+
largeWidth = Math.max(160, availableWidth);
|
|
883
|
+
mediumWidth = largeWidth;
|
|
884
|
+
break;
|
|
885
|
+
}
|
|
886
|
+
case "center-aligned-hero": {
|
|
887
|
+
const availableWidth = safeContainerWidth - contentPadding * 2 - smallWidth * 2 - itemSpacing * 2;
|
|
888
|
+
largeWidth = Math.max(160, availableWidth);
|
|
889
|
+
mediumWidth = largeWidth;
|
|
890
|
+
break;
|
|
891
|
+
}
|
|
892
|
+
case "uncontained":
|
|
893
|
+
case "uncontained-multi-aspect": {
|
|
894
|
+
largeWidth = Math.min(
|
|
895
|
+
preferredItemWidth,
|
|
896
|
+
safeContainerWidth - contentPadding * 2
|
|
897
|
+
);
|
|
898
|
+
mediumWidth = largeWidth;
|
|
899
|
+
break;
|
|
900
|
+
}
|
|
901
|
+
case "full-screen": {
|
|
902
|
+
largeWidth = safeContainerWidth;
|
|
903
|
+
mediumWidth = safeContainerWidth;
|
|
904
|
+
break;
|
|
905
|
+
}
|
|
906
|
+
default: {
|
|
907
|
+
const maxLargeWidth = safeContainerWidth - contentPadding * 2 - smallWidth - itemSpacing;
|
|
908
|
+
largeWidth = Math.min(preferredItemWidth, Math.max(160, maxLargeWidth));
|
|
909
|
+
mediumWidth = Math.max(smallWidth + 16, Math.round(largeWidth * 0.65));
|
|
910
|
+
break;
|
|
911
|
+
}
|
|
912
|
+
}
|
|
913
|
+
const keylines = [];
|
|
914
|
+
if (layout === "hero") {
|
|
915
|
+
const smallMask = Math.max(
|
|
916
|
+
0,
|
|
917
|
+
Math.min(
|
|
918
|
+
100,
|
|
919
|
+
Math.round((largeWidth - smallWidth) / largeWidth * 100)
|
|
920
|
+
)
|
|
921
|
+
);
|
|
922
|
+
keylines.push(
|
|
923
|
+
{
|
|
924
|
+
offset: contentPadding,
|
|
925
|
+
width: largeWidth,
|
|
926
|
+
type: "large",
|
|
927
|
+
maskClip: 0
|
|
928
|
+
},
|
|
929
|
+
{
|
|
930
|
+
offset: contentPadding + largeWidth + itemSpacing,
|
|
931
|
+
width: smallWidth,
|
|
932
|
+
type: "small",
|
|
933
|
+
maskClip: smallMask
|
|
934
|
+
}
|
|
935
|
+
);
|
|
936
|
+
} else if (layout === "center-aligned-hero") {
|
|
937
|
+
const smallMask = Math.max(
|
|
938
|
+
0,
|
|
939
|
+
Math.min(
|
|
940
|
+
100,
|
|
941
|
+
Math.round((largeWidth - smallWidth) / largeWidth * 100)
|
|
942
|
+
)
|
|
943
|
+
);
|
|
944
|
+
keylines.push(
|
|
945
|
+
{
|
|
946
|
+
offset: contentPadding,
|
|
947
|
+
width: smallWidth,
|
|
948
|
+
type: "small",
|
|
949
|
+
maskClip: smallMask
|
|
950
|
+
},
|
|
951
|
+
{
|
|
952
|
+
offset: contentPadding + smallWidth + itemSpacing,
|
|
953
|
+
width: largeWidth,
|
|
954
|
+
type: "large",
|
|
955
|
+
maskClip: 0
|
|
956
|
+
},
|
|
957
|
+
{
|
|
958
|
+
offset: contentPadding + smallWidth + itemSpacing + largeWidth + itemSpacing,
|
|
959
|
+
width: smallWidth,
|
|
960
|
+
type: "small",
|
|
961
|
+
maskClip: smallMask
|
|
962
|
+
}
|
|
963
|
+
);
|
|
964
|
+
} else if (layout === "multi-browse") {
|
|
965
|
+
const mediumMask = Math.max(
|
|
966
|
+
0,
|
|
967
|
+
Math.min(
|
|
968
|
+
100,
|
|
969
|
+
Math.round((largeWidth - mediumWidth) / largeWidth * 100)
|
|
970
|
+
)
|
|
971
|
+
);
|
|
972
|
+
const smallMask = Math.max(
|
|
973
|
+
0,
|
|
974
|
+
Math.min(
|
|
975
|
+
100,
|
|
976
|
+
Math.round((largeWidth - smallWidth) / largeWidth * 100)
|
|
977
|
+
)
|
|
978
|
+
);
|
|
979
|
+
const availableWidth = safeContainerWidth - contentPadding * 2;
|
|
980
|
+
const numLarge = Math.max(
|
|
981
|
+
1,
|
|
982
|
+
Math.floor((availableWidth + itemSpacing) / (largeWidth + itemSpacing))
|
|
983
|
+
);
|
|
984
|
+
let offset = contentPadding;
|
|
985
|
+
for (let k = 0; k < numLarge; k++) {
|
|
986
|
+
keylines.push({
|
|
987
|
+
offset,
|
|
988
|
+
width: largeWidth,
|
|
989
|
+
type: "large",
|
|
990
|
+
maskClip: 0
|
|
991
|
+
});
|
|
992
|
+
offset += largeWidth + itemSpacing;
|
|
993
|
+
}
|
|
994
|
+
keylines.push({
|
|
995
|
+
offset,
|
|
996
|
+
width: mediumWidth,
|
|
997
|
+
type: "medium",
|
|
998
|
+
maskClip: mediumMask
|
|
999
|
+
});
|
|
1000
|
+
offset += mediumWidth + itemSpacing;
|
|
1001
|
+
keylines.push({
|
|
1002
|
+
offset,
|
|
1003
|
+
width: smallWidth,
|
|
1004
|
+
type: "small",
|
|
1005
|
+
maskClip: smallMask
|
|
1006
|
+
});
|
|
1007
|
+
} else {
|
|
1008
|
+
keylines.push({
|
|
1009
|
+
offset: contentPadding,
|
|
1010
|
+
width: largeWidth,
|
|
1011
|
+
type: "large",
|
|
1012
|
+
maskClip: 0
|
|
1013
|
+
});
|
|
1014
|
+
}
|
|
1015
|
+
const getItemRestWidth = (i) => {
|
|
1016
|
+
if (layout === "full-screen") return safeContainerWidth;
|
|
1017
|
+
if (layout === "uncontained") return largeWidth;
|
|
1018
|
+
if (layout === "uncontained-multi-aspect") {
|
|
1019
|
+
const ratios = [1.77, 1.33, 1, 0.56];
|
|
1020
|
+
const ratio = ratios[i % ratios.length];
|
|
1021
|
+
return Math.round(Math.min(largeWidth, 220 * ratio));
|
|
1022
|
+
}
|
|
1023
|
+
if (layout === "hero") return i === 0 ? largeWidth : smallWidth;
|
|
1024
|
+
if (layout === "center-aligned-hero")
|
|
1025
|
+
return i === 0 || i === totalItems - 1 ? smallWidth : largeWidth;
|
|
1026
|
+
const pattern = [largeWidth, largeWidth, mediumWidth, smallWidth];
|
|
1027
|
+
return pattern[i % pattern.length];
|
|
1028
|
+
};
|
|
1029
|
+
const snapPositions = [];
|
|
1030
|
+
let currentOffset = 0;
|
|
1031
|
+
const itemLayoutWidth = layout === "full-screen" ? safeContainerWidth : largeWidth;
|
|
1032
|
+
for (let i = 0; i < totalItems; i++) {
|
|
1033
|
+
snapPositions.push(currentOffset);
|
|
1034
|
+
currentOffset += itemLayoutWidth + itemSpacing;
|
|
1035
|
+
}
|
|
1036
|
+
const getItemWidth = (_index) => {
|
|
1037
|
+
if (layout === "full-screen") return safeContainerWidth;
|
|
1038
|
+
return largeWidth;
|
|
1039
|
+
};
|
|
1040
|
+
const getItemMaskClip = (index) => {
|
|
1041
|
+
if (layout === "full-screen" || layout === "uncontained" || layout === "uncontained-multi-aspect") {
|
|
1042
|
+
return 0;
|
|
1043
|
+
}
|
|
1044
|
+
const itemW = getItemRestWidth(index);
|
|
1045
|
+
if (itemW >= largeWidth || largeWidth <= 0) return 0;
|
|
1046
|
+
return Math.max(
|
|
1047
|
+
0,
|
|
1048
|
+
Math.min(100, Math.round((largeWidth - itemW) / largeWidth * 100))
|
|
1049
|
+
);
|
|
1050
|
+
};
|
|
1051
|
+
const getItemParallaxOffset = (index) => {
|
|
1052
|
+
const maskClip = getItemMaskClip(index);
|
|
1053
|
+
if (maskClip <= 0) return 0;
|
|
1054
|
+
return calculateParallaxOffset(0, maskClip, largeWidth);
|
|
1055
|
+
};
|
|
1056
|
+
let maxAccumulatedShift = 0;
|
|
1057
|
+
if (layout === "hero") {
|
|
1058
|
+
maxAccumulatedShift = Math.max(
|
|
1059
|
+
0,
|
|
1060
|
+
(totalItems - 1) * (largeWidth - smallWidth)
|
|
1061
|
+
);
|
|
1062
|
+
} else if (layout === "center-aligned-hero") {
|
|
1063
|
+
maxAccumulatedShift = Math.max(
|
|
1064
|
+
0,
|
|
1065
|
+
Math.min(totalItems, 2) * (largeWidth - smallWidth)
|
|
1066
|
+
);
|
|
1067
|
+
} else if (layout === "multi-browse") {
|
|
1068
|
+
const availableWidth = safeContainerWidth - contentPadding * 2;
|
|
1069
|
+
const numLarge = Math.max(
|
|
1070
|
+
1,
|
|
1071
|
+
Math.floor((availableWidth + itemSpacing) / (largeWidth + itemSpacing))
|
|
1072
|
+
);
|
|
1073
|
+
const nonLargeItems = Math.max(0, totalItems - numLarge);
|
|
1074
|
+
if (nonLargeItems > 0) {
|
|
1075
|
+
const mediumClipped = largeWidth - mediumWidth;
|
|
1076
|
+
const smallClipped = largeWidth - smallWidth;
|
|
1077
|
+
const numSmall = Math.max(0, nonLargeItems - 1);
|
|
1078
|
+
maxAccumulatedShift = mediumClipped + numSmall * smallClipped;
|
|
1079
|
+
}
|
|
1080
|
+
}
|
|
1081
|
+
return {
|
|
1082
|
+
largeWidth,
|
|
1083
|
+
mediumWidth,
|
|
1084
|
+
smallWidth,
|
|
1085
|
+
keylines,
|
|
1086
|
+
snapPositions,
|
|
1087
|
+
maxAccumulatedShift,
|
|
1088
|
+
getItemWidth,
|
|
1089
|
+
getItemMaskClip,
|
|
1090
|
+
getItemParallaxOffset
|
|
1091
|
+
};
|
|
1092
|
+
}, [
|
|
1093
|
+
containerWidth,
|
|
1094
|
+
preferredItemWidth,
|
|
1095
|
+
layout,
|
|
1096
|
+
itemSpacing,
|
|
1097
|
+
contentPadding,
|
|
1098
|
+
totalItems
|
|
1099
|
+
]);
|
|
1100
|
+
}
|
|
1101
|
+
function calculateMaskClipForOffset(itemLeftInViewport, containerWidth, largeWidth, mediumWidth, smallWidth, contentPadding = 16, layout = "multi-browse") {
|
|
1102
|
+
if (layout === "full-screen" || layout === "uncontained" || layout === "uncontained-multi-aspect" || largeWidth <= 0) {
|
|
1103
|
+
return 0;
|
|
1104
|
+
}
|
|
1105
|
+
const mediumMask = Math.max(
|
|
1106
|
+
0,
|
|
1107
|
+
Math.min(100, (largeWidth - mediumWidth) / largeWidth * 100)
|
|
1108
|
+
);
|
|
1109
|
+
const smallMask = Math.max(
|
|
1110
|
+
0,
|
|
1111
|
+
Math.min(100, (largeWidth - smallWidth) / largeWidth * 100)
|
|
1112
|
+
);
|
|
1113
|
+
const trailingFocalThreshold = containerWidth - contentPadding - mediumWidth - (largeWidth - mediumWidth);
|
|
1114
|
+
const trailingMediumThreshold = containerWidth - contentPadding - smallWidth;
|
|
1115
|
+
const trailingEndThreshold = containerWidth - contentPadding;
|
|
1116
|
+
const leadingThreshold = contentPadding;
|
|
1117
|
+
if (itemLeftInViewport < leadingThreshold) {
|
|
1118
|
+
const dist = leadingThreshold - itemLeftInViewport;
|
|
1119
|
+
const progress = Math.min(1, Math.max(0, dist / largeWidth));
|
|
1120
|
+
return Math.min(100, Math.max(0, progress * smallMask));
|
|
1121
|
+
}
|
|
1122
|
+
if (itemLeftInViewport > trailingFocalThreshold) {
|
|
1123
|
+
if (itemLeftInViewport < trailingMediumThreshold) {
|
|
1124
|
+
const range2 = Math.max(
|
|
1125
|
+
1,
|
|
1126
|
+
trailingMediumThreshold - trailingFocalThreshold
|
|
1127
|
+
);
|
|
1128
|
+
const progress2 = Math.min(
|
|
1129
|
+
1,
|
|
1130
|
+
Math.max(0, (itemLeftInViewport - trailingFocalThreshold) / range2)
|
|
1131
|
+
);
|
|
1132
|
+
return progress2 * mediumMask;
|
|
1133
|
+
}
|
|
1134
|
+
const range = Math.max(1, trailingEndThreshold - trailingMediumThreshold);
|
|
1135
|
+
const progress = Math.min(
|
|
1136
|
+
1,
|
|
1137
|
+
Math.max(0, (itemLeftInViewport - trailingMediumThreshold) / range)
|
|
1138
|
+
);
|
|
1139
|
+
return mediumMask + progress * (smallMask - mediumMask);
|
|
1140
|
+
}
|
|
1141
|
+
return 0;
|
|
1142
|
+
}
|
|
1143
|
+
function calculateParallaxOffset(_itemLeftInViewport, maskClipPercent, largeWidth) {
|
|
1144
|
+
if (maskClipPercent <= 0 || largeWidth <= 0) return 0;
|
|
1145
|
+
return -Math.round(maskClipPercent / 100 * (largeWidth * 0.2));
|
|
1146
|
+
}
|
|
1147
|
+
function CarouselScrollClient(_a) {
|
|
1148
|
+
var _b = _a, {
|
|
1149
|
+
children,
|
|
1150
|
+
items,
|
|
1151
|
+
renderItem,
|
|
1152
|
+
layout = "multi-browse",
|
|
1153
|
+
preferredItemWidth = 300,
|
|
1154
|
+
itemSpacing = 8,
|
|
1155
|
+
contentPadding = 16,
|
|
1156
|
+
verticalPadding = 8,
|
|
1157
|
+
userScrollEnabled = true,
|
|
1158
|
+
totalItemsCount,
|
|
1159
|
+
className,
|
|
1160
|
+
style
|
|
1161
|
+
} = _b, props = __objRest(_b, [
|
|
1162
|
+
"children",
|
|
1163
|
+
"items",
|
|
1164
|
+
"renderItem",
|
|
1165
|
+
"layout",
|
|
1166
|
+
"preferredItemWidth",
|
|
1167
|
+
"itemSpacing",
|
|
1168
|
+
"contentPadding",
|
|
1169
|
+
"verticalPadding",
|
|
1170
|
+
"userScrollEnabled",
|
|
1171
|
+
"totalItemsCount",
|
|
1172
|
+
"className",
|
|
1173
|
+
"style"
|
|
1174
|
+
]);
|
|
1175
|
+
const trackRef = React23.useRef(null);
|
|
1176
|
+
const [containerWidth, setContainerWidth] = React23.useState(600);
|
|
1177
|
+
const rafIdRef = React23.useRef(null);
|
|
1178
|
+
const isDraggingRef = React23.useRef(false);
|
|
1179
|
+
const hasMovedRef = React23.useRef(false);
|
|
1180
|
+
const startPosRef = React23.useRef(0);
|
|
1181
|
+
const startScrollRef = React23.useRef(0);
|
|
1182
|
+
const keylines = useCarouselKeylines({
|
|
1183
|
+
containerWidth,
|
|
1184
|
+
preferredItemWidth,
|
|
1185
|
+
layout,
|
|
1186
|
+
itemSpacing,
|
|
1187
|
+
contentPadding,
|
|
1188
|
+
totalItems: totalItemsCount
|
|
1189
|
+
});
|
|
1190
|
+
const handleScroll = React23.useCallback(() => {
|
|
1191
|
+
if (rafIdRef.current !== null) return;
|
|
1192
|
+
rafIdRef.current = requestAnimationFrame(() => {
|
|
1193
|
+
var _a2, _b2;
|
|
1194
|
+
const track = trackRef.current;
|
|
1195
|
+
if (track) {
|
|
1196
|
+
const scrollVal = layout === "full-screen" ? track.scrollTop : track.scrollLeft;
|
|
1197
|
+
track.style.setProperty("--carousel-scroll-left", `${scrollVal}px`);
|
|
1198
|
+
if (layout !== "full-screen") {
|
|
1199
|
+
const prefersReducedMotion = typeof window !== "undefined" && ((_b2 = (_a2 = window.matchMedia) == null ? void 0 : _a2.call(window, "(prefers-reduced-motion: reduce)")) == null ? void 0 : _b2.matches);
|
|
1200
|
+
let accumulatedShift = 0;
|
|
1201
|
+
const items2 = track.children;
|
|
1202
|
+
for (let i = 0; i < items2.length; i++) {
|
|
1203
|
+
const itemEl = items2[i];
|
|
1204
|
+
if (!itemEl || itemEl.getAttribute("role") !== "group") continue;
|
|
1205
|
+
if (prefersReducedMotion) {
|
|
1206
|
+
itemEl.style.clipPath = "none";
|
|
1207
|
+
itemEl.style.transform = "none";
|
|
1208
|
+
const innerContent2 = itemEl.firstElementChild;
|
|
1209
|
+
if (innerContent2) innerContent2.style.transform = "none";
|
|
1210
|
+
continue;
|
|
1211
|
+
}
|
|
1212
|
+
const nativeOffset = itemEl.offsetLeft - scrollVal;
|
|
1213
|
+
const visualOffset = nativeOffset - accumulatedShift;
|
|
1214
|
+
const maskPercent = calculateMaskClipForOffset(
|
|
1215
|
+
visualOffset,
|
|
1216
|
+
containerWidth,
|
|
1217
|
+
keylines.largeWidth,
|
|
1218
|
+
keylines.mediumWidth,
|
|
1219
|
+
keylines.smallWidth,
|
|
1220
|
+
contentPadding,
|
|
1221
|
+
layout
|
|
1222
|
+
);
|
|
1223
|
+
const clippedPixels = maskPercent / 100 * keylines.largeWidth;
|
|
1224
|
+
itemEl.style.transform = accumulatedShift > 0 ? `translateX(${-accumulatedShift}px)` : "none";
|
|
1225
|
+
itemEl.style.clipPath = maskPercent > 0 ? `inset(0px ${maskPercent}% 0px 0px round 28px)` : "none";
|
|
1226
|
+
const innerContent = itemEl.firstElementChild;
|
|
1227
|
+
if (innerContent) {
|
|
1228
|
+
const parallaxX = calculateParallaxOffset(
|
|
1229
|
+
visualOffset,
|
|
1230
|
+
maskPercent,
|
|
1231
|
+
keylines.largeWidth
|
|
1232
|
+
);
|
|
1233
|
+
innerContent.style.transform = parallaxX !== 0 ? `translateX(${parallaxX}px)` : "none";
|
|
1234
|
+
}
|
|
1235
|
+
accumulatedShift += clippedPixels;
|
|
1236
|
+
}
|
|
1237
|
+
}
|
|
1238
|
+
}
|
|
1239
|
+
rafIdRef.current = null;
|
|
1240
|
+
});
|
|
1241
|
+
}, [
|
|
1242
|
+
layout,
|
|
1243
|
+
containerWidth,
|
|
1244
|
+
keylines.largeWidth,
|
|
1245
|
+
keylines.mediumWidth,
|
|
1246
|
+
keylines.smallWidth,
|
|
1247
|
+
contentPadding
|
|
1248
|
+
]);
|
|
1249
|
+
React23.useEffect(() => {
|
|
1250
|
+
const track = trackRef.current;
|
|
1251
|
+
if (!track) return;
|
|
1252
|
+
const updateWidth = () => {
|
|
1253
|
+
if (track.clientWidth > 0) {
|
|
1254
|
+
setContainerWidth(track.clientWidth);
|
|
1255
|
+
}
|
|
1256
|
+
};
|
|
1257
|
+
updateWidth();
|
|
1258
|
+
const observer = new ResizeObserver(updateWidth);
|
|
1259
|
+
observer.observe(track);
|
|
1260
|
+
return () => observer.disconnect();
|
|
1261
|
+
}, []);
|
|
1262
|
+
React23.useEffect(() => {
|
|
1263
|
+
handleScroll();
|
|
1264
|
+
}, [handleScroll]);
|
|
1265
|
+
React23.useEffect(() => {
|
|
1266
|
+
return () => {
|
|
1267
|
+
if (rafIdRef.current !== null) {
|
|
1268
|
+
cancelAnimationFrame(rafIdRef.current);
|
|
1269
|
+
}
|
|
1270
|
+
};
|
|
1271
|
+
}, []);
|
|
1272
|
+
const handlePointerDown = React23.useCallback(
|
|
1273
|
+
(e) => {
|
|
1274
|
+
var _a2, _b2;
|
|
1275
|
+
if (!userScrollEnabled || e.button !== 0) return;
|
|
1276
|
+
const track = trackRef.current;
|
|
1277
|
+
if (!track) return;
|
|
1278
|
+
isDraggingRef.current = true;
|
|
1279
|
+
hasMovedRef.current = false;
|
|
1280
|
+
startPosRef.current = layout === "full-screen" ? e.clientY : e.clientX;
|
|
1281
|
+
startScrollRef.current = layout === "full-screen" ? track.scrollTop : track.scrollLeft;
|
|
1282
|
+
try {
|
|
1283
|
+
(_b2 = (_a2 = e.target).setPointerCapture) == null ? void 0 : _b2.call(_a2, e.pointerId);
|
|
1284
|
+
} catch (e2) {
|
|
1285
|
+
}
|
|
1286
|
+
},
|
|
1287
|
+
[userScrollEnabled, layout]
|
|
1288
|
+
);
|
|
1289
|
+
const handlePointerMove = React23.useCallback(
|
|
1290
|
+
(e) => {
|
|
1291
|
+
if (!isDraggingRef.current || !trackRef.current) return;
|
|
1292
|
+
const currentPos = layout === "full-screen" ? e.clientY : e.clientX;
|
|
1293
|
+
const delta = currentPos - startPosRef.current;
|
|
1294
|
+
if (Math.abs(delta) > 4) {
|
|
1295
|
+
hasMovedRef.current = true;
|
|
1296
|
+
}
|
|
1297
|
+
if (hasMovedRef.current) {
|
|
1298
|
+
if (layout === "full-screen") {
|
|
1299
|
+
trackRef.current.scrollTop = startScrollRef.current - delta;
|
|
1300
|
+
} else {
|
|
1301
|
+
trackRef.current.scrollLeft = startScrollRef.current - delta;
|
|
1302
|
+
}
|
|
1303
|
+
}
|
|
1304
|
+
},
|
|
1305
|
+
[layout]
|
|
1306
|
+
);
|
|
1307
|
+
const handlePointerUp = React23.useCallback(
|
|
1308
|
+
(e) => {
|
|
1309
|
+
var _a2, _b2;
|
|
1310
|
+
if (!isDraggingRef.current) return;
|
|
1311
|
+
isDraggingRef.current = false;
|
|
1312
|
+
try {
|
|
1313
|
+
(_b2 = (_a2 = e.target).releasePointerCapture) == null ? void 0 : _b2.call(_a2, e.pointerId);
|
|
1314
|
+
} catch (e2) {
|
|
1315
|
+
}
|
|
1316
|
+
},
|
|
1317
|
+
[]
|
|
1318
|
+
);
|
|
1319
|
+
const handleClickCapture = React23.useCallback((e) => {
|
|
1320
|
+
if (hasMovedRef.current) {
|
|
1321
|
+
e.stopPropagation();
|
|
1322
|
+
e.preventDefault();
|
|
1323
|
+
hasMovedRef.current = false;
|
|
1324
|
+
}
|
|
1325
|
+
}, []);
|
|
1326
|
+
const scrollToIndex = React23.useCallback(
|
|
1327
|
+
(index) => {
|
|
1328
|
+
const track = trackRef.current;
|
|
1329
|
+
if (!track) return;
|
|
1330
|
+
const itemEl = track.children[index];
|
|
1331
|
+
if (!itemEl) return;
|
|
1332
|
+
const targetPos = Math.max(0, itemEl.offsetLeft - contentPadding);
|
|
1333
|
+
track.scrollTo({
|
|
1334
|
+
left: targetPos,
|
|
1335
|
+
behavior: "smooth"
|
|
1336
|
+
});
|
|
1337
|
+
},
|
|
1338
|
+
[contentPadding]
|
|
1339
|
+
);
|
|
1340
|
+
const { focusedIndex, handleKeyDown, getItemA11yProps } = useCarouselA11y({
|
|
1341
|
+
totalItems: totalItemsCount,
|
|
1342
|
+
scrollToIndex
|
|
1343
|
+
});
|
|
1344
|
+
const isFullScreen = layout === "full-screen";
|
|
1345
|
+
const isHero = layout === "hero" || layout === "center-aligned-hero";
|
|
1346
|
+
const trackClasses = cn(
|
|
1347
|
+
// Base layout & GPU containment
|
|
1348
|
+
"relative box-border select-none [contain:layout_style]",
|
|
1349
|
+
userScrollEnabled && "cursor-grab active:cursor-grabbing",
|
|
1350
|
+
// Scrollbar hide
|
|
1351
|
+
"[scrollbar-width:none] [&::-webkit-scrollbar]:hidden",
|
|
1352
|
+
// Full-screen: vertical snap column
|
|
1353
|
+
isFullScreen ? "flex flex-col flex-1 min-h-0 overflow-x-hidden overflow-y-auto p-0 gap-0 [scroll-snap-type:y_mandatory] [touch-action:pan-y]" : "flex flex-row items-stretch overflow-x-auto overflow-y-hidden [-webkit-overflow-scrolling:touch] [touch-action:pan-x]",
|
|
1354
|
+
// Snap for hero/center-aligned-hero
|
|
1355
|
+
isHero && !isFullScreen && "[scroll-snap-type:x_mandatory]",
|
|
1356
|
+
// Disabled
|
|
1357
|
+
!userScrollEnabled && "overflow-x-hidden pointer-events-none [touch-action:none]",
|
|
1358
|
+
className
|
|
1359
|
+
);
|
|
1360
|
+
const trackStyle = isFullScreen ? __spreadValues({}, style) : __spreadValues({
|
|
1361
|
+
paddingLeft: `${contentPadding}px`,
|
|
1362
|
+
paddingRight: layout === "uncontained" || layout === "uncontained-multi-aspect" ? 0 : `${contentPadding}px`,
|
|
1363
|
+
scrollPaddingLeft: `${contentPadding}px`,
|
|
1364
|
+
scrollPaddingRight: `${contentPadding}px`,
|
|
1365
|
+
paddingTop: `${verticalPadding}px`,
|
|
1366
|
+
paddingBottom: `${verticalPadding}px`,
|
|
1367
|
+
gap: `${itemSpacing}px`
|
|
1368
|
+
}, style);
|
|
1369
|
+
const renderSlides = () => {
|
|
1370
|
+
if (items && renderItem) {
|
|
1371
|
+
return items.map((item, index) => {
|
|
1372
|
+
const itemWidth = keylines.largeWidth;
|
|
1373
|
+
const maskClip = keylines.getItemMaskClip(index);
|
|
1374
|
+
const parallax = keylines.getItemParallaxOffset(index);
|
|
1375
|
+
const a11yProps = getItemA11yProps(index);
|
|
1376
|
+
const itemKey = typeof item === "object" && item !== null && "id" in item ? item.id : typeof item === "object" && item !== null && "key" in item ? item.key : index;
|
|
1377
|
+
return /* @__PURE__ */ jsx(
|
|
1378
|
+
CarouselItem,
|
|
1379
|
+
__spreadProps(__spreadValues({
|
|
1380
|
+
index,
|
|
1381
|
+
totalItems: totalItemsCount,
|
|
1382
|
+
layout,
|
|
1383
|
+
width: itemWidth,
|
|
1384
|
+
minContentWidth: keylines.largeWidth,
|
|
1385
|
+
maskClipPercent: maskClip,
|
|
1386
|
+
parallaxOffset: parallax,
|
|
1387
|
+
isFocused: focusedIndex === index
|
|
1388
|
+
}, a11yProps), {
|
|
1389
|
+
children: renderItem(item, index)
|
|
1390
|
+
}),
|
|
1391
|
+
itemKey
|
|
1392
|
+
);
|
|
1393
|
+
});
|
|
1394
|
+
}
|
|
1395
|
+
return React23.Children.map(children, (child, index) => {
|
|
1396
|
+
if (!React23.isValidElement(child)) return child;
|
|
1397
|
+
const itemWidth = keylines.largeWidth;
|
|
1398
|
+
const maskClip = keylines.getItemMaskClip(index);
|
|
1399
|
+
const parallax = keylines.getItemParallaxOffset(index);
|
|
1400
|
+
const a11yProps = getItemA11yProps(index);
|
|
1401
|
+
const childKey = child.key != null ? child.key : index;
|
|
1402
|
+
return /* @__PURE__ */ jsx(
|
|
1403
|
+
CarouselItem,
|
|
1404
|
+
__spreadProps(__spreadValues({
|
|
1405
|
+
index,
|
|
1406
|
+
totalItems: totalItemsCount,
|
|
1407
|
+
layout,
|
|
1408
|
+
width: itemWidth,
|
|
1409
|
+
minContentWidth: keylines.largeWidth,
|
|
1410
|
+
maskClipPercent: maskClip,
|
|
1411
|
+
parallaxOffset: parallax,
|
|
1412
|
+
isFocused: focusedIndex === index
|
|
1413
|
+
}, a11yProps), {
|
|
1414
|
+
children: child
|
|
1415
|
+
}),
|
|
1416
|
+
childKey
|
|
1417
|
+
);
|
|
1418
|
+
});
|
|
1419
|
+
};
|
|
1420
|
+
return /* @__PURE__ */ jsxs(
|
|
1421
|
+
"section",
|
|
1422
|
+
__spreadProps(__spreadValues({
|
|
1423
|
+
ref: trackRef,
|
|
1424
|
+
"aria-roledescription": "carousel",
|
|
1425
|
+
"aria-label": props["aria-label"] || "Content carousel",
|
|
1426
|
+
tabIndex: 0,
|
|
1427
|
+
className: trackClasses,
|
|
1428
|
+
style: trackStyle,
|
|
1429
|
+
onScroll: handleScroll,
|
|
1430
|
+
onPointerDown: handlePointerDown,
|
|
1431
|
+
onPointerMove: handlePointerMove,
|
|
1432
|
+
onPointerUp: handlePointerUp,
|
|
1433
|
+
onPointerCancel: handlePointerUp,
|
|
1434
|
+
onClickCapture: handleClickCapture,
|
|
1435
|
+
onKeyDown: handleKeyDown
|
|
1436
|
+
}, props), {
|
|
1437
|
+
children: [
|
|
1438
|
+
renderSlides(),
|
|
1439
|
+
!isFullScreen && /* @__PURE__ */ jsx(
|
|
1440
|
+
"div",
|
|
1441
|
+
{
|
|
1442
|
+
"aria-hidden": "true",
|
|
1443
|
+
className: "shrink-0 pointer-events-none",
|
|
1444
|
+
style: {
|
|
1445
|
+
width: 0,
|
|
1446
|
+
marginRight: keylines.maxAccumulatedShift > 0 ? `-${keylines.maxAccumulatedShift}px` : void 0
|
|
1447
|
+
}
|
|
1448
|
+
}
|
|
1449
|
+
)
|
|
1450
|
+
]
|
|
1451
|
+
})
|
|
1452
|
+
);
|
|
1453
|
+
}
|
|
1454
|
+
function Carousel(_a) {
|
|
1455
|
+
var _b = _a, {
|
|
1456
|
+
children,
|
|
1457
|
+
items,
|
|
1458
|
+
renderItem,
|
|
1459
|
+
layout = "multi-browse",
|
|
1460
|
+
preferredItemWidth = 300,
|
|
1461
|
+
itemSpacing = 8,
|
|
1462
|
+
contentPadding = 16,
|
|
1463
|
+
verticalPadding = 8,
|
|
1464
|
+
isExpanded: controlledExpanded,
|
|
1465
|
+
onShowAllClick,
|
|
1466
|
+
showAllLabel = "Show all",
|
|
1467
|
+
userScrollEnabled = true,
|
|
1468
|
+
className,
|
|
1469
|
+
style
|
|
1470
|
+
} = _b, props = __objRest(_b, [
|
|
1471
|
+
"children",
|
|
1472
|
+
"items",
|
|
1473
|
+
"renderItem",
|
|
1474
|
+
"layout",
|
|
1475
|
+
"preferredItemWidth",
|
|
1476
|
+
"itemSpacing",
|
|
1477
|
+
"contentPadding",
|
|
1478
|
+
"verticalPadding",
|
|
1479
|
+
"isExpanded",
|
|
1480
|
+
"onShowAllClick",
|
|
1481
|
+
"showAllLabel",
|
|
1482
|
+
"userScrollEnabled",
|
|
1483
|
+
"className",
|
|
1484
|
+
"style"
|
|
1485
|
+
]);
|
|
1486
|
+
const [internalExpanded, setInternalExpanded] = React23.useState(false);
|
|
1487
|
+
const isExpanded = controlledExpanded != null ? controlledExpanded : internalExpanded;
|
|
1488
|
+
const totalItemsCount = React23.useMemo(() => {
|
|
1489
|
+
if (items) return items.length;
|
|
1490
|
+
return React23.Children.count(children);
|
|
1491
|
+
}, [items, children]);
|
|
1492
|
+
const handleShowAllToggle = React23.useCallback(() => {
|
|
1493
|
+
if (onShowAllClick) {
|
|
1494
|
+
onShowAllClick();
|
|
1495
|
+
} else {
|
|
1496
|
+
setInternalExpanded((prev) => !prev);
|
|
1497
|
+
}
|
|
1498
|
+
}, [onShowAllClick]);
|
|
1499
|
+
const isFullScreen = layout === "full-screen";
|
|
1500
|
+
return /* @__PURE__ */ jsxs(
|
|
1501
|
+
"div",
|
|
1502
|
+
{
|
|
1503
|
+
className: cn(
|
|
1504
|
+
"relative w-full flex flex-col gap-3 box-border min-h-0",
|
|
1505
|
+
// Full-screen: propagate height to track
|
|
1506
|
+
isFullScreen && "flex-1",
|
|
1507
|
+
className
|
|
1508
|
+
),
|
|
1509
|
+
style,
|
|
1510
|
+
children: [
|
|
1511
|
+
!isFullScreen && /* @__PURE__ */ jsxs(
|
|
1512
|
+
"div",
|
|
1513
|
+
{
|
|
1514
|
+
className: "flex items-center justify-between",
|
|
1515
|
+
style: { padding: `0 ${contentPadding}px` },
|
|
1516
|
+
children: [
|
|
1517
|
+
props["aria-label"] && /* @__PURE__ */ jsx("h3", { className: "m-0 text-(length:--md-sys-typescale-title-medium-size,1.125rem) font-medium text-(--md-sys-color-on-surface,currentColor)", children: props["aria-label"] }),
|
|
1518
|
+
/* @__PURE__ */ jsx(
|
|
1519
|
+
"button",
|
|
1520
|
+
{
|
|
1521
|
+
type: "button",
|
|
1522
|
+
className: cn(
|
|
1523
|
+
"inline-flex items-center justify-center min-h-12 min-w-12 px-4 py-2",
|
|
1524
|
+
"rounded-[20px] border border-(--md-sys-color-outline-variant,rgba(121,116,126,0.3))",
|
|
1525
|
+
"bg-transparent text-(--md-sys-color-primary,#6750a4) font-medium text-[0.875rem]",
|
|
1526
|
+
"cursor-pointer outline-none transition-colors duration-200",
|
|
1527
|
+
"hover:bg-(--md-sys-color-surface-container-high,rgba(103,80,164,0.08))",
|
|
1528
|
+
"focus-visible:outline-[3px] focus-visible:outline-(--md-sys-color-secondary,#625b71) focus-visible:outline-offset-2"
|
|
1529
|
+
),
|
|
1530
|
+
onClick: handleShowAllToggle,
|
|
1531
|
+
"aria-expanded": isExpanded,
|
|
1532
|
+
"aria-label": isExpanded ? "Collapse carousel view" : `${showAllLabel} (${totalItemsCount} items)`,
|
|
1533
|
+
children: isExpanded ? "Show carousel" : showAllLabel
|
|
1534
|
+
}
|
|
1535
|
+
)
|
|
1536
|
+
]
|
|
1537
|
+
}
|
|
1538
|
+
),
|
|
1539
|
+
isExpanded ? /* @__PURE__ */ jsx(
|
|
1540
|
+
CarouselGrid,
|
|
1541
|
+
{
|
|
1542
|
+
items,
|
|
1543
|
+
renderItem,
|
|
1544
|
+
preferredItemWidth,
|
|
1545
|
+
children
|
|
1546
|
+
}
|
|
1547
|
+
) : /* @__PURE__ */ jsx(
|
|
1548
|
+
CarouselScrollClient,
|
|
1549
|
+
__spreadProps(__spreadValues({
|
|
1550
|
+
items,
|
|
1551
|
+
renderItem,
|
|
1552
|
+
layout,
|
|
1553
|
+
preferredItemWidth,
|
|
1554
|
+
itemSpacing,
|
|
1555
|
+
contentPadding,
|
|
1556
|
+
verticalPadding,
|
|
1557
|
+
userScrollEnabled,
|
|
1558
|
+
totalItemsCount
|
|
1559
|
+
}, props), {
|
|
1560
|
+
children
|
|
1561
|
+
})
|
|
1562
|
+
)
|
|
1563
|
+
]
|
|
1564
|
+
}
|
|
1565
|
+
);
|
|
1566
|
+
}
|
|
304
1567
|
var SHAPE_KEY_TIMES = "0; 0.14; 0.14; 0.29; 0.29; 0.43; 0.43; 0.57; 0.57; 0.71; 0.71; 0.86; 0.86; 1";
|
|
305
1568
|
var SHAPE_KEY_SPLINES = [
|
|
306
1569
|
"0.5 0.2 0 0.8",
|
|
@@ -346,11 +1609,11 @@ var ROTATE_KEY_SPLINES = [
|
|
|
346
1609
|
var ROTATE_VALUES = "0 24 24; 154 24 24; 309 24 24; 463 24 24; 617 24 24; 771 24 24; 926 24 24; 1080 24 24";
|
|
347
1610
|
var DETERMINATE_CIRCLE = "M24 7 C34.49 7 41 13.51 41 24 C41 34.49 34.49 41 24 41 C13.51 41 7 34.49 7 24 C7 13.51 13.51 7 24 7 Z";
|
|
348
1611
|
var DETERMINATE_SOFT_BURST = "M20.9 10.4 21.4 9.5 21.9 8.7 22.5 7.8 23.2 7.2 24.2 7 25.1 7.4 25.7 8.1 26.2 9 26.8 9.8 27.3 10.6 28.1 11.2 29 11.3 30 11 30.9 10.6 31.8 10.3 32.8 9.9 33.7 10 34.5 10.6 34.9 11.5 34.8 12.5 34.8 13.5 34.7 14.5 34.7 15.5 35.2 16.3 36 16.8 37 17.1 37.9 17.3 38.9 17.5 39.8 17.9 40.4 18.7 40.5 19.7 40 20.5 39.4 21.3 38.7 22 38.1 22.8 37.6 23.7 37.7 24.6 38.3 25.5 38.9 26.2 39.6 27 40.2 27.7 40.5 28.7 40.3 29.6 39.5 30.3 38.6 30.6 37.6 30.8 36.7 31 35.7 31.3 35 31.9 34.6 32.8 34.7 33.8 34.8 34.8 34.9 35.8 34.8 36.8 34.3 37.6 33.4 38.1 32.4 38 31.5 37.6 30.6 37.2 29.7 36.9 28.7 36.6 27.8 36.9 27.1 37.6 26.6 38.5 26.1 39.3 25.5 40.2 24.8 40.8 23.8 41 22.9 40.6 22.3 39.9 21.8 39 21.2 38.2 20.7 37.4 19.9 36.8 19 36.7 18 37 17.1 37.4 16.2 37.7 15.2 38.1 14.3 38 13.5 37.4 13.1 36.5 13.2 35.5 13.2 34.5 13.3 33.5 13.3 32.5 12.8 31.7 12 31.2 11 31 10.1 30.7 9.1 30.5 8.2 30.1 7.6 29.3 7.5 28.3 8 27.5 8.7 26.7 9.3 26 9.9 25.2 10.4 24.3 10.3 23.4 9.7 22.5 9.1 21.8 8.4 21 7.8 20.3 7.5 19.3 7.7 18.4 8.5 17.7 9.4 17.4 10.4 17.2 11.3 17 12.3 16.7 13 16.1 13.4 15.2 13.3 14.2 13.2 13.2 13.1 12.2 13.2 11.2 13.7 10.4 14.6 9.9 15.6 10 16.5 10.4 17.4 10.8 18.3 11.1 19.3 11.4 20.2 11.1Z";
|
|
349
|
-
var IndeterminateSvg =
|
|
1612
|
+
var IndeterminateSvg = React23.memo(function IndeterminateSvg2({
|
|
350
1613
|
size
|
|
351
1614
|
}) {
|
|
352
|
-
const [ready, setReady] =
|
|
353
|
-
|
|
1615
|
+
const [ready, setReady] = React23.useState(false);
|
|
1616
|
+
React23.useEffect(() => {
|
|
354
1617
|
const raf = requestAnimationFrame(() => setReady(true));
|
|
355
1618
|
return () => cancelAnimationFrame(raf);
|
|
356
1619
|
}, []);
|
|
@@ -395,7 +1658,7 @@ var IndeterminateSvg = React18.memo(function IndeterminateSvg2({
|
|
|
395
1658
|
}
|
|
396
1659
|
);
|
|
397
1660
|
});
|
|
398
|
-
var DeterminateSvg =
|
|
1661
|
+
var DeterminateSvg = React23.memo(function DeterminateSvg2({
|
|
399
1662
|
size,
|
|
400
1663
|
progress
|
|
401
1664
|
}) {
|
|
@@ -420,7 +1683,7 @@ var DeterminateSvg = React18.memo(function DeterminateSvg2({
|
|
|
420
1683
|
}
|
|
421
1684
|
);
|
|
422
1685
|
});
|
|
423
|
-
var LoadingIndicator =
|
|
1686
|
+
var LoadingIndicator = React23.forwardRef(
|
|
424
1687
|
(_a, ref) => {
|
|
425
1688
|
var _b = _a, {
|
|
426
1689
|
variant = "uncontained",
|
|
@@ -488,7 +1751,7 @@ LoadingIndicator.displayName = "LoadingIndicator";
|
|
|
488
1751
|
function easeInOutCubic(x) {
|
|
489
1752
|
return x < 0.5 ? 4 * x * x * x : 1 - (-2 * x + 2) ** 3 / 2;
|
|
490
1753
|
}
|
|
491
|
-
function generateWavyCircularPath(center, radius, amplitude, wavelength) {
|
|
1754
|
+
function generateWavyCircularPath(center, radius, amplitude, wavelength, phase = 0) {
|
|
492
1755
|
const circumference = 2 * Math.PI * radius;
|
|
493
1756
|
const numWaves = Math.max(
|
|
494
1757
|
3,
|
|
@@ -496,8 +1759,8 @@ function generateWavyCircularPath(center, radius, amplitude, wavelength) {
|
|
|
496
1759
|
);
|
|
497
1760
|
const steps = numWaves * 4;
|
|
498
1761
|
const dt = 2 * Math.PI / steps;
|
|
499
|
-
const rAt = (t) => radius + amplitude * Math.sin(numWaves * t);
|
|
500
|
-
const drAt = (t) => amplitude * numWaves * Math.cos(numWaves * t);
|
|
1762
|
+
const rAt = (t) => radius + amplitude * Math.sin(numWaves * t + phase);
|
|
1763
|
+
const drAt = (t) => amplitude * numWaves * Math.cos(numWaves * t + phase);
|
|
501
1764
|
const xAt = (t) => center + rAt(t) * Math.cos(t);
|
|
502
1765
|
const yAt = (t) => center + rAt(t) * Math.sin(t);
|
|
503
1766
|
const dxAt = (t) => drAt(t) * Math.cos(t) - rAt(t) * Math.sin(t);
|
|
@@ -555,22 +1818,25 @@ var ADDITIONAL_ROTATION_EASE_DURATION = 500;
|
|
|
555
1818
|
var DEFAULT_MIN_PROGRESS = 0.1;
|
|
556
1819
|
var DEFAULT_MAX_PROGRESS = 0.8;
|
|
557
1820
|
var PROGRESS_CYCLE_DURATION = 1500;
|
|
558
|
-
var CircularProgress =
|
|
1821
|
+
var CircularProgress = React23.forwardRef(
|
|
559
1822
|
(_a, ref) => {
|
|
560
1823
|
var _b = _a, {
|
|
561
1824
|
value,
|
|
562
1825
|
size = 48,
|
|
563
1826
|
trackHeight = 4,
|
|
564
1827
|
shape = "flat",
|
|
1828
|
+
trackShape = "flat",
|
|
565
1829
|
amplitude,
|
|
566
1830
|
wavelength,
|
|
567
1831
|
gapSize = 4,
|
|
1832
|
+
waveSpeed = 1,
|
|
568
1833
|
crawlerSpeed = 1,
|
|
569
1834
|
color,
|
|
570
1835
|
trackColor,
|
|
571
1836
|
showTrack = "auto",
|
|
572
1837
|
minProgress = DEFAULT_MIN_PROGRESS,
|
|
573
1838
|
maxProgress = DEFAULT_MAX_PROGRESS,
|
|
1839
|
+
determinateAnimation = "md3",
|
|
574
1840
|
amplitudeRange,
|
|
575
1841
|
className,
|
|
576
1842
|
"aria-label": ariaLabel
|
|
@@ -579,15 +1845,18 @@ var CircularProgress = React18.forwardRef(
|
|
|
579
1845
|
"size",
|
|
580
1846
|
"trackHeight",
|
|
581
1847
|
"shape",
|
|
1848
|
+
"trackShape",
|
|
582
1849
|
"amplitude",
|
|
583
1850
|
"wavelength",
|
|
584
1851
|
"gapSize",
|
|
1852
|
+
"waveSpeed",
|
|
585
1853
|
"crawlerSpeed",
|
|
586
1854
|
"color",
|
|
587
1855
|
"trackColor",
|
|
588
1856
|
"showTrack",
|
|
589
1857
|
"minProgress",
|
|
590
1858
|
"maxProgress",
|
|
1859
|
+
"determinateAnimation",
|
|
591
1860
|
"amplitudeRange",
|
|
592
1861
|
"className",
|
|
593
1862
|
"aria-label"
|
|
@@ -600,21 +1869,22 @@ var CircularProgress = React18.forwardRef(
|
|
|
600
1869
|
const bgTrackColor = trackColor || "var(--md-sys-color-indicator-track)";
|
|
601
1870
|
const isWavy = shape === "wavy";
|
|
602
1871
|
const shouldShowIndeterminateTrack = showTrack === "auto" ? isWavy : showTrack;
|
|
1872
|
+
const shouldShowDeterminateTrack = showTrack === "auto" ? true : showTrack;
|
|
603
1873
|
const BASELINE_SIZE = 48;
|
|
604
1874
|
const scaleFactor = size / BASELINE_SIZE;
|
|
605
|
-
const effectiveAmplitude =
|
|
1875
|
+
const effectiveAmplitude = React23.useMemo(
|
|
606
1876
|
() => amplitude != null ? amplitude : 1.6 * scaleFactor,
|
|
607
1877
|
[amplitude, scaleFactor]
|
|
608
1878
|
);
|
|
609
|
-
const effectiveWavelength =
|
|
1879
|
+
const effectiveWavelength = React23.useMemo(
|
|
610
1880
|
() => wavelength != null ? wavelength : 15 * scaleFactor,
|
|
611
1881
|
[wavelength, scaleFactor]
|
|
612
1882
|
);
|
|
613
|
-
const resolvedAmplitudeRange =
|
|
1883
|
+
const resolvedAmplitudeRange = React23.useMemo(
|
|
614
1884
|
() => amplitudeRange != null ? amplitudeRange : [0, effectiveAmplitude],
|
|
615
1885
|
[amplitudeRange, effectiveAmplitude]
|
|
616
1886
|
);
|
|
617
|
-
const wavyActivePath =
|
|
1887
|
+
const wavyActivePath = React23.useMemo(
|
|
618
1888
|
() => isWavy ? generateWavyCircularPath(
|
|
619
1889
|
center,
|
|
620
1890
|
radius,
|
|
@@ -623,8 +1893,8 @@ var CircularProgress = React18.forwardRef(
|
|
|
623
1893
|
) : null,
|
|
624
1894
|
[isWavy, center, radius, effectiveAmplitude, effectiveWavelength]
|
|
625
1895
|
);
|
|
626
|
-
const circumference =
|
|
627
|
-
const gapForTrack =
|
|
1896
|
+
const circumference = React23.useMemo(() => 2 * Math.PI * radius, [radius]);
|
|
1897
|
+
const gapForTrack = React23.useMemo(
|
|
628
1898
|
() => (gapSize + trackHeight) / circumference,
|
|
629
1899
|
[gapSize, trackHeight, circumference]
|
|
630
1900
|
);
|
|
@@ -632,19 +1902,50 @@ var CircularProgress = React18.forwardRef(
|
|
|
632
1902
|
const trackOffset = isDeterminate ? activeAngularFraction + gapForTrack : 0;
|
|
633
1903
|
const trackLength = isDeterminate ? Math.max(1e-3, 1 - activeAngularFraction - 2 * gapForTrack) : 1;
|
|
634
1904
|
const ActiveCircleElem = m.circle;
|
|
635
|
-
const
|
|
636
|
-
const
|
|
637
|
-
const
|
|
638
|
-
const
|
|
639
|
-
const
|
|
640
|
-
const
|
|
641
|
-
const
|
|
642
|
-
|
|
1905
|
+
const indeterminateSvgRef = React23.useRef(null);
|
|
1906
|
+
const indeterminateTrackRef = React23.useRef(null);
|
|
1907
|
+
const indeterminateActiveRef = React23.useRef(null);
|
|
1908
|
+
const indeterminateWavyTrackPathRef = React23.useRef(null);
|
|
1909
|
+
const indeterminateWavyActivePathRef = React23.useRef(null);
|
|
1910
|
+
const determinateWavyActivePathRef = React23.useRef(null);
|
|
1911
|
+
const determinateWavyTrackPathRef = React23.useRef(null);
|
|
1912
|
+
const cachedPathLengthRef = React23.useRef(0);
|
|
1913
|
+
const fractionMV = useMotionValue(isDeterminate ? clampedValue / 100 : 0);
|
|
1914
|
+
const amplitudeMV = useMotionValue(isWavy ? effectiveAmplitude : 0);
|
|
1915
|
+
React23.useEffect(() => {
|
|
1916
|
+
if (isDeterminate) {
|
|
1917
|
+
animate(fractionMV, clampedValue / 100, {
|
|
1918
|
+
duration: 0.4,
|
|
1919
|
+
ease: [0.2, 0, 0, 1]
|
|
1920
|
+
});
|
|
1921
|
+
}
|
|
1922
|
+
}, [clampedValue, isDeterminate, fractionMV]);
|
|
1923
|
+
React23.useEffect(() => {
|
|
1924
|
+
if (!isDeterminate || !isWavy) return;
|
|
1925
|
+
const fraction = clampedValue / 100;
|
|
1926
|
+
let targetAmp = effectiveAmplitude;
|
|
1927
|
+
if (determinateAnimation === "md3") {
|
|
1928
|
+
targetAmp = fraction <= 0.1 || fraction >= 0.95 ? 0 : effectiveAmplitude;
|
|
1929
|
+
}
|
|
1930
|
+
animate(amplitudeMV, targetAmp, {
|
|
1931
|
+
type: "spring",
|
|
1932
|
+
bounce: 0,
|
|
1933
|
+
duration: 0.5
|
|
1934
|
+
});
|
|
1935
|
+
}, [
|
|
1936
|
+
clampedValue,
|
|
1937
|
+
isDeterminate,
|
|
1938
|
+
isWavy,
|
|
1939
|
+
effectiveAmplitude,
|
|
1940
|
+
amplitudeMV,
|
|
1941
|
+
determinateAnimation
|
|
1942
|
+
]);
|
|
1943
|
+
React23.useLayoutEffect(() => {
|
|
643
1944
|
if (!isWavy || !wavyActivePath) {
|
|
644
1945
|
cachedPathLengthRef.current = circumference;
|
|
645
1946
|
return;
|
|
646
1947
|
}
|
|
647
|
-
const el = indeterminateActiveRef.current;
|
|
1948
|
+
const el = indeterminateActiveRef.current || determinateWavyActivePathRef.current;
|
|
648
1949
|
if (el && "getTotalLength" in el) {
|
|
649
1950
|
try {
|
|
650
1951
|
const len = el.getTotalLength();
|
|
@@ -658,7 +1959,65 @@ var CircularProgress = React18.forwardRef(
|
|
|
658
1959
|
cachedPathLengthRef.current = circumference;
|
|
659
1960
|
}, [isWavy, circumference, wavyActivePath]);
|
|
660
1961
|
useAnimationFrame((time) => {
|
|
661
|
-
|
|
1962
|
+
const safeWaveSpeed = Math.max(0.1, waveSpeed);
|
|
1963
|
+
const wavePhase = time / 1e3 * safeWaveSpeed * 2 * Math.PI;
|
|
1964
|
+
if (isDeterminate) {
|
|
1965
|
+
if (isWavy) {
|
|
1966
|
+
const currentAmp = amplitudeMV.get();
|
|
1967
|
+
const dynamicPath = generateWavyCircularPath(
|
|
1968
|
+
center,
|
|
1969
|
+
radius,
|
|
1970
|
+
currentAmp,
|
|
1971
|
+
effectiveWavelength,
|
|
1972
|
+
wavePhase
|
|
1973
|
+
);
|
|
1974
|
+
if (determinateWavyActivePathRef.current) {
|
|
1975
|
+
determinateWavyActivePathRef.current.setAttribute("d", dynamicPath);
|
|
1976
|
+
}
|
|
1977
|
+
if (trackShape === "wavy" && determinateWavyTrackPathRef.current) {
|
|
1978
|
+
determinateWavyTrackPathRef.current.setAttribute("d", dynamicPath);
|
|
1979
|
+
}
|
|
1980
|
+
const pathEl = determinateWavyActivePathRef.current;
|
|
1981
|
+
let totalLen = cachedPathLengthRef.current || circumference;
|
|
1982
|
+
if (pathEl) {
|
|
1983
|
+
try {
|
|
1984
|
+
const len = pathEl.getTotalLength();
|
|
1985
|
+
if (len > 0) totalLen = len;
|
|
1986
|
+
} catch (e) {
|
|
1987
|
+
}
|
|
1988
|
+
}
|
|
1989
|
+
const activeFrac = Math.max(0, Math.min(1, fractionMV.get()));
|
|
1990
|
+
const activeLen = totalLen * activeFrac;
|
|
1991
|
+
if (determinateWavyActivePathRef.current) {
|
|
1992
|
+
determinateWavyActivePathRef.current.setAttribute(
|
|
1993
|
+
"stroke-dasharray",
|
|
1994
|
+
`${activeLen} ${totalLen}`
|
|
1995
|
+
);
|
|
1996
|
+
determinateWavyActivePathRef.current.setAttribute(
|
|
1997
|
+
"stroke-dashoffset",
|
|
1998
|
+
"0"
|
|
1999
|
+
);
|
|
2000
|
+
}
|
|
2001
|
+
if (shouldShowDeterminateTrack && trackShape === "wavy" && determinateWavyTrackPathRef.current) {
|
|
2002
|
+
const gapFrac = (gapSize + trackHeight) / totalLen;
|
|
2003
|
+
const trackStartFrac = activeFrac + gapFrac;
|
|
2004
|
+
const trackLen = Math.max(
|
|
2005
|
+
1e-3,
|
|
2006
|
+
totalLen * (1 - activeFrac - 2 * gapFrac)
|
|
2007
|
+
);
|
|
2008
|
+
const trackOff = -totalLen * trackStartFrac;
|
|
2009
|
+
determinateWavyTrackPathRef.current.setAttribute(
|
|
2010
|
+
"stroke-dasharray",
|
|
2011
|
+
`${trackLen} ${totalLen}`
|
|
2012
|
+
);
|
|
2013
|
+
determinateWavyTrackPathRef.current.setAttribute(
|
|
2014
|
+
"stroke-dashoffset",
|
|
2015
|
+
`${trackOff}`
|
|
2016
|
+
);
|
|
2017
|
+
}
|
|
2018
|
+
}
|
|
2019
|
+
return;
|
|
2020
|
+
}
|
|
662
2021
|
const safeCrawlerSpeed = Math.max(0.1, crawlerSpeed);
|
|
663
2022
|
const scaledTime = time * safeCrawlerSpeed;
|
|
664
2023
|
const globalCycle = scaledTime % GLOBAL_ROTATION_DURATION;
|
|
@@ -693,7 +2052,8 @@ var CircularProgress = React18.forwardRef(
|
|
|
693
2052
|
center,
|
|
694
2053
|
radius,
|
|
695
2054
|
currentAmplitude,
|
|
696
|
-
effectiveWavelength
|
|
2055
|
+
effectiveWavelength,
|
|
2056
|
+
wavePhase
|
|
697
2057
|
);
|
|
698
2058
|
if (indeterminateWavyActivePathRef.current) {
|
|
699
2059
|
indeterminateWavyActivePathRef.current.setAttribute("d", dynamicPath);
|
|
@@ -788,7 +2148,7 @@ var CircularProgress = React18.forwardRef(
|
|
|
788
2148
|
style: { width: size, height: size }
|
|
789
2149
|
}, restProps), {
|
|
790
2150
|
children: /* @__PURE__ */ jsxs(LazyMotion, { features: domMax, strict: true, children: [
|
|
791
|
-
/* @__PURE__ */
|
|
2151
|
+
/* @__PURE__ */ jsx(
|
|
792
2152
|
"svg",
|
|
793
2153
|
{
|
|
794
2154
|
width: size,
|
|
@@ -796,8 +2156,18 @@ var CircularProgress = React18.forwardRef(
|
|
|
796
2156
|
viewBox: `0 0 ${size} ${size}`,
|
|
797
2157
|
"aria-hidden": "true",
|
|
798
2158
|
style: { transform: "rotate(-90deg)", overflow: "visible" },
|
|
799
|
-
children: [
|
|
800
|
-
|
|
2159
|
+
children: isDeterminate ? isWavy ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
2160
|
+
shouldShowDeterminateTrack && (trackShape === "wavy" ? /* @__PURE__ */ jsx(
|
|
2161
|
+
"path",
|
|
2162
|
+
{
|
|
2163
|
+
ref: determinateWavyTrackPathRef,
|
|
2164
|
+
d: wavyActivePath != null ? wavyActivePath : "",
|
|
2165
|
+
fill: "none",
|
|
2166
|
+
stroke: bgTrackColor,
|
|
2167
|
+
strokeWidth: trackHeight,
|
|
2168
|
+
strokeLinecap: "round"
|
|
2169
|
+
}
|
|
2170
|
+
) : /* @__PURE__ */ jsx(
|
|
801
2171
|
m.circle,
|
|
802
2172
|
{
|
|
803
2173
|
cx: center,
|
|
@@ -806,28 +2176,52 @@ var CircularProgress = React18.forwardRef(
|
|
|
806
2176
|
fill: "none",
|
|
807
2177
|
stroke: bgTrackColor,
|
|
808
2178
|
strokeWidth: trackHeight,
|
|
809
|
-
initial: {
|
|
810
|
-
|
|
2179
|
+
initial: {
|
|
2180
|
+
pathLength: trackLength,
|
|
2181
|
+
pathOffset: trackOffset
|
|
2182
|
+
},
|
|
2183
|
+
animate: {
|
|
2184
|
+
pathLength: trackLength,
|
|
2185
|
+
pathOffset: trackOffset
|
|
2186
|
+
},
|
|
811
2187
|
transition: { duration: 0.4, ease: [0.2, 0, 0, 1] },
|
|
812
2188
|
strokeLinecap: "round"
|
|
813
2189
|
}
|
|
814
|
-
)
|
|
815
|
-
|
|
816
|
-
|
|
2190
|
+
)),
|
|
2191
|
+
/* @__PURE__ */ jsx(
|
|
2192
|
+
"path",
|
|
817
2193
|
{
|
|
2194
|
+
ref: determinateWavyActivePathRef,
|
|
818
2195
|
d: wavyActivePath != null ? wavyActivePath : "",
|
|
819
2196
|
fill: "none",
|
|
820
2197
|
stroke: activeColor,
|
|
821
2198
|
strokeWidth: trackHeight,
|
|
822
|
-
strokeLinecap: "round"
|
|
823
|
-
initial: { pathLength: 0 },
|
|
824
|
-
animate: { pathLength: clampedValue / 100 },
|
|
825
|
-
transition: {
|
|
826
|
-
duration: 0.4,
|
|
827
|
-
ease: [0.2, 0, 0, 1]
|
|
828
|
-
}
|
|
2199
|
+
strokeLinecap: "round"
|
|
829
2200
|
}
|
|
830
|
-
)
|
|
2201
|
+
)
|
|
2202
|
+
] }) : /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
2203
|
+
/* @__PURE__ */ jsx(
|
|
2204
|
+
m.circle,
|
|
2205
|
+
{
|
|
2206
|
+
cx: center,
|
|
2207
|
+
cy: center,
|
|
2208
|
+
r: radius,
|
|
2209
|
+
fill: "none",
|
|
2210
|
+
stroke: bgTrackColor,
|
|
2211
|
+
strokeWidth: trackHeight,
|
|
2212
|
+
initial: {
|
|
2213
|
+
pathLength: trackLength,
|
|
2214
|
+
pathOffset: trackOffset
|
|
2215
|
+
},
|
|
2216
|
+
animate: {
|
|
2217
|
+
pathLength: trackLength,
|
|
2218
|
+
pathOffset: trackOffset
|
|
2219
|
+
},
|
|
2220
|
+
transition: { duration: 0.4, ease: [0.2, 0, 0, 1] },
|
|
2221
|
+
strokeLinecap: "round"
|
|
2222
|
+
}
|
|
2223
|
+
),
|
|
2224
|
+
/* @__PURE__ */ jsx(
|
|
831
2225
|
ActiveCircleElem,
|
|
832
2226
|
{
|
|
833
2227
|
cx: center,
|
|
@@ -844,8 +2238,8 @@ var CircularProgress = React18.forwardRef(
|
|
|
844
2238
|
ease: [0.2, 0, 0, 1]
|
|
845
2239
|
}
|
|
846
2240
|
}
|
|
847
|
-
)
|
|
848
|
-
]
|
|
2241
|
+
)
|
|
2242
|
+
] }) : null
|
|
849
2243
|
}
|
|
850
2244
|
),
|
|
851
2245
|
!isDeterminate && /* @__PURE__ */ jsx(
|
|
@@ -923,9 +2317,9 @@ var CircularProgress = React18.forwardRef(
|
|
|
923
2317
|
);
|
|
924
2318
|
CircularProgress.displayName = "CircularProgress";
|
|
925
2319
|
function useContainerWidth() {
|
|
926
|
-
const [width, setWidth] =
|
|
927
|
-
const observerRef =
|
|
928
|
-
const ref =
|
|
2320
|
+
const [width, setWidth] = React23.useState(0);
|
|
2321
|
+
const observerRef = React23.useRef(null);
|
|
2322
|
+
const ref = React23.useCallback((node) => {
|
|
929
2323
|
if (observerRef.current) {
|
|
930
2324
|
observerRef.current.disconnect();
|
|
931
2325
|
observerRef.current = null;
|
|
@@ -939,7 +2333,7 @@ function useContainerWidth() {
|
|
|
939
2333
|
observerRef.current = obs;
|
|
940
2334
|
}
|
|
941
2335
|
}, []);
|
|
942
|
-
|
|
2336
|
+
React23.useEffect(() => {
|
|
943
2337
|
return () => {
|
|
944
2338
|
if (observerRef.current) {
|
|
945
2339
|
observerRef.current.disconnect();
|
|
@@ -949,7 +2343,7 @@ function useContainerWidth() {
|
|
|
949
2343
|
return [ref, width];
|
|
950
2344
|
}
|
|
951
2345
|
function useMergedRef(...refs) {
|
|
952
|
-
return
|
|
2346
|
+
return React23.useCallback(
|
|
953
2347
|
(node) => {
|
|
954
2348
|
for (const ref of refs) {
|
|
955
2349
|
if (typeof ref === "function") {
|
|
@@ -963,7 +2357,7 @@ function useMergedRef(...refs) {
|
|
|
963
2357
|
[refs]
|
|
964
2358
|
);
|
|
965
2359
|
}
|
|
966
|
-
var FlatLinearTrack =
|
|
2360
|
+
var FlatLinearTrack = React23.memo(function FlatLinearTrack2({
|
|
967
2361
|
trackHeight,
|
|
968
2362
|
activeColor,
|
|
969
2363
|
trackColor,
|
|
@@ -1039,7 +2433,7 @@ var FlatLinearTrack = React18.memo(function FlatLinearTrack2({
|
|
|
1039
2433
|
}
|
|
1040
2434
|
);
|
|
1041
2435
|
});
|
|
1042
|
-
var WavyLinearTrack =
|
|
2436
|
+
var WavyLinearTrack = React23.memo(function WavyLinearTrack2({
|
|
1043
2437
|
trackHeight,
|
|
1044
2438
|
svgHeight,
|
|
1045
2439
|
amplitude,
|
|
@@ -1058,13 +2452,13 @@ var WavyLinearTrack = React18.memo(function WavyLinearTrack2({
|
|
|
1058
2452
|
}) {
|
|
1059
2453
|
const isDeterminate = typeof value === "number";
|
|
1060
2454
|
const clampedValue = isDeterminate ? Math.max(0, Math.min(100, value)) : 100;
|
|
1061
|
-
const titleId =
|
|
2455
|
+
const titleId = React23.useId();
|
|
1062
2456
|
const [containerRef, width] = useContainerWidth();
|
|
1063
|
-
const activePathRef =
|
|
1064
|
-
const trackPathRef =
|
|
2457
|
+
const activePathRef = React23.useRef(null);
|
|
2458
|
+
const trackPathRef = React23.useRef(null);
|
|
1065
2459
|
const amplitudeMV = useMotionValue(amplitude);
|
|
1066
2460
|
const fractionMV = useMotionValue(isDeterminate ? clampedValue / 100 : 1);
|
|
1067
|
-
|
|
2461
|
+
React23.useEffect(() => {
|
|
1068
2462
|
if (isDeterminate) {
|
|
1069
2463
|
const fraction = clampedValue / 100;
|
|
1070
2464
|
let targetAmp = amplitude;
|
|
@@ -1252,7 +2646,7 @@ var WavyLinearTrack = React18.memo(function WavyLinearTrack2({
|
|
|
1252
2646
|
}
|
|
1253
2647
|
);
|
|
1254
2648
|
});
|
|
1255
|
-
var LinearProgress =
|
|
2649
|
+
var LinearProgress = React23.forwardRef(
|
|
1256
2650
|
(_a, ref) => {
|
|
1257
2651
|
var _b = _a, {
|
|
1258
2652
|
value,
|
|
@@ -1293,10 +2687,10 @@ var LinearProgress = React18.forwardRef(
|
|
|
1293
2687
|
]);
|
|
1294
2688
|
const isDeterminate = value !== void 0;
|
|
1295
2689
|
const clampedValue = isDeterminate ? Math.min(100, Math.max(0, value)) : 0;
|
|
1296
|
-
const containerRef =
|
|
2690
|
+
const containerRef = React23.useRef(null);
|
|
1297
2691
|
const mergedRef = useMergedRef(ref, containerRef);
|
|
1298
|
-
const [isRtl, setIsRtl] =
|
|
1299
|
-
|
|
2692
|
+
const [isRtl, setIsRtl] = React23.useState(false);
|
|
2693
|
+
React23.useEffect(() => {
|
|
1300
2694
|
if (containerRef.current) {
|
|
1301
2695
|
const dir = getComputedStyle(containerRef.current).direction;
|
|
1302
2696
|
setIsRtl(dir === "rtl");
|
|
@@ -1304,16 +2698,16 @@ var LinearProgress = React18.forwardRef(
|
|
|
1304
2698
|
}, []);
|
|
1305
2699
|
const resolvedTrackShape = trackShape != null ? trackShape : shape;
|
|
1306
2700
|
const isWavy = shape === "wavy" || resolvedTrackShape === "wavy";
|
|
1307
|
-
const effectiveAmplitude =
|
|
1308
|
-
const svgHeight =
|
|
2701
|
+
const effectiveAmplitude = React23.useMemo(() => amplitude != null ? amplitude : 3, [amplitude]);
|
|
2702
|
+
const svgHeight = React23.useMemo(
|
|
1309
2703
|
() => isWavy ? trackHeight + effectiveAmplitude * 2 : trackHeight,
|
|
1310
2704
|
[isWavy, trackHeight, effectiveAmplitude]
|
|
1311
2705
|
);
|
|
1312
|
-
const shouldShowStop =
|
|
2706
|
+
const shouldShowStop = React23.useMemo(
|
|
1313
2707
|
() => isDeterminate && resolvedTrackShape === "flat" && showStopIndicator !== false,
|
|
1314
2708
|
[isDeterminate, resolvedTrackShape, showStopIndicator]
|
|
1315
2709
|
);
|
|
1316
|
-
const stopSize =
|
|
2710
|
+
const stopSize = React23.useMemo(
|
|
1317
2711
|
() => Math.max(2, trackHeight > 4 ? 4 : trackHeight / 2),
|
|
1318
2712
|
[trackHeight]
|
|
1319
2713
|
);
|
|
@@ -1388,7 +2782,7 @@ var LinearProgress = React18.forwardRef(
|
|
|
1388
2782
|
}
|
|
1389
2783
|
);
|
|
1390
2784
|
LinearProgress.displayName = "LinearProgress";
|
|
1391
|
-
var ProgressIndicator =
|
|
2785
|
+
var ProgressIndicator = React23.forwardRef((props, ref) => {
|
|
1392
2786
|
if (props.variant === "circular") {
|
|
1393
2787
|
return /* @__PURE__ */ jsx(CircularProgress, __spreadValues({ ref }, props));
|
|
1394
2788
|
}
|
|
@@ -1642,7 +3036,7 @@ function AnimatedIconSlot({
|
|
|
1642
3036
|
}
|
|
1643
3037
|
);
|
|
1644
3038
|
}
|
|
1645
|
-
var ButtonComponent =
|
|
3039
|
+
var ButtonComponent = React23.forwardRef(
|
|
1646
3040
|
(_a, ref) => {
|
|
1647
3041
|
var _b = _a, {
|
|
1648
3042
|
className,
|
|
@@ -1708,9 +3102,9 @@ var ButtonComponent = React18.forwardRef(
|
|
|
1708
3102
|
borderWidth: outlineWidth != null ? outlineWidth : colorStyle === "outlined" ? sizeTokens.outlineWidth : 0,
|
|
1709
3103
|
borderStyle: colorStyle === "outlined" ? "solid" : void 0
|
|
1710
3104
|
}, style);
|
|
1711
|
-
const labelText =
|
|
3105
|
+
const labelText = React23.useMemo(() => {
|
|
1712
3106
|
if (asChild) {
|
|
1713
|
-
const child =
|
|
3107
|
+
const child = React23.Children.only(children);
|
|
1714
3108
|
return child.props.children;
|
|
1715
3109
|
}
|
|
1716
3110
|
return children;
|
|
@@ -1718,8 +3112,8 @@ var ButtonComponent = React18.forwardRef(
|
|
|
1718
3112
|
const computedAriaLabel = ariaLabelProp || (typeof children === "string" ? children : void 0);
|
|
1719
3113
|
const needsTouchTarget = size === "xs" || size === "sm";
|
|
1720
3114
|
const motionRadius = useMotionValue(animateRadius);
|
|
1721
|
-
const asChildRef =
|
|
1722
|
-
const mergedRef =
|
|
3115
|
+
const asChildRef = React23.useRef(null);
|
|
3116
|
+
const mergedRef = React23.useCallback(
|
|
1723
3117
|
(node) => {
|
|
1724
3118
|
asChildRef.current = node;
|
|
1725
3119
|
if (typeof ref === "function") ref(node);
|
|
@@ -1728,14 +3122,14 @@ var ButtonComponent = React18.forwardRef(
|
|
|
1728
3122
|
},
|
|
1729
3123
|
[ref]
|
|
1730
3124
|
);
|
|
1731
|
-
|
|
3125
|
+
React23.useEffect(() => {
|
|
1732
3126
|
if (!asChild) return;
|
|
1733
3127
|
return motionRadius.on("change", (v) => {
|
|
1734
3128
|
if (asChildRef.current)
|
|
1735
3129
|
asChildRef.current.style.borderRadius = `${v}px`;
|
|
1736
3130
|
});
|
|
1737
3131
|
}, [motionRadius, asChild]);
|
|
1738
|
-
|
|
3132
|
+
React23.useEffect(() => {
|
|
1739
3133
|
if (!asChild) return;
|
|
1740
3134
|
const controls = springAnimate(motionRadius, animateRadius);
|
|
1741
3135
|
return () => controls.stop();
|
|
@@ -1743,14 +3137,14 @@ var ButtonComponent = React18.forwardRef(
|
|
|
1743
3137
|
const { ripples, onPointerDown, removeRipple } = useRippleState({
|
|
1744
3138
|
disabled: loading
|
|
1745
3139
|
});
|
|
1746
|
-
const handleClick =
|
|
3140
|
+
const handleClick = React23.useCallback(
|
|
1747
3141
|
(e) => {
|
|
1748
3142
|
if (loading) return e.preventDefault();
|
|
1749
3143
|
onClick == null ? void 0 : onClick(e);
|
|
1750
3144
|
},
|
|
1751
3145
|
[loading, onClick]
|
|
1752
3146
|
);
|
|
1753
|
-
const handleKeyDown =
|
|
3147
|
+
const handleKeyDown = React23.useCallback(
|
|
1754
3148
|
(e) => {
|
|
1755
3149
|
if (loading) return;
|
|
1756
3150
|
if (onClick && (e.key === "Enter" || e.key === " ")) {
|
|
@@ -1829,17 +3223,17 @@ var ButtonComponent = React18.forwardRef(
|
|
|
1829
3223
|
isSelected && selectedIcon ? "selected-icon" : "icon"
|
|
1830
3224
|
) })
|
|
1831
3225
|
] });
|
|
1832
|
-
const handleAsChildPointerDown =
|
|
3226
|
+
const handleAsChildPointerDown = React23.useCallback(
|
|
1833
3227
|
(e) => {
|
|
1834
3228
|
springAnimate(motionRadius, pressedRadius);
|
|
1835
3229
|
onPointerDown == null ? void 0 : onPointerDown(e);
|
|
1836
3230
|
},
|
|
1837
3231
|
[motionRadius, pressedRadius, onPointerDown]
|
|
1838
3232
|
);
|
|
1839
|
-
const handleAsChildPointerUp =
|
|
3233
|
+
const handleAsChildPointerUp = React23.useCallback(() => {
|
|
1840
3234
|
springAnimate(motionRadius, animateRadius);
|
|
1841
3235
|
}, [motionRadius, animateRadius]);
|
|
1842
|
-
const handlePointerDown =
|
|
3236
|
+
const handlePointerDown = React23.useCallback(
|
|
1843
3237
|
(e) => {
|
|
1844
3238
|
onPointerDown(e);
|
|
1845
3239
|
},
|
|
@@ -1849,7 +3243,7 @@ var ButtonComponent = React18.forwardRef(
|
|
|
1849
3243
|
const strippedProps = __spreadValues({}, restProps);
|
|
1850
3244
|
for (const key of MOTION_PROP_KEYS) delete strippedProps[key];
|
|
1851
3245
|
const htmlProps = strippedProps;
|
|
1852
|
-
const child =
|
|
3246
|
+
const child = React23.Children.only(children);
|
|
1853
3247
|
return /* @__PURE__ */ jsx(LazyMotion, { features: domMax, strict: true, children: /* @__PURE__ */ jsx(
|
|
1854
3248
|
Slot,
|
|
1855
3249
|
__spreadProps(__spreadValues({
|
|
@@ -1866,7 +3260,7 @@ var ButtonComponent = React18.forwardRef(
|
|
|
1866
3260
|
}),
|
|
1867
3261
|
className: buttonClassName
|
|
1868
3262
|
}, htmlProps), {
|
|
1869
|
-
children:
|
|
3263
|
+
children: React23.cloneElement(child, { children: innerContent })
|
|
1870
3264
|
})
|
|
1871
3265
|
) });
|
|
1872
3266
|
}
|
|
@@ -1894,13 +3288,13 @@ var ButtonComponent = React18.forwardRef(
|
|
|
1894
3288
|
}
|
|
1895
3289
|
);
|
|
1896
3290
|
ButtonComponent.displayName = "Button";
|
|
1897
|
-
var Button =
|
|
3291
|
+
var Button = React23.memo(ButtonComponent);
|
|
1898
3292
|
var VARIANT_FONT = {
|
|
1899
3293
|
outlined: "'Material Symbols Outlined'",
|
|
1900
3294
|
rounded: "'Material Symbols Rounded'",
|
|
1901
3295
|
sharp: "'Material Symbols Sharp'"
|
|
1902
3296
|
};
|
|
1903
|
-
var IconComponent =
|
|
3297
|
+
var IconComponent = React23.forwardRef(
|
|
1904
3298
|
(_a, ref) => {
|
|
1905
3299
|
var _b = _a, {
|
|
1906
3300
|
name,
|
|
@@ -1966,8 +3360,8 @@ var IconComponent = React18.forwardRef(
|
|
|
1966
3360
|
}
|
|
1967
3361
|
);
|
|
1968
3362
|
IconComponent.displayName = "Icon";
|
|
1969
|
-
var Icon =
|
|
1970
|
-
var ScrollArea =
|
|
3363
|
+
var Icon = React23.memo(IconComponent);
|
|
3364
|
+
var ScrollArea = React23.forwardRef(
|
|
1971
3365
|
(_a, ref) => {
|
|
1972
3366
|
var _b = _a, {
|
|
1973
3367
|
className,
|
|
@@ -1988,15 +3382,15 @@ var ScrollArea = React18.forwardRef(
|
|
|
1988
3382
|
"viewportRef",
|
|
1989
3383
|
"viewportProps"
|
|
1990
3384
|
]);
|
|
1991
|
-
const [isTouchDevice, setIsTouchDevice] =
|
|
1992
|
-
|
|
3385
|
+
const [isTouchDevice, setIsTouchDevice] = React23.useState(false);
|
|
3386
|
+
React23.useEffect(() => {
|
|
1993
3387
|
if (typeof window !== "undefined") {
|
|
1994
3388
|
setIsTouchDevice(
|
|
1995
3389
|
"ontouchstart" in window || navigator.maxTouchPoints > 0
|
|
1996
3390
|
);
|
|
1997
3391
|
}
|
|
1998
3392
|
}, []);
|
|
1999
|
-
const resolvedType =
|
|
3393
|
+
const resolvedType = React23.useMemo(() => {
|
|
2000
3394
|
if (type === "hover" && isTouchDevice) {
|
|
2001
3395
|
return "scroll";
|
|
2002
3396
|
}
|
|
@@ -2047,7 +3441,7 @@ var ScrollArea = React18.forwardRef(
|
|
|
2047
3441
|
}
|
|
2048
3442
|
);
|
|
2049
3443
|
ScrollArea.displayName = "ScrollArea";
|
|
2050
|
-
var ScrollAreaScrollbar =
|
|
3444
|
+
var ScrollAreaScrollbar = React23.forwardRef((_a, ref) => {
|
|
2051
3445
|
var _b = _a, { className, orientation = "vertical" } = _b, props = __objRest(_b, ["className", "orientation"]);
|
|
2052
3446
|
return /* @__PURE__ */ jsx(
|
|
2053
3447
|
RadixScrollArea.Scrollbar,
|
|
@@ -2077,7 +3471,7 @@ var ScrollAreaScrollbar = React18.forwardRef((_a, ref) => {
|
|
|
2077
3471
|
);
|
|
2078
3472
|
});
|
|
2079
3473
|
ScrollAreaScrollbar.displayName = RadixScrollArea.Scrollbar.displayName;
|
|
2080
|
-
var ScrollAreaCorner =
|
|
3474
|
+
var ScrollAreaCorner = React23.forwardRef((_a, ref) => {
|
|
2081
3475
|
var _b = _a, { className } = _b, props = __objRest(_b, ["className"]);
|
|
2082
3476
|
return /* @__PURE__ */ jsx(
|
|
2083
3477
|
RadixScrollArea.Corner,
|
|
@@ -2273,7 +3667,7 @@ function buildWavePath(startX, endX, amplitude = 2, wavelength = 32, yCenter = 4
|
|
|
2273
3667
|
}
|
|
2274
3668
|
return d;
|
|
2275
3669
|
}
|
|
2276
|
-
var DividerImpl =
|
|
3670
|
+
var DividerImpl = React23.forwardRef(
|
|
2277
3671
|
(_a, ref) => {
|
|
2278
3672
|
var _b = _a, {
|
|
2279
3673
|
variant = "full-bleed",
|
|
@@ -2282,7 +3676,7 @@ var DividerImpl = React18.forwardRef(
|
|
|
2282
3676
|
insetStart = "standard",
|
|
2283
3677
|
waveConfig,
|
|
2284
3678
|
decorative = false,
|
|
2285
|
-
animate:
|
|
3679
|
+
animate: animate4 = true,
|
|
2286
3680
|
className,
|
|
2287
3681
|
style
|
|
2288
3682
|
} = _b, props = __objRest(_b, [
|
|
@@ -2298,7 +3692,7 @@ var DividerImpl = React18.forwardRef(
|
|
|
2298
3692
|
]);
|
|
2299
3693
|
var _a2, _b2, _c;
|
|
2300
3694
|
const reducedMotion = useReducedMotion();
|
|
2301
|
-
const shouldAnimate =
|
|
3695
|
+
const shouldAnimate = animate4 && !reducedMotion;
|
|
2302
3696
|
const effectiveShape = shape === "wavy" && orientation === "vertical" ? "flat" : shape;
|
|
2303
3697
|
if (shape === "wavy" && orientation === "vertical") {
|
|
2304
3698
|
console.warn(
|
|
@@ -2393,9 +3787,9 @@ var DividerImpl = React18.forwardRef(
|
|
|
2393
3787
|
}
|
|
2394
3788
|
);
|
|
2395
3789
|
DividerImpl.displayName = "Divider";
|
|
2396
|
-
var Divider =
|
|
2397
|
-
var ListContext =
|
|
2398
|
-
var useListContext = () =>
|
|
3790
|
+
var Divider = React23.memo(DividerImpl);
|
|
3791
|
+
var ListContext = React23.createContext(null);
|
|
3792
|
+
var useListContext = () => React23.useContext(ListContext);
|
|
2399
3793
|
var LIST_TOKENS = {
|
|
2400
3794
|
oneLineHeight: 56,
|
|
2401
3795
|
twoLineHeight: 72,
|
|
@@ -2460,9 +3854,9 @@ function resolveItemId(item) {
|
|
|
2460
3854
|
return String(item);
|
|
2461
3855
|
}
|
|
2462
3856
|
function isListItem(child) {
|
|
2463
|
-
return
|
|
3857
|
+
return React23.isValidElement(child) && child.props != null && typeof child.props === "object" && "value" in child.props;
|
|
2464
3858
|
}
|
|
2465
|
-
var ListImpl =
|
|
3859
|
+
var ListImpl = React23.forwardRef(
|
|
2466
3860
|
(_a, ref) => {
|
|
2467
3861
|
var _b = _a, {
|
|
2468
3862
|
className,
|
|
@@ -2493,12 +3887,12 @@ var ListImpl = React18.forwardRef(
|
|
|
2493
3887
|
"innerRadius",
|
|
2494
3888
|
"children"
|
|
2495
3889
|
]);
|
|
2496
|
-
const listRef =
|
|
2497
|
-
const [draggedOrder, setDraggedOrder] =
|
|
3890
|
+
const listRef = React23.useRef(null);
|
|
3891
|
+
const [draggedOrder, setDraggedOrder] = React23.useState(
|
|
2498
3892
|
null
|
|
2499
3893
|
);
|
|
2500
|
-
|
|
2501
|
-
const [selectedState, setSelectedState] =
|
|
3894
|
+
React23.useImperativeHandle(ref, () => listRef.current);
|
|
3895
|
+
const [selectedState, setSelectedState] = React23.useState(
|
|
2502
3896
|
() => {
|
|
2503
3897
|
var _a2;
|
|
2504
3898
|
const initialValue = (_a2 = value != null ? value : defaultValue) != null ? _a2 : [];
|
|
@@ -2508,13 +3902,13 @@ var ListImpl = React18.forwardRef(
|
|
|
2508
3902
|
}
|
|
2509
3903
|
);
|
|
2510
3904
|
const isControlled = value !== void 0;
|
|
2511
|
-
const selectedValues =
|
|
3905
|
+
const selectedValues = React23.useMemo(() => {
|
|
2512
3906
|
if (isControlled) {
|
|
2513
3907
|
return new Set(Array.isArray(value) ? value : value ? [value] : []);
|
|
2514
3908
|
}
|
|
2515
3909
|
return selectedState;
|
|
2516
3910
|
}, [isControlled, value, selectedState]);
|
|
2517
|
-
const onItemChange =
|
|
3911
|
+
const onItemChange = React23.useCallback(
|
|
2518
3912
|
(itemValue, selected) => {
|
|
2519
3913
|
const nextSet = new Set(selectedValues);
|
|
2520
3914
|
if (selectionMode === "single-select") {
|
|
@@ -2546,11 +3940,11 @@ var ListImpl = React18.forwardRef(
|
|
|
2546
3940
|
coordinateGetter: sortableKeyboardCoordinates
|
|
2547
3941
|
})
|
|
2548
3942
|
);
|
|
2549
|
-
const itemIds =
|
|
3943
|
+
const itemIds = React23.useMemo(
|
|
2550
3944
|
() => items ? items.map(resolveItemId) : [],
|
|
2551
3945
|
[items]
|
|
2552
3946
|
);
|
|
2553
|
-
const currentOrder =
|
|
3947
|
+
const currentOrder = React23.useMemo(
|
|
2554
3948
|
() => draggedOrder || itemIds,
|
|
2555
3949
|
[draggedOrder, itemIds]
|
|
2556
3950
|
);
|
|
@@ -2610,20 +4004,20 @@ var ListImpl = React18.forwardRef(
|
|
|
2610
4004
|
}
|
|
2611
4005
|
(_a2 = focusableItems[nextIndex]) == null ? void 0 : _a2.focus();
|
|
2612
4006
|
};
|
|
2613
|
-
const childrenArray =
|
|
4007
|
+
const childrenArray = React23.Children.toArray(children);
|
|
2614
4008
|
const listItemCount = childrenArray.filter(isListItem).length;
|
|
2615
4009
|
let currentListItemIndex = 0;
|
|
2616
|
-
const processedChildren =
|
|
4010
|
+
const processedChildren = React23.Children.map(children, (child) => {
|
|
2617
4011
|
if (!isListItem(child)) return child;
|
|
2618
4012
|
const childValue = child.props.value;
|
|
2619
4013
|
const index = reorderable && currentOrder.length > 0 ? currentOrder.indexOf(String(childValue)) : currentListItemIndex;
|
|
2620
4014
|
currentListItemIndex++;
|
|
2621
|
-
return
|
|
4015
|
+
return React23.cloneElement(
|
|
2622
4016
|
child,
|
|
2623
4017
|
{ _listIndex: index }
|
|
2624
4018
|
);
|
|
2625
4019
|
});
|
|
2626
|
-
const contextValue =
|
|
4020
|
+
const contextValue = React23.useMemo(
|
|
2627
4021
|
() => ({
|
|
2628
4022
|
selectionMode,
|
|
2629
4023
|
variant,
|
|
@@ -2647,7 +4041,7 @@ var ListImpl = React18.forwardRef(
|
|
|
2647
4041
|
innerRadius
|
|
2648
4042
|
]
|
|
2649
4043
|
);
|
|
2650
|
-
const dndId =
|
|
4044
|
+
const dndId = React23.useId();
|
|
2651
4045
|
const isListbox = selectionMode === "single-select" || selectionMode === "multi-select";
|
|
2652
4046
|
const role = isListbox ? "listbox" : "list";
|
|
2653
4047
|
const ariaMultiselectable = selectionMode === "multi-select" ? true : void 0;
|
|
@@ -2694,13 +4088,13 @@ var ListImpl = React18.forwardRef(
|
|
|
2694
4088
|
}
|
|
2695
4089
|
);
|
|
2696
4090
|
ListImpl.displayName = "List";
|
|
2697
|
-
var List =
|
|
4091
|
+
var List = React23.memo(ListImpl);
|
|
2698
4092
|
var INSET_CLASSES = {
|
|
2699
4093
|
icon: "pl-[56px]",
|
|
2700
4094
|
avatar: "pl-[72px]",
|
|
2701
4095
|
custom: "pl-4"
|
|
2702
4096
|
};
|
|
2703
|
-
var ListDividerImpl =
|
|
4097
|
+
var ListDividerImpl = React23.forwardRef(
|
|
2704
4098
|
(_a, ref) => {
|
|
2705
4099
|
var _b = _a, { className, inset = false, insetType = "avatar" } = _b, props = __objRest(_b, ["className", "inset", "insetType"]);
|
|
2706
4100
|
const insetClass = inset ? INSET_CLASSES[insetType] : "";
|
|
@@ -2725,7 +4119,7 @@ var ListDividerImpl = React18.forwardRef(
|
|
|
2725
4119
|
}
|
|
2726
4120
|
);
|
|
2727
4121
|
ListDividerImpl.displayName = "ListDivider";
|
|
2728
|
-
var ListDivider =
|
|
4122
|
+
var ListDivider = React23.memo(ListDividerImpl);
|
|
2729
4123
|
var MD3_STANDARD = [0.2, 0, 0, 1];
|
|
2730
4124
|
var MD3_FAST_EFFECTS = [0.3, 0, 1, 1];
|
|
2731
4125
|
var CHECKMARK_PATH = "M 4.5 9.5 L 7.5 12.5 L 13.5 5.5";
|
|
@@ -2739,7 +4133,7 @@ var NEXT_STATE = {
|
|
|
2739
4133
|
checked: "indeterminate",
|
|
2740
4134
|
indeterminate: "unchecked"
|
|
2741
4135
|
};
|
|
2742
|
-
var CheckboxVisual =
|
|
4136
|
+
var CheckboxVisual = React23.memo(function CheckboxVisual2({
|
|
2743
4137
|
isSelected,
|
|
2744
4138
|
isIndeterminate,
|
|
2745
4139
|
containerBg,
|
|
@@ -2810,7 +4204,7 @@ var CheckboxVisual = React18.memo(function CheckboxVisual2({
|
|
|
2810
4204
|
);
|
|
2811
4205
|
});
|
|
2812
4206
|
function useMergedRef2(externalRef, internalRef) {
|
|
2813
|
-
return
|
|
4207
|
+
return React23.useCallback(
|
|
2814
4208
|
(node) => {
|
|
2815
4209
|
internalRef.current = node;
|
|
2816
4210
|
if (!externalRef) return;
|
|
@@ -2823,7 +4217,7 @@ function useMergedRef2(externalRef, internalRef) {
|
|
|
2823
4217
|
[externalRef, internalRef]
|
|
2824
4218
|
);
|
|
2825
4219
|
}
|
|
2826
|
-
var CheckboxComponent =
|
|
4220
|
+
var CheckboxComponent = React23.forwardRef(
|
|
2827
4221
|
({
|
|
2828
4222
|
checked,
|
|
2829
4223
|
defaultChecked = false,
|
|
@@ -2845,20 +4239,20 @@ var CheckboxComponent = React18.forwardRef(
|
|
|
2845
4239
|
}, ref) => {
|
|
2846
4240
|
var _a;
|
|
2847
4241
|
const prefersReduced = (_a = useReducedMotion()) != null ? _a : false;
|
|
2848
|
-
const generatedId =
|
|
4242
|
+
const generatedId = React23.useId();
|
|
2849
4243
|
const inputId = idProp != null ? idProp : label ? `checkbox-${generatedId}` : void 0;
|
|
2850
|
-
const [internalState, setInternalState] =
|
|
4244
|
+
const [internalState, setInternalState] = React23.useState(
|
|
2851
4245
|
() => defaultChecked ? "checked" : "unchecked"
|
|
2852
4246
|
);
|
|
2853
4247
|
const isControlled = stateProp !== void 0 || checked !== void 0;
|
|
2854
4248
|
const baseState = isControlled ? resolveState(checked, false, stateProp) : internalState;
|
|
2855
4249
|
const effectiveState = indeterminate ? "indeterminate" : baseState;
|
|
2856
|
-
const [ripples, setRipples] =
|
|
2857
|
-
const removeRipple =
|
|
4250
|
+
const [ripples, setRipples] = React23.useState([]);
|
|
4251
|
+
const removeRipple = React23.useCallback(
|
|
2858
4252
|
(id) => setRipples((prev) => prev.filter((r) => r.id !== id)),
|
|
2859
4253
|
[]
|
|
2860
4254
|
);
|
|
2861
|
-
const onPointerDown =
|
|
4255
|
+
const onPointerDown = React23.useCallback(
|
|
2862
4256
|
(e) => {
|
|
2863
4257
|
if (disabled) return;
|
|
2864
4258
|
const rect = e.currentTarget.getBoundingClientRect();
|
|
@@ -2872,7 +4266,7 @@ var CheckboxComponent = React18.forwardRef(
|
|
|
2872
4266
|
},
|
|
2873
4267
|
[disabled]
|
|
2874
4268
|
);
|
|
2875
|
-
const handleChange =
|
|
4269
|
+
const handleChange = React23.useCallback(
|
|
2876
4270
|
(e) => {
|
|
2877
4271
|
if (disabled) return;
|
|
2878
4272
|
if (stateProp !== void 0) {
|
|
@@ -2898,9 +4292,9 @@ var CheckboxComponent = React18.forwardRef(
|
|
|
2898
4292
|
onCheckedChange
|
|
2899
4293
|
]
|
|
2900
4294
|
);
|
|
2901
|
-
const inputRef =
|
|
4295
|
+
const inputRef = React23.useRef(null);
|
|
2902
4296
|
const mergedRef = useMergedRef2(ref, inputRef);
|
|
2903
|
-
|
|
4297
|
+
React23.useEffect(() => {
|
|
2904
4298
|
if (inputRef.current) {
|
|
2905
4299
|
inputRef.current.indeterminate = effectiveState === "indeterminate";
|
|
2906
4300
|
}
|
|
@@ -3025,19 +4419,19 @@ var CheckboxComponent = React18.forwardRef(
|
|
|
3025
4419
|
}
|
|
3026
4420
|
);
|
|
3027
4421
|
CheckboxComponent.displayName = "Checkbox";
|
|
3028
|
-
var Checkbox =
|
|
3029
|
-
var TriStateCheckboxComponent =
|
|
4422
|
+
var Checkbox = React23.memo(CheckboxComponent);
|
|
4423
|
+
var TriStateCheckboxComponent = React23.forwardRef((_a, ref) => {
|
|
3030
4424
|
var _b = _a, { state, onStateChange } = _b, rest = __objRest(_b, ["state", "onStateChange"]);
|
|
3031
4425
|
return /* @__PURE__ */ jsx(Checkbox, __spreadValues({ ref, state, onStateChange }, rest));
|
|
3032
4426
|
});
|
|
3033
4427
|
TriStateCheckboxComponent.displayName = "TriStateCheckbox";
|
|
3034
|
-
|
|
4428
|
+
React23.memo(TriStateCheckboxComponent);
|
|
3035
4429
|
var MD3_FAST_EFFECTS2 = [0.3, 0, 1, 1];
|
|
3036
|
-
var RadioGroupContext =
|
|
4430
|
+
var RadioGroupContext = React23.createContext(
|
|
3037
4431
|
null
|
|
3038
4432
|
);
|
|
3039
4433
|
function useMergedRef3(externalRef, internalRef) {
|
|
3040
|
-
return
|
|
4434
|
+
return React23.useCallback(
|
|
3041
4435
|
(node) => {
|
|
3042
4436
|
internalRef.current = node;
|
|
3043
4437
|
if (!externalRef) return;
|
|
@@ -3050,7 +4444,7 @@ function useMergedRef3(externalRef, internalRef) {
|
|
|
3050
4444
|
[externalRef, internalRef]
|
|
3051
4445
|
);
|
|
3052
4446
|
}
|
|
3053
|
-
var RadioVisual =
|
|
4447
|
+
var RadioVisual = React23.memo(function RadioVisual2({
|
|
3054
4448
|
isSelected,
|
|
3055
4449
|
disabled,
|
|
3056
4450
|
error,
|
|
@@ -3103,7 +4497,7 @@ var RadioVisual = React18.memo(function RadioVisual2({
|
|
|
3103
4497
|
}
|
|
3104
4498
|
);
|
|
3105
4499
|
});
|
|
3106
|
-
var RadioButtonComponent =
|
|
4500
|
+
var RadioButtonComponent = React23.forwardRef(
|
|
3107
4501
|
({
|
|
3108
4502
|
selected,
|
|
3109
4503
|
defaultSelected = false,
|
|
@@ -3122,23 +4516,23 @@ var RadioButtonComponent = React18.forwardRef(
|
|
|
3122
4516
|
required: requiredProp
|
|
3123
4517
|
}, ref) => {
|
|
3124
4518
|
var _a, _b;
|
|
3125
|
-
const group =
|
|
4519
|
+
const group = React23.useContext(RadioGroupContext);
|
|
3126
4520
|
const prefersReduced = (_a = useReducedMotion()) != null ? _a : false;
|
|
3127
|
-
const generatedId =
|
|
4521
|
+
const generatedId = React23.useId();
|
|
3128
4522
|
const inputId = idProp != null ? idProp : label ? `radio-${generatedId}` : void 0;
|
|
3129
4523
|
const name = (_b = group == null ? void 0 : group.name) != null ? _b : nameProp;
|
|
3130
4524
|
const disabled = (group == null ? void 0 : group.disabled) || disabledProp;
|
|
3131
4525
|
const error = (group == null ? void 0 : group.error) || errorProp || color === "error";
|
|
3132
4526
|
const required = (group == null ? void 0 : group.required) || requiredProp;
|
|
3133
|
-
const [internalSelected, setInternalSelected] =
|
|
4527
|
+
const [internalSelected, setInternalSelected] = React23.useState(defaultSelected);
|
|
3134
4528
|
const isControlled = selected !== void 0;
|
|
3135
4529
|
const isSelected = group ? group.selectedValue === value : isControlled ? selected != null ? selected : false : internalSelected;
|
|
3136
|
-
const [ripples, setRipples] =
|
|
3137
|
-
const removeRipple =
|
|
4530
|
+
const [ripples, setRipples] = React23.useState([]);
|
|
4531
|
+
const removeRipple = React23.useCallback(
|
|
3138
4532
|
(id) => setRipples((prev) => prev.filter((r) => r.id !== id)),
|
|
3139
4533
|
[]
|
|
3140
4534
|
);
|
|
3141
|
-
const onPointerDown =
|
|
4535
|
+
const onPointerDown = React23.useCallback(
|
|
3142
4536
|
(e) => {
|
|
3143
4537
|
if (disabled) return;
|
|
3144
4538
|
const rect = e.currentTarget.getBoundingClientRect();
|
|
@@ -3152,12 +4546,12 @@ var RadioButtonComponent = React18.forwardRef(
|
|
|
3152
4546
|
},
|
|
3153
4547
|
[disabled]
|
|
3154
4548
|
);
|
|
3155
|
-
const [isHovered, setIsHovered] =
|
|
3156
|
-
const onPointerEnter =
|
|
4549
|
+
const [isHovered, setIsHovered] = React23.useState(false);
|
|
4550
|
+
const onPointerEnter = React23.useCallback(() => {
|
|
3157
4551
|
if (!disabled) setIsHovered(true);
|
|
3158
4552
|
}, [disabled]);
|
|
3159
|
-
const onPointerLeave =
|
|
3160
|
-
const handleChange =
|
|
4553
|
+
const onPointerLeave = React23.useCallback(() => setIsHovered(false), []);
|
|
4554
|
+
const handleChange = React23.useCallback(
|
|
3161
4555
|
(_e) => {
|
|
3162
4556
|
if (disabled || onClick === null) return;
|
|
3163
4557
|
if (group) {
|
|
@@ -3171,7 +4565,7 @@ var RadioButtonComponent = React18.forwardRef(
|
|
|
3171
4565
|
},
|
|
3172
4566
|
[disabled, onClick, group, value, isControlled]
|
|
3173
4567
|
);
|
|
3174
|
-
const inputRef =
|
|
4568
|
+
const inputRef = React23.useRef(null);
|
|
3175
4569
|
const mergedRef = useMergedRef3(ref, inputRef);
|
|
3176
4570
|
const stateLayerBg = error ? "before:bg-m3-error" : "before:bg-m3-primary";
|
|
3177
4571
|
const stateLayerClass = cn(
|
|
@@ -3282,8 +4676,8 @@ var RadioButtonComponent = React18.forwardRef(
|
|
|
3282
4676
|
}
|
|
3283
4677
|
);
|
|
3284
4678
|
RadioButtonComponent.displayName = "RadioButton";
|
|
3285
|
-
var RadioButton =
|
|
3286
|
-
var RadioGroupComponent =
|
|
4679
|
+
var RadioButton = React23.memo(RadioButtonComponent);
|
|
4680
|
+
var RadioGroupComponent = React23.forwardRef(
|
|
3287
4681
|
({
|
|
3288
4682
|
name,
|
|
3289
4683
|
value: valueProp,
|
|
@@ -3298,19 +4692,19 @@ var RadioGroupComponent = React18.forwardRef(
|
|
|
3298
4692
|
children,
|
|
3299
4693
|
className
|
|
3300
4694
|
}, ref) => {
|
|
3301
|
-
const [internalValue, setInternalValue] =
|
|
4695
|
+
const [internalValue, setInternalValue] = React23.useState(defaultValue);
|
|
3302
4696
|
const isControlled = valueProp !== void 0;
|
|
3303
4697
|
const selectedValue = isControlled ? valueProp : internalValue;
|
|
3304
|
-
const handleValueChange =
|
|
4698
|
+
const handleValueChange = React23.useCallback(
|
|
3305
4699
|
(val) => {
|
|
3306
4700
|
if (!isControlled) setInternalValue(val);
|
|
3307
4701
|
onValueChange == null ? void 0 : onValueChange(val);
|
|
3308
4702
|
},
|
|
3309
4703
|
[isControlled, onValueChange]
|
|
3310
4704
|
);
|
|
3311
|
-
const groupRef =
|
|
4705
|
+
const groupRef = React23.useRef(null);
|
|
3312
4706
|
const mergedRef = useMergedRef3(ref, groupRef);
|
|
3313
|
-
const onKeyDown =
|
|
4707
|
+
const onKeyDown = React23.useCallback(
|
|
3314
4708
|
(e) => {
|
|
3315
4709
|
var _a, _b;
|
|
3316
4710
|
if (disabled) return;
|
|
@@ -3334,7 +4728,7 @@ var RadioGroupComponent = React18.forwardRef(
|
|
|
3334
4728
|
},
|
|
3335
4729
|
[disabled, handleValueChange]
|
|
3336
4730
|
);
|
|
3337
|
-
const contextValue =
|
|
4731
|
+
const contextValue = React23.useMemo(
|
|
3338
4732
|
() => ({
|
|
3339
4733
|
name,
|
|
3340
4734
|
selectedValue,
|
|
@@ -3369,7 +4763,7 @@ var RadioGroupComponent = React18.forwardRef(
|
|
|
3369
4763
|
}
|
|
3370
4764
|
);
|
|
3371
4765
|
RadioGroupComponent.displayName = "RadioGroup";
|
|
3372
|
-
|
|
4766
|
+
React23.memo(RadioGroupComponent);
|
|
3373
4767
|
|
|
3374
4768
|
// src/ui/switch/switch.tokens.ts
|
|
3375
4769
|
var SwitchTokens = {
|
|
@@ -3447,7 +4841,7 @@ function isIconVisible(thumbContent, icons, showOnlySelectedIcon, checked) {
|
|
|
3447
4841
|
if (icons) return true;
|
|
3448
4842
|
return showOnlySelectedIcon && checked;
|
|
3449
4843
|
}
|
|
3450
|
-
var SwitchVisual =
|
|
4844
|
+
var SwitchVisual = React23.memo(function SwitchVisual2({
|
|
3451
4845
|
checked,
|
|
3452
4846
|
disabled,
|
|
3453
4847
|
isPressed,
|
|
@@ -3567,7 +4961,7 @@ var SwitchVisual = React18.memo(function SwitchVisual2({
|
|
|
3567
4961
|
}
|
|
3568
4962
|
);
|
|
3569
4963
|
});
|
|
3570
|
-
var SwitchComponent =
|
|
4964
|
+
var SwitchComponent = React23.forwardRef(
|
|
3571
4965
|
({
|
|
3572
4966
|
checked,
|
|
3573
4967
|
onCheckedChange,
|
|
@@ -3585,16 +4979,16 @@ var SwitchComponent = React18.forwardRef(
|
|
|
3585
4979
|
}, ref) => {
|
|
3586
4980
|
var _a;
|
|
3587
4981
|
const prefersReduced = (_a = useReducedMotion()) != null ? _a : false;
|
|
3588
|
-
const [isPressed, setIsPressed] =
|
|
3589
|
-
const [isHovered, setIsHovered] =
|
|
3590
|
-
const [isFocused, setIsFocused] =
|
|
3591
|
-
const [ripples, setRipples] =
|
|
3592
|
-
const generatedId =
|
|
4982
|
+
const [isPressed, setIsPressed] = React23.useState(false);
|
|
4983
|
+
const [isHovered, setIsHovered] = React23.useState(false);
|
|
4984
|
+
const [isFocused, setIsFocused] = React23.useState(false);
|
|
4985
|
+
const [ripples, setRipples] = React23.useState([]);
|
|
4986
|
+
const generatedId = React23.useId();
|
|
3593
4987
|
const switchId = label ? `switch-${generatedId}` : void 0;
|
|
3594
|
-
const handleClick =
|
|
4988
|
+
const handleClick = React23.useCallback(() => {
|
|
3595
4989
|
if (!disabled) onCheckedChange(!checked);
|
|
3596
4990
|
}, [disabled, checked, onCheckedChange]);
|
|
3597
|
-
const handleKeyDown =
|
|
4991
|
+
const handleKeyDown = React23.useCallback(
|
|
3598
4992
|
(e) => {
|
|
3599
4993
|
if (disabled) return;
|
|
3600
4994
|
if (e.key === " " || e.key === "Enter") {
|
|
@@ -3604,7 +4998,7 @@ var SwitchComponent = React18.forwardRef(
|
|
|
3604
4998
|
},
|
|
3605
4999
|
[disabled, checked, onCheckedChange]
|
|
3606
5000
|
);
|
|
3607
|
-
const handlePointerDown =
|
|
5001
|
+
const handlePointerDown = React23.useCallback(
|
|
3608
5002
|
(e) => {
|
|
3609
5003
|
if (disabled) return;
|
|
3610
5004
|
setIsPressed(true);
|
|
@@ -3619,19 +5013,19 @@ var SwitchComponent = React18.forwardRef(
|
|
|
3619
5013
|
},
|
|
3620
5014
|
[disabled]
|
|
3621
5015
|
);
|
|
3622
|
-
const handlePointerUp =
|
|
5016
|
+
const handlePointerUp = React23.useCallback(() => {
|
|
3623
5017
|
setIsPressed(false);
|
|
3624
5018
|
}, []);
|
|
3625
|
-
const handlePointerEnter =
|
|
5019
|
+
const handlePointerEnter = React23.useCallback(() => {
|
|
3626
5020
|
if (!disabled) setIsHovered(true);
|
|
3627
5021
|
}, [disabled]);
|
|
3628
|
-
const handlePointerLeave =
|
|
5022
|
+
const handlePointerLeave = React23.useCallback(() => {
|
|
3629
5023
|
setIsHovered(false);
|
|
3630
5024
|
setIsPressed(false);
|
|
3631
5025
|
}, []);
|
|
3632
|
-
const handleFocus =
|
|
3633
|
-
const handleBlur =
|
|
3634
|
-
const removeRipple =
|
|
5026
|
+
const handleFocus = React23.useCallback(() => setIsFocused(true), []);
|
|
5027
|
+
const handleBlur = React23.useCallback(() => setIsFocused(false), []);
|
|
5028
|
+
const removeRipple = React23.useCallback(
|
|
3635
5029
|
(id) => setRipples((prev) => prev.filter((r) => r.id !== id)),
|
|
3636
5030
|
[]
|
|
3637
5031
|
);
|
|
@@ -3657,7 +5051,7 @@ var SwitchComponent = React18.forwardRef(
|
|
|
3657
5051
|
onFocus: handleFocus,
|
|
3658
5052
|
onBlur: handleBlur,
|
|
3659
5053
|
className: cn(
|
|
3660
|
-
"relative inline-flex items-center justify-center cursor-pointer select-none",
|
|
5054
|
+
"relative inline-flex items-center justify-center cursor-pointer select-none shrink-0",
|
|
3661
5055
|
// Touch target: 48×48 minimum (pad around 32px track)
|
|
3662
5056
|
"min-w-12 min-h-12",
|
|
3663
5057
|
// Focus ring — MD3 FocusIndicatorColor = secondary
|
|
@@ -3667,7 +5061,7 @@ var SwitchComponent = React18.forwardRef(
|
|
|
3667
5061
|
disabled && "pointer-events-none cursor-not-allowed",
|
|
3668
5062
|
!label && className
|
|
3669
5063
|
),
|
|
3670
|
-
children: /* @__PURE__ */ jsxs("div", { className: "relative overflow-hidden rounded-full", children: [
|
|
5064
|
+
children: /* @__PURE__ */ jsxs("div", { className: "relative overflow-hidden rounded-full shrink-0", children: [
|
|
3671
5065
|
/* @__PURE__ */ jsx(
|
|
3672
5066
|
SwitchVisual,
|
|
3673
5067
|
{
|
|
@@ -3716,7 +5110,7 @@ var SwitchComponent = React18.forwardRef(
|
|
|
3716
5110
|
}
|
|
3717
5111
|
);
|
|
3718
5112
|
SwitchComponent.displayName = "Switch";
|
|
3719
|
-
var Switch =
|
|
5113
|
+
var Switch = React23.memo(SwitchComponent);
|
|
3720
5114
|
|
|
3721
5115
|
// src/ui/lists/list-utils.ts
|
|
3722
5116
|
function getListItemHeight(hasOverline, supportingTextLines) {
|
|
@@ -3856,7 +5250,7 @@ function renderSwitchTrailing({
|
|
|
3856
5250
|
trailingClass
|
|
3857
5251
|
}) {
|
|
3858
5252
|
const isSelectingMode = selectionMode === "single-select" || selectionMode === "multi-select";
|
|
3859
|
-
const switchElement =
|
|
5253
|
+
const switchElement = React23.isValidElement(trailingContent) ? (() => {
|
|
3860
5254
|
const trailingProps = trailingContent.props;
|
|
3861
5255
|
const checkedValue = !isSelectingMode && trailingProps.checked !== void 0 ? trailingProps.checked : isSelected;
|
|
3862
5256
|
const disabledValue = trailingProps.disabled !== void 0 ? disabled || trailingProps.disabled : disabled;
|
|
@@ -3867,7 +5261,7 @@ function renderSwitchTrailing({
|
|
|
3867
5261
|
onItemChange(value, checked);
|
|
3868
5262
|
}
|
|
3869
5263
|
};
|
|
3870
|
-
return
|
|
5264
|
+
return React23.cloneElement(
|
|
3871
5265
|
trailingContent,
|
|
3872
5266
|
{ checked: checkedValue, disabled: disabledValue, onCheckedChange }
|
|
3873
5267
|
);
|
|
@@ -3892,7 +5286,7 @@ function renderSwitchTrailing({
|
|
|
3892
5286
|
)
|
|
3893
5287
|
);
|
|
3894
5288
|
}
|
|
3895
|
-
var ListItemImpl =
|
|
5289
|
+
var ListItemImpl = React23.forwardRef(
|
|
3896
5290
|
(_a, ref) => {
|
|
3897
5291
|
var _b = _a, {
|
|
3898
5292
|
className,
|
|
@@ -3948,9 +5342,9 @@ var ListItemImpl = React18.forwardRef(
|
|
|
3948
5342
|
});
|
|
3949
5343
|
const reorderable = (_e = context == null ? void 0 : context.reorderable) != null ? _e : false;
|
|
3950
5344
|
const isSelected = selected !== void 0 ? selected : (_f = context == null ? void 0 : context.selectedValues.has(value)) != null ? _f : false;
|
|
3951
|
-
const [isHovered, setIsHovered] =
|
|
3952
|
-
const [isFocused, setIsFocused] =
|
|
3953
|
-
const [isPressed, setIsPressed] =
|
|
5345
|
+
const [isHovered, setIsHovered] = React23.useState(false);
|
|
5346
|
+
const [isFocused, setIsFocused] = React23.useState(false);
|
|
5347
|
+
const [isPressed, setIsPressed] = React23.useState(false);
|
|
3954
5348
|
const { ripples, onPointerDown, removeRipple } = useRippleState({
|
|
3955
5349
|
disabled
|
|
3956
5350
|
});
|
|
@@ -3962,8 +5356,8 @@ var ListItemImpl = React18.forwardRef(
|
|
|
3962
5356
|
transition,
|
|
3963
5357
|
isDragging
|
|
3964
5358
|
} = useSortable({ id: value, disabled: !reorderable });
|
|
3965
|
-
const itemRef =
|
|
3966
|
-
const setRefs =
|
|
5359
|
+
const itemRef = React23.useRef(null);
|
|
5360
|
+
const setRefs = React23.useCallback(
|
|
3967
5361
|
(node) => {
|
|
3968
5362
|
itemRef.current = node;
|
|
3969
5363
|
setNodeRef(node);
|
|
@@ -4416,7 +5810,7 @@ var ListItemImpl = React18.forwardRef(
|
|
|
4416
5810
|
}
|
|
4417
5811
|
);
|
|
4418
5812
|
ListItemImpl.displayName = "ListItem";
|
|
4419
|
-
var ListItem =
|
|
5813
|
+
var ListItem = React23.memo(ListItemImpl);
|
|
4420
5814
|
var typographyVariants = cva("m-0 p-0 text-m3-on-surface", {
|
|
4421
5815
|
variants: {
|
|
4422
5816
|
variant: {
|
|
@@ -4442,10 +5836,10 @@ var typographyVariants = cva("m-0 p-0 text-m3-on-surface", {
|
|
|
4442
5836
|
variant: "body-md"
|
|
4443
5837
|
}
|
|
4444
5838
|
});
|
|
4445
|
-
var Text =
|
|
5839
|
+
var Text = React23.forwardRef(
|
|
4446
5840
|
(_a, ref) => {
|
|
4447
5841
|
var _b = _a, { className, variant, as: Component, color, weight, style } = _b, props = __objRest(_b, ["className", "variant", "as", "color", "weight", "style"]);
|
|
4448
|
-
const defaultComponent =
|
|
5842
|
+
const defaultComponent = React23.useMemo(() => {
|
|
4449
5843
|
const v = variant ? String(variant).toLowerCase() : "";
|
|
4450
5844
|
if (v.startsWith("display") || v.startsWith("headline")) return "h1";
|
|
4451
5845
|
if (v.startsWith("title")) return "h2";
|
|
@@ -5264,6 +6658,6 @@ function TypographyProvider({
|
|
|
5264
6658
|
return /* @__PURE__ */ jsx(TypographyContext.Provider, { value, children });
|
|
5265
6659
|
}
|
|
5266
6660
|
|
|
5267
|
-
export { Card, CodeBlock, DEFAULT_FONT_VARIATION_AXES, Divider, LIST_TOKENS, List, ListContext, ListDivider, ListItem, MD3_EXPRESSIVE_FONT_VARIATION, ScrollArea, ScrollAreaScrollbar, TableOfContents, Text, TypeScaleTokens, Typography, TypographyContext, TypographyKeyTokens, TypographyProvider, TypographyTokens, buildWavePath, getExpressiveShape, getListItemHeight, serializeFontVariationAxes, shouldTopAlign, typographyVariants, useListContext, useTypography };
|
|
6661
|
+
export { Card, CardContent, CardFooter, CardHeader, CardMedia, Carousel, CarouselGrid, CarouselItem, CarouselScrollClient, CarouselTokens, CodeBlock, DEFAULT_FONT_VARIATION_AXES, Divider, LIST_TOKENS, List, ListContext, ListDivider, ListItem, MD3_EXPRESSIVE_FONT_VARIATION, SHADOW, ScrollArea, ScrollAreaScrollbar, TableOfContents, Text, TypeScaleTokens, Typography, TypographyContext, TypographyKeyTokens, TypographyProvider, TypographyTokens, VARIANT_ELEVATION, buildWavePath, cardVariants, getExpressiveShape, getListItemHeight, resolveElevationShadow, serializeFontVariationAxes, shouldTopAlign, typographyVariants, useCardElevation, useCarouselA11y, useCarouselKeylines, useListContext, useTypography };
|
|
5268
6662
|
//# sourceMappingURL=layout.mjs.map
|
|
5269
6663
|
//# sourceMappingURL=layout.mjs.map
|