Skip to content

Commit

Permalink
fix: Add container to textarea to resolve style issues
Browse files Browse the repository at this point in the history
  • Loading branch information
ynotdraw committed Aug 14, 2023
1 parent a6ed2cc commit c18922f
Show file tree
Hide file tree
Showing 9 changed files with 71 additions and 46 deletions.
10 changes: 10 additions & 0 deletions .changeset/olive-buttons-kiss.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
---
'@crowdstrike/ember-toucan-core': minor
'@crowdstrike/ember-toucan-form': minor
---

Both `Textarea` and `Input` Controls are now full width by default.

The `Textarea` Control markup was adjusted to account for collision with the resize handle and focus/error shadows.

The `Input` Control now has small padding along the x-axis.
4 changes: 3 additions & 1 deletion docs/components/input/demo/base-demo.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
```hbs template
<Form::Controls::Input />
<div class='w-96'>
<Form::Controls::Input />
</div>
```

```js component
Expand Down
4 changes: 3 additions & 1 deletion docs/components/textarea/demo/base-demo.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
```hbs template
<Form::Controls::Textarea />
<div class='w-96'>
<Form::Controls::Textarea />
</div>
```

```js component
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ export default class ToucanFormControlsInputComponent extends Component<ToucanFo

<template>
<input
class="focus:outline-none block rounded-sm p-1 transition-shadow
class="focus:outline-none block rounded-sm py-1 transition-shadow w-full px-2
{{this.styles}}"
disabled={{@isDisabled}}
readonly={{@isReadOnly}}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,14 +44,14 @@ export default class ToucanFormTextareaControlComponent extends Component<Toucan
}

if (isReadOnly) {
return 'focus:shadow-focus-outline bg-surface-xl shadow-read-only-outline text-titles-and-attributes';
return 'focus-within:shadow-focus-outline bg-surface-xl shadow-read-only-outline text-titles-and-attributes';
}

if (hasError) {
return 'shadow-error-outline focus:shadow-error-focus-outline bg-overlay-1 text-titles-and-attributes';
return 'shadow-error-outline focus-within:shadow-error-focus-outline bg-overlay-1 text-titles-and-attributes';
}

return 'shadow-focusable-outline focus:shadow-focus-outline bg-overlay-1 text-titles-and-attributes';
return 'shadow-focusable-outline focus-within:shadow-focus-outline bg-overlay-1 text-titles-and-attributes';
}

@action
Expand All @@ -65,13 +65,22 @@ export default class ToucanFormTextareaControlComponent extends Component<Toucan
}

