From 77d3f947b67b935286c4b41135a8a5d81d52c5c8 Mon Sep 17 00:00:00 2001 From: kyledurand Date: Fri, 16 Feb 2024 09:10:49 -0500 Subject: [PATCH 1/5] feat: add large size prop to Tag --- .changeset/violet-goats-kick.md | 5 ++ .../src/components/Tag/Tag.module.scss | 47 +++++++++++- .../src/components/Tag/Tag.stories.tsx | 75 ++++++++++++++++++- polaris-react/src/components/Tag/Tag.tsx | 6 +- 4 files changed, 130 insertions(+), 3 deletions(-) create mode 100644 .changeset/violet-goats-kick.md diff --git a/.changeset/violet-goats-kick.md b/.changeset/violet-goats-kick.md new file mode 100644 index 00000000000..a4556c9f210 --- /dev/null +++ b/.changeset/violet-goats-kick.md @@ -0,0 +1,5 @@ +--- +'@shopify/polaris': minor +--- + +Added `size` prop to `Tag` diff --git a/polaris-react/src/components/Tag/Tag.module.scss b/polaris-react/src/components/Tag/Tag.module.scss index f8ec864a1ba..0edb83bdc9f 100644 --- a/polaris-react/src/components/Tag/Tag.module.scss +++ b/polaris-react/src/components/Tag/Tag.module.scss @@ -1,9 +1,9 @@ @import '../../styles/common'; $height: 20px; -$button-size: 20px; .Tag { + position: relative; display: inline-flex; max-width: 100%; align-items: center; @@ -208,3 +208,48 @@ $button-size: 20px; background: var(--p-color-bg-fill-tertiary-active); } } + +.sizeLarge, +.sizeLarge:is(.linkable), +.sizeLarge:is(.removable), +.sizeLarge:is(.removable, .linkable) { + min-height: 24px; + padding: 0 var(--p-space-200); +} + +.sizeLarge.removable { + padding-right: var(--p-space-200); +} + +.sizeLarge .Button { + opacity: 0; + position: absolute; + right: 0; + left: auto; + width: calc(20px + var(--p-space-100)); + height: 20px; + padding-left: var(--p-space-100); + margin: 0; +} +/* stylelint-disable-next-line selector-max-specificity -- specificity override */ +.sizeLarge:is(.linkable):hover .Button, +.sizeLarge:is(.removable):hover .Button, +.sizeLarge:is(.removable, .linkable):hover .Button, +.sizeLarge .Button:focus-visible { + opacity: 1; + background: linear-gradient( + to left, + var(--p-color-bg-fill-tertiary-hover) 0%, + var(--p-color-bg-fill-tertiary-hover) 65%, + transparent 100% + ); +} +/* stylelint-disable-next-line selector-max-specificity -- specificity override */ +.sizeLarge:is(.removable):not(.linkable):hover .Button { + background: linear-gradient( + to left, + var(--p-color-bg-fill-tertiary) 0%, + var(--p-color-bg-fill-tertiary) 65%, + transparent 100% + ); +} diff --git a/polaris-react/src/components/Tag/Tag.stories.tsx b/polaris-react/src/components/Tag/Tag.stories.tsx index b2d2df35fdb..1ad5be91a95 100644 --- a/polaris-react/src/components/Tag/Tag.stories.tsx +++ b/polaris-react/src/components/Tag/Tag.stories.tsx @@ -1,12 +1,47 @@ import React, {useCallback, useState} from 'react'; import type {ComponentMeta} from '@storybook/react'; -import {InlineStack, Icon, LegacyStack, Tag, Bleed} from '@shopify/polaris'; +import { + InlineStack, + Icon, + LegacyStack, + Tag, + Bleed, + BlockStack, + Text, +} from '@shopify/polaris'; import {WandIcon} from '@shopify/polaris-icons'; export default { component: Tag, } as ComponentMeta; +export function All() { + return ( + + Default + +
+ Removable + +
+ Clickable + +
+ With Link + +
+ With Custom Content + +
+ Removable with Link + +
+ Removable large + +
+ ); +} + export function Default() { return ( @@ -101,3 +136,41 @@ export function RemovableWithLink() { return {tagMarkup}; } + +export function RemovableLarge() { + const [selectedTags, setSelectedTags] = useState([ + 'Rustic', + 'Antique', + 'Vinyl', + 'Refurbished', + ]); + + const removeTag = useCallback( + (tag) => () => { + setSelectedTags((previousTags) => + previousTags.filter((previousTag) => previousTag !== tag), + ); + }, + [], + ); + + const tagMarkup = selectedTags.map((option, index) => ( + + {option} + + )); + const tagWithLinkMarkup = selectedTags.map((option, index) => ( + + {option} + + )); + + return ( + + Large + {tagMarkup} + Large with link + {tagWithLinkMarkup} + + ); +} diff --git a/polaris-react/src/components/Tag/Tag.tsx b/polaris-react/src/components/Tag/Tag.tsx index ae9c193b237..632bacbfe14 100644 --- a/polaris-react/src/components/Tag/Tag.tsx +++ b/polaris-react/src/components/Tag/Tag.tsx @@ -1,7 +1,7 @@ import React from 'react'; import {XSmallIcon} from '@shopify/polaris-icons'; -import {classNames} from '../../utilities/css'; +import {classNames, variationName} from '../../utilities/css'; import {useI18n} from '../../utilities/i18n'; import {Icon} from '../Icon'; import {handleMouseUpByBlurring} from '../../utilities/focus'; @@ -21,6 +21,8 @@ export interface NonMutuallyExclusiveProps { accessibilityLabel?: string; /** Url to navigate to when tag is clicked or keypressed. */ url?: string; + /** The size of the tag */ + size?: 'large'; } export type TagProps = NonMutuallyExclusiveProps & @@ -36,6 +38,7 @@ export function Tag({ onRemove, accessibilityLabel, url, + size, }: TagProps) { const i18n = useI18n(); @@ -47,6 +50,7 @@ export function Tag({ onRemove && styles.removable, url && !disabled && styles.linkable, segmented && styles.segmented, + size && styles[variationName('size', size)], ); if (onClick) { From d92377b48e3e78a26e8b6b979763c73a001f19a6 Mon Sep 17 00:00:00 2001 From: kyledurand Date: Wed, 21 Feb 2024 14:17:14 -0500 Subject: [PATCH 2/5] fix hover and active button color --- .../src/components/Tag/Tag.module.scss | 55 ++++++++++++------- .../src/components/Tag/Tag.stories.tsx | 5 +- 2 files changed, 37 insertions(+), 23 deletions(-) diff --git a/polaris-react/src/components/Tag/Tag.module.scss b/polaris-react/src/components/Tag/Tag.module.scss index 0edb83bdc9f..a9216de608e 100644 --- a/polaris-react/src/components/Tag/Tag.module.scss +++ b/polaris-react/src/components/Tag/Tag.module.scss @@ -210,46 +210,59 @@ $height: 20px; } .sizeLarge, -.sizeLarge:is(.linkable), -.sizeLarge:is(.removable), .sizeLarge:is(.removable, .linkable) { min-height: 24px; padding: 0 var(--p-space-200); } -.sizeLarge.removable { - padding-right: var(--p-space-200); +/* stylelint-disable-next-line selector-max-class, selector-max-specificity -- override code above */ +.sizeLarge .Link.segmented::after { + margin-right: 0; } .sizeLarge .Button { opacity: 0; position: absolute; - right: 0; + right: var(--p-space-050); left: auto; - width: calc(20px + var(--p-space-100)); + width: 20px; height: 20px; - padding-left: var(--p-space-100); margin: 0; + background-color: var(--p-color-bg-fill-tertiary); + + &:hover { + background: var(--p-color-bg-fill-tertiary-hover); + } + + &:active { + background: var(--p-color-bg-fill-tertiary-active); + } + + &::before { + content: ''; + position: absolute; + top: 0; + right: 100%; + bottom: 0; + left: calc(-1 * var(--p-width-200)); + pointer-events: none; + background: linear-gradient( + to left, + var(--p-color-bg-fill-tertiary) 0%, + transparent 100% + ); + } } -/* stylelint-disable-next-line selector-max-specificity -- specificity override */ -.sizeLarge:is(.linkable):hover .Button, -.sizeLarge:is(.removable):hover .Button, -.sizeLarge:is(.removable, .linkable):hover .Button, + +.sizeLarge:hover .Button, .sizeLarge .Button:focus-visible { opacity: 1; - background: linear-gradient( - to left, - var(--p-color-bg-fill-tertiary-hover) 0%, - var(--p-color-bg-fill-tertiary-hover) 65%, - transparent 100% - ); } -/* stylelint-disable-next-line selector-max-specificity -- specificity override */ -.sizeLarge:is(.removable):not(.linkable):hover .Button { +/* stylelint-disable-next-line selector-max-class, selector-max-specificity -- match tag hover color */ +.sizeLarge.removable.linkable:hover .Button::before { background: linear-gradient( to left, - var(--p-color-bg-fill-tertiary) 0%, - var(--p-color-bg-fill-tertiary) 65%, + var(--p-color-bg-fill-tertiary-hover) 0%, transparent 100% ); } diff --git a/polaris-react/src/components/Tag/Tag.stories.tsx b/polaris-react/src/components/Tag/Tag.stories.tsx index 1ad5be91a95..c16e5017403 100644 --- a/polaris-react/src/components/Tag/Tag.stories.tsx +++ b/polaris-react/src/components/Tag/Tag.stories.tsx @@ -154,12 +154,13 @@ export function RemovableLarge() { [], ); - const tagMarkup = selectedTags.map((option, index) => ( + const tagMarkup = selectedTags.map((option) => ( {option} )); - const tagWithLinkMarkup = selectedTags.map((option, index) => ( + + const tagWithLinkMarkup = selectedTags.map((option) => ( {option} From a6e8cb4ef8c787e2bac453a4708aea5ff16c12ec Mon Sep 17 00:00:00 2001 From: kyledurand Date: Wed, 21 Feb 2024 15:39:32 -0500 Subject: [PATCH 3/5] use overlay element vs pseudo --- .../src/components/Tag/Tag.module.scss | 31 +++++++++---------- polaris-react/src/components/Tag/Tag.tsx | 1 + 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/polaris-react/src/components/Tag/Tag.module.scss b/polaris-react/src/components/Tag/Tag.module.scss index a9216de608e..fee3902e680 100644 --- a/polaris-react/src/components/Tag/Tag.module.scss +++ b/polaris-react/src/components/Tag/Tag.module.scss @@ -237,29 +237,28 @@ $height: 20px; &:active { background: var(--p-color-bg-fill-tertiary-active); } - - &::before { - content: ''; - position: absolute; - top: 0; - right: 100%; - bottom: 0; - left: calc(-1 * var(--p-width-200)); - pointer-events: none; - background: linear-gradient( - to left, - var(--p-color-bg-fill-tertiary) 0%, - transparent 100% - ); - } } .sizeLarge:hover .Button, .sizeLarge .Button:focus-visible { opacity: 1; } + +.sizeLarge:hover .overlay { + position: absolute; + top: 0; + right: 20px; + bottom: 0; + width: 12px; + pointer-events: none; + background: linear-gradient( + to left, + var(--p-color-bg-fill-tertiary) 0%, + transparent 100% + ); +} /* stylelint-disable-next-line selector-max-class, selector-max-specificity -- match tag hover color */ -.sizeLarge.removable.linkable:hover .Button::before { +.sizeLarge.removable.linkable:hover .overlay { background: linear-gradient( to left, var(--p-color-bg-fill-tertiary-hover) 0%, diff --git a/polaris-react/src/components/Tag/Tag.tsx b/polaris-react/src/components/Tag/Tag.tsx index 632bacbfe14..6bc784318ee 100644 --- a/polaris-react/src/components/Tag/Tag.tsx +++ b/polaris-react/src/components/Tag/Tag.tsx @@ -108,6 +108,7 @@ export function Tag({ return ( {tagContent} + {size === 'large' && } {removeButton} ); From d3e00d4e6476a080bb5f40208c626e0010d1b643 Mon Sep 17 00:00:00 2001 From: kyledurand Date: Wed, 21 Feb 2024 16:46:51 -0500 Subject: [PATCH 4/5] revert hover / active bg colors --- .../src/components/Tag/Tag.module.scss | 28 ++++++++++++------- 1 file changed, 18 insertions(+), 10 deletions(-) diff --git a/polaris-react/src/components/Tag/Tag.module.scss b/polaris-react/src/components/Tag/Tag.module.scss index fee3902e680..52f4e31e2ce 100644 --- a/polaris-react/src/components/Tag/Tag.module.scss +++ b/polaris-react/src/components/Tag/Tag.module.scss @@ -231,11 +231,12 @@ $height: 20px; background-color: var(--p-color-bg-fill-tertiary); &:hover { - background: var(--p-color-bg-fill-tertiary-hover); + color: var(--p-color-icon-secondary-hover); } - &:active { - background: var(--p-color-bg-fill-tertiary-active); + &:active, + &:focus { + color: var(--p-color-icon-secondary-active); } } @@ -257,11 +258,18 @@ $height: 20px; transparent 100% ); } -/* stylelint-disable-next-line selector-max-class, selector-max-specificity -- match tag hover color */ -.sizeLarge.removable.linkable:hover .overlay { - background: linear-gradient( - to left, - var(--p-color-bg-fill-tertiary-hover) 0%, - transparent 100% - ); +/* stylelint-disable-next-line selector-max-class -- match tag hover color */ +.sizeLarge.removable.linkable { + /* stylelint-disable-next-line selector-max-class, selector-max-specificity -- match tag hover color */ + .Button { + background-color: var(--p-color-bg-fill-tertiary-hover); + } + /* stylelint-disable-next-line selector-max-class, selector-max-specificity -- match tag hover color */ + &:hover .overlay { + background: linear-gradient( + to left, + var(--p-color-bg-fill-tertiary-hover) 0%, + transparent 100% + ); + } } From 0d0646db031180845eaf6bffee578a90dddc1108 Mon Sep 17 00:00:00 2001 From: kyledurand Date: Thu, 22 Feb 2024 09:17:22 -0500 Subject: [PATCH 5/5] add documentation example --- .../components/selection-and-input/tag.mdx | 3 ++ .../pages/examples/tag-removable-large.tsx | 49 +++++++++++++++++++ 2 files changed, 52 insertions(+) create mode 100644 polaris.shopify.com/pages/examples/tag-removable-large.tsx diff --git a/polaris.shopify.com/content/components/selection-and-input/tag.mdx b/polaris.shopify.com/content/components/selection-and-input/tag.mdx index dbc5853652c..3001b190d67 100644 --- a/polaris.shopify.com/content/components/selection-and-input/tag.mdx +++ b/polaris.shopify.com/content/components/selection-and-input/tag.mdx @@ -28,6 +28,9 @@ examples: - fileName: tag-removable-with-link.tsx title: Removable with link description: A removable attribute to an object that allows merchants to navigate to a resource. + - fileName: tag-removable-large.tsx + title: Removable large + description: A larger, removable attribute to an object that allows merchants to navigate to a resource. previewImg: /images/components/selection-and-input/tag.png --- diff --git a/polaris.shopify.com/pages/examples/tag-removable-large.tsx b/polaris.shopify.com/pages/examples/tag-removable-large.tsx new file mode 100644 index 00000000000..9fca8445e2a --- /dev/null +++ b/polaris.shopify.com/pages/examples/tag-removable-large.tsx @@ -0,0 +1,49 @@ +import {Tag, LegacyStack, Text, BlockStack, Card} from '@shopify/polaris'; +import {useState, useCallback} from 'react'; +import {withPolarisExample} from '../../src/components/PolarisExampleWrapper'; + +export function RemovableLarge() { + const [selectedTags, setSelectedTags] = useState([ + 'Rustic', + 'Antique', + 'Vinyl', + 'Refurbished', + ]); + + const removeTag = useCallback( + (tag: string) => () => { + setSelectedTags((previousTags) => + previousTags.filter((previousTag) => previousTag !== tag), + ); + }, + [], + ); + + const tagMarkup = selectedTags.map((option) => ( + + {option} + + )); + + const tagWithLinkMarkup = selectedTags.map((option) => ( + + {option} + + )); + + return ( + + + Large + {tagMarkup} + + + + Large with link + {tagWithLinkMarkup} + + + ); +} + +export default withPolarisExample(RemovableLarge);