Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
61 changes: 46 additions & 15 deletions stories/elements/Chip/Gallery.stories.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
import React from 'react';
import Chip, { ChipProps } from 'ui/elements/Chip';
import { CHIP_VARIANTS } from 'ui/elements/Chip/constants';
import {
CHIP_DARKER_BG_OPTIONS,
CHIP_STATES,
CHIP_TYPES,
CHIP_WITH_BORDER_OPTIONS,
} from 'ui/elements/Chip/constants';
import Table from 'ui/elements/Table';

import TokenBlock from '../../helper-components/TokenBlock';
Expand All @@ -11,6 +16,19 @@ export default {
tags: ['!autodocs'],
};

const variantCombinations = CHIP_TYPES.flatMap((type) =>
CHIP_STATES.flatMap((state) =>
CHIP_DARKER_BG_OPTIONS.flatMap((darkerbg) =>
CHIP_WITH_BORDER_OPTIONS.map((withborder) => ({
type,
state,
darkerbg,
withborder,
}))
)
)
);

const Template = (args: ChipProps) => (
<Table.Table borderAround={false} borderVertical={false}>
<Table.TableHead highlightHeaders={false}>
Expand All @@ -24,26 +42,39 @@ const Template = (args: ChipProps) => (
</Table.TableRow>
</Table.TableHead>
<Table.TableBody>
{CHIP_VARIANTS.map((variant) => (
<Table.TableRow condensed>
<Table.TableDataCell>
<TokenBlock copy>{variant}</TokenBlock>
</Table.TableDataCell>
<Table.TableDataCell>
<Chip {...args} variant={variant} key={variant}>
Chip {variant}
</Chip>
</Table.TableDataCell>
</Table.TableRow>
))}
{variantCombinations.map(({ type, state, darkerbg, withborder }) => {
const key = `${type}-${state}-${darkerbg}-${withborder}`;
return (
<Table.TableRow condensed key={key}>
<Table.TableDataCell>
<TokenBlock copy>
{`type=${type}, state=${state}, darkerbg=${darkerbg}, withborder=${withborder}`}
</TokenBlock>
</Table.TableDataCell>
<Table.TableDataCell>
<Chip
{...args}
type={type}
state={state}
darkerbg={darkerbg}
withborder={withborder}
>
Chip {type}
</Chip>
</Table.TableDataCell>
</Table.TableRow>
);
})}
</Table.TableBody>
</Table.Table>
);

const defaultArgs: ChipProps = {
variant: 'brand',
type: 'brand',
state: 'default',
darkerbg: false,
withborder: false,
size: 'medium',
hasBorder: false,
textColor: null,
className: 'chip',
backgroundColor: null,
Expand Down
6 changes: 4 additions & 2 deletions stories/elements/Chip/index.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,11 @@ export default {
const Template = (args: ChipProps) => <Chip {...args}>This is a chip</Chip>;

const defaultArgs: ChipProps = {
variant: 'brand',
type: 'brand',
state: 'default',
darkerbg: false,
withborder: false,
size: 'medium',
hasBorder: false,
textColor: null,
backgroundColor: null,
borderColor: null,
Expand Down
54 changes: 25 additions & 29 deletions ui/elements/Chip/Chip.styles.ts
Original file line number Diff line number Diff line change
@@ -1,66 +1,62 @@
import styled, { css } from 'styled-components';

import {
CHIP_FONT_SIZE_MAPPING,
CHIP_VARIANT_STYLES_MAPPING,
} from './constants';
import { CHIP_FONT_SIZE_MAPPING, isChipSize } from './constants';
import { StyledChip, StyledChipTextProps } from './types';

export const StyledChipDiv = styled.div<StyledChip>`
display: flex;
padding: 3px 6px;
padding: var(--spacing-3px, 3px) var(--spacing-6px, 6px);
justify-content: center;
align-items: center;
gap: 4px;
gap: var(--spacing-4px, 4px);
height: fit-content;
width: fit-content;
border-radius: 4px;
border-radius: var(--corner-radius-4px, 4px);
color: ${({ $baseTextColor }) =>
$baseTextColor || 'var(--text-emphasis-brand-default, #0673f9)'};
background: ${({ $baseBackgroundColor }) =>
$baseBackgroundColor || 'var(--bg-subtle-brand-default, #e5f1ff)'};
font-family: var(--font-family, 'Mona Sans');
font-style: normal;
font-weight: var(--font-weight-semibold, 550);
line-height: 120%;
letter-spacing: 0.4px;

${({ variant }) =>
variant &&
${({ $size }) =>
isChipSize($size) &&
css`
${CHIP_VARIANT_STYLES_MAPPING[variant]};
${CHIP_FONT_SIZE_MAPPING[$size]}
`}
${({ size }) =>
size &&
css`
${CHIP_FONT_SIZE_MAPPING[size]}
`}
${({ hasBorder, borderColor }) =>
hasBorder &&
${({ $withborder, $baseBorderColor, $borderColor }) =>
$withborder &&
css`
border: 1px solid;
border-color: ${borderColor};
border-color: ${$borderColor || $baseBorderColor || 'transparent'};
`}
${({ textColor }) =>
textColor &&
${({ $textColor }) =>
$textColor &&
css`
color: ${textColor};
color: ${$textColor};
`}
${({ backgroundColor }) =>
backgroundColor &&
${({ $backgroundColor }) =>
$backgroundColor &&
css`
background: ${backgroundColor};
background: ${$backgroundColor};
`}
${({ rounded }) =>
rounded &&
${({ $rounded }) =>
$rounded &&
css`
border-radius: 100px;
`}
${({ iconPosition }) =>
iconPosition === 'right' &&
${({ $iconPosition }) =>
$iconPosition === 'right' &&
css`
flex-direction: row-reverse;
`}
`;

export const StyledChipText = styled.span<StyledChipTextProps>`
--alignment-padding: 2px;
--alignment-padding: var(--spacing-2px, 2px);

overflow: hidden;
display: -webkit-box;
Expand Down
90 changes: 68 additions & 22 deletions ui/elements/Chip/Chip.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,47 +4,93 @@ import { render, screen } from '@testing-library/react';
import React from 'react';

import Chip from './Chip';
import { CHIP_VARIANT_STYLES_MAPPING } from './constants';
import { ChipVariants } from './types';
import { resolveChipVariantStyles } from './constants';
import { ChipTypes } from './types';

describe('Chip Component', () => {
// Component Rendering
const getChipContainer = () =>
screen.getByText('Test Chip').closest('div') as HTMLElement;

it('renders the correct children', () => {
render(<Chip>Test Chip</Chip>);
expect(screen.getByText('Test Chip')).toBeInTheDocument();
});

// Variant Styles
const variants: ChipVariants[] = [
const types: ChipTypes[] = [
'brand',
'success',
'error',
'neutral',
'purple',
'success',
'warning',
'yellow',
'purple',
'disabled',
'action-brand',
'action-success',
'action-error',
'action-warning',
'action-yellow',
'action-purple',
];

variants.forEach((variant) => {
it(`renders with correct styles for variant: ${variant}`, () => {
render(<Chip variant={variant}>Test Chip</Chip>);
const chipElement = screen.getByText('Test Chip');
const styles = CHIP_VARIANT_STYLES_MAPPING[variant];
types.forEach((type) => {
it(`renders with correct default-state styles for type: ${type}`, () => {
render(<Chip type={type}>Test Chip</Chip>);
const chipElement = getChipContainer();
const { styles } = resolveChipVariantStyles({ type });

expect(chipElement).toHaveStyle(`background: ${styles.background}`);
expect(chipElement).toHaveStyle(`color: ${styles.color}`);
if (styles.border) {
expect(chipElement).toHaveStyle(`border: ${styles.border}`);
}
});
});

it('supports filled state and darker background variants', () => {
render(
<Chip type="brand" state="filled" darkerbg>
Test Chip
</Chip>
);

const chipElement = getChipContainer();
const { styles } = resolveChipVariantStyles({
type: 'brand',
state: 'filled',
darkerbg: true,
});

expect(chipElement).toHaveStyle(`background: ${styles.background}`);
expect(chipElement).toHaveStyle(`color: ${styles.color}`);
});

it('renders border when withborder is true', () => {
render(
<Chip type="success" withborder>
Test Chip
</Chip>
);

const chipElement = getChipContainer();
const { styles } = resolveChipVariantStyles({ type: 'success' });

expect(chipElement).toHaveStyle('border-style: solid');
expect(chipElement).toHaveStyle(`border-color: ${styles.border}`);
});

it('keeps legacy hasBorder alias working', () => {
render(
<Chip type="warning" hasBorder>
Test Chip
</Chip>
);

expect(getChipContainer()).toHaveStyle('border-style: solid');
});

it('keeps legacy variant mapping working', () => {
render(<Chip variant="action-brand">Test Chip</Chip>);

const chipElement = getChipContainer();
const { styles } = resolveChipVariantStyles({
variant: 'action-brand',
});

expect(chipElement).toHaveStyle(`background: ${styles.background}`);
expect(chipElement).toHaveStyle(`color: ${styles.color}`);
});

it('applies visual alignment padding correctly based on icon position', () => {
const { rerender } = render(
<Chip icon="check" iconPosition="left">
Expand Down
Loading