Skip to content

Commit

Permalink
allow configuring right side modal width
Browse files Browse the repository at this point in the history
  • Loading branch information
fontanierh committed Oct 26, 2023
1 parent a896470 commit 175b554
Show file tree
Hide file tree
Showing 2 changed files with 69 additions and 20 deletions.
51 changes: 31 additions & 20 deletions sparkle/src/components/Modal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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,
Expand All @@ -31,7 +44,7 @@ export function Modal({
isSaving,
savingLabel,
title,
type = "default",
...props
}: ModalProps) {
const buttonBarProps: BarHeaderButtonBarProps = hasChanged
? {
Expand All @@ -48,55 +61,54 @@ export function Modal({
};

const justifyClass = (() => {
switch (type) {
switch (props.type) {
case "right-side":
case "right-side-wide":
return "s-justify-end";

case "full-screen":
case "default":
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";

case "default":
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":
case "default":
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";
Expand All @@ -105,22 +117,21 @@ 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";

case "default":
return "";

default:
throw assertNever(type);
throw assertNever(props);
}
})();

Expand Down
38 changes: 38 additions & 0 deletions sparkle/src/stories/Modal.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,18 @@ 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 (
<Page.Layout gap="md">
<Modal
isOpen={isOpenNoActionNoChange}
onClose={() => setIsOpenNoActionNoChange(false)}
hasChanged={false}
title="Modal title"
type="default"
>
<div className="s-mt-4 s-h-72">I'm the modal content</div>
</Modal>
Expand Down Expand Up @@ -62,6 +67,7 @@ export const ModalExample = () => {
}}
saveLabel="Save (custom name possible)"
hasChanged={true}
type="default"
>
<div className="s-mt-4 s-h-72 s-text-left">I'm the modal content</div>
</Modal>
Expand Down Expand Up @@ -94,6 +100,30 @@ export const ModalExample = () => {
I'm the modal content
</div>
</Modal>
<Modal
isOpen={isRightSideWideModalOpen}
onClose={() => setIsRightSideWideModalOpen(false)}
hasChanged={false}
type="right-side"
title="Modal title"
width="wide"
>
<div className="s-mt-4 s-h-72 s-text-left">
I'm the modal content, and I am wide
</div>
</Modal>
<Modal
isOpen={isRightSideUltraWideModalOpen}
onClose={() => setIsRightSideUltraWideModalOpen(false)}
hasChanged={false}
type="right-side"
title="Modal title"
width="ultra-wide"
>
<div className="s-mt-4 s-h-72 s-text-left">
I'm the modal content, and I am ultra-wide
</div>
</Modal>
<Button
label="Modal without action and without changes"
onClick={() => setIsOpenNoActionNoChange(true)}
Expand All @@ -114,6 +144,14 @@ export const ModalExample = () => {
label="Modal right side"
onClick={() => setIsRightSideModalOpen(true)}
/>
<Button
label="Modal right side wide"
onClick={() => setIsRightSideWideModalOpen(true)}
/>
<Button
label="Modal right side ultra-wide"
onClick={() => setIsRightSideUltraWideModalOpen(true)}
/>
</Page.Layout>
);
};

0 comments on commit 175b554

Please sign in to comment.