-
Notifications
You must be signed in to change notification settings - Fork 8
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Nimble tooltip implementation (#608)
# Pull Request ## π€¨ Rationale Initial implementation for nimble-tooltip, intended to get the default tooltip working and implemented. See #309 ## π©βπ» Implementation Includes only the default tooltip state, with the other states to be implemented in the future. See tooltip spec, [API section](https://github.com/ni/nimble/blob/c1031e33f9f62748f48ec0ce69ea895dde39327a/packages/nimble-components/src/tooltip/tooltip.spec.md). Styling and implementation will need to be updated in the future in order to make the error and information states functional. Other questions listed in the [open issues section](https://github.com/ni/nimble/blob/c1031e33f9f62748f48ec0ce69ea895dde39327a/packages/nimble-components/src/tooltip/tooltip.spec.md) will also be addressed in future updates. ## π§ͺ Testing Added unit tests and storybook matrix pages. ## β Checklist - [x] I have updated the project documentation to reflect my changes or determined no changes are needed.
- Loading branch information
Showing
10 changed files
with
275 additions
and
0 deletions.
There are no files selected for viewing
7 changes: 7 additions & 0 deletions
7
change/@ni-nimble-components-8a80cab3-e911-4d17-8e6e-0626017dc72c.json
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
{ | ||
"type": "minor", | ||
"comment": "Implementation, styling, and tests for the 'default' state of the nimble-tooltip.", | ||
"packageName": "@ni/nimble-components", | ||
"email": "[email protected]", | ||
"dependentChangeType": "patch" | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
import { | ||
DesignSystem, | ||
Tooltip as FoundationTooltip, | ||
tooltipTemplate as template | ||
} from '@microsoft/fast-foundation'; | ||
import { styles } from './styles'; | ||
|
||
declare global { | ||
interface HTMLElementTagNameMap { | ||
'nimble-tooltip': Tooltip; | ||
} | ||
} | ||
|
||
/** | ||
* A nimble-styled tooltip control. | ||
*/ | ||
export class Tooltip extends FoundationTooltip {} | ||
|
||
const nimbleTooltip = Tooltip.compose({ | ||
baseName: 'tooltip', | ||
baseClass: FoundationTooltip, | ||
template, | ||
styles | ||
}); | ||
|
||
DesignSystem.getOrCreate().withPrefix('nimble').register(nimbleTooltip()); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
import { css } from '@microsoft/fast-element'; | ||
import { display } from '@microsoft/fast-foundation'; | ||
import { | ||
borderRgbPartialColor, | ||
tooltipCaptionFont, | ||
tooltipCaptionFontColor, | ||
borderWidth, | ||
tooltipBackgroundColor, | ||
smallPadding, | ||
standardPadding, | ||
popupBoxShadowColor | ||
} from '../theme-provider/design-tokens'; | ||
|
||
export const styles = css` | ||
${display('inline-flex')} | ||
:host { | ||
font: ${tooltipCaptionFont}; | ||
color: ${tooltipCaptionFontColor}; | ||
text-align: left; | ||
} | ||
.tooltip { | ||
box-sizing: border-box; | ||
flex-shrink: 0; | ||
max-width: 440px; | ||
border: ${borderWidth} solid rgba(${borderRgbPartialColor}, 0.3); | ||
box-shadow: 0px 3px 4px ${popupBoxShadowColor}; | ||
background-color: ${tooltipBackgroundColor}; | ||
padding-bottom: 6px; | ||
padding-left: calc(${standardPadding} / 2); | ||
padding-right: calc(${standardPadding} / 2); | ||
padding-top: ${smallPadding}; | ||
display: inline-flex; | ||
} | ||
`; |
93 changes: 93 additions & 0 deletions
93
packages/nimble-components/src/tooltip/tests/tooltip-matrix.stories.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,93 @@ | ||
import type { Meta, Story } from '@storybook/html'; | ||
import { withXD } from 'storybook-addon-xd-designs'; | ||
import { html, ViewTemplate } from '@microsoft/fast-element'; | ||
import { | ||
createMatrix, | ||
sharedMatrixParameters | ||
} from '../../utilities/tests/matrix'; | ||
import { createFixedThemeStory } from '../../utilities/tests/storybook'; | ||
import { backgroundStates } from '../../utilities/tests/states'; | ||
import '../../all-components'; | ||
import { | ||
bodyFont, | ||
bodyFontColor, | ||
borderColor | ||
} from '../../theme-provider/design-tokens'; | ||
|
||
const metadata: Meta = { | ||
title: 'Tests/Tooltip', | ||
decorators: [withXD], | ||
parameters: { | ||
...sharedMatrixParameters(), | ||
design: { | ||
artboardUrl: | ||
'https://xd.adobe.com/view/8ce280ab-1559-4961-945c-182955c7780b-d9b1/screen/044414d7-1714-40f2-9679-2ce2c8202d1c/specs/' | ||
} | ||
} | ||
}; | ||
|
||
export default metadata; | ||
|
||
const valueStates = [ | ||
['shortText', 'Hello'], | ||
[ | ||
'longText', | ||
'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident.' | ||
] | ||
] as const; | ||
type ValueState = typeof valueStates[number]; | ||
|
||
const component = ([valueName, valueValue]: ValueState): ViewTemplate => html` | ||
<style> | ||
.container { | ||
display: inline-flex; | ||
padding: 120px; | ||
justify-content: center; | ||
text-align: center; | ||
} | ||
.anchorDiv { | ||
border: 1px solid var(${borderColor.cssCustomProperty}); | ||
font: var(${bodyFont.cssCustomProperty}); | ||
color: var(${bodyFontColor.cssCustomProperty}); | ||
} | ||
.tooltip { | ||
justify-content: center; | ||
} | ||
</style> | ||
<div class="container"> | ||
<div class="anchorDiv" id="${() => `${valueName}`}">${valueName}</div> | ||
<nimble-tooltip | ||
anchor="${() => `${valueName}`}" | ||
visible | ||
position="bottom" | ||
auto-update-mode="auto" | ||
> | ||
${() => valueValue} | ||
</nimble-tooltip> | ||
</div> | ||
`; | ||
|
||
const [ | ||
lightThemeWhiteBackground, | ||
colorThemeDarkGreenBackground, | ||
darkThemeBlackBackground | ||
] = backgroundStates; | ||
|
||
export const tooltipLightThemeWhiteBackground: Story = createFixedThemeStory( | ||
createMatrix(component, [valueStates]), | ||
lightThemeWhiteBackground | ||
); | ||
|
||
export const tooltipColorThemeDarkGreenBackground: Story = createFixedThemeStory( | ||
createMatrix(component, [valueStates]), | ||
colorThemeDarkGreenBackground | ||
); | ||
|
||
export const tooltipDarkThemeBlackBackground: Story = createFixedThemeStory( | ||
createMatrix(component, [valueStates]), | ||
darkThemeBlackBackground | ||
); |
17 changes: 17 additions & 0 deletions
17
packages/nimble-components/src/tooltip/tests/tooltip.spec.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
import { | ||
DesignSystem, | ||
Tooltip as FoundationTooltip | ||
} from '@microsoft/fast-foundation'; | ||
import { Tooltip } from '..'; | ||
|
||
describe('Tooltip', () => { | ||
it('should have its tag returned by tagFor(FoundationTooltip)', () => { | ||
expect(DesignSystem.tagFor(FoundationTooltip)).toBe('nimble-tooltip'); | ||
}); | ||
|
||
it('can construct an element instance', () => { | ||
expect(document.createElement('nimble-tooltip')).toBeInstanceOf( | ||
Tooltip | ||
); | ||
}); | ||
}); |
89 changes: 89 additions & 0 deletions
89
packages/nimble-components/src/tooltip/tests/tooltip.stories.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,89 @@ | ||
import { html } from '@microsoft/fast-element'; | ||
import type { Meta, StoryObj } from '@storybook/html'; | ||
import { withXD } from 'storybook-addon-xd-designs'; | ||
import type { AutoUpdateMode } from '@microsoft/fast-foundation'; | ||
import { createUserSelectedThemeStory } from '../../utilities/tests/storybook'; | ||
import '../../all-components'; | ||
import { | ||
borderColor, | ||
bodyFont, | ||
bodyFontColor | ||
} from '../../theme-provider/design-tokens'; | ||
|
||
interface TooltipArgs { | ||
visible: boolean; | ||
delay: number; | ||
tooltip: string; | ||
autoUpdateMode: AutoUpdateMode; | ||
} | ||
|
||
const metadata: Meta<TooltipArgs> = { | ||
title: 'Tooltip', | ||
decorators: [withXD], | ||
parameters: { | ||
docs: { | ||
description: { | ||
component: | ||
'<b>Experimental - The tooltip is still in development. It will be ready for app use soon.</b>Per [W3C](https://w3c.github.io/aria-practices/#tooltip) βΒ A tooltip is a popup that displays information related to an element when the element receives keyboard focus or the mouse hovers over it. It typically appears after a small delay and disappears when Escape is pressed or on mouse out. <br><br> It is recommended to set up aria-describedby, an accessibility feature that uses element IDs to set the description of one element based on another element. To leverage this, the anchor element (button, text, icon, etc.) of the tooltip must have `aria-describedby= "name"` in its attributes, where `name` is the ID of the nimble-tooltip. More information can be found in the [aria-describedby docs](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Attributes/aria-describedby).' | ||
} | ||
}, | ||
design: { | ||
artboardUrl: | ||
'https://xd.adobe.com/view/8ce280ab-1559-4961-945c-182955c7780b-d9b1/screen/044414d7-1714-40f2-9679-2ce2c8202d1c/specs/' | ||
}, | ||
actions: { | ||
handles: ['dismiss'] | ||
} | ||
}, | ||
render: createUserSelectedThemeStory(html<TooltipArgs>` | ||
<style> | ||
.container { | ||
width: 100px; | ||
height: 50px; | ||
} | ||
.anchorDiv { | ||
border: 1px solid var(${borderColor.cssCustomProperty}); | ||
font: var(${bodyFont.cssCustomProperty}); | ||
color: var(${bodyFontColor.cssCustomProperty}); | ||
} | ||
</style> | ||
<div class="container"> | ||
<div class="anchorDiv" id="anchor" aria-describedby="ariaAnchor"> | ||
Text, Button, Icon, etc. | ||
</div> | ||
<nimble-tooltip | ||
anchor="anchor" | ||
?visible="${x => x.visible}" | ||
delay="${x => x.delay}" | ||
auto-update-mode="${x => x.autoUpdateMode}" | ||
id="ariaAnchor" | ||
> | ||
${x => x.tooltip} | ||
</nimble-tooltip> | ||
</div> | ||
`), | ||
args: { | ||
visible: false, | ||
tooltip: 'Tooltip label', | ||
delay: 300, | ||
autoUpdateMode: 'auto' | ||
}, | ||
argTypes: { | ||
autoUpdateMode: { | ||
options: { anchor: 'anchor', auto: 'auto' }, | ||
control: { type: 'radio' }, | ||
description: | ||
'Controls when the tooltip updates its position. The default is `anchor`, which only updates when the anchor is resized. `auto` will update on scroll/resize events.' | ||
}, | ||
delay: { | ||
description: | ||
'The delay in milliseconds before a tooltip is shown after a hover event' | ||
} | ||
} | ||
}; | ||
|
||
export default metadata; | ||
|
||
export const tooltip: StoryObj<TooltipArgs> = {}; |