Skip to content

Commit 0f5d1c0

Browse files
committed
feat(input): add clearInputIcon property (#29246)
Issue number: resolves #26974 --------- <!-- Please do not submit updates to dependencies unless it fixes an issue. --> <!-- Please try to limit your pull request to one type (bugfix, feature, etc). Submit multiple pull requests if needed. --> ## What is the current behavior? <!-- Please describe the current behavior that you are modifying. --> In #26354 we updated the clear icon to use an ionicon instead of an hardcoded SVG. This has made it challenging to customize the icon. ## What is the new behavior? <!-- Please describe the behavior or changes that are being added by this PR. --> - Added `clearInputIcon` property to allow developers to customize the ionicon used. ## Does this introduce a breaking change? - [ ] Yes - [x] No <!-- If this introduces a breaking change: 1. Describe the impact and migration path for existing applications below. 2. Update the BREAKING.md file with the breaking change. 3. Add "BREAKING CHANGE: [...]" to the commit description when merging. See https://github.com/ionic-team/ionic-framework/blob/main/.github/CONTRIBUTING.md#footer for more information. --> ## Other information <!-- Any other information that is important to this PR such as screenshots of how the component looks before and after the change. -->
1 parent 4b79bbe commit 0f5d1c0

File tree

6 files changed

+37
-4
lines changed

6 files changed

+37
-4
lines changed

core/api.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -553,6 +553,7 @@ ion-input,prop,autocomplete,"name" | "on" | "off" | "honorific-prefix" | "given-
553553
ion-input,prop,autocorrect,"off" | "on",'off',false,false
554554
ion-input,prop,autofocus,boolean,false,false,false
555555
ion-input,prop,clearInput,boolean,false,false,false
556+
ion-input,prop,clearInputIcon,string | undefined,undefined,false,false
556557
ion-input,prop,clearOnEdit,boolean | undefined,undefined,false,false
557558
ion-input,prop,color,"danger" | "dark" | "light" | "medium" | "primary" | "secondary" | "success" | "tertiary" | "warning" | string & Record<never, never> | undefined,undefined,false,true
558559
ion-input,prop,counter,boolean,false,false,false

core/src/components.d.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1162,6 +1162,10 @@ export namespace Components {
11621162
* If `true`, a clear icon will appear in the input when there is a value. Clicking it clears the input.
11631163
*/
11641164
"clearInput": boolean;
1165+
/**
1166+
* The icon to use for the clear button. Only applies when `clearInput` is set to `true`.
1167+
*/
1168+
"clearInputIcon"?: string;
11651169
/**
11661170
* If `true`, the value will be cleared after focus upon edit. Defaults to `true` when `type` is `"password"`, `false` for all other types.
11671171
*/
@@ -5886,6 +5890,10 @@ declare namespace LocalJSX {
58865890
* If `true`, a clear icon will appear in the input when there is a value. Clicking it clears the input.
58875891
*/
58885892
"clearInput"?: boolean;
5893+
/**
5894+
* The icon to use for the clear button. Only applies when `clearInput` is set to `true`.
5895+
*/
5896+
"clearInputIcon"?: string;
58895897
/**
58905898
* If `true`, the value will be cleared after focus upon edit. Defaults to `true` when `type` is `"password"`, `false` for all other types.
58915899
*/

core/src/components/input/input.tsx

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,11 @@ export class Input implements ComponentInterface {
9292
*/
9393
@Prop() clearInput = false;
9494

95+
/**
96+
* The icon to use for the clear button. Only applies when `clearInput` is set to `true`.
97+
*/
98+
@Prop() clearInputIcon?: string;
99+
95100
/**
96101
* If `true`, the value will be cleared after focus upon edit. Defaults to `true` when `type` is `"password"`, `false` for all other types.
97102
*/
@@ -681,11 +686,13 @@ export class Input implements ComponentInterface {
681686
}
682687

683688
render() {
684-
const { disabled, fill, readonly, shape, inputId, labelPlacement, el, hasFocus } = this;
689+
const { disabled, fill, readonly, shape, inputId, labelPlacement, el, hasFocus, clearInputIcon } = this;
685690
const mode = getIonMode(this);
686691
const value = this.getValue();
687692
const inItem = hostContext('ion-item', this.el);
688693
const shouldRenderHighlight = mode === 'md' && fill !== 'outline' && !inItem;
694+
const defaultClearIcon = mode === 'ios' ? closeCircle : closeSharp;
695+
const clearIconData = clearInputIcon ?? defaultClearIcon;
689696

690697
const hasValue = this.hasValue();
691698
const hasStartEndSlots = el.querySelector('[slot="start"], [slot="end"]') !== null;
@@ -784,7 +791,7 @@ export class Input implements ComponentInterface {
784791
}}
785792
onClick={this.clearTextInput}
786793
>
787-
<ion-icon aria-hidden="true" icon={mode === 'ios' ? closeCircle : closeSharp}></ion-icon>
794+
<ion-icon aria-hidden="true" icon={clearIconData}></ion-icon>
788795
</button>
789796
)}
790797
<slot name="end"></slot>

core/src/components/input/test/input.spec.ts

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,3 +99,19 @@ describe('input: label rendering', () => {
9999
expect(labelText.textContent).toBe('Label Prop Text');
100100
});
101101
});
102+
103+
// https://github.com/ionic-team/ionic-framework/issues/26974
104+
describe('input: clear icon', () => {
105+
it('should render custom icon', async () => {
106+
const page = await newSpecPage({
107+
components: [Input],
108+
html: `
109+
<ion-input clear-input-icon="foo" clear-input="true"></ion-input>
110+
`,
111+
});
112+
113+
const icon = page.body.querySelector<HTMLIonIconElement>('ion-input ion-icon')!;
114+
115+
expect(icon.getAttribute('icon')).toBe('foo');
116+
});
117+
});

packages/angular/src/directives/proxies.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -955,15 +955,15 @@ export declare interface IonInfiniteScrollContent extends Components.IonInfinite
955955

956956

957957
@ProxyCmp({
958-
inputs: ['autocapitalize', 'autocomplete', 'autocorrect', 'autofocus', 'clearInput', 'clearOnEdit', 'color', 'counter', 'counterFormatter', 'debounce', 'disabled', 'enterkeyhint', 'errorText', 'fill', 'helperText', 'inputmode', 'label', 'labelPlacement', 'max', 'maxlength', 'min', 'minlength', 'mode', 'multiple', 'name', 'pattern', 'placeholder', 'readonly', 'required', 'shape', 'spellcheck', 'step', 'type', 'value'],
958+
inputs: ['autocapitalize', 'autocomplete', 'autocorrect', 'autofocus', 'clearInput', 'clearInputIcon', 'clearOnEdit', 'color', 'counter', 'counterFormatter', 'debounce', 'disabled', 'enterkeyhint', 'errorText', 'fill', 'helperText', 'inputmode', 'label', 'labelPlacement', 'max', 'maxlength', 'min', 'minlength', 'mode', 'multiple', 'name', 'pattern', 'placeholder', 'readonly', 'required', 'shape', 'spellcheck', 'step', 'type', 'value'],
959959
methods: ['setFocus', 'getInputElement']
960960
})
961961
@Component({
962962
selector: 'ion-input',
963963
changeDetection: ChangeDetectionStrategy.OnPush,
964964
template: '<ng-content></ng-content>',
965965
// eslint-disable-next-line @angular-eslint/no-inputs-metadata-property
966-
inputs: ['autocapitalize', 'autocomplete', 'autocorrect', 'autofocus', 'clearInput', 'clearOnEdit', 'color', 'counter', 'counterFormatter', 'debounce', 'disabled', 'enterkeyhint', 'errorText', 'fill', 'helperText', 'inputmode', 'label', 'labelPlacement', 'max', 'maxlength', 'min', 'minlength', 'mode', 'multiple', 'name', 'pattern', 'placeholder', 'readonly', 'required', 'shape', 'spellcheck', 'step', 'type', 'value'],
966+
inputs: ['autocapitalize', 'autocomplete', 'autocorrect', 'autofocus', 'clearInput', 'clearInputIcon', 'clearOnEdit', 'color', 'counter', 'counterFormatter', 'debounce', 'disabled', 'enterkeyhint', 'errorText', 'fill', 'helperText', 'inputmode', 'label', 'labelPlacement', 'max', 'maxlength', 'min', 'minlength', 'mode', 'multiple', 'name', 'pattern', 'placeholder', 'readonly', 'required', 'shape', 'spellcheck', 'step', 'type', 'value'],
967967
})
968968
export class IonInput {
969969
protected el: HTMLElement;

packages/vue/src/proxies.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -402,6 +402,7 @@ export const IonInput = /*@__PURE__*/ defineContainer<JSX.IonInput, JSX.IonInput
402402
'autocorrect',
403403
'autofocus',
404404
'clearInput',
405+
'clearInputIcon',
405406
'clearOnEdit',
406407
'counter',
407408
'counterFormatter',

0 commit comments

Comments
 (0)