fix: removed FieldCustomMixin
This commit is contained in:
parent
d81764e9fd
commit
f44d8aa26a
8 changed files with 59 additions and 127 deletions
|
|
@ -101,12 +101,6 @@ function deserializeDate(serializeValue, options) {
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
### FieldCustomMixin
|
|
||||||
|
|
||||||
When creating your own custom input, please use `FieldCustomMixin` as a basis for this.
|
|
||||||
Concrete examples can be found at [`<lion-input-date>`](../../input-date/) and
|
|
||||||
[`<lion-input-amount>`](../../input-amount/).
|
|
||||||
|
|
||||||
## Flow diagram
|
## Flow diagram
|
||||||
|
|
||||||
The following flow diagram is based on both end user input and interaction programmed by the
|
The following flow diagram is based on both end user input and interaction programmed by the
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,5 @@
|
||||||
export { FocusMixin } from './src/FocusMixin.js';
|
export { FocusMixin } from './src/FocusMixin.js';
|
||||||
export { FormatMixin } from './src/FormatMixin.js';
|
export { FormatMixin } from './src/FormatMixin.js';
|
||||||
export { FieldCustomMixin } from './src/FieldCustomMixin.js';
|
|
||||||
export { FormControlMixin } from './src/FormControlMixin.js';
|
export { FormControlMixin } from './src/FormControlMixin.js';
|
||||||
export { InteractionStateMixin } from './src/InteractionStateMixin.js'; // applies FocusMixin
|
export { InteractionStateMixin } from './src/InteractionStateMixin.js'; // applies FocusMixin
|
||||||
export { LionField } from './src/LionField.js';
|
export { LionField } from './src/LionField.js';
|
||||||
|
|
|
||||||
|
|
@ -1,46 +0,0 @@
|
||||||
import { dedupeMixin, nothing } from '@lion/core';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* #FieldCustomMixin
|
|
||||||
*
|
|
||||||
* @polymerMixin
|
|
||||||
* @mixinFunction
|
|
||||||
*/
|
|
||||||
|
|
||||||
export const FieldCustomMixin = dedupeMixin(
|
|
||||||
superclass =>
|
|
||||||
// eslint-disable-next-line no-shadow, max-len
|
|
||||||
class FieldCustomMixin extends superclass {
|
|
||||||
static get properties() {
|
|
||||||
return {
|
|
||||||
/**
|
|
||||||
* When no light dom defined and prop set
|
|
||||||
*/
|
|
||||||
disableHelpText: {
|
|
||||||
type: Boolean,
|
|
||||||
attribute: 'disable-help-text',
|
|
||||||
},
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
get slots() {
|
|
||||||
return {
|
|
||||||
...super.slots,
|
|
||||||
'help-text': () => {
|
|
||||||
if (!this.disableHelpText) {
|
|
||||||
return super.slots['help-text']();
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
},
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
helpTextTemplate(...args) {
|
|
||||||
if (this.disableHelpText || !super.helpTextTemplate) {
|
|
||||||
return nothing;
|
|
||||||
}
|
|
||||||
|
|
||||||
return super.helpTextTemplate.apply(this, args);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
);
|
|
||||||
|
|
@ -1,31 +0,0 @@
|
||||||
import { expect, fixture, defineCE } from '@open-wc/testing';
|
|
||||||
import { LionField } from '../src/LionField.js';
|
|
||||||
|
|
||||||
import { FieldCustomMixin } from '../src/FieldCustomMixin.js';
|
|
||||||
|
|
||||||
describe('FieldCustomMixin', () => {
|
|
||||||
const inputSlot = '<input slot="input" />';
|
|
||||||
let elem;
|
|
||||||
|
|
||||||
before(async () => {
|
|
||||||
const FieldCustomMixinClass = class extends FieldCustomMixin(LionField) {
|
|
||||||
static get properties() {
|
|
||||||
return {
|
|
||||||
modelValue: {
|
|
||||||
type: String,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
}
|
|
||||||
};
|
|
||||||
elem = defineCE(FieldCustomMixinClass);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('has the capability to disable help text', async () => {
|
|
||||||
const lionField = await fixture(`
|
|
||||||
<${elem} disable-help-text>${inputSlot}</${elem}>
|
|
||||||
`);
|
|
||||||
expect(Array.from(lionField.children).find(child => child.slot === 'help-text')).to.equal(
|
|
||||||
undefined,
|
|
||||||
);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
@ -1,7 +1,6 @@
|
||||||
import { css } from '@lion/core';
|
import { css } from '@lion/core';
|
||||||
import { LocalizeMixin, getCurrencyName } from '@lion/localize';
|
import { LocalizeMixin, getCurrencyName } from '@lion/localize';
|
||||||
import { LionInput } from '@lion/input';
|
import { LionInput } from '@lion/input';
|
||||||
import { FieldCustomMixin } from '@lion/field';
|
|
||||||
import { IsNumber } from '@lion/validate';
|
import { IsNumber } from '@lion/validate';
|
||||||
import { parseAmount } from './parsers.js';
|
import { parseAmount } from './parsers.js';
|
||||||
import { formatAmount } from './formatters.js';
|
import { formatAmount } from './formatters.js';
|
||||||
|
|
@ -12,22 +11,26 @@ import { formatAmount } from './formatters.js';
|
||||||
* @customElement lion-input-amount
|
* @customElement lion-input-amount
|
||||||
* @extends {LionInput}
|
* @extends {LionInput}
|
||||||
*/
|
*/
|
||||||
export class LionInputAmount extends FieldCustomMixin(LocalizeMixin(LionInput)) {
|
export class LionInputAmount extends LocalizeMixin(LionInput) {
|
||||||
static get properties() {
|
static get properties() {
|
||||||
return {
|
return {
|
||||||
currency: {
|
/**
|
||||||
type: String,
|
* @desc an iso code like 'EUR' or 'USD' that will be displayed next to the input
|
||||||
},
|
* and from which an accessible label (like 'euros') is computed for screen
|
||||||
|
* reader users
|
||||||
|
* @type {string}
|
||||||
|
*/
|
||||||
|
currency: String,
|
||||||
|
/**
|
||||||
|
* @desc the modelValue of the input-amount has the 'Number' type. This allows
|
||||||
|
* Application Developers to easily read from and write to this input or write custom
|
||||||
|
* validators.
|
||||||
|
* @type {number}
|
||||||
|
*/
|
||||||
|
modelValue: Number,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
updated(changedProps) {
|
|
||||||
super.updated(changedProps);
|
|
||||||
if (changedProps.has('currency')) {
|
|
||||||
this._onCurrencyChanged({ currency: this.currency });
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
get slots() {
|
get slots() {
|
||||||
return {
|
return {
|
||||||
...super.slots,
|
...super.slots,
|
||||||
|
|
@ -45,6 +48,21 @@ export class LionInputAmount extends FieldCustomMixin(LocalizeMixin(LionInput))
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
get _currencyDisplayNode() {
|
||||||
|
return Array.from(this.children).find(child => child.slot === 'after');
|
||||||
|
}
|
||||||
|
|
||||||
|
static get styles() {
|
||||||
|
return [
|
||||||
|
...super.styles,
|
||||||
|
css`
|
||||||
|
.input-group__container > .input-group__input ::slotted(.form-control) {
|
||||||
|
text-align: right;
|
||||||
|
}
|
||||||
|
`,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
super();
|
super();
|
||||||
this.parser = parseAmount;
|
this.parser = parseAmount;
|
||||||
|
|
@ -59,18 +77,6 @@ export class LionInputAmount extends FieldCustomMixin(LocalizeMixin(LionInput))
|
||||||
this.defaultValidators.push(new IsNumber());
|
this.defaultValidators.push(new IsNumber());
|
||||||
}
|
}
|
||||||
|
|
||||||
__callParser(value = this.formattedValue) {
|
|
||||||
// TODO: input and change events both trigger parsing therefore we need to handle the second parse
|
|
||||||
this.__parserCallcountSincePaste += 1;
|
|
||||||
this.__isPasting = this.__parserCallcountSincePaste === 2;
|
|
||||||
this.formatOptions.mode = this.__isPasting === true ? 'pasted' : 'auto';
|
|
||||||
return super.__callParser(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
_reflectBackOn() {
|
|
||||||
return super._reflectBackOn() || this.__isPasting;
|
|
||||||
}
|
|
||||||
|
|
||||||
connectedCallback() {
|
connectedCallback() {
|
||||||
// eslint-disable-next-line wc/guard-super-call
|
// eslint-disable-next-line wc/guard-super-call
|
||||||
super.connectedCallback();
|
super.connectedCallback();
|
||||||
|
|
@ -81,12 +87,29 @@ export class LionInputAmount extends FieldCustomMixin(LocalizeMixin(LionInput))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
__setCurrencyDisplayLabel() {
|
updated(changedProps) {
|
||||||
this._currencyDisplayNode.setAttribute('aria-label', getCurrencyName(this.currency));
|
super.updated(changedProps);
|
||||||
|
if (changedProps.has('currency')) {
|
||||||
|
this._onCurrencyChanged({ currency: this.currency });
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
get _currencyDisplayNode() {
|
/**
|
||||||
return Array.from(this.children).find(child => child.slot === 'after');
|
* @override of FormatMixin
|
||||||
|
*/
|
||||||
|
__callParser(value = this.formattedValue) {
|
||||||
|
// TODO: input and change events both trigger parsing therefore we need to handle the second parse
|
||||||
|
this.__parserCallcountSincePaste += 1;
|
||||||
|
this.__isPasting = this.__parserCallcountSincePaste === 2;
|
||||||
|
this.formatOptions.mode = this.__isPasting === true ? 'pasted' : 'auto';
|
||||||
|
return super.__callParser(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @override of FormatMixin
|
||||||
|
*/
|
||||||
|
_reflectBackOn() {
|
||||||
|
return super._reflectBackOn() || this.__isPasting;
|
||||||
}
|
}
|
||||||
|
|
||||||
_onCurrencyChanged({ currency }) {
|
_onCurrencyChanged({ currency }) {
|
||||||
|
|
@ -98,14 +121,10 @@ export class LionInputAmount extends FieldCustomMixin(LocalizeMixin(LionInput))
|
||||||
this.__setCurrencyDisplayLabel();
|
this.__setCurrencyDisplayLabel();
|
||||||
}
|
}
|
||||||
|
|
||||||
static get styles() {
|
__setCurrencyDisplayLabel() {
|
||||||
return [
|
// TODO: for optimal a11y, abbreviations should be part of aria-label
|
||||||
...super.styles,
|
// example, for a language switch with text 'en', an aria-label of 'english' is not
|
||||||
css`
|
// sufficient, it should also contain the abbreviation.
|
||||||
.input-group__container > .input-group__input ::slotted(.form-control) {
|
this._currencyDisplayNode.setAttribute('aria-label', getCurrencyName(this.currency));
|
||||||
text-align: right;
|
|
||||||
}
|
|
||||||
`,
|
|
||||||
];
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,4 @@
|
||||||
import { LocalizeMixin } from '@lion/localize';
|
import { LocalizeMixin } from '@lion/localize';
|
||||||
import { FieldCustomMixin } from '@lion/field';
|
|
||||||
import { LionInput } from '@lion/input';
|
import { LionInput } from '@lion/input';
|
||||||
import { IsEmail } from '@lion/validate';
|
import { IsEmail } from '@lion/validate';
|
||||||
|
|
||||||
|
|
@ -9,7 +8,7 @@ import { IsEmail } from '@lion/validate';
|
||||||
* @customElement lion-input-email
|
* @customElement lion-input-email
|
||||||
* @extends {LionInput}
|
* @extends {LionInput}
|
||||||
*/
|
*/
|
||||||
export class LionInputEmail extends FieldCustomMixin(LocalizeMixin(LionInput)) {
|
export class LionInputEmail extends LocalizeMixin(LionInput) {
|
||||||
constructor() {
|
constructor() {
|
||||||
super();
|
super();
|
||||||
// local-part@domain where the local part may be up to 64 characters long
|
// local-part@domain where the local part may be up to 64 characters long
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,5 @@
|
||||||
import { LocalizeMixin } from '@lion/localize';
|
import { LocalizeMixin } from '@lion/localize';
|
||||||
import { LionInput } from '@lion/input';
|
import { LionInput } from '@lion/input';
|
||||||
import { FieldCustomMixin } from '@lion/field';
|
|
||||||
import { formatIBAN } from './formatters.js';
|
import { formatIBAN } from './formatters.js';
|
||||||
import { parseIBAN } from './parsers.js';
|
import { parseIBAN } from './parsers.js';
|
||||||
import { IsIBAN } from './validators.js';
|
import { IsIBAN } from './validators.js';
|
||||||
|
|
@ -10,7 +9,7 @@ import { IsIBAN } from './validators.js';
|
||||||
*
|
*
|
||||||
* @extends {LionInput}
|
* @extends {LionInput}
|
||||||
*/
|
*/
|
||||||
export class LionInputIban extends FieldCustomMixin(LocalizeMixin(LionInput)) {
|
export class LionInputIban extends LocalizeMixin(LionInput) {
|
||||||
constructor() {
|
constructor() {
|
||||||
super();
|
super();
|
||||||
this.formatter = formatIBAN;
|
this.formatter = formatIBAN;
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,5 @@
|
||||||
/* eslint-disable import/no-extraneous-dependencies */
|
/* eslint-disable import/no-extraneous-dependencies */
|
||||||
import { LocalizeMixin, formatNumber } from '@lion/localize';
|
import { LocalizeMixin, formatNumber } from '@lion/localize';
|
||||||
import { FieldCustomMixin } from '@lion/field';
|
|
||||||
import { LionInput } from '@lion/input';
|
import { LionInput } from '@lion/input';
|
||||||
import { html, css, unsafeCSS } from '@lion/core';
|
import { html, css, unsafeCSS } from '@lion/core';
|
||||||
|
|
||||||
|
|
@ -10,7 +9,7 @@ import { html, css, unsafeCSS } from '@lion/core';
|
||||||
* @customElement `lion-input-range`
|
* @customElement `lion-input-range`
|
||||||
* @extends LionInput
|
* @extends LionInput
|
||||||
*/
|
*/
|
||||||
export class LionInputRange extends FieldCustomMixin(LocalizeMixin(LionInput)) {
|
export class LionInputRange extends LocalizeMixin(LionInput) {
|
||||||
static get properties() {
|
static get properties() {
|
||||||
return {
|
return {
|
||||||
min: Number,
|
min: Number,
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue