Repository navigation
refactor(tags): build tag on chip and look its colour up #8689
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
350f0ab
3624e64
ff75e13
00e7bb7
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,99 @@ | ||
| import React, { useState } from 'react' | ||
| import type { Meta, StoryObj } from 'storybook' | ||
|
|
||
| import Tag from 'components/tags/Tag' | ||
| import Constants from 'common/constants' | ||
| import { contentColourNames, contentColours } from 'common/theme/tokens' | ||
| import type { Tag as TTag } from 'common/types/responses' | ||
|
|
||
| const meta: Meta<typeof Tag> = { | ||
| component: Tag, | ||
| parameters: { | ||
| chromatic: { disableSnapshot: false }, | ||
| docs: { | ||
| description: { | ||
| component: | ||
| 'A project tag. Custom tags take a fill from the design system Content palette, keyed on the colour stored on the tag so nothing needs migrating. System tags (Stale, GitHub, GitLab, Unhealthy) take no fill and carry their state in a coloured icon and their border rather than the fill, so the state survives for anyone who cannot tell the fills apart.', | ||
| }, | ||
| }, | ||
| layout: 'padded', | ||
| }, | ||
| title: 'Components/Tags/Tag', | ||
| } | ||
| export default meta | ||
|
|
||
| type Story = StoryObj<typeof Tag> | ||
|
|
||
| const tag = (over: Partial<TTag>): Partial<TTag> => ({ | ||
| color: Constants.tagColors[0], | ||
| label: 'Checkout', | ||
| type: 'NONE', | ||
| ...over, | ||
| }) | ||
|
|
||
| export const Custom: Story = { args: { tag: tag({}) } } | ||
|
|
||
| export const EveryColour: Story = { | ||
| name: 'Every colour', | ||
| render: () => ( | ||
| <div className='d-flex flex-wrap gap-1'> | ||
| {contentColourNames.map((name) => ( | ||
| <Tag | ||
| key={name} | ||
| tag={tag({ color: contentColours[name], label: 'Checkout' })} | ||
| /> | ||
| ))} | ||
| </div> | ||
| ), | ||
| } | ||
|
|
||
| // The VCS icon is keyed on the tag's label, which the integration sets, so the | ||
| // examples use labels it actually produces rather than the type name. | ||
| // No Unhealthy example: Tag returns null for it unless the feature_health flag | ||
| // is on, and Storybook's Utils stub answers false to every flag. | ||
|
Comment on lines
+52
to
+53
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win Correct the stale comment about The comment says |
||
| const SYSTEM_EXAMPLES: Partial<TTag>[] = [ | ||
| { label: 'Stale', type: 'STALE' }, | ||
| { label: 'PR Open', type: 'GITHUB' }, | ||
| { label: 'PR Merged', type: 'GITHUB' }, | ||
| { label: 'Issue Open', type: 'GITLAB' }, | ||
| { label: 'Issue Closed', type: 'GITLAB' }, | ||
| ] | ||
|
|
||
| export const SystemTags: Story = { | ||
| name: 'System tags', | ||
| render: () => ( | ||
| <div className='d-flex flex-wrap gap-1'> | ||
| {SYSTEM_EXAMPLES.map((over) => ( | ||
| <Tag key={over.label} tag={tag(over)} /> | ||
| ))} | ||
| </div> | ||
| ), | ||
| } | ||
|
|
||
| // A colour we never issued, which the API allows. It takes the neutral rather | ||
| // than a guess: the label still reads, and the tag claims no category. | ||
| export const UnknownColour: Story = { | ||
| args: { tag: tag({ color: '#123456', label: 'Set via API' }) }, | ||
| name: 'Colour outside the scale', | ||
| } | ||
|
|
||
| /** Hooks cannot live in a story's render, so selection state gets a component. */ | ||
| const SelectableTags: React.FC = () => { | ||
| const [picked, setPicked] = useState<string>('Checkout') | ||
| return ( | ||
| <div className='d-flex flex-wrap gap-1'> | ||
| {['Checkout', 'Billing', 'Search'].map((label, i) => ( | ||
| <Tag | ||
| key={label} | ||
| onClick={() => setPicked(label)} | ||
| selected={picked === label} | ||
| tag={tag({ color: Constants.tagColors[i], label })} | ||
| /> | ||
| ))} | ||
| </div> | ||
| ) | ||
| } | ||
|
|
||
| export const Selectable: Story = { | ||
| render: () => <SelectableTags />, | ||
| } | ||
This file was deleted.
This file was deleted.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win
Correct the description:
Chiphas nononeoption.The description says "
noneleaves the colour to the caller".ChipVariantis'neutral' | 'accent' | 'outline', and a caller-chosen colour goes through thecolourprop. The Storybook docs therefore describe an API that does not exist. Describe thecolourprop instead.