mirror of
https://github.com/ionic-team/ionic-framework.git
synced 2025-11-05 05:38:49 +08:00
Issue number: resolves #28431
---------
<!-- Please do not submit updates to dependencies unless it fixes an
issue. -->
<!-- Please try to limit your pull request to one type (bugfix, feature,
etc). Submit multiple pull requests if needed. -->
## What is the current behavior?
<!-- Please describe the current behavior that you are modifying. -->
My previous attempt at fixing
https://github.com/ionic-team/ionic-framework/issues/28358 caused inputs
to no longer be correctly proxied to the underlying components. This was
an attempt to work around an underlying ng-packagr bug (see linked
thread for more info).
## What is the new behavior?
<!-- Please describe the behavior or changes that are being added by
this PR. -->
I decided it would be best to continue using `ProxyCmp` (since we know
that works) and find an alternative to working around the ng-packagr
bug. I spoke with the Angular team, and they recommended pulling the
provider into its own object. `forwardRef` is now required since we are
referencing the component before it is declared.
- Revert
82d6309ef1
- Moves provider to an object to avoid ng-packagr issue
- I reverted the proxy e2e tests. These are no longer needed since we
are not ejecting from the typical `ProxyCmp` usage anymore.
## Does this introduce a breaking change?
- [ ] Yes
- [x] No
<!-- If this introduces a breaking change, please describe the impact
and migration path for existing applications below. -->
## Other information
<!-- Any other information that is important to this PR such as
screenshots of how the component looks before and after the change. -->
Dev build: `7.5.3-dev.11698699090.1151d73f`
Verified that the issue is fixed with the repro provided in
https://github.com/ionic-team/ionic-framework/issues/28431
Also verified that this does not regress the issue described in
https://github.com/ionic-team/ionic-framework/issues/28358.
118 lines
3.4 KiB
TypeScript
118 lines
3.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 { SearchbarInputEventDetail, SearchbarChangeEventDetail, Components } from '@ionic/core/components';
|
|
import { defineCustomElement } from '@ionic/core/components/ion-searchbar.js';
|
|
|
|
import { ProxyCmp, proxyOutputs } from './angular-component-lib/utils';
|
|
|
|
const SEARCHBAR_INPUTS = [
|
|
'animated',
|
|
'autocomplete',
|
|
'autocorrect',
|
|
'cancelButtonIcon',
|
|
'cancelButtonText',
|
|
'clearIcon',
|
|
'color',
|
|
'debounce',
|
|
'disabled',
|
|
'enterkeyhint',
|
|
'inputmode',
|
|
'mode',
|
|
'name',
|
|
'placeholder',
|
|
'searchIcon',
|
|
'showCancelButton',
|
|
'showClearButton',
|
|
'spellcheck',
|
|
'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(() => IonSearchbar),
|
|
multi: true,
|
|
};
|
|
|
|
@ProxyCmp({
|
|
defineCustomElementFn: defineCustomElement,
|
|
inputs: SEARCHBAR_INPUTS,
|
|
methods: ['setFocus', 'getInputElement'],
|
|
})
|
|
@Component({
|
|
selector: 'ion-searchbar',
|
|
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
template: '<ng-content></ng-content>',
|
|
// eslint-disable-next-line @angular-eslint/no-inputs-metadata-property
|
|
inputs: SEARCHBAR_INPUTS,
|
|
providers: [accessorProvider],
|
|
standalone: true,
|
|
})
|
|
export class IonSearchbar 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', 'ionCancel', 'ionClear', 'ionBlur', 'ionFocus']);
|
|
}
|
|
|
|
@HostListener('ionInput', ['$event.target'])
|
|
handleIonInput(el: HTMLIonSearchbarElement): void {
|
|
this.handleValueChange(el, el.value);
|
|
}
|
|
}
|
|
|
|
export declare interface IonSearchbar extends Components.IonSearchbar {
|
|
/**
|
|
* Emitted when the `value` of the `ion-searchbar` element has changed.
|
|
*/
|
|
ionInput: EventEmitter<CustomEvent<SearchbarInputEventDetail>>;
|
|
/**
|
|
* The `ionChange` event is fired for `<ion-searchbar>` elements when the user
|
|
modifies the element's value. Unlike the `ionInput` event, the `ionChange`
|
|
event is not necessarily fired for each alteration to an element's value.
|
|
|
|
The `ionChange` event is fired when the value has been committed
|
|
by the user. This can happen when the element loses focus or
|
|
when the "Enter" key is pressed. `ionChange` can also fire
|
|
when clicking the clear or cancel buttons.
|
|
*/
|
|
ionChange: EventEmitter<CustomEvent<SearchbarChangeEventDetail>>;
|
|
/**
|
|
* Emitted when the cancel button is clicked.
|
|
*/
|
|
ionCancel: EventEmitter<CustomEvent<void>>;
|
|
/**
|
|
* Emitted when the clear input button is clicked.
|
|
*/
|
|
ionClear: EventEmitter<CustomEvent<void>>;
|
|
/**
|
|
* Emitted when the input loses focus.
|
|
*/
|
|
ionBlur: EventEmitter<CustomEvent<void>>;
|
|
/**
|
|
* Emitted when the input has focus.
|
|
*/
|
|
ionFocus: EventEmitter<CustomEvent<void>>;
|
|
}
|