UNPKG

@atlaskit/editor-plugin-synced-block

Version:

SyncedBlock plugin for @atlaskit/editor-core

133 lines • 6.29 kB
/* SyncBlockLabel.tsx generated by @compiled/babel-plugin v3.0.2 */ import "./SyncBlockLabel.compiled.css"; import { ax, ix } from "@compiled/react/runtime"; import React, { useCallback, useMemo, useState } from 'react'; import { useIntl } from 'react-intl'; import { syncBlockMessages as messages } from '@atlaskit/editor-common/messages'; import { SyncBlockLabelSharedCssClassName } from '@atlaskit/editor-common/sync-block'; import BlockSyncedIcon from '@atlaskit/icon-lab/core/block-synced'; import { Box, Text } from '@atlaskit/primitives/compiled'; import Tooltip from '@atlaskit/tooltip/Tooltip'; import VisuallyHidden from '@atlaskit/visually-hidden/visually-hidden'; import { formatElapsedTime } from './utils/time'; const SyncBlockLabelDataId = 'sync-block-label'; const styles = { truncatedLabelText: "_11c8wadc _1reo15vq _18m915vq _syazazsu _1ul9idpf _1bto1l2s _o5721q9c", unpublishedSuffix: "_11c8wadc _syazazsu _1o9zidpf _o5721q9c" }; const SyncBlockLabelComponent = ({ contentUpdatedAt, isSource, localId, title, isUnsyncedBlock, unpublishedInfo }) => { const intl = useIntl(); const { formatMessage } = intl; const [tooltipContent, setTooltipContent] = useState(formatMessage(messages.defaultSyncBlockTooltip)); let tooltipMessage = formatMessage(messages.defaultSyncBlockTooltip); if (title) { tooltipMessage = formatMessage(messages.referenceSyncBlockTooltip, { title }); } const updateTooltipContent = useCallback(() => { let tooltipContent = tooltipMessage; if (contentUpdatedAt) { const elapsedTime = formatElapsedTime(contentUpdatedAt, intl); tooltipContent = /*#__PURE__*/React.createElement("div", null, title ? /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(Text, { size: "small", color: "color.text.inverse", weight: "bold" }, formatMessage(messages.referenceSyncBlockSyncedFrom)), /*#__PURE__*/React.createElement(Text, { size: "small", color: "color.text.inverse" }, ' ', title)) : /*#__PURE__*/React.createElement(Text, { size: "small", color: "color.text.inverse" }, tooltipMessage), /*#__PURE__*/React.createElement("br", null), /*#__PURE__*/React.createElement("br", null), /*#__PURE__*/React.createElement(Text, { size: "small", color: "color.text.inverse", weight: "bold" }, formatMessage(messages.referenceSyncBlockLastEdited)), /*#__PURE__*/React.createElement(Text, { size: "small", color: "color.text.inverse" }, ' ', elapsedTime)); } setTooltipContent(tooltipContent); }, [contentUpdatedAt, formatMessage, intl, title, tooltipMessage]); const ariaDescribedById = `sync-block-label-description-${localId}`; const unpublishedParenthetical = unpublishedInfo ? formatMessage(messages.unpublishedInParentheses) : undefined; const getLabelContent = useMemo(() => { // The parenthetical carries a leading space so the accessible name and copied text read as // "… (unpublished)". Flex trims it visually, and the label's own gap provides the spacing. const renderUnpublishedLabel = label => /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(Box, { as: "span", xcss: styles.truncatedLabelText }, label), /*#__PURE__*/React.createElement(Box, { as: "span", xcss: styles.unpublishedSuffix }, ` ${unpublishedParenthetical}`)); const renderPlainLabel = label => unpublishedParenthetical ? renderUnpublishedLabel(label) : /*#__PURE__*/React.createElement(Text, { size: "small", color: "color.text.subtle" }, label); const renderTruncatingTitle = label => unpublishedParenthetical ? renderUnpublishedLabel(label) : /*#__PURE__*/React.createElement(Text, { maxLines: 1, size: "small", color: "color.text.subtle" }, label); if (isUnsyncedBlock) { return renderPlainLabel(formatMessage(messages.unsyncedBlockLabel)); } if (isSource) { return renderPlainLabel(formatMessage(messages.sourceSyncedBlockLabel)); } if (!title) { return renderPlainLabel(formatMessage(messages.syncedBlockLabel)); } return renderTruncatingTitle(title); }, [formatMessage, isSource, isUnsyncedBlock, title, unpublishedParenthetical]); const unpublishedTooltipLabel = unpublishedInfo ? formatMessage(unpublishedInfo.variant === 'source' ? messages.unpublishedSourceAvailabilityTooltip : messages.unpublishedLocalReferenceAvailabilityTooltip, { sourceType: unpublishedInfo.sourceType }) : undefined; const primaryLabel = /*#__PURE__*/React.createElement("div", { "data-testid": SyncBlockLabelDataId // eslint-disable-next-line @atlaskit/ui-styling-standard/no-classname-prop , className: SyncBlockLabelSharedCssClassName.labelClassName, "aria-describedby": isSource || isUnsyncedBlock ? undefined : ariaDescribedById }, /*#__PURE__*/React.createElement(BlockSyncedIcon, { color: "var(--ds-icon-subtle, #505258)", size: "small", label: "" }), getLabelContent); const referenceDescription = !isSource && !isUnsyncedBlock && /*#__PURE__*/React.createElement(VisuallyHidden, { id: ariaDescribedById }, tooltipMessage); if (unpublishedTooltipLabel) { return /*#__PURE__*/React.createElement(Tooltip, { position: "top", content: unpublishedTooltipLabel }, primaryLabel, referenceDescription); } if (isSource || isUnsyncedBlock) { return primaryLabel; } return /*#__PURE__*/React.createElement(Tooltip, { position: "top", content: tooltipContent // workaround because tooltip adds aria-describedby with a new id every time the tooltip is opened // this causes an infinite rerender loop because of the forwardRef from the node view we are inside in bodiedSyncBlock // tooltip content is available for screen readers in visually hidden content after the label , isScreenReaderAnnouncementDisabled: true // using this to ensure that the 'last edited' time is updated when the tooltip is opened , onShow: updateTooltipContent }, primaryLabel, referenceDescription); }; export const SyncBlockLabel = /*#__PURE__*/React.memo(SyncBlockLabelComponent);