UNPKG

@atlaskit/editor-common

Version:

A package that contains common classes and components for editor and renderer

91 lines (90 loc) 3.03 kB
import React, { useEffect, useState } from 'react'; import debounce from 'lodash/debounce'; import { fg } from '@atlaskit/platform-feature-flags'; import { Box, xcss } from '@atlaskit/primitives'; const MEDIA_BADGE_VISIBILITY_BREAKPOINT = 200; const containerStyles = xcss({ display: 'flex', position: 'absolute', top: 'space.0', right: 'space.0', // eslint-disable-next-line @atlaskit/design-system/use-tokens-typography lineHeight: "var(--ds-space-200, 16px)", gap: 'space.025', zIndex: 'card', height: 'fit-content', width: 'fit-content', margin: 'space.075' }); // The above styles are used for both editor and renderer, and in renderer the // document body is the main scroll area. This means it overscrolls the primary // toolbar, where the z-index is "2". We have to hack in our own z-index less // than that to ensure our badge appears under the toolbar when scrolled. const hackedZIndexStyles = xcss({ // @ts-ignore zIndex: '1' }); const resizeOffsetStyles = xcss({ right: 'space.150' }); const smallBadgeStyles = xcss({ margin: 'space.025' }); const getBadgeSize = (width, height) => { // width is the original width of image, not resized or currently rendered to user. Defaulting to medium for now return width && width < 70 || height && height < 70 ? 'small' : 'medium'; }; const getBadgeVisible = (width, height) => { if (!fg('platform_editor_support_media_badge_visibility')) { return true; } return width && width < MEDIA_BADGE_VISIBILITY_BREAKPOINT || height && height < MEDIA_BADGE_VISIBILITY_BREAKPOINT ? false : true; }; export const MediaBadges = ({ children, mediaElement, mediaWidth, mediaHeight, extendedResizeOffset, useMinimumZIndex = false }) => { const [badgeSize, setBadgeSize] = useState(getBadgeSize(mediaWidth, mediaHeight)); const [visible, setVisible] = useState(getBadgeVisible(mediaWidth, mediaHeight)); useEffect(() => { const observer = new ResizeObserver(debounce(entries => { const [entry] = entries; const { width, height } = entry.contentRect; setBadgeSize(getBadgeSize(width, height)); if (fg('platform_editor_support_media_badge_visibility')) { setVisible(getBadgeVisible(width, height)); } })); if (mediaElement) { // Ignored via go/ees005 // eslint-disable-next-line @atlaskit/editor/no-as-casting observer.observe(mediaElement); } return () => { observer.disconnect(); }; }, [mediaElement]); if (typeof children === 'function') { children = children({ badgeSize, visible }); } if (!mediaElement || React.Children.count(children) === 0) { return null; } return /*#__PURE__*/React.createElement(Box, { as: "div", testId: "media-badges", "data-media-badges": "true", contentEditable: false, xcss: [containerStyles, useMinimumZIndex && hackedZIndexStyles, extendedResizeOffset && resizeOffsetStyles, badgeSize === 'small' && smallBadgeStyles] }, children); };