UNPKG

@wordpress/block-editor

Version:
543 lines (484 loc) 18.4 kB
"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); exports.default = ColorPanel; exports.useHasBackgroundPanel = useHasBackgroundPanel; exports.useHasButtonPanel = useHasButtonPanel; exports.useHasCaptionPanel = useHasCaptionPanel; exports.useHasColorPanel = useHasColorPanel; exports.useHasHeadingPanel = useHasHeadingPanel; exports.useHasLinkPanel = useHasLinkPanel; exports.useHasTextPanel = useHasTextPanel; var _element = require("@wordpress/element"); var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends")); var _classnames = _interopRequireDefault(require("classnames")); var _components = require("@wordpress/components"); var _i18n = require("@wordpress/i18n"); var _control = _interopRequireDefault(require("../colors-gradients/control")); var _hooks = require("./hooks"); var _utils = require("./utils"); var _object = require("../../utils/object"); /** * External dependencies */ /** * WordPress dependencies */ /** * Internal dependencies */ function useHasColorPanel(settings) { const hasTextPanel = useHasTextPanel(settings); const hasBackgroundPanel = useHasBackgroundPanel(settings); const hasLinkPanel = useHasLinkPanel(settings); const hasHeadingPanel = useHasHeadingPanel(settings); const hasButtonPanel = useHasHeadingPanel(settings); const hasCaptionPanel = useHasCaptionPanel(settings); return hasTextPanel || hasBackgroundPanel || hasLinkPanel || hasHeadingPanel || hasButtonPanel || hasCaptionPanel; } function useHasTextPanel(settings) { const colors = (0, _hooks.useColorsPerOrigin)(settings); return settings?.color?.text && (colors?.length > 0 || settings?.color?.custom); } function useHasLinkPanel(settings) { const colors = (0, _hooks.useColorsPerOrigin)(settings); return settings?.color?.link && (colors?.length > 0 || settings?.color?.custom); } function useHasCaptionPanel(settings) { const colors = (0, _hooks.useColorsPerOrigin)(settings); return settings?.color?.caption && (colors?.length > 0 || settings?.color?.custom); } function useHasHeadingPanel(settings) { const colors = (0, _hooks.useColorsPerOrigin)(settings); const gradients = (0, _hooks.useGradientsPerOrigin)(settings); return settings?.color?.heading && (colors?.length > 0 || settings?.color?.custom || gradients?.length > 0 || settings?.color?.customGradient); } function useHasButtonPanel(settings) { const colors = (0, _hooks.useColorsPerOrigin)(settings); const gradients = (0, _hooks.useGradientsPerOrigin)(settings); return settings?.color?.button && (colors?.length > 0 || settings?.color?.custom || gradients?.length > 0 || settings?.color?.customGradient); } function useHasBackgroundPanel(settings) { const colors = (0, _hooks.useColorsPerOrigin)(settings); const gradients = (0, _hooks.useGradientsPerOrigin)(settings); return settings?.color?.background && (colors?.length > 0 || settings?.color?.custom || gradients?.length > 0 || settings?.color?.customGradient); } function ColorToolsPanel({ resetAllFilter, onChange, value, panelId, children }) { const resetAll = () => { const updatedValue = resetAllFilter(value); onChange(updatedValue); }; return (0, _element.createElement)(_components.__experimentalToolsPanel, { label: (0, _i18n.__)('Color'), resetAll: resetAll, panelId: panelId, hasInnerWrapper: true, className: "color-block-support-panel", __experimentalFirstVisibleItemClass: "first", __experimentalLastVisibleItemClass: "last" }, (0, _element.createElement)("div", { className: "color-block-support-panel__inner-wrapper" }, children)); } const DEFAULT_CONTROLS = { text: true, background: true, link: true, heading: true, button: true, caption: true }; const popoverProps = { placement: 'left-start', offset: 36, shift: true }; const LabeledColorIndicators = ({ indicators, label }) => (0, _element.createElement)(_components.__experimentalHStack, { justify: "flex-start" }, (0, _element.createElement)(_components.__experimentalZStack, { isLayered: false, offset: -8 }, indicators.map((indicator, index) => (0, _element.createElement)(_components.Flex, { key: index, expanded: false }, (0, _element.createElement)(_components.ColorIndicator, { colorValue: indicator })))), (0, _element.createElement)(_components.FlexItem, { className: "block-editor-panel-color-gradient-settings__color-name", title: label }, label)); function ColorPanelTab({ isGradient, inheritedValue, userValue, setValue, colorGradientControlSettings }) { return (0, _element.createElement)(_control.default, (0, _extends2.default)({}, colorGradientControlSettings, { showTitle: false, enableAlpha: true, __experimentalIsRenderedInSidebar: true, colorValue: isGradient ? undefined : inheritedValue, gradientValue: isGradient ? inheritedValue : undefined, onColorChange: isGradient ? undefined : setValue, onGradientChange: isGradient ? setValue : undefined, clearable: inheritedValue === userValue, headingLevel: 3 })); } function ColorPanelDropdown({ label, hasValue, resetValue, isShownByDefault, indicators, tabs, colorGradientControlSettings, panelId }) { const tabConfigs = tabs.map(({ key, label: tabLabel }) => { return { name: key, title: tabLabel }; }); return (0, _element.createElement)(_components.__experimentalToolsPanelItem, { className: "block-editor-tools-panel-color-gradient-settings__item", hasValue: hasValue, label: label, onDeselect: resetValue, isShownByDefault: isShownByDefault, panelId: panelId }, (0, _element.createElement)(_components.Dropdown, { popoverProps: popoverProps, className: "block-editor-tools-panel-color-gradient-settings__dropdown", renderToggle: ({ onToggle, isOpen }) => { const toggleProps = { onClick: onToggle, className: (0, _classnames.default)('block-editor-panel-color-gradient-settings__dropdown', { 'is-open': isOpen }), 'aria-expanded': isOpen, 'aria-label': (0, _i18n.sprintf)( /* translators: %s is the type of color property, e.g., "background" */ (0, _i18n.__)('Color %s styles'), label) }; return (0, _element.createElement)(_components.Button, toggleProps, (0, _element.createElement)(LabeledColorIndicators, { indicators: indicators, label: label })); }, renderContent: () => (0, _element.createElement)(_components.__experimentalDropdownContentWrapper, { paddingSize: "none" }, (0, _element.createElement)("div", { className: "block-editor-panel-color-gradient-settings__dropdown-content" }, tabs.length === 1 && (0, _element.createElement)(ColorPanelTab, (0, _extends2.default)({}, tabs[0], { colorGradientControlSettings: colorGradientControlSettings })), tabs.length > 1 && (0, _element.createElement)(_components.TabPanel, { tabs: tabConfigs }, tab => { const selectedTab = tabs.find(t => t.key === tab.name); if (!selectedTab) { return null; } return (0, _element.createElement)(ColorPanelTab, (0, _extends2.default)({}, selectedTab, { colorGradientControlSettings: colorGradientControlSettings })); }))) })); } function ColorPanel({ as: Wrapper = ColorToolsPanel, value, onChange, inheritedValue = value, settings, panelId, defaultControls = DEFAULT_CONTROLS, children }) { const colors = (0, _hooks.useColorsPerOrigin)(settings); const gradients = (0, _hooks.useGradientsPerOrigin)(settings); const areCustomSolidsEnabled = settings?.color?.custom; const areCustomGradientsEnabled = settings?.color?.customGradient; const hasSolidColors = colors.length > 0 || areCustomSolidsEnabled; const hasGradientColors = gradients.length > 0 || areCustomGradientsEnabled; const decodeValue = rawValue => (0, _utils.getValueFromVariable)({ settings }, '', rawValue); const encodeColorValue = colorValue => { const allColors = colors.flatMap(({ colors: originColors }) => originColors); const colorObject = allColors.find(({ color }) => color === colorValue); return colorObject ? 'var:preset|color|' + colorObject.slug : colorValue; }; const encodeGradientValue = gradientValue => { const allGradients = gradients.flatMap(({ gradients: originGradients }) => originGradients); const gradientObject = allGradients.find(({ gradient }) => gradient === gradientValue); return gradientObject ? 'var:preset|gradient|' + gradientObject.slug : gradientValue; }; // Text Color const showTextPanel = useHasTextPanel(settings); const textColor = decodeValue(inheritedValue?.color?.text); const userTextColor = decodeValue(value?.color?.text); const hasTextColor = () => !!userTextColor; const setTextColor = newColor => { onChange((0, _object.setImmutably)(value, ['color', 'text'], encodeColorValue(newColor))); }; const resetTextColor = () => setTextColor(undefined); // BackgroundColor const showBackgroundPanel = useHasBackgroundPanel(settings); const backgroundColor = decodeValue(inheritedValue?.color?.background); const userBackgroundColor = decodeValue(value?.color?.background); const gradient = decodeValue(inheritedValue?.color?.gradient); const userGradient = decodeValue(value?.color?.gradient); const hasBackground = () => !!userBackgroundColor || !!userGradient; const setBackgroundColor = newColor => { const newValue = (0, _object.setImmutably)(value, ['color', 'background'], encodeColorValue(newColor)); newValue.color.gradient = undefined; onChange(newValue); }; const setGradient = newGradient => { const newValue = (0, _object.setImmutably)(value, ['color', 'gradient'], encodeGradientValue(newGradient)); newValue.color.background = undefined; onChange(newValue); }; const resetBackground = () => { const newValue = (0, _object.setImmutably)(value, ['color', 'background'], undefined); newValue.color.gradient = undefined; onChange(newValue); }; // Links const showLinkPanel = useHasLinkPanel(settings); const linkColor = decodeValue(inheritedValue?.elements?.link?.color?.text); const userLinkColor = decodeValue(value?.elements?.link?.color?.text); const setLinkColor = newColor => { onChange((0, _object.setImmutably)(value, ['elements', 'link', 'color', 'text'], encodeColorValue(newColor))); }; const hoverLinkColor = decodeValue(inheritedValue?.elements?.link?.[':hover']?.color?.text); const userHoverLinkColor = decodeValue(value?.elements?.link?.[':hover']?.color?.text); const setHoverLinkColor = newColor => { onChange((0, _object.setImmutably)(value, ['elements', 'link', ':hover', 'color', 'text'], encodeColorValue(newColor))); }; const hasLink = () => !!userLinkColor || !!userHoverLinkColor; const resetLink = () => { let newValue = (0, _object.setImmutably)(value, ['elements', 'link', ':hover', 'color', 'text'], undefined); newValue = (0, _object.setImmutably)(newValue, ['elements', 'link', 'color', 'text'], undefined); onChange(newValue); }; // Elements const elements = [{ name: 'caption', label: (0, _i18n.__)('Captions'), showPanel: useHasCaptionPanel(settings) }, { name: 'button', label: (0, _i18n.__)('Button'), showPanel: useHasButtonPanel(settings) }, { name: 'heading', label: (0, _i18n.__)('Heading'), showPanel: useHasHeadingPanel(settings) }, { name: 'h1', label: (0, _i18n.__)('H1'), showPanel: useHasHeadingPanel(settings) }, { name: 'h2', label: (0, _i18n.__)('H2'), showPanel: useHasHeadingPanel(settings) }, { name: 'h3', label: (0, _i18n.__)('H3'), showPanel: useHasHeadingPanel(settings) }, { name: 'h4', label: (0, _i18n.__)('H4'), showPanel: useHasHeadingPanel(settings) }, { name: 'h5', label: (0, _i18n.__)('H5'), showPanel: useHasHeadingPanel(settings) }, { name: 'h6', label: (0, _i18n.__)('H6'), showPanel: useHasHeadingPanel(settings) }]; const resetAllFilter = (0, _element.useCallback)(previousValue => { return { ...previousValue, color: undefined, elements: { ...previousValue?.elements, link: { ...previousValue?.elements?.link, color: undefined, ':hover': { color: undefined } }, ...elements.reduce((acc, element) => { return { ...acc, [element.name]: { ...previousValue?.elements?.[element.name], color: undefined } }; }, {}) } }; }, []); const items = [showTextPanel && { key: 'text', label: (0, _i18n.__)('Text'), hasValue: hasTextColor, resetValue: resetTextColor, isShownByDefault: defaultControls.text, indicators: [textColor], tabs: [{ key: 'text', label: (0, _i18n.__)('Text'), inheritedValue: textColor, setValue: setTextColor, userValue: userTextColor }] }, showBackgroundPanel && { key: 'background', label: (0, _i18n.__)('Background'), hasValue: hasBackground, resetValue: resetBackground, isShownByDefault: defaultControls.background, indicators: [gradient !== null && gradient !== void 0 ? gradient : backgroundColor], tabs: [{ key: 'background', label: (0, _i18n.__)('Solid'), inheritedValue: backgroundColor, setValue: setBackgroundColor, userValue: userBackgroundColor }, { key: 'gradient', label: (0, _i18n.__)('Gradient'), inheritedValue: gradient, setValue: setGradient, userValue: userGradient, isGradient: true }] }, showLinkPanel && { key: 'link', label: (0, _i18n.__)('Link'), hasValue: hasLink, resetValue: resetLink, isShownByDefault: defaultControls.link, indicators: [linkColor, hoverLinkColor], tabs: [{ key: 'link', label: (0, _i18n.__)('Default'), inheritedValue: linkColor, setValue: setLinkColor, userValue: userLinkColor }, { key: 'hover', label: (0, _i18n.__)('Hover'), inheritedValue: hoverLinkColor, setValue: setHoverLinkColor, userValue: userHoverLinkColor }] }].filter(Boolean); elements.forEach(({ name, label, showPanel }) => { if (!showPanel) return; const elementBackgroundColor = decodeValue(inheritedValue?.elements?.[name]?.color?.background); const elementGradient = decodeValue(inheritedValue?.elements?.[name]?.color?.gradient); const elementTextColor = decodeValue(inheritedValue?.elements?.[name]?.color?.text); const elementBackgroundUserColor = decodeValue(value?.elements?.[name]?.color?.background); const elementGradientUserColor = decodeValue(value?.elements?.[name]?.color?.gradient); const elementTextUserColor = decodeValue(value?.elements?.[name]?.color?.text); const hasElement = () => !!(elementTextUserColor || elementBackgroundUserColor || elementGradientUserColor); const resetElement = () => { const newValue = (0, _object.setImmutably)(value, ['elements', name, 'color', 'background'], undefined); newValue.elements[name].color.gradient = undefined; newValue.elements[name].color.text = undefined; onChange(newValue); }; const setElementTextColor = newTextColor => { onChange((0, _object.setImmutably)(value, ['elements', name, 'color', 'text'], encodeColorValue(newTextColor))); }; const setElementBackgroundColor = newBackgroundColor => { const newValue = (0, _object.setImmutably)(value, ['elements', name, 'color', 'background'], encodeColorValue(newBackgroundColor)); newValue.elements[name].color.gradient = undefined; onChange(newValue); }; const setElementGradient = newGradient => { const newValue = (0, _object.setImmutably)(value, ['elements', name, 'color', 'gradient'], encodeGradientValue(newGradient)); newValue.elements[name].color.background = undefined; onChange(newValue); }; const supportsTextColor = true; // Background color is not supported for `caption` // as there isn't yet a way to set padding for the element. const supportsBackground = name !== 'caption'; items.push({ key: name, label, hasValue: hasElement, resetValue: resetElement, isShownByDefault: defaultControls[name], indicators: supportsTextColor && supportsBackground ? [elementTextColor, elementGradient !== null && elementGradient !== void 0 ? elementGradient : elementBackgroundColor] : [supportsTextColor ? elementTextColor : elementGradient !== null && elementGradient !== void 0 ? elementGradient : elementBackgroundColor], tabs: [hasSolidColors && supportsTextColor && { key: 'text', label: (0, _i18n.__)('Text'), inheritedValue: elementTextColor, setValue: setElementTextColor, userValue: elementTextUserColor }, hasSolidColors && supportsBackground && { key: 'background', label: (0, _i18n.__)('Background'), inheritedValue: elementBackgroundColor, setValue: setElementBackgroundColor, userValue: elementBackgroundUserColor }, hasGradientColors && supportsBackground && { key: 'gradient', label: (0, _i18n.__)('Gradient'), inheritedValue: elementGradient, setValue: setElementGradient, userValue: elementGradientUserColor, isGradient: true }].filter(Boolean) }); }); return (0, _element.createElement)(Wrapper, { resetAllFilter: resetAllFilter, value: value, onChange: onChange, panelId: panelId }, items.map(item => (0, _element.createElement)(ColorPanelDropdown, (0, _extends2.default)({ key: item.key }, item, { colorGradientControlSettings: { colors, disableCustomColors: !areCustomSolidsEnabled, gradients, disableCustomGradients: !areCustomGradientsEnabled }, panelId: panelId }))), children); } //# sourceMappingURL=color-panel.js.map