@kubex/zinc 1.1.185 → 2.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.browserslistrc +2 -0
- package/.github/workflows/js_build_and_deploy.yaml +54 -1
- package/.github/workflows/test.yaml +27 -0
- package/dist/chunks/zn.UWJLIXDT.js +1 -0
- package/dist/custom-elements.json +10319 -2666
- package/dist/vscode.html-custom-data.json +1012 -57
- package/dist/web-types.json +2097 -145
- package/dist/zn.d.ts +2294 -416
- package/dist/zn.min.css +1 -1
- package/dist/zn.min.js +2310 -1637
- package/docs/_includes/default.njk +4 -1
- package/docs/assets/scripts/docs.js +22 -6
- package/docs/assets/styles/docs.css +9 -2
- package/docs/data/report-table-day-compare.json +380 -0
- package/docs/data/report-table.json +314 -0
- package/docs/pages/components/avatar-group.md +57 -0
- package/docs/pages/components/badge.md +67 -0
- package/docs/pages/components/button.md +41 -1
- package/docs/pages/components/chat-message.md +16 -0
- package/docs/pages/components/checkbox.md +1 -1
- package/docs/pages/components/chip.md +25 -13
- package/docs/pages/components/color-picker.md +37 -0
- package/docs/pages/components/copy-button.md +2 -2
- package/docs/pages/components/data-table-filter.md +33 -50
- package/docs/pages/components/data-table-search.md +4 -4
- package/docs/pages/components/data-table.md +27 -3
- package/docs/pages/components/date-range.md +116 -0
- package/docs/pages/components/dialog.md +29 -37
- package/docs/pages/components/diff-row.md +28 -0
- package/docs/pages/components/diff.md +46 -0
- package/docs/pages/components/editor.md +55 -0
- package/docs/pages/components/icon.md +46 -1
- package/docs/pages/components/input.md +30 -11
- package/docs/pages/components/item.md +35 -0
- package/docs/pages/components/key-value.md +25 -0
- package/docs/pages/components/menu.md +74 -7
- package/docs/pages/components/nav-item.md +15 -0
- package/docs/pages/components/nav-list.md +132 -0
- package/docs/pages/components/navbar.md +100 -1
- package/docs/pages/components/page.md +242 -74
- package/docs/pages/components/priority-list.md +43 -5
- package/docs/pages/components/query-builder.md +23 -0
- package/docs/pages/components/radio-group.md +33 -1
- package/docs/pages/components/radio.md +1 -1
- package/docs/pages/components/report-table.md +202 -0
- package/docs/pages/components/stat.md +30 -0
- package/docs/pages/components/tile.md +11 -0
- package/docs/pages/components/tooltip.md +1 -1
- package/docs/pages/components/translation-grid.md +86 -0
- package/docs/pages/components/vertical-stepper.md +108 -64
- package/package.json +2 -1
- package/scss/_global-spacing.scss +2 -2
- package/scss/_root.scss +11 -171
- package/scss/boot.scss +14 -0
- package/scss/mixins/_helper-mixins.scss +24 -2
- package/scss/mixins/_motion-mixins.scss +126 -0
- package/scss/mixins/_spacing-mixins.scss +4 -3
- package/scss/mixins/_tab-indicator-mixins.scss +12 -0
- package/scss/mixins/_typography-mixins.scss +1 -1
- package/scss/mixins/index.scss +14 -0
- package/scss/shared/_base.scss +32 -1
- package/scss/shared/_button-mixin.scss +7 -5
- package/scss/shared/_table.scss +35 -4
- package/scss/shared/nav.scss +4 -0
- package/scss/shared/shimmer.scss +1 -1
- package/scss/table-controls.scss +206 -0
- package/scss/themes/_dark.scss +1 -3
- package/scss/themes/_index.scss +1 -1
- package/scss/themes/_light.scss +46 -6
- package/scss/themes/_modes.scss +11 -11
- package/scss/themes/_openbyte.scss +944 -0
- package/scss/themes/_typography.scss +4 -2
- package/scss/variables/index.scss +0 -9
- package/src/components/alert/alert.component.ts +14 -4
- package/src/components/alert/alert.scss +55 -69
- package/src/components/alert/alert.test.ts +8 -0
- package/src/components/animated-button/animated-button.component.ts +3 -2
- package/src/components/animated-button/animated-button.scss +6 -23
- package/src/components/animated-button/animated-button.test.ts +4 -3
- package/src/components/avatar-group/avatar-group.component.ts +84 -0
- package/src/components/avatar-group/avatar-group.scss +54 -0
- package/src/components/avatar-group/avatar-group.test.ts +59 -0
- package/src/components/avatar-group/index.ts +12 -0
- package/src/components/badge/badge.component.ts +49 -0
- package/src/components/badge/badge.scss +80 -0
- package/src/components/badge/badge.test.ts +34 -0
- package/src/components/badge/index.ts +12 -0
- package/src/components/bulk-actions/bulk-actions.component.ts +14 -2
- package/src/components/button/button.component.ts +228 -8
- package/src/components/button/button.scss +115 -32
- package/src/components/button/button.test.ts +122 -0
- package/src/components/button-menu/button-menu.component.ts +32 -11
- package/src/components/button-menu/button-menu.scss +5 -1
- package/src/components/channel-tile/channel-tile.component.ts +34 -27
- package/src/components/channel-tile/channel-tile.scss +76 -43
- package/src/components/chart/builders.test.ts +46 -0
- package/src/components/chart/builders.ts +27 -3
- package/src/components/chart/chart-live.test.ts +4 -6
- package/src/components/chart/chart.component.ts +125 -5
- package/src/components/chart/chart.scss +121 -0
- package/src/components/chart/chart.test.ts +81 -0
- package/src/components/chat-message/chat-message.component.ts +21 -1
- package/src/components/chat-message/chat-message.scss +13 -2
- package/src/components/chat-message/chat-message.test.ts +9 -0
- package/src/components/checkbox/checkbox.component.ts +61 -27
- package/src/components/checkbox/checkbox.scss +58 -25
- package/src/components/checkbox-group/checkbox-group.component.ts +7 -1
- package/src/components/chip/chip.component.ts +11 -1
- package/src/components/chip/chip.scss +91 -26
- package/src/components/chip/chip.test.ts +17 -0
- package/src/components/collapsible/collapsible.component.ts +17 -3
- package/src/components/collapsible/collapsible.scss +19 -10
- package/src/components/color-picker/color-picker.component.ts +277 -0
- package/src/components/color-picker/color-picker.scss +141 -0
- package/src/components/color-picker/color-picker.test.ts +57 -0
- package/src/components/color-picker/index.ts +12 -0
- package/src/components/cols/cols.component.ts +10 -0
- package/src/components/cols/cols.test.ts +17 -0
- package/src/components/confirm/confirm.component.ts +20 -6
- package/src/components/confirm/confirm.test.ts +52 -0
- package/src/components/content-block/content-block.component.ts +38 -9
- package/src/components/content-block/content-block.scss +11 -5
- package/src/components/content-block/content-block.test.ts +26 -0
- package/src/components/copy-button/copy-button.component.ts +2 -2
- package/src/components/copy-button/copy-button.scss +17 -4
- package/src/components/data-select/data-select.component.ts +3 -1
- package/src/components/data-table/data-table.component.ts +362 -140
- package/src/components/data-table/data-table.scss +136 -60
- package/src/components/data-table/data-table.test.ts +356 -4
- package/src/components/data-table-filter/data-table-filter.component.ts +426 -406
- package/src/components/data-table-filter/data-table-filter.scss +176 -148
- package/src/components/data-table-filter/data-table-filter.test.ts +271 -273
- package/src/components/data-table-search/data-table-search.component.ts +4 -2
- package/src/components/data-table-search/data-table-search.scss +8 -1
- package/src/components/data-table-search/data-table-search.test.ts +29 -0
- package/src/components/date-range/date-range-math.test.ts +78 -0
- package/src/components/date-range/date-range-math.ts +105 -0
- package/src/components/date-range/date-range.component.ts +375 -0
- package/src/components/date-range/date-range.scss +272 -0
- package/src/components/date-range/date-range.test.ts +247 -0
- package/src/components/date-range/index.ts +12 -0
- package/src/components/datepicker/datepicker.component.ts +44 -7
- package/src/components/datepicker/datepicker.scss +9 -0
- package/src/components/datepicker/datepicker.test.ts +2 -2
- package/src/components/dialog/dialog.component.ts +38 -19
- package/src/components/dialog/dialog.scss +65 -36
- package/src/components/dialog/dialog.test.ts +14 -0
- package/src/components/diff/diff.component.ts +55 -0
- package/src/components/diff/diff.scss +46 -0
- package/src/components/diff/diff.test.ts +15 -0
- package/src/components/diff/index.ts +12 -0
- package/src/components/diff-row/diff-row.component.ts +75 -0
- package/src/components/diff-row/diff-row.scss +70 -0
- package/src/components/diff-row/diff-row.test.ts +37 -0
- package/src/components/diff-row/index.ts +12 -0
- package/src/components/dropdown/dropdown.component.ts +12 -10
- package/src/components/dropdown/dropdown.scss +2 -0
- package/src/components/editor/editor.component.ts +159 -11
- package/src/components/editor/editor.scss +250 -1
- package/src/components/editor/editor.test.ts +31 -3
- package/src/components/editor/modules/ai/panel/ai-panel.scss +0 -1
- package/src/components/editor/modules/attachment/attachment.ts +53 -31
- package/src/components/editor/modules/context-menu/context-menu.ts +17 -0
- package/src/components/editor/modules/dialog/dialog.component.ts +23 -1
- package/src/components/editor/modules/dialog/dialog.test.ts +28 -0
- package/src/components/editor/modules/emoji/emoji.ts +4 -5
- package/src/components/editor/modules/merge-field/merge-field.ts +83 -0
- package/src/components/editor/modules/toolbar/toolbar.component.ts +121 -68
- package/src/components/editor/modules/toolbar/toolbar.scss +38 -0
- package/src/components/editor/modules/toolbar/toolbar.ts +25 -1
- package/src/components/empty-state/empty-state.component.ts +6 -1
- package/src/components/empty-state/empty-state.scss +21 -4
- package/src/components/expanding-action/expanding-action.component.ts +22 -34
- package/src/components/expanding-action/expanding-action.scss +3 -45
- package/src/components/expanding-action/expanding-action.test.ts +2 -1
- package/src/components/file/file.component.ts +30 -2
- package/src/components/file/file.scss +6 -0
- package/src/components/flow-builder/flow-builder.component.ts +36 -3
- package/src/components/flow-builder/flow-builder.scss +0 -6
- package/src/components/flow-builder/modules/flow-canvas/flow-canvas.component.ts +8 -0
- package/src/components/flow-builder/modules/flow-canvas/flow-canvas.scss +10 -5
- package/src/components/flow-builder/modules/flow-node/flow-node.component.ts +17 -0
- package/src/components/flow-builder/modules/flow-node/flow-node.scss +10 -0
- package/src/components/form-actions/form-actions.component.ts +48 -2
- package/src/components/form-actions/form-actions.scss +1 -1
- package/src/components/form-group/form-group.component.ts +10 -3
- package/src/components/form-group/form-group.scss +37 -4
- package/src/components/form-group/form-group.test.ts +10 -0
- package/src/components/header/header.component.ts +11 -4
- package/src/components/header/header.scss +47 -5
- package/src/components/hover-container/hover-container.component.ts +4 -5
- package/src/components/icon/icon.component.ts +95 -9
- package/src/components/icon/icon.scss +70 -6
- package/src/components/icon/icon.test.ts +55 -0
- package/src/components/icon-picker/icon-picker.component.ts +35 -1
- package/src/components/inline-edit/inline-edit.component.ts +38 -8
- package/src/components/inline-edit/inline-edit.scss +128 -19
- package/src/components/input/input.component.ts +173 -297
- package/src/components/input/input.scss +65 -43
- package/src/components/input/input.test.ts +86 -4
- package/src/components/item/item.component.ts +12 -0
- package/src/components/item/item.scss +102 -3
- package/src/components/item/item.test.ts +23 -0
- package/src/components/key/key.component.ts +2 -2
- package/src/components/key/key.scss +11 -0
- package/src/components/key-value/index.ts +12 -0
- package/src/components/key-value/key-value.component.ts +160 -0
- package/src/components/key-value/key-value.scss +20 -0
- package/src/components/key-value/key-value.test.ts +22 -0
- package/src/components/markdown-editor/markdown-editor.component.ts +8 -1
- package/src/components/menu/menu.component.ts +21 -2
- package/src/components/menu/menu.scss +43 -23
- package/src/components/menu/menu.test.ts +33 -0
- package/src/components/menu-item/menu-item.component.ts +13 -2
- package/src/components/menu-item/menu-item.scss +56 -23
- package/src/components/menu-item/menu-item.test.ts +31 -0
- package/src/components/menu-item/submenu-controller.ts +25 -15
- package/src/components/menu-label/index.ts +12 -0
- package/src/components/menu-label/menu-label.component.ts +30 -0
- package/src/components/menu-label/menu-label.scss +18 -0
- package/src/components/nav-item/index.ts +12 -0
- package/src/components/nav-item/nav-item.component.ts +83 -0
- package/src/components/nav-item/nav-item.scss +128 -0
- package/src/components/nav-list/index.ts +12 -0
- package/src/components/nav-list/nav-list.component.ts +313 -0
- package/src/components/nav-list/nav-list.scss +87 -0
- package/src/components/nav-list/nav-list.test.ts +250 -0
- package/src/components/navbar/navbar.component.ts +235 -171
- package/src/components/navbar/navbar.scss +333 -169
- package/src/components/navbar/navbar.test.ts +63 -143
- package/src/components/page/page.component.ts +114 -29
- package/src/components/page/page.scss +223 -95
- package/src/components/page/page.test.ts +214 -3
- package/src/components/page-builder/page-builder.component.ts +51 -5
- package/src/components/page-builder/page-builder.scss +6 -1
- package/src/components/page-nav/page-nav.component.ts +25 -3
- package/src/components/page-nav/page-nav.scss +10 -2
- package/src/components/pagination/pagination.scss +1 -1
- package/src/components/panel/panel.component.ts +14 -13
- package/src/components/panel/panel.scss +14 -10
- package/src/components/panel/panel.test.ts +42 -0
- package/src/components/popup/popup.component.ts +20 -13
- package/src/components/popup/popup.test.ts +21 -1
- package/src/components/priority-list/priority-list.component.ts +157 -172
- package/src/components/priority-list/priority-list.scss +113 -17
- package/src/components/priority-list/priority-list.test.ts +301 -3
- package/src/components/progress-bar/progress-bar.component.ts +1 -1
- package/src/components/progress-bar/progress-bar.scss +16 -4
- package/src/components/progress-tile/progress-tile.scss +1 -1
- package/src/components/query-builder/query-builder.component.ts +85 -10
- package/src/components/query-builder/query-builder.scss +7 -1
- package/src/components/query-builder/query-builder.test.ts +40 -0
- package/src/components/radio/radio.component.ts +57 -18
- package/src/components/radio/radio.scss +101 -26
- package/src/components/radio-group/radio-group.component.ts +45 -7
- package/src/components/radio-group/radio-group.scss +17 -0
- package/src/components/radio-group/radio-group.test.ts +63 -2
- package/src/components/rating/rating.component.ts +23 -0
- package/src/components/rating/rating.scss +1 -1
- package/src/components/remarkd-editor/remarkd-editor.component.ts +60 -5
- package/src/components/remarkd-editor/remarkd-editor.scss +12 -4
- package/src/components/report-table/index.ts +12 -0
- package/src/components/report-table/report-format.test.ts +86 -0
- package/src/components/report-table/report-format.ts +72 -0
- package/src/components/report-table/report-math.test.ts +74 -0
- package/src/components/report-table/report-math.ts +252 -0
- package/src/components/report-table/report-table.component.ts +681 -0
- package/src/components/report-table/report-table.scss +328 -0
- package/src/components/report-table/report-table.test.ts +702 -0
- package/src/components/reveal/reveal.component.ts +15 -1
- package/src/components/reveal/reveal.scss +5 -0
- package/src/components/schedule-builder/schedule-builder.component.ts +23 -8
- package/src/components/scroll-container/scroll-container.component.ts +19 -1
- package/src/components/scroll-container/scroll-container.scss +6 -1
- package/src/components/select/select.component.ts +52 -36
- package/src/components/select/select.scss +42 -25
- package/src/components/select/select.test.ts +14 -2
- package/src/components/settings-container/settings-container.scss +18 -5
- package/src/components/sidebar/sidebar.component.ts +8 -1
- package/src/components/sidebar/sidebar.scss +6 -1
- package/src/components/skeleton/skeleton.component.ts +3 -3
- package/src/components/skeleton/skeleton.scss +6 -6
- package/src/components/skeleton/skeleton.test.ts +9 -0
- package/src/components/slash-menu/slash-menu.scss +1 -1
- package/src/components/slideout/slideout.component.ts +20 -3
- package/src/components/slideout/slideout.scss +13 -6
- package/src/components/slideout/slideout.test.ts +19 -0
- package/src/components/split-button/split-button.component.ts +1 -1
- package/src/components/split-pane/split-pane.component.ts +71 -8
- package/src/components/split-pane/split-pane.scss +145 -41
- package/src/components/split-pane/split-pane.test.ts +23 -3
- package/src/components/stat/stat.component.ts +209 -14
- package/src/components/stat/stat.scss +305 -5
- package/src/components/stat/stat.test.ts +143 -2
- package/src/components/status-indicator/status-indicator.scss +22 -21
- package/src/components/stepper/stepper.scss +3 -3
- package/src/components/tab/tab.component.ts +1 -0
- package/src/components/table/table.component.ts +12 -1
- package/src/components/table/table.scss +21 -13
- package/src/components/table/table.test.ts +17 -0
- package/src/components/tabs/tabs.component.ts +150 -37
- package/src/components/tabs/tabs.scss +48 -7
- package/src/components/tabs/tabs.test.ts +169 -0
- package/src/components/textarea/textarea.component.ts +25 -3
- package/src/components/textarea/textarea.scss +10 -0
- package/src/components/textarea/textarea.test.ts +8 -4
- package/src/components/theme-editor/theme-editor.scss +0 -6
- package/src/components/tile/tile.component.ts +32 -2
- package/src/components/tile/tile.scss +40 -7
- package/src/components/tile/tile.test.ts +10 -0
- package/src/components/toggle/toggle.component.ts +23 -7
- package/src/components/toggle/toggle.scss +36 -29
- package/src/components/toggle/toggle.test.ts +17 -0
- package/src/components/tooltip/tooltip.component.ts +3 -0
- package/src/components/tooltip/tooltip.scss +11 -6
- package/src/components/tooltip/tooltip.test.ts +12 -0
- package/src/components/translation-field/index.ts +12 -0
- package/src/components/translation-field/translation-field.component.ts +55 -0
- package/src/components/translation-field/translation-field.scss +101 -0
- package/src/components/translation-fields/index.ts +12 -0
- package/src/components/translation-fields/translation-fields.component.ts +80 -0
- package/src/components/translation-fields/translation-fields.scss +60 -0
- package/src/components/translation-grid/index.ts +12 -0
- package/src/components/translation-grid/translation-grid.component.ts +157 -0
- package/src/components/translation-grid/translation-grid.scss +138 -0
- package/src/components/translation-grid/translation-grid.test.ts +28 -0
- package/src/components/vertical-stepper/vertical-stepper.component.ts +35 -9
- package/src/components/vertical-stepper/vertical-stepper.scss +110 -39
- package/src/components/vertical-stepper/vertical-stepper.test.ts +35 -0
- package/src/components/well/well.scss +2 -2
- package/src/events/events.ts +2 -0
- package/src/events/zn-chart-click.ts +13 -0
- package/src/events/zn-report-change.ts +7 -0
- package/src/form-control.scss +36 -3
- package/src/internal/anchored-popover.ts +175 -0
- package/src/internal/animate.ts +19 -5
- package/src/internal/cosmic-border.ts +15 -0
- package/src/internal/form.ts +1 -1
- package/src/internal/hover-intent.ts +15 -0
- package/src/internal/input-modality.ts +15 -0
- package/src/internal/pointer-intent.ts +37 -0
- package/src/internal/reorder.ts +632 -0
- package/src/internal/scroll.ts +51 -3
- package/src/internal/selection-card.ts +1 -1
- package/src/internal/tab-indicator.ts +92 -0
- package/src/internal/table-sort.ts +25 -0
- package/src/internal/table-tabs.ts +108 -0
- package/src/internal/test-drag.ts +35 -0
- package/src/internal/theme-openbyte.test.ts +126 -0
- package/src/internal/theme.ts +4 -4
- package/src/internal/zinc-element.ts +2 -2
- package/src/selection-card.scss +25 -0
- package/src/types/web-test-runner-commands.d.ts +1 -0
- package/src/utilities/color.test.ts +43 -0
- package/src/utilities/color.ts +189 -0
- package/src/zinc.ts +14 -0
- package/.github/workflows/eleventy_build.yml +0 -42
- package/scss/themes/_aura.scss +0 -114
|
@@ -1,378 +1,376 @@
|
|
|
1
1
|
import '../../../dist/zn.min.js';
|
|
2
2
|
import {expect, fixture, html, waitUntil} from '@open-wc/testing';
|
|
3
3
|
import type ZnDataTableFilter from './data-table-filter.component';
|
|
4
|
-
import type ZnDatepicker from '../datepicker/datepicker.component';
|
|
5
|
-
import type ZnDropdown from '../dropdown/dropdown.component';
|
|
6
4
|
import type ZnInput from '../input/input.component';
|
|
5
|
+
import type ZnSelect from '../select/select.component';
|
|
7
6
|
|
|
8
7
|
const FILTERS = [
|
|
9
8
|
{id: 'role', name: 'role', operators: ['in'], options: {pm: 'Project Manager', eng: 'Engineer'}},
|
|
10
|
-
{id: 'status', name: '
|
|
11
|
-
{id: 'email', name: '
|
|
12
|
-
{id: 'created', name: '
|
|
13
|
-
{id: 'age', name: '
|
|
9
|
+
{id: 'status', name: 'Status', operators: ['eq', 'neq'], options: {active: 'Active', inactive: 'Inactive'}},
|
|
10
|
+
{id: 'email', name: 'Email', operators: ['contains']},
|
|
11
|
+
{id: 'created', name: 'Created', type: 'date', operators: ['eq', 'before']},
|
|
12
|
+
{id: 'age', name: 'Age', type: 'number', operators: ['eq', 'gte']},
|
|
13
|
+
{id: 'state', name: 'State', operators: ['eq', 'in'], options: {open: 'Open', closed: 'Closed'}},
|
|
14
14
|
];
|
|
15
15
|
|
|
16
|
-
const
|
|
16
|
+
const MANY = Array.from({length: 10}, (_, i) => ({id: `f${i}`, name: i === 4 ? 'Mac Hotspot Shield' : `Field ${i}`, operators: ['eq']}));
|
|
17
|
+
|
|
18
|
+
const click = (el: Element | null | undefined) =>
|
|
17
19
|
el?.dispatchEvent(new MouseEvent('click', {bubbles: true, composed: true, cancelable: true}));
|
|
18
20
|
|
|
19
|
-
const
|
|
21
|
+
const choose = (control: Element, value: string | string[]) => {
|
|
22
|
+
(control as HTMLElement & {value: string | string[]}).value = value;
|
|
23
|
+
control.dispatchEvent(new CustomEvent('zn-change', {bubbles: true, composed: true}));
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
const decode = (value: string) => JSON.parse(atob(value)) as {key: string; comparator: string; value: string}[];
|
|
27
|
+
const encode = (rules: {key: string; comparator: string; value: string}[]) => btoa(JSON.stringify(rules));
|
|
20
28
|
|
|
21
|
-
async function
|
|
29
|
+
async function filter(attrs: {defaultFilters?: string; value?: string; filters?: unknown[]} = {}) {
|
|
22
30
|
const el = await fixture<ZnDataTableFilter>(html`
|
|
23
|
-
<zn-data-table-filter default-filters="${defaultFilters}" .filters="${FILTERS}"
|
|
31
|
+
<zn-data-table-filter default-filters="${attrs.defaultFilters ?? ''}" .filters="${attrs.filters ?? FILTERS}"
|
|
32
|
+
.value="${attrs.value ?? ''}"></zn-data-table-filter>`);
|
|
24
33
|
await el.updateComplete;
|
|
25
34
|
return el;
|
|
26
35
|
}
|
|
27
36
|
|
|
28
|
-
const
|
|
29
|
-
|
|
37
|
+
const root = (el: ZnDataTableFilter) => el.shadowRoot!;
|
|
38
|
+
const rules = (el: ZnDataTableFilter) => [...root(el).querySelectorAll('.filter__rule')];
|
|
39
|
+
const control = <T extends Element>(el: ZnDataTableFilter, label: string, index = 0) =>
|
|
40
|
+
rules(el)[index].querySelector<T>(`[aria-label="${label}"]`)!;
|
|
41
|
+
const chips = (el: ZnDataTableFilter) =>
|
|
42
|
+
[...root(el).querySelectorAll('.filter__chip__text')].map(chip => chip.textContent!.trim());
|
|
30
43
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
44
|
+
async function open(el: ZnDataTableFilter) {
|
|
45
|
+
click(root(el).querySelector('.filter__toggle'));
|
|
46
|
+
await el.updateComplete;
|
|
47
|
+
}
|
|
35
48
|
|
|
36
|
-
|
|
37
|
-
|
|
49
|
+
async function apply(el: ZnDataTableFilter) {
|
|
50
|
+
click(root(el).querySelector('.filter__pop__foot zn-button[color="primary"]'));
|
|
51
|
+
await el.updateComplete;
|
|
52
|
+
}
|
|
38
53
|
|
|
39
|
-
|
|
40
|
-
|
|
54
|
+
async function setRule(el: ZnDataTableFilter, key: string, value?: string | string[], index = 0) {
|
|
55
|
+
choose(control(el, 'Filter field', index), key);
|
|
56
|
+
await el.updateComplete;
|
|
57
|
+
if (value === undefined) return;
|
|
58
|
+
await waitUntil(() => control(el, 'Filter value', index));
|
|
59
|
+
choose(control(el, 'Filter value', index), value);
|
|
60
|
+
await el.updateComplete;
|
|
61
|
+
}
|
|
41
62
|
|
|
42
|
-
|
|
63
|
+
describe('<zn-data-table-filter>', () => {
|
|
64
|
+
it('opens the filter popover from the funnel with one empty rule', async () => {
|
|
65
|
+
const el = await filter();
|
|
66
|
+
const toggle = root(el).querySelector('.filter__toggle')!;
|
|
67
|
+
expect(root(el).querySelector('.filter__pop')).to.not.exist;
|
|
68
|
+
expect(toggle.getAttribute('aria-expanded')).to.equal('false');
|
|
69
|
+
expect(toggle.classList.contains('filter__toggle--open')).to.be.false;
|
|
70
|
+
|
|
71
|
+
await open(el);
|
|
72
|
+
expect(toggle.getAttribute('aria-expanded')).to.equal('true');
|
|
73
|
+
expect(toggle.classList.contains('filter__toggle--open')).to.be.true;
|
|
74
|
+
|
|
75
|
+
const pop = root(el).querySelector('.filter__pop')!;
|
|
76
|
+
expect(pop).to.exist;
|
|
77
|
+
const head = () => pop.querySelector('.filter__pop__head')!.textContent!.replace(/\s+/g, ' ').trim();
|
|
78
|
+
expect(head()).to.equal('Filters Choose a value for the empty filter to apply it');
|
|
79
|
+
expect(rules(el).length).to.equal(1);
|
|
80
|
+
expect(control<ZnSelect>(el, 'Filter field').value).to.equal('');
|
|
81
|
+
|
|
82
|
+
await setRule(el, 'status', 'active');
|
|
83
|
+
expect(head()).to.equal('Filters Show records that match all of these');
|
|
43
84
|
});
|
|
44
85
|
|
|
45
|
-
it('
|
|
46
|
-
const el = await
|
|
86
|
+
it('encodes field, operator and value exactly as the table builder did', async () => {
|
|
87
|
+
const el = await filter();
|
|
88
|
+
await open(el);
|
|
47
89
|
|
|
48
|
-
|
|
49
|
-
|
|
90
|
+
await setRule(el, 'status', 'active');
|
|
91
|
+
await apply(el);
|
|
50
92
|
|
|
51
|
-
expect(
|
|
52
|
-
expect(
|
|
93
|
+
expect(el.value).to.equal('W3sia2V5Ijoic3RhdHVzIiwiY29tcGFyYXRvciI6ImVxIiwidmFsdWUiOiJhY3RpdmUifV0=');
|
|
94
|
+
expect(el.activeCount).to.equal(1);
|
|
53
95
|
});
|
|
54
96
|
|
|
55
|
-
it('
|
|
56
|
-
const el = await
|
|
57
|
-
|
|
58
|
-
|
|
97
|
+
it('offers the field\'s operators and resets operator and value when the field changes', async () => {
|
|
98
|
+
const el = await filter();
|
|
99
|
+
await open(el);
|
|
100
|
+
await setRule(el, 'age', '18');
|
|
101
|
+
choose(control(el, 'Filter operator'), 'gte');
|
|
59
102
|
await el.updateComplete;
|
|
103
|
+
await apply(el);
|
|
104
|
+
expect(decode(el.value)).to.deep.equal([{key: 'age', comparator: 'gte', value: '18'}]);
|
|
60
105
|
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
it('accumulates values for an `in` filter and counts them on the pill', async () => {
|
|
65
|
-
const el = await filterBar('role');
|
|
66
|
-
|
|
67
|
-
clickOn(el.shadowRoot!.querySelector('zn-menu-item[value="pm"]'));
|
|
68
|
-
await el.updateComplete;
|
|
69
|
-
clickOn(el.shadowRoot!.querySelector('zn-menu-item[value="eng"]'));
|
|
70
|
-
await el.updateComplete;
|
|
106
|
+
await open(el);
|
|
107
|
+
const operators = [...control(el, 'Filter operator').querySelectorAll('zn-option')].map(o => o.textContent!.trim());
|
|
108
|
+
expect(operators).to.deep.equal(['is', 'is at least']);
|
|
71
109
|
|
|
72
|
-
|
|
73
|
-
expect(
|
|
110
|
+
await setRule(el, 'email');
|
|
111
|
+
expect(control<ZnSelect>(el, 'Filter operator').value).to.equal('contains');
|
|
112
|
+
expect(control<ZnInput>(el, 'Filter value').value).to.equal('');
|
|
113
|
+
await apply(el);
|
|
114
|
+
expect(el.value).to.equal('');
|
|
74
115
|
});
|
|
75
116
|
|
|
76
|
-
it('
|
|
77
|
-
const el = await
|
|
117
|
+
it('narrows a long field list with its search', async () => {
|
|
118
|
+
const el = await filter({filters: MANY});
|
|
119
|
+
await open(el);
|
|
120
|
+
const select = control<ZnSelect>(el, 'Filter field');
|
|
121
|
+
expect(select.hasAttribute('search')).to.be.true;
|
|
78
122
|
|
|
79
|
-
|
|
80
|
-
await
|
|
81
|
-
clickOn(el.shadowRoot!.querySelector('zn-menu-item[value="active"]'));
|
|
123
|
+
expect(select.placeholder).to.equal('Please select...');
|
|
124
|
+
await select.show();
|
|
82
125
|
await el.updateComplete;
|
|
126
|
+
expect(select.placeholder).to.equal('Search 10 fields...');
|
|
83
127
|
|
|
84
|
-
|
|
128
|
+
await select.updateComplete;
|
|
129
|
+
const input = select.shadowRoot!.querySelector<HTMLInputElement>('.select__display-input')!;
|
|
130
|
+
input.value = 'HOTSPOT';
|
|
131
|
+
input.dispatchEvent(new Event('input', {bubbles: true, composed: true}));
|
|
132
|
+
await select.updateComplete;
|
|
133
|
+
|
|
134
|
+
const visible = [...select.querySelectorAll<HTMLElement>('zn-option')].filter(o => !o.hidden).map(o => o.textContent!.trim());
|
|
135
|
+
expect(visible).to.deep.equal(['Mac Hotspot Shield']);
|
|
85
136
|
});
|
|
86
137
|
|
|
87
|
-
it('
|
|
88
|
-
const el = await
|
|
138
|
+
it('joins an `in` multi-select\'s values with spaces', async () => {
|
|
139
|
+
const el = await filter();
|
|
140
|
+
await open(el);
|
|
141
|
+
choose(control(el, 'Filter field'), 'role');
|
|
142
|
+
await el.updateComplete;
|
|
89
143
|
|
|
90
|
-
|
|
144
|
+
expect(control(el, 'Filter value').hasAttribute('multiple')).to.be.true;
|
|
145
|
+
choose(control(el, 'Filter value'), ['pm', 'eng']);
|
|
91
146
|
await el.updateComplete;
|
|
147
|
+
await apply(el);
|
|
92
148
|
|
|
93
|
-
expect(decode(el.value)).to.deep.equal([{key: '
|
|
149
|
+
expect(decode(el.value)).to.deep.equal([{key: 'role', comparator: 'in', value: 'pm eng'}]);
|
|
150
|
+
expect(chips(el)).to.deep.equal(['Role is any of Project Manager, Engineer']);
|
|
94
151
|
});
|
|
95
152
|
|
|
96
|
-
it('
|
|
97
|
-
const el = await
|
|
98
|
-
|
|
99
|
-
el
|
|
153
|
+
it('keeps the first value when an `in` rule moves to a single-value operator', async () => {
|
|
154
|
+
const el = await filter();
|
|
155
|
+
await open(el);
|
|
156
|
+
await setRule(el, 'state');
|
|
157
|
+
choose(control(el, 'Filter operator'), 'in');
|
|
158
|
+
await el.updateComplete;
|
|
159
|
+
choose(control(el, 'Filter value'), ['open', 'closed']);
|
|
160
|
+
await el.updateComplete;
|
|
100
161
|
|
|
101
|
-
|
|
102
|
-
await
|
|
162
|
+
choose(control(el, 'Filter operator'), 'eq');
|
|
163
|
+
await el.updateComplete;
|
|
164
|
+
await apply(el);
|
|
103
165
|
|
|
104
|
-
expect(
|
|
166
|
+
expect(decode(el.value)).to.deep.equal([{key: 'state', comparator: 'eq', value: 'open'}]);
|
|
105
167
|
});
|
|
106
168
|
|
|
107
|
-
it('
|
|
108
|
-
const el = await
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
const multi = dropdowns.find(d => d.querySelector('zn-menu-item[value="pm"]'))!;
|
|
112
|
-
const single = dropdowns.find(d => d.querySelector('zn-menu-item[value="active"]'))!;
|
|
169
|
+
it('renders a number input for a number field', async () => {
|
|
170
|
+
const el = await filter();
|
|
171
|
+
await open(el);
|
|
172
|
+
await setRule(el, 'age');
|
|
113
173
|
|
|
114
|
-
expect(
|
|
115
|
-
expect(single.stayOpenOnSelect).to.be.false;
|
|
174
|
+
expect(control(el, 'Filter value').getAttribute('type')).to.equal('number');
|
|
116
175
|
});
|
|
117
176
|
|
|
118
|
-
it('
|
|
119
|
-
const el = await
|
|
177
|
+
it('keeps the legacy date encoding and re-encodes on an operator change', async () => {
|
|
178
|
+
const el = await filter();
|
|
179
|
+
await open(el);
|
|
180
|
+
await setRule(el, 'created');
|
|
181
|
+
expect(control(el, 'Filter value').getAttribute('type')).to.equal('date');
|
|
120
182
|
|
|
121
|
-
|
|
122
|
-
input.value = 'thats really bad';
|
|
123
|
-
input.dispatchEvent(new Event('zn-input', {bubbles: true, composed: true}));
|
|
124
|
-
await waitUntil(() => el.value.length > 0);
|
|
183
|
+
choose(control(el, 'Filter value'), '2026-10-20');
|
|
125
184
|
await el.updateComplete;
|
|
185
|
+
await apply(el);
|
|
186
|
+
const timestamp = new Date(2026, 9, 20).getTime();
|
|
187
|
+
expect(decode(el.value)).to.deep.equal([{key: 'created', comparator: 'eq', value: (timestamp / 1000).toString()}]);
|
|
188
|
+
expect(chips(el)).to.deep.equal(['Created is 2026-10-20']);
|
|
126
189
|
|
|
127
|
-
|
|
190
|
+
await open(el);
|
|
191
|
+
choose(control(el, 'Filter operator'), 'before');
|
|
192
|
+
await el.updateComplete;
|
|
193
|
+
await apply(el);
|
|
194
|
+
const [rule] = decode(el.value);
|
|
195
|
+
expect(rule.comparator).to.equal('before');
|
|
196
|
+
expect(Number(rule.value)).to.be.closeTo(-Math.floor((Date.now() - timestamp) / 60_000), 1);
|
|
128
197
|
});
|
|
129
198
|
|
|
130
|
-
it('
|
|
131
|
-
const el = await
|
|
132
|
-
el
|
|
133
|
-
|
|
134
|
-
const input = el.shadowRoot!.querySelector<ZnInput>('zn-input')!;
|
|
135
|
-
input.value = 'ADA';
|
|
136
|
-
input.dispatchEvent(new Event('zn-input', {bubbles: true, composed: true}));
|
|
137
|
-
await waitUntil(() => el.shadowRoot!.querySelectorAll('.filter-bar__suggestion').length > 0);
|
|
138
|
-
|
|
139
|
-
const shown = [...el.shadowRoot!.querySelectorAll('.filter-bar__suggestion')].map(b => b.textContent!.trim());
|
|
199
|
+
it('shows an empty row for each default filter', async () => {
|
|
200
|
+
const el = await filter({defaultFilters: 'email'});
|
|
201
|
+
await open(el);
|
|
140
202
|
|
|
141
|
-
expect(
|
|
203
|
+
expect(rules(el).length).to.equal(1);
|
|
204
|
+
expect(control<ZnSelect>(el, 'Filter field').value).to.equal('email');
|
|
205
|
+
expect(control<ZnInput>(el, 'Filter value').value).to.equal('');
|
|
206
|
+
expect(el.value).to.equal('');
|
|
142
207
|
});
|
|
143
208
|
|
|
144
|
-
it('
|
|
145
|
-
const el = await
|
|
209
|
+
it('shows chips for a value it is given', async () => {
|
|
210
|
+
const el = await filter({
|
|
211
|
+
value: encode([
|
|
212
|
+
{key: 'status', comparator: 'eq', value: 'active'},
|
|
213
|
+
{key: 'email', comparator: 'contains', value: 'acme'},
|
|
214
|
+
]),
|
|
215
|
+
});
|
|
146
216
|
|
|
147
|
-
expect(el.
|
|
217
|
+
expect(chips(el)).to.deep.equal(['Status is Active', 'Email contains acme']);
|
|
218
|
+
expect(el.activeCount).to.equal(2);
|
|
219
|
+
expect(root(el).querySelector('.filter__toggle')!.getAttribute('notification')).to.equal('2');
|
|
148
220
|
});
|
|
149
221
|
|
|
150
|
-
it('
|
|
151
|
-
const el = await
|
|
152
|
-
|
|
153
|
-
|
|
222
|
+
it('keeps a single option value with spaces whole', async () => {
|
|
223
|
+
const el = await filter({
|
|
224
|
+
filters: [{id: 'stage', name: 'Stage', operators: ['eq', 'in'], options: {'in progress': 'In progress', done: 'Done'}}],
|
|
225
|
+
value: encode([{key: 'stage', comparator: 'eq', value: 'in progress'}]),
|
|
226
|
+
});
|
|
154
227
|
|
|
155
|
-
expect(
|
|
156
|
-
expect(picker!.hasAttribute('inline')).to.be.true;
|
|
228
|
+
expect(chips(el)).to.deep.equal(['Stage is In progress']);
|
|
157
229
|
});
|
|
158
230
|
|
|
159
|
-
it('
|
|
160
|
-
const el = await
|
|
161
|
-
const picker = el.shadowRoot!.querySelector<ZnDatepicker>('zn-datepicker')!;
|
|
162
|
-
await picker.updateComplete;
|
|
231
|
+
it('rebuilds its rules when the value is changed from outside', async () => {
|
|
232
|
+
const el = await filter({defaultFilters: 'role'});
|
|
163
233
|
|
|
164
|
-
|
|
165
|
-
// AirDatepicker reports a selection on the next task, not synchronously
|
|
166
|
-
await waitUntil(() => el.value.length > 0);
|
|
234
|
+
el.value = encode([{key: 'status', comparator: 'eq', value: 'active'}]);
|
|
167
235
|
await el.updateComplete;
|
|
236
|
+
expect(chips(el)).to.deep.equal(['Status is Active']);
|
|
168
237
|
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
expect(
|
|
172
|
-
expect(filter.comparator).to.equal('eq');
|
|
173
|
-
expect(Number(filter.value)).to.be.greaterThan(0);
|
|
174
|
-
expect(pills(el)[0]).to.equal(`Created: ${picker.value as string}`);
|
|
175
|
-
});
|
|
176
|
-
|
|
177
|
-
it('offers each operator when a filter defines more than one', async () => {
|
|
178
|
-
const el = await filterBar('age');
|
|
179
|
-
|
|
180
|
-
const operators = [...el.shadowRoot!.querySelectorAll('.filter-bar__operator')].map(o => o.textContent!.trim());
|
|
181
|
-
|
|
182
|
-
expect(operators).to.deep.equal(['is', '\u2265']);
|
|
238
|
+
await open(el);
|
|
239
|
+
expect(rules(el).length).to.equal(1);
|
|
240
|
+
expect(control<ZnSelect>(el, 'Filter field').value).to.equal('status');
|
|
183
241
|
});
|
|
184
242
|
|
|
185
|
-
it('
|
|
186
|
-
const el = await
|
|
243
|
+
it('emits zn-filter-change only when Apply changes the encoded value', async () => {
|
|
244
|
+
const el = await filter();
|
|
245
|
+
let emitted = 0;
|
|
246
|
+
el.addEventListener('zn-filter-change', () => emitted++);
|
|
247
|
+
await open(el);
|
|
187
248
|
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
249
|
+
await setRule(el, 'status', 'active');
|
|
250
|
+
expect(emitted).to.equal(0);
|
|
251
|
+
expect(el.value).to.equal('');
|
|
252
|
+
expect(chips(el)).to.deep.equal([]);
|
|
192
253
|
|
|
193
|
-
|
|
194
|
-
|
|
254
|
+
await apply(el);
|
|
255
|
+
expect(emitted).to.equal(1);
|
|
256
|
+
expect(root(el).querySelector('.filter__pop')).to.not.exist;
|
|
195
257
|
|
|
196
|
-
|
|
197
|
-
|
|
258
|
+
await open(el);
|
|
259
|
+
await apply(el);
|
|
260
|
+
expect(emitted).to.equal(1);
|
|
198
261
|
});
|
|
199
262
|
|
|
200
|
-
it('
|
|
201
|
-
const el = await
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
name: 'state',
|
|
206
|
-
operators: ['eq', 'in'],
|
|
207
|
-
options: {open: 'Open', closed: 'Closed'}
|
|
208
|
-
}]}"></zn-data-table-filter>`);
|
|
263
|
+
it('closes on Escape and discards unapplied rules', async () => {
|
|
264
|
+
const el = await filter();
|
|
265
|
+
await open(el);
|
|
266
|
+
await setRule(el, 'status', 'active');
|
|
267
|
+
click(root(el).querySelector('.filter__pop__foot zn-button[icon="plus@lu"]'));
|
|
209
268
|
await el.updateComplete;
|
|
269
|
+
expect(rules(el).length).to.equal(2);
|
|
210
270
|
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
expect(items).to.deep.equal(['is', 'is any of', 'Open', 'Closed']);
|
|
214
|
-
});
|
|
215
|
-
|
|
216
|
-
it('opens the new pill so its value can be set without a second click', async () => {
|
|
217
|
-
const el = await filterBar();
|
|
218
|
-
|
|
219
|
-
clickOn(el.shadowRoot!.querySelector('zn-menu-item[value="status"]'));
|
|
271
|
+
document.dispatchEvent(new KeyboardEvent('keydown', {key: 'Escape', bubbles: true}));
|
|
220
272
|
await el.updateComplete;
|
|
273
|
+
expect(root(el).querySelector('.filter__pop')).to.not.exist;
|
|
274
|
+
expect(root(el).querySelector('.filter__toggle')!.classList.contains('filter__toggle--open')).to.be.false;
|
|
221
275
|
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
expect(pill.open).to.be.true;
|
|
276
|
+
expect(el.value).to.equal('');
|
|
277
|
+
await open(el);
|
|
278
|
+
expect(rules(el).length).to.equal(1);
|
|
279
|
+
expect(control<ZnSelect>(el, 'Filter field').value).to.equal('');
|
|
227
280
|
});
|
|
228
281
|
|
|
229
|
-
it('
|
|
230
|
-
const el = await
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
id: 'state',
|
|
234
|
-
name: 'state',
|
|
235
|
-
operators: ['eq', 'in'],
|
|
236
|
-
options: {open: 'Open', closed: 'Closed'}
|
|
237
|
-
}]}"></zn-data-table-filter>`);
|
|
238
|
-
await el.updateComplete;
|
|
239
|
-
|
|
240
|
-
const pill = el.shadowRoot!.querySelector<ZnDropdown>('zn-dropdown')!;
|
|
241
|
-
await pill.show();
|
|
282
|
+
it('closes on a click outside and drops incomplete rules', async () => {
|
|
283
|
+
const el = await filter();
|
|
284
|
+
await open(el);
|
|
285
|
+
await setRule(el, 'email');
|
|
242
286
|
|
|
243
|
-
|
|
244
|
-
clickOn(operator);
|
|
287
|
+
click(document.body);
|
|
245
288
|
await el.updateComplete;
|
|
246
|
-
expect(
|
|
247
|
-
|
|
248
|
-
clickOn(pill.querySelector('zn-menu-item[value="open"]'));
|
|
249
|
-
await waitUntil(() => !pill.open, 'picking a value should close the panel');
|
|
250
|
-
expect(pill.open).to.be.false;
|
|
289
|
+
expect(root(el).querySelector('.filter__pop')).to.not.exist;
|
|
290
|
+
expect(chips(el)).to.deep.equal([]);
|
|
251
291
|
});
|
|
252
292
|
|
|
253
|
-
|
|
254
|
-
const
|
|
255
|
-
['How To', 'Linux', 'Beta', 'Router', 'TV', 'Other', 'Mac Hotspot Shield', 'General', 'iOS', 'Tutorials']
|
|
256
|
-
.map((label, index) => [`c${index}`, label])
|
|
257
|
-
);
|
|
258
|
-
|
|
259
|
-
async function categoryBar() {
|
|
260
|
-
const el = await fixture<ZnDataTableFilter>(html`
|
|
261
|
-
<zn-data-table-filter default-filters="category"
|
|
262
|
-
.filters="${[{
|
|
263
|
-
id: 'category',
|
|
264
|
-
name: 'category',
|
|
265
|
-
operators: ['eq'],
|
|
266
|
-
options: many
|
|
267
|
-
}]}"></zn-data-table-filter>`);
|
|
268
|
-
await el.updateComplete;
|
|
269
|
-
return el;
|
|
270
|
-
}
|
|
271
|
-
|
|
272
|
-
const search = async (el: ZnDataTableFilter, term: string) => {
|
|
273
|
-
const input = el.shadowRoot!.querySelector<ZnInput>('.filter-bar__option-search')!;
|
|
274
|
-
input.value = term;
|
|
275
|
-
input.dispatchEvent(new Event('zn-input', {bubbles: true, composed: true}));
|
|
276
|
-
await el.updateComplete;
|
|
277
|
-
};
|
|
278
|
-
|
|
279
|
-
const labels = (el: ZnDataTableFilter) =>
|
|
280
|
-
[...el.shadowRoot!.querySelectorAll('zn-menu-item')].map(item => item.textContent!.trim());
|
|
281
|
-
|
|
282
|
-
it('offers a search above the options', async () => {
|
|
283
|
-
const el = await categoryBar();
|
|
284
|
-
|
|
285
|
-
expect(el.shadowRoot!.querySelector('.filter-bar__option-search')).to.exist;
|
|
286
|
-
});
|
|
287
|
-
|
|
288
|
-
it('leaves the search off a short list', async () => {
|
|
289
|
-
const el = await filterBar('status');
|
|
290
|
-
|
|
291
|
-
expect(el.shadowRoot!.querySelector('.filter-bar__option-search')).to.not.exist;
|
|
292
|
-
});
|
|
293
|
-
|
|
294
|
-
it('narrows the options without regard to case', async () => {
|
|
295
|
-
const el = await categoryBar();
|
|
296
|
-
|
|
297
|
-
await search(el, 'HOTSPOT');
|
|
298
|
-
|
|
299
|
-
expect(labels(el)).to.deep.equal(['Mac Hotspot Shield']);
|
|
300
|
-
});
|
|
293
|
+
it('drops a rule when its chip\'s remove button is clicked', async () => {
|
|
294
|
+
const el = await filter({value: encode([{key: 'status', comparator: 'eq', value: 'active'}])});
|
|
301
295
|
|
|
302
|
-
|
|
303
|
-
const el = await categoryBar();
|
|
304
|
-
|
|
305
|
-
await search(el, 'nothing here');
|
|
306
|
-
|
|
307
|
-
expect(labels(el)).to.deep.equal(['No matches']);
|
|
308
|
-
});
|
|
309
|
-
});
|
|
310
|
-
|
|
311
|
-
it('drops a filter when its chip\'s remove button is clicked', async () => {
|
|
312
|
-
const el = await filterBar('role,status');
|
|
313
|
-
clickOn(el.shadowRoot!.querySelector('zn-menu-item[value="active"]'));
|
|
314
|
-
await el.updateComplete;
|
|
315
|
-
|
|
316
|
-
const chip = [...el.shadowRoot!.querySelectorAll('.filter-bar__chip')]
|
|
317
|
-
.find(item => item.querySelector('zn-dropdown')!.getAttribute('data-key') === 'status')!;
|
|
318
|
-
clickOn(chip.querySelector('.filter-bar__remove'));
|
|
296
|
+
click(root(el).querySelector('.filter__chip__remove'));
|
|
319
297
|
await el.updateComplete;
|
|
320
298
|
|
|
321
|
-
expect(
|
|
299
|
+
expect(chips(el)).to.deep.equal([]);
|
|
322
300
|
expect(el.value).to.equal('');
|
|
323
301
|
});
|
|
324
302
|
|
|
325
|
-
it('clear() removes every
|
|
326
|
-
const el = await
|
|
327
|
-
clickOn(el.shadowRoot!.querySelector('zn-menu-item[value="active"]'));
|
|
328
|
-
await el.updateComplete;
|
|
303
|
+
it('clear() removes every rule and empties the value', async () => {
|
|
304
|
+
const el = await filter({value: encode([{key: 'status', comparator: 'eq', value: 'active'}])});
|
|
329
305
|
|
|
330
306
|
el.clear();
|
|
331
307
|
await el.updateComplete;
|
|
332
308
|
|
|
333
|
-
expect(
|
|
309
|
+
expect(chips(el)).to.deep.equal([]);
|
|
334
310
|
expect(el.value).to.equal('');
|
|
335
311
|
});
|
|
336
312
|
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
it('rebuilds the active pills from an encoded value', async () => {
|
|
344
|
-
const value = encode([
|
|
345
|
-
{key: 'status', comparator: 'eq', value: 'active'},
|
|
346
|
-
{key: 'email', comparator: 'contains', value: 'acme'},
|
|
347
|
-
]);
|
|
313
|
+
it('offers suggestions matching a typed value, without regard to case', async () => {
|
|
314
|
+
const el = await filter();
|
|
315
|
+
el.suggestions = {email: ['Ada@example.com', 'grace@example.com']};
|
|
316
|
+
await open(el);
|
|
317
|
+
await setRule(el, 'email');
|
|
348
318
|
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
319
|
+
const input = control<ZnInput>(el, 'Filter value');
|
|
320
|
+
input.value = 'ADA';
|
|
321
|
+
input.dispatchEvent(new Event('zn-input', {bubbles: true, composed: true}));
|
|
322
|
+
await el.updateComplete;
|
|
352
323
|
|
|
353
|
-
|
|
354
|
-
|
|
324
|
+
const shown = [...root(el).querySelectorAll('.filter__suggestion')];
|
|
325
|
+
expect(shown.map(b => b.textContent!.trim())).to.deep.equal(['Ada@example.com']);
|
|
355
326
|
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
327
|
+
click(shown[0]);
|
|
328
|
+
await el.updateComplete;
|
|
329
|
+
expect(root(el).querySelector('.filter__suggestion')).to.not.exist;
|
|
330
|
+
await apply(el);
|
|
331
|
+
expect(decode(el.value)).to.deep.equal([{key: 'email', comparator: 'contains', value: 'Ada@example.com'}]);
|
|
332
|
+
});
|
|
360
333
|
|
|
361
|
-
|
|
362
|
-
});
|
|
334
|
+
it('forgets typed text when the field changes', async () => {
|
|
335
|
+
const el = await filter({filters: [...FILTERS, {id: 'name', name: 'Name', operators: ['contains']}]});
|
|
336
|
+
el.suggestions = {email: ['Ada@example.com'], name: ['Adam']};
|
|
337
|
+
await open(el);
|
|
338
|
+
await setRule(el, 'email');
|
|
363
339
|
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
await el.updateComplete;
|
|
370
|
-
expect(pills(el)).to.deep.equal(['Role']);
|
|
340
|
+
const input = control<ZnInput>(el, 'Filter value');
|
|
341
|
+
input.value = 'ADA';
|
|
342
|
+
input.dispatchEvent(new Event('zn-input', {bubbles: true, composed: true}));
|
|
343
|
+
await el.updateComplete;
|
|
344
|
+
expect(root(el).querySelector('.filter__suggestion')).to.exist;
|
|
371
345
|
|
|
372
|
-
|
|
373
|
-
|
|
346
|
+
await setRule(el, 'name');
|
|
347
|
+
expect(root(el).querySelector('.filter__suggestion')).to.not.exist;
|
|
348
|
+
});
|
|
374
349
|
|
|
375
|
-
|
|
376
|
-
|
|
350
|
+
it('hands its chips to a filter whose source it is', async () => {
|
|
351
|
+
const wrap = await fixture<HTMLDivElement>(html`
|
|
352
|
+
<div>
|
|
353
|
+
<zn-data-table-filter .filters="${FILTERS}"
|
|
354
|
+
.value="${encode([{key: 'status', comparator: 'eq', value: 'active'}])}"></zn-data-table-filter>
|
|
355
|
+
<zn-data-table-filter></zn-data-table-filter>
|
|
356
|
+
</div>`);
|
|
357
|
+
const [source, mirror] = [...wrap.querySelectorAll<ZnDataTableFilter>('zn-data-table-filter')];
|
|
358
|
+
mirror.source = source;
|
|
359
|
+
await mirror.updateComplete;
|
|
360
|
+
await source.updateComplete;
|
|
361
|
+
|
|
362
|
+
expect(chips(source)).to.deep.equal([]);
|
|
363
|
+
expect(chips(mirror)).to.deep.equal(['Status is Active']);
|
|
364
|
+
expect(root(mirror).querySelector('.filter__toggle')).to.not.exist;
|
|
365
|
+
|
|
366
|
+
click(root(mirror).querySelector('.filter__chip__text'));
|
|
367
|
+
await source.updateComplete;
|
|
368
|
+
expect(root(source).querySelector('.filter__pop')).to.exist;
|
|
369
|
+
|
|
370
|
+
click(root(mirror).querySelector('.filter__chip__remove'));
|
|
371
|
+
await source.updateComplete;
|
|
372
|
+
await mirror.updateComplete;
|
|
373
|
+
expect(source.value).to.equal('');
|
|
374
|
+
expect(chips(mirror)).to.deep.equal([]);
|
|
377
375
|
});
|
|
378
376
|
});
|