@vygruppen/spor-react 12.24.15 → 13.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 (88) hide show
  1. package/.turbo/turbo-build.log +10 -10
  2. package/.turbo/turbo-postinstall.log +4 -3
  3. package/CHANGELOG.md +25 -0
  4. package/dist/index.cjs +2888 -2534
  5. package/dist/index.cjs.map +1 -1
  6. package/dist/index.d.cts +921 -572
  7. package/dist/index.d.ts +921 -572
  8. package/dist/index.mjs +2860 -2517
  9. package/dist/index.mjs.map +1 -1
  10. package/package.json +8 -8
  11. package/src/accordion/Accordion.tsx +34 -29
  12. package/src/accordion/Expandable.tsx +20 -21
  13. package/src/alert/Alert.tsx +7 -5
  14. package/src/alert/AlertIcon.tsx +19 -20
  15. package/src/alert/ExpandableAlert.tsx +65 -64
  16. package/src/alert/ServiceAlert.tsx +78 -78
  17. package/src/breadcrumb/Breadcrumb.tsx +37 -34
  18. package/src/button/Button.tsx +64 -57
  19. package/src/button/ButtonGroup.tsx +12 -10
  20. package/src/button/Clipboard.tsx +21 -18
  21. package/src/button/CloseButton.tsx +19 -17
  22. package/src/button/FloatingActionButton.tsx +41 -47
  23. package/src/button/IconButton.tsx +20 -18
  24. package/src/calendar/CalendarContext.tsx +1 -1
  25. package/src/color-mode/color-mode.tsx +7 -5
  26. package/src/datepicker/CalendarTriggerButton.tsx +11 -7
  27. package/src/datepicker/DateField.tsx +53 -51
  28. package/src/datepicker/DatePicker.tsx +127 -134
  29. package/src/datepicker/DateTimeSegment.tsx +44 -40
  30. package/src/datepicker/StyledField.tsx +39 -36
  31. package/src/dialog/Dialog.tsx +14 -11
  32. package/src/dialog/Drawer.tsx +74 -67
  33. package/src/input/AttachedInputs.tsx +35 -41
  34. package/src/input/Autocomplete.tsx +118 -129
  35. package/src/input/CardSelect.tsx +67 -65
  36. package/src/input/Checkbox.tsx +19 -17
  37. package/src/input/CheckboxGroup.tsx +0 -2
  38. package/src/input/ChoiceChip.tsx +42 -38
  39. package/src/input/Combobox.tsx +4 -4
  40. package/src/input/CountryCodeSelect.tsx +8 -8
  41. package/src/input/Field.tsx +78 -75
  42. package/src/input/FloatingLabel.tsx +6 -8
  43. package/src/input/Input.tsx +87 -92
  44. package/src/input/ListBox.tsx +3 -4
  45. package/src/input/Menu.tsx +241 -0
  46. package/src/input/NativeSelect.tsx +7 -5
  47. package/src/input/NumericStepper.tsx +15 -12
  48. package/src/input/PasswordInput.tsx +65 -61
  49. package/src/input/PhoneNumberInput.tsx +7 -7
  50. package/src/input/Popover.tsx +52 -55
  51. package/src/input/Radio.tsx +16 -11
  52. package/src/input/SearchInput.tsx +32 -31
  53. package/src/input/Select.tsx +106 -96
  54. package/src/input/Switch.tsx +43 -41
  55. package/src/input/Textarea.tsx +68 -66
  56. package/src/input/index.ts +1 -0
  57. package/src/layout/PressableCard.tsx +11 -10
  58. package/src/layout/RadioCard.tsx +57 -53
  59. package/src/layout/Separator.tsx +8 -7
  60. package/src/layout/StaticCard.tsx +11 -10
  61. package/src/linjetag/LineIcon.tsx +48 -54
  62. package/src/linjetag/TravelTag.tsx +57 -59
  63. package/src/link/TextLink.tsx +50 -40
  64. package/src/loader/ProgressBar.tsx +41 -46
  65. package/src/loader/ProgressLoader.tsx +83 -86
  66. package/src/loader/Skeleton.tsx +56 -48
  67. package/src/logo/CargonetLogo.tsx +88 -87
  68. package/src/logo/VyLogo.tsx +80 -77
  69. package/src/logo/VyLogoPride.tsx +137 -135
  70. package/src/media-controller/JumpButton.tsx +30 -28
  71. package/src/media-controller/PlayPauseButton.tsx +8 -7
  72. package/src/media-controller/SkipButton.tsx +28 -26
  73. package/src/nudge/Nudge.tsx +66 -70
  74. package/src/pagination/Pagination.tsx +52 -46
  75. package/src/popover/index.tsx +46 -41
  76. package/src/progress-indicator/ProgressIndicator.tsx +10 -7
  77. package/src/stepper/Stepper.tsx +84 -81
  78. package/src/tab/Tabs.tsx +8 -4
  79. package/src/table/Table.tsx +89 -109
  80. package/src/theme/slot-recipes/anatomy.ts +14 -0
  81. package/src/theme/slot-recipes/index.ts +2 -0
  82. package/src/theme/slot-recipes/menu.ts +111 -0
  83. package/src/tooltip.tsx +26 -22
  84. package/src/typography/Badge.tsx +8 -5
  85. package/src/typography/Code.tsx +8 -5
  86. package/src/typography/Heading.tsx +22 -23
  87. package/src/typography/Text.tsx +11 -9
  88. package/tsconfig.json +1 -0
