From b942a54314ed037bf6b3380d9bb7f741cd1fbeab Mon Sep 17 00:00:00 2001 From: Masoud Amjadi Date: Tue, 26 Nov 2024 20:27:25 -0500 Subject: [PATCH] refactor(callout): add sdsStyle prop to control expandability or dismissability --- .../core/Callout/__storybook__/constants.tsx | 13 +++- .../Callout/__storybook__/index.stories.tsx | 31 +++----- .../Callout/__storybook__/stories/default.tsx | 14 ++-- .../components/src/core/Callout/index.tsx | 72 ++++++++++--------- packages/components/src/core/Callout/style.ts | 20 +++--- 5 files changed, 74 insertions(+), 76 deletions(-) diff --git a/packages/components/src/core/Callout/__storybook__/constants.tsx b/packages/components/src/core/Callout/__storybook__/constants.tsx index 47854bf3c..aa2fc0db6 100644 --- a/packages/components/src/core/Callout/__storybook__/constants.tsx +++ b/packages/components/src/core/Callout/__storybook__/constants.tsx @@ -1,13 +1,16 @@ -import { action } from "@storybook/addon-actions"; import CustomSdsIcon from "src/common/storybook/customSdsIcon"; import CustomSvgIcon from "src/common/storybook/customSvgIcon"; export const CALLOUT_EXCLUDED_CONTROLS = [ "autoDismiss", - "expandable", "icon", "intent", "onClose", + "sdsStyle", + "hideTitle", + "hideBody", + "title", + "body", ]; export const CALLOUT_ICON_OPTIONS = [ @@ -17,4 +20,8 @@ export const CALLOUT_ICON_OPTIONS = [ "CheckCircle", ]; -export const CALLOUT_ON_CLOSE_OPTIONS = [action("onClick"), undefined]; +export const CALLOUT_SDS_STYLE_OPTIONS = [ + "persistent", + "expandable", + "dismissible", +]; diff --git a/packages/components/src/core/Callout/__storybook__/index.stories.tsx b/packages/components/src/core/Callout/__storybook__/index.stories.tsx index 555f5f9fd..30dd02184 100644 --- a/packages/components/src/core/Callout/__storybook__/index.stories.tsx +++ b/packages/components/src/core/Callout/__storybook__/index.stories.tsx @@ -1,6 +1,6 @@ import { Meta } from "@storybook/react"; import { BADGE } from "@geometricpanda/storybook-addon-badges"; -import { CALLOUT_ICON_OPTIONS, CALLOUT_ON_CLOSE_OPTIONS } from "./constants"; +import { CALLOUT_ICON_OPTIONS, CALLOUT_SDS_STYLE_OPTIONS } from "./constants"; import { Callout } from "./stories/default"; export default { @@ -17,17 +17,6 @@ export default { defaultValue: { summary: "-" }, description: "The body text of the callout.", }, - expandable: { - control: { type: "boolean" }, - defaultValue: { summary: "false" }, - description: "If true, the callout will be expandable.", - }, - extraContent: { - control: { type: "boolean" }, - defaultValue: { summary: "-" }, - description: - "The extra content in the Callout is passed as children to the component, allowing you to add custom content to it. For Storybook purposes, a predefined example of extra content has been added to the Callout component. You can toggle this boolean to test it out. Note that this is not an actual prop on the Callout component.", - }, hideBody: { control: { type: "boolean" }, defaultValue: { summary: "false" }, @@ -60,16 +49,16 @@ export default { description: "The intent of the callout.", options: ["info", "negative", "positive", "notice"], }, - onClose: { + sdsStyle: { control: { - labels: ["() => {}", "undefined"], + labels: ["persistent", "expandable", "dismissible"], type: "select", }, - defaultValue: { summary: "-" }, + defaultValue: { summary: "persistent" }, description: - "If set to a function, the callout will have a close button.", - mapping: CALLOUT_ON_CLOSE_OPTIONS, - options: Object.keys(CALLOUT_ON_CLOSE_OPTIONS), + "The style of the Callout determines its behavior: Persistent Callouts are always visible, Expandable Callouts can be toggled to show or hide extra content, and Dismissible Callouts can be closed by the user.", + mapping: CALLOUT_SDS_STYLE_OPTIONS, + options: Object.keys(CALLOUT_SDS_STYLE_OPTIONS), }, title: { control: { type: "text" }, @@ -92,9 +81,7 @@ export default { export const Default = { args: { autoDismiss: false, - body: "Callout text—replace the content here and the height of the component will adjust automatically.", - expandable: false, - onClose: false, - title: "Title", + body: "Callout text — replace the content here and the height of the component will adjust automatically.", + title: "The callout title goes here", }, }; diff --git a/packages/components/src/core/Callout/__storybook__/stories/default.tsx b/packages/components/src/core/Callout/__storybook__/stories/default.tsx index a1f3b96b9..a602717db 100644 --- a/packages/components/src/core/Callout/__storybook__/stories/default.tsx +++ b/packages/components/src/core/Callout/__storybook__/stories/default.tsx @@ -1,4 +1,4 @@ -import { FormControlLabel } from "@mui/material"; +import { Box, FormControlLabel } from "@mui/material"; import { Args } from "@storybook/react"; import { useState } from "react"; import RawCallout from "src/core/Callout"; @@ -7,7 +7,7 @@ import { SHORT_LOREM_IPSUM } from "src/common/storybook/loremIpsum"; import TooltipTableContent from "src/core/TooltipTable"; export const Callout = (props: Args): JSX.Element => { - const { intent, onClose, autoDismiss, extraContent, ...rest } = props; + const { intent, autoDismiss, ...rest } = props; const [dismissed, setDismissed] = useState(false); @@ -15,10 +15,10 @@ export const Callout = (props: Args): JSX.Element => { setDismissed((prev) => !prev); }; - const finalOnclose = !onClose ? undefined : () => setDismissed(true); + const finalOnclose = (_: React.SyntheticEvent) => setDismissed(true); return ( - <> + {!autoDismiss && ( } @@ -38,7 +38,7 @@ export const Callout = (props: Args): JSX.Element => { onClose={finalOnclose} {...rest} > - {extraContent && ( + {
{SHORT_LOREM_IPSUM}
@@ -55,8 +55,8 @@ export const Callout = (props: Args): JSX.Element => { />
- )} + } - +
); }; diff --git a/packages/components/src/core/Callout/index.tsx b/packages/components/src/core/Callout/index.tsx index 3ccaf6af5..71688eb55 100644 --- a/packages/components/src/core/Callout/index.tsx +++ b/packages/components/src/core/Callout/index.tsx @@ -12,6 +12,7 @@ const SDS_STAGE_OPEN = "open"; const SDS_STAGE_CLOSED = "closed"; export type CalloutIntentType = "info" | "negative" | "notice" | "positive"; +export type CalloutSdsStyleType = "persistent" | "expandable" | "dismissible"; export interface CalloutProps { autoDismiss?: boolean | number; dismissed?: boolean; @@ -24,7 +25,7 @@ export interface CalloutProps { body?: string; hideBody?: boolean; extraContent?: React.ReactNode; - expandable?: boolean; + sdsStyle?: CalloutSdsStyleType; } export type ExposedCalloutProps = Omit & CalloutProps; @@ -32,22 +33,22 @@ export type ExposedCalloutProps = Omit & CalloutProps; /** * @see https://mui.com/material-ui/react-alert/ */ -const Callout = ({ - autoDismiss, - dismissed, - expandable, - onClose, - icon, - sdsIconProps, - intent, - sdsStage, - title, - body, - hideTitle = false, - hideBody = false, - children, - ...rest -}: ExposedCalloutProps): JSX.Element => { +const Callout = (props: ExposedCalloutProps): JSX.Element => { + const { + autoDismiss, + dismissed, + icon, + sdsIconProps, + intent, + sdsStage, + title, + body, + hideTitle = false, + hideBody = false, + sdsStyle = "persistent", + children, + ...rest + } = props; const [hide, setHide] = useState(dismissed); const [stage, setStage] = useState(sdsStage || SDS_STAGE_CLOSED); @@ -64,7 +65,7 @@ const Callout = ({ const handleClose = (event: React.SyntheticEvent) => { setHide(true); - if (onClose) onClose(event); + if (props?.onClose) props?.onClose(event); }; const getIcon = () => { @@ -93,7 +94,7 @@ const Callout = ({ }; const getAction = (collapsed: boolean) => { - if (expandable) { + if (sdsStyle === "expandable") { return (