Floating Action Button.
Page content
<div class="fab-frame">
<p class="fab-frame__hint">Page content</p>
<button type="button" class="fab fab--bottom-right fab--md" style="--bg:#241430" aria-label="Create new item">
<svg width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><path d="M12 5v14M5 12h14"/></svg>
</button>
</div>
<style>
.fab-frame { position: relative; height: 220px; border: 1px dashed rgba(36,20,48,.25); overflow: hidden; }
.fab-frame__hint { margin: 14px; font: 500 13px/1 system-ui, sans-serif; color: rgba(36,20,48,.5); }
.fab {
position: absolute;
display: inline-flex; align-items: center; justify-content: center; gap: 8px;
width: 56px; height: 56px;
border-radius: 999px;
border: none;
background: var(--bg);
color: #FAF7F2;
cursor: pointer;
box-shadow: 0 6px 16px rgba(36,20,48,.3);
}
.fab--lg { width: 64px; height: 64px; }
.fab--extended { width: auto; height: 52px; padding: 0 22px 0 20px; border-radius: 999px; }
.fab--bottom-right { right: 16px; bottom: 16px; }
.fab--bottom-left { left: 16px; bottom: 16px; }
.fab--top-right { right: 16px; top: 16px; }
.fab--top-left { left: 16px; top: 16px; }
.fab:hover { filter: brightness(1.1); }
.fab:active { filter: brightness(0.92); }
.fab:focus-visible { outline: 3px solid #241430; outline-offset: 3px; }
.fab__label { font: 600 14px/1 system-ui, sans-serif; white-space: nowrap; }
</style><div class="relative h-[220px] overflow-hidden" style="border:1px dashed rgba(36,20,48,.25)">
<p class="m-3.5 text-[13px] font-medium" style="color:rgba(36,20,48,.5)">Page content</p>
<button type="button" class="absolute inline-flex items-center justify-center gap-2 rounded-full border-none text-[#FAF7F2] cursor-pointer shadow-lg hover:brightness-110 active:brightness-90 fab-tw fab-tw--bottom-right fab-tw--md" style="background:#241430" aria-label="Create new item">
<svg width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><path d="M12 5v14M5 12h14"/></svg>
</button>
</div>
<style>
.fab-tw--md { width: 56px; height: 56px; }
.fab-tw--lg { width: 64px; height: 64px; }
.fab-tw--extended { width: auto; height: 52px; padding: 0 22px 0 20px; }
.fab-tw--bottom-right { right: 16px; bottom: 16px; }
.fab-tw--bottom-left { left: 16px; bottom: 16px; }
.fab-tw--top-right { right: 16px; top: 16px; }
.fab-tw--top-left { left: 16px; top: 16px; }
.fab-tw--bottom-right:focus-visible { outline: 3px solid #241430; outline-offset: 3px; }
</style>export function Fab({
label = "Create new item",
corner = "bottom-right",
size = "md",
bg = "#241430",
extended = false,
}) {
const pos = {
"bottom-right": { right: 16, bottom: 16 },
"bottom-left": { left: 16, bottom: 16 },
"top-right": { right: 16, top: 16 },
"top-left": { left: 16, top: 16 },
}[corner];
const dim = size === "lg" ? 64 : 56;
return (
<div style={{ position: "relative", height: 220, border: "1px dashed rgba(36,20,48,.25)", overflow: "hidden" }}>
<p style={{ margin: 14, font: "500 13px/1 system-ui, sans-serif", color: "rgba(36,20,48,.5)" }}>Page content</p>
<button
type="button"
aria-label={label}
style={{
position: "absolute",
...pos,
display: "inline-flex",
alignItems: "center",
justifyContent: "center",
gap: 8,
width: extended ? "auto" : dim,
height: extended ? 52 : dim,
padding: extended ? "0 22px 0 20px" : 0,
borderRadius: 999,
border: "none",
background: bg,
color: "#FAF7F2",
cursor: "pointer",
boxShadow: "0 6px 16px rgba(36,20,48,.3)",
}}
>
<svg width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true">
<path d="M12 5v14M5 12h14" />
</svg>
{extended && <span style={{ font: "600 14px/1 system-ui, sans-serif", whiteSpace: "nowrap" }}>{label}</span>}
</button>
</div>
);
}