@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
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vygruppen/spor-react",
3
- "version": "11.3.10",
3
+ "version": "12.0.0",
4
4
  "main": "./dist/index.js",
5
5
  "module": "./dist/index.mjs",
6
6
  "types": "./dist/index.d.ts",
@@ -13,29 +13,34 @@
13
13
  "directory": "packages/spor-react"
14
14
  },
15
15
  "dependencies": {
16
+ "@chakra-ui/react": "^3.9.0",
17
+ "@ark-ui/react": "^4.9.2",
16
18
  "@chakra-ui/anatomy": "^2.3.4",
17
- "@chakra-ui/react": "^2.8.2",
18
19
  "@chakra-ui/react-use-size": "^2.1.0",
19
20
  "@chakra-ui/styled-system": "^2.12.0",
20
21
  "@chakra-ui/system": "^2.6.2",
21
22
  "@chakra-ui/theme": "^3.4.6",
22
23
  "@chakra-ui/theme-tools": "^2.0.12",
23
24
  "@chakra-ui/utils": "^2.2.2",
24
- "@emotion/react": "^11.11.4",
25
+ "@emotion/react": "^11.14.0",
25
26
  "@emotion/styled": "^11.11.5",
26
- "@internationalized/date": "^3.5.4",
27
+ "@internationalized/date": "^3.6.0",
27
28
  "awesome-phonenumber": "^5.11.0",
28
29
  "deepmerge": "^4.3.1",
29
- "framer-motion": "^8.5.5",
30
- "lottie-react": "^2.4.0",
30
+ "framer-motion": "^11.11.17",
31
+ "lottie-react": "^2.4.1",
32
+ "next-themes": "^0.4.4",
31
33
  "react-aria": "^3.33.1",
34
+ "react-icons": "^5.4.0",
32
35
  "react-stately": "^3.31.1",
33
36
  "react-swipeable": "^7.0.1",
34
- "@vygruppen/spor-design-tokens": "3.10.0",
35
- "@vygruppen/spor-icon-react": "3.14.0",
36
- "@vygruppen/spor-loader": "0.5.0"
37
+ "usehooks-ts": "^3.1.0",
38
+ "@vygruppen/spor-design-tokens": "4.0.0",
39
+ "@vygruppen/spor-loader": "0.6.0",
40
+ "@vygruppen/spor-icon-react": "4.0.0"
37
41
  },
38
42
  "devDependencies": {
43
+ "@chakra-ui/cli": "^3.8.0",
39
44
  "@react-types/datepicker": "^3.10.0",
40
45
  "@react-types/shared": "^3.27.0",
41
46
  "@testing-library/jest-dom": "^6.4.5",
@@ -46,18 +51,21 @@
46
51
  "react": "^18.3.1",
47
52
  "react-dom": "^18.3.1",
48
53
  "tsup": "^7.2.0",
54
+ "typescript": "^5.7.3",
49
55
  "vitest": "^0.26.3",
50
56
  "vitest-axe": "^0.1.0",
51
57
  "vitest-canvas-mock": "^0.2.2",
52
- "typescript": "^5.7.3",
53
- "@vygruppen/tsconfig": "0.0.0"
58
+ "@vygruppen/tsconfig": "0.1.0"
54
59
  },
55
60
  "peerDependencies": {
56
61
  "react": "^18.2.0",
57
62
  "react-dom": "^18.2.0"
58
63
  },
59
64
  "scripts": {
60
- "build": "tsup",
61
- "dev": "tsup --watch"
65
+ "build": "pnpm typegen && tsup",
66
+ "dev": "tsup --watch",
67
+ "typegen": "npx @chakra-ui/cli typegen src/theme/index.ts",
68
+ "typegen:watch": "npx @chakra-ui/cli typegen src/theme/index.ts --watch",
69
+ "typegen:strict": "npx @chakra-ui/cli typegen /src/theme/index.ts --strict"
62
70
  }
63
71
  }
