tutu/src/material/Scaffold.tsx

71 lines
1.5 KiB
TypeScript
Raw Normal View History

2024-07-14 12:28:44 +00:00
import { createElementSize } from "@solid-primitives/resize-observer";
import {
2024-11-03 12:50:31 +00:00
JSX,
2024-07-14 12:28:44 +00:00
Show,
createRenderEffect,
createSignal,
2024-11-03 12:50:31 +00:00
splitProps,
type Component,
type ParentProps,
2024-07-14 12:28:44 +00:00
} from "solid-js";
2024-11-03 12:50:31 +00:00
import "./Scaffold.css";
2024-07-14 12:28:44 +00:00
2024-11-03 12:50:31 +00:00
type ScaffoldProps = ParentProps<
{
topbar?: JSX.Element;
fab?: JSX.Element;
bottom?: JSX.Element;
} & JSX.HTMLElementTags["div"]
>;
2024-07-14 12:28:44 +00:00
2024-11-03 12:50:31 +00:00
/**
* The passthrough props are passed to the content container.
*/
const Scaffold: Component<ScaffoldProps> = (props) => {
const [managed, rest] = splitProps(props, [
"topbar",
"fab",
"bottom",
"children",
"ref",
]);
2024-07-14 12:28:44 +00:00
const [topbarElement, setTopbarElement] = createSignal<HTMLElement>();
const topbarSize = createElementSize(topbarElement);
return (
<>
<Show when={props.topbar}>
2024-11-03 12:50:31 +00:00
<div class="Scaffold__topbar" ref={setTopbarElement}>
2024-07-14 12:28:44 +00:00
{props.topbar}
</div>
</Show>
<Show when={props.fab}>
2024-11-03 12:50:31 +00:00
<div class="Scaffold__fab-dock">{props.fab}</div>
2024-07-14 12:28:44 +00:00
</Show>
2024-11-03 12:50:31 +00:00
<div
ref={(e) => {
createRenderEffect(() => {
e.style.setProperty(
"--scaffold-topbar-height",
(topbarSize.height?.toString() ?? 0) + "px",
);
});
if (managed.ref) {
(managed.ref as (val: typeof e) => void)(e);
}
}}
{...rest}
>
{managed.children}
</div>
2024-09-25 11:30:05 +00:00
<Show when={props.bottom}>
2024-11-03 12:50:31 +00:00
<div class="Scaffold__bottom-dock">{props.bottom}</div>
2024-09-25 11:30:05 +00:00
</Show>
2024-07-14 12:28:44 +00:00
</>
);
};
export default Scaffold;