@momentum-design/components 0.104.17 → 0.105.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.
Files changed (39) hide show
  1. package/dist/browser/index.js +292 -275
  2. package/dist/browser/index.js.map +4 -4
  3. package/dist/components/listbox/index.d.ts +7 -0
  4. package/dist/components/listbox/index.js +4 -0
  5. package/dist/components/listbox/listbox.component.d.ts +94 -0
  6. package/dist/components/listbox/listbox.component.js +198 -0
  7. package/dist/components/listbox/listbox.constants.d.ts +2 -0
  8. package/dist/components/listbox/listbox.constants.js +3 -0
  9. package/dist/components/listbox/listbox.styles.d.ts +2 -0
  10. package/dist/components/listbox/listbox.styles.js +20 -0
  11. package/dist/components/listbox/listbox.types.d.ts +7 -0
  12. package/dist/components/listbox/listbox.types.js +1 -0
  13. package/dist/components/listitem/listitem.component.d.ts +1 -2
  14. package/dist/components/listitem/listitem.component.js +4 -6
  15. package/dist/components/option/option.component.js +1 -0
  16. package/dist/custom-elements.json +1480 -707
  17. package/dist/index.d.ts +2 -1
  18. package/dist/index.js +2 -1
  19. package/dist/react/index.d.ts +3 -2
  20. package/dist/react/index.js +3 -2
  21. package/dist/react/listbox/index.d.ts +30 -0
  22. package/dist/react/listbox/index.js +38 -0
  23. package/dist/utils/controllers/ElementStore.d.ts +153 -0
  24. package/dist/utils/controllers/ElementStore.js +171 -0
  25. package/dist/utils/dom.d.ts +13 -0
  26. package/dist/utils/dom.js +14 -0
  27. package/dist/utils/mixins/ItemCollectionMixin.d.ts +68 -0
  28. package/dist/utils/mixins/ItemCollectionMixin.js +89 -0
  29. package/dist/utils/mixins/ListNavigationMixin.d.ts +28 -0
  30. package/dist/utils/mixins/ListNavigationMixin.js +199 -0
  31. package/dist/utils/mixins/lifecycle/CaptureDestroyEventForChildElement.d.ts +30 -0
  32. package/dist/utils/mixins/lifecycle/CaptureDestroyEventForChildElement.js +65 -0
  33. package/dist/utils/mixins/lifecycle/LifeCycleMixin.d.ts +33 -0
  34. package/dist/utils/mixins/lifecycle/LifeCycleMixin.js +41 -0
  35. package/dist/utils/mixins/lifecycle/LifeCycleModifiedEvent.d.ts +19 -0
  36. package/dist/utils/mixins/lifecycle/LifeCycleModifiedEvent.js +1 -0
  37. package/dist/utils/mixins/lifecycle/lifecycle.contants.d.ts +5 -0
  38. package/dist/utils/mixins/lifecycle/lifecycle.contants.js +5 -0
  39. package/package.json +1 -1