@@ -1,64 +1,115 @@
1
+ "use client";
2
+
1
3
  import {
4
+ Box,
2
5
  Accordion as ChakraAccordion,
3
- AccordionProps as ChakraAccordionProps,
4
- forwardRef,
5
- } from "@chakra-ui/react";
6
- import React from "react";
7
- import { Stack, StackProps } from "../layout";
8
- export {
9
- AccordionButton,
10
- AccordionIcon,
11
- AccordionItem,
12
- AccordionPanel,
13
- } from "@chakra-ui/react";
14
- export type {
15
- AccordionButtonProps,
16
- AccordionItemProps,
17
- AccordionPanelProps,
6
+ HStack,
7
+ Stack,
8
+ useSlotRecipe,
18
9
  } from "@chakra-ui/react";
10
+ import { DropdownDownFill24Icon } from "@vygruppen/spor-icon-react";
11
+ import React, { forwardRef } from "react";
12
+ import {
13
+ AccordionProps,
14
+ AccordionItemTriggerProps,
15
+ AccordionItemContentProps,
16
+ } from "./types";
17
+ import { warnAboutMismatchingIcon } from "./helpers";
19
18
 
20
- export type AccordionProps = Omit<ChakraAccordionProps, "variant" | "size"> & {
21
- /**
22
- * The display variant of the accordion items.
23
- *
24
- * - `ghost` renders a pretty unstyled expandable list without any borders
25
- * - `base` renders an outlined version
26
- * - `floating` renders a version with a drop shadow
27
- */
28
- variant?: "ghost" | "base" | "floating";
29
- /** The margin between accordion items */
30
- spacing?: StackProps["spacing"];
31
- };
32
19
  /*
33
- * Wraps a set of ExpandableItem or AccordionItem components.
20
+ * Wraps a set of AccordionItem or AccordionItem components.
34
21
  *
35
22
  * ```tsx
36
23
  * <Accordion variant="ghost">
37
- * <ExpandableItem title="Is Spor easy?" headingLevel="h3">
38
- * Yes
39
- * </ExpandableItem>
40
- * <ExpandableItem title="Is Spor lovable?" headingLevel="h3">
41
- * 🥰
42
- * </ExpandableItem>
24
+ * <AccordionItem>
25
+ * <AccordionItemTrigger>Is Spor easy?</AccordionItemTrigger>
26
+ * <AccordionItemContent>Yes</AccordionItemContent>
27
+ * </AccordionItem>
28
+ * <AccordionItem>
29
+ * <AccordionItemTrigger>Is Spor lovable?</AccordionItemTrigger>
30
+ * <AccordionItemContent>Yes</AccordionItemContent>
31
+ * </AccordionItem>
32
+ * </Accordion>
33
+ * ```
34
+ *
35
+ * If you need to have a default open item, you can use the `defaultValue` prop.
36
+ *
37
+ * ```tsx
38
+ * <Accordion defaultValue={["a"]}>
39
+ * <AccordionItem value="a">
40
+ * <AccordionItemTrigger>Is Spor easy?</AccordionItemTrigger>
41
+ * <AccordionItemContent>Yes</AccordionItemContent>
42
+ * </AccordionItem>
43
+ * <AccordionItem value="b">
44
+ * <AccordionItemTrigger>Is Spor lovable?</AccordionItemTrigger>
45
+ * <AccordionItemContent>Yes</AccordionItemContent>
46
+ * </AccordionItem>
43
47
  * </Accordion>
44
48
  * ```
45
49
  *
46
50
  * If you only have one expandable item, you can use the `<Expandable />` component instead.
51
+ *
52
+ * @see https://spor.vy.no/components/accordion
47
53
  */
