Gallery¶
The builtins, rendered by pyjinhx at docs build time (PJXLazyPanel needs a backend, so it sits this page out). Click through to the guide for props and DOM contracts.
Static¶
PJXBadge¶
PJXCard¶
PJXCard(title="Quarterly report", body="Revenue grew 12% over Q1.", footer="Updated today").render()
PJXDivider¶
PJXSpinner¶
PJXAvatar¶
PJXAvatarStack¶
PJXAvatarStack(
avatars=[
PJXAvatar(initials="AB", size="sm", alt="Alice Brown"),
PJXAvatar(initials="CD", size="sm", alt="Carol Davis"),
PJXAvatar(initials="EF", size="sm", alt="Eve Foster"),
],
extra_count=4,
).render()
PJXBreadcrumb¶
PJXSkeleton¶
PJXProgress¶
PJXEmptyState¶
PJXEmptyState(
title="No results",
description="Try a different search term.",
actions=['<button class="pjx-demo-btn">Clear filters</button>'],
).render()
Overlays & dialogs¶
PJXModal¶
[
'<button class="pjx-demo-btn" data-pjx-open="demo-modal">Open modal</button>',
PJXModal(
id="demo-modal",
title="Confirm changes",
body="Your draft will be published immediately. This action cannot be undone.",
footer='<button class="pjx-demo-btn" data-pjx-close>Cancel</button>',
).render(),
]
PJXDrawer¶
[
'<button class="pjx-demo-btn" data-pjx-open="demo-drawer">Open drawer</button>',
PJXDrawer(
id="demo-drawer",
side="right",
title="Filter results",
body="<p>Adjust filters to narrow down your results.</p>",
footer='<button class="pjx-demo-btn" data-pjx-close>Done</button>',
).render(),
]
PJXConfirmDialog¶
[
"""<button class="pjx-demo-btn"
onclick="pjx.confirm('Delete this file?', { okLabel: 'Delete', danger: true })
.then(ok => { if (ok) alert('Deleted.') })">Delete file</button>""",
PJXConfirmDialog(id="demo-confirm").render(),
]
PJXPromptDialog¶
[
"""<button class="pjx-demo-btn"
onclick="pjx.prompt('Rename file', { initial: 'report.pdf', placeholder: 'New name' })
.then(name => { if (name !== null) alert('Renamed to: ' + name) })">Rename file</button>""",
PJXPromptDialog(id="demo-prompt").render(),
]
PJXNotification¶
PJXNotification(
id="demo-notification",
content="Your changes have been saved.",
corner="top-right",
timeout=4000,
autoshow=True,
).render()
PJXAlert¶
PJXAlert(
id="demo-alert",
variant="warning",
title="Storage almost full",
body="You have used 90% of your storage quota. Consider removing old files.",
dismissible=True,
).render()
PJXTooltip¶
PJXTooltip(
id="demo-tooltip",
trigger="Hover over me",
tip="This is additional context shown on hover or focus.",
placement="top",
).render()
PJXPopover¶
PJXPopover(
id="demo-popover",
content=(
PJXPopoverTrigger(id="demo-popover-t", content="Show info", role="dialog").render()
+ PJXPopoverPanel(
id="demo-popover-p",
role="dialog",
content="<p>Here is some extra detail about this item.</p>",
).render()
),
).render()
Interaction & loading¶
PJXDropdown¶
PJXDropdown(
trigger="Actions",
items=[
"<button>Edit</button>",
"<button>Duplicate</button>",
"<button>Delete</button>",
],
menu_label="Actions menu",
).render()
PJXTabGroup¶
PJXTabGroup(
tabs={
"Overview": "<p>Project summary and key metrics.</p>",
"Activity": "<p>Recent commits and deploys.</p>",
"Settings": "<p>Repository configuration.</p>",
},
tabs_label="Project tabs",
).render()
PJXPanel¶
[
'<div style="display:flex;gap:0.5rem;margin-bottom:1rem">',
PJXPanelTrigger(
panel_id="demo-panel",
panel="chat",
content='<button class="pjx-demo-btn">Chat</button>',
).render(),
PJXPanelTrigger(
panel_id="demo-panel",
panel="files",
content='<button class="pjx-demo-btn">Files</button>',
).render(),
PJXPanelTrigger(
panel_id="demo-panel",
panel="settings",
content='<button class="pjx-demo-btn">Settings</button>',
).render(),
"</div>",
PJXPanel(
id="demo-panel",
panels={
"chat": "<p>Active conversations with your team.</p>",
"files": "<p>Uploaded assets and project documents.</p>",
"settings": "<p>Notification preferences and integrations.</p>",
},
).render(),
]
PJXToastHost¶
[
'<button class="pjx-demo-btn" onclick="pjx.toast(\'Saved.\')">Show toast</button>',
PJXToastHost(position="bottom-right").render(),
]
PJXRegionLoader¶
[
'<div style="position:relative;min-height:6rem;padding:1rem;border:1px solid #8884;border-radius:6px">',
'<p style="margin:0">Region content — click to trigger a loading veil.</p>',
PJXRegionLoader(id="demo-region").render(),
"</div>",
"""<button class="pjx-demo-btn" style="margin-top:0.75rem"
onclick="pjx.loader.region.show('demo-region');setTimeout(()=>pjx.loader.region.hide('demo-region'),1500)">
Simulate load</button>""",
]
PJXPageLoader¶
[
PJXPageLoader(id="demo-page-loader").render(),
"""<button class="pjx-demo-btn" style="margin-top:0.75rem"
onclick="pjx.loader.page.show();setTimeout(()=>pjx.loader.page.hide(),1500)">
Simulate load</button>""",
]
Form controls¶
PJXChipInput¶
PJXFormField¶
PJXFormField(
label="Email address",
for_id="demo-email",
content='<input id="demo-email" type="email" name="email" placeholder="you@example.com">',
help="We'll never share your email with anyone.",
required=True,
).render()
PJXToggleSwitch¶
PJXSegmentedControl¶
PJXSegmentedControl(
name="view",
options=[("list", "List"), ("grid", "Grid"), ("table", "Table")],
selected="grid",
).render()