@timmbr/ui 1.10.0 → 1.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/dist/components/Accordion/Accordion.d.ts.map +1 -1
- package/dist/components/Accordion/Accordion.js +23 -12
- package/dist/components/AuthModal/AuthModal.styles.js +1 -1
- package/dist/components/AuthModal/subcomponents/AuthModalParts.d.ts +1 -1
- package/dist/components/AuthModal/subcomponents/AuthModalParts.d.ts.map +1 -1
- package/dist/components/AuthModal/subcomponents/AuthModalParts.js +24 -42
- package/dist/components/Button/Button.d.ts.map +1 -1
- package/dist/components/Button/Button.js +1 -0
- package/dist/components/Checkbox/Checkbox.d.ts.map +1 -1
- package/dist/components/Checkbox/Checkbox.js +10 -1
- package/dist/components/Checkbox/Checkbox.styles.js +1 -1
- package/dist/components/Checkbox/Checkbox.types.d.ts +3 -0
- package/dist/components/Checkbox/Checkbox.types.d.ts.map +1 -1
- package/dist/components/Chip/Chip.js +1 -1
- package/dist/components/Dialog/Dialog.js +1 -1
- package/dist/components/Drawer/Drawer.js +1 -1
- package/dist/components/FilterChips/FilterChips.d.ts.map +1 -1
- package/dist/components/FilterChips/FilterChips.js +2 -9
- package/dist/components/FilterPanel/FilterPanel.d.ts.map +1 -1
- package/dist/components/FilterPanel/FilterPanel.js +9 -7
- package/dist/components/ImageUpload/subcomponents/ImageUploadThumbnailCard.js +1 -1
- package/dist/components/Input/Input.d.ts.map +1 -1
- package/dist/components/Input/Input.js +2 -1
- package/dist/components/NavFooter/NavFooter.styles.js +1 -1
- package/dist/components/NavFooter/subcomponents/FooterBrand.js +1 -1
- package/dist/components/NavHeader/NavHeader.js +1 -1
- package/dist/components/NavHeader/NavHeader.styles.js +4 -4
- package/dist/components/NavHeader/NavHeader.types.d.ts +10 -8
- package/dist/components/NavHeader/NavHeader.types.d.ts.map +1 -1
- package/dist/components/NavHeader/subcomponents/NavActions.d.ts +4 -4
- package/dist/components/NavHeader/subcomponents/NavActions.d.ts.map +1 -1
- package/dist/components/NavHeader/subcomponents/NavActions.js +31 -25
- package/dist/components/PageProgress/PageProgress.d.ts +12 -0
- package/dist/components/PageProgress/PageProgress.d.ts.map +1 -0
- package/dist/components/PageProgress/PageProgress.js +68 -0
- package/dist/components/PageProgress/PageProgress.styles.d.ts +8 -0
- package/dist/components/PageProgress/PageProgress.styles.d.ts.map +1 -0
- package/dist/components/PageProgress/PageProgress.styles.js +32 -0
- package/dist/components/PageProgress/PageProgress.types.d.ts +18 -0
- package/dist/components/PageProgress/PageProgress.types.d.ts.map +1 -0
- package/dist/components/PageProgress/index.d.ts +3 -0
- package/dist/components/PageProgress/index.d.ts.map +1 -0
- package/dist/components/RadioCard/RadioCard.d.ts +9 -0
- package/dist/components/RadioCard/RadioCard.d.ts.map +1 -0
- package/dist/components/RadioCard/RadioCard.js +40 -0
- package/dist/components/RadioCard/RadioCard.styles.d.ts +9 -0
- package/dist/components/RadioCard/RadioCard.styles.d.ts.map +1 -0
- package/dist/components/RadioCard/RadioCard.styles.js +24 -0
- package/dist/components/RadioCard/RadioCard.types.d.ts +28 -0
- package/dist/components/RadioCard/RadioCard.types.d.ts.map +1 -0
- package/dist/components/RadioCard/index.d.ts +4 -0
- package/dist/components/RadioCard/index.d.ts.map +1 -0
- package/dist/components/Skeleton/Skeleton.styles.d.ts +1 -1
- package/dist/components/Snackbar/Snackbar.d.ts.map +1 -1
- package/dist/components/Snackbar/Snackbar.js +6 -2
- package/dist/components/Snackbar/Snackbar.styles.d.ts +1 -0
- package/dist/components/Snackbar/Snackbar.styles.d.ts.map +1 -1
- package/dist/components/Snackbar/Snackbar.styles.js +8 -4
- package/dist/components/Snackbar/Snackbar.types.d.ts +3 -0
- package/dist/components/Snackbar/Snackbar.types.d.ts.map +1 -1
- package/dist/components/Snackbar/snackbarStore.d.ts +3 -0
- package/dist/components/Snackbar/snackbarStore.d.ts.map +1 -1
- package/dist/components/Switch/Switch.d.ts.map +1 -1
- package/dist/components/Switch/Switch.js +19 -2
- package/dist/components/Switch/Switch.styles.js +2 -2
- package/dist/components/Switch/Switch.types.d.ts +3 -0
- package/dist/components/Switch/Switch.types.d.ts.map +1 -1
- package/dist/components/Toast/Toast.js +2 -2
- package/dist/components/Toast/toastStore.d.ts +4 -0
- package/dist/components/Toast/toastStore.d.ts.map +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -0
- package/dist/providers/AnimationProvider.d.ts +5 -1
- package/dist/providers/AnimationProvider.d.ts.map +1 -1
- package/dist/providers/AnimationProvider.js +6 -3
- package/package.json +3 -3
|
@@ -52,31 +52,37 @@ const NavActions = ({
|
|
|
52
52
|
}
|
|
53
53
|
}
|
|
54
54
|
};
|
|
55
|
-
const
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
55
|
+
const wishlist = wishlistAction === false ? void 0 : wishlistAction;
|
|
56
|
+
if (wishlistAction !== false) {
|
|
57
|
+
const wishCount = wishlist?.count;
|
|
58
|
+
defaultItems.push({
|
|
59
|
+
id: "wishlist",
|
|
60
|
+
label: wishlist?.label ?? "WISH LIST",
|
|
61
|
+
icon: wishlist?.icon ?? /* @__PURE__ */ jsx(Heart, { size: 22, className: "stroke-[1.8]" }),
|
|
62
|
+
href: wishlist?.href ?? "/wishlist",
|
|
63
|
+
zone: wishlist?.zone,
|
|
64
|
+
crossZone: wishlist?.crossZone,
|
|
65
|
+
badge: wishlist?.badge ?? (wishCount && wishCount > 0 ? wishCount : void 0),
|
|
66
|
+
onClick: wishlist?.onClick,
|
|
67
|
+
ariaLabel: wishlist?.ariaLabel ?? (wishCount ? `Wishlist with ${wishCount} items` : "Wishlist")
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
const cart = cartAction === false ? void 0 : cartAction;
|
|
71
|
+
if (cartAction !== false) {
|
|
72
|
+
const cartCount = cart?.count;
|
|
73
|
+
defaultItems.push({
|
|
74
|
+
id: "cart",
|
|
75
|
+
label: cart?.label ?? "CART",
|
|
76
|
+
icon: cart?.icon ?? /* @__PURE__ */ jsx(ShoppingCart, { size: 22, className: "stroke-[1.8]" }),
|
|
77
|
+
href: cart?.href ?? "/cart",
|
|
78
|
+
zone: cart?.zone,
|
|
79
|
+
crossZone: cart?.crossZone,
|
|
80
|
+
badge: cart?.badge ?? (cartCount && cartCount > 0 ? cartCount : void 0),
|
|
81
|
+
onClick: cart?.onClick,
|
|
82
|
+
ariaLabel: cart?.ariaLabel ?? (cartCount ? `Shopping cart with ${cartCount} items` : "Shopping cart"),
|
|
83
|
+
priority: "high"
|
|
84
|
+
});
|
|
85
|
+
}
|
|
80
86
|
defaultItems.push({
|
|
81
87
|
id: "profile",
|
|
82
88
|
label: profileAction?.label ?? "LOGIN",
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import type { PageProgressProps } from './PageProgress.types';
|
|
3
|
+
/**
|
|
4
|
+
* NProgress-style slim line fixed at the very top of the viewport. Mount it (or set
|
|
5
|
+
* `loading={true}`) to show; unmount (or `loading={false}`) to fade out.
|
|
6
|
+
*
|
|
7
|
+
* Indeterminate mode (no `progress`): the bar sweeps left-to-right continuously until
|
|
8
|
+
* loading ends, matching the Progress component's indeterminate style.
|
|
9
|
+
* Determinate mode (`progress` 0–100): bar grows to the given percentage.
|
|
10
|
+
*/
|
|
11
|
+
export declare const PageProgress: React.ForwardRefExoticComponent<PageProgressProps & React.RefAttributes<HTMLDivElement>>;
|
|
12
|
+
//# sourceMappingURL=PageProgress.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PageProgress.d.ts","sourceRoot":"","sources":["../../../src/components/PageProgress/PageProgress.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAK/B,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AAE9D;;;;;;;GAOG;AACH,eAAO,MAAM,YAAY,0FA0DxB,CAAC"}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx } from 'react/jsx-runtime';
|
|
3
|
+
import * as React from 'react';
|
|
4
|
+
import { cn } from '@timmbr/utils';
|
|
5
|
+
import { resolveMotion } from '../../types/motion.js';
|
|
6
|
+
import { pageProgressBarVariants, pageProgressVariants } from './PageProgress.styles.js';
|
|
7
|
+
import { useGlobalAnimation } from '../../providers/AnimationProvider.js';
|
|
8
|
+
|
|
9
|
+
const PageProgress = React.forwardRef(
|
|
10
|
+
({ loading = true, progress, height = 3, zIndex = 9999, color = "bg-primary", motion }, ref) => {
|
|
11
|
+
const globalMotion = useGlobalAnimation();
|
|
12
|
+
const { shouldAnimate } = resolveMotion(motion, globalMotion);
|
|
13
|
+
const isIndeterminate = progress === void 0;
|
|
14
|
+
const safeProgress = isIndeterminate ? void 0 : Math.min(Math.max(progress, 0), 100);
|
|
15
|
+
const [visible, setVisible] = React.useState(loading);
|
|
16
|
+
const [fading, setFading] = React.useState(false);
|
|
17
|
+
React.useEffect(() => {
|
|
18
|
+
if (loading) {
|
|
19
|
+
setVisible(true);
|
|
20
|
+
setFading(false);
|
|
21
|
+
} else if (visible) {
|
|
22
|
+
if (!shouldAnimate) {
|
|
23
|
+
setVisible(false);
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
setFading(true);
|
|
27
|
+
const t = setTimeout(() => {
|
|
28
|
+
setVisible(false);
|
|
29
|
+
setFading(false);
|
|
30
|
+
}, 350);
|
|
31
|
+
return () => clearTimeout(t);
|
|
32
|
+
}
|
|
33
|
+
}, [loading, shouldAnimate]);
|
|
34
|
+
if (!visible) return null;
|
|
35
|
+
return /* @__PURE__ */ jsx(
|
|
36
|
+
"div",
|
|
37
|
+
{
|
|
38
|
+
ref,
|
|
39
|
+
role: "progressbar",
|
|
40
|
+
"aria-valuemin": 0,
|
|
41
|
+
"aria-valuemax": 100,
|
|
42
|
+
"aria-valuenow": safeProgress,
|
|
43
|
+
"aria-label": "Page loading",
|
|
44
|
+
"data-slot": "page-progress",
|
|
45
|
+
style: { height, zIndex },
|
|
46
|
+
className: pageProgressVariants({ fading: fading && shouldAnimate }),
|
|
47
|
+
children: /* @__PURE__ */ jsx(
|
|
48
|
+
"div",
|
|
49
|
+
{
|
|
50
|
+
"data-slot": "page-progress-bar",
|
|
51
|
+
className: cn(
|
|
52
|
+
pageProgressBarVariants({
|
|
53
|
+
indeterminate: isIndeterminate && !fading,
|
|
54
|
+
animated: shouldAnimate
|
|
55
|
+
}),
|
|
56
|
+
color,
|
|
57
|
+
!isIndeterminate && shouldAnimate && "transition-[width] duration-300 ease-out"
|
|
58
|
+
),
|
|
59
|
+
style: isIndeterminate ? void 0 : { width: `${safeProgress}%` }
|
|
60
|
+
}
|
|
61
|
+
)
|
|
62
|
+
}
|
|
63
|
+
);
|
|
64
|
+
}
|
|
65
|
+
);
|
|
66
|
+
PageProgress.displayName = "PageProgress";
|
|
67
|
+
|
|
68
|
+
export { PageProgress };
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export declare const pageProgressVariants: (props?: ({
|
|
2
|
+
fading?: boolean | null | undefined;
|
|
3
|
+
} & import("class-variance-authority/types").ClassProp) | undefined) => string;
|
|
4
|
+
export declare const pageProgressBarVariants: (props?: ({
|
|
5
|
+
indeterminate?: boolean | null | undefined;
|
|
6
|
+
animated?: boolean | null | undefined;
|
|
7
|
+
} & import("class-variance-authority/types").ClassProp) | undefined) => string;
|
|
8
|
+
//# sourceMappingURL=PageProgress.styles.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PageProgress.styles.d.ts","sourceRoot":"","sources":["../../../src/components/PageProgress/PageProgress.styles.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,oBAAoB;;8EAWhC,CAAC;AAEF,eAAO,MAAM,uBAAuB;;;8EAenC,CAAC"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { cva } from 'class-variance-authority';
|
|
2
|
+
|
|
3
|
+
const pageProgressVariants = cva(
|
|
4
|
+
"fixed top-0 left-0 right-0 overflow-hidden",
|
|
5
|
+
{
|
|
6
|
+
variants: {
|
|
7
|
+
fading: {
|
|
8
|
+
true: "transition-opacity duration-300 opacity-0",
|
|
9
|
+
false: ""
|
|
10
|
+
}
|
|
11
|
+
},
|
|
12
|
+
defaultVariants: { fading: false }
|
|
13
|
+
}
|
|
14
|
+
);
|
|
15
|
+
const pageProgressBarVariants = cva(
|
|
16
|
+
"absolute top-0 bottom-0 rounded-full",
|
|
17
|
+
{
|
|
18
|
+
variants: {
|
|
19
|
+
indeterminate: {
|
|
20
|
+
true: "animate-indeterminate-bar",
|
|
21
|
+
false: ""
|
|
22
|
+
},
|
|
23
|
+
animated: {
|
|
24
|
+
true: "",
|
|
25
|
+
false: "transition-none animate-none"
|
|
26
|
+
}
|
|
27
|
+
},
|
|
28
|
+
defaultVariants: { indeterminate: false, animated: true }
|
|
29
|
+
}
|
|
30
|
+
);
|
|
31
|
+
|
|
32
|
+
export { pageProgressBarVariants, pageProgressVariants };
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { MotionProp } from '../../types/motion';
|
|
2
|
+
export interface PageProgressProps {
|
|
3
|
+
/** When false, the bar is hidden; when true (or omitted while mounted), it shows. */
|
|
4
|
+
loading?: boolean;
|
|
5
|
+
/**
|
|
6
|
+
* Determinate value 0–100. Omit for indeterminate mode (the bar crawls to ~80% and stalls
|
|
7
|
+
* until `loading` becomes false, at which point it completes and fades out).
|
|
8
|
+
*/
|
|
9
|
+
progress?: number;
|
|
10
|
+
/** Bar height in px. Default: 3. */
|
|
11
|
+
height?: number;
|
|
12
|
+
/** CSS stack order. Default: 9999. */
|
|
13
|
+
zIndex?: number;
|
|
14
|
+
/** Tailwind color class for the bar. Default: bg-primary. */
|
|
15
|
+
color?: string;
|
|
16
|
+
motion?: MotionProp;
|
|
17
|
+
}
|
|
18
|
+
//# sourceMappingURL=PageProgress.types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PageProgress.types.d.ts","sourceRoot":"","sources":["../../../src/components/PageProgress/PageProgress.types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAErD,MAAM,WAAW,iBAAiB;IAChC,qFAAqF;IACrF,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB;;;OAGG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,oCAAoC;IACpC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,sCAAsC;IACtC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,6DAA6D;IAC7D,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,UAAU,CAAC;CACrB"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/PageProgress/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,YAAY,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import type { RadioCardProps } from './RadioCard.types';
|
|
3
|
+
/**
|
|
4
|
+
* A selectable row or tile for choices that need more than a label (a payment method, a delivery
|
|
5
|
+
* speed). Place inside a `RadioGroup`: the whole card is the radio, so the group's `value`,
|
|
6
|
+
* `onValueChange`, arrow-key navigation and `name` work as usual.
|
|
7
|
+
*/
|
|
8
|
+
export declare const RadioCard: React.ForwardRefExoticComponent<RadioCardProps & React.RefAttributes<HTMLButtonElement>>;
|
|
9
|
+
//# sourceMappingURL=RadioCard.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"RadioCard.d.ts","sourceRoot":"","sources":["../../../src/components/RadioCard/RadioCard.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAM/B,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAExD;;;;GAIG;AACH,eAAO,MAAM,SAAS,0FAwCrB,CAAC"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
3
|
+
import * as React from 'react';
|
|
4
|
+
import * as RadioGroupPrimitive from '@radix-ui/react-radio-group';
|
|
5
|
+
import { cn } from '@timmbr/utils';
|
|
6
|
+
import { resolveMotion } from '../../types/motion.js';
|
|
7
|
+
import { radioCardMarkerClass, radioCardDotClass, radioCardVariants } from './RadioCard.styles.js';
|
|
8
|
+
import { useGlobalAnimation } from '../../providers/AnimationProvider.js';
|
|
9
|
+
|
|
10
|
+
const RadioCard = React.forwardRef(
|
|
11
|
+
({ className, variant, label, description, icon, trailing, motion, ...props }, ref) => {
|
|
12
|
+
const globalMotion = useGlobalAnimation();
|
|
13
|
+
const { shouldAnimate, motionClass } = resolveMotion(motion, globalMotion);
|
|
14
|
+
return /* @__PURE__ */ jsxs(
|
|
15
|
+
RadioGroupPrimitive.Item,
|
|
16
|
+
{
|
|
17
|
+
ref,
|
|
18
|
+
"data-slot": "radio-card",
|
|
19
|
+
className: cn(
|
|
20
|
+
radioCardVariants({ variant }),
|
|
21
|
+
!shouldAnimate && "transition-none",
|
|
22
|
+
motionClass,
|
|
23
|
+
className
|
|
24
|
+
),
|
|
25
|
+
...props,
|
|
26
|
+
children: [
|
|
27
|
+
icon && /* @__PURE__ */ jsx("span", { className: "flex shrink-0 items-center justify-center", "aria-hidden": "true", children: icon }),
|
|
28
|
+
/* @__PURE__ */ jsxs("span", { className: "flex min-w-0 flex-1 flex-col gap-1", children: [
|
|
29
|
+
/* @__PURE__ */ jsx("span", { className: "text-body-2 font-medium leading-tight", children: label }),
|
|
30
|
+
description && /* @__PURE__ */ jsx("span", { className: "text-body-3 leading-normal text-muted-foreground", children: description })
|
|
31
|
+
] }),
|
|
32
|
+
trailing ? /* @__PURE__ */ jsx("span", { className: "flex shrink-0 items-center", "aria-hidden": "true", children: trailing }) : /* @__PURE__ */ jsx("span", { className: radioCardMarkerClass, "aria-hidden": "true", children: /* @__PURE__ */ jsx(RadioGroupPrimitive.Indicator, { className: radioCardDotClass }) })
|
|
33
|
+
]
|
|
34
|
+
}
|
|
35
|
+
);
|
|
36
|
+
}
|
|
37
|
+
);
|
|
38
|
+
RadioCard.displayName = "RadioCard";
|
|
39
|
+
|
|
40
|
+
export { RadioCard };
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { type VariantProps } from 'class-variance-authority';
|
|
2
|
+
export declare const radioCardVariants: (props?: ({
|
|
3
|
+
variant?: "row" | "card" | null | undefined;
|
|
4
|
+
} & import("class-variance-authority/types").ClassProp) | undefined) => string;
|
|
5
|
+
/** The round marker at the end of a card (replaced by `trailing`). */
|
|
6
|
+
export declare const radioCardMarkerClass = "flex h-5 w-5 shrink-0 items-center justify-center rounded-full border border-grey-300 dark:border-grey-700 bg-grey-50 dark:bg-grey-900 group-data-[state=checked]:border-primary";
|
|
7
|
+
export declare const radioCardDotClass = "h-2.5 w-2.5 rounded-full bg-primary";
|
|
8
|
+
export type RadioCardVariants = VariantProps<typeof radioCardVariants>;
|
|
9
|
+
//# sourceMappingURL=RadioCard.styles.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"RadioCard.styles.d.ts","sourceRoot":"","sources":["../../../src/components/RadioCard/RadioCard.styles.ts"],"names":[],"mappings":"AAAA,OAAO,EAAO,KAAK,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAElE,eAAO,MAAM,iBAAiB;;8EAiB7B,CAAC;AAEF,sEAAsE;AACtE,eAAO,MAAM,oBAAoB,qLACmJ,CAAC;AAErL,eAAO,MAAM,iBAAiB,wCAAwC,CAAC;AAEvE,MAAM,MAAM,iBAAiB,GAAG,YAAY,CAAC,OAAO,iBAAiB,CAAC,CAAC"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { cva } from 'class-variance-authority';
|
|
2
|
+
|
|
3
|
+
const radioCardVariants = cva(
|
|
4
|
+
"group flex w-full items-center gap-3 text-left font-sans text-foreground transition-colors duration-150 focus:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 cursor-pointer",
|
|
5
|
+
{
|
|
6
|
+
variants: {
|
|
7
|
+
/**
|
|
8
|
+
* - `row`: no surface of its own, for lists inside a card (divide them with `divide-y` on the group);
|
|
9
|
+
* - `card`: a bordered tile that highlights when selected.
|
|
10
|
+
*/
|
|
11
|
+
variant: {
|
|
12
|
+
row: "py-4",
|
|
13
|
+
card: "rounded-[8px] border border-grey-200 dark:border-grey-800 bg-card p-4 hover:border-grey-400 data-[state=checked]:border-primary"
|
|
14
|
+
}
|
|
15
|
+
},
|
|
16
|
+
defaultVariants: {
|
|
17
|
+
variant: "row"
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
);
|
|
21
|
+
const radioCardMarkerClass = "flex h-5 w-5 shrink-0 items-center justify-center rounded-full border border-grey-300 dark:border-grey-700 bg-grey-50 dark:bg-grey-900 group-data-[state=checked]:border-primary";
|
|
22
|
+
const radioCardDotClass = "h-2.5 w-2.5 rounded-full bg-primary";
|
|
23
|
+
|
|
24
|
+
export { radioCardDotClass, radioCardMarkerClass, radioCardVariants };
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import type * as React from 'react';
|
|
2
|
+
import type * as RadioGroupPrimitive from '@radix-ui/react-radio-group';
|
|
3
|
+
import type { RadioCardVariants } from './RadioCard.styles';
|
|
4
|
+
import type { MotionProp } from '../../types/motion';
|
|
5
|
+
export interface RadioCardProps extends Omit<RadioGroupPrimitive.RadioGroupItemProps, 'children'>, RadioCardVariants {
|
|
6
|
+
/**
|
|
7
|
+
* Main text of the option.
|
|
8
|
+
*/
|
|
9
|
+
label: React.ReactNode;
|
|
10
|
+
/**
|
|
11
|
+
* Supporting text under the label.
|
|
12
|
+
*/
|
|
13
|
+
description?: React.ReactNode;
|
|
14
|
+
/**
|
|
15
|
+
* Leading visual (an icon or logo), shown before the label.
|
|
16
|
+
*/
|
|
17
|
+
icon?: React.ReactNode;
|
|
18
|
+
/**
|
|
19
|
+
* Replaces the round selection marker at the end (e.g. a chevron).
|
|
20
|
+
* The card is still announced and navigated as a radio.
|
|
21
|
+
*/
|
|
22
|
+
trailing?: React.ReactNode;
|
|
23
|
+
/**
|
|
24
|
+
* Motion transition control.
|
|
25
|
+
*/
|
|
26
|
+
motion?: MotionProp;
|
|
27
|
+
}
|
|
28
|
+
//# sourceMappingURL=RadioCard.types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"RadioCard.types.d.ts","sourceRoot":"","sources":["../../../src/components/RadioCard/RadioCard.types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,KAAK,MAAM,OAAO,CAAC;AACpC,OAAO,KAAK,KAAK,mBAAmB,MAAM,6BAA6B,CAAC;AACxE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAC5D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAErD,MAAM,WAAW,cACf,SAAQ,IAAI,CAAC,mBAAmB,CAAC,mBAAmB,EAAE,UAAU,CAAC,EAC/D,iBAAiB;IACnB;;OAEG;IACH,KAAK,EAAE,KAAK,CAAC,SAAS,CAAC;IACvB;;OAEG;IACH,WAAW,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC9B;;OAEG;IACH,IAAI,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACvB;;;OAGG;IACH,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC3B;;OAEG;IACH,MAAM,CAAC,EAAE,UAAU,CAAC;CACrB"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/RadioCard/index.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAC;AAC5B,cAAc,mBAAmB,CAAC;AAClC,cAAc,oBAAoB,CAAC"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { type VariantProps } from 'class-variance-authority';
|
|
2
2
|
export declare const skeletonVariants: (props?: ({
|
|
3
|
-
variant?: "text" | "
|
|
3
|
+
variant?: "text" | "card" | "circular" | "rectangular" | null | undefined;
|
|
4
4
|
animation?: "none" | "pulse" | "wave" | null | undefined;
|
|
5
5
|
} & import("class-variance-authority/types").ClassProp) | undefined) => string;
|
|
6
6
|
export type SkeletonVariants = VariantProps<typeof skeletonVariants>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Snackbar.d.ts","sourceRoot":"","sources":["../../../src/components/Snackbar/Snackbar.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"Snackbar.d.ts","sourceRoot":"","sources":["../../../src/components/Snackbar/Snackbar.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAW/B,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAatD;;;;GAIG;AACH,eAAO,MAAM,QAAQ,sFAiGpB,CAAC"}
|
|
@@ -3,7 +3,9 @@ import { jsxs, jsx } from 'react/jsx-runtime';
|
|
|
3
3
|
import * as React from 'react';
|
|
4
4
|
import { AlertCircle, AlertTriangle, CheckCircle, Info, X } from '@timmbr/icons';
|
|
5
5
|
import { cn } from '@timmbr/utils';
|
|
6
|
+
import { resolveMotion } from '../../types/motion.js';
|
|
6
7
|
import { snackbarIconVariants, snackbarActionVariants, snackbarCloseVariants, snackbarVariants } from './Snackbar.styles.js';
|
|
8
|
+
import { useGlobalAnimation } from '../../providers/AnimationProvider.js';
|
|
7
9
|
|
|
8
10
|
const ICONS = {
|
|
9
11
|
default: Info,
|
|
@@ -14,9 +16,11 @@ const ICONS = {
|
|
|
14
16
|
};
|
|
15
17
|
const SWIPE_DISMISS_PX = 48;
|
|
16
18
|
const Snackbar = React.forwardRef(
|
|
17
|
-
({ item, onDismiss, dismissLabel = "Dismiss", className, style, ...props }, ref) => {
|
|
19
|
+
({ item, onDismiss, dismissLabel = "Dismiss", motion, className, style, ...props }, ref) => {
|
|
18
20
|
const variant = item.variant ?? "default";
|
|
19
21
|
const Icon = ICONS[variant];
|
|
22
|
+
const globalMotion = useGlobalAnimation();
|
|
23
|
+
const { shouldAnimate } = resolveMotion(motion, globalMotion);
|
|
20
24
|
const duration = item.duration ?? (item.action ? 6e3 : 4e3);
|
|
21
25
|
const [paused, setPaused] = React.useState(false);
|
|
22
26
|
const remaining = React.useRef(duration);
|
|
@@ -62,7 +66,7 @@ const Snackbar = React.forwardRef(
|
|
|
62
66
|
"data-slot": "snackbar",
|
|
63
67
|
"data-variant": variant,
|
|
64
68
|
"data-state": item.open ? "open" : "closed",
|
|
65
|
-
className: cn(snackbarVariants({ open: item.open }), dragging && "transition-none", className),
|
|
69
|
+
className: cn(snackbarVariants({ open: item.open, animated: shouldAnimate }), dragging && "transition-none", className),
|
|
66
70
|
style: {
|
|
67
71
|
...style,
|
|
68
72
|
...dragging && {
|
|
@@ -7,6 +7,7 @@ export declare const snackbarHostVariants: (props?: import("class-variance-autho
|
|
|
7
7
|
/** Inverse surface (dark bar, light text), as on Android and most shopping apps. */
|
|
8
8
|
export declare const snackbarVariants: (props?: ({
|
|
9
9
|
open?: boolean | null | undefined;
|
|
10
|
+
animated?: boolean | null | undefined;
|
|
10
11
|
} & import("class-variance-authority/types").ClassProp) | undefined) => string;
|
|
11
12
|
export declare const snackbarIconVariants: (props?: ({
|
|
12
13
|
variant?: "default" | "destructive" | "success" | "warning" | "info" | null | undefined;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Snackbar.styles.d.ts","sourceRoot":"","sources":["../../../src/components/Snackbar/Snackbar.styles.ts"],"names":[],"mappings":"AAEA;;;;GAIG;AACH,eAAO,MAAM,oBAAoB,oFAEhC,CAAC;AAEF,oFAAoF;AACpF,eAAO,MAAM,gBAAgB
|
|
1
|
+
{"version":3,"file":"Snackbar.styles.d.ts","sourceRoot":"","sources":["../../../src/components/Snackbar/Snackbar.styles.ts"],"names":[],"mappings":"AAEA;;;;GAIG;AACH,eAAO,MAAM,oBAAoB,oFAEhC,CAAC;AAEF,oFAAoF;AACpF,eAAO,MAAM,gBAAgB;;;8EAe5B,CAAC;AAEF,eAAO,MAAM,oBAAoB;;8EAW/B,CAAC;AAEH,oFAAoF;AACpF,eAAO,MAAM,sBAAsB,oFAElC,CAAC;AAEF,eAAO,MAAM,qBAAqB,oFAEjC,CAAC"}
|
|
@@ -4,15 +4,19 @@ const snackbarHostVariants = cva(
|
|
|
4
4
|
"pointer-events-none fixed inset-x-3 z-[110] flex justify-center bottom-[calc(0.75rem+env(safe-area-inset-bottom)+var(--toast-offset-bottom,0px))] transition-[bottom] duration-200 sm:inset-x-auto sm:left-1/2 sm:-translate-x-1/2"
|
|
5
5
|
);
|
|
6
6
|
const snackbarVariants = cva(
|
|
7
|
-
"pointer-events-auto flex w-full min-h-12 touch-pan-y select-none items-center gap-3 rounded-md bg-grey-950 py-2.5 pl-4 pr-2 font-sans text-grey-50 shadow-xl sm:w-auto sm:min-w-[22rem] sm:max-w-[36rem]
|
|
7
|
+
"pointer-events-auto flex w-full min-h-12 touch-pan-y select-none items-center gap-3 rounded-md bg-grey-950 py-2.5 pl-4 pr-2 font-sans text-grey-50 shadow-xl sm:w-auto sm:min-w-[22rem] sm:max-w-[36rem]",
|
|
8
8
|
{
|
|
9
9
|
variants: {
|
|
10
10
|
open: {
|
|
11
11
|
true: "translate-y-0 opacity-100",
|
|
12
12
|
false: "translate-y-2 opacity-0"
|
|
13
|
+
},
|
|
14
|
+
animated: {
|
|
15
|
+
true: "transition-[transform,opacity] duration-200",
|
|
16
|
+
false: "transition-none"
|
|
13
17
|
}
|
|
14
18
|
},
|
|
15
|
-
defaultVariants: { open: true }
|
|
19
|
+
defaultVariants: { open: true, animated: true }
|
|
16
20
|
}
|
|
17
21
|
);
|
|
18
22
|
const snackbarIconVariants = cva("size-5 shrink-0", {
|
|
@@ -28,10 +32,10 @@ const snackbarIconVariants = cva("size-5 shrink-0", {
|
|
|
28
32
|
defaultVariants: { variant: "default" }
|
|
29
33
|
});
|
|
30
34
|
const snackbarActionVariants = cva(
|
|
31
|
-
"shrink-0 rounded-sm px-2.5 py-2 text-body-3 font-bold uppercase tracking-wide text-primary-200 transition-colors hover:bg-grey-50/10 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-grey-50"
|
|
35
|
+
"cursor-pointer shrink-0 rounded-sm px-2.5 py-2 text-body-3 font-bold uppercase tracking-wide text-primary-200 transition-colors hover:bg-grey-50/10 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-grey-50"
|
|
32
36
|
);
|
|
33
37
|
const snackbarCloseVariants = cva(
|
|
34
|
-
"flex size-8 shrink-0 items-center justify-center rounded-full text-grey-400 transition-colors hover:bg-grey-50/10 hover:text-grey-50 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-grey-50"
|
|
38
|
+
"cursor-pointer flex size-8 shrink-0 items-center justify-center rounded-full text-grey-400 transition-colors hover:bg-grey-50/10 hover:text-grey-50 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-grey-50"
|
|
35
39
|
);
|
|
36
40
|
|
|
37
41
|
export { snackbarActionVariants, snackbarCloseVariants, snackbarHostVariants, snackbarIconVariants, snackbarVariants };
|
|
@@ -22,11 +22,14 @@ export interface SnackbarItem extends SnackbarOptions {
|
|
|
22
22
|
/** False while it animates out. */
|
|
23
23
|
open: boolean;
|
|
24
24
|
}
|
|
25
|
+
import type { MotionProp } from '../../types/motion';
|
|
25
26
|
export interface SnackbarProps extends Omit<React.HTMLAttributes<HTMLDivElement>, 'children'> {
|
|
26
27
|
item: SnackbarItem;
|
|
27
28
|
onDismiss: () => void;
|
|
28
29
|
/** Labels for assistive tech. */
|
|
29
30
|
dismissLabel?: string;
|
|
31
|
+
/** Override animation behaviour. `false` disables entry/exit transitions; omit to inherit global setting. */
|
|
32
|
+
motion?: MotionProp;
|
|
30
33
|
}
|
|
31
34
|
export interface SnackbarHostProps {
|
|
32
35
|
/** Accessible name of the dismiss control (snackbars can be swiped away too). */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Snackbar.types.d.ts","sourceRoot":"","sources":["../../../src/components/Snackbar/Snackbar.types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,KAAK,MAAM,OAAO,CAAC;AAEpC,MAAM,MAAM,eAAe,GAAG,SAAS,GAAG,SAAS,GAAG,MAAM,GAAG,SAAS,GAAG,aAAa,CAAC;AAEzF,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,KAAK,CAAC,SAAS,CAAC;IACvB,OAAO,EAAE,CAAC,KAAK,EAAE,KAAK,CAAC,UAAU,CAAC,iBAAiB,CAAC,KAAK,IAAI,CAAC;CAC/D;AAED,MAAM,WAAW,eAAe;IAC9B,sEAAsE;IACtE,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,sEAAsE;IACtE,WAAW,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC9B,OAAO,CAAC,EAAE,eAAe,CAAC;IAC1B,mFAAmF;IACnF,MAAM,CAAC,EAAE,cAAc,CAAC;IACxB,2FAA2F;IAC3F,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,IAAI,CAAC;CACxB;AAED,MAAM,WAAW,YAAa,SAAQ,eAAe;IACnD,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,KAAK,CAAC,SAAS,CAAC;IACzB,mCAAmC;IACnC,IAAI,EAAE,OAAO,CAAC;CACf;AAED,MAAM,WAAW,aAAc,SAAQ,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,cAAc,CAAC,EAAE,UAAU,CAAC;IAC3F,IAAI,EAAE,YAAY,CAAC;IACnB,SAAS,EAAE,MAAM,IAAI,CAAC;IACtB,iCAAiC;IACjC,YAAY,CAAC,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"Snackbar.types.d.ts","sourceRoot":"","sources":["../../../src/components/Snackbar/Snackbar.types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,KAAK,MAAM,OAAO,CAAC;AAEpC,MAAM,MAAM,eAAe,GAAG,SAAS,GAAG,SAAS,GAAG,MAAM,GAAG,SAAS,GAAG,aAAa,CAAC;AAEzF,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,KAAK,CAAC,SAAS,CAAC;IACvB,OAAO,EAAE,CAAC,KAAK,EAAE,KAAK,CAAC,UAAU,CAAC,iBAAiB,CAAC,KAAK,IAAI,CAAC;CAC/D;AAED,MAAM,WAAW,eAAe;IAC9B,sEAAsE;IACtE,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,sEAAsE;IACtE,WAAW,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC9B,OAAO,CAAC,EAAE,eAAe,CAAC;IAC1B,mFAAmF;IACnF,MAAM,CAAC,EAAE,cAAc,CAAC;IACxB,2FAA2F;IAC3F,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,IAAI,CAAC;CACxB;AAED,MAAM,WAAW,YAAa,SAAQ,eAAe;IACnD,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,KAAK,CAAC,SAAS,CAAC;IACzB,mCAAmC;IACnC,IAAI,EAAE,OAAO,CAAC;CACf;AAED,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAErD,MAAM,WAAW,aAAc,SAAQ,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,cAAc,CAAC,EAAE,UAAU,CAAC;IAC3F,IAAI,EAAE,YAAY,CAAC;IACnB,SAAS,EAAE,MAAM,IAAI,CAAC;IACtB,iCAAiC;IACjC,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,6GAA6G;IAC7G,MAAM,CAAC,EAAE,UAAU,CAAC;CACrB;AAED,MAAM,WAAW,iBAAiB;IAChC,iFAAiF;IACjF,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB"}
|
|
@@ -4,6 +4,9 @@ import type { SnackbarItem, SnackbarOptions } from './Snackbar.types';
|
|
|
4
4
|
export declare const SNACKBAR_EXIT_MS = 180;
|
|
5
5
|
type Listener = () => void;
|
|
6
6
|
/**
|
|
7
|
+
* Browser-only module-level singleton. Not SSR-safe — never import this on the server.
|
|
8
|
+
* Use `.reset()` in tests to clear state between cases.
|
|
9
|
+
*
|
|
7
10
|
* One snackbar at a time (the mobile pattern): showing a new one closes the current one first;
|
|
8
11
|
* extra ones wait their turn. Re-showing an id that's on screen or queued updates it in place.
|
|
9
12
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"snackbarStore.d.ts","sourceRoot":"","sources":["../../../src/components/Snackbar/snackbarStore.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,KAAK,MAAM,OAAO,CAAC;AACpC,OAAO,KAAK,EAAE,YAAY,EAAE,eAAe,EAAmB,MAAM,kBAAkB,CAAC;AAEvF,0EAA0E;AAC1E,eAAO,MAAM,gBAAgB,MAAM,CAAC;AAEpC,KAAK,QAAQ,GAAG,MAAM,IAAI,CAAC;AAE3B
|
|
1
|
+
{"version":3,"file":"snackbarStore.d.ts","sourceRoot":"","sources":["../../../src/components/Snackbar/snackbarStore.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,KAAK,MAAM,OAAO,CAAC;AACpC,OAAO,KAAK,EAAE,YAAY,EAAE,eAAe,EAAmB,MAAM,kBAAkB,CAAC;AAEvF,0EAA0E;AAC1E,eAAO,MAAM,gBAAgB,MAAM,CAAC;AAEpC,KAAK,QAAQ,GAAG,MAAM,IAAI,CAAC;AAE3B;;;;;;GAMG;AACH,cAAM,aAAa;IACjB,OAAO,CAAC,OAAO,CAA6B;IAC5C,OAAO,CAAC,KAAK,CAAsB;IACnC,OAAO,CAAC,SAAS,CAAuB;IACxC,OAAO,CAAC,SAAS,CAA4C;IAC7D,OAAO,CAAC,KAAK,CAAK;IAElB,0FAA0F;IAC1F,YAAY,mBAKV;IAEF,OAAO,gBAAwB;IAE/B,SAAS,GAAI,UAAU,QAAQ,gBAK7B;IAEF,UAAU,4BAAsB;IAEhC,OAAO,CAAC,MAAM;IAId,IAAI,CAAC,OAAO,EAAE,KAAK,CAAC,SAAS,EAAE,OAAO,GAAE,eAAoB,GAAG,MAAM;IAsBrE,OAAO,CAAC,EAAE,CAAC,EAAE,MAAM;IAMnB,OAAO,CAAC,KAAK;IAab,OAAO,CAAC,IAAI;IAKZ,mBAAmB;IACnB,KAAK;CAMN;AAED,eAAO,MAAM,aAAa,eAAsB,CAAC;AAEjD,KAAK,eAAe,GAAG,CAAC,OAAO,EAAE,KAAK,CAAC,SAAS,EAAE,OAAO,CAAC,EAAE,IAAI,CAAC,eAAe,EAAE,SAAS,CAAC,KAAK,MAAM,CAAC;AAExG,MAAM,WAAW,gBAAgB;IAC/B,CAAC,OAAO,EAAE,KAAK,CAAC,SAAS,EAAE,OAAO,CAAC,EAAE,eAAe,GAAG,MAAM,CAAC;IAC9D,OAAO,EAAE,eAAe,CAAC;IACzB,IAAI,EAAE,eAAe,CAAC;IACtB,OAAO,EAAE,eAAe,CAAC;IACzB,KAAK,EAAE,eAAe,CAAC;IACvB,OAAO,EAAE,CAAC,EAAE,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC;CAChC;AAOD,8FAA8F;AAC9F,eAAO,MAAM,QAAQ,EAAE,gBAStB,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Switch.d.ts","sourceRoot":"","sources":["../../../src/components/Switch/Switch.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"Switch.d.ts","sourceRoot":"","sources":["../../../src/components/Switch/Switch.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAM/B,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAElD,eAAO,MAAM,MAAM,uFAkFlB,CAAC"}
|
|
@@ -3,7 +3,9 @@ import { jsx, jsxs } from 'react/jsx-runtime';
|
|
|
3
3
|
import * as React from 'react';
|
|
4
4
|
import * as SwitchPrimitive from '@radix-ui/react-switch';
|
|
5
5
|
import { cn } from '@timmbr/utils';
|
|
6
|
+
import { resolveMotion } from '../../types/motion.js';
|
|
6
7
|
import { switchThumbVariants, switchVariants } from './Switch.styles.js';
|
|
8
|
+
import { useGlobalAnimation } from '../../providers/AnimationProvider.js';
|
|
7
9
|
|
|
8
10
|
const Switch = React.forwardRef(
|
|
9
11
|
({
|
|
@@ -13,22 +15,37 @@ const Switch = React.forwardRef(
|
|
|
13
15
|
size,
|
|
14
16
|
label,
|
|
15
17
|
description,
|
|
18
|
+
motion,
|
|
16
19
|
id: customId,
|
|
17
20
|
disabled,
|
|
18
21
|
...props
|
|
19
22
|
}, ref) => {
|
|
20
23
|
const generatedId = React.useId();
|
|
21
24
|
const id = customId || generatedId;
|
|
25
|
+
const globalMotion = useGlobalAnimation();
|
|
26
|
+
const { shouldAnimate } = resolveMotion(motion, globalMotion);
|
|
22
27
|
const switchElement = /* @__PURE__ */ jsx(
|
|
23
28
|
SwitchPrimitive.Root,
|
|
24
29
|
{
|
|
25
30
|
ref,
|
|
26
31
|
id,
|
|
27
32
|
disabled,
|
|
28
|
-
className: cn(
|
|
33
|
+
className: cn(
|
|
34
|
+
switchVariants({ size }),
|
|
35
|
+
shouldAnimate ? "transition-colors" : "transition-none",
|
|
36
|
+
!label && className
|
|
37
|
+
),
|
|
29
38
|
style: !label ? style : void 0,
|
|
30
39
|
...props,
|
|
31
|
-
children: /* @__PURE__ */ jsx(
|
|
40
|
+
children: /* @__PURE__ */ jsx(
|
|
41
|
+
SwitchPrimitive.Thumb,
|
|
42
|
+
{
|
|
43
|
+
className: cn(
|
|
44
|
+
switchThumbVariants({ size }),
|
|
45
|
+
shouldAnimate ? "transition-transform" : "transition-none"
|
|
46
|
+
)
|
|
47
|
+
}
|
|
48
|
+
)
|
|
32
49
|
}
|
|
33
50
|
);
|
|
34
51
|
if (!label && !description) {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { cva } from 'class-variance-authority';
|
|
2
2
|
|
|
3
3
|
const switchVariants = cva(
|
|
4
|
-
"peer inline-flex shrink-0 cursor-pointer items-center rounded-full border-2 border-transparent
|
|
4
|
+
"peer inline-flex shrink-0 cursor-pointer items-center rounded-full border-2 border-transparent focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 data-[state=checked]:bg-primary data-[state=unchecked]:bg-grey-200 dark:data-[state=unchecked]:bg-grey-700",
|
|
5
5
|
{
|
|
6
6
|
variants: {
|
|
7
7
|
size: {
|
|
@@ -17,7 +17,7 @@ const switchVariants = cva(
|
|
|
17
17
|
}
|
|
18
18
|
);
|
|
19
19
|
const switchThumbVariants = cva(
|
|
20
|
-
"pointer-events-none block rounded-full bg-grey-50 shadow-md ring-0
|
|
20
|
+
"pointer-events-none block rounded-full bg-grey-50 shadow-md ring-0 data-[state=unchecked]:translate-x-0",
|
|
21
21
|
{
|
|
22
22
|
variants: {
|
|
23
23
|
size: {
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type * as React from 'react';
|
|
2
2
|
import type * as SwitchPrimitive from '@radix-ui/react-switch';
|
|
3
3
|
import type { SwitchVariants } from './Switch.styles';
|
|
4
|
+
import type { MotionProp } from '../../types/motion';
|
|
4
5
|
export interface SwitchProps extends Omit<React.ComponentPropsWithoutRef<typeof SwitchPrimitive.Root>, 'size'>, SwitchVariants {
|
|
5
6
|
/**
|
|
6
7
|
* Primary label text displayed next to the switch toggle.
|
|
@@ -14,5 +15,7 @@ export interface SwitchProps extends Omit<React.ComponentPropsWithoutRef<typeof
|
|
|
14
15
|
* Custom className for the outer container wrapper.
|
|
15
16
|
*/
|
|
16
17
|
containerClassName?: string;
|
|
18
|
+
/** Override animation behaviour. `false` disables transitions; omit to inherit global setting. */
|
|
19
|
+
motion?: MotionProp;
|
|
17
20
|
}
|
|
18
21
|
//# sourceMappingURL=Switch.types.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Switch.types.d.ts","sourceRoot":"","sources":["../../../src/components/Switch/Switch.types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,KAAK,MAAM,OAAO,CAAC;AACpC,OAAO,KAAK,KAAK,eAAe,MAAM,wBAAwB,CAAC;AAC/D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;
|
|
1
|
+
{"version":3,"file":"Switch.types.d.ts","sourceRoot":"","sources":["../../../src/components/Switch/Switch.types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,KAAK,MAAM,OAAO,CAAC;AACpC,OAAO,KAAK,KAAK,eAAe,MAAM,wBAAwB,CAAC;AAC/D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AACtD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAErD,MAAM,WAAW,WACf,SAAQ,IAAI,CACR,KAAK,CAAC,wBAAwB,CAAC,OAAO,eAAe,CAAC,IAAI,CAAC,EAC3D,MAAM,CACP,EACD,cAAc;IAChB;;OAEG;IACH,KAAK,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACxB;;OAEG;IACH,WAAW,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC9B;;OAEG;IACH,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,kGAAkG;IAClG,MAAM,CAAC,EAAE,UAAU,CAAC;CACrB"}
|