@digital-realty/ix-email-list 1.1.1 → 1.1.2

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.
@@ -23,7 +23,6 @@ export declare class IxEmailList extends LitElement {
23
23
  static readonly formAssociated = true;
24
24
  private readonly internals;
25
25
  emailInput: HTMLInputElement;
26
- items: string[];
27
26
  lookup: (address?: string) => string | undefined;
28
27
  label: string;
29
28
  value: string;
@@ -37,7 +36,6 @@ export declare class IxEmailList extends LitElement {
37
36
  */
38
37
  error: boolean;
39
38
  required: boolean;
40
- addresses: EmailListItem[];
41
39
  onChanged: any;
42
40
  checkDuplicates: boolean;
43
41
  maximumEmailCount: number;
@@ -57,6 +55,7 @@ export declare class IxEmailList extends LitElement {
57
55
  set name(name: string);
58
56
  private focused;
59
57
  private inputValue;
58
+ addresses: EmailListItem[];
60
59
  /**
61
60
  * Returns the text field's validation error message.
62
61
  *
@@ -79,7 +78,6 @@ export declare class IxEmailList extends LitElement {
79
78
  get willValidate(): boolean;
80
79
  checkValidity(): boolean;
81
80
  reportValidity(): boolean;
82
- firstUpdated(): void;
83
81
  disconnectedCallback(): void;
84
82
  private chipRemove;
85
83
  handleFocusin: () => void;
@@ -14,12 +14,11 @@ export class IxEmailList extends LitElement {
14
14
  super(...arguments);
15
15
  this.internals = this /* needed for closure */
16
16
  .attachInternals();
17
- this.items = [];
18
17
  // eslint-disable-next-line class-methods-use-this
19
18
  this.lookup = () => undefined;
20
19
  this.label = '';
21
20
  this.value = '';
22
- this.errorText = 'Invalid email in list. ';
21
+ this.errorText = 'Invalid email in list.';
23
22
  this.disabled = false;
24
23
  /**
25
24
  * Gets or sets whether or not the text field is in a visually invalid state.
@@ -29,7 +28,6 @@ export class IxEmailList extends LitElement {
29
28
  */
30
29
  this.error = false;
31
30
  this.required = false;
32
- this.addresses = [];
33
31
  // eslint-disable-next-line class-methods-use-this
34
32
  this.onChanged = () => { };
35
33
  this.checkDuplicates = false;
@@ -37,12 +35,14 @@ export class IxEmailList extends LitElement {
37
35
  this.errorMessage = '';
38
36
  this.focused = false;
39
37
  this.inputValue = '';
38
+ this.addresses = [];
40
39
  this.chipRemove = async (id) => {
41
40
  const addresses = this.addresses.filter((_item, i) => i !== id);
42
41
  this.addresses = [];
43
42
  await 0;
44
43
  this.addresses = addresses;
45
44
  this.isValidList();
45
+ this.value = this.addresses.map(item => item.address).join(',');
46
46
  this.onChanged(this.addresses);
47
47
  if (!this.addresses.length) {
48
48
  this.handleFocusout();
@@ -55,7 +55,7 @@ export class IxEmailList extends LitElement {
55
55
  if (this.inputValue) {
56
56
  this.resolveInput();
57
57
  }
58
- else if (this.value !== '') {
58
+ if (this.value !== '') {
59
59
  this.focused = true;
60
60
  }
61
61
  else {
@@ -76,6 +76,7 @@ export class IxEmailList extends LitElement {
76
76
  const name = this.lookup(address);
77
77
  this.addresses = [...this.addresses, { address, isValid, name }];
78
78
  this.inputValue = '';
79
+ this.value = this.addresses.map(item => item.address).join(',');
79
80
  this.isValidList();
80
81
  this.onChanged(this.addresses);
81
82
  };
@@ -162,20 +163,6 @@ export class IxEmailList extends LitElement {
162
163
  reportValidity() {
163
164
  return this.internals.reportValidity();
164
165
  }
165
- firstUpdated() {
166
- this.internals.setFormValue(this.value);
167
- if (this.value !== '') {
168
- this.addresses = this.value.split(',').map((item) => {
169
- const address = item.toLowerCase().trim();
170
- return {
171
- address,
172
- isValid: isValidEmail(address),
173
- };
174
- });
175
- }
176
- this.focused = this.addresses.length > 0;
177
- this.isValidList();
178
- }
179
166
  disconnectedCallback() {
180
167
  super.disconnectedCallback();
181
168
  this.reset();
@@ -222,10 +209,20 @@ export class IxEmailList extends LitElement {
222
209
  }
223
210
  }
224
211
  updated(changedProperties) {
225
- if (changedProperties.has('addresses')) {
226
- this.value = this.addresses.map(item => item.address).join(', ');
212
+ if (changedProperties.has('value')) {
213
+ this.internals.setFormValue(this.value);
214
+ if (this.value.trim() !== '') {
215
+ this.addresses = this.value.split(',').map((item) => {
216
+ const address = item.toLowerCase().trim();
217
+ return {
218
+ address,
219
+ isValid: isValidEmail(address),
220
+ };
221
+ });
222
+ }
223
+ this.focused = this.addresses.length > 0;
224
+ this.isValidList();
227
225
  }
228
- this.internals.setFormValue(this.value);
229
226
  }
230
227
  focus() {
231
228
  this.emailInput.focus();
@@ -252,6 +249,7 @@ export class IxEmailList extends LitElement {
252
249
  error-text=${this.errorMessage}
253
250
  @focusin=${this.handleFocusin}
254
251
  @focusout=${this.handleFocusout}
252
+ ?populated=${this.value.length}
255
253
  >
256
254
  <ix-chip-set>
257
255
  ${this.addresses.map((item, id) => html `<span
@@ -304,9 +302,6 @@ IxEmailList.labelText = (item) => {
304
302
  __decorate([
305
303
  query('#email-input')
306
304
  ], IxEmailList.prototype, "emailInput", void 0);
307
- __decorate([
308
- property({ type: Array })
309
- ], IxEmailList.prototype, "items", void 0);
310
305
  __decorate([
311
306
  property()
312
307
  ], IxEmailList.prototype, "lookup", void 0);
@@ -328,9 +323,6 @@ __decorate([
328
323
  __decorate([
329
324
  property({ type: Boolean, reflect: true })
330
325
  ], IxEmailList.prototype, "required", void 0);
331
- __decorate([
332
- property({ type: Array })
333
- ], IxEmailList.prototype, "addresses", void 0);
334
326
  __decorate([
335
327
  property({ type: Function })
336
328
  ], IxEmailList.prototype, "onChanged", void 0);
@@ -346,4 +338,7 @@ __decorate([
346
338
  __decorate([
347
339
  state()
348
340
  ], IxEmailList.prototype, "inputValue", void 0);
341
+ __decorate([
342
+ state()
343
+ ], IxEmailList.prototype, "addresses", void 0);
349
344
  //# sourceMappingURL=IxEmailList.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"IxEmailList.js","sourceRoot":"","sources":["../src/IxEmailList.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-icon-button/ix-icon-button.js';\nimport { IxEmailListStyles } from './ix-email-list-styles.js';\nimport { isValidEmail } from './utils/email-validation.js';\n\nexport interface EmailListItem {\n address: string;\n isValid: boolean;\n name?: string;\n isDuplicate?: boolean;\n}\n\nexport class IxEmailList extends LitElement {\n static {\n requestUpdateOnAriaChange(IxEmailList);\n }\n\n static get styles() {\n return [IxEmailListStyles];\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 @query('#email-input') emailInput!: HTMLInputElement;\n\n @property({ type: Array }) items: string[] = [];\n\n // eslint-disable-next-line class-methods-use-this\n @property() lookup: (address?: string) => string | undefined = () =>\n undefined;\n\n @property({ type: String }) label = '';\n\n @property({ type: String }) value = '';\n\n @property({ type: String, attribute: 'error-text' }) errorText =\n 'Invalid email in list. ';\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 @property({ type: Array }) addresses: EmailListItem[] = [];\n\n // eslint-disable-next-line class-methods-use-this\n @property({ type: Function }) onChanged: any = () => {};\n\n @property({ type: Boolean, reflect: true }) checkDuplicates = false;\n\n @property({ type: Number, reflect: true }) maximumEmailCount = -1;\n\n private errorMessage: string = '';\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 set name(name: string) {\n this.setAttribute('name', name);\n }\n\n @state() private focused = false;\n\n @state() private inputValue = '';\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 firstUpdated() {\n this.internals.setFormValue(this.value);\n if (this.value !== '') {\n this.addresses = this.value.split(',').map((item: string) => {\n const address = item.toLowerCase().trim();\n return {\n address,\n isValid: isValidEmail(address),\n };\n });\n }\n this.focused = this.addresses.length > 0;\n this.isValidList();\n }\n\n disconnectedCallback() {\n super.disconnectedCallback();\n this.reset();\n }\n\n private chipRemove = async (id: number) => {\n const addresses = this.addresses.filter((_item, i: number) => i !== id);\n this.addresses = [];\n await 0;\n this.addresses = addresses;\n this.isValidList();\n this.onChanged(this.addresses);\n if (!this.addresses.length) {\n this.handleFocusout();\n }\n };\n\n handleFocusin = () => {\n this.focused = true;\n };\n\n handleFocusout = () => {\n if (this.inputValue) {\n this.resolveInput();\n } else if (this.value !== '') {\n this.focused = true;\n } else {\n this.focused = false;\n }\n };\n\n keydown = (e: KeyboardEvent) => {\n // input completion keys\n const completionKeys = [' ', ',', 'Tab', 'Enter'];\n if (completionKeys.includes(e.key) && this.inputValue.length) {\n e.preventDefault();\n this.resolveInput();\n }\n };\n\n resolveInput = () => {\n const address = this.inputValue.toLowerCase();\n const isValid = isValidEmail(address);\n\n const name = this.lookup(address);\n this.addresses = [...this.addresses, { address, isValid, name }];\n this.inputValue = '';\n this.isValidList();\n this.onChanged(this.addresses);\n };\n\n input = (e: InputEvent) => {\n const { value } = e.target as HTMLInputElement;\n this.inputValue = value;\n };\n\n clear = () => {\n this.addresses = [];\n this.inputValue = '';\n this.value = '';\n this.error = false;\n this.onChanged(this.addresses);\n this.handleFocusout();\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.clear();\n this.value = this.getAttribute('value') ?? '';\n }\n\n isValidList = () => {\n this.errorMessage = '';\n this.error = false;\n\n if (this.addresses.some((item: EmailListItem) => !item.isValid))\n this.addError(this.errorText);\n\n if (this.checkDuplicates) this.checkForDuplicates();\n\n if (this.maximumEmailCount > 0) this.validateEmailCount();\n\n this.internals.setValidity(\n {\n badInput: this.error,\n },\n this.error ? this.errorMessage : '',\n this.emailInput\n );\n };\n\n validateEmailCount() {\n if (this.addresses.length > this.maximumEmailCount)\n this.addError(\n `Maximum of ${this.maximumEmailCount} emails are allowed. `\n );\n }\n\n checkForDuplicates() {\n let hasDuplicates = false;\n\n const groupByAddress = this.addresses.reduce((addressMap, email, index) => {\n const { address } = email;\n\n if (!addressMap[address]) {\n addressMap[address] = [];\n }\n addressMap[address].push(index);\n return addressMap;\n }, {} as Record<string, number[]>);\n\n Object.values(groupByAddress).forEach((addressIds: number[]) => {\n if (addressIds.length > 1) {\n hasDuplicates = true;\n addressIds.forEach(index => {\n this.addresses[index].isDuplicate = true;\n });\n } else {\n this.addresses[addressIds[0]].isDuplicate = false;\n }\n });\n\n if (hasDuplicates) {\n this.addError('Duplicate emails detected.');\n }\n }\n\n static labelText = (item: EmailListItem) => {\n const address = item.isValid ? item.address : `${item.address}!`;\n return item.name ? item.name : address;\n };\n\n protected override updated(changedProperties: PropertyValues) {\n if (changedProperties.has('addresses')) {\n this.value = this.addresses.map(item => item.address).join(', ');\n }\n this.internals.setFormValue(this.value);\n }\n\n override focus() {\n this.emailInput.focus();\n }\n\n private addError(errorText: string) {\n this.error = true;\n this.errorMessage += errorText;\n }\n\n render() {\n const classes = {\n disabled: this.disabled,\n error: !this.disabled && this.error,\n };\n\n return html`\n <ix-field\n class=\"${classMap(classes)}\"\n ?focused=${this.focused}\n ?disabled=${this.disabled}\n ?required=${this.required}\n ?checkDuplicates=${this.checkDuplicates}\n ?maximumEmailCount=${this.maximumEmailCount}\n label=${this.label}\n ?error=${this.error}\n error-text=${this.errorMessage}\n @focusin=${this.handleFocusin}\n @focusout=${this.handleFocusout}\n >\n <ix-chip-set>\n ${this.addresses.map(\n (item, id: number) => html`<span\n ><ix-chip\n @remove=${() => this.chipRemove(id)}\n label=${IxEmailList.labelText(item)}\n class=${!item.isValid || item.isDuplicate ? 'error' : ''}\n appearance=\"input\"\n removable\n remove-only\n ></ix-chip\n ></span>`\n )}\n <input\n id=\"email-input\"\n @keydown=${this.keydown}\n @input=${this.input}\n .value=${this.inputValue}\n class=\"flex-fill\"\n type=\"text\"\n />\n </ix-chip-set>\n <slot name=\"end\" slot=\"end\">\n ${this.addresses.length\n ? html`<ix-icon-button\n class=\"clear-icon\"\n @click=${this.clear}\n icon=\"close\"\n aria-label=\"clear\"\n ></ix-icon-button>`\n : nothing}\n </slot>\n </ix-field>\n `;\n }\n}\n"]}
1
+ {"version":3,"file":"IxEmailList.js","sourceRoot":"","sources":["../src/IxEmailList.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-icon-button/ix-icon-button.js';\nimport { IxEmailListStyles } from './ix-email-list-styles.js';\nimport { isValidEmail } from './utils/email-validation.js';\n\nexport interface EmailListItem {\n address: string;\n isValid: boolean;\n name?: string;\n isDuplicate?: boolean;\n}\n\nexport class IxEmailList extends LitElement {\n static {\n requestUpdateOnAriaChange(IxEmailList);\n }\n\n static get styles() {\n return [IxEmailListStyles];\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 @query('#email-input') emailInput!: HTMLInputElement;\n\n // eslint-disable-next-line class-methods-use-this\n @property() lookup: (address?: string) => string | undefined = () =>\n undefined;\n\n @property({ type: String }) label = '';\n\n @property({ type: String }) value = '';\n\n @property({ type: String, attribute: 'error-text' }) errorText =\n 'Invalid email in list.';\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 // eslint-disable-next-line class-methods-use-this\n @property({ type: Function }) onChanged: any = () => {};\n\n @property({ type: Boolean, reflect: true }) checkDuplicates = false;\n\n @property({ type: Number, reflect: true }) maximumEmailCount = -1;\n\n private errorMessage: string = '';\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 set name(name: string) {\n this.setAttribute('name', name);\n }\n\n @state() private focused = false;\n\n @state() private inputValue = '';\n\n @state() addresses: EmailListItem[] = [];\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 disconnectedCallback() {\n super.disconnectedCallback();\n this.reset();\n }\n\n private chipRemove = async (id: number) => {\n const addresses = this.addresses.filter((_item, i: number) => i !== id);\n this.addresses = [];\n await 0;\n this.addresses = addresses;\n this.isValidList();\n this.value = this.addresses.map(item => item.address).join(',');\n this.onChanged(this.addresses);\n if (!this.addresses.length) {\n this.handleFocusout();\n }\n };\n\n handleFocusin = () => {\n this.focused = true;\n };\n\n handleFocusout = () => {\n if (this.inputValue) {\n this.resolveInput();\n }\n if (this.value !== '') {\n this.focused = true;\n } else {\n this.focused = false;\n }\n };\n\n keydown = (e: KeyboardEvent) => {\n // input completion keys\n const completionKeys = [' ', ',', 'Tab', 'Enter'];\n if (completionKeys.includes(e.key) && this.inputValue.length) {\n e.preventDefault();\n this.resolveInput();\n }\n };\n\n resolveInput = () => {\n const address = this.inputValue.toLowerCase();\n const isValid = isValidEmail(address);\n\n const name = this.lookup(address);\n this.addresses = [...this.addresses, { address, isValid, name }];\n this.inputValue = '';\n this.value = this.addresses.map(item => item.address).join(',');\n this.isValidList();\n this.onChanged(this.addresses);\n };\n\n input = (e: InputEvent) => {\n const { value } = e.target as HTMLInputElement;\n this.inputValue = value;\n };\n\n clear = () => {\n this.addresses = [];\n this.inputValue = '';\n this.value = '';\n this.error = false;\n this.onChanged(this.addresses);\n this.handleFocusout();\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.clear();\n this.value = this.getAttribute('value') ?? '';\n }\n\n isValidList = () => {\n this.errorMessage = '';\n this.error = false;\n\n if (this.addresses.some((item: EmailListItem) => !item.isValid))\n this.addError(this.errorText);\n\n if (this.checkDuplicates) this.checkForDuplicates();\n\n if (this.maximumEmailCount > 0) this.validateEmailCount();\n\n this.internals.setValidity(\n {\n badInput: this.error,\n },\n this.error ? this.errorMessage : '',\n this.emailInput\n );\n };\n\n validateEmailCount() {\n if (this.addresses.length > this.maximumEmailCount)\n this.addError(\n `Maximum of ${this.maximumEmailCount} emails are allowed. `\n );\n }\n\n checkForDuplicates() {\n let hasDuplicates = false;\n\n const groupByAddress = this.addresses.reduce((addressMap, email, index) => {\n const { address } = email;\n\n if (!addressMap[address]) {\n addressMap[address] = [];\n }\n addressMap[address].push(index);\n return addressMap;\n }, {} as Record<string, number[]>);\n\n Object.values(groupByAddress).forEach((addressIds: number[]) => {\n if (addressIds.length > 1) {\n hasDuplicates = true;\n addressIds.forEach(index => {\n this.addresses[index].isDuplicate = true;\n });\n } else {\n this.addresses[addressIds[0]].isDuplicate = false;\n }\n });\n\n if (hasDuplicates) {\n this.addError('Duplicate emails detected.');\n }\n }\n\n static labelText = (item: EmailListItem) => {\n const address = item.isValid ? item.address : `${item.address}!`;\n return item.name ? item.name : address;\n };\n\n protected override updated(changedProperties: PropertyValues) {\n if (changedProperties.has('value')) {\n this.internals.setFormValue(this.value);\n if (this.value.trim() !== '') {\n this.addresses = this.value.split(',').map((item: string) => {\n const address = item.toLowerCase().trim();\n return {\n address,\n isValid: isValidEmail(address),\n };\n });\n }\n this.focused = this.addresses.length > 0;\n this.isValidList();\n }\n }\n\n override focus() {\n this.emailInput.focus();\n }\n\n private addError(errorText: string) {\n this.error = true;\n this.errorMessage += errorText;\n }\n\n render() {\n const classes = {\n disabled: this.disabled,\n error: !this.disabled && this.error,\n };\n\n return html`\n <ix-field\n class=\"${classMap(classes)}\"\n ?focused=${this.focused}\n ?disabled=${this.disabled}\n ?required=${this.required}\n ?checkDuplicates=${this.checkDuplicates}\n ?maximumEmailCount=${this.maximumEmailCount}\n label=${this.label}\n ?error=${this.error}\n error-text=${this.errorMessage}\n @focusin=${this.handleFocusin}\n @focusout=${this.handleFocusout}\n ?populated=${this.value.length}\n >\n <ix-chip-set>\n ${this.addresses.map(\n (item, id: number) => html`<span\n ><ix-chip\n @remove=${() => this.chipRemove(id)}\n label=${IxEmailList.labelText(item)}\n class=${!item.isValid || item.isDuplicate ? 'error' : ''}\n appearance=\"input\"\n removable\n remove-only\n ></ix-chip\n ></span>`\n )}\n <input\n id=\"email-input\"\n @keydown=${this.keydown}\n @input=${this.input}\n .value=${this.inputValue}\n class=\"flex-fill\"\n type=\"text\"\n />\n </ix-chip-set>\n <slot name=\"end\" slot=\"end\">\n ${this.addresses.length\n ? html`<ix-icon-button\n class=\"clear-icon\"\n @click=${this.clear}\n icon=\"close\"\n aria-label=\"clear\"\n ></ix-icon-button>`\n : nothing}\n </slot>\n </ix-field>\n `;\n }\n}\n"]}
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "description": "Webcomponent ix-email-list following open-wc recommendations",
4
4
  "license": "MIT",
5
5
  "author": "Digital Realty",
6
- "version": "1.1.1",
6
+ "version": "1.1.2",
7
7
  "type": "module",
8
8
  "main": "dist/index.js",
9
9
  "module": "dist/index.js",
@@ -25,10 +25,10 @@
25
25
  "test:watch": "tsc && concurrently -k -r \"tsc --watch --preserveWatchOutput\" \"wtr --watch\""
26
26
  },
27
27
  "dependencies": {
28
- "@digital-realty/ix-chip": "^1.0.8",
28
+ "@digital-realty/ix-chip": "^1.0.10",
29
29
  "@digital-realty/ix-field": "^1.0.4",
30
- "@digital-realty/ix-icon-button": "^1.0.23",
31
- "@digital-realty/theme": "^1.0.12",
30
+ "@digital-realty/ix-icon-button": "^1.0.24",
31
+ "@digital-realty/theme": "^1.0.13",
32
32
  "@material/web": "1.2.0",
33
33
  "@web/test-runner-commands": "^0.9.0",
34
34
  "lit": "^2.0.2"
@@ -98,5 +98,5 @@
98
98
  "README.md",
99
99
  "LICENSE"
100
100
  ],
101
- "gitHead": "a4bf5d96056159d64023dbe8304736582373a98f"
101
+ "gitHead": "43b0e609ef85f29e50a1872181cb8e685bcc13ec"
102
102
  }