@digital-realty/ix-multi-select 0.0.5 → 0.0.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.
@@ -1,4 +1,4 @@
1
- import { LitElement } from 'lit';
1
+ import { LitElement, PropertyValues } from 'lit';
2
2
  import '@digital-realty/ix-chip/ix-chip-set.js';
3
3
  import '@digital-realty/ix-chip/ix-chip.js';
4
4
  import '@digital-realty/ix-field/ix-field.js';
@@ -6,7 +6,7 @@ import '@digital-realty/ix-menu/ix-menu.js';
6
6
  import '@digital-realty/ix-menu/ix-menu-item.js';
7
7
  import '@digital-realty/ix-icon-button/ix-icon-button.js';
8
8
  import { IxMenu } from '@digital-realty/ix-menu';
9
- import { IxChipSet } from '@digital-realty/ix-chip/dist/IxChipSet.js';
9
+ import { IxChipSet } from '@digital-realty/ix-chip';
10
10
  interface MultiSelectItem {
11
11
  label: string;
12
12
  selected: boolean;
@@ -14,18 +14,77 @@ interface MultiSelectItem {
14
14
  }
15
15
  export declare class IxMultiSelect extends LitElement {
16
16
  static get styles(): import("lit").CSSResult[];
17
+ /** @nocollapse */
18
+ static shadowRootOptions: {
19
+ delegatesFocus: boolean;
20
+ mode: ShadowRootMode;
21
+ slotAssignment?: SlotAssignmentMode | undefined;
22
+ customElements?: CustomElementRegistry | undefined;
23
+ registry?: CustomElementRegistry | undefined;
24
+ };
25
+ /** @nocollapse */
26
+ static readonly formAssociated = true;
27
+ private readonly internals;
28
+ /**
29
+ * The associated form element with which this element's value will submit.
30
+ */
31
+ get form(): HTMLFormElement | null;
32
+ /**
33
+ * The labels this element is associated with.
34
+ */
35
+ get labels(): NodeList;
36
+ /**
37
+ * The HTML name to use in form submission.
38
+ */
39
+ get name(): string;
40
+ /**
41
+ * Returns the text field's validation error message.
42
+ *
43
+ * https://developer.mozilla.org/en-US/docs/Web/HTML/Constraint_validation
44
+ */
45
+ get validationMessage(): string;
46
+ /**
47
+ * Returns a `ValidityState` object that represents the validity states of the
48
+ * text field.
49
+ *
50
+ * https://developer.mozilla.org/en-US/docs/Web/API/ValidityState
51
+ */
52
+ get validity(): ValidityState;
53
+ /**
54
+ * Returns whether an element will successfully validate based on forms
55
+ * validation rules and constraints.
56
+ *
57
+ * https://developer.mozilla.org/en-US/docs/Web/API/ElementInternals/willValidate
58
+ */
59
+ get willValidate(): boolean;
60
+ checkValidity(): boolean;
61
+ reportValidity(): boolean;
17
62
  menu: IxMenu;
18
63
  chips: IxChipSet;
19
64
  inputFilter: HTMLInputElement;
20
65
  items: MultiSelectItem[];
21
66
  label: string;
67
+ errorText: string;
68
+ disabled: boolean;
69
+ /**
70
+ * Gets or sets whether or not the text field is in a visually invalid state.
71
+ *
72
+ * This error state overrides the error state controlled by
73
+ * `reportValidity()`.
74
+ */
75
+ error: boolean;
76
+ required: boolean;
22
77
  private _items;
23
78
  private filterValue;
24
79
  private menuOpen;
25
80
  private focused;
26
81
  private noFilteredOptions;
27
- get value(): string[];
82
+ get value(): string;
83
+ set value(selected: string);
28
84
  firstUpdated(): void;
85
+ updated(changedProperties: PropertyValues): void;
86
+ handleFocusin: () => void;
87
+ handleFocusout: () => void;
29
88
  private optionSelect;
30
89
  private chipRemove;
31
90
  private filterOptions;
@@ -34,6 +93,12 @@ export declare class IxMultiSelect extends LitElement {
34
93
  handleMenuClose: () => void;
35
94
  toggleOpen: (e: Event) => void;
36
95
  clear: (e: Event) => void;
96
+ /** @private */
97
+ formResetCallback(): void;
98
+ /**
99
+ * Reset the text field to its default value.
100
+ */
101
+ reset(): void;
37
102
  render(): import("lit").TemplateResult<1>;
38
103
  }
39
104
  export {};
@@ -1,6 +1,8 @@
1
1
  import { __decorate } from "tslib";
2
2
  import { html, LitElement, nothing } from 'lit';
3
3
  import { property, query, state } from 'lit/decorators.js';
4
+ import { classMap } from 'lit/directives/class-map.js';
5
+ import { requestUpdateOnAriaChange } from '@material/web/internal/aria/delegate.js';
4
6
  import '@digital-realty/ix-chip/ix-chip-set.js';
5
7
  import '@digital-realty/ix-chip/ix-chip.js';
6
8
  import '@digital-realty/ix-field/ix-field.js';
@@ -11,13 +13,36 @@ import { IxMultiSelectStyles } from './ix-multi-select-styles.js';
11
13
  export class IxMultiSelect extends LitElement {
12
14
  constructor() {
13
15
  super(...arguments);
16
+ this.internals = this /* needed for closure */
17
+ .attachInternals();
14
18
  this.items = [];
15
19
  this.label = '';
20
+ this.errorText = 'Invalid error text';
21
+ this.disabled = false;
22
+ /**
23
+ * Gets or sets whether or not the text field is in a visually invalid state.
24
+ *
25
+ * This error state overrides the error state controlled by
26
+ * `reportValidity()`.
27
+ */
28
+ this.error = false;
29
+ this.required = false;
16
30
  this._items = [];
17
31
  this.filterValue = '';
18
32
  this.menuOpen = false;
19
33
  this.focused = false;
20
34
  this.noFilteredOptions = 'No options';
35
+ this.handleFocusin = () => {
36
+ this.focused = true;
37
+ };
38
+ this.handleFocusout = () => {
39
+ if (this.value.length) {
40
+ this.focused = true;
41
+ }
42
+ else {
43
+ this.focused = false;
44
+ }
45
+ };
21
46
  this.optionSelect = (e, id) => {
22
47
  const ischecked = e.target.checked;
23
48
  this._items = this._items.map((item, i) => id === i
@@ -78,6 +103,7 @@ export class IxMultiSelect extends LitElement {
78
103
  this.clear = (e) => {
79
104
  e.stopPropagation();
80
105
  this._items = this._items.map(item => ({ ...item, selected: false }));
106
+ this.focused = false;
81
107
  this.dispatchEvent(new CustomEvent('clear-multi-select', {
82
108
  bubbles: true,
83
109
  composed: true,
@@ -87,23 +113,118 @@ export class IxMultiSelect extends LitElement {
87
113
  static get styles() {
88
114
  return [IxMultiSelectStyles];
89
115
  }
116
+ /**
117
+ * The associated form element with which this element's value will submit.
118
+ */
119
+ get form() {
120
+ return this.internals.form;
121
+ }
122
+ /**
123
+ * The labels this element is associated with.
124
+ */
125
+ get labels() {
126
+ return this.internals.labels;
127
+ }
128
+ /**
129
+ * The HTML name to use in form submission.
130
+ */
131
+ get name() {
132
+ var _a;
133
+ return (_a = this.getAttribute('name')) !== null && _a !== void 0 ? _a : '';
134
+ }
135
+ /**
136
+ * Returns the text field's validation error message.
137
+ *
138
+ * https://developer.mozilla.org/en-US/docs/Web/HTML/Constraint_validation
139
+ */
140
+ get validationMessage() {
141
+ return this.internals.validationMessage;
142
+ }
143
+ /**
144
+ * Returns a `ValidityState` object that represents the validity states of the
145
+ * text field.
146
+ *
147
+ * https://developer.mozilla.org/en-US/docs/Web/API/ValidityState
148
+ */
149
+ get validity() {
150
+ return this.internals.validity;
151
+ }
152
+ /**
153
+ * Returns whether an element will successfully validate based on forms
154
+ * validation rules and constraints.
155
+ *
156
+ * https://developer.mozilla.org/en-US/docs/Web/API/ElementInternals/willValidate
157
+ */
158
+ get willValidate() {
159
+ return this.internals.willValidate;
160
+ }
161
+ checkValidity() {
162
+ return this.internals.checkValidity();
163
+ }
164
+ reportValidity() {
165
+ return this.internals.reportValidity();
166
+ }
90
167
  get value() {
91
- return this._items.filter(item => item.selected).map(item => item.label);
168
+ return this._items
169
+ .filter(item => item.selected)
170
+ .map(item => item.label)
171
+ .join(', ');
172
+ }
173
+ set value(selected) {
174
+ const vals = selected.split(',').map(item => item.trim());
175
+ this._items = this._items.map(item => ({
176
+ ...item,
177
+ selected: vals.includes(item.label),
178
+ }));
92
179
  }
93
180
  firstUpdated() {
94
181
  this._items = [...this.items];
95
- if (this._items.length > 0) {
182
+ if (this._items.find(item => item.selected)) {
96
183
  this.focused = true;
97
184
  }
185
+ this.internals.setFormValue(this.value);
186
+ }
187
+ updated(changedProperties) {
188
+ if (changedProperties.has('_items') || changedProperties.has('disabled')) {
189
+ this.internals.setFormValue(this.value);
190
+ if (this._items.find(item => item.selected)) {
191
+ this.focused = true;
192
+ }
193
+ else {
194
+ this.focused = false;
195
+ }
196
+ }
197
+ }
198
+ /** @private */
199
+ formResetCallback() {
200
+ this.reset();
201
+ }
202
+ /**
203
+ * Reset the text field to its default value.
204
+ */
205
+ reset() {
206
+ this._items = this._items.map(item => ({ ...item, selected: false }));
98
207
  }
99
208
  render() {
209
+ const classes = {
210
+ disabled: this.disabled,
211
+ error: !this.disabled && this.error,
212
+ };
100
213
  return html `
101
214
  <div class="multi-select">
102
215
  <ix-field
216
+ class="${classMap(classes)}"
103
217
  id="anchor"
104
- .focused=${this.focused}
218
+ ?focused=${this.focused}
219
+ ?disabled=${this.disabled}
220
+ ?required=${this.required}
221
+ ?error=${this.error}
222
+ error-text=${this.errorText}
105
223
  label=${this.label}
106
224
  @click=${() => this.inputFilter.focus()}
225
+ @focusin=${this.handleFocusin}
226
+ @focusout=${this.handleFocusout}
227
+ ?populated=${this._items.find(item => item.selected)}
107
228
  >
108
229
  <ix-chip-set>
109
230
  ${this._items.map((item, id) => item.selected
@@ -175,6 +296,16 @@ export class IxMultiSelect extends LitElement {
175
296
  `;
176
297
  }
177
298
  }
299
+ (() => {
300
+ requestUpdateOnAriaChange(IxMultiSelect);
301
+ })();
302
+ /** @nocollapse */
303
+ IxMultiSelect.shadowRootOptions = {
304
+ ...LitElement.shadowRootOptions,
305
+ delegatesFocus: true,
306
+ };
307
+ /** @nocollapse */
308
+ IxMultiSelect.formAssociated = true;
178
309
  __decorate([
179
310
  query('ix-menu')
180
311
  ], IxMultiSelect.prototype, "menu", void 0);
@@ -190,6 +321,18 @@ __decorate([
190
321
  __decorate([
191
322
  property({ type: String })
192
323
  ], IxMultiSelect.prototype, "label", void 0);
324
+ __decorate([
325
+ property({ type: String, attribute: 'error-text' })
326
+ ], IxMultiSelect.prototype, "errorText", void 0);
327
+ __decorate([
328
+ property({ type: Boolean, reflect: true })
329
+ ], IxMultiSelect.prototype, "disabled", void 0);
330
+ __decorate([
331
+ property({ type: Boolean, reflect: true })
332
+ ], IxMultiSelect.prototype, "error", void 0);
333
+ __decorate([
334
+ property({ type: Boolean, reflect: true })
335
+ ], IxMultiSelect.prototype, "required", void 0);
193
336
  __decorate([
194
337
  state()
195
338
  ], IxMultiSelect.prototype, "_items", void 0);
@@ -1 +1 @@
1
- {"version":3,"file":"IxMultiSelect.js","sourceRoot":"","sources":["../src/IxMultiSelect.ts"],"names":[],"mappings":"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","sourcesContent":["import { html, LitElement, nothing } from 'lit';\nimport { property, query, state } from 'lit/decorators.js';\nimport '@digital-realty/ix-chip/ix-chip-set.js';\nimport '@digital-realty/ix-chip/ix-chip.js';\nimport '@digital-realty/ix-field/ix-field.js';\nimport '@digital-realty/ix-menu/ix-menu.js';\nimport '@digital-realty/ix-menu/ix-menu-item.js';\nimport '@digital-realty/ix-icon-button/ix-icon-button.js';\nimport { IxMenu } from '@digital-realty/ix-menu';\nimport { IxChipSet } from '@digital-realty/ix-chip/dist/IxChipSet.js';\nimport { IxMultiSelectStyles } from './ix-multi-select-styles.js';\n\ninterface MultiSelectItem {\n label: string;\n selected: boolean;\n filtered: boolean;\n}\n\nexport class IxMultiSelect extends LitElement {\n static get styles() {\n return [IxMultiSelectStyles];\n }\n\n @query('ix-menu') menu!: IxMenu;\n\n @query('ix-chip-set') chips!: IxChipSet;\n\n @query('#filter') inputFilter!: HTMLInputElement;\n\n @property({ type: Array }) items: MultiSelectItem[] = [];\n\n @property({ type: String }) label = '';\n\n @state() private _items: MultiSelectItem[] = [];\n\n @state() private filterValue = '';\n\n @state() private menuOpen = false;\n\n @state() private focused = false;\n\n private noFilteredOptions = 'No options';\n\n get value() {\n return this._items.filter(item => item.selected).map(item => item.label);\n }\n\n firstUpdated() {\n this._items = [...this.items];\n if (this._items.length > 0) {\n this.focused = true;\n }\n }\n\n private optionSelect = (e: InputEvent, id: number) => {\n const ischecked = (<HTMLInputElement>e.target).checked;\n this._items = this._items.map((item, i: number) =>\n id === i\n ? { ...item, selected: ischecked, filtered: false }\n : { ...item, filtered: false }\n );\n this.dispatchEvent(\n new CustomEvent('toggle-multi-select-item', {\n detail: { label: this._items[id].label, selected: ischecked },\n bubbles: true,\n composed: true,\n })\n );\n this.filterValue = '';\n };\n\n private chipRemove = (id: number) => {\n this._items = this._items.map((item, i: number) =>\n id === i ? { ...item, selected: false } : { ...item }\n );\n this.dispatchEvent(\n new CustomEvent('remove-multi-select-item', {\n detail: this._items[id].label,\n bubbles: true,\n composed: true,\n })\n );\n };\n\n private filterOptions = (e: InputEvent) => {\n const filterValue = (<HTMLInputElement>e.target).value.toLocaleLowerCase();\n this.filterValue = filterValue;\n this._items = this._items.map(item => {\n const filtered = item.label.toLowerCase().indexOf(filterValue) === -1;\n return { ...item, filtered };\n });\n };\n\n focusin = () => {\n this.menu.show();\n this.focused = true;\n };\n\n handleMenuOpen = () => {\n this.focused = true;\n this.menuOpen = true;\n const innerMenu = this.menu.shadowRoot?.querySelector(\n '.menu'\n ) as HTMLElement;\n if (innerMenu) {\n innerMenu.style.width = '100%';\n innerMenu.style.insetBlockStart = '0';\n }\n };\n\n handleMenuClose = () => {\n if (this.value.length === 0) {\n this.focused = false;\n }\n this.menuOpen = false;\n };\n\n toggleOpen = (e: Event) => {\n e.stopPropagation();\n if (!this.menuOpen) {\n this.focusin();\n } else {\n this.menu.close();\n }\n };\n\n clear = (e: Event) => {\n e.stopPropagation();\n this._items = this._items.map(item => ({ ...item, selected: false }));\n this.dispatchEvent(\n new CustomEvent('clear-multi-select', {\n bubbles: true,\n composed: true,\n })\n );\n };\n\n render() {\n return html`\n <div class=\"multi-select\">\n <ix-field\n id=\"anchor\"\n .focused=${this.focused}\n label=${this.label}\n @click=${() => this.inputFilter.focus()}\n >\n <ix-chip-set>\n ${this._items.map((item, id: number) =>\n item.selected\n ? html`<span\n ><ix-chip\n @remove=${() => this.chipRemove(id)}\n label=${item.label}\n appearance=\"input\"\n removable\n remove-only\n ></ix-chip\n ></span>`\n : nothing\n )}\n <input\n id=\"filter\"\n @input=${this.filterOptions}\n @focus=${this.focusin}\n .value=${this.filterValue}\n class=\"flex-fill\"\n type=\"text\"\n />\n </ix-chip-set>\n <slot name=\"end\" slot=\"end\">\n ${this.value.length\n ? html`<ix-icon-button\n @click=${this.clear}\n icon=\"close\"\n aria-label=\"clear\"\n ></ix-icon-button>`\n : nothing}\n <ix-icon-button\n @click=${this.toggleOpen}\n class=\"open-icon\"\n icon=${`arrow_drop_${this.menuOpen ? 'up' : 'down'}`}\n aria-label=\"options\"\n ></ix-icon-button>\n </slot>\n </ix-field>\n <div class=\"menu\">\n <ix-menu\n anchor=\"anchor\"\n skip-restore-focus\n quick\n @opening=${this.handleMenuOpen}\n @closing=${this.handleMenuClose}\n >\n ${this._items.filter(item => !item.filtered).length\n ? this._items.map(\n (item, id: number) =>\n html`${!item.filtered\n ? html`<ix-menu-item\n keep-open\n class=${item.selected ? 'selected' : ''}\n >\n <div slot=\"headline\">\n <label>\n <input\n type=\"checkbox\"\n @change=${(e: InputEvent) =>\n this.optionSelect(e, id)}\n .checked=${item.selected}\n />\n ${item.label}\n </label>\n </div>\n </ix-menu-item>`\n : nothing}`\n )\n : html`<ix-menu-item>${this.noFilteredOptions}</ix-menu-item>`}\n </ix-menu>\n </div>\n </div>\n `;\n }\n}\n"]}
1
+ {"version":3,"file":"IxMultiSelect.js","sourceRoot":"","sources":["../src/IxMultiSelect.ts"],"names":[],"mappings":"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","sourcesContent":["import { html, LitElement, nothing, PropertyValues } from 'lit';\nimport { property, query, state } from 'lit/decorators.js';\nimport { classMap } from 'lit/directives/class-map.js';\nimport { requestUpdateOnAriaChange } from '@material/web/internal/aria/delegate.js';\nimport '@digital-realty/ix-chip/ix-chip-set.js';\nimport '@digital-realty/ix-chip/ix-chip.js';\nimport '@digital-realty/ix-field/ix-field.js';\nimport '@digital-realty/ix-menu/ix-menu.js';\nimport '@digital-realty/ix-menu/ix-menu-item.js';\nimport '@digital-realty/ix-icon-button/ix-icon-button.js';\nimport { IxMenu } from '@digital-realty/ix-menu';\nimport { IxChipSet } from '@digital-realty/ix-chip';\nimport { IxMultiSelectStyles } from './ix-multi-select-styles.js';\n\ninterface MultiSelectItem {\n label: string;\n selected: boolean;\n filtered: boolean;\n}\n\nexport class IxMultiSelect extends LitElement {\n static get styles() {\n return [IxMultiSelectStyles];\n }\n\n static {\n requestUpdateOnAriaChange(IxMultiSelect);\n }\n\n /** @nocollapse */\n static override shadowRootOptions = {\n ...LitElement.shadowRootOptions,\n delegatesFocus: true,\n };\n\n /** @nocollapse */\n static readonly formAssociated = true;\n\n private readonly internals = (this as HTMLElement) /* needed for closure */\n .attachInternals();\n\n /**\n * The associated form element with which this element's value will submit.\n */\n get form() {\n return this.internals.form;\n }\n\n /**\n * The labels this element is associated with.\n */\n get labels() {\n return this.internals.labels;\n }\n\n /**\n * The HTML name to use in form submission.\n */\n get name() {\n return this.getAttribute('name') ?? '';\n }\n\n /**\n * Returns the text field's validation error message.\n *\n * https://developer.mozilla.org/en-US/docs/Web/HTML/Constraint_validation\n */\n get validationMessage() {\n return this.internals.validationMessage;\n }\n\n /**\n * Returns a `ValidityState` object that represents the validity states of the\n * text field.\n *\n * https://developer.mozilla.org/en-US/docs/Web/API/ValidityState\n */\n get validity() {\n return this.internals.validity;\n }\n\n /**\n * Returns whether an element will successfully validate based on forms\n * validation rules and constraints.\n *\n * https://developer.mozilla.org/en-US/docs/Web/API/ElementInternals/willValidate\n */\n get willValidate() {\n return this.internals.willValidate;\n }\n\n checkValidity() {\n return this.internals.checkValidity();\n }\n\n reportValidity() {\n return this.internals.reportValidity();\n }\n\n @query('ix-menu') menu!: IxMenu;\n\n @query('ix-chip-set') chips!: IxChipSet;\n\n @query('#filter') inputFilter!: HTMLInputElement;\n\n @property({ type: Array }) items: MultiSelectItem[] = [];\n\n @property({ type: String }) label = '';\n\n @property({ type: String, attribute: 'error-text' }) errorText =\n 'Invalid error text';\n\n @property({ type: Boolean, reflect: true }) disabled = false;\n\n /**\n * Gets or sets whether or not the text field is in a visually invalid state.\n *\n * This error state overrides the error state controlled by\n * `reportValidity()`.\n */\n @property({ type: Boolean, reflect: true }) error = false;\n\n @property({ type: Boolean, reflect: true }) required = false;\n\n @state() private _items: MultiSelectItem[] = [];\n\n @state() private filterValue = '';\n\n @state() private menuOpen = false;\n\n @state() private focused = false;\n\n private noFilteredOptions = 'No options';\n\n get value() {\n return this._items\n .filter(item => item.selected)\n .map(item => item.label)\n .join(', ');\n }\n\n set value(selected: string) {\n const vals = selected.split(',').map(item => item.trim());\n this._items = this._items.map(item => ({\n ...item,\n selected: vals.includes(item.label),\n }));\n }\n\n firstUpdated() {\n this._items = [...this.items];\n if (this._items.find(item => item.selected)) {\n this.focused = true;\n }\n this.internals.setFormValue(this.value);\n }\n\n updated(changedProperties: PropertyValues) {\n if (changedProperties.has('_items') || changedProperties.has('disabled')) {\n this.internals.setFormValue(this.value);\n if (this._items.find(item => item.selected)) {\n this.focused = true;\n } else {\n this.focused = false;\n }\n }\n }\n\n handleFocusin = () => {\n this.focused = true;\n };\n\n handleFocusout = () => {\n if (this.value.length) {\n this.focused = true;\n } else {\n this.focused = false;\n }\n };\n\n private optionSelect = (e: InputEvent, id: number) => {\n const ischecked = (<HTMLInputElement>e.target).checked;\n this._items = this._items.map((item, i: number) =>\n id === i\n ? { ...item, selected: ischecked, filtered: false }\n : { ...item, filtered: false }\n );\n this.dispatchEvent(\n new CustomEvent('toggle-multi-select-item', {\n detail: { label: this._items[id].label, selected: ischecked },\n bubbles: true,\n composed: true,\n })\n );\n this.filterValue = '';\n };\n\n private chipRemove = (id: number) => {\n this._items = this._items.map((item, i: number) =>\n id === i ? { ...item, selected: false } : { ...item }\n );\n this.dispatchEvent(\n new CustomEvent('remove-multi-select-item', {\n detail: this._items[id].label,\n bubbles: true,\n composed: true,\n })\n );\n };\n\n private filterOptions = (e: InputEvent) => {\n const filterValue = (<HTMLInputElement>e.target).value.toLocaleLowerCase();\n this.filterValue = filterValue;\n this._items = this._items.map(item => {\n const filtered = item.label.toLowerCase().indexOf(filterValue) === -1;\n return { ...item, filtered };\n });\n };\n\n focusin = () => {\n this.menu.show();\n this.focused = true;\n };\n\n handleMenuOpen = () => {\n this.focused = true;\n this.menuOpen = true;\n const innerMenu = this.menu.shadowRoot?.querySelector(\n '.menu'\n ) as HTMLElement;\n if (innerMenu) {\n innerMenu.style.width = '100%';\n innerMenu.style.insetBlockStart = '0';\n }\n };\n\n handleMenuClose = () => {\n if (this.value.length === 0) {\n this.focused = false;\n }\n this.menuOpen = false;\n };\n\n toggleOpen = (e: Event) => {\n e.stopPropagation();\n if (!this.menuOpen) {\n this.focusin();\n } else {\n this.menu.close();\n }\n };\n\n clear = (e: Event) => {\n e.stopPropagation();\n this._items = this._items.map(item => ({ ...item, selected: false }));\n this.focused = false;\n this.dispatchEvent(\n new CustomEvent('clear-multi-select', {\n bubbles: true,\n composed: true,\n })\n );\n };\n\n /** @private */\n formResetCallback() {\n this.reset();\n }\n\n /**\n * Reset the text field to its default value.\n */\n reset() {\n this._items = this._items.map(item => ({ ...item, selected: false }));\n }\n\n render() {\n const classes = {\n disabled: this.disabled,\n error: !this.disabled && this.error,\n };\n\n return html`\n <div class=\"multi-select\">\n <ix-field\n class=\"${classMap(classes)}\"\n id=\"anchor\"\n ?focused=${this.focused}\n ?disabled=${this.disabled}\n ?required=${this.required}\n ?error=${this.error}\n error-text=${this.errorText}\n label=${this.label}\n @click=${() => this.inputFilter.focus()}\n @focusin=${this.handleFocusin}\n @focusout=${this.handleFocusout}\n ?populated=${this._items.find(item => item.selected)}\n >\n <ix-chip-set>\n ${this._items.map((item, id: number) =>\n item.selected\n ? html`<span\n ><ix-chip\n @remove=${() => this.chipRemove(id)}\n label=${item.label}\n appearance=\"input\"\n removable\n remove-only\n ></ix-chip\n ></span>`\n : nothing\n )}\n <input\n id=\"filter\"\n @input=${this.filterOptions}\n @focus=${this.focusin}\n .value=${this.filterValue}\n class=\"flex-fill\"\n type=\"text\"\n />\n </ix-chip-set>\n <slot name=\"end\" slot=\"end\">\n ${this.value.length\n ? html`<ix-icon-button\n @click=${this.clear}\n icon=\"close\"\n aria-label=\"clear\"\n ></ix-icon-button>`\n : nothing}\n <ix-icon-button\n @click=${this.toggleOpen}\n class=\"open-icon\"\n icon=${`arrow_drop_${this.menuOpen ? 'up' : 'down'}`}\n aria-label=\"options\"\n ></ix-icon-button>\n </slot>\n </ix-field>\n <div class=\"menu\">\n <ix-menu\n anchor=\"anchor\"\n skip-restore-focus\n quick\n @opening=${this.handleMenuOpen}\n @closing=${this.handleMenuClose}\n >\n ${this._items.filter(item => !item.filtered).length\n ? this._items.map(\n (item, id: number) =>\n html`${!item.filtered\n ? html`<ix-menu-item\n keep-open\n class=${item.selected ? 'selected' : ''}\n >\n <div slot=\"headline\">\n <label>\n <input\n type=\"checkbox\"\n @change=${(e: InputEvent) =>\n this.optionSelect(e, id)}\n .checked=${item.selected}\n />\n ${item.label}\n </label>\n </div>\n </ix-menu-item>`\n : nothing}`\n )\n : html`<ix-menu-item>${this.noFilteredOptions}</ix-menu-item>`}\n </ix-menu>\n </div>\n </div>\n `;\n }\n}\n"]}
@@ -5,7 +5,8 @@ export const IxMultiSelectStyles = css `
5
5
  }
6
6
  ix-field {
7
7
  display: block;
8
- --md-outlined-field-label-text-color: var(--md-sys-text-color-secondary);
8
+ --md-outlined-field-label-text-color: var(--md-sys-text-color-primary);
9
+ --md-outlined-field-outline-color: var(--md-outlined-field-outline-color);
9
10
  }
10
11
  ix-field label {
11
12
  display: none;
@@ -1 +1 @@
1
- {"version":3,"file":"ix-multi-select-styles.js","sourceRoot":"","sources":["../src/ix-multi-select-styles.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,KAAK,CAAC;AAE1B,MAAM,CAAC,MAAM,mBAAmB,GAAG,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAqErC,CAAC","sourcesContent":["import { css } from 'lit';\n\nexport const IxMultiSelectStyles = css`\n :host {\n display: block;\n }\n ix-field {\n display: block;\n --md-outlined-field-label-text-color: var(--md-sys-text-color-secondary);\n }\n ix-field label {\n display: none;\n }\n .flex-fill {\n flex: 1;\n }\n .menu {\n position: relative;\n }\n .menu label,\n .menu input {\n cursor: pointer;\n }\n input {\n border: none;\n background: transparent;\n outline: none;\n min-width: 3rem;\n }\n ix-chip-set {\n min-height: var(--_content-line-height);\n }\n ix-menu {\n --md-menu-container-color: #fff;\n max-height: 500px;\n }\n ix-menu-item {\n position: relative;\n }\n ix-menu-item label {\n display: flex;\n align-items: center;\n position: absolute;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n }\n ix-menu-item label input[type='checkbox'] {\n margin: 0 1rem 2px;\n }\n ix-menu-item.selected {\n background: var(--md-sys-color-tertiary-container);\n }\n ix-icon-button {\n --md-icon-button-icon-color: var(--md-sys-text-color-secondary);\n --md-icon-button-hover-icon-color: var(--md-sys-text-color-secondary);\n --md-icon-button-hover-state-layer-color: var(\n --md-sys-text-color-secondary\n );\n --md-icon-button-pressed-icon-color: var(--md-sys-text-color-secondary);\n --md-icon-button-pressed-state-layer-color: var(\n --md-sys-text-color-secondary\n );\n }\n .open-icon {\n margin-right: 0.5rem;\n }\n .multi-select {\n position: relative;\n }\n`;\n"]}
1
+ {"version":3,"file":"ix-multi-select-styles.js","sourceRoot":"","sources":["../src/ix-multi-select-styles.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,KAAK,CAAC;AAE1B,MAAM,CAAC,MAAM,mBAAmB,GAAG,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAsErC,CAAC","sourcesContent":["import { css } from 'lit';\n\nexport const IxMultiSelectStyles = css`\n :host {\n display: block;\n }\n ix-field {\n display: block;\n --md-outlined-field-label-text-color: var(--md-sys-text-color-primary);\n --md-outlined-field-outline-color: var(--md-outlined-field-outline-color);\n }\n ix-field label {\n display: none;\n }\n .flex-fill {\n flex: 1;\n }\n .menu {\n position: relative;\n }\n .menu label,\n .menu input {\n cursor: pointer;\n }\n input {\n border: none;\n background: transparent;\n outline: none;\n min-width: 3rem;\n }\n ix-chip-set {\n min-height: var(--_content-line-height);\n }\n ix-menu {\n --md-menu-container-color: #fff;\n max-height: 500px;\n }\n ix-menu-item {\n position: relative;\n }\n ix-menu-item label {\n display: flex;\n align-items: center;\n position: absolute;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n }\n ix-menu-item label input[type='checkbox'] {\n margin: 0 1rem 2px;\n }\n ix-menu-item.selected {\n background: var(--md-sys-color-tertiary-container);\n }\n ix-icon-button {\n --md-icon-button-icon-color: var(--md-sys-text-color-secondary);\n --md-icon-button-hover-icon-color: var(--md-sys-text-color-secondary);\n --md-icon-button-hover-state-layer-color: var(\n --md-sys-text-color-secondary\n );\n --md-icon-button-pressed-icon-color: var(--md-sys-text-color-secondary);\n --md-icon-button-pressed-state-layer-color: var(\n --md-sys-text-color-secondary\n );\n }\n .open-icon {\n margin-right: 0.5rem;\n }\n .multi-select {\n position: relative;\n }\n`;\n"]}
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "description": "Webcomponent ix-multi-select following open-wc recommendations",
4
4
  "license": "MIT",
5
5
  "author": "Digital Realty",
6
- "version": "0.0.5",
6
+ "version": "0.0.6",
7
7
  "type": "module",
8
8
  "main": "dist/index.js",
9
9
  "module": "dist/index.js",
@@ -97,5 +97,5 @@
97
97
  "README.md",
98
98
  "LICENSE"
99
99
  ],
100
- "gitHead": "4c0b776d7e028829eb231dc34af90f9f31a790b0"
100
+ "gitHead": "1b89f4799af29a2ed1c0946843cb4b694a5d8cae"
101
101
  }