mirror of
				https://github.com/ionic-team/ionic-framework.git
				synced 2025-11-04 03:48:13 +08:00 
			
		
		
		
	Issue number: internal --------- ## What is the current behavior? In Ionic Framework v7, we [simplified the input 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-input></ion-input> </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/input#migrating-from-legacy-input-syntax) in the input documentation to update their apps. The new syntax requires a `label` or `aria-label` on `ion-input`: ```html <ion-item> <ion-input label="Label"></ion-input> </ion-item> ``` - Removes the legacy tests under under `input/test/legacy/` and all related screenshots - Removes the input usage from `item/test/a11y`, `item/test/counter`, `item/test/disabled`, `item/test/highlight`, `item/test/legacy/alignment`, `item/test/legacy/disabled`, `item/test/legacy/fill`, and `item/test/legacy/form` and all related screenshots if the test was removed ## 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 input syntax is outlined in the [Input documentation](https://ionicframework.com/docs/api/input#migrating-from-legacy-input-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-input` inside of an `ion-item` with an `ion-label`, have been removed from input. For more information on migrating from the legacy input syntax, refer to the [Input documentation](https://ionicframework.com/docs/api/input#migrating-from-legacy-input-syntax). --------- Co-authored-by: ionitron <hi@ionicframework.com>
		
			
				
	
	
		
			154 lines
		
	
	
		
			4.4 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
			
		
		
	
	
			154 lines
		
	
	
		
			4.4 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 {
 | 
						|
  InputInputEventDetail as IIonInputInputInputEventDetail,
 | 
						|
  InputChangeEventDetail as IIonInputInputChangeEventDetail,
 | 
						|
  Components,
 | 
						|
} from '@ionic/core/components';
 | 
						|
import { defineCustomElement } from '@ionic/core/components/ion-input.js';
 | 
						|
 | 
						|
import { ProxyCmp, proxyOutputs } from './angular-component-lib/utils';
 | 
						|
 | 
						|
const INPUT_INPUTS = [
 | 
						|
  'accept',
 | 
						|
  'autocapitalize',
 | 
						|
  'autocomplete',
 | 
						|
  'autocorrect',
 | 
						|
  'autofocus',
 | 
						|
  'clearInput',
 | 
						|
  'clearOnEdit',
 | 
						|
  'color',
 | 
						|
  'counter',
 | 
						|
  'counterFormatter',
 | 
						|
  'debounce',
 | 
						|
  'disabled',
 | 
						|
  'enterkeyhint',
 | 
						|
  'errorText',
 | 
						|
  'fill',
 | 
						|
  'helperText',
 | 
						|
  'inputmode',
 | 
						|
  'label',
 | 
						|
  'labelPlacement',
 | 
						|
  'max',
 | 
						|
  'maxlength',
 | 
						|
  'min',
 | 
						|
  'minlength',
 | 
						|
  'mode',
 | 
						|
  'multiple',
 | 
						|
  'name',
 | 
						|
  'pattern',
 | 
						|
  'placeholder',
 | 
						|
  'readonly',
 | 
						|
  'required',
 | 
						|
  'shape',
 | 
						|
  'size',
 | 
						|
  'spellcheck',
 | 
						|
  'step',
 | 
						|
  'type',
 | 
						|
  'value',
 | 
						|
];
 | 
						|
 | 
						|
/**
 | 
						|
 * 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(() => IonInput),
 | 
						|
  multi: true,
 | 
						|
};
 | 
						|
 | 
						|
@ProxyCmp({
 | 
						|
  defineCustomElementFn: defineCustomElement,
 | 
						|
  inputs: INPUT_INPUTS,
 | 
						|
  methods: ['setFocus', 'getInputElement'],
 | 
						|
})
 | 
						|
@Component({
 | 
						|
  selector: 'ion-input',
 | 
						|
  changeDetection: ChangeDetectionStrategy.OnPush,
 | 
						|
  template: '<ng-content></ng-content>',
 | 
						|
  // eslint-disable-next-line @angular-eslint/no-inputs-metadata-property
 | 
						|
  inputs: INPUT_INPUTS,
 | 
						|
  providers: [accessorProvider],
 | 
						|
  standalone: true,
 | 
						|
})
 | 
						|
export class IonInput 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, ['ionInput', 'ionChange', 'ionBlur', 'ionFocus']);
 | 
						|
  }
 | 
						|
 | 
						|
  @HostListener('ionInput', ['$event.target'])
 | 
						|
  handleIonInput(el: HTMLIonInputElement): void {
 | 
						|
    this.handleValueChange(el, el.value);
 | 
						|
  }
 | 
						|
 | 
						|
  registerOnChange(fn: (_: any) => void): void {
 | 
						|
    super.registerOnChange((value: string) => {
 | 
						|
      if (this.type === 'number') {
 | 
						|
        /**
 | 
						|
         * If the input type is `number`, we need to convert the value to a number
 | 
						|
         * when the value is not empty. If the value is empty, we want to treat
 | 
						|
         * the value as null.
 | 
						|
         */
 | 
						|
        fn(value === '' ? null : parseFloat(value));
 | 
						|
      } else {
 | 
						|
        fn(value);
 | 
						|
      }
 | 
						|
    });
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
export declare interface IonInput extends Components.IonInput {
 | 
						|
  /**
 | 
						|
   * The `ionInput` event is fired each time the user modifies the input's value.
 | 
						|
Unlike the `ionChange` event, the `ionInput` event is fired for each alteration
 | 
						|
to the input's value. This typically happens for each keystroke as the user types.
 | 
						|
 | 
						|
For elements that accept text input (`type=text`, `type=tel`, etc.), the interface
 | 
						|
is [`InputEvent`](https://developer.mozilla.org/en-US/docs/Web/API/InputEvent); for others,
 | 
						|
the interface is [`Event`](https://developer.mozilla.org/en-US/docs/Web/API/Event). If
 | 
						|
the input is cleared on edit, the type is `null`.
 | 
						|
   */
 | 
						|
  ionInput: EventEmitter<CustomEvent<IIonInputInputInputEventDetail>>;
 | 
						|
  /**
 | 
						|
   * The `ionChange` event is fired when the user modifies the input's value.
 | 
						|
Unlike the `ionInput` event, the `ionChange` event is only fired when changes
 | 
						|
are committed, not as the user types.
 | 
						|
 | 
						|
Depending on the way the users interacts with the element, the `ionChange`
 | 
						|
event fires at a different moment:
 | 
						|
- When the user commits the change explicitly (e.g. by selecting a date
 | 
						|
from a date picker for `<ion-input type="date">`, pressing the "Enter" key, etc.).
 | 
						|
- When the element loses focus after its value has changed: for elements
 | 
						|
where the user's interaction is typing.
 | 
						|
   */
 | 
						|
  ionChange: EventEmitter<CustomEvent<IIonInputInputChangeEventDetail>>;
 | 
						|
  /**
 | 
						|
   * Emitted when the input loses focus.
 | 
						|
   */
 | 
						|
  ionBlur: EventEmitter<CustomEvent<FocusEvent>>;
 | 
						|
  /**
 | 
						|
   * Emitted when the input has focus.
 | 
						|
   */
 | 
						|
  ionFocus: EventEmitter<CustomEvent<FocusEvent>>;
 | 
						|
}
 |