@vygruppen/spor-react 11.3.9 → 12.0.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 (322) hide show
  1. package/.turbo/turbo-build.log +32 -11
  2. package/.turbo/turbo-typegen.log +23 -0
  3. package/CHANGELOG.md +245 -0
  4. package/dist/index.d.mts +2552 -8319
  5. package/dist/index.d.ts +2552 -8319
  6. package/dist/index.js +9609 -8607
  7. package/dist/index.js.map +1 -1
  8. package/dist/index.mjs +9487 -8454
  9. package/dist/index.mjs.map +1 -1
  10. package/package.json +21 -13
  11. package/src/accordion/Accordion.tsx +96 -45
  12. package/src/accordion/Expandable.tsx +54 -127
  13. package/src/accordion/helpers.ts +31 -0
  14. package/src/accordion/types.ts +60 -0
  15. package/src/alert/Alert.tsx +101 -0
  16. package/src/alert/AlertIcon.tsx +63 -45
  17. package/src/alert/ExpandableAlert.tsx +96 -64
  18. package/src/alert/ServiceAlert.tsx +127 -125
  19. package/src/alert/{index.tsx → index.ts} +1 -2
  20. package/src/breadcrumb/Breadcrumb.tsx +39 -24
  21. package/src/button/Button.tsx +86 -105
  22. package/src/button/ButtonGroup.tsx +45 -20
  23. package/src/button/Clipboard.tsx +82 -0
  24. package/src/button/CloseButton.tsx +4 -3
  25. package/src/button/FloatingActionButton.tsx +35 -41
  26. package/src/button/IconButton.tsx +34 -30
  27. package/src/button/index.tsx +1 -0
  28. package/src/color-mode/color-mode.tsx +75 -0
  29. package/src/color-mode/index.ts +1 -0
  30. package/src/datepicker/Calendar.tsx +17 -8
  31. package/src/datepicker/CalendarCell.tsx +20 -13
  32. package/src/datepicker/CalendarGrid.tsx +18 -10
  33. package/src/datepicker/CalendarHeader.tsx +2 -0
  34. package/src/datepicker/CalendarNavigationButton.tsx +1 -0
  35. package/src/datepicker/CalendarTriggerButton.tsx +43 -45
  36. package/src/datepicker/DateField.tsx +21 -12
  37. package/src/datepicker/DatePicker.tsx +61 -58
  38. package/src/datepicker/DateRangePicker.tsx +52 -58
  39. package/src/datepicker/DateTimeSegment.tsx +13 -5
  40. package/src/datepicker/RangeCalendar.tsx +13 -7
  41. package/src/datepicker/StyledField.tsx +25 -17
  42. package/src/datepicker/TimeField.tsx +10 -8
  43. package/src/datepicker/TimePicker.tsx +48 -45
  44. package/src/datepicker/types.ts +5 -0
  45. package/src/dialog/Dialog.tsx +56 -0
  46. package/src/dialog/Drawer.tsx +187 -0
  47. package/src/dialog/index.ts +2 -0
  48. package/src/dialog/types.ts +26 -0
  49. package/src/image/index.tsx +2 -2
  50. package/src/index.tsx +5 -3
  51. package/src/input/AttachedInputs.tsx +17 -42
  52. package/src/input/CardSelect.tsx +75 -162
  53. package/src/input/Checkbox.tsx +30 -6
  54. package/src/input/CheckboxGroup.tsx +25 -16
  55. package/src/input/ChoiceChip.tsx +58 -77
  56. package/src/input/Combobox.tsx +172 -172
  57. package/src/input/CountryCodeSelect.tsx +42 -28
  58. package/src/input/Dialog.tsx +1 -0
  59. package/src/input/Field.tsx +71 -0
  60. package/src/input/Fieldset.tsx +7 -0
  61. package/src/input/Input.tsx +68 -73
  62. package/src/input/InputGroup.tsx +66 -0
  63. package/src/input/ListBox.tsx +83 -70
  64. package/src/input/NativeSelect.tsx +68 -33
  65. package/src/input/NumericStepper.tsx +173 -171
  66. package/src/input/PasswordInput.tsx +99 -52
  67. package/src/input/PhoneNumberInput.tsx +69 -72
  68. package/src/input/Popover.tsx +1 -0
  69. package/src/input/Radio.tsx +37 -17
  70. package/src/input/SearchInput.tsx +24 -86
  71. package/src/input/Select.tsx +237 -0
  72. package/src/input/Switch.tsx +60 -18
  73. package/src/input/Textarea.tsx +53 -101
  74. package/src/input/{index.tsx → index.ts} +2 -8
  75. package/src/layout/PressableCard.tsx +12 -21
  76. package/src/layout/RadioCard.tsx +68 -100
  77. package/src/layout/Separator.tsx +32 -0
  78. package/src/layout/StaticCard.tsx +13 -33
  79. package/src/layout/index.tsx +3 -7
  80. package/src/linjetag/InfoTag.tsx +16 -9
  81. package/src/linjetag/LineIcon.tsx +74 -28
  82. package/src/linjetag/TravelTag.tsx +38 -27
  83. package/src/link/TextLink.tsx +25 -16
  84. package/src/list/index.tsx +24 -2
  85. package/src/loader/ClientOnly.tsx +8 -7
  86. package/src/loader/ColorInlineLoader.tsx +4 -3
  87. package/src/loader/ColorSpinner.tsx +5 -4
  88. package/src/loader/ContentLoader.tsx +6 -4
  89. package/src/loader/DarkFullScreenLoader.tsx +11 -3
  90. package/src/loader/DarkInlineLoader.tsx +5 -3
  91. package/src/loader/DarkSpinner.tsx +7 -3
  92. package/src/loader/LightFullScreenLoader.tsx +11 -3
  93. package/src/loader/LightInlineLoader.tsx +11 -3
  94. package/src/loader/LightSpinner.tsx +5 -3
  95. package/src/loader/Lottie.tsx +3 -3
  96. package/src/loader/ProgressBar.tsx +83 -84
  97. package/src/loader/ProgressLoader.tsx +120 -75
  98. package/src/loader/Skeleton.tsx +94 -19
  99. package/src/loader/index.tsx +0 -2
  100. package/src/loader/useHydrated.tsx +1 -0
  101. package/src/loader/useRotatingLabel.tsx +2 -1
  102. package/src/logo/CargonetLogo.tsx +89 -89
  103. package/src/logo/VyLogo.tsx +61 -42
  104. package/src/logo/VyLogoPride.tsx +137 -139
  105. package/src/media-controller/JumpButton.tsx +48 -38
  106. package/src/media-controller/PlayPauseButton.tsx +31 -29
  107. package/src/media-controller/SkipButton.tsx +38 -37
  108. package/src/nudge/Nudge.tsx +195 -123
  109. package/src/nudge/index.tsx +0 -1
  110. package/src/pagination/Pagination.tsx +221 -118
  111. package/src/pagination/types.ts +23 -0
  112. package/src/popover/index.tsx +67 -0
  113. package/src/progress-indicator/ProgressDot.tsx +11 -10
  114. package/src/progress-indicator/ProgressIndicator.tsx +28 -15
  115. package/src/provider/SporProvider.tsx +17 -14
  116. package/src/stepper/Stepper.tsx +88 -85
  117. package/src/stepper/StepperContext.tsx +2 -1
  118. package/src/stepper/StepperStep.tsx +28 -21
  119. package/src/tab/Tabs.tsx +62 -12
  120. package/src/tab/index.tsx +1 -9
  121. package/src/table/Table.tsx +35 -30
  122. package/src/table/index.tsx +11 -7
  123. package/src/theme/brand.ts +7 -0
  124. package/src/theme/index.ts +45 -37
  125. package/src/theme/recipes/attached-inputs.ts +43 -0
  126. package/src/theme/recipes/badge.ts +104 -0
  127. package/src/theme/recipes/button.ts +124 -0
  128. package/src/theme/recipes/choice-chip.ts +144 -0
  129. package/src/theme/recipes/close-button.ts +41 -0
  130. package/src/theme/recipes/code.ts +14 -0
  131. package/src/theme/recipes/group.ts +19 -0
  132. package/src/theme/recipes/index.ts +29 -0
  133. package/src/theme/recipes/input.ts +89 -0
  134. package/src/theme/recipes/link.ts +64 -0
  135. package/src/theme/recipes/nudge.ts +12 -0
  136. package/src/theme/recipes/pressable-card.ts +83 -0
  137. package/src/theme/recipes/progress-loader.ts +14 -0
  138. package/src/theme/recipes/separator.ts +85 -0
  139. package/src/theme/recipes/skeleton.ts +57 -0
  140. package/src/theme/recipes/static-card.ts +39 -0
  141. package/src/theme/recipes/textarea.ts +27 -0
  142. package/src/theme/semantic-tokens/colors.ts +22 -0
  143. package/src/theme/semantic-tokens/index.ts +24 -0
  144. package/src/theme/semantic-tokens/radii.ts +14 -0
  145. package/src/theme/semantic-tokens/shadows.ts +17 -0
  146. package/src/theme/slot-recipes/accordion.ts +131 -0
  147. package/src/theme/slot-recipes/alert-expandable.ts +133 -0
  148. package/src/theme/slot-recipes/alert-service.ts +66 -0
  149. package/src/theme/slot-recipes/alert.ts +72 -0
  150. package/src/theme/slot-recipes/anatomy.ts +269 -0
  151. package/src/theme/slot-recipes/breadcrumb.ts +61 -0
  152. package/src/theme/slot-recipes/checkbox.ts +89 -0
  153. package/src/theme/slot-recipes/datepicker.ts +214 -0
  154. package/src/theme/slot-recipes/dialog.ts +221 -0
  155. package/src/theme/slot-recipes/drawer.ts +205 -0
  156. package/src/theme/slot-recipes/field.ts +79 -0
  157. package/src/theme/slot-recipes/floating-action-button.ts +131 -0
  158. package/src/theme/slot-recipes/index.ts +65 -0
  159. package/src/theme/slot-recipes/info-tag.ts +62 -0
  160. package/src/theme/slot-recipes/line-icon.ts +140 -0
  161. package/src/theme/slot-recipes/list.ts +45 -0
  162. package/src/theme/slot-recipes/listbox.ts +72 -0
  163. package/src/theme/slot-recipes/media-controller-button.ts +131 -0
  164. package/src/theme/slot-recipes/native-select.ts +54 -0
  165. package/src/theme/slot-recipes/numeric-stepper.ts +65 -0
  166. package/src/theme/slot-recipes/pagination.ts +41 -0
  167. package/src/theme/slot-recipes/popover.ts +78 -0
  168. package/src/theme/slot-recipes/progress-bar.ts +39 -0
  169. package/src/theme/slot-recipes/progress-indicator.ts +22 -0
  170. package/src/theme/slot-recipes/radio-card.ts +112 -0
  171. package/src/theme/slot-recipes/radio.ts +80 -0
  172. package/src/theme/slot-recipes/select.ts +243 -0
  173. package/src/theme/slot-recipes/stepper.ts +92 -0
  174. package/src/theme/slot-recipes/switch.ts +147 -0
  175. package/src/theme/slot-recipes/table.ts +200 -0
  176. package/src/theme/slot-recipes/tabs.ts +169 -0
  177. package/src/theme/slot-recipes/toast.ts +56 -0
  178. package/src/theme/slot-recipes/travel-tag.ts +192 -0
  179. package/src/theme/tokens/animation-styles.ts +50 -0
  180. package/src/theme/tokens/animations.ts +22 -0
  181. package/src/theme/tokens/aspect-ratios.ts +22 -0
  182. package/src/theme/tokens/blurs.ts +28 -0
  183. package/src/theme/tokens/borders.ts +26 -0
  184. package/src/theme/{foundations → tokens}/breakpoints.ts +0 -1
  185. package/src/theme/tokens/colors.ts +10 -0
  186. package/src/theme/tokens/config.ts +10 -0
  187. package/src/theme/tokens/cursor.ts +28 -0
  188. package/src/theme/tokens/durations.ts +25 -0
  189. package/src/theme/tokens/easings.ts +16 -0
  190. package/src/theme/tokens/font-sizes.ts +30 -0
  191. package/src/theme/tokens/font-weights.ts +31 -0
  192. package/src/theme/tokens/fonts.ts +8 -0
  193. package/src/theme/tokens/global-css.ts +18 -0
  194. package/src/theme/tokens/index.ts +37 -0
  195. package/src/theme/tokens/keyframes.ts +255 -0
  196. package/src/theme/tokens/letter-spacings.ts +19 -0
  197. package/src/theme/tokens/line-heights.ts +19 -0
  198. package/src/theme/tokens/radii.ts +13 -0
  199. package/src/theme/tokens/sizes.ts +51 -0
  200. package/src/theme/tokens/spacing.ts +20 -0
  201. package/src/theme/tokens/text-styles.ts +89 -0
  202. package/src/theme/tokens/z-index.ts +17 -0
  203. package/src/theme/utils/accent-utils.ts +8 -21
  204. package/src/theme/utils/bg-utils.ts +4 -6
  205. package/src/theme/utils/brand-utils.ts +6 -19
  206. package/src/theme/utils/core-utils.ts +91 -0
  207. package/src/theme/utils/floating-utils.ts +20 -39
  208. package/src/theme/utils/ghost-utils.ts +7 -21
  209. package/src/theme/utils/input-utils.ts +32 -37
  210. package/src/theme/utils/outline-utils.ts +4 -11
  211. package/src/theme/utils/surface-utils.ts +5 -19
  212. package/src/theme/utils/types.ts +1 -0
  213. package/src/toast/index.tsx +1 -1
  214. package/src/toast/toast.tsx +105 -0
  215. package/src/transition/index.ts +2 -8
  216. package/src/typography/Badge.tsx +15 -61
  217. package/src/typography/Code.tsx +16 -28
  218. package/src/typography/Heading.tsx +34 -19
  219. package/src/typography/Text.tsx +9 -6
  220. package/src/typography/{index.tsx → index.ts} +1 -0
  221. package/src/util/externals.tsx +13 -27
  222. package/tsconfig.json +5 -1
  223. package/src/accordion/Accordion.test.tsx +0 -20
  224. package/src/alert/BaseAlert.test.tsx +0 -37
  225. package/src/alert/BaseAlert.tsx +0 -34
  226. package/src/alert/ClosableAlert.test.tsx +0 -37
  227. package/src/alert/ClosableAlert.tsx +0 -85
  228. package/src/alert/ExpandableAlert.test.tsx +0 -84
  229. package/src/alert/StaticAlert.tsx +0 -33
  230. package/src/button/Button.test.tsx +0 -23
  231. package/src/datepicker/TimePicker.test.tsx +0 -74
  232. package/src/input/FormControl.tsx +0 -2
  233. package/src/input/FormErrorMessage.tsx +0 -95
  234. package/src/input/FormLabel.tsx +0 -11
  235. package/src/input/InfoSelect.tsx +0 -274
  236. package/src/input/InputElement.tsx +0 -44
  237. package/src/input/RadioGroup.tsx +0 -47
  238. package/src/layout/Divider.tsx +0 -27
  239. package/src/layout/RadioCardGroup.tsx +0 -79
  240. package/src/layout/Stack.tsx +0 -42
  241. package/src/loader/SkeletonCircle.tsx +0 -13
  242. package/src/loader/SkeletonText.tsx +0 -14
  243. package/src/media-controller/index.test.tsx +0 -59
  244. package/src/modal/Drawer.tsx +0 -120
  245. package/src/modal/FullScreenDrawer.tsx +0 -239
  246. package/src/modal/Modal.tsx +0 -15
  247. package/src/modal/ModalHeader.tsx +0 -31
  248. package/src/modal/SimpleDrawer.tsx +0 -51
  249. package/src/modal/index.tsx +0 -5
  250. package/src/nudge/WizardNudge.tsx +0 -107
  251. package/src/theme/components/accordion.ts +0 -102
  252. package/src/theme/components/alert-expandable.ts +0 -125
  253. package/src/theme/components/alert-service.ts +0 -98
  254. package/src/theme/components/alert.ts +0 -71
  255. package/src/theme/components/badge.ts +0 -109
  256. package/src/theme/components/breadcrumb.ts +0 -60
  257. package/src/theme/components/button.ts +0 -125
  258. package/src/theme/components/card-select.ts +0 -117
  259. package/src/theme/components/checkbox.ts +0 -88
  260. package/src/theme/components/choice-chip.ts +0 -161
  261. package/src/theme/components/close-button.ts +0 -48
  262. package/src/theme/components/code.ts +0 -17
  263. package/src/theme/components/datepicker.ts +0 -198
  264. package/src/theme/components/divider.ts +0 -50
  265. package/src/theme/components/drawer.ts +0 -95
  266. package/src/theme/components/fab.ts +0 -109
  267. package/src/theme/components/form-label.ts +0 -17
  268. package/src/theme/components/form.ts +0 -27
  269. package/src/theme/components/index.ts +0 -45
  270. package/src/theme/components/info-select.ts +0 -85
  271. package/src/theme/components/info-tag.ts +0 -63
  272. package/src/theme/components/input.ts +0 -28
  273. package/src/theme/components/line-icon.ts +0 -129
  274. package/src/theme/components/link.ts +0 -78
  275. package/src/theme/components/list.ts +0 -23
  276. package/src/theme/components/listbox.ts +0 -77
  277. package/src/theme/components/media-controller-button.ts +0 -97
  278. package/src/theme/components/modal.ts +0 -96
  279. package/src/theme/components/numeric-stepper.ts +0 -65
  280. package/src/theme/components/pagination.ts +0 -74
  281. package/src/theme/components/popover.ts +0 -68
  282. package/src/theme/components/pressable-card.ts +0 -72
  283. package/src/theme/components/progress-bar.ts +0 -47
  284. package/src/theme/components/progress-indicator.ts +0 -44
  285. package/src/theme/components/radio-card.ts +0 -134
  286. package/src/theme/components/radio.ts +0 -68
  287. package/src/theme/components/select.ts +0 -74
  288. package/src/theme/components/skeleton.ts +0 -40
  289. package/src/theme/components/static-card.ts +0 -82
  290. package/src/theme/components/stepper.ts +0 -100
  291. package/src/theme/components/switch.ts +0 -112
  292. package/src/theme/components/table.ts +0 -161
  293. package/src/theme/components/tabs.ts +0 -135
  294. package/src/theme/components/textarea.ts +0 -33
  295. package/src/theme/components/toast.ts +0 -28
  296. package/src/theme/components/travel-tag.ts +0 -256
  297. package/src/theme/foundations/borders.ts +0 -11
  298. package/src/theme/foundations/colors.ts +0 -12
  299. package/src/theme/foundations/config.ts +0 -5
  300. package/src/theme/foundations/fontSizes.ts +0 -29
  301. package/src/theme/foundations/fontWeights.ts +0 -5
  302. package/src/theme/foundations/fonts.ts +0 -7
  303. package/src/theme/foundations/index.ts +0 -15
  304. package/src/theme/foundations/lineHeights.ts +0 -6
  305. package/src/theme/foundations/radii.ts +0 -12
  306. package/src/theme/foundations/shadows.ts +0 -8
  307. package/src/theme/foundations/sizes.ts +0 -36
  308. package/src/theme/foundations/spacing.ts +0 -31
  309. package/src/theme/foundations/styles.ts +0 -12
  310. package/src/theme/foundations/textStyles.ts +0 -74
  311. package/src/theme/foundations/zIndices.ts +0 -17
  312. package/src/theme/utils/base-utils.ts +0 -104
  313. package/src/theme/utils/focus-utils.ts +0 -10
  314. package/src/toast/ActionToast.test.tsx +0 -22
  315. package/src/toast/ActionToast.tsx +0 -28
  316. package/src/toast/BaseToast.test.tsx +0 -27
  317. package/src/toast/BaseToast.tsx +0 -75
  318. package/src/toast/ClosableToast.test.tsx +0 -17
  319. package/src/toast/ClosableToast.tsx +0 -40
  320. package/src/toast/useToast.tsx +0 -121
  321. package/src/tooltip/Tooltip.tsx +0 -70
  322. package/src/tooltip/index.tsx +0 -1
