@atlaskit/navigation-system
Version:
The latest navigation system for Atlassian apps.
154 lines (149 loc) • 6.38 kB
JavaScript
/* aside.tsx generated by @compiled/babel-plugin v3.0.2 */
import "./aside.compiled.css";
import * as React from 'react';
import { ax, ix } from "@compiled/react/runtime";
import { useContext, useEffect, useRef, useState } from 'react';
import usePreviousValue from '@atlaskit/ds-lib/use-previous-value';
import { fg } from '@atlaskit/platform-feature-flags/fg';
// eslint-disable-next-line @atlaskit/design-system/no-emotion-primitives -- TODO: migrate to @atlaskit/primitives/compiled
import { useSkipLinkInternal } from '../../context/skip-links/use-skip-link-internal';
import { UNSAFE_asideLayoutVar, asidePanelSplitterId, asideVar } from './constants';
import { DangerouslyHoistCssVarToDocumentRoot } from './dangerously-hoist-css-var-to-document-root';
import { DangerouslyHoistSlotSizes } from './hoist-slot-sizes-context';
import { PanelSplitterProvider } from './panel-splitter/provider';
import { useLayoutId } from './use-layout-id';
import { useResizingWidthCssVarOnRootElement } from './use-resizing-width-css-var-on-root-element';
import { useSafeDefaultWidth } from './use-safe-default-width';
const panelSplitterResizingVar = '--n_asdRsz';
/**
* The bounds for Aside and Panel are purposely set to support the current usage in Jira.
*
* Jira sets the slot's width to `0px` when there is no active content to display in it.
* - This means the min width needs to support `0px`.
* The Conversation Assistant component in Jira (rendered in a nav3 RightSidebar, or a nav4 Aside) has a custom resizing
* implementation, which has a maximum width of `50vw`.
* - This means the max width needs to support `50vw`.
*
* This is not the final implementation and will be updated once Jira's usage has been fixed.
* Ticket to track this is: https://jplat.atlassian.net/browse/BLU-3951
*
* We're using two different bounds for each slot here, to support the `0px` min width when programatically set using the
* `defaultWidth` prop, and another one that is used when resizing the slots which has a sensible min width.
*/
const asideWidthSlotBounds = {
min: '0px',
max: '50vw'
};
const asideWidthResizeBounds = {
min: '120px',
max: '50vw'
};
function getResizeBounds() {
return asideWidthResizeBounds;
}
const styles = {
root: "_nd5lns35 _vchhusvi _kqswh2mm _glte1kzp _ndwch9n0",
inner: "_1reo1wug _18m91wug _152timx3 _4t3i1osq _165teqxy _13wn1if8"
};
const fallbackDefaultWidth = 330;
/**
* The Aside is rendered to the right (inline end) of the Main area.
*
* You can optionally render a `PanelSplitter` as a child to make the aside area resizable.
*
* @deprecated Use `Panel` instead.
*/
export function Aside({
children,
xcss,
defaultWidth: defaultWidthProp = fallbackDefaultWidth,
label = 'Aside',
skipLinkLabel = label,
testId,
id: providedId
}) {
const dangerouslyHoistSlotSizes = useContext(DangerouslyHoistSlotSizes);
const id = useLayoutId({
providedId
});
const defaultWidth = useSafeDefaultWidth({
defaultWidthProp,
fallbackDefaultWidth,
slotName: 'Aside'
});
/**
* 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
*/
useSkipLinkInternal({
id,
label: skipLinkLabel,
isHidden: defaultWidth === 0 || fg('platform_dst_nav4_skip_link_a11y_1')
});
const ref = useRef(null);
const [width, setWidth] = useState(defaultWidth);
// Used to track the previous value of the `defaultWidth` prop, for logging dev warnings when it changes.
const previousWidthProp = usePreviousValue(defaultWidth);
/**
* Updates the width state based on changes to `defaultWidth`.
* This is temporary and needed to support the current usage in Jira, and will be removed once it is no longer needed.
* https://jplat.atlassian.net/browse/BLU-3951
*/
useEffect(() => {
setWidth(defaultWidth);
}, [defaultWidth]);
// Putting the warning in a separate effect to avoid adding `previousWidthProp` as an effect dependency when updating width.
useEffect(() => {
if (process.env.NODE_ENV !== 'production') {
if (previousWidthProp !== undefined && defaultWidth !== previousWidthProp) {
// eslint-disable-next-line no-console
console.warn('Page Layout warning\n\n', 'The value of the `defaultWidth` prop on the `Aside` 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, previousWidthProp]);
const asideVariableWidth = `clamp(${asideWidthSlotBounds.min}, ${width}px, ${asideWidthSlotBounds.max})`;
useResizingWidthCssVarOnRootElement({
isEnabled: dangerouslyHoistSlotSizes,
panelId: asidePanelSplitterId,
cssVar: panelSplitterResizingVar
});
return /*#__PURE__*/React.createElement("aside", {
id: id,
"data-layout-slot": true,
"aria-label": label,
className: ax([styles.root, xcss])
// eslint-disable-next-line @atlaskit/ui-styling-standard/enforce-style-prop, @atlaskit/ui-styling-standard/no-imported-style-values
,
style: {
[asideVar]: asideVariableWidth
},
"data-testid": testId,
ref: ref
}, 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, {
variableName: UNSAFE_asideLayoutVar,
value: "0px",
mediaQuery: '@media (min-width: 64rem)',
responsiveValue: `var(${panelSplitterResizingVar}, ${asideVariableWidth})`
})
// ------ END UNSAFE STYLES ------
, /*#__PURE__*/React.createElement(PanelSplitterProvider, {
panelId: asidePanelSplitterId,
panelRef: ref,
panelWidth: width,
onCompleteResize: setWidth,
getResizeBounds: getResizeBounds,
resizingCssVar: panelSplitterResizingVar,
position: "start"
}, /*#__PURE__*/React.createElement("div", {
"data-testid": testId ? `${testId}--inner` : undefined,
className: ax([styles.inner])
}, children)));
}