Skip to content

Commit

Permalink
feat(picker): add ability to use picker inline (#26336)
Browse files Browse the repository at this point in the history
  • Loading branch information
liamdebeasi committed Nov 22, 2022
1 parent f23fb34 commit c0a8501
Show file tree
Hide file tree
Showing 17 changed files with 480 additions and 35 deletions.
1 change: 1 addition & 0 deletions angular/src/directives/proxies-list.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ export const DIRECTIVES = [
d.IonNav,
d.IonNavLink,
d.IonNote,
d.IonPicker,
d.IonProgressBar,
d.IonRadio,
d.IonRadioGroup,
Expand Down
61 changes: 61 additions & 0 deletions angular/src/directives/proxies.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1418,6 +1418,67 @@ export class IonNote {
}
}

import type { OverlayEventDetail as IPickerOverlayEventDetail } from '@ionic/core';
export declare interface IonPicker extends Components.IonPicker {
/**
* Emitted after the picker has presented.
*/
ionPickerDidPresent: EventEmitter<CustomEvent<void>>;
/**
* Emitted before the picker has presented.
*/
ionPickerWillPresent: EventEmitter<CustomEvent<void>>;
/**
* Emitted before the picker has dismissed.
*/
ionPickerWillDismiss: EventEmitter<CustomEvent<IPickerOverlayEventDetail>>;
/**
* Emitted after the picker has dismissed.
*/
ionPickerDidDismiss: EventEmitter<CustomEvent<IPickerOverlayEventDetail>>;
/**
* Emitted after the picker has presented.
Shorthand for ionPickerWillDismiss.
*/
didPresent: EventEmitter<CustomEvent<void>>;
/**
* Emitted before the picker has presented.
Shorthand for ionPickerWillPresent.
*/
willPresent: EventEmitter<CustomEvent<void>>;
/**
* Emitted before the picker has dismissed.
Shorthand for ionPickerWillDismiss.
*/
willDismiss: EventEmitter<CustomEvent<IPickerOverlayEventDetail>>;
/**
* Emitted after the picker has dismissed.
Shorthand for ionPickerDidDismiss.
*/
didDismiss: EventEmitter<CustomEvent<IPickerOverlayEventDetail>>;

}

@ProxyCmp({
defineCustomElementFn: undefined,
inputs: ['animated', 'backdropDismiss', 'buttons', 'columns', 'cssClass', 'duration', 'enterAnimation', 'htmlAttributes', 'isOpen', 'keyboardClose', 'leaveAnimation', 'mode', 'showBackdrop', 'trigger'],
methods: ['present', 'dismiss', 'onDidDismiss', 'onWillDismiss', 'getColumn']
})
@Component({
selector: 'ion-picker',
changeDetection: ChangeDetectionStrategy.OnPush,
template: '<ng-content></ng-content>',
inputs: ['animated', 'backdropDismiss', 'buttons', 'columns', 'cssClass', 'duration', 'enterAnimation', 'htmlAttributes', 'isOpen', 'keyboardClose', 'leaveAnimation', 'mode', 'showBackdrop', 'trigger']
})
export class IonPicker {
protected el: HTMLElement;
constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone) {
c.detach();
this.el = r.nativeElement;
proxyOutputs(this, this.el, ['ionPickerDidPresent', 'ionPickerWillPresent', 'ionPickerWillDismiss', 'ionPickerDidDismiss', 'didPresent', 'willPresent', 'willDismiss', 'didDismiss']);
}
}


export declare interface IonProgressBar extends Components.IonProgressBar {}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
<ion-button id="open-action-sheet">Open Action Sheet</ion-button>
<ion-button id="open-loading">Open Loading</ion-button>
<ion-button id="open-toast">Open Toast</ion-button>
<ion-button id="open-picker">Open Picker</ion-button>

