diff --git a/e2e/components/InteractiveTag/InteractiveTag-test.avt.e2e.js b/e2e/components/InteractiveTag/InteractiveTag-test.avt.e2e.js index 406818fc503a..9cea0bf2c0b8 100644 --- a/e2e/components/InteractiveTag/InteractiveTag-test.avt.e2e.js +++ b/e2e/components/InteractiveTag/InteractiveTag-test.avt.e2e.js @@ -14,7 +14,7 @@ test.describe('@avt InteractiveTag', () => { test('@avt-advanced-states DismissibleTag', async ({ page }) => { await visitStory(page, { component: 'Tag', - id: 'experimental-unstable-interactivetag--dismissible', + id: 'components-tag--dismissible', globals: { theme: 'white', }, @@ -26,7 +26,7 @@ test.describe('@avt InteractiveTag', () => { test('@avt-advanced-states OperationalTag', async ({ page }) => { await visitStory(page, { component: 'Tag', - id: 'experimental-unstable-interactivetag--operational', + id: 'components-tag--operational', globals: { theme: 'white', }, @@ -37,7 +37,7 @@ test.describe('@avt InteractiveTag', () => { test('@avt-advanced-states SelectableTag', async ({ page }) => { await visitStory(page, { component: 'Tag', - id: 'experimental-unstable-interactivetag--selectable', + id: 'components-tag--selectable', globals: { theme: 'white', }, @@ -48,7 +48,7 @@ test.describe('@avt InteractiveTag', () => { test('@avt-keyboard-nav DismissibleTag', async ({ page }) => { await visitStory(page, { component: 'Tag', - id: 'experimental-unstable-interactivetag--dismissible', + id: 'components-tag--dismissible', globals: { theme: 'white', }, @@ -82,7 +82,7 @@ test.describe('@avt InteractiveTag', () => { test('@avt-keyboard-nav OperationalTag', async ({ page }) => { await visitStory(page, { component: 'Tag', - id: 'experimental-unstable-interactivetag--operational', + id: 'components-tag--operational', globals: { theme: 'white', }, @@ -117,7 +117,7 @@ test.describe('@avt InteractiveTag', () => { test('@avt-keyboard-nav SelectableTag', async ({ page }) => { await visitStory(page, { component: 'Tag', - id: 'experimental-unstable-interactivetag--selectable', + id: 'components-tag--selectable', globals: { theme: 'white', }, diff --git a/e2e/components/InteractiveTag/InteractiveTag-test.e2e.js b/e2e/components/InteractiveTag/InteractiveTag-test.e2e.js index fe9795fd3fa8..8b68d48140cb 100644 --- a/e2e/components/InteractiveTag/InteractiveTag-test.e2e.js +++ b/e2e/components/InteractiveTag/InteractiveTag-test.e2e.js @@ -17,7 +17,7 @@ test.describe('InteractiveTag', () => { test('DismissibleTag @vrt', async ({ page }) => { await snapshotStory(page, { component: 'DismissibleTag', - id: 'experimental-unstable-interactivetag--dismissible', + id: 'components-tag--dismissible', theme, }); }); @@ -25,7 +25,7 @@ test.describe('InteractiveTag', () => { test('OperationalTag @vrt', async ({ page }) => { await snapshotStory(page, { component: 'OperationalTag', - id: 'experimental-unstable-interactivetag--operational', + id: 'components-tag--operational', theme, }); }); @@ -33,7 +33,7 @@ test.describe('InteractiveTag', () => { test('SelectableTag @vrt', async ({ page }) => { await snapshotStory(page, { component: 'SelectableTag', - id: 'experimental-unstable-interactivetag--selectable', + id: 'components-tag--selectable', theme, }); }); diff --git a/packages/react/__tests__/__snapshots__/PublicAPI-test.js.snap b/packages/react/__tests__/__snapshots__/PublicAPI-test.js.snap index 746d4afdb6e1..d3504990412c 100644 --- a/packages/react/__tests__/__snapshots__/PublicAPI-test.js.snap +++ b/packages/react/__tests__/__snapshots__/PublicAPI-test.js.snap @@ -5874,9 +5874,6 @@ Map { ], "type": "oneOf", }, - "slug": Object { - "type": "node", - }, "text": Object { "type": "string", }, @@ -7012,9 +7009,6 @@ Map { ], "type": "oneOf", }, - "slug": Object { - "type": "node", - }, "text": Object { "type": "string", }, diff --git a/packages/react/src/components/Tag/DismissibleTag.tsx b/packages/react/src/components/Tag/DismissibleTag.tsx index 7221b3ef3a13..eb68a9b6a41d 100644 --- a/packages/react/src/components/Tag/DismissibleTag.tsx +++ b/packages/react/src/components/Tag/DismissibleTag.tsx @@ -149,6 +149,7 @@ const DismissibleTag = ({ className={`${prefix}--tag__label`}> {text} + {normalizedSlug} ({ - {normalizedSlug} ); diff --git a/packages/react/src/components/Tag/InteractiveTag.mdx b/packages/react/src/components/Tag/InteractiveTag.mdx deleted file mode 100644 index 9e75d691b13b..000000000000 --- a/packages/react/src/components/Tag/InteractiveTag.mdx +++ /dev/null @@ -1,85 +0,0 @@ -import { Canvas, Story, Meta } from '@storybook/blocks'; -import * as InteractiveTagStories from './InteractiveTag.stories'; - - - -# Interactive Tag - -[Source code](https://github.com/carbon-design-system/carbon/tree/main/packages/react/src/components/Tag) - |  -[Usage guidelines](https://www.carbondesignsystem.com/components/tag/usage) - |  -[Accessibility](https://www.carbondesignsystem.com/components/tag/accessibility) - -## Overview - -Tags can be used to categorize items. Use short labels for easy scanning. Use -two words only if necessary to describe the status and differentiate it from -other tags. - -## Dismissible - -Dismissible tags are used to remove tags that can be filtered out by the user. - -When to use: - -- Use DismissibleTag when you want to allow users to easily clear or dismiss - specific filters applied to items. - - - -```jsx - - {'Tag content'} - -``` - -## Selectable - -Selectable tags are used to select or unselect single or multiple items. -Selectable tags can also be used in filtering by label scenarios when they do -not need to be dismissed. - -When to use: - -- Use selectable tags to toggle between a selected or unselected state. -- Use when needing to filter without an explicit dismissable functionality. (We - need to be a little more specific around filtering for selectable versus - dismissable tags). - - - -```jsx - - {'Tag content'} - -``` - -## Operational - -Operational tags enable the user to view a list of all items associated with a -given tag in different ways. - -When to use: - -- Use to view a list of items with the same tag in a popover, or breadcrumb - detail view. - -When not to use: - -- Do not use operational tags as a replacement for links that direct you to an - entirely different page or launch you out to another tab. -- Do not use in combination with Dismissable tags. Instead, consider letting the - user enter an "edit mode" to dismiss tags. - - - -```jsx - - {'Tag content'} - -``` diff --git a/packages/react/src/components/Tag/InteractiveTag.stories.js b/packages/react/src/components/Tag/InteractiveTag.stories.js index e5c450254e96..170743dee83c 100644 --- a/packages/react/src/components/Tag/InteractiveTag.stories.js +++ b/packages/react/src/components/Tag/InteractiveTag.stories.js @@ -12,13 +12,13 @@ import { default as OperationalTag } from './OperationalTag'; import { default as DismissibleTag } from './DismissibleTag'; import { Asleep } from '@carbon/icons-react'; import { Popover, PopoverContent } from '../Popover'; -import mdx from './InteractiveTag.mdx'; +import mdx from './Tag.mdx'; import './storyInteractiveTag.scss'; import { Text } from '../Text'; import Button from '../Button'; export default { - title: 'Experimental/unstable__InteractiveTag', + title: 'Components/Tag', component: SelectableTag, parameters: { docs: { diff --git a/packages/react/src/components/Tag/OperationalTag.tsx b/packages/react/src/components/Tag/OperationalTag.tsx index 84d9c4296fb1..5f7cae649815 100644 --- a/packages/react/src/components/Tag/OperationalTag.tsx +++ b/packages/react/src/components/Tag/OperationalTag.tsx @@ -64,11 +64,6 @@ export interface OperationalTagBaseProps { */ size?: keyof typeof SIZES; - /** - * **Experimental:** Provide a `Slug` component to be rendered inside the `OperationalTag` component - */ - slug?: ReactNode; - /** * Provide text to be rendered inside of a the tag. */ @@ -90,7 +85,6 @@ const OperationalTag = ({ disabled, id, renderIcon, - slug, size, text, type = 'gray', @@ -110,14 +104,6 @@ const OperationalTag = ({ setIsEllipsisApplied(isEllipsisActive(newElement)); }, [prefix, tagRef]); - let normalizedSlug; - if (slug && slug['type']?.displayName === 'AILabel') { - normalizedSlug = React.cloneElement(slug as React.ReactElement, { - size: 'sm', - kind: 'inline', - }); - } - const tooltipClasses = classNames( `${prefix}--icon-tooltip`, `${prefix}--tag-label-tooltip` @@ -144,7 +130,6 @@ const OperationalTag = ({ {text} - {normalizedSlug} ); @@ -160,7 +145,6 @@ const OperationalTag = ({ className={tagClasses} id={tagId} {...other}> - {normalizedSlug} {text} @@ -196,11 +180,6 @@ OperationalTag.propTypes = { */ size: PropTypes.oneOf(Object.keys(SIZES)), - /** - * **Experimental:** Provide a `Slug` component to be rendered inside the `OperationalTag` component - */ - slug: PropTypes.node, - /** * Provide text to be rendered inside of a the tag. */ diff --git a/packages/react/src/components/Tag/SelectableTag.tsx b/packages/react/src/components/Tag/SelectableTag.tsx index 06b712eb8421..0441f1d34dd5 100644 --- a/packages/react/src/components/Tag/SelectableTag.tsx +++ b/packages/react/src/components/Tag/SelectableTag.tsx @@ -49,11 +49,6 @@ export interface SelectableTagBaseProps { */ size?: keyof typeof SIZES; - /** - * **Experimental:** Provide a `Slug` component to be rendered inside the `SelectableTag` component - */ - slug?: ReactNode; - /** * Provide text to be rendered inside of a the tag. */ @@ -71,7 +66,6 @@ const SelectableTag = ({ id, renderIcon, selected = false, - slug, size, text, ...other @@ -92,14 +86,6 @@ const SelectableTag = ({ setIsEllipsisApplied(isEllipsisActive(newElement)); }, [prefix, tagRef]); - let normalizedSlug; - if (slug && slug['type']?.displayName === 'AILabel') { - normalizedSlug = React.cloneElement(slug as React.ReactElement, { - size: 'sm', - kind: 'inline', - }); - } - const tooltipClasses = classNames( `${prefix}--icon-tooltip`, `${prefix}--tag-label-tooltip` @@ -120,7 +106,6 @@ const SelectableTag = ({ ({ {text} - {normalizedSlug} ); @@ -141,7 +125,6 @@ const SelectableTag = ({ ({ id={tagId} onClick={() => setSelectedTag(!selectedTag)} {...otherProps}> - {normalizedSlug} {text} @@ -190,11 +172,6 @@ SelectableTag.propTypes = { */ size: PropTypes.oneOf(Object.keys(SIZES)), - /** - * **Experimental:** Provide a `Slug` component to be rendered inside the `SelectableTag` component - */ - slug: PropTypes.node, - /** * Provide text to be rendered inside of a the tag. */ diff --git a/packages/react/src/components/Tag/Tag.mdx b/packages/react/src/components/Tag/Tag.mdx index cb0420bdea82..459fc7e9b9a5 100644 --- a/packages/react/src/components/Tag/Tag.mdx +++ b/packages/react/src/components/Tag/Tag.mdx @@ -1,5 +1,6 @@ -import { ArgTypes, Meta } from '@storybook/blocks'; +import { ArgTypes, Canvas, Meta } from '@storybook/blocks'; import * as TagStories from './Tag.stories'; +import * as InteractiveTagStories from './InteractiveTag.stories'; @@ -11,16 +12,73 @@ import * as TagStories from './Tag.stories';  |  [Accessibility](https://www.carbondesignsystem.com/components/tag/accessibility) -## Table of Contents - ## Overview -## Component API +Tags can be used to categorize items. Use short labels for easy scanning. Use +two words only if necessary to describe the status and differentiate it from +other tags. + +## Read Only + +Read-only tags are used to categorize, are used for labeling, and do not have +interactive functionality. Read-only tags come in several color choices and can +use optional decorative icons to delineate between multiple categories. + + + +## Dismissible + +Dismissible tags are used to remove tags that can be filtered out by the user. + +When to use: + +- Use DismissibleTag when you want to allow users to easily clear or dismiss + specific filters applied to items. + + + +## Selectable + +Selectable tags are used to select or unselect single or multiple items. +Selectable tags can also be used in filtering by label scenarios when they do +not need to be dismissed. + +When to use: + +- Use selectable tags to toggle between a selected or unselected state. +- Use when needing to filter without an explicit dismissable functionality. (We + need to be a little more specific around filtering for selectable versus + dismissable tags). + + + +## Operational + +Operational tags enable the user to view a list of all items associated with a +given tag in different ways. + +When to use: + +- Use to view a list of items with the same tag in a popover, or breadcrumb + detail view. + +When not to use: + +- Do not use operational tags as a replacement for links that direct you to an + entirely different page or launch you out to another tab. +- Do not use in combination with Dismissable tags. Instead, consider letting the + user enter an "edit mode" to dismiss tags. + + + +## With AI Label + +Tag with AI label is now stable for Read Only tags. This addition changes the +visual appearance of the component and introduces an AI explainability feature +when AI is present in the component. - + -## Feedback +## Skeleton -Help us improve this component by providing feedback, asking questions on Slack, -or updating this file on -[GitHub](https://github.com/carbon-design-system/carbon/edit/main/packages/react/src/components/Tag/Tag.mdx). + diff --git a/packages/react/src/components/Tag/Tag.stories.js b/packages/react/src/components/Tag/Tag.stories.js index 850d5f048fb0..294ad9f65740 100644 --- a/packages/react/src/components/Tag/Tag.stories.js +++ b/packages/react/src/components/Tag/Tag.stories.js @@ -13,71 +13,69 @@ import Button from '../Button'; import { AILabel, AILabelContent, AILabelActions } from '../AILabel'; import { IconButton } from '../IconButton'; import '../AILabel/ailabel-story.scss'; +import mdx from './Tag.mdx'; export default { title: 'Components/Tag', component: Tag, + parameters: { + docs: { + page: mdx, + }, + }, }; -export const ReadOnly = () => { +export const ReadOnly = (args) => { return ( <> - + {'Tag content with a long text description'} - + {'Tag content'} - + {'Tag content'} - + {'Tag content'} - + {'Tag content'} - + {'Tag content'} - + {'Tag content'} - + {'Tag content'} - + {'Tag content'} - + {'Tag content'} - + {'Tag content'} - + {'Tag content'} ); }; -export const Playground = (args) => { - return ( - - {'Tag content'} - - ); -}; - -Playground.args = { +ReadOnly.args = { disabled: false, filter: false, size: 'md', title: 'Clear filter', }; -Playground.argTypes = { +ReadOnly.argTypes = { children: { control: false, }, @@ -112,23 +110,7 @@ Playground.argTypes = { }, }, type: { - options: [ - 'red', - 'magenta', - 'purple', - 'blue', - 'cyan', - 'teal', - 'green', - 'gray', - 'cool-gray', - 'warm-gray', - 'high-contrast', - 'outline', - ], - control: { - type: 'select', - }, + control: false, }, }; diff --git a/packages/styles/scss/components/tag/_tag.scss b/packages/styles/scss/components/tag/_tag.scss index 30d5dcee08dc..f4d0f5cf11de 100644 --- a/packages/styles/scss/components/tag/_tag.scss +++ b/packages/styles/scss/components/tag/_tag.scss @@ -396,6 +396,10 @@ border-color: currentColor; } + .#{$prefix}--tag--filter .#{$prefix}--slug { + min-inline-size: convert.to-rem(32.14px); + } + // Windows HCM fix /* stylelint-disable */ .#{$prefix}--tag {