Skip to content

Commit

Permalink
feat: add icon button (#64)
Browse files Browse the repository at this point in the history
This pull request adds the icon button component to the designs system.
  • Loading branch information
malinovic authored Dec 4, 2023

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
1 parent 1002f2a commit 805cdef
Showing 6 changed files with 108 additions and 11 deletions.
48 changes: 48 additions & 0 deletions src/components/icon-button/icon-button.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import type { Meta, StoryObj } from '@storybook/react';
import { IconButton } from './icon-button';
import { CalendarIcon, LocationIcon, ProfileIcon, TimeIcon } from '../icons';

const meta: Meta<typeof IconButton> = {
title: 'Components/Icon Button',
component: IconButton,
tags: ['autodocs'],
};

type Story = StoryObj<typeof meta>;

export default meta;

export const Default: Story = {
args: {
href: '#',
children: 'Username',
Icon: ProfileIcon,
},
};

export const BaseColor: Story = {
args: {
href: '#',
children: 'Timestamp',
Icon: TimeIcon,
variant: 'base',
},
};

export const Location: Story = {
args: {
href: '#',
children: 'Location',
Icon: LocationIcon,
variant: 'base',
},
};

export const Calendar: Story = {
args: {
href: '#',
children: 'Joined',
Icon: CalendarIcon,
variant: 'base',
},
};
45 changes: 45 additions & 0 deletions src/components/icon-button/icon-button.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import React, { ComponentType, FC, LinkHTMLAttributes } from 'react';
import classnames from 'classnames';
import { IconProps } from '../icons/iconUtils';

export type IconButton<T> = {
href: string;
children: string;
variant?: 'primary' | 'base';
linkComponent?: FC<T>;
Icon: ComponentType<IconProps>;
} & Omit<T, 'className' | 'target' | 'rel'>;

export const IconButton = <
T extends {
className?: string;
rel?: string;
target?: string;
} = LinkHTMLAttributes<HTMLElement>,
>({
children,
linkComponent,
variant = 'primary',
Icon,
...props
}: IconButton<T>) => {
const LinkComponent: FC<T> | 'a' = linkComponent || 'a';
const colorClasses = classnames({
'text-primary-600 hover:text-primary-900': variant === 'primary',
'text-base-600 hover:text-base-900 hover:fill-error': variant === 'base',
});

return (
<LinkComponent
/* explicitly set props to any instead of writing the whole statement for the sake of simplicity:
* IntrinsicAttributes & T & ClassAttributes<HTMLAnchorElement> & AnchorHTMLAttributes<HTMLAnchorElement>
* It should have no effect on typings for the user and therefor we consider it as best to keep the code simple.
*/
/* eslint-disable-next-line */
{...(props as any)}
className={classnames(' flex items-center gap-xxs transition-colors duration-300 mb-font-label-s', colorClasses)}>
{<Icon size={'s'} color={'inherit'} />}
<span>{children}</span>
</LinkComponent>
);
};
1 change: 1 addition & 0 deletions src/components/icon-button/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { IconButton } from './icon-button';
6 changes: 4 additions & 2 deletions src/components/icons/iconUtils.ts
Original file line number Diff line number Diff line change
@@ -11,7 +11,7 @@ export const getSizeClass = (size: 's' | 'm' | 'l') => {
}
};

export const getColorClass = (color: 'base' | 'white' | 'primary' | 'secondary' | 'error') => {
export const getColorClass = (color: 'base' | 'white' | 'primary' | 'secondary' | 'error' | 'inherit') => {
switch (color) {
case 'base':
return 'fill-base-600';
@@ -23,14 +23,16 @@ export const getColorClass = (color: 'base' | 'white' | 'primary' | 'secondary'
return 'fill-white';
case 'error':
return 'fill-error';
case 'inherit':
return 'fill-current';
default:
return 'fill-slate-600';
}
};

export interface IconProps {
size: 's' | 'm' | 'l';
color: 'base' | 'white' | 'primary' | 'secondary' | 'error';
color: 'base' | 'white' | 'primary' | 'secondary' | 'error' | 'inherit';
}

export interface FillableIconProps extends IconProps {
1 change: 1 addition & 0 deletions src/components/index.ts
Original file line number Diff line number Diff line change
@@ -23,3 +23,4 @@ export { Label } from './label';
export { Link } from './link';
export { Textarea } from './textarea';
export { Logo } from './logo';
export { IconButton } from './icon-button';
18 changes: 9 additions & 9 deletions tailwind.config.js
Original file line number Diff line number Diff line change
@@ -6,15 +6,6 @@ import plugin from 'tailwindcss/plugin';
module.exports = {
content: ['./src/**/*.{js,ts,jsx,tsx,mdx}'],
theme: {
colors: {
'transparent': 'transparent',
white: '#ffffff',
black: '#000000',
error: '#FF0000',
primary: colors.violet,
secondary: colors.pink,
base: colors.slate,
},
fontFamily: {
default: ['Poppins', 'Arial', 'sans-serif'],
},
@@ -54,6 +45,15 @@ module.exports = {
full: '9999px',
},
extend: {
colors: {
transparent: 'transparent',
white: '#ffffff',
black: '#000000',
error: '#FF0000',
primary: colors.violet,
secondary: colors.pink,
base: colors.slate,
},
spacing: {
xxs: '4px',
xs: '8px',

0 comments on commit 805cdef

Please sign in to comment.