<ion-alert
trigger="open-alert"
Expand Down Expand Up @@ -30,4 +31,10 @@
message="This is a toast message"
[buttons]="['Button']"
></ion-toast>

<ion-picker
trigger="open-picker"
[columns]="pickerColumns"
[buttons]="pickerButtons"
></ion-picker>
</ion-content>
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,25 @@ import { Component } from "@angular/core";
selector: 'app-overlays-inline',
templateUrl: 'overlays-inline.component.html'
})
export class OverlaysInlineComponent {}
export class OverlaysInlineComponent {
public pickerButtons = [{ text: 'Ok' }, { text: 'Cancel', role: 'cancel' }];
public pickerColumns = [
{
name: 'Colors',
options: [
{
text: 'Red',
value: 'red',
},
{
text: 'Blue',
value: 'blue',
},
{
text: 'Green',
value: 'green',
},
],
},
];
}
6 changes: 6 additions & 0 deletions core/api.txt
Original file line number Diff line number Diff line change
Expand Up @@ -900,19 +900,25 @@ ion-picker,prop,cssClass,string | string[] | undefined,undefined,false,false
ion-picker,prop,duration,number,0,false,false
ion-picker,prop,enterAnimation,((baseEl: any, opts?: any) => Animation) | undefined,undefined,false,false
ion-picker,prop,htmlAttributes,undefined | { [key: string]: any; },undefined,false,false
ion-picker,prop,isOpen,boolean,false,false,false
ion-picker,prop,keyboardClose,boolean,true,false,false
ion-picker,prop,leaveAnimation,((baseEl: any, opts?: any) => Animation) | undefined,undefined,false,false
ion-picker,prop,mode,"ios" | "md",undefined,false,false
ion-picker,prop,showBackdrop,boolean,true,false,false
ion-picker,prop,trigger,string | undefined,undefined,false,false
ion-picker,method,dismiss,dismiss(data?: any, role?: string) => Promise<boolean>
ion-picker,method,getColumn,getColumn(name: string) => Promise<PickerColumn | undefined>
ion-picker,method,onDidDismiss,onDidDismiss<T = any>() => Promise<OverlayEventDetail<T>>
ion-picker,method,onWillDismiss,onWillDismiss<T = any>() => Promise<OverlayEventDetail<T>>
ion-picker,method,present,present() => Promise<void>
ion-picker,event,didDismiss,OverlayEventDetail<any>,true
ion-picker,event,didPresent,void,true
ion-picker,event,ionPickerDidDismiss,OverlayEventDetail<any>,true
ion-picker,event,ionPickerDidPresent,void,true
ion-picker,event,ionPickerWillDismiss,OverlayEventDetail<any>,true
ion-picker,event,ionPickerWillPresent,void,true
ion-picker,event,willDismiss,OverlayEventDetail<any>,true
ion-picker,event,willPresent,void,true
ion-picker,css-prop,--backdrop-opacity
ion-picker,css-prop,--background
ion-picker,css-prop,--background-rgb
Expand Down
36 changes: 36 additions & 0 deletions core/src/components.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1883,6 +1883,7 @@ export namespace Components {
* Additional classes to apply for custom CSS. If multiple classes are provided they should be separated by spaces.
*/
"cssClass"?: string | string[];
"delegate"?: FrameworkDelegate;
/**
* Dismiss the picker overlay after it has been presented.
* @param data Any data to emit in the dismiss events.
Expand All @@ -1902,10 +1903,15 @@ export namespace Components {
* @param name The name of the column.
*/
"getColumn": (name: string) => Promise<PickerColumn | undefined>;
"hasController": boolean;
/**
* Additional attributes to pass to the picker.
*/
"htmlAttributes"?: { [key: string]: any };
/**
* If `true`, the picker will open. If `false`, the picker will close. Use this if you need finer grained control over presentation, otherwise just use the pickerController or the `trigger` property. Note: `isOpen` will not automatically be set back to `false` when the picker dismisses. You will need to do that in your code.
*/
"isOpen": boolean;
/**
* If `true`, the keyboard will be automatically dismissed when the overlay is presented.
*/
Expand Down Expand Up @@ -1935,6 +1941,10 @@ export namespace Components {
* If `true`, a backdrop will be displayed behind the picker.
*/
"showBackdrop": boolean;
/**
* An ID corresponding to the trigger element that causes the picker to open when clicked.
*/
"trigger": string | undefined;
}
interface IonPickerColumn {
/**
Expand Down Expand Up @@ -5720,6 +5730,7 @@ declare namespace LocalJSX {
* Additional classes to apply for custom CSS. If multiple classes are provided they should be separated by spaces.
*/
"cssClass"?: string | string[];
"delegate"?: FrameworkDelegate;
/**
* Number of milliseconds to wait before dismissing the picker.
*/
Expand All @@ -5728,10 +5739,15 @@ declare namespace LocalJSX {
* Animation to use when the picker is presented.
*/
"enterAnimation"?: AnimationBuilder;
"hasController"?: boolean;
/**
* Additional attributes to pass to the picker.
*/
"htmlAttributes"?: { [key: string]: any };
/**
* If `true`, the picker will open. If `false`, the picker will close. Use this if you need finer grained control over presentation, otherwise just use the pickerController or the `trigger` property. Note: `isOpen` will not automatically be set back to `false` when the picker dismisses. You will need to do that in your code.
*/
"isOpen"?: boolean;
/**
* If `true`, the keyboard will be automatically dismissed when the overlay is presented.
*/
Expand All @@ -5744,6 +5760,14 @@ declare namespace LocalJSX {
* The mode determines which platform styles to use.
*/
"mode"?: "ios" | "md";
/**
* Emitted after the picker has dismissed. Shorthand for ionPickerDidDismiss.
*/
"onDidDismiss"?: (event: IonPickerCustomEvent<OverlayEventDetail>) => void;
/**
* Emitted after the picker has presented. Shorthand for ionPickerWillDismiss.
*/
"onDidPresent"?: (event: IonPickerCustomEvent<void>) => void;
/**
* Emitted after the picker has dismissed.
*/
Expand All @@ -5760,11 +5784,23 @@ declare namespace LocalJSX {
* Emitted before the picker has presented.
*/
"onIonPickerWillPresent"?: (event: IonPickerCustomEvent<void>) => void;
/**
* Emitted before the picker has dismissed. Shorthand for ionPickerWillDismiss.
*/
"onWillDismiss"?: (event: IonPickerCustomEvent<OverlayEventDetail>) => void;
/**
* Emitted before the picker has presented. Shorthand for ionPickerWillPresent.
*/
"onWillPresent"?: (event: IonPickerCustomEvent<void>) => void;
"overlayIndex": number;
/**
* If `true`, a backdrop will be displayed behind the picker.
*/
"showBackdrop"?: boolean;
/**
* An ID corresponding to the trigger element that causes the picker to open when clicked.
*/
"trigger"?: string | undefined;
}
interface IonPickerColumn {
/**
Expand Down
18 changes: 10 additions & 8 deletions core/src/components/picker-column/picker-column.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -171,14 +171,16 @@ export class PickerColumnCmp implements ComponentInterface {
}
button.style.transform = transform;

// Update selected item
if (selected !== opt.selected) {
opt.selected = selected;
if (selected) {
button.classList.add(PICKER_OPT_SELECTED);
} else {
button.classList.remove(PICKER_OPT_SELECTED);
}
/**
* Ensure that the select column
* item has the selected class
*/
opt.selected = selected;

if (selected) {
button.classList.add(PICKER_OPT_SELECTED);
} else {
button.classList.remove(PICKER_OPT_SELECTED);
}
}
this.col.prevSelected = selectedIndex;
Expand Down

0 comments on commit c0a8501

Please sign in to comment.