Skip to content

Commit

Permalink
Merge pull request #397 from dcos-labs/mp/feat/DCOS-58216-segmented-c…
Browse files Browse the repository at this point in the history
…ontrol-tooltip-content

DCOS-58216: add tooltipContent prop to SegmentedControlButton
  • Loading branch information
mperrotti authored Sep 4, 2019
2 parents fe5c211 + c8bac68 commit 958bc36
Show file tree
Hide file tree
Showing 7 changed files with 122 additions and 41 deletions.
6 changes: 5 additions & 1 deletion packages/dropdownable/components/Dropdownable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,7 @@ class Dropdownable extends React.Component<DropdownableProps, State> {
windowDimensions
): Direction {
// Determine if there is enough space in each direction to fit dropdown
const triggerCenter = childBounds.width / 2 + childBounds.left;
const possibleVertDirections = {
top: dropdownDimensions.height <= childBounds.top,
bottom:
Expand All @@ -181,7 +182,10 @@ class Dropdownable extends React.Component<DropdownableProps, State> {
};
const possibleHorizDirections = {
left: dropdownDimensions.width >= childBounds.right,
right: dropdownDimensions.width <= childBounds.right
right: dropdownDimensions.width <= childBounds.right,
center:
triggerCenter - dropdownDimensions.width / 2 > 0 &&
triggerCenter + dropdownDimensions.width / 2 < windowDimensions.width
};

// Pick the first available preference
Expand Down
6 changes: 5 additions & 1 deletion packages/segmentedControl/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,13 @@ A segmented control is group of two or more buttons that represent a list of opt

A segmented control can be a good alternative to a dropdown or a select input because it requires less interactions to make a selection. They can be a good alternative to a group of radio buttons when there are space limitations or if form controls look visually awkward.

## Segment tooltips
Each segmented control button can also render a tooltip when the user hovers. Show tooltip content to show "nice-to-have" information about a segment button.

## Icons in button labels
Button labels can contain icons. When using an icon in a button label, the default icon size to use is `iconSizeXs`.

When an icon is the only button label content, be sure to provide text content to keep the buttons screenreader accessible. If you're using the `Icon` component to render the icon, this is as simple as passing a string to the `ariaLabel` prop.
When an icon is the only button label content, be sure to provide text content to keep the buttons screenreader accessible. If you're using the `Icon` component to render the icon, this is as simple as passing a string to the `ariaLabel` prop. It's also recommended to show a tooltip when an icon is the only button label content.

## Do's and Dont's

Expand All @@ -18,3 +21,4 @@ When an icon is the only button label content, be sure to provide text content t
### Don't
- Use a segmented control for navigation instead of Tabs
- Put long strings in the segments
- Rely completely on the tooltip content to convey what a segment button does
31 changes: 28 additions & 3 deletions packages/segmentedControl/components/SegmentedControlButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,12 @@ import shortid from "shortid";
import {
segmentedControlButton,
segmentedControlButtonActive,
staticKeyboardFocusClassname
staticKeyboardFocusClassname,
segmentedControlButtonInner
} from "../style";
import { visuallyHidden, display } from "../../shared/styles/styleUtils";
import FocusStyleManager from "../../shared/components/FocusStyleManager";
import { Tooltip } from "../../tooltip";

export interface SegmentedControlButtonProps {
/**
Expand All @@ -30,12 +32,35 @@ export interface SegmentedControlButtonProps {
* The value of the input
*/
value: string;
/**
* Content that appears in a Tooltip when a users hovers the button
*/
tooltipContent?: React.ReactNode;
}

const SegmentedControlButton: React.SFC<
SegmentedControlButtonProps
> = props => {
const { id = shortid.generate(), isActive, onChange, name, value } = props;
const {
id = shortid.generate(),
isActive,
onChange,
name,
value,
tooltipContent,
children
} = props;
const segmentChildren = tooltipContent ? (
<Tooltip
id={`${id}-tooltip`}
trigger={<div className={segmentedControlButtonInner}>{children}</div>}
>
{tooltipContent}
</Tooltip>
) : (
<div className={segmentedControlButtonInner}>{children}</div>
);

return (
<React.Fragment>
{/*
Expand All @@ -60,7 +85,7 @@ const SegmentedControlButton: React.SFC<
checked={isActive}
onChange={onChange}
/>
{props.children}
{segmentChildren}
</label>
</FocusStyleManager>
</React.Fragment>
Expand Down
32 changes: 32 additions & 0 deletions packages/segmentedControl/stories/SegmentedControl.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,38 @@ storiesOf("SegmentedControl", module)
)}
</SegmentedControlStoryHelper>
))
.add("with tooltip content", () => (
<SegmentedControlStoryHelper>
{({ changeHandler, selectedSegment }) => (
<SegmentedControl
id="nontextChildren"
selectedSegment={selectedSegment}
onSelect={changeHandler}
>
<SegmentedControlButton
value="list"
tooltipContent="Turn on the list"
>
<Icon
ariaLabel="list view"
shape={SystemIcons.List}
size={iconSizeXs}
/>
</SegmentedControlButton>
<SegmentedControlButton
value="charts"
tooltipContent="Turn on the charts"
>
<Icon
ariaLabel="chart view"
shape={SystemIcons.Donut}
size={iconSizeXs}
/>
</SegmentedControlButton>
</SegmentedControl>
)}
</SegmentedControlStoryHelper>
))
.add(
"custom SegmentedControlButton id prop",
() => (
Expand Down
5 changes: 4 additions & 1 deletion packages/segmentedControl/style.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ export const segmentedControlButton = css`
border-style: solid;
border-right-width: 0;
cursor: pointer;
padding: ${buttonPadding.vert} ${buttonPadding.horiz};
&:first-child {
border-radius: ${borderRadiusDefault} 0 0 ${borderRadiusDefault};
Expand All @@ -45,6 +44,10 @@ export const segmentedControlButton = css`
}
`;

export const segmentedControlButtonInner = css`
padding: ${buttonPadding.vert} ${buttonPadding.horiz};
`;

export const segmentedControlButtonActive = css`
background-color: ${themeBorder};
border-color: ${themeBorder};
Expand Down
9 changes: 8 additions & 1 deletion packages/tooltip/components/Tooltip.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,14 @@ class Tooltip extends React.PureComponent<TooltipProps, TooltipState> {
</TooltipContent>
}
preferredDirections={
preferredDirections || [Direction.TopCenter, Direction.BottomCenter]
preferredDirections || [
Direction.TopCenter,
Direction.TopLeft,
Direction.TopRight,
Direction.BottomCenter,
Direction.BottomLeft,
Direction.BottomRight
]
}
>
{trigger}
Expand Down
74 changes: 40 additions & 34 deletions packages/tooltip/tests/__snapshots__/Tooltip.test.tsx.snap
Original file line number Diff line number Diff line change
@@ -1,6 +1,17 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`Tooltip renders 1`] = `
.emotion-3 {
top: 0px;
left: 0px;
position: absolute;
-webkit-transform: scale(0);
-ms-transform: scale(0);
transform: scale(0);
opacity: 0;
z-index: 2;
}
.emotion-5 {
position: relative;
}
Expand All @@ -21,17 +32,6 @@ exports[`Tooltip renders 1`] = `
position: absolute;
}
.emotion-3 {
top: 0px;
left: NaNpx;
position: absolute;
-webkit-transform: scale(0);
-ms-transform: scale(0);
transform: scale(0);
opacity: 0;
z-index: 2;
}
<Tooltip
id="renders"
trigger="trigger"
Expand Down Expand Up @@ -59,7 +59,11 @@ exports[`Tooltip renders 1`] = `
preferredDirections={
Array [
"top-center",
"top-left",
"top-right",
"bottom-center",
"bottom-left",
"bottom-right",
]
}
>
Expand All @@ -73,7 +77,18 @@ exports[`Tooltip renders 1`] = `
<Overlay
className="emotion-3"
overlayRoot={
.emotion-2 {
.emotion-3 {
top: 0px;
left: 0px;
position: absolute;
-webkit-transform: scale(0);
-ms-transform: scale(0);
transform: scale(0);
opacity: 0;
z-index: 2;
}
.emotion-2 {
background-color: var(--themeBgPrimaryInverted,#1B2029);
border-radius: 2px;
box-sizing: border-box;
Expand All @@ -89,17 +104,6 @@ exports[`Tooltip renders 1`] = `
position: absolute;
}
.emotion-3 {
top: 0px;
left: NaNpx;
position: absolute;
-webkit-transform: scale(0);
-ms-transform: scale(0);
transform: scale(0);
opacity: 0;
z-index: 2;
}
<body>
<div>
<div
Expand Down Expand Up @@ -157,7 +161,7 @@ exports[`Tooltip renders 1`] = `
open={false}
>
<TooltipContent
direction="top-center"
direction="top-left"
id="renders"
open={false}
>
Expand Down Expand Up @@ -214,7 +218,7 @@ exports[`Tooltip renders open tooltip 1`] = `
.emotion-3 {
top: 0px;
left: NaNpx;
left: 0px;
position: absolute;
-webkit-transform: scale(1);
-ms-transform: scale(1);
Expand Down Expand Up @@ -251,7 +255,11 @@ exports[`Tooltip renders open tooltip 1`] = `
preferredDirections={
Array [
"top-center",
"top-left",
"top-right",
"bottom-center",
"bottom-left",
"bottom-right",
]
}
>
Expand All @@ -268,7 +276,7 @@ exports[`Tooltip renders open tooltip 1`] = `
<body>
<div>
<div
class="css-xeraz5"
class="css-ao6agm"
>
<div>
<div
Expand Down Expand Up @@ -302,7 +310,7 @@ exports[`Tooltip renders open tooltip 1`] = `
.emotion-3 {
top: 0px;
left: NaNpx;
left: 0px;
position: absolute;
-webkit-transform: scale(1);
-ms-transform: scale(1);
Expand Down Expand Up @@ -367,7 +375,7 @@ exports[`Tooltip renders open tooltip 1`] = `
open={true}
>
<TooltipContent
direction="top-center"
direction="top-left"
id="opened"
open={true}
>
Expand Down Expand Up @@ -482,15 +490,14 @@ exports[`Tooltip renders with preferred directions 1`] = `
<body>
<div>
<div
class="css-xeraz5"
class="css-ao6agm"
>
<div>
<div
aria-hidden="true"
class="
css-10cr3um
css-miht3n
inverseColorMode emotion-2"
emotion-1 inverseColorMode emotion-2"
data-cy="tooltipContent"
id="renders"
role="tooltip"
Expand All @@ -502,15 +509,14 @@ exports[`Tooltip renders with preferred directions 1`] = `
</div>
<div>
<div
class="css-asbxzi"
class="emotion-3"
>
<div>
<div
aria-hidden="false"
class="
css-10cr3um
css-miht3n
inverseColorMode emotion-2"
emotion-1 inverseColorMode emotion-2"
data-cy="tooltipContent"
id="opened"
role="tooltip"
Expand Down

0 comments on commit 958bc36

Please sign in to comment.