@timmbr/ui 1.5.0 → 1.7.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 (258) hide show
  1. package/README.md +12 -10
  2. package/dist/components/Alert/Alert.styles.d.ts +2 -2
  3. package/dist/components/AlertDialog/AlertDialog.d.ts +5 -3
  4. package/dist/components/AlertDialog/AlertDialog.d.ts.map +1 -1
  5. package/dist/components/AlertDialog/AlertDialog.js +21 -8
  6. package/dist/components/AlertDialog/AlertDialog.styles.d.ts +7 -1
  7. package/dist/components/AlertDialog/AlertDialog.styles.d.ts.map +1 -1
  8. package/dist/components/AlertDialog/AlertDialog.styles.js +26 -3
  9. package/dist/components/AlertDialog/AlertDialog.types.d.ts +19 -2
  10. package/dist/components/AlertDialog/AlertDialog.types.d.ts.map +1 -1
  11. package/dist/components/Avatar/Avatar.styles.d.ts +2 -2
  12. package/dist/components/Badge/Badge.styles.d.ts +2 -2
  13. package/dist/components/Badge/Badge.styles.d.ts.map +1 -1
  14. package/dist/components/Badge/Badge.styles.js +3 -1
  15. package/dist/components/Button/Button.d.ts.map +1 -1
  16. package/dist/components/Button/Button.js +6 -0
  17. package/dist/components/Button/Button.styles.d.ts +4 -2
  18. package/dist/components/Button/Button.styles.d.ts.map +1 -1
  19. package/dist/components/Button/Button.styles.js +26 -7
  20. package/dist/components/Card/Card.d.ts.map +1 -1
  21. package/dist/components/Card/Card.js +51 -32
  22. package/dist/components/Card/Card.styles.d.ts +32 -5
  23. package/dist/components/Card/Card.styles.d.ts.map +1 -1
  24. package/dist/components/Card/Card.styles.js +69 -10
  25. package/dist/components/Card/Card.types.d.ts +14 -3
  26. package/dist/components/Card/Card.types.d.ts.map +1 -1
  27. package/dist/components/Checkbox/Checkbox.styles.d.ts +2 -2
  28. package/dist/components/Chip/Chip.styles.d.ts +1 -1
  29. package/dist/components/ConfirmDialog/ConfirmDialog.d.ts +30 -0
  30. package/dist/components/ConfirmDialog/ConfirmDialog.d.ts.map +1 -0
  31. package/dist/components/ConfirmDialog/ConfirmDialog.js +57 -0
  32. package/dist/components/ConfirmDialog/index.d.ts +2 -0
  33. package/dist/components/ConfirmDialog/index.d.ts.map +1 -0
  34. package/dist/components/Container/Container.styles.d.ts +1 -1
  35. package/dist/components/DataList/DataList.d.ts +3 -1
  36. package/dist/components/DataList/DataList.d.ts.map +1 -1
  37. package/dist/components/DataList/DataList.js +53 -15
  38. package/dist/components/DataList/DataList.styles.d.ts +17 -4
  39. package/dist/components/DataList/DataList.styles.d.ts.map +1 -1
  40. package/dist/components/DataList/DataList.styles.js +53 -10
  41. package/dist/components/DataList/DataList.types.d.ts +19 -2
  42. package/dist/components/DataList/DataList.types.d.ts.map +1 -1
  43. package/dist/components/Drawer/Drawer.d.ts +4 -3
  44. package/dist/components/Drawer/Drawer.d.ts.map +1 -1
  45. package/dist/components/Drawer/Drawer.js +33 -6
  46. package/dist/components/Drawer/Drawer.styles.d.ts +4 -0
  47. package/dist/components/Drawer/Drawer.styles.d.ts.map +1 -1
  48. package/dist/components/Drawer/Drawer.styles.js +8 -5
  49. package/dist/components/Drawer/Drawer.types.d.ts +1 -0
  50. package/dist/components/Drawer/Drawer.types.d.ts.map +1 -1
  51. package/dist/components/Dropdown/Dropdown.d.ts.map +1 -1
  52. package/dist/components/Dropdown/Dropdown.js +23 -10
  53. package/dist/components/Dropdown/Dropdown.styles.d.ts +5 -1
  54. package/dist/components/Dropdown/Dropdown.styles.d.ts.map +1 -1
  55. package/dist/components/Dropdown/Dropdown.styles.js +12 -2
  56. package/dist/components/Dropdown/Dropdown.types.d.ts +4 -0
  57. package/dist/components/Dropdown/Dropdown.types.d.ts.map +1 -1
  58. package/dist/components/EmptyState/EmptyState.d.ts.map +1 -1
  59. package/dist/components/EmptyState/EmptyState.js +2 -1
  60. package/dist/components/EmptyState/EmptyState.styles.d.ts +3 -2
  61. package/dist/components/EmptyState/EmptyState.styles.d.ts.map +1 -1
  62. package/dist/components/EmptyState/EmptyState.styles.js +5 -0
  63. package/dist/components/Fieldset/Fieldset.d.ts +14 -0
  64. package/dist/components/Fieldset/Fieldset.d.ts.map +1 -0
  65. package/dist/components/Fieldset/Fieldset.js +24 -0
  66. package/dist/components/Fieldset/index.d.ts +2 -0
  67. package/dist/components/Fieldset/index.d.ts.map +1 -0
  68. package/dist/components/FormActions/FormActions.d.ts +13 -0
  69. package/dist/components/FormActions/FormActions.d.ts.map +1 -0
  70. package/dist/components/FormActions/FormActions.js +24 -0
  71. package/dist/components/FormActions/index.d.ts +2 -0
  72. package/dist/components/FormActions/index.d.ts.map +1 -0
  73. package/dist/components/Grid/Grid.d.ts +3 -1
  74. package/dist/components/Grid/Grid.d.ts.map +1 -1
  75. package/dist/components/Grid/Grid.js +31 -5
  76. package/dist/components/Grid/Grid.styles.d.ts +86 -0
  77. package/dist/components/Grid/Grid.styles.d.ts.map +1 -1
  78. package/dist/components/Grid/Grid.styles.js +85 -1
  79. package/dist/components/Grid/Grid.types.d.ts +31 -3
  80. package/dist/components/Grid/Grid.types.d.ts.map +1 -1
  81. package/dist/components/Heading/Heading.styles.d.ts +2 -2
  82. package/dist/components/Heading/Heading.styles.d.ts.map +1 -1
  83. package/dist/components/Heading/Heading.styles.js +3 -1
  84. package/dist/components/Heading/Heading.types.d.ts +1 -1
  85. package/dist/components/Heading/Heading.types.d.ts.map +1 -1
  86. package/dist/components/Icon/Icon.styles.d.ts +2 -2
  87. package/dist/components/Icon/Icon.styles.d.ts.map +1 -1
  88. package/dist/components/Icon/Icon.styles.js +6 -2
  89. package/dist/components/IconTile/IconTile.d.ts +8 -0
  90. package/dist/components/IconTile/IconTile.d.ts.map +1 -0
  91. package/dist/components/IconTile/IconTile.js +23 -0
  92. package/dist/components/IconTile/IconTile.styles.d.ts +7 -0
  93. package/dist/components/IconTile/IconTile.styles.d.ts.map +1 -0
  94. package/dist/components/IconTile/IconTile.styles.js +24 -0
  95. package/dist/components/IconTile/IconTile.types.d.ts +12 -0
  96. package/dist/components/IconTile/IconTile.types.d.ts.map +1 -0
  97. package/dist/components/IconTile/index.d.ts +4 -0
  98. package/dist/components/IconTile/index.d.ts.map +1 -0
  99. package/dist/components/Inline/Inline.d.ts.map +1 -1
  100. package/dist/components/Inline/Inline.js +10 -2
  101. package/dist/components/Inline/Inline.types.d.ts +6 -1
  102. package/dist/components/Inline/Inline.types.d.ts.map +1 -1
  103. package/dist/components/Input/Input.styles.d.ts +1 -1
  104. package/dist/components/Label/Label.styles.d.ts +1 -1
  105. package/dist/components/LinkButton/LinkButton.d.ts.map +1 -1
  106. package/dist/components/LinkButton/LinkButton.js +2 -0
  107. package/dist/components/LinkButton/LinkButton.styles.d.ts +3 -2
  108. package/dist/components/LinkButton/LinkButton.styles.d.ts.map +1 -1
  109. package/dist/components/LinkButton/LinkButton.styles.js +6 -0
  110. package/dist/components/List/List.d.ts.map +1 -1
  111. package/dist/components/List/List.js +18 -5
  112. package/dist/components/List/List.styles.d.ts +3 -1
  113. package/dist/components/List/List.styles.d.ts.map +1 -1
  114. package/dist/components/List/List.styles.js +4 -3
  115. package/dist/components/List/List.types.d.ts +7 -0
  116. package/dist/components/List/List.types.d.ts.map +1 -1
  117. package/dist/components/MediaCard/MediaCard.d.ts +13 -0
  118. package/dist/components/MediaCard/MediaCard.d.ts.map +1 -0
  119. package/dist/components/MediaCard/MediaCard.js +125 -0
  120. package/dist/components/MediaCard/MediaCard.styles.d.ts +17 -0
  121. package/dist/components/MediaCard/MediaCard.styles.d.ts.map +1 -0
  122. package/dist/components/MediaCard/MediaCard.styles.js +57 -0
  123. package/dist/components/MediaCard/MediaCard.types.d.ts +82 -0
  124. package/dist/components/MediaCard/MediaCard.types.d.ts.map +1 -0
  125. package/dist/components/MediaCard/index.d.ts +4 -0
  126. package/dist/components/MediaCard/index.d.ts.map +1 -0
  127. package/dist/components/NavFooter/NavFooter.styles.d.ts +1 -1
  128. package/dist/components/NavHeader/NavHeader.d.ts.map +1 -1
  129. package/dist/components/NavHeader/NavHeader.js +2 -1
  130. package/dist/components/NavHeader/NavHeader.styles.d.ts +1 -1
  131. package/dist/components/NavHeader/NavHeader.types.d.ts +22 -0
  132. package/dist/components/NavHeader/NavHeader.types.d.ts.map +1 -1
  133. package/dist/components/NavHeader/index.d.ts +1 -1
  134. package/dist/components/NavHeader/index.d.ts.map +1 -1
  135. package/dist/components/NavHeader/subcomponents/NavActions.d.ts +5 -0
  136. package/dist/components/NavHeader/subcomponents/NavActions.d.ts.map +1 -1
  137. package/dist/components/NavHeader/subcomponents/NavActions.js +32 -2
  138. package/dist/components/OtpInput/OtpInput.styles.d.ts +1 -1
  139. package/dist/components/PageHeader/PageHeader.d.ts +8 -0
  140. package/dist/components/PageHeader/PageHeader.d.ts.map +1 -0
  141. package/dist/components/PageHeader/PageHeader.js +55 -0
  142. package/dist/components/PageHeader/PageHeader.styles.d.ts +10 -0
  143. package/dist/components/PageHeader/PageHeader.styles.d.ts.map +1 -0
  144. package/dist/components/PageHeader/PageHeader.styles.js +23 -0
  145. package/dist/components/PageHeader/PageHeader.types.d.ts +24 -0
  146. package/dist/components/PageHeader/PageHeader.types.d.ts.map +1 -0
  147. package/dist/components/PageHeader/index.d.ts +4 -0
  148. package/dist/components/PageHeader/index.d.ts.map +1 -0
  149. package/dist/components/Pagination/Pagination.d.ts +9 -3
  150. package/dist/components/Pagination/Pagination.d.ts.map +1 -1
  151. package/dist/components/Pagination/Pagination.js +60 -39
  152. package/dist/components/Pagination/Pagination.styles.d.ts +1 -1
  153. package/dist/components/Pagination/Pagination.types.d.ts +23 -14
  154. package/dist/components/Pagination/Pagination.types.d.ts.map +1 -1
  155. package/dist/components/Price/Price.d.ts +10 -0
  156. package/dist/components/Price/Price.d.ts.map +1 -0
  157. package/dist/components/Price/Price.js +49 -0
  158. package/dist/components/Price/Price.styles.d.ts +15 -0
  159. package/dist/components/Price/Price.styles.d.ts.map +1 -0
  160. package/dist/components/Price/Price.styles.js +44 -0
  161. package/dist/components/Price/Price.types.d.ts +22 -0
  162. package/dist/components/Price/Price.types.d.ts.map +1 -0
  163. package/dist/components/Price/index.d.ts +4 -0
  164. package/dist/components/Price/index.d.ts.map +1 -0
  165. package/dist/components/Progress/Progress.styles.d.ts +1 -1
  166. package/dist/components/Radio/Radio.styles.d.ts +2 -2
  167. package/dist/components/Rating/Rating.d.ts +5 -0
  168. package/dist/components/Rating/Rating.d.ts.map +1 -0
  169. package/dist/components/Rating/Rating.js +38 -0
  170. package/dist/components/Rating/Rating.styles.d.ts +6 -0
  171. package/dist/components/Rating/Rating.styles.d.ts.map +1 -0
  172. package/dist/components/Rating/Rating.styles.js +13 -0
  173. package/dist/components/Rating/Rating.types.d.ts +18 -0
  174. package/dist/components/Rating/Rating.types.d.ts.map +1 -0
  175. package/dist/components/Rating/index.d.ts +4 -0
  176. package/dist/components/Rating/index.d.ts.map +1 -0
  177. package/dist/components/ResponsiveDialog/ResponsiveDialog.d.ts +29 -0
  178. package/dist/components/ResponsiveDialog/ResponsiveDialog.d.ts.map +1 -0
  179. package/dist/components/ResponsiveDialog/ResponsiveDialog.js +74 -0
  180. package/dist/components/ResponsiveDialog/ResponsiveDialog.types.d.ts +27 -0
  181. package/dist/components/ResponsiveDialog/ResponsiveDialog.types.d.ts.map +1 -0
  182. package/dist/components/ResponsiveDialog/index.d.ts +3 -0
  183. package/dist/components/ResponsiveDialog/index.d.ts.map +1 -0
  184. package/dist/components/SectionNav/SectionNav.d.ts +12 -0
  185. package/dist/components/SectionNav/SectionNav.d.ts.map +1 -0
  186. package/dist/components/SectionNav/SectionNav.js +67 -0
  187. package/dist/components/SectionNav/SectionNav.styles.d.ts +11 -0
  188. package/dist/components/SectionNav/SectionNav.styles.d.ts.map +1 -0
  189. package/dist/components/SectionNav/SectionNav.styles.js +28 -0
  190. package/dist/components/SectionNav/SectionNav.types.d.ts +37 -0
  191. package/dist/components/SectionNav/SectionNav.types.d.ts.map +1 -0
  192. package/dist/components/SectionNav/index.d.ts +4 -0
  193. package/dist/components/SectionNav/index.d.ts.map +1 -0
  194. package/dist/components/Select/Select.styles.d.ts +1 -1
  195. package/dist/components/Spinner/Spinner.styles.d.ts +1 -1
  196. package/dist/components/Stack/Stack.d.ts.map +1 -1
  197. package/dist/components/Stack/Stack.js +16 -1
  198. package/dist/components/Stack/Stack.types.d.ts +14 -1
  199. package/dist/components/Stack/Stack.types.d.ts.map +1 -1
  200. package/dist/components/Stepper/Stepper.d.ts +9 -0
  201. package/dist/components/Stepper/Stepper.d.ts.map +1 -0
  202. package/dist/components/Stepper/Stepper.js +81 -0
  203. package/dist/components/Stepper/Stepper.styles.d.ts +14 -0
  204. package/dist/components/Stepper/Stepper.styles.d.ts.map +1 -0
  205. package/dist/components/Stepper/Stepper.styles.js +40 -0
  206. package/dist/components/Stepper/Stepper.types.d.ts +17 -0
  207. package/dist/components/Stepper/Stepper.types.d.ts.map +1 -0
  208. package/dist/components/Stepper/index.d.ts +4 -0
  209. package/dist/components/Stepper/index.d.ts.map +1 -0
  210. package/dist/components/Steps/Steps.d.ts +9 -0
  211. package/dist/components/Steps/Steps.d.ts.map +1 -0
  212. package/dist/components/Steps/Steps.js +81 -0
  213. package/dist/components/Steps/Steps.styles.d.ts +14 -0
  214. package/dist/components/Steps/Steps.styles.d.ts.map +1 -0
  215. package/dist/components/Steps/Steps.styles.js +40 -0
  216. package/dist/components/Steps/Steps.types.d.ts +17 -0
  217. package/dist/components/Steps/Steps.types.d.ts.map +1 -0
  218. package/dist/components/Steps/index.d.ts +4 -0
  219. package/dist/components/Steps/index.d.ts.map +1 -0
  220. package/dist/components/SubNav/SubNav.d.ts +17 -0
  221. package/dist/components/SubNav/SubNav.d.ts.map +1 -0
  222. package/dist/components/SubNav/SubNav.js +87 -0
  223. package/dist/components/SubNav/SubNav.styles.d.ts +18 -0
  224. package/dist/components/SubNav/SubNav.styles.d.ts.map +1 -0
  225. package/dist/components/SubNav/SubNav.styles.js +33 -0
  226. package/dist/components/SubNav/SubNav.types.d.ts +45 -0
  227. package/dist/components/SubNav/SubNav.types.d.ts.map +1 -0
  228. package/dist/components/SubNav/index.d.ts +4 -0
  229. package/dist/components/SubNav/index.d.ts.map +1 -0
  230. package/dist/components/Switch/Switch.styles.d.ts +2 -2
  231. package/dist/components/Table/Table.styles.d.ts +1 -1
  232. package/dist/components/Tabs/Tabs.d.ts.map +1 -1
  233. package/dist/components/Tabs/Tabs.js +73 -6
  234. package/dist/components/Tabs/Tabs.styles.d.ts +10 -2
  235. package/dist/components/Tabs/Tabs.styles.d.ts.map +1 -1
  236. package/dist/components/Tabs/Tabs.styles.js +17 -2
  237. package/dist/components/Tabs/Tabs.types.d.ts +13 -0
  238. package/dist/components/Tabs/Tabs.types.d.ts.map +1 -1
  239. package/dist/components/Text/Text.d.ts.map +1 -1
  240. package/dist/components/Text/Text.js +4 -0
  241. package/dist/components/Text/Text.styles.d.ts +4 -2
  242. package/dist/components/Text/Text.styles.d.ts.map +1 -1
  243. package/dist/components/Text/Text.styles.js +16 -2
  244. package/dist/components/Text/Text.types.d.ts +1 -1
  245. package/dist/components/Text/Text.types.d.ts.map +1 -1
  246. package/dist/components/Textarea/Textarea.styles.d.ts +1 -1
  247. package/dist/components/VisuallyHidden/VisuallyHidden.d.ts +8 -0
  248. package/dist/components/VisuallyHidden/VisuallyHidden.d.ts.map +1 -0
  249. package/dist/components/VisuallyHidden/VisuallyHidden.js +14 -0
  250. package/dist/components/VisuallyHidden/index.d.ts +2 -0
  251. package/dist/components/VisuallyHidden/index.d.ts.map +1 -0
  252. package/dist/index.d.ts +13 -0
  253. package/dist/index.d.ts.map +1 -1
  254. package/dist/index.js +32 -13
  255. package/dist/utils/gap.d.ts +21 -1
  256. package/dist/utils/gap.d.ts.map +1 -1
  257. package/dist/utils/gap.js +306 -46
  258. package/package.json +5 -5
