@momentum-design/components 0.118.4 → 0.118.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/browser/index.js +259 -263
- package/dist/browser/index.js.map +4 -4
- package/dist/components/checkbox/checkbox.component.js +2 -2
- package/dist/components/checkbox/checkbox.styles.js +13 -8
- package/dist/components/combobox/combobox.component.js +1 -1
- package/dist/components/formfieldgroup/formfieldgroup.styles.js +0 -4
- package/dist/components/formfieldwrapper/formfieldwrapper.component.d.ts +2 -2
- package/dist/components/formfieldwrapper/formfieldwrapper.component.js +5 -7
- package/dist/components/formfieldwrapper/formfieldwrapper.styles.js +22 -16
- package/dist/components/popover/index.js +2 -0
- package/dist/components/popover/popover.component.d.ts +44 -8
- package/dist/components/popover/popover.component.js +53 -11
- package/dist/components/popover/popover.portal.component.d.ts +29 -0
- package/dist/components/popover/popover.portal.component.js +37 -0
- package/dist/components/popover/popover.utils.d.ts +15 -0
- package/dist/components/popover/popover.utils.js +32 -3
- package/dist/components/progressbar/progressbar.styles.js +3 -5
- package/dist/components/radio/radio.component.js +2 -2
- package/dist/components/radio/radio.styles.js +8 -12
- package/dist/components/toggle/toggle.component.d.ts +0 -3
- package/dist/components/toggle/toggle.component.js +0 -3
- package/dist/components/toggle/toggle.styles.js +11 -14
- package/dist/custom-elements.json +355 -347
- package/dist/react/index.d.ts +2 -2
- package/dist/react/index.js +2 -2
- package/dist/react/popover/index.d.ts +43 -7
- package/dist/react/popover/index.js +43 -7
- package/dist/react/toggle/index.d.ts +0 -3
- package/dist/react/toggle/index.js +0 -3
- package/package.json +1 -1
@@ -73,7 +73,7 @@ class Checkbox extends AutoFocusOnMountMixin(FormInternalsMixin(DataAriaLabelMix
|
|
73
73
|
this.renderLabelAndHelperText = () => {
|
74
74
|
if (!this.label)
|
75
75
|
return nothing;
|
76
|
-
return html `<div
|
76
|
+
return html `<div part="text-container">${this.renderLabel()} ${this.renderHelperText()}</div>`;
|
77
77
|
};
|
78
78
|
}
|
79
79
|
connectedCallback() {
|
@@ -187,7 +187,7 @@ class Checkbox extends AutoFocusOnMountMixin(FormInternalsMixin(DataAriaLabelMix
|
|
187
187
|
<input
|
188
188
|
id="${this.inputId}"
|
189
189
|
type="checkbox"
|
190
|
-
|
190
|
+
part="checkbox-input"
|
191
191
|
name="${ifDefined(this.name)}"
|
192
192
|
value="${ifDefined(this.value)}"
|
193
193
|
?required="${this.required}"
|
@@ -12,13 +12,18 @@ const styles = [
|
|
12
12
|
flex-direction: row;
|
13
13
|
align-items: flex-start;
|
14
14
|
}
|
15
|
-
|
16
|
-
|
15
|
+
|
16
|
+
:host::part(label) {
|
17
|
+
font-size: var(--mds-font-apps-body-midsize-regular-font-size);
|
18
|
+
font-weight: var(--mds-font-apps-body-midsize-regular-font-weight);
|
19
|
+
line-height: var(--mds-font-apps-body-midsize-regular-line-height);
|
20
|
+
}
|
21
|
+
|
22
|
+
:host::part(label) :host::part(checkbox-input) {
|
17
23
|
cursor: pointer;
|
18
24
|
}
|
19
25
|
|
20
|
-
:host([disabled])
|
21
|
-
:host([disabled]) .input {
|
26
|
+
:host([disabled])::part(label) :host([disabled])::part(checkbox-input) {
|
22
27
|
cursor: default;
|
23
28
|
}
|
24
29
|
|
@@ -51,7 +56,7 @@ const styles = [
|
|
51
56
|
position: relative;
|
52
57
|
}
|
53
58
|
|
54
|
-
|
59
|
+
:host::part(checkbox-input) {
|
55
60
|
margin: 0;
|
56
61
|
padding: 0;
|
57
62
|
position: absolute;
|
@@ -62,19 +67,19 @@ const styles = [
|
|
62
67
|
z-index: 1;
|
63
68
|
}
|
64
69
|
|
65
|
-
|
70
|
+
:host::part(checkbox-input) {
|
66
71
|
width: 1rem;
|
67
72
|
height: 1rem;
|
68
73
|
border-radius: 0.125rem;
|
69
74
|
}
|
70
75
|
|
71
|
-
|
76
|
+
:host::part(text-container) {
|
72
77
|
display: flex;
|
73
78
|
flex-direction: column;
|
74
79
|
gap: 0.25rem;
|
75
80
|
}
|
76
81
|
|
77
|
-
|
82
|
+
:host::part(label) {
|
78
83
|
word-break: break-word;
|
79
84
|
white-space: normal;
|
80
85
|
}
|
@@ -692,7 +692,7 @@ class Combobox extends CaptureDestroyEventForChildElement(AutoFocusOnMountMixin(
|
|
692
692
|
`;
|
693
693
|
}
|
694
694
|
}
|
695
|
-
Combobox.styles = [...
|
695
|
+
Combobox.styles = [...Input.styles, ...FormfieldWrapper.styles, ...styles];
|
696
696
|
__decorate([
|
697
697
|
property({ type: String }),
|
698
698
|
__metadata("design:type", String)
|
@@ -82,12 +82,12 @@ declare class FormfieldWrapper extends FormfieldWrapper_base {
|
|
82
82
|
*/
|
83
83
|
protected renderHelpText(): import("lit-html").TemplateResult<1> | typeof nothing;
|
84
84
|
/**
|
85
|
-
* renders the
|
85
|
+
* renders the label container that contains the label and labelInfoToggleTip.
|
86
86
|
* @returns void
|
87
87
|
*/
|
88
88
|
protected renderLabel(): import("lit-html").TemplateResult<1> | typeof nothing;
|
89
89
|
/**
|
90
|
-
* renders the
|
90
|
+
* renders the help-text container that contains the helpertext icon and helpertext.
|
91
91
|
* @returns void
|
92
92
|
*/
|
93
93
|
protected renderHelperText(): import("lit-html").TemplateResult<1> | typeof nothing;
|
@@ -72,9 +72,7 @@ class FormfieldWrapper extends DisabledMixin(Component) {
|
|
72
72
|
return nothing;
|
73
73
|
}
|
74
74
|
return this.shouldRenderLabel
|
75
|
-
? html `<label for="${this.inputId}" id="${DEFAULTS.HEADING_ID}"
|
76
|
-
>${this.label}</label
|
77
|
-
>`
|
75
|
+
? html `<label for="${this.inputId}" id="${DEFAULTS.HEADING_ID}" part="label">${this.label}</label>`
|
78
76
|
: html ` <mdc-text
|
79
77
|
id="${DEFAULTS.HEADING_ID}"
|
80
78
|
tagname="${MDC_TEXT_OPTIONS.TAGNAME}"
|
@@ -119,14 +117,14 @@ class FormfieldWrapper extends DisabledMixin(Component) {
|
|
119
117
|
`;
|
120
118
|
}
|
121
119
|
/**
|
122
|
-
* renders the
|
120
|
+
* renders the label container that contains the label and labelInfoToggleTip.
|
123
121
|
* @returns void
|
124
122
|
*/
|
125
123
|
renderLabel() {
|
126
124
|
if (!this.label)
|
127
125
|
return nothing;
|
128
126
|
const triggerId = `toggletip-trigger-${uuidv4()}`;
|
129
|
-
return html `<div
|
127
|
+
return html `<div part="label-text">
|
130
128
|
<slot name="label">${this.renderLabelElement()}</slot>
|
131
129
|
${this.required ? html `<span part="required-indicator">*</span>` : nothing}
|
132
130
|
<slot name="toggletip">
|
@@ -154,14 +152,14 @@ class FormfieldWrapper extends DisabledMixin(Component) {
|
|
154
152
|
</div>`;
|
155
153
|
}
|
156
154
|
/**
|
157
|
-
* renders the
|
155
|
+
* renders the help-text container that contains the helpertext icon and helpertext.
|
158
156
|
* @returns void
|
159
157
|
*/
|
160
158
|
renderHelperText() {
|
161
159
|
if (!this.helpText) {
|
162
160
|
return nothing;
|
163
161
|
}
|
164
|
-
return html `<div
|
162
|
+
return html `<div part="help-text-container">
|
165
163
|
<slot name="help-icon">${this.renderHelpTextIcon()}</slot>
|
166
164
|
<slot name="help-text">${this.renderHelpText()}</slot>
|
167
165
|
</div>`;
|
@@ -9,13 +9,13 @@ const styles = [
|
|
9
9
|
gap: 0.5rem;
|
10
10
|
}
|
11
11
|
:host([disabled]),
|
12
|
-
:host([disabled])
|
13
|
-
:host([disabled])
|
12
|
+
:host([disabled])::part(label),
|
13
|
+
:host([disabled])::part(help-text-container),
|
14
14
|
:host([disabled])::part(required-indicator),
|
15
|
-
:host([disabled][help-text-type='error'])
|
16
|
-
:host([disabled][help-text-type='success'])
|
17
|
-
:host([disabled][help-text-type='warning'])
|
18
|
-
:host([disabled][help-text-type='priority'])
|
15
|
+
:host([disabled][help-text-type='error'])::part(help-text-container),
|
16
|
+
:host([disabled][help-text-type='success'])::part(help-text-container),
|
17
|
+
:host([disabled][help-text-type='warning'])::part(help-text-container),
|
18
|
+
:host([disabled][help-text-type='priority'])::part(help-text-container) {
|
19
19
|
color: var(--mds-color-theme-text-primary-disabled);
|
20
20
|
}
|
21
21
|
|
@@ -23,29 +23,35 @@ const styles = [
|
|
23
23
|
color: var(--mds-color-theme-text-error-normal);
|
24
24
|
}
|
25
25
|
|
26
|
-
|
27
|
-
|
26
|
+
:host::part(label-text),
|
27
|
+
:host::part(help-text-container) {
|
28
28
|
display: flex;
|
29
29
|
align-items: center;
|
30
30
|
gap: 0.5rem;
|
31
31
|
width: 100%;
|
32
32
|
}
|
33
33
|
|
34
|
-
|
35
|
-
|
34
|
+
:host::part(label) {
|
35
|
+
font-size: var(--mds-font-apps-body-midsize-medium-font-size);
|
36
|
+
font-weight: var(--mds-font-apps-body-midsize-medium-font-weight);
|
37
|
+
line-height: var(--mds-font-apps-body-midsize-medium-line-height);
|
38
|
+
}
|
39
|
+
|
40
|
+
:host::part(help-text),
|
41
|
+
:host::part(help-text-container) {
|
36
42
|
font-size: var(--mds-font-apps-body-midsize-regular-font-size);
|
37
43
|
font-weight: var(--mds-font-apps-body-midsize-regular-font-weight);
|
38
44
|
line-height: var(--mds-font-apps-body-midsize-regular-line-height);
|
39
45
|
}
|
40
46
|
|
41
|
-
|
47
|
+
:host::part(label) {
|
42
48
|
color: var(--mds-color-theme-text-primary-normal);
|
43
49
|
overflow: hidden;
|
44
50
|
text-overflow: ellipsis;
|
45
51
|
white-space: nowrap;
|
46
52
|
}
|
47
53
|
|
48
|
-
|
54
|
+
:host::part(help-text-container) {
|
49
55
|
color: var(--mds-color-theme-text-secondary-normal);
|
50
56
|
}
|
51
57
|
|
@@ -53,16 +59,16 @@ const styles = [
|
|
53
59
|
align-self: flex-start;
|
54
60
|
}
|
55
61
|
|
56
|
-
:host([help-text-type='error'])
|
62
|
+
:host([help-text-type='error'])::part(help-text-container) {
|
57
63
|
color: var(--mds-color-theme-text-error-normal);
|
58
64
|
}
|
59
|
-
:host([help-text-type='warning'])
|
65
|
+
:host([help-text-type='warning'])::part(help-text-container) {
|
60
66
|
color: var(--mds-color-theme-text-warning-normal);
|
61
67
|
}
|
62
|
-
:host([help-text-type='success'])
|
68
|
+
:host([help-text-type='success'])::part(help-text-container) {
|
63
69
|
color: var(--mds-color-theme-text-success-normal);
|
64
70
|
}
|
65
|
-
:host([help-text-type='priority'])
|
71
|
+
:host([help-text-type='priority'])::part(help-text-container) {
|
66
72
|
color: var(--mds-color-theme-text-accent-normal);
|
67
73
|
}
|
68
74
|
`,
|
@@ -1,5 +1,7 @@
|
|
1
1
|
import Popover from './popover.component';
|
2
|
+
import { PopoverPortal, TAG_NAME as POPOVER_PORTAL_TAG_NAME } from './popover.portal.component';
|
2
3
|
import { TAG_NAME } from './popover.constants';
|
3
4
|
import '../button';
|
4
5
|
Popover.register(TAG_NAME);
|
6
|
+
PopoverPortal.register(POPOVER_PORTAL_TAG_NAME);
|
5
7
|
export default Popover;
|
@@ -3,20 +3,56 @@ import { Component } from '../../models';
|
|
3
3
|
import type { PopoverColor, PopoverPlacement, PopoverStrategy, PopoverTrigger } from './popover.types';
|
4
4
|
declare const Popover_base: import("../../utils/mixins/index.types").Constructor<Component & import("../../utils/mixins/BackdropMixin").BackdropMixinInterface> & import("../../utils/mixins/index.types").Constructor<Component & import("../../utils/mixins/PreventScrollMixin").PreventScrollMixinInterface> & import("../../utils/mixins/index.types").Constructor<Component & import("../../utils/mixins/FocusTrapMixin").FocusTrapClassInterface> & typeof Component;
|
5
5
|
/**
|
6
|
-
* Popover
|
7
|
-
*
|
6
|
+
* Popover is genric overlay which can be trigered by any actinable element.
|
7
|
+
*
|
8
|
+
* It can be used for tooltips, dropdowns, menus or any showing any other contextual content.
|
9
|
+
*
|
8
10
|
* The popover automatically positions itself based on available space and
|
9
|
-
* supports dynamic height adjustments with scrollable content when needed
|
11
|
+
* supports dynamic height adjustments with scrollable content when needed.
|
12
|
+
* It uses [Floating UI](https://floating-ui.com/) for maintaining the position of the popover.
|
13
|
+
*
|
14
|
+
* ## Limitations
|
15
|
+
*
|
16
|
+
* ### On trigger for multiple popovers
|
17
|
+
*
|
18
|
+
* A component (button, etc.) can trigger more than one popover, but only one of them should change the
|
19
|
+
* aria-expanded and aria-haspopup attributes on the trigger.
|
20
|
+
*
|
21
|
+
* To prevent unexpected attribute changes on the trigger `disable-aria-expanded` attribute must be set on all linked
|
22
|
+
* Popoers except one.
|
10
23
|
*
|
11
|
-
*
|
12
|
-
*
|
13
|
-
*
|
24
|
+
* ### React Popover with append-to attribute
|
25
|
+
*
|
26
|
+
* React mounts the popover based on the virtual DOM, but when the append-to attribute is set, the popover removes itself
|
27
|
+
* and mounts to the specified element. React will not know about the move and will not know about the
|
28
|
+
* newly created mdc-popoverportal element either. This throws a `NotFoundError` error when the Popover is directly
|
29
|
+
* added/removed by React, for example:
|
30
|
+
*
|
31
|
+
* ```tsx
|
32
|
+
* const SomeComponent = () => {
|
33
|
+
* const [isOpen, setIsOpen] = useState(false);
|
34
|
+
* return (<div>
|
35
|
+
* {isOpen && <Popover append-to="some-element-id">...</mdc-popover>}
|
36
|
+
* </div>);
|
37
|
+
* }
|
38
|
+
* ```
|
39
|
+
* As a workaround Popover need to wrap with any other element/component, for example:
|
40
|
+
* ```tsx
|
41
|
+
* const SomeComponent = () => {
|
42
|
+
* const [isOpen, setIsOpen] = useState(false);
|
43
|
+
* return (<div>
|
44
|
+
* {isOpen && <div>
|
45
|
+
* <Popover append-to="some-element-id">...</mdc-popover>
|
46
|
+
* <div>}
|
47
|
+
* </div>);
|
48
|
+
* }
|
49
|
+
* ```
|
50
|
+
* Note the wrapper <div> around the Popover component (React.Fragment does not work).
|
14
51
|
*
|
15
52
|
* @dependency mdc-button
|
16
53
|
*
|
17
54
|
* @tagname mdc-popover
|
18
55
|
*
|
19
|
-
*
|
20
56
|
* @event shown - (React: onShown) This event is dispatched when the popover is shown
|
21
57
|
* @event hidden - (React: onHidden) This event is dispatched when the popover is hidden
|
22
58
|
* @event created - (React: onCreated) This event is dispatched when the popover is created (added to the DOM)
|
@@ -312,9 +348,9 @@ declare class Popover extends Popover_base {
|
|
312
348
|
*/
|
313
349
|
get triggerElement(): HTMLElement | null;
|
314
350
|
constructor();
|
351
|
+
private parseTrigger;
|
315
352
|
protected firstUpdated(changedProperties: PropertyValues): Promise<void>;
|
316
353
|
connectedCallback(): void;
|
317
|
-
private parseTrigger;
|
318
354
|
disconnectedCallback(): Promise<void>;
|
319
355
|
/**
|
320
356
|
* Sets up the trigger related event listeners, based on the trigger type.
|
@@ -22,20 +22,56 @@ import { popoverStack } from './popover.stack';
|
|
22
22
|
import styles from './popover.styles';
|
23
23
|
import { PopoverUtils } from './popover.utils';
|
24
24
|
/**
|
25
|
-
* Popover
|
26
|
-
*
|
25
|
+
* Popover is genric overlay which can be trigered by any actinable element.
|
26
|
+
*
|
27
|
+
* It can be used for tooltips, dropdowns, menus or any showing any other contextual content.
|
28
|
+
*
|
27
29
|
* The popover automatically positions itself based on available space and
|
28
|
-
* supports dynamic height adjustments with scrollable content when needed
|
30
|
+
* supports dynamic height adjustments with scrollable content when needed.
|
31
|
+
* It uses [Floating UI](https://floating-ui.com/) for maintaining the position of the popover.
|
32
|
+
*
|
33
|
+
* ## Limitations
|
34
|
+
*
|
35
|
+
* ### On trigger for multiple popovers
|
36
|
+
*
|
37
|
+
* A component (button, etc.) can trigger more than one popover, but only one of them should change the
|
38
|
+
* aria-expanded and aria-haspopup attributes on the trigger.
|
39
|
+
*
|
40
|
+
* To prevent unexpected attribute changes on the trigger `disable-aria-expanded` attribute must be set on all linked
|
41
|
+
* Popoers except one.
|
42
|
+
*
|
43
|
+
* ### React Popover with append-to attribute
|
44
|
+
*
|
45
|
+
* React mounts the popover based on the virtual DOM, but when the append-to attribute is set, the popover removes itself
|
46
|
+
* and mounts to the specified element. React will not know about the move and will not know about the
|
47
|
+
* newly created mdc-popoverportal element either. This throws a `NotFoundError` error when the Popover is directly
|
48
|
+
* added/removed by React, for example:
|
29
49
|
*
|
30
|
-
*
|
31
|
-
*
|
32
|
-
*
|
50
|
+
* ```tsx
|
51
|
+
* const SomeComponent = () => {
|
52
|
+
* const [isOpen, setIsOpen] = useState(false);
|
53
|
+
* return (<div>
|
54
|
+
* {isOpen && <Popover append-to="some-element-id">...</mdc-popover>}
|
55
|
+
* </div>);
|
56
|
+
* }
|
57
|
+
* ```
|
58
|
+
* As a workaround Popover need to wrap with any other element/component, for example:
|
59
|
+
* ```tsx
|
60
|
+
* const SomeComponent = () => {
|
61
|
+
* const [isOpen, setIsOpen] = useState(false);
|
62
|
+
* return (<div>
|
63
|
+
* {isOpen && <div>
|
64
|
+
* <Popover append-to="some-element-id">...</mdc-popover>
|
65
|
+
* <div>}
|
66
|
+
* </div>);
|
67
|
+
* }
|
68
|
+
* ```
|
69
|
+
* Note the wrapper <div> around the Popover component (React.Fragment does not work).
|
33
70
|
*
|
34
71
|
* @dependency mdc-button
|
35
72
|
*
|
36
73
|
* @tagname mdc-popover
|
37
74
|
*
|
38
|
-
*
|
39
75
|
* @event shown - (React: onShown) This event is dispatched when the popover is shown
|
40
76
|
* @event hidden - (React: onHidden) This event is dispatched when the popover is hidden
|
41
77
|
* @event created - (React: onCreated) This event is dispatched when the popover is created (added to the DOM)
|
@@ -632,12 +668,12 @@ class Popover extends BackdropMixin(PreventScrollMixin(FocusTrapMixin(Component)
|
|
632
668
|
}
|
633
669
|
async firstUpdated(changedProperties) {
|
634
670
|
super.firstUpdated(changedProperties);
|
635
|
-
this.style.zIndex = `${this.zIndex}`;
|
636
|
-
this.utils.setupAppendTo();
|
637
671
|
PopoverEventManager.onCreatedPopover(this);
|
638
672
|
}
|
639
673
|
connectedCallback() {
|
640
674
|
super.connectedCallback();
|
675
|
+
this.style.zIndex = `${this.zIndex}`;
|
676
|
+
this.utils.setupAppendTo();
|
641
677
|
this.setupTriggerListeners();
|
642
678
|
}
|
643
679
|
async disconnectedCallback() {
|
@@ -656,6 +692,7 @@ class Popover extends BackdropMixin(PreventScrollMixin(FocusTrapMixin(Component)
|
|
656
692
|
this.connectedTooltip.shouldSuppressOpening = false;
|
657
693
|
}
|
658
694
|
}
|
695
|
+
this.utils.cleanupAppendTo();
|
659
696
|
PopoverEventManager.onDestroyedPopover(this);
|
660
697
|
popoverStack.remove(this);
|
661
698
|
}
|
@@ -683,8 +720,13 @@ class Popover extends BackdropMixin(PreventScrollMixin(FocusTrapMixin(Component)
|
|
683
720
|
if (changedProperties.has('zIndex')) {
|
684
721
|
this.setAttribute('z-index', `${this.zIndex}`);
|
685
722
|
}
|
686
|
-
if (changedProperties.has('
|
687
|
-
this.
|
723
|
+
if (changedProperties.has('appendTo')) {
|
724
|
+
if (this.appendTo) {
|
725
|
+
this.utils.setupAppendTo();
|
726
|
+
}
|
727
|
+
else {
|
728
|
+
this.utils.cleanupAppendTo();
|
729
|
+
}
|
688
730
|
}
|
689
731
|
if (changedProperties.has('interactive') ||
|
690
732
|
changedProperties.has('aria-label') ||
|
@@ -0,0 +1,29 @@
|
|
1
|
+
import { Component } from '../../models';
|
2
|
+
export declare const TAG_NAME: "mdc-popoverportal";
|
3
|
+
/**
|
4
|
+
* PopoverPortal in a placeholder component
|
5
|
+
*
|
6
|
+
* When the popover appended to another container, this component is used to mark the original place of the
|
7
|
+
* popover in the DOM. When the portal removed from the DOM, we remove the popover from the container as well.
|
8
|
+
*
|
9
|
+
* We need this behavior to support on hover menus. Without the portal:
|
10
|
+
* - Each time when then consumer renders the menu we append a new instance of the popover to the container which
|
11
|
+
* cause memory leak.
|
12
|
+
* - Trigger component will open all popovers at once, because all of them has the same triggerID and all
|
13
|
+
* listeners attached to the document.
|
14
|
+
*
|
15
|
+
* Portal component make sure the popover clean up when it was normally (without append-to) removed from the DOM.
|
16
|
+
* This is especially important when the popover is used in a framework like React or Angular, where virtual does not
|
17
|
+
* know about the popover moved to another place in the DOM.
|
18
|
+
*
|
19
|
+
* @internal
|
20
|
+
*/
|
21
|
+
export declare class PopoverPortal extends Component {
|
22
|
+
onDisconnect: Function | undefined;
|
23
|
+
connectedCallback(): void;
|
24
|
+
/**
|
25
|
+
* When the portal removed from the DOM, we remove the popover from the container as well.
|
26
|
+
* @internal
|
27
|
+
*/
|
28
|
+
disconnectedCallback(): void;
|
29
|
+
}
|
@@ -0,0 +1,37 @@
|
|
1
|
+
import { Component } from '../../models';
|
2
|
+
import utils from '../../utils/tag-name';
|
3
|
+
export const TAG_NAME = utils.constructTagName('popoverportal');
|
4
|
+
/**
|
5
|
+
* PopoverPortal in a placeholder component
|
6
|
+
*
|
7
|
+
* When the popover appended to another container, this component is used to mark the original place of the
|
8
|
+
* popover in the DOM. When the portal removed from the DOM, we remove the popover from the container as well.
|
9
|
+
*
|
10
|
+
* We need this behavior to support on hover menus. Without the portal:
|
11
|
+
* - Each time when then consumer renders the menu we append a new instance of the popover to the container which
|
12
|
+
* cause memory leak.
|
13
|
+
* - Trigger component will open all popovers at once, because all of them has the same triggerID and all
|
14
|
+
* listeners attached to the document.
|
15
|
+
*
|
16
|
+
* Portal component make sure the popover clean up when it was normally (without append-to) removed from the DOM.
|
17
|
+
* This is especially important when the popover is used in a framework like React or Angular, where virtual does not
|
18
|
+
* know about the popover moved to another place in the DOM.
|
19
|
+
*
|
20
|
+
* @internal
|
21
|
+
*/
|
22
|
+
export class PopoverPortal extends Component {
|
23
|
+
connectedCallback() {
|
24
|
+
super.connectedCallback();
|
25
|
+
// We don't want the portal to be focusable or visible for screen readers
|
26
|
+
this.ariaHidden = 'true';
|
27
|
+
}
|
28
|
+
/**
|
29
|
+
* When the portal removed from the DOM, we remove the popover from the container as well.
|
30
|
+
* @internal
|
31
|
+
*/
|
32
|
+
disconnectedCallback() {
|
33
|
+
var _a;
|
34
|
+
super.disconnectedCallback();
|
35
|
+
(_a = this.onDisconnect) === null || _a === void 0 ? void 0 : _a.call(this);
|
36
|
+
}
|
37
|
+
}
|
@@ -2,6 +2,17 @@ import type Popover from './popover.component';
|
|
2
2
|
export declare class PopoverUtils {
|
3
3
|
/** @internal */
|
4
4
|
private popover;
|
5
|
+
/**
|
6
|
+
* The portal element used when the popover is appended to another container.
|
7
|
+
* @internal
|
8
|
+
*/
|
9
|
+
private portalElement;
|
10
|
+
/**
|
11
|
+
* Flag to indicate if the popover was diconnected because it was appended to another container, or
|
12
|
+
* it was actually removed from the DOM.
|
13
|
+
* @internal
|
14
|
+
*/
|
15
|
+
private disconnectAfterAppendTo;
|
5
16
|
/** @internal */
|
6
17
|
private arrowPixelChange;
|
7
18
|
constructor(popover: Popover);
|
@@ -24,6 +35,10 @@ export declare class PopoverUtils {
|
|
24
35
|
* DOM element by its ID, and appends this popover as a child of that element.
|
25
36
|
*/
|
26
37
|
setupAppendTo(): void;
|
38
|
+
/**
|
39
|
+
* Remove portal component to when the popover appended to somewhere else and removed from the DOM
|
40
|
+
*/
|
41
|
+
cleanupAppendTo(): void;
|
27
42
|
/**
|
28
43
|
* Sets up the aria labels
|
29
44
|
*/
|
@@ -1,6 +1,18 @@
|
|
1
1
|
import { ROLE } from '../../utils/roles';
|
2
|
+
import { TAG_NAME as POPOVER_PORTAL_TAG_NAME } from './popover.portal.component';
|
2
3
|
export class PopoverUtils {
|
3
4
|
constructor(popover) {
|
5
|
+
/**
|
6
|
+
* The portal element used when the popover is appended to another container.
|
7
|
+
* @internal
|
8
|
+
*/
|
9
|
+
this.portalElement = null;
|
10
|
+
/**
|
11
|
+
* Flag to indicate if the popover was diconnected because it was appended to another container, or
|
12
|
+
* it was actually removed from the DOM.
|
13
|
+
* @internal
|
14
|
+
*/
|
15
|
+
this.disconnectAfterAppendTo = false;
|
4
16
|
/** @internal */
|
5
17
|
this.arrowPixelChange = false;
|
6
18
|
this.popover = popover;
|
@@ -78,13 +90,30 @@ export class PopoverUtils {
|
|
78
90
|
* DOM element by its ID, and appends this popover as a child of that element.
|
79
91
|
*/
|
80
92
|
setupAppendTo() {
|
93
|
+
var _a, _b;
|
81
94
|
if (this.popover.appendTo) {
|
82
|
-
const
|
83
|
-
if (
|
84
|
-
|
95
|
+
const appendToEl = document.getElementById(this.popover.appendTo);
|
96
|
+
if (appendToEl && !Array.from(appendToEl.children).includes(this.popover)) {
|
97
|
+
this.disconnectAfterAppendTo = true;
|
98
|
+
this.portalElement = document.createElement(POPOVER_PORTAL_TAG_NAME);
|
99
|
+
this.portalElement.onDisconnect = () => {
|
100
|
+
this.popover.remove();
|
101
|
+
this.portalElement = null;
|
102
|
+
};
|
103
|
+
(_b = (_a = this.popover.parentElement) === null || _a === void 0 ? void 0 : _a.appendChild) === null || _b === void 0 ? void 0 : _b.call(_a, this.portalElement);
|
104
|
+
appendToEl.appendChild(this.popover);
|
85
105
|
}
|
86
106
|
}
|
87
107
|
}
|
108
|
+
/**
|
109
|
+
* Remove portal component to when the popover appended to somewhere else and removed from the DOM
|
110
|
+
*/
|
111
|
+
cleanupAppendTo() {
|
112
|
+
if (!this.disconnectAfterAppendTo && this.portalElement) {
|
113
|
+
this.portalElement.remove();
|
114
|
+
}
|
115
|
+
this.disconnectAfterAppendTo = false;
|
116
|
+
}
|
88
117
|
/**
|
89
118
|
* Sets up the aria labels
|
90
119
|
*/
|
@@ -13,9 +13,9 @@ const styles = [
|
|
13
13
|
--mdc-progressbar-border-radius: var(--mdc-progressbar-height);
|
14
14
|
|
15
15
|
--mdc-progressbar-label-color: var(--mds-color-theme-text-primary-normal);
|
16
|
-
--mdc-progressbar-label-line-height: var(--mds-font-
|
17
|
-
--mdc-progressbar-label-font-size: var(--mds-font-
|
18
|
-
--mdc-progressbar-label-font-weight: var(--mds-font-
|
16
|
+
--mdc-progressbar-label-line-height: var(--mds-font-apps-body-midsize-regular-line-height);
|
17
|
+
--mdc-progressbar-label-font-size: var(--mds-font-apps-body-midsize-regular-font-size);
|
18
|
+
--mdc-progressbar-label-font-weight: var(--mds-font-apps-body-midsize-regular-font-weight);
|
19
19
|
--mdc-progressbar-help-text-color: var(--mds-color-theme-text-secondary-normal);
|
20
20
|
|
21
21
|
width: 100%;
|
@@ -71,8 +71,6 @@ const styles = [
|
|
71
71
|
border-radius: var(--mdc-progressbar-border-radius);
|
72
72
|
}
|
73
73
|
|
74
|
-
:host::part(label-text),
|
75
|
-
:host::part(help-text),
|
76
74
|
:host::part(percentage) {
|
77
75
|
font-size: var(--mdc-progressbar-label-font-size);
|
78
76
|
font-weight: var(--mdc-progressbar-label-font-weight);
|
@@ -64,7 +64,7 @@ class Radio extends AutoFocusOnMountMixin(FormInternalsMixin(DataAriaLabelMixin(
|
|
64
64
|
this.renderLabelAndHelperText = () => {
|
65
65
|
if (!this.label)
|
66
66
|
return nothing;
|
67
|
-
return html `<div
|
67
|
+
return html `<div part="text-container">${this.renderLabel()} ${this.renderHelperText()}</div>`;
|
68
68
|
};
|
69
69
|
}
|
70
70
|
connectedCallback() {
|
@@ -279,6 +279,7 @@ class Radio extends AutoFocusOnMountMixin(FormInternalsMixin(DataAriaLabelMixin(
|
|
279
279
|
>
|
280
280
|
<input
|
281
281
|
id="${this.inputId}"
|
282
|
+
part="radio-input"
|
282
283
|
type="radio"
|
283
284
|
role="${ROLE.RADIO}"
|
284
285
|
?autofocus="${this.autofocus}"
|
@@ -290,7 +291,6 @@ class Radio extends AutoFocusOnMountMixin(FormInternalsMixin(DataAriaLabelMixin(
|
|
290
291
|
?checked=${this.checked}
|
291
292
|
?readonly=${this.readonly}
|
292
293
|
?disabled=${this.disabled}
|
293
|
-
class="mdc-radio__input"
|
294
294
|
aria-checked="${this.checked}"
|
295
295
|
aria-describedby="${ifDefined(this.helpText ? FORMFIELD_DEFAULTS.HELPER_TEXT_ID : '')}"
|
296
296
|
aria-label="${(_a = this.dataAriaLabel) !== null && _a !== void 0 ? _a : ''}"
|