@scottish-government/designsystem-react 0.7.1 → 0.8.0-beta.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 (147) hide show
  1. package/@types/common/AbstractNotificationBanner.d.ts +2 -2
  2. package/@types/common/ActionLink.d.ts +8 -0
  3. package/@types/common/FileIcon.d.ts +1 -1
  4. package/@types/common/Icon.d.ts +1 -1
  5. package/@types/components/Accordion.d.ts +0 -1
  6. package/@types/components/Breadcrumbs.d.ts +2 -5
  7. package/@types/components/Checkbox.d.ts +0 -2
  8. package/@types/components/ConfirmationMessage.d.ts +1 -1
  9. package/@types/components/ContentsNav.d.ts +4 -6
  10. package/@types/components/DatePicker.d.ts +1 -1
  11. package/@types/components/ErrorSummary.d.ts +3 -4
  12. package/@types/components/NotificationPanel.d.ts +1 -1
  13. package/@types/components/Pagination.d.ts +5 -4
  14. package/@types/components/PhaseBanner.d.ts +0 -1
  15. package/@types/components/Question.d.ts +1 -1
  16. package/@types/components/RadioButton.d.ts +0 -1
  17. package/@types/components/Select.d.ts +0 -7
  18. package/@types/components/SequentialNavigation.d.ts +4 -4
  19. package/@types/components/SideNavigation.d.ts +4 -5
  20. package/@types/components/SiteFooter.d.ts +25 -0
  21. package/@types/components/SiteHeader.d.ts +10 -3
  22. package/@types/components/SiteNavigation.d.ts +2 -3
  23. package/@types/components/SkipLinks.d.ts +3 -4
  24. package/@types/components/SummaryCard.d.ts +0 -2
  25. package/@types/components/SummaryList.d.ts +0 -13
  26. package/@types/components/Tabs.d.ts +0 -1
  27. package/@types/components/Tag.d.ts +1 -3
  28. package/@types/components/TaskList.d.ts +1 -0
  29. package/@types/sgds.d.ts +13 -2
  30. package/CHANGELOG.md +63 -1
  31. package/dist/common/AbstractNotificationBanner.jsx +8 -6
  32. package/dist/common/ActionLink.jsx +19 -0
  33. package/dist/common/FileIcon.jsx +2 -7
  34. package/dist/common/Icon.jsx +3 -9
  35. package/dist/components/Accordion/Accordion.jsx +12 -7
  36. package/dist/components/Breadcrumbs/Breadcrumbs.jsx +20 -15
  37. package/dist/components/Checkbox/Checkbox.jsx +4 -29
  38. package/dist/components/Checkbox/CheckboxGroup.jsx +63 -0
  39. package/dist/components/ContentsNav/ContentsNav.jsx +27 -16
  40. package/dist/components/CookieBanner/CookieBanner.jsx +1 -0
  41. package/dist/components/DatePicker/DatePicker.jsx +5 -5
  42. package/dist/components/ErrorSummary/ErrorSummary.jsx +28 -18
  43. package/dist/components/NotificationBanner/NotificationBanner.jsx +2 -2
  44. package/dist/components/Pagination/Pagination.jsx +42 -22
  45. package/dist/components/PhaseBanner/PhaseBanner.jsx +3 -3
  46. package/dist/components/Question/Question.jsx +3 -3
  47. package/dist/components/RadioButton/RadioButton.jsx +7 -17
  48. package/dist/components/RadioButton/RadioGroup.jsx +21 -0
  49. package/dist/components/Select/Select.jsx +4 -7
  50. package/dist/components/SequentialNavigation/SequentialNavigation.jsx +31 -18
  51. package/dist/components/SideNavigation/SideNavigation.jsx +17 -16
  52. package/dist/components/SiteFooter/SiteFooter.jsx +104 -0
  53. package/dist/components/SiteHeader/SiteHeader.jsx +113 -32
  54. package/dist/components/SiteNavigation/SiteNavigation.jsx +20 -7
  55. package/dist/components/SkipLinks/SkipLinks.jsx +10 -10
  56. package/dist/components/SummaryCard/SummaryCard.jsx +25 -14
  57. package/dist/components/SummaryList/SummaryList.jsx +65 -47
  58. package/dist/components/Tabs/Tabs.jsx +6 -6
  59. package/dist/components/Tag/Tag.jsx +2 -2
  60. package/dist/components/TaskList/TaskList.jsx +14 -3
  61. package/dist/components/TextInput/TextInput.jsx +3 -3
  62. package/dist/components/Textarea/Textarea.jsx +3 -3
  63. package/dist/hooks/useTracking.js +21 -0
  64. package/dist/tsconfig.tsbuildinfo +1 -1
  65. package/dist/utils/context.js +5 -0
  66. package/package.json +2 -2
  67. package/src/common/AbstractNotificationBanner.test.tsx +1 -1
  68. package/src/common/AbstractNotificationBanner.tsx +14 -13
  69. package/src/common/ActionLink.test.tsx +80 -0
  70. package/src/common/ActionLink.tsx +27 -0
  71. package/src/common/ConditionalWrapper.tsx +1 -1
  72. package/src/common/FileIcon.tsx +7 -11
  73. package/src/common/HintText.tsx +2 -2
  74. package/src/common/Icon.tsx +13 -17
  75. package/src/common/ScreenReaderText.tsx +2 -2
  76. package/src/common/WrapperTag.tsx +2 -2
  77. package/src/components/Accordion/Accordion.test.tsx +17 -4
  78. package/src/components/Accordion/Accordion.tsx +19 -14
  79. package/src/components/AspectBox/AspectBox.tsx +2 -2
  80. package/src/components/BackToTop/BackToTop.tsx +2 -2
  81. package/src/components/Breadcrumbs/Breadcrumbs.test.tsx +79 -48
  82. package/src/components/Breadcrumbs/Breadcrumbs.tsx +31 -31
  83. package/src/components/Button/Button.tsx +2 -2
  84. package/src/components/Checkbox/Checkbox.test.tsx +1 -96
  85. package/src/components/Checkbox/Checkbox.tsx +8 -55
  86. package/src/components/Checkbox/CheckboxGroup.test.tsx +37 -0
  87. package/src/components/Checkbox/CheckboxGroup.tsx +41 -0
  88. package/src/components/ConfirmationMessage/ConfirmationMessage.tsx +2 -2
  89. package/src/components/ContentsNav/ContentsNav.test.tsx +40 -51
  90. package/src/components/ContentsNav/ContentsNav.tsx +32 -25
  91. package/src/components/CookieBanner/CookieBanner.tsx +3 -3
  92. package/src/components/DatePicker/DatePicker.test.tsx +1 -1
  93. package/src/components/DatePicker/DatePicker.tsx +7 -7
  94. package/src/components/Details/Details.tsx +2 -2
  95. package/src/components/ErrorMessage/ErrorMessage.tsx +2 -2
  96. package/src/components/ErrorSummary/ErrorSummary.test.tsx +40 -34
  97. package/src/components/ErrorSummary/ErrorSummary.tsx +40 -32
  98. package/src/components/FileDownload/FileDownload.tsx +2 -2
  99. package/src/components/HideThisPage/HideThisPage.tsx +2 -2
  100. package/src/components/InsetText/InsetText.tsx +2 -2
  101. package/src/components/NotificationBanner/NotificationBanner.tsx +6 -7
  102. package/src/components/NotificationPanel/NotificationPanel.tsx +2 -2
  103. package/src/components/PageHeader/PageHeader.tsx +2 -2
  104. package/src/components/PageMetadata/PageMetadata.tsx +4 -5
  105. package/src/components/Pagination/Pagination.test.tsx +26 -7
  106. package/src/components/Pagination/Pagination.tsx +70 -36
  107. package/src/components/PhaseBanner/PhaseBanner.tsx +4 -5
  108. package/src/components/Question/Question.test.tsx +1 -1
  109. package/src/components/Question/Question.tsx +5 -5
  110. package/src/components/RadioButton/RadioButton.test.tsx +7 -126
  111. package/src/components/RadioButton/RadioButton.tsx +10 -41
  112. package/src/components/RadioButton/RadioGroup.test.tsx +65 -0
  113. package/src/components/RadioButton/RadioGroup.tsx +31 -0
  114. package/src/components/Select/Select.test.tsx +39 -37
  115. package/src/components/Select/Select.tsx +7 -22
  116. package/src/components/SequentialNavigation/SequentialNavigation.test.tsx +32 -21
  117. package/src/components/SequentialNavigation/SequentialNavigation.tsx +52 -30
  118. package/src/components/SideNavigation/SideNavigation.test.tsx +39 -85
  119. package/src/components/SideNavigation/SideNavigation.tsx +27 -29
  120. package/src/components/SiteFooter/SiteFooter.test.tsx +153 -0
  121. package/src/components/SiteFooter/SiteFooter.tsx +107 -0
  122. package/src/components/SiteHeader/SiteHeader.test.tsx +87 -79
  123. package/src/components/SiteHeader/SiteHeader.tsx +103 -40
  124. package/src/components/SiteNavigation/SiteNavigation.test.tsx +42 -23
  125. package/src/components/SiteNavigation/SiteNavigation.tsx +28 -16
  126. package/src/components/SiteSearch/SiteSearch.tsx +2 -2
  127. package/src/components/SkipLinks/SkipLinks.test.tsx +22 -10
  128. package/src/components/SkipLinks/SkipLinks.tsx +16 -15
  129. package/src/components/SummaryCard/SummaryCard.test.tsx +31 -35
  130. package/src/components/SummaryCard/SummaryCard.tsx +39 -28
  131. package/src/components/SummaryList/SummaryList.test.tsx +49 -148
  132. package/src/components/SummaryList/SummaryList.tsx +54 -92
  133. package/src/components/Table/Table.tsx +2 -2
  134. package/src/components/Tabs/Tabs.tsx +14 -15
  135. package/src/components/Tag/Tag.test.tsx +4 -4
  136. package/src/components/Tag/Tag.tsx +4 -4
  137. package/src/components/TaskList/TaskList.test.tsx +26 -0
  138. package/src/components/TaskList/TaskList.tsx +21 -11
  139. package/src/components/TextInput/TextInput.test.tsx +1 -1
  140. package/src/components/TextInput/TextInput.tsx +5 -5
  141. package/src/components/Textarea/Textarea.test.tsx +1 -1
  142. package/src/components/Textarea/Textarea.tsx +5 -5
  143. package/src/components/WarningText/WarningText.tsx +2 -2
  144. package/src/hooks/useTracking.test.tsx +64 -0
  145. package/src/hooks/useTracking.ts +19 -0
  146. package/src/utils/context.ts +3 -0
  147. package/tsconfig.json +1 -1
