@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,7 +1,7 @@
|
|
|
1
1
|
import type { FindOptions } from '@furystack/core'
|
|
2
2
|
import { Injector } from '@furystack/inject'
|
|
3
|
-
import { createComponent, initializeShadeRoot } from '@furystack/shades'
|
|
4
|
-
import { ObservableValue,
|
|
3
|
+
import { createComponent, flushUpdates, initializeShadeRoot } from '@furystack/shades'
|
|
4
|
+
import { ObservableValue, usingAsync } from '@furystack/utils'
|
|
5
5
|
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'
|
|
6
6
|
import { CollectionService } from '../../services/collection-service.js'
|
|
7
7
|
import { DataGrid } from './data-grid.js'
|
|
@@ -70,7 +70,7 @@ describe('DataGrid', () => {
|
|
|
70
70
|
),
|
|
71
71
|
})
|
|
72
72
|
|
|
73
|
-
await
|
|
73
|
+
await flushUpdates()
|
|
74
74
|
|
|
75
75
|
const grid = document.querySelector('shade-data-grid')
|
|
76
76
|
expect(grid).not.toBeNull()
|
|
@@ -99,7 +99,7 @@ describe('DataGrid', () => {
|
|
|
99
99
|
),
|
|
100
100
|
})
|
|
101
101
|
|
|
102
|
-
await
|
|
102
|
+
await flushUpdates()
|
|
103
103
|
|
|
104
104
|
const grid = document.querySelector('shade-data-grid')
|
|
105
105
|
const table = grid?.querySelector('table')
|
|
@@ -133,7 +133,7 @@ describe('DataGrid', () => {
|
|
|
133
133
|
),
|
|
134
134
|
})
|
|
135
135
|
|
|
136
|
-
await
|
|
136
|
+
await flushUpdates()
|
|
137
137
|
|
|
138
138
|
const grid = document.querySelector('shade-data-grid')
|
|
139
139
|
const customHeader = grid?.querySelector('[data-testid="custom-header-id"]')
|
|
@@ -163,7 +163,7 @@ describe('DataGrid', () => {
|
|
|
163
163
|
),
|
|
164
164
|
})
|
|
165
165
|
|
|
166
|
-
await
|
|
166
|
+
await flushUpdates()
|
|
167
167
|
|
|
168
168
|
const grid = document.querySelector('shade-data-grid')
|
|
169
169
|
const defaultHeaderId = grid?.querySelector('[data-testid="default-header-id"]')
|
|
@@ -193,13 +193,91 @@ describe('DataGrid', () => {
|
|
|
193
193
|
),
|
|
194
194
|
})
|
|
195
195
|
|
|
196
|
-
await
|
|
196
|
+
await flushUpdates()
|
|
197
197
|
|
|
198
198
|
const grid = document.querySelector('shade-data-grid')
|
|
199
199
|
const defaultHeaders = grid?.querySelectorAll('data-grid-header')
|
|
200
200
|
expect(defaultHeaders?.length).toBe(2)
|
|
201
201
|
})
|
|
202
202
|
})
|
|
203
|
+
|
|
204
|
+
it('should render filter buttons when columnFilters are provided', async () => {
|
|
205
|
+
await withTestGrid(async ({ injector, service, findOptions }) => {
|
|
206
|
+
const rootElement = document.getElementById('root') as HTMLDivElement
|
|
207
|
+
|
|
208
|
+
initializeShadeRoot({
|
|
209
|
+
injector,
|
|
210
|
+
rootElement,
|
|
211
|
+
jsxElement: (
|
|
212
|
+
<DataGrid<TestEntry, 'id' | 'name'>
|
|
213
|
+
columns={['id', 'name']}
|
|
214
|
+
collectionService={service}
|
|
215
|
+
findOptions={findOptions}
|
|
216
|
+
styles={{}}
|
|
217
|
+
columnFilters={{ name: { type: 'string' } }}
|
|
218
|
+
/>
|
|
219
|
+
),
|
|
220
|
+
})
|
|
221
|
+
|
|
222
|
+
await flushUpdates()
|
|
223
|
+
|
|
224
|
+
const grid = document.querySelector('shade-data-grid')
|
|
225
|
+
const filterButtons = grid?.querySelectorAll('data-grid-filter-button')
|
|
226
|
+
expect(filterButtons?.length).toBe(1)
|
|
227
|
+
})
|
|
228
|
+
})
|
|
229
|
+
|
|
230
|
+
it('should not render filter buttons when columnFilters is not provided', async () => {
|
|
231
|
+
await withTestGrid(async ({ injector, service, findOptions }) => {
|
|
232
|
+
const rootElement = document.getElementById('root') as HTMLDivElement
|
|
233
|
+
|
|
234
|
+
initializeShadeRoot({
|
|
235
|
+
injector,
|
|
236
|
+
rootElement,
|
|
237
|
+
jsxElement: (
|
|
238
|
+
<DataGrid<TestEntry, 'id' | 'name'>
|
|
239
|
+
columns={['id', 'name']}
|
|
240
|
+
collectionService={service}
|
|
241
|
+
findOptions={findOptions}
|
|
242
|
+
styles={{}}
|
|
243
|
+
/>
|
|
244
|
+
),
|
|
245
|
+
})
|
|
246
|
+
|
|
247
|
+
await flushUpdates()
|
|
248
|
+
|
|
249
|
+
const grid = document.querySelector('shade-data-grid')
|
|
250
|
+
const filterButtons = grid?.querySelectorAll('data-grid-filter-button')
|
|
251
|
+
expect(filterButtons?.length).toBe(0)
|
|
252
|
+
})
|
|
253
|
+
})
|
|
254
|
+
|
|
255
|
+
it('should render without headerComponents and rowComponents', async () => {
|
|
256
|
+
await withTestGrid(async ({ injector, service, findOptions }) => {
|
|
257
|
+
const rootElement = document.getElementById('root') as HTMLDivElement
|
|
258
|
+
|
|
259
|
+
initializeShadeRoot({
|
|
260
|
+
injector,
|
|
261
|
+
rootElement,
|
|
262
|
+
jsxElement: (
|
|
263
|
+
<DataGrid<TestEntry, 'id' | 'name'>
|
|
264
|
+
columns={['id', 'name']}
|
|
265
|
+
collectionService={service}
|
|
266
|
+
findOptions={findOptions}
|
|
267
|
+
styles={{}}
|
|
268
|
+
/>
|
|
269
|
+
),
|
|
270
|
+
})
|
|
271
|
+
|
|
272
|
+
await flushUpdates()
|
|
273
|
+
|
|
274
|
+
const grid = document.querySelector('shade-data-grid')
|
|
275
|
+
expect(grid).not.toBeNull()
|
|
276
|
+
|
|
277
|
+
const headers = grid?.querySelectorAll('data-grid-header')
|
|
278
|
+
expect(headers?.length).toBe(2)
|
|
279
|
+
})
|
|
280
|
+
})
|
|
203
281
|
})
|
|
204
282
|
|
|
205
283
|
describe('focus management', () => {
|
|
@@ -224,7 +302,7 @@ describe('DataGrid', () => {
|
|
|
224
302
|
),
|
|
225
303
|
})
|
|
226
304
|
|
|
227
|
-
await
|
|
305
|
+
await flushUpdates()
|
|
228
306
|
|
|
229
307
|
const grid = document.querySelector('shade-data-grid')
|
|
230
308
|
const wrapper = grid?.querySelector('.shade-grid-wrapper') as HTMLElement
|
|
@@ -257,7 +335,7 @@ describe('DataGrid', () => {
|
|
|
257
335
|
),
|
|
258
336
|
})
|
|
259
337
|
|
|
260
|
-
await
|
|
338
|
+
await flushUpdates()
|
|
261
339
|
|
|
262
340
|
const grid = document.querySelector('shade-data-grid')
|
|
263
341
|
const wrapper = grid?.querySelector('.shade-grid-wrapper') as HTMLElement
|
|
@@ -296,7 +374,7 @@ describe('DataGrid', () => {
|
|
|
296
374
|
),
|
|
297
375
|
})
|
|
298
376
|
|
|
299
|
-
await
|
|
377
|
+
await flushUpdates()
|
|
300
378
|
|
|
301
379
|
const keydownEvent = new KeyboardEvent('keydown', { key: 'ArrowDown', bubbles: true })
|
|
302
380
|
window.dispatchEvent(keydownEvent)
|
|
@@ -327,7 +405,7 @@ describe('DataGrid', () => {
|
|
|
327
405
|
),
|
|
328
406
|
})
|
|
329
407
|
|
|
330
|
-
await
|
|
408
|
+
await flushUpdates()
|
|
331
409
|
|
|
332
410
|
const keydownEvent = new KeyboardEvent('keydown', { key: 'ArrowUp', bubbles: true })
|
|
333
411
|
window.dispatchEvent(keydownEvent)
|
|
@@ -358,7 +436,7 @@ describe('DataGrid', () => {
|
|
|
358
436
|
),
|
|
359
437
|
})
|
|
360
438
|
|
|
361
|
-
await
|
|
439
|
+
await flushUpdates()
|
|
362
440
|
|
|
363
441
|
const keydownEvent = new KeyboardEvent('keydown', { key: 'Home', bubbles: true })
|
|
364
442
|
window.dispatchEvent(keydownEvent)
|
|
@@ -389,7 +467,7 @@ describe('DataGrid', () => {
|
|
|
389
467
|
),
|
|
390
468
|
})
|
|
391
469
|
|
|
392
|
-
await
|
|
470
|
+
await flushUpdates()
|
|
393
471
|
|
|
394
472
|
const keydownEvent = new KeyboardEvent('keydown', { key: 'End', bubbles: true })
|
|
395
473
|
window.dispatchEvent(keydownEvent)
|
|
@@ -419,7 +497,7 @@ describe('DataGrid', () => {
|
|
|
419
497
|
),
|
|
420
498
|
})
|
|
421
499
|
|
|
422
|
-
await
|
|
500
|
+
await flushUpdates()
|
|
423
501
|
|
|
424
502
|
const keydownEvent = new KeyboardEvent('keydown', { key: 'Tab', bubbles: true })
|
|
425
503
|
window.dispatchEvent(keydownEvent)
|
|
@@ -452,7 +530,7 @@ describe('DataGrid', () => {
|
|
|
452
530
|
),
|
|
453
531
|
})
|
|
454
532
|
|
|
455
|
-
await
|
|
533
|
+
await flushUpdates()
|
|
456
534
|
|
|
457
535
|
const keydownEvent = new KeyboardEvent('keydown', { key: 'Escape', bubbles: true })
|
|
458
536
|
window.dispatchEvent(keydownEvent)
|
|
@@ -485,7 +563,7 @@ describe('DataGrid', () => {
|
|
|
485
563
|
),
|
|
486
564
|
})
|
|
487
565
|
|
|
488
|
-
await
|
|
566
|
+
await flushUpdates()
|
|
489
567
|
|
|
490
568
|
const keydownEvent = new KeyboardEvent('keydown', { key: ' ', bubbles: true })
|
|
491
569
|
window.dispatchEvent(keydownEvent)
|
|
@@ -518,7 +596,7 @@ describe('DataGrid', () => {
|
|
|
518
596
|
),
|
|
519
597
|
})
|
|
520
598
|
|
|
521
|
-
await
|
|
599
|
+
await flushUpdates()
|
|
522
600
|
|
|
523
601
|
const keydownEvent = new KeyboardEvent('keydown', { key: '+', bubbles: true })
|
|
524
602
|
window.dispatchEvent(keydownEvent)
|
|
@@ -550,7 +628,7 @@ describe('DataGrid', () => {
|
|
|
550
628
|
),
|
|
551
629
|
})
|
|
552
630
|
|
|
553
|
-
await
|
|
631
|
+
await flushUpdates()
|
|
554
632
|
|
|
555
633
|
const keydownEvent = new KeyboardEvent('keydown', { key: '-', bubbles: true })
|
|
556
634
|
window.dispatchEvent(keydownEvent)
|
|
@@ -582,7 +660,7 @@ describe('DataGrid', () => {
|
|
|
582
660
|
),
|
|
583
661
|
})
|
|
584
662
|
|
|
585
|
-
await
|
|
663
|
+
await flushUpdates()
|
|
586
664
|
|
|
587
665
|
const keydownEvent = new KeyboardEvent('keydown', { key: '*', bubbles: true })
|
|
588
666
|
window.dispatchEvent(keydownEvent)
|
|
@@ -616,7 +694,7 @@ describe('DataGrid', () => {
|
|
|
616
694
|
),
|
|
617
695
|
})
|
|
618
696
|
|
|
619
|
-
await
|
|
697
|
+
await flushUpdates()
|
|
620
698
|
|
|
621
699
|
const keydownEvent = new KeyboardEvent('keydown', { key: 'ArrowDown', bubbles: true })
|
|
622
700
|
window.dispatchEvent(keydownEvent)
|
|
@@ -648,7 +726,7 @@ describe('DataGrid', () => {
|
|
|
648
726
|
),
|
|
649
727
|
})
|
|
650
728
|
|
|
651
|
-
await
|
|
729
|
+
await flushUpdates()
|
|
652
730
|
|
|
653
731
|
const keydownEvent = new KeyboardEvent('keydown', { key: 'Insert', bubbles: true })
|
|
654
732
|
window.dispatchEvent(keydownEvent)
|
|
@@ -681,7 +759,7 @@ describe('DataGrid', () => {
|
|
|
681
759
|
),
|
|
682
760
|
})
|
|
683
761
|
|
|
684
|
-
await
|
|
762
|
+
await flushUpdates()
|
|
685
763
|
|
|
686
764
|
const grid = document.querySelector('shade-data-grid') as HTMLElement
|
|
687
765
|
expect(grid?.style.backgroundColor).toBe('red')
|
|
@@ -709,7 +787,7 @@ describe('DataGrid', () => {
|
|
|
709
787
|
),
|
|
710
788
|
})
|
|
711
789
|
|
|
712
|
-
await
|
|
790
|
+
await flushUpdates()
|
|
713
791
|
|
|
714
792
|
const grid = document.querySelector('shade-data-grid')
|
|
715
793
|
const headers = grid?.querySelectorAll('th') as NodeListOf<HTMLElement>
|
|
@@ -740,7 +818,7 @@ describe('DataGrid', () => {
|
|
|
740
818
|
),
|
|
741
819
|
})
|
|
742
820
|
|
|
743
|
-
await
|
|
821
|
+
await flushUpdates()
|
|
744
822
|
|
|
745
823
|
const grid = document.querySelector('shade-data-grid')
|
|
746
824
|
const emptyState = grid?.querySelector('[data-testid="empty-state"]')
|
|
@@ -779,7 +857,7 @@ describe('DataGrid', () => {
|
|
|
779
857
|
),
|
|
780
858
|
})
|
|
781
859
|
|
|
782
|
-
await
|
|
860
|
+
await flushUpdates()
|
|
783
861
|
|
|
784
862
|
const grid = document.querySelector('shade-data-grid')
|
|
785
863
|
const cell = grid?.querySelector('td') as HTMLTableCellElement
|
|
@@ -817,7 +895,7 @@ describe('DataGrid', () => {
|
|
|
817
895
|
),
|
|
818
896
|
})
|
|
819
897
|
|
|
820
|
-
await
|
|
898
|
+
await flushUpdates()
|
|
821
899
|
|
|
822
900
|
const grid = document.querySelector('shade-data-grid')
|
|
823
901
|
const cell = grid?.querySelector('td') as HTMLTableCellElement
|
|
@@ -854,12 +932,12 @@ describe('DataGrid', () => {
|
|
|
854
932
|
),
|
|
855
933
|
})
|
|
856
934
|
|
|
857
|
-
await
|
|
935
|
+
await flushUpdates()
|
|
858
936
|
|
|
859
937
|
const grid = document.querySelector('shade-data-grid') as HTMLElement
|
|
860
938
|
grid.remove()
|
|
861
939
|
|
|
862
|
-
await
|
|
940
|
+
await flushUpdates()
|
|
863
941
|
|
|
864
942
|
window.dispatchEvent(new KeyboardEvent('keydown', { key: 'ArrowDown', bubbles: true }))
|
|
865
943
|
expect(service.focusedEntry.getValue()).toEqual({ id: 1, name: 'First' })
|
|
@@ -10,6 +10,35 @@ import { DataGridBody } from './body.js'
|
|
|
10
10
|
import { DataGridFooter } from './footer.js'
|
|
11
11
|
import { DataGridHeader } from './header.js'
|
|
12
12
|
|
|
13
|
+
export type StringFilterConfig = { type: 'string' }
|
|
14
|
+
export type NumberFilterConfig = { type: 'number' }
|
|
15
|
+
export type BooleanFilterConfig = { type: 'boolean' }
|
|
16
|
+
export type EnumFilterConfig = {
|
|
17
|
+
type: 'enum'
|
|
18
|
+
values: Array<{ label: string; value: string }>
|
|
19
|
+
}
|
|
20
|
+
export type DateFilterConfig = { type: 'date' }
|
|
21
|
+
|
|
22
|
+
export type ColumnFilterConfig =
|
|
23
|
+
| StringFilterConfig
|
|
24
|
+
| NumberFilterConfig
|
|
25
|
+
| BooleanFilterConfig
|
|
26
|
+
| EnumFilterConfig
|
|
27
|
+
| DateFilterConfig
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Loosely typed find options used internally by filter components.
|
|
31
|
+
* Avoids generic entity types while supporting dynamic field access
|
|
32
|
+
* with explicit casts at each use site.
|
|
33
|
+
*/
|
|
34
|
+
export type FilterableFindOptions = {
|
|
35
|
+
top?: number
|
|
36
|
+
skip?: number
|
|
37
|
+
order?: Record<string, 'ASC' | 'DESC'>
|
|
38
|
+
filter?: Record<string, unknown>
|
|
39
|
+
select?: string[]
|
|
40
|
+
}
|
|
41
|
+
|
|
13
42
|
export type DataHeaderCells<Column extends string> = {
|
|
14
43
|
[TKey in Column | 'default']?: (name: Column) => JSX.Element
|
|
15
44
|
}
|
|
@@ -38,11 +67,17 @@ export interface DataGridProps<T, Column extends string> {
|
|
|
38
67
|
/**
|
|
39
68
|
* A list of custom header components to use
|
|
40
69
|
*/
|
|
41
|
-
headerComponents
|
|
70
|
+
headerComponents?: DataHeaderCells<Column>
|
|
42
71
|
/**
|
|
43
72
|
* A list of custom row components to use
|
|
44
73
|
*/
|
|
45
|
-
rowComponents
|
|
74
|
+
rowComponents?: DataRowCells<T, Column>
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* Filter configuration per column. Only columns with a config will show a filter button.
|
|
78
|
+
*/
|
|
79
|
+
columnFilters?: { [K in Column]?: ColumnFilterConfig }
|
|
80
|
+
|
|
46
81
|
/**
|
|
47
82
|
* Optional autoFocus property to set the grid as focused
|
|
48
83
|
*/
|
|
@@ -96,20 +131,17 @@ export const DataGrid: <T, Column extends string>(
|
|
|
96
131
|
backdropFilter: 'blur(12px) saturate(180%)',
|
|
97
132
|
background: cssVariableTheme.action.activeBackground,
|
|
98
133
|
color: cssVariableTheme.text.secondary,
|
|
99
|
-
height: '
|
|
100
|
-
padding: '0
|
|
134
|
+
height: '36px',
|
|
135
|
+
padding: '0 0.6em',
|
|
101
136
|
alignItems: 'center',
|
|
102
|
-
|
|
103
|
-
top: '2px',
|
|
137
|
+
top: '0',
|
|
104
138
|
position: 'sticky',
|
|
105
|
-
|
|
106
|
-
fontSize: '0.875rem',
|
|
139
|
+
fontSize: '0.75rem',
|
|
107
140
|
fontWeight: cssVariableTheme.typography.fontWeight.semibold,
|
|
108
|
-
letterSpacing: '0.
|
|
141
|
+
letterSpacing: '0.03em',
|
|
109
142
|
textAlign: 'left',
|
|
110
143
|
zIndex: '1',
|
|
111
|
-
|
|
112
|
-
borderBottom: `2px solid ${cssVariableTheme.action.subtleBorder}`,
|
|
144
|
+
borderBottom: `1px solid ${cssVariableTheme.action.subtleBorder}`,
|
|
113
145
|
borderRight: `1px solid ${cssVariableTheme.action.subtleBorder}`,
|
|
114
146
|
},
|
|
115
147
|
},
|
|
@@ -156,6 +188,7 @@ export const DataGrid: <T, Column extends string>(
|
|
|
156
188
|
>
|
|
157
189
|
field={column}
|
|
158
190
|
findOptions={props.findOptions}
|
|
191
|
+
filterConfig={props.columnFilters?.[column]}
|
|
159
192
|
/>
|
|
160
193
|
)}
|
|
161
194
|
</th>
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
import { Injector } from '@furystack/inject'
|
|
2
|
+
import { createComponent, flushUpdates, initializeShadeRoot } from '@furystack/shades'
|
|
3
|
+
import { ObservableValue, usingAsync } from '@furystack/utils'
|
|
4
|
+
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'
|
|
5
|
+
import type { FilterableFindOptions } from '../data-grid.js'
|
|
6
|
+
import { BooleanFilter } from './boolean-filter.js'
|
|
7
|
+
|
|
8
|
+
describe('BooleanFilter', () => {
|
|
9
|
+
beforeEach(() => {
|
|
10
|
+
document.body.innerHTML = '<div id="root"></div>'
|
|
11
|
+
})
|
|
12
|
+
|
|
13
|
+
afterEach(() => {
|
|
14
|
+
document.body.innerHTML = ''
|
|
15
|
+
})
|
|
16
|
+
|
|
17
|
+
const createFindOptions = (options: Partial<FilterableFindOptions> = {}): ObservableValue<FilterableFindOptions> => {
|
|
18
|
+
return new ObservableValue<FilterableFindOptions>(options)
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
const renderBooleanFilter = async (
|
|
22
|
+
findOptions: ObservableValue<FilterableFindOptions>,
|
|
23
|
+
field = 'isActive',
|
|
24
|
+
onClose = vi.fn(),
|
|
25
|
+
) => {
|
|
26
|
+
const injector = new Injector()
|
|
27
|
+
const rootElement = document.getElementById('root')!
|
|
28
|
+
initializeShadeRoot({
|
|
29
|
+
injector,
|
|
30
|
+
rootElement,
|
|
31
|
+
jsxElement: <BooleanFilter field={field} findOptions={findOptions} onClose={onClose} />,
|
|
32
|
+
})
|
|
33
|
+
await flushUpdates()
|
|
34
|
+
return { injector, onClose }
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
it('should render three options: True, False, Any', async () => {
|
|
38
|
+
const findOptions = createFindOptions()
|
|
39
|
+
await usingAsync((await renderBooleanFilter(findOptions)).injector, async () => {
|
|
40
|
+
const buttons = document.querySelectorAll('shade-segmented-control button[data-value]')
|
|
41
|
+
expect(buttons.length).toBe(3)
|
|
42
|
+
const values = Array.from(buttons).map((b) => b.getAttribute('data-value'))
|
|
43
|
+
expect(values).toEqual(['true', 'false', 'any'])
|
|
44
|
+
})
|
|
45
|
+
})
|
|
46
|
+
|
|
47
|
+
it('should select "any" when no filter is set', async () => {
|
|
48
|
+
const findOptions = createFindOptions()
|
|
49
|
+
await usingAsync((await renderBooleanFilter(findOptions)).injector, async () => {
|
|
50
|
+
const selected = document.querySelector('shade-segmented-control button[data-selected]')
|
|
51
|
+
expect(selected?.getAttribute('data-value')).toBe('any')
|
|
52
|
+
})
|
|
53
|
+
})
|
|
54
|
+
|
|
55
|
+
it('should select "true" when filter is $eq: true', async () => {
|
|
56
|
+
const findOptions = createFindOptions({ filter: { isActive: { $eq: true } } })
|
|
57
|
+
await usingAsync((await renderBooleanFilter(findOptions)).injector, async () => {
|
|
58
|
+
const selected = document.querySelector('shade-segmented-control button[data-selected]')
|
|
59
|
+
expect(selected?.getAttribute('data-value')).toBe('true')
|
|
60
|
+
})
|
|
61
|
+
})
|
|
62
|
+
|
|
63
|
+
it('should select "false" when filter is $eq: false', async () => {
|
|
64
|
+
const findOptions = createFindOptions({ filter: { isActive: { $eq: false } } })
|
|
65
|
+
await usingAsync((await renderBooleanFilter(findOptions)).injector, async () => {
|
|
66
|
+
const selected = document.querySelector('shade-segmented-control button[data-selected]')
|
|
67
|
+
expect(selected?.getAttribute('data-value')).toBe('false')
|
|
68
|
+
})
|
|
69
|
+
})
|
|
70
|
+
|
|
71
|
+
it('should set filter to $eq: true when "True" is clicked', async () => {
|
|
72
|
+
const findOptions = createFindOptions()
|
|
73
|
+
const { injector, onClose } = await renderBooleanFilter(findOptions)
|
|
74
|
+
await usingAsync(injector, async () => {
|
|
75
|
+
const trueButton = document.querySelector(
|
|
76
|
+
'shade-segmented-control button[data-value="true"]',
|
|
77
|
+
) as HTMLButtonElement
|
|
78
|
+
trueButton?.click()
|
|
79
|
+
await flushUpdates()
|
|
80
|
+
|
|
81
|
+
expect(findOptions.getValue().filter).toEqual({ isActive: { $eq: true } })
|
|
82
|
+
expect(onClose).toHaveBeenCalled()
|
|
83
|
+
})
|
|
84
|
+
})
|
|
85
|
+
|
|
86
|
+
it('should set filter to $eq: false when "False" is clicked', async () => {
|
|
87
|
+
const findOptions = createFindOptions()
|
|
88
|
+
const { injector, onClose } = await renderBooleanFilter(findOptions)
|
|
89
|
+
await usingAsync(injector, async () => {
|
|
90
|
+
const falseButton = document.querySelector(
|
|
91
|
+
'shade-segmented-control button[data-value="false"]',
|
|
92
|
+
) as HTMLButtonElement
|
|
93
|
+
falseButton?.click()
|
|
94
|
+
await flushUpdates()
|
|
95
|
+
|
|
96
|
+
expect(findOptions.getValue().filter).toEqual({ isActive: { $eq: false } })
|
|
97
|
+
expect(onClose).toHaveBeenCalled()
|
|
98
|
+
})
|
|
99
|
+
})
|
|
100
|
+
|
|
101
|
+
it('should remove filter when "Any" is clicked', async () => {
|
|
102
|
+
const findOptions = createFindOptions({ filter: { isActive: { $eq: true } } })
|
|
103
|
+
const { injector, onClose } = await renderBooleanFilter(findOptions)
|
|
104
|
+
await usingAsync(injector, async () => {
|
|
105
|
+
const anyButton = document.querySelector('shade-segmented-control button[data-value="any"]') as HTMLButtonElement
|
|
106
|
+
anyButton?.click()
|
|
107
|
+
await flushUpdates()
|
|
108
|
+
|
|
109
|
+
expect(findOptions.getValue().filter?.isActive).toBeUndefined()
|
|
110
|
+
expect(onClose).toHaveBeenCalled()
|
|
111
|
+
})
|
|
112
|
+
})
|
|
113
|
+
|
|
114
|
+
it('should preserve filters on other fields', async () => {
|
|
115
|
+
const findOptions = createFindOptions({ filter: { isActive: { $eq: true }, name: { $regex: 'test' } } })
|
|
116
|
+
const { injector, onClose } = await renderBooleanFilter(findOptions)
|
|
117
|
+
await usingAsync(injector, async () => {
|
|
118
|
+
const anyButton = document.querySelector('shade-segmented-control button[data-value="any"]') as HTMLButtonElement
|
|
119
|
+
anyButton?.click()
|
|
120
|
+
await flushUpdates()
|
|
121
|
+
|
|
122
|
+
const updatedFilter = findOptions.getValue().filter
|
|
123
|
+
expect(updatedFilter?.isActive).toBeUndefined()
|
|
124
|
+
expect(updatedFilter?.name).toEqual({ $regex: 'test' })
|
|
125
|
+
expect(onClose).toHaveBeenCalled()
|
|
126
|
+
})
|
|
127
|
+
})
|
|
128
|
+
|
|
129
|
+
it('should reset skip to 0 when applying filter', async () => {
|
|
130
|
+
const findOptions = createFindOptions({ skip: 20 })
|
|
131
|
+
const { injector } = await renderBooleanFilter(findOptions)
|
|
132
|
+
await usingAsync(injector, async () => {
|
|
133
|
+
const trueButton = document.querySelector(
|
|
134
|
+
'shade-segmented-control button[data-value="true"]',
|
|
135
|
+
) as HTMLButtonElement
|
|
136
|
+
trueButton?.click()
|
|
137
|
+
await flushUpdates()
|
|
138
|
+
|
|
139
|
+
expect(findOptions.getValue().skip).toBe(0)
|
|
140
|
+
})
|
|
141
|
+
})
|
|
142
|
+
})
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { createComponent, Shade } from '@furystack/shades'
|
|
2
|
+
import type { ObservableValue } from '@furystack/utils'
|
|
3
|
+
import { SegmentedControl } from '../../button-group.js'
|
|
4
|
+
import type { FilterableFindOptions } from '../data-grid.js'
|
|
5
|
+
|
|
6
|
+
type BooleanFilterValue = 'true' | 'false' | 'any'
|
|
7
|
+
|
|
8
|
+
export const BooleanFilter = Shade<{
|
|
9
|
+
field: string
|
|
10
|
+
findOptions: ObservableValue<FilterableFindOptions>
|
|
11
|
+
onClose: () => void
|
|
12
|
+
}>({
|
|
13
|
+
shadowDomName: 'data-grid-boolean-filter',
|
|
14
|
+
render: ({ props, useObservable }) => {
|
|
15
|
+
const [findOptions, setFindOptions] = useObservable('findOptions', props.findOptions)
|
|
16
|
+
|
|
17
|
+
const currentFilter = findOptions.filter?.[props.field] as { $eq?: boolean } | undefined
|
|
18
|
+
const currentValue: BooleanFilterValue =
|
|
19
|
+
currentFilter?.$eq === true ? 'true' : currentFilter?.$eq === false ? 'false' : 'any'
|
|
20
|
+
|
|
21
|
+
const applyFilter = (value: BooleanFilterValue) => {
|
|
22
|
+
const filter = { ...findOptions.filter }
|
|
23
|
+
if (value === 'any') {
|
|
24
|
+
delete filter[props.field]
|
|
25
|
+
} else {
|
|
26
|
+
filter[props.field] = { $eq: value === 'true' }
|
|
27
|
+
}
|
|
28
|
+
setFindOptions({ ...findOptions, filter, skip: 0 })
|
|
29
|
+
props.onClose()
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
return (
|
|
33
|
+
<SegmentedControl
|
|
34
|
+
size="small"
|
|
35
|
+
value={currentValue}
|
|
36
|
+
onValueChange={(v) => applyFilter(v as BooleanFilterValue)}
|
|
37
|
+
options={[
|
|
38
|
+
{ value: 'true', label: 'True' },
|
|
39
|
+
{ value: 'false', label: 'False' },
|
|
40
|
+
{ value: 'any', label: 'Any' },
|
|
41
|
+
]}
|
|
42
|
+
/>
|
|
43
|
+
)
|
|
44
|
+
},
|
|
45
|
+
})
|