Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
176 changes: 176 additions & 0 deletions examples/reference/layouts/Drawer.ipynb
Original file line number Diff line number Diff line change
@@ -0,0 +1,176 @@
{
"cells": [
{
"cell_type": "code",
"execution_count": null,
"id": "5ccb1a30-351b-47dd-8dca-caf18dd097ed",
"metadata": {},
"outputs": [],
"source": [
"import panel as pn\n",
"from panel_material_ui import Button, Container, Drawer, Toggle\n",
"\n",
"pn.extension()"
]
},
{
"cell_type": "markdown",
"id": "a6c6a705-0ea1-4a19-a264-eacac2b2544e",
"metadata": {},
"source": [
"The `Drawer` component (akin to a sidebar) provides ergonomic access to destinations in a site or app functionality.\n",
"\n",
"## Parameters:\n",
"For details on other options for customizing the component see the layout and styling how-to guides.\n",
"\n",
"### Core\n",
"\n",
"* **`open`** (`boolean`): Whether the `Drawer` is open.\n",
"* **`variant`** (`Literal[\"temporary\", \"persistent\"]`): Whether the Drawer is temporary or persistent.\n",
"\n",
"### Display\n",
"\n",
"* **`anchor`** (`Literal[\"left\", \"right\", \"bottom\", \"right\"]`): Where to position the `Drawer`.\n",
"* **`size`** (`int`): The width or height depending on whether the `Drawer` is rendered on the left/right or top/bottom respectively.\n",
"* **`variant`** (`Literal[\"filled\", \"outlined\"]`): Whether to show an outline instead of elevation.\n",
"\n",
"---"
]
},
{
"cell_type": "markdown",
"id": "70597098-996d-44cd-b511-ad6dc1702c61",
"metadata": {},
"source": [
"Temporary navigation drawers can toggle open or closed. Closed by default, the drawer opens temporarily above all other content until a section is selected.\n",
"\n",
"The `Drawer` can be cancelled by clicking the overlay or pressing the Esc key. It closes when an item is selected, handled by controlling the `open` parameter."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "a9e7a8a4-3cb9-4c7a-8f2a-1068cee48cf2",
"metadata": {},
"outputs": [],
"source": [
"drawer = Drawer(\"I'm in a Drawer\", size=300)\n",
"\n",
"button = Button(label='Open Drawer')\n",
"\n",
"button.js_on_click(args={'drawer': drawer}, code='drawer.data.open = true')\n",
"\n",
"Container(button, drawer)"
]
},
{
"cell_type": "markdown",
"id": "424988c8-1da9-495a-8c98-7a1c3e9ef5c4",
"metadata": {},
"source": [
"### Anchor\n",
"\n",
"Use the `anchor` parameter to specify which side of the screen the `Drawer` should originate from.\n",
"\n",
"The default value is left."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "ada8993e-14c3-4f3d-b663-38edee773d07",
"metadata": {},
"outputs": [],
"source": [
"container = pn.Row()\n",
"for anchor in Drawer.param.anchor.objects:\n",
" drawer = Drawer(f\"I'm in a Drawer on the {anchor}\", size=300, anchor=anchor)\n",
" button = Button(label=anchor.upper(), width=100)\n",
" button.js_on_click(args={'drawer': drawer}, code='drawer.data.open = true')\n",
" container.extend([button, drawer])\n",
"\n",
"container"
]
},
{
"cell_type": "markdown",
"id": "9c7bdd10-0deb-43f4-8de9-a0a945199e8a",
"metadata": {},
"source": [
"### Persistent drawer\n",
"\n",
"Persistent navigation drawers can toggle open or closed. The drawer sits on the same surface elevation as the content. It is closed by default and opens by selecting the menu icon, and stays open until closed by the user. The state of the drawer is remembered from action to action and session to session.\n",
"\n",
"When the drawer is outside of the page grid and opens, the drawer forces other content to change size and adapt to the smaller viewport.\n",
"\n",
"Persistent navigation drawers are acceptable for all sizes larger than mobile. They are not recommended for apps with multiple levels of hierarchy that require using an up arrow for navigation."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "ed9114f8-6f77-436f-bc00-7b562364bbc0",
"metadata": {},
"outputs": [],
"source": [
"drawer = Drawer(\"I'm in a Drawer\", size=300, variant=\"persistent\")\n",
"\n",
"button = Toggle(label='Toggle Drawer')\n",
"\n",
"button.jslink(drawer, value='open')\n",
"\n",
"Container(button, drawer)"
]
},
{
"cell_type": "markdown",
"id": "52078d10-646d-4809-8e39-38bb723e8779",
"metadata": {},
"source": [
"When working with a persistent drawer you will usually also want to ensure that the rest of the Page contents shifts along with the drawer:"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "9c451806-c98b-403a-979b-e6ec05efa78f",
"metadata": {},
"outputs": [],
"source": [
"drawer = Drawer(\"I'm in a Drawer\", size=300, variant=\"persistent\")\n",
"\n",
"button = Toggle(label='Toggle Drawer')\n",
"\n",
"container = Container(button, drawer)\n",
"\n",
"button.jscallback(args={'drawer': drawer, 'container': container}, value=\"\"\"\n",
"container.data.sx = cb_obj.value ? {marginLeft: `${drawer.data.size}px`} : {}\n",
"drawer.data.open = cb_obj.value\n",
"\"\"\")\n",
"\n",
"container"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3 (ipykernel)",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.12.2"
}
},
"nbformat": 4,
"nbformat_minor": 5
}
21 changes: 21 additions & 0 deletions src/panel_material_ui/layout/Drawer.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import Drawer from "@mui/material/Drawer"

export function render({model, view}) {
const [anchor] = model.useState("anchor")
const [open, setOpen] = model.useState("open")
const [size] = model.useState("size")
const [variant] = model.useState("variant")
const objects = model.get_child("objects")

let dims
if (!["top", "bottom"].includes(anchor)) {
dims = {width: `${size}px`}
} else {
dims = {height: `${size}px`}
}
return (
<Drawer anchor={anchor} open={open} onClose={() => setOpen(false)} PaperProps={{sx: dims}} variant={variant}>
{objects}
</Drawer>
)
}
43 changes: 36 additions & 7 deletions src/panel_material_ui/layout/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -467,15 +467,44 @@ class Dialog(MaterialListLike):
_esm_base = "Dialog.jsx"


class Drawer(MaterialListLike):
"""
The `Drawer` component can be used to display important content in a modal-like overlay that requires
user interaction. It is often used for tasks such as confirmations, forms, or displaying
additional information.

Reference: https://mui.com/material-ui/react-drawer/

:Example:
>>> drawer = Drawer("This is a drawer")
>>> button = Button(on_click=lambda _: drawer.param.update(open=True), label='Open Drawer')
>>> pn.Column(button, drawer).servable()
"""

anchor = param.Selector(default="left", objects=["left", "right", "top", "bottom"])

size = param.Integer(default=250, doc="""
The width (for left/right anchors) or height (for top/bottom anchors) of the drawer.""")

open = param.Boolean(default=False, doc="""
Whether the drawer is open.""")

variant = param.Selector(default="temporary", objects=["permanent", "persistent", "temporary"])

_esm_base = "Drawer.jsx"



__all__ = [
"Paper",
"Container",
"Grid",
"Card",
"Accordion",
"Tabs",
"Divider",
"Alert",
"Backdrop",
"Dialog"
"Card",
"Container",
"Dialog",
"Divider",
"Drawer",
"Grid",
"Paper",
"Tabs",
]
Loading