@timmbr/ui 1.11.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.
Files changed (61) hide show
  1. package/dist/components/Accordion/Accordion.d.ts.map +1 -1
  2. package/dist/components/Accordion/Accordion.js +23 -12
  3. package/dist/components/AuthModal/AuthModal.styles.js +1 -1
  4. package/dist/components/AuthModal/subcomponents/AuthModalParts.d.ts +1 -1
  5. package/dist/components/AuthModal/subcomponents/AuthModalParts.d.ts.map +1 -1
  6. package/dist/components/AuthModal/subcomponents/AuthModalParts.js +24 -42
  7. package/dist/components/Button/Button.d.ts.map +1 -1
  8. package/dist/components/Button/Button.js +1 -0
  9. package/dist/components/Checkbox/Checkbox.d.ts.map +1 -1
  10. package/dist/components/Checkbox/Checkbox.js +10 -1
  11. package/dist/components/Checkbox/Checkbox.styles.js +1 -1
  12. package/dist/components/Checkbox/Checkbox.types.d.ts +3 -0
  13. package/dist/components/Checkbox/Checkbox.types.d.ts.map +1 -1
  14. package/dist/components/Chip/Chip.js +1 -1
  15. package/dist/components/Dialog/Dialog.js +1 -1
  16. package/dist/components/Drawer/Drawer.js +1 -1
  17. package/dist/components/FilterChips/FilterChips.d.ts.map +1 -1
  18. package/dist/components/FilterChips/FilterChips.js +2 -9
  19. package/dist/components/FilterPanel/FilterPanel.d.ts.map +1 -1
  20. package/dist/components/FilterPanel/FilterPanel.js +9 -7
  21. package/dist/components/ImageUpload/subcomponents/ImageUploadThumbnailCard.js +1 -1
  22. package/dist/components/Input/Input.d.ts.map +1 -1
  23. package/dist/components/Input/Input.js +2 -1
  24. package/dist/components/NavFooter/NavFooter.styles.js +1 -1
  25. package/dist/components/NavFooter/subcomponents/FooterBrand.js +1 -1
  26. package/dist/components/NavHeader/NavHeader.js +1 -1
  27. package/dist/components/NavHeader/NavHeader.styles.js +4 -4
  28. package/dist/components/PageProgress/PageProgress.d.ts +12 -0
  29. package/dist/components/PageProgress/PageProgress.d.ts.map +1 -0
  30. package/dist/components/PageProgress/PageProgress.js +68 -0
  31. package/dist/components/PageProgress/PageProgress.styles.d.ts +8 -0
  32. package/dist/components/PageProgress/PageProgress.styles.d.ts.map +1 -0
  33. package/dist/components/PageProgress/PageProgress.styles.js +32 -0
  34. package/dist/components/PageProgress/PageProgress.types.d.ts +18 -0
  35. package/dist/components/PageProgress/PageProgress.types.d.ts.map +1 -0
  36. package/dist/components/PageProgress/index.d.ts +3 -0
  37. package/dist/components/PageProgress/index.d.ts.map +1 -0
  38. package/dist/components/Snackbar/Snackbar.d.ts.map +1 -1
  39. package/dist/components/Snackbar/Snackbar.js +6 -2
  40. package/dist/components/Snackbar/Snackbar.styles.d.ts +1 -0
  41. package/dist/components/Snackbar/Snackbar.styles.d.ts.map +1 -1
  42. package/dist/components/Snackbar/Snackbar.styles.js +8 -4
  43. package/dist/components/Snackbar/Snackbar.types.d.ts +3 -0
  44. package/dist/components/Snackbar/Snackbar.types.d.ts.map +1 -1
  45. package/dist/components/Snackbar/snackbarStore.d.ts +3 -0
  46. package/dist/components/Snackbar/snackbarStore.d.ts.map +1 -1
  47. package/dist/components/Switch/Switch.d.ts.map +1 -1
  48. package/dist/components/Switch/Switch.js +19 -2
  49. package/dist/components/Switch/Switch.styles.js +2 -2
  50. package/dist/components/Switch/Switch.types.d.ts +3 -0
  51. package/dist/components/Switch/Switch.types.d.ts.map +1 -1
  52. package/dist/components/Toast/Toast.js +2 -2
  53. package/dist/components/Toast/toastStore.d.ts +4 -0
  54. package/dist/components/Toast/toastStore.d.ts.map +1 -1
  55. package/dist/index.d.ts +1 -0
  56. package/dist/index.d.ts.map +1 -1
  57. package/dist/index.js +1 -0
  58. package/dist/providers/AnimationProvider.d.ts +5 -1
  59. package/dist/providers/AnimationProvider.d.ts.map +1 -1
  60. package/dist/providers/AnimationProvider.js +6 -3
  61. package/package.json +4 -4
@@ -1 +1 @@
1
- {"version":3,"file":"Accordion.d.ts","sourceRoot":"","sources":["../../../src/components/Accordion/Accordion.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,KAAK,kBAAkB,MAAM,2BAA2B,CAAC;AAShE,OAAO,KAAK,EAGV,qBAAqB,EACtB,MAAM,mBAAmB,CAAC;AAE3B,eAAO,MAAM,SAAS,8JAA0B,CAAC;AAEjD,eAAO,MAAM,aAAa,iKASxB,CAAC;AAGH,eAAO,MAAM,gBAAgB,0KAc3B,CAAC;AAGH,eAAO,MAAM,gBAAgB,8FAoB3B,CAAC"}
1
+ {"version":3,"file":"Accordion.d.ts","sourceRoot":"","sources":["../../../src/components/Accordion/Accordion.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,KAAK,kBAAkB,MAAM,2BAA2B,CAAC;AAShE,OAAO,KAAK,EAGV,qBAAqB,EACtB,MAAM,mBAAmB,CAAC;AAE3B,eAAO,MAAM,SAAS,8JAA0B,CAAC;AAEjD,eAAO,MAAM,aAAa,iKASxB,CAAC;AAGH,eAAO,MAAM,gBAAgB,0KAsB3B,CAAC;AAGH,eAAO,MAAM,gBAAgB,8FAoB3B,CAAC"}
@@ -17,18 +17,29 @@ const AccordionItem = React.forwardRef(({ className, ...props }, ref) => /* @__P
17
17
  }
18
18
  ));
19
19
  AccordionItem.displayName = "AccordionItem";
20
- const AccordionTrigger = React.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ jsx(AccordionPrimitive.Header, { className: "flex", children: /* @__PURE__ */ jsxs(
21
- AccordionPrimitive.Trigger,
22
- {
23
- ref,
24
- className: cn(accordionTriggerVariants(), className),
25
- ...props,
26
- children: [
27
- children,
28
- /* @__PURE__ */ jsx(ChevronDown, { className: "h-4 w-4 shrink-0 text-grey-500 transition-transform duration-200" })
29
- ]
30
- }
31
- ) }));
20
+ const AccordionTrigger = React.forwardRef(({ className, children, ...props }, ref) => {
21
+ const globalMotion = useGlobalAnimation();
22
+ return /* @__PURE__ */ jsx(AccordionPrimitive.Header, { className: "flex", children: /* @__PURE__ */ jsxs(
23
+ AccordionPrimitive.Trigger,
24
+ {
25
+ ref,
26
+ className: cn(accordionTriggerVariants(), className),
27
+ ...props,
28
+ children: [
29
+ children,
30
+ /* @__PURE__ */ jsx(
31
+ ChevronDown,
32
+ {
33
+ className: cn(
34
+ "h-4 w-4 shrink-0 text-grey-500",
35
+ globalMotion ? "transition-transform duration-200" : "transition-none"
36
+ )
37
+ }
38
+ )
39
+ ]
40
+ }
41
+ ) });
42
+ });
32
43
  AccordionTrigger.displayName = AccordionPrimitive.Trigger.displayName;
