shadcn-rails 0.1.0 → 0.2.1

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 (169) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +69 -2
  3. data/README.md +102 -1398
  4. data/__mocks__/@floating-ui/dom.js +67 -0
  5. data/app/assets/javascripts/shadcn/controllers/base_menu_controller.js +266 -0
  6. data/app/assets/javascripts/shadcn/controllers/combobox_controller.js +34 -8
  7. data/app/assets/javascripts/shadcn/controllers/command_controller.js +5 -1
  8. data/app/assets/javascripts/shadcn/controllers/context_menu_controller.js +64 -135
  9. data/app/assets/javascripts/shadcn/controllers/dropdown_controller.js +56 -186
  10. data/app/assets/javascripts/shadcn/controllers/hover_card_controller.js +29 -55
  11. data/app/assets/javascripts/shadcn/controllers/menubar_controller.js +10 -7
  12. data/app/assets/javascripts/shadcn/controllers/navigation_menu_controller.js +10 -6
  13. data/app/assets/javascripts/shadcn/controllers/popover_controller.js +35 -60
  14. data/app/assets/javascripts/shadcn/controllers/select_controller.js +37 -17
  15. data/app/assets/javascripts/shadcn/controllers/sidebar_controller.js +24 -14
  16. data/app/assets/javascripts/shadcn/controllers/tooltip_controller.js +28 -59
  17. data/app/assets/javascripts/shadcn/index.js +9 -1
  18. data/app/assets/javascripts/shadcn/utils/floating.js +179 -0
  19. data/app/assets/stylesheets/shadcn/base.css +32 -0
  20. data/app/assets/stylesheets/shadcn/components.css +12 -0
  21. data/app/components/shadcn/accordion_component.html.erb +8 -0
  22. data/app/components/shadcn/accordion_component.rb +6 -15
  23. data/app/components/shadcn/alert_component.html.erb +6 -0
  24. data/app/components/shadcn/alert_component.rb +0 -18
  25. data/app/components/shadcn/alert_dialog_component.html.erb +12 -0
  26. data/app/components/shadcn/alert_dialog_component.rb +7 -27
  27. data/app/components/shadcn/aspect_ratio_component.html.erb +7 -0
  28. data/app/components/shadcn/aspect_ratio_component.rb +4 -19
  29. data/app/components/shadcn/avatar_component.html.erb +20 -0
  30. data/app/components/shadcn/avatar_component.rb +8 -36
  31. data/app/components/shadcn/badge_component.html.erb +1 -0
  32. data/app/components/shadcn/badge_component.rb +0 -11
  33. data/app/components/shadcn/base_component.rb +15 -2
  34. data/app/components/shadcn/breadcrumb_component.html.erb +5 -0
  35. data/app/components/shadcn/breadcrumb_component.rb +6 -16
  36. data/app/components/shadcn/button_component.html.erb +18 -0
  37. data/app/components/shadcn/button_component.rb +1 -41
  38. data/app/components/shadcn/card_component.html.erb +8 -0
  39. data/app/components/shadcn/card_component.rb +2 -6
  40. data/app/components/shadcn/checkbox_component.html.erb +32 -0
  41. data/app/components/shadcn/checkbox_component.rb +4 -43
  42. data/app/components/shadcn/collapsible_component.html.erb +8 -0
  43. data/app/components/shadcn/collapsible_component.rb +6 -15
  44. data/app/components/shadcn/command_list_component.rb +29 -14
  45. data/app/components/shadcn/context_menu_checkbox_item_component.rb +76 -0
  46. data/app/components/shadcn/context_menu_component.html.erb +11 -0
  47. data/app/components/shadcn/context_menu_component.rb +6 -26
  48. data/app/components/shadcn/context_menu_content_component.rb +37 -14
  49. data/app/components/shadcn/context_menu_item_component.rb +3 -2
  50. data/app/components/shadcn/context_menu_radio_group_component.rb +42 -0
  51. data/app/components/shadcn/context_menu_radio_item_component.rb +76 -0
  52. data/app/components/shadcn/dialog_component.html.erb +14 -0
  53. data/app/components/shadcn/dialog_component.rb +8 -29
  54. data/app/components/shadcn/drawer_component.html.erb +12 -0
  55. data/app/components/shadcn/drawer_component.rb +7 -27
  56. data/app/components/shadcn/dropdown_menu_checkbox_item_component.rb +76 -0
  57. data/app/components/shadcn/dropdown_menu_component.html.erb +14 -0
  58. data/app/components/shadcn/dropdown_menu_component.rb +9 -29
  59. data/app/components/shadcn/dropdown_menu_content_component.rb +45 -16
  60. data/app/components/shadcn/dropdown_menu_radio_group_component.rb +42 -0
  61. data/app/components/shadcn/dropdown_menu_radio_item_component.rb +76 -0
  62. data/app/components/shadcn/field_component.rb +7 -8
  63. data/app/components/shadcn/hover_card_component.html.erb +12 -0
  64. data/app/components/shadcn/hover_card_component.rb +7 -26
  65. data/app/components/shadcn/input_component.html.erb +18 -0
  66. data/app/components/shadcn/input_component.rb +2 -27
  67. data/app/components/shadcn/input_otp_component.rb +3 -3
  68. data/app/components/shadcn/kbd_component.html.erb +1 -0
  69. data/app/components/shadcn/kbd_component.rb +3 -10
  70. data/app/components/shadcn/label_component.html.erb +3 -0
  71. data/app/components/shadcn/label_component.rb +2 -18
  72. data/app/components/shadcn/menubar_component.html.erb +6 -0
  73. data/app/components/shadcn/menubar_component.rb +4 -15
  74. data/app/components/shadcn/menubar_content_component.rb +45 -20
  75. data/app/components/shadcn/menubar_sub_content_component.rb +21 -8
  76. data/app/components/shadcn/native_select_component.html.erb +22 -0
  77. data/app/components/shadcn/native_select_component.rb +9 -39
  78. data/app/components/shadcn/navigation_menu_component.html.erb +6 -0
  79. data/app/components/shadcn/navigation_menu_component.rb +4 -15
  80. data/app/components/shadcn/pagination_component.html.erb +5 -0
  81. data/app/components/shadcn/pagination_component.rb +11 -15
  82. data/app/components/shadcn/popover_component.html.erb +15 -0
  83. data/app/components/shadcn/popover_component.rb +10 -30
  84. data/app/components/shadcn/progress_component.html.erb +13 -0
  85. data/app/components/shadcn/progress_component.rb +6 -26
  86. data/app/components/shadcn/radio_group_component.html.erb +8 -0
  87. data/app/components/shadcn/radio_group_component.rb +12 -26
  88. data/app/components/shadcn/radio_group_item_component.rb +32 -6
  89. data/app/components/shadcn/resizable_panel_group_component.rb +27 -16
  90. data/app/components/shadcn/scroll_area_component.html.erb +7 -0
  91. data/app/components/shadcn/scroll_area_component.rb +4 -16
  92. data/app/components/shadcn/select_component.html.erb +46 -0
  93. data/app/components/shadcn/select_component.rb +29 -86
  94. data/app/components/shadcn/separator_component.html.erb +5 -0
  95. data/app/components/shadcn/separator_component.rb +6 -14
  96. data/app/components/shadcn/sheet_component.html.erb +12 -0
  97. data/app/components/shadcn/sheet_component.rb +7 -27
  98. data/app/components/shadcn/sidebar_component.rb +2 -2
  99. data/app/components/shadcn/skeleton_component.html.erb +1 -0
  100. data/app/components/shadcn/skeleton_component.rb +4 -2
  101. data/app/components/shadcn/slider_component.html.erb +12 -0
  102. data/app/components/shadcn/slider_component.rb +2 -21
  103. data/app/components/shadcn/spinner_component.html.erb +18 -0
  104. data/app/components/shadcn/spinner_component.rb +2 -30
  105. data/app/components/shadcn/switch_component.html.erb +72 -0
  106. data/app/components/shadcn/switch_component.rb +4 -82
  107. data/app/components/shadcn/table_component.html.erb +9 -0
  108. data/app/components/shadcn/table_component.rb +2 -10
  109. data/app/components/shadcn/tabs_component.html.erb +8 -0
  110. data/app/components/shadcn/tabs_component.rb +4 -17
  111. data/app/components/shadcn/textarea_component.html.erb +13 -0
  112. data/app/components/shadcn/textarea_component.rb +6 -22
  113. data/app/components/shadcn/toast_component.html.erb +36 -0
  114. data/app/components/shadcn/toast_component.rb +6 -54
  115. data/app/components/shadcn/toggle_component.html.erb +12 -0
  116. data/app/components/shadcn/toggle_component.rb +6 -21
  117. data/app/components/shadcn/toggle_group_component.html.erb +14 -0
  118. data/app/components/shadcn/toggle_group_component.rb +6 -29
  119. data/app/components/shadcn/tooltip_component.html.erb +20 -0
  120. data/app/components/shadcn/tooltip_component.rb +13 -38
  121. data/lib/generators/shadcn/add/USAGE +24 -0
  122. data/lib/generators/shadcn/add/add_generator.rb +279 -0
  123. data/lib/generators/shadcn/install/USAGE +22 -0
  124. data/lib/generators/shadcn/install/install_generator.rb +8 -3
  125. data/lib/generators/shadcn/install/templates/initializer.rb.tt +7 -27
  126. data/lib/generators/shadcn/install/templates/shadcn.yml.tt +15 -31
  127. data/lib/shadcn/rails/version.rb +1 -1
  128. metadata +54 -42
  129. data/.dockerignore +0 -40
  130. data/CLAUDE.md +0 -463
  131. data/PROGRESS.md +0 -485
  132. data/Rakefile +0 -29
  133. data/__tests__/controllers/__snapshots__/calendar_controller.test.js.snap +0 -13
  134. data/__tests__/controllers/__snapshots__/popover_controller.test.js.snap +0 -46
  135. data/__tests__/controllers/__snapshots__/sheet_controller.test.js.snap +0 -111
  136. data/__tests__/controllers/__snapshots__/tabs_controller.test.js.snap +0 -27
  137. data/__tests__/controllers/accordion_controller.test.js +0 -904
  138. data/__tests__/controllers/calendar_controller.test.js +0 -1370
  139. data/__tests__/controllers/carousel_controller.test.js +0 -912
  140. data/__tests__/controllers/checkbox_controller.test.js +0 -454
  141. data/__tests__/controllers/collapsible_controller.test.js +0 -407
  142. data/__tests__/controllers/combobox_controller.test.js +0 -966
  143. data/__tests__/controllers/context_menu_controller.test.js +0 -627
  144. data/__tests__/controllers/date_picker_controller.test.js +0 -636
  145. data/__tests__/controllers/dialog_controller.test.js +0 -878
  146. data/__tests__/controllers/drawer_controller.test.js +0 -995
  147. data/__tests__/controllers/menubar_controller.test.js +0 -736
  148. data/__tests__/controllers/navigation_menu_controller.test.js +0 -598
  149. data/__tests__/controllers/popover_controller.test.js +0 -1007
  150. data/__tests__/controllers/radio_group_controller.test.js +0 -640
  151. data/__tests__/controllers/resizable_controller.test.js +0 -680
  152. data/__tests__/controllers/select_controller.test.js +0 -674
  153. data/__tests__/controllers/sheet_controller.test.js +0 -986
  154. data/__tests__/controllers/slider_controller.test.js +0 -1036
  155. data/__tests__/controllers/switch_controller.test.js +0 -424
  156. data/__tests__/controllers/tabs_controller.test.js +0 -907
  157. data/__tests__/controllers/toggle_group_controller.test.js +0 -839
  158. data/__tests__/controllers/tooltip_controller.test.js +0 -808
  159. data/__tests__/helpers/stimulus-test-helper.js +0 -203
  160. data/babel.config.cjs +0 -5
  161. data/bin/console +0 -11
  162. data/bin/setup +0 -8
  163. data/jest.config.js +0 -19
  164. data/jest.setup.js +0 -8
  165. data/lib/generators/shadcn/component/component_generator.rb +0 -188
  166. data/lib/generators/shadcn/theme/theme_generator.rb +0 -128
  167. data/package-lock.json +0 -7415
  168. data/package.json +0 -68
  169. data/rollup.config.js +0 -29
