Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ One way to ensure all dependencies are loaded is to use the [`@wordpress/depende
- [`ImageSelect`](src/components/ImageSelect)
- [`PostSelect`](src/components/PostSelect)
- [`TermSelect`](src/components/TermSelect)
- [`TermsSelect`](src/components/TermsSelect)
- [`VideoSelect`](src/components/VideoSelect)

## Contributing
Expand Down
2 changes: 1 addition & 1 deletion dist/index.asset.php
Original file line number Diff line number Diff line change
@@ -1 +1 @@
<?php return array('dependencies' => array('react', 'wp-block-editor', 'wp-components', 'wp-core-data', 'wp-data', 'wp-i18n'), 'version' => '6afcf74866286596fb72');
<?php return array('dependencies' => array('react', 'wp-block-editor', 'wp-components', 'wp-core-data', 'wp-data', 'wp-i18n'), 'version' => 'e2614129b7d60c8a3bbb');
2 changes: 1 addition & 1 deletion dist/index.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@meom/block-components",
"version": "1.3.0",
"version": "1.4.0",
"description": "MEOM block components",
"homepage": "https://github.com/MEOM/block-components",
"repository": {
Expand Down
45 changes: 45 additions & 0 deletions src/components/TermsSelect/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
# TermSelect

The `TermsSelect` component allows for selecting multiple terms from wanted taxonomy using `<FormTokenField>` component.

## Usage

For a minimum working setup, you need to define `termIDs` attribute and pass an taxonomy as `taxonomyName` and other `props`.

```js
import { TermsSelect } from '@meom/block-components';

// Inside block `edit` function:
const {
attributes: {},
setAttributes,
} = props;

// `category` can be any taxonomy name.
<TermsSelect
taxonomyName="category" {...props}
/>
```

## `termIds`

Term ID array.

Remember to define `termIds` in `block.json` file as attribute:

```json
"attributes": {
"termIds": {
"type": "array",
"default": []
},
}
```

### `settingsLabel`

Component label.

- Type: `string`
- Required: No
- Default: `Choose categories`
85 changes: 85 additions & 0 deletions src/components/TermsSelect/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
/**
* WordPress dependencies
*/
import { __ } from '@wordpress/i18n';
import { FormTokenField, Spinner } from '@wordpress/components';
import { useEntityRecords } from '@wordpress/core-data';

const SETTINGS_LABEL = __( 'Choose categories', 'meom-block-components' );

/**
* Multi-select term picker for a taxonomy using FormTokenField.
*
* Stores selected term IDs in `attributes.termIds`. Display tokens are term
* names; the component converts between names and IDs via the resolved list.
*
* @param {Object} props Props for component.
* @param {Object} props.attributes Block attributes (expects `termIds` array).
* @param {string} props.taxonomyName Taxonomy slug to query terms from.
* @param {Object} [props.queryArgs] Args passed to useEntityRecords.
* @param {Object} [props.queryOptions] Options passed to useEntityRecords.
* @param {Function} props.setAttributes Block setAttributes.
* @return {JSX.Element|null} TermsSelect markup, or null when no records.
*/
function TermsSelect( props ) {
const {
attributes: { termIds = [] },
taxonomyName,
queryArgs = {
per_page: 99,
orderby: 'name',
order: 'asc',
_fields: 'id,name',
},
queryOptions = { enabled: true },
setAttributes,
settingsLabel = SETTINGS_LABEL,
} = props;

// See: https://make.wordpress.org/core/2022/10/11/simplified-data-access-with-new-react-hooks-in-wordpress-6-1/
// See: https://developer.wordpress.org/block-editor/reference-guides/packages/packages-core-data/#useentityrecords
const { records, isResolving } = useEntityRecords(
'taxonomy',
taxonomyName,
queryArgs,
queryOptions
);

if ( isResolving ) {
return <Spinner />;
}

if ( ! records || records.length === 0 ) {
return null;
}

const idToName = new Map( records.map( ( t ) => [ t.id, t.name ] ) );
const nameToId = new Map( records.map( ( t ) => [ t.name, t.id ] ) );
const allNames = records.map( ( t ) => t.name );

const selectedNames = termIds
.map( ( id ) => idToName.get( id ) )
.filter( Boolean );

return (
<FormTokenField
label={ settingsLabel }
value={ selectedNames }
suggestions={ allNames }
onChange={ ( newNames ) => {
const newIds = newNames
.map( ( name ) => nameToId.get( name ) )
.filter( ( id ) => typeof id === 'number' );
setAttributes( { termIds: newIds } );
} }
__experimentalExpandOnFocus
__experimentalShowHowTo={ false }
help={ __(
'You can select one or more terms. Selecting multiple terms will expand the lifts (OR logic).',
'meom-block-components'
) }
/>
);
}

export default TermsSelect;
1 change: 1 addition & 0 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,5 @@
export { default as ImageSelect } from './components/ImageSelect';
export { default as PostSelect } from './components/PostSelect';
export { default as TermSelect } from './components/TermSelect';
export { default as TermsSelect } from './components/TermsSelect';
export { default as VideoSelect } from './components/VideoSelect';