ui: add Alert

pull/305/head
Yangshun Tay 2 years ago
parent 842837fb4e
commit db672a2beb

@ -0,0 +1,53 @@
import { ComponentMeta } from '@storybook/react';
import { Alert, AlertVariant } from '@tih/ui';
import React from 'react';
const alertVariants: ReadonlyArray<AlertVariant> = [
'info',
'danger',
'success',
'warning',
];
export default {
title: 'Alert',
component: Alert,
argTypes: {
title: {
control: 'text',
},
variant: {
options: alertVariants,
control: { type: 'select' },
},
},
} as ComponentMeta<typeof Alert>;
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 (
<div className="space-y-4">
<Alert title="Order completed" variant="success">
Your order has been placed! Please check your email for the
confirmation.
</Alert>
<Alert title="Update available" variant="info">
A new software update is available. See what's new in version 2.0.4.
</Alert>
<Alert title="Warning!" variant="warning">
Doing that are not advisable, you are recommended to stay away from such
practices.
</Alert>
<Alert title="Errors submitting" variant="danger">
Please try again later, or close it and forget about it.
</Alert>
</div>
);
}

@ -11,6 +11,10 @@ module.exports = {
},
colors: {
primary: colors.purple,
danger: colors.rose,
info: colors.sky,
success: colors.emerald,
warning: colors.amber,
},
},
},

@ -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 (
<div className={clsx('rounded-md p-4', backgroundClass)}>
<div className="flex">
<div className="flex-shrink-0">
<Icon aria-hidden="true" className={clsx('h-5 w-5', iconClass)} />
</div>
<div className="ml-3 space-y-2">
{title && (
<h3 className={clsx('text-sm font-medium', titleClass)}>{title}</h3>
)}
<div className={clsx('text-sm', bodyClass)}>
<p>{children}</p>
</div>
</div>
</div>
</div>
);
}

@ -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';

@ -1,4 +0,0 @@
import Button from './Button';
export * from './Button';
export default Button;

@ -1,4 +0,0 @@
import Spinner from './Spinner';
export * from './Spinner';
export default Spinner;

@ -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';

Loading…
Cancel
Save