Jake Vanderwerf
2026-09-04 c16a4d78d07e81ecdd2ff9b1b9090560ab2fe488
=Got the panel loading up the fields, organized by section! Now to ensure it saves properly. Still need to add: upload fields, selector fields, repeater/taglist/group fields
6 files modified
4 files added
218 ■■■■■ changed files
build/_meta/fields.asset.php 2 ●●●●● patch | view | raw | blame | history
build/_meta/fields.js 2 ●●●●● patch | view | raw | blame | history
inc/registrar/helpers/AddCustomFields.php 2 ●●●●● patch | view | raw | blame | history
src/editor-fields/Fields.js 9 ●●●●● patch | view | raw | blame | history
src/editor-fields/Section.js 27 ●●●●● patch | view | raw | blame | history
src/editor-fields/SidePanel.js 70 ●●●●● patch | view | raw | blame | history
src/editor-fields/fields/date-field.js 28 ●●●●● patch | view | raw | blame | history
src/editor-fields/fields/datetime-field.js 33 ●●●●● patch | view | raw | blame | history
src/editor-fields/fields/time-field.js 25 ●●●●● patch | view | raw | blame | history
src/editor-fields/index.js 20 ●●●●● patch | view | raw | blame | history
build/_meta/fields.asset.php
@@ -1 +1 @@
<?php return array('dependencies' => array('react-jsx-runtime', 'wp-components', 'wp-compose', 'wp-core-data', 'wp-data', 'wp-edit-post', 'wp-editor', 'wp-i18n', 'wp-plugins'), 'version' => 'e8150048804582196e08');
<?php return array('dependencies' => array('react', 'react-jsx-runtime', 'wp-components', 'wp-compose', 'wp-core-data', 'wp-data', 'wp-editor', 'wp-i18n', 'wp-plugins'), 'version' => '867be6566063509d0ebe');
build/_meta/fields.js
@@ -1 +1 @@
(()=>{"use strict";const e=window.wp.plugins,t=window.wp.i18n,o=window.wp.compose,l=window.wp.data,i=window.wp.editPost,n=window.wp.components,a=window.wp.coreData,s=window.ReactJSXRuntime,d=()=>(0,s.jsx)("svg",{xmlns:"http://www.w3.org/2000/svg",fillRule:"evenodd",strokeLinecap:"square",strokeLinejoin:"round",strokeMiterlimit:"1.5",clipRule:"evenodd",viewBox:"0 0 32 32",children:(0,s.jsx)("path",{fill:"currentColor",fillRule:"nonzero",d:"M16.58 2.133c-7.715 0-15.14 6.014-14.547 13.707.561 7.287 6.938 13.185 13.938 13.947 8.25.898 14.47-5.953 14.004-13.988-.447-7.7-5.683-13.666-13.395-13.666m0 .607h.031v26.492q-.285-.017-.574-.048c-6.724-.732-12.86-6.391-13.398-13.391C2.072 8.442 9.209 2.74 16.58 2.74m-.488 1.145L16 3.889c-3.275.13-6.448 1.476-8.744 3.611-2.297 2.135-3.716 5.065-3.463 8.346.492 6.384 6.071 11.538 12.201 12.207l.09.01.021-.182-.091-.01c-6.041-.66-11.555-5.755-12.04-12.04-.247-3.221 1.142-6.092 3.405-8.196s5.4-3.437 8.629-3.565l.092-.004zm0 1.502L16 5.39c-2.868.113-5.647 1.293-7.658 3.164-2.012 1.87-3.255 4.436-3.033 7.31.43 5.593 5.316 10.106 10.685 10.692l.09.01.021-.18-.091-.01c-5.28-.576-10.1-5.031-10.524-10.525-.217-2.815.997-5.325 2.975-7.164 1.978-1.84 4.72-3.004 7.543-3.116l.092-.004zm0 1.504L16 6.893c-2.462.097-4.846 1.111-6.572 2.716-1.727 1.606-2.796 3.808-2.606 6.276.37 4.8 4.564 8.674 9.172 9.177l.09.01.021-.181-.091-.01c-4.52-.494-8.648-4.307-9.01-9.01-.186-2.408.854-4.554 2.547-6.129s4.04-2.57 6.457-2.666l.092-.004zm0 1.502L16 8.396c-2.055.082-4.045.926-5.486 2.266-1.442 1.34-2.335 3.182-2.176 5.244.309 4.009 3.808 7.24 7.656 7.66l.09.01.008-.068v-.002l.002-.01.004-.01v-.02l.007-.072-.091-.01c-3.76-.41-7.193-3.58-7.494-7.491-.155-2.002.709-3.787 2.117-5.096s3.361-2.14 5.37-2.219l.093-.004zm0 1.502L16 9.898a6.95 6.95 0 0 0-4.402 1.819c-1.157 1.075-1.872 2.553-1.744 4.209.247 3.216 3.053 5.81 6.14 6.146l.09.01.021-.182-.091-.01c-2.999-.327-5.739-2.86-5.979-5.978-.123-1.595.564-3.018 1.688-4.062a6.78 6.78 0 0 1 4.285-1.77l.092-.004zm0 1.503L16 11.4a5.24 5.24 0 0 0-3.316 1.372c-.872.81-1.413 1.924-1.317 3.173.187 2.425 2.3 4.377 4.627 4.631l.09.01.021-.182-.091-.01c-2.238-.244-4.286-2.136-4.465-4.462-.092-1.19.421-2.248 1.26-3.028a5.06 5.06 0 0 1 3.199-1.32l.092-.004zm0 1.502-.092.004a3.52 3.52 0 0 0-2.23.92c-.587.546-.952 1.3-.887 2.143.126 1.633 1.545 2.942 3.111 3.113h-.008l.01.002h.01l.078.01.022-.182-.092-.01c-1.477-.16-2.831-1.412-2.95-2.947-.06-.782.277-1.48.83-1.994a3.35 3.35 0 0 1 2.114-.873l.092-.004zm0 1.502-.092.004c-.43.017-.843.192-1.145.473-.301.28-.49.67-.457 1.107.065.841.791 1.512 1.596 1.6l.09.01.021-.182-.091-.01c-.717-.078-1.377-.688-1.434-1.431-.029-.377.132-.712.4-.961.269-.25.644-.409 1.028-.424l.092-.004z",clipRule:"nonzero",overflow:"visible"})}),r=(0,l.withSelect)(e=>({metaFields:e("core/editor").getEditedPostAttribute("meta"),postType:e("core/editor").getCurrentPostType()})),c=(0,l.withDispatch)(e=>({setMetaFields(t){e("core/editor").editPost({meta:t})}})),_=(0,o.compose)([r,c])(({postType:e,metaFields:o,setMetaFields:l})=>{const{content:r,fields:c}=window.jvbFieldConfig||{},[_,w]=(0,a.useEntityProp)("postType",r,"meta");return console.log(c),(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(i.PluginSidebarMoreMenuItem,{target:"metadata-sidebar",icon:(0,s.jsx)(d,{}),children:"Metadata Sidebar"}),(0,s.jsx)(i.PluginSidebar,{name:"metadata-sidebar",icon:(0,s.jsx)(d,{}),title:"Fields",children:(0,s.jsxs)(n.PanelBody,{title:"Book details",initialOpen:!0,children:[(0,s.jsx)(n.PanelRow,{children:(0,s.jsx)(n.TextControl,{value:o._meta_fields_book_title,label:(0,t.__)("Title"),onChange:e=>l({_meta_fields_book_title:e})})}),(0,s.jsx)(n.PanelRow,{children:(0,s.jsx)(n.TextControl,{value:o._meta_fields_book_author,label:(0,t.__)("Author","textdomain"),onChange:e=>l({_meta_fields_book_author:e})})}),(0,s.jsx)(n.PanelRow,{children:(0,s.jsx)(n.TextControl,{value:o._meta_fields_book_publisher,label:(0,t.__)("Publisher","textdomain"),onChange:e=>l({_meta_fields_book_publisher:e})})}),(0,s.jsx)(n.PanelRow,{children:(0,s.jsx)(n.DateTimePicker,{currentDate:o._meta_fields_book_date,onChange:e=>l({_meta_fields_book_date:e}),__nextRemoveHelpButton:!0,__nextRemoveResetButton:!0})})]})})]})});window.wp.editor,(0,e.registerPlugin)("jvb-meta-fields",{render:_})})();
(()=>{"use strict";const e=window.wp.plugins,l=(window.wp.i18n,window.wp.compose),n=window.wp.data,t=window.wp.editor,i=window.wp.components,a=window.wp.coreData,o=window.ReactJSXRuntime,s={text:"text",email:"email",tel:"tel",url:"url",number:"number"},r=({field:e,value:l,onChange:n})=>"textarea"===e.type?(0,o.jsx)(i.TextareaControl,{label:e.label,help:e.description,value:l??"",onChange:n}):(0,o.jsx)(i.TextControl,{label:e.label,help:e.description,type:s[e.type]||"text",value:l??"",onChange:n,required:e.required}),c=({field:e,value:l,onChange:n})=>{const t=Object.entries(e.options||{}).map(([e,l])=>({label:l,value:e}));return"radio"===e.type?(0,o.jsx)(i.RadioControl,{label:e.label,help:e.description,selected:l,options:t,onChange:n}):(0,o.jsx)(i.SelectControl,{label:e.label,help:e.description,value:l??"",options:[{label:"— Select —",value:""},...t],onChange:n})},d=({field:e,value:l,onChange:n})=>{const t=Array.isArray(l)?l:[];return(0,o.jsxs)("fieldset",{children:[(0,o.jsx)("legend",{className:"jvb-field-label",children:e.label}),Object.entries(e.options||{}).map(([e,l])=>(0,o.jsx)(i.CheckboxControl,{label:l,checked:t.includes(e),onChange:l=>((e,l)=>{n(l?[...t,e]:t.filter(l=>l!==e))})(e,l)},e))]})},p=window.React,u=e=>{if(e.description&&0!==e.description.length)return(0,o.jsx)("p",{className:"hint",children:e.description})},m=e=>{if(e.description&&0!==e.description.length)return(0,o.jsx)("p",{className:"hint",children:e.description})},h={text:r,email:r,tel:r,url:r,number:r,textarea:r,select:c,radio:c,checkbox:d,set:d,true_false:({field:e,value:l,onChange:n})=>(0,o.jsx)(i.ToggleControl,{label:e.label,help:e.description,checked:!!l,onChange:n}),date:({field:e,value:l,onChange:n})=>{const[t,a]=(0,p.useState)(new Date);return(0,o.jsxs)("div",{className:"components-base-control",children:[(0,o.jsx)("label",{className:"components-base-control__label",children:e.label}),(0,o.jsx)(i.DatePicker,{currentDate:t,onChange:n,help:e.description,value:l??""}),u(e)]})},time:({field:e,value:l,onChange:n})=>{const[t,a]=(0,p.useState)(new Date);return(0,o.jsx)(i.TimePicker,{currentTime:t,onChange:n,label:e.label,help:e.description,value:l??"",is12Hour:!0})},datetime:({field:e,value:l,onChange:n})=>{const[t,a]=(0,p.useState)(new Date);return console.log(e),(0,o.jsxs)("div",{className:"components-base-control",children:[(0,o.jsx)("label",{className:"components-base-control__label",children:e.label}),(0,o.jsx)(i.DateTimePicker,{currentDate:t,onChange:n,label:e.label,help:e.description,value:l??"",is12Hour:!0}),m(e)]})}},b=({field:e,value:l,onChange:n})=>{const t=h[e.type];return t?(0,o.jsx)(i.PanelRow,{children:(0,o.jsx)(t,{field:e,value:l,onChange:n})}):null},g=({id:e,name:l,isOpen:n=!1})=>{const{content:t,fields:s,sections:r,base:c}=window.jvbFieldConfig||{},[d,p]=(0,a.useEntityProp)("postType",t,"meta");return(0,o.jsx)(i.PanelBody,{name:"jvb-"+e,title:l,initialOpen:n,children:s.map(e=>(0,o.jsx)(b,{field:e,value:d?.[e.name],onChange:l=>((e,l)=>p({...d,[e]:l}))(e.name,l)},e.name))})},w=()=>(0,o.jsx)("svg",{xmlns:"http://www.w3.org/2000/svg",fillRule:"evenodd",strokeLinecap:"square",strokeLinejoin:"round",strokeMiterlimit:"1.5",clipRule:"evenodd",viewBox:"0 0 32 32",children:(0,o.jsx)("path",{fill:"currentColor",fillRule:"nonzero",d:"M16.58 2.133c-7.715 0-15.14 6.014-14.547 13.707.561 7.287 6.938 13.185 13.938 13.947 8.25.898 14.47-5.953 14.004-13.988-.447-7.7-5.683-13.666-13.395-13.666m0 .607h.031v26.492q-.285-.017-.574-.048c-6.724-.732-12.86-6.391-13.398-13.391C2.072 8.442 9.209 2.74 16.58 2.74m-.488 1.145L16 3.889c-3.275.13-6.448 1.476-8.744 3.611-2.297 2.135-3.716 5.065-3.463 8.346.492 6.384 6.071 11.538 12.201 12.207l.09.01.021-.182-.091-.01c-6.041-.66-11.555-5.755-12.04-12.04-.247-3.221 1.142-6.092 3.405-8.196s5.4-3.437 8.629-3.565l.092-.004zm0 1.502L16 5.39c-2.868.113-5.647 1.293-7.658 3.164-2.012 1.87-3.255 4.436-3.033 7.31.43 5.593 5.316 10.106 10.685 10.692l.09.01.021-.18-.091-.01c-5.28-.576-10.1-5.031-10.524-10.525-.217-2.815.997-5.325 2.975-7.164 1.978-1.84 4.72-3.004 7.543-3.116l.092-.004zm0 1.504L16 6.893c-2.462.097-4.846 1.111-6.572 2.716-1.727 1.606-2.796 3.808-2.606 6.276.37 4.8 4.564 8.674 9.172 9.177l.09.01.021-.181-.091-.01c-4.52-.494-8.648-4.307-9.01-9.01-.186-2.408.854-4.554 2.547-6.129s4.04-2.57 6.457-2.666l.092-.004zm0 1.502L16 8.396c-2.055.082-4.045.926-5.486 2.266-1.442 1.34-2.335 3.182-2.176 5.244.309 4.009 3.808 7.24 7.656 7.66l.09.01.008-.068v-.002l.002-.01.004-.01v-.02l.007-.072-.091-.01c-3.76-.41-7.193-3.58-7.494-7.491-.155-2.002.709-3.787 2.117-5.096s3.361-2.14 5.37-2.219l.093-.004zm0 1.502L16 9.898a6.95 6.95 0 0 0-4.402 1.819c-1.157 1.075-1.872 2.553-1.744 4.209.247 3.216 3.053 5.81 6.14 6.146l.09.01.021-.182-.091-.01c-2.999-.327-5.739-2.86-5.979-5.978-.123-1.595.564-3.018 1.688-4.062a6.78 6.78 0 0 1 4.285-1.77l.092-.004zm0 1.503L16 11.4a5.24 5.24 0 0 0-3.316 1.372c-.872.81-1.413 1.924-1.317 3.173.187 2.425 2.3 4.377 4.627 4.631l.09.01.021-.182-.091-.01c-2.238-.244-4.286-2.136-4.465-4.462-.092-1.19.421-2.248 1.26-3.028a5.06 5.06 0 0 1 3.199-1.32l.092-.004zm0 1.502-.092.004a3.52 3.52 0 0 0-2.23.92c-.587.546-.952 1.3-.887 2.143.126 1.633 1.545 2.942 3.111 3.113h-.008l.01.002h.01l.078.01.022-.182-.092-.01c-1.477-.16-2.831-1.412-2.95-2.947-.06-.782.277-1.48.83-1.994a3.35 3.35 0 0 1 2.114-.873l.092-.004zm0 1.502-.092.004c-.43.017-.843.192-1.145.473-.301.28-.49.67-.457 1.107.065.841.791 1.512 1.596 1.6l.09.01.021-.182-.091-.01c-.717-.078-1.377-.688-1.434-1.431-.029-.377.132-.712.4-.961.269-.25.644-.409 1.028-.424l.092-.004z",clipRule:"nonzero",overflow:"visible"})}),x=(0,n.withSelect)(e=>({metaFields:e("core/editor").getEditedPostAttribute("meta"),postType:e("core/editor").getCurrentPostType()})),j=(0,n.withDispatch)(e=>({setMetaFields(l){e("core/editor").editPost({meta:l})}})),v=({section:e,fields:l,base:n})=>{const t=e.fields.map(e=>n+e);return l.filter(e=>t.includes(e.name))},f=e=>0===e,C=(0,l.compose)([x,j])(({postType:e,metaFields:l,setMetaFields:n})=>{const{content:i,fields:s,sections:r,base:c}=window.jvbFieldConfig||{},[d,p]=(0,a.useEntityProp)("postType",i,"meta");return s&&s.length?(console.log(s),console.log(r),(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(t.PluginSidebarMoreMenuItem,{target:"jvb-meta-fields",icon:(0,o.jsx)(w,{}),children:"Additional Fields"}),(0,o.jsx)(t.PluginSidebar,{name:"jvb-meta-fields",icon:(0,o.jsx)(w,{}),title:"Additional Fields",children:Object.values(r).map((e,l)=>(0,o.jsx)(g,{id:e.slug,name:e.title,fields:v({section:e,fields:s,base:c}),meta:d,setMeta:p,isOpen:f(l)}))})]})):null});(0,e.registerPlugin)("jvb-meta-fields",{render:C})})();
inc/registrar/helpers/AddCustomFields.php
@@ -49,6 +49,8 @@
                    $f['name'] = jvbCheckBase($f['name']);
                    return $f;
                },array_values($this->registrar->getFields(false))),
                'sections'  => $this->registrar->getSections(),
                'base'  => BASE
            ]).';',
            'before'
        );
