Skip to content

Commit

Permalink
feat(elements|ino-dialog): add new dialogOpen event to prevent rend…
Browse files Browse the repository at this point in the history
…ering issues (#1177)

* refactor: scoped styling for ino-icon in slot header

* refactor: delay ripple creation

* refactor: Emit dialogOpen event for time sensitive child component rendering (e.g. ino-icon-button) and document usage notes

* chore: format:fix
  • Loading branch information
TobiasHeimGalindo committed Jan 31, 2024
1 parent 625228a commit 40c6dfe
Show file tree
Hide file tree
Showing 6 changed files with 67 additions and 10 deletions.
6 changes: 5 additions & 1 deletion packages/elements-angular/src/directives/proxies.ts
Original file line number Diff line number Diff line change
Expand Up @@ -348,7 +348,7 @@ export class InoDialog {
constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone) {
c.detach();
this.el = r.nativeElement;
proxyOutputs(this, this.el, ['close', 'action']);
proxyOutputs(this, this.el, ['close', 'action', 'dialogOpen']);
}
}

Expand All @@ -365,6 +365,10 @@ export declare interface InoDialog extends Components.InoDialog {
* Emits an event upon clicking the action button of the dialog
*/
action: EventEmitter<CustomEvent<IInoDialogDialogSubmitAction>>;
/**
* Emits an event when the dialog is opened.
*/
dialogOpen: EventEmitter<CustomEvent<void>>;
}


Expand Down
3 changes: 2 additions & 1 deletion packages/elements-vue/src/proxies.ts
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,8 @@ export const InoDialog = /*@__PURE__*/ defineContainer<JSX.InoDialog>('ino-dialo
'actionText',
'icon',
'close',
'action'
'action',
'dialogOpen'
]);


