Skip to content

Commit

Permalink
fix(Tooltip): v11 (next) accessibility refactor (#8324)
Browse files Browse the repository at this point in the history
* fix(Tooltip): add newTooltip

* chore: check-in work

* chore: check-in work

* feat(tooltip): add delay ms props to tooltip

* chore: check-in work

* feat(react): add useDelayedState hook

* chore(popover): update popover styles to work with tooltip

* chore(popover): revert story includeStories change

Co-authored-by: Josh Black <[email protected]>
  • Loading branch information
dakahn and joshblack authored May 21, 2021
1 parent 5e7720a commit 311c4ab
Show file tree
Hide file tree
Showing 7 changed files with 586 additions and 101 deletions.
272 changes: 180 additions & 92 deletions packages/components/src/components/popover/_popover.scss
Original file line number Diff line number Diff line change
Expand Up @@ -11,21 +11,34 @@

/// Popover component
/// @access private
/// @group popover
/// @group components
@mixin popover {
$popover-text-color: $text-primary;
$popover-caret-offset: 1rem;
$popover-box-shadow: 2px 2px 6px 0 rgba(0, 0, 0, 0.2);
$popover-offset: 8px;

.#{$prefix}--popover {
// Specify the distance between the popover and the trigger. This value must
// have a unit otherwise the `calc()` expression will not work
// stylelint-disable-next-line length-zero-no-unit
--cds-popover-offset: 0rem;

// Specify the distance that the caret should be offset from the side of the
// popover when not centered
--cds-popover-caret-offset: 1rem;

position: absolute;
z-index: z('floating');
display: none;
}

.#{$prefix}--popover--relative {
position: relative;
// We use a pseudo element inside of the popover to create a space between the
// target and the popover. This helps in situations like tooltips where you do
// not want the tooltip to disappear when the user moves from the target to
// the popover.
.#{$prefix}--popover::before {
position: absolute;
display: block;
content: '';
}

.#{$prefix}--popover--open {
Expand All @@ -40,7 +53,7 @@
max-width: rem(368px);
background-color: $layer;
border-radius: 2px;
color: $popover-text-color;
color: $text-primary;
}

.#{$prefix}--popover--light .#{$prefix}--popover-contents {
Expand All @@ -52,6 +65,10 @@
color: $text-inverse;
}

.#{$prefix}--popover--caret {
--cds-popover-offset: 0.5rem;
}

.#{$prefix}--popover--caret .#{$prefix}--popover-contents::before,
.#{$prefix}--popover--caret .#{$prefix}--popover-contents::after {
position: absolute;
Expand All @@ -64,167 +81,238 @@

.#{$prefix}--popover--caret .#{$prefix}--popover-contents::before {
z-index: -1;
box-shadow: $popover-box-shadow;
box-shadow: 2px 2px 6px 0 rgba(0, 0, 0, 0.2);
}

// The popover's tooltip is created by drawing two 8px x 8px boxes, one for
// rendering the box-shadow that the popover content uses and another for
// layering on top of this box to create an effect of a popover caret with a
// box-shadow. The layer with the box-shadow is rendered behind the popover
// content, while the other is rendered oabove of the popover content.
// content, while the other is rendered above of the popover content.

//-----------------------------------------------------------------------------
// Top
//-----------------------------------------------------------------------------
.#{$prefix}--popover--top,
.#{$prefix}--popover--top-left,
.#{$prefix}--popover--top-right {
.#{$prefix}--popover--top {
bottom: 0;
transform: translateY(calc(100% + #{$popover-offset}));
left: 50%;
transform: translate(-50%, calc(100% + var(--cds-popover-offset)));
}

.#{$prefix}--popover--caret.#{$prefix}--popover--top
.#{$prefix}--popover-contents::before,
.#{$prefix}--popover--caret.#{$prefix}--popover--top
.#{$prefix}--popover-contents::after {
@include place-caret(top) {
top: 0;
left: 50%;
transform: translate(-50%, -50%) rotate(45deg);
}

.#{$prefix}--popover--top-left .#{$prefix}--popover-contents {
margin-left: 0;
// Top-left
.#{$prefix}--popover--top-left {
bottom: 0;
left: 0;
transform: translateY(calc(100% + var(--cds-popover-offset)));
}

.#{$prefix}--popover--caret.#{$prefix}--popover--top-left
.#{$prefix}--popover-contents::before,
.#{$prefix}--popover--caret.#{$prefix}--popover--top-left
.#{$prefix}--popover-contents::after {
@include place-caret(top-left) {
top: 0;
left: $popover-caret-offset;
transform: translateY(-50%) rotate(45deg);
left: 0;
transform: translate(var(--cds-popover-caret-offset), -50%) rotate(45deg);
}