48
- export const Accordion = forwardRef<AccordionProps, "div">(
49
- ({ children, spacing = 2, ...props }, ref) => {
50
- const defaultIndex =
51
- typeof props.defaultIndex === "number" && props.allowMultiple
52
- ? [props.defaultIndex]
53
- : props.defaultIndex;
54
+
55
+ export const Accordion = forwardRef<HTMLDivElement, AccordionProps>(
56
+ (props, ref) => {
57
+ const { variant = "core", children, gap = 2, ...rest } = props;
58
+ const recipe = useSlotRecipe({ key: "accordion" });
59
+ const styles = recipe({ variant });
54
60
  return (
55
- <ChakraAccordion
56
- {...props}
61
+ <ChakraAccordion.Root
62
+ {...rest}
57
63
  ref={ref}
58
- defaultIndex={defaultIndex as number[] | undefined}
64
+ css={styles.root}
65
+ variant={variant}
59
66
  >
60
- <Stack spacing={spacing}>{children}</Stack>
61
- </ChakraAccordion>
67
+ <Stack gap={gap}>{children}</Stack>
68
+ </ChakraAccordion.Root>
62
69
  );
63
70
  },
64
71
  );
72
+
73
+ export const AccordionItemTrigger = forwardRef<
74
+ HTMLButtonElement,
75
+ AccordionItemTriggerProps
76
+ >(function AccordionItemTrigger(props, ref) {
77
+ const { startElement, children, headingLevel, ...rest } = props;
78
+ warnAboutMismatchingIcon({ icon: startElement });
79
+ const recipe = useSlotRecipe({ key: "accordion" });
80
+ const styles = recipe();
81
+ return (
82
+ <Box as={headingLevel}>
83
+ <ChakraAccordion.ItemTrigger {...rest} ref={ref} css={styles.itemTrigger}>
84
+ <HStack flex="1" gap={1} textAlign="start" width="full">
85
+ {startElement && startElement}
86
+ {children}
87
+ </HStack>
88
+
89
+ <ChakraAccordion.ItemIndicator>
90
+ <DropdownDownFill24Icon />
91
+ </ChakraAccordion.ItemIndicator>
92
+ </ChakraAccordion.ItemTrigger>
93
+ </Box>
94
+ );
95
+ });
96
+
97
+ export const AccordionItemContent = forwardRef<
98
+ HTMLDivElement,
99
+ AccordionItemContentProps
100
+ >(function AccordionItemContent(props, ref) {
101
+ const { children } = props;
102
+
103
+ const recipe = useSlotRecipe({ key: "accordion" });
104
+ const styles = recipe();
105
+
106
+ return (
107
+ <ChakraAccordion.ItemContent css={styles.itemContent}>
108
+ <ChakraAccordion.ItemBody {...props} ref={ref}>
109
+ {children}
110
+ </ChakraAccordion.ItemBody>
111
+ </ChakraAccordion.ItemContent>
112
+ );
113
+ });
114
+
115
+ export const AccordionItem = ChakraAccordion.Item;
@@ -1,40 +1,15 @@
1
+ "use client";
2
+
3
+ import React, { forwardRef } from "react";
1
4
  import {
2
- AccordionButton,
3
- AccordionIcon,
5
+ Accordion,
4
6
  AccordionItem,
5
- AccordionItemProps,
6
- AccordionPanel,
7
- Box,
8
- Flex,
9
- } from "@chakra-ui/react";
10
- import React from "react";
11
- import { Accordion, AccordionProps } from "./Accordion";
12
-
13
- type HeadingLevel = "h2" | "h3" | "h4" | "h5" | "h6";
14
- type ExpandableProps = Omit<
15
- AccordionProps,
16
- "title" | "index" | "defaultIndex" | "onChange"
17
- > & {
18
- /** The hidden content */
19
- children: React.ReactNode;
20
- /** The title that's shown inside the toggle button */
21
- title: React.ReactNode;
22
- /** The semantic heading level of the toggle button */
23
- headingLevel?: HeadingLevel;
24
- /**
25
- * Icon shown to the left of the title
26
- *
27
- * Make sure it's the 24px outlined version of the icon
28
- */
29
- leftIcon?: React.ReactNode;
7
+ AccordionItemContent,
8
+ AccordionItemTrigger,
9
+ } from "./Accordion";
10
+ import { ExpandableItemProps, ExpandableProps } from "./types";
11
+ import { warnAboutMismatchingIcon } from "./helpers";
30
12
 
31
- /** Controlled value of whether the accordion is open or not */
32
- isOpen?: boolean;
33
- /** Default value of when the accordion is open or not */
34
- defaultOpen?: boolean;
35
- /** Callback for when the expandable opens or closes */
36
- onChange?: (isOpen: boolean) => void;
37
- };
38
13
  /**
39
14
  * A standalone expandable component.
40
15
  *
@@ -42,118 +17,70 @@ type ExpandableProps = Omit<
42
17
  * If you want several expandables in a row, use the `Accordion` and `ExpandableItem` components instead.
43
18
  *
44
19
  * ```tsx
45
- * <Expandable title="Click for more" variant="base">
20
+ * <Expandable title="Click for more" variant="core">
46
21
  * <Text>MORE! 🎉</Text>
47
22
  * </Expandable>
48
23
  * ```
49
24
  */
50
- export const Expandable = ({
51
- children,
52
- headingLevel,
53
- title,
54
- leftIcon,
55
- defaultOpen,
56
- isOpen,
57
- onChange = () => {},
58
- ...rest
59
- }: ExpandableProps) => {
60
- return (
61
- <Accordion
62
- {...rest}
63
- index={isOpen ? 0 : undefined}
64
- defaultIndex={defaultOpen ? 0 : undefined}
65
- onChange={(expandedIndex) => onChange(expandedIndex === 0)}
66
- >
67
- <ExpandableItem
68
- headingLevel={headingLevel}
69
- title={title}
70
- leftIcon={leftIcon}
71
- >
72
- {children}
73
- </ExpandableItem>
74
- </Accordion>
75
- );
76
- };
77
25
 
78
- export type ExpandableItemProps = Omit<AccordionItemProps, "title"> & {
79
- /** The hidden content */
80
- children: React.ReactNode;
81
- /** The title that's shown inside the toggle button */
82
- title: React.ReactNode;
83
- /** The semantic heading level of the toggle button */
84
- headingLevel?: HeadingLevel;
85
- /**
86
- * Icon shown to the left of the title
87
- *
88
- * Make sure it's the 24px outlined version of the icon
89
- */
90
- leftIcon?: React.ReactNode;
91
- };
26
+ export const Expandable = forwardRef<HTMLDivElement, ExpandableProps>(
27
+ (props, ref) => {
28
+ const { title, children, headingLevel, startElement, ...rest } = props;
29
+ return (
30
+ <Accordion {...props} ref={ref} {...rest}>
31
+ <ExpandableItem
32
+ title={title}
33
+ headingLevel={headingLevel}
34
+ startElement={startElement}
35
+ value="single-expandable"
36
+ >
37
+ {children}
38
+ </ExpandableItem>
39
+ </Accordion>
40
+ );
41
+ },
42
+ );
43
+
92
44
  /**
93
45
  * An item in a set of Expandables. Must be wrapped in an `<Accordion>` component.
94
46
  *
95
47
  * ```tsx
96
48
  * <Accordion variant="ghost">
97
- * <ExpandableItem title="Is Spor easy?" headingLevel="h3">
49
+ * <ExpandableItem value="a" title="Is Spor easy?" headingLevel="h3">
98
50
  * Yes
99
51
  * </ExpandableItem>
100
- * <ExpandableItem title="Do you love it?" headingLevel="h3">
52
+ * <ExpandableItem value="b" title="Do you love it?" headingLevel="h3">
101
53
  * 🥰
102
54
  * </ExpandableItem>
103
55
  * </Accordion>
104
56
  * ```
105
57
  *
106
- * If you need even more control, you can put together your own expandable with the `Accordion`, `AccordionItem`, `AccordionButton`, `AccordionIcon` and `AccordionPanel` components.
58
+ *
59
+ * If you need even more control, you can put together your own expandable with the `Accordion`, `AccordionItem`, `AccordionItemTrigger`, and `AccordionItemContent` components.
60
+ *
61
+ * @see https://spor.vy.no/components/accordion
107
62
  */
108
- export const ExpandableItem = ({
109
- children,
110
- title,
111
- headingLevel = "h3",
112
- leftIcon,
113
- ...rest
114
- }: ExpandableItemProps) => {
115
- warnAboutMismatchingIcon({ icon: leftIcon });
63
+
64
+ export const ExpandableItem = (props: ExpandableItemProps) => {
65
+ const {
66
+ title,
67
+ children,
68
+ value,
69
+ headingLevel = "h3",
70
+ startElement,
71
+ ...rest
72
+ } = props;
73
+ warnAboutMismatchingIcon({ icon: startElement });
116
74
  return (
117
- <AccordionItem {...rest}>
118
- <Box as={headingLevel}>
119
- <AccordionButton>
120
- <Flex alignItems="center">
121
- {leftIcon && <Box marginRight={1}>{leftIcon}</Box>}
122
- {title}
123
- </Flex>
124
- <AccordionIcon />
125
- </AccordionButton>
126
- </Box>
127
- <AccordionPanel>{children}</AccordionPanel>
75
+ <AccordionItem value={value} {...rest}>
76
+ <AccordionItemTrigger
77
+ startElement={startElement}
78
+ headingLevel={headingLevel}
79
+ >
80
+ {title}
81
+ </AccordionItemTrigger>
82
+
83
+ <AccordionItemContent>{children}</AccordionItemContent>
128
84
  </AccordionItem>
129
85
  );
130
86
  };
131
-
132
- type WarnAboutMismatchingIcon = {
133
- icon: any;
134
- };
135
- const warnAboutMismatchingIcon = ({ icon }: WarnAboutMismatchingIcon) => {
136
- if (process.env.NODE_ENV !== "production") {
137
- const displayName = icon?.type?.render?.displayName;
138
- if (!displayName) {
139
- return;
140
- }
141
- if (displayName.includes("Fill")) {
142
- console.warn(
143
- `You passed a filled icon. This component requires outlined icons. You passed ${displayName}, replace it with ${displayName.replace(
144
- "Fill",
145
- "Outline",
146
- )}.`,
147
- );
148
- return;
149
- }
150
- if (!displayName.includes("24Icon")) {
151
- console.warn(
152
- `The icon you passed was of the wrong size. You passed ${displayName}, replace it with ${displayName.replace(
153
- /(\d{2})Icon/,
154
- "24Icon",
155
- )}.`,
156
- );
157
- }
158
- }
159
- };
@@ -0,0 +1,31 @@
1
+ type WarnAboutMismatchingIcon = {
2
+ icon: any;
3
+ };
4
+
5
+ export const warnAboutMismatchingIcon = ({
6
+ icon,
7
+ }: WarnAboutMismatchingIcon) => {
8
+ if (process.env.NODE_ENV !== "production") {
9
+ const displayName = icon?.type?.render?.displayName;
10
+ if (!displayName) {
11
+ return;
12
+ }
13
+ if (displayName.includes("Fill")) {
14
+ console.warn(
15
+ `You passed a filled icon. This component requires outlined icons. You passed ${displayName}, replace it with ${displayName.replace(
16
+ "Fill",
17
+ "Outline",
18
+ )}.`,
19
+ );
20
+ return;
21
+ }
22
+ if (!displayName.includes("24Icon")) {
23
+ console.warn(
24
+ `The icon you passed was of the wrong size. You passed ${displayName}, replace it with ${displayName.replace(
25
+ /(\d{2})Icon/,
26
+ "24Icon",
27
+ )}.`,
28
+ );
29
+ }
30
+ }
31
+ };
@@ -0,0 +1,60 @@
1
+ import { accordionSlotRecipe } from "@/theme/slot-recipes/accordion";
2
+ import { RecipeVariantProps } from "@chakra-ui/react";
3
+ import {
4
+ AccordionRootProps as ChakraAccordionProps,
5
+ Accordion as ChakraAccordion,
6
+ } from "@chakra-ui/react";
7
+ import { PropsWithChildren } from "react";
8
+
9
+ export type AccordionVariantProps = RecipeVariantProps<
10
+ typeof accordionSlotRecipe
11
+ >;
12
+
13
+ export type AccordionProps = Exclude<
14
+ ChakraAccordionProps,
15
+ "variant" | "size" | "orientation"
16
+ > &
17
+ AccordionVariantProps &
18
+ PropsWithChildren & {
19
+ /**
20
+ * The display variant of the accordion items.
21
+ *
22
+ * - `core` renders a pretty unstyled expandable list without any borders
23
+ * - `base` renders an outlined version
24
+ * - `floating` renders a version with a drop shadow
25
+ */
26
+ variant?: "ghost" | "core" | "floating";
27
+ /* Gap between accordions */
28
+ gap?: string | number;
29
+ };
30
+
31
+ export type HeadingLevel = {
32
+ /** Heading level of the trigger button */
33
+ headingLevel?: "h2" | "h3" | "h4" | "h5" | "h6";
34
+ };
35
+
36
+ export type AccordionItemTriggerProps = Omit<
37
+ ChakraAccordion.ItemTriggerProps,
38
+ "indicatorElement"
39
+ > &
40
+ HeadingLevel & {
41
+ /** Icon to be displayed on the left of the trigger button. Use 24px outline. */
42
+ startElement?: React.ReactNode;
43
+ };
44
+
45
+ export type AccordionItemContentProps = ChakraAccordion.ItemContentProps & {
46
+ children?: React.ReactNode;
47
+ };
48
+
49
+ export type ExpandableProps = AccordionProps &
50
+ AccordionItemTriggerProps &
51
+ HeadingLevel & {
52
+ title: string;
53
+ };
54
+
55
+ export type ExpandableItemProps = HeadingLevel & {
56
+ value: string;
57
+ title: string;
58
+ children?: React.ReactNode;
59
+ startElement?: React.ReactNode;
60
+ };
@@ -0,0 +1,101 @@
1
+ "use client";
2
+
3
+ import {
4
+ Alert as ChakraAlert,
5
+ useDisclosure,
6
+ HStack,
7
+ useSlotRecipe,
8
+ } from "@chakra-ui/react";
9
+ import React, { forwardRef } from "react";
10
+ import { AlertIcon } from "./AlertIcon";
11
+ import { CloseButton } from "@/button";
12
+ import { IconComponent } from "@vygruppen/spor-icon-react";
13
+
14
+ export type AlertProps = Omit<ChakraAlert.RootProps, "colorPalette"> & {
15
+ /** Whether or not to show the alert icon */
16
+ showIndicator?: boolean;
17
+ /** Whether or not the alert is closable */
18
+ icon?: IconComponent;
19
+ closable?: boolean;
20
+ /** Callback for when the alert is closed */
21
+ onAlertClose?: () => void;
22
+ };
23
+
24
+ /**
25
+ *
26
+ * Alerts are used to communicate important information to the user.
27
+ * They can be used to inform about success, errors, warnings, or other important information.
28
+ *
29
+ * ```tsx
30
+ * <Alert variant="info" title="Information">
31
+ * This is an information alert
32
+ * </Alert>
33
+ * ```
34
+ *
35
+ * You may also use the closable prop to allow the user to dismiss the alert.
36
+ *
37
+ * ```tsx
38
+ * <Alert variant="info" title="Information" closable>
39
+ * This is an closable alert
40
+ * </Alert>
41
+ *
42
+ * @see Docs https://spor.vy.no/alert
43
+ */
44
+
45
+ export const Alert = forwardRef<HTMLDivElement, AlertProps>((props, ref) => {
46
+ const {
47
+ title,
48
+ showIndicator = true,
49
+ icon,
50
+ closable = false,
51
+ onAlertClose,
52
+ children,
53
+ } = props;
54
+ const { open, onClose } = useDisclosure({ defaultOpen: true });
55
+
56
+ const handleAlertClose = () => {
57
+ onClose();
58
+ onAlertClose?.();
59
+ };
60
+
61
+ const recipe = useSlotRecipe({ key: "alert" });
62
+ const styles = recipe({ variant: props.variant });
63
+
64
+ if (!open) return null;
65
+ return (
66
+ <ChakraAlert.Root ref={ref} {...props}>
67
+ <ChakraAlert.Content flexDirection={title ? "column" : "row"}>
68
+ <HStack gap="1" alignItems="flex-start">
69
+ {showIndicator && (
70
+ <ChakraAlert.Indicator asChild>
71
+ <AlertIcon variant={props.variant} customIcon={icon} />
72
+ </ChakraAlert.Indicator>
73
+ )}
74
+ {title && (
75
+ <ChakraAlert.Title paddingRight={closable ? 6 : 0}>
76
+ {title}
77
+ </ChakraAlert.Title>
78
+ )}
79
+ </HStack>
80
+ {children && (
81
+ <ChakraAlert.Description
82
+ paddingLeft={title ? 0.5 : 0}
83
+ paddingRight={closable ? 6 : 0}
84
+ >
85
+ {children}
86
+ </ChakraAlert.Description>
87
+ )}
88
+ </ChakraAlert.Content>
89
+ {closable && (
90
+ <CloseButton
91
+ size="xs"
92
+ position="absolute"
93
+ top="1.5"
94
+ right="1.5"
95
+ onClick={handleAlertClose}
96
+ css={styles.closeButton}
97
+ />
98
+ )}
99
+ </ChakraAlert.Root>
100
+ );
101
+ });