@vygruppen/spor-react 11.3.10 → 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 +239 -0
  4. package/dist/index.d.mts +2552 -8319
  5. package/dist/index.d.ts +2552 -8319
  6. package/dist/index.js +9609 -8608
  7. package/dist/index.js.map +1 -1
  8. package/dist/index.mjs +9487 -8455
  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 -101
  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,25 +1,26 @@
1
1
  import {
2
2
  IconButton as ChakraIconButton,
3
- IconButtonProps as ChakraIconButtonProps,
4
- forwardRef,
3
+ type IconButtonProps as ChakraIconButtonProps,
5
4
  } from "@chakra-ui/react";
6
- import React from "react";
7
- import { ColorSpinner } from "..";
8
- import { As } from "@chakra-ui/system";
5
+ import React, { forwardRef, PropsWithChildren } from "react";
6
+ import { ButtonVariantProps, ColorSpinner } from "..";
7
+
8
+ export type IconButtonProps = Exclude<
9
+ ChakraIconButtonProps,
10
+ "variant" | "spinner" | "icon"
11
+ > &
12
+ PropsWithChildren<ButtonVariantProps> & {
13
+ /** The button variant.
14
+ *
15
+ */
16
+ variant: "primary" | "secondary" | "tertiary" | "ghost" | "floating";
17
+ spinner?: React.JSX.Element;
18
+ icon?: React.JSX.Element;
19
+ loading?: boolean;
20
+ download?: string;
21
+ href?: string;
22
+ };
9
23
 
10
- export type IconButtonProps = Omit<ChakraIconButtonProps, "variant"> & {
11
- /** The button variant.
12
- *
13
- * "control" is deprecated
14
- */
15
- variant:
16
- | "control"
17
- | "primary"
18
- | "secondary"
19
- | "tertiary"
20
- | "ghost"
21
- | "floating";
22
- };
23
24
  /**
24
25
  * An icon-only button.
25
26
  *
@@ -27,7 +28,6 @@ export type IconButtonProps = Omit<ChakraIconButtonProps, "variant"> & {
27
28
  *
28
29
  * There are several icon button variants. You can specify which one you want with the `variant` prop. The available variants are:
29
30
  *
30
- * - `control`: This button is used for ticket controls only.
31
31
  * - `primary`: This is our main button. It's used for the main actions in a view, like a call to action. There should only be a single primary button in each view.
32
32
  * - `secondary`: Used for secondary actions in a view, and when you need to make several actions available at the same time.
33
33
  * - `tertiary`: Used for additional choices, like a less important secondary action.
@@ -55,15 +55,19 @@ export type IconButtonProps = Omit<ChakraIconButtonProps, "variant"> & {
55
55
  * />
56
56
  * ```
57
57
  */
