Skip to content

Commit

Permalink
chore: make Autocomplete @noResultsText required
Browse files Browse the repository at this point in the history
  • Loading branch information
clintcs committed Jul 27, 2023
1 parent 40465de commit b59a575
Show file tree
Hide file tree
Showing 9 changed files with 113 additions and 34 deletions.
6 changes: 6 additions & 0 deletions .changeset/tough-planets-raise.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
'@crowdstrike/ember-toucan-core': minor
'@crowdstrike/ember-toucan-form': minor
---

Make Autocomplete `@noResultsText` required.
20 changes: 17 additions & 3 deletions docs/components/autocomplete-field/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ Provide a string to the `@label` component argument or content to the `:label` n
<Form::Fields::Autocomplete
@label='Label'
@error={{this.errorMessage}}
@noResultsText='No results'
@onChange={{this.onChange}}
as |autocomplete|
>
Expand All @@ -30,6 +31,7 @@ Provide a string to the `@label` component argument or content to the `:label` n
```hbs
<Form::Fields::Autocomplete
@error={{this.errorMessage}}
@noResultsText='No results'
@onChange={{this.onChange}}
placeholder='Colors'
as |autocomplete|
Expand All @@ -55,6 +57,7 @@ Provide a string to the `@hint` component argument or content to `:hint` named b
@label='Label'
@hint='Here is a hint'
@error={{this.errorMessage}}
@noResultsText='No results'
@onChange={{this.onChange}}
as |autocomplete|
>
Expand All @@ -70,6 +73,7 @@ Provide a string to the `@hint` component argument or content to `:hint` named b
<Form::Fields::Autocomplete
@label='Label'
@error={{this.errorMessage}}
@noResultsText='No results'
@onChange={{this.onChange}}
as |autocomplete|
>
Expand All @@ -96,6 +100,7 @@ Provide a string or array of strings to `@error` to render the text into the Err
<Form::Fields::Autocomplete
@label='Label'
@error={{(array 'Error 1' 'Error 2')}}
@noResultsText='No results'
@onChange={{this.onChange}}
as |autocomplete|
>
Expand All @@ -113,6 +118,7 @@ Provide an `@onChange` callback to be notified when the user's selections have c
```hbs
<Form::Fields::Autocomplete
@label='Label'
@noResultsText='No results'
@onChange={{this.onChange}}
as |autocomplete|
>
Expand Down Expand Up @@ -156,7 +162,7 @@ This test selector will be used as the value for the `data-root-field` attribute
The Field can be targeted via:

```hbs
<Form::Fields::Autocomplete @label='Label' @rootTestSelector='example' />
<Form::Fields::Autocomplete @label='Label' @noResultsText='No results' @rootTestSelector='example' />
```

```js
Expand All @@ -182,7 +188,7 @@ Target the error block via `data-error`.
### autocompleteField with `@label`

<div class='mb-4 w-64'>
<Form::Fields::Autocomplete @label='Label' placeholder='Colors' />
<Form::Fields::Autocomplete @noResultsText='No results' @label='Label' placeholder='Colors' />
</div>

### autocompleteField with `@label` and `@hint`
Expand All @@ -191,14 +197,15 @@ Target the error block via `data-error`.
<Form::Fields::Autocomplete
@label='Label'
@hint='With hint text'
@noResultsText='No results'
placeholder='Colors'
/>
</div>

### autocompleteField with `:label` and `:hint` blocks

<div class='mb-4 w-64'>
<Form::Fields::Autocomplete placeholder='Colors'>
<Form::Fields::Autocomplete @noResultsText='No results' placeholder='Colors'>
<:label>Label <svg class="inline w-4 h-4" xmlns="http://www.w3.org/2000/svg" width="24" height="24" stroke="currentColor" viewBox="0 0 24 24"><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"></path></svg></:label>
<:hint>Hint text <a href="https://www.crowdstrike.com/">link</a></:hint>
<:default as |autocomplete|>
Expand All @@ -215,6 +222,7 @@ Target the error block via `data-error`.
<Form::Fields::Autocomplete
@label='Label'
@error='With error text'
@noResultsText='No results'
placeholder='Colors'
/>
</div>
Expand All @@ -226,6 +234,7 @@ Target the error block via `data-error`.
@label='Label'
@hint='With hint text'
@error='With error text'
@noResultsText='No results'
placeholder='Colors'
/>
</div>
Expand All @@ -236,6 +245,7 @@ Target the error block via `data-error`.
<Form::Fields::Autocomplete
@label='Label'
@isDisabled={{true}}
@noResultsText='No results'
placeholder='Colors'
/>
</div>
Expand All @@ -248,6 +258,7 @@ Target the error block via `data-error`.
@isDisabled={{true}}
@selected="blue"
@options={{(array 'blue' 'red')}}
@noResultsText='No results'
placeholder='Colors'
as |autocomplete|>
<autocomplete.Option>
Expand All @@ -263,6 +274,7 @@ Target the error block via `data-error`.
@label='Label'
@options={{(array 'blue' 'red')}}
@error={{(array 'With error 1' 'With error 2' 'With error 3')}}
@noResultsText='No results'
placeholder='Colors'
as |autocomplete|>
<autocomplete.Option>
Expand All @@ -278,6 +290,7 @@ Target the error block via `data-error`.
@label='Label'
@hint='With hint text'
@isReadOnly={{true}}
@noResultsText='No results'
/>
</div>

Expand All @@ -289,6 +302,7 @@ Target the error block via `data-error`.
@isReadOnly={{true}}
@selected="blue"
@options={{(array 'blue' 'red')}}
@noResultsText='No results'
placeholder='Colors'
as |autocomplete|>
<autocomplete.Option>
Expand Down
20 changes: 13 additions & 7 deletions docs/components/autocomplete/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ A CSS class to add to this component's content container. Commonly used to speci

```hbs
<Form::Controls::Autocomplete
@noResultsText='No results'
@options={{this.options}}
@selected={{this.selected}}
as |autocomplete|
Expand All @@ -34,6 +35,7 @@ The currently selected option.

