UNPKG

@atlaskit/navigation-system

Version:

The latest navigation system for Atlassian apps.

253 lines (244 loc) • 13.1 kB
/* panel.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.Panel = Panel; require("./panel.compiled.css"); var _react = _interopRequireWildcard(require("react")); var React = _react; var _runtime = require("@compiled/react/runtime"); var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty")); var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray")); var _mergeRefs = _interopRequireDefault(require("@atlaskit/ds-lib/merge-refs")); var _useMotion3 = require("@atlaskit/motion/entering/use-motion"); var _exitingPersistence = _interopRequireDefault(require("@atlaskit/motion/exiting-persistence")); var _reanimate = require("@atlaskit/motion/reanimate"); var _fg = require("@atlaskit/platform-feature-flags/fg"); var _useSkipLinkInternal = require("../../context/skip-links/use-skip-link-internal"); var _constants = require("./constants"); var _dangerouslyHoistCssVarToDocumentRoot = require("./dangerously-hoist-css-var-to-document-root"); var _hoistSlotSizesContext = require("./hoist-slot-sizes-context"); var _provider = require("./panel-splitter/provider"); var _useSideNavRef = require("./side-nav/use-side-nav-ref"); var _useLayoutId = require("./use-layout-id"); var _useResizingWidthCssVarOnRootElement = require("./use-resizing-width-css-var-on-root-element"); var _useSafeDefaultWidth = require("./use-safe-default-width"); 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); } // eslint-disable-next-line @atlaskit/design-system/no-emotion-primitives -- TODO: migrate to @atlaskit/primitives/compiled var panelSplitterResizingVar = '--n_pnlRsz'; var fallbackDefaultWidth = 365; /** * We typically use the `defaultWidth` as the minimum resizing width, * but for large default widths we fallback to a standard value. * * This standard value of `400px` is to align with the Global Preview Panels. */ var fallbackResizeMinWidth = 400; var styles = { root: "_nd5l1b6c _10fph9n0 _vchhusvi _1pbykb7n _4t3ieqxy _kqsw1if8 _152timx3 _bfhk1bhr _1bsb1dxx _14b54rrg _4ap3vuon _1dhy1c6w _9sns1wug", border: "_191wglyw _16qs130s _1w6eia51 _scbpglyw", scrollContainer: "_1reo1wug _18m91wug _4t3i1osq", hidden: "_1e0cglyw", entering: "_k1af1nn1 _10t81ia4 _xrrp147i _1wsa4so3 _1vrh1a5r _1kmh1n9t _105abamb", exiting: "_k1af14vv _10t81ia4 _xrrp147i _1wsa1jkh _1vrh1a5r _bq641n9t _105aeydr", contentEntering: "_y44v1mph", contentExiting: "_y44vf1qi", contentChangeContainer: "_4t3i1osq" }; var PanelContentMotion = function PanelContentMotion(_ref) { var children = _ref.children; var _useMotion = (0, _useMotion3.useMotion)(), state = _useMotion.state, ref = _useMotion.ref; return /*#__PURE__*/React.createElement("div", { ref: ref, className: (0, _runtime.ax)([styles.contentChangeContainer, state === 'entering' && styles.contentEntering, state === 'exiting' && styles.contentExiting]) }, children); }; /** * The Panel layout area is rendered to the right (inline end) of the Main area, or the Aside area if it is present. * * On small viewports (below 64rem, or 1024px), the Panel slot will become an overlay. * * You can optionally render a `PanelSplitter` as a child to make the panel area resizable. */ function Panel(_ref2) { var children = _ref2.children, _ref2$defaultWidth = _ref2.defaultWidth, defaultWidthProp = _ref2$defaultWidth === void 0 ? fallbackDefaultWidth : _ref2$defaultWidth, _ref2$label = _ref2.label, label = _ref2$label === void 0 ? 'Panel' : _ref2$label, _ref2$skipLinkLabel = _ref2.skipLinkLabel, skipLinkLabel = _ref2$skipLinkLabel === void 0 ? label : _ref2$skipLinkLabel, testId = _ref2.testId, providedId = _ref2.id, xcss = _ref2.xcss, _ref2$hasBorder = _ref2.hasBorder, hasBorder = _ref2$hasBorder === void 0 ? true : _ref2$hasBorder, maxWidth = _ref2.maxWidth, contentKey = _ref2.contentKey; var dangerouslyHoistSlotSizes = (0, _react.useContext)(_hoistSlotSizesContext.DangerouslyHoistSlotSizes); var id = (0, _useLayoutId.useLayoutId)({ providedId: providedId }); var isMotionUpliftEnabled = (0, _fg.fg)('platform-dst-motion-uplift-panel'); var isContentMotionEnabled = (0, _fg.fg)('platform-dst-motion-uplift-panel-content'); var prevContentKeyRef = (0, _react.useRef)(contentKey); (0, _react.useEffect)(function () { if (isContentMotionEnabled && contentKey !== undefined) { prevContentKeyRef.current = contentKey; } }, [contentKey, isContentMotionEnabled]); var defaultWidth = (0, _useSafeDefaultWidth.useSafeDefaultWidth)({ defaultWidthProp: defaultWidthProp, fallbackDefaultWidth: fallbackDefaultWidth, slotName: 'Panel' }); // useMotion is applied only when the `platform-dst-motion-uplift-panel` gate is enabled. var _useMotion2 = (0, _useMotion3.useMotion)({ onFinish: function onFinish(state) { if (state === 'exiting' && defaultWidthRef.current === 0) { // Set width to 0 as animation is complete setWidth(0); } }, initialState: defaultWidth === 0 ? 'hidden' : undefined }), state = _useMotion2.state, motionRef = _useMotion2.ref, reanimate = _useMotion2.reanimate; /** * Don't show the skip link if the slot has 0 width. * * Remove `isHidden` usage after https://jplat.atlassian.net/browse/BLU-3951 * * TODO: when cleaning up 'platform_dst_nav4_skip_link_a11y_1' remove this call entirely */ (0, _useSkipLinkInternal.useSkipLinkInternal)({ id: id, label: skipLinkLabel, isHidden: defaultWidth === 0 || (0, _fg.fg)('platform_dst_nav4_skip_link_a11y_1') }); var ref = (0, _react.useRef)(null); var _useState = (0, _react.useState)(defaultWidth), _useState2 = (0, _slicedToArray2.default)(_useState, 2), width = _useState2[0], setWidth = _useState2[1]; // Used to track the previous value of the `defaultWidth` prop, for logging dev warnings when it changes. var defaultWidthRef = (0, _react.useRef)(defaultWidth); // `mergeRefs` returns a new callback ref on every call, and combined with a new array literal // this would cause React to detach/re-attach the ref on every render. Memoise it so the merged // ref is stable across renders. var mergedRef = (0, _react.useMemo)(function () { return isMotionUpliftEnabled ? (0, _mergeRefs.default)([ref, motionRef]) : ref; }, // eslint-disable-next-line react-hooks/exhaustive-deps [isMotionUpliftEnabled, motionRef]); /** * TODO: Remove this useEffect once the `width: 0` usage is removed from Jira. * It updates the width state based on changes to `defaultWidth`, as a temporary stopgap to support Jira's current usage. * https://jplat.atlassian.net/browse/BLU-3951 */ (0, _react.useEffect)(function () { if (defaultWidthRef.current === defaultWidth) { return; } if (isMotionUpliftEnabled) { if (defaultWidth === 0) { reanimate(_reanimate.Reanimate.exit); defaultWidthRef.current = defaultWidth; // Set width to 0 once the exit animation is complete return; } else if (defaultWidthRef.current === 0) { reanimate(_reanimate.Reanimate.enter); } } defaultWidthRef.current = defaultWidth; setWidth(defaultWidth); if (process.env.NODE_ENV !== 'production') { // eslint-disable-next-line no-console console.warn('Page Layout warning\n\n', 'The value of the `defaultWidth` prop on the `Panel` layout slot component has changed. This should not be changed after the component has been mounted.\n\n', 'In the future, changes to the `defaultWidth` prop will not be respected. It is only supported as a stopgap to enable migration from Nav3 to Nav4.\n\n'); } }, [defaultWidth, isMotionUpliftEnabled, reanimate]); var sideNavRef = (0, _useSideNavRef.useSideNavRef)(); /** * The minimum width that the panel can be resized to by the user. * * We only use the `defaultWidth` up to a point to avoid huge panels. */ var minWidth = Math.min(defaultWidth, fallbackResizeMinWidth); /** * Returns the bounds for resizing, evaluated lazily when needed. * * Defined separately to the slot bounds because the resizing bounds need to be resolvable to a pixel value, * and the panel's slot bounds use a complex CSS expression. */ var getResizeBounds = (0, _react.useCallback)(function () { var _sideNavRef$current$o, _sideNavRef$current; var sideNavWidth = (_sideNavRef$current$o = (_sideNavRef$current = sideNavRef.current) === null || _sideNavRef$current === void 0 ? void 0 : _sideNavRef$current.offsetWidth) !== null && _sideNavRef$current$o !== void 0 ? _sideNavRef$current$o : 0; /** * By default the panel should not resize larger than the page content, equivalent to the `Main` + `Aside` slots. * * This maximum width is equivalent to half the viewport width, after removing the sidebar width. * * Consumers can opt in to a larger maximum via the `maxWidth` prop. */ var defaultMaxWidth = "".concat(Math.round((window.innerWidth - sideNavWidth) / 2), "px"); return { min: "".concat(minWidth, "px"), max: maxWidth !== null && maxWidth !== void 0 ? maxWidth : defaultMaxWidth }; }, [maxWidth, minWidth, sideNavRef]); var panelWidthSlotBounds = { min: "".concat(minWidth, "px"), // `sideNavLiveWidthVar` is not defined if the `SideNav` is not mounted, so we fallback to `0px`. // Consumers can opt in to a larger maximum via the `maxWidth` prop. max: maxWidth !== null && maxWidth !== void 0 ? maxWidth : "round(nearest, calc((100vw - var(".concat(_constants.sideNavLiveWidthVar, ", 0px)) / 2), 1px)") }; var panelVariableWidth = "clamp(".concat(panelWidthSlotBounds.min, ", ").concat(width, "px, ").concat(panelWidthSlotBounds.max, ")"); (0, _useResizingWidthCssVarOnRootElement.useResizingWidthCssVarOnRootElement)({ isEnabled: dangerouslyHoistSlotSizes, cssVar: panelSplitterResizingVar, panelId: _constants.panelPanelSplitterId }); return /*#__PURE__*/React.createElement("section", { id: id, "data-layout-slot": true, "aria-label": label // eslint-disable-next-line @atlaskit/ui-styling-standard/no-classname-prop , className: (0, _runtime.ax)([styles.root, isMotionUpliftEnabled && state === 'hidden' && styles.hidden, isMotionUpliftEnabled && state === 'entering' && styles.entering, isMotionUpliftEnabled && state === 'exiting' && styles.exiting, !isMotionUpliftEnabled && defaultWidth === 0 && styles.hidden, hasBorder && styles.border, xcss]), style: (0, _defineProperty2.default)((0, _defineProperty2.default)({}, _constants.panelVar, panelVariableWidth), '--minWidth', "".concat(minWidth, "px")), "data-testid": testId, ref: mergedRef }, dangerouslyHoistSlotSizes && /*#__PURE__*/ // ------ START UNSAFE STYLES ------ // These styles are only needed for the UNSAFE legacy use case for Jira + Confluence. // When they aren't needed anymore we can delete them wholesale. React.createElement(_dangerouslyHoistCssVarToDocumentRoot.DangerouslyHoistCssVarToDocumentRoot, { variableName: _constants.UNSAFE_panelLayoutVar, value: "0px", mediaQuery: '@media (min-width: 90rem)', responsiveValue: "var(".concat(panelSplitterResizingVar, ", ").concat(panelVariableWidth, ")") }) // ------ END UNSAFE STYLES ------ , /*#__PURE__*/React.createElement(_provider.PanelSplitterProvider, { panelId: _constants.panelPanelSplitterId, panelRef: ref, panelWidth: width, onCompleteResize: setWidth, getResizeBounds: getResizeBounds, resizingCssVar: panelSplitterResizingVar, position: "start" }, /*#__PURE__*/React.createElement("div", { className: (0, _runtime.ax)([styles.scrollContainer, isMotionUpliftEnabled && state === 'entering' && styles.contentEntering, isMotionUpliftEnabled && state === 'exiting' && styles.contentExiting]) }, isContentMotionEnabled ? /*#__PURE__*/React.createElement(_exitingPersistence.default, { exitThenEnter: contentKey !== undefined }, /*#__PURE__*/React.createElement(PanelContentMotion, { key: contentKey === undefined ? prevContentKeyRef.current : contentKey }, children)) : children))); }