diff --git a/src/components/FileIcon/FileIcon.props.ts b/src/components/FileIcon/FileIcon.props.ts new file mode 100644 index 00000000..23bdeef1 --- /dev/null +++ b/src/components/FileIcon/FileIcon.props.ts @@ -0,0 +1,20 @@ +import { BaseProps } from '@/types'; + +export type IconType = + | 'Sketch' + | 'Photoshop' + | 'Excel' + | 'Word' + | 'Pdf' + | 'Spreadsheet' + | 'Document' + | 'File' + | 'Archive' + | 'Figma'; +export type Size = 'Large' | 'Medium'; + +export type FileIconProps = { + iconType: IconType; + size?: Size; + custom?: BaseProps; +}; diff --git a/src/components/FileIcon/FileIcon.stories.tsx b/src/components/FileIcon/FileIcon.stories.tsx new file mode 100644 index 00000000..3f9bdd51 --- /dev/null +++ b/src/components/FileIcon/FileIcon.stories.tsx @@ -0,0 +1,31 @@ +import { Meta, StoryObj } from '@storybook/react'; + +import { FileIcon } from './FileIcon'; + +import { FileIconDocs } from '@/docs-components/FileIconDocs'; +import { TetDocs } from '@/docs-components/TetDocs'; + +const meta = { + title: 'File Icon', + component: FileIcon, + tags: ['autodocs'], + parameters: { + docs: { + page: () => ( + + + + ), + }, + }, +} satisfies Meta; + +export default meta; +type Story = StoryObj; + +export const Default: Story = { + args: { + iconType: 'Archive', + size: 'Large', + }, +}; diff --git a/src/components/FileIcon/FileIcon.styles.ts b/src/components/FileIcon/FileIcon.styles.ts new file mode 100644 index 00000000..abaebf20 --- /dev/null +++ b/src/components/FileIcon/FileIcon.styles.ts @@ -0,0 +1,9 @@ +import { BaseProps } from '@/types'; + +export type FileIconConfig = BaseProps; + +export const defaultConfig = {} satisfies FileIconConfig; + +export const fileIconStyles = { + defaultConfig, +}; diff --git a/src/components/FileIcon/FileIcon.test.tsx b/src/components/FileIcon/FileIcon.test.tsx new file mode 100644 index 00000000..cdb639da --- /dev/null +++ b/src/components/FileIcon/FileIcon.test.tsx @@ -0,0 +1,24 @@ +import { FileIcon } from './FileIcon'; + +import { customPropTester } from '@/tests/customPropTester'; +import { render } from '@/tests/render'; + +const getFileIcon = (jsx: JSX.Element) => { + const { getByTestId } = render(jsx); + + return getByTestId('file-icon'); +}; + +describe('FileIcon', () => { + customPropTester(, { + containerId: 'file-icon', + props: { + size: ['Large', 'Medium'], + }, + }); + + it('should render the file icon', () => { + const fileIcon = getFileIcon(); + expect(fileIcon).toBeInTheDocument(); + }); +}); diff --git a/src/components/FileIcon/FileIcon.tsx b/src/components/FileIcon/FileIcon.tsx new file mode 100644 index 00000000..cbae44e5 --- /dev/null +++ b/src/components/FileIcon/FileIcon.tsx @@ -0,0 +1,23 @@ +import { useMemo, type FC } from 'react'; + +import { FileIconProps } from './FileIcon.props'; +import { stylesBuilder } from './stylesBuilder'; +import { renderProperIcon } from './utils'; + +import { tet } from '@/tetrisly'; +import type { MarginProps } from '@/types'; + +export const FileIcon: FC = ({ + iconType, + size = 'Large', + custom, + ...restProps +}) => { + const styles = useMemo(() => stylesBuilder(custom), [custom]); + + return ( + + {renderProperIcon(iconType, size)} + + ); +}; diff --git a/src/components/FileIcon/index.tsx b/src/components/FileIcon/index.tsx new file mode 100644 index 00000000..928496b5 --- /dev/null +++ b/src/components/FileIcon/index.tsx @@ -0,0 +1,2 @@ +export { FileIcon } from './FileIcon'; +export type { FileIconProps } from './FileIcon.props'; diff --git a/src/components/FileIcon/stylesBuilder.ts b/src/components/FileIcon/stylesBuilder.ts new file mode 100644 index 00000000..2fbe146c --- /dev/null +++ b/src/components/FileIcon/stylesBuilder.ts @@ -0,0 +1,18 @@ +import { defaultConfig, FileIconConfig } from './FileIcon.styles'; + +import { mergeConfigWithCustom } from '@/services'; +import { BaseProps } from '@/types'; + +type StylesBuilderParams = { + container: BaseProps; +}; + +export const stylesBuilder = (custom?: FileIconConfig): StylesBuilderParams => { + const { ...container } = mergeConfigWithCustom({ defaultConfig, custom }); + + return { + container: { + ...container, + }, + }; +}; diff --git a/src/components/FileIcon/utils.tsx b/src/components/FileIcon/utils.tsx new file mode 100644 index 00000000..ea3caa5c --- /dev/null +++ b/src/components/FileIcon/utils.tsx @@ -0,0 +1,669 @@ +import { IconType, Size } from './FileIcon.props'; + +import { tet } from '@/tetrisly'; + +export const renderProperIcon = (iconType: IconType, size: Size) => { + switch (iconType) { + case 'Sketch': + switch (size) { + case 'Large': + return ( + + + + + + ); + + case 'Medium': + return ( + + + + ); + default: + return ( + + + + ); + } + case 'Photoshop': + switch (size) { + case 'Large': + return ( + + + + + + ); + case 'Medium': + return ( + + + + + ); + default: + return ( + + + + + ); + } + case 'Excel': + switch (size) { + case 'Large': + return ( + + + + + ); + + case 'Medium': + return ( + + + + ); + default: + return ( + + + + ); + } + case 'Word': + switch (size) { + case 'Large': + return ( + + + + + ); + + case 'Medium': + return ( + + + + ); + + default: + return ( + + + + ); + } + case 'Pdf': + switch (size) { + case 'Large': + return ( + + + + + + + ); + + case 'Medium': + return ( + + + + + + ); + + default: + return ( + + + + + + ); + } + case 'Spreadsheet': + switch (size) { + case 'Large': + return ( + + + + + + ); + + case 'Medium': + return ( + + + + ); + + default: + return ( + + + + ); + } + case 'Document': + switch (size) { + case 'Large': + return ( + + + + + ); + + case 'Medium': + return ( + + + + ); + default: + return ( + + + + ); + } + case 'File': + switch (size) { + case 'Large': + return ( + + + + ); + case 'Medium': + return ( + + + + ); + default: + return ( + + + + ); + } + case 'Archive': + switch (size) { + case 'Large': + return ( + + + + + + ); + case 'Medium': + return ( + + + + + ); + default: + return ( + + + + + ); + } + case 'Figma': + switch (size) { + case 'Large': + return ( + + + + + + + + + + ); + case 'Medium': + return ( + + + + ); + default: + return ( + + + + ); + } + default: + return ( + + + + ); + } +}; diff --git a/src/docs-components/FileIconDocs.tsx b/src/docs-components/FileIconDocs.tsx new file mode 100644 index 00000000..41f251b9 --- /dev/null +++ b/src/docs-components/FileIconDocs.tsx @@ -0,0 +1,54 @@ +import { FileIcon } from '@/components/FileIcon/FileIcon'; +import { tet } from '@/tetrisly'; + +const iconTypes = [ + 'Sketch', + 'Photoshop', + 'Excel', + 'Word', + 'Pdf', + 'Spreadsheet', + 'Document', + 'File', + 'Archive', + 'Figma', +] as const; + +export const FileIconDocs = () => ( + + + + {iconTypes.map((iconType) => ( + + + {iconType} + + + + + + + ))} + + + +); diff --git a/src/index.ts b/src/index.ts index f7258878..3838ef03 100644 --- a/src/index.ts +++ b/src/index.ts @@ -9,6 +9,7 @@ export * from './components/CheckboxGroup'; export * from './components/CornerDialog'; export * from './components/Counter'; export * from './components/Divider'; +export * from './components/FileIcon'; export * from './components/FileItem'; export * from './components/HelperText'; export * from './components/Icon';