Profile: add subscribe menu
This commit is contained in:
parent
8a435be4c8
commit
65fa4c4fa5
6 changed files with 226 additions and 151 deletions
src/material
|
@ -3,8 +3,9 @@ import { MenuList } from "@suid/material";
|
|||
import {
|
||||
createEffect,
|
||||
createSignal,
|
||||
type Component,
|
||||
type JSX,
|
||||
type ParentComponent,
|
||||
type ParentProps,
|
||||
} from "solid-js";
|
||||
import { ANIM_CURVE_STD } from "./theme";
|
||||
import "./Menu.css";
|
||||
|
@ -13,13 +14,13 @@ import {
|
|||
animateShrinkToTopRight,
|
||||
} from "../platform/anim";
|
||||
|
||||
type Anchor = Pick<DOMRect, "top" | "left" | "right">
|
||||
export type Anchor = Pick<DOMRect, "top" | "left" | "right">
|
||||
|
||||
type Props = {
|
||||
export type MenuProps = ParentProps<{
|
||||
open?: boolean;
|
||||
onClose?: JSX.EventHandlerUnion<HTMLDialogElement, Event>;
|
||||
anchor: () => Anchor;
|
||||
};
|
||||
}>;
|
||||
|
||||
function px(n?: number) {
|
||||
if (n) {
|
||||
|
@ -29,7 +30,22 @@ function px(n?: number) {
|
|||
}
|
||||
}
|
||||
|
||||
const Menu: ParentComponent<Props> = (props) => {
|
||||
export function createManagedMenuState() {
|
||||
const [anchor, setAnchor] = createSignal<Anchor>();
|
||||
|
||||
return [
|
||||
setAnchor,
|
||||
{
|
||||
get open() {
|
||||
return !!anchor();
|
||||
},
|
||||
anchor: anchor as () => Anchor,
|
||||
onClose: () => setAnchor(),
|
||||
},
|
||||
] as const;
|
||||
}
|
||||
|
||||
const Menu: Component<MenuProps> = (props) => {
|
||||
let root: HTMLDialogElement;
|
||||
const windowSize = useWindowSize();
|
||||
|
||||
|
|
22
src/material/Scaffold.css
Normal file
22
src/material/Scaffold.css
Normal file
|
@ -0,0 +1,22 @@
|
|||
|
||||
.Scaffold__topbar {
|
||||
position: sticky;
|
||||
top: 0px;
|
||||
z-index: var(--tutu-zidx-nav, auto);
|
||||
}
|
||||
|
||||
.Scaffold__fab-dock {
|
||||
position: fixed;
|
||||
bottom: 40px;
|
||||
right: 40px;
|
||||
z-index: var(--tutu-zidx-nav, auto);
|
||||
}
|
||||
|
||||
.Scaffold__bottom-dock {
|
||||
position: sticky;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
z-index: var(--tutu-zidx-nav, auto);
|
||||
padding-bottom: var(--safe-area-inset-bottom, 0);
|
||||
}
|
|
@ -1,66 +1,67 @@
|
|||
import { createElementSize } from "@solid-primitives/resize-observer";
|
||||
import {
|
||||
JSX,
|
||||
Show,
|
||||
createRenderEffect,
|
||||
createSignal,
|
||||
onCleanup,
|
||||
type JSX,
|
||||
type ParentComponent,
|
||||
splitProps,
|
||||
type Component,
|
||||
type ParentProps,
|
||||
} from "solid-js";
|
||||
import { css } from "solid-styled";
|
||||
import "./Scaffold.css";
|
||||
|
||||
interface ScaffoldProps {
|
||||
topbar?: JSX.Element;
|
||||
fab?: JSX.Element;
|
||||
bottom?: JSX.Element;
|
||||
}
|
||||
type ScaffoldProps = ParentProps<
|
||||
{
|
||||
topbar?: JSX.Element;
|
||||
fab?: JSX.Element;
|
||||
bottom?: JSX.Element;
|
||||
} & JSX.HTMLElementTags["div"]
|
||||
>;
|
||||
|
||||
const Scaffold: ParentComponent<ScaffoldProps> = (props) => {
|
||||
/**
|
||||
* The passthrough props are passed to the content container.
|
||||
*/
|
||||
const Scaffold: Component<ScaffoldProps> = (props) => {
|
||||
const [managed, rest] = splitProps(props, [
|
||||
"topbar",
|
||||
"fab",
|
||||
"bottom",
|
||||
"children",
|
||||
"ref",
|
||||
]);
|
||||
const [topbarElement, setTopbarElement] = createSignal<HTMLElement>();
|
||||
|
||||
const topbarSize = createElementSize(topbarElement);
|
||||
|
||||
css`
|
||||
.scaffold-content {
|
||||
--scaffold-topbar-height: ${(topbarSize.height?.toString() ?? 0) + "px"};
|
||||
}
|
||||
|
||||
.topbar {
|
||||
position: sticky;
|
||||
top: 0px;
|
||||
z-index: var(--tutu-zidx-nav, auto);
|
||||
}
|
||||
|
||||
.fab-dock {
|
||||
position: fixed;
|
||||
bottom: 40px;
|
||||
right: 40px;
|
||||
z-index: var(--tutu-zidx-nav, auto);
|
||||
}
|
||||
|
||||
.bottom-dock {
|
||||
position: sticky;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
z-index: var(--tutu-zidx-nav, auto);
|
||||
padding-bottom: var(--safe-area-inset-bottom, 0);
|
||||
|
||||
}
|
||||
`;
|
||||
return (
|
||||
<>
|
||||
<Show when={props.topbar}>
|
||||
<div class="topbar" ref={setTopbarElement}>
|
||||
<div class="Scaffold__topbar" ref={setTopbarElement}>
|
||||
{props.topbar}
|
||||
</div>
|
||||
</Show>
|
||||
<Show when={props.fab}>
|
||||
<div class="fab-dock">{props.fab}</div>
|
||||
<div class="Scaffold__fab-dock">{props.fab}</div>
|
||||
</Show>
|
||||
<div class="scaffold-content">{props.children}</div>
|
||||
<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>
|
||||
<Show when={props.bottom}>
|
||||
<div class="bottom-dock">{props.bottom}</div>
|
||||
<div class="Scaffold__bottom-dock">{props.bottom}</div>
|
||||
</Show>
|
||||
</>
|
||||
);
|
||||
|
|
|
@ -106,6 +106,8 @@
|
|||
|
||||
/* Submenu (+1dp for each submenu) */
|
||||
--tutu-shadow-e9: 0px 9px 18px 0px var(--tutu-color-shadow);
|
||||
--tutu-shadow-e10: 0px 10px 18px 0px var(--tutu-color-shadow);
|
||||
--tutu-shadow-e11: 0px 11px 18px 0px var(--tutu-color-shadow-l1);
|
||||
|
||||
/* (pressed) FAB */
|
||||
--tutu-shadow-e12: 0px 12px 24px 0px var(--tutu-color-shadow-l1);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue