@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
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
@use "../../wc";
|
|
2
|
+
|
|
3
|
+
:host {
|
|
4
|
+
display: block;
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
.color-picker {
|
|
8
|
+
display: flex;
|
|
9
|
+
flex-direction: column;
|
|
10
|
+
gap: 12px;
|
|
11
|
+
width: var(--zn-color-picker-width, 280px);
|
|
12
|
+
padding: 12px;
|
|
13
|
+
background: var(--zn-panel-background-color, rgb(var(--zn-panel)));
|
|
14
|
+
border: 1px solid rgb(var(--zn-border-color));
|
|
15
|
+
border-radius: var(--zn-border-radius-medium);
|
|
16
|
+
box-shadow: var(--zn-shadow-large);
|
|
17
|
+
font-family: var(--zn-font-family-sans);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
.color-picker__area {
|
|
21
|
+
position: relative;
|
|
22
|
+
height: 152px;
|
|
23
|
+
border-radius: var(--zn-border-radius);
|
|
24
|
+
cursor: crosshair;
|
|
25
|
+
touch-action: none;
|
|
26
|
+
background-image: linear-gradient(to top, #000, transparent), linear-gradient(to right, #fff, rgba(255, 255, 255, 0));
|
|
27
|
+
|
|
28
|
+
&:focus-visible {
|
|
29
|
+
outline: none;
|
|
30
|
+
box-shadow: 0 0 0 var(--zn-focus-ring-width) var(--zn-input-focus-ring-color);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
// Not @extend: a merged selector list holding an unknown vendor pseudo-element is dropped whole.
|
|
35
|
+
@mixin thumb {
|
|
36
|
+
border: 2px solid #fff;
|
|
37
|
+
border-radius: 50%;
|
|
38
|
+
box-shadow: 0 0 0 1px rgba(0, 0, 0, .35), 0 1px 3px rgba(0, 0, 0, .4);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
.color-picker__dot {
|
|
42
|
+
@include thumb;
|
|
43
|
+
position: absolute;
|
|
44
|
+
width: 14px;
|
|
45
|
+
height: 14px;
|
|
46
|
+
margin: -7px 0 0 -7px;
|
|
47
|
+
pointer-events: none;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
.color-picker__hue {
|
|
51
|
+
appearance: none;
|
|
52
|
+
width: 100%;
|
|
53
|
+
height: 12px;
|
|
54
|
+
margin: 0;
|
|
55
|
+
border-radius: 999px;
|
|
56
|
+
cursor: pointer;
|
|
57
|
+
background: linear-gradient(to right, #f00, #ff0, #0f0, #0ff, #00f, #f0f, #f00);
|
|
58
|
+
|
|
59
|
+
&::-webkit-slider-thumb {
|
|
60
|
+
@include thumb;
|
|
61
|
+
appearance: none;
|
|
62
|
+
width: 16px;
|
|
63
|
+
height: 16px;
|
|
64
|
+
background: transparent;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
&::-moz-range-thumb {
|
|
68
|
+
@include thumb;
|
|
69
|
+
width: 12px;
|
|
70
|
+
height: 12px;
|
|
71
|
+
background: transparent;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
&:focus-visible {
|
|
75
|
+
outline: none;
|
|
76
|
+
box-shadow: 0 0 0 var(--zn-focus-ring-width) var(--zn-input-focus-ring-color);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
.color-picker__values {
|
|
81
|
+
display: flex;
|
|
82
|
+
flex-direction: column;
|
|
83
|
+
gap: 8px;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
.color-picker__row {
|
|
87
|
+
display: grid;
|
|
88
|
+
grid-template-columns: 48px 1fr;
|
|
89
|
+
align-items: center;
|
|
90
|
+
gap: 8px;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
.color-picker__row-label {
|
|
94
|
+
font-size: 11px;
|
|
95
|
+
font-weight: var(--zn-font-weight-semibold);
|
|
96
|
+
line-height: 1;
|
|
97
|
+
letter-spacing: 0.04em;
|
|
98
|
+
color: var(--zn-input-placeholder-color);
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
.color-picker__trio {
|
|
102
|
+
display: grid;
|
|
103
|
+
grid-template-columns: repeat(3, minmax(0, 1fr));
|
|
104
|
+
gap: 4px;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
.color-picker__field {
|
|
108
|
+
width: 100%;
|
|
109
|
+
min-width: 0;
|
|
110
|
+
height: var(--zn-input-height-small);
|
|
111
|
+
padding: 0 8px;
|
|
112
|
+
font-family: var(--zn-font-family-mono);
|
|
113
|
+
font-size: 12px;
|
|
114
|
+
font-variant-numeric: tabular-nums;
|
|
115
|
+
text-align: center;
|
|
116
|
+
color: var(--zn-input-color);
|
|
117
|
+
background: var(--zn-input-background-color);
|
|
118
|
+
border: solid var(--zn-input-border-width) var(--zn-input-border-color);
|
|
119
|
+
border-radius: var(--zn-input-border-radius-small);
|
|
120
|
+
box-shadow: var(--zn-input-shadow, none);
|
|
121
|
+
transition: var(--zn-transition-fast) border-color, var(--zn-transition-fast) box-shadow;
|
|
122
|
+
|
|
123
|
+
&:hover {
|
|
124
|
+
border-color: var(--zn-input-border-color-hover);
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
&:focus {
|
|
128
|
+
outline: none;
|
|
129
|
+
border-color: var(--zn-input-border-color-focus);
|
|
130
|
+
box-shadow: 0 0 0 var(--zn-focus-ring-width) var(--zn-input-focus-ring-color);
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
&[aria-invalid='true'] {
|
|
134
|
+
color: var(--zn-color-danger-fg);
|
|
135
|
+
border-color: var(--zn-input-border-color-invalid);
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
.color-picker__row--hex .color-picker__field {
|
|
140
|
+
text-align: left;
|
|
141
|
+
}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import '../../../dist/zn.min.js';
|
|
2
|
+
import {expect, fixture, html, oneEvent} from '@open-wc/testing';
|
|
3
|
+
import type ZnColorPicker from './color-picker.component';
|
|
4
|
+
|
|
5
|
+
const field = (el: ZnColorPicker, key: string) => el.shadowRoot!.querySelector<HTMLInputElement>(`[data-k="${key}"]`)!;
|
|
6
|
+
|
|
7
|
+
const type = (input: HTMLInputElement, value: string) => {
|
|
8
|
+
input.focus();
|
|
9
|
+
input.value = value;
|
|
10
|
+
input.dispatchEvent(new Event('input', {bubbles: true, composed: true}));
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
describe('<zn-color-picker>', () => {
|
|
14
|
+
it('shows the colour in every format', async () => {
|
|
15
|
+
const el = await fixture<ZnColorPicker>(html`<zn-color-picker value="rgb(8, 94, 253)"></zn-color-picker>`);
|
|
16
|
+
|
|
17
|
+
expect(el.value).to.equal('#085EFD');
|
|
18
|
+
expect(field(el, 'hex').value).to.equal('#085EFD');
|
|
19
|
+
expect([field(el, 'r').value, field(el, 'g').value, field(el, 'b').value]).to.deep.equal(['8', '94', '253']);
|
|
20
|
+
expect([field(el, 'h').value, field(el, 's').value, field(el, 'l').value]).to.deep.equal(['219', '98', '51']);
|
|
21
|
+
expect([field(el, 'ol').value, field(el, 'oc').value, field(el, 'oh').value]).to.deep.equal(['54.8', '0.247', '262']);
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
it('updates the other rows when one is edited and switches to its format', async () => {
|
|
25
|
+
const el = await fixture<ZnColorPicker>(html`<zn-color-picker value="#085EFD"></zn-color-picker>`);
|
|
26
|
+
|
|
27
|
+
const changed = oneEvent(el, 'zn-input');
|
|
28
|
+
type(field(el, 'g'), '200');
|
|
29
|
+
await changed;
|
|
30
|
+
await el.updateComplete;
|
|
31
|
+
|
|
32
|
+
expect(el.value).to.equal('#08C8FD');
|
|
33
|
+
expect(el.format).to.equal('rgb');
|
|
34
|
+
expect(field(el, 'hex').value).to.equal('#08C8FD');
|
|
35
|
+
expect(field(el, 'g').value).to.equal('200');
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
it('marks an out-of-range value red without changing the colour', async () => {
|
|
39
|
+
const el = await fixture<ZnColorPicker>(html`<zn-color-picker value="#085EFD"></zn-color-picker>`);
|
|
40
|
+
|
|
41
|
+
type(field(el, 'r'), '300');
|
|
42
|
+
await el.updateComplete;
|
|
43
|
+
|
|
44
|
+
expect(field(el, 'r').getAttribute('aria-invalid')).to.equal('true');
|
|
45
|
+
expect(el.value).to.equal('#085EFD');
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
it('moves brightness with the arrow keys', async () => {
|
|
49
|
+
const el = await fixture<ZnColorPicker>(html`<zn-color-picker value="#FFFFFF"></zn-color-picker>`);
|
|
50
|
+
const area = el.shadowRoot!.querySelector<HTMLElement>('.color-picker__area')!;
|
|
51
|
+
|
|
52
|
+
area.dispatchEvent(new KeyboardEvent('keydown', {key: 'ArrowDown'}));
|
|
53
|
+
await el.updateComplete;
|
|
54
|
+
|
|
55
|
+
expect(el.value).to.equal('#FCFCFC');
|
|
56
|
+
});
|
|
57
|
+
});
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import ZnColorPicker from './color-picker.component';
|
|
2
|
+
|
|
3
|
+
export * from './color-picker.component';
|
|
4
|
+
export default ZnColorPicker;
|
|
5
|
+
|
|
6
|
+
ZnColorPicker.define('zn-color-picker');
|
|
7
|
+
|
|
8
|
+
declare global {
|
|
9
|
+
interface HTMLElementTagNameMap {
|
|
10
|
+
'zn-color-picker': ZnColorPicker;
|
|
11
|
+
}
|
|
12
|
+
}
|
|
@@ -48,6 +48,9 @@ export default class ZnCols extends ZincElement {
|
|
|
48
48
|
|
|
49
49
|
@property({attribute: 'mc', type: Number, reflect: true}) maxColumns: number = 0;
|
|
50
50
|
|
|
51
|
+
/** Minimum width in px of a one-unit column before the row wraps; a column of layout `n` asks for n times this. Defaults to 250. */
|
|
52
|
+
@property({type: Number}) basis: number;
|
|
53
|
+
|
|
51
54
|
@property({attribute: 'no-gap', type: Boolean}) noGap: boolean = false;
|
|
52
55
|
|
|
53
56
|
@property({type: Boolean}) border: boolean = false;
|
|
@@ -81,6 +84,13 @@ export default class ZnCols extends ZincElement {
|
|
|
81
84
|
|
|
82
85
|
protected updated(changed: PropertyValues<this>) {
|
|
83
86
|
super.updated(changed);
|
|
87
|
+
if (changed.has('basis')) {
|
|
88
|
+
if (this.basis > 0) {
|
|
89
|
+
this.style.setProperty('--zn-col-basis', `${this.basis}px`);
|
|
90
|
+
} else {
|
|
91
|
+
this.style.removeProperty('--zn-col-basis');
|
|
92
|
+
}
|
|
93
|
+
}
|
|
84
94
|
this.markRowEnds();
|
|
85
95
|
}
|
|
86
96
|
|
|
@@ -182,4 +182,21 @@ describe('<zn-cols>', () => {
|
|
|
182
182
|
expect(ruleOf('#d')).to.equal('none');
|
|
183
183
|
});
|
|
184
184
|
});
|
|
185
|
+
|
|
186
|
+
it('sizes columns from the basis attribute', async () => {
|
|
187
|
+
const el = await cols(`
|
|
188
|
+
<zn-cols layout="1,2" basis="140">
|
|
189
|
+
<div id="one"></div>
|
|
190
|
+
<div id="two"></div>
|
|
191
|
+
</zn-cols>`);
|
|
192
|
+
|
|
193
|
+
expect(getComputedStyle(el.querySelector('#one')!).flexBasis).to.equal('140px');
|
|
194
|
+
expect(getComputedStyle(el.querySelector('#two')!).flexBasis).to.equal('280px');
|
|
195
|
+
});
|
|
196
|
+
|
|
197
|
+
it('keeps the default basis without the attribute', async () => {
|
|
198
|
+
const el = await cols(`<zn-cols layout="1"><div id="one"></div></zn-cols>`);
|
|
199
|
+
|
|
200
|
+
expect(getComputedStyle(el.querySelector('#one')!).flexBasis).to.equal('250px');
|
|
201
|
+
});
|
|
185
202
|
});
|
|
@@ -6,6 +6,7 @@ import {ifDefined} from "lit/directives/if-defined.js";
|
|
|
6
6
|
import {property, query, state} from 'lit/decorators.js';
|
|
7
7
|
import ZincElement from "../../internal/zinc-element";
|
|
8
8
|
import ZnDialog from "../dialog";
|
|
9
|
+
import type ZnButton from "../button";
|
|
9
10
|
|
|
10
11
|
import styles from './confirm.scss';
|
|
11
12
|
|
|
@@ -66,11 +67,11 @@ export default class ZnConfirm extends ZincElement {
|
|
|
66
67
|
|
|
67
68
|
@property() content: string = '';
|
|
68
69
|
|
|
69
|
-
@property() confirmText: string = "Confirm";
|
|
70
|
+
@property({attribute: 'confirm-text'}) confirmText: string = "Confirm";
|
|
70
71
|
|
|
71
|
-
@property() cancelText: string = "Cancel";
|
|
72
|
+
@property({attribute: 'cancel-text'}) cancelText: string = "Cancel";
|
|
72
73
|
|
|
73
|
-
@property() closeText: string = "Close";
|
|
74
|
+
@property({attribute: 'close-text'}) closeText: string = "Close";
|
|
74
75
|
|
|
75
76
|
@property({type: Boolean, attribute: 'hide-icon'}) hideIcon: boolean = false;
|
|
76
77
|
|
|
@@ -102,6 +103,8 @@ export default class ZnConfirm extends ZincElement {
|
|
|
102
103
|
|
|
103
104
|
private submitted: HTMLFormElement | null = null;
|
|
104
105
|
|
|
106
|
+
private generatedForm: HTMLFormElement | null = null;
|
|
107
|
+
|
|
105
108
|
protected firstUpdated(_changedProperties: PropertyValues) {
|
|
106
109
|
super.firstUpdated(_changedProperties);
|
|
107
110
|
if (this.open) {
|
|
@@ -132,11 +135,13 @@ export default class ZnConfirm extends ZincElement {
|
|
|
132
135
|
});
|
|
133
136
|
}
|
|
134
137
|
|
|
135
|
-
show = (event: Event | undefined = undefined) => {
|
|
138
|
+
show = async (event: Event | undefined = undefined) => {
|
|
136
139
|
const trigger = event?.target as HTMLButtonElement
|
|
137
140
|
if (trigger?.disabled) return;
|
|
138
141
|
this.reset();
|
|
139
142
|
this.dialog.show();
|
|
143
|
+
await this.updateComplete;
|
|
144
|
+
this.renderRoot.querySelector<ZnButton>('zn-button[dialog-closer]')?.button?.focus();
|
|
140
145
|
}
|
|
141
146
|
|
|
142
147
|
hide() {
|
|
@@ -169,7 +174,7 @@ export default class ZnConfirm extends ZincElement {
|
|
|
169
174
|
* The console dispatches the pagelet lifecycle on the form it submitted. Without it the loading
|
|
170
175
|
* state only ends when a response happens to reload the page, so every failure hangs the dialog.
|
|
171
176
|
*/
|
|
172
|
-
private settle = (event: Event) => {
|
|
177
|
+
private settle = async (event: Event) => {
|
|
173
178
|
const response = (event as CustomEvent<{ response?: PageletResponse }>).detail?.response;
|
|
174
179
|
this.stopWatching();
|
|
175
180
|
if (event.type === 'error' || this.responseFailed(response)) {
|
|
@@ -179,6 +184,8 @@ export default class ZnConfirm extends ZincElement {
|
|
|
179
184
|
if (this.dialog?.closer) {
|
|
180
185
|
this.dialog.closer.disabled = false;
|
|
181
186
|
}
|
|
187
|
+
await this.updateComplete;
|
|
188
|
+
this.renderRoot.querySelector<ZnButton>('zn-button[dialog-closer]')?.button?.focus();
|
|
182
189
|
return;
|
|
183
190
|
}
|
|
184
191
|
this.hide();
|
|
@@ -237,7 +244,7 @@ export default class ZnConfirm extends ZincElement {
|
|
|
237
244
|
<zn-button outline color="${this.type}" slot="footer" dialog-closer disabled=${this.loading || nothing}>
|
|
238
245
|
${this.cancelText}
|
|
239
246
|
</zn-button>
|
|
240
|
-
<zn-button color="${this.type}" slot="footer" @click="${this.submitDialog}"
|
|
247
|
+
<zn-button color="${this.type}" slot="footer" @click="${this.submitDialog}" ?processing=${this.loading}>
|
|
241
248
|
${this.confirmText}
|
|
242
249
|
</zn-button>`}
|
|
243
250
|
|
|
@@ -246,10 +253,17 @@ export default class ZnConfirm extends ZincElement {
|
|
|
246
253
|
}
|
|
247
254
|
|
|
248
255
|
submitDialog() {
|
|
256
|
+
if (this.loading) return;
|
|
257
|
+
|
|
258
|
+
// Rebuilt per submit: a re-rendered list can reuse this element for another row with a different action
|
|
259
|
+
this.generatedForm?.remove();
|
|
260
|
+
this.generatedForm = null;
|
|
261
|
+
|
|
249
262
|
// get the form from the slot
|
|
250
263
|
let form = this.querySelector('form');
|
|
251
264
|
if (!form && this.action) {
|
|
252
265
|
form = document.createElement('form') as HTMLFormElement;
|
|
266
|
+
this.generatedForm = form;
|
|
253
267
|
form.action = this.action;
|
|
254
268
|
form.method = 'POST';
|
|
255
269
|
|
|
@@ -61,6 +61,15 @@ describe('<zn-confirm-modal>', () => {
|
|
|
61
61
|
expect(confirm.shadowRoot!.textContent).to.contain('Loading');
|
|
62
62
|
});
|
|
63
63
|
|
|
64
|
+
it('keeps the confirm button focusable while loading', async () => {
|
|
65
|
+
const {confirm} = await submittedConfirm();
|
|
66
|
+
|
|
67
|
+
const buttons = confirm.shadowRoot!.querySelectorAll('zn-button[slot="footer"]');
|
|
68
|
+
expect(buttons[0].hasAttribute('disabled')).to.be.true;
|
|
69
|
+
expect(buttons[1].hasAttribute('disabled')).to.be.false;
|
|
70
|
+
expect(buttons[1].hasAttribute('processing')).to.be.true;
|
|
71
|
+
});
|
|
72
|
+
|
|
64
73
|
it('reports failure when the response carries a danger alert', async () => {
|
|
65
74
|
const {confirm, form, dialog} = await submittedConfirm();
|
|
66
75
|
|
|
@@ -75,6 +84,16 @@ describe('<zn-confirm-modal>', () => {
|
|
|
75
84
|
expect(closer(dialog).disabled).to.be.false;
|
|
76
85
|
});
|
|
77
86
|
|
|
87
|
+
it('focuses cancel when opened', async () => {
|
|
88
|
+
const confirm = await fixture<HTMLElement>(html`<zn-confirm caption="Deploy"></zn-confirm>`);
|
|
89
|
+
|
|
90
|
+
await (confirm as never as {show: () => Promise<void>}).show();
|
|
91
|
+
|
|
92
|
+
const cancel = confirm.shadowRoot!.querySelector('zn-button[dialog-closer]');
|
|
93
|
+
expect(cancel!.textContent!.trim()).to.equal('Cancel');
|
|
94
|
+
expect(confirm.shadowRoot!.activeElement).to.equal(cancel);
|
|
95
|
+
});
|
|
96
|
+
|
|
78
97
|
it('offers only a close button once the request has failed', async () => {
|
|
79
98
|
const {confirm, form} = await submittedConfirm();
|
|
80
99
|
|
|
@@ -85,6 +104,7 @@ describe('<zn-confirm-modal>', () => {
|
|
|
85
104
|
expect(buttons.length).to.equal(1);
|
|
86
105
|
expect(buttons[0].textContent!.trim()).to.equal('Close');
|
|
87
106
|
expect(buttons[0].hasAttribute('dialog-closer')).to.be.true;
|
|
107
|
+
expect(confirm.shadowRoot!.activeElement).to.equal(buttons[0]);
|
|
88
108
|
});
|
|
89
109
|
|
|
90
110
|
it('reports failure when the request errors', async () => {
|
|
@@ -117,4 +137,36 @@ describe('<zn-confirm-modal>', () => {
|
|
|
117
137
|
|
|
118
138
|
expect(confirm.shadowRoot!.textContent).to.not.contain('Failed');
|
|
119
139
|
});
|
|
140
|
+
it('submits to its current action after the action changes', async () => {
|
|
141
|
+
const confirm = await fixture<HTMLElement & {action: string; updateComplete: Promise<void>; show: () => void}>(
|
|
142
|
+
html`<zn-confirm caption="Delete" action="/items/1/delete"></zn-confirm>`);
|
|
143
|
+
const posted: string[] = [];
|
|
144
|
+
document.addEventListener('submit', e => {
|
|
145
|
+
e.preventDefault();
|
|
146
|
+
posted.push(new URL((e.target as HTMLFormElement).action).pathname);
|
|
147
|
+
});
|
|
148
|
+
const submit = async () => {
|
|
149
|
+
confirm.show();
|
|
150
|
+
await confirm.updateComplete;
|
|
151
|
+
click(confirm.shadowRoot!.querySelectorAll('zn-button[slot="footer"]')[1]);
|
|
152
|
+
};
|
|
153
|
+
|
|
154
|
+
await submit();
|
|
155
|
+
confirm.action = '/items/2/delete';
|
|
156
|
+
await confirm.updateComplete;
|
|
157
|
+
await submit();
|
|
158
|
+
|
|
159
|
+
expect(posted).to.deep.equal(['/items/1/delete', '/items/2/delete']);
|
|
160
|
+
});
|
|
161
|
+
|
|
162
|
+
it('labels its buttons from the dashed text attributes', async () => {
|
|
163
|
+
const confirm = await fixture<HTMLElement & {updateComplete: Promise<void>}>(html`
|
|
164
|
+
<zn-confirm confirm-text="Archive" cancel-text="Keep"></zn-confirm>
|
|
165
|
+
`);
|
|
166
|
+
await confirm.updateComplete;
|
|
167
|
+
|
|
168
|
+
const buttons = confirm.shadowRoot!.querySelectorAll('zn-button[slot="footer"]');
|
|
169
|
+
expect(buttons[0].textContent!.trim()).to.equal('Keep');
|
|
170
|
+
expect(buttons[1].textContent!.trim()).to.equal('Archive');
|
|
171
|
+
});
|
|
120
172
|
});
|
|
@@ -3,6 +3,7 @@ import {deepQuerySelectorAll} from "../../utilities/query";
|
|
|
3
3
|
import {HasSlotController} from "../../internal/slot";
|
|
4
4
|
import {html, unsafeCSS} from 'lit';
|
|
5
5
|
import {htmlToText, looksLikeHtml} from './html-text';
|
|
6
|
+
import {ifDefined} from "lit/directives/if-defined.js";
|
|
6
7
|
import {MutationController} from '@lit-labs/observers/mutation-controller.js';
|
|
7
8
|
import {property, queryAssignedNodes, queryAsync, state} from 'lit/decorators.js';
|
|
8
9
|
import {sanitizeHtml} from '../../utilities/sanitize-html';
|
|
@@ -82,6 +83,7 @@ export default class ContentBlock extends ZincElement {
|
|
|
82
83
|
connectedCallback() {
|
|
83
84
|
super.connectedCallback();
|
|
84
85
|
this.iframe.then((iframe) => {
|
|
86
|
+
if (!iframe) return;
|
|
85
87
|
if (iframe.contentDocument) {
|
|
86
88
|
const div = this.htmlNodes[0] as HTMLDivElement;
|
|
87
89
|
if (div) {
|
|
@@ -109,6 +111,23 @@ export default class ContentBlock extends ZincElement {
|
|
|
109
111
|
super.disconnectedCallback();
|
|
110
112
|
}
|
|
111
113
|
|
|
114
|
+
private _handleHeaderKeyDown(e: KeyboardEvent) {
|
|
115
|
+
// Keys from the header's own actions belong to them
|
|
116
|
+
if (e.target !== e.currentTarget || (e.key !== 'Enter' && e.key !== ' ')) {
|
|
117
|
+
return;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
e.preventDefault();
|
|
121
|
+
this._collapseContent(e);
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
private _handleReplyKeyDown(e: KeyboardEvent) {
|
|
125
|
+
if (e.key === 'Enter' || e.key === ' ') {
|
|
126
|
+
e.preventDefault();
|
|
127
|
+
(e.currentTarget as HTMLElement).click();
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
|
|
112
131
|
private _collapseContent(e: Event) {
|
|
113
132
|
if (this.noCollapse) {
|
|
114
133
|
return;
|
|
@@ -136,7 +155,7 @@ export default class ContentBlock extends ZincElement {
|
|
|
136
155
|
private _toggleText() {
|
|
137
156
|
const textContent = this.shadowRoot?.querySelector('.text-content') as HTMLDivElement | null;
|
|
138
157
|
this.iframe.then((iframe) => {
|
|
139
|
-
if (textContent) {
|
|
158
|
+
if (iframe && textContent) {
|
|
140
159
|
iframe.classList.add('hidden');
|
|
141
160
|
textContent.classList.remove('hidden');
|
|
142
161
|
}
|
|
@@ -146,7 +165,7 @@ export default class ContentBlock extends ZincElement {
|
|
|
146
165
|
private _toggleHtml() {
|
|
147
166
|
const textContent = this.shadowRoot?.querySelector('.text-content') as HTMLDivElement | null;
|
|
148
167
|
this.iframe.then((iframe) => {
|
|
149
|
-
if (textContent) {
|
|
168
|
+
if (iframe && textContent) {
|
|
150
169
|
iframe.classList.remove('hidden');
|
|
151
170
|
textContent.classList.add('hidden');
|
|
152
171
|
setTimeout(() => this._resizeIframe(iframe), 0);
|
|
@@ -230,7 +249,12 @@ export default class ContentBlock extends ZincElement {
|
|
|
230
249
|
'content-block--collapsible': !this.noCollapse
|
|
231
250
|
})}">
|
|
232
251
|
|
|
233
|
-
<div class="content-block-header"
|
|
252
|
+
<div class="content-block-header"
|
|
253
|
+
role="${ifDefined(this.noCollapse ? undefined : 'button')}"
|
|
254
|
+
tabindex="${ifDefined(this.noCollapse ? undefined : '0')}"
|
|
255
|
+
aria-expanded="${ifDefined(this.noCollapse ? undefined : String(!this.short))}"
|
|
256
|
+
@click="${this._collapseContent}"
|
|
257
|
+
@keydown="${this._handleHeaderKeyDown}">
|
|
234
258
|
<div class="content-block-header__icon">
|
|
235
259
|
<slot name="icon">
|
|
236
260
|
<zn-icon src="${this.avatar}"
|
|
@@ -270,13 +294,16 @@ export default class ContentBlock extends ZincElement {
|
|
|
270
294
|
</div>
|
|
271
295
|
|
|
272
296
|
<zn-sp no-gap flush-x flush-t>
|
|
273
|
-
|
|
297
|
+
${hasHtmlSlot ? html`
|
|
298
|
+
<iframe class="${classMap({'hidden': !initialShowHtml})}" title="Content block HTML preview"></iframe>` : ''}
|
|
274
299
|
<slot class="html-content" name="html" style="display: none;"></slot>
|
|
275
300
|
<slot name="text" style="display: none;"></slot>
|
|
276
301
|
<div class="${classMap({'text-content': true, 'hidden': initialShowHtml})}">
|
|
277
302
|
${text.map((section) => html`
|
|
278
303
|
${section.type === 'reply' ? html`
|
|
279
|
-
<div class="toggle-reply"
|
|
304
|
+
<div class="toggle-reply" role="button" tabindex="0" aria-label="Show quoted text"
|
|
305
|
+
@click="${this.showReply}"
|
|
306
|
+
@keydown="${this._handleReplyKeyDown}">...</div>` : ''}
|
|
280
307
|
<div class=${classMap({
|
|
281
308
|
'text-section': true,
|
|
282
309
|
'text-section--reply': section.type === 'reply',
|
|
@@ -307,7 +334,7 @@ export default class ContentBlock extends ZincElement {
|
|
|
307
334
|
protected truncateText() {
|
|
308
335
|
const textContent = this.querySelector('[slot="text"]') as HTMLDivElement | null;
|
|
309
336
|
if (!textContent) return '';
|
|
310
|
-
const trimmed = htmlToText(textContent.
|
|
337
|
+
const trimmed = htmlToText(textContent.textContent ?? '');
|
|
311
338
|
return trimmed.length > 32 ? trimmed.substring(0, 32) + '...' : trimmed;
|
|
312
339
|
}
|
|
313
340
|
|
|
@@ -379,13 +406,15 @@ export default class ContentBlock extends ZincElement {
|
|
|
379
406
|
const textContent = this.querySelector('[slot="text"]') as HTMLDivElement | null;
|
|
380
407
|
const textRows: TextRow[] = [];
|
|
381
408
|
|
|
382
|
-
|
|
383
|
-
|
|
409
|
+
// Not innerText: it forces a layout per read (~6ms each in Safari), and this slot is never rendered.
|
|
410
|
+
const source = textContent?.textContent ?? '';
|
|
411
|
+
if (textContent && looksLikeHtml(source)) {
|
|
412
|
+
this._textRows = [{lines: [sanitizeHtml(source, EDITOR_TAGS, true)], type: 'text', html: true}];
|
|
384
413
|
return this._textRows;
|
|
385
414
|
}
|
|
386
415
|
|
|
387
416
|
if (textContent) {
|
|
388
|
-
const text =
|
|
417
|
+
const text = source.replace(/<br\s*\/?>/gi, '\n');
|
|
389
418
|
const rows = text.split('\n');
|
|
390
419
|
let previousType: TextRow['type'] | null = null;
|
|
391
420
|
let forceReply = false;
|
|
@@ -18,6 +18,11 @@
|
|
|
18
18
|
|
|
19
19
|
.content-block--collapsible .content-block-header {
|
|
20
20
|
cursor: pointer;
|
|
21
|
+
|
|
22
|
+
&:focus-visible {
|
|
23
|
+
outline: var(--zn-focus-ring);
|
|
24
|
+
border-radius: var(--zn-border-radius-small);
|
|
25
|
+
}
|
|
21
26
|
}
|
|
22
27
|
|
|
23
28
|
.content-block-header__icon {
|
|
@@ -37,6 +42,7 @@
|
|
|
37
42
|
}
|
|
38
43
|
|
|
39
44
|
.content-block-header__caption {
|
|
45
|
+
font-family: var(--zn-text-h1-font-family, inherit);
|
|
40
46
|
font-weight: var(--zn-text-h1-font-weight);
|
|
41
47
|
font-size: var(--zn-text-h1-font-size);
|
|
42
48
|
color: rgba(var(--zn-text-panel-title), 100%);
|
|
@@ -130,18 +136,18 @@
|
|
|
130
136
|
}
|
|
131
137
|
|
|
132
138
|
code {
|
|
133
|
-
background-color: #f0f0f0;
|
|
139
|
+
background-color: var(--zn-code-inline-background, #f0f0f0);
|
|
134
140
|
border-radius: 3px;
|
|
135
141
|
font-size: 85%;
|
|
136
142
|
padding: 2px 4px;
|
|
137
143
|
}
|
|
138
144
|
|
|
139
145
|
pre {
|
|
140
|
-
background-color: #23241f;
|
|
146
|
+
background-color: var(--zn-code-background, #23241f);
|
|
141
147
|
border-radius: 3px;
|
|
142
148
|
margin-block: 5px;
|
|
143
149
|
padding: 5px 10px;
|
|
144
|
-
color: #f8f8f2;
|
|
150
|
+
color: var(--zn-code-color, #f8f8f2);
|
|
145
151
|
overflow: auto;
|
|
146
152
|
}
|
|
147
153
|
|
|
@@ -176,7 +182,7 @@ li > ol, li > ul {
|
|
|
176
182
|
}
|
|
177
183
|
|
|
178
184
|
li[data-list=checked] > .ql-ui, li[data-list=unchecked] > .ql-ui {
|
|
179
|
-
color: #777;
|
|
185
|
+
color: var(--zn-content-block-meta-color, #777);
|
|
180
186
|
}
|
|
181
187
|
|
|
182
188
|
li {
|
|
@@ -207,7 +213,7 @@ li[data-list="unchecked"]::before {
|
|
|
207
213
|
|
|
208
214
|
li[data-list="checked"]::before,
|
|
209
215
|
li[data-list="unchecked"]::before {
|
|
210
|
-
color: #777;
|
|
216
|
+
color: var(--zn-content-block-meta-color, #777);
|
|
211
217
|
}
|
|
212
218
|
|
|
213
219
|
ol li::before,
|
|
@@ -17,6 +17,13 @@ describe('<zn-content-block>', () => {
|
|
|
17
17
|
expect(el).to.exist;
|
|
18
18
|
});
|
|
19
19
|
|
|
20
|
+
it('should only create the html preview frame when there is html', async () => {
|
|
21
|
+
const el = await fixture<LitElement>('<zn-content-block><div slot="text">plain</div></zn-content-block>');
|
|
22
|
+
await el.updateComplete;
|
|
23
|
+
|
|
24
|
+
expect(el.shadowRoot!.querySelector('iframe')).to.be.null;
|
|
25
|
+
});
|
|
26
|
+
|
|
20
27
|
it('should decode escaped source in the html body once', async () => {
|
|
21
28
|
const el = await fixture<LitElement>(
|
|
22
29
|
'<zn-content-block><div slot="html"><p>Test&nbsp;Format</p></div></zn-content-block>'
|
|
@@ -27,6 +34,25 @@ describe('<zn-content-block>', () => {
|
|
|
27
34
|
expect(iframe.srcdoc).to.contain('<p>Test Format</p>');
|
|
28
35
|
});
|
|
29
36
|
|
|
37
|
+
it('should read the text slot without forcing layout', async () => {
|
|
38
|
+
const descriptor = Object.getOwnPropertyDescriptor(HTMLElement.prototype, 'innerText')!;
|
|
39
|
+
let reads = 0;
|
|
40
|
+
Object.defineProperty(HTMLElement.prototype, 'innerText', {
|
|
41
|
+
...descriptor,
|
|
42
|
+
get() {
|
|
43
|
+
reads++;
|
|
44
|
+
return descriptor.get!.call(this);
|
|
45
|
+
}
|
|
46
|
+
});
|
|
47
|
+
try {
|
|
48
|
+
const content = await textSection('line one<br>\nline two');
|
|
49
|
+
expect(content.textContent).to.contain('line two');
|
|
50
|
+
} finally {
|
|
51
|
+
Object.defineProperty(HTMLElement.prototype, 'innerText', descriptor);
|
|
52
|
+
}
|
|
53
|
+
expect(reads).to.equal(0);
|
|
54
|
+
});
|
|
55
|
+
|
|
30
56
|
it('should render plain text in the text body as text', async () => {
|
|
31
57
|
const content = await textSection('1 < 2 && 3 > 2');
|
|
32
58
|
|
|
@@ -44,7 +44,7 @@ export default class ZnCopyButton extends ZincElement {
|
|
|
44
44
|
|
|
45
45
|
@property() src = '';
|
|
46
46
|
|
|
47
|
-
@property({type: Number, reflect: true}) size: number =
|
|
47
|
+
@property({type: Number, reflect: true}) size: number = 16;
|
|
48
48
|
|
|
49
49
|
/**
|
|
50
50
|
* An id that references an element in the same document from which data will be copied. If both this and `value` are
|
|
@@ -68,7 +68,7 @@ export default class ZnCopyButton extends ZincElement {
|
|
|
68
68
|
content=${copyLabel}>
|
|
69
69
|
<button class="copy-button__button" part="button" @click=${this.handleCopy}>
|
|
70
70
|
<slot part="copy-icon" name="copy-icon">
|
|
71
|
-
<zn-icon src="${this.src ? this.src : '
|
|
71
|
+
<zn-icon src="${this.src ? this.src : 'copy@lu'}" size="${this.size}"></zn-icon>
|
|
72
72
|
</slot>
|
|
73
73
|
<slot part="success-icon" name="success-icon" hidden>
|
|
74
74
|
<zn-icon src="check" size="${this.size}"></zn-icon>
|