feat(textarea): add option to expand textarea as value changes (#16916)

* feat(textarea): add autoGrow - set height to scrollHeight

* change 1px to inherit, remove additional 4px
This commit is contained in:
Adam LaCombe
2019-05-07 16:52:24 -04:00
committed by Liam DeBeasi
parent 669ec0da3d
commit cc8678ad58
7 changed files with 34 additions and 3 deletions

View File

@ -857,7 +857,7 @@ export class IonText {
proxyInputs(IonText, ['color', 'mode']); proxyInputs(IonText, ['color', 'mode']);
export declare interface IonTextarea extends StencilComponents<'IonTextarea'> {} export declare interface IonTextarea extends StencilComponents<'IonTextarea'> {}
@Component({ selector: 'ion-textarea', changeDetection: 0, template: '<ng-content></ng-content>', inputs: ['mode', 'color', 'autocapitalize', 'autofocus', 'clearOnEdit', 'debounce', 'disabled', 'maxlength', 'minlength', 'name', 'placeholder', 'readonly', 'required', 'spellcheck', 'cols', 'rows', 'wrap', 'value'] }) @Component({ selector: 'ion-textarea', changeDetection: 0, template: '<ng-content></ng-content>', inputs: ['mode', 'color', 'autocapitalize', 'autofocus', 'clearOnEdit', 'debounce', 'disabled', 'maxlength', 'minlength', 'name', 'placeholder', 'readonly', 'required', 'spellcheck', 'cols', 'rows', 'wrap', 'autoGrow', 'value'] })
export class IonTextarea { export class IonTextarea {
ionChange!: EventEmitter<CustomEvent>; ionChange!: EventEmitter<CustomEvent>;
ionInput!: EventEmitter<CustomEvent>; ionInput!: EventEmitter<CustomEvent>;
@ -871,7 +871,7 @@ export class IonTextarea {
} }
} }
proxyMethods(IonTextarea, ['setFocus', 'getInputElement']); proxyMethods(IonTextarea, ['setFocus', 'getInputElement']);
proxyInputs(IonTextarea, ['mode', 'color', 'autocapitalize', 'autofocus', 'clearOnEdit', 'debounce', 'disabled', 'maxlength', 'minlength', 'name', 'placeholder', 'readonly', 'required', 'spellcheck', 'cols', 'rows', 'wrap', 'value']); proxyInputs(IonTextarea, ['mode', 'color', 'autocapitalize', 'autofocus', 'clearOnEdit', 'debounce', 'disabled', 'maxlength', 'minlength', 'name', 'placeholder', 'readonly', 'required', 'spellcheck', 'cols', 'rows', 'wrap', 'autoGrow', 'value']);
export declare interface IonThumbnail extends StencilComponents<'IonThumbnail'> {} export declare interface IonThumbnail extends StencilComponents<'IonThumbnail'> {}
@Component({ selector: 'ion-thumbnail', changeDetection: 0, template: '<ng-content></ng-content>' }) @Component({ selector: 'ion-thumbnail', changeDetection: 0, template: '<ng-content></ng-content>' })

View File

@ -1096,6 +1096,7 @@ ion-text,prop,color,string | undefined,undefined,false,false
ion-text,prop,mode,"ios" | "md",undefined,false,false ion-text,prop,mode,"ios" | "md",undefined,false,false
ion-textarea,scoped ion-textarea,scoped
ion-textarea,prop,autoGrow,boolean,false,false,false
ion-textarea,prop,autocapitalize,string,'none',false,false ion-textarea,prop,autocapitalize,string,'none',false,false
ion-textarea,prop,autofocus,boolean,false,false,false ion-textarea,prop,autofocus,boolean,false,false,false
ion-textarea,prop,clearOnEdit,boolean,false,false,false ion-textarea,prop,clearOnEdit,boolean,false,false,false

View File

@ -4604,6 +4604,10 @@ export namespace Components {
} }
interface IonTextarea { interface IonTextarea {
/**
* If `true`, the element height will increase based on the value.
*/
'autoGrow': boolean;
/** /**
* Indicates whether and how the text value should be automatically capitalized as it is entered/edited by the user. * Indicates whether and how the text value should be automatically capitalized as it is entered/edited by the user.
*/ */
@ -4686,6 +4690,10 @@ export namespace Components {
'wrap'?: 'hard' | 'soft' | 'off'; 'wrap'?: 'hard' | 'soft' | 'off';
} }
interface IonTextareaAttributes extends StencilHTMLAttributes { interface IonTextareaAttributes extends StencilHTMLAttributes {
/**
* If `true`, the element height will increase based on the value.
*/
'autoGrow'?: boolean;
/** /**
* Indicates whether and how the text value should be automatically capitalized as it is entered/edited by the user. * Indicates whether and how the text value should be automatically capitalized as it is entered/edited by the user.
*/ */

View File

@ -194,6 +194,7 @@ export default Example;
| Property | Attribute | Description | Type | Default | | Property | Attribute | Description | Type | Default |
| ---------------- | ---------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------- | -------------- | | ---------------- | ---------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------- | -------------- |
| `autoGrow` | `auto-grow` | If `true`, the element height will increase based on the value. | `boolean` | `false` |
| `autocapitalize` | `autocapitalize` | Indicates whether and how the text value should be automatically capitalized as it is entered/edited by the user. | `string` | `'none'` | | `autocapitalize` | `autocapitalize` | Indicates whether and how the text value should be automatically capitalized as it is entered/edited by the user. | `string` | `'none'` |
| `autofocus` | `autofocus` | This Boolean attribute lets you specify that a form control should have input focus when the page loads. | `boolean` | `false` | | `autofocus` | `autofocus` | This Boolean attribute lets you specify that a form control should have input focus when the page loads. | `boolean` | `false` |
| `clearOnEdit` | `clear-on-edit` | If `true`, the value will be cleared after focus upon edit. Defaults to `true` when `type` is `"password"`, `false` for all other types. | `boolean` | `false` | | `clearOnEdit` | `clear-on-edit` | If `true`, the value will be cleared after focus upon edit. Defaults to `true` when `type` is `"password"`, `false` for all other types. | `boolean` | `false` |

View File

@ -66,6 +66,11 @@
<ion-label color="primary">Clear on Edit</ion-label> <ion-label color="primary">Clear on Edit</ion-label>
<ion-textarea clear-on-edit="true"></ion-textarea> <ion-textarea clear-on-edit="true"></ion-textarea>
</ion-item> </ion-item>
<ion-item>
<ion-label color="primary">Autogrow</ion-label>
<ion-textarea auto-grow="true"></ion-textarea>
</ion-item>
</ion-list> </ion-list>
<div text-center> <div text-center>

View File

@ -15,7 +15,8 @@
<ion-textarea placeholder="Textarea"></ion-textarea> <ion-textarea placeholder="Textarea"></ion-textarea>
<ion-textarea value="value"></ion-textarea> <ion-textarea value="value"></ion-textarea>
<ion-textarea value="44"></ion-textarea> <ion-textarea value="44"></ion-textarea>
<ion-textarea placeholder="Custom" class="custom"></textarea> <ion-textarea placeholder="Custom" class="custom"></ion-textarea>
<ion-textarea placeholder="Auto Grow!" auto-grow="true"></ion-textarea>
<style> <style>
.custom { .custom {

View File

@ -119,6 +119,11 @@ export class Textarea implements ComponentInterface {
*/ */
@Prop() wrap?: 'hard' | 'soft' | 'off'; @Prop() wrap?: 'hard' | 'soft' | 'off';
/**
* If `true`, the element height will increase based on the value.
*/
@Prop() autoGrow = false;
/** /**
* The value of the textarea. * The value of the textarea.
*/ */
@ -134,6 +139,7 @@ export class Textarea implements ComponentInterface {
if (nativeInput && nativeInput.value !== value) { if (nativeInput && nativeInput.value !== value) {
nativeInput.value = value; nativeInput.value = value;
} }
this.runAutoGrow();
this.emitStyle(); this.emitStyle();
this.ionChange.emit({ value }); this.ionChange.emit({ value });
} }
@ -183,9 +189,18 @@ export class Textarea implements ComponentInterface {
componentDidLoad() { componentDidLoad() {
this.debounceChanged(); this.debounceChanged();
this.runAutoGrow();
this.ionInputDidLoad.emit(); this.ionInputDidLoad.emit();
} }
private runAutoGrow() {
if (this.nativeInput && this.autoGrow) {
this.nativeInput.style.height = 'inherit';
this.nativeInput.style.height = this.nativeInput.scrollHeight + 'px';
}
}
componentDidUnload() { componentDidUnload() {
this.ionInputDidUnload.emit(); this.ionInputDidUnload.emit();
} }