@wordpress/components
Version:
UI components for WordPress.
241 lines (230 loc) • 7.17 kB
JavaScript
import { createElement, Fragment } from "@wordpress/element";
/**
* External dependencies
*/
import classnames from 'classnames';
import { isEmpty, kebabCase } from 'lodash';
/**
* WordPress dependencies
*/
import { __, sprintf } from '@wordpress/i18n';
import { useEffect, useState } from '@wordpress/element';
import { edit, close, chevronDown, chevronUp, plus } from '@wordpress/icons';
/**
* Internal dependencies
*/
import Dropdown from '../dropdown';
import CircularOptionPicker from '../circular-option-picker';
import ColorPicker from '../color-picker';
import Button from '../button';
import TextControl from '../text-control';
import BaseControl from '../base-control';
function DropdownOpenOnMount({
shouldOpen,
isOpen,
onToggle
}) {
useEffect(() => {
if (shouldOpen && !isOpen) {
onToggle();
}
}, []);
return null;
}
function ColorOption({
color,
name,
slug,
onChange,
onRemove,
onConfirm,
confirmLabel = __('OK'),
isEditingNameOnMount = false,
isEditingColorOnMount = false,
onCancel,
immutableColorSlugs = []
}) {
const [isHover, setIsHover] = useState(false);
const [isFocused, setIsFocused] = useState(false);
const [isEditingName, setIsEditingName] = useState(isEditingNameOnMount);
const [isShowingAdvancedPanel, setIsShowingAdvancedPanel] = useState(false);
const isShowingControls = (isHover || isFocused || isEditingName || isShowingAdvancedPanel) && !immutableColorSlugs.includes(slug);
return createElement("div", {
tabIndex: 0,
className: classnames('components-color-edit__color-option', {
'is-hover': isHover && !isEditingName && !isShowingAdvancedPanel
}),
onMouseEnter: () => setIsHover(true),
onMouseLeave: () => setIsHover(false),
onFocus: () => setIsFocused(true),
onBlur: () => setIsFocused(false),
"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)
}, createElement("div", {
className: "components-color-edit__color-option-main-area"
}, createElement(Dropdown, {
renderToggle: ({
isOpen,
onToggle
}) => createElement(Fragment, null, createElement(DropdownOpenOnMount, {
shouldOpen: isEditingColorOnMount,
isOpen: isOpen,
onToggle: onToggle
}), createElement(CircularOptionPicker.Option, {
style: {
backgroundColor: color,
color
},
"aria-expanded": isOpen,
"aria-haspopup": "true",
onClick: onToggle,
"aria-label": __('Edit color value')
})),
renderContent: () => createElement(ColorPicker, {
color: color,
onChangeComplete: newColor => onChange({
color: newColor.hex,
slug,
name
}),
disableAlpha: true
})
}), !isEditingName && createElement("div", {
className: "components-color-edit__color-option-color-name"
}, name), isEditingName && createElement(Fragment, null, createElement(TextControl, {
className: "components-color-edit__color-option-color-name-input",
hideLabelFromVision: true,
onChange: newColorName => onChange({
color,
slug: kebabCase(newColorName),
name: newColorName
}),
label: __('Color name'),
placeholder: __('Name'),
value: name
}), createElement(Button, {
onClick: () => {
setIsEditingName(false);
setIsFocused(false);
if (onConfirm) {
onConfirm();
}
},
isPrimary: true
}, confirmLabel)), !isEditingName && createElement(Fragment, null, createElement(Button, {
className: classnames({
'components-color-edit__hidden-control': !isShowingControls
}),
icon: edit,
label: __('Edit color name'),
onClick: () => setIsEditingName(true)
}), createElement(Button, {
className: classnames({
'components-color-edit__hidden-control': !isShowingControls
}),
icon: close,
label: __('Remove color'),
onClick: onRemove
})), createElement(Button, {
className: classnames({
'components-color-edit__hidden-control': !isShowingControls
}),
icon: isShowingAdvancedPanel ? chevronUp : chevronDown,
label: __('Additional color settings'),
onClick: () => {
if (isShowingAdvancedPanel) {
setIsFocused(false);
}
setIsShowingAdvancedPanel(!isShowingAdvancedPanel);
},
"aria-expanded": isShowingAdvancedPanel
})), onCancel && createElement(Button, {
className: "components-color-edit__cancel-button",
onClick: onCancel
}, __('Cancel')), isShowingAdvancedPanel && createElement(TextControl, {
className: "components-color-edit__slug-input",
onChange: newSlug => onChange({
color,
slug: newSlug,
name
}),
label: __('Slug'),
value: slug
}));
}
function ColorInserter({
onInsert,
onCancel
}) {
const [color, setColor] = useState({
color: '#fff',
name: '',
slug: ''
});
return createElement(ColorOption, {
color: color.color,
name: color.name,
slug: color.slug,
onChange: setColor,
confirmLabel: __('Save'),
onConfirm: () => onInsert(color),
isEditingNameOnMount: true,
isEditingColorOnMount: true,
onCancel: onCancel
});
}
export default function ColorEdit({
colors,
onChange,
emptyUI,
immutableColorSlugs,
canReset = true
}) {
const [isInsertingColor, setIsInsertingColor] = useState(false);
return createElement(BaseControl, null, createElement("fieldset", null, createElement("div", {
className: "components-color-edit__label-and-insert-container"
}, createElement("legend", null, createElement("div", null, createElement(BaseControl.VisualLabel, null, __('Color palette')))), !isInsertingColor && createElement(Button, {
onClick: () => {
setIsInsertingColor(true);
},
className: "components-color-edit__insert-button",
icon: plus
})), createElement("div", null, !isEmpty(colors) && colors.map((color, index) => {
return createElement(ColorOption, {
key: index,
color: color.color,
name: color.name,
slug: color.slug,
immutableColorSlugs: immutableColorSlugs,
onChange: newColor => {
onChange(colors.map((currentColor, currentIndex) => {
if (currentIndex === index) {
return newColor;
}
return currentColor;
}));
},
onRemove: () => {
onChange(colors.filter((_currentColor, currentIndex) => {
if (currentIndex === index) {
return false;
}
return true;
}));
}
});
}), isInsertingColor && createElement(ColorInserter, {
onInsert: newColor => {
setIsInsertingColor(false);
onChange([...(colors || []), newColor]);
},
onCancel: () => setIsInsertingColor(false)
}), !isInsertingColor && isEmpty(colors) && emptyUI), !!canReset && createElement(Button, {
isSmall: true,
isSecondary: true,
className: "components-color-edit__reset-button",
onClick: () => onChange()
}, __('Reset'))));
}
//# sourceMappingURL=index.js.map