diff --git a/frontend/src/components/v2/Button/Button.tsx b/frontend/src/components/v2/Button/Button.tsx index f00d1d0a3..c0894f261 100644 --- a/frontend/src/components/v2/Button/Button.tsx +++ b/frontend/src/components/v2/Button/Button.tsx @@ -24,16 +24,16 @@ const buttonVariants = cva( variants: { colorSchema: { primary: ['bg-primary', 'text-black', 'border-primary hover:bg-opacity-80'], - secondary: ['bg-mineshaft-200', 'text-white', 'border-mineshaft-200'], + secondary: ['bg-mineshaft', 'text-gray-300', 'border-mineshaft hover:bg-opacity-80'], danger: ['bg-red', 'text-white', 'border-red'] }, variant: { solid: '', - outline: ['bg-transparent', 'border', 'border-solid'], + outline: ['bg-transparent', 'border-2', 'border-solid'], plain: '' }, isDisabled: { - true: 'bg-opacity-70', + true: 'bg-opacity-70 cursor-not-allowed', false: '' }, isFullWidth: { @@ -60,7 +60,7 @@ const buttonVariants = cva( { colorSchema: 'secondary', variant: 'outline', - className: 'text-mineshaft-200 hover:bg-mineshaft-400 hover:text-white' + className: 'hover:bg-mineshaft' }, { colorSchema: 'danger', @@ -75,7 +75,7 @@ const buttonVariants = cva( { colorSchema: 'secondary', variant: 'plain', - className: 'text-mineshaft-400' + className: 'text-mineshaft' }, { colorSchema: 'danger', @@ -139,7 +139,7 @@ export const Button = forwardRef( src="/images/loading/loadingblack.gif" width={36} alt="loading animation" - className="rounded-xl absolute" + className="absolute rounded-xl" /> )} = { + title: 'Components/IconButton', + component: IconButton, + tags: ['v2'], + argTypes: { + isRounded: { + defaultValue: true, + type: 'boolean' + }, + ariaLabel: { + defaultValue: 'Some buttons...' + } + } +}; + +export default meta; +type Story = StoryObj; + +// More on writing stories with args: https://storybook.js.org/docs/7.0/react/writing-stories/args +export const Primary: Story = { + args: { + children: + } +}; + +export const Secondary: Story = { + args: { + children: , + colorSchema: 'secondary', + variant: 'outline' + } +}; + +export const Danger: Story = { + args: { + children: , + colorSchema: 'danger', + variant: 'solid' + } +}; + +export const Plain: Story = { + args: { + children: , + variant: 'plain' + } +}; + +export const Disabled: Story = { + args: { + children: , + disabled: true + } +}; diff --git a/frontend/src/components/v2/IconButton/IconButton.tsx b/frontend/src/components/v2/IconButton/IconButton.tsx new file mode 100644 index 000000000..9790d9d7b --- /dev/null +++ b/frontend/src/components/v2/IconButton/IconButton.tsx @@ -0,0 +1,131 @@ +import { ButtonHTMLAttributes, forwardRef, ReactNode } from 'react'; +import { cva, VariantProps } from 'cva'; +import { twMerge } from 'tailwind-merge'; + +type Props = { + children: ReactNode; + // This is kept as required because by accessibility convention and eslint + // when button doesn't have text an aria-label needs to be passed + ariaLabel: string; + isDisabled?: boolean; +}; + +const iconButtonVariants = cva( + [ + 'button', + 'transition-all', + 'font-medium', + 'cursor-pointer', + 'inline-flex items-center justify-center', + 'relative' + ], + { + variants: { + colorSchema: { + primary: ['bg-primary', 'text-black', 'border-primary hover:bg-opacity-80'], + secondary: ['bg-mineshaft', 'text-gray-300', 'border-mineshaft hover:bg-opacity-80'], + danger: ['bg-red', 'text-white', 'border-red'] + }, + variant: { + solid: '', + outline: ['bg-transparent', 'border-2', 'border-solid'], + plain: '' + }, + isDisabled: { + true: 'bg-opacity-70 cursor-not-allowed', + false: '' + }, + isRounded: { + true: 'rounded-md', + false: '' + }, + size: { + xs: ['text-xs', 'py-1', 'px-2'], + sm: ['text-sm', 'py-2', 'px-3'], + md: ['text-md', 'py-3', 'px-4'], + lg: ['text-lg', 'py-3', 'px-6'] + } + }, + compoundVariants: [ + { + colorSchema: 'primary', + variant: 'outline', + className: 'text-primary hover:bg-primary hover:text-black' + }, + { + colorSchema: 'secondary', + variant: 'outline', + className: 'hover:bg-mineshaft' + }, + { + colorSchema: 'danger', + variant: 'outline', + className: 'text-red hover:bg-red hover:text-black' + }, + { + colorSchema: 'primary', + variant: 'plain', + className: 'text-primary' + }, + { + colorSchema: 'secondary', + variant: 'plain', + className: 'text-mineshaft' + }, + { + colorSchema: 'danger', + variant: 'plain', + className: 'text-red' + }, + { + colorSchema: ['danger', 'primary', 'secondary'], + variant: ['plain'], + className: 'bg-transparent py-1 px-1' + } + ] + } +); + +export type IconButtonProps = Omit, 'aria-label'> & + VariantProps & + Props; + +export const IconButton = forwardRef( + ( + { + children, + ariaLabel, + isDisabled = false, + className, + size = 'md', + variant = 'solid', + isRounded = true, + colorSchema = 'primary', + ...props + }, + ref + ): JSX.Element => ( + + ) +); + +IconButton.displayName = 'IconButton'; diff --git a/frontend/src/components/v2/IconButton/index.tsx b/frontend/src/components/v2/IconButton/index.tsx new file mode 100644 index 000000000..e920c3d6a --- /dev/null +++ b/frontend/src/components/v2/IconButton/index.tsx @@ -0,0 +1,2 @@ +export type { IconButtonProps } from './IconButton'; +export { IconButton } from './IconButton'; diff --git a/frontend/src/components/v2/Select/Select.tsx b/frontend/src/components/v2/Select/Select.tsx index 7b45a1848..3fee8b7c7 100644 --- a/frontend/src/components/v2/Select/Select.tsx +++ b/frontend/src/components/v2/Select/Select.tsx @@ -13,7 +13,7 @@ type Props = { isLoading?: boolean; }; -type SelectProps = SelectPrimitive.SelectProps & Props; +export type SelectProps = SelectPrimitive.SelectProps & Props; export const Select = forwardRef( ({ children, placeholder, className, isLoading, ...props }, ref): JSX.Element => { @@ -64,7 +64,7 @@ export const Select = forwardRef( Select.displayName = 'Select'; -type SelectItemProps = Omit & { +export type SelectItemProps = Omit & { isDisabled?: boolean; isSelected?: boolean; }; diff --git a/frontend/src/components/v2/Select/index.tsx b/frontend/src/components/v2/Select/index.tsx index d42fd8d59..269099af6 100644 --- a/frontend/src/components/v2/Select/index.tsx +++ b/frontend/src/components/v2/Select/index.tsx @@ -1 +1,2 @@ -export {Select} from './Select' \ No newline at end of file +export type { SelectItemProps, SelectProps } from './Select'; +export { Select, SelectItem } from './Select'; diff --git a/frontend/src/components/v2/index.tsx b/frontend/src/components/v2/index.tsx index 71d91fc1e..0d6c14ea2 100644 --- a/frontend/src/components/v2/index.tsx +++ b/frontend/src/components/v2/index.tsx @@ -1,3 +1,5 @@ export * from './Button'; export * from './FormControl'; +export * from './IconButton'; export * from './Input'; +export * from './Select';