@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,11 +1,15 @@
1
- import { Flex, useMultiStyleConfig } from "@chakra-ui/react";
1
+ "use client";
2
+ import { Flex, RecipeVariantProps, useSlotRecipe } from "@chakra-ui/react";
2
3
  import { ArrowLeftFill24Icon } from "@vygruppen/spor-icon-react";
3
- import React from "react";
4
+ import React, { forwardRef, PropsWithChildren } from "react";
4
5
  import { StepperStep } from ".";
5
- import { Box, IconButton, Text, createTexts, useTranslation } from "..";
6
+ import { Box, createTexts, IconButton, Text, useTranslation } from "..";
7
+ import { stepperSlotRecipe } from "../theme/slot-recipes/stepper";
6
8
  import { StepperProvider } from "./StepperContext";
7
9
 
8
- type StepperProps = {
10
+ export type StepperVariantProps = RecipeVariantProps<typeof stepperSlotRecipe>;
11
+
12
+ type StepperProps = PropsWithChildren<StepperVariantProps> & {
9
13
  /** Callback for when a step is clicked */
10
14
  onClick: (clickedStep: number) => void;
11
15
  /** Callback for when the back button is clicked (on smaller screens).
@@ -13,11 +17,6 @@ type StepperProps = {
13
17
  * If this is not provided, the back button will not be shown on smaller screens on the first step.
14
18
  */
15
19
  onBackButtonClick?: (stepNumberToGoTo: number) => void;
16
- /**
17
- * Heading shown on smaller devices
18
- * @deprecated Use `heading` instead
19
- */
20
- title?: string;
21
20
  /** Heading shown on smaller devices */
22
21
  heading?: string;
23
22
  /**
@@ -31,11 +30,11 @@ type StepperProps = {
31
30
  /** The labels of each step */
32
31
  steps: string[];
33
32
  /** The variant.
34
- * "base" has a transparent background,
33
+ * "core" has a transparent background,
35
34
  * while "accent" has a slight accent color */
36
- variant: "base" | "accent";
35
+ variant: "core" | "accent";
37
36
  /** Disables all clicks */
38
- isDisabled?: boolean;
37
+ disabled?: boolean;
39
38
  };
40
39
  /**
41
40
  * A stepper is used to show which step of a process a user is currently in.
@@ -51,81 +50,85 @@ type StepperProps = {
51
50
  * />
52
51
  * ```
53
52
  **/
54
- export const Stepper = ({
55
- onClick = () => {},
56
- onBackButtonClick,
57
- steps,
58
- activeStep: activeStepAsStringOrNumber,
59
- title,
60
- heading,
61
- headingLevel,
62
- variant,
63
- isDisabled,
64
- }: StepperProps) => {
65
- const style = useMultiStyleConfig("Stepper", { variant });
66
- const numberOfSteps = steps.length;
67
- const activeStep = Number(activeStepAsStringOrNumber);
68
- const { t } = useTranslation();
69
- const hideBackButtonOnFirstStep = activeStep === 1 && !onBackButtonClick;
70
- const shownHeading = heading || title;
71
- return (
72
- <Box sx={style.root}>
73
- <StepperProvider
74
- onClick={onClick}
75
- activeStep={activeStep}
76
- variant={variant}
77
- numberOfSteps={numberOfSteps}
78
- >
79
- <Box sx={style.container}>
80
- <Box sx={style.innerContainer}>
81
- <Flex
82
- justifyContent="space-between"
83
- alignItems="center"
84
- gap={2}
85
- flex={1}
86
- >
87
- <IconButton
88
- aria-label={t(texts.back)}
89
- icon={<ArrowLeftFill24Icon />}
90
- variant="ghost"
91
- size="sm"
92
- visibility={hideBackButtonOnFirstStep ? "hidden" : "visible"}
93
- onClick={() => {
94
- const stepToGoTo = activeStep - 1;
95
- if (onBackButtonClick) {
96
- onBackButtonClick(stepToGoTo);
97
- }
98
- onClick(stepToGoTo);
99
- }}
100
- />
101
- {shownHeading && (
102
- <Text flex={1} variant="sm" as={headingLevel} sx={style.title}>
103
- {shownHeading}
104
- </Text>
105
- )}
106
- <Box sx={style.stepCounter}>
107
- {t(texts.stepsOf(activeStep, numberOfSteps))}
108
- </Box>
53
+
54
+ export const Stepper = forwardRef<HTMLDivElement, StepperProps>(
55
+ function Stepper(props, ref) {
56
+ const {
57
+ onClick = () => {},
58
+ onBackButtonClick,
59
+ steps,
60
+ activeStep: activeStepAsStringOrNumber,
61
+ heading,
62
+ headingLevel,
63
+ variant,
64
+ disabled,
65
+ } = props;
66
+ const recipe = useSlotRecipe({ key: "stepper" });
67
+ const style = recipe({ variant });
68
+ const numberOfSteps = steps.length;
69
+ const activeStep = Number(activeStepAsStringOrNumber);
70
+ const { t } = useTranslation();
71
+ const hideBackButtonOnFirstStep = activeStep === 1 && !onBackButtonClick;
72
+
73
+ return (
74
+ <Box css={style.root} ref={ref}>
75
+ <StepperProvider
76
+ onClick={onClick}
77
+ activeStep={activeStep}
78
+ variant={variant}
79
+ numberOfSteps={numberOfSteps}
80
+ >
81
+ <Box css={style.container}>
82
+ <Box css={style.innerContainer}>
83
+ <Flex
84
+ justifyContent="space-between"
85
+ alignItems="center"
86
+ gap={2}
87
+ flex={1}
88
+ >
89
+ <IconButton
90
+ aria-label={t(texts.back)}
91
+ icon={<ArrowLeftFill24Icon />}
92
+ variant="ghost"
93
+ size="sm"
94
+ visibility={hideBackButtonOnFirstStep ? "hidden" : "visible"}
95
+ onClick={() => {
96
+ const stepToGoTo = activeStep - 1;
97
+ if (onBackButtonClick) {
98
+ onBackButtonClick(stepToGoTo);
99
+ }
100
+ onClick(stepToGoTo);
101
+ }}
102
+ />
103
+ {heading && (
104
+ <Text variant="sm" as={headingLevel} css={style.title}>
105
+ {heading}
106
+ </Text>
107
+ )}
108
+ <Box css={style.stepCounter}>
109
+ {t(texts.stepsOf(activeStep, numberOfSteps))}
110
+ </Box>
111
+ </Flex>
112
+ </Box>
113
+ <Flex justifyContent="center" display={["none", null, "flex"]}>
114
+ {steps.map((step, index) => (
115
+ <StepperStep
116
+ key={index}
117
+ stepNumber={index + 1}
118
+ variant={variant}
119
+ aria-current={index + 1 === activeStep ? "step" : undefined}
120
+ disabled={disabled}
121
+ >
122
+ {step}
123
+ </StepperStep>
124
+ ))}
109
125
  </Flex>
110
126
  </Box>
111
- <Flex justifyContent="center" display={["none", null, "flex"]}>
112
- {steps.map((step, index) => (
113
- <StepperStep
114
- key={index}
115
- stepNumber={index + 1}
116
- variant={variant}
117
- aria-current={index + 1 === activeStep ? "step" : undefined}
118
- isDisabled={isDisabled}
119
- >
120
- {step}
121
- </StepperStep>
122
- ))}
123
- </Flex>
124
- </Box>
125
- </StepperProvider>
126
- </Box>
127
- );
128
- };
127
+ </StepperProvider>
128
+ </Box>
129
+ );
130
+ },
131
+ );
129
132
 
130
133
  const texts = createTexts({
131
134
  stepsOf: (activeStep, numberOfSteps) => ({
@@ -1,3 +1,4 @@
1
+ "use client";
1
2
  import React from "react";
2
3
 
3
4
  type StepperContextType = {
@@ -8,7 +9,7 @@ type StepperContextType = {
8
9
  };
9
10
  const StepperContext = React.createContext<StepperContextType | null>(null);
10
11
 
11
- type Variant = "base" | "accent";
12
+ type Variant = "core" | "accent";
12
13
 
13
14
  type StepperProviderProps = {
14
15
  /** Stepper steps */
@@ -1,38 +1,38 @@
1
- import { useColorModeValue, useMultiStyleConfig } from "@chakra-ui/react";
1
+ "use client";
2
+ import { useSlotRecipe } from "@chakra-ui/react";
2
3
  import { DropdownRightFill18Icon } from "@vygruppen/spor-icon-react";
3
- import React from "react";
4
+ import React, { PropsWithChildren } from "react";
4
5
  import { Box, Button, Text } from "..";
6
+ import { StepperVariantProps } from "./Stepper";
5
7
  import { useStepper } from "./StepperContext";
6
8
 
7
- type StepperStepProps = {
9
+ type StepperStepProps = PropsWithChildren<StepperVariantProps> & {
8
10
  children: React.ReactNode;
9
11
  stepNumber: number;
10
- variant: "base" | "accent";
11
- isDisabled?: boolean;
12
+ variant: "core" | "accent";
13
+ disabled?: boolean;
12
14
  };
13
15
  export const StepperStep = ({
14
16
  children,
15
17
  stepNumber,
16
18
  variant,
17
- isDisabled: isDisabledOverride,
19
+ disabled: disabledOverride,
18
20
  }: StepperStepProps) => {
19
21
  const { activeStep, onClick } = useStepper();
20
22
  const state = getState(stepNumber, activeStep);
21
- const style = useMultiStyleConfig("Stepper", {
22
- state,
23
- variant,
24
- });
25
- const disabledTextColor = useColorModeValue(
26
- "blackAlpha.400",
27
- "whiteAlpha.400",
28
- );
29
- const iconColor = useColorModeValue("blackAlpha.200", "whiteAlpha.200");
23
+ const recipe = useSlotRecipe({ key: "stepper" });
24
+ const style = recipe({ variant });
25
+ const disabledTextColor = "text.disabled";
26
+ const iconColor = {
27
+ _light: "blackAlpha.200",
28
+ _dark: "whiteAlpha.200",
29
+ };
30
30
 
31
- const isDisabled =
32
- (state !== "active" && isDisabledOverride) || state === "disabled";
31
+ const disabled =
32
+ (state !== "active" && disabledOverride) || state === "disabled";
33
33
 
34
34
  return (
35
- <Box sx={style.stepContainer}>
35
+ <Box css={style.stepContainer}>
36
36
  {stepNumber > 1 && (
37
37
  <DropdownRightFill18Icon
38
38
  marginX={5}
@@ -40,10 +40,10 @@ export const StepperStep = ({
40
40
  color={iconColor}
41
41
  />
42
42
  )}
43
- {isDisabled ? (
43
+ {disabled ? (
44
44
  <Text
45
45
  variant="xs"
46
- fontSize="16px"
46
+ fontSize="1rem"
47
47
  color={disabledTextColor}
48
48
  cursor="default"
49
49
  paddingX={2}
@@ -59,7 +59,14 @@ export const StepperStep = ({
59
59
  }
60
60
  pointerEvents={state === "active" ? "none" : "auto"}
61
61
  tabIndex={state === "active" ? -1 : undefined}
62
- sx={style.stepButton}
62
+ disabled={disabled}
63
+ aria-current={state === "active" ? "step" : undefined}
64
+ css={
65
+ state === "active"
66
+ ? style.stepButton._currentStep
67
+ : style.stepButton
68
+ }
69
+ fontWeight={state === "active" ? "bold" : undefined}
63
70
  >
64
71
  {children}
65
72
  </Button>
package/src/tab/Tabs.tsx CHANGED
@@ -1,19 +1,69 @@
1
+ "use client";
1
2
  import {
2
3
  Tabs as ChakraTabs,
3
- TabsProps as ChakraTabsProps,
4
- forwardRef,
4
+ TabsRootProps as ChakraTabsRootProps,
5
+ RecipeVariantProps,
5
6
  } from "@chakra-ui/react";
6
7
  import * as React from "react";
8
+ import { forwardRef, PropsWithChildren } from "react";
9
+ import { tabsSlotRecipe } from "../theme/slot-recipes/tabs";
10
+
11
+ type TabsVariantProps = RecipeVariantProps<typeof tabsSlotRecipe>;
12
+
13
+ /**
14
+ * Tabs are used to organize content into different sections.
15
+ * They are used to display different types of content in the same space.
16
+ *
17
+ * @example
18
+ * ```tsx
19
+ * <Tabs defaultValue="coming" fitted>
20
+ * <TabsList>
21
+ * <TabsTrigger value="coming">
22
+ * Kommende
23
+ * </TabsTrigger>
24
+ * <TabsTrigger value="completed">
25
+ * Fullført
26
+ * </TabsTrigger>
27
+ * <TabsTrigger value="cancelled">
28
+ * Avbestilt
29
+ * </TabsTrigger>
30
+ * </TabsList>
31
+ * <TabsContent value="coming">
32
+ * <Heading>Kommende</heading>
33
+ * <Text>Kommende billeter</Text>
34
+ * </TabsContent>
35
+ * <TabsContent value="completed">
36
+ * <Heading>Fullført</heading>
37
+ * <Text>Fullført billeter</Text>
38
+ * </TabsContent>
39
+ * <TabsContent value="cancelled">
40
+ * <Heading>Avbestilt</heading>
41
+ * <Text>Avbestilte billeter</Text>
42
+ * </TabsContent>
43
+ * </Tabs>
44
+ * ```
45
+ */
7
46
 
8
47
  export type TabsProps = Exclude<
9
- ChakraTabsProps,
10
- "colorScheme" | "variant" | "orientation" | "size"
11
- > & {
12
- /** Defaults to `base` */
13
- variant: "base" | "accent";
14
- /** Defaults to `sm` */
15
- size?: "xs" | "sm" | "md" | "lg";
16
- };
17
- export const Tabs = forwardRef<TabsProps, "div">((props, ref) => {
18
- return <ChakraTabs {...props} ref={ref} />;
48
+ ChakraTabsRootProps,
49
+ "colorPalette" | "orientation"
50
+ > &
51
+ PropsWithChildren<TabsVariantProps> & {
52
+ /** Defaults to `core` */
53
+ variant?: "core" | "accent";
54
+ /** Defaults to `sm` */
55
+ size?: "xs" | "sm" | "md" | "lg";
56
+ /** If Tabs should take up the full width or not. Defaults to `false` */
57
+ fitted?: boolean;
58
+ /** Defaults to `start` */
59
+ justify?: "start" | "center" | "end";
60
+ };
61
+ export const Tabs = forwardRef<HTMLDivElement, TabsProps>((props, ref) => {
62
+ const { variant = "core", size = "sm" } = props;
63
+ return <ChakraTabs.Root {...props} ref={ref} variant={variant} size={size} />;
19
64
  });
65
+
66
+ export const TabsList = ChakraTabs.List;
67
+ export const TabsTrigger = ChakraTabs.Trigger;
68
+ export const TabsIndicator = ChakraTabs.Indicator;
69
+ export const TabsContent = ChakraTabs.Content;
package/src/tab/index.tsx CHANGED
@@ -1,9 +1 @@
1
- export { Tab, TabList, TabPanel, TabPanels } from "@chakra-ui/react";
2
- export type {
3
- TabListProps,
4
- TabPanelProps,
5
- TabPanelsProps,
6
- TabProps,
7
- } from "@chakra-ui/react";
8
- export { Tabs } from "./Tabs";
9
- export type { TabsProps } from "./Tabs";
1
+ export * from "./Tabs";
@@ -1,26 +1,30 @@
1
+ "use client";
1
2
  import {
2
3
  Box,
3
- forwardRef,
4
4
  Table as ChakraTable,
5
- TableProps as ChakraTableProps,
5
+ TableRootProps as ChakraTableProps,
6
+ RecipeVariantProps,
7
+ useSlotRecipe,
6
8
  } from "@chakra-ui/react";
7
- import React from "react";
9
+ import React, { forwardRef, PropsWithChildren } from "react";
10
+ import { tableSlotRecipe } from "../theme/slot-recipes/table";
8
11
 
9
- export type TableProps = Omit<ChakraTableProps, "variant" | "colorScheme"> & {
10
- variant?: "simple" | "outline";
11
- colorScheme?: "grey" | "green";
12
- };
12
+ type TableVariantProps = RecipeVariantProps<typeof tableSlotRecipe>;
13
+
14
+ export type TableProps = Exclude<ChakraTableProps, "variant" | "colorPalette"> &
15
+ PropsWithChildren<TableVariantProps> & {
16
+ variant?: "ghost" | "core";
17
+ colorPalette?: "grey" | "green" | "white";
18
+ };
13
19
  /**
14
- * These components are used the same way as in Chakra UI. Please refer to [their documentation](https://chakra-ui.com/docs/data-display/table).
15
- *
16
- * The `Table` component has support for two different variants - `simple` and `outline`. The `simple` variant has basic lines between rows, while the `outline` variant has borders for each cell, plus a hover effect per row.
20
+ * The `Table` component has support for two different variants - `ghost` and `core`. The `ghost` variant has basic lines between rows, while the `core` variant has borders for each cell.
17
21
  *
18
- * You can also specify a `grey` or `green` `colorScheme` prop. Use `green` if you want to place the table on a light green background.
22
+ * You can also specify a `grey` or `green` `colorPalette` prop. Use `green` if you want to place the table on a light green background.
19
23
  *
20
24
  * Finally, there are three different `size` props you can specify - `sm`, `md` and `lg`.
21
25
  *
22
26
  * ```tsx
23
- * <Table variant="outlined" size="lg">
27
+ * <Table variant="core" size="lg">
24
28
  * <Thead>
25
29
  * ...
26
30
  * </Thead>
@@ -28,31 +32,32 @@ export type TableProps = Omit<ChakraTableProps, "variant" | "colorScheme"> & {
28
32
  * </Table>
29
33
  * ```
30
34
  */
31
- export const Table = forwardRef<TableProps, "table">((props, ref) => {
32
- const { variant, size, colorScheme, children, ...rest } = props;
35
+ export const Table = forwardRef<HTMLTableElement, TableProps>((props, ref) => {
36
+ const { variant = "ghost", size, colorPalette = "green", children } = props;
37
+
38
+ const recipe = useSlotRecipe({ recipe: tableSlotRecipe });
39
+ const styles = recipe({ variant, size });
33
40
  return (
34
- <Box {...rest} {...getStyleProps(props)}>
35
- <Box overflowX="auto" role="region">
36
- <ChakraTable
37
- variant={variant}
38
- size={size}
39
- colorScheme={colorScheme}
40
- ref={ref}
41
- >
42
- {children}
43
- </ChakraTable>
44
- </Box>
41
+ <Box overflowX="auto" role="region" {...getStyleProps(props)} {...props}>
42
+ <ChakraTable.Root
43
+ variant={variant}
44
+ size={size}
45
+ colorPalette={colorPalette}
46
+ css={styles}
47
+ ref={ref}
48
+ >
49
+ {children}
50
+ </ChakraTable.Root>
45
51
  </Box>
46
52
  );
47
53
  });
48
54
 
49
55
  function getStyleProps(props: TableProps) {
50
- return props.variant === "outline"
56
+ return props.variant === "core"
51
57
  ? {
52
- border: "1px solid",
53
- borderColor: props.colorScheme === "grey" ? "silver" : "blackAlpha.200",
54
- overflow: "hidden",
55
- borderRadius: "md",
58
+ borderRadius: "sm",
59
+ border: "sm",
60
+ borderColor: "outline.disabled",
56
61
  }
57
62
  : {};
58
63
  }
@@ -1,11 +1,13 @@
1
1
  export {
2
2
  TableCaption,
3
- Tbody,
4
- Td,
5
- Tfoot,
6
- Th,
7
- Thead,
8
- Tr,
3
+ TableHeader,
4
+ TableRow,
5
+ TableColumn,
6
+ TableColumnHeader,
7
+ TableRoot,
8
+ TableBody,
9
+ TableCell,
10
+ TableFooter,
9
11
  } from "@chakra-ui/react";
10
12
  export type {
11
13
  TableBodyProps,
@@ -13,7 +15,9 @@ export type {
13
15
  TableCellProps,
14
16
  TableColumnHeaderProps,
15
17
  TableFooterProps,
16
- TableHeadProps,
17
18
  TableRowProps,
19
+ TableHeaderProps,
20
+ TableColumnProps,
21
+ TableRootProps,
18
22
  } from "@chakra-ui/react";
19
23
  export * from "./Table";
@@ -0,0 +1,7 @@
1
+ export enum Brand {
2
+ VyDigital = "VyDigital",
3
+ VyUtvikling = "VyUtvikling",
4
+ CargoNet = "CargoNet",
5
+ }
6
+
7
+ export { fontFaces } from "./font-faces";
@@ -1,42 +1,50 @@
1
- import { theme as defaultTheme } from "@chakra-ui/theme";
2
- import tokens from "@vygruppen/spor-design-tokens";
3
- import * as components from "./components";
4
- import * as foundations from "./foundations";
1
+ import {
2
+ createSystem,
3
+ defaultBaseConfig,
4
+ defineConfig,
5
+ } from "@chakra-ui/react";
6
+ import { animationStyles } from "./tokens/animation-styles";
7
+ import { breakpoints } from "./tokens/breakpoints";
8
+ import { globalCss } from "./tokens/global-css";
9
+ import { keyframes } from "./tokens/keyframes";
10
+ import { recipes } from "./recipes";
11
+ import { semanticTokens } from "./semantic-tokens";
12
+ import { slotRecipes } from "./slot-recipes";
13
+ import { textStyles } from "./tokens/text-styles";
14
+ import { tokens } from "./tokens";
15
+ import { Brand } from "./brand";
16
+ import { config } from "./tokens/config";
5
17
 
6
- export enum Brand {
7
- VyDigital = "VyDigital",
8
- VyUtvikling = "VyUtvikling",
9
- CargoNet = "CargoNet",
10
- }
11
-
12
- export const theme = {
13
- ...defaultTheme,
14
- ...foundations,
15
- components: {
16
- ...defaultTheme.components,
17
- ...components,
18
- },
18
+ const generateTheme = (brand: Brand) => {
19
+ return defineConfig({
20
+ ...config,
21
+ globalCss,
22
+ theme: {
23
+ breakpoints,
24
+ keyframes,
25
+ tokens,
26
+ semanticTokens: semanticTokens[brand],
27
+ recipes,
28
+ slotRecipes,
29
+ textStyles,
30
+ animationStyles,
31
+ },
32
+ });
19
33
  };
20
34
 
21
- export const brandTheme = {
22
- [Brand.VyDigital]: {},
23
- [Brand.VyUtvikling]: {
24
- colors: {
25
- bg: {
26
- default: {
27
- dark: foundations.colors.darkGrey,
28
- },
29
- },
30
- surface: {
31
- default: {
32
- dark: foundations.colors.darkGrey,
33
- },
34
- },
35
- },
36
- },
37
- [Brand.CargoNet]: {
38
- colors: tokens.color.cargonet as any,
39
- },
35
+ export const themes = {
36
+ [Brand.VyDigital]: createSystem(
37
+ defaultBaseConfig,
38
+ generateTheme(Brand.VyDigital),
39
+ ),
40
+ [Brand.CargoNet]: createSystem(
41
+ defaultBaseConfig,
42
+ generateTheme(Brand.CargoNet),
43
+ ),
44
+ [Brand.VyUtvikling]: createSystem(
45
+ defaultBaseConfig,
46
+ generateTheme(Brand.VyUtvikling),
47
+ ),
40
48
  };
41
49
 
42
- export { fontFaces } from "./font-faces";
50
+ export const system = themes[Brand.VyDigital];
@@ -0,0 +1,43 @@
1
+ import { defineRecipe } from "@chakra-ui/react";
2
+
3
+ export const attachedInputsRecipe = defineRecipe({
4
+ base: {
5
+ display: "flex",
6
+ gap: "0.1rem",
7
+ width: "100%",
8
+ "& select": {
9
+ borderEndRadius: 0,
10
+ },
11
+ },
12
+ variants: {
13
+ orientation: {
14
+ horizontal: {
15
+ flexDirection: "row",
16
+ "& > *:first-of-type:not(:last-of-type) [data-attachable]": {
17
+ borderEndRadius: 0,
18
+ },
19
+ "& > *:not(:first-of-type):not(:last-of-type) [data-attachable]": {
20
+ borderRadius: 0,
21
+ },
22
+ "& > *:not(:first-of-type):last-of-type [data-attachable]": {
23
+ borderStartRadius: 0,
24
+ },
25
+ },
26
+ vertical: {
27
+ flexDirection: "column",
28
+ "& > *:first-of-type:not(:last-of-type) [data-attachable]": {
29
+ borderBottomRadius: 0,
30
+ },
31
+ "& > *:not(:first-of-type):not(:last-of-type) [data-attachable]": {
32
+ borderRadius: 0,
33
+ },
34
+ "& > *:not(:first-of-type):last-of-type [data-attachable]": {
35
+ borderTopRadius: 0,
36
+ },
37
+ },
38
+ },
39
+ },
40
+ defaultVariants: {
41
+ orientation: "horizontal",
42
+ },
43
+ });