mirror of
https://github.com/ionic-team/ionic-framework.git
synced 2025-08-16 10:01:59 +08:00
fix(input): check for tabindex and pass it properly to native input (#21170)
* fix(input): check for tabindex and pass it properly to native input references #17515 * style(input): fix lint error * test(input): update test for more use cases (inside item) * fix(item): adds delegatesFocus to shadow * style(input): add comment block on what the code does
This commit is contained in:
@ -21,6 +21,7 @@ export class Input implements ComponentInterface {
|
||||
private nativeInput?: HTMLInputElement;
|
||||
private inputId = `ion-input-${inputIds++}`;
|
||||
private didBlurAfterEdit = false;
|
||||
private tabindex?: string | number;
|
||||
|
||||
@State() hasFocus = false;
|
||||
|
||||
@ -88,13 +89,6 @@ export class Input implements ComponentInterface {
|
||||
this.emitStyle();
|
||||
}
|
||||
|
||||
/**
|
||||
* A hint to the browser for which keyboard to display.
|
||||
* Possible values: `"none"`, `"text"`, `"tel"`, `"url"`,
|
||||
* `"email"`, `"numeric"`, `"decimal"`, and `"search"`.
|
||||
*/
|
||||
@Prop() inputmode?: 'none' | 'text' | 'tel' | 'url' | 'email' | 'numeric' | 'decimal' | 'search';
|
||||
|
||||
/**
|
||||
* A hint to the browser for which enter key to display.
|
||||
* Possible values: `"enter"`, `"done"`, `"go"`, `"next"`,
|
||||
@ -102,6 +96,13 @@ export class Input implements ComponentInterface {
|
||||
*/
|
||||
@Prop() enterkeyhint?: 'enter' | 'done' | 'go' | 'next' | 'previous' | 'search' | 'send';
|
||||
|
||||
/**
|
||||
* A hint to the browser for which keyboard to display.
|
||||
* Possible values: `"none"`, `"text"`, `"tel"`, `"url"`,
|
||||
* `"email"`, `"numeric"`, `"decimal"`, and `"search"`.
|
||||
*/
|
||||
@Prop() inputmode?: 'none' | 'text' | 'tel' | 'url' | 'email' | 'numeric' | 'decimal' | 'search';
|
||||
|
||||
/**
|
||||
* The maximum value, which must not be less than its minimum (min attribute) value.
|
||||
*/
|
||||
@ -213,6 +214,17 @@ export class Input implements ComponentInterface {
|
||||
*/
|
||||
@Event() ionStyle!: EventEmitter<StyleEventDetail>;
|
||||
|
||||
componentWillLoad() {
|
||||
// If the ion-input has a tabindex attribute we get the value
|
||||
// and pass it down to the native input, then remove it from the
|
||||
// ion-input to avoid causing tabbing twice on the same element
|
||||
if (this.el.hasAttribute('tabindex')) {
|
||||
const tabindex = this.el.getAttribute('tabindex');
|
||||
this.tabindex = tabindex !== null ? tabindex : undefined;
|
||||
this.el.removeAttribute('tabindex');
|
||||
}
|
||||
}
|
||||
|
||||
connectedCallback() {
|
||||
this.emitStyle();
|
||||
this.debounceChanged();
|
||||
@ -384,6 +396,7 @@ export class Input implements ComponentInterface {
|
||||
spellCheck={this.spellcheck}
|
||||
step={this.step}
|
||||
size={this.size}
|
||||
tabindex={this.tabindex}
|
||||
type={this.type}
|
||||
value={value}
|
||||
onInput={this.onInput}
|
||||
|
76
core/src/components/input/test/tabindex/index.html
Normal file
76
core/src/components/input/test/tabindex/index.html
Normal file
@ -0,0 +1,76 @@
|
||||
<!DOCTYPE html>
|
||||
<html dir="ltr">
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Input - Tabindex</title>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no">
|
||||
<link href="../../../../../css/ionic.bundle.css" rel="stylesheet">
|
||||
<link href="../../../../../scripts/testing/styles.css" rel="stylesheet">
|
||||
<script src="../../../../../scripts/testing/scripts.js"></script>
|
||||
<script nomodule src="../../../../../dist/ionic/ionic.js"></script>
|
||||
<script type="module" src="../../../../../dist/ionic/ionic.esm.js"></script></head>
|
||||
|
||||
<body>
|
||||
<ion-app>
|
||||
|
||||
<ion-header>
|
||||
<ion-toolbar>
|
||||
<ion-title>Input - Tabindex</ion-title>
|
||||
<ion-buttons slot="primary">
|
||||
<ion-button>
|
||||
<ion-icon slot="icon-only" name="menu"></ion-icon>
|
||||
</ion-button>
|
||||
</ion-buttons>
|
||||
</ion-toolbar>
|
||||
</ion-header>
|
||||
|
||||
<ion-content class="ion-padding">
|
||||
<ion-input tabindex="0" placeholder="Tab 9th"></ion-input>
|
||||
<ion-input placeholder="Tab 10th"></ion-input>
|
||||
|
||||
<hr>
|
||||
|
||||
<ion-input placeholder="Tab 8th" tabindex="8"></ion-input>
|
||||
<ion-input placeholder="Skip" tabindex="-1"></ion-input>
|
||||
<ion-input placeholder="Tab 7th" tabindex="7"></ion-input>
|
||||
<div tabindex="0">Tab 11th</div>
|
||||
<ion-input placeholder="Tab 6th" tabindex="6"></ion-input>
|
||||
<ion-input placeholder="Tab 5th" tabindex="5"></ion-input>
|
||||
|
||||
<ion-item tabindex="4">
|
||||
<ion-label position="stacked">Tab 4th</ion-label>
|
||||
<ion-input></ion-input>
|
||||
</ion-item>
|
||||
<ion-item tabindex="3">
|
||||
<ion-label position="stacked">Tab 3rd</ion-label>
|
||||
<ion-input></ion-input>
|
||||
</ion-item>
|
||||
<ion-item tabindex="-1">
|
||||
<ion-label position="stacked">Skip</ion-label>
|
||||
<ion-input></ion-input>
|
||||
</ion-item>
|
||||
<ion-item tabindex="2">
|
||||
<ion-label position="stacked">Tab 2nd</ion-label>
|
||||
<ion-input></ion-input>
|
||||
</ion-item>
|
||||
<ion-item tabindex="1">
|
||||
<ion-label position="stacked">Tab 1st</ion-label>
|
||||
<ion-input></ion-input>
|
||||
</ion-item>
|
||||
</ion-content>
|
||||
|
||||
<style>
|
||||
ion-input,
|
||||
div {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.md div {
|
||||
padding-left: 8px;
|
||||
}
|
||||
</style>
|
||||
</ion-app>
|
||||
</body>
|
||||
|
||||
</html>
|
@ -20,7 +20,9 @@ import { createColorClasses, hostContext, openURL } from '../../utils/theme';
|
||||
ios: 'item.ios.scss',
|
||||
md: 'item.md.scss'
|
||||
},
|
||||
shadow: true
|
||||
shadow: {
|
||||
delegatesFocus: true
|
||||
}
|
||||
})
|
||||
export class Item implements ComponentInterface, AnchorInterface, ButtonInterface {
|
||||
|
||||
|
Reference in New Issue
Block a user