@lmvz-ds/components 0.30.0 → 0.32.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +10 -0
- package/cjs/{ds.constants-D3srqM9m.js → ds.constants-CKeXfK-s.js} +10 -0
- package/cjs/{component-C7cavwmZ.js → element.util-Cq4y-_iX.js} +42 -31
- package/cjs/index.cjs.js +7 -1
- package/cjs/{list-keyboard-controller-CzZdPBeH.js → list-keyboard-controller-StN6Yn8W.js} +13 -8
- package/cjs/lmvz-action-list.cjs.entry.js +79 -0
- package/cjs/lmvz-button-group.cjs.entry.js +43 -47
- package/cjs/lmvz-button_2.cjs.entry.js +10 -8
- package/cjs/lmvz-card.cjs.entry.js +2 -2
- package/cjs/lmvz-checkbox.cjs.entry.js +1 -1
- package/cjs/lmvz-chip.cjs.entry.js +2 -2
- package/cjs/lmvz-components.cjs.js +1 -1
- package/cjs/lmvz-header_2.cjs.entry.js +3 -3
- package/cjs/lmvz-input.cjs.entry.js +5 -5
- package/cjs/lmvz-link.cjs.entry.js +2 -2
- package/cjs/lmvz-menuitem.cjs.entry.js +1 -1
- package/cjs/lmvz-message.cjs.entry.js +1 -1
- package/cjs/lmvz-modal.cjs.entry.js +5 -5
- package/cjs/lmvz-radio.cjs.entry.js +1 -1
- package/cjs/lmvz-select.cjs.entry.js +1 -1
- package/cjs/lmvz-snackbar.cjs.entry.js +1 -1
- package/cjs/lmvz-spinner.cjs.entry.js +1 -1
- package/cjs/lmvz-tab.cjs.entry.js +2 -2
- package/cjs/lmvz-tabs.cjs.entry.js +4 -4
- package/cjs/lmvz-toggle.cjs.entry.js +3 -3
- package/cjs/loader.cjs.js +1 -1
- package/cjs/stencil.util-DzvzXSwk.js +25 -0
- package/collection/collection-manifest.json +1 -0
- package/collection/components/lmvz-action-list/lmvz-action-list.css +93 -0
- package/collection/components/lmvz-action-list/lmvz-action-list.js +104 -0
- package/collection/components/lmvz-button/lmvz-button.css +65 -45
- package/collection/components/lmvz-button/lmvz-button.js +28 -7
- package/collection/components/lmvz-button-group/lmvz-button-group.css +33 -2
- package/collection/components/lmvz-button-group/lmvz-button-group.js +54 -38
- package/collection/components/lmvz-card/lmvz-card.css +58 -45
- package/collection/components/lmvz-card/lmvz-card.js +2 -2
- package/collection/components/lmvz-checkbox/lmvz-checkbox.js +2 -2
- package/collection/components/lmvz-chip/lmvz-chip.js +7 -7
- package/collection/components/lmvz-header/lmvz-header.js +2 -2
- package/collection/components/lmvz-icon/lmvz-icon.js +2 -2
- package/collection/components/lmvz-input/lmvz-input.js +5 -5
- package/collection/components/lmvz-link/lmvz-link.js +3 -3
- package/collection/components/lmvz-menuitem/lmvz-menuitem.js +2 -2
- package/collection/components/lmvz-message/lmvz-message.js +1 -1
- package/collection/components/lmvz-modal/lmvz-modal.css +7 -0
- package/collection/components/lmvz-modal/lmvz-modal.js +3 -3
- package/collection/components/lmvz-radio/lmvz-radio.js +2 -2
- package/collection/components/lmvz-select/lmvz-select.js +2 -2
- package/collection/components/lmvz-snackbar/lmvz-snackbar.js +1 -1
- package/collection/components/lmvz-spinner/lmvz-spinner.js +1 -1
- package/collection/components/lmvz-tab/lmvz-tab.css +7 -0
- package/collection/components/lmvz-tab/lmvz-tab.js +1 -1
- package/collection/components/lmvz-tabs/lmvz-tabs.css +7 -0
- package/collection/components/lmvz-tabs/lmvz-tabs.js +2 -2
- package/collection/components/lmvz-toggle/lmvz-toggle.js +3 -3
- package/collection/index.js +1 -1
- package/collection/integration/header-integration/header-integration.js +1 -1
- package/collection/utils/aria/aria.constants.js +53 -0
- package/collection/utils/aria/list-keyboard-controller.js +12 -7
- package/collection/utils/async/async.util.js +62 -0
- package/collection/utils/data/event.utilt.js +19 -0
- package/collection/utils/data/number.util.js +6 -0
- package/collection/utils/data/object.util.js +20 -0
- package/collection/utils/data/time.util.js +3 -0
- package/collection/utils/element/element.util.js +117 -0
- package/collection/utils/{assets.js → stencil/assets.js} +1 -1
- package/collection/utils/stencil/stencil.util.js +12 -0
- package/components/index.d.ts +2 -0
- package/components/index.d.ts.bak +2 -0
- package/components/index.js +1 -1
- package/components/lmvz-action-list.d.ts +11 -0
- package/components/lmvz-action-list.d.ts.bak +11 -0
- package/components/lmvz-action-list.js +1 -0
- package/components/lmvz-button-group.js +1 -1
- package/components/lmvz-button.js +1 -1
- package/components/lmvz-card.js +1 -1
- package/components/lmvz-checkbox.js +1 -1
- package/components/lmvz-chip.js +1 -1
- package/components/lmvz-header.js +1 -1
- package/components/lmvz-icon.js +1 -1
- package/components/lmvz-input.js +1 -1
- package/components/lmvz-link.js +1 -1
- package/components/lmvz-menuitem.js +1 -1
- package/components/lmvz-message.js +1 -1
- package/components/lmvz-modal.js +1 -1
- package/components/lmvz-radio.js +1 -1
- package/components/lmvz-select.js +1 -1
- package/components/lmvz-snackbar.js +1 -1
- package/components/lmvz-spinner.js +1 -1
- package/components/lmvz-tab.js +1 -1
- package/components/lmvz-tabs.js +1 -1
- package/components/lmvz-toggle.js +1 -1
- package/components/p-B0H9qIwE.js +1 -0
- package/components/p-B4m1n4et.js +1 -0
- package/components/p-CJRqhXjK.js +1 -0
- package/components/p-CxfT9IA1.js +1 -0
- package/components/{p-CXakymyP.js → p-DJ90327O.js} +1 -1
- package/components/p-DeO5Vbxh.js +1 -0
- package/components/p-DuEtnKRj.js +1 -0
- package/esm/{ds.constants-BLS5MjIu.js → ds.constants-DuEtnKRj.js} +5 -1
- package/esm/{component-DOTK1OW3.js → element.util-CxfT9IA1.js} +37 -31
- package/esm/index.js +1 -1
- package/esm/{list-keyboard-controller-Coi8XfUH.js → list-keyboard-controller-BKa9Kd2t.js} +12 -7
- package/esm/lmvz-action-list.entry.js +77 -0
- package/esm/lmvz-button-group.entry.js +35 -39
- package/esm/lmvz-button_2.entry.js +9 -7
- package/esm/lmvz-card.entry.js +2 -2
- package/esm/lmvz-checkbox.entry.js +1 -1
- package/esm/lmvz-chip.entry.js +2 -2
- package/esm/lmvz-components.js +1 -1
- package/esm/lmvz-header_2.entry.js +3 -3
- package/esm/lmvz-input.entry.js +4 -4
- package/esm/lmvz-link.entry.js +2 -2
- package/esm/lmvz-menuitem.entry.js +1 -1
- package/esm/lmvz-message.entry.js +1 -1
- package/esm/lmvz-modal.entry.js +3 -3
- package/esm/lmvz-radio.entry.js +1 -1
- package/esm/lmvz-select.entry.js +1 -1
- package/esm/lmvz-snackbar.entry.js +1 -1
- package/esm/lmvz-spinner.entry.js +1 -1
- package/esm/lmvz-tab.entry.js +2 -2
- package/esm/lmvz-tabs.entry.js +4 -4
- package/esm/lmvz-toggle.entry.js +2 -2
- package/esm/loader.js +1 -1
- package/esm/stencil.util-CJRqhXjK.js +23 -0
- package/hydrate/index.js +501 -388
- package/hydrate/index.mjs +501 -388
- package/lmvz-components/index.esm.js +1 -1
- package/lmvz-components/lmvz-components.esm.js +1 -1
- package/lmvz-components/{p-f3c44dd4.entry.js → p-1ce90ea7.entry.js} +1 -1
- package/lmvz-components/{p-b08db5ad.entry.js → p-24125bcf.entry.js} +1 -1
- package/lmvz-components/p-25a78ead.entry.js +1 -0
- package/lmvz-components/p-4072b2fb.entry.js +1 -0
- package/lmvz-components/p-48109e1d.entry.js +1 -0
- package/lmvz-components/{p-3b3e532f.entry.js → p-582f44ff.entry.js} +1 -1
- package/lmvz-components/p-592d509b.entry.js +1 -0
- package/lmvz-components/{p-d7e99f03.entry.js → p-6f61c24d.entry.js} +1 -1
- package/lmvz-components/{p-58498d43.entry.js → p-703b10b5.entry.js} +1 -1
- package/lmvz-components/p-74c7521c.entry.js +1 -0
- package/lmvz-components/{p-b5254532.entry.js → p-80a26307.entry.js} +1 -1
- package/lmvz-components/{p-c60ab9c9.entry.js → p-8e1f66dd.entry.js} +1 -1
- package/lmvz-components/p-947e1fe6.entry.js +1 -0
- package/lmvz-components/p-B4m1n4et.js +1 -0
- package/lmvz-components/p-CJRqhXjK.js +1 -0
- package/lmvz-components/p-CxfT9IA1.js +1 -0
- package/lmvz-components/p-DuEtnKRj.js +1 -0
- package/lmvz-components/{p-230962c8.entry.js → p-b79af711.entry.js} +1 -1
- package/lmvz-components/p-c00f0d96.entry.js +1 -0
- package/lmvz-components/{p-5c951888.entry.js → p-c0d05a97.entry.js} +1 -1
- package/lmvz-components/{p-c0b1d0af.entry.js → p-c3e8092e.entry.js} +1 -1
- package/lmvz-components/{p-2ca85b7c.entry.js → p-ed3c2b13.entry.js} +1 -1
- package/lmvz-components/{p-35da6bfb.entry.js → p-fa2cd315.entry.js} +1 -1
- package/manifest.json +130 -18
- package/package.json +5 -1
- package/types/api/ds.constants.d.ts +0 -40
- package/types/api/ds.types.d.ts +68 -1
- package/types/components/lmvz-action-list/lmvz-action-list.d.ts +15 -0
- package/types/components/lmvz-button/lmvz-button.d.ts +6 -3
- package/types/components/lmvz-button-group/lmvz-button-group.d.ts +2 -0
- package/types/components/lmvz-checkbox/lmvz-checkbox.d.ts +1 -1
- package/types/components/lmvz-chip/lmvz-chip.d.ts +2 -2
- package/types/components/lmvz-header/lmvz-header.d.ts +1 -1
- package/types/components/lmvz-icon/lmvz-icon.d.ts +1 -1
- package/types/components/lmvz-input/lmvz-input.d.ts +1 -1
- package/types/components/lmvz-link/lmvz-link.d.ts +1 -1
- package/types/components/lmvz-menuitem/lmvz-menuitem.d.ts +1 -1
- package/types/components/lmvz-modal/lmvz-modal.d.ts +1 -1
- package/types/components/lmvz-radio/lmvz-radio.d.ts +1 -1
- package/types/components/lmvz-select/lmvz-select.d.ts +1 -1
- package/types/components/lmvz-tabs/lmvz-tabs.d.ts +1 -1
- package/types/components/lmvz-toggle/lmvz-toggle.d.ts +1 -1
- package/types/components.d.ts +83 -2
- package/types/index.d.ts +1 -1
- package/types/utils/aria/aria-validation-controller.d.ts +3 -3
- package/types/utils/aria/aria.constants.d.ts +1 -0
- package/types/utils/aria/element-activation-controller.d.ts +1 -1
- package/types/utils/aria/list-keyboard-controller.d.ts +4 -1
- package/types/utils/async/async.util.d.ts +8 -0
- package/types/utils/data/event.utilt.d.ts +4 -0
- package/types/utils/data/number.util.d.ts +2 -0
- package/types/utils/data/object.util.d.ts +5 -0
- package/types/utils/data/time.util.d.ts +1 -0
- package/types/utils/element/element.util.d.ts +21 -0
- package/types/utils/radio/radio-group-controller.d.ts +1 -1
- package/types/utils/{reactive-controller-host.d.ts → stencil/reactive-controller-host.d.ts} +1 -1
- package/types/utils/stencil/stencil.util.d.ts +6 -0
- package/collection/utils/component.js +0 -270
- package/collection/utils/http.js +0 -21
- package/collection/utils/http.unit.js +0 -47
- package/components/p-BLS5MjIu.js +0 -1
- package/components/p-C0f2nNPZ.js +0 -1
- package/components/p-CtaMrBNE.js +0 -1
- package/components/p-DGlgVBPj.js +0 -1
- package/components/p-DOTK1OW3.js +0 -1
- package/lmvz-components/p-0d435e7b.entry.js +0 -1
- package/lmvz-components/p-44fea470.entry.js +0 -1
- package/lmvz-components/p-4dc44520.entry.js +0 -1
- package/lmvz-components/p-BLS5MjIu.js +0 -1
- package/lmvz-components/p-CtaMrBNE.js +0 -1
- package/lmvz-components/p-DOTK1OW3.js +0 -1
- package/lmvz-components/p-a4077c9f.entry.js +0 -1
- package/lmvz-components/p-dce6e41d.entry.js +0 -1
- package/lmvz-components/p-e3ce44a3.entry.js +0 -1
- package/types/utils/component.d.ts +0 -33
- package/types/utils/http.d.ts +0 -26
- package/types/utils/http.unit.d.ts +0 -1
- /package/collection/utils/{reactive-controller-host.js → stencil/reactive-controller-host.js} +0 -0
- /package/types/utils/{assets.d.ts → stencil/assets.d.ts} +0 -0
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
|
|
2
|
+
@layer lmvz-ds.reset, lmvz-ds.theme, lmvz-ds.components, lmvz-ds.overrides;
|
|
3
|
+
/**
|
|
4
|
+
* This defines the order of our lmvz-ds' CSS layers. See readme.md for details.
|
|
5
|
+
* Important: Always import this file _before_ layering your own styles!
|
|
6
|
+
*/
|
|
7
|
+
@layer lmvz-ds.reset {
|
|
8
|
+
body {
|
|
9
|
+
margin: 0;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
h1,
|
|
13
|
+
h2,
|
|
14
|
+
h3,
|
|
15
|
+
h4,
|
|
16
|
+
h5,
|
|
17
|
+
h6 {
|
|
18
|
+
margin: 0;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
*[hidden] {
|
|
22
|
+
display: none !important;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
hr {
|
|
26
|
+
height: 0;
|
|
27
|
+
border: none;
|
|
28
|
+
margin: var(--lmvz-dimension-4-8, clamp(0.25rem, 0.19rem + 0.26vw, 0.5rem)) 0;
|
|
29
|
+
border-top: var(--lmvz-semantic-border-width-default, 1px) solid var(--lmvz-semantic-color-border-subtle, #f0f0f0);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
}
|
|
33
|
+
@layer lmvz-ds.components {
|
|
34
|
+
.lmvz-wrapper-card-sm,
|
|
35
|
+
.lmvz-wrapper-card-md,
|
|
36
|
+
.lmvz-wrapper-card-lg {
|
|
37
|
+
background: var(--lmvz-semantic-color-surface-primary, #ffffff);
|
|
38
|
+
box-shadow: var(--lmvz-ds-shadow-l3-default-strong, 0 2px 32px 0 rgba(120, 120, 128, 0.11));
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
.lmvz-wrapper-card-sm {
|
|
42
|
+
padding: var(--lmvz-component-wrapper-sm-padding-y, clamp(0.75rem, 0.69rem + 0.26vw, 1rem)) var(--lmvz-component-wrapper-sm-padding-x, clamp(0.75rem, 0.69rem + 0.26vw, 1rem));
|
|
43
|
+
border-radius: var(--lmvz-component-wrapper-sm-border-radius, 14px);
|
|
44
|
+
}
|
|
45
|
+
.lmvz-wrapper-card-md {
|
|
46
|
+
padding: var(--lmvz-component-wrapper-md-padding-y, clamp(1rem, 0.88rem + 0.52vw, 1.5rem)) var(--lmvz-component-wrapper-md-padding-x, clamp(1rem, 0.88rem + 0.52vw, 1.5rem));
|
|
47
|
+
border-radius: var(--lmvz-component-wrapper-md-border-radius, 18px);
|
|
48
|
+
}
|
|
49
|
+
.lmvz-wrapper-card-lg {
|
|
50
|
+
padding: var(--lmvz-component-wrapper-lg-padding-y, clamp(2.25rem, 2.19rem + 0.26vw, 2.5rem)) var(--lmvz-component-wrapper-lg-padding-x, clamp(1.5rem, 1.14rem + 1.55vw, 3rem));
|
|
51
|
+
border-radius: var(--lmvz-component-wrapper-lg-border-radius, 18px);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
}
|
|
55
|
+
:host {
|
|
56
|
+
display: flex;
|
|
57
|
+
flex-direction: column;
|
|
58
|
+
gap: 0;
|
|
59
|
+
|
|
60
|
+
lmvz-button,
|
|
61
|
+
button {
|
|
62
|
+
--lmvz-button-background-override: var(--lmvz-semantic-color-int-tertiary, #ffffff);
|
|
63
|
+
--lmvz-button-color-override: var(--lmvz-semantic-color-int-on-tertiary, #000000);
|
|
64
|
+
--lmvz-button-radius-override: var(--lmvz-semantic-border-radius-md, 6px);
|
|
65
|
+
--lmvz-button-padding-inline-override: var(--lmvz-component-input-padding-md, clamp(0.88rem, 0.84rem + 0.13vw, 1rem));
|
|
66
|
+
--lmvz-button-padding-block-override: var(--lmvz-component-input-padding-md, clamp(0.88rem, 0.84rem + 0.13vw, 1rem));
|
|
67
|
+
|
|
68
|
+
width: 100%;
|
|
69
|
+
display: block;
|
|
70
|
+
|
|
71
|
+
&:hover {
|
|
72
|
+
--lmvz-button-background-override: var(--lmvz-semantic-color-int-tertiary-hover, #f0f0f0);
|
|
73
|
+
--lmvz-button-color-override: var(--lmvz-semantic-color-int-on-tertiary-hover, #000000);
|
|
74
|
+
}
|
|
75
|
+
&:active {
|
|
76
|
+
--lmvz-button-background-override: var(--lmvz-semantic-color-int-tertiary-active, #e0e0e0);
|
|
77
|
+
--lmvz-button-color-override: var(--lmvz-semantic-color-int-on-tertiary-active, #000000);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
.lmvz-action-list-item--danger {
|
|
82
|
+
--lmvz-button-color-override: var(--lmvz-semantic-color-status-on-danger, #e52a31);
|
|
83
|
+
|
|
84
|
+
&:hover {
|
|
85
|
+
--lmvz-button-background-override: var(--lmvz-semantic-color-status-danger, #fdf1f2);
|
|
86
|
+
--lmvz-button-color-override: var(--lmvz-semantic-color-status-on-danger, #e52a31);
|
|
87
|
+
}
|
|
88
|
+
&:active {
|
|
89
|
+
--lmvz-button-background-override: var(--lmvz-semantic-color-status-on-danger-subtle, #f7bfc2);
|
|
90
|
+
--lmvz-button-color-override: var(--lmvz-semantic-color-status-on-danger, #e52a31);
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
}
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
import { Host, h } from "@stencil/core";
|
|
2
|
+
import { AriaValidationController } from "../../utils/aria/aria-validation-controller";
|
|
3
|
+
import { DirectionalFocusController } from "../../utils/aria/list-keyboard-controller";
|
|
4
|
+
import { ReactiveControllerHost } from "../../utils/stencil/reactive-controller-host";
|
|
5
|
+
export class LmvzActionList extends ReactiveControllerHost {
|
|
6
|
+
el;
|
|
7
|
+
slotEl;
|
|
8
|
+
get validationEl() {
|
|
9
|
+
return this.el;
|
|
10
|
+
}
|
|
11
|
+
get validationSlot() {
|
|
12
|
+
return this.slotEl;
|
|
13
|
+
}
|
|
14
|
+
focusController = new DirectionalFocusController(this, {
|
|
15
|
+
orientation: 'vertical',
|
|
16
|
+
manageTabIndex: true,
|
|
17
|
+
enableHomeAndEnd: true,
|
|
18
|
+
});
|
|
19
|
+
label;
|
|
20
|
+
constructor() {
|
|
21
|
+
super();
|
|
22
|
+
this.addController(this.focusController);
|
|
23
|
+
this.addController(new AriaValidationController(this, {
|
|
24
|
+
validationTiming: 'slot',
|
|
25
|
+
}));
|
|
26
|
+
}
|
|
27
|
+
componentDidLoad() {
|
|
28
|
+
this.handleSlotChange();
|
|
29
|
+
super.componentDidLoad();
|
|
30
|
+
}
|
|
31
|
+
handleSlotChange = () => {
|
|
32
|
+
const slot = this.slotEl;
|
|
33
|
+
if (!slot)
|
|
34
|
+
return;
|
|
35
|
+
const assigned = slot.assignedElements();
|
|
36
|
+
const interactive = [];
|
|
37
|
+
for (const el of assigned) {
|
|
38
|
+
collectInteractiveButtonsRecursively(el, interactive);
|
|
39
|
+
}
|
|
40
|
+
this.focusController.updateElements(interactive);
|
|
41
|
+
};
|
|
42
|
+
render() {
|
|
43
|
+
const ariaLabel = this.label || undefined;
|
|
44
|
+
return (h(Host, { key: '79e2d77c9aca02fb3ef2e58d241664598253334b', role: "menu", "aria-label": ariaLabel, class: "lmvz-wrapper-card-sm" }, h("slot", { key: '941b875a5be536c3d0e2ff9287da5af1a416d356', onSlotchange: this.handleSlotChange, ref: (el) => (this.slotEl = el) })));
|
|
45
|
+
}
|
|
46
|
+
static get is() { return "lmvz-action-list"; }
|
|
47
|
+
static get encapsulation() { return "scoped"; }
|
|
48
|
+
static get originalStyleUrls() {
|
|
49
|
+
return {
|
|
50
|
+
"$": ["./lmvz-action-list.css"]
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
static get styleUrls() {
|
|
54
|
+
return {
|
|
55
|
+
"$": ["lmvz-action-list.css"]
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
static get properties() {
|
|
59
|
+
return {
|
|
60
|
+
"label": {
|
|
61
|
+
"type": "string",
|
|
62
|
+
"mutable": false,
|
|
63
|
+
"complexType": {
|
|
64
|
+
"original": "string",
|
|
65
|
+
"resolved": "string | undefined",
|
|
66
|
+
"references": {}
|
|
67
|
+
},
|
|
68
|
+
"required": false,
|
|
69
|
+
"optional": true,
|
|
70
|
+
"docs": {
|
|
71
|
+
"tags": [],
|
|
72
|
+
"text": "Accessible label for the menu, reflected as `aria-label` on the host Element.\nWhen absent, `aria-label` is not rendered on the host."
|
|
73
|
+
},
|
|
74
|
+
"getter": false,
|
|
75
|
+
"setter": false,
|
|
76
|
+
"reflect": false,
|
|
77
|
+
"attribute": "label"
|
|
78
|
+
}
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
static get elementRef() { return "el"; }
|
|
82
|
+
}
|
|
83
|
+
function collectInteractiveButtonsRecursively(el, collection) {
|
|
84
|
+
const tag = el.tagName.toLowerCase();
|
|
85
|
+
if (tag === 'lmvz-button') {
|
|
86
|
+
el.buttonRole = 'menuitem';
|
|
87
|
+
collection.push(el);
|
|
88
|
+
return;
|
|
89
|
+
}
|
|
90
|
+
if (tag === 'button') {
|
|
91
|
+
el.setAttribute('role', 'menuitem');
|
|
92
|
+
collection.push(el);
|
|
93
|
+
return;
|
|
94
|
+
}
|
|
95
|
+
if (tag === 'hr') {
|
|
96
|
+
return;
|
|
97
|
+
}
|
|
98
|
+
if (el.getAttribute('role') === 'group') {
|
|
99
|
+
const children = el.querySelectorAll('lmvz-button, button');
|
|
100
|
+
children.forEach((child) => collectInteractiveButtonsRecursively(child, collection));
|
|
101
|
+
return;
|
|
102
|
+
}
|
|
103
|
+
console.warn('Unexpected element encountered in ActionList:', tag);
|
|
104
|
+
}
|
|
@@ -55,23 +55,34 @@ h6 {
|
|
|
55
55
|
display: none !important;
|
|
56
56
|
}
|
|
57
57
|
|
|
58
|
+
hr {
|
|
59
|
+
height: 0;
|
|
60
|
+
border: none;
|
|
61
|
+
margin: var(--lmvz-dimension-4-8, clamp(0.25rem, 0.19rem + 0.26vw, 0.5rem)) 0;
|
|
62
|
+
border-top: var(--lmvz-semantic-border-width-default, 1px) solid var(--lmvz-semantic-color-border-subtle, #f0f0f0);
|
|
63
|
+
}
|
|
64
|
+
|
|
58
65
|
}
|
|
59
66
|
:host {
|
|
60
67
|
/* * the (invalid nested) import will be handled by postcss */
|
|
61
68
|
/* stylelint-disable-next-line no-invalid-position-at-import-rule */
|
|
62
69
|
button {
|
|
63
70
|
/* secondary styling is default, primary is explicit */
|
|
64
|
-
--lmvz-button-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
--lmvz-button-
|
|
69
|
-
--lmvz-button-
|
|
70
|
-
|
|
71
|
-
--lmvz-button-
|
|
72
|
-
--lmvz-button-
|
|
73
|
-
--lmvz-button-
|
|
74
|
-
--lmvz-button-
|
|
71
|
+
/* --lmvz-button-background, --lmvz-button-color, --lmvz-button-radius are declared on :host
|
|
72
|
+
so that outer ::slotted(lmvz-button) overrides are inherited correctly via shadow inheritance.
|
|
73
|
+
They are also declared here so that non-shadow consumers (e.g. @lmvz-ds/styles buttons.css
|
|
74
|
+
bundle and lmvz-card) have the default values in scope. */
|
|
75
|
+
--lmvz-button-background: var(--lmvz-button-background-override, var(--lmvz-semantic-color-int-secondary, #f0f0f0));
|
|
76
|
+
--lmvz-button-color: var(--lmvz-button-color-override, var(--lmvz-semantic-color-int-on-secondary, #000000));
|
|
77
|
+
--lmvz-button-radius: var(--lmvz-button-radius-override, var(--lmvz-component-input-radius-default, 999px));
|
|
78
|
+
--lmvz-button-padding-inline: var(--lmvz-button-padding-inline-override, var(--lmvz-button-padding, var(--lmvz-component-input-padding-md, clamp(0.88rem, 0.84rem + 0.13vw, 1rem))));
|
|
79
|
+
--lmvz-button-padding-block: var(--lmvz-button-padding-block-override, var(--lmvz-button-padding, var(--lmvz-component-input-padding-md, clamp(0.88rem, 0.84rem + 0.13vw, 1rem))));
|
|
80
|
+
--lmvz-button-gap: var(--lmvz-button-gap-override, var(--lmvz-component-input-gap-md, clamp(0.5rem, 0.44rem + 0.26vw, 0.75rem)));
|
|
81
|
+
--lmvz-button-min-height: var(--lmvz-button-min-height-override, var(--lmvz-component-input-size-md, clamp(2.5rem, 2.44rem + 0.26vw, 2.75rem)));
|
|
82
|
+
--lmvz-button-font: var(--lmvz-button-font-override, var(--lmvz-typography-body-md-strong, 500 clamp(0.88rem, 0.84rem + 0.13vw, 1rem) / 1.5
|
|
83
|
+
Router));
|
|
84
|
+
--lmvz-button-border-width: var(--lmvz-button-border-width-override, 0);
|
|
85
|
+
--lmvz-button-border-color: var(--lmvz-button-border-color-override, transparent);
|
|
75
86
|
|
|
76
87
|
display: inline-flex;
|
|
77
88
|
align-items: center;
|
|
@@ -104,6 +115,8 @@ button > * {
|
|
|
104
115
|
button:focus-visible {
|
|
105
116
|
outline: var(--lmvz-ds-outline, 1px solid #0e7ab4);
|
|
106
117
|
outline-offset: var(--lmvz-ds-outline-offset, clamp(0.25rem, 0.19rem + 0.26vw, 0.5rem));
|
|
118
|
+
position: relative;
|
|
119
|
+
z-index: 1;
|
|
107
120
|
}
|
|
108
121
|
|
|
109
122
|
button:is([disabled], .disabled) {
|
|
@@ -119,80 +132,87 @@ button:is([disabled], .disabled) {
|
|
|
119
132
|
}
|
|
120
133
|
|
|
121
134
|
button:not([disabled]):hover {
|
|
122
|
-
--lmvz-button-background: var(--lmvz-semantic-color-int-secondary-hover, #e0e0e0);
|
|
135
|
+
--lmvz-button-background: var(--lmvz-button-background-override, var(--lmvz-semantic-color-int-secondary-hover, #e0e0e0));
|
|
123
136
|
}
|
|
124
137
|
|
|
125
138
|
button:not([disabled]):active {
|
|
126
|
-
--lmvz-button-background: var(--lmvz-semantic-color-int-secondary-active, #d4d4d4);
|
|
139
|
+
--lmvz-button-background: var(--lmvz-button-background-override, var(--lmvz-semantic-color-int-secondary-active, #d4d4d4));
|
|
127
140
|
}
|
|
128
141
|
|
|
129
142
|
button.primary {
|
|
130
|
-
--lmvz-button-background: var(--lmvz-semantic-color-int-primary, #000000);
|
|
131
|
-
--lmvz-button-color: var(--lmvz-semantic-color-int-on-primary, #ffffff);
|
|
132
|
-
--lmvz-button-border-width: 0;
|
|
133
|
-
--lmvz-button-border-color: transparent;
|
|
143
|
+
--lmvz-button-background: var(--lmvz-button-background-override, var(--lmvz-semantic-color-int-primary, #000000));
|
|
144
|
+
--lmvz-button-color: var(--lmvz-button-color-override, var(--lmvz-semantic-color-int-on-primary, #ffffff));
|
|
145
|
+
--lmvz-button-border-width: var(--lmvz-button-border-width-override, 0);
|
|
146
|
+
--lmvz-button-border-color: var(--lmvz-button-border-color-override, transparent);
|
|
134
147
|
}
|
|
135
148
|
|
|
136
149
|
button.primary:not([disabled], .disabled):hover {
|
|
137
|
-
--lmvz-button-background: var(--lmvz-semantic-color-int-primary-hover, #2e2e2e);
|
|
150
|
+
--lmvz-button-background: var(--lmvz-button-background-override, var(--lmvz-semantic-color-int-primary-hover, #2e2e2e));
|
|
138
151
|
}
|
|
139
152
|
|
|
140
153
|
button.primary:not([disabled], .disabled):active {
|
|
141
|
-
--lmvz-button-background: var(--lmvz-semantic-color-int-primary-active, #545454);
|
|
154
|
+
--lmvz-button-background: var(--lmvz-button-background-override, var(--lmvz-semantic-color-int-primary-active, #545454));
|
|
142
155
|
}
|
|
143
156
|
|
|
144
157
|
button.secondary {
|
|
145
|
-
--lmvz-button-background: var(--lmvz-semantic-color-int-secondary, #f0f0f0);
|
|
146
|
-
--lmvz-button-color: var(--lmvz-semantic-color-int-on-secondary, #000000);
|
|
147
|
-
--lmvz-button-border-width: 0;
|
|
148
|
-
--lmvz-button-border-color: transparent;
|
|
158
|
+
--lmvz-button-background: var(--lmvz-button-background-override, var(--lmvz-semantic-color-int-secondary, #f0f0f0));
|
|
159
|
+
--lmvz-button-color: var(--lmvz-button-color-override, var(--lmvz-semantic-color-int-on-secondary, #000000));
|
|
160
|
+
--lmvz-button-border-width: var(--lmvz-button-border-width-override, 0);
|
|
161
|
+
--lmvz-button-border-color: var(--lmvz-button-border-color-override, transparent);
|
|
149
162
|
}
|
|
150
163
|
|
|
151
164
|
button.secondary:not([disabled], .disabled):hover {
|
|
152
|
-
--lmvz-button-background: var(--lmvz-semantic-color-int-secondary-hover, #e0e0e0);
|
|
153
|
-
--lmvz-button-color: var(--lmvz-semantic-color-int-on-secondary-hover, #000000);
|
|
165
|
+
--lmvz-button-background: var(--lmvz-button-background-override, var(--lmvz-semantic-color-int-secondary-hover, #e0e0e0));
|
|
166
|
+
--lmvz-button-color: var(--lmvz-button-color-override, var(--lmvz-semantic-color-int-on-secondary-hover, #000000));
|
|
154
167
|
}
|
|
155
168
|
|
|
156
169
|
button.secondary:not([disabled], .disabled):active {
|
|
157
|
-
--lmvz-button-background: var(--lmvz-semantic-color-int-secondary-active, #d4d4d4);
|
|
158
|
-
--lmvz-button-color: var(--lmvz-semantic-color-int-on-secondary-active, #000000);
|
|
170
|
+
--lmvz-button-background: var(--lmvz-button-background-override, var(--lmvz-semantic-color-int-secondary-active, #d4d4d4));
|
|
171
|
+
--lmvz-button-color: var(--lmvz-button-color-override, var(--lmvz-semantic-color-int-on-secondary-active, #000000));
|
|
159
172
|
}
|
|
160
173
|
|
|
161
174
|
button.tertiary {
|
|
162
|
-
--lmvz-button-background: var(--lmvz-semantic-color-int-tertiary, #ffffff);
|
|
163
|
-
--lmvz-button-color: var(--lmvz-semantic-color-int-on-tertiary, #000000);
|
|
175
|
+
--lmvz-button-background: var(--lmvz-button-background-override, var(--lmvz-semantic-color-int-tertiary, #ffffff));
|
|
176
|
+
--lmvz-button-color: var(--lmvz-button-color-override, var(--lmvz-semantic-color-int-on-tertiary, #000000));
|
|
164
177
|
}
|
|
165
178
|
|
|
166
179
|
button.tertiary:not([disabled], .disabled):hover {
|
|
167
|
-
--lmvz-button-background: var(--lmvz-semantic-color-int-tertiary-hover, #f0f0f0);
|
|
168
|
-
--lmvz-button-color: var(--lmvz-semantic-color-int-on-tertiary-hover, #000000);
|
|
180
|
+
--lmvz-button-background: var(--lmvz-button-background-override, var(--lmvz-semantic-color-int-tertiary-hover, #f0f0f0));
|
|
181
|
+
--lmvz-button-color: var(--lmvz-button-color-override, var(--lmvz-semantic-color-int-on-tertiary-hover, #000000));
|
|
169
182
|
}
|
|
170
183
|
|
|
171
184
|
button.tertiary:not([disabled], .disabled):active {
|
|
172
|
-
--lmvz-button-background: var(--lmvz-semantic-color-int-tertiary-active, #e0e0e0);
|
|
173
|
-
--lmvz-button-color: var(--lmvz-semantic-color-int-on-tertiary-active, #000000);
|
|
185
|
+
--lmvz-button-background: var(--lmvz-button-background-override, var(--lmvz-semantic-color-int-tertiary-active, #e0e0e0));
|
|
186
|
+
--lmvz-button-color: var(--lmvz-button-color-override, var(--lmvz-semantic-color-int-on-tertiary-active, #000000));
|
|
174
187
|
}
|
|
175
188
|
|
|
176
189
|
button.small {
|
|
177
|
-
--lmvz-button-padding-inline: var(--lmvz-component-input-padding-sm, clamp(0.75rem, 0.72rem + 0.13vw, 0.88rem));
|
|
178
|
-
--lmvz-button-padding-block: var(--lmvz-component-input-padding-sm, clamp(0.75rem, 0.72rem + 0.13vw, 0.88rem));
|
|
179
|
-
--lmvz-button-gap: var(--lmvz-component-input-gap-sm, clamp(0.38rem, 0.31rem + 0.26vw, 0.63rem));
|
|
180
|
-
--lmvz-button-min-height: var(--lmvz-component-input-size-sm, clamp(2rem, 1.94rem + 0.26vw, 2.25rem));
|
|
181
|
-
--lmvz-button-font: var(--lmvz-typography-body-sm-strong, 500 clamp(0.69rem, 0.67rem + 0.06vw, 0.75rem) / 1.5
|
|
182
|
-
Router);
|
|
190
|
+
--lmvz-button-padding-inline: var(--lmvz-button-padding-inline-override, var(--lmvz-component-input-padding-sm, clamp(0.75rem, 0.72rem + 0.13vw, 0.88rem)));
|
|
191
|
+
--lmvz-button-padding-block: var(--lmvz-button-padding-block-override, var(--lmvz-component-input-padding-sm, clamp(0.75rem, 0.72rem + 0.13vw, 0.88rem)));
|
|
192
|
+
--lmvz-button-gap: var(--lmvz-button-gap-override, var(--lmvz-component-input-gap-sm, clamp(0.38rem, 0.31rem + 0.26vw, 0.63rem)));
|
|
193
|
+
--lmvz-button-min-height: var(--lmvz-button-min-height-override, var(--lmvz-component-input-size-sm, clamp(2rem, 1.94rem + 0.26vw, 2.25rem)));
|
|
194
|
+
--lmvz-button-font: var(--lmvz-button-font-override, var(--lmvz-typography-body-sm-strong, 500 clamp(0.69rem, 0.67rem + 0.06vw, 0.75rem) / 1.5
|
|
195
|
+
Router));
|
|
183
196
|
}
|
|
184
197
|
|
|
185
198
|
button.large {
|
|
186
|
-
--lmvz-button-padding-inline: var(--lmvz-component-input-padding-lg, clamp(1rem, 0.94rem + 0.26vw, 1.25rem));
|
|
187
|
-
--lmvz-button-padding-block: var(--lmvz-component-input-padding-lg, clamp(1rem, 0.94rem + 0.26vw, 1.25rem));
|
|
188
|
-
--lmvz-button-gap: var(--lmvz-component-input-gap-lg, clamp(0.75rem, 0.69rem + 0.26vw, 1rem));
|
|
189
|
-
--lmvz-button-min-height: var(--lmvz-component-input-size-lg, clamp(2.75rem, 2.69rem + 0.26vw, 3rem));
|
|
190
|
-
--lmvz-button-font: var(--lmvz-typography-body-lg-strong, 500 clamp(1rem, 0.97rem + 0.13vw, 1.13rem) / 1.5
|
|
191
|
-
Router);
|
|
199
|
+
--lmvz-button-padding-inline: var(--lmvz-button-padding-inline-override, var(--lmvz-component-input-padding-lg, clamp(1rem, 0.94rem + 0.26vw, 1.25rem)));
|
|
200
|
+
--lmvz-button-padding-block: var(--lmvz-button-padding-block-override, var(--lmvz-component-input-padding-lg, clamp(1rem, 0.94rem + 0.26vw, 1.25rem)));
|
|
201
|
+
--lmvz-button-gap: var(--lmvz-button-gap-override, var(--lmvz-component-input-gap-lg, clamp(0.75rem, 0.69rem + 0.26vw, 1rem)));
|
|
202
|
+
--lmvz-button-min-height: var(--lmvz-button-min-height-override, var(--lmvz-component-input-size-lg, clamp(2.75rem, 2.69rem + 0.26vw, 3rem)));
|
|
203
|
+
--lmvz-button-font: var(--lmvz-button-font-override, var(--lmvz-typography-body-lg-strong, 500 clamp(1rem, 0.97rem + 0.13vw, 1.13rem) / 1.5
|
|
204
|
+
Router));
|
|
192
205
|
}
|
|
193
206
|
|
|
194
207
|
|
|
195
208
|
display: inline-block;
|
|
209
|
+
|
|
210
|
+
button {
|
|
211
|
+
width: 100%;
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
button {
|
|
215
|
+
width: 100%;
|
|
196
216
|
}
|
|
197
217
|
::slotted(*) {
|
|
198
218
|
--lmvz-component-color: var(--lmvz-button-color);
|
|
@@ -2,8 +2,8 @@ import { Host, h } from "@stencil/core";
|
|
|
2
2
|
import classNames from "classnames";
|
|
3
3
|
import { AriaValidationController } from "../../utils/aria/aria-validation-controller";
|
|
4
4
|
import { ElementActivationController } from "../../utils/aria/element-activation-controller";
|
|
5
|
-
import { findFormByRef, inheritAriaAttributes } from "../../utils/
|
|
6
|
-
import { ReactiveControllerHost } from "../../utils/reactive-controller-host";
|
|
5
|
+
import { findFormByRef, inheritAriaAttributes } from "../../utils/element/element.util";
|
|
6
|
+
import { ReactiveControllerHost } from "../../utils/stencil/reactive-controller-host";
|
|
7
7
|
export class LmvzButton extends ReactiveControllerHost {
|
|
8
8
|
el;
|
|
9
9
|
validationEl;
|
|
@@ -11,8 +11,9 @@ export class LmvzButton extends ReactiveControllerHost {
|
|
|
11
11
|
formEl = null;
|
|
12
12
|
formButtonEl = null;
|
|
13
13
|
lmvzActivation;
|
|
14
|
-
|
|
15
|
-
|
|
14
|
+
ti = 0;
|
|
15
|
+
resolveFocusableElement() {
|
|
16
|
+
return this.validationEl;
|
|
16
17
|
}
|
|
17
18
|
scale = 'default';
|
|
18
19
|
variant;
|
|
@@ -22,6 +23,7 @@ export class LmvzButton extends ReactiveControllerHost {
|
|
|
22
23
|
formMethod;
|
|
23
24
|
name;
|
|
24
25
|
value;
|
|
26
|
+
buttonRole;
|
|
25
27
|
constructor() {
|
|
26
28
|
super();
|
|
27
29
|
this.addController(new AriaValidationController(this));
|
|
@@ -31,7 +33,7 @@ export class LmvzButton extends ReactiveControllerHost {
|
|
|
31
33
|
}));
|
|
32
34
|
}
|
|
33
35
|
connectedCallback() {
|
|
34
|
-
this.inheritedAttributes = inheritAriaAttributes(this.el);
|
|
36
|
+
this.inheritedAttributes = inheritAriaAttributes(this.el, ['role']);
|
|
35
37
|
super.connectedCallback();
|
|
36
38
|
}
|
|
37
39
|
disconnectedCallback() {
|
|
@@ -88,7 +90,7 @@ export class LmvzButton extends ReactiveControllerHost {
|
|
|
88
90
|
};
|
|
89
91
|
render() {
|
|
90
92
|
this.renderHiddenButton();
|
|
91
|
-
return (h(Host, { key: '
|
|
93
|
+
return (h(Host, { key: 'f3e619dca398c3a8a78e9d2f8c3df4178b2531b2', role: "presentation" }, h("button", { key: 'eb1aac6756a70968d3a72cb40c1d52d96340423e', ref: (e) => (this.validationEl = e), part: "button", role: this.buttonRole, disabled: this.disabled, type: this.type, class: classNames(this.variant ?? 'secondary', { [this.scale ?? '']: !!this.scale, disabled: this.disabled }), ...this.inheritedAttributes }, h("slot", { key: '786ff1c10ae05eda646c77ac8779813be6e51949' }))));
|
|
92
94
|
}
|
|
93
95
|
static get is() { return "lmvz-button"; }
|
|
94
96
|
static get encapsulation() { return "shadow"; }
|
|
@@ -119,7 +121,7 @@ export class LmvzButton extends ReactiveControllerHost {
|
|
|
119
121
|
"tags": [],
|
|
120
122
|
"text": ""
|
|
121
123
|
},
|
|
122
|
-
"getter":
|
|
124
|
+
"getter": false,
|
|
123
125
|
"setter": false,
|
|
124
126
|
"reflect": true,
|
|
125
127
|
"attribute": "tabindex",
|
|
@@ -312,6 +314,25 @@ export class LmvzButton extends ReactiveControllerHost {
|
|
|
312
314
|
"setter": false,
|
|
313
315
|
"reflect": false,
|
|
314
316
|
"attribute": "value"
|
|
317
|
+
},
|
|
318
|
+
"buttonRole": {
|
|
319
|
+
"type": "string",
|
|
320
|
+
"mutable": false,
|
|
321
|
+
"complexType": {
|
|
322
|
+
"original": "string",
|
|
323
|
+
"resolved": "string | undefined",
|
|
324
|
+
"references": {}
|
|
325
|
+
},
|
|
326
|
+
"required": false,
|
|
327
|
+
"optional": true,
|
|
328
|
+
"docs": {
|
|
329
|
+
"tags": [],
|
|
330
|
+
"text": "ARIA role applied to the inner `<button>` element.\nWhen set, the host element receives `role=\"presentation\"` so that AT\nsees only one interactive element with the correct role.\nUse `\"menuitem\"` when the button is a child of a `role=\"menu\"` container."
|
|
331
|
+
},
|
|
332
|
+
"getter": false,
|
|
333
|
+
"setter": false,
|
|
334
|
+
"reflect": false,
|
|
335
|
+
"attribute": "button-role"
|
|
315
336
|
}
|
|
316
337
|
};
|
|
317
338
|
}
|
|
@@ -1,14 +1,45 @@
|
|
|
1
1
|
:host {
|
|
2
2
|
display: flex;
|
|
3
|
-
|
|
3
|
+
flex-flow: row-reverse wrap;
|
|
4
4
|
gap: var(--lmvz-component-input-gap-md, clamp(0.5rem, 0.44rem + 0.26vw, 0.75rem));
|
|
5
5
|
font: var(--lmvz-typography-body-md, 400 clamp(0.88rem, 0.84rem + 0.13vw, 1rem) / 1.5
|
|
6
6
|
Router);
|
|
7
7
|
|
|
8
8
|
/* TODO(LDHCID-135): Action wrapping threshold remains an assumption and currently follows intrinsic content width */
|
|
9
|
-
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
:host([stacked]) {
|
|
12
|
+
flex-flow: column nowrap;
|
|
13
|
+
align-items: stretch;
|
|
14
|
+
padding: 0;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
:host([stacked]) ::slotted(*) {
|
|
18
|
+
display: block;
|
|
19
|
+
width: 100%;
|
|
10
20
|
}
|
|
11
21
|
|
|
12
22
|
::slotted([hidden]) {
|
|
13
23
|
display: none !important;
|
|
14
24
|
}
|
|
25
|
+
|
|
26
|
+
/*
|
|
27
|
+
* Non-stacked alignment split: push tertiary cluster to the right, primary/secondary stays left.
|
|
28
|
+
*
|
|
29
|
+
* OQ-A1 resolution: margin-inline-end: auto is used (not margin-inline-start).
|
|
30
|
+
* The host uses flex-flow: row-reverse, so the flex main axis runs right→left
|
|
31
|
+
* (main-start is on the right, main-end is on the left in LTR).
|
|
32
|
+
* Tertiary buttons appear last in DOM but are rendered leftmost by row-reverse.
|
|
33
|
+
* Applying margin-inline-end: auto on the tertiary items creates an auto margin on
|
|
34
|
+
* their inline-end side (right in LTR), which corresponds to the flex main-start
|
|
35
|
+
* direction — this absorbs all available space between the p/s cluster and the
|
|
36
|
+
* tertiary cluster, pushing tertiary visually to the right as intended.
|
|
37
|
+
*/
|
|
38
|
+
|
|
39
|
+
:host(:not([data-only-tertiary], [stacked])) ::slotted([data-first-tertiary]) {
|
|
40
|
+
margin-inline-end: auto;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
:host([data-only-tertiary]:not([stacked])) {
|
|
44
|
+
justify-content: flex-end;
|
|
45
|
+
}
|
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
import { h, Host } from "@stencil/core";
|
|
2
2
|
import { negate } from "@lmvz-ds/lib-ts/stream/negate.js";
|
|
3
|
-
import { isAriaValidationEnabled } from "../..";
|
|
4
|
-
import { canReceiveFocus } from "../../utils/
|
|
3
|
+
import { isAriaValidationEnabled, variants } from "../..";
|
|
4
|
+
import { canReceiveFocus, isActionButton, isDisabledButton, isLmvzButton, isPrimaryAction, isSecondaryAction, isVisible } from "../../utils/element/element.util";
|
|
5
5
|
export class LmvzButtonGroup {
|
|
6
|
+
el;
|
|
6
7
|
actionsSlot;
|
|
7
8
|
validationMessageCache = [];
|
|
8
9
|
actionsStateObserver;
|
|
10
|
+
stacked = false;
|
|
9
11
|
get primaryEnabledAction() {
|
|
10
12
|
return this.enabledButtons.find(isPrimaryAction) ?? this.enabledButtons[0];
|
|
11
13
|
}
|
|
@@ -37,23 +39,23 @@ export class LmvzButtonGroup {
|
|
|
37
39
|
const primaryActions = this.visibleButtons.filter(isPrimaryAction);
|
|
38
40
|
const secondaryActions = this.visibleButtons.filter(isSecondaryAction);
|
|
39
41
|
const issues = [];
|
|
40
|
-
const order = this.visibleButtons
|
|
42
|
+
const order = this.visibleButtons;
|
|
41
43
|
if (primaryActions.length !== 1)
|
|
42
|
-
issues.push('
|
|
44
|
+
issues.push('LmvzButtonGroup actions slot should contain exactly one primary action.');
|
|
43
45
|
if (secondaryActions.length > 1)
|
|
44
|
-
issues.push(`
|
|
46
|
+
issues.push(`LmvzButtonGroup actions slot should contain at most one secondary action (received ${secondaryActions.length})`);
|
|
45
47
|
if (primaryActions.length) {
|
|
46
48
|
const primaryAction = primaryActions[0];
|
|
47
49
|
const secondaryAction = secondaryActions[0];
|
|
48
50
|
if (order.indexOf(primaryAction) !== 0)
|
|
49
|
-
issues.push('Primary action
|
|
51
|
+
issues.push('Primary action should be the first focusable element in the actions slot (i.e. first child of the actions slot).');
|
|
50
52
|
if (secondaryAction && order.indexOf(secondaryAction) !== 1)
|
|
51
|
-
issues.push('Secondary action
|
|
53
|
+
issues.push('Secondary action should be the second focusable element in the actions slot (i.e. immediately after the primary button).');
|
|
52
54
|
}
|
|
53
55
|
else if (secondaryActions.length) {
|
|
54
56
|
const secondaryAction = secondaryActions[0];
|
|
55
57
|
if (order.indexOf(secondaryAction) !== 0)
|
|
56
|
-
issues.push('Secondary action
|
|
58
|
+
issues.push('Secondary action should be the first focusable element in the actions slot when no primary action is present (i.e. first child of the actions slot).');
|
|
57
59
|
}
|
|
58
60
|
return issues;
|
|
59
61
|
}
|
|
@@ -91,20 +93,35 @@ export class LmvzButtonGroup {
|
|
|
91
93
|
}
|
|
92
94
|
});
|
|
93
95
|
this.checkActions();
|
|
94
|
-
const
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
96
|
+
const visibleButtons = this.visibleButtons;
|
|
97
|
+
const hasNonTertiary = visibleButtons.length > 0 && visibleButtons.some((btn) => isPrimaryAction(btn) || isSecondaryAction(btn));
|
|
98
|
+
if (visibleButtons.length > 0 && !hasNonTertiary) {
|
|
99
|
+
this.el.setAttribute('data-only-tertiary', '');
|
|
100
|
+
}
|
|
101
|
+
else {
|
|
102
|
+
this.el.removeAttribute('data-only-tertiary');
|
|
103
|
+
}
|
|
104
|
+
this.visibleButtons.forEach((element, i) => {
|
|
105
|
+
const variant = variants[i] ?? 'tertiary';
|
|
98
106
|
if (!element)
|
|
99
|
-
|
|
107
|
+
return;
|
|
100
108
|
if (isLmvzButton(element)) {
|
|
101
|
-
if (!element.getAttribute('variant'))
|
|
109
|
+
if (!element.getAttribute('variant') && !element.variant)
|
|
102
110
|
element.setAttribute('variant', variant);
|
|
103
111
|
}
|
|
104
112
|
else {
|
|
105
113
|
element.classList.add(variant);
|
|
106
114
|
}
|
|
107
|
-
}
|
|
115
|
+
});
|
|
116
|
+
const firstTertiary = this.visibleButtons.find((btn) => btn.getAttribute('variant') === 'tertiary');
|
|
117
|
+
this.visibleButtons.forEach((btn) => {
|
|
118
|
+
if (btn === firstTertiary) {
|
|
119
|
+
btn.setAttribute('data-first-tertiary', '');
|
|
120
|
+
}
|
|
121
|
+
else {
|
|
122
|
+
btn.removeAttribute('data-first-tertiary');
|
|
123
|
+
}
|
|
124
|
+
});
|
|
108
125
|
this.focusPrimaryAction();
|
|
109
126
|
}
|
|
110
127
|
focusPrimaryAction() {
|
|
@@ -132,7 +149,7 @@ export class LmvzButtonGroup {
|
|
|
132
149
|
});
|
|
133
150
|
}
|
|
134
151
|
render() {
|
|
135
|
-
return (h(Host, { key: '
|
|
152
|
+
return (h(Host, { key: '3e8ce38f7e83e201e47d31579f22161ff36247b1' }, h("slot", { key: 'bc953d19b333f51c5f5c5ba86be3a85d155a29d1', ref: (element) => (this.actionsSlot = element), onSlotchange: this.handleActionsSlotChange })));
|
|
136
153
|
}
|
|
137
154
|
static get is() { return "lmvz-button-group"; }
|
|
138
155
|
static get encapsulation() { return "shadow"; }
|
|
@@ -148,6 +165,26 @@ export class LmvzButtonGroup {
|
|
|
148
165
|
}
|
|
149
166
|
static get properties() {
|
|
150
167
|
return {
|
|
168
|
+
"stacked": {
|
|
169
|
+
"type": "boolean",
|
|
170
|
+
"mutable": false,
|
|
171
|
+
"complexType": {
|
|
172
|
+
"original": "boolean",
|
|
173
|
+
"resolved": "boolean",
|
|
174
|
+
"references": {}
|
|
175
|
+
},
|
|
176
|
+
"required": false,
|
|
177
|
+
"optional": false,
|
|
178
|
+
"docs": {
|
|
179
|
+
"tags": [],
|
|
180
|
+
"text": ""
|
|
181
|
+
},
|
|
182
|
+
"getter": false,
|
|
183
|
+
"setter": false,
|
|
184
|
+
"reflect": true,
|
|
185
|
+
"attribute": "stacked",
|
|
186
|
+
"defaultValue": "false"
|
|
187
|
+
},
|
|
151
188
|
"primaryEnabledAction": {
|
|
152
189
|
"type": "unknown",
|
|
153
190
|
"mutable": false,
|
|
@@ -191,26 +228,5 @@ export class LmvzButtonGroup {
|
|
|
191
228
|
}
|
|
192
229
|
};
|
|
193
230
|
}
|
|
194
|
-
}
|
|
195
|
-
function isActionButton(element) {
|
|
196
|
-
return ['LMVZ-BUTTON', 'BUTTON'].includes(element.tagName.toUpperCase());
|
|
197
|
-
}
|
|
198
|
-
function isLmvzButton(element) {
|
|
199
|
-
return element?.tagName.toUpperCase() === 'LMVZ-BUTTON';
|
|
200
|
-
}
|
|
201
|
-
function isDisabledButton(element) {
|
|
202
|
-
return element.hasAttribute('disabled') || element.disabled === true;
|
|
203
|
-
}
|
|
204
|
-
function isVisible(element) {
|
|
205
|
-
return !element.hasAttribute('hidden');
|
|
206
|
-
}
|
|
207
|
-
function getActionVariant(element) {
|
|
208
|
-
const variant = element.getAttribute('variant') ?? element.variant;
|
|
209
|
-
return variant === 'primary' || variant === 'secondary' || variant === 'tertiary' ? variant : 'secondary';
|
|
210
|
-
}
|
|
211
|
-
function isPrimaryAction(element) {
|
|
212
|
-
return getActionVariant(element) === 'primary';
|
|
213
|
-
}
|
|
214
|
-
function isSecondaryAction(element) {
|
|
215
|
-
return getActionVariant(element) === 'secondary';
|
|
231
|
+
static get elementRef() { return "el"; }
|
|
216
232
|
}
|