@coreui/react-pro 5.24.0 → 5.25.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 (180) hide show
  1. package/README.md +1 -1
  2. package/dist/cjs/components/calendar/CCalendar.js +4 -3
  3. package/dist/cjs/components/calendar/CCalendar.js.map +1 -1
  4. package/dist/cjs/components/date-picker/CDatePicker.d.ts +1 -1
  5. package/dist/cjs/components/date-picker/CDatePicker.js.map +1 -1
  6. package/dist/cjs/components/date-range-picker/CDateRangePicker.js +2 -0
  7. package/dist/cjs/components/date-range-picker/CDateRangePicker.js.map +1 -1
  8. package/dist/cjs/components/dropdown/CDropdown.js +1 -1
  9. package/dist/cjs/components/dropdown/CDropdown.js.map +1 -1
  10. package/dist/cjs/components/index.d.ts +1 -0
  11. package/dist/cjs/components/nav/CNavGroup.d.ts +3 -1
  12. package/dist/cjs/components/nav/CNavGroup.js +9 -5
  13. package/dist/cjs/components/nav/CNavGroup.js.map +1 -1
  14. package/dist/cjs/components/one-time-password-input/COneTimePassword.js +3 -3
  15. package/dist/cjs/components/one-time-password-input/COneTimePassword.js.map +1 -1
  16. package/dist/cjs/components/popover/CPopover.js +14 -17
  17. package/dist/cjs/components/popover/CPopover.js.map +1 -1
  18. package/dist/cjs/components/search-button/CSearchButton.d.ts +32 -0
  19. package/dist/cjs/components/search-button/CSearchButton.js +77 -0
  20. package/dist/cjs/components/search-button/CSearchButton.js.map +1 -0
  21. package/dist/cjs/components/search-button/index.d.ts +2 -0
  22. package/dist/cjs/components/search-button/types.d.ts +10 -0
  23. package/dist/cjs/components/search-button/utils.d.ts +11 -0
  24. package/dist/cjs/components/search-button/utils.js +115 -0
  25. package/dist/cjs/components/search-button/utils.js.map +1 -0
  26. package/dist/cjs/components/sidebar/CSidebarNav.d.ts +12 -0
  27. package/dist/cjs/components/sidebar/CSidebarNav.js +7 -2
  28. package/dist/cjs/components/sidebar/CSidebarNav.js.map +1 -1
  29. package/dist/cjs/components/smart-table/CSmartTable.js +2 -2
  30. package/dist/cjs/components/smart-table/CSmartTable.js.map +1 -1
  31. package/dist/cjs/components/smart-table/CSmartTableInterface.d.ts +2 -2
  32. package/dist/cjs/components/time-picker/CTimePicker.d.ts +1 -1
  33. package/dist/cjs/components/time-picker/CTimePicker.js +1 -1
  34. package/dist/cjs/components/time-picker/CTimePicker.js.map +1 -1
  35. package/dist/cjs/components/tooltip/CTooltip.js +14 -17
  36. package/dist/cjs/components/tooltip/CTooltip.js.map +1 -1
  37. package/dist/cjs/components/virtual-scroller/CVirtualScroller.js +11 -8
  38. package/dist/cjs/components/virtual-scroller/CVirtualScroller.js.map +1 -1
  39. package/dist/cjs/hooks/useDebouncedCallback.d.ts +1 -1
  40. package/dist/cjs/hooks/useDebouncedCallback.js +1 -1
  41. package/dist/cjs/hooks/useDebouncedCallback.js.map +1 -1
  42. package/dist/cjs/index.js +2 -0
  43. package/dist/cjs/index.js.map +1 -1
  44. package/dist/cjs/node_modules/@coreui/icons/dist/esm/free/cil-arrow-bottom.js +1 -1
  45. package/dist/cjs/node_modules/@coreui/icons/dist/esm/free/cil-arrow-bottom.js.map +1 -1
  46. package/dist/cjs/node_modules/@coreui/icons/dist/esm/free/cil-arrow-top.js +1 -1
  47. package/dist/cjs/node_modules/@coreui/icons/dist/esm/free/cil-arrow-top.js.map +1 -1
  48. package/dist/cjs/node_modules/@coreui/icons/dist/esm/free/cil-filter-x.js +1 -1
  49. package/dist/cjs/node_modules/@coreui/icons/dist/esm/free/cil-filter-x.js.map +1 -1
  50. package/dist/cjs/node_modules/@coreui/icons/dist/esm/free/cil-swap-vertical.js +1 -1
  51. package/dist/cjs/node_modules/@coreui/icons/dist/esm/free/cil-swap-vertical.js.map +1 -1
  52. package/dist/cjs/node_modules/ua-parser-js/dist/ua-parser.min.js +2 -2
  53. package/dist/cjs/node_modules/ua-parser-js/dist/ua-parser.min.js.map +1 -1
  54. package/dist/esm/components/calendar/CCalendar.js +4 -3
  55. package/dist/esm/components/calendar/CCalendar.js.map +1 -1
  56. package/dist/esm/components/date-picker/CDatePicker.d.ts +1 -1
  57. package/dist/esm/components/date-picker/CDatePicker.js.map +1 -1
  58. package/dist/esm/components/date-range-picker/CDateRangePicker.js +2 -0
  59. package/dist/esm/components/date-range-picker/CDateRangePicker.js.map +1 -1
  60. package/dist/esm/components/dropdown/CDropdown.js +1 -1
  61. package/dist/esm/components/dropdown/CDropdown.js.map +1 -1
  62. package/dist/esm/components/index.d.ts +1 -0
  63. package/dist/esm/components/nav/CNavGroup.d.ts +3 -1
  64. package/dist/esm/components/nav/CNavGroup.js +9 -5
  65. package/dist/esm/components/nav/CNavGroup.js.map +1 -1
  66. package/dist/esm/components/one-time-password-input/COneTimePassword.js +3 -3
  67. package/dist/esm/components/one-time-password-input/COneTimePassword.js.map +1 -1
  68. package/dist/esm/components/popover/CPopover.js +14 -17
  69. package/dist/esm/components/popover/CPopover.js.map +1 -1
  70. package/dist/esm/components/search-button/CSearchButton.d.ts +32 -0
  71. package/dist/esm/components/search-button/CSearchButton.js +75 -0
  72. package/dist/esm/components/search-button/CSearchButton.js.map +1 -0
  73. package/dist/esm/components/search-button/index.d.ts +2 -0
  74. package/dist/esm/components/search-button/types.d.ts +10 -0
  75. package/dist/esm/components/search-button/utils.d.ts +11 -0
  76. package/dist/esm/components/search-button/utils.js +104 -0
  77. package/dist/esm/components/search-button/utils.js.map +1 -0
  78. package/dist/esm/components/sidebar/CSidebarNav.d.ts +12 -0
  79. package/dist/esm/components/sidebar/CSidebarNav.js +7 -2
  80. package/dist/esm/components/sidebar/CSidebarNav.js.map +1 -1
  81. package/dist/esm/components/smart-table/CSmartTable.js +2 -2
  82. package/dist/esm/components/smart-table/CSmartTable.js.map +1 -1
  83. package/dist/esm/components/smart-table/CSmartTableInterface.d.ts +2 -2
  84. package/dist/esm/components/time-picker/CTimePicker.d.ts +1 -1
  85. package/dist/esm/components/time-picker/CTimePicker.js +1 -1
  86. package/dist/esm/components/time-picker/CTimePicker.js.map +1 -1
  87. package/dist/esm/components/tooltip/CTooltip.js +14 -17
  88. package/dist/esm/components/tooltip/CTooltip.js.map +1 -1
  89. package/dist/esm/components/virtual-scroller/CVirtualScroller.js +11 -8
  90. package/dist/esm/components/virtual-scroller/CVirtualScroller.js.map +1 -1
  91. package/dist/esm/hooks/useDebouncedCallback.d.ts +1 -1
  92. package/dist/esm/hooks/useDebouncedCallback.js +1 -1
  93. package/dist/esm/hooks/useDebouncedCallback.js.map +1 -1
  94. package/dist/esm/index.js +1 -0
  95. package/dist/esm/index.js.map +1 -1
  96. package/dist/esm/node_modules/@coreui/icons/dist/esm/free/cil-arrow-bottom.js +1 -1
  97. package/dist/esm/node_modules/@coreui/icons/dist/esm/free/cil-arrow-bottom.js.map +1 -1
  98. package/dist/esm/node_modules/@coreui/icons/dist/esm/free/cil-arrow-top.js +1 -1
  99. package/dist/esm/node_modules/@coreui/icons/dist/esm/free/cil-arrow-top.js.map +1 -1
  100. package/dist/esm/node_modules/@coreui/icons/dist/esm/free/cil-filter-x.js +1 -1
  101. package/dist/esm/node_modules/@coreui/icons/dist/esm/free/cil-filter-x.js.map +1 -1
  102. package/dist/esm/node_modules/@coreui/icons/dist/esm/free/cil-swap-vertical.js +1 -1
  103. package/dist/esm/node_modules/@coreui/icons/dist/esm/free/cil-swap-vertical.js.map +1 -1
  104. package/dist/esm/node_modules/ua-parser-js/dist/ua-parser.min.js +2 -2
  105. package/dist/esm/node_modules/ua-parser-js/dist/ua-parser.min.js.map +1 -1
  106. package/package.json +7 -5
  107. package/src/components/autocomplete/__tests__/CAutocomplete.spec.tsx +18 -16
  108. package/src/components/autocomplete/__tests__/CAutocompleteOptions.spec.tsx +37 -28
  109. package/src/components/autocomplete/__tests__/__snapshots__/CAutocomplete.spec.tsx.snap +129 -0
  110. package/src/components/autocomplete/__tests__/__snapshots__/CAutocompleteOptions.spec.tsx.snap +36 -0
  111. package/src/components/calendar/CCalendar.tsx +5 -4
  112. package/src/components/calendar/__tests__/CCalendar.spec.tsx +40 -45
  113. package/src/components/calendar/__tests__/__snapshots__/CCalendar.spec.tsx.snap +99 -75
  114. package/src/components/calendar/__tests__/utils.spec.tsx +8 -18
  115. package/src/components/date-picker/CDatePicker.tsx +12 -13
  116. package/src/components/date-picker/__tests__/CDatePicker.spec.tsx +1 -1
  117. package/src/components/date-picker/__tests__/__snapshots__/CDatePicker.spec.tsx.snap +12 -640
  118. package/src/components/date-range-picker/CDateRangePicker.tsx +2 -0
  119. package/src/components/date-range-picker/__tests__/CDateRangePicker.spec.tsx +1 -1
  120. package/src/components/date-range-picker/__tests__/__snapshots__/CDateRangePicker.spec.tsx.snap +21 -1259
  121. package/src/components/dropdown/CDropdown.tsx +1 -1
  122. package/src/components/dropdown/__tests__/CDropdown.spec.tsx +1 -1
  123. package/src/components/dropdown/__tests__/__snapshots__/CDropdown.spec.tsx.snap +2 -2
  124. package/src/components/dropdown/__tests__/__snapshots__/CDropdownMenu.spec.tsx.snap +1 -1
  125. package/src/components/form/__tests__/CFormInput.spec.tsx +17 -20
  126. package/src/components/form/__tests__/__snapshots__/CFormInput.spec.tsx.snap +12 -3
  127. package/src/components/index.ts +1 -0
  128. package/src/components/loading-button/__tests__/CLoadingButton.spec.tsx +1 -1
  129. package/src/components/loading-button/__tests__/__snapshots__/CLoadingButton.spec.tsx.snap +4 -4
  130. package/src/components/multi-select/__tests__/CMultiSelect.spec.tsx +15 -61
  131. package/src/components/multi-select/__tests__/CMultiSelectNativeSelect.spec.tsx +4 -5
  132. package/src/components/multi-select/__tests__/CMultiSelectOptions.spec.tsx +4 -4
  133. package/src/components/multi-select/__tests__/CMultiSelectSelection.spec.tsx +7 -24
  134. package/src/components/multi-select/__tests__/__snapshots__/CMultiSelect.spec.tsx.snap +50 -20
  135. package/src/components/multi-select/__tests__/__snapshots__/CMultiSelectNativeSelect.spec.tsx.snap +0 -2
  136. package/src/components/multi-select/__tests__/__snapshots__/CMultiSelectOptions.spec.tsx.snap +6 -0
  137. package/src/components/multi-select/__tests__/__snapshots__/CMultiSelectSelection.spec.tsx.snap +11 -8
  138. package/src/components/nav/CNavGroup.tsx +11 -6
  139. package/src/components/nav/__tests__/CNavGroup.spec.tsx +29 -1
  140. package/src/components/nav/__tests__/__snapshots__/CNavGroup.spec.tsx.snap +1 -1
  141. package/src/components/offcanvas/__tests__/COffcanvas.spec.tsx +1 -0
  142. package/src/components/one-time-password-input/COneTimePassword.tsx +10 -11
  143. package/src/components/picker/__tests__/CPicker.spec.tsx +1 -1
  144. package/src/components/picker/__tests__/__snapshots__/CPicker.spec.tsx.snap +2 -16
  145. package/src/components/popover/CPopover.tsx +15 -20
  146. package/src/components/popover/__tests__/CPopover.spec.tsx +10 -4
  147. package/src/components/search-button/CSearchButton.tsx +195 -0
  148. package/src/components/search-button/__tests__/CSearchButton.spec.tsx +95 -0
  149. package/src/components/search-button/__tests__/__snapshots__/CSearchButton.spec.tsx.snap +87 -0
  150. package/src/components/search-button/index.ts +3 -0
  151. package/src/components/search-button/types.ts +10 -0
  152. package/src/components/search-button/utils.ts +140 -0
  153. package/src/components/sidebar/CSidebarNav.tsx +27 -2
  154. package/src/components/smart-table/CSmartTable.tsx +5 -4
  155. package/src/components/smart-table/CSmartTableInterface.tsx +2 -2
  156. package/src/components/smart-table/__tests__/CSmartTable.spec.tsx +3 -2
  157. package/src/components/smart-table/__tests__/__snapshots__/CSmartTable.spec.tsx.snap +7 -15
  158. package/src/components/stepper/__tests__/CStepper.spec.tsx +24 -21
  159. package/src/components/stepper/__tests__/__snapshots__/CStepper.spec.tsx.snap +295 -0
  160. package/src/components/tabs/__tests__/CTabContent.spec.tsx +1 -0
  161. package/src/components/tabs/__tests__/CTabPane.spec.tsx +1 -0
  162. package/src/components/time-picker/CTimePicker.tsx +6 -7
  163. package/src/components/time-picker/__tests__/CTimePicker.spec.tsx +10 -1
  164. package/src/components/time-picker/__tests__/__snapshots__/CTimePicker.spec.tsx.snap +599 -315
  165. package/src/components/tooltip/CTooltip.tsx +15 -20
  166. package/src/components/tooltip/__tests__/CTooltip.spec.tsx +6 -0
  167. package/src/components/virtual-scroller/CVirtualScroller.tsx +13 -14
  168. package/src/hooks/useDebouncedCallback.ts +7 -4
  169. package/dist/cjs/components/accordion/CAccordionCollapse.d.ts +0 -3
  170. package/dist/esm/components/accordion/CAccordionCollapse.d.ts +0 -3
  171. package/src/components/accordion/CAccordionCollapse.tsx +0 -20
  172. package/src/components/accordion/__tests__/CAccordionCollapse.spec.tsx +0 -10
  173. package/src/components/accordion/__tests__/__snapshots__/CAccordionCollapse.spec.tsx.snap +0 -11
  174. package/src/components/button/__tests__/__snapshots__/CButtonClose.spec.tsx.snap +0 -26
  175. package/src/components/calendar/__tests__/CCalendar.accessibility.spec.tsx +0 -595
  176. package/src/components/calendar/__tests__/CCalendar.comprehensive.spec.tsx +0 -402
  177. package/src/components/calendar/__tests__/CCalendar.edge-cases.spec.tsx +0 -416
  178. package/src/components/calendar/__tests__/CCalendar.interactions.spec.tsx +0 -593
  179. package/src/components/header/CHeaderBrand.tsx~HEAD +0 -36
  180. /package/src/components/calendar/__tests__/{test-setup.ts → setup.ts} +0 -0
