@kubex/zinc 1.1.185 → 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 +9998 -2345
- package/dist/vscode.html-custom-data.json +1022 -67
- package/dist/web-types.json +2129 -177
- package/dist/zn.d.ts +2293 -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 +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/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
|
@@ -40,6 +40,27 @@ describe('<zn-page>', () => {
|
|
|
40
40
|
expect(navItems[3].getAttribute('tab-uri')).to.equal('/tab-three');
|
|
41
41
|
});
|
|
42
42
|
|
|
43
|
+
it('shows the footer only when the footer slot has content', async () => {
|
|
44
|
+
const el = await fixture<ZnPage>(html`
|
|
45
|
+
<zn-page caption="Page Title">
|
|
46
|
+
<zn-tab caption="Overview">Content</zn-tab>
|
|
47
|
+
</zn-page>
|
|
48
|
+
`);
|
|
49
|
+
await aTimeout(20);
|
|
50
|
+
|
|
51
|
+
const footer = el.shadowRoot!.querySelector<HTMLElement>('[part="footer"]')!;
|
|
52
|
+
expect(footer.hidden).to.equal(true);
|
|
53
|
+
|
|
54
|
+
const actions = document.createElement('zn-form-actions');
|
|
55
|
+
actions.slot = 'footer';
|
|
56
|
+
el.appendChild(actions);
|
|
57
|
+
await aTimeout(20);
|
|
58
|
+
|
|
59
|
+
const footerSlot = el.shadowRoot!.querySelector<HTMLSlotElement>('slot[name="footer"]')!;
|
|
60
|
+
expect(footer.hidden).to.equal(false);
|
|
61
|
+
expect(footerSlot.assignedElements()[0]).to.equal(actions);
|
|
62
|
+
});
|
|
63
|
+
|
|
43
64
|
it('pushes nested expanding actions into the generated navbar', async () => {
|
|
44
65
|
const el = await fixture<ZnPage>(html`
|
|
45
66
|
<zn-page caption="Page Title">
|
|
@@ -152,6 +173,27 @@ describe('<zn-page>', () => {
|
|
|
152
173
|
expect(freshPage.getAttribute('active')).to.equal('');
|
|
153
174
|
});
|
|
154
175
|
|
|
176
|
+
it('loads the first uri tab when the stored tab belongs to a previous entity', async () => {
|
|
177
|
+
const renderUriPage = (entity: string) => fixture<ZnPage>(html`
|
|
178
|
+
<zn-page>
|
|
179
|
+
<zn-tab caption="Accounts" uri="/${entity}/accounts"></zn-tab>
|
|
180
|
+
<zn-tab caption="Invoices" uri="/${entity}/invoices"></zn-tab>
|
|
181
|
+
</zn-page>
|
|
182
|
+
`);
|
|
183
|
+
|
|
184
|
+
const first = await renderUriPage('a');
|
|
185
|
+
await aTimeout(40);
|
|
186
|
+
first.shadowRoot!.querySelector('zn-navbar')!.querySelector<HTMLElement>('li[tab-uri="/a/accounts"]')!.click();
|
|
187
|
+
await aTimeout(40);
|
|
188
|
+
first.remove();
|
|
189
|
+
|
|
190
|
+
window.dispatchEvent(new PopStateEvent('popstate'));
|
|
191
|
+
const second = await renderUriPage('b');
|
|
192
|
+
await aTimeout(60);
|
|
193
|
+
const panel = second.shadowRoot!.querySelector('#content > div[selected]');
|
|
194
|
+
expect(panel?.getAttribute('data-self-uri')).to.equal('/b/accounts');
|
|
195
|
+
});
|
|
196
|
+
|
|
155
197
|
it('restores a tab cycled without the navigation', async () => {
|
|
156
198
|
const page = await renderPage();
|
|
157
199
|
await aTimeout(40);
|
|
@@ -378,6 +420,135 @@ describe('<zn-page>', () => {
|
|
|
378
420
|
expect(activeItem?.getAttribute('tab')).to.equal('details');
|
|
379
421
|
});
|
|
380
422
|
|
|
423
|
+
it('opens a tab from a tab attribute inside a uri tab, which loads into the page\'s shadow root', async () => {
|
|
424
|
+
const el = await fixture<ZnPage>(html`
|
|
425
|
+
<zn-page caption="Uri Tab Link">
|
|
426
|
+
<zn-tab caption="Details" id="details">Details Content</zn-tab>
|
|
427
|
+
<zn-tab caption="Publish" uri="/publish-tab"></zn-tab>
|
|
428
|
+
</zn-page>
|
|
429
|
+
`);
|
|
430
|
+
await aTimeout(40);
|
|
431
|
+
|
|
432
|
+
const navbar = el.shadowRoot!.querySelector('zn-navbar')!;
|
|
433
|
+
navbar.shadowRoot!.querySelector<HTMLElement>('li[tab-uri="/publish-tab"]')!.click();
|
|
434
|
+
await aTimeout(100);
|
|
435
|
+
|
|
436
|
+
const panel = el.shadowRoot!.querySelector<HTMLElement>('#content > div[data-self-uri="/publish-tab"]')!;
|
|
437
|
+
const link = document.createElement('span');
|
|
438
|
+
link.setAttribute('tab', 'details');
|
|
439
|
+
link.textContent = 'Edit in Details';
|
|
440
|
+
panel.replaceChildren(link);
|
|
441
|
+
expect(el.getAttribute('active')).to.not.equal('details');
|
|
442
|
+
|
|
443
|
+
link.click();
|
|
444
|
+
await aTimeout(40);
|
|
445
|
+
expect(el.getAttribute('active')).to.equal('details');
|
|
446
|
+
});
|
|
447
|
+
|
|
448
|
+
it('shows tabs inside a tab as a pill tab set without a header', async () => {
|
|
449
|
+
const el = await fixture<ZnPage>(html`
|
|
450
|
+
<zn-page caption="Outer Page">
|
|
451
|
+
<zn-tab caption="Overview">
|
|
452
|
+
<zn-tab caption="Invoices">Invoices Content</zn-tab>
|
|
453
|
+
<zn-tab caption="Payments" selected>Payments Content</zn-tab>
|
|
454
|
+
</zn-tab>
|
|
455
|
+
<zn-tab caption="Other">Other Content</zn-tab>
|
|
456
|
+
</zn-page>
|
|
457
|
+
`);
|
|
458
|
+
await aTimeout(50);
|
|
459
|
+
|
|
460
|
+
const group = el.querySelector<ZnPage>('zn-tab > zn-page')!;
|
|
461
|
+
expect(group.getAttribute('navigation-style')).to.equal('pills');
|
|
462
|
+
expect(group.querySelectorAll(':scope > zn-tab').length).to.equal(2);
|
|
463
|
+
expect(el.shadowRoot!.querySelector('zn-navbar')!.hasAttribute('pill')).to.be.false;
|
|
464
|
+
|
|
465
|
+
const navbar = group.shadowRoot!.querySelector('zn-navbar')!;
|
|
466
|
+
expect(navbar.hasAttribute('pill')).to.be.true;
|
|
467
|
+
expect(Array.from(navbar.querySelectorAll('li')).map(li => li.textContent?.trim())).to.deep.equal(['Invoices', 'Payments']);
|
|
468
|
+
expect(getComputedStyle(group.shadowRoot!.querySelector('.header')!).display).to.equal('none');
|
|
469
|
+
expect(group.getAttribute('active')).to.equal('payments');
|
|
470
|
+
|
|
471
|
+
// An app sidebar restyles the group, which must still sit inside the parent's padding without adding its own
|
|
472
|
+
group.setAttribute('navigation-style', 'sidebar');
|
|
473
|
+
await aTimeout(20);
|
|
474
|
+
expect(getComputedStyle(group.shadowRoot!.querySelector('#content')!).paddingLeft).to.equal('0px');
|
|
475
|
+
});
|
|
476
|
+
|
|
477
|
+
it('keeps a nested page\'s tab bar and header', async () => {
|
|
478
|
+
const el = await fixture<ZnPage>(html`
|
|
479
|
+
<zn-page caption="Outer Page">
|
|
480
|
+
<zn-tab caption="Overview">
|
|
481
|
+
<zn-page caption="Inner Page" nested>
|
|
482
|
+
<zn-tab caption="Overview">Inner Overview</zn-tab>
|
|
483
|
+
<zn-tab caption="Details">Inner Details</zn-tab>
|
|
484
|
+
</zn-page>
|
|
485
|
+
</zn-tab>
|
|
486
|
+
<zn-tab caption="Other">Other Content</zn-tab>
|
|
487
|
+
</zn-page>
|
|
488
|
+
`);
|
|
489
|
+
await aTimeout(20);
|
|
490
|
+
|
|
491
|
+
const inner = el.querySelector<ZnPage>('zn-page')!;
|
|
492
|
+
expect(inner.shadowRoot!.querySelector('zn-navbar')!.hasAttribute('pill')).to.be.false;
|
|
493
|
+
expect(getComputedStyle(inner.shadowRoot!.querySelector('.header')!).display).to.not.equal('none');
|
|
494
|
+
});
|
|
495
|
+
|
|
496
|
+
it('gives a nested page\'s header the card title style and a single inset', async () => {
|
|
497
|
+
const el = await fixture<ZnPage>(html`
|
|
498
|
+
<zn-page caption="Outer Page">
|
|
499
|
+
<zn-tab caption="Overview">
|
|
500
|
+
<zn-page caption="Inner Page" summary="Inner summary" nested>
|
|
501
|
+
<zn-tab caption="Overview">Inner Overview</zn-tab>
|
|
502
|
+
<zn-tab caption="Details">Inner Details</zn-tab>
|
|
503
|
+
</zn-page>
|
|
504
|
+
</zn-tab>
|
|
505
|
+
</zn-page>
|
|
506
|
+
`);
|
|
507
|
+
await aTimeout(20);
|
|
508
|
+
|
|
509
|
+
const inner = el.querySelector<ZnPage>('zn-page')!;
|
|
510
|
+
inner.style.setProperty('--zn-text-h1-font-size', '14px');
|
|
511
|
+
inner.style.setProperty('--zn-base-gap', '16px');
|
|
512
|
+
const root = inner.shadowRoot!;
|
|
513
|
+
const header = getComputedStyle(root.querySelector('.header')!);
|
|
514
|
+
expect(header.paddingLeft).to.equal('16px');
|
|
515
|
+
expect(header.paddingRight).to.equal('16px');
|
|
516
|
+
expect(getComputedStyle(root.querySelector('.header .content')!).maxWidth).to.equal('100%');
|
|
517
|
+
expect(getComputedStyle(root.querySelector('.header__caption')!).fontSize).to.equal('14px');
|
|
518
|
+
expect(getComputedStyle(root.querySelector('.header__left')!).rowGap).to.equal('0px');
|
|
519
|
+
});
|
|
520
|
+
|
|
521
|
+
it('hides an empty header', async () => {
|
|
522
|
+
const el = await fixture<ZnPage>(html`
|
|
523
|
+
<zn-page>
|
|
524
|
+
<zn-tab caption="Overview">Overview Content</zn-tab>
|
|
525
|
+
<zn-tab caption="Details">Details Content</zn-tab>
|
|
526
|
+
</zn-page>
|
|
527
|
+
`);
|
|
528
|
+
await aTimeout(20);
|
|
529
|
+
|
|
530
|
+
expect(getComputedStyle(el.shadowRoot!.querySelector('.header')!).display).to.equal('none');
|
|
531
|
+
});
|
|
532
|
+
|
|
533
|
+
it('hides its navbar in the sidebar style unless it has bottom content', async () => {
|
|
534
|
+
const el = await fixture<ZnPage>(html`
|
|
535
|
+
<zn-page caption="Page Title" navigation-style="sidebar">
|
|
536
|
+
<zn-tab caption="Overview">Overview Content</zn-tab>
|
|
537
|
+
<zn-tab caption="Details">Details Content</zn-tab>
|
|
538
|
+
</zn-page>
|
|
539
|
+
`);
|
|
540
|
+
await aTimeout(20);
|
|
541
|
+
|
|
542
|
+
const navbar = el.shadowRoot!.querySelector('zn-navbar')!;
|
|
543
|
+
expect(getComputedStyle(navbar).display).to.equal('none');
|
|
544
|
+
|
|
545
|
+
const chip = document.createElement('zn-chip');
|
|
546
|
+
chip.slot = 'bottom';
|
|
547
|
+
el.append(chip);
|
|
548
|
+
await aTimeout(20);
|
|
549
|
+
expect(getComputedStyle(navbar).display).to.not.equal('none');
|
|
550
|
+
});
|
|
551
|
+
|
|
381
552
|
it('leaves content tab links inside a nested page to that page', async () => {
|
|
382
553
|
const outerPage = await fixture<ZnPage>(html`
|
|
383
554
|
<zn-page caption="Nested Content Tab Link">
|
|
@@ -492,9 +663,9 @@ describe('<zn-page>', () => {
|
|
|
492
663
|
const el = await fixture<ZnPage>(html`
|
|
493
664
|
<zn-page caption="Page Title">
|
|
494
665
|
<zn-tab caption="Later">Later Content</zn-tab>
|
|
495
|
-
<zn-tab caption="Second" priority="
|
|
666
|
+
<zn-tab caption="Second" priority="10">Second Content</zn-tab>
|
|
496
667
|
<zn-tab caption="Overview">Overview Content</zn-tab>
|
|
497
|
-
<zn-tab caption="First" priority="
|
|
668
|
+
<zn-tab caption="First" priority="20">First Content</zn-tab>
|
|
498
669
|
<zn-tab caption="Dynamic" priority="15" uri="/dynamic"></zn-tab>
|
|
499
670
|
</zn-page>
|
|
500
671
|
`);
|
|
@@ -514,6 +685,22 @@ describe('<zn-page>', () => {
|
|
|
514
685
|
expect(el.querySelector<HTMLElement>('zn-tab[caption="Dynamic"]')!.getAttribute('id')).to.equal('dynamic');
|
|
515
686
|
});
|
|
516
687
|
|
|
688
|
+
it('shows a tab icon before its caption', async () => {
|
|
689
|
+
const el = await fixture<ZnPage>(html`
|
|
690
|
+
<zn-page caption="Page Title">
|
|
691
|
+
<zn-tab caption="Overview">Overview Content</zn-tab>
|
|
692
|
+
<zn-tab caption="History" icon="history" uri="/history"></zn-tab>
|
|
693
|
+
</zn-page>
|
|
694
|
+
`);
|
|
695
|
+
await aTimeout(20);
|
|
696
|
+
|
|
697
|
+
const navbar = el.shadowRoot!.querySelector('zn-navbar')!;
|
|
698
|
+
const historyItem = navbar.shadowRoot!.querySelector('li[tab-uri="/history"]')!;
|
|
699
|
+
expect(historyItem.querySelector('zn-icon')!.getAttribute('src')).to.equal('history');
|
|
700
|
+
expect(historyItem.textContent?.trim()).to.equal('History');
|
|
701
|
+
expect(navbar.shadowRoot!.querySelector('li[tab=""] zn-icon')).to.be.null;
|
|
702
|
+
});
|
|
703
|
+
|
|
517
704
|
it('preserves source order for tabs without priority', async () => {
|
|
518
705
|
const el = await fixture<ZnPage>(html`
|
|
519
706
|
<zn-page caption="Page Title">
|
|
@@ -703,7 +890,8 @@ describe('<zn-page>', () => {
|
|
|
703
890
|
await aTimeout(120);
|
|
704
891
|
|
|
705
892
|
expect(getComputedStyle(activeNavItem).backgroundColor).to.equal('rgb(1, 2, 3)');
|
|
706
|
-
expect(getComputedStyle(activeNavItem).
|
|
893
|
+
expect(getComputedStyle(activeNavItem).transitionProperty).to.equal('background-color, color');
|
|
894
|
+
expect(getComputedStyle(activeNavItem).transitionDuration).to.equal('0.1s, 0.15s');
|
|
707
895
|
});
|
|
708
896
|
|
|
709
897
|
it('opens the tab flagged with the selected attribute instead of the first', async () => {
|
|
@@ -737,4 +925,27 @@ describe('<zn-page>', () => {
|
|
|
737
925
|
expect(header.classList.contains('header--has-breadcrumb')).to.equal(false);
|
|
738
926
|
expect(el.shadowRoot!.querySelector('slot[name="breadcrumb"]')).to.equal(null);
|
|
739
927
|
});
|
|
928
|
+
|
|
929
|
+
it('keeps breadcrumbs inline in the title by default', async () => {
|
|
930
|
+
const el = await fixture<ZnPage>(html`
|
|
931
|
+
<zn-page caption="Performance"><a href="#" slot="breadcrumb">Quality Assurance</a></zn-page>`);
|
|
932
|
+
const crumbs = el.shadowRoot!.querySelector('.header__crumbs')!;
|
|
933
|
+
|
|
934
|
+
expect(getComputedStyle(crumbs).display).to.equal('contents');
|
|
935
|
+
expect(getComputedStyle(el.shadowRoot!.querySelector('.breadcrumb__current')!).display).to.equal('none');
|
|
936
|
+
});
|
|
937
|
+
|
|
938
|
+
it('lifts breadcrumbs onto their own row when the theme asks', async () => {
|
|
939
|
+
const el = await fixture<ZnPage>(html`
|
|
940
|
+
<zn-page caption="Performance"
|
|
941
|
+
style="--zn-page-breadcrumb-display: flex; --zn-page-breadcrumb-current-display: inline; --zn-page-breadcrumb-separator-icon: 'chevron-right@lu'">
|
|
942
|
+
<a href="#" slot="breadcrumb">Quality Assurance</a>
|
|
943
|
+
</zn-page>`);
|
|
944
|
+
await el.updateComplete;
|
|
945
|
+
const root = el.shadowRoot!;
|
|
946
|
+
|
|
947
|
+
expect(getComputedStyle(root.querySelector('.header__crumbs')!).display).to.equal('flex');
|
|
948
|
+
expect(root.querySelector('.breadcrumb__current')!.textContent).to.equal('Performance');
|
|
949
|
+
expect(root.querySelector('.breadcrumb__separator')!.getAttribute('src')).to.contain('chevron-right');
|
|
950
|
+
});
|
|
740
951
|
});
|
|
@@ -721,6 +721,12 @@ export default class ZnPageBuilder extends ZincElement {
|
|
|
721
721
|
const [removed, sections] = this._extract(id);
|
|
722
722
|
if (!removed) return;
|
|
723
723
|
this._pushHistory();
|
|
724
|
+
const cardIds = [...(this.shadowRoot?.querySelectorAll<HTMLElement>('zn-page-section-card') ?? [])]
|
|
725
|
+
.map(card => card.dataset.id!)
|
|
726
|
+
.filter(cardId => !removed.children?.some(c => c?.id === cardId));
|
|
727
|
+
const at = cardIds.indexOf(id);
|
|
728
|
+
const neighbour = cardIds[at + 1] ?? cardIds[at - 1];
|
|
729
|
+
const hadFocus = !!this.shadowRoot?.activeElement?.closest('zn-page-section-card');
|
|
724
730
|
// Cards are rendered unkeyed, so the focused action button survives the
|
|
725
731
|
// re-render as part of whichever section shifts into this slot.
|
|
726
732
|
this._blurActiveCard();
|
|
@@ -730,6 +736,7 @@ export default class ZnPageBuilder extends ZincElement {
|
|
|
730
736
|
}
|
|
731
737
|
// Removing the leading section hands the lead to the next one that may hold it.
|
|
732
738
|
this._commit({ sections: this._requireFirst(sections) });
|
|
739
|
+
if (hadFocus && neighbour) void this._focusCard(neighbour);
|
|
733
740
|
}
|
|
734
741
|
|
|
735
742
|
private _duplicateSection(id: string) {
|
|
@@ -1023,7 +1030,16 @@ export default class ZnPageBuilder extends ZincElement {
|
|
|
1023
1030
|
};
|
|
1024
1031
|
|
|
1025
1032
|
private _onCardKeydown(e: KeyboardEvent, id: string) {
|
|
1026
|
-
if (e.key === '
|
|
1033
|
+
if (e.altKey && (e.key === 'ArrowUp' || e.key === 'ArrowDown')) {
|
|
1034
|
+
e.preventDefault();
|
|
1035
|
+
const index = this._state.sections.findIndex(s => s.id === id);
|
|
1036
|
+
if (index === -1) return;
|
|
1037
|
+
// _moveSection inserts before the given index, so moving down one skips past the next card
|
|
1038
|
+
const target = e.key === 'ArrowUp' ? index - 1 : index + 2;
|
|
1039
|
+
if (target > this._state.sections.length) return;
|
|
1040
|
+
this._moveSection(id, target);
|
|
1041
|
+
void this._focusCard(id);
|
|
1042
|
+
} else if (e.key === 'Delete' || e.key === 'Backspace') {
|
|
1027
1043
|
e.preventDefault();
|
|
1028
1044
|
this._removeSection(id);
|
|
1029
1045
|
} else if (e.key === 'Enter' || e.key === ' ') {
|
|
@@ -1226,9 +1242,20 @@ export default class ZnPageBuilder extends ZincElement {
|
|
|
1226
1242
|
}
|
|
1227
1243
|
}}"
|
|
1228
1244
|
@drop="${(e: DragEvent) => this._onSlotDrop(e, container.id, index)}"
|
|
1245
|
+
role="button"
|
|
1246
|
+
tabindex="0"
|
|
1247
|
+
aria-label="Add section"
|
|
1248
|
+
aria-expanded="${pickerOpen}"
|
|
1229
1249
|
@click="${(e: Event) => {
|
|
1230
1250
|
e.stopPropagation();
|
|
1231
1251
|
this._slotPicker = pickerOpen ? null : { containerId: container.id, index };
|
|
1252
|
+
if (!pickerOpen) void this._focusFirstPickerItem(e.currentTarget as HTMLElement);
|
|
1253
|
+
}}"
|
|
1254
|
+
@keydown="${(e: KeyboardEvent) => {
|
|
1255
|
+
// The open picker renders inside this slot; its keys are its own
|
|
1256
|
+
if (e.target !== e.currentTarget || (e.key !== 'Enter' && e.key !== ' ')) return;
|
|
1257
|
+
e.preventDefault();
|
|
1258
|
+
(e.currentTarget as HTMLElement).click();
|
|
1232
1259
|
}}">
|
|
1233
1260
|
<zn-icon src="add" size="16"></zn-icon>
|
|
1234
1261
|
${pickerOpen
|
|
@@ -1244,10 +1271,26 @@ export default class ZnPageBuilder extends ZincElement {
|
|
|
1244
1271
|
!t.slots && (!containerType?.accepts || containerType.accepts.includes(t.type)));
|
|
1245
1272
|
}
|
|
1246
1273
|
|
|
1274
|
+
private async _focusFirstPickerItem(zone: HTMLElement) {
|
|
1275
|
+
await this.updateComplete;
|
|
1276
|
+
zone.querySelector<HTMLElement>('.picker__item')?.focus();
|
|
1277
|
+
}
|
|
1278
|
+
|
|
1247
1279
|
/** The one type-picker template both drop zones and slot cells render. */
|
|
1248
|
-
private _renderTypePicker(types: PageSectionType[], pick: (type: string) =>
|
|
1280
|
+
private _renderTypePicker(types: PageSectionType[], pick: (type: string) => PageSection | null) {
|
|
1249
1281
|
return html`
|
|
1250
|
-
<div
|
|
1282
|
+
<div
|
|
1283
|
+
class="picker"
|
|
1284
|
+
@click="${(e: Event) => e.stopPropagation()}"
|
|
1285
|
+
@keydown="${(e: KeyboardEvent) => {
|
|
1286
|
+
if (e.key !== 'Escape') return;
|
|
1287
|
+
e.preventDefault();
|
|
1288
|
+
e.stopPropagation();
|
|
1289
|
+
const zone = (e.currentTarget as HTMLElement).parentElement!;
|
|
1290
|
+
(zone.querySelector<HTMLElement>(':scope > .drop__add') ?? zone).focus();
|
|
1291
|
+
this._pickerIndex = null;
|
|
1292
|
+
this._slotPicker = null;
|
|
1293
|
+
}}">
|
|
1251
1294
|
${types.map(type => html`
|
|
1252
1295
|
<button
|
|
1253
1296
|
type="button"
|
|
@@ -1255,7 +1298,8 @@ export default class ZnPageBuilder extends ZincElement {
|
|
|
1255
1298
|
@click="${() => {
|
|
1256
1299
|
this._pickerIndex = null;
|
|
1257
1300
|
this._slotPicker = null;
|
|
1258
|
-
pick(type.type);
|
|
1301
|
+
const section = pick(type.type);
|
|
1302
|
+
if (section) void this._focusCard(section.id);
|
|
1259
1303
|
}}">
|
|
1260
1304
|
<zn-icon src="${type.icon ?? 'widgets'}" library="${ifDefined(type.iconLibrary)}" size="14"></zn-icon>
|
|
1261
1305
|
${type.label}
|
|
@@ -1278,7 +1322,9 @@ export default class ZnPageBuilder extends ZincElement {
|
|
|
1278
1322
|
title="Add section"
|
|
1279
1323
|
@click="${(e: Event) => {
|
|
1280
1324
|
e.stopPropagation();
|
|
1281
|
-
|
|
1325
|
+
const opening = this._pickerIndex !== index;
|
|
1326
|
+
this._pickerIndex = opening ? index : null;
|
|
1327
|
+
if (opening) void this._focusFirstPickerItem((e.currentTarget as HTMLElement).parentElement!);
|
|
1282
1328
|
}}">
|
|
1283
1329
|
<zn-icon src="add" size="14"></zn-icon>
|
|
1284
1330
|
</button>
|
|
@@ -533,7 +533,8 @@ zn-page-palette-item {
|
|
|
533
533
|
}
|
|
534
534
|
|
|
535
535
|
&:hover &__add,
|
|
536
|
-
&--active &__add
|
|
536
|
+
&--active &__add,
|
|
537
|
+
&__add:focus-visible {
|
|
537
538
|
opacity: 1;
|
|
538
539
|
}
|
|
539
540
|
}
|
|
@@ -582,6 +583,10 @@ zn-page-section-card.dragging,
|
|
|
582
583
|
border-color: rgb(var(--zn-color-border-active));
|
|
583
584
|
color: rgba(var(--zn-text), 0.7);
|
|
584
585
|
}
|
|
586
|
+
|
|
587
|
+
&:focus-visible {
|
|
588
|
+
outline: var(--zn-focus-ring);
|
|
589
|
+
}
|
|
585
590
|
}
|
|
586
591
|
|
|
587
592
|
&--active {
|
|
@@ -45,9 +45,16 @@ export default class ZnPageNav extends ZnTabs {
|
|
|
45
45
|
|
|
46
46
|
toggleNavigation() {
|
|
47
47
|
const navigationElement = this.shadowRoot?.querySelector('.navigation');
|
|
48
|
+
const toggle = this.shadowRoot?.querySelector<HTMLElement>('.breadcrumb-menu-toggle');
|
|
48
49
|
if (navigationElement) {
|
|
49
50
|
// Toggle the 'active' class to show/hide the navigation
|
|
50
|
-
navigationElement.classList.toggle('active');
|
|
51
|
+
const open = navigationElement.classList.toggle('active');
|
|
52
|
+
toggle?.setAttribute('aria-expanded', String(open));
|
|
53
|
+
|
|
54
|
+
// The closed menu is hidden, so focus inside it would be lost. The toggle is only shown on narrow layouts.
|
|
55
|
+
if (!open && navigationElement.contains(this.shadowRoot!.activeElement) && toggle?.checkVisibility()) {
|
|
56
|
+
toggle.focus();
|
|
57
|
+
}
|
|
51
58
|
}
|
|
52
59
|
// toggle menu overlay
|
|
53
60
|
const menuOverlay = this.shadowRoot?.querySelector('.menu-overlay');
|
|
@@ -56,6 +63,20 @@ export default class ZnPageNav extends ZnTabs {
|
|
|
56
63
|
}
|
|
57
64
|
}
|
|
58
65
|
|
|
66
|
+
private handleToggleKeyDown = (e: KeyboardEvent) => {
|
|
67
|
+
if (e.key === 'Enter' || e.key === ' ') {
|
|
68
|
+
e.preventDefault();
|
|
69
|
+
this.toggleNavigation();
|
|
70
|
+
}
|
|
71
|
+
};
|
|
72
|
+
|
|
73
|
+
private handleNavigationKeyDown = (e: KeyboardEvent) => {
|
|
74
|
+
if (e.key === 'Escape' && (e.currentTarget as HTMLElement).classList.contains('active')) {
|
|
75
|
+
e.stopPropagation();
|
|
76
|
+
this.toggleNavigation();
|
|
77
|
+
}
|
|
78
|
+
};
|
|
79
|
+
|
|
59
80
|
setActiveTab(tabName: string, store: boolean, refresh: boolean, refTab: string | null = null) {
|
|
60
81
|
super.setActiveTab(tabName, store, refresh, refTab);
|
|
61
82
|
|
|
@@ -96,13 +117,14 @@ export default class ZnPageNav extends ZnTabs {
|
|
|
96
117
|
|
|
97
118
|
return html`
|
|
98
119
|
<div class="breadcrumb">
|
|
99
|
-
<div @click="${this.toggleNavigation}" class="breadcrumb-menu-toggle"
|
|
120
|
+
<div @click="${this.toggleNavigation}" @keydown="${this.handleToggleKeyDown}" class="breadcrumb-menu-toggle"
|
|
121
|
+
role="button" tabindex="0" aria-expanded="false">
|
|
100
122
|
<zn-icon src="menu" size="24"></zn-icon>
|
|
101
123
|
<span>${this.breadcrumb}</span>
|
|
102
124
|
</div>
|
|
103
125
|
</div>
|
|
104
126
|
<div class="tabs">
|
|
105
|
-
<div class="navigation">
|
|
127
|
+
<div class="navigation" @keydown="${this.handleNavigationKeyDown}">
|
|
106
128
|
${navItems}
|
|
107
129
|
</div>
|
|
108
130
|
<div class="menu-overlay" @click="${this.toggleNavigation}"></div>
|
|
@@ -84,7 +84,7 @@
|
|
|
84
84
|
}
|
|
85
85
|
|
|
86
86
|
.navigation-item.active {
|
|
87
|
-
color: rgb(var(--zn-primary));
|
|
87
|
+
color: var(--zn-color-primary-fg, rgb(var(--zn-primary)));
|
|
88
88
|
}
|
|
89
89
|
|
|
90
90
|
.navigation-group + .navigation-group {
|
|
@@ -104,6 +104,10 @@
|
|
|
104
104
|
}
|
|
105
105
|
|
|
106
106
|
.breadcrumb-menu-toggle {
|
|
107
|
+
&:focus-visible {
|
|
108
|
+
outline: var(--zn-focus-ring);
|
|
109
|
+
}
|
|
110
|
+
|
|
107
111
|
cursor: pointer;
|
|
108
112
|
margin-left: var(--zn-base-gap);
|
|
109
113
|
|
|
@@ -148,7 +152,10 @@
|
|
|
148
152
|
height: 100%;
|
|
149
153
|
bottom: 0;
|
|
150
154
|
z-index: var(--zn-z-index-page-nav);
|
|
151
|
-
|
|
155
|
+
// Visibility keeps the closed menu out of the tab order; it flips only after the slide-out finishes
|
|
156
|
+
visibility: hidden;
|
|
157
|
+
transition: left var(--page-nav-animation-duration) ease-in-out, opacity var(--page-nav-animation-duration) ease-in-out,
|
|
158
|
+
visibility var(--page-nav-animation-duration);
|
|
152
159
|
}
|
|
153
160
|
|
|
154
161
|
.tabs {
|
|
@@ -158,6 +165,7 @@
|
|
|
158
165
|
}
|
|
159
166
|
|
|
160
167
|
.navigation.active {
|
|
168
|
+
visibility: visible;
|
|
161
169
|
pointer-events: all;
|
|
162
170
|
left: 0;
|
|
163
171
|
opacity: 1;
|
|
@@ -1,7 +1,9 @@
|
|
|
1
|
+
import {ifDefined} from "lit/directives/if-defined.js";
|
|
1
2
|
import {classMap} from "lit/directives/class-map.js";
|
|
2
3
|
import {type CSSResultGroup, html, type PropertyValues, unsafeCSS} from 'lit';
|
|
3
4
|
import {HasSlotController} from "../../internal/slot";
|
|
4
5
|
import {property, state} from 'lit/decorators.js';
|
|
6
|
+
import {registerCosmicBorder} from "../../internal/cosmic-border";
|
|
5
7
|
import ZincElement from '../../internal/zinc-element';
|
|
6
8
|
|
|
7
9
|
import styles from './panel.scss';
|
|
@@ -19,11 +21,14 @@ import styles from './panel.scss';
|
|
|
19
21
|
* @csspart base - The component's base wrapper.
|
|
20
22
|
* @csspart header - The header region, when a caption or actions are given.
|
|
21
23
|
* @csspart header-content - The padded row inside the header, forwarded from zn-header.
|
|
24
|
+
* @csspart header-left - The caption and description, forwarded from zn-header.
|
|
22
25
|
* @csspart footer - The footer region, when the footer slot is filled.
|
|
23
26
|
*
|
|
24
27
|
* @cssproperty --zn-panel-basis - The flex-basis of the panel. Can be set using the basis-px attribute.
|
|
25
28
|
* @cssproperty --zn-panel-header-padding - Padding around the header row. Defaults to `--zn-base-gap`.
|
|
26
29
|
* @cssproperty --zn-panel-footer-padding - Padding around the footer row.
|
|
30
|
+
* @cssproperty --zn-panel-padding - Padding around the body. Defaults to `--zn-base-gap`.
|
|
31
|
+
* @cssproperty --zn-panel-shadow - Resting shadow. Defaults to none.
|
|
27
32
|
*/
|
|
28
33
|
export default class ZnPanel extends ZincElement {
|
|
29
34
|
static styles: CSSResultGroup = unsafeCSS(styles);
|
|
@@ -32,6 +37,11 @@ export default class ZnPanel extends ZincElement {
|
|
|
32
37
|
|
|
33
38
|
@property({attribute: 'basis-px', type: Number}) basis: number;
|
|
34
39
|
@property() caption: string;
|
|
40
|
+
/** Help text under the caption, in the panel's header. */
|
|
41
|
+
@property() description: string;
|
|
42
|
+
|
|
43
|
+
/** Sets the description beside the caption rather than under it. */
|
|
44
|
+
@property({attribute: 'inline-description', type: Boolean}) inlineDescription = false;
|
|
35
45
|
@property() icon: string;
|
|
36
46
|
@property({type: Boolean}) tabbed: boolean;
|
|
37
47
|
@property({attribute: 'header-borderless', type: Boolean}) headerBorderless: boolean;
|
|
@@ -72,18 +82,7 @@ export default class ZnPanel extends ZincElement {
|
|
|
72
82
|
this.observeBodyContent();
|
|
73
83
|
}
|
|
74
84
|
|
|
75
|
-
|
|
76
|
-
try {
|
|
77
|
-
window.CSS.registerProperty({
|
|
78
|
-
inherits: false,
|
|
79
|
-
initialValue: '0deg',
|
|
80
|
-
name: '--rotate',
|
|
81
|
-
syntax: '<angle>',
|
|
82
|
-
});
|
|
83
|
-
} catch (e) {
|
|
84
|
-
// do nothing
|
|
85
|
-
}
|
|
86
|
-
}
|
|
85
|
+
registerCosmicBorder();
|
|
87
86
|
}
|
|
88
87
|
|
|
89
88
|
disconnectedCallback() {
|
|
@@ -142,13 +141,15 @@ export default class ZnPanel extends ZincElement {
|
|
|
142
141
|
<div class="panel__inner">
|
|
143
142
|
${hasHeader ? html`
|
|
144
143
|
<zn-header part="header"
|
|
145
|
-
exportparts="content:header-content"
|
|
144
|
+
exportparts="content:header-content, header-left"
|
|
146
145
|
class="${classMap({
|
|
147
146
|
"panel__header": true,
|
|
148
147
|
"panel__header--underline": underlineHeader,
|
|
149
148
|
})}"
|
|
150
149
|
icon="${this.icon}"
|
|
151
150
|
caption="${this.caption}"
|
|
151
|
+
description="${ifDefined(this.description)}"
|
|
152
|
+
?inline-description="${this.inlineDescription}"
|
|
152
153
|
transparent>
|
|
153
154
|
${hasActionSlot ? html`
|
|
154
155
|
<slot name="actions" slot="actions" class="panel__header__actions"></slot>` : null}
|
|
@@ -19,7 +19,8 @@
|
|
|
19
19
|
position: relative;
|
|
20
20
|
border: 1px solid rgb(var(--zn-border-color));
|
|
21
21
|
display: flex;
|
|
22
|
-
border-radius: var(--zn-border-radius);
|
|
22
|
+
border-radius: var(--zn-panel-border-radius, var(--zn-border-radius));
|
|
23
|
+
box-shadow: var(--zn-panel-shadow, none);
|
|
23
24
|
flex-direction: column;
|
|
24
25
|
flex-grow: 1;
|
|
25
26
|
flex-basis: var(--zn-spacing-small-panel);
|
|
@@ -29,7 +30,7 @@
|
|
|
29
30
|
&__inner {
|
|
30
31
|
overflow: hidden;
|
|
31
32
|
display: flex;
|
|
32
|
-
border-radius: var(--zn-border-radius);
|
|
33
|
+
border-radius: var(--zn-panel-border-radius, var(--zn-border-radius));
|
|
33
34
|
flex-direction: column;
|
|
34
35
|
flex-grow: 1;
|
|
35
36
|
}
|
|
@@ -58,7 +59,7 @@
|
|
|
58
59
|
}
|
|
59
60
|
|
|
60
61
|
&--underline {
|
|
61
|
-
border-bottom: 1px solid rgb(var(--zn-border-color));
|
|
62
|
+
border-bottom: 1px solid var(--zn-panel-header-divider-color, rgb(var(--zn-border-color)));
|
|
62
63
|
}
|
|
63
64
|
|
|
64
65
|
&::part(content) {
|
|
@@ -71,7 +72,7 @@
|
|
|
71
72
|
flex-direction: column;
|
|
72
73
|
overflow-y: auto;
|
|
73
74
|
flex-grow: 1;
|
|
74
|
-
padding: var(--zn-base-gap);
|
|
75
|
+
padding: var(--zn-panel-padding, var(--zn-base-gap));
|
|
75
76
|
|
|
76
77
|
> :not([hidden]) ~ :not([hidden]) {
|
|
77
78
|
border: 1px solid rgb(var(--zn-border-color));
|
|
@@ -82,9 +83,10 @@
|
|
|
82
83
|
font-size: var(--zn-font-size-small);
|
|
83
84
|
display: block;
|
|
84
85
|
padding: var(--zn-panel-footer-padding, var(--zn-spacing-small) var(--zn-base-gap));
|
|
85
|
-
background: rgb(var(--zn-body));
|
|
86
|
-
border-
|
|
87
|
-
border-bottom-
|
|
86
|
+
background: var(--zn-panel-footer-background, rgb(var(--zn-body)));
|
|
87
|
+
border-top: var(--zn-panel-footer-divider, none);
|
|
88
|
+
border-bottom-left-radius: var(--zn-panel-border-radius, var(--zn-border-radius));
|
|
89
|
+
border-bottom-right-radius: var(--zn-panel-border-radius, var(--zn-border-radius));
|
|
88
90
|
}
|
|
89
91
|
|
|
90
92
|
&--tabbed .panel__body {
|
|
@@ -94,6 +96,7 @@
|
|
|
94
96
|
&--transparent {
|
|
95
97
|
background-color: transparent;
|
|
96
98
|
border: none;
|
|
99
|
+
box-shadow: none;
|
|
97
100
|
|
|
98
101
|
&:before {
|
|
99
102
|
display: none;
|
|
@@ -145,14 +148,15 @@
|
|
|
145
148
|
// The body scrolls, so it can't take a clip margin — it gets a gutter cancelled by a negative margin instead.
|
|
146
149
|
&--transparent {
|
|
147
150
|
.panel__header {
|
|
151
|
+
position: relative;
|
|
152
|
+
z-index: 1;
|
|
148
153
|
padding-left: 0;
|
|
149
154
|
padding-right: 0;
|
|
150
155
|
}
|
|
151
156
|
|
|
152
157
|
.panel__inner,
|
|
153
158
|
.panel__content {
|
|
154
|
-
|
|
155
|
-
overflow-clip-margin: var(--zn-focus-ring-outset);
|
|
159
|
+
@include wc.clip-focus-room;
|
|
156
160
|
}
|
|
157
161
|
|
|
158
162
|
&.panel--flush .panel__body {
|
|
@@ -176,7 +180,7 @@
|
|
|
176
180
|
}
|
|
177
181
|
|
|
178
182
|
&--shadow {
|
|
179
|
-
box-shadow: 0 6px 20px 10px rgba(0, 0, 0, 0.25);
|
|
183
|
+
box-shadow: var(--zn-panel-shadow-raised, 0 6px 20px 10px rgba(0, 0, 0, 0.25));
|
|
180
184
|
}
|
|
181
185
|
|
|
182
186
|
}
|