@vygruppen/spor-react 11.3.10 → 12.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (322) hide show
  1. package/.turbo/turbo-build.log +33 -11
  2. package/.turbo/turbo-typegen.log +22 -0
  3. package/CHANGELOG.md +247 -0
  4. package/dist/index.d.mts +2589 -8303
  5. package/dist/index.d.ts +2589 -8303
  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 +23 -15
  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 +70 -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 +36 -21
  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,47 +1,59 @@
1
+ "use client";
2
+
1
3
  import {
2
- AltTransportOutline24Icon,
4
+ AltTransportFill24Icon,
5
+ ErrorFill24Icon,
3
6
  ErrorOutline24Icon,
4
- InformationOutline24Icon,
5
- SuccessOutline24Icon,
6
- WarningOutline24Icon,
7
- WarningFill24Icon,
7
+ IconComponent,
8
+ InformationFill24Icon,
9
+ QuestionFill24Icon,
8
10
  ServiceFill24Icon,
11
+ SuccessFill24Icon,
12
+ WarningFill24Icon,
9
13
  } from "@vygruppen/spor-icon-react";
10
- import React from "react";
14
+ import React, { PropsWithChildren } from "react";
11
15
  import { createTexts, useTranslation } from "../i18n";
12
- import { BaseAlertProps } from "./BaseAlert";
16
+ import { AlertProps } from "./Alert";
17
+ import { Box, useSlotRecipe, Alert as ChakraAlert } from "@chakra-ui/react";
18
+
19
+ type AlertIconProps = {
20
+ variant: ChakraAlert.RootProps["variant"];
21
+ customIcon?: IconComponent;
22
+ };
13
23
 
14
- type AlertIconProps = { variant: BaseAlertProps["variant"] };
15
24
  /**
16
25
  * Internal component that shows the correct icon for the alert
17
26
  */