@@ -16,7 +16,6 @@ import {
16
16
  } from "@vygruppen/spor-icon-react";
17
17
  import {
18
18
  createContext,
19
- forwardRef,
20
19
  PropsWithChildren,
21
20
  useContext,
22
21
  useLayoutEffect,
@@ -52,75 +51,58 @@ export type TableProps = Exclude<ChakraTableProps, "variant" | "colorPalette"> &
52
51
  variant?: "ghost" | "core";
53
52
  colorPalette?: "grey" | "green" | "white";
54
53
  sortable?: boolean;
54
+ ref?: React.Ref<HTMLTableElement>;
55
55
  };
56
56
 
57
- /**
58
- * 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.
59
- *
60
- * You can also specify a `grey` or `green` `colorPalette` prop. Use `green` if you want to place the table on a light green background.
61
- *
62
- * Finally, there are three different `size` props you can specify - `sm`, `md` and `lg`.
63
- *
64
- * ```tsx
65
- * <Table variant="core" size="lg">
66
- * <Thead>
67
- * ...
68
- * </Thead>
69
- * ...
70
- * </Table>
71
- * ```
72
- */
73
- export const Table = forwardRef<HTMLTableElement, TableProps>(
74
- (
75
- {
76
- variant = "ghost",
77
- size,
78
- colorPalette = "green",
79
- children,
80
- sortable = false,
81
- ...rest
82
- },
83
- ref,
84
- ) => {
85
- const [sortState, setSortState] = useState<SortState>({
86
- direction: "asc",
87
- columnIndex: null,
88
- });
89
-
90
- const handleSort = (columnIndex: number) => {
91
- if (!sortable) return;
92
- setSortState(getNextSortState(sortState, columnIndex));
93
- };
94
-
95
- const recipe = useSlotRecipe({ key: "table" });
96
- const styles = recipe({ variant, size });
97
-
98
- return (
99
- <ChakraTable.Root
100
- variant={variant}
101
- size={size}
102
- colorPalette={colorPalette}
103
- css={styles}
104
- ref={ref}
105
- {...rest}
57
+ export const Table = ({
58
+ variant = "ghost",
59
+ size,
60
+ colorPalette = "green",
61
+ children,
62
+ sortable = false,
63
+ ref,
64
+ ...rest
65
+ }: TableProps) => {
66
+ const [sortState, setSortState] = useState<SortState>({
67
+ direction: "asc",
68
+ columnIndex: null,
69
+ });
70
+
71
+ const handleSort = (columnIndex: number) => {
72
+ if (!sortable) return;
73
+ setSortState(getNextSortState(sortState, columnIndex));
74
+ };
75
+
76
+ const recipe = useSlotRecipe({ key: "table" });
77
+ const styles = recipe({ variant, size });
78
+
79
+ return (
80
+ <ChakraTable.Root
81
+ variant={variant}
82
+ size={size}
83
+ colorPalette={colorPalette}
84
+ css={styles}
85
+ ref={ref}
86
+ {...rest}
87
+ >
88
+ <SortContext.Provider
89
+ value={{ enabled: sortable, sortState, onSort: handleSort }}
106
90
  >
107
- <SortContext.Provider
108
- value={{ enabled: sortable, sortState, onSort: handleSort }}
109
- >
110
- {children}
111
- </SortContext.Provider>
112
- </ChakraTable.Root>
113
- );
114
- },
115
- );
116
- Table.displayName = "Table";
117
-
118
- export type TableColumnHeaderProps = ChakraTableColumnHeaderProps;
119
-
120
- export const TableColumnHeader = forwardRef<
121
- HTMLTableCellElement,
122
- TableColumnHeaderProps
123
- >(({ children, ...rest }, ref) => {
91
+ {children}
92
+ </SortContext.Provider>
93
+ </ChakraTable.Root>
94
+ );
95
+ };
96
+
97
+ export type TableColumnHeaderProps = ChakraTableColumnHeaderProps & {
98
+ ref?: React.Ref<HTMLTableCellElement>;
99
+ };
100
+
101
+ export const TableColumnHeader = ({
102
+ children,
103
+ ref,
104
+ ...rest
105
+ }: TableColumnHeaderProps) => {
124
106
  const { enabled, sortState, onSort } = useTableSort();
125
107
  const [columnIndex, setColumnIndex] = useState<number | null>(null);
126
108
  const props = rest as Record<string, unknown>;
@@ -165,45 +147,43 @@ export const TableColumnHeader = forwardRef<
165
147
  </HStack>
166
148
  </ChakraTable.ColumnHeader>
167
149
  );
168
- });
169
- TableColumnHeader.displayName = "ColumnHeader";
170
-
171
- export type TableBodyProps = ChakraTableBodyProps;
172
-
173
- export const TableBody = forwardRef<HTMLTableSectionElement, TableBodyProps>(
174
- ({ children, ...rest }, ref) => {
175
- const { sortState } = useTableSort();
176
- const tbodyRef = useRef<HTMLTableSectionElement | null>(null);
177
- const originalOrder = useRef<HTMLTableRowElement[]>([]);
178
- const previousChildren = useRef(children);
179
-
180
- useLayoutEffect(() => {
181
- const tbody = tbodyRef.current;
182
- if (!tbody) return;
183
-
184
- if (
185
- previousChildren.current !== children ||
186
- originalOrder.current.length === 0
187
- ) {
188
- originalOrder.current = captureRowOrder(tbody);
189
- previousChildren.current = children;
190
- }
191
-
192
- applyDomSort(tbody, sortState, originalOrder.current);
193
- }, [sortState, children]);
194
-
195
- return (
196
- <ChakraTable.Body
197
- ref={(element: HTMLTableSectionElement) => {
198
- tbodyRef.current = element;
199
- if (typeof ref === "function") ref(element);
200
- else if (ref) ref.current = element;
201
- }}
202
- {...rest}
203
- >
204
- {children}
205
- </ChakraTable.Body>
206
- );
207
- },
208
- );
209
- TableBody.displayName = "TableBody";
150
+ };
151
+
152
+ export type TableBodyProps = ChakraTableBodyProps & {
153
+ ref?: React.Ref<HTMLTableSectionElement>;
154
+ };
155
+
156
+ export const TableBody = ({ children, ref, ...rest }: TableBodyProps) => {
157
+ const { sortState } = useTableSort();
158
+ const tbodyRef = useRef<HTMLTableSectionElement | null>(null);
159
+ const originalOrder = useRef<HTMLTableRowElement[]>([]);
160
+ const previousChildren = useRef(children);
161
+
162
+ useLayoutEffect(() => {
163
+ const tbody = tbodyRef.current;
164
+ if (!tbody) return;
165
+
166
+ if (
167
+ previousChildren.current !== children ||
168
+ originalOrder.current.length === 0
169
+ ) {
170
+ originalOrder.current = captureRowOrder(tbody);
171
+ previousChildren.current = children;
172
+ }
173
+
174
+ applyDomSort(tbody, sortState, originalOrder.current);
175
+ }, [sortState, children]);
176
+
177
+ return (
178
+ <ChakraTable.Body
179
+ ref={(element: HTMLTableSectionElement) => {
180
+ tbodyRef.current = element;
181
+ if (typeof ref === "function") ref(element);
182
+ else if (ref) ref.current = element;
183
+ }}
184
+ {...rest}
185
+ >
186
+ {children}
187
+ </ChakraTable.Body>
188
+ );
189
+ };
@@ -285,3 +285,17 @@ export const comboboxAnatomy = arkComboboxAnatomy.extendWith(
285
285
  "indicatorGroup",
286
286
  "empty",
287
287
  );
