diff --git a/packages/app-elements/src/ui/atoms/Icon/icons.tsx b/packages/app-elements/src/ui/atoms/Icon/icons.tsx index 2bf7c1ab..5795249a 100644 --- a/packages/app-elements/src/ui/atoms/Icon/icons.tsx +++ b/packages/app-elements/src/ui/atoms/Icon/icons.tsx @@ -53,6 +53,7 @@ export const iconMapping = { equals: phosphor.EqualsIcon, eye: phosphor.EyeIcon, eyeSlash: phosphor.EyeSlashIcon, + fileArrowDown: phosphor.FileArrowDownIcon, flag: phosphor.FlagIcon, folderOpen: phosphor.FolderOpenIcon, funnel: phosphor.FunnelIcon, diff --git a/packages/app-elements/src/ui/atoms/RadialProgress.tsx b/packages/app-elements/src/ui/atoms/RadialProgress.tsx index f0ab821f..099fd326 100644 --- a/packages/app-elements/src/ui/atoms/RadialProgress.tsx +++ b/packages/app-elements/src/ui/atoms/RadialProgress.tsx @@ -13,11 +13,16 @@ export interface RadialProgressProps extends SVGAttributes { * When missing, default size is 42px, small is 24px * @default 'large' */ - size?: "small" | "large" + size?: "small" | "large" | "x-large" /** * Optional icon to be rendered in the center of the circle */ icon?: StatusIconProps["name"] + + /** + * Optional alignment of the component + */ + align?: "center" } /** @@ -32,9 +37,10 @@ function RadialProgress({ className, size = "large", icon, + align, ...rest }: RadialProgressProps): JSX.Element { - const sizePixels = size === "small" ? 24 : 42 + const sizePixels = size === "small" ? 24 : size === "x-large" ? 56 : 42 const viewBox = `0 0 ${sizePixels * 2} ${sizePixels * 2}` const circumference = sizePixels * 2 * Math.PI const emptyOffset = @@ -46,7 +52,13 @@ function RadialProgress({ data-testid="radial-progress" viewBox={viewBox} xmlns="http://www.w3.org/2000/svg" - className={cn("transform -rotate-90 rounded-full", className)} + className={cn( + "transform -rotate-90 rounded-full", + { + "mx-auto": align === "center", + }, + className, + )} width={sizePixels} height={sizePixels} {...rest} diff --git a/packages/app-elements/src/ui/atoms/StatusIcon.tsx b/packages/app-elements/src/ui/atoms/StatusIcon.tsx index 6a128412..5ebf90d5 100644 --- a/packages/app-elements/src/ui/atoms/StatusIcon.tsx +++ b/packages/app-elements/src/ui/atoms/StatusIcon.tsx @@ -23,7 +23,11 @@ export interface StatusIconProps extends React.HTMLAttributes { /** * padding around the icon can bne: 'none' | 'small' | 'large' */ - gap?: "none" | "small" | "medium" | "large" + gap?: "none" | "small" | "medium" | "large" | "x-large" + /** + * Optional alignment of the component + */ + align?: "center" } export const StatusIcon: React.FC = ({ @@ -31,15 +35,30 @@ export const StatusIcon: React.FC = ({ className, background = "none", gap = "none", + align, ...rest }) => { + const iconSize = (gap?: StatusIconProps["gap"]): string | undefined => { + switch (gap) { + case "x-large": + return "1.65rem" + case "large": + return "1.25rem" + default: + return undefined + } + } + return (
= ({ { "bg-teal border-teal text-white": background === "teal" }, { "bg-white border-gray-200": background === "white" }, { "bg-gray-800 border-gray-800 text-white": background === "black" }, + // className className, ])} @@ -62,7 +82,7 @@ export const StatusIcon: React.FC = ({ >
diff --git a/packages/app-elements/src/ui/composite/Modal.tsx b/packages/app-elements/src/ui/composite/Modal.tsx index f8bb93b0..8247d45f 100644 --- a/packages/app-elements/src/ui/composite/Modal.tsx +++ b/packages/app-elements/src/ui/composite/Modal.tsx @@ -27,7 +27,7 @@ export type ModalProps = { /** Modal content */ children: React.ReactNode /** Max width preset */ - size?: "large" | "small" + size?: "large" | "small" | "x-small" } export const Modal: React.FC< @@ -56,7 +56,7 @@ export const Modal: React.FC<
@@ -131,14 +132,12 @@ Modal.Header = ({ children }) => { } Modal.Body = ({ children }) => { - return ( -
{children}
- ) + return
{children}
} Modal.Footer = ({ children }) => { return ( -
+
{children}
) diff --git a/packages/docs/src/stories/composite/Modal.stories.tsx b/packages/docs/src/stories/composite/Modal.stories.tsx index 1981882d..933a8380 100644 --- a/packages/docs/src/stories/composite/Modal.stories.tsx +++ b/packages/docs/src/stories/composite/Modal.stories.tsx @@ -8,6 +8,10 @@ import { import type { Meta, StoryFn } from "@storybook/react-vite" import { useRef, useState } from "react" import { Button } from "#ui/atoms/Button" +import { Icon } from "#ui/atoms/Icon" +import { Spacer } from "#ui/atoms/Spacer" +import { StatusIcon } from "#ui/atoms/StatusIcon" +import { Text } from "#ui/atoms/Text" import { Modal } from "#ui/composite/Modal" import { InputSelect } from "#ui/forms/InputSelect" @@ -169,3 +173,62 @@ export const WithInput: StoryFn = () => {
) } + +/** + * Modal as dialog without header + */ +export const AsDialog: StoryFn = () => { + const [show, setShow] = useState(false) + + const handleClose = () => setShow(false) + const handleShow = () => setShow(true) + + return ( +
+ + + + + + + + Your coupons are ready. + + + + Download now or find them later in Imports. + + + + + + + + +
+ ) +}