diff --git a/src/material/BottomSheet.tsx b/src/material/BottomSheet.tsx index 73fd734..b9a9f38 100644 --- a/src/material/BottomSheet.tsx +++ b/src/material/BottomSheet.tsx @@ -1,14 +1,19 @@ import { children, createEffect, + createSignal, onCleanup, useTransition, type JSX, type ParentComponent, + type ResolvedChildren, } from "solid-js"; import "./BottomSheet.css"; import material from "./material.module.css"; -import { ANIM_CURVE_ACELERATION, ANIM_CURVE_DECELERATION } from "./theme"; +import { + ANIM_CURVE_ACELERATION, + ANIM_CURVE_DECELERATION, +} from "./theme"; import { animateSlideInFromRight, animateSlideOutToRight, @@ -23,36 +28,11 @@ export type BottomSheetProps = { const MOVE_SPEED = 1600; -function animateSlideInFromBottom(element: HTMLElement, reverse?: boolean) { - const rect = element.getBoundingClientRect(); - const easing = "cubic-bezier(0.4, 0, 0.2, 1)"; - element.classList.add("animated"); - const oldOverflow = document.body.style.overflow; - document.body.style.overflow = "hidden"; - const distance = Math.abs(rect.top - window.innerHeight); - const duration = (distance / MOVE_SPEED) * 1000; - - const animation = element.animate( - { - top: reverse - ? [`${rect.top}px`, `${window.innerHeight}px`] - : [`${window.innerHeight}px`, `${rect.top}px`], - }, - { easing, duration }, - ); - const onAnimationEnd = () => { - element.classList.remove("animated"); - document.body.style.overflow = oldOverflow; - }; - animation.addEventListener("cancel", onAnimationEnd); - animation.addEventListener("finish", onAnimationEnd); - return animation; -} - const BottomSheet: ParentComponent = (props) => { let element: HTMLDialogElement; let animation: Animation | undefined; - const child = children(() => props.children); + const [cache, setCache] = createSignal(); + const ochildren = children(() => props.children); const [pending] = useTransition(); @@ -60,10 +40,12 @@ const BottomSheet: ParentComponent = (props) => { if (props.open) { if (!element.open && !pending()) { requestAnimationFrame(animatedOpen); + setCache(ochildren()); } } else { if (element.open) { animatedClose(); + setCache(undefined); } } }); @@ -73,21 +55,22 @@ const BottomSheet: ParentComponent = (props) => { }; const animatedClose = () => { - if (window.innerWidth > 560 && !props.bottomUp) { - onClose(); - return; - } - const onAnimationEnd = () => { - element.classList.remove("animated"); - animation = undefined; - onClose(); - }; - element.classList.add("animated"); - animation = props.bottomUp - ? animateSlideInFromBottom(element, true) - : animateSlideOutToRight(element, { easing: ANIM_CURVE_ACELERATION }); - animation.addEventListener("finish", onAnimationEnd); - animation.addEventListener("cancel", onAnimationEnd); + + if (window.innerWidth > 560 && !props.bottomUp) { + onClose(); + return; + } + const onAnimationEnd = () => { + element.classList.remove("animated"); + onClose(); + }; + element.classList.add("animated"); + animation = props.bottomUp + ? animateSlideInFromBottom(element, true) + : animateSlideOutToRight(element, { easing: ANIM_CURVE_ACELERATION }); + animation.addEventListener("finish", onAnimationEnd); + animation.addEventListener("cancel", onAnimationEnd); + }; const animatedOpen = () => { @@ -98,7 +81,6 @@ const BottomSheet: ParentComponent = (props) => { element.classList.add("animated"); const onAnimationEnd = () => { element.classList.remove("animated"); - animation = undefined; }; animation = animateSlideInFromRight(element, { easing: ANIM_CURVE_DECELERATION, @@ -108,6 +90,36 @@ const BottomSheet: ParentComponent = (props) => { } }; + const animateSlideInFromBottom = ( + element: HTMLElement, + reserve?: boolean, + ) => { + const rect = element.getBoundingClientRect(); + const easing = "cubic-bezier(0.4, 0, 0.2, 1)"; + element.classList.add("animated"); + const oldOverflow = document.body.style.overflow; + document.body.style.overflow = "hidden"; + const distance = Math.abs(rect.top - window.innerHeight); + const duration = (distance / MOVE_SPEED) * 1000; + + animation = element.animate( + { + top: reserve + ? [`${rect.top}px`, `${window.innerHeight}px`] + : [`${window.innerHeight}px`, `${rect.top}px`], + }, + { easing, duration }, + ); + const onAnimationEnd = () => { + element.classList.remove("animated"); + document.body.style.overflow = oldOverflow; + animation = undefined; + }; + animation.addEventListener("cancel", onAnimationEnd); + animation.addEventListener("finish", onAnimationEnd); + return animation; + }; + onCleanup(() => { if (animation) { animation.cancel(); @@ -117,7 +129,6 @@ const BottomSheet: ParentComponent = (props) => { const onDialogClick = ( event: MouseEvent & { currentTarget: HTMLDialogElement }, ) => { - event.stopPropagation(); if (event.target !== event.currentTarget) return; const rect = event.currentTarget.getBoundingClientRect(); const isNotInDialog = @@ -148,7 +159,7 @@ const BottomSheet: ParentComponent = (props) => { tabIndex={-1} role="presentation" > - {child()} + {ochildren() ?? cache()} ); }; diff --git a/src/material/theme.css b/src/material/theme.css index fc8d718..5048f98 100644 --- a/src/material/theme.css +++ b/src/material/theme.css @@ -153,8 +153,6 @@ --tutu-transition-shadow: box-shadow 175ms var(--tutu-anim-curve-std); --tutu-zidx-nav: 1100; - - accent-color: var(--tutu-color-primary); } * { diff --git a/src/material/theme.ts b/src/material/theme.ts index 0eb4eaf..a7c2c65 100644 --- a/src/material/theme.ts +++ b/src/material/theme.ts @@ -1,5 +1,5 @@ import { Theme, createTheme } from "@suid/material/styles"; -import { deepPurple, amber, red } from "@suid/material/colors"; +import { deepPurple, amber } from "@suid/material/colors"; import { Accessor } from "solid-js"; /** @@ -12,9 +12,6 @@ export function useRootTheme(): Accessor { primary: { main: deepPurple[500], }, - error: { - main: red[900], - }, secondary: { main: amber.A200, }, diff --git a/src/profiles/Profile.css b/src/profiles/Profile.css index 021afdd..a8ce070 100644 --- a/src/profiles/Profile.css +++ b/src/profiles/Profile.css @@ -8,7 +8,6 @@ display: flex; flex-flow: column nowrap; gap: 16px; - contain: layout style; } .banner { diff --git a/src/profiles/Profile.tsx b/src/profiles/Profile.tsx index 56f6c8e..f795c7c 100644 --- a/src/profiles/Profile.tsx +++ b/src/profiles/Profile.tsx @@ -237,7 +237,7 @@ const Profile: Component = () => { } class="Profile" > - -