Skip to content

Commit 8ad66c0

Browse files
authored
fix(searchbar): autocapitalize is initialized correctly (#29197)
Issue number: resolves #29193 --------- <!-- 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 an attempt to preserve backwards compatibility when adding `autocapitalize` to Searchbar, we used `!` to indicate that the prop was never undefined. The `autocapitalize` on `HTMLElement` expects this value to be a string and never undefined. For the purposes of the property on Searchbar, setting this prop to one of the accepted values would constitute a breaking change because it would override the default browser behavior (which we previously relied upon). As a result, we used `!` to not set a default prop but inform TypeScript that this prop is always defined. This unintentionally made it so developers needed to define the `autocapitalize` property every time which is not what we want. ## What is the new behavior? <!-- Please describe the behavior or changes that are being added by this PR. --> - `autocapitalize` now defaults to the `'default'` keyword. This is an internal keyword that is used to tell Ionic to **not** set the `autocapitalize` attribute on the inner `input` element and instead rely on the default browser behavior. This satisfies the `HTMLElement` requirement that `autocapitalize` is never undefined. In Ionic 8 this `'default'` value will be replaced with `'off'`. [Typescript currently sets the `HTMLElement` `autocapitalize` type to `string`](https://github.com/microsoft/TypeScript/blob/65812bf3ec3b9208141ef46e43d146a2eef88ae5/src/lib/dom.generated.d.ts#L10087) which is why we can add a `'default'` keyword here. There is some risk that if these type definitions change in the future that applications may encounter errors. However, changing this on the TypeScript side would itself be a breaking change. Additionally, we are moving away from `'default'` in Ionic 8, so I think this is an acceptable amount of risk. ## 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. --> Dev build: `7.8.2-dev.11711027016.13b2a920` Tested in a React starter app with Searchbar, and I verified this fix works.
1 parent d1253c0 commit 8ad66c0

File tree

3 files changed

+9
-10
lines changed

3 files changed

+9
-10
lines changed

core/api.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1158,7 +1158,7 @@ ion-row,shadow
11581158

11591159
ion-searchbar,scoped
11601160
ion-searchbar,prop,animated,boolean,false,false,false
1161-
ion-searchbar,prop,autocapitalize,string,undefined,true,false
1161+
ion-searchbar,prop,autocapitalize,string,'default',false,false
11621162
ion-searchbar,prop,autocomplete,"name" | "email" | "tel" | "url" | "on" | "off" | "honorific-prefix" | "given-name" | "additional-name" | "family-name" | "honorific-suffix" | "nickname" | "username" | "new-password" | "current-password" | "one-time-code" | "organization-title" | "organization" | "street-address" | "address-line1" | "address-line2" | "address-line3" | "address-level4" | "address-level3" | "address-level2" | "address-level1" | "country" | "country-name" | "postal-code" | "cc-name" | "cc-given-name" | "cc-additional-name" | "cc-family-name" | "cc-number" | "cc-exp" | "cc-exp-month" | "cc-exp-year" | "cc-csc" | "cc-type" | "transaction-currency" | "transaction-amount" | "language" | "bday" | "bday-day" | "bday-month" | "bday-year" | "sex" | "tel-country-code" | "tel-national" | "tel-area-code" | "tel-local" | "tel-extension" | "impp" | "photo",'off',false,false
11631163
ion-searchbar,prop,autocorrect,"off" | "on",'off',false,false
11641164
ion-searchbar,prop,cancelButtonIcon,string,config.get('backButtonIcon', arrowBackSharp) as string,false,false

core/src/components.d.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7295,7 +7295,7 @@ declare namespace LocalJSX {
72957295
/**
72967296
* Indicates whether and how the text value should be automatically capitalized as it is entered/edited by the user. Available options: `"off"`, `"none"`, `"on"`, `"sentences"`, `"words"`, `"characters"`.
72977297
*/
7298-
"autocapitalize": string;
7298+
"autocapitalize"?: string;
72997299
/**
73007300
* Set the input's autocomplete property.
73017301
*/

core/src/components/searchbar/searchbar.tsx

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -84,20 +84,19 @@ export class Searchbar implements ComponentInterface {
8484
* and disabled by default on Android
8585
* for Searchbar. The autocapitalize type on HTMLElement
8686
* requires that it be a string and never undefined.
87-
* However, setting it to a string value would be a breaking change
88-
* in behavior, so we use "!" to tell TypeScript that this property
89-
* is always defined so we can rely on the browser defaults. Browsers
90-
* will automatically set a default value if the developer does not set one.
87+
* However, setting it to one of the accepted values would be a breaking change
88+
* in behavior, so we use the internal "default" keyword to ensure
89+
* we use the default browser behavior for now.
9190
*
9291
* In the future, this property will default to "off" to align with
93-
* Input and Textarea, and the "!" will not be needed.
92+
* Input and Textarea, and the internal "default" keyword will not be needed.
9493
*/
9594

9695
/**
9796
* Indicates whether and how the text value should be automatically capitalized as it is entered/edited by the user.
9897
* Available options: `"off"`, `"none"`, `"on"`, `"sentences"`, `"words"`, `"characters"`.
9998
*/
100-
@Prop() autocapitalize!: string;
99+
@Prop() autocapitalize: string = 'default';
101100

102101
/**
103102
* Set the input's autocomplete property.
@@ -621,7 +620,7 @@ export class Searchbar implements ComponentInterface {
621620
}
622621

623622
render() {
624-
const { cancelButtonText } = this;
623+
const { cancelButtonText, autocapitalize } = this;
625624
const animated = this.animated && config.getBoolean('animated', true);
626625
const mode = getIonMode(this);
627626
const clearIcon = this.clearIcon || (mode === 'ios' ? closeCircle : closeSharp);
@@ -683,7 +682,7 @@ export class Searchbar implements ComponentInterface {
683682
placeholder={this.placeholder}
684683
type={this.type}
685684
value={this.getValue()}
686-
autoCapitalize={this.autocapitalize}
685+
autoCapitalize={autocapitalize === 'default' ? undefined : autocapitalize}
687686
autoComplete={this.autocomplete}
688687
autoCorrect={this.autocorrect}
689688
spellcheck={this.spellcheck}

0 commit comments

Comments
 (0)