18
- export const AlertIcon = ({ variant }: AlertIconProps) => {
19
- const Icon = getIcon(variant);
27
+ export const AlertIcon = ({ variant, customIcon }: AlertIconProps) => {
20
28
  const { t } = useTranslation();
29
+
30
+ const icon = customIcon ?? getIcon(variant);
31
+
21
32
  return (
22
- <Icon
23
- flexShrink={0}
24
- aria-label={t(texts[variant])}
25
- marginRight={1}
26
- color="darkGrey"
33
+ <Box
34
+ as={icon}
35
+ aria-label={t(texts[variant as keyof typeof texts])}
36
+ color={customIcon ? `alert.${variant}.icon` : undefined}
27
37
  />
28
38
  );
29
39
  };
30
40
 
31
- const getIcon = (variant: BaseAlertProps["variant"]) => {
41
+ const getIcon = (variant: AlertProps["variant"]) => {
32
42
  switch (variant) {
33
43
  case "info":
34
- return InformationOutline24Icon;
44
+ return InformationFill24Icon;
35
45
  case "success":
36
- return SuccessOutline24Icon;
37
- case "warning":
38
- return WarningOutline24Icon;
39
- case "alt-transport":
40
- return AltTransportOutline24Icon;
46
+ return SuccessFill24Icon;
47
+ case "important":
48
+ return WarningFill24Icon;
49
+ case "alt":
50
+ return AltTransportFill24Icon;
41
51
  case "error":
52
+ return ErrorFill24Icon;
53
+ case "error-secondary":
42
54
  return ErrorOutline24Icon;
43
- case "global-deviation":
44
- return WarningFill24Icon;
55
+ case "neutral":
56
+ return QuestionFill24Icon;
45
57
  case "service":
46
58
  return ServiceFill24Icon;
47
59
  }
@@ -60,34 +72,40 @@ const texts = createTexts({
60
72
  sv: "Succé",
61
73
  en: "Success",
62
74
  },
63
- warning: {
64
- nb: "Advarsel",
65
- nn: "Advarsel",
66
- sv: "Varning",
67
- en: "Warning",
75
+ important: {
76
+ nb: "Viktig",
77
+ nn: "Viktig",
78
+ sv: "Viktig",
79
+ en: "Important",
80
+ },
81
+ alt: {
82
+ nb: "Alternativ",
83
+ nn: "Alternativ",
84
+ sv: "Alternativ",
85
+ en: "Alternative",
68
86
  },
69
87
  error: {
70
88
  nb: "Feil",
71
89
  nn: "Feil",
72
- sv: "Error",
90
+ sv: "Fel",
73
91
  en: "Error",
74
92
  },
75
- "alt-transport": {
76
- nb: "Alternativ transport",
77
- nn: "Alternativ transport",
78
- sv: "Alternativ transport",
79
- en: "Alternative transport",
93
+ "error-secondary": {
94
+ nb: "Feil",
95
+ nn: "Feil",
96
+ sv: "Fel",
97
+ en: "Error",
80
98
  },
81
- service: {
82
- nb: "Driftsmelding",
83
- nn: "Driftsmelding",
84
- sv: "Servicemeddelande",
85
- en: "Service message",
99
+ neutral: {
100
+ nb: "Nøytral",
101
+ nn: "Nøytral",
102
+ sv: "Neutral",
103
+ en: "Neutral",
86
104
  },
87
- "global-deviation": {
88
- nb: "Trafikkmelding",
89
- nn: "Trafikkmelding",
90
- sv: "Trafikmeddelande",
91
- en: "Traffic announcement",
105
+ service: {
106
+ nb: "Service",
107
+ nn: "Service",
108
+ sv: "Service",
109
+ en: "Service",
92
110
  },
93
111
  });
@@ -1,30 +1,52 @@
1
+ "use client";
2
+
1
3
  import {
2
4
  Accordion,
3
- AccordionButton,
4
- AccordionIcon,
5
- AccordionItem,
6
- AccordionPanel,
7
5
  Box,
8
- Flex,
9
- useMultiStyleConfig,
6
+ ConditionalValue,
7
+ HStack,
8
+ RecipeVariantProps,
9
+ Span,
10
+ useSlotRecipe,
10
11
  } from "@chakra-ui/react";
11
- import React from "react";
12
+ import React, { forwardRef, PropsWithChildren } from "react";
12
13
  import { AlertIcon } from "./AlertIcon";
13
- import { BaseAlert, BaseAlertProps } from "./BaseAlert";
14
+ import { AlertProps } from "./Alert";
15
+ import { alertExpandableSlotRecipe } from "@/theme/slot-recipes/alert-expandable";
16
+ import { DropdownDownFill18Icon } from "@vygruppen/spor-icon-react";
17
+ import { AccordionItemContent } from "@/accordion";
18
+
19
+ type ExpandableAlertVariantProps = RecipeVariantProps<
20
+ typeof alertExpandableSlotRecipe
21
+ >;
14
22
 
15
- type ExpandableAlertProps = BaseAlertProps & {
16
- /** The title string */
17
- title: string;
18
- /** Callback for when the expandable panel is opened or closed */
19
- onToggle?: (isOpen: boolean) => void;
20
- /** Whether or not the default state of the expandable alert is open */
21
- defaultOpen?: boolean;
22
- /**
23
- * The HTML element used for the `title` prop.
24
- *
25
- * Defaults to h3 */
26
- headingLevel?: "h2" | "h3" | "h4" | "h5" | "h6";
27
- };
23
+ type ExpandableAlertProps = PropsWithChildren<ExpandableAlertVariantProps> &
24
+ Omit<Accordion.RootProps, "variant" | "orientation" | "size" | "value"> & {
25
+ /** The title string */
26
+ title: string;
27
+ /** Whether or not the default state of the expandable alert is open */
28
+ defaultOpen?: boolean;
29
+ /**
30
+ * The HTML element used for the `title` prop.
31
+ *
32
+ * Defaults to h3 */
33
+ headingLevel?: "h2" | "h3" | "h4" | "h5" | "h6";
34
+ /** If the user should be able to close the Accordion. Defaults to true */
35
+ collapsible?: boolean;
36
+ /**
37
+ * The variant of the alert. Default: info
38
+ * "info"
39
+ | "success"
40
+ | "important"
41
+ | "alt-transport"
42
+ | "error"
43
+ | "service"
44
+ | "global-deviation";
45
+ */
46
+ variant?: ConditionalValue<
47
+ "important" | "success" | "alt" | "info" | "error" | undefined
48
+ >;
49
+ };
28
50
  /**
29
51
  * An expandable alert component.
30
52
  *
@@ -36,58 +58,68 @@ type ExpandableAlertProps = BaseAlertProps & {
36
58
  * </ExpandableAlert>
37
59
  * ```
38
60
  */
39
- export const ExpandableAlert = ({
40
- variant,
41
- children,
42
- title,
43
- headingLevel = "h3",
44
- defaultOpen = false,
45
- onToggle = () => {},
46
- ...boxProps
47
- }: ExpandableAlertProps) => {
48
- const styles = useMultiStyleConfig("AlertExpandable", { variant });
49
- return (
50
- <BaseAlert variant={variant} {...boxProps} paddingX={0} paddingY={0}>
51
- <Accordion
52
- onChange={(expandedIndex) => onToggle(expandedIndex === 0)}
53
- defaultIndex={defaultOpen ? 0 : -1}
54
- allowToggle
55
- flexGrow="1"
61
+ export const ExpandableAlert = forwardRef<HTMLDivElement, ExpandableAlertProps>(
62
+ (props, ref) => {
63
+ const {
64
+ variant = "info",
65
+ children,
66
+ title,
67
+ collapsible = true,
68
+ headingLevel = "h3",
69
+ defaultOpen = false,
70
+ css,
71
+ ...rest
72
+ } = props;
73
+ const recipe = useSlotRecipe({ key: "alertExpandable" });
74
+ const styles = recipe({ variant });
75
+
76
+ const defaultValue = "alert-expandable";
77
+
78
+ return (
79
+ <Accordion.Root
80
+ defaultValue={defaultOpen ? [defaultValue] : undefined}
81
+ ref={ref}
82
+ css={{ ...styles.root, ...css }}
83
+ collapsible={collapsible}
84
+ {...rest}
56
85
  >
57
- <AccordionItem sx={styles.accordion}>
58
- <AccordionButton sx={styles.container}>
59
- <Flex
60
- justifyContent="space-between"
86
+ <Accordion.Item value={defaultValue}>
87
+ <Accordion.ItemTrigger css={styles.itemTrigger}>
88
+ <HStack
89
+ gap="1"
61
90
  alignItems="center"
62
- flexGrow="1"
91
+ justifyContent="space-between"
92
+ flex="1"
93
+ width="full"
63
94
  >
64
- <Flex as={headingLevel} alignItems="center">
65
- <AlertIcon variant={variant} />
66
-
67
- <Box
68
- as="span"
69
- sx={{
95
+ <HStack gap="1" alignItems="center">
96
+ <Box css={styles.indicator}>
97
+ <AlertIcon variant={variant} />
98
+ </Box>
99
+ <Span
100
+ as={headingLevel}
101
+ css={{
70
102
  // Truncate the title to one line
71
103
  display: "-webkit-box",
72
104
  overflow: "hidden",
73
105
  WebkitLineClamp: "1",
74
106
  WebkitBoxOrient: "vertical",
75
107
  }}
76
- color={variant === "service" ? "white" : "darkGrey"}
77
108
  >
78
109
  {title}
79
- </Box>
80
- </Flex>
81
- <AccordionIcon
82
- color={variant === "service" ? "white" : "darkGrey"}
83
- />
84
- </Flex>
85
- </AccordionButton>
86
- <AccordionPanel color={variant === "service" ? "white" : "darkGrey"}>
110
+ </Span>
111
+ </HStack>
112
+
113
+ <Accordion.ItemIndicator>
114
+ <DropdownDownFill18Icon />
115
+ </Accordion.ItemIndicator>
116
+ </HStack>
117
+ </Accordion.ItemTrigger>
118
+ <AccordionItemContent css={styles.itemContent}>
87
119
  {children}
88
- </AccordionPanel>
89
- </AccordionItem>
90
- </Accordion>
91
- </BaseAlert>
92
- );
93
- };
120
+ </AccordionItemContent>
121
+ </Accordion.Item>
122
+ </Accordion.Root>
123
+ );
124
+ },
125
+ );
@@ -1,41 +1,50 @@
1
+ "use client";
2
+
1
3
  import {
2
4
  Accordion,
3
- AccordionButton,
4
- AccordionIcon,
5
- AccordionItem,
6
- AccordionPanel,
7
- Box,
8
5
  Flex,
6
+ HStack,
7
+ RecipeVariantProps,
8
+ Span,
9
9
  Stack,
10
10
  Text,
11
- useMultiStyleConfig,
11
+ useSlotRecipe,
12
12
  } from "@chakra-ui/react";
13
- import React from "react";
13
+ import React, { forwardRef, PropsWithChildren } from "react";
14
+ import { AlertProps } from "./Alert";
14
15
  import { createTexts, useTranslation } from "../i18n";
15
- import { AlertIcon } from "./AlertIcon";
16
- import { BaseAlert, BaseAlertProps } from "./BaseAlert";
16
+ import { alertServiceSlotRecipe } from "../theme/slot-recipes/alert-service";
17
+ import {
18
+ DropdownDownFill24Icon,
19
+ ServiceFill24Icon,
20
+ WarningFill24Icon,
21
+ } from "@vygruppen/spor-icon-react";
17
22
 
18
- type ServiceAlertProps = BaseAlertProps & {
19
- /** The title string */
20
- title: string;
21
- /** The number of notifications when there is a list of multiple alerts */
22
- notification: number;
23
- /** The maximum width to display the service message
24
- *
25
- * Defaults to container.md */
26
- contentWidth: string;
27
- /** Callback for when the expandable panel is opened or closed */
28
- onToggle?: (isOpen: boolean) => void;
29
- /** Whether or not the default state of the alert is open */
30
- defaultOpen?: boolean;
31
- /**
32
- * The HTML element used for the `title` prop.
33
- *
34
- * Defaults to h3 */
35
- headingLevel?: "h2" | "h3" | "h4" | "h5" | "h6";
36
- /** The variant of Service Alert. Default: service */
37
- variant?: "service" | "global-deviation";
38
- };
23
+ type ServiceAlertVariantProps = RecipeVariantProps<
24
+ typeof alertServiceSlotRecipe
25
+ >;
26
+
27
+ type ServiceAlertProps = Omit<AlertProps, "variant"> &
28
+ PropsWithChildren<ServiceAlertVariantProps> &
29
+ Omit<Accordion.RootProps, "variant" | "orientation" | "size" | "value"> & {
30
+ /** The title string */
31
+ title: string;
32
+ /** The number of notifications when there is a list of multiple alerts */
33
+ notification: number;
34
+ /** The maximum width to display the service message
35
+ *
36
+ * Defaults to container.md */
37
+ contentWidth: string;
38
+ /** Whether or not the default state of the alert is open */
39
+ defaultOpen?: boolean;
40
+ /**
41
+ * The HTML element used for the `title` prop.
42
+ *
43
+ * Defaults to h3 */
44
+ headingLevel?: "h2" | "h3" | "h4" | "h5" | "h6";
45
+ /** The variant of Service Alert. Default: service */
46
+ variant?: "service" | "global-deviation";
47
+ };
39
48
  /**
40
49
  * A service alert component.
41
50
  *
@@ -47,111 +56,92 @@ type ServiceAlertProps = BaseAlertProps & {
47
56
  * </ServiceAlert>
48
57
  * ```
49
58
  */
50
- export const ServiceAlert = ({
51
- variant = "service",
52
- children,
53
- title,
54
- notification,
55
- contentWidth = "container.md",
56
- headingLevel = "h3",
57
- defaultOpen = false,
58
- onToggle = () => {},
59
- ...boxProps
60
- }: ServiceAlertProps) => {
61
- const { t } = useTranslation();
62
- const styles = useMultiStyleConfig("AlertService", { variant });
63
- return (
64
- <BaseAlert
65
- variant={variant}
66
- {...boxProps}
67
- paddingX={0}
68
- paddingY={0}
69
- sx={styles.outerBox}
70
- >
71
- <Accordion
72
- onChange={(expandedIndex) => onToggle(expandedIndex === 0)}
73
- defaultIndex={defaultOpen ? 0 : -1}
74
- allowToggle
75
- flexGrow={1}
76
- sx={{ outline: "none" }}
77
- variant={variant}
59
+
60
+ export const ServiceAlert = forwardRef<HTMLDivElement, ServiceAlertProps>(
61
+ (props, ref) => {
62
+ const {
63
+ variant = "service",
64
+ children,
65
+ title,
66
+ notification,
67
+ contentWidth = "container.md",
68
+ headingLevel = "h3",
69
+ defaultOpen = false,
70
+ collapsible = true,
71
+ css,
72
+ ...rest
73
+ } = props;
74
+ const { t } = useTranslation();
75
+ const recipe = useSlotRecipe({ key: "alertService" });
76
+ const styles = recipe({ variant });
77
+
78
+ const defaultValue = "spor-service-alert";
79
+ return (
80
+ <Accordion.Root
81
+ defaultValue={defaultOpen ? [defaultValue] : undefined}
82
+ collapsible={collapsible}
83
+ css={{ ...styles.root, ...css }}
84
+ ref={ref}
85
+ {...rest}
78
86
  >
79
- <AccordionItem>
80
- <AccordionButton sx={styles.container}>
81
- <Stack
82
- flexDirection="row"
83
- justifyContent="center"
87
+ <Accordion.Item value={defaultValue}>
88
+ <Accordion.ItemTrigger css={styles.itemTrigger}>
89
+ <HStack
90
+ justifyContent="space-between"
91
+ alignContent="center"
84
92
  width="100%"
85
- paddingX={2}
93
+ maxWidth={contentWidth}
86
94
  >
87
- <Flex
88
- justifyContent="space-between"
89
- alignItems="center"
90
- flexGrow={1}
91
- maxWidth={contentWidth}
92
- >
93
- <Flex as={headingLevel} alignItems="center">
94
- {notification === 1 && <AlertIcon variant={variant} />}
95
-
96
- <Box
97
- as="span"
98
- sx={{
99
- // Truncate the title to one line
100
- display: "-webkit-box",
101
- overflow: "hidden",
102
- WebkitLineClamp: "1",
103
- WebkitBoxOrient: "vertical",
104
- }}
105
- >
106
- {title}
107
- </Box>
108
- </Flex>
109
-
110
- <Flex alignItems="center">
111
- {notification && (
112
- <Text sx={styles.notificationText}>
113
- {t(texts.notification(notification))}
114
- </Text>
115
- )}
116
-
117
- <AccordionIcon />
118
- </Flex>
95
+ <HStack as={headingLevel} alignItems="center" gap="1">
96
+ {variant === "service" ? (
97
+ <ServiceFill24Icon aria-label={t(texts.service)} />
98
+ ) : (
99
+ <WarningFill24Icon
100
+ aria-label={t(texts["global-deviation"])}
101
+ />
102
+ )}
103
+ <Span
104
+ css={{
105
+ // Truncate the title to one line
106
+ display: "-webkit-box",
107
+ overflow: "hidden",
108
+ WebkitLineClamp: "1",
109
+ WebkitBoxOrient: "vertical",
110
+ ...styles.itemTriggerTitle,
111
+ }}
112
+ >
113
+ {title}
114
+ </Span>
115
+ </HStack>
116
+ <Flex alignItems="center" gap={[0.5, null, null, 1]}>
117
+ {notification && (
118
+ <Text css={styles.notificationText}>
119
+ {t(texts.notification(notification))}
120
+ </Text>
121
+ )}
122
+ <Accordion.ItemIndicator>
123
+ <DropdownDownFill24Icon color="icon.inverted" />
124
+ </Accordion.ItemIndicator>
119
125
  </Flex>
120
- </Stack>
121
- </AccordionButton>
126
+ </HStack>
127
+ </Accordion.ItemTrigger>
122
128
 
123
- <AccordionPanel sx={styles.serviceMessageContent}>
129
+ <Accordion.ItemContent asChild>
124
130
  <Stack flexDirection="row" justifyContent="center" width="100%">
125
- <Stack
126
- justifyContent="center"
127
- alignItems="center"
128
- flexGrow={1}
131
+ <Accordion.ItemBody
132
+ as={Stack}
129
133
  maxWidth={contentWidth}
130
- flexFlow="column"
131
- gap={2}
132
- sx={{
133
- p: {
134
- padding: "0.8rem 0",
135
- borderBottom: "0.08rem solid",
136
- borderColor:
137
- variant === "global-deviation"
138
- ? "blackAlpha.400"
139
- : "whiteAlpha.400",
140
- },
141
- "p:last-child": {
142
- borderBottom: "none",
143
- },
144
- }}
134
+ css={styles.itemBody}
145
135
  >
146
136
  {children}
147
- </Stack>
137
+ </Accordion.ItemBody>
148
138
  </Stack>
149
- </AccordionPanel>
150
- </AccordionItem>
151
- </Accordion>
152
- </BaseAlert>
153
- );
154
- };
139
+ </Accordion.ItemContent>
140
+ </Accordion.Item>
141
+ </Accordion.Root>
142
+ );
143
+ },
144
+ );
155
145
 
156
146
  const texts = createTexts({
157
147
  notification: (notification) => {
@@ -163,4 +153,16 @@ const texts = createTexts({
163
153
  en: `${numNotification} ${numNotification > 1 ? "notifications" : "notification"}`,
164
154
  };
165
155
  },
156
+ service: {
157
+ nb: "Driftsmelding",
158
+ nn: "Driftsmelding",
159
+ sv: "Service meddelande",
160
+ en: "Service message",
161
+ },
162
+ "global-deviation": {
163
+ nb: "Trafikkmelding",
164
+ nn: "Trafikkmelding",
165
+ sv: "Trafikmeddelande",
166
+ en: "Traffic announcement",
167
+ },
166
168
  });
@@ -1,4 +1,3 @@
1
- export * from "./ClosableAlert";
2
1
  export * from "./ExpandableAlert";
3
- export * from "./StaticAlert";
4
2
  export * from "./ServiceAlert";
3
+ export * from "./Alert";