From df74c25a0367a4c34200dbea8d695864949b24c8 Mon Sep 17 00:00:00 2001 From: Dylan Hyun Date: Fri, 17 Jan 2025 13:24:22 -0500 Subject: [PATCH 1/7] HDS-4317 tag text truncation --- .../src/components/hds/tag/index.hbs | 58 ++++++++++++++----- .../src/components/hds/tag/index.ts | 6 ++ .../components/src/styles/components/tag.scss | 4 ++ 3 files changed, 52 insertions(+), 16 deletions(-) diff --git a/packages/components/src/components/hds/tag/index.hbs b/packages/components/src/components/hds/tag/index.hbs index 40f56af3ef9..03c375da4f7 100644 --- a/packages/components/src/components/hds/tag/index.hbs +++ b/packages/components/src/components/hds/tag/index.hbs @@ -9,22 +9,48 @@ {{/if}} {{#if (or @href @route)}} - - {{this.text}} - + {{#if this.isTextTruncated}} + + {{this.text}} + + {{else}} + + {{this.text}} + + {{/if}} {{else}} - - {{this.text}} - + {{#if this.isTextTruncated}} + + {{this.text}} + + {{else}} + + {{this.text}} + + {{/if}} {{/if}} \ No newline at end of file diff --git a/packages/components/src/components/hds/tag/index.ts b/packages/components/src/components/hds/tag/index.ts index 0670d6a31a0..e601eb0d926 100644 --- a/packages/components/src/components/hds/tag/index.ts +++ b/packages/components/src/components/hds/tag/index.ts @@ -25,6 +25,8 @@ export interface HdsTagSignature { } export default class HdsTag extends Component { + private _characterLimit = 20; + /** * @param onDismiss * @type {function} @@ -54,6 +56,10 @@ export default class HdsTag extends Component { return text; } + get isTextTruncated(): boolean { + return this.args.text.length > this._characterLimit; + } + /** * @param ariaLabel * @type {string} diff --git a/packages/components/src/styles/components/tag.scss b/packages/components/src/styles/components/tag.scss index c008848330a..1da8828a362 100644 --- a/packages/components/src/styles/components/tag.scss +++ b/packages/components/src/styles/components/tag.scss @@ -20,6 +20,7 @@ $hds-tag-border-radius: 50px; background-color: var(--token-color-surface-interactive); border: 1px solid var(--token-color-border-strong); border-radius: $hds-tag-border-radius; + max-width: 20ch; } .hds-tag__dismiss { @@ -43,6 +44,9 @@ $hds-tag-border-radius: 50px; flex: 1 0 0; padding: 3px 10px 5px 10px; border-radius: inherit; + overflow: hidden; + white-space: nowrap; + text-overflow: ellipsis; } .hds-tag__dismiss ~ .hds-tag__text, From d99d48a99c0f1d6587fe16a5f2252a956df92ba3 Mon Sep 17 00:00:00 2001 From: Dylan Hyun Date: Fri, 17 Jan 2025 16:10:21 -0500 Subject: [PATCH 2/7] Fix: Refactor to use `line-clamp` --- packages/components/src/components/hds/tag/index.hbs | 12 +++++++++--- packages/components/src/styles/components/tag.scss | 10 +++++++--- 2 files changed, 16 insertions(+), 6 deletions(-) diff --git a/packages/components/src/components/hds/tag/index.hbs b/packages/components/src/components/hds/tag/index.hbs index 03c375da4f7..480743b72f3 100644 --- a/packages/components/src/components/hds/tag/index.hbs +++ b/packages/components/src/components/hds/tag/index.hbs @@ -36,7 +36,9 @@ @href={{@href}} @isHrefExternal={{@isHrefExternal}} > - {{this.text}} +
+ {{this.text}} +
{{/if}} {{else}} @@ -45,11 +47,15 @@ class="hds-tag__text" {{hds-tooltip this.text options=(hash placement="right")}} > - {{this.text}} +
+ {{this.text}} +
{{else}} - {{this.text}} +
+ {{this.text}} +
{{/if}} {{/if}} diff --git a/packages/components/src/styles/components/tag.scss b/packages/components/src/styles/components/tag.scss index 1da8828a362..c2e270396e9 100644 --- a/packages/components/src/styles/components/tag.scss +++ b/packages/components/src/styles/components/tag.scss @@ -20,7 +20,6 @@ $hds-tag-border-radius: 50px; background-color: var(--token-color-surface-interactive); border: 1px solid var(--token-color-border-strong); border-radius: $hds-tag-border-radius; - max-width: 20ch; } .hds-tag__dismiss { @@ -44,9 +43,14 @@ $hds-tag-border-radius: 50px; flex: 1 0 0; padding: 3px 10px 5px 10px; border-radius: inherit; +} + +.hds-tag__text-container { overflow: hidden; - white-space: nowrap; - text-overflow: ellipsis; + display: -webkit-box; + -webkit-box-orient: vertical; + line-clamp: 1; + -webkit-line-clamp: 1; } .hds-tag__dismiss ~ .hds-tag__text, From a100715e491db99bb2e9b5c909ad2d9dd3773721 Mon Sep 17 00:00:00 2001 From: Dylan Hyun Date: Tue, 21 Jan 2025 11:10:49 -0500 Subject: [PATCH 3/7] Feat: Tag tooltip shown based on text overflow --- .../src/components/hds/tag/index.hbs | 26 +++++++---- .../src/components/hds/tag/index.ts | 43 ++++++++++++++++--- .../components/src/styles/components/tag.scss | 16 ++++++- showcase/app/templates/components/tag.hbs | 10 +++++ 4 files changed, 79 insertions(+), 16 deletions(-) diff --git a/packages/components/src/components/hds/tag/index.hbs b/packages/components/src/components/hds/tag/index.hbs index 480743b72f3..a319be88e30 100644 --- a/packages/components/src/components/hds/tag/index.hbs +++ b/packages/components/src/components/hds/tag/index.hbs @@ -2,14 +2,23 @@ Copyright (c) HashiCorp, Inc. SPDX-License-Identifier: MPL-2.0 }} - + {{#if this.onDismiss}} {{/if}} {{#if (or @href @route)}} - {{#if this.isTextTruncated}} + {{#if this._isTextOverflow}} - {{this.text}} +
+ {{this.text}} +
{{else}} {{/if}} {{else}} - {{#if this.isTextTruncated}} - + {{#if this._isTextOverflow}} +
{{this.text}}
-
+ {{else}}
diff --git a/packages/components/src/components/hds/tag/index.ts b/packages/components/src/components/hds/tag/index.ts index e601eb0d926..a893417e561 100644 --- a/packages/components/src/components/hds/tag/index.ts +++ b/packages/components/src/components/hds/tag/index.ts @@ -4,6 +4,8 @@ */ import Component from '@glimmer/component'; +import { tracked } from '@glimmer/tracking'; +import { action } from '@ember/object'; import { assert } from '@ember/debug'; import { HdsTagColorValues } from './types.ts'; @@ -25,7 +27,8 @@ export interface HdsTagSignature { } export default class HdsTag extends Component { - private _characterLimit = 20; + @tracked private _isTextOverflow!: boolean; + private _observer!: ResizeObserver; /** * @param onDismiss @@ -56,10 +59,6 @@ export default class HdsTag extends Component { return text; } - get isTextTruncated(): boolean { - return this.args.text.length > this._characterLimit; - } - /** * @param ariaLabel * @type {string} @@ -110,4 +109,38 @@ export default class HdsTag extends Component { return classes.join(' '); } + + @action + didInsert(element: HTMLElement): void { + const textElement = element.querySelector( + '.hds-tag__text-container' + ) as HTMLElement; + + // Used to detect when text is clipped to one line, and tooltip should be added + this._observer = new ResizeObserver((entries) => { + entries.forEach((entry) => { + this._isTextOverflow = this._isOverflow( + entry.target, + this._isTextOverflow + ); + }); + }); + this._observer.observe(textElement); + } + + @action + willDestroyNode(): void { + super.willDestroy(); + this._observer.disconnect(); + } + + private _isOverflow(el: Element, previousOverflow: boolean): boolean { + // If any overflow was present previously and was clipped the scroll height and client height will then be equal + // Any future resizes will incorrectly see the element as not overflowing unless the previous value is accounted for + if (previousOverflow || el.scrollHeight > el.clientHeight) { + return true; + } else { + return false; + } + } } diff --git a/packages/components/src/styles/components/tag.scss b/packages/components/src/styles/components/tag.scss index c2e270396e9..111296c7768 100644 --- a/packages/components/src/styles/components/tag.scss +++ b/packages/components/src/styles/components/tag.scss @@ -46,11 +46,11 @@ $hds-tag-border-radius: 50px; } .hds-tag__text-container { - overflow: hidden; display: -webkit-box; + overflow: hidden; -webkit-box-orient: vertical; - line-clamp: 1; -webkit-line-clamp: 1; + line-clamp: 1; } .hds-tag__dismiss ~ .hds-tag__text, @@ -84,6 +84,18 @@ $hds-tag-border-radius: 50px; } } +.hds-tooltip-button.hds-tag__text { + &:focus, + &.mock-focus { + @include hds-focus-ring-basic(); + z-index: 1; // ensures focus is not obscured by adjacent elements + } + + &:focus-visible::before { + box-shadow: none; // override default tooltip button focus styles + } +} + // COLORS (FOR LINK) .hds-tag--color-primary { diff --git a/showcase/app/templates/components/tag.hbs b/showcase/app/templates/components/tag.hbs index 19441765a63..1e22abd99e8 100644 --- a/showcase/app/templates/components/tag.hbs +++ b/showcase/app/templates/components/tag.hbs @@ -39,6 +39,16 @@ + + + + + + From b718928a6f9fea63ec9274a5b3e442b8e05e6056 Mon Sep 17 00:00:00 2001 From: Dylan Hyun Date: Tue, 21 Jan 2025 13:38:31 -0500 Subject: [PATCH 4/7] Fix: Tag ResizeObserver error message --- .../components/src/components/hds/tag/index.ts | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/packages/components/src/components/hds/tag/index.ts b/packages/components/src/components/hds/tag/index.ts index a893417e561..91bc3c102df 100644 --- a/packages/components/src/components/hds/tag/index.ts +++ b/packages/components/src/components/hds/tag/index.ts @@ -118,12 +118,14 @@ export default class HdsTag extends Component { // Used to detect when text is clipped to one line, and tooltip should be added this._observer = new ResizeObserver((entries) => { - entries.forEach((entry) => { - this._isTextOverflow = this._isOverflow( - entry.target, - this._isTextOverflow - ); - }); + requestAnimationFrame(() => { + entries.forEach((entry) => { + this._isTextOverflow = this._isOverflow( + entry.target, + this._isTextOverflow + ); + }); + }) }); this._observer.observe(textElement); } From 3c1798559b818ff9573ec838751aaac08fa21abc Mon Sep 17 00:00:00 2001 From: Dylan Hyun Date: Tue, 21 Jan 2025 13:41:58 -0500 Subject: [PATCH 5/7] Fix: component linting --- packages/components/src/components/hds/tag/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/components/src/components/hds/tag/index.ts b/packages/components/src/components/hds/tag/index.ts index 91bc3c102df..3cfb6aa1366 100644 --- a/packages/components/src/components/hds/tag/index.ts +++ b/packages/components/src/components/hds/tag/index.ts @@ -125,7 +125,7 @@ export default class HdsTag extends Component { this._isTextOverflow ); }); - }) + }); }); this._observer.observe(textElement); } From 9ff1e3cbb2eff519ffbeae6e3bb5642e22802edb Mon Sep 17 00:00:00 2001 From: Dylan Hyun Date: Wed, 22 Jan 2025 08:46:40 -0500 Subject: [PATCH 6/7] Fix: Tag tooltip being removed on resize --- .../components/src/components/hds/tag/index.ts | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-) diff --git a/packages/components/src/components/hds/tag/index.ts b/packages/components/src/components/hds/tag/index.ts index 3cfb6aa1366..a32f720b060 100644 --- a/packages/components/src/components/hds/tag/index.ts +++ b/packages/components/src/components/hds/tag/index.ts @@ -112,22 +112,17 @@ export default class HdsTag extends Component { @action didInsert(element: HTMLElement): void { - const textElement = element.querySelector( - '.hds-tag__text-container' - ) as HTMLElement; - // Used to detect when text is clipped to one line, and tooltip should be added this._observer = new ResizeObserver((entries) => { requestAnimationFrame(() => { entries.forEach((entry) => { this._isTextOverflow = this._isOverflow( - entry.target, - this._isTextOverflow + entry.target.querySelector('.hds-tag__text-container')! ); }); }); }); - this._observer.observe(textElement); + this._observer.observe(element); } @action @@ -136,10 +131,8 @@ export default class HdsTag extends Component { this._observer.disconnect(); } - private _isOverflow(el: Element, previousOverflow: boolean): boolean { - // If any overflow was present previously and was clipped the scroll height and client height will then be equal - // Any future resizes will incorrectly see the element as not overflowing unless the previous value is accounted for - if (previousOverflow || el.scrollHeight > el.clientHeight) { + private _isOverflow(el: Element): boolean { + if (el.scrollHeight > el.clientHeight) { return true; } else { return false; From 4adba3007332c5d840ab54ec05ff101770d6caf8 Mon Sep 17 00:00:00 2001 From: Dylan Hyun Date: Fri, 24 Jan 2025 09:58:12 -0500 Subject: [PATCH 7/7] Add changeset --- .changeset/brown-wolves-admire.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/brown-wolves-admire.md diff --git a/.changeset/brown-wolves-admire.md b/.changeset/brown-wolves-admire.md new file mode 100644 index 00000000000..39860f69c62 --- /dev/null +++ b/.changeset/brown-wolves-admire.md @@ -0,0 +1,5 @@ +--- +"@hashicorp/design-system-components": minor +--- + +`Tag` - Truncate any text that wraps to multiple lines and add a tooltip with the full text when truncation occurs