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

Commit b2122dd

Browse files
committed
feat(SearchBox): forward class-names & slots (#553)
* feat(SearchBox): forward class-names & slots * chore: fix typo & update stories * test(Searchbox): assert slots work
1 parent c645cc1 commit b2122dd

File tree

5 files changed

+133
-37
lines changed

5 files changed

+133
-37
lines changed

docs/src/components/SearchBox.md

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,8 @@ A search input with a clear and submit button.
2424
Name | Type | Default | Description | Required
2525
---|---|---|---|---
2626
placeholder | String | `'Search here…'` | The input placeholder | no
27-
submit-title | String | `'search'` | The submit button text | no
28-
clear-title | String | `'clear'` | The clear button text | no
27+
submit-title | String | `'search'` | The submit button's alternative text | no
28+
reset-title | String | `'clear'` | The clear button's alternative text | no
2929
autofocus | Boolean | `false` | Whether to automatically focus on the input when rendered | no
3030
show-loading-indicator | Boolean | `false` | Show a spinner in the search box if a delay is passed and no results are returned yet | no
3131
class-names | Object | | Override class names | no
@@ -35,6 +35,9 @@ class-names | Object | | Override class names | no
3535
Name | Scope | Description
3636
---|---|---
3737
default | `{ currentRefinement: String, isSearchStalled: Boolean, refine: String => void }` | Slot to override the DOM output
38+
loading-indicator | | Slot to override the loading indicator
39+
reset-icon | | Slot to override the reset icon
40+
submit-icon | | Slot to override the submit icon
3841

3942
## CSS classes
4043

src/components/SearchBox.vue

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,23 @@
1414
:show-loading-indicator="showLoadingIndicator"
1515
:should-show-loading-indicator="state.isSearchStalled"
1616
:submit-title="submitTitle"
17-
:clear-title="clearTitle"
17+
:reset-title="resetTitle"
18+
:class-names="classNames"
1819
v-model="currentRefinement"
19-
/>
20+
>
21+
<slot
22+
name="loading-indicator"
23+
slot="loading-indicator"
24+
/>
25+
<slot
26+
name="submit-icon"
27+
slot="submit-icon"
28+
/>
29+
<slot
30+
name="reset-icon"
31+
slot="reset-icon"
32+
/>
33+
</search-input>
2034
</slot>
2135
</div>
2236
</template>
@@ -53,7 +67,7 @@ export default {
5367
type: String,
5468
default: 'Search',
5569
},
56-
clearTitle: {
70+
resetTitle: {
5771
type: String,
5872
default: 'Clear',
5973
},

src/components/SearchInput.vue

Lines changed: 33 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
@submit.prevent="onFormSubmit"
88
@reset.prevent="onFormReset"
99
>
10+
<!-- :value/@input allows us to pass v-model to the component -->
1011
<input
1112
type="search"
1213
autocorrect="off"
@@ -23,47 +24,50 @@
2324
@input="$emit('input', $event.target.value)"
2425
ref="input"
2526
>
26-
<!-- value/input allows us to pass v-model to the component -->
2727
<button
2828
type="submit"
2929
:title="submitTitle"
3030
:class="suit('submit')"
3131
:hidden="showLoadingIndicator && shouldShowLoadingIndicator"
3232
>
33-
<svg
34-
role="img"
35-
xmlns="http://www.w3.org/2000/svg"
36-
width="10"
37-
height="10"
38-
viewBox="0 0 40 40"
39-
:class="suit('submitIcon')"
40-
>
41-
<path
42-
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"
43-
fillRule="evenodd"
44-
/>
45-
</svg>
33+
<slot name="submit-icon">
34+
<svg
35+
role="img"
36+
xmlns="http://www.w3.org/2000/svg"
37+
width="10"
38+
height="10"
39+
viewBox="0 0 40 40"
40+
:class="suit('submitIcon')"
41+
>
42+
<path
43+
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"
44+
fillRule="evenodd"
45+
/>
46+
</svg>
47+
</slot>
4648
</button>
4749

4850
<button
4951
type="reset"
50-
:title="clearTitle"
52+
:title="resetTitle"
5153
:class="suit('reset')"
5254
:hidden="!value || (showLoadingIndicator && shouldShowLoadingIndicator)"
5355
>
54-
<svg
55-
role="img"
56-
xmlns="http://www.w3.org/2000/svg"
57-
width="1em"
58-
height="1em"
59-
viewBox="0 0 20 20"
60-
:class="suit('resetIcon')"
61-
>
62-
<path
63-
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"
64-
fillRule="evenodd"
65-
/>
66-
</svg>
56+
<slot name="reset-icon">
57+
<svg
58+
role="img"
59+
xmlns="http://www.w3.org/2000/svg"
60+
width="1em"
61+
height="1em"
62+
viewBox="0 0 20 20"
63+
:class="suit('resetIcon')"
64+
>
65+
<path
66+
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"
67+
fillRule="evenodd"
68+
/>
69+
</svg>
70+
</slot>
6771
</button>
6872

6973
<span
@@ -141,7 +145,7 @@ export default {
141145
type: String,
142146
default: 'Search',
143147
},
144-
clearTitle: {
148+
resetTitle: {
145149
type: String,
146150
default: 'Clear',
147151
},

src/components/__tests__/SearchBox.js

Lines changed: 62 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,11 +51,11 @@ test('with submit title', () => {
5151
);
5252
});
5353

54-
test('with clear title', () => {
54+
test('with reset title', () => {
5555
__setState(defaultState);
5656
const wrapper = mount(SearchBox, {
5757
propsData: {
58-
clearTitle: 'Clear Title',
58+
resetTitle: 'Clear Title',
5959
},
6060
});
6161

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

167167
expect(state.refine).toHaveBeenCalledWith('');
168168
});
169+
170+
test('overriding slots', () => {
171+
__setState({
172+
...defaultState,
173+
isSearchStalled: true,
174+
});
175+
const wrapper = mount(SearchBox, {
176+
propsData: {
177+
showLoadingIndicator: true,
178+
},
179+
slots: {
180+
'submit-icon': '<span>SUBMIT</span>',
181+
'reset-icon': '<span>RESET</span>',
182+
'loading-indicator': '<span>LOADING...</span>',
183+
},
184+
});
185+
186+
expect(wrapper.find('.ais-SearchBox-submit').html()).toMatch(/SUBMIT/);
187+
expect(wrapper.find('.ais-SearchBox-reset').html()).toMatch(/RESET/);
188+
expect(wrapper.find('.ais-SearchBox-loadingIndicator').html()).toMatch(
189+
/LOADING.../
190+
);
191+
192+
expect(wrapper.find('.ais-SearchBox-submit').html()).toMatchInlineSnapshot(`
193+
194+
<button type="submit"
195+
title="Search"
196+
hidden="hidden"
197+
class="ais-SearchBox-submit"
198+
>
199+
<span>
200+
SUBMIT
201+
</span>
202+
</button>
203+
204+
`);
205+
expect(wrapper.find('.ais-SearchBox-reset').html()).toMatchInlineSnapshot(`
206+
207+
<button type="reset"
208+
title="Clear"
209+
hidden="hidden"
210+
class="ais-SearchBox-reset"
211+
>
212+
<span>
213+
RESET
214+
</span>
215+
</button>
216+
217+
`);
218+
expect(wrapper.find('.ais-SearchBox-loadingIndicator').html())
219+
.toMatchInlineSnapshot(`
220+
221+
<span class="ais-SearchBox-loadingIndicator">
222+
<span>
223+
LOADING...
224+
</span>
225+
</span>
226+
227+
`);
228+
});

stories/SearchBox.stories.js

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ storiesOf('ais-search-box', module)
77
template: '<ais-search-box></ais-search-box>',
88
}))
99
.add('with loading indicator', () => ({
10-
template: '<ais-search-box showLoadingIndicator></ais-search-box>',
10+
template: '<ais-search-box show-loading-indicator></ais-search-box>',
1111
}))
1212
.add('with autofocus', () => ({
1313
template: '<ais-search-box autofocus></ais-search-box>',
@@ -24,6 +24,21 @@ storiesOf('ais-search-box', module)
2424
</ais-search-box>
2525
`,
2626
}))
27+
.add('with custom rendering of icons', () => ({
28+
template: `
29+
<ais-search-box show-loading-indicator>
30+
<template slot="reset-icon">
31+
32+
</template>
33+
<template slot="submit-icon">
34+
🔎
35+
</template>
36+
<template slot="loading-indicator">
37+
🔄
38+
</template>
39+
</ais-search-box>
40+
`,
41+
}))
2742
.add('with a Panel', () => ({
2843
template: `
2944
<ais-panel>

0 commit comments

Comments
 (0)