feat(form-core): add select and upload specific required messages

This commit is contained in:
gerjanvangeest 2024-01-24 16:16:45 +01:00 committed by Thijs Louisse
parent b68fa39924
commit e72fd6d6ea
31 changed files with 362 additions and 198 deletions

View file

@ -0,0 +1,5 @@
---
'@lion/ui': patch
---
[form-core] add operationMode to ValidateMixin, to create specific select and upload required messages

View file

@ -106,7 +106,7 @@ When file has to be uploaded as soon as it is selected by the user. Use `file-li
export const basicFileUpload = () => {
return html`
<lion-input-file
label="Label"
label="Passport"
max-file-size="1024000"
accept=".jpg,.svg,.xml,image/svg+xml"
@file-list-changed="${ev => {
@ -131,7 +131,7 @@ export const acceptValidator = () => {
return html`
<lion-input-file
accept=".jpg,.svg,.xml,image/svg+xml"
label="Upload"
label="Passport"
enable-drop-zone
@file-list-changed="${ev => {
console.log(ev.detail.newFiles);
@ -151,7 +151,7 @@ export const sizeValidator = () => {
return html`
<lion-input-file
max-file-size="2048"
label="Upload"
label="Passport"
@file-list-changed="${ev => {
console.log(ev.detail.newFiles);
}}"
@ -169,7 +169,7 @@ When file has to be uploaded as soon as it is selected by the user. Use `file-li
export const multipleFileUpload = () => {
return html`
<lion-input-file
label="Upload"
label="Passport"
name="upload"
multiple
max-file-size="1024000"
@ -203,7 +203,7 @@ On every reload of page, the file upload component reverts to the initial state
export const prefilledState = () => {
return html`
<lion-input-file
label="Upload"
label="Passport"
name="myFiles"
multiple
.validators="${[new Required()]}"
@ -272,7 +272,7 @@ export const withIngForm = () => {
return html`
<form @submit="${myFormSubmit}" @reset="${myFormReset}">
<lion-input-file
label="Upload"
label="Passport"
name="upload"
multiple
.validators="${[new Required(), new FilenameLengthValidator({ maxFilenameLength: 20 })]}"
@ -321,7 +321,7 @@ Below is the flow:
export const uploadWithoutFormSubmit = () => {
return html`
<lion-input-file
label="Upload"
label="Passport"
name="upload"
multiple
upload-on-select
@ -393,7 +393,7 @@ Drag and drop the files to be uploaded to the server.
export const dragAndDrop = () => {
return html`
<lion-input-file
label="Upload"
label="Passport"
name="myFiles"
accept=".png"
max-file-size="1024000"

View file

@ -3,8 +3,11 @@
```js script
import { html } from '@mdjs/mdjs-preview';
import { listboxData } from './src/listboxData.js';
import { Required } from '@lion/ui/form-core.js';
import { loadDefaultFeedbackMessages } from '@lion/ui/validate-messages.js';
import '@lion/ui/define/lion-listbox.js';
import '@lion/ui/define/lion-option.js';
loadDefaultFeedbackMessages();
```
## Multiple choice
@ -16,9 +19,8 @@ This will:
- display a list of selected option representations next to the text box
- make the value of type `Array` instead of `String`
```js preview-story
export const multiple = () => html`
<lion-listbox name="combo" label="Multiple" multiple-choice>
```html preview-story
<lion-listbox name="combo" label="Multiple" multiple-choice>
<lion-option .choiceValue=${'Apple'}>Apple</lion-option>
<lion-option .choiceValue=${'Artichoke'}>Artichoke</lion-option>
<lion-option .choiceValue=${'Asparagus'}>Asparagus</lion-option>
@ -29,8 +31,7 @@ export const multiple = () => html`
<lion-option .choiceValue=${'Brussels sprout'}>Brussels sprout</lion-option>
<lion-option .choiceValue=${'Cabbage'}>Cabbage</lion-option>
<lion-option .choiceValue=${'Carrot'}>Carrot</lion-option>
</lion-listbox>
`;
</lion-listbox>
```
## Orientation
@ -39,9 +40,8 @@ When `orientation="horizontal"`, left and right arrow keys will be enabled, plus
will be informed about the direction of the options.
By default, `orientation="vertical"` is set, which enables up and down arrow keys.
```js preview-story
export const orientationHorizontal = () => html`
<lion-listbox name="combo" label="Orientation horizontal" orientation="horizontal">
```html preview-story
<lion-listbox name="combo" label="Orientation horizontal" orientation="horizontal">
<lion-option .choiceValue=${'Apple'}>Apple</lion-option>
<lion-option .choiceValue=${'Artichoke'}>Artichoke</lion-option>
<lion-option .choiceValue=${'Asparagus'}>Asparagus</lion-option>
@ -52,20 +52,18 @@ export const orientationHorizontal = () => html`
<lion-option .choiceValue=${'Brussels sprout'}>Brussels sprout</lion-option>
<lion-option .choiceValue=${'Cabbage'}>Cabbage</lion-option>
<lion-option .choiceValue=${'Carrot'}>Carrot</lion-option>
</lion-listbox>
`;
</lion-listbox>
```
With `multiple-choice` flag configured, multiple options can be checked.
```js preview-story
export const orientationHorizontalMultiple = () => html`
<lion-listbox
```html preview-story
<lion-listbox
name="combo"
label="Orientation horizontal multiple"
orientation="horizontal"
multiple-choice
>
>
<lion-option .choiceValue=${'Apple'}>Apple</lion-option>
<lion-option .choiceValue=${'Artichoke'}>Artichoke</lion-option>
<lion-option .choiceValue=${'Asparagus'}>Asparagus</lion-option>
@ -76,8 +74,7 @@ export const orientationHorizontalMultiple = () => html`
<lion-option .choiceValue=${'Brussels sprout'}>Brussels sprout</lion-option>
<lion-option .choiceValue=${'Cabbage'}>Cabbage</lion-option>
<lion-option .choiceValue=${'Carrot'}>Carrot</lion-option>
</lion-listbox>
`;
</lion-listbox>
```
## Selection-follows-focus
@ -87,9 +84,8 @@ This behavior can usually be seen in `<select>` on the Windows platform.
Note that this behavior cannot be used when multiple-choice is true.
See [wai aria spec](https://www.w3.org/TR/wai-aria-practices/#kbd_selection_follows_focus)
```js preview-story
export const selectionFollowsFocus = () => html`
<lion-listbox name="combo" label="Selection follows focus" selection-follows-focus>
```html preview-story
<lion-listbox name="combo" label="Selection follows focus" selection-follows-focus>
<lion-option .choiceValue=${'Apple'}>Apple</lion-option>
<lion-option .choiceValue=${'Artichoke'} disabled>Artichoke</lion-option>
<lion-option .choiceValue=${'Asparagus'}>Asparagus</lion-option>
@ -100,17 +96,15 @@ export const selectionFollowsFocus = () => html`
<lion-option .choiceValue=${'Brussels sprout'}>Brussels sprout</lion-option>
<lion-option .choiceValue=${'Cabbage'}>Cabbage</lion-option>
<lion-option .choiceValue=${'Carrot'}>Carrot</lion-option>
</lion-listbox>
`;
</lion-listbox>
```
## Rotate keyboard navigation
`rotate-keyboard-navigation` attribute on the listbox will give the first option active state when navigated to the next option from last option.
```js preview-story
export const rotateKeyboardNavigation = () => html`
<lion-listbox name="combo" label="Rotate keyboard navigation" rotate-keyboard-navigation>
```html preview-story
<lion-listbox name="combo" label="Rotate keyboard navigation" rotate-keyboard-navigation>
<lion-option .choiceValue=${'Apple'}>Apple</lion-option>
<lion-option .choiceValue=${'Artichoke'}>Artichoke</lion-option>
<lion-option .choiceValue=${'Asparagus'}>Asparagus</lion-option>
@ -121,17 +115,15 @@ export const rotateKeyboardNavigation = () => html`
<lion-option .choiceValue=${'Brussels sprout'}>Brussels sprout</lion-option>
<lion-option .choiceValue=${'Cabbage'}>Cabbage</lion-option>
<lion-option .choiceValue=${'Carrot'}>Carrot</lion-option>
</lion-listbox>
`;
</lion-listbox>
```
## Disabled options
Navigation will skip over disabled options. Let's disable Artichoke and Brussel sprout, because they're gross.
```js preview-story
export const disabledRotateNavigation = () => html`
<lion-listbox name="combo" label="Rotate with disabled options" rotate-keyboard-navigation>
```html preview-story
<lion-listbox name="combo" label="Rotate with disabled options" rotate-keyboard-navigation>
<lion-option .choiceValue=${'Apple'}>Apple</lion-option>
<lion-option .choiceValue=${'Artichoke'} disabled>Artichoke</lion-option>
<lion-option .choiceValue=${'Asparagus'}>Asparagus</lion-option>
@ -142,6 +134,9 @@ export const disabledRotateNavigation = () => html`
<lion-option .choiceValue=${'Brussels sprout'} disabled>Brussels sprout</lion-option>
<lion-option .choiceValue=${'Cabbage'}>Cabbage</lion-option>
<lion-option .choiceValue=${'Carrot'}>Carrot</lion-option>
</lion-listbox>
`;
</lion-listbox>
```
## Validation
A validator can be used to make it e.g. `required`. If you want to know how to do that, please take a look at our [validation examples](../../fundamentals/systems/form/validate.md).

View file

@ -2,54 +2,55 @@
```js script
import { html } from '@mdjs/mdjs-preview';
import { Required } from '@lion/ui/form-core.js';
import { loadDefaultFeedbackMessages } from '@lion/ui/validate-messages.js';
import '@lion/ui/define/lion-select.js';
loadDefaultFeedbackMessages();
```
## Pre-select
You can preselect an option by setting the property modelValue.
```js preview-story
export const preSelect = () => html`
<lion-select name="favoriteColor" label="Favorite color" .modelValue=${'hotpink'}>
```html preview-story
<lion-select name="favoriteColor" label="Favorite color" .modelValue=${'hotpink'}>
<select slot="input">
<option selected hidden value>Please select</option>
<option value="red">Red</option>
<option value="hotpink">Hotpink</option>
<option value="teal">Teal</option>
</select>
</lion-select>
`;
</lion-select>
```
## Disabled
You can disable an option by adding the `disabled` attribute to an option.
```js preview-story
export const disabledOption = () => html`
<lion-select name="favoriteColor" label="Favorite color">
```html preview-story
<lion-select name="favoriteColor" label="Favorite color">
<select slot="input">
<option selected hidden value>Please select</option>
<option value="red">Red</option>
<option value="hotpink" disabled>Hotpink</option>
<option value="teal">Teal</option>
</select>
</lion-select>
`;
</lion-select>
```
Or by setting the `disabled` attribute on the entire `lion-select` field.
```js preview-story
export const disabledSelect = () => html`
<lion-select name="favoriteColor" label="Favorite color" disabled>
```html preview-story
<lion-select name="favoriteColor" label="Favorite color" disabled>
<select slot="input">
<option selected hidden value>Please select</option>
<option value="red">Red</option>
<option value="hotpink">Hotpink</option>
<option value="teal">Teal</option>
</select>
</lion-select>
`;
</lion-select>
```
## Validation
A validator can be used to make it e.g. `required`. If you want to know how to do that, please take a look at our [validation examples](../../fundamentals/systems/form/validate.md).

View file

@ -4,7 +4,7 @@
import { html } from '@mdjs/mdjs-preview';
import { LionInput } from '@lion/ui/input.js';
import '@lion/ui/define/lion-checkbox-group.js';
import '@lion/ui/define/lion-checkbox-group.js';
import '@lion/ui/define/lion-checkbox.js';
import '@lion/ui/define/lion-combobox.js';
import '@lion/ui/define/lion-fieldset.js';
import '@lion/ui/define/lion-form.js';
@ -21,7 +21,6 @@ import '@lion/ui/define/lion-listbox.js';
import '@lion/ui/define/lion-option.js';
import '@lion/ui/define/lion-options.js';
import '@lion/ui/define/lion-radio-group.js';
import '@lion/ui/define/lion-radio-group.js';
import '@lion/ui/define/lion-radio.js';
import '@lion/ui/define/lion-select.js';
import '@lion/ui/define/lion-select-rich.js';
@ -229,10 +228,14 @@ The required validator can be put onto every form field element and will make su
```js preview-story
export const requiredValidator = () => html`
<lion-input .validators=${[new Required()]} label="Required"></lion-input>
<lion-input .validators=${[new Required()]} label="Required" .fieldName="value"></lion-input>
`;
```
The default `Required` validation message is "Please, enter a(n) {fieldName}". In which the "fieldName" can be provided separately via the `fieldName` attribute, with a fallback to the label. See [override fieldname](#override-fieldname) for more information.
Specific required messages for a select and file-upload are created.
### String Validators
Useful on input elements it allows to define how many characters can be entered.

View file

@ -1,6 +1,7 @@
import { dedupeMixin } from '@open-wc/dedupe-mixin';
import { FormRegistrarMixin } from '../registration/FormRegistrarMixin.js';
import { InteractionStateMixin } from '../InteractionStateMixin.js';
import { ValidateMixin } from '../validate/ValidateMixin.js';
/**
* @typedef {import('../../types/choice-group/ChoiceGroupMixinTypes.js').ChoiceGroupMixin} ChoiceGroupMixin
@ -8,6 +9,7 @@ import { InteractionStateMixin } from '../InteractionStateMixin.js';
* @typedef {import('../../types/registration/FormRegistrarMixinTypes.js').ElementWithParentFormGroup} ElementWithParentFormGroup
* @typedef {import('../../types/form-group/FormGroupMixinTypes.js').FormControl} FormControl
* @typedef {import('../../types/choice-group/ChoiceInputMixinTypes.js').ChoiceInputHost} ChoiceInputHost
* @typedef {import('../validate/Validator.js').Validator} Validator
*/
/**
@ -22,7 +24,9 @@ import { InteractionStateMixin } from '../InteractionStateMixin.js';
*/
const ChoiceGroupMixinImplementation = superclass =>
// @ts-ignore https://github.com/microsoft/TypeScript/issues/36821#issuecomment-588375051
class ChoiceGroupMixin extends FormRegistrarMixin(InteractionStateMixin(superclass)) {
class ChoiceGroupMixin extends FormRegistrarMixin(
ValidateMixin(InteractionStateMixin(superclass)),
) {
/** @type {any} */
static get properties() {
return {
@ -123,6 +127,11 @@ const ChoiceGroupMixinImplementation = superclass =>
}
}
get operationMode() {
// @ts-ignore
return this._repropagationRole === 'choice-group' ? 'select' : 'enter';
}
constructor() {
super();

View file

@ -20,6 +20,7 @@ import { FormControlMixin } from '../FormControlMixin.js';
* @typedef {import('../../types/validate/ValidateMixinTypes.js').ValidateMixin} ValidateMixin
* @typedef {import('../../types/validate/ValidateMixinTypes.js').ValidationType} ValidationType
* @typedef {import('../../types/validate/ValidateMixinTypes.js').ValidateHost} ValidateHost
* @typedef {import('../../types/validate/ValidateMixinTypes.js').OperationMode} OperationMode
* @typedef {import('../../types/validate/index.js').ValidatorOutcome} ValidatorOutcome
* @typedef {typeof import('../../types/validate/ValidateMixinTypes.js').ValidateHost} ValidateHostConstructor
* @typedef {{validator:Validator; outcome:boolean|string}} ValidationResultEntry
@ -98,6 +99,15 @@ export const ValidateMixinImplementation = superclass =>
return ['error'];
}
/**
* Types of input interaction of the FormControl (for instance 'enter'|'select'|'upload')
* @overridable
* @type {OperationMode}
*/
get operationMode() {
return 'enter';
}
/**
* Adds "._feedbackNode" as described below
* @public

View file

@ -27,12 +27,15 @@ export class Validator extends EventTarget {
this.__param = param;
/** @type {ValidatorConfig} */
this.__config = config || {};
/** @type {ValidationType} */
this.type = config?.type || 'error'; // Default type supported by ValidateMixin
/**
* Default type supported by ValidateMixin
* @type {ValidationType}
*/
this.type = config?.type || 'error';
}
/**
* The name under which validation results get registered. For convience and predictability, this
* The name under which validation results get registered. For convenience and predictability, this
* should always be the same as the constructor name (since it will be obfuscated in js builds,
* we need to provide it separately).
* @type {ValidatorName}

View file

@ -115,6 +115,8 @@ export declare class FormControlHost {
set fieldName(arg: string);
get fieldName(): string;
get operationMode(): string;
/**
* Allows to add extra element references to aria-labelledby attribute.
*/

View file

@ -17,6 +17,8 @@ export type FeedbackMessage = {
export type ValidationType = 'error' | 'warning' | 'info' | 'success' | string;
export type OperationMode = 'enter' | 'select' | 'upload';
export declare class ValidateHost {
/**
* Used by Application Developers to add Validators to a FormControl.

View file

@ -2,7 +2,7 @@ import { FormControlHost } from '../../src/FormControlMixin.js';
import { ValidationType } from './ValidateMixinTypes.js';
/**
* The name under which validation results get registered. For convience and predictability, this
* The name under which validation results get registered. For convenience and predictability, this
* should always be the same as the constructor name (since it will be obfuscated in js builds,
* we need to provide it separately).
* @example
@ -34,7 +34,7 @@ export type ValidatorConfig = {
};
/**
* Output of the `execute` function that returns a validity outcome. When we need to shpw feedback,
* Output of the `execute` function that returns a validity outcome. When we need to show feedback,
* it should return true, otherwise false. So when an error\info|warning|success message
* needs to be shown, return true.
* It's also possible to return an enum. Let's say that a phone number can have multiple

View file

@ -215,6 +215,11 @@ export class LionInputFile extends ScopedElementsMixin(LocalizeMixin(LionField))
}
}
// eslint-disable-next-line class-methods-use-this
get operationMode() {
return 'upload';
}
get _acceptCriteria() {
/** @type {string[]} */
let allowedFileTypes = [];

View file

@ -57,6 +57,11 @@ class LionFieldWithSelect extends LionField {
* @customElement lion-select
*/
export class LionSelect extends LionFieldWithSelect {
// eslint-disable-next-line class-methods-use-this
get operationMode() {
return 'select';
}
connectedCallback() {
super.connectedCallback();
this._inputNode.addEventListener('change', this._proxyChangeEvent);

View file

@ -6,6 +6,11 @@
/** @type {Promise<void | object>} */
let pendingPromise;
/**
* @param {string} string
*/
const capitalize = string => (string && string[0].toUpperCase() + string.slice(1)) || '';
/**
* @param {{localize: LocalizeManager}} opts
*/
@ -105,7 +110,13 @@ export async function loadValidateNamespace({ localize }) {
export const getLocalizedMessage = async ({ data, localize }) => {
await loadValidateNamespace({ localize });
if (data) {
return localize.msg(`lion-validate:${data.type}.${data.name}`, data);
const operationMode =
data.formControl?.operationMode !== 'enter' && data.name === 'Required'
? capitalize(data.formControl?.operationMode)
: undefined;
const validatorName = operationMode ? `_${data.name}${operationMode}` : data.name;
return localize.msg(`lion-validate:${data.type}.${validatorName}`, data);
}
return '';
};

View file

@ -1,51 +0,0 @@
/* eslint-disable no-unused-vars, no-param-reassign */
import { expect } from '@open-wc/testing';
import { getLocalizeManager } from '@lion/ui/localize-no-side-effects.js';
import { Required } from '@lion/ui/form-core.js';
import { loadDefaultFeedbackMessagesNoSideEffects } from '@lion/ui/validate-messages-no-side-effects.js';
/**
* @typedef {import('../../form-core/src/validate/Validator.js').Validator} Validator
*/
/**
* @param {Validator} validatorEl
*/
function getProtectedMembers(validatorEl) {
// @ts-ignore protected members allowed in test
return {
// @ts-ignore
getMessage: (...args) => validatorEl._getMessage(...args),
};
}
describe('loadDefaultFeedbackMessagesNoSideEffects', () => {
const localizeManager = getLocalizeManager();
it('will set default feedback message for Required', async () => {
const el = new Required();
const { getMessage } = getProtectedMembers(el);
expect(await getMessage()).to.equals(
'Please configure an error message for "Required" by overriding "static async getMessage()"',
);
loadDefaultFeedbackMessagesNoSideEffects({ localize: localizeManager });
expect(await getMessage({ fieldName: 'password' })).to.equal('Please enter a(n) password.');
});
it('will await loading of translations when switching locale', async () => {
const el = new Required();
const { getMessage } = getProtectedMembers(el);
loadDefaultFeedbackMessagesNoSideEffects({ localize: localizeManager });
expect(await getMessage({ fieldName: 'password' })).to.equal('Please enter a(n) password.');
expect(await getMessage({ fieldName: 'user name' })).to.equal('Please enter a(n) user name.');
localizeManager.locale = 'de-DE';
expect(await getMessage({ fieldName: 'Password' })).to.equal(
'Password muss ausgefüllt werden.',
);
expect(await getMessage({ fieldName: 'Benutzername' })).to.equal(
'Benutzername muss ausgefüllt werden.',
);
});
});

View file

@ -0,0 +1,104 @@
/* eslint-disable no-unused-vars, no-param-reassign */
import { expect } from '@open-wc/testing';
import { getLocalizeManager } from '@lion/ui/localize-no-side-effects.js';
import { MinDate, MinLength, Required } from '@lion/ui/form-core.js';
import { loadDefaultFeedbackMessagesNoSideEffects } from '@lion/ui/validate-messages-no-side-effects.js';
/**
* @typedef {import('../../form-core/src/validate/Validator.js').Validator} Validator
*/
/**
* @param {Validator} validatorEl
*/
function getProtectedMembers(validatorEl) {
// @ts-ignore protected members allowed in test
return {
// @ts-ignore
getMessage: (...args) => validatorEl._getMessage(...args),
};
}
/**
* @typedef {import('@lion/ui/types/form-core.js').FormControlHost} FormControlHost
* @typedef {ArrayConstructor | ObjectConstructor | NumberConstructor | BooleanConstructor | StringConstructor | DateConstructor | 'iban' | 'email'} modelValueType
*/
describe('loadDefaultFeedbackMessagesNoSideEffects', () => {
const localizeManager = getLocalizeManager();
it('will set default feedback message for Required', async () => {
const el = new Required();
const { getMessage } = getProtectedMembers(el);
expect(await getMessage()).to.equals(
'Please configure an error message for "Required" by overriding "static async getMessage()"',
);
loadDefaultFeedbackMessagesNoSideEffects({ localize: localizeManager });
expect(await getMessage({ fieldName: 'password' })).to.equal('Please enter a(n) password.');
});
it('passes data to the feedback message', async () => {
const el = new MinLength(10);
const { getMessage } = getProtectedMembers(el);
loadDefaultFeedbackMessagesNoSideEffects({ localize: localizeManager });
expect(await getMessage({ fieldName: 'password' })).to.equal(
'Please enter a correct password (at least 10 characters).',
);
const el2 = new MinDate(new Date('2024-01-29'));
// @ts-ignore protected members allowed in test
expect(await el2._getMessage({ fieldName: 'date' })).to.equal(
'Please enter a(n) date after or equal to 29/01/2024.',
);
});
it('will set select specific feedback message for Required when operationMode is set', async () => {
const el = new Required();
loadDefaultFeedbackMessagesNoSideEffects({ localize: localizeManager });
const { getMessage } = getProtectedMembers(el);
const formControl = { operationMode: 'select' };
expect(await getMessage({ fieldName: 'password', formControl })).to.equal(
'Please select a(n) password.',
);
});
it('will set upload specific feedback message for Required when operationMode is set', async () => {
const el = new Required();
const { getMessage } = getProtectedMembers(el);
loadDefaultFeedbackMessagesNoSideEffects({ localize: localizeManager });
const formControl = { operationMode: 'upload' };
expect(await getMessage({ fieldName: 'password', formControl })).to.equal(
'Please upload a(n) password.',
);
});
it('will set ignore the operationMode for any other validator then Required, e.g. MinLength', async () => {
const el = new MinLength(10);
const { getMessage } = getProtectedMembers(el);
loadDefaultFeedbackMessagesNoSideEffects({ localize: localizeManager });
const formControl = { operationMode: 'select' };
expect(await getMessage({ fieldName: 'password', formControl })).to.equal(
'Please enter a correct password (at least 10 characters).',
);
});
it('will await loading of translations when switching locale', async () => {
const el = new Required();
const { getMessage } = getProtectedMembers(el);
loadDefaultFeedbackMessagesNoSideEffects({ localize: localizeManager });
expect(await getMessage({ fieldName: 'password' })).to.equal('Please enter a(n) password.');
expect(await getMessage({ fieldName: 'user name' })).to.equal('Please enter a(n) user name.');
localizeManager.locale = 'de-DE';
expect(await getMessage({ fieldName: 'Password' })).to.equal(
'Password muss ausgefüllt werden.',
);
expect(await getMessage({ fieldName: 'Benutzername' })).to.equal(
'Benutzername muss ausgefüllt werden.',
);
});
});

View file

@ -1,6 +1,8 @@
export default {
error: {
Required: 'Моля, въведете също {fieldName}.',
_RequiredUpload: 'Моля, качете {fieldName}.',
_RequiredSelect: 'Wählen Sie auch einen Wert für {fieldName} aus.',
EqualsLength: 'Моля, въведете правилно {fieldName} от точно {params} знака.',
MinLength: 'Моля, въведете правилен {fieldName} (поне {params}).',
MaxLength: 'Моля, въведете правилен {fieldName} (до {params} знака).',
@ -22,6 +24,8 @@ export default {
},
warning: {
Required: 'Моля, въведете също {fieldName}.',
_RequiredUpload: 'Моля, качете {fieldName}.',
_RequiredSelect: 'Wählen Sie auch einen Wert für {fieldName} aus.',
EqualsLength: 'Моля, въведете правилно {fieldName} от точно {params} знака.',
MinLength: 'Моля, въведете правилен {fieldName} (поне {params}).',
MaxLength: 'Моля, въведете правилен {fieldName} (до {params} знака).',

View file

@ -1,6 +1,8 @@
export default {
error: {
Required: 'Zadejte rovněž {fieldName}.',
_RequiredUpload: 'Nahrajte {fieldname}.',
_RequiredSelect: 'Vyberte rovněž {fieldname}.',
EqualsLength: 'Zadejte správné {fieldName}, přesně {params} znaků.',
MinLength: 'Zadejte správné {fieldName} (alespoň {params}).',
MaxLength: 'Zadejte správné {fieldName} (až {params} znaků).',
@ -21,6 +23,8 @@ export default {
},
warning: {
Required: 'Zadejte rovněž {fieldName}.',
_RequiredUpload: 'Nahrajte {fieldname}.',
_RequiredSelect: 'Vyberte rovněž {fieldname}.',
EqualsLength: 'Zadejte správné {fieldName}, přesně {params} znaků.',
MinLength: 'Zadejte správné {fieldName} (alespoň {params}).',
MaxLength: 'Zadejte správné {fieldName} (až {params} znaků).',

View file

@ -1,6 +1,8 @@
export default {
error: {
Required: '{fieldName} muss ausgefüllt werden.',
_RequiredUpload: 'Bitte laden Sie ein/e/n {fieldName} hoch.',
_RequiredSelect: 'Wählen Sie auch einen Wert für {fieldName} aus.',
EqualsLength: 'Geben Sie einen korrekten Wert für {fieldName} mit exakt {params} Zeichen ein.',
MinLength: 'Du musst mindestens {params} Zeichen eingeben.',
MaxLength: 'Du kannst maximal {params} Zeichen eingeben.',
@ -23,6 +25,8 @@ export default {
},
warning: {
Required: '{fieldName} sollte ausgefüllt werden.',
_RequiredUpload: 'Bitte laden Sie ein/e/n {fieldName} hoch.',
_RequiredSelect: 'Wählen Sie auch einen Wert für {fieldName} aus.',
EqualsLength: 'Geben Sie einen korrekten Wert für {fieldName} mit exakt {params} Zeichen ein.',
MinLength: 'Du solltest mindestens {params} Zeichen eingeben.',
MaxLength: 'Du kannst maximal {params} Zeichen eingeben.',

View file

@ -1,6 +1,8 @@
export default {
error: {
Required: 'Please enter a(n) {fieldName}.',
_RequiredUpload: 'Please upload a(n) {fieldName}.',
_RequiredSelect: 'Please select a(n) {fieldName}.',
EqualsLength: 'Please enter a correct {fieldName} of exactly {params} characters.',
MinLength: 'Please enter a correct {fieldName} (at least {params} characters).',
MaxLength: 'Please enter a correct {fieldName} (up to {params} characters).',
@ -22,8 +24,10 @@ export default {
},
warning: {
Required: 'Please enter a(n) {fieldName}.',
_RequiredUpload: 'Please upload a(n) {fieldName}.',
_RequiredSelect: 'Please select a(n) {fieldName}.',
EqualsLength: 'Please enter a correct {fieldName} of exactly {params} characters.',
MinLength: 'Please enter a correct {fieldName} (at least {params}).',
MinLength: 'Please enter a correct {fieldName} (at least {params} characters).',
MaxLength: 'Please enter a correct {fieldName} (up to {params} characters).',
MinMaxLength:
'Please enter a correct {fieldName} (between {params.min} and {params.max} characters).',

View file

@ -1,6 +1,8 @@
export default {
error: {
Required: 'Introduzca también un/a {fieldName}.',
_RequiredUpload: 'Cargue un {fieldName}.',
_RequiredSelect: 'Seleccione también un/a {fieldname}.',
EqualsLength: 'Introduzca un/a {fieldName} correcto/a de exactamente {params} caracteres.',
MinLength: 'Introduzca un/a {fieldName} correcto/a (de al menos {params} caracteres).',
MaxLength: 'Introduzca un/a {fieldName} correcto/a (hasta {params} caracteres).',
@ -23,6 +25,8 @@ export default {
},
warning: {
Required: 'Introduzca también un/a {fieldName}.',
_RequiredUpload: 'Cargue un {fieldName}.',
_RequiredSelect: 'Seleccione también un/a {fieldname}.',
EqualsLength: 'Introduzca un/a {fieldName} correcto/a de exactamente {params} caracteres.',
MinLength: 'Introduzca un/a {fieldName} correcto/a (de al menos {params} caracteres).',
MaxLength: 'Introduzca un/a {fieldName} correcto/a (hasta {params} caracteres).',

View file

@ -1,6 +1,8 @@
export default {
error: {
Required: 'Veuillez également indiquer un(e) {fieldName}.',
_RequiredUpload: 'Veuillez télécharger un(e) {fieldName}.',
_RequiredSelect: 'Veuillez également sélectionner un(e) {fieldName}.',
EqualsLength:
'Veuillez saisir un(e) {fieldName} correct(e) comptant précisément {params} caractères.',
MinLength: 'Veuillez indiquer un(e) {fieldName} correct(e) (au moins {params}).',
@ -24,6 +26,8 @@ export default {
},
warning: {
Required: 'Veuillez également indiquer un(e) {fieldName}.',
_RequiredUpload: 'Veuillez télécharger un(e) {fieldName}.',
_RequiredSelect: 'Veuillez également sélectionner un(e) {fieldName}.',
EqualsLength:
'Veuillez saisir un(e) {fieldName} correct(e) comptant précisément {params} caractères.',
MinLength: 'Veuillez indiquer un(e) {fieldName} correct(e) (au moins {params}).',

View file

@ -1,6 +1,8 @@
export default {
error: {
Required: 'Továbbá adjon meg egy {fieldName} értéket.',
_RequiredUpload: 'Töltsön fel egy {fieldName} elemet.',
_RequiredSelect: 'Továbbá válasszon ki egy {fieldname} értéket.',
EqualsLength: 'Adjon meg egy helyes {fieldName} értéket (pontosan {params} karakter).',
MinLength: 'Adjon meg egy helyes {fieldName} értéket (legalább {params}).',
MaxLength: 'Adjon meg egy helyes {fieldName} értéket (legfeljebb {params} karakter).',
@ -23,6 +25,8 @@ export default {
},
warning: {
Required: 'Továbbá adjon meg egy {fieldName} értéket.',
_RequiredUpload: 'Töltsön fel egy {fieldName} elemet.',
_RequiredSelect: 'Továbbá válasszon ki egy {fieldname} értéket.',
EqualsLength: 'Adjon meg egy helyes {fieldName} értéket (pontosan {params} karakter).',
MinLength: 'Adjon meg egy helyes {fieldName} értéket (legalább {params}).',
MaxLength: 'Adjon meg egy helyes {fieldName} értéket (legfeljebb {params} karakter).',

View file

@ -1,6 +1,8 @@
export default {
error: {
Required: 'Inserire anche un(a) {fieldName}.',
_RequiredUpload: 'Caricare un {fieldName}.',
_RequiredSelect: 'Selezionare anche un(a) {fieldname}.',
EqualsLength: 'Inserire un(a) {fieldName} corretto(a) di esattamente {params} caratteri.',
MinLength: 'Inserire un(a) {fieldName} corretto(a) (almeno {params}).',
MaxLength: 'Inserire un(a) {fieldName} corretto(a) (fino a {params} caratteri).',
@ -23,6 +25,8 @@ export default {
},
warning: {
Required: 'Inserire anche un(a) {fieldName}.',
_RequiredUpload: 'Caricare un {fieldName}.',
_RequiredSelect: 'Selezionare anche un(a) {fieldname}.',
EqualsLength: 'Inserire un(a) {fieldName} corretto(a) di esattamente {params} caratteri.',
MinLength: 'Inserire un(a) {fieldName} corretto(a) (almeno {params}).',
MaxLength: 'Inserire un(a) {fieldName} corretto(a) (fino a {params} caratteri).',

View file

@ -1,6 +1,8 @@
export default {
error: {
Required: 'Vul een {fieldName} in.',
_RequiredUpload: 'Upload een {fieldName}.',
_RequiredSelect: 'Selecteer een {fieldname}.',
EqualsLength: 'Vul een {fieldName} in gelijk aan {params} karakters.',
MinLength: 'Vul een {fieldName} in van minimaal {params} karakters.',
MaxLength: 'Vul een {fieldName} in van maximaal {params} karakters.',
@ -22,6 +24,8 @@ export default {
},
warning: {
Required: 'Vul een {fieldName} in.',
_RequiredUpload: 'Upload een {fieldName}.',
_RequiredSelect: 'Selecteer een {fieldname}.',
EqualsLength: 'Vul een {fieldName} in gelijk aan {params} karakters.',
MinLength: 'Vul een {fieldName} in van minimaal {params} karakters.',
MaxLength: 'Vul een {fieldName} in van maximaal {params} karakters.',

View file

@ -1,6 +1,8 @@
export default {
error: {
Required: 'Proszę również podać wartość {fieldName}.',
_RequiredUpload: 'Prześlij plik {fieldName}.',
_RequiredSelect: 'Wprowadź prawidłową wartość w polu {fieldname}.',
EqualsLength: 'Wprowadź prawidłową wartość w polu {fieldName} (maks. liczba znaków: {params}).',
MinLength: 'Proszę podać prawidłową wartość {fieldName} (co najmniej {params} znaków).',
MaxLength: 'Proszę podać prawidłową wartość {fieldName} (maks. {params} znaków).',
@ -22,6 +24,8 @@ export default {
},
warning: {
Required: 'Proszę również podać wartość {fieldName}.',
_RequiredUpload: 'Prześlij plik {fieldName}.',
_RequiredSelect: 'Wprowadź prawidłową wartość w polu {fieldname}.',
EqualsLength: 'Wprowadź prawidłową wartość w polu {fieldName} (maks. liczba znaków: {params}).',
MinLength: 'Proszę podać prawidłową wartość {fieldName} (co najmniej {params} znaków).',
MaxLength: 'Proszę podać prawidłową wartość {fieldName} (maks. {params} znaków).',

View file

@ -1,6 +1,8 @@
export default {
error: {
Required: 'Introduceți un/o {fieldName}.',
_RequiredUpload: 'Încărcaţi un {fieldName}.',
_RequiredSelect: 'Selectați un/o {fieldName}.',
EqualsLength: 'Introduceți un/o {fieldName} corect(ă) de exact {params} (de) caractere.',
MinLength: 'Introduceți un/o {fieldName} corect(ă) (cel puțin {params}).',
MaxLength: 'Introduceți un/o {fieldName} corect(ă) (până la {params} (de) caractere).',
@ -23,6 +25,8 @@ export default {
},
warning: {
Required: 'Introduceți un/o {fieldName}.',
_RequiredUpload: 'Încărcaţi un {fieldName}.',
_RequiredSelect: 'Selectați un/o {fieldName}.',
EqualsLength: 'Introduceți un/o {fieldName} corect(ă) de exact {params} (de) caractere.',
MinLength: 'Introduceți un/o {fieldName} corect(ă) (cel puțin {params}).',
MaxLength: 'Introduceți un/o {fieldName} corect(ă) (până la {params} (de) caractere).',

View file

@ -1,6 +1,8 @@
export default {
error: {
Required: 'Введите значение поля {fieldName}.',
_RequiredUpload: 'Загрузите {fieldName}.',
_RequiredSelect: 'Также выберите значение поля {fieldname}.',
EqualsLength: 'Введите корректное значение поля {fieldName} — ровно {params} симв.',
MinLength: 'Введите корректное значение поля {fieldName} (не менее {params}).',
MaxLength: 'Введите корректное значение поля {fieldName} (до {params} симв.).',
@ -23,6 +25,8 @@ export default {
},
warning: {
Required: 'Введите значение поля {fieldName}.',
_RequiredUpload: 'Загрузите {fieldName}.',
_RequiredSelect: 'Также выберите значение поля {fieldname}.',
EqualsLength: 'Введите корректное значение поля {fieldName} — ровно {paramsn} симв.',
MinLength: 'Введите корректное значение поля {fieldName} (не менее {params}).',
MaxLength: 'Введите корректное значение поля {fieldName} (до {params} симв.).',

View file

@ -1,6 +1,8 @@
export default {
error: {
Required: 'Uveďte aj {fieldName}.',
_RequiredUpload: 'Nahrajte pole {fieldName}.',
_RequiredSelect: 'Vyberte aj hodnotu v poli {fieldname}.',
EqualsLength: 'Do poľa {fieldName} zadajte platnú hodnotu v dĺžke presne {params} znaky/-ov.',
MinLength: 'Uveďte správne {fieldName} (najmenej {params}).',
MaxLength: 'Uveďte správne {fieldName} (maximálne {params} znakov).',
@ -21,6 +23,8 @@ export default {
},
warning: {
Required: 'Uveďte aj {fieldName}.',
_RequiredUpload: 'Nahrajte pole {fieldName}.',
_RequiredSelect: 'Vyberte aj hodnotu v poli {fieldname}.',
EqualsLength: 'Do poľa {fieldName} zadajte platnú hodnotu v dĺžke presne {params} znaky/-ov.',
MinLength: 'Uveďte správne {fieldName} (najmenej {params}).',
MaxLength: 'Uveďte správne {fieldName} (maximálne {params} znakov).',

View file

@ -1,6 +1,8 @@
export default {
error: {
Required: 'Уведіть також значення {fieldName}.',
_RequiredUpload: 'Завантажте {fieldName}.',
_RequiredSelect: 'Виберіть також {fieldname}.',
EqualsLength:
'Введіть правильне значення {fieldName}, кількість символів має бути точно {params}.',
MinLength: 'Уведіть правильне значення {fieldName} (щонайменше {params}).',
@ -24,6 +26,8 @@ export default {
},
warning: {
Required: 'Уведіть також значення {fieldName}.',
_RequiredUpload: 'Завантажте {fieldName}.',
_RequiredSelect: 'Виберіть також {fieldname}.',
EqualsLength:
'Введіть правильне значення {fieldName}, кількість символів має бути точно {params}.',
MinLength: 'Уведіть правильне значення {fieldName} (щонайменше {params}).',

View file

@ -1,6 +1,8 @@
export default {
error: {
Required: '請輸入{fieldName}。',
_RequiredUpload: '请上传 {fieldName}。',
_RequiredSelect: '请选择一个 {fieldName}。',
EqualsLength: '請輸入正確的{fieldName}長度為{params}個字符。',
MinLength: '請輸入正確的{fieldName}(長度至少{params}個字符)​​。',
MaxLength: '請輸入正確的{fieldName}(長度最多{params}個字符)​​。',
@ -21,6 +23,8 @@ export default {
},
warning: {
Required: '請輸入{fieldName}。',
_RequiredUpload: '请上传 {fieldName}。',
_RequiredSelect: '请选择一个 {fieldName}。',
EqualsLength: '請輸入正確的{fieldName}長度為{params}個字符。',
MinLength: '請輸入正確的{fieldName}(長度至少{params}個字符)​​。',
MaxLength: '請輸入正確的{fieldName}(長度最多{params}個字符)​​。',