Skip to content
This repository has been archived by the owner on Dec 30, 2022. It is now read-only.

Commit

Permalink
feat(SearchBox): forward class-names & slots (#553)
Browse files Browse the repository at this point in the history
* feat(SearchBox): forward class-names & slots

* chore: fix typo & update stories

* test(Searchbox): assert slots work
  • Loading branch information
Haroenv committed Oct 22, 2018
1 parent c645cc1 commit b2122dd
Show file tree
Hide file tree
Showing 5 changed files with 133 additions and 37 deletions.
7 changes: 5 additions & 2 deletions docs/src/components/SearchBox.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@ A search input with a clear and submit button.
Name | Type | Default | Description | Required
---|---|---|---|---
placeholder | String | `'Search here…'` | The input placeholder | no
submit-title | String | `'search'` | The submit button text | no
clear-title | String | `'clear'` | The clear button text | no
submit-title | String | `'search'` | The submit button's alternative text | no
reset-title | String | `'clear'` | The clear button's alternative text | no
autofocus | Boolean | `false` | Whether to automatically focus on the input when rendered | no
show-loading-indicator | Boolean | `false` | Show a spinner in the search box if a delay is passed and no results are returned yet | no
class-names | Object | | Override class names | no
Expand All @@ -35,6 +35,9 @@ class-names | Object | | Override class names | no
Name | Scope | Description
---|---|---
default | `{ currentRefinement: String, isSearchStalled: Boolean, refine: String => void }` | Slot to override the DOM output
loading-indicator | | Slot to override the loading indicator
reset-icon | | Slot to override the reset icon
submit-icon | | Slot to override the submit icon

## CSS classes

Expand Down
20 changes: 17 additions & 3 deletions src/components/SearchBox.vue
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,23 @@
:show-loading-indicator="showLoadingIndicator"
:should-show-loading-indicator="state.isSearchStalled"
:submit-title="submitTitle"
:clear-title="clearTitle"
:reset-title="resetTitle"
:class-names="classNames"
v-model="currentRefinement"
/>
>
<slot
name="loading-indicator"
slot="loading-indicator"
/>
<slot
name="submit-icon"
slot="submit-icon"
/>
<slot
name="reset-icon"
slot="reset-icon"
/>
</search-input>
</slot>
</div>
</template>
Expand Down Expand Up @@ -53,7 +67,7 @@ export default {
type: String,
default: 'Search',
},
clearTitle: {
resetTitle: {
type: String,
default: 'Clear',
},
Expand Down
62 changes: 33 additions & 29 deletions src/components/SearchInput.vue
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
@submit.prevent="onFormSubmit"
@reset.prevent="onFormReset"
>
<!-- :value/@input allows us to pass v-model to the component -->
<input
type="search"
autocorrect="off"
Expand All @@ -23,47 +24,50 @@
@input="$emit('input', $event.target.value)"
ref="input"
>
<!-- value/input allows us to pass v-model to the component -->
<button
type="submit"
:title="submitTitle"
:class="suit('submit')"
:hidden="showLoadingIndicator && shouldShowLoadingIndicator"
>
<svg
role="img"
xmlns="http://www.w3.org/2000/svg"
width="10"
height="10"
viewBox="0 0 40 40"
:class="suit('submitIcon')"
>
<path
d="M26.804 29.01c-2.832 2.34-6.465 3.746-10.426 3.746C7.333 32.756 0 25.424 0 16.378 0 7.333 7.333 0 16.378 0c9.046 0 16.378 7.333 16.378 16.378 0 3.96-1.406 7.594-3.746 10.426l10.534 10.534c.607.607.61 1.59-.004 2.202-.61.61-1.597.61-2.202.004L26.804 29.01zm-10.426.627c7.323 0 13.26-5.936 13.26-13.26 0-7.32-5.937-13.257-13.26-13.257C9.056 3.12 3.12 9.056 3.12 16.378c0 7.323 5.936 13.26 13.258 13.26z"
fillRule="evenodd"
/>
</svg>
<slot name="submit-icon">
<svg
role="img"
xmlns="http://www.w3.org/2000/svg"
width="10"
height="10"
viewBox="0 0 40 40"
:class="suit('submitIcon')"
>
<path
d="M26.804 29.01c-2.832 2.34-6.465 3.746-10.426 3.746C7.333 32.756 0 25.424 0 16.378 0 7.333 7.333 0 16.378 0c9.046 0 16.378 7.333 16.378 16.378 0 3.96-1.406 7.594-3.746 10.426l10.534 10.534c.607.607.61 1.59-.004 2.202-.61.61-1.597.61-2.202.004L26.804 29.01zm-10.426.627c7.323 0 13.26-5.936 13.26-13.26 0-7.32-5.937-13.257-13.26-13.257C9.056 3.12 3.12 9.056 3.12 16.378c0 7.323 5.936 13.26 13.258 13.26z"
fillRule="evenodd"
/>
</svg>
</slot>
</button>

<button
type="reset"
:title="clearTitle"
:title="resetTitle"
:class="suit('reset')"
:hidden="!value || (showLoadingIndicator && shouldShowLoadingIndicator)"
>
<svg
role="img"
xmlns="http://www.w3.org/2000/svg"
width="1em"
height="1em"
viewBox="0 0 20 20"
:class="suit('resetIcon')"
>
<path
d="M8.114 10L.944 2.83 0 1.885 1.886 0l.943.943L10 8.113l7.17-7.17.944-.943L20 1.886l-.943.943-7.17 7.17 7.17 7.17.943.944L18.114 20l-.943-.943-7.17-7.17-7.17 7.17-.944.943L0 18.114l.943-.943L8.113 10z"
fillRule="evenodd"
/>
</svg>
<slot name="reset-icon">
<svg
role="img"
xmlns="http://www.w3.org/2000/svg"
width="1em"
height="1em"
viewBox="0 0 20 20"
:class="suit('resetIcon')"
>
<path
d="M8.114 10L.944 2.83 0 1.885 1.886 0l.943.943L10 8.113l7.17-7.17.944-.943L20 1.886l-.943.943-7.17 7.17 7.17 7.17.943.944L18.114 20l-.943-.943-7.17-7.17-7.17 7.17-.944.943L0 18.114l.943-.943L8.113 10z"
fillRule="evenodd"
/>
</svg>
</slot>
</button>

<span
Expand Down Expand Up @@ -141,7 +145,7 @@ export default {
type: String,
default: 'Search',
},
clearTitle: {
resetTitle: {
type: String,
default: 'Clear',
},
Expand Down
64 changes: 62 additions & 2 deletions src/components/__tests__/SearchBox.js
Original file line number Diff line number Diff line change
Expand Up @@ -51,11 +51,11 @@ test('with submit title', () => {
);
});

test('with clear title', () => {
test('with reset title', () => {
__setState(defaultState);
const wrapper = mount(SearchBox, {
propsData: {
clearTitle: 'Clear Title',
resetTitle: 'Clear Title',
},
});

Expand Down Expand Up @@ -166,3 +166,63 @@ test('refine on empty string on form reset', () => {

expect(state.refine).toHaveBeenCalledWith('');
});

test('overriding slots', () => {
__setState({
...defaultState,
isSearchStalled: true,
});
const wrapper = mount(SearchBox, {
propsData: {
showLoadingIndicator: true,
},
slots: {
'submit-icon': '<span>SUBMIT</span>',
'reset-icon': '<span>RESET</span>',
'loading-indicator': '<span>LOADING...</span>',
},
});

expect(wrapper.find('.ais-SearchBox-submit').html()).toMatch(/SUBMIT/);
expect(wrapper.find('.ais-SearchBox-reset').html()).toMatch(/RESET/);
expect(wrapper.find('.ais-SearchBox-loadingIndicator').html()).toMatch(
/LOADING.../
);

expect(wrapper.find('.ais-SearchBox-submit').html()).toMatchInlineSnapshot(`
<button type="submit"
title="Search"
hidden="hidden"
class="ais-SearchBox-submit"
>
<span>
SUBMIT
</span>
</button>
`);
expect(wrapper.find('.ais-SearchBox-reset').html()).toMatchInlineSnapshot(`
<button type="reset"
title="Clear"
hidden="hidden"
class="ais-SearchBox-reset"
>
<span>
RESET
</span>
</button>
`);
expect(wrapper.find('.ais-SearchBox-loadingIndicator').html())
.toMatchInlineSnapshot(`
<span class="ais-SearchBox-loadingIndicator">
<span>
LOADING...
</span>
</span>
`);
});
17 changes: 16 additions & 1 deletion stories/SearchBox.stories.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ storiesOf('ais-search-box', module)
template: '<ais-search-box></ais-search-box>',
}))
.add('with loading indicator', () => ({
template: '<ais-search-box showLoadingIndicator></ais-search-box>',
template: '<ais-search-box show-loading-indicator></ais-search-box>',
}))
.add('with autofocus', () => ({
template: '<ais-search-box autofocus></ais-search-box>',
Expand All @@ -24,6 +24,21 @@ storiesOf('ais-search-box', module)
</ais-search-box>
`,
}))
.add('with custom rendering of icons', () => ({
template: `
<ais-search-box show-loading-indicator>
<template slot="reset-icon">
</template>
<template slot="submit-icon">
🔎
</template>
<template slot="loading-indicator">
🔄
</template>
</ais-search-box>
`,
}))
.add('with a Panel', () => ({
template: `
<ais-panel>
Expand Down

0 comments on commit b2122dd

Please sign in to comment.