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

Add TooltipIcon component to Related Resources #266

Merged
merged 3 commits into from
Jul 20, 2023
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
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
2 changes: 1 addition & 1 deletion web/app/components/document/sidebar.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -276,7 +276,7 @@
@allowAddingExternalLinks={{true}}
@headerTitle="Related resources"
@modalHeaderTitle="Add related resource"
@modalInputPlaceholder="Paste a URL or search documents..."
@modalInputPlaceholder="Search docs or paste a URL..."
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reversed the order to be consistent with the tooltip text.

@scrollContainer={{this.body}}
@optionalSearchFilters={{array (concat "product:" @document.product)}}
/>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
<Document::Sidebar::SectionHeader
{{did-insert (perform this.loadRelatedResources)}}
@title={{@headerTitle}}
@titleTooltipText={{this.titleTooltipText}}
@badgeText="New"
@buttonIsHidden={{this.sectionHeaderButtonIsHidden}}
@buttonAction={{this.showAddResourceModal}}
Expand Down
6 changes: 6 additions & 0 deletions web/app/components/document/sidebar/related-resources.ts
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,12 @@ export default class DocumentSidebarRelatedResourcesComponent extends Component<
}
return documents;
}
/**
* The text passed to the TooltipIcon beside the title.
*/
protected get titleTooltipText(): string {
return `Documents and links that are relevant to this work.`;
}

/**
* The action to update the `sortOrder` attribute of
Expand Down
8 changes: 6 additions & 2 deletions web/app/components/document/sidebar/section-header.hbs
Original file line number Diff line number Diff line change
@@ -1,15 +1,19 @@
<div class="sidebar-section-header-container" ...attributes>
<div class="inline-flex relative">
<div class="inline-flex items-center relative">
<h5 class="sidebar-section-header">
{{@title}}
</h5>
{{#if @titleTooltipText}}
<TooltipIcon @text={{@titleTooltipText}} class="ml-1.5" />
{{/if}}
{{#if @badgeText}}
<Hds::Badge
data-test-sidebar-section-header-badge
@text={{@badgeText}}
@color="highlight"
@type="inverted"
@size="small"
class="absolute -right-2 top-1/2 -translate-y-1/2 translate-x-full"
class="absolute -right-1.5 top-1/2 -translate-y-1/2 translate-x-full"
/>
{{/if}}
</div>
Expand Down
1 change: 1 addition & 0 deletions web/app/components/document/sidebar/section-header.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ interface DocumentSidebarSectionHeaderComponentSignature {
Element: HTMLDivElement;
Args: {
title: string;
titleTooltipText?: string;
badgeText?: string;
buttonLabel?: string;
buttonAction?: () => void;
Expand Down
9 changes: 9 additions & 0 deletions web/app/components/tooltip-icon.hbs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<span
data-test-tooltip-icon-trigger
data-test-icon={{this.icon}}
{{tooltip @text class="max-w-[200px]"}}
class="flex text-color-foreground-faint hover:text-color-foreground-primary"
...attributes
>
<FlightIcon @name={{this.icon}} />
</span>
21 changes: 21 additions & 0 deletions web/app/components/tooltip-icon.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import Component from "@glimmer/component";

interface TooltipIconComponentSignature {
Element: HTMLSpanElement;
Args: {
text: string;
icon?: string;
};
}

export default class TooltipIconComponent extends Component<TooltipIconComponentSignature> {
protected get icon(): string {
return this.args.icon ?? "help";
}
}

declare module "@glint/environment-ember-loose/registry" {
export default interface Registry {
TooltipIcon: typeof TooltipIconComponent;
}
}
17 changes: 16 additions & 1 deletion web/app/modifiers/tooltip.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ interface TooltipModifierNamedArgs {
stayOpenOnClick?: boolean;
delay?: number;
openDuration?: number;
class?: string;
_useTestDelay?: boolean;
}

Expand Down Expand Up @@ -171,6 +172,11 @@ export default class TooltipModifier extends Modifier<TooltipModifierSignature>
*/
@tracked stayOpenOnClick = false;

/**
* Optional classnames to append to the tooltip.
*/
@tracked class: string | null = null;

/**
* An asserted-to-exist reference to the reference element.
*/
Expand Down Expand Up @@ -240,6 +246,11 @@ export default class TooltipModifier extends Modifier<TooltipModifierSignature>
*/
this.tooltip = document.createElement("div");
this.tooltip.classList.add("hermes-floating-ui-content", "hermes-tooltip");

