Skip to content

Commit 2a539f5

Browse files
committed
refactor: update new <pl-search> component to better handle the clear button's placement + logic for opting out, including an example in the HTML template
1 parent 0b175d9 commit 2a539f5

File tree

3 files changed

+116
-61
lines changed

3 files changed

+116
-61
lines changed

packages/uikit-workshop/src/html/partials/header.html

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,13 @@
44

55
<nav class="pl-c-nav pl-js-nav-target pl-js-nav-container" role="navigation">
66

7-
<!-- @todo: as a next step, implement <pl-search> as a customizable slot in the new <pl-header> for customization via available props -->
8-
<pl-search max-results="10" placeholder="Find a Pattern"></pl-search>
7+
<!--
8+
@todo: as a next step, implement <pl-search> as a customizable slot in the new <pl-header> for customization via available props
9+
10+
Example of always hiding the search's clear button
11+
<pl-search max-results="10" placeholder="Find a Pattern" hide-clear-button></pl-search>
12+
-->
13+
<pl-search max-results="10" placeholder="Find a Pattern"></pl-search>
914

1015
<ol class="pl-c-nav__list pl-js-pattern-nav-target">
1116
<!-- pattern lab nav will be inserted here -->

packages/uikit-workshop/src/scripts/components/pl-search/pl-search.js

Lines changed: 60 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ class Search extends BaseComponent {
3535
this.toggleSearch = this.toggleSearch.bind(this);
3636
// this.clearSearch = this.clearSearch.bind(this);
3737
this.closeSearch = this.closeSearch.bind(this);
38+
this.renderInputComponent = this.renderInputComponent.bind(this);
3839
this.openSearch = this.openSearch.bind(this);
3940

4041
this.items = [];
@@ -70,7 +71,7 @@ class Search extends BaseComponent {
7071
static props = {
7172
maxResults: props.string,
7273
placeholder: props.string,
73-
showClearButton: props.boolean,
74+
hideClearButton: props.boolean,
7475
clearButtonText: props.string,
7576
};
7677

@@ -228,6 +229,50 @@ class Search extends BaseComponent {
228229
});
229230
};
230231

