diff --git a/gatsby-config.js b/gatsby-config.js index e2ecd72d..62e6c83f 100644 --- a/gatsby-config.js +++ b/gatsby-config.js @@ -112,6 +112,10 @@ module.exports = { { title: "Navigation", path: "/services/aem-cf-console-admin/api/navigation/" + }, + { + title: "Modal Dialogs", + path: "/services/aem-cf-console-admin/api/modal/" } ] }, @@ -162,6 +166,10 @@ module.exports = { { title: "Navigation", path: "/services/aem-cf-editor/api/navigation/" + }, + { + title: "Modal Dialogs", + path: "/services/aem-cf-editor/api/modal/" } ] }, diff --git a/src/pages/services/aem-cf-console-admin/api/commons/index.md b/src/pages/services/aem-cf-console-admin/api/commons/index.md index 2eb65dea..7edb8d70 100644 --- a/src/pages/services/aem-cf-console-admin/api/commons/index.md +++ b/src/pages/services/aem-cf-console-admin/api/commons/index.md @@ -53,60 +53,6 @@ At the moment [Modal](#modal) is the only way for extension to provide custom UI Both `register` and `attach` function of `@adobe/uix-guest` returns same connection object that has `host` property and expose API of Content Fragments console exposed for UI Extensions. -### Modal - -Content Fragments console provides API for showing modal dialogs with custom UI defined by an extension. These modals can be triggered by a click on the button or other events. Modal API is defined in the `modal` namespace. - -Content of the modal is rendered in an iframe with source defined by extension. Before showing modal you should create a page which renders Modal UI. This UI should use Adobe Spectrum UI library to provide consistent experiense to the user. - -In order to display modal dialog extension must call `showUrl` method in `modal` namespace. - -```js -import { register } from "@adobe/uix-guest"; - -const guestConnection = await register({ - id: "my.company.extension-with-modal", - { - //... - } -} - -guestConnection.host.modal.showUrl({ - title: "Extension Modal", - url: "/index.html#/modal", // absolute or relative path -}) -``` - -Modal may be closed by `close` method - -```js -import { attach } from "@adobe/uix-guest"; - -const guestConnection = await attach({ - id: "my.company.extension-with-modal" -} - -guestConnection.host.modal.close(); -``` - -#### Modal API Methods - -All extensions can access this API: -`modal.showUrl(modal: ModalRequest)` - -When an extension is loaded into the ModalProvider as a dialog, the extension can then call two more APIs: - -- `modal.setSize(size: string)` Manually update the "size" parameter of the modal and rerender. -- `modal.close()` Close modal. - -#### Formatting Options - -Spectrum dialogs can expand vertically according to content size, but not horizontally. Vertical height can be manually specified, or autodetected. Horizontally, there are only three "sizes" which Spectrum accepts, "S", "M", and "L". The ModalProvider tries to pick the right size based on the window width of the inner document if it isn't manually specified. - -To get the largest possible size, pass `fullscreen: true` in the object send to `modal.showUrl`. - -`size` can be changed during the component's lifetime with `.setSize` - ### Progress Circle A progress circle shows the presence of background system operation in a visual way. The progress circle also blocks all user interactions with the UI. diff --git a/src/pages/services/aem-cf-console-admin/api/index.md b/src/pages/services/aem-cf-console-admin/api/index.md index 1b06ea5b..5b8844a6 100644 --- a/src/pages/services/aem-cf-console-admin/api/index.md +++ b/src/pages/services/aem-cf-console-admin/api/index.md @@ -38,3 +38,9 @@ Explore the ways to extend and customize Header Menu [Navigation](navigation) Learn how to use basic methods for navigating within an extension + + + +[Modal Dialogs](modal) + +Learn about modal host API methods that can be used in any extension diff --git a/src/pages/services/aem-cf-console-admin/api/modal/index.md b/src/pages/services/aem-cf-console-admin/api/modal/index.md new file mode 100644 index 00000000..afba3434 --- /dev/null +++ b/src/pages/services/aem-cf-console-admin/api/modal/index.md @@ -0,0 +1,97 @@ +--- +title: Modal dialogs - AEM Content Fragments Console Extensibility +description: Learn about modal host API methods that can be used in any extension +contributors: + - https://github.com/AdobeDocs/uix +--- + +# Modal dialogs + +Describes basic methods for using modals dialogs within an extension. + +The AEM instance (host instance) provides an API for showing modal dialogs with custom UI defined by an extension. These modals can be triggered by a click on the button or other events. Modal API is defined in the `modal` namespace. + +Content of the modal is rendered in an iframe with source defined by extension. Before showing modal you should create a page which renders Modal UI. This UI should use Adobe Spectrum UI library to provide consistent experience to the user. + +## An example of opening and closing a modal + +In order to display modal dialog extension must call `showUrl` method in `modal` namespace. + +```js +import { register } from "@adobe/uix-guest"; + +const guestConnection = await register({ + id: "my.company.extension-with-modal", + { + //... + } +} + +guestConnection.host.modal.showUrl({ + title: "Extension Modal", + url: "/index.html#/modal", // absolute or relative path +}) +``` + +Modal may be closed by `close` method + +```js +import { attach } from "@adobe/uix-guest"; + +const guestConnection = await attach({ + id: "my.company.extension-with-modal" +} + +guestConnection.host.modal.close(); +``` +![](./modal.jpeg) + +## API Reference + +### Modal API Request Object + +The `modal.showUrl` and `modalInstance.set` methods accept a `ModalRequest` object. + +| Property | Type | Required | Default | Description | +|-----------------|-------------------------------------------|----------|-----------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| `url` | `string` | ✔️ | | URL of the page to load in the dialog frame. The URL must have the same origin as the extension making the modal request. | +| `title` | `string` | ✔️ | | Title of the modal to display. | +| `height` | `string`
`number`
`"auto"` | | `auto` | A number of pixels, a CSS value, or the string `auto`. The `auto` keyword will grow or shrink the modal to the height of the document in the iframe every time the guest document resizes, to a minimum of 20% and a maximum of 75% of window height. In fullscreen mode, this is ignored. | +| `width` | `string`
`number`
`"auto"` | | `auto` | A number of pixels, a CSS value, or the string `auto`. The `auto` keyword will grow or shrink the modal to the width of the document in the iframe every time the guest document resizes, to a minimum of 20% and a maximum of 75% of window width. In fullscreen mode, this is ignored. | +| `fullscreen` | `boolean` | | `false` | Display the dialog as large as possible. It will overlay most of the application, leaving small borders to indicate overlay. If true, any "width" and "height" parameters will be ignored. | +| `isDismissable` | `boolean` | | `true` | Show the dismiss button, so a user can close the modal no matter what state it is in. If an extension disables this, it must provide its own UI control which calls `modal.close()`. | +| `loading` | `boolean` | | `false` | Preserve the progress spinner that displays before the modal contents load. When `false` or unset, the modal will show a progress spinner until the guest in the iframe is connected, and then display the frame contents. If the `modal.showUrl()` call sets `{ loading: true }`, the spinner will continue displaying after the guest has connected, until the guest calls `modal.set({ loading: false })`. A modal which needs to do data fetching or layout adjustment after connecting should set `{ loading: true }` and then dismiss it from the modal when its UI is ready. | + +### Modal API + +The modal API is available to all extensions at the host.modal property. + +#### `modal.showUrl(request: ModalRequest): Promise` + +Any guest's GuestServer may call `modal.showUrl` to open a modal dialog. The provided `ModalRequest` object must have a `url` of the page to be displayed inside the modal. Typically this is another page or route in the calling extension app. + +If another modal is displaying and it belongs to a different extension, it rejects. + +#### `modal.close(): Promise` + +Close the current modal. If the current modal doesn't belong to the calling extension, it rejects. + +### Modal Instance API + +This API is returned to the GuestServer and also shared with the modal that loads inside the frame. A GuestServer loaded in a modal must call `set` instead of `showUrl`. + +#### `modal.set(request: ModalRequest): Promise` + +Modify the currently displaying modal. GuestUI frames running inside the modal may call this method to change their dimensions, or to change other parameters. + +#### `modal.close(): Promise` + +Close the modal. + +### Resizing + +When `height` and/or `width` are set to `"auto"`, the modal will attempt to resize whenever the displayed page changes size. This is to make the content of the iframe behave, as much as possible, like they're part of the content flow of the host application. + +- ⚠️ Resizes are detected every 100ms. +- ⚠️ Height is limited to between 20% and 75% of page height, and width is similarly limited. +- ⚠️ **If the page sets certain kinds of relative dimensions on its body elements, such as `99vh` or `101vmin`, it can cause slow expansion or contraction of the displayed frame.** Those measurements change as the outer document resizes the inner document, which triggers a loop. Remedy this by using other units to define the outside of your app. diff --git a/src/pages/services/aem-cf-console-admin/api/modal/modal.jpeg b/src/pages/services/aem-cf-console-admin/api/modal/modal.jpeg new file mode 100644 index 00000000..7912e8ec Binary files /dev/null and b/src/pages/services/aem-cf-console-admin/api/modal/modal.jpeg differ diff --git a/src/pages/services/aem-cf-editor/api/commons/index.md b/src/pages/services/aem-cf-editor/api/commons/index.md index babff481..d817d05b 100644 --- a/src/pages/services/aem-cf-editor/api/commons/index.md +++ b/src/pages/services/aem-cf-editor/api/commons/index.md @@ -52,60 +52,6 @@ At the moment [Modal](#modal) is the only way for extension to provide custom UI Both `register` and `attach` function of `@adobe/uix-guest` returns same connection object that has `host` property and expose API of Content Fragments console exposed for UI Extensions. -### Modal - -Content Fragments console provides API for showing modal dialogs with custom UI defined by an extension. These modals can be triggered by a click on the button or other events. Modal API is defined in the `modal` namespace. - -Content of the modal is rendered in an iframe with source defined by extension. Before showing modal you should create a page which renders Modal UI. This UI should use Adobe Spectrum UI library to provide consistent experiense to the user. - -In order to display modal dialog extension must call `showUrl` method in `modal` namespace. - -```js -import { register } from "@adobe/uix-guest"; - -const guestConnection = await register({ - id: "my.company.extension-with-modal", - { - //... - } -} - -guestConnection.host.modal.showUrl({ - title: "Extension Modal", - url: "/index.html#/modal", // absolute or relative path -}) -``` - -Modal may be closed by `close` method - -```js -import { attach } from "@adobe/uix-guest"; - -const guestConnection = await attach({ - id: "my.company.extension-with-modal" -} - -guestConnection.host.modal.close(); -``` - -#### Modal API Methods - -All extensions can access this API: -`modal.showUrl(modal: ModalRequest)` - -When an extension is loaded into the ModalProvider as a dialog, the extension can then call two more APIs: - -- `modal.setSize(size: string)` Manually update the "size" parameter of the modal and rerender. -- `modal.close()` Close modal. - -#### Formatting Options - -Spectrum dialogs can expand vertically according to content size, but not horizontally. Vertical height can be manually specified, or autodetected. Horizontally, there are only three "sizes" which Spectrum accepts, "S", "M", and "L". The ModalProvider tries to pick the right size based on the window width of the inner document if it isn't manually specified. - -To get the largest possible size, pass `fullscreen: true` in the object send to `modal.showUrl`. - -`size` can be changed during the component's lifetime with `.setSize` - ### Progress Circle A progress circle shows the presence of background system operation in a visual way. The progress circle also blocks all user interactions with the UI. diff --git a/src/pages/services/aem-cf-editor/api/index.md b/src/pages/services/aem-cf-editor/api/index.md index c22e3b64..1e0b59e1 100644 --- a/src/pages/services/aem-cf-editor/api/index.md +++ b/src/pages/services/aem-cf-editor/api/index.md @@ -50,3 +50,9 @@ Explore the ways to extend and customize Header Menu [Navigation](navigation) Learn how to use basic methods for navigating within an extension + + + +[Modal Dialogs](modal) + +Learn about modal host API methods that can be used in any extension diff --git a/src/pages/services/aem-cf-editor/api/modal/index.md b/src/pages/services/aem-cf-editor/api/modal/index.md new file mode 100644 index 00000000..ec2d668b --- /dev/null +++ b/src/pages/services/aem-cf-editor/api/modal/index.md @@ -0,0 +1,97 @@ +--- +title: Modal dialogs - AEM Content Fragments Editor Extensibility +description: Learn about modal host API methods that can be used in any extension +contributors: + - https://github.com/AdobeDocs/uix +--- + +# Modal dialogs + +Describes basic methods for using modals dialogs within an extension. + +The AEM instance (host instance) provides an API for showing modal dialogs with custom UI defined by an extension. These modals can be triggered by a click on the button or other events. Modal API is defined in the `modal` namespace. + +Content of the modal is rendered in an iframe with source defined by extension. Before showing modal you should create a page which renders Modal UI. This UI should use Adobe Spectrum UI library to provide consistent experience to the user. + +## An example of opening and closing a modal + +In order to display modal dialog extension must call `showUrl` method in `modal` namespace. + +```js +import { register } from "@adobe/uix-guest"; + +const guestConnection = await register({ + id: "my.company.extension-with-modal", + { + //... + } +} + +guestConnection.host.modal.showUrl({ + title: "Extension Modal", + url: "/index.html#/modal", // absolute or relative path +}) +``` + +Modal may be closed by `close` method + +```js +import { attach } from "@adobe/uix-guest"; + +const guestConnection = await attach({ + id: "my.company.extension-with-modal" +} + +guestConnection.host.modal.close(); +``` +![](./modal.jpeg) + +## API Reference + +### Modal API Request Object + +The `modal.showUrl` and `modalInstance.set` methods accept a `ModalRequest` object. + +| Property | Type | Required | Default | Description | +|-----------------|-------------------------------------------|----------|-----------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| `url` | `string` | ✔️ | | URL of the page to load in the dialog frame. The URL must have the same origin as the extension making the modal request. | +| `title` | `string` | ✔️ | | Title of the modal to display. | +| `height` | `string`
`number`
`"auto"` | | `auto` | A number of pixels, a CSS value, or the string `auto`. The `auto` keyword will grow or shrink the modal to the height of the document in the iframe every time the guest document resizes, to a minimum of 20% and a maximum of 75% of window height. In fullscreen mode, this is ignored. | +| `width` | `string`
`number`
`"auto"` | | `auto` | A number of pixels, a CSS value, or the string `auto`. The `auto` keyword will grow or shrink the modal to the width of the document in the iframe every time the guest document resizes, to a minimum of 20% and a maximum of 75% of window width. In fullscreen mode, this is ignored. | +| `fullscreen` | `boolean` | | `false` | Display the dialog as large as possible. It will overlay most of the application, leaving small borders to indicate overlay. If true, any "width" and "height" parameters will be ignored. | +| `isDismissable` | `boolean` | | `true` | Show the dismiss button, so a user can close the modal no matter what state it is in. If an extension disables this, it must provide its own UI control which calls `modal.close()`. | +| `loading` | `boolean` | | `false` | Preserve the progress spinner that displays before the modal contents load. When `false` or unset, the modal will show a progress spinner until the guest in the iframe is connected, and then display the frame contents. If the `modal.showUrl()` call sets `{ loading: true }`, the spinner will continue displaying after the guest has connected, until the guest calls `modal.set({ loading: false })`. A modal which needs to do data fetching or layout adjustment after connecting should set `{ loading: true }` and then dismiss it from the modal when its UI is ready. | + +### Modal API + +The modal API is available to all extensions at the host.modal property. + +#### `modal.showUrl(request: ModalRequest): Promise` + +Any guest's GuestServer may call `modal.showUrl` to open a modal dialog. The provided `ModalRequest` object must have a `url` of the page to be displayed inside the modal. Typically this is another page or route in the calling extension app. + +If another modal is displaying and it belongs to a different extension, it rejects. + +#### `modal.close(): Promise` + +Close the current modal. If the current modal doesn't belong to the calling extension, it rejects. + +### Modal Instance API + +This API is returned to the GuestServer and also shared with the modal that loads inside the frame. A GuestServer loaded in a modal must call `set` instead of `showUrl`. + +#### `modal.set(request: ModalRequest): Promise` + +Modify the currently displaying modal. GuestUI frames running inside the modal may call this method to change their dimensions, or to change other parameters. + +#### `modal.close(): Promise` + +Close the modal. + +### Resizing + +When `height` and/or `width` are set to `"auto"`, the modal will attempt to resize whenever the displayed page changes size. This is to make the content of the iframe behave, as much as possible, like they're part of the content flow of the host application. + +- ⚠️ Resizes are detected every 100ms. +- ⚠️ Height is limited to between 20% and 75% of page height, and width is similarly limited. +- ⚠️ **If the page sets certain kinds of relative dimensions on its body elements, such as `99vh` or `101vmin`, it can cause slow expansion or contraction of the displayed frame.** Those measurements change as the outer document resizes the inner document, which triggers a loop. Remedy this by using other units to define the outside of your app. diff --git a/src/pages/services/aem-cf-editor/api/modal/modal.jpeg b/src/pages/services/aem-cf-editor/api/modal/modal.jpeg new file mode 100644 index 00000000..7912e8ec Binary files /dev/null and b/src/pages/services/aem-cf-editor/api/modal/modal.jpeg differ