Skip to content

Commit

Permalink
add required component
Browse files Browse the repository at this point in the history
  • Loading branch information
Sidsector9 committed Jun 29, 2023
1 parent 18d7369 commit 40668bc
Show file tree
Hide file tree
Showing 6 changed files with 146 additions and 0 deletions.
1 change: 1 addition & 0 deletions components/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,3 +25,4 @@ export { PostPrimaryTerm } from './post-primary-term';
export { PostPrimaryCategory } from './post-primary-category';
export { RichTextCharacterLimit, getCharacterCount } from './rich-text-character-limit';
export { CircularProgressBar, Counter } from './counter';
export { Required } from './required';
47 changes: 47 additions & 0 deletions components/required/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import PropTypes from 'prop-types';
import { useDispatch, useSelect } from '@wordpress/data';
import { useEffect, useRef } from '@wordpress/element';
import { v4 as uuidv4 } from 'uuid';
import { store as editorStore } from '@wordpress/editor';
import { store as requiredFieldsStore } from './store';

const lockKey = 'tenup-required-fields-lock-post'

export const Required = ({ value, children }) => {
const { current: componentId } = useRef( uuidv4() );
const { lockPostSaving, unlockPostSaving } = useDispatch( editorStore );
const { setIsFilled } = useDispatch( requiredFieldsStore );

useEffect( () => {
setIsFilled( componentId, !! value );
}, [ value ] );

useDispatch()

const { shouldLock } = useSelect( ( select ) => {
return {
shouldLock: select( requiredFieldsStore ).shouldLock(),
}
} );

useEffect( () => {
if ( shouldLock ) {
lockPostSaving( lockKey );
} else {
unlockPostSaving( lockKey );
}

return () => unlockPostSaving( lockKey );
}, [ shouldLock ] );

return children;
};

Required.defaultProps = {
value: '',
};

Required.propTypes = {
value: PropTypes.string || PropTypes.bool,
children: PropTypes.node.isRequired,
};
1 change: 1 addition & 0 deletions components/required/readme.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
# Required
41 changes: 41 additions & 0 deletions components/required/store.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import { createReduxStore, register } from '@wordpress/data';

const DEFAULT_STATE = {
fields: {},
};

export const store = createReduxStore( 'required-fields-store', {
reducer( state = DEFAULT_STATE, action ) {
switch ( action.type ) {
case 'SET_FIELD_REQUIRED_STATUS':
return {
...state,
fields: {
...state.fields,
[ action.componentId ]: action.status
}
};
}

return state;
},
actions: {
setIsFilled( componentId, status ) {
return {
type: 'SET_FIELD_REQUIRED_STATUS',
componentId,
status,
};
},
},
selectors: {
getFieldRequiredStatuses( state ) {
return state.fields;
},
shouldLock( state ) {
return Object.keys( state.fields ).filter( field => ! state.fields[ field ] ).length > 0;
}
},
} );

register( store );
55 changes: 55 additions & 0 deletions example/src/blocks/required-component-example/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
import { registerBlockType } from '@wordpress/blocks';
import { useBlockProps } from '@wordpress/block-editor';
import { TextControl } from '@wordpress/components';
import { __ } from '@wordpress/i18n';

import { Required } from '@10up/block-components';

const NAMESPACE = 'example';

registerBlockType( `${ NAMESPACE }/required-component-example`, {
apiVersion: 2,
title: __( 'Required Component Example', NAMESPACE ),
icon: 'smiley',
category: 'common',
example: {},
supports: {
html: false
},
attributes: {
fname: {
type: 'string',
default: '',
},
lname: {
type: 'string',
default: ''
}
},
transforms: {},
variations: [],
edit: ( { attributes, setAttributes } ) => {
const blockProps = useBlockProps();
const { fname, lname } = attributes;

return (
<div {...blockProps}>
<Required value={ fname }>
<TextControl
label="First name"
value={ fname }
onChange={ ( val ) => setAttributes( { fname: val } ) }
/>
</Required>
<Required value={ lname }>
<TextControl
label="Last name"
value={ lname }
onChange={ ( val ) => setAttributes( { lname: val } ) }
/>
</Required>
</div>
)
},
save: () => null
} );
1 change: 1 addition & 0 deletions example/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,4 @@ import './blocks/post-featured-image';
import './blocks/content-item';
import './blocks/hero';
import './blocks/post-meta';
import './blocks/required-component-example';

0 comments on commit 40668bc

Please sign in to comment.