232+
renderInputComponent(inputProps) {
233+
const { value } = this.state;
234+
235+
const shouldShowClearButton =
236+
this.props.hideClearButton !== undefined &&
237+
this.props.hideClearButton !== true &&
238+
value !== '';
239+
240+
const clearButtonText = this.props.clearButtonText
241+
? this.props.clearButtonText
242+
: 'Clear Search Results';
243+
244+
return (
245+
<div
246+
className={classNames('pl-c-typeahead__input-wrapper', {
247+
[`pl-c-typeahead__input-wrapper--with-clear-button`]: shouldShowClearButton,
248+
})}
249+
>
250+
<input {...inputProps} />
251+
{shouldShowClearButton && (
252+
<button
253+
className={classNames('pl-c-typeahead__clear-button', {
254+
[`pl-is-visible`]: value !== '',
255+
})}
256+
onClick={() => {
257+
this.clearSearch();
258+
}}
259+
>
260+
<VisuallyHidden>{clearButtonText}</VisuallyHidden>
261+
<svg
262+
viewBox="0 0 16 16"
263+
height="16"
264+
width="16"
265+
className={'pl-c-typeahead__clear-button-icon'}
266+
>
267+
<title>{clearButtonText}</title>
268+
<path d="M12.207 10.793l-1.414 1.414-2.793-2.793-2.793 2.793-1.414-1.414 2.793-2.793-2.793-2.793 1.414-1.414 2.793 2.793 2.793-2.793 1.414 1.414-2.793 2.793 2.793 2.793z" />
269+
</svg>
270+
</button>
271+
)}
272+
</div>
273+
);
274+
}
275+
231276
// Autosuggest calls this every time you need to clear suggestions.
232277
onSuggestionsClearRequested = () => {
233278
this.setState({
@@ -244,13 +289,10 @@ class Search extends BaseComponent {
244289
render() {
245290
const { value, suggestions } = this.state;
246291

247-
const shouldShowClearButton = this.props.showClearButton
248-
? this.props.showClearButton
249-
: true;
250-
251-
const clearButtonText = this.props.clearButtonText
252-
? this.props.clearButtonText
253-
: 'Clear Search Results';
292+
const shouldShowClearButton =
293+
this.props.hideClearButton !== undefined &&
294+
this.props.hideClearButton !== true &&
295+
value !== '';
254296

255297
// no CSS for these Autosuggest selectors yet -- not yet needed
256298
const theme = {
@@ -286,38 +328,16 @@ class Search extends BaseComponent {
286328
};
287329

288330
return (
289-
<div className={classNames('pl-c-typeahead-wrapper')}>
290-
<Autosuggest
291-
theme={theme}
292-
suggestions={suggestions}
293-
onSuggestionsFetchRequested={this.onSuggestionsFetchRequested}
294-
onSuggestionsClearRequested={this.onSuggestionsClearRequested}
295-
getSuggestionValue={this.getSuggestionValue}
296-
renderSuggestion={this.renderSuggestion}
297-
inputProps={inputProps}
298-
/>
299-
{shouldShowClearButton && (
300-
<button
301-
className={classNames('pl-c-typeahead__clear-button', {
302-
[`pl-is-visible`]: value !== '',
303-
})}
304-
onClick={() => {
305-
this.clearSearch();
306-
}}
307-
>
308-
<VisuallyHidden>{clearButtonText}</VisuallyHidden>
309-
<svg
310-
viewBox="0 0 16 16"
311-
height="16"
312-
width="16"
313-
className={'pl-c-typeahead__clear-button-icon'}
314-
>
315-
<title>{clearButtonText}</title>
316-
<path d="M12.207 10.793l-1.414 1.414-2.793-2.793-2.793 2.793-1.414-1.414 2.793-2.793-2.793-2.793 1.414-1.414 2.793 2.793 2.793-2.793 1.414 1.414-2.793 2.793 2.793 2.793z" />
317-
</svg>
318-
</button>
319-
)}
320-
</div>
331+
<Autosuggest
332+
theme={theme}
333+
suggestions={suggestions}
334+
onSuggestionsFetchRequested={this.onSuggestionsFetchRequested}
335+
onSuggestionsClearRequested={this.onSuggestionsClearRequested}
336+
getSuggestionValue={this.getSuggestionValue}
337+
renderSuggestion={this.renderSuggestion}
338+
inputProps={inputProps}
339+
renderInputComponent={this.renderInputComponent}
340+
/>
321341
);
322342
}
323343
}

packages/uikit-workshop/src/scripts/components/pl-search/pl-search.scss

Lines changed: 49 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@
88
* searches. https://twitter.github.io/typeahead.js/
99
*/
1010

11-
$pl-clear-button-size: 1.8rem;
12-
$pl-clear-button-size-at-med: 1.5rem;
11+
$pl-clear-button-size: 1.7rem;
12+
$pl-clear-button-size-at-med: 1.4rem;
1313

1414
pl-search {
1515
background-color: inherit;
@@ -48,6 +48,7 @@ pl-search {
4848
text-transform: capitalize;
4949
flex-direction: column;
5050
color: $pl-color-gray-02;
51+
position: relative;
5152

5253
.pl-c-body--theme-light & {
5354
color: $pl-color-gray-87;
@@ -72,7 +73,6 @@ pl-search {
7273
.pl-c-typeahead__hint,
7374
.pl-c-typeahead__input {
7475
text-transform: capitalize;
75-
border-radius: $pl-border-radius-med;
7676
background-color: $pl-color-gray-87;
7777
color: $pl-color-white;
7878
border-color: darken($pl-color-gray-87, 10%);
@@ -83,13 +83,16 @@ pl-search {
8383
max-width: 100%;
8484
padding: 0.31rem 0.5rem;
8585
font-size: 16px; // prevent zooming in on mobile
86+
width: 100%;
87+
outline-offset: -3px;
88+
outline-width: 2px;
8689

8790
.pl-c-body--theme-sidebar & {
8891
border-radius: 0;
8992
}
9093

9194
// Modify the padding defaults when the clear button UI exists
92-
&--with-clear-button {
95+
.pl-c-typeahead__input-wrapper--with-clear-button & {
9396
padding-right: $pl-clear-button-size;
9497

9598
@media all and (min-width: $pl-bp-med) {
@@ -98,7 +101,6 @@ pl-search {
98101
}
99102

100103
@media all and (min-width: $pl-bp-med) {
101-
max-width: 12vw;
102104
font-size: inherit;
103105

104106
.pl-c-body--theme-sidebar & {
@@ -107,7 +109,7 @@ pl-search {
107109
}
108110

109111
.pl-c-body--theme-light & {
110-
background-color: $pl-color-gray-07 !important;
112+
background-color: $pl-color-gray-07;
111113
color: $pl-color-gray-70 !important;
112114
border-color: $pl-color-gray-13 !important;
113115
}
@@ -143,8 +145,6 @@ pl-search {
143145
.pl-c-typeahead__menu {
144146
@include accordionPanel;
145147
background-color: $pl-color-gray-87;
146-
border-bottom-right-radius: $pl-border-radius-med;
147-
border-bottom-left-radius: $pl-border-radius-med;
148148
text-transform: capitalize;
149149
position: absolute;
150150
min-width: 100%;
@@ -157,6 +157,11 @@ pl-search {
157157
transition: max-height 0.3s ease, opacity 0.3s ease;
158158
opacity: 0;
159159

160+
@media all and (min-width: $pl-bp-med) {
161+
border-bottom-right-radius: $pl-border-radius-med;
162+
border-bottom-left-radius: $pl-border-radius-med;
163+
}
164+
160165
.pl-c-body--theme-light & {
161166
background-color: $pl-color-gray-02;
162167
}
@@ -187,8 +192,12 @@ pl-search {
187192
border-color: transparent;
188193
border-width: 1px;
189194
border-style: solid;
190-
border-bottom-right-radius: $pl-border-radius-med;
191-
border-bottom-left-radius: $pl-border-radius-med;
195+
196+
@media all and (min-width: $pl-bp-med) {
197+
border-bottom-right-radius: $pl-border-radius-med;
198+
border-bottom-left-radius: $pl-border-radius-med;
199+
}
200+
192201
overflow: hidden;
193202
border-color: darken($pl-color-gray-87, 5%);
194203

@@ -198,7 +207,7 @@ pl-search {
198207
}
199208

200209
.pl-c-body--theme-light & {
201-
border-color: $pl-color-gray-07;
210+
border-color: $pl-color-gray-20;
202211
}
203212

204213
.pl-c-body--theme-sidebar & {
@@ -213,6 +222,16 @@ pl-search {
213222
background-color: inherit;
214223
padding: 0.8em;
215224
cursor: pointer;
225+
overflow: hidden;
226+
227+
&:last-child {
228+
border-bottom-right-radius: $pl-border-radius-med;
229+
border-bottom-left-radius: $pl-border-radius-med;
230+
231+
.pl-c-body--theme-sidebar & {
232+
border-radius: 0;
233+
}
234+
}
216235

217236
&:hover {
218237
background-color: rgba($pl-color-white, 0.15);
@@ -225,6 +244,10 @@ pl-search {
225244
&:active,
226245
&:focus {
227246
background-color: rgba(255, 255, 255, 0.18);
247+
248+
.pl-c-body--theme-light & {
249+
background-color: $pl-color-gray-13;
250+
}
228251
}
229252
}
230253

@@ -238,19 +261,20 @@ pl-search {
238261
}
239262
}
240263

241-
.pl-c-typeahead__result p {
242-
margin: 0;
243-
}
244-
245-
.pl-c-typeahead-wrapper {
246-
position: relative;
264+
.pl-c-typeahead__input-wrapper {
265+
position: relative; // used for positioning search clear button in relation to the <input>
247266
}
248267

249268
.pl-c-typeahead__clear-button {
250269
@include linkStyle;
251-
background-color: transparent;
252270
height: $pl-clear-button-size;
253271
width: $pl-clear-button-size;
272+
background-color: transparent;
273+
274+
&:hover,
275+
&:active {
276+
background-color: transparent;
277+
}
254278

255279
@media all and (min-width: $pl-bp-med) {
256280
height: $pl-clear-button-size-at-med;
@@ -259,13 +283,19 @@ pl-search {
259283

260284
.pl-c-body--theme-light & {
261285
background-color: transparent;
286+
287+
&:hover,
288+
&:active {
289+
background-color: transparent;
290+
}
262291
}
263292

264293
border-radius: 20rem;
265294
overflow: hidden;
266295
position: absolute;
267296
right: 0;
268-
top: 0;
297+
top: 50%;
298+
transform: translateY(-50%);
269299
z-index: 100;
270300
cursor: pointer;
271301
border: 0;

0 commit comments

Comments
 (0)