Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

upd(mox:text-area): add light mode for component #130

Merged
merged 2 commits into from
Jul 24, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/tame-crabs-cross.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"mx-ui-components": minor
---

upd(mox:text-area): add light mode for component
10 changes: 7 additions & 3 deletions addon/components/mox/text-area.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,13 @@
<textarea
id={{@id}}
type="text"
class="px-4 py-2 w-full bg-gray-800 text-white text-sm rounded block resize-none
disabled:bg-gray-700 disabled:text-gray-500
{{if this.isValid 'border-gray-500 focus:border-cyan-500 focus:ring-cyan-500' 'border-red-800 active:border-red-900 focus:border-red-900 focus:ring-red-900'}}"
class="resize-none px-4 py-2 w-full text-gray-800 dark:text-white text-sm rounded bg-white dark:bg-gray-800
read-only:text-gray-800 dark:read-only:text-white disabled:text-gray-600 dark:disabled:text-gray-500
disabled:bg-gray-200 read-only:bg-gray-50 disabled:border-gray-200 read-only:border-gray-400
dark:disabled:bg-gray-700 dark:read-only:bg-gray-700 dark:disabled:border-gray-700 dark:read-only:border-gray-700 disabled:cursor-not-allowed
read-only:focus:border-cyan-500 dark:read-only:focus:border-white dark:ready-only:focus:ring-white
{{if this.isValid 'border-gray-400 dark:border-gray-500 focus:border-cyan-500 focus:ring-cyan-500'
'border-red-500 dark:border-red-800 active:border-red-500 dark:active:border-red-900 focus:border-red-500 dark:focus:border-red-900 focus:ring-red-500 dark:focus:ring-red-900'}}"
value={{@value}}
placeholder={{@placeholder}}
{{on "input" @onInput}}
Expand Down
73 changes: 73 additions & 0 deletions stories/mox-text-area-light.stories.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
import { hbs } from 'ember-cli-htmlbars';

export default {
title: 'Mox Light/Mox::TextArea',
parameters: {
backgrounds: {
default: 'Mute',
values: [
{
name: 'White',
value: '#ffffff',
},
{
name: 'Mute',
value: '#F3F4F6',
},
],
},
},
};

const Template = (args) => ({
template: hbs`<Mox::TextArea
@value={{this.value}} @onInput={{this.inputAction}}
@placeholder={{this.placeholder}} @label={{this.label}}
disabled={{this.isDisabled}} @isRequired={{this.isRequired}}
@isValid={{this.isValid}} @error={{this.error}} />`,
context: args,
});

export const Default = Template.bind({});
Default.args = {
value: 'Moon',
placeholder: 'Name',
label: 'Name',
inputAction: () => {},
};

export const Disabled = Template.bind({});
Disabled.args = {
value: 'Sun',
isDisabled: true,
label: 'Name',
inputAction: () => {},
};

export const Placeholder = Template.bind({});
Placeholder.args = {
value: '',
placeholder: 'Name',
label: 'Name',
inputAction: () => {},
};

export const Required = Template.bind({});
Required.args = {
value: 'Neptune',
placeholder: 'Your Name',
label: 'Name',
isRequired: true,
inputAction: () => {},
};

export const Errors = Template.bind({});
Errors.args = {
value: '',
placeholder: 'e.g. Saturn',
label: 'Planet Name',
isRequired: true,
isValid: false,
error: 'You forgot to specify a planet',
inputAction: () => {},
};
7 changes: 5 additions & 2 deletions stories/mox-text-area.stories.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,14 @@ export default {
};

const Template = (args) => ({
template: hbs`<Mox::TextArea class="mb-2"
template: hbs`
<div class="dark">
<Mox::TextArea
@value={{this.value}} @onInput={{this.inputAction}}
@placeholder={{this.placeholder}} @label={{this.label}}
disabled={{this.isDisabled}} @isRequired={{this.isRequired}}
@isValid={{this.isValid}} @error={{this.error}} />`,
@isValid={{this.isValid}} @error={{this.error}} />
</div>`,
context: args,
});