if (this.class) {
this.tooltip.classList.add(this.class);
}

this.tooltip.setAttribute("id", `tooltip-${this.id}`);
this.tooltip.setAttribute("role", "tooltip");

Expand Down Expand Up @@ -283,7 +294,7 @@ export default class TooltipModifier extends Modifier<TooltipModifierSignature>
middleware: [
offset(8),
flip(),
shift(),
shift({ padding: 20 }),
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This prevents the tooltip from hitting the edge of the viewport by 20px.

arrow({
element: this.arrow,
padding: 10,
Expand Down Expand Up @@ -473,6 +484,10 @@ export default class TooltipModifier extends Modifier<TooltipModifierSignature>
this.placement = named.placement;
}

if (named.class) {
this.class = named.class;
}

if (named.stayOpenOnClick) {
this.stayOpenOnClick = named.stayOpenOnClick;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import {
fillIn,
find,
render,
triggerEvent,
waitFor,
waitUntil,
} from "@ember/test-helpers";
Expand Down Expand Up @@ -53,9 +54,12 @@ const ADD_EXTERNAL_RESOURCE_ERROR_SELECTOR =
"[data-test-add-external-resource-error]";
const EDIT_EXTERNAL_RESOURCE_ERROR_SELECTOR =
"[data-test-external-resource-title-error]";
const TOOLTIP_TRIGGER_SELECTOR = "[data-test-tooltip-icon-trigger]";
const TOOLTIP_SELECTOR = ".hermes-tooltip";

interface DocumentSidebarRelatedResourcesTestContext extends MirageTestContext {
document: HermesDocument;
body: HTMLElement;
}

module(
Expand All @@ -73,6 +77,8 @@ module(
});

this.set("document", this.server.schema.document.first().attrs);
const bodyDiv = document.createElement("div");
this.set("body", bodyDiv);
});

test("it renders the related resources list", async function (this: DocumentSidebarRelatedResourcesTestContext, assert) {
Expand All @@ -98,6 +104,7 @@ module(
@headerTitle="Test title"
@modalHeaderTitle="Add related resource"
@modalInputPlaceholder="Paste a URL or search documents..."
@scrollContainer={{this.body}}
/>
`);

Expand All @@ -113,6 +120,13 @@ module(
.dom(HEADER_SELECTOR)
.hasText("Test title", "the header title is correct");

assert.dom(TOOLTIP_SELECTOR).doesNotExist();
assert.dom(TOOLTIP_TRIGGER_SELECTOR).exists();
await triggerEvent(TOOLTIP_TRIGGER_SELECTOR, "mouseenter");
assert
.dom(".hermes-tooltip")
.hasText("Documents and links that are relevant to this work.");

assert.dom(BADGE_SELECTOR).hasText("New", "the 'new' badge is rendered'");

assert
Expand Down Expand Up @@ -163,6 +177,7 @@ module(
@headerTitle="Test title"
@modalHeaderTitle="Add related resource"
@modalInputPlaceholder="Paste a URL or search documents..."
@scrollContainer={{this.body}}
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These lines fix Glint errors in the test.

/>
`);

Expand Down Expand Up @@ -194,6 +209,7 @@ module(
@headerTitle="Test title"
@modalHeaderTitle="Add related resource"
@modalInputPlaceholder="Paste a URL or search documents..."
@scrollContainer={{this.body}}
/>
`);

Expand Down Expand Up @@ -224,6 +240,7 @@ module(
@headerTitle="Test title"
@modalHeaderTitle="Test header"
@modalInputPlaceholder="Paste a URL or search documents..."
@scrollContainer={{this.body}}
/>
`);

Expand Down Expand Up @@ -251,6 +268,7 @@ module(
@headerTitle="Test title"
@modalHeaderTitle="Test header"
@modalInputPlaceholder="Paste a URL or search documents..."
@scrollContainer={{this.body}}
/>
`);

Expand Down Expand Up @@ -289,6 +307,7 @@ module(
@headerTitle="Test title"
@modalHeaderTitle="Add related resource"
@modalInputPlaceholder="Paste a URL or search documents..."
@scrollContainer={{this.body}}
/>
`);

Expand Down Expand Up @@ -325,6 +344,7 @@ module(
@headerTitle="Test title"
@modalHeaderTitle="Add related resource"
@modalInputPlaceholder="Paste a URL or search documents..."
@scrollContainer={{this.body}}
/>
`);

Expand Down Expand Up @@ -352,6 +372,7 @@ module(
@headerTitle="Test title"
@modalHeaderTitle="Add related resource"
@modalInputPlaceholder="Test placeholder"
@scrollContainer={{this.body}}
/>
`);

Expand Down Expand Up @@ -420,6 +441,7 @@ module(
@headerTitle="Test title"
@modalHeaderTitle="Add related resource"
@modalInputPlaceholder="Test placeholder"
@scrollContainer={{this.body}}
/>
`);

Expand Down Expand Up @@ -462,6 +484,7 @@ module(
@headerTitle="Test title"
@modalHeaderTitle="Add related resource"
@modalInputPlaceholder="Test placeholder"
@scrollContainer={{this.body}}
/>
`);

Expand All @@ -483,6 +506,7 @@ module(
@headerTitle="Test title"
@modalHeaderTitle="Add related resource"
@modalInputPlaceholder="Test placeholder"
@scrollContainer={{this.body}}
/>
`);

Expand Down Expand Up @@ -534,6 +558,7 @@ module(
@headerTitle="Test title"
@modalHeaderTitle="Add related resource"
@modalInputPlaceholder="Test placeholder"
@scrollContainer={{this.body}}
/>
`);

Expand Down Expand Up @@ -564,6 +589,7 @@ module(
@headerTitle="Test title"
@modalHeaderTitle="Test header"
@modalInputPlaceholder="Paste a URL or search documents..."
@scrollContainer={{this.body}}
/>
`);

Expand Down Expand Up @@ -604,6 +630,7 @@ module(
@headerTitle="Test title"
@modalHeaderTitle="Test header"
@modalInputPlaceholder="Paste a URL or search documents..."
@scrollContainer={{this.body}}
/>
`);

Expand Down Expand Up @@ -679,6 +706,7 @@ module(
@headerTitle="Test title"
@modalHeaderTitle="Test header"
@modalInputPlaceholder="Paste a URL or search documents..."
@scrollContainer={{this.body}}
/>
`);

Expand Down
50 changes: 50 additions & 0 deletions web/tests/integration/components/tooltip-icon-test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import { module, test } from "qunit";
import { setupRenderingTest } from "ember-qunit";
import { TestContext, render, triggerEvent } from "@ember/test-helpers";
import { hbs } from "ember-cli-htmlbars";

interface TooltipIconComponentTestContext extends TestContext {
icon?: string;
}

const TRIGGER_SELECTOR = "[data-test-tooltip-icon-trigger]";
const TOOLTIP_SELECTOR = ".hermes-tooltip";

module("Integration | Component | tooltip-icon", function (hooks) {
setupRenderingTest(hooks);

test("it renders correctly", async function (this: TooltipIconComponentTestContext, assert) {
this.set("icon", undefined);

await render<TooltipIconComponentTestContext>(hbs`
<TooltipIcon
@text="This is a tooltip"
@icon={{this.icon}}
class="foo"
/>
`);

assert
.dom(TRIGGER_SELECTOR)
.hasAttribute("data-test-icon", "help", "default icon shown")
.hasClass("foo", "splattributes handled");

assert.dom(TOOLTIP_SELECTOR).doesNotExist();

this.set("icon", "smile");

assert
.dom(TRIGGER_SELECTOR)
.hasAttribute(
"data-test-icon",
"smile",
"default icon can be overridden"
);

await triggerEvent(TRIGGER_SELECTOR, "mouseenter");

assert
.dom(TOOLTIP_SELECTOR)
.hasText("This is a tooltip", "tooltip text shown");
});
});
13 changes: 12 additions & 1 deletion web/tests/integration/modifiers/tooltip-test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import { setupRenderingTest } from "ember-qunit";
import { render, triggerEvent, waitUntil } from "@ember/test-helpers";
import { hbs } from "ember-cli-htmlbars";
import htmlElement from "hermes/utils/html-element";
import { wait } from "ember-animated/.";

module("Integration | Modifier | tooltip", function (hooks) {
setupRenderingTest(hooks);
Expand Down Expand Up @@ -139,4 +138,16 @@ module("Integration | Modifier | tooltip", function (hooks) {

assert.equal(tip.getAttribute("data-tooltip-state"), "closed");
});

test("you can pass a class to the tooltip", async function (assert) {
await render(hbs`
<div class="tip" {{tooltip "more information" class="foo"}}>
Hover or focus me
</div>
`);

await triggerEvent(".tip", "mouseenter");

assert.dom(".hermes-tooltip").hasClass("foo");
});
});