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

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.
@@ -39,6 +39,7 @@ export declare class IxEmailList extends LitElement {
39
39
  onChanged: any;
40
40
  checkDuplicates: boolean;
41
41
  maximumEmailCount: number;
42
+ tabIndex: number;
42
43
  private errorMessage;
43
44
  /**
44
45
  * The associated form element with which this element's value will submit.
@@ -32,6 +32,7 @@ export class IxEmailList extends LitElement {
32
32
  this.onChanged = () => { };
33
33
  this.checkDuplicates = false;
34
34
  this.maximumEmailCount = -1;
35
+ this.tabIndex = 0;
35
36
  this.errorMessage = '';
36
37
  this.focused = false;
37
38
  this.inputValue = '';
@@ -55,12 +56,7 @@ export class IxEmailList extends LitElement {
55
56
  if (this.inputValue) {
56
57
  this.resolveInput();
57
58
  }
58
- if (this.value !== '') {
59
- this.focused = true;
60
- }
61
- else {
62
- this.focused = false;
63
- }
59
+ this.focused = false;
64
60
  };
65
61
  this.keydown = (e) => {
66
62
  // input completion keys
@@ -209,6 +205,9 @@ export class IxEmailList extends LitElement {
209
205
  }
210
206
  }
211
207
  updated(changedProperties) {
208
+ if (changedProperties.has('disabled')) {
209
+ this.tabIndex = this.disabled ? -1 : 0;
210
+ }
212
211
  if (changedProperties.has('value')) {
213
212
  this.internals.setFormValue(this.value);
214
213
  if (this.value.trim() !== '') {
@@ -220,7 +219,6 @@ export class IxEmailList extends LitElement {
220
219
  };
221
220
  });
222
221
  }
223
- this.focused = this.addresses.length > 0;
224
222
  this.isValidList();
225
223
  }
226
224
  }
@@ -249,28 +247,31 @@ export class IxEmailList extends LitElement {
249
247
  error-text=${this.errorMessage}
250
248
  @focusin=${this.handleFocusin}
251
249
  @focusout=${this.handleFocusout}
252
- ?populated=${this.value.length}
250
+ ?populated=${this.addresses.length || this.inputValue.length}
253
251
  >
254
- <ix-chip-set>
255
- ${this.addresses.map((item, id) => html `<span
256
- ><ix-chip
257
- @remove=${() => this.chipRemove(id)}
258
- label=${IxEmailList.labelText(item)}
259
- class=${!item.isValid || item.isDuplicate ? 'error' : ''}
260
- appearance="input"
261
- removable
262
- remove-only
263
- ></ix-chip
264
- ></span>`)}
252
+ <div class="field-content">
253
+ ${this.addresses.length
254
+ ? html `<ix-chip-set>
255
+ ${this.addresses.map((item, id) => html `<span
256
+ ><ix-chip
257
+ @remove=${() => this.chipRemove(id)}
258
+ label=${IxEmailList.labelText(item)}
259
+ class=${!item.isValid || item.isDuplicate ? 'error' : ''}
260
+ appearance="input"
261
+ removable
262
+ remove-only
263
+ ></ix-chip
264
+ ></span>`)}
265
+ </ix-chip-set>`
266
+ : nothing}
265
267
  <input
266
268
  id="email-input"
267
269
  @keydown=${this.keydown}
268
270
  @input=${this.input}
269
271
  .value=${this.inputValue}
270
- class="flex-fill"
271
272
  type="text"
272
273
  />
273
- </ix-chip-set>
274
+ </div>
274
275
  <slot name="end" slot="end">
275
276
  ${this.addresses.length
276
277
  ? html `<ix-icon-button
@@ -332,6 +333,9 @@ __decorate([
332
333
  __decorate([
333
334
  property({ type: Number, reflect: true })
334
335
  ], IxEmailList.prototype, "maximumEmailCount", void 0);
336
+ __decorate([
337
+ property({ type: Number, reflect: true })
338
+ ], IxEmailList.prototype, "tabIndex", void 0);
335
339
  __decorate([
336
340
  state()
337
341
  ], IxEmailList.prototype, "focused", void 0);
@@ -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 // 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"]}
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 @property({ type: Number, reflect: true }) tabIndex = 0;\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 this.focused = false;\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('disabled')) {\n this.tabIndex = this.disabled ? -1 : 0;\n }\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.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.addresses.length || this.inputValue.length}\n >\n <div class=\"field-content\">\n ${this.addresses.length\n ? html`<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 </ix-chip-set>`\n : nothing}\n <input\n id=\"email-input\"\n @keydown=${this.keydown}\n @input=${this.input}\n .value=${this.inputValue}\n type=\"text\"\n />\n </div>\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"]}
@@ -3,31 +3,36 @@ export const IxEmailListStyles = css `
3
3
  :host {
4
4
  display: block;
5
5
  }
6
+ :host([disabled]) {
7
+ pointer-events: none;
8
+ }
6
9
  ix-field {
7
10
  display: block;
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);
10
11
  }
11
12
  ix-field label {
12
13
  display: none;
13
14
  }
14
15
  ix-chip.error {
15
- --md-input-chip-label-text-color: red;
16
- --md-input-chip-hover-label-text-color: red;
16
+ --ix-chip-container-color: var(--md-sys-color-error);
17
+ --md-input-chip-outline-color: var(--md-sys-color-error);
17
18
  }
18
- .flex-fill {
19
- flex: 1;
19
+ .field-content {
20
+ display: flex;
21
+ flex-wrap: wrap;
22
+ min-height: var(--ix-custom-field-min-height, 24px);
20
23
  }
21
24
  input {
22
25
  border: none;
23
26
  background: transparent;
24
27
  outline: none;
25
- min-width: 3rem;
26
- font-size: var(--md-outlined-text-field-input-text-font, 16px);
27
- line-height: var(--md-outlined-text-field-input-text-font, 24px);
28
+ min-width: 30%;
29
+ line-height: var(--_content-line-height);
30
+ flex-grow: 1;
28
31
  }
29
32
  ix-chip-set {
30
33
  min-height: var(--_content-line-height);
34
+ display: flex;
35
+ padding-right: 0.5rem;
31
36
  }
32
37
  ix-icon-button {
33
38
  --md-icon-button-icon-color: var(--md-sys-text-color-secondary);
@@ -1 +1 @@
1
- {"version":3,"file":"ix-email-list-styles.js","sourceRoot":"","sources":["../src/ix-email-list-styles.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,KAAK,CAAC;AAE1B,MAAM,CAAC,MAAM,iBAAiB,GAAG,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA4CnC,CAAC","sourcesContent":["import { css } from 'lit';\n\nexport const IxEmailListStyles = 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 ix-chip.error {\n --md-input-chip-label-text-color: red;\n --md-input-chip-hover-label-text-color: red;\n }\n .flex-fill {\n flex: 1;\n }\n input {\n border: none;\n background: transparent;\n outline: none;\n min-width: 3rem;\n font-size: var(--md-outlined-text-field-input-text-font, 16px);\n line-height: var(--md-outlined-text-field-input-text-font, 24px);\n }\n ix-chip-set {\n min-height: var(--_content-line-height);\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 .clear-icon {\n margin-right: 0.5rem;\n }\n`;\n"]}
1
+ {"version":3,"file":"ix-email-list-styles.js","sourceRoot":"","sources":["../src/ix-email-list-styles.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,KAAK,CAAC;AAE1B,MAAM,CAAC,MAAM,iBAAiB,GAAG,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAiDnC,CAAC","sourcesContent":["import { css } from 'lit';\n\nexport const IxEmailListStyles = css`\n :host {\n display: block;\n }\n :host([disabled]) {\n pointer-events: none;\n }\n ix-field {\n display: block;\n }\n ix-field label {\n display: none;\n }\n ix-chip.error {\n --ix-chip-container-color: var(--md-sys-color-error);\n --md-input-chip-outline-color: var(--md-sys-color-error);\n }\n .field-content {\n display: flex;\n flex-wrap: wrap;\n min-height: var(--ix-custom-field-min-height, 24px);\n }\n input {\n border: none;\n background: transparent;\n outline: none;\n min-width: 30%;\n line-height: var(--_content-line-height);\n flex-grow: 1;\n }\n ix-chip-set {\n min-height: var(--_content-line-height);\n display: flex;\n padding-right: 0.5rem;\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 .clear-icon {\n margin-right: 0.5rem;\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.2",
6
+ "version": "1.1.3",
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.10",
28
+ "@digital-realty/ix-chip": "^1.0.22",
29
29
  "@digital-realty/ix-field": "^1.0.4",
30
- "@digital-realty/ix-icon-button": "^1.0.24",
31
- "@digital-realty/theme": "^1.0.13",
30
+ "@digital-realty/ix-icon-button": "^1.0.35",
31
+ "@digital-realty/theme": "^1.0.26",
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": "43b0e609ef85f29e50a1872181cb8e685bcc13ec"
101
+ "gitHead": "dced04ebef5c8342344b1fd3df33b5e22a78725f"
102
102
  }