@kubex/zinc 1.0.25 → 1.0.99
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/.claude/project.md +556 -0
- package/.github/workflows/js_build_and_deploy.yaml +9 -10
- package/dist/custom-elements.json +13575 -8856
- package/dist/vscode.html-custom-data.json +583 -48
- package/dist/web-types.json +1441 -181
- package/dist/zn.d.ts +1645 -660
- package/dist/zn.min.css +1 -1
- package/dist/zn.min.js +1412 -893
- package/docs/_utilities/code-previews.cjs +10 -1
- package/docs/assets/scripts/docs.js +42 -18
- package/docs/data/data-table.json +229 -66
- package/docs/data/empty.json +6 -0
- package/docs/data/products-table.json +41 -193
- package/docs/pages/components/action-bar.md +121 -6
- package/docs/pages/components/alert.md +118 -15
- package/docs/pages/components/animated-button.md +299 -0
- package/docs/pages/components/audio-select.md +534 -0
- package/docs/pages/components/bulk-actions.md +79 -5
- package/docs/pages/components/button-group.md +235 -27
- package/docs/pages/components/button.md +139 -1
- package/docs/pages/components/chart.md +365 -9
- package/docs/pages/components/checkbox.md +387 -58
- package/docs/pages/components/chip.md +253 -33
- package/docs/pages/components/collapsible.md +393 -46
- package/docs/pages/components/cols.md +152 -30
- package/docs/pages/components/confirm.md +182 -16
- package/docs/pages/components/copy-button.md +169 -6
- package/docs/pages/components/data-select.md +194 -15
- package/docs/pages/components/data-table-filter.md +96 -5
- package/docs/pages/components/data-table-search.md +451 -0
- package/docs/pages/components/data-table-sort.md +66 -5
- package/docs/pages/components/data-table.md +727 -66
- package/docs/pages/components/datepicker.md +402 -7
- package/docs/pages/components/defined-label.md +120 -5
- package/docs/pages/components/dialog.md +339 -59
- package/docs/pages/components/dropdown.md +366 -11
- package/docs/pages/components/editor.md +604 -7
- package/docs/pages/components/empty-state.md +315 -16
- package/docs/pages/components/expanding-action.md +212 -28
- package/docs/pages/components/file.md +421 -12
- package/docs/pages/components/filter-container.md +158 -5
- package/docs/pages/components/filter-wrapper.md +167 -6
- package/docs/pages/components/form-group.md +383 -6
- package/docs/pages/components/hover-container.md +237 -6
- package/docs/pages/components/icon-picker.md +121 -0
- package/docs/pages/components/icon.md +454 -48
- package/docs/pages/components/inline-edit.md +787 -19
- package/docs/pages/components/input-group.md +207 -13
- package/docs/pages/components/input.md +194 -0
- package/docs/pages/components/item.md +18 -0
- package/docs/pages/components/key-container.md +115 -0
- package/docs/pages/components/key.md +101 -0
- package/docs/pages/components/menu.md +512 -6
- package/docs/pages/components/note.md +239 -36
- package/docs/pages/components/opt-group.md +107 -0
- package/docs/pages/components/pagination.md +332 -6
- package/docs/pages/components/pane.md +222 -6
- package/docs/pages/components/panel.md +213 -26
- package/docs/pages/components/popup.md +1354 -6
- package/docs/pages/components/priority-list.md +233 -0
- package/docs/pages/components/progress-bar.md +387 -6
- package/docs/pages/components/radio-group.md +242 -5
- package/docs/pages/components/radio.md +474 -6
- package/docs/pages/components/rating.md +331 -7
- package/docs/pages/components/reveal.md +524 -6
- package/docs/pages/components/scroll-container.md +552 -6
- package/docs/pages/components/select.md +762 -160
- package/docs/pages/components/skeleton.md +473 -30
- package/docs/pages/components/slideout.md +261 -5
- package/docs/pages/components/sp.md +99 -41
- package/docs/pages/components/split-button.md +347 -9
- package/docs/pages/components/split-pane.md +445 -6
- package/docs/pages/components/stat.md +549 -9
- package/docs/pages/components/status-indicator.md +230 -1
- package/docs/pages/components/stepper.md +563 -6
- package/docs/pages/components/tabs.md +439 -13
- package/docs/pages/components/textarea.md +415 -17
- package/docs/pages/components/tile.md +385 -26
- package/docs/pages/components/toggle.md +424 -6
- package/docs/pages/components/tooltip.md +367 -0
- package/docs/pages/components/translation-group.md +210 -0
- package/docs/pages/components/translations.md +319 -19
- package/docs/pages/components/vertical-stepper.md +401 -8
- package/docs/pages/components/well.md +300 -3
- package/docs/pages/getting-started/form-controls.md +162 -0
- package/docs/pages/index.md +116 -15
- package/package.json +5 -6
- package/scss/_global-spacing.scss +4 -0
- package/scss/_root.scss +2 -2
- package/scss/boot.scss +19 -0
- package/scss/shared/layout.scss +5 -0
- package/scss/themes/_light.scss +3 -3
- package/src/components/alert/alert.scss +1 -0
- package/src/components/animated-button/README.md +306 -0
- package/src/components/animated-button/animated-button.component.ts +229 -0
- package/src/components/animated-button/animated-button.scss +228 -0
- package/src/components/animated-button/animated-button.test.ts +143 -0
- package/src/components/animated-button/index.ts +12 -0
- package/src/components/button/button.component.ts +5 -0
- package/src/components/button-group/button-group.component.ts +25 -13
- package/src/components/button-group/button-group.scss +6 -0
- package/src/components/checkbox/checkbox.component.ts +4 -0
- package/src/components/checkbox/checkbox.scss +7 -4
- package/src/components/checkbox-group/checkbox-group.scss +7 -0
- package/src/components/chip/chip.component.ts +7 -2
- package/src/components/chip/chip.scss +16 -2
- package/src/components/collapsible/collapsible.component.ts +27 -20
- package/src/components/cols/cols.component.ts +14 -2
- package/src/components/cols/cols.scss +6 -12
- package/src/components/confirm/confirm.component.ts +7 -0
- package/src/components/copy-button/copy-button.component.ts +12 -11
- package/src/components/data-select/data-select.component.ts +215 -44
- package/src/components/data-select/data-select.scss +66 -6
- package/src/components/data-select/providers/currency-data-provider.ts +20 -6
- package/src/components/data-select/providers/provider.ts +1 -0
- package/src/components/data-select/providers/us-state-data-provider.ts +68 -0
- package/src/components/data-table/data-table.component.ts +81 -22
- package/src/components/data-table-search/data-table-search.component.ts +184 -0
- package/src/components/data-table-search/data-table-search.scss +17 -0
- package/src/components/data-table-search/data-table-search.test.ts +11 -0
- package/src/components/data-table-search/index.ts +12 -0
- package/src/components/datepicker/datepicker.component.ts +347 -13
- package/src/components/dialog/dialog.component.ts +1 -1
- package/src/components/empty-state/empty-state.scss +6 -1
- package/src/components/header/header.scss +3 -3
- package/src/components/icon/icon.component.ts +23 -1
- package/src/components/icon/icon.scss +23 -0
- package/src/components/icon-picker/brand-icons.ts +24 -0
- package/src/components/icon-picker/icon-picker.component.ts +407 -0
- package/src/components/icon-picker/icon-picker.scss +205 -0
- package/src/components/icon-picker/index.ts +12 -0
- package/src/components/icon-picker/line-icons.ts +612 -0
- package/src/components/icon-picker/material-icons.ts +14543 -0
- package/src/components/inline-edit/inline-edit.component.ts +190 -46
- package/src/components/inline-edit/inline-edit.scss +29 -0
- package/src/components/inline-edit/inline-edit.test.ts +314 -1
- package/src/components/input/input.component.ts +324 -5
- package/src/components/input/input.scss +87 -0
- package/src/components/input-group/input-group.component.ts +28 -7
- package/src/components/input-group/input-group.scss +48 -10
- package/src/components/item/item.component.ts +24 -3
- package/src/components/item/item.scss +18 -0
- package/src/components/key/index.ts +12 -0
- package/src/components/key/key.component.ts +47 -0
- package/src/components/key/key.scss +38 -0
- package/src/components/key-container/index.ts +12 -0
- package/src/components/key-container/key-container.component.ts +142 -0
- package/src/components/key-container/key-container.scss +33 -0
- package/src/components/menu-item/menu-item.component.ts +20 -0
- package/src/components/menu-item/menu-item.scss +69 -2
- package/src/components/navbar/navbar.component.ts +103 -11
- package/src/components/navbar/navbar.scss +6 -1
- package/src/components/opt-group/index.ts +12 -0
- package/src/components/opt-group/opt-group.component.ts +74 -0
- package/src/components/opt-group/opt-group.scss +37 -0
- package/src/components/opt-group/opt-group.test.ts +27 -0
- package/src/components/option/option.component.ts +1 -16
- package/src/components/option/option.scss +4 -0
- package/src/components/panel/panel.component.ts +10 -8
- package/src/components/panel/panel.scss +20 -0
- package/src/components/priority-list/index.ts +12 -0
- package/src/components/priority-list/priority-list.component.ts +611 -0
- package/src/components/priority-list/priority-list.scss +185 -0
- package/src/components/priority-list/priority-list.test.ts +139 -0
- package/src/components/progress-bar/progress-bar.component.ts +22 -16
- package/src/components/radio/radio.scss +10 -3
- package/src/components/select/select.component.ts +812 -72
- package/src/components/select/select.scss +108 -2
- package/src/components/select/select.test.ts +147 -2
- package/src/components/settings-container/settings-container.component.ts +44 -19
- package/src/components/settings-container/settings-container.scss +1 -1
- package/src/components/skeleton/skeleton.component.ts +6 -1
- package/src/components/slideout/slideout.scss +8 -3
- package/src/components/sp/sp.component.ts +3 -1
- package/src/components/sp/sp.scss +19 -0
- package/src/components/stepper/stepper.component.ts +16 -10
- package/src/components/textarea/textarea.scss +0 -4
- package/src/components/tile/tile.component.ts +12 -3
- package/src/components/tile/tile.scss +1 -1
- package/src/components/timer/timer.component.ts +15 -2
- package/src/components/toggle/toggle.component.ts +29 -26
- package/src/components/toggle/toggle.scss +13 -1
- package/src/components/translation-group/index.ts +12 -0
- package/src/components/translation-group/translation-group.component.ts +207 -0
- package/src/components/translation-group/translation-group.scss +8 -0
- package/src/components/translations/translations.component.ts +90 -44
- package/src/components/translations/translations.scss +4 -0
- package/src/components/vertical-stepper/vertical-stepper.component.ts +14 -9
- package/src/events/events.ts +12 -7
- package/src/events/zn-language-change.ts +7 -0
- package/src/events/zn-purchase.ts +11 -0
- package/src/events/zn-redirect.ts +7 -0
- package/src/events/zn-reorder.ts +7 -0
- package/src/events/zn-search-change.ts +11 -0
- package/src/events/zn-submit.ts +1 -1
- package/src/form-control.scss +4 -0
- package/src/internal/form-navigation.ts +510 -0
- package/src/internal/form.ts +6 -0
- package/src/zinc.ts +91 -83
|
@@ -3,6 +3,7 @@ import {type CSSResultGroup, html, type PropertyValues, unsafeCSS} from 'lit';
|
|
|
3
3
|
import {property} from 'lit/decorators.js';
|
|
4
4
|
import ZincElement from '../../internal/zinc-element';
|
|
5
5
|
import ZnIcon from "../icon";
|
|
6
|
+
import ZnTooltip from "../tooltip";
|
|
6
7
|
|
|
7
8
|
import styles from './item.scss';
|
|
8
9
|
|
|
@@ -13,6 +14,7 @@ import styles from './item.scss';
|
|
|
13
14
|
* @since 1.0
|
|
14
15
|
*
|
|
15
16
|
* @dependency zn-icon
|
|
17
|
+
* @dependency zn-tooltip
|
|
16
18
|
*
|
|
17
19
|
* @slot - The default slot. Can either be slotted or use the value attribute
|
|
18
20
|
* @slot actions - Used for adding actions to a zn-item.
|
|
@@ -23,7 +25,8 @@ import styles from './item.scss';
|
|
|
23
25
|
*/
|
|
24
26
|
export default class ZnItem extends ZincElement {
|
|
25
27
|
static dependencies = {
|
|
26
|
-
'zn-icon': ZnIcon
|
|
28
|
+
'zn-icon': ZnIcon,
|
|
29
|
+
'zn-tooltip': ZnTooltip
|
|
27
30
|
};
|
|
28
31
|
|
|
29
32
|
static styles: CSSResultGroup = unsafeCSS(styles);
|
|
@@ -38,6 +41,8 @@ export default class ZnItem extends ZincElement {
|
|
|
38
41
|
|
|
39
42
|
@property({attribute: 'edit-on-hover', type: Boolean}) editOnHover: boolean;
|
|
40
43
|
|
|
44
|
+
@property({attribute: 'help-tooltip'}) helpTooltip: string;
|
|
45
|
+
|
|
41
46
|
@property() icon: string;
|
|
42
47
|
|
|
43
48
|
@property() value: string;
|
|
@@ -52,7 +57,7 @@ export default class ZnItem extends ZincElement {
|
|
|
52
57
|
@property({type: Boolean, attribute: 'align-end'}) alignEnd: boolean;
|
|
53
58
|
|
|
54
59
|
// align items in the center
|
|
55
|
-
@property({type: Boolean, attribute: 'align-center'})
|
|
60
|
+
@property({type: Boolean, attribute: 'align-center'}) alignCenter: boolean;
|
|
56
61
|
|
|
57
62
|
connectedCallback() {
|
|
58
63
|
super.connectedCallback();
|
|
@@ -74,12 +79,28 @@ export default class ZnItem extends ZincElement {
|
|
|
74
79
|
return slotContent > 0 || this.innerText.length > 0 || !(this.value === undefined || this.value === null)
|
|
75
80
|
}
|
|
76
81
|
|
|
82
|
+
protected _hasRequiredSlot(): boolean {
|
|
83
|
+
const slotElements = this.querySelectorAll(":scope > *:not([slot])");
|
|
84
|
+
return Array.from(slotElements).some(el => el.hasAttribute && el.hasAttribute('required'));
|
|
85
|
+
}
|
|
86
|
+
|
|
77
87
|
render() {
|
|
78
88
|
const hasIcon = this.icon && this.icon.length > 0;
|
|
79
89
|
|
|
90
|
+
const hasHelpTooltip = this.helpTooltip?.length > 0;
|
|
91
|
+
|
|
80
92
|
const headings = html`
|
|
81
93
|
<div class="item__headings">
|
|
82
|
-
<div class
|
|
94
|
+
<div class=${classMap({
|
|
95
|
+
'item__caption': true,
|
|
96
|
+
'item__caption--required': this._hasRequiredSlot(),
|
|
97
|
+
'item__caption--has-help': hasHelpTooltip
|
|
98
|
+
})} part="caption">${this.caption}
|
|
99
|
+
${hasHelpTooltip ? html`
|
|
100
|
+
<zn-tooltip class="item__help-tooltip" content="${this.helpTooltip}">
|
|
101
|
+
<zn-icon src="info"></zn-icon>
|
|
102
|
+
</zn-tooltip>` : ''}
|
|
103
|
+
</div>
|
|
83
104
|
${this.description ? html`
|
|
84
105
|
<div class="item__description">${this.description}</div>` : ''}
|
|
85
106
|
</div>`;
|
|
@@ -12,6 +12,7 @@
|
|
|
12
12
|
flex-direction: row;
|
|
13
13
|
padding: 0 var(--zn-spacing-medium);
|
|
14
14
|
gap: var(--zn-spacing-2x-small);
|
|
15
|
+
min-height: 35px;
|
|
15
16
|
|
|
16
17
|
@include wc.container-query(null, md) {
|
|
17
18
|
--zn-item-label-max-width: 220px;
|
|
@@ -95,6 +96,23 @@
|
|
|
95
96
|
line-height: var(--zn-line-height-loose);
|
|
96
97
|
width: 100%;
|
|
97
98
|
flex-shrink: 0;
|
|
99
|
+
|
|
100
|
+
&--has-help {
|
|
101
|
+
display: inline-flex;
|
|
102
|
+
align-items: center;
|
|
103
|
+
gap: var(--zn-spacing-2x-small);
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
&--required::after {
|
|
107
|
+
content: var(--zn-input-required-content);
|
|
108
|
+
margin-inline-start: var(--zn-input-required-content-offset);
|
|
109
|
+
color: var(--zn-input-required-content-color);
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
&__help-tooltip {
|
|
114
|
+
color: var(--zn-color-neutral-700);
|
|
115
|
+
font-size: var(--zn-font-size-small);
|
|
98
116
|
}
|
|
99
117
|
|
|
100
118
|
&__description {
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import {type CSSResultGroup, html, unsafeCSS} from 'lit';
|
|
2
|
+
import {property} from 'lit/decorators.js';
|
|
3
|
+
import ZincElement from '../../internal/zinc-element';
|
|
4
|
+
|
|
5
|
+
import styles from './key.scss';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* @summary A legend key item, typically used alongside charts to label and toggle visibility of data series by category.
|
|
9
|
+
* @documentation https://zinc.style/components/key
|
|
10
|
+
* @status experimental
|
|
11
|
+
* @since 1.0
|
|
12
|
+
*
|
|
13
|
+
* @slot - The description of the key.
|
|
14
|
+
*/
|
|
15
|
+
export default class ZnKey extends ZincElement {
|
|
16
|
+
static styles: CSSResultGroup = unsafeCSS(styles);
|
|
17
|
+
|
|
18
|
+
@property() icon: string = '';
|
|
19
|
+
@property() attribute: string = '';
|
|
20
|
+
@property() value: string = '';
|
|
21
|
+
@property() color: 'primary' | 'success' | 'warning' | 'error' | 'info' | 'neutral' = 'primary';
|
|
22
|
+
@property({type: Boolean, reflect: true}) active: boolean = false;
|
|
23
|
+
@property({attribute: 'icon-size', type: Number}) iconSize: number = 24;
|
|
24
|
+
|
|
25
|
+
private _handleClick() {
|
|
26
|
+
this.active = !this.active;
|
|
27
|
+
this.emit('zn-change');
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
render() {
|
|
31
|
+
const chipType = this.active ? this.color : 'transparent';
|
|
32
|
+
|
|
33
|
+
return html`
|
|
34
|
+
<div class="key" @click="${this._handleClick}">
|
|
35
|
+
<zn-chip
|
|
36
|
+
.icon="${this.icon}"
|
|
37
|
+
.iconSize="${this.iconSize}"
|
|
38
|
+
.type="${chipType}"
|
|
39
|
+
size="medium"
|
|
40
|
+
></zn-chip>
|
|
41
|
+
<div class="key__description">
|
|
42
|
+
<slot></slot>
|
|
43
|
+
</div>
|
|
44
|
+
</div>
|
|
45
|
+
`;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
@use "../../wc";
|
|
2
|
+
|
|
3
|
+
:host {
|
|
4
|
+
display: block;
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
.key {
|
|
8
|
+
cursor: pointer;
|
|
9
|
+
display: flex;
|
|
10
|
+
flex-direction: row;
|
|
11
|
+
gap: var(--zn-spacing-medium);
|
|
12
|
+
align-items: center;
|
|
13
|
+
text-align: left;
|
|
14
|
+
|
|
15
|
+
&__description {
|
|
16
|
+
font-size: var(--zn-font-size-small);
|
|
17
|
+
color: rgb(var(--zn-text-body));
|
|
18
|
+
opacity: 0.7;
|
|
19
|
+
line-height: var(--zn-line-height-normal);
|
|
20
|
+
user-select: none;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
:host([active]) .key__label {
|
|
25
|
+
color: rgb(var(--zn-text-heading));
|
|
26
|
+
font-weight: 600;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
:host(:not([active])) {
|
|
30
|
+
.key__description {
|
|
31
|
+
opacity: 0.6;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
zn-chip {
|
|
35
|
+
--zn-chip-color: rgb(var(--zn-text-body));
|
|
36
|
+
opacity: 0.5;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import ZnKeyContainer from './key-container.component';
|
|
2
|
+
|
|
3
|
+
export * from './key-container.component';
|
|
4
|
+
export default ZnKeyContainer;
|
|
5
|
+
|
|
6
|
+
ZnKeyContainer.define('zn-key-container');
|
|
7
|
+
|
|
8
|
+
declare global {
|
|
9
|
+
interface HTMLElementTagNameMap {
|
|
10
|
+
'zn-key-container': ZnKeyContainer;
|
|
11
|
+
}
|
|
12
|
+
}
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
import {classMap} from "lit/directives/class-map.js";
|
|
2
|
+
import {type CSSResultGroup, html, unsafeCSS} from 'lit';
|
|
3
|
+
import {deepQuerySelectorAll} from "../../utilities/query";
|
|
4
|
+
import {property, query} from 'lit/decorators.js';
|
|
5
|
+
import ZincElement from '../../internal/zinc-element';
|
|
6
|
+
import type ZnKey from "../key/key.component";
|
|
7
|
+
|
|
8
|
+
import styles from './key-container.scss';
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* @summary A legend container that manages key items, typically used alongside charts to toggle visibility of data series by category.
|
|
12
|
+
* @documentation https://zinc.style/components/key-container
|
|
13
|
+
* @status experimental
|
|
14
|
+
* @since 1.0
|
|
15
|
+
*
|
|
16
|
+
* @slot - The content to be filtered.
|
|
17
|
+
* @slot keys - The key items (zn-key) that define the filters.
|
|
18
|
+
*
|
|
19
|
+
* @event zn-change - Emitted when the set of active keys changes.
|
|
20
|
+
*/
|
|
21
|
+
export default class ZnKeyContainer extends ZincElement {
|
|
22
|
+
static styles: CSSResultGroup = unsafeCSS(styles);
|
|
23
|
+
|
|
24
|
+
@query('slot[name="keys"]') keysSlot: HTMLSlotElement;
|
|
25
|
+
@query('slot:not([name])') defaultSlot: HTMLSlotElement;
|
|
26
|
+
|
|
27
|
+
@property() position: 'top-end' | 'top-start' | 'bottom-end' | 'bottom-start' = 'bottom-start';
|
|
28
|
+
@property() target: string = ''; // ID of the target element containing items
|
|
29
|
+
@property({attribute: 'item-selector'}) itemSelector: string = '[data-type]';
|
|
30
|
+
@property({attribute: 'filter-attribute'}) filterAttribute: string = '';
|
|
31
|
+
@property({attribute: 'no-scroll', type: Boolean}) noScroll: boolean = false;
|
|
32
|
+
|
|
33
|
+
private _hiddenElements: Set<Element> = new Set();
|
|
34
|
+
private _targetElement: HTMLElement | null = null;
|
|
35
|
+
|
|
36
|
+
connectedCallback() {
|
|
37
|
+
super.connectedCallback();
|
|
38
|
+
this.updateFilters();
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
firstUpdated() {
|
|
42
|
+
if (this.target) {
|
|
43
|
+
const rootNode = this.getRootNode() as Document | ShadowRoot;
|
|
44
|
+
this._targetElement = rootNode.getElementById ? rootNode.getElementById(this.target) : document.getElementById(this.target);
|
|
45
|
+
}
|
|
46
|
+
this.updateFilters();
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
private _handleKeyChange() {
|
|
50
|
+
this.updateFilters();
|
|
51
|
+
this.emit('zn-change');
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
private getKeys(): ZnKey[] {
|
|
55
|
+
const keys = [];
|
|
56
|
+
if (this.keysSlot) {
|
|
57
|
+
keys.push(...this.keysSlot.assignedElements({flatten: true}));
|
|
58
|
+
}
|
|
59
|
+
if (this.defaultSlot) {
|
|
60
|
+
keys.push(...this.defaultSlot.assignedElements({flatten: true}));
|
|
61
|
+
}
|
|
62
|
+
return keys.filter(el => el.tagName.toLowerCase() === 'zn-key') as ZnKey[];
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
private updateFilters() {
|
|
66
|
+
const keys = this.getKeys();
|
|
67
|
+
if (!keys || keys.length === 0) return;
|
|
68
|
+
|
|
69
|
+
// Reset hidden elements
|
|
70
|
+
this._hiddenElements.forEach(el => el.removeAttribute('hidden'));
|
|
71
|
+
this._hiddenElements.clear();
|
|
72
|
+
|
|
73
|
+
if (this.target && !this._targetElement) {
|
|
74
|
+
const rootNode = this.getRootNode() as Document | ShadowRoot;
|
|
75
|
+
this._targetElement = rootNode.getElementById?.(this.target) ?? document.getElementById(this.target);
|
|
76
|
+
}
|
|
77
|
+
let root: Element | Document | DocumentFragment | null = this._targetElement ?? null;
|
|
78
|
+
|
|
79
|
+
if (!root) {
|
|
80
|
+
const slotElements = this.defaultSlot?.assignedElements({flatten: true}) ?? [];
|
|
81
|
+
root = slotElements.some(el => el.tagName !== 'ZN-KEY')
|
|
82
|
+
? this
|
|
83
|
+
: this.parentElement ?? (this.parentNode as DocumentFragment);
|
|
84
|
+
}
|
|
85
|
+
if (!root) return;
|
|
86
|
+
|
|
87
|
+
const selector = this.filterAttribute ? `[${this.filterAttribute}]` : this.itemSelector;
|
|
88
|
+
const items = deepQuerySelectorAll(selector, root as HTMLElement, "");
|
|
89
|
+
items.forEach(item => {
|
|
90
|
+
if (item === this) return;
|
|
91
|
+
|
|
92
|
+
const matchesInactive = keys.some(key => !key.active && this.itemMatchesKey(item, key));
|
|
93
|
+
if (matchesInactive) {
|
|
94
|
+
item.setAttribute('hidden', '');
|
|
95
|
+
this._hiddenElements.add(item);
|
|
96
|
+
}
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
private itemMatchesKey(item: Element, key: ZnKey): boolean {
|
|
101
|
+
// 1. If the container specifies filterAttribute, use key.attribute as the value to look for
|
|
102
|
+
if (this.filterAttribute) {
|
|
103
|
+
const itemValue = item.getAttribute(this.filterAttribute);
|
|
104
|
+
if (!itemValue) return false;
|
|
105
|
+
|
|
106
|
+
const targetValue = key.attribute;
|
|
107
|
+
if (!targetValue) return false;
|
|
108
|
+
|
|
109
|
+
return itemValue.split(/\s+/).includes(targetValue);
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
// 2. If key specifies attribute and value
|
|
113
|
+
if (key.attribute && key.value) {
|
|
114
|
+
const itemValue = item.getAttribute(key.attribute);
|
|
115
|
+
if (!itemValue) return false;
|
|
116
|
+
|
|
117
|
+
return itemValue.split(/\s+/).includes(key.value);
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
// 3. If the key only specifies attribute (and no value), check for existence
|
|
121
|
+
if (key.attribute) {
|
|
122
|
+
return item.hasAttribute(key.attribute);
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
return false;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
render() {
|
|
129
|
+
return html`
|
|
130
|
+
<div class="${classMap({
|
|
131
|
+
'key-container': true,
|
|
132
|
+
'key-container--scroll': !this.noScroll,
|
|
133
|
+
})}" @zn-change="${this._handleKeyChange}">
|
|
134
|
+
${this.target ? '' : html`
|
|
135
|
+
<div class="key-container__content">
|
|
136
|
+
<slot @slotchange="${this.updateFilters.bind(this)}" class="key-container__keys"></slot>
|
|
137
|
+
</div>
|
|
138
|
+
`}
|
|
139
|
+
</div>
|
|
140
|
+
`;
|
|
141
|
+
}
|
|
142
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
@use "../../wc";
|
|
2
|
+
|
|
3
|
+
:host {
|
|
4
|
+
display: contents;
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
.key-container--scroll {
|
|
8
|
+
height: 100%;
|
|
9
|
+
width: 100%;
|
|
10
|
+
overflow: hidden;
|
|
11
|
+
position: relative;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
.key-container__content {
|
|
15
|
+
height: 100%;
|
|
16
|
+
width: 100%;
|
|
17
|
+
overflow: auto;
|
|
18
|
+
box-sizing: border-box;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
.key-container__keys {
|
|
22
|
+
display: flex;
|
|
23
|
+
flex-direction: column;
|
|
24
|
+
gap: var(--zn-spacing-medium);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
::slotted(zn-key) {
|
|
28
|
+
flex: 0 0 auto;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
::slotted([hidden]) {
|
|
32
|
+
display: none !important;
|
|
33
|
+
}
|
|
@@ -78,6 +78,21 @@ export default class ZnMenuItem extends ZincElement {
|
|
|
78
78
|
|
|
79
79
|
@property({type: Boolean, reflect: true}) confirm = false;
|
|
80
80
|
|
|
81
|
+
/** Removes all padding from the menu item. */
|
|
82
|
+
@property({type: Boolean, reflect: true}) flush = false;
|
|
83
|
+
|
|
84
|
+
/** Removes horizontal (left/right) padding only. Ignored if flush is set. */
|
|
85
|
+
@property({type: Boolean, reflect: true, attribute: 'flush-x'}) flushX = false;
|
|
86
|
+
|
|
87
|
+
/** Removes vertical (top/bottom) padding only. Ignored if flush is set. */
|
|
88
|
+
@property({type: Boolean, reflect: true, attribute: 'flush-y'}) flushY = false;
|
|
89
|
+
|
|
90
|
+
/** Removes the border from the menu item. */
|
|
91
|
+
@property({type: Boolean, reflect: true, attribute: 'no-border'}) noBorder = false;
|
|
92
|
+
|
|
93
|
+
/** Marks the menu item as currently active/selected. */
|
|
94
|
+
@property({type: Boolean, reflect: true}) active = false;
|
|
95
|
+
|
|
81
96
|
private readonly localize = new LocalizeController(this);
|
|
82
97
|
private readonly hasSlotController = new HasSlotController(this, 'submenu');
|
|
83
98
|
private submenuController: SubmenuController = new SubmenuController(this, this.hasSlotController, this.localize);
|
|
@@ -209,6 +224,11 @@ export default class ZnMenuItem extends ZincElement {
|
|
|
209
224
|
'menu-item--success': this.color === 'success',
|
|
210
225
|
'menu-item--warning': this.color === 'warning',
|
|
211
226
|
'menu-item--transparent': this.color === 'transparent',
|
|
227
|
+
'menu-item--flush': this.flush,
|
|
228
|
+
'menu-item--flush-x': this.flushX && !this.flush,
|
|
229
|
+
'menu-item--flush-y': this.flushY && !this.flush,
|
|
230
|
+
'menu-item--no-border': this.noBorder,
|
|
231
|
+
'menu-item--active': this.active,
|
|
212
232
|
|
|
213
233
|
})}
|
|
214
234
|
?aria-haspopup="${this.isSubmenu()}"
|
|
@@ -23,7 +23,7 @@
|
|
|
23
23
|
white-space: nowrap;
|
|
24
24
|
cursor: pointer;
|
|
25
25
|
border-bottom-width: 1px;
|
|
26
|
-
|
|
26
|
+
width: 100%;
|
|
27
27
|
text-decoration: none;
|
|
28
28
|
color: var(--color);
|
|
29
29
|
}
|
|
@@ -44,6 +44,72 @@
|
|
|
44
44
|
cursor: wait;
|
|
45
45
|
}
|
|
46
46
|
|
|
47
|
+
// Flush variants - remove padding
|
|
48
|
+
.menu-item--flush {
|
|
49
|
+
padding: 0;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
.menu-item--flush-x {
|
|
53
|
+
padding-left: 0;
|
|
54
|
+
padding-right: 0;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
.menu-item--flush-y {
|
|
58
|
+
padding-top: 0;
|
|
59
|
+
padding-bottom: 0;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
// No border variant
|
|
63
|
+
.menu-item--no-border {
|
|
64
|
+
border-bottom-width: 0;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
// Active state - vertical strip indicator
|
|
68
|
+
.menu-item--active::before {
|
|
69
|
+
content: '';
|
|
70
|
+
position: absolute;
|
|
71
|
+
left: 0;
|
|
72
|
+
top: 0;
|
|
73
|
+
bottom: 0;
|
|
74
|
+
width: 3px;
|
|
75
|
+
background-color: var(--hover-color);
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
.menu-item.menu-item--active .menu-item__label {
|
|
79
|
+
font-weight: 700;
|
|
80
|
+
color: var(--hover-color);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
.menu-item--rtl.menu-item--active::before {
|
|
84
|
+
left: auto;
|
|
85
|
+
right: 0;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
// Active state with color variants
|
|
89
|
+
.menu-item--active.menu-item--primary::before {
|
|
90
|
+
background-color: rgb(var(--zn-primary));
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
.menu-item--active.menu-item--error::before {
|
|
94
|
+
background-color: rgb(var(--zn-color-error));
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
.menu-item--active.menu-item--info::before {
|
|
98
|
+
background-color: rgb(var(--zn-color-info));
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
.menu-item--active.menu-item--warning::before {
|
|
102
|
+
background-color: rgb(var(--zn-color-warning));
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
.menu-item--active.menu-item--success::before {
|
|
106
|
+
background-color: rgb(var(--zn-color-success));
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
.menu-item--active.menu-item--secondary::before {
|
|
110
|
+
background-color: rgb(var(--zn-accent));
|
|
111
|
+
}
|
|
112
|
+
|
|
47
113
|
.menu-item .menu-item__label {
|
|
48
114
|
display: flex;
|
|
49
115
|
flex: 1 1 auto;
|
|
@@ -99,7 +165,8 @@
|
|
|
99
165
|
}
|
|
100
166
|
|
|
101
167
|
:host(:hover:not([aria-disabled='true'], :focus-visible)) .menu-item,
|
|
102
|
-
.menu-item--submenu-expanded
|
|
168
|
+
.menu-item--submenu-expanded,
|
|
169
|
+
.menu-item--active {
|
|
103
170
|
background-color: var(--hover-bg);
|
|
104
171
|
color: var(--hover-color);
|
|
105
172
|
}
|