useTeleport
This hook provides a way to render children outside the DOM hierarchy of the parent component using React Portals.
As recommended by the UI5 Web Component for React Library team, this hook helps to mount the Modals and Popovers in an easy way.
Live example here
Api
This hook returns an Object with the following values
isOpen - boolean value gives the state of the visibility.
Teleport - React Component to wrap the Children.
close - Close Handler. It removes the Element from the DOM.
warning
Do not forget to call this close function to avoid unexpected behavior.
info
Popover Based Components [ActionSheet, Popover, ResponsivePopover]
popoverRef - Ref Object Ui5PopoverDomRef
openPopover - This Opener Function expects HTMLElement | EventTarget
info
Dialog Based Components [Dialog, MessageBox]
dialogRef - Ref Object Ui5DialogDomRef
openDialog - Dialog Opener Function
ActionSheet
import React from "react"
import { useTeleport } from "@bowbridge/ui5-react-toolkit"
import {
ActionSheet,
Button,
PopoverPlacementType,
} from "@ui5/webcomponents-react"
import { spacing } from "@ui5/webcomponents-react-base"
export const ActionSheetExample = () => {
const { isOpen, openPopover, popoverRef, Teleport, close } = useTeleport()
return (
<>
<Button
style={{ ...spacing.sapUiLargeMarginTopBottom }}
onClick={(e) => openPopover(e.target)}
>
Open ActionSheet
</Button>
{isOpen && (
<Teleport>
<ActionSheet
ref={popoverRef}
onAfterClose={close}
placementType={PopoverPlacementType.Right}
>
<Button icon='add'>Accept</Button>
<Button>Reject</Button>
<Button>This is my super long text!</Button>
</ActionSheet>
</Teleport>
)}
</>
)
}
Dialog
import React from "react"
import { useTeleport } from "@bowbridge/ui5-react-toolkit"
import { Dialog, Button } from "@ui5/webcomponents-react"
import { spacing } from "@ui5/webcomponents-react-base"
export const DialogExample = () => {
const { isOpen, openDialog, dialogRef, Teleport, close } = useTeleport()
return (
<>
<Button
style={{ ...spacing.sapUiLargeMarginTopBottom }}
onClick={openDialog}
>
Open Dialog
</Button>
{isOpen && (
<Teleport>
<Dialog ref={dialogRef} onAfterClose={close}>
Press "Escape to close the Dialog"
</Dialog>
</Teleport>
)}
</>
)
}
MessageBox
import React from "react"
import { useTeleport } from "@bowbridge/ui5-react-toolkit"
import { MessageBox, Button } from "@ui5/webcomponents-react"
import { spacing } from "@ui5/webcomponents-react-base"
type MessageBoxCloseEvent = CustomEvent<{
action: string,
}>
export const MessageBoxExample = () => {
const { isOpen, openDialog, dialogRef, Teleport, close } = useTeleport()
const closeHandler = (e: MessageBoxCloseEvent) => {
console.log(e.detail.action)
close()
}
return (
<>
<Button
style={{ ...spacing.sapUiLargeMarginTopBottom }}
onClick={openDialog}
>
Open MessageBox
</Button>
{isOpen && (
<Teleport>
<MessageBox
ref={dialogRef}
open={isOpen}
onClose={(e) => closeHandler(e)}
>
Press "Escape" to close the MessageBox.
</MessageBox>
</Teleport>
)}
</>
)
}
tip
The following example shows multiple usages of useTeleport Hook in a single Component.
Popover
import { useTeleport } from "@bowbridge/ui5-react-toolkit"
import {
Popover,
Button,
PopoverPlacementType,
Label,
ResponsivePopover,
List,
StandardListItem,
Icon,
Title,
Bar,
} from "@ui5/webcomponents-react"
import { spacing } from "@ui5/webcomponents-react-base"
import React from "react"
export const PopoverHook = () => {
const { isOpen, openPopover, popoverRef, Teleport, close } = useTeleport()
const HandleResponsivePopover = useTeleport()
return (
<>
<Button
style={{ ...spacing.sapUiLargeMarginTopBottom }}
onClick={(e) => openPopover(e.target)}
>
Open Popover
</Button>
{isOpen && (
<Teleport>
<Popover
headerText='Popover Header'
ref={popoverRef}
onAfterClose={close}
placementType={PopoverPlacementType.Left}
>
<Label>
Press "Escape" or click outside to close the Popover
</Label>
</Popover>
</Teleport>
)}
</div>
<div style={{}}>
<Button
style={{ ...spacing.sapUiLargeMarginTopBottom }}
onClick={(e) => HandleResponsivePopover.openPopover(e.target)}
>
Open ResponsivePopover
</Button>
{HandleResponsivePopover.isOpen && (
<HandleResponsivePopover.Teleport>
<ResponsivePopover
footer={
<Bar
endContent={
<Button onClick={HandleResponsivePopover.close}>
Close
</Button>
}
/>
}
header={
<Bar endContent={<Icon name='settings' />}>
<Title>Popover</Title>
</Bar>
}
headerText='ResponsivePopover Header'
ref={HandleResponsivePopover.popoverRef}
onAfterClose={HandleResponsivePopover.close}
>
<List
style={{
width: "200px",
}}
>
<StandardListItem additionalText='3'>
List Item 1
</StandardListItem>
<StandardListItem additionalText='2'>
List Item 2
</StandardListItem>
<StandardListItem additionalText='1'>
List Item 3
</StandardListItem>
</List>
</ResponsivePopover>
</HandleResponsivePopover.Teleport>
)}
</>
)
}