Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(action-sheet, loading, modal, picker, popover): pass HTML attributes to host element #23929

Merged
merged 11 commits into from
Sep 15, 2021
7 changes: 6 additions & 1 deletion core/api.txt
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ ion-action-sheet,prop,buttons,(string | ActionSheetButton)[],[],false,false
ion-action-sheet,prop,cssClass,string | string[] | undefined,undefined,false,false
ion-action-sheet,prop,enterAnimation,((baseEl: any, opts?: any) => Animation) | undefined,undefined,false,false
ion-action-sheet,prop,header,string | undefined,undefined,false,false
ion-action-sheet,prop,htmlAttributes,ActionSheetAttributes | undefined,undefined,false,false
ion-action-sheet,prop,keyboardClose,boolean,true,false,false
ion-action-sheet,prop,leaveAnimation,((baseEl: any, opts?: any) => Animation) | undefined,undefined,false,false
ion-action-sheet,prop,mode,"ios" | "md",undefined,false,false
Expand Down Expand Up @@ -334,7 +335,7 @@ ion-datetime,prop,monthShortNames,string | string[] | undefined,undefined,false,
ion-datetime,prop,monthValues,number | number[] | string | undefined,undefined,false,false
ion-datetime,prop,name,string,this.inputId,false,false
ion-datetime,prop,pickerFormat,string | undefined,undefined,false,false
ion-datetime,prop,pickerOptions,undefined | { columns?: PickerColumn[] | undefined; buttons?: PickerButton[] | undefined; cssClass?: string | string[] | undefined; showBackdrop?: boolean | undefined; backdropDismiss?: boolean | undefined; animated?: boolean | undefined; mode?: Mode | undefined; keyboardClose?: boolean | undefined; id?: string | undefined; enterAnimation?: AnimationBuilder | undefined; leaveAnimation?: AnimationBuilder | undefined; },undefined,false,false
ion-datetime,prop,pickerOptions,undefined | { columns?: PickerColumn[] | undefined; buttons?: PickerButton[] | undefined; cssClass?: string | string[] | undefined; showBackdrop?: boolean | undefined; backdropDismiss?: boolean | undefined; animated?: boolean | undefined; mode?: Mode | undefined; keyboardClose?: boolean | undefined; id?: string | undefined; htmlAttributes?: PickerAttributes | undefined; enterAnimation?: AnimationBuilder | undefined; leaveAnimation?: AnimationBuilder | undefined; },undefined,false,false
ion-datetime,prop,placeholder,null | string | undefined,undefined,false,false
ion-datetime,prop,readonly,boolean,false,false,false
ion-datetime,prop,value,null | string | undefined,undefined,false,false
Expand Down Expand Up @@ -622,6 +623,7 @@ ion-loading,prop,backdropDismiss,boolean,false,false,false
ion-loading,prop,cssClass,string | string[] | undefined,undefined,false,false
ion-loading,prop,duration,number,0,false,false
ion-loading,prop,enterAnimation,((baseEl: any, opts?: any) => Animation) | undefined,undefined,false,false
ion-loading,prop,htmlAttributes,LoadingAttributes | undefined,undefined,false,false
ion-loading,prop,keyboardClose,boolean,true,false,false
ion-loading,prop,leaveAnimation,((baseEl: any, opts?: any) => Animation) | undefined,undefined,false,false
ion-loading,prop,message,IonicSafeString | string | undefined,undefined,false,false
Expand Down Expand Up @@ -709,6 +711,7 @@ ion-modal,prop,component,Function | HTMLElement | null | string,undefined,true,f
ion-modal,prop,componentProps,undefined | { [key: string]: any; },undefined,false,false
ion-modal,prop,cssClass,string | string[] | undefined,undefined,false,false
ion-modal,prop,enterAnimation,((baseEl: any, opts?: any) => Animation) | undefined,undefined,false,false
ion-modal,prop,htmlAttributes,ModalAttributes | undefined,undefined,false,false
ion-modal,prop,keyboardClose,boolean,true,false,false
ion-modal,prop,leaveAnimation,((baseEl: any, opts?: any) => Animation) | undefined,undefined,false,false
ion-modal,prop,mode,"ios" | "md",undefined,false,false
Expand Down Expand Up @@ -777,6 +780,7 @@ ion-picker,prop,columns,PickerColumn[],[],false,false
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,PickerAttributes | undefined,undefined,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
Expand Down Expand Up @@ -812,6 +816,7 @@ ion-popover,prop,componentProps,undefined | { [key: string]: any; },undefined,fa
ion-popover,prop,cssClass,string | string[] | undefined,undefined,false,false
ion-popover,prop,enterAnimation,((baseEl: any, opts?: any) => Animation) | undefined,undefined,false,false
ion-popover,prop,event,any,undefined,false,false
ion-popover,prop,htmlAttributes,PopoverAttributes | undefined,undefined,false,false
ion-popover,prop,keyboardClose,boolean,true,false,false
ion-popover,prop,leaveAnimation,((baseEl: any, opts?: any) => Animation) | undefined,undefined,false,false
ion-popover,prop,mode,"ios" | "md",undefined,false,false
Expand Down
42 changes: 41 additions & 1 deletion core/src/components.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
* It contains typing information for all components that exist in this project.
*/
import { HTMLStencilElement, JSXBase } from "@stencil/core/internal";
import { ActionSheetButton, AlertButton, AlertInput, AnimationBuilder, AutocompleteTypes, CheckboxChangeEventDetail, Color, ComponentProps, ComponentRef, DatetimeChangeEventDetail, DatetimeOptions, DomRenderFn, FooterHeightFn, FrameworkDelegate, HeaderFn, HeaderHeightFn, InputChangeEventDetail, ItemHeightFn, ItemRenderFn, ItemReorderEventDetail, MenuChangeEventDetail, NavComponent, NavComponentWithProps, NavOptions, OverlayEventDetail, PickerButton, PickerColumn, RadioGroupChangeEventDetail, RangeChangeEventDetail, RangeValue, RefresherEventDetail, RouteID, RouterDirection, RouterEventDetail, RouterOutletOptions, RouteWrite, ScrollBaseDetail, ScrollDetail, SearchbarChangeEventDetail, SegmentButtonLayout, SegmentChangeEventDetail, SelectChangeEventDetail, SelectInterface, SelectPopoverOption, Side, SpinnerTypes, StyleEventDetail, SwipeGestureHandler, TabBarChangedEventDetail, TabButtonClickEventDetail, TabButtonLayout, TextareaChangeEventDetail, TextFieldTypes, ToastButton, ToggleChangeEventDetail, TransitionDoneFn, TransitionInstruction, ViewController } from "./interface";
import { ActionSheetAttributes, ActionSheetButton, AlertButton, AlertInput, AnimationBuilder, AutocompleteTypes, CheckboxChangeEventDetail, Color, ComponentProps, ComponentRef, DatetimeChangeEventDetail, DatetimeOptions, DomRenderFn, FooterHeightFn, FrameworkDelegate, HeaderFn, HeaderHeightFn, InputChangeEventDetail, ItemHeightFn, ItemRenderFn, ItemReorderEventDetail, LoadingAttributes, MenuChangeEventDetail, ModalAttributes, NavComponent, NavComponentWithProps, NavOptions, OverlayEventDetail, PickerAttributes, PickerButton, PickerColumn, PopoverAttributes, RadioGroupChangeEventDetail, RangeChangeEventDetail, RangeValue, RefresherEventDetail, RouteID, RouterDirection, RouterEventDetail, RouterOutletOptions, RouteWrite, ScrollBaseDetail, ScrollDetail, SearchbarChangeEventDetail, SegmentButtonLayout, SegmentChangeEventDetail, SelectChangeEventDetail, SelectInterface, SelectPopoverOption, Side, SpinnerTypes, StyleEventDetail, SwipeGestureHandler, TabBarChangedEventDetail, TabButtonClickEventDetail, TabButtonLayout, TextareaChangeEventDetail, TextFieldTypes, ToastButton, ToggleChangeEventDetail, TransitionDoneFn, TransitionInstruction, ViewController } from "./interface";
import { IonicSafeString } from "./utils/sanitization";
import { AlertAttributes } from "./components/alert/alert-interface";
import { NavigationHookCallback } from "./components/route/route-interface";
Expand Down Expand Up @@ -43,6 +43,10 @@ export namespace Components {
* Title for the action sheet.
*/
"header"?: string;
/**
* Additional attributes to pass to the action sheet.
*/
"htmlAttributes"?: ActionSheetAttributes;
/**
* If `true`, the keyboard will be automatically dismissed when the overlay is presented.
*/
Expand Down Expand Up @@ -1183,6 +1187,10 @@ export namespace Components {
* Animation to use when the loading indicator is presented.
*/
"enterAnimation"?: AnimationBuilder;
/**
* Additional attributes to pass to the loader.
*/
"htmlAttributes"?: LoadingAttributes;
/**
* If `true`, the keyboard will be automatically dismissed when the overlay is presented.
*/
Expand Down Expand Up @@ -1347,6 +1355,10 @@ export namespace Components {
* Animation to use when the modal is presented.
*/
"enterAnimation"?: AnimationBuilder;
/**
* Additional attributes to pass to the modal.
*/
"htmlAttributes"?: ModalAttributes;
/**
* If `true`, the keyboard will be automatically dismissed when the overlay is presented.
*/
Expand Down Expand Up @@ -1564,6 +1576,10 @@ export namespace Components {
* @param name The name of the column.
*/
"getColumn": (name: string) => Promise<PickerColumn | undefined>;
/**
* Additional attributes to pass to the picker.
*/
"htmlAttributes"?: PickerAttributes;
/**
* If `true`, the keyboard will be automatically dismissed when the overlay is presented.
*/
Expand Down Expand Up @@ -1636,6 +1652,10 @@ export namespace Components {
* The event to pass to the popover animation.
*/
"event": any;
/**
* Additional attributes to pass to the popover.
*/
"htmlAttributes"?: PopoverAttributes;
/**
* If `true`, the keyboard will be automatically dismissed when the overlay is presented.
*/
Expand Down Expand Up @@ -3356,6 +3376,10 @@ declare namespace LocalJSX {
* Title for the action sheet.
*/
"header"?: string;
/**
* Additional attributes to pass to the action sheet.
*/
"htmlAttributes"?: ActionSheetAttributes;
/**
* If `true`, the keyboard will be automatically dismissed when the overlay is presented.
*/
Expand Down Expand Up @@ -4534,6 +4558,10 @@ declare namespace LocalJSX {
* Animation to use when the loading indicator is presented.
*/
"enterAnimation"?: AnimationBuilder;
/**
* Additional attributes to pass to the loader.
*/
"htmlAttributes"?: LoadingAttributes;
/**
* If `true`, the keyboard will be automatically dismissed when the overlay is presented.
*/
Expand Down Expand Up @@ -4692,6 +4720,10 @@ declare namespace LocalJSX {
* Animation to use when the modal is presented.
*/
"enterAnimation"?: AnimationBuilder;
/**
* Additional attributes to pass to the modal.
*/
"htmlAttributes"?: ModalAttributes;
/**
* If `true`, the keyboard will be automatically dismissed when the overlay is presented.
*/
Expand Down Expand Up @@ -4826,6 +4858,10 @@ declare namespace LocalJSX {
* Animation to use when the picker is presented.
*/
"enterAnimation"?: AnimationBuilder;
/**
* Additional attributes to pass to the picker.
*/
"htmlAttributes"?: PickerAttributes;
/**
* If `true`, the keyboard will be automatically dismissed when the overlay is presented.
*/
Expand Down Expand Up @@ -4900,6 +4936,10 @@ declare namespace LocalJSX {
* The event to pass to the popover animation.
*/
"event"?: any;
/**
* Additional attributes to pass to the popover.
*/
"htmlAttributes"?: PopoverAttributes;
/**
* If `true`, the keyboard will be automatically dismissed when the overlay is presented.
*/
Expand Down
5 changes: 5 additions & 0 deletions core/src/components/action-sheet/action-sheet-interface.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { JSXBase } from '@stencil/core/internal';

import { AnimationBuilder, Mode } from '../../interface';

export interface ActionSheetOptions {
Expand All @@ -11,11 +13,14 @@ export interface ActionSheetOptions {
mode?: Mode;
keyboardClose?: boolean;
id?: string;
htmlAttributes?: ActionSheetAttributes;

enterAnimation?: AnimationBuilder;
leaveAnimation?: AnimationBuilder;
}

export interface ActionSheetAttributes extends JSXBase.HTMLAttributes<HTMLElement> {}

export interface ActionSheetButton {
text?: string;
role?: 'cancel' | 'destructive' | 'selected' | string;
Expand Down
9 changes: 8 additions & 1 deletion core/src/components/action-sheet/action-sheet.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { Component, ComponentInterface, Element, Event, EventEmitter, Host, Method, Prop, h, readTask } from '@stencil/core';

import { getIonMode } from '../../global/ionic-global';
import { ActionSheetButton, AnimationBuilder, CssClassMap, OverlayEventDetail, OverlayInterface } from '../../interface';
import { ActionSheetAttributes, ActionSheetButton, AnimationBuilder, CssClassMap, OverlayEventDetail, OverlayInterface } from '../../interface';
import { Gesture } from '../../utils/gesture';
import { createButtonActiveGesture } from '../../utils/gesture/button-active';
import { BACKDROP, dismiss, eventMethod, isCancel, prepareOverlay, present, safeCall } from '../../utils/overlays';
Expand Down Expand Up @@ -90,6 +90,11 @@ export class ActionSheet implements ComponentInterface, OverlayInterface {
*/
@Prop() animated = true;

/**
* Additional attributes to pass to the action sheet.
*/
@Prop() htmlAttributes?: ActionSheetAttributes;

/**
* Emitted after the alert has presented.
*/
Expand Down Expand Up @@ -228,6 +233,7 @@ export class ActionSheet implements ComponentInterface, OverlayInterface {
}

render() {
const { htmlAttributes } = this;
const mode = getIonMode(this);
const allButtons = this.getButtons();
const cancelButton = allButtons.find(b => b.role === 'cancel');
Expand All @@ -238,6 +244,7 @@ export class ActionSheet implements ComponentInterface, OverlayInterface {
role="dialog"
aria-modal="true"
tabindex="-1"
{...htmlAttributes as any}
style={{
zIndex: `${20000 + this.overlayIndex}`,
}}
Expand Down
8 changes: 8 additions & 0 deletions core/src/components/action-sheet/readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -62,12 +62,19 @@ interface ActionSheetOptions {
mode?: Mode;
keyboardClose?: boolean;
id?: string;
htmlAttributes?: ActionSheetAttributes;

enterAnimation?: AnimationBuilder;
leaveAnimation?: AnimationBuilder;
}
```

### ActionSheetAttributes

```typescript
interface ActionSheetAttributes extends JSXBase.HTMLAttributes<HTMLElement> {}
```

<!-- Auto Generated Below -->


Expand Down Expand Up @@ -524,6 +531,7 @@ export default defineComponent({
| `cssClass` | `css-class` | Additional classes to apply for custom CSS. If multiple classes are provided they should be separated by spaces. | `string \| string[] \| undefined` | `undefined` |
| `enterAnimation` | -- | Animation to use when the action sheet is presented. | `((baseEl: any, opts?: any) => Animation) \| undefined` | `undefined` |
| `header` | `header` | Title for the action sheet. | `string \| undefined` | `undefined` |
| `htmlAttributes` | -- | Additional attributes to pass to the action sheet. | `ActionSheetAttributes \| undefined` | `undefined` |
| `keyboardClose` | `keyboard-close` | If `true`, the keyboard will be automatically dismissed when the overlay is presented. | `boolean` | `true` |
| `leaveAnimation` | -- | Animation to use when the action sheet is dismissed. | `((baseEl: any, opts?: any) => Animation) \| undefined` | `undefined` |
| `mode` | `mode` | The mode determines which platform styles to use. | `"ios" \| "md"` | `undefined` |
Expand Down
18 changes: 18 additions & 0 deletions core/src/components/action-sheet/test/basic/e2e.ts
Original file line number Diff line number Diff line change
Expand Up @@ -111,3 +111,21 @@ test('action-sheet:rtl: basic, scroll without cancel', async () => {
test('action-sheet:rtl: basic, custom backdrop', async () => {
await testActionSheet(DIRECTORY, '#customBackdrop', true);
});

// Attributes

test('action-sheet: htmlAttributes', async () => {
const page = await newE2EPage({ url: '/src/components/action-sheet/test/basic?ionic:_testing=true' });

await page.click('#basic');
await page.waitForSelector('#basic');

let toast = await page.find('ion-action-sheet');

expect(toast).not.toBe(null);
await toast.waitForVisible();

const attribute = await page.evaluate((el) => document.querySelector('ion-action-sheet').getAttribute('data-testid'));

expect(attribute).toEqual('basic-action-sheet');
});
3 changes: 3 additions & 0 deletions core/src/components/action-sheet/test/basic/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,9 @@
await openActionSheet({
header: "Albums",
subHeader: 'This is a sub header inside of an action sheet',
htmlAttributes: {
'data-testid': 'basic-action-sheet'
},
buttons: [{
text: 'Delete',
role: 'destructive',
Expand Down
4 changes: 2 additions & 2 deletions core/src/components/alert/alert.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -561,13 +561,14 @@ export class Alert implements ComponentInterface, OverlayInterface {
const hdrId = `alert-${overlayIndex}-hdr`;
const subHdrId = `alert-${overlayIndex}-sub-hdr`;
const msgId = `alert-${overlayIndex}-msg`;
const role = htmlAttributes?.role || (this.inputs.length > 0 || this.buttons.length > 0 ? 'alertdialog' : 'alert');
const role = this.inputs.length > 0 || this.buttons.length > 0 ? 'alertdialog' : 'alert';

return (
<Host
role={role}
aria-modal="true"
tabindex="-1"
{...htmlAttributes as any}
style={{
zIndex: `${20000 + overlayIndex}`,
}}
Expand All @@ -578,7 +579,6 @@ export class Alert implements ComponentInterface, OverlayInterface {
}}
onIonAlertWillDismiss={this.dispatchCancelHandler}
onIonBackdropTap={this.onBackdropTap}
{...htmlAttributes as any}
>

<ion-backdrop tappable={this.backdropDismiss}/>
Expand Down
Loading