@@ -1,46 +1,59 @@
1
+ "use client";
2
+ import { Field } from "@/input/Field";
1
3
  import {
2
4
  Box,
3
5
  BoxProps,
4
- FocusLock,
5
- Popover,
6
+ Popover as ChakraPopover,
6
7
  PopoverAnchor,
7
- PopoverArrow,
8
- PopoverBody,
9
- PopoverContent,
10
- PopoverTrigger,
11
8
  Portal,
12
- InputGroup,
13
- ResponsiveValue,
14
- useFormControlContext,
15
- useMultiStyleConfig,
9
+ RecipeVariantProps,
10
+ useFieldContext,
11
+ useSlotRecipe,
16
12
  } from "@chakra-ui/react";
17
- import { DateValue } from "@internationalized/date";
18
- import React, { ReactNode, forwardRef, useId, useRef } from "react";
19
- import { AriaDatePickerProps, I18nProvider, useDatePicker } from "react-aria";
13
+ import React, {
14
+ PropsWithChildren,
15
+ ReactNode,
16
+ forwardRef,
17
+ useId,
18
+ useRef,
19
+ } from "react";
20
+ import {
21
+ AriaDatePickerProps,
22
+ DateValue,
23
+ I18nProvider,
24
+ useDatePicker,
25
+ } from "react-aria";
20
26
  import { useDatePickerState } from "react-stately";
