diff --git a/apps/storybook/stories/alert.stories.tsx b/apps/storybook/stories/alert.stories.tsx new file mode 100644 index 00000000..d59de9bf --- /dev/null +++ b/apps/storybook/stories/alert.stories.tsx @@ -0,0 +1,53 @@ +import { ComponentMeta } from '@storybook/react'; +import { Alert, AlertVariant } from '@tih/ui'; +import React from 'react'; + +const alertVariants: ReadonlyArray = [ + 'info', + 'danger', + 'success', + 'warning', +]; + +export default { + title: 'Alert', + component: Alert, + argTypes: { + title: { + control: 'text', + }, + variant: { + options: alertVariants, + control: { type: 'select' }, + }, + }, +} as ComponentMeta; + +export const Basic = { + args: { + title: 'Please pay attention', + variant: 'info', + children: 'This is something you should pay your full attention to.', + }, +}; + +export function Variants() { + return ( +
+ + Your order has been placed! Please check your email for the + confirmation. + + + A new software update is available. See what's new in version 2.0.4. + + + Doing that are not advisable, you are recommended to stay away from such + practices. + + + Please try again later, or close it and forget about it. + +
+ ); +} diff --git a/packages/tailwind-config/tailwind.config.js b/packages/tailwind-config/tailwind.config.js index 8fb08202..8fa4940f 100644 --- a/packages/tailwind-config/tailwind.config.js +++ b/packages/tailwind-config/tailwind.config.js @@ -11,6 +11,10 @@ module.exports = { }, colors: { primary: colors.purple, + danger: colors.rose, + info: colors.sky, + success: colors.emerald, + warning: colors.amber, }, }, }, diff --git a/packages/ui/src/Alert/Alert.tsx b/packages/ui/src/Alert/Alert.tsx new file mode 100644 index 00000000..55359614 --- /dev/null +++ b/packages/ui/src/Alert/Alert.tsx @@ -0,0 +1,84 @@ +import clsx from 'clsx'; +import type { ReactNode } from 'react'; +import { + CheckCircleIcon, + ExclamationTriangleIcon, + InformationCircleIcon, + XCircleIcon, +} from '@heroicons/react/20/solid'; + +export type AlertVariant = 'danger' | 'info' | 'success' | 'warning'; + +type Props = Readonly<{ + children: ReactNode; + title?: string; + variant: AlertVariant; +}>; + +const classes: Record< + AlertVariant, + Readonly<{ + backgroundClass: string; + bodyClass: string; + icon: (props: React.ComponentProps<'svg'>) => JSX.Element; + iconClass: string; + titleClass: string; + }> +> = { + danger: { + backgroundClass: 'bg-danger-50', + bodyClass: 'text-danger-700', + icon: XCircleIcon, + iconClass: 'text-danger-400', + titleClass: 'text-danger-800', + }, + info: { + backgroundClass: 'bg-info-50', + bodyClass: 'text-info-700', + icon: InformationCircleIcon, + iconClass: 'text-info-400', + titleClass: 'text-info-800', + }, + success: { + backgroundClass: 'bg-success-50', + bodyClass: 'text-success-700', + icon: CheckCircleIcon, + iconClass: 'text-success-400', + titleClass: 'text-success-800', + }, + warning: { + backgroundClass: 'bg-warning-50', + bodyClass: 'text-warning-700', + icon: ExclamationTriangleIcon, + iconClass: 'text-warning-400', + titleClass: 'text-warning-800', + }, +}; + +export default function Alert({ children, title, variant }: Props) { + const { + backgroundClass, + iconClass, + titleClass, + bodyClass, + icon: Icon, + } = classes[variant]; + + return ( +
+
+
+
+
+ {title && ( +

{title}

+ )} +
+

{children}

+
+
+
+
+ ); +} diff --git a/packages/ui/src/Button/Button.tsx b/packages/ui/src/Button/Button.tsx index d95906a7..d957721b 100644 --- a/packages/ui/src/Button/Button.tsx +++ b/packages/ui/src/Button/Button.tsx @@ -2,7 +2,7 @@ import clsx from 'clsx'; import Link from 'next/link'; import type { UrlObject } from 'url'; -import Spinner from '../Spinner'; +import { Spinner } from '../'; export type ButtonAddOnPosition = 'end' | 'start'; export type ButtonDisplay = 'block' | 'inline'; diff --git a/packages/ui/src/Button/index.ts b/packages/ui/src/Button/index.ts deleted file mode 100644 index 301ea717..00000000 --- a/packages/ui/src/Button/index.ts +++ /dev/null @@ -1,4 +0,0 @@ -import Button from './Button'; - -export * from './Button'; -export default Button; diff --git a/packages/ui/src/Spinner/index.ts b/packages/ui/src/Spinner/index.ts deleted file mode 100644 index 0e0be394..00000000 --- a/packages/ui/src/Spinner/index.ts +++ /dev/null @@ -1,4 +0,0 @@ -import Spinner from './Spinner'; - -export * from './Spinner'; -export default Spinner; diff --git a/packages/ui/src/index.tsx b/packages/ui/src/index.tsx index 215b15fe..e165928b 100644 --- a/packages/ui/src/index.tsx +++ b/packages/ui/src/index.tsx @@ -1,4 +1,6 @@ -export { default as Button } from './Button'; -export * from './Button'; -export { default as Spinner } from './Spinner'; -export * from './Spinner'; +export * from './Alert/Alert'; +export { default as Alert } from './Alert/Alert'; +export * from './Button/Button'; +export { default as Button } from './Button/Button'; +export * from './Spinner/Spinner'; +export { default as Spinner } from './Spinner/Spinner';