UNPKG

@atlaskit/spotlight

Version:

A spotlight introduces users to points of interest, from focused messages to multi-step tours.

169 lines (165 loc) 5.39 kB
/* legacy.tsx generated by @compiled/babel-plugin v3.0.2 */ import "./legacy.compiled.css"; import * as React from 'react'; import { ax, ix } from "@compiled/react/runtime"; import { useContext, useEffect, useLayoutEffect, useRef } from 'react'; import mergeRefs from '@atlaskit/ds-lib/merge-refs'; import Motion from '@atlaskit/motion/entering/motion'; import { fg } from '@atlaskit/platform-feature-flags/fg'; import { Popper } from '@atlaskit/popper/main'; import { SpotlightContext } from '../../controllers/context'; import { useFocusWithin } from '../../utils/use-focus-within'; import { useOnClickOutside } from '../../utils/use-on-click-outside'; import { useOnEscape } from '../../utils/use-on-escape'; import { ConditionalExitingPersistence } from './conditional-exiting-persistence'; const styles = { root: "_1pby1fw0" }; /** * Taken from `@atlaskit/popper` */ /** * The `transform: rotate(45deg);` styles used to rotate the `Caret` component result in the corners of * the caret extending beyond the bounding box (by roughly 2px). So, apply an offset to ensure * the caret points to the very edge of the target element. * * Note: `@atlaskit/popper` maps the offset to the placement, so we only need to define `[0, 2]` and * the offset will get correctly rotated depending on the placement. */ const defaultOffset = [0, 2]; /** * The Spotlight card can be positioned in many different configurations, but the caret should always point to * the center of the target element. `@atlaskit/popper` uses `'top' | 'right' | 'bottom' | 'left'` values for * this center alignment along the respective face. So we translate between the Spotlight position, and the * Popper position using this map. */ const popperPlacementMap = { 'top-start': 'top', 'top-center': 'top', 'top-end': 'top', 'bottom-start': 'bottom', 'bottom-center': 'bottom', 'bottom-end': 'bottom', 'right-start': 'right', 'right-end': 'right', 'left-start': 'left', 'left-end': 'left' }; const DefaultMotion = ({ children }) => /*#__PURE__*/React.createElement(Motion, { enteringAnimation: "var(--ds-spotlight-enter, 250ms cubic-bezier(0.4, 0, 0, 1) ScaleIn95to100, 250ms cubic-bezier(0.4, 0, 0, 1) FadeIn0to100)", exitingAnimation: "var(--ds-spotlight-exit, 200ms cubic-bezier(0.6, 0, 0.8, 0.6) ScaleOut100to95, 200ms cubic-bezier(0.6, 0, 0.8, 0.6) FadeOut100to0)" }, children); /** * __PopoverContent__ * * A `PopoverContent` is the element that is shown as a popover. */ export const PopoverContent = props => { const { children, placement, motion = DefaultMotion, isVisible = true, shouldDismissOnClickOutside = true, dismiss, back, testId, offset = defaultOffset, strategy } = props; /** * A user should only be able to pass a `done` or a `next`. Not both. * The type is set up as a discriminant union. So, we need a typeguard * here to destructure it properly. */ const done = 'done' in props ? props.done : undefined; const next = 'next' in props ? props.next : undefined; const updateRef = useRef(() => new Promise(() => undefined)); const ref = useRef(null); const { heading, popoverContent, card, primaryAction, secondaryAction } = useContext(SpotlightContext); const focusWithin = useFocusWithin(popoverContent.ref); useEffect(() => { popoverContent.setRef(ref); }, [ref, popoverContent]); useEffect(() => { if (!done && !next) { return; } if (done) { primaryAction.setAction(done); return; } else if (next) { primaryAction.setAction(next); return; } }, [done, next, primaryAction]); useEffect(() => { popoverContent.setDismiss(dismiss); }, [dismiss, popoverContent]); useEffect(() => { if (!back) { return; } secondaryAction.setAction(back); }, [back, secondaryAction]); useLayoutEffect(() => { card.setPlacement(placement); if (motion) { card.setMotion(() => motion); } }, [placement, card, motion]); useEffect(() => { if (updateRef.current) { popoverContent.setUpdate(() => updateRef.current); } }, [popoverContent]); useOnEscape(event => { if (!focusWithin) { return; } popoverContent.dismiss.current(event); }); useOnClickOutside(event => { if (!shouldDismissOnClickOutside) { return; } popoverContent.dismiss.current(event); }); return /*#__PURE__*/React.createElement(Popper, { offset: offset, strategy: strategy, placement: popperPlacementMap[placement] }, ({ ref: localRef, style, update }) => { if (!isVisible && !fg('platform-dst-motion-uplift-spotlight')) { return; } updateRef.current = update; return fg('platform-dst-motion-uplift-spotlight') ? /*#__PURE__*/React.createElement(ConditionalExitingPersistence, null, isVisible && /*#__PURE__*/React.createElement("div", { role: "dialog", "data-testid": testId, "aria-labelledby": heading.id, ref: mergeRefs([ref, localRef]), style: style, className: ax([styles.root]) }, children)) : /*#__PURE__*/React.createElement("div", { role: "dialog", "data-testid": testId, "aria-labelledby": heading.id, ref: mergeRefs([ref, localRef]), style: style, className: ax([styles.root]) }, children); }); };