mirror of
https://github.com/ionic-team/ionic-framework.git
synced 2026-03-13 10:22:08 +08:00
feat(searchbar): add cancel button options
This commit is contained in:
@@ -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
|
||||
|
||||
8
core/src/components.d.ts
vendored
8
core/src/components.d.ts
vendored
@@ -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 `<Ionic>` 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 - 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 @@
|
||||
// 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
|
||||
|
||||
Reference in New Issue
Block a user