UNPKG

@nouance/payload-better-fields-plugin

Version:

A Payload plugin that aims to provide improved fields for the admin panel

157 lines (156 loc) 6.33 kB
'use client'; import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime"; import { RenderCustomComponent, useField } from '@payloadcms/ui'; import { FieldDescription } from '@payloadcms/ui/fields/FieldDescription'; import { FieldLabel } from '@payloadcms/ui/fields/FieldLabel'; import { useDebouncedCallback } from '@payloadcms/ui/hooks/useDebouncedCallback'; import { extend } from 'colord'; import namesPlugin from 'colord/plugins/names'; import React, { useCallback, useMemo, useState } from 'react'; import { HexAlphaColorPicker, HexColorPicker, HslaStringColorPicker, HslStringColorPicker, RgbaStringColorPicker, RgbStringColorPicker } from 'react-colorful'; import './styles.css'; // @ts-expect-error - unknown lib issue extend([ namesPlugin ]); const ColourComponents = { hex: HexColorPicker, hexA: HexAlphaColorPicker, hsl: HslStringColorPicker, hslA: HslaStringColorPicker, rgb: RgbStringColorPicker, rgbA: RgbaStringColorPicker }; export const ColourPickerComponent = (props)=>{ const { type, expanded = false, field: { admin: { description } = {}, label, required }, inputRef, path, readOnly, showPreview, validate } = props; const memoizedValidate = useCallback((value, options)=>{ if (typeof validate === 'function') { return validate(value, { ...options, required }); } }, [ validate, required ]); const isReadonly = Boolean(readOnly); const { customComponents: { AfterInput, BeforeInput, Description, Label } = {}, setValue, value } = useField({ path, // @ts-expect-error - memoizedValidate is not typed validate: memoizedValidate }); const [isAdding, setIsAdding] = useState(expanded); const Picker = useMemo(()=>{ return type ? ColourComponents[type] : ColourComponents['hex']; }, [ type ]); // Had to debounce it here so it doesn't error with maxdepth const debouncedAddColor = useDebouncedCallback((val)=>{ if (val !== value && !isReadonly) { setValue(val); if (inputRef?.current) { inputRef.current.value = val ?? ''; } } }, 150); const handleAddColor = useCallback((val)=>{ if (val !== value && !isReadonly) { setValue(val); } }, [ value, isReadonly, setValue ]); const labelToUse = label; return /*#__PURE__*/ _jsxs("div", { className: `bfColourPickerFieldWrapper`, children: [ /*#__PURE__*/ _jsx(RenderCustomComponent, { CustomComponent: Label, Fallback: /*#__PURE__*/ _jsx(FieldLabel, { label: labelToUse, path: path, required: required }) }), BeforeInput, (expanded || isAdding) && /*#__PURE__*/ _jsxs("div", { className: "expandedContainer", children: [ /*#__PURE__*/ _jsx("div", { className: [ 'colourPickerWrapper', isReadonly && 'readOnly' ].filter(Boolean).join(' '), // @ts-expect-error - inert is not a valid attribute inert: isReadonly ? '' : null, children: /*#__PURE__*/ _jsx(Picker, { color: value || '', onBlur: (e)=>{ if (e.relatedTarget === null) { setIsAdding(false); } }, onChange: debouncedAddColor, onKeyDown: (e)=>(e.key === 'Enter' || e.key === 'Escape') && setIsAdding(false) }) }), /*#__PURE__*/ _jsx("input", { className: `manual-field-input`, id: `field-${path}`, onChange: ({ currentTarget })=>{ handleAddColor(currentTarget.value); }, readOnly: isReadonly, ref: inputRef, value: value || '' }) ] }), !expanded && /*#__PURE__*/ _jsxs("div", { className: "buttonContainer", children: [ /*#__PURE__*/ _jsx("button", { "aria-label": value, className: `chip chip--clickable`, onClick: ()=>{ setIsAdding(!isAdding); }, style: { backgroundColor: value }, type: "button" }), showPreview && /*#__PURE__*/ _jsxs(_Fragment, { children: [ /*#__PURE__*/ _jsx("label", { className: "srOnly", htmlFor: `bfColourPickerField-previewField-${path.replace(/\./g, '__')}`, children: "Preview" }), /*#__PURE__*/ _jsx("input", { className: "previewField", disabled: true, id: `bfColourPickerField-previewField-${path.replace(/\./g, '__')}`, value: value }) ] }) ] }), /*#__PURE__*/ _jsx(RenderCustomComponent, { CustomComponent: Description, Fallback: /*#__PURE__*/ _jsx(FieldDescription, { className: `field-description-${path.replace(/\./g, '__')}`, description: description ?? '', path: path }) }), AfterInput ] }); }; //# sourceMappingURL=Component.js.map