@furystack/shades-common-components 12.3.0 → 12.5.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.
- package/CHANGELOG.md +86 -0
- package/esm/components/app-bar-link.spec.js +16 -19
- package/esm/components/app-bar-link.spec.js.map +1 -1
- package/esm/components/app-bar.spec.js +6 -4
- package/esm/components/app-bar.spec.js.map +1 -1
- package/esm/components/avatar.spec.js +9 -9
- package/esm/components/avatar.spec.js.map +1 -1
- package/esm/components/breadcrumb.spec.js +2 -2
- package/esm/components/breadcrumb.spec.js.map +1 -1
- package/esm/components/button-group.d.ts +32 -0
- package/esm/components/button-group.d.ts.map +1 -1
- package/esm/components/button-group.js +26 -2
- package/esm/components/button-group.js.map +1 -1
- package/esm/components/button-group.spec.js +127 -11
- package/esm/components/button-group.spec.js.map +1 -1
- package/esm/components/button.spec.js +4 -4
- package/esm/components/button.spec.js.map +1 -1
- package/esm/components/cache-view.spec.js +2 -3
- package/esm/components/cache-view.spec.js.map +1 -1
- package/esm/components/carousel.spec.js +47 -47
- package/esm/components/carousel.spec.js.map +1 -1
- package/esm/components/circular-progress.spec.js +2 -2
- package/esm/components/command-palette/command-palette-input.spec.js +23 -19
- package/esm/components/command-palette/command-palette-input.spec.js.map +1 -1
- package/esm/components/command-palette/command-palette-suggestion-list.spec.js +27 -27
- package/esm/components/command-palette/command-palette-suggestion-list.spec.js.map +1 -1
- package/esm/components/command-palette/index.spec.js +64 -51
- package/esm/components/command-palette/index.spec.js.map +1 -1
- package/esm/components/context-menu/context-menu.spec.js +33 -33
- package/esm/components/context-menu/context-menu.spec.js.map +1 -1
- package/esm/components/data-grid/body.spec.js +13 -13
- package/esm/components/data-grid/body.spec.js.map +1 -1
- package/esm/components/data-grid/data-grid-row.spec.js +8 -8
- package/esm/components/data-grid/data-grid-row.spec.js.map +1 -1
- package/esm/components/data-grid/data-grid.d.ts +40 -2
- package/esm/components/data-grid/data-grid.d.ts.map +1 -1
- package/esm/components/data-grid/data-grid.js +7 -10
- package/esm/components/data-grid/data-grid.js.map +1 -1
- package/esm/components/data-grid/data-grid.spec.js +71 -28
- package/esm/components/data-grid/data-grid.spec.js.map +1 -1
- package/esm/components/data-grid/filters/boolean-filter.d.ts +12 -0
- package/esm/components/data-grid/filters/boolean-filter.d.ts.map +1 -0
- package/esm/components/data-grid/filters/boolean-filter.js +27 -0
- package/esm/components/data-grid/filters/boolean-filter.js.map +1 -0
- package/esm/components/data-grid/filters/boolean-filter.spec.d.ts +2 -0
- package/esm/components/data-grid/filters/boolean-filter.spec.d.ts.map +1 -0
- package/esm/components/data-grid/filters/boolean-filter.spec.js +114 -0
- package/esm/components/data-grid/filters/boolean-filter.spec.js.map +1 -0
- package/esm/components/data-grid/filters/date-filter.d.ts +12 -0
- package/esm/components/data-grid/filters/date-filter.d.ts.map +1 -0
- package/esm/components/data-grid/filters/date-filter.js +109 -0
- package/esm/components/data-grid/filters/date-filter.js.map +1 -0
- package/esm/components/data-grid/filters/date-filter.spec.d.ts +2 -0
- package/esm/components/data-grid/filters/date-filter.spec.d.ts.map +1 -0
- package/esm/components/data-grid/filters/date-filter.spec.js +145 -0
- package/esm/components/data-grid/filters/date-filter.spec.js.map +1 -0
- package/esm/components/data-grid/filters/enum-filter.d.ts +16 -0
- package/esm/components/data-grid/filters/enum-filter.d.ts.map +1 -0
- package/esm/components/data-grid/filters/enum-filter.js +72 -0
- package/esm/components/data-grid/filters/enum-filter.js.map +1 -0
- package/esm/components/data-grid/filters/enum-filter.spec.d.ts +2 -0
- package/esm/components/data-grid/filters/enum-filter.spec.d.ts.map +1 -0
- package/esm/components/data-grid/filters/enum-filter.spec.js +136 -0
- package/esm/components/data-grid/filters/enum-filter.spec.js.map +1 -0
- package/esm/components/data-grid/filters/filter-dropdown.d.ts +6 -0
- package/esm/components/data-grid/filters/filter-dropdown.d.ts.map +1 -0
- package/esm/components/data-grid/filters/filter-dropdown.js +41 -0
- package/esm/components/data-grid/filters/filter-dropdown.js.map +1 -0
- package/esm/components/data-grid/filters/filter-dropdown.spec.d.ts +2 -0
- package/esm/components/data-grid/filters/filter-dropdown.spec.d.ts.map +1 -0
- package/esm/components/data-grid/filters/filter-dropdown.spec.js +69 -0
- package/esm/components/data-grid/filters/filter-dropdown.spec.js.map +1 -0
- package/esm/components/data-grid/filters/filter-styles.d.ts +24 -0
- package/esm/components/data-grid/filters/filter-styles.d.ts.map +1 -0
- package/esm/components/data-grid/filters/filter-styles.js +25 -0
- package/esm/components/data-grid/filters/filter-styles.js.map +1 -0
- package/esm/components/data-grid/filters/index.d.ts +7 -0
- package/esm/components/data-grid/filters/index.d.ts.map +1 -0
- package/esm/components/data-grid/filters/index.js +7 -0
- package/esm/components/data-grid/filters/index.js.map +1 -0
- package/esm/components/data-grid/filters/number-filter.d.ts +12 -0
- package/esm/components/data-grid/filters/number-filter.d.ts.map +1 -0
- package/esm/components/data-grid/filters/number-filter.js +65 -0
- package/esm/components/data-grid/filters/number-filter.js.map +1 -0
- package/esm/components/data-grid/filters/number-filter.spec.d.ts +2 -0
- package/esm/components/data-grid/filters/number-filter.spec.d.ts.map +1 -0
- package/esm/components/data-grid/filters/number-filter.spec.js +142 -0
- package/esm/components/data-grid/filters/number-filter.spec.js.map +1 -0
- package/esm/components/data-grid/filters/string-filter.d.ts +12 -0
- package/esm/components/data-grid/filters/string-filter.d.ts.map +1 -0
- package/esm/components/data-grid/filters/string-filter.js +63 -0
- package/esm/components/data-grid/filters/string-filter.js.map +1 -0
- package/esm/components/data-grid/filters/string-filter.spec.d.ts +2 -0
- package/esm/components/data-grid/filters/string-filter.spec.d.ts.map +1 -0
- package/esm/components/data-grid/filters/string-filter.spec.js +128 -0
- package/esm/components/data-grid/filters/string-filter.spec.js.map +1 -0
- package/esm/components/data-grid/footer.d.ts.map +1 -1
- package/esm/components/data-grid/footer.js +24 -9
- package/esm/components/data-grid/footer.js.map +1 -1
- package/esm/components/data-grid/footer.spec.js +38 -36
- package/esm/components/data-grid/footer.spec.js.map +1 -1
- package/esm/components/data-grid/header.d.ts +6 -9
- package/esm/components/data-grid/header.d.ts.map +1 -1
- package/esm/components/data-grid/header.js +51 -117
- package/esm/components/data-grid/header.js.map +1 -1
- package/esm/components/data-grid/header.spec.js +116 -187
- package/esm/components/data-grid/header.spec.js.map +1 -1
- package/esm/components/data-grid/index.d.ts +1 -0
- package/esm/components/data-grid/index.d.ts.map +1 -1
- package/esm/components/data-grid/index.js +1 -0
- package/esm/components/data-grid/index.js.map +1 -1
- package/esm/components/data-grid/selection-cell.spec.js +8 -8
- package/esm/components/data-grid/selection-cell.spec.js.map +1 -1
- package/esm/components/drawer/drawer-toggle-button.spec.js +22 -22
- package/esm/components/drawer/drawer-toggle-button.spec.js.map +1 -1
- package/esm/components/drawer/index.spec.js +36 -36
- package/esm/components/drawer/index.spec.js.map +1 -1
- package/esm/components/dropdown.spec.js +38 -30
- package/esm/components/dropdown.spec.js.map +1 -1
- package/esm/components/fab.spec.js +4 -4
- package/esm/components/fab.spec.js.map +1 -1
- package/esm/components/form.d.ts +5 -2
- package/esm/components/form.d.ts.map +1 -1
- package/esm/components/form.js +28 -6
- package/esm/components/form.js.map +1 -1
- package/esm/components/form.spec.js +227 -20
- package/esm/components/form.spec.js.map +1 -1
- package/esm/components/grid.spec.js +3 -3
- package/esm/components/grid.spec.js.map +1 -1
- package/esm/components/image.spec.js +55 -52
- package/esm/components/image.spec.js.map +1 -1
- package/esm/components/inputs/autocomplete.spec.js +7 -14
- package/esm/components/inputs/autocomplete.spec.js.map +1 -1
- package/esm/components/inputs/checkbox.spec.js +22 -22
- package/esm/components/inputs/checkbox.spec.js.map +1 -1
- package/esm/components/inputs/input-number.spec.js +47 -47
- package/esm/components/inputs/input-number.spec.js.map +1 -1
- package/esm/components/inputs/input.spec.js +53 -53
- package/esm/components/inputs/input.spec.js.map +1 -1
- package/esm/components/inputs/radio-group.spec.js +14 -14
- package/esm/components/inputs/radio-group.spec.js.map +1 -1
- package/esm/components/inputs/radio.spec.js +16 -16
- package/esm/components/inputs/radio.spec.js.map +1 -1
- package/esm/components/inputs/select.spec.js +74 -74
- package/esm/components/inputs/select.spec.js.map +1 -1
- package/esm/components/inputs/slider.spec.js +16 -16
- package/esm/components/inputs/slider.spec.js.map +1 -1
- package/esm/components/inputs/switch.spec.js +24 -24
- package/esm/components/inputs/switch.spec.js.map +1 -1
- package/esm/components/inputs/text-area.spec.js +17 -17
- package/esm/components/inputs/text-area.spec.js.map +1 -1
- package/esm/components/linear-progress.spec.js +2 -2
- package/esm/components/list/list.spec.js +36 -36
- package/esm/components/list/list.spec.js.map +1 -1
- package/esm/components/markdown/markdown-display.spec.js +15 -15
- package/esm/components/markdown/markdown-display.spec.js.map +1 -1
- package/esm/components/markdown/markdown-editor.spec.js +8 -8
- package/esm/components/markdown/markdown-editor.spec.js.map +1 -1
- package/esm/components/markdown/markdown-input.spec.js +17 -17
- package/esm/components/markdown/markdown-input.spec.js.map +1 -1
- package/esm/components/menu/menu.spec.js +28 -28
- package/esm/components/menu/menu.spec.js.map +1 -1
- package/esm/components/modal.spec.js +15 -18
- package/esm/components/modal.spec.js.map +1 -1
- package/esm/components/noty-list.spec.js +25 -23
- package/esm/components/noty-list.spec.js.map +1 -1
- package/esm/components/page-container/index.spec.js +16 -16
- package/esm/components/page-container/index.spec.js.map +1 -1
- package/esm/components/page-container/page-header.spec.js +16 -16
- package/esm/components/page-container/page-header.spec.js.map +1 -1
- package/esm/components/page-layout/index.spec.js +29 -29
- package/esm/components/page-layout/index.spec.js.map +1 -1
- package/esm/components/paper.spec.js +3 -3
- package/esm/components/paper.spec.js.map +1 -1
- package/esm/components/rating.spec.js +61 -61
- package/esm/components/rating.spec.js.map +1 -1
- package/esm/components/skeleton.spec.js +10 -6
- package/esm/components/skeleton.spec.js.map +1 -1
- package/esm/components/suggest/suggest-input.spec.js +4 -10
- package/esm/components/suggest/suggest-input.spec.js.map +1 -1
- package/esm/components/tabs.spec.js +30 -30
- package/esm/components/tabs.spec.js.map +1 -1
- package/esm/components/tree/tree.spec.js +27 -27
- package/esm/components/tree/tree.spec.js.map +1 -1
- package/esm/components/typography.spec.js +3 -3
- package/esm/components/typography.spec.js.map +1 -1
- package/esm/components/wizard/index.spec.js +5 -5
- package/esm/components/wizard/index.spec.js.map +1 -1
- package/esm/utils/promisify-animation.d.ts.map +1 -1
- package/esm/utils/promisify-animation.js +3 -0
- package/esm/utils/promisify-animation.js.map +1 -1
- package/package.json +2 -2
- package/src/components/app-bar-link.spec.tsx +16 -19
- package/src/components/app-bar.spec.tsx +6 -4
- package/src/components/avatar.spec.tsx +9 -9
- package/src/components/breadcrumb.spec.tsx +2 -2
- package/src/components/button-group.spec.tsx +155 -11
- package/src/components/button-group.tsx +49 -2
- package/src/components/button.spec.tsx +4 -4
- package/src/components/cache-view.spec.tsx +3 -3
- package/src/components/carousel.spec.tsx +47 -47
- package/src/components/circular-progress.spec.tsx +2 -2
- package/src/components/command-palette/command-palette-input.spec.tsx +23 -19
- package/src/components/command-palette/command-palette-suggestion-list.spec.tsx +27 -27
- package/src/components/command-palette/index.spec.tsx +64 -51
- package/src/components/context-menu/context-menu.spec.tsx +33 -33
- package/src/components/data-grid/body.spec.tsx +13 -13
- package/src/components/data-grid/data-grid-row.spec.tsx +8 -8
- package/src/components/data-grid/data-grid.spec.tsx +106 -28
- package/src/components/data-grid/data-grid.tsx +44 -11
- package/src/components/data-grid/filters/boolean-filter.spec.tsx +142 -0
- package/src/components/data-grid/filters/boolean-filter.tsx +45 -0
- package/src/components/data-grid/filters/date-filter.spec.tsx +181 -0
- package/src/components/data-grid/filters/date-filter.tsx +162 -0
- package/src/components/data-grid/filters/enum-filter.spec.tsx +168 -0
- package/src/components/data-grid/filters/enum-filter.tsx +119 -0
- package/src/components/data-grid/filters/filter-dropdown.spec.tsx +89 -0
- package/src/components/data-grid/filters/filter-dropdown.tsx +60 -0
- package/src/components/data-grid/filters/filter-styles.ts +26 -0
- package/src/components/data-grid/filters/index.ts +6 -0
- package/src/components/data-grid/filters/number-filter.spec.tsx +174 -0
- package/src/components/data-grid/filters/number-filter.tsx +115 -0
- package/src/components/data-grid/filters/string-filter.spec.tsx +157 -0
- package/src/components/data-grid/filters/string-filter.tsx +112 -0
- package/src/components/data-grid/footer.spec.tsx +38 -36
- package/src/components/data-grid/footer.tsx +21 -8
- package/src/components/data-grid/header.spec.tsx +128 -212
- package/src/components/data-grid/header.tsx +95 -183
- package/src/components/data-grid/index.tsx +1 -0
- package/src/components/data-grid/selection-cell.spec.tsx +8 -8
- package/src/components/drawer/drawer-toggle-button.spec.tsx +22 -22
- package/src/components/drawer/index.spec.tsx +36 -36
- package/src/components/dropdown.spec.tsx +38 -30
- package/src/components/fab.spec.tsx +4 -4
- package/src/components/form.spec.tsx +329 -20
- package/src/components/form.tsx +31 -8
- package/src/components/grid.spec.tsx +3 -3
- package/src/components/image.spec.tsx +55 -52
- package/src/components/inputs/autocomplete.spec.tsx +7 -14
- package/src/components/inputs/checkbox.spec.tsx +22 -22
- package/src/components/inputs/input-number.spec.tsx +47 -47
- package/src/components/inputs/input.spec.tsx +53 -53
- package/src/components/inputs/radio-group.spec.tsx +14 -14
- package/src/components/inputs/radio.spec.tsx +16 -16
- package/src/components/inputs/select.spec.tsx +74 -74
- package/src/components/inputs/slider.spec.tsx +16 -16
- package/src/components/inputs/switch.spec.tsx +24 -24
- package/src/components/inputs/text-area.spec.tsx +17 -17
- package/src/components/linear-progress.spec.tsx +2 -2
- package/src/components/list/list.spec.tsx +36 -36
- package/src/components/markdown/markdown-display.spec.tsx +15 -15
- package/src/components/markdown/markdown-editor.spec.tsx +8 -8
- package/src/components/markdown/markdown-input.spec.tsx +17 -17
- package/src/components/menu/menu.spec.tsx +28 -28
- package/src/components/modal.spec.tsx +15 -18
- package/src/components/noty-list.spec.tsx +25 -23
- package/src/components/page-container/index.spec.tsx +16 -16
- package/src/components/page-container/page-header.spec.tsx +16 -16
- package/src/components/page-layout/index.spec.tsx +29 -29
- package/src/components/paper.spec.tsx +3 -3
- package/src/components/rating.spec.tsx +61 -61
- package/src/components/skeleton.spec.tsx +10 -6
- package/src/components/suggest/suggest-input.spec.tsx +4 -10
- package/src/components/tabs.spec.tsx +30 -30
- package/src/components/tree/tree.spec.tsx +27 -27
- package/src/components/typography.spec.tsx +3 -3
- package/src/components/wizard/index.spec.tsx +5 -5
- package/src/utils/promisify-animation.ts +3 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Injector } from '@furystack/inject'
|
|
2
|
-
import { createComponent, initializeShadeRoot } from '@furystack/shades'
|
|
3
|
-
import {
|
|
2
|
+
import { createComponent, flushUpdates, initializeShadeRoot } from '@furystack/shades'
|
|
3
|
+
import { using, usingAsync } from '@furystack/utils'
|
|
4
4
|
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'
|
|
5
5
|
import { Form, FormService } from './form.js'
|
|
6
6
|
|
|
@@ -35,6 +35,18 @@ describe('FormService', () => {
|
|
|
35
35
|
expect(service.inputs.size).toBe(0)
|
|
36
36
|
})
|
|
37
37
|
})
|
|
38
|
+
|
|
39
|
+
it('should initialize isSubmitting as false', () => {
|
|
40
|
+
using(new FormService(), (service) => {
|
|
41
|
+
expect(service.isSubmitting.getValue()).toBe(false)
|
|
42
|
+
})
|
|
43
|
+
})
|
|
44
|
+
|
|
45
|
+
it('should initialize submitError as undefined', () => {
|
|
46
|
+
using(new FormService(), (service) => {
|
|
47
|
+
expect(service.submitError.getValue()).toBeUndefined()
|
|
48
|
+
})
|
|
49
|
+
})
|
|
38
50
|
})
|
|
39
51
|
|
|
40
52
|
describe('setFieldState', () => {
|
|
@@ -84,12 +96,18 @@ describe('FormService', () => {
|
|
|
84
96
|
const validatedFormDataDisposeSpy = vi.spyOn(service.validatedFormData, Symbol.dispose)
|
|
85
97
|
const rawFormDataDisposeSpy = vi.spyOn(service.rawFormData, Symbol.dispose)
|
|
86
98
|
const validationResultDisposeSpy = vi.spyOn(service.validationResult, Symbol.dispose)
|
|
99
|
+
const fieldErrorsDisposeSpy = vi.spyOn(service.fieldErrors, Symbol.dispose)
|
|
100
|
+
const isSubmittingDisposeSpy = vi.spyOn(service.isSubmitting, Symbol.dispose)
|
|
101
|
+
const submitErrorDisposeSpy = vi.spyOn(service.submitError, Symbol.dispose)
|
|
87
102
|
|
|
88
103
|
service[Symbol.dispose]()
|
|
89
104
|
|
|
90
105
|
expect(validatedFormDataDisposeSpy).toHaveBeenCalled()
|
|
91
106
|
expect(rawFormDataDisposeSpy).toHaveBeenCalled()
|
|
92
107
|
expect(validationResultDisposeSpy).toHaveBeenCalled()
|
|
108
|
+
expect(fieldErrorsDisposeSpy).toHaveBeenCalled()
|
|
109
|
+
expect(isSubmittingDisposeSpy).toHaveBeenCalled()
|
|
110
|
+
expect(submitErrorDisposeSpy).toHaveBeenCalled()
|
|
93
111
|
})
|
|
94
112
|
})
|
|
95
113
|
})
|
|
@@ -126,7 +144,7 @@ describe('Form component', () => {
|
|
|
126
144
|
),
|
|
127
145
|
})
|
|
128
146
|
|
|
129
|
-
await
|
|
147
|
+
await flushUpdates()
|
|
130
148
|
|
|
131
149
|
const form = document.querySelector('form[is="shade-form"]')
|
|
132
150
|
expect(form).not.toBeNull()
|
|
@@ -159,7 +177,7 @@ describe('Form component', () => {
|
|
|
159
177
|
),
|
|
160
178
|
})
|
|
161
179
|
|
|
162
|
-
await
|
|
180
|
+
await flushUpdates()
|
|
163
181
|
|
|
164
182
|
const form = document.querySelector('form[is="shade-form"]') as HTMLFormElement
|
|
165
183
|
const input = form.querySelector('input[name="name"]') as HTMLInputElement
|
|
@@ -168,7 +186,7 @@ describe('Form component', () => {
|
|
|
168
186
|
const submitEvent = new Event('submit', { bubbles: true, cancelable: true })
|
|
169
187
|
form.dispatchEvent(submitEvent)
|
|
170
188
|
|
|
171
|
-
await
|
|
189
|
+
await flushUpdates()
|
|
172
190
|
|
|
173
191
|
expect(onSubmit).toHaveBeenCalledWith({ name: 'Test Name' })
|
|
174
192
|
})
|
|
@@ -199,7 +217,7 @@ describe('Form component', () => {
|
|
|
199
217
|
),
|
|
200
218
|
})
|
|
201
219
|
|
|
202
|
-
await
|
|
220
|
+
await flushUpdates()
|
|
203
221
|
|
|
204
222
|
const form = document.querySelector('form[is="shade-form"]') as HTMLFormElement
|
|
205
223
|
const nameInput = form.querySelector('input[name="name"]') as HTMLInputElement
|
|
@@ -211,7 +229,7 @@ describe('Form component', () => {
|
|
|
211
229
|
const submitEvent = new Event('submit', { bubbles: true, cancelable: true })
|
|
212
230
|
form.dispatchEvent(submitEvent)
|
|
213
231
|
|
|
214
|
-
await
|
|
232
|
+
await flushUpdates()
|
|
215
233
|
|
|
216
234
|
expect(onSubmit).not.toHaveBeenCalled()
|
|
217
235
|
})
|
|
@@ -240,7 +258,7 @@ describe('Form component', () => {
|
|
|
240
258
|
),
|
|
241
259
|
})
|
|
242
260
|
|
|
243
|
-
await
|
|
261
|
+
await flushUpdates()
|
|
244
262
|
|
|
245
263
|
const form = document.querySelector('form[is="shade-form"]') as HTMLFormElement
|
|
246
264
|
const input = form.querySelector('input[name="email"]') as HTMLInputElement
|
|
@@ -249,7 +267,7 @@ describe('Form component', () => {
|
|
|
249
267
|
const changeEvent = new Event('change', { bubbles: true })
|
|
250
268
|
form.dispatchEvent(changeEvent)
|
|
251
269
|
|
|
252
|
-
await
|
|
270
|
+
await flushUpdates()
|
|
253
271
|
|
|
254
272
|
const formInjector = (form as unknown as { injector: Injector }).injector
|
|
255
273
|
const formService = formInjector.getInstance(FormService)
|
|
@@ -287,7 +305,7 @@ describe('Form component', () => {
|
|
|
287
305
|
),
|
|
288
306
|
})
|
|
289
307
|
|
|
290
|
-
await
|
|
308
|
+
await flushUpdates()
|
|
291
309
|
|
|
292
310
|
const form = document.querySelector('form[is="shade-form"]') as HTMLFormElement
|
|
293
311
|
const input = form.querySelector('input[name="name"]') as HTMLInputElement
|
|
@@ -296,7 +314,7 @@ describe('Form component', () => {
|
|
|
296
314
|
const changeEvent = new Event('change', { bubbles: true })
|
|
297
315
|
form.dispatchEvent(changeEvent)
|
|
298
316
|
|
|
299
|
-
await
|
|
317
|
+
await flushUpdates()
|
|
300
318
|
|
|
301
319
|
const formInjector = (form as unknown as { injector: Injector }).injector
|
|
302
320
|
const formService = formInjector.getInstance(FormService)
|
|
@@ -306,7 +324,7 @@ describe('Form component', () => {
|
|
|
306
324
|
const resetEvent = new Event('reset', { bubbles: true })
|
|
307
325
|
form.dispatchEvent(resetEvent)
|
|
308
326
|
|
|
309
|
-
await
|
|
327
|
+
await flushUpdates()
|
|
310
328
|
|
|
311
329
|
expect(formService.rawFormData.getValue()).toBeNull()
|
|
312
330
|
expect(formService.validationResult.getValue()).toEqual({ isValid: null })
|
|
@@ -336,7 +354,7 @@ describe('Form component', () => {
|
|
|
336
354
|
),
|
|
337
355
|
})
|
|
338
356
|
|
|
339
|
-
await
|
|
357
|
+
await flushUpdates()
|
|
340
358
|
|
|
341
359
|
const form = document.querySelector('form[is="shade-form"]') as HTMLFormElement
|
|
342
360
|
const input = form.querySelector('input[name="username"]') as HTMLInputElement
|
|
@@ -345,7 +363,7 @@ describe('Form component', () => {
|
|
|
345
363
|
const changeEvent = new Event('change', { bubbles: true })
|
|
346
364
|
form.dispatchEvent(changeEvent)
|
|
347
365
|
|
|
348
|
-
await
|
|
366
|
+
await flushUpdates()
|
|
349
367
|
|
|
350
368
|
const formInjector = (form as unknown as { injector: Injector }).injector
|
|
351
369
|
const formService = formInjector.getInstance(FormService)
|
|
@@ -376,7 +394,7 @@ describe('Form component', () => {
|
|
|
376
394
|
),
|
|
377
395
|
})
|
|
378
396
|
|
|
379
|
-
await
|
|
397
|
+
await flushUpdates()
|
|
380
398
|
|
|
381
399
|
const form = document.querySelector('form[is="shade-form"]') as HTMLFormElement
|
|
382
400
|
const input = form.querySelector('input[name="title"]') as HTMLInputElement
|
|
@@ -385,7 +403,7 @@ describe('Form component', () => {
|
|
|
385
403
|
const changeEvent = new Event('change', { bubbles: true })
|
|
386
404
|
form.dispatchEvent(changeEvent)
|
|
387
405
|
|
|
388
|
-
await
|
|
406
|
+
await flushUpdates()
|
|
389
407
|
|
|
390
408
|
const formInjector = (form as unknown as { injector: Injector }).injector
|
|
391
409
|
const formService = formInjector.getInstance(FormService)
|
|
@@ -412,7 +430,7 @@ describe('Form component', () => {
|
|
|
412
430
|
),
|
|
413
431
|
})
|
|
414
432
|
|
|
415
|
-
await
|
|
433
|
+
await flushUpdates()
|
|
416
434
|
|
|
417
435
|
const form = document.querySelector('form[is="shade-form"]') as HTMLFormElement
|
|
418
436
|
|
|
@@ -441,7 +459,7 @@ describe('Form component', () => {
|
|
|
441
459
|
),
|
|
442
460
|
})
|
|
443
461
|
|
|
444
|
-
await
|
|
462
|
+
await flushUpdates()
|
|
445
463
|
|
|
446
464
|
const form = document.querySelector('form[is="shade-form"]') as HTMLFormElement
|
|
447
465
|
const formInjector = (form as unknown as { injector: Injector }).injector
|
|
@@ -477,7 +495,7 @@ describe('Form component', () => {
|
|
|
477
495
|
),
|
|
478
496
|
})
|
|
479
497
|
|
|
480
|
-
await
|
|
498
|
+
await flushUpdates()
|
|
481
499
|
|
|
482
500
|
const form = document.querySelector('form[is="shade-form"]') as HTMLFormElement
|
|
483
501
|
const input = form.querySelector('input[name="required"]') as HTMLInputElement
|
|
@@ -485,7 +503,298 @@ describe('Form component', () => {
|
|
|
485
503
|
const invalidEvent = new Event('invalid', { bubbles: true })
|
|
486
504
|
input.dispatchEvent(invalidEvent)
|
|
487
505
|
|
|
488
|
-
await
|
|
506
|
+
await flushUpdates()
|
|
507
|
+
})
|
|
508
|
+
})
|
|
509
|
+
|
|
510
|
+
it('should set isSubmitting during async onSubmit and reset after', async () => {
|
|
511
|
+
await usingAsync(new Injector(), async (injector) => {
|
|
512
|
+
const rootElement = document.getElementById('root') as HTMLDivElement
|
|
513
|
+
|
|
514
|
+
let resolveSubmit: () => void
|
|
515
|
+
const submitPromise = new Promise<void>((resolve) => {
|
|
516
|
+
resolveSubmit = resolve
|
|
517
|
+
})
|
|
518
|
+
|
|
519
|
+
type FormData = { name: string }
|
|
520
|
+
|
|
521
|
+
initializeShadeRoot({
|
|
522
|
+
injector,
|
|
523
|
+
rootElement,
|
|
524
|
+
jsxElement: (
|
|
525
|
+
<Form<FormData>
|
|
526
|
+
onSubmit={() => submitPromise}
|
|
527
|
+
validate={(data): data is FormData => {
|
|
528
|
+
const d = data as Record<string, unknown>
|
|
529
|
+
return typeof d.name === 'string'
|
|
530
|
+
}}
|
|
531
|
+
>
|
|
532
|
+
<input name="name" type="text" />
|
|
533
|
+
<button type="submit">Submit</button>
|
|
534
|
+
</Form>
|
|
535
|
+
),
|
|
536
|
+
})
|
|
537
|
+
|
|
538
|
+
await flushUpdates()
|
|
539
|
+
|
|
540
|
+
const form = document.querySelector('form[is="shade-form"]') as HTMLFormElement
|
|
541
|
+
const input = form.querySelector('input[name="name"]') as HTMLInputElement
|
|
542
|
+
input.value = 'Test'
|
|
543
|
+
|
|
544
|
+
const formInjector = (form as unknown as { injector: Injector }).injector
|
|
545
|
+
const formService = formInjector.getInstance(FormService)
|
|
546
|
+
|
|
547
|
+
expect(formService.isSubmitting.getValue()).toBe(false)
|
|
548
|
+
|
|
549
|
+
const submitEvent = new Event('submit', { bubbles: true, cancelable: true })
|
|
550
|
+
form.dispatchEvent(submitEvent)
|
|
551
|
+
|
|
552
|
+
await flushUpdates()
|
|
553
|
+
expect(formService.isSubmitting.getValue()).toBe(true)
|
|
554
|
+
|
|
555
|
+
resolveSubmit!()
|
|
556
|
+
await flushUpdates()
|
|
557
|
+
expect(formService.isSubmitting.getValue()).toBe(false)
|
|
558
|
+
})
|
|
559
|
+
})
|
|
560
|
+
|
|
561
|
+
it('should reset isSubmitting to false and set submitError when onSubmit throws', async () => {
|
|
562
|
+
await usingAsync(new Injector(), async (injector) => {
|
|
563
|
+
const rootElement = document.getElementById('root') as HTMLDivElement
|
|
564
|
+
|
|
565
|
+
type FormData = { name: string }
|
|
566
|
+
|
|
567
|
+
const submitError = new Error('Submit failed')
|
|
568
|
+
|
|
569
|
+
initializeShadeRoot({
|
|
570
|
+
injector,
|
|
571
|
+
rootElement,
|
|
572
|
+
jsxElement: (
|
|
573
|
+
<Form<FormData>
|
|
574
|
+
onSubmit={async () => {
|
|
575
|
+
throw submitError
|
|
576
|
+
}}
|
|
577
|
+
validate={(data): data is FormData => {
|
|
578
|
+
const d = data as Record<string, unknown>
|
|
579
|
+
return typeof d.name === 'string'
|
|
580
|
+
}}
|
|
581
|
+
>
|
|
582
|
+
<input name="name" type="text" />
|
|
583
|
+
<button type="submit">Submit</button>
|
|
584
|
+
</Form>
|
|
585
|
+
),
|
|
586
|
+
})
|
|
587
|
+
|
|
588
|
+
await flushUpdates()
|
|
589
|
+
|
|
590
|
+
const form = document.querySelector('form[is="shade-form"]') as HTMLFormElement
|
|
591
|
+
const input = form.querySelector('input[name="name"]') as HTMLInputElement
|
|
592
|
+
input.value = 'Test'
|
|
593
|
+
|
|
594
|
+
const formInjector = (form as unknown as { injector: Injector }).injector
|
|
595
|
+
const formService = formInjector.getInstance(FormService)
|
|
596
|
+
|
|
597
|
+
const submitEvent = new Event('submit', { bubbles: true, cancelable: true })
|
|
598
|
+
form.dispatchEvent(submitEvent)
|
|
599
|
+
|
|
600
|
+
await flushUpdates()
|
|
601
|
+
expect(formService.isSubmitting.getValue()).toBe(false)
|
|
602
|
+
expect(formService.submitError.getValue()).toBe(submitError)
|
|
603
|
+
})
|
|
604
|
+
})
|
|
605
|
+
|
|
606
|
+
it('should clear submitError before a new submission', async () => {
|
|
607
|
+
await usingAsync(new Injector(), async (injector) => {
|
|
608
|
+
const rootElement = document.getElementById('root') as HTMLDivElement
|
|
609
|
+
|
|
610
|
+
let shouldThrow = true
|
|
611
|
+
let resolveSubmit: () => void
|
|
612
|
+
|
|
613
|
+
type FormData = { name: string }
|
|
614
|
+
|
|
615
|
+
initializeShadeRoot({
|
|
616
|
+
injector,
|
|
617
|
+
rootElement,
|
|
618
|
+
jsxElement: (
|
|
619
|
+
<Form<FormData>
|
|
620
|
+
onSubmit={async () => {
|
|
621
|
+
if (shouldThrow) {
|
|
622
|
+
throw new Error('First submit fails')
|
|
623
|
+
}
|
|
624
|
+
return new Promise<void>((resolve) => {
|
|
625
|
+
resolveSubmit = resolve
|
|
626
|
+
})
|
|
627
|
+
}}
|
|
628
|
+
validate={(data): data is FormData => {
|
|
629
|
+
const d = data as Record<string, unknown>
|
|
630
|
+
return typeof d.name === 'string'
|
|
631
|
+
}}
|
|
632
|
+
>
|
|
633
|
+
<input name="name" type="text" />
|
|
634
|
+
<button type="submit">Submit</button>
|
|
635
|
+
</Form>
|
|
636
|
+
),
|
|
637
|
+
})
|
|
638
|
+
|
|
639
|
+
await flushUpdates()
|
|
640
|
+
|
|
641
|
+
const form = document.querySelector('form[is="shade-form"]') as HTMLFormElement
|
|
642
|
+
const input = form.querySelector('input[name="name"]') as HTMLInputElement
|
|
643
|
+
input.value = 'Test'
|
|
644
|
+
|
|
645
|
+
const formInjector = (form as unknown as { injector: Injector }).injector
|
|
646
|
+
const formService = formInjector.getInstance(FormService)
|
|
647
|
+
|
|
648
|
+
form.dispatchEvent(new Event('submit', { bubbles: true, cancelable: true }))
|
|
649
|
+
await flushUpdates()
|
|
650
|
+
expect(formService.submitError.getValue()).toBeInstanceOf(Error)
|
|
651
|
+
|
|
652
|
+
shouldThrow = false
|
|
653
|
+
form.dispatchEvent(new Event('submit', { bubbles: true, cancelable: true }))
|
|
654
|
+
await flushUpdates()
|
|
655
|
+
expect(formService.submitError.getValue()).toBeUndefined()
|
|
656
|
+
expect(formService.isSubmitting.getValue()).toBe(true)
|
|
657
|
+
|
|
658
|
+
resolveSubmit!()
|
|
659
|
+
await flushUpdates()
|
|
660
|
+
expect(formService.isSubmitting.getValue()).toBe(false)
|
|
661
|
+
})
|
|
662
|
+
})
|
|
663
|
+
|
|
664
|
+
it('should set inert on form element when disableOnSubmit is true during async submit', async () => {
|
|
665
|
+
await usingAsync(new Injector(), async (injector) => {
|
|
666
|
+
const rootElement = document.getElementById('root') as HTMLDivElement
|
|
667
|
+
|
|
668
|
+
let resolveSubmit: () => void
|
|
669
|
+
const submitPromise = new Promise<void>((resolve) => {
|
|
670
|
+
resolveSubmit = resolve
|
|
671
|
+
})
|
|
672
|
+
|
|
673
|
+
type FormData = { name: string }
|
|
674
|
+
|
|
675
|
+
initializeShadeRoot({
|
|
676
|
+
injector,
|
|
677
|
+
rootElement,
|
|
678
|
+
jsxElement: (
|
|
679
|
+
<Form<FormData>
|
|
680
|
+
onSubmit={() => submitPromise}
|
|
681
|
+
disableOnSubmit
|
|
682
|
+
validate={(data): data is FormData => {
|
|
683
|
+
const d = data as Record<string, unknown>
|
|
684
|
+
return typeof d.name === 'string'
|
|
685
|
+
}}
|
|
686
|
+
>
|
|
687
|
+
<input name="name" type="text" />
|
|
688
|
+
<button type="submit">Submit</button>
|
|
689
|
+
</Form>
|
|
690
|
+
),
|
|
691
|
+
})
|
|
692
|
+
|
|
693
|
+
await flushUpdates()
|
|
694
|
+
|
|
695
|
+
const form = document.querySelector('form[is="shade-form"]') as HTMLFormElement
|
|
696
|
+
const input = form.querySelector('input[name="name"]') as HTMLInputElement
|
|
697
|
+
input.value = 'Test'
|
|
698
|
+
|
|
699
|
+
expect(form.inert).toBeFalsy()
|
|
700
|
+
|
|
701
|
+
const submitEvent = new Event('submit', { bubbles: true, cancelable: true })
|
|
702
|
+
form.dispatchEvent(submitEvent)
|
|
703
|
+
|
|
704
|
+
await flushUpdates()
|
|
705
|
+
expect(form.inert).toBe(true)
|
|
706
|
+
|
|
707
|
+
resolveSubmit!()
|
|
708
|
+
await flushUpdates()
|
|
709
|
+
expect(form.inert).toBe(false)
|
|
710
|
+
})
|
|
711
|
+
})
|
|
712
|
+
|
|
713
|
+
it('should not set inert when disableOnSubmit is not provided', async () => {
|
|
714
|
+
await usingAsync(new Injector(), async (injector) => {
|
|
715
|
+
const rootElement = document.getElementById('root') as HTMLDivElement
|
|
716
|
+
|
|
717
|
+
let resolveSubmit: () => void
|
|
718
|
+
const submitPromise = new Promise<void>((resolve) => {
|
|
719
|
+
resolveSubmit = resolve
|
|
720
|
+
})
|
|
721
|
+
|
|
722
|
+
type FormData = { name: string }
|
|
723
|
+
|
|
724
|
+
initializeShadeRoot({
|
|
725
|
+
injector,
|
|
726
|
+
rootElement,
|
|
727
|
+
jsxElement: (
|
|
728
|
+
<Form<FormData>
|
|
729
|
+
onSubmit={() => submitPromise}
|
|
730
|
+
validate={(data): data is FormData => {
|
|
731
|
+
const d = data as Record<string, unknown>
|
|
732
|
+
return typeof d.name === 'string'
|
|
733
|
+
}}
|
|
734
|
+
>
|
|
735
|
+
<input name="name" type="text" />
|
|
736
|
+
<button type="submit">Submit</button>
|
|
737
|
+
</Form>
|
|
738
|
+
),
|
|
739
|
+
})
|
|
740
|
+
|
|
741
|
+
await flushUpdates()
|
|
742
|
+
|
|
743
|
+
const form = document.querySelector('form[is="shade-form"]') as HTMLFormElement
|
|
744
|
+
const input = form.querySelector('input[name="name"]') as HTMLInputElement
|
|
745
|
+
input.value = 'Test'
|
|
746
|
+
|
|
747
|
+
const submitEvent = new Event('submit', { bubbles: true, cancelable: true })
|
|
748
|
+
form.dispatchEvent(submitEvent)
|
|
749
|
+
|
|
750
|
+
await flushUpdates()
|
|
751
|
+
expect(form.inert).toBeFalsy()
|
|
752
|
+
|
|
753
|
+
resolveSubmit!()
|
|
754
|
+
await flushUpdates()
|
|
755
|
+
})
|
|
756
|
+
})
|
|
757
|
+
|
|
758
|
+
it('should remove inert even if onSubmit throws when disableOnSubmit is true', async () => {
|
|
759
|
+
await usingAsync(new Injector(), async (injector) => {
|
|
760
|
+
const rootElement = document.getElementById('root') as HTMLDivElement
|
|
761
|
+
|
|
762
|
+
type FormData = { name: string }
|
|
763
|
+
|
|
764
|
+
initializeShadeRoot({
|
|
765
|
+
injector,
|
|
766
|
+
rootElement,
|
|
767
|
+
jsxElement: (
|
|
768
|
+
<Form<FormData>
|
|
769
|
+
onSubmit={async () => {
|
|
770
|
+
throw new Error('Submit failed')
|
|
771
|
+
}}
|
|
772
|
+
disableOnSubmit
|
|
773
|
+
validate={(data): data is FormData => {
|
|
774
|
+
const d = data as Record<string, unknown>
|
|
775
|
+
return typeof d.name === 'string'
|
|
776
|
+
}}
|
|
777
|
+
>
|
|
778
|
+
<input name="name" type="text" />
|
|
779
|
+
<button type="submit">Submit</button>
|
|
780
|
+
</Form>
|
|
781
|
+
),
|
|
782
|
+
})
|
|
783
|
+
|
|
784
|
+
await flushUpdates()
|
|
785
|
+
|
|
786
|
+
const form = document.querySelector('form[is="shade-form"]') as HTMLFormElement
|
|
787
|
+
const input = form.querySelector('input[name="name"]') as HTMLInputElement
|
|
788
|
+
input.value = 'Test'
|
|
789
|
+
|
|
790
|
+
const submitEvent = new Event('submit', { bubbles: true, cancelable: true })
|
|
791
|
+
form.dispatchEvent(submitEvent)
|
|
792
|
+
|
|
793
|
+
await flushUpdates()
|
|
794
|
+
expect(form.inert).toBe(false)
|
|
795
|
+
const formInjector = (form as unknown as { injector: Injector }).injector
|
|
796
|
+
const formService = formInjector.getInstance(FormService)
|
|
797
|
+
expect(formService.isSubmitting.getValue()).toBe(false)
|
|
489
798
|
})
|
|
490
799
|
})
|
|
491
800
|
})
|
package/src/components/form.tsx
CHANGED
|
@@ -29,6 +29,10 @@ export class FormService<T> {
|
|
|
29
29
|
|
|
30
30
|
public inputs = new Set<HTMLInputElement>()
|
|
31
31
|
|
|
32
|
+
public isSubmitting = new ObservableValue<boolean>(false)
|
|
33
|
+
|
|
34
|
+
public submitError = new ObservableValue<unknown>(undefined)
|
|
35
|
+
|
|
32
36
|
public setFieldState = (key: keyof T, validationResult: InputValidationResult, validity: ValidityState) => {
|
|
33
37
|
this.fieldErrors.setValue({ ...this.fieldErrors.getValue(), [key]: { validationResult, validity } })
|
|
34
38
|
}
|
|
@@ -37,13 +41,17 @@ export class FormService<T> {
|
|
|
37
41
|
this.validatedFormData[Symbol.dispose]()
|
|
38
42
|
this.rawFormData[Symbol.dispose]()
|
|
39
43
|
this.validationResult[Symbol.dispose]()
|
|
44
|
+
this.fieldErrors[Symbol.dispose]()
|
|
45
|
+
this.isSubmitting[Symbol.dispose]()
|
|
46
|
+
this.submitError[Symbol.dispose]()
|
|
40
47
|
}
|
|
41
48
|
}
|
|
42
49
|
|
|
43
50
|
type FormProps<T> = {
|
|
44
|
-
onSubmit: (formData: T) => void
|
|
51
|
+
onSubmit: (formData: T) => void | Promise<void>
|
|
45
52
|
onReset?: () => void
|
|
46
|
-
validate: (formData:
|
|
53
|
+
validate: (formData: unknown) => formData is T
|
|
54
|
+
disableOnSubmit?: boolean
|
|
47
55
|
} & PartialElement<Omit<HTMLFormElement, 'onsubmit' | 'onchange' | 'onreset'>>
|
|
48
56
|
|
|
49
57
|
export const Form: <T>(props: FormProps<T>, children: ChildrenList) => JSX.Element = Shade({
|
|
@@ -61,13 +69,14 @@ export const Form: <T>(props: FormProps<T>, children: ChildrenList) => JSX.Eleme
|
|
|
61
69
|
// `injector` setter defined on the Shade base class.
|
|
62
70
|
useHostProps({ injector: formInjector })
|
|
63
71
|
|
|
64
|
-
const changeHandler = (ev: Event, shouldSubmit?: boolean) => {
|
|
72
|
+
const changeHandler = async (ev: Event, shouldSubmit?: boolean) => {
|
|
65
73
|
formService.inputs.forEach((i) => {
|
|
66
74
|
const e = document.createEvent('FocusEvent')
|
|
67
75
|
e.initEvent('blur', true, true)
|
|
68
76
|
i.dispatchEvent(e)
|
|
69
77
|
})
|
|
70
|
-
const
|
|
78
|
+
const formElement = ev.currentTarget as HTMLFormElement
|
|
79
|
+
const formData = Object.fromEntries(new FormData(formElement).entries())
|
|
71
80
|
formService.rawFormData.setValue(formData)
|
|
72
81
|
const currentFieldErrors = formService.fieldErrors.getValue()
|
|
73
82
|
|
|
@@ -80,7 +89,21 @@ export const Form: <T>(props: FormProps<T>, children: ChildrenList) => JSX.Eleme
|
|
|
80
89
|
formService.validationResult.setValue({ isValid: true })
|
|
81
90
|
formService.validatedFormData.setValue(formData)
|
|
82
91
|
if (shouldSubmit) {
|
|
83
|
-
|
|
92
|
+
formService.isSubmitting.setValue(true)
|
|
93
|
+
formService.submitError.setValue(undefined)
|
|
94
|
+
if (props.disableOnSubmit) {
|
|
95
|
+
formElement.inert = true
|
|
96
|
+
}
|
|
97
|
+
try {
|
|
98
|
+
await props.onSubmit(formData)
|
|
99
|
+
} catch (error) {
|
|
100
|
+
formService.submitError.setValue(error)
|
|
101
|
+
} finally {
|
|
102
|
+
formService.isSubmitting.setValue(false)
|
|
103
|
+
if (props.disableOnSubmit) {
|
|
104
|
+
formElement.inert = false
|
|
105
|
+
}
|
|
106
|
+
}
|
|
84
107
|
}
|
|
85
108
|
} else {
|
|
86
109
|
formService.validationResult.setValue({ isValid: false, reason: 'validation-failed' })
|
|
@@ -89,14 +112,14 @@ export const Form: <T>(props: FormProps<T>, children: ChildrenList) => JSX.Eleme
|
|
|
89
112
|
|
|
90
113
|
useHostProps({
|
|
91
114
|
oninvalid: (ev: Event) => {
|
|
92
|
-
changeHandler(ev)
|
|
115
|
+
void changeHandler(ev)
|
|
93
116
|
},
|
|
94
117
|
onsubmit: (ev: SubmitEvent) => {
|
|
95
118
|
ev.preventDefault()
|
|
96
|
-
changeHandler(ev, true)
|
|
119
|
+
void changeHandler(ev, true)
|
|
97
120
|
},
|
|
98
121
|
onchange: (ev: Event) => {
|
|
99
|
-
changeHandler(ev)
|
|
122
|
+
void changeHandler(ev)
|
|
100
123
|
},
|
|
101
124
|
onreset: () => {
|
|
102
125
|
formService.rawFormData.setValue(null)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Injector } from '@furystack/inject'
|
|
2
|
-
import { createComponent, initializeShadeRoot } from '@furystack/shades'
|
|
3
|
-
import {
|
|
2
|
+
import { createComponent, flushUpdates, initializeShadeRoot } from '@furystack/shades'
|
|
3
|
+
import { usingAsync } from '@furystack/utils'
|
|
4
4
|
import { afterEach, beforeEach, describe, expect, it } from 'vitest'
|
|
5
5
|
import { Grid, type GridProps, type HeaderCells, type RowCells } from './grid.js'
|
|
6
6
|
|
|
@@ -24,7 +24,7 @@ describe('Grid', () => {
|
|
|
24
24
|
rootElement: root,
|
|
25
25
|
jsxElement: <Grid {...props} />,
|
|
26
26
|
})
|
|
27
|
-
await
|
|
27
|
+
await flushUpdates()
|
|
28
28
|
const grid = document.querySelector('shade-grid') as HTMLElement
|
|
29
29
|
return {
|
|
30
30
|
injector,
|