Skip to content

Commit

Permalink
feat(Tag): update to 2.0 styles (#2087)
Browse files Browse the repository at this point in the history
- use new render color tokens
- update layout
- update tests and snapshots
  • Loading branch information
booc0mtaco authored Nov 14, 2024
1 parent 497d4a9 commit a344222
Show file tree
Hide file tree
Showing 8 changed files with 312 additions and 452 deletions.
34 changes: 29 additions & 5 deletions src/components/Tag/Tag.module.css
Original file line number Diff line number Diff line change
Expand Up @@ -10,23 +10,22 @@
.tag {
width: max-content;
height: calc(var(--eds-size-3) / 16 * 1rem);
padding-left: calc(var(--eds-size-1-and-half) / 16 * 1rem);
padding-right: calc(var(--eds-size-1-and-half) / 16 * 1rem);
padding: calc(var(--eds-size-half) / 16 * 1rem) calc(var(--eds-size-1) / 16 * 1rem);

display: inline-flex;
align-items: center;

/* border color matches the background color, unless a color variant is applied */
border: calc(var(--eds-theme-border-width) * 1px) solid var(--tag-secondary-color) ;
border-radius: calc(var(--eds-border-radius-full) * 1px);
border-radius: calc(var(--eds-border-radius-md) * 1px);

background-color: var(--tag-secondary-color);
color: var(--tag-primary-color);
--icon-size-default: 0.875rem;
}

/**
* If tags are used inline, ensures spacing between tags.
* Spacing between icon and label text, if icon present
* TODO: perhaps use gap?
*/
.tag > :not(:last-child) {
margin-right: calc(var(--eds-size-half) / 16 * 1rem);
Expand All @@ -45,6 +44,7 @@

/**
* Color variants.
* TODO(next-major): remove these status colors
*/
:where(.tag--neutral) {
--tag-primary-color: var(--eds-theme-color-text-neutral-default);
Expand Down Expand Up @@ -76,8 +76,32 @@
--tag-outline-color: var(--eds-theme-color-border-brand-primary-default);
}

/**
* Status color treatments
*/
:where(.tag--status-critical) {
--tag-primary-color: var(--eds-theme-color-icon-utility-critical);
--tag-secondary-color: var(--eds-theme-color-background-utility-critical-low-emphasis);
}

:where(.tag--status-favorable) {
--tag-primary-color: var(--eds-theme-color-icon-utility-favorable);
--tag-secondary-color: var(--eds-theme-color-background-utility-favorable-low-emphasis);
}

:where(.tag--status-warning) {
--tag-primary-color: var(--eds-theme-color-icon-utility-warning);
--tag-secondary-color: var(--eds-theme-color-background-utility-warning-low-emphasis);
}

:where(.tag--status-informational) {
--tag-primary-color: var(--eds-theme-color-text-utility-informational);
--tag-secondary-color: var(--eds-theme-color-background-utility-information-low-emphasis);
}

/**
* Adds outline to the tag.
* TODO(next-major): remove handling for outline in 2.0 component
*/
.tag--outline {
border-color: var(--tag-outline-color);
Expand Down
7 changes: 0 additions & 7 deletions src/components/Tag/Tag.stories.module.css

This file was deleted.

105 changes: 23 additions & 82 deletions src/components/Tag/Tag.stories.tsx
Original file line number Diff line number Diff line change
@@ -1,72 +1,46 @@
import type { StoryObj, Meta } from '@storybook/react';
import React from 'react';
import { Tag, VARIANTS } from './Tag';
import styles from './Tag.stories.module.css';
import { Tag } from './Tag';

export default {
title: 'Components/Tag',
component: Tag,
parameters: {
layout: 'centered',
badges: ['intro-1.0', 'current-1.3'],
badges: ['intro-1.0', 'current-2.0'],
},
args: {
label: 'Tag text',
},
argTypes: {
hasOutline: {
table: {
disable: true,
},
},
text: {
table: {
disable: true,
},
},
variant: {
control: {
type: 'select',
table: {
disable: true,
},
options: VARIANTS,
},
},
args: {
text: 'Tag text',
variant: 'neutral' as const,
},
} as Meta<Args>;

type Args = React.ComponentProps<typeof Tag>;
type Story = StoryObj<Args>;

export const Default: Story = {};

/**
* `Tag` variants correspond to named use cases. Each variant defines a text color, background/surface color, and potential outline color.
*/
export const Variants: Story = {
export const Default: Story = {
render: (args) => (
<div className={styles.tagList}>
{VARIANTS.map((variant) => {
return (
<Tag
data-testid="test"
key={variant}
{...args}
text={variant}
variant={variant}
/>
);
})}
</div>
),
};

/**
* `Tag` can have an outside border, which corresponds to the variant selected. When false, the border will be set to match the background color.
*/
export const OutlineVariants: Story = {
render: (args) => (
<div className={styles.tagList}>
{VARIANTS.map((variant) => {
return (
<Tag
key={variant}
{...args}
hasOutline
text={variant}
variant={variant}
/>
);
})}
<div className="flex gap-size-2">
<Tag {...args} status="informational" />
<Tag {...args} status="favorable" />
<Tag {...args} status="warning" />
<Tag {...args} status="critical" />
</div>
),
};
Expand All @@ -79,37 +53,4 @@ export const WithIcon: Story = {
args: {
icon: 'star-filled',
},
render: (args) => (
<div className={styles.tagList}>
{VARIANTS.map((variant) => {
return (
<Tag
key={variant}
{...args}
hasOutline
text={variant}
variant={variant}
/>
);
})}
</div>
),
};

/**
* `Tag` can support lengthy text, but should be kept as brief as possible.
*/
export const WithLongTextAndIcon: Story = {
...Default,
args: {
text: 'This tag has a really long text message',
icon: 'star',
},
render: (args) => (
<div className={styles.tagList}>
{VARIANTS.map((variant) => {
return <Tag key={variant} {...args} hasOutline variant={variant} />;
})}
</div>
),
};
7 changes: 0 additions & 7 deletions src/components/Tag/Tag.test.ts

This file was deleted.

54 changes: 54 additions & 0 deletions src/components/Tag/Tag.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import { generateSnapshots } from '@chanzuckerberg/story-utils';
import { render } from '@testing-library/react';
import React from 'react';

import { Tag } from './Tag';
import * as stories from './Tag.stories';
import type { StoryFile } from '../../util/utility-types';

describe('<Tag />', () => {
beforeEach(() => {
// Add in mocks for the calls that can occur in implementation to suppress logging in tests
const consoleMock = jest.spyOn(console, 'error');
const consoleWarnMock = jest.spyOn(console, 'warn');
consoleMock.mockImplementation();
consoleWarnMock.mockImplementation();
});

afterEach(() => {
jest.resetAllMocks();
});

generateSnapshots(stories as StoryFile);

describe('emits messages when misused', () => {
let consoleErrorMock: jest.SpyInstance, consoleWarnMock: jest.SpyInstance;
beforeEach(() => {
consoleWarnMock = jest.spyOn(console, 'warn');
consoleErrorMock = jest.spyOn(console, 'error');
consoleWarnMock.mockImplementation();
consoleErrorMock.mockImplementation();
});

it('errors when specifying hasOutline', () => {
render(<Tag hasOutline label="click" />);

expect(consoleWarnMock).toHaveBeenCalledTimes(0);
expect(consoleErrorMock).toHaveBeenCalledTimes(1);
});

it('warns when variant is used', () => {
render(<Tag label="click" variant="brand" />);

expect(consoleWarnMock).toHaveBeenCalledTimes(1);
expect(consoleErrorMock).toHaveBeenCalledTimes(0);
});

it('warns when text is used', () => {
render(<Tag text="click" />);

expect(consoleWarnMock).toHaveBeenCalledTimes(1);
expect(consoleErrorMock).toHaveBeenCalledTimes(0);
});
});
});
Loading

0 comments on commit a344222

Please sign in to comment.