From bfa19b079a043bbaf3165474d59c528b1216b9ab Mon Sep 17 00:00:00 2001 From: Sami Keijonen Date: Sat, 2 May 2026 21:36:16 +0300 Subject: [PATCH 1/2] Add TermsSelect component --- README.md | 1 + dist/index.asset.php | 2 +- dist/index.js | 2 +- package.json | 2 +- src/components/TermsSelect/README.md | 37 +++++++++++++ src/components/TermsSelect/index.js | 82 ++++++++++++++++++++++++++++ src/index.js | 1 + 7 files changed, 124 insertions(+), 3 deletions(-) create mode 100644 src/components/TermsSelect/README.md create mode 100644 src/components/TermsSelect/index.js diff --git a/README.md b/README.md index 853ed8e..c6ff696 100644 --- a/README.md +++ b/README.md @@ -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 diff --git a/dist/index.asset.php b/dist/index.asset.php index 7de53ca..4420fff 100644 --- a/dist/index.asset.php +++ b/dist/index.asset.php @@ -1 +1 @@ - array('react', 'wp-block-editor', 'wp-components', 'wp-core-data', 'wp-data', 'wp-i18n'), 'version' => '6afcf74866286596fb72'); + array('react', 'wp-block-editor', 'wp-components', 'wp-core-data', 'wp-data', 'wp-i18n'), 'version' => 'cc535db7ba4926150b6d'); diff --git a/dist/index.js b/dist/index.js index 0c669af..8616f74 100644 --- a/dist/index.js +++ b/dist/index.js @@ -1 +1 @@ -!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define([],t):"object"==typeof exports?exports["@meom/block-components"]=t():e["@meom/block-components"]=t()}(globalThis,(()=>(()=>{"use strict";var e={d:(t,o)=>{for(var n in o)e.o(o,n)&&!e.o(t,n)&&Object.defineProperty(t,n,{enumerable:!0,get:o[n]})},o:(e,t)=>Object.prototype.hasOwnProperty.call(e,t),r:e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})}},t={};e.r(t),e.d(t,{ImageSelect:()=>y,PostSelect:()=>_,TermSelect:()=>v,VideoSelect:()=>k});const o=window.React,n=window.wp.i18n,l=window.wp.components,a=window.wp.blockEditor,r=window.wp.data,c=window.wp.coreData,m=(0,n.__)("Media","meom-block-components"),i=(0,n.__)("Replace Image","meom-block-components"),s=(0,n.__)("Remove Image","meom-block-components"),u=(0,n.__)("Add Image","meom-block-components"),d=e=>{const{onSelect:t,onRemove:n,isOptional:d=!0,id:p}=e,b=!!p,{media:g}=function(e){return(0,r.useSelect)((t=>{const{getMedia:o,isResolving:n,hasFinishedResolution:l}=t(c.store),a=[e,{context:"view"}];return{media:o(...a),isResolvingMedia:n("getMedia",a),hasResolvedMedia:l("getMedia",a)}}),[e])}(p);return(0,o.createElement)(a.BlockControls,null,(0,o.createElement)(l.ToolbarGroup,{label:m},b?(0,o.createElement)(o.Fragment,null,(0,o.createElement)(a.MediaReplaceFlow,{mediaUrl:g?.source_url,onSelect:t,name:i}),!!d&&(0,o.createElement)(l.ToolbarButton,{onClick:n},s)):(0,o.createElement)(a.MediaUploadCheck,null,(0,o.createElement)(a.MediaUpload,{onSelect:t,render:({open:e})=>(0,o.createElement)(l.ToolbarButton,{onClick:e},u)}))))},p=(0,n.__)("Image settings","meom-block-components"),b=(0,n.__)("Image focalpoint","meom-block-components"),g=(0,n.__)("Pick image focalpoint which is central point of the image.","meom-block-components"),E=(0,n.__)("Remove Image","meom-block-components"),y=function(e){const{image:t,onChange:n,settingsText:r=p,showRemoveImageButton:c=!0,buttonText:m=E,useFocalPoint:i=!1,useMediaToolbar:s=!0,focalPointLabel:u=b,focalPointHelp:y=g,focalPoint:_={x:.5,y:.5},onChangeFocalPoint:v,...f}=e,h=t&&t.id,w=t&&t.url;if(i){const e={objectFit:"cover",objectPosition:`${100*_.x}% ${100*_.y}%`};f.style={...f.style,...e}}return(0,o.createElement)(o.Fragment,null,h?(0,o.createElement)(o.Fragment,null,i&&(0,o.createElement)(a.InspectorControls,null,(0,o.createElement)(l.PanelBody,{title:r},(0,o.createElement)(l.FocalPointPicker,{label:u,help:y,url:w,value:_,onChange:v}))),s&&(0,o.createElement)(d,{id:h,onSelect:({id:e,url:t})=>{n({id:e,url:t})},onRemove:()=>{n(null)}}),(0,o.createElement)("img",{src:w,alt:"",...f}),c&&(0,o.createElement)(l.Button,{className:"meom-media-button button button-large",onClick:()=>n(null)},m)):(0,o.createElement)(a.MediaPlaceholder,{onSelect:({id:e,url:t})=>{n({id:e,url:t})},allowedTypes:["image"]}))},_=function(e){const{attributes:{postId:t},postTypeName:a,queryArgs:r={per_page:99},queryOptions:m={enabled:!0},setAttributes:i}=e,s=[],{records:u,isResolving:d}=(0,c.useEntityRecords)("postType",a,r,m);return s.push({value:0,label:(0,n.__)("No post selected","meom-block-components")}),!d&&u&&u.length>0&&u.forEach((e=>{s.push({value:e.id,label:e.title.raw})})),(0,o.createElement)(o.Fragment,null,d&&(0,o.createElement)(l.Spinner,null),!d&&(0,o.createElement)(o.Fragment,null,(0,o.createElement)(l.SelectControl,{label:(0,n.__)("Choose post","meom-block-components"),options:s,onChange:e=>{i({postId:e})},value:t})))},v=function(e){const{attributes:{termId:t},taxonomyName:a,queryArgs:r={per_page:99},queryOptions:m={enabled:!0},setAttributes:i,useMultiple:s=!1}=e,u=[],{records:d,isResolving:p}=(0,c.useEntityRecords)("taxonomy",a,r,m);return u.push({value:0,label:(0,n.__)("From all categories","meom-block-components")}),!p&&d&&d.length>0&&d.forEach((e=>{u.push({value:e.id,label:e.name})})),(0,o.createElement)(o.Fragment,null,p&&(0,o.createElement)(l.Spinner,null),!p&&(0,o.createElement)(o.Fragment,null,(0,o.createElement)(l.SelectControl,{label:(0,n.__)("Choose category","meom-block-components"),options:u,onChange:e=>{i({termId:e})},value:t,...s?{multiple:!0}:{}})))},f=(0,n.__)("Remove Video","meom-block-components"),h={autoPlay:!0,muted:!0,loop:!0},w="video/mp4",k=function(e){const{video:t,onChange:n,buttonText:r=f,videoAttributes:c=h,videoType:m=w}=e,i=t&&t.id,s=t&&t.url;return(0,o.createElement)(o.Fragment,null,i?(0,o.createElement)(o.Fragment,null,(0,o.createElement)("video",{...c},(0,o.createElement)("source",{src:s,type:m})),(0,o.createElement)(l.Button,{className:"meom-media-button button button-large",onClick:()=>n(null)},r)):(0,o.createElement)(a.MediaPlaceholder,{onSelect:({id:e,url:t})=>{n({id:e,url:t})},allowedTypes:["video"]}))};return t})())); \ No newline at end of file +!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define([],t):"object"==typeof exports?exports["@meom/block-components"]=t():e["@meom/block-components"]=t()}(globalThis,(()=>(()=>{"use strict";var e={d:(t,o)=>{for(var n in o)e.o(o,n)&&!e.o(t,n)&&Object.defineProperty(t,n,{enumerable:!0,get:o[n]})},o:(e,t)=>Object.prototype.hasOwnProperty.call(e,t),r:e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})}},t={};e.r(t),e.d(t,{ImageSelect:()=>_,PostSelect:()=>E,TermSelect:()=>f,TermsSelect:()=>h,VideoSelect:()=>S});const o=window.React,n=window.wp.i18n,l=window.wp.components,a=window.wp.blockEditor,r=window.wp.data,m=window.wp.coreData,c=(0,n.__)("Media","meom-block-components"),i=(0,n.__)("Replace Image","meom-block-components"),s=(0,n.__)("Remove Image","meom-block-components"),u=(0,n.__)("Add Image","meom-block-components"),p=e=>{const{onSelect:t,onRemove:n,isOptional:p=!0,id:d}=e,b=!!d,{media:g}=function(e){return(0,r.useSelect)((t=>{const{getMedia:o,isResolving:n,hasFinishedResolution:l}=t(m.store),a=[e,{context:"view"}];return{media:o(...a),isResolvingMedia:n("getMedia",a),hasResolvedMedia:l("getMedia",a)}}),[e])}(d);return(0,o.createElement)(a.BlockControls,null,(0,o.createElement)(l.ToolbarGroup,{label:c},b?(0,o.createElement)(o.Fragment,null,(0,o.createElement)(a.MediaReplaceFlow,{mediaUrl:g?.source_url,onSelect:t,name:i}),!!p&&(0,o.createElement)(l.ToolbarButton,{onClick:n},s)):(0,o.createElement)(a.MediaUploadCheck,null,(0,o.createElement)(a.MediaUpload,{onSelect:t,render:({open:e})=>(0,o.createElement)(l.ToolbarButton,{onClick:e},u)}))))},d=(0,n.__)("Image settings","meom-block-components"),b=(0,n.__)("Image focalpoint","meom-block-components"),g=(0,n.__)("Pick image focalpoint which is central point of the image.","meom-block-components"),y=(0,n.__)("Remove Image","meom-block-components"),_=function(e){const{image:t,onChange:n,settingsText:r=d,showRemoveImageButton:m=!0,buttonText:c=y,useFocalPoint:i=!1,useMediaToolbar:s=!0,focalPointLabel:u=b,focalPointHelp:_=g,focalPoint:E={x:.5,y:.5},onChangeFocalPoint:f,...h}=e,v=t&&t.id,w=t&&t.url;if(i){const e={objectFit:"cover",objectPosition:`${100*E.x}% ${100*E.y}%`};h.style={...h.style,...e}}return(0,o.createElement)(o.Fragment,null,v?(0,o.createElement)(o.Fragment,null,i&&(0,o.createElement)(a.InspectorControls,null,(0,o.createElement)(l.PanelBody,{title:r},(0,o.createElement)(l.FocalPointPicker,{label:u,help:_,url:w,value:E,onChange:f}))),s&&(0,o.createElement)(p,{id:v,onSelect:({id:e,url:t})=>{n({id:e,url:t})},onRemove:()=>{n(null)}}),(0,o.createElement)("img",{src:w,alt:"",...h}),m&&(0,o.createElement)(l.Button,{className:"meom-media-button button button-large",onClick:()=>n(null)},c)):(0,o.createElement)(a.MediaPlaceholder,{onSelect:({id:e,url:t})=>{n({id:e,url:t})},allowedTypes:["image"]}))},E=function(e){const{attributes:{postId:t},postTypeName:a,queryArgs:r={per_page:99},queryOptions:c={enabled:!0},setAttributes:i}=e,s=[],{records:u,isResolving:p}=(0,m.useEntityRecords)("postType",a,r,c);return s.push({value:0,label:(0,n.__)("No post selected","meom-block-components")}),!p&&u&&u.length>0&&u.forEach((e=>{s.push({value:e.id,label:e.title.raw})})),(0,o.createElement)(o.Fragment,null,p&&(0,o.createElement)(l.Spinner,null),!p&&(0,o.createElement)(o.Fragment,null,(0,o.createElement)(l.SelectControl,{label:(0,n.__)("Choose post","meom-block-components"),options:s,onChange:e=>{i({postId:e})},value:t})))},f=function(e){const{attributes:{termId:t},taxonomyName:a,queryArgs:r={per_page:99},queryOptions:c={enabled:!0},setAttributes:i,useMultiple:s=!1}=e,u=[],{records:p,isResolving:d}=(0,m.useEntityRecords)("taxonomy",a,r,c);return u.push({value:0,label:(0,n.__)("From all categories","meom-block-components")}),!d&&p&&p.length>0&&p.forEach((e=>{u.push({value:e.id,label:e.name})})),(0,o.createElement)(o.Fragment,null,d&&(0,o.createElement)(l.Spinner,null),!d&&(0,o.createElement)(o.Fragment,null,(0,o.createElement)(l.SelectControl,{label:(0,n.__)("Choose category","meom-block-components"),options:u,onChange:e=>{i({termId:e})},value:t,...s?{multiple:!0}:{}})))},h=function(e){const{attributes:{termIds:t=[]},taxonomyName:a,queryArgs:r={per_page:99,orderby:"name",order:"asc",_fields:"id,name"},queryOptions:c={enabled:!0},setAttributes:i}=e,{records:s,isResolving:u}=(0,m.useEntityRecords)("taxonomy",a,r,c);if(u)return(0,o.createElement)(l.Spinner,null);if(!s||0===s.length)return null;const p=new Map(s.map((e=>[e.id,e.name]))),d=new Map(s.map((e=>[e.name,e.id]))),b=s.map((e=>e.name)),g=t.map((e=>p.get(e))).filter(Boolean);return(0,o.createElement)(l.FormTokenField,{label:(0,n.__)("Choose categories","meom-block-components"),value:g,suggestions:b,onChange:e=>{const t=e.map((e=>d.get(e))).filter((e=>"number"==typeof e));i({termIds:t})},__experimentalExpandOnFocus:!0,__experimentalShowHowTo:!1,help:(0,n.__)("You can select one or more terms. Selecting multiple terms will expand the lifts (OR logic).","block-components")})},v=(0,n.__)("Remove Video","meom-block-components"),w={autoPlay:!0,muted:!0,loop:!0},k="video/mp4",S=function(e){const{video:t,onChange:n,buttonText:r=v,videoAttributes:m=w,videoType:c=k}=e,i=t&&t.id,s=t&&t.url;return(0,o.createElement)(o.Fragment,null,i?(0,o.createElement)(o.Fragment,null,(0,o.createElement)("video",{...m},(0,o.createElement)("source",{src:s,type:c})),(0,o.createElement)(l.Button,{className:"meom-media-button button button-large",onClick:()=>n(null)},r)):(0,o.createElement)(a.MediaPlaceholder,{onSelect:({id:e,url:t})=>{n({id:e,url:t})},allowedTypes:["video"]}))};return t})())); \ No newline at end of file diff --git a/package.json b/package.json index 17772f8..04d83f8 100644 --- a/package.json +++ b/package.json @@ -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": { diff --git a/src/components/TermsSelect/README.md b/src/components/TermsSelect/README.md new file mode 100644 index 0000000..261cb5e --- /dev/null +++ b/src/components/TermsSelect/README.md @@ -0,0 +1,37 @@ +# TermSelect + +The `TermsSelect` component allows for selecting multiple terms from wanted taxonomy using `` 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. + +``` + +## `termIds` + +Term ID array. + +Remember to define `termIds` in `block.json` file as attribute: + +```json +"attributes": { + "termIds": { + "type": "array", + "default": [] + }, +} +``` diff --git a/src/components/TermsSelect/index.js b/src/components/TermsSelect/index.js new file mode 100644 index 0000000..156da37 --- /dev/null +++ b/src/components/TermsSelect/index.js @@ -0,0 +1,82 @@ +/** + * WordPress dependencies + */ +import { __ } from '@wordpress/i18n'; +import { FormTokenField, Spinner } from '@wordpress/components'; +import { useEntityRecords } from '@wordpress/core-data'; + +/** + * 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, + } = 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 ; + } + + 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 ( + { + 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).', + 'block-components' + ) } + /> + ); +} + +export default TermsSelect; diff --git a/src/index.js b/src/index.js index 0620405..4650f03 100644 --- a/src/index.js +++ b/src/index.js @@ -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'; From 8c06f8a7508e80e2758bfe67f6f8c0440066c9a7 Mon Sep 17 00:00:00 2001 From: Sami Keijonen Date: Sat, 2 May 2026 21:49:30 +0300 Subject: [PATCH 2/2] Add label prop for TermsSelect --- dist/index.asset.php | 2 +- dist/index.js | 2 +- src/components/TermsSelect/README.md | 8 ++++++++ src/components/TermsSelect/index.js | 7 +++++-- 4 files changed, 15 insertions(+), 4 deletions(-) diff --git a/dist/index.asset.php b/dist/index.asset.php index 4420fff..b2c6448 100644 --- a/dist/index.asset.php +++ b/dist/index.asset.php @@ -1 +1 @@ - array('react', 'wp-block-editor', 'wp-components', 'wp-core-data', 'wp-data', 'wp-i18n'), 'version' => 'cc535db7ba4926150b6d'); + array('react', 'wp-block-editor', 'wp-components', 'wp-core-data', 'wp-data', 'wp-i18n'), 'version' => 'e2614129b7d60c8a3bbb'); diff --git a/dist/index.js b/dist/index.js index 8616f74..b4c8ab5 100644 --- a/dist/index.js +++ b/dist/index.js @@ -1 +1 @@ -!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define([],t):"object"==typeof exports?exports["@meom/block-components"]=t():e["@meom/block-components"]=t()}(globalThis,(()=>(()=>{"use strict";var e={d:(t,o)=>{for(var n in o)e.o(o,n)&&!e.o(t,n)&&Object.defineProperty(t,n,{enumerable:!0,get:o[n]})},o:(e,t)=>Object.prototype.hasOwnProperty.call(e,t),r:e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})}},t={};e.r(t),e.d(t,{ImageSelect:()=>_,PostSelect:()=>E,TermSelect:()=>f,TermsSelect:()=>h,VideoSelect:()=>S});const o=window.React,n=window.wp.i18n,l=window.wp.components,a=window.wp.blockEditor,r=window.wp.data,m=window.wp.coreData,c=(0,n.__)("Media","meom-block-components"),i=(0,n.__)("Replace Image","meom-block-components"),s=(0,n.__)("Remove Image","meom-block-components"),u=(0,n.__)("Add Image","meom-block-components"),p=e=>{const{onSelect:t,onRemove:n,isOptional:p=!0,id:d}=e,b=!!d,{media:g}=function(e){return(0,r.useSelect)((t=>{const{getMedia:o,isResolving:n,hasFinishedResolution:l}=t(m.store),a=[e,{context:"view"}];return{media:o(...a),isResolvingMedia:n("getMedia",a),hasResolvedMedia:l("getMedia",a)}}),[e])}(d);return(0,o.createElement)(a.BlockControls,null,(0,o.createElement)(l.ToolbarGroup,{label:c},b?(0,o.createElement)(o.Fragment,null,(0,o.createElement)(a.MediaReplaceFlow,{mediaUrl:g?.source_url,onSelect:t,name:i}),!!p&&(0,o.createElement)(l.ToolbarButton,{onClick:n},s)):(0,o.createElement)(a.MediaUploadCheck,null,(0,o.createElement)(a.MediaUpload,{onSelect:t,render:({open:e})=>(0,o.createElement)(l.ToolbarButton,{onClick:e},u)}))))},d=(0,n.__)("Image settings","meom-block-components"),b=(0,n.__)("Image focalpoint","meom-block-components"),g=(0,n.__)("Pick image focalpoint which is central point of the image.","meom-block-components"),y=(0,n.__)("Remove Image","meom-block-components"),_=function(e){const{image:t,onChange:n,settingsText:r=d,showRemoveImageButton:m=!0,buttonText:c=y,useFocalPoint:i=!1,useMediaToolbar:s=!0,focalPointLabel:u=b,focalPointHelp:_=g,focalPoint:E={x:.5,y:.5},onChangeFocalPoint:f,...h}=e,v=t&&t.id,w=t&&t.url;if(i){const e={objectFit:"cover",objectPosition:`${100*E.x}% ${100*E.y}%`};h.style={...h.style,...e}}return(0,o.createElement)(o.Fragment,null,v?(0,o.createElement)(o.Fragment,null,i&&(0,o.createElement)(a.InspectorControls,null,(0,o.createElement)(l.PanelBody,{title:r},(0,o.createElement)(l.FocalPointPicker,{label:u,help:_,url:w,value:E,onChange:f}))),s&&(0,o.createElement)(p,{id:v,onSelect:({id:e,url:t})=>{n({id:e,url:t})},onRemove:()=>{n(null)}}),(0,o.createElement)("img",{src:w,alt:"",...h}),m&&(0,o.createElement)(l.Button,{className:"meom-media-button button button-large",onClick:()=>n(null)},c)):(0,o.createElement)(a.MediaPlaceholder,{onSelect:({id:e,url:t})=>{n({id:e,url:t})},allowedTypes:["image"]}))},E=function(e){const{attributes:{postId:t},postTypeName:a,queryArgs:r={per_page:99},queryOptions:c={enabled:!0},setAttributes:i}=e,s=[],{records:u,isResolving:p}=(0,m.useEntityRecords)("postType",a,r,c);return s.push({value:0,label:(0,n.__)("No post selected","meom-block-components")}),!p&&u&&u.length>0&&u.forEach((e=>{s.push({value:e.id,label:e.title.raw})})),(0,o.createElement)(o.Fragment,null,p&&(0,o.createElement)(l.Spinner,null),!p&&(0,o.createElement)(o.Fragment,null,(0,o.createElement)(l.SelectControl,{label:(0,n.__)("Choose post","meom-block-components"),options:s,onChange:e=>{i({postId:e})},value:t})))},f=function(e){const{attributes:{termId:t},taxonomyName:a,queryArgs:r={per_page:99},queryOptions:c={enabled:!0},setAttributes:i,useMultiple:s=!1}=e,u=[],{records:p,isResolving:d}=(0,m.useEntityRecords)("taxonomy",a,r,c);return u.push({value:0,label:(0,n.__)("From all categories","meom-block-components")}),!d&&p&&p.length>0&&p.forEach((e=>{u.push({value:e.id,label:e.name})})),(0,o.createElement)(o.Fragment,null,d&&(0,o.createElement)(l.Spinner,null),!d&&(0,o.createElement)(o.Fragment,null,(0,o.createElement)(l.SelectControl,{label:(0,n.__)("Choose category","meom-block-components"),options:u,onChange:e=>{i({termId:e})},value:t,...s?{multiple:!0}:{}})))},h=function(e){const{attributes:{termIds:t=[]},taxonomyName:a,queryArgs:r={per_page:99,orderby:"name",order:"asc",_fields:"id,name"},queryOptions:c={enabled:!0},setAttributes:i}=e,{records:s,isResolving:u}=(0,m.useEntityRecords)("taxonomy",a,r,c);if(u)return(0,o.createElement)(l.Spinner,null);if(!s||0===s.length)return null;const p=new Map(s.map((e=>[e.id,e.name]))),d=new Map(s.map((e=>[e.name,e.id]))),b=s.map((e=>e.name)),g=t.map((e=>p.get(e))).filter(Boolean);return(0,o.createElement)(l.FormTokenField,{label:(0,n.__)("Choose categories","meom-block-components"),value:g,suggestions:b,onChange:e=>{const t=e.map((e=>d.get(e))).filter((e=>"number"==typeof e));i({termIds:t})},__experimentalExpandOnFocus:!0,__experimentalShowHowTo:!1,help:(0,n.__)("You can select one or more terms. Selecting multiple terms will expand the lifts (OR logic).","block-components")})},v=(0,n.__)("Remove Video","meom-block-components"),w={autoPlay:!0,muted:!0,loop:!0},k="video/mp4",S=function(e){const{video:t,onChange:n,buttonText:r=v,videoAttributes:m=w,videoType:c=k}=e,i=t&&t.id,s=t&&t.url;return(0,o.createElement)(o.Fragment,null,i?(0,o.createElement)(o.Fragment,null,(0,o.createElement)("video",{...m},(0,o.createElement)("source",{src:s,type:c})),(0,o.createElement)(l.Button,{className:"meom-media-button button button-large",onClick:()=>n(null)},r)):(0,o.createElement)(a.MediaPlaceholder,{onSelect:({id:e,url:t})=>{n({id:e,url:t})},allowedTypes:["video"]}))};return t})())); \ No newline at end of file +!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define([],t):"object"==typeof exports?exports["@meom/block-components"]=t():e["@meom/block-components"]=t()}(globalThis,(()=>(()=>{"use strict";var e={d:(t,o)=>{for(var n in o)e.o(o,n)&&!e.o(t,n)&&Object.defineProperty(t,n,{enumerable:!0,get:o[n]})},o:(e,t)=>Object.prototype.hasOwnProperty.call(e,t),r:e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})}},t={};e.r(t),e.d(t,{ImageSelect:()=>_,PostSelect:()=>E,TermSelect:()=>f,TermsSelect:()=>v,VideoSelect:()=>R});const o=window.React,n=window.wp.i18n,l=window.wp.components,a=window.wp.blockEditor,r=window.wp.data,m=window.wp.coreData,c=(0,n.__)("Media","meom-block-components"),i=(0,n.__)("Replace Image","meom-block-components"),s=(0,n.__)("Remove Image","meom-block-components"),u=(0,n.__)("Add Image","meom-block-components"),p=e=>{const{onSelect:t,onRemove:n,isOptional:p=!0,id:d}=e,b=!!d,{media:g}=function(e){return(0,r.useSelect)((t=>{const{getMedia:o,isResolving:n,hasFinishedResolution:l}=t(m.store),a=[e,{context:"view"}];return{media:o(...a),isResolvingMedia:n("getMedia",a),hasResolvedMedia:l("getMedia",a)}}),[e])}(d);return(0,o.createElement)(a.BlockControls,null,(0,o.createElement)(l.ToolbarGroup,{label:c},b?(0,o.createElement)(o.Fragment,null,(0,o.createElement)(a.MediaReplaceFlow,{mediaUrl:g?.source_url,onSelect:t,name:i}),!!p&&(0,o.createElement)(l.ToolbarButton,{onClick:n},s)):(0,o.createElement)(a.MediaUploadCheck,null,(0,o.createElement)(a.MediaUpload,{onSelect:t,render:({open:e})=>(0,o.createElement)(l.ToolbarButton,{onClick:e},u)}))))},d=(0,n.__)("Image settings","meom-block-components"),b=(0,n.__)("Image focalpoint","meom-block-components"),g=(0,n.__)("Pick image focalpoint which is central point of the image.","meom-block-components"),y=(0,n.__)("Remove Image","meom-block-components"),_=function(e){const{image:t,onChange:n,settingsText:r=d,showRemoveImageButton:m=!0,buttonText:c=y,useFocalPoint:i=!1,useMediaToolbar:s=!0,focalPointLabel:u=b,focalPointHelp:_=g,focalPoint:E={x:.5,y:.5},onChangeFocalPoint:f,...h}=e,v=t&&t.id,w=t&&t.url;if(i){const e={objectFit:"cover",objectPosition:`${100*E.x}% ${100*E.y}%`};h.style={...h.style,...e}}return(0,o.createElement)(o.Fragment,null,v?(0,o.createElement)(o.Fragment,null,i&&(0,o.createElement)(a.InspectorControls,null,(0,o.createElement)(l.PanelBody,{title:r},(0,o.createElement)(l.FocalPointPicker,{label:u,help:_,url:w,value:E,onChange:f}))),s&&(0,o.createElement)(p,{id:v,onSelect:({id:e,url:t})=>{n({id:e,url:t})},onRemove:()=>{n(null)}}),(0,o.createElement)("img",{src:w,alt:"",...h}),m&&(0,o.createElement)(l.Button,{className:"meom-media-button button button-large",onClick:()=>n(null)},c)):(0,o.createElement)(a.MediaPlaceholder,{onSelect:({id:e,url:t})=>{n({id:e,url:t})},allowedTypes:["image"]}))},E=function(e){const{attributes:{postId:t},postTypeName:a,queryArgs:r={per_page:99},queryOptions:c={enabled:!0},setAttributes:i}=e,s=[],{records:u,isResolving:p}=(0,m.useEntityRecords)("postType",a,r,c);return s.push({value:0,label:(0,n.__)("No post selected","meom-block-components")}),!p&&u&&u.length>0&&u.forEach((e=>{s.push({value:e.id,label:e.title.raw})})),(0,o.createElement)(o.Fragment,null,p&&(0,o.createElement)(l.Spinner,null),!p&&(0,o.createElement)(o.Fragment,null,(0,o.createElement)(l.SelectControl,{label:(0,n.__)("Choose post","meom-block-components"),options:s,onChange:e=>{i({postId:e})},value:t})))},f=function(e){const{attributes:{termId:t},taxonomyName:a,queryArgs:r={per_page:99},queryOptions:c={enabled:!0},setAttributes:i,useMultiple:s=!1}=e,u=[],{records:p,isResolving:d}=(0,m.useEntityRecords)("taxonomy",a,r,c);return u.push({value:0,label:(0,n.__)("From all categories","meom-block-components")}),!d&&p&&p.length>0&&p.forEach((e=>{u.push({value:e.id,label:e.name})})),(0,o.createElement)(o.Fragment,null,d&&(0,o.createElement)(l.Spinner,null),!d&&(0,o.createElement)(o.Fragment,null,(0,o.createElement)(l.SelectControl,{label:(0,n.__)("Choose category","meom-block-components"),options:u,onChange:e=>{i({termId:e})},value:t,...s?{multiple:!0}:{}})))},h=(0,n.__)("Choose categories","meom-block-components"),v=function(e){const{attributes:{termIds:t=[]},taxonomyName:a,queryArgs:r={per_page:99,orderby:"name",order:"asc",_fields:"id,name"},queryOptions:c={enabled:!0},setAttributes:i,settingsLabel:s=h}=e,{records:u,isResolving:p}=(0,m.useEntityRecords)("taxonomy",a,r,c);if(p)return(0,o.createElement)(l.Spinner,null);if(!u||0===u.length)return null;const d=new Map(u.map((e=>[e.id,e.name]))),b=new Map(u.map((e=>[e.name,e.id]))),g=u.map((e=>e.name)),y=t.map((e=>d.get(e))).filter(Boolean);return(0,o.createElement)(l.FormTokenField,{label:s,value:y,suggestions:g,onChange:e=>{const t=e.map((e=>b.get(e))).filter((e=>"number"==typeof e));i({termIds:t})},__experimentalExpandOnFocus:!0,__experimentalShowHowTo:!1,help:(0,n.__)("You can select one or more terms. Selecting multiple terms will expand the lifts (OR logic).","meom-block-components")})},w=(0,n.__)("Remove Video","meom-block-components"),k={autoPlay:!0,muted:!0,loop:!0},S="video/mp4",R=function(e){const{video:t,onChange:n,buttonText:r=w,videoAttributes:m=k,videoType:c=S}=e,i=t&&t.id,s=t&&t.url;return(0,o.createElement)(o.Fragment,null,i?(0,o.createElement)(o.Fragment,null,(0,o.createElement)("video",{...m},(0,o.createElement)("source",{src:s,type:c})),(0,o.createElement)(l.Button,{className:"meom-media-button button button-large",onClick:()=>n(null)},r)):(0,o.createElement)(a.MediaPlaceholder,{onSelect:({id:e,url:t})=>{n({id:e,url:t})},allowedTypes:["video"]}))};return t})())); \ No newline at end of file diff --git a/src/components/TermsSelect/README.md b/src/components/TermsSelect/README.md index 261cb5e..12da133 100644 --- a/src/components/TermsSelect/README.md +++ b/src/components/TermsSelect/README.md @@ -35,3 +35,11 @@ Remember to define `termIds` in `block.json` file as attribute: }, } ``` + +### `settingsLabel` + +Component label. + +- Type: `string` +- Required: No +- Default: `Choose categories` diff --git a/src/components/TermsSelect/index.js b/src/components/TermsSelect/index.js index 156da37..29449b9 100644 --- a/src/components/TermsSelect/index.js +++ b/src/components/TermsSelect/index.js @@ -5,6 +5,8 @@ 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. * @@ -31,6 +33,7 @@ function TermsSelect( props ) { }, 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/ @@ -60,7 +63,7 @@ function TermsSelect( props ) { return ( { @@ -73,7 +76,7 @@ function TermsSelect( props ) { __experimentalShowHowTo={ false } help={ __( 'You can select one or more terms. Selecting multiple terms will expand the lifts (OR logic).', - 'block-components' + 'meom-block-components' ) } /> );