@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
2
|
import { createComponent, flushUpdates, initializeShadeRoot, LocationService } from '@furystack/shades'
|
|
3
|
-
import {
|
|
3
|
+
import { usingAsync } from '@furystack/utils'
|
|
4
4
|
import { afterEach, beforeEach, describe, expect, it } from 'vitest'
|
|
5
5
|
import { AppBarLink } from './app-bar-link.js'
|
|
6
6
|
|
|
@@ -24,7 +24,7 @@ describe('AppBarLink component', () => {
|
|
|
24
24
|
jsxElement: <AppBarLink href="/test">Link</AppBarLink>,
|
|
25
25
|
})
|
|
26
26
|
|
|
27
|
-
await
|
|
27
|
+
await flushUpdates()
|
|
28
28
|
|
|
29
29
|
const appBarLink = document.querySelector('shade-app-bar-link')
|
|
30
30
|
expect(appBarLink).not.toBeNull()
|
|
@@ -42,7 +42,7 @@ describe('AppBarLink component', () => {
|
|
|
42
42
|
jsxElement: <AppBarLink href="/test">Test Link Text</AppBarLink>,
|
|
43
43
|
})
|
|
44
44
|
|
|
45
|
-
await
|
|
45
|
+
await flushUpdates()
|
|
46
46
|
|
|
47
47
|
expect(document.body.innerHTML).toContain('Test Link Text')
|
|
48
48
|
})
|
|
@@ -58,7 +58,7 @@ describe('AppBarLink component', () => {
|
|
|
58
58
|
jsxElement: <AppBarLink href="/my-route">Link</AppBarLink>,
|
|
59
59
|
})
|
|
60
60
|
|
|
61
|
-
await
|
|
61
|
+
await flushUpdates()
|
|
62
62
|
|
|
63
63
|
expect(document.body.innerHTML).toContain('href="/my-route"')
|
|
64
64
|
})
|
|
@@ -78,7 +78,7 @@ describe('AppBarLink component', () => {
|
|
|
78
78
|
jsxElement: <AppBarLink href="/dashboard">Dashboard</AppBarLink>,
|
|
79
79
|
})
|
|
80
80
|
|
|
81
|
-
await
|
|
81
|
+
await flushUpdates()
|
|
82
82
|
|
|
83
83
|
const appBarLink = document.querySelector('shade-app-bar-link')
|
|
84
84
|
expect(appBarLink?.hasAttribute('data-active')).toBe(true)
|
|
@@ -97,7 +97,7 @@ describe('AppBarLink component', () => {
|
|
|
97
97
|
jsxElement: <AppBarLink href="/dashboard">Dashboard</AppBarLink>,
|
|
98
98
|
})
|
|
99
99
|
|
|
100
|
-
await
|
|
100
|
+
await flushUpdates()
|
|
101
101
|
|
|
102
102
|
const appBarLink = document.querySelector('shade-app-bar-link')
|
|
103
103
|
expect(appBarLink?.hasAttribute('data-active')).toBe(false)
|
|
@@ -116,7 +116,7 @@ describe('AppBarLink component', () => {
|
|
|
116
116
|
jsxElement: <AppBarLink href="/dashboard">Dashboard</AppBarLink>,
|
|
117
117
|
})
|
|
118
118
|
|
|
119
|
-
await
|
|
119
|
+
await flushUpdates()
|
|
120
120
|
|
|
121
121
|
const appBarLink = document.querySelector('shade-app-bar-link')
|
|
122
122
|
expect(appBarLink?.hasAttribute('data-active')).toBe(false)
|
|
@@ -125,7 +125,6 @@ describe('AppBarLink component', () => {
|
|
|
125
125
|
history.pushState(null, '', '/dashboard')
|
|
126
126
|
injector.getInstance(LocationService).updateState()
|
|
127
127
|
|
|
128
|
-
await sleepAsync(50)
|
|
129
128
|
await flushUpdates()
|
|
130
129
|
|
|
131
130
|
expect(appBarLink?.hasAttribute('data-active')).toBe(true)
|
|
@@ -144,7 +143,7 @@ describe('AppBarLink component', () => {
|
|
|
144
143
|
jsxElement: <AppBarLink href="/dashboard">Dashboard</AppBarLink>,
|
|
145
144
|
})
|
|
146
145
|
|
|
147
|
-
await
|
|
146
|
+
await flushUpdates()
|
|
148
147
|
|
|
149
148
|
const appBarLink = document.querySelector('shade-app-bar-link')
|
|
150
149
|
expect(appBarLink?.hasAttribute('data-active')).toBe(true)
|
|
@@ -153,7 +152,6 @@ describe('AppBarLink component', () => {
|
|
|
153
152
|
history.pushState(null, '', '/other')
|
|
154
153
|
injector.getInstance(LocationService).updateState()
|
|
155
154
|
|
|
156
|
-
await sleepAsync(50)
|
|
157
155
|
await flushUpdates()
|
|
158
156
|
|
|
159
157
|
expect(appBarLink?.hasAttribute('data-active')).toBe(false)
|
|
@@ -172,7 +170,7 @@ describe('AppBarLink component', () => {
|
|
|
172
170
|
jsxElement: <AppBarLink href="/users/:id">Users</AppBarLink>,
|
|
173
171
|
})
|
|
174
172
|
|
|
175
|
-
await
|
|
173
|
+
await flushUpdates()
|
|
176
174
|
|
|
177
175
|
const appBarLink = document.querySelector('shade-app-bar-link')
|
|
178
176
|
expect(appBarLink?.hasAttribute('data-active')).toBe(true)
|
|
@@ -195,7 +193,7 @@ describe('AppBarLink component', () => {
|
|
|
195
193
|
),
|
|
196
194
|
})
|
|
197
195
|
|
|
198
|
-
await
|
|
196
|
+
await flushUpdates()
|
|
199
197
|
|
|
200
198
|
const appBarLink = document.querySelector('shade-app-bar-link')
|
|
201
199
|
expect(appBarLink?.hasAttribute('data-active')).toBe(true)
|
|
@@ -214,7 +212,7 @@ describe('AppBarLink component', () => {
|
|
|
214
212
|
jsxElement: <AppBarLink href="/admin">Admin</AppBarLink>,
|
|
215
213
|
})
|
|
216
214
|
|
|
217
|
-
await
|
|
215
|
+
await flushUpdates()
|
|
218
216
|
|
|
219
217
|
const appBarLink = document.querySelector('shade-app-bar-link')
|
|
220
218
|
expect(appBarLink?.hasAttribute('data-active')).toBe(false)
|
|
@@ -241,7 +239,7 @@ describe('AppBarLink component', () => {
|
|
|
241
239
|
),
|
|
242
240
|
})
|
|
243
241
|
|
|
244
|
-
await
|
|
242
|
+
await flushUpdates()
|
|
245
243
|
|
|
246
244
|
const links = document.querySelectorAll('shade-app-bar-link')
|
|
247
245
|
expect(links[0]?.hasAttribute('data-active')).toBe(false)
|
|
@@ -267,7 +265,7 @@ describe('AppBarLink component', () => {
|
|
|
267
265
|
),
|
|
268
266
|
})
|
|
269
267
|
|
|
270
|
-
await
|
|
268
|
+
await flushUpdates()
|
|
271
269
|
|
|
272
270
|
const links = document.querySelectorAll('shade-app-bar-link')
|
|
273
271
|
expect(links[0]?.hasAttribute('data-active')).toBe(true)
|
|
@@ -277,7 +275,6 @@ describe('AppBarLink component', () => {
|
|
|
277
275
|
history.pushState(null, '', '/settings')
|
|
278
276
|
injector.getInstance(LocationService).updateState()
|
|
279
277
|
|
|
280
|
-
await sleepAsync(50)
|
|
281
278
|
await flushUpdates()
|
|
282
279
|
|
|
283
280
|
expect(links[0]?.hasAttribute('data-active')).toBe(false)
|
|
@@ -297,7 +294,7 @@ describe('AppBarLink component', () => {
|
|
|
297
294
|
jsxElement: <AppBarLink href="/test">Link</AppBarLink>,
|
|
298
295
|
})
|
|
299
296
|
|
|
300
|
-
await
|
|
297
|
+
await flushUpdates()
|
|
301
298
|
|
|
302
299
|
const appBarLink = document.querySelector('shade-app-bar-link') as HTMLElement
|
|
303
300
|
const computedStyle = window.getComputedStyle(appBarLink)
|
|
@@ -315,7 +312,7 @@ describe('AppBarLink component', () => {
|
|
|
315
312
|
jsxElement: <AppBarLink href="/test">Link</AppBarLink>,
|
|
316
313
|
})
|
|
317
314
|
|
|
318
|
-
await
|
|
315
|
+
await flushUpdates()
|
|
319
316
|
|
|
320
317
|
const appBarLink = document.querySelector('shade-app-bar-link') as HTMLElement
|
|
321
318
|
const computedStyle = window.getComputedStyle(appBarLink)
|
|
@@ -333,7 +330,7 @@ describe('AppBarLink component', () => {
|
|
|
333
330
|
jsxElement: <AppBarLink href="/test">Link</AppBarLink>,
|
|
334
331
|
})
|
|
335
332
|
|
|
336
|
-
await
|
|
333
|
+
await flushUpdates()
|
|
337
334
|
|
|
338
335
|
const appBarLink = document.querySelector('shade-app-bar-link') as HTMLElement
|
|
339
336
|
const computedStyle = window.getComputedStyle(appBarLink)
|
|
@@ -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 { AppBar } from './app-bar.js'
|
|
6
6
|
|
|
@@ -23,7 +23,9 @@ describe('AppBar component', () => {
|
|
|
23
23
|
jsxElement: <AppBar>{children}</AppBar>,
|
|
24
24
|
})
|
|
25
25
|
|
|
26
|
-
await
|
|
26
|
+
await flushUpdates()
|
|
27
|
+
await new Promise((resolve) => requestAnimationFrame(resolve))
|
|
28
|
+
await flushUpdates()
|
|
27
29
|
|
|
28
30
|
return {
|
|
29
31
|
injector,
|
|
@@ -63,7 +65,7 @@ describe('AppBar component', () => {
|
|
|
63
65
|
),
|
|
64
66
|
})
|
|
65
67
|
|
|
66
|
-
await
|
|
68
|
+
await flushUpdates()
|
|
67
69
|
|
|
68
70
|
const appBar = document.querySelector('shade-app-bar')
|
|
69
71
|
expect(appBar).not.toBeNull()
|
|
@@ -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 { Avatar } from './avatar.js'
|
|
6
6
|
|
|
@@ -24,7 +24,7 @@ describe('Avatar component', () => {
|
|
|
24
24
|
jsxElement: <Avatar avatarUrl={testUrl} />,
|
|
25
25
|
})
|
|
26
26
|
|
|
27
|
-
await
|
|
27
|
+
await flushUpdates()
|
|
28
28
|
|
|
29
29
|
const avatar = document.querySelector('shade-avatar')
|
|
30
30
|
expect(avatar).not.toBeNull()
|
|
@@ -46,7 +46,7 @@ describe('Avatar component', () => {
|
|
|
46
46
|
jsxElement: <Avatar avatarUrl="invalid-url" />,
|
|
47
47
|
})
|
|
48
48
|
|
|
49
|
-
await
|
|
49
|
+
await flushUpdates()
|
|
50
50
|
|
|
51
51
|
const avatar = document.querySelector('shade-avatar')
|
|
52
52
|
expect(avatar).not.toBeNull()
|
|
@@ -58,7 +58,7 @@ describe('Avatar component', () => {
|
|
|
58
58
|
const errorEvent = new Event('error')
|
|
59
59
|
img?.dispatchEvent(errorEvent)
|
|
60
60
|
|
|
61
|
-
await
|
|
61
|
+
await flushUpdates()
|
|
62
62
|
|
|
63
63
|
// After error, img should be replaced with fallback div
|
|
64
64
|
const fallbackImg = avatar?.querySelector('img')
|
|
@@ -81,7 +81,7 @@ describe('Avatar component', () => {
|
|
|
81
81
|
jsxElement: <Avatar avatarUrl="invalid-url" fallback={customFallback} />,
|
|
82
82
|
})
|
|
83
83
|
|
|
84
|
-
await
|
|
84
|
+
await flushUpdates()
|
|
85
85
|
|
|
86
86
|
const avatar = document.querySelector('shade-avatar')
|
|
87
87
|
expect(avatar).not.toBeNull()
|
|
@@ -93,7 +93,7 @@ describe('Avatar component', () => {
|
|
|
93
93
|
const errorEvent = new Event('error')
|
|
94
94
|
img?.dispatchEvent(errorEvent)
|
|
95
95
|
|
|
96
|
-
await
|
|
96
|
+
await flushUpdates()
|
|
97
97
|
|
|
98
98
|
// After error, img should be replaced with fallback div
|
|
99
99
|
const fallbackImg = avatar?.querySelector('img')
|
|
@@ -116,7 +116,7 @@ describe('Avatar component', () => {
|
|
|
116
116
|
jsxElement: <Avatar avatarUrl="https://example.com/avatar.png" style={{ width: '64px', height: '64px' }} />,
|
|
117
117
|
})
|
|
118
118
|
|
|
119
|
-
await
|
|
119
|
+
await flushUpdates()
|
|
120
120
|
|
|
121
121
|
const avatar = document.querySelector('shade-avatar') as HTMLElement
|
|
122
122
|
expect(avatar).not.toBeNull()
|
|
@@ -135,7 +135,7 @@ describe('Avatar component', () => {
|
|
|
135
135
|
jsxElement: <Avatar avatarUrl="https://example.com/avatar.png" className="custom-avatar" title="User Avatar" />,
|
|
136
136
|
})
|
|
137
137
|
|
|
138
|
-
await
|
|
138
|
+
await flushUpdates()
|
|
139
139
|
|
|
140
140
|
const avatar = document.querySelector('shade-avatar') as HTMLElement
|
|
141
141
|
expect(avatar).not.toBeNull()
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Injector } from '@furystack/inject'
|
|
2
2
|
import { createComponent, flushUpdates, initializeShadeRoot, LocationService } from '@furystack/shades'
|
|
3
3
|
import type { ExtractRouteParams, NestedRoute } from '@furystack/shades'
|
|
4
|
-
import {
|
|
4
|
+
import { usingAsync } from '@furystack/utils'
|
|
5
5
|
import { afterEach, beforeEach, describe, expect, expectTypeOf, it, vi } from 'vitest'
|
|
6
6
|
import type { BreadcrumbItem, TypedBreadcrumbProps } from './breadcrumb.js'
|
|
7
7
|
import { Breadcrumb, createBreadcrumb } from './breadcrumb.js'
|
|
@@ -247,7 +247,7 @@ describe('Breadcrumb', () => {
|
|
|
247
247
|
),
|
|
248
248
|
})
|
|
249
249
|
|
|
250
|
-
await
|
|
250
|
+
await flushUpdates()
|
|
251
251
|
|
|
252
252
|
const breadcrumb = rootElement.querySelector('nav[is="shade-breadcrumb"]')
|
|
253
253
|
expect(breadcrumb?.classList.contains('custom-breadcrumb')).toBe(true)
|
|
@@ -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, vi } from 'vitest'
|
|
5
5
|
import {
|
|
6
6
|
ButtonGroup,
|
|
@@ -28,7 +28,7 @@ describe('ButtonGroup', () => {
|
|
|
28
28
|
rootElement: root,
|
|
29
29
|
jsxElement: <ButtonGroup {...props}>{children}</ButtonGroup>,
|
|
30
30
|
})
|
|
31
|
-
await
|
|
31
|
+
await flushUpdates()
|
|
32
32
|
return {
|
|
33
33
|
injector,
|
|
34
34
|
group: root.querySelector('shade-button-group') as HTMLElement,
|
|
@@ -132,6 +132,78 @@ describe('ButtonGroup', () => {
|
|
|
132
132
|
})
|
|
133
133
|
})
|
|
134
134
|
|
|
135
|
+
describe('ToggleButton', () => {
|
|
136
|
+
beforeEach(() => {
|
|
137
|
+
document.body.innerHTML = '<div id="root"></div>'
|
|
138
|
+
})
|
|
139
|
+
|
|
140
|
+
afterEach(() => {
|
|
141
|
+
document.body.innerHTML = ''
|
|
142
|
+
})
|
|
143
|
+
|
|
144
|
+
const renderToggleButton = async (props: Parameters<typeof ToggleButton>[0]) => {
|
|
145
|
+
const injector = new Injector()
|
|
146
|
+
const root = document.getElementById('root')!
|
|
147
|
+
initializeShadeRoot({
|
|
148
|
+
injector,
|
|
149
|
+
rootElement: root,
|
|
150
|
+
jsxElement: <ToggleButton {...props}>Label</ToggleButton>,
|
|
151
|
+
})
|
|
152
|
+
await flushUpdates()
|
|
153
|
+
return {
|
|
154
|
+
injector,
|
|
155
|
+
button: root.querySelector('button[is="shade-toggle-button"]') as HTMLButtonElement,
|
|
156
|
+
[Symbol.asyncDispose]: () => injector[Symbol.asyncDispose](),
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
describe('pressed', () => {
|
|
161
|
+
it('should not set data-selected when pressed is not specified', async () => {
|
|
162
|
+
await usingAsync(await renderToggleButton({ value: 'a' }), async ({ button }) => {
|
|
163
|
+
expect(button.hasAttribute('data-selected')).toBe(false)
|
|
164
|
+
})
|
|
165
|
+
})
|
|
166
|
+
|
|
167
|
+
it('should set data-selected when pressed is true', async () => {
|
|
168
|
+
await usingAsync(await renderToggleButton({ value: 'a', pressed: true }), async ({ button }) => {
|
|
169
|
+
expect(button.hasAttribute('data-selected')).toBe(true)
|
|
170
|
+
})
|
|
171
|
+
})
|
|
172
|
+
|
|
173
|
+
it('should not set data-selected when pressed is false', async () => {
|
|
174
|
+
await usingAsync(await renderToggleButton({ value: 'a', pressed: false }), async ({ button }) => {
|
|
175
|
+
expect(button.hasAttribute('data-selected')).toBe(false)
|
|
176
|
+
})
|
|
177
|
+
})
|
|
178
|
+
})
|
|
179
|
+
|
|
180
|
+
describe('size', () => {
|
|
181
|
+
it('should not set data-size by default', async () => {
|
|
182
|
+
await usingAsync(await renderToggleButton({ value: 'a' }), async ({ button }) => {
|
|
183
|
+
expect(button.hasAttribute('data-size')).toBe(false)
|
|
184
|
+
})
|
|
185
|
+
})
|
|
186
|
+
|
|
187
|
+
it('should not set data-size for medium (default)', async () => {
|
|
188
|
+
await usingAsync(await renderToggleButton({ value: 'a', size: 'medium' }), async ({ button }) => {
|
|
189
|
+
expect(button.hasAttribute('data-size')).toBe(false)
|
|
190
|
+
})
|
|
191
|
+
})
|
|
192
|
+
|
|
193
|
+
it('should set data-size="small" for small size', async () => {
|
|
194
|
+
await usingAsync(await renderToggleButton({ value: 'a', size: 'small' }), async ({ button }) => {
|
|
195
|
+
expect(button.getAttribute('data-size')).toBe('small')
|
|
196
|
+
})
|
|
197
|
+
})
|
|
198
|
+
|
|
199
|
+
it('should set data-size="large" for large size', async () => {
|
|
200
|
+
await usingAsync(await renderToggleButton({ value: 'a', size: 'large' }), async ({ button }) => {
|
|
201
|
+
expect(button.getAttribute('data-size')).toBe('large')
|
|
202
|
+
})
|
|
203
|
+
})
|
|
204
|
+
})
|
|
205
|
+
})
|
|
206
|
+
|
|
135
207
|
describe('ToggleButtonGroup', () => {
|
|
136
208
|
beforeEach(() => {
|
|
137
209
|
document.body.innerHTML = '<div id="root"></div>'
|
|
@@ -149,7 +221,7 @@ describe('ToggleButtonGroup', () => {
|
|
|
149
221
|
rootElement: root,
|
|
150
222
|
jsxElement: <ToggleButtonGroup {...props}>{children}</ToggleButtonGroup>,
|
|
151
223
|
})
|
|
152
|
-
await
|
|
224
|
+
await flushUpdates()
|
|
153
225
|
return {
|
|
154
226
|
injector,
|
|
155
227
|
group: root.querySelector('shade-toggle-button-group') as HTMLElement,
|
|
@@ -257,8 +329,8 @@ describe('ToggleButtonGroup', () => {
|
|
|
257
329
|
<ToggleButton value="right">Right</ToggleButton>,
|
|
258
330
|
] as unknown as JSX.Element[]),
|
|
259
331
|
async ({ group }) => {
|
|
260
|
-
|
|
261
|
-
await
|
|
332
|
+
await flushUpdates()
|
|
333
|
+
await new Promise<void>((resolve) => requestAnimationFrame(() => resolve()))
|
|
262
334
|
const centerBtn = group.querySelector('button[data-value="center"]') as HTMLButtonElement
|
|
263
335
|
const leftBtn = group.querySelector('button[data-value="left"]') as HTMLButtonElement
|
|
264
336
|
expect(centerBtn.hasAttribute('data-selected')).toBe(true)
|
|
@@ -275,7 +347,8 @@ describe('ToggleButtonGroup', () => {
|
|
|
275
347
|
<ToggleButton value="underline">U</ToggleButton>,
|
|
276
348
|
] as unknown as JSX.Element[]),
|
|
277
349
|
async ({ group }) => {
|
|
278
|
-
await
|
|
350
|
+
await flushUpdates()
|
|
351
|
+
await new Promise<void>((resolve) => requestAnimationFrame(() => resolve()))
|
|
279
352
|
const boldBtn = group.querySelector('button[data-value="bold"]') as HTMLButtonElement
|
|
280
353
|
const italicBtn = group.querySelector('button[data-value="italic"]') as HTMLButtonElement
|
|
281
354
|
const underlineBtn = group.querySelector('button[data-value="underline"]') as HTMLButtonElement
|
|
@@ -314,6 +387,75 @@ describe('ToggleButtonGroup', () => {
|
|
|
314
387
|
})
|
|
315
388
|
})
|
|
316
389
|
})
|
|
390
|
+
|
|
391
|
+
describe('size', () => {
|
|
392
|
+
it('should not set data-size on children by default', async () => {
|
|
393
|
+
await usingAsync(
|
|
394
|
+
await renderToggleGroup({}, [
|
|
395
|
+
<ToggleButton value="a">A</ToggleButton>,
|
|
396
|
+
<ToggleButton value="b">B</ToggleButton>,
|
|
397
|
+
] as unknown as JSX.Element[]),
|
|
398
|
+
async ({ group }) => {
|
|
399
|
+
await flushUpdates()
|
|
400
|
+
await new Promise<void>((resolve) => requestAnimationFrame(() => resolve()))
|
|
401
|
+
const buttons = group.querySelectorAll('button[data-value]')
|
|
402
|
+
buttons.forEach((btn) => {
|
|
403
|
+
expect(btn.hasAttribute('data-size')).toBe(false)
|
|
404
|
+
})
|
|
405
|
+
},
|
|
406
|
+
)
|
|
407
|
+
})
|
|
408
|
+
|
|
409
|
+
it('should propagate size="small" to child buttons', async () => {
|
|
410
|
+
await usingAsync(
|
|
411
|
+
await renderToggleGroup({ size: 'small' }, [
|
|
412
|
+
<ToggleButton value="a">A</ToggleButton>,
|
|
413
|
+
<ToggleButton value="b">B</ToggleButton>,
|
|
414
|
+
] as unknown as JSX.Element[]),
|
|
415
|
+
async ({ group }) => {
|
|
416
|
+
await flushUpdates()
|
|
417
|
+
await new Promise<void>((resolve) => requestAnimationFrame(() => resolve()))
|
|
418
|
+
const buttons = group.querySelectorAll('button[data-value]')
|
|
419
|
+
buttons.forEach((btn) => {
|
|
420
|
+
expect(btn.getAttribute('data-size')).toBe('small')
|
|
421
|
+
})
|
|
422
|
+
},
|
|
423
|
+
)
|
|
424
|
+
})
|
|
425
|
+
|
|
426
|
+
it('should propagate size="large" to child buttons', async () => {
|
|
427
|
+
await usingAsync(
|
|
428
|
+
await renderToggleGroup({ size: 'large' }, [
|
|
429
|
+
<ToggleButton value="a">A</ToggleButton>,
|
|
430
|
+
<ToggleButton value="b">B</ToggleButton>,
|
|
431
|
+
] as unknown as JSX.Element[]),
|
|
432
|
+
async ({ group }) => {
|
|
433
|
+
await flushUpdates()
|
|
434
|
+
await new Promise<void>((resolve) => requestAnimationFrame(() => resolve()))
|
|
435
|
+
const buttons = group.querySelectorAll('button[data-value]')
|
|
436
|
+
buttons.forEach((btn) => {
|
|
437
|
+
expect(btn.getAttribute('data-size')).toBe('large')
|
|
438
|
+
})
|
|
439
|
+
},
|
|
440
|
+
)
|
|
441
|
+
})
|
|
442
|
+
|
|
443
|
+
it('should remove data-size when size is medium', async () => {
|
|
444
|
+
await usingAsync(
|
|
445
|
+
await renderToggleGroup({ size: 'medium' }, [
|
|
446
|
+
<ToggleButton value="a" size="small">
|
|
447
|
+
A
|
|
448
|
+
</ToggleButton>,
|
|
449
|
+
] as unknown as JSX.Element[]),
|
|
450
|
+
async ({ group }) => {
|
|
451
|
+
await flushUpdates()
|
|
452
|
+
await new Promise<void>((resolve) => requestAnimationFrame(() => resolve()))
|
|
453
|
+
const btn = group.querySelector('button[data-value]')
|
|
454
|
+
expect(btn?.hasAttribute('data-size')).toBe(false)
|
|
455
|
+
},
|
|
456
|
+
)
|
|
457
|
+
})
|
|
458
|
+
})
|
|
317
459
|
})
|
|
318
460
|
|
|
319
461
|
describe('SegmentedControl', () => {
|
|
@@ -339,7 +481,7 @@ describe('SegmentedControl', () => {
|
|
|
339
481
|
rootElement: root,
|
|
340
482
|
jsxElement: <SegmentedControl options={defaultOptions} {...props} />,
|
|
341
483
|
})
|
|
342
|
-
await
|
|
484
|
+
await flushUpdates()
|
|
343
485
|
return {
|
|
344
486
|
injector,
|
|
345
487
|
control: root.querySelector('shade-segmented-control') as HTMLElement,
|
|
@@ -502,7 +644,7 @@ describe('ToggleButtonGroup edge cases', () => {
|
|
|
502
644
|
rootElement: root,
|
|
503
645
|
jsxElement: <ToggleButtonGroup {...props}>{children}</ToggleButtonGroup>,
|
|
504
646
|
})
|
|
505
|
-
await
|
|
647
|
+
await flushUpdates()
|
|
506
648
|
return {
|
|
507
649
|
injector,
|
|
508
650
|
group: root.querySelector('shade-toggle-button-group') as HTMLElement,
|
|
@@ -577,7 +719,8 @@ describe('ToggleButtonGroup edge cases', () => {
|
|
|
577
719
|
<ToggleButton value="b">B</ToggleButton>,
|
|
578
720
|
] as unknown as JSX.Element[]),
|
|
579
721
|
async ({ group }) => {
|
|
580
|
-
await
|
|
722
|
+
await flushUpdates()
|
|
723
|
+
await new Promise<void>((resolve) => requestAnimationFrame(() => resolve()))
|
|
581
724
|
const buttons = group.querySelectorAll('button[data-value]')
|
|
582
725
|
buttons.forEach((btn) => {
|
|
583
726
|
expect(btn.hasAttribute('disabled')).toBe(true)
|
|
@@ -593,7 +736,8 @@ describe('ToggleButtonGroup edge cases', () => {
|
|
|
593
736
|
<ToggleButton value="b">B</ToggleButton>,
|
|
594
737
|
] as unknown as JSX.Element[]),
|
|
595
738
|
async ({ group }) => {
|
|
596
|
-
await
|
|
739
|
+
await flushUpdates()
|
|
740
|
+
await new Promise<void>((resolve) => requestAnimationFrame(() => resolve()))
|
|
597
741
|
const buttons = group.querySelectorAll('button[data-value]')
|
|
598
742
|
// First button should have top radius
|
|
599
743
|
expect((buttons[0] as HTMLElement).style.borderRadius).toContain('0 0')
|
|
@@ -89,6 +89,19 @@ export type ToggleButtonProps = PartialElement<HTMLButtonElement> & {
|
|
|
89
89
|
value: string
|
|
90
90
|
/** Whether the button is disabled */
|
|
91
91
|
disabled?: boolean
|
|
92
|
+
/**
|
|
93
|
+
* The size of the toggle button.
|
|
94
|
+
* @default 'medium'
|
|
95
|
+
*/
|
|
96
|
+
size?: 'small' | 'medium' | 'large'
|
|
97
|
+
/**
|
|
98
|
+
* Whether the button is in a pressed (selected) state.
|
|
99
|
+
* Use this for standalone toggle buttons or controlled state.
|
|
100
|
+
* When used inside a `ToggleButtonGroup`, the group manages the
|
|
101
|
+
* pressed state automatically via its `value` prop and will
|
|
102
|
+
* override this attribute.
|
|
103
|
+
*/
|
|
104
|
+
pressed?: boolean
|
|
92
105
|
}
|
|
93
106
|
|
|
94
107
|
export const ToggleButton = Shade<ToggleButtonProps>({
|
|
@@ -111,13 +124,17 @@ export const ToggleButton = Shade<ToggleButtonProps>({
|
|
|
111
124
|
userSelect: 'none',
|
|
112
125
|
background: 'transparent',
|
|
113
126
|
color: 'var(--toggle-color-main)',
|
|
114
|
-
boxShadow: '
|
|
127
|
+
boxShadow: 'none',
|
|
115
128
|
transition: buildTransition(
|
|
116
129
|
['background', cssVariableTheme.transitions.duration.normal, cssVariableTheme.transitions.easing.default],
|
|
117
130
|
['color', cssVariableTheme.transitions.duration.normal, cssVariableTheme.transitions.easing.default],
|
|
118
131
|
['box-shadow', cssVariableTheme.transitions.duration.normal, cssVariableTheme.transitions.easing.default],
|
|
119
132
|
),
|
|
120
133
|
|
|
134
|
+
'&[data-grouped]': {
|
|
135
|
+
boxShadow: '0px 0px 0px 1px var(--toggle-color-main)',
|
|
136
|
+
},
|
|
137
|
+
|
|
121
138
|
'&:hover:not(:disabled):not([data-selected])': {
|
|
122
139
|
background: 'color-mix(in srgb, var(--toggle-color-main) 10%, transparent)',
|
|
123
140
|
},
|
|
@@ -140,11 +157,27 @@ export const ToggleButton = Shade<ToggleButtonProps>({
|
|
|
140
157
|
'&:active:not(:disabled)': {
|
|
141
158
|
transform: 'scale(0.96)',
|
|
142
159
|
},
|
|
160
|
+
|
|
161
|
+
'&[data-size="small"]': {
|
|
162
|
+
padding: `${cssVariableTheme.spacing.xs} ${cssVariableTheme.spacing.sm}`,
|
|
163
|
+
fontSize: cssVariableTheme.typography.fontSize.sm,
|
|
164
|
+
},
|
|
165
|
+
|
|
166
|
+
'&[data-size="large"]': {
|
|
167
|
+
padding: `${cssVariableTheme.spacing.md} ${cssVariableTheme.spacing.xl}`,
|
|
168
|
+
fontSize: cssVariableTheme.typography.fontSize.lg,
|
|
169
|
+
},
|
|
143
170
|
},
|
|
144
171
|
render: ({ props, children, useHostProps }) => {
|
|
145
172
|
useHostProps({
|
|
146
173
|
'data-value': props.value || undefined,
|
|
174
|
+
'data-size': props.size && props.size !== 'medium' ? props.size : undefined,
|
|
175
|
+
'data-selected': props.pressed ? '' : undefined,
|
|
147
176
|
type: 'button',
|
|
177
|
+
style: {
|
|
178
|
+
'--toggle-color-main': cssVariableTheme.text.secondary,
|
|
179
|
+
...(props.style as Record<string, string>),
|
|
180
|
+
},
|
|
148
181
|
})
|
|
149
182
|
|
|
150
183
|
return <>{children}</>
|
|
@@ -171,6 +204,12 @@ export type ToggleButtonGroupProps = PartialElement<HTMLElement> & {
|
|
|
171
204
|
orientation?: 'horizontal' | 'vertical'
|
|
172
205
|
/** Whether all toggle buttons are disabled */
|
|
173
206
|
disabled?: boolean
|
|
207
|
+
/**
|
|
208
|
+
* Size applied to all toggle buttons in the group.
|
|
209
|
+
* Individual ToggleButton `size` props are overridden by this value.
|
|
210
|
+
* @default 'medium'
|
|
211
|
+
*/
|
|
212
|
+
size?: 'small' | 'medium' | 'large'
|
|
174
213
|
}
|
|
175
214
|
|
|
176
215
|
export const ToggleButtonGroup: (props: ToggleButtonGroupProps, children: ChildrenList) => JSX.Element =
|
|
@@ -228,7 +267,7 @@ export const ToggleButtonGroup: (props: ToggleButtonGroupProps, children: Childr
|
|
|
228
267
|
return { [Symbol.dispose]: () => el?.removeEventListener('click', handleClick) }
|
|
229
268
|
})
|
|
230
269
|
|
|
231
|
-
const { orientation = 'horizontal', disabled, color, style } = props
|
|
270
|
+
const { orientation = 'horizontal', disabled, color, size, style } = props
|
|
232
271
|
const selectedValues = Array.isArray(props.value) ? props.value : props.value ? [props.value] : ([] as string[])
|
|
233
272
|
|
|
234
273
|
const colors = color ? paletteFullColors[color] : defaultToggleColors
|
|
@@ -256,10 +295,18 @@ export const ToggleButtonGroup: (props: ToggleButtonGroupProps, children: Childr
|
|
|
256
295
|
btn.removeAttribute('data-selected')
|
|
257
296
|
}
|
|
258
297
|
|
|
298
|
+
btn.setAttribute('data-grouped', '')
|
|
299
|
+
|
|
259
300
|
if (disabled) {
|
|
260
301
|
btn.setAttribute('disabled', '')
|
|
261
302
|
}
|
|
262
303
|
|
|
304
|
+
if (size && size !== 'medium') {
|
|
305
|
+
btn.setAttribute('data-size', size)
|
|
306
|
+
} else if (size === 'medium') {
|
|
307
|
+
btn.removeAttribute('data-size')
|
|
308
|
+
}
|
|
309
|
+
|
|
263
310
|
// Propagate color CSS variable
|
|
264
311
|
;(btn as HTMLElement).style.setProperty('--toggle-color-main', colors.main)
|
|
265
312
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Injector } from '@furystack/inject'
|
|
2
|
-
import { createComponent, initializeShadeRoot, Shade } from '@furystack/shades'
|
|
3
|
-
import {
|
|
2
|
+
import { createComponent, flushUpdates, initializeShadeRoot, Shade } from '@furystack/shades'
|
|
3
|
+
import { usingAsync } from '@furystack/utils'
|
|
4
4
|
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'
|
|
5
5
|
import { Button } from './button.js'
|
|
6
6
|
|
|
@@ -22,7 +22,7 @@ describe('Button', () => {
|
|
|
22
22
|
rootElement: root,
|
|
23
23
|
jsxElement: <Button {...props}>{children}</Button>,
|
|
24
24
|
})
|
|
25
|
-
await
|
|
25
|
+
await flushUpdates()
|
|
26
26
|
return {
|
|
27
27
|
injector,
|
|
28
28
|
button: root.querySelector('button[is="shade-button"]') as HTMLButtonElement,
|
|
@@ -86,7 +86,7 @@ describe('Button', () => {
|
|
|
86
86
|
jsxElement: <TestComponent variant="contained" />,
|
|
87
87
|
})
|
|
88
88
|
|
|
89
|
-
await
|
|
89
|
+
await flushUpdates()
|
|
90
90
|
const button = root.querySelector('button[is="shade-button"]') as HTMLButtonElement
|
|
91
91
|
expect(button.getAttribute('data-variant')).toBe('contained')
|
|
92
92
|
})
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Cache } from '@furystack/cache'
|
|
2
2
|
import type { CacheResult, CacheWithValue } from '@furystack/cache'
|
|
3
3
|
import { Shade, createComponent, flushUpdates } from '@furystack/shades'
|
|
4
|
-
|
|
4
|
+
|
|
5
5
|
import { describe, expect, it, vi } from 'vitest'
|
|
6
6
|
import { CacheView } from './cache-view.js'
|
|
7
7
|
|
|
@@ -162,7 +162,7 @@ describe('CacheView', () => {
|
|
|
162
162
|
|
|
163
163
|
loadFn.mockResolvedValueOnce('recovered')
|
|
164
164
|
capturedRetry!()
|
|
165
|
-
await
|
|
165
|
+
await flushUpdates()
|
|
166
166
|
|
|
167
167
|
const observable = cache.getObservable('test')
|
|
168
168
|
const result = observable.getValue()
|
|
@@ -183,7 +183,7 @@ describe('CacheView', () => {
|
|
|
183
183
|
const contentEl = cacheView.querySelector('test-cache-content')
|
|
184
184
|
expect(contentEl).not.toBeNull()
|
|
185
185
|
|
|
186
|
-
await
|
|
186
|
+
await flushUpdates()
|
|
187
187
|
// reload should have been called (initial load + obsolete reload)
|
|
188
188
|
expect(loadFn).toHaveBeenCalledTimes(2)
|
|
189
189
|
cache[Symbol.dispose]()
|