src/editor-fields/Fields.js
@@ -2,6 +2,10 @@
import SelectField from './fields/select-field';
import CheckboxField from './fields/checkbox-field';
import SwitchField from './fields/switch-field';
import DateField from './fields/date-field';
import TimeField from './fields/time-field';
import DateTimeField from "./fields/datetime-field";
import { PanelRow } from '@wordpress/components';
const FIELD_MAP = {
    text: TextField,
@@ -15,12 +19,15 @@
    checkbox: CheckboxField,
    set: CheckboxField,
    true_false: SwitchField,
    date: DateField,
    time: TimeField,
    datetime: DateTimeField,
};
const Fields = ({ field, value, onChange }) => {
    const Component = FIELD_MAP[field.type];
    if (!Component) return null; // repeater/upload/selector: TODO
    return <Component field={field} value={value} onChange={onChange} />;
    return <PanelRow><Component field={field} value={value} onChange={onChange} /></PanelRow>;
};
export default Fields;
src/editor-fields/Section.js
New file
@@ -0,0 +1,27 @@
import { PanelBody, PanelRow } from '@wordpress/components';
import Fields from "./Fields";
import { useEntityProp } from '@wordpress/core-data';
const Section = ({id, name, isOpen = false}) => {
    const { content, fields, sections, base } = window.jvbFieldConfig || {};
    const [meta, setMeta] = useEntityProp('postType', content, 'meta');
    const setField = (name, value) => setMeta({ ...meta, [name]: value });
    return (
        <PanelBody name={'jvb-'+id} title={name} initialOpen={isOpen}>
            {
                fields.map((field) => (
                    <Fields
                        key={field.name}
                        field={field}
                        value={meta?.[field.name]}
                        onChange={(value) => setField(field.name, value)}
                    />
                ))
            }
        </PanelBody>
    );
}
export default Section;
src/editor-fields/SidePanel.js
@@ -1,9 +1,10 @@
import { __ } from '@wordpress/i18n';
import { compose } from '@wordpress/compose';
import { withSelect, withDispatch } from '@wordpress/data';
import { PluginSidebar, PluginSidebarMoreMenuItem } from '@wordpress/edit-post';
import { PluginSidebar, PluginSidebarMoreMenuItem } from '@wordpress/editor';
import { PanelBody, PanelRow, TextControl, DateTimePicker } from '@wordpress/components';
import { useEntityProp } from '@wordpress/core-data';
import Section from './Section';
const JVIcon = () => (
    <svg xmlns="http://www.w3.org/2000/svg" fillRule="evenodd" strokeLinecap="square" strokeLinejoin="round" strokeMiterlimit="1.5" clipRule="evenodd" viewBox="0 0 32 32">
@@ -11,54 +12,42 @@
</svg>
);
const SidePanel = ( { postType, metaFields, setMetaFields } ) => {
    const { content, fields } = window.jvbFieldConfig || {};
    const { content, fields, sections, base } = window.jvbFieldConfig || {};
    const [meta, setMeta] = useEntityProp('postType', content, 'meta');
    if (!fields || !fields.length) return null;
    console.log(fields);
    console.log(sections);
    return (
        <>
            <PluginSidebarMoreMenuItem
                target="metadata-sidebar"
                target="jvb-meta-fields"
                icon={<JVIcon /> }
            >
                Metadata Sidebar
                Additional Fields
            </PluginSidebarMoreMenuItem>
            <PluginSidebar
                name="metadata-sidebar"
                name="jvb-meta-fields"
                icon={<JVIcon /> }
                title="Fields"
                title="Additional Fields"
            >
                <PanelBody title="Book details" initialOpen={ true }>
                    <PanelRow>
                        <TextControl
                            value={ metaFields._meta_fields_book_title }
                            label={ __( "Title" ) }
                            onChange={ (value) => setMetaFields( { _meta_fields_book_title: value } ) }
                {
                    Object.values(sections).map((section, index) => (
                        <Section
                            id={section.slug}
                            name={section.title}
                            fields={filterFields({section, fields, base})}
                            meta={meta}
                            setMeta={setMeta}
                            isOpen={testOpen(index)}
                        />
                    </PanelRow>
                    <PanelRow>
                        <TextControl
                            value={ metaFields._meta_fields_book_author }
                            label={ __("Author", "textdomain") }
                            onChange={ (value) => setMetaFields( { _meta_fields_book_author: value } ) }
                        />
                    </PanelRow>
                    <PanelRow>
                        <TextControl
                            value={ metaFields._meta_fields_book_publisher }
                            label={ __("Publisher", "textdomain") }
                            onChange={ (value) => setMetaFields( { _meta_fields_book_publisher: value } ) }
                        />
                    </PanelRow>
                    <PanelRow>
                        <DateTimePicker
                            currentDate={ metaFields._meta_fields_book_date }
                            onChange={ ( newDate ) => setMetaFields( { _meta_fields_book_date: newDate } ) }
                            __nextRemoveHelpButton
                            __nextRemoveResetButton
                        />
                    </PanelRow>
                </PanelBody>
                    ))
                }
            </PluginSidebar>
        </>
    )
@@ -79,6 +68,15 @@
    }
} );
const filterFields = ({section, fields, base}) => {
    const sectionFields = section.fields.map(f => base+f);
    return fields.filter(item => sectionFields.includes(item.name))
};
const testOpen = (index) => {
    return index === 0;
};
export default compose([
    applyWithSelect,
    applyWithDispatch
src/editor-fields/fields/date-field.js
New file
@@ -0,0 +1,28 @@
import { useState } from 'react';
import { DatePicker } from '@wordpress/components';
const DateField = ({field, value, onChange}) => {
    const [ date, setDate ] = useState( new Date() );
    return (
        <div className="components-base-control">
            <label className="components-base-control__label">
                { field.label }
            </label>
            <DatePicker
                currentDate={ date }
                onChange={ onChange }
                help={ field.description }
                value={value??''}
            />
            { getDescription(field) }
        </div>
    );
};
const getDescription = (field) => {
    if (!field.description || field.description.length === 0) return;
    return (
        <p className="hint">{field.description}</p>
    )
};
export default DateField;
src/editor-fields/fields/datetime-field.js
New file
@@ -0,0 +1,33 @@
import { useState } from 'react';
import { DateTimePicker } from '@wordpress/components';
const DateTimeField = ({field, value, onChange}) => {
    const [ date, setDate ] = useState( new Date() );
    console.log(field);
    return (
        <div className="components-base-control">
            <label className="components-base-control__label">
                { field.label }
            </label>
            <DateTimePicker
                currentDate={ date }
                onChange={ onChange }
                label={ field.label }
                help={ field.description }
                value={value??''}
                is12Hour={ true }
            />
            { getDescription(field) }
        </div>
    );
};
const getDescription = (field) => {
    if (!field.description || field.description.length === 0) return;
    return (
        <p className="hint">{field.description}</p>
    )
};
export default DateTimeField;
src/editor-fields/fields/time-field.js
New file
@@ -0,0 +1,25 @@
import { useState } from 'react';
import { TimePicker } from '@wordpress/components';
const TimeField = ({field, value, onChange}) => {
    const [ time, setTime ] = useState( new Date() );
    return (
        <TimePicker
            currentTime={ time }
            onChange={ onChange }
            label={ field.label }
            help={ field.description }
            value={value??''}
            is12Hour={ true }
        />
    );
};
const getDescription = (field) => {
    if (!field.description || field.description.length === 0) return;
    return (
        <p className="hint">{field.description}</p>
    )
};
export default TimeField;
src/editor-fields/index.js
@@ -1,13 +1,12 @@
import { registerPlugin } from '@wordpress/plugins';
import SidePanel from './SidePanel';
import { PluginDocumentSettingPanel } from '@wordpress/editor';
import { useEntityProp } from '@wordpress/core-data';
import Fields from './Fields';
const CustomFieldsPanel = () => {
    const { postType, fields } = window.jvbFieldConfig || {};
    const [meta, setMeta] = useEntityProp('postType', postType, 'meta');
    if (!fields || !fields.length) {
        return null;
@@ -15,18 +14,7 @@
    const setField = (name, value) => setMeta({ ...meta, [name]: value });
    return (
        <PluginDocumentSettingPanel name="jvb-custom-fields" title="Custom Fields">
            {fields.map((field) => (
                <Fields
                    key={field.name}
                    field={field}
                    value={meta?.[field.name]}
                    onChange={(value) => setField(field.name, value)}
                />
            ))}
        </PluginDocumentSettingPanel>
    );
};
registerPlugin('jvb-meta-fields', {