From 3c608bca46e59dd7068ce6fde1ed3580c8ac5b7b Mon Sep 17 00:00:00 2001 From: Cory Tyburski Date: Fri, 14 Apr 2023 15:51:33 -0400 Subject: [PATCH 1/2] First iteration of tooltips --- src/docs/links.ts | 3 +- src/lib/utilities/Tooltip/tooltip.ts | 45 ++++ src/lib/utilities/Tooltip/types.ts | 12 + .../(inner)/utilities/tooltips/+page.svelte | 209 ++++++++++++++++++ 4 files changed, 268 insertions(+), 1 deletion(-) create mode 100644 src/lib/utilities/Tooltip/tooltip.ts create mode 100644 src/lib/utilities/Tooltip/types.ts create mode 100644 src/routes/(inner)/utilities/tooltips/+page.svelte diff --git a/src/docs/links.ts b/src/docs/links.ts index 90d4351ca6..bcd3ff18d5 100644 --- a/src/docs/links.ts +++ b/src/docs/links.ts @@ -131,7 +131,8 @@ export const menuNavLinks: any = [ keywords: 'overlay, dialog, notification, alert, confirm, prompt, multiple, form, list, embed, video' }, { href: '/utilities/toasts', label: 'Toasts', keywords: 'overlay, snack, snackbar, bar, action, alert, notification' }, - { href: '/utilities/popups', label: 'Popups', keywords: 'menu, tooltip, overlay, dropdown, combobox, drop, down, select' } + { href: '/utilities/popups', label: 'Popups', keywords: 'menu, tooltip, overlay, dropdown, combobox, drop, down, select' }, + { href: '/utilities/tooltips', label: 'Tooltips', keywords: 'menu, tooltip' } // CHRIS: these are delisted until further notice // { // href: '/utilities/data-tables', diff --git a/src/lib/utilities/Tooltip/tooltip.ts b/src/lib/utilities/Tooltip/tooltip.ts new file mode 100644 index 0000000000..c226bfead0 --- /dev/null +++ b/src/lib/utilities/Tooltip/tooltip.ts @@ -0,0 +1,45 @@ +import { popup } from '$lib/utilities/Popup/popup'; +// Types +import type { PopupSettings } from '../Popup/types'; +import type { TooltipSettings } from './types'; + +function randomUUID(): string { + const random = Math.random(); + return Number(random).toString(32); +} + +// Default tooltip container classes +const defaultContentClasses = ['text-xs', 'text-center', 'card', 'variant-filled', 'p-2', 'whitespace-nowrap', 'shadow-xl']; + +export function tooltip(node: HTMLElement, args: TooltipSettings) { + const { content, arrow, ...remainingArgs } = args; + + if (!args.event || !content) return; + + // Generate unique ID for tooltip + const id = randomUUID(); + + const popupArgs: PopupSettings = { + target: id, + ...remainingArgs + } + + // If user content, create div on the fly + if (args.content) { + const elemPopup = document.createElement('span'); + elemPopup.innerHTML = args.content; + elemPopup.setAttribute('data-popup', id); + elemPopup.classList.add(...defaultContentClasses); + document.body.appendChild(elemPopup); // Add arrow div to body + + if (arrow) { + const elemArrow = document.createElement('div'); + elemArrow.classList.add('arrow', 'variant-filled'); + elemPopup.appendChild(elemArrow); + } + } + + popup(node, popupArgs); +} + + // TODO: Destroy at fade? \ No newline at end of file diff --git a/src/lib/utilities/Tooltip/types.ts b/src/lib/utilities/Tooltip/types.ts new file mode 100644 index 0000000000..ab1aa8f218 --- /dev/null +++ b/src/lib/utilities/Tooltip/types.ts @@ -0,0 +1,12 @@ +// Popup Types +// Note: these are a simple iteration based on the official docs. + +import type { PopupSettings } from "../Popup/types"; + +// Action Arguments +export type TooltipSettings = Omit & { + /** Set plain text content of tooltip */ + content: string, + /** Set to display an arrow */ + arrow?: boolean +}; \ No newline at end of file diff --git a/src/routes/(inner)/utilities/tooltips/+page.svelte b/src/routes/(inner)/utilities/tooltips/+page.svelte new file mode 100644 index 0000000000..773d4871a6 --- /dev/null +++ b/src/routes/(inner)/utilities/tooltips/+page.svelte @@ -0,0 +1,209 @@ + + + + + + + +
+
+ +
+
+
+ + +