@@ -6,7 +6,7 @@ const TAG_TEXT = 'Beta';
6
6
 
7
7
  test('tag renders correctly', () => {
8
8
  render(
9
- <Tag title={TAG_TEXT}/>
9
+ <Tag>{TAG_TEXT}</Tag>
10
10
  );
11
11
 
12
12
  const tag = screen.getByText(TAG_TEXT);
@@ -17,7 +17,7 @@ test('tag renders correctly', () => {
17
17
 
18
18
  test('tag with custom colour', () => {
19
19
  render(
20
- <Tag colour="red" title={TAG_TEXT}/>
20
+ <Tag colour="red">{TAG_TEXT}</Tag>
21
21
  );
22
22
 
23
23
  const tag = screen.getByText(TAG_TEXT);
@@ -27,7 +27,7 @@ test('tag with custom colour', () => {
27
27
 
28
28
  test('passing additional props', () => {
29
29
  render(
30
- <Tag data-test="foo" title={TAG_TEXT}/>
30
+ <Tag data-test="foo">{TAG_TEXT}</Tag>
31
31
  );
32
32
 
33
33
  const tag = screen.getByText(TAG_TEXT);
@@ -36,7 +36,7 @@ test('passing additional props', () => {
36
36
 
37
37
  test('tag with additional CSS class', () => {
38
38
  render(
39
- <Tag className="foo" title={TAG_TEXT}/>
39
+ <Tag className="foo">{TAG_TEXT}</Tag>
40
40
  );
41
41
 
42
42
  const tag = screen.getByText(TAG_TEXT);
@@ -1,9 +1,9 @@
1
- const Tag: React.FC<SGDS.Component.Tag> = ({
1
+ const Tag = ({
2
+ children,
2
3
  className,
3
4
  colour,
4
- title,
5
5
  ...props
6
- }) => {
6
+ }: SGDS.Component.Tag) => {
7
7
  return (
8
8
  <span
9
9
  className={[
@@ -13,7 +13,7 @@ const Tag: React.FC<SGDS.Component.Tag> = ({
13
13
  ].join(' ')}
14
14
  {...props}
15
15
  >
16
- {title}
16
+ {children}
17
17
  </span>
18
18
  );
19
19
  };
@@ -192,6 +192,32 @@ test('task with link', () => {
192
192
  expect(link.textContent).toEqual(taskHeading.textContent);
193
193
  });
194
194
 
195
+ test('task with custom link element', () => {
196
+ const TASK_HREF = '#foo';
197
+
198
+ render(
199
+ <TaskList.Item
200
+ id={TASK_ITEM.id}
201
+ statusText={TASK_ITEM.statusText}
202
+ title={TASK_ITEM.title}
203
+ href={TASK_HREF}
204
+ linkComponent={
205
+ ({ className, ...props }) => (
206
+ <strong role="link" className={className} {...props}/>
207
+ )}
208
+ >
209
+ {TASK_SUMMARY_CONTENT}
210
+ </TaskList.Item>
211
+ );
212
+
213
+ const task = screen.getByRole('listitem');
214
+ const taskHeading = within(task).getByRole('heading');
215
+ const link = within(task).getByRole('link');
216
+
217
+ expect(link?.tagName).toEqual('STRONG');
218
+ expect(link?.textContent).toEqual(taskHeading.textContent);
219
+ });
220
+
195
221
  test('completed task has green tag', () => {
196
222
  render(
197
223
  <TaskList.Item
@@ -4,21 +4,32 @@ import HintText from '../../common/HintText';
4
4
  import ScreenReaderText from '../../common/ScreenReaderText';
5
5
  import Tag from '../Tag/Tag';
6
6
 
7
- const TaskItem: React.FC<SGDS.Component.TaskList.Item> = ({
7
+ const TaskItem = ({
8
8
  children,
9
9
  className,
10
10
  href,
11
11
  id,
12
12
  isComplete = false,
13
+ linkComponent,
13
14
  statusText,
14
15
  tagColour = 'grey',
15
16
  title,
16
17
  ...props
17
- }) => {
18
+ }: SGDS.Component.TaskList.Item) => {
18
19
  if (isComplete) {
19
20
  tagColour = 'green';
20
21
  }
21
22
 
23
+ const LINK_CLASS = 'ds_task-list__task-link';
24
+
25
+ function getLinkElement(children: React.ReactNode) {
26
+ if (linkComponent) {
27
+ return linkComponent({ className: LINK_CLASS, href, children });
28
+ } else if (href) {
29
+ return <a href={href} className={LINK_CLASS}>{children}</a>;
30
+ }
31
+ }
32
+
22
33
  return (
23
34
  <li
24
35
  className={[
@@ -32,7 +43,7 @@ const TaskItem: React.FC<SGDS.Component.TaskList.Item> = ({
32
43
  <h3 className="ds_task-list__task-heading">
33
44
  <ConditionalWrapper
34
45
  condition={typeof href !== 'undefined'}
35
- wrapper={(children: React.JSX.Element) => <a className="ds_task-list__task-link" href={href}>{children}</a>}
46
+ wrapper={(children: React.JSX.Element) => getLinkElement(children)}
36
47
  >
37
48
  {title}
38
49
  {statusText && <ScreenReaderText>({statusText})</ScreenReaderText>}
@@ -45,8 +56,9 @@ const TaskItem: React.FC<SGDS.Component.TaskList.Item> = ({
45
56
  <Tag
46
57
  aria-hidden="true"
47
58
  colour={tagColour}
48
- title={statusText}
49
- />
59
+ >
60
+ {statusText}
61
+ </Tag>
50
62
  }
51
63
  </li>
52
64
  );
@@ -58,13 +70,13 @@ const TaskItem: React.FC<SGDS.Component.TaskList.Item> = ({
58
70
  * @param {string} props.title - The title of the task group
59
71
  * @returns {JSX.Element} - The element
60
72
  */
61
- const TaskGroup: React.FC<SGDS.Component.TaskList.Group> = ({
73
+ const TaskGroup = ({
62
74
  children,
63
75
  className,
64
76
  intro,
65
77
  title,
66
78
  ...props
67
- }) => {
79
+ }: SGDS.Component.TaskList.Group) => {
68
80
  return (
69
81
  <li
70
82
  className={[
@@ -82,15 +94,13 @@ const TaskGroup: React.FC<SGDS.Component.TaskList.Group> = ({
82
94
  );
83
95
  };
84
96
 
85
- const TaskList: React.FC<SGDS.Component.TaskList>
86
- & { Group: React.FC<SGDS.Component.TaskList.Group> }
87
- & { Item: React.FC<SGDS.Component.TaskList.Item> } = ({
97
+ const TaskList = ({
88
98
  children,
89
99
  className,
90
100
  headingId = 'task-list',
91
101
  title,
92
102
  ...props
93
- }) => {
103
+ }: SGDS.Component.TaskList) => {
94
104
  let taskCount = 0;
95
105
  let incompleteTaskIds: string[] = [];
96
106
  let completedTasksCount = 0;
@@ -284,8 +284,8 @@ test('text input with error message', () => {
284
284
  <TextInput
285
285
  id={INPUT_ID}
286
286
  label={LABEL_TEXT}
287
- error
288
287
  errorMessage={ERROR_MESSAGE_TEXT}
288
+ hasError
289
289
  />
290
290
  );
291
291
 
@@ -6,7 +6,7 @@ import ConditionalWrapper from '../../common/ConditionalWrapper';
6
6
  import ErrorMessage from '../ErrorMessage/ErrorMessage';
7
7
  import HintText from '../../common/HintText';
8
8
 
9
- const TextInput: React.FC<SGDS.Component.TextInput> = ({
9
+ const TextInput = ({
10
10
  buttonIcon,
11
11
  buttonText,
12
12
  children,
@@ -15,9 +15,9 @@ const TextInput: React.FC<SGDS.Component.TextInput> = ({
15
15
  width,
16
16
  currency,
17
17
  currencySymbol,
18
- error,
19
18
  errorMessage,
20
19
  hasButton = false,
20
+ hasError,
21
21
  hintText,
22
22
  id,
23
23
  label,
@@ -29,7 +29,7 @@ const TextInput: React.FC<SGDS.Component.TextInput> = ({
29
29
  type = 'text',
30
30
  value,
31
31
  ...props
32
- }) => {
32
+ }: SGDS.Component.TextInput) => {
33
33
  const errorMessageId = `error-message-${id}`;
34
34
  const hintTextId = `hint-text-${id}`;
35
35
  const ref = useRef(null);
@@ -71,11 +71,11 @@ const TextInput: React.FC<SGDS.Component.TextInput> = ({
71
71
  >
72
72
  <input
73
73
  aria-describedby={describedbys.join(' ')}
74
- aria-invalid={error}
74
+ aria-invalid={hasError}
75
75
  className={[
76
76
  'ds_input',
77
77
  className,
78
- error ? 'ds_input--error' : '',
78
+ hasError ? 'ds_input--error' : '',
79
79
  width ? `ds_input--${width}` : '',
80
80
  ].join(' ')}
81
81
  defaultValue={value}
@@ -188,8 +188,8 @@ test('textarea with error message', () => {
188
188
  <Textarea
189
189
  id={TEXTAREA_ID}
190
190
  label={LABEL_TEXT}
191
- error
192
191
  errorMessage={ERROR_MESSAGE_TEXT}
192
+ hasError
193
193
  />
194
194
  );
195
195
 
@@ -5,11 +5,11 @@ import ConditionalWrapper from '../../common/ConditionalWrapper';
5
5
  import ErrorMessage from '../ErrorMessage/ErrorMessage';
6
6
  import HintText from '../../common/HintText';
7
7
 
8
- const Textarea: React.FC<SGDS.Component.Textarea> = ({
8
+ const Textarea = ({
9
9
  className,
10
10
  countThreshold,
11
- error,
12
11
  errorMessage,
12
+ hasError,
13
13
  hintText,
14
14
  id,
15
15
  label,
@@ -21,7 +21,7 @@ const Textarea: React.FC<SGDS.Component.Textarea> = ({
21
21
  rows = 4,
22
22
  value,
23
23
  ...props
24
- }) => {
24
+ }: SGDS.Component.Textarea) => {
25
25
  const errorMessageId = `error-message-${id}`;
26
26
  const hintTextId = `hint-text-${id}`;
27
27
  const ref = useRef(null);
@@ -59,10 +59,10 @@ const Textarea: React.FC<SGDS.Component.Textarea> = ({
59
59
 
60
60
  <textarea
61
61
  aria-describedby={describedbys.join(' ')}
62
- aria-invalid={error}
62
+ aria-invalid={hasError}
63
63
  className={[
64
64
  'ds_input',
65
- error && 'ds_input--error',
65
+ hasError && 'ds_input--error',
66
66
  className
67
67
  ].join(' ')}
68
68
  defaultValue={value}
@@ -1,8 +1,8 @@
1
- const WarningText: React.FC<SGDS.Component.WarningText> = ({
1
+ const WarningText = ({
2
2
  children,
3
3
  className,
4
4
  ...props
5
- }) => {
5
+ }: SGDS.Component.WarningText) => {
6
6
  return (
7
7
  <div
8
8
  className={[
@@ -0,0 +1,64 @@
1
+
2
+ import { useState } from 'react';
3
+
4
+ import { test, expect } from 'vitest';
5
+ import { fireEvent, render, screen } from '@testing-library/react';
6
+
7
+ import useTracking from './useTracking';
8
+
9
+ const Link = ({ children }) => <a href="#">{children}</a>;
10
+
11
+ const Links = () => {
12
+ useTracking();
13
+ const [links, setLinks] = useState<string[]>([]);
14
+
15
+ const addNewLink = () => {
16
+ setLinks((prev) => [...prev, 'Second link']);
17
+ };
18
+
19
+ return (
20
+ <>
21
+ {links.map((link, index) => (
22
+ <Link key={`link-${index}`}>{link}</Link>
23
+ ))}
24
+
25
+ <button onClick={addNewLink}>
26
+ Add
27
+ </button>
28
+ </>
29
+ );
30
+ };
31
+
32
+ // basic test to verify the tracking script is having an effect
33
+ test('text tracking on component render', async () => {
34
+ const SECTION_ONE_TEXT = 'Foo';
35
+ const SECTION_TWO_TEXT = 'Bar';
36
+
37
+ render(
38
+ <>
39
+ <h1>{SECTION_ONE_TEXT}</h1>
40
+ <Link>First link</Link>
41
+ <h1>{SECTION_TWO_TEXT}</h1>
42
+ <Links />
43
+ </>
44
+ );
45
+
46
+ const button = screen.getByRole('button');
47
+ const firstLink = screen.getByText('First link');
48
+
49
+ // todo: this will fail until the tracking script in DS core is updated to use textContent instead of innerText
50
+ // expect(firstLink).toHaveAttribute('data-section', SECTION_ONE_TEXT);
51
+
52
+ fireEvent(
53
+ button,
54
+ new MouseEvent('click', new MouseEvent('click', {
55
+ bubbles: true,
56
+ cancelable: true,
57
+ })
58
+ ));
59
+
60
+ const secondLink = await screen.findByText('Second link')
61
+
62
+ // todo: this will fail until the tracking script in DS core is updated to use textContent instead of innerText
63
+ // expect(secondLink).toHaveAttribute('data-section', SECTION_TWO_TEXT);
64
+ });
@@ -0,0 +1,19 @@
1
+ import { useEffect } from 'react';
2
+
3
+ //@ts-ignore
4
+ import DSTracking from '@scottish-government/design-system/src/base/tools/tracking/tracking';
5
+
6
+ export default function () {
7
+ useEffect(() => {
8
+ const observer = new MutationObserver(() => {
9
+ DSTracking.init();
10
+ });
11
+ DSTracking.init();
12
+
13
+ observer.observe(document.body, { childList: true, subtree: true, characterData: true });
14
+
15
+ return () => {
16
+ observer.disconnect();
17
+ }
18
+ }, []);
19
+ }
@@ -0,0 +1,3 @@
1
+ import { createContext } from 'react';
2
+
3
+ export const CheckboxRadioContext = createContext({ small: true, name: '' });
package/tsconfig.json CHANGED
@@ -35,7 +35,7 @@
35
35
  },
36
36
  "include": [
37
37
  "@types",
38
- "src/**/*.tsx",
38
+ "src/**/*",
39
39
  "vitest.setup.ts"
40
40
  ],
41
41
  "exclude": [