@dhasdk/simple-ui 1.0.8 → 1.0.10

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 (228) hide show
  1. package/README.md +2 -2
  2. package/index.css +1 -0
  3. package/{src/index.ts → index.d.ts} +8 -15
  4. package/index.js +34 -0
  5. package/index.mjs +5473 -0
  6. package/lib/Accordion.d.ts +36 -0
  7. package/lib/AppointmentPicker.d.ts +21 -0
  8. package/lib/Badge.d.ts +11 -0
  9. package/lib/Breadcrumbs.d.ts +13 -0
  10. package/lib/Button.d.ts +15 -0
  11. package/lib/ButtonGroup.d.ts +8 -0
  12. package/lib/Card.d.ts +11 -0
  13. package/lib/CharacterCounter.d.ts +11 -0
  14. package/lib/CheckBox.d.ts +30 -0
  15. package/lib/DatePicker.d.ts +7 -0
  16. package/lib/Input.d.ts +16 -0
  17. package/lib/List.d.ts +22 -0
  18. package/lib/Modal.d.ts +18 -0
  19. package/lib/Pill.d.ts +13 -0
  20. package/lib/ProgressBar.d.ts +19 -0
  21. package/lib/RadioGroup.d.ts +16 -0
  22. package/lib/RadioIcon.d.ts +3 -0
  23. package/lib/Search.d.ts +26 -0
  24. package/lib/SearchContent.d.ts +6 -0
  25. package/lib/SectionHeader.d.ts +18 -0
  26. package/lib/Select.d.ts +19 -0
  27. package/lib/Shield.d.ts +12 -0
  28. package/lib/SideBarNav.d.ts +21 -0
  29. package/lib/Skeleton.d.ts +15 -0
  30. package/lib/SkipLink.d.ts +23 -0
  31. package/lib/Slider.d.ts +14 -0
  32. package/lib/Status.d.ts +10 -0
  33. package/lib/Tabs.d.ts +26 -0
  34. package/lib/Toggle.d.ts +11 -0
  35. package/lib/Tooltip.d.ts +14 -0
  36. package/package.json +1 -1
  37. package/.babelrc +0 -12
  38. package/.storybook/main.ts +0 -35
  39. package/.storybook/preview.ts +0 -4
  40. package/BAKpostcss.config.jsBAK +0 -15
  41. package/BAKtailwind.config.mjsBAK +0 -99
  42. package/coverage/storybook/coverage-storybook.json +0 -32411
  43. package/coverage/storybook/lcov-report/Accordion.tsx.html +0 -805
  44. package/coverage/storybook/lcov-report/Badge.tsx.html +0 -346
  45. package/coverage/storybook/lcov-report/Breadcrumbs.tsx.html +0 -742
  46. package/coverage/storybook/lcov-report/Button.tsx.html +0 -448
  47. package/coverage/storybook/lcov-report/ButtonGroup.tsx.html +0 -403
  48. package/coverage/storybook/lcov-report/Card.tsx.html +0 -292
  49. package/coverage/storybook/lcov-report/CharacterCounter.tsx.html +0 -253
  50. package/coverage/storybook/lcov-report/CheckBox.tsx.html +0 -1555
  51. package/coverage/storybook/lcov-report/DatePicker.tsx.html +0 -826
  52. package/coverage/storybook/lcov-report/Input.tsx.html +0 -1012
  53. package/coverage/storybook/lcov-report/List.tsx.html +0 -364
  54. package/coverage/storybook/lcov-report/Modal.tsx.html +0 -745
  55. package/coverage/storybook/lcov-report/Pill.tsx.html +0 -358
  56. package/coverage/storybook/lcov-report/Search.tsx.html +0 -997
  57. package/coverage/storybook/lcov-report/SearchContent.tsx.html +0 -235
  58. package/coverage/storybook/lcov-report/SectionHeader.tsx.html +0 -358
  59. package/coverage/storybook/lcov-report/Select.tsx.html +0 -1012
  60. package/coverage/storybook/lcov-report/Shield.tsx.html +0 -802
  61. package/coverage/storybook/lcov-report/SideBarNav.tsx.html +0 -490
  62. package/coverage/storybook/lcov-report/Skeleton.tsx.html +0 -394
  63. package/coverage/storybook/lcov-report/Slider.tsx.html +0 -385
  64. package/coverage/storybook/lcov-report/Status.tsx.html +0 -322
  65. package/coverage/storybook/lcov-report/Tabs.tsx.html +0 -610
  66. package/coverage/storybook/lcov-report/Toggle.tsx.html +0 -373
  67. package/coverage/storybook/lcov-report/Tooltip.tsx.html +0 -496
  68. package/coverage/storybook/lcov-report/base.css +0 -224
  69. package/coverage/storybook/lcov-report/block-navigation.js +0 -87
  70. package/coverage/storybook/lcov-report/favicon.png +0 -0
  71. package/coverage/storybook/lcov-report/index.html +0 -476
  72. package/coverage/storybook/lcov-report/prettify.css +0 -1
  73. package/coverage/storybook/lcov-report/prettify.js +0 -2
  74. package/coverage/storybook/lcov-report/sort-arrow-sprite.png +0 -0
  75. package/coverage/storybook/lcov-report/sorter.js +0 -196
  76. package/coverage/storybook/lcov.info +0 -2312
  77. package/dist/README.md +0 -1815
  78. package/eslint.config.mjs +0 -13
  79. package/project.json +0 -11
  80. package/src/assets/img/Frame.svg +0 -5
  81. package/src/assets/img/backArrowRight.svg +0 -10
  82. package/src/assets/img/bc-separator.png +0 -0
  83. package/src/assets/img/calendar.png +0 -0
  84. package/src/assets/img/calendar.svg +0 -4
  85. package/src/assets/img/check.svg +0 -5
  86. package/src/assets/img/check_box.svg +0 -10
  87. package/src/assets/img/check_box_empty.svg +0 -10
  88. package/src/assets/img/check_box_fill.svg +0 -10
  89. package/src/assets/img/check_box_fill_empty.svg +0 -10
  90. package/src/assets/img/chevron-down-white.svg +0 -2
  91. package/src/assets/img/chevron-down.svg +0 -2
  92. package/src/assets/img/chevron-left.svg +0 -1
  93. package/src/assets/img/chevron-right-light.svg +0 -4
  94. package/src/assets/img/chevron-right.svg +0 -3
  95. package/src/assets/img/chevron-up-white.svg +0 -1
  96. package/src/assets/img/chevron-up.svg +0 -1
  97. package/src/assets/img/clock.svg +0 -6
  98. package/src/assets/img/close.svg +0 -1
  99. package/src/assets/img/close2.svg +0 -6
  100. package/src/assets/img/closeModal.svg +0 -10
  101. package/src/assets/img/close_icon_dark.svg +0 -10
  102. package/src/assets/img/close_small.svg +0 -3
  103. package/src/assets/img/emergency_home.svg +0 -10
  104. package/src/assets/img/first-aid-kit.svg +0 -7
  105. package/src/assets/img/heartbeat.svg +0 -4
  106. package/src/assets/img/home-gray.svg +0 -3
  107. package/src/assets/img/home.svg +0 -3
  108. package/src/assets/img/hospital.jpg +0 -0
  109. package/src/assets/img/indeterminate_check_box.svg +0 -10
  110. package/src/assets/img/indeterminate_check_box_fill.svg +0 -10
  111. package/src/assets/img/info_24_ 1d4ed8.svg +0 -3
  112. package/src/assets/img/info_24_ 2c6441.svg +0 -3
  113. package/src/assets/img/marker_check_by_default.svg +0 -10
  114. package/src/assets/img/marker_check_by_default_fill.svg +0 -10
  115. package/src/assets/img/minus-accordion.svg +0 -5
  116. package/src/assets/img/minus.svg +0 -3
  117. package/src/assets/img/open.svg +0 -1
  118. package/src/assets/img/pill-white.svg +0 -7
  119. package/src/assets/img/pill.svg +0 -5
  120. package/src/assets/img/plus-accordion.svg +0 -5
  121. package/src/assets/img/plus.svg +0 -4
  122. package/src/assets/img/prescription.svg +0 -6
  123. package/src/assets/img/search.svg +0 -10
  124. package/src/assets/img/search_icon_light.svg +0 -10
  125. package/src/assets/img/separator.svg +0 -3
  126. package/src/assets/img/stethoscope-white.svg +0 -8
  127. package/src/assets/img/stethoscope.svg +0 -8
  128. package/src/assets/img/thumb_up.svg +0 -10
  129. package/src/assets/img/vector.svg +0 -3
  130. package/src/assets/img/warning-badge-disabled.svg +0 -11
  131. package/src/assets/img/warning-badge-green.svg +0 -11
  132. package/src/assets/img/warning-badge-red.svg +0 -11
  133. package/src/assets/img/warning-badge-yellow.svg +0 -11
  134. package/src/assets/img/warning.svg +0 -10
  135. package/src/global.d.ts +0 -13
  136. package/src/lib/Accordian--Accordian.stories.tsx +0 -312
  137. package/src/lib/Accordion.spec.tsx +0 -384
  138. package/src/lib/Accordion.tsx +0 -240
  139. package/src/lib/AppointmentPicker.spec.tsx +0 -138
  140. package/src/lib/AppointmentPicker.tsx +0 -97
  141. package/src/lib/Badge--Badge.stories.tsx +0 -60
  142. package/src/lib/Badge.spec.tsx +0 -70
  143. package/src/lib/Badge.tsx +0 -87
  144. package/src/lib/Breadcrumbs-Breadcrumbs.stories.tsx +0 -114
  145. package/src/lib/Breadcrumbs.spec.tsx +0 -218
  146. package/src/lib/Breadcrumbs.tsx +0 -219
  147. package/src/lib/Button--Button.stories.tsx +0 -220
  148. package/src/lib/Button.spec.tsx +0 -241
  149. package/src/lib/Button.tsx +0 -121
  150. package/src/lib/ButtonGroup--ButtonGroup.stories.tsx +0 -129
  151. package/src/lib/ButtonGroup.spec.tsx +0 -89
  152. package/src/lib/ButtonGroup.tsx +0 -107
  153. package/src/lib/Card--Card.stories.tsx +0 -113
  154. package/src/lib/Card.spec.tsx +0 -112
  155. package/src/lib/Card.tsx +0 -69
  156. package/src/lib/CharacterCounter--CharacterCounter.stories.tsx +0 -169
  157. package/src/lib/CharacterCounter.spec.tsx +0 -123
  158. package/src/lib/CharacterCounter.tsx +0 -56
  159. package/src/lib/CheckBox--CheckBox.stories.tsx +0 -107
  160. package/src/lib/CheckBox.spec.tsx +0 -412
  161. package/src/lib/CheckBox.tsx +0 -491
  162. package/src/lib/DatePicker--DatePicker.stories.tsx +0 -228
  163. package/src/lib/DatePicker.spec.tsx +0 -424
  164. package/src/lib/DatePicker.tsx +0 -247
  165. package/src/lib/Input--Input.stories.tsx +0 -449
  166. package/src/lib/Input.spec.tsx +0 -281
  167. package/src/lib/Input.tsx +0 -309
  168. package/src/lib/List--List.stories.tsx +0 -157
  169. package/src/lib/List.spec.tsx +0 -211
  170. package/src/lib/List.tsx +0 -93
  171. package/src/lib/Modal--Modal.stories.tsx +0 -454
  172. package/src/lib/Modal.spec.tsx +0 -202
  173. package/src/lib/Modal.tsx +0 -220
  174. package/src/lib/Pill--Pill.stories.tsx +0 -98
  175. package/src/lib/Pill.spec.tsx +0 -103
  176. package/src/lib/Pill.tsx +0 -91
  177. package/src/lib/ProgressBar.spec.tsx +0 -106
  178. package/src/lib/ProgressBar.tsx +0 -112
  179. package/src/lib/RadioGroup.spec.tsx +0 -84
  180. package/src/lib/RadioGroup.tsx +0 -74
  181. package/src/lib/RadioIcon.tsx +0 -13
  182. package/src/lib/Search--Search.stories.tsx +0 -67
  183. package/src/lib/Search.spec.tsx +0 -182
  184. package/src/lib/Search.tsx +0 -304
  185. package/src/lib/SearchContent.tsx +0 -51
  186. package/src/lib/SectionHeader--SectionHeader.stories.tsx +0 -98
  187. package/src/lib/SectionHeader.spec.tsx +0 -60
  188. package/src/lib/SectionHeader.tsx +0 -91
  189. package/src/lib/Select--Select.stories.tsx +0 -387
  190. package/src/lib/Select.spec.tsx +0 -493
  191. package/src/lib/Select.tsx +0 -311
  192. package/src/lib/Shield--Shield.stories.tsx +0 -196
  193. package/src/lib/Shield.spec.tsx +0 -275
  194. package/src/lib/Shield.tsx +0 -239
  195. package/src/lib/SideBarNav--SideBarNav.stories.tsx +0 -136
  196. package/src/lib/SideBarNav.spec.tsx +0 -178
  197. package/src/lib/SideBarNav.tsx +0 -135
  198. package/src/lib/Skeleton--Skeleton.stories.tsx +0 -77
  199. package/src/lib/Skeleton.module.css +0 -16
  200. package/src/lib/Skeleton.spec.tsx +0 -83
  201. package/src/lib/Skeleton.tsx +0 -103
  202. package/src/lib/SkipLink.spec.tsx +0 -76
  203. package/src/lib/SkipLink.tsx +0 -48
  204. package/src/lib/Slider--Slider.stories.tsx +0 -108
  205. package/src/lib/Slider.module.css +0 -109
  206. package/src/lib/Slider.spec.tsx +0 -67
  207. package/src/lib/Slider.tsx +0 -101
  208. package/src/lib/Status--Status.stories.tsx +0 -93
  209. package/src/lib/Status.spec.tsx +0 -118
  210. package/src/lib/Status.tsx +0 -79
  211. package/src/lib/Tabs--Tabs.stories.tsx +0 -294
  212. package/src/lib/Tabs.spec.tsx +0 -249
  213. package/src/lib/Tabs.tsx +0 -188
  214. package/src/lib/Tester.spec.tsx +0 -17
  215. package/src/lib/Toggle--Toggle.stories.tsx +0 -162
  216. package/src/lib/Toggle.spec.tsx +0 -122
  217. package/src/lib/Toggle.tsx +0 -96
  218. package/src/lib/Tooltip--Tooltip.stories.tsx +0 -315
  219. package/src/lib/Tooltip.spec.tsx +0 -307
  220. package/src/lib/Tooltip.tsx +0 -137
  221. package/src/lib/bak-simple-ui.stories.tsx-bak +0 -24
  222. package/src/styles.css +0 -190
  223. package/tsconfig.json +0 -25
  224. package/tsconfig.lib.json +0 -42
  225. package/tsconfig.spec.json +0 -29
  226. package/tsconfig.storybook.json +0 -36
  227. package/vite.config.mts +0 -87
  228. package/vitest.setup.ts +0 -12