Create a TooltipSettings object, or even set inline. + +

Apply the use:tooltip action to your trigger element.

+ Trigger`} /> +
+
+
+ + + + +
+

Getting Started

+

Install Floating UI from NPM. This is required.

+ +

Import Floating UI into your application's root layout /src/routes/+layout.svelte.

+ +

Then import storePopup in your root layout as well.

+ +

Finally, pass an object containing each of the Floating UI modules to the store.

+ +
+ +
+

Tooltip Settings

+ + Placement + Close Query + State + Middleware + + + {#if tabSettings === 0} + + +

+ Reference the available placement options. This setting defaults to bottom. +

+ + {:else if tabSettings === 1} + + +

Query the list of elements that will close the drawer when clicked. This is set to 'a[href], button' by default, but to limited to .listbox-item only we would use:

+ +

To disable any child elements from closing the tooltip, use the following:

+ + {:else if tabSettings === 2} + +

You can optionally monitor the show and hide state of a tooltip using state.

+ console.log(e) +}; +`} + /> + {:else if tabSettings === 3} + + +

+ You can provide Floating UI middleware settings within TooltipSettings. These settings are passed verbatim. +

+ + {/if} +
+
+
+ + +
+

Z-Index

+

+ Neither Skeleton nor Floating-UI will provide a Z-Index out of the box for the reasons layed out in the + Floating-UI docs. +

+
+ +
+

Browser Support

+

+ Please be aware that there is a z-index bug for tooltips rendered over elements using backdrop-blur in some browsers. The + tooltip will appear to be rendered behind the blurred element, even with an elevated z-index. +

+
+ +
+

Accessibility

+

We recommend you favor the click event for mobile devices, as hover is not well supported.

+
+
+
From d7d9b32a5d1178b7e76b415f48268cf9d08a7d56 Mon Sep 17 00:00:00 2001 From: Cory Tyburski Date: Fri, 14 Apr 2023 15:55:11 -0400 Subject: [PATCH 2/2] Modify descriptions --- src/routes/(inner)/utilities/popups/+page.svelte | 2 +- src/routes/(inner)/utilities/tooltips/+page.svelte | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/src/routes/(inner)/utilities/popups/+page.svelte b/src/routes/(inner)/utilities/popups/+page.svelte index d6a5c1e247..c892208bfc 100644 --- a/src/routes/(inner)/utilities/popups/+page.svelte +++ b/src/routes/(inner)/utilities/popups/+page.svelte @@ -18,7 +18,7 @@ feature: DocsFeature.Utility, name: 'Popups', description: - 'Create floating menus and tooltips using Floating UI.', + 'Create floating menus using Floating UI. Use the Tooltips component if you just want basic tooltip functionality.', imports: ['popup'], types: ['PopupSettings'], stylesheetIncludes: ['all', 'elements'], diff --git a/src/routes/(inner)/utilities/tooltips/+page.svelte b/src/routes/(inner)/utilities/tooltips/+page.svelte index 773d4871a6..fa4da3348b 100644 --- a/src/routes/(inner)/utilities/tooltips/+page.svelte +++ b/src/routes/(inner)/utilities/tooltips/+page.svelte @@ -6,7 +6,6 @@ import CodeBlock from '$lib/utilities/CodeBlock/CodeBlock.svelte'; import TabGroup from '$lib/components/Tab/TabGroup.svelte'; import Tab from '$lib/components/Tab/Tab.svelte'; - import type { TooltipSettings } from '$lib/utilities/Tooltip/types'; import { tooltip } from '$lib/utilities/Tooltip/tooltip'; // Docs Shell @@ -14,7 +13,7 @@ feature: DocsFeature.Utility, name: 'Tooltips', description: - 'Create floating menus and tooltips using Floating UI.', + 'Create tooltips using Floating UI. Use the Popups component if you want more advanced functionality.', imports: ['tooltip'], types: ['TooltipSettings'], stylesheetIncludes: ['all', 'elements'],