mirror of
https://github.com/ionic-team/ionic-framework.git
synced 2025-11-10 00:27:41 +08:00
fix(textarea): reposition textarea when keybard appears (#18098)
fixes #17847
This commit is contained in:
@ -57,8 +57,6 @@
|
||||
// --------------------------------------------------
|
||||
|
||||
:host-context(ion-item) {
|
||||
position: static;
|
||||
|
||||
align-self: baseline;
|
||||
}
|
||||
|
||||
@ -79,7 +77,8 @@
|
||||
display: block;
|
||||
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
max-width: 100%;
|
||||
max-height: 100%;
|
||||
|
||||
border: 0;
|
||||
|
||||
@ -106,3 +105,19 @@
|
||||
.native-textarea[disabled] {
|
||||
opacity: .4;
|
||||
}
|
||||
|
||||
// Input Cover: Unfocused
|
||||
// --------------------------------------------------
|
||||
// The input cover is the div that actually receives the
|
||||
// tap/click event when scroll assist is configured to true.
|
||||
// This make it so the native input element is not clickable.
|
||||
// This will only show when the scroll assist is configured
|
||||
// otherwise the .input-cover will not be rendered at all
|
||||
// The input cover is not clickable when the input is disabled
|
||||
.cloned-input {
|
||||
@include position(0, null, null, 0);
|
||||
|
||||
position: absolute;
|
||||
|
||||
pointer-events: none;
|
||||
}
|
||||
@ -164,12 +164,30 @@ export class Textarea implements ComponentInterface {
|
||||
*/
|
||||
@Event() ionFocus!: EventEmitter<void>;
|
||||
|
||||
/**
|
||||
* Emitted when the input has been created.
|
||||
* @internal
|
||||
*/
|
||||
@Event() ionInputDidLoad!: EventEmitter<void>;
|
||||
|
||||
/**
|
||||
* Emitted when the input has been removed.
|
||||
* @internal
|
||||
*/
|
||||
@Event() ionInputDidUnload!: EventEmitter<void>;
|
||||
|
||||
componentWillLoad() {
|
||||
this.emitStyle();
|
||||
}
|
||||
|
||||
componentDidLoad() {
|
||||
this.debounceChanged();
|
||||
|
||||
this.ionInputDidLoad.emit();
|
||||
}
|
||||
|
||||
componentDidUnload() {
|
||||
this.ionInputDidUnload.emit();
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -2,7 +2,7 @@ const cloneMap = new WeakMap<HTMLElement, HTMLElement>();
|
||||
|
||||
export function relocateInput(
|
||||
componentEl: HTMLElement,
|
||||
inputEl: HTMLInputElement,
|
||||
inputEl: HTMLInputElement | HTMLTextAreaElement,
|
||||
shouldRelocate: boolean,
|
||||
inputRelativeY = 0
|
||||
) {
|
||||
@ -17,11 +17,11 @@ export function relocateInput(
|
||||
}
|
||||
}
|
||||
|
||||
export function isFocused(input: HTMLInputElement): boolean {
|
||||
export function isFocused(input: HTMLInputElement | HTMLTextAreaElement): boolean {
|
||||
return input === (input as any).getRootNode().activeElement;
|
||||
}
|
||||
|
||||
function addClone(componentEl: HTMLElement, inputEl: HTMLInputElement, inputRelativeY: number) {
|
||||
function addClone(componentEl: HTMLElement, inputEl: HTMLInputElement | HTMLTextAreaElement, inputRelativeY: number) {
|
||||
// this allows for the actual input to receive the focus from
|
||||
// the user's touch event, but before it receives focus, it
|
||||
// moves the actual input to a location that will not screw
|
||||
@ -34,7 +34,7 @@ function addClone(componentEl: HTMLElement, inputEl: HTMLInputElement, inputRela
|
||||
const parentEl = inputEl.parentNode!;
|
||||
|
||||
// DOM WRITES
|
||||
const clonedEl = inputEl.cloneNode(false) as HTMLInputElement;
|
||||
const clonedEl = inputEl.cloneNode(false) as HTMLElement;
|
||||
clonedEl.classList.add('cloned-input');
|
||||
clonedEl.tabIndex = -1;
|
||||
parentEl.appendChild(clonedEl);
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
import { isFocused, relocateInput } from './common';
|
||||
|
||||
export function enableHideCaretOnScroll(componentEl: HTMLElement, inputEl: HTMLInputElement | undefined, scrollEl: HTMLIonContentElement | undefined) {
|
||||
export function enableHideCaretOnScroll(componentEl: HTMLElement, inputEl: HTMLInputElement | HTMLTextAreaElement | undefined, scrollEl: HTMLIonContentElement | undefined) {
|
||||
if (!scrollEl || !inputEl) {
|
||||
return () => { return; };
|
||||
}
|
||||
|
||||
@ -5,7 +5,7 @@ import { getScrollData } from './scroll-data';
|
||||
|
||||
export function enableScrollAssist(
|
||||
componentEl: HTMLElement,
|
||||
inputEl: HTMLInputElement,
|
||||
inputEl: HTMLInputElement | HTMLTextAreaElement,
|
||||
contentEl: HTMLIonContentElement,
|
||||
keyboardHeight: number
|
||||
) {
|
||||
@ -45,7 +45,7 @@ export function enableScrollAssist(
|
||||
|
||||
function jsSetFocus(
|
||||
componentEl: HTMLElement,
|
||||
inputEl: HTMLInputElement,
|
||||
inputEl: HTMLInputElement | HTMLTextAreaElement,
|
||||
contentEl: HTMLIonContentElement,
|
||||
keyboardHeight: number
|
||||
) {
|
||||
|
||||
@ -25,7 +25,7 @@ export function startInputShims(
|
||||
const scrollAssistMap = new WeakMap<HTMLElement, () => void>();
|
||||
|
||||
function registerInput(componentEl: HTMLElement) {
|
||||
const inputEl = (componentEl.shadowRoot || componentEl).querySelector('input');
|
||||
const inputEl = (componentEl.shadowRoot || componentEl).querySelector('input') || (componentEl.shadowRoot || componentEl).querySelector('textarea');
|
||||
const scrollEl = componentEl.closest('ion-content');
|
||||
|
||||
if (!inputEl) {
|
||||
@ -70,9 +70,9 @@ export function startInputShims(
|
||||
}
|
||||
|
||||
// Input might be already loaded in the DOM before ion-device-hacks did.
|
||||
// At this point we need to look for all the ion-inputs not registered yet
|
||||
// At this point we need to look for all of the inputs not registered yet
|
||||
// and register them.
|
||||
const inputs = Array.from(doc.querySelectorAll('ion-input'));
|
||||
const inputs = Array.from(doc.querySelectorAll('ion-input, ion-textarea')) as HTMLElement[];
|
||||
for (const input of inputs) {
|
||||
registerInput(input);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user