-
Notifications
You must be signed in to change notification settings - Fork 14
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Adds a `post-tooltip` component. - Why `[popover]`?: using the popover attribute (with polyfill) has several advantages. In supporting browsers, the tooltip will be lifted to the top-layer, ignoring `overflow: hidden` and the `z-index` order. This ensures that tooltips are always displayed on top of everything and never cut off. Until all browsers support the popover API (ETA is end of 2023), a polyfill without these qualities (but some decent standards) is needed. - Why `[data-tooltip-trigger]`? This is a custom attribute in place of `popovertargetaction`, an attribute that can be used to trigger a popover, but reacts to clicks only. In this situation we want to show the popover on hover, focus and long-press. This behavior is in consideration with `popovertargetaction="interest"`, but is not implemented at the moment. To be able to patch this functionality without interference from clicks, there is no `popovertargetaction` on the trigger element. - floating-ui: this component uses [floating-ui](https://floating-ui.com/docs/getting-started), the successor to `@popperjs/core`, for positioning. This low-level library can be used to dynamically position the tooltip and the corresponding arrow and can be customised in every imaginable way while leaving a pretty small footprint. - No snapshot tests: not sure how to test something that only shows up on user interaction - No animation: had some trouble implementing an animation that was compatible with the polyfill as well as the default API. Suggestion: wait till Design provides a concept and the popover API is standardised --------- Co-authored-by: imagoiq <[email protected]>
- Loading branch information
Showing
14 changed files
with
689 additions
and
308 deletions.
There are no files selected for viewing
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,6 @@ | ||
--- | ||
'@swisspost/design-system-documentation': minor | ||
'@swisspost/design-system-components': minor | ||
--- | ||
|
||
Added the `post-tooltip` component. |
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,54 @@ | ||
describe('tooltips', () => { | ||
describe('default', () => { | ||
beforeEach(() => { | ||
cy.getComponent('tooltip', 'multiple'); | ||
cy.get('button[data-tooltip-target="tooltip-multiple"]:first-of-type').as('target1'); | ||
cy.get('button[data-tooltip-target="tooltip-multiple"]:last-of-type').as('target2'); | ||
cy.get('#tooltip-multiple').shadow().find('div[popover]').as('tooltip'); | ||
}); | ||
|
||
it('should display a tooltip', () => { | ||
cy.get('@tooltip').should('not.be.visible'); | ||
cy.get('@target2').focus(); | ||
cy.get('@tooltip').should('be.visible'); | ||
cy.get('@target2').blur(); | ||
cy.get('@tooltip').should('not.be.visible'); | ||
}); | ||
|
||
it('tooltip placement right', () => { | ||
cy.get('#tooltip-multiple').invoke('attr', 'placement', 'right'); | ||
cy.get('@target2').focus(); | ||
cy.wait(10); | ||
cy.get('@tooltip') | ||
.should('have.css', 'left') | ||
.then((v: any) => { | ||
expect(parseInt(v)).to.be.greaterThan(150); | ||
}); | ||
}); | ||
}); | ||
|
||
describe('non-focusable element', () => { | ||
beforeEach(() => { | ||
cy.getComponent('tooltip', 'non-focusable'); | ||
cy.get('cite[data-tooltip-target="tooltip-non-focusable"]').as('target'); | ||
}); | ||
|
||
it('should add tabindex', () => { | ||
cy.get('@target').should('have.attr', 'tabindex').should('eq', '0'); | ||
}); | ||
}); | ||
|
||
describe('aria', () => { | ||
beforeEach(() => { | ||
cy.getComponent('tooltip', 'multiple'); | ||
cy.get('button[data-tooltip-target="tooltip-multiple"]:first-of-type').as('target1'); | ||
cy.get('@target1').invoke('attr', 'aria-describedby', 'existing-value'); | ||
}); | ||
|
||
it('should append aria-describedby without deleting existing values', () => { | ||
cy.get('@target1') | ||
.should('have.attr', 'aria-describedby') | ||
.should('eq', 'existing-value tooltip-multiple'); | ||
}); | ||
}); | ||
}); |
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
59 changes: 59 additions & 0 deletions
59
packages/components/src/components/post-tooltip/post-tooltip.scss
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,59 @@ | ||
@use 'sass:meta'; | ||
@use 'sass:math'; | ||
@use '@swisspost/design-system-styles/variables/color'; | ||
@use '@swisspost/design-system-styles/variables/commons'; | ||
@use '@swisspost/design-system-styles/variables/spacing'; | ||
@use '@swisspost/design-system-styles/mixins/color' as color-mx; | ||
|
||
// Puts polyfilled styles in a separate layer so they are easy to override | ||
// Can be removed as soon as popover is supported by all major browsers | ||
// https://caniuse.com/?search=popover | ||
@layer polyfill { | ||
@include meta.load-css('@oddbird/popover-polyfill/dist/popover.css'); | ||
} | ||
|
||
:host { | ||
// Sets default background color | ||
@include color-mx.colored-background(color.$gray-80); | ||
} | ||
|
||
div { | ||
position: absolute; | ||
z-index: commons.$zindex-tooltip; | ||
|
||
width: max-content; | ||
max-width: 30ch; | ||
margin: 0; | ||
padding: spacing.$size-micro spacing.$size-mini; | ||
|
||
color: inherit; | ||
background-color: inherit; | ||
border-color: transparent; // Keeping the default border for HCM | ||
border-radius: commons.$border-radius; | ||
|
||
// Keeps the little arrow visible | ||
overflow: visible; | ||
|
||
// Prevents instantly closing tooltips because the opening tooltip opens under the cursor and the trigger gets a mouseleave | ||
pointer-events: none; | ||
} | ||
|
||
.arrow { | ||
position: absolute; | ||
// Diagonale of 16px -> 1rem -> 1/1.41 = ~0.7 | ||
// https://www.omnicalculator.com/math/square-diagonal?c=CHF&v=hide:0,diagonal:16!cm | ||
width: math.div(spacing.$spacer, math.sqrt(2)); | ||
aspect-ratio: 1/1; | ||
background-color: inherit; | ||
rotate: 45deg; | ||
pointer-events: none; | ||
z-index: -1; | ||
|
||
// High contrast mode borders | ||
border-right: 2px solid transparent; | ||
border-bottom: 2px solid transparent; | ||
} | ||
|
||
.bg-yellow { | ||
@include color-mx.colored-background(color.$yellow); | ||
} |
Oops, something went wrong.