diff --git a/.changeset/khaki-icons-hammer.md b/.changeset/khaki-icons-hammer.md new file mode 100644 index 00000000000..7a84d651601 --- /dev/null +++ b/.changeset/khaki-icons-hammer.md @@ -0,0 +1,62 @@ +--- +"@spectrum-css/tag": major +--- + +Tag now uses Spectrum 2 tokens and specifications: + +- The invalid variant has been removed, tag errors are now displayed with help text within the tag group only. +- Borders remain in high contrast but are otherwise transparent. +- Thumbnail has been added as a visual option. +- Tag now has a max-inline-size. +- Read-only tags are now supported. +- Passthroughs for clear button have been updated to match the current spec. +- Default t-shirt size for tag is small. +- Clear button has accessibly sized target. +- Emphasized tags have accent coloring only when they are selected. + +Changed mods: + +- "--mod-tag-avatar-spacing-inline-end" --> "--mod-tag-visual-spacing-inline-end", +- "--mod-tag-icon-spacing-inline-end" --> "--mod-tag-visual-spacing-inline-end", +- "--mod-tag-spacing-inline-start" --> "--mod-tag-label-spacing-inline", +- "--mod-tag-label-spacing-inline-end" --> "--mod-tag-label-spacing-inline" +- "--mod-tag-clear-button-spacing-inline-start" --> "--mod-tag-label-to-clear-icon", +- "--mod-tag-clear-button-spacing-inline-end" --> "--mod-tag-edge-to-clear-icon" + +Added mods: + +- "--mod-tag-avatar-size", +- "--mod-tag-clear-button-size", +- "--mod-tag-label-font-family", +- "--mod-tag-label-font-style", +- "--mod-tag-label-line-height-cjk", +- "--mod-tag-maximum-width-multiplier", +- "--mod-tag-min-inline-size", +- "--mod-tag-thumbnail-size", +- "--mod-tag-visual-spacing-inline-start" + +Removed mods: + +- "--mod-tag-background-color-invalid-selected", +- "--mod-tag-background-color-invalid-selected-active", +- "--mod-tag-background-color-invalid-selected-focus", +- "--mod-tag-background-color-invalid-selected-hover", +- "--mod-tag-border-color-emphasized-active", +- "--mod-tag-border-color-emphasized-focus", +- "--mod-tag-border-color-emphasized-hover", +- "--mod-tag-border-color-invalid", +- "--mod-tag-border-color-invalid-active", +- "--mod-tag-border-color-invalid-focus", +- "--mod-tag-border-color-invalid-hover", +- "--mod-tag-border-color-invalid-selected", +- "--mod-tag-border-color-invalid-selected-active", +- "--mod-tag-border-color-invalid-selected-focus", +- "--mod-tag-border-color-invalid-selected-hover", +- "--mod-tag-border-color-selected-active", +- "--mod-tag-border-color-selected-focus", +- "--mod-tag-border-color-selected-hover", +- "--mod-tag-content-color-invalid", +- "--mod-tag-content-color-invalid-active", +- "--mod-tag-content-color-invalid-focus", +- "--mod-tag-content-color-invalid-hover", +- "--mod-tag-content-color-invalid-selected", diff --git a/components/clearbutton/stories/template.js b/components/clearbutton/stories/template.js index 4e09cb2b394..9ea01f8eeb0 100644 --- a/components/clearbutton/stories/template.js +++ b/components/clearbutton/stories/template.js @@ -15,6 +15,7 @@ export const Template = ({ isFocusable = true, staticColor, id = getRandomId("clearbutton"), + onclick = () => {}, customClasses = [], customStyles = {}, }, context) => html` @@ -38,6 +39,7 @@ export const Template = ({ ?disabled=${isDisabled} tabindex=${isFocusable ? 0 : -1} aria-hidden=${isFocusable} + @click=${onclick} >
${Icon({ diff --git a/components/tag/dist/metadata.json b/components/tag/dist/metadata.json index 58ce63ea185..e4503014031 100644 --- a/components/tag/dist/metadata.json +++ b/components/tag/dist/metadata.json @@ -4,46 +4,32 @@ ".spectrum-Tag", ".spectrum-Tag .spectrum-Avatar", ".spectrum-Tag .spectrum-Tag-clearButton", - ".spectrum-Tag .spectrum-Tag-clearButton .spectrum-ClearButton-fill", ".spectrum-Tag .spectrum-Tag-itemIcon", ".spectrum-Tag .spectrum-Tag-itemLabel", + ".spectrum-Tag .spectrum-Thumbnail", ".spectrum-Tag--sizeL", ".spectrum-Tag--sizeM", - ".spectrum-Tag--sizeS", ".spectrum-Tag.is-disabled", ".spectrum-Tag.is-disabled .spectrum-Avatar", - ".spectrum-Tag.is-emphasized", - ".spectrum-Tag.is-emphasized.is-focused", - ".spectrum-Tag.is-emphasized:active", - ".spectrum-Tag.is-emphasized:focus-visible", - ".spectrum-Tag.is-emphasized:hover", - ".spectrum-Tag.is-focused", - ".spectrum-Tag.is-focused:after", - ".spectrum-Tag.is-invalid", - ".spectrum-Tag.is-invalid.is-focused", - ".spectrum-Tag.is-invalid.is-selected", - ".spectrum-Tag.is-invalid.is-selected.is-focused", - ".spectrum-Tag.is-invalid.is-selected:active", - ".spectrum-Tag.is-invalid.is-selected:focus-visible", - ".spectrum-Tag.is-invalid.is-selected:hover", - ".spectrum-Tag.is-invalid:active", - ".spectrum-Tag.is-invalid:focus-visible", - ".spectrum-Tag.is-invalid:hover", + ".spectrum-Tag.is-disabled .spectrum-Thumbnail", ".spectrum-Tag.is-selected", - ".spectrum-Tag.is-selected.is-focused", - ".spectrum-Tag.is-selected:active", - ".spectrum-Tag.is-selected:focus-visible", - ".spectrum-Tag.is-selected:hover", - ".spectrum-Tag:active", - ".spectrum-Tag:focus-visible", - ".spectrum-Tag:focus-visible:after", - ".spectrum-Tag:hover" + ".spectrum-Tag.is-selected:not(.is-disabled, .is-readOnly)", + ".spectrum-Tag.spectrum-Tag--emphasized", + ".spectrum-Tag.spectrum-Tag--emphasized.is-selected:not(.is-disabled, .is-readOnly)", + ".spectrum-Tag.spectrum-Tag.is-disabled", + ".spectrum-Tag:lang(ja)", + ".spectrum-Tag:lang(ko)", + ".spectrum-Tag:lang(zh)", + ".spectrum-Tag:not(.is-disabled, .is-readOnly):active", + ".spectrum-Tag:not(.is-disabled, .is-readOnly):focus-visible", + ".spectrum-Tag:not(.is-disabled, .is-readOnly):focus-visible:after", + ".spectrum-Tag:not(.is-disabled, .is-readOnly):hover" ], "modifiers": [ "--mod-tag-animation-duration", + "--mod-tag-avatar-size", "--mod-tag-avatar-spacing-block-end", "--mod-tag-avatar-spacing-block-start", - "--mod-tag-avatar-spacing-inline-end", "--mod-tag-background-color", "--mod-tag-background-color-active", "--mod-tag-background-color-disabled", @@ -53,10 +39,6 @@ "--mod-tag-background-color-emphasized-hover", "--mod-tag-background-color-focus", "--mod-tag-background-color-hover", - "--mod-tag-background-color-invalid-selected", - "--mod-tag-background-color-invalid-selected-active", - "--mod-tag-background-color-invalid-selected-focus", - "--mod-tag-background-color-invalid-selected-hover", "--mod-tag-background-color-selected", "--mod-tag-background-color-selected-active", "--mod-tag-background-color-selected-focus", @@ -65,40 +47,21 @@ "--mod-tag-border-color-active", "--mod-tag-border-color-disabled", "--mod-tag-border-color-emphasized", - "--mod-tag-border-color-emphasized-active", - "--mod-tag-border-color-emphasized-focus", - "--mod-tag-border-color-emphasized-hover", "--mod-tag-border-color-focus", "--mod-tag-border-color-hover", - "--mod-tag-border-color-invalid", - "--mod-tag-border-color-invalid-active", - "--mod-tag-border-color-invalid-focus", - "--mod-tag-border-color-invalid-hover", - "--mod-tag-border-color-invalid-selected", - "--mod-tag-border-color-invalid-selected-active", - "--mod-tag-border-color-invalid-selected-focus", - "--mod-tag-border-color-invalid-selected-hover", "--mod-tag-border-color-selected", - "--mod-tag-border-color-selected-active", - "--mod-tag-border-color-selected-focus", - "--mod-tag-border-color-selected-hover", "--mod-tag-border-width", + "--mod-tag-clear-button-size", "--mod-tag-clear-button-spacing-block", - "--mod-tag-clear-button-spacing-inline-end", - "--mod-tag-clear-button-spacing-inline-start", "--mod-tag-content-color", "--mod-tag-content-color-active", "--mod-tag-content-color-disabled", "--mod-tag-content-color-emphasized", "--mod-tag-content-color-focus", "--mod-tag-content-color-hover", - "--mod-tag-content-color-invalid", - "--mod-tag-content-color-invalid-active", - "--mod-tag-content-color-invalid-focus", - "--mod-tag-content-color-invalid-hover", - "--mod-tag-content-color-invalid-selected", "--mod-tag-content-color-selected", "--mod-tag-corner-radius", + "--mod-tag-edge-to-clear-icon", "--mod-tag-focus-ring-color", "--mod-tag-focus-ring-gap", "--mod-tag-focus-ring-thickness", @@ -107,73 +70,45 @@ "--mod-tag-icon-size", "--mod-tag-icon-spacing-block-end", "--mod-tag-icon-spacing-block-start", - "--mod-tag-icon-spacing-inline-end", + "--mod-tag-label-font-family", + "--mod-tag-label-font-style", "--mod-tag-label-font-weight", "--mod-tag-label-line-height", + "--mod-tag-label-line-height-cjk", "--mod-tag-label-spacing-block", - "--mod-tag-label-spacing-inline-end", - "--mod-tag-spacing-inline-start" + "--mod-tag-label-spacing-inline", + "--mod-tag-label-to-clear-icon", + "--mod-tag-maximum-width-multiplier", + "--mod-tag-min-inline-size", + "--mod-tag-thumbnail-size", + "--mod-tag-visual-spacing-inline-end", + "--mod-tag-visual-spacing-inline-start" ], "component": [ "--spectrum-tag-animation-duration", + "--spectrum-tag-avatar-size", "--spectrum-tag-avatar-spacing-block-end", "--spectrum-tag-avatar-spacing-block-start", - "--spectrum-tag-avatar-spacing-inline-end", "--spectrum-tag-background-color", "--spectrum-tag-background-color-active", - "--spectrum-tag-background-color-disabled", - "--spectrum-tag-background-color-emphasized", - "--spectrum-tag-background-color-emphasized-active", - "--spectrum-tag-background-color-emphasized-focus", - "--spectrum-tag-background-color-emphasized-hover", "--spectrum-tag-background-color-focus", "--spectrum-tag-background-color-hover", - "--spectrum-tag-background-color-invalid-selected", - "--spectrum-tag-background-color-invalid-selected-active", - "--spectrum-tag-background-color-invalid-selected-focus", - "--spectrum-tag-background-color-invalid-selected-hover", - "--spectrum-tag-background-color-selected", - "--spectrum-tag-background-color-selected-active", - "--spectrum-tag-background-color-selected-focus", - "--spectrum-tag-background-color-selected-hover", "--spectrum-tag-border-color", "--spectrum-tag-border-color-active", - "--spectrum-tag-border-color-disabled", - "--spectrum-tag-border-color-emphasized", - "--spectrum-tag-border-color-emphasized-active", - "--spectrum-tag-border-color-emphasized-focus", - "--spectrum-tag-border-color-emphasized-hover", "--spectrum-tag-border-color-focus", "--spectrum-tag-border-color-hover", - "--spectrum-tag-border-color-invalid", - "--spectrum-tag-border-color-invalid-active", - "--spectrum-tag-border-color-invalid-focus", - "--spectrum-tag-border-color-invalid-hover", - "--spectrum-tag-border-color-invalid-selected", - "--spectrum-tag-border-color-invalid-selected-active", - "--spectrum-tag-border-color-invalid-selected-focus", - "--spectrum-tag-border-color-invalid-selected-hover", - "--spectrum-tag-border-color-selected", - "--spectrum-tag-border-color-selected-active", - "--spectrum-tag-border-color-selected-focus", - "--spectrum-tag-border-color-selected-hover", "--spectrum-tag-border-width", + "--spectrum-tag-clear-button-size", "--spectrum-tag-clear-button-spacing-block", - "--spectrum-tag-clear-button-spacing-inline-end", - "--spectrum-tag-clear-button-spacing-inline-start", "--spectrum-tag-content-color", "--spectrum-tag-content-color-active", - "--spectrum-tag-content-color-disabled", - "--spectrum-tag-content-color-emphasized", "--spectrum-tag-content-color-focus", "--spectrum-tag-content-color-hover", - "--spectrum-tag-content-color-invalid", - "--spectrum-tag-content-color-invalid-active", - "--spectrum-tag-content-color-invalid-focus", - "--spectrum-tag-content-color-invalid-hover", - "--spectrum-tag-content-color-invalid-selected", - "--spectrum-tag-content-color-selected", "--spectrum-tag-corner-radius", + "--spectrum-tag-edge-to-clear-icon", + "--spectrum-tag-edge-to-clear-icon-large", + "--spectrum-tag-edge-to-clear-icon-medium", + "--spectrum-tag-edge-to-clear-icon-small", "--spectrum-tag-focus-ring-color", "--spectrum-tag-focus-ring-gap", "--spectrum-tag-focus-ring-thickness", @@ -182,30 +117,31 @@ "--spectrum-tag-icon-size", "--spectrum-tag-icon-spacing-block-end", "--spectrum-tag-icon-spacing-block-start", - "--spectrum-tag-icon-spacing-inline-end", + "--spectrum-tag-label-font-family", + "--spectrum-tag-label-font-style", "--spectrum-tag-label-font-weight", "--spectrum-tag-label-line-height", + "--spectrum-tag-label-line-height-cjk", "--spectrum-tag-label-spacing-block", - "--spectrum-tag-label-spacing-inline-end", - "--spectrum-tag-size-large-clear-button-spacing-inline-end", - "--spectrum-tag-size-large-corner-radius", - "--spectrum-tag-size-large-label-spacing-inline-end", - "--spectrum-tag-size-large-spacing-inline-start", - "--spectrum-tag-size-medium-clear-button-spacing-inline-end", - "--spectrum-tag-size-medium-corner-radius", - "--spectrum-tag-size-medium-label-spacing-inline-end", - "--spectrum-tag-size-medium-spacing-inline-start", - "--spectrum-tag-size-small-clear-button-spacing-inline-end", - "--spectrum-tag-size-small-corner-radius", - "--spectrum-tag-size-small-label-spacing-inline-end", - "--spectrum-tag-size-small-spacing-inline-start", - "--spectrum-tag-spacing-inline-start", + "--spectrum-tag-label-spacing-inline", + "--spectrum-tag-label-to-clear-icon", + "--spectrum-tag-label-to-clear-icon-large", + "--spectrum-tag-label-to-clear-icon-medium", + "--spectrum-tag-label-to-clear-icon-small", + "--spectrum-tag-maximum-width-multiplier", + "--spectrum-tag-min-inline-size", + "--spectrum-tag-minimum-width-large", + "--spectrum-tag-minimum-width-medium", + "--spectrum-tag-minimum-width-small", + "--spectrum-tag-thumbnail-size", "--spectrum-tag-top-to-avatar-large", "--spectrum-tag-top-to-avatar-medium", "--spectrum-tag-top-to-avatar-small", "--spectrum-tag-top-to-cross-icon-large", "--spectrum-tag-top-to-cross-icon-medium", - "--spectrum-tag-top-to-cross-icon-small" + "--spectrum-tag-top-to-cross-icon-small", + "--spectrum-tag-visual-spacing-inline-end", + "--spectrum-tag-visual-spacing-inline-start" ], "global": [ "--spectrum-accent-background-color-default", @@ -214,20 +150,39 @@ "--spectrum-accent-background-color-key-focus", "--spectrum-animation-duration-100", "--spectrum-avatar-opacity-disabled", + "--spectrum-avatar-size-100", + "--spectrum-avatar-size-50", + "--spectrum-avatar-size-75", "--spectrum-border-width-100", - "--spectrum-clearbutton-fill-background-color", - "--spectrum-clearbutton-fill-size", + "--spectrum-cjk-line-height-100", + "--spectrum-component-edge-to-text-100", + "--spectrum-component-edge-to-text-200", + "--spectrum-component-edge-to-text-75", + "--spectrum-component-edge-to-visual-100", + "--spectrum-component-edge-to-visual-200", + "--spectrum-component-edge-to-visual-75", "--spectrum-component-height-100", "--spectrum-component-height-200", "--spectrum-component-height-75", + "--spectrum-component-size-difference-down", + "--spectrum-component-size-width-ratio-down", "--spectrum-component-top-to-text-100", "--spectrum-component-top-to-text-200", "--spectrum-component-top-to-text-75", "--spectrum-component-top-to-workflow-icon-100", "--spectrum-component-top-to-workflow-icon-200", "--spectrum-component-top-to-workflow-icon-75", - "--spectrum-corner-radius-100", + "--spectrum-corner-radius-medium-size-large", + "--spectrum-corner-radius-medium-size-medium", + "--spectrum-corner-radius-medium-size-small", + "--spectrum-cross-icon-size-100", + "--spectrum-cross-icon-size-200", + "--spectrum-cross-icon-size-75", + "--spectrum-default-font-style", + "--spectrum-disabled-background-color", "--spectrum-disabled-content-color", + "--spectrum-downstate-height", + "--spectrum-downstate-width", "--spectrum-focus-indicator-color", "--spectrum-focus-indicator-gap", "--spectrum-focus-indicator-thickness", @@ -235,45 +190,44 @@ "--spectrum-font-size-200", "--spectrum-font-size-75", "--spectrum-gray-100", + "--spectrum-gray-200", "--spectrum-gray-25", - "--spectrum-gray-50", - "--spectrum-gray-700", - "--spectrum-gray-800", - "--spectrum-gray-900", "--spectrum-line-height-100", - "--spectrum-negative-background-color-default", - "--spectrum-negative-background-color-down", - "--spectrum-negative-background-color-hover", - "--spectrum-negative-background-color-key-focus", - "--spectrum-negative-color-1000", - "--spectrum-negative-color-1100", - "--spectrum-negative-color-900", - "--spectrum-negative-content-color-default", - "--spectrum-negative-content-color-down", - "--spectrum-negative-content-color-hover", - "--spectrum-negative-content-color-key-focus", - "--spectrum-neutral-background-color-selected-default", - "--spectrum-neutral-background-color-selected-down", - "--spectrum-neutral-background-color-selected-hover", - "--spectrum-neutral-background-color-selected-key-focus", - "--spectrum-neutral-subdued-content-color-default", - "--spectrum-neutral-subdued-content-color-down", - "--spectrum-neutral-subdued-content-color-hover", - "--spectrum-neutral-subdued-content-color-key-focus", - "--spectrum-regular-font-weight", + "--spectrum-medium-font-weight", + "--spectrum-neutral-background-color-default", + "--spectrum-neutral-background-color-down", + "--spectrum-neutral-background-color-hover", + "--spectrum-neutral-background-color-key-focus", + "--spectrum-neutral-content-color-default", + "--spectrum-neutral-content-color-down", + "--spectrum-neutral-content-color-hover", + "--spectrum-neutral-content-color-key-focus", + "--spectrum-sans-font-family-stack", "--spectrum-text-to-visual-100", "--spectrum-text-to-visual-200", "--spectrum-text-to-visual-75", + "--spectrum-thumbnail-opacity-disabled", + "--spectrum-thumbnail-size-100", + "--spectrum-thumbnail-size-50", + "--spectrum-thumbnail-size-75", "--spectrum-white", "--spectrum-workflow-icon-size-100", "--spectrum-workflow-icon-size-200", "--spectrum-workflow-icon-size-75" ], "passthroughs": [ + "--mod-avatar-block-size", + "--mod-avatar-inline-size", "--mod-avatar-opacity-disabled", + "--mod-clear-button-background-color", + "--mod-clear-button-height", + "--mod-clear-button-icon-color", + "--mod-clear-button-icon-color-hover", + "--mod-clear-button-icon-color-key-focus", "--mod-clear-button-width", - "--mod-clearbutton-fill-background-color", - "--mod-clearbutton-fill-size" + "--mod-icon-size", + "--mod-thumbnail-opacity-disabled", + "--mod-thumbnail-size" ], "high-contrast": [ "--highcontrast-tag-background-color", @@ -285,10 +239,6 @@ "--highcontrast-tag-background-color-emphasized-hover", "--highcontrast-tag-background-color-focus", "--highcontrast-tag-background-color-hover", - "--highcontrast-tag-background-color-invalid-selected", - "--highcontrast-tag-background-color-invalid-selected-active", - "--highcontrast-tag-background-color-invalid-selected-focus", - "--highcontrast-tag-background-color-invalid-selected-hover", "--highcontrast-tag-background-color-selected", "--highcontrast-tag-background-color-selected-active", "--highcontrast-tag-background-color-selected-focus", @@ -297,34 +247,15 @@ "--highcontrast-tag-border-color-active", "--highcontrast-tag-border-color-disabled", "--highcontrast-tag-border-color-emphasized", - "--highcontrast-tag-border-color-emphasized-active", - "--highcontrast-tag-border-color-emphasized-focus", - "--highcontrast-tag-border-color-emphasized-hover", "--highcontrast-tag-border-color-focus", "--highcontrast-tag-border-color-hover", - "--highcontrast-tag-border-color-invalid", - "--highcontrast-tag-border-color-invalid-active", - "--highcontrast-tag-border-color-invalid-focus", - "--highcontrast-tag-border-color-invalid-hover", - "--highcontrast-tag-border-color-invalid-selected", - "--highcontrast-tag-border-color-invalid-selected-active", - "--highcontrast-tag-border-color-invalid-selected-focus", - "--highcontrast-tag-border-color-invalid-selected-hover", "--highcontrast-tag-border-color-selected", - "--highcontrast-tag-border-color-selected-active", - "--highcontrast-tag-border-color-selected-focus", - "--highcontrast-tag-border-color-selected-hover", "--highcontrast-tag-content-color", "--highcontrast-tag-content-color-active", "--highcontrast-tag-content-color-disabled", "--highcontrast-tag-content-color-emphasized", "--highcontrast-tag-content-color-focus", "--highcontrast-tag-content-color-hover", - "--highcontrast-tag-content-color-invalid", - "--highcontrast-tag-content-color-invalid-active", - "--highcontrast-tag-content-color-invalid-focus", - "--highcontrast-tag-content-color-invalid-hover", - "--highcontrast-tag-content-color-invalid-selected", "--highcontrast-tag-content-color-selected", "--highcontrast-tag-focus-ring-color" ] diff --git a/components/tag/index.css b/components/tag/index.css index 285a9cabeea..1a35a10b3f4 100644 --- a/components/tag/index.css +++ b/components/tag/index.css @@ -1,5 +1,5 @@ /*! - * Copyright 2024 Adobe. All rights reserved. + * Copyright 2025 Adobe. All rights reserved. * * This file is licensed to you under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. You may obtain a copy @@ -12,195 +12,216 @@ */ .spectrum-Tag { - /* TODO - replace placeholder disabled avatar opacity with correct token once avatar is migrated */ - --spectrum-avatar-opacity-disabled: 0.3; - --spectrum-tag-animation-duration: var(--spectrum-animation-duration-100); + + /* border color - transparent unless modified or high contrast mode */ --spectrum-tag-border-width: var(--spectrum-border-width-100); + --spectrum-tag-border-color: var(--highcontrast-tag-border-color, var(--mod-tag-border-color, transparent)); + --spectrum-tag-border-color-hover: var(--highcontrast-tag-border-color-hover, var(--mod-tag-border-color-hover, transparent)); + --spectrum-tag-border-color-active: var(--highcontrast-tag-border-color-active, var(--mod-tag-border-color-active, transparent)); + --spectrum-tag-border-color-focus: var(--highcontrast-tag-border-color-focus, var(--mod-tag-border-color-focus, transparent)); /* background color */ - --spectrum-tag-background-color: var(--spectrum-gray-50); - --spectrum-tag-background-color-hover: var(--spectrum-gray-50); - --spectrum-tag-background-color-active: var(--spectrum-gray-100); - --spectrum-tag-background-color-focus: var(--spectrum-gray-50); - - /* border radius */ - --spectrum-tag-size-small-corner-radius: var(--spectrum-corner-radius-100); - --spectrum-tag-size-medium-corner-radius: var(--spectrum-corner-radius-100); - --spectrum-tag-size-large-corner-radius: var(--spectrum-corner-radius-100); - - /* border color */ - --spectrum-tag-border-color: var(--spectrum-gray-700); - --spectrum-tag-border-color-hover: var(--spectrum-gray-800); - --spectrum-tag-border-color-active: var(--spectrum-gray-900); - --spectrum-tag-border-color-focus: var(--spectrum-gray-800); + --spectrum-tag-background-color: var(--highcontrast-tag-background-color, var(--mod-tag-background-color, var(--spectrum-gray-100))); + --spectrum-tag-background-color-hover: var(--highcontrast-tag-background-color-hover, var(--mod-tag-background-color-hover, var(--spectrum-gray-200))); + --spectrum-tag-background-color-active: var(--highcontrast-tag-background-color-active, var(--mod-tag-background-color-active, var(--spectrum-gray-200))); + --spectrum-tag-background-color-focus: var(--highcontrast-tag-background-color-focus, var(--mod-tag-background-color-focus, var(--spectrum-gray-200))); /* content color */ - --spectrum-tag-content-color: var(--spectrum-neutral-subdued-content-color-default); - --spectrum-tag-content-color-hover: var(--spectrum-neutral-subdued-content-color-hover); - --spectrum-tag-content-color-active: var(--spectrum-neutral-subdued-content-color-down); - --spectrum-tag-content-color-focus: var(--spectrum-neutral-subdued-content-color-key-focus); - --spectrum-tag-content-color-selected: var(--spectrum-gray-25); + --spectrum-tag-content-color: var(--highcontrast-tag-content-color, var(--mod-tag-content-color, var(--spectrum-neutral-content-color-default))); + --spectrum-tag-content-color-hover: var(--highcontrast-tag-content-color-hover, var(--mod-tag-content-color-hover, var(--spectrum-neutral-content-color-hover))); + --spectrum-tag-content-color-active: var(--highcontrast-tag-content-color-active, var(--mod-tag-content-color-active, var(--spectrum-neutral-content-color-down))); + --spectrum-tag-content-color-focus: var(--highcontrast-tag-content-color-focus, var(--mod-tag-content-color-focus, var(--spectrum-neutral-content-color-key-focus))); /* focus ring */ --spectrum-tag-focus-ring-thickness: var(--spectrum-focus-indicator-thickness); --spectrum-tag-focus-ring-gap: var(--spectrum-focus-indicator-gap); - --spectrum-tag-focus-ring-color: var(--spectrum-focus-indicator-color); + --spectrum-tag-focus-ring-color: var(--highcontrast-tag-focus-ring-color, var(--mod-tag-focus-ring-color, var(--spectrum-focus-indicator-color))); /* label */ --spectrum-tag-label-line-height: var(--spectrum-line-height-100); - --spectrum-tag-label-font-weight: var(--spectrum-regular-font-weight); - - --spectrum-tag-background-color-selected: var(--spectrum-neutral-background-color-selected-default); - --spectrum-tag-background-color-selected-hover: var(--spectrum-neutral-background-color-selected-hover); - --spectrum-tag-background-color-selected-active: var(--spectrum-neutral-background-color-selected-down); - --spectrum-tag-background-color-selected-focus: var(--spectrum-neutral-background-color-selected-key-focus); - - /* invalid variant */ - --spectrum-tag-border-color-invalid: var(--spectrum-negative-color-900); - --spectrum-tag-border-color-invalid-hover: var(--spectrum-negative-color-1000); - --spectrum-tag-border-color-invalid-active: var(--spectrum-negative-color-1100); - --spectrum-tag-border-color-invalid-focus: var(--spectrum-negative-color-1000); - - /* invalid variant content */ - --spectrum-tag-content-color-invalid: var(--spectrum-negative-content-color-default); - --spectrum-tag-content-color-invalid-hover: var(--spectrum-negative-content-color-hover); - --spectrum-tag-content-color-invalid-active: var(--spectrum-negative-content-color-down); - --spectrum-tag-content-color-invalid-focus: var(--spectrum-negative-content-color-key-focus); - - /* invalid selected variant */ - --spectrum-tag-border-color-invalid-selected: var(--spectrum-negative-background-color-default); - --spectrum-tag-border-color-invalid-selected-hover: var(--spectrum-negative-background-color-hover); - --spectrum-tag-border-color-invalid-selected-focus: var(--spectrum-negative-background-color-down); - --spectrum-tag-border-color-invalid-selected-active: var(--spectrum-negative-background-color-key-focus); - --spectrum-tag-background-color-invalid-selected: var(--spectrum-negative-background-color-default); - --spectrum-tag-background-color-invalid-selected-hover: var(--spectrum-negative-background-color-hover); - --spectrum-tag-background-color-invalid-selected-active: var(--spectrum-negative-background-color-down); - --spectrum-tag-background-color-invalid-selected-focus: var(--spectrum-negative-background-color-key-focus); - - /* invalid selected variant content */ - --spectrum-tag-content-color-invalid-selected: var(--spectrum-white); - - /* emphasized variant */ - --spectrum-tag-border-color-emphasized: var(--spectrum-accent-background-color-default); - --spectrum-tag-border-color-emphasized-hover: var(--spectrum-accent-background-color-hover); - --spectrum-tag-border-color-emphasized-active: var(--spectrum-accent-background-color-down); - --spectrum-tag-border-color-emphasized-focus: var(--spectrum-accent-background-color-key-focus); - --spectrum-tag-background-color-emphasized: var(--spectrum-accent-background-color-default); - --spectrum-tag-background-color-emphasized-hover: var(--spectrum-accent-background-color-hover); - --spectrum-tag-background-color-emphasized-active: var(--spectrum-accent-background-color-down); - --spectrum-tag-background-color-emphasized-focus: var(--spectrum-accent-background-color-key-focus); - - /* emphasized variant content */ - --spectrum-tag-content-color-emphasized: var(--spectrum-white); - - /* disabled variant content */ - --spectrum-tag-content-color-disabled: var(--spectrum-disabled-content-color); -} - -.spectrum-Tag, -.spectrum-Tag--sizeM { - --spectrum-tag-height: var(--spectrum-component-height-100); - --spectrum-tag-font-size: var(--spectrum-font-size-100); - --spectrum-tag-icon-size: var(--spectrum-workflow-icon-size-100); - - --spectrum-tag-clear-button-spacing-inline-start: var(--spectrum-text-to-visual-100); - --spectrum-tag-clear-button-spacing-block: var(--spectrum-tag-top-to-cross-icon-medium); + --spectrum-tag-label-line-height-cjk: var(--spectrum-cjk-line-height-100); + --spectrum-tag-label-font-family: var(--spectrum-sans-font-family-stack); + --spectrum-tag-label-font-style: var(--spectrum-default-font-style); + --spectrum-tag-label-font-weight: var(--spectrum-medium-font-weight); - --spectrum-tag-icon-spacing-block-start: var(--spectrum-component-top-to-workflow-icon-100); - --spectrum-tag-icon-spacing-block-end: var(--spectrum-component-top-to-workflow-icon-100); - --spectrum-tag-icon-spacing-inline-end: var(--spectrum-text-to-visual-100); - - --spectrum-tag-avatar-spacing-block-start: var(--spectrum-tag-top-to-avatar-medium); /* 6px 9px */ - --spectrum-tag-avatar-spacing-block-end: var(--spectrum-tag-top-to-avatar-medium); - --spectrum-tag-avatar-spacing-inline-end: var(--spectrum-text-to-visual-100); - - --spectrum-tag-label-spacing-block: var(--spectrum-component-top-to-text-100); - - /* tokens based on theme and t-shirt size */ - --spectrum-tag-corner-radius: var(--spectrum-tag-size-medium-corner-radius); - --spectrum-tag-spacing-inline-start: var(--spectrum-tag-size-medium-spacing-inline-start); - --spectrum-tag-label-spacing-inline-end: var(--spectrum-tag-size-medium-label-spacing-inline-end); - --spectrum-tag-clear-button-spacing-inline-end: var(--spectrum-tag-size-medium-clear-button-spacing-inline-end); -} - -/* t-shirt sizes */ -.spectrum-Tag--sizeS { + /* default size/sizeS */ --spectrum-tag-height: var(--spectrum-component-height-75); + --spectrum-tag-min-inline-size: var(--spectrum-tag-minimum-width-small); --spectrum-tag-font-size: var(--spectrum-font-size-75); --spectrum-tag-icon-size: var(--spectrum-workflow-icon-size-75); + --spectrum-tag-corner-radius: var(--spectrum-corner-radius-medium-size-small); - --spectrum-tag-clear-button-spacing-inline-start: var(--spectrum-text-to-visual-75); + --spectrum-tag-clear-button-size: var(--spectrum-cross-icon-size-75); --spectrum-tag-clear-button-spacing-block: var(--spectrum-tag-top-to-cross-icon-small); + --spectrum-tag-label-to-clear-icon: var(--spectrum-tag-label-to-clear-icon-small); + --spectrum-tag-edge-to-clear-icon: var(--spectrum-tag-edge-to-clear-icon-small); + + --spectrum-tag-visual-spacing-inline-start: var(--spectrum-component-edge-to-visual-75); + --spectrum-tag-visual-spacing-inline-end: var(--spectrum-text-to-visual-75); --spectrum-tag-icon-spacing-block-start: var(--spectrum-component-top-to-workflow-icon-75); --spectrum-tag-icon-spacing-block-end: var(--spectrum-component-top-to-workflow-icon-75); - --spectrum-tag-icon-spacing-inline-end: var(--spectrum-text-to-visual-75); + --spectrum-tag-avatar-size: var(--spectrum-avatar-size-50); --spectrum-tag-avatar-spacing-block-start: var(--spectrum-tag-top-to-avatar-small); --spectrum-tag-avatar-spacing-block-end: var(--spectrum-tag-top-to-avatar-small); - --spectrum-tag-avatar-spacing-inline-end: var(--spectrum-text-to-visual-75); + + --spectrum-tag-thumbnail-size: var(--spectrum-thumbnail-size-50); --spectrum-tag-label-spacing-block: var(--spectrum-component-top-to-text-75); + --spectrum-tag-label-spacing-inline: var(--spectrum-component-edge-to-text-75); + + /* @passthrough start for nested components */ + --mod-avatar-inline-size: var(--mod-tag-avatar-size, var(--spectrum-tag-avatar-size)); + --mod-avatar-block-size: var(--mod-tag-avatar-size, var(--spectrum-tag-avatar-size)); + --mod-thumbnail-size: var(--mod-tag-thumbnail-size, var(--spectrum-tag-thumbnail-size)); + --mod-clear-button-background-color: transparent; + --mod-clear-button-icon-color: currentColor; + --mod-clear-button-icon-color-hover: currentColor; + --mod-clear-button-icon-color-key-focus: currentColor; + + --mod-icon-size: var(--mod-tag-clear-button-size, var(--spectrum-tag-clear-button-size)); + + /* clear icon inline spacing + icon size */ + --mod-clear-button-width: calc(var(--mod-tag-label-to-clear-icon, var(--spectrum-tag-label-to-clear-icon)) + var(--mod-tag-edge-to-clear-icon, var(--spectrum-tag-edge-to-clear-icon)) + var(--mod-tag-clear-button-size, var(--spectrum-tag-clear-button-size))); + + /* clear icon block spacing + icon size */ + --mod-clear-button-height: calc(2 * var(--mod-tag-clear-button-spacing-block, var(--spectrum-tag-clear-button-spacing-block)) + var(--mod-tag-clear-button-size, var(--spectrum-tag-clear-button-size))); + /* @passthrough end */ + + &:lang(ja), + &:lang(zh), + &:lang(ko) { + --mod-tag-label-line-height: var(--mod-tag-label-line-height-cjk, var(--spectrum-tag-label-line-height-cjk)); + } + + &.is-selected:not(.is-disabled, .is-readOnly) { + --spectrum-tag-border-color: var(--highcontrast-tag-border-color-selected, var(--mod-tag-border-color-selected, transparent)); + --spectrum-tag-background-color: var(--highcontrast-tag-background-color-selected, var(--mod-tag-background-color-selected, var(--spectrum-neutral-background-color-default))); + --spectrum-tag-content-color: var(--highcontrast-tag-content-color-selected, var(--mod-tag-content-color-selected, var(--spectrum-gray-25))); + + --spectrum-tag-border-color-hover: var(--highcontrast-tag-border-color-selected, var(--mod-tag-border-color-selected, transparent)); + --spectrum-tag-background-color-hover: var(--highcontrast-tag-background-color-selected-hover, var(--mod-tag-background-color-selected-hover, var(--spectrum-neutral-background-color-hover))); + --spectrum-tag-content-color-hover: var(--highcontrast-tag-content-color-selected, var(--mod-tag-content-color-selected, var(--spectrum-gray-25))); + + --spectrum-tag-border-color-active: var(--highcontrast-tag-border-color-selected, var(--mod-tag-border-color-selected, transparent)); + --spectrum-tag-background-color-active: var(--highcontrast-tag-background-color-selected-active, var(--mod-tag-background-color-selected-active, var(--spectrum-neutral-background-color-down))); + --spectrum-tag-content-color-active: var(--highcontrast-tag-content-color-selected, var(--mod-tag-content-color-selected, var(--spectrum-gray-25))); + + --spectrum-tag-border-color-focus: var(--highcontrast-tag-border-color-selected, var(--mod-tag-border-color-selected, transparent)); + --spectrum-tag-background-color-focus: var(--highcontrast-tag-background-color-selected-focus, var(--mod-tag-background-color-selected-focus, var(--spectrum-neutral-background-color-key-focus))); + --spectrum-tag-content-color-focus: var(--highcontrast-tag-content-color-selected, var(--mod-tag-content-color-selected, var(--spectrum-gray-25))); + } - /* tokens based on theme and t-shirt size */ - --spectrum-tag-corner-radius: var(--spectrum-tag-size-small-corner-radius); - --spectrum-tag-spacing-inline-start: var(--spectrum-tag-size-small-spacing-inline-start); - --spectrum-tag-label-spacing-inline-end: var(--spectrum-tag-size-small-label-spacing-inline-end); - --spectrum-tag-clear-button-spacing-inline-end: var(--spectrum-tag-size-small-clear-button-spacing-inline-end); + &.spectrum-Tag--emphasized.is-selected:not(.is-disabled, .is-readOnly) { + --spectrum-tag-border-color: var(--highcontrast-tag-border-color-emphasized, var(--mod-tag-border-color-emphasized, transparent)); + --spectrum-tag-background-color: var(--highcontrast-tag-background-color-emphasized, var(--mod-tag-background-color-emphasized, var(--spectrum-accent-background-color-default))); + --spectrum-tag-content-color: var(--highcontrast-tag-content-color-emphasized, var(--mod-tag-content-color-emphasized, var(--spectrum-white))); + + --spectrum-tag-border-color-hover: var(--highcontrast-tag-border-color-emphasized, var(--mod-tag-border-color-emphasized, transparent)); + --spectrum-tag-background-color-hover: var(--highcontrast-tag-background-color-emphasized-hover, var(--mod-tag-background-color-emphasized-hover, var(--spectrum-accent-background-color-hover))); + --spectrum-tag-content-color-hover: var(--highcontrast-tag-content-color-emphasized, var(--mod-tag-content-color-emphasized, var(--spectrum-white))); + + --spectrum-tag-border-color-active: var(--highcontrast-tag-border-color-emphasized, var(--mod-tag-border-color-emphasized, transparent)); + --spectrum-tag-background-color-active: var(--highcontrast-tag-background-color-emphasized-active, var(--mod-tag-background-color-emphasized-active, var(--spectrum-accent-background-color-down))); + --spectrum-tag-content-color-active: var(--highcontrast-tag-content-color-emphasized, var(--mod-tag-content-color-emphasized, var(--spectrum-white))); + + --spectrum-tag-border-color-focus: var(--highcontrast-tag-border-color-emphasized, var(--mod-tag-border-color-emphasized, transparent)); + --spectrum-tag-background-color-focus: var(--highcontrast-tag-background-color-emphasized-focus, var(--mod-tag-background-color-emphasized-focus, var(--spectrum-accent-background-color-key-focus))); + --spectrum-tag-content-color-focus: var(--highcontrast-tag-content-color-emphasized, var(--mod-tag-content-color-emphasized, var(--spectrum-white))); + } + + &.spectrum-Tag.is-disabled { + --spectrum-tag-border-color: var(--highcontrast-tag-border-color-disabled, var(--mod-tag-border-color-disabled, transparent)); + --spectrum-tag-background-color: var(--highcontrast-tag-background-color-disabled, var(--mod-tag-background-color-disabled, var(--spectrum-disabled-background-color))); + --spectrum-tag-content-color: var(--highcontrast-tag-content-color-disabled, var(--mod-tag-content-color-disabled, var(--spectrum-disabled-content-color))); + } +} + +/* t-shirt sizes - small is default */ +.spectrum-Tag--sizeM { + --spectrum-tag-height: var(--spectrum-component-height-100); + --spectrum-tag-min-inline-size: var(--spectrum-tag-minimum-width-medium); + --spectrum-tag-font-size: var(--spectrum-font-size-100); + --spectrum-tag-icon-size: var(--spectrum-workflow-icon-size-100); + --spectrum-tag-corner-radius: var(--spectrum-corner-radius-medium-size-medium); + + --spectrum-tag-clear-button-size: var(--spectrum-cross-icon-size-100); + --spectrum-tag-clear-button-spacing-block: var(--spectrum-tag-top-to-cross-icon-medium); + --spectrum-tag-label-to-clear-icon: var(--spectrum-tag-label-to-clear-icon-medium); + --spectrum-tag-edge-to-clear-icon: var(--spectrum-tag-edge-to-clear-icon-medium); + + --spectrum-tag-visual-spacing-inline-start: var(--spectrum-component-edge-to-visual-100); + --spectrum-tag-visual-spacing-inline-end: var(--spectrum-text-to-visual-100); + + --spectrum-tag-icon-spacing-block-start: var(--spectrum-component-top-to-workflow-icon-100); + --spectrum-tag-icon-spacing-block-end: var(--spectrum-component-top-to-workflow-icon-100); + + --spectrum-tag-avatar-size: var(--spectrum-avatar-size-75); + --spectrum-tag-avatar-spacing-block-start: var(--spectrum-tag-top-to-avatar-medium); + --spectrum-tag-avatar-spacing-block-end: var(--spectrum-tag-top-to-avatar-medium); + + --spectrum-tag-thumbnail-size: var(--spectrum-thumbnail-size-75); + + --spectrum-tag-label-spacing-block: var(--spectrum-component-top-to-text-100); + --spectrum-tag-label-spacing-inline: var(--spectrum-component-edge-to-text-100); } .spectrum-Tag--sizeL { --spectrum-tag-height: var(--spectrum-component-height-200); + --spectrum-tag-min-inline-size: var(--spectrum-tag-minimum-width-large); --spectrum-tag-font-size: var(--spectrum-font-size-200); --spectrum-tag-icon-size: var(--spectrum-workflow-icon-size-200); + --spectrum-tag-corner-radius: var(--spectrum-corner-radius-medium-size-large); - --spectrum-tag-clear-button-spacing-inline-start: var(--spectrum-text-to-visual-200); + --spectrum-tag-clear-button-size: var(--spectrum-cross-icon-size-200); --spectrum-tag-clear-button-spacing-block: var(--spectrum-tag-top-to-cross-icon-large); + --spectrum-tag-label-to-clear-icon: var(--spectrum-tag-label-to-clear-icon-large); + --spectrum-tag-edge-to-clear-icon: var(--spectrum-tag-edge-to-clear-icon-large); + + --spectrum-tag-visual-spacing-inline-start: var(--spectrum-component-edge-to-visual-200); + --spectrum-tag-visual-spacing-inline-end: var(--spectrum-text-to-visual-200); --spectrum-tag-icon-spacing-block-start: var(--spectrum-component-top-to-workflow-icon-200); --spectrum-tag-icon-spacing-block-end: var(--spectrum-component-top-to-workflow-icon-200); - --spectrum-tag-icon-spacing-inline-end: var(--spectrum-text-to-visual-200); + --spectrum-tag-avatar-size: var(--spectrum-avatar-size-100); --spectrum-tag-avatar-spacing-block-start: var(--spectrum-tag-top-to-avatar-large); --spectrum-tag-avatar-spacing-block-end: var(--spectrum-tag-top-to-avatar-large); - --spectrum-tag-avatar-spacing-inline-end: var(--spectrum-text-to-visual-200); - --spectrum-tag-label-spacing-block: var(--spectrum-component-top-to-text-200); + --spectrum-tag-thumbnail-size: var(--spectrum-thumbnail-size-100); - /* tokens based on theme and t-shirt size */ - --spectrum-tag-corner-radius: var(--spectrum-tag-size-large-corner-radius); - --spectrum-tag-spacing-inline-start: var(--spectrum-tag-size-large-spacing-inline-start); - --spectrum-tag-label-spacing-inline-end: var(--spectrum-tag-size-large-label-spacing-inline-end); - --spectrum-tag-clear-button-spacing-inline-end: var(--spectrum-tag-size-large-clear-button-spacing-inline-end); + --spectrum-tag-label-spacing-block: var(--spectrum-component-top-to-text-200); + --spectrum-tag-label-spacing-inline: var(--spectrum-component-edge-to-text-200); } .spectrum-Tag { - border-color: var(--highcontrast-tag-border-color, var(--mod-tag-border-color, var(--spectrum-tag-border-color))); - background-color: var(--highcontrast-tag-background-color, var(--mod-tag-background-color, var(--spectrum-tag-background-color))); - color: var(--highcontrast-tag-content-color, var(--mod-tag-content-color, var(--spectrum-tag-content-color))); + /* mod/highcontrast colors specified at top */ + border-color: var(--spectrum-tag-border-color); + background-color: var(--spectrum-tag-background-color); + color: var(--spectrum-tag-content-color); border-radius: var(--mod-tag-corner-radius, var(--spectrum-tag-corner-radius)); border-width: var(--mod-tag-border-width, var(--spectrum-tag-border-width)); border-style: solid; - padding-inline-start: calc(var(--mod-tag-spacing-inline-start, var(--spectrum-tag-spacing-inline-start)) - var(--mod-tag-border-width, var(--spectrum-tag-border-width))); + padding-inline-start: calc(var(--mod-tag-label-spacing-inline, var(--spectrum-tag-label-spacing-inline)) - var(--mod-tag-border-width, var(--spectrum-tag-border-width))); padding-inline-end: 0; block-size: var(--mod-tag-height, var(--spectrum-tag-height)); + min-inline-size: var(--mod-tag-min-inline-size, var(--spectrum-tag-min-inline-size)); position: relative; display: inline-flex; align-items: center; box-sizing: border-box; vertical-align: bottom; - max-inline-size: 100%; + max-inline-size: calc(var(--mod-tag-height, var(--spectrum-tag-height)) * var(--mod-tag-maximum-width-multiplier, var(--spectrum-tag-maximum-width-multiplier))); outline: none; - user-select: none; transition: border-color var(--mod-tag-animation-duration, var(--spectrum-tag-animation-duration)) ease-in-out, color var(--mod-tag-animation-duration, var(--spectrum-tag-animation-duration)) ease-in-out, - box-shadow var(--mod-tag-animation-duration, var(--spectrum-tag-animation-duration)) ease-in-out, background-color var(--mod-tag-animation-duration, var(--spectrum-tag-animation-duration)) ease-in-out; .spectrum-Tag-itemIcon { @@ -209,54 +230,50 @@ margin-block-start: calc(var(--mod-tag-icon-spacing-block-start, var(--spectrum-tag-icon-spacing-block-start)) - var(--mod-tag-border-width, var(--spectrum-tag-border-width))); margin-block-end: calc(var(--mod-tag-icon-spacing-block-end, var(--spectrum-tag-icon-spacing-block-end)) - var(--mod-tag-border-width, var(--spectrum-tag-border-width))); - margin-inline-end: var(--mod-tag-icon-spacing-inline-end, var(--spectrum-tag-icon-spacing-inline-end)); flex-shrink: 0; } .spectrum-Avatar { margin-block-start: calc(var(--mod-tag-avatar-spacing-block-start, var(--spectrum-tag-avatar-spacing-block-start)) - var(--mod-tag-border-width, var(--spectrum-tag-border-width))); margin-block-end: calc(var(--mod-tag-avatar-spacing-block-end, var(--spectrum-tag-avatar-spacing-block-end)) - var(--mod-tag-border-width, var(--spectrum-tag-border-width))); - margin-inline-end: var(--mod-tag-avatar-spacing-inline-end, var(--spectrum-tag-avatar-spacing-inline-end)); + } + + .spectrum-Thumbnail { + /* prevent thumbnail shrinking when label is longer */ + flex-shrink: 0; + } + + .spectrum-Tag-itemIcon, + .spectrum-Avatar, + .spectrum-Thumbnail { + /* set visual inline-start spacing, but take away label spacing, this will result in negative margin - this calc does not need border width */ + margin-inline-start: calc(var(--mod-tag-visual-spacing-inline-start, var(--spectrum-tag-visual-spacing-inline-start)) - var(--mod-tag-label-spacing-inline, var(--spectrum-tag-label-spacing-inline))); + margin-inline-end: var(--mod-tag-visual-spacing-inline-end, var(--spectrum-tag-visual-spacing-inline-end)); } /* clear button */ .spectrum-Tag-clearButton { - /* @passthrough start -- width of fill neutralized to ensure correct inline spacing within tag */ - --mod-clear-button-width: fit-content; - --spectrum-clearbutton-fill-size: fit-content; - --spectrum-clearbutton-fill-background-color: transparent; - /* @passthrough end */ - box-sizing: border-box; + flex-shrink: 0; - padding-block-start: calc(var(--mod-tag-clear-button-spacing-block, var(--spectrum-tag-clear-button-spacing-block)) - var(--mod-tag-border-width, var(--spectrum-tag-border-width))); - padding-block-end: calc(var(--mod-tag-clear-button-spacing-block, var(--spectrum-tag-clear-button-spacing-block)) - var(--mod-tag-border-width, var(--spectrum-tag-border-width))); - - /* move button negative calc to cancel label end margin, then add button start margin */ - margin-inline-start: calc(var(--mod-tag-clear-button-spacing-inline-start, var(--spectrum-tag-clear-button-spacing-inline-start)) + (var(--mod-tag-label-spacing-inline-end, var(--spectrum-tag-label-spacing-inline-end)) * -1)); - - /* end spacing is theme-specific */ - margin-inline-end: calc(var(--mod-tag-clear-button-spacing-inline-end, var(--spectrum-tag-clear-button-spacing-inline-end)) - var(--mod-tag-border-width, var(--spectrum-tag-border-width))); - - /* ensure clear button is correct color */ - color: currentColor; - - .spectrum-ClearButton-fill { - background-color: var(--mod-clearbutton-fill-background-color, var(--spectrum-clearbutton-fill-background-color)); + /* remove label inline-end spacing with negative margin */ + margin-inline-start: calc((var(--mod-tag-label-spacing-inline, var(--spectrum-tag-label-spacing-inline)) - var(--mod-tag-border-width, var(--spectrum-tag-border-width))) * -1); - inline-size: var(--mod-clearbutton-fill-size, var(--spectrum-clearbutton-fill-size)); - block-size: var(--mod-clearbutton-fill-size, var(--spectrum-clearbutton-fill-size)); - } + /* remove border width from clear button */ + margin-inline-end: calc(var(--mod-tag-border-width, var(--spectrum-tag-border-width)) * -1); } .spectrum-Tag-itemLabel { block-size: 100%; box-sizing: border-box; + line-height: var(--mod-tag-label-line-height, var(--spectrum-tag-label-line-height)); + font-family: var(--mod-tag-label-font-family, var(--spectrum-tag-label-font-family)); + font-style: var(--mod-tag-label-font-style, var(--spectrum-tag-label-font-style)); font-weight: var(--mod-tag-label-font-weight, var(--spectrum-tag-label-font-weight)); + font-size: var(--mod-tag-font-size, var(--spectrum-tag-font-size)); flex: 1 1 auto; - font-size: var(--mod-tag-font-size, var(--spectrum-tag-font-size)); cursor: default; overflow: hidden; white-space: nowrap; @@ -265,37 +282,39 @@ padding-block-start: calc(var(--mod-tag-label-spacing-block, var(--spectrum-tag-label-spacing-block)) - var(--mod-tag-border-width, var(--spectrum-tag-border-width))); /* space from label text to end edge */ - margin-inline-end: calc(var(--mod-tag-label-spacing-inline-end, var(--spectrum-tag-label-spacing-inline-end)) - var(--mod-tag-border-width, var(--spectrum-tag-border-width))); + margin-inline-end: calc(var(--mod-tag-label-spacing-inline, var(--spectrum-tag-label-spacing-inline)) - var(--mod-tag-border-width, var(--spectrum-tag-border-width))); } - &:hover { - border-color: var(--highcontrast-tag-border-color-hover, var(--mod-tag-border-color-hover, var(--spectrum-tag-border-color-hover))); - background-color: var(--highcontrast-tag-background-color-hover, var(--mod-tag-background-color-hover, var(--spectrum-tag-background-color-hover))); - color: var(--highcontrast-tag-content-color-hover, var(--mod-tag-content-color-hover, var(--spectrum-tag-content-color-hover))); + &:not(.is-disabled, .is-readOnly):hover { + /* mod/highcontrast specified at top */ + border-color: var(--spectrum-tag-border-color-hover); + background-color: var(--spectrum-tag-background-color-hover); + color: var(--spectrum-tag-content-color-hover); } - &:active { - border-color: var(--highcontrast-tag-border-color-active, var(--mod-tag-border-color-active, var(--spectrum-tag-border-color-active))); - background-color: var(--highcontrast-tag-background-color-active, var(--mod-tag-background-color-active, var(--spectrum-tag-background-color-active))); - color: var(--highcontrast-tag-content-color-active, var(--mod-tag-content-color-active, var(--spectrum-tag-content-color-active))); + &:not(.is-disabled, .is-readOnly):active { + /* mod/highcontrast specified at top */ + border-color: var(--spectrum-tag-border-color-active); + background-color: var(--spectrum-tag-background-color-active); + color: var(--spectrum-tag-content-color-active); + + /* stylelint-disable-next-line spectrum-tools/no-unknown-custom-properties -- height and width are set by implementations */ + transform: perspective(max(var(--spectrum-downstate-height), var(--spectrum-downstate-width) * var(--spectrum-component-size-width-ratio-down))) translateZ(var(--spectrum-component-size-difference-down)); } - &:focus-visible, - &.is-focused { - border-color: var(--highcontrast-tag-border-color-focus, var(--mod-tag-border-color-focus, var(--spectrum-tag-border-color-focus))); - background-color: var(--highcontrast-tag-background-color-focus, var(--mod-tag-background-color-focus, var(--spectrum-tag-background-color-focus))); - color: var(--highcontrast-tag-content-color-focus, var(--mod-tag-content-color-focus, var(--spectrum-tag-content-color-focus))); + &:not(.is-disabled, .is-readOnly):focus-visible { + /* mod/highcontrast specified at top */ + border-color: var(--spectrum-tag-border-color-focus); + background-color: var(--spectrum-tag-background-color-focus); + color: var(--spectrum-tag-content-color-focus); /* focus indicator */ &::after { content: ""; display: inline-block; position: absolute; - inset-block-start: calc(-1 * var(--mod-tag-focus-ring-gap, var(--spectrum-tag-focus-ring-gap)) - var(--mod-tag-border-width, var(--spectrum-tag-border-width)) - var(--mod-tag-focus-ring-thickness, var(--spectrum-tag-focus-ring-thickness))); - inset-block-end: calc(-1 * var(--mod-tag-focus-ring-gap, var(--spectrum-tag-focus-ring-gap)) - var(--mod-tag-border-width, var(--spectrum-tag-border-width)) - var(--mod-tag-focus-ring-thickness, var(--spectrum-tag-focus-ring-thickness))); - inset-inline-start: calc(-1 * var(--mod-tag-focus-ring-gap, var(--spectrum-tag-focus-ring-gap)) - var(--mod-tag-border-width, var(--spectrum-tag-border-width)) - var(--mod-tag-focus-ring-thickness, var(--spectrum-tag-focus-ring-thickness))); - inset-inline-end: calc(-1 * var(--mod-tag-focus-ring-gap, var(--spectrum-tag-focus-ring-gap)) - var(--mod-tag-border-width, var(--spectrum-tag-border-width)) - var(--mod-tag-focus-ring-thickness, var(--spectrum-tag-focus-ring-thickness))); - border-color: var(--highcontrast-tag-focus-ring-color, var(--mod-tag-focus-ring-color, var(--spectrum-tag-focus-ring-color))); + inset: calc(-1 * var(--mod-tag-focus-ring-gap, var(--spectrum-tag-focus-ring-gap)) - var(--mod-tag-border-width, var(--spectrum-tag-border-width)) - var(--mod-tag-focus-ring-thickness, var(--spectrum-tag-focus-ring-thickness))); + border-color: var(--spectrum-tag-focus-ring-color); /* mod/highcontrast specified at top */ border-radius: calc(var(--mod-tag-corner-radius, var(--spectrum-tag-corner-radius)) + var(--mod-tag-focus-ring-gap, var(--spectrum-tag-focus-ring-gap)) + var(--mod-tag-border-width, var(--spectrum-tag-border-width))); border-width: var(--mod-tag-focus-ring-thickness, var(--spectrum-tag-focus-ring-thickness)); border-style: solid; @@ -304,108 +323,18 @@ } } -/* selected */ -.spectrum-Tag.is-selected { - border-color: var(--highcontrast-tag-border-color-selected, var(--mod-tag-border-color-selected, var(--spectrum-tag-border-color-selected))); - background-color: var(--highcontrast-tag-background-color-selected, var(--mod-tag-background-color-selected, var(--spectrum-tag-background-color-selected))); - color: var(--highcontrast-tag-content-color-selected, var(--mod-tag-content-color-selected, var(--spectrum-tag-content-color-selected))); - - &:hover { - border-color: var(--highcontrast-tag-border-color-selected-hover, var(--mod-tag-border-color-selected-hover, var(--spectrum-tag-border-color-selected-hover))); - background-color: var(--highcontrast-tag-background-color-selected-hover, var(--mod-tag-background-color-selected-hover, var(--spectrum-tag-background-color-selected-hover))); - color: var(--highcontrast-tag-content-color-selected, var(--mod-tag-content-color-selected, var(--spectrum-tag-content-color-selected))); - } - - &:active { - border-color: var(--highcontrast-tag-border-color-selected-active, var(--mod-tag-border-color-selected-active, var(--spectrum-tag-border-color-selected-active))); - background-color: var(--highcontrast-tag-background-color-selected-active, var(--mod-tag-background-color-selected-active, var(--spectrum-tag-background-color-selected-active))); - } - - &:focus-visible, - &.is-focused { - border-color: var(--highcontrast-tag-border-color-selected-focus, var(--mod-tag-border-color-selected-focus, var(--spectrum-tag-border-color-selected-focus))); - background-color: var(--highcontrast-tag-background-color-selected-focus, var(--mod-tag-background-color-selected-focus, var(--spectrum-tag-background-color-selected-focus))); - } -} - -.spectrum-Tag.is-invalid { - border-color: var(--highcontrast-tag-border-color-invalid, var(--mod-tag-border-color-invalid, var(--spectrum-tag-border-color-invalid))); - color: var(--highcontrast-tag-content-color-invalid, var(--mod-tag-content-color-invalid, var(--spectrum-tag-content-color-invalid))); - - &:hover { - border-color: var(--highcontrast-tag-border-color-invalid-hover, var(--mod-tag-border-color-invalid-hover, var(--spectrum-tag-border-color-invalid-hover))); - color: var(--highcontrast-tag-content-color-invalid-hover, var(--mod-tag-content-color-invalid-hover, var(--spectrum-tag-content-color-invalid-hover))); - } - - &:active { - border-color: var(--highcontrast-tag-border-color-invalid-active, var(--mod-tag-border-color-invalid-active, var(--spectrum-tag-border-color-invalid-active))); - color: var(--highcontrast-tag-content-color-invalid-active, var(--mod-tag-content-color-invalid-active, var(--spectrum-tag-content-color-invalid-active))); - } - - &:focus-visible, - &.is-focused { - border-color: var(--highcontrast-tag-border-color-invalid-focus, var(--mod-tag-border-color-invalid-focus, var(--spectrum-tag-border-color-invalid-focus))); - color: var(--highcontrast-tag-content-color-invalid-focus, var(--mod-tag-content-color-invalid-focus, var(--spectrum-tag-content-color-invalid-focus))); - } - - &.is-selected { - border-color: var(--highcontrast-tag-border-color-invalid-selected, var(--mod-tag-border-color-invalid-selected, var(--spectrum-tag-border-color-invalid-selected))); - background-color: var(--highcontrast-tag-background-color-invalid-selected, var(--mod-tag-background-color-invalid-selected, var(--spectrum-tag-background-color-invalid-selected))); - color: var(--highcontrast-tag-content-color-invalid-selected, var(--mod-tag-content-color-invalid-selected, var(--spectrum-tag-content-color-invalid-selected))); - - &:hover { - border-color: var(--highcontrast-tag-border-color-invalid-selected-hover, var(--mod-tag-border-color-invalid-selected-hover, var(--spectrum-tag-border-color-invalid-selected-hover))); - background-color: var(--highcontrast-tag-background-color-invalid-selected-hover, var(--mod-tag-background-color-invalid-selected-hover, var(--spectrum-tag-background-color-invalid-selected-hover))); - color: var(--highcontrast-tag-content-color-invalid-selected, var(--mod-tag-content-color-invalid-selected, var(--spectrum-tag-content-color-invalid-selected))); - } - - &:active { - border-color: var(--highcontrast-tag-border-color-invalid-selected-active, var(--mod-tag-border-color-invalid-selected-active, var(--spectrum-tag-border-color-invalid-selected-active))); - background-color: var(--highcontrast-tag-background-color-invalid-selected-active, var(--mod-tag-background-color-invalid-selected-active, var(--spectrum-tag-background-color-invalid-selected-active))); - } - - &:focus-visible, - &.is-focused { - border-color: var(--highcontrast-tag-border-color-invalid-selected-focus, var(--mod-tag-border-color-invalid-selected-focus, var(--spectrum-tag-border-color-invalid-selected-focus))); - background-color: var(--highcontrast-tag-background-color-invalid-selected-focus, var(--mod-tag-background-color-invalid-selected-focus, var(--spectrum-tag-background-color-invalid-selected-focus))); - } - } -} - -/* emphasized */ -.spectrum-Tag.is-emphasized { - border-color: var(--highcontrast-tag-border-color-emphasized, var(--mod-tag-border-color-emphasized, var(--spectrum-tag-border-color-emphasized))); - background-color: var(--highcontrast-tag-background-color-emphasized, var(--mod-tag-background-color-emphasized, var(--spectrum-tag-background-color-emphasized))); - color: var(--highcontrast-tag-content-color-emphasized, var(--mod-tag-content-color-emphasized, var(--spectrum-tag-content-color-emphasized))); - - &:hover { - border-color: var(--highcontrast-tag-border-color-emphasized-hover, var(--mod-tag-border-color-emphasized-hover, var(--spectrum-tag-border-color-emphasized-hover))); - background-color: var(--highcontrast-tag-background-color-emphasized-hover, var(--mod-tag-background-color-emphasized-hover, var(--spectrum-tag-background-color-emphasized-hover))); - color: var(--highcontrast-tag-content-color-emphasized, var(--mod-tag-content-color-emphasized, var(--spectrum-tag-content-color-emphasized))); - } - - &:active { - border-color: var(--highcontrast-tag-border-color-emphasized-active, var(--mod-tag-border-color-emphasized-active, var(--spectrum-tag-border-color-emphasized-active))); - background-color: var(--highcontrast-tag-background-color-emphasized-active, var(--mod-tag-background-color-emphasized-active, var(--spectrum-tag-background-color-emphasized-active))); - } - - &:focus-visible, - &.is-focused { - border-color: var(--highcontrast-tag-border-color-emphasized-focus, var(--mod-tag-border-color-emphasized-focus, var(--spectrum-tag-border-color-emphasized-focus))); - background-color: var(--highcontrast-tag-background-color-emphasized-focus, var(--mod-tag-background-color-emphasized-focus, var(--spectrum-tag-background-color-emphasized-focus))); - } -} - /* disabled */ .spectrum-Tag.is-disabled { - border-color: var(--highcontrast-tag-border-color-disabled, var(--mod-tag-border-color-disabled, var(--spectrum-tag-border-color-disabled))); - background-color: var(--highcontrast-tag-background-color-disabled, var(--mod-tag-background-color-disabled, var(--spectrum-tag-background-color-disabled))); - color: var(--highcontrast-tag-content-color-disabled, var(--mod-tag-content-color-disabled, var(--spectrum-tag-content-color-disabled))); pointer-events: none; + user-select: none; .spectrum-Avatar { opacity: var(--mod-avatar-opacity-disabled, var(--spectrum-avatar-opacity-disabled)); } + + .spectrum-Thumbnail { + opacity: var(--mod-thumbnail-opacity-disabled, var(--spectrum-thumbnail-opacity-disabled)); + } } /* windows high contrast mode */ @@ -414,7 +343,7 @@ --highcontrast-tag-border-color: ButtonText; --highcontrast-tag-border-color-hover: ButtonText; --highcontrast-tag-border-color-active: ButtonText; - --highcontrast-tag-border-color-focus: Highlight; + --highcontrast-tag-border-color-focus: ButtonText; --highcontrast-tag-background-color: ButtonFace; --highcontrast-tag-background-color-hover: ButtonFace; @@ -427,14 +356,10 @@ --highcontrast-tag-content-color-focus: ButtonText; --highcontrast-tag-focus-ring-color: Highlight; - forced-color-adjust: none; &.is-selected { --highcontrast-tag-border-color-selected: Highlight; - --highcontrast-tag-border-color-selected-hover: Highlight; - --highcontrast-tag-border-color-selected-active: Highlight; - --highcontrast-tag-border-color-selected-focus: Highlight; --highcontrast-tag-background-color-selected: Highlight; --highcontrast-tag-background-color-selected-hover: Highlight; @@ -450,37 +375,8 @@ --highcontrast-tag-content-color-disabled: GrayText; } - &.is-invalid { - --highcontrast-tag-border-color-invalid: Highlight; - --highcontrast-tag-border-color-invalid-hover: Highlight; - --highcontrast-tag-border-color-invalid-active: Highlight; - --highcontrast-tag-border-color-invalid-focus: Highlight; - - --highcontrast-tag-content-color-invalid: CanvasText; - --highcontrast-tag-content-color-invalid-hover: CanvasText; - --highcontrast-tag-content-color-invalid-active: CanvasText; - --highcontrast-tag-content-color-invalid-focus: CanvasText; - - &.is-selected { - --highcontrast-tag-border-color-invalid-selected: Highlight; - --highcontrast-tag-border-color-invalid-selected-hover: Highlight; - --highcontrast-tag-border-color-invalid-selected-focus: Highlight; - --highcontrast-tag-border-color-invalid-selected-active: Highlight; - - --highcontrast-tag-background-color-invalid-selected: Highlight; - --highcontrast-tag-background-color-invalid-selected-hover: Highlight; - --highcontrast-tag-background-color-invalid-selected-active: Highlight; - --highcontrast-tag-background-color-invalid-selected-focus: Highlight; - - --highcontrast-tag-content-color-invalid-selected: HighlightText; - } - } - - &.is-emphasized { + &.spectrum-Tag--emphasized { --highcontrast-tag-border-color-emphasized: Highlight; - --highcontrast-tag-border-color-emphasized-hover: Highlight; - --highcontrast-tag-border-color-emphasized-active: Highlight; - --highcontrast-tag-border-color-emphasized-focus: Highlight; --highcontrast-tag-background-color-emphasized: ButtonFace; --highcontrast-tag-background-color-emphasized-hover: ButtonFace; diff --git a/components/tag/stories/tag.stories.js b/components/tag/stories/tag.stories.js index 6061c450e7d..cbbc0a1b485 100644 --- a/components/tag/stories/tag.stories.js +++ b/components/tag/stories/tag.stories.js @@ -1,11 +1,11 @@ import { default as IconStories } from "@spectrum-css/icon/stories/icon.stories.js"; -import { Sizes } from "@spectrum-css/preview/decorators"; +import { Sizes, withDownStateDimensionCapture } from "@spectrum-css/preview/decorators"; import { disableDefaultModes } from "@spectrum-css/preview/modes"; -import { isDisabled, isEmphasized, isInvalid, isSelected, size } from "@spectrum-css/preview/types"; +import { isActive, isDisabled, isEmphasized, isHovered, isKeyboardFocused, isReadOnly, isSelected, size } from "@spectrum-css/preview/types"; import metadata from "../dist/metadata.json"; import packageJson from "../package.json"; import { TagGroups } from "./tag.test.js"; -import { SelectedTemplate, TagsDefaultOptions } from "./template.js"; +import { TagsDefaultOptions } from "./template.js"; /** * A tag categorizes content. It can represent keywords or people, and are [grouped](?path=/docs/components-tag-group--docs) to describe an item or a search request. @@ -15,29 +15,29 @@ export default { component: "Tag", argTypes: { size: size(["s", "m", "l"]), - hasIcon: { - name: "Has icon", - type: { name: "boolean" }, + label: { + name: "Label", + type: { name: "string" }, table: { - type: { summary: "boolean" }, - category: "Component", + type: { summary: "string" }, + category: "Content", }, - control: "boolean", - if: { arg: "hasAvatar", truthy: false }, - }, - iconName: { - ...(IconStories?.argTypes?.iconName ?? {}), - if: { arg: "hasIcon", truthy: true }, + control: { type: "text" }, }, - hasAvatar: { - name: "Has avatar", - type: { name: "boolean" }, + visualContent: { + name: "Visual content", + description: "Can consist of a thumbnail, icon, or avatar.", + type: { name: "string" }, table: { - type: { summary: "boolean" }, - category: "Component", + type: { summary: "string" }, + category: "Content", }, - control: "boolean", - if: { arg: "hasIcon", truthy: false }, + options: ["none", "avatar", "icon", "thumbnail"], + control: "select", + }, + iconName: { + ...(IconStories?.argTypes?.iconName ?? {}), + if: { arg: "visualContent", eq: "icon" }, }, avatarUrl: { name: "Avatar image", @@ -47,27 +47,28 @@ export default { category: "Content", }, control: { type: "file", accept: ".svg,.png,.jpg,.jpeg,.webc" }, - if: { arg: "hasAvatar", truthy: true }, + if: { arg: "visualContent", eq: "avatar" }, }, - label: { - name: "Label", + thumbnailUrl: { + name: "Thumbnail image", type: { name: "string" }, table: { type: { summary: "string" }, category: "Content", }, - control: { type: "text" }, - }, - isEmphasized: { - ...isEmphasized, - if: { arg: "isInvalid", truthy: false }, + control: { type: "file", accept: ".svg,.png,.jpg,.jpeg,.webc" }, + if: { arg: "visualContent", eq: "thumbnail" }, }, - isInvalid, + isEmphasized, isDisabled, isSelected, - hasClearButton: { - name: "Clear button", - description: "True if a button is present to clear the tag.", + isHovered, + isKeyboardFocused, + isActive, + isReadOnly, + isRemovable: { + name: "Removable", + description: "Has a clear button to clear the tag.", type: { name: "boolean" }, table: { type: { summary: "boolean" }, @@ -78,17 +79,19 @@ export default { }, args: { rootClass: "spectrum-Tag", - size: "m", + size: "s", label: "Tag label", - hasIcon: false, - iconName: "Info", + iconName: "Circle", avatarUrl: "example-ava.png", - hasAvatar: false, + thumbnailUrl: "example-card-landscape.png", isSelected: false, isDisabled: false, - isInvalid: false, isEmphasized: false, - hasClearButton: false, + isHovered: false, + isKeyboardFocused: false, + isActive: false, + isReadOnly: false, + isRemovable: false, }, parameters: { actions: { @@ -100,7 +103,17 @@ export default { }, packageJson, metadata, + downState: { + selectors: [".spectrum-Tag:not(:disabled)"], + }, + status: { + type: "migrated", + }, }, + decorators: [ + withDownStateDimensionCapture, + ], + tags: ["migrated"], }; export const Default = TagGroups.bind({}); @@ -108,7 +121,6 @@ Default.tags = ["!autodocs"]; Default.args = {}; // ********* VRT ONLY ********* // -// @todo combine variants into one snapshot export const WithForcedColors = TagGroups.bind({}); WithForcedColors.tags = ["!autodocs", "!dev"]; WithForcedColors.parameters = { @@ -119,66 +131,85 @@ WithForcedColors.parameters = { }; // ********* DOCS ONLY ********* // - +/** + * Tags should always include a label to represent search terms, filters, or keywords. Tags also + * have the option to include an [icon](?path=/docs/components-icon--docs), + * [avatar](?path=/docs/components-avatar--docs), or + * [thumbnail](?path=/docs/components-thumbnail--docs) in addition to the label. + */ export const Standard = TagsDefaultOptions.bind({}); Standard.args = Default.args; +Standard.storyName = "Default"; Standard.tags = ["!dev"]; Standard.parameters = { chromatic: { disableSnapshot: true }, }; -Standard.storyName = "Default"; -export const Selected = SelectedTemplate.bind({}); +export const Selected = TagsDefaultOptions.bind({}); +Selected.storyName = "Selected default"; Selected.tags = ["!dev"]; Selected.args = { isSelected: true }; - Selected.parameters = { chromatic: { disableSnapshot: true }, }; +/** + * A tag in a disabled state shows that a tag exists, but is not available in that circumstance. + * This can be used to maintain layout continuity and communicate that a tag may become available later. + */ export const Disabled = TagsDefaultOptions.bind({}); Disabled.tags = ["!dev"]; Disabled.args = { isDisabled: true, }; - Disabled.parameters = { chromatic: { disableSnapshot: true }, }; export const Emphasized = TagsDefaultOptions.bind({}); +Emphasized.storyName = "Selected emphasized"; Emphasized.tags = ["!dev"]; Emphasized.args = { - isEmphasized: true + isEmphasized: true, + isSelected: true, }; - Emphasized.parameters = { chromatic: { disableSnapshot: true }, }; -export const Invalid = TagGroups.bind({}); -Invalid.tags = ["!dev"]; -Invalid.args = { - isInvalid: true -}; - -Invalid.parameters = { - chromatic: { disableSnapshot: true }, -}; - +/** + * Tags have the option to be removable or not. Removable tags have a small clear ("x") button. + */ export const Removable = TagsDefaultOptions.bind({}); +Removable.storyName = "Default, removable"; Removable.tags = ["!dev"]; Removable.args = { - hasClearButton: true, + isRemovable: true, }; - Removable.parameters = { chromatic: { disableSnapshot: true }, }; +/** + * Tags have a read-only option for when content in the disabled state still needs to be shown. + * Read-only tags cannot be interacted with or changed. + */ +export const ReadOnly = TagsDefaultOptions.bind({}); +ReadOnly.storyName = "Read-only"; +ReadOnly.tags = ["!dev"]; +ReadOnly.args = { + isReadOnly: true, +}; +ReadOnly.parameters = { + chromatic: { disableSnapshot: true }, +}; + +/** + * The default size of a tag is small, but tags are also available in medium and large sizes. + */ export const Sizing = (args, context) => Sizes({ Template: TagsDefaultOptions, withHeading: false, @@ -192,16 +223,22 @@ Sizing.parameters = { /** - * When the tag text is too long for the available horizontal space, it truncates. The full text should be revealed with a tooltip on hover. + * When the tag text is too long for the available horizontal space, it truncates. The full text + * should be revealed with a tooltip on hover. Tags have a maximum width that differs depending on + * the size of the tag. * */ -export const TextOverflow = TagGroups.bind({}); +export const TextOverflow = (args, context) => Sizes({ + Template: TagGroups, + withHeading: false, + withBorder: false, + ...args, +}, context); TextOverflow.tags = ["!dev"]; TextOverflow.args = { hasIcon: true, iconName: "CheckmarkCircle", label: "An example of text overflow behavior. When the button text is too long for the horizontal space available, it will truncate and stay on one line.", - customStyles: { "max-inline-size": "200px" } }; TextOverflow.parameters = { diff --git a/components/tag/stories/tag.test.js b/components/tag/stories/tag.test.js index c4f4e390164..5c3ed2194d7 100644 --- a/components/tag/stories/tag.test.js +++ b/components/tag/stories/tag.test.js @@ -1,51 +1,140 @@ import { Variants } from "@spectrum-css/preview/decorators"; -import { Template } from "./template.js"; +import { TagsDefaultOptions, Template } from "./template.js"; export const TagGroups = Variants({ Template, + SizeTemplate: TagsDefaultOptions, sizeDirection: "row", testData: [ { testHeading: "Default", }, { - testHeading: "Is removable", - hasClearButton: true, + testHeading: "Emphasized", + isEmphasized: true, }, { - testHeading: "With icon", - hasIcon: true, - iconName: "Info", + testHeading: "Disabled with states", + isDisabled: true, }, + // variants with visuals { - testHeading: "With avatar", - hasAvatar: true, + testHeading: "Default, with icon", + iconName: "Circle", + }, + { + testHeading: "Default, with avatar", avatarUrl: "example-ava.png", }, + { + testHeading: "Emphasized, with thumbnail", + isEmphasized: true, + thumbnailUrl: "example-card-landscape.png", + }, + // read-only + { + testHeading: "Default, read-only", + isReadOnly: true, + }, + { + testHeading: "Emphasized, read-only", + isReadOnly: true, + isEmphasized: true, + isSelected: true, + }, + // truncated, which many states below ignore { testHeading: "Truncated", label: "Tag label that truncates when it gets too long", - customStyles: { - "max-inline-size": "200px" - } } ], stateData: [ { - testHeading: "Invalid", - isInvalid: true, + testHeading: "Removable", + isRemovable: true, + }, + { + testHeading: "Hovered", + isHovered: true, + ignore: ["Truncated"], + }, + { + testHeading: "Keyboard focused", + isKeyboardFocused: true, + ignore: ["Truncated"], + }, + { + testHeading: "Active", + isActive: true, + ignore: ["Truncated"], }, { testHeading: "Disabled", isDisabled: true, + ignore: ["Truncated", "Disabled with states"], }, { testHeading: "Selected", isSelected: true, + ignore: ["Truncated"], }, { - testHeading: "Emphasized", - isEmphasized: true, + testHeading: "Selected & removable", + isSelected: true, + isRemovable: true, + ignore: ["Truncated"], + }, + { + testHeading: "Selected & hovered", + isSelected: true, + isHovered: true, + ignore: ["Truncated"], + }, + { + testHeading: "Selected & keyboard focused", + isSelected: true, + isKeyboardFocused: true, + ignore: ["Truncated"], + }, + { + testHeading: "Selected & active", + isSelected: true, + isActive: true, + ignore: ["Truncated"], + }, + // adding visuals as states so we can test them in the truncated section + { + testHeading: "With icon", + iconName: "Circle", + include: ["Truncated"], + }, + { + testHeading: "With icon, removable", + iconName: "Circle", + isRemovable: true, + include: ["Truncated"], + }, + { + testHeading: "With avatar", + avatarUrl: "example-ava.png", + include: ["Truncated"], + }, + { + testHeading: "With avatar, removable", + avatarUrl: "example-ava.png", + isRemovable: true, + include: ["Truncated"], + }, + { + testHeading: "With thumbnail", + thumbnailUrl: "example-card-landscape.png", + include: ["Truncated"], + }, + { + testHeading: "With thumbnail, removable", + thumbnailUrl: "example-card-landscape.png", + isRemovable: true, + include: ["Truncated"], }, ] }); diff --git a/components/tag/stories/template.js b/components/tag/stories/template.js index ee4b244dd43..6eee8ba8ee3 100644 --- a/components/tag/stories/template.js +++ b/components/tag/stories/template.js @@ -2,7 +2,8 @@ import { Template as Avatar } from "@spectrum-css/avatar/stories/template.js"; import { Template as ClearButton } from "@spectrum-css/clearbutton/stories/template.js"; import { Template as Icon } from "@spectrum-css/icon/stories/template.js"; import { Container, getRandomId } from "@spectrum-css/preview/decorators"; -import { html, nothing } from "lit"; +import { Template as Thumbnail } from "@spectrum-css/thumbnail/stories/template.js"; +import { html } from "lit"; import { classMap } from "lit/directives/class-map.js"; import { ifDefined } from "lit/directives/if-defined.js"; import { styleMap } from "lit/directives/style-map.js"; @@ -12,20 +13,24 @@ import "../index.css"; export const Template = ({ rootClass = "spectrum-Tag", - size = "m", - iconName, - avatarUrl, - label, + size = "s", + iconName = "", + avatarUrl = "", + thumbnailUrl = "", + label = "", isSelected = false, isEmphasized = false, isDisabled = false, - isInvalid = false, - hasClearButton = false, + isHovered = false, + isKeyboardFocused = false, + isActive = false, + isReadOnly = false, + isRemovable = false, id = getRandomId("tag"), customClasses = [], customStyles = {}, } = {}, context = {}) => { - if(isInvalid) iconName = "Alert"; + const { updateArgs } = context; return html`
({ ...a, [c]: true }), {}), })} id=${ifDefined(id)} tabindex=${isDisabled ? "-1" : "0"} style=${styleMap(customStyles)} + @click=${function() { + if (isReadOnly || isDisabled) return; + updateArgs({ isSelected: !isSelected }); + }} > - ${when(avatarUrl && !isInvalid, () => + ${when(avatarUrl, () => Avatar({ + size: ({ + s: "50", + m: "75", + l: "100", + }[size] || "75"), image: avatarUrl, - size: "50", }, context) )} - ${when(iconName || isInvalid, () => + ${when(iconName, () => Icon({ size, iconName, @@ -57,16 +73,28 @@ export const Template = ({ customClasses: [`${rootClass}-itemIcon`], }, context) )} + ${when(thumbnailUrl, () => + Thumbnail({ + size: ({ + s: "50", + m: "75", + l: "100", + }[size] || "75"), + imageURL: thumbnailUrl, + }, context) + )} ${label} - ${when(hasClearButton, () => + ${when(isRemovable, () => ClearButton({ size, + isDisabled, + isFocusable: false, customClasses: [`${rootClass}-clearButton`], onclick: (evt) => { - const el = evt.target; - if (!el) return; + const button = evt.currentTarget; + if (!button) return; - const wrapper = el.closest(rootClass); + const wrapper = button.closest(`.${rootClass}`); wrapper.parentNode.removeChild(wrapper); }, }, context) @@ -85,36 +113,23 @@ export const TagsDefaultOptions = ({ }, content: html` ${Template(args, context)} - ${!args.isInvalid ? - Template({ + ${args.isRemovable ? "" : Template({ + ...args, + isRemovable: true, + }, context)} + ${Template({ ...args, hasIcon: true, - iconName: "CheckmarkCircle" - }, context): nothing } - ${!args.isInvalid ? - Template({ + iconName: "CheckmarkCircle", + }, context)} + ${Template({ + ...args, + hasThumbnail: true, + thumbnailUrl: "example-card-landscape.png", + }, context)} + ${Template({ ...args, hasAvatar: true, avatarUrl: "example-ava.png", - }, context): nothing }`, -}, context); - -export const SelectedTemplate = (args, context) => Container({ - withBorder: false, - direction: "row", - wrapperStyles: { - rowGap: "12px", - }, - content: html`${[ - { isSelected: true, isDisabled: false, heading: "Selected" }, - { isSelected: true, isDisabled: false, isInvalid: true, heading: "Selected + Invalid" }, - ].map(({isSelected, heading, isInvalid}) => Container({ - withBorder: false, - heading: heading, - content: TagsDefaultOptions({ - ...args, - isSelected, - isInvalid - }) - }, context))}` + }, context)}`, }, context);