288
+
289
+ export const menuAnatomy = createAnatomy("menu").parts(
290
+ "trigger",
291
+ "content",
292
+ "item",
293
+ "itemGroup",
294
+ "triggerItem",
295
+ "itemCommand",
296
+ "itemGroupLabel",
297
+ "separator",
298
+ "radioItem",
299
+ "triggerItem",
300
+ "checkboxItem",
301
+ );
@@ -17,6 +17,7 @@ import { lineIconSlotRecipe } from "./line-icon";
17
17
  import { listSlotRecipe } from "./list";
18
18
  import { listBoxSlotRecipe } from "./listbox";
19
19
  import { mediaControllerSlotRecipe } from "./media-controller-button";
20
+ import { menuSlotRecipe } from "./menu";
20
21
  import { nativeSelectSlotRecipe } from "./native-select";
21
22
  import { numericStepperRecipe } from "./numeric-stepper";
22
23
  import { paginationSlotRecipe } from "./pagination";
@@ -69,4 +70,5 @@ export const slotRecipes = {
69
70
  checkboxCard: choiceChipSlotRecipe,
70
71
  collapsible: collapsibleSlotRecipe,
71
72
  tooltip: popoverSlotRecipe,
73
+ menu: menuSlotRecipe,
72
74
  };
@@ -0,0 +1,111 @@
1
+ import { defineSlotRecipe } from "@chakra-ui/react";
2
+
3
+ import { menuAnatomy } from "./anatomy";
4
+
5
+ export const menuSlotRecipe = defineSlotRecipe({
6
+ className: "menu",
7
+ slots: menuAnatomy.keys(),
8
+ base: {
9
+ content: {
10
+ bg: "bg",
11
+ borderRadius: "sm",
12
+ boxShadow: "sm",
13
+ width: "fit-content",
14
+ padding: "1",
15
+
16
+ display: "flex",
17
+ flexDirection: "column",
18
+ gap: "0.5",
19
+ zIndex: "dropdown",
20
+
21
+ _open: {
22
+ animationStyle: "slide-fade-in",
23
+ animationDuration: "fast",
24
+ zIndex: "popover",
25
+ outline: "none",
26
+ },
27
+ },
28
+ itemGroup: {
29
+ display: "flex",
30
+ flexDirection: "column",
31
+ gap: "0.5",
32
+ },
33
+ item: {
34
+ borderRadius: "9px",
35
+ padding: "2",
36
+ display: "flex",
37
+ justifyContent: "space-between",
38
+ gap: 1.5,
39
+
40
+ _hover: {
41
+ backgroundColor: "accent.surface.hover",
42
+ },
43
+
44
+ "&:active": {
45
+ backgroundColor: "accent.surface.active",
46
+ },
47
+
48
+ _checked: {
49
+ backgroundColor: "accent.surface",
50
+ },
51
+
52
+ _highlighted: {
53
+ backgroundColor: "ghost.surface.hover",
54
+ },
55
+ },
56
+ itemGroupLabel: {
57
+ paddingY: "1",
58
+ fontWeight: "bold",
59
+ fontSize: "xs",
60
+ },
61
+ itemCommand: {
62
+ fontSize: "2xs",
63
+ },
64
+ separator: {
65
+ color: "outline",
66
+ },
67
+ radioItem: {
68
+ display: "flex",
69
+ justifyContent: "space-between",
70
+ gap: 2,
71
+ },
72
+ triggerItem: {
73
+ display: "flex",
74
+ justifyContent: "space-between",
75
+ gap: 1.5,
76
+ alignItems: "center",
77
+ },
78
+ checkboxItem: {
79
+ display: "flex",
80
+ gap: 2,
81
+ alignItems: "center",
82
+ width: "full",
83
+ },
84
+ },
85
+ variants: {
86
+ variant: {
87
+ core: {
88
+ content: {
89
+ border: "1px solid",
90
+ borderColor: "core.outline",
91
+ },
92
+ },
93
+ accent: {
94
+ content: {
95
+ border: "1px solid",
96
+ borderColor: "core.outline",
97
+ },
98
+ },
99
+ floating: {
100
+ content: {
101
+ border: "sm",
102
+ borderColor: "floating.outline",
103
+ boxShadow: "lg",
104
+ },
105
+ },
106
+ },
107
+ },
108
+ defaultVariants: {
109
+ variant: "core",
110
+ },
111
+ });
package/src/tooltip.tsx CHANGED
@@ -1,14 +1,16 @@
1
1
  "use client";
