chore: 🤖 add error messages support to fields, except radios
This commit is contained in:
27 files changed
+363
-121
No files matched your search
@@ -10,58 +10,8 @@ import { text, boolean, select } from '@storybook/addon-knobs';
|
||||
A component for building accessible forms. Yields contextual fields
|
||||
and actions.
|
||||
|
||||
```htmlbars
|
||||
<Rose::Form
|
||||
@onSubmit={{this.submit}}
|
||||
@cancel={{this.cancel}}
|
||||
@disabled={{false}}
|
||||
as |form|>
|
||||
<form.input
|
||||
@label="Label"
|
||||
@helperText="Helper text"
|
||||
@value="Text"
|
||||
/>
|
||||
<form.textarea
|
||||
@label="Label"
|
||||
@helperText="Helper text"
|
||||
@value="Text"
|
||||
/>
|
||||
<form.select
|
||||
@label="Label"
|
||||
@helperText="Helper text"
|
||||
@onChange={{fn this.actionHandler}}
|
||||
as |Field|
|
||||
>
|
||||
<Field as |select|>
|
||||
<select.option>Choose an option</select.option>
|
||||
<select.option @value="value-1">Value 1</select.option>
|
||||
<select.option @value="value-2">Value 2</select.option>
|
||||
<select.option @value="value-3">Value 3</select.option>
|
||||
</Field>
|
||||
</form.select>
|
||||
<form.radioGroup @name="color" @selectedValue="green" as |radioGroup|>
|
||||
<radioGroup.radio
|
||||
@label="Red"
|
||||
@value="red"
|
||||
/>
|
||||
<radioGroup.radio
|
||||
@label="Green"
|
||||
@value="green"
|
||||
/>
|
||||
<radioGroup.radio
|
||||
@label="Blue"
|
||||
@value="blue"
|
||||
/>
|
||||
</form.radioGroup>
|
||||
<form.checkbox
|
||||
@label="Label"
|
||||
/>
|
||||
<form.actions @submitText="Save" @cancelText="Cancel" @showCancel={{true}} />
|
||||
</Rose::Form>
|
||||
```
|
||||
|
||||
<Preview>
|
||||
<Story name="Form">{{
|
||||
<Story name="Form" height="35rem">{{
|
||||
template: hbs`
|
||||
<Rose::Form
|
||||
@onSubmit={{submit}}
|
||||
@@ -82,14 +32,14 @@ and actions.
|
||||
@label="Label"
|
||||
@helperText="Helper text"
|
||||
@onChange={{selectChange}}
|
||||
as |Field|
|
||||
as |field|
|
||||
>
|
||||
<Field as |select|>
|
||||
<field.field as |select|>
|
||||
<select.option>Choose an option</select.option>
|
||||
<select.option @value="value-1">Value 1</select.option>
|
||||
<select.option @value="value-2">Value 2</select.option>
|
||||
<select.option @value="value-3">Value 3</select.option>
|
||||
</Field>
|
||||
</field.field>
|
||||
</form.select>
|
||||
<form.radioGroup @name="color" @selectedValue="green" as |radioGroup|>
|
||||
<radioGroup.radio
|
||||
@@ -120,3 +70,54 @@ and actions.
|
||||
},
|
||||
}}</Story>
|
||||
</Preview>
|
||||
|
||||
|
||||
```htmlbars
|
||||
<Rose::Form
|
||||
@onSubmit={{this.submit}}
|
||||
@cancel={{this.cancel}}
|
||||
@disabled={{false}}
|
||||
as |form|>
|
||||
<form.input
|
||||
@label="Label"
|
||||
@helperText="Helper text"
|
||||
@value="Text"
|
||||
/>
|
||||
<form.textarea
|
||||
@label="Label"
|
||||
@helperText="Helper text"
|
||||
@value="Text"
|
||||
/>
|
||||
<form.select
|
||||
@label="Label"
|
||||
@helperText="Helper text"
|
||||
@onChange={{fn this.actionHandler}}
|
||||
as |field|
|
||||
>
|
||||
<field.field as |select|>
|
||||
<select.option>Choose an option</select.option>
|
||||
<select.option @value="value-1">Value 1</select.option>
|
||||
<select.option @value="value-2">Value 2</select.option>
|
||||
<select.option @value="value-3">Value 3</select.option>
|
||||
</field.field>
|
||||
</form.select>
|
||||
<form.radioGroup @name="color" @selectedValue="green" as |radioGroup|>
|
||||
<radioGroup.radio
|
||||
@label="Red"
|
||||
@value="red"
|
||||
/>
|
||||
<radioGroup.radio
|
||||
@label="Green"
|
||||
@value="green"
|
||||
/>
|
||||
<radioGroup.radio
|
||||
@label="Blue"
|
||||
@value="blue"
|
||||
/>
|
||||
</form.radioGroup>
|
||||
<form.checkbox
|
||||
@label="Label"
|
||||
/>
|
||||
<form.actions @submitText="Save" @cancelText="Cancel" @showCancel={{true}} />
|
||||
</Rose::Form>
|
||||
```
|
||||
@@ -20,7 +20,7 @@ Renders a form input checkbox.
|
||||
```
|
||||
|
||||
<Preview>
|
||||
<Story name="Basic" height="10rem">{{
|
||||
<Story name="Basic Checkbox" height="10rem">{{
|
||||
template: hbs`
|
||||
<Rose::Form::Checkbox
|
||||
name={{name}}
|
||||
@@ -39,3 +39,28 @@ Renders a form input checkbox.
|
||||
}
|
||||
}}</Story>
|
||||
</Preview>
|
||||
|
||||
<Preview>
|
||||
<Story name="Checkbox with errors" height="10rem">{{
|
||||
template: hbs`
|
||||
<Rose::Form::Checkbox
|
||||
name={{name}}
|
||||
@label={{label}}
|
||||
@checked={{checked}}
|
||||
@error={{true}}
|
||||
@disabled={{disabled}}
|
||||
as |field|
|
||||
>
|
||||
<field.errors as |errors|>
|
||||
<errors.message>An error occurred.</errors.message>
|
||||
</field.errors>
|
||||
</Rose::Form::Checkbox>
|
||||
`,
|
||||
context: {
|
||||
label: text('text', 'Checkbox 🛎'),
|
||||
name: text('name', 'checkbox-1'),
|
||||
checked: boolean('checked', false),
|
||||
disabled: boolean('disabled', false),
|
||||
}
|
||||
}}</Story>
|
||||
</Preview>
|
||||
@@ -6,5 +6,5 @@ import layout from '../../../templates/components/rose/form/errors';
|
||||
*/
|
||||
export default Component.extend({
|
||||
layout,
|
||||
tagName: ''
|
||||
tagName: '',
|
||||
});
|
||||
@@ -6,5 +6,5 @@ import layout from '../../../../templates/components/rose/form/errors/message';
|
||||
*/
|
||||
export default Component.extend({
|
||||
layout,
|
||||
tagName: ''
|
||||
tagName: '',
|
||||
});
|
||||
@@ -22,14 +22,14 @@ Renders a simple form input.
|
||||
```
|
||||
|
||||
<Preview>
|
||||
<Story name="Basic">{{
|
||||
<Story name="Basic Field">{{
|
||||
template: hbs`
|
||||
<Rose::Form::Input
|
||||
@type={{type}}
|
||||
@value={{value}}
|
||||
@label={{label}}
|
||||
@helperText={{helperText}}
|
||||
@error={{error}}
|
||||
@error={{false}}
|
||||
@disabled={{disabled}}
|
||||
readonly={{read-only}}
|
||||
/>
|
||||
@@ -50,7 +50,44 @@ Renders a simple form input.
|
||||
helperText: text('helperText', 'Helper text'),
|
||||
disabled: boolean('disabled', false),
|
||||
'read-only': boolean('readonly', false),
|
||||
error: boolean('error', false),
|
||||
}
|
||||
}}</Story>
|
||||
</Preview>
|
||||
|
||||
<Preview>
|
||||
<Story name="Field with Errors">{{
|
||||
template: hbs`
|
||||
<Rose::Form::Input
|
||||
@type={{type}}
|
||||
@value={{value}}
|
||||
@label={{label}}
|
||||
@helperText={{helperText}}
|
||||
@error={{true}}
|
||||
@disabled={{disabled}}
|
||||
readonly={{read-only}}
|
||||
as |field|
|
||||
>
|
||||
<field.errors as |errors|>
|
||||
<errors.message>An error occurred.</errors.message>
|
||||
</field.errors>
|
||||
</Rose::Form::Input>
|
||||
`,
|
||||
context: {
|
||||
type: select(
|
||||
'type',
|
||||
{
|
||||
text: 'text',
|
||||
email: 'email',
|
||||
number: 'number',
|
||||
password: 'password',
|
||||
},
|
||||
'text'
|
||||
),
|
||||
value: text('value', 'Value'),
|
||||
label: text('label', 'Label'),
|
||||
helperText: text('helperText', 'Helper text'),
|
||||
disabled: boolean('disabled', false),
|
||||
'read-only': boolean('readonly', false),
|
||||
}
|
||||
}}</Story>
|
||||
</Preview>
|
||||
@@ -17,14 +17,14 @@ Renders a form select element.
|
||||
@helperText="Set your desired color"
|
||||
@disabled={{false}}
|
||||
@error={{false}}
|
||||
as |Field|
|
||||
as |field|
|
||||
>
|
||||
<Field as |select|>
|
||||
<field.field as |select|>
|
||||
<select.option>Choose a color</select.option>
|
||||
<select.option @value="red">Red</select.option>
|
||||
<select.option @value="green">Green</select.option>
|
||||
<select.option @value="blue">Blue</select.option>
|
||||
</Field>
|
||||
</field.field>
|
||||
</Rose::Form::Select>
|
||||
```
|
||||
|
||||
@@ -37,16 +37,60 @@ Renders a form select element.
|
||||
@label={{label}}
|
||||
@helperText={{helperText}}
|
||||
@disabled={{disabled}}
|
||||
@error={{error}}
|
||||
@error={{false}}
|
||||
@onChange={{fn onChange}}
|
||||
as |Field|
|
||||
as |field|
|
||||
>
|
||||
<Field as |select|>
|
||||
<field.field as |select|>
|
||||
<select.option>Choose an option</select.option>
|
||||
<select.option @value="value-1">Value 1</select.option>
|
||||
<select.option @value="value-2">Value 2</select.option>
|
||||
<select.option @value="value-3">Value 3</select.option>
|
||||
</Field>
|
||||
</field.field>
|
||||
</Rose::Form::Select>
|
||||
`,
|
||||
context: {
|
||||
value: select(
|
||||
'value',
|
||||
{
|
||||
null: null,
|
||||
'value-1': 'value-1',
|
||||
'value-2': 'value-2',
|
||||
'value-3': 'value-3',
|
||||
},
|
||||
null
|
||||
),
|
||||
name: text('name', 'select-name'),
|
||||
label: text('label', 'Label'),
|
||||
helperText: text('helperText', 'Helper text'),
|
||||
disabled: boolean('disabled', false),
|
||||
onChange: action('changed'),
|
||||
}
|
||||
}}</Story>
|
||||
</Preview>
|
||||
|
||||
<Preview>
|
||||
<Story name="Select with Errors" height="10rem">{{
|
||||
template: hbs`
|
||||
<Rose::Form::Select
|
||||
@name={{name}}
|
||||
@value={{value}}
|
||||
@label={{label}}
|
||||
@helperText={{helperText}}
|
||||
@disabled={{disabled}}
|
||||
@error={{true}}
|
||||
@onChange={{fn onChange}}
|
||||
as |field|
|
||||
>
|
||||
<field.field as |select|>
|
||||
<select.option>Choose an option</select.option>
|
||||
<select.option @value="value-1">Value 1</select.option>
|
||||
<select.option @value="value-2">Value 2</select.option>
|
||||
<select.option @value="value-3">Value 3</select.option>
|
||||
</field.field>
|
||||
<field.errors as |errors|>
|
||||
<errors.message>An error occurred.</errors.message>
|
||||
</field.errors>
|
||||
</Rose::Form::Select>
|
||||
`,
|
||||
context: {
|
||||
@@ -64,7 +108,6 @@ Renders a form select element.
|
||||
label: text('label', 'Label'),
|
||||
helperText: text('helperText', 'Helper text'),
|
||||
disabled: boolean('disabled', false),
|
||||
error: boolean('error', false),
|
||||
onChange: action('changed'),
|
||||
}
|
||||
}}</Story>
|
||||
|
||||
@@ -21,13 +21,13 @@ Renders a simple form textarea.
|
||||
```
|
||||
|
||||
<Preview>
|
||||
<Story name="Basic" height="10rem">{{
|
||||
<Story name="Basic Textarea" height="10rem">{{
|
||||
template: hbs`
|
||||
<Rose::Form::Textarea
|
||||
@value={{value}}
|
||||
@label={{label}}
|
||||
@helperText={{helperText}}
|
||||
@error={{error}}
|
||||
@error={{false}}
|
||||
@disabled={{disabled}}
|
||||
readonly={{read-only}}
|
||||
/>
|
||||
@@ -38,7 +38,32 @@ Renders a simple form textarea.
|
||||
helperText: text('helperText', 'Helper text'),
|
||||
disabled: boolean('disabled', false),
|
||||
'read-only': boolean('readonly', false),
|
||||
error: boolean('error', false),
|
||||
}
|
||||
}}</Story>
|
||||
</Preview>
|
||||
|
||||
<Preview>
|
||||
<Story name="Textarea with Errors" height="10rem">{{
|
||||
template: hbs`
|
||||
<Rose::Form::Textarea
|
||||
@value={{value}}
|
||||
@label={{label}}
|
||||
@helperText={{helperText}}
|
||||
@error={{true}}
|
||||
@disabled={{disabled}}
|
||||
readonly={{read-only}}
|
||||
as |field|>
|
||||
<field.errors as |errors|>
|
||||
<errors.message>An error occurred.</errors.message>
|
||||
</field.errors>
|
||||
</Rose::Form::Textarea>
|
||||
`,
|
||||
context: {
|
||||
value: text('value', 'Value'),
|
||||
label: text('label', 'Label'),
|
||||
helperText: text('helperText', 'Helper text'),
|
||||
disabled: boolean('disabled', false),
|
||||
'read-only': boolean('readonly', false),
|
||||
}
|
||||
}}</Story>
|
||||
</Preview>
|
||||
@@ -6,6 +6,11 @@
|
||||
margin-bottom: sizing.rems(xs);
|
||||
color: var(--ui-gray);
|
||||
|
||||
.rose-form-errors {
|
||||
margin-top: sizing.rems(xs);
|
||||
margin-bottom: sizing.rems(xs);
|
||||
}
|
||||
|
||||
.rose-form-checkbox-label {
|
||||
// label styles
|
||||
@include type.type(s, semibold);
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
|
||||
.rose-form-input-field {
|
||||
@include type.type(m);
|
||||
margin-bottom: sizing.rems(xs);
|
||||
padding: sizing.rems(xs);
|
||||
color: var(--stark);
|
||||
background-color: var(--subtle);
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
appearance: none;
|
||||
vertical-align: middle;
|
||||
display: inline-block;
|
||||
margin-bottom: sizing.rems(xs);
|
||||
padding: sizing.rems(xs) sizing.rems(xxl) sizing.rems(xs) sizing.rems(xs);
|
||||
border: sizing.rems(xxxxs) solid var(--ui-gray-subtler-2);
|
||||
border-radius: sizing.rems(xxxs);
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
@use '../../../variables/sizing';
|
||||
|
||||
@import "message";
|
||||
@import 'message';
|
||||
|
||||
.rose-form-errors {
|
||||
margin-bottom: sizing.rems(l);
|
||||
|
||||
@@ -6,12 +6,15 @@
|
||||
id={{this.id}}
|
||||
disabled={{@disabled}}
|
||||
@type="checkbox"
|
||||
@checked={{if @checked true false}} />
|
||||
@checked={{if @checked true false}}
|
||||
aria-describedby="{{if @error (concat 'errors-' this.id)}}" />
|
||||
|
||||
<label class="rose-form-checkbox-label" for={{this.id}}>
|
||||
{{@label}}
|
||||
</label>
|
||||
|
||||
{{yield}}
|
||||
{{yield (hash
|
||||
errors=(component 'rose/form/errors' id=(concat 'errors-' this.id))
|
||||
)}}
|
||||
|
||||
</div>
|
||||
@@ -1,4 +1,4 @@
|
||||
<div class="rose-form-errors" ...attributes>
|
||||
<div class="rose-form-errors" id={{@id}} ...attributes>
|
||||
{{yield (hash
|
||||
message=(component 'rose/form/errors/message')
|
||||
)}}
|
||||
|
||||
@@ -19,8 +19,10 @@
|
||||
disabled={{@disabled}}
|
||||
@type={{@type}}
|
||||
@value={{@value}}
|
||||
aria-describedby="{{if @helperText (concat 'helper-text-' this.id)}}" />
|
||||
aria-describedby="{{if @helperText (concat 'helper-text-' this.id)}} {{if @error (concat 'errors-' this.id)}}" />
|
||||
|
||||
{{yield}}
|
||||
{{yield (hash
|
||||
errors=(component 'rose/form/errors' id=(concat 'errors-' this.id))
|
||||
)}}
|
||||
|
||||
</div>
|
||||
@@ -12,13 +12,17 @@
|
||||
</span>
|
||||
{{/if}}
|
||||
|
||||
{{yield (component 'rose/form/select/select'
|
||||
id=this.id
|
||||
name=@name
|
||||
disabled=@disabled
|
||||
value=@value
|
||||
onChange=@onChange
|
||||
helperText=@helperText
|
||||
{{yield (hash
|
||||
field=(component 'rose/form/select/select'
|
||||
id=this.id
|
||||
name=@name
|
||||
disabled=@disabled
|
||||
value=@value
|
||||
onChange=@onChange
|
||||
helperText=@helperText
|
||||
error=@error
|
||||
)
|
||||
errors=(component 'rose/form/errors' id=(concat 'errors-' this.id))
|
||||
)}}
|
||||
|
||||
</div>
|
||||
@@ -5,7 +5,7 @@
|
||||
disabled={{@disabled}}
|
||||
@value={{@value}}
|
||||
@onChange={{@onChange}}
|
||||
aria-describedby="{{if @helperText (concat 'helper-text-' this.id)}}"
|
||||
aria-describedby="{{if @helperText (concat 'helper-text-' this.id)}} {{if @error (concat 'errors-' this.id)}}"
|
||||
as |xs|
|
||||
>
|
||||
{{yield xs}}
|
||||
|
||||
@@ -18,8 +18,10 @@
|
||||
id={{this.id}}
|
||||
disabled={{@disabled}}
|
||||
@value={{@value}}
|
||||
aria-describedby="{{if @helperText (concat 'helper-text-' this.id)}}" />
|
||||
aria-describedby="{{if @helperText (concat 'helper-text-' this.id)}} {{if @error (concat 'errors-' this.id)}}" />
|
||||
|
||||
{{yield}}
|
||||
{{yield (hash
|
||||
errors=(component 'rose/form/errors' id=(concat 'errors-' this.id))
|
||||
)}}
|
||||
|
||||
</div>
|
||||
@@ -1 +1 @@
|
||||
export { default } from 'rose/components/rose/form/errors';
|
||||
export { default } from 'rose/components/rose/form/errors';
|
||||
@@ -1 +1 @@
|
||||
export { default } from 'rose/components/rose/form/errors/message';
|
||||
export { default } from 'rose/components/rose/form/errors/message';
|
||||
@@ -107,25 +107,25 @@ Dummy app index template
|
||||
@label="Label"
|
||||
@helperText="Helper text"
|
||||
@onChange={{fn this.actionHandler}}
|
||||
as |Field|
|
||||
as |field|
|
||||
>
|
||||
<Field as |select|>
|
||||
<field.field as |select|>
|
||||
<select.option>Choose an option</select.option>
|
||||
<select.option @value="value-1">Value 1</select.option>
|
||||
<select.option @value="value-2">Value 2</select.option>
|
||||
<select.option @value="value-3">Value 3</select.option>
|
||||
</Field>
|
||||
</field.field>
|
||||
</form.select>
|
||||
<form.select
|
||||
|
||||
@label="Label"
|
||||
@helperText="Helper text"
|
||||
@onChange={{fn this.actionHandler}}
|
||||
as |Field|
|
||||
as |field|
|
||||
>
|
||||
<Field as |select|>
|
||||
<field.field as |select|>
|
||||
<select.option>Choose an option</select.option>
|
||||
</Field>
|
||||
</field.field>
|
||||
</form.select>
|
||||
|
||||
|
||||
|
||||
@@ -45,9 +45,9 @@ module('Integration | Component | rose/form', function (hooks) {
|
||||
@label="Select"
|
||||
@name="select-field"
|
||||
@onChange={{this.select}}
|
||||
as |Field|
|
||||
as |field|
|
||||
>
|
||||
<Field />
|
||||
<field.field />
|
||||
</form.select>
|
||||
<form.checkbox @label="Checkbox" name="checkbox-field" />
|
||||
<form.radioGroup @name="radio-group-field" @selectedValue="green" as |radioGroup|>
|
||||
|
||||
@@ -12,6 +12,23 @@ module('Integration | Component | rose/form/checkbox', function (hooks) {
|
||||
assert.ok(await find('input'));
|
||||
});
|
||||
|
||||
test('it displays optional errors', async function (assert) {
|
||||
await render(hbs`
|
||||
<Rose::Form::Checkbox @error={{true}} as |field|>
|
||||
<field.errors as |errors|>
|
||||
<errors.message>An error occurred.</errors.message>
|
||||
</field.errors>
|
||||
</Rose::Form::Checkbox>
|
||||
`);
|
||||
const fieldEl = find('input');
|
||||
const id = fieldEl.id;
|
||||
const errorsId = `errors-${id}`;
|
||||
const errorMessageEl = find('.rose-form-errors');
|
||||
assert.equal(errorMessageEl.id, errorsId);
|
||||
assert.equal(errorMessageEl.textContent.trim(), 'An error occurred.');
|
||||
assert.equal(fieldEl.getAttribute('aria-describedby').trim(), errorsId);
|
||||
});
|
||||
|
||||
test('it is not checked by default', async function (assert) {
|
||||
await render(hbs`<Rose::Form::Checkbox />`);
|
||||
assert.equal(await find('input').checked, false);
|
||||
|
||||
@@ -3,10 +3,10 @@ import { setupRenderingTest } from 'ember-qunit';
|
||||
import { render, find } from '@ember/test-helpers';
|
||||
import hbs from 'htmlbars-inline-precompile';
|
||||
|
||||
module('Integration | Component | rose/form/errors', function(hooks) {
|
||||
module('Integration | Component | rose/form/errors', function (hooks) {
|
||||
setupRenderingTest(hooks);
|
||||
|
||||
test('it renders', async function(assert) {
|
||||
test('it renders', async function (assert) {
|
||||
assert.expect(3);
|
||||
await render(hbs`
|
||||
<Rose::Form::Errors as |errors|>
|
||||
@@ -15,7 +15,13 @@ module('Integration | Component | rose/form/errors', function(hooks) {
|
||||
<//Rose::Form::Errors>
|
||||
`);
|
||||
assert.ok(find('.rose-form-errors'));
|
||||
assert.equal(find('.rose-form-error-message:first-child').textContent.trim(), 'An error occurred.');
|
||||
assert.equal(find('.rose-form-error-message:last-child').textContent.trim(), 'Another error occurred.');
|
||||
assert.equal(
|
||||
find('.rose-form-error-message:first-child').textContent.trim(),
|
||||
'An error occurred.'
|
||||
);
|
||||
assert.equal(
|
||||
find('.rose-form-error-message:last-child').textContent.trim(),
|
||||
'Another error occurred.'
|
||||
);
|
||||
});
|
||||
});
|
||||
@@ -3,10 +3,10 @@ import { setupRenderingTest } from 'ember-qunit';
|
||||
import { render } from '@ember/test-helpers';
|
||||
import hbs from 'htmlbars-inline-precompile';
|
||||
|
||||
module('Integration | Component | rose/form/errors/message', function(hooks) {
|
||||
module('Integration | Component | rose/form/errors/message', function (hooks) {
|
||||
setupRenderingTest(hooks);
|
||||
|
||||
test('it renders', async function(assert) {
|
||||
test('it renders', async function (assert) {
|
||||
await render(hbs`
|
||||
<Rose::Form::Errors::Message>
|
||||
An error occurred.
|
||||
|
||||
@@ -20,7 +20,27 @@ module('Integration | Component | rose/form/input', function (hooks) {
|
||||
const helperTextEl = find('.rose-form-input-helper-text');
|
||||
assert.equal(helperTextEl.textContent.trim(), 'Help me');
|
||||
assert.equal(helperTextEl.id, helperId);
|
||||
assert.equal(fieldEl.getAttribute('aria-describedby'), helperId);
|
||||
assert.equal(fieldEl.getAttribute('aria-describedby').trim(), helperId);
|
||||
});
|
||||
|
||||
test('it displays optional errors', async function (assert) {
|
||||
await render(hbs`
|
||||
<Rose::Form::Input @error={{true}} as |field|>
|
||||
<field.errors as |errors|>
|
||||
<errors.message>An error occurred.</errors.message>
|
||||
</field.errors>
|
||||
</Rose::Form::Input>
|
||||
`);
|
||||
const fieldEl = find('input');
|
||||
const id = fieldEl.id;
|
||||
const errorsId = `errors-${id}`;
|
||||
const errorMessageEl = find('.rose-form-errors');
|
||||
assert.equal(errorMessageEl.id, errorsId);
|
||||
assert.equal(errorMessageEl.textContent.trim(), 'An error occurred.');
|
||||
assert.equal(
|
||||
fieldEl.getAttribute('aria-describedby').split(' ')[1],
|
||||
errorsId
|
||||
);
|
||||
});
|
||||
|
||||
test('it is type="text" by default', async function (assert) {
|
||||
|
||||
@@ -12,14 +12,14 @@ module('Integration | Component | rose/form/select', function (hooks) {
|
||||
<Rose::Form::Select
|
||||
@label="Label"
|
||||
@onChange={{fn this.onChange}}
|
||||
as |Field|
|
||||
as |field|
|
||||
>
|
||||
<Field as |select|>
|
||||
<field.field as |select|>
|
||||
<select.option>Choose an option</select.option>
|
||||
<select.option @value="value-1">Value 1</select.option>
|
||||
<select.option @value="value-2">Value 2</select.option>
|
||||
<select.option @value="value-3">Value 3</select.option>
|
||||
</Field>
|
||||
</field.field>
|
||||
</Rose::Form::Select>
|
||||
`);
|
||||
assert.equal(find('label').textContent.trim(), 'Label');
|
||||
@@ -34,11 +34,11 @@ module('Integration | Component | rose/form/select', function (hooks) {
|
||||
@label="Label"
|
||||
@helperText="Help me"
|
||||
@onChange={{fn this.onChange}}
|
||||
as |Field|
|
||||
as |field|
|
||||
>
|
||||
<Field as |select|>
|
||||
<field.field as |select|>
|
||||
<select.option>Choose an option</select.option>
|
||||
</Field>
|
||||
</field.field>
|
||||
</Rose::Form::Select>
|
||||
`);
|
||||
const fieldEl = find('select');
|
||||
@@ -47,7 +47,37 @@ module('Integration | Component | rose/form/select', function (hooks) {
|
||||
const helperTextEl = find('.rose-form-select-helper-text');
|
||||
assert.equal(helperTextEl.textContent.trim(), 'Help me');
|
||||
assert.equal(helperTextEl.id, helperId);
|
||||
assert.equal(fieldEl.getAttribute('aria-describedby'), helperId);
|
||||
assert.equal(fieldEl.getAttribute('aria-describedby').trim(), helperId);
|
||||
});
|
||||
|
||||
test('it displays optional errors', async function (assert) {
|
||||
this.onChange = () => {};
|
||||
await render(hbs`
|
||||
<Rose::Form::Select
|
||||
@label="Label"
|
||||
@helperText="Help me"
|
||||
@onChange={{fn this.onChange}}
|
||||
@error={{true}}
|
||||
as |field|
|
||||
>
|
||||
<field.field as |select|>
|
||||
<select.option>Choose an option</select.option>
|
||||
</field.field>
|
||||
<field.errors as |errors|>
|
||||
<errors.message>An error occurred.</errors.message>
|
||||
</field.errors>
|
||||
</Rose::Form::Select>
|
||||
`);
|
||||
const fieldEl = find('select');
|
||||
const id = fieldEl.id;
|
||||
const errorsId = `errors-${id}`;
|
||||
const errorMessageEl = find('.rose-form-errors');
|
||||
assert.equal(errorMessageEl.id, errorsId);
|
||||
assert.equal(errorMessageEl.textContent.trim(), 'An error occurred.');
|
||||
assert.equal(
|
||||
fieldEl.getAttribute('aria-describedby').split(' ')[1],
|
||||
errorsId
|
||||
);
|
||||
});
|
||||
|
||||
test('it supports disabled attribute', async function (assert) {
|
||||
@@ -56,11 +86,11 @@ module('Integration | Component | rose/form/select', function (hooks) {
|
||||
<Rose::Form::Select
|
||||
@onChange={{fn this.onChange}}
|
||||
@disabled={{true}}
|
||||
as |Field|
|
||||
as |field|
|
||||
>
|
||||
<Field as |select|>
|
||||
<field.field as |select|>
|
||||
<select.option>Choose an option</select.option>
|
||||
</Field>
|
||||
</field.field>
|
||||
</Rose::Form::Select>
|
||||
`);
|
||||
assert.ok(find('[disabled]'));
|
||||
@@ -73,12 +103,12 @@ module('Integration | Component | rose/form/select', function (hooks) {
|
||||
<Rose::Form::Select
|
||||
@onChange={{fn this.onChange}}
|
||||
@value={{value}}
|
||||
as |Field|
|
||||
as |field|
|
||||
>
|
||||
<Field as |select|>
|
||||
<field.field as |select|>
|
||||
<select.option @value="value-1">value-1</select.option>
|
||||
<select.option @value="value-2">value-2</select.option>
|
||||
</Field>
|
||||
</field.field>
|
||||
</Rose::Form::Select>
|
||||
`);
|
||||
assert.equal(find('select').value, 'value-1');
|
||||
@@ -104,12 +134,12 @@ module('Integration | Component | rose/form/select', function (hooks) {
|
||||
<Rose::Form::Select
|
||||
@name="my-select"
|
||||
@onChange={{fn this.onChange}}
|
||||
as |Field|
|
||||
as |field|
|
||||
>
|
||||
<Field as |select|>
|
||||
<field.field as |select|>
|
||||
<select.option>Choose an option</select.option>
|
||||
<select.option @value="value-1">value-1</select.option>
|
||||
</Field>
|
||||
</field.field>
|
||||
</Rose::Form::Select>
|
||||
`);
|
||||
await fillIn('[name="my-select"]', 'value-1');
|
||||
|
||||
@@ -20,7 +20,27 @@ module('Integration | Component | rose/form/textarea', function (hooks) {
|
||||
const helperTextEl = find('.rose-form-input-helper-text');
|
||||
assert.equal(helperTextEl.textContent.trim(), 'Help me');
|
||||
assert.equal(helperTextEl.id, helperId);
|
||||
assert.equal(fieldEl.getAttribute('aria-describedby'), helperId);
|
||||
assert.equal(fieldEl.getAttribute('aria-describedby').trim(), helperId);
|
||||
});
|
||||
|
||||
test('it displays optional errors', async function (assert) {
|
||||
await render(hbs`
|
||||
<Rose::Form::Textarea @error={{true}} as |field|>
|
||||
<field.errors as |errors|>
|
||||
<errors.message>An error occurred.</errors.message>
|
||||
</field.errors>
|
||||
</Rose::Form::Textarea>
|
||||
`);
|
||||
const fieldEl = find('textarea');
|
||||
const id = fieldEl.id;
|
||||
const errorsId = `errors-${id}`;
|
||||
const errorMessageEl = find('.rose-form-errors');
|
||||
assert.equal(errorMessageEl.id, errorsId);
|
||||
assert.equal(errorMessageEl.textContent.trim(), 'An error occurred.');
|
||||
assert.equal(
|
||||
fieldEl.getAttribute('aria-describedby').split(' ')[1],
|
||||
errorsId
|
||||
);
|
||||
});
|
||||
|
||||
test('it supports disabled attribute', async function (assert) {
|
||||
|
||||
Reference in new issue
Block a user