diff --git a/src/components/Tag/Tag.props.ts b/src/components/Tag/Tag.props.ts deleted file mode 100644 index 5100aed1..00000000 --- a/src/components/Tag/Tag.props.ts +++ /dev/null @@ -1,13 +0,0 @@ -import { SyntheticEvent } from 'react'; - -import { TagConfig } from '@/components/Tag/Tag.styles.ts'; -import { TextInputProps } from '@/components/TextInput'; - -export type TagProps = { - label: string; - state?: 'selected' | 'disabled'; - beforeComponent?: TextInputProps.InnerComponents.Avatar; - onClick?: (e: SyntheticEvent) => void; - onCloseClick?: (e: SyntheticEvent) => void; - custom?: TagConfig; -}; diff --git a/src/components/Tag/Tag.stories.tsx b/src/components/Tag/Tag.stories.tsx deleted file mode 100644 index 4e505186..00000000 --- a/src/components/Tag/Tag.stories.tsx +++ /dev/null @@ -1,53 +0,0 @@ -import type { Meta, StoryObj } from '@storybook/react'; - -import { Tag } from './Tag'; - -import { TagDocs } from '@/docs-components/TagDocs.tsx'; -import { TetDocs } from '@/docs-components/TetDocs'; - -const meta = { - title: 'Tag', - component: Tag, - tags: ['autodocs'], - parameters: { - docs: { - description: { - component: - 'A compact, visually distinct element used to label, categorize, or organize content. Tags can help users quickly identify and filter items by attributes such as keywords, topics, or statuses.', - }, - page: () => ( - - - - ), - }, - }, - args: { - label: 'Tag', - onClick: () => null, - }, -} satisfies Meta; - -export default meta; -type Story = StoryObj; - -export const Default: Story = {}; - -export const BeforeAvatarComponent: Story = { - args: { - beforeComponent: { - type: 'Avatar', - props: { - initials: 'A', - emphasis: 'high', - }, - }, - }, -}; - -export const WithRemoveButton: Story = { - args: { - state: undefined, - onCloseClick: () => null, - }, -}; diff --git a/src/components/Tag/Tag.styles.ts b/src/components/Tag/Tag.styles.ts deleted file mode 100644 index de04d9ea..00000000 --- a/src/components/Tag/Tag.styles.ts +++ /dev/null @@ -1,69 +0,0 @@ -import type { BaseProps } from '@/types/BaseProps'; - -export type TagConfig = { - hasOnClick?: BaseProps; - innerElements?: { - label: BaseProps; - closeButton?: BaseProps; - beforeComponent?: { - avatar?: BaseProps; - }; - }; -} & BaseProps; - -const backgroundColor = { - hover: '$color-interaction-neutral-subtle-hover', - active: '$color-interaction-neutral-subtle-active', - focus: '$color-interaction-neutral-subtle-normal', -}; - -export const defaultConfig = { - display: 'inline-flex', - h: '$size-xSmall', - alignItems: 'center', - borderRadius: '$border-radius-medium', - backgroundColor: '$color-interaction-neutral-subtle-normal', - opacity: { - disabled: '$opacity-disabled', - }, - cursor: 'default', - outlineColor: { - focus: '$color-interaction-focus-default', - }, - transitionDuration: 50, - color: '$color-content-primary', - hasOnClick: { - backgroundColor: { - _: '$color-interaction-neutral-subtle-normal', - disabled: '$color-interaction-neutral-subtle-normal', - selected: { - _: '$color-interaction-neutral-subtle-selected', - ...backgroundColor, - }, - ...backgroundColor, - }, - cursor: { - _: 'pointer', - disabled: 'default', - }, - }, - innerElements: { - label: { - mx: '$space-component-padding-small', - text: '$typo-body-medium', - }, - closeButton: { - mr: '$space-component-padding-xSmall', - h: '$size-2xSmall', - w: '$size-2xSmall', - opacity: { - disabled: '$opacity-100', - }, - }, - beforeComponent: { - avatar: { - ml: '$space-component-padding-2xSmall', - }, - }, - }, -} satisfies TagConfig; diff --git a/src/components/Tag/Tag.test.tsx b/src/components/Tag/Tag.test.tsx deleted file mode 100644 index 5736746c..00000000 --- a/src/components/Tag/Tag.test.tsx +++ /dev/null @@ -1,112 +0,0 @@ -import { vi } from 'vitest'; - -import { render, fireEvent } from '../../tests/render'; - -import { Tag } from '@/components/Tag/Tag.tsx'; -import { customPropTester } from '@/tests/customPropTester'; - -const getTag = (jsx: JSX.Element) => { - const { getByTestId, queryByTestId } = render(jsx); - - return { - tag: getByTestId('tag'), - label: getByTestId('tag-label'), - avatar: queryByTestId('tag-avatar'), - closeButton: queryByTestId('tag-iconButton'), - }; -}; - -describe('Tag', () => { - const handleEventMock = vi.fn(); - - customPropTester(, { - containerId: 'tag', - }); - - beforeEach(() => { - handleEventMock.mockReset(); - }); - - it('should render the tag', () => { - const { tag } = getTag(); - expect(tag).toBeInTheDocument(); - }); - - it('should render the correct label', () => { - const { tag } = getTag(); - expect(tag).toHaveTextContent('label'); - }); - - it('should render beforeComponent', () => { - const { avatar } = getTag( - , - ); - expect(avatar).toBeInTheDocument(); - }); - - it('should render closeButton', () => { - const { closeButton } = getTag( - , - ); - expect(closeButton).toBeInTheDocument(); - }); - - it('should emit onClick', () => { - const { tag } = getTag(); - fireEvent.click(tag); - expect(handleEventMock).toHaveBeenCalled(); - }); - - it('should not emit onCloseClick', () => { - const { closeButton } = getTag( - , - ); - fireEvent.click(closeButton as Element); - expect(handleEventMock).not.toHaveBeenCalled(); - }); - - it('should render disabled closeButton', () => { - const { closeButton } = getTag( - , - ); - expect(closeButton).toBeDisabled(); - }); - - it('should render the correct color (disabled)', () => { - const { tag } = getTag(); - expect(tag).toHaveStyle('background-color: rgb(240, 243, 245);'); - }); - - it('should render the right cursor (with onClick)', () => { - const { tag } = getTag(); - expect(tag).toHaveStyle('cursor: pointer'); - }); - - it('should render the right cursor (without onClick)', () => { - const { tag } = getTag(); - expect(tag).toHaveStyle('cursor: default'); - }); - - it('should render the right cursor (with state disabled)', () => { - const { tag } = getTag(); - expect(tag).toHaveStyle('cursor: default'); - }); - - it('should not emit onClick', () => { - const onCloseCLick = vi.fn(); - const onClick = vi.fn(); - - const { closeButton } = getTag( - , - ); - - if (closeButton) { - fireEvent.click(closeButton); - } - expect(onCloseCLick).toBeCalledTimes(1); - expect(onClick).not.toHaveBeenCalled(); - }); -}); diff --git a/src/components/Tag/Tag.tsx b/src/components/Tag/Tag.tsx deleted file mode 100644 index 301dba37..00000000 --- a/src/components/Tag/Tag.tsx +++ /dev/null @@ -1,103 +0,0 @@ -import { - FC, - KeyboardEventHandler, - MouseEventHandler, - useCallback, - useMemo, - useRef, -} from 'react'; - -import { stylesBuilder } from './stylesBuilder'; -import { TagProps } from './Tag.props'; -import { Avatar } from '../Avatar'; -import { IconButton } from '../IconButton'; - -import { tet } from '@/tetrisly'; -import { MarginProps } from '@/types'; - -const KEYBOARD_KEYS = { - Enter: 'Enter', - Space: ' ', -}; - -export const Tag: FC = ({ - label, - state, - beforeComponent, - onClick, - onCloseClick, - custom, - ...restProps -}) => { - const hasCloseButton = !!onCloseClick; - const hasOnClick = !!onClick; - const styles = useMemo( - () => stylesBuilder(custom, hasOnClick), - [custom, hasOnClick], - ); - - const containerRef = useRef(null); - const handleOnKeyDown: KeyboardEventHandler = useCallback( - (e) => { - if ( - e.target === containerRef.current && - (e.key === KEYBOARD_KEYS.Enter || e.key === KEYBOARD_KEYS.Space) - ) { - onClick?.(e); - } - }, - [containerRef, onClick], - ); - - const handleOnCloseClick: MouseEventHandler = useCallback( - (e) => { - onCloseClick?.(e); - e.stopPropagation(); - }, - [onCloseClick], - ); - - return ( - - {!!beforeComponent && ( - - )} - - {label} - - {hasCloseButton && ( - - )} - - ); -}; diff --git a/src/components/Tag/index.ts b/src/components/Tag/index.ts deleted file mode 100644 index cd8beb86..00000000 --- a/src/components/Tag/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export { Tag } from './Tag'; -export type { TagProps } from './Tag.props'; diff --git a/src/components/Tag/stylesBuilder/index.ts b/src/components/Tag/stylesBuilder/index.ts deleted file mode 100644 index fe248ee5..00000000 --- a/src/components/Tag/stylesBuilder/index.ts +++ /dev/null @@ -1 +0,0 @@ -export { stylesBuilder } from './stylesBuilder'; diff --git a/src/components/Tag/stylesBuilder/stylesBuilder.ts b/src/components/Tag/stylesBuilder/stylesBuilder.ts deleted file mode 100644 index 117b5c6c..00000000 --- a/src/components/Tag/stylesBuilder/stylesBuilder.ts +++ /dev/null @@ -1,36 +0,0 @@ -import type { TagProps } from '../Tag.props'; -import { defaultConfig } from '../Tag.styles'; - -import { mergeConfigWithCustom } from '@/services'; -import type { BaseProps } from '@/types/BaseProps'; - -type TagStylesBuilder = { - container: BaseProps; - label: BaseProps; - avatar: BaseProps; - closeButton: BaseProps; -}; -export const stylesBuilder = ( - custom: TagProps['custom'], - hasOnClick?: boolean, -): TagStylesBuilder => { - const { - hasOnClick: hasOnClickStyles, - innerElements: { - label, - closeButton, - beforeComponent: { avatar }, - }, - ...container - } = mergeConfigWithCustom({ defaultConfig, custom }); - - return { - container: { - ...container, - ...(hasOnClick && hasOnClickStyles), - }, - label, - avatar, - closeButton, - }; -}; diff --git a/src/docs-components/TagDocs.tsx b/src/docs-components/TagDocs.tsx deleted file mode 100644 index b9c8a074..00000000 --- a/src/docs-components/TagDocs.tsx +++ /dev/null @@ -1,70 +0,0 @@ -import { FC } from 'react'; - -import { Tag, TagProps } from '@/components/Tag'; -import { SectionHeader } from '@/docs-components/common/SectionHeader.tsx'; -import { States } from '@/docs-components/common/States.tsx'; -import { tet } from '@/tetrisly'; - -const headers = ['Remove button: No', 'Remove button: Yes'] as const; -const labels = ['Before component: None', 'Before component: Avatar']; -const states = [':normal', ':selected', ':disabled']; - -const RenderTag = ({ - header, - label, - state, -}: { - header: (typeof headers)[number]; - label: (typeof labels)[number]; - state: (typeof states)[number]; -}) => ( - - null : undefined} - onClick={() => null} - beforeComponent={ - label === 'Before component: Avatar' - ? { - type: 'Avatar', - props: { initials: 'A', appearance: 'blue', emphasis: 'high' }, - } - : undefined - } - /> - -); - -export const TagDocs: FC = () => ( - - {headers.map((header) => ( - - - {header} - - {labels.map((label) => ( - - - - - {states.map((state) => ( - - ))} - - - ))} - - ))} - -);