2
2
 
3
3
  import { Portal, Tooltip as ChakraTooltip } from "@chakra-ui/react";
4
- import { forwardRef } from "react";
5
4
 
6
5
  export const Tooltip = ChakraTooltip.Root;
7
6
 
8
- export const TooltipTrigger = forwardRef<
9
- HTMLButtonElement,
10
- ChakraTooltip.TriggerProps
11
- >(({ children, ...props }, ref) => {
7
+ export const TooltipTrigger = ({
8
+ ref,
9
+ children,
10
+ ...props
11
+ }: ChakraTooltip.TriggerProps & {
12
+ ref?: React.RefObject<HTMLButtonElement>;
13
+ }) => {
12
14
  const isStringChild = typeof children === "string";
13
15
 
14
16
  return (
@@ -16,23 +18,25 @@ export const TooltipTrigger = forwardRef<
16
18
  {children}
17
19
  </ChakraTooltip.Trigger>
18
20
  );
19
- });
20
- TooltipTrigger.displayName = "TooltipTrigger";
21
+ };
21
22
 
22
23
  export type TooltipProps = ChakraTooltip.ContentProps;
23
24
 
24
- export const TooltipContent = forwardRef<HTMLDivElement, TooltipProps>(
25
- ({ children, ...props }, ref) => {
26
- return (
27
- <Portal>
28
- <ChakraTooltip.Positioner>
29
- <ChakraTooltip.Content ref={ref} {...props}>
30
- <ChakraTooltip.Arrow />
31
- <ChakraTooltip.Content {...props}>{children}</ChakraTooltip.Content>
32
- </ChakraTooltip.Content>
33
- </ChakraTooltip.Positioner>
34
- </Portal>
35
- );
36
- },
37
- );
38
- TooltipContent.displayName = "TooltipContent";
25
+ export const TooltipContent = ({
26
+ ref,
27
+ children,
28
+ ...props
29
+ }: TooltipProps & {
30
+ ref?: React.RefObject<HTMLDivElement>;
31
+ }) => {
32
+ return (
33
+ <Portal>
34
+ <ChakraTooltip.Positioner>
35
+ <ChakraTooltip.Content ref={ref} {...props}>
36
+ <ChakraTooltip.Arrow />
37
+ <ChakraTooltip.Content {...props}>{children}</ChakraTooltip.Content>
38
+ </ChakraTooltip.Content>
39
+ </ChakraTooltip.Positioner>
40
+ </Portal>
41
+ );
42
+ };
@@ -5,20 +5,23 @@ import {
5
5
  Box,
6
6
  } from "@chakra-ui/react";
