From 56fb3185ff7ca0d2aa8d4323bc15786f69612c68 Mon Sep 17 00:00:00 2001 From: zuramai Date: Sat, 11 Nov 2023 13:39:45 +0700 Subject: [PATCH] feat(components): alert variants --- packages/alert/src/index.tsx | 39 ++++-- packages/alert/stories/Types.stories.tsx | 130 ++++++++++++++++++ ...Alert.stories.tsx => Variants.stories.tsx} | 2 +- 3 files changed, 159 insertions(+), 12 deletions(-) create mode 100644 packages/alert/stories/Types.stories.tsx rename packages/alert/stories/{Alert.stories.tsx => Variants.stories.tsx} (98%) diff --git a/packages/alert/src/index.tsx b/packages/alert/src/index.tsx index 720b48c..45326ef 100644 --- a/packages/alert/src/index.tsx +++ b/packages/alert/src/index.tsx @@ -1,10 +1,11 @@ -import React, { useState } from 'react'; +import React, { ReactNode, useState } from 'react'; import { GoInfo, GoXCircle, GoCheckCircle } from 'react-icons/go'; interface AlertProps { type: 'warning' | 'danger' | 'success' | 'info'; - title: string; - description?: string | React.ReactNode; + icon?: boolean | ReactNode + title?: string; + description?: string | ReactNode; actions?: React.ReactNode; link?: { url: string; @@ -47,6 +48,7 @@ const classes = { const Alert: React.FC = ({ type, title, + icon, description, actions, link, @@ -55,6 +57,11 @@ const Alert: React.FC = ({ const [isDismissed, setIsDismissed] = useState(false); const getIcon = () => { + // Use the provided ReactNode icon in props if exists + if (React.isValidElement(icon)) { + return icon + } + switch (type) { case 'warning': return ( @@ -91,16 +98,26 @@ const Alert: React.FC = ({ className={`rounded-md p-4 ${classes[type].bg}`} >
-
{getIcon()}
-
-

- {title} -

+ {icon && ( +
{getIcon()}
+ )} +
+ + {title && ( +

+ {title} +

+ )} + + {/* Create gap between title and desc */} + {title && description &&
} + + {description && (
{typeof description === 'string' ? (

{description}

diff --git a/packages/alert/stories/Types.stories.tsx b/packages/alert/stories/Types.stories.tsx new file mode 100644 index 0000000..24e2413 --- /dev/null +++ b/packages/alert/stories/Types.stories.tsx @@ -0,0 +1,130 @@ +import React from 'react'; +import { Meta } from '@storybook/react'; +import Alert from '../src/index'; + +export default { + title: 'Components/Alert/Types', + component: Alert, + argTypes: {}, +} as Meta; + +export const WithTitle = () => ( + <> +
+ +
+ + +
  • Your password must be at least 8 characters
  • +
  • + Your password must include at least one pro wrestling finishing move +
  • + + } + /> + + +); + +export const WithoutTitle = () => ( + <> +
    + +
    +
    + +
    +
    + +
    +
    + +
    + +); +export const DismissLink = () => ( + <> +
    + +
    +
    + +
    +
    + +
    +
    + +
    + +); + +export const WithIcon = () => ( + <> +
    + +
    +
    + +
    +
    + +
    +
    + +
    + +); diff --git a/packages/alert/stories/Alert.stories.tsx b/packages/alert/stories/Variants.stories.tsx similarity index 98% rename from packages/alert/stories/Alert.stories.tsx rename to packages/alert/stories/Variants.stories.tsx index 66d7d68..b040cd7 100644 --- a/packages/alert/stories/Alert.stories.tsx +++ b/packages/alert/stories/Variants.stories.tsx @@ -3,7 +3,7 @@ import { Meta } from '@storybook/react'; import Alert from '../src/index'; export default { - title: 'Components/Alert', + title: 'Components/Alert/Variants', component: Alert, argTypes: {}, } as Meta;