Expand Down
16 changes: 16 additions & 0 deletions packages/elements/src/components.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -464,6 +464,9 @@ export namespace Components {
/**
* The ino-dialog component displays a modal window that can be used to display additional information or notify the user.
* It is based on the mdc-dialog and is fully customizable. The styling of a dialog's content must be provided by users.
* #### Usage Notes
* - **Child Component Layout Issues**: If elements like ripples or labels in the `ino-dialog` are mispositioned or incorrectly sized, it may indicate that child components are being rendered before the dialog is fully open.
* - **Rendering After Dialog Opens**: To prevent layout issues, render sensitive child components (e.g. `ino-icon-button`) only after the `dialogOpen` event has fired.
*/
interface InoDialog {
/**
Expand Down Expand Up @@ -1948,6 +1951,9 @@ declare global {
/**
* The ino-dialog component displays a modal window that can be used to display additional information or notify the user.
* It is based on the mdc-dialog and is fully customizable. The styling of a dialog's content must be provided by users.
* #### Usage Notes
* - **Child Component Layout Issues**: If elements like ripples or labels in the `ino-dialog` are mispositioned or incorrectly sized, it may indicate that child components are being rendered before the dialog is fully open.
* - **Rendering After Dialog Opens**: To prevent layout issues, render sensitive child components (e.g. `ino-icon-button`) only after the `dialogOpen` event has fired.
*/
interface HTMLInoDialogElement extends Components.InoDialog, HTMLStencilElement {
}
Expand Down Expand Up @@ -2872,6 +2878,9 @@ declare namespace LocalJSX {
/**
* The ino-dialog component displays a modal window that can be used to display additional information or notify the user.
* It is based on the mdc-dialog and is fully customizable. The styling of a dialog's content must be provided by users.
* #### Usage Notes
* - **Child Component Layout Issues**: If elements like ripples or labels in the `ino-dialog` are mispositioned or incorrectly sized, it may indicate that child components are being rendered before the dialog is fully open.
* - **Rendering After Dialog Opens**: To prevent layout issues, render sensitive child components (e.g. `ino-icon-button`) only after the `dialogOpen` event has fired.
*/
interface InoDialog {
/**
Expand Down Expand Up @@ -2922,6 +2931,10 @@ declare namespace LocalJSX {
* Emits an event upon closing the dialog
*/
"onClose"?: (event: InoDialogCustomEvent<DialogCloseAction>) => void;
/**
* Emits an event when the dialog is opened.
*/
"onDialogOpen"?: (event: InoDialogCustomEvent<void>) => void;
/**
* Opens the dialog if set to true
*/
Expand Down Expand Up @@ -4310,6 +4323,9 @@ declare module "@stencil/core" {
/**
* The ino-dialog component displays a modal window that can be used to display additional information or notify the user.
* It is based on the mdc-dialog and is fully customizable. The styling of a dialog's content must be provided by users.
* #### Usage Notes
* - **Child Component Layout Issues**: If elements like ripples or labels in the `ino-dialog` are mispositioned or incorrectly sized, it may indicate that child components are being rendered before the dialog is fully open.
* - **Rendering After Dialog Opens**: To prevent layout issues, render sensitive child components (e.g. `ino-icon-button`) only after the `dialogOpen` event has fired.
*/
"ino-dialog": LocalJSX.InoDialog & JSXBase.HTMLAttributes<HTMLInoDialogElement>;
/**
Expand Down
20 changes: 18 additions & 2 deletions packages/elements/src/components/ino-dialog/ino-dialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,11 @@ const DIALOG_ACTION_ATTRIBUTE = 'data-ino-dialog-action';
* The ino-dialog component displays a modal window that can be used to display additional information or notify the user.
* It is based on the mdc-dialog and is fully customizable. The styling of a dialog's content must be provided by users.
*
* #### Usage Notes
*
* - **Child Component Layout Issues**: If elements like ripples or labels in the `ino-dialog` are mispositioned or incorrectly sized, it may indicate that child components are being rendered before the dialog is fully open.
* - **Rendering After Dialog Opens**: To prevent layout issues, render sensitive child components (e.g. `ino-icon-button`) only after the `dialogOpen` event has fired.
*
* @slot default - content of the dialog
* @slot header - content to replace default header of dialog
* @slot body - content to replace default body of dialog
Expand Down Expand Up @@ -116,6 +121,11 @@ export class Dialog implements ComponentInterface {
*/
@Event() action!: EventEmitter<DialogSubmitAction>;

/**
* Emits an event when the dialog is opened.
*/
@Event() dialogOpen!: EventEmitter<void>;

componentWillRender(): Promise<void> {
if (!this.mdcDialog || !this.open) {
return;
Expand Down Expand Up @@ -149,6 +159,10 @@ export class Dialog implements ComponentInterface {

this.mdcDialog.listen('click', this.handleDialogClick.bind(this));
this.open && this.mdcDialog?.open();

this.mdcDialog.listen('MDCDialog:opened', () => {
this.dialogOpen.emit();
});
}

disconnectedCallback() {
Expand All @@ -174,11 +188,11 @@ export class Dialog implements ComponentInterface {
}

render() {
// Conditional rendering based on 'dialogIsOpen' causes layout jumps and only can fixes rare misalignment issues. Use the 'dialogOpen' event to render content after dialog opens for these cases.
const hasDefaultSlot = hasSlotContent(this.el, 'default');
const hasHeaderSlot = hasSlotContent(this.el, 'header');
const hasBodySlot = hasSlotContent(this.el, 'body');
const hasFooterSlot = hasSlotContent(this.el, 'footer');

return (
<Host class={{ 'ino-dialog--fullwidth': this.fullwidth }}>
<div class="mdc-dialog">
Expand Down Expand Up @@ -208,7 +222,9 @@ export class Dialog implements ComponentInterface {
<slot name="header"></slot>
) : (
<header>
{this.icon && <ino-icon icon={this.icon} />}
{this.icon && (
<ino-icon class="header-icon" icon={this.icon} />
)}
<h1 id="ino-dialog-title">{this.headerText}</h1>
</header>
)}
Expand Down
14 changes: 10 additions & 4 deletions packages/elements/src/components/ino-dialog/readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,11 @@
The ino-dialog component displays a modal window that can be used to display additional information or notify the user.
It is based on the mdc-dialog and is fully customizable. The styling of a dialog's content must be provided by users.

#### Usage Notes

- **Child Component Layout Issues**: If elements like ripples or labels in the `ino-dialog` are mispositioned or incorrectly sized, it may indicate that child components are being rendered before the dialog is fully open.
- **Rendering After Dialog Opens**: To prevent layout issues, render sensitive child components (e.g. `ino-icon-button`) only after the `dialogOpen` event has fired.

## Properties

| Property | Attribute | Description | Type | Default |
Expand All @@ -28,10 +33,11 @@ It is based on the mdc-dialog and is fully customizable. The styling of a dialog

## Events

| Event | Description | Type |
| -------- | ------------------------------------------------------------ | --------------------- |
| `action` | Emits an event upon clicking the action button of the dialog | `CustomEvent<string>` |
| `close` | Emits an event upon closing the dialog | `CustomEvent<string>` |
| Event | Description | Type |
| ------------ | ------------------------------------------------------------ | --------------------- |
| `action` | Emits an event upon clicking the action button of the dialog | `CustomEvent<string>` |
| `close` | Emits an event upon closing the dialog | `CustomEvent<string>` |
| `dialogOpen` | Emits an event when the dialog is opened. | `CustomEvent<void>` |


## Slots
Expand Down
18 changes: 16 additions & 2 deletions packages/storybook/elements-stencil-docs.json
Original file line number Diff line number Diff line change
Expand Up @@ -2741,9 +2741,9 @@
"fileName": "ino-dialog.tsx",
"tag": "ino-dialog",
"readme": "# ino-dialog\n\n",
"overview": "The ino-dialog component displays a modal window that can be used to display additional information or notify the user.\nIt is based on the mdc-dialog and is fully customizable. The styling of a dialog's content must be provided by users.",
"overview": "The ino-dialog component displays a modal window that can be used to display additional information or notify the user.\nIt is based on the mdc-dialog and is fully customizable. The styling of a dialog's content must be provided by users.\n\n#### Usage Notes\n\n- **Child Component Layout Issues**: If elements like ripples or labels in the `ino-dialog` are mispositioned or incorrectly sized, it may indicate that child components are being rendered before the dialog is fully open.\n- **Rendering After Dialog Opens**: To prevent layout issues, render sensitive child components (e.g. `ino-icon-button`) only after the `dialogOpen` event has fired.",
"usage": {},
"docs": "The ino-dialog component displays a modal window that can be used to display additional information or notify the user.\nIt is based on the mdc-dialog and is fully customizable. The styling of a dialog's content must be provided by users.",
"docs": "The ino-dialog component displays a modal window that can be used to display additional information or notify the user.\nIt is based on the mdc-dialog and is fully customizable. The styling of a dialog's content must be provided by users.\n\n#### Usage Notes\n\n- **Child Component Layout Issues**: If elements like ripples or labels in the `ino-dialog` are mispositioned or incorrectly sized, it may indicate that child components are being rendered before the dialog is fully open.\n- **Rendering After Dialog Opens**: To prevent layout issues, render sensitive child components (e.g. `ino-icon-button`) only after the `dialogOpen` event has fired.",
"docsTags": [
{
"name": "slot",
Expand Down Expand Up @@ -3069,6 +3069,20 @@
"composed": true,
"docs": "Emits an event upon closing the dialog",
"docsTags": []
},
{
"event": "dialogOpen",
"detail": "void",
"bubbles": true,
"complexType": {
"original": "void",
"resolved": "void",
"references": {}
},
"cancelable": true,
"composed": true,
"docs": "Emits an event when the dialog is opened.",
"docsTags": []
}
],
"styles": [
Expand Down

0 comments on commit 40c6dfe

Please sign in to comment.