```hbs
<Form::Controls::Autocomplete
@noResultsText='No results'
@options={{this.options}}
@selected={{this.selected}}
as |autocomplete|
Expand All @@ -60,7 +62,8 @@ Called when the user makes a selection. It is called with the selected option (d

```hbs
<Form::Controls::Autocomplete
@onChange={{this.handleChange}}
@noResultsText='No results'
@onChange={{this.onChange}}
@options={{this.options}}
@selected={{this.selected}}
as |autocomplete|
Expand All @@ -82,7 +85,7 @@ export default class extends Component {
options = ['Blue', 'Red', 'Yellow'];

@action
handleChange(option) {
onChange(option) {
this.selected = option;
}
}
Expand All @@ -92,12 +95,15 @@ export default class extends Component {

Optional.

By default, when `@options` are an array of strings, the built-in filtering does simple `startsWith` filtering. When `@options` are an array of objects, the same filtering logic applies, but the key of each object is determined by the provided `@optionKey`. There may be cases where you need to write your own filtering logic completely that is more complex than the built-in `startsWith` filtering described. To do so, leverage `@onFilter` instead. This function should return an array of items that will then be used to populate the dropdown results.
By default, when `@options` are an array of strings, the built-in filtering does simple `String.prototype.startsWith` filtering.
There may be cases where you need to write your own filtering logic completely that is more complex than the built-in `String.prototype.startsWith` filtering described.
To do so, leverage `@onFilter` instead. This function should return an array of items that will then be used to populate the dropdown results.

```hbs
<Form::Controls::Autocomplete
@onFilter={{this.handleFilter}}
@onChange={{this.handleChange}}
@noResultsText='No results'
@onFilter={{this.onFilter}}
@onChange={{this.onChange}}
@options={{this.options}}
@selected={{this.selected}}
as |autocomplete|
Expand Down Expand Up @@ -148,12 +154,12 @@ export default class extends Component {
];

@action
handleChange(option) {
onChange(option) {
this.selected = option;
}

@action
handleFilter(value) {
onFilter(value) {
return this.options.filter((option) => option === value);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ export interface ToucanFormAutocompleteControlComponentSignature {
/**
* A string to display when there are no results after filtering.
*/
noResultsText?: string;
noResultsText: string;

/**
* Called when the user makes a selection.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ export interface ToucanFormAutocompleteFieldComponentSignature {
/**
* A string to display when there are no results after filtering.
*/
noResultsText?: string;
noResultsText: string;

/**
* The function called when a new selection is made.
Expand Down
47 changes: 38 additions & 9 deletions test-app/tests/integration/components/autocomplete-field-test.gts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ module('Integration | Component | Fields | Autocomplete', function (hooks) {

test('it renders', async function (assert) {
await render(<template>
<Autocomplete @label="Label" data-autocomplete />
<Autocomplete @noResultsText="No results" @label="Label" data-autocomplete />
</template>);

assert.dom('[data-label]').hasText('Label');
Expand All @@ -35,7 +35,12 @@ module('Integration | Component | Fields | Autocomplete', function (hooks) {

test('it renders with a hint', async function (assert) {
await render(<template>
<Autocomplete @label="Label" @hint="Hint text" data-autocomplete />
<Autocomplete
@noResultsText="No results"
@label="Label"
@hint="Hint text"
data-autocomplete
/>
</template>);

let hint = find('[data-hint]');
Expand All @@ -58,7 +63,7 @@ module('Integration | Component | Fields | Autocomplete', function (hooks) {

test('it renders with a hint and label block', async function (assert) {
await render(<template>
<Autocomplete data-autocomplete>
<Autocomplete @noResultsText="No results" data-autocomplete>
<:label><span data-label>label block content</span></:label>
<:hint><span data-hint>hint block content</span></:hint>
</Autocomplete>
Expand All @@ -70,7 +75,12 @@ module('Integration | Component | Fields | Autocomplete', function (hooks) {

test('it renders with an error', async function (assert) {
await render(<template>
<Autocomplete @label="Label" @error="Error text" data-autocomplete />
<Autocomplete
@label="Label"
@error="Error text"
@noResultsText="No results"
data-autocomplete
/>
</template>);

let error = find('[data-error]');
Expand Down Expand Up @@ -107,6 +117,7 @@ module('Integration | Component | Fields | Autocomplete', function (hooks) {
@label="Label"
@error="Error text"
@hint="Hint text"
@noResultsText="No results"
data-autocomplete
/>
</template>);
Expand All @@ -126,7 +137,12 @@ module('Integration | Component | Fields | Autocomplete', function (hooks) {

test('it disables the input using `@isDisabled` and renders a lock icon', async function (assert) {
await render(<template>
<Autocomplete @label="Label" @isDisabled={{true}} data-autocomplete />
<Autocomplete
@label="Label"
@isDisabled={{true}}
@noResultsText="No results"
data-autocomplete
/>
</template>);

assert.dom('[data-autocomplete]').isDisabled();
Expand All @@ -137,7 +153,12 @@ module('Integration | Component | Fields | Autocomplete', function (hooks) {

test('it sets readonly on the input using `@isReadOnly` and renders a lock icon', async function (assert) {
await render(<template>
<Autocomplete @label="Label" @isReadOnly={{true}} data-autocomplete />
<Autocomplete
@label="Label"
@isReadOnly={{true}}
@noResultsText="No results"
data-autocomplete
/>
</template>);

assert.dom('[data-autocomplete]').hasAttribute('readonly');
Expand All @@ -149,6 +170,7 @@ module('Integration | Component | Fields | Autocomplete', function (hooks) {
await render(<template>
<Autocomplete
@label="Label"
@noResultsText="No results"
placeholder="Placeholder text"
data-autocomplete
/>
Expand All @@ -161,7 +183,12 @@ module('Integration | Component | Fields | Autocomplete', function (hooks) {

test('it sets the value attribute via `@selected`', async function (assert) {
await render(<template>
<Autocomplete @label="Label" @selected="blue" data-autocomplete />
<Autocomplete
@label="Label"
@noResultsText="No results"
@selected="blue"
data-autocomplete
/>
</template>);

assert.dom('[data-autocomplete]').hasValue('blue');
Expand All @@ -183,6 +210,7 @@ module('Integration | Component | Fields | Autocomplete', function (hooks) {
await render(<template>
<Autocomplete
@label="Label"
@noResultsText="No results"
@options={{options}}
@onChange={{handleChange}}
data-autocomplete
Expand All @@ -207,6 +235,7 @@ module('Integration | Component | Fields | Autocomplete', function (hooks) {
await render(<template>
<Autocomplete
@label="Label"
@noResultsText="No results"
@rootTestSelector="selector"
data-autocomplete
/>
Expand All @@ -227,7 +256,7 @@ module('Integration | Component | Fields | Autocomplete', function (hooks) {
);
});

await render(<template><Autocomplete /></template>);
await render(<template><Autocomplete @noResultsText="No results" /></template>);
});

test('it throws an assertion error if a `@label` and :label are provided', async function (assert) {
Expand All @@ -243,7 +272,7 @@ module('Integration | Component | Fields | Autocomplete', function (hooks) {
});

await render(<template>
<Autocomplete @label="Label">
<Autocomplete @label="Label" @noResultsText="No results">
<:label>Label</:label>
</Autocomplete>
</template>);
Expand Down
Loading

0 comments on commit b59a575

Please sign in to comment.