@timmbr/ui 1.9.0 → 1.11.0
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/Breadcrumb/Breadcrumb.d.ts +9 -0
- package/dist/components/Breadcrumb/Breadcrumb.d.ts.map +1 -0
- package/dist/components/Breadcrumb/Breadcrumb.js +32 -0
- package/dist/components/Breadcrumb/Breadcrumb.styles.d.ts +8 -0
- package/dist/components/Breadcrumb/Breadcrumb.styles.d.ts.map +1 -0
- package/dist/components/Breadcrumb/Breadcrumb.styles.js +20 -0
- package/dist/components/Breadcrumb/Breadcrumb.types.d.ts +27 -0
- package/dist/components/Breadcrumb/Breadcrumb.types.d.ts.map +1 -0
- package/dist/components/Breadcrumb/index.d.ts +4 -0
- package/dist/components/Breadcrumb/index.d.ts.map +1 -0
- package/dist/components/Chip/Chip.d.ts.map +1 -1
- package/dist/components/Chip/Chip.js +13 -3
- package/dist/components/Chip/Chip.types.d.ts +5 -0
- package/dist/components/Chip/Chip.types.d.ts.map +1 -1
- package/dist/components/Drawer/Drawer.d.ts.map +1 -1
- package/dist/components/Drawer/Drawer.js +4 -4
- package/dist/components/Drawer/Drawer.styles.d.ts +1 -0
- package/dist/components/Drawer/Drawer.styles.d.ts.map +1 -1
- package/dist/components/Drawer/Drawer.styles.js +7 -1
- package/dist/components/Drawer/Drawer.types.d.ts +2 -0
- package/dist/components/Drawer/Drawer.types.d.ts.map +1 -1
- package/dist/components/FilterChips/FilterChips.d.ts +8 -0
- package/dist/components/FilterChips/FilterChips.d.ts.map +1 -0
- package/dist/components/FilterChips/FilterChips.js +39 -0
- package/dist/components/FilterChips/FilterChips.types.d.ts +17 -0
- package/dist/components/FilterChips/FilterChips.types.d.ts.map +1 -0
- package/dist/components/FilterChips/index.d.ts +3 -0
- package/dist/components/FilterChips/index.d.ts.map +1 -0
- package/dist/components/FilterDrawer/FilterDrawer.d.ts +12 -0
- package/dist/components/FilterDrawer/FilterDrawer.d.ts.map +1 -0
- package/dist/components/FilterDrawer/FilterDrawer.js +157 -0
- package/dist/components/FilterDrawer/FilterDrawer.styles.d.ts +12 -0
- package/dist/components/FilterDrawer/FilterDrawer.styles.d.ts.map +1 -0
- package/dist/components/FilterDrawer/FilterDrawer.styles.js +30 -0
- package/dist/components/FilterDrawer/FilterDrawer.types.d.ts +28 -0
- package/dist/components/FilterDrawer/FilterDrawer.types.d.ts.map +1 -0
- package/dist/components/FilterDrawer/index.d.ts +4 -0
- package/dist/components/FilterDrawer/index.d.ts.map +1 -0
- package/dist/components/FilterPanel/FilterPanel.d.ts +33 -0
- package/dist/components/FilterPanel/FilterPanel.d.ts.map +1 -0
- package/dist/components/FilterPanel/FilterPanel.js +239 -0
- package/dist/components/FilterPanel/FilterPanel.styles.d.ts +16 -0
- package/dist/components/FilterPanel/FilterPanel.styles.d.ts.map +1 -0
- package/dist/components/FilterPanel/FilterPanel.styles.js +31 -0
- package/dist/components/FilterPanel/FilterPanel.types.d.ts +80 -0
- package/dist/components/FilterPanel/FilterPanel.types.d.ts.map +1 -0
- package/dist/components/FilterPanel/FilterPanel.types.js +3 -0
- package/dist/components/FilterPanel/index.d.ts +4 -0
- package/dist/components/FilterPanel/index.d.ts.map +1 -0
- package/dist/components/ImageUpload/ImageUpload.styles.d.ts +3 -3
- package/dist/components/MediaCard/MediaCard.d.ts.map +1 -1
- package/dist/components/MediaCard/MediaCard.js +3 -1
- package/dist/components/NavHeader/NavHeader.styles.d.ts +7 -0
- package/dist/components/NavHeader/NavHeader.styles.d.ts.map +1 -1
- package/dist/components/NavHeader/NavHeader.styles.js +20 -2
- package/dist/components/NavHeader/NavHeader.types.d.ts +59 -9
- package/dist/components/NavHeader/NavHeader.types.d.ts.map +1 -1
- package/dist/components/NavHeader/index.d.ts +3 -2
- package/dist/components/NavHeader/index.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/NavHeader/subcomponents/NavMobileSearchDrawer.d.ts.map +1 -1
- package/dist/components/NavHeader/subcomponents/NavMobileSearchDrawer.js +15 -33
- package/dist/components/NavHeader/subcomponents/NavSearch.d.ts.map +1 -1
- package/dist/components/NavHeader/subcomponents/NavSearch.js +37 -83
- package/dist/components/NavHeader/subcomponents/NavSearchPanel.d.ts +63 -0
- package/dist/components/NavHeader/subcomponents/NavSearchPanel.d.ts.map +1 -0
- package/dist/components/NavHeader/subcomponents/NavSearchPanel.js +289 -0
- package/dist/components/NavMenuColumns/NavMenuColumns.styles.js +1 -1
- package/dist/components/OptionPicker/OptionPicker.d.ts +10 -0
- package/dist/components/OptionPicker/OptionPicker.d.ts.map +1 -0
- package/dist/components/OptionPicker/OptionPicker.js +116 -0
- package/dist/components/OptionPicker/OptionPicker.styles.d.ts +20 -0
- package/dist/components/OptionPicker/OptionPicker.styles.d.ts.map +1 -0
- package/dist/components/OptionPicker/OptionPicker.styles.js +60 -0
- package/dist/components/OptionPicker/OptionPicker.types.d.ts +39 -0
- package/dist/components/OptionPicker/OptionPicker.types.d.ts.map +1 -0
- package/dist/components/OptionPicker/index.d.ts +4 -0
- package/dist/components/OptionPicker/index.d.ts.map +1 -0
- package/dist/components/Price/Price.styles.d.ts.map +1 -1
- package/dist/components/Price/Price.styles.js +3 -2
- package/dist/components/ProductGallery/ProductGallery.d.ts +10 -0
- package/dist/components/ProductGallery/ProductGallery.d.ts.map +1 -0
- package/dist/components/ProductGallery/ProductGallery.js +306 -0
- package/dist/components/ProductGallery/ProductGallery.styles.d.ts +32 -0
- package/dist/components/ProductGallery/ProductGallery.styles.d.ts.map +1 -0
- package/dist/components/ProductGallery/ProductGallery.styles.js +86 -0
- package/dist/components/ProductGallery/ProductGallery.types.d.ts +55 -0
- package/dist/components/ProductGallery/ProductGallery.types.d.ts.map +1 -0
- package/dist/components/ProductGallery/ProductGalleryLightbox.d.ts +20 -0
- package/dist/components/ProductGallery/ProductGalleryLightbox.d.ts.map +1 -0
- package/dist/components/ProductGallery/ProductGalleryLightbox.js +210 -0
- package/dist/components/ProductGallery/index.d.ts +4 -0
- package/dist/components/ProductGallery/index.d.ts.map +1 -0
- package/dist/components/QuantityStepper/QuantityStepper.d.ts +8 -0
- package/dist/components/QuantityStepper/QuantityStepper.d.ts.map +1 -0
- package/dist/components/QuantityStepper/QuantityStepper.js +65 -0
- package/dist/components/QuantityStepper/QuantityStepper.styles.d.ts +8 -0
- package/dist/components/QuantityStepper/QuantityStepper.styles.d.ts.map +1 -0
- package/dist/components/QuantityStepper/QuantityStepper.styles.js +24 -0
- package/dist/components/QuantityStepper/QuantityStepper.types.d.ts +20 -0
- package/dist/components/QuantityStepper/QuantityStepper.types.d.ts.map +1 -0
- package/dist/components/QuantityStepper/index.d.ts +4 -0
- package/dist/components/QuantityStepper/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/RangeSlider/RangeSlider.d.ts.map +1 -1
- package/dist/components/RangeSlider/RangeSlider.js +5 -3
- package/dist/components/RangeSlider/RangeSlider.types.d.ts +7 -0
- package/dist/components/RangeSlider/RangeSlider.types.d.ts.map +1 -1
- package/dist/components/Select/Select.d.ts.map +1 -1
- package/dist/components/Select/Select.js +14 -1
- package/dist/components/Select/Select.types.d.ts +4 -0
- package/dist/components/Select/Select.types.d.ts.map +1 -1
- package/dist/components/Skeleton/Skeleton.styles.d.ts +1 -1
- package/dist/components/Snackbar/Snackbar.d.ts +9 -0
- package/dist/components/Snackbar/Snackbar.d.ts.map +1 -0
- package/dist/components/Snackbar/Snackbar.js +108 -0
- package/dist/components/Snackbar/Snackbar.styles.d.ts +17 -0
- package/dist/components/Snackbar/Snackbar.styles.d.ts.map +1 -0
- package/dist/components/Snackbar/Snackbar.styles.js +37 -0
- package/dist/components/Snackbar/Snackbar.types.d.ts +36 -0
- package/dist/components/Snackbar/Snackbar.types.d.ts.map +1 -0
- package/dist/components/Snackbar/SnackbarHost.d.ts +4 -0
- package/dist/components/Snackbar/SnackbarHost.d.ts.map +1 -0
- package/dist/components/Snackbar/SnackbarHost.js +24 -0
- package/dist/components/Snackbar/index.d.ts +6 -0
- package/dist/components/Snackbar/index.d.ts.map +1 -0
- package/dist/components/Snackbar/snackbarStore.d.ts +42 -0
- package/dist/components/Snackbar/snackbarStore.d.ts.map +1 -0
- package/dist/components/Snackbar/snackbarStore.js +87 -0
- package/dist/components/StockMeter/StockMeter.d.ts +8 -0
- package/dist/components/StockMeter/StockMeter.d.ts.map +1 -0
- package/dist/components/StockMeter/StockMeter.js +19 -0
- package/dist/components/StockMeter/StockMeter.styles.d.ts +4 -0
- package/dist/components/StockMeter/StockMeter.styles.d.ts.map +1 -0
- package/dist/components/StockMeter/StockMeter.styles.js +7 -0
- package/dist/components/StockMeter/StockMeter.types.d.ts +10 -0
- package/dist/components/StockMeter/StockMeter.types.d.ts.map +1 -0
- package/dist/components/StockMeter/index.d.ts +4 -0
- package/dist/components/StockMeter/index.d.ts.map +1 -0
- package/dist/components/Swatch/Swatch.d.ts +11 -0
- package/dist/components/Swatch/Swatch.d.ts.map +1 -0
- package/dist/components/Swatch/Swatch.js +40 -0
- package/dist/components/Swatch/Swatch.styles.d.ts +8 -0
- package/dist/components/Swatch/Swatch.styles.d.ts.map +1 -0
- package/dist/components/Swatch/Swatch.styles.js +26 -0
- package/dist/components/Swatch/Swatch.types.d.ts +11 -0
- package/dist/components/Swatch/Swatch.types.d.ts.map +1 -0
- package/dist/components/Swatch/index.d.ts +4 -0
- package/dist/components/Swatch/index.d.ts.map +1 -0
- package/dist/components/Toast/Toast.d.ts.map +1 -1
- package/dist/components/Toast/Toast.js +49 -42
- package/dist/components/Toast/Toast.types.d.ts +7 -0
- package/dist/components/Toast/Toast.types.d.ts.map +1 -1
- package/dist/components/Toast/ToastContainer.d.ts.map +1 -1
- package/dist/components/Toast/ToastContainer.js +5 -0
- package/dist/components/Toast/toastStore.d.ts +11 -0
- package/dist/components/Toast/toastStore.d.ts.map +1 -1
- package/dist/components/Toast/toastStore.js +70 -30
- package/dist/index.d.ts +11 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +26 -1
- package/dist/providers/TimmbrConfigProvider.d.ts.map +1 -1
- package/dist/providers/TimmbrConfigProvider.js +5 -9
- package/package.json +5 -5
|
@@ -0,0 +1,210 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx, jsxs } from 'react/jsx-runtime';
|
|
3
|
+
import * as React from 'react';
|
|
4
|
+
import * as DialogPrimitive from '@radix-ui/react-dialog';
|
|
5
|
+
import { ZoomOut, ZoomIn, X, ChevronLeft, ChevronRight } from '@timmbr/icons';
|
|
6
|
+
import { productGalleryLightboxButtonVariants, productGalleryLightboxVariants } from './ProductGallery.styles.js';
|
|
7
|
+
|
|
8
|
+
const MAX_SCALE = 3;
|
|
9
|
+
const ZOOM_STEP = 2;
|
|
10
|
+
const SWIPE_PX = 50;
|
|
11
|
+
const TAP_SLOP_PX = 10;
|
|
12
|
+
const FIT = { scale: 1, x: 0, y: 0 };
|
|
13
|
+
function ProductGalleryLightbox({
|
|
14
|
+
open,
|
|
15
|
+
onOpenChange,
|
|
16
|
+
images,
|
|
17
|
+
index,
|
|
18
|
+
onIndexChange,
|
|
19
|
+
renderImage,
|
|
20
|
+
labels,
|
|
21
|
+
onCloseAutoFocus
|
|
22
|
+
}) {
|
|
23
|
+
const [view, setView] = React.useState(FIT);
|
|
24
|
+
const pointers = React.useRef(/* @__PURE__ */ new Map());
|
|
25
|
+
const pinch = React.useRef(null);
|
|
26
|
+
const lastTap = React.useRef(0);
|
|
27
|
+
const lastPointerType = React.useRef("mouse");
|
|
28
|
+
const swipe = React.useRef(null);
|
|
29
|
+
const [dragX, setDragX] = React.useState(0);
|
|
30
|
+
const total = images.length;
|
|
31
|
+
const image = images[index];
|
|
32
|
+
const [shown, setShown] = React.useState({ index, open });
|
|
33
|
+
if (shown.index !== index || shown.open !== open) {
|
|
34
|
+
setShown({ index, open });
|
|
35
|
+
setView(FIT);
|
|
36
|
+
}
|
|
37
|
+
const handleOpenChange = (next) => {
|
|
38
|
+
if (!next) {
|
|
39
|
+
pointers.current.clear();
|
|
40
|
+
pinch.current = null;
|
|
41
|
+
swipe.current = null;
|
|
42
|
+
lastTap.current = 0;
|
|
43
|
+
setDragX(0);
|
|
44
|
+
}
|
|
45
|
+
onOpenChange(next);
|
|
46
|
+
};
|
|
47
|
+
const go = (delta) => {
|
|
48
|
+
const next = index + delta;
|
|
49
|
+
if (next >= 0 && next < total) onIndexChange(next);
|
|
50
|
+
};
|
|
51
|
+
const zoomTo = (scale) => setView((current) => {
|
|
52
|
+
const clamped = Math.min(MAX_SCALE, Math.max(1, scale));
|
|
53
|
+
return clamped === 1 ? FIT : { ...current, scale: clamped };
|
|
54
|
+
});
|
|
55
|
+
const toggleZoom = () => zoomTo(view.scale > 1 ? 1 : ZOOM_STEP);
|
|
56
|
+
const onKeyDown = (event) => {
|
|
57
|
+
if (event.key === "ArrowRight") go(1);
|
|
58
|
+
else if (event.key === "ArrowLeft") go(-1);
|
|
59
|
+
else if (event.key === "+" || event.key === "=") zoomTo(view.scale + 0.5);
|
|
60
|
+
else if (event.key === "-") zoomTo(view.scale - 0.5);
|
|
61
|
+
};
|
|
62
|
+
const distance = () => {
|
|
63
|
+
const [a, b] = [...pointers.current.values()];
|
|
64
|
+
return Math.hypot(a.x - b.x, a.y - b.y);
|
|
65
|
+
};
|
|
66
|
+
const onPointerDown = (event) => {
|
|
67
|
+
lastPointerType.current = event.pointerType;
|
|
68
|
+
event.currentTarget.setPointerCapture(event.pointerId);
|
|
69
|
+
pointers.current.set(event.pointerId, { x: event.clientX, y: event.clientY });
|
|
70
|
+
if (pointers.current.size === 1) {
|
|
71
|
+
swipe.current = { x: event.clientX, y: event.clientY, multi: false };
|
|
72
|
+
} else {
|
|
73
|
+
if (swipe.current) swipe.current.multi = true;
|
|
74
|
+
setDragX(0);
|
|
75
|
+
}
|
|
76
|
+
if (pointers.current.size === 2) pinch.current = { distance: distance(), scale: view.scale };
|
|
77
|
+
};
|
|
78
|
+
const onPointerMove = (event) => {
|
|
79
|
+
const previous = pointers.current.get(event.pointerId);
|
|
80
|
+
if (!previous) return;
|
|
81
|
+
pointers.current.set(event.pointerId, { x: event.clientX, y: event.clientY });
|
|
82
|
+
if (pinch.current && pointers.current.size === 2) {
|
|
83
|
+
zoomTo(pinch.current.scale * distance() / pinch.current.distance);
|
|
84
|
+
} else if (view.scale > 1) {
|
|
85
|
+
const dx = event.clientX - previous.x;
|
|
86
|
+
const dy = event.clientY - previous.y;
|
|
87
|
+
setView((current) => ({ ...current, x: current.x + dx, y: current.y + dy }));
|
|
88
|
+
} else if (swipe.current && !swipe.current.multi && event.pointerType !== "mouse") {
|
|
89
|
+
setDragX(event.clientX - swipe.current.x);
|
|
90
|
+
}
|
|
91
|
+
};
|
|
92
|
+
const onPointerUp = (event) => {
|
|
93
|
+
const start = pointers.current.get(event.pointerId);
|
|
94
|
+
pointers.current.delete(event.pointerId);
|
|
95
|
+
if (pointers.current.size < 2) pinch.current = null;
|
|
96
|
+
const gesture = swipe.current;
|
|
97
|
+
if (pointers.current.size === 0) {
|
|
98
|
+
swipe.current = null;
|
|
99
|
+
setDragX(0);
|
|
100
|
+
}
|
|
101
|
+
if (!start || event.pointerType === "mouse") return;
|
|
102
|
+
if (gesture && !gesture.multi && view.scale === 1) {
|
|
103
|
+
const dx = event.clientX - gesture.x;
|
|
104
|
+
const dy = event.clientY - gesture.y;
|
|
105
|
+
if (Math.abs(dx) > SWIPE_PX && Math.abs(dx) > Math.abs(dy)) {
|
|
106
|
+
lastTap.current = 0;
|
|
107
|
+
go(dx < 0 ? 1 : -1);
|
|
108
|
+
return;
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
const still = gesture && !gesture.multi && Math.hypot(event.clientX - gesture.x, event.clientY - gesture.y) < TAP_SLOP_PX;
|
|
112
|
+
if (!still) {
|
|
113
|
+
lastTap.current = 0;
|
|
114
|
+
return;
|
|
115
|
+
}
|
|
116
|
+
const now = Date.now();
|
|
117
|
+
if (now - lastTap.current < 300) {
|
|
118
|
+
lastTap.current = 0;
|
|
119
|
+
toggleZoom();
|
|
120
|
+
} else {
|
|
121
|
+
lastTap.current = now;
|
|
122
|
+
}
|
|
123
|
+
};
|
|
124
|
+
return /* @__PURE__ */ jsx(DialogPrimitive.Root, { open, onOpenChange: handleOpenChange, children: /* @__PURE__ */ jsx(DialogPrimitive.Portal, { children: /* @__PURE__ */ jsxs(
|
|
125
|
+
DialogPrimitive.Content,
|
|
126
|
+
{
|
|
127
|
+
className: productGalleryLightboxVariants(),
|
|
128
|
+
onKeyDown,
|
|
129
|
+
onCloseAutoFocus,
|
|
130
|
+
"aria-describedby": void 0,
|
|
131
|
+
"data-slot": "product-gallery-lightbox",
|
|
132
|
+
children: [
|
|
133
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between gap-3 p-3 sm:p-4", children: [
|
|
134
|
+
/* @__PURE__ */ jsxs(DialogPrimitive.Title, { className: "text-body-2 font-semibold tabular-nums", children: [
|
|
135
|
+
labels.position(index, total),
|
|
136
|
+
/* @__PURE__ */ jsx("span", { className: "sr-only", children: image ? ` — ${image.alt}` : "" })
|
|
137
|
+
] }),
|
|
138
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
|
|
139
|
+
/* @__PURE__ */ jsx(
|
|
140
|
+
"button",
|
|
141
|
+
{
|
|
142
|
+
type: "button",
|
|
143
|
+
className: productGalleryLightboxButtonVariants(),
|
|
144
|
+
"aria-label": view.scale > 1 ? labels.zoomOut : labels.zoomIn,
|
|
145
|
+
onClick: toggleZoom,
|
|
146
|
+
children: view.scale > 1 ? /* @__PURE__ */ jsx(ZoomOut, { "aria-hidden": "true" }) : /* @__PURE__ */ jsx(ZoomIn, { "aria-hidden": "true" })
|
|
147
|
+
}
|
|
148
|
+
),
|
|
149
|
+
/* @__PURE__ */ jsx(DialogPrimitive.Close, { className: productGalleryLightboxButtonVariants(), "aria-label": labels.close, children: /* @__PURE__ */ jsx(X, { "aria-hidden": "true" }) })
|
|
150
|
+
] })
|
|
151
|
+
] }),
|
|
152
|
+
/* @__PURE__ */ jsxs(
|
|
153
|
+
"div",
|
|
154
|
+
{
|
|
155
|
+
className: "relative min-h-0 flex-1 touch-none select-none overflow-hidden",
|
|
156
|
+
onDoubleClick: () => lastPointerType.current === "mouse" && toggleZoom(),
|
|
157
|
+
onWheel: (event) => zoomTo(view.scale - event.deltaY * 2e-3),
|
|
158
|
+
onPointerDown,
|
|
159
|
+
onPointerMove,
|
|
160
|
+
onPointerUp,
|
|
161
|
+
onPointerCancel: onPointerUp,
|
|
162
|
+
style: { cursor: view.scale > 1 ? "grab" : "zoom-in" },
|
|
163
|
+
"data-slot": "product-gallery-lightbox-stage",
|
|
164
|
+
children: [
|
|
165
|
+
image && /* @__PURE__ */ jsx(
|
|
166
|
+
"div",
|
|
167
|
+
{
|
|
168
|
+
className: `absolute inset-0 ease-out motion-reduce:transition-none ${dragX ? "" : "transition-transform duration-150"}`,
|
|
169
|
+
style: { transform: `translate(${view.x + dragX}px, ${view.y}px) scale(${view.scale})` },
|
|
170
|
+
children: renderImage(image, {
|
|
171
|
+
priority: false,
|
|
172
|
+
sizes: "100vw",
|
|
173
|
+
slot: "lightbox",
|
|
174
|
+
className: "object-contain"
|
|
175
|
+
})
|
|
176
|
+
}
|
|
177
|
+
),
|
|
178
|
+
/* @__PURE__ */ jsx(
|
|
179
|
+
"button",
|
|
180
|
+
{
|
|
181
|
+
type: "button",
|
|
182
|
+
className: `${productGalleryLightboxButtonVariants()} absolute left-3 top-1/2 hidden -translate-y-1/2 md:flex`,
|
|
183
|
+
"aria-label": labels.previous,
|
|
184
|
+
disabled: index === 0,
|
|
185
|
+
onClick: () => go(-1),
|
|
186
|
+
onPointerDown: (event) => event.stopPropagation(),
|
|
187
|
+
children: /* @__PURE__ */ jsx(ChevronLeft, { "aria-hidden": "true" })
|
|
188
|
+
}
|
|
189
|
+
),
|
|
190
|
+
/* @__PURE__ */ jsx(
|
|
191
|
+
"button",
|
|
192
|
+
{
|
|
193
|
+
type: "button",
|
|
194
|
+
className: `${productGalleryLightboxButtonVariants()} absolute right-3 top-1/2 hidden -translate-y-1/2 md:flex`,
|
|
195
|
+
"aria-label": labels.next,
|
|
196
|
+
disabled: index >= total - 1,
|
|
197
|
+
onClick: () => go(1),
|
|
198
|
+
onPointerDown: (event) => event.stopPropagation(),
|
|
199
|
+
children: /* @__PURE__ */ jsx(ChevronRight, { "aria-hidden": "true" })
|
|
200
|
+
}
|
|
201
|
+
)
|
|
202
|
+
]
|
|
203
|
+
}
|
|
204
|
+
)
|
|
205
|
+
]
|
|
206
|
+
}
|
|
207
|
+
) }) });
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
export { ProductGalleryLightbox };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/ProductGallery/index.ts"],"names":[],"mappings":"AAAA,cAAc,kBAAkB,CAAC;AACjC,cAAc,wBAAwB,CAAC;AACvC,cAAc,yBAAyB,CAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import type { QuantityStepperProps } from './QuantityStepper.types';
|
|
3
|
+
/**
|
|
4
|
+
* − value + for a quantity. The buttons stop at `min` and `max` (e.g. the units in stock), and
|
|
5
|
+
* the value is announced when it changes. Arrow up/down on either button steps too.
|
|
6
|
+
*/
|
|
7
|
+
export declare const QuantityStepper: React.ForwardRefExoticComponent<QuantityStepperProps & React.RefAttributes<HTMLDivElement>>;
|
|
8
|
+
//# sourceMappingURL=QuantityStepper.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"QuantityStepper.d.ts","sourceRoot":"","sources":["../../../src/components/QuantityStepper/QuantityStepper.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAQ/B,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,yBAAyB,CAAC;AAEpE;;;GAGG;AACH,eAAO,MAAM,eAAe,6FAmD3B,CAAC"}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
3
|
+
import * as React from 'react';
|
|
4
|
+
import { Minus, Plus } from '@timmbr/icons';
|
|
5
|
+
import { cn } from '@timmbr/utils';
|
|
6
|
+
import { quantityStepperButtonVariants, quantityStepperValueVariants, quantityStepperVariants } from './QuantityStepper.styles.js';
|
|
7
|
+
|
|
8
|
+
const QuantityStepper = React.forwardRef(
|
|
9
|
+
({ value, onChange, min = 1, max = 99, size, disabled = false, labels, className, ...props }, ref) => {
|
|
10
|
+
const clamp = (next) => Math.min(Math.max(next, min), Math.max(min, max));
|
|
11
|
+
const step = (delta) => {
|
|
12
|
+
const next = clamp(value + delta);
|
|
13
|
+
if (next !== value) onChange(next);
|
|
14
|
+
};
|
|
15
|
+
const onKeyDown = (event) => {
|
|
16
|
+
if (event.key === "ArrowUp" || event.key === "ArrowRight") {
|
|
17
|
+
event.preventDefault();
|
|
18
|
+
step(1);
|
|
19
|
+
} else if (event.key === "ArrowDown" || event.key === "ArrowLeft") {
|
|
20
|
+
event.preventDefault();
|
|
21
|
+
step(-1);
|
|
22
|
+
}
|
|
23
|
+
};
|
|
24
|
+
return /* @__PURE__ */ jsxs(
|
|
25
|
+
"div",
|
|
26
|
+
{
|
|
27
|
+
ref,
|
|
28
|
+
role: "group",
|
|
29
|
+
"aria-label": labels?.group ?? "Quantity",
|
|
30
|
+
"data-slot": "quantity-stepper",
|
|
31
|
+
className: cn(quantityStepperVariants({ size, disabled }), className),
|
|
32
|
+
onKeyDown: disabled ? void 0 : onKeyDown,
|
|
33
|
+
...props,
|
|
34
|
+
children: [
|
|
35
|
+
/* @__PURE__ */ jsx(
|
|
36
|
+
"button",
|
|
37
|
+
{
|
|
38
|
+
type: "button",
|
|
39
|
+
"aria-label": labels?.decrease ?? "Decrease quantity",
|
|
40
|
+
disabled: disabled || value <= min,
|
|
41
|
+
onClick: () => step(-1),
|
|
42
|
+
className: quantityStepperButtonVariants(),
|
|
43
|
+
children: /* @__PURE__ */ jsx(Minus, { "aria-hidden": "true", className: "size-4" })
|
|
44
|
+
}
|
|
45
|
+
),
|
|
46
|
+
/* @__PURE__ */ jsx("output", { "aria-live": "polite", className: quantityStepperValueVariants(), "data-slot": "quantity-stepper-value", children: value }),
|
|
47
|
+
/* @__PURE__ */ jsx(
|
|
48
|
+
"button",
|
|
49
|
+
{
|
|
50
|
+
type: "button",
|
|
51
|
+
"aria-label": labels?.increase ?? "Increase quantity",
|
|
52
|
+
disabled: disabled || value >= max,
|
|
53
|
+
onClick: () => step(1),
|
|
54
|
+
className: quantityStepperButtonVariants(),
|
|
55
|
+
children: /* @__PURE__ */ jsx(Plus, { "aria-hidden": "true", className: "size-4" })
|
|
56
|
+
}
|
|
57
|
+
)
|
|
58
|
+
]
|
|
59
|
+
}
|
|
60
|
+
);
|
|
61
|
+
}
|
|
62
|
+
);
|
|
63
|
+
QuantityStepper.displayName = "QuantityStepper";
|
|
64
|
+
|
|
65
|
+
export { QuantityStepper };
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/** Bordered box: − value +, on a white surface with the 4px radius used by fields. */
|
|
2
|
+
export declare const quantityStepperVariants: (props?: ({
|
|
3
|
+
size?: "md" | "lg" | null | undefined;
|
|
4
|
+
disabled?: boolean | null | undefined;
|
|
5
|
+
} & import("class-variance-authority/types").ClassProp) | undefined) => string;
|
|
6
|
+
export declare const quantityStepperButtonVariants: (props?: import("class-variance-authority/types").ClassProp | undefined) => string;
|
|
7
|
+
export declare const quantityStepperValueVariants: (props?: import("class-variance-authority/types").ClassProp | undefined) => string;
|
|
8
|
+
//# sourceMappingURL=QuantityStepper.styles.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"QuantityStepper.styles.d.ts","sourceRoot":"","sources":["../../../src/components/QuantityStepper/QuantityStepper.styles.ts"],"names":[],"mappings":"AAEA,sFAAsF;AACtF,eAAO,MAAM,uBAAuB;;;8EAenC,CAAC;AAEF,eAAO,MAAM,6BAA6B,oFAEzC,CAAC;AAEF,eAAO,MAAM,4BAA4B,oFAAoE,CAAC"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { cva } from 'class-variance-authority';
|
|
2
|
+
|
|
3
|
+
const quantityStepperVariants = cva(
|
|
4
|
+
"inline-flex shrink-0 items-center rounded-sm border border-grey-300 bg-grey-50 font-sans text-grey-950",
|
|
5
|
+
{
|
|
6
|
+
variants: {
|
|
7
|
+
size: {
|
|
8
|
+
md: "h-11",
|
|
9
|
+
lg: "h-[52px]"
|
|
10
|
+
},
|
|
11
|
+
disabled: {
|
|
12
|
+
true: "opacity-50",
|
|
13
|
+
false: ""
|
|
14
|
+
}
|
|
15
|
+
},
|
|
16
|
+
defaultVariants: { size: "md", disabled: false }
|
|
17
|
+
}
|
|
18
|
+
);
|
|
19
|
+
const quantityStepperButtonVariants = cva(
|
|
20
|
+
"flex h-full w-10 items-center justify-center rounded-sm text-grey-500 transition-colors hover:text-grey-950 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-ring disabled:cursor-not-allowed disabled:text-grey-300"
|
|
21
|
+
);
|
|
22
|
+
const quantityStepperValueVariants = cva("min-w-6 text-center text-body-1 font-semibold tabular-nums");
|
|
23
|
+
|
|
24
|
+
export { quantityStepperButtonVariants, quantityStepperValueVariants, quantityStepperVariants };
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type * as React from 'react';
|
|
2
|
+
export interface QuantityStepperLabels {
|
|
3
|
+
/** Accessible name of the whole control. */
|
|
4
|
+
group?: string;
|
|
5
|
+
decrease?: string;
|
|
6
|
+
increase?: string;
|
|
7
|
+
}
|
|
8
|
+
export interface QuantityStepperProps extends Omit<React.HTMLAttributes<HTMLDivElement>, 'onChange'> {
|
|
9
|
+
value: number;
|
|
10
|
+
onChange: (value: number) => void;
|
|
11
|
+
/** Defaults to 1. */
|
|
12
|
+
min?: number;
|
|
13
|
+
/** The + button disables here (e.g. units in stock). Defaults to 99. */
|
|
14
|
+
max?: number;
|
|
15
|
+
/** `md` matches the default button height (44px); `lg` matches a 52px buy button. */
|
|
16
|
+
size?: 'md' | 'lg';
|
|
17
|
+
disabled?: boolean;
|
|
18
|
+
labels?: QuantityStepperLabels;
|
|
19
|
+
}
|
|
20
|
+
//# sourceMappingURL=QuantityStepper.types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"QuantityStepper.types.d.ts","sourceRoot":"","sources":["../../../src/components/QuantityStepper/QuantityStepper.types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,KAAK,MAAM,OAAO,CAAC;AAEpC,MAAM,WAAW,qBAAqB;IACpC,4CAA4C;IAC5C,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,oBAAqB,SAAQ,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,cAAc,CAAC,EAAE,UAAU,CAAC;IAClG,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAClC,qBAAqB;IACrB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,wEAAwE;IACxE,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,qFAAqF;IACrF,IAAI,CAAC,EAAE,IAAI,GAAG,IAAI,CAAC;IACnB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,MAAM,CAAC,EAAE,qBAAqB,CAAC;CAChC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/QuantityStepper/index.ts"],"names":[],"mappings":"AAAA,cAAc,mBAAmB,CAAC;AAClC,cAAc,yBAAyB,CAAC;AACxC,cAAc,0BAA0B,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 +1 @@
|
|
|
1
|
-
{"version":3,"file":"RangeSlider.d.ts","sourceRoot":"","sources":["../../../src/components/RangeSlider/RangeSlider.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAU/B,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAE5D,eAAO,MAAM,WAAW,
|
|
1
|
+
{"version":3,"file":"RangeSlider.d.ts","sourceRoot":"","sources":["../../../src/components/RangeSlider/RangeSlider.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAU/B,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAE5D,eAAO,MAAM,WAAW,0FA2IvB,CAAC"}
|
|
@@ -25,6 +25,8 @@ const RangeSlider = React.forwardRef(
|
|
|
25
25
|
onValueCommit,
|
|
26
26
|
onApply,
|
|
27
27
|
onReset,
|
|
28
|
+
thumbLabels = ["Minimum value", "Maximum value"],
|
|
29
|
+
resetDisabled = false,
|
|
28
30
|
disabled,
|
|
29
31
|
...props
|
|
30
32
|
}, ref) => {
|
|
@@ -98,7 +100,7 @@ const RangeSlider = React.forwardRef(
|
|
|
98
100
|
SliderPrimitive.Thumb,
|
|
99
101
|
{
|
|
100
102
|
className: rangeSliderThumbVariants(),
|
|
101
|
-
"aria-label": index === 0 ?
|
|
103
|
+
"aria-label": thumbLabels[index === 0 ? 0 : 1]
|
|
102
104
|
},
|
|
103
105
|
index
|
|
104
106
|
))
|
|
@@ -111,8 +113,8 @@ const RangeSlider = React.forwardRef(
|
|
|
111
113
|
{
|
|
112
114
|
type: "button",
|
|
113
115
|
onClick: handleReset,
|
|
114
|
-
disabled,
|
|
115
|
-
className: "text-body-3 font-
|
|
116
|
+
disabled: disabled || resetDisabled,
|
|
117
|
+
className: "rounded-sm text-body-3 font-semibold text-foreground underline decoration-border underline-offset-4 transition-colors cursor-pointer hover:text-primary hover:decoration-primary focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring disabled:cursor-not-allowed disabled:no-underline disabled:opacity-40 disabled:hover:text-foreground",
|
|
116
118
|
children: resetLabel
|
|
117
119
|
}
|
|
118
120
|
),
|
|
@@ -64,5 +64,12 @@ export interface RangeSliderProps extends Omit<React.ComponentPropsWithoutRef<ty
|
|
|
64
64
|
* Callback fired when the Reset button is clicked.
|
|
65
65
|
*/
|
|
66
66
|
onReset?: () => void;
|
|
67
|
+
/**
|
|
68
|
+
* Accessible names of the two thumbs (translate these).
|
|
69
|
+
* @default ['Minimum value', 'Maximum value']
|
|
70
|
+
*/
|
|
71
|
+
thumbLabels?: [string, string];
|
|
72
|
+
/** Disables Reset (e.g. nothing to reset). */
|
|
73
|
+
resetDisabled?: boolean;
|
|
67
74
|
}
|
|
68
75
|
//# sourceMappingURL=RangeSlider.types.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"RangeSlider.types.d.ts","sourceRoot":"","sources":["../../../src/components/RangeSlider/RangeSlider.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,mBAAmB,EAAE,MAAM,sBAAsB,CAAC;AAEhE,MAAM,WAAW,gBACf,SAAQ,IAAI,CACR,KAAK,CAAC,wBAAwB,CAAC,OAAO,eAAe,CAAC,IAAI,CAAC,EAC3D,OAAO,GAAG,cAAc,GAAG,eAAe,GAAG,eAAe,CAC7D,EACD,mBAAmB;IACrB;;OAEG;IACH,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;IACjB;;OAEG;IACH,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;IACxB;;OAEG;IACH,GAAG,CAAC,EAAE,MAAM,CAAC;IACb;;OAEG;IACH,GAAG,CAAC,EAAE,MAAM,CAAC;IACb;;OAEG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC;IACd;;OAEG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;;OAEG;IACH,WAAW,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,MAAM,CAAC;IACxC;;;OAGG;IACH,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB;;;OAGG;IACH,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB;;OAEG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB;;OAEG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB;;OAEG;IACH,aAAa,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,IAAI,CAAC;IAC3C;;OAEG;IACH,aAAa,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,IAAI,CAAC;IAC3C;;OAEG;IACH,OAAO,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,IAAI,CAAC;IACrC;;OAEG;IACH,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;
|
|
1
|
+
{"version":3,"file":"RangeSlider.types.d.ts","sourceRoot":"","sources":["../../../src/components/RangeSlider/RangeSlider.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,mBAAmB,EAAE,MAAM,sBAAsB,CAAC;AAEhE,MAAM,WAAW,gBACf,SAAQ,IAAI,CACR,KAAK,CAAC,wBAAwB,CAAC,OAAO,eAAe,CAAC,IAAI,CAAC,EAC3D,OAAO,GAAG,cAAc,GAAG,eAAe,GAAG,eAAe,CAC7D,EACD,mBAAmB;IACrB;;OAEG;IACH,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;IACjB;;OAEG;IACH,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;IACxB;;OAEG;IACH,GAAG,CAAC,EAAE,MAAM,CAAC;IACb;;OAEG;IACH,GAAG,CAAC,EAAE,MAAM,CAAC;IACb;;OAEG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC;IACd;;OAEG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;;OAEG;IACH,WAAW,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,MAAM,CAAC;IACxC;;;OAGG;IACH,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB;;;OAGG;IACH,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB;;OAEG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB;;OAEG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB;;OAEG;IACH,aAAa,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,IAAI,CAAC;IAC3C;;OAEG;IACH,aAAa,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,IAAI,CAAC;IAC3C;;OAEG;IACH,OAAO,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,IAAI,CAAC;IACrC;;OAEG;IACH,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB;;;OAGG;IACH,WAAW,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC/B,8CAA8C;IAC9C,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Select.d.ts","sourceRoot":"","sources":["../../../src/components/Select/Select.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,KAAK,eAAe,MAAM,wBAAwB,CAAC;AAU1D,OAAO,KAAK,EAAE,WAAW,EAAgB,MAAM,gBAAgB,CAAC;AAEhE,eAAO,MAAM,MAAM,
|
|
1
|
+
{"version":3,"file":"Select.d.ts","sourceRoot":"","sources":["../../../src/components/Select/Select.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,KAAK,eAAe,MAAM,wBAAwB,CAAC;AAU1D,OAAO,KAAK,EAAE,WAAW,EAAgB,MAAM,gBAAgB,CAAC;AAEhE,eAAO,MAAM,MAAM,uFAiIlB,CAAC;AAKF,eAAO,MAAM,UAAU,uCAAuB,CAAC;AAC/C,eAAO,MAAM,aAAa,8GAA0B,CAAC;AACrD,eAAO,MAAM,WAAW,0GAAwB,CAAC;AACjD,eAAO,MAAM,aAAa,2GAA0B,CAAC;AACrD,eAAO,MAAM,UAAU,wGAAuB,CAAC;AAC/C,eAAO,MAAM,WAAW,yGAAwB,CAAC;AACjD,eAAO,MAAM,WAAW,yGAAwB,CAAC;AACjD,eAAO,MAAM,eAAe,6GAA4B,CAAC"}
|
|
@@ -26,8 +26,12 @@ const Select = React.forwardRef(
|
|
|
26
26
|
onValueChange,
|
|
27
27
|
disabled,
|
|
28
28
|
children,
|
|
29
|
+
ariaLabel,
|
|
30
|
+
id: customId,
|
|
29
31
|
...props
|
|
30
32
|
}, ref) => {
|
|
33
|
+
const generatedId = React.useId();
|
|
34
|
+
const triggerId = customId ?? generatedId;
|
|
31
35
|
const isError = Boolean(error);
|
|
32
36
|
const errorMessage = typeof error === "string" ? error : void 0;
|
|
33
37
|
const globalMotion = useGlobalAnimation();
|
|
@@ -38,7 +42,14 @@ const Select = React.forwardRef(
|
|
|
38
42
|
className: cn("flex flex-col gap-1.5 w-full font-sans", containerClassName),
|
|
39
43
|
style,
|
|
40
44
|
children: [
|
|
41
|
-
label && /* @__PURE__ */ jsx(
|
|
45
|
+
label && /* @__PURE__ */ jsx(
|
|
46
|
+
"label",
|
|
47
|
+
{
|
|
48
|
+
htmlFor: triggerId,
|
|
49
|
+
className: "text-body-3 font-semibold text-foreground tracking-wide select-none",
|
|
50
|
+
children: label
|
|
51
|
+
}
|
|
52
|
+
),
|
|
42
53
|
/* @__PURE__ */ jsxs(
|
|
43
54
|
SelectPrimitive.Root,
|
|
44
55
|
{
|
|
@@ -52,6 +63,8 @@ const Select = React.forwardRef(
|
|
|
52
63
|
SelectPrimitive.Trigger,
|
|
53
64
|
{
|
|
54
65
|
ref,
|
|
66
|
+
id: triggerId,
|
|
67
|
+
"aria-label": ariaLabel,
|
|
55
68
|
"data-slot": "select-trigger",
|
|
56
69
|
"aria-invalid": isError ? "true" : void 0,
|
|
57
70
|
className: cn(
|
|
@@ -13,6 +13,10 @@ export interface SelectProps extends Omit<SelectPrimitive.SelectProps, 'children
|
|
|
13
13
|
* Field label displayed above the select trigger.
|
|
14
14
|
*/
|
|
15
15
|
label?: string;
|
|
16
|
+
/** Accessible name when there is no visible `label` (e.g. a compact "Sort by" control). */
|
|
17
|
+
ariaLabel?: string;
|
|
18
|
+
/** Id of the trigger (generated when omitted); the visible label points at it. */
|
|
19
|
+
id?: string;
|
|
16
20
|
/**
|
|
17
21
|
* Placeholder text shown when no value is selected.
|
|
18
22
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Select.types.d.ts","sourceRoot":"","sources":["../../../src/components/Select/Select.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,qBAAqB,EAAE,MAAM,iBAAiB,CAAC;AAC7D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAErD,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,WACf,SAAQ,IAAI,CAAC,eAAe,CAAC,WAAW,EAAE,UAAU,CAAC,EACnD,qBAAqB;IACvB;;OAEG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;;OAEG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;OAEG;IACH,OAAO,CAAC,EAAE,YAAY,EAAE,CAAC;IACzB;;OAEG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB;;OAEG;IACH,KAAK,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;IACzB;;OAEG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;OAEG;IACH,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B;;OAEG;IACH,KAAK,CAAC,EAAE,KAAK,CAAC,aAAa,CAAC;IAC5B;;OAEG;IACH,MAAM,CAAC,EAAE,UAAU,CAAC;IACpB;;OAEG;IACH,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;CAC5B"}
|
|
1
|
+
{"version":3,"file":"Select.types.d.ts","sourceRoot":"","sources":["../../../src/components/Select/Select.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,qBAAqB,EAAE,MAAM,iBAAiB,CAAC;AAC7D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAErD,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,WACf,SAAQ,IAAI,CAAC,eAAe,CAAC,WAAW,EAAE,UAAU,CAAC,EACnD,qBAAqB;IACvB;;OAEG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,2FAA2F;IAC3F,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,kFAAkF;IAClF,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ;;OAEG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;OAEG;IACH,OAAO,CAAC,EAAE,YAAY,EAAE,CAAC;IACzB;;OAEG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB;;OAEG;IACH,KAAK,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;IACzB;;OAEG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;OAEG;IACH,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B;;OAEG;IACH,KAAK,CAAC,EAAE,KAAK,CAAC,aAAa,CAAC;IAC5B;;OAEG;IACH,MAAM,CAAC,EAAE,UAAU,CAAC;IACpB;;OAEG;IACH,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;CAC5B"}
|
|
@@ -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>;
|