.#{$prefix}--popover--top-right .#{$prefix}--popover-contents {
margin-right: 0;
// Top-right
.#{$prefix}--popover--top-right {
right: 0;
bottom: 0;
transform: translateY(calc(100% + var(--cds-popover-offset)));
}

.#{$prefix}--popover--caret.#{$prefix}--popover--top-right
.#{$prefix}--popover-contents::before,
.#{$prefix}--popover--caret.#{$prefix}--popover--top-right
.#{$prefix}--popover-contents::after {
@include place-caret(top-right) {
top: 0;
right: $popover-caret-offset;
transform: translateY(-50%) rotate(45deg);
right: 0;
transform: translate(calc(-1 * var(--cds-popover-caret-offset)), -50%)
rotate(45deg);
}

// Hover area
.#{$prefix}--popover--top.#{$prefix}--popover::before,
.#{$prefix}--popover--top-left.#{$prefix}--popover::before,
.#{$prefix}--popover--top-right.#{$prefix}--popover::before {
top: 0;
right: 0;
left: 0;
height: var(--cds-popover-offset);
transform: translateY(-100%);
}

//-----------------------------------------------------------------------------
// Bottom
//-----------------------------------------------------------------------------
.#{$prefix}--popover--bottom,
.#{$prefix}--popover--bottom-left,
.#{$prefix}--popover--bottom-right {
top: 0;
transform: translateY(calc(-100% - #{$popover-offset}));
.#{$prefix}--popover--bottom {
bottom: 100%;
left: 50%;
transform: translate(-50%, calc(-1 * var(--cds-popover-offset)));
}

.#{$prefix}--popover--caret.#{$prefix}--popover--bottom
.#{$prefix}--popover-contents::before,
.#{$prefix}--popover--caret.#{$prefix}--popover--bottom
.#{$prefix}--popover-contents::after {
@include place-caret(bottom) {
bottom: 0;
left: 50%;
transform: translate(-50%, 50%) rotate(45deg);
}

.#{$prefix}--popover--caret.#{$prefix}--popover--bottom-left
.#{$prefix}--popover-contents::before,
.#{$prefix}--popover--caret.#{$prefix}--popover--bottom-left
.#{$prefix}--popover-contents::after {
// Bottom left
.#{$prefix}--popover--bottom-left {
bottom: 100%;
left: 0;
transform: translateY(calc(-1 * var(--cds-popover-offset)));
}

@include place-caret(bottom-left) {
bottom: 0;
left: $popover-caret-offset;
transform: translateY(50%) rotate(45deg);
left: 0;
transform: translate(var(--cds-popover-caret-offset), 50%) rotate(45deg);
}

.#{$prefix}--popover--caret.#{$prefix}--popover--bottom-right
.#{$prefix}--popover-contents::before,
.#{$prefix}--popover--caret.#{$prefix}--popover--bottom-right
.#{$prefix}--popover-contents::after {
right: $popover-caret-offset;
// Bottom right
.#{$prefix}--popover--bottom-right {
right: 0;
bottom: 100%;
transform: translateY(calc(-1 * var(--cds-popover-offset)));
}

@include place-caret(bottom-right) {
right: 0;
bottom: 0;
transform: translate(calc(-1 * var(--cds-popover-caret-offset)), 50%)
rotate(45deg);
}

// Hover area
.#{$prefix}--popover--bottom.#{$prefix}--popover::before,
.#{$prefix}--popover--bottom-left.#{$prefix}--popover::before,
.#{$prefix}--popover--bottom-right.#{$prefix}--popover::before {
right: 0;
bottom: 0;
transform: translateY(50%) rotate(45deg);
left: 0;
height: var(--cds-popover-offset);
transform: translateY(100%);
}

//-----------------------------------------------------------------------------
// Left
//-----------------------------------------------------------------------------
.#{$prefix}--popover--left,
.#{$prefix}--popover--left-top,
.#{$prefix}--popover--left-bottom {
margin-left: $popover-offset;
.#{$prefix}--popover--left {
top: 50%;
left: 100%;
transform: translate(var(--cds-popover-offset), -50%);
}

.#{$prefix}--popover--caret.#{$prefix}--popover--left
.#{$prefix}--popover-contents::before,
.#{$prefix}--popover--caret.#{$prefix}--popover--left
.#{$prefix}--popover-contents::after {
@include place-caret(left) {
top: 50%;
left: 0;
transform: translate(-50%, -50%) rotate(45deg);
}

.#{$prefix}--popover--caret.#{$prefix}--popover--left-bottom
.#{$prefix}--popover-contents::before,
.#{$prefix}--popover--caret.#{$prefix}--popover--left-bottom
.#{$prefix}--popover-contents::after {
bottom: $popover-caret-offset;
// Left top
.#{$prefix}--popover--left-top {
top: 0;
left: 100%;
transform: translateX($popover-offset);
}

@include place-caret(left-top) {
top: 0;
left: 0;
transform: translateX(-50%) rotate(45deg);
transform: translate(-50%, var(--cds-popover-caret-offset)) rotate(45deg);
}

.#{$prefix}--popover--caret.#{$prefix}--popover--left-top
.#{$prefix}--popover-contents::before,
.#{$prefix}--popover--caret.#{$prefix}--popover--left-top
.#{$prefix}--popover-contents::after {
top: $popover-caret-offset;
// Left bottom
.#{$prefix}--popover--left-bottom {
bottom: 0;
left: 100%;
transform: translateX(var(--cds-popover-offset));
}

@include place-caret(left-bottom) {
bottom: 0;
left: 0;
transform: translateX(-50%) rotate(45deg);
transform: translate(-50%, calc(-1 * var(--cds-popover-caret-offset)))
rotate(45deg);
}

// Hover area
.#{$prefix}--popover--left.#{$prefix}--popover::before,
.#{$prefix}--popover--left-top.#{$prefix}--popover::before,
.#{$prefix}--popover--left-bottom.#{$prefix}--popover::before {
top: 0;
bottom: 0;
left: 0;
width: var(--cds-popover-offset);
transform: translateX(-100%);
}

//-----------------------------------------------------------------------------
// Right
//-----------------------------------------------------------------------------
.#{$prefix}--popover--right,
.#{$prefix}--popover--right-top,
.#{$prefix}--popover--right-bottom {
margin-right: $popover-offset;
.#{$prefix}--popover--right {
top: 50%;
right: 100%;
transform: translate(calc(-1 * var(--cds-popover-offset)), -50%);
}

.#{$prefix}--popover--caret.#{$prefix}--popover--right
.#{$prefix}--popover-contents::before,
.#{$prefix}--popover--caret.#{$prefix}--popover--right
.#{$prefix}--popover-contents::after {
@include place-caret(right) {
top: 50%;
right: 0;
transform: translate(50%, -50%) rotate(45deg);
}

.#{$prefix}--popover--caret.#{$prefix}--popover--right-bottom
.#{$prefix}--popover-contents::before,
.#{$prefix}--popover--caret.#{$prefix}--popover--right-bottom
.#{$prefix}--popover-contents::after {
// Right top
.#{$prefix}--popover--right-top {
top: 0;
right: 100%;
transform: translateX(calc(-1 * var(--cds-popover-offset)));
}

@include place-caret(right-top) {
top: 0;
right: 0;
transform: translate(50%, var(--cds-popover-caret-offset)) rotate(45deg);
}

// Right bottom
.#{$prefix}--popover--right-bottom {
right: 100%;
bottom: 0;
transform: translateX(calc(-1 * var(--cds-popover-offset)));
}

@include place-caret(right-bottom) {
right: 0;
bottom: 0;
transform: translate(50%, calc(-1 * var(--cds-popover-caret-offset)))
rotate(45deg);
}

// Hover area
.#{$prefix}--popover--right.#{$prefix}--popover::before,
.#{$prefix}--popover--right-top.#{$prefix}--popover::before,
.#{$prefix}--popover--right-bottom.#{$prefix}--popover::before {
top: 0;
right: 0;
bottom: $popover-caret-offset;
transform: translateX(50%) rotate(45deg);
bottom: 0;
width: var(--cds-popover-offset);
transform: translateX(100%);
}
}

.#{$prefix}--popover--caret.#{$prefix}--popover--right-top
/// Helper for placing the caret inside a popover. The selectors here can get
/// distracting in the main stylesheet, but ultimately they target the ::before
/// and ::after pseudo-elements for the given direction. The @content block
/// passed in should appropriately position the caret for the given direction.
@mixin place-caret($direction) {
.#{$prefix}--popover--caret.#{$prefix}--popover--#{$direction}
.#{$prefix}--popover-contents::before,
.#{$prefix}--popover--caret.#{$prefix}--popover--right-top
.#{$prefix}--popover--caret.#{$prefix}--popover--#{$direction}
.#{$prefix}--popover-contents::after {
top: $popover-caret-offset;
right: 0;
transform: translateX(50%) rotate(45deg);
@content;
}
}

Expand Down
Loading

0 comments on commit 311c4ab

Please sign in to comment.