Implements the general layout for a Stackspot web application.
npm install @stack-spot/portal-layoutThe overlay components (modal, right panel, bottom dialog and toaster) are controlled imperatively through the overlay object. Example:overlay.showModal(options).
The header, menus and page are rendered by the component according to its props. If you need a custom header or menu, you can use which accepts React elements instead of configuration objects.
You can also render the menu and header separately by importing the components , or .
, check the example below:``tsx
const menu = {
options: [
{
label: 'Section 1',
icon:
href: '/section-1',
active: true,
},
{
label: 'Section 2',
icon:
href: '/section-2',
}
]
}
const header = {
userName: 'Test',
email: 'test@stackspot.com',
center:
options: [
{
label: 'Logout',
icon:
onClick: () => logout(),
}
]
}
const MyApp = () => {
return
}
`
The Header and Menu in a layout are highly customizable. Check the code documentation for more details!
or await confirm({ message: '...' }). This makes using a modal much easier, but
prevents us from using React Portals.Without the use of React Portals, the modal content becomes isolated from the context it was called, meaning, updating a state of the
component who called it, won't update the content of the modal.
Programming a modal isolated from whatever called it is a good thing! It makes the code more maintainable and less coupled. But we need to
keep this behavior in mind. See the example below:
`tsx
const Counter = () => {
const [current, setCurrent] = useState(0)
function showCounterModal() {
overlay.showModal({
title: 'Counter',
children: (
The value is {counter}.
),
})
}
return
}
`This won't work because the state was declared outside the modal. We may click as muck as we want to increment the value, the text will keep
saying the first value it showed. The value will only be updated once we close the modal and open it up again.
The correct way of doing this would be, instead of declaring the state outside the modal, declaring it inside, see the example below:
`tsx
const CounterModal = () => {
const [current, setCurrent] = useState(0) return (
The value is {counter}.
)
}const Counter = () => {
function showCounterModal() {
overlay.showModal({
title: 'Counter',
children: ,
})
}
return
}
`This is going to work as expected, because the modal controls its own state!
If you really need to use an external state, consider:
1. Using a React Context declared before
.
2. Calling overlay.showModal() again to force its UI to update with the new state value.$3
The operations to open or close a modal or right panel are side effects, and, because of this, they should not be called during the
rendering phase of a component!You should open/close a modal/rightPanel on events (e.g.
onClick) or React effects (e.g. useEffect).Layout elements
You can easily refer to layout elements by using their ids: elementIds or by calling the function getLayoutElements().Error handling
Every part of the layout is wrapped under a React Error Boundary. If an error occurs in a part of the layout that is large enough
(e.g. Page), an error feedback is rendered. Otherwise, the content stays empty. The error is always logged to the console.In development mode, a button shows up in the error feedback, the button allows the error message to be seen without opening the console.
For the error boundaries that don't show an error feedback, in development mode, a small error icon is rendered.
To better format errors in an error boundary, please pass
errorDescriptor to the component , this is a function that transforms
an Error into something readable to present to the user.To intercept every error when it's catch by an Error Boundary, use the property
onError of the component