Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(item): show tooltip when text ellipsis #394

Merged
merged 26 commits into from
Sep 6, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
cec66de
feat(item): show tooltip when text ellipsis
Nantawat-Poothong Jul 12, 2022
03d0e02
style(item): fix lint error
Nantawat-Poothong Jul 12, 2022
ce428da
fix(item): remove condition to register tooltip
Nantawat-Poothong Jul 14, 2022
641f41e
chore(item): use isElementOverflown and remove isTruncated
Nantawat-Poothong Jul 14, 2022
f71343a
Merge branch 'v6' into fix/select-with-tooltip-data-object
Nantawat-Poothong Jul 18, 2022
ec8dfee
fix(item): add tooltip for label and sub-label
Nantawat-Poothong Aug 17, 2022
647c1e9
fix(item): change way to call methods
Nantawat-Poothong Aug 17, 2022
b35b2e8
Merge branch 'v6' into fix/select-with-tooltip-data-object
Nantawat-Poothong Aug 17, 2022
c01de6a
test(item): add more test cases
Nantawat-Poothong Aug 18, 2022
077f9c1
Merge branch 'v6' into fix/select-with-tooltip-data-object
Nantawat-Poothong Aug 18, 2022
e99d4e3
Merge branch 'v6' into fix/select-with-tooltip-data-object
Nantawat-Poothong Aug 18, 2022
5913e0d
fix(item): update tooltip content
Nantawat-Poothong Aug 18, 2022
390305b
fix(item): update tooltip follow feedback
Nantawat-Poothong Aug 25, 2022
79b5617
fix(item): update subLabel show content logic
Nantawat-Poothong Aug 25, 2022
d293a1e
Merge branch 'v6' into fix/select-with-tooltip-data-object
Nantawat-Poothong Aug 25, 2022
6701858
chore(color-picker): add new slot ref
Nantawat-Poothong Aug 26, 2022
9f76ec7
Merge remote-tracking branch 'origin/fix/select-with-tooltip-data-obj…
Nantawat-Poothong Aug 26, 2022
1495102
fix(item): update test snapshot
Nantawat-Poothong Aug 26, 2022
b9a5731
chore(color-picker): simplify label and subLabel logic template
Nantawat-Poothong Aug 26, 2022
0036e90
fix(item): remove unnecessary code
Nantawat-Poothong Aug 26, 2022
eba8dcd
Merge branch 'v6' into fix/select-with-tooltip-data-object
Nantawat-Poothong Aug 26, 2022
6e4d645
chore(item): update code comment
Nantawat-Poothong Aug 31, 2022
ca05a77
chore(item): remove unnecessary casting type
Nantawat-Poothong Aug 31, 2022
4849f93
chore(color-picker): remove empty line
Nantawat-Poothong Sep 1, 2022
e29c869
Merge branch 'v6' into fix/select-with-tooltip-data-object
Nantawat-Poothong Sep 5, 2022
59e0f3d
fix(item): handle empty slot when assign to nodes
Nantawat-Poothong Sep 6, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
60 changes: 12 additions & 48 deletions packages/elements/src/item/__snapshots__/Item.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,7 @@
<slot name="left">
</slot>
</div>
<div
id="label"
part="center"
>
<div part="center">
<slot>
</slot>
</div>
Expand All @@ -35,10 +32,7 @@
<slot name="left">
</slot>
</div>
<div
id="label"
part="center"
>
<div part="center">
<slot>
</slot>
</div>
Expand All @@ -61,10 +55,7 @@
<slot name="left">
</slot>
</div>
<div
id="label"
part="center"
>
<div part="center">
<slot>
</slot>
</div>
Expand All @@ -82,10 +73,7 @@
<slot name="left">
</slot>
</div>
<div
id="label"
part="center"
>
<div part="center">
tiger
<slot>
</slot>
Expand All @@ -107,10 +95,7 @@
<slot name="left">
</slot>
</div>
<div
id="label"
part="center"
>
<div part="center">
tiger
<slot>
</slot>
Expand All @@ -132,10 +117,7 @@
<slot name="left">
</slot>
</div>
<div
id="label"
part="center"
>
<div part="center">
<slot>
</slot>
</div>
Expand All @@ -153,10 +135,7 @@
<slot name="left">
</slot>
</div>
<div
id="label"
part="center"
>
<div part="center">
<slot>
</slot>
<div part="sub-label">
Expand All @@ -177,10 +156,7 @@
<slot name="left">
</slot>
</div>
<div
id="label"
part="center"
>
<div part="center">
tiger
<slot>
</slot>
Expand Down Expand Up @@ -225,10 +201,7 @@
<slot name="left">
</slot>
</div>
<div
id="label"
part="center"
>
<div part="center">
<slot>
</slot>
</div>
Expand All @@ -255,10 +228,7 @@
<slot name="left">
</slot>
</div>
<div
id="label"
part="center"
>
<div part="center">
<slot>
</slot>
</div>
Expand All @@ -282,10 +252,7 @@
<slot name="left">
</slot>
</div>
<div
id="label"
part="center"
>
<div part="center">
<slot>
</slot>
</div>
Expand All @@ -301,10 +268,7 @@
<slot name="left">
</slot>
</div>
<div
id="label"
part="center"
>
<div part="center">
<slot>
</slot>
</div>
Expand Down
30 changes: 19 additions & 11 deletions packages/elements/src/item/__test__/item.test.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { elementUpdated, expect, fixture, nextFrame } from '@refinitiv-ui/test-helpers';
TremayneChrist marked this conversation as resolved.
Show resolved Hide resolved
import { elementUpdated, expect, fixture } from '@refinitiv-ui/test-helpers';
// import element and theme
import '@refinitiv-ui/elements/item';
import '@refinitiv-ui/elemental-theme/light/ef-item';
Expand All @@ -17,6 +17,10 @@ const createFixture = (type = '') => {
return fixture('<ef-item label="tiger">Test Not Highlightable</ef-item>');
case 'is_truncated':
return fixture('<div style="width: 100px; overflow: hidden;"><ef-item>Super vary long string that need to be truncated by parent</ef-item></div>');
case 'is_truncated_label':
return fixture('<div style="width: 100px; overflow: hidden;"><ef-item label="Super vary long string that need to be truncated by parent"></ef-item></div>');
case 'is_truncated_subLabel':
return fixture('<div style="width: 100px; overflow: hidden;"><ef-item sub-label="Super vary long string that need to be truncated by parent"></ef-item></div>');
case 'with_icon':
return fixture('<ef-item icon="tick">With settings icon</ef-item>');
case 'with_empty_icon':
Expand Down Expand Up @@ -130,23 +134,27 @@ describe('item/Item', () => {
expect(el.highlightable).to.equal(false);
});

it('Should truncate text', async () => {
it('Should truncate item text', async () => {
const div = await createFixture('is_truncated');
const el = div.querySelector('ef-item');
expect(el.isItemOverflown(), 'Should truncate text').to.equal(true);
});

await elementUpdated(el);
await nextFrame();
it('Should truncate label', async () => {
const div = await createFixture('is_truncated_label');
const el = div.querySelector('ef-item');
expect(el.isItemOverflown(), 'Should truncate text').to.equal(true);
});

expect(el.isTruncated, 'Should truncate text').to.equal(true);
it('Should truncate subLabel', async () => {
const div = await createFixture('is_truncated_subLabel');
const el = div.querySelector('ef-item');
expect(el.isItemOverflown(), 'Should truncate text').to.equal(true);
});

it('Should not truncate text', async () => {
it('Should not truncate item text', async () => {
const el = await createFixture();

await elementUpdated(el);
await nextFrame();

expect(el.isTruncated, 'Should not truncate text').to.equal(false);
expect(el.isItemOverflown(), 'Should not truncate text').to.equal(false);
});
});

Expand Down
98 changes: 78 additions & 20 deletions packages/elements/src/item/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,12 @@ import {
} from '@refinitiv-ui/core';
import { customElement } from '@refinitiv-ui/core/decorators/custom-element.js';
import { property } from '@refinitiv-ui/core/decorators/property.js';
import { query } from '@refinitiv-ui/core/decorators/query.js';
import { VERSION } from '../version.js';
import '../icon/index.js';
import '../checkbox/index.js';

import { registerOverflowTooltip } from '../tooltip/index.js';
import { isElementOverflown } from '@refinitiv-ui/utils/element.js';
import { createRef, ref, Ref } from '@refinitiv-ui/core/directives/ref.js';
import type { ItemType, ItemText, ItemHeader, ItemDivider, ItemData } from './helpers/types';
export type { ItemType, ItemText, ItemHeader, ItemDivider, ItemData };

Expand Down Expand Up @@ -126,10 +127,19 @@ export class Item extends ControlElement {
public for: string | null = null;

/**
* Cache label element
* Reference to the label element
*/
private labelRef: Ref<HTMLDivElement> = createRef();

TremayneChrist marked this conversation as resolved.
Show resolved Hide resolved
/**
* Reference to the subLabel element
*/
private subLabelRef: Ref<HTMLDivElement> = createRef();

/**
* Reference to the slot element
*/
@query('#label')
private labelEl?: HTMLElement;
private slotRef: Ref<HTMLSlotElement> = createRef();

/**
* True, if there is no slotted content
Expand Down Expand Up @@ -187,6 +197,16 @@ export class Item extends ControlElement {
}
}

/**
* Called after the component is first rendered
* @param changedProperties Properties which have changed
* @returns {void}
*/
protected firstUpdated (changedProperties: PropertyValues): void {
super.firstUpdated(changedProperties);
registerOverflowTooltip(this, () => this.getItemContent(), () => this.isItemOverflown());
}

/**
* Invoked before update() to compute values needed during the update.
* @param changedProperties changed properties
Expand All @@ -204,6 +224,45 @@ export class Item extends ControlElement {
}
}


/**
* Get Item content
* @returns return item content from slot or label and sub-label
*/
private getItemContent (): string {

if (this.isSlotEmpty) {
TremayneChrist marked this conversation as resolved.
Show resolved Hide resolved
let text = '';
if (this.label) {
text += this.label;
}
if (this.subLabel) {
text += text ? ` (${this.subLabel})` : this.subLabel;
}
return text;
}
else {
return this.slotContent;
}
}

/**
* Get element overflown
* @param element Target element
* @returns return true if element is overflown.
*/
private isItemElementOverflown (element?: HTMLElement): boolean {
return element ? isElementOverflown(element) : false;
}

/**
* Get item overflown
* @returns return true if an item is overflown.
*/
private isItemOverflown (): boolean {
return this.isItemElementOverflown(this.labelRef.value) || this.isItemElementOverflown(this.subLabelRef.value);
}

/**
* Get icon template if icon attribute is defined
*/
Expand All @@ -215,14 +274,22 @@ export class Item extends ControlElement {
* Get subLabel template if it is defined and no slot content present
*/
private get subLabelTemplate (): TemplateResult | undefined {
return this.subLabel && this.isSlotEmpty ? html`<div part="sub-label">${this.subLabel}</div>` : undefined;
return html`<div part="sub-label" ${ref(this.subLabelRef)}>${this.subLabel}</div>`;
}

/**
* Get label template if it is defined and no slot content present
*/
private get labelTemplate (): TemplateResult | undefined {
return this.label && this.isSlotEmpty ? html`${this.label}` : undefined;
return html`${this.label}`;
}

/**
* Get slot content
*/
private get slotContent (): string {
const nodes = this.slotRef.value?.assignedNodes() || [];
return nodes.map(node => node.textContent).join(' ').trim();
}

/**
Expand Down Expand Up @@ -251,15 +318,6 @@ export class Item extends ControlElement {
return !this.disabled && this.type !== 'header' && this.type !== 'divider';
}

/**
* Getter returning if the label is truncated
* @prop {boolean} isTruncated
* @returns whether element is truncated or not
*/
public get isTruncated (): boolean {
return !!(this.labelEl && (this.labelEl.offsetWidth < this.labelEl.scrollWidth));
}

/**
* A `TemplateResult` that will be used
* to render the updated internal template.
Expand All @@ -272,10 +330,10 @@ export class Item extends ControlElement {
${this.multipleTemplate}
<slot name="left"></slot>
</div>
<div part="center" id="label">
${this.labelTemplate}
<slot @slotchange="${this.checkSlotChildren}"></slot>
${this.subLabelTemplate}
<div part="center" ${ref(this.labelRef)}>
${this.label && this.isSlotEmpty ? this.labelTemplate : undefined}
<slot ${ref(this.slotRef)} @slotchange="${this.checkSlotChildren}"></slot>
${this.subLabel && this.isSlotEmpty ? this.subLabelTemplate : undefined}
</div>
<div part="right">
<slot name="right"></slot>
Expand Down