Skip to content
Permalink
Browse files

feat(searchbar): add cancel button options

  • Loading branch information...
liamdebeasi committed Jun 11, 2019
1 parent 20c146e commit b959e0b5ec8cfac8732416817d859888b6c5f803
@@ -917,7 +917,7 @@ ion-searchbar,prop,disabled,boolean,false,false,false
ion-searchbar,prop,mode,"ios" | "md",undefined,false,false
ion-searchbar,prop,placeholder,string,'Search',false,false
ion-searchbar,prop,searchIcon,string,'search',false,false
ion-searchbar,prop,showCancelButton,boolean,false,false,false
ion-searchbar,prop,showCancelButton,boolean | string,false,false,false
ion-searchbar,prop,spellcheck,boolean,false,false,false
ion-searchbar,prop,type,"email" | "number" | "password" | "search" | "tel" | "text" | "url",'search',false,false
ion-searchbar,prop,value,null | string | undefined,'',false,false
@@ -3800,9 +3800,9 @@ export namespace Components {
*/
'setFocus': () => void;
/**
* If `true`, show the cancel button.
* Sets the behavior for the cancel button. Setting to `"focus"` shows the cancel button on focus. Setting to `"never"` hides the cancel button. Setting to `"always"` shows the cancel button regardless of focus state.
*/
'showCancelButton': boolean;
'showCancelButton': boolean | string;
/**
* If `true`, enable spellcheck on the input.
*/
@@ -3890,9 +3890,9 @@ export namespace Components {
*/
'searchIcon'?: string;
/**
* If `true`, show the cancel button.
* Sets the behavior for the cancel button. Setting to `"focus"` shows the cancel button on focus. Setting to `"never"` hides the cancel button. Setting to `"always"` shows the cancel button regardless of focus state.
*/
'showCancelButton'?: boolean;
'showCancelButton'?: boolean | string;
/**
* If `true`, enable spellcheck on the input.
*/
@@ -188,7 +188,7 @@ export default Example;
| `mode` | `mode` | The mode determines which platform styles to use. | `"ios" \| "md"` | `undefined` |
| `placeholder` | `placeholder` | Set the input's placeholder. `placeholder` can accept either plaintext or HTML as a string. To display characters normally reserved for HTML, they must be escaped. For example `<Ionic>` would become `&lt;Ionic&gt;` For more information: [Security Documentation](https://ionicframework.com/docs/faq/security) | `string` | `'Search'` |
| `searchIcon` | `search-icon` | The icon to use as the search icon. | `string` | `'search'` |
| `showCancelButton` | `show-cancel-button` | If `true`, show the cancel button. | `boolean` | `false` |
| `showCancelButton` | `show-cancel-button` | Sets the behavior for the cancel button. Setting to `"focus"` shows the cancel button on focus. Setting to `"never"` hides the cancel button. Setting to `"always"` shows the cancel button regardless of focus state. | `boolean \| string` | `false` |
| `spellcheck` | `spellcheck` | If `true`, enable spellcheck on the input. | `boolean` | `false` |
| `type` | `type` | Set the type of the input. | `"email" \| "number" \| "password" \| "search" \| "tel" \| "text" \| "url"` | `'search'` |
| `value` | `value` | the value of the searchbar. | `null \| string \| undefined` | `''` |
@@ -110,6 +110,7 @@
// -----------------------------------------

:host(.searchbar-has-focus) .searchbar-cancel-button,
:host(.searchbar-should-show-cancel) .searchbar-cancel-button,
:host(.searchbar-animated) .searchbar-cancel-button {
display: block;
}
@@ -119,7 +120,8 @@
transition: $searchbar-ios-input-transition;
}

:host(.searchbar-animated.searchbar-has-focus) .searchbar-cancel-button {
:host(.searchbar-animated.searchbar-has-focus) .searchbar-cancel-button,
:host(.searchbar-animated.searchbar-should-show-cancel) .searchbar-cancel-button {
opacity: 1;
pointer-events: auto;
}
@@ -105,7 +105,8 @@
display: block;
}

:host(.searchbar-has-focus) .searchbar-cancel-button {
:host(.searchbar-has-focus) .searchbar-cancel-button,
:host(.searchbar-should-show-cancel) .searchbar-cancel-button {
display: block;
}

@@ -19,7 +19,7 @@ export class Searchbar implements ComponentInterface {
private isCancelVisible = false;
private shouldAlignLeft = true;

@Element() el!: HTMLElement;
@Element() el!: HTMLStencilElement;

@Prop({ context: 'config' }) config!: Config;
@Prop({ context: 'document' }) doc!: Document;
@@ -101,9 +101,13 @@ export class Searchbar implements ComponentInterface {
@Prop() searchIcon = 'search';

/**
* If `true`, show the cancel button.
* Sets the behavior for the cancel button.
* Setting to `"focus"` shows the cancel button on focus.
* Setting to `"never"` hides the cancel button.
* Setting to `"always"` shows the cancel button regardless
* of focus state.
*/
@Prop() showCancelButton = false;
@Prop() showCancelButton: boolean | string = false;

/**
* If `true`, enable spellcheck on the input.
@@ -160,6 +164,14 @@ export class Searchbar implements ComponentInterface {
this.ionChange.emit({ value });
}

@Watch('showCancelButton')
protected showCancelButtonChanged() {
requestAnimationFrame(() => {
this.positionElements();
this.el.forceUpdate();
});
}

componentDidLoad() {
this.positionElements();
this.debounceChanged();
@@ -330,7 +342,7 @@ export class Searchbar implements ComponentInterface {
private positionCancelButton() {
const isRTL = this.doc.dir === 'rtl';
const cancelButton = (this.el.shadowRoot || this.el).querySelector('.searchbar-cancel-button') as HTMLElement;
const shouldShowCancel = this.focused;
const shouldShowCancel = this.shouldShowCancelButton();

if (cancelButton && shouldShowCancel !== this.isCancelVisible) {
const cancelStyle = cancelButton.style;
@@ -362,6 +374,50 @@ export class Searchbar implements ComponentInterface {
return this.getValue() !== '';
}

/**
* Determines whether or not the cancel button should visible onscreen
* Cancel button should be shown if one of the three conditions applies:
* 1. The user has called showCancel(), setting forceShowCancel = true
* 2. The user has focused the searchbar
* 3. The user has `showCancelButton` set to `persist` and the searchbar has
* already been focused at least once
*/
private shouldShowCancelButton(): boolean {
if (
this.isCancelButtonSetToNever() ||
(this.isCancelButtonSetToFocus() && !this.focused)
) { return false; }

return true;
}

/**
* Wrapper method to check if the cancel button
* should be shown on focus.
*
* TODO: Remove this when the `true` and `false`
* options are removed.
*/
private isCancelButtonSetToFocus(): boolean {
return this.showCancelButton === 'focus' ||
this.showCancelButton === 'true' ||
this.showCancelButton === true ||
this.showCancelButton === '';
}

/**
* Wrapper method to check if the cancel button
* should never be shown.
*
* TODO: Remove this when the `true` and `false`
* options are removed.
*/
private isCancelButtonSetToNever(): boolean {
return this.showCancelButton === 'never' ||
this.showCancelButton === 'false' ||
this.showCancelButton === false;
}

hostData() {
const animated = this.animated && this.config.getBoolean('animated', true);

@@ -375,7 +431,8 @@ export class Searchbar implements ComponentInterface {
'searchbar-no-animate': animated && this.noAnimate,
'searchbar-has-value': this.hasValue(),
'searchbar-left-aligned': this.shouldAlignLeft,
'searchbar-has-focus': this.focused
'searchbar-has-focus': this.focused,
'searchbar-should-show-cancel': this.shouldShowCancelButton()
}
};
}
@@ -384,10 +441,10 @@ export class Searchbar implements ComponentInterface {
const clearIcon = this.clearIcon || (this.mode === 'ios' ? 'ios-close-circle' : 'md-close');
const searchIcon = this.searchIcon;

const cancelButton = this.showCancelButton && (
const cancelButton = !this.isCancelButtonSetToNever() && (
<button
type="button"
tabIndex={this.mode === 'ios' && !this.focused ? -1 : undefined}
tabIndex={this.mode === 'ios' && !this.shouldShowCancelButton() ? -1 : undefined}
onMouseDown={this.onCancelSearchbar}
onTouchStart={this.onCancelSearchbar}
class="searchbar-cancel-button"
@@ -28,6 +28,26 @@ <h5 class="ion-padding-start ion-padding-top"> Search - Default </h5>
<h5 class="ion-padding-start ion-padding-top"> Search - No Cancel Button </h5>
<ion-searchbar id="noCancel" value="after view" autocorrect="off" autocomplete="off" spellcheck="true" type="text" show-cancel-button="false">
</ion-searchbar>

<h5 class="ion-padding-start ion-padding-top"> Search - Always Show Cancel Button</h5>
<ion-searchbar id="noCancel" value="after view" animated="true" show-cancel-button="always">
</ion-searchbar>

<h5 class="ion-padding-start ion-padding-top"> Search - Never Show Cancel Button</h5>
<ion-searchbar id="noCancel" value="after view" animated="true" show-cancel-button="never">
</ion-searchbar>

<h5 class="ion-padding-start ion-padding-top"> Search - Show Cancel Button on Focus</h5>
<ion-searchbar id="noCancel" value="after view" animated="true" show-cancel-button="focus">
</ion-searchbar>

<h5 class="ion-padding-start ion-padding-top"> Search - Cancel Button set to false</h5>
<ion-searchbar id="noCancel" value="after view" autocorrect="off" autocomplete="off" spellcheck="true" type="text" show-cancel-button="false">
</ion-searchbar>

<h5 class="ion-padding-start ion-padding-top"> Search - Cancel Button set to true</h5>
<ion-searchbar id="noCancel" value="after view" autocorrect="off" autocomplete="off" spellcheck="true" type="text" show-cancel-button="true">
</ion-searchbar>

<h5 class="ion-padding-start ion-padding-top"> Search - Disabled </h5>
<ion-searchbar id="disabled" value="disabled" type="text" disabled="true">
@@ -97,9 +117,32 @@ <h5 class="ion-padding-start ion-padding-top"> Search - Animated and No Cancel</
// Toggle animated attribute
const attrIsAnimated = dynamicAttr.getAttribute('animated') === 'true' ? false : true;
dynamicAttr.setAttribute('animated', attrIsAnimated);
// Toggle show-cancel-button attribute
const attrShowCancel = dynamicAttr.getAttribute('show-cancel-button') === 'true' ? false : true;
let attrShowCancel;
const showCancelValue = dynamicAttr.getAttribute('show-cancel-button');
switch(showCancelValue) {
case true:
case "true":
attrShowCancel = false;
break;
case false:
case "false":
attrShowCancel = 'always';
break;
case 'always':
attrShowCancel = 'focus';
break;
case 'focus':
attrShowCancel = 'never';
break;
case 'never':
default:
attrShowCancel = true;
break;
}
dynamicAttr.setAttribute('show-cancel-button', attrShowCancel);
// Toggle placeholder attribute

0 comments on commit b959e0b

Please sign in to comment.
You can’t perform that action at this time.