7
7
  import { IconComponent } from "@vygruppen/spor-icon-react";
8
- import { forwardRef } from "react";
9
8
 
10
9
  export type BadgeProps = ChakraBadgeProps & {
11
10
  icon?: IconComponent;
12
11
  };
13
12
 
14
- export const Badge = forwardRef<HTMLSpanElement, BadgeProps>(function Badge(
15
- { icon, children, ...props },
13
+ export const Badge = function Badge({
16
14
  ref,
17
- ) {
15
+ icon,
16
+ children,
17
+ ...props
18
+ }: BadgeProps & {
19
+ ref?: React.RefObject<HTMLSpanElement>;
20
+ }) {
18
21
  return (
19
22
  <ChakraBadge ref={ref} {...props}>
20
23
  {children}
21
24
  {icon && <Box as={icon} />}
22
25
  </ChakraBadge>
23
26
  );
24
- });
27
+ };
@@ -14,8 +14,11 @@ type CodeVariantProps = RecipeVariantProps<typeof codeRecipie> & CodeProps;
14
14
 
15
15
  const StyledCode = chakra(ChakraCode, codeRecipie);
16
16
 
17
- export const Code = React.forwardRef<HTMLElement, CodeVariantProps>(
18
- function Code(props, ref) {
19
- return <StyledCode {...props} ref={ref} />;
20
- },
21
- );
17
+ export const Code = function Code({
18
+ ref,
19
+ ...props
20
+ }: CodeVariantProps & {
21
+ ref?: React.RefObject<HTMLElement>;
22
+ }) {
23
+ return <StyledCode {...props} ref={ref} />;
24
+ };
@@ -4,7 +4,7 @@ import {
4
4
  HeadingProps as ChakraHeadingProps,
5
5
  Text,
6
6
  } from "@chakra-ui/react";
