UNPKG

@atlaskit/renderer

Version:
289 lines (286 loc) • 11.1 kB
/** * @jsxRuntime classic * @jsx jsx */ // eslint-disable-next-line @atlaskit/ui-styling-standard/use-compiled -- Ignored via go/DSP-18766 import { css, jsx } from '@emotion/react'; import React, { useCallback, useRef, Suspense, lazy } from 'react'; // eslint-disable-next-line @atlaskit/design-system/no-deprecated-imports import { ACTION, ACTION_SUBJECT, EVENT_TYPE } from '@atlaskit/editor-common/analytics'; import { ExpandIconWrapper, ExpandLayoutWrapperWithRef, expandMessages, WidthProvider } from '@atlaskit/editor-common/ui'; import { akEditorLineHeight, akEditorSwoopCubicBezier, akLayoutGutterOffset } from '@atlaskit/editor-shared-styles'; import ChevronRightIcon from '@atlaskit/icon/core/chevron-right'; import Tooltip from '@atlaskit/tooltip'; import { fg } from '@atlaskit/platform-feature-flags'; import _uniqueId from 'lodash/uniqueId'; import { injectIntl } from 'react-intl'; import { MODE, PLATFORM } from '../analytics/events'; import { ActiveHeaderIdConsumer } from './active-header-id-provider'; import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals'; const titleStyles = css({ outline: 'none', border: 'none', // eslint-disable-next-line @atlaskit/design-system/use-tokens-typography fontSize: `${14 / 16}rem`, // eslint-disable-next-line @atlaskit/ui-styling-standard/no-imported-style-values, @atlaskit/ui-styling-standard/no-unsafe-values, @atlaskit/design-system/use-tokens-typography -- Ignored via go/DSP-18766 lineHeight: akEditorLineHeight, fontWeight: "var(--ds-font-weight-regular, 400)", display: 'flex', flex: 1, margin: 0, padding: `0 0 0 ${"var(--ds-space-050, 4px)"}`, textAlign: 'left' }); const titleStylesDense = css({ // eslint-disable-next-line @atlaskit/design-system/use-tokens-typography fontSize: 'var(--ak-renderer-base-font-size)' }); const containerStyles = css({ borderWidth: "var(--ds-border-width, 1px)", borderStyle: 'solid', borderColor: 'transparent', borderRadius: "var(--ds-radius-small, 4px)", minHeight: '25px', background: "var(--ds-background-neutral-subtle, #00000000)", // eslint-disable-next-line @atlaskit/ui-styling-standard/no-imported-style-values, @atlaskit/ui-styling-standard/no-unsafe-values -- Ignored via go/DSP-18766 transition: `background 0.3s ${akEditorSwoopCubicBezier}, border-color 0.3s ${akEditorSwoopCubicBezier}`, padding: "var(--ds-space-0, 0px)", paddingBottom: "var(--ds-space-0, 0px)", marginTop: "var(--ds-space-050, 4px)", marginBottom: 0, marginLeft: 0, marginRight: 0, // eslint-disable-next-line @atlaskit/ui-styling-standard/no-nested-selectors, @atlaskit/ui-styling-standard/no-unsafe-selectors -- Ignored via go/DSP-18766 'td > :not(style):first-child, td > style:first-child + *': { marginTop: 0 } }); const containerStylesExpanded = css({ background: "var(--ds-surface, #FFFFFF)", paddingBottom: "var(--ds-space-100, 8px)", borderColor: "var(--ds-border, #0B120E24)" }); const containerStylesFocused = css({ borderColor: "var(--ds-border-focused, #4688EC)" }); const containerStylesDataNodeTypeExpand = css({ // eslint-disable-next-line @atlaskit/ui-styling-standard/no-imported-style-values, @atlaskit/ui-styling-standard/no-unsafe-values marginLeft: `-${akLayoutGutterOffset}px`, // eslint-disable-next-line @atlaskit/ui-styling-standard/no-imported-style-values, @atlaskit/ui-styling-standard/no-unsafe-values marginRight: `-${akLayoutGutterOffset}px` }); const titleContainerStyles = css({ display: 'flex', alignItems: 'flex-start', background: 'none', border: 'none', // eslint-disable-next-line @atlaskit/design-system/use-tokens-typography fontSize: `${14 / 16}rem`, width: '100%', color: "var(--ds-text-subtle, #505258)", overflow: 'hidden', cursor: 'pointer', padding: "var(--ds-space-100, 8px)", '&:focus': { outline: 0 } }); const titleContainerStylesExpanded = css({ paddingBottom: "var(--ds-space-0, 0px)" }); const contentContainerStyles = css({ paddingTop: "var(--ds-space-0, 0px)", marginLeft: "var(--ds-space-050, 4px)", paddingRight: "var(--ds-space-200, 16px)", paddingLeft: "var(--ds-space-400, 32px)", display: 'flow-root', visibility: 'hidden', // The follow rules inside @supports block are added as a part of ED-8893 // The fix is targeting mobile bridge on iOS 12 or below, // We should consider remove this fix when we no longer support iOS 12 '@supports not (display: flow-root)': { width: '100%', boxSizing: 'border-box' } }); const contentContainerStylesExpanded = css({ paddingTop: "var(--ds-space-100, 8px)", visibility: 'visible' }); const contentContainerStylesNotExpanded = css({ // eslint-disable-next-line @atlaskit/ui-styling-standard/no-nested-selectors '.expand-content-wrapper, .nestedExpand-content-wrapper': { /* We visually hide the content here to preserve the content during copy+paste */ /* Do not add text nowrap here because inline comment navigation depends on the location of the text */ width: '100%', display: 'block', height: 0, overflow: 'hidden', clip: 'rect(1px, 1px, 1px, 1px)', userSelect: 'none' } }); const clearNextSiblingMarginTopStyle = css({ // eslint-disable-next-line @atlaskit/ui-styling-standard/no-nested-selectors -- Ignored via go/DSP-18766 '& + *': { // eslint-disable-next-line @atlaskit/design-system/ensure-design-token-usage/preview, @atlaskit/ui-styling-standard/no-important-styles -- Ignored via go/DSP-18766 marginTop: '0 !important' } }); // Lazy-loaded children component const LazyChildren = /*#__PURE__*/lazy(() => { return Promise.resolve({ default: ({ children }) => { return /*#__PURE__*/React.createElement(React.Fragment, null, children); } }); }); const Container = props => { return jsx("div", { css: [containerStyles, props['data-node-type'] === 'expand' && containerStylesDataNodeTypeExpand, props.expanded && containerStylesExpanded, props.focused && containerStylesFocused], "data-testid": props['data-testid'], "data-node-type": props['data-node-type'], "data-title": props['data-title'], "data-expanded": props['data-expanded'], "data-local-id": props['data-local-id'] }, props.children); }; const TitleContainer = props => { const { expanded } = props; return ( // eslint-disable-next-line @atlaskit/design-system/no-html-button jsx("button", { type: "button", css: [titleContainerStyles, expanded && titleContainerStylesExpanded], onClick: props.onClick, onFocus: props.onFocus, onBlur: props.onBlur, "aria-labelledby": props['aria-labelledby'], "aria-expanded": props['aria-expanded'], contentEditable: props.contentEditable }, props.children) ); }; TitleContainer.displayName = 'TitleContainerButton'; const ContentContainer = props => { return jsx("div", { css: [contentContainerStyles, props.expanded && contentContainerStylesExpanded, !props.expanded && contentContainerStylesNotExpanded] }, props.children); }; function fireExpandToggleAnalytics(nodeType, expanded, fireAnalyticsEvent) { if (!fireAnalyticsEvent) { return; } fireAnalyticsEvent({ action: ACTION.TOGGLE_EXPAND, actionSubject: nodeType === 'expand' ? ACTION_SUBJECT.EXPAND : ACTION_SUBJECT.NESTED_EXPAND, attributes: { platform: PLATFORM.WEB, mode: MODE.RENDERER, expanded: !expanded }, eventType: EVENT_TYPE.TRACK }); } function Expand({ title, children, nodeType, intl, fireAnalyticsEvent, localId, nestedHeaderIds, rendererContentMode, loadBodyContent }) { const [expanded, setExpanded] = React.useState(false); const [focused, setFocused] = React.useState(false); const [hasLoadedChildren, setHasLoadedChildren] = React.useState(false); const isMobile = false; const label = intl.formatMessage(expanded ? expandMessages.collapseNode : expandMessages.expandNode); const { current: id } = useRef(_uniqueId('expand-title-')); const handleFocus = useCallback(() => setFocused(true), []); const handleBlur = useCallback(() => setFocused(false), []); const isCompactModeSupported = expValEquals('confluence_compact_text_format', 'isEnabled', true) || expValEquals('cc_editor_ai_content_mode', 'variant', 'test') && fg('platform_editor_content_mode_button_mvp'); const isCompact = rendererContentMode === 'compact' && isCompactModeSupported; return jsx(Container, { "data-testid": `expand-container-${nodeType}-${id}`, "data-node-type": nodeType, "data-title": title, "data-expanded": expanded, "data-local-id": localId, expanded: expanded, focused: focused }, nestedHeaderIds && nestedHeaderIds.length > 0 ? jsx(ActiveHeaderIdConsumer, { nestedHeaderIds: nestedHeaderIds // eslint-disable-next-line @atlassian/perf-linting/no-unstable-inline-props -- Ignored via go/ees017 (to be fixed) , onNestedHeaderIdMatch: () => { if (!hasLoadedChildren) { setHasLoadedChildren(true); } setExpanded(true); } }) : null, jsx(TitleContainer // eslint-disable-next-line @atlassian/perf-linting/no-unstable-inline-props -- Ignored via go/ees017 (to be fixed) , { onClick: e => { e.preventDefault(); e.stopPropagation(); fireExpandToggleAnalytics(nodeType, expanded, fireAnalyticsEvent); // Mark children as loaded when expanding for the first time if (!expanded && !hasLoadedChildren) { setHasLoadedChildren(true); } setExpanded(!expanded); e.persist(); // @ts-ignore detail doesn't exist on type e.detail ? handleBlur() : handleFocus(); }, onFocus: handleFocus, onBlur: handleBlur, "aria-labelledby": id, "aria-expanded": expanded, contentEditable: false, expanded: expanded }, isMobile ? jsx(ExpandIconWrapper, { expanded: expanded }, jsx(ChevronRightIcon, { label: label, spacing: "spacious", size: "small" })) : jsx(Tooltip, { content: label, position: "top" // @ts-ignore: [PIT-1685] Fails in post-office due to backwards incompatibility issue with React 18 , tag: ExpandLayoutWrapperWithRef, testId: 'tooltip' }, jsx(ExpandIconWrapper, { expanded: expanded }, jsx(ChevronRightIcon, { label: label, spacing: "spacious", size: "small" }))), jsx("span", { css: [titleStyles, isCompact && titleStylesDense], id: id }, title || intl.formatMessage(expandMessages.expandDefaultTitle))), jsx(ContentContainer, { expanded: expanded }, jsx("div", { className: `${nodeType}-content-wrapper` }, jsx(WidthProvider, null, jsx("div", { css: clearNextSiblingMarginTopStyle }), fg('hot-121622_lazy_load_expand_content') ? hasLoadedChildren || loadBodyContent ? jsx(Suspense, { fallback: jsx("div", null, intl.formatMessage(expandMessages.loading)) }, jsx(LazyChildren, null, children)) : null : children)))); } // eslint-disable-next-line @typescript-eslint/ban-types const _default_1 = injectIntl(Expand); export default _default_1;