diff --git a/core/src/components/textarea/textarea.scss b/core/src/components/textarea/textarea.scss index 58399fb53d..7f7cffa130 100644 --- a/core/src/components/textarea/textarea.scss +++ b/core/src/components/textarea/textarea.scss @@ -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; +} \ No newline at end of file diff --git a/core/src/components/textarea/textarea.tsx b/core/src/components/textarea/textarea.tsx index 13dd1fe41a..949f362364 100644 --- a/core/src/components/textarea/textarea.tsx +++ b/core/src/components/textarea/textarea.tsx @@ -164,12 +164,30 @@ export class Textarea implements ComponentInterface { */ @Event() ionFocus!: EventEmitter; + /** + * Emitted when the input has been created. + * @internal + */ + @Event() ionInputDidLoad!: EventEmitter; + + /** + * Emitted when the input has been removed. + * @internal + */ + @Event() ionInputDidUnload!: EventEmitter; + componentWillLoad() { this.emitStyle(); } componentDidLoad() { this.debounceChanged(); + + this.ionInputDidLoad.emit(); + } + + componentDidUnload() { + this.ionInputDidUnload.emit(); } /** diff --git a/core/src/utils/input-shims/hacks/common.ts b/core/src/utils/input-shims/hacks/common.ts index 91351e85fb..04fa1b40ca 100644 --- a/core/src/utils/input-shims/hacks/common.ts +++ b/core/src/utils/input-shims/hacks/common.ts @@ -2,7 +2,7 @@ const cloneMap = new WeakMap(); 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); diff --git a/core/src/utils/input-shims/hacks/hide-caret.ts b/core/src/utils/input-shims/hacks/hide-caret.ts index 85d454e8bf..2162166954 100644 --- a/core/src/utils/input-shims/hacks/hide-caret.ts +++ b/core/src/utils/input-shims/hacks/hide-caret.ts @@ -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; }; } diff --git a/core/src/utils/input-shims/hacks/scroll-assist.ts b/core/src/utils/input-shims/hacks/scroll-assist.ts index bf44473f33..db0f0be923 100644 --- a/core/src/utils/input-shims/hacks/scroll-assist.ts +++ b/core/src/utils/input-shims/hacks/scroll-assist.ts @@ -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 ) { diff --git a/core/src/utils/input-shims/input-shims.ts b/core/src/utils/input-shims/input-shims.ts index 1a873870cc..daa0ea5a6e 100644 --- a/core/src/utils/input-shims/input-shims.ts +++ b/core/src/utils/input-shims/input-shims.ts @@ -25,7 +25,7 @@ export function startInputShims( const scrollAssistMap = new WeakMap 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); }