@@ -0,0 +1,7 @@
1
+ import ListBox from './listbox.component';
2
+ declare global {
3
+ interface HTMLElementTagNameMap {
4
+ ['mdc-listbox']: ListBox;
5
+ }
6
+ }
7
+ export default ListBox;
@@ -0,0 +1,4 @@
1
+ import ListBox from './listbox.component';
2
+ import { TAG_NAME } from './listbox.constants';
3
+ ListBox.register(TAG_NAME);
4
+ export default ListBox;
@@ -0,0 +1,94 @@
1
+ import { CSSResult, PropertyValues } from 'lit';
2
+ import type Option from '../option';
3
+ import { Component } from '../../models';
4
+ declare const ListBox_base: import("../../utils/mixins/index.types").Constructor<Component & import("../../utils/mixins/ListNavigationMixin").ListNavigationMixinInterface> & import("../../utils/mixins/index.types").Constructor<import("../../utils/mixins/lifecycle/CaptureDestroyEventForChildElement").CaptureDestroyEventForChildElementInterface> & typeof Component;
5
+ /**
6
+ * listbox component presents a list of options and allows a user to select one of them.
7
+ *
8
+ * Notes:
9
+ * - This is a standalone listbox component. Select has its own mdc-selectlistbox component.
10
+ * - this component has name and value attributes and also emits change event,
11
+ * but it is not a form control (yet).
12
+ *
13
+ * @dependency mdc-list
14
+ * @dependency mdc-icon
15
+ * @dependency mdc-text
16
+ * @dependency mdc-option
17
+ * @dependency mdc-optgroup
18
+ *
19
+ * @tagname mdc-listbox
20
+ *
21
+ * @cssproperty --mdc-listbox-max-height - max height of the listbox
22
+ *
23
+ * @slot default - This is a default/unnamed slot, where options and optgroups are placed
24
+ *
25
+ * @csspart container - The container of the listbox
26
+ *
27
+ * @event change - (React: onChange) This event is emitted when the selected item changed
28
+ */
29
+ declare class ListBox extends ListBox_base {
30
+ /**
31
+ * According to WCAG this is the expected behavior for listbox
32
+ * https://www.w3.org/WAI/ARIA/apg/practices/listbox
33
+ * @internal
34
+ */
35
+ protected loop: boolean;
36
+ /**
37
+ * The name attribute is used to identify the listbox
38
+ */
39
+ name?: undefined | string;
40
+ /**
41
+ * The value attribute is used to represent the last selected option's value in the listbox.
42
+ */
43
+ value?: undefined | string;
44
+ /** @internal */
45
+ selectedOption?: Option | null;
46
+ /** @internal */
47
+ private itemsStore;
48
+ constructor();
49
+ connectedCallback(): void;
50
+ /** @internal */
51
+ private handleModifiedEvent;
52
+ /**
53
+ * If nothing is selected anymore, clear the value
54
+ * @internal
55
+ */
56
+ private handleNoSelection;
57
+ /** @internal */
58
+ private handleDestroyEvent;
59
+ /** @internal */
60
+ protected get navItems(): HTMLElement[];
61
+ /** @internal */
62
+ private isValidItem;
63
+ /** @internal */
64
+ private handleClick;
65
+ /** @internal */
66
+ private getFirstSelectedOption;
67
+ /**
68
+ * Handles the updated lifecycle event.
69
+ *
70
+ * @param changedProperties - The properties that have changed since the last update.
71
+ */
72
+ protected updated(changedProperties: PropertyValues): void;
73
+ /**
74
+ * When an option is selected, this method updates local and options' DOM state and fires the change event.
75
+ *
76
+ * @param option - The option element in DOM which gets selected.
77
+ * @param fireEvent - A boolean flag to indicate whether to fire the change event or not.
78
+ * @param updateOptions - Whether update the other options or not
79
+ */
80
+ private setSelectedOption;
81
+ /**
82
+ * Update all options selection state in the DDM.
83
+ *
84
+ * @param selectedOption - The option which gets selected
85
+ */
86
+ private updateSelectedInChildOptions;
87
+ /**
88
+ * Dispatch change event when an option is selected.
89
+ */
90
+ private fireEvents;
91
+ render(): import("lit-html").TemplateResult<1>;
92
+ static styles: Array<CSSResult>;
93
+ }
94
+ export default ListBox;
@@ -0,0 +1,198 @@
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 { property, state } from 'lit/decorators.js';
12
+ import List from '../list';
13
+ import { TAG_NAME as OPTION_TAGNAME } from '../option/option.constants';
14
+ import { ROLE } from '../../utils/roles';
15
+ import { CaptureDestroyEventForChildElement } from '../../utils/mixins/lifecycle/CaptureDestroyEventForChildElement';
16
+ import { ListNavigationMixin } from '../../utils/mixins/ListNavigationMixin';
17
+ import { Component } from '../../models';
18
+ import { ElementStore } from '../../utils/controllers/ElementStore';
19
+ import styles from './listbox.styles';
20
+ /**
21
+ * listbox component presents a list of options and allows a user to select one of them.
22
+ *
23
+ * Notes:
24
+ * - This is a standalone listbox component. Select has its own mdc-selectlistbox component.
25
+ * - this component has name and value attributes and also emits change event,
26
+ * but it is not a form control (yet).
27
+ *
28
+ * @dependency mdc-list
29
+ * @dependency mdc-icon
30
+ * @dependency mdc-text
31
+ * @dependency mdc-option
32
+ * @dependency mdc-optgroup
33
+ *
34
+ * @tagname mdc-listbox
35
+ *
36
+ * @cssproperty --mdc-listbox-max-height - max height of the listbox
37
+ *
38
+ * @slot default - This is a default/unnamed slot, where options and optgroups are placed
39
+ *
40
+ * @csspart container - The container of the listbox
41
+ *
42
+ * @event change - (React: onChange) This event is emitted when the selected item changed
43
+ */
44
+ class ListBox extends ListNavigationMixin(CaptureDestroyEventForChildElement(Component)) {
45
+ constructor() {
46
+ super();
47
+ /**
48
+ * According to WCAG this is the expected behavior for listbox
49
+ * https://www.w3.org/WAI/ARIA/apg/practices/listbox
50
+ * @internal
51
+ */
52
+ this.loop = false;
53
+ /**
54
+ * The name attribute is used to identify the listbox
55
+ */
56
+ this.name = undefined;
57
+ /**
58
+ * The value attribute is used to represent the last selected option's value in the listbox.
59
+ */
60
+ this.value = undefined;
61
+ /** @internal */
62
+ this.itemsStore = new ElementStore(this, {
63
+ isValidItem: this.isValidItem,
64
+ });
65
+ /** @internal */
66
+ this.handleDestroyEvent = () => {
67
+ this.handleNoSelection();
68
+ };
69
+ this.addEventListener('click', this.handleClick);
70
+ this.addEventListener('modified', this.handleModifiedEvent);
71
+ this.addEventListener('destroyed', this.handleDestroyEvent);
72
+ }
73
+ connectedCallback() {
74
+ super.connectedCallback();
75
+ this.role = ROLE.LISTBOX;
76
+ }
77
+ /** @internal */
78
+ handleModifiedEvent(event) {
79
+ const item = event.target;
80
+ switch (event.detail.change) {
81
+ case 'enabled':
82
+ this.itemsStore.add(item);
83
+ break;
84
+ case 'disabled':
85
+ this.itemsStore.delete(item);
86
+ break;
87
+ case 'selected':
88
+ // When selection changed on the option
89
+ this.setSelectedOption(item, false, false);
90
+ break;
91
+ case 'unselected':
92
+ this.handleNoSelection();
93
+ break;
94
+ default:
95
+ break;
96
+ }
97
+ }
98
+ /**
99
+ * If nothing is selected anymore, clear the value
100
+ * @internal
101
+ */
102
+ handleNoSelection() {
103
+ const selectedOption = this.getFirstSelectedOption();
104
+ if (!selectedOption) {
105
+ this.selectedOption = undefined;
106
+ this.value = undefined;
107
+ }
108
+ }
109
+ /** @internal */
110
+ get navItems() {
111
+ return this.itemsStore.items;
112
+ }
113
+ /** @internal */
114
+ isValidItem(item) {
115
+ return item.matches(`${OPTION_TAGNAME}:not([disabled])`);
116
+ }
117
+ /** @internal */
118
+ handleClick(event) {
119
+ const target = event.target;
120
+ if (this.isValidItem(target)) {
121
+ this.setSelectedOption(target);
122
+ }
123
+ }
124
+ /** @internal */
125
+ getFirstSelectedOption() {
126
+ return this.itemsStore.items.find(el => el.matches('[selected]'));
127
+ }
128
+ /**
129
+ * Handles the updated lifecycle event.
130
+ *
131
+ * @param changedProperties - The properties that have changed since the last update.
132
+ */
133
+ updated(changedProperties) {
134
+ if (changedProperties.has('value')) {
135
+ const newSelectedOption = this.itemsStore.items.find(option => option.value === this.value);
136
+ if (newSelectedOption) {
137
+ this.setSelectedOption(newSelectedOption, false);
138
+ }
139
+ else {
140
+ this.setSelectedOption(null, false);
141
+ }
142
+ }
143
+ }
144
+ /**
145
+ * When an option is selected, this method updates local and options' DOM state and fires the change event.
146
+ *
147
+ * @param option - The option element in DOM which gets selected.
148
+ * @param fireEvent - A boolean flag to indicate whether to fire the change event or not.
149
+ * @param updateOptions - Whether update the other options or not
150
+ */
151
+ setSelectedOption(option, fireEvent = true, updateOptions = true) {
152
+ if ((option === null || option === void 0 ? void 0 : option.disabled) || (option === null || option === void 0 ? void 0 : option.softDisabled))
153
+ return;
154
+ if (updateOptions) {
155
+ this.updateSelectedInChildOptions(option);
156
+ }
157
+ // set the selected option in the component state
158
+ this.selectedOption = option;
159
+ this.value = option === null || option === void 0 ? void 0 : option.value;
160
+ if (fireEvent) {
161
+ this.fireEvents();
162
+ }
163
+ }
164
+ /**
165
+ * Update all options selection state in the DDM.
166
+ *
167
+ * @param selectedOption - The option which gets selected
168
+ */
169
+ updateSelectedInChildOptions(selectedOption) {
170
+ this.itemsStore.items.forEach(option => option.removeAttribute('selected'));
171
+ selectedOption === null || selectedOption === void 0 ? void 0 : selectedOption.toggleAttribute('selected', true);
172
+ }
173
+ /**
174
+ * Dispatch change event when an option is selected.
175
+ */
176
+ fireEvents() {
177
+ if (this.selectedOption) {
178
+ this.dispatchEvent(new Event('change', { composed: true, bubbles: true }));
179
+ }
180
+ }
181
+ render() {
182
+ return html `<slot part="container"></slot>`;
183
+ }
184
+ }
185
+ ListBox.styles = [...List.styles, ...styles];
186
+ __decorate([
187
+ property({ type: String, reflect: true }),
188
+ __metadata("design:type", Object)
189
+ ], ListBox.prototype, "name", void 0);
190
+ __decorate([
191
+ property({ type: String, reflect: true }),
192
+ __metadata("design:type", Object)
193
+ ], ListBox.prototype, "value", void 0);
194
+ __decorate([
195
+ state(),
196
+ __metadata("design:type", Object)
197
+ ], ListBox.prototype, "selectedOption", void 0);
198
+ export default ListBox;
@@ -0,0 +1,2 @@
1
+ declare const TAG_NAME: "mdc-listbox";
2
+ export { TAG_NAME };
@@ -0,0 +1,3 @@
1
+ import utils from '../../utils/tag-name';
2
+ const TAG_NAME = utils.constructTagName('listbox');
3
+ export { TAG_NAME };
@@ -0,0 +1,2 @@
1
+ declare const _default: import("lit").CSSResult[];
2
+ export default _default;
@@ -0,0 +1,20 @@
1
+ import { css } from 'lit';
2
+ const styles = css `
3
+ :host {
4
+ --mdc-listbox-max-height: auto;
5
+
6
+ height: inherit;
7
+ width: inherit;
8
+
9
+ overflow-y: scroll;
10
+ max-height: var(--mdc-listbox-max-height);
11
+
12
+ /* prevent focus ring clipping */
13
+ padding: 0.25rem;
14
+ }
15
+
16
+ ::slotted(mdc-option) {
17
+ width: 100%;
18
+ }
19
+ `;
20
+ export default [styles];
@@ -0,0 +1,7 @@
1
+ import { OverrideEventTarget } from '../../utils/types';
2
+ import type ListBox from './listbox.component';
3
+ export type ListBoxChangeEvent = OverrideEventTarget<Event, ListBox>;
4
+ interface Events {
5
+ onChangeEvent: ListBoxChangeEvent;
6
+ }
7
+ export type { Events };
@@ -0,0 +1 @@
1
+ export {};
@@ -3,7 +3,7 @@ import { Component } from '../../models';
3
3
  import type { PopoverPlacement } from '../popover/popover.types';
