@kubex/zinc 1.0.4 → 1.0.6
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/dist/custom-elements.json +1278 -191
- package/dist/vscode.html-custom-data.json +93 -16
- package/dist/web-types.json +235 -25
- package/dist/zn.d.ts +1313 -941
- package/dist/zn.min.css +1 -1
- package/dist/zn.min.js +2049 -931
- package/docs/_includes/default.njk +1 -0
- package/docs/assets/scripts/docs.js +4 -5
- package/docs/assets/scripts/search.js +0 -9
- package/docs/assets/styles/docs.css +3 -3
- package/docs/data/data-table.json +79 -0
- package/docs/data/products-table.json +36 -0
- package/docs/eleventy.config.cjs +3 -0
- package/docs/pages/components/data-select.md +10 -0
- package/docs/pages/components/data-table.md +84 -45
- package/docs/pages/components/dialog.md +1 -1
- package/docs/pages/components/editor.md +1 -3
- package/docs/pages/components/filter-wrapper.md +20 -0
- package/docs/pages/components/icon.md +2 -0
- package/docs/pages/components/item.md +2 -2
- package/docs/pages/components/menu-item.md +12 -3
- package/docs/pages/components/panel.md +17 -0
- package/docs/pages/components/progress-tile.md +17 -1
- package/docs/pages/components/settings-container.md +137 -0
- package/docs/pages/components/textarea.md +1 -1
- package/package.json +3 -1
- package/scss/_root.scss +26 -0
- package/scss/boot.scss +27 -1
- package/scss/mixins/index.scss +30 -1
- package/scss/shared/_base.scss +1 -1
- package/scss/shared/_button.scss +1 -1
- package/scss/shared/layout.scss +7 -0
- package/scss/themes/_dark.scss +5 -5
- package/scss/themes/_light.scss +6 -5
- package/scss/variables/index.scss +9 -0
- package/src/components/alert/alert.component.ts +1 -1
- package/src/components/alert/alert.scss +18 -4
- package/src/components/bulk-actions/bulk-actions.component.ts +152 -84
- package/src/components/bulk-actions/bulk-actions.scss +2 -0
- package/src/components/button/button.component.ts +6 -2
- package/src/components/button/button.scss +16 -1
- package/src/components/button-menu/button-menu.component.ts +23 -15
- package/src/components/button-menu/button-menu.scss +4 -4
- package/src/components/chart/chart.component.ts +14 -12
- package/src/components/checkbox/checkbox.component.ts +5 -1
- package/src/components/checkbox/checkbox.scss +1 -1
- package/src/components/chip/chip.component.ts +7 -3
- package/src/components/chip/chip.scss +9 -1
- package/src/components/collapsible/collapsible.component.ts +48 -2
- package/src/components/cols/cols.component.ts +7 -3
- package/src/components/cols/cols.scss +22 -14
- package/src/components/confirm/confirm.component.ts +1 -2
- package/src/components/content-block/content-block.component.ts +104 -14
- package/src/components/content-block/content-block.scss +8 -0
- package/src/components/data-select/data-select.component.ts +1 -1
- package/src/components/data-table/data-table.component.ts +394 -430
- package/src/components/data-table/data-table.scss +6 -1
- package/src/components/datepicker/datepicker.scss +1 -1
- package/src/components/dialog/dialog.component.ts +52 -33
- package/src/components/dialog/dialog.scss +15 -1
- package/src/components/dropdown/dropdown.component.ts +1 -1
- package/src/components/editor/editor.component.ts +196 -158
- package/src/components/editor/editor.scss +25 -5
- package/src/components/editor/modules/ai/index.ts +281 -0
- package/src/components/editor/modules/ai/panel/ai-panel.component.ts +102 -0
- package/src/components/editor/modules/ai/panel/ai-panel.scss +83 -0
- package/src/components/editor/modules/ai/tooltip/ai-tooltip.component.ts +30 -0
- package/src/components/editor/modules/ai/tooltip/ai-tooltip.scss +28 -0
- package/src/components/editor/modules/{attachment-module.ts → attachment/attachment.ts} +7 -7
- package/src/components/editor/modules/context-menu/context-menu-component.ts +115 -0
- package/src/components/editor/modules/context-menu/context-menu.scss +49 -0
- package/src/components/editor/modules/context-menu/context-menu.ts +296 -0
- package/src/components/editor/modules/context-menu/quick-action/index.ts +12 -0
- package/src/components/editor/modules/context-menu/quick-action/quick-action.component.ts +18 -0
- package/src/components/editor/modules/date-picker/date-picker.ts +77 -0
- package/src/components/editor/modules/dialog/dialog.component.ts +115 -0
- package/src/components/editor/modules/dialog/dialog.scss +43 -0
- package/src/components/editor/modules/dialog/dialog.ts +46 -0
- package/src/components/editor/modules/{drag-drop-module.ts → drag-drop/drag-drop.ts} +6 -6
- package/src/components/editor/modules/emoji/emoji.ts +106 -0
- package/src/components/editor/modules/emoji/headless/headless-emoji.component.ts +122 -0
- package/src/components/editor/modules/emoji/headless/headless-emoji.scss +52 -0
- package/src/components/editor/modules/emoji/headless/headless-emoji.ts +223 -0
- package/src/components/editor/modules/{image-resize-module/image-resize-module.ts → image-resize/image-resize.ts} +5 -5
- package/src/components/editor/modules/{time-tracking-module.ts → time-tracking/time-tracking.ts} +5 -5
- package/src/components/editor/modules/toolbar/tool/index.ts +12 -0
- package/src/components/editor/modules/toolbar/tool/tool.component.ts +30 -0
- package/src/components/editor/modules/toolbar/tool/tool.scss +5 -0
- package/src/components/editor/modules/toolbar/toolbar.component.ts +738 -0
- package/src/components/editor/modules/toolbar/toolbar.scss +98 -0
- package/src/components/editor/modules/toolbar/toolbar.ts +328 -0
- package/src/components/expanding-action/expanding-action.component.ts +2 -2
- package/src/components/expanding-action/expanding-action.scss +2 -2
- package/src/components/filter-wrapper/filter-wrapper.component.ts +91 -0
- package/src/components/filter-wrapper/filter-wrapper.scss +11 -0
- package/src/components/filter-wrapper/filter-wrapper.test.ts +10 -0
- package/src/components/filter-wrapper/index.ts +12 -0
- package/src/components/header/header.component.ts +1 -1
- package/src/components/header/header.scss +8 -1
- package/src/components/hover-container/hover-container.scss +39 -36
- package/src/components/icon/icon.component.ts +11 -5
- package/src/components/icon/icon.scss +15 -2
- package/src/components/inline-edit/inline-edit.component.ts +52 -6
- package/src/components/inline-edit/inline-edit.scss +15 -2
- package/src/components/input/input.scss +1 -1
- package/src/components/item/item.component.ts +30 -19
- package/src/components/item/item.scss +57 -23
- package/src/components/linked-select/linked-select.component.ts +5 -1
- package/src/components/menu/menu.component.ts +1 -0
- package/src/components/menu/menu.scss +1 -1
- package/src/components/menu-item/menu-item.component.ts +22 -4
- package/src/components/menu-item/menu-item.scss +54 -7
- package/src/components/navbar/navbar.component.ts +7 -1
- package/src/components/navbar/navbar.scss +26 -16
- package/src/components/option/option.component.ts +4 -1
- package/src/components/option/option.scss +9 -0
- package/src/components/page-nav/page-nav.component.ts +2 -2
- package/src/components/page-nav/page-nav.scss +4 -4
- package/src/components/panel/panel.component.ts +20 -9
- package/src/components/panel/panel.scss +5 -1
- package/src/components/popup/popup.component.ts +16 -2
- package/src/components/progress-tile/progress-tile.component.ts +10 -4
- package/src/components/progress-tile/progress-tile.scss +7 -4
- package/src/components/query-builder/query-builder.component.ts +1 -1
- package/src/components/radio/radio.scss +1 -1
- package/src/components/scroll-container/scroll-container.component.ts +56 -9
- package/src/components/scroll-container/scroll-container.scss +37 -2
- package/src/components/select/select.component.ts +3 -0
- package/src/components/select/select.scss +1 -1
- package/src/components/settings-container/index.ts +12 -0
- package/src/components/settings-container/settings-container.component.ts +226 -0
- package/src/components/settings-container/settings-container.scss +99 -0
- package/src/components/settings-container/settings-container.test.ts +10 -0
- package/src/components/skeleton/skeleton.scss +5 -4
- package/src/components/sp/sp.component.ts +2 -0
- package/src/components/sp/sp.scss +2 -0
- package/src/components/split-button/split-button.component.ts +24 -18
- package/src/components/split-pane/split-pane.component.ts +5 -5
- package/src/components/stat/stat.component.ts +5 -1
- package/src/components/stat/stat.scss +24 -1
- package/src/components/style/style.component.ts +25 -1
- package/src/components/tabs/tabs.component.ts +12 -1
- package/src/components/textarea/textarea.component.ts +3 -1
- package/src/components/textarea/textarea.scss +21 -2
- package/src/components/vertical-stepper/vertical-stepper.scss +1 -1
- package/src/internal/form.ts +3 -1
- package/src/internal/slot.ts +29 -3
- package/src/utilities/on.ts +7 -8
- package/src/utilities/query.ts +5 -1
- package/src/wc.scss +7 -0
- package/src/zinc.ts +5 -0
- package/src/components/editor/modules/dialog-module/dialog-module.component.ts +0 -289
- package/src/components/editor/modules/dialog-module/dialog-module.scss +0 -115
- package/src/components/editor/modules/dialog-module/dialog-module.ts +0 -99
- package/src/components/editor/modules/events/zn-show-canned-response-dialog.ts +0 -15
- package/src/components/editor/modules/menu-module/menu-module.component.ts +0 -149
- package/src/components/editor/modules/menu-module/menu-module.scss +0 -17
- package/src/components/editor/modules/menu-module/menu-module.ts +0 -203
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import {type CSSResultGroup, html, unsafeCSS} from 'lit';
|
|
1
|
+
import {type CSSResultGroup, html, unsafeCSS, PropertyValues} from 'lit';
|
|
2
2
|
import ZincElement from '../../internal/zinc-element';
|
|
3
|
+
import {property, query} from "lit/decorators.js";
|
|
3
4
|
|
|
4
5
|
import styles from './scroll-container.scss';
|
|
5
6
|
|
|
@@ -23,19 +24,65 @@ import styles from './scroll-container.scss';
|
|
|
23
24
|
export default class ZnScrollContainer extends ZincElement {
|
|
24
25
|
static styles: CSSResultGroup = unsafeCSS(styles);
|
|
25
26
|
|
|
26
|
-
|
|
27
|
-
super();
|
|
27
|
+
@property({attribute: 'start-scrolled', type: Boolean, reflect: true}) startScrolled: boolean = false;
|
|
28
28
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
29
|
+
@query('.scroll-container')
|
|
30
|
+
private container: HTMLElement;
|
|
31
|
+
|
|
32
|
+
@query('.scroll-footer')
|
|
33
|
+
private footer: HTMLElement;
|
|
34
|
+
|
|
35
|
+
protected firstUpdated(_changedProperties: PropertyValues) {
|
|
36
|
+
super.firstUpdated(_changedProperties);
|
|
37
|
+
if (this.startScrolled && this.container) {
|
|
38
|
+
setTimeout(this.scrollEnd.bind(this), 10);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
scrollEnd() {
|
|
43
|
+
this.container.scrollTop = this.container.scrollHeight;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
private _footerResizeObserver?: ResizeObserver;
|
|
47
|
+
|
|
48
|
+
connectedCallback() {
|
|
49
|
+
super.connectedCallback();
|
|
50
|
+
if (this.startScrolled) {
|
|
51
|
+
const observer = new MutationObserver(() => {
|
|
52
|
+
setTimeout(this.scrollEnd.bind(this), 100);
|
|
53
|
+
if (this.footer) {
|
|
54
|
+
// Initialize height immediately
|
|
55
|
+
this.style.setProperty('--zn-scroll-footer-height', `${this.footer.clientHeight}px`);
|
|
56
|
+
// Attach ResizeObserver to watch for size changes
|
|
57
|
+
this._footerResizeObserver = new ResizeObserver(() => {
|
|
58
|
+
this.style.setProperty('--zn-scroll-footer-height', `${this.footer?.clientHeight ?? 0}px`);
|
|
59
|
+
});
|
|
60
|
+
this._footerResizeObserver.observe(this.footer);
|
|
61
|
+
}
|
|
62
|
+
});
|
|
63
|
+
observer.observe(this, {childList: true, subtree: true});
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
disconnectedCallback() {
|
|
68
|
+
super.disconnectedCallback();
|
|
69
|
+
this._footerResizeObserver?.disconnect();
|
|
70
|
+
this._footerResizeObserver = undefined;
|
|
34
71
|
}
|
|
35
72
|
|
|
36
73
|
render() {
|
|
37
74
|
return html`
|
|
38
|
-
<
|
|
75
|
+
<div class="container">
|
|
76
|
+
<div class="scroll-header">
|
|
77
|
+
<slot name="header"></slot>
|
|
78
|
+
</div>
|
|
79
|
+
<div class="scroll-container">
|
|
80
|
+
<slot></slot>
|
|
81
|
+
</div>
|
|
82
|
+
<div class="scroll-footer">
|
|
83
|
+
<slot name="footer"></slot>
|
|
84
|
+
</div>
|
|
85
|
+
</div>
|
|
39
86
|
`;
|
|
40
87
|
}
|
|
41
88
|
}
|
|
@@ -1,6 +1,27 @@
|
|
|
1
1
|
@use "../../wc";
|
|
2
2
|
|
|
3
3
|
:host {
|
|
4
|
+
display: contents;
|
|
5
|
+
--zn-scroll-footer-height: 0px;
|
|
6
|
+
--zn-scroll-header-height: 0px;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
.container {
|
|
10
|
+
max-height: 100%;
|
|
11
|
+
max-width: 100%;
|
|
12
|
+
height: 100%;
|
|
13
|
+
width: 100%;
|
|
14
|
+
display: flex;
|
|
15
|
+
flex-direction: column;
|
|
16
|
+
position: relative;
|
|
17
|
+
overflow: hidden;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
:host([flex-end]) ::slotted(*) {
|
|
21
|
+
// margin-top: auto;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
.scroll-container {
|
|
4
25
|
@include wc.scrollbars;
|
|
5
26
|
container-type: inline-size;
|
|
6
27
|
display: flex;
|
|
@@ -10,8 +31,22 @@
|
|
|
10
31
|
max-width: 100%;
|
|
11
32
|
width: 100%;
|
|
12
33
|
overflow-y: auto;
|
|
34
|
+
flex-grow: 1;
|
|
35
|
+
margin: 0;
|
|
36
|
+
padding: 0 0 var(--zn-scroll-footer-height, 0px) 0;
|
|
13
37
|
}
|
|
14
38
|
|
|
15
|
-
|
|
16
|
-
|
|
39
|
+
.scroll-header {
|
|
40
|
+
display: contents;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
.scroll-footer {
|
|
44
|
+
padding: 0;
|
|
45
|
+
margin: 0;
|
|
46
|
+
|
|
47
|
+
position: absolute;
|
|
48
|
+
bottom: 0;
|
|
49
|
+
left: 0;
|
|
50
|
+
right: 0;
|
|
51
|
+
display: flex;
|
|
17
52
|
}
|
|
@@ -623,6 +623,8 @@ export default class ZnSelect extends ZincElement implements ZincFormControl {
|
|
|
623
623
|
|
|
624
624
|
// Update the value and display label
|
|
625
625
|
if (this.multiple) {
|
|
626
|
+
this.getAllOptions().filter(el => el.multiple !== true).forEach(el => el.multiple = true);
|
|
627
|
+
|
|
626
628
|
this.value = this.selectedOptions.map(el => el.value);
|
|
627
629
|
|
|
628
630
|
if (this.placeholder && this.value.length === 0) {
|
|
@@ -632,6 +634,7 @@ export default class ZnSelect extends ZincElement implements ZincFormControl {
|
|
|
632
634
|
this.displayLabel = this.localize.term('numOptionsSelected', this.selectedOptions.length);
|
|
633
635
|
}
|
|
634
636
|
} else {
|
|
637
|
+
this.getAllOptions().filter(el => el.multiple === true).forEach(el => el.multiple = false);
|
|
635
638
|
const selectedOption = this.selectedOptions[0];
|
|
636
639
|
this.value = selectedOption?.value ?? '';
|
|
637
640
|
this.displayLabel = selectedOption?.getTextLabel() ?? '';
|
|
@@ -38,7 +38,7 @@
|
|
|
38
38
|
font-family: var(--zn-input-font-family);
|
|
39
39
|
font-weight: var(--zn-input-font-weight);
|
|
40
40
|
letter-spacing: var(--zn-input-letter-spacing);
|
|
41
|
-
box-shadow: var(--zn-shadow-small);
|
|
41
|
+
box-shadow: var(--zn-shadow-x-small);
|
|
42
42
|
vertical-align: middle;
|
|
43
43
|
overflow: hidden;
|
|
44
44
|
cursor: pointer;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import ZnSettingsContainer from './settings-container.component';
|
|
2
|
+
|
|
3
|
+
export * from './settings-container.component';
|
|
4
|
+
export default ZnSettingsContainer;
|
|
5
|
+
|
|
6
|
+
ZnSettingsContainer.define('zn-settings-container');
|
|
7
|
+
|
|
8
|
+
declare global {
|
|
9
|
+
interface HTMLElementTagNameMap {
|
|
10
|
+
'zn-settings-container': ZnSettingsContainer;
|
|
11
|
+
}
|
|
12
|
+
}
|
|
@@ -0,0 +1,226 @@
|
|
|
1
|
+
import {classMap} from "lit/directives/class-map.js";
|
|
2
|
+
import {type CSSResultGroup, html, unsafeCSS} from 'lit';
|
|
3
|
+
import {property, state} from "lit/decorators.js";
|
|
4
|
+
import {Store} from "../../internal/storage";
|
|
5
|
+
import {type ZnChangeEvent} from "../../events/zn-change";
|
|
6
|
+
import ZincElement from '../../internal/zinc-element';
|
|
7
|
+
import type ZnCheckbox from "../checkbox";
|
|
8
|
+
|
|
9
|
+
import styles from './settings-container.scss';
|
|
10
|
+
import {deepQuerySelectorAll} from "../../utilities/query";
|
|
11
|
+
|
|
12
|
+
interface SettingsContainerFilter {
|
|
13
|
+
attribute: string;
|
|
14
|
+
checked: boolean;
|
|
15
|
+
label: string;
|
|
16
|
+
itemSelector?: string;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* @summary Short summary of the component's intended use.
|
|
21
|
+
* @documentation https://zinc.style/components/settings-container
|
|
22
|
+
* @status experimental
|
|
23
|
+
* @since 1.0
|
|
24
|
+
*
|
|
25
|
+
* @dependency zn-example
|
|
26
|
+
*
|
|
27
|
+
* @event zn-event-name - Emitted as an example.
|
|
28
|
+
*
|
|
29
|
+
* @slot - The default slot.
|
|
30
|
+
* @slot example - An example slot.
|
|
31
|
+
*
|
|
32
|
+
* @csspart base - The component's base wrapper.
|
|
33
|
+
*
|
|
34
|
+
* @cssproperty --example - An example CSS custom property.
|
|
35
|
+
*/
|
|
36
|
+
export default class ZnSettingsContainer extends ZincElement {
|
|
37
|
+
static styles: CSSResultGroup = unsafeCSS(styles);
|
|
38
|
+
|
|
39
|
+
@state() filters: SettingsContainerFilter[] = [];
|
|
40
|
+
|
|
41
|
+
@property() position: 'top-end' | 'top-start' | 'bottom-end' | 'bottom-start' = 'bottom-start';
|
|
42
|
+
|
|
43
|
+
@property({attribute: 'store-key'}) storeKey: string;
|
|
44
|
+
@property({attribute: 'no-scroll'}) noScroll: boolean;
|
|
45
|
+
|
|
46
|
+
private _mutationObserver: MutationObserver | null = null;
|
|
47
|
+
|
|
48
|
+
private _updateFiltersScheduled = false;
|
|
49
|
+
|
|
50
|
+
private _store: Store;
|
|
51
|
+
|
|
52
|
+
private _hiddenElements: Set<Element> = new Set();
|
|
53
|
+
|
|
54
|
+
connectedCallback() {
|
|
55
|
+
super.connectedCallback();
|
|
56
|
+
|
|
57
|
+
this._store = new Store(window.sessionStorage, this.storeKey);
|
|
58
|
+
|
|
59
|
+
this.recomputeFiltersFromSlot();
|
|
60
|
+
this.updateFilters();
|
|
61
|
+
|
|
62
|
+
// Load saved filter states
|
|
63
|
+
if (this.storeKey) {
|
|
64
|
+
const savedFilters = this._store.get('filters');
|
|
65
|
+
if (savedFilters) {
|
|
66
|
+
const parsedFilters = JSON.parse(savedFilters) as Record<string, boolean>;
|
|
67
|
+
this.filters = this.filters.map(filter => ({
|
|
68
|
+
...filter,
|
|
69
|
+
checked: Object.prototype.hasOwnProperty.call(parsedFilters, filter.attribute) ? parsedFilters[filter.attribute] : filter.checked
|
|
70
|
+
}));
|
|
71
|
+
this.updateFilters();
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
this._mutationObserver = new MutationObserver(mutations => {
|
|
76
|
+
for (const mutation of mutations) {
|
|
77
|
+
if (mutation.type === 'attributes' && mutation.attributeName === 'hidden') {
|
|
78
|
+
continue;
|
|
79
|
+
}
|
|
80
|
+
this.scheduleUpdateFilters();
|
|
81
|
+
break;
|
|
82
|
+
}
|
|
83
|
+
});
|
|
84
|
+
this._mutationObserver.observe(this, {childList: true, subtree: true, attributes: true});
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
disconnectedCallback() {
|
|
88
|
+
super.disconnectedCallback();
|
|
89
|
+
if (this._mutationObserver) {
|
|
90
|
+
this._mutationObserver.disconnect();
|
|
91
|
+
this._mutationObserver = null;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
// Debounced scheduling to avoid excessive updates on rapid DOM mutations
|
|
96
|
+
private scheduleUpdateFilters() {
|
|
97
|
+
if (this._updateFiltersScheduled) return;
|
|
98
|
+
this._updateFiltersScheduled = true;
|
|
99
|
+
Promise.resolve().then(() => {
|
|
100
|
+
this._updateFiltersScheduled = false;
|
|
101
|
+
this.updateFilters();
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
private handleContentSlotChange = () => {
|
|
106
|
+
this.updateFilters();
|
|
107
|
+
};
|
|
108
|
+
|
|
109
|
+
private handleFiltersSlotChange = () => {
|
|
110
|
+
this.recomputeFiltersFromSlot();
|
|
111
|
+
this.updateFilters();
|
|
112
|
+
};
|
|
113
|
+
|
|
114
|
+
private recomputeFiltersFromSlot() {
|
|
115
|
+
const existingChecked = new Map(this.filters.map(f => [f.attribute, f.checked]));
|
|
116
|
+
const slotFilters = this.querySelectorAll('[slot="filter"]');
|
|
117
|
+
const nextFilters: SettingsContainerFilter[] = [];
|
|
118
|
+
slotFilters.forEach(filter => {
|
|
119
|
+
const attribute = filter.getAttribute('attribute');
|
|
120
|
+
if (!attribute) return;
|
|
121
|
+
const defaultChecked = filter.getAttribute('default') === 'true';
|
|
122
|
+
const checked = existingChecked.has(attribute) ? !!existingChecked.get(attribute) : defaultChecked;
|
|
123
|
+
const label = filter.textContent || 'Unnamed Filter';
|
|
124
|
+
const itemSelector = filter.getAttribute('item-selector') || '*';
|
|
125
|
+
nextFilters.push({attribute, checked, label, itemSelector});
|
|
126
|
+
});
|
|
127
|
+
this.filters = nextFilters;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
updateFilters() {
|
|
131
|
+
// reset all items
|
|
132
|
+
this._hiddenElements.forEach(el => el.removeAttribute('hidden'));
|
|
133
|
+
|
|
134
|
+
// apply filters
|
|
135
|
+
this.filters.forEach(filter => {
|
|
136
|
+
let items;
|
|
137
|
+
const attrAppend = filter.attribute === "*" ? `` : `[${filter.attribute}]`;
|
|
138
|
+
if (filter.itemSelector && filter.itemSelector.startsWith('>')) {
|
|
139
|
+
items = deepQuerySelectorAll(filter.itemSelector.substring(1) + attrAppend, this, "");
|
|
140
|
+
} else {
|
|
141
|
+
items = this.querySelectorAll(filter.itemSelector + attrAppend);
|
|
142
|
+
}
|
|
143
|
+
items.forEach(item => {
|
|
144
|
+
if (filter.checked) {
|
|
145
|
+
item.removeAttribute('hidden');
|
|
146
|
+
} else {
|
|
147
|
+
item.setAttribute('hidden', 'true');
|
|
148
|
+
this._hiddenElements.add(item);
|
|
149
|
+
}
|
|
150
|
+
});
|
|
151
|
+
});
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
updateFilter(e: ZnChangeEvent) {
|
|
155
|
+
const attribute = (e.target as ZnCheckbox).getAttribute('data-attribute');
|
|
156
|
+
const checked = (e.target as ZnCheckbox).isChecked
|
|
157
|
+
|
|
158
|
+
this.filters = this.filters.map(filter => {
|
|
159
|
+
if (filter.attribute === attribute) {
|
|
160
|
+
return {...filter, checked};
|
|
161
|
+
}
|
|
162
|
+
return filter;
|
|
163
|
+
});
|
|
164
|
+
|
|
165
|
+
// Save filter states
|
|
166
|
+
if (this.storeKey) {
|
|
167
|
+
const filterStates = this.filters.reduce((acc: Record<string, boolean>, filter) => {
|
|
168
|
+
acc[filter.attribute] = filter.checked;
|
|
169
|
+
return acc;
|
|
170
|
+
}, {} satisfies Record<string, boolean>);
|
|
171
|
+
this._store.set('filters', JSON.stringify(filterStates));
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
this.updateFilters();
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
render() {
|
|
178
|
+
let placement = 'top-start';
|
|
179
|
+
|
|
180
|
+
switch (this.position) {
|
|
181
|
+
case 'top-end':
|
|
182
|
+
placement = 'bottom-end';
|
|
183
|
+
break;
|
|
184
|
+
case 'top-start':
|
|
185
|
+
placement = 'bottom-start';
|
|
186
|
+
break;
|
|
187
|
+
case 'bottom-end':
|
|
188
|
+
placement = 'top-end';
|
|
189
|
+
break;
|
|
190
|
+
case 'bottom-start':
|
|
191
|
+
placement = 'top-start';
|
|
192
|
+
break;
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
return html`
|
|
196
|
+
<div class="${classMap({
|
|
197
|
+
'container': true,
|
|
198
|
+
'container--scroll': !this.noScroll,
|
|
199
|
+
})}">
|
|
200
|
+
<div class="scroll-content">
|
|
201
|
+
<slot @slotchange="${this.handleContentSlotChange}"></slot>
|
|
202
|
+
</div>
|
|
203
|
+
<zn-dropdown placement="${placement}" class="${classMap({
|
|
204
|
+
'setting-container__dropdown': true,
|
|
205
|
+
'setting-container__dropdown--top-end': this.position === 'top-end',
|
|
206
|
+
'setting-container__dropdown--top-start': this.position === 'top-start',
|
|
207
|
+
'setting-container__dropdown--bottom-end': this.position === 'bottom-end',
|
|
208
|
+
'setting-container__dropdown--bottom-start': this.position === 'bottom-start',
|
|
209
|
+
})}">
|
|
210
|
+
<zn-icon class="setting-container__toggle-button" slot="trigger" size="24" src="settings" round></zn-icon>
|
|
211
|
+
<div class="settings-container__dropdown-content">
|
|
212
|
+
<slot name="filter" style="display: none;" @slotchange="${this.handleFiltersSlotChange}"></slot>
|
|
213
|
+
${this.filters.map(filter => html`
|
|
214
|
+
<zn-checkbox class="settings-container__dropdown-item"
|
|
215
|
+
data-attribute="${filter.attribute}"
|
|
216
|
+
?checked="${filter.checked}"
|
|
217
|
+
@zn-change="${this.updateFilter}">
|
|
218
|
+
${filter.label}
|
|
219
|
+
</zn-checkbox>
|
|
220
|
+
`)}
|
|
221
|
+
</div>
|
|
222
|
+
</zn-dropdown>
|
|
223
|
+
</div>
|
|
224
|
+
`;
|
|
225
|
+
}
|
|
226
|
+
}
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
@use "../../wc";
|
|
2
|
+
|
|
3
|
+
:host {
|
|
4
|
+
display: contents;
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
.container {
|
|
8
|
+
padding-bottom: 30px;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
.container--scroll {
|
|
12
|
+
height: 100%;
|
|
13
|
+
width: 100%;
|
|
14
|
+
overflow: hidden;
|
|
15
|
+
position: relative;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
.container--scroll .scroll-content {
|
|
19
|
+
height: 100%;
|
|
20
|
+
width: 100%;
|
|
21
|
+
overflow: auto;
|
|
22
|
+
box-sizing: border-box;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
.setting-container__dropdown {
|
|
26
|
+
z-index: 10;
|
|
27
|
+
position: absolute;
|
|
28
|
+
border-radius: 50%;
|
|
29
|
+
width: 32px;
|
|
30
|
+
height: 32px;
|
|
31
|
+
padding: 4px;
|
|
32
|
+
background: rgba(var(--zn-panel, 0.8));
|
|
33
|
+
box-shadow: var(--zn-shadow-small);
|
|
34
|
+
transition: bottom 0.2s ease;
|
|
35
|
+
opacity: 0.7;
|
|
36
|
+
transition-duration: 0.3s;
|
|
37
|
+
transition-property: opacity;
|
|
38
|
+
|
|
39
|
+
&:hover {
|
|
40
|
+
background: rgba(var(--zn-panel, 1));
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
&--top-end {
|
|
44
|
+
top: var(--zn-spacing-medium);
|
|
45
|
+
right: var(--zn-spacing-medium);
|
|
46
|
+
bottom: auto;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
&--top-start {
|
|
50
|
+
top: var(--zn-spacing-medium);
|
|
51
|
+
right: auto;
|
|
52
|
+
left: var(--zn-spacing-medium);
|
|
53
|
+
bottom: auto;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
&--bottom-end {
|
|
57
|
+
bottom: calc(var(--zn-spacing-medium) + var(--zn-scroll-footer-height, 0px));
|
|
58
|
+
right: var(--zn-spacing-medium);
|
|
59
|
+
top: auto;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
&--bottom-start {
|
|
63
|
+
bottom: calc(var(--zn-spacing-medium) + var(--zn-scroll-footer-height, 0px));
|
|
64
|
+
left: var(--zn-spacing-medium);
|
|
65
|
+
top: auto;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
.setting-container__dropdown[open], .setting-container__dropdown:hover {
|
|
70
|
+
opacity: 1;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
.setting-container__dropdown[open] .setting-container__toggle-button::part(icon), .setting-container__toggle-button:hover::part(icon) {
|
|
74
|
+
color: rgb(var(--zn-primary));
|
|
75
|
+
cursor: pointer;
|
|
76
|
+
transition-duration: 0.9s;
|
|
77
|
+
transition-property: rotate, color;
|
|
78
|
+
rotate: 380deg;
|
|
79
|
+
transition-timing-function: ease-in-out;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
zn-button {
|
|
83
|
+
border-radius: var(--zn-border-radius-medium);
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
.settings-container__dropdown-content {
|
|
87
|
+
display: flex;
|
|
88
|
+
flex-direction: column;
|
|
89
|
+
gap: var(--zn-spacing-large);
|
|
90
|
+
background-color: rgb(var(--zn-panel));
|
|
91
|
+
padding: var(--zn-spacing-large);
|
|
92
|
+
box-shadow: var(--zn-shadow-small);
|
|
93
|
+
border-radius: var(--zn-border-radius-medium);
|
|
94
|
+
max-width: var(--zn-size-mpanel);
|
|
95
|
+
width: fit-content;
|
|
96
|
+
z-index: 20;
|
|
97
|
+
border: 1px solid rgb(var(--zn-border-color));
|
|
98
|
+
margin-bottom: 10px;
|
|
99
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import '../../../dist/zn.min.js';
|
|
2
|
+
import { expect, fixture, html } from '@open-wc/testing';
|
|
3
|
+
|
|
4
|
+
describe('<zn-settings-container>', () => {
|
|
5
|
+
it('should render a component', async () => {
|
|
6
|
+
const el = await fixture(html` <zn-settings-container></zn-settings-container> `);
|
|
7
|
+
|
|
8
|
+
expect(el).to.exist;
|
|
9
|
+
});
|
|
10
|
+
});
|
|
@@ -9,19 +9,20 @@
|
|
|
9
9
|
height: var(--skeleton-height);
|
|
10
10
|
width: var(--skeleton-width);
|
|
11
11
|
border-radius: var(--skeleton-border-radius);
|
|
12
|
+
background-color: lightgrey;
|
|
12
13
|
|
|
13
14
|
@media (prefers-reduced-motion: reduce) {
|
|
14
15
|
background-repeat: no-repeat;
|
|
15
|
-
background-color:
|
|
16
|
+
background-color: lightgrey;
|
|
16
17
|
}
|
|
17
18
|
|
|
18
19
|
@media (prefers-reduced-motion: no-preference) {
|
|
19
20
|
background-repeat: no-repeat;
|
|
20
21
|
background-image: linear-gradient(
|
|
21
22
|
90deg,
|
|
22
|
-
rgba(
|
|
23
|
-
rgba(
|
|
24
|
-
rgba(
|
|
23
|
+
rgba(255, 255, 255, 0) 0%,
|
|
24
|
+
rgba(255, 255, 255, 0.8) 50%,
|
|
25
|
+
rgba(255, 255, 255, 0) 100%
|
|
25
26
|
);
|
|
26
27
|
background-size: 200% 100%;
|
|
27
28
|
background-position: -150% 0;
|
|
@@ -51,6 +51,7 @@ export default class ZnSp extends ZincElement {
|
|
|
51
51
|
@property({attribute: 'flush-l', type: Boolean, reflect: true}) flushL: boolean = false;
|
|
52
52
|
@property({attribute: 'flush-r', type: Boolean, reflect: true}) flushR: boolean = false;
|
|
53
53
|
@property({attribute: 'width-container', type: Boolean, reflect: true}) widthContainer: boolean = false;
|
|
54
|
+
@property({attribute: 'form-container', type: Boolean, reflect: true}) formContainer: boolean = false;
|
|
54
55
|
|
|
55
56
|
connectedCallback() {
|
|
56
57
|
if (this.gap) {
|
|
@@ -79,6 +80,7 @@ export default class ZnSp extends ZincElement {
|
|
|
79
80
|
'sp--flush-l': this.flushL,
|
|
80
81
|
'sp--flush-r': this.flushR,
|
|
81
82
|
'width-container': this.widthContainer,
|
|
83
|
+
'form-container': this.formContainer,
|
|
82
84
|
})}">
|
|
83
85
|
<slot></slot>
|
|
84
86
|
</div>`;
|
|
@@ -10,12 +10,14 @@
|
|
|
10
10
|
}
|
|
11
11
|
|
|
12
12
|
.sp {
|
|
13
|
+
position: relative;
|
|
13
14
|
display: flex;
|
|
14
15
|
flex-direction: column;
|
|
15
16
|
flex-grow: 0;
|
|
16
17
|
padding: var(--zn-sp-padding);
|
|
17
18
|
gap: var(--zn-sp-gap);
|
|
18
19
|
width: 100%;
|
|
20
|
+
height: 100%;
|
|
19
21
|
//max-width: var(--zn-container-hd); //don't worry about max width just yet
|
|
20
22
|
margin: 0 auto;
|
|
21
23
|
|
|
@@ -3,8 +3,8 @@ import {defaultValue} from "../../internal/default-value";
|
|
|
3
3
|
import {FormControlController, validValidityState} from "../../internal/form";
|
|
4
4
|
import {ifDefined} from "lit/directives/if-defined.js";
|
|
5
5
|
import {property, query} from 'lit/decorators.js';
|
|
6
|
-
import type {ZincFormControl} from '../../internal/zinc-element';
|
|
7
6
|
import ZincElement from '../../internal/zinc-element';
|
|
7
|
+
import type {ZincFormControl} from '../../internal/zinc-element';
|
|
8
8
|
import type {ZnMenuSelectEvent} from "../../events/zn-menu-select";
|
|
9
9
|
import type ZnButton from "../button";
|
|
10
10
|
import type ZnDropdown from "../dropdown";
|
|
@@ -51,14 +51,12 @@ export default class ZnSplitButton extends ZincElement implements ZincFormContro
|
|
|
51
51
|
|
|
52
52
|
connectedCallback() {
|
|
53
53
|
super.connectedCallback();
|
|
54
|
-
this.addEventListener('click', this.handleClick)
|
|
55
54
|
this.addEventListener('zn-menu-select', this.handleMenuItemClick);
|
|
56
55
|
this.defaultValue = this.value;
|
|
57
56
|
}
|
|
58
57
|
|
|
59
58
|
disconnectedCallback() {
|
|
60
59
|
super.disconnectedCallback();
|
|
61
|
-
this.removeEventListener('click', this.handleClick);
|
|
62
60
|
this.removeEventListener('zn-menu-select', this.handleMenuItemClick);
|
|
63
61
|
}
|
|
64
62
|
|
|
@@ -73,10 +71,6 @@ export default class ZnSplitButton extends ZincElement implements ZincFormContro
|
|
|
73
71
|
}
|
|
74
72
|
}
|
|
75
73
|
|
|
76
|
-
public handleClick(e: MouseEvent) {
|
|
77
|
-
e.stopPropagation();
|
|
78
|
-
}
|
|
79
|
-
|
|
80
74
|
public handleTriggerClick() {
|
|
81
75
|
this.value = this.defaultValue;
|
|
82
76
|
|
|
@@ -87,17 +81,8 @@ export default class ZnSplitButton extends ZincElement implements ZincFormContro
|
|
|
87
81
|
|
|
88
82
|
render() {
|
|
89
83
|
return html`
|
|
90
|
-
<zn-dropdown placement="bottom-
|
|
91
|
-
|
|
92
|
-
<zn-button-group>
|
|
93
|
-
<zn-button id="trigger-btn"
|
|
94
|
-
href=${ifDefined(this.href)}
|
|
95
|
-
@click=${this.handleTriggerClick}>
|
|
96
|
-
${this.caption}
|
|
97
|
-
</zn-button>
|
|
98
|
-
<zn-button icon="keyboard_arrow_down"></zn-button>
|
|
99
|
-
</zn-button-group>
|
|
100
|
-
</div>
|
|
84
|
+
<zn-dropdown placement="bottom-end">
|
|
85
|
+
${this.renderTriggerSlot()}
|
|
101
86
|
<div>
|
|
102
87
|
<slot name="menu"></slot>
|
|
103
88
|
</div>
|
|
@@ -105,6 +90,27 @@ export default class ZnSplitButton extends ZincElement implements ZincFormContro
|
|
|
105
90
|
`;
|
|
106
91
|
}
|
|
107
92
|
|
|
93
|
+
private renderTriggerSlot() {
|
|
94
|
+
const hasTriggerSlot = !!this.querySelector('[slot="trigger"]');
|
|
95
|
+
if (hasTriggerSlot) {
|
|
96
|
+
return html`
|
|
97
|
+
<slot name="trigger" slot="trigger"></slot>`;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
return html`
|
|
101
|
+
<div slot="trigger">
|
|
102
|
+
<zn-button-group>
|
|
103
|
+
<zn-button id="trigger-btn"
|
|
104
|
+
href=${ifDefined(this.href)}
|
|
105
|
+
@click=${this.handleTriggerClick}>
|
|
106
|
+
${this.caption}
|
|
107
|
+
</zn-button>
|
|
108
|
+
<zn-button icon="keyboard_arrow_down"></zn-button>
|
|
109
|
+
</zn-button-group>
|
|
110
|
+
</div>
|
|
111
|
+
`;
|
|
112
|
+
}
|
|
113
|
+
|
|
108
114
|
checkValidity(): boolean {
|
|
109
115
|
if (this._isButton() && this.button) {
|
|
110
116
|
return this.button.checkValidity();
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import {eventOptions, property} from 'lit/decorators.js';
|
|
2
1
|
import {type CSSResultGroup, html, unsafeCSS} from 'lit';
|
|
2
|
+
import {eventOptions, property} from 'lit/decorators.js';
|
|
3
|
+
import {on} from "../../utilities/on";
|
|
4
|
+
import {Store} from "../../internal/storage";
|
|
3
5
|
import ZincElement from '../../internal/zinc-element';
|
|
4
6
|
|
|
5
7
|
import styles from './split-pane.scss';
|
|
6
|
-
import {Store} from "../../internal/storage";
|
|
7
|
-
import {on} from "../../utilities/on";
|
|
8
8
|
|
|
9
9
|
/**
|
|
10
10
|
* @summary Short summary of the component's intended use.
|
|
@@ -64,7 +64,7 @@ export default class ZnSplitPane extends ZincElement {
|
|
|
64
64
|
on(this, 'click', '[split-pane-focus]', (e: Event & { selectedTarget: EventTarget }) => {
|
|
65
65
|
e.preventDefault();
|
|
66
66
|
e.stopPropagation();
|
|
67
|
-
this._setFocusPane(parseInt((e.selectedTarget as HTMLElement).getAttribute('split-pane-focus')
|
|
67
|
+
this._setFocusPane(parseInt((e.selectedTarget as HTMLElement).getAttribute('split-pane-focus')!));
|
|
68
68
|
});
|
|
69
69
|
}
|
|
70
70
|
|
|
@@ -160,7 +160,7 @@ export default class ZnSplitPane extends ZincElement {
|
|
|
160
160
|
_setFocusPane(idx: number) {
|
|
161
161
|
this._focusPane = idx;
|
|
162
162
|
this.querySelectorAll('ul#split-nav li').forEach((el) => {
|
|
163
|
-
el.classList.toggle('active', parseInt(el.getAttribute('idx')
|
|
163
|
+
el.classList.toggle('active', parseInt(el.getAttribute('idx')!) == idx);
|
|
164
164
|
});
|
|
165
165
|
}
|
|
166
166
|
|