feat(ui-shell): HeaderAction supports tooltip (#2111)

Closes #2110
This commit is contained in:
Eric Liu 2025-03-09 13:47:34 -07:00 committed by GitHub
commit 24b9cbc9c3
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 82 additions and 12 deletions

View file

@ -1616,15 +1616,17 @@ None.
### Props ### Props
| Prop name | Required | Kind | Reactive | Type | Default value | Description | | Prop name | Required | Kind | Reactive | Type | Default value | Description |
| :------------------------- | :------- | :--------------- | :------- | ----------------------------------------------------------------- | ------------------------------ | ---------------------------------------------------------------------------------------------------------------- | | :------------------------- | :------- | :--------------- | :------- | ----------------------------------------------------------------- | ------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------- |
| ref | No | <code>let</code> | Yes | <code>null &#124; HTMLButtonElement</code> | <code>null</code> | Obtain a reference to the button HTML element | | ref | No | <code>let</code> | Yes | <code>null &#124; HTMLButtonElement</code> | <code>null</code> | Obtain a reference to the button HTML element |
| isOpen | No | <code>let</code> | Yes | <code>boolean</code> | <code>false</code> | Set to `true` to open the panel | | isOpen | No | <code>let</code> | Yes | <code>boolean</code> | <code>false</code> | Set to `true` to open the panel |
| icon | No | <code>let</code> | No | <code>any</code> | <code>undefined</code> | Specify the icon to render when the action panel is closed.<br />Defaults to `&lt;Switcher size={20} /&gt;` | | icon | No | <code>let</code> | No | <code>any</code> | <code>undefined</code> | Specify the icon to render when the action panel is closed.<br />Defaults to `&lt;Switcher size={20} /&gt;` |
| closeIcon | No | <code>let</code> | No | <code>any</code> | <code>undefined</code> | Specify the icon to render when the action panel is open.<br />Defaults to `&lt;Close size={20} /&gt;` | | closeIcon | No | <code>let</code> | No | <code>any</code> | <code>undefined</code> | Specify the icon to render when the action panel is open.<br />Defaults to `&lt;Close size={20} /&gt;` |
| text | No | <code>let</code> | No | <code>string</code> | <code>undefined</code> | Specify the text.<br />Alternatively, use the named slot "text" (e.g., `&lt;div slot="text"&gt;...&lt;/div&gt;`) | | text | No | <code>let</code> | No | <code>string</code> | <code>undefined</code> | Specify the text displayed next to the icon.<br />Alternatively, use the named slot "text" (e.g., `&lt;div slot="text"&gt;...&lt;/div&gt;`) |
| transition | No | <code>let</code> | No | <code>false &#124; import("svelte/transition").SlideParams</code> | <code>{ duration: 200 }</code> | Customize the panel transition (i.e., `transition:slide`).<br />Set to `false` to disable the transition | | iconDescription | No | <code>let</code> | No | <code>string</code> | <code>undefined</code> | Specify an icon tooltip. The tooltip will not be displayed<br />if either the `text` prop or a named slot="text" is used |
| preventCloseOnClickOutside | No | <code>let</code> | No | <code>boolean</code> | <code>false</code> | Set to `true` to prevent the panel from closing when clicking outside | | tooltipAlignment | No | <code>let</code> | No | <code>"start" &#124; "center" &#124; "end"</code> | <code>"center"</code> | Set the alignment of the tooltip relative to the icon.<br />Only applies when `iconDescription` is provided |
| transition | No | <code>let</code> | No | <code>false &#124; import("svelte/transition").SlideParams</code> | <code>{ duration: 200 }</code> | Customize the panel transition (i.e., `transition:slide`).<br />Set to `false` to disable the transition |
| preventCloseOnClickOutside | No | <code>let</code> | No | <code>boolean</code> | <code>false</code> | Set to `true` to prevent the panel from closing when clicking outside |
### Slots ### Slots

View file

@ -5882,7 +5882,7 @@
{ {
"name": "text", "name": "text",
"kind": "let", "kind": "let",
"description": "Specify the text.\nAlternatively, use the named slot \"text\" (e.g., `<div slot=\"text\">...</div>`)", "description": "Specify the text displayed next to the icon.\nAlternatively, use the named slot \"text\" (e.g., `<div slot=\"text\">...</div>`)",
"type": "string", "type": "string",
"isFunction": false, "isFunction": false,
"isFunctionDeclaration": false, "isFunctionDeclaration": false,
@ -5890,6 +5890,29 @@
"constant": false, "constant": false,
"reactive": false "reactive": false
}, },
{
"name": "iconDescription",
"kind": "let",
"description": "Specify an icon tooltip. The tooltip will not be displayed\nif either the `text` prop or a named slot=\"text\" is used",
"type": "string",
"isFunction": false,
"isFunctionDeclaration": false,
"isRequired": false,
"constant": false,
"reactive": false
},
{
"name": "tooltipAlignment",
"kind": "let",
"description": "Set the alignment of the tooltip relative to the icon.\nOnly applies when `iconDescription` is provided",
"type": "\"start\" | \"center\" | \"end\"",
"value": "\"center\"",
"isFunction": false,
"isFunctionDeclaration": false,
"isRequired": false,
"constant": false,
"reactive": false
},
{ {
"name": "ref", "name": "ref",
"kind": "let", "kind": "let",

View file

@ -22,12 +22,26 @@
export let closeIcon = Close; export let closeIcon = Close;
/** /**
* Specify the text. * Specify the text displayed next to the icon.
* Alternatively, use the named slot "text" (e.g., `<div slot="text">...</div>`) * Alternatively, use the named slot "text" (e.g., `<div slot="text">...</div>`)
* @type {string} * @type {string}
*/ */
export let text = undefined; export let text = undefined;
/**
* Specify an icon tooltip. The tooltip will not be displayed
* if either the `text` prop or a named slot="text" is used
* @type {string}
*/
export let iconDescription = undefined;
/**
* Set the alignment of the tooltip relative to the icon.
* Only applies when `iconDescription` is provided
* @type {"start" | "center" | "end"}
*/
export let tooltipAlignment = "center";
/** Obtain a reference to the button HTML element */ /** Obtain a reference to the button HTML element */
export let ref = null; export let ref = null;
@ -49,6 +63,17 @@
const dispatch = createEventDispatcher(); const dispatch = createEventDispatcher();
let refPanel = null; let refPanel = null;
$: hasIconOnly = iconDescription && !(text || $$slots.text);
$: buttonClass = [
hasIconOnly && "bx--btn bx--btn--primary",
hasIconOnly && "bx--tooltip__trigger bx--tooltip--a11y",
hasIconOnly && "bx--btn--icon-only bx--btn--icon-only--bottom",
hasIconOnly && `bx--tooltip--align-${tooltipAlignment}`,
$$restProps.class,
]
.filter(Boolean)
.join(" ");
</script> </script>
<svelte:window <svelte:window
@ -72,12 +97,16 @@
class:bx--header__action--active={isOpen} class:bx--header__action--active={isOpen}
class:bx--header__action--text={text} class:bx--header__action--text={text}
{...$$restProps} {...$$restProps}
class={buttonClass}
on:click on:click
on:click|stopPropagation={() => { on:click|stopPropagation={() => {
isOpen = !isOpen; isOpen = !isOpen;
dispatch(isOpen ? "open" : "close"); dispatch(isOpen ? "open" : "close");
}} }}
> >
{#if hasIconOnly}
<span class:bx--assistive-text={true}>{iconDescription}</span>
{/if}
{#if isOpen} {#if isOpen}
<slot name="closeIcon"> <slot name="closeIcon">
<svelte:component this={closeIcon} size={20} /> <svelte:component this={closeIcon} size={20} />

View file

@ -35,6 +35,8 @@
bind:isOpen bind:isOpen
on:open on:open
on:close on:close
iconDescription="Switcher"
tooltipAlignment="start"
transition={{ duration: 400, easing: quintOut }} transition={{ duration: 400, easing: quintOut }}
> >
<HeaderPanelLinks> <HeaderPanelLinks>

View file

@ -25,12 +25,26 @@ type $Props = {
closeIcon?: any; closeIcon?: any;
/** /**
* Specify the text. * Specify the text displayed next to the icon.
* Alternatively, use the named slot "text" (e.g., `<div slot="text">...</div>`) * Alternatively, use the named slot "text" (e.g., `<div slot="text">...</div>`)
* @default undefined * @default undefined
*/ */
text?: string; text?: string;
/**
* Specify an icon tooltip. The tooltip will not be displayed
* if either the `text` prop or a named slot="text" is used
* @default undefined
*/
iconDescription?: string;
/**
* Set the alignment of the tooltip relative to the icon.
* Only applies when `iconDescription` is provided
* @default "center"
*/
tooltipAlignment?: "start" | "center" | "end";
/** /**
* Obtain a reference to the button HTML element * Obtain a reference to the button HTML element
* @default null * @default null