7
- import { forwardRef, useId } from "react";
7
+ import { useId } from "react";
8
8
 
9
9
  import { slugify } from "..";
10
10
 
@@ -42,28 +42,27 @@ export type HeadingProps = Omit<ChakraHeadingProps, "textStyle" | "as"> & {
42
42
  * ```
43
43
  */
44
44
 
45
- export const Heading = forwardRef<HTMLHeadingElement, HeadingProps>(
46
- function Heading(props, ref) {
47
- const {
48
- as,
49
- variant = "xl-display",
50
- autoId = false,
51
- id: externalId,
52
- ...rest
53
- } = props;
45
+ export const Heading = function Heading({
46
+ ref,
47
+ ...props
48
+ }: HeadingProps & {
49
+ ref?: React.RefObject<HTMLHeadingElement>;
50
+ }) {
51
+ const {
52
+ as,
53
+ variant = "xl-display",
54
+ autoId = false,
55
+ id: externalId,
56
+ ...rest
57
+ } = props;
54
58
 
55
- const reactId = useId();
59
+ const reactId = useId();
56
60
 
57
- function getId() {
58
- if (externalId !== undefined) return externalId;
59
- if (!autoId) return;
60
- return typeof rest.children === "string"
61
- ? slugify(rest.children)
62
- : reactId;
63
- }
61
+ function getId() {
62
+ if (externalId !== undefined) return externalId;
63
+ if (!autoId) return;
64
+ return typeof rest.children === "string" ? slugify(rest.children) : reactId;
65
+ }
64
66
 
65
- return (
66
- <Text as={as} textStyle={variant} id={getId()} ref={ref} {...rest} />
67
- );
68
- },
69
- );
67
+ return <Text as={as} textStyle={variant} id={getId()} ref={ref} {...rest} />;
68
+ };
@@ -3,7 +3,6 @@ import {
3
3
  Text as ChakraText,
4
4
  TextProps as ChakraTextProps,
5
5
  } from "@chakra-ui/react";
6
- import { forwardRef } from "react";
7
6
 
8
7
  export type TextProps = Omit<ChakraTextProps, "textStyle"> & {
9
8
  /** The size and style of the text.
@@ -45,11 +44,14 @@ function resolveTextProps({
45
44
  * <Text>Welcome to this paragraph of text.</Text>
46
45
  * ```
47
46
  */
48
- export const Text = forwardRef<HTMLParagraphElement, TextProps>(
49
- function Text(props, ref) {
50
- const { variant, lineHeight, fontSize, ...rest } = props;
51
- const resolvedProps = resolveTextProps({ variant, fontSize, lineHeight });
52
-
53
- return <ChakraText {...resolvedProps} {...rest} ref={ref} />;
54
- },
55
- );
47
+ export const Text = function Text({
48
+ ref,
49
+ ...props
50
+ }: TextProps & {
51
+ ref?: React.RefObject<HTMLParagraphElement>;
52
+ }) {
53
+ const { variant, lineHeight, fontSize, ...rest } = props;
54
+ const resolvedProps = resolveTextProps({ variant, fontSize, lineHeight });
55
+
56
+ return <ChakraText {...resolvedProps} {...rest} ref={ref} />;
57
+ };
package/tsconfig.json CHANGED
@@ -5,6 +5,7 @@
5
5
  "compilerOptions": {
6
6
  "lib": ["dom", "es2023"],
7
7
  "rootDir": ".",
8
+
8
9
  "paths": {
9
10
  "@/*": ["./src/*"]
10
11
  },