diff --git a/src/components/Icon/Icon.props.ts b/src/components/Icon/Icon.props.ts new file mode 100644 index 00000000..a7d08b9a --- /dev/null +++ b/src/components/Icon/Icon.props.ts @@ -0,0 +1,9 @@ +import { IconName } from '@virtuslab/tetrisly-icons'; + +import type { BaseProps } from '@/types/BaseProps'; + +export type IconProps = { + name: IconName; + color?: BaseProps['color']; + custom?: BaseProps; +}; diff --git a/src/components/Icon/Icon.stories.tsx b/src/components/Icon/Icon.stories.tsx new file mode 100644 index 00000000..d3e673b4 --- /dev/null +++ b/src/components/Icon/Icon.stories.tsx @@ -0,0 +1,41 @@ +import { Meta, StoryObj } from '@storybook/react'; +import { icons } from '@virtuslab/tetrisly-icons'; + +import { Icon } from './Icon'; + +import { IconDocs } from '@/docs-components/IconDocs'; +import { TetDocs } from '@/docs-components/TetDocs'; + +const meta = { + title: 'Foundations / Icon', + component: Icon, + tags: ['autodocs'], + args: { + name: '20-tetrisly', + }, + argTypes: { + name: { + options: Object.keys(icons), + defaultValue: undefined, + control: { type: 'select' }, + }, + }, + parameters: { + docs: { + description: { + component: + 'A clean, consistent, and pixel-perfect icon library crafted especially for modern UI design.', + }, + page: () => ( + + + + ), + }, + }, +} satisfies Meta; + +export default meta; +type Story = StoryObj; + +export const Default: Story = {}; diff --git a/src/components/Icon/Icon.test.tsx b/src/components/Icon/Icon.test.tsx new file mode 100644 index 00000000..08597cc0 --- /dev/null +++ b/src/components/Icon/Icon.test.tsx @@ -0,0 +1,22 @@ +import { Icon } from './Icon'; +import { render } from '../../tests/render'; + +const getIcon = (jsx: JSX.Element) => { + const { getByTestId } = render(jsx); + + return getByTestId('icon'); +}; + +describe('Loader', () => { + it('should render the component', () => { + const icon = getIcon(); + + expect(icon).toBeInTheDocument(); + }); + + it('should render star with $color-raspberry-0 color', () => { + const icon = getIcon(); + + expect(icon).toHaveStyle('color: rgb(192, 48, 96);'); + }); +}); diff --git a/src/components/Icon/Icon.tsx b/src/components/Icon/Icon.tsx new file mode 100644 index 00000000..27fe622e --- /dev/null +++ b/src/components/Icon/Icon.tsx @@ -0,0 +1,15 @@ +import { Icon as SVGIcon } from '@virtuslab/tetrisly-icons'; +import { styled, system } from '@xstyled/styled-components'; +import { FC } from 'react'; + +import type { IconProps } from './Icon.props'; + +import type { MarginProps } from '@/types/MarginProps'; + +const SVG = styled(SVGIcon)` + ${system} +`; + +export const Icon: FC = ({ custom, ...rest }) => ( + +); diff --git a/src/components/Icon/index.ts b/src/components/Icon/index.ts new file mode 100644 index 00000000..20736fa0 --- /dev/null +++ b/src/components/Icon/index.ts @@ -0,0 +1,2 @@ +export { Icon } from './Icon'; +export type { IconProps } from './Icon.props'; diff --git a/src/docs-components/IconDocs.tsx b/src/docs-components/IconDocs.tsx new file mode 100644 index 00000000..80015e49 --- /dev/null +++ b/src/docs-components/IconDocs.tsx @@ -0,0 +1,78 @@ +import { icons, IconName } from '@virtuslab/tetrisly-icons'; +import { FC } from 'react'; + +import { SectionHeader } from './common/SectionHeader'; + +import { Icon } from '@/components/Icon'; +import { tet } from '@/tetrisly'; +import { MarginProps } from '@/types'; + +const iconsNames = Object.keys(icons) as IconName[]; + +const icons20 = iconsNames.filter((iconName) => iconName.startsWith('20-')); +const icons16 = iconsNames.filter((iconName) => iconName.startsWith('16-')); + +const IconsBoard: FC<{ heading: string; items: IconName[] } & MarginProps> = ({ + heading, + items, + ...rest +}) => ( + + + {heading} + + + {items.map((iconName) => ( + + + + + + {iconName} + + + ))} + + +); + +export const IconDocs = () => ( + + + + Icons lists + + + + + +); diff --git a/src/index.ts b/src/index.ts index 5de5e0f1..f8d3dbfb 100644 --- a/src/index.ts +++ b/src/index.ts @@ -7,6 +7,7 @@ export * from './components/CheckboxGroup'; export * from './components/Counter'; export * from './components/Divider'; export * from './components/HelperText'; +export * from './components/Icon'; export * from './components/IconButton'; export * from './components/InlineBanner'; export * from './components/InlineMessage'; @@ -20,6 +21,7 @@ export * from './components/SearchInput'; export * from './components/Select'; export * from './components/SocialButton'; export * from './components/StatusDot'; +export * from './components/Tag'; export * from './components/TextInput'; export * from './components/Toast'; export * from './tetrisly';