@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.
Files changed (175) hide show
  1. package/dist/components/Breadcrumb/Breadcrumb.d.ts +9 -0
  2. package/dist/components/Breadcrumb/Breadcrumb.d.ts.map +1 -0
  3. package/dist/components/Breadcrumb/Breadcrumb.js +32 -0
  4. package/dist/components/Breadcrumb/Breadcrumb.styles.d.ts +8 -0
  5. package/dist/components/Breadcrumb/Breadcrumb.styles.d.ts.map +1 -0
  6. package/dist/components/Breadcrumb/Breadcrumb.styles.js +20 -0
  7. package/dist/components/Breadcrumb/Breadcrumb.types.d.ts +27 -0
  8. package/dist/components/Breadcrumb/Breadcrumb.types.d.ts.map +1 -0
  9. package/dist/components/Breadcrumb/index.d.ts +4 -0
  10. package/dist/components/Breadcrumb/index.d.ts.map +1 -0
  11. package/dist/components/Chip/Chip.d.ts.map +1 -1
  12. package/dist/components/Chip/Chip.js +13 -3
  13. package/dist/components/Chip/Chip.types.d.ts +5 -0
  14. package/dist/components/Chip/Chip.types.d.ts.map +1 -1
  15. package/dist/components/Drawer/Drawer.d.ts.map +1 -1
  16. package/dist/components/Drawer/Drawer.js +4 -4
  17. package/dist/components/Drawer/Drawer.styles.d.ts +1 -0
  18. package/dist/components/Drawer/Drawer.styles.d.ts.map +1 -1
  19. package/dist/components/Drawer/Drawer.styles.js +7 -1
  20. package/dist/components/Drawer/Drawer.types.d.ts +2 -0
  21. package/dist/components/Drawer/Drawer.types.d.ts.map +1 -1
  22. package/dist/components/FilterChips/FilterChips.d.ts +8 -0
  23. package/dist/components/FilterChips/FilterChips.d.ts.map +1 -0
  24. package/dist/components/FilterChips/FilterChips.js +39 -0
  25. package/dist/components/FilterChips/FilterChips.types.d.ts +17 -0
  26. package/dist/components/FilterChips/FilterChips.types.d.ts.map +1 -0
  27. package/dist/components/FilterChips/index.d.ts +3 -0
  28. package/dist/components/FilterChips/index.d.ts.map +1 -0
  29. package/dist/components/FilterDrawer/FilterDrawer.d.ts +12 -0
  30. package/dist/components/FilterDrawer/FilterDrawer.d.ts.map +1 -0
  31. package/dist/components/FilterDrawer/FilterDrawer.js +157 -0
  32. package/dist/components/FilterDrawer/FilterDrawer.styles.d.ts +12 -0
  33. package/dist/components/FilterDrawer/FilterDrawer.styles.d.ts.map +1 -0
  34. package/dist/components/FilterDrawer/FilterDrawer.styles.js +30 -0
  35. package/dist/components/FilterDrawer/FilterDrawer.types.d.ts +28 -0
  36. package/dist/components/FilterDrawer/FilterDrawer.types.d.ts.map +1 -0
  37. package/dist/components/FilterDrawer/index.d.ts +4 -0
  38. package/dist/components/FilterDrawer/index.d.ts.map +1 -0
  39. package/dist/components/FilterPanel/FilterPanel.d.ts +33 -0
  40. package/dist/components/FilterPanel/FilterPanel.d.ts.map +1 -0
  41. package/dist/components/FilterPanel/FilterPanel.js +239 -0
  42. package/dist/components/FilterPanel/FilterPanel.styles.d.ts +16 -0
  43. package/dist/components/FilterPanel/FilterPanel.styles.d.ts.map +1 -0
  44. package/dist/components/FilterPanel/FilterPanel.styles.js +31 -0
  45. package/dist/components/FilterPanel/FilterPanel.types.d.ts +80 -0
  46. package/dist/components/FilterPanel/FilterPanel.types.d.ts.map +1 -0
  47. package/dist/components/FilterPanel/FilterPanel.types.js +3 -0
  48. package/dist/components/FilterPanel/index.d.ts +4 -0
  49. package/dist/components/FilterPanel/index.d.ts.map +1 -0
  50. package/dist/components/ImageUpload/ImageUpload.styles.d.ts +3 -3
  51. package/dist/components/MediaCard/MediaCard.d.ts.map +1 -1
  52. package/dist/components/MediaCard/MediaCard.js +3 -1
  53. package/dist/components/NavHeader/NavHeader.styles.d.ts +7 -0
  54. package/dist/components/NavHeader/NavHeader.styles.d.ts.map +1 -1
  55. package/dist/components/NavHeader/NavHeader.styles.js +20 -2
  56. package/dist/components/NavHeader/NavHeader.types.d.ts +59 -9
  57. package/dist/components/NavHeader/NavHeader.types.d.ts.map +1 -1
  58. package/dist/components/NavHeader/index.d.ts +3 -2
  59. package/dist/components/NavHeader/index.d.ts.map +1 -1
  60. package/dist/components/NavHeader/subcomponents/NavActions.d.ts +4 -4
  61. package/dist/components/NavHeader/subcomponents/NavActions.d.ts.map +1 -1
  62. package/dist/components/NavHeader/subcomponents/NavActions.js +31 -25
  63. package/dist/components/NavHeader/subcomponents/NavMobileSearchDrawer.d.ts.map +1 -1
  64. package/dist/components/NavHeader/subcomponents/NavMobileSearchDrawer.js +15 -33
  65. package/dist/components/NavHeader/subcomponents/NavSearch.d.ts.map +1 -1
  66. package/dist/components/NavHeader/subcomponents/NavSearch.js +37 -83
  67. package/dist/components/NavHeader/subcomponents/NavSearchPanel.d.ts +63 -0
  68. package/dist/components/NavHeader/subcomponents/NavSearchPanel.d.ts.map +1 -0
  69. package/dist/components/NavHeader/subcomponents/NavSearchPanel.js +289 -0
  70. package/dist/components/NavMenuColumns/NavMenuColumns.styles.js +1 -1
  71. package/dist/components/OptionPicker/OptionPicker.d.ts +10 -0
  72. package/dist/components/OptionPicker/OptionPicker.d.ts.map +1 -0
  73. package/dist/components/OptionPicker/OptionPicker.js +116 -0
  74. package/dist/components/OptionPicker/OptionPicker.styles.d.ts +20 -0
  75. package/dist/components/OptionPicker/OptionPicker.styles.d.ts.map +1 -0
  76. package/dist/components/OptionPicker/OptionPicker.styles.js +60 -0
  77. package/dist/components/OptionPicker/OptionPicker.types.d.ts +39 -0
  78. package/dist/components/OptionPicker/OptionPicker.types.d.ts.map +1 -0
  79. package/dist/components/OptionPicker/index.d.ts +4 -0
  80. package/dist/components/OptionPicker/index.d.ts.map +1 -0
  81. package/dist/components/Price/Price.styles.d.ts.map +1 -1
  82. package/dist/components/Price/Price.styles.js +3 -2
  83. package/dist/components/ProductGallery/ProductGallery.d.ts +10 -0
  84. package/dist/components/ProductGallery/ProductGallery.d.ts.map +1 -0
  85. package/dist/components/ProductGallery/ProductGallery.js +306 -0
  86. package/dist/components/ProductGallery/ProductGallery.styles.d.ts +32 -0
  87. package/dist/components/ProductGallery/ProductGallery.styles.d.ts.map +1 -0
  88. package/dist/components/ProductGallery/ProductGallery.styles.js +86 -0
  89. package/dist/components/ProductGallery/ProductGallery.types.d.ts +55 -0
  90. package/dist/components/ProductGallery/ProductGallery.types.d.ts.map +1 -0
  91. package/dist/components/ProductGallery/ProductGalleryLightbox.d.ts +20 -0
  92. package/dist/components/ProductGallery/ProductGalleryLightbox.d.ts.map +1 -0
  93. package/dist/components/ProductGallery/ProductGalleryLightbox.js +210 -0
  94. package/dist/components/ProductGallery/index.d.ts +4 -0
  95. package/dist/components/ProductGallery/index.d.ts.map +1 -0
  96. package/dist/components/QuantityStepper/QuantityStepper.d.ts +8 -0
  97. package/dist/components/QuantityStepper/QuantityStepper.d.ts.map +1 -0
  98. package/dist/components/QuantityStepper/QuantityStepper.js +65 -0
  99. package/dist/components/QuantityStepper/QuantityStepper.styles.d.ts +8 -0
  100. package/dist/components/QuantityStepper/QuantityStepper.styles.d.ts.map +1 -0
  101. package/dist/components/QuantityStepper/QuantityStepper.styles.js +24 -0
  102. package/dist/components/QuantityStepper/QuantityStepper.types.d.ts +20 -0
  103. package/dist/components/QuantityStepper/QuantityStepper.types.d.ts.map +1 -0
  104. package/dist/components/QuantityStepper/index.d.ts +4 -0
  105. package/dist/components/QuantityStepper/index.d.ts.map +1 -0
  106. package/dist/components/RadioCard/RadioCard.d.ts +9 -0
  107. package/dist/components/RadioCard/RadioCard.d.ts.map +1 -0
  108. package/dist/components/RadioCard/RadioCard.js +40 -0
  109. package/dist/components/RadioCard/RadioCard.styles.d.ts +9 -0
  110. package/dist/components/RadioCard/RadioCard.styles.d.ts.map +1 -0
  111. package/dist/components/RadioCard/RadioCard.styles.js +24 -0
  112. package/dist/components/RadioCard/RadioCard.types.d.ts +28 -0
  113. package/dist/components/RadioCard/RadioCard.types.d.ts.map +1 -0
  114. package/dist/components/RadioCard/index.d.ts +4 -0
  115. package/dist/components/RadioCard/index.d.ts.map +1 -0
  116. package/dist/components/RangeSlider/RangeSlider.d.ts.map +1 -1
  117. package/dist/components/RangeSlider/RangeSlider.js +5 -3
  118. package/dist/components/RangeSlider/RangeSlider.types.d.ts +7 -0
  119. package/dist/components/RangeSlider/RangeSlider.types.d.ts.map +1 -1
  120. package/dist/components/Select/Select.d.ts.map +1 -1
  121. package/dist/components/Select/Select.js +14 -1
  122. package/dist/components/Select/Select.types.d.ts +4 -0
  123. package/dist/components/Select/Select.types.d.ts.map +1 -1
  124. package/dist/components/Skeleton/Skeleton.styles.d.ts +1 -1
  125. package/dist/components/Snackbar/Snackbar.d.ts +9 -0
  126. package/dist/components/Snackbar/Snackbar.d.ts.map +1 -0
  127. package/dist/components/Snackbar/Snackbar.js +108 -0
  128. package/dist/components/Snackbar/Snackbar.styles.d.ts +17 -0
  129. package/dist/components/Snackbar/Snackbar.styles.d.ts.map +1 -0
  130. package/dist/components/Snackbar/Snackbar.styles.js +37 -0
  131. package/dist/components/Snackbar/Snackbar.types.d.ts +36 -0
  132. package/dist/components/Snackbar/Snackbar.types.d.ts.map +1 -0
  133. package/dist/components/Snackbar/SnackbarHost.d.ts +4 -0
  134. package/dist/components/Snackbar/SnackbarHost.d.ts.map +1 -0
  135. package/dist/components/Snackbar/SnackbarHost.js +24 -0
  136. package/dist/components/Snackbar/index.d.ts +6 -0
  137. package/dist/components/Snackbar/index.d.ts.map +1 -0
  138. package/dist/components/Snackbar/snackbarStore.d.ts +42 -0
  139. package/dist/components/Snackbar/snackbarStore.d.ts.map +1 -0
  140. package/dist/components/Snackbar/snackbarStore.js +87 -0
  141. package/dist/components/StockMeter/StockMeter.d.ts +8 -0
  142. package/dist/components/StockMeter/StockMeter.d.ts.map +1 -0
  143. package/dist/components/StockMeter/StockMeter.js +19 -0
  144. package/dist/components/StockMeter/StockMeter.styles.d.ts +4 -0
  145. package/dist/components/StockMeter/StockMeter.styles.d.ts.map +1 -0
  146. package/dist/components/StockMeter/StockMeter.styles.js +7 -0
  147. package/dist/components/StockMeter/StockMeter.types.d.ts +10 -0
  148. package/dist/components/StockMeter/StockMeter.types.d.ts.map +1 -0
  149. package/dist/components/StockMeter/index.d.ts +4 -0
  150. package/dist/components/StockMeter/index.d.ts.map +1 -0
  151. package/dist/components/Swatch/Swatch.d.ts +11 -0
  152. package/dist/components/Swatch/Swatch.d.ts.map +1 -0
  153. package/dist/components/Swatch/Swatch.js +40 -0
  154. package/dist/components/Swatch/Swatch.styles.d.ts +8 -0
  155. package/dist/components/Swatch/Swatch.styles.d.ts.map +1 -0
  156. package/dist/components/Swatch/Swatch.styles.js +26 -0
  157. package/dist/components/Swatch/Swatch.types.d.ts +11 -0
  158. package/dist/components/Swatch/Swatch.types.d.ts.map +1 -0
  159. package/dist/components/Swatch/index.d.ts +4 -0
  160. package/dist/components/Swatch/index.d.ts.map +1 -0
  161. package/dist/components/Toast/Toast.d.ts.map +1 -1
  162. package/dist/components/Toast/Toast.js +49 -42
  163. package/dist/components/Toast/Toast.types.d.ts +7 -0
  164. package/dist/components/Toast/Toast.types.d.ts.map +1 -1
  165. package/dist/components/Toast/ToastContainer.d.ts.map +1 -1
  166. package/dist/components/Toast/ToastContainer.js +5 -0
  167. package/dist/components/Toast/toastStore.d.ts +11 -0
  168. package/dist/components/Toast/toastStore.d.ts.map +1 -1
  169. package/dist/components/Toast/toastStore.js +70 -30
  170. package/dist/index.d.ts +11 -0
  171. package/dist/index.d.ts.map +1 -1
  172. package/dist/index.js +26 -1
  173. package/dist/providers/TimmbrConfigProvider.d.ts.map +1 -1
  174. package/dist/providers/TimmbrConfigProvider.js +5 -9
  175. package/package.json +5 -5
