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..73cb9ccc4
--- /dev/null
+++ b/addons/rose/addon/components/rose/form.stories.mdx
@@ -0,0 +1,126 @@
+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.
+
+```htmlbars
+
+
+
+
+ Choose an option
+ Value 1
+ Value 2
+ Value 3
+
+
+
+
+
+
+
+
+
+```
+
+
+ {{
+ 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'),
+ },
+ }}
+
diff --git a/addons/rose/addon/components/rose/form/checkbox.stories.mdx b/addons/rose/addon/components/rose/form/checkbox.stories.mdx
index 3c342c827..3a47e9f8c 100644
--- a/addons/rose/addon/components/rose/form/checkbox.stories.mdx
+++ b/addons/rose/addon/components/rose/form/checkbox.stories.mdx
@@ -16,7 +16,7 @@ Renders a form input checkbox.
@label="Yes?"
@checked={{false}}
@error={{false}}
- disabled={{false}}
+ @disabled={{false}}
/>
```
@@ -29,7 +29,7 @@ Renders a form input checkbox.
@label={{label}}
@checked={{checked}}
@error={{error}}
- disabled={{disabled}}
+ @disabled={{disabled}}
/>
`,
context: {
diff --git a/addons/rose/addon/components/rose/form/input.stories.mdx b/addons/rose/addon/components/rose/form/input.stories.mdx
index c62620de7..0e7465be9 100644
--- a/addons/rose/addon/components/rose/form/input.stories.mdx
+++ b/addons/rose/addon/components/rose/form/input.stories.mdx
@@ -16,7 +16,7 @@ Renders a simple form input.
@label="Email"
@helperText="Enter your email"
@error={{false}}
- disabled={{false}}
+ @disabled={{false}}
readonly={{false}}
/>
```
@@ -30,7 +30,7 @@ Renders a simple form input.
@label={{label}}
@helperText={{helperText}}
@error={{error}}
- disabled={{disabled}}
+ @disabled={{disabled}}
readonly={{read-only}}
/>
`,
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..ef99aa922 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,7 +9,12 @@ import { text } from '@storybook/addon-knobs';
Renders a form radiofield group.
```htmlbars
-
+
{{
template: hbs`
-
+
@@ -34,7 +34,7 @@ Renders a form select element.
@value={{value}}
@label={{label}}
@helperText={{helperText}}
- disabled={{disabled}}
+ @disabled={{disabled}}
@error={{error}}
@onChange={{fn onChange}}
as |select|
diff --git a/addons/rose/addon/components/rose/form/textarea.stories.mdx b/addons/rose/addon/components/rose/form/textarea.stories.mdx
index 8caffcdd8..17ae649f5 100644
--- a/addons/rose/addon/components/rose/form/textarea.stories.mdx
+++ b/addons/rose/addon/components/rose/form/textarea.stories.mdx
@@ -15,7 +15,7 @@ Renders a simple form textarea.
@label="Description"
@helperText="Enter a description"
@error={{false}}
- disabled={{false}}
+ @disabled={{false}}
readonly={{false}}
/>
```
@@ -28,7 +28,7 @@ Renders a simple form textarea.
@label={{label}}
@helperText={{helperText}}
@error={{error}}
- disabled={{disabled}}
+ @disabled={{disabled}}
readonly={{read-only}}
/>
`,
diff --git a/addons/rose/addon/templates/components/rose/form.hbs b/addons/rose/addon/templates/components/rose/form.hbs
new file mode 100644
index 000000000..6c74ccae4
--- /dev/null
+++ b/addons/rose/addon/templates/components/rose/form.hbs
@@ -0,0 +1,16 @@
+
diff --git a/addons/rose/addon/templates/components/rose/form/checkbox.hbs b/addons/rose/addon/templates/components/rose/form/checkbox.hbs
index ab2dec73b..b8d3f1dc5 100644
--- a/addons/rose/addon/templates/components/rose/form/checkbox.hbs
+++ b/addons/rose/addon/templates/components/rose/form/checkbox.hbs
@@ -4,6 +4,7 @@
...attributes
class="rose-form-checkbox-field"
id={{@id}}
+ disabled={{@disabled}}
@type="checkbox"
@checked={{if @checked true false}} />
diff --git a/addons/rose/addon/templates/components/rose/form/input.hbs b/addons/rose/addon/templates/components/rose/form/input.hbs
index fe8e86eed..9212c79df 100644
--- a/addons/rose/addon/templates/components/rose/form/input.hbs
+++ b/addons/rose/addon/templates/components/rose/form/input.hbs
@@ -12,6 +12,7 @@
...attributes
class="rose-form-input-field"
id={{@id}}
+ disabled={{@disabled}}
@type={{@type}}
@value={{@value}} />
diff --git a/addons/rose/addon/templates/components/rose/form/radio/group.hbs b/addons/rose/addon/templates/components/rose/form/radio/group.hbs
index 6aa52cf50..76cfea93b 100644
--- a/addons/rose/addon/templates/components/rose/form/radio/group.hbs
+++ b/addons/rose/addon/templates/components/rose/form/radio/group.hbs
@@ -1,3 +1,3 @@
{{yield (hash
- radio=(component 'rose/form/radio/radio' name=@name selectedValue=@selectedValue)
+ radio=(component 'rose/form/radio/radio' name=@name selectedValue=@selectedValue disabled=@disabled)
)}}
diff --git a/addons/rose/addon/templates/components/rose/form/radio/radio.hbs b/addons/rose/addon/templates/components/rose/form/radio/radio.hbs
index 088853d5b..ee54aa72c 100644
--- a/addons/rose/addon/templates/components/rose/form/radio/radio.hbs
+++ b/addons/rose/addon/templates/components/rose/form/radio/radio.hbs
@@ -5,6 +5,7 @@
@radioClass="rose-form-radio-field"
@radioId={{@id}}
type="radio"
+ disabled={{@disabled}}
@name={{@name}}
@value={{@value}}
@groupValue={{@selectedValue}}
diff --git a/addons/rose/addon/templates/components/rose/form/select.hbs b/addons/rose/addon/templates/components/rose/form/select.hbs
index f7466ba0f..586e002a1 100644
--- a/addons/rose/addon/templates/components/rose/form/select.hbs
+++ b/addons/rose/addon/templates/components/rose/form/select.hbs
@@ -12,6 +12,7 @@
...attributes
class="rose-form-select-field"
id={{@id}}
+ disabled={{@disabled}}
@value={{@value}}
@onChange={{@onChange}}
as |xs|
diff --git a/addons/rose/addon/templates/components/rose/form/textarea.hbs b/addons/rose/addon/templates/components/rose/form/textarea.hbs
index 94017089a..317ebeea3 100644
--- a/addons/rose/addon/templates/components/rose/form/textarea.hbs
+++ b/addons/rose/addon/templates/components/rose/form/textarea.hbs
@@ -10,8 +10,9 @@
{{yield}}
diff --git a/addons/rose/app/components/rose/form.js b/addons/rose/app/components/rose/form.js
new file mode 100644
index 000000000..69c59c497
--- /dev/null
+++ b/addons/rose/app/components/rose/form.js
@@ -0,0 +1 @@
+export { default } from 'rose/components/rose/form';
diff --git a/addons/rose/tests/dummy/app/controllers/index.js b/addons/rose/tests/dummy/app/controllers/index.js
index ff0929bb6..45faa7e5a 100644
--- a/addons/rose/tests/dummy/app/controllers/index.js
+++ b/addons/rose/tests/dummy/app/controllers/index.js
@@ -2,9 +2,11 @@ import Controller from '@ember/controller';
import { action } from '@ember/object';
export default class IndexController extends Controller {
+ color = 'green';
+
@action
actionHandler(/*value*/) {
// eslint-disable-next-line no-console
- //console.log(value);
+ //console.log('action handled');
}
}
diff --git a/addons/rose/tests/dummy/app/templates/index.hbs b/addons/rose/tests/dummy/app/templates/index.hbs
index 40586ca08..9d69a47a1 100644
--- a/addons/rose/tests/dummy/app/templates/index.hbs
+++ b/addons/rose/tests/dummy/app/templates/index.hbs
@@ -47,160 +47,132 @@ Dummy app index template
Form
-
- Choose an option
- Value 1
- Value 2
- Value 3
-
-
- Choose an option
-
+ Inputs
+
+
+
+
-Form Actions
-
+ Textareas
+
+
+
+
-
-
-
-
-
-
-
+ Selects
+
+ Choose an option
+ Value 1
+ Value 2
+ Value 3
+
+
+ Choose an option
+
-
+ Radio Group
+
+
+
+
+
-
+ Checkboxes
+
+
+
+
+
-
-
-
-
-Checkbox
-
-
-
-
-
-
-Radio field
-
-
-
-
-
-
-
-Radio field group
-
-
-
-
-
+
+
diff --git a/addons/rose/tests/integration/components/rose/form-test.js b/addons/rose/tests/integration/components/rose/form-test.js
new file mode 100644
index 000000000..2578e5538
--- /dev/null
+++ b/addons/rose/tests/integration/components/rose/form-test.js
@@ -0,0 +1,61 @@
+import { module, test } from 'qunit';
+import { setupRenderingTest } from 'ember-qunit';
+import { render, find, click } from '@ember/test-helpers';
+import hbs from 'htmlbars-inline-precompile';
+
+module('Integration | Component | rose/form', function (hooks) {
+ setupRenderingTest(hooks);
+
+ test('it renders and handles submit/cancel actions', async function (assert) {
+ assert.expect(3);
+ this.submit = () => assert.ok(true, 'submitted');
+ this.cancel = () => assert.ok(true, 'cancelled');
+ await render(hbs`
+
+
+
+ `);
+ assert.ok(find('.rose-form'));
+ await click('[type="submit"]');
+ await click('button:not([type="submit"])');
+ });
+
+ test('it can render contextual form components', async function (assert) {
+ assert.expect(5);
+ this.submit = () => {};
+ this.cancel = () => {};
+ this.select = () => {};
+ await render(hbs`
+
+
+
+
+
+
+
+
+
+ `);
+ assert.ok(find('[name="input-field"]'));
+ assert.ok(find('[name="textarea-field"]'));
+ assert.ok(find('[name="select-field"]'));
+ assert.ok(find('[name="checkbox-field"]'));
+ assert.ok(find('[name="radio-group-field"]'));
+ });
+});
diff --git a/addons/rose/tests/integration/components/rose/form/checkbox-test.js b/addons/rose/tests/integration/components/rose/form/checkbox-test.js
index e341dd0db..9c2d4e479 100644
--- a/addons/rose/tests/integration/components/rose/form/checkbox-test.js
+++ b/addons/rose/tests/integration/components/rose/form/checkbox-test.js
@@ -32,8 +32,8 @@ module('Integration | Component | rose/form/checkbox', function (hooks) {
assert.ok(await find('.error'));
});
- test('it is disabled when disabled={{true}}', async function (assert) {
- await render(hbs``);
+ test('it is disabled when @disabled={{true}}', async function (assert) {
+ await render(hbs``);
assert.equal(await find('input').disabled, true);
});
});
diff --git a/addons/rose/tests/integration/components/rose/form/input-test.js b/addons/rose/tests/integration/components/rose/form/input-test.js
index 85c78eeb7..7cc960c00 100644
--- a/addons/rose/tests/integration/components/rose/form/input-test.js
+++ b/addons/rose/tests/integration/components/rose/form/input-test.js
@@ -31,7 +31,7 @@ module('Integration | Component | rose/form/input', function (hooks) {
});
test('it supports disabled attribute', async function (assert) {
- await render(hbs``);
+ await render(hbs``);
assert.ok(await find('[disabled]'));
});
diff --git a/addons/rose/tests/integration/components/rose/form/select-test.js b/addons/rose/tests/integration/components/rose/form/select-test.js
index 2abd4b463..b91543758 100644
--- a/addons/rose/tests/integration/components/rose/form/select-test.js
+++ b/addons/rose/tests/integration/components/rose/form/select-test.js
@@ -48,7 +48,7 @@ module('Integration | Component | rose/form/select', function (hooks) {
await render(hbs`
Choose an option
diff --git a/addons/rose/tests/integration/components/rose/form/textarea-test.js b/addons/rose/tests/integration/components/rose/form/textarea-test.js
index cce85cc32..0e57aff8b 100644
--- a/addons/rose/tests/integration/components/rose/form/textarea-test.js
+++ b/addons/rose/tests/integration/components/rose/form/textarea-test.js
@@ -21,7 +21,7 @@ module('Integration | Component | rose/form/textarea', function (hooks) {
});
test('it supports disabled attribute', async function (assert) {
- await render(hbs``);
+ await render(hbs``);
assert.ok(await find('[disabled]'));
});