@@ -0,0 +1,29 @@
1
+ import * as React from 'react';
2
+ import type { ResponsiveDialogContentProps, ResponsiveDialogMode, ResponsiveDialogProps, ResponsiveDialogSectionProps, ResponsiveDialogFormProps } from './ResponsiveDialog.types';
3
+ export declare const RESPONSIVE_DIALOG_BREAKPOINT = "(min-width: 640px)";
4
+ /** Whether the surrounding ResponsiveDialog renders as a `dialog` or a bottom `drawer`. */
5
+ export declare const useResponsiveDialogMode: () => ResponsiveDialogMode;
6
+ /**
7
+ * A centred Dialog on larger screens and a bottom sheet (Drawer) on phones,
8
+ * with one API. Use it for forms and pickers; keep short confirmations in
9
+ * AlertDialog. Before hydration it renders as a dialog.
10
+ */
11
+ export declare function ResponsiveDialog({ breakpoint, children, ...props }: ResponsiveDialogProps): React.JSX.Element;
12
+ export declare namespace ResponsiveDialog {
13
+ var displayName: string;
14
+ }
15
+ export declare const ResponsiveDialogContent: React.ForwardRefExoticComponent<ResponsiveDialogContentProps & React.RefAttributes<HTMLDivElement>>;
16
+ export declare const ResponsiveDialogHeader: React.FC<ResponsiveDialogSectionProps>;
17
+ export declare const ResponsiveDialogBody: React.FC<ResponsiveDialogSectionProps>;
18
+ /** Actions; pinned to the bottom of the sheet on phones (above the keyboard and home bar). */
19
+ export declare const ResponsiveDialogFooter: React.FC<ResponsiveDialogSectionProps>;
20
+ export declare const ResponsiveDialogTitle: React.ForwardRefExoticComponent<Omit<Omit<import("@radix-ui/react-dialog").DialogTitleProps & React.RefAttributes<HTMLHeadingElement>, "ref"> & React.RefAttributes<HTMLHeadingElement>, "ref"> & React.RefAttributes<HTMLHeadingElement>>;
21
+ export declare const ResponsiveDialogDescription: React.ForwardRefExoticComponent<Omit<Omit<import("@radix-ui/react-dialog").DialogDescriptionProps & React.RefAttributes<HTMLParagraphElement>, "ref"> & React.RefAttributes<HTMLParagraphElement>, "ref"> & React.RefAttributes<HTMLParagraphElement>>;
22
+ /**
23
+ * A form that wraps ResponsiveDialogBody + ResponsiveDialogFooter, so the
24
+ * submit button can live in the (pinned) footer and the fields still scroll.
25
+ */
26
+ export declare const ResponsiveDialogForm: React.ForwardRefExoticComponent<ResponsiveDialogFormProps & React.RefAttributes<HTMLFormElement>>;
27
+ /** Same Radix close in both modes. */
28
+ export declare const ResponsiveDialogClose: React.ForwardRefExoticComponent<import("@radix-ui/react-dialog").DialogCloseProps & React.RefAttributes<HTMLButtonElement>>;
29
+ //# sourceMappingURL=ResponsiveDialog.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ResponsiveDialog.d.ts","sourceRoot":"","sources":["../../../src/components/ResponsiveDialog/ResponsiveDialog.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAqB/B,OAAO,KAAK,EACV,4BAA4B,EAC5B,oBAAoB,EACpB,qBAAqB,EACrB,4BAA4B,EAC5B,yBAAyB,EAC1B,MAAM,0BAA0B,CAAC;AAIlC,eAAO,MAAM,4BAA4B,uBAAuB,CAAC;AAIjE,2FAA2F;AAC3F,eAAO,MAAM,uBAAuB,4BAAsC,CAAC;AAE3E;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,EAAE,UAAyC,EAAE,QAAQ,EAAE,GAAG,KAAK,EAAE,EAAE,qBAAqB,qBAUxH;yBAVe,gBAAgB;;;AAahC,eAAO,MAAM,uBAAuB,qGAoBnC,CAAC;AAGF,eAAO,MAAM,sBAAsB,EAAE,KAAK,CAAC,EAAE,CAAC,4BAA4B,CAC0B,CAAC;AAGrG,eAAO,MAAM,oBAAoB,EAAE,KAAK,CAAC,EAAE,CAAC,4BAA4B,CACwB,CAAC;AAGjG,8FAA8F;AAC9F,eAAO,MAAM,sBAAsB,EAAE,KAAK,CAAC,EAAE,CAAC,4BAA4B,CAKvE,CAAC;AAGJ,eAAO,MAAM,qBAAqB,4OAKjC,CAAC;AAGF,eAAO,MAAM,2BAA2B,wPASvC,CAAC;AAGF;;;GAGG;AACH,eAAO,MAAM,oBAAoB,mGAYhC,CAAC;AAGF,sCAAsC;AACtC,eAAO,MAAM,qBAAqB,6HAAc,CAAC"}
@@ -0,0 +1,74 @@
1
+ "use client";
2
+ import { jsx } from 'react/jsx-runtime';
3
+ import * as React from 'react';
4
+ import { useMediaQuery } from '@timmbr/hooks';
5
+ import { cn } from '@timmbr/utils';
6
+ import { DialogClose, Dialog, DialogBody, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle } from '../Dialog/Dialog.js';
7
+ import { DrawerBody, DrawerContent, DrawerDescription, DrawerFooter, DrawerHeader, DrawerTitle } from '../Drawer/Drawer.js';
8
+
9
+ const DIALOG_SIZE = { sm: "max-w-md", md: "max-w-lg", lg: "max-w-2xl" };
10
+ const RESPONSIVE_DIALOG_BREAKPOINT = "(min-width: 640px)";
11
+ const ModeContext = React.createContext("dialog");
12
+ const useResponsiveDialogMode = () => React.useContext(ModeContext);
13
+ function ResponsiveDialog({ breakpoint = RESPONSIVE_DIALOG_BREAKPOINT, children, ...props }) {
14
+ const isSmall = useMediaQuery(`not all and ${breakpoint}`);
15
+ const mode = isSmall ? "drawer" : "dialog";
16
+ return /* @__PURE__ */ jsx(ModeContext.Provider, { value: mode, children: /* @__PURE__ */ jsx(Dialog, { ...props, children }) });
17
+ }
18
+ ResponsiveDialog.displayName = "ResponsiveDialog";
19
+ const ResponsiveDialogContent = React.forwardRef(
20
+ ({ className, dialogClassName, drawerClassName, size = "md", ...props }, ref) => {
21
+ const mode = useResponsiveDialogMode();
22
+ return mode === "drawer" ? /* @__PURE__ */ jsx(
23
+ DrawerContent,
24
+ {
25
+ ref,
26
+ side: "bottom",
27
+ "data-mode": "drawer",
28
+ className: cn(className, drawerClassName),
29
+ ...props
30
+ }
31
+ ) : /* @__PURE__ */ jsx(
32
+ DialogContent,
33
+ {
34
+ ref,
35
+ "data-mode": "dialog",
36
+ className: cn(DIALOG_SIZE[size], className, dialogClassName),
37
+ ...props
38
+ }
39
+ );
40
+ }
41
+ );
42
+ ResponsiveDialogContent.displayName = "ResponsiveDialogContent";
43
+ const ResponsiveDialogHeader = (props) => useResponsiveDialogMode() === "drawer" ? /* @__PURE__ */ jsx(DrawerHeader, { ...props }) : /* @__PURE__ */ jsx(DialogHeader, { ...props });
44
+ ResponsiveDialogHeader.displayName = "ResponsiveDialogHeader";
45
+ const ResponsiveDialogBody = (props) => useResponsiveDialogMode() === "drawer" ? /* @__PURE__ */ jsx(DrawerBody, { ...props }) : /* @__PURE__ */ jsx(DialogBody, { ...props });
46
+ ResponsiveDialogBody.displayName = "ResponsiveDialogBody";
47
+ const ResponsiveDialogFooter = ({ className, ...props }) => useResponsiveDialogMode() === "drawer" ? /* @__PURE__ */ jsx(DrawerFooter, { className: cn("-mx-6 border-t border-border px-6", className), ...props }) : /* @__PURE__ */ jsx(DialogFooter, { className, ...props });
48
+ ResponsiveDialogFooter.displayName = "ResponsiveDialogFooter";
49
+ const ResponsiveDialogTitle = React.forwardRef(
50
+ (props, ref) => useResponsiveDialogMode() === "drawer" ? /* @__PURE__ */ jsx(DrawerTitle, { ref, ...props }) : /* @__PURE__ */ jsx(DialogTitle, { ref, ...props })
51
+ );
52
+ ResponsiveDialogTitle.displayName = "ResponsiveDialogTitle";
53
+ const ResponsiveDialogDescription = React.forwardRef(
54
+ (props, ref) => useResponsiveDialogMode() === "drawer" ? /* @__PURE__ */ jsx(DrawerDescription, { ref, ...props }) : /* @__PURE__ */ jsx(DialogDescription, { ref, ...props })
55
+ );
56
+ ResponsiveDialogDescription.displayName = "ResponsiveDialogDescription";
57
+ const ResponsiveDialogForm = React.forwardRef(
58
+ ({ className, ...props }, ref) => {
59
+ const mode = useResponsiveDialogMode();
60
+ return /* @__PURE__ */ jsx(
61
+ "form",
62
+ {
63
+ ref,
64
+ "data-slot": "responsive-dialog-form",
65
+ className: cn("flex min-h-0 flex-1 flex-col", mode === "drawer" && "gap-4", className),
66
+ ...props
67
+ }
68
+ );
69
+ }
70
+ );
71
+ ResponsiveDialogForm.displayName = "ResponsiveDialogForm";
72
+ const ResponsiveDialogClose = DialogClose;
73
+
74
+ export { RESPONSIVE_DIALOG_BREAKPOINT, ResponsiveDialog, ResponsiveDialogBody, ResponsiveDialogClose, ResponsiveDialogContent, ResponsiveDialogDescription, ResponsiveDialogFooter, ResponsiveDialogForm, ResponsiveDialogHeader, ResponsiveDialogTitle, useResponsiveDialogMode };
@@ -0,0 +1,27 @@
1
+ import type * as React from 'react';
2
+ import type { DialogProps } from '../Dialog/Dialog.types';
3
+ import type { MotionProp } from '../../types/motion';
4
+ export type ResponsiveDialogMode = 'dialog' | 'drawer';
5
+ export interface ResponsiveDialogProps extends DialogProps {
6
+ /**
7
+ * Media query from which the centred dialog is used; below it the content
8
+ * opens as a bottom sheet. Default `(min-width: 640px)` (Tailwind `sm`).
9
+ */
10
+ breakpoint?: string;
11
+ }
12
+ export interface ResponsiveDialogContentProps extends React.HTMLAttributes<HTMLDivElement> {
13
+ /** Dialog width on larger screens: sm (28rem), md (32rem, default), lg (42rem). */
14
+ size?: 'sm' | 'md' | 'lg';
15
+ /** Extra classes in dialog mode only (e.g. `max-w-2xl`). */
16
+ dialogClassName?: string;
17
+ /** Extra classes in bottom-sheet mode only. */
18
+ drawerClassName?: string;
19
+ motion?: MotionProp;
20
+ onOpenAutoFocus?: (event: Event) => void;
21
+ onCloseAutoFocus?: (event: Event) => void;
22
+ onEscapeKeyDown?: (event: KeyboardEvent) => void;
23
+ onInteractOutside?: (event: Event) => void;
24
+ }
25
+ export type ResponsiveDialogSectionProps = React.HTMLAttributes<HTMLDivElement>;
26
+ export type ResponsiveDialogFormProps = React.FormHTMLAttributes<HTMLFormElement>;
27
+ //# sourceMappingURL=ResponsiveDialog.types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ResponsiveDialog.types.d.ts","sourceRoot":"","sources":["../../../src/components/ResponsiveDialog/ResponsiveDialog.types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,KAAK,MAAM,OAAO,CAAC;AACpC,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAC1D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAErD,MAAM,MAAM,oBAAoB,GAAG,QAAQ,GAAG,QAAQ,CAAC;AAEvD,MAAM,WAAW,qBAAsB,SAAQ,WAAW;IACxD;;;OAGG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,4BAA6B,SAAQ,KAAK,CAAC,cAAc,CAAC,cAAc,CAAC;IACxF,mFAAmF;IACnF,IAAI,CAAC,EAAE,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC;IAC1B,4DAA4D;IAC5D,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,+CAA+C;IAC/C,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,MAAM,CAAC,EAAE,UAAU,CAAC;IACpB,eAAe,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;IACzC,gBAAgB,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;IAC1C,eAAe,CAAC,EAAE,CAAC,KAAK,EAAE,aAAa,KAAK,IAAI,CAAC;IACjD,iBAAiB,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;CAC5C;AAED,MAAM,MAAM,4BAA4B,GAAG,KAAK,CAAC,cAAc,CAAC,cAAc,CAAC,CAAC;AAEhF,MAAM,MAAM,yBAAyB,GAAG,KAAK,CAAC,kBAAkB,CAAC,eAAe,CAAC,CAAC"}
@@ -0,0 +1,3 @@
1
+ export * from './ResponsiveDialog';
2
+ export * from './ResponsiveDialog.types';
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/ResponsiveDialog/index.ts"],"names":[],"mappings":"AAAA,cAAc,oBAAoB,CAAC;AACnC,cAAc,0BAA0B,CAAC"}
@@ -0,0 +1,12 @@
1
+ import * as React from 'react';
2
+ import type { SectionNavProps } from './SectionNav.types';
3
+ /** Exact match, or nested under the item (`/orders/1` → `/orders`). */
4
+ export declare function isSectionNavItemActive(href: string, activeHref?: string): boolean;
5
+ /**
6
+ * In-page section navigation (account, settings, help centre…): a vertical
7
+ * list on desktop and a horizontally scrolling row on small screens.
8
+ * Unlike `SideBarNavigation` it's not an app shell: no branding, collapse or
9
+ * full-height frame.
10
+ */
11
+ export declare const SectionNav: React.ForwardRefExoticComponent<SectionNavProps & React.RefAttributes<HTMLElement>>;
12
+ //# sourceMappingURL=SectionNav.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SectionNav.d.ts","sourceRoot":"","sources":["../../../src/components/SectionNav/SectionNav.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAO/B,OAAO,KAAK,EAAuB,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAU/E,uEAAuE;AACvE,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,GAAG,OAAO,CAKjF;AAED;;;;;GAKG;AACH,eAAO,MAAM,UAAU,qFAgEtB,CAAC"}
@@ -0,0 +1,67 @@
1
+ "use client";
2
+ import { jsxs, jsx } from 'react/jsx-runtime';
3
+ import * as React from 'react';
4
+ import { cn } from '@timmbr/utils';
5
+ import { sectionNavItemVariants, sectionNavListVariants, sectionNavFooterVariants } from './SectionNav.styles.js';
6
+
7
+ const DefaultLink = ({ href, className, children, ...rest }) => /* @__PURE__ */ jsx("a", { href, className, ...rest, children });
8
+ const trimSlash = (path) => path.length > 1 ? path.replace(/\/+$/, "") : path;
9
+ function isSectionNavItemActive(href, activeHref) {
10
+ if (!activeHref) return false;
11
+ const item = trimSlash(href);
12
+ const current = trimSlash(activeHref.split(/[?#]/)[0] ?? "");
13
+ return current === item || current.startsWith(`${item}/`);
14
+ }
15
+ const SectionNav = React.forwardRef(
16
+ ({
17
+ items,
18
+ activeHref,
19
+ linkComponent: Link = DefaultLink,
20
+ footer,
21
+ mobileLayout = "scroll",
22
+ className,
23
+ "aria-label": ariaLabel = "Section navigation",
24
+ ...props
25
+ }, ref) => {
26
+ const activeId = React.useMemo(() => {
27
+ const matches = items.filter((item) => isSectionNavItemActive(item.href, activeHref));
28
+ return matches.sort((a, b) => b.href.length - a.href.length)[0]?.id;
29
+ }, [items, activeHref]);
30
+ return /* @__PURE__ */ jsxs(
31
+ "nav",
32
+ {
33
+ ref,
34
+ "aria-label": ariaLabel,
35
+ "data-slot": "section-nav",
36
+ className: cn(
37
+ "flex gap-2 lg:flex-col lg:items-stretch lg:gap-0",
38
+ mobileLayout === "wrap" ? "flex-col items-stretch" : "items-center",
39
+ className
40
+ ),
41
+ ...props,
42
+ children: [
43
+ /* @__PURE__ */ jsx("ul", { className: cn(sectionNavListVariants({ mobileLayout }), "min-w-0 flex-1"), role: "list", children: items.map((item) => {
44
+ const active = item.id === activeId;
45
+ return /* @__PURE__ */ jsx("li", { className: "shrink-0", children: /* @__PURE__ */ jsxs(
46
+ Link,
47
+ {
48
+ href: item.href,
49
+ "aria-current": active ? "page" : void 0,
50
+ className: sectionNavItemVariants({ active }),
51
+ children: [
52
+ item.icon && /* @__PURE__ */ jsx("span", { className: "flex size-5 shrink-0 items-center justify-center", "aria-hidden": "true", children: item.icon }),
53
+ /* @__PURE__ */ jsx("span", { className: "flex-1", children: item.label }),
54
+ item.badge !== void 0 && item.badge !== null && /* @__PURE__ */ jsx("span", { className: "text-caption-lg text-muted-foreground", children: item.badge })
55
+ ]
56
+ }
57
+ ) }, item.id);
58
+ }) }),
59
+ footer && /* @__PURE__ */ jsx("div", { className: sectionNavFooterVariants(), "data-slot": "section-nav-footer", children: footer })
60
+ ]
61
+ }
62
+ );
63
+ }
64
+ );
65
+ SectionNav.displayName = "SectionNav";
66
+
67
+ export { SectionNav, isSectionNavItemActive };
@@ -0,0 +1,11 @@
1
+ import { type VariantProps } from 'class-variance-authority';
2
+ /** Desktop (lg): a vertical list. Small screens: a scrolling row or wrapped lines. */
3
+ export declare const sectionNavListVariants: (props?: ({
4
+ mobileLayout?: "scroll" | "wrap" | null | undefined;
5
+ } & import("class-variance-authority/types").ClassProp) | undefined) => string;
6
+ export declare const sectionNavItemVariants: (props?: ({
7
+ active?: boolean | null | undefined;
8
+ } & import("class-variance-authority/types").ClassProp) | undefined) => string;
9
+ export declare const sectionNavFooterVariants: (props?: import("class-variance-authority/types").ClassProp | undefined) => string;
10
+ export type SectionNavItemVariants = VariantProps<typeof sectionNavItemVariants>;
11
+ //# sourceMappingURL=SectionNav.styles.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SectionNav.styles.d.ts","sourceRoot":"","sources":["../../../src/components/SectionNav/SectionNav.styles.ts"],"names":[],"mappings":"AAAA,OAAO,EAAO,KAAK,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAElE,sFAAsF;AACtF,eAAO,MAAM,sBAAsB;;8EAQjC,CAAC;AAEH,eAAO,MAAM,sBAAsB;;8EAWlC,CAAC;AAEF,eAAO,MAAM,wBAAwB,oFAEpC,CAAC;AAEF,MAAM,MAAM,sBAAsB,GAAG,YAAY,CAAC,OAAO,sBAAsB,CAAC,CAAC"}
@@ -0,0 +1,28 @@
1
+ import { cva } from 'class-variance-authority';
2
+
3
+ const sectionNavListVariants = cva("flex gap-1 lg:flex-col lg:flex-nowrap lg:overflow-visible", {
4
+ variants: {
5
+ mobileLayout: {
6
+ scroll: "overflow-x-auto [scrollbar-width:none] [&::-webkit-scrollbar]:hidden",
7
+ wrap: "flex-wrap"
8
+ }
9
+ },
10
+ defaultVariants: { mobileLayout: "scroll" }
11
+ });
12
+ const sectionNavItemVariants = cva(
13
+ "flex items-center gap-3 whitespace-nowrap rounded-md px-3 py-2 lg:py-2.5 font-sans text-body-2 font-medium transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring",
14
+ {
15
+ variants: {
16
+ active: {
17
+ true: "bg-primary-50 text-primary-700 dark:bg-primary-900 dark:text-primary-100",
18
+ false: "text-grey-700 hover:bg-grey-100 hover:text-foreground dark:text-grey-300 dark:hover:bg-grey-800"
19
+ }
20
+ },
21
+ defaultVariants: { active: false }
22
+ }
23
+ );
24
+ const sectionNavFooterVariants = cva(
25
+ "flex shrink-0 items-center lg:mt-2 lg:border-t lg:border-border lg:pt-2"
26
+ );
27
+
28
+ export { sectionNavFooterVariants, sectionNavItemVariants, sectionNavListVariants };
@@ -0,0 +1,37 @@
1
+ import type * as React from 'react';
2
+ export interface SectionNavItem {
3
+ id: string;
4
+ label: React.ReactNode;
5
+ href: string;
6
+ /** Leading icon (decorative; hidden from screen readers). */
7
+ icon?: React.ReactNode;
8
+ /** Trailing count or tag, e.g. a number of items. */
9
+ badge?: React.ReactNode;
10
+ }
11
+ export interface SectionNavLinkProps {
12
+ href: string;
13
+ className?: string;
14
+ children: React.ReactNode;
15
+ 'aria-current'?: 'page';
16
+ }
17
+ export interface SectionNavProps extends Omit<React.HTMLAttributes<HTMLElement>, 'children'> {
18
+ items: SectionNavItem[];
19
+ /**
20
+ * Current path. An item is active when it equals its `href` or is nested
21
+ * under it (`/account/orders/123` activates `/account/orders`).
22
+ */
23
+ activeHref?: string;
24
+ /** Link to render items with (e.g. `next/link`). Defaults to `<a>`. */
25
+ linkComponent?: React.ComponentType<SectionNavLinkProps>;
26
+ /**
27
+ * Small screens: `scroll` keeps one horizontally scrolling row (good for many
28
+ * short items); `wrap` wraps the items onto several lines so every one stays
29
+ * visible (good for a handful of longer labels).
30
+ */
31
+ mobileLayout?: 'scroll' | 'wrap';
32
+ /** Extra content after the items, e.g. a "Log out" button. */
33
+ footer?: React.ReactNode;
34
+ /** Accessible name of the navigation landmark. */
35
+ 'aria-label'?: string;
36
+ }
37
+ //# sourceMappingURL=SectionNav.types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SectionNav.types.d.ts","sourceRoot":"","sources":["../../../src/components/SectionNav/SectionNav.types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,KAAK,MAAM,OAAO,CAAC;AAEpC,MAAM,WAAW,cAAc;IAC7B,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,KAAK,CAAC,SAAS,CAAC;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,6DAA6D;IAC7D,IAAI,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACvB,qDAAqD;IACrD,KAAK,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;CACzB;AAED,MAAM,WAAW,mBAAmB;IAClC,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;IAC1B,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,eAAgB,SAAQ,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,WAAW,CAAC,EAAE,UAAU,CAAC;IAC1F,KAAK,EAAE,cAAc,EAAE,CAAC;IACxB;;;OAGG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,uEAAuE;IACvE,aAAa,CAAC,EAAE,KAAK,CAAC,aAAa,CAAC,mBAAmB,CAAC,CAAC;IACzD;;;;OAIG;IACH,YAAY,CAAC,EAAE,QAAQ,GAAG,MAAM,CAAC;IACjC,8DAA8D;IAC9D,MAAM,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACzB,kDAAkD;IAClD,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB"}
@@ -0,0 +1,4 @@
1
+ export * from './SectionNav';
2
+ export * from './SectionNav.types';
3
+ export * from './SectionNav.styles';
4
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/SectionNav/index.ts"],"names":[],"mappings":"AAAA,cAAc,cAAc,CAAC;AAC7B,cAAc,oBAAoB,CAAC;AACnC,cAAc,qBAAqB,CAAC"}
@@ -1,7 +1,7 @@
1
1
  import { type VariantProps } from 'class-variance-authority';
2
2
  export declare const selectTriggerVariants: (props?: ({
3
3
  variant?: "filled" | "outline" | null | undefined;
4
- size?: "default" | "sm" | "lg" | "md" | null | undefined;
4
+ size?: "sm" | "md" | "lg" | "default" | null | undefined;
5
5
  isError?: boolean | null | undefined;
6
6
  } & import("class-variance-authority/types").ClassProp) | undefined) => string;
7
7
  export declare const selectContentVariants: (props?: import("class-variance-authority/types").ClassProp | undefined) => string;
@@ -7,7 +7,7 @@ export declare const spinnerVariants: (props?: ({
7
7
  variant?: "default" | "white" | "primary" | "secondary" | "muted" | null | undefined;
8
8
  } & import("class-variance-authority/types").ClassProp) | undefined) => string;
9
9
  export declare const spinnerIconVariants: (props?: ({
10
- size?: "sm" | "lg" | "md" | "xl" | "xs" | null | undefined;
10
+ size?: "sm" | "md" | "lg" | "xl" | "xs" | null | undefined;
11
11
  } & import("class-variance-authority/types").ClassProp) | undefined) => string;
12
12
  export type SpinnerVariants = VariantProps<typeof spinnerVariants> & VariantProps<typeof spinnerIconVariants>;
13
13
  //# sourceMappingURL=Spinner.styles.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"Stack.d.ts","sourceRoot":"","sources":["../../../src/components/Stack/Stack.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAK/B,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAEhD,eAAO,MAAM,KAAK,mFA2CjB,CAAC"}
1
+ {"version":3,"file":"Stack.d.ts","sourceRoot":"","sources":["../../../src/components/Stack/Stack.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAK/B,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAqBhD,eAAO,MAAM,KAAK,mFA4CjB,CAAC"}
@@ -6,11 +6,26 @@ import { cn } from '@timmbr/utils';
6
6
  import { formatGap } from '../../utils/gap.js';
7
7
  import { stackVariants } from './Stack.styles.js';
8
8
 
9
+ const DIRECTION = {
10
+ base: { column: "flex-col", row: "flex-row" },
11
+ sm: { column: "sm:flex-col", row: "sm:flex-row" },
12
+ md: { column: "md:flex-col", row: "md:flex-row" },
13
+ lg: { column: "lg:flex-col", row: "lg:flex-row" }
14
+ };
15
+ function directionClasses(direction) {
16
+ if (!direction) return void 0;
17
+ if (typeof direction === "string") return DIRECTION.base[direction];
18
+ return Object.keys(DIRECTION).map((bp) => {
19
+ const value = direction[bp];
20
+ return value ? DIRECTION[bp][value] : void 0;
21
+ }).filter(Boolean).join(" ");
22
+ }
9
23
  const Stack = React.forwardRef(
10
24
  ({
11
25
  className,
12
26
  style,
13
27
  gap = 4,
28
+ direction,
14
29
  align = "stretch",
15
30
  justify = "start",
16
31
  divider,
@@ -35,7 +50,7 @@ const Stack = React.forwardRef(
35
50
  "data-slot": "stack",
36
51
  "data-testid": "timmbr-stack",
37
52
  style,
38
- className: cn(stackVariants({ align, justify }), gapClass, className),
53
+ className: cn(stackVariants({ align, justify }), directionClasses(direction), gapClass, className),
39
54
  ...props,
40
55
  children: renderChildren()
41
56
  }
@@ -1,10 +1,23 @@
1
1
  import type * as React from 'react';
2
2
  import type { StackVariants } from './Stack.styles';
3
+ import type { GapValue } from '../../utils/gap';
4
+ /** Direction per breakpoint (`base` = all sizes). */
5
+ export interface ResponsiveDirection {
6
+ base?: 'column' | 'row';
7
+ sm?: 'column' | 'row';
8
+ md?: 'column' | 'row';
9
+ lg?: 'column' | 'row';
10
+ }
3
11
  export interface StackProps extends Omit<React.HTMLAttributes<HTMLDivElement>, 'gap'>, Omit<StackVariants, 'gap'> {
4
12
  /**
5
13
  * Gap between items. Translates standard Tailwind tokens, any number (px), or custom string.
6
14
  */
7
- gap?: number | string;
15
+ gap?: GapValue;
16
+ /**
17
+ * Stack direction: a column by default; e.g. `{ sm: 'row' }` lays the
18
+ * items out in a row from the `sm` breakpoint.
19
+ */
20
+ direction?: 'column' | 'row' | ResponsiveDirection;
8
21
  /**
9
22
  * Optional divider element rendered between each child in the stack.
10
23
  */
@@ -1 +1 @@
1
- {"version":3,"file":"Stack.types.d.ts","sourceRoot":"","sources":["../../../src/components/Stack/Stack.types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,KAAK,MAAM,OAAO,CAAC;AACpC,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAEpD,MAAM,WAAW,UACf,SAAQ,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,cAAc,CAAC,EAAE,KAAK,CAAC,EACvD,IAAI,CAAC,aAAa,EAAE,KAAK,CAAC;IAC5B;;OAEG;IACH,GAAG,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACtB;;OAEG;IACH,OAAO,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC1B;;OAEG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB"}
1
+ {"version":3,"file":"Stack.types.d.ts","sourceRoot":"","sources":["../../../src/components/Stack/Stack.types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,KAAK,MAAM,OAAO,CAAC;AACpC,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AACpD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAEhD,qDAAqD;AACrD,MAAM,WAAW,mBAAmB;IAClC,IAAI,CAAC,EAAE,QAAQ,GAAG,KAAK,CAAC;IACxB,EAAE,CAAC,EAAE,QAAQ,GAAG,KAAK,CAAC;IACtB,EAAE,CAAC,EAAE,QAAQ,GAAG,KAAK,CAAC;IACtB,EAAE,CAAC,EAAE,QAAQ,GAAG,KAAK,CAAC;CACvB;AAED,MAAM,WAAW,UACf,SAAQ,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,cAAc,CAAC,EAAE,KAAK,CAAC,EACvD,IAAI,CAAC,aAAa,EAAE,KAAK,CAAC;IAC5B;;OAEG;IACH,GAAG,CAAC,EAAE,QAAQ,CAAC;IACf;;;OAGG;IACH,SAAS,CAAC,EAAE,QAAQ,GAAG,KAAK,GAAG,mBAAmB,CAAC;IACnD;;OAEG;IACH,OAAO,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC1B;;OAEG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB"}
@@ -0,0 +1,9 @@
1
+ import * as React from 'react';
2
+ import type { StepperProps } from './Stepper.types';
3
+ /**
4
+ * Progress through a sequence of steps (order tracking, checkout, onboarding).
5
+ * Steps before `current` are complete; `status="error"` marks the current
6
+ * step as failed (e.g. a cancelled order).
7
+ */
8
+ export declare const Stepper: React.ForwardRefExoticComponent<StepperProps & React.RefAttributes<HTMLOListElement>>;
9
+ //# sourceMappingURL=Stepper.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Stepper.d.ts","sourceRoot":"","sources":["../../../src/components/Stepper/Stepper.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAQ/B,OAAO,KAAK,EAAa,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAQ/D;;;;GAIG;AACH,eAAO,MAAM,OAAO,uFA0EnB,CAAC"}
@@ -0,0 +1,81 @@
1
+ import { jsx, jsxs } from 'react/jsx-runtime';
2
+ import * as React from 'react';
3
+ import { cn } from '@timmbr/utils';
4
+ import { Check, X } from '@timmbr/icons';
5
+ import { stepConnectorVariants, stepIndicatorVariants, stepperVariants } from './Stepper.styles.js';
6
+
7
+ function stateOf(index, current, status) {
8
+ if (index < current) return "complete";
9
+ if (index === current) return status === "error" ? "error" : "current";
10
+ return "upcoming";
11
+ }
12
+ const Stepper = React.forwardRef(
13
+ ({ steps, current, status = "default", orientation = "horizontal", className, ...props }, ref) => /* @__PURE__ */ jsx(
14
+ "ol",
15
+ {
16
+ ref,
17
+ "data-slot": "stepper",
18
+ "data-orientation": orientation,
19
+ className: cn(stepperVariants({ orientation }), className),
20
+ ...props,
21
+ children: steps.map((step, index) => {
22
+ const state = stateOf(index, current, status);
23
+ const isLast = index === steps.length - 1;
24
+ return /* @__PURE__ */ jsxs(
25
+ "li",
26
+ {
27
+ "data-state": state,
28
+ "aria-current": state === "current" || state === "error" ? "step" : void 0,
29
+ className: cn(
30
+ "relative flex min-w-0",
31
+ orientation === "horizontal" ? "flex-1 flex-col items-center text-center" : "gap-3 pb-6 last:pb-0"
32
+ ),
33
+ children: [
34
+ !isLast && /* @__PURE__ */ jsx(
35
+ "span",
36
+ {
37
+ "aria-hidden": "true",
38
+ className: stepConnectorVariants({
39
+ orientation,
40
+ complete: state === "complete"
41
+ })
42
+ }
43
+ ),
44
+ /* @__PURE__ */ jsx("span", { className: stepIndicatorVariants({ state }), "aria-hidden": "true", children: state === "complete" ? /* @__PURE__ */ jsx(Check, { size: 14, strokeWidth: 3 }) : state === "error" ? /* @__PURE__ */ jsx(X, { size: 14, strokeWidth: 3 }) : index + 1 }),
45
+ /* @__PURE__ */ jsxs(
46
+ "span",
47
+ {
48
+ className: cn(
49
+ "min-w-0",
50
+ orientation === "horizontal" ? "mt-2 px-1" : "pt-0.5"
51
+ ),
52
+ children: [
53
+ /* @__PURE__ */ jsxs(
54
+ "span",
55
+ {
56
+ className: cn(
57
+ "block text-body-2 font-medium",
58
+ state === "upcoming" ? "text-muted-foreground" : "text-foreground",
59
+ state === "error" && "text-destructive"
60
+ ),
61
+ children: [
62
+ step.label,
63
+ /* @__PURE__ */ jsx("span", { className: "sr-only", children: state === "complete" ? " (completed)" : state === "error" ? " (failed)" : "" })
64
+ ]
65
+ }
66
+ ),
67
+ step.description && /* @__PURE__ */ jsx("span", { className: "mt-0.5 block text-caption-lg text-muted-foreground", children: step.description })
68
+ ]
69
+ }
70
+ )
71
+ ]
72
+ },
73
+ step.id ?? index
74
+ );
75
+ })
76
+ }
77
+ )
78
+ );
79
+ Stepper.displayName = "Stepper";
80
+
81
+ export { Stepper };
@@ -0,0 +1,14 @@
1
+ import { type VariantProps } from 'class-variance-authority';
2
+ export declare const stepperVariants: (props?: ({
3
+ orientation?: "horizontal" | "vertical" | null | undefined;
4
+ } & import("class-variance-authority/types").ClassProp) | undefined) => string;
5
+ export declare const stepIndicatorVariants: (props?: ({
6
+ state?: "current" | "error" | "complete" | "upcoming" | null | undefined;
7
+ } & import("class-variance-authority/types").ClassProp) | undefined) => string;
8
+ /** Line to the next step, behind the indicators. */
9
+ export declare const stepConnectorVariants: (props?: ({
10
+ orientation?: "horizontal" | "vertical" | null | undefined;
11
+ complete?: boolean | null | undefined;
12
+ } & import("class-variance-authority/types").ClassProp) | undefined) => string;
13
+ export type StepperVariants = VariantProps<typeof stepperVariants>;
14
+ //# sourceMappingURL=Stepper.styles.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Stepper.styles.d.ts","sourceRoot":"","sources":["../../../src/components/Stepper/Stepper.styles.ts"],"names":[],"mappings":"AAAA,OAAO,EAAO,KAAK,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAElE,eAAO,MAAM,eAAe;;8EAQ1B,CAAC;AAEH,eAAO,MAAM,qBAAqB;;8EAajC,CAAC;AAEF,oDAAoD;AACpD,eAAO,MAAM,qBAAqB;;;8EAYhC,CAAC;AAEH,MAAM,MAAM,eAAe,GAAG,YAAY,CAAC,OAAO,eAAe,CAAC,CAAC"}
@@ -0,0 +1,40 @@
1
+ import { cva } from 'class-variance-authority';
2
+
3
+ const stepperVariants = cva("font-sans", {
4
+ variants: {
5
+ orientation: {
6
+ horizontal: "flex items-start",
7
+ vertical: "flex flex-col"
8
+ }
9
+ },
10
+ defaultVariants: { orientation: "horizontal" }
11
+ });
12
+ const stepIndicatorVariants = cva(
13
+ "relative z-10 flex size-7 shrink-0 items-center justify-center rounded-full border-2 text-caption-lg font-semibold tabular-nums transition-colors",
14
+ {
15
+ variants: {
16
+ state: {
17
+ complete: "border-primary bg-primary text-primary-foreground",
18
+ current: "border-primary bg-background text-primary",
19
+ error: "border-destructive bg-destructive text-destructive-foreground",
20
+ upcoming: "border-muted-foreground/40 bg-background text-muted-foreground"
21
+ }
22
+ },
23
+ defaultVariants: { state: "upcoming" }
24
+ }
25
+ );
26
+ const stepConnectorVariants = cva("absolute", {
27
+ variants: {
28
+ orientation: {
29
+ horizontal: "left-1/2 top-3.5 h-0.5 w-full",
30
+ vertical: "left-3.5 top-7 h-full w-0.5 -translate-x-1/2"
31
+ },
32
+ complete: {
33
+ true: "bg-primary",
34
+ false: "bg-border"
35
+ }
36
+ },
37
+ defaultVariants: { orientation: "horizontal", complete: false }
38
+ });
39
+
40
+ export { stepConnectorVariants, stepIndicatorVariants, stepperVariants };
@@ -0,0 +1,17 @@
1
+ import type * as React from 'react';
2
+ export type StepState = 'complete' | 'current' | 'error' | 'upcoming';
3
+ export interface StepItem {
4
+ id?: string;
5
+ label: React.ReactNode;
6
+ /** Secondary line, e.g. a date. */
7
+ description?: React.ReactNode;
8
+ }
9
+ export interface StepperProps extends React.OlHTMLAttributes<HTMLOListElement> {
10
+ steps: StepItem[];
11
+ /** Index of the current step. Steps before it are complete. */
12
+ current: number;
13
+ /** `error` marks the current step as failed. */
14
+ status?: 'default' | 'error';
15
+ orientation?: 'horizontal' | 'vertical';
16
+ }
17
+ //# sourceMappingURL=Stepper.types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Stepper.types.d.ts","sourceRoot":"","sources":["../../../src/components/Stepper/Stepper.types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,KAAK,MAAM,OAAO,CAAC;AAEpC,MAAM,MAAM,SAAS,GAAG,UAAU,GAAG,SAAS,GAAG,OAAO,GAAG,UAAU,CAAC;AAEtE,MAAM,WAAW,QAAQ;IACvB,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,KAAK,CAAC,SAAS,CAAC;IACvB,mCAAmC;IACnC,WAAW,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;CAC/B;AAED,MAAM,WAAW,YAAa,SAAQ,KAAK,CAAC,gBAAgB,CAAC,gBAAgB,CAAC;IAC5E,KAAK,EAAE,QAAQ,EAAE,CAAC;IAClB,+DAA+D;IAC/D,OAAO,EAAE,MAAM,CAAC;IAChB,gDAAgD;IAChD,MAAM,CAAC,EAAE,SAAS,GAAG,OAAO,CAAC;IAC7B,WAAW,CAAC,EAAE,YAAY,GAAG,UAAU,CAAC;CACzC"}
@@ -0,0 +1,4 @@
1
+ export * from './Stepper';
2
+ export * from './Stepper.types';
3
+ export * from './Stepper.styles';
4
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/Stepper/index.ts"],"names":[],"mappings":"AAAA,cAAc,WAAW,CAAC;AAC1B,cAAc,iBAAiB,CAAC;AAChC,cAAc,kBAAkB,CAAC"}
@@ -0,0 +1,9 @@
1
+ import * as React from 'react';
2
+ import type { StepsProps } from './Steps.types';
3
+ /**
4
+ * Progress through a sequence of steps (order tracking, checkout, onboarding).
5
+ * Steps before `current` are complete; `status="error"` marks the current
6
+ * step as failed (e.g. a cancelled order).
7
+ */
8
+ export declare const Steps: React.ForwardRefExoticComponent<StepsProps & React.RefAttributes<HTMLOListElement>>;
9
+ //# sourceMappingURL=Steps.d.ts.map