@momentum-design/components 0.100.1 → 0.101.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/dist/browser/index.js +1370 -1142
- package/dist/browser/index.js.map +4 -4
- package/dist/components/accordion/accordion.component.d.ts +76 -0
- package/dist/components/accordion/accordion.component.js +130 -0
- package/dist/components/accordion/accordion.constants.d.ts +2 -0
- package/dist/components/accordion/accordion.constants.js +3 -0
- package/dist/components/accordion/accordion.styles.d.ts +2 -0
- package/dist/components/accordion/accordion.styles.js +17 -0
- package/dist/components/accordion/index.d.ts +10 -0
- package/dist/components/accordion/index.js +7 -0
- package/dist/components/accordionbutton/accordionbutton.component.d.ts +121 -0
- package/dist/components/accordionbutton/accordionbutton.component.js +240 -0
- package/dist/components/accordionbutton/accordionbutton.constants.d.ts +17 -0
- package/dist/components/accordionbutton/accordionbutton.constants.js +19 -0
- package/dist/components/accordionbutton/accordionbutton.styles.d.ts +2 -0
- package/dist/components/accordionbutton/accordionbutton.styles.js +121 -0
- package/dist/components/accordionbutton/accordionbutton.types.d.ts +8 -0
- package/dist/components/accordionbutton/accordionbutton.types.js +1 -0
- package/dist/components/accordionbutton/index.d.ts +10 -0
- package/dist/components/accordionbutton/index.js +7 -0
- package/dist/components/accordiongroup/accordiongroup.component.d.ts +73 -0
- package/dist/components/accordiongroup/accordiongroup.component.js +134 -0
- package/dist/components/accordiongroup/accordiongroup.constants.d.ts +15 -0
- package/dist/components/accordiongroup/accordiongroup.constants.js +16 -0
- package/dist/components/accordiongroup/accordiongroup.styles.d.ts +2 -0
- package/dist/components/accordiongroup/accordiongroup.styles.js +48 -0
- package/dist/components/accordiongroup/accordiongroup.types.d.ts +5 -0
- package/dist/components/accordiongroup/accordiongroup.types.js +1 -0
- package/dist/components/accordiongroup/index.d.ts +7 -0
- package/dist/components/accordiongroup/index.js +4 -0
- package/dist/custom-elements.json +966 -0
- package/dist/index.d.ts +10 -7
- package/dist/index.js +10 -7
- package/dist/react/accordion/index.d.ts +55 -0
- package/dist/react/accordion/index.js +63 -0
- package/dist/react/accordionbutton/index.d.ts +52 -0
- package/dist/react/accordionbutton/index.js +60 -0
- package/dist/react/accordiongroup/index.d.ts +32 -0
- package/dist/react/accordiongroup/index.js +41 -0
- package/dist/react/index.d.ts +3 -0
- package/dist/react/index.js +3 -0
- package/dist/utils/keys.d.ts +1 -0
- package/dist/utils/keys.js +1 -0
- package/dist/utils/roles.d.ts +2 -0
- package/dist/utils/roles.js +2 -0
- package/package.json +1 -1
@@ -0,0 +1,76 @@
|
|
1
|
+
import type { CSSResult, PropertyValues } from 'lit';
|
2
|
+
import AccordionButton from '../accordionbutton/accordionbutton.component';
|
3
|
+
/**
|
4
|
+
* An accordion contains a header and body section with a focusable heading that can be expanded or collapsed.
|
5
|
+
*
|
6
|
+
* The header section contains:
|
7
|
+
* - Prefix Icon
|
8
|
+
* - Header Text
|
9
|
+
* - Leading Slot - Contains the leading controls of the accordion on the header section. This will be placed on the leading side, after the header text.
|
10
|
+
* - Trailing Slot - Contains the trailing controls of the accordion on the header section. This will be placed on the trailing side, before the expand/collapse button.
|
11
|
+
*
|
12
|
+
* The body section contains:
|
13
|
+
* - Default slot - User can place any content inside the body section.
|
14
|
+
*
|
15
|
+
* The accordion can be expanded or collapsed. The visibility of the body section can be controlled by `expanded` attribute. <br/>
|
16
|
+
* There are two types of variants based on that the border styling of the accordion gets reflected. <br/>
|
17
|
+
* There are two sizes of accordion, one is small and the other is large.
|
18
|
+
* Small size has a padding of 1rem (16px) and large size has a padding of 1.5rem (24px) for the body section of accordion.
|
19
|
+
*
|
20
|
+
* By default, the header text in the accordion heading is of H3 with an aria-level of '3'.
|
21
|
+
* If this accordion is placed on any other level in the entire webpage, then do adjust the aria-level number based on that.
|
22
|
+
*
|
23
|
+
* An accordion can be disabled, and when it's disabled, the header section will not be clickable.
|
24
|
+
*
|
25
|
+
* If you don't need any controls on your accordion heading, then it's advised to use `accordionbutton` component.
|
26
|
+
*
|
27
|
+
* If an accordion is expanded by default, then the screen reader might loose focus when toggling the visibilty of the accordion.
|
28
|
+
*
|
29
|
+
* @tagname mdc-accordion
|
30
|
+
*
|
31
|
+
* @dependency mdc-button
|
32
|
+
* @dependency mdc-icon
|
33
|
+
* @dependency mdc-text
|
34
|
+
*
|
35
|
+
* @slot leading-controls - The leading controls slot of the accordion on the header section.
|
36
|
+
* @slot trailing-controls - The trailing controls slot of the accordion on the header section.
|
37
|
+
* @slot default - The default slot contains the body section of the accordion. User can place anything inside this body slot.
|
38
|
+
*
|
39
|
+
* @event shown - (React: onShown) This event is triggered when the accordion is expanded.
|
40
|
+
*
|
41
|
+
* @cssproperty --mdc-accordionbutton-border-color - The border color of the accordion.
|
42
|
+
* @cssproperty --mdc-accordionbutton-hover-color - The hover color of the accordion.
|
43
|
+
* @cssproperty --mdc-accordionbutton-active-color - The active color of the accordion.
|
44
|
+
* @cssproperty --mdc-accordionbutton-disabled-color - The disabled color of the accordion.
|
45
|
+
*
|
46
|
+
* @csspart header-section - The header section of the accordion.
|
47
|
+
* @csspart leading-header - The leading header of the accordion.
|
48
|
+
* @csspart trailing-header - The trailing header of the accordion.
|
49
|
+
* @csspart trailing-header__button - The trailing header button of the accordion.
|
50
|
+
* @csspart body-section - The body section of the accordion.
|
51
|
+
*/
|
52
|
+
declare class Accordion extends AccordionButton {
|
53
|
+
/** @internal */
|
54
|
+
leadingControlsSlot: Array<HTMLElement>;
|
55
|
+
/** @internal */
|
56
|
+
trailingControlsSlot: Array<HTMLElement>;
|
57
|
+
/**
|
58
|
+
* Handles property changes for the accordion.
|
59
|
+
* If the disabled property is updated, applies the same disabled state to all elements in the leading and trailing controls slots.
|
60
|
+
* @param changedProperties - The changed properties of the accordion.
|
61
|
+
*/
|
62
|
+
update(changedProperties: PropertyValues): void;
|
63
|
+
/**
|
64
|
+
* Renders the header section of the accordion.
|
65
|
+
* This includes the leading icon, text and controls, and the trailing controls.
|
66
|
+
* The trailing controls include the expand/collapse button.
|
67
|
+
* The button is disabled if the accordion is disabled.
|
68
|
+
* The button is also given the aria-controls attribute set to the id of the body section.
|
69
|
+
* The button is also given the aria-expanded attribute set to the expanded state of the accordion.
|
70
|
+
* The prefix icon of the button is set to the expanded state of the accordion.
|
71
|
+
* @returns The rendered header section of the accordion.
|
72
|
+
*/
|
73
|
+
renderHeader(): import("lit-html").TemplateResult<1>;
|
74
|
+
static styles: Array<CSSResult>;
|
75
|
+
}
|
76
|
+
export default Accordion;
|
@@ -0,0 +1,130 @@
|
|
1
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
2
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
3
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
4
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
5
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
6
|
+
};
|
7
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
8
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
9
|
+
};
|
10
|
+
import { html } from 'lit';
|
11
|
+
import { queryAssignedElements } from 'lit/decorators.js';
|
12
|
+
import { ifDefined } from 'lit/directives/if-defined.js';
|
13
|
+
import { ROLE } from '../../utils/roles';
|
14
|
+
import AccordionButton from '../accordionbutton/accordionbutton.component';
|
15
|
+
import { BUTTON_VARIANTS, ICON_BUTTON_SIZES } from '../button/button.constants';
|
16
|
+
import styles from './accordion.styles';
|
17
|
+
/**
|
18
|
+
* An accordion contains a header and body section with a focusable heading that can be expanded or collapsed.
|
19
|
+
*
|
20
|
+
* The header section contains:
|
21
|
+
* - Prefix Icon
|
22
|
+
* - Header Text
|
23
|
+
* - Leading Slot - Contains the leading controls of the accordion on the header section. This will be placed on the leading side, after the header text.
|
24
|
+
* - Trailing Slot - Contains the trailing controls of the accordion on the header section. This will be placed on the trailing side, before the expand/collapse button.
|
25
|
+
*
|
26
|
+
* The body section contains:
|
27
|
+
* - Default slot - User can place any content inside the body section.
|
28
|
+
*
|
29
|
+
* The accordion can be expanded or collapsed. The visibility of the body section can be controlled by `expanded` attribute. <br/>
|
30
|
+
* There are two types of variants based on that the border styling of the accordion gets reflected. <br/>
|
31
|
+
* There are two sizes of accordion, one is small and the other is large.
|
32
|
+
* Small size has a padding of 1rem (16px) and large size has a padding of 1.5rem (24px) for the body section of accordion.
|
33
|
+
*
|
34
|
+
* By default, the header text in the accordion heading is of H3 with an aria-level of '3'.
|
35
|
+
* If this accordion is placed on any other level in the entire webpage, then do adjust the aria-level number based on that.
|
36
|
+
*
|
37
|
+
* An accordion can be disabled, and when it's disabled, the header section will not be clickable.
|
38
|
+
*
|
39
|
+
* If you don't need any controls on your accordion heading, then it's advised to use `accordionbutton` component.
|
40
|
+
*
|
41
|
+
* If an accordion is expanded by default, then the screen reader might loose focus when toggling the visibilty of the accordion.
|
42
|
+
*
|
43
|
+
* @tagname mdc-accordion
|
44
|
+
*
|
45
|
+
* @dependency mdc-button
|
46
|
+
* @dependency mdc-icon
|
47
|
+
* @dependency mdc-text
|
48
|
+
*
|
49
|
+
* @slot leading-controls - The leading controls slot of the accordion on the header section.
|
50
|
+
* @slot trailing-controls - The trailing controls slot of the accordion on the header section.
|
51
|
+
* @slot default - The default slot contains the body section of the accordion. User can place anything inside this body slot.
|
52
|
+
*
|
53
|
+
* @event shown - (React: onShown) This event is triggered when the accordion is expanded.
|
54
|
+
*
|
55
|
+
* @cssproperty --mdc-accordionbutton-border-color - The border color of the accordion.
|
56
|
+
* @cssproperty --mdc-accordionbutton-hover-color - The hover color of the accordion.
|
57
|
+
* @cssproperty --mdc-accordionbutton-active-color - The active color of the accordion.
|
58
|
+
* @cssproperty --mdc-accordionbutton-disabled-color - The disabled color of the accordion.
|
59
|
+
*
|
60
|
+
* @csspart header-section - The header section of the accordion.
|
61
|
+
* @csspart leading-header - The leading header of the accordion.
|
62
|
+
* @csspart trailing-header - The trailing header of the accordion.
|
63
|
+
* @csspart trailing-header__button - The trailing header button of the accordion.
|
64
|
+
* @csspart body-section - The body section of the accordion.
|
65
|
+
*/
|
66
|
+
class Accordion extends AccordionButton {
|
67
|
+
/**
|
68
|
+
* Handles property changes for the accordion.
|
69
|
+
* If the disabled property is updated, applies the same disabled state to all elements in the leading and trailing controls slots.
|
70
|
+
* @param changedProperties - The changed properties of the accordion.
|
71
|
+
*/
|
72
|
+
update(changedProperties) {
|
73
|
+
super.update(changedProperties);
|
74
|
+
if (changedProperties.has('disabled')) {
|
75
|
+
[...this.leadingControlsSlot, ...this.trailingControlsSlot].forEach(element => {
|
76
|
+
if (this.disabled) {
|
77
|
+
element.setAttribute('disabled', '');
|
78
|
+
}
|
79
|
+
else {
|
80
|
+
element.removeAttribute('disabled');
|
81
|
+
}
|
82
|
+
});
|
83
|
+
}
|
84
|
+
}
|
85
|
+
/**
|
86
|
+
* Renders the header section of the accordion.
|
87
|
+
* This includes the leading icon, text and controls, and the trailing controls.
|
88
|
+
* The trailing controls include the expand/collapse button.
|
89
|
+
* The button is disabled if the accordion is disabled.
|
90
|
+
* The button is also given the aria-controls attribute set to the id of the body section.
|
91
|
+
* The button is also given the aria-expanded attribute set to the expanded state of the accordion.
|
92
|
+
* The prefix icon of the button is set to the expanded state of the accordion.
|
93
|
+
* @returns The rendered header section of the accordion.
|
94
|
+
*/
|
95
|
+
renderHeader() {
|
96
|
+
return html `
|
97
|
+
<div part="header-section">
|
98
|
+
<div part="leading-header">
|
99
|
+
${this.renderIcon(this.prefixIcon)}
|
100
|
+
<div role="${ROLE.HEADING}" aria-level="${this.dataAriaLevel}">${this.renderHeadingText()}</div>
|
101
|
+
<slot name="leading-controls"></slot>
|
102
|
+
</div>
|
103
|
+
<div part="trailing-header">
|
104
|
+
<slot name="trailing-controls"></slot>
|
105
|
+
<mdc-button
|
106
|
+
part="trailing-header__button"
|
107
|
+
?disabled="${this.disabled}"
|
108
|
+
@click="${this.handleHeaderClick}"
|
109
|
+
aria-controls="${this.bodySectionId}"
|
110
|
+
aria-expanded="${this.expanded}"
|
111
|
+
title="${ifDefined(this.headerText)}"
|
112
|
+
prefix-icon="${this.getArrowIconName()}"
|
113
|
+
variant="${BUTTON_VARIANTS.TERTIARY}"
|
114
|
+
size="${ICON_BUTTON_SIZES[20]}"
|
115
|
+
></mdc-button>
|
116
|
+
</div>
|
117
|
+
</div>
|
118
|
+
`;
|
119
|
+
}
|
120
|
+
}
|
121
|
+
Accordion.styles = [...AccordionButton.styles, ...styles];
|
122
|
+
__decorate([
|
123
|
+
queryAssignedElements({ slot: 'leading-controls' }),
|
124
|
+
__metadata("design:type", Array)
|
125
|
+
], Accordion.prototype, "leadingControlsSlot", void 0);
|
126
|
+
__decorate([
|
127
|
+
queryAssignedElements({ slot: 'trailing-controls' }),
|
128
|
+
__metadata("design:type", Array)
|
129
|
+
], Accordion.prototype, "trailingControlsSlot", void 0);
|
130
|
+
export default Accordion;
|
@@ -0,0 +1,17 @@
|
|
1
|
+
import { css } from 'lit';
|
2
|
+
const styles = css `
|
3
|
+
:host::part(header-section) {
|
4
|
+
display: flex;
|
5
|
+
align-items: center;
|
6
|
+
cursor: unset;
|
7
|
+
justify-content: space-between;
|
8
|
+
}
|
9
|
+
:host::part(header-section):hover,
|
10
|
+
:host::part(header-section):active {
|
11
|
+
background-color: unset;
|
12
|
+
}
|
13
|
+
:host::part(trailing-header__button) {
|
14
|
+
margin: 0.125rem;
|
15
|
+
}
|
16
|
+
`;
|
17
|
+
export default [styles];
|
@@ -0,0 +1,121 @@
|
|
1
|
+
import type { CSSResult, PropertyValues, TemplateResult } from 'lit';
|
2
|
+
import { nothing } from 'lit';
|
3
|
+
import { Component } from '../../models';
|
4
|
+
import type { Size } from '../accordiongroup/accordiongroup.types';
|
5
|
+
import type { IconNames } from '../icon/icon.types';
|
6
|
+
import type { IconName, Variant } from './accordionbutton.types';
|
7
|
+
declare const AccordionButton_base: import("../../utils/mixins/index.types").Constructor<import("../../utils/mixins/DisabledMixin").DisabledMixinInterface> & typeof Component;
|
8
|
+
/**
|
9
|
+
* An accordion button contains a header and body section with optional slots inside the heading which are focusable.
|
10
|
+
*
|
11
|
+
* The header section contains:
|
12
|
+
* - Prefix Icon
|
13
|
+
* - Header Text
|
14
|
+
*
|
15
|
+
* The body section contains:
|
16
|
+
* - Default slot - User can place any content inside the body section.
|
17
|
+
*
|
18
|
+
* The accordion button can be expanded or collapsed. The visibility of the body section can be controlled by `expanded` attribute. <br/>
|
19
|
+
* There are two types of variants based on that the border styling of the accordion gets reflected. <br/>
|
20
|
+
* There are two sizes of accordion, one is small and the other is large.
|
21
|
+
* Small size has a padding of 1rem (16px) and large size has a padding of 1.5rem (24px) for the body section of accordion.
|
22
|
+
*
|
23
|
+
* By default, the header text in the accordion heading is of H3 with an aria-level of '3'.
|
24
|
+
* If this accordion is placed on any other level in the entire webpage, then do adjust the aria-level number based on that.
|
25
|
+
*
|
26
|
+
* An accordion can be disabled, and when it's disabled, the header section will not be clickable.
|
27
|
+
*
|
28
|
+
* If you do need any controls on your accordion heading, then it's advised to use `accordion` component.
|
29
|
+
*
|
30
|
+
* If an accordion button is expanded by default, then the screen reader might loose focus when toggling the visibilty of the accordion button.
|
31
|
+
*
|
32
|
+
* @tagname mdc-accordionbutton
|
33
|
+
*
|
34
|
+
* @dependency mdc-button
|
35
|
+
* @dependency mdc-icon
|
36
|
+
* @dependency mdc-text
|
37
|
+
*
|
38
|
+
* @slot default - The default slot contains the body section of the accordion. User can place anything inside this body slot.
|
39
|
+
*
|
40
|
+
* @event shown - (React: onShown) This event is triggered when the accordion button is expanded.
|
41
|
+
*
|
42
|
+
* @cssproperty --mdc-accordionbutton-border-color - The border color of the accordion button.
|
43
|
+
* @cssproperty --mdc-accordionbutton-hover-color - The hover color of the accordion button.
|
44
|
+
* @cssproperty --mdc-accordionbutton-active-color - The active color of the accordion button.
|
45
|
+
* @cssproperty --mdc-accordionbutton-disabled-color - The disabled color of the accordion button.
|
46
|
+
*
|
47
|
+
* @csspart header-section - The header section of the accordion button.
|
48
|
+
* @csspart header-button-section - The header button section of the accordion button.
|
49
|
+
* @csspart leading-header - The leading header of the accordion button.
|
50
|
+
* @csspart trailing-header - The trailing header of the accordion button.
|
51
|
+
* @csspart trailing-header__icon - The trailing header icon of the accordion button.
|
52
|
+
* @csspart body-section - The body section of the accordion button.
|
53
|
+
*/
|
54
|
+
declare class AccordionButton extends AccordionButton_base {
|
55
|
+
/**
|
56
|
+
* The size of the accordion item.
|
57
|
+
* @default 'small'
|
58
|
+
*/
|
59
|
+
size: Size;
|
60
|
+
/**
|
61
|
+
* The variant of the accordion item. Based on the variant, the styling of the accordion gets changed.
|
62
|
+
* @default 'default'
|
63
|
+
*/
|
64
|
+
variant: Variant;
|
65
|
+
/**
|
66
|
+
* The aria level of the accordion component.
|
67
|
+
* @default 3
|
68
|
+
*/
|
69
|
+
dataAriaLevel: number;
|
70
|
+
/**
|
71
|
+
* The visibility of the accordion button.
|
72
|
+
* @default false
|
73
|
+
*/
|
74
|
+
expanded: boolean;
|
75
|
+
/**
|
76
|
+
* The header text of the accordion item.
|
77
|
+
*/
|
78
|
+
headerText?: string;
|
79
|
+
/**
|
80
|
+
* The leading icon that is displayed before the header text.
|
81
|
+
*/
|
82
|
+
prefixIcon?: IconNames;
|
83
|
+
/** @internal */
|
84
|
+
private headSectionId;
|
85
|
+
/** @internal */
|
86
|
+
protected bodySectionId: string;
|
87
|
+
/**
|
88
|
+
* Handles the click event of the header section.
|
89
|
+
* If the accordion is disabled, it will not toggle the expanded state.
|
90
|
+
* It will dispatch the `shown` event with the current expanded state.
|
91
|
+
*/
|
92
|
+
protected handleHeaderClick(): void;
|
93
|
+
/**
|
94
|
+
* Dispatches the `shown` event with the current expanded state.
|
95
|
+
* The event is cancelable and bubbles.
|
96
|
+
* The event detail contains the current expanded state.
|
97
|
+
*/
|
98
|
+
private dispatchHeaderClickEvent;
|
99
|
+
/**
|
100
|
+
* Handles the keydown event of the component.
|
101
|
+
* If the key pressed is either Enter or Space, it calls the handleHeaderClick method.
|
102
|
+
* This allows keyboard users to toggle the accordion button using these keys.
|
103
|
+
* @param event - The KeyboardEvent fired.
|
104
|
+
*/
|
105
|
+
private handleKeyDown;
|
106
|
+
protected renderIcon(iconName?: IconNames): TemplateResult | typeof nothing;
|
107
|
+
protected renderHeadingText(): TemplateResult | typeof nothing;
|
108
|
+
protected renderHeader(): TemplateResult;
|
109
|
+
/**
|
110
|
+
* Returns the icon name based on the expanded state.
|
111
|
+
* If the accordion button is disabled, it always returns the arrow down icon.
|
112
|
+
* Otherwise, it returns the arrow up icon if the accordion button is expanded, otherwise the arrow down icon.
|
113
|
+
* @returns The icon name based on the expanded state.
|
114
|
+
*/
|
115
|
+
protected getArrowIconName(): IconName;
|
116
|
+
protected renderBody(): TemplateResult | typeof nothing;
|
117
|
+
updated(changedProperties: PropertyValues): void;
|
118
|
+
render(): TemplateResult<1>;
|
119
|
+
static styles: Array<CSSResult>;
|
120
|
+
}
|
121
|
+
export default AccordionButton;
|
@@ -0,0 +1,240 @@
|
|
1
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
2
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
3
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
4
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
5
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
6
|
+
};
|
7
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
8
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
9
|
+
};
|
10
|
+
import { html, nothing } from 'lit';
|
11
|
+
import { v4 as uuidv4 } from 'uuid';
|
12
|
+
import { property } from 'lit/decorators.js';
|
13
|
+
import { Component } from '../../models';
|
14
|
+
import { KEYS } from '../../utils/keys';
|
15
|
+
import { DisabledMixin } from '../../utils/mixins/DisabledMixin';
|
16
|
+
import { ROLE } from '../../utils/roles';
|
17
|
+
import { TYPE, VALID_TEXT_TAGS } from '../text/text.constants';
|
18
|
+
import { DEFAULTS, ICON_NAME } from './accordionbutton.constants';
|
19
|
+
import styles from './accordionbutton.styles';
|
20
|
+
/**
|
21
|
+
* An accordion button contains a header and body section with optional slots inside the heading which are focusable.
|
22
|
+
*
|
23
|
+
* The header section contains:
|
24
|
+
* - Prefix Icon
|
25
|
+
* - Header Text
|
26
|
+
*
|
27
|
+
* The body section contains:
|
28
|
+
* - Default slot - User can place any content inside the body section.
|
29
|
+
*
|
30
|
+
* The accordion button can be expanded or collapsed. The visibility of the body section can be controlled by `expanded` attribute. <br/>
|
31
|
+
* There are two types of variants based on that the border styling of the accordion gets reflected. <br/>
|
32
|
+
* There are two sizes of accordion, one is small and the other is large.
|
33
|
+
* Small size has a padding of 1rem (16px) and large size has a padding of 1.5rem (24px) for the body section of accordion.
|
34
|
+
*
|
35
|
+
* By default, the header text in the accordion heading is of H3 with an aria-level of '3'.
|
36
|
+
* If this accordion is placed on any other level in the entire webpage, then do adjust the aria-level number based on that.
|
37
|
+
*
|
38
|
+
* An accordion can be disabled, and when it's disabled, the header section will not be clickable.
|
39
|
+
*
|
40
|
+
* If you do need any controls on your accordion heading, then it's advised to use `accordion` component.
|
41
|
+
*
|
42
|
+
* If an accordion button is expanded by default, then the screen reader might loose focus when toggling the visibilty of the accordion button.
|
43
|
+
*
|
44
|
+
* @tagname mdc-accordionbutton
|
45
|
+
*
|
46
|
+
* @dependency mdc-button
|
47
|
+
* @dependency mdc-icon
|
48
|
+
* @dependency mdc-text
|
49
|
+
*
|
50
|
+
* @slot default - The default slot contains the body section of the accordion. User can place anything inside this body slot.
|
51
|
+
*
|
52
|
+
* @event shown - (React: onShown) This event is triggered when the accordion button is expanded.
|
53
|
+
*
|
54
|
+
* @cssproperty --mdc-accordionbutton-border-color - The border color of the accordion button.
|
55
|
+
* @cssproperty --mdc-accordionbutton-hover-color - The hover color of the accordion button.
|
56
|
+
* @cssproperty --mdc-accordionbutton-active-color - The active color of the accordion button.
|
57
|
+
* @cssproperty --mdc-accordionbutton-disabled-color - The disabled color of the accordion button.
|
58
|
+
*
|
59
|
+
* @csspart header-section - The header section of the accordion button.
|
60
|
+
* @csspart header-button-section - The header button section of the accordion button.
|
61
|
+
* @csspart leading-header - The leading header of the accordion button.
|
62
|
+
* @csspart trailing-header - The trailing header of the accordion button.
|
63
|
+
* @csspart trailing-header__icon - The trailing header icon of the accordion button.
|
64
|
+
* @csspart body-section - The body section of the accordion button.
|
65
|
+
*/
|
66
|
+
class AccordionButton extends DisabledMixin(Component) {
|
67
|
+
constructor() {
|
68
|
+
super(...arguments);
|
69
|
+
/**
|
70
|
+
* The size of the accordion item.
|
71
|
+
* @default 'small'
|
72
|
+
*/
|
73
|
+
this.size = DEFAULTS.SIZE;
|
74
|
+
/**
|
75
|
+
* The variant of the accordion item. Based on the variant, the styling of the accordion gets changed.
|
76
|
+
* @default 'default'
|
77
|
+
*/
|
78
|
+
this.variant = DEFAULTS.VARIANT;
|
79
|
+
/**
|
80
|
+
* The aria level of the accordion component.
|
81
|
+
* @default 3
|
82
|
+
*/
|
83
|
+
this.dataAriaLevel = DEFAULTS.DATA_ARIA_LEVEL;
|
84
|
+
/**
|
85
|
+
* The visibility of the accordion button.
|
86
|
+
* @default false
|
87
|
+
*/
|
88
|
+
this.expanded = DEFAULTS.EXPANDED;
|
89
|
+
/** @internal */
|
90
|
+
this.headSectionId = `head-section-${uuidv4()}`;
|
91
|
+
/** @internal */
|
92
|
+
this.bodySectionId = `body-section-${uuidv4()}`;
|
93
|
+
}
|
94
|
+
/**
|
95
|
+
* Handles the click event of the header section.
|
96
|
+
* If the accordion is disabled, it will not toggle the expanded state.
|
97
|
+
* It will dispatch the `shown` event with the current expanded state.
|
98
|
+
*/
|
99
|
+
handleHeaderClick() {
|
100
|
+
if (this.disabled)
|
101
|
+
return;
|
102
|
+
this.expanded = !this.expanded;
|
103
|
+
this.dispatchHeaderClickEvent();
|
104
|
+
}
|
105
|
+
/**
|
106
|
+
* Dispatches the `shown` event with the current expanded state.
|
107
|
+
* The event is cancelable and bubbles.
|
108
|
+
* The event detail contains the current expanded state.
|
109
|
+
*/
|
110
|
+
dispatchHeaderClickEvent() {
|
111
|
+
const event = new CustomEvent('shown', {
|
112
|
+
bubbles: true,
|
113
|
+
cancelable: true,
|
114
|
+
detail: {
|
115
|
+
expanded: this.expanded,
|
116
|
+
},
|
117
|
+
});
|
118
|
+
this.dispatchEvent(event);
|
119
|
+
}
|
120
|
+
/**
|
121
|
+
* Handles the keydown event of the component.
|
122
|
+
* If the key pressed is either Enter or Space, it calls the handleHeaderClick method.
|
123
|
+
* This allows keyboard users to toggle the accordion button using these keys.
|
124
|
+
* @param event - The KeyboardEvent fired.
|
125
|
+
*/
|
126
|
+
handleKeyDown(event) {
|
127
|
+
if (event.key === KEYS.ENTER || event.key === KEYS.SPACE) {
|
128
|
+
this.handleHeaderClick();
|
129
|
+
}
|
130
|
+
}
|
131
|
+
renderIcon(iconName) {
|
132
|
+
return iconName ? html `<mdc-icon name="${iconName}" length-unit="rem" size="1"></mdc-icon>` : nothing;
|
133
|
+
}
|
134
|
+
renderHeadingText() {
|
135
|
+
return this.headerText
|
136
|
+
? html `<mdc-text id="${this.headSectionId}" type="${TYPE.BODY_LARGE_REGULAR}" tagname=${VALID_TEXT_TAGS.SPAN}
|
137
|
+
>${this.headerText}</mdc-text
|
138
|
+
>`
|
139
|
+
: nothing;
|
140
|
+
}
|
141
|
+
renderHeader() {
|
142
|
+
return html `
|
143
|
+
<div
|
144
|
+
part="header-section"
|
145
|
+
class="mdc-focus-ring"
|
146
|
+
@click="${this.handleHeaderClick}"
|
147
|
+
@keydown="${this.handleKeyDown}"
|
148
|
+
role="${ROLE.HEADING}"
|
149
|
+
aria-level="${this.dataAriaLevel}"
|
150
|
+
tabindex="${this.disabled ? -1 : 0}"
|
151
|
+
>
|
152
|
+
<div
|
153
|
+
part="header-button-section"
|
154
|
+
role="${ROLE.BUTTON}"
|
155
|
+
aria-expanded="${this.expanded}"
|
156
|
+
aria-controls="${this.bodySectionId}"
|
157
|
+
>
|
158
|
+
<div part="leading-header">${this.renderIcon(this.prefixIcon)} ${this.renderHeadingText()}</div>
|
159
|
+
<div part="trailing-header">
|
160
|
+
<div part="trailing-header__icon">${this.renderIcon(this.getArrowIconName())}</div>
|
161
|
+
</div>
|
162
|
+
</div>
|
163
|
+
</div>
|
164
|
+
`;
|
165
|
+
}
|
166
|
+
/**
|
167
|
+
* Returns the icon name based on the expanded state.
|
168
|
+
* If the accordion button is disabled, it always returns the arrow down icon.
|
169
|
+
* Otherwise, it returns the arrow up icon if the accordion button is expanded, otherwise the arrow down icon.
|
170
|
+
* @returns The icon name based on the expanded state.
|
171
|
+
*/
|
172
|
+
getArrowIconName() {
|
173
|
+
if (this.disabled) {
|
174
|
+
return ICON_NAME.ARROW_DOWN;
|
175
|
+
}
|
176
|
+
return this.expanded ? ICON_NAME.ARROW_UP : ICON_NAME.ARROW_DOWN;
|
177
|
+
}
|
178
|
+
renderBody() {
|
179
|
+
// When disabled, then the body section should not be visible,
|
180
|
+
// even if the expanded attribute is set true.
|
181
|
+
if (this.disabled) {
|
182
|
+
return nothing;
|
183
|
+
}
|
184
|
+
if (this.expanded) {
|
185
|
+
return html `<div
|
186
|
+
id="${this.bodySectionId}"
|
187
|
+
aria-labelledby="${this.headSectionId}"
|
188
|
+
part="body-section"
|
189
|
+
role="${ROLE.REGION}"
|
190
|
+
>
|
191
|
+
<slot></slot>
|
192
|
+
</div>`;
|
193
|
+
}
|
194
|
+
return nothing;
|
195
|
+
}
|
196
|
+
updated(changedProperties) {
|
197
|
+
super.updated(changedProperties);
|
198
|
+
if (changedProperties.has('disabled')) {
|
199
|
+
this.setAttribute('aria-disabled', `${this.disabled}`);
|
200
|
+
}
|
201
|
+
if (changedProperties.has('dataAriaLevel') && !this.dataAriaLevel) {
|
202
|
+
this.dataAriaLevel = DEFAULTS.DATA_ARIA_LEVEL;
|
203
|
+
}
|
204
|
+
if (changedProperties.has('size') && !this.size) {
|
205
|
+
this.size = DEFAULTS.SIZE;
|
206
|
+
}
|
207
|
+
if (changedProperties.has('variant') && !this.variant) {
|
208
|
+
this.variant = DEFAULTS.VARIANT;
|
209
|
+
}
|
210
|
+
}
|
211
|
+
render() {
|
212
|
+
return html ` ${this.renderHeader()} ${this.renderBody()} `;
|
213
|
+
}
|
214
|
+
}
|
215
|
+
AccordionButton.styles = [...Component.styles, ...styles];
|
216
|
+
__decorate([
|
217
|
+
property({ type: String, reflect: true }),
|
218
|
+
__metadata("design:type", String)
|
219
|
+
], AccordionButton.prototype, "size", void 0);
|
220
|
+
__decorate([
|
221
|
+
property({ type: String, reflect: true }),
|
222
|
+
__metadata("design:type", String)
|
223
|
+
], AccordionButton.prototype, "variant", void 0);
|
224
|
+
__decorate([
|
225
|
+
property({ type: Number, reflect: true, attribute: 'data-aria-level' }),
|
226
|
+
__metadata("design:type", Number)
|
227
|
+
], AccordionButton.prototype, "dataAriaLevel", void 0);
|
228
|
+
__decorate([
|
229
|
+
property({ type: Boolean, reflect: true }),
|
230
|
+
__metadata("design:type", Boolean)
|
231
|
+
], AccordionButton.prototype, "expanded", void 0);
|
232
|
+
__decorate([
|
233
|
+
property({ type: String, reflect: true, attribute: 'header-text' }),
|
234
|
+
__metadata("design:type", String)
|
235
|
+
], AccordionButton.prototype, "headerText", void 0);
|
236
|
+
__decorate([
|
237
|
+
property({ type: String, attribute: 'prefix-icon' }),
|
238
|
+
__metadata("design:type", String)
|
239
|
+
], AccordionButton.prototype, "prefixIcon", void 0);
|
240
|
+
export default AccordionButton;
|
@@ -0,0 +1,17 @@
|
|
1
|
+
declare const TAG_NAME: "mdc-accordionbutton";
|
2
|
+
declare const ICON_NAME: {
|
3
|
+
readonly ARROW_UP: "arrow-up-bold";
|
4
|
+
readonly ARROW_DOWN: "arrow-down-bold";
|
5
|
+
};
|
6
|
+
declare const VARIANT: {
|
7
|
+
readonly DEFAULT: "default";
|
8
|
+
readonly BORDERLESS: "borderless";
|
9
|
+
};
|
10
|
+
declare const DEFAULTS: {
|
11
|
+
readonly EXPANDED: false;
|
12
|
+
readonly SIZE: "small";
|
13
|
+
readonly DATA_ARIA_LEVEL: 3;
|
14
|
+
readonly VARIANT: "default";
|
15
|
+
readonly ICON_NAME: "arrow-up-bold";
|
16
|
+
};
|
17
|
+
export { TAG_NAME, ICON_NAME, DEFAULTS, VARIANT };
|
@@ -0,0 +1,19 @@
|
|
1
|
+
import utils from '../../utils/tag-name';
|
2
|
+
import { SIZE } from '../accordiongroup/accordiongroup.constants';
|
3
|
+
const TAG_NAME = utils.constructTagName('accordionbutton');
|
4
|
+
const ICON_NAME = {
|
5
|
+
ARROW_UP: 'arrow-up-bold',
|
6
|
+
ARROW_DOWN: 'arrow-down-bold',
|
7
|
+
};
|
8
|
+
const VARIANT = {
|
9
|
+
DEFAULT: 'default',
|
10
|
+
BORDERLESS: 'borderless',
|
11
|
+
};
|
12
|
+
const DEFAULTS = {
|
13
|
+
EXPANDED: false,
|
14
|
+
SIZE: SIZE.SMALL,
|
15
|
+
DATA_ARIA_LEVEL: 3,
|
16
|
+
VARIANT: VARIANT.DEFAULT,
|
17
|
+
ICON_NAME: ICON_NAME.ARROW_UP,
|
18
|
+
};
|
19
|
+
export { TAG_NAME, ICON_NAME, DEFAULTS, VARIANT };
|