Expand Down
217 changes: 158 additions & 59 deletions tests/integration/components/mox/text-area-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,35 +39,6 @@ module('Integration | Component | mox/text-area', function (hooks) {
assert.dom('[data-test-mox-text-area]').isDisabled();
});

test('it highlights the field if it is invalid', async function (assert) {
this.set('onInput', () => {});

await render(
hbs`<Mox::TextArea @onInput={{this.onInput}} @isValid={{false}} />`
);

assert.dom('[data-test-mox-text-area]').hasClass('border-red-800');
});

test('it allows to validate and invalidate the field after rendering', async function (assert) {
this.set('onInput', () => {});
this.set('isValid', null);

await render(
hbs`<Mox::TextArea @onInput={{this.onInput}} @isValid={{this.isValid}} />`
);

assert.dom('[data-test-mox-text-area]').doesNotHaveClass('border-red-800');

this.set('isValid', false);

assert.dom('[data-test-mox-text-area]').hasClass('border-red-800');

this.set('isValid', true);

assert.dom('[data-test-mox-text-area]').doesNotHaveClass('border-red-800');
});

test('it may display a validation error alongside the field', async function (assert) {
this.set('onInput', () => {});

Expand All @@ -80,37 +51,165 @@ module('Integration | Component | mox/text-area', function (hooks) {
.includesText(`Name can't be blank`);
});

test('the disabled input state is accessible (dark mode)', async function (assert) {
this.set('onInput', () => {});

await render(hbs`
<div class="dark bg-gray-900 p-4">
<Mox::TextArea @onInput={{this.onInput}} @label="Address" @id="address-field" disabled />
</div>`);
await a11yAudit();
assert.ok(true, 'no accessibility errors');
});

test('the disabled input state used together with an external label is accessible', async function (assert) {
this.set('onInput', () => {});

await render(hbs`
<div class="dark bg-gray-900 p-4">
<label for="address-field">Address</label>
<Mox::TextArea @onInput={{this.onInput}} id="address-field" disabled />
</div>
`);
await a11yAudit();
assert.ok(true, 'no accessibility errors');
module('dark mode', function () {
test('the disabled input state is accessible (dark mode)', async function (assert) {
this.set('onInput', () => {});

await render(hbs`
<div class="dark bg-gray-900 p-4">
<Mox::TextArea @onInput={{this.onInput}} @label="Address" @id="address-field" disabled />
</div>`);
await a11yAudit();
assert.ok(true, 'no accessibility errors');
});

test('the disabled input state used together with an external label is accessible', async function (assert) {
this.set('onInput', () => {});

await render(hbs`
<div class="dark bg-gray-900 p-4">
<label for="address-field">Address</label>
<Mox::TextArea @onInput={{this.onInput}} id="address-field" disabled />
</div>
`);
await a11yAudit();
assert.ok(true, 'no accessibility errors');
});

test('the invalid input state is accessible', async function (assert) {
this.set('onInput', () => {});

await render(
hbs`<div class="dark bg-gray-900 p-4"><Mox::TextArea @onInput={{this.onInput}} @label="Address" @id="address-field" @isValid={{false}} @error="Missing something?" /></div>`
);
await a11yAudit();
assert.ok(true, 'no accessibility errors');
});

test('it highlights the field if it is invalid', async function (assert) {
this.set('onInput', () => {});

await render(
hbs`<div class="dark bg-gray-900 p-4"><Mox::TextArea @onInput={{this.onInput}} @isValid={{false}} /></div>`
);

assert.dom('[data-test-mox-text-area]').hasClass('dark:border-red-800');
assert
.dom('[data-test-mox-text-area]')
.hasStyle({ borderColor: 'rgb(153, 27, 27)' });
});

test('it allows to validate and invalidate the field after rendering', async function (assert) {
this.set('onInput', () => {});
this.set('isValid', null);

await render(
hbs`<div class="dark bg-gray-900 p-4"><Mox::TextArea @onInput={{this.onInput}} @isValid={{this.isValid}} /></div>`
);

assert
.dom('[data-test-mox-text-area]')
.doesNotHaveClass('dark:border-red-800');
assert
.dom('[data-test-mox-text-area]')
.hasStyle({ borderColor: 'rgb(107, 114, 128)' });

this.set('isValid', false);

assert.dom('[data-test-mox-text-area]').hasClass('dark:border-red-800');
assert
.dom('[data-test-mox-text-area]')
.hasStyle({ borderColor: 'rgb(153, 27, 27)' });

this.set('isValid', true);

assert
.dom('[data-test-mox-text-area]')
.doesNotHaveClass('dark:border-red-800');
assert
.dom('[data-test-mox-text-area]')
.hasStyle({ borderColor: 'rgb(107, 114, 128)' });
});
});

test('the invalid input state is accessible', async function (assert) {
this.set('onInput', () => {});

await render(
hbs`<div class="dark bg-gray-900 p-4"><Mox::TextArea @onInput={{this.onInput}} @label="Address" @id="address-field" @isValid={{false}} @error="Missing something?" /></div>`
);
await a11yAudit();
assert.ok(true, 'no accessibility errors');
module('light mode', function () {
test('the disabled input state is accessible (light mode)', async function (assert) {
this.set('onInput', () => {});

await render(hbs`
<div class="bg-gray-50 p-4">
<Mox::TextArea @onInput={{this.onInput}} @label="Address" @id="address-field" disabled />
</div>`);
await a11yAudit();
assert.ok(true, 'no accessibility errors');
});

test('the disabled input state used together with an external label is accessible', async function (assert) {
this.set('onInput', () => {});

await render(hbs`
<div class="bg-gray-50 p-4">
<label for="address-field">Address</label>
<Mox::TextArea @onInput={{this.onInput}} id="address-field" disabled />
</div>
`);
await a11yAudit();
assert.ok(true, 'no accessibility errors');
});

test('the invalid input state is accessible', async function (assert) {
this.set('onInput', () => {});

await render(
hbs`<div class="bg-gray-50 p-4"><Mox::TextArea @onInput={{this.onInput}} @label="Address" @id="address-field" @isValid={{false}} @error="Missing something?" /></div>`
);
await a11yAudit();
assert.ok(true, 'no accessibility errors');
});

test('it highlights the field if it is invalid', async function (assert) {
this.set('onInput', () => {});

await render(
hbs`<div class="bg-gray-50 p-4"><Mox::TextArea @onInput={{this.onInput}} @isValid={{false}} /></div>`
);

assert.dom('[data-test-mox-text-area]').hasClass('border-red-500');
assert
.dom('[data-test-mox-text-area]')
.hasStyle({ borderColor: 'rgb(239, 68, 68)' });
});

test('it allows to validate and invalidate the field after rendering', async function (assert) {
this.set('onInput', () => {});
this.set('isValid', null);

await render(
hbs`<div class="bg-gray-50 p-4"><Mox::TextArea @onInput={{this.onInput}} @isValid={{this.isValid}} /></div>`
);

assert
.dom('[data-test-mox-text-area]')
.doesNotHaveClass('border-red-500');
assert
.dom('[data-test-mox-text-area]')
.hasStyle({ borderColor: 'rgb(156, 163, 175)' });

this.set('isValid', false);

assert.dom('[data-test-mox-text-area]').hasClass('border-red-500');
assert
.dom('[data-test-mox-text-area]')
.hasStyle({ borderColor: 'rgb(239, 68, 68)' });

this.set('isValid', true);

assert
.dom('[data-test-mox-text-area]')
.doesNotHaveClass('border-red-500');
assert
.dom('[data-test-mox-text-area]')
.hasStyle({ borderColor: 'rgb(156, 163, 175)' });
});
});
});
Loading