21
- import { FormErrorMessage } from "..";
27
+ import { datePickerSlotRecipe } from "../theme/slot-recipes/datepicker";
22
28
  import { Calendar } from "./Calendar";
23
29
  import { CalendarTriggerButton } from "./CalendarTriggerButton";
24
30
  import { DateField } from "./DateField";
25
31
  import { StyledField } from "./StyledField";
32
+ import { CalendarVariants } from "./types";
26
33
  import { useCurrentLocale } from "./utils";
27
34
 
35
+ export type DatePickerVariantProps = RecipeVariantProps<
36
+ typeof datePickerSlotRecipe
37
+ >;
38
+
28
39
  type DatePickerProps = Omit<AriaDatePickerProps<DateValue>, "onChange"> &
29
- Pick<BoxProps, "minHeight" | "width"> & {
30
- variant: ResponsiveValue<"base" | "floating" | "ghost">;
40
+ Pick<BoxProps, "minHeight" | "width"> &
41
+ PropsWithChildren<DatePickerVariantProps> &
42
+ CalendarVariants & {
31
43
  name?: string;
32
44
  showYearNavigation?: boolean;
33
45
  withPortal?: boolean;
34
46
  onChange?: (value: DateValue | null) => void;
47
+ errorMessage?: ReactNode;
35
48
  };
36
49
 
37
50
  /**
38
51
  * A date picker component.
39
52
  *
40
- * There are three different variants – `base`, `floating` and `ghost`.
53
+ * There are three different variants – `core`, `floating` and `ghost`.
41
54
  *
42
55
  * ```tsx
43
- * <DatePicker label="Dato" variant="base" />
56
+ * <DatePicker label="Dato" variant="core" />
44
57
  * ```
45
58
  */
46
59
 
@@ -57,33 +70,31 @@ export const DatePicker = forwardRef<HTMLDivElement, DatePickerProps>(
57
70
  },
58
71
  externalRef,
59
72
  ) => {
60
- const formControlProps = useFormControlContext();
73
+ const chakraFieldProps = useFieldContext();
61
74
  const state = useDatePickerState({
62
75
  ...props,
63
76
  shouldCloseOnSelect: true,
64
77
  errorMessage,
65
- isRequired: props.isRequired ?? formControlProps?.isRequired,
66
- validationState: formControlProps?.isInvalid ? "invalid" : "valid",
78
+ isRequired: props.isRequired ?? chakraFieldProps?.required,
79
+ validationState: chakraFieldProps?.invalid ? "invalid" : "valid",
67
80
  });
68
81
  const internalRef = useRef<HTMLDivElement>(null);
69
82
  const ref = externalRef ?? internalRef;
70
- const {
71
- labelProps,
72
- fieldProps,
73
- buttonProps,
74
- dialogProps,
75
- calendarProps,
76
- errorMessageProps,
77
- } = useDatePicker(
78
- props,
79
- state,
80
- ref as React.MutableRefObject<HTMLDivElement>,
81
- );
83
+ const { labelProps, fieldProps, buttonProps, dialogProps, calendarProps } =
84
+ useDatePicker(
85
+ props,
86
+ state,
87
+ ref as React.MutableRefObject<HTMLDivElement>,
88
+ );
82
89
 
83
90
  const labelId = `label-${useId()}`;
84
91
  const inputGroupId = `input-group-${useId()}`;
85
92
 
86
- const styles = useMultiStyleConfig("Datepicker", { variant });
93
+ const recipe = useSlotRecipe({
94
+ key: "datePicker",
95
+ recipe: datePickerSlotRecipe,
96
+ });
97
+ const styles = recipe({ variant });
87
98
  const locale = useCurrentLocale();
88
99
 
89
100
  const onFieldClick = () => {
@@ -91,18 +102,17 @@ export const DatePicker = forwardRef<HTMLDivElement, DatePickerProps>(
91
102
  };
92
103
 
93
104
  const popoverContent = (
94
- <PopoverContent color="darkGrey" sx={styles.calendarPopover}>
95
- <PopoverArrow sx={styles.arrow} />
96
- <PopoverBody>
97
- <FocusLock>
105
+ <ChakraPopover.Positioner>
106
+ <ChakraPopover.Content css={styles.calendarPopover}>
107
+ <ChakraPopover.Body minWidth={"20rem"}>
98
108
  <Calendar
99
109
  {...calendarProps}
100
110
  variant={variant}
101
111
  showYearNavigation={showYearNavigation}
102
112
  />
103
- </FocusLock>
104
- </PopoverBody>
105
- </PopoverContent>
113
+ </ChakraPopover.Body>
114
+ </ChakraPopover.Content>
115
+ </ChakraPopover.Positioner>
106
116
  );
107
117
 
108
118
  return (
@@ -113,17 +123,12 @@ export const DatePicker = forwardRef<HTMLDivElement, DatePickerProps>(
113
123
  flexDirection="column"
114
124
  width={width}
115
125
  >
116
- <Popover
117
- {...dialogProps}
118
- isOpen={state.isOpen}
119
- onOpen={state.open}
120
- onClose={state.close}
121
- flip={false}
122
- >
123
- <InputGroup
126
+ <ChakraPopover.Root {...dialogProps}>
127
+ <Field
124
128
  display="inline-flex"
125
129
  id={inputGroupId}
126
130
  aria-labelledby={labelId}
131
+ errorText={errorMessage}
127
132
  >
128
133
  <PopoverAnchor>
129
134
  <StyledField
@@ -134,15 +139,15 @@ export const DatePicker = forwardRef<HTMLDivElement, DatePickerProps>(
134
139
  isDisabled={props.isDisabled}
135
140
  ariaLabelledby={labelId}
136
141
  >
137
- <PopoverTrigger>
142
+ <ChakraPopover.Trigger asChild>
138
143
  <CalendarTriggerButton
144
+ paddingLeft={1}
145
+ paddingRight={1}
139
146
  variant={variant}
140
147
  ref={ref}
141
- isDisabled={props.isDisabled}
142
- ariaLabelledby={labelId}
143
148
  {...buttonProps}
144
149
  />
145
- </PopoverTrigger>
150
+ </ChakraPopover.Trigger>
146
151
  <DateField
147
152
  label={props.label}
148
153
  labelProps={labelProps}
@@ -152,15 +157,13 @@ export const DatePicker = forwardRef<HTMLDivElement, DatePickerProps>(
152
157
  />
153
158
  </StyledField>
154
159
  </PopoverAnchor>
155
- </InputGroup>
156
- <FormErrorMessage {...errorMessageProps}>
157
- {errorMessage as ReactNode}
158
- </FormErrorMessage>
160
+ </Field>
161
+
159
162
  {state.isOpen && !props.isDisabled && withPortal && (
160
163
  <Portal>{popoverContent}</Portal>
161
164
  )}
162
165
  {state.isOpen && !props.isDisabled && !withPortal && popoverContent}
163
- </Popover>
166
+ </ChakraPopover.Root>
164
167
  </Box>
165
168
  </I18nProvider>
166
169
  );
@@ -1,44 +1,44 @@
1
+ "use client";
1
2
  import {
2
3
  Box,
3
4
  BoxProps,
4
- FocusLock,
5
- FormLabel,
6
- InputGroup,
7
- Popover,
8
5
  PopoverAnchor,
9
- PopoverArrow,
10
- PopoverBody,
11
- PopoverContent,
12
- PopoverTrigger,
6
+ Popover as ChakraPopover,
13
7
  Portal,
14
- ResponsiveValue,
15
- useFormControlContext,
16
- useMultiStyleConfig,
8
+ useFieldContext,
9
+ useSlotRecipe,
17
10
  } from "@chakra-ui/react";
18
11
  import { DateValue } from "@internationalized/date";
19
- import React, { useRef } from "react";
12
+ import React, { PropsWithChildren, useRef } from "react";
20
13
  import {
21
14
  AriaDateRangePickerProps,
22
15
  I18nProvider,
23
16
  useDateRangePicker,
17
+ useId,
24
18
  } from "react-aria";
25
19
  import { useDateRangePickerState } from "react-stately";
26
- import { CalendarTriggerButton } from "./CalendarTriggerButton";
27
20
  import { DateField } from "./DateField";
28
21
  import { RangeCalendar } from "./RangeCalendar";
29
22
  import { StyledField } from "./StyledField";
30
23
  import { useCurrentLocale } from "./utils";
31
24
 
25
+ import { Field } from "../input/Field";
26
+ import { DatePickerVariantProps } from "./DatePicker";
27
+ import { datePickerSlotRecipe } from "../theme/slot-recipes/datepicker";
28
+ import { CalendarVariants } from "./types";
29
+ import { CalendarTriggerButton } from "./CalendarTriggerButton";
30
+
32
31
  type DateRangePickerProps = Omit<
33
32
  AriaDateRangePickerProps<DateValue>,
34
33
  "onChange"
35
34
  > &
36
- Pick<BoxProps, "minHeight"> & {
35
+ Pick<BoxProps, "minHeight"> &
36
+ PropsWithChildren<DatePickerVariantProps> &
37
+ CalendarVariants & {
37
38
  startLabel?: string;
38
39
  startName?: string;
39
40
  endLabel?: string;
40
41
  endName?: string;
41
- variant: ResponsiveValue<"base" | "floating" | "ghost">;
42
42
  withPortal?: boolean;
43
43
  onChange?: (
44
44
  dates: {
@@ -50,13 +50,12 @@ type DateRangePickerProps = Omit<
50
50
  /**
51
51
  * A date range picker component.
52
52
  *
53
- * There are three variants to choose from – `base`, `floating` and `ghost`.
53
+ * There are three variants to choose from – `core`, `floating` and `ghost`.
54
54
  *
55
55
  * ```tsx
56
- * <DateRangePicker startLabel="From" startName="from" endLabel="To" endName="to" variant="base" />
56
+ * <DateRangePicker startLabel="From" startName="from" endLabel="To" endName="to" variant="core" />
57
57
  * ```
58
- */
59
- export function DateRangePicker({
58
+ */ export function DateRangePicker({
60
59
  variant,
61
60
  minHeight,
62
61
  startName,
@@ -64,16 +63,18 @@ export function DateRangePicker({
64
63
  withPortal = true,
65
64
  ...props
66
65
  }: DateRangePickerProps) {
67
- const formControlProps = useFormControlContext();
66
+ const fieldContextPRops = useFieldContext();
68
67
  const state = useDateRangePickerState({
69
68
  ...props,
70
69
  shouldCloseOnSelect: true,
71
- isRequired: props.isRequired ?? formControlProps?.isRequired,
72
- validationState: formControlProps.isInvalid ? "invalid" : "valid",
70
+ isRequired: props.isRequired ?? fieldContextPRops?.required,
71
+ validationState: fieldContextPRops?.invalid ? "invalid" : "valid",
73
72
  });
74
73
  const ref = useRef(null);
74
+ const uniqueId = useId();
75
+ const datePickerId = `date-range-picker-${uniqueId}`;
76
+
75
77
  const {
76
- groupProps,
77
78
  labelProps,
78
79
  startFieldProps,
79
80
  endFieldProps,
@@ -82,77 +83,70 @@ export function DateRangePicker({
82
83
  calendarProps,
83
84
  } = useDateRangePicker(props, state, ref);
84
85
 
85
- const styles = useMultiStyleConfig("Datepicker", { variant });
86
+ const recipe = useSlotRecipe({
87
+ key: "datePicker",
88
+ recipe: datePickerSlotRecipe,
89
+ });
90
+ const styles = recipe({ variant });
86
91
  const locale = useCurrentLocale();
87
92
 
88
- const handleEnterClick = (e: React.KeyboardEvent) => {
89
- if (e.key === "Enter" && !state.isOpen && variant === "base") {
90
- // Don't submit the form
91
- e.stopPropagation();
92
- state.setOpen(true);
93
- }
94
- };
95
-
96
93
  const onFieldClick = () => {
97
94
  state.setOpen(true);
98
95
  };
99
96
 
100
97
  const popoverContent = (
101
- <PopoverContent sx={styles.calendarPopover} maxWidth="none">
102
- <PopoverArrow sx={styles.arrow} />
103
- <PopoverBody>
104
- <FocusLock>
105
- <RangeCalendar variant={"base"} {...calendarProps} />
106
- </FocusLock>
107
- </PopoverBody>
108
- </PopoverContent>
98
+ <ChakraPopover.Positioner>
99
+ <ChakraPopover.Content css={styles.calendarPopover}>
100
+ <ChakraPopover.Body maxWidth="60rem">
101
+ <RangeCalendar variant={"core"} {...calendarProps} />
102
+ </ChakraPopover.Body>
103
+ </ChakraPopover.Content>
104
+ </ChakraPopover.Positioner>
109
105
  );
110
106
 
111
107
  return (
112
108
  <I18nProvider locale={locale}>
113
109
  <Box position="relative" display="inline-flex" flexDirection="column">
114
110
  {props.label && (
115
- <FormLabel {...labelProps} sx={styles.inputLabel}>
111
+ <label {...labelProps} htmlFor={datePickerId}>
116
112
  {props.label}
117
- </FormLabel>
113
+ </label>
118
114
  )}
119
- <Popover
120
- {...dialogProps}
121
- isOpen={state.isOpen}
122
- onOpen={state.open}
123
- onClose={state.close}
124
- flip={false}
125
- >
126
- <InputGroup {...groupProps} width="auto" display="inline-flex">
115
+ <ChakraPopover.Root {...dialogProps}>
116
+ <Field width="auto" display="inline-flex" id={datePickerId}>
127
117
  <PopoverAnchor>
128
118
  <StyledField
129
119
  alignItems="center"
130
120
  paddingX={3}
131
121
  variant={variant}
132
122
  onClick={onFieldClick}
133
- onKeyPress={handleEnterClick}
134
123
  minHeight={minHeight}
135
124
  >
136
125
  {variant && (
137
- <PopoverTrigger>
126
+ <ChakraPopover.Trigger asChild>
138
127
  <CalendarTriggerButton
139
- paddingLeft={1}
140
- paddingRight={1}
141
128
  variant={variant}
142
129
  ref={ref}
143
130
  {...buttonProps}
144
131
  />
145
- </PopoverTrigger>
132
+ </ChakraPopover.Trigger>
146
133
  )}
134
+
147
135
  <DateField
148
136
  {...startFieldProps}
149
137
  name={startName}
150
138
  label={props.startLabel}
151
139
  labelProps={labelProps}
152
140
  />
153
- <Box as="span" aria-hidden="true" paddingRight="2">
141
+ <Box
142
+ as="span"
143
+ aria-hidden="true"
144
+ paddingRight="2"
145
+ paddingLeft={"2"}
146
+ >
154
147
 
155
148
  </Box>
149
+
156
150
  <DateField
157
151
  {...endFieldProps}
158
152
  name={endName}
@@ -161,10 +155,10 @@ export function DateRangePicker({
161
155
  />
162
156
  </StyledField>
163
157
  </PopoverAnchor>
164
- </InputGroup>
158
+ </Field>
165
159
  {state.isOpen && withPortal && <Portal>{popoverContent}</Portal>}
166
160
  {state.isOpen && !withPortal && popoverContent}
167
- </Popover>
161
+ </ChakraPopover.Root>
168
162
  </Box>
169
163
  </I18nProvider>
170
164
  );
@@ -1,9 +1,12 @@
1
- import { Box, useMultiStyleConfig } from "@chakra-ui/react";
2
- import React, { RefObject, forwardRef, useRef } from "react";
1
+ "use client";
2
+ import { Box, useSlotRecipe } from "@chakra-ui/react";
3
+ import React, { PropsWithChildren, RefObject, forwardRef, useRef } from "react";
3
4
  import { useDateSegment } from "react-aria";
4
5
  import { DateFieldState, DateSegment } from "react-stately";
6
+ import { datePickerSlotRecipe } from "../theme/slot-recipes/datepicker";
7
+ import { DatePickerVariantProps } from "..";
5
8
 
6
- type DateTimeSegmentProps = {
9
+ type DateTimeSegmentProps = PropsWithChildren<DatePickerVariantProps> & {
7
10
  segment: DateSegment;
8
11
  state: DateFieldState;
9
12
  ariaLabel?: string;
@@ -27,10 +30,15 @@ export const DateTimeSegment = forwardRef<HTMLDivElement, DateTimeSegmentProps>(
27
30
  ref as RefObject<HTMLDivElement>,
28
31
  );
29
32
 
30
- const styles = useMultiStyleConfig("Datepicker", {
33
+ const recipe = useSlotRecipe({
34
+ key: "datePicker",
35
+ recipe: datePickerSlotRecipe,
36
+ });
37
+ const styles = recipe({
31
38
  isPlaceholder: segment.isPlaceholder,
32
39
  isEditable: segment.isEditable,
33
40
  });
41
+
34
42
  return (
35
43
  <Box
36
44
  {...segmentProps}
@@ -43,7 +51,7 @@ export const DateTimeSegment = forwardRef<HTMLDivElement, DateTimeSegmentProps>(
43
51
  outline="none"
44
52
  borderRadius="xs"
45
53
  fontSize={["mobile.sm", "desktop.sm"]}
46
- sx={styles.dateTimeSegment}
54
+ css={styles.dateTimeSegment}
47
55
  aria-description={ariaDescription}
48
56
  aria-labelledby={ariaLabel}
49
57
  >
@@ -1,4 +1,5 @@
1
- import { Box, ResponsiveValue } from "@chakra-ui/react";
1
+ "use client";
2
+ import { Box, useSlotRecipe } from "@chakra-ui/react";
2
3
  import { DateValue, createCalendar } from "@internationalized/date";
3
4
  import React, { useRef } from "react";
4
5
  import {
@@ -9,10 +10,11 @@ import { useRangeCalendarState } from "react-stately";
9
10
  import { CalendarGrid } from "./CalendarGrid";
10
11
  import { CalendarHeader } from "./CalendarHeader";
11
12
  import { useCurrentLocale } from "./utils";
13
+ import { CalendarVariants } from "./types";
14
+ import { datePickerSlotRecipe } from "@/theme/slot-recipes/datepicker";
12
15
 
13
- type RangeCalendarProps = ReactAriaRangeCalendarProps<DateValue> & {
14
- variant: ResponsiveValue<"base" | "floating" | "ghost">;
15
- };
16
+ type RangeCalendarProps = ReactAriaRangeCalendarProps<DateValue> &
17
+ CalendarVariants;
16
18
 
17
19
  export function RangeCalendar(props: RangeCalendarProps) {
18
20
  const locale = useCurrentLocale();
@@ -22,14 +24,18 @@ export function RangeCalendar(props: RangeCalendarProps) {
22
24
  locale,
23
25
  createCalendar,
24
26
  });
25
-
27
+ const recipe = useSlotRecipe({
28
+ key: "datePicker",
29
+ recipe: datePickerSlotRecipe,
30
+ });
31
+ const styles = recipe({});
26
32
  const ref = useRef(null);
27
33
  const { calendarProps, title } = useRangeCalendar(props, state, ref);
28
34
 
29
35
  return (
30
- <Box {...calendarProps} ref={ref}>
36
+ <Box {...calendarProps} ref={ref} css={styles.rangeCalendarPopover}>
31
37
  <CalendarHeader state={state} title={title} />
32
- <Box display="flex" gap="8">
38
+ <Box display="flex" gap="8" maxWidth="100vw" overflow="scroll">
33
39
  <CalendarGrid variant={props.variant} state={state} />
34
40
  <CalendarGrid
35
41
  variant={props.variant}
@@ -1,33 +1,41 @@
1
+ "use client";
1
2
  import {
2
3
  Box,
3
4
  BoxProps,
4
- ResponsiveValue,
5
- forwardRef,
6
- useFormControlContext,
7
- useMultiStyleConfig,
5
+ useFieldContext,
6
+ useSlotRecipe,
8
7
  } from "@chakra-ui/react";
9
- import { As } from "@chakra-ui/system";
10
- import React from "react";
8
+ import React, { forwardRef, PropsWithChildren } from "react";
9
+ import { DatePickerVariantProps } from "./DatePicker";
10
+ import { datePickerSlotRecipe } from "../theme/slot-recipes/datepicker";
11
+ import { CalendarVariants } from "./types";
11
12
 
12
- type StyledFieldProps = BoxProps & {
13
- variant: ResponsiveValue<"base" | "floating" | "ghost">;
14
- isDisabled?: boolean;
15
- ariaLabelledby?: string;
16
- };
17
- export const StyledField = forwardRef<StyledFieldProps, As>(
18
- ({ children, variant, isDisabled, ariaLabelledby, ...otherProps }, ref) => {
19
- const { isInvalid } = useFormControlContext() ?? {
13
+ type StyledFieldProps = BoxProps &
14
+ PropsWithChildren<DatePickerVariantProps> &
15
+ CalendarVariants & {
16
+ isDisabled?: boolean;
17
+ ariaLabelledby?: string;
18
+ };
19
+ export const StyledField = forwardRef<HTMLDivElement, StyledFieldProps>(
20
+ function StyledField(props, ref) {
21
+ const { children, variant, isDisabled, ariaLabelledby, ...otherProps } =
22
+ props;
23
+ const { invalid } = useFieldContext() ?? {
20
24
  isInvalid: false,
21
25
  };
22
26
 
23
- const styles = useMultiStyleConfig("Datepicker", { variant });
27
+ const recipe = useSlotRecipe({
28
+ key: "datePicker",
29
+ recipe: datePickerSlotRecipe,
30
+ });
31
+ const styles = recipe({ variant });
24
32
 
25
33
  return (
26
34
  <Box
27
35
  {...otherProps}
28
- __css={styles.wrapper}
36
+ css={styles.wrapper}
29
37
  ref={ref}
30
- aria-invalid={isInvalid}
38
+ aria-invalid={invalid}
31
39
  aria-disabled={isDisabled}
32
40
  aria-labelledby={ariaLabelledby}
33
41
  >
@@ -1,9 +1,9 @@
1
+ "use client";
1
2
  import { Box, Flex } from "@chakra-ui/react";
2
3
  import { CalendarDateTime, Time } from "@internationalized/date";
3
4
  import React, { useRef } from "react";
4
5
  import { AriaTimeFieldProps, useTimeField } from "react-aria";
5
6
  import { TimeFieldState } from "@react-stately/datepicker";
6
- import { FormLabel } from "..";
7
7
  import { DateTimeSegment } from "./DateTimeSegment";
8
8
  import { getTimestampFromTime } from "./utils";
9
9
 
@@ -23,17 +23,19 @@ export const TimeField = ({ state, ...props }: TimeFieldProps) => {
23
23
 
24
24
  return (
25
25
  <Box>
26
- <FormLabel
26
+ <label
27
27
  {...labelProps}
28
28
  htmlFor={fieldProps.id}
29
- marginBottom={0}
30
- fontSize="mobile.xs"
31
- cursor="text"
32
- position="absolute"
33
- paddingTop="2px"
29
+ style={{
30
+ marginBottom: 0,
31
+ fontSize: "mobile.xs",
32
+ cursor: "text",
33
+ position: "absolute",
34
+ paddingTop: "2px",
35
+ }}
34
36
  >
35
37
  {props.label}
36
- </FormLabel>
38
+ </label>
37
39
  <Flex {...fieldProps} ref={ref} paddingTop="3" paddingBottom="0.5">
38
40
  {state.segments.map((segment) => (
39
41
  <DateTimeSegment key={segment.type} segment={segment} state={state} />