@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
|
@@ -5,9 +5,10 @@
|
|
|
5
5
|
display: contents;
|
|
6
6
|
}
|
|
7
7
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
8
|
+
// Content loaded from a tab's uri sits inline in the tab: the tabs' own padding already spaces it
|
|
9
|
+
#content > [data-self-uri] > zn-sp {
|
|
10
|
+
--zn-sp-padding: 0;
|
|
11
|
+
}
|
|
11
12
|
|
|
12
13
|
#mid, #content {
|
|
13
14
|
flex: 1;
|
|
@@ -26,8 +27,12 @@
|
|
|
26
27
|
max-height: 100%;
|
|
27
28
|
width: 100%;
|
|
28
29
|
|
|
29
|
-
zn-header
|
|
30
|
-
|
|
30
|
+
zn-header {
|
|
31
|
+
padding: var(--zn-panel-header-padding, var(--zn-base-gap));
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
zn-header::part(content) {
|
|
35
|
+
padding: 0;
|
|
31
36
|
}
|
|
32
37
|
}
|
|
33
38
|
|
|
@@ -39,10 +44,34 @@ h1, h2 {
|
|
|
39
44
|
|
|
40
45
|
|
|
41
46
|
#mid {
|
|
42
|
-
container-type: inline-size;
|
|
43
47
|
flex-direction: row;
|
|
44
48
|
}
|
|
45
49
|
|
|
50
|
+
:host([gap]) #mid {
|
|
51
|
+
gap: var(--zn-gap, var(--zn-spacing-medium));
|
|
52
|
+
align-items: flex-start;
|
|
53
|
+
|
|
54
|
+
// The side card keeps its own width; the content takes the rest.
|
|
55
|
+
> ::slotted([slot="left"]),
|
|
56
|
+
> ::slotted([slot="right"]) {
|
|
57
|
+
flex-grow: 0;
|
|
58
|
+
flex-shrink: 0;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
// The container for the side-card stacking below and for queries from the tab content: #mid is
|
|
63
|
+
// the same width, and every nested container costs Safari a full layout per restyle beneath it.
|
|
64
|
+
.tabs {
|
|
65
|
+
container: zn-tabs / inline-size;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
@container zn-tabs (max-width: 900px) {
|
|
69
|
+
:host([gap]) #mid {
|
|
70
|
+
flex-direction: column;
|
|
71
|
+
align-items: stretch;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
|
|
46
75
|
#content {
|
|
47
76
|
flex: 1;
|
|
48
77
|
max-height: 100%;
|
|
@@ -60,8 +89,19 @@ h1, h2 {
|
|
|
60
89
|
}
|
|
61
90
|
|
|
62
91
|
:host([no-scroll]) {
|
|
92
|
+
// Clipped rather than hidden so focus rings on fields flush with the edge still show
|
|
93
|
+
.tabs, #mid, #content {
|
|
94
|
+
overflow: clip;
|
|
95
|
+
overflow-clip-margin: var(--zn-focus-ring-outset);
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
// Unlike hidden, clip keeps a flex item's minimum size at its content's, so #mid would grow past the tabs
|
|
99
|
+
#mid {
|
|
100
|
+
min-height: 0;
|
|
101
|
+
min-width: 0;
|
|
102
|
+
}
|
|
103
|
+
|
|
63
104
|
#content {
|
|
64
|
-
overflow: hidden;
|
|
65
105
|
|
|
66
106
|
> div {
|
|
67
107
|
max-height: 100%;
|
|
@@ -132,6 +172,7 @@ h1, h2 {
|
|
|
132
172
|
}
|
|
133
173
|
|
|
134
174
|
h2 {
|
|
175
|
+
font-family: var(--zn-text-h1-font-family, inherit);
|
|
135
176
|
font-weight: var(--zn-font-weight-bold);
|
|
136
177
|
flex-grow: 1;
|
|
137
178
|
font-size: var(--zn-font-size-medium);
|
|
@@ -10,6 +10,79 @@ describe('<zn-tabs>', () => {
|
|
|
10
10
|
expect(el).to.exist;
|
|
11
11
|
});
|
|
12
12
|
|
|
13
|
+
describe('panel entrance', () => {
|
|
14
|
+
const renderTabs = () => fixture<ZnTabs>(html`
|
|
15
|
+
<zn-tabs active="first">
|
|
16
|
+
<zn-navbar slot="top">
|
|
17
|
+
<li tab="first">First</li>
|
|
18
|
+
<li tab="second">Second</li>
|
|
19
|
+
</zn-navbar>
|
|
20
|
+
<div id="first">First panel</div>
|
|
21
|
+
<div id="second">Second panel</div>
|
|
22
|
+
</zn-tabs>
|
|
23
|
+
`);
|
|
24
|
+
const fading = (el: Element) => el.getAnimations().filter(a => a.playState === 'running').length;
|
|
25
|
+
|
|
26
|
+
it('fades in a panel the pointer switched to', async () => {
|
|
27
|
+
const el = await renderTabs();
|
|
28
|
+
await el.updateComplete;
|
|
29
|
+
|
|
30
|
+
const second = el.querySelector<HTMLElement>('li[tab="second"]')!;
|
|
31
|
+
second.dispatchEvent(new PointerEvent('pointerdown', {bubbles: true, composed: true}));
|
|
32
|
+
second.click();
|
|
33
|
+
await aTimeout(40);
|
|
34
|
+
|
|
35
|
+
expect(fading(el.querySelector('#second')!)).to.equal(1);
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
it('stays still on first render and on keyboard switches', async () => {
|
|
39
|
+
// As if a click had just opened the page holding these tabs
|
|
40
|
+
document.body.dispatchEvent(new PointerEvent('pointerdown', {bubbles: true}));
|
|
41
|
+
const el = await fixture<ZnTabs>(html`
|
|
42
|
+
<zn-tabs>
|
|
43
|
+
<zn-navbar slot="top">
|
|
44
|
+
<li tab="first">First</li>
|
|
45
|
+
<li tab="second">Second</li>
|
|
46
|
+
</zn-navbar>
|
|
47
|
+
<div id="first">First panel</div>
|
|
48
|
+
<div id="second">Second panel</div>
|
|
49
|
+
</zn-tabs>
|
|
50
|
+
`);
|
|
51
|
+
await el.updateComplete;
|
|
52
|
+
expect(fading(el.querySelector('#first')!)).to.equal(0);
|
|
53
|
+
|
|
54
|
+
el.querySelector<HTMLElement>('li[tab="second"]')!.dispatchEvent(new KeyboardEvent('keydown', {key: 'Enter'}));
|
|
55
|
+
await aTimeout(40);
|
|
56
|
+
|
|
57
|
+
expect(el.querySelector('#second')!.hasAttribute('selected')).to.be.true;
|
|
58
|
+
expect(fading(el.querySelector('#second')!)).to.equal(0);
|
|
59
|
+
});
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
it('preloads a uri tab only once the pointer rests on it', async () => {
|
|
63
|
+
const el = await fixture<ZnTabs>(html`
|
|
64
|
+
<zn-tabs>
|
|
65
|
+
<zn-navbar slot="top">
|
|
66
|
+
<li tab-uri="/default">Default</li>
|
|
67
|
+
<li tab-uri="/passed-over">Passed</li>
|
|
68
|
+
<li tab-uri="/rested-on">Rested</li>
|
|
69
|
+
</zn-navbar>
|
|
70
|
+
</zn-tabs>
|
|
71
|
+
`);
|
|
72
|
+
await el.updateComplete;
|
|
73
|
+
const [, passed, rested] = Array.from(el.querySelectorAll<HTMLElement>('li[tab-uri]'));
|
|
74
|
+
expect(passed.hasAttribute('tab') || rested.hasAttribute('tab')).to.be.false;
|
|
75
|
+
|
|
76
|
+
passed.dispatchEvent(new MouseEvent('mouseenter'));
|
|
77
|
+
await aTimeout(50);
|
|
78
|
+
passed.dispatchEvent(new MouseEvent('mouseleave'));
|
|
79
|
+
rested.dispatchEvent(new MouseEvent('mouseenter'));
|
|
80
|
+
await aTimeout(250);
|
|
81
|
+
|
|
82
|
+
expect(passed.hasAttribute('tab')).to.be.false;
|
|
83
|
+
expect(rested.hasAttribute('tab')).to.be.true;
|
|
84
|
+
});
|
|
85
|
+
|
|
13
86
|
it('does not register tabs belonging to a nested zn-page', async () => {
|
|
14
87
|
const el = await fixture<ZnTabs>(html`
|
|
15
88
|
<zn-tabs>
|
|
@@ -112,6 +185,47 @@ describe('<zn-tabs>', () => {
|
|
|
112
185
|
|
|
113
186
|
expect(wrapper.scrollTop).to.equal(0);
|
|
114
187
|
});
|
|
188
|
+
|
|
189
|
+
it('scrolls nested enclosing scrollers only as far as the tabs need', async () => {
|
|
190
|
+
const outer = await fixture<HTMLElement>(html`
|
|
191
|
+
<div style="height: 300px; overflow: auto;">
|
|
192
|
+
<div style="height: 2000px;">Above the inner scroller</div>
|
|
193
|
+
<div style="height: 300px; overflow: auto;">
|
|
194
|
+
<zn-tabs active="first">${panels}</zn-tabs>
|
|
195
|
+
</div>
|
|
196
|
+
<div style="height: 2000px;">Below the inner scroller</div>
|
|
197
|
+
</div>
|
|
198
|
+
`);
|
|
199
|
+
const inner = outer.children[1] as HTMLElement;
|
|
200
|
+
const el = inner.querySelector<ZnTabs>('zn-tabs')!;
|
|
201
|
+
await aTimeout(40);
|
|
202
|
+
|
|
203
|
+
inner.scrollTop = 500;
|
|
204
|
+
outer.scrollTop = 2100;
|
|
205
|
+
|
|
206
|
+
await openSecondTab(el);
|
|
207
|
+
|
|
208
|
+
expect(inner.scrollTop).to.equal(0);
|
|
209
|
+
expect(outer.scrollTop).to.equal(2000);
|
|
210
|
+
});
|
|
211
|
+
|
|
212
|
+
it('leaves an enclosing scroller alone while the tabs are still in view', async () => {
|
|
213
|
+
const wrapper = await fixture<HTMLElement>(html`
|
|
214
|
+
<div style="height: 200px; overflow: auto;">
|
|
215
|
+
<div style="height: 100px;">Above the tabs</div>
|
|
216
|
+
<zn-tabs active="first">${panels}</zn-tabs>
|
|
217
|
+
</div>
|
|
218
|
+
`);
|
|
219
|
+
const el = wrapper.querySelector<ZnTabs>('zn-tabs')!;
|
|
220
|
+
await aTimeout(40);
|
|
221
|
+
|
|
222
|
+
wrapper.scrollTop = 60;
|
|
223
|
+
expect(wrapper.scrollTop, 'the enclosing scroller never scrolled').to.equal(60);
|
|
224
|
+
|
|
225
|
+
await openSecondTab(el);
|
|
226
|
+
|
|
227
|
+
expect(wrapper.scrollTop).to.equal(60);
|
|
228
|
+
});
|
|
115
229
|
});
|
|
116
230
|
|
|
117
231
|
describe('selection persistence', () => {
|
|
@@ -158,6 +272,61 @@ describe('<zn-tabs>', () => {
|
|
|
158
272
|
expect(restored.getAttribute('active')).to.equal('second');
|
|
159
273
|
});
|
|
160
274
|
|
|
275
|
+
it('opens a tab added since the page was last shown, with select-added', async () => {
|
|
276
|
+
const render = (withThird: boolean) => fixture<ZnTabs>(html`
|
|
277
|
+
<zn-tabs store-key=${storeKey} active="first" select-added>
|
|
278
|
+
<zn-navbar slot="top">
|
|
279
|
+
<li tab="first">First</li>
|
|
280
|
+
<li tab="second">Second</li>
|
|
281
|
+
${withThird ? html`<li tab="third">Third</li>` : null}
|
|
282
|
+
</zn-navbar>
|
|
283
|
+
<div id="first">First panel</div>
|
|
284
|
+
<div id="second">Second panel</div>
|
|
285
|
+
${withThird ? html`<div id="third">Third panel</div>` : null}
|
|
286
|
+
</zn-tabs>
|
|
287
|
+
`);
|
|
288
|
+
|
|
289
|
+
const el = await render(false);
|
|
290
|
+
await aTimeout(40);
|
|
291
|
+
el.querySelector('zn-navbar')!.querySelectorAll<HTMLElement>('li')[1].click();
|
|
292
|
+
await aTimeout(40);
|
|
293
|
+
el.remove();
|
|
294
|
+
|
|
295
|
+
returnWithHistory();
|
|
296
|
+
const same = await render(false);
|
|
297
|
+
await aTimeout(40);
|
|
298
|
+
expect(same.getAttribute('active')).to.equal('second');
|
|
299
|
+
same.remove();
|
|
300
|
+
|
|
301
|
+
returnWithHistory();
|
|
302
|
+
const added = await render(true);
|
|
303
|
+
await aTimeout(40);
|
|
304
|
+
expect(added.getAttribute('active')).to.equal('third');
|
|
305
|
+
expect(added.querySelector('#third')!.hasAttribute('selected')).to.equal(true);
|
|
306
|
+
});
|
|
307
|
+
|
|
308
|
+
it('starts from the default tab when the restored tab no longer exists', async () => {
|
|
309
|
+
const el = await renderTabs();
|
|
310
|
+
await aTimeout(40);
|
|
311
|
+
el.querySelector('zn-navbar')!.querySelectorAll<HTMLElement>('li')[1].click();
|
|
312
|
+
await aTimeout(40);
|
|
313
|
+
el.remove();
|
|
314
|
+
|
|
315
|
+
returnWithHistory();
|
|
316
|
+
const restored = await fixture<ZnTabs>(html`
|
|
317
|
+
<zn-tabs store-key=${storeKey} active="first">
|
|
318
|
+
<zn-navbar slot="top">
|
|
319
|
+
<li tab="first">First</li>
|
|
320
|
+
</zn-navbar>
|
|
321
|
+
<div id="first">First panel</div>
|
|
322
|
+
</zn-tabs>
|
|
323
|
+
`);
|
|
324
|
+
await aTimeout(40);
|
|
325
|
+
|
|
326
|
+
expect(restored.getAttribute('active')).to.equal('first');
|
|
327
|
+
expect(restored.querySelector('#first')!.hasAttribute('selected')).to.equal(true);
|
|
328
|
+
});
|
|
329
|
+
|
|
161
330
|
it('starts from the default tab when navigating to the location', async () => {
|
|
162
331
|
const first = await renderTabs();
|
|
163
332
|
await aTimeout(40);
|
|
@@ -8,6 +8,7 @@ import {ifDefined} from "lit/directives/if-defined.js";
|
|
|
8
8
|
import {live} from "lit/directives/live.js";
|
|
9
9
|
import {property, query, state} from 'lit/decorators.js';
|
|
10
10
|
import {ResizeController} from '@lit-labs/observers/resize-controller.js';
|
|
11
|
+
import {revealBottom} from '../../internal/scroll';
|
|
11
12
|
import {watch} from '../../internal/watch';
|
|
12
13
|
import ZincElement, {type ZincFormControl} from '../../internal/zinc-element';
|
|
13
14
|
import ZnSlashItem from "../slash-item";
|
|
@@ -64,10 +65,16 @@ export default class ZnTextarea extends ZincElement implements ZincFormControl {
|
|
|
64
65
|
private readonly hasSlotController = new HasSlotController(this, 'help-text', 'label');
|
|
65
66
|
private readonly resizeObserver = new ResizeController(this, {
|
|
66
67
|
target: null,
|
|
67
|
-
callback: () =>
|
|
68
|
+
callback: () => {
|
|
69
|
+
this.setTextareaHeight();
|
|
70
|
+
// The native resize grip doesn't scroll, so a textarea at the bottom of a scroller would grow out of sight
|
|
71
|
+
if (this.pointerHeld) revealBottom(this.input);
|
|
72
|
+
},
|
|
68
73
|
});
|
|
74
|
+
private pointerHeld = false;
|
|
69
75
|
/** Ensures we only attempt to derive the initial value from light DOM content once */
|
|
70
76
|
private _didInitFromContent = false;
|
|
77
|
+
private escapeSwallowed = false;
|
|
71
78
|
|
|
72
79
|
private readonly slashController = new SlashMenuController(this, {
|
|
73
80
|
menu: () => this.mountSlashMenu(),
|
|
@@ -139,6 +146,9 @@ export default class ZnTextarea extends ZincElement implements ZincFormControl {
|
|
|
139
146
|
/** Makes the textarea a required field. */
|
|
140
147
|
@property({type: Boolean, reflect: true}) required = false;
|
|
141
148
|
|
|
149
|
+
/** Short text shown next to the label, styled like the help text, e.g. `optional`. */
|
|
150
|
+
@property({attribute: 'label-note'}) labelNote = '';
|
|
151
|
+
|
|
142
152
|
/** The minimum length of input that will be considered valid. */
|
|
143
153
|
@property({type: Number}) minlength: number;
|
|
144
154
|
|
|
@@ -377,12 +387,22 @@ export default class ZnTextarea extends ZincElement implements ZincFormControl {
|
|
|
377
387
|
// The slash menu claims its own keys before this handler runs; Escape closes it, not the field
|
|
378
388
|
if (this.slashController.open) return;
|
|
379
389
|
|
|
390
|
+
// The first Escape stays in the field so it doesn't also dismiss a containing popup; a repeat bubbles
|
|
380
391
|
if (event.key === 'Escape') {
|
|
381
|
-
this.
|
|
382
|
-
|
|
392
|
+
if (!this.escapeSwallowed) {
|
|
393
|
+
this.escapeSwallowed = true;
|
|
394
|
+
event.stopPropagation();
|
|
395
|
+
}
|
|
396
|
+
return;
|
|
383
397
|
}
|
|
398
|
+
this.escapeSwallowed = false;
|
|
384
399
|
}
|
|
385
400
|
|
|
401
|
+
private handlePointerDown = () => {
|
|
402
|
+
this.pointerHeld = true;
|
|
403
|
+
window.addEventListener('pointerup', () => this.pointerHeld = false, {once: true});
|
|
404
|
+
};
|
|
405
|
+
|
|
386
406
|
private setTextareaHeight() {
|
|
387
407
|
if (this.resize === 'auto') {
|
|
388
408
|
this.input.style.height = 'auto';
|
|
@@ -536,6 +556,7 @@ export default class ZnTextarea extends ZincElement implements ZincFormControl {
|
|
|
536
556
|
<zn-icon library="fa" src="info"></zn-icon>
|
|
537
557
|
</zn-tooltip>`
|
|
538
558
|
: ''}
|
|
559
|
+
${this.labelNote ? html`<span class="form-control__label-note">${this.labelNote}</span>` : ''}
|
|
539
560
|
</label>
|
|
540
561
|
${hasContextNote
|
|
541
562
|
? html`<span class="form-control__label-context-note"><slot
|
|
@@ -585,6 +606,7 @@ export default class ZnTextarea extends ZincElement implements ZincFormControl {
|
|
|
585
606
|
aria-describedby="help-text"
|
|
586
607
|
@change=${this.handleChange}
|
|
587
608
|
@input=${this.handleInput}
|
|
609
|
+
@pointerdown=${this.handlePointerDown}
|
|
588
610
|
@invalid=${this.handleInvalid}
|
|
589
611
|
@keydown=${this.handleKeyDown}
|
|
590
612
|
@focus=${this.handleFocus}
|
|
@@ -31,6 +31,7 @@
|
|
|
31
31
|
.textarea--standard {
|
|
32
32
|
background-color: var(--zn-input-background-color);
|
|
33
33
|
border: solid var(--zn-input-border-width) var(--zn-input-border-color);
|
|
34
|
+
box-shadow: var(--zn-input-shadow, none);
|
|
34
35
|
}
|
|
35
36
|
|
|
36
37
|
.textarea--standard:hover:not(.textarea--disabled) {
|
|
@@ -53,6 +54,15 @@
|
|
|
53
54
|
color: var(--zn-input-color-focus);
|
|
54
55
|
}
|
|
55
56
|
|
|
57
|
+
/* Invalid, once the user has interacted */
|
|
58
|
+
:host([data-user-invalid]) .textarea--standard:not(.textarea--disabled) {
|
|
59
|
+
border-color: var(--zn-input-border-color-invalid);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
:host([data-user-invalid]) .textarea--standard.textarea--focused:not(.textarea--disabled) {
|
|
63
|
+
box-shadow: 0 0 0 var(--zn-focus-ring-width) var(--zn-input-focus-ring-color-invalid);
|
|
64
|
+
}
|
|
65
|
+
|
|
56
66
|
.textarea--standard.textarea--disabled {
|
|
57
67
|
background-color: var(--zn-input-background-color-disabled);
|
|
58
68
|
border-color: var(--zn-input-border-color-disabled);
|
|
@@ -54,7 +54,7 @@ describe('<zn-textarea>', () => {
|
|
|
54
54
|
});
|
|
55
55
|
|
|
56
56
|
describe('Escape key', () => {
|
|
57
|
-
it('
|
|
57
|
+
it('keeps focus and swallows only the first Escape', async () => {
|
|
58
58
|
const wrapper = await fixture<HTMLDivElement>(html`
|
|
59
59
|
<div>
|
|
60
60
|
<zn-textarea></zn-textarea>
|
|
@@ -72,16 +72,20 @@ describe('<zn-textarea>', () => {
|
|
|
72
72
|
await el.updateComplete;
|
|
73
73
|
expect(el.shadowRoot!.activeElement).to.equal(el.input);
|
|
74
74
|
|
|
75
|
-
el.input.dispatchEvent(new KeyboardEvent('keydown', {
|
|
75
|
+
const pressEscape = () => el.input.dispatchEvent(new KeyboardEvent('keydown', {
|
|
76
76
|
key: 'Escape',
|
|
77
77
|
bubbles: true,
|
|
78
78
|
composed: true,
|
|
79
79
|
cancelable: true
|
|
80
80
|
}));
|
|
81
|
-
await el.updateComplete;
|
|
82
81
|
|
|
83
|
-
|
|
82
|
+
pressEscape();
|
|
83
|
+
await el.updateComplete;
|
|
84
|
+
expect(el.shadowRoot!.activeElement, 'inner textarea should keep focus').to.equal(el.input);
|
|
84
85
|
expect(wrapperEscapes, 'wrapper should not see Escape on press 1').to.equal(0);
|
|
86
|
+
|
|
87
|
+
pressEscape();
|
|
88
|
+
expect(wrapperEscapes, 'wrapper should see Escape on press 2').to.equal(1);
|
|
85
89
|
});
|
|
86
90
|
});
|
|
87
91
|
|
|
@@ -70,12 +70,6 @@
|
|
|
70
70
|
// rather than the navbar's default body colour (flow-builder pattern).
|
|
71
71
|
--zn-active-nav-background: var(--zn-panel);
|
|
72
72
|
|
|
73
|
-
// Themes with a glass page tab bar (e.g. Aura) frost inactive tabs on every
|
|
74
|
-
// navbar under a zn-page — over the editor's opaque panel the translucent
|
|
75
|
-
// white just reads as white. Pin the standard tab tint instead.
|
|
76
|
-
--navbar-page-inactive-tab-background: rgb(var(--zn-color-tab));
|
|
77
|
-
--navbar-page-inactive-tab-filter: none;
|
|
78
|
-
|
|
79
73
|
position: relative;
|
|
80
74
|
display: flex;
|
|
81
75
|
flex-direction: column;
|
|
@@ -5,6 +5,7 @@ import {html, literal} from "lit/static-html.js";
|
|
|
5
5
|
import {ifDefined} from "lit/directives/if-defined.js";
|
|
6
6
|
import {property} from 'lit/decorators.js';
|
|
7
7
|
import ZincElement from '../../internal/zinc-element';
|
|
8
|
+
import ZnIcon from '../icon';
|
|
8
9
|
|
|
9
10
|
import styles from './tile.scss';
|
|
10
11
|
|
|
@@ -14,7 +15,7 @@ import styles from './tile.scss';
|
|
|
14
15
|
* @status experimental
|
|
15
16
|
* @since 1.0
|
|
16
17
|
*
|
|
17
|
-
* @dependency zn-
|
|
18
|
+
* @dependency zn-icon
|
|
18
19
|
*
|
|
19
20
|
* @event zn-event-name - Emitted as an example.
|
|
20
21
|
*
|
|
@@ -22,11 +23,17 @@ import styles from './tile.scss';
|
|
|
22
23
|
* @slot example - An example slot.
|
|
23
24
|
*
|
|
24
25
|
* @csspart base - The component's base wrapper.
|
|
26
|
+
* @csspart icon - The tinted square around the icon.
|
|
25
27
|
*
|
|
26
28
|
* @cssproperty --example - An example CSS custom property.
|
|
29
|
+
* @cssproperty --zn-tile-hover-caption-color - The caption color while a linked tile is hovered.
|
|
30
|
+
* @cssproperty --zn-tile-hover-caption-decoration - The caption text decoration while a linked tile is hovered.
|
|
27
31
|
*/
|
|
28
32
|
export default class ZnTile extends ZincElement {
|
|
29
33
|
static styles: CSSResultGroup = unsafeCSS(styles);
|
|
34
|
+
static dependencies = {
|
|
35
|
+
'zn-icon': ZnIcon,
|
|
36
|
+
};
|
|
30
37
|
|
|
31
38
|
private readonly hasSlotController = new HasSlotController(this, '[default]', 'caption', 'description', 'properties', 'actions', 'image');
|
|
32
39
|
|
|
@@ -34,6 +41,12 @@ export default class ZnTile extends ZincElement {
|
|
|
34
41
|
|
|
35
42
|
@property({attribute: 'description'}) description: string;
|
|
36
43
|
|
|
44
|
+
/** Shows the icon in a tinted square before the caption. */
|
|
45
|
+
@property() icon: string;
|
|
46
|
+
|
|
47
|
+
/** The tint of the icon square: `success`, `warning`, `danger`, `info`, `ai` or `neutral`. */
|
|
48
|
+
@property({attribute: 'icon-color'}) iconColor: 'success' | 'warning' | 'danger' | 'info' | 'ai' | 'neutral' = 'neutral';
|
|
49
|
+
|
|
37
50
|
@property({attribute: 'href'}) href: string;
|
|
38
51
|
|
|
39
52
|
@property({attribute: 'data-target'}) dataTarget: string;
|
|
@@ -63,6 +76,13 @@ export default class ZnTile extends ZincElement {
|
|
|
63
76
|
return this.href || this.dataUri;
|
|
64
77
|
}
|
|
65
78
|
|
|
79
|
+
// An <a> without href, as data-uri renders, is neither focusable nor activated by Enter on its own
|
|
80
|
+
private _handleLinkKeyDown(e: KeyboardEvent) {
|
|
81
|
+
if (this.href || !this.dataUri || e.key !== 'Enter' || e.target !== e.currentTarget) return;
|
|
82
|
+
e.preventDefault();
|
|
83
|
+
(e.currentTarget as HTMLElement).click();
|
|
84
|
+
}
|
|
85
|
+
|
|
66
86
|
private _handleActionsClick(e: MouseEvent) {
|
|
67
87
|
if (!this._isLink()) return;
|
|
68
88
|
|
|
@@ -90,6 +110,7 @@ export default class ZnTile extends ZincElement {
|
|
|
90
110
|
const hasProperties = this.hasSlotController.test('properties');
|
|
91
111
|
const hasActions = this.hasSlotController.test('actions');
|
|
92
112
|
const hasImage = this.hasSlotController.test('image');
|
|
113
|
+
const hasIcon = !!this.icon;
|
|
93
114
|
|
|
94
115
|
return html`
|
|
95
116
|
<div
|
|
@@ -106,19 +127,28 @@ export default class ZnTile extends ZincElement {
|
|
|
106
127
|
'tile--has-properties': hasProperties,
|
|
107
128
|
'tile--has-actions': hasActions,
|
|
108
129
|
'tile--has-image': hasImage,
|
|
130
|
+
'tile--has-icon': hasIcon,
|
|
109
131
|
})}">
|
|
110
132
|
<${tag}
|
|
111
133
|
href="${ifDefined(this.href)}"
|
|
112
134
|
data-uri="${ifDefined(this.dataUri)}"
|
|
113
135
|
gaid="${ifDefined(this.gaid)}"
|
|
114
136
|
data-target="${ifDefined(this.dataTarget)}"
|
|
137
|
+
draggable="${ifDefined(isLink ? 'false' : undefined)}"
|
|
138
|
+
role="${ifDefined(this.dataUri && !this.href ? 'link' : undefined)}"
|
|
139
|
+
tabindex="${ifDefined(this.dataUri && !this.href ? '0' : undefined)}"
|
|
140
|
+
@keydown="${this._handleLinkKeyDown}"
|
|
115
141
|
class="tile__link">
|
|
116
|
-
${!hasCaption && !hasDescription && !hasProperties && !hasActions ? html`
|
|
142
|
+
${!hasCaption && !hasDescription && !hasProperties && !hasActions && !hasIcon ? html`
|
|
117
143
|
<slot></slot>
|
|
118
144
|
` : html`
|
|
119
145
|
<div class="tile__left">
|
|
120
146
|
${hasImage ? html`
|
|
121
147
|
<slot name="image" part="image" class="tile__image"></slot>` : html``}
|
|
148
|
+
${hasIcon ? html`
|
|
149
|
+
<span part="icon" class="tile__icon tile__icon--${this.iconColor}">
|
|
150
|
+
<zn-icon src="${this.icon}" size="18"></zn-icon>
|
|
151
|
+
</span>` : html``}
|
|
122
152
|
<div class="tile__content">
|
|
123
153
|
<p part="caption" class="tile__caption">
|
|
124
154
|
<slot name="caption">${this.caption}</slot>
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
display: flex;
|
|
10
10
|
align-items: center;
|
|
11
11
|
justify-content: space-between;
|
|
12
|
-
min-height: 48px;
|
|
12
|
+
min-height: var(--zn-tile-min-height, 48px);
|
|
13
13
|
column-gap: var(--zn-spacing-large);
|
|
14
14
|
|
|
15
15
|
font-size: var(--zn-text-table-content-font-size);
|
|
@@ -18,15 +18,16 @@
|
|
|
18
18
|
color: var(--zn-text-table-content-color);
|
|
19
19
|
|
|
20
20
|
&--has-image,
|
|
21
|
+
&--has-icon,
|
|
21
22
|
&--has-caption,
|
|
22
23
|
&--has-description,
|
|
23
24
|
&--has-properties,
|
|
24
25
|
&--has-actions {
|
|
25
|
-
padding-inline: var(--zn-base-gap);
|
|
26
|
+
padding-inline: var(--zn-tile-padding-inline, var(--zn-base-gap));
|
|
26
27
|
}
|
|
27
28
|
|
|
28
29
|
&--has-description#{&}--has-caption {
|
|
29
|
-
padding-block: var(--zn-base-gap);
|
|
30
|
+
padding-block: var(--zn-tile-padding-block, var(--zn-base-gap));
|
|
30
31
|
}
|
|
31
32
|
|
|
32
33
|
&--has-image {
|
|
@@ -37,7 +38,12 @@
|
|
|
37
38
|
cursor: pointer;
|
|
38
39
|
|
|
39
40
|
&:hover {
|
|
40
|
-
background-color: var(--zn-color-neutral-100);
|
|
41
|
+
background-color: var(--zn-tile-hover-background, var(--zn-color-neutral-100));
|
|
42
|
+
|
|
43
|
+
.tile__caption {
|
|
44
|
+
--tile-caption-hover-color: var(--zn-tile-hover-caption-color);
|
|
45
|
+
text-decoration: var(--zn-tile-hover-caption-decoration, none);
|
|
46
|
+
}
|
|
41
47
|
}
|
|
42
48
|
}
|
|
43
49
|
|
|
@@ -73,6 +79,11 @@ a {
|
|
|
73
79
|
flex: 1;
|
|
74
80
|
column-gap: var(--zn-spacing-small);
|
|
75
81
|
min-width: 0;
|
|
82
|
+
|
|
83
|
+
&:focus-visible {
|
|
84
|
+
outline: var(--zn-focus-ring);
|
|
85
|
+
border-radius: var(--zn-border-radius-small);
|
|
86
|
+
}
|
|
76
87
|
}
|
|
77
88
|
|
|
78
89
|
.tile__left {
|
|
@@ -88,6 +99,25 @@ a {
|
|
|
88
99
|
flex-shrink: 0;
|
|
89
100
|
}
|
|
90
101
|
|
|
102
|
+
.tile__icon {
|
|
103
|
+
display: flex;
|
|
104
|
+
align-items: center;
|
|
105
|
+
justify-content: center;
|
|
106
|
+
flex-shrink: 0;
|
|
107
|
+
width: 36px;
|
|
108
|
+
height: 36px;
|
|
109
|
+
border-radius: var(--zn-border-radius-medium, var(--zn-border-radius));
|
|
110
|
+
color: var(--zn-color-neutral-fg);
|
|
111
|
+
background: var(--zn-color-neutral-bg);
|
|
112
|
+
|
|
113
|
+
@each $tone in success, warning, danger, info, ai {
|
|
114
|
+
&--#{$tone} {
|
|
115
|
+
color: var(--zn-color-#{$tone}-fg);
|
|
116
|
+
background: var(--zn-color-#{$tone}-bg);
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
|
|
91
121
|
.tile__content {
|
|
92
122
|
display: flex;
|
|
93
123
|
flex-direction: column;
|
|
@@ -104,7 +134,8 @@ a {
|
|
|
104
134
|
.tile__caption {
|
|
105
135
|
margin: 0;
|
|
106
136
|
font-weight: 600;
|
|
107
|
-
|
|
137
|
+
// Unset outside a linked tile's hover, so each caption falls back to its resting colour
|
|
138
|
+
color: var(--tile-caption-hover-color, rgb(var(--zn-text-heading)));
|
|
108
139
|
white-space: nowrap;
|
|
109
140
|
overflow: hidden;
|
|
110
141
|
text-overflow: ellipsis;
|
|
@@ -112,7 +143,7 @@ a {
|
|
|
112
143
|
|
|
113
144
|
.tile--plain .tile__caption {
|
|
114
145
|
font-weight: var(--zn-text-table-content-font-weight);
|
|
115
|
-
color: var(--zn-text-table-content-color);
|
|
146
|
+
color: var(--tile-caption-hover-color, var(--zn-text-table-content-color));
|
|
116
147
|
}
|
|
117
148
|
|
|
118
149
|
.tile__description {
|
|
@@ -134,6 +165,8 @@ slot.tile__description {
|
|
|
134
165
|
}
|
|
135
166
|
|
|
136
167
|
.tile__right {
|
|
168
|
+
// Keeps actions clickable when a host such as zn-priority-list disables pointer events on the tile
|
|
169
|
+
pointer-events: auto;
|
|
137
170
|
display: flex;
|
|
138
171
|
align-items: center;
|
|
139
172
|
justify-content: flex-end;
|
|
@@ -179,7 +212,7 @@ slot.tile__description {
|
|
|
179
212
|
grid-template-columns: subgrid;
|
|
180
213
|
align-items: center;
|
|
181
214
|
justify-items: end;
|
|
182
|
-
min-height: 48px;
|
|
215
|
+
min-height: var(--zn-tile-min-height, 48px);
|
|
183
216
|
}
|
|
184
217
|
|
|
185
218
|
:host([grouped]) .tile__link,
|
|
@@ -20,6 +20,16 @@ describe('<zn-tile>', () => {
|
|
|
20
20
|
expect(el.shadowRoot!.querySelector('slot[name="image"]')).to.exist;
|
|
21
21
|
});
|
|
22
22
|
|
|
23
|
+
it('draws the icon in a tinted square', async () => {
|
|
24
|
+
const el = await fixture<ZnTile>(html`
|
|
25
|
+
<zn-tile caption="Second chance" icon="tag@lu" icon-color="success"
|
|
26
|
+
style="--zn-color-success-bg: rgb(1, 2, 3)"></zn-tile>`);
|
|
27
|
+
|
|
28
|
+
const square = el.shadowRoot!.querySelector<HTMLElement>('.tile__icon')!;
|
|
29
|
+
expect(square.querySelector('zn-icon')).to.exist;
|
|
30
|
+
expect(getComputedStyle(square).backgroundColor).to.equal('rgb(1, 2, 3)');
|
|
31
|
+
});
|
|
32
|
+
|
|
23
33
|
it('should render its content as a link when href is set', async () => {
|
|
24
34
|
const el = await fixture<ZnTile>(html`
|
|
25
35
|
<zn-tile href="/users/leslie" caption="Leslie Alexander"></zn-tile>`);
|