@kubex/zinc 1.1.184 → 2.0.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/.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 +10344 -2583
- package/dist/vscode.html-custom-data.json +1102 -125
- package/dist/web-types.json +2217 -224
- package/dist/zn.d.ts +2306 -417
- package/dist/zn.min.css +1 -1
- package/dist/zn.min.js +2313 -1635
- 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/filter-wrapper.md +20 -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 +242 -11
- package/src/components/button/button.scss +133 -25
- 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 +17 -3
- package/src/components/cols/cols.scss +24 -13
- package/src/components/cols/cols.test.ts +33 -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 +364 -142
- package/src/components/data-table/data-table.scss +133 -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/filter-wrapper/filter-wrapper.component.ts +45 -10
- package/src/components/filter-wrapper/filter-wrapper.test.ts +58 -2
- 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 +625 -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
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
@use "../../wc";
|
|
2
|
+
|
|
3
|
+
:host {
|
|
4
|
+
display: inline-flex;
|
|
5
|
+
vertical-align: middle;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
.badge {
|
|
9
|
+
--badge-fg: var(--zn-color-neutral-fg);
|
|
10
|
+
--badge-bg: var(--zn-color-neutral-bg);
|
|
11
|
+
--badge-line: var(--zn-color-neutral-line);
|
|
12
|
+
--badge-solid: var(--zn-color-neutral-solid);
|
|
13
|
+
--badge-ink: 255, 255, 255;
|
|
14
|
+
|
|
15
|
+
box-sizing: border-box;
|
|
16
|
+
display: inline-flex;
|
|
17
|
+
align-items: center;
|
|
18
|
+
gap: var(--zn-badge-gap, 4.8px);
|
|
19
|
+
height: var(--zn-badge-height, 20px);
|
|
20
|
+
padding-inline: var(--zn-badge-padding-inline, 7.2px);
|
|
21
|
+
font-family: var(--zn-font-family-sans);
|
|
22
|
+
font-size: var(--zn-badge-font-size, 11px);
|
|
23
|
+
font-weight: var(--zn-font-weight-semibold);
|
|
24
|
+
line-height: 1;
|
|
25
|
+
white-space: nowrap;
|
|
26
|
+
color: var(--badge-fg);
|
|
27
|
+
background: var(--badge-bg);
|
|
28
|
+
border: 1px solid var(--badge-line);
|
|
29
|
+
border-radius: var(--zn-badge-border-radius, var(--zn-border-radius));
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
.badge--large {
|
|
33
|
+
height: var(--zn-badge-large-height, 24px);
|
|
34
|
+
padding-inline: var(--zn-badge-large-padding-inline, 9.6px);
|
|
35
|
+
font-size: var(--zn-badge-large-font-size, 12px);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
@each $type in (success, warning, danger, info, ai) {
|
|
39
|
+
.badge--#{$type} {
|
|
40
|
+
--badge-fg: var(--zn-color-#{$type}-fg);
|
|
41
|
+
--badge-bg: var(--zn-color-#{$type}-bg);
|
|
42
|
+
--badge-line: var(--zn-color-#{$type}-line);
|
|
43
|
+
--badge-solid: var(--zn-color-#{$type}-solid);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
.badge--warning {
|
|
48
|
+
--badge-ink: var(--zn-color-on-warning, 255, 255, 255);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
.badge--ai {
|
|
52
|
+
--badge-ink: var(--zn-color-on-ai, 255, 255, 255);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
.badge--solid {
|
|
56
|
+
color: rgb(var(--badge-ink));
|
|
57
|
+
background: var(--badge-solid);
|
|
58
|
+
border-color: var(--badge-solid);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
.badge--dot::before {
|
|
62
|
+
content: "";
|
|
63
|
+
flex: none;
|
|
64
|
+
width: 6.4px;
|
|
65
|
+
height: 6.4px;
|
|
66
|
+
border-radius: 50%;
|
|
67
|
+
background: var(--badge-solid);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
.badge--solid.badge--dot::before {
|
|
71
|
+
background: currentColor;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
.badge__icon {
|
|
75
|
+
flex: none;
|
|
76
|
+
|
|
77
|
+
&::part(icon) {
|
|
78
|
+
stroke-width: 1.75;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import '../../../dist/zn.min.js';
|
|
2
|
+
import { expect, fixture, html } from '@open-wc/testing';
|
|
3
|
+
|
|
4
|
+
const base = (el: HTMLElement) => el.shadowRoot!.querySelector<HTMLElement>('[part="base"]')!;
|
|
5
|
+
|
|
6
|
+
describe('<zn-badge>', () => {
|
|
7
|
+
it('should render a component', async () => {
|
|
8
|
+
const el = await fixture(html` <zn-badge></zn-badge> `);
|
|
9
|
+
|
|
10
|
+
expect(el).to.exist;
|
|
11
|
+
});
|
|
12
|
+
|
|
13
|
+
it('applies the type, size, solid and dot classes', async () => {
|
|
14
|
+
const el = await fixture<HTMLElement>(html`<zn-badge type="success" size="large" solid dot>Large</zn-badge>`);
|
|
15
|
+
|
|
16
|
+
expect([...base(el).classList]).to.include.members(
|
|
17
|
+
['badge--success', 'badge--large', 'badge--solid', 'badge--dot']);
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
it('shows the sparkle icon only on ai badges', async () => {
|
|
21
|
+
const ai = await fixture<HTMLElement>(html`<zn-badge type="ai">AI suggested</zn-badge>`);
|
|
22
|
+
const info = await fixture<HTMLElement>(html`<zn-badge type="info">Trial</zn-badge>`);
|
|
23
|
+
|
|
24
|
+
expect(ai.shadowRoot!.querySelector('zn-icon')).to.exist;
|
|
25
|
+
expect(info.shadowRoot!.querySelector('zn-icon')).to.not.exist;
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
it('fills a solid badge with its type colour', async () => {
|
|
29
|
+
const el = await fixture<HTMLElement>(html`
|
|
30
|
+
<zn-badge type="danger" solid style="--zn-color-danger-solid: rgb(217, 46, 75)">Urgent</zn-badge>`);
|
|
31
|
+
|
|
32
|
+
expect(getComputedStyle(base(el)).backgroundColor).to.equal('rgb(217, 46, 75)');
|
|
33
|
+
});
|
|
34
|
+
});
|
|
@@ -147,6 +147,7 @@ export default class ZnBulkActions extends ZincElement {
|
|
|
147
147
|
icon="delete"
|
|
148
148
|
icon-size="24"
|
|
149
149
|
color="transparent"
|
|
150
|
+
label="Remove rule"
|
|
150
151
|
@click="${(e: Event) => this._removeRule(uniqueId, e)}">
|
|
151
152
|
</zn-button>`;
|
|
152
153
|
|
|
@@ -260,21 +261,32 @@ export default class ZnBulkActions extends ZincElement {
|
|
|
260
261
|
return position;
|
|
261
262
|
}
|
|
262
263
|
|
|
263
|
-
private _changeRule(id: string, event: ZnChangeEvent) {
|
|
264
|
+
private async _changeRule(id: string, event: ZnChangeEvent) {
|
|
264
265
|
// remove the element from the dom
|
|
265
266
|
const pos: number = this._getRulePosition(id);
|
|
266
267
|
const select = event.target as ZnSelect;
|
|
268
|
+
const hadFocus = select.matches(':focus-within');
|
|
267
269
|
select.popup.active = false;
|
|
268
270
|
select?.parentElement?.remove();
|
|
269
271
|
// recreate the element based on the selected value;
|
|
270
272
|
this._removeRule(id, event as unknown as Event);
|
|
271
273
|
this._addRule(event as unknown as Event, '', pos);
|
|
274
|
+
|
|
275
|
+
const replacement = this.container.children[pos]?.querySelector<ZnSelect>('.query-builder__key');
|
|
276
|
+
if (hadFocus && replacement) {
|
|
277
|
+
await replacement.updateComplete;
|
|
278
|
+
replacement.focus();
|
|
279
|
+
}
|
|
272
280
|
}
|
|
273
281
|
|
|
274
282
|
private _removeRule(id: string, event: Event) {
|
|
275
283
|
this._selectedRules.delete(id);
|
|
276
284
|
const button = event.target as ZnButton;
|
|
277
|
-
button?.closest('.query-builder__row')
|
|
285
|
+
const row = button?.closest('.query-builder__row');
|
|
286
|
+
const hadFocus = row?.matches(':focus-within');
|
|
287
|
+
const neighbour = row?.nextElementSibling?.matches('.query-builder__row') ? row.nextElementSibling : row?.previousElementSibling;
|
|
288
|
+
row?.remove();
|
|
289
|
+
if (hadFocus) (neighbour?.querySelector<ZnButton>('.query-builder__remove')?.button ?? this.addRule).focus();
|
|
278
290
|
this._handleChange();
|
|
279
291
|
}
|
|
280
292
|
|
|
@@ -4,7 +4,7 @@ import {FormControlController, validValidityState} from "../../internal/form";
|
|
|
4
4
|
import {HasSlotController} from '../../internal/slot';
|
|
5
5
|
import {html, literal} from 'lit/static-html.js';
|
|
6
6
|
import {ifDefined} from 'lit/directives/if-defined.js';
|
|
7
|
-
import {property, query, queryAll} from 'lit/decorators.js';
|
|
7
|
+
import {property, query, queryAll, state} from 'lit/decorators.js';
|
|
8
8
|
import {styleMap} from "lit/directives/style-map.js";
|
|
9
9
|
import {watch} from '../../internal/watch';
|
|
10
10
|
import ZincElement from '../../internal/zinc-element';
|
|
@@ -12,6 +12,7 @@ import ZnDropdown from "../dropdown";
|
|
|
12
12
|
import ZnIcon from "../icon";
|
|
13
13
|
import ZnTooltip from "../tooltip";
|
|
14
14
|
import type {IconColor, IconLibrary} from "../icon";
|
|
15
|
+
import type ZnMenu from "../menu";
|
|
15
16
|
import type {ZincFormControl} from '../../internal/zinc-element';
|
|
16
17
|
|
|
17
18
|
import sharedStyles from '../../../scss/shared/index.scss';
|
|
@@ -23,6 +24,7 @@ import styles from './button.scss';
|
|
|
23
24
|
* @status stable
|
|
24
25
|
* @since 2.0
|
|
25
26
|
*
|
|
27
|
+
* @dependency zn-dropdown
|
|
26
28
|
* @dependency zn-icon
|
|
27
29
|
* @dependency zn-tooltip
|
|
28
30
|
*
|
|
@@ -34,6 +36,7 @@ import styles from './button.scss';
|
|
|
34
36
|
* @slot prefix - A presentational prefix icon or similar element.
|
|
35
37
|
* @slot suffix - A presentational suffix icon or similar element.
|
|
36
38
|
* @slot cancel - Slot for custom cancel button/content when autoClick is active.
|
|
39
|
+
* @slot menu - A `<zn-menu>` of advanced options, opened by a long press, a right click, or ArrowDown on the button.
|
|
37
40
|
*
|
|
38
41
|
* @csspart base - The component's base wrapper.
|
|
39
42
|
* @csspart prefix - The container that wraps the prefix.
|
|
@@ -45,26 +48,43 @@ import styles from './button.scss';
|
|
|
45
48
|
export default class ZnButton extends ZincElement implements ZincFormControl {
|
|
46
49
|
static styles: CSSResultGroup = [unsafeCSS(sharedStyles), unsafeCSS(styles)];
|
|
47
50
|
static dependencies = {
|
|
51
|
+
'zn-dropdown': ZnDropdown,
|
|
48
52
|
'zn-tooltip': ZnTooltip,
|
|
49
53
|
'zn-icon': ZnIcon
|
|
50
54
|
};
|
|
51
55
|
|
|
52
56
|
private readonly formControlController = new FormControlController(this);
|
|
53
|
-
private readonly hasSlotController = new HasSlotController(this, '[default]');
|
|
57
|
+
private readonly hasSlotController = new HasSlotController(this, '[default]', 'menu');
|
|
54
58
|
private _autoClickTimeout: number | undefined;
|
|
55
59
|
private _loadingState = {
|
|
56
60
|
countdown: null as number | null,
|
|
57
61
|
interval: undefined as number | undefined,
|
|
58
62
|
};
|
|
59
63
|
|
|
64
|
+
// Long press menu
|
|
65
|
+
private _longPressTimeout: number | undefined;
|
|
66
|
+
private _longPressOrigin: { x: number, y: number } | null = null;
|
|
67
|
+
/** The pointer that opened the menu is still down, so releasing it over an item selects that item. */
|
|
68
|
+
private _menuPointerHeld = false;
|
|
69
|
+
/** Swallows the click that ends a long press, so the button's own action does not run. */
|
|
70
|
+
private _suppressClick = false;
|
|
71
|
+
private _menuHadFocus = false;
|
|
72
|
+
|
|
73
|
+
@state() private menuOpen = false;
|
|
74
|
+
|
|
60
75
|
@query('.button') button: HTMLButtonElement;
|
|
76
|
+
@query('.button__menu') menuDropdown: ZnDropdown;
|
|
61
77
|
@queryAll('.loading-countdown') countdownContainer: HTMLElement[];
|
|
62
78
|
|
|
63
|
-
|
|
79
|
+
/** `ai` is reserved for actions that invoke or act on AI-generated content. */
|
|
80
|
+
@property({}) color: 'default' | 'primary' | 'secondary' | 'error' | 'info' | 'success' | 'warning' | 'ai' |
|
|
64
81
|
'transparent' | 'star' | (string & Record<never, never>) = 'default';
|
|
82
|
+
@property() size: 'small' | 'medium' | 'large' = 'medium';
|
|
65
83
|
@property({attribute: 'hover-color'}) hoverColor: string;
|
|
66
84
|
@property({type: Boolean}) text = false;
|
|
67
85
|
@property({type: Boolean}) outline = false;
|
|
86
|
+
/** Keeps the filled look where a container forces `text`, such as a page header's action menu. */
|
|
87
|
+
@property({type: Boolean}) solid = false;
|
|
68
88
|
@property({type: Boolean}) disabled = false;
|
|
69
89
|
@property({type: Boolean}) grow = false;
|
|
70
90
|
@property({type: Boolean}) square = false;
|
|
@@ -89,6 +109,13 @@ export default class ZnButton extends ZincElement implements ZincFormControl {
|
|
|
89
109
|
@property({type: Boolean, reflect: true}) pill = false;
|
|
90
110
|
@property({type: Boolean, attribute: 'panel-bg'}) panelBackground = false;
|
|
91
111
|
|
|
112
|
+
/** How long, in milliseconds, the button must be held to open the `menu` slot. */
|
|
113
|
+
@property({type: Number, attribute: 'long-press-delay'}) longPressDelay = 500;
|
|
114
|
+
|
|
115
|
+
/** Where the `menu` slot opens relative to the button. */
|
|
116
|
+
@property({attribute: 'menu-placement'}) menuPlacement: 'top' | 'top-start' | 'top-end' | 'right' | 'right-start' |
|
|
117
|
+
'right-end' | 'bottom' | 'bottom-start' | 'bottom-end' | 'left' | 'left-start' | 'left-end' = 'bottom-start';
|
|
118
|
+
|
|
92
119
|
@property({attribute: 'dropdown-closer', type: Boolean}) dropdownCloser = false;
|
|
93
120
|
|
|
94
121
|
@property({type: Number}) notification: number;
|
|
@@ -131,6 +158,12 @@ export default class ZnButton extends ZincElement implements ZincFormControl {
|
|
|
131
158
|
/** Toggle state, forwarded to the inner button's `aria-pressed`. */
|
|
132
159
|
@property({attribute: 'aria-pressed'}) pressed: 'true' | 'false' | 'mixed';
|
|
133
160
|
|
|
161
|
+
/** Popup state, forwarded to the inner button's `aria-expanded`. */
|
|
162
|
+
@property({attribute: 'aria-expanded'}) expanded: 'true' | 'false';
|
|
163
|
+
|
|
164
|
+
/** Popup type, forwarded to the inner button's `aria-haspopup`. */
|
|
165
|
+
@property({attribute: 'aria-haspopup'}) hasPopup: string;
|
|
166
|
+
|
|
134
167
|
// Auto Click Specific
|
|
135
168
|
@property({type: Boolean, attribute: 'auto-click'}) autoClick = false;
|
|
136
169
|
@property({type: Number, attribute: 'auto-click-delay'}) autoClickDelay = 2000;
|
|
@@ -141,6 +174,12 @@ export default class ZnButton extends ZincElement implements ZincFormControl {
|
|
|
141
174
|
}) loadingTextPosition: 'left' | 'right' | 'center' | string = 'center';
|
|
142
175
|
@property({type: Boolean}) loading = false;
|
|
143
176
|
|
|
177
|
+
/** Shows a spinner and ignores clicks, e.g. while a request is in flight. */
|
|
178
|
+
@property({type: Boolean, reflect: true}) processing = false;
|
|
179
|
+
|
|
180
|
+
/** Replaces the label while processing. */
|
|
181
|
+
@property({attribute: 'processing-text'}) processingText = '';
|
|
182
|
+
|
|
144
183
|
get validity() {
|
|
145
184
|
if (this._isButton() && this.button) {
|
|
146
185
|
return (this.button as HTMLButtonElement).validity;
|
|
@@ -163,9 +202,16 @@ export default class ZnButton extends ZincElement implements ZincFormControl {
|
|
|
163
202
|
}
|
|
164
203
|
}
|
|
165
204
|
|
|
205
|
+
connectedCallback() {
|
|
206
|
+
super.connectedCallback();
|
|
207
|
+
this.addEventListener('click', this.handleHostClickCapture, {capture: true});
|
|
208
|
+
}
|
|
209
|
+
|
|
166
210
|
disconnectedCallback() {
|
|
167
211
|
super.disconnectedCallback();
|
|
168
212
|
this.teardownAutoClick();
|
|
213
|
+
this.cancelLongPress();
|
|
214
|
+
this.removeEventListener('click', this.handleHostClickCapture, {capture: true});
|
|
169
215
|
}
|
|
170
216
|
|
|
171
217
|
@watch('autoClick')
|
|
@@ -242,7 +288,7 @@ export default class ZnButton extends ZincElement implements ZincFormControl {
|
|
|
242
288
|
}
|
|
243
289
|
|
|
244
290
|
handleClick = () => {
|
|
245
|
-
if (this.disabled) {
|
|
291
|
+
if (this.disabled || this.processing) {
|
|
246
292
|
return;
|
|
247
293
|
}
|
|
248
294
|
|
|
@@ -264,13 +310,180 @@ export default class ZnButton extends ZincElement implements ZincFormControl {
|
|
|
264
310
|
dropdown?.hide();
|
|
265
311
|
}
|
|
266
312
|
|
|
313
|
+
// Passing the button through carries its name, value and formaction onto the submission.
|
|
267
314
|
if (this.type === 'submit') {
|
|
268
|
-
this.formControlController.submit();
|
|
315
|
+
this.formControlController.submit(this);
|
|
269
316
|
}
|
|
270
317
|
|
|
271
318
|
if (this.type === 'reset') {
|
|
272
|
-
this.formControlController.reset();
|
|
319
|
+
this.formControlController.reset(this);
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
private _hasMenu() {
|
|
324
|
+
return this.hasSlotController.test('menu');
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
private getMenu() {
|
|
328
|
+
return this.querySelector<ZnMenu>(':scope > zn-menu[slot="menu"], :scope > [slot="menu"] zn-menu');
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
/** Opens the advanced options in the `menu` slot. */
|
|
332
|
+
async showMenu() {
|
|
333
|
+
if (!this._hasMenu() || this.disabled || this.processing) return;
|
|
334
|
+
await this.updateComplete;
|
|
335
|
+
await this.menuDropdown?.show();
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
/** Closes the advanced options in the `menu` slot. */
|
|
339
|
+
async hideMenu() {
|
|
340
|
+
await this.menuDropdown?.hide();
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
// Runs before any click listener on the button, including the consumer's own
|
|
344
|
+
private handleHostClickCapture = (event: MouseEvent) => {
|
|
345
|
+
if (!this._suppressClick) return;
|
|
346
|
+
|
|
347
|
+
const menuSlot = this.shadowRoot?.querySelector('slot[name="menu"]');
|
|
348
|
+
const fromMenu = event.composedPath().some(el => (el as Element).assignedSlot === menuSlot);
|
|
349
|
+
if (fromMenu) return;
|
|
350
|
+
|
|
351
|
+
this._suppressClick = false;
|
|
352
|
+
event.preventDefault();
|
|
353
|
+
event.stopImmediatePropagation();
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
private handleMenuPointerDown = (event: PointerEvent) => {
|
|
357
|
+
if (!this._hasMenu() || this.disabled || this.processing || event.button !== 0) return;
|
|
358
|
+
|
|
359
|
+
// Pressing the button while its menu is open only closes the menu, which the dropdown does on mousedown
|
|
360
|
+
if (this.menuOpen) {
|
|
361
|
+
this._suppressClick = true;
|
|
362
|
+
document.addEventListener('pointerup', this.handleMenuPointerUp);
|
|
363
|
+
return;
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
this.cancelLongPress();
|
|
367
|
+
this._longPressOrigin = {x: event.clientX, y: event.clientY};
|
|
368
|
+
this._longPressTimeout = window.setTimeout(() => {
|
|
369
|
+
this._longPressTimeout = undefined;
|
|
370
|
+
this._suppressClick = true;
|
|
371
|
+
this._menuPointerHeld = true;
|
|
372
|
+
this.showMenu().then(r => r);
|
|
373
|
+
}, this.longPressDelay);
|
|
374
|
+
|
|
375
|
+
document.addEventListener('pointermove', this.handleMenuPointerMove);
|
|
376
|
+
document.addEventListener('pointerup', this.handleMenuPointerUp);
|
|
377
|
+
document.addEventListener('pointercancel', this.handleMenuPointerCancel);
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
private handleMenuPointerMove = (event: PointerEvent) => {
|
|
381
|
+
if (this._longPressTimeout === undefined || !this._longPressOrigin) return;
|
|
382
|
+
|
|
383
|
+
const moved = Math.hypot(event.clientX - this._longPressOrigin.x, event.clientY - this._longPressOrigin.y);
|
|
384
|
+
if (moved > 8) {
|
|
385
|
+
this.cancelLongPress();
|
|
386
|
+
}
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
private handleMenuPointerUp = (event: PointerEvent) => {
|
|
390
|
+
const held = this._menuPointerHeld;
|
|
391
|
+
this.cancelLongPress();
|
|
392
|
+
|
|
393
|
+
// Press, drag onto an item and release selects it, as in the macOS Dock
|
|
394
|
+
if (held) {
|
|
395
|
+
const item = document.elementFromPoint(event.clientX, event.clientY)?.closest('zn-menu-item');
|
|
396
|
+
if (item && this.contains(item) && !item.hasAttribute('disabled')) {
|
|
397
|
+
(item as HTMLElement).click();
|
|
398
|
+
}
|
|
273
399
|
}
|
|
400
|
+
|
|
401
|
+
// A long press on touch ends without a click, so the flag must not outlive this gesture
|
|
402
|
+
if (this._suppressClick) {
|
|
403
|
+
window.setTimeout(() => this._suppressClick = false, 300);
|
|
404
|
+
}
|
|
405
|
+
}
|
|
406
|
+
|
|
407
|
+
private handleMenuPointerCancel = () => {
|
|
408
|
+
this.cancelLongPress();
|
|
409
|
+
this._suppressClick = false;
|
|
410
|
+
}
|
|
411
|
+
|
|
412
|
+
private cancelLongPress() {
|
|
413
|
+
window.clearTimeout(this._longPressTimeout);
|
|
414
|
+
this._longPressTimeout = undefined;
|
|
415
|
+
this._longPressOrigin = null;
|
|
416
|
+
this._menuPointerHeld = false;
|
|
417
|
+
document.removeEventListener('pointermove', this.handleMenuPointerMove);
|
|
418
|
+
document.removeEventListener('pointerup', this.handleMenuPointerUp);
|
|
419
|
+
document.removeEventListener('pointercancel', this.handleMenuPointerCancel);
|
|
420
|
+
}
|
|
421
|
+
|
|
422
|
+
private handleMenuContextMenu = (event: MouseEvent) => {
|
|
423
|
+
if (!this._hasMenu()) return;
|
|
424
|
+
|
|
425
|
+
event.preventDefault();
|
|
426
|
+
// A touch long press also fires contextmenu, after the menu has already opened
|
|
427
|
+
if (!this.menuOpen) {
|
|
428
|
+
this.cancelLongPress();
|
|
429
|
+
this.showMenu().then(r => r);
|
|
430
|
+
}
|
|
431
|
+
}
|
|
432
|
+
|
|
433
|
+
private handleMenuKeyDown = async (event: KeyboardEvent) => {
|
|
434
|
+
if (!this._hasMenu()) return;
|
|
435
|
+
|
|
436
|
+
const opensMenu = event.key === 'ArrowDown' || event.key === 'ContextMenu' || (event.key === 'F10' && event.shiftKey);
|
|
437
|
+
if (!opensMenu) return;
|
|
438
|
+
|
|
439
|
+
event.preventDefault();
|
|
440
|
+
await this.showMenu();
|
|
441
|
+
|
|
442
|
+
const menu = this.getMenu();
|
|
443
|
+
const first = menu?.getAllItems()[0];
|
|
444
|
+
if (menu && first) {
|
|
445
|
+
menu.setCurrentItem(first);
|
|
446
|
+
first.focus();
|
|
447
|
+
}
|
|
448
|
+
}
|
|
449
|
+
|
|
450
|
+
private handleMenuShow = (event: Event) => {
|
|
451
|
+
if (event.target !== this.menuDropdown) return;
|
|
452
|
+
this.menuOpen = true;
|
|
453
|
+
}
|
|
454
|
+
|
|
455
|
+
private handleMenuHide = (event: Event) => {
|
|
456
|
+
if (event.target !== this.menuDropdown) return;
|
|
457
|
+
this.menuOpen = false;
|
|
458
|
+
this._menuHadFocus = !!this.getMenu()?.matches(':focus-within');
|
|
459
|
+
}
|
|
460
|
+
|
|
461
|
+
// The dropdown's anchor is not focusable, so focus returns to the button itself
|
|
462
|
+
private handleMenuAfterHide = (event: Event) => {
|
|
463
|
+
if (event.target !== this.menuDropdown) return;
|
|
464
|
+
if (this._menuHadFocus) {
|
|
465
|
+
this._menuHadFocus = false;
|
|
466
|
+
this.button?.focus();
|
|
467
|
+
}
|
|
468
|
+
}
|
|
469
|
+
|
|
470
|
+
private _renderMenu() {
|
|
471
|
+
if (!this._hasMenu()) {
|
|
472
|
+
// Kept in the tree so adding a menu later fires slotchange
|
|
473
|
+
return html`<slot name="menu" hidden></slot>`;
|
|
474
|
+
}
|
|
475
|
+
|
|
476
|
+
return html`
|
|
477
|
+
<zn-dropdown class="button__menu"
|
|
478
|
+
placement=${this.menuPlacement}
|
|
479
|
+
@zn-show=${this.handleMenuShow}
|
|
480
|
+
@zn-hide=${this.handleMenuHide}
|
|
481
|
+
@zn-after-hide=${this.handleMenuAfterHide}>
|
|
482
|
+
<span slot="trigger" class="button__menu-anchor"></span>
|
|
483
|
+
<div class="button__menu-panel">
|
|
484
|
+
<slot name="menu"></slot>
|
|
485
|
+
</div>
|
|
486
|
+
</zn-dropdown>`;
|
|
274
487
|
}
|
|
275
488
|
|
|
276
489
|
private _isLink() {
|
|
@@ -299,6 +512,8 @@ export default class ZnButton extends ZincElement implements ZincFormControl {
|
|
|
299
512
|
return 'rgb(var(--zn-color-success))';
|
|
300
513
|
case 'warning':
|
|
301
514
|
return 'rgb(var(--zn-color-warning))';
|
|
515
|
+
case 'ai':
|
|
516
|
+
return 'var(--zn-color-ai-fg)';
|
|
302
517
|
case 'transparent':
|
|
303
518
|
return 'inherit';
|
|
304
519
|
case 'star':
|
|
@@ -376,9 +591,10 @@ export default class ZnButton extends ZincElement implements ZincFormControl {
|
|
|
376
591
|
|
|
377
592
|
protected render(): unknown {
|
|
378
593
|
const isLink = this._isLink();
|
|
594
|
+
const hasMenu = this._hasMenu();
|
|
379
595
|
const showCancel = this.loading && this.autoClick;
|
|
380
596
|
const resolvedIconSize = this.iconSize ? this.iconSize : 20;
|
|
381
|
-
const icon = this.icon && !this.loading ? html`
|
|
597
|
+
const icon = this.icon && !this.loading && !this.processing ? html`
|
|
382
598
|
<zn-icon part="icon" src="${this.icon}" id="xy2" size="${resolvedIconSize}"
|
|
383
599
|
color="${ifDefined(this.iconColor)}" fill="${ifDefined(this.iconFill)}"
|
|
384
600
|
library="${ifDefined(this.iconLibrary)}"></zn-icon>`
|
|
@@ -411,10 +627,13 @@ export default class ZnButton extends ZincElement implements ZincFormControl {
|
|
|
411
627
|
'button--info': this.color === 'info',
|
|
412
628
|
'button--success': this.color === 'success',
|
|
413
629
|
'button--warning': this.color === 'warning',
|
|
630
|
+
'button--ai': this.color === 'ai',
|
|
631
|
+
'button--small': this.size === 'small',
|
|
632
|
+
'button--large': this.size === 'large',
|
|
414
633
|
'button--transparent': this.color === 'transparent',
|
|
415
634
|
'button--star': this.color === 'star',
|
|
416
635
|
'button--outline': this.outline,
|
|
417
|
-
'button--text': (this.text && !this.outline),
|
|
636
|
+
'button--text': (this.text && !this.outline && !this.solid),
|
|
418
637
|
'button--icon-button': !!this.iconButton,
|
|
419
638
|
'button--plain': !!this.iconButton && this.plain,
|
|
420
639
|
'button--pill': this.pill,
|
|
@@ -431,6 +650,8 @@ export default class ZnButton extends ZincElement implements ZincFormControl {
|
|
|
431
650
|
'button--has-notification': notification !== undefined && notification !== 0,
|
|
432
651
|
'button--muted-notification': this.mutedNotifications || notification === -2,
|
|
433
652
|
'button--notification-dot': notification !== undefined && notification < 0,
|
|
653
|
+
'button--processing': this.processing,
|
|
654
|
+
'button--has-menu': hasMenu,
|
|
434
655
|
})}"
|
|
435
656
|
type="${ifDefined(this.type)}"
|
|
436
657
|
href="${ifDefined(this.href)}"
|
|
@@ -440,15 +661,25 @@ export default class ZnButton extends ZincElement implements ZincFormControl {
|
|
|
440
661
|
gaid="${ifDefined(this.gaid)}"
|
|
441
662
|
aria-label="${ifDefined(ariaLabel)}"
|
|
442
663
|
aria-pressed="${ifDefined(isLink ? undefined : this.pressed)}"
|
|
664
|
+
aria-expanded="${ifDefined(this.expanded ?? (hasMenu ? String(this.menuOpen) : undefined))}"
|
|
665
|
+
aria-haspopup="${ifDefined(this.hasPopup ?? (hasMenu ? 'menu' : undefined))}"
|
|
666
|
+
draggable="${ifDefined(isLink && hasMenu ? 'false' : undefined)}"
|
|
667
|
+
aria-busy="${this.processing ? 'true' : nothing}"
|
|
443
668
|
data-notification="${ifDefined(notification)}"
|
|
444
669
|
disabled="${this.disabled || nothing}"
|
|
445
670
|
style=${styleMap(buttonStyles)}
|
|
446
|
-
@click="${this.handleClick}"
|
|
671
|
+
@click="${this.handleClick}"
|
|
672
|
+
@pointerdown="${this.handleMenuPointerDown}"
|
|
673
|
+
@contextmenu="${this.handleMenuContextMenu}"
|
|
674
|
+
@keydown="${this.handleMenuKeyDown}">
|
|
447
675
|
${this.iconPosition === 'left' ? icon : ''}
|
|
676
|
+
${this.processing ? html`<span part="spinner" class="button__spinner"></span>` : ''}
|
|
677
|
+
${this.processing && this.processingText ? html`<span class="button__processing-text">${this.processingText}</span>` : ''}
|
|
448
678
|
<slot part="label"
|
|
449
679
|
class="${classMap({
|
|
450
680
|
'button__label': true,
|
|
451
|
-
'button__label--hidden': this.loading
|
|
681
|
+
'button__label--hidden': this.loading,
|
|
682
|
+
'button__label--replaced': this.processing && !!this.processingText
|
|
452
683
|
})}"
|
|
453
684
|
style="--loading-duration: ${this.autoClickDelay / 1000}s">
|
|
454
685
|
${this.content}
|
|
@@ -473,7 +704,7 @@ export default class ZnButton extends ZincElement implements ZincFormControl {
|
|
|
473
704
|
</zn-tooltip>`;
|
|
474
705
|
}
|
|
475
706
|
|
|
476
|
-
return content
|
|
707
|
+
return html`${content}${this._renderMenu()}`;
|
|
477
708
|
}
|
|
478
709
|
|
|
479
710
|
private _getLoadingContainer() {
|