@atlaskit/editor-plugin-text-color
Version:
Text color plugin for @atlaskit/editor-core
142 lines • 5.93 kB
JavaScript
/* ColorAccessibilityMenuItem.tsx generated by @compiled/babel-plugin v0.39.1 */
import "./ColorAccessibilityMenuItem.compiled.css";
import { ax, ix } from "@compiled/react/runtime";
import React from 'react';
import { useIntl } from 'react-intl';
import { IconButton } from '@atlaskit/button/new';
import { useSharedPluginStateWithSelector } from '@atlaskit/editor-common/hooks';
import { colorAccessibilityMessages as messages } from '@atlaskit/editor-common/messages';
import { getTokenCSSVariableValue } from '@atlaskit/editor-common/ui-color';
import { hexToEditorTextBackgroundPaletteColor, hexToEditorTextPaletteColor } from '@atlaskit/editor-palette';
import AccessibilityIcon from '@atlaskit/icon/core/accessibility';
import QuestionCircleIcon from '@atlaskit/icon/core/question-circle';
import { Box, Inline, Text } from '@atlaskit/primitives/compiled';
import { getTokenValue } from '@atlaskit/tokens';
import { getContrastRatio as calcContrastRatio } from '../pm-plugins/utils/color-contrast';
import { DEFAULT_COLOR, DEFAULT_BACKGROUND_COLOR, TRANSPARENT_HIGHLIGHT_COLOR, ACCESSIBLE_CONTRAST_RATIO, DIFFICULT_CONTRAST_RATIO } from '../pm-plugins/utils/constants';
const resolveColorValue = (color, fallback) => {
return getTokenCSSVariableValue(color) || (color.startsWith('var(') ? fallback : color);
};
const getForegroundColor = (textColor, defaultColor) => {
if (!textColor || defaultColor && textColor === defaultColor) {
return getTokenValue('color.text', defaultColor || DEFAULT_COLOR.color);
}
const colorValue = hexToEditorTextPaletteColor(textColor) || textColor;
return resolveColorValue(colorValue, textColor);
};
const getBackgroundColor = highlightColor => {
if (!highlightColor || highlightColor === TRANSPARENT_HIGHLIGHT_COLOR) {
return getTokenValue('elevation.surface', DEFAULT_BACKGROUND_COLOR);
}
const colorValue = hexToEditorTextBackgroundPaletteColor(highlightColor) || highlightColor;
return resolveColorValue(colorValue, highlightColor);
};
const useColorAccessibilityState = api => {
return useSharedPluginStateWithSelector(api, ['textColor', 'highlight'], states => {
var _states$textColorStat, _states$highlightStat, _states$textColorStat2;
return {
defaultColor: (_states$textColorStat = states.textColorState) === null || _states$textColorStat === void 0 ? void 0 : _states$textColorStat.defaultColor,
highlightColor: (_states$highlightStat = states.highlightState) === null || _states$highlightStat === void 0 ? void 0 : _states$highlightStat.activeColor,
textColor: (_states$textColorStat2 = states.textColorState) === null || _states$textColorStat2 === void 0 ? void 0 : _states$textColorStat2.color
};
});
};
const getContrastRatio = (defaultColor, highlightColor, textColor) => {
try {
const contrastRatio = calcContrastRatio(getForegroundColor(textColor, defaultColor), getBackgroundColor(highlightColor));
return contrastRatio;
} catch {
// if we failed to calculate the contrast ratio, return null
return null;
}
};
const getAccessibilityStatus = contrastRatio => {
if (contrastRatio >= ACCESSIBLE_CONTRAST_RATIO) {
return 'accessible';
} else if (contrastRatio >= DIFFICULT_CONTRAST_RATIO) {
return 'difficultToRead';
} else {
return 'inaccessible';
}
};
const AccessibilityStatus = ({
accessibilityStatus,
formatMessage
}) => {
if (accessibilityStatus === 'accessible') {
return /*#__PURE__*/React.createElement(Text, {
as: "span",
size: "small",
color: "color.text.success"
}, formatMessage(messages.accessibleLabel));
} else if (accessibilityStatus === 'difficultToRead') {
return /*#__PURE__*/React.createElement(Text, {
as: "span",
size: "small",
color: "color.text.warning"
}, formatMessage(messages.difficultToReadLabel));
} else {
return /*#__PURE__*/React.createElement(Text, {
as: "span",
size: "small",
color: "color.text.danger"
}, formatMessage(messages.inaccessibleLabel));
}
};
const styles = {
container: "_19itglyw _19pku2gc _ca0q1b66 _n3td1b66 _19bvu2gc _u5f31b66 _1e0c1txw _4cvr1h6o _1bah1yb4"
};
export const ColorAccessibilityMenuItem = ({
api
}) => {
const {
formatMessage
} = useIntl();
const {
defaultColor,
highlightColor,
textColor
} = useColorAccessibilityState(api);
const contrastRatio = getContrastRatio(defaultColor, highlightColor, textColor);
if (contrastRatio === null) {
return /*#__PURE__*/React.createElement(React.Fragment, null);
}
const accessibilityStatus = getAccessibilityStatus(contrastRatio);
const tooltipContent = accessibilityStatus => {
if (accessibilityStatus === 'accessible') {
return formatMessage(messages.accessibleTooltip);
} else if (accessibilityStatus === 'difficultToRead') {
return formatMessage(messages.difficultToReadTooltip);
} else {
return formatMessage(messages.inaccessibleTooltip);
}
};
return /*#__PURE__*/React.createElement(Box, {
xcss: styles.container
}, /*#__PURE__*/React.createElement(Inline, {
alignBlock: "center",
space: "space.050"
}, /*#__PURE__*/React.createElement(AccessibilityIcon, {
label: "",
size: "medium"
}), /*#__PURE__*/React.createElement(Text, {
as: "span",
size: "small",
color: "color.text.subtle"
}, formatMessage(messages.accessibility)), /*#__PURE__*/React.createElement(Text, {
as: "span",
size: "small",
color: "color.text.subtle",
"aria-hidden": "true"
}, "\u2022"), /*#__PURE__*/React.createElement(AccessibilityStatus, {
accessibilityStatus: accessibilityStatus,
formatMessage: formatMessage
})), /*#__PURE__*/React.createElement(IconButton, {
icon: QuestionCircleIcon,
shape: "circle",
label: tooltipContent(accessibilityStatus),
isTooltipDisabled: false,
spacing: "compact",
appearance: "subtle"
}));
};