Skip to content

Commit

Permalink
feat: TET-863 add Status component
Browse files Browse the repository at this point in the history
  • Loading branch information
karolinaszarek committed Apr 22, 2024
1 parent 05eb801 commit bdd4df9
Show file tree
Hide file tree
Showing 11 changed files with 512 additions and 0 deletions.
12 changes: 12 additions & 0 deletions src/components/Status/Status.props.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { StatusConfig } from './Status.styles';
import { StatusAppearance } from './StatusAppearance.type';
import { StatusEmphasis } from './StatusEmphasis.type';

type Status = string;

export type StatusProps = {
appearance?: StatusAppearance;
custom?: StatusConfig;
emphasis?: StatusEmphasis;
label?: Status;
};
49 changes: 49 additions & 0 deletions src/components/Status/Status.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import { Meta, StoryObj } from '@storybook/react';

import { Status } from './Status';
import { StatusEmphasis } from './StatusEmphasis.type';

import { StatusDocs } from '@/docs-components/StatusDocs';
import { TetDocs } from '@/docs-components/TetDocs';

const meta = {
title: 'Status',
component: Status,
tags: ['autodocs'],
argTypes: {
emphasis: {
control: {
type: 'select',
options: ['high', 'medium', 'low'] satisfies StatusEmphasis[],
},
},
},
args: {
appearance: 'grey',
emphasis: 'high',
},
parameters: {
docs: {
description: {
component:
'An indicator that conveys the current state or condition of a process, item, or user. Status indicators often use colors, icons, or text to communicate information, such as online presence, approval, or completion.',
},
page: () => (
<TetDocs docs="https://docs.tetrisly.com/components/in-progress/status">
<StatusDocs />
</TetDocs>
),
},
},
} satisfies Meta<typeof Status>;

export default meta;
type Story = StoryObj<typeof meta>;

export const Default: Story = {
args: {
appearance: 'grey',
emphasis: 'high',
label: 'status',
},
};
196 changes: 196 additions & 0 deletions src/components/Status/Status.styles.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,196 @@
import { StatusAppearance } from './StatusAppearance.type';

import { BaseProps } from '@/types';

export type StatusConfig = {
appearance?: Partial<
Record<
StatusAppearance,
{ emphasis?: Partial<Record<'high' | 'medium' | 'low', BaseProps>> }
>
>;
dot: {
appearance: Partial<
Record<
StatusAppearance,
{ emphasis?: Partial<Record<'high' | 'medium' | 'low', BaseProps>> }
>
>;
} & BaseProps<'appearance'>;
hasLabel?: BaseProps;
innerElements: {
label?: BaseProps;
};
} & BaseProps<'appearance'>;

export const defaultConfig = {
display: 'flex',
w: 'fit-content',
h: '$size-xSmall',
gap: '$space-component-gap-small',
p: '$space-component-padding-null $space-component-padding-medium',
borderRadius: '$border-radius-medium',
alignItems: 'center',
text: '$typo-body-medium',
dot: {
w: '8px',
h: '8px',
borderRadius: '$border-radius-full',
appearance: {
grey: {
emphasis: {
high: {
backgroundColor: '$color-nonSemantic-white-content-primary',
},
medium: {
backgroundColor: '$color-nonSemantic-grey-background-strong',
},
low: {
backgroundColor: '$color-nonSemantic-grey-background-strong',
},
},
},
blue: {
emphasis: {
high: {
backgroundColor: '$color-nonSemantic-white-content-primary',
},
medium: {
backgroundColor: '$color-nonSemantic-blue-background-strong',
},
low: {
backgroundColor: '$color-nonSemantic-blue-background-strong',
},
},
},
green: {
emphasis: {
high: {
backgroundColor: '$color-nonSemantic-white-content-primary',
},
medium: {
backgroundColor: '$color-nonSemantic-green-background-strong',
},
low: {
backgroundColor: '$color-nonSemantic-green-background-strong',
},
},
},
red: {
emphasis: {
high: {
backgroundColor: '$color-nonSemantic-white-content-primary',
},
medium: {
backgroundColor: '$color-nonSemantic-red-background-strong',
},
low: {
backgroundColor: '$color-nonSemantic-red-background-strong',
},
},
},
orange: {
emphasis: {
high: {
backgroundColor: '$color-nonSemantic-grey-content-primary',
},
medium: {
backgroundColor: '$color-nonSemantic-orange-background-strong',
},
low: {
backgroundColor: '$color-nonSemantic-orange-background-strong',
},
},
},
},
},
appearance: {
grey: {
emphasis: {
high: {
backgroundColor: '$color-nonSemantic-grey-background-strong',
color: '$color-nonSemantic-white-content-primary',
},
medium: {
backgroundColor: '$color-nonSemantic-grey-background-muted',
color: '$color-nonSemantic-grey-content-primary',
},
low: {
backgroundColor: '$color-transparent',
color: '$color-nonSemantic-grey-content-primary',
},
},
},
blue: {
emphasis: {
high: {
backgroundColor: '$color-nonSemantic-blue-background-strong',
color: '$color-nonSemantic-white-content-primary',
},
medium: {
backgroundColor: '$color-nonSemantic-blue-background-muted',
color: '$color-nonSemantic-blue-content-primary',
},
low: {
backgroundColor: '$color-transparent',
color: '$color-nonSemantic-blue-content-primary',
},
},
},
green: {
emphasis: {
high: {
color: '$color-nonSemantic-white-content-primary',
backgroundColor: '$color-nonSemantic-green-background-strong',
},
medium: {
color: '$color-nonSemantic-green-content-primary',
backgroundColor: '$color-nonSemantic-green-background-muted',
},
low: {
color: '$color-nonSemantic-green-content-primary',
backgroundColor: '$color-transparent',
},
},
},
red: {
emphasis: {
high: {
color: '$color-nonSemantic-white-content-primary',
backgroundColor: '$color-nonSemantic-red-background-strong',
},
medium: {
color: '$color-nonSemantic-red-content-primary',
backgroundColor: '$color-nonSemantic-red-background-muted',
},
low: {
color: '$color-nonSemantic-red-content-primary',
backgroundColor: '$color-transparent',
},
},
},
orange: {
emphasis: {
high: {
backgroundColor: '$color-nonSemantic-orange-background-strong',
color: '$color-nonSemantic-grey-content-primary',
},
medium: {
color: '$color-nonSemantic-orange-content-primary',
backgroundColor: '$color-nonSemantic-orange-background-muted',
},
low: {
color: '$color-nonSemantic-orange-content-primary',
backgroundColor: '$color-transparent',
},
},
},
},
innerElements: {
label: {},
},
} satisfies StatusConfig;