@@ -1,107 +0,0 @@
1
- import { Meta } from '@storybook/react';
2
- import { CheckBox, CheckBoxGroup, CheckBoxProps } from './CheckBox';
3
-
4
- // import imagePath from 'src/assets/img/pill.svg';
5
- const imagePath = 'src/assets/img/hospital.jpg';
6
- // imagePath: 'src/assets/img/heartbeat.svg',
7
-
8
- // Meta object - defines basic storybook options for this story
9
- export default {
10
- title: 'Components/CheckBox',
11
- component: CheckBox,
12
- argTypes: {
13
- variant: {
14
- control: 'select',
15
- options: ['','']
16
- },
17
- },
18
- args: {
19
- // label: 'Button', // set default argument values
20
- },
21
- parameters: {
22
- layout: 'centered', // options are 'centered', 'fullscreen', and 'padded' (default value)
23
- backgrounds: { default: 'light' }, // options are light, medium, or dark
24
- },
25
- } as Meta<CheckBoxProps>;
26
-
27
- // Define "Default" story
28
- export const Default = {
29
- args: {
30
- ariaLabel: 'test label',
31
- alt: 'image alt',
32
- children: 'CheckBox 1'
33
- }
34
- };
35
-
36
- export const Group = () => {
37
- // const [searchResults, setSearchResults] = useState<DataSearchResults>();
38
-
39
- return (
40
- <>
41
- <div className='mb-4'>Note: 'level' prop does not take effect w/o use of the CheckBoxContainer component.</div>
42
- <CheckBox level={0}>Group 1</CheckBox>
43
- <CheckBox level={1}>g1, item 1</CheckBox>
44
- <CheckBox level={1}>g1, item 2</CheckBox>
45
- <CheckBox level={0}>Group 2</CheckBox>
46
- <CheckBox level={1}>g2, item 1</CheckBox>
47
- <CheckBox level={1}>g2, item 2</CheckBox>
48
- <CheckBox level={2}>g2, item 2, item 1</CheckBox>
49
- </>
50
- );
51
- };
52
-
53
-
54
- export const GroupContainer = () => {
55
- // const [searchResults, setSearchResults] = useState<DataSearchResults>();
56
-
57
- return (
58
- <CheckBoxGroup>
59
- <CheckBox level={0}>Group 1</CheckBox>
60
- <CheckBox level={1}>g1, item 1</CheckBox>
61
- <CheckBox level={1}>g1, item 2</CheckBox>
62
- <CheckBox level={0}>Group 2</CheckBox>
63
- <CheckBox level={1}>g2, item 1</CheckBox>
64
- <CheckBox level={1}>g2, item 2</CheckBox>
65
- <CheckBox level={2}>g2, item 2, item 1</CheckBox>
66
- </CheckBoxGroup>
67
- );
68
- };
69
-
70
-
71
- export const GroupContainer2 = () => {
72
- // const [searchResults, setSearchResults] = useState<DataSearchResults>();
73
-
74
- return (
75
- <CheckBoxGroup>
76
- <CheckBox level={0}>Group 1</CheckBox>
77
- <CheckBox level={1}>g1, item 1</CheckBox>
78
- <CheckBox level={1}>g1, item 2</CheckBox>
79
- <CheckBox level={2}>g1, item 2, item 1</CheckBox>
80
- <CheckBox level={2}>g1, item 2, item 2</CheckBox>
81
- <CheckBox level={0}>Group 2</CheckBox>
82
- <CheckBox level={1}>g2, item 1</CheckBox>
83
- <CheckBox level={1}>g2, item 2</CheckBox>
84
- <CheckBox level={2}>g2, item 2, item 1</CheckBox>
85
- </CheckBoxGroup>
86
- );
87
- };
88
-
89
-
90
- export const GroupContainer3 = () => {
91
- // const [searchResults, setSearchResults] = useState<DataSearchResults>();
92
-
93
- return (
94
- <CheckBoxGroup>
95
- <CheckBox level={0}>Group 1</CheckBox>
96
- <CheckBox level={1}>g1, item 1</CheckBox>
97
- <CheckBox level={1}>g1, item 2</CheckBox>
98
- <CheckBox level={2}>g1, item 2, item 1</CheckBox>
99
- <CheckBox level={2}>g1, item 2, item 2</CheckBox>
100
- <CheckBox level={1}>g1, item 3</CheckBox>
101
- <CheckBox level={0}>Group 2</CheckBox>
102
- <CheckBox level={1}>g2, item 1</CheckBox>
103
- <CheckBox level={1}>g2, item 2</CheckBox>
104
- <CheckBox level={2}>g2, item 2, item 1</CheckBox>
105
- </CheckBoxGroup>
106
- );
107
- };
@@ -1,412 +0,0 @@
1
- import React, { createRef } from "react";
2
- import { render, screen, fireEvent } from "@testing-library/react";
3
- import userEvent from "@testing-library/user-event";
4
- import { describe, it, expect, vi } from "vitest";
5
- import { axe } from "vitest-axe";
6
-
7
- import { CheckBox, CheckBoxGroup } from "./CheckBox";
8
-
9
- // add jest-dom / vitest-dom matchers
10
- // expect.extend(toHaveNoViolations);
11
-
12
- describe("CheckBox component", () => {
13
- it("should render unchecked by default and have no accessibility violations", async () => {
14
- render(<main><CheckBox ariaLabel="accept terms">Accept terms</CheckBox></main>);
15
-
16
- // find checkbox input
17
- const input = screen.getByRole("checkbox", { name: "accept terms" });
18
- expect(input).toBeInTheDocument();
19
- expect(input).not.toBeChecked();
20
-
21
- // icon img alt should reflect 'unchecked'
22
- const img = screen.getByAltText("unchecked") as HTMLImageElement;
23
- expect(img).toBeInTheDocument();
24
- expect(img.src).toContain("check_box_empty.svg");
25
-
26
- // axe accessibility scan
27
- const results = await axe(document.body);
28
- expect(results).toHaveNoViolations();
29
- });
30
-
31
- it("toggles to checked on click and calls setStatusUpdate", async () => {
32
- const mockSet = vi.fn();
33
- render(
34
- <CheckBox
35
- ariaLabel="my box"
36
- setStatusUpdate={mockSet}
37
- index={0}
38
- >
39
- Label
40
- </CheckBox>
41
- );
42
-
43
- const input = screen.getByRole("checkbox", { name: "my box" });
44
- // click to check
45
- await userEvent.click(input);
46
- expect(input).toBeChecked();
47
-
48
- // after toggle, the internal effect should call setStatusUpdate('checked', 0)
49
- expect(mockSet).toHaveBeenCalledWith("checked", 0);
50
-
51
- // the icon src should update to checked icon
52
- const img = screen.getByAltText("checked") as HTMLImageElement;
53
- expect(img.src).toContain("check_box.svg");
54
- });
55
-
56
-
57
- it("uses marker icon when checked with marker prop", async () => {
58
- render(
59
- <CheckBox
60
- ariaLabel="marker box"
61
- marker={true}
62
- setStatusUpdate={vi.fn()}
63
- index={0}
64
- >
65
- Marker
66
- </CheckBox>
67
- );
68
-
69
- const input = screen.getByRole("checkbox", { name: "marker box" }) as HTMLInputElement;
70
- // check it
71
- await userEvent.click(input);
72
- expect(input).toBeChecked();
73
-
74
- // marker (unchecked) initially shows regular empty – marker only kicks in on checked
75
- // now that it's checked, we expect the marker icon
76
- const img = screen.getByAltText("checked") as HTMLImageElement;
77
- expect(img.src).toContain("marker_check_by_default.svg");
78
- });
79
-
80
- it("uses filled marker icon when checked with marker and fill props", async () => {
81
- render(
82
- <CheckBox
83
- ariaLabel="filled marker box"
84
- marker={true}
85
- fill={true}
86
- setStatusUpdate={vi.fn()}
87
- index={0}
88
- >
89
- Filled Marker
90
- </CheckBox>
91
- );
92
-
93
- const input = screen.getByRole("checkbox", { name: "filled marker box" }) as HTMLInputElement;
94
- // check it
95
- await userEvent.click(input);
96
- expect(input).toBeChecked();
97
-
98
- // with fill and marker, we expect the filled marker icon
99
- const img = screen.getByAltText("checked") as HTMLImageElement;
100
- expect(img.src).toContain("marker_check_by_default_fill.svg");
101
- });
102
-
103
- });
104
-
105
-
106
- // CHECKBOX GROUP COMPONENT --------------------------
107
-
108
- describe("CheckBoxGroup component", () => {
109
-
110
- const Siblings = (props: { bridgeParent?: boolean }) => (
111
- <CheckBoxGroup bridgeParent>
112
- <CheckBox level={0} ariaLabel="item A">A</CheckBox>
113
- <CheckBox level={0} ariaLabel="item B">B</CheckBox>
114
- <CheckBox level={1} ariaLabel="item BA">BA</CheckBox>
115
- <CheckBox level={1} ariaLabel="item BB">BB</CheckBox>
116
- <CheckBox level={2} ariaLabel="item BBA">BBA</CheckBox>
117
- <CheckBox level={2} ariaLabel="item BBB">BBB</CheckBox>
118
- <CheckBox level={2} ariaLabel="item BBC">BBC</CheckBox>
119
- <CheckBox level={1} ariaLabel="item BC">BC</CheckBox>
120
- <CheckBox level={0} ariaLabel="item C">C</CheckBox>
121
- <CheckBox level={1} ariaLabel="item CA">CA</CheckBox>
122
- <CheckBox level={2} ariaLabel="item CAA">CAA</CheckBox>
123
- <CheckBox level={2} ariaLabel="item CAB">CAB</CheckBox>
124
- <CheckBox level={2} ariaLabel="item CAC">CAC</CheckBox>
125
- </CheckBoxGroup>
126
- );
127
-
128
-
129
- const SiblingsFill = (props: { bridgeParent?: boolean }) => (
130
- <CheckBoxGroup bridgeParent fill>
131
- <CheckBox level={0} ariaLabel="item A">A</CheckBox>
132
- <CheckBox level={0} ariaLabel="item B">B</CheckBox>
133
- <CheckBox level={1} ariaLabel="item BA">BA</CheckBox>
134
- <CheckBox level={1} ariaLabel="item BB">BB</CheckBox>
135
- <CheckBox level={2} ariaLabel="item BBA">BBA</CheckBox>
136
- <CheckBox level={2} ariaLabel="item BBB">BBB</CheckBox>
137
- <CheckBox level={2} ariaLabel="item BBC">BBC</CheckBox>
138
- <CheckBox level={1} ariaLabel="item BC">BC</CheckBox>
139
- <CheckBox level={0} ariaLabel="item C">C</CheckBox>
140
- <CheckBox level={1} ariaLabel="item CA">CA</CheckBox>
141
- <CheckBox level={2} ariaLabel="item CAA">CAA</CheckBox>
142
- <CheckBox level={2} ariaLabel="item CAB">CAB</CheckBox>
143
- <CheckBox level={2} ariaLabel="item CAC">CAC</CheckBox>
144
- </CheckBoxGroup>
145
- );
146
-
147
-
148
-
149
- /**
150
- * Build a tiny hierarchy:
151
- * - parent (level 0)
152
- * - child 1 (level 1)
153
- * - child 2 (level 1)
154
- */
155
- const Parent = () => (
156
- <CheckBoxGroup>
157
- <CheckBox level={0} ariaLabel="parent">Parent</CheckBox>
158
- <CheckBox level={1} ariaLabel="child 1">Child 1</CheckBox>
159
- <CheckBox level={1} ariaLabel="child 2">Child 2</CheckBox>
160
- </CheckBoxGroup>
161
- );
162
-
163
- it("checks all children when parent is clicked", async () => {
164
- render(<Parent />);
165
-
166
- const parentInput = screen.getByRole("checkbox", { name: "parent" });
167
- const child1 = screen.getByRole("checkbox", { name: "child 1" });
168
- const child2 = screen.getByRole("checkbox", { name: "child 2" });
169
-
170
- // click parent → should check parent and both children
171
- await userEvent.click(parentInput);
172
- expect(parentInput).toBeChecked();
173
- expect(child1).toBeChecked();
174
- expect(child2).toBeChecked();
175
- });
176
-
177
- it("sets parent to indeterminate if only one child is checked", async () => {
178
- render(<Parent />);
179
-
180
- const parentInput = screen.getByRole("checkbox", { name: "parent" }) as HTMLInputElement;
181
- const child1 = screen.getByRole("checkbox", { name: "child 1" });
182
- const child2 = screen.getByRole("checkbox", { name: "child 2" });
183
-
184
- // click only the first child
185
- await userEvent.click(child1);
186
- expect(child1).toBeChecked();
187
- expect(child2).not.toBeChecked();
188
-
189
- // parent should now be indeterminate
190
- expect(parentInput.indeterminate).toBe(true);
191
- });
192
-
193
- it("unchecks all children when parent is clicked twice", async () => {
194
- render(<Parent />);
195
-
196
- const parentInput = screen.getByRole("checkbox", { name: "parent" });
197
- const child1 = screen.getByRole("checkbox", { name: "child 1" });
198
- const child2 = screen.getByRole("checkbox", { name: "child 2" });
199
-
200
- // first click → all checked
201
- await userEvent.click(parentInput);
202
- expect(child1).toBeChecked();
203
- expect(child2).toBeChecked();
204
-
205
- // second click → all unchecked
206
- await userEvent.click(parentInput);
207
- expect(parentInput).not.toBeChecked();
208
- expect(child1).not.toBeChecked();
209
- expect(child2).not.toBeChecked();
210
- });
211
-
212
-
213
- // Uses SIBLINGS
214
- it("only toggles the clicked checkbox among siblings at the same level", async () => {
215
- render(<Siblings />);
216
-
217
- const [a, b, ba, bb, bba, bbb, bbc, bc, c, ca, caa, cab, cac] = ["item A", "item B", "item BA",
218
- "item BB", "item BBA", "item BBB", "item BBC", "item BC", "item C",
219
- "item CA", "item CAA", "item CAB", "item CAC"].map(name =>
220
- screen.getByRole("checkbox", { name }) as HTMLInputElement
221
- );
222
-
223
- // click A → only A becomes checked
224
- await userEvent.click(a);
225
- expect(a).toBeChecked(); // Checked
226
- expect(b).not.toBeChecked();
227
- expect(ba).not.toBeChecked();
228
- expect(bb).not.toBeChecked();
229
- expect(bba).not.toBeChecked();
230
- expect(bbb).not.toBeChecked();
231
- expect(bbc).not.toBeChecked();
232
- expect(bc).not.toBeChecked();
233
- expect(c).not.toBeChecked();
234
-
235
- // click B → A remains checked, B toggles on, C stays off
236
- await userEvent.click(b);
237
- expect(a).toBeChecked(); // Checked
238
- expect(b).toBeChecked(); // Checked
239
- expect(ba).toBeChecked(); // Checked
240
- expect(bb).toBeChecked(); // Checked
241
- expect(bba).toBeChecked(); // Checked
242
- expect(bbb).toBeChecked(); // Checked
243
- expect(bbc).toBeChecked(); // Checked
244
- expect(bc).toBeChecked(); // Checked
245
- expect(c).not.toBeChecked();
246
-
247
- // click A again → A toggles off, B stays on, C stays off
248
- await userEvent.click(a);
249
- expect(a).not.toBeChecked();
250
- expect(b).toBeChecked(); // Checked
251
- expect(ba).toBeChecked(); // Checked
252
- expect(bb).toBeChecked(); // Checked
253
- expect(bba).toBeChecked(); // Checked
254
- expect(bbb).toBeChecked(); // Checked
255
- expect(bbc).toBeChecked(); // Checked
256
- expect(bc).toBeChecked(); // Checked
257
- expect(c).not.toBeChecked();
258
-
259
- // click BB → A remains unchecked, BB toggles off
260
- // click BB → BB and its descendants are unchecked; B should become indeterminate
261
- await userEvent.click(bb);
262
-
263
- // first grab everything as HTMLInputElements
264
- const bInput = b as HTMLInputElement;
265
-
266
- expect(a).not.toBeChecked();
267
-
268
- // instead of expecting B to be unchecked, we assert that:
269
- // • it's not checked,
270
- // • but it *is* indeterminate
271
- expect(bInput.checked).toBe(false);
272
- expect(bInput.indeterminate).toBe(true);
273
-
274
- // BA stays checked
275
- expect(ba).toBeChecked();
276
-
277
- // BB itself is now unchecked
278
- expect(bb).not.toBeChecked();
279
-
280
- // its children (BBA, BBB, BBC) are all unchecked
281
- expect(bba).not.toBeChecked();
282
- expect(bbb).not.toBeChecked();
283
- expect(bbc).not.toBeChecked();
284
-
285
- // BC (sibling-child of B) remains checked
286
- expect(bc).toBeChecked();
287
-
288
- expect(c).not.toBeChecked();
289
-
290
-
291
- await userEvent.click(caa);
292
- expect(c).not.toBeChecked();
293
- expect(ca).not.toBeChecked();
294
- expect(caa).toBeChecked();
295
- expect(cab).not.toBeChecked();
296
- expect(cac).not.toBeChecked();
297
- });
298
-
299
-
300
- it("only toggles the clicked checkbox among siblings at the same level - fill variant", async () => {
301
- render(<SiblingsFill />);
302
-
303
- const [a, b, ba, bb, bba, bbb, bbc, bc, c, ca, caa, cab, cac] = ["item A", "item B", "item BA",
304
- "item BB", "item BBA", "item BBB", "item BBC", "item BC", "item C",
305
- "item CA", "item CAA", "item CAB", "item CAC"].map(name =>
306
- screen.getByRole("checkbox", { name }) as HTMLInputElement
307
- );
308
-
309
- // click A → only A becomes checked
310
- await userEvent.click(a);
311
- expect(a).toBeChecked(); // Checked
312
- expect(b).not.toBeChecked();
313
- expect(ba).not.toBeChecked();
314
- expect(bb).not.toBeChecked();
315
- expect(bba).not.toBeChecked();
316
- expect(bbb).not.toBeChecked();
317
- expect(bbc).not.toBeChecked();
318
- expect(bc).not.toBeChecked();
319
- expect(c).not.toBeChecked();
320
-
321
- // click B → A remains checked, B toggles on, C stays off
322
- await userEvent.click(b);
323
- expect(a).toBeChecked(); // Checked
324
- expect(b).toBeChecked(); // Checked
325
- expect(ba).toBeChecked(); // Checked
326
- expect(bb).toBeChecked(); // Checked
327
- expect(bba).toBeChecked(); // Checked
328
- expect(bbb).toBeChecked(); // Checked
329
- expect(bbc).toBeChecked(); // Checked
330
- expect(bc).toBeChecked(); // Checked
331
- expect(c).not.toBeChecked();
332
-
333
- // click A again → A toggles off, B stays on, C stays off
334
- await userEvent.click(a);
335
- expect(a).not.toBeChecked();
336
- expect(b).toBeChecked(); // Checked
337
- expect(ba).toBeChecked(); // Checked
338
- expect(bb).toBeChecked(); // Checked
339
- expect(bba).toBeChecked(); // Checked
340
- expect(bbb).toBeChecked(); // Checked
341
- expect(bbc).toBeChecked(); // Checked
342
- expect(bc).toBeChecked(); // Checked
343
- expect(c).not.toBeChecked();
344
-
345
- // click BB → A remains unchecked, BB toggles off
346
- // click BB → BB and its descendants are unchecked; B should become indeterminate
347
- await userEvent.click(bb);
348
-
349
- // first grab everything as HTMLInputElements
350
- const bInput = b as HTMLInputElement;
351
-
352
- expect(a).not.toBeChecked();
353
-
354
- // instead of expecting B to be unchecked, we assert that:
355
- // • it's not checked,
356
- // • but it *is* indeterminate
357
- expect(bInput.checked).toBe(false);
358
- expect(bInput.indeterminate).toBe(true);
359
-
360
- // BA stays checked
361
- expect(ba).toBeChecked();
362
-
363
- // BB itself is now unchecked
364
- expect(bb).not.toBeChecked();
365
-
366
- // its children (BBA, BBB, BBC) are all unchecked
367
- expect(bba).not.toBeChecked();
368
- expect(bbb).not.toBeChecked();
369
- expect(bbc).not.toBeChecked();
370
-
371
- // BC (sibling-child of B) remains checked
372
- expect(bc).toBeChecked();
373
-
374
- expect(c).not.toBeChecked();
375
-
376
-
377
- await userEvent.click(caa);
378
- expect(c).not.toBeChecked();
379
- expect(ca).not.toBeChecked();
380
- expect(caa).toBeChecked();
381
- expect(cab).not.toBeChecked();
382
- expect(cac).not.toBeChecked();
383
- });
384
-
385
- // Uses SIBLINGS
386
- it("with bridgeParent=true still treats siblings independently", async () => {
387
- render(<Siblings bridgeParent={true} />);
388
-
389
- const [a, b, c] = ["item A", "item B", "item C"].map(name =>
390
- screen.getByRole("checkbox", { name }) as HTMLInputElement
391
- );
392
-
393
- // click C → only C becomes checked
394
- await userEvent.click(c);
395
- expect(a).not.toBeChecked();
396
- expect(b).not.toBeChecked();
397
- expect(c).toBeChecked();
398
-
399
- // click B → C remains checked, B toggles on, A stays off
400
- await userEvent.click(b);
401
- expect(a).not.toBeChecked();
402
- expect(b).toBeChecked();
403
- expect(c).toBeChecked();
404
-
405
- // click B again → B toggles off, C stays on
406
- await userEvent.click(b);
407
- expect(a).not.toBeChecked();
408
- expect(b).not.toBeChecked();
409
- expect(c).toBeChecked();
410
-
411
- });
412
- });