4
4
  import type { TextType } from '../text/text.types';
5
5
  import { ListItemVariants } from './listitem.types';
6
- declare const ListItem_base: import("../../utils/mixins/index.types").Constructor<import("../../utils/mixins/DisabledMixin").DisabledMixinInterface> & import("../../utils/mixins/index.types").Constructor<import("../../utils/mixins/TabIndexMixin").TabIndexMixinInterface> & typeof Component;
6
+ declare const ListItem_base: import("../../utils/mixins/index.types").Constructor<import("../../utils/mixins/DisabledMixin").DisabledMixinInterface> & import("../../utils/mixins/index.types").Constructor<import("../../utils/mixins/TabIndexMixin").TabIndexMixinInterface> & import("../../utils/mixins/index.types").Constructor<import("../../utils/mixins/lifecycle/LifeCycleMixin").LifeCycleMixinInterface> & typeof Component;
7
7
  /**
8
8
  * mdc-listitem component is used to display a label with different types of controls.
9
9
  * There can be three types of controls, a radio button, a checkbox on the
@@ -117,7 +117,6 @@ declare class ListItem extends ListItem_base {
117
117
  tooltipPlacement: PopoverPlacement;
118
118
  constructor();
119
119
  connectedCallback(): void;
120
- disconnectedCallback(): void;
121
120
  /**
122
121
  * Fires the click event when the enter or space key is pressed down.
123
122
  * This behavior is similar to a button click and key interaction.
@@ -16,6 +16,7 @@ import { TabIndexMixin } from '../../utils/mixins/TabIndexMixin';
16
16
  import { ROLE } from '../../utils/roles';
17
17
  import { TYPE, VALID_TEXT_TAGS } from '../text/text.constants';
18
18
  import { TAG_NAME as TOOLTIP_TAG_NAME } from '../tooltip/tooltip.constants';
19
+ import { LifeCycleMixin } from '../../utils/mixins/lifecycle/LifeCycleMixin';
19
20
  import { DEFAULTS } from './listitem.constants';
20
21
  import styles from './listitem.styles';
21
22
  import { generateListItemId, generateTooltipId } from './listitem.utils';
@@ -75,7 +76,7 @@ import { ListItemEventManager } from './listitem.events';
75
76
  * @event created - (React: onCreated) This event is dispatched after the listitem is created (added to the DOM)
76
77
  * @event destroyed - (React: onDestroyed) This event is dispatched after the listitem is destroyed (removed from the DOM)
77
78
  */
