UNPKG

@atlaskit/inline-dialog

Version:

An inline dialog is a pop-up container for small amounts of information. It can also contain controls.

188 lines (181 loc) • 7.88 kB
/* inline-dialog-top-layer.tsx generated by @compiled/babel-plugin v3.0.2 */ "use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); var _typeof = require("@babel/runtime/helpers/typeof"); Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; require("./inline-dialog-top-layer.compiled.css"); var _react = _interopRequireWildcard(require("react")); var React = _react; var _runtime = require("@compiled/react/runtime"); var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray")); var _usePlatformLeafEventHandler = require("@atlaskit/analytics-next/usePlatformLeafEventHandler"); var _noop = _interopRequireDefault(require("@atlaskit/ds-lib/noop")); var _getAriaForTrigger = require("@atlaskit/top-layer/get-aria-for-trigger"); var _index = require("@atlaskit/top-layer/placement-map/index"); var _createCloseEvent = require("@atlaskit/top-layer/popover/create-close-event"); var _popover = require("@atlaskit/top-layer/popover/popover"); var _useAnchoredPopover = require("@atlaskit/top-layer/use-anchored-popover"); var _usePopoverId = require("@atlaskit/top-layer/use-popover-id"); function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function _interopRequireWildcard(e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != _typeof(e) && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (var _t in e) "default" !== _t && {}.hasOwnProperty.call(e, _t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, _t)) && (i.get || i.set) ? o(f, _t, i) : f[_t] = e[_t]); return f; })(e, t); } var displayContentsStyles = { root: "_1e0c1bgi" }; var styles = { container: "_2rkofajl _vchh1ntv _p12flti4 _c71llti4 _bfhk1bhr _16qs130s _85i5pxbi _1q51pxbi _y4ti1ejb _bozg1ejb" }; /** * Returns the trigger button when the element is a button, or its first descendant button. * InlineDialog accepts arbitrary child markup, so the first button is used as the pragmatic target * when a wrapper contains multiple buttons. */ function getTriggerElement(trigger) { if (!trigger) { return null; } if (trigger instanceof HTMLButtonElement) { return trigger; } return trigger.querySelector('button'); } /** * Applies ARIA attributes to the child trigger element via an effect, * keeping them in sync with popup state. */ function TriggerWrapper(_ref) { var children = _ref.children, triggerRef = _ref.triggerRef, ariaAttributes = _ref.ariaAttributes; (0, _react.useEffect)(function () { var trigger = getTriggerElement(triggerRef.current); if (!trigger) { return; } // Apply each attribute. When a value is `undefined` (e.g. // `aria-controls` while the popover host is not in the DOM), // remove the attribute so the trigger does not retain a stale // reference from a previous open. Object.entries(ariaAttributes).forEach(function (_ref2) { var _ref3 = (0, _slicedToArray2.default)(_ref2, 2), key = _ref3[0], value = _ref3[1]; if (value === undefined) { trigger.removeAttribute(key); return; } trigger.setAttribute(key, String(value)); }); }, [ariaAttributes, triggerRef]); return /*#__PURE__*/React.createElement("div", { ref: function ref(node) { if (!node) { triggerRef.current = null; return; } // CSS-in-JS may inject <style> elements into this wrapper; they are not trigger elements. var triggerElement = Array.from(node.children).find(function (child) { return child instanceof HTMLElement && !(child instanceof HTMLStyleElement); }); triggerRef.current = triggerElement !== null && triggerElement !== void 0 ? triggerElement : null; }, className: (0, _runtime.ax)([displayContentsStyles.root]) }, children); } /** * Top-layer implementation of InlineDialog. * * Replaces the legacy rendering pipeline (Popper.js + Portal + @atlaskit/layering) * with the native Popover API + CSS Anchor Positioning via @atlaskit/top-layer. * * Gated behind the `platform-dst-top-layer` feature flag. */ var InlineDialogTopLayer = /*#__PURE__*/(0, _react.memo)(function InlineDialogTopLayer(_ref4) { var _ref4$isOpen = _ref4.isOpen, isOpen = _ref4$isOpen === void 0 ? false : _ref4$isOpen, _ref4$onContentBlur = _ref4.onContentBlur, onContentBlur = _ref4$onContentBlur === void 0 ? _noop.default : _ref4$onContentBlur, _ref4$onContentClick = _ref4.onContentClick, onContentClick = _ref4$onContentClick === void 0 ? _noop.default : _ref4$onContentClick, _ref4$onContentFocus = _ref4.onContentFocus, onContentFocus = _ref4$onContentFocus === void 0 ? _noop.default : _ref4$onContentFocus, _ref4$onClose = _ref4.onClose, providedOnClose = _ref4$onClose === void 0 ? _noop.default : _ref4$onClose, _ref4$placement = _ref4.placement, placement = _ref4$placement === void 0 ? 'bottom-start' : _ref4$placement, testId = _ref4.testId, content = _ref4.content, children = _ref4.children, _strategy = _ref4.strategy, _fallbackPlacements = _ref4.fallbackPlacements; var triggerRef = (0, _react.useRef)(null); var popoverRef = (0, _react.useRef)(null); var popoverId = (0, _usePopoverId.usePopoverId)(); var onClose = (0, _usePlatformLeafEventHandler.usePlatformLeafEventHandler)({ fn: function fn(event) { return providedOnClose(event); }, action: 'closed', componentName: 'inlineDialog', packageName: "@atlaskit/inline-dialog", packageVersion: "20.3.6" }); // Placement conversion. var topLayerPlacement = (0, _react.useMemo)(function () { return (0, _index.fromLegacyPlacement)({ legacy: placement }); }, [placement]); // `isOpen` is included so the anchor positioning effect re-runs when // the Popover host element is unmounted/remounted across open cycles. (0, _useAnchoredPopover.useAnchoredPopover)({ anchorRef: triggerRef, popoverRef: popoverRef, placement: topLayerPlacement, isOpen: isOpen }); // onClose bridge. // Translates top-layer's { reason } into the legacy onClose({ isOpen, event }) shape. // Focus restoration is handled automatically by the Popover based on the content role // (role="dialog" -> auto-restore). var handleOnClose = (0, _react.useCallback)(function (_ref5) { var reason = _ref5.reason; var syntheticEvent = (0, _createCloseEvent.createPopoverCloseEvent)({ reason: reason }); onClose({ isOpen: false, event: syntheticEvent }); }, [onClose]); var ariaAttributes = (0, _getAriaForTrigger.getAriaForTrigger)({ role: 'dialog', isOpen: isOpen, popoverId: popoverId }); return /*#__PURE__*/React.createElement(_react.Fragment, null, /*#__PURE__*/React.createElement(TriggerWrapper, { triggerRef: triggerRef, ariaAttributes: ariaAttributes }, children), /*#__PURE__*/React.createElement(_popover.Popover, { ref: popoverRef, id: popoverId, role: "dialog" // TODO: i18n. Hardcoded label is not translatable. // Acceptable given this component is intent-to-deprecate. , label: "Inline dialog", isOpen: isOpen, onClose: handleOnClose, shouldAnimate: true, placement: topLayerPlacement, testId: testId }, /*#__PURE__*/React.createElement("div", { role: "presentation", onBlur: onContentBlur, onClick: onContentClick, onFocus: onContentFocus, className: (0, _runtime.ax)([styles.container]) }, typeof content === 'function' ? content() : content))); }); var _default = exports.default = InlineDialogTopLayer;