@bug-on/m3-expressive 1.3.1 → 1.3.3
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 +113 -60
- package/dist/buttons.d.mts +3 -3
- package/dist/buttons.d.ts +3 -3
- 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 +9 -7
- package/dist/core.js.map +1 -1
- package/dist/core.mjs +9 -7
- package/dist/core.mjs.map +1 -1
- package/dist/feedback.d.mts +2 -1
- package/dist/feedback.d.ts +2 -1
- package/dist/feedback.js +11 -8
- package/dist/feedback.js.map +1 -1
- package/dist/feedback.mjs +11 -9
- package/dist/feedback.mjs.map +1 -1
- package/dist/forms.d.mts +4 -3
- package/dist/forms.d.ts +4 -3
- package/dist/forms.js +5084 -2987
- package/dist/forms.js.map +1 -1
- package/dist/forms.mjs +5083 -2989
- 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 +13 -83
- package/dist/index.d.ts +13 -83
- package/dist/index.js +2843 -1210
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +2692 -1072
- package/dist/index.mjs.map +1 -1
- package/dist/layout.d.mts +496 -37
- package/dist/layout.d.ts +496 -37
- package/dist/layout.js +1537 -238
- package/dist/layout.js.map +1 -1
- package/dist/layout.mjs +1509 -226
- 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 +28 -296
- package/dist/navigation.d.ts +28 -296
- package/dist/navigation.js +584 -288
- package/dist/navigation.js.map +1 -1
- package/dist/navigation.mjs +576 -282
- package/dist/navigation.mjs.map +1 -1
- package/dist/overlays.d.mts +2 -2
- package/dist/overlays.d.ts +2 -2
- 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-DTQJjzsB.d.ts → split-button-trailing-uncheckable-CGzk7KcG.d.ts} +1 -1
- package/dist/{split-button-trailing-uncheckable-CIVEYgjY.d.mts → split-button-trailing-uncheckable-gAz6OAIi.d.mts} +1 -1
- package/dist/{text-field-Ear3hCSq.d.mts → text-field-4OlT9o8s.d.mts} +155 -5
- package/dist/{text-field-CiOmDM_8.d.ts → text-field-DARNdj14.d.ts} +155 -5
- package/llms-full.txt +255 -0
- package/llms.txt +102 -0
- package/package.json +10 -5
package/dist/layout.mjs
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import { Slot } from '@radix-ui/react-slot';
|
|
3
3
|
import { cva } from 'class-variance-authority';
|
|
4
4
|
import { m, LazyMotion, domMax, useMotionValue, animate, useAnimationFrame, AnimatePresence, useReducedMotion } from 'motion/react';
|
|
5
|
-
import * as
|
|
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",
|
|
@@ -555,7 +1818,7 @@ 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,
|
|
@@ -609,19 +1872,19 @@ var CircularProgress = React18.forwardRef(
|
|
|
609
1872
|
const shouldShowDeterminateTrack = showTrack === "auto" ? true : showTrack;
|
|
610
1873
|
const BASELINE_SIZE = 48;
|
|
611
1874
|
const scaleFactor = size / BASELINE_SIZE;
|
|
612
|
-
const effectiveAmplitude =
|
|
1875
|
+
const effectiveAmplitude = React23.useMemo(
|
|
613
1876
|
() => amplitude != null ? amplitude : 1.6 * scaleFactor,
|
|
614
1877
|
[amplitude, scaleFactor]
|
|
615
1878
|
);
|
|
616
|
-
const effectiveWavelength =
|
|
1879
|
+
const effectiveWavelength = React23.useMemo(
|
|
617
1880
|
() => wavelength != null ? wavelength : 15 * scaleFactor,
|
|
618
1881
|
[wavelength, scaleFactor]
|
|
619
1882
|
);
|
|
620
|
-
const resolvedAmplitudeRange =
|
|
1883
|
+
const resolvedAmplitudeRange = React23.useMemo(
|
|
621
1884
|
() => amplitudeRange != null ? amplitudeRange : [0, effectiveAmplitude],
|
|
622
1885
|
[amplitudeRange, effectiveAmplitude]
|
|
623
1886
|
);
|
|
624
|
-
const wavyActivePath =
|
|
1887
|
+
const wavyActivePath = React23.useMemo(
|
|
625
1888
|
() => isWavy ? generateWavyCircularPath(
|
|
626
1889
|
center,
|
|
627
1890
|
radius,
|
|
@@ -630,8 +1893,8 @@ var CircularProgress = React18.forwardRef(
|
|
|
630
1893
|
) : null,
|
|
631
1894
|
[isWavy, center, radius, effectiveAmplitude, effectiveWavelength]
|
|
632
1895
|
);
|
|
633
|
-
const circumference =
|
|
634
|
-
const gapForTrack =
|
|
1896
|
+
const circumference = React23.useMemo(() => 2 * Math.PI * radius, [radius]);
|
|
1897
|
+
const gapForTrack = React23.useMemo(
|
|
635
1898
|
() => (gapSize + trackHeight) / circumference,
|
|
636
1899
|
[gapSize, trackHeight, circumference]
|
|
637
1900
|
);
|
|
@@ -639,17 +1902,17 @@ var CircularProgress = React18.forwardRef(
|
|
|
639
1902
|
const trackOffset = isDeterminate ? activeAngularFraction + gapForTrack : 0;
|
|
640
1903
|
const trackLength = isDeterminate ? Math.max(1e-3, 1 - activeAngularFraction - 2 * gapForTrack) : 1;
|
|
641
1904
|
const ActiveCircleElem = m.circle;
|
|
642
|
-
const indeterminateSvgRef =
|
|
643
|
-
const indeterminateTrackRef =
|
|
644
|
-
const indeterminateActiveRef =
|
|
645
|
-
const indeterminateWavyTrackPathRef =
|
|
646
|
-
const indeterminateWavyActivePathRef =
|
|
647
|
-
const determinateWavyActivePathRef =
|
|
648
|
-
const determinateWavyTrackPathRef =
|
|
649
|
-
const cachedPathLengthRef =
|
|
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);
|
|
650
1913
|
const fractionMV = useMotionValue(isDeterminate ? clampedValue / 100 : 0);
|
|
651
1914
|
const amplitudeMV = useMotionValue(isWavy ? effectiveAmplitude : 0);
|
|
652
|
-
|
|
1915
|
+
React23.useEffect(() => {
|
|
653
1916
|
if (isDeterminate) {
|
|
654
1917
|
animate(fractionMV, clampedValue / 100, {
|
|
655
1918
|
duration: 0.4,
|
|
@@ -657,7 +1920,7 @@ var CircularProgress = React18.forwardRef(
|
|
|
657
1920
|
});
|
|
658
1921
|
}
|
|
659
1922
|
}, [clampedValue, isDeterminate, fractionMV]);
|
|
660
|
-
|
|
1923
|
+
React23.useEffect(() => {
|
|
661
1924
|
if (!isDeterminate || !isWavy) return;
|
|
662
1925
|
const fraction = clampedValue / 100;
|
|
663
1926
|
let targetAmp = effectiveAmplitude;
|
|
@@ -677,7 +1940,7 @@ var CircularProgress = React18.forwardRef(
|
|
|
677
1940
|
amplitudeMV,
|
|
678
1941
|
determinateAnimation
|
|
679
1942
|
]);
|
|
680
|
-
|
|
1943
|
+
React23.useLayoutEffect(() => {
|
|
681
1944
|
if (!isWavy || !wavyActivePath) {
|
|
682
1945
|
cachedPathLengthRef.current = circumference;
|
|
683
1946
|
return;
|
|
@@ -1054,9 +2317,9 @@ var CircularProgress = React18.forwardRef(
|
|
|
1054
2317
|
);
|
|
1055
2318
|
CircularProgress.displayName = "CircularProgress";
|
|
1056
2319
|
function useContainerWidth() {
|
|
1057
|
-
const [width, setWidth] =
|
|
1058
|
-
const observerRef =
|
|
1059
|
-
const ref =
|
|
2320
|
+
const [width, setWidth] = React23.useState(0);
|
|
2321
|
+
const observerRef = React23.useRef(null);
|
|
2322
|
+
const ref = React23.useCallback((node) => {
|
|
1060
2323
|
if (observerRef.current) {
|
|
1061
2324
|
observerRef.current.disconnect();
|
|
1062
2325
|
observerRef.current = null;
|
|
@@ -1070,7 +2333,7 @@ function useContainerWidth() {
|
|
|
1070
2333
|
observerRef.current = obs;
|
|
1071
2334
|
}
|
|
1072
2335
|
}, []);
|
|
1073
|
-
|
|
2336
|
+
React23.useEffect(() => {
|
|
1074
2337
|
return () => {
|
|
1075
2338
|
if (observerRef.current) {
|
|
1076
2339
|
observerRef.current.disconnect();
|
|
@@ -1080,7 +2343,7 @@ function useContainerWidth() {
|
|
|
1080
2343
|
return [ref, width];
|
|
1081
2344
|
}
|
|
1082
2345
|
function useMergedRef(...refs) {
|
|
1083
|
-
return
|
|
2346
|
+
return React23.useCallback(
|
|
1084
2347
|
(node) => {
|
|
1085
2348
|
for (const ref of refs) {
|
|
1086
2349
|
if (typeof ref === "function") {
|
|
@@ -1094,7 +2357,7 @@ function useMergedRef(...refs) {
|
|
|
1094
2357
|
[refs]
|
|
1095
2358
|
);
|
|
1096
2359
|
}
|
|
1097
|
-
var FlatLinearTrack =
|
|
2360
|
+
var FlatLinearTrack = React23.memo(function FlatLinearTrack2({
|
|
1098
2361
|
trackHeight,
|
|
1099
2362
|
activeColor,
|
|
1100
2363
|
trackColor,
|
|
@@ -1170,7 +2433,7 @@ var FlatLinearTrack = React18.memo(function FlatLinearTrack2({
|
|
|
1170
2433
|
}
|
|
1171
2434
|
);
|
|
1172
2435
|
});
|
|
1173
|
-
var WavyLinearTrack =
|
|
2436
|
+
var WavyLinearTrack = React23.memo(function WavyLinearTrack2({
|
|
1174
2437
|
trackHeight,
|
|
1175
2438
|
svgHeight,
|
|
1176
2439
|
amplitude,
|
|
@@ -1189,13 +2452,13 @@ var WavyLinearTrack = React18.memo(function WavyLinearTrack2({
|
|
|
1189
2452
|
}) {
|
|
1190
2453
|
const isDeterminate = typeof value === "number";
|
|
1191
2454
|
const clampedValue = isDeterminate ? Math.max(0, Math.min(100, value)) : 100;
|
|
1192
|
-
const titleId =
|
|
2455
|
+
const titleId = React23.useId();
|
|
1193
2456
|
const [containerRef, width] = useContainerWidth();
|
|
1194
|
-
const activePathRef =
|
|
1195
|
-
const trackPathRef =
|
|
2457
|
+
const activePathRef = React23.useRef(null);
|
|
2458
|
+
const trackPathRef = React23.useRef(null);
|
|
1196
2459
|
const amplitudeMV = useMotionValue(amplitude);
|
|
1197
2460
|
const fractionMV = useMotionValue(isDeterminate ? clampedValue / 100 : 1);
|
|
1198
|
-
|
|
2461
|
+
React23.useEffect(() => {
|
|
1199
2462
|
if (isDeterminate) {
|
|
1200
2463
|
const fraction = clampedValue / 100;
|
|
1201
2464
|
let targetAmp = amplitude;
|
|
@@ -1383,7 +2646,7 @@ var WavyLinearTrack = React18.memo(function WavyLinearTrack2({
|
|
|
1383
2646
|
}
|
|
1384
2647
|
);
|
|
1385
2648
|
});
|
|
1386
|
-
var LinearProgress =
|
|
2649
|
+
var LinearProgress = React23.forwardRef(
|
|
1387
2650
|
(_a, ref) => {
|
|
1388
2651
|
var _b = _a, {
|
|
1389
2652
|
value,
|
|
@@ -1424,10 +2687,10 @@ var LinearProgress = React18.forwardRef(
|
|
|
1424
2687
|
]);
|
|
1425
2688
|
const isDeterminate = value !== void 0;
|
|
1426
2689
|
const clampedValue = isDeterminate ? Math.min(100, Math.max(0, value)) : 0;
|
|
1427
|
-
const containerRef =
|
|
2690
|
+
const containerRef = React23.useRef(null);
|
|
1428
2691
|
const mergedRef = useMergedRef(ref, containerRef);
|
|
1429
|
-
const [isRtl, setIsRtl] =
|
|
1430
|
-
|
|
2692
|
+
const [isRtl, setIsRtl] = React23.useState(false);
|
|
2693
|
+
React23.useEffect(() => {
|
|
1431
2694
|
if (containerRef.current) {
|
|
1432
2695
|
const dir = getComputedStyle(containerRef.current).direction;
|
|
1433
2696
|
setIsRtl(dir === "rtl");
|
|
@@ -1435,16 +2698,16 @@ var LinearProgress = React18.forwardRef(
|
|
|
1435
2698
|
}, []);
|
|
1436
2699
|
const resolvedTrackShape = trackShape != null ? trackShape : shape;
|
|
1437
2700
|
const isWavy = shape === "wavy" || resolvedTrackShape === "wavy";
|
|
1438
|
-
const effectiveAmplitude =
|
|
1439
|
-
const svgHeight =
|
|
2701
|
+
const effectiveAmplitude = React23.useMemo(() => amplitude != null ? amplitude : 3, [amplitude]);
|
|
2702
|
+
const svgHeight = React23.useMemo(
|
|
1440
2703
|
() => isWavy ? trackHeight + effectiveAmplitude * 2 : trackHeight,
|
|
1441
2704
|
[isWavy, trackHeight, effectiveAmplitude]
|
|
1442
2705
|
);
|
|
1443
|
-
const shouldShowStop =
|
|
2706
|
+
const shouldShowStop = React23.useMemo(
|
|
1444
2707
|
() => isDeterminate && resolvedTrackShape === "flat" && showStopIndicator !== false,
|
|
1445
2708
|
[isDeterminate, resolvedTrackShape, showStopIndicator]
|
|
1446
2709
|
);
|
|
1447
|
-
const stopSize =
|
|
2710
|
+
const stopSize = React23.useMemo(
|
|
1448
2711
|
() => Math.max(2, trackHeight > 4 ? 4 : trackHeight / 2),
|
|
1449
2712
|
[trackHeight]
|
|
1450
2713
|
);
|
|
@@ -1519,7 +2782,7 @@ var LinearProgress = React18.forwardRef(
|
|
|
1519
2782
|
}
|
|
1520
2783
|
);
|
|
1521
2784
|
LinearProgress.displayName = "LinearProgress";
|
|
1522
|
-
var ProgressIndicator =
|
|
2785
|
+
var ProgressIndicator = React23.forwardRef((props, ref) => {
|
|
1523
2786
|
if (props.variant === "circular") {
|
|
1524
2787
|
return /* @__PURE__ */ jsx(CircularProgress, __spreadValues({ ref }, props));
|
|
1525
2788
|
}
|
|
@@ -1773,7 +3036,7 @@ function AnimatedIconSlot({
|
|
|
1773
3036
|
}
|
|
1774
3037
|
);
|
|
1775
3038
|
}
|
|
1776
|
-
var ButtonComponent =
|
|
3039
|
+
var ButtonComponent = React23.forwardRef(
|
|
1777
3040
|
(_a, ref) => {
|
|
1778
3041
|
var _b = _a, {
|
|
1779
3042
|
className,
|
|
@@ -1839,9 +3102,9 @@ var ButtonComponent = React18.forwardRef(
|
|
|
1839
3102
|
borderWidth: outlineWidth != null ? outlineWidth : colorStyle === "outlined" ? sizeTokens.outlineWidth : 0,
|
|
1840
3103
|
borderStyle: colorStyle === "outlined" ? "solid" : void 0
|
|
1841
3104
|
}, style);
|
|
1842
|
-
const labelText =
|
|
3105
|
+
const labelText = React23.useMemo(() => {
|
|
1843
3106
|
if (asChild) {
|
|
1844
|
-
const child =
|
|
3107
|
+
const child = React23.Children.only(children);
|
|
1845
3108
|
return child.props.children;
|
|
1846
3109
|
}
|
|
1847
3110
|
return children;
|
|
@@ -1849,8 +3112,8 @@ var ButtonComponent = React18.forwardRef(
|
|
|
1849
3112
|
const computedAriaLabel = ariaLabelProp || (typeof children === "string" ? children : void 0);
|
|
1850
3113
|
const needsTouchTarget = size === "xs" || size === "sm";
|
|
1851
3114
|
const motionRadius = useMotionValue(animateRadius);
|
|
1852
|
-
const asChildRef =
|
|
1853
|
-
const mergedRef =
|
|
3115
|
+
const asChildRef = React23.useRef(null);
|
|
3116
|
+
const mergedRef = React23.useCallback(
|
|
1854
3117
|
(node) => {
|
|
1855
3118
|
asChildRef.current = node;
|
|
1856
3119
|
if (typeof ref === "function") ref(node);
|
|
@@ -1859,14 +3122,14 @@ var ButtonComponent = React18.forwardRef(
|
|
|
1859
3122
|
},
|
|
1860
3123
|
[ref]
|
|
1861
3124
|
);
|
|
1862
|
-
|
|
3125
|
+
React23.useEffect(() => {
|
|
1863
3126
|
if (!asChild) return;
|
|
1864
3127
|
return motionRadius.on("change", (v) => {
|
|
1865
3128
|
if (asChildRef.current)
|
|
1866
3129
|
asChildRef.current.style.borderRadius = `${v}px`;
|
|
1867
3130
|
});
|
|
1868
3131
|
}, [motionRadius, asChild]);
|
|
1869
|
-
|
|
3132
|
+
React23.useEffect(() => {
|
|
1870
3133
|
if (!asChild) return;
|
|
1871
3134
|
const controls = springAnimate(motionRadius, animateRadius);
|
|
1872
3135
|
return () => controls.stop();
|
|
@@ -1874,14 +3137,14 @@ var ButtonComponent = React18.forwardRef(
|
|
|
1874
3137
|
const { ripples, onPointerDown, removeRipple } = useRippleState({
|
|
1875
3138
|
disabled: loading
|
|
1876
3139
|
});
|
|
1877
|
-
const handleClick =
|
|
3140
|
+
const handleClick = React23.useCallback(
|
|
1878
3141
|
(e) => {
|
|
1879
3142
|
if (loading) return e.preventDefault();
|
|
1880
3143
|
onClick == null ? void 0 : onClick(e);
|
|
1881
3144
|
},
|
|
1882
3145
|
[loading, onClick]
|
|
1883
3146
|
);
|
|
1884
|
-
const handleKeyDown =
|
|
3147
|
+
const handleKeyDown = React23.useCallback(
|
|
1885
3148
|
(e) => {
|
|
1886
3149
|
if (loading) return;
|
|
1887
3150
|
if (onClick && (e.key === "Enter" || e.key === " ")) {
|
|
@@ -1960,17 +3223,17 @@ var ButtonComponent = React18.forwardRef(
|
|
|
1960
3223
|
isSelected && selectedIcon ? "selected-icon" : "icon"
|
|
1961
3224
|
) })
|
|
1962
3225
|
] });
|
|
1963
|
-
const handleAsChildPointerDown =
|
|
3226
|
+
const handleAsChildPointerDown = React23.useCallback(
|
|
1964
3227
|
(e) => {
|
|
1965
3228
|
springAnimate(motionRadius, pressedRadius);
|
|
1966
3229
|
onPointerDown == null ? void 0 : onPointerDown(e);
|
|
1967
3230
|
},
|
|
1968
3231
|
[motionRadius, pressedRadius, onPointerDown]
|
|
1969
3232
|
);
|
|
1970
|
-
const handleAsChildPointerUp =
|
|
3233
|
+
const handleAsChildPointerUp = React23.useCallback(() => {
|
|
1971
3234
|
springAnimate(motionRadius, animateRadius);
|
|
1972
3235
|
}, [motionRadius, animateRadius]);
|
|
1973
|
-
const handlePointerDown =
|
|
3236
|
+
const handlePointerDown = React23.useCallback(
|
|
1974
3237
|
(e) => {
|
|
1975
3238
|
onPointerDown(e);
|
|
1976
3239
|
},
|
|
@@ -1980,7 +3243,7 @@ var ButtonComponent = React18.forwardRef(
|
|
|
1980
3243
|
const strippedProps = __spreadValues({}, restProps);
|
|
1981
3244
|
for (const key of MOTION_PROP_KEYS) delete strippedProps[key];
|
|
1982
3245
|
const htmlProps = strippedProps;
|
|
1983
|
-
const child =
|
|
3246
|
+
const child = React23.Children.only(children);
|
|
1984
3247
|
return /* @__PURE__ */ jsx(LazyMotion, { features: domMax, strict: true, children: /* @__PURE__ */ jsx(
|
|
1985
3248
|
Slot,
|
|
1986
3249
|
__spreadProps(__spreadValues({
|
|
@@ -1997,7 +3260,7 @@ var ButtonComponent = React18.forwardRef(
|
|
|
1997
3260
|
}),
|
|
1998
3261
|
className: buttonClassName
|
|
1999
3262
|
}, htmlProps), {
|
|
2000
|
-
children:
|
|
3263
|
+
children: React23.cloneElement(child, { children: innerContent })
|
|
2001
3264
|
})
|
|
2002
3265
|
) });
|
|
2003
3266
|
}
|
|
@@ -2025,13 +3288,13 @@ var ButtonComponent = React18.forwardRef(
|
|
|
2025
3288
|
}
|
|
2026
3289
|
);
|
|
2027
3290
|
ButtonComponent.displayName = "Button";
|
|
2028
|
-
var Button =
|
|
3291
|
+
var Button = React23.memo(ButtonComponent);
|
|
2029
3292
|
var VARIANT_FONT = {
|
|
2030
3293
|
outlined: "'Material Symbols Outlined'",
|
|
2031
3294
|
rounded: "'Material Symbols Rounded'",
|
|
2032
3295
|
sharp: "'Material Symbols Sharp'"
|
|
2033
3296
|
};
|
|
2034
|
-
var IconComponent =
|
|
3297
|
+
var IconComponent = React23.forwardRef(
|
|
2035
3298
|
(_a, ref) => {
|
|
2036
3299
|
var _b = _a, {
|
|
2037
3300
|
name,
|
|
@@ -2097,8 +3360,8 @@ var IconComponent = React18.forwardRef(
|
|
|
2097
3360
|
}
|
|
2098
3361
|
);
|
|
2099
3362
|
IconComponent.displayName = "Icon";
|
|
2100
|
-
var Icon =
|
|
2101
|
-
var ScrollArea =
|
|
3363
|
+
var Icon = React23.memo(IconComponent);
|
|
3364
|
+
var ScrollArea = React23.forwardRef(
|
|
2102
3365
|
(_a, ref) => {
|
|
2103
3366
|
var _b = _a, {
|
|
2104
3367
|
className,
|
|
@@ -2119,15 +3382,15 @@ var ScrollArea = React18.forwardRef(
|
|
|
2119
3382
|
"viewportRef",
|
|
2120
3383
|
"viewportProps"
|
|
2121
3384
|
]);
|
|
2122
|
-
const [isTouchDevice, setIsTouchDevice] =
|
|
2123
|
-
|
|
3385
|
+
const [isTouchDevice, setIsTouchDevice] = React23.useState(false);
|
|
3386
|
+
React23.useEffect(() => {
|
|
2124
3387
|
if (typeof window !== "undefined") {
|
|
2125
3388
|
setIsTouchDevice(
|
|
2126
3389
|
"ontouchstart" in window || navigator.maxTouchPoints > 0
|
|
2127
3390
|
);
|
|
2128
3391
|
}
|
|
2129
3392
|
}, []);
|
|
2130
|
-
const resolvedType =
|
|
3393
|
+
const resolvedType = React23.useMemo(() => {
|
|
2131
3394
|
if (type === "hover" && isTouchDevice) {
|
|
2132
3395
|
return "scroll";
|
|
2133
3396
|
}
|
|
@@ -2178,7 +3441,7 @@ var ScrollArea = React18.forwardRef(
|
|
|
2178
3441
|
}
|
|
2179
3442
|
);
|
|
2180
3443
|
ScrollArea.displayName = "ScrollArea";
|
|
2181
|
-
var ScrollAreaScrollbar =
|
|
3444
|
+
var ScrollAreaScrollbar = React23.forwardRef((_a, ref) => {
|
|
2182
3445
|
var _b = _a, { className, orientation = "vertical" } = _b, props = __objRest(_b, ["className", "orientation"]);
|
|
2183
3446
|
return /* @__PURE__ */ jsx(
|
|
2184
3447
|
RadixScrollArea.Scrollbar,
|
|
@@ -2208,7 +3471,7 @@ var ScrollAreaScrollbar = React18.forwardRef((_a, ref) => {
|
|
|
2208
3471
|
);
|
|
2209
3472
|
});
|
|
2210
3473
|
ScrollAreaScrollbar.displayName = RadixScrollArea.Scrollbar.displayName;
|
|
2211
|
-
var ScrollAreaCorner =
|
|
3474
|
+
var ScrollAreaCorner = React23.forwardRef((_a, ref) => {
|
|
2212
3475
|
var _b = _a, { className } = _b, props = __objRest(_b, ["className"]);
|
|
2213
3476
|
return /* @__PURE__ */ jsx(
|
|
2214
3477
|
RadixScrollArea.Corner,
|
|
@@ -2404,7 +3667,7 @@ function buildWavePath(startX, endX, amplitude = 2, wavelength = 32, yCenter = 4
|
|
|
2404
3667
|
}
|
|
2405
3668
|
return d;
|
|
2406
3669
|
}
|
|
2407
|
-
var DividerImpl =
|
|
3670
|
+
var DividerImpl = React23.forwardRef(
|
|
2408
3671
|
(_a, ref) => {
|
|
2409
3672
|
var _b = _a, {
|
|
2410
3673
|
variant = "full-bleed",
|
|
@@ -2524,9 +3787,9 @@ var DividerImpl = React18.forwardRef(
|
|
|
2524
3787
|
}
|
|
2525
3788
|
);
|
|
2526
3789
|
DividerImpl.displayName = "Divider";
|
|
2527
|
-
var Divider =
|
|
2528
|
-
var ListContext =
|
|
2529
|
-
var useListContext = () =>
|
|
3790
|
+
var Divider = React23.memo(DividerImpl);
|
|
3791
|
+
var ListContext = React23.createContext(null);
|
|
3792
|
+
var useListContext = () => React23.useContext(ListContext);
|
|
2530
3793
|
var LIST_TOKENS = {
|
|
2531
3794
|
oneLineHeight: 56,
|
|
2532
3795
|
twoLineHeight: 72,
|
|
@@ -2591,9 +3854,9 @@ function resolveItemId(item) {
|
|
|
2591
3854
|
return String(item);
|
|
2592
3855
|
}
|
|
2593
3856
|
function isListItem(child) {
|
|
2594
|
-
return
|
|
3857
|
+
return React23.isValidElement(child) && child.props != null && typeof child.props === "object" && "value" in child.props;
|
|
2595
3858
|
}
|
|
2596
|
-
var ListImpl =
|
|
3859
|
+
var ListImpl = React23.forwardRef(
|
|
2597
3860
|
(_a, ref) => {
|
|
2598
3861
|
var _b = _a, {
|
|
2599
3862
|
className,
|
|
@@ -2624,12 +3887,12 @@ var ListImpl = React18.forwardRef(
|
|
|
2624
3887
|
"innerRadius",
|
|
2625
3888
|
"children"
|
|
2626
3889
|
]);
|
|
2627
|
-
const listRef =
|
|
2628
|
-
const [draggedOrder, setDraggedOrder] =
|
|
3890
|
+
const listRef = React23.useRef(null);
|
|
3891
|
+
const [draggedOrder, setDraggedOrder] = React23.useState(
|
|
2629
3892
|
null
|
|
2630
3893
|
);
|
|
2631
|
-
|
|
2632
|
-
const [selectedState, setSelectedState] =
|
|
3894
|
+
React23.useImperativeHandle(ref, () => listRef.current);
|
|
3895
|
+
const [selectedState, setSelectedState] = React23.useState(
|
|
2633
3896
|
() => {
|
|
2634
3897
|
var _a2;
|
|
2635
3898
|
const initialValue = (_a2 = value != null ? value : defaultValue) != null ? _a2 : [];
|
|
@@ -2639,13 +3902,13 @@ var ListImpl = React18.forwardRef(
|
|
|
2639
3902
|
}
|
|
2640
3903
|
);
|
|
2641
3904
|
const isControlled = value !== void 0;
|
|
2642
|
-
const selectedValues =
|
|
3905
|
+
const selectedValues = React23.useMemo(() => {
|
|
2643
3906
|
if (isControlled) {
|
|
2644
3907
|
return new Set(Array.isArray(value) ? value : value ? [value] : []);
|
|
2645
3908
|
}
|
|
2646
3909
|
return selectedState;
|
|
2647
3910
|
}, [isControlled, value, selectedState]);
|
|
2648
|
-
const onItemChange =
|
|
3911
|
+
const onItemChange = React23.useCallback(
|
|
2649
3912
|
(itemValue, selected) => {
|
|
2650
3913
|
const nextSet = new Set(selectedValues);
|
|
2651
3914
|
if (selectionMode === "single-select") {
|
|
@@ -2677,11 +3940,11 @@ var ListImpl = React18.forwardRef(
|
|
|
2677
3940
|
coordinateGetter: sortableKeyboardCoordinates
|
|
2678
3941
|
})
|
|
2679
3942
|
);
|
|
2680
|
-
const itemIds =
|
|
3943
|
+
const itemIds = React23.useMemo(
|
|
2681
3944
|
() => items ? items.map(resolveItemId) : [],
|
|
2682
3945
|
[items]
|
|
2683
3946
|
);
|
|
2684
|
-
const currentOrder =
|
|
3947
|
+
const currentOrder = React23.useMemo(
|
|
2685
3948
|
() => draggedOrder || itemIds,
|
|
2686
3949
|
[draggedOrder, itemIds]
|
|
2687
3950
|
);
|
|
@@ -2741,20 +4004,20 @@ var ListImpl = React18.forwardRef(
|
|
|
2741
4004
|
}
|
|
2742
4005
|
(_a2 = focusableItems[nextIndex]) == null ? void 0 : _a2.focus();
|
|
2743
4006
|
};
|
|
2744
|
-
const childrenArray =
|
|
4007
|
+
const childrenArray = React23.Children.toArray(children);
|
|
2745
4008
|
const listItemCount = childrenArray.filter(isListItem).length;
|
|
2746
4009
|
let currentListItemIndex = 0;
|
|
2747
|
-
const processedChildren =
|
|
4010
|
+
const processedChildren = React23.Children.map(children, (child) => {
|
|
2748
4011
|
if (!isListItem(child)) return child;
|
|
2749
4012
|
const childValue = child.props.value;
|
|
2750
4013
|
const index = reorderable && currentOrder.length > 0 ? currentOrder.indexOf(String(childValue)) : currentListItemIndex;
|
|
2751
4014
|
currentListItemIndex++;
|
|
2752
|
-
return
|
|
4015
|
+
return React23.cloneElement(
|
|
2753
4016
|
child,
|
|
2754
4017
|
{ _listIndex: index }
|
|
2755
4018
|
);
|
|
2756
4019
|
});
|
|
2757
|
-
const contextValue =
|
|
4020
|
+
const contextValue = React23.useMemo(
|
|
2758
4021
|
() => ({
|
|
2759
4022
|
selectionMode,
|
|
2760
4023
|
variant,
|
|
@@ -2778,7 +4041,7 @@ var ListImpl = React18.forwardRef(
|
|
|
2778
4041
|
innerRadius
|
|
2779
4042
|
]
|
|
2780
4043
|
);
|
|
2781
|
-
const dndId =
|
|
4044
|
+
const dndId = React23.useId();
|
|
2782
4045
|
const isListbox = selectionMode === "single-select" || selectionMode === "multi-select";
|
|
2783
4046
|
const role = isListbox ? "listbox" : "list";
|
|
2784
4047
|
const ariaMultiselectable = selectionMode === "multi-select" ? true : void 0;
|
|
@@ -2825,13 +4088,13 @@ var ListImpl = React18.forwardRef(
|
|
|
2825
4088
|
}
|
|
2826
4089
|
);
|
|
2827
4090
|
ListImpl.displayName = "List";
|
|
2828
|
-
var List =
|
|
4091
|
+
var List = React23.memo(ListImpl);
|
|
2829
4092
|
var INSET_CLASSES = {
|
|
2830
4093
|
icon: "pl-[56px]",
|
|
2831
4094
|
avatar: "pl-[72px]",
|
|
2832
4095
|
custom: "pl-4"
|
|
2833
4096
|
};
|
|
2834
|
-
var ListDividerImpl =
|
|
4097
|
+
var ListDividerImpl = React23.forwardRef(
|
|
2835
4098
|
(_a, ref) => {
|
|
2836
4099
|
var _b = _a, { className, inset = false, insetType = "avatar" } = _b, props = __objRest(_b, ["className", "inset", "insetType"]);
|
|
2837
4100
|
const insetClass = inset ? INSET_CLASSES[insetType] : "";
|
|
@@ -2856,7 +4119,7 @@ var ListDividerImpl = React18.forwardRef(
|
|
|
2856
4119
|
}
|
|
2857
4120
|
);
|
|
2858
4121
|
ListDividerImpl.displayName = "ListDivider";
|
|
2859
|
-
var ListDivider =
|
|
4122
|
+
var ListDivider = React23.memo(ListDividerImpl);
|
|
2860
4123
|
var MD3_STANDARD = [0.2, 0, 0, 1];
|
|
2861
4124
|
var MD3_FAST_EFFECTS = [0.3, 0, 1, 1];
|
|
2862
4125
|
var CHECKMARK_PATH = "M 4.5 9.5 L 7.5 12.5 L 13.5 5.5";
|
|
@@ -2870,7 +4133,7 @@ var NEXT_STATE = {
|
|
|
2870
4133
|
checked: "indeterminate",
|
|
2871
4134
|
indeterminate: "unchecked"
|
|
2872
4135
|
};
|
|
2873
|
-
var CheckboxVisual =
|
|
4136
|
+
var CheckboxVisual = React23.memo(function CheckboxVisual2({
|
|
2874
4137
|
isSelected,
|
|
2875
4138
|
isIndeterminate,
|
|
2876
4139
|
containerBg,
|
|
@@ -2941,7 +4204,7 @@ var CheckboxVisual = React18.memo(function CheckboxVisual2({
|
|
|
2941
4204
|
);
|
|
2942
4205
|
});
|
|
2943
4206
|
function useMergedRef2(externalRef, internalRef) {
|
|
2944
|
-
return
|
|
4207
|
+
return React23.useCallback(
|
|
2945
4208
|
(node) => {
|
|
2946
4209
|
internalRef.current = node;
|
|
2947
4210
|
if (!externalRef) return;
|
|
@@ -2954,7 +4217,7 @@ function useMergedRef2(externalRef, internalRef) {
|
|
|
2954
4217
|
[externalRef, internalRef]
|
|
2955
4218
|
);
|
|
2956
4219
|
}
|
|
2957
|
-
var CheckboxComponent =
|
|
4220
|
+
var CheckboxComponent = React23.forwardRef(
|
|
2958
4221
|
({
|
|
2959
4222
|
checked,
|
|
2960
4223
|
defaultChecked = false,
|
|
@@ -2976,20 +4239,20 @@ var CheckboxComponent = React18.forwardRef(
|
|
|
2976
4239
|
}, ref) => {
|
|
2977
4240
|
var _a;
|
|
2978
4241
|
const prefersReduced = (_a = useReducedMotion()) != null ? _a : false;
|
|
2979
|
-
const generatedId =
|
|
4242
|
+
const generatedId = React23.useId();
|
|
2980
4243
|
const inputId = idProp != null ? idProp : label ? `checkbox-${generatedId}` : void 0;
|
|
2981
|
-
const [internalState, setInternalState] =
|
|
4244
|
+
const [internalState, setInternalState] = React23.useState(
|
|
2982
4245
|
() => defaultChecked ? "checked" : "unchecked"
|
|
2983
4246
|
);
|
|
2984
4247
|
const isControlled = stateProp !== void 0 || checked !== void 0;
|
|
2985
4248
|
const baseState = isControlled ? resolveState(checked, false, stateProp) : internalState;
|
|
2986
4249
|
const effectiveState = indeterminate ? "indeterminate" : baseState;
|
|
2987
|
-
const [ripples, setRipples] =
|
|
2988
|
-
const removeRipple =
|
|
4250
|
+
const [ripples, setRipples] = React23.useState([]);
|
|
4251
|
+
const removeRipple = React23.useCallback(
|
|
2989
4252
|
(id) => setRipples((prev) => prev.filter((r) => r.id !== id)),
|
|
2990
4253
|
[]
|
|
2991
4254
|
);
|
|
2992
|
-
const onPointerDown =
|
|
4255
|
+
const onPointerDown = React23.useCallback(
|
|
2993
4256
|
(e) => {
|
|
2994
4257
|
if (disabled) return;
|
|
2995
4258
|
const rect = e.currentTarget.getBoundingClientRect();
|
|
@@ -3003,7 +4266,7 @@ var CheckboxComponent = React18.forwardRef(
|
|
|
3003
4266
|
},
|
|
3004
4267
|
[disabled]
|
|
3005
4268
|
);
|
|
3006
|
-
const handleChange =
|
|
4269
|
+
const handleChange = React23.useCallback(
|
|
3007
4270
|
(e) => {
|
|
3008
4271
|
if (disabled) return;
|
|
3009
4272
|
if (stateProp !== void 0) {
|
|
@@ -3029,9 +4292,9 @@ var CheckboxComponent = React18.forwardRef(
|
|
|
3029
4292
|
onCheckedChange
|
|
3030
4293
|
]
|
|
3031
4294
|
);
|
|
3032
|
-
const inputRef =
|
|
4295
|
+
const inputRef = React23.useRef(null);
|
|
3033
4296
|
const mergedRef = useMergedRef2(ref, inputRef);
|
|
3034
|
-
|
|
4297
|
+
React23.useEffect(() => {
|
|
3035
4298
|
if (inputRef.current) {
|
|
3036
4299
|
inputRef.current.indeterminate = effectiveState === "indeterminate";
|
|
3037
4300
|
}
|
|
@@ -3156,19 +4419,19 @@ var CheckboxComponent = React18.forwardRef(
|
|
|
3156
4419
|
}
|
|
3157
4420
|
);
|
|
3158
4421
|
CheckboxComponent.displayName = "Checkbox";
|
|
3159
|
-
var Checkbox =
|
|
3160
|
-
var TriStateCheckboxComponent =
|
|
4422
|
+
var Checkbox = React23.memo(CheckboxComponent);
|
|
4423
|
+
var TriStateCheckboxComponent = React23.forwardRef((_a, ref) => {
|
|
3161
4424
|
var _b = _a, { state, onStateChange } = _b, rest = __objRest(_b, ["state", "onStateChange"]);
|
|
3162
4425
|
return /* @__PURE__ */ jsx(Checkbox, __spreadValues({ ref, state, onStateChange }, rest));
|
|
3163
4426
|
});
|
|
3164
4427
|
TriStateCheckboxComponent.displayName = "TriStateCheckbox";
|
|
3165
|
-
|
|
4428
|
+
React23.memo(TriStateCheckboxComponent);
|
|
3166
4429
|
var MD3_FAST_EFFECTS2 = [0.3, 0, 1, 1];
|
|
3167
|
-
var RadioGroupContext =
|
|
4430
|
+
var RadioGroupContext = React23.createContext(
|
|
3168
4431
|
null
|
|
3169
4432
|
);
|
|
3170
4433
|
function useMergedRef3(externalRef, internalRef) {
|
|
3171
|
-
return
|
|
4434
|
+
return React23.useCallback(
|
|
3172
4435
|
(node) => {
|
|
3173
4436
|
internalRef.current = node;
|
|
3174
4437
|
if (!externalRef) return;
|
|
@@ -3181,7 +4444,7 @@ function useMergedRef3(externalRef, internalRef) {
|
|
|
3181
4444
|
[externalRef, internalRef]
|
|
3182
4445
|
);
|
|
3183
4446
|
}
|
|
3184
|
-
var RadioVisual =
|
|
4447
|
+
var RadioVisual = React23.memo(function RadioVisual2({
|
|
3185
4448
|
isSelected,
|
|
3186
4449
|
disabled,
|
|
3187
4450
|
error,
|
|
@@ -3234,7 +4497,7 @@ var RadioVisual = React18.memo(function RadioVisual2({
|
|
|
3234
4497
|
}
|
|
3235
4498
|
);
|
|
3236
4499
|
});
|
|
3237
|
-
var RadioButtonComponent =
|
|
4500
|
+
var RadioButtonComponent = React23.forwardRef(
|
|
3238
4501
|
({
|
|
3239
4502
|
selected,
|
|
3240
4503
|
defaultSelected = false,
|
|
@@ -3253,23 +4516,23 @@ var RadioButtonComponent = React18.forwardRef(
|
|
|
3253
4516
|
required: requiredProp
|
|
3254
4517
|
}, ref) => {
|
|
3255
4518
|
var _a, _b;
|
|
3256
|
-
const group =
|
|
4519
|
+
const group = React23.useContext(RadioGroupContext);
|
|
3257
4520
|
const prefersReduced = (_a = useReducedMotion()) != null ? _a : false;
|
|
3258
|
-
const generatedId =
|
|
4521
|
+
const generatedId = React23.useId();
|
|
3259
4522
|
const inputId = idProp != null ? idProp : label ? `radio-${generatedId}` : void 0;
|
|
3260
4523
|
const name = (_b = group == null ? void 0 : group.name) != null ? _b : nameProp;
|
|
3261
4524
|
const disabled = (group == null ? void 0 : group.disabled) || disabledProp;
|
|
3262
4525
|
const error = (group == null ? void 0 : group.error) || errorProp || color === "error";
|
|
3263
4526
|
const required = (group == null ? void 0 : group.required) || requiredProp;
|
|
3264
|
-
const [internalSelected, setInternalSelected] =
|
|
4527
|
+
const [internalSelected, setInternalSelected] = React23.useState(defaultSelected);
|
|
3265
4528
|
const isControlled = selected !== void 0;
|
|
3266
4529
|
const isSelected = group ? group.selectedValue === value : isControlled ? selected != null ? selected : false : internalSelected;
|
|
3267
|
-
const [ripples, setRipples] =
|
|
3268
|
-
const removeRipple =
|
|
4530
|
+
const [ripples, setRipples] = React23.useState([]);
|
|
4531
|
+
const removeRipple = React23.useCallback(
|
|
3269
4532
|
(id) => setRipples((prev) => prev.filter((r) => r.id !== id)),
|
|
3270
4533
|
[]
|
|
3271
4534
|
);
|
|
3272
|
-
const onPointerDown =
|
|
4535
|
+
const onPointerDown = React23.useCallback(
|
|
3273
4536
|
(e) => {
|
|
3274
4537
|
if (disabled) return;
|
|
3275
4538
|
const rect = e.currentTarget.getBoundingClientRect();
|
|
@@ -3283,12 +4546,12 @@ var RadioButtonComponent = React18.forwardRef(
|
|
|
3283
4546
|
},
|
|
3284
4547
|
[disabled]
|
|
3285
4548
|
);
|
|
3286
|
-
const [isHovered, setIsHovered] =
|
|
3287
|
-
const onPointerEnter =
|
|
4549
|
+
const [isHovered, setIsHovered] = React23.useState(false);
|
|
4550
|
+
const onPointerEnter = React23.useCallback(() => {
|
|
3288
4551
|
if (!disabled) setIsHovered(true);
|
|
3289
4552
|
}, [disabled]);
|
|
3290
|
-
const onPointerLeave =
|
|
3291
|
-
const handleChange =
|
|
4553
|
+
const onPointerLeave = React23.useCallback(() => setIsHovered(false), []);
|
|
4554
|
+
const handleChange = React23.useCallback(
|
|
3292
4555
|
(_e) => {
|
|
3293
4556
|
if (disabled || onClick === null) return;
|
|
3294
4557
|
if (group) {
|
|
@@ -3302,7 +4565,7 @@ var RadioButtonComponent = React18.forwardRef(
|
|
|
3302
4565
|
},
|
|
3303
4566
|
[disabled, onClick, group, value, isControlled]
|
|
3304
4567
|
);
|
|
3305
|
-
const inputRef =
|
|
4568
|
+
const inputRef = React23.useRef(null);
|
|
3306
4569
|
const mergedRef = useMergedRef3(ref, inputRef);
|
|
3307
4570
|
const stateLayerBg = error ? "before:bg-m3-error" : "before:bg-m3-primary";
|
|
3308
4571
|
const stateLayerClass = cn(
|
|
@@ -3413,8 +4676,8 @@ var RadioButtonComponent = React18.forwardRef(
|
|
|
3413
4676
|
}
|
|
3414
4677
|
);
|
|
3415
4678
|
RadioButtonComponent.displayName = "RadioButton";
|
|
3416
|
-
var RadioButton =
|
|
3417
|
-
var RadioGroupComponent =
|
|
4679
|
+
var RadioButton = React23.memo(RadioButtonComponent);
|
|
4680
|
+
var RadioGroupComponent = React23.forwardRef(
|
|
3418
4681
|
({
|
|
3419
4682
|
name,
|
|
3420
4683
|
value: valueProp,
|
|
@@ -3429,19 +4692,19 @@ var RadioGroupComponent = React18.forwardRef(
|
|
|
3429
4692
|
children,
|
|
3430
4693
|
className
|
|
3431
4694
|
}, ref) => {
|
|
3432
|
-
const [internalValue, setInternalValue] =
|
|
4695
|
+
const [internalValue, setInternalValue] = React23.useState(defaultValue);
|
|
3433
4696
|
const isControlled = valueProp !== void 0;
|
|
3434
4697
|
const selectedValue = isControlled ? valueProp : internalValue;
|
|
3435
|
-
const handleValueChange =
|
|
4698
|
+
const handleValueChange = React23.useCallback(
|
|
3436
4699
|
(val) => {
|
|
3437
4700
|
if (!isControlled) setInternalValue(val);
|
|
3438
4701
|
onValueChange == null ? void 0 : onValueChange(val);
|
|
3439
4702
|
},
|
|
3440
4703
|
[isControlled, onValueChange]
|
|
3441
4704
|
);
|
|
3442
|
-
const groupRef =
|
|
4705
|
+
const groupRef = React23.useRef(null);
|
|
3443
4706
|
const mergedRef = useMergedRef3(ref, groupRef);
|
|
3444
|
-
const onKeyDown =
|
|
4707
|
+
const onKeyDown = React23.useCallback(
|
|
3445
4708
|
(e) => {
|
|
3446
4709
|
var _a, _b;
|
|
3447
4710
|
if (disabled) return;
|
|
@@ -3465,7 +4728,7 @@ var RadioGroupComponent = React18.forwardRef(
|
|
|
3465
4728
|
},
|
|
3466
4729
|
[disabled, handleValueChange]
|
|
3467
4730
|
);
|
|
3468
|
-
const contextValue =
|
|
4731
|
+
const contextValue = React23.useMemo(
|
|
3469
4732
|
() => ({
|
|
3470
4733
|
name,
|
|
3471
4734
|
selectedValue,
|
|
@@ -3500,7 +4763,7 @@ var RadioGroupComponent = React18.forwardRef(
|
|
|
3500
4763
|
}
|
|
3501
4764
|
);
|
|
3502
4765
|
RadioGroupComponent.displayName = "RadioGroup";
|
|
3503
|
-
|
|
4766
|
+
React23.memo(RadioGroupComponent);
|
|
3504
4767
|
|
|
3505
4768
|
// src/ui/switch/switch.tokens.ts
|
|
3506
4769
|
var SwitchTokens = {
|
|
@@ -3578,7 +4841,7 @@ function isIconVisible(thumbContent, icons, showOnlySelectedIcon, checked) {
|
|
|
3578
4841
|
if (icons) return true;
|
|
3579
4842
|
return showOnlySelectedIcon && checked;
|
|
3580
4843
|
}
|
|
3581
|
-
var SwitchVisual =
|
|
4844
|
+
var SwitchVisual = React23.memo(function SwitchVisual2({
|
|
3582
4845
|
checked,
|
|
3583
4846
|
disabled,
|
|
3584
4847
|
isPressed,
|
|
@@ -3698,7 +4961,7 @@ var SwitchVisual = React18.memo(function SwitchVisual2({
|
|
|
3698
4961
|
}
|
|
3699
4962
|
);
|
|
3700
4963
|
});
|
|
3701
|
-
var SwitchComponent =
|
|
4964
|
+
var SwitchComponent = React23.forwardRef(
|
|
3702
4965
|
({
|
|
3703
4966
|
checked,
|
|
3704
4967
|
onCheckedChange,
|
|
@@ -3716,16 +4979,16 @@ var SwitchComponent = React18.forwardRef(
|
|
|
3716
4979
|
}, ref) => {
|
|
3717
4980
|
var _a;
|
|
3718
4981
|
const prefersReduced = (_a = useReducedMotion()) != null ? _a : false;
|
|
3719
|
-
const [isPressed, setIsPressed] =
|
|
3720
|
-
const [isHovered, setIsHovered] =
|
|
3721
|
-
const [isFocused, setIsFocused] =
|
|
3722
|
-
const [ripples, setRipples] =
|
|
3723
|
-
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();
|
|
3724
4987
|
const switchId = label ? `switch-${generatedId}` : void 0;
|
|
3725
|
-
const handleClick =
|
|
4988
|
+
const handleClick = React23.useCallback(() => {
|
|
3726
4989
|
if (!disabled) onCheckedChange(!checked);
|
|
3727
4990
|
}, [disabled, checked, onCheckedChange]);
|
|
3728
|
-
const handleKeyDown =
|
|
4991
|
+
const handleKeyDown = React23.useCallback(
|
|
3729
4992
|
(e) => {
|
|
3730
4993
|
if (disabled) return;
|
|
3731
4994
|
if (e.key === " " || e.key === "Enter") {
|
|
@@ -3735,7 +4998,7 @@ var SwitchComponent = React18.forwardRef(
|
|
|
3735
4998
|
},
|
|
3736
4999
|
[disabled, checked, onCheckedChange]
|
|
3737
5000
|
);
|
|
3738
|
-
const handlePointerDown =
|
|
5001
|
+
const handlePointerDown = React23.useCallback(
|
|
3739
5002
|
(e) => {
|
|
3740
5003
|
if (disabled) return;
|
|
3741
5004
|
setIsPressed(true);
|
|
@@ -3750,19 +5013,19 @@ var SwitchComponent = React18.forwardRef(
|
|
|
3750
5013
|
},
|
|
3751
5014
|
[disabled]
|
|
3752
5015
|
);
|
|
3753
|
-
const handlePointerUp =
|
|
5016
|
+
const handlePointerUp = React23.useCallback(() => {
|
|
3754
5017
|
setIsPressed(false);
|
|
3755
5018
|
}, []);
|
|
3756
|
-
const handlePointerEnter =
|
|
5019
|
+
const handlePointerEnter = React23.useCallback(() => {
|
|
3757
5020
|
if (!disabled) setIsHovered(true);
|
|
3758
5021
|
}, [disabled]);
|
|
3759
|
-
const handlePointerLeave =
|
|
5022
|
+
const handlePointerLeave = React23.useCallback(() => {
|
|
3760
5023
|
setIsHovered(false);
|
|
3761
5024
|
setIsPressed(false);
|
|
3762
5025
|
}, []);
|
|
3763
|
-
const handleFocus =
|
|
3764
|
-
const handleBlur =
|
|
3765
|
-
const removeRipple =
|
|
5026
|
+
const handleFocus = React23.useCallback(() => setIsFocused(true), []);
|
|
5027
|
+
const handleBlur = React23.useCallback(() => setIsFocused(false), []);
|
|
5028
|
+
const removeRipple = React23.useCallback(
|
|
3766
5029
|
(id) => setRipples((prev) => prev.filter((r) => r.id !== id)),
|
|
3767
5030
|
[]
|
|
3768
5031
|
);
|
|
@@ -3788,7 +5051,7 @@ var SwitchComponent = React18.forwardRef(
|
|
|
3788
5051
|
onFocus: handleFocus,
|
|
3789
5052
|
onBlur: handleBlur,
|
|
3790
5053
|
className: cn(
|
|
3791
|
-
"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",
|
|
3792
5055
|
// Touch target: 48×48 minimum (pad around 32px track)
|
|
3793
5056
|
"min-w-12 min-h-12",
|
|
3794
5057
|
// Focus ring — MD3 FocusIndicatorColor = secondary
|
|
@@ -3798,7 +5061,7 @@ var SwitchComponent = React18.forwardRef(
|
|
|
3798
5061
|
disabled && "pointer-events-none cursor-not-allowed",
|
|
3799
5062
|
!label && className
|
|
3800
5063
|
),
|
|
3801
|
-
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: [
|
|
3802
5065
|
/* @__PURE__ */ jsx(
|
|
3803
5066
|
SwitchVisual,
|
|
3804
5067
|
{
|
|
@@ -3847,7 +5110,7 @@ var SwitchComponent = React18.forwardRef(
|
|
|
3847
5110
|
}
|
|
3848
5111
|
);
|
|
3849
5112
|
SwitchComponent.displayName = "Switch";
|
|
3850
|
-
var Switch =
|
|
5113
|
+
var Switch = React23.memo(SwitchComponent);
|
|
3851
5114
|
|
|
3852
5115
|
// src/ui/lists/list-utils.ts
|
|
3853
5116
|
function getListItemHeight(hasOverline, supportingTextLines) {
|
|
@@ -3987,7 +5250,7 @@ function renderSwitchTrailing({
|
|
|
3987
5250
|
trailingClass
|
|
3988
5251
|
}) {
|
|
3989
5252
|
const isSelectingMode = selectionMode === "single-select" || selectionMode === "multi-select";
|
|
3990
|
-
const switchElement =
|
|
5253
|
+
const switchElement = React23.isValidElement(trailingContent) ? (() => {
|
|
3991
5254
|
const trailingProps = trailingContent.props;
|
|
3992
5255
|
const checkedValue = !isSelectingMode && trailingProps.checked !== void 0 ? trailingProps.checked : isSelected;
|
|
3993
5256
|
const disabledValue = trailingProps.disabled !== void 0 ? disabled || trailingProps.disabled : disabled;
|
|
@@ -3998,7 +5261,7 @@ function renderSwitchTrailing({
|
|
|
3998
5261
|
onItemChange(value, checked);
|
|
3999
5262
|
}
|
|
4000
5263
|
};
|
|
4001
|
-
return
|
|
5264
|
+
return React23.cloneElement(
|
|
4002
5265
|
trailingContent,
|
|
4003
5266
|
{ checked: checkedValue, disabled: disabledValue, onCheckedChange }
|
|
4004
5267
|
);
|
|
@@ -4023,7 +5286,7 @@ function renderSwitchTrailing({
|
|
|
4023
5286
|
)
|
|
4024
5287
|
);
|
|
4025
5288
|
}
|
|
4026
|
-
var ListItemImpl =
|
|
5289
|
+
var ListItemImpl = React23.forwardRef(
|
|
4027
5290
|
(_a, ref) => {
|
|
4028
5291
|
var _b = _a, {
|
|
4029
5292
|
className,
|
|
@@ -4079,9 +5342,9 @@ var ListItemImpl = React18.forwardRef(
|
|
|
4079
5342
|
});
|
|
4080
5343
|
const reorderable = (_e = context == null ? void 0 : context.reorderable) != null ? _e : false;
|
|
4081
5344
|
const isSelected = selected !== void 0 ? selected : (_f = context == null ? void 0 : context.selectedValues.has(value)) != null ? _f : false;
|
|
4082
|
-
const [isHovered, setIsHovered] =
|
|
4083
|
-
const [isFocused, setIsFocused] =
|
|
4084
|
-
const [isPressed, setIsPressed] =
|
|
5345
|
+
const [isHovered, setIsHovered] = React23.useState(false);
|
|
5346
|
+
const [isFocused, setIsFocused] = React23.useState(false);
|
|
5347
|
+
const [isPressed, setIsPressed] = React23.useState(false);
|
|
4085
5348
|
const { ripples, onPointerDown, removeRipple } = useRippleState({
|
|
4086
5349
|
disabled
|
|
4087
5350
|
});
|
|
@@ -4093,8 +5356,8 @@ var ListItemImpl = React18.forwardRef(
|
|
|
4093
5356
|
transition,
|
|
4094
5357
|
isDragging
|
|
4095
5358
|
} = useSortable({ id: value, disabled: !reorderable });
|
|
4096
|
-
const itemRef =
|
|
4097
|
-
const setRefs =
|
|
5359
|
+
const itemRef = React23.useRef(null);
|
|
5360
|
+
const setRefs = React23.useCallback(
|
|
4098
5361
|
(node) => {
|
|
4099
5362
|
itemRef.current = node;
|
|
4100
5363
|
setNodeRef(node);
|
|
@@ -4547,7 +5810,7 @@ var ListItemImpl = React18.forwardRef(
|
|
|
4547
5810
|
}
|
|
4548
5811
|
);
|
|
4549
5812
|
ListItemImpl.displayName = "ListItem";
|
|
4550
|
-
var ListItem =
|
|
5813
|
+
var ListItem = React23.memo(ListItemImpl);
|
|
4551
5814
|
var typographyVariants = cva("m-0 p-0 text-m3-on-surface", {
|
|
4552
5815
|
variants: {
|
|
4553
5816
|
variant: {
|
|
@@ -4573,10 +5836,10 @@ var typographyVariants = cva("m-0 p-0 text-m3-on-surface", {
|
|
|
4573
5836
|
variant: "body-md"
|
|
4574
5837
|
}
|
|
4575
5838
|
});
|
|
4576
|
-
var Text =
|
|
5839
|
+
var Text = React23.forwardRef(
|
|
4577
5840
|
(_a, ref) => {
|
|
4578
5841
|
var _b = _a, { className, variant, as: Component, color, weight, style } = _b, props = __objRest(_b, ["className", "variant", "as", "color", "weight", "style"]);
|
|
4579
|
-
const defaultComponent =
|
|
5842
|
+
const defaultComponent = React23.useMemo(() => {
|
|
4580
5843
|
const v = variant ? String(variant).toLowerCase() : "";
|
|
4581
5844
|
if (v.startsWith("display") || v.startsWith("headline")) return "h1";
|
|
4582
5845
|
if (v.startsWith("title")) return "h2";
|
|
@@ -4598,12 +5861,15 @@ Text.displayName = "Text";
|
|
|
4598
5861
|
function TableOfContents({
|
|
4599
5862
|
items,
|
|
4600
5863
|
className,
|
|
4601
|
-
scrollAreaProps
|
|
5864
|
+
scrollAreaProps,
|
|
5865
|
+
scrollContainerRef
|
|
4602
5866
|
}) {
|
|
4603
5867
|
const [activeId, setActiveId] = useState("");
|
|
4604
5868
|
const itemIds = useMemo(() => items.map((i) => i.id), [items]);
|
|
4605
5869
|
useEffect(() => {
|
|
5870
|
+
var _a;
|
|
4606
5871
|
if (typeof IntersectionObserver === "undefined") return;
|
|
5872
|
+
const root = (_a = scrollContainerRef == null ? void 0 : scrollContainerRef.current) != null ? _a : null;
|
|
4607
5873
|
const observer = new IntersectionObserver(
|
|
4608
5874
|
(entries) => {
|
|
4609
5875
|
for (const entry of entries) {
|
|
@@ -4611,19 +5877,20 @@ function TableOfContents({
|
|
|
4611
5877
|
}
|
|
4612
5878
|
},
|
|
4613
5879
|
// rootMargin: top offset ~100px (fixed header), bottom -80% (early switch)
|
|
4614
|
-
{ rootMargin: "-100px 0% -80% 0%" }
|
|
5880
|
+
{ root, rootMargin: "-100px 0% -80% 0%" }
|
|
4615
5881
|
);
|
|
4616
5882
|
for (const id of itemIds) {
|
|
4617
5883
|
const el = document.getElementById(id);
|
|
4618
5884
|
if (el) observer.observe(el);
|
|
4619
5885
|
}
|
|
4620
5886
|
return () => observer.disconnect();
|
|
4621
|
-
}, [itemIds]);
|
|
5887
|
+
}, [itemIds, scrollContainerRef]);
|
|
4622
5888
|
const handleClick = useCallback(
|
|
4623
5889
|
(e, id) => {
|
|
4624
|
-
var _a;
|
|
4625
5890
|
e.preventDefault();
|
|
4626
|
-
|
|
5891
|
+
const target = document.getElementById(id);
|
|
5892
|
+
if (!target) return;
|
|
5893
|
+
target.scrollIntoView({ behavior: "smooth", block: "start" });
|
|
4627
5894
|
},
|
|
4628
5895
|
[]
|
|
4629
5896
|
);
|
|
@@ -4640,19 +5907,35 @@ function TableOfContents({
|
|
|
4640
5907
|
type: "hover"
|
|
4641
5908
|
}, scrollAreaProps), {
|
|
4642
5909
|
className: cn("flex-1 min-h-0", scrollAreaProps == null ? void 0 : scrollAreaProps.className),
|
|
4643
|
-
children: /* @__PURE__ */ jsx("ul", { className: "space-y-
|
|
4644
|
-
|
|
4645
|
-
|
|
4646
|
-
|
|
4647
|
-
|
|
4648
|
-
"
|
|
4649
|
-
|
|
4650
|
-
|
|
4651
|
-
|
|
4652
|
-
|
|
4653
|
-
|
|
4654
|
-
|
|
4655
|
-
|
|
5910
|
+
children: /* @__PURE__ */ jsx("ul", { className: "space-y-2 pr-4", children: items.map((item) => {
|
|
5911
|
+
var _a;
|
|
5912
|
+
const depth = (_a = item.depth) != null ? _a : 1;
|
|
5913
|
+
const isSubItem = depth > 1;
|
|
5914
|
+
return /* @__PURE__ */ jsx(
|
|
5915
|
+
"li",
|
|
5916
|
+
{
|
|
5917
|
+
className: cn(
|
|
5918
|
+
isSubItem && "pl-3.5 border-l border-m3-outline-variant/40 ml-1"
|
|
5919
|
+
),
|
|
5920
|
+
children: /* @__PURE__ */ jsx(
|
|
5921
|
+
"a",
|
|
5922
|
+
{
|
|
5923
|
+
href: `#${item.id}`,
|
|
5924
|
+
onClick: (e) => handleClick(e, item.id),
|
|
5925
|
+
"aria-current": activeId === item.id ? "true" : void 0,
|
|
5926
|
+
className: cn(
|
|
5927
|
+
"transition-colors hover:text-m3-primary block truncate",
|
|
5928
|
+
isSubItem ? "text-xs py-0.5 leading-relaxed" : "text-sm py-1 font-medium leading-snug",
|
|
5929
|
+
activeId === item.id ? "text-m3-primary font-bold" : "text-m3-on-surface-variant"
|
|
5930
|
+
),
|
|
5931
|
+
title: item.label,
|
|
5932
|
+
children: item.label
|
|
5933
|
+
}
|
|
5934
|
+
)
|
|
5935
|
+
},
|
|
5936
|
+
item.id
|
|
5937
|
+
);
|
|
5938
|
+
}) })
|
|
4656
5939
|
})
|
|
4657
5940
|
)
|
|
4658
5941
|
]
|
|
@@ -5395,6 +6678,6 @@ function TypographyProvider({
|
|
|
5395
6678
|
return /* @__PURE__ */ jsx(TypographyContext.Provider, { value, children });
|
|
5396
6679
|
}
|
|
5397
6680
|
|
|
5398
|
-
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 };
|
|
6681
|
+
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 };
|
|
5399
6682
|
//# sourceMappingURL=layout.mjs.map
|
|
5400
6683
|
//# sourceMappingURL=layout.mjs.map
|