@@ -0,0 +1,9 @@
1
+ import * as React from 'react';
2
+ import type { SnackbarProps } from './Snackbar.types';
3
+ /**
4
+ * One snackbar: message (and an optional second line), one inline action, a small close button.
5
+ * It leaves on its own after `duration` (paused while hovered, focused or touched), when swiped
6
+ * sideways or down, or when its action is used.
7
+ */
8
+ export declare const Snackbar: React.ForwardRefExoticComponent<SnackbarProps & React.RefAttributes<HTMLDivElement>>;
9
+ //# sourceMappingURL=Snackbar.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Snackbar.d.ts","sourceRoot":"","sources":["../../../src/components/Snackbar/Snackbar.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAS/B,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAatD;;;;GAIG;AACH,eAAO,MAAM,QAAQ,sFA+FpB,CAAC"}
@@ -0,0 +1,108 @@
1
+ "use client";
2
+ import { jsxs, jsx } from 'react/jsx-runtime';
3
+ import * as React from 'react';
4
+ import { AlertCircle, AlertTriangle, CheckCircle, Info, X } from '@timmbr/icons';
5
+ import { cn } from '@timmbr/utils';
6
+ import { snackbarIconVariants, snackbarActionVariants, snackbarCloseVariants, snackbarVariants } from './Snackbar.styles.js';
7
+
8
+ const ICONS = {
9
+ default: Info,
10
+ info: Info,
11
+ success: CheckCircle,
12
+ warning: AlertTriangle,
13
+ destructive: AlertCircle
14
+ };
15
+ const SWIPE_DISMISS_PX = 48;
16
+ const Snackbar = React.forwardRef(
17
+ ({ item, onDismiss, dismissLabel = "Dismiss", className, style, ...props }, ref) => {
18
+ const variant = item.variant ?? "default";
19
+ const Icon = ICONS[variant];
20
+ const duration = item.duration ?? (item.action ? 6e3 : 4e3);
21
+ const [paused, setPaused] = React.useState(false);
22
+ const remaining = React.useRef(duration);
23
+ React.useEffect(() => {
24
+ remaining.current = duration;
25
+ }, [item, duration]);
26
+ React.useEffect(() => {
27
+ if (!item.open || paused || duration === Infinity) return;
28
+ const started = Date.now();
29
+ const timer = setTimeout(onDismiss, remaining.current);
30
+ return () => {
31
+ clearTimeout(timer);
32
+ remaining.current -= Date.now() - started;
33
+ };
34
+ }, [item, paused, duration, onDismiss]);
35
+ const start = React.useRef(null);
36
+ const [drag, setDrag] = React.useState({ x: 0, y: 0 });
37
+ const onPointerDown = (event) => {
38
+ if (event.target.closest("button")) return;
39
+ start.current = { x: event.clientX, y: event.clientY };
40
+ event.currentTarget.setPointerCapture?.(event.pointerId);
41
+ setPaused(true);
42
+ };
43
+ const onPointerMove = (event) => {
44
+ if (!start.current) return;
45
+ setDrag({
46
+ x: event.clientX - start.current.x,
47
+ y: Math.max(0, event.clientY - start.current.y)
48
+ });
49
+ };
50
+ const onPointerEnd = () => {
51
+ if (!start.current) return;
52
+ start.current = null;
53
+ setPaused(false);
54
+ if (Math.abs(drag.x) > SWIPE_DISMISS_PX || drag.y > SWIPE_DISMISS_PX) onDismiss();
55
+ else setDrag({ x: 0, y: 0 });
56
+ };
57
+ const dragging = drag.x !== 0 || drag.y !== 0;
58
+ return /* @__PURE__ */ jsxs(
59
+ "div",
60
+ {
61
+ ref,
62
+ "data-slot": "snackbar",
63
+ "data-variant": variant,
64
+ "data-state": item.open ? "open" : "closed",
65
+ className: cn(snackbarVariants({ open: item.open }), dragging && "transition-none", className),
66
+ style: {
67
+ ...style,
68
+ ...dragging && {
69
+ transform: `translate(${drag.x}px, ${drag.y}px)`,
70
+ opacity: Math.max(0.3, 1 - Math.max(Math.abs(drag.x), drag.y) / 200)
71
+ }
72
+ },
73
+ onMouseEnter: () => setPaused(true),
74
+ onMouseLeave: () => setPaused(false),
75
+ onFocus: () => setPaused(true),
76
+ onBlur: () => setPaused(false),
77
+ onPointerDown,
78
+ onPointerMove,
79
+ onPointerUp: onPointerEnd,
80
+ onPointerCancel: onPointerEnd,
81
+ ...props,
82
+ children: [
83
+ /* @__PURE__ */ jsx(Icon, { "aria-hidden": "true", className: snackbarIconVariants({ variant }) }),
84
+ /* @__PURE__ */ jsxs("div", { className: "min-w-0 flex-1 py-1", children: [
85
+ /* @__PURE__ */ jsx("p", { className: "text-body-2 font-medium leading-snug", children: item.message }),
86
+ item.description && /* @__PURE__ */ jsx("p", { className: "mt-0.5 text-body-3 leading-snug text-grey-300", children: item.description })
87
+ ] }),
88
+ item.action && /* @__PURE__ */ jsx(
89
+ "button",
90
+ {
91
+ type: "button",
92
+ className: snackbarActionVariants(),
93
+ onClick: (event) => {
94
+ item.action?.onClick(event);
95
+ onDismiss();
96
+ },
97
+ children: item.action.label
98
+ }
99
+ ),
100
+ /* @__PURE__ */ jsx("button", { type: "button", "aria-label": dismissLabel, className: snackbarCloseVariants(), onClick: onDismiss, children: /* @__PURE__ */ jsx(X, { "aria-hidden": "true", className: "size-4" }) })
101
+ ]
102
+ }
103
+ );
104
+ }
105
+ );
106
+ Snackbar.displayName = "Snackbar";
107
+
108
+ export { Snackbar };
@@ -0,0 +1,17 @@
1
+ /**
2
+ * Bottom of the screen, above anything pinned there (pages set --toast-offset-bottom to a bar's
3
+ * height) and the home indicator. Full width minus margins on phones; a compact bar centred on
4
+ * wider screens.
5
+ */
6
+ export declare const snackbarHostVariants: (props?: import("class-variance-authority/types").ClassProp | undefined) => string;
7
+ /** Inverse surface (dark bar, light text), as on Android and most shopping apps. */
8
+ export declare const snackbarVariants: (props?: ({
9
+ open?: boolean | null | undefined;
10
+ } & import("class-variance-authority/types").ClassProp) | undefined) => string;
11
+ export declare const snackbarIconVariants: (props?: ({
12
+ variant?: "default" | "destructive" | "success" | "warning" | "info" | null | undefined;
13
+ } & import("class-variance-authority/types").ClassProp) | undefined) => string;
14
+ /** Text action: light primary on the dark bar (high contrast), no button chrome. */
15
+ export declare const snackbarActionVariants: (props?: import("class-variance-authority/types").ClassProp | undefined) => string;
16
+ export declare const snackbarCloseVariants: (props?: import("class-variance-authority/types").ClassProp | undefined) => string;
17
+ //# sourceMappingURL=Snackbar.styles.d.ts.map
@@ -0,0 +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;;8EAW5B,CAAC;AAEF,eAAO,MAAM,oBAAoB;;8EAW/B,CAAC;AAEH,oFAAoF;AACpF,eAAO,MAAM,sBAAsB,oFAElC,CAAC;AAEF,eAAO,MAAM,qBAAqB,oFAEjC,CAAC"}
@@ -0,0 +1,37 @@
1
+ import { cva } from 'class-variance-authority';
2
+
3
+ const snackbarHostVariants = cva(
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
+ );
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] motion-safe:transition-[transform,opacity] motion-safe:duration-200",
8
+ {
9
+ variants: {
10
+ open: {
11
+ true: "translate-y-0 opacity-100",
12
+ false: "translate-y-2 opacity-0"
13
+ }
14
+ },
15
+ defaultVariants: { open: true }
16
+ }
17
+ );
18
+ const snackbarIconVariants = cva("size-5 shrink-0", {
19
+ variants: {
20
+ variant: {
21
+ default: "hidden",
22
+ info: "text-grey-300",
23
+ success: "text-success",
24
+ warning: "text-warning",
25
+ destructive: "text-destructive"
26
+ }
27
+ },
28
+ defaultVariants: { variant: "default" }
29
+ });
30
+ 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"
32
+ );
33
+ 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"
35
+ );
36
+
37
+ export { snackbarActionVariants, snackbarCloseVariants, snackbarHostVariants, snackbarIconVariants, snackbarVariants };
@@ -0,0 +1,36 @@
1
+ import type * as React from 'react';
2
+ export type SnackbarVariant = 'default' | 'success' | 'info' | 'warning' | 'destructive';
3
+ export interface SnackbarAction {
4
+ label: React.ReactNode;
5
+ onClick: (event: React.MouseEvent<HTMLButtonElement>) => void;
6
+ }
7
+ export interface SnackbarOptions {
8
+ /** Re-showing the same id replaces it instead of queueing another. */
9
+ id?: string;
10
+ /** Second line, smaller (keep it short: snackbars are glanceable). */
11
+ description?: React.ReactNode;
12
+ variant?: SnackbarVariant;
13
+ /** One inline action, e.g. "View cart". Tapping it also dismisses the snackbar. */
14
+ action?: SnackbarAction;
15
+ /** Milliseconds on screen. Defaults to 4000, or 6000 with an action (time to reach it). */
16
+ duration?: number;
17
+ onDismiss?: () => void;
18
+ }
19
+ export interface SnackbarItem extends SnackbarOptions {
20
+ id: string;
21
+ message: React.ReactNode;
22
+ /** False while it animates out. */
23
+ open: boolean;
24
+ }
25
+ export interface SnackbarProps extends Omit<React.HTMLAttributes<HTMLDivElement>, 'children'> {
26
+ item: SnackbarItem;
27
+ onDismiss: () => void;
28
+ /** Labels for assistive tech. */
29
+ dismissLabel?: string;
30
+ }
31
+ export interface SnackbarHostProps {
32
+ /** Accessible name of the dismiss control (snackbars can be swiped away too). */
33
+ dismissLabel?: string;
34
+ className?: string;
35
+ }
36
+ //# sourceMappingURL=Snackbar.types.d.ts.map
@@ -0,0 +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;CACvB;AAED,MAAM,WAAW,iBAAiB;IAChC,iFAAiF;IACjF,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB"}
@@ -0,0 +1,4 @@
1
+ import * as React from 'react';
2
+ import type { SnackbarHostProps } from './Snackbar.types';
3
+ export declare function SnackbarHost({ dismissLabel, className }: SnackbarHostProps): React.JSX.Element;
4
+ //# sourceMappingURL=SnackbarHost.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SnackbarHost.d.ts","sourceRoot":"","sources":["../../../src/components/Snackbar/SnackbarHost.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAK/B,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAS1D,wBAAgB,YAAY,CAAC,EAAE,YAAY,EAAE,SAAS,EAAE,EAAE,iBAAiB,qBAsB1E"}
@@ -0,0 +1,24 @@
1
+ "use client";
2
+ import { jsx, jsxs } from 'react/jsx-runtime';
3
+ import * as React from 'react';
4
+ import { cn } from '@timmbr/utils';
5
+ import { Snackbar } from './Snackbar.js';
6
+ import { snackbarHostVariants } from './Snackbar.styles.js';
7
+ import { snackbarStore } from './snackbarStore.js';
8
+
9
+ const useIsomorphicLayoutEffect = typeof window === "undefined" ? React.useEffect : React.useLayoutEffect;
10
+ function SnackbarHost({ dismissLabel, className }) {
11
+ const current = React.useSyncExternalStore(snackbarStore.subscribe, snackbarStore.getCurrent, () => null);
12
+ useIsomorphicLayoutEffect(() => snackbarStore.registerHost(), []);
13
+ const urgent = current?.variant === "destructive";
14
+ const dismiss = React.useCallback(() => {
15
+ if (current) snackbarStore.dismiss(current.id);
16
+ }, [current]);
17
+ const content = current && /* @__PURE__ */ jsx(Snackbar, { item: current, onDismiss: dismiss, dismissLabel }, current.id);
18
+ return /* @__PURE__ */ jsxs("div", { className: cn(snackbarHostVariants(), className), "data-slot": "snackbar-host", children: [
19
+ /* @__PURE__ */ jsx("div", { role: "status", "aria-live": "polite", "aria-atomic": "true", className: "contents", children: !urgent && content }),
20
+ /* @__PURE__ */ jsx("div", { role: "alert", "aria-live": "assertive", "aria-atomic": "true", className: "contents", children: urgent && content })
21
+ ] });
22
+ }
23
+
24
+ export { SnackbarHost };
@@ -0,0 +1,6 @@
1
+ export * from './Snackbar';
2
+ export * from './SnackbarHost';
3
+ export * from './snackbarStore';
4
+ export * from './Snackbar.types';
5
+ export * from './Snackbar.styles';
6
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/Snackbar/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAC;AAC3B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,iBAAiB,CAAC;AAChC,cAAc,kBAAkB,CAAC;AACjC,cAAc,mBAAmB,CAAC"}
@@ -0,0 +1,42 @@
1
+ import type * as React from 'react';
2
+ import type { SnackbarItem, SnackbarOptions } from './Snackbar.types';
3
+ /** How long the closing animation runs before the next snackbar shows. */
4
+ export declare const SNACKBAR_EXIT_MS = 180;
5
+ type Listener = () => void;
6
+ /**
7
+ * One snackbar at a time (the mobile pattern): showing a new one closes the current one first;
8
+ * extra ones wait their turn. Re-showing an id that's on screen or queued updates it in place.
9
+ */
10
+ declare class SnackbarStore {
11
+ private current;
12
+ private queue;
13
+ private listeners;
14
+ private exitTimer;
15
+ private hosts;
16
+ /** SnackbarHost registers while mounted; toast() only routes to snackbars when one is. */
17
+ registerHost: () => () => void;
18
+ hasHost: () => boolean;
19
+ subscribe: (listener: Listener) => () => void;
20
+ getCurrent: () => SnackbarItem | null;
21
+ private notify;
22
+ show(message: React.ReactNode, options?: SnackbarOptions): string;
23
+ dismiss(id?: string): void;
24
+ private close;
25
+ private next;
26
+ /** Test helper. */
27
+ reset(): void;
28
+ }
29
+ export declare const snackbarStore: SnackbarStore;
30
+ type VariantShortcut = (message: React.ReactNode, options?: Omit<SnackbarOptions, 'variant'>) => string;
31
+ export interface SnackbarFunction {
32
+ (message: React.ReactNode, options?: SnackbarOptions): string;
33
+ success: VariantShortcut;
34
+ info: VariantShortcut;
35
+ warning: VariantShortcut;
36
+ error: VariantShortcut;
37
+ dismiss: (id?: string) => void;
38
+ }
39
+ /** Shows a snackbar: `snackbar('Saved')`, `snackbar.success('Added to cart', { action })`. */
40
+ export declare const snackbar: SnackbarFunction;
41
+ export {};
42
+ //# sourceMappingURL=snackbarStore.d.ts.map
@@ -0,0 +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;;;GAGG;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"}
@@ -0,0 +1,87 @@
1
+ "use client";
2
+ const SNACKBAR_EXIT_MS = 180;
3
+ class SnackbarStore {
4
+ current = null;
5
+ queue = [];
6
+ listeners = /* @__PURE__ */ new Set();
7
+ exitTimer;
8
+ hosts = 0;
9
+ /** SnackbarHost registers while mounted; toast() only routes to snackbars when one is. */
10
+ registerHost = () => {
11
+ this.hosts += 1;
12
+ return () => {
13
+ this.hosts -= 1;
14
+ };
15
+ };
16
+ hasHost = () => this.hosts > 0;
17
+ subscribe = (listener) => {
18
+ this.listeners.add(listener);
19
+ return () => {
20
+ this.listeners.delete(listener);
21
+ };
22
+ };
23
+ getCurrent = () => this.current;
24
+ notify() {
25
+ this.listeners.forEach((listener) => listener());
26
+ }
27
+ show(message, options = {}) {
28
+ const id = options.id ?? Math.random().toString(36).slice(2, 9);
29
+ const item = { ...options, id, message, open: true };
30
+ if (this.current?.id === id && this.current.open) {
31
+ this.current = item;
32
+ this.notify();
33
+ return id;
34
+ }
35
+ const queued = this.queue.findIndex((q) => q.id === id);
36
+ if (queued >= 0) {
37
+ this.queue[queued] = item;
38
+ return id;
39
+ }
40
+ this.queue.unshift(item);
41
+ if (this.current?.open) this.close();
42
+ else if (!this.current) this.next();
43
+ return id;
44
+ }
45
+ dismiss(id) {
46
+ if (!id) this.queue = [];
47
+ if (this.current && (!id || this.current.id === id)) this.close();
48
+ else if (id) this.queue = this.queue.filter((q) => q.id !== id);
49
+ }
50
+ close() {
51
+ if (!this.current || !this.current.open) return;
52
+ const closing = this.current;
53
+ this.current = { ...closing, open: false };
54
+ this.notify();
55
+ closing.onDismiss?.();
56
+ clearTimeout(this.exitTimer);
57
+ this.exitTimer = setTimeout(() => {
58
+ this.current = null;
59
+ this.next();
60
+ }, SNACKBAR_EXIT_MS);
61
+ }
62
+ next() {
63
+ this.current = this.queue.shift() ?? null;
64
+ this.notify();
65
+ }
66
+ /** Test helper. */
67
+ reset() {
68
+ clearTimeout(this.exitTimer);
69
+ this.current = null;
70
+ this.queue = [];
71
+ this.notify();
72
+ }
73
+ }
74
+ const snackbarStore = new SnackbarStore();
75
+ const withVariant = (variant) => (message, options) => snackbarStore.show(message, { ...options, variant });
76
+ const snackbar = Object.assign(
77
+ (message, options) => snackbarStore.show(message, options),
78
+ {
79
+ success: withVariant("success"),
80
+ info: withVariant("info"),
81
+ warning: withVariant("warning"),
82
+ error: withVariant("destructive"),
83
+ dismiss: (id) => snackbarStore.dismiss(id)
84
+ }
85
+ );
86
+
87
+ export { SNACKBAR_EXIT_MS, snackbar, snackbarStore };
@@ -0,0 +1,8 @@
1
+ import * as React from 'react';
2
+ import type { StockMeterProps } from './StockMeter.types';
3
+ /**
4
+ * "Only 3 left" urgency line with a short bar. Renders nothing above `threshold` or when sold
5
+ * out (urgency only helps while it's true and the item can still be bought).
6
+ */
7
+ export declare const StockMeter: React.ForwardRefExoticComponent<StockMeterProps & React.RefAttributes<HTMLDivElement>>;
8
+ //# sourceMappingURL=StockMeter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"StockMeter.d.ts","sourceRoot":"","sources":["../../../src/components/StockMeter/StockMeter.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAG/B,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAE1D;;;GAGG;AACH,eAAO,MAAM,UAAU,wFAetB,CAAC"}
@@ -0,0 +1,19 @@
1
+ import { jsxs, jsx } from 'react/jsx-runtime';
2
+ import * as React from 'react';
3
+ import { cn } from '@timmbr/utils';
4
+ import { stockMeterFillVariants, stockMeterTrackVariants, stockMeterVariants } from './StockMeter.styles.js';
5
+
6
+ const StockMeter = React.forwardRef(
7
+ ({ available, threshold = 5, label, className, ...props }, ref) => {
8
+ if (available <= 0 || available > threshold) return null;
9
+ const text = label ? label(available) : `Hurry! Only ${available} left in stock`;
10
+ const fill = Math.max(8, Math.round(available / (threshold * 2) * 100));
11
+ return /* @__PURE__ */ jsxs("div", { ref, "data-slot": "stock-meter", className: cn(stockMeterVariants(), className), ...props, children: [
12
+ /* @__PURE__ */ jsx("p", { className: "text-body-2 font-semibold text-primary", children: text }),
13
+ /* @__PURE__ */ jsx("div", { className: stockMeterTrackVariants(), "aria-hidden": "true", children: /* @__PURE__ */ jsx("div", { className: stockMeterFillVariants(), style: { width: `${fill}%` } }) })
14
+ ] });
15
+ }
16
+ );
17
+ StockMeter.displayName = "StockMeter";
18
+
19
+ export { StockMeter };
@@ -0,0 +1,4 @@
1
+ export declare const stockMeterVariants: (props?: import("class-variance-authority/types").ClassProp | undefined) => string;
2
+ export declare const stockMeterTrackVariants: (props?: import("class-variance-authority/types").ClassProp | undefined) => string;
3
+ export declare const stockMeterFillVariants: (props?: import("class-variance-authority/types").ClassProp | undefined) => string;
4
+ //# sourceMappingURL=StockMeter.styles.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"StockMeter.styles.d.ts","sourceRoot":"","sources":["../../../src/components/StockMeter/StockMeter.styles.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,kBAAkB,oFAAuC,CAAC;AAEvE,eAAO,MAAM,uBAAuB,oFAA6D,CAAC;AAElG,eAAO,MAAM,sBAAsB,oFAAwE,CAAC"}
@@ -0,0 +1,7 @@
1
+ import { cva } from 'class-variance-authority';
2
+
3
+ const stockMeterVariants = cva("flex flex-col gap-2 font-sans");
4
+ const stockMeterTrackVariants = cva("h-1 w-full overflow-hidden rounded-full bg-grey-200");
5
+ const stockMeterFillVariants = cva("h-full rounded-full bg-primary transition-[width] duration-300");
6
+
7
+ export { stockMeterFillVariants, stockMeterTrackVariants, stockMeterVariants };
@@ -0,0 +1,10 @@
1
+ import type * as React from 'react';
2
+ export interface StockMeterProps extends React.HTMLAttributes<HTMLDivElement> {
3
+ /** Units that can still be bought. */
4
+ available: number;
5
+ /** Shows at or below this many units. Defaults to 5. */
6
+ threshold?: number;
7
+ /** Message for a count; defaults to "Hurry! Only N left in stock". */
8
+ label?: (available: number) => string;
9
+ }
10
+ //# sourceMappingURL=StockMeter.types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"StockMeter.types.d.ts","sourceRoot":"","sources":["../../../src/components/StockMeter/StockMeter.types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,KAAK,MAAM,OAAO,CAAC;AAEpC,MAAM,WAAW,eAAgB,SAAQ,KAAK,CAAC,cAAc,CAAC,cAAc,CAAC;IAC3E,sCAAsC;IACtC,SAAS,EAAE,MAAM,CAAC;IAClB,wDAAwD;IACxD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,sEAAsE;IACtE,KAAK,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,MAAM,CAAC;CACvC"}
@@ -0,0 +1,4 @@
1
+ export * from './StockMeter';
2
+ export * from './StockMeter.types';
3
+ export * from './StockMeter.styles';
4
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/StockMeter/index.ts"],"names":[],"mappings":"AAAA,cAAc,cAAc,CAAC;AAC7B,cAAc,oBAAoB,CAAC;AACnC,cAAc,qBAAqB,CAAC"}
@@ -0,0 +1,11 @@
1
+ import * as React from 'react';
2
+ import type { SwatchProps } from './Swatch.types';
3
+ /** Relative luminance of a #RRGGBB colour (0 dark … 1 light); null when not a hex colour. */
4
+ export declare function swatchLuminance(color: string): number | null;
5
+ /**
6
+ * A colour dot (finish, fabric, colour options). The colour comes from data, so it's passed as a
7
+ * CSS variable rather than a class. Light colours get a border so they stay visible on white.
8
+ * Decorative by default; pass `label` when the swatch is the only way the colour is named.
9
+ */
10
+ export declare const Swatch: React.ForwardRefExoticComponent<SwatchProps & React.RefAttributes<HTMLSpanElement>>;
11
+ //# sourceMappingURL=Swatch.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Swatch.d.ts","sourceRoot":"","sources":["../../../src/components/Swatch/Swatch.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAG/B,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAElD,6FAA6F;AAC7F,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAS5D;AAED;;;;GAIG;AACH,eAAO,MAAM,MAAM,qFAoBlB,CAAC"}
@@ -0,0 +1,40 @@
1
+ import { jsx } from 'react/jsx-runtime';
2
+ import * as React from 'react';
3
+ import { cn } from '@timmbr/utils';
4
+ import { swatchVariants } from './Swatch.styles.js';
5
+
6
+ function swatchLuminance(color) {
7
+ const match = /^#?([0-9a-f]{6})$/i.exec(color.trim());
8
+ if (!match) return null;
9
+ const n = parseInt(match[1], 16);
10
+ const [r, g, b] = [n >> 16 & 255, n >> 8 & 255, n & 255].map((c) => {
11
+ const s = c / 255;
12
+ return s <= 0.03928 ? s / 12.92 : ((s + 0.055) / 1.055) ** 2.4;
13
+ });
14
+ return 0.2126 * r + 0.7152 * g + 0.0722 * b;
15
+ }
16
+ const Swatch = React.forwardRef(
17
+ ({ color, size, selected, label, className, style, ...props }, ref) => {
18
+ const luminance = swatchLuminance(color);
19
+ return /* @__PURE__ */ jsx(
20
+ "span",
21
+ {
22
+ ref,
23
+ "data-slot": "swatch",
24
+ "data-selected": selected ? "" : void 0,
25
+ role: label ? "img" : void 0,
26
+ "aria-label": label,
27
+ "aria-hidden": label ? void 0 : true,
28
+ className: cn(
29
+ swatchVariants({ size, selected: !!selected, light: luminance !== null && luminance > 0.8 }),
30
+ className
31
+ ),
32
+ style: { ...style, ["--swatch"]: color },
33
+ ...props
34
+ }
35
+ );
36
+ }
37
+ );
38
+ Swatch.displayName = "Swatch";
39
+
40
+ export { Swatch, swatchLuminance };
@@ -0,0 +1,8 @@
1
+ import { type VariantProps } from 'class-variance-authority';
2
+ export declare const swatchVariants: (props?: ({
3
+ size?: "sm" | "md" | "lg" | null | undefined;
4
+ selected?: boolean | null | undefined;
5
+ light?: boolean | null | undefined;
6
+ } & import("class-variance-authority/types").ClassProp) | undefined) => string;
7
+ export type SwatchVariants = VariantProps<typeof swatchVariants>;
8
+ //# sourceMappingURL=Swatch.styles.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Swatch.styles.d.ts","sourceRoot":"","sources":["../../../src/components/Swatch/Swatch.styles.ts"],"names":[],"mappings":"AAAA,OAAO,EAAO,KAAK,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAElE,eAAO,MAAM,cAAc;;;;8EAqB1B,CAAC;AAEF,MAAM,MAAM,cAAc,GAAG,YAAY,CAAC,OAAO,cAAc,CAAC,CAAC"}
@@ -0,0 +1,26 @@
1
+ import { cva } from 'class-variance-authority';
2
+
3
+ const swatchVariants = cva(
4
+ "inline-block shrink-0 rounded-full bg-[var(--swatch)] ring-offset-2 ring-offset-grey-50 transition-shadow",
5
+ {
6
+ variants: {
7
+ size: {
8
+ sm: "size-4",
9
+ md: "size-5",
10
+ lg: "size-7"
11
+ },
12
+ selected: {
13
+ true: "ring-2 ring-primary",
14
+ false: ""
15
+ },
16
+ /** Very light colours need an edge to show on white. */
17
+ light: {
18
+ true: "border border-grey-300",
19
+ false: ""
20
+ }
21
+ },
22
+ defaultVariants: { size: "md", selected: false, light: false }
23
+ }
24
+ );
25
+
26
+ export { swatchVariants };
@@ -0,0 +1,11 @@
1
+ import type * as React from 'react';
2
+ export interface SwatchProps extends Omit<React.HTMLAttributes<HTMLSpanElement>, 'color'> {
3
+ /** Any CSS colour; hex (#RRGGBB) also gets a border when very light. */
4
+ color: string;
5
+ size?: 'sm' | 'md' | 'lg';
6
+ /** Ring around the dot. */
7
+ selected?: boolean;
8
+ /** Accessible name; omit when a visible label sits next to the swatch. */
9
+ label?: string;
10
+ }
11
+ //# sourceMappingURL=Swatch.types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Swatch.types.d.ts","sourceRoot":"","sources":["../../../src/components/Swatch/Swatch.types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,KAAK,MAAM,OAAO,CAAC;AAEpC,MAAM,WAAW,WAAY,SAAQ,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,eAAe,CAAC,EAAE,OAAO,CAAC;IACvF,wEAAwE;IACxE,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC;IAC1B,2BAA2B;IAC3B,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,0EAA0E;IAC1E,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB"}
@@ -0,0 +1,4 @@
1
+ export * from './Swatch';
2
+ export * from './Swatch.types';
3
+ export * from './Swatch.styles';
4
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/Swatch/index.ts"],"names":[],"mappings":"AAAA,cAAc,UAAU,CAAC;AACzB,cAAc,gBAAgB,CAAC;AAC/B,cAAc,iBAAiB,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"Toast.d.ts","sourceRoot":"","sources":["../../../src/components/Toast/Toast.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,KAAK,cAAc,MAAM,uBAAuB,CAAC;AAMxD,OAAO,KAAK,EAAiB,UAAU,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AAEnF,eAAO,MAAM,aAAa,6CAA0B,CAAC;AAWrD,eAAO,MAAM,aAAa,6FAexB,CAAC;AAGH,eAAO,MAAM,KAAK,kFAuChB,CAAC;AAGH,eAAO,MAAM,WAAW,iKAatB,CAAC;AAGH,eAAO,MAAM,UAAU,gKAgBrB,CAAC;AAGH,eAAO,MAAM,UAAU,0JAUrB,CAAC;AAGH,eAAO,MAAM,gBAAgB,gKAU3B,CAAC"}
1
+ {"version":3,"file":"Toast.d.ts","sourceRoot":"","sources":["../../../src/components/Toast/Toast.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,KAAK,cAAc,MAAM,uBAAuB,CAAC;AAMxD,OAAO,KAAK,EAAiB,UAAU,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AAEnF,eAAO,MAAM,aAAa,6CAA0B,CAAC;AAerD,eAAO,MAAM,aAAa,6FAgBzB,CAAC;AAGF,eAAO,MAAM,KAAK,kFAsCjB,CAAC;AAGF,eAAO,MAAM,WAAW,iKAatB,CAAC;AAGH,eAAO,MAAM,UAAU,gKAgBrB,CAAC;AAGH,eAAO,MAAM,UAAU,0JAUrB,CAAC;AAGH,eAAO,MAAM,gBAAgB,gKAU3B,CAAC"}