<template>
<textarea
class="min-h-6 focus:outline-none block h-20 rounded-sm p-1 transition-shadow
{{this.styles}}"
disabled={{@isDisabled}}
readonly={{@isReadOnly}}
...attributes
{{on "input" this.handleInput}}
>{{@value}}</textarea>
{{!
A styled container div is used here so that we can give some space for
the textarea resize handle and focus/error shadows. Otherwise, the
shadows / handle visually collides.
}}
<div
class="{{this.styles}} w-full py-1 px-2 rounded-sm transition-shadow"
data-container
>
<textarea
class="min-h-6 focus:outline-none block h-20 bg-transparent w-full"
disabled={{@isDisabled}}
readonly={{@isReadOnly}}
...attributes
{{on "input" this.handleInput}}
>{{@value}}</textarea>
</div>
</template>
}
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,6 @@ export default class ToucanFormInputFieldComponent extends Component<ToucanFormI
field.errorId
}}"
aria-invalid={{if @error "true"}}
class="w-full"
@isDisabled={{@isDisabled}}
@isReadOnly={{@isReadOnly}}
@value={{@value}}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,6 @@ export default class ToucanFormTextareaFieldComponent extends Component<ToucanFo
@hint
field.hintId
}}"
class="w-full"
id={{field.id}}
@isDisabled={{@isDisabled}}
@isReadOnly={{@isReadOnly}}
Expand Down
28 changes: 15 additions & 13 deletions test-app/tests/integration/components/textarea-field-test.gts
Original file line number Diff line number Diff line change
Expand Up @@ -19,17 +19,17 @@ module('Integration | Component | Fields | Textarea', function (hooks) {
assert
.dom('[data-hint]')
.doesNotExist(
'Expected hint block not to be displayed as a hint was not provided'
'Expected hint block not to be displayed as a hint was not provided',
);

assert.dom('[data-textarea]').hasTagName('textarea');
assert.dom('[data-textarea]').hasAttribute('id');
assert.dom('[data-textarea]').hasClass('text-titles-and-attributes');
assert.dom('[data-container]').hasClass('text-titles-and-attributes');

assert
.dom('[data-error]')
.doesNotExist(
'Expected hint block not to be displayed as an error was not provided'
'Expected hint block not to be displayed as an error was not provided',
);

assert.dom('[data-lock-icon]').doesNotExist();
Expand All @@ -54,7 +54,7 @@ module('Integration | Component | Fields | Textarea', function (hooks) {

assert.ok(
describedby.includes(hintId),
'Expected hintId to be included in the aria-describedby'
'Expected hintId to be included in the aria-describedby',
);
});

Expand Down Expand Up @@ -89,14 +89,16 @@ module('Integration | Component | Fields | Textarea', function (hooks) {

assert.ok(
describedby.includes(errorId),
'Expected errorId to be included in the aria-describedby'
'Expected errorId to be included in the aria-describedby',
);

assert.dom('[data-textarea]').hasAttribute('aria-invalid', 'true');

assert.dom('[data-textarea]').hasClass('shadow-error-outline');
assert.dom('[data-textarea]').hasClass('focus:shadow-error-focus-outline');
assert.dom('[data-textarea]').doesNotHaveClass('shadow-focusable-outline');
assert.dom('[data-container]').hasClass('shadow-error-outline');
assert
.dom('[data-container]')
.hasClass('focus-within:shadow-error-focus-outline');
assert.dom('[data-container]').doesNotHaveClass('shadow-focusable-outline');
});

test('it sets aria-describedby when both a hint and error are provided using the hint and errorIds', async function (assert) {
Expand Down Expand Up @@ -128,7 +130,7 @@ module('Integration | Component | Fields | Textarea', function (hooks) {
</template>);

assert.dom('[data-textarea]').isDisabled();
assert.dom('[data-textarea]').hasClass('text-disabled');
assert.dom('[data-container]').hasClass('text-disabled');

assert.dom('[data-lock-icon]').exists();

Expand Down Expand Up @@ -208,9 +210,9 @@ module('Integration | Component | Fields | Textarea', function (hooks) {
setupOnerror((e: Error) => {
assert.ok(
e.message.includes(
'Assertion Failed: You need either :label or @label'
'Assertion Failed: You need either :label or @label',
),
'Expected assertion error message'
'Expected assertion error message',
);
});

Expand All @@ -223,9 +225,9 @@ module('Integration | Component | Fields | Textarea', function (hooks) {
setupOnerror((e: Error) => {
assert.ok(
e.message.includes(
'Assertion Failed: You can have :label or @label, but not both'
'Assertion Failed: You can have :label or @label, but not both',
),
'Expected assertion error message'
'Expected assertion error message',
);
});

Expand Down
36 changes: 19 additions & 17 deletions test-app/tests/integration/components/textarea-test.gts
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,13 @@ module('Integration | Component | Textarea', function (hooks) {
</template>);

assert.dom('[data-textarea]').hasTagName('textarea');
assert.dom('[data-textarea]').hasClass('text-titles-and-attributes');
assert.dom('[data-textarea]').hasClass('shadow-focusable-outline');
assert.dom('[data-textarea]').doesNotHaveClass('text-disabled');
assert.dom('[data-textarea]').doesNotHaveClass('shadow-error-outline');
assert.dom('[data-container]').hasClass('text-titles-and-attributes');
assert.dom('[data-container]').hasClass('shadow-focusable-outline');
assert.dom('[data-container]').doesNotHaveClass('text-disabled');
assert.dom('[data-container]').doesNotHaveClass('shadow-error-outline');
assert
.dom('[data-textarea]')
.doesNotHaveClass('focus:shadow-error-focus-outline');
.dom('[data-container]')
.doesNotHaveClass('focus-within:shadow-error-focus-outline');
});

test('it disables the textarea using `@isDisabled`', async function (assert) {
Expand All @@ -33,9 +33,9 @@ module('Integration | Component | Textarea', function (hooks) {
</template>);

assert.dom('[data-textarea]').isDisabled();
assert.dom('[data-textarea]').hasClass('text-disabled');
assert.dom('[data-container]').hasClass('text-disabled');
assert
.dom('[data-textarea]')
.dom('[data-container]')
.doesNotHaveClass('text-titles-and-attributes');
});

Expand All @@ -48,12 +48,12 @@ module('Integration | Component | Textarea', function (hooks) {

assert.dom('[data-textarea]').hasAttribute('readonly');

assert.dom('[data-textarea]').hasClass('shadow-read-only-outline');
assert.dom('[data-textarea]').hasClass('bg-surface-xl');
assert.dom('[data-textarea]').hasNoClass('bg-overlay-1');
assert.dom('[data-textarea]').hasNoClass('text-disabled');
assert.dom('[data-textarea]').hasNoClass('shadow-error-outline');
assert.dom('[data-textarea]').hasNoClass('shadow-focusable-outline');
assert.dom('[data-container]').hasClass('shadow-read-only-outline');
assert.dom('[data-container]').hasClass('bg-surface-xl');
assert.dom('[data-container]').hasNoClass('bg-overlay-1');
assert.dom('[data-container]').hasNoClass('text-disabled');
assert.dom('[data-container]').hasNoClass('shadow-error-outline');
assert.dom('[data-container]').hasNoClass('shadow-focusable-outline');
});

test('it spreads attributes to the underlying textarea', async function (assert) {
Expand Down Expand Up @@ -108,8 +108,10 @@ module('Integration | Component | Textarea', function (hooks) {
<TextareaControl @hasError={{true}} data-textarea />
</template>);

assert.dom('[data-textarea]').hasClass('shadow-error-outline');
assert.dom('[data-textarea]').hasClass('focus:shadow-error-focus-outline');
assert.dom('[data-textarea]').doesNotHaveClass('shadow-focusable-outline');
assert.dom('[data-container]').hasClass('shadow-error-outline');
assert
.dom('[data-container]')
.hasClass('focus-within:shadow-error-focus-outline');
assert.dom('[data-container]').doesNotHaveClass('shadow-focusable-outline');
});
});

0 comments on commit c18922f

Please sign in to comment.