UNPKG

@wordpress/components

Version:
250 lines (237 loc) 8.03 kB
import _extends from "@babel/runtime/helpers/esm/extends"; import { createElement } from "@wordpress/element"; /** * External dependencies */ import { colord, extend } from 'colord'; import namesPlugin from 'colord/plugins/names'; import a11yPlugin from 'colord/plugins/a11y'; /** * WordPress dependencies */ import { __, sprintf } from '@wordpress/i18n'; import { useCallback, useMemo, useState, forwardRef } from '@wordpress/element'; /** * Internal dependencies */ import Dropdown from '../dropdown'; import { ColorPicker } from '../color-picker'; import CircularOptionPicker from '../circular-option-picker'; import { VStack } from '../v-stack'; import { Flex, FlexItem } from '../flex'; import { Truncate } from '../truncate'; import { ColorHeading } from './styles'; import DropdownContentWrapper from '../dropdown/dropdown-content-wrapper'; import { extractColorNameFromCurrentValue, isMultiplePaletteArray, normalizeColorValue, showTransparentBackground } from './utils'; extend([namesPlugin, a11yPlugin]); function SinglePalette(_ref) { let { className, clearColor, colors, onChange, value, actions } = _ref; const colorOptions = useMemo(() => { return colors.map((_ref2, index) => { let { color, name } = _ref2; const colordColor = colord(color); const isSelected = value === color; return createElement(CircularOptionPicker.Option, { key: `${color}-${index}`, isSelected: isSelected, selectedIconProps: isSelected ? { fill: colordColor.contrast() > colordColor.contrast('#000') ? '#fff' : '#000' } : {}, tooltipText: name || // translators: %s: color hex code e.g: "#f00". sprintf(__('Color code: %s'), color), style: { backgroundColor: color, color }, onClick: isSelected ? clearColor : () => onChange(color, index), "aria-label": name ? // translators: %s: The name of the color e.g: "vivid red". sprintf(__('Color: %s'), name) : // translators: %s: color hex code e.g: "#f00". sprintf(__('Color code: %s'), color) }); }); }, [colors, value, onChange, clearColor]); return createElement(CircularOptionPicker, { className: className, options: colorOptions, actions: actions }); } function MultiplePalettes(_ref3) { let { className, clearColor, colors, onChange, value, actions, headingLevel } = _ref3; if (colors.length === 0) { return null; } return createElement(VStack, { spacing: 3, className: className }, colors.map((_ref4, index) => { let { name, colors: colorPalette } = _ref4; return createElement(VStack, { spacing: 2, key: index }, createElement(ColorHeading, { level: headingLevel }, name), createElement(SinglePalette, { clearColor: clearColor, colors: colorPalette, onChange: newColor => onChange(newColor, index), value: value, actions: colors.length === index + 1 ? actions : null })); })); } export function CustomColorPickerDropdown(_ref5) { let { isRenderedInSidebar, popoverProps: receivedPopoverProps, ...props } = _ref5; const popoverProps = useMemo(() => ({ shift: true, ...(isRenderedInSidebar ? { // When in the sidebar: open to the left (stacking), // leaving the same gap as the parent popover. placement: 'left-start', offset: 34 } : { // Default behavior: open below the anchor placement: 'bottom', offset: 8 }), ...receivedPopoverProps }), [isRenderedInSidebar, receivedPopoverProps]); return createElement(Dropdown, _extends({ contentClassName: "components-color-palette__custom-color-dropdown-content", popoverProps: popoverProps }, props)); } function UnforwardedColorPalette(props, forwardedRef) { const { clearable = true, colors = [], disableCustomColors = false, enableAlpha = false, onChange, value, __experimentalIsRenderedInSidebar = false, headingLevel = 2, ...otherProps } = props; const [normalizedColorValue, setNormalizedColorValue] = useState(value); const clearColor = useCallback(() => onChange(undefined), [onChange]); const customColorPaletteCallbackRef = useCallback(node => { setNormalizedColorValue(normalizeColorValue(value, node)); }, [value]); const hasMultipleColorOrigins = isMultiplePaletteArray(colors); const buttonLabelName = useMemo(() => extractColorNameFromCurrentValue(value, colors, hasMultipleColorOrigins), [value, colors, hasMultipleColorOrigins]); const renderCustomColorPicker = () => createElement(DropdownContentWrapper, { paddingSize: "none" }, createElement(ColorPicker, { color: normalizedColorValue, onChange: color => onChange(color), enableAlpha: enableAlpha })); const colordColor = colord(normalizedColorValue !== null && normalizedColorValue !== void 0 ? normalizedColorValue : ''); const valueWithoutLeadingHash = value !== null && value !== void 0 && value.startsWith('#') ? value.substring(1) : value !== null && value !== void 0 ? value : ''; const customColorAccessibleLabel = !!valueWithoutLeadingHash ? sprintf( // translators: %1$s: The name of the color e.g: "vivid red". %2$s: The color's hex code e.g: "#f00". __('Custom color picker. The currently selected color is called "%1$s" and has a value of "%2$s".'), buttonLabelName, valueWithoutLeadingHash) : __('Custom color picker.'); const paletteCommonProps = { clearable, clearColor, onChange, value, actions: !!clearable && createElement(CircularOptionPicker.ButtonAction, { onClick: clearColor }, __('Clear')), headingLevel }; return createElement(VStack, _extends({ spacing: 3, ref: forwardedRef }, otherProps), !disableCustomColors && createElement(CustomColorPickerDropdown, { isRenderedInSidebar: __experimentalIsRenderedInSidebar, renderContent: renderCustomColorPicker, renderToggle: _ref6 => { let { isOpen, onToggle } = _ref6; return createElement(Flex, { as: 'button', ref: customColorPaletteCallbackRef, justify: "space-between", align: "flex-start", className: "components-color-palette__custom-color", "aria-expanded": isOpen, "aria-haspopup": "true", onClick: onToggle, "aria-label": customColorAccessibleLabel, style: showTransparentBackground(value) ? { color: '#000' } : { background: value, color: colordColor.contrast() > colordColor.contrast('#000') ? '#fff' : '#000' } }, createElement(FlexItem, { isBlock: true, as: Truncate, className: "components-color-palette__custom-color-name" }, buttonLabelName), createElement(FlexItem, { as: "span", className: "components-color-palette__custom-color-value" }, valueWithoutLeadingHash)); } }), hasMultipleColorOrigins ? createElement(MultiplePalettes, _extends({}, paletteCommonProps, { colors: colors })) : createElement(SinglePalette, _extends({}, paletteCommonProps, { colors: colors }))); } /** * Allows the user to pick a color from a list of pre-defined color entries. * * ```jsx * import { ColorPalette } from '@wordpress/components'; * import { useState } from '@wordpress/element'; * * const MyColorPalette = () => { * const [ color, setColor ] = useState ( '#f00' ) * const colors = [ * { name: 'red', color: '#f00' }, * { name: 'white', color: '#fff' }, * { name: 'blue', color: '#00f' }, * ]; * return ( * <ColorPalette * colors={ colors } * value={ color } * onChange={ ( color ) => setColor( color ) } * /> * ); * } ); * ``` */ export const ColorPalette = forwardRef(UnforwardedColorPalette); export default ColorPalette; //# sourceMappingURL=index.js.map