-
Notifications
You must be signed in to change notification settings - Fork 6
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
This PR introduces a Field component. It will enable us to build other form controls by providing styled form-elements.
- Loading branch information
Showing
18 changed files
with
495 additions
and
46 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
```hbs template | ||
<Form::Field as |field|> | ||
<field.Label for={{field.id}}>Label</field.Label> | ||
<field.Hint id={{field.hintId}}>Extra information about the field</field.Hint> | ||
<field.Control> | ||
<input | ||
class='border bg-basement text-titles-and-attributes p-1 rounded-sm' | ||
id={{field.id}} | ||
aria-invalid='true' | ||
aria-describedby='{{field.hintId}} {{field.errorId}}' | ||
...attributes | ||
/> | ||
</field.Control> | ||
<field.Error id={{field.errorId}}>Error message</field.Error> | ||
</Form::Field> | ||
``` | ||
|
||
```js component | ||
import Component from '@glimmer/component'; | ||
|
||
export default class extends Component {} | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
# Field | ||
|
||
Field is a component to aid in creating form components. It provides a label, hint sections for things like help text, a control block, and an error section for rendering errors. It allows users to provide custom controls with a consistent form-element shell and is not opinionated on what underlying control element is used. | ||
|
||
## Yielded Items | ||
|
||
- `id`: A unique ID to provide to the control element `id` attribute and the Label component `for` attribute. | ||
- `hintId`: A unique ID to provide to the control element `aria-describedby` attribute and the Hint component `id` attribute. | ||
- `errorId`: A unique ID to provide to the control element `aria-describedby` or `aria-errormessage` attribute and the Error component `id` attribute. | ||
- `Label`: Renders a `<label>` element. Form element label text is normally rendered here. | ||
- `Hint`: Renders a `<div>` element. Help text or supplemental information is normally rendered here. | ||
- `Control`: A control block where a form element is rendered, for example, an `<input>`, `<textarea>`, etc. | ||
- `Error`: Renders a `<div>` element. Error information is normally rendered here. | ||
|
||
## Accessibility | ||
|
||
The Field component does not handle accessibility automatically for the label, hint, and error sections of the component; however, it does provide identifiers to assist here. Each code example on this page also shows how to take advantage of these IDs. | ||
|
||
- [for](https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes/for) | ||
- [aria-describedby](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Attributes/aria-describedby) | ||
- [aria-errormessage](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Attributes/aria-errormessage) | ||
- [aria-invalid](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Attributes/aria-invalid) | ||
|
||
## Optionally Rendering Components | ||
|
||
The yielded components from Field can be optionally rendered by using the `{{#if}}` helper. The below example optionally renders the Hint and Error based on component arguments. | ||
|
||
```hbs | ||
<Form::Field as |field|> | ||
<field.Label for={{field.id}}>{{@label}}</field.Label> | ||
{{#if @helperText}} | ||
<field.Hint id={{field.hintId}}>{{@helperText}}</field.Hint> | ||
{{/if}} | ||
<field.Control> | ||
<input id={{field.id}} aria-describedby={{field.hintId}} aria-invalid={{if @error "true"}} aria-errormessage={{if @error field.errorId}}class='border-critical bg-blue' ...attributes /> | ||
</field.Control> | ||
{{#if @error}} | ||
<field.Error id={{field.errorId}}>{{@error}}</field.Error> | ||
{{/if}} | ||
</Form::Field> | ||
``` | ||
|
||
### Attributes and Modifiers | ||
|
||
Attributes are spread to each sub component of the Field via `...attributes`, so HTML attributes and Ember modifiers can be added. | ||
|
||
```hbs | ||
<Form::Field as |field|> | ||
<field.Label | ||
for={{field.id}} | ||
class='mt-3' | ||
data-test-label | ||
{{on 'hover' this.onLabelHover}} | ||
>First name</field.Label> | ||
{{! other components below ...}} | ||
</Form::Field> | ||
``` | ||
|
||
### Ordering of Components | ||
|
||
Ordering of the elements can be changed by adjusting the order of the children. For example, if it is preferred to put the hint block underneath the control. | ||
|
||
```hbs | ||
<Form::Field as |field|> | ||
<field.Label for={{field.id}}>First name</field.Label> | ||
<field.Control> | ||
<input id={{field.id}} aria-describedby={{field.hintId}} ...attributes /> | ||
</field.Control> | ||
<field.Hint id={{field.hintId}}>Hint text below the input</field.Hint> | ||
</Form::Field> | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
<div class="mt-1" ...attributes> | ||
{{yield}} | ||
</div> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
import templateOnlyComponent from '@ember/component/template-only'; | ||
|
||
export interface ToucanFormControlComponentSignature { | ||
Element: HTMLDivElement; | ||
Args: {}; | ||
Blocks: { | ||
default: []; | ||
}; | ||
} | ||
|
||
export default templateOnlyComponent<ToucanFormControlComponentSignature>(); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
<div class="type-xs-tight text-critical flex items-center mt-1" ...attributes> | ||
{{! Icon taken from Tony's open source icon set, this is temporary! }} | ||
<svg | ||
xmlns="http://www.w3.org/2000/svg" | ||
width="24" | ||
height="24" | ||
stroke="currentColor" | ||
viewBox="0 0 24 24" | ||
aria-hidden="true" | ||
class="w-3 h-3 mr-1" | ||
> | ||
<path | ||
d="M12 3a9 9 0 11-6.364 2.636A8.972 8.972 0 0112 3zm0 4.7v5.2m0 3.39v.01" | ||
fill="none" | ||
stroke-linecap="round" | ||
stroke-linejoin="round" | ||
stroke-width="2" | ||
/> | ||
</svg> | ||
|
||
{{yield}} | ||
</div> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
import templateOnlyComponent from '@ember/component/template-only'; | ||
|
||
export interface ToucanFormErrorComponentSignature { | ||
Element: HTMLDivElement; | ||
Args: {}; | ||
Blocks: { | ||
default: []; | ||
}; | ||
} | ||
|
||
export default templateOnlyComponent<ToucanFormErrorComponentSignature>(); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
<div class="type-xs-tight text-body-and-labels" ...attributes>{{yield}}</div> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
import templateOnlyComponent from '@ember/component/template-only'; | ||
|
||
export interface ToucanFormHintComponentSignature { | ||
Element: HTMLDivElement; | ||
Args: {}; | ||
Blocks: { | ||
default: []; | ||
}; | ||
} | ||
|
||
export default templateOnlyComponent<ToucanFormHintComponentSignature>(); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
<label class="type-md-tight text-body-and-labels block" ...attributes> | ||
{{yield}} | ||
</label> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
import templateOnlyComponent from '@ember/component/template-only'; | ||
|
||
export interface ToucanFormLabelComponentSignature { | ||
Element: HTMLLabelElement; | ||
Args: {}; | ||
Blocks: { | ||
default: []; | ||
}; | ||
} | ||
|
||
export default templateOnlyComponent<ToucanFormLabelComponentSignature>(); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
{{#let (unique-id) (unique-id) (unique-id) as |uniqueId hintId errorId|}} | ||
{{yield | ||
(hash | ||
Label=this.Label | ||
Hint=this.Hint | ||
Control=this.Control | ||
Error=this.Error | ||
id=uniqueId | ||
hintId=hintId | ||
errorId=errorId | ||
) | ||
}} | ||
{{/let}} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
import Component from '@glimmer/component'; | ||
|
||
import Control from './-private/control'; | ||
import Error from './-private/error'; | ||
import Hint from './-private/hint'; | ||
import Label from './-private/label'; | ||
|
||
interface ToucanFormFieldComponentSignature { | ||
Element: null; | ||
Args: {}; | ||
Blocks: { | ||
default: [ | ||
{ | ||
/** | ||
* ID to link the Label and underlying control element for screenreaders. | ||
* | ||
* - Provide this to the `id` attribute on the control element. | ||
* - Provide this to the `for` attribute on the Label component. | ||
*/ | ||
id: string; | ||
/** | ||
* A provided ID for element descriptors. Normally used to link the | ||
* hint section with the control so that it is read by screenreaders. | ||
* | ||
* - Provide this to the `id` attribute on the Hint component. | ||
* - Add this to the `aria-describedby` of the control element. | ||
*/ | ||
hintId: string; | ||
/** | ||
* A provided ID for element descriptors. Normally used to link the | ||
* error section with the control so that it is read by screenreaders. | ||
* | ||
* - Provide this to the `id` attribute on the Error component. | ||
* - Add this to the `aria-describedby` or `aria-errormessage` of the control element. | ||
*/ | ||
errorId: string; | ||
Label: typeof Label; | ||
Hint: typeof Hint; | ||
Control: typeof Control; | ||
Error: typeof Error; | ||
} | ||
]; | ||
}; | ||
} | ||
|
||
export default class ToucanFormFieldComponent extends Component<ToucanFormFieldComponentSignature> { | ||
Label = Label; | ||
Hint = Hint; | ||
Control = Control; | ||
Error = Error; | ||
} |
Oops, something went wrong.