diff --git a/src/core/directives/auto-rows.ts b/src/core/directives/auto-rows.ts
new file mode 100644
index 000000000..05d4f12bc
--- /dev/null
+++ b/src/core/directives/auto-rows.ts
@@ -0,0 +1,79 @@
+// (C) Copyright 2015 Moodle Pty Ltd.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+import { Directive, ElementRef, HostListener, Output, EventEmitter, AfterViewInit } from '@angular/core';
+
+/**
+ * Directive to adapt a textarea rows depending on the input text. It's based on Moodle's data-auto-rows.
+ *
+ * @description
+ * Usage:
+ *
+ */
+@Directive({
+ selector: 'textarea[core-auto-rows], ion-textarea[core-auto-rows]',
+})
+export class CoreAutoRowsDirective implements AfterViewInit {
+
+ protected height = 0;
+
+ @Output() onResize: EventEmitter; // Emit when resizing the textarea.
+
+ constructor(protected element: ElementRef) {
+ this.onResize = new EventEmitter();
+ }
+
+ @HostListener('input') onInput(): void {
+ this.resize();
+ }
+
+ @HostListener('change') onChange(): void {
+ // Fired on reset. Wait to the change to be finished.
+ setTimeout(() => {
+ this.resize();
+ }, 300);
+ }
+
+ /**
+ * Resize after content.
+ */
+ ngAfterViewInit(): void {
+ // Wait for rendering of child views.
+ setTimeout(() => {
+ this.resize();
+ }, 300);
+ }
+
+ /**
+ * Resize the textarea.
+ */
+ protected resize(): void {
+ let nativeElement = this.element.nativeElement;
+ if (nativeElement.tagName == 'ION-TEXTAREA') {
+ // The first child of ion-textarea is the actual textarea element.
+ nativeElement = nativeElement.firstElementChild;
+ }
+
+ // Set height to 1px to force scroll height to calculate correctly.
+ nativeElement.style.height = '1px';
+ nativeElement.style.height = nativeElement.scrollHeight + 'px';
+
+ // Emit event when resizing.
+ if (this.height != nativeElement.scrollHeight) {
+ this.height = nativeElement.scrollHeight;
+ this.onResize.emit();
+ }
+ }
+
+}
diff --git a/src/core/directives/directives.module.ts b/src/core/directives/directives.module.ts
index 06e4c6fa5..494c1e1d2 100644
--- a/src/core/directives/directives.module.ts
+++ b/src/core/directives/directives.module.ts
@@ -23,6 +23,7 @@ import { CoreLongPressDirective } from './long-press';
import { CoreSupressEventsDirective } from './supress-events';
import { CoreFaIconDirective } from './fa-icon';
import { CoreUserLinkDirective } from './user-link';
+import { CoreAutoRowsDirective } from './auto-rows';
@NgModule({
declarations: [
@@ -35,6 +36,7 @@ import { CoreUserLinkDirective } from './user-link';
CoreFabDirective,
CoreFaIconDirective,
CoreUserLinkDirective,
+ CoreAutoRowsDirective,
],
imports: [],
exports: [
@@ -47,6 +49,7 @@ import { CoreUserLinkDirective } from './user-link';
CoreFabDirective,
CoreFaIconDirective,
CoreUserLinkDirective,
+ CoreAutoRowsDirective,
],
})
export class CoreDirectivesModule {}