Floating chrome actions
Optional floating action chrome owned by Shellui and driven by embedded apps through the SDK. Apps declare intent; the shell renders buttons above/below the iframe, reserves safe padding, and posts click events back into that iframe only.
Quick start
import { shellui } from '@shellui/sdk';
await shellui.init();
shellui.actions.set({
back: {
id: 'back',
onClick: () => history.back(),
},
title: 'Inbox',
trailing: [
{ id: 'edit', label: 'Edit', onClick: () => {} },
{ id: 'share', label: 'Share', onClick: () => {} },
],
primary: {
id: 'compose',
icon: 'plus',
onClick: () => {},
},
});
// When leaving the screen / route:
shellui.actions.clear();
SPA navigation (important)
Shellui does not infer actions from the iframe URL or history. On every in-app route change you must:
shellui.actions.set(...)for the new screen, orshellui.actions.clear()when the screen should not show chrome.
Shell navigation to another app / contentView clears that iframe’s actions and resets padding automatically.
Density caps
| Slot | Cap |
|---|---|
back | 1 |
title | 1 |
trailing | up to 8 kept; ≤3 visible on desktop (rest in ···); on mobile/tablet all trailing collapse into ··· |
primary | 1 bottom FAB |
Missing id values are skipped (warned). Duplicate ids across slots are rejected.
Clicks
Clicking a chrome control posts SHELLUI_ACTION with { id } into only the declaring iframe. The SDK triggers the matching onClick registered by actions.set. Callbacks stay registered until the next set / clear (unlike one-shot toasts).
Layouts
- Floating / sidebar / app-bar / fullscreen: top bar overlays the content iframe; the shell publishes safe
--shellui-inset-*padding whenever actions are set (including non-floating layouts, vialayout: 'actions'). Padding animates with a short CSS transition on show/hide. Primary FAB sits above floating tab bar when present (extra bottom inset). - Windows: top actions render in the window title bar (no top inset); FAB still overlays the window content with bottom inset.
Icons
icon may be a URL / path (https://…, data:…, /icons/edit.svg) or a built-in name:
back, plus, more, edit, share, filter, archive, settings, delete, star, refresh
Provide label and/or icon. Custom React nodes are not supported (actions cross the iframe boundary as JSON).
Glyph animation
Set animate: 'icon-rotate' to spin the glyph continuously (typical refresh / loading). Pair with disabled: true while work is in flight:
shellui.actions.set({
trailing: [
{
id: 'refresh',
icon: 'refresh',
label: 'Refresh',
disabled: true,
animate: 'icon-rotate',
onClick: () => {},
},
],
});
Known limitations
postMessagetarget origin is'*'forSHELLUI_ACTIONS_SET/CLEAR(same pattern as toast, dialog, and modal SDK messages). Any script listening on the parent window can observe action ids and labels. Prefer same-origin shell embeddings; locking the target origin is planned before GA.
Try it locally
Minimal smoke harness (not a product demo):
- Run a Shellui app (
shellui start). - Open Settings → Develop.
- Use Chrome actions → Open demo (modal iframe) or Open demo (drawer iframe).
- Inside the demo iframe, use Set / Update / Clear. Clicks toast via the real
SHELLUI_ACTIONround-trip.
Narrow the viewport to exercise the ··· overflow menu.
Clickable showcase (code sample + triggers): separate PR on shellui/playground (coming) — preferred place for the UX demo.
Out of scope (v2+)
- Floating search / text-field slots
- Auto-inferring actions from iframe URL
- Locked
postMessagetarget origin (see Known limitations)