diff --git a/packages/library/components/inputter/src/inputter-component.js b/packages/library/components/inputter/src/inputter-component.js
index f061852b..9957f90c 100644
--- a/packages/library/components/inputter/src/inputter-component.js
+++ b/packages/library/components/inputter/src/inputter-component.js
@@ -1,4 +1,4 @@
-import { html, MuonElement, classMap, ScopedElementsMixin } from '@muons/library';
+import { html, MuonElement, ScopedElementsMixin, classMap, styleMap } from '@muons/library';
import {
INPUTTER_TYPE,
INPUTTER_DETAIL_TOGGLE_OPEN,
@@ -7,23 +7,23 @@ import {
INPUTTER_VALIDATION_WARNING_ICON
} from '@muons/library/build/tokens/es6/muon-tokens';
import { ValidationMixin } from '@muons/library/mixins/validation-mixin';
+import { MaskMixin } from '@muons/library/mixins/mask-mixin';
import { DetailMixin } from '@muons/library/mixins/detail-mixin';
import { Icon } from '@muons/library/components/icon';
import styles from './styles.css';
/**
- * Allow for inputs
+ * A component to allow for user inputs of type text, radio, checkbox, select,
+ * date, tel, number, textarea, search.
*
* @element inputter
*/
-export class Inputter extends ScopedElementsMixin(ValidationMixin(MuonElement)) {
+export class Inputter extends ScopedElementsMixin(MaskMixin(ValidationMixin(MuonElement))) {
static get properties() {
return {
helper: { type: String },
- mask: { type: String },
- separator: { type: String },
isHelperOpen: { type: Boolean }
};
}
@@ -52,12 +52,6 @@ export class Inputter extends ScopedElementsMixin(ValidationMixin(MuonElement))
return html``;
}
- get validity() {
- this.pristine = false;
- this.validate();
- return this._validity;
- }
-
/**
* A method to check availability of tip details slot.
* @returns {Boolean} - availability of tip details slot.
@@ -94,15 +88,24 @@ export class Inputter extends ScopedElementsMixin(ValidationMixin(MuonElement))
get standardTemplate() {
const classes = {
'slotted-content': true,
- 'select-arrow': this._inputType === this._isSelect
+ 'select-arrow': this._isSelect,
+ 'has-mask': this.mask
};
+ let styles = {};
+ if (this.mask) {
+ styles = {
+ '--maxlength': this.mask.length
+ };
+ }
+
return html `
-
+
${this._isMultiple ? this._headingTemplate : this._labelTemplate}
${this._helperTemplate}
${super.standardTemplate}
+ ${this._maskTemplate}
${this._validationMessageTemplate}`;
diff --git a/packages/library/components/inputter/src/styles.css b/packages/library/components/inputter/src/styles.css
index f26d7012..8dd49ffb 100644
--- a/packages/library/components/inputter/src/styles.css
+++ b/packages/library/components/inputter/src/styles.css
@@ -3,6 +3,35 @@
:host {
display: block;
+ & .has-mask {
+ position: relative;
+
+ & .input-mask,
+ & ::slotted(input) {
+ padding: 0.5rem 1rem;
+ margin: 0.75rem 0;
+ letter-spacing: 0.5rem;
+ max-width: calc((var(--maxlength) + 1) * 1rem);
+ }
+
+ & .input-mask {
+ display: inline-block;
+ position: absolute;
+ left: 0;
+ color: lightslategray;
+ white-space: pre;
+ z-index: -1;
+ text-align: start;
+ font-size: 1.5rem;
+ }
+
+ & ::slotted(input) {
+ background-color: transparent;
+ font-size: 1.25rem;
+ padding-right: 1.25rem;
+ }
+ }
+
& .validation {
display: flex;
margin: 0.5rem 0;
diff --git a/packages/library/components/inputter/story.js b/packages/library/components/inputter/story.js
index 0872ccbc..af73d6e2 100644
--- a/packages/library/components/inputter/story.js
+++ b/packages/library/components/inputter/story.js
@@ -49,6 +49,12 @@ const textareaInputText = (args) => `
export const Textarea = (args) => details.template(args, textareaInputText);
Textarea.args = { label: 'A label', value: 'gas', validation: '["isRequired"]' };
+export const Mask = (args) => details.template(args, innerInputText);
+Mask.args = { label: 'A label', value: '', mask: '000000' };
+
+export const Separator = (args) => details.template(args, innerInputText);
+Separator.args = { label: 'A label', value: '', separator: '-', mask: ' - - ' };
+
const innerInputDate = (args) => `
@@ -56,10 +62,20 @@ const innerInputDate = (args) => `
export const Date = (args) => details.template(args, innerInputDate);
Date.args = { label: 'A label', value: '', validation: '["isRequired","minDate(\'11/11/2021\')"]' };
+export const DateMask = (args) => details.template(args, innerInputDate);
+DateMask.args = { label: 'A label', value: '', mask: 'dd/mm/yyyy', separator: '/', validation: '["isRequired","minDate(\'11/11/2021\')"]' };
+
const innerInputTel = (args) => `
`;
export const Tel = (args) => details.template(args, innerInputTel);
-Tel.args = { label: 'A label', value: '', validation: '["isRequired"]' };
+Tel.args = { label: 'A label', value: '', validation: '["isRequired"]', mask: '000-000-0000', separator: '-' };
+
+const innerInputNumber = (args) => `
+
+
+`;
+export const Number = (args) => details.template(args, innerInputNumber);
+Number.args = { label: 'A label', value: '', validation: '["isRequired"]' };
diff --git a/packages/library/mixins/form-element-mixin.js b/packages/library/mixins/form-element-mixin.js
index 91a599cd..420d6c75 100644
--- a/packages/library/mixins/form-element-mixin.js
+++ b/packages/library/mixins/form-element-mixin.js
@@ -88,7 +88,7 @@ export const FormElementMixin = (superClass) =>
}
firstUpdated() {
-
+ super.firstUpdated();
this._slottedInputs.forEach((input) => {
input.addEventListener('change', this._onChange.bind(this));
input.addEventListener('blur', this._onBlur.bind(this));
diff --git a/packages/library/mixins/mask-mixin.js b/packages/library/mixins/mask-mixin.js
new file mode 100644
index 00000000..00fee662
--- /dev/null
+++ b/packages/library/mixins/mask-mixin.js
@@ -0,0 +1,151 @@
+import { html, ifDefined } from '@muons/library';
+import { dedupeMixin } from '@open-wc/dedupe-mixin';
+import { FormElementMixin } from './form-element-mixin';
+
+/**
+ * A mixin to enable mask and separator features to a form element.
+ * `mask` property is supported for input of type text, date, tel.
+ * `separator` property is supported for input of type text, date, tel.
+ * @mixin
+ */
+
+export const MaskMixin = dedupeMixin((superclass) =>
+ class MaskMixinClass extends FormElementMixin(superclass) {
+ static get properties() {
+ return {
+ mask: {
+ type: String
+ },
+
+ separator: {
+ type: String
+ }
+ };
+ }
+
+ constructor() {
+ super();
+
+ this.mask = '';
+ this.separator = '';
+ }
+
+ firstUpdated() {
+ super.firstUpdated();
+
+ if (this.mask) {
+ this._slottedInputs.map((input) => {
+ input.addEventListener('input', this._onInput.bind(this));
+ input.setAttribute('maxlength', this.mask.length);
+ });
+ }
+ }
+
+ /**
+ * A method to handle `input` event when `mask` is provided.
+ * @param {Event} inputEvent - event while 'input.
+ * @returns {undefined}
+ * @protected
+ * @override
+ */
+ _onInput(inputEvent) {
+ inputEvent.stopPropagation();
+ inputEvent.preventDefault();
+ const inputElement = this._slottedInputs[0];
+ if (ifDefined(this.separator)) {
+ this.updateValue(inputElement);
+ } else {
+ this.value = inputElement.value;
+ }
+ }
+
+ _processValue(value) {
+ value = super._processValue(value);
+ if (ifDefined(this.separator)) {
+ value = this.formatWithMaskAndSeparator(value);
+ this._slottedInputs[0].value = value;
+ }
+ return value;
+ }
+
+ /**
+ * A method to update the form element value with separator in adjusted indices and cursor position.
+ *
+ * @param {HTMLInputElement} input - HTMLInputElement value to be updated with seperators
+ * @returns {undefined}
+ */
+ updateValue(input) {
+ let value = input.value;
+ let cursor = input.selectionStart;
+ const diff = this.value.length - value.length;
+
+ if (diff > 0 && this.mask.charAt(cursor) === this.separator) {
+ value = value.slice(0, cursor - 1) + (cursor < value.length ? value.slice(cursor) : '');
+ cursor -= 1;
+ }
+ const formattedValue = this.formatWithMaskAndSeparator(value);
+ input.value = formattedValue;
+ this.value = formattedValue;
+
+ if (this.mask.charAt(cursor) === this.separator) {
+ cursor += 1;
+ }
+ this.updateComplete.then(() => {
+ input.setSelectionRange(cursor, cursor);
+ });
+ }
+
+ /**
+ * A method to format the form element value with separator adjusted to correct indices
+ * after editing the form element value.
+ *
+ * @param {String} value - value of the form element.
+ * @return {String} - value with adjusted separator in correct indices.
+ */
+ formatWithMaskAndSeparator(value) {
+ const formattedValue = this.__formatInputWithoutSeparator(value);
+ const parts = this.mask.split(this.separator);
+ let processedValue = '';
+ let length = 0;
+ let currentLength = 0;
+
+ for (let i = 0; i < parts.length && length < formattedValue.length; i++) {
+ const remainingLength = formattedValue.length - length;
+ const splitPoint = remainingLength > parts[i].length ? parts[i].length : remainingLength;
+
+ processedValue += formattedValue.substr(length, splitPoint);
+ currentLength += parts[i].length;
+
+ if (i < (parts.length - 1) && processedValue.length === currentLength) {
+ processedValue += this.separator;
+ currentLength += 1;
+ }
+
+ length += parts[i].length;
+ }
+
+ return processedValue;
+ }
+
+ /**
+ * A method to remove separator from the value of the form element.
+ *
+ * @param {String} value - form element value.
+ * @return {String} - value with separator removed.
+ */
+ __formatInputWithoutSeparator(value) {
+ return value.split(this.separator).join('');
+ }
+
+ get _maskTemplate() {
+ if (this.mask) {
+ const length = this.value ? this.value.length : 0;
+ let updatedMask = new Array(length + 1).join(' ');
+ updatedMask += this.mask.slice(length);
+ return html`
${updatedMask}
`;
+ } else {
+ return undefined;
+ }
+ }
+ }
+);
diff --git a/packages/library/tests/components/inputter/__snapshots__/inputter.test.snap.js b/packages/library/tests/components/inputter/__snapshots__/inputter.test.snap.js
new file mode 100644
index 00000000..1752d2dc
--- /dev/null
+++ b/packages/library/tests/components/inputter/__snapshots__/inputter.test.snap.js
@@ -0,0 +1,55 @@
+/* @web/test-runner snapshot v1 */
+export const snapshots = {};
+
+snapshots["Inputter standard default default checks"] =
+`
+`;
+/* end snapshot Inputter standard default default checks */
+
+snapshots["Inputter text input mask text default checks"] =
+`
+`;
+/* end snapshot Inputter text input mask text default checks */
+
+snapshots["Inputter radio input standard radio default checks"] =
+`
+
+ What is your heating source?
+
+
+
+
+
+
+`;
+/* end snapshot Inputter radio input standard radio default checks */
+
diff --git a/packages/library/tests/components/inputter/inputter.test.js b/packages/library/tests/components/inputter/inputter.test.js
new file mode 100644
index 00000000..4db85509
--- /dev/null
+++ b/packages/library/tests/components/inputter/inputter.test.js
@@ -0,0 +1,79 @@
+/* eslint-disable no-undef */
+import { expect, fixture, html, defineCE, unsafeStatic } from '@open-wc/testing';
+import { Inputter } from '@muons/library/components/inputter';
+import { defaultChecks } from '../../helpers';
+
+const tagName = defineCE(Inputter);
+const tag = unsafeStatic(tagName);
+
+describe('Inputter', () => {
+ describe('standard default', async () => {
+ let inputter;
+ before(async () => {
+ inputter = await fixture(html`
+ <${tag}>
+ ${tag}>`);
+ });
+
+ it('default checks', async () => {
+ await defaultChecks(inputter);
+ });
+
+ it('default properties', async () => {
+ expect(inputter.type).to.equal('standard', 'default type is set');
+ expect(inputter.id).to.not.be.null; // eslint-disable-line no-unused-expressions
+ });
+ });
+ describe('text input', async () => {
+ describe('mask text', async () => {
+ let inputter;
+ let shadowRoot;
+ before(async () => {
+ inputter = await fixture(html`
+ <${tag} mask="0000">
+
+
+ ${tag}>`);
+ shadowRoot = inputter.shadowRoot;
+ });
+
+ it('default checks', async () => {
+ await defaultChecks(inputter);
+ });
+
+ it('default properties', async () => {
+ expect(inputter.type).to.equal('standard', 'default type is set');
+ expect(inputter.id).to.not.be.null; // eslint-disable-line no-unused-expressions
+ expect(shadowRoot.querySelector('.has-mask')).to.not.be.null; // eslint-disable-line no-unused-expressions
+ });
+ });
+ });
+
+ describe('radio input', async () => {
+ describe('standard radio', async () => {
+ let inputter;
+ let shadowRoot;
+ before(async () => {
+ inputter = await fixture(html`
+ <${tag} heading="What is your heating source?">
+
+
+
+
+ ${tag}>`);
+ shadowRoot = inputter.shadowRoot;
+ });
+
+ it('default checks', async () => {
+ await defaultChecks(inputter);
+ });
+
+ it('default properties', async () => {
+ expect(inputter.type).to.equal('standard', 'default type is set');
+ expect(inputter.id).to.not.be.null; // eslint-disable-line no-unused-expressions
+ expect(shadowRoot.querySelector('.input-heading')).to.not.be.null; // eslint-disable-line no-unused-expressions
+ expect(shadowRoot.querySelector('.input-mask')).to.be.null; // eslint-disable-line no-unused-expressions
+ });
+ });
+ });
+});
diff --git a/packages/library/tests/helpers/index.js b/packages/library/tests/helpers/index.js
index 0f16b6cd..52833eea 100644
--- a/packages/library/tests/helpers/index.js
+++ b/packages/library/tests/helpers/index.js
@@ -10,14 +10,18 @@ export const defaultChecks = async (el) => {
await expect(el).to.be.accessible();
};
+export const fireEvent = async (element, event) => {
+ const customEvent = new CustomEvent(event, { bubbles: true });
+ await element.dispatchEvent(customEvent);
+};
+
const fireChangeEvent = async (element) => {
- const event = new CustomEvent('change', { bubbles: true });
- await element.dispatchEvent(event);
+ await fireEvent(element, 'change');
};
-export const fillIn = async (element, content) => {
+export const fillIn = async (element, content, event = 'change') => {
element.value = content;
- await fireChangeEvent(element);
+ await fireEvent(element, event);
};
export const selectEvent = async (element, value) => {
diff --git a/packages/library/tests/mixins/__snapshots__/form-element.test.snap.js b/packages/library/tests/mixins/__snapshots__/form-element.test.snap.js
index a2fe50d4..f1a5a4cc 100644
--- a/packages/library/tests/mixins/__snapshots__/form-element.test.snap.js
+++ b/packages/library/tests/mixins/__snapshots__/form-element.test.snap.js
@@ -52,7 +52,7 @@ snapshots["form-element standard checkbox input"] =
/* end snapshot form-element standard checkbox input */
snapshots["form-element standard select input"] =
-`
+`
diff --git a/packages/library/tests/mixins/__snapshots__/mask.test.snap.js b/packages/library/tests/mixins/__snapshots__/mask.test.snap.js
new file mode 100644
index 00000000..fe7e4d17
--- /dev/null
+++ b/packages/library/tests/mixins/__snapshots__/mask.test.snap.js
@@ -0,0 +1,45 @@
+/* @web/test-runner snapshot v1 */
+export const snapshots = {};
+
+snapshots["mask & separator mask default checks"] =
+`
+
+
+
+
+ 00000
+
+`;
+/* end snapshot mask & separator mask default checks */
+
+snapshots["mask & separator mask separator default checks"] =
+`
+
+
+
+
+ 00-00-00
+
+`;
+/* end snapshot mask & separator mask separator default checks */
+
+snapshots["mask & separator tel mask seprator default checks"] =
+`
+
+
+
+
+ 00-00-00
+
+`;
+/* end snapshot mask & separator tel mask seprator default checks */
+
diff --git a/packages/library/tests/mixins/form-element.test.js b/packages/library/tests/mixins/form-element.test.js
index 82737320..7fc72adb 100644
--- a/packages/library/tests/mixins/form-element.test.js
+++ b/packages/library/tests/mixins/form-element.test.js
@@ -10,7 +10,7 @@ const MuonFormElement = class extends FormElementMixin(MuonElement) {
get standardTemplate() {
const classes = {
'slotted-content': true,
- 'select-arrow': this._inputType === this._isSelect
+ 'select-arrow': this._isSelect
};
return html `
@@ -62,12 +62,12 @@ const MuonFormElement = class extends FormElementMixin(MuonElement) {
if (this._isSelect) {
const classes = {
'slotted-content': true,
- 'select-arrow': this._inputType === this._isSelect
+ 'select-arrow': this._isSelect
};
return html `
- ${this._isMultiple ? this._headingTemplate : this._labelTemplate}
+ ${this._labelTemplate}
${super.standardTemplate}
diff --git a/packages/library/tests/mixins/mask.test.js b/packages/library/tests/mixins/mask.test.js
new file mode 100644
index 00000000..12f68279
--- /dev/null
+++ b/packages/library/tests/mixins/mask.test.js
@@ -0,0 +1,186 @@
+/* eslint-disable no-undef */
+import { expect, fixture, html, defineCE, unsafeStatic, waitUntil } from '@open-wc/testing';
+import { MuonElement } from '@muons/library';
+import { MaskMixin } from '@muons/library/mixins/mask-mixin';
+import { defaultChecks, fillIn } from '../helpers';
+
+const Inputter = class extends MaskMixin(MuonElement) {
+ get standardTemplate() {
+ return html`
+ ${this._labelTemplate}
+ ${this._htmlFormElementTemplate}
+ ${this._maskTemplate}
+ `;
+ }
+};
+const tagName = defineCE(Inputter);
+const tag = unsafeStatic(tagName);
+
+describe('mask & separator', () => {
+ describe('mask', async () => {
+ let inputter;
+ let shadowRoot;
+ let maskedInput;
+ let inputElement;
+ before(async () => {
+ inputter = await fixture(html`
+ <${tag} mask="00000" >
+
+
+ ${tag}>`);
+ shadowRoot = inputter.shadowRoot;
+ maskedInput = shadowRoot.querySelector('.input-mask');
+ inputElement = inputter.querySelector('input');
+ });
+
+ it('default checks', async () => {
+ await defaultChecks(inputter);
+ });
+
+ it('masked input check', async () => {
+ expect(maskedInput).to.be.not.null; // eslint-disable-line no-unused-expressions
+ expect(maskedInput.textContent).to.be.equal('00000', '`input-mask` has correct value');
+ });
+
+ it('input value `1`', async () => {
+ await fillIn(inputElement, '1', 'input');
+ await waitUntil(() => inputter.value === '1');
+ maskedInput = shadowRoot.querySelector('.input-mask');
+ expect(inputElement.value).to.be.equal('1', 'Input has correct value');
+ expect(inputter.value).to.be.equal('1', 'Inputter has correct value');
+ expect(maskedInput.textContent).to.be.equal(' 0000', '`input-mask` has correct value');
+ });
+
+ it('input value `12`', async () => {
+ await fillIn(inputElement, '12', 'input');
+ await waitUntil(() => inputter.value === '12');
+ maskedInput = shadowRoot.querySelector('.input-mask');
+ expect(inputElement.value).to.be.equal('12', 'Input has correct value');
+ expect(inputter.value).to.be.equal('12', 'Inputter has correct value');
+ expect(maskedInput.textContent).to.be.equal(' 000', '`input-mask` has correct value');
+ });
+ });
+
+ describe('mask separator', async () => {
+ let inputter;
+ let shadowRoot;
+ let maskedInput;
+ let inputElement;
+ before(async () => {
+ inputter = await fixture(html`
+ <${tag} mask="00-00-00" separator="-">
+
+
+ ${tag}>`);
+ shadowRoot = inputter.shadowRoot;
+ maskedInput = shadowRoot.querySelector('.input-mask');
+ inputElement = inputter.querySelector('input');
+ });
+
+ it('default checks', async () => {
+ await defaultChecks(inputter);
+ });
+
+ it('masked input check', async () => {
+ expect(maskedInput).to.be.not.null; // eslint-disable-line no-unused-expressions
+ expect(maskedInput.textContent).to.be.equal('00-00-00', '`input-mask` has correct value');
+ });
+
+ it('input value `1`', async () => {
+ await fillIn(inputElement, '1', 'input');
+ await waitUntil(() => inputter.value === '1');
+ maskedInput = inputter.shadowRoot.querySelector('.input-mask');
+ expect(inputElement.value).to.be.equal('1', 'Input has correct value');
+ expect(inputter.value).to.be.equal('1', 'Inputter has correct value');
+ expect(maskedInput.textContent).to.be.equal(' 0-00-00', '`input-mask` has correct value');
+ });
+
+ it('input value `12`', async () => {
+ await fillIn(inputElement, '12', 'input');
+ await waitUntil(() => inputter.value === '12-');
+ maskedInput = inputter.shadowRoot.querySelector('.input-mask');
+ expect(inputElement.value).to.be.equal('12-', 'Input has correct value');
+ expect(inputter.value).to.be.equal('12-', 'Inputter has correct value');
+ expect(maskedInput.textContent).to.be.equal(' 00-00', '`input-mask` has correct value');
+ });
+
+ it('input value `123`', async () => {
+ await fillIn(inputElement, '123', 'input');
+ await waitUntil(() => inputter.value === '12-3');
+ maskedInput = inputter.shadowRoot.querySelector('.input-mask');
+ expect(inputElement.value).to.be.equal('12-3', 'Input has correct value');
+ expect(inputter.value).to.be.equal('12-3', 'Inputter has correct value');
+ expect(maskedInput.textContent).to.be.equal(' 0-00', '`input-mask` has correct value');
+ });
+
+ it('delete value `3`', async () => {
+ await fillIn(inputElement, '12-', 'input');
+ await waitUntil(() => inputter.value === '12-');
+ maskedInput = inputter.shadowRoot.querySelector('.input-mask');
+ expect(inputElement.value).to.be.equal('12-', 'Input has correct value');
+ expect(inputter.value).to.be.equal('12-', 'Inputter has correct value');
+ expect(maskedInput.textContent).to.be.equal(' 00-00', '`input-mask` has correct value');
+ });
+
+ it('delete value `2`', async () => {
+ await fillIn(inputElement, '12', 'input');
+ await waitUntil(() => inputter.value === '1');
+ maskedInput = inputter.shadowRoot.querySelector('.input-mask');
+ expect(inputElement.value).to.be.equal('1', 'Input has correct value');
+ expect(inputter.value).to.be.equal('1', 'Inputter has correct value');
+ expect(maskedInput.textContent).to.be.equal(' 0-00-00', '`input-mask` has correct value');
+ });
+
+ it('input value `123`', async () => {
+ await fillIn(inputElement, '123');
+ await waitUntil(() => inputter.value === '12-3');
+ maskedInput = inputter.shadowRoot.querySelector('.input-mask');
+ expect(inputElement.value).to.be.equal('12-3', 'Input has correct value');
+ expect(inputter.value).to.be.equal('12-3', 'Inputter has correct value');
+ expect(maskedInput.textContent).to.be.equal(' 0-00', '`input-mask` has correct value');
+ });
+ });
+
+ describe('tel mask seprator', async () => {
+ let inputter;
+ let shadowRoot;
+ let maskedInput;
+ let inputElement;
+ before(async () => {
+ inputter = await fixture(html`
+ <${tag} mask="00-00-00" separator="-">
+
+
+ ${tag}>`);
+ shadowRoot = inputter.shadowRoot;
+ maskedInput = shadowRoot.querySelector('.input-mask');
+ inputElement = inputter.querySelector('input');
+ });
+
+ it('default checks', async () => {
+ await defaultChecks(inputter);
+ });
+
+ it('masked input check', async () => {
+ expect(maskedInput).to.be.not.null; // eslint-disable-line no-unused-expressions
+ expect(maskedInput.textContent).to.be.equal('00-00-00', '`input-mask` has correct value');
+ });
+
+ it('input value `1`', async () => {
+ await fillIn(inputElement, '1', 'input');
+ await waitUntil(() => inputter.value === '1');
+ maskedInput = inputter.shadowRoot.querySelector('.input-mask');
+ expect(inputter.value).to.be.equal('1', 'Inputter has correct value');
+ expect(maskedInput.textContent).to.be.equal(' 0-00-00', '`input-mask` has correct value');
+ });
+
+ it('input value `12`', async () => {
+ await fillIn(inputElement, '12', 'input');
+ await waitUntil(() => inputter.value === '12-');
+ maskedInput = inputter.shadowRoot.querySelector('.input-mask');
+ expect(inputElement.value).to.be.equal('12-', 'Input has correct value');
+ expect(inputter.value).to.be.equal('12-', 'Inputter has correct value');
+ expect(maskedInput.textContent).to.be.equal(' 00-00', '`input-mask` has correct value');
+ });
+ });
+});
diff --git a/packages/library/tests/mixins/validation.test.js b/packages/library/tests/mixins/validation.test.js
index 4266cf1a..cd5fdac5 100644
--- a/packages/library/tests/mixins/validation.test.js
+++ b/packages/library/tests/mixins/validation.test.js
@@ -3,7 +3,7 @@ import { expect, fixture, html, defineCE, unsafeStatic } from '@open-wc/testing'
import { MuonElement } from '@muons/library';
import sinon from 'sinon';
import { defaultChecks, fillIn, selectEvent } from '../helpers';
-import { ValidationMixin } from '../../mixins/validation-mixin';
+import { ValidationMixin } from '@muons/library/mixins/validation-mixin';
const isFirstName = (inputter, value) => {
const isName = /^[A-Za-zÀ-ÖØ-öø-ÿ\-\s]{1,24}$/i.test(value);