diff --git a/addons/rose/.eslintrc.js b/addons/rose/.eslintrc.js index 85a190092..b705ae52d 100644 --- a/addons/rose/.eslintrc.js +++ b/addons/rose/.eslintrc.js @@ -21,7 +21,8 @@ module.exports = { browser: true }, rules: { - 'ember/no-jquery': 'error' + 'ember/no-jquery': 'error', + 'ember/no-new-mixins': 0 }, overrides: [ // node files diff --git a/addons/rose/addon/components/rose/form.js b/addons/rose/addon/components/rose/form.js new file mode 100644 index 000000000..0805f0348 --- /dev/null +++ b/addons/rose/addon/components/rose/form.js @@ -0,0 +1,27 @@ +import Component from '@ember/component'; +import layout from '../../templates/components/rose/form'; +import { action } from '@ember/object'; + +/** + * A component for building accessible forms. Yields contextual fields + * and actions. + */ +export default Component.extend({ + layout, + tagName: '', + + // =actions + + /** + * Calls the passed `onSubmit` function and disabled the default form + * submit behavior. + * @param {Event} e + */ + @action + handleSubmit(e) { + e.preventDefault(); + e.stopPropagation(); + this.onSubmit(); + return false; + }, +}); diff --git a/addons/rose/addon/components/rose/form.stories.mdx b/addons/rose/addon/components/rose/form.stories.mdx new file mode 100644 index 000000000..f57f85da2 --- /dev/null +++ b/addons/rose/addon/components/rose/form.stories.mdx @@ -0,0 +1,123 @@ +import { Meta, Story, Preview } from '@storybook/addon-docs/blocks'; +import { hbs } from 'ember-cli-htmlbars'; +import { action } from '@storybook/addon-actions'; +import { text, boolean, select } from '@storybook/addon-knobs'; + + + +# Form + +A component for building accessible forms. Yields contextual fields +and actions. + + + {{ + template: hbs` + + + + + + Choose an option + Value 1 + Value 2 + Value 3 + + + + + + + + + + + `, + context: { + disabled: boolean('disabled', false), + submit: action('submit'), + cancel: action('cancel'), + selectChange: action('selectChange'), + }, + }} + + + +```htmlbars + + + + + + Choose an option + Value 1 + Value 2 + Value 3 + + + + + + + + + + +``` diff --git a/addons/rose/addon/components/rose/form/actions.js b/addons/rose/addon/components/rose/form/actions.js new file mode 100644 index 000000000..4bfcbea85 --- /dev/null +++ b/addons/rose/addon/components/rose/form/actions.js @@ -0,0 +1,24 @@ +import Component from '@ember/component'; +import layout from '../../../templates/components/rose/form/actions'; + +/** + * A set of two form action buttons for submit and cancel. + * To handle submit, place a submit handler on the parent form element. + * To handle cancel button click, pass in a function to `@cancel`. + * + * @example + * + */ +export default Component.extend({ + layout, + tagName: '', + + /** + * @type {boolean} + */ + showCancel: true, +}); diff --git a/addons/rose/addon/components/rose/form/actions.stories.mdx b/addons/rose/addon/components/rose/form/actions.stories.mdx new file mode 100644 index 000000000..7517bddb6 --- /dev/null +++ b/addons/rose/addon/components/rose/form/actions.stories.mdx @@ -0,0 +1,42 @@ +import { Meta, Story, Preview } from '@storybook/addon-docs/blocks'; +import { hbs } from 'ember-cli-htmlbars'; +import { action } from '@storybook/addon-actions'; +import { text, boolean } from '@storybook/addon-knobs'; + + + +# Form Actions + +A simple collection of buttons for performing common actions like submit/save +and cancel. Form actions should always be used in the context of a form element +where the form has a submit action handler. The submit button does not directly +support actions. The cancel button supports a cancel action. + +```html + +``` + + + {{ + template: hbs` + + `, + context: { + submitText: text('submitText', 'Save'), + cancelText: text('cancelText', 'Cancel'), + showCancel: boolean('showCancel', true), + disabled: boolean('disabled', false), + onCancel: action('cancel'), + }, + }} + diff --git a/addons/rose/addon/components/rose/form/checkbox.js b/addons/rose/addon/components/rose/form/checkbox.js index 5b94c0a1d..ad6ad3f38 100644 --- a/addons/rose/addon/components/rose/form/checkbox.js +++ b/addons/rose/addon/components/rose/form/checkbox.js @@ -1,21 +1,11 @@ import Component from '@ember/component'; import layout from '../../../templates/components/rose/form/checkbox'; +import ComponentAutoId from '../../../mixins/component-auto-id'; /** * A simple HTML `` element. - * - * @example - * */ -export default Component.extend({ +export default Component.extend(ComponentAutoId, { layout, - tagName: '', }); diff --git a/addons/rose/addon/components/rose/form/checkbox.stories.mdx b/addons/rose/addon/components/rose/form/checkbox.stories.mdx index 3c342c827..95200ce1c 100644 --- a/addons/rose/addon/components/rose/form/checkbox.stories.mdx +++ b/addons/rose/addon/components/rose/form/checkbox.stories.mdx @@ -11,30 +11,27 @@ Renders a form input checkbox. ```htmlbars ``` - {{ + {{ template: hbs` `, context: { label: text('text', 'Checkbox 🛎'), - id: text('id', 'checkbox-1'), name: text('name', 'checkbox-1'), checked: boolean('checked', false), error: boolean('error', false), @@ -42,3 +39,28 @@ Renders a form input checkbox. } }} + + + {{ + template: hbs` + + + An error occurred. + + + `, + context: { + label: text('text', 'Checkbox 🛎'), + name: text('name', 'checkbox-1'), + checked: boolean('checked', false), + disabled: boolean('disabled', false), + } + }} + diff --git a/addons/rose/addon/components/rose/form/errors.js b/addons/rose/addon/components/rose/form/errors.js new file mode 100644 index 000000000..bc13c3f56 --- /dev/null +++ b/addons/rose/addon/components/rose/form/errors.js @@ -0,0 +1,10 @@ +import Component from '@ember/component'; +import layout from '../../../templates/components/rose/form/errors'; + +/** + * A container for error messages. Yields the error message component. + */ +export default Component.extend({ + layout, + tagName: '', +}); diff --git a/addons/rose/addon/components/rose/form/errors.stories.mdx b/addons/rose/addon/components/rose/form/errors.stories.mdx new file mode 100644 index 000000000..27bcbb867 --- /dev/null +++ b/addons/rose/addon/components/rose/form/errors.stories.mdx @@ -0,0 +1,29 @@ +import { Meta, Story, Preview } from '@storybook/addon-docs/blocks'; +import { hbs } from 'ember-cli-htmlbars'; +import { action } from '@storybook/addon-actions'; +import { text, boolean } from '@storybook/addon-knobs'; + + + +# Form Errors + +Use this component to display one or more error messages. + +```html + + An error message goes here. + Another message goes here. + +``` + + + {{ + template: hbs` + + An error message goes here. + Another message goes here. + + `, + context: {}, + }} + diff --git a/addons/rose/addon/components/rose/form/errors/message.js b/addons/rose/addon/components/rose/form/errors/message.js new file mode 100644 index 000000000..0f59c6b06 --- /dev/null +++ b/addons/rose/addon/components/rose/form/errors/message.js @@ -0,0 +1,10 @@ +import Component from '@ember/component'; +import layout from '../../../../templates/components/rose/form/errors/message'; + +/** + * A simple, styled error message. Do not use directly. + */ +export default Component.extend({ + layout, + tagName: '', +}); diff --git a/addons/rose/addon/components/rose/form/errors/message.stories.mdx b/addons/rose/addon/components/rose/form/errors/message.stories.mdx new file mode 100644 index 000000000..161a5dd61 --- /dev/null +++ b/addons/rose/addon/components/rose/form/errors/message.stories.mdx @@ -0,0 +1,29 @@ +import { Meta, Story, Preview } from '@storybook/addon-docs/blocks'; +import { hbs } from 'ember-cli-htmlbars'; +import { action } from '@storybook/addon-actions'; +import { text, boolean } from '@storybook/addon-knobs'; + + + +# Form Error Message + +This component accepts block content describing a single error to the user. +Normally this component would not be used directly, but rather in the context +of the `Rose::Form::Errors` component. + +```html + + An error message goes here. + +``` + + + {{ + template: hbs` + + An error message goes here. + + `, + context: {}, + }} + diff --git a/addons/rose/addon/components/rose/form/input.js b/addons/rose/addon/components/rose/form/input.js index 005ed82e2..60ae3d0f1 100644 --- a/addons/rose/addon/components/rose/form/input.js +++ b/addons/rose/addon/components/rose/form/input.js @@ -1,22 +1,11 @@ import Component from '@ember/component'; import layout from '../../../templates/components/rose/form/input'; +import ComponentAutoId from '../../../mixins/component-auto-id'; /** * A simple HTML `` element. - * - * @example - * */ -export default Component.extend({ +export default Component.extend(ComponentAutoId, { layout, tagName: '', }); diff --git a/addons/rose/addon/components/rose/form/input.stories.mdx b/addons/rose/addon/components/rose/form/input.stories.mdx index c62620de7..48d38020a 100644 --- a/addons/rose/addon/components/rose/form/input.stories.mdx +++ b/addons/rose/addon/components/rose/form/input.stories.mdx @@ -16,21 +16,21 @@ Renders a simple form input. @label="Email" @helperText="Enter your email" @error={{false}} - disabled={{false}} + @disabled={{false}} readonly={{false}} /> ``` - {{ + {{ template: hbs` `, @@ -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), + } + }} + + + + {{ + template: hbs` + + + An error occurred. + + + `, + 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), } }} diff --git a/addons/rose/addon/components/rose/form/radio/group.js b/addons/rose/addon/components/rose/form/radio/group.js index a9508a084..80bba183e 100644 --- a/addons/rose/addon/components/rose/form/radio/group.js +++ b/addons/rose/addon/components/rose/form/radio/group.js @@ -3,29 +3,8 @@ import layout from '../../../../templates/components/rose/form/radio/group'; /** * A `` element. - * - * @example - * - * - * - * - * */ - export default Component.extend({ layout, - tagName: '', }); diff --git a/addons/rose/addon/components/rose/form/radio/group.stories.mdx b/addons/rose/addon/components/rose/form/radio/group.stories.mdx index af30e8246..ebdb50560 100644 --- a/addons/rose/addon/components/rose/form/radio/group.stories.mdx +++ b/addons/rose/addon/components/rose/form/radio/group.stories.mdx @@ -1,6 +1,6 @@ import { Meta, Story, Preview } from '@storybook/addon-docs/blocks'; import { hbs } from 'ember-cli-htmlbars'; -import { text } from '@storybook/addon-knobs'; +import { text, boolean } from '@storybook/addon-knobs'; @@ -9,19 +9,21 @@ import { text } from '@storybook/addon-knobs'; Renders a form radiofield group. ```htmlbars - + @@ -30,19 +32,21 @@ Renders a form radiofield group. {{ template: hbs` - + @@ -50,6 +54,7 @@ Renders a form radiofield group. `, context: { name: text('name', 'mustagree'), + disabled: boolean('disabled', false), selectedValue: text('selectedValue', 'disagree'), firstFieldLabel: text('first label', 'Agree'), firstFieldValue: text('first value', 'agree'), diff --git a/addons/rose/addon/components/rose/form/radio/radio.js b/addons/rose/addon/components/rose/form/radio/radio.js index f32a6835e..196e47951 100644 --- a/addons/rose/addon/components/rose/form/radio/radio.js +++ b/addons/rose/addon/components/rose/form/radio/radio.js @@ -1,22 +1,13 @@ import Component from '@ember/component'; import layout from '../../../../templates/components/rose/form/radio/radio'; +import ComponentAutoId from '../../../../mixins/component-auto-id'; /** * A `` element. * `value` and `selectedValue` must be equal to select * radiofield. - * - * @example - * */ -export default Component.extend({ +export default Component.extend(ComponentAutoId, { layout, tagName: '', }); diff --git a/addons/rose/addon/components/rose/form/radio/radio.stories.mdx b/addons/rose/addon/components/rose/form/radio/radio.stories.mdx index 79f2704d9..91d256e9a 100644 --- a/addons/rose/addon/components/rose/form/radio/radio.stories.mdx +++ b/addons/rose/addon/components/rose/form/radio/radio.stories.mdx @@ -10,7 +10,6 @@ Renders a form radiofield. ```htmlbars {{ template: hbs` `, context: { - id: text('id', 'radio-1'), label: text('text', 'Radiofield'), error: boolean('error', false), value: text('value', 'value and selectedValue must match to select radiofield'), diff --git a/addons/rose/addon/components/rose/form/select.js b/addons/rose/addon/components/rose/form/select.js index 3de2fd273..c71537542 100644 --- a/addons/rose/addon/components/rose/form/select.js +++ b/addons/rose/addon/components/rose/form/select.js @@ -1,27 +1,11 @@ import Component from '@ember/component'; import layout from '../../../templates/components/rose/form/select'; +import ComponentAutoId from '../../../mixins/component-auto-id'; /** * A `