From a167e70e637c7bf1d5f329f033204aa2779bae7c Mon Sep 17 00:00:00 2001 From: Johannes Kirschbauer Date: Tue, 19 Aug 2025 12:50:19 +0200 Subject: [PATCH] ui/modal: refactor mounting and controlled state --- .../ui/src/components/Modal/Modal.module.css | 8 ++ .../ui/src/components/Modal/Modal.tsx | 93 ++++++++++--------- pkgs/clan-app/ui/src/routes/Clan/Clan.tsx | 1 + pkgs/clan-app/ui/src/routes/Layout.tsx | 3 +- .../ui/src/routes/Machine/Machine.tsx | 17 ++-- .../ui/src/workflows/Install/install.tsx | 3 +- 6 files changed, 68 insertions(+), 57 deletions(-) diff --git a/pkgs/clan-app/ui/src/components/Modal/Modal.module.css b/pkgs/clan-app/ui/src/components/Modal/Modal.module.css index 5624aa7e0..4eefd08a6 100644 --- a/pkgs/clan-app/ui/src/components/Modal/Modal.module.css +++ b/pkgs/clan-app/ui/src/components/Modal/Modal.module.css @@ -35,3 +35,11 @@ .header_divider { @apply bg-def-3 h-[6px] border-def-2 border-t-[1px]; } + +.backdrop { + @apply absolute left-0 top-0 z-50 size-full bg-white/90; +} + +.contentWrapper { + @apply absolute left-0 top-0 z-50 flex size-full items-center justify-center; +} diff --git a/pkgs/clan-app/ui/src/components/Modal/Modal.tsx b/pkgs/clan-app/ui/src/components/Modal/Modal.tsx index edfde6462..cfe31ce80 100644 --- a/pkgs/clan-app/ui/src/components/Modal/Modal.tsx +++ b/pkgs/clan-app/ui/src/components/Modal/Modal.tsx @@ -1,4 +1,4 @@ -import { Component, createSignal, JSX, Show } from "solid-js"; +import { Component, JSX, Show } from "solid-js"; import { Dialog as KDialog } from "@kobalte/core/dialog"; import styles from "./Modal.module.css"; import { Typography } from "../Typography/Typography"; @@ -19,53 +19,58 @@ export interface ModalProps { class?: string; metaHeader?: Component; disablePadding?: boolean; + open: boolean; } export const Modal = (props: ModalProps) => { - const [open, setOpen] = createSignal(true); - return ( - - - -
- - {props.title} - - { - setOpen(false); - props.onClose(); - }} - > - - + + + +
+
+ +
+ + {props.title} + + { + props.onClose(); + }} + > + + +
+ + {(metaHeader) => ( + <> +
+ +
+
+ + )} + +
+ {props.children({ + close: () => { + props.onClose(); + }, + })} +
+
- - {(metaHeader) => ( - <> -
- -
-
- - )} - -
- {props.children({ - close: () => { - setOpen(false); - props.onClose(); - }, - })} -
- - - + + + ); }; diff --git a/pkgs/clan-app/ui/src/routes/Clan/Clan.tsx b/pkgs/clan-app/ui/src/routes/Clan/Clan.tsx index 01fe7e4d5..e4d019e0a 100644 --- a/pkgs/clan-app/ui/src/routes/Clan/Clan.tsx +++ b/pkgs/clan-app/ui/src/routes/Clan/Clan.tsx @@ -61,6 +61,7 @@ const MockCreateMachine = (props: MockProps) => { return (
(container = el)} class="create-backdrop"> { reset(form); diff --git a/pkgs/clan-app/ui/src/routes/Layout.tsx b/pkgs/clan-app/ui/src/routes/Layout.tsx index c4234137d..e1234d7bd 100644 --- a/pkgs/clan-app/ui/src/routes/Layout.tsx +++ b/pkgs/clan-app/ui/src/routes/Layout.tsx @@ -1,8 +1,7 @@ import { Component, createEffect, on } from "solid-js"; import { RouteSectionProps, useNavigate } from "@solidjs/router"; -import { activeClanURI, setActiveClanURI } from "@/src/stores/clan"; +import { activeClanURI } from "@/src/stores/clan"; import { navigateToClan } from "@/src/hooks/clan"; -import { Button } from "../components/Button/Button"; export const Layout: Component = (props) => { const navigate = useNavigate(); diff --git a/pkgs/clan-app/ui/src/routes/Machine/Machine.tsx b/pkgs/clan-app/ui/src/routes/Machine/Machine.tsx index 31db91827..271b6bc6c 100644 --- a/pkgs/clan-app/ui/src/routes/Machine/Machine.tsx +++ b/pkgs/clan-app/ui/src/routes/Machine/Machine.tsx @@ -69,17 +69,14 @@ export const Machine = (props: RouteSectionProps) => { > Install me! + {/* Unmount the whole component to destroy the store and form values */} -
(container = el)} - > - setShowModal(false)} - /> -
+ setShowModal(false)} + />
{sidebarPane(useMachineName())} diff --git a/pkgs/clan-app/ui/src/workflows/Install/install.tsx b/pkgs/clan-app/ui/src/workflows/Install/install.tsx index 518199550..b4fb82dd8 100644 --- a/pkgs/clan-app/ui/src/workflows/Install/install.tsx +++ b/pkgs/clan-app/ui/src/workflows/Install/install.tsx @@ -32,6 +32,7 @@ export interface InstallModalProps { initialStep?: InstallSteps[number]["id"]; mount?: Node; onClose?: () => void; + open: boolean; } const steps = [ @@ -85,12 +86,12 @@ export const InstallModal = (props: InstallModalProps) => { { console.log("Install modal closed"); props.onClose?.(); }} + open={props.open} // @ts-expect-error some steps might not have metaHeader={stepper.currentStep()?.title ? : undefined} // @ts-expect-error some steps might not have