@@ -1,424 +0,0 @@
1
- import { Application } from "@hotwired/stimulus"
2
- import SwitchController from "../../app/assets/javascripts/shadcn/controllers/switch_controller.js"
3
- import { setupController, cleanupController, click, nextFrame, keydown } from '../helpers/stimulus-test-helper.js'
4
-
5
- describe("SwitchController", () => {
6
- let application
7
- let element
8
- let controller
9
-
10
- afterEach(() => {
11
- cleanupController(application)
12
- })
13
-
14
- describe("basic rendering and initialization", () => {
15
- const basicHTML = `
16
- <div data-controller="shadcn--switch"
17
- data-shadcn--switch-checked-value="false">
18
- <button data-shadcn--switch-target="button"
19
- type="button"
20
- role="switch"
21
- aria-checked="false"
22
- data-action="click->shadcn--switch#toggle keydown->shadcn--switch#handleKeydown">
23
- <span data-shadcn--switch-target="thumb"></span>
24
- </button>
25
- <input type="checkbox"
26
- data-shadcn--switch-target="input"
27
- name="notifications"
28
- hidden>
29
- </div>
30
- `
31
-
32
- beforeEach(async () => {
33
- const setup = await setupController(SwitchController, basicHTML, 'shadcn--switch')
34
- application = setup.application
35
- element = setup.element
36
- controller = setup.controller
37
- })
38
-
39
- test("initializes with unchecked state", () => {
40
- expect(controller.checkedValue).toBe(false)
41
- })
42
-
43
- test("sets data-state on element", () => {
44
- expect(element.dataset.state).toBe("unchecked")
45
- })
46
-
47
- test("sets data-state on button", () => {
48
- expect(controller.buttonTarget.dataset.state).toBe("unchecked")
49
- })
50
-
51
- test("sets aria-checked on button", () => {
52
- expect(controller.buttonTarget.getAttribute("aria-checked")).toBe("false")
53
- })
54
-
55
- test("sets data-state on thumb", () => {
56
- expect(controller.thumbTarget.dataset.state).toBe("unchecked")
57
- })
58
- })
59
-
60
- describe("toggle functionality", () => {
61
- const toggleHTML = `
62
- <div data-controller="shadcn--switch"
63
- data-shadcn--switch-checked-value="false">
64
- <button data-shadcn--switch-target="button"
65
- type="button"
66
- role="switch"
67
- data-action="click->shadcn--switch#toggle">
68
- <span data-shadcn--switch-target="thumb"></span>
69
- </button>
70
- <input type="checkbox"
71
- data-shadcn--switch-target="input"
72
- name="enabled"
73
- hidden>
74
- </div>
75
- `
76
-
77
- beforeEach(async () => {
78
- const setup = await setupController(SwitchController, toggleHTML, 'shadcn--switch')
79
- application = setup.application
80
- element = setup.element
81
- controller = setup.controller
82
- })
83
-
84
- test("toggles from unchecked to checked", async () => {
85
- controller.toggle()
86
- await nextFrame()
87
-
88
- expect(controller.checkedValue).toBe(true)
89
- })
90
-
91
- test("toggles from checked to unchecked", async () => {
92
- controller.checkedValue = true
93
- controller.toggle()
94
- await nextFrame()
95
-
96
- expect(controller.checkedValue).toBe(false)
97
- })
98
-
99
- test("updates data-state on toggle to checked", async () => {
100
- controller.toggle()
101
- await nextFrame()
102
-
103
- expect(element.dataset.state).toBe("checked")
104
- expect(controller.buttonTarget.dataset.state).toBe("checked")
105
- expect(controller.thumbTarget.dataset.state).toBe("checked")
106
- })
107
-
108
- test("updates aria-checked on toggle", async () => {
109
- controller.toggle()
110
- await nextFrame()
111
-
112
- expect(controller.buttonTarget.getAttribute("aria-checked")).toBe("true")
113
- })
114
-
115
- test("dispatches change event on toggle", async () => {
116
- let eventDetail = null
117
- element.addEventListener("shadcn--switch:change", (e) => {
118
- eventDetail = e.detail
119
- })
120
-
121
- controller.toggle()
122
- await nextFrame()
123
-
124
- expect(eventDetail).not.toBeNull()
125
- expect(eventDetail.checked).toBe(true)
126
- })
127
-
128
- test("dispatches change event with false when toggling off", async () => {
129
- controller.checkedValue = true
130
- let eventDetail = null
131
- element.addEventListener("shadcn--switch:change", (e) => {
132
- eventDetail = e.detail
133
- })
134
-
135
- controller.toggle()
136
- await nextFrame()
137
-
138
- expect(eventDetail.checked).toBe(false)
139
- })
140
- })
141
-
142
- describe("hidden input synchronization", () => {
143
- const inputSyncHTML = `
144
- <div data-controller="shadcn--switch"
145
- data-shadcn--switch-checked-value="false">
146
- <button data-shadcn--switch-target="button"
147
- data-action="click->shadcn--switch#toggle">
148
- <span data-shadcn--switch-target="thumb"></span>
149
- </button>
150
- <input type="checkbox"
151
- data-shadcn--switch-target="input"
152
- name="feature_flag"
153
- hidden>
154
- </div>
155
- `
156
-
157
- beforeEach(async () => {
158
- const setup = await setupController(SwitchController, inputSyncHTML, 'shadcn--switch')
159
- application = setup.application
160
- element = setup.element
161
- controller = setup.controller
162
- })
163
-
164
- test("syncs hidden input checked state", async () => {
165
- controller.toggle()
166
- await nextFrame()
167
-
168
- expect(controller.inputTarget.checked).toBe(true)
169
- })
170
-
171
- test("unchecks hidden input when toggled off", async () => {
172
- controller.checkedValue = true
173
- controller.syncInput()
174
- expect(controller.inputTarget.checked).toBe(true)
175
-
176
- controller.toggle()
177
- await nextFrame()
178
-
179
- expect(controller.inputTarget.checked).toBe(false)
180
- })
181
-
182
- test("dispatches native change event on input", async () => {
183
- let nativeChangeEvent = false
184
- controller.inputTarget.addEventListener("change", () => {
185
- nativeChangeEvent = true
186
- })
187
-
188
- controller.toggle()
189
- await nextFrame()
190
-
191
- expect(nativeChangeEvent).toBe(true)
192
- })
193
- })
194
-
195
- describe("keyboard navigation", () => {
196
- const keyboardHTML = `
197
- <div data-controller="shadcn--switch"
198
- data-shadcn--switch-checked-value="false">
199
- <button data-shadcn--switch-target="button"
200
- data-action="click->shadcn--switch#toggle keydown->shadcn--switch#handleKeydown">
201
- <span data-shadcn--switch-target="thumb"></span>
202
- </button>
203
- <input type="checkbox" data-shadcn--switch-target="input" hidden>
204
- </div>
205
- `
206
-
207
- beforeEach(async () => {
208
- const setup = await setupController(SwitchController, keyboardHTML, 'shadcn--switch')
209
- application = setup.application
210
- element = setup.element
211
- controller = setup.controller
212
- })
213
-
214
- test("toggles on Space key", async () => {
215
- controller.handleKeydown({ key: " ", preventDefault: jest.fn() })
216
- await nextFrame()
217
-
218
- expect(controller.checkedValue).toBe(true)
219
- })
220
-
221
- test("toggles on Enter key", async () => {
222
- controller.handleKeydown({ key: "Enter", preventDefault: jest.fn() })
223
- await nextFrame()
224
-
225
- expect(controller.checkedValue).toBe(true)
226
- })
227
-
228
- test("prevents default on Space", () => {
229
- const preventDefault = jest.fn()
230
- controller.handleKeydown({ key: " ", preventDefault })
231
-
232
- expect(preventDefault).toHaveBeenCalled()
233
- })
234
-
235
- test("prevents default on Enter", () => {
236
- const preventDefault = jest.fn()
237
- controller.handleKeydown({ key: "Enter", preventDefault })
238
-
239
- expect(preventDefault).toHaveBeenCalled()
240
- })
241
-
242
- test("ignores other keys", () => {
243
- const preventDefault = jest.fn()
244
- controller.handleKeydown({ key: "Tab", preventDefault })
245
-
246
- expect(preventDefault).not.toHaveBeenCalled()
247
- expect(controller.checkedValue).toBe(false)
248
- })
249
- })
250
-
251
- describe("disabled state", () => {
252
- const disabledHTML = `
253
- <div data-controller="shadcn--switch"
254
- data-shadcn--switch-checked-value="false">
255
- <button data-shadcn--switch-target="button"
256
- disabled
257
- data-action="click->shadcn--switch#toggle">
258
- <span data-shadcn--switch-target="thumb"></span>
259
- </button>
260
- <input type="checkbox" data-shadcn--switch-target="input" hidden>
261
- </div>
262
- `
263
-
264
- beforeEach(async () => {
265
- const setup = await setupController(SwitchController, disabledHTML, 'shadcn--switch')
266
- application = setup.application
267
- element = setup.element
268
- controller = setup.controller
269
- })
270
-
271
- test("does not toggle when disabled", async () => {
272
- controller.toggle()
273
- await nextFrame()
274
-
275
- expect(controller.checkedValue).toBe(false)
276
- })
277
- })
278
-
279
- describe("initial checked state", () => {
280
- const checkedHTML = `
281
- <div data-controller="shadcn--switch"
282
- data-shadcn--switch-checked-value="true">
283
- <button data-shadcn--switch-target="button"
284
- role="switch"
285
- aria-checked="true"
286
- data-action="click->shadcn--switch#toggle">
287
- <span data-shadcn--switch-target="thumb"></span>
288
- </button>
289
- <input type="checkbox" data-shadcn--switch-target="input" checked hidden>
290
- </div>
291
- `
292
-
293
- beforeEach(async () => {
294
- const setup = await setupController(SwitchController, checkedHTML, 'shadcn--switch')
295
- application = setup.application
296
- element = setup.element
297
- controller = setup.controller
298
- })
299
-
300
- test("initializes with checked state", () => {
301
- expect(controller.checkedValue).toBe(true)
302
- })
303
-
304
- test("sets checked data-state on init", () => {
305
- expect(element.dataset.state).toBe("checked")
306
- })
307
-
308
- test("sets aria-checked true on init", () => {
309
- expect(controller.buttonTarget.getAttribute("aria-checked")).toBe("true")
310
- })
311
- })
312
-
313
- describe("programmatic value change", () => {
314
- const programmaticHTML = `
315
- <div data-controller="shadcn--switch"
316
- data-shadcn--switch-checked-value="false">
317
- <button data-shadcn--switch-target="button">
318
- <span data-shadcn--switch-target="thumb"></span>
319
- </button>
320
- <input type="checkbox" data-shadcn--switch-target="input" hidden>
321
- </div>
322
- `
323
-
324
- beforeEach(async () => {
325
- const setup = await setupController(SwitchController, programmaticHTML, 'shadcn--switch')
326
- application = setup.application
327
- element = setup.element
328
- controller = setup.controller
329
- })
330
-
331
- test("updates UI when checkedValue changes", async () => {
332
- controller.checkedValue = true
333
- await nextFrame()
334
-
335
- expect(element.dataset.state).toBe("checked")
336
- expect(controller.buttonTarget.getAttribute("aria-checked")).toBe("true")
337
- })
338
-
339
- test("syncs input when checkedValue changes", async () => {
340
- controller.checkedValue = true
341
- await nextFrame()
342
-
343
- expect(controller.inputTarget.checked).toBe(true)
344
- })
345
- })
346
-
347
- describe("multiple toggles", () => {
348
- const multipleToggleHTML = `
349
- <div data-controller="shadcn--switch"
350
- data-shadcn--switch-checked-value="false">
351
- <button data-shadcn--switch-target="button"
352
- data-action="click->shadcn--switch#toggle">
353
- <span data-shadcn--switch-target="thumb"></span>
354
- </button>
355
- <input type="checkbox" data-shadcn--switch-target="input" hidden>
356
- </div>
357
- `
358
-
359
- beforeEach(async () => {
360
- const setup = await setupController(SwitchController, multipleToggleHTML, 'shadcn--switch')
361
- application = setup.application
362
- element = setup.element
363
- controller = setup.controller
364
- })
365
-
366
- test("handles rapid toggles correctly", async () => {
367
- controller.toggle() // true
368
- controller.toggle() // false
369
- controller.toggle() // true
370
- await nextFrame()
371
-
372
- expect(controller.checkedValue).toBe(true)
373
- })
374
-
375
- test("maintains state consistency through multiple toggles", async () => {
376
- let changeCount = 0
377
- element.addEventListener("shadcn--switch:change", () => {
378
- changeCount++
379
- })
380
-
381
- controller.toggle()
382
- controller.toggle()
383
- controller.toggle()
384
- controller.toggle()
385
- await nextFrame()
386
-
387
- expect(changeCount).toBe(4)
388
- expect(controller.checkedValue).toBe(false)
389
- })
390
- })
391
-
392
- describe("without optional targets", () => {
393
- const minimalHTML = `
394
- <div data-controller="shadcn--switch"
395
- data-shadcn--switch-checked-value="false">
396
- <button data-shadcn--switch-target="button"
397
- data-action="click->shadcn--switch#toggle">Toggle</button>
398
- </div>
399
- `
400
-
401
- beforeEach(async () => {
402
- const setup = await setupController(SwitchController, minimalHTML, 'shadcn--switch')
403
- application = setup.application
404
- element = setup.element
405
- controller = setup.controller
406
- })
407
-
408
- test("works without thumb target", async () => {
409
- expect(() => {
410
- controller.toggle()
411
- }).not.toThrow()
412
-
413
- expect(controller.checkedValue).toBe(true)
414
- })
415
-
416
- test("works without input target", async () => {
417
- expect(() => {
418
- controller.toggle()
419
- }).not.toThrow()
420
-
421
- expect(controller.checkedValue).toBe(true)
422
- })
423
- })
424
- })