@ionic/core
Version:
Base components for Ionic
184 lines (183 loc) • 7.91 kB
JavaScript
/*!
* (C) Ionic http://ionicframework.com - MIT License
*/
import { Host, h } from "@stencil/core";
import { printIonWarning } from "../../utils/logging/index";
import { createColorClasses } from "../../utils/theme";
import { eyeOff, eye } from "ionicons/icons";
import { getIonMode } from "../../global/ionic-global";
/**
* @virtualProp {"ios" | "md"} mode - The mode determines which platform styles to use.
*/
export class InputPasswordToggle {
constructor() {
this.togglePasswordVisibility = () => {
const { inputElRef } = this;
if (!inputElRef) {
return;
}
inputElRef.type = inputElRef.type === 'text' ? 'password' : 'text';
};
this.color = undefined;
this.showIcon = undefined;
this.hideIcon = undefined;
this.type = 'password';
}
/**
* Whenever the input type changes we need to re-run validation to ensure the password
* toggle is being used with the correct input type. If the application changes the type
* outside of this component we also need to re-render so the correct icon is shown.
*/
onTypeChange(newValue) {
if (newValue !== 'text' && newValue !== 'password') {
printIonWarning(`ion-input-password-toggle only supports inputs of type "text" or "password". Input of type "${newValue}" is not compatible.`, this.el);
return;
}
}
connectedCallback() {
const { el } = this;
const inputElRef = (this.inputElRef = el.closest('ion-input'));
if (!inputElRef) {
printIonWarning('No ancestor ion-input found for ion-input-password-toggle. This component must be slotted inside of an ion-input.', el);
return;
}
/**
* Important: Set the type in connectedCallback because the default value
* of this.type may not always be accurate. Usually inputs have the "password" type
* but it is possible to have the input to initially have the "text" type. In that scenario
* the wrong icon will show briefly before switching to the correct icon. Setting the
* type here allows us to avoid that flicker.
*/
this.type = inputElRef.type;
}
disconnectedCallback() {
this.inputElRef = null;
}
render() {
var _a, _b;
const { color, type } = this;
const mode = getIonMode(this);
const showPasswordIcon = (_a = this.showIcon) !== null && _a !== void 0 ? _a : eye;
const hidePasswordIcon = (_b = this.hideIcon) !== null && _b !== void 0 ? _b : eyeOff;
const isPasswordVisible = type === 'text';
return (h(Host, { key: 'd9811e25bfeb2aa197352bb9be852e9e420739d5', class: createColorClasses(color, {
[mode]: true,
}) }, h("ion-button", { key: '1eaea1442b248fb2b8d61538b27274e647a07804', mode: mode, color: color, fill: "clear", shape: "round", "aria-checked": isPasswordVisible ? 'true' : 'false', "aria-label": "show password", role: "switch", type: "button", onPointerDown: (ev) => {
/**
* This prevents mobile browsers from
* blurring the input when the password toggle
* button is activated.
*/
ev.preventDefault();
}, onClick: this.togglePasswordVisibility }, h("ion-icon", { key: '9c88de8f4631d9bde222ce2edf6950d639e04773', slot: "icon-only", "aria-hidden": "true", icon: isPasswordVisible ? hidePasswordIcon : showPasswordIcon }))));
}
static get is() { return "ion-input-password-toggle"; }
static get encapsulation() { return "shadow"; }
static get originalStyleUrls() {
return {
"ios": ["input-password-toggle.scss"],
"md": ["input-password-toggle.scss"]
};
}
static get styleUrls() {
return {
"ios": ["input-password-toggle.css"],
"md": ["input-password-toggle.css"]
};
}
static get properties() {
return {
"color": {
"type": "string",
"mutable": false,
"complexType": {
"original": "Color",
"resolved": "\"danger\" | \"dark\" | \"light\" | \"medium\" | \"primary\" | \"secondary\" | \"success\" | \"tertiary\" | \"warning\" | string & Record<never, never> | undefined",
"references": {
"Color": {
"location": "import",
"path": "../../interface",
"id": "src/interface.d.ts::Color"
}
}
},
"required": false,
"optional": true,
"docs": {
"tags": [],
"text": "The color to use from your application's color palette.\nDefault options are: `\"primary\"`, `\"secondary\"`, `\"tertiary\"`, `\"success\"`, `\"warning\"`, `\"danger\"`, `\"light\"`, `\"medium\"`, and `\"dark\"`.\nFor more information on colors, see [theming](/docs/theming/basics)."
},
"attribute": "color",
"reflect": true
},
"showIcon": {
"type": "string",
"mutable": false,
"complexType": {
"original": "string",
"resolved": "string | undefined",
"references": {}
},
"required": false,
"optional": true,
"docs": {
"tags": [],
"text": "The icon that can be used to represent showing a password. If not set, the \"eye\" Ionicon will be used."
},
"attribute": "show-icon",
"reflect": false
},
"hideIcon": {
"type": "string",
"mutable": false,
"complexType": {
"original": "string",
"resolved": "string | undefined",
"references": {}
},
"required": false,
"optional": true,
"docs": {
"tags": [],
"text": "The icon that can be used to represent hiding a password. If not set, the \"eyeOff\" Ionicon will be used."
},
"attribute": "hide-icon",
"reflect": false
},
"type": {
"type": "string",
"mutable": true,
"complexType": {
"original": "TextFieldTypes",
"resolved": "\"date\" | \"datetime-local\" | \"email\" | \"month\" | \"number\" | \"password\" | \"search\" | \"tel\" | \"text\" | \"time\" | \"url\" | \"week\"",
"references": {
"TextFieldTypes": {
"location": "import",
"path": "../../interface",
"id": "src/interface.d.ts::TextFieldTypes"
}
}
},
"required": false,
"optional": false,
"docs": {
"tags": [{
"name": "internal",
"text": undefined
}],
"text": ""
},
"attribute": "type",
"reflect": false,
"defaultValue": "'password'"
}
};
}
static get elementRef() { return "el"; }
static get watchers() {
return [{
"propName": "type",
"methodName": "onTypeChange"
}];
}
}