Skip to content

Commit

Permalink
docs draft
Browse files Browse the repository at this point in the history
  • Loading branch information
chloerice committed Jan 12, 2024
1 parent b2d7e88 commit caf60f9
Show file tree
Hide file tree
Showing 8 changed files with 725 additions and 29 deletions.
8 changes: 3 additions & 5 deletions polaris-react/src/components/HoverCard/HoverCard.module.scss
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ $vertical-motion-offset: -5px;
// stylelint-disable-next-line polaris/conventions/polaris/custom-property-allowed-list -- HoverCard CSS Custom Variables
min-width: var(--pc-hovercard-min-width);
background: var(--p-color-bg-surface);
will-change: opacity, left, top, width, height;
will-change: opacity, left, top;
margin: var(--p-space-100) var(--p-space-200) var(--p-space-400);
box-shadow: var(--p-shadow-500);
border-radius: var(--p-border-radius-300);
Expand All @@ -39,19 +39,18 @@ $vertical-motion-offset: -5px;

.HoverCardOverlay-open {
opacity: 1;
transform: none;

transition: top var(--p-motion-duration-100) cubic-bezier(0.25, 0, 0.75, 1.35),
opacity var(--p-motion-duration-100) ease-in-out,
width var(--p-motion-duration-100) ease-in-out,
height var(--p-motion-duration-100) ease-in-out;
}

