From 175b55462d3cf72886488f860d1e99d03cd19adf Mon Sep 17 00:00:00 2001 From: Henry Fontanier Date: Thu, 26 Oct 2023 15:00:13 +0200 Subject: [PATCH] allow configuring right side modal width --- sparkle/src/components/Modal.tsx | 51 ++++++++++++++++----------- sparkle/src/stories/Modal.stories.tsx | 38 ++++++++++++++++++++ 2 files changed, 69 insertions(+), 20 deletions(-) diff --git a/sparkle/src/components/Modal.tsx b/sparkle/src/components/Modal.tsx index 72323f298c610..001218847f5f3 100644 --- a/sparkle/src/components/Modal.tsx +++ b/sparkle/src/components/Modal.tsx @@ -6,7 +6,13 @@ import { assertNever, classNames } from "@sparkle/lib/utils"; import { BarHeader, BarHeaderButtonBarProps } from "./BarHeader"; import { Button, ButtonProps } from "./Button"; -interface ModalProps { +const RIGHT_SIDE_MODAL_WIDTH = { + normal: "sm:s-w-[448px]", + wide: "sm:s-w-[50rem]", + "ultra-wide": "sm:s-w-[80rem]", +} as const; + +type ModalProps = { isOpen: boolean; onClose: () => void; action?: ButtonProps; @@ -17,8 +23,15 @@ interface ModalProps { isSaving?: boolean; savingLabel?: string; title?: string; - type?: "full-screen" | "right-side" | "default" | "right-side-wide"; -} +} & ( + | { + type: "right-side"; + width?: keyof typeof RIGHT_SIDE_MODAL_WIDTH; + } + | { + type: "full-screen" | "default"; + } +); export function Modal({ isOpen, @@ -31,7 +44,7 @@ export function Modal({ isSaving, savingLabel, title, - type = "default", + ...props }: ModalProps) { const buttonBarProps: BarHeaderButtonBarProps = hasChanged ? { @@ -48,9 +61,8 @@ export function Modal({ }; const justifyClass = (() => { - switch (type) { + switch (props.type) { case "right-side": - case "right-side-wide": return "s-justify-end"; case "full-screen": @@ -58,14 +70,13 @@ export function Modal({ return "s-justify-center"; default: - throw assertNever(type); + throw assertNever(props); } })(); const outerContainerClasses = (() => { - switch (type) { + switch (props.type) { case "right-side": - case "right-side-wide": case "full-screen": return "s-h-full s-p-0"; @@ -73,14 +84,13 @@ export function Modal({ return "s-min-h-full s-p-4"; default: - throw assertNever(type); + throw assertNever(props); } })(); const transitionEnterLeaveClasses = (() => { - switch (type) { + switch (props.type) { case "right-side": - case "right-side-wide": return "s-translate-x-full"; case "full-screen": @@ -88,15 +98,17 @@ export function Modal({ return "s-translate-y-4 sm:s-translate-y-0 sm:s-scale-95"; default: - throw assertNever(type); + throw assertNever(props); } })(); const panelClasses = (() => { - switch (type) { + switch (props.type) { case "right-side": - case "right-side-wide": - return "s-m-0 s-h-full s-max-h-full s-w-full s-max-w-full sm:s-w-[448px]"; + return classNames( + "s-m-0 s-h-full s-max-h-full s-w-full s-max-w-full", + RIGHT_SIDE_MODAL_WIDTH[props.width || "normal"] + ); case "full-screen": return "s-m-0 s-h-full s-max-h-full s-w-full s-max-w-full"; @@ -105,14 +117,13 @@ export function Modal({ return "s-max-w-2xl s-rounded-lg s-shadow-xl lg:s-w-1/2"; default: - throw assertNever(type); + throw assertNever(props); } })(); const innerContainerClasses = (() => { - switch (type) { + switch (props.type) { case "right-side": - case "right-side-wide": case "full-screen": return "s-h-full s-overflow-y-auto"; @@ -120,7 +131,7 @@ export function Modal({ return ""; default: - throw assertNever(type); + throw assertNever(props); } })(); diff --git a/sparkle/src/stories/Modal.stories.tsx b/sparkle/src/stories/Modal.stories.tsx index 64909329c1ef2..b3807212d71ab 100644 --- a/sparkle/src/stories/Modal.stories.tsx +++ b/sparkle/src/stories/Modal.stories.tsx @@ -19,6 +19,10 @@ export const ModalExample = () => { useState(false); const [isRightSideModalOpen, setIsRightSideModalOpen] = useState(false); const [inputValue, setInputValue] = useState("initial value"); + const [isRightSideWideModalOpen, setIsRightSideWideModalOpen] = + useState(false); + const [isRightSideUltraWideModalOpen, setIsRightSideUltraWideModalOpen] = + useState(false); return ( { onClose={() => setIsOpenNoActionNoChange(false)} hasChanged={false} title="Modal title" + type="default" >
I'm the modal content
@@ -62,6 +67,7 @@ export const ModalExample = () => { }} saveLabel="Save (custom name possible)" hasChanged={true} + type="default" >
I'm the modal content
@@ -94,6 +100,30 @@ export const ModalExample = () => { I'm the modal content + setIsRightSideWideModalOpen(false)} + hasChanged={false} + type="right-side" + title="Modal title" + width="wide" + > +
+ I'm the modal content, and I am wide +
+
+ setIsRightSideUltraWideModalOpen(false)} + hasChanged={false} + type="right-side" + title="Modal title" + width="ultra-wide" + > +
+ I'm the modal content, and I am ultra-wide +
+