export const statusStyles = {
defaultConfig,
};
117 changes: 117 additions & 0 deletions src/components/Status/Status.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
import { Status } from './Status';
import { render } from '../../tests/render';

import { customPropTester } from '@/tests/customPropTester';

const getStatus = (jsx: JSX.Element) => {
const { getByTestId } = render(jsx);
return {
status: getByTestId('status'),
dot: getByTestId('status-dot'),
};
};

describe('Status', () => {
it('should render the status', () => {
const { status } = getStatus(<Status />);
expect(status).toBeInTheDocument();
});

it('should render a correct color (grey, high)', () => {
const { status, dot } = getStatus(
<Status appearance="grey" emphasis="high" />,
);
expect(status).toHaveStyle(
'background-color: rgb(85, 95, 109); color: rgb(255, 255, 255)',
);
expect(dot).toHaveStyle('background-color: rgb(255, 255, 255)');
});

it('should render a correct color (grey, medium)', () => {
const { status, dot } = getStatus(
<Status appearance="grey" emphasis="medium" />,
);
expect(status).toHaveStyle(
'background-color: rgb(222, 227, 231); color: rgb(39, 46, 53)',
);
expect(dot).toHaveStyle('background-color: rgb(85, 95, 109)');
});

it('should render a correct color (grey, low)', () => {
const { status, dot } = getStatus(
<Status appearance="grey" emphasis="low" />,
);
expect(status).toHaveStyle(
'background-color: rgba(255, 255, 255, 0); color: rgb(39, 46, 53)',
);
expect(dot).toHaveStyle('background-color: rgb(85, 95, 109)');
});

it('should render a correct color (blue, high)', () => {
const { status, dot } = getStatus(
<Status appearance="blue" emphasis="high" />,
);
expect(status).toHaveStyle(
'background-color: rgb(48, 98, 212); color: rgb(255, 255, 255)',
);
expect(dot).toHaveStyle('background-color: rgb(255, 255, 255)');
});

it('should render a correct color (green, high)', () => {
const { status, dot } = getStatus(
<Status appearance="green" emphasis="high" />,
);
expect(status).toHaveStyle(
'background-color: rgb(29, 124, 77); color: rgb(255, 255, 255)',
);
expect(dot).toHaveStyle('background-color: rgb(255, 255, 255)');
});

it('should render a correct color (red, high)', () => {
const { status, dot } = getStatus(
<Status appearance="red" emphasis="high" />,
);
expect(status).toHaveStyle(
'background-color: rgb(197, 52, 52); color: rgb(255, 255, 255)',
);
expect(dot).toHaveStyle('background-color: rgb(255, 255, 255)');
});

it('should render a correct color (orange, high)', () => {
const { status, dot } = getStatus(
<Status appearance="orange" emphasis="high" />,
);
expect(status).toHaveStyle(
'background-color: rgb(245, 150, 56); color: rgb(39, 46, 53)',
);
expect(dot).toHaveStyle('background-color: rgb(39, 46, 53)');
});

it('should render a correct color (orange, medium)', () => {
const { status, dot } = getStatus(
<Status appearance="orange" emphasis="medium" />,
);
expect(status).toHaveStyle(
'background-color: rgb(252, 222, 192); color: rgb(122, 69, 16)',
);
expect(dot).toHaveStyle('background-color: rgb(245, 150, 56)');
});

it('should render a correct color (orange, low)', () => {
const { status, dot } = getStatus(
<Status appearance="orange" emphasis="low" />,
);
expect(status).toHaveStyle(
'background-color: rgba(255, 255, 255, 0); color: rgb(122, 69, 16)',
);
expect(dot).toHaveStyle('background-color: rgb(245, 150, 56)');
});

customPropTester(<Status />, {
containerId: 'status',
props: {
appearance: ['grey', 'blue', 'green', 'red', 'orange'],
emphasis: ['high', 'medium', 'low'],
},
});
});
Loading

0 comments on commit bdd4df9

Please sign in to comment.