33
44
  const AccordionContent = React.forwardRef(({ className, children, motion = true, ...props }, ref) => {
34
45
  const globalMotion = useGlobalAnimation();
@@ -1,7 +1,7 @@
1
1
  import { cva } from 'class-variance-authority';
2
2
 
3
3
  const authModalContainerVariants = cva(
4
- "relative flex w-full max-w-[675px] bg-grey-50 overflow-hidden rounded-sm shadow-[0px_12px_24px_-4px_rgba(0,0,0,0.15)] flex-col sm:flex-row sm:min-h-[454px] max-h-[calc(100dvh-24px)] sm:max-h-[calc(100dvh-32px)]"
4
+ "relative flex w-full max-w-[675px] bg-grey-50 overflow-hidden rounded-sm shadow-2xl flex-col sm:flex-row sm:min-h-[454px] max-h-[calc(100dvh-24px)] sm:max-h-[calc(100dvh-32px)]"
5
5
  );
6
6
  const authModalBannerVariants = cva(
7
7
  "relative hidden sm:flex shrink-0 w-[320px] flex-col justify-between p-8 overflow-hidden select-none"
@@ -32,7 +32,7 @@ export declare function AuthDestination({ value, onEdit, disabled, }: {
32
32
  onEdit?: () => void;
33
33
  disabled?: boolean;
34
34
  }): React.JSX.Element;
35
- type PasswordFieldProps = Omit<React.InputHTMLAttributes<HTMLInputElement>, 'onChange' | 'type'> & {
35
+ type PasswordFieldProps = Omit<React.InputHTMLAttributes<HTMLInputElement>, 'onChange' | 'type' | 'size'> & {
36
36
  id: string;
37
37
  label: string;
38
38
  onValueChange?: (value: string) => void;
@@ -1 +1 @@
1
- {"version":3,"file":"AuthModalParts.d.ts","sourceRoot":"","sources":["../../../../src/components/AuthModal/subcomponents/AuthModalParts.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAe/B,yEAAyE;AACzE,wBAAgB,QAAQ,CAAC,EACvB,QAAQ,EACR,SAAS,EACT,QAAQ,GACT,EAAE;IACD,QAAQ,CAAC,EAAE,CAAC,CAAC,EAAE,KAAK,CAAC,SAAS,KAAK,IAAI,CAAC;IACxC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;CAC3B,qBAaA;AAED,yFAAyF;AACzF,wBAAgB,cAAc,CAAC,EAC7B,KAAK,EACL,QAAQ,EACR,YAAoB,GACrB,EAAE;IACD,KAAK,EAAE,KAAK,CAAC,SAAS,CAAC;IACvB,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC3B,YAAY,CAAC,EAAE,OAAO,CAAC;CACxB,qBAcA;AAED,wBAAgB,cAAc,CAAC,EAAE,EAAE,EAAE,QAAQ,EAAE,EAAE;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAA;CAAE,4BAO1F;AAED,wBAAgB,gBAAgB,CAAC,EAC/B,SAAS,EACT,QAAQ,EACR,QAAQ,GACT,EAAE;IACD,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;CAC3B,qBAmBA;AAED,wBAAgB,YAAY,CAAC,EAC3B,OAAO,EACP,QAAQ,EACR,SAAS,EACT,QAAQ,GACT,EAAE;IACD,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;CAC3B,qBAWA;AAED,mFAAmF;AACnF,wBAAgB,eAAe,CAAC,EAC9B,KAAK,EACL,MAAM,EACN,QAAQ,GACT,EAAE;IACD,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,IAAI,CAAC;IACpB,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB,qBAYA;AAED,KAAK,kBAAkB,GAAG,IAAI,CAAC,KAAK,CAAC,mBAAmB,CAAC,gBAAgB,CAAC,EAAE,UAAU,GAAG,MAAM,CAAC,GAAG;IACjG,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACxC,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB,CAAC;AAEF,wBAAgB,iBAAiB,CAAC,EAChC,EAAE,EACF,KAAK,EACL,aAAa,EACb,OAAO,EACP,WAAW,EACX,SAAS,EACT,GAAG,UAAU,EACd,EAAE,kBAAkB,qBA+BpB"}
1
+ {"version":3,"file":"AuthModalParts.d.ts","sourceRoot":"","sources":["../../../../src/components/AuthModal/subcomponents/AuthModalParts.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAa/B,yEAAyE;AACzE,wBAAgB,QAAQ,CAAC,EACvB,QAAQ,EACR,SAAS,EACT,QAAQ,GACT,EAAE;IACD,QAAQ,CAAC,EAAE,CAAC,CAAC,EAAE,KAAK,CAAC,SAAS,KAAK,IAAI,CAAC;IACxC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;CAC3B,qBAaA;AAED,yFAAyF;AACzF,wBAAgB,cAAc,CAAC,EAC7B,KAAK,EACL,QAAQ,EACR,YAAoB,GACrB,EAAE;IACD,KAAK,EAAE,KAAK,CAAC,SAAS,CAAC;IACvB,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC3B,YAAY,CAAC,EAAE,OAAO,CAAC;CACxB,qBAcA;AAED,wBAAgB,cAAc,CAAC,EAAE,EAAE,EAAE,QAAQ,EAAE,EAAE;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAA;CAAE,4BAO1F;AAED,wBAAgB,gBAAgB,CAAC,EAC/B,SAAS,EACT,QAAQ,EACR,QAAQ,GACT,EAAE;IACD,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;CAC3B,qBAYA;AAED,wBAAgB,YAAY,CAAC,EAC3B,OAAO,EACP,QAAQ,EACR,SAAS,EACT,QAAQ,GACT,EAAE;IACD,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;CAC3B,qBAWA;AAED,mFAAmF;AACnF,wBAAgB,eAAe,CAAC,EAC9B,KAAK,EACL,MAAM,EACN,QAAQ,GACT,EAAE;IACD,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,IAAI,CAAC;IACpB,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB,qBAYA;AAED,KAAK,kBAAkB,GAAG,IAAI,CAAC,KAAK,CAAC,mBAAmB,CAAC,gBAAgB,CAAC,EAAE,UAAU,GAAG,MAAM,GAAG,MAAM,CAAC,GAAG;IAC1G,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACxC,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB,CAAC;AAEF,wBAAgB,iBAAiB,CAAC,EAChC,EAAE,EACF,KAAK,EACL,aAAa,EACb,OAAO,EACP,WAAW,EACX,SAAS,EACT,GAAG,UAAU,EACd,EAAE,kBAAkB,qBAcpB"}
@@ -1,11 +1,11 @@
1
1
  "use client";
2
- import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
2
+ import { jsxs, jsx } from 'react/jsx-runtime';
3
3
  import * as React from 'react';
4
4
  import { cn } from '@timmbr/utils';
5
- import { EyeOff, Eye } from '@timmbr/icons';
6
5
  import { useAuthModalLabels } from '../AuthModal.labels.js';
7
- import { authModalHeadingVariants, authModalSubtitleVariants, authModalSubmitButtonVariants, authModalLinkVariants, authModalInputVariants } from '../AuthModal.styles.js';
8
- import { Spinner } from '../../Spinner/Spinner.js';
6
+ import { authModalHeadingVariants, authModalSubtitleVariants, authModalLinkVariants } from '../AuthModal.styles.js';
7
+ import { Button } from '../../Button/Button.js';
8
+ import { Input } from '../../Input/Input.js';
9
9
 
10
10
  function AuthForm({
11
11
  onSubmit,
@@ -49,16 +49,14 @@ function AuthSubmitButton({
49
49
  children
50
50
  }) {
51
51
  return /* @__PURE__ */ jsx(
52
- "button",
52
+ Button,
53
53
  {
54
54
  type: "submit",
55
- disabled: disabled || isLoading,
56
- "aria-busy": isLoading || void 0,
57
- className: authModalSubmitButtonVariants(),
58
- children: isLoading ? /* @__PURE__ */ jsxs(Fragment, { children: [
59
- /* @__PURE__ */ jsx(Spinner, { size: "sm", variant: "white", decorative: true }),
60
- /* @__PURE__ */ jsx("span", { className: "sr-only", children })
61
- ] }) : children
55
+ variant: "primary",
56
+ fullWidth: true,
57
+ loading: isLoading,
58
+ disabled,
59
+ children
62
60
  }
63
61
  );
64
62
  }
@@ -99,36 +97,20 @@ function AuthPasswordField({
99
97
  className,
100
98
  ...inputProps
101
99
  }) {
102
- const labels = useAuthModalLabels();
103
- const [visible, setVisible] = React.useState(false);
104
- return /* @__PURE__ */ jsxs("div", { className, children: [
105
- /* @__PURE__ */ jsx("label", { htmlFor: id, className: "sr-only", children: label }),
106
- /* @__PURE__ */ jsxs("div", { className: "relative", children: [
107
- /* @__PURE__ */ jsx(
108
- "input",
109
- {
110
- id,
111
- type: visible ? "text" : "password",
112
- onChange: (e) => onValueChange?.(e.target.value),
113
- "aria-invalid": invalid || void 0,
114
- "aria-describedby": describedBy,
115
- className: cn(authModalInputVariants({ invalid: !!invalid }), "pr-12"),
116
- ...inputProps
117
- }
118
- ),
119
- /* @__PURE__ */ jsx(
120
- "button",
121
- {
122
- type: "button",
123
- onClick: () => setVisible((v) => !v),
124
- "aria-label": visible ? labels.hidePassword : labels.showPassword,
125
- "aria-pressed": visible,
126
- className: "absolute inset-y-0 right-0 flex w-12 items-center justify-center text-grey-600 hover:text-grey-950 focus:outline-none focus-visible:text-primary cursor-pointer",
127
- children: visible ? /* @__PURE__ */ jsx(EyeOff, { className: "size-5", "aria-hidden": "true" }) : /* @__PURE__ */ jsx(Eye, { className: "size-5", "aria-hidden": "true" })
128
- }
129
- )
130
- ] })
131
- ] });
100
+ return /* @__PURE__ */ jsx(
101
+ Input,
102
+ {
103
+ id,
104
+ type: "password",
105
+ showPasswordToggle: true,
106
+ "aria-label": label,
107
+ "aria-describedby": describedBy,
108
+ error: invalid,
109
+ containerClassName: className,
110
+ onChange: (e) => onValueChange?.(e.target.value),
111
+ ...inputProps
112
+ }
113
+ );
132
114
  }
133
115
 
134
116
  export { AuthDestination, AuthFieldError, AuthForm, AuthPasswordField, AuthStepHeader, AuthSubmitButton, AuthTextLink };
@@ -1 +1 @@
1
- {"version":3,"file":"Button.d.ts","sourceRoot":"","sources":["../../../src/components/Button/Button.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAO/B,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAElD,eAAO,MAAM,MAAM,uFAqGlB,CAAC"}
1
+ {"version":3,"file":"Button.d.ts","sourceRoot":"","sources":["../../../src/components/Button/Button.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAO/B,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAElD,eAAO,MAAM,MAAM,uFAsGlB,CAAC"}
@@ -63,6 +63,7 @@ const Button = React.forwardRef(
63
63
  ref,
64
64
  type: "button",
65
65
  disabled: isDisabled,
66
+ "aria-busy": loading || void 0,
66
67
  "data-slot": "button",
67
68
  "data-testid": "timmbr-button",
68
69
  style,
@@ -1 +1 @@
1
- {"version":3,"file":"Checkbox.d.ts","sourceRoot":"","sources":["../../../src/components/Checkbox/Checkbox.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAK/B,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAEtD,eAAO,MAAM,QAAQ,yFAwFpB,CAAC"}
1
+ {"version":3,"file":"Checkbox.d.ts","sourceRoot":"","sources":["../../../src/components/Checkbox/Checkbox.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAO/B,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAEtD,eAAO,MAAM,QAAQ,yFA+FpB,CAAC"}
@@ -4,7 +4,9 @@ import * as React from 'react';
4
4
  import * as CheckboxPrimitive from '@radix-ui/react-checkbox';
5
5
  import { Check } from '@timmbr/icons';
6
6
  import { cn } from '@timmbr/utils';
7
+ import { resolveMotion } from '../../types/motion.js';
7
8
  import { checkboxIndicatorVariants, checkboxVariants } from './Checkbox.styles.js';
9
+ import { useGlobalAnimation } from '../../providers/AnimationProvider.js';
8
10
 
9
11
  const Checkbox = React.forwardRef(
10
12
  ({
@@ -16,6 +18,7 @@ const Checkbox = React.forwardRef(
16
18
  description,
17
19
  error,
18
20
  checked,
21
+ motion,
19
22
  id: customId,
20
23
  disabled,
21
24
  ...props
@@ -24,6 +27,8 @@ const Checkbox = React.forwardRef(
24
27
  const id = customId || generatedId;
25
28
  const isError = Boolean(error);
26
29
  const errorMessage = typeof error === "string" ? error : void 0;
30
+ const globalMotion = useGlobalAnimation();
31
+ const { shouldAnimate } = resolveMotion(motion, globalMotion);
27
32
  const checkboxElement = /* @__PURE__ */ jsx(
28
33
  CheckboxPrimitive.Root,
29
34
  {
@@ -31,7 +36,11 @@ const Checkbox = React.forwardRef(
31
36
  id,
32
37
  disabled,
33
38
  ...checked !== void 0 ? { checked } : {},
34
- className: cn(checkboxVariants({ size, isError }), !label && className),
39
+ className: cn(
40
+ checkboxVariants({ size, isError }),
41
+ shouldAnimate ? "transition-all" : "transition-none",
42
+ !label && className
43
+ ),
35
44
  style: !label ? style : void 0,
36
45
  ...props,
37
46
  children: /* @__PURE__ */ jsxs(
@@ -1,7 +1,7 @@
1
1
  import { cva } from 'class-variance-authority';
2
2
 
3
3
  const checkboxVariants = cva(
4
- "peer shrink-0 rounded-[2px] border border-grey-300 dark:border-grey-600 bg-grey-50 dark:bg-grey-900 transition-all 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=checked]:border-primary data-[state=checked]:text-grey-50 data-[state=indeterminate]:bg-primary data-[state=indeterminate]:border-primary data-[state=indeterminate]:text-grey-50 cursor-pointer flex items-center justify-center",
4
+ "peer shrink-0 rounded-[2px] border border-grey-300 dark:border-grey-600 bg-grey-50 dark:bg-grey-900 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=checked]:border-primary data-[state=checked]:text-grey-50 data-[state=indeterminate]:bg-primary data-[state=indeterminate]:border-primary data-[state=indeterminate]:text-grey-50 cursor-pointer flex items-center justify-center",
5
5
  {
6
6
  variants: {
7
7
  size: {
@@ -1,6 +1,7 @@
1
1
  import type * as React from 'react';
2
2
  import type * as CheckboxPrimitive from '@radix-ui/react-checkbox';
3
3
  import type { CheckboxVariants } from './Checkbox.styles';
4
+ import type { MotionProp } from '../../types/motion';
4
5
  export interface CheckboxProps extends Omit<React.ComponentPropsWithoutRef<typeof CheckboxPrimitive.Root>, 'size'>, CheckboxVariants {
5
6
  /**
6
7
  * Primary label text displayed next to the checkbox.
@@ -18,5 +19,7 @@ export interface CheckboxProps extends Omit<React.ComponentPropsWithoutRef<typeo
18
19
  * Custom className for the outer container wrapper.
19
20
  */
20
21
  containerClassName?: string;
22
+ /** Override animation behaviour. `false` disables transitions; omit to inherit global setting. */
23
+ motion?: MotionProp;
21
24
  }
22
25
  //# sourceMappingURL=Checkbox.types.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"Checkbox.types.d.ts","sourceRoot":"","sources":["../../../src/components/Checkbox/Checkbox.types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,KAAK,MAAM,OAAO,CAAC;AACpC,OAAO,KAAK,KAAK,iBAAiB,MAAM,0BAA0B,CAAC;AACnE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAE1D,MAAM,WAAW,aACf,SAAQ,IAAI,CACR,KAAK,CAAC,wBAAwB,CAAC,OAAO,iBAAiB,CAAC,IAAI,CAAC,EAC7D,MAAM,CACP,EACD,gBAAgB;IAClB;;OAEG;IACH,KAAK,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACxB;;OAEG;IACH,WAAW,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC9B;;OAEG;IACH,KAAK,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;IACzB;;OAEG;IACH,kBAAkB,CAAC,EAAE,MAAM,CAAC;CAC7B"}
1
+ {"version":3,"file":"Checkbox.types.d.ts","sourceRoot":"","sources":["../../../src/components/Checkbox/Checkbox.types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,KAAK,MAAM,OAAO,CAAC;AACpC,OAAO,KAAK,KAAK,iBAAiB,MAAM,0BAA0B,CAAC;AACnE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAC1D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAErD,MAAM,WAAW,aACf,SAAQ,IAAI,CACR,KAAK,CAAC,wBAAwB,CAAC,OAAO,iBAAiB,CAAC,IAAI,CAAC,EAC7D,MAAM,CACP,EACD,gBAAgB;IAClB;;OAEG;IACH,KAAK,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACxB;;OAEG;IACH,WAAW,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC9B;;OAEG;IACH,KAAK,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;IACzB;;OAEG;IACH,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,kGAAkG;IAClG,MAAM,CAAC,EAAE,UAAU,CAAC;CACrB"}
@@ -70,7 +70,7 @@ const Chip = React.forwardRef(
70
70
  tabIndex: isInteractive ? -1 : void 0,
71
71
  onClick: handleRemove,
72
72
  "aria-label": removeLabel,
73
- className: "shrink-0 -mr-1 size-4 rounded-full inline-flex items-center justify-center opacity-70 hover:opacity-100 hover:bg-grey-1000/10 dark:hover:bg-grey-50/20 transition-all cursor-pointer focus-visible:opacity-100 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring",
73
+ className: "shrink-0 -mr-1 min-w-[28px] min-h-[28px] rounded-full inline-flex items-center justify-center opacity-70 hover:opacity-100 hover:bg-grey-1000/10 dark:hover:bg-grey-50/20 transition-all cursor-pointer focus-visible:opacity-100 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring",
74
74
  children: /* @__PURE__ */ jsx(X, { className: "size-3" })
75
75
  }
76
76
  )
@@ -45,7 +45,7 @@ const DialogContent = React.forwardRef(({ className, children, motion, ...props
45
45
  DialogPrimitive.Close,
46
46
  {
47
47
  "data-slot": "dialog-close",
48
- className: "absolute right-4 top-4 z-20 rounded-sm p-1 text-muted hover:text-foreground opacity-70 hover:opacity-100 transition-opacity focus:outline-none focus:ring-2 focus:ring-primary cursor-pointer",
48
+ className: "absolute right-3 top-3 z-20 flex items-center justify-center min-w-[44px] min-h-[44px] rounded-sm text-muted hover:text-foreground opacity-70 hover:opacity-100 transition-opacity focus:outline-none focus-visible:ring-2 focus-visible:ring-primary cursor-pointer",
49
49
  children: [
50
50
  /* @__PURE__ */ jsx(X, { className: "h-4 w-4" }),
51
51
  /* @__PURE__ */ jsx("span", { className: "sr-only", children: "Close" })
@@ -53,7 +53,7 @@ const DrawerContent = React.forwardRef(({ className, children, side = "right", s
53
53
  DialogPrimitive.Close,
54
54
  {
55
55
  "data-slot": "drawer-close",
56
- className: "absolute right-4 top-4 rounded-sm p-1 text-muted hover:text-foreground opacity-70 hover:opacity-100 transition-opacity focus:outline-none focus:ring-2 focus:ring-primary cursor-pointer",
56
+ className: "absolute right-3 top-3 flex items-center justify-center min-w-[44px] min-h-[44px] rounded-sm text-muted hover:text-foreground opacity-70 hover:opacity-100 transition-opacity focus:outline-none focus-visible:ring-2 focus-visible:ring-primary cursor-pointer",
57
57
  children: [
58
58
  /* @__PURE__ */ jsx(X, { className: "h-4 w-4" }),
59
59
  /* @__PURE__ */ jsx("span", { className: "sr-only", children: "Close" })
@@ -1 +1 @@
1
- {"version":3,"file":"FilterChips.d.ts","sourceRoot":"","sources":["../../../src/components/FilterChips/FilterChips.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAG/B,OAAO,KAAK,EAAE,UAAU,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAExE;;;GAGG;AACH,wBAAgB,WAAW,CAAC,CAAC,SAAS,UAAU,GAAG,UAAU,EAAE,EAC7D,KAAK,EACL,QAAQ,EACR,UAAU,EACV,aAA2B,EAC3B,WAA0C,EAC1C,SAAS,GACV,EAAE,gBAAgB,CAAC,CAAC,CAAC,4BA8BrB"}
1
+ {"version":3,"file":"FilterChips.d.ts","sourceRoot":"","sources":["../../../src/components/FilterChips/FilterChips.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAI/B,OAAO,KAAK,EAAE,UAAU,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAExE;;;GAGG;AACH,wBAAgB,WAAW,CAAC,CAAC,SAAS,UAAU,GAAG,UAAU,EAAE,EAC7D,KAAK,EACL,QAAQ,EACR,UAAU,EACV,aAA2B,EAC3B,WAA0C,EAC1C,SAAS,GACV,EAAE,gBAAgB,CAAC,CAAC,CAAC,4BA0BrB"}
@@ -2,6 +2,7 @@
2
2
  import { jsxs, jsx } from 'react/jsx-runtime';
3
3
  import { cn } from '@timmbr/utils';
4
4
  import { Chip } from '../Chip/Chip.js';
5
+ import { Button } from '../Button/Button.js';
5
6
 
6
7
  function FilterChips({
7
8
  chips,
@@ -22,15 +23,7 @@ function FilterChips({
22
23
  ),
23
24
  children: [
24
25
  /* @__PURE__ */ jsx("ul", { className: "flex shrink-0 items-center gap-2 sm:flex-wrap", children: chips.map((chip) => /* @__PURE__ */ jsx("li", { className: "shrink-0", children: /* @__PURE__ */ jsx(Chip, { color: "primary", onRemove: () => onRemove(chip), removeLabel: removeLabel(String(chip.label)), children: chip.label }) }, chip.id)) }),
25
- onClearAll && chips.length > 1 && /* @__PURE__ */ jsx(
26
- "button",
27
- {
28
- type: "button",
29
- onClick: onClearAll,
30
- className: "shrink-0 rounded-sm px-1 font-sans text-body-3 font-semibold text-primary underline-offset-4 hover:underline focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring",
31
- children: clearAllLabel
32
- }
33
- )
26
+ onClearAll && chips.length > 1 && /* @__PURE__ */ jsx(Button, { variant: "link", size: "sm", className: "shrink-0", onClick: onClearAll, children: clearAllLabel })
34
27
  ]
35
28
  }
36
29
  );
@@ -1 +1 @@
1
- {"version":3,"file":"FilterPanel.d.ts","sourceRoot":"","sources":["../../../src/components/FilterPanel/FilterPanel.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAsB/B,OAAO,EAEL,KAAK,WAAW,EAChB,KAAK,YAAY,EACjB,KAAK,qBAAqB,EAC1B,KAAK,iBAAiB,EACtB,KAAK,gBAAgB,EACrB,KAAK,iBAAiB,EACvB,MAAM,qBAAqB,CAAC;AAE7B,eAAO,MAAM,qBAAqB,EAAE,iBAYnC,CAAC;AAEF,iGAAiG;AACjG,eAAO,MAAM,gBAAgB,GAAI,QAAQ,YAAY,YAAgE,CAAC;AActH;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,EAC/B,KAAK,EACL,QAAQ,EACR,KAAS,EACT,eAAoB,EACpB,MAAM,EAAE,cAAc,EACtB,SAAS,GACV,EAAE,qBAAqB,qBA2DvB;AAED,uDAAuD;AACvD,wBAAgB,eAAe,CAAC,EAC9B,KAAK,EACL,QAAQ,GACT,EAAE;IACD,KAAK,EAAE,WAAW,CAAC;IACnB,QAAQ,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;CAChD,4BAmBA;AAED,gFAAgF;AAChF,wBAAgB,iBAAiB,CAAC,EAChC,KAAK,EACL,MAAM,EAAE,cAAc,EACtB,aAAa,EACb,WAAkB,GACnB,EAAE;IACD,KAAK,EAAE,iBAAiB,CAAC;IACzB,MAAM,CAAC,EAAE,OAAO,CAAC,iBAAiB,CAAC,CAAC;IACpC,kFAAkF;IAClF,aAAa,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;IACnD,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB,qBAkCA;AAED;;;;;GAKG;AACH,eAAO,MAAM,WAAW,yFA2FvB,CAAC"}
1
+ {"version":3,"file":"FilterPanel.d.ts","sourceRoot":"","sources":["../../../src/components/FilterPanel/FilterPanel.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAsB/B,OAAO,EAEL,KAAK,WAAW,EAChB,KAAK,YAAY,EACjB,KAAK,qBAAqB,EAC1B,KAAK,iBAAiB,EACtB,KAAK,gBAAgB,EACrB,KAAK,iBAAiB,EACvB,MAAM,qBAAqB,CAAC;AAE7B,eAAO,MAAM,qBAAqB,EAAE,iBAYnC,CAAC;AAEF,iGAAiG;AACjG,eAAO,MAAM,gBAAgB,GAAI,QAAQ,YAAY,YAAgE,CAAC;AActH;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,EAC/B,KAAK,EACL,QAAQ,EACR,KAAS,EACT,eAAoB,EACpB,MAAM,EAAE,cAAc,EACtB,SAAS,GACV,EAAE,qBAAqB,qBA2DvB;AAED,uDAAuD;AACvD,wBAAgB,eAAe,CAAC,EAC9B,KAAK,EACL,QAAQ,GACT,EAAE;IACD,KAAK,EAAE,WAAW,CAAC;IACnB,QAAQ,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;CAChD,4BAmBA;AAED,gFAAgF;AAChF,wBAAgB,iBAAiB,CAAC,EAChC,KAAK,EACL,MAAM,EAAE,cAAc,EACtB,aAAa,EACb,WAAkB,GACnB,EAAE;IACD,KAAK,EAAE,iBAAiB,CAAC;IACzB,MAAM,CAAC,EAAE,OAAO,CAAC,iBAAiB,CAAC,CAAC;IACpC,kFAAkF;IAClF,aAAa,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;IACnD,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB,qBAkCA;AAED;;;;;GAKG;AACH,eAAO,MAAM,WAAW,yFA4FvB,CAAC"}
@@ -3,10 +3,11 @@ import { jsxs, jsx } from 'react/jsx-runtime';
3
3
  import * as React from 'react';
4
4
  import { Search } from '@timmbr/icons';
5
5
  import { cn } from '@timmbr/utils';
6
- import { filterOptionRowVariants, filterLinkButtonVariants, filterPanelTitleVariants, filterPanelHeaderVariants, filterToggleListVariants, filterSectionTriggerVariants, filterSectionContentVariants, filterPanelBodyVariants, filterPanelVariants, filterOptionCountVariants, filterOptionLabelVariants } from './FilterPanel.styles.js';
6
+ import { filterOptionRowVariants, filterPanelTitleVariants, filterPanelHeaderVariants, filterToggleListVariants, filterSectionTriggerVariants, filterSectionContentVariants, filterPanelBodyVariants, filterPanelVariants, filterOptionCountVariants, filterOptionLabelVariants } from './FilterPanel.styles.js';
7
7
  import { PRICE_GROUP_KEY } from './FilterPanel.types.js';
8
8
  import { Input } from '../Input/Input.js';
9
9
  import { Checkbox } from '../Checkbox/Checkbox.js';
10
+ import { Button } from '../Button/Button.js';
10
11
  import { Accordion, AccordionItem, AccordionTrigger, AccordionContent } from '../Accordion/Accordion.js';
11
12
  import { RangeSlider } from '../RangeSlider/RangeSlider.js';
12
13
  import { Switch } from '../Switch/Switch.js';
@@ -88,10 +89,10 @@ function FilterOptionList({
88
89
  visible.length === 0 && /* @__PURE__ */ jsx("li", { className: "text-body-3 text-grey-500", children: labels.noMatches })
89
90
  ] }),
90
91
  !needle && (hidden > 0 || expanded) && matching.length > limit && /* @__PURE__ */ jsx(
91
- "button",
92
+ Button,
92
93
  {
93
- type: "button",
94
- className: filterLinkButtonVariants(),
94
+ variant: "link",
95
+ size: "sm",
95
96
  "aria-expanded": expanded,
96
97
  onClick: () => setExpanded((e) => !e),
97
98
  children: expanded ? labels.showLess : labels.showMore(hidden)
@@ -208,10 +209,11 @@ const FilterPanel = React.forwardRef(
208
209
  ] }) }),
209
210
  /* @__PURE__ */ jsxs(AccordionContent, { className: filterSectionContentVariants(), children: [
210
211
  count > 0 && onClearGroup && /* @__PURE__ */ jsx(
211
- "button",
212
+ Button,
212
213
  {
213
- type: "button",
214
- className: cn(filterLinkButtonVariants(), "mb-3"),
214
+ variant: "link",
215
+ size: "sm",
216
+ className: "mb-3",
215
217
  onClick: () => onClearGroup(group.key),
216
218
  children: labels.clear
217
219
  }
@@ -51,7 +51,7 @@ const ImageUploadThumbnailCard = ({
51
51
  }
52
52
  ),
53
53
  /* @__PURE__ */ jsx("div", { className: "absolute top-2 left-2 z-10 flex items-center gap-1.5 pointer-events-none", children: index === 0 ? /* @__PURE__ */ jsxs("div", { className: "bg-grey-1000/65 backdrop-blur-md text-grey-50 text-caption font-semibold px-2 py-0.5 rounded-full border border-grey-50/20 shadow-md flex items-center gap-1.5", children: [
54
- /* @__PURE__ */ jsx("span", { className: "size-1.5 rounded-full bg-success shadow-[0_0_6px_rgba(52,211,153,0.8)]" }),
54
+ /* @__PURE__ */ jsx("span", { className: "size-1.5 rounded-full bg-success shadow-[0_0_6px_color-mix(in_srgb,var(--color-success)_80%,transparent)]" }),
55
55
  /* @__PURE__ */ jsx("span", { children: "Cover" })
56
56
  ] }) : /* @__PURE__ */ jsxs("div", { className: "bg-grey-1000/55 backdrop-blur-md text-grey-50/90 text-caption font-medium px-2 py-0.5 rounded-full border border-grey-50/10 shadow-sm", children: [
57
57
  "#",
@@ -1 +1 @@
1
- {"version":3,"file":"Input.d.ts","sourceRoot":"","sources":["../../../src/components/Input/Input.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAM/B,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAEhD,eAAO,MAAM,KAAK,qFAoNjB,CAAC"}
1
+ {"version":3,"file":"Input.d.ts","sourceRoot":"","sources":["../../../src/components/Input/Input.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAM/B,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAEhD,eAAO,MAAM,KAAK,qFAqNjB,CAAC"}
@@ -112,7 +112,8 @@ const Input = React.forwardRef(
112
112
  {
113
113
  htmlFor: id,
114
114
  className: cn(
115
- "absolute pointer-events-none transition-all duration-200 select-none truncate max-w-full z-10",
115
+ "absolute pointer-events-none select-none truncate max-w-full z-10",
116
+ shouldAnimate ? "transition-all duration-200" : "transition-none",
116
117
  isFloatingActive ? "-top-2.5 left-0 px-1 bg-grey-50 dark:bg-grey-900 text-caption-lg font-semibold leading-none rounded-xs" : "top-1/2 -translate-y-1/2 left-0 text-body-2 text-muted-foreground leading-none"
117
118
  ),
118
119
  style: {
@@ -6,7 +6,7 @@ const navFooterRootVariants = cva(
6
6
  variants: {
7
7
  tone: {
8
8
  dark: "bg-surface-dark text-bg-2",
9
- light: "bg-[var(--color-bg-2,#F7F1E6)] text-[var(--color-grey-800,#3C3C3C)] border-t border-border-warm"
9
+ light: "bg-bg-2 text-grey-800 border-t border-border-warm"
10
10
  }
11
11
  },
12
12
  defaultVariants: {
@@ -25,7 +25,7 @@ const DefaultFooterWordmark = ({ className }) => /* @__PURE__ */ jsxs(
25
25
  {
26
26
  x: "0",
27
27
  y: "38",
28
- fill: "#D39375",
28
+ fill: "currentColor",
29
29
  fontFamily: "Outfit, sans-serif",
30
30
  fontWeight: "700",
31
31
  fontSize: "40",
@@ -504,7 +504,7 @@ const NavHeader = React.forwardRef(
504
504
  ]
505
505
  }
506
506
  ),
507
- isSearchVisible && resolvedMobileSearchMode !== "icon" && /* @__PURE__ */ jsx("div", { className: "px-3 sm:px-6 pb-2.5 pt-0.5 bg-[var(--color-bg-2,#F7F1E6)]", children: /* @__PURE__ */ jsxs(
507
+ isSearchVisible && resolvedMobileSearchMode !== "icon" && /* @__PURE__ */ jsx("div", { className: "px-3 sm:px-6 pb-2.5 pt-0.5 bg-bg-2", children: /* @__PURE__ */ jsxs(
508
508
  "button",
509
509
  {
510
510
  type: "button",
@@ -4,11 +4,11 @@ const offerBannerVariants = cva(
4
4
  "w-full bg-surface-dark text-bg-2 font-title! text-body-3 font-semibold uppercase tracking-[0.14em] py-2 px-4 flex items-center justify-center relative transition-all duration-200 z-50 border-b border-grey-1000/20"
5
5
  );
6
6
  const navHeaderVariants = cva(
7
- "w-full bg-[var(--color-bg-2,#F7F1E6)] text-[var(--color-grey-800,#3C3C3C)] border-b border-border-warm relative z-40 transition-colors",
7
+ "w-full bg-bg-2 text-grey-800 border-b border-border-warm relative z-40 transition-colors",
8
8
  {
9
9
  variants: {
10
10
  sticky: {
11
- true: "sticky top-0 shadow-sm backdrop-blur-md bg-[var(--color-bg-2,#F7F1E6)]/95",
11
+ true: "sticky top-0 shadow-sm backdrop-blur-md bg-bg-2/95",
12
12
  false: "relative"
13
13
  }
14
14
  },
@@ -110,7 +110,7 @@ const actionOverflowItemVariants = cva(
110
110
  }
111
111
  );
112
112
  const mobileTabSliderVariants = cva(
113
- "w-full overflow-x-auto flex items-center gap-6 px-4 py-2 border-b border-border-warm bg-[var(--color-bg-2,#F7F1E6)] select-none scroll-smooth [&::-webkit-scrollbar]:hidden [-ms-overflow-style:none] [scrollbar-width:none]"
113
+ "w-full overflow-x-auto flex items-center gap-6 px-4 py-2 border-b border-border-warm bg-bg-2 select-none scroll-smooth [&::-webkit-scrollbar]:hidden [-ms-overflow-style:none] [scrollbar-width:none]"
114
114
  );
115
115
  const mobileTabItemVariants = cva(
116
116
  "relative text-body-3 sm:text-body-2 tracking-tight whitespace-nowrap py-1.5 px-1 font-semibold transition-colors cursor-pointer select-none",
@@ -135,7 +135,7 @@ const mobileTabContentPanelVariants = cva(
135
135
  "w-full bg-grey-50 border-b border-border-warm shadow-md overflow-hidden"
136
136
  );
137
137
  const mobileSearchDrawerVariants = cva(
138
- "fixed inset-0 z-[9999] h-[100dvh] w-screen bg-[var(--color-bg-2,#F7F1E6)] flex flex-col overflow-hidden"
138
+ "fixed inset-0 z-[9999] h-[100dvh] w-screen bg-bg-2 flex flex-col overflow-hidden"
139
139
  );
140
140
 
141
141
  export { actionOverflowItemVariants, actionOverflowPopoverVariants, megaMenuCardVariants, mobileSearchDrawerVariants, mobileTabContentPanelVariants, mobileTabItemVariants, mobileTabSliderVariants, navActionVariants, navHeaderContainerVariants, navHeaderItemVariants, navHeaderVariants, offerBannerVariants, searchPanelOptionVariants, searchPanelSectionTitleVariants, searchPanelTextButtonVariants, searchPopoverCardVariants };
@@ -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,3 @@
1
+ export { PageProgress } from './PageProgress';
2
+ export type { PageProgressProps } from './PageProgress.types';
3
+ //# sourceMappingURL=index.d.ts.map
@@ -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"}
@@ -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;AAS/B,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAatD;;;;GAIG;AACH,eAAO,MAAM,QAAQ,sFA+FpB,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;;8EAW5B,CAAC;AAEF,eAAO,MAAM,oBAAoB;;8EAW/B,CAAC;AAEH,oFAAoF;AACpF,eAAO,MAAM,sBAAsB,oFAElC,CAAC;AAEF,eAAO,MAAM,qBAAqB,oFAEjC,CAAC"}
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] motion-safe:transition-[transform,opacity] motion-safe:duration-200",
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;CACvB;AAED,MAAM,WAAW,iBAAiB;IAChC,iFAAiF;IACjF,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB"}
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;;;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"}
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;AAI/B,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAElD,eAAO,MAAM,MAAM,uFAsElB,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(switchVariants({ size }), !label && className),
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(SwitchPrimitive.Thumb, { className: cn(switchThumbVariants({ size })) })
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 transition-colors 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",
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 transition-transform data-[state=unchecked]:translate-x-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;AAEtD,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;CAC7B"}
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"}
@@ -77,7 +77,7 @@ const ToastAction = React.forwardRef(({ className, ...props }, ref) => /* @__PUR
77
77
  ref,
78
78
  "data-slot": "toast-action",
79
79
  className: cn(
80
- "inline-flex h-8 shrink-0 items-center justify-center rounded-[2px] border bg-transparent px-3 text-body-3 font-semibold ring-offset-background transition-colors hover:bg-grey-100 dark:hover:bg-grey-800 focus:outline-none focus:ring-2 focus:ring-primary disabled:pointer-events-none disabled:opacity-50 cursor-pointer",
80
+ "inline-flex h-8 shrink-0 items-center justify-center rounded-[2px] border bg-transparent px-3 text-body-3 font-semibold ring-offset-background transition-colors hover:bg-grey-100 dark:hover:bg-grey-800 focus:outline-none focus-visible:ring-2 focus-visible:ring-primary disabled:pointer-events-none disabled:opacity-50 cursor-pointer",
81
81
  className
82
82
  ),
83
83
  ...props
@@ -90,7 +90,7 @@ const ToastClose = React.forwardRef(({ className, ...props }, ref) => /* @__PURE
90
90
  ref,
91
91
  "data-slot": "toast-close",
92
92
  className: cn(
93
- "absolute right-2 top-2 rounded-sm p-1 text-muted hover:text-foreground opacity-70 hover:opacity-100 transition-opacity focus:outline-none cursor-pointer",
93
+ "absolute right-1 top-1 flex items-center justify-center min-w-[44px] min-h-[44px] rounded-sm text-muted hover:text-foreground opacity-70 hover:opacity-100 transition-opacity focus:outline-none focus-visible:ring-2 focus-visible:ring-ring cursor-pointer",
94
94
  className
95
95
  ),
96
96
  "toast-close": "",
@@ -1,6 +1,10 @@
1
1
  import * as React from 'react';
2
2
  import type { ToastItem, ToastOptions } from './Toast.types';
3
3
  type ToastSubscriber = () => void;
4
+ /**
5
+ * Browser-only module-level singleton. Not SSR-safe — never import this on the server.
6
+ * Use `.reset()` in tests to clear state between cases.
7
+ */
4
8
  declare class ToastStore {
5
9
  private toasts;
6
10
  private listeners;
@@ -1 +1 @@
1
- {"version":3,"file":"toastStore.d.ts","sourceRoot":"","sources":["../../../src/components/Toast/toastStore.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,KAAK,EAAqB,SAAS,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAUhF,KAAK,eAAe,GAAG,MAAM,IAAI,CAAC;AAElC,cAAM,UAAU;IACd,OAAO,CAAC,MAAM,CAAmB;IACjC,OAAO,CAAC,SAAS,CAAmC;IACpD,OAAO,CAAC,UAAU,CAAa;IAC/B,OAAO,CAAC,YAAY,CAAoC;IACxD,OAAO,CAAC,eAAe,CAAqB;IAE5C,SAAS,CAAC,QAAQ,EAAE,eAAe,GAAG,MAAM,IAAI;IAOhD,OAAO,CAAC,MAAM;IAId,SAAS,IAAI,SAAS,EAAE;IAIxB,aAAa,CAAC,GAAG,EAAE,MAAM;IAIzB,eAAe,CAAC,MAAM,EAAE,UAAU,GAAG,OAAO;IAI5C,4FAA4F;IAC5F,kBAAkB,CAAC,QAAQ,EAAE,MAAM,GAAG,SAAS;IAI/C;;;;OAIG;IACH,OAAO,CAAC,UAAU;IAQlB,QAAQ,CAAC,OAAO,EAAE,YAAY,GAAG,MAAM;IA2CvC,OAAO,CAAC,EAAE,CAAC,EAAE,MAAM;CAmBpB;AAED,eAAO,MAAM,UAAU,YAAmB,CAAC;AAE3C,MAAM,WAAW,aAAa;IAC5B,CAAC,OAAO,EAAE,YAAY,GAAG,MAAM,CAAC;IAChC,KAAK,EAAE,CAAC,KAAK,EAAE,KAAK,CAAC,SAAS,EAAE,WAAW,CAAC,EAAE,KAAK,CAAC,SAAS,EAAE,OAAO,CAAC,EAAE,OAAO,CAAC,YAAY,CAAC,KAAK,MAAM,CAAC;IAC1G,OAAO,EAAE,CAAC,KAAK,EAAE,KAAK,CAAC,SAAS,EAAE,WAAW,CAAC,EAAE,KAAK,CAAC,SAAS,EAAE,OAAO,CAAC,EAAE,OAAO,CAAC,YAAY,CAAC,KAAK,MAAM,CAAC;IAC5G,OAAO,EAAE,CAAC,KAAK,EAAE,KAAK,CAAC,SAAS,EAAE,WAAW,CAAC,EAAE,KAAK,CAAC,SAAS,EAAE,OAAO,CAAC,EAAE,OAAO,CAAC,YAAY,CAAC,KAAK,MAAM,CAAC;IAC5G,IAAI,EAAE,CAAC,KAAK,EAAE,KAAK,CAAC,SAAS,EAAE,WAAW,CAAC,EAAE,KAAK,CAAC,SAAS,EAAE,OAAO,CAAC,EAAE,OAAO,CAAC,YAAY,CAAC,KAAK,MAAM,CAAC;IACzG,OAAO,EAAE,CAAC,EAAE,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC;CAChC;AAED,eAAO,MAAM,KAAK,EAAE,aA8BlB,CAAC;AAEH,wBAAgB,QAAQ;;mBAWa,MAAM;;EAG1C"}
1
+ {"version":3,"file":"toastStore.d.ts","sourceRoot":"","sources":["../../../src/components/Toast/toastStore.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,KAAK,EAAqB,SAAS,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAUhF,KAAK,eAAe,GAAG,MAAM,IAAI,CAAC;AAElC;;;GAGG;AACH,cAAM,UAAU;IACd,OAAO,CAAC,MAAM,CAAmB;IACjC,OAAO,CAAC,SAAS,CAAmC;IACpD,OAAO,CAAC,UAAU,CAAa;IAC/B,OAAO,CAAC,YAAY,CAAoC;IACxD,OAAO,CAAC,eAAe,CAAqB;IAE5C,SAAS,CAAC,QAAQ,EAAE,eAAe,GAAG,MAAM,IAAI;IAOhD,OAAO,CAAC,MAAM;IAId,SAAS,IAAI,SAAS,EAAE;IAIxB,aAAa,CAAC,GAAG,EAAE,MAAM;IAIzB,eAAe,CAAC,MAAM,EAAE,UAAU,GAAG,OAAO;IAI5C,4FAA4F;IAC5F,kBAAkB,CAAC,QAAQ,EAAE,MAAM,GAAG,SAAS;IAI/C;;;;OAIG;IACH,OAAO,CAAC,UAAU;IAQlB,QAAQ,CAAC,OAAO,EAAE,YAAY,GAAG,MAAM;IA2CvC,OAAO,CAAC,EAAE,CAAC,EAAE,MAAM;CAmBpB;AAED,eAAO,MAAM,UAAU,YAAmB,CAAC;AAE3C,MAAM,WAAW,aAAa;IAC5B,CAAC,OAAO,EAAE,YAAY,GAAG,MAAM,CAAC;IAChC,KAAK,EAAE,CAAC,KAAK,EAAE,KAAK,CAAC,SAAS,EAAE,WAAW,CAAC,EAAE,KAAK,CAAC,SAAS,EAAE,OAAO,CAAC,EAAE,OAAO,CAAC,YAAY,CAAC,KAAK,MAAM,CAAC;IAC1G,OAAO,EAAE,CAAC,KAAK,EAAE,KAAK,CAAC,SAAS,EAAE,WAAW,CAAC,EAAE,KAAK,CAAC,SAAS,EAAE,OAAO,CAAC,EAAE,OAAO,CAAC,YAAY,CAAC,KAAK,MAAM,CAAC;IAC5G,OAAO,EAAE,CAAC,KAAK,EAAE,KAAK,CAAC,SAAS,EAAE,WAAW,CAAC,EAAE,KAAK,CAAC,SAAS,EAAE,OAAO,CAAC,EAAE,OAAO,CAAC,YAAY,CAAC,KAAK,MAAM,CAAC;IAC5G,IAAI,EAAE,CAAC,KAAK,EAAE,KAAK,CAAC,SAAS,EAAE,WAAW,CAAC,EAAE,KAAK,CAAC,SAAS,EAAE,OAAO,CAAC,EAAE,OAAO,CAAC,YAAY,CAAC,KAAK,MAAM,CAAC;IACzG,OAAO,EAAE,CAAC,EAAE,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC;CAChC;AAED,eAAO,MAAM,KAAK,EAAE,aA8BlB,CAAC;AAEH,wBAAgB,QAAQ;;mBAWa,MAAM;;EAG1C"}
package/dist/index.d.ts CHANGED
@@ -48,6 +48,7 @@ export * from './components/Icon';
48
48
  export * from './components/Text';
49
49
  export * from './components/Alert';
50
50
  export * from './components/Progress';
51
+ export * from './components/PageProgress';
51
52
  export * from './components/Spinner';
52
53
  export * from './components/Skeleton';
53
54
  export * from './components/EmptyState';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,cAAc,gBAAgB,CAAC;AAC/B,YAAY,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAG3D,cAAc,aAAa,CAAC;AAG5B,cAAc,wBAAwB,CAAC;AACvC,cAAc,mBAAmB,CAAC;AAClC,cAAc,qBAAqB,CAAC;AACpC,cAAc,oBAAoB,CAAC;AACnC,cAAc,qBAAqB,CAAC;AAGpC,cAAc,oBAAoB,CAAC;AACnC,cAAc,uBAAuB,CAAC;AACtC,cAAc,qBAAqB,CAAC;AACpC,cAAc,oBAAoB,CAAC;AACnC,cAAc,wBAAwB,CAAC;AACvC,cAAc,uBAAuB,CAAC;AACtC,cAAc,qBAAqB,CAAC;AACpC,cAAc,0BAA0B,CAAC;AACzC,cAAc,0BAA0B,CAAC;AACzC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,oBAAoB,CAAC;AACnC,cAAc,wBAAwB,CAAC;AACvC,cAAc,0BAA0B,CAAC;AACzC,cAAc,uBAAuB,CAAC;AAGtC,cAAc,0BAA0B,CAAC;AACzC,cAAc,qBAAqB,CAAC;AACpC,cAAc,qBAAqB,CAAC;AACpC,cAAc,+BAA+B,CAAC;AAC9C,cAAc,uBAAuB,CAAC;AACtC,cAAc,sBAAsB,CAAC;AACrC,cAAc,oBAAoB,CAAC;AACnC,cAAc,uBAAuB,CAAC;AACtC,cAAc,sBAAsB,CAAC;AACrC,cAAc,mBAAmB,CAAC;AAClC,cAAc,gCAAgC,CAAC;AAC/C,cAAc,wBAAwB,CAAC;AACvC,cAAc,6BAA6B,CAAC;AAC5C,cAAc,yBAAyB,CAAC;AACxC,cAAc,wBAAwB,CAAC;AACvC,cAAc,wBAAwB,CAAC;AAGvC,cAAc,qBAAqB,CAAC;AACpC,cAAc,yBAAyB,CAAC;AACxC,cAAc,wBAAwB,CAAC;AACvC,cAAc,qBAAqB,CAAC;AACpC,cAAc,oBAAoB,CAAC;AACnC,cAAc,mBAAmB,CAAC;AAClC,cAAc,sBAAsB,CAAC;AACrC,cAAc,sBAAsB,CAAC;AACrC,cAAc,mBAAmB,CAAC;AAClC,cAAc,mBAAmB,CAAC;AAGlC,cAAc,oBAAoB,CAAC;AACnC,cAAc,uBAAuB,CAAC;AACtC,cAAc,sBAAsB,CAAC;AACrC,cAAc,uBAAuB,CAAC;AACtC,cAAc,yBAAyB,CAAC;AAGxC,cAAc,oBAAoB,CAAC;AACnC,cAAc,yBAAyB,CAAC;AACxC,cAAc,uBAAuB,CAAC;AACtC,cAAc,mBAAmB,CAAC;AAClC,cAAc,mBAAmB,CAAC;AAClC,cAAc,0BAA0B,CAAC;AACzC,cAAc,qBAAqB,CAAC;AACpC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,8BAA8B,CAAC;AAC7C,cAAc,yBAAyB,CAAC;AACxC,cAAc,6BAA6B,CAAC;AAC5C,cAAc,mBAAmB,CAAC;AAClC,cAAc,qBAAqB,CAAC;AACpC,cAAc,yBAAyB,CAAC;AACxC,cAAc,sBAAsB,CAAC;AACrC,cAAc,wBAAwB,CAAC;AACvC,cAAc,oBAAoB,CAAC;AACnC,cAAc,qBAAqB,CAAC;AACpC,cAAc,uBAAuB,CAAC;AACtC,cAAc,6BAA6B,CAAC;AAC5C,cAAc,uBAAuB,CAAC;AACtC,cAAc,0BAA0B,CAAC;AACzC,cAAc,4BAA4B,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,cAAc,gBAAgB,CAAC;AAC/B,YAAY,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAG3D,cAAc,aAAa,CAAC;AAG5B,cAAc,wBAAwB,CAAC;AACvC,cAAc,mBAAmB,CAAC;AAClC,cAAc,qBAAqB,CAAC;AACpC,cAAc,oBAAoB,CAAC;AACnC,cAAc,qBAAqB,CAAC;AAGpC,cAAc,oBAAoB,CAAC;AACnC,cAAc,uBAAuB,CAAC;AACtC,cAAc,qBAAqB,CAAC;AACpC,cAAc,oBAAoB,CAAC;AACnC,cAAc,wBAAwB,CAAC;AACvC,cAAc,uBAAuB,CAAC;AACtC,cAAc,qBAAqB,CAAC;AACpC,cAAc,0BAA0B,CAAC;AACzC,cAAc,0BAA0B,CAAC;AACzC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,oBAAoB,CAAC;AACnC,cAAc,wBAAwB,CAAC;AACvC,cAAc,0BAA0B,CAAC;AACzC,cAAc,uBAAuB,CAAC;AAGtC,cAAc,0BAA0B,CAAC;AACzC,cAAc,qBAAqB,CAAC;AACpC,cAAc,qBAAqB,CAAC;AACpC,cAAc,+BAA+B,CAAC;AAC9C,cAAc,uBAAuB,CAAC;AACtC,cAAc,sBAAsB,CAAC;AACrC,cAAc,oBAAoB,CAAC;AACnC,cAAc,uBAAuB,CAAC;AACtC,cAAc,sBAAsB,CAAC;AACrC,cAAc,mBAAmB,CAAC;AAClC,cAAc,gCAAgC,CAAC;AAC/C,cAAc,wBAAwB,CAAC;AACvC,cAAc,6BAA6B,CAAC;AAC5C,cAAc,yBAAyB,CAAC;AACxC,cAAc,wBAAwB,CAAC;AACvC,cAAc,wBAAwB,CAAC;AAGvC,cAAc,qBAAqB,CAAC;AACpC,cAAc,yBAAyB,CAAC;AACxC,cAAc,wBAAwB,CAAC;AACvC,cAAc,qBAAqB,CAAC;AACpC,cAAc,oBAAoB,CAAC;AACnC,cAAc,mBAAmB,CAAC;AAClC,cAAc,sBAAsB,CAAC;AACrC,cAAc,sBAAsB,CAAC;AACrC,cAAc,mBAAmB,CAAC;AAClC,cAAc,mBAAmB,CAAC;AAGlC,cAAc,oBAAoB,CAAC;AACnC,cAAc,uBAAuB,CAAC;AACtC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,sBAAsB,CAAC;AACrC,cAAc,uBAAuB,CAAC;AACtC,cAAc,yBAAyB,CAAC;AAGxC,cAAc,oBAAoB,CAAC;AACnC,cAAc,yBAAyB,CAAC;AACxC,cAAc,uBAAuB,CAAC;AACtC,cAAc,mBAAmB,CAAC;AAClC,cAAc,mBAAmB,CAAC;AAClC,cAAc,0BAA0B,CAAC;AACzC,cAAc,qBAAqB,CAAC;AACpC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,8BAA8B,CAAC;AAC7C,cAAc,yBAAyB,CAAC;AACxC,cAAc,6BAA6B,CAAC;AAC5C,cAAc,mBAAmB,CAAC;AAClC,cAAc,qBAAqB,CAAC;AACpC,cAAc,yBAAyB,CAAC;AACxC,cAAc,sBAAsB,CAAC;AACrC,cAAc,wBAAwB,CAAC;AACvC,cAAc,oBAAoB,CAAC;AACnC,cAAc,qBAAqB,CAAC;AACpC,cAAc,uBAAuB,CAAC;AACtC,cAAc,6BAA6B,CAAC;AAC5C,cAAc,uBAAuB,CAAC;AACtC,cAAc,0BAA0B,CAAC;AACzC,cAAc,4BAA4B,CAAC"}
package/dist/index.js CHANGED
@@ -68,6 +68,7 @@ export { OptionPicker } from './components/OptionPicker/OptionPicker.js';
68
68
  export { OtpInput } from './components/OtpInput/OtpInput.js';
69
69
  export { PRICE_GROUP_KEY } from './components/FilterPanel/FilterPanel.types.js';
70
70
  export { PageHeader } from './components/PageHeader/PageHeader.js';
71
+ export { PageProgress } from './components/PageProgress/PageProgress.js';
71
72
  export { Pagination, PaginationContent, PaginationEllipsis, PaginationItem, PaginationLink, PaginationNext, PaginationPrevious, PaginationSummary } from './components/Pagination/Pagination.js';
72
73
  export { Popover, PopoverAnchor, PopoverClose, PopoverContent, PopoverTrigger } from './components/Popover/Popover.js';
73
74
  export { Price, discountPercent } from './components/Price/Price.js';
@@ -4,7 +4,11 @@ export interface AnimationProviderProps {
4
4
  disableAnimations?: boolean;
5
5
  }
6
6
  /**
7
- * Dual-layer animation provider satisfying the requirement for global toggle + component-level overrides.
7
+ * Dual-layer animation provider.
8
+ * Animations are disabled when:
9
+ * - disableAnimations={true} is passed explicitly, OR
10
+ * - the OS/browser has prefers-reduced-motion: reduce set.
11
+ * This is the single place that translates both signals into the DS motion system.
8
12
  */
9
13
  export declare const AnimationProvider: React.FC<AnimationProviderProps>;
10
14
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"AnimationProvider.d.ts","sourceRoot":"","sources":["../../src/providers/AnimationProvider.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAS/B,MAAM,WAAW,sBAAsB;IACrC,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;IAC1B,iBAAiB,CAAC,EAAE,OAAO,CAAC;CAC7B;AAED;;GAEG;AACH,eAAO,MAAM,iBAAiB,EAAE,KAAK,CAAC,EAAE,CAAC,sBAAsB,CAuB9D,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,kBAAkB,QAAO,OASrC,CAAC"}
1
+ {"version":3,"file":"AnimationProvider.d.ts","sourceRoot":"","sources":["../../src/providers/AnimationProvider.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAU/B,MAAM,WAAW,sBAAsB;IACrC,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;IAC1B,iBAAiB,CAAC,EAAE,OAAO,CAAC;CAC7B;AAED;;;;;;GAMG;AACH,eAAO,MAAM,iBAAiB,EAAE,KAAK,CAAC,EAAE,CAAC,sBAAsB,CA0B9D,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,kBAAkB,QAAO,OASrC,CAAC"}
@@ -1,6 +1,7 @@
1
1
  "use client";
2
2
  import { jsx } from 'react/jsx-runtime';
3
3
  import * as React from 'react';
4
+ import { usePrefersReducedMotion } from '@timmbr/hooks';
4
5
  import { useTimmbrConfig } from './TimmbrConfigProvider.js';
5
6
 
6
7
  const AnimationContext = React.createContext(null);
@@ -8,11 +9,13 @@ const AnimationProvider = ({
8
9
  children,
9
10
  disableAnimations = false
10
11
  }) => {
12
+ const prefersReduced = usePrefersReducedMotion();
13
+ const animationsDisabled = disableAnimations || prefersReduced;
11
14
  React.useEffect(() => {
12
15
  if (typeof document !== "undefined") {
13
16
  document.documentElement.setAttribute(
14
17
  "data-animations-disabled",
15
- disableAnimations ? "true" : "false"
18
+ animationsDisabled ? "true" : "false"
16
19
  );
17
20
  }
18
21
  return () => {
@@ -20,8 +23,8 @@ const AnimationProvider = ({
20
23
  document.documentElement.removeAttribute("data-animations-disabled");
21
24
  }
22
25
  };
23
- }, [disableAnimations]);
24
- return /* @__PURE__ */ jsx(AnimationContext.Provider, { value: { globalMotion: !disableAnimations }, children });
26
+ }, [animationsDisabled]);
27
+ return /* @__PURE__ */ jsx(AnimationContext.Provider, { value: { globalMotion: !animationsDisabled }, children });
25
28
  };
26
29
  const useGlobalAnimation = () => {
27
30
  const directContext = React.useContext(AnimationContext);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@timmbr/ui",
3
- "version": "1.11.0",
3
+ "version": "1.11.1",
4
4
  "description": "High-performance, Next.js App Router-compatible UI design system components for Timmbr",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -42,11 +42,11 @@
42
42
  "@radix-ui/react-tooltip": "^1.2.16",
43
43
  "class-variance-authority": "^0.7.1",
44
44
  "input-otp": "^1.5.0",
45
- "@timmbr/hooks": "1.1.0",
46
45
  "@timmbr/icons": "1.6.0",
47
- "@timmbr/theme": "1.3.0",
46
+ "@timmbr/hooks": "1.1.0",
48
47
  "@timmbr/utils": "1.6.0",
49
- "@timmbr/motion": "1.2.4"
48
+ "@timmbr/theme": "1.3.0",
49
+ "@timmbr/motion": "1.2.5"
50
50
  },
51
51
  "peerDependencies": {
52
52
  "next": ">=13.0.0 || >=14.0.0 || >=15.0.0 || >=16.0.0",