Files
Brandy Carney 92d810338d refactor(textarea): remove legacy property and support for legacy syntax (#28993)
Issue number: internal

---------

## What is the current behavior?

In Ionic Framework v7, we [simplified the textarea
syntax](https://ionic.io/blog/ionic-7-is-here#simplified-form-control-syntax)
so that it was no longer required to be placed inside of an `ion-item`.
We maintained backwards compatibility by adding a `legacy` property
which allowed it to continue to be styled properly when written in the
following way:

```html
<ion-item>
  <ion-label>Label</ion-label>
  <ion-textarea></ion-textarea>
</ion-item>
```

While this was supported in v7, console warnings were logged to notify
developers that they needed to update this syntax for the best
accessibility experience.

## What is the new behavior?

- Removes the `legacy` property and support for the legacy syntax.
Developers should follow the [migration
guide](https://ionicframework.com/docs/api/textarea#migrating-from-legacy-textarea-syntax)
in the textarea documentation to update their apps. The new syntax
requires a `label` or `aria-label` on `ion-textarea`:
    ```html
    <ion-item>
      <ion-textarea label="Label"></ion-textarea>
    </ion-item>
    ```
- Removes the legacy tests under `textarea/test/legacy/` and all related
screenshots
- Removes the textarea usage in `input/test/legacy/spec`,
`item/test/disabled`, `item/test/legacy/disabled` and
`item/test/legacy/fill`

## Does this introduce a breaking change?

- [x] Yes
- [ ] No

1. Developers have had console warnings when using the legacy syntax
since the v7 release. The migration guide for the new textarea syntax is
outlined in the [Textarea
documentation](https://ionicframework.com/docs/api/textarea#migrating-from-legacy-textarea-syntax).
2. This change has been documented in the Breaking Changes document with
a link to the migration guide.

BREAKING CHANGE:

The `legacy` property and support for the legacy syntax, which involved
placing an `ion-textarea` inside of an `ion-item` with an `ion-label`,
have been removed from textarea. For more information on migrating from
the legacy textarea syntax, refer to the [Textarea
documentation](https://ionicframework.com/docs/api/textarea#migrating-from-legacy-textarea-syntax).

---------

Co-authored-by: ionitron <hi@ionicframework.com>
2024-02-08 13:27:51 -05:00

119 lines
3.3 KiB
TypeScript

import {
ChangeDetectionStrategy,
ChangeDetectorRef,
Component,
ElementRef,
EventEmitter,
HostListener,
Injector,
NgZone,
forwardRef,
} from '@angular/core';
import { NG_VALUE_ACCESSOR } from '@angular/forms';
import { ValueAccessor } from '@ionic/angular/common';
import type { TextareaChangeEventDetail, TextareaInputEventDetail, Components } from '@ionic/core/components';
import { defineCustomElement } from '@ionic/core/components/ion-textarea.js';
import { ProxyCmp, proxyOutputs } from './angular-component-lib/utils';
const TEXTAREA_INPUTS = [
'autoGrow',
'autocapitalize',
'autofocus',
'clearOnEdit',
'color',
'cols',
'counter',
'counterFormatter',
'debounce',
'disabled',
'enterkeyhint',
'errorText',
'fill',
'helperText',
'inputmode',
'label',
'labelPlacement',
'maxlength',
'minlength',
'mode',
'name',
'placeholder',
'readonly',
'required',
'rows',
'shape',
'spellcheck',
'value',
'wrap',
];
/**
* Pulling the provider into an object and using PURE works
* around an ng-packagr issue that causes
* components with multiple decorators and
* a provider to be re-assigned. This re-assignment
* is not supported by Webpack and causes treeshaking
* to not work on these kinds of components.
*/
const accessorProvider = {
provide: NG_VALUE_ACCESSOR,
useExisting: /*@__PURE__*/ forwardRef(() => IonTextarea),
multi: true,
};
@ProxyCmp({
defineCustomElementFn: defineCustomElement,
inputs: TEXTAREA_INPUTS,
methods: ['setFocus', 'getInputElement'],
})
@Component({
selector: 'ion-textarea',
changeDetection: ChangeDetectionStrategy.OnPush,
template: '<ng-content></ng-content>',
// eslint-disable-next-line @angular-eslint/no-inputs-metadata-property
inputs: TEXTAREA_INPUTS,
providers: [accessorProvider],
standalone: true,
})
export class IonTextarea extends ValueAccessor {
protected el: HTMLElement;
constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone, injector: Injector) {
super(injector, r);
c.detach();
this.el = r.nativeElement;
proxyOutputs(this, this.el, ['ionChange', 'ionInput', 'ionBlur', 'ionFocus']);
}
@HostListener('ionInput', ['$event.target'])
handleIonInput(el: HTMLIonTextareaElement): void {
this.handleValueChange(el, el.value);
}
}
export declare interface IonTextarea extends Components.IonTextarea {
/**
* The `ionChange` event is fired when the user modifies the textarea's value.
Unlike the `ionInput` event, the `ionChange` event is fired when
the element loses focus after its value has been modified.
*/
ionChange: EventEmitter<CustomEvent<TextareaChangeEventDetail>>;
/**
* The `ionInput` event is fired each time the user modifies the textarea's value.
Unlike the `ionChange` event, the `ionInput` event is fired for each alteration
to the textarea's value. This typically happens for each keystroke as the user types.
When `clearOnEdit` is enabled, the `ionInput` event will be fired when
the user clears the textarea by performing a keydown event.
*/
ionInput: EventEmitter<CustomEvent<TextareaInputEventDetail>>;
/**
* Emitted when the input loses focus.
*/
ionBlur: EventEmitter<CustomEvent<FocusEvent>>;
/**
* Emitted when the input has focus.
*/
ionFocus: EventEmitter<CustomEvent<FocusEvent>>;
}