78
- class ListItem extends DisabledMixin(TabIndexMixin(Component)) {
79
+ class ListItem extends DisabledMixin(TabIndexMixin(LifeCycleMixin(Component))) {
79
80
  constructor() {
80
81
  super();
81
82
  /**
@@ -101,11 +102,6 @@ class ListItem extends DisabledMixin(TabIndexMixin(Component)) {
101
102
  this.role = this.role || ROLE.LISTITEM;
102
103
  // Add a unique id to the listitem if it does not have one.
103
104
  this.id = this.id || generateListItemId();
104
- ListItemEventManager.onCreatedListItem(this);
105
- }
106
- disconnectedCallback() {
107
- super.disconnectedCallback();
108
- ListItemEventManager.onDestroyedListItem(this);
109
105
  }
110
106
  /**
111
107
  * Fires the click event when the enter or space key is pressed down.
@@ -206,10 +202,12 @@ class ListItem extends DisabledMixin(TabIndexMixin(Component)) {
206
202
  [...this.leadingControlsSlot, ...this.trailingControlsSlot].forEach(element => {
207
203
  if (disabled) {
208
204
  element.setAttribute('disabled', '');
205
+ this.dispatchModifiedEvent('disabled');
209
206
  ListItemEventManager.onDisableListItem(this);
210
207
  }
211
208
  else {
212
209
  element.removeAttribute('disabled');
210
+ this.dispatchModifiedEvent('enabled');
213
211
  ListItemEventManager.onEnableListItem(this);
214
212
  }
215
213
  });
@@ -68,6 +68,7 @@ class Option extends FormInternalsMixin(ListItem) {
68
68
  super.update(changedProperties);
69
69
  if (changedProperties.has('selected')) {
70
70
  this.setAttribute('aria-selected', `${this.selected}`);
71
+ this.dispatchModifiedEvent(this.selected ? 'selected' : 'unselected');
71
72
  }
72
73
  }
73
74
  render() {