@@ -1,593 +0,0 @@
1
- import * as React from 'react'
2
- import { render, screen, fireEvent, waitFor } from '@testing-library/react'
3
- import userEvent from '@testing-library/user-event'
4
- import '@testing-library/jest-dom'
5
- import { CCalendar } from '../CCalendar'
6
-
7
- describe('CCalendar Interactions', () => {
8
- let user: ReturnType<typeof userEvent.setup>
9
-
10
- beforeEach(() => {
11
- user = userEvent.setup()
12
- jest.clearAllMocks()
13
- })
14
-
15
- describe('Mouse Interactions', () => {
16
- it('handles click on calendar dates', async () => {
17
- const onCalendarDateChange = jest.fn()
18
- render(<CCalendar onCalendarDateChange={onCalendarDateChange} />)
19
-
20
- const calendar = screen.getByRole('application')
21
- expect(calendar).toBeInTheDocument()
22
-
23
- // This would need to be more specific based on actual calendar DOM structure
24
- // For now, we just verify the component renders and can receive clicks
25
- await user.click(calendar)
26
- })
27
-
28
- it('handles double-click events', async () => {
29
- const onCalendarDateChange = jest.fn()
30
- render(<CCalendar onCalendarDateChange={onCalendarDateChange} />)
31
-
32
- const calendar = screen.getByRole('application')
33
- await user.dblClick(calendar)
34
-
35
- expect(calendar).toBeInTheDocument()
36
- })
37
-
38
- it('handles mouse hover for date previews', async () => {
39
- render(<CCalendar />)
40
-
41
- const calendar = screen.getByRole('application')
42
- await user.hover(calendar)
43
-
44
- expect(calendar).toBeInTheDocument()
45
- })
46
-
47
- it('handles right-click context menu', async () => {
48
- const onContextMenu = jest.fn((e) => e.preventDefault())
49
- render(<CCalendar onContextMenu={onContextMenu} />)
50
-
51
- const calendar = screen.getByRole('application')
52
- fireEvent.contextMenu(calendar)
53
-
54
- expect(calendar).toBeInTheDocument()
55
- })
56
-
57
- it('handles mouse drag for range selection', async () => {
58
- render(<CCalendar range />)
59
-
60
- const calendar = screen.getByRole('application')
61
-
62
- // Simulate drag operation
63
- fireEvent.mouseDown(calendar, { clientX: 100, clientY: 100 })
64
- fireEvent.mouseMove(calendar, { clientX: 200, clientY: 100 })
65
- fireEvent.mouseUp(calendar, { clientX: 200, clientY: 100 })
66
-
67
- expect(calendar).toBeInTheDocument()
68
- })
69
- })
70
-
71
- describe('Keyboard Interactions', () => {
72
- it('handles Arrow keys for navigation', async () => {
73
- const onCalendarDateChange = jest.fn()
74
- render(<CCalendar onCalendarDateChange={onCalendarDateChange} />)
75
-
76
- const calendar = screen.getByRole('application')
77
- calendar.focus()
78
-
79
- // Test all arrow keys
80
- await user.keyboard('{ArrowRight}')
81
- await user.keyboard('{ArrowLeft}')
82
- await user.keyboard('{ArrowDown}')
83
- await user.keyboard('{ArrowUp}')
84
-
85
- expect(calendar).toBeInTheDocument()
86
- })
87
-
88
- it('handles Enter key for selection', async () => {
89
- const onCalendarDateChange = jest.fn()
90
- render(<CCalendar onCalendarDateChange={onCalendarDateChange} />)
91
-
92
- const calendar = screen.getByRole('application')
93
- calendar.focus()
94
-
95
- await user.keyboard('{Enter}')
96
-
97
- expect(calendar).toBeInTheDocument()
98
- })
99
-
100
- it('handles Space key for selection', async () => {
101
- const onCalendarDateChange = jest.fn()
102
- render(<CCalendar onCalendarDateChange={onCalendarDateChange} />)
103
-
104
- const calendar = screen.getByRole('application')
105
- calendar.focus()
106
-
107
- await user.keyboard('{Space}')
108
-
109
- expect(calendar).toBeInTheDocument()
110
- })
111
-
112
- it('handles Escape key for cancellation', async () => {
113
- const onEscape = jest.fn()
114
- render(<CCalendar onKeyDown={onEscape} />)
115
-
116
- const calendar = screen.getByRole('application')
117
- calendar.focus()
118
-
119
- await user.keyboard('{Escape}')
120
-
121
- expect(calendar).toBeInTheDocument()
122
- })
123
-
124
- it('handles Tab key for focus management', async () => {
125
- render(
126
- <div>
127
- <button>Before</button>
128
- <CCalendar />
129
- <button>After</button>
130
- </div>
131
- )
132
-
133
- const beforeButton = screen.getByText('Before')
134
- const afterButton = screen.getByText('After')
135
-
136
- beforeButton.focus()
137
-
138
- // Tab to calendar
139
- await user.keyboard('{Tab}')
140
-
141
- // Tab past calendar
142
- await user.keyboard('{Tab}')
143
-
144
- expect(afterButton).toHaveFocus()
145
- })
146
-
147
- it('handles Home/End keys for navigation', async () => {
148
- render(<CCalendar />)
149
-
150
- const calendar = screen.getByRole('application')
151
- calendar.focus()
152
-
153
- await user.keyboard('{Home}')
154
- await user.keyboard('{End}')
155
-
156
- expect(calendar).toBeInTheDocument()
157
- })
158
-
159
- it('handles Page Up/Down for month navigation', async () => {
160
- render(<CCalendar />)
161
-
162
- const calendar = screen.getByRole('application')
163
- calendar.focus()
164
-
165
- await user.keyboard('{PageUp}')
166
- await user.keyboard('{PageDown}')
167
-
168
- expect(calendar).toBeInTheDocument()
169
- })
170
-
171
- it('handles Ctrl+Arrow keys for year navigation', async () => {
172
- render(<CCalendar />)
173
-
174
- const calendar = screen.getByRole('application')
175
- calendar.focus()
176
-
177
- await user.keyboard('{Control>}{ArrowUp}{/Control}')
178
- await user.keyboard('{Control>}{ArrowDown}{/Control}')
179
-
180
- expect(calendar).toBeInTheDocument()
181
- })
182
-
183
- it('handles Shift+Arrow keys for range selection', async () => {
184
- render(<CCalendar range />)
185
-
186
- const calendar = screen.getByRole('application')
187
- calendar.focus()
188
-
189
- await user.keyboard('{Shift>}{ArrowRight}{/Shift}')
190
- await user.keyboard('{Shift>}{ArrowDown}{/Shift}')
191
-
192
- expect(calendar).toBeInTheDocument()
193
- })
194
- })
195
-
196
- describe('Touch Interactions', () => {
197
- it('handles touch tap for selection', () => {
198
- const onCalendarDateChange = jest.fn()
199
- render(<CCalendar onCalendarDateChange={onCalendarDateChange} />)
200
-
201
- const calendar = screen.getByRole('application')
202
-
203
- fireEvent.touchStart(calendar, {
204
- touches: [{ clientX: 100, clientY: 100 }]
205
- })
206
-
207
- fireEvent.touchEnd(calendar, {
208
- changedTouches: [{ clientX: 100, clientY: 100 }]
209
- })
210
-
211
- expect(calendar).toBeInTheDocument()
212
- })
213
-
214
- it('handles touch swipe for navigation', () => {
215
- render(<CCalendar />)
216
-
217
- const calendar = screen.getByRole('application')
218
-
219
- // Swipe left (next month)
220
- fireEvent.touchStart(calendar, {
221
- touches: [{ clientX: 200, clientY: 100 }]
222
- })
223
-
224
- fireEvent.touchMove(calendar, {
225
- touches: [{ clientX: 100, clientY: 100 }]
226
- })
227
-
228
- fireEvent.touchEnd(calendar, {
229
- changedTouches: [{ clientX: 100, clientY: 100 }]
230
- })
231
-
232
- expect(calendar).toBeInTheDocument()
233
- })
234
-
235
- it('handles pinch gestures for zoom', () => {
236
- render(<CCalendar />)
237
-
238
- const calendar = screen.getByRole('application')
239
-
240
- // Simulate pinch gesture
241
- fireEvent.touchStart(calendar, {
242
- touches: [
243
- { clientX: 100, clientY: 100 },
244
- { clientX: 200, clientY: 100 }
245
- ]
246
- })
247
-
248
- fireEvent.touchMove(calendar, {
249
- touches: [
250
- { clientX: 50, clientY: 100 },
251
- { clientX: 250, clientY: 100 }
252
- ]
253
- })
254
-
255
- fireEvent.touchEnd(calendar, {
256
- changedTouches: [
257
- { clientX: 50, clientY: 100 },
258
- { clientX: 250, clientY: 100 }
259
- ]
260
- })
261
-
262
- expect(calendar).toBeInTheDocument()
263
- })
264
-
265
- it('prevents default touch behaviors appropriately', () => {
266
- const preventDefault = jest.fn()
267
-
268
- render(<CCalendar />)
269
-
270
- const calendar = screen.getByRole('application')
271
-
272
- const mockEvent = {
273
- touches: [{ clientX: 100, clientY: 100 }],
274
- preventDefault
275
- }
276
-
277
- fireEvent.touchStart(calendar, mockEvent)
278
-
279
- expect(calendar).toBeInTheDocument()
280
- })
281
- })
282
-
283
- describe('Focus Management', () => {
284
- it('manages focus within calendar', async () => {
285
- render(<CCalendar />)
286
-
287
- const calendar = screen.getByRole('application')
288
-
289
- // Focus should be manageable
290
- calendar.focus()
291
- expect(calendar).toHaveFocus()
292
-
293
- calendar.blur()
294
- expect(calendar).not.toHaveFocus()
295
- })
296
-
297
- it('traps focus within modal calendar', async () => {
298
- render(
299
- <div>
300
- <button>Outside Before</button>
301
- <CCalendar />
302
- <button>Outside After</button>
303
- </div>
304
- )
305
-
306
- const calendar = screen.getByRole('application')
307
- calendar.focus()
308
-
309
- // Tab should stay within calendar (if it's modal)
310
- await user.keyboard('{Tab}')
311
-
312
- expect(screen.getByText('Outside After')).not.toHaveFocus()
313
- })
314
-
315
- it('restores focus after date selection', async () => {
316
- const onCalendarDateChange = jest.fn()
317
- render(<CCalendar onCalendarDateChange={onCalendarDateChange} />)
318
-
319
- const calendar = screen.getByRole('application')
320
- calendar.focus()
321
-
322
- await user.keyboard('{Enter}')
323
-
324
- // Focus should remain on calendar or appropriate element
325
- expect(document.activeElement).toBeDefined()
326
- })
327
-
328
- it('handles focus with disabled dates', async () => {
329
- const disabledDate = new Date(2022, 1, 16)
330
- render(<CCalendar disabledDate={[disabledDate]} />)
331
-
332
- const calendar = screen.getByRole('application')
333
- calendar.focus()
334
-
335
- // Navigation should skip disabled dates
336
- await user.keyboard('{ArrowRight}')
337
-
338
- expect(calendar).toBeInTheDocument()
339
- })
340
- })
341
-
342
- describe('Navigation Controls', () => {
343
- it('handles navigation button clicks', async () => {
344
- const onViewChange = jest.fn()
345
- render(<CCalendar navigation onViewChange={onViewChange} />)
346
-
347
- const calendar = screen.getByRole('application')
348
- expect(calendar).toBeInTheDocument()
349
-
350
- // This would need specific selectors for navigation buttons
351
- // For now, we verify the component renders with navigation
352
- })
353
-
354
- it('handles month/year selector changes', async () => {
355
- const onCalendarDateChange = jest.fn()
356
- render(<CCalendar navigation onCalendarDateChange={onCalendarDateChange} />)
357
-
358
- const calendar = screen.getByRole('application')
359
- expect(calendar).toBeInTheDocument()
360
-
361
- // This would interact with month/year dropdowns if they exist
362
- })
363
-
364
- it('handles view type switching', async () => {
365
- const onViewChange = jest.fn()
366
- render(<CCalendar onViewChange={onViewChange} />)
367
-
368
- const calendar = screen.getByRole('application')
369
-
370
- // Test clicking on month/year headers to switch views
371
- // Implementation depends on actual DOM structure
372
- expect(calendar).toBeInTheDocument()
373
- })
374
- })
375
-
376
- describe('Range Selection Interactions', () => {
377
- it('handles range selection with mouse', async () => {
378
- const onStartDateChange = jest.fn()
379
- const onEndDateChange = jest.fn()
380
-
381
- render(
382
- <CCalendar
383
- range
384
- onStartDateChange={onStartDateChange}
385
- onEndDateChange={onEndDateChange}
386
- />
387
- )
388
-
389
- const calendar = screen.getByRole('application')
390
-
391
- // Click to start range
392
- await user.click(calendar)
393
-
394
- // Click to end range (would need specific date cells)
395
- await user.click(calendar)
396
-
397
- expect(calendar).toBeInTheDocument()
398
- })
399
-
400
- it('handles range selection with keyboard', async () => {
401
- const onStartDateChange = jest.fn()
402
- const onEndDateChange = jest.fn()
403
-
404
- render(
405
- <CCalendar
406
- range
407
- onStartDateChange={onStartDateChange}
408
- onEndDateChange={onEndDateChange}
409
- />
410
- )
411
-
412
- const calendar = screen.getByRole('application')
413
- calendar.focus()
414
-
415
- // Start range with Enter
416
- await user.keyboard('{Enter}')
417
-
418
- // Navigate and end range
419
- await user.keyboard('{ArrowRight}{ArrowRight}{ArrowRight}')
420
- await user.keyboard('{Enter}')
421
-
422
- expect(calendar).toBeInTheDocument()
423
- })
424
-
425
- it('handles range selection cancellation', async () => {
426
- render(<CCalendar range />)
427
-
428
- const calendar = screen.getByRole('application')
429
- calendar.focus()
430
-
431
- // Start range
432
- await user.keyboard('{Enter}')
433
-
434
- // Cancel with Escape
435
- await user.keyboard('{Escape}')
436
-
437
- expect(calendar).toBeInTheDocument()
438
- })
439
- })
440
-
441
- describe('Callback Behavior', () => {
442
- it('calls callbacks with correct parameters', async () => {
443
- const onCalendarDateChange = jest.fn()
444
- const onStartDateChange = jest.fn()
445
- const onEndDateChange = jest.fn()
446
- const onViewChange = jest.fn()
447
-
448
- render(
449
- <CCalendar
450
- range
451
- onCalendarDateChange={onCalendarDateChange}
452
- onStartDateChange={onStartDateChange}
453
- onEndDateChange={onEndDateChange}
454
- onViewChange={onViewChange}
455
- />
456
- )
457
-
458
- const calendar = screen.getByRole('application')
459
-
460
- // Test interactions that should trigger callbacks
461
- await user.click(calendar)
462
-
463
- expect(calendar).toBeInTheDocument()
464
- })
465
-
466
- it('handles callback errors gracefully', async () => {
467
- const errorCallback = jest.fn(() => {
468
- throw new Error('Callback error')
469
- })
470
-
471
- // Component should not crash due to callback errors
472
- render(<CCalendar onCalendarDateChange={errorCallback} />)
473
-
474
- const calendar = screen.getByRole('application')
475
-
476
- // This should not throw
477
- await user.click(calendar)
478
-
479
- expect(calendar).toBeInTheDocument()
480
- })
481
-
482
- it('calls callbacks in correct order', async () => {
483
- const callOrder: string[] = []
484
-
485
- const onCalendarDateChange = jest.fn(() => callOrder.push('calendarDate'))
486
- const onViewChange = jest.fn(() => callOrder.push('view'))
487
-
488
- render(
489
- <CCalendar
490
- onCalendarDateChange={onCalendarDateChange}
491
- onViewChange={onViewChange}
492
- />
493
- )
494
-
495
- const calendar = screen.getByRole('application')
496
-
497
- // Perform actions that trigger multiple callbacks
498
- await user.click(calendar)
499
-
500
- expect(calendar).toBeInTheDocument()
501
- // Verify order if callbacks were called
502
- })
503
-
504
- it('prevents callback loops', async () => {
505
- const onCalendarDateChange = jest.fn((date) => {
506
- // Callback that might cause infinite loop
507
- if (date) {
508
- // This should not cause the component to re-trigger the callback
509
- }
510
- })
511
-
512
- render(<CCalendar onCalendarDateChange={onCalendarDateChange} />)
513
-
514
- const calendar = screen.getByRole('application')
515
- await user.click(calendar)
516
-
517
- expect(calendar).toBeInTheDocument()
518
-
519
- // Ensure callback wasn't called excessively
520
- await waitFor(() => {
521
- expect(onCalendarDateChange.mock.calls.length).toBeLessThan(10)
522
- })
523
- })
524
- })
525
-
526
- describe('Dynamic Content Updates', () => {
527
- it('handles dynamic disabled date updates', async () => {
528
- const TestComponent = () => {
529
- const [disabledDates, setDisabledDates] = React.useState<Date[]>([])
530
-
531
- React.useEffect(() => {
532
- setTimeout(() => {
533
- setDisabledDates([new Date(2022, 1, 16)])
534
- }, 100)
535
- }, [])
536
-
537
- return <CCalendar disabledDate={disabledDates} />
538
- }
539
-
540
- render(<TestComponent />)
541
-
542
- const calendar = screen.getByRole('application')
543
-
544
- await waitFor(() => {
545
- expect(calendar).toBeInTheDocument()
546
- })
547
- })
548
-
549
- it('handles dynamic min/max date updates', async () => {
550
- const TestComponent = () => {
551
- const [minDate, setMinDate] = React.useState<Date | null>(null)
552
-
553
- React.useEffect(() => {
554
- setTimeout(() => {
555
- setMinDate(new Date(2022, 0, 1))
556
- }, 100)
557
- }, [])
558
-
559
- return <CCalendar minDate={minDate} />
560
- }
561
-
562
- render(<TestComponent />)
563
-
564
- const calendar = screen.getByRole('application')
565
-
566
- await waitFor(() => {
567
- expect(calendar).toBeInTheDocument()
568
- })
569
- })
570
-
571
- it('handles dynamic locale changes', async () => {
572
- const TestComponent = () => {
573
- const [locale, setLocale] = React.useState('en-US')
574
-
575
- React.useEffect(() => {
576
- setTimeout(() => {
577
- setLocale('pl-PL')
578
- }, 100)
579
- }, [])
580
-
581
- return <CCalendar locale={locale} />
582
- }
583
-
584
- render(<TestComponent />)
585
-
586
- const calendar = screen.getByRole('application')
587
-
588
- await waitFor(() => {
589
- expect(calendar).toBeInTheDocument()
590
- })
591
- })
592
- })
593
- })
@@ -1,36 +0,0 @@
1
- import React, { ElementType, forwardRef, AnchorHTMLAttributes } from 'react'
2
- import PropTypes from 'prop-types'
3
- import classNames from 'classnames'
4
-
5
- import { PolymorphicRefForwardingComponent } from '../../helpers'
6
-
7
- export interface CHeaderBrandProps
8
- extends AnchorHTMLAttributes<HTMLAnchorElement | HTMLSpanElement> {
9
- /**
10
- * Component used for the root node. Either a string to use a HTML element or a component.
11
- */
12
- as?: ElementType
13
- /**
14
- * A string of all className you want applied to the component.
15
- */
16
- className?: string
17
- }
18
-
19
- export const CHeaderBrand: PolymorphicRefForwardingComponent<'a', CHeaderBrandProps> = forwardRef<
20
- HTMLAnchorElement | HTMLSpanElement,
21
- CHeaderBrandProps
22
- >(({ children, as: Component = 'a', className, ...rest }, ref) => {
23
- return (
24
- <Component className={classNames('header-brand', className)} {...rest} ref={ref}>
25
- {children}
26
- </Component>
27
- )
28
- })
29
-
30
- CHeaderBrand.propTypes = {
31
- as: PropTypes.elementType,
32
- children: PropTypes.node,
33
- className: PropTypes.string,
34
- }
35
-
36
- CHeaderBrand.displayName = 'CHeaderBrand'