@tinybigui/react 0.10.0 → 0.11.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +18 -18
- package/dist/index.cjs +196 -176
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +168 -70
- package/dist/index.d.ts +168 -70
- package/dist/index.js +196 -176
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -12,7 +12,7 @@ A modern, accessible React component library implementing Google's Material Desi
|
|
|
12
12
|
|
|
13
13
|
## ✅ Status
|
|
14
14
|
|
|
15
|
-
> **Latest Release: v0.
|
|
15
|
+
> **Latest Release: v0.11.1** (2026-06-09)
|
|
16
16
|
>
|
|
17
17
|
> **29 MD3 components** published to npm with full TypeScript support and WCAG 2.1 AA accessibility.
|
|
18
18
|
>
|
|
@@ -159,26 +159,26 @@ See [THEMING.md](./THEMING.md) for the full customization guide.
|
|
|
159
159
|
|
|
160
160
|
### Phase 3: Feedback ✅
|
|
161
161
|
|
|
162
|
-
| Component | Status | Description
|
|
163
|
-
| ------------- | ------ |
|
|
164
|
-
| `Dialog` | ✅ | Basic and fullscreen modal dialogs
|
|
165
|
-
| `Snackbar` | ✅ | Provider, stacking, imperative API
|
|
166
|
-
| `Menu` | ✅ | Dropdown, context menu, submenus
|
|
167
|
-
| `Progress` | ✅ | Linear and circular indicators
|
|
168
|
-
| `BottomSheet` | ✅ |
|
|
169
|
-
| `Tooltip` | ✅ | Plain and rich tooltip with positioning
|
|
162
|
+
| Component | Status | Description |
|
|
163
|
+
| ------------- | ------ | ---------------------------------------------------------------- |
|
|
164
|
+
| `Dialog` | ✅ | Basic and fullscreen modal dialogs |
|
|
165
|
+
| `Snackbar` | ✅ | Provider, stacking, imperative API |
|
|
166
|
+
| `Menu` | ✅ | Dropdown, context menu, submenus |
|
|
167
|
+
| `Progress` | ✅ | Linear and circular indicators |
|
|
168
|
+
| `BottomSheet` | ✅ | MD3 expressive handle, variants-vs-states architecture (v0.11.0) |
|
|
169
|
+
| `Tooltip` | ✅ | Plain and rich tooltip with positioning |
|
|
170
170
|
|
|
171
171
|
### Phase 4: Data Display ✅
|
|
172
172
|
|
|
173
|
-
| Component | Status | Description
|
|
174
|
-
| ------------ | ------ |
|
|
175
|
-
| `Card` | ✅ |
|
|
176
|
-
| `List` | ✅ | Static and interactive list items
|
|
177
|
-
| `Chip` | ✅ | MD3 expressive slot architecture, elevated surface (v0.9.0)
|
|
178
|
-
| `Badge` | ✅ | MD3 expressive dot/count badges, icon-corner anchoring (v0.8.0)
|
|
179
|
-
| `Divider` | ✅ | Horizontal/vertical, inset variants
|
|
180
|
-
| `DatePicker` | ✅ | Docked, modal, and input variants
|
|
181
|
-
| `TimePicker` | ✅ | 12h/24h clock dial, range selection
|
|
173
|
+
| Component | Status | Description |
|
|
174
|
+
| ------------ | ------ | -------------------------------------------------------------------- |
|
|
175
|
+
| `Card` | ✅ | MD3 motion tier, media aspect-ratio fix, CVA export parity (v0.11.1) |
|
|
176
|
+
| `List` | ✅ | Static and interactive list items |
|
|
177
|
+
| `Chip` | ✅ | MD3 expressive slot architecture, elevated surface (v0.9.0) |
|
|
178
|
+
| `Badge` | ✅ | MD3 expressive dot/count badges, icon-corner anchoring (v0.8.0) |
|
|
179
|
+
| `Divider` | ✅ | Horizontal/vertical, inset variants |
|
|
180
|
+
| `DatePicker` | ✅ | Docked, modal, and input variants |
|
|
181
|
+
| `TimePicker` | ✅ | 12h/24h clock dial, range selection |
|
|
182
182
|
|
|
183
183
|
### Planned
|
|
184
184
|
|
package/dist/index.cjs
CHANGED
|
@@ -5403,28 +5403,42 @@ var ProgressHeadless = React.forwardRef(
|
|
|
5403
5403
|
}
|
|
5404
5404
|
);
|
|
5405
5405
|
ProgressHeadless.displayName = "ProgressHeadless";
|
|
5406
|
-
var CardHeadless = React.forwardRef(function CardHeadless2({ className, children, ...
|
|
5406
|
+
var CardHeadless = React.forwardRef(function CardHeadless2({ className, children, onMouseDown, onMouseUp, onMouseLeave, ...rest }, forwardedRef) {
|
|
5407
5407
|
const internalRef = React.useRef(null);
|
|
5408
5408
|
const ref = forwardedRef ?? internalRef;
|
|
5409
|
-
const isInteractive = !!(
|
|
5410
|
-
const { buttonProps } = reactAria.useButton({ elementType: "div", ...
|
|
5411
|
-
const {
|
|
5409
|
+
const isInteractive = !!(rest.onPress ?? rest.href);
|
|
5410
|
+
const { buttonProps } = reactAria.useButton({ elementType: "div", ...rest }, ref);
|
|
5411
|
+
const {
|
|
5412
|
+
isDisabled: _isDisabled,
|
|
5413
|
+
onPress: _onPress,
|
|
5414
|
+
onPressStart: _onPressStart,
|
|
5415
|
+
onPressEnd: _onPressEnd,
|
|
5416
|
+
onPressChange: _onPressChange,
|
|
5417
|
+
onPressUp: _onPressUp,
|
|
5418
|
+
href: _href,
|
|
5419
|
+
target: _target,
|
|
5420
|
+
rel: _rel,
|
|
5421
|
+
...htmlAttrs
|
|
5422
|
+
} = rest;
|
|
5423
|
+
const mouseHandlers = { onMouseDown, onMouseUp, onMouseLeave };
|
|
5412
5424
|
if (isInteractive) {
|
|
5413
|
-
const interactiveProps = utils.mergeProps(buttonProps,
|
|
5414
|
-
className,
|
|
5415
|
-
"data-focus-visible": isFocusVisible ? "true" : void 0
|
|
5416
|
-
});
|
|
5425
|
+
const interactiveProps = utils.mergeProps(buttonProps, mouseHandlers, htmlAttrs, { className });
|
|
5417
5426
|
return /* @__PURE__ */ jsxRuntime.jsx("div", { ...interactiveProps, ref, children });
|
|
5418
5427
|
}
|
|
5419
|
-
return /* @__PURE__ */ jsxRuntime.jsx("div", { role: "article", className, ref, children });
|
|
5428
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { role: "article", className, ref, ...mouseHandlers, ...htmlAttrs, children });
|
|
5420
5429
|
});
|
|
5421
5430
|
CardHeadless.displayName = "CardHeadless";
|
|
5422
5431
|
var cardVariants = classVarianceAuthority.cva(
|
|
5423
5432
|
[
|
|
5424
5433
|
// Shape: MD3 medium corner = 12dp
|
|
5425
|
-
"relative overflow-hidden rounded-md",
|
|
5426
|
-
//
|
|
5427
|
-
|
|
5434
|
+
"relative overflow-hidden rounded-md text-on-surface",
|
|
5435
|
+
// Transition: effects properties — standard default tier (cards are standard-size, not <48dp)
|
|
5436
|
+
// Covers shadow (elevation), opacity (disabled fade), border-color (outlined state)
|
|
5437
|
+
"transition-[box-shadow,opacity,border-color] duration-spring-standard-default-effects ease-spring-standard-default-effects",
|
|
5438
|
+
// Interactive affordance (content flag set by the component)
|
|
5439
|
+
"data-[interactive]:cursor-pointer",
|
|
5440
|
+
// Disabled — self-targeting selectors (38% container, no interaction)
|
|
5441
|
+
"data-[disabled]:cursor-not-allowed data-[disabled]:pointer-events-none data-[disabled]:opacity-38"
|
|
5428
5442
|
],
|
|
5429
5443
|
{
|
|
5430
5444
|
variants: {
|
|
@@ -5432,92 +5446,74 @@ var cardVariants = classVarianceAuthority.cva(
|
|
|
5432
5446
|
* Card visual variant per MD3 specification.
|
|
5433
5447
|
*/
|
|
5434
5448
|
variant: {
|
|
5435
|
-
|
|
5436
|
-
|
|
5437
|
-
|
|
5438
|
-
|
|
5439
|
-
|
|
5440
|
-
|
|
5441
|
-
|
|
5442
|
-
|
|
5443
|
-
|
|
5444
|
-
|
|
5445
|
-
"
|
|
5446
|
-
"
|
|
5447
|
-
"
|
|
5448
|
-
"focus-visible:outline-offset-2"
|
|
5449
|
+
/**
|
|
5450
|
+
* Elevated — separation via shadow.
|
|
5451
|
+
* MD3: container=surface-container-low.
|
|
5452
|
+
* Elevation: 1 base → 2 hover → 1 focus → 1 pressed → 4 dragged.
|
|
5453
|
+
*/
|
|
5454
|
+
elevated: [
|
|
5455
|
+
"bg-surface-container-low",
|
|
5456
|
+
"shadow-elevation-1",
|
|
5457
|
+
"data-[hovered]:shadow-elevation-2",
|
|
5458
|
+
"data-[focus-visible]:shadow-elevation-1",
|
|
5459
|
+
"data-[pressed]:data-[pressed]:shadow-elevation-1",
|
|
5460
|
+
"data-[dragged]:data-[dragged]:data-[dragged]:shadow-elevation-4",
|
|
5461
|
+
"data-[disabled]:shadow-none"
|
|
5449
5462
|
],
|
|
5450
|
-
|
|
5451
|
-
|
|
5452
|
-
|
|
5453
|
-
|
|
5454
|
-
|
|
5455
|
-
|
|
5456
|
-
|
|
5457
|
-
|
|
5458
|
-
|
|
5459
|
-
"shadow-
|
|
5460
|
-
|
|
5461
|
-
"
|
|
5462
|
-
"
|
|
5463
|
+
/**
|
|
5464
|
+
* Filled — subtle container fill, no resting shadow.
|
|
5465
|
+
* MD3: container=surface-container-highest.
|
|
5466
|
+
* Elevation: 0 base → 1 hover → 0 focus → 0 pressed → 3 dragged.
|
|
5467
|
+
*/
|
|
5468
|
+
filled: [
|
|
5469
|
+
"bg-surface-container-highest",
|
|
5470
|
+
"shadow-none",
|
|
5471
|
+
"data-[hovered]:shadow-elevation-1",
|
|
5472
|
+
"data-[focus-visible]:shadow-none",
|
|
5473
|
+
"data-[pressed]:data-[pressed]:shadow-none",
|
|
5474
|
+
"data-[dragged]:data-[dragged]:data-[dragged]:shadow-elevation-3",
|
|
5475
|
+
"data-[disabled]:shadow-none"
|
|
5463
5476
|
],
|
|
5464
|
-
|
|
5465
|
-
|
|
5466
|
-
|
|
5467
|
-
|
|
5468
|
-
|
|
5469
|
-
|
|
5470
|
-
|
|
5471
|
-
|
|
5472
|
-
|
|
5477
|
+
/**
|
|
5478
|
+
* Outlined — visual boundary via border, no resting shadow.
|
|
5479
|
+
* MD3: container=surface, outline=outline-variant.
|
|
5480
|
+
* Elevation: 0 base → 1 hover → 0 focus → 0 pressed → 3 dragged.
|
|
5481
|
+
*/
|
|
5482
|
+
outlined: [
|
|
5483
|
+
"bg-surface border border-outline-variant",
|
|
5484
|
+
"shadow-none",
|
|
5485
|
+
"data-[hovered]:shadow-elevation-1",
|
|
5486
|
+
"data-[focus-visible]:shadow-none",
|
|
5487
|
+
"data-[pressed]:data-[pressed]:shadow-none",
|
|
5488
|
+
"data-[dragged]:data-[dragged]:data-[dragged]:shadow-elevation-3",
|
|
5489
|
+
"data-[disabled]:shadow-none"
|
|
5490
|
+
]
|
|
5473
5491
|
}
|
|
5474
5492
|
},
|
|
5475
|
-
compoundVariants: [
|
|
5476
|
-
// Filled + enabled
|
|
5477
|
-
{
|
|
5478
|
-
variant: "filled",
|
|
5479
|
-
isDisabled: false,
|
|
5480
|
-
class: "bg-surface-container-highest"
|
|
5481
|
-
},
|
|
5482
|
-
// Filled + disabled
|
|
5483
|
-
{
|
|
5484
|
-
variant: "filled",
|
|
5485
|
-
isDisabled: true,
|
|
5486
|
-
class: "bg-surface-container-variant"
|
|
5487
|
-
},
|
|
5488
|
-
// Elevated + enabled
|
|
5489
|
-
{
|
|
5490
|
-
variant: "elevated",
|
|
5491
|
-
isDisabled: true,
|
|
5492
|
-
class: "bg-surface"
|
|
5493
|
-
},
|
|
5494
|
-
// Elevated + disabled
|
|
5495
|
-
{
|
|
5496
|
-
variant: "elevated",
|
|
5497
|
-
isDisabled: false,
|
|
5498
|
-
class: "bg-surface-container-low"
|
|
5499
|
-
},
|
|
5500
|
-
// Outlined + enabled
|
|
5501
|
-
{
|
|
5502
|
-
variant: "outlined",
|
|
5503
|
-
isDisabled: true,
|
|
5504
|
-
class: "bg-surface"
|
|
5505
|
-
},
|
|
5506
|
-
// Outlined + disabled
|
|
5507
|
-
{
|
|
5508
|
-
variant: "outlined",
|
|
5509
|
-
isDisabled: false,
|
|
5510
|
-
class: "bg-surface"
|
|
5511
|
-
}
|
|
5512
|
-
],
|
|
5513
5493
|
defaultVariants: {
|
|
5514
|
-
variant: "elevated"
|
|
5515
|
-
isInteractive: false,
|
|
5516
|
-
isDragged: false,
|
|
5517
|
-
isDisabled: false
|
|
5494
|
+
variant: "elevated"
|
|
5518
5495
|
}
|
|
5519
5496
|
}
|
|
5520
5497
|
);
|
|
5498
|
+
var cardStateLayerVariants = classVarianceAuthority.cva([
|
|
5499
|
+
"pointer-events-none absolute inset-0 rounded-[inherit] opacity-0",
|
|
5500
|
+
"bg-on-surface",
|
|
5501
|
+
// Effects transition for opacity — standard default tier (200ms, no overshoot)
|
|
5502
|
+
"transition-opacity duration-spring-standard-default-effects ease-spring-standard-default-effects",
|
|
5503
|
+
"group-data-[hovered]/card:opacity-8",
|
|
5504
|
+
"group-data-[focus-visible]/card:opacity-10",
|
|
5505
|
+
"group-data-[pressed]/card:group-data-[pressed]/card:opacity-10",
|
|
5506
|
+
"group-data-[dragged]/card:group-data-[dragged]/card:group-data-[dragged]/card:opacity-16",
|
|
5507
|
+
"group-data-[disabled]/card:hidden"
|
|
5508
|
+
]);
|
|
5509
|
+
var cardFocusRingVariants = classVarianceAuthority.cva([
|
|
5510
|
+
"pointer-events-none absolute inset-0 z-20 rounded-[inherit]",
|
|
5511
|
+
"outline outline-2 -outline-offset-2 outline-secondary",
|
|
5512
|
+
// Effects transition — standard default tier, opacity must not overshoot
|
|
5513
|
+
"transition-opacity duration-spring-standard-default-effects ease-spring-standard-default-effects",
|
|
5514
|
+
"opacity-0",
|
|
5515
|
+
"group-data-[focus-visible]/card:opacity-100"
|
|
5516
|
+
]);
|
|
5521
5517
|
var Card = React.forwardRef(function Card2({
|
|
5522
5518
|
variant = "elevated",
|
|
5523
5519
|
onPress,
|
|
@@ -5528,9 +5524,15 @@ var Card = React.forwardRef(function Card2({
|
|
|
5528
5524
|
children,
|
|
5529
5525
|
"aria-label": ariaLabel
|
|
5530
5526
|
}, ref) {
|
|
5527
|
+
const internalRef = React.useRef(null);
|
|
5528
|
+
const resolvedRef = ref ?? internalRef;
|
|
5531
5529
|
const isInteractive = !!(onPress ?? href);
|
|
5532
5530
|
const [isDragged, setIsDragged] = React.useState(false);
|
|
5533
5531
|
const [isPressed, setIsPressed] = React.useState(false);
|
|
5532
|
+
const { isHovered, hoverProps } = reactAria.useHover({ isDisabled: !isInteractive || isDisabled });
|
|
5533
|
+
const { isFocusVisible, focusProps } = reactAria.useFocusRing();
|
|
5534
|
+
const handlePressStart = React.useCallback(() => setIsPressed(true), []);
|
|
5535
|
+
const handlePressEnd = React.useCallback(() => setIsPressed(false), []);
|
|
5534
5536
|
const { onMouseDown: handleRipple, ripples } = useRipple({
|
|
5535
5537
|
disabled: !isInteractive || isDisabled
|
|
5536
5538
|
});
|
|
@@ -5544,42 +5546,41 @@ var Card = React.forwardRef(function Card2({
|
|
|
5544
5546
|
const handleMouseLeave = () => {
|
|
5545
5547
|
if (isDraggable) setIsDragged(false);
|
|
5546
5548
|
};
|
|
5547
|
-
const
|
|
5548
|
-
const
|
|
5549
|
+
const interactionAttrs = isInteractive ? getInteractionDataAttributes({ isHovered, isFocusVisible, isPressed, isDisabled }) : {};
|
|
5550
|
+
const interactiveHandlers = isInteractive ? reactAria.mergeProps(hoverProps, focusProps, {
|
|
5551
|
+
onPressStart: handlePressStart,
|
|
5552
|
+
onPressEnd: handlePressEnd
|
|
5553
|
+
}) : {};
|
|
5549
5554
|
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
5550
5555
|
CardHeadless,
|
|
5551
5556
|
{
|
|
5552
|
-
ref,
|
|
5557
|
+
ref: resolvedRef,
|
|
5553
5558
|
...onPress !== void 0 && { onPress },
|
|
5554
5559
|
...href !== void 0 && { href },
|
|
5555
5560
|
isDisabled,
|
|
5556
5561
|
...ariaLabel !== void 0 && { "aria-label": ariaLabel },
|
|
5557
|
-
|
|
5558
|
-
|
|
5559
|
-
|
|
5560
|
-
|
|
5561
|
-
|
|
5562
|
-
|
|
5563
|
-
|
|
5564
|
-
|
|
5565
|
-
|
|
5566
|
-
),
|
|
5562
|
+
...interactiveHandlers,
|
|
5563
|
+
...isInteractive && { onMouseDown: handleMouseDown },
|
|
5564
|
+
...isInteractive && isDraggable && {
|
|
5565
|
+
onMouseUp: handleMouseUp,
|
|
5566
|
+
onMouseLeave: handleMouseLeave
|
|
5567
|
+
},
|
|
5568
|
+
...interactionAttrs,
|
|
5569
|
+
"data-interactive": isInteractive ? "" : void 0,
|
|
5570
|
+
"data-dragged": isInteractive && isDragged ? "" : void 0,
|
|
5571
|
+
className: cn(cardVariants({ variant }), "group/card", className),
|
|
5567
5572
|
children: [
|
|
5568
5573
|
isInteractive && /* @__PURE__ */ jsxRuntime.jsx(
|
|
5569
|
-
"
|
|
5574
|
+
"span",
|
|
5570
5575
|
{
|
|
5571
5576
|
"data-testid": "card-state-layer",
|
|
5572
|
-
"data-pressed": isPressed ? "" : void 0,
|
|
5573
5577
|
"aria-hidden": "true",
|
|
5574
|
-
className: cn(
|
|
5575
|
-
"bg-on-surface pointer-events-none absolute inset-0 rounded-md",
|
|
5576
|
-
"opacity-0 group-hover:opacity-8 data-[pressed]:opacity-12",
|
|
5577
|
-
"duration-spring-standard-fast-effects ease-spring-standard-fast-effects transition-opacity"
|
|
5578
|
-
)
|
|
5578
|
+
className: cn(cardStateLayerVariants())
|
|
5579
5579
|
}
|
|
5580
5580
|
),
|
|
5581
5581
|
isInteractive && ripples,
|
|
5582
|
-
|
|
5582
|
+
isInteractive && /* @__PURE__ */ jsxRuntime.jsx("span", { "aria-hidden": "true", className: cn(cardFocusRingVariants()) }),
|
|
5583
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "relative z-10", children })
|
|
5583
5584
|
]
|
|
5584
5585
|
}
|
|
5585
5586
|
);
|
|
@@ -5589,7 +5590,7 @@ var cardMediaVariants = classVarianceAuthority.cva("w-full object-cover", {
|
|
|
5589
5590
|
variants: {
|
|
5590
5591
|
aspectRatio: {
|
|
5591
5592
|
"16/9": "aspect-video",
|
|
5592
|
-
"4/3": "aspect-
|
|
5593
|
+
"4/3": "aspect-[4/3]",
|
|
5593
5594
|
"1/1": "aspect-square",
|
|
5594
5595
|
auto: ""
|
|
5595
5596
|
}
|
|
@@ -5613,7 +5614,7 @@ var CardMedia = React.forwardRef(function CardMedia2({ src, alt, aspectRatio = "
|
|
|
5613
5614
|
CardMedia.displayName = "CardMedia";
|
|
5614
5615
|
var CardHeader = React.forwardRef(function CardHeader2({ headline, subheader, className }, ref) {
|
|
5615
5616
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { ref, className: cn("p-4", className), children: [
|
|
5616
|
-
/* @__PURE__ */ jsxRuntime.jsx("h3", { className: "text-on-surface text-title-
|
|
5617
|
+
/* @__PURE__ */ jsxRuntime.jsx("h3", { className: "text-on-surface text-title-medium", children: headline }),
|
|
5617
5618
|
subheader !== void 0 && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-on-surface-variant text-body-medium mt-1", children: subheader })
|
|
5618
5619
|
] });
|
|
5619
5620
|
});
|
|
@@ -11160,7 +11161,7 @@ var BottomSheetModalPanel = ({
|
|
|
11160
11161
|
"aria-modal": "true",
|
|
11161
11162
|
className: cn(className, getAnimationClassName?.(animationState)),
|
|
11162
11163
|
"data-animation-state": animationState,
|
|
11163
|
-
"data-dragging": isDragging
|
|
11164
|
+
"data-dragging": isDragging ? "" : void 0,
|
|
11164
11165
|
style: panelStyle,
|
|
11165
11166
|
onTransitionEnd,
|
|
11166
11167
|
children
|
|
@@ -11297,7 +11298,7 @@ var BottomSheetHeadless = React.forwardRef(
|
|
|
11297
11298
|
ref,
|
|
11298
11299
|
className: cn(className, getAnimationClassName?.(animationState)),
|
|
11299
11300
|
"data-animation-state": animationState,
|
|
11300
|
-
"data-dragging": isDragging
|
|
11301
|
+
"data-dragging": isDragging ? "" : void 0,
|
|
11301
11302
|
style: panelStyle,
|
|
11302
11303
|
onTransitionEnd: handleTransitionEnd,
|
|
11303
11304
|
children
|
|
@@ -11312,7 +11313,6 @@ var bottomSheetAnimationVariants = classVarianceAuthority.cva("", {
|
|
|
11312
11313
|
variants: {
|
|
11313
11314
|
animationState: {
|
|
11314
11315
|
// entering: initial mount frame — sheet starts below viewport (translateY(100%))
|
|
11315
|
-
// The CSS is handled inside animate-md-slide-in-bottom keyframes
|
|
11316
11316
|
entering: ["opacity-0"],
|
|
11317
11317
|
// visible: entry animation active — animate-md-slide-in-bottom runs once
|
|
11318
11318
|
visible: ["animate-md-slide-in-bottom"],
|
|
@@ -11329,52 +11329,38 @@ var bottomSheetAnimationVariants = classVarianceAuthority.cva("", {
|
|
|
11329
11329
|
var bottomSheetVariants = classVarianceAuthority.cva(
|
|
11330
11330
|
[
|
|
11331
11331
|
// Position: fixed to bottom edge, full width
|
|
11332
|
-
"fixed",
|
|
11333
|
-
"bottom-0",
|
|
11334
|
-
"left-0",
|
|
11335
|
-
"right-0",
|
|
11332
|
+
"fixed bottom-0 left-0 right-0",
|
|
11336
11333
|
// Surface token
|
|
11337
11334
|
"bg-surface-container-low",
|
|
11338
11335
|
// Elevation level 1 per MD3 spec
|
|
11339
11336
|
"shadow-elevation-1",
|
|
11340
|
-
// Shape: extra-large top corners (28dp), bottom
|
|
11337
|
+
// Shape: extra-large top corners (28dp), square bottom (screen-attached)
|
|
11338
|
+
// NOTE: measurement-derived value from MD3 spec; permitted exception per component-variants rule
|
|
11341
11339
|
"rounded-t-xl",
|
|
11342
11340
|
// Layout
|
|
11343
|
-
"flex",
|
|
11344
|
-
|
|
11345
|
-
// Max width constraint (full width up to 640dp)
|
|
11341
|
+
"flex flex-col",
|
|
11342
|
+
// Width constraint (full width up to 640dp)
|
|
11346
11343
|
"mx-auto",
|
|
11347
11344
|
// NOTE: measurement-derived value from MD3 spec; permitted exception
|
|
11348
11345
|
"w-[640px] max-w-full",
|
|
11349
|
-
// Clip content during height transitions
|
|
11346
|
+
// Clip content during height transitions
|
|
11350
11347
|
"overflow-hidden",
|
|
11351
|
-
//
|
|
11352
|
-
// Standard personality, default speed tier, spatial: no overshoot.
|
|
11353
|
-
// During drag, data-[dragging=true]:transition-none suppresses this so the
|
|
11354
|
-
// sheet height follows the pointer 1:1 without transition lag.
|
|
11355
|
-
// After drag release, the spring transition animates height to the new snap position.
|
|
11348
|
+
// Snap spring: spatial property (height), standard personality, default tier
|
|
11356
11349
|
"transition-[height]",
|
|
11357
11350
|
"duration-spring-standard-default-spatial",
|
|
11358
11351
|
"ease-spring-standard-default-spatial",
|
|
11359
|
-
|
|
11352
|
+
// Suppress spring while dragging so the sheet follows the pointer 1:1
|
|
11353
|
+
"data-[dragging]:transition-none",
|
|
11360
11354
|
"will-change-[height]",
|
|
11361
|
-
// Responsive layout:
|
|
11362
|
-
// The sheet remains bottom-anchored at all sizes. Side centering is handled by
|
|
11363
|
-
// mx-auto + max-w-[640px] — at 752dp viewport this naturally produces 56dp side
|
|
11364
|
-
// margins on each side (exactly matching MD3 measurements).
|
|
11365
|
-
// Top margin is expressed as max-height so the sheet cannot overlap the top edge:
|
|
11366
|
-
// - Default: 72dp top margin (max-h-[calc(100vh-72px)])
|
|
11367
|
-
// - Wide viewport (> 640dp): 56dp top margin (sm:max-h-[calc(100vh-56px)])
|
|
11355
|
+
// Responsive layout: top margin expressed as max-height
|
|
11368
11356
|
// NOTE: measurement-derived values from MD3 spec; permitted exception
|
|
11369
11357
|
"max-h-[calc(100vh-72px)]",
|
|
11370
|
-
"sm:max-h-[calc(100vh-56px)]"
|
|
11371
|
-
// Top corners rounded at wide layout (sheet floats away from screen edge)
|
|
11372
|
-
"rounded-t-xl"
|
|
11358
|
+
"sm:max-h-[calc(100vh-56px)]"
|
|
11373
11359
|
],
|
|
11374
11360
|
{
|
|
11375
11361
|
variants: {
|
|
11376
11362
|
variant: {
|
|
11377
|
-
// Modal: above scrim (z-50)
|
|
11363
|
+
// Modal: rendered above the scrim (z-50)
|
|
11378
11364
|
modal: "z-50",
|
|
11379
11365
|
// Standard: sits above normal content but below overlays
|
|
11380
11366
|
standard: "z-10"
|
|
@@ -11386,62 +11372,96 @@ var bottomSheetVariants = classVarianceAuthority.cva(
|
|
|
11386
11372
|
}
|
|
11387
11373
|
);
|
|
11388
11374
|
var bottomSheetScrimVariants = classVarianceAuthority.cva([
|
|
11389
|
-
"fixed",
|
|
11390
|
-
"
|
|
11391
|
-
|
|
11392
|
-
"
|
|
11393
|
-
"opacity-32",
|
|
11394
|
-
"transition-opacity",
|
|
11395
|
-
"duration-short4",
|
|
11396
|
-
"ease-standard"
|
|
11375
|
+
"fixed inset-0 z-40",
|
|
11376
|
+
"bg-scrim opacity-32",
|
|
11377
|
+
// Screen-level effects transition (scrim enters/exits the screen, not an on-screen state change)
|
|
11378
|
+
"transition-opacity duration-short4 ease-standard"
|
|
11397
11379
|
]);
|
|
11398
11380
|
var bottomSheetHandleWrapperVariants = classVarianceAuthority.cva([
|
|
11399
|
-
// Center the
|
|
11400
|
-
"flex",
|
|
11401
|
-
|
|
11402
|
-
"justify-center",
|
|
11403
|
-
// Top/bottom padding creates the 48dp touch target area
|
|
11404
|
-
// 22dp top + 4dp handle + 22dp bottom ≈ 48dp interaction zone (per MD3 measurements)
|
|
11381
|
+
// Center the pill horizontally; provide positioning context for overlays
|
|
11382
|
+
"relative flex items-center justify-center w-full",
|
|
11383
|
+
// 48dp touch target (22dp top + 4dp pill + 22dp bottom)
|
|
11405
11384
|
// NOTE: measurement-derived value from MD3 spec; permitted exception
|
|
11406
11385
|
"py-[22px]",
|
|
11407
|
-
//
|
|
11408
|
-
"w-full",
|
|
11409
|
-
// Focus ring styling for keyboard/switch navigation
|
|
11410
|
-
// MD3 spec: focus indicator color = secondary, thickness = 3dp, offset = 2dp
|
|
11386
|
+
// Suppress browser default focus outline — the focus-ring overlay slot handles it
|
|
11411
11387
|
"focus-visible:outline-none",
|
|
11412
|
-
|
|
11413
|
-
"focus-visible:ring-secondary",
|
|
11414
|
-
"focus-visible:ring-offset-2",
|
|
11415
|
-
"focus-visible:rounded-sm",
|
|
11416
|
-
// Cursor affordance
|
|
11388
|
+
// Cursor affordance for drag interaction
|
|
11417
11389
|
"cursor-ns-resize"
|
|
11418
11390
|
]);
|
|
11391
|
+
var bottomSheetHandleStateLayerVariants = classVarianceAuthority.cva([
|
|
11392
|
+
// Overlay positioned centrally — sits behind the pill
|
|
11393
|
+
"absolute pointer-events-none",
|
|
11394
|
+
// Pill-shaped to complement the handle's form
|
|
11395
|
+
"rounded-full",
|
|
11396
|
+
// Sized wider than the pill to provide a visible state layer halo
|
|
11397
|
+
// 48dp wide × 16dp tall — centred by the flex wrapper
|
|
11398
|
+
"w-12 h-4",
|
|
11399
|
+
// State-layer color (same role as the pill)
|
|
11400
|
+
"bg-on-surface-variant",
|
|
11401
|
+
// Effects transition — opacity must NOT overshoot
|
|
11402
|
+
"transition-opacity duration-spring-standard-fast-effects ease-spring-standard-fast-effects",
|
|
11403
|
+
// Opacity at rest
|
|
11404
|
+
"opacity-0",
|
|
11405
|
+
// Hover: 8%
|
|
11406
|
+
"group-data-[hovered]/handle:opacity-8",
|
|
11407
|
+
// Focus-visible: 10%
|
|
11408
|
+
"group-data-[focus-visible]/handle:opacity-10",
|
|
11409
|
+
// Pressed: 10% (doubled selector wins over hover at same cascade position)
|
|
11410
|
+
"group-data-[pressed]/handle:group-data-[pressed]/handle:opacity-10",
|
|
11411
|
+
// Dragging: 16% (MD3 dragged state — highest on-screen opacity)
|
|
11412
|
+
// Doubled selector wins over hover + pressed
|
|
11413
|
+
"group-data-[dragging]/handle:group-data-[dragging]/handle:opacity-16"
|
|
11414
|
+
]);
|
|
11415
|
+
var bottomSheetHandleFocusRingVariants = classVarianceAuthority.cva([
|
|
11416
|
+
"absolute pointer-events-none",
|
|
11417
|
+
"rounded-full",
|
|
11418
|
+
// Sized to sit around the state layer halo
|
|
11419
|
+
"w-14 h-5",
|
|
11420
|
+
// MD3 focus indicator: secondary color, 2dp weight
|
|
11421
|
+
"outline outline-2 outline-offset-0 outline-secondary",
|
|
11422
|
+
// Effects transition — opacity change must NOT overshoot
|
|
11423
|
+
"transition-opacity duration-spring-standard-fast-effects ease-spring-standard-fast-effects",
|
|
11424
|
+
// Hidden at rest; shown on keyboard/programmatic focus
|
|
11425
|
+
"opacity-0",
|
|
11426
|
+
"group-data-[focus-visible]/handle:opacity-100"
|
|
11427
|
+
]);
|
|
11419
11428
|
var bottomSheetHandlePillVariants = classVarianceAuthority.cva([
|
|
11429
|
+
"relative z-10 pointer-events-none",
|
|
11420
11430
|
"bg-on-surface-variant",
|
|
11421
|
-
"opacity-40",
|
|
11422
11431
|
"rounded-full",
|
|
11423
11432
|
// Dimensions: 32dp × 4dp per MD3 spec (measurement-derived; permitted exception)
|
|
11424
11433
|
"w-8",
|
|
11425
|
-
// 32dp = 2rem
|
|
11426
|
-
"h-1"
|
|
11427
|
-
// 4dp
|
|
11428
|
-
// Pill itself is decorative; the wrapper handles interaction
|
|
11429
|
-
"pointer-events-none"
|
|
11434
|
+
// 32dp = 2rem
|
|
11435
|
+
"h-1"
|
|
11436
|
+
// 4dp = 0.25rem
|
|
11430
11437
|
]);
|
|
11431
11438
|
function BottomSheetHandle({
|
|
11432
11439
|
className,
|
|
11433
11440
|
"aria-label": ariaLabelOverride
|
|
11434
11441
|
}) {
|
|
11435
11442
|
const { handleProps, isDragging } = useBottomSheetContext();
|
|
11436
|
-
|
|
11443
|
+
const { isHovered, hoverProps } = reactAria.useHover({});
|
|
11444
|
+
const { isFocusVisible, focusProps } = reactAria.useFocusRing();
|
|
11445
|
+
const mergedHandleProps = reactAria.mergeProps(handleProps, hoverProps, focusProps);
|
|
11446
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
11437
11447
|
"div",
|
|
11438
11448
|
{
|
|
11439
|
-
...
|
|
11449
|
+
...mergedHandleProps,
|
|
11440
11450
|
...ariaLabelOverride !== void 0 ? { "aria-label": ariaLabelOverride } : {},
|
|
11441
|
-
className: cn(bottomSheetHandleWrapperVariants(), className),
|
|
11451
|
+
className: cn(bottomSheetHandleWrapperVariants(), "group/handle", className),
|
|
11442
11452
|
"data-testid": "bottom-sheet-handle",
|
|
11443
|
-
|
|
11444
|
-
|
|
11453
|
+
...getInteractionDataAttributes({
|
|
11454
|
+
isHovered,
|
|
11455
|
+
isFocusVisible,
|
|
11456
|
+
// Treat active drag as pressed — drives the state layer to 10% opacity
|
|
11457
|
+
isPressed: isDragging
|
|
11458
|
+
}),
|
|
11459
|
+
"data-dragging": isDragging ? "" : void 0,
|
|
11460
|
+
children: [
|
|
11461
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: cn(bottomSheetHandleStateLayerVariants()), "aria-hidden": "true" }),
|
|
11462
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: cn(bottomSheetHandleFocusRingVariants()), "aria-hidden": "true" }),
|
|
11463
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: cn(bottomSheetHandlePillVariants()), "aria-hidden": "true" })
|
|
11464
|
+
]
|
|
11445
11465
|
}
|
|
11446
11466
|
);
|
|
11447
11467
|
}
|