shadcn-rails 0.2.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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +66 -2
- data/README.md +21 -8
- data/__mocks__/@floating-ui/dom.js +67 -0
- data/app/assets/javascripts/shadcn/controllers/combobox_controller.js +23 -2
- data/app/assets/javascripts/shadcn/controllers/context_menu_controller.js +4 -31
- data/app/assets/javascripts/shadcn/controllers/dropdown_controller.js +32 -41
- data/app/assets/javascripts/shadcn/controllers/hover_card_controller.js +29 -55
- data/app/assets/javascripts/shadcn/controllers/popover_controller.js +29 -54
- data/app/assets/javascripts/shadcn/controllers/select_controller.js +26 -8
- data/app/assets/javascripts/shadcn/controllers/tooltip_controller.js +28 -59
- data/app/assets/javascripts/shadcn/index.js +7 -1
- data/app/assets/javascripts/shadcn/utils/floating.js +179 -0
- data/app/assets/stylesheets/shadcn/base.css +32 -0
- data/app/components/shadcn/accordion_component.html.erb +8 -0
- data/app/components/shadcn/accordion_component.rb +6 -15
- data/app/components/shadcn/alert_component.html.erb +6 -0
- data/app/components/shadcn/alert_component.rb +0 -18
- data/app/components/shadcn/alert_dialog_component.html.erb +12 -0
- data/app/components/shadcn/alert_dialog_component.rb +7 -27
- data/app/components/shadcn/aspect_ratio_component.html.erb +7 -0
- data/app/components/shadcn/aspect_ratio_component.rb +4 -19
- data/app/components/shadcn/avatar_component.html.erb +20 -0
- data/app/components/shadcn/avatar_component.rb +8 -36
- data/app/components/shadcn/badge_component.html.erb +1 -0
- data/app/components/shadcn/badge_component.rb +0 -11
- data/app/components/shadcn/base_component.rb +15 -2
- data/app/components/shadcn/breadcrumb_component.html.erb +5 -0
- data/app/components/shadcn/breadcrumb_component.rb +6 -16
- data/app/components/shadcn/button_component.html.erb +18 -0
- data/app/components/shadcn/button_component.rb +1 -41
- data/app/components/shadcn/card_component.html.erb +8 -0
- data/app/components/shadcn/card_component.rb +2 -6
- data/app/components/shadcn/checkbox_component.html.erb +32 -0
- data/app/components/shadcn/checkbox_component.rb +4 -43
- data/app/components/shadcn/collapsible_component.html.erb +8 -0
- data/app/components/shadcn/collapsible_component.rb +6 -15
- data/app/components/shadcn/context_menu_component.html.erb +11 -0
- data/app/components/shadcn/context_menu_component.rb +6 -26
- data/app/components/shadcn/dialog_component.html.erb +14 -0
- data/app/components/shadcn/dialog_component.rb +8 -29
- data/app/components/shadcn/drawer_component.html.erb +12 -0
- data/app/components/shadcn/drawer_component.rb +7 -27
- data/app/components/shadcn/dropdown_menu_component.html.erb +14 -0
- data/app/components/shadcn/dropdown_menu_component.rb +9 -29
- data/app/components/shadcn/field_component.rb +7 -8
- data/app/components/shadcn/hover_card_component.html.erb +12 -0
- data/app/components/shadcn/hover_card_component.rb +7 -26
- data/app/components/shadcn/input_component.html.erb +18 -0
- data/app/components/shadcn/input_component.rb +2 -27
- data/app/components/shadcn/input_otp_component.rb +3 -3
- data/app/components/shadcn/kbd_component.html.erb +1 -0
- data/app/components/shadcn/kbd_component.rb +3 -10
- data/app/components/shadcn/label_component.html.erb +3 -0
- data/app/components/shadcn/label_component.rb +2 -18
- data/app/components/shadcn/menubar_component.html.erb +6 -0
- data/app/components/shadcn/menubar_component.rb +4 -15
- data/app/components/shadcn/native_select_component.html.erb +22 -0
- data/app/components/shadcn/native_select_component.rb +9 -39
- data/app/components/shadcn/navigation_menu_component.html.erb +6 -0
- data/app/components/shadcn/navigation_menu_component.rb +4 -15
- data/app/components/shadcn/pagination_component.html.erb +5 -0
- data/app/components/shadcn/pagination_component.rb +11 -15
- data/app/components/shadcn/popover_component.html.erb +15 -0
- data/app/components/shadcn/popover_component.rb +10 -30
- data/app/components/shadcn/progress_component.html.erb +13 -0
- data/app/components/shadcn/progress_component.rb +6 -26
- data/app/components/shadcn/radio_group_component.html.erb +8 -0
- data/app/components/shadcn/radio_group_component.rb +12 -26
- data/app/components/shadcn/scroll_area_component.html.erb +7 -0
- data/app/components/shadcn/scroll_area_component.rb +4 -16
- data/app/components/shadcn/select_component.html.erb +46 -0
- data/app/components/shadcn/select_component.rb +6 -80
- data/app/components/shadcn/separator_component.html.erb +5 -0
- data/app/components/shadcn/separator_component.rb +6 -14
- data/app/components/shadcn/sheet_component.html.erb +12 -0
- data/app/components/shadcn/sheet_component.rb +7 -27
- data/app/components/shadcn/sidebar_component.rb +2 -2
- data/app/components/shadcn/skeleton_component.html.erb +1 -0
- data/app/components/shadcn/skeleton_component.rb +4 -2
- data/app/components/shadcn/slider_component.html.erb +12 -0
- data/app/components/shadcn/slider_component.rb +2 -21
- data/app/components/shadcn/spinner_component.html.erb +18 -0
- data/app/components/shadcn/spinner_component.rb +2 -30
- data/app/components/shadcn/switch_component.html.erb +72 -0
- data/app/components/shadcn/switch_component.rb +4 -82
- data/app/components/shadcn/table_component.html.erb +9 -0
- data/app/components/shadcn/table_component.rb +2 -10
- data/app/components/shadcn/tabs_component.html.erb +8 -0
- data/app/components/shadcn/tabs_component.rb +4 -17
- data/app/components/shadcn/textarea_component.html.erb +13 -0
- data/app/components/shadcn/textarea_component.rb +6 -22
- data/app/components/shadcn/toast_component.html.erb +36 -0
- data/app/components/shadcn/toast_component.rb +6 -54
- data/app/components/shadcn/toggle_component.html.erb +12 -0
- data/app/components/shadcn/toggle_component.rb +6 -21
- data/app/components/shadcn/toggle_group_component.html.erb +14 -0
- data/app/components/shadcn/toggle_group_component.rb +6 -29
- data/app/components/shadcn/tooltip_component.html.erb +20 -0
- data/app/components/shadcn/tooltip_component.rb +13 -38
- data/lib/generators/shadcn/add/USAGE +24 -0
- data/lib/generators/shadcn/add/add_generator.rb +279 -0
- data/lib/generators/shadcn/install/USAGE +22 -0
- data/lib/generators/shadcn/install/install_generator.rb +8 -3
- data/lib/generators/shadcn/install/templates/initializer.rb.tt +7 -27
- data/lib/generators/shadcn/install/templates/shadcn.yml.tt +15 -31
- data/lib/shadcn/rails/version.rb +1 -1
- metadata +47 -45
- data/.dockerignore +0 -40
- data/CLAUDE.md +0 -612
- data/PROGRESS.md +0 -495
- data/Rakefile +0 -95
- data/__tests__/controllers/__snapshots__/calendar_controller.test.js.snap +0 -13
- data/__tests__/controllers/__snapshots__/popover_controller.test.js.snap +0 -46
- data/__tests__/controllers/__snapshots__/sheet_controller.test.js.snap +0 -111
- data/__tests__/controllers/__snapshots__/tabs_controller.test.js.snap +0 -27
- data/__tests__/controllers/accordion_controller.test.js +0 -904
- data/__tests__/controllers/calendar_controller.test.js +0 -1370
- data/__tests__/controllers/carousel_controller.test.js +0 -912
- data/__tests__/controllers/checkbox_controller.test.js +0 -454
- data/__tests__/controllers/collapsible_controller.test.js +0 -407
- data/__tests__/controllers/combobox_controller.test.js +0 -971
- data/__tests__/controllers/context_menu_controller.test.js +0 -905
- data/__tests__/controllers/date_picker_controller.test.js +0 -636
- data/__tests__/controllers/dialog_controller.test.js +0 -878
- data/__tests__/controllers/drawer_controller.test.js +0 -995
- data/__tests__/controllers/menubar_controller.test.js +0 -737
- data/__tests__/controllers/navigation_menu_controller.test.js +0 -599
- data/__tests__/controllers/popover_controller.test.js +0 -982
- data/__tests__/controllers/radio_group_controller.test.js +0 -640
- data/__tests__/controllers/resizable_controller.test.js +0 -680
- data/__tests__/controllers/select_controller.test.js +0 -678
- data/__tests__/controllers/sheet_controller.test.js +0 -986
- data/__tests__/controllers/slider_controller.test.js +0 -1036
- data/__tests__/controllers/switch_controller.test.js +0 -424
- data/__tests__/controllers/tabs_controller.test.js +0 -907
- data/__tests__/controllers/toggle_group_controller.test.js +0 -839
- data/__tests__/controllers/tooltip_controller.test.js +0 -808
- data/__tests__/helpers/stimulus-test-helper.js +0 -203
- data/babel.config.cjs +0 -5
- data/bin/bump +0 -321
- data/bin/console +0 -11
- data/bin/release +0 -205
- data/bin/setup +0 -8
- data/bin/test +0 -75
- data/jest.config.js +0 -19
- data/jest.setup.js +0 -8
- data/lib/generators/shadcn/component/component_generator.rb +0 -188
- data/lib/generators/shadcn/theme/theme_generator.rb +0 -128
- data/package-lock.json +0 -7438
- data/package.json +0 -71
- 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
|
-
})
|