@atlaskit/editor-plugin-block-controls
Version:
Block controls plugin for @atlaskit/editor-core
586 lines (580 loc) • 40.3 kB
JavaScript
/**
* @jsxRuntime classic
* @jsx jsx
*/
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-global-styles, @atlaskit/ui-styling-standard/use-compiled, @typescript-eslint/consistent-type-imports
import { css, Global, jsx } from '@emotion/react';
import { useSharedPluginStateWithSelector } from '@atlaskit/editor-common/hooks';
import { ANCHOR_VARIABLE_NAME, DRAG_HANDLE_WIDTH, isCSSAnchorSupported, tableControlsSpacing } from '@atlaskit/editor-common/styles';
import { areToolbarFlagsEnabled } from '@atlaskit/editor-common/toolbar-flag-check';
import { ZERO_WIDTH_SPACE } from '@atlaskit/editor-common/whitespace';
import { akEditorBreakoutPadding, akEditorCalculatedWideLayoutWidth, akEditorCalculatedWideLayoutWidthSmallViewport, akEditorFullPageNarrowBreakout, akEditorGutterPaddingDynamic, akEditorGutterPaddingReduced } from '@atlaskit/editor-shared-styles';
import { layers } from '@atlaskit/theme/constants';
import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals';
import { editorExperiment } from '@atlaskit/tmp-editor-statsig/experiments';
import { DRAG_HANDLE_MAX_WIDTH_PLUS_GAP } from './consts';
import { NODE_ANCHOR_ATTR_NAME } from './utils/dom-attr-name';
/**
* This anchor element selector disregards anchors that are solely utilized for size measurements,
* including those within table rows and media.
*/
const dragHandlerAnchorSelector = '[data-drag-handler-anchor-name]:not([data-drag-handler-node-type="tableRow"], [data-drag-handler-node-type="media"])';
/**
* Disregards anchors that can not have handles next to them, and so shouldn't have an extended hover zone
*/
const dragHandlerAnchorSelectorNext = `[${NODE_ANCHOR_ATTR_NAME}]:not([data-prosemirror-node-name="tableRow"], [data-prosemirror-node-name="tableCell"], [data-prosemirror-node-name="tableHeader"], [data-prosemirror-node-name="media"], [data-prosemirror-node-inline="true"])`;
/**
* Extended version that also excludes descendants of taskList.
* preventing the ::after hover zone from blocking checkbox inputs in blockTaskItem nodes.
*/
const dragHandlerAnchorSelectorWithTaskExclusion = `[${NODE_ANCHOR_ATTR_NAME}]:not([data-prosemirror-node-name="tableRow"], [data-prosemirror-node-name="tableCell"], [data-prosemirror-node-name="tableHeader"], [data-prosemirror-node-name="media"], [data-prosemirror-node-inline="true"], [data-prosemirror-node-name="taskList"] [${NODE_ANCHOR_ATTR_NAME}])`;
const gutterPaddingWidth = () => editorExperiment('platform_editor_controls', 'variant1') ? `${akEditorGutterPaddingDynamic()}px` : '100%';
const gutterPaddingLeft = () => editorExperiment('platform_editor_controls', 'variant1') ? `-${akEditorGutterPaddingDynamic()}px` : '-100px';
const extendedHoverZone = () => css({
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-nested-selectors, @atlaskit/ui-styling-standard/no-unsafe-values
[`.block-ctrl-drag-preview ${dragHandlerAnchorSelector}::after`]: {
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-important-styles
display: 'none !important'
},
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-nested-selectors
'.ProseMirror': {
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-nested-selectors, @atlaskit/ui-styling-standard/no-unsafe-selectors, @atlaskit/ui-styling-standard/no-unsafe-values
[`&& ${dragHandlerAnchorSelector}::after`]: {
content: '""',
position: 'absolute',
top: 0,
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-unsafe-values, @atlaskit/ui-styling-standard/no-imported-style-values
left: `-${DRAG_HANDLE_MAX_WIDTH_PLUS_GAP}px`,
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-unsafe-values, @atlaskit/ui-styling-standard/no-imported-style-values
width: `${DRAG_HANDLE_MAX_WIDTH_PLUS_GAP}px`,
height: '100%',
cursor: 'default',
zIndex: 1
},
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-nested-selectors, @atlaskit/ui-styling-standard/no-unsafe-selectors, @atlaskit/ui-styling-standard/no-unsafe-values
[`&& [data-drag-handler-anchor-depth="0"]${dragHandlerAnchorSelector}::after`]: {
content: '""',
position: 'absolute',
top: 0,
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-imported-style-values, @atlaskit/ui-styling-standard/no-unsafe-values -- Ignored via go/DSP-18766
left: gutterPaddingLeft(),
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-imported-style-values, @atlaskit/ui-styling-standard/no-unsafe-values -- Ignored via go/DSP-18766
width: gutterPaddingWidth(),
height: '100%',
cursor: 'default',
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-imported-style-values, @atlaskit/ui-styling-standard/no-unsafe-values
zIndex: -1
},
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-nested-selectors, @atlaskit/ui-styling-standard/no-unsafe-selectors, @atlaskit/ui-styling-standard/no-unsafe-values
[`&& :is(.pm-table-cell-content-wrap, .pm-table-header-content-wrap) > ${dragHandlerAnchorSelector}::after`]: {
content: '""',
position: 'absolute',
top: 0,
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-unsafe-values, @atlaskit/ui-styling-standard/no-imported-style-values
left: 0,
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-unsafe-values, @atlaskit/ui-styling-standard/no-imported-style-values
width: 0,
height: '100%',
cursor: 'default',
zIndex: 1
},
// hover zone for layout column should be placed near the top of the column (where drag handle is)
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-nested-selectors, @atlaskit/ui-styling-standard/no-unsafe-selectors
'&& [data-drag-handler-anchor-name][data-layout-column]::after': {
content: '""',
position: 'absolute',
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-unsafe-values, @atlaskit/ui-styling-standard/no-imported-style-values
top: `${-DRAG_HANDLE_WIDTH / 2}px`,
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-unsafe-values, @atlaskit/ui-styling-standard/no-imported-style-values
left: 0,
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-unsafe-values, @atlaskit/ui-styling-standard/no-imported-style-values
width: '100%',
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-imported-style-values, @atlaskit/ui-styling-standard/no-unsafe-values
height: `${DRAG_HANDLE_WIDTH}px`,
cursor: 'default',
zIndex: 1
}
},
// TODO: ED-23995 - this style override needs to be moved to the Rule styles after FF cleanup packages/editor/editor-common/src/styles/shared/rule.ts
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-nested-selectors
'hr[data-drag-handler-anchor-name]': {
overflow: 'visible'
},
//Hide pseudo element at top depth level. Leave for nested depths to prevent mouseover loop.
//eslint-disable-next-line @atlaskit/ui-styling-standard/no-nested-selectors
'[data-blocks-drag-handle-container="true"] + [data-drag-handler-anchor-depth="0"]::after': {
display: 'none'
}
});
const extendedHoverZoneNext = () => css({
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-nested-selectors, @atlaskit/ui-styling-standard/no-unsafe-values, @atlaskit/ui-styling-standard/no-imported-style-values
[`.block-ctrl-drag-preview ${expValEquals('platform_editor_unify_native_dnd_selectors', 'isEnabled', true) ? dragHandlerAnchorSelectorWithTaskExclusion : dragHandlerAnchorSelectorNext}::after`]: {
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-important-styles
display: 'none !important'
},
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-nested-selectors
'.ProseMirror': {
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-nested-selectors, @atlaskit/ui-styling-standard/no-unsafe-selectors, @atlaskit/ui-styling-standard/no-unsafe-values, @atlaskit/ui-styling-standard/no-imported-style-values
[`&& ${expValEquals('platform_editor_unify_native_dnd_selectors', 'isEnabled', true) ? dragHandlerAnchorSelectorWithTaskExclusion : dragHandlerAnchorSelectorNext}::after`]: {
content: '""',
position: 'absolute',
top: 0,
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-unsafe-values, @atlaskit/ui-styling-standard/no-imported-style-values
left: `-${DRAG_HANDLE_MAX_WIDTH_PLUS_GAP}px`,
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-unsafe-values, @atlaskit/ui-styling-standard/no-imported-style-values
width: `${DRAG_HANDLE_MAX_WIDTH_PLUS_GAP}px`,
height: '100%',
cursor: 'default',
zIndex: 1
},
// Top level depth hover zone should extend to gutter padding area
// we select the top level by using NOT nested anchor selector
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-nested-selectors, @atlaskit/ui-styling-standard/no-unsafe-selectors, @atlaskit/ui-styling-standard/no-unsafe-values, @atlaskit/ui-styling-standard/no-imported-style-values
[`&& ${expValEquals('platform_editor_unify_native_dnd_selectors', 'isEnabled', true) ? dragHandlerAnchorSelectorWithTaskExclusion : dragHandlerAnchorSelectorNext}:not([${NODE_ANCHOR_ATTR_NAME}] [${NODE_ANCHOR_ATTR_NAME}])::after`]: {
content: '""',
position: 'absolute',
top: 0,
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-imported-style-values, @atlaskit/ui-styling-standard/no-unsafe-values -- Ignored via go/DSP-18766
left: gutterPaddingLeft(),
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-imported-style-values, @atlaskit/ui-styling-standard/no-unsafe-values -- Ignored via go/DSP-18766
width: gutterPaddingWidth(),
height: '100%',
cursor: 'default',
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-imported-style-values, @atlaskit/ui-styling-standard/no-unsafe-values
zIndex: -1
},
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-nested-selectors, @atlaskit/ui-styling-standard/no-unsafe-selectors, @atlaskit/ui-styling-standard/no-unsafe-values, @atlaskit/ui-styling-standard/no-imported-style-values
[`&& :is(.pm-table-cell-content-wrap, .pm-table-header-content-wrap) > ${expValEquals('platform_editor_unify_native_dnd_selectors', 'isEnabled', true) ? dragHandlerAnchorSelectorWithTaskExclusion : dragHandlerAnchorSelectorNext}::after`]: {
content: '""',
position: 'absolute',
top: 0,
left: 0,
width: 0,
height: '100%',
cursor: 'default',
zIndex: 1
}
},
// TODO: ED-23995 - this style override needs to be moved to the Rule styles after FF cleanup packages/editor/editor-common/src/styles/shared/rule.ts
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-nested-selectors
'hr[data-drag-handler-anchor-name]': {
overflow: 'visible'
},
//Hide pseudo element at top depth level. Leave for nested depths to prevent mouseover loop.
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-unsafe-values, @atlaskit/ui-styling-standard/no-imported-style-values
[`[data-blocks-drag-handle-container="true"] + ${expValEquals('platform_editor_unify_native_dnd_selectors', 'isEnabled', true) ? dragHandlerAnchorSelectorWithTaskExclusion : dragHandlerAnchorSelectorNext}:not([${NODE_ANCHOR_ATTR_NAME}] [${NODE_ANCHOR_ATTR_NAME}])::after`]: {
display: 'none'
}
});
const layoutColumnExtendedHoverZone = css({
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-nested-selectors
'.ProseMirror': {
// hover zone for layout column should be placed near the top of the column (where drag handle is)
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-nested-selectors, @atlaskit/ui-styling-standard/no-unsafe-selectors, @atlaskit/ui-styling-standard/no-unsafe-values, @atlaskit/ui-styling-standard/no-imported-style-values
[`&&& ${expValEquals('platform_editor_unify_native_dnd_selectors', 'isEnabled', true) ? dragHandlerAnchorSelectorWithTaskExclusion : dragHandlerAnchorSelectorNext}[data-layout-column]::after`]: {
content: '""',
position: 'absolute',
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-unsafe-values, @atlaskit/ui-styling-standard/no-imported-style-values
top: `${-DRAG_HANDLE_WIDTH / 2}px`,
left: 0,
width: '100%',
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-imported-style-values, @atlaskit/ui-styling-standard/no-unsafe-values
height: `${DRAG_HANDLE_WIDTH}px`,
cursor: 'default',
zIndex: 1
}
}
});
const layoutColumnWithoutHoverZone = css({
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-nested-selectors
'.ProseMirror': {
// when advanced_layouts is off, layout columns should not have hover zones, because there aren't any drag handles for layout columns
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-nested-selectors, @atlaskit/ui-styling-standard/no-unsafe-selectors, @atlaskit/ui-styling-standard/no-unsafe-values, @atlaskit/ui-styling-standard/no-imported-style-values
[`&&& ${expValEquals('platform_editor_unify_native_dnd_selectors', 'isEnabled', true) ? dragHandlerAnchorSelectorWithTaskExclusion : dragHandlerAnchorSelectorNext}[data-layout-column]::after`]: {
display: 'none'
}
}
});
const extendHoverZoneReduced = css({
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-nested-selectors
'.ProseMirror': {
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-nested-selectors, @atlaskit/ui-styling-standard/no-unsafe-selectors, @atlaskit/ui-styling-standard/no-unsafe-values
[`&& [data-drag-handler-anchor-depth="0"]${dragHandlerAnchorSelector}::after`]: {
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-container-queries, @atlaskit/ui-styling-standard/no-imported-style-values, @atlaskit/ui-styling-standard/no-unsafe-values
[`@container editor-area (max-width: ${akEditorFullPageNarrowBreakout}px)`]: {
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-imported-style-values, @atlaskit/ui-styling-standard/no-unsafe-values
left: `-${akEditorGutterPaddingReduced}px`,
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-imported-style-values, @atlaskit/ui-styling-standard/no-unsafe-values
width: `${akEditorGutterPaddingReduced}px`
}
}
}
});
const extendHoverZoneReducedNext = css({
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-nested-selectors
'.ProseMirror': {
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-nested-selectors, @atlaskit/ui-styling-standard/no-unsafe-selectors, @atlaskit/ui-styling-standard/no-unsafe-values, @atlaskit/ui-styling-standard/no-imported-style-values
[`> ${expValEquals('platform_editor_unify_native_dnd_selectors', 'isEnabled', true) ? dragHandlerAnchorSelectorWithTaskExclusion : dragHandlerAnchorSelectorNext}::after`]: {
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-container-queries, @atlaskit/ui-styling-standard/no-imported-style-values, @atlaskit/ui-styling-standard/no-unsafe-values
[`@container editor-area (max-width: ${akEditorFullPageNarrowBreakout}px)`]: {
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-imported-style-values, @atlaskit/ui-styling-standard/no-unsafe-values
left: `-${akEditorGutterPaddingReduced}px`,
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-imported-style-values, @atlaskit/ui-styling-standard/no-unsafe-values
width: `${akEditorGutterPaddingReduced}px`
}
}
}
});
const extendedDragZone = css({
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-nested-selectors
'.ProseMirror': {
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-nested-selectors, @atlaskit/ui-styling-standard/no-unsafe-selectors, @atlaskit/ui-styling-standard/no-unsafe-values
[`&& [data-drag-handler-anchor-depth="0"]${dragHandlerAnchorSelector}::after`]: {
width: 'var(--ak-editor-max-container-width)',
left: `calc((100% - var(--ak-editor-max-container-width))/2)`
}
}
});
const extendedDragZoneNext = css({
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-nested-selectors
'.ProseMirror': {
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-nested-selectors, @atlaskit/ui-styling-standard/no-unsafe-selectors, @atlaskit/ui-styling-standard/no-unsafe-values, @atlaskit/ui-styling-standard/no-imported-style-values
[`&& ${expValEquals('platform_editor_unify_native_dnd_selectors', 'isEnabled', true) ? dragHandlerAnchorSelectorWithTaskExclusion : dragHandlerAnchorSelectorNext}:not([${NODE_ANCHOR_ATTR_NAME}] [${NODE_ANCHOR_ATTR_NAME}])::after`]: {
width: 'var(--ak-editor-max-container-width)',
left: `calc((100% - var(--ak-editor-max-container-width))/2)`
}
}
});
const paragraphWithTrailingBreakAsOnlyChild = '+ :is(p, h1, h2, h3, h4, h5, h6) > .ProseMirror-trailingBreak:only-child';
const indentatedParagraphWithTrailingBreakAsOnlyChild = '+ div.fabric-editor-indentation-mark > :is(p, h1, h2, h3, h4, h5, h6) > .ProseMirror-trailingBreak:only-child';
const paragraphWithPlaceholder = '+ p > .placeholder-decoration';
const dragHandleContainer = '.ProseMirror-widget[data-blocks-drag-handle-container="true"]';
const dragHandleSelector = 'button[data-testid="block-ctrl-drag-handle"]';
const dropTargetContainer = '.ProseMirror-widget[data-blocks-drop-target-container="true"]';
const dividerBodiedInCustomPanelWithNoIconSelector = '[data-panel-type].ak-editor-panel__no-icon .ProseMirror-widget:first-child + .ProseMirror-widget:nth-child(2) + hr, [data-panel-type] hr:first-child';
const withInlineNodeStyleSelectors = [`${dragHandleContainer}:has(${paragraphWithTrailingBreakAsOnlyChild}) ${dragHandleSelector}`, `${dragHandleContainer}:has(${indentatedParagraphWithTrailingBreakAsOnlyChild}) ${dragHandleSelector}`, `${dragHandleContainer}:has(${paragraphWithPlaceholder}) ${dragHandleSelector}`].join(', ');
const withFormatInLayoutStyleFixSelectors = [`${dragHandleContainer}:first-child + .fabric-editor-indentation-mark > p:first-child`, `${dragHandleContainer}:first-child + .fabric-editor-alignment > p:first-child`, `${dragHandleContainer}:first-child + .fabric-editor-font-size > p:first-child`, `${dragHandleContainer}:first-child + ${dropTargetContainer} + .fabric-editor-indentation-mark > p:first-child`, `${dragHandleContainer}:first-child + ${dropTargetContainer} + .fabric-editor-alignment > p:first-child`, `${dragHandleContainer}:first-child + ${dropTargetContainer} + .fabric-editor-font-size > p:first-child`, `${dropTargetContainer}:first-child + .fabric-editor-alignment > p:first-child`, `${dropTargetContainer}:first-child + .fabric-editor-indentation-mark > p:first-child`, `${dropTargetContainer}:first-child + .fabric-editor-font-size > p:first-child`, `${dragHandleContainer}:first-child + .fabric-editor-indentation-mark > :is(h1, h2, h3, h4, h5, h6):first-child`, `${dragHandleContainer}:first-child + .fabric-editor-font-size > :is(h1, h2, h3, h4, h5, h6):first-child`].join(', ');
/**
* Please do not change change transform to display:none, or visibility:hidden
* Otherwise it might break composition input for Chrome
* https://product-fabric.atlassian.net/browse/ED-24136
*/
const withInlineNodeStyle = css({
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-nested-selectors, @atlaskit/ui-styling-standard/no-unsafe-values
[withInlineNodeStyleSelectors]: {
transform: 'scale(0)'
}
});
const legacyBreakoutWideLayoutStyle = css({
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-nested-selectors, @atlaskit/ui-styling-standard/no-unsafe-values
'.ProseMirror-widget[data-blocks-drop-target-container="true"]': {
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-imported-style-values, @atlaskit/ui-styling-standard/no-unsafe-values
'--ak-editor--legacy-breakout-wide-layout-width': `${akEditorCalculatedWideLayoutWidthSmallViewport}px`,
'@media (width>=1280px)': {
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-imported-style-values, @atlaskit/ui-styling-standard/no-unsafe-values
'--ak-editor--legacy-breakout-wide-layout-width': `${akEditorCalculatedWideLayoutWidth}px`
}
}
});
const globalDnDStyle = css({
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-nested-selectors
'.ProseMirror': {
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-nested-selectors, @atlaskit/ui-styling-standard/no-unsafe-selectors, @atlaskit/ui-styling-standard/no-unsafe-values
'[data-layout-content]': {
userDrag: 'none'
}
}
});
const globalStyles = () => css({
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-nested-selectors, @atlaskit/ui-styling-standard/no-unsafe-selectors -- Ignored via go/DSP-18766
'.ProseMirror-widget:first-child + *:not([data-panel-type], .code-block, [data-node-type="nestedExpand"], [data-node-type="expand"], [data-layout-section="true"], [data-prosemirror-node-name="bodiedSyncBlock"])': {
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-important-styles -- Ignored via go/DSP-18766
marginTop: '0 !important'
},
// Font-size wrapper is a div with no inherent margin — reach through to the content node inside.
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-nested-selectors, @atlaskit/ui-styling-standard/no-unsafe-selectors
'.ProseMirror-widget:first-child + .fabric-editor-font-size > :is(p, h1, h2, h3, h4, h5, h6):first-child, .ProseMirror-widget:first-child + .ProseMirror-widget + .fabric-editor-font-size > :is(p, h1, h2, h3, h4, h5, h6):first-child': {
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-important-styles
marginTop: '0 !important'
}
});
const quickInsertStyles = () => css({
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-nested-selectors
'.blocks-quick-insert-button': {
backgroundColor: 'transparent',
top: `var(--top-override,8px)`,
position: 'sticky',
boxSizing: 'border-box',
display: 'flex',
flexDirection: 'column',
justifyContent: 'center',
alignItems: 'center',
height: "var(--ds-space-300, 24px)",
width: "var(--ds-space-300, 24px)",
border: 'none',
borderRadius: "var(--ds-radius-full, 9999px)",
zIndex: layers.card(),
outline: 'none',
cursor: 'pointer',
color: "var(--ds-icon-subtle, #505258)"
},
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-nested-selectors, @atlaskit/ui-styling-standard/no-unsafe-selectors
'[data-blocks-quick-insert-container]:has(~ [data-prosemirror-node-name="table"] .pm-table-with-controls tr.sticky) &': {
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-imported-style-values, @atlaskit/ui-styling-standard/no-unsafe-values
'--top-override': `${tableControlsSpacing}px`
},
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-nested-selectors, @atlaskit/ui-styling-standard/no-unsafe-selectors
'[data-prosemirror-mark-name="breakout"]:has([data-blocks-quick-insert-container]):has(~ [data-prosemirror-node-name="table"] .pm-table-with-controls tr.sticky) &': {
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-imported-style-values, @atlaskit/ui-styling-standard/no-unsafe-values
'--top-override': `${tableControlsSpacing}px`
},
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-nested-selectors
'.blocks-quick-insert-button:hover': {
backgroundColor: "var(--ds-background-neutral-subtle-hovered, #0515240F)"
},
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-nested-selectors
'.blocks-quick-insert-button:active': {
backgroundColor: "var(--ds-background-neutral-subtle-pressed, #0B120E24)"
},
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-nested-selectors
'.blocks-quick-insert-button:focus': {
outline: `${"var(--ds-border-width-focused, 2px)"} solid ${"var(--ds-border-focused, #4688EC)"}`
},
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-nested-selectors
'.blocks-quick-insert-visible-container': {
transition: 'opacity 0.1s ease-in-out, visibility 0.1s ease-in-out',
opacity: 1,
visibility: 'visible'
},
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-nested-selectors
'.blocks-quick-insert-invisible-container': {
transition: 'opacity 0.1s ease-in-out, visibility 0.1s ease-in-out',
opacity: 0,
visibility: 'hidden'
},
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-nested-selectors
'.blocks-quick-insert-tooltip': {
zIndex: layers.tooltip(),
borderRadius: "var(--ds-radius-small, 4px)",
padding: `${"var(--ds-space-050, 4px)"} 0`,
boxSizing: 'border-box',
maxWidth: '240px',
backgroundColor: "var(--ds-background-neutral-bold, #292A2E)",
color: "var(--ds-text-inverse, #FFFFFF)",
font: "var(--ds-font-body-small, normal 400 12px/16px \"Atlassian Sans\", ui-sans-serif, -apple-system, BlinkMacSystemFont, \"Segoe UI\", Ubuntu, \"Helvetica Neue\", sans-serif)",
insetBlockStart: "var(--ds-space-0, 0px)",
insetInlineStart: "var(--ds-space-0, 0px)",
overflowWrap: 'break-word',
paddingBlockEnd: "var(--ds-space-025, 2px)",
paddingBlockStart: "var(--ds-space-025, 2px)",
paddingInlineEnd: "var(--ds-space-075, 6px)",
paddingInlineStart: "var(--ds-space-075, 6px)",
wordWrap: 'break-word',
pointerEvents: 'none',
userSelect: 'none',
// Based on: platform/packages/design-system/motion/src/entering/keyframes-motion.tsx
transition: 'opacity .1s ease-in-out, transform .1s ease-in-out, visibility .1s ease-in-out',
'@media (prefers-reduced-motion: reduce)': {
transition: 'none'
}
}
});
const topLevelNodeMarginStyles = css({
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-nested-selectors, @atlaskit/ui-styling-standard/no-unsafe-selectors -- Ignored via go/DSP-18766
'.ProseMirror': {
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-nested-selectors, @atlaskit/ui-styling-standard/no-unsafe-selectors
'> .ProseMirror-widget:first-child + .ProseMirror-gapcursor + *:not([data-layout-section="true"], [data-prosemirror-node-name="bodiedSyncBlock"]), > .ProseMirror-widget:first-child + *:not([data-layout-section="true"], [data-prosemirror-node-name="bodiedSyncBlock"])': {
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-important-styles -- Ignored via go/DSP-18766
marginTop: '0 !important'
},
// When a drop target widget is inserted during drag, the font-size wrapper is no longer
// adjacent to the first widget. Reach through the wrapper to zero the inner content margin.
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-nested-selectors, @atlaskit/ui-styling-standard/no-unsafe-selectors
'> .ProseMirror-widget:first-child + .ProseMirror-widget + .fabric-editor-font-size > :is(p, h1, h2, h3, h4, h5, h6):first-child, > .ProseMirror-widget:first-child + .ProseMirror-gapcursor + .fabric-editor-font-size > :is(p, h1, h2, h3, h4, h5, h6):first-child': {
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-important-styles
marginTop: '0 !important'
}
}
});
const withDividerInPanelStyleFix = css({
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-nested-selectors, @atlaskit/ui-styling-standard/no-unsafe-values
[`${dividerBodiedInCustomPanelWithNoIconSelector}`]: {
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-important-styles
marginTop: '0 !important'
}
});
const withDeleteLinesStyleFix = css({
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-nested-selectors, @atlaskit/ui-styling-standard/no-unsafe-values
[`p[data-drag-handler-anchor-name] ${dragHandleContainer}`]: {
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-important-styles
display: 'none !important'
}
});
// Image dnd is broken in Firefox due to a previous fix for image caption https://product-fabric.atlassian.net/browse/ED-14034
// We could remove this fix if the previous issue is invalid
const withMediaSingleStyleFix = css({
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-nested-selectors, @atlaskit/ui-styling-standard/no-unsafe-values
['.ProseMirror.ua-firefox .mediaSingleView-content-wrap[data-drag-handler-node-type="mediaSingle"][data-drag-handler-anchor-name], .ProseMirror.ua-firefox [data-drag-handler-anchor-name][data-drag-handler-node-type] .mediaSingleView-content-wrap']: {
userSelect: 'auto',
cursor: 'pointer'
}
});
const withFormatInLayoutStyleFix = css({
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-nested-selectors, @atlaskit/ui-styling-standard/no-unsafe-values
[`${withFormatInLayoutStyleFixSelectors}`]: {
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-important-styles
marginTop: '0 !important'
}
});
const headingWithIndentationInLayoutStyleFix = css({
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-nested-selectors, @atlaskit/ui-styling-standard/no-unsafe-values
[`${dragHandleContainer}:first-child + .fabric-editor-indentation-mark > :is(h1, h2, h3, h4, h5, h6):first-child`]: {
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-important-styles
marginTop: '0 !important'
}
});
const withRelativePosStyle = css({
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-nested-selectors
'.ProseMirror': {
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-nested-selectors, @atlaskit/ui-styling-standard/no-unsafe-selectors, @atlaskit/ui-styling-standard/no-unsafe-values
[`&& ${dragHandlerAnchorSelector}`]: {
position: 'relative'
},
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-nested-selectors, @atlaskit/ui-styling-standard/no-unsafe-selectors, @atlaskit/ui-styling-standard/no-unsafe-values
[`&& ${dragHandlerAnchorSelector}:has(> .ProseMirror-trailingBreak:only-child)::before`]: {
// Workaround to force safari to show the cursor on blank lines even when there is no content
// See: CONFCLOUD-80210
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-imported-style-values, @atlaskit/ui-styling-standard/no-unsafe-values
content: `"${ZERO_WIDTH_SPACE}"`
}
}
});
const withRelativePosStyleNext = css({
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-nested-selectors
'.ProseMirror': {
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-nested-selectors, @atlaskit/ui-styling-standard/no-unsafe-selectors, @atlaskit/ui-styling-standard/no-unsafe-values
[`&& ${dragHandlerAnchorSelectorNext}`]: {
position: 'relative'
},
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-nested-selectors, @atlaskit/ui-styling-standard/no-unsafe-selectors, @atlaskit/ui-styling-standard/no-unsafe-values
[`&& ${dragHandlerAnchorSelectorNext}:has(> .ProseMirror-trailingBreak:only-child)::before`]: {
// Workaround to force safari to show the cursor on blank lines even when there is no content
// See: CONFCLOUD-80210
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-imported-style-values, @atlaskit/ui-styling-standard/no-unsafe-values
content: `"${ZERO_WIDTH_SPACE}"`
}
}
});
const withAnchorNameZindexStyle = css({
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-nested-selectors
'.ProseMirror': {
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-nested-selectors, @atlaskit/ui-styling-standard/no-unsafe-selectors
'&& [data-drag-handler-anchor-depth="0"][data-drag-handler-anchor-name]': {
zIndex: 1
}
}
});
const withAnchorNameZindexStyleNext = css({
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-nested-selectors
'.ProseMirror': {
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-nested-selectors, @atlaskit/ui-styling-standard/no-unsafe-selectors, @atlaskit/ui-styling-standard/no-unsafe-values, @atlaskit/ui-styling-standard/no-imported-style-values
[`&& [${NODE_ANCHOR_ATTR_NAME}]:not([${NODE_ANCHOR_ATTR_NAME}] [${NODE_ANCHOR_ATTR_NAME}])`]: {
zIndex: 1
}
}
});
// This style is used to define width for block card (with datasource) that does not have layout
// In full-width editor, block card has width of full-width layout
// In fixed-width editor, block card has width of wide layout
const blockCardWithoutLayout = css({
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-nested-selectors
'.ak-editor-content-area.fabric-editor--full-width-mode .ProseMirror .ProseMirror-widget[data-blocks-drop-target-container="true"]': {
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-imported-style-values, @atlaskit/ui-styling-standard/no-unsafe-values
'--ak-editor-block-card-width': `min(calc(100cqw - ${akEditorBreakoutPadding}px), 1800px)`
},
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-nested-selectors, @atlaskit/ui-styling-standard/no-unsafe-selectors
'.ak-editor-content-area .ProseMirror .ProseMirror-widget[data-blocks-drop-target-container="true"]': {
'--ak-editor-block-card-width': 'max(var(--ak-editor--legacy-breakout-wide-layout-width), var(--ak-editor--line-length))'
}
});
const nextAnchorSelector = ['&[data-node-anchor]',
// adjacent sibling with anchor
'&:not([data-node-anchor]) [data-node-anchor]:first-of-type',
// first nested anchor inside adjacent sibling
'&.ProseMirror-widget + [data-node-anchor]',
// adjacent sibling with anchor (when next to a widget like gap cursor)
'&.ProseMirror-widget + :not([data-node-anchor]) [data-node-anchor]:first-of-type' // first nested anchor inside adjacent sibling (when next to a widget like gap cursor)
].join(', ');
const dragHandlerAnchorStyles = css({
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-nested-selectors
'.ProseMirror': {
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-nested-selectors
'[data-testid="block-ctrl-decorator-widget"] + *': {
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-nested-selectors, @atlaskit/ui-styling-standard/no-unsafe-selectors, @atlaskit/ui-styling-standard/no-unsafe-values, @atlaskit/ui-styling-standard/no-imported-style-values
[`${nextAnchorSelector}`]: {
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-unsafe-values, @atlaskit/ui-styling-standard/no-imported-style-values
anchorName: `var(${ANCHOR_VARIABLE_NAME}, attr(data-node-anchor type(<custom-ident>)))`
}
},
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-nested-selectors
'[data-testid="block-ctrl-quick-insert-button"] + *': {
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-nested-selectors, @atlaskit/ui-styling-standard/no-unsafe-selectors, @atlaskit/ui-styling-standard/no-unsafe-values, @atlaskit/ui-styling-standard/no-imported-style-values
[`${nextAnchorSelector}`]: {
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-unsafe-values, @atlaskit/ui-styling-standard/no-imported-style-values
anchorName: `var(${ANCHOR_VARIABLE_NAME}, attr(data-node-anchor type(<custom-ident>)))`
}
}
}
});
// Styles applied to nodes with anchors when dragging
const dragAnchorStyles = css({
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-nested-selectors
'.ProseMirror': {
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-nested-selectors, @atlaskit/ui-styling-standard/no-unsafe-selectors
'[data-node-anchor]:not([data-node-anchor] [data-node-anchor])': {
// all top level nodes with anchor
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-unsafe-values, @atlaskit/ui-styling-standard/no-imported-style-values
anchorName: `var(${ANCHOR_VARIABLE_NAME}, attr(data-node-anchor type(<custom-ident>)))`
},
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-nested-selectors, @atlaskit/ui-styling-standard/no-unsafe-selectors
'[data-node-anchor]:has([data-blocks-drop-target-container]) [data-node-anchor]': {
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-unsafe-values, @atlaskit/ui-styling-standard/no-imported-style-values
anchorName: `var(${ANCHOR_VARIABLE_NAME}, attr(data-node-anchor type(<custom-ident>)))`
},
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-nested-selectors
'[data-prosemirror-node-name="media"][data-node-anchor]': {
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-unsafe-values, @atlaskit/ui-styling-standard/no-imported-style-values
anchorName: `var(${ANCHOR_VARIABLE_NAME}, attr(data-node-anchor type(<custom-ident>)))`
},
// first table row to avoid multiple anchors in table
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-nested-selectors, @atlaskit/ui-styling-standard/no-unsafe-selectors
'[data-prosemirror-node-name="table"] [data-prosemirror-node-name="tableRow"][data-node-anchor]:first-of-type': {
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-unsafe-values, @atlaskit/ui-styling-standard/no-imported-style-values
anchorName: `var(${ANCHOR_VARIABLE_NAME}, attr(data-node-anchor type(<custom-ident>)))`
}
}
});
export const GlobalStylesWrapper = ({
api
}) => {
const {
isDragging: isDraggingFromState
} = useSharedPluginStateWithSelector(api, ['blockControls'], states => {
var _states$blockControls;
return {
isDragging: (_states$blockControls = states.blockControlsState) === null || _states$blockControls === void 0 ? void 0 : _states$blockControls.isDragging
};
});
const isDragging = expValEquals('platform_editor_block_controls_perf_optimization', 'isEnabled', true) ? isDraggingFromState : false;
const shouldRenderAnchors = isCSSAnchorSupported() && expValEquals('platform_editor_native_anchor_with_dnd', 'isEnabled', true);
const toolbarFlagsEnabled = areToolbarFlagsEnabled(Boolean(api === null || api === void 0 ? void 0 : api.toolbar));
return jsx(Global
// eslint-disable-next-line @atlassian/perf-linting/no-unstable-inline-props -- Ignored via go/ees017 (to be fixed)
, {
styles: [globalStyles(), globalDnDStyle, expValEquals('platform_editor_native_anchor_with_dnd', 'isEnabled', true) ? extendedHoverZoneNext() : extendedHoverZone(), isDragging && (expValEquals('platform_editor_native_anchor_with_dnd', 'isEnabled', true) ? extendedDragZoneNext : extendedDragZone), editorExperiment('platform_editor_preview_panel_responsiveness', true, {
exposure: true
}) ? expValEquals('platform_editor_native_anchor_with_dnd', 'isEnabled', true) ? extendHoverZoneReducedNext : extendHoverZoneReduced : undefined,
// platform_editor_controls note: this allows drag handles to render on empty lines
toolbarFlagsEnabled ? undefined : withInlineNodeStyle, editorExperiment('platform_editor_block_control_optimise_render', true) ? quickInsertStyles : undefined, withDeleteLinesStyleFix, withMediaSingleStyleFix, legacyBreakoutWideLayoutStyle, headingWithIndentationInLayoutStyleFix, editorExperiment('advanced_layouts', true) ? blockCardWithoutLayout : undefined, withDividerInPanelStyleFix, withFormatInLayoutStyleFix, expValEquals('platform_editor_native_anchor_with_dnd', 'isEnabled', true) ? withRelativePosStyleNext : withRelativePosStyle, topLevelNodeMarginStyles, expValEquals('platform_editor_native_anchor_with_dnd', 'isEnabled', true) ? withAnchorNameZindexStyleNext : withAnchorNameZindexStyle, expValEquals('platform_editor_native_anchor_with_dnd', 'isEnabled', true) && expValEquals('advanced_layouts', 'isEnabled', true) ? layoutColumnExtendedHoverZone : layoutColumnWithoutHoverZone, shouldRenderAnchors && (isDragging ? dragAnchorStyles : dragHandlerAnchorStyles)]
});
};