58
- export const IconButton = forwardRef<IconButtonProps, As>(
59
- ({ ...props }, ref) => (
60
- <ChakraIconButton
61
- title={props["aria-label"]}
62
- {...props}
63
- spinner={
64
- <ColorSpinner width="80%" height="80%" marginX={1} marginTop={1} />
65
- }
66
- ref={ref}
67
- />
68
- ),
58
+ export const IconButton = forwardRef<HTMLButtonElement, IconButtonProps>(
59
+ (props, ref) => {
60
+ const { icon, size = "sm", loading = false, ...rest } = props;
61
+ return (
62
+ <ChakraIconButton
63
+ aria-label={props["aria-label"]}
64
+ size={size}
65
+ ref={ref}
66
+ position={"relative"}
67
+ {...rest}
68
+ >
69
+ {loading ? <ColorSpinner width="2em" height="2em" margin={1} /> : icon}
70
+ </ChakraIconButton>
71
+ );
72
+ },
69
73
  );
@@ -3,3 +3,4 @@ export * from "./ButtonGroup";
3
3
  export * from "./CloseButton";
4
4
  export * from "./FloatingActionButton";
5
5
  export * from "./IconButton";
6
+ export * from "./Clipboard";
@@ -0,0 +1,75 @@
1
+ "use client";
2
+
3
+ import type { IconButtonProps } from "@chakra-ui/react";
4
+ import { ClientOnly, IconButton, Skeleton } from "@chakra-ui/react";
5
+ import { ThemeProvider, useTheme } from "next-themes";
6
+ import type { ThemeProviderProps } from "next-themes";
7
+ import * as React from "react";
8
+ import { LuMoon, LuSun } from "react-icons/lu";
9
+
10
+ export interface ColorModeProviderProps extends ThemeProviderProps {}
11
+
12
+ export function ColorModeProvider(props: ColorModeProviderProps) {
13
+ return (
14
+ <ThemeProvider attribute="class" disableTransitionOnChange {...props} />
15
+ );
16
+ }
17
+
18
+ export type ColorMode = "light" | "dark";
19
+
20
+ export interface UseColorModeReturn {
21
+ colorMode: ColorMode;
22
+ setColorMode: (colorMode: ColorMode) => void;
23
+ toggleColorMode: () => void;
24
+ }
25
+
26
+ export function useColorMode(): UseColorModeReturn {
27
+ const { resolvedTheme, setTheme } = useTheme();
28
+ const toggleColorMode = () => {
29
+ setTheme(resolvedTheme === "light" ? "dark" : "light");
30
+ };
31
+ return {
32
+ colorMode: resolvedTheme as ColorMode,
33
+ setColorMode: setTheme,
34
+ toggleColorMode,
35
+ };
36
+ }
37
+
38
+ export function useColorModeValue<T>(light: T, dark: T) {
39
+ const { colorMode } = useColorMode();
40
+ return colorMode === "dark" ? dark : light;
41
+ }
42
+
43
+ export function ColorModeIcon() {
44
+ const { colorMode } = useColorMode();
45
+ return colorMode === "dark" ? <LuMoon /> : <LuSun />;
46
+ }
47
+
48
+ interface ColorModeButtonProps extends Omit<IconButtonProps, "aria-label"> {}
49
+
50
+ export const ColorModeButton = React.forwardRef<
51
+ HTMLButtonElement,
52
+ ColorModeButtonProps
53
+ >(function ColorModeButton(props, ref) {
54
+ const { toggleColorMode } = useColorMode();
55
+ return (
56
+ <ClientOnly fallback={<Skeleton boxSize="8" />}>
57
+ <IconButton
58
+ onClick={toggleColorMode}
59
+ variant="ghost"
60
+ aria-label="Toggle color mode"
61
+ size="sm"
62
+ ref={ref}
63
+ {...props}
64
+ css={{
65
+ _icon: {
66
+ width: "5",
67
+ height: "5",
68
+ },
69
+ }}
70
+ >
71
+ <ColorModeIcon />
72
+ </IconButton>
73
+ </ClientOnly>
74
+ );
75
+ });
@@ -0,0 +1 @@
1
+ export * from "./color-mode";
@@ -1,20 +1,25 @@
1
- import { Box, ResponsiveValue } from "@chakra-ui/react";
2
- import { DateValue, createCalendar } from "@internationalized/date";
1
+ "use client";
2
+
3
+ import { Box, useSlotRecipe } from "@chakra-ui/react";
4
+ import { createCalendar } from "@internationalized/date";
3
5
  import React from "react";
4
6
  import {
5
7
  CalendarProps as ReactAriaCalendarProps,
6
8
  useCalendar,
9
+ DateValue,
7
10
  } from "react-aria";
8
11
  import { useCalendarState } from "react-stately";
9
12
  import { createTexts, useTranslation } from "../i18n";
10
13
  import { CalendarGrid } from "./CalendarGrid";
11
14
  import { CalendarHeader } from "./CalendarHeader";
12
15
  import { useCurrentLocale } from "./utils";
16
+ import { CalendarVariants } from "./types";
17
+ import { datePickerSlotRecipe } from "@/theme/slot-recipes/datepicker";
13
18
 
14
- type CalendarProps = ReactAriaCalendarProps<DateValue> & {
15
- showYearNavigation?: boolean;
16
- variant: ResponsiveValue<"base" | "floating" | "ghost">;
17
- };
19
+ type CalendarProps = ReactAriaCalendarProps<DateValue> &
20
+ CalendarVariants & {
21
+ showYearNavigation?: boolean;
22
+ };
18
23
  export function Calendar({
19
24
  showYearNavigation,
20
25
  variant,
@@ -27,7 +32,11 @@ export function Calendar({
27
32
  locale,
28
33
  createCalendar,
29
34
  });
30
-
35
+ const recipe = useSlotRecipe({
36
+ key: "datePicker",
37
+ recipe: datePickerSlotRecipe,
38
+ });
39
+ const styles = recipe({ variant });
31
40
  const { calendarProps } = useCalendar(props, state);
32
41
  const calendarAriaLabel = calendarProps["aria-label"];
33
42
 
@@ -35,7 +44,7 @@ export function Calendar({
35
44
  t(texts.calendar) + (calendarAriaLabel ? ` ${calendarAriaLabel}` : "");
36
45
 
37
46
  return (
38
- <Box {...calendarProps} aria-label={ariaLabel}>
47
+ <Box {...calendarProps} aria-label={ariaLabel} css={styles.box}>
39
48
  <CalendarHeader state={state} showYearNavigation={showYearNavigation} />
40
49
  <CalendarGrid variant={variant} state={state} />
41
50
  </Box>
@@ -1,20 +1,25 @@
1
- import { Box, ResponsiveValue, useMultiStyleConfig } from "@chakra-ui/react";
1
+ "use client";
2
+
3
+ import { Box, ConditionalValue, useSlotRecipe } from "@chakra-ui/react";
2
4
  import {
3
5
  CalendarDate,
4
6
  DateValue,
5
7
  isSameMonth,
6
8
  isToday,
7
9
  } from "@internationalized/date";
8
- import React, { useEffect, useRef } from "react";
10
+ import React, { PropsWithChildren, useEffect, useRef } from "react";
9
11
  import { useCalendarCell } from "react-aria";
10
12
  import { CalendarState, RangeCalendarState } from "react-stately";
13
+ import { DatePickerVariantProps } from "./DatePicker";
14
+ import { datePickerSlotRecipe } from "../theme/slot-recipes/datepicker";
15
+ import { CalendarVariants } from "./types";
11
16
 
12
- type CalendarCellProps = {
13
- variant: ResponsiveValue<"base" | "floating" | "ghost">;
14
- state: CalendarState | RangeCalendarState;
15
- date: CalendarDate;
16
- currentMonth: DateValue;
17
- };
17
+ type CalendarCellProps = PropsWithChildren<DatePickerVariantProps> &
18
+ CalendarVariants & {
19
+ state: CalendarState | RangeCalendarState;
20
+ date: CalendarDate;
21
+ currentMonth: DateValue;
22
+ };
18
23
  export function CalendarCell({
19
24
  state,
20
25
  date,
@@ -32,7 +37,11 @@ export function CalendarCell({
32
37
  } = useCalendarCell({ date }, state, ref);
33
38
 
34
39
  const isOutsideMonth = !isSameMonth(currentMonth, date);
35
- const styles = useMultiStyleConfig("Datepicker", { variant });
40
+ const recipe = useSlotRecipe({
41
+ key: "datePicker",
42
+ recipe: datePickerSlotRecipe,
43
+ });
44
+ const styles = recipe({ variant });
36
45
 
37
46
  const stateProps: Record<string, any> = {};
38
47
  if (isSelected) {
@@ -64,16 +73,14 @@ export function CalendarCell({
64
73
  }, []);
65
74
 
66
75
  return (
67
- <Box as="td" {...cellProps} textAlign="center" sx={styles.cell}>
76
+ <Box as="td" {...cellProps} textAlign="center" css={styles.cell}>
68
77
  <Box
69
78
  as="button"
70
- type="button"
71
79
  {...buttonProps}
72
80
  {...stateProps}
73
81
  ref={ref}
74
- sx={styles.dateCell}
82
+ css={styles.dateCell}
75
83
  hidden={isOutsideVisibleRange}
76
- width="100%"
77
84
  >
78
85
  {date.day}
79
86
  </Box>
@@ -1,3 +1,5 @@
1
+ "use client";
2
+
1
3
  import { endOfMonth, getWeeksInMonth } from "@internationalized/date";
2
4
  import React from "react";
3
5
  import { AriaCalendarGridProps, useCalendarGrid } from "react-aria";
@@ -6,7 +8,9 @@ import { Language, useTranslation } from "../i18n";
6
8
  import { Text } from "../typography";
7
9
  import { CalendarCell } from "./CalendarCell";
8
10
  import { useCurrentLocale } from "./utils";
9
- import { ResponsiveValue, useMultiStyleConfig } from "@chakra-ui/react";
11
+ import { Box, useSlotRecipe } from "@chakra-ui/react";
12
+ import { datePickerSlotRecipe } from "../theme/slot-recipes/datepicker";
13
+ import { CalendarVariants } from "./types";
10
14
 
11
15
  const weekDays: Record<Language, string[]> = {
12
16
  nb: ["Ma", "Ti", "On", "To", "Fr", "Lø", "Sø"],
@@ -15,11 +19,11 @@ const weekDays: Record<Language, string[]> = {
15
19
  en: ["Mo", "Tu", "We", "Th", "Fr", "Sa", "Su"],
16
20
  };
17
21
 
18
- type CalendarGridProps = AriaCalendarGridProps & {
19
- variant: ResponsiveValue<"base" | "floating" | "ghost">;
20
- state: CalendarState | RangeCalendarState;
21
- offset?: { months?: number };
22
- };
22
+ type CalendarGridProps = AriaCalendarGridProps &
23
+ CalendarVariants & {
24
+ state: CalendarState | RangeCalendarState;
25
+ offset?: { months?: number };
26
+ };
23
27
  export function CalendarGrid({
24
28
  state,
25
29
  variant,
@@ -40,10 +44,14 @@ export function CalendarGrid({
40
44
  // Get the number of weeks in the month so we can render the proper number of rows.
41
45
  const weeksInMonth = getWeeksInMonth(state.visibleRange.start, locale);
42
46
  const weeksInMonthRange = new Array(weeksInMonth).fill(0).map((_, i) => i);
43
- const styles = useMultiStyleConfig("Datepicker", { variant });
47
+ const recipe = useSlotRecipe({
48
+ key: "datePicker",
49
+ recipe: datePickerSlotRecipe,
50
+ });
51
+ const styles = recipe({ variant });
44
52
 
45
53
  return (
46
- <table {...gridProps}>
54
+ <Box as="table" {...gridProps} css={styles.box}>
47
55
  <thead {...headerProps}>
48
56
  <tr>
49
57
  {weekDays[language].map((day, index) => {
@@ -51,7 +59,7 @@ export function CalendarGrid({
51
59
  <Text
52
60
  as="th"
53
61
  key={index}
54
- sx={index < 5 ? styles.weekdays : styles.weekend}
62
+ css={index < 5 ? styles.weekdays : styles.weekend}
55
63
  variant="sm"
56
64
  >
57
65
  {day}
@@ -81,6 +89,6 @@ export function CalendarGrid({
81
89
  </tr>
82
90
  ))}
83
91
  </tbody>
84
- </table>
92
+ </Box>
85
93
  );
86
94
  }
@@ -1,3 +1,4 @@
1
+ "use client";
1
2
  import { Box, Flex } from "@chakra-ui/react";
2
3
  import { getLocalTimeZone } from "@internationalized/date";
3
4
  import {
@@ -110,6 +111,7 @@ export const CalendarNavigator = ({
110
111
  fontWeight="bold"
111
112
  flex="1"
112
113
  textAlign="center"
114
+ color={"core.text"}
113
115
  >
114
116
  {capitalize(title)}
115
117
  </Box>
@@ -1,3 +1,4 @@
1
+ "use client";
1
2
  import React, { useRef } from "react";
2
3
  import { AriaButtonProps, useButton } from "react-aria";
3
4
  import { IconButton } from "..";
@@ -1,53 +1,51 @@
1
- import {
2
- Box,
3
- PopoverAnchor,
4
- useMultiStyleConfig,
5
- forwardRef,
6
- ResponsiveValue,
7
- } from "@chakra-ui/react";
1
+ "use client";
2
+
3
+ import { BoxProps, PopoverAnchor, useSlotRecipe } from "@chakra-ui/react";
8
4
  import { CalendarOutline24Icon } from "@vygruppen/spor-icon-react";
9
- import React, { KeyboardEventHandler } from "react";
5
+ import React, { forwardRef, PropsWithChildren } from "react";
10
6
  import { AriaButtonProps } from "react-aria";
11
- import { IconButton, createTexts, useTranslation } from "..";
12
- import { As } from "@chakra-ui/system";
13
-
14
- type CalendarTriggerButtonProps = AriaButtonProps<"button"> & {
15
- variant: ResponsiveValue<"base" | "floating" | "ghost">;
16
- isDisabled?: boolean;
17
- ariaLabelledby?: string;
18
- };
19
- export const CalendarTriggerButton = forwardRef<CalendarTriggerButtonProps, As>(
20
- ({ variant, isDisabled, ariaLabelledby, ...buttonProps }, ref) => {
21
- const { t } = useTranslation();
22
- const styles = useMultiStyleConfig("Datepicker", { variant });
7
+ import {
8
+ createTexts,
9
+ DatePickerVariantProps,
10
+ IconButton,
11
+ useTranslation,
12
+ } from "..";
13
+ import { datePickerSlotRecipe } from "../theme/slot-recipes/datepicker";
14
+ import { CalendarVariants } from "./types";
23
15
 
24
- const { onPress, ...filteredButtonProps } = buttonProps;
16
+ type CalendarTriggerButtonProps = AriaButtonProps<"button"> &
17
+ PropsWithChildren<DatePickerVariantProps> &
18
+ BoxProps &
19
+ CalendarVariants & {
20
+ disabled?: boolean;
21
+ ariaLabelledby?: string;
22
+ };
23
+ export const CalendarTriggerButton = forwardRef<
24
+ HTMLDivElement,
25
+ CalendarTriggerButtonProps
26
+ >(({ variant, disabled, ariaLabelledby, ...buttonProps }, ref) => {
27
+ const { t } = useTranslation();
28
+ const recipe = useSlotRecipe({
29
+ key: "datePicker",
30
+ recipe: datePickerSlotRecipe,
31
+ });
32
+ const styles = recipe({ variant });
25
33
 
26
- const handleCommand: KeyboardEventHandler = (event) => {
27
- if (event.key === "Enter" || event.key === " ") {
28
- event.preventDefault();
29
- onPress?.(event as any);
30
- }
31
- };
34
+ const { onPress, ...filteredButtonProps } = buttonProps;
32
35
 
33
- return (
34
- <PopoverAnchor>
35
- <IconButton
36
- ref={ref}
37
- role="button"
38
- icon={<CalendarOutline24Icon />}
39
- aria-label={t(texts.openCalendar)}
40
- sx={styles.calendarTriggerButton}
41
- variant="ghost"
42
- {...filteredButtonProps}
43
- isDisabled={isDisabled}
44
- onKeyDown={handleCommand}
45
- aria-labelledby={ariaLabelledby}
46
- />
47
- </PopoverAnchor>
48
- );
49
- },
50
- );
36
+ return (
37
+ <PopoverAnchor {...buttonProps}>
38
+ <IconButton
39
+ icon={<CalendarOutline24Icon />}
40
+ aria-label={t(texts.openCalendar)}
41
+ css={styles.calendarTriggerButton}
42
+ variant="ghost"
43
+ disabled={disabled}
44
+ aria-labelledby={ariaLabelledby}
45
+ />
46
+ </PopoverAnchor>
47
+ );
48
+ });
51
49
 
52
50
  const texts = createTexts({
53
51
  openCalendar: {
@@ -1,12 +1,15 @@
1
- import { Box, Flex, FormLabel, useMultiStyleConfig } from "@chakra-ui/react";
1
+ "use client";
2
+ import { Box, Flex, useSlotRecipe } from "@chakra-ui/react";
2
3
  import { DateValue, GregorianCalendar } from "@internationalized/date";
3
4
  import { DOMAttributes, FocusableElement } from "@react-types/shared";
4
- import React, { RefObject, forwardRef, useId, useRef } from "react";
5
+ import React, { PropsWithChildren, RefObject, forwardRef, useRef } from "react";
5
6
  import { AriaDateFieldProps, useDateField } from "react-aria";
6
7
  import { DateSegment, useDateFieldState } from "react-stately";
7
8
  import { DateTimeSegment } from "./DateTimeSegment";
8
9
  import { useCurrentLocale } from "./utils";
9
10
  import { createTexts, useTranslation } from "../i18n";
11
+ import { DatePickerVariantProps } from "./DatePicker";
12
+ import { datePickerSlotRecipe } from "../theme/slot-recipes/datepicker";
10
13
 
11
14
  function createCalendar(identifier: string) {
12
15
  switch (identifier) {
@@ -17,16 +20,21 @@ function createCalendar(identifier: string) {
17
20
  }
18
21
  }
19
22
 
20
- type DateFieldProps = AriaDateFieldProps<DateValue> & {
21
- label?: React.ReactNode;
22
- labelProps?: DOMAttributes<FocusableElement>;
23
- name?: string;
24
- labelId?: string;
25
- };
23
+ type DateFieldProps = AriaDateFieldProps<DateValue> &
24
+ PropsWithChildren<DatePickerVariantProps> & {
25
+ label?: React.ReactNode;
26
+ labelProps?: DOMAttributes<FocusableElement>;
27
+ name?: string;
28
+ labelId?: string;
29
+ };
26
30
  export const DateField = forwardRef<HTMLDivElement, DateFieldProps>(
27
31
  ({ labelId, ...props }, externalRef) => {
28
32
  const locale = useCurrentLocale();
29
- const styles = useMultiStyleConfig("Datepicker", {});
33
+ const recipe = useSlotRecipe({
34
+ key: "datePicker",
35
+ recipe: datePickerSlotRecipe,
36
+ });
37
+ const styles = recipe({});
30
38
  const state = useDateFieldState({
31
39
  ...props,
32
40
  locale,
@@ -46,14 +54,15 @@ export const DateField = forwardRef<HTMLDivElement, DateFieldProps>(
46
54
  return (
47
55
  <Box minWidth="6rem" width="100%">
48
56
  {props.label && (
49
- <FormLabel
50
- sx={styles.inputLabel}
57
+ <Box
58
+ as="label"
59
+ css={styles.inputLabel}
51
60
  position="absolute"
52
61
  paddingTop="2px"
53
62
  id={labelId}
54
63
  >
55
64
  {props.label}
56
- </FormLabel>
65
+ </Box>
57
66
  )}
58
67
  <Flex {...fieldProps} ref={ref} paddingTop="3" paddingBottom="0.5">
59
68
  {state.segments.map((segment, i) => (