.measuring:not(.HoverCardOverlay-exiting) {
.measuring:not(.HoverCardOverlay-exited) {
opacity: 0;
}

.measured:not(.HoverCardOverlay-open) {
.measured {
opacity: 1;
transition: opacity var(--p-motion-duration-100) var(--p-motion-ease)
var(--p-motion-duration-300);
Expand Down Expand Up @@ -84,7 +83,6 @@ $vertical-motion-offset: -5px;
}

.Content {
opacity: 1;
display: flex;
width: 100%;
flex-direction: column;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -616,7 +616,6 @@ export function WithDynamicActivator() {
<HoverCard
snapToParent
minWidth={activeHoverCard.order ? 300 : undefined}
hoverDelay={100}
activator={activatorElement}
activatorWrapper="div"
preferredPosition="right"
Expand Down
12 changes: 4 additions & 8 deletions polaris-react/src/components/HoverCard/HoverCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,27 +11,25 @@ interface BaseHoverCardProps {
id?: string;
/** The activator markup to render that triggers the overlay. Only wrap individual commerce objects rendered by themselves. */
children?: React.ReactNode;
/** The preferred direction to open the overlay */
/** The preferred placement of the overlay relative to its activator */
preferredPosition?: PositionedOverlayProps['preferredPosition'];
/** The preferred alignment of the popover relative to its activator */
/** The preferred alignment of the overlay relative to its activator */
preferredAlignment?: PositionedOverlayProps['preferredAlignment'];
/** Show or hide the overlay */
active?: boolean;
/** The activator element currently triggering the overlay. Use to dynamically trigger a single, standalone overlay with several of the same commerce object in close context, like a column of customer names in an index table of orders. */
/** The activator element currently triggering the overlay. Use to dynamically trigger a single, standalone overlay with several of the same commerce object type in close context, like a column of customer names in an index table of orders. */
activator?: HTMLElement | null;
/**
* The element type to wrap the activator in
* @default 'span'
*/
activatorWrapper?: string;
/** Style activatorWrapper to fill parent dimensions and remove overlay margin
/** Whether the activatorWrapper should fill its parent's dimensions and remove overlay margin. Set to true if the activator is within a table cell.
* @default false
*/
snapToParent?: boolean;
/** Minimum pixel width for the overlay */
minWidth?: number;
/** Delay in milliseconds while hovering over an element before the overlay is visible */
hoverDelay?: number;
/** Content to render inside of the overlay. */
content: React.ReactNode;
/** Override on the default z-index of 400 */
Expand Down Expand Up @@ -84,7 +82,6 @@ export function HoverCard({
activatorWrapper = 'span',
snapToParent = false,
minWidth,
hoverDelay,
content,
zIndexOverride,
id: providedId,
Expand All @@ -106,7 +103,6 @@ export function HoverCard({
handleMouseLeaveOverlay,
} = useHoverCardActivatorWrapperProps({
toggleActive,
hoverDelay,
ref,
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,10 @@ import styles from '../HoverCard.module.scss';
const HOVER_OUT_TIMEOUT = 150;

export function useHoverCardActivatorWrapperProps({
hoverDelay,
snapToParent,
ref: providedActivatorRef,
toggleActive,
}: {
hoverDelay?: number;
snapToParent?: boolean;
ref?: React.RefObject<HTMLElement | null>;
toggleActive?(active: boolean): void;
Expand Down Expand Up @@ -103,22 +101,15 @@ export function useHoverCardActivatorWrapperProps({

mouseEntered.current = true;

if (hoverDelay && !presenceList.hovercard) {
if (!presenceList.hovercard) {
hoverDelayTimeout.current = setTimeout(() => {
handleOpen();
}, hoverDelay);
}, 100);
} else {
handleOpen();
}
},
[
handleOpen,
hoverDelay,
hoverDelayTimeout,
presenceList,
mdUp,
providedActivatorRef,
],
[handleOpen, hoverDelayTimeout, presenceList, mdUp, providedActivatorRef],
);

// https://github.com/facebook/react/issues/10109
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,6 @@ export interface PositionedOverlayProps {
preventInteraction?: boolean;
classNames?: string;
zIndexOverride?: number;
transform?: string;
render(overlayDetails: OverlayDetails): React.ReactNode;
onScrollOut?(): void;
}
Expand Down Expand Up @@ -137,11 +136,9 @@ export class PositionedOverlay extends PureComponent<
preventInteraction,
classNames: propClassNames,
zIndexOverride,
transform,
} = this.props;

const style = {
transform,
top: top == null || isNaN(top) ? undefined : top,
left: left == null || isNaN(left) ? undefined : left,
right: right == null || isNaN(right) ? undefined : right,
Expand Down
39 changes: 39 additions & 0 deletions polaris.shopify.com/content/components/overlays/hovercard.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
---
title: HoverCard
shortDescription: Used to present a preview of a commerce object's key information when hovering a link to its detail page.
category: Overlays
keywords:
- hovercard
- link preview
- link details
- commerce object
examples:
- fileName: hovercard-with-child-activator.tsx
title: With child activator
description: A hover card that renders and is triggered to be `active` by its `children`. Use for commerce objects rendered by themselves within normal page content.
- fileName: hovercard-with-dynamic-activator.tsx
title: With dynamic activator
description: A HoverCard rendered without `children` that is triggered to be `active` and repositioned by dynamically setting the `activator` prop. Use when several of the same commerce object type are in close context, like a column of customer names in an index table of orders.
---

# {frontmatter.title}

<Lede>

A hover card is an overlay only triggered by mouse over of a link. They are not triggered on focus, keyboard navigable, or visible to screen readers. Use to present a preview of a commerce object's key information when hovering a link to its detail page.

</Lede>

<Examples />

<Props componentName={frontmatter.title} />

## Best practices

---

## Content guidelines

---

## Related components
146 changes: 146 additions & 0 deletions polaris.shopify.com/pages/examples/hovercard-with-child-activator.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
import React, {useState} from 'react';
import {
ButtonGroup,
Box,
Button,
HoverCard,
Icon,
Link,
Text,
BlockStack,
InlineStack,
Card,
} from '@shopify/polaris';
import type {PositionedOverlayProps} from '@shopify/polaris';
import {LocationsMinor, OrdersMinor} from '@shopify/polaris-icons';
import {withPolarisExample} from '../../src/components/PolarisExampleWrapper';

function HoverCardWithChildActivator() {
const [active, setActive] = useState(false);
const [position, setPosition] =
useState<PositionedOverlayProps['preferredPosition']>('below');

const handleChangePosition =
(position: PositionedOverlayProps['preferredPosition']) => () => {
setPosition(position);
};

const activator = (
<Link removeUnderline url="#">
Saul Goodman
</Link>
);

const customerHoverCardContent = (
<Box padding="400">
<BlockStack gap="400">
<BlockStack gap="0">
<Text as="span" variant="headingSm">
<Link removeUnderline>Saul Goodman</Link>
</Text>
<Text as="span" variant="bodyMd">
<Link url="mailto:help@bettercallsaul.com">
help@bettercallsaul.com
</Link>
</Text>
<Text as="p" variant="bodyMd">
<Link url="tel:+1505-842-5662">+1 505-842-5662</Link>
</Text>
</BlockStack>
<Box width="100%">
<BlockStack gap="100">
<InlineStack wrap={false} gap="100" align="start">
<Icon tone="subdued" source={LocationsMinor} />
<Text tone="subdued" as="p">
Albequerque, NM, USA
</Text>
</InlineStack>
<InlineStack wrap={false} gap="100" align="start">
<Box>
<Icon tone="subdued" source={OrdersMinor} />
</Box>
<Text tone="subdued" as="p">
8 Orders
</Text>
</InlineStack>
</BlockStack>
</Box>
</BlockStack>
</Box>
);

const positionControlBar = (
<BlockStack gap="100" align="start" inlineAlign="center">
<Text as="p" tone="subdued">
Use the buttons below to change the hover card position
</Text>
<ButtonGroup variant="segmented">
<Button
pressed={position === 'left'}
onClick={handleChangePosition('left')}
>
Left
</Button>
<Button
pressed={position === 'right'}
onClick={handleChangePosition('right')}
>
Right
</Button>
<Button
pressed={position === 'above'}
onClick={handleChangePosition('above')}
>
Above
</Button>
<Button
pressed={position === 'below'}
onClick={handleChangePosition('below')}
>
Below
</Button>
</ButtonGroup>
</BlockStack>
);

return (
<div
style={{
display: 'flex',
flexDirection: 'column',
alignItems: 'center',
justifyContent: 'center',
margin: '0 auto',
height: '300px',
width: '100%',
}}
>
<InlineStack align="center" blockAlign="center">
<BlockStack gap="500">
{positionControlBar}

<Card>
<BlockStack gap="300">
<Text as="h2" variant="headingSm">
Customer
</Text>

<HoverCard
active={active}
preferredPosition={position}
preferredAlignment="center"
content={customerHoverCardContent}
toggleActive={setActive}
>
{activator}
</HoverCard>
</BlockStack>
</Card>
<Box minHeight="100px" />
</BlockStack>
</InlineStack>
</div>
);
}

export default withPolarisExample(HoverCardWithChildActivator);
Loading

0 comments on commit caf60f9

Please sign in to comment.