Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add tooltip and popover components #442

Merged
merged 5 commits into from
Aug 6, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/patternfly/components/Button/examples/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ export default () => {
</Example>
<Example heading="Links as Buttons" handlebars={ButtonLinkExampleRaw}>
{buttonLinkExample}
</Example>
</Example>
<Example heading="Button (Block Level)" handlebars={ButtonBlockTemplateRaw}>
{buttonBlockTemplate}
</Example>
Expand Down
15 changes: 3 additions & 12 deletions src/patternfly/components/ModalBox/examples/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,22 +19,13 @@ export default () => {

return (
<Documentation docs={Docs}>
<Example
heading="ModalBox Basic Example"
handlebars={ModalBoxBasicExampleRaw}
>
<Example heading="ModalBox Basic Example" handlebars={ModalBoxBasicExampleRaw}>
{modalBoxBasicExample}
</Example>
<Example
heading="ModalBox Large Example"
handlebars={ModalBoxLgExampleRaw}
>
<Example heading="ModalBox Large Example" handlebars={ModalBoxLgExampleRaw}>
{modalBoxLgExample}
</Example>
<Example
heading="ModalBox No Header Example"
handlebars={ModalBoxNoHeaderExampleRaw}
>
<Example heading="ModalBox No Header Example" handlebars={ModalBoxNoHeaderExampleRaw}>
{modalBoxNoHeaderExample}
</Example>
</Documentation>
Expand Down
31 changes: 31 additions & 0 deletions src/patternfly/components/Popover/docs/code.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
## Overview

A popover is used to provide contextual information for another component on click. The popover itself is made up of two main elements: arrow and content. The content element follows the pattern of the popover box component, with a close icon in the top right corner, as well as a header and body. One of the directional modifiers (`.pf-m-left`, `.pf-m-top`, etc.) is required on the popover component

## Accessibility

| Attribute | Applies to | Outcome |
| -- | -- | -- |
| `role="dialog"` | `.pf-c-popover` | Identifies the element that serves as the popover container. **Required**|
| `aria-labeledby="[id value of .pf-c-popover__header-title]"` | `.pf-c-popover` | Gives the popover an accessible name by referring to the element that provides the dialog title. **Required when .pf-c-popover__header-title is present** |
| `aria-label="[title of popover]"` | `.pf-c-popover` | Gives the popover an accessible name. **Required when .pf-c-popover__header-title is _not_ present** |
| `aria-describedby="[id value of applicable content]"` | `.pf-c-popover` | Gives the popover an accessible description by referring to the popover content that describes the primary message or purpose of the dialog. Not used if there is no static text that describes the popover. |
| `aria-popover="true"` | `.pf-c-popover` | Tells assistive technologies that the windows underneath the current popover are not available for interaction. **Required**|
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks like a Find/Replace mistake. 😉 I don't see aria-popover listed as an aria attribute.

I think you meant aria-modal="true" instead.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I opened #527 to track this one separately from this PR.

| `aria-label="Close Dialog"` | `.pf-c-popover__close .pf-c-button` | Provides an accessible name for the close button as it uses an icon instead of text. **Required**|
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@mcarrano Did you have a text string you wanted to use for the Close buttons on popovers? This looks like it was copied over from the Modal example, but I'm assuming we'd want something different for popovers.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jgiardino Do we even need the label to reference the object? What if we just say "Close?"

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That works for me. Would you want the same label for the ModalBox example? If so, we should open an issue to update that one, too.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, I think so @jgiardino . We shouldn't assume users will know what we mean when we use words like "dialog" or "popover." Aren't popovers some kind of puff pastry? :)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But that would go nicely with our food theme: kebab, hamburger, toast...

I opened an issue to capture the text string changes for both this and the modal so that we can track that change separately from this PR: #525



## Usage

| Class | Applied To | Outcome |
| -- | -- | -- |
| `.pf-c-popover` | `<div>` | Creates a popover. |
| `.pf-c-popover__arrow` | `.pf-c-popover` | Creates an arrow pointing towards the element the popover describes. ** Required.** |
| `.pf-c-popover__content` | `.pf-c-popover` | Creates the body of the popover. ** Required.** |
| `.pf-c-popover__close` | `.pf-c-popover__content` | Contains and positions the close icon in the top-right corner of the popover. ** Required.** |
| `.pf-c-popover__header` | `.pf-c-popover__content` | The header text area of the popover. |
| `.pf-c-popover__title` | `.pf-c-popover__header` | The actual popover title. |
| `.pf-c-popover__body` | `.pf-c-popover__content` | The popover's body text. ** Required.** |
| `.pf-m-left` | `.pf-c-popover` | Puts arrow to the left of the popover's content. |
| `.pf-m-right` | `.pf-c-popover` | Puts arrow to the right of the popover's content. |
| `.pf-m-top` | `.pf-c-popover` | Puts arrow on top of the popover's content. |
| `.pf-m-bottom` | `.pf-c-popover` | Puts arrow on the bottom of the popover's content. |
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These last four rows are accurate. The class .pf-m-top is applied to the element with class .pf-c-popover, but I think all the other rows (except for the first) are inaccurate. For example, .pf-c-popover__arrow is applied to a <div> that's a child of .pf-c-popover, but it's not applied to .pf-c-popover directly.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I opened #527 to track these changes separately from this PR.

3 changes: 3 additions & 0 deletions src/patternfly/components/Popover/docs/design.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# design md file

TODO: design documentation
28 changes: 28 additions & 0 deletions src/patternfly/components/Popover/examples/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import React from 'react';
import Documentation from '@siteComponents/Documentation';
import Example from '@siteComponents/Example';

import PopoverExampleRaw from '!raw!./popover-example.hbs';

import PopoverExample from './popover-example.hbs';

import docs from '../docs/code.md';
import '../styles.scss';

export const Docs = docs;

export default () => {
const popoverExample = PopoverExample();

return (
<Documentation docs={Docs}>
<Example
className="is-popover"
heading="Popover"
handlebars={PopoverExampleRaw}
>
{popoverExample}
</Example>
</Documentation>
);
};
32 changes: 32 additions & 0 deletions src/patternfly/components/Popover/examples/popover-example.hbs
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
{{#> popover direction="pf-m-right" header="hello"}}
World! I am a popover
{{#*inline "popover-parent"}}
{{#> button btnClass='pf-m-primary'}}
parent
{{/button}}
{{/inline}}
{{/popover}}
{{#> popover direction="pf-m-top" header="I can have a long title"}}
And also very, very, very, very, very, very, very, very, very, very, very, very, very, very, very, very, very, very, very, very long body text.
{{#*inline "popover-parent"}}
{{#> button btnClass='pf-m-primary'}}
parent
{{/button}}
{{/inline}}
{{/popover}}
{{#> popover direction="pf-m-bottom"}}
Or no body text, and be short
{{#*inline "popover-parent"}}
{{#> button btnClass='pf-m-primary'}}
parent
{{/button}}
{{/inline}}
{{/popover}}
{{#> popover direction="pf-m-left"}}
!
{{#*inline "popover-parent"}}
{{#> button btnClass='pf-m-primary'}}
parent
{{/button}}
{{/inline}}
{{/popover}}
23 changes: 23 additions & 0 deletions src/patternfly/components/Popover/popover.hbs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<div class="Preview__overlay">
<div class="Preview__overlay-container {{direction}}">
<div class="pf-c-popover {{direction}}">
<div class="pf-c-popover__arrow"></div>
<div class="pf-c-popover__content" role="dialog" aria-modal="true" aria-labelledby="popover-title" aria-describedby="popover-description">
<div class="pf-c-popover__close">
<button class="pf-c-button pf-m-action" aria-label="Close Dialog">
<i class="fas fa-times"></i>
</button>
</div>
<header class="pf-c-popover__header">
<h1 class="pf-c-popover__header-title" id="popover-title">
{{header}}
</h1>
</header>
<div class="pf-c-popover__body" id="popover-description">
{{> @partial-block}}
</div>
</div>
</div>
</div>
{{#> popover-parent }} {{/popover-parent}}
</div>
145 changes: 145 additions & 0 deletions src/patternfly/components/Popover/styles.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
@import "../../patternfly-utilities";

.pf-c-popover {
// Component variables
--pf-c-popover--MinWidth: pf-size-prem(100px);
--pf-c-popover--MaxWidth: pf-size-prem(300px);
--pf-c-popover--BoxShadow: var(--pf-global--BoxShadow);
// Set margin to arrow width for placement
--pf-c-popover--MarginBottom: var(--pf-global--arrow--width-lg);
--pf-c-popover--MarginTop: var(--pf-global--arrow--width-lg);
--pf-c-popover--MarginRight: var(--pf-global--arrow--width-lg);
--pf-c-popover--MarginLeft: var(--pf-global--arrow--width-lg);

// Content variables
--pf-c-popover__content--BackgroundColor: var(--pf-global--BackgroundColor--100);

// Arrow variables
--pf-c-popover__arrow--Width: var(--pf-global--arrow--width-lg);
// Set arrow margin to half arrow width for placement
--pf-c-popover__arrow--Margin: var(--pf-global--arrow--width-lg) / 2;
--pf-c-popover__arrow--BoxShadow: var(--pf-global--BoxShadow);
--pf-c-popover__arrow--BackgroundColor: var(--pf-global--BackgroundColor--100);
// used in the directional modifiers for placement
--pf-c-popover__arrow-half-size: var(--pf-global--arrow--width) / 2;

// Close container variables
--pf-c-popover__close--Top: var(--pf-global--spacer--sm);
--pf-c-popover__close--Right: var(--pf-global--spacer--md);

// Header variables
--pf-c-popover__header--PaddingTop: var(--pf-global--spacer--xl);
--pf-c-popover__header--PaddingRight: var(--pf-global--spacer--xl);
--pf-c-popover__header--PaddingBottom: var(--pf-global--spacer--sm);
--pf-c-popover__header--PaddingLeft: var(--pf-global--spacer--xl);

// Header title variables
--pf-c-popover__header-title--FontSize: var(--pf-c-title--m-3xl--FontSize);
--pf-c-popover__header-title--FontWeight: var(--pf-c-title--m-3xl--FontWeight);
--pf-c-popover__header-title--LineHeight: var(--pf-c-title--m-3xl--LineHeight);

// Body variables
--pf-c-popover__body--PaddingTop: var(--pf-global--spacer--sm);
--pf-c-popover__body--PaddingRight: var(--pf-global--spacer--xl);
--pf-c-popover__body--PaddingBottom: var(--pf-global--spacer--xl);
--pf-c-popover__body--PaddingLeft: var(--pf-global--spacer--xl);
--pf-c-popover__body--MarginTop: var(--pf-global--spacer--xl);

$half-size: $pf-global--arrow--width-lg / 2;

position: relative;
min-width: var(--pf-c-popover--MinWidth);
max-width: var(--pf-c-popover--MaxWidth);
box-shadow: var(--pf-c-popover--BoxShadow);

&__content {
position: relative;
display: flex;
flex-direction: column;
background-color: var(--pf-c-popover__content--BackgroundColor);
}

&__arrow {
position: absolute;
// Popover arrow is square, sharing width value to prevent positioning errors
width: var(--pf-c-popover__arrow--Width);
height: var(--pf-c-popover__arrow--Width);
margin: var(--pf-c-popover__arrow--Margin);
pointer-events: none;
background-color: var(--pf-c-popover__arrow--BackgroundColor);
box-shadow: var(--pf-c-popover__arrow--BoxShadow);
transform: rotate(45deg);
}

&__close {
position: absolute;
top: var(--pf-c-popover__close--Top);
right: var(--pf-c-popover__close--Right);
}

// Header
&__header {
flex: 0 0 auto;
padding: var(--pf-c-popover__header--PaddingTop) var(--pf-c-popover__header--PaddingRight) var(--pf-c-popover__header--PaddingBottom) var(--pf-c-popover__header--PaddingLeft);

// Header title
&-title {
font-size: var(--pf-c-popover__header-title--FontSize);
font-weight: var(--pf-c-popover__header-title--FontWeight);
line-height: var(--pf-c-popover__header-title--LineHeight);
}
}

// Body
&__body {
flex: 1 1 auto;
padding: var(--pf-c-popover__body--PaddingTop) var(--pf-c-popover__body--PaddingRight) var(--pf-c-popover__body--PaddingBottom) var(--pf-c-popover__body--PaddingLeft);
// Adding margin top here for no header being present. When the header is present, margin-top is removed
margin-top: var(--pf-c-popover__body--MarginTop);
overflow-x: hidden;
overflow-y: auto;
overscroll-behavior: contain;
word-break: break-word;
}

// Removing top margin when header is present
&__header + &__body {
margin-top: 0;
}

&.pf-m-top {
margin-bottom: var(--pf-c-popover--MarginBottom);
}

&.pf-m-bottom {
margin-top: var(--pf-c-popover--MarginTop);
}

&.pf-m-left {
margin-right: var(--pf-c-popover--MarginRight);
}

&.pf-m-right {
margin-left: var(--pf-c-popover--MarginLeft);
}

&.pf-m-top > &__arrow {
bottom: calc(var(--pf-c-popover__arrow-half-size) * -1);
left: calc(50% - var(--pf-c-popover__arrow-half-size));
}

&.pf-m-bottom > &__arrow {
top: calc(var(--pf-c-popover__arrow-half-size) * -1);
left: calc(50% - var(--pf-c-popover__arrow-half-size));
}

&.pf-m-right > &__arrow {
top: calc(50% - var(--pf-c-popover__arrow-half-size));
left: calc(var(--pf-c-popover__arrow-half-size) * -1);
}

&.pf-m-left > &__arrow {
top: calc(50% - var(--pf-c-popover__arrow-half-size));
right: calc(var(--pf-c-popover__arrow-half-size) * -1);
}
}
22 changes: 22 additions & 0 deletions src/patternfly/components/Tooltip/docs/code.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
## Overview

A tooltip is used to provide contextual information for another component on hover. The tooltip itself is made up of two elements: arrow and content. One of the directional modifiers (`.pf-m-left`, `.pf-m-top`, etc.) is required on the tooltip component

## Accessibility

| Attribute | Applied To | Outcome |
| -- | -- | -- |
| `aria-describedby="[id value of applicable content]"` | `.pf-c-tooltip` | Gives the tooltip an accessible description by referring to the tooltip content that describes the primary message or purpose of the dialog. Not used if there is no static text that describes the popover. |


## Usage

| Class | Applied To | Outcome |
| -- | -- | -- |
| `.pf-c-tooltip` | `<div>` | Creates a tooltip. |
| `.pf-c-tooltip__arrow` | `.pf-c-tooltip` | Creates an arrow pointing towards the element the tooltip describes. ** Required.** |
| `.pf-c-tooltip__content` | `.pf-c-tooltip` | Creates the body of the tooltip. ** Required.** |
| `.pf-m-left` | `.pf-c-tooltip` | Puts arrow to the left of the tooltip's content. |
| `.pf-m-right` | `.pf-c-tooltip` | Puts arrow to the right of the tooltip's content. |
| `.pf-m-top` | `.pf-c-tooltip` | Puts arrow on top of the tooltip's content. |
| `.pf-m-bottom` | `.pf-c-tooltip` | Puts arrow on the bottom of the tooltip's content. |
3 changes: 3 additions & 0 deletions src/patternfly/components/Tooltip/docs/design.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# design md file

TODO: design documentation
27 changes: 27 additions & 0 deletions src/patternfly/components/Tooltip/examples/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import React from 'react';
import Documentation from '@siteComponents/Documentation';
import Example from '@siteComponents/Example';

import TooltipExampleRaw from '!raw!./tooltip-example.hbs';

import TooltipExample from './tooltip-example.hbs';

import docs from '../docs/code.md';
import '../styles.scss';

export const Docs = docs;

export default () => {
const tooltipExample = TooltipExample();
return (
<Documentation docs={Docs}>
<Example
className="is-tooltip"
heading="Tooltip"
handlebars={TooltipExampleRaw}
>
{tooltipExample}
</Example>
</Documentation>
);
};
32 changes: 32 additions & 0 deletions src/patternfly/components/Tooltip/examples/tooltip-example.hbs
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
{{#> tooltip direction="pf-m-right"}}
Hello!
{{#*inline "tooltip-parent"}}
{{#> button btnClass='pf-m-primary' btnAttributes="aria-describedby=\"tooltip-description\" "}}
parent
{{/button}}
{{/inline}}
{{/tooltip}}
{{#> tooltip direction="pf-m-top"}}
I am a tooltip component!
{{#*inline "tooltip-parent"}}
{{#> button btnClass='pf-m-primary' btnAttributes="aria-describedby=\"tooltip-description\" "}}
parent
{{/button}}
{{/inline}}
{{/tooltip}}
{{#> tooltip direction="pf-m-left"}}
I can container a very, very, very, very, very, very, very, very, very, very, very, very, very, very, very, very, very, very, long piece of content. As well as very short.
{{#*inline "tooltip-parent"}}
{{#> button btnClass='pf-m-primary' btnAttributes="aria-describedby=\"tooltip-description\" "}}
parent
{{/button}}
{{/inline}}
{{/tooltip}}
{{#> tooltip direction="pf-m-bottom"}}
!
{{#*inline "tooltip-parent"}}
{{#> button btnClass='pf-m-primary' btnAttributes="aria-describedby=\"tooltip-description\" "}}
parent
{{/button}}
{{/inline}}
{{/tooltip}}
Loading