From 3bbb90afee286764938f7550166591bd78e18325 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20Ka=CC=88gy?= Date: Fri, 9 Dec 2022 13:54:12 +0100 Subject: [PATCH 001/112] add new property to image component to show placeholder without upload controls --- components/image/index.js | 11 +++++++++-- components/image/readme.md | 2 +- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/components/image/index.js b/components/image/index.js index dcd64c08..6208df4e 100644 --- a/components/image/index.js +++ b/components/image/index.js @@ -1,5 +1,5 @@ import { MediaPlaceholder, InspectorControls } from '@wordpress/block-editor'; -import { Spinner, FocalPointPicker, PanelBody } from '@wordpress/components'; +import { Spinner, FocalPointPicker, PanelBody, Placeholder } from '@wordpress/components'; import { __ } from '@wordpress/i18n'; import PropTypes from 'prop-types'; @@ -12,6 +12,7 @@ const Image = (props) => { onSelect, focalPoint = undefined, onChangeFocalPoint, + canEditImage = true, ...rest } = props; const hasImage = !!id; @@ -24,7 +25,11 @@ const Image = (props) => { console.warn('onChangeFocalPoint is required when focalPoint is set'); } - if (!hasImage) { + if (!hasImage && !canEditImage) { + return ; + } + + if (!hasImage && canEditImage) { return ; } @@ -72,6 +77,7 @@ Image.defaultProps = { size: 'large', focalPoint: undefined, onChangeFocalPoint: undefined, + canEditImage: true, }; Image.propTypes = { @@ -83,4 +89,5 @@ Image.propTypes = { x: PropTypes.string, y: PropTypes.string, }), + canEditImage: PropTypes.bool, }; diff --git a/components/image/readme.md b/components/image/readme.md index bf01465a..0c5a693a 100644 --- a/components/image/readme.md +++ b/components/image/readme.md @@ -37,7 +37,6 @@ function BlockEdit(props) { > **Note** > In order to get the same result as the GIF you also need to use the [`MediaToolbar`](https://github.com/10up/block-components/tree/develop/components/media-toolbar) component. It adds the Replace flow to the Blocks Toolbar. - ## Props | Name | Type | Default | Description | @@ -48,3 +47,4 @@ function BlockEdit(props) { | `focalPoint` | `object` | `undefined` | optional focal point object | | `onChangeFocalPoint` | `function` | `undefined` | Callback that gets called with the new focal point when it changes | | `...rest` | `*` | `null` | any additional attributes you want to pass to the underlying `img` tag | +| `canEditImage` | `boolean` | `true` | whether or not the image can be edited by in the context its getting viewed. Controls whether a placeholder or upload controls should be shown when no image is present | From 352c7d70e5944b6ab5a232002961871d033e1700 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20Ka=CC=88gy?= Date: Fri, 9 Dec 2022 13:55:04 +0100 Subject: [PATCH 002/112] add use post hook to get correct post within query loop --- hooks/index.js | 1 + hooks/use-post/index.js | 18 ++++++++++++++++++ 2 files changed, 19 insertions(+) create mode 100644 hooks/use-post/index.js diff --git a/hooks/index.js b/hooks/index.js index 15f37a2e..07f787c3 100644 --- a/hooks/index.js +++ b/hooks/index.js @@ -4,3 +4,4 @@ export { useIcons, useIcon } from './use-icons'; export { useFilteredList } from './use-filtered-list'; export { useMedia } from './use-media'; export { useBlockParentAttributes } from './use-block-parent-attributes'; +export { usePost } from './use-post'; diff --git a/hooks/use-post/index.js b/hooks/use-post/index.js new file mode 100644 index 00000000..9ec6d397 --- /dev/null +++ b/hooks/use-post/index.js @@ -0,0 +1,18 @@ +import { useSelect } from '@wordpress/data'; +import { store as editorStore } from '@wordpress/editor'; + +export function usePost(blockContext = {}) { + const { globalPostId, globalPostType } = useSelect( + (select) => ({ + globalPostId: select(editorStore).getCurrentPostId(), + globalPostType: select(editorStore).getCurrentPostType(), + }), + [], + ); + + return { + postId: blockContext?.postId || globalPostId, + postType: blockContext?.postType || globalPostType, + isDescendentOfQueryLoop: !!Number.isFinite(blockContext?.queryId), + }; +} From 31044e95497204b167e23a4b7db72b7c10f7eaff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20Ka=CC=88gy?= Date: Fri, 9 Dec 2022 13:55:59 +0100 Subject: [PATCH 003/112] add useCanEditEntity hook --- hooks/index.js | 1 + hooks/use-can-edit-entity/index.js | 17 +++++++++++++++++ 2 files changed, 18 insertions(+) create mode 100644 hooks/use-can-edit-entity/index.js diff --git a/hooks/index.js b/hooks/index.js index 07f787c3..f3f8b98b 100644 --- a/hooks/index.js +++ b/hooks/index.js @@ -5,3 +5,4 @@ export { useFilteredList } from './use-filtered-list'; export { useMedia } from './use-media'; export { useBlockParentAttributes } from './use-block-parent-attributes'; export { usePost } from './use-post'; +export { useCanEditEntity } from './use-can-edit-entity'; diff --git a/hooks/use-can-edit-entity/index.js b/hooks/use-can-edit-entity/index.js new file mode 100644 index 00000000..e917ceed --- /dev/null +++ b/hooks/use-can-edit-entity/index.js @@ -0,0 +1,17 @@ +import { useSelect } from '@wordpress/data'; +import { store as coreStore } from '@wordpress/core-data'; + +/** + * Returns whether the current user can edit the given entity. + * + * @param {string} kind Entity kind. + * @param {string} name Entity name. + * @param {string} recordId Record's id. + */ + +export function useCanEditEntity(kind, name, recordId) { + return useSelect( + (select) => select(coreStore).canUserEditEntityRecord(kind, name, recordId), + [kind, name, recordId], + ); +} From 2bf1a97c4625cee684a1f586eefb2b8d8119ef3e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20Ka=CC=88gy?= Date: Fri, 9 Dec 2022 13:57:12 +0100 Subject: [PATCH 004/112] add useIsSupportedTaxonomy hook --- hooks/index.js | 1 + hooks/use-is-supported-taxonomy/index.js | 20 ++++++++++++++++++++ 2 files changed, 21 insertions(+) create mode 100644 hooks/use-is-supported-taxonomy/index.js diff --git a/hooks/index.js b/hooks/index.js index f3f8b98b..afcc6fdb 100644 --- a/hooks/index.js +++ b/hooks/index.js @@ -6,3 +6,4 @@ export { useMedia } from './use-media'; export { useBlockParentAttributes } from './use-block-parent-attributes'; export { usePost } from './use-post'; export { useCanEditEntity } from './use-can-edit-entity'; +export { useIsSupportedTaxonomy } from './use-is-supported-taxonomy'; diff --git a/hooks/use-is-supported-taxonomy/index.js b/hooks/use-is-supported-taxonomy/index.js new file mode 100644 index 00000000..c954909d --- /dev/null +++ b/hooks/use-is-supported-taxonomy/index.js @@ -0,0 +1,20 @@ +import { useSelect } from '@wordpress/data'; +import { store as coreStore } from '@wordpress/core-data'; + +export const useIsSupportedTaxonomy = (postType, taxonomyName) => { + return useSelect( + (select) => { + const postTypeObject = select(coreStore).getPostType(postType); + const hasResolvedPostType = select(coreStore).hasFinishedResolution('getPostType', [ + postType, + ]); + + const isSupportedTaxonomy = postTypeObject?.taxonomies?.some( + (name) => name === taxonomyName, + ); + + return [!!isSupportedTaxonomy, hasResolvedPostType]; + }, + [postType, taxonomyName], + ); +}; From 941a4d917af2b5b328c102ef22d20a402ec59b02 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20Ka=CC=88gy?= Date: Fri, 9 Dec 2022 13:57:46 +0100 Subject: [PATCH 005/112] add hooks to get selected terms --- hooks/index.js | 4 ++ hooks/use-all-terms/index.js | 25 +++++++++++ hooks/use-selected-term-ids/index.js | 19 ++++++++ .../use-selected-terms-of-saved-post/index.js | 24 ++++++++++ hooks/use-selected-terms/index.js | 45 +++++++++++++++++++ 5 files changed, 117 insertions(+) create mode 100644 hooks/use-all-terms/index.js create mode 100644 hooks/use-selected-term-ids/index.js create mode 100644 hooks/use-selected-terms-of-saved-post/index.js create mode 100644 hooks/use-selected-terms/index.js diff --git a/hooks/index.js b/hooks/index.js index afcc6fdb..16a032a9 100644 --- a/hooks/index.js +++ b/hooks/index.js @@ -7,3 +7,7 @@ export { useBlockParentAttributes } from './use-block-parent-attributes'; export { usePost } from './use-post'; export { useCanEditEntity } from './use-can-edit-entity'; export { useIsSupportedTaxonomy } from './use-is-supported-taxonomy'; +export { useAllTerms } from './use-all-terms'; +export { useSelectedTermIds } from './use-selected-term-ids'; +export { useSelectedTerms } from './use-selected-terms'; +export { useSelectedTermsOfSavedPost } from './use-selected-terms-of-saved-post'; diff --git a/hooks/use-all-terms/index.js b/hooks/use-all-terms/index.js new file mode 100644 index 00000000..5b4ac5bf --- /dev/null +++ b/hooks/use-all-terms/index.js @@ -0,0 +1,25 @@ +import { useSelect } from '@wordpress/data'; +import { store as coreStore } from '@wordpress/core-data'; + +export const useAllTerms = (taxonomyName) => { + return useSelect( + (select) => { + const { getEntityRecords, hasFinishedResolution } = select(coreStore); + + const termsSelector = [ + 'taxonomy', + taxonomyName, + { + per_page: -1, + }, + ]; + + const terms = getEntityRecords(...termsSelector); + + const hasResolvedTerms = hasFinishedResolution('getEntityRecords', termsSelector); + + return [terms, hasResolvedTerms]; + }, + [taxonomyName], + ); +}; diff --git a/hooks/use-selected-term-ids/index.js b/hooks/use-selected-term-ids/index.js new file mode 100644 index 00000000..5fdc048d --- /dev/null +++ b/hooks/use-selected-term-ids/index.js @@ -0,0 +1,19 @@ +import { store as editorStore } from '@wordpress/editor'; +import { useSelect } from '@wordpress/data'; +import { store as coreStore } from '@wordpress/core-data'; + +export const useSelectedTermIds = (taxonomyName) => { + return useSelect( + (select) => { + const { getTaxonomy, hasFinishedResolution } = select(coreStore); + const taxonomyObject = getTaxonomy(taxonomyName); + const hasResolvedTaxonomyObject = hasFinishedResolution('getTaxonomy', [taxonomyName]); + const { getEditedPostAttribute } = select(editorStore); + + const selectedTermIds = getEditedPostAttribute(taxonomyObject?.rest_base); + + return [selectedTermIds, hasResolvedTaxonomyObject]; + }, + [taxonomyName], + ); +}; diff --git a/hooks/use-selected-terms-of-saved-post/index.js b/hooks/use-selected-terms-of-saved-post/index.js new file mode 100644 index 00000000..c271c022 --- /dev/null +++ b/hooks/use-selected-terms-of-saved-post/index.js @@ -0,0 +1,24 @@ +import { useSelect } from '@wordpress/data'; + +export const useSelectedTermsOfSavedPost = (taxonomyName, postId) => { + return useSelect( + (select) => { + const { getEntityRecords, hasFinishedResolution } = select('core'); + + const selectedTermsQuery = [ + 'taxonomy', + taxonomyName, + { + per_page: -1, + post: postId, + }, + ]; + + return [ + getEntityRecords(...selectedTermsQuery), + hasFinishedResolution('getEntityRecords', selectedTermsQuery), + ]; + }, + [taxonomyName, postId], + ); +}; diff --git a/hooks/use-selected-terms/index.js b/hooks/use-selected-terms/index.js new file mode 100644 index 00000000..24cb9354 --- /dev/null +++ b/hooks/use-selected-terms/index.js @@ -0,0 +1,45 @@ +import { usePost } from '../use-post'; +import { useIsSupportedTaxonomy } from '../use-is-supported-taxonomy'; +import { useAllTerms } from '../use-all-terms'; +import { useSelectedTermIds } from '../use-selected-term-ids'; +import { useSelectedTermsOfSavedPost } from '../use-selected-terms-of-saved-post'; + +export const useSelectedTerms = (taxonomyName, context = {}) => { + const { postId, postType, isDescendentOfQueryLoop } = usePost(context); + const [isSupportedTaxonomy, hasResolvedIsSupportedTaxonomy] = useIsSupportedTaxonomy( + postType, + taxonomyName, + ); + const [selectedTermIds, hasResolvedSelectedTermIds] = useSelectedTermIds(taxonomyName); + const [terms, hasResolvedTerms] = useAllTerms(taxonomyName); + const [selectedTermsOfSavedPost, hasResolvedSelectedTermsOfSavedPost] = + useSelectedTermsOfSavedPost(taxonomyName, postId); + + if (!hasResolvedIsSupportedTaxonomy) { + return [[], false]; + } + + if (!isSupportedTaxonomy && hasResolvedIsSupportedTaxonomy) { + // eslint-disable-next-line no-console + console.error( + `The taxonomy "${taxonomyName}" is not supported for the post type "${postType}". Please use a supported taxonomy.`, + ); + return [[], true]; + } + + if ( + (isDescendentOfQueryLoop && !hasResolvedSelectedTermsOfSavedPost) || + (!isDescendentOfQueryLoop && (!hasResolvedTerms || !hasResolvedSelectedTermIds)) + ) { + return [[], false]; + } + + if (isDescendentOfQueryLoop && hasResolvedSelectedTermsOfSavedPost) { + return [selectedTermsOfSavedPost, hasResolvedSelectedTermsOfSavedPost]; + } + + return [ + terms.filter((term) => selectedTermIds?.includes(term.id)), + hasResolvedTerms && hasResolvedSelectedTermIds, + ]; +}; From abab9d3606d07387c85c108439e40b48d500a02d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20Ka=CC=88gy?= Date: Fri, 9 Dec 2022 13:58:27 +0100 Subject: [PATCH 006/112] add useIsPluginActive hook to check whether a plugin is active --- hooks/index.js | 1 + hooks/use-is-plugin-active/index.js | 14 ++++++++++++++ 2 files changed, 15 insertions(+) create mode 100644 hooks/use-is-plugin-active/index.js diff --git a/hooks/index.js b/hooks/index.js index 16a032a9..8715d6e1 100644 --- a/hooks/index.js +++ b/hooks/index.js @@ -11,3 +11,4 @@ export { useAllTerms } from './use-all-terms'; export { useSelectedTermIds } from './use-selected-term-ids'; export { useSelectedTerms } from './use-selected-terms'; export { useSelectedTermsOfSavedPost } from './use-selected-terms-of-saved-post'; +export { useIsPluginActive } from './use-is-plugin-active'; diff --git a/hooks/use-is-plugin-active/index.js b/hooks/use-is-plugin-active/index.js new file mode 100644 index 00000000..d4ec55f9 --- /dev/null +++ b/hooks/use-is-plugin-active/index.js @@ -0,0 +1,14 @@ +import { useSelect } from '@wordpress/data'; +import { store as coreStore } from '@wordpress/core-data'; + +export const useIsPluginActive = (pluginName) => { + return useSelect( + (select) => { + const plugins = select(coreStore).getPlugins(); + const hasResolvedPlugins = select(coreStore).hasFinishedResolution('getPlugins'); + const plugin = plugins?.find((plugin) => plugin.plugin === pluginName); + return [plugin?.status === 'active' ?? false, hasResolvedPlugins]; + }, + [pluginName], + ); +}; From 28e63031407e95f2ba3c22f23a26badbc4dd2ddc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20Ka=CC=88gy?= Date: Fri, 9 Dec 2022 13:59:00 +0100 Subject: [PATCH 007/112] add usePrimaryTerm hook which works with Yoast SEO Primary Term Feature --- hooks/index.js | 1 + hooks/use-primary-term/index.js | 65 +++++++++++++++++++++++++++++++++ 2 files changed, 66 insertions(+) create mode 100644 hooks/use-primary-term/index.js diff --git a/hooks/index.js b/hooks/index.js index 8715d6e1..c749490d 100644 --- a/hooks/index.js +++ b/hooks/index.js @@ -12,3 +12,4 @@ export { useSelectedTermIds } from './use-selected-term-ids'; export { useSelectedTerms } from './use-selected-terms'; export { useSelectedTermsOfSavedPost } from './use-selected-terms-of-saved-post'; export { useIsPluginActive } from './use-is-plugin-active'; +export { usePrimaryTerm } from './use-primary-term'; diff --git a/hooks/use-primary-term/index.js b/hooks/use-primary-term/index.js new file mode 100644 index 00000000..5c0a6043 --- /dev/null +++ b/hooks/use-primary-term/index.js @@ -0,0 +1,65 @@ +import { useSelect } from '@wordpress/data'; +import { __ } from '@wordpress/i18n'; +import { usePost } from '../use-post'; +import { useIsPluginActive } from '../use-is-plugin-active'; +import { useIsSupportedTaxonomy } from '../use-is-supported-taxonomy'; + +export const usePrimaryTerm = (taxonomyName, context = {}) => { + const { postType, isDescendentOfQueryLoop } = usePost(context); + + const [isYoastSeoActive, hasResolvedIsPluginActive] = useIsPluginActive('wordpress-seo/wp-seo'); + const [isSupportedTaxonomy, hasResolvedIsSupportedTaxonomy] = useIsSupportedTaxonomy( + postType, + taxonomyName, + ); + + const primaryTermId = useSelect( + (select) => { + if (!hasResolvedIsSupportedTaxonomy || !hasResolvedIsPluginActive) { + return null; + } + + if (!isYoastSeoActive && hasResolvedIsPluginActive) { + // eslint-disable-next-line no-console + console.error( + 'Yoast SEO is not active. Please install and activate Yoast SEO to use the PostPrimaryCategory component.', + ); + return null; + } + + if (!isSupportedTaxonomy && hasResolvedIsSupportedTaxonomy) { + // eslint-disable-next-line no-console + console.error( + `The taxonomy "${taxonomyName}" is not supported for the post type "${postType}". Please use a supported taxonomy.`, + ); + return null; + } + + return select('yoast-seo/editor').getPrimaryTaxonomyId(taxonomyName); + }, + [ + taxonomyName, + isYoastSeoActive, + isSupportedTaxonomy, + hasResolvedIsSupportedTaxonomy, + hasResolvedIsPluginActive, + ], + ); + + const primaryTerm = useSelect( + (select) => { + if (!primaryTermId) { + return null; + } + + const { getEntityRecord } = select('core'); + return getEntityRecord('taxonomy', taxonomyName, primaryTermId); + }, + [primaryTermId], + ); + + return [ + isDescendentOfQueryLoop ? { name: __('Primary Term', 'tenup') } : primaryTerm, + isSupportedTaxonomy, + ]; +}; From 72d8defd88dd2bb9cb26ec1af7cda708c8bb7e26 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20Ka=CC=88gy?= Date: Fri, 9 Dec 2022 13:59:32 +0100 Subject: [PATCH 008/112] add usePropover hook to easily add popovers to elements --- hooks/index.js | 1 + hooks/use-popover/index.js | 33 +++++++++++++++++++++++++++++++++ 2 files changed, 34 insertions(+) create mode 100644 hooks/use-popover/index.js diff --git a/hooks/index.js b/hooks/index.js index c749490d..7256e4b2 100644 --- a/hooks/index.js +++ b/hooks/index.js @@ -13,3 +13,4 @@ export { useSelectedTerms } from './use-selected-terms'; export { useSelectedTermsOfSavedPost } from './use-selected-terms-of-saved-post'; export { useIsPluginActive } from './use-is-plugin-active'; export { usePrimaryTerm } from './use-primary-term'; +export { usePopover } from './use-popover'; diff --git a/hooks/use-popover/index.js b/hooks/use-popover/index.js new file mode 100644 index 00000000..a8007d47 --- /dev/null +++ b/hooks/use-popover/index.js @@ -0,0 +1,33 @@ +import { Popover } from '@wordpress/components'; +import { useState } from '@wordpress/element'; +import { useOnClickOutside } from '../use-on-click-outside'; + +export const usePopover = () => { + // Use internal state instead of a ref to make sure that the component + // re-renders when the popover's anchor updates. + const [popoverAnchor, setPopoverAnchor] = useState(); + const [isVisible, setIsVisible] = useState(false); + const toggleVisible = () => { + setIsVisible(!isVisible); + }; + + const toggleProps = { + onClick: toggleVisible, + 'aria-expanded': isVisible, + ref: setPopoverAnchor, + }; + + const ref = useOnClickOutside(() => setIsVisible(false)); + + return { + setPopoverAnchor, + toggleVisible, + toggleProps, + Popover: ({ children }) => + isVisible ? ( + +
{children}
+
+ ) : null, + }; +}; From 87742f3a144b161ef6e39406e3c2b7313a67e8e4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20Ka=CC=88gy?= Date: Fri, 9 Dec 2022 14:00:10 +0100 Subject: [PATCH 009/112] add PostTitle component --- components/index.js | 1 + components/post-title/index.js | 49 ++++++++++++++++++++++++++++++++++ 2 files changed, 50 insertions(+) create mode 100644 components/post-title/index.js diff --git a/components/index.js b/components/index.js index efb26ca9..e0775962 100644 --- a/components/index.js +++ b/components/index.js @@ -18,3 +18,4 @@ export { CircularProgressBar, Counter, } from './rich-text-character-limit'; +export { PostTitle } from './post-title'; diff --git a/components/post-title/index.js b/components/post-title/index.js new file mode 100644 index 00000000..f0716715 --- /dev/null +++ b/components/post-title/index.js @@ -0,0 +1,49 @@ +import { useEntityProp } from '@wordpress/core-data'; +import { RichText, store as blockEditorStore } from '@wordpress/block-editor'; +import { useSelect } from '@wordpress/data'; +import PropTypes from 'prop-types'; +import { usePost, useCanEditEntity } from '../../hooks'; + +export const PostTitle = (props) => { + const { context, tagName: TagName = 'h1', ...rest } = props; + const { postId, postType, isDescendentOfQueryLoop } = usePost(context); + + const userCanEditTitle = useCanEditEntity('postType', postType, postId); + const [rawTitle = '', setTitle, fullTitle] = useEntityProp( + 'postType', + postType, + 'title', + postId, + ); + + const titlePlaceholder = useSelect( + (select) => select(blockEditorStore).getSettings().titlePlaceholder, + [], + ); + + if (!userCanEditTitle || isDescendentOfQueryLoop) { + // eslint-disable-next-line react/no-danger + return ; + } + + return ( + + ); +}; + +PostTitle.propTypes = { + context: PropTypes.object, + tagName: PropTypes.string, +}; + +PostTitle.defaultProps = { + context: {}, + tagName: 'h1', +}; From 67c2ea142a2cea4a3b2ba89c65b9efda76a5f13a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20Ka=CC=88gy?= Date: Fri, 9 Dec 2022 14:00:28 +0100 Subject: [PATCH 010/112] add PostFeaturedImage component --- components/index.js | 1 + components/post-featured-image/index.js | 36 +++++++++++++++++++++++++ 2 files changed, 37 insertions(+) create mode 100644 components/post-featured-image/index.js diff --git a/components/index.js b/components/index.js index e0775962..b29de976 100644 --- a/components/index.js +++ b/components/index.js @@ -19,3 +19,4 @@ export { Counter, } from './rich-text-character-limit'; export { PostTitle } from './post-title'; +export { PostFeaturedImage } from './post-featured-image'; diff --git a/components/post-featured-image/index.js b/components/post-featured-image/index.js new file mode 100644 index 00000000..09f1d2a8 --- /dev/null +++ b/components/post-featured-image/index.js @@ -0,0 +1,36 @@ +import { useEntityProp } from '@wordpress/core-data'; +import PropTypes from 'prop-types'; +import { usePost } from '../../hooks'; +import { Image } from '../image'; + +export const PostFeaturedImage = (props) => { + const { context, ...rest } = props; + const { postId, postType, isDescendentOfQueryLoop } = usePost(context); + const [featuredImage, setFeaturedImage] = useEntityProp( + 'postType', + postType, + 'featured_media', + postId, + ); + + const handleImageSelect = (image) => { + setFeaturedImage(image.id); + }; + + return ( + + ); +}; + +PostFeaturedImage.propTypes = { + context: PropTypes.object, +}; + +PostFeaturedImage.defaultProps = { + context: {}, +}; From 8e133ecec736ac07213d8986f43193c7a9bcd763 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20Ka=CC=88gy?= Date: Fri, 9 Dec 2022 14:01:03 +0100 Subject: [PATCH 011/112] add PostExcerpt component --- components/index.js | 1 + components/post-excerpt/index.js | 44 ++++++++++++++++++++++++++++++++ 2 files changed, 45 insertions(+) create mode 100644 components/post-excerpt/index.js diff --git a/components/index.js b/components/index.js index b29de976..ce6d51a8 100644 --- a/components/index.js +++ b/components/index.js @@ -20,3 +20,4 @@ export { } from './rich-text-character-limit'; export { PostTitle } from './post-title'; export { PostFeaturedImage } from './post-featured-image'; +export { PostExcerpt } from './post-excerpt'; diff --git a/components/post-excerpt/index.js b/components/post-excerpt/index.js new file mode 100644 index 00000000..fea9376c --- /dev/null +++ b/components/post-excerpt/index.js @@ -0,0 +1,44 @@ +import { useEntityProp } from '@wordpress/core-data'; +import { __ } from '@wordpress/i18n'; +import { RichText } from '@wordpress/block-editor'; +import PropTypes from 'prop-types'; +import { usePost, useCanEditEntity } from '../../hooks'; + +export const PostExcerpt = (props) => { + const { context, placeholder = __('Enter excerpt...', 'tenup'), ...rest } = props; + const { postId, postType, isDescendentOfQueryLoop } = usePost(context); + + const userCanEditExcerpt = useCanEditEntity('postType', postType, postId); + const [rawExcerpt = '', setExcerpt, fullExcerpt] = useEntityProp( + 'postType', + postType, + 'excerpt', + postId, + ); + + if (!userCanEditExcerpt || isDescendentOfQueryLoop) { + // eslint-disable-next-line react/no-danger + return

; + } + + return ( + + ); +}; + +PostExcerpt.propTypes = { + context: PropTypes.object, + placeholder: PropTypes.string, +}; + +PostExcerpt.defaultProps = { + context: {}, + placeholder: __('Enter excerpt...', 'tenup'), +}; From ab52565bcaffd1a6849002770f7d27d275122f52 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20Ka=CC=88gy?= Date: Fri, 9 Dec 2022 14:01:34 +0100 Subject: [PATCH 012/112] add PostAuthor component --- components/author/context.js | 3 + components/author/index.js | 153 ++++++++++++++++++++++++++++++++ components/index.js | 1 + components/post-author/index.js | 68 ++++++++++++++ 4 files changed, 225 insertions(+) create mode 100644 components/author/context.js create mode 100644 components/author/index.js create mode 100644 components/post-author/index.js diff --git a/components/author/context.js b/components/author/context.js new file mode 100644 index 00000000..1fb47589 --- /dev/null +++ b/components/author/context.js @@ -0,0 +1,3 @@ +import { createContext } from '@wordpress/element'; + +export const AUTHOR_CONTEXT = createContext(); diff --git a/components/author/index.js b/components/author/index.js new file mode 100644 index 00000000..a9615a64 --- /dev/null +++ b/components/author/index.js @@ -0,0 +1,153 @@ +/* eslint-disable react-hooks/rules-of-hooks */ +import { useContext } from '@wordpress/element'; +import { useSelect } from '@wordpress/data'; +import { store as blockEditorStore } from '@wordpress/block-editor'; +import PropTypes from 'prop-types'; +import { AUTHOR_CONTEXT } from './context'; + +/** + * @typedef {object} Author + * @property {object} author + * @property {object} author.avatar_urls + * @property {string} author.description + * @property {string} author.email + * @property {string} author.first_name + * @property {number} author.id + * @property {string} author.last_name + * @property {string} author.link + * @property {string} author.name + * @property {string} author.nickname + * @property {string} author.registered_date + * @property {string} author.slug + * @property {string} author.url + */ + +export const Name = (props) => { + const { as: Component = 'span', ...rest } = props; + + /** + * @type {Author} + */ + const { name, link } = useContext(AUTHOR_CONTEXT); + + const wrapperProps = { ...rest }; + + if (Component === 'a' && link) { + wrapperProps.href = link; + } + + return {name}; +}; + +Name.propTypes = { + as: PropTypes.string, +}; + +Name.defaultProps = { + as: 'span', +}; + +export const FirstName = (props) => { + const { as: Component = 'span', ...rest } = props; + + /** + * @type {Author} + */ + const { first_name: firstName } = useContext(AUTHOR_CONTEXT); + + return {firstName}; +}; + +FirstName.propTypes = { + as: PropTypes.string, +}; + +FirstName.defaultProps = { + as: 'span', +}; + +export const LastName = (props) => { + const { as: Component = 'span', ...rest } = props; + + /** + * @type {Author} + */ + const { last_name: lastName } = useContext(AUTHOR_CONTEXT); + + return {lastName}; +}; + +LastName.propTypes = { + as: PropTypes.string, +}; + +LastName.defaultProps = { + as: 'span', +}; + +function useDefaultAvatar() { + const { avatarURL: defaultAvatarUrl } = useSelect((select) => { + const { getSettings } = select(blockEditorStore); + const { __experimentalDiscussionSettings } = getSettings(); + return __experimentalDiscussionSettings; + }); + return defaultAvatarUrl; +} + +export const Avatar = (props) => { + const { as: Component = 'img', ...rest } = props; + + /** + * @type {Author} + */ + const authorDetails = useContext(AUTHOR_CONTEXT); + + const avatarUrls = authorDetails?.avatar_urls ? Object.values(authorDetails.avatar_urls) : null; + const defaultAvatar = useDefaultAvatar(); + + const avatarSourceUrl = avatarUrls ? avatarUrls[avatarUrls.length - 1] : defaultAvatar; + + return ; +}; + +Avatar.propTypes = { + as: PropTypes.string, +}; + +Avatar.defaultProps = { + as: 'img', +}; + +export const Bio = (props) => { + const { as: Component = 'p', ...rest } = props; + + /** + * @type {Author} + */ + const { description } = useContext(AUTHOR_CONTEXT); + + return {description}; +}; + +Bio.propTypes = { + as: PropTypes.string, +}; + +Bio.defaultProps = { + as: 'p', +}; + +export const Email = (props) => { + const { ...rest } = props; + + /** + * @type {Author} + */ + const { email } = useContext(AUTHOR_CONTEXT); + + return ( + + {email} + + ); +}; diff --git a/components/index.js b/components/index.js index ce6d51a8..03a35f1e 100644 --- a/components/index.js +++ b/components/index.js @@ -21,3 +21,4 @@ export { export { PostTitle } from './post-title'; export { PostFeaturedImage } from './post-featured-image'; export { PostExcerpt } from './post-excerpt'; +export { PostAuthor } from './post-author'; diff --git a/components/post-author/index.js b/components/post-author/index.js new file mode 100644 index 00000000..7bb76b6d --- /dev/null +++ b/components/post-author/index.js @@ -0,0 +1,68 @@ +import { Children } from '@wordpress/element'; +import { store as coreStore } from '@wordpress/core-data'; +import { Spinner } from '@wordpress/components'; +import { useSelect } from '@wordpress/data'; +import PropTypes from 'prop-types'; +import { usePost } from '../../hooks'; +import { Name, FirstName, LastName, Avatar, Bio, Email } from '../author'; + +import { AUTHOR_CONTEXT } from '../author/context'; + +export const PostAuthor = (props) => { + const { context, children, ...rest } = props; + const { postId, postType } = usePost(context); + + const [author, hasResolved] = useSelect( + (select) => { + const { getEditedEntityRecord, getUser, hasFinishedResolution } = select(coreStore); + + const postQuery = ['postType', postType, postId]; + + const post = getEditedEntityRecord(...postQuery); + const hasResolvedPost = hasFinishedResolution('getEditedEntityRecord', postQuery); + + const _authorId = hasResolvedPost ? post?.author : undefined; + + const author = getUser(_authorId); + const hasResolvedAuthor = hasFinishedResolution('getUser', [_authorId]); + + return [author, hasResolvedAuthor && hasResolvedPost]; + }, + [postType, postId], + ); + + const hasRenderCallback = typeof children === 'function'; + + const hasChildComponents = !hasRenderCallback && Children.count(children); + + if (!hasResolved) { + return ; + } + + if (hasChildComponents) { + return {children}; + } + + if (hasRenderCallback) { + return children(author); + } + + return ; +}; + +PostAuthor.propTypes = { + context: PropTypes.object, + children: PropTypes.oneOfType([PropTypes.func, PropTypes.node]), +}; + +PostAuthor.defaultProps = { + context: {}, + children: null, +}; + +PostAuthor.Name = Name; +PostAuthor.FirstName = FirstName; +PostAuthor.LastName = LastName; +PostAuthor.Avatar = Avatar; +PostAuthor.Bio = Bio; +PostAuthor.Email = Email; From c4a0227c4616f70796b3f1d9541765bd39a40fe5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20Ka=CC=88gy?= Date: Fri, 9 Dec 2022 14:01:56 +0100 Subject: [PATCH 013/112] add PostDate and PostDatePicker components --- components/index.js | 1 + components/post-date/index.js | 82 +++++++++++++++++++++++++++++++++++ 2 files changed, 83 insertions(+) create mode 100644 components/post-date/index.js diff --git a/components/index.js b/components/index.js index 03a35f1e..def5d7db 100644 --- a/components/index.js +++ b/components/index.js @@ -22,3 +22,4 @@ export { PostTitle } from './post-title'; export { PostFeaturedImage } from './post-featured-image'; export { PostExcerpt } from './post-excerpt'; export { PostAuthor } from './post-author'; +export { PostDate, PostDatePicker } from './post-date'; diff --git a/components/post-date/index.js b/components/post-date/index.js new file mode 100644 index 00000000..70f645ba --- /dev/null +++ b/components/post-date/index.js @@ -0,0 +1,82 @@ +import { __ } from '@wordpress/i18n'; +import { DateTimePicker } from '@wordpress/components'; +import { getSettings, dateI18n } from '@wordpress/date'; +import { useEntityProp } from '@wordpress/core-data'; +import PropTypes from 'prop-types'; +import { usePopover } from '../../hooks/use-popover'; +import { usePost } from '../../hooks'; + +export const PostDatePicker = ({ date, setDate }) => { + const settings = getSettings(); + // To know if the current time format is a 12 hour time, look for "a". + // Also make sure this "a" is not escaped by a "/". + const is12Hour = /a(?!\\)/i.test( + settings.formats.time + .toLowerCase() // Test only for the lower case "a". + .replace(/\\\\/g, '') // Replace "//" with empty strings. + .split('') + .reverse() + .join(''), // Reverse the string and test for "a" not followed by a slash. + ); + + return ; +}; + +PostDatePicker.propTypes = { + date: PropTypes.string.isRequired, + setDate: PropTypes.func.isRequired, +}; + +export const PostDate = (props) => { + const { context, placeholder = __('No date set', 'tenup'), ...rest } = props; + + const { postId, postType, isDescendentOfQueryLoop } = usePost(context); + + const [date, setDate] = useEntityProp('postType', postType, 'date', postId); + const [siteFormat] = useEntityProp('root', 'site', 'date_format'); + const settings = getSettings(); + const timezone = Intl.DateTimeFormat().resolvedOptions().timeZone; + + const resolvedFormat = siteFormat || settings.formats.date; + + const { toggleProps, Popover } = usePopover(); + + const timeString = dateI18n(resolvedFormat, date, timezone) || placeholder; + + let parentProps = { ...rest }; + + if (!isDescendentOfQueryLoop) { + parentProps = { + ...toggleProps, + ...parentProps, + }; + } + + return ( + <> + + {!isDescendentOfQueryLoop && ( + + + + )} + + ); +}; + +PostDate.propTypes = { + context: PropTypes.object, + placeholder: PropTypes.string, +}; + +PostDate.defaultProps = { + context: {}, + placeholder: __('No date set', 'tenup'), +}; From c64112e823a56c9df2e8e425abeae7476c89e187 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20Ka=CC=88gy?= Date: Fri, 9 Dec 2022 14:02:10 +0100 Subject: [PATCH 014/112] add PostCategories component --- components/index.js | 1 + components/post-categories/index.js | 43 +++++++++++++++++++++++++++++ 2 files changed, 44 insertions(+) create mode 100644 components/post-categories/index.js diff --git a/components/index.js b/components/index.js index def5d7db..a4260926 100644 --- a/components/index.js +++ b/components/index.js @@ -23,3 +23,4 @@ export { PostFeaturedImage } from './post-featured-image'; export { PostExcerpt } from './post-excerpt'; export { PostAuthor } from './post-author'; export { PostDate, PostDatePicker } from './post-date'; +export { PostCategories } from './post-categories'; diff --git a/components/post-categories/index.js b/components/post-categories/index.js new file mode 100644 index 00000000..3dc5f355 --- /dev/null +++ b/components/post-categories/index.js @@ -0,0 +1,43 @@ +import { Spinner } from '@wordpress/components'; +import PropTypes from 'prop-types'; + +import { usePost, useSelectedTerms } from '../../hooks'; + +export const PostCategories = (props) => { + const { context, children, ...rest } = props; + + const { isDescendentOfQueryLoop } = usePost(context); + + const hasRenderCallback = typeof children === 'function'; + + const [selectedCategories, hasResolvedSelectedCategories] = useSelectedTerms( + 'category', + context, + ); + + if (!hasResolvedSelectedCategories) { + return ; + } + + if (hasRenderCallback) { + return selectedCategories.map((category) => + children({ ...category, isDescendentOfQueryLoop }), + ); + } + + return selectedCategories.map((category) => ( +

  • + {category.name} +
  • + )); +}; + +PostCategories.propTypes = { + context: PropTypes.object, + children: PropTypes.func, +}; + +PostCategories.defaultProps = { + context: {}, + children: null, +}; From a99e3131c24ea057c147fb0bc83a002a06348362 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20Ka=CC=88gy?= Date: Fri, 9 Dec 2022 14:02:33 +0100 Subject: [PATCH 015/112] add PostPrimaryCategory component which interacts with Yoast SEO primary term --- components/index.js | 1 + components/post-primary-category/index.js | 47 +++++++++++++++++++++++ 2 files changed, 48 insertions(+) create mode 100644 components/post-primary-category/index.js diff --git a/components/index.js b/components/index.js index a4260926..9883ff91 100644 --- a/components/index.js +++ b/components/index.js @@ -24,3 +24,4 @@ export { PostExcerpt } from './post-excerpt'; export { PostAuthor } from './post-author'; export { PostDate, PostDatePicker } from './post-date'; export { PostCategories } from './post-categories'; +export { PostPrimaryCategory } from './post-primary-category'; diff --git a/components/post-primary-category/index.js b/components/post-primary-category/index.js new file mode 100644 index 00000000..b490d7bc --- /dev/null +++ b/components/post-primary-category/index.js @@ -0,0 +1,47 @@ +import { __ } from '@wordpress/i18n'; +import PropTypes from 'prop-types'; +import { usePrimaryTerm } from '../../hooks'; + +export const PostPrimaryCategory = (props) => { + const { + context, + placeholder = __('Select a category', 'tenup'), + isLink = true, + ...rest + } = props; + + const [primaryCategory, isSupportedTaxonomy] = usePrimaryTerm('category', context); + + const hasPrimaryCategory = !!primaryCategory; + + const categoryString = hasPrimaryCategory ? primaryCategory.name : placeholder; + const categoryUrl = hasPrimaryCategory ? primaryCategory.link : '#'; + + if (!isSupportedTaxonomy) { + return null; + } + + const Tag = isLink ? 'a' : 'span'; + + const wrapperProps = { + ...rest, + }; + + if (isLink) { + wrapperProps.href = categoryUrl; + } + + return {categoryString}; +}; + +PostPrimaryCategory.propTypes = { + context: PropTypes.object, + placeholder: PropTypes.string, + isLink: PropTypes.bool, +}; + +PostPrimaryCategory.defaultProps = { + context: {}, + placeholder: __('Select a category', 'tenup'), + isLink: true, +}; From 59ac2eb6a58b2663c6418d93d790cb5b37e2b06d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20Ka=CC=88gy?= Date: Fri, 9 Dec 2022 14:06:50 +0100 Subject: [PATCH 016/112] add PostTerms component --- components/index.js | 1 + components/post-terms/index.js | 39 ++++++++++++++++++++++++++++++++++ 2 files changed, 40 insertions(+) create mode 100644 components/post-terms/index.js diff --git a/components/index.js b/components/index.js index 9883ff91..7ecfd94a 100644 --- a/components/index.js +++ b/components/index.js @@ -23,5 +23,6 @@ export { PostFeaturedImage } from './post-featured-image'; export { PostExcerpt } from './post-excerpt'; export { PostAuthor } from './post-author'; export { PostDate, PostDatePicker } from './post-date'; +export { PostTerms } from './post-terms'; export { PostCategories } from './post-categories'; export { PostPrimaryCategory } from './post-primary-category'; diff --git a/components/post-terms/index.js b/components/post-terms/index.js new file mode 100644 index 00000000..1cc20715 --- /dev/null +++ b/components/post-terms/index.js @@ -0,0 +1,39 @@ +import { Spinner } from '@wordpress/components'; +import PropTypes from 'prop-types'; + +import { usePost, useSelectedTerms } from '../../hooks'; + +export const PostTerms = (props) => { + const { context, taxonomyName = 'category', children, ...rest } = props; + + const { isDescendentOfQueryLoop } = usePost(context); + + const hasRenderCallback = typeof children === 'function'; + + const [selectedTerms, hasResolvedSelectedTerms] = useSelectedTerms(taxonomyName, context); + + if (!hasResolvedSelectedTerms) { + return ; + } + + if (hasRenderCallback) { + return selectedTerms.map((term) => children({ ...term, isDescendentOfQueryLoop })); + } + + return selectedTerms.map((term) => ( +
  • + {term.name} +
  • + )); +}; + +PostTerms.propTypes = { + context: PropTypes.object, + children: PropTypes.func, + taxonomyName: PropTypes.string.isRequired, +}; + +PostTerms.defaultProps = { + context: {}, + children: null, +}; From 9f544d15d4e2ce0be7c5c3c403f63be6de68f415 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20Ka=CC=88gy?= Date: Fri, 9 Dec 2022 14:07:09 +0100 Subject: [PATCH 017/112] refactor PostCategories component to use PostTerms --- components/post-categories/index.js | 28 ++-------------------------- 1 file changed, 2 insertions(+), 26 deletions(-) diff --git a/components/post-categories/index.js b/components/post-categories/index.js index 3dc5f355..0da38607 100644 --- a/components/post-categories/index.js +++ b/components/post-categories/index.js @@ -1,35 +1,11 @@ -import { Spinner } from '@wordpress/components'; import PropTypes from 'prop-types'; -import { usePost, useSelectedTerms } from '../../hooks'; +import { PostTerms } from '../post-terms'; export const PostCategories = (props) => { const { context, children, ...rest } = props; - const { isDescendentOfQueryLoop } = usePost(context); - - const hasRenderCallback = typeof children === 'function'; - - const [selectedCategories, hasResolvedSelectedCategories] = useSelectedTerms( - 'category', - context, - ); - - if (!hasResolvedSelectedCategories) { - return ; - } - - if (hasRenderCallback) { - return selectedCategories.map((category) => - children({ ...category, isDescendentOfQueryLoop }), - ); - } - - return selectedCategories.map((category) => ( -
  • - {category.name} -
  • - )); + return ; }; PostCategories.propTypes = { From 5743a08859b0d3b93badc412135e7d37bf1db0fb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20Ka=CC=88gy?= Date: Fri, 9 Dec 2022 14:11:04 +0100 Subject: [PATCH 018/112] add PostPrimaryTerm component --- components/index.js | 1 + components/post-primary-term/index.js | 49 +++++++++++++++++++++++++++ 2 files changed, 50 insertions(+) create mode 100644 components/post-primary-term/index.js diff --git a/components/index.js b/components/index.js index 7ecfd94a..bf51f3be 100644 --- a/components/index.js +++ b/components/index.js @@ -25,4 +25,5 @@ export { PostAuthor } from './post-author'; export { PostDate, PostDatePicker } from './post-date'; export { PostTerms } from './post-terms'; export { PostCategories } from './post-categories'; +export { PostPrimaryTerm } from './post-primary-term'; export { PostPrimaryCategory } from './post-primary-category'; diff --git a/components/post-primary-term/index.js b/components/post-primary-term/index.js new file mode 100644 index 00000000..42e401bc --- /dev/null +++ b/components/post-primary-term/index.js @@ -0,0 +1,49 @@ +import { __ } from '@wordpress/i18n'; +import PropTypes from 'prop-types'; +import { usePrimaryTerm } from '../../hooks'; + +export const PostPrimaryTerm = (props) => { + const { + context, + taxonomyName = 'category', + placeholder = __('Select a term', 'tenup'), + isLink = true, + ...rest + } = props; + + const [primaryTerm, isSupportedTaxonomy] = usePrimaryTerm(taxonomyName, context); + + const hasPrimaryTerm = !!primaryTerm; + + const termString = hasPrimaryTerm ? primaryTerm.name : placeholder; + const termUrl = hasPrimaryTerm ? primaryTerm.link : '#'; + + if (!isSupportedTaxonomy) { + return null; + } + + const Tag = isLink ? 'a' : 'span'; + + const wrapperProps = { + ...rest, + }; + + if (isLink) { + wrapperProps.href = termUrl; + } + + return {termString}; +}; + +PostPrimaryTerm.propTypes = { + context: PropTypes.object, + placeholder: PropTypes.string, + taxonomyName: PropTypes.string.isRequired, + isLink: PropTypes.bool, +}; + +PostPrimaryTerm.defaultProps = { + context: {}, + placeholder: __('Select a Term', 'tenup'), + isLink: true, +}; From aa20ab6c78eb69dd4af7ae5289417ef34e945bd0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20Ka=CC=88gy?= Date: Fri, 9 Dec 2022 14:11:30 +0100 Subject: [PATCH 019/112] refactor PostPrimaryCategory with PostPrimaryTerm --- components/post-primary-category/index.js | 33 +++++++---------------- 1 file changed, 10 insertions(+), 23 deletions(-) diff --git a/components/post-primary-category/index.js b/components/post-primary-category/index.js index b490d7bc..2fb6adb2 100644 --- a/components/post-primary-category/index.js +++ b/components/post-primary-category/index.js @@ -1,6 +1,6 @@ import { __ } from '@wordpress/i18n'; import PropTypes from 'prop-types'; -import { usePrimaryTerm } from '../../hooks'; +import { PostPrimaryTerm } from '../post-primary-term'; export const PostPrimaryCategory = (props) => { const { @@ -10,28 +10,15 @@ export const PostPrimaryCategory = (props) => { ...rest } = props; - const [primaryCategory, isSupportedTaxonomy] = usePrimaryTerm('category', context); - - const hasPrimaryCategory = !!primaryCategory; - - const categoryString = hasPrimaryCategory ? primaryCategory.name : placeholder; - const categoryUrl = hasPrimaryCategory ? primaryCategory.link : '#'; - - if (!isSupportedTaxonomy) { - return null; - } - - const Tag = isLink ? 'a' : 'span'; - - const wrapperProps = { - ...rest, - }; - - if (isLink) { - wrapperProps.href = categoryUrl; - } - - return {categoryString}; + return ( + + ); }; PostPrimaryCategory.propTypes = { From e778cae7120e62b72985af7edbbbc724419ea6fd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20Ka=CC=88gy?= Date: Fri, 9 Dec 2022 14:11:55 +0100 Subject: [PATCH 020/112] add example block for post title component --- example/src/blocks/post-title/index.js | 31 ++++++++++++++++++++++++++ example/src/index.js | 1 + 2 files changed, 32 insertions(+) create mode 100644 example/src/blocks/post-title/index.js diff --git a/example/src/blocks/post-title/index.js b/example/src/blocks/post-title/index.js new file mode 100644 index 00000000..378df9f3 --- /dev/null +++ b/example/src/blocks/post-title/index.js @@ -0,0 +1,31 @@ +import { registerBlockType } from '@wordpress/blocks'; +import { useBlockProps } from '@wordpress/block-editor'; +import { __ } from '@wordpress/i18n'; + +import { PostTitle } from '@10up/block-components'; + +const NAMESPACE = 'example'; + +registerBlockType( `${ NAMESPACE }/custom-post-title`, { + apiVersion: 2, + title: __( 'Custom Post Title', NAMESPACE ), + icon: 'smiley', + category: 'common', + example: {}, + supports: { + html: false + }, + attributes: {}, + transforms: {}, + variations: [], + usesContext: [ 'postId', 'postType', 'queryId' ], + edit: ({context}) => { + const blockProps = useBlockProps(); + return ( +
    + +
    + ) + }, + save: () => null +} ); diff --git a/example/src/index.js b/example/src/index.js index 971797d1..6f7dda10 100644 --- a/example/src/index.js +++ b/example/src/index.js @@ -5,3 +5,4 @@ import './blocks/repeater-component-example'; import './blocks/link-example'; import './blocks/image-example'; import './blocks/rich-text-character-limit'; +import './blocks/post-title'; From e1b0f9010454a507f53f9cec8517d14d5fe99ba2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20Ka=CC=88gy?= Date: Fri, 9 Dec 2022 14:12:10 +0100 Subject: [PATCH 021/112] add example post for post featured image component --- .../src/blocks/post-featured-image/index.js | 31 +++++++++++++++++++ example/src/index.js | 1 + 2 files changed, 32 insertions(+) create mode 100644 example/src/blocks/post-featured-image/index.js diff --git a/example/src/blocks/post-featured-image/index.js b/example/src/blocks/post-featured-image/index.js new file mode 100644 index 00000000..65c0efe6 --- /dev/null +++ b/example/src/blocks/post-featured-image/index.js @@ -0,0 +1,31 @@ +import { registerBlockType } from '@wordpress/blocks'; +import { useBlockProps } from '@wordpress/block-editor'; +import { __ } from '@wordpress/i18n'; + +import { PostFeaturedImage } from '@10up/block-components'; + +const NAMESPACE = 'example'; + +registerBlockType( `${ NAMESPACE }/custom-post-featured-image`, { + apiVersion: 2, + title: __( 'Custom Post Featured Image', NAMESPACE ), + icon: 'format-image', + category: 'common', + example: {}, + supports: { + html: false + }, + attributes: {}, + transforms: {}, + variations: [], + usesContext: [ 'postId', 'postType', 'queryId' ], + edit: ({context}) => { + const blockProps = useBlockProps(); + return ( +
    + +
    + ) + }, + save: () => null +} ); diff --git a/example/src/index.js b/example/src/index.js index 6f7dda10..97f27596 100644 --- a/example/src/index.js +++ b/example/src/index.js @@ -6,3 +6,4 @@ import './blocks/link-example'; import './blocks/image-example'; import './blocks/rich-text-character-limit'; import './blocks/post-title'; +import './blocks/post-featured-image'; From 56ebd6fd766e508b35b60876dfeb937b2570c50f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20Ka=CC=88gy?= Date: Fri, 9 Dec 2022 14:12:42 +0100 Subject: [PATCH 022/112] add exampel block for a content item / card component using the post components in a query loop --- example/src/blocks/content-item/index.js | 58 ++++++++++++++++++++++++ example/src/index.js | 1 + 2 files changed, 59 insertions(+) create mode 100644 example/src/blocks/content-item/index.js diff --git a/example/src/blocks/content-item/index.js b/example/src/blocks/content-item/index.js new file mode 100644 index 00000000..d7623cfe --- /dev/null +++ b/example/src/blocks/content-item/index.js @@ -0,0 +1,58 @@ +import { registerBlockType } from '@wordpress/blocks'; +import { useBlockProps } from '@wordpress/block-editor'; +import { __ } from '@wordpress/i18n'; + +import { PostFeaturedImage, PostTitle, PostPrimaryCategory, PostDate, PostCategories } from '@10up/block-components'; +import { PostAuthor, PostExcerpt, PostCoAuthors } from '../../../../components'; + +const NAMESPACE = 'example'; + +registerBlockType( `${ NAMESPACE }/content-item`, { + apiVersion: 2, + title: __( 'Content Item', NAMESPACE ), + icon: 'smiley', + category: 'common', + example: {}, + supports: { + html: false + }, + attributes: {}, + transforms: {}, + variations: [], + usesContext: [ 'postId', 'postType', 'queryId' ], + ancestor: [ 'core/post-template' ], + edit: ({context}) => { + const blockProps = useBlockProps(); + return ( +
    +
    + +
    + + +
      + + {({ name, link, id }) => ( +
    • + {name} +
    • + )} +
      +
    + + + +
    + + + + + + +
    +
    +
    + ) + }, + save: () => null +} ); diff --git a/example/src/index.js b/example/src/index.js index 97f27596..15668738 100644 --- a/example/src/index.js +++ b/example/src/index.js @@ -7,3 +7,4 @@ import './blocks/image-example'; import './blocks/rich-text-character-limit'; import './blocks/post-title'; import './blocks/post-featured-image'; +import './blocks/content-item'; From 140c68f16be1451c88ab91719e9e3a3e49ac54fd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20Ka=CC=88gy?= Date: Fri, 9 Dec 2022 14:13:00 +0100 Subject: [PATCH 023/112] add an example hero block using the post level components --- example/src/blocks/hero/index.js | 58 ++++++++++++++++++++++++++++++++ example/src/index.js | 1 + 2 files changed, 59 insertions(+) create mode 100644 example/src/blocks/hero/index.js diff --git a/example/src/blocks/hero/index.js b/example/src/blocks/hero/index.js new file mode 100644 index 00000000..5e155fbc --- /dev/null +++ b/example/src/blocks/hero/index.js @@ -0,0 +1,58 @@ +import { registerBlockType } from '@wordpress/blocks'; +import { useBlockProps } from '@wordpress/block-editor'; +import { __ } from '@wordpress/i18n'; +import { header } from '@wordpress/icons'; + +import { PostFeaturedImage, PostTitle, PostPrimaryCategory, PostDate, PostCategories, PostAuthor } from '@10up/block-components'; +import { PostExcerpt } from '../../../../components'; + +const NAMESPACE = 'example'; + +registerBlockType(`${NAMESPACE}/hero`, { + apiVersion: 2, + title: __('Hero', NAMESPACE), + icon: header, + category: 'common', + example: {}, + supports: { + html: false, + }, + attributes: { + }, + transforms: {}, + variations: [], + parent: ['core/post-content'], + edit: () => { + const blockProps = useBlockProps({ className: 'alignwide' }); + return ( +
    +
    + +
    + + +
      + + {({ name, link, id }) => ( +
    • + {name} +
    • + )} +
      +
    + + + +
    + + + + + +
    +
    +
    + ) + }, + save: () => null +}); diff --git a/example/src/index.js b/example/src/index.js index 15668738..65b6232e 100644 --- a/example/src/index.js +++ b/example/src/index.js @@ -8,3 +8,4 @@ import './blocks/rich-text-character-limit'; import './blocks/post-title'; import './blocks/post-featured-image'; import './blocks/content-item'; +import './blocks/hero'; From 6ff0b637f267bbd7758ff628d1c8a635b826ce78 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20Ka=CC=88gy?= Date: Fri, 9 Dec 2022 14:19:20 +0100 Subject: [PATCH 024/112] install Yoast SEO plugin in the example project --- example/.wp-env.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/example/.wp-env.json b/example/.wp-env.json index 73a2230d..b25ad4bf 100644 --- a/example/.wp-env.json +++ b/example/.wp-env.json @@ -1,5 +1,5 @@ { - "plugins": [ "." ], + "plugins": [ ".", "https://downloads.wordpress.org/plugin/wordpress-seo.19.11.zip" ], "mappings": { "/var/www/html/images": "./images" } From 64aefa6dd459528df684881c9c421c939c218d0a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20Ka=CC=88gy?= Date: Fri, 9 Dec 2022 14:20:43 +0100 Subject: [PATCH 025/112] fix popover linting issue --- hooks/use-popover/index.js | 1 + 1 file changed, 1 insertion(+) diff --git a/hooks/use-popover/index.js b/hooks/use-popover/index.js index a8007d47..3e14f349 100644 --- a/hooks/use-popover/index.js +++ b/hooks/use-popover/index.js @@ -23,6 +23,7 @@ export const usePopover = () => { setPopoverAnchor, toggleVisible, toggleProps, + // eslint-disable-next-line react/prop-types Popover: ({ children }) => isVisible ? ( From 589018b12abb9a51879acd83217e2835d98ce7bd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20Ka=CC=88gy?= Date: Fri, 9 Dec 2022 14:21:18 +0100 Subject: [PATCH 026/112] 1.14.2-alpha.0 --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index b2b18ac3..e5b25b58 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@10up/block-components", - "version": "1.14.2-next.1", + "version": "1.14.2-alpha.0", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "@10up/block-components", - "version": "1.14.2-next.1", + "version": "1.14.2-alpha.0", "license": "GPL-2.0-or-later", "dependencies": { "@dnd-kit/core": "^6.0.3", diff --git a/package.json b/package.json index 33495a15..ed7384ce 100644 --- a/package.json +++ b/package.json @@ -3,7 +3,7 @@ "publishConfig": { "access": "public" }, - "version": "1.14.2-next.1", + "version": "1.14.2-alpha.0", "description": "10up Components built for the WordPress Block Editor.", "main": "./dist/index.js", "source": "index.js", From b04b0c000def9a0f55580c85db60d8d4ee46f4fb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20Ka=CC=88gy?= Date: Mon, 12 Dec 2022 13:08:32 +0100 Subject: [PATCH 027/112] fix use tagName as prop name over as --- components/author/index.js | 42 +++++++++++++++++++------------------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/components/author/index.js b/components/author/index.js index a9615a64..b191a1e0 100644 --- a/components/author/index.js +++ b/components/author/index.js @@ -23,7 +23,7 @@ import { AUTHOR_CONTEXT } from './context'; */ export const Name = (props) => { - const { as: Component = 'span', ...rest } = props; + const { tagName: TagName = 'span', ...rest } = props; /** * @type {Author} @@ -32,57 +32,57 @@ export const Name = (props) => { const wrapperProps = { ...rest }; - if (Component === 'a' && link) { + if (TagName === 'a' && link) { wrapperProps.href = link; } - return {name}; + return {name}; }; Name.propTypes = { - as: PropTypes.string, + tagName: PropTypes.string, }; Name.defaultProps = { - as: 'span', + tagName: 'span', }; export const FirstName = (props) => { - const { as: Component = 'span', ...rest } = props; + const { tagName: TagName = 'span', ...rest } = props; /** * @type {Author} */ const { first_name: firstName } = useContext(AUTHOR_CONTEXT); - return {firstName}; + return {firstName}; }; FirstName.propTypes = { - as: PropTypes.string, + tagName: PropTypes.string, }; FirstName.defaultProps = { - as: 'span', + tagName: 'span', }; export const LastName = (props) => { - const { as: Component = 'span', ...rest } = props; + const { tagName: TagName = 'span', ...rest } = props; /** * @type {Author} */ const { last_name: lastName } = useContext(AUTHOR_CONTEXT); - return {lastName}; + return {lastName}; }; LastName.propTypes = { - as: PropTypes.string, + tagName: PropTypes.string, }; LastName.defaultProps = { - as: 'span', + tagName: 'span', }; function useDefaultAvatar() { @@ -95,7 +95,7 @@ function useDefaultAvatar() { } export const Avatar = (props) => { - const { as: Component = 'img', ...rest } = props; + const { tagName: TagName = 'img', ...rest } = props; /** * @type {Author} @@ -107,34 +107,34 @@ export const Avatar = (props) => { const avatarSourceUrl = avatarUrls ? avatarUrls[avatarUrls.length - 1] : defaultAvatar; - return ; + return ; }; Avatar.propTypes = { - as: PropTypes.string, + tagName: PropTypes.string, }; Avatar.defaultProps = { - as: 'img', + tagName: 'img', }; export const Bio = (props) => { - const { as: Component = 'p', ...rest } = props; + const { tagName: TagName = 'p', ...rest } = props; /** * @type {Author} */ const { description } = useContext(AUTHOR_CONTEXT); - return {description}; + return {description}; }; Bio.propTypes = { - as: PropTypes.string, + tagName: PropTypes.string, }; Bio.defaultProps = { - as: 'p', + tagName: 'p', }; export const Email = (props) => { From 62c9c2f6aadd0bdf9d039bc5e8e98011aaa5e7b0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20Ka=CC=88gy?= Date: Mon, 12 Dec 2022 13:43:41 +0100 Subject: [PATCH 028/112] refactor post term list --- components/index.js | 4 +- components/post-categories/index.js | 19 ------ components/post-category-list/index.js | 3 + components/post-term-list/context.js | 4 ++ components/post-term-list/index.js | 79 ++++++++++++++++++++++++ components/post-term-list/item.js | 42 +++++++++++++ components/post-terms/index.js | 39 ------------ example/src/blocks/content-item/index.js | 6 +- example/src/blocks/hero/index.js | 16 ++--- 9 files changed, 139 insertions(+), 73 deletions(-) delete mode 100644 components/post-categories/index.js create mode 100644 components/post-category-list/index.js create mode 100644 components/post-term-list/context.js create mode 100644 components/post-term-list/index.js create mode 100644 components/post-term-list/item.js delete mode 100644 components/post-terms/index.js diff --git a/components/index.js b/components/index.js index bf51f3be..f2dfac06 100644 --- a/components/index.js +++ b/components/index.js @@ -23,7 +23,7 @@ export { PostFeaturedImage } from './post-featured-image'; export { PostExcerpt } from './post-excerpt'; export { PostAuthor } from './post-author'; export { PostDate, PostDatePicker } from './post-date'; -export { PostTerms } from './post-terms'; -export { PostCategories } from './post-categories'; +export { PostTermList } from './post-term-list'; +export { PostCategoryList } from './post-category-list'; export { PostPrimaryTerm } from './post-primary-term'; export { PostPrimaryCategory } from './post-primary-category'; diff --git a/components/post-categories/index.js b/components/post-categories/index.js deleted file mode 100644 index 0da38607..00000000 --- a/components/post-categories/index.js +++ /dev/null @@ -1,19 +0,0 @@ -import PropTypes from 'prop-types'; - -import { PostTerms } from '../post-terms'; - -export const PostCategories = (props) => { - const { context, children, ...rest } = props; - - return ; -}; - -PostCategories.propTypes = { - context: PropTypes.object, - children: PropTypes.func, -}; - -PostCategories.defaultProps = { - context: {}, - children: null, -}; diff --git a/components/post-category-list/index.js b/components/post-category-list/index.js new file mode 100644 index 00000000..ace9998c --- /dev/null +++ b/components/post-category-list/index.js @@ -0,0 +1,3 @@ +import { PostTermList } from '../post-term-list'; + +export const PostCategoryList = PostTermList; diff --git a/components/post-term-list/context.js b/components/post-term-list/context.js new file mode 100644 index 00000000..f8e3faf0 --- /dev/null +++ b/components/post-term-list/context.js @@ -0,0 +1,4 @@ +import { createContext } from '@wordpress/element'; + +export const POST_TERM_CONTEXT = createContext(); +export const POST_TERM_ITEM_CONTEXT = createContext(); diff --git a/components/post-term-list/index.js b/components/post-term-list/index.js new file mode 100644 index 00000000..239cb195 --- /dev/null +++ b/components/post-term-list/index.js @@ -0,0 +1,79 @@ +import { Spinner } from '@wordpress/components'; +import { Children } from '@wordpress/element'; +import PropTypes from 'prop-types'; +import { PostTaxonomiesHierarchicalTermSelector } from '@wordpress/editor'; + +import { usePopover, usePost, useSelectedTerms } from '../../hooks'; +import { POST_TERM_ITEM_CONTEXT } from './context'; +import { ListItem, TermLink } from './item'; + +export const PostTermList = (props) => { + const { context, taxonomyName = 'category', children, ...rest } = props; + + const { isDescendentOfQueryLoop } = usePost(context); + + const hasRenderCallback = typeof children === 'function'; + const hasChildComponents = !hasRenderCallback && Children.count(children); + + const [selectedTerms, hasResolvedSelectedTerms] = useSelectedTerms(taxonomyName, context); + + const { toggleProps, Popover } = usePopover(); + + if (!hasResolvedSelectedTerms) { + return ; + } + + if (hasRenderCallback) { + return selectedTerms.map((term) => children({ ...term, isDescendentOfQueryLoop })); + } + + let listElementProps = { + ...rest, + }; + + if (!isDescendentOfQueryLoop) { + listElementProps = { + ...listElementProps, + ...toggleProps, + }; + } + + if (hasChildComponents) { + return ( + <> +
      + {selectedTerms.map((term) => ( + + {children} + + ))} +
    + {!isDescendentOfQueryLoop && ( + + + + )} + + ); + } + + return selectedTerms.map((term) => ( +
  • + {term.name} +
  • + )); +}; + +PostTermList.propTypes = { + context: PropTypes.object, + children: PropTypes.func, + taxonomyName: PropTypes.string.isRequired, +}; + +PostTermList.defaultProps = { + context: {}, + children: null, +}; + +PostTermList.ListItem = ListItem; +PostTermList.TermLink = TermLink; diff --git a/components/post-term-list/item.js b/components/post-term-list/item.js new file mode 100644 index 00000000..9c745b61 --- /dev/null +++ b/components/post-term-list/item.js @@ -0,0 +1,42 @@ +import { useContext } from '@wordpress/element'; +import PropTypes from 'prop-types'; +import { Disabled } from '@wordpress/components'; +import { POST_TERM_ITEM_CONTEXT } from './context'; + +export const ListItem = (props) => { + const { tagName: TagName = 'li', children, ...rest } = props; + + return {children}; +}; + +ListItem.propTypes = { + tagName: PropTypes.string, + children: PropTypes.node.isRequired, +}; + +ListItem.defaultProps = { + tagName: 'li', +}; + +export const TermLink = (props) => { + const { tagName: TagName = 'a', children, ...rest } = props; + + const { link, name } = useContext(POST_TERM_ITEM_CONTEXT); + + return ( + + + {name} + + + ); +}; + +TermLink.propTypes = { + tagName: PropTypes.string, + children: PropTypes.node.isRequired, +}; + +TermLink.defaultProps = { + tagName: 'a', +}; diff --git a/components/post-terms/index.js b/components/post-terms/index.js deleted file mode 100644 index 1cc20715..00000000 --- a/components/post-terms/index.js +++ /dev/null @@ -1,39 +0,0 @@ -import { Spinner } from '@wordpress/components'; -import PropTypes from 'prop-types'; - -import { usePost, useSelectedTerms } from '../../hooks'; - -export const PostTerms = (props) => { - const { context, taxonomyName = 'category', children, ...rest } = props; - - const { isDescendentOfQueryLoop } = usePost(context); - - const hasRenderCallback = typeof children === 'function'; - - const [selectedTerms, hasResolvedSelectedTerms] = useSelectedTerms(taxonomyName, context); - - if (!hasResolvedSelectedTerms) { - return ; - } - - if (hasRenderCallback) { - return selectedTerms.map((term) => children({ ...term, isDescendentOfQueryLoop })); - } - - return selectedTerms.map((term) => ( -
  • - {term.name} -
  • - )); -}; - -PostTerms.propTypes = { - context: PropTypes.object, - children: PropTypes.func, - taxonomyName: PropTypes.string.isRequired, -}; - -PostTerms.defaultProps = { - context: {}, - children: null, -}; diff --git a/example/src/blocks/content-item/index.js b/example/src/blocks/content-item/index.js index d7623cfe..787ae1f9 100644 --- a/example/src/blocks/content-item/index.js +++ b/example/src/blocks/content-item/index.js @@ -2,7 +2,7 @@ import { registerBlockType } from '@wordpress/blocks'; import { useBlockProps } from '@wordpress/block-editor'; import { __ } from '@wordpress/i18n'; -import { PostFeaturedImage, PostTitle, PostPrimaryCategory, PostDate, PostCategories } from '@10up/block-components'; +import { PostFeaturedImage, PostTitle, PostPrimaryCategory, PostDate, PostCategoryList } from '@10up/block-components'; import { PostAuthor, PostExcerpt, PostCoAuthors } from '../../../../components'; const NAMESPACE = 'example'; @@ -31,13 +31,13 @@ registerBlockType( `${ NAMESPACE }/content-item`, {
      - + {({ name, link, id }) => (
    • {name}
    • )} -
      +
    diff --git a/example/src/blocks/hero/index.js b/example/src/blocks/hero/index.js index 5e155fbc..0327e40e 100644 --- a/example/src/blocks/hero/index.js +++ b/example/src/blocks/hero/index.js @@ -3,7 +3,7 @@ import { useBlockProps } from '@wordpress/block-editor'; import { __ } from '@wordpress/i18n'; import { header } from '@wordpress/icons'; -import { PostFeaturedImage, PostTitle, PostPrimaryCategory, PostDate, PostCategories, PostAuthor } from '@10up/block-components'; +import { PostFeaturedImage, PostTitle, PostPrimaryCategory, PostDate, PostCategoryList, PostAuthor } from '@10up/block-components'; import { PostExcerpt } from '../../../../components'; const NAMESPACE = 'example'; @@ -31,15 +31,11 @@ registerBlockType(`${NAMESPACE}/hero`, { -
      - - {({ name, link, id }) => ( -
    • - {name} -
    • - )} -
      -
    + + + + + From 5f44f85ae388035fc7311c0f3ee10ead074f590e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20Ka=CC=88gy?= Date: Mon, 12 Dec 2022 13:47:26 +0100 Subject: [PATCH 029/112] fix render callback and default markup of term list --- components/post-term-list/index.js | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/components/post-term-list/index.js b/components/post-term-list/index.js index 239cb195..e8937120 100644 --- a/components/post-term-list/index.js +++ b/components/post-term-list/index.js @@ -24,7 +24,7 @@ export const PostTermList = (props) => { } if (hasRenderCallback) { - return selectedTerms.map((term) => children({ ...term, isDescendentOfQueryLoop })); + return children({ selectedTerms, isDescendentOfQueryLoop }); } let listElementProps = { @@ -57,11 +57,15 @@ export const PostTermList = (props) => { ); } - return selectedTerms.map((term) => ( -
  • - {term.name} -
  • - )); + return ( +
      + {selectedTerms.map((term) => ( +
    • + {term.name} +
    • + ))} +
    + ); }; PostTermList.propTypes = { From 2aaa26fc1881e72624d5cf6484ee4e4ce7a38c74 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20Ka=CC=88gy?= Date: Mon, 12 Dec 2022 14:29:30 +0100 Subject: [PATCH 030/112] logical refactors --- components/post-author/index.js | 12 ++++++++-- components/post-term-list/index.js | 16 +++++++++---- components/post-term-list/item.js | 11 +++------ example/src/blocks/content-item/index.js | 30 ++++++++++-------------- example/src/blocks/hero/index.js | 14 +++++------ 5 files changed, 43 insertions(+), 40 deletions(-) diff --git a/components/post-author/index.js b/components/post-author/index.js index 7bb76b6d..c675d3db 100644 --- a/components/post-author/index.js +++ b/components/post-author/index.js @@ -40,7 +40,11 @@ export const PostAuthor = (props) => { } if (hasChildComponents) { - return {children}; + return ( + +
    {children}
    +
    + ); } if (hasRenderCallback) { @@ -52,7 +56,11 @@ export const PostAuthor = (props) => { PostAuthor.propTypes = { context: PropTypes.object, - children: PropTypes.oneOfType([PropTypes.func, PropTypes.node]), + children: PropTypes.oneOfType([ + PropTypes.func, + PropTypes.node, + PropTypes.arrayOf(PropTypes.node), + ]), }; PostAuthor.defaultProps = { diff --git a/components/post-term-list/index.js b/components/post-term-list/index.js index e8937120..914958b1 100644 --- a/components/post-term-list/index.js +++ b/components/post-term-list/index.js @@ -8,7 +8,13 @@ import { POST_TERM_ITEM_CONTEXT } from './context'; import { ListItem, TermLink } from './item'; export const PostTermList = (props) => { - const { context, taxonomyName = 'category', children, ...rest } = props; + const { + context, + tagName: TagName = 'ul', + taxonomyName = 'category', + children, + ...rest + } = props; const { isDescendentOfQueryLoop } = usePost(context); @@ -41,13 +47,13 @@ export const PostTermList = (props) => { if (hasChildComponents) { return ( <> -
      + {selectedTerms.map((term) => ( {children} ))} -
    +
    {!isDescendentOfQueryLoop && ( @@ -70,13 +76,15 @@ export const PostTermList = (props) => { PostTermList.propTypes = { context: PropTypes.object, - children: PropTypes.func, + children: PropTypes.func || PropTypes.node, taxonomyName: PropTypes.string.isRequired, + tagName: PropTypes.string, }; PostTermList.defaultProps = { context: {}, children: null, + tagName: 'ul', }; PostTermList.ListItem = ListItem; diff --git a/components/post-term-list/item.js b/components/post-term-list/item.js index 9c745b61..71aad04f 100644 --- a/components/post-term-list/item.js +++ b/components/post-term-list/item.js @@ -19,24 +19,19 @@ ListItem.defaultProps = { }; export const TermLink = (props) => { - const { tagName: TagName = 'a', children, ...rest } = props; + const { children, ...rest } = props; const { link, name } = useContext(POST_TERM_ITEM_CONTEXT); return ( - + {name} - + ); }; TermLink.propTypes = { - tagName: PropTypes.string, children: PropTypes.node.isRequired, }; - -TermLink.defaultProps = { - tagName: 'a', -}; diff --git a/example/src/blocks/content-item/index.js b/example/src/blocks/content-item/index.js index 787ae1f9..ebe87ac1 100644 --- a/example/src/blocks/content-item/index.js +++ b/example/src/blocks/content-item/index.js @@ -30,26 +30,20 @@ registerBlockType( `${ NAMESPACE }/content-item`, { -
      - - {({ name, link, id }) => ( -
    • - {name} -
    • - )} -
      -
    + + + + + - -
    - - - - - - -
    + + + + + + + ) diff --git a/example/src/blocks/hero/index.js b/example/src/blocks/hero/index.js index 0327e40e..04addc69 100644 --- a/example/src/blocks/hero/index.js +++ b/example/src/blocks/hero/index.js @@ -38,14 +38,12 @@ registerBlockType(`${NAMESPACE}/hero`, { - -
    - - - - - -
    + + + + + + ) From 34aca1fb4f01d901308363e0abc09d198cb3950f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20Ka=CC=88gy?= Date: Mon, 12 Dec 2022 14:29:46 +0100 Subject: [PATCH 031/112] add base readme files --- components/post-author/readme.md | 42 ++++++++++++++++++++++ components/post-date/readme.md | 22 ++++++++++++ components/post-excerpt/readme.md | 22 ++++++++++++ components/post-featured-image/readme.md | 21 +++++++++++ components/post-primary-term/readme.md | 4 +++ components/post-term-list/readme.md | 44 ++++++++++++++++++++++++ components/post-title/readme.md | 22 ++++++++++++ 7 files changed, 177 insertions(+) create mode 100644 components/post-author/readme.md create mode 100644 components/post-date/readme.md create mode 100644 components/post-excerpt/readme.md create mode 100644 components/post-featured-image/readme.md create mode 100644 components/post-primary-term/readme.md create mode 100644 components/post-term-list/readme.md create mode 100644 components/post-title/readme.md diff --git a/components/post-author/readme.md b/components/post-author/readme.md new file mode 100644 index 00000000..24f1f6d6 --- /dev/null +++ b/components/post-author/readme.md @@ -0,0 +1,42 @@ +# PostAuthor + +## Usage + +```js +import { PostAuthor } from '@10up/block-components'; + +function BlockEdit() { + + return ( + + + + + + + + ) +} +``` + +## Props + +| Name | Type | Default | Description | +| ---------- | ----------------- | -------- | -------------------------------------------------------------- | +| `context` | `object` | `{}` | | +| `children` | `function\|node\|null` | `null` | | +| `...rest` | `object` | `{}` | | + +## Child Components + +### `PostAuthor.Name` + +### `PostAuthor.FirstName` + +### `PostAuthor.LastName` + +### `PostAuthor.Avatar` + +### `PostAuthor.Bio` + +### `PostAuthor.Email` diff --git a/components/post-date/readme.md b/components/post-date/readme.md new file mode 100644 index 00000000..1cc91df6 --- /dev/null +++ b/components/post-date/readme.md @@ -0,0 +1,22 @@ +# Post Date + +## Usage + +```js +import { PostDate } from '@10up/block-components'; + +function BlockEdit() { + + return ( + + ) +} +``` + +## Props + +| Name | Type | Default | Description | +| ---------- | ----------------- | -------- | -------------------------------------------------------------- | +| `context` | `object` | `{}` | | +| `placeholder` | `string` | `No date set` | | +| `...rest` | `object` | `{}` | | diff --git a/components/post-excerpt/readme.md b/components/post-excerpt/readme.md new file mode 100644 index 00000000..e419ecd0 --- /dev/null +++ b/components/post-excerpt/readme.md @@ -0,0 +1,22 @@ +# Post Excerpt + +## Usage + +```js +import { PostExcerpt } from '@10up/block-components'; + +function BlockEdit() { + + return ( + + ) +} +``` + +## Props + +| Name | Type | Default | Description | +| ---------- | ----------------- | -------- | -------------------------------------------------------------- | +| `context` | `object` | `{}` | | +| `placeholder` | `string` | `Enter excerpt...` | | +| `...rest` | `object` | `{}` | | diff --git a/components/post-featured-image/readme.md b/components/post-featured-image/readme.md new file mode 100644 index 00000000..bf53d09c --- /dev/null +++ b/components/post-featured-image/readme.md @@ -0,0 +1,21 @@ +# Post Featured Image + +## Usage + +```js +import { PostFeaturedImage } from '@10up/block-components'; + +function BlockEdit() { + + return ( + + ) +} +``` + +## Props + +| Name | Type | Default | Description | +| ---------- | ----------------- | -------- | -------------------------------------------------------------- | +| `context` | `object` | `{}` | | +| `...rest` | `object` | `{}` | | diff --git a/components/post-primary-term/readme.md b/components/post-primary-term/readme.md new file mode 100644 index 00000000..4822e9f4 --- /dev/null +++ b/components/post-primary-term/readme.md @@ -0,0 +1,4 @@ +# PostPrimaryTerm + +> **Note** +> This Component depends on the Primary Term functionality of the Yoast SEO Plugin diff --git a/components/post-term-list/readme.md b/components/post-term-list/readme.md new file mode 100644 index 00000000..fafda1a8 --- /dev/null +++ b/components/post-term-list/readme.md @@ -0,0 +1,44 @@ +# PostTermList + +## Usage + +```js +import { PostTermList } from '@10up/block-components'; + +function BlockEdit() { + + return ( + + + + + + ) +} +``` + +### Output + +```html + +``` + +## Props + +| Name | Type | Default | Description | +| ---------- | ----------------- | -------- | -------------------------------------------------------------- | +| `context` | `object` | `{}` | | +| `children` | `function\|node\|null` | `null` | | +| `taxonomyName` | `string` | `category` | | +| `tagName` | `string` | `ul` | | +| `...rest` | `object` | `{}` | | + +## Child Components + +### `PostTermList.ListItem` + +### `PostTermList.TermLink` diff --git a/components/post-title/readme.md b/components/post-title/readme.md new file mode 100644 index 00000000..4551d5f3 --- /dev/null +++ b/components/post-title/readme.md @@ -0,0 +1,22 @@ +# Post Title + +## Usage + +```js +import { PostTitle } from '@10up/block-components'; + +function BlockEdit() { + + return ( + + ) +} +``` + +## Props + +| Name | Type | Default | Description | +| ---------- | ----------------- | -------- | -------------------------------------------------------------- | +| `context` | `object` | `{}` | | +| `tagName` | `string` | `h1` | | +| `...rest` | `object` | `{}` | | From bad8cf47dcaf329e6e5db292ee13cf9a8eb5c9a3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20Ka=CC=88gy?= Date: Mon, 12 Dec 2022 14:32:52 +0100 Subject: [PATCH 032/112] fix title rendering performance --- components/post-title/index.js | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/components/post-title/index.js b/components/post-title/index.js index f0716715..70bd0a45 100644 --- a/components/post-title/index.js +++ b/components/post-title/index.js @@ -2,13 +2,12 @@ import { useEntityProp } from '@wordpress/core-data'; import { RichText, store as blockEditorStore } from '@wordpress/block-editor'; import { useSelect } from '@wordpress/data'; import PropTypes from 'prop-types'; -import { usePost, useCanEditEntity } from '../../hooks'; +import { usePost } from '../../hooks'; export const PostTitle = (props) => { const { context, tagName: TagName = 'h1', ...rest } = props; const { postId, postType, isDescendentOfQueryLoop } = usePost(context); - const userCanEditTitle = useCanEditEntity('postType', postType, postId); const [rawTitle = '', setTitle, fullTitle] = useEntityProp( 'postType', postType, @@ -21,7 +20,7 @@ export const PostTitle = (props) => { [], ); - if (!userCanEditTitle || isDescendentOfQueryLoop) { + if (isDescendentOfQueryLoop) { // eslint-disable-next-line react/no-danger return ; } From 099a607af21de81a3d5f056675570960d7dab18d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20Ka=CC=88gy?= Date: Mon, 12 Dec 2022 14:35:48 +0100 Subject: [PATCH 033/112] 1.14.2-alpha.1 --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index e5b25b58..e07172dc 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@10up/block-components", - "version": "1.14.2-alpha.0", + "version": "1.14.2-alpha.1", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "@10up/block-components", - "version": "1.14.2-alpha.0", + "version": "1.14.2-alpha.1", "license": "GPL-2.0-or-later", "dependencies": { "@dnd-kit/core": "^6.0.3", diff --git a/package.json b/package.json index ed7384ce..b6a8fec6 100644 --- a/package.json +++ b/package.json @@ -3,7 +3,7 @@ "publishConfig": { "access": "public" }, - "version": "1.14.2-alpha.0", + "version": "1.14.2-alpha.1", "description": "10up Components built for the WordPress Block Editor.", "main": "./dist/index.js", "source": "index.js", From a8e2dd0129896743dc89c56c80af2b51bdcab7eb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20Ka=CC=88gy?= Date: Tue, 13 Dec 2022 09:49:49 +0100 Subject: [PATCH 034/112] add PostContext component --- components/index.js | 1 + components/post-context/context.js | 9 +++++++++ components/post-context/index.js | 31 ++++++++++++++++++++++++++++++ 3 files changed, 41 insertions(+) create mode 100644 components/post-context/context.js create mode 100644 components/post-context/index.js diff --git a/components/index.js b/components/index.js index f2dfac06..a03d4a8f 100644 --- a/components/index.js +++ b/components/index.js @@ -18,6 +18,7 @@ export { CircularProgressBar, Counter, } from './rich-text-character-limit'; +export { PostContext } from './post-context'; export { PostTitle } from './post-title'; export { PostFeaturedImage } from './post-featured-image'; export { PostExcerpt } from './post-excerpt'; diff --git a/components/post-context/context.js b/components/post-context/context.js new file mode 100644 index 00000000..0d6272cb --- /dev/null +++ b/components/post-context/context.js @@ -0,0 +1,9 @@ +import { createContext } from '@wordpress/element'; + +const DEFAULT_POST_CONTEXT = { + postId: null, + postType: null, + isEditable: null, +}; + +export const POST_CONTEXT = createContext(DEFAULT_POST_CONTEXT); diff --git a/components/post-context/index.js b/components/post-context/index.js new file mode 100644 index 00000000..5776b3cb --- /dev/null +++ b/components/post-context/index.js @@ -0,0 +1,31 @@ +import PropTypes from 'prop-types'; +import { useMemo } from '@wordpress/element'; +import { POST_CONTEXT } from './context'; + +export const PostContext = (props) => { + const { children, postId, postType, isEditable } = props; + + const value = useMemo( + () => ({ + postId, + postType, + isEditable, + }), + [postId, postType, isEditable], + ); + + return {children}; +}; + +PostContext.propTypes = { + children: PropTypes.node.isRequired, + postId: PropTypes.number, + postType: PropTypes.string, + isEditable: PropTypes.bool, +}; + +PostContext.defaultProps = { + postId: null, + postType: null, + isEditable: null, +}; From 51630aabc9302e5c0102c7d591fb507db92d2e26 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20Ka=CC=88gy?= Date: Tue, 13 Dec 2022 09:50:08 +0100 Subject: [PATCH 035/112] fix propTypes of PostCategoryList --- components/post-category-list/index.js | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/components/post-category-list/index.js b/components/post-category-list/index.js index ace9998c..7f50b3e5 100644 --- a/components/post-category-list/index.js +++ b/components/post-category-list/index.js @@ -1,3 +1,12 @@ +import PropTypes from 'prop-types'; import { PostTermList } from '../post-term-list'; export const PostCategoryList = PostTermList; + +PostCategoryList.propTypes = { + taxonomyName: PropTypes.string, +}; + +PostCategoryList.defaultProps = { + taxonomyName: 'category', +}; From b4bb572696714937ffa1d81fc8157871d7150877 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20Ka=CC=88gy?= Date: Tue, 13 Dec 2022 09:50:28 +0100 Subject: [PATCH 036/112] fix propTypes of PostPrimaryCategory --- components/post-primary-category/index.js | 23 +++++------------------ 1 file changed, 5 insertions(+), 18 deletions(-) diff --git a/components/post-primary-category/index.js b/components/post-primary-category/index.js index 2fb6adb2..7fc8977c 100644 --- a/components/post-primary-category/index.js +++ b/components/post-primary-category/index.js @@ -2,33 +2,20 @@ import { __ } from '@wordpress/i18n'; import PropTypes from 'prop-types'; import { PostPrimaryTerm } from '../post-primary-term'; -export const PostPrimaryCategory = (props) => { - const { - context, - placeholder = __('Select a category', 'tenup'), - isLink = true, - ...rest - } = props; +export const PostPrimaryCategory = PostPrimaryTerm; - return ( - - ); +PostPrimaryCategory.defaultProps = { + placeholder: __('Select a category', 'tenup'), }; PostPrimaryCategory.propTypes = { - context: PropTypes.object, placeholder: PropTypes.string, + taxonomyName: PropTypes.string, isLink: PropTypes.bool, }; PostPrimaryCategory.defaultProps = { - context: {}, placeholder: __('Select a category', 'tenup'), + taxonomyName: 'category', isLink: true, }; From d11a0e46d77d14b85b501e7927dbba66bacddf2e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20Ka=CC=88gy?= Date: Tue, 13 Dec 2022 09:51:10 +0100 Subject: [PATCH 037/112] fix refactor components away from passign through context --- components/post-author/index.js | 6 +- components/post-author/readme.md | 1 - components/post-date/index.js | 10 ++- components/post-date/readme.md | 1 - components/post-excerpt/index.js | 11 ++- components/post-excerpt/readme.md | 1 - components/post-featured-image/index.js | 7 +- components/post-featured-image/readme.md | 1 - components/post-primary-category/readme.md | 0 components/post-primary-term/index.js | 5 +- components/post-primary-term/readme.md | 2 +- components/post-term-list/index.js | 22 ++---- components/post-term-list/item.js | 8 +-- components/post-title/index.js | 8 +-- components/post-title/readme.md | 1 - example/src/blocks/content-item/index.js | 84 +++++++++++----------- hooks/use-post/index.js | 16 +++-- hooks/use-primary-term/index.js | 9 +-- hooks/use-selected-terms/index.js | 10 +-- 19 files changed, 89 insertions(+), 114 deletions(-) create mode 100644 components/post-primary-category/readme.md diff --git a/components/post-author/index.js b/components/post-author/index.js index c675d3db..95f8c0aa 100644 --- a/components/post-author/index.js +++ b/components/post-author/index.js @@ -9,8 +9,8 @@ import { Name, FirstName, LastName, Avatar, Bio, Email } from '../author'; import { AUTHOR_CONTEXT } from '../author/context'; export const PostAuthor = (props) => { - const { context, children, ...rest } = props; - const { postId, postType } = usePost(context); + const { children, ...rest } = props; + const { postId, postType } = usePost(); const [author, hasResolved] = useSelect( (select) => { @@ -55,7 +55,6 @@ export const PostAuthor = (props) => { }; PostAuthor.propTypes = { - context: PropTypes.object, children: PropTypes.oneOfType([ PropTypes.func, PropTypes.node, @@ -64,7 +63,6 @@ PostAuthor.propTypes = { }; PostAuthor.defaultProps = { - context: {}, children: null, }; diff --git a/components/post-author/readme.md b/components/post-author/readme.md index 24f1f6d6..309c928c 100644 --- a/components/post-author/readme.md +++ b/components/post-author/readme.md @@ -23,7 +23,6 @@ function BlockEdit() { | Name | Type | Default | Description | | ---------- | ----------------- | -------- | -------------------------------------------------------------- | -| `context` | `object` | `{}` | | | `children` | `function\|node\|null` | `null` | | | `...rest` | `object` | `{}` | | diff --git a/components/post-date/index.js b/components/post-date/index.js index 70f645ba..8d342c1c 100644 --- a/components/post-date/index.js +++ b/components/post-date/index.js @@ -28,9 +28,9 @@ PostDatePicker.propTypes = { }; export const PostDate = (props) => { - const { context, placeholder = __('No date set', 'tenup'), ...rest } = props; + const { placeholder = __('No date set', 'tenup'), ...rest } = props; - const { postId, postType, isDescendentOfQueryLoop } = usePost(context); + const { postId, postType, isEditable } = usePost(); const [date, setDate] = useEntityProp('postType', postType, 'date', postId); const [siteFormat] = useEntityProp('root', 'site', 'date_format'); @@ -45,7 +45,7 @@ export const PostDate = (props) => { let parentProps = { ...rest }; - if (!isDescendentOfQueryLoop) { + if (isEditable) { parentProps = { ...toggleProps, ...parentProps, @@ -62,7 +62,7 @@ export const PostDate = (props) => { > {timeString} - {!isDescendentOfQueryLoop && ( + {isEditable && ( @@ -72,11 +72,9 @@ export const PostDate = (props) => { }; PostDate.propTypes = { - context: PropTypes.object, placeholder: PropTypes.string, }; PostDate.defaultProps = { - context: {}, placeholder: __('No date set', 'tenup'), }; diff --git a/components/post-date/readme.md b/components/post-date/readme.md index 1cc91df6..ba707e8b 100644 --- a/components/post-date/readme.md +++ b/components/post-date/readme.md @@ -17,6 +17,5 @@ function BlockEdit() { | Name | Type | Default | Description | | ---------- | ----------------- | -------- | -------------------------------------------------------------- | -| `context` | `object` | `{}` | | | `placeholder` | `string` | `No date set` | | | `...rest` | `object` | `{}` | | diff --git a/components/post-excerpt/index.js b/components/post-excerpt/index.js index fea9376c..1404a71e 100644 --- a/components/post-excerpt/index.js +++ b/components/post-excerpt/index.js @@ -2,13 +2,12 @@ import { useEntityProp } from '@wordpress/core-data'; import { __ } from '@wordpress/i18n'; import { RichText } from '@wordpress/block-editor'; import PropTypes from 'prop-types'; -import { usePost, useCanEditEntity } from '../../hooks'; +import { usePost } from '../../hooks'; export const PostExcerpt = (props) => { - const { context, placeholder = __('Enter excerpt...', 'tenup'), ...rest } = props; - const { postId, postType, isDescendentOfQueryLoop } = usePost(context); + const { placeholder = __('Enter excerpt...', 'tenup'), ...rest } = props; + const { postId, postType, isEditable } = usePost(); - const userCanEditExcerpt = useCanEditEntity('postType', postType, postId); const [rawExcerpt = '', setExcerpt, fullExcerpt] = useEntityProp( 'postType', postType, @@ -16,7 +15,7 @@ export const PostExcerpt = (props) => { postId, ); - if (!userCanEditExcerpt || isDescendentOfQueryLoop) { + if (!isEditable) { // eslint-disable-next-line react/no-danger return

    ; } @@ -34,11 +33,9 @@ export const PostExcerpt = (props) => { }; PostExcerpt.propTypes = { - context: PropTypes.object, placeholder: PropTypes.string, }; PostExcerpt.defaultProps = { - context: {}, placeholder: __('Enter excerpt...', 'tenup'), }; diff --git a/components/post-excerpt/readme.md b/components/post-excerpt/readme.md index e419ecd0..5914437d 100644 --- a/components/post-excerpt/readme.md +++ b/components/post-excerpt/readme.md @@ -17,6 +17,5 @@ function BlockEdit() { | Name | Type | Default | Description | | ---------- | ----------------- | -------- | -------------------------------------------------------------- | -| `context` | `object` | `{}` | | | `placeholder` | `string` | `Enter excerpt...` | | | `...rest` | `object` | `{}` | | diff --git a/components/post-featured-image/index.js b/components/post-featured-image/index.js index 09f1d2a8..2e7b238c 100644 --- a/components/post-featured-image/index.js +++ b/components/post-featured-image/index.js @@ -4,8 +4,7 @@ import { usePost } from '../../hooks'; import { Image } from '../image'; export const PostFeaturedImage = (props) => { - const { context, ...rest } = props; - const { postId, postType, isDescendentOfQueryLoop } = usePost(context); + const { postId, postType, isEditable } = usePost(); const [featuredImage, setFeaturedImage] = useEntityProp( 'postType', postType, @@ -20,9 +19,9 @@ export const PostFeaturedImage = (props) => { return ( ); }; diff --git a/components/post-featured-image/readme.md b/components/post-featured-image/readme.md index bf53d09c..66e2d62b 100644 --- a/components/post-featured-image/readme.md +++ b/components/post-featured-image/readme.md @@ -17,5 +17,4 @@ function BlockEdit() { | Name | Type | Default | Description | | ---------- | ----------------- | -------- | -------------------------------------------------------------- | -| `context` | `object` | `{}` | | | `...rest` | `object` | `{}` | | diff --git a/components/post-primary-category/readme.md b/components/post-primary-category/readme.md new file mode 100644 index 00000000..e69de29b diff --git a/components/post-primary-term/index.js b/components/post-primary-term/index.js index 42e401bc..1b07f2fd 100644 --- a/components/post-primary-term/index.js +++ b/components/post-primary-term/index.js @@ -4,14 +4,13 @@ import { usePrimaryTerm } from '../../hooks'; export const PostPrimaryTerm = (props) => { const { - context, taxonomyName = 'category', placeholder = __('Select a term', 'tenup'), isLink = true, ...rest } = props; - const [primaryTerm, isSupportedTaxonomy] = usePrimaryTerm(taxonomyName, context); + const [primaryTerm, isSupportedTaxonomy] = usePrimaryTerm(taxonomyName); const hasPrimaryTerm = !!primaryTerm; @@ -36,14 +35,12 @@ export const PostPrimaryTerm = (props) => { }; PostPrimaryTerm.propTypes = { - context: PropTypes.object, placeholder: PropTypes.string, taxonomyName: PropTypes.string.isRequired, isLink: PropTypes.bool, }; PostPrimaryTerm.defaultProps = { - context: {}, placeholder: __('Select a Term', 'tenup'), isLink: true, }; diff --git a/components/post-primary-term/readme.md b/components/post-primary-term/readme.md index 4822e9f4..f36d98df 100644 --- a/components/post-primary-term/readme.md +++ b/components/post-primary-term/readme.md @@ -1,4 +1,4 @@ # PostPrimaryTerm -> **Note** +> **Warning** > This Component depends on the Primary Term functionality of the Yoast SEO Plugin diff --git a/components/post-term-list/index.js b/components/post-term-list/index.js index 914958b1..1fc51fb0 100644 --- a/components/post-term-list/index.js +++ b/components/post-term-list/index.js @@ -8,20 +8,14 @@ import { POST_TERM_ITEM_CONTEXT } from './context'; import { ListItem, TermLink } from './item'; export const PostTermList = (props) => { - const { - context, - tagName: TagName = 'ul', - taxonomyName = 'category', - children, - ...rest - } = props; + const { tagName: TagName = 'ul', taxonomyName = 'category', children, ...rest } = props; - const { isDescendentOfQueryLoop } = usePost(context); + const { isEditable } = usePost(); const hasRenderCallback = typeof children === 'function'; const hasChildComponents = !hasRenderCallback && Children.count(children); - const [selectedTerms, hasResolvedSelectedTerms] = useSelectedTerms(taxonomyName, context); + const [selectedTerms, hasResolvedSelectedTerms] = useSelectedTerms(taxonomyName); const { toggleProps, Popover } = usePopover(); @@ -30,14 +24,14 @@ export const PostTermList = (props) => { } if (hasRenderCallback) { - return children({ selectedTerms, isDescendentOfQueryLoop }); + return children({ selectedTerms, isEditable }); } let listElementProps = { ...rest, }; - if (!isDescendentOfQueryLoop) { + if (isEditable) { listElementProps = { ...listElementProps, ...toggleProps, @@ -54,7 +48,7 @@ export const PostTermList = (props) => { ))} - {!isDescendentOfQueryLoop && ( + {isEditable && ( @@ -75,14 +69,12 @@ export const PostTermList = (props) => { }; PostTermList.propTypes = { - context: PropTypes.object, - children: PropTypes.func || PropTypes.node, + children: PropTypes.oneOfType([PropTypes.node, PropTypes.func]), taxonomyName: PropTypes.string.isRequired, tagName: PropTypes.string, }; PostTermList.defaultProps = { - context: {}, children: null, tagName: 'ul', }; diff --git a/components/post-term-list/item.js b/components/post-term-list/item.js index 71aad04f..86debb17 100644 --- a/components/post-term-list/item.js +++ b/components/post-term-list/item.js @@ -19,19 +19,13 @@ ListItem.defaultProps = { }; export const TermLink = (props) => { - const { children, ...rest } = props; - const { link, name } = useContext(POST_TERM_ITEM_CONTEXT); return ( - + {name} ); }; - -TermLink.propTypes = { - children: PropTypes.node.isRequired, -}; diff --git a/components/post-title/index.js b/components/post-title/index.js index 70bd0a45..3db54ad6 100644 --- a/components/post-title/index.js +++ b/components/post-title/index.js @@ -5,8 +5,8 @@ import PropTypes from 'prop-types'; import { usePost } from '../../hooks'; export const PostTitle = (props) => { - const { context, tagName: TagName = 'h1', ...rest } = props; - const { postId, postType, isDescendentOfQueryLoop } = usePost(context); + const { tagName: TagName = 'h1', ...rest } = props; + const { postId, postType, isEditable } = usePost(); const [rawTitle = '', setTitle, fullTitle] = useEntityProp( 'postType', @@ -20,7 +20,7 @@ export const PostTitle = (props) => { [], ); - if (isDescendentOfQueryLoop) { + if (!isEditable) { // eslint-disable-next-line react/no-danger return ; } @@ -38,11 +38,9 @@ export const PostTitle = (props) => { }; PostTitle.propTypes = { - context: PropTypes.object, tagName: PropTypes.string, }; PostTitle.defaultProps = { - context: {}, tagName: 'h1', }; diff --git a/components/post-title/readme.md b/components/post-title/readme.md index 4551d5f3..eae03efb 100644 --- a/components/post-title/readme.md +++ b/components/post-title/readme.md @@ -17,6 +17,5 @@ function BlockEdit() { | Name | Type | Default | Description | | ---------- | ----------------- | -------- | -------------------------------------------------------------- | -| `context` | `object` | `{}` | | | `tagName` | `string` | `h1` | | | `...rest` | `object` | `{}` | | diff --git a/example/src/blocks/content-item/index.js b/example/src/blocks/content-item/index.js index ebe87ac1..2c885ecc 100644 --- a/example/src/blocks/content-item/index.js +++ b/example/src/blocks/content-item/index.js @@ -2,51 +2,53 @@ import { registerBlockType } from '@wordpress/blocks'; import { useBlockProps } from '@wordpress/block-editor'; import { __ } from '@wordpress/i18n'; -import { PostFeaturedImage, PostTitle, PostPrimaryCategory, PostDate, PostCategoryList } from '@10up/block-components'; +import { PostContext, PostFeaturedImage, PostTitle, PostPrimaryCategory, PostDate, PostCategoryList } from '@10up/block-components'; import { PostAuthor, PostExcerpt, PostCoAuthors } from '../../../../components'; const NAMESPACE = 'example'; -registerBlockType( `${ NAMESPACE }/content-item`, { +registerBlockType(`${NAMESPACE}/content-item`, { apiVersion: 2, - title: __( 'Content Item', NAMESPACE ), - icon: 'smiley', - category: 'common', - example: {}, - supports: { - html: false - }, - attributes: {}, - transforms: {}, - variations: [], - usesContext: [ 'postId', 'postType', 'queryId' ], - ancestor: [ 'core/post-template' ], - edit: ({context}) => { + title: __('Content Item', NAMESPACE), + icon: 'smiley', + category: 'common', + example: {}, + supports: { + html: false + }, + attributes: {}, + transforms: {}, + variations: [], + usesContext: ['postId', 'postType', 'queryId'], + ancestor: ['core/post-template'], + edit: ({ context }) => { const blockProps = useBlockProps(); - return ( -

    -
    - -
    - - - - - - - - - - - - - - - - - + return ( +
    + +
    + +
    + + + + + + + + + + + + + + + + + +
    - ) - }, - save: () => null -} ); + ) + }, + save: () => null +}); diff --git a/hooks/use-post/index.js b/hooks/use-post/index.js index 9ec6d397..48c94c40 100644 --- a/hooks/use-post/index.js +++ b/hooks/use-post/index.js @@ -1,7 +1,15 @@ import { useSelect } from '@wordpress/data'; +import { useContext } from '@wordpress/element'; import { store as editorStore } from '@wordpress/editor'; +import { POST_CONTEXT } from '../../components/post-context/context'; + +export function usePost() { + const { + postId: blockContextPostId, + postType: blockContextPostType, + isEditable: blockContextIsEditable, + } = useContext(POST_CONTEXT); -export function usePost(blockContext = {}) { const { globalPostId, globalPostType } = useSelect( (select) => ({ globalPostId: select(editorStore).getCurrentPostId(), @@ -11,8 +19,8 @@ export function usePost(blockContext = {}) { ); return { - postId: blockContext?.postId || globalPostId, - postType: blockContext?.postType || globalPostType, - isDescendentOfQueryLoop: !!Number.isFinite(blockContext?.queryId), + postId: blockContextPostId || globalPostId, + postType: blockContextPostType || globalPostType, + isEditable: blockContextPostId && blockContextPostType ? blockContextIsEditable : true, }; } diff --git a/hooks/use-primary-term/index.js b/hooks/use-primary-term/index.js index 5c0a6043..ff3c54e0 100644 --- a/hooks/use-primary-term/index.js +++ b/hooks/use-primary-term/index.js @@ -4,8 +4,8 @@ import { usePost } from '../use-post'; import { useIsPluginActive } from '../use-is-plugin-active'; import { useIsSupportedTaxonomy } from '../use-is-supported-taxonomy'; -export const usePrimaryTerm = (taxonomyName, context = {}) => { - const { postType, isDescendentOfQueryLoop } = usePost(context); +export const usePrimaryTerm = (taxonomyName) => { + const { postType, isEditable } = usePost(); const [isYoastSeoActive, hasResolvedIsPluginActive] = useIsPluginActive('wordpress-seo/wp-seo'); const [isSupportedTaxonomy, hasResolvedIsSupportedTaxonomy] = useIsSupportedTaxonomy( @@ -58,8 +58,5 @@ export const usePrimaryTerm = (taxonomyName, context = {}) => { [primaryTermId], ); - return [ - isDescendentOfQueryLoop ? { name: __('Primary Term', 'tenup') } : primaryTerm, - isSupportedTaxonomy, - ]; + return [!isEditable ? { name: __('Primary Term', 'tenup') } : primaryTerm, isSupportedTaxonomy]; }; diff --git a/hooks/use-selected-terms/index.js b/hooks/use-selected-terms/index.js index 24cb9354..2769a332 100644 --- a/hooks/use-selected-terms/index.js +++ b/hooks/use-selected-terms/index.js @@ -4,8 +4,8 @@ import { useAllTerms } from '../use-all-terms'; import { useSelectedTermIds } from '../use-selected-term-ids'; import { useSelectedTermsOfSavedPost } from '../use-selected-terms-of-saved-post'; -export const useSelectedTerms = (taxonomyName, context = {}) => { - const { postId, postType, isDescendentOfQueryLoop } = usePost(context); +export const useSelectedTerms = (taxonomyName) => { + const { postId, postType, isEditable } = usePost(); const [isSupportedTaxonomy, hasResolvedIsSupportedTaxonomy] = useIsSupportedTaxonomy( postType, taxonomyName, @@ -28,13 +28,13 @@ export const useSelectedTerms = (taxonomyName, context = {}) => { } if ( - (isDescendentOfQueryLoop && !hasResolvedSelectedTermsOfSavedPost) || - (!isDescendentOfQueryLoop && (!hasResolvedTerms || !hasResolvedSelectedTermIds)) + (!isEditable && !hasResolvedSelectedTermsOfSavedPost) || + (isEditable && (!hasResolvedTerms || !hasResolvedSelectedTermIds)) ) { return [[], false]; } - if (isDescendentOfQueryLoop && hasResolvedSelectedTermsOfSavedPost) { + if (!isEditable && hasResolvedSelectedTermsOfSavedPost) { return [selectedTermsOfSavedPost, hasResolvedSelectedTermsOfSavedPost]; } From 1f07d1b93171572435458fdc7ab2bc3250f22a90 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20Ka=CC=88gy?= Date: Tue, 13 Dec 2022 10:41:10 +0100 Subject: [PATCH 038/112] fix import path for all components --- example/src/blocks/content-item/index.js | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/example/src/blocks/content-item/index.js b/example/src/blocks/content-item/index.js index 2c885ecc..9cd57d69 100644 --- a/example/src/blocks/content-item/index.js +++ b/example/src/blocks/content-item/index.js @@ -2,8 +2,16 @@ import { registerBlockType } from '@wordpress/blocks'; import { useBlockProps } from '@wordpress/block-editor'; import { __ } from '@wordpress/i18n'; -import { PostContext, PostFeaturedImage, PostTitle, PostPrimaryCategory, PostDate, PostCategoryList } from '@10up/block-components'; -import { PostAuthor, PostExcerpt, PostCoAuthors } from '../../../../components'; +import { + PostContext, + PostFeaturedImage, + PostTitle, + PostPrimaryCategory, + PostDate, + PostCategoryList, + PostAuthor, + PostExcerpt +} from '@10up/block-components'; const NAMESPACE = 'example'; From 26d913a0f66e49b62b82430f09cabd94f372f496 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20Ka=CC=88gy?= Date: Tue, 13 Dec 2022 10:41:23 +0100 Subject: [PATCH 039/112] fix use correct isEditable factor --- example/src/blocks/content-item/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/example/src/blocks/content-item/index.js b/example/src/blocks/content-item/index.js index 9cd57d69..0f839ab4 100644 --- a/example/src/blocks/content-item/index.js +++ b/example/src/blocks/content-item/index.js @@ -33,7 +33,7 @@ registerBlockType(`${NAMESPACE}/content-item`, { const blockProps = useBlockProps(); return (
    - +
    From 77a856df0a73a6ceb27ece68444f1dfc07ec0ff3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20Ka=CC=88gy?= Date: Tue, 13 Dec 2022 10:41:47 +0100 Subject: [PATCH 040/112] refactor post context context --- components/post-context/context.js | 8 ++++++-- components/post-context/index.js | 8 ++------ hooks/use-post/index.js | 9 +++++---- 3 files changed, 13 insertions(+), 12 deletions(-) diff --git a/components/post-context/context.js b/components/post-context/context.js index 0d6272cb..bceb6975 100644 --- a/components/post-context/context.js +++ b/components/post-context/context.js @@ -1,9 +1,13 @@ -import { createContext } from '@wordpress/element'; +import { createContext, useContext } from '@wordpress/element'; -const DEFAULT_POST_CONTEXT = { +export const DEFAULT_POST_CONTEXT = { postId: null, postType: null, isEditable: null, }; export const POST_CONTEXT = createContext(DEFAULT_POST_CONTEXT); + +export const usePostContext = () => { + return useContext(POST_CONTEXT); +}; diff --git a/components/post-context/index.js b/components/post-context/index.js index 5776b3cb..82dc7b35 100644 --- a/components/post-context/index.js +++ b/components/post-context/index.js @@ -1,6 +1,6 @@ import PropTypes from 'prop-types'; import { useMemo } from '@wordpress/element'; -import { POST_CONTEXT } from './context'; +import { DEFAULT_POST_CONTEXT, POST_CONTEXT } from './context'; export const PostContext = (props) => { const { children, postId, postType, isEditable } = props; @@ -24,8 +24,4 @@ PostContext.propTypes = { isEditable: PropTypes.bool, }; -PostContext.defaultProps = { - postId: null, - postType: null, - isEditable: null, -}; +PostContext.defaultProps = DEFAULT_POST_CONTEXT; diff --git a/hooks/use-post/index.js b/hooks/use-post/index.js index 48c94c40..e78703dd 100644 --- a/hooks/use-post/index.js +++ b/hooks/use-post/index.js @@ -1,14 +1,13 @@ import { useSelect } from '@wordpress/data'; -import { useContext } from '@wordpress/element'; import { store as editorStore } from '@wordpress/editor'; -import { POST_CONTEXT } from '../../components/post-context/context'; +import { usePostContext } from '../../components/post-context/context'; export function usePost() { const { postId: blockContextPostId, postType: blockContextPostType, isEditable: blockContextIsEditable, - } = useContext(POST_CONTEXT); + } = usePostContext(); const { globalPostId, globalPostType } = useSelect( (select) => ({ @@ -18,9 +17,11 @@ export function usePost() { [], ); + const hasBlockContext = !!blockContextPostId && !!blockContextPostType; + return { postId: blockContextPostId || globalPostId, postType: blockContextPostType || globalPostType, - isEditable: blockContextPostId && blockContextPostType ? blockContextIsEditable : true, + isEditable: hasBlockContext ? blockContextIsEditable : true, }; } From 2f4c01e59d87115bc40f189f326ab215d2c1a492 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20Ka=CC=88gy?= Date: Tue, 13 Dec 2022 10:41:59 +0100 Subject: [PATCH 041/112] fix remove unused proptypes --- components/post-featured-image/index.js | 9 --------- 1 file changed, 9 deletions(-) diff --git a/components/post-featured-image/index.js b/components/post-featured-image/index.js index 2e7b238c..4d4d3bc5 100644 --- a/components/post-featured-image/index.js +++ b/components/post-featured-image/index.js @@ -1,5 +1,4 @@ import { useEntityProp } from '@wordpress/core-data'; -import PropTypes from 'prop-types'; import { usePost } from '../../hooks'; import { Image } from '../image'; @@ -25,11 +24,3 @@ export const PostFeaturedImage = (props) => { /> ); }; - -PostFeaturedImage.propTypes = { - context: PropTypes.object, -}; - -PostFeaturedImage.defaultProps = { - context: {}, -}; From 3082a9172d79064bd62d4130820a6d9dee2e4694 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20Ka=CC=88gy?= Date: Tue, 13 Dec 2022 10:56:56 +0100 Subject: [PATCH 042/112] fix use inert for disabled elements --- components/post-primary-term/index.js | 1 + components/post-term-list/item.js | 9 +++------ hooks/use-popover/index.js | 2 +- 3 files changed, 5 insertions(+), 7 deletions(-) diff --git a/components/post-primary-term/index.js b/components/post-primary-term/index.js index 1b07f2fd..3a4efaab 100644 --- a/components/post-primary-term/index.js +++ b/components/post-primary-term/index.js @@ -29,6 +29,7 @@ export const PostPrimaryTerm = (props) => { if (isLink) { wrapperProps.href = termUrl; + wrapperProps.inert = 'true'; } return {termString}; diff --git a/components/post-term-list/item.js b/components/post-term-list/item.js index 86debb17..e234cc0b 100644 --- a/components/post-term-list/item.js +++ b/components/post-term-list/item.js @@ -1,6 +1,5 @@ import { useContext } from '@wordpress/element'; import PropTypes from 'prop-types'; -import { Disabled } from '@wordpress/components'; import { POST_TERM_ITEM_CONTEXT } from './context'; export const ListItem = (props) => { @@ -22,10 +21,8 @@ export const TermLink = (props) => { const { link, name } = useContext(POST_TERM_ITEM_CONTEXT); return ( - - - {name} - - + + {name} + ); }; diff --git a/hooks/use-popover/index.js b/hooks/use-popover/index.js index 3e14f349..db96c5b6 100644 --- a/hooks/use-popover/index.js +++ b/hooks/use-popover/index.js @@ -27,7 +27,7 @@ export const usePopover = () => { Popover: ({ children }) => isVisible ? ( -
    {children}
    +
    {children}
    ) : null, }; From 8a8278682d30e8c6134da7d94644973235529126 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20Ka=CC=88gy?= Date: Tue, 13 Dec 2022 11:05:49 +0100 Subject: [PATCH 043/112] allow usage of custom date format --- components/post-date/index.js | 6 ++++-- components/post-date/readme.md | 1 + 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/components/post-date/index.js b/components/post-date/index.js index 8d342c1c..ba29b139 100644 --- a/components/post-date/index.js +++ b/components/post-date/index.js @@ -28,7 +28,7 @@ PostDatePicker.propTypes = { }; export const PostDate = (props) => { - const { placeholder = __('No date set', 'tenup'), ...rest } = props; + const { placeholder = __('No date set', 'tenup'), format = undefined, ...rest } = props; const { postId, postType, isEditable } = usePost(); @@ -37,7 +37,7 @@ export const PostDate = (props) => { const settings = getSettings(); const timezone = Intl.DateTimeFormat().resolvedOptions().timeZone; - const resolvedFormat = siteFormat || settings.formats.date; + const resolvedFormat = format || siteFormat || settings.formats.date; const { toggleProps, Popover } = usePopover(); @@ -73,8 +73,10 @@ export const PostDate = (props) => { PostDate.propTypes = { placeholder: PropTypes.string, + format: PropTypes.string, }; PostDate.defaultProps = { placeholder: __('No date set', 'tenup'), + format: undefined, }; diff --git a/components/post-date/readme.md b/components/post-date/readme.md index ba707e8b..d8182679 100644 --- a/components/post-date/readme.md +++ b/components/post-date/readme.md @@ -18,4 +18,5 @@ function BlockEdit() { | Name | Type | Default | Description | | ---------- | ----------------- | -------- | -------------------------------------------------------------- | | `placeholder` | `string` | `No date set` | | +| `format` | `string` | | Uses the WordPress date format setting of the site | | `...rest` | `object` | `{}` | | From 296fb7b9a0290359bc51775c627e262832ec3dfd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20Ka=CC=88gy?= Date: Thu, 15 Dec 2022 12:19:50 +0100 Subject: [PATCH 044/112] fix remove duplicate import caused by false merge resoluton --- components/index.js | 6 ------ 1 file changed, 6 deletions(-) diff --git a/components/index.js b/components/index.js index e7fa9978..d92c3241 100644 --- a/components/index.js +++ b/components/index.js @@ -12,12 +12,6 @@ export { Repeater } from './repeater'; export { Link } from './link'; export { MediaToolbar } from './media-toolbar'; export { Image } from './image'; -export { - RichTextCharacterLimit, - getCharacterCount, - CircularProgressBar, - Counter, -} from './rich-text-character-limit'; export { PostContext } from './post-context'; export { PostTitle } from './post-title'; export { PostFeaturedImage } from './post-featured-image'; From 84216fc75e6435e160e77a3e04e182cb74ee7322 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20Ka=CC=88gy?= Date: Thu, 15 Dec 2022 13:31:53 +0100 Subject: [PATCH 045/112] ensure yoast SEO panel is hidden before running tests --- cypress/support/commands.js | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/cypress/support/commands.js b/cypress/support/commands.js index 941d7708..8961873b 100644 --- a/cypress/support/commands.js +++ b/cypress/support/commands.js @@ -58,6 +58,14 @@ Cypress.Commands.add('createPost', (options = {}) => { .contains(postType, { matchCase: false }) .click({ force: true }); + // close the Yoast SEO metabox + cy.get('.wpseo-metabox .handlediv').then(button => { + const isExpanded = button[0].getAttribute('aria-expanded') === 'true'; + if ( isExpanded ) { + cy.get('.wpseo-metabox .handlediv').click(); + } + }); + cy.wait(100); if (title !== '') { From 3e7848331b22e3e9def7040eb70b05fddbc65e6c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20Ka=CC=88gy?= Date: Mon, 9 Jan 2023 08:55:13 +0100 Subject: [PATCH 046/112] 1.14.4-alpha.0 --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 55900c39..73a3fd47 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@10up/block-components", - "version": "1.14.3", + "version": "1.14.4-alpha.0", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "@10up/block-components", - "version": "1.14.3", + "version": "1.14.4-alpha.0", "license": "GPL-2.0-or-later", "workspaces": [ "./", diff --git a/package.json b/package.json index 5df74065..52951207 100644 --- a/package.json +++ b/package.json @@ -3,7 +3,7 @@ "publishConfig": { "access": "public" }, - "version": "1.14.3", + "version": "1.14.4-alpha.0", "description": "10up Components built for the WordPress Block Editor.", "main": "./dist/index.js", "source": "index.js", From 424f4f1c7ba291220b8c9f4d405b4554aa20b581 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20Ka=CC=88gy?= Date: Mon, 9 Jan 2023 08:55:17 +0100 Subject: [PATCH 047/112] 1.14.4-alpha.1 --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 73a3fd47..5309d008 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@10up/block-components", - "version": "1.14.4-alpha.0", + "version": "1.14.4-alpha.1", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "@10up/block-components", - "version": "1.14.4-alpha.0", + "version": "1.14.4-alpha.1", "license": "GPL-2.0-or-later", "workspaces": [ "./", diff --git a/package.json b/package.json index 52951207..af8487de 100644 --- a/package.json +++ b/package.json @@ -3,7 +3,7 @@ "publishConfig": { "access": "public" }, - "version": "1.14.4-alpha.0", + "version": "1.14.4-alpha.1", "description": "10up Components built for the WordPress Block Editor.", "main": "./dist/index.js", "source": "index.js", From 55ec429c36feed0d462cfa7d56833ef205780a80 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20Ka=CC=88gy?= Date: Mon, 9 Jan 2023 08:55:18 +0100 Subject: [PATCH 048/112] 1.14.4-alpha.2 --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 5309d008..7703bb58 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@10up/block-components", - "version": "1.14.4-alpha.1", + "version": "1.14.4-alpha.2", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "@10up/block-components", - "version": "1.14.4-alpha.1", + "version": "1.14.4-alpha.2", "license": "GPL-2.0-or-later", "workspaces": [ "./", diff --git a/package.json b/package.json index af8487de..27076655 100644 --- a/package.json +++ b/package.json @@ -3,7 +3,7 @@ "publishConfig": { "access": "public" }, - "version": "1.14.4-alpha.1", + "version": "1.14.4-alpha.2", "description": "10up Components built for the WordPress Block Editor.", "main": "./dist/index.js", "source": "index.js", From ad24c3f76af0d4b33c90345849b9c0ee2d11f323 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20Ka=CC=88gy?= Date: Wed, 18 Jan 2023 07:57:58 +0100 Subject: [PATCH 049/112] 1.14.5-alpha.0 --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 87f748fa..09ecb8e4 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@10up/block-components", - "version": "1.14.4", + "version": "1.14.5-alpha.0", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "@10up/block-components", - "version": "1.14.4", + "version": "1.14.5-alpha.0", "license": "GPL-2.0-or-later", "workspaces": [ "./", diff --git a/package.json b/package.json index 2030b342..9ebf32a8 100644 --- a/package.json +++ b/package.json @@ -3,7 +3,7 @@ "publishConfig": { "access": "public" }, - "version": "1.14.4", + "version": "1.14.5-alpha.0", "description": "10up Components built for the WordPress Block Editor.", "main": "./dist/index.js", "source": "index.js", From a4564cf383416eb22034b233cfb4958b2ab84b56 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20Ka=CC=88gy?= Date: Wed, 18 Jan 2023 08:53:57 +0100 Subject: [PATCH 050/112] fix always register icons only when the browser is ready --- api/register-icons/index.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/api/register-icons/index.js b/api/register-icons/index.js index 3b2d8ed3..3200a327 100644 --- a/api/register-icons/index.js +++ b/api/register-icons/index.js @@ -1,7 +1,10 @@ import { dispatch } from '@wordpress/data'; +import domReady from '@wordpress/dom-ready'; import { iconStore } from '../../stores'; export function registerIcons(options) { - dispatch(iconStore).registerIconSet(options); + domReady(() => { + dispatch(iconStore).registerIconSet(options); + }); } From 2c877b39864f78469d8ba4097bae41eb2d8dc3bb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20Ka=CC=88gy?= Date: Wed, 18 Jan 2023 10:05:44 +0100 Subject: [PATCH 051/112] removed unused hook --- hooks/index.js | 1 - hooks/use-can-edit-entity/index.js | 17 ----------------- 2 files changed, 18 deletions(-) delete mode 100644 hooks/use-can-edit-entity/index.js diff --git a/hooks/index.js b/hooks/index.js index 9db31a91..35420c91 100644 --- a/hooks/index.js +++ b/hooks/index.js @@ -5,7 +5,6 @@ export { useFilteredList } from './use-filtered-list'; export { useMedia } from './use-media'; export { useBlockParentAttributes } from './use-block-parent-attributes'; export { usePost } from './use-post'; -export { useCanEditEntity } from './use-can-edit-entity'; export { useIsSupportedTaxonomy } from './use-is-supported-taxonomy'; export { useAllTerms } from './use-all-terms'; export { useSelectedTermIds } from './use-selected-term-ids'; diff --git a/hooks/use-can-edit-entity/index.js b/hooks/use-can-edit-entity/index.js deleted file mode 100644 index e917ceed..00000000 --- a/hooks/use-can-edit-entity/index.js +++ /dev/null @@ -1,17 +0,0 @@ -import { useSelect } from '@wordpress/data'; -import { store as coreStore } from '@wordpress/core-data'; - -/** - * Returns whether the current user can edit the given entity. - * - * @param {string} kind Entity kind. - * @param {string} name Entity name. - * @param {string} recordId Record's id. - */ - -export function useCanEditEntity(kind, name, recordId) { - return useSelect( - (select) => select(coreStore).canUserEditEntityRecord(kind, name, recordId), - [kind, name, recordId], - ); -} From 3c7c1546be2a53e8c824a547a5c95281c2dfd52e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20Ka=CC=88gy?= Date: Wed, 18 Jan 2023 10:06:21 +0100 Subject: [PATCH 052/112] add readme for useAllTerms hook --- hooks/use-all-terms/readme.md | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 hooks/use-all-terms/readme.md diff --git a/hooks/use-all-terms/readme.md b/hooks/use-all-terms/readme.md new file mode 100644 index 00000000..397f51db --- /dev/null +++ b/hooks/use-all-terms/readme.md @@ -0,0 +1,21 @@ +# `useAllTerms` + +The `useAllTerms` hook is a simple utility that makes it easy to get all terms from a taxonomy. + +## Usage + +```js +import { useAllTerms } from '@10up/block-components'; + +function BlockEdit(props) { + const [categories, hasResolvedCategories] = useAllTerms('category'); + + if ( ! hasResolvedCategories ) { + return + } + + return ( + ... + ); +} +``` From 0453c464d32dec78a37834f7217a7630107cd4f2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20Ka=CC=88gy?= Date: Wed, 18 Jan 2023 10:06:29 +0100 Subject: [PATCH 053/112] add readme for useIsPluginActive hook --- hooks/use-is-plugin-active/readme.md | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 hooks/use-is-plugin-active/readme.md diff --git a/hooks/use-is-plugin-active/readme.md b/hooks/use-is-plugin-active/readme.md new file mode 100644 index 00000000..dc6b6a5b --- /dev/null +++ b/hooks/use-is-plugin-active/readme.md @@ -0,0 +1,21 @@ +# `useIsPluginActive` + +The `useIsPluginActive` hook is a simple utility that returns whether or not a given plugin is activated. + +## Usage + +```js +import { useIsPluginActive } from '@10up/block-components'; + +function BlockEdit(props) { + const [isYoastSeoActive, hasResolvedIsPluginActive] = useIsPluginActive('wordpress-seo/wp-seo'); + + if ( ! hasResolvedIsPluginActive ) { + return + } + + return ( + ... + ); +} +``` From 0663e2b92af1bb291e586472c218f5c14f500d98 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20Ka=CC=88gy?= Date: Wed, 18 Jan 2023 10:09:50 +0100 Subject: [PATCH 054/112] add readme for useIsSupportedTaxonomy hook --- hooks/use-is-supported-taxonomy/readme.md | 26 +++++++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 hooks/use-is-supported-taxonomy/readme.md diff --git a/hooks/use-is-supported-taxonomy/readme.md b/hooks/use-is-supported-taxonomy/readme.md new file mode 100644 index 00000000..2c89dac8 --- /dev/null +++ b/hooks/use-is-supported-taxonomy/readme.md @@ -0,0 +1,26 @@ +# `useIsSupportedTaxonomy` + +The `useIsSupportedTaxonomy` hook is a simple utility that returns whether or not a given taxonomy is supported on a given post type. + +## Usage + +```js +import { useIsSupportedTaxonomy } from '@10up/block-components'; + +function BlockEdit(props) { + const { context } = props; + const { postType } = context; + const [isSupportingCategoryTaxonomy, hasResolvedIsSupportingCategoryTaxonomy] = useIsSupportedTaxonomy( + postType, + 'category', + ); + + if ( ! hasResolvedIsSupportingCategoryTaxonomy ) { + return + } + + return ( + ... + ); +} +``` From 74528d0f45183703e66a29bd711bcd2e0c9c82c2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20Ka=CC=88gy?= Date: Wed, 18 Jan 2023 10:13:31 +0100 Subject: [PATCH 055/112] add readme for usePopover hook --- hooks/use-popover/readme.md | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 hooks/use-popover/readme.md diff --git a/hooks/use-popover/readme.md b/hooks/use-popover/readme.md new file mode 100644 index 00000000..18da8304 --- /dev/null +++ b/hooks/use-popover/readme.md @@ -0,0 +1,24 @@ +# `usePopover` + +The `usePopover` hook is a simple utility allows you to easily add Popovers to any element. + +## Usage + +```js +import { usePopover } from '@10up/block-components'; + +function BlockEdit(props) { + const { toggleProps, Popover } = usePopover(); + + return ( + <> + + + I'm rendered inside a Popover + + + ); +} +``` From 7d77118a35075d442f4ce17465dd7c8990b362d5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20Ka=CC=88gy?= Date: Wed, 18 Jan 2023 10:18:15 +0100 Subject: [PATCH 056/112] add readme to usePost hook --- hooks/use-post/readme.md | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 hooks/use-post/readme.md diff --git a/hooks/use-post/readme.md b/hooks/use-post/readme.md new file mode 100644 index 00000000..b22ac247 --- /dev/null +++ b/hooks/use-post/readme.md @@ -0,0 +1,21 @@ +# `usePost` + +The `usePost` hook allows you to get information about the current post. It either references the global post, or when used within a [``](../../components/post-context/) it reference that post. + +## Usage + +```js +import { usePost } from '@10up/block-components'; + +function BlockEdit(props) { + const { + postId, + postType, + isEditable + } = usePost(); + + return ( + ... + ); +} +``` From 7fc3e900e5f5d24459690056607f9b6d5256e156 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20Ka=CC=88gy?= Date: Wed, 18 Jan 2023 11:01:50 +0100 Subject: [PATCH 057/112] add readme for usePrimaryTerm hook --- hooks/use-primary-term/readme.md | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 hooks/use-primary-term/readme.md diff --git a/hooks/use-primary-term/readme.md b/hooks/use-primary-term/readme.md new file mode 100644 index 00000000..7d701c2c --- /dev/null +++ b/hooks/use-primary-term/readme.md @@ -0,0 +1,20 @@ +# `usePrimaryTerm` + +The `usePrimaryTerm` hook allows you to get information about the current post. It either references the global post, or when used within a [``](../../components/post-context/) it reference that post. + +> **Warning** +> This hook will not function without having [Yoast SEO](https://wordpress.org/plugins/wordpress-seo/) installed and activated. + +## Usage + +```js +import { usePrimaryTerm } from '@10up/block-components'; + +function BlockEdit(props) { + const [primaryCategory, isSupportingCategory] = usePrimaryTerm('category'); + + return ( + ... + ); +} +``` From 4f0f198205c3a202850c5fd99c0254935bbc0e4c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20Ka=CC=88gy?= Date: Wed, 18 Jan 2023 11:04:35 +0100 Subject: [PATCH 058/112] fix description of usePrimaryTerm readme --- hooks/use-primary-term/readme.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hooks/use-primary-term/readme.md b/hooks/use-primary-term/readme.md index 7d701c2c..914bd8a5 100644 --- a/hooks/use-primary-term/readme.md +++ b/hooks/use-primary-term/readme.md @@ -1,6 +1,6 @@ # `usePrimaryTerm` -The `usePrimaryTerm` hook allows you to get information about the current post. It either references the global post, or when used within a [``](../../components/post-context/) it reference that post. +The `usePrimaryTerm` hook retrieves the primary term of any given taxonomy. > **Warning** > This hook will not function without having [Yoast SEO](https://wordpress.org/plugins/wordpress-seo/) installed and activated. From ee459e10034c57b95923559fb4771d2c2b7e174c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20Ka=CC=88gy?= Date: Wed, 18 Jan 2023 11:07:36 +0100 Subject: [PATCH 059/112] add readme for useSelectedTermIds hook --- hooks/use-selected-term-ids/readme.md | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 hooks/use-selected-term-ids/readme.md diff --git a/hooks/use-selected-term-ids/readme.md b/hooks/use-selected-term-ids/readme.md new file mode 100644 index 00000000..44d9025b --- /dev/null +++ b/hooks/use-selected-term-ids/readme.md @@ -0,0 +1,17 @@ +# `useSelectedTermIds` + +The `useSelectedTermIds` hook retrieves ids of the selected terms of the provided taxonomy. It gets used internally by the [`useSelectedTerms`](../use-selected-terms/) hook which is a more full featured version of this hook. + +## Usage + +```js +import { useSelectedTermIds } from '@10up/block-components'; + +function BlockEdit(props) { + const [selectedCategoryIds, hasResolvedSelectedCategoryIds] = useSelectedTermIds('category'); + + return ( + ... + ); +} +``` From 7b91d9c8f30e4515b7d22f7b8cdfbb325b0e8e5d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20Ka=CC=88gy?= Date: Wed, 18 Jan 2023 11:09:13 +0100 Subject: [PATCH 060/112] add readme for useSelectedTerms hook --- hooks/use-selected-terms/readme.md | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 hooks/use-selected-terms/readme.md diff --git a/hooks/use-selected-terms/readme.md b/hooks/use-selected-terms/readme.md new file mode 100644 index 00000000..cc981f08 --- /dev/null +++ b/hooks/use-selected-terms/readme.md @@ -0,0 +1,17 @@ +# `useSelectedTerms` + +The `useSelectedTerms` hook retrieves the term objects of the selected terms of the provided taxonomy. + +## Usage + +```js +import { useSelectedTerms } from '@10up/block-components'; + +function BlockEdit(props) { + const [selectedCategories, hasResolvedSelectedCategories] = useSelectedTerms('category'); + + return ( + ... + ); +} +``` From d4bee9aaa1d46a84b2a79f076c49287d92347fd4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20Ka=CC=88gy?= Date: Wed, 18 Jan 2023 11:11:32 +0100 Subject: [PATCH 061/112] add readme for useSelectedTermsOfSavedPost hook --- .../readme.md | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 hooks/use-selected-terms-of-saved-post/readme.md diff --git a/hooks/use-selected-terms-of-saved-post/readme.md b/hooks/use-selected-terms-of-saved-post/readme.md new file mode 100644 index 00000000..e23a49e4 --- /dev/null +++ b/hooks/use-selected-terms-of-saved-post/readme.md @@ -0,0 +1,20 @@ +# `useSelectedTermsOfSavedPost` + +The `useSelectedTermsOfSavedPost` hook retrieves the ids of the selected terms of the provided taxonomy. It gets used internally by the [`useSelectedTerms`](../use-selected-terms/) hook which is a more full featured version of this hook. + +## Usage + +```js +import { useSelectedTermsOfSavedPost } from '@10up/block-components'; + +function BlockEdit(props) { + const { context } = props; + const { postId } = context; + const [selectedCategoriesOfSavedPost, hasResolvedSelectedCategoriesOfSavedPost] = + useSelectedTermsOfSavedPost('category', postId); + + return ( + ... + ); +} +``` From 8e3b28eb66dcfc08c533c86182264835a2dbb381 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20Ka=CC=88gy?= Date: Wed, 18 Jan 2023 11:33:16 +0100 Subject: [PATCH 062/112] fix Author components markup --- components/author/index.js | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/components/author/index.js b/components/author/index.js index b191a1e0..a48ee10e 100644 --- a/components/author/index.js +++ b/components/author/index.js @@ -95,7 +95,7 @@ function useDefaultAvatar() { } export const Avatar = (props) => { - const { tagName: TagName = 'img', ...rest } = props; + const { ...rest } = props; /** * @type {Author} @@ -107,15 +107,7 @@ export const Avatar = (props) => { const avatarSourceUrl = avatarUrls ? avatarUrls[avatarUrls.length - 1] : defaultAvatar; - return ; -}; - -Avatar.propTypes = { - tagName: PropTypes.string, -}; - -Avatar.defaultProps = { - tagName: 'img', + return ; }; export const Bio = (props) => { From e116fc815c563e3dc2b28415a956705ce24fe78e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20Ka=CC=88gy?= Date: Wed, 18 Jan 2023 11:33:27 +0100 Subject: [PATCH 063/112] add more docs to PostAuthor component --- components/post-author/readme.md | 67 +++++++++++++++++++++++++++++++- 1 file changed, 65 insertions(+), 2 deletions(-) diff --git a/components/post-author/readme.md b/components/post-author/readme.md index 309c928c..63c2f009 100644 --- a/components/post-author/readme.md +++ b/components/post-author/readme.md @@ -1,5 +1,9 @@ # PostAuthor +The `PostAuthor` component is part of the suite of components that read / write data from the global post object or the current [``](../post-context/). It has a composable declarative approach to allow you full control over the markup without needing to worry about the data handling at all. + +The Component allows you to showcase information about the author of the current post. + ## Usage ```js @@ -10,8 +14,8 @@ function BlockEdit() { return ( - - + + @@ -28,14 +32,73 @@ function BlockEdit() { ## Child Components +You can use this component in three different ways. Without any children it will just return some default markup containing the name of the author. Alternatively you can pass a render function as the children. This render function will get the author object passed into it. The third option is using the provided sub-components as shown in the example code. Each of these child component again automatically manages the data and allows you to just focus on the markup. + +## Sub-Components + +These are all the available sub-components of the `PostAuthor` component. + ### `PostAuthor.Name` +Returns the full name of the Author + +#### Props + +| Name | Type | Default | Description | +| ---------- | ----------------- | -------- | -------------------------------------------------------------- | +| `tagName` | `string` | `span` | the tag name that should be used for the element | +| `...rest` | `object` | `{}` | | + ### `PostAuthor.FirstName` +Returns the first name of the Author + +#### Props + +| Name | Type | Default | Description | +| ---------- | ----------------- | -------- | +-------------------------------------------------------------- | +| `tagName` | `string` | `span` | the tag name that should be used for the element | +| `...rest` | `object` | `{}` | | + ### `PostAuthor.LastName` +Returns the last name of the Author + +#### Props + +| Name | Type | Default | Description | +| ---------- | ----------------- | -------- | -------------------------------------------------------------- | +| `tagName` | `string` | `span` | the tag name that should be used for the element | +| `...rest` | `object` | `{}` | | + ### `PostAuthor.Avatar` +Returns the avatar image of the Author + +#### Props + +| Name | Type | Default | Description | +| ---------- | ----------------- | -------- | -------------------------------------------------------------- | +| `...rest` | `object` | `{}` | | + ### `PostAuthor.Bio` +Returns the bio of the Author + +#### Props + +| Name | Type | Default | Description | +| ---------- | ----------------- | -------- | -------------------------------------------------------------- | +| `tagName` | `string` | `p` | the tag name that should be used for the element | +| `...rest` | `object` | `{}` | | + ### `PostAuthor.Email` + +Returns the email of the Author + +#### Props + +| Name | Type | Default | Description | +| ---------- | ----------------- | -------- | -------------------------------------------------------------- | +| `...rest` | `object` | `{}` | | From a9b9d427d2f6b575e6b2cfaf7e38bd36762eff2d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20Ka=CC=88gy?= Date: Wed, 18 Jan 2023 11:47:12 +0100 Subject: [PATCH 064/112] add more detailed docs --- components/post-category-list/readme.md | 5 ++++ components/post-context/readme.md | 29 ++++++++++++++++++++++ components/post-date/readme.md | 4 +++ components/post-excerpt/readme.md | 4 +++ components/post-featured-image/readme.md | 4 +++ components/post-primary-category/readme.md | 5 ++++ components/post-primary-term/readme.md | 4 +++ components/post-term-list/readme.md | 4 +++ components/post-title/readme.md | 4 +++ 9 files changed, 63 insertions(+) create mode 100644 components/post-category-list/readme.md create mode 100644 components/post-context/readme.md diff --git a/components/post-category-list/readme.md b/components/post-category-list/readme.md new file mode 100644 index 00000000..46bbc39a --- /dev/null +++ b/components/post-category-list/readme.md @@ -0,0 +1,5 @@ +# `PostCategoryList` + +The `PostCategoryList` component is part of the suite of components that read / write data from the global post object or the current [``](../post-context/). It has a composable declarative approach to allow you full control over the markup without needing to worry about the data handling at all. + +The Component allows you to showcase the list of Categories assigned to the current post diff --git a/components/post-context/readme.md b/components/post-context/readme.md new file mode 100644 index 00000000..c24fcd05 --- /dev/null +++ b/components/post-context/readme.md @@ -0,0 +1,29 @@ +# `PostContext` + +The `PostContext` component allows you to customize the post object referenced by and of the components referencing the current post object. They are all prefixed with `Post`. + +For example this can be used to build a custom block that gets used inside the core query loop and accesses the passed in post id / post type of that to power the functionality of all the `Post` child components. + +## Usage + +```js +import { PostContext, PostTitle } from '@10up/block-components'; + +function BlockEdit() { + + return ( + + + + ) +} +``` + +## Props + +| Name | Type | Default | Description | +| ---------- | ----------------- | -------- | -------------------------------------------------------------- | +| `postId` | `number` | `null` | ID of the post | +| `postType` | `string` | `null` | post type of the post | +| `isEditable` | `boolean` | `null` | whether the post is editable. Controls the behavior of the nested `Post` components | +| `children` | `node` | `null` | any child components | diff --git a/components/post-date/readme.md b/components/post-date/readme.md index d8182679..accf1d71 100644 --- a/components/post-date/readme.md +++ b/components/post-date/readme.md @@ -1,5 +1,9 @@ # Post Date +The `PostDate` component is part of the suite of components that read/write data from the global post object or the current [``](../post-context/). It has a composable declarative approach to allow you full control over the markup without needing to worry about the data handling at all. + +The Component allows you to showcase the publish date of the current post. + ## Usage ```js diff --git a/components/post-excerpt/readme.md b/components/post-excerpt/readme.md index 5914437d..388779c4 100644 --- a/components/post-excerpt/readme.md +++ b/components/post-excerpt/readme.md @@ -1,5 +1,9 @@ # Post Excerpt +The `PostExcerpt` component is part of the suite of components that read/write data from the global post object or the current [``](../post-context/). It has a composable declarative approach to allow you full control over the markup without needing to worry about the data handling at all. + +The Component allows you to showcase the excerpt of the current post. + ## Usage ```js diff --git a/components/post-featured-image/readme.md b/components/post-featured-image/readme.md index 66e2d62b..e236934f 100644 --- a/components/post-featured-image/readme.md +++ b/components/post-featured-image/readme.md @@ -1,5 +1,9 @@ # Post Featured Image +The `PostFeaturedImage` component is part of the suite of components that read/write data from the global post object or the current [``](../post-context/). It has a composable declarative approach to allow you full control over the markup without needing to worry about the data handling at all. + +The Component allows you to showcase the featured image of the current post. + ## Usage ```js diff --git a/components/post-primary-category/readme.md b/components/post-primary-category/readme.md index e69de29b..2dc797ca 100644 --- a/components/post-primary-category/readme.md +++ b/components/post-primary-category/readme.md @@ -0,0 +1,5 @@ +# `PostPrimaryCategory` + +The `PostPrimaryCategory` component is part of the suite of components that read/write data from the global post object or the current [``](../post-context/). It has a composable declarative approach to allow you full control over the markup without needing to worry about the data handling at all. + +The Component allows you to showcase the primary category of the current post. It relies on the Primary Term feature provided by the Yoast SEO plugin. diff --git a/components/post-primary-term/readme.md b/components/post-primary-term/readme.md index f36d98df..9fd75563 100644 --- a/components/post-primary-term/readme.md +++ b/components/post-primary-term/readme.md @@ -1,4 +1,8 @@ # PostPrimaryTerm +The `PostPrimaryTerm` component is part of the suite of components that read/write data from the global post object or the current [``](../post-context/). It has a composable declarative approach to allow you full control over the markup without needing to worry about the data handling at all. + +The Component allows you to showcase the primary term of any taxonomy of the current post. + > **Warning** > This Component depends on the Primary Term functionality of the Yoast SEO Plugin diff --git a/components/post-term-list/readme.md b/components/post-term-list/readme.md index fafda1a8..b697adc6 100644 --- a/components/post-term-list/readme.md +++ b/components/post-term-list/readme.md @@ -1,5 +1,9 @@ # PostTermList +The `PostTermList` component is part of the suite of components that read/write data from the global post object or the current [``](../post-context/). It has a composable declarative approach to allow you full control over the markup without needing to worry about the data handling at all. + +The Component allows you to showcase a list of the selected terms of the provided taxonomy of the current post. + ## Usage ```js diff --git a/components/post-title/readme.md b/components/post-title/readme.md index eae03efb..6c56ee52 100644 --- a/components/post-title/readme.md +++ b/components/post-title/readme.md @@ -1,5 +1,9 @@ # Post Title +The `PostTitle` component is part of the suite of components that read/write data from the global post object or the current [``](../post-context/). It has a composable declarative approach to allow you full control over the markup without needing to worry about the data handling at all. + +The Component allows you to showcase the title of any taxonomy of the current post. + ## Usage ```js From 5058d5322a990bc1605d51153c7f13b84b70c333 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20Ka=CC=88gy?= Date: Wed, 18 Jan 2023 11:57:40 +0100 Subject: [PATCH 065/112] add new hooks and components to main readme --- README.md | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/README.md b/README.md index 3558c906..a14f283e 100644 --- a/README.md +++ b/README.md @@ -37,6 +37,21 @@ A collection of components built to be used in the block editor. These component - [Repeater](./components/repeater/) - [RichTextCharacterLimit](./components/rich-text-character-limit) +### Post related Components + +These components read/write information from the global post object or a `PostContext`. + +- [PostAuthor](./components/post-author/) +- [PostCategoryList](./components/post-category-list/) +- [PostContext](./components/post-context/) +- [PostDate](./components/post-date) +- [PostExcerpt](./components/post-excerpt/) +- [PostFeaturedImage](./components/post-featured-image/) +- [PostPrimaryCategory](./components/post-primary-category/) +- [PostPrimaryTerm](./components/post-primary-term/) +- [PostTermList](./components/post-term-list/) +- [PostTitle](./components/post-title/) + ## Hooks - [useFilteredList](./hooks/use-filtered-list) @@ -46,6 +61,20 @@ A collection of components built to be used in the block editor. These component - [useRequestData](./hooks/use-request-data/) - [useBlockParentAttributes](./hooks/use-block-parent-attributes/) - [useScript](./hooks/use-script/) +- [useIsPluginActive](./hooks/use-is-plugin-active/) +- [usePopover](./hooks/use-popover/) + +### Post related hooks + +These hooks read/write information from the global post object or a `PostContext`. + +- [useAllTerms](./hooks/use-all-terms/) +- [useIsSupportedTaxonomy](./hooks/use-is-supported-taxonomy/) +- [usePost](./hooks/use-post/) +- [usePrimaryTerm](./hooks/use-primary-term/) +- [useSelectedTermIds](./hooks/use-selected-term-ids/) +- [useSelectedTerms](./hooks/use-selected-terms/) +- [useSelectedTermsOfSavedPost](./hooks/use-selected-terms-of-saved-post/) ## Stores From f8eeed6d4da30ded86f79abbdd865b3fd884871e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20Ka=CC=88gy?= Date: Wed, 18 Jan 2023 11:59:17 +0100 Subject: [PATCH 066/112] fix formatting in readme --- components/post-author/readme.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/components/post-author/readme.md b/components/post-author/readme.md index 63c2f009..3f2f72c8 100644 --- a/components/post-author/readme.md +++ b/components/post-author/readme.md @@ -56,8 +56,7 @@ Returns the first name of the Author #### Props | Name | Type | Default | Description | -| ---------- | ----------------- | -------- | --------------------------------------------------------------- | +| ---------- | ----------------- | -------- | -------------------------------------------------------------- | | `tagName` | `string` | `span` | the tag name that should be used for the element | | `...rest` | `object` | `{}` | | From d6d96a437002aab6a9ce8855dab4cbfe4c08c6a3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20Ka=CC=88gy?= Date: Wed, 18 Jan 2023 12:01:13 +0100 Subject: [PATCH 067/112] add more detail to PostCategoryList readme --- components/post-category-list/readme.md | 42 +++++++++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/components/post-category-list/readme.md b/components/post-category-list/readme.md index 46bbc39a..b148ec29 100644 --- a/components/post-category-list/readme.md +++ b/components/post-category-list/readme.md @@ -3,3 +3,45 @@ The `PostCategoryList` component is part of the suite of components that read / write data from the global post object or the current [``](../post-context/). It has a composable declarative approach to allow you full control over the markup without needing to worry about the data handling at all. The Component allows you to showcase the list of Categories assigned to the current post + +## Usage + +```js +import { PostCategoryList } from '@10up/block-components'; + +function BlockEdit() { + + return ( + + + + + + ) +} +``` + +### Output + +```html + +``` + +## Props + +| Name | Type | Default | Description | +| ---------- | ----------------- | -------- | -------------------------------------------------------------- | +| `context` | `object` | `{}` | | +| `children` | `function\|node\|null` | `null` | | +| `tagName` | `string` | `ul` | | +| `...rest` | `object` | `{}` | | + +## Child Components + +### `PostCategoryList.ListItem` + +### `PostCategoryList.TermLink` From c3b0b2d960e91868aebad06f09249ee7a8d64022 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20Ka=CC=88gy?= Date: Wed, 18 Jan 2023 12:03:22 +0100 Subject: [PATCH 068/112] add more context --- components/post-category-list/readme.md | 6 ++++++ components/post-term-list/readme.md | 6 ++++++ 2 files changed, 12 insertions(+) diff --git a/components/post-category-list/readme.md b/components/post-category-list/readme.md index b148ec29..b7201596 100644 --- a/components/post-category-list/readme.md +++ b/components/post-category-list/readme.md @@ -42,6 +42,12 @@ function BlockEdit() { ## Child Components +You can use this component in three different ways. Without any children it will just return some default markup containing the name of the category. Alternatively you can pass a render function as the children. This render function will get the category object passed into it. The third option is using the provided sub-components as shown in the example code. Each of these child component again automatically manages the data and allows you to just focus on the markup. + +## Sub-Components + +These are all the available sub-components of the `PostCategoryList` component. + ### `PostCategoryList.ListItem` ### `PostCategoryList.TermLink` diff --git a/components/post-term-list/readme.md b/components/post-term-list/readme.md index b697adc6..a7e279e5 100644 --- a/components/post-term-list/readme.md +++ b/components/post-term-list/readme.md @@ -43,6 +43,12 @@ function BlockEdit() { ## Child Components +You can use this component in three different ways. Without any children it will just return some default markup containing the name of the term. Alternatively you can pass a render function as the children. This render function will get the term object passed into it. The third option is using the provided sub-components as shown in the example code. Each of these child component again automatically manages the data and allows you to just focus on the markup. + +## Sub-Components + +These are all the available sub-components of the `PostTermList` component. + ### `PostTermList.ListItem` ### `PostTermList.TermLink` From d9e99dcaada6dc9d0c61895603977097b5e4eb77 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20Ka=CC=88gy?= Date: Wed, 18 Jan 2023 12:04:14 +0100 Subject: [PATCH 069/112] Add yoast warning --- components/post-primary-category/readme.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/components/post-primary-category/readme.md b/components/post-primary-category/readme.md index 2dc797ca..86bb2405 100644 --- a/components/post-primary-category/readme.md +++ b/components/post-primary-category/readme.md @@ -3,3 +3,6 @@ The `PostPrimaryCategory` component is part of the suite of components that read/write data from the global post object or the current [``](../post-context/). It has a composable declarative approach to allow you full control over the markup without needing to worry about the data handling at all. The Component allows you to showcase the primary category of the current post. It relies on the Primary Term feature provided by the Yoast SEO plugin. + +> **Warning** +> This Component depends on the Primary Term functionality of the Yoast SEO Plugin From ddf08fe319d5054b505578f7c00c3fc9e594c8ef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20Ka=CC=88gy?= Date: Wed, 25 Jan 2023 07:59:28 +0100 Subject: [PATCH 070/112] 1.14.6-alpha.0 --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 5628ff53..9ba63715 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@10up/block-components", - "version": "1.14.5", + "version": "1.14.6-alpha.0", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "@10up/block-components", - "version": "1.14.5", + "version": "1.14.6-alpha.0", "license": "GPL-2.0-or-later", "workspaces": [ "./", diff --git a/package.json b/package.json index c52ae9ba..bba6cdc9 100644 --- a/package.json +++ b/package.json @@ -3,7 +3,7 @@ "publishConfig": { "access": "public" }, - "version": "1.14.5", + "version": "1.14.6-alpha.0", "description": "10up Components built for the WordPress Block Editor.", "main": "./dist/index.js", "source": "index.js", From 45e80cf532b708f079996d7ae9d791453ef9a24a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20Ka=CC=88gy?= Date: Wed, 25 Jan 2023 08:32:24 +0100 Subject: [PATCH 071/112] add docs for subcomponents of post term list --- components/post-category-list/readme.md | 17 +++++++++++++++++ components/post-term-list/readme.md | 17 +++++++++++++++++ 2 files changed, 34 insertions(+) diff --git a/components/post-category-list/readme.md b/components/post-category-list/readme.md index b7201596..e0485076 100644 --- a/components/post-category-list/readme.md +++ b/components/post-category-list/readme.md @@ -50,4 +50,21 @@ These are all the available sub-components of the `PostCategoryList` component. ### `PostCategoryList.ListItem` +Returns the list item markup + +#### Props + +| Name | Type | Default | Description | +| ---------- | ----------------- | -------- | -------------------------------------------------------------- | +| `tagName` | `string` | `li` | the tag name that should be used for the element | +| `...rest` | `object` | `{}` | | + ### `PostCategoryList.TermLink` + +Returns the anchor element containing the title of the term + +#### Props + +| Name | Type | Default | Description | +| ---------- | ----------------- | -------- | -------------------------------------------------------------- | +| `...rest` | `object` | `{}` | | diff --git a/components/post-term-list/readme.md b/components/post-term-list/readme.md index a7e279e5..921f88d6 100644 --- a/components/post-term-list/readme.md +++ b/components/post-term-list/readme.md @@ -51,4 +51,21 @@ These are all the available sub-components of the `PostTermList` component. ### `PostTermList.ListItem` +Returns the list item markup + +#### Props + +| Name | Type | Default | Description | +| ---------- | ----------------- | -------- | -------------------------------------------------------------- | +| `tagName` | `string` | `li` | the tag name that should be used for the element | +| `...rest` | `object` | `{}` | | + ### `PostTermList.TermLink` + +Returns the anchor element containing the title of the term + +#### Props + +| Name | Type | Default | Description | +| ---------- | ----------------- | -------- | -------------------------------------------------------------- | +| `...rest` | `object` | `{}` | | From 4ecfaa8d9ed5ba5b79be0161a40ed322e1a82384 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20Ka=CC=88gy?= Date: Wed, 25 Jan 2023 08:37:53 +0100 Subject: [PATCH 072/112] expand documentation of PostContext component --- components/post-context/readme.md | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/components/post-context/readme.md b/components/post-context/readme.md index c24fcd05..8785c143 100644 --- a/components/post-context/readme.md +++ b/components/post-context/readme.md @@ -19,6 +19,24 @@ function BlockEdit() { } ``` +The `PostContext` component works great with the Core Query Loop block if you want / need to create a custom block to be used within the post template. Any block that gets used inside the query loop can access the current post id, post type, and query id via the block context. These values can then be used within the `` to make them available for any of the post level components nested within. + +```js +import { PostContext, PostTitle } from '@10up/block-components'; + +function BlockEdit(props) { + const { context } = props; + const { postId, postType, queryId } = context; + const isDescendantOfQueryLoop = Number.isFinite(queryId); + + return ( + + + + ) +} +``` + ## Props | Name | Type | Default | Description | From 1469ac6982599174130a5c22b777dc9a12c22958 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20Ka=CC=88gy?= Date: Wed, 25 Jan 2023 08:41:49 +0100 Subject: [PATCH 073/112] add more context to post context docs --- components/post-context/readme.md | 4 ++++ images/block-editor-unsaved-external-change.png | Bin 0 -> 17247 bytes 2 files changed, 4 insertions(+) create mode 100644 images/block-editor-unsaved-external-change.png diff --git a/components/post-context/readme.md b/components/post-context/readme.md index 8785c143..e0746b93 100644 --- a/components/post-context/readme.md +++ b/components/post-context/readme.md @@ -37,6 +37,10 @@ function BlockEdit(props) { } ``` +*Note: If you enable `isEditable` prop in the `` component for posts that aren't the current post this will actually update the external post. This should be used with caution since it may not be immediately obvious for users.* + +![Block Editor Save button showing an indicator for unsaved external changes](../../images/block-editor-unsaved-external-change.png) + ## Props | Name | Type | Default | Description | diff --git a/images/block-editor-unsaved-external-change.png b/images/block-editor-unsaved-external-change.png new file mode 100644 index 0000000000000000000000000000000000000000..a297551295ada20f71ecd6e0e2b023a70ac2afc4 GIT binary patch literal 17247 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 literal 0 HcmV?d00001 From 536ff2587f91346fb86aafc5af49cd3dbe1c7aee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20Ka=CC=88gy?= Date: Wed, 25 Jan 2023 08:44:02 +0100 Subject: [PATCH 074/112] add more context to post featured image component --- components/post-featured-image/readme.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/post-featured-image/readme.md b/components/post-featured-image/readme.md index e236934f..65a55611 100644 --- a/components/post-featured-image/readme.md +++ b/components/post-featured-image/readme.md @@ -2,7 +2,7 @@ The `PostFeaturedImage` component is part of the suite of components that read/write data from the global post object or the current [``](../post-context/). It has a composable declarative approach to allow you full control over the markup without needing to worry about the data handling at all. -The Component allows you to showcase the featured image of the current post. +The Component allows you to showcase the featured image of the current post. It uses the [`Image`](../image/) component under the hood but handles all the selection/image management logic. ## Usage From 32cdfa1ca1a01c24d984a65975b9ace24385331c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20Ka=CC=88gy?= Date: Wed, 25 Jan 2023 10:32:50 +0100 Subject: [PATCH 075/112] fix issue in title component readme --- components/post-title/readme.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/post-title/readme.md b/components/post-title/readme.md index 6c56ee52..39670f5a 100644 --- a/components/post-title/readme.md +++ b/components/post-title/readme.md @@ -2,7 +2,7 @@ The `PostTitle` component is part of the suite of components that read/write data from the global post object or the current [``](../post-context/). It has a composable declarative approach to allow you full control over the markup without needing to worry about the data handling at all. -The Component allows you to showcase the title of any taxonomy of the current post. +The Component allows you to showcase the title of the current post. ## Usage From 5c85a967c03c786df9e0f1e00e4d1f6a412965b9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20Ka=CC=88gy?= Date: Wed, 25 Jan 2023 10:45:31 +0100 Subject: [PATCH 076/112] add PostMeta component --- README.md | 2 + components/index.js | 1 + components/post-meta/index.js | 67 ++++++++++++++++++++++++++ components/post-meta/readme.md | 75 +++++++++++++++++++++++++++++ components/post-meta/utilities.js | 45 +++++++++++++++++ hooks/index.js | 1 + hooks/use-post-meta-value/index.js | 17 +++++++ hooks/use-post-meta-value/readme.md | 17 +++++++ 8 files changed, 225 insertions(+) create mode 100644 components/post-meta/index.js create mode 100644 components/post-meta/readme.md create mode 100644 components/post-meta/utilities.js create mode 100644 hooks/use-post-meta-value/index.js create mode 100644 hooks/use-post-meta-value/readme.md diff --git a/README.md b/README.md index a14f283e..3ee2c565 100644 --- a/README.md +++ b/README.md @@ -51,6 +51,7 @@ These components read/write information from the global post object or a `PostCo - [PostPrimaryTerm](./components/post-primary-term/) - [PostTermList](./components/post-term-list/) - [PostTitle](./components/post-title/) +- [PostMeta](./components/post-meta/) ## Hooks @@ -75,6 +76,7 @@ These hooks read/write information from the global post object or a `PostContext - [useSelectedTermIds](./hooks/use-selected-term-ids/) - [useSelectedTerms](./hooks/use-selected-terms/) - [useSelectedTermsOfSavedPost](./hooks/use-selected-terms-of-saved-post/) +- [usePostMetaValue](./hooks/use-post-meta-value/) ## Stores diff --git a/components/index.js b/components/index.js index d92c3241..fa74a066 100644 --- a/components/index.js +++ b/components/index.js @@ -15,6 +15,7 @@ export { Image } from './image'; export { PostContext } from './post-context'; export { PostTitle } from './post-title'; export { PostFeaturedImage } from './post-featured-image'; +export { PostMeta } from './post-meta'; export { PostExcerpt } from './post-excerpt'; export { PostAuthor } from './post-author'; export { PostDate, PostDatePicker } from './post-date'; diff --git a/components/post-meta/index.js b/components/post-meta/index.js new file mode 100644 index 00000000..e882ab8c --- /dev/null +++ b/components/post-meta/index.js @@ -0,0 +1,67 @@ +import { RichText } from '@wordpress/block-editor'; +import { __experimentalNumberControl as NumberControl, ToggleControl } from '@wordpress/components'; +import PropTypes from 'prop-types'; +import { usePostMetaValue } from '../../hooks'; +import { toSentence } from './utilities'; + +export const PostMeta = (props) => { + const { metaKey } = props; + const [metaValue] = usePostMetaValue(metaKey); + const metaValueType = typeof metaValue; + + if (metaValueType === 'number') { + return ; + } + + if (metaValueType === 'boolean') { + return ; + } + + return ; +}; + +PostMeta.propTypes = { + metaKey: PropTypes.string.isRequired, +}; + +const MetaString = (props) => { + const { metaKey, tagName = 'p' } = props; + const [metaValue, setMetaValue] = usePostMetaValue(metaKey); + + return ; +}; + +MetaString.propTypes = { + metaKey: PropTypes.string.isRequired, + tagName: PropTypes.string, +}; + +MetaString.defaultProps = { + tagName: 'p', +}; + +const MetaNumber = (props) => { + const { metaKey } = props; + const [metaValue, setMetaValue] = usePostMetaValue(metaKey); + + return ; +}; + +MetaNumber.propTypes = { + metaKey: PropTypes.string.isRequired, +}; + +const MetaBoolean = (props) => { + const { metaKey } = props; + const [metaValue, setMetaValue] = usePostMetaValue(metaKey); + + return ; +}; + +MetaBoolean.propTypes = { + metaKey: PropTypes.string.isRequired, +}; + +PostMeta.String = MetaString; +PostMeta.Number = MetaNumber; +PostMeta.Boolean = MetaBoolean; diff --git a/components/post-meta/readme.md b/components/post-meta/readme.md new file mode 100644 index 00000000..d3f80121 --- /dev/null +++ b/components/post-meta/readme.md @@ -0,0 +1,75 @@ +# Post Meta + +The `PostMeta` component is part of the suite of components that read/write data from the global post object or the current [``](../post-context/). It has a composable declarative approach to allow you full control over the markup without needing to worry about the data handling at all. + +The Component allows you to showcase any piece of post-meta information of the current post. + +> **Warning** +> In order for the Meta Value to show up it needs to be registered properly and have `show_in_rest` set to `true`. + +## Usage + +```js +import { PostMeta } from '@10up/block-components'; + +function BlockEdit() { + + return ( + + ) +} +``` + +The component automatically tries to figure out the type of the meta value and dynamically displays either a text field, number control, or a toggle control. + +If you want to override this automatic type casting you can use the sub-components which expose the underlying type controls. + +> **Warning** +> Currently only `string`, `number`, `boolean` for `single` meta values are supported. + +## Props + +| Name | Type | Default | Description | +| ---------- | ----------------- | -------- | -------------------------------------------------------------- | +| `metaKey` | `string` | `""` | name of the meta key | +| `...rest` | `object` | `{}` | | + +## Sub-components + +This component contains a few sub-components which relate to the various types a piece of meta can be represented as. + +### `PostMeta.String` + +Control string meta values + +#### Props + +| Name | Type | Default | Description | +| ---------- | ----------------- | -------- | -------------------------------------------------------------- | +| `metaKey` | `string` | `""` | name of the meta key | +| `tagName` | `string` | `p` | tagName to be used by the underlying RichText field | +| `...rest` | `object` | `{}` | | + +### `PostMeta.Number` + +Control number meta values + +#### Props + +| Name | Type | Default | Description | +| ---------- | ----------------- | -------- | -------------------------------------------------------------- | +| `metaKey` | `string` | `""` | name of the meta key | +| `label` | `string` | `""` | Label to be added to the NumberControl | +| `...rest` | `object` | `{}` | | + +### `PostMeta.Boolean` + +Control boolean meta values + +#### Props + +| Name | Type | Default | Description | +| ---------- | ----------------- | -------- | -------------------------------------------------------------- | +| `metaKey` | `string` | `""` | name of the meta key | +| `label` | `string` | `""` | Label to be added to the ToggleControl | +| `...rest` | `object` | `{}` | | diff --git a/components/post-meta/utilities.js b/components/post-meta/utilities.js new file mode 100644 index 00000000..6580c76d --- /dev/null +++ b/components/post-meta/utilities.js @@ -0,0 +1,45 @@ +// Checks whether character is Uppercase. +// Crude version. Checks only A-Z. +function isCaps(char) { + if (char.match(/[A-Z]/)) return true; + return false; +} + +// Checks whether character is digit. +function isDigit(char) { + if (char.match(/[0-9]/)) return true; + return false; +} + +export function toKebab(string) { + return string + .split('') + .map((letter, index) => { + const previousLetter = string[index - 1] || ''; + const currentLetter = letter; + + if (isDigit(currentLetter) && !isDigit(previousLetter)) { + return `-${currentLetter}`; + } + + if (!isCaps(currentLetter)) return currentLetter; + + if (previousLetter === '') { + return `${currentLetter.toLowerCase()}`; + } + + if (isCaps(previousLetter)) { + return `${currentLetter.toLowerCase()}`; + } + + return `-${currentLetter.toLowerCase()}`; + }) + .join('') + .trim() + .replace(/[-_\s]+/g, '-'); +} + +export function toSentence(string) { + const interim = toKebab(string).replace(/-/g, ' '); + return interim.slice(0, 1).toUpperCase() + interim.slice(1); +} diff --git a/hooks/index.js b/hooks/index.js index 35420c91..d60f01f4 100644 --- a/hooks/index.js +++ b/hooks/index.js @@ -14,3 +14,4 @@ export { useIsPluginActive } from './use-is-plugin-active'; export { usePrimaryTerm } from './use-primary-term'; export { usePopover } from './use-popover'; export { useScript } from './use-script'; +export { usePostMetaValue } from './use-post-meta-value'; diff --git a/hooks/use-post-meta-value/index.js b/hooks/use-post-meta-value/index.js new file mode 100644 index 00000000..eab975fc --- /dev/null +++ b/hooks/use-post-meta-value/index.js @@ -0,0 +1,17 @@ +import { useEntityProp } from '@wordpress/core-data'; +import { usePost } from '../use-post'; + +export const usePostMetaValue = (metaKey) => { + const { postId, postType } = usePost(); + const [meta, setMeta] = useEntityProp('postType', postType, 'meta', postId); + + const metaValue = meta[metaKey]; + const setMetaValue = (newValue) => { + setMeta({ + ...meta, + [metaKey]: newValue, + }); + }; + + return [metaValue, setMetaValue]; +}; diff --git a/hooks/use-post-meta-value/readme.md b/hooks/use-post-meta-value/readme.md new file mode 100644 index 00000000..b6139086 --- /dev/null +++ b/hooks/use-post-meta-value/readme.md @@ -0,0 +1,17 @@ +# `usePostMetaValue` + +The `usePostMetaValue` hook allows you to read and write meta values of the current post. It either references the global post, or when used within a [``](../../components/post-context/) it reference that post. + +## Usage + +```js +import { usePostMetaValue } from '@10up/block-components'; + +function BlockEdit(props) { + const [price, setPrice] = usePostMetaValue( 'price' ); + + return ( + ... + ); +} +``` From 4b75a51ffb9810d45a46970953504b7eb8fbfba0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20Ka=CC=88gy?= Date: Wed, 25 Jan 2023 10:45:41 +0100 Subject: [PATCH 077/112] add example block for PostMeta component --- example/plugin.php | 58 +++++++++++ example/src/blocks/post-meta/block.json | 12 +++ example/src/blocks/post-meta/index.js | 133 ++++++++++++++++++++++++ example/src/index.js | 1 + 4 files changed, 204 insertions(+) create mode 100644 example/src/blocks/post-meta/block.json create mode 100644 example/src/blocks/post-meta/index.js diff --git a/example/plugin.php b/example/plugin.php index 908eaf76..14bd0e4b 100644 --- a/example/plugin.php +++ b/example/plugin.php @@ -67,3 +67,61 @@ function register_block() { ] ); }; + +function register_book_custom_post_type() { + $labels = array( + 'name' => __( 'Books', 'tenup' ), + 'singular_name' => __( 'Book', 'tenup' ), + 'menu_name' => __( 'Books', 'tenup' ), + 'view_item' => __( 'View book', 'tenup' ), + ); + + $args = [ + 'labels' => $labels, + 'menu_icon' => 'dashicons-book', + 'supports' => [ 'title', 'editor', 'meta', 'custom-fields', 'revisions' ], + 'hierarchical' => false, + 'public' => true, + 'show_ui' => true, + 'show_in_menu' => true, + 'show_in_nav_menus' => true, + 'show_in_admin_bar' => true, + 'menu_position' => 20, + 'can_export' => true, + 'has_archive' => false, + 'exclude_from_search' => false, + 'publicly_queryable' => true, + 'template' => [], + 'template_lock' => false, + 'capability_type' => 'post', + 'show_in_rest' => true, + ]; + + register_post_type( 'books', $args ); + + register_post_meta( 'books', 'author', [ + 'type' => 'string', + 'single' => true, + 'show_in_rest' => true, + ] ); + + register_post_meta( 'books', 'isbn', [ + 'type' => 'string', + 'single' => true, + 'show_in_rest' => true, + ] ); + + register_post_meta( 'books', 'price', [ + 'type' => 'number', + 'single' => true, + 'show_in_rest' => true, + ] ); + + register_post_meta( 'books', 'is_featured', [ + 'type' => 'boolean', + 'single' => true, + 'show_in_rest' => true, + ] ); +} + +add_action( 'init', __NAMESPACE__ . '\register_book_custom_post_type' ); diff --git a/example/src/blocks/post-meta/block.json b/example/src/blocks/post-meta/block.json new file mode 100644 index 00000000..6fe6007c --- /dev/null +++ b/example/src/blocks/post-meta/block.json @@ -0,0 +1,12 @@ +{ + "apiVersion": 2, + "name": "example/post-meta", + "description": "Set some Metadata", + "title": "Post Meta", + "attributes": { + "metaKey": { + "type": "string", + "default": "" + } + } +} \ No newline at end of file diff --git a/example/src/blocks/post-meta/index.js b/example/src/blocks/post-meta/index.js new file mode 100644 index 00000000..d212a733 --- /dev/null +++ b/example/src/blocks/post-meta/index.js @@ -0,0 +1,133 @@ +import { registerBlockType, registerBlockVariation, store as blocksStore, createBlocksFromInnerBlocksTemplate } from '@wordpress/blocks'; +import { + useBlockProps, __experimentalBlockVariationPicker as BlockVariationPicker, store as blockEditorStore, +} from '@wordpress/block-editor'; +import { select, subscribe, useSelect, useDispatch } from '@wordpress/data'; +import { PostMeta } from '@10up/block-components'; +import { box } from '@wordpress/icons'; + +// Checks whether character is Uppercase. +// Crude version. Checks only A-Z. +function isCaps(char) { + if (char.match(/[A-Z]/)) return true; + return false; +} + +// Checks whether character is digit. +function isDigit(char) { + if (char.match(/[0-9]/)) return true; + return false; +} + +export function toKebab(string) { + return string + .split('') + .map((letter, index) => { + const previousLetter = string[index - 1] || ''; + const currentLetter = letter; + + if (isDigit(currentLetter) && !isDigit(previousLetter)) { + return `-${currentLetter}`; + } + + if (!isCaps(currentLetter)) return currentLetter; + + if (previousLetter === '') { + return `${currentLetter.toLowerCase()}`; + } + + if (isCaps(previousLetter)) { + return `${currentLetter.toLowerCase()}`; + } + + return `-${currentLetter.toLowerCase()}`; + }) + .join('') + .trim() + .replace(/[-_\s]+/g, '-'); +} + +export function toSentence(string) { + const interim = toKebab(string).replace(/-/g, ' '); + return interim.slice(0, 1).toUpperCase() + interim.slice(1); +} + +import metadata from './block.json'; + +registerBlockType(metadata, { + icon: box, + edit: (props) => { + const { attributes, setAttributes, name } = props; + const { metaKey } = attributes; + const blockProps = useBlockProps(); + + const { replaceInnerBlocks } = useDispatch(blockEditorStore); + + const variations = useSelect( + (select) => { + const { getBlockVariations } = select(blocksStore); + return getBlockVariations(name, 'block'); + }, + [name], + ); + + if (!metaKey) { + return ( +
    + { + if (nextVariation.attributes) { + setAttributes(nextVariation.attributes); + } + if (nextVariation.innerBlocks) { + replaceInnerBlocks( + clientId, + createBlocksFromInnerBlocksTemplate(nextVariation.innerBlocks), + true, + ); + } + }} + /> +
    + ) + } + + return ( +
    + +
    + ); + }, + save: () => null +}) + +let availableKeys = []; +subscribe(() => { + const meta = select('core/editor').getCurrentPostAttribute('meta'); + if (!meta) { + return; + } + + const keys = Object.keys(meta); + + if (JSON.stringify(keys) === JSON.stringify(availableKeys)) { + return; + } + + availableKeys = keys; + + const newVariations = availableKeys.map(metaKey => ({ + title: toSentence(metaKey) + ' - Meta', + description: `Displays the value of the meta key: "${metaKey}"`, + name: metaKey, + scope: ['inserter', 'block'], + attributes: { + metaKey: metaKey + }, + isActive: ['metaKey'] + })); + + registerBlockVariation('example/post-meta', newVariations); + +}); \ No newline at end of file diff --git a/example/src/index.js b/example/src/index.js index 65b6232e..64fc41c9 100644 --- a/example/src/index.js +++ b/example/src/index.js @@ -9,3 +9,4 @@ import './blocks/post-title'; import './blocks/post-featured-image'; import './blocks/content-item'; import './blocks/hero'; +import './blocks/post-meta'; From 60e39ddf272ee4124183fc65b15d1084f9cb7862 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20Ka=CC=88gy?= Date: Wed, 25 Jan 2023 10:52:36 +0100 Subject: [PATCH 078/112] fix allow usage of render function inside post meta component --- components/post-meta/index.js | 8 ++++++-- components/post-meta/readme.md | 20 ++++++++++++++++++++ 2 files changed, 26 insertions(+), 2 deletions(-) diff --git a/components/post-meta/index.js b/components/post-meta/index.js index e882ab8c..27a06f74 100644 --- a/components/post-meta/index.js +++ b/components/post-meta/index.js @@ -5,10 +5,14 @@ import { usePostMetaValue } from '../../hooks'; import { toSentence } from './utilities'; export const PostMeta = (props) => { - const { metaKey } = props; - const [metaValue] = usePostMetaValue(metaKey); + const { metaKey, children } = props; + const [metaValue, setMetaValue] = usePostMetaValue(metaKey); const metaValueType = typeof metaValue; + if (typeof children === 'function') { + return children(metaValue, setMetaValue); + } + if (metaValueType === 'number') { return ; } diff --git a/components/post-meta/readme.md b/components/post-meta/readme.md index d3f80121..c4384770 100644 --- a/components/post-meta/readme.md +++ b/components/post-meta/readme.md @@ -27,6 +27,26 @@ If you want to override this automatic type casting you can use the sub-componen > **Warning** > Currently only `string`, `number`, `boolean` for `single` meta values are supported. +You can also completely customize the UI of the meta field by passing a render function to the `PostMeta` component: + +```js +import { PostMeta } from '@10up/block-components'; + +function BlockEdit() { + + return ( + + ( price, setPrice ) => ( + <> + + + + ) + + ) +} +``` + ## Props | Name | Type | Default | Description | From f2fb4159883f5f47b5ab1fe301a4bd345f4170e0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20Ka=CC=88gy?= Date: Wed, 25 Jan 2023 10:54:22 +0100 Subject: [PATCH 079/112] fix docs of postMeta component --- components/post-meta/readme.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/components/post-meta/readme.md b/components/post-meta/readme.md index c4384770..414ce50c 100644 --- a/components/post-meta/readme.md +++ b/components/post-meta/readme.md @@ -36,12 +36,12 @@ function BlockEdit() { return ( - ( price, setPrice ) => ( + {( price, setPrice ) => ( <> - ) + )} ) } From b1666bfdacfcb5e4cb7f8057b05c2977867148de Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20Ka=CC=88gy?= Date: Mon, 30 Jan 2023 06:22:39 +0100 Subject: [PATCH 080/112] fix link component test --- cypress/e2e/Link.spec.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cypress/e2e/Link.spec.js b/cypress/e2e/Link.spec.js index 2aeda59a..fb676272 100644 --- a/cypress/e2e/Link.spec.js +++ b/cypress/e2e/Link.spec.js @@ -13,7 +13,7 @@ context('Link', () => { // create the first link cy.get('.tenup-block-components-link__label').first().click(); cy.wait(1500); - cy.get('.tenup-block-components-link__label').first().type('First Link Label', { delay: 50, waitForAnimations: true }); + cy.get('.tenup-block-components-link__label').first().scrollIntoView({offset: {top: 100}}).type('First Link Label', { delay: 50, waitForAnimations: true }); cy.get('.block-editor-url-input__input').first().type('https://10up.com/', { delay: 50, waitForAnimations: true }); cy.get('button.block-editor-link-control__search-submit').first().click(); From 8e6cf06d0b4d718e2a013bdd6d83adbbeaf4d4dd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20Ka=CC=88gy?= Date: Thu, 2 Feb 2023 14:56:47 +0100 Subject: [PATCH 081/112] 1.14.6-alpha.1 --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 9ba63715..73f06062 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@10up/block-components", - "version": "1.14.6-alpha.0", + "version": "1.14.6-alpha.1", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "@10up/block-components", - "version": "1.14.6-alpha.0", + "version": "1.14.6-alpha.1", "license": "GPL-2.0-or-later", "workspaces": [ "./", diff --git a/package.json b/package.json index bba6cdc9..ab434e04 100644 --- a/package.json +++ b/package.json @@ -3,7 +3,7 @@ "publishConfig": { "access": "public" }, - "version": "1.14.6-alpha.0", + "version": "1.14.6-alpha.1", "description": "10up Components built for the WordPress Block Editor.", "main": "./dist/index.js", "source": "index.js", From dd17d63b60c8655e63992e2886e13dcb52d8e06a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20Ka=CC=88gy?= Date: Wed, 15 Feb 2023 08:37:57 +0100 Subject: [PATCH 082/112] fix refacor useIsPluginActive to only query for individual plugin --- hooks/use-is-plugin-active/index.js | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/hooks/use-is-plugin-active/index.js b/hooks/use-is-plugin-active/index.js index d4ec55f9..7dd2cf5b 100644 --- a/hooks/use-is-plugin-active/index.js +++ b/hooks/use-is-plugin-active/index.js @@ -4,9 +4,10 @@ import { store as coreStore } from '@wordpress/core-data'; export const useIsPluginActive = (pluginName) => { return useSelect( (select) => { - const plugins = select(coreStore).getPlugins(); - const hasResolvedPlugins = select(coreStore).hasFinishedResolution('getPlugins'); - const plugin = plugins?.find((plugin) => plugin.plugin === pluginName); + const plugin = select(coreStore).getPlugin(pluginName); + const hasResolvedPlugins = select(coreStore).hasFinishedResolution('getPlugin', [ + pluginName, + ]); return [plugin?.status === 'active' ?? false, hasResolvedPlugins]; }, [pluginName], From 24ec39b701b1b1705a10fcc7caabb53769063fd2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20Ka=CC=88gy?= Date: Wed, 15 Feb 2023 08:38:29 +0100 Subject: [PATCH 083/112] 1.14.6-alpha.2 --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 73f06062..e15d8534 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@10up/block-components", - "version": "1.14.6-alpha.1", + "version": "1.14.6-alpha.2", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "@10up/block-components", - "version": "1.14.6-alpha.1", + "version": "1.14.6-alpha.2", "license": "GPL-2.0-or-later", "workspaces": [ "./", diff --git a/package.json b/package.json index ab434e04..f5dd97b5 100644 --- a/package.json +++ b/package.json @@ -3,7 +3,7 @@ "publishConfig": { "access": "public" }, - "version": "1.14.6-alpha.1", + "version": "1.14.6-alpha.2", "description": "10up Components built for the WordPress Block Editor.", "main": "./dist/index.js", "source": "index.js", From b35dbdf5a38269149a963d37712fb1a6ec29c743 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20Ka=CC=88gy?= Date: Wed, 15 Feb 2023 08:45:30 +0100 Subject: [PATCH 084/112] fix support network-active plugins in useIsPluginActive hook --- hooks/use-is-plugin-active/index.js | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/hooks/use-is-plugin-active/index.js b/hooks/use-is-plugin-active/index.js index 7dd2cf5b..4f44ebe1 100644 --- a/hooks/use-is-plugin-active/index.js +++ b/hooks/use-is-plugin-active/index.js @@ -1,6 +1,8 @@ import { useSelect } from '@wordpress/data'; import { store as coreStore } from '@wordpress/core-data'; +const ACTIVE_STATUSES = ['active', 'network-active']; + export const useIsPluginActive = (pluginName) => { return useSelect( (select) => { @@ -8,7 +10,10 @@ export const useIsPluginActive = (pluginName) => { const hasResolvedPlugins = select(coreStore).hasFinishedResolution('getPlugin', [ pluginName, ]); - return [plugin?.status === 'active' ?? false, hasResolvedPlugins]; + + const isPluginActive = ACTIVE_STATUSES.includes(plugin?.status); + + return [isPluginActive, hasResolvedPlugins]; }, [pluginName], ); From cae99a7c15f7799faea47204da2b20109147130f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20Ka=CC=88gy?= Date: Wed, 15 Feb 2023 08:45:40 +0100 Subject: [PATCH 085/112] 1.14.6-alpha.3 --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index e15d8534..1c1444d0 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@10up/block-components", - "version": "1.14.6-alpha.2", + "version": "1.14.6-alpha.3", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "@10up/block-components", - "version": "1.14.6-alpha.2", + "version": "1.14.6-alpha.3", "license": "GPL-2.0-or-later", "workspaces": [ "./", diff --git a/package.json b/package.json index f5dd97b5..52c42056 100644 --- a/package.json +++ b/package.json @@ -3,7 +3,7 @@ "publishConfig": { "access": "public" }, - "version": "1.14.6-alpha.2", + "version": "1.14.6-alpha.3", "description": "10up Components built for the WordPress Block Editor.", "main": "./dist/index.js", "source": "index.js", From bb6dce90df8fffebb59bba8bbbd83f308c42d388 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20Ka=CC=88gy?= Date: Wed, 15 Feb 2023 09:07:31 +0100 Subject: [PATCH 086/112] add new useTaxonomy hook --- hooks/index.js | 1 + hooks/use-taxonomy/index.js | 16 ++++++++++++++++ hooks/use-taxonomy/readme.md | 21 +++++++++++++++++++++ 3 files changed, 38 insertions(+) create mode 100644 hooks/use-taxonomy/index.js create mode 100644 hooks/use-taxonomy/readme.md diff --git a/hooks/index.js b/hooks/index.js index d60f01f4..38767900 100644 --- a/hooks/index.js +++ b/hooks/index.js @@ -15,3 +15,4 @@ export { usePrimaryTerm } from './use-primary-term'; export { usePopover } from './use-popover'; export { useScript } from './use-script'; export { usePostMetaValue } from './use-post-meta-value'; +export { useTaxonomy } from './use-taxonomy'; diff --git a/hooks/use-taxonomy/index.js b/hooks/use-taxonomy/index.js new file mode 100644 index 00000000..ba153ff1 --- /dev/null +++ b/hooks/use-taxonomy/index.js @@ -0,0 +1,16 @@ +import { useSelect } from '@wordpress/data'; +import { store as coreStore } from '@wordpress/core-data'; + +export function useTaxonomy(taxonomyName) { + return useSelect( + (select) => { + const { getTaxonomy, hasFinishedResolution } = select(coreStore); + + const hasResolvedTaxonomy = hasFinishedResolution('getTaxonomy', [taxonomyName]); + const taxonomy = getTaxonomy(taxonomyName); + + return [taxonomy, hasResolvedTaxonomy]; + }, + [taxonomyName], + ); +} diff --git a/hooks/use-taxonomy/readme.md b/hooks/use-taxonomy/readme.md new file mode 100644 index 00000000..d27b53b0 --- /dev/null +++ b/hooks/use-taxonomy/readme.md @@ -0,0 +1,21 @@ +# `useTaxonomy` + +The `useTaxonomy` hook is a simple utility that returns the taxonomy object for any given taxonomy. + +## Usage + +```js +import { useTaxonomy } from '@10up/block-components'; + +function BlockEdit(props) { + const [postTag, hasResolvedPostTag] = useTaxonomy('post_tag'); + + if ( ! hasResolvedPostTag ) { + return + } + + return ( + ... + ); +} +``` From 5b4a3864e055d304e2674853ba09b7768bc8822a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20Ka=CC=88gy?= Date: Wed, 15 Feb 2023 09:09:44 +0100 Subject: [PATCH 087/112] fix use correct hierarchical or flat term selector --- components/post-term-list/index.js | 37 +++++++++++++++++++++--------- 1 file changed, 26 insertions(+), 11 deletions(-) diff --git a/components/post-term-list/index.js b/components/post-term-list/index.js index 1fc51fb0..f5fa12bf 100644 --- a/components/post-term-list/index.js +++ b/components/post-term-list/index.js @@ -1,9 +1,12 @@ import { Spinner } from '@wordpress/components'; import { Children } from '@wordpress/element'; import PropTypes from 'prop-types'; -import { PostTaxonomiesHierarchicalTermSelector } from '@wordpress/editor'; +import { + PostTaxonomiesHierarchicalTermSelector, + PostTaxonomiesFlatTermSelector, +} from '@wordpress/editor'; -import { usePopover, usePost, useSelectedTerms } from '../../hooks'; +import { usePopover, usePost, useSelectedTerms, useTaxonomy } from '../../hooks'; import { POST_TERM_ITEM_CONTEXT } from './context'; import { ListItem, TermLink } from './item'; @@ -16,13 +19,18 @@ export const PostTermList = (props) => { const hasChildComponents = !hasRenderCallback && Children.count(children); const [selectedTerms, hasResolvedSelectedTerms] = useSelectedTerms(taxonomyName); + const [taxonomy, hasResolvedTaxonomy] = useTaxonomy(taxonomyName); const { toggleProps, Popover } = usePopover(); - if (!hasResolvedSelectedTerms) { + if (!hasResolvedSelectedTerms || !hasResolvedTaxonomy) { return ; } + const PostTaxonomiesTermSelector = taxonomy.hierarchical + ? PostTaxonomiesHierarchicalTermSelector + : PostTaxonomiesFlatTermSelector; + if (hasRenderCallback) { return children({ selectedTerms, isEditable }); } @@ -50,7 +58,7 @@ export const PostTermList = (props) => {
    {isEditable && ( - + )} @@ -58,13 +66,20 @@ export const PostTermList = (props) => { } return ( -
      - {selectedTerms.map((term) => ( -
    • - {term.name} -
    • - ))} -
    + <> + + {selectedTerms.map((term) => ( +
  • + {term.name} +
  • + ))} +
    + {isEditable && ( + + + + )} + ); }; From 37ae86b2fd99b34d5d7fecff3a59c5a704caa4c1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20Ka=CC=88gy?= Date: Wed, 15 Feb 2023 09:10:42 +0100 Subject: [PATCH 088/112] fix import path in example --- example/src/blocks/hero/index.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/example/src/blocks/hero/index.js b/example/src/blocks/hero/index.js index 04addc69..a72645b2 100644 --- a/example/src/blocks/hero/index.js +++ b/example/src/blocks/hero/index.js @@ -3,8 +3,7 @@ import { useBlockProps } from '@wordpress/block-editor'; import { __ } from '@wordpress/i18n'; import { header } from '@wordpress/icons'; -import { PostFeaturedImage, PostTitle, PostPrimaryCategory, PostDate, PostCategoryList, PostAuthor } from '@10up/block-components'; -import { PostExcerpt } from '../../../../components'; +import { PostFeaturedImage, PostTitle, PostPrimaryCategory, PostDate, PostCategoryList, PostAuthor, PostExcerpt } from '@10up/block-components'; const NAMESPACE = 'example'; From 18512dca658faa88bac8b8b83bbc414ca4ed5384 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20Ka=CC=88gy?= Date: Wed, 15 Feb 2023 09:12:56 +0100 Subject: [PATCH 089/112] 1.14.6-alpha.4 --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 1c1444d0..033a11c8 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@10up/block-components", - "version": "1.14.6-alpha.3", + "version": "1.14.6-alpha.4", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "@10up/block-components", - "version": "1.14.6-alpha.3", + "version": "1.14.6-alpha.4", "license": "GPL-2.0-or-later", "workspaces": [ "./", diff --git a/package.json b/package.json index 52c42056..0692aa3f 100644 --- a/package.json +++ b/package.json @@ -3,7 +3,7 @@ "publishConfig": { "access": "public" }, - "version": "1.14.6-alpha.3", + "version": "1.14.6-alpha.4", "description": "10up Components built for the WordPress Block Editor.", "main": "./dist/index.js", "source": "index.js", From 49de9cb4677bfc85a19e6d509858b80016e6118b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20Ka=CC=88gy?= Date: Wed, 15 Feb 2023 09:24:19 +0100 Subject: [PATCH 090/112] fix add missing reference to main readme file --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 3ee2c565..bf6eb8f2 100644 --- a/README.md +++ b/README.md @@ -70,6 +70,7 @@ These components read/write information from the global post object or a `PostCo These hooks read/write information from the global post object or a `PostContext`. - [useAllTerms](./hooks/use-all-terms/) +- [useTaxonomy](./hooks/use-taxonomy/) - [useIsSupportedTaxonomy](./hooks/use-is-supported-taxonomy/) - [usePost](./hooks/use-post/) - [usePrimaryTerm](./hooks/use-primary-term/) From 61d03b3774a46114939b1dd7b71e7af2602f0282 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20Ka=CC=88gy?= Date: Wed, 15 Feb 2023 10:06:59 +0100 Subject: [PATCH 091/112] fix remove disabeling of eslint rule --- components/author/index.js | 1 - 1 file changed, 1 deletion(-) diff --git a/components/author/index.js b/components/author/index.js index a48ee10e..566e3fa4 100644 --- a/components/author/index.js +++ b/components/author/index.js @@ -1,4 +1,3 @@ -/* eslint-disable react-hooks/rules-of-hooks */ import { useContext } from '@wordpress/element'; import { useSelect } from '@wordpress/data'; import { store as blockEditorStore } from '@wordpress/block-editor'; From 474dba26bde6a23aa9d0eab3bea087be76784c6a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20Ka=CC=88gy?= Date: Wed, 15 Feb 2023 11:37:26 +0100 Subject: [PATCH 092/112] fix rename PostContext to use PascalCase --- components/post-context/context.js | 4 ++-- components/post-context/index.js | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/components/post-context/context.js b/components/post-context/context.js index bceb6975..d87d63de 100644 --- a/components/post-context/context.js +++ b/components/post-context/context.js @@ -6,8 +6,8 @@ export const DEFAULT_POST_CONTEXT = { isEditable: null, }; -export const POST_CONTEXT = createContext(DEFAULT_POST_CONTEXT); +export const PostContext = createContext(DEFAULT_POST_CONTEXT); export const usePostContext = () => { - return useContext(POST_CONTEXT); + return useContext(PostContext); }; diff --git a/components/post-context/index.js b/components/post-context/index.js index 82dc7b35..e0257493 100644 --- a/components/post-context/index.js +++ b/components/post-context/index.js @@ -1,6 +1,6 @@ import PropTypes from 'prop-types'; import { useMemo } from '@wordpress/element'; -import { DEFAULT_POST_CONTEXT, POST_CONTEXT } from './context'; +import { DEFAULT_POST_CONTEXT, PostContext as PostContextContext } from './context'; export const PostContext = (props) => { const { children, postId, postType, isEditable } = props; @@ -14,7 +14,7 @@ export const PostContext = (props) => { [postId, postType, isEditable], ); - return {children}; + return {children}; }; PostContext.propTypes = { From 437b832dc4b139b89600dbe08284aa42018e7cff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20Ka=CC=88gy?= Date: Wed, 15 Feb 2023 11:37:48 +0100 Subject: [PATCH 093/112] fix rename PostTermItemContext to use PascalCase --- components/post-term-list/context.js | 2 +- components/post-term-list/index.js | 6 +++--- components/post-term-list/item.js | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/components/post-term-list/context.js b/components/post-term-list/context.js index f8e3faf0..45c633cd 100644 --- a/components/post-term-list/context.js +++ b/components/post-term-list/context.js @@ -1,4 +1,4 @@ import { createContext } from '@wordpress/element'; export const POST_TERM_CONTEXT = createContext(); -export const POST_TERM_ITEM_CONTEXT = createContext(); +export const PostTermItemContext = createContext(); diff --git a/components/post-term-list/index.js b/components/post-term-list/index.js index f5fa12bf..61dce732 100644 --- a/components/post-term-list/index.js +++ b/components/post-term-list/index.js @@ -7,7 +7,7 @@ import { } from '@wordpress/editor'; import { usePopover, usePost, useSelectedTerms, useTaxonomy } from '../../hooks'; -import { POST_TERM_ITEM_CONTEXT } from './context'; +import { PostTermItemContext } from './context'; import { ListItem, TermLink } from './item'; export const PostTermList = (props) => { @@ -51,9 +51,9 @@ export const PostTermList = (props) => { <> {selectedTerms.map((term) => ( - + {children} - + ))} {isEditable && ( diff --git a/components/post-term-list/item.js b/components/post-term-list/item.js index e234cc0b..92e4660a 100644 --- a/components/post-term-list/item.js +++ b/components/post-term-list/item.js @@ -1,6 +1,6 @@ import { useContext } from '@wordpress/element'; import PropTypes from 'prop-types'; -import { POST_TERM_ITEM_CONTEXT } from './context'; +import { PostTermItemContext } from './context'; export const ListItem = (props) => { const { tagName: TagName = 'li', children, ...rest } = props; @@ -18,7 +18,7 @@ ListItem.defaultProps = { }; export const TermLink = (props) => { - const { link, name } = useContext(POST_TERM_ITEM_CONTEXT); + const { link, name } = useContext(PostTermItemContext); return ( From 31e668ac27962549d2f68208df1cf738015fbd85 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20Ka=CC=88gy?= Date: Wed, 15 Feb 2023 11:38:10 +0100 Subject: [PATCH 094/112] fix rename AuthorContext to use PascalContext --- components/author/context.js | 2 +- components/author/index.js | 14 +++++++------- components/post-author/index.js | 6 +++--- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/components/author/context.js b/components/author/context.js index 1fb47589..a711fea6 100644 --- a/components/author/context.js +++ b/components/author/context.js @@ -1,3 +1,3 @@ import { createContext } from '@wordpress/element'; -export const AUTHOR_CONTEXT = createContext(); +export const AuthorContext = createContext(); diff --git a/components/author/index.js b/components/author/index.js index 566e3fa4..11f52641 100644 --- a/components/author/index.js +++ b/components/author/index.js @@ -2,7 +2,7 @@ import { useContext } from '@wordpress/element'; import { useSelect } from '@wordpress/data'; import { store as blockEditorStore } from '@wordpress/block-editor'; import PropTypes from 'prop-types'; -import { AUTHOR_CONTEXT } from './context'; +import { AuthorContext } from './context'; /** * @typedef {object} Author @@ -27,7 +27,7 @@ export const Name = (props) => { /** * @type {Author} */ - const { name, link } = useContext(AUTHOR_CONTEXT); + const { name, link } = useContext(AuthorContext); const wrapperProps = { ...rest }; @@ -52,7 +52,7 @@ export const FirstName = (props) => { /** * @type {Author} */ - const { first_name: firstName } = useContext(AUTHOR_CONTEXT); + const { first_name: firstName } = useContext(AuthorContext); return {firstName}; }; @@ -71,7 +71,7 @@ export const LastName = (props) => { /** * @type {Author} */ - const { last_name: lastName } = useContext(AUTHOR_CONTEXT); + const { last_name: lastName } = useContext(AuthorContext); return {lastName}; }; @@ -99,7 +99,7 @@ export const Avatar = (props) => { /** * @type {Author} */ - const authorDetails = useContext(AUTHOR_CONTEXT); + const authorDetails = useContext(AuthorContext); const avatarUrls = authorDetails?.avatar_urls ? Object.values(authorDetails.avatar_urls) : null; const defaultAvatar = useDefaultAvatar(); @@ -115,7 +115,7 @@ export const Bio = (props) => { /** * @type {Author} */ - const { description } = useContext(AUTHOR_CONTEXT); + const { description } = useContext(AuthorContext); return {description}; }; @@ -134,7 +134,7 @@ export const Email = (props) => { /** * @type {Author} */ - const { email } = useContext(AUTHOR_CONTEXT); + const { email } = useContext(AuthorContext); return ( diff --git a/components/post-author/index.js b/components/post-author/index.js index 95f8c0aa..d8a60bb8 100644 --- a/components/post-author/index.js +++ b/components/post-author/index.js @@ -6,7 +6,7 @@ import PropTypes from 'prop-types'; import { usePost } from '../../hooks'; import { Name, FirstName, LastName, Avatar, Bio, Email } from '../author'; -import { AUTHOR_CONTEXT } from '../author/context'; +import { AuthorContext } from '../author/context'; export const PostAuthor = (props) => { const { children, ...rest } = props; @@ -41,9 +41,9 @@ export const PostAuthor = (props) => { if (hasChildComponents) { return ( - +
    {children}
    -
    + ); } From 3b4e115ca834abb1746868ec9d41fc2d10a3a75e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20Ka=CC=88gy?= Date: Wed, 15 Feb 2023 11:39:13 +0100 Subject: [PATCH 095/112] fix delete unused context definition --- components/post-term-list/context.js | 1 - 1 file changed, 1 deletion(-) diff --git a/components/post-term-list/context.js b/components/post-term-list/context.js index 45c633cd..9ad0e7ea 100644 --- a/components/post-term-list/context.js +++ b/components/post-term-list/context.js @@ -1,4 +1,3 @@ import { createContext } from '@wordpress/element'; -export const POST_TERM_CONTEXT = createContext(); export const PostTermItemContext = createContext(); From 326ab5fa9ac91e60951a31226d988d48f5981d74 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20Ka=CC=88gy?= Date: Wed, 15 Feb 2023 11:39:36 +0100 Subject: [PATCH 096/112] fix rename PostTermItemContext to PostTermContext --- components/post-term-list/context.js | 2 +- components/post-term-list/index.js | 6 +++--- components/post-term-list/item.js | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/components/post-term-list/context.js b/components/post-term-list/context.js index 9ad0e7ea..70e27911 100644 --- a/components/post-term-list/context.js +++ b/components/post-term-list/context.js @@ -1,3 +1,3 @@ import { createContext } from '@wordpress/element'; -export const PostTermItemContext = createContext(); +export const PostTermContext = createContext(); diff --git a/components/post-term-list/index.js b/components/post-term-list/index.js index 61dce732..7067fae3 100644 --- a/components/post-term-list/index.js +++ b/components/post-term-list/index.js @@ -7,7 +7,7 @@ import { } from '@wordpress/editor'; import { usePopover, usePost, useSelectedTerms, useTaxonomy } from '../../hooks'; -import { PostTermItemContext } from './context'; +import { PostTermContext } from './context'; import { ListItem, TermLink } from './item'; export const PostTermList = (props) => { @@ -51,9 +51,9 @@ export const PostTermList = (props) => { <> {selectedTerms.map((term) => ( - + {children} - + ))} {isEditable && ( diff --git a/components/post-term-list/item.js b/components/post-term-list/item.js index 92e4660a..df44640f 100644 --- a/components/post-term-list/item.js +++ b/components/post-term-list/item.js @@ -1,6 +1,6 @@ import { useContext } from '@wordpress/element'; import PropTypes from 'prop-types'; -import { PostTermItemContext } from './context'; +import { PostTermContext } from './context'; export const ListItem = (props) => { const { tagName: TagName = 'li', children, ...rest } = props; @@ -18,7 +18,7 @@ ListItem.defaultProps = { }; export const TermLink = (props) => { - const { link, name } = useContext(PostTermItemContext); + const { link, name } = useContext(PostTermContext); return (
    From 35d043649878155c360b3a65f92d6271f2c3174e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20Ka=CC=88gy?= Date: Wed, 15 Feb 2023 11:40:44 +0100 Subject: [PATCH 097/112] fix remove redundant default value covered by defaultProps --- components/author/index.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/components/author/index.js b/components/author/index.js index 11f52641..8fe39562 100644 --- a/components/author/index.js +++ b/components/author/index.js @@ -22,7 +22,7 @@ import { AuthorContext } from './context'; */ export const Name = (props) => { - const { tagName: TagName = 'span', ...rest } = props; + const { tagName: TagName, ...rest } = props; /** * @type {Author} @@ -47,7 +47,7 @@ Name.defaultProps = { }; export const FirstName = (props) => { - const { tagName: TagName = 'span', ...rest } = props; + const { tagName: TagName, ...rest } = props; /** * @type {Author} @@ -66,7 +66,7 @@ FirstName.defaultProps = { }; export const LastName = (props) => { - const { tagName: TagName = 'span', ...rest } = props; + const { tagName: TagName, ...rest } = props; /** * @type {Author} From fcb479e97de9f9c793490553321ac6b9418e13bf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20Ka=CC=88gy?= Date: Wed, 15 Feb 2023 11:46:35 +0100 Subject: [PATCH 098/112] add more detail to PostContext readme about `usesContext` --- components/post-context/readme.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/post-context/readme.md b/components/post-context/readme.md index e0746b93..84651aea 100644 --- a/components/post-context/readme.md +++ b/components/post-context/readme.md @@ -19,7 +19,7 @@ function BlockEdit() { } ``` -The `PostContext` component works great with the Core Query Loop block if you want / need to create a custom block to be used within the post template. Any block that gets used inside the query loop can access the current post id, post type, and query id via the block context. These values can then be used within the `` to make them available for any of the post level components nested within. +The `PostContext` component works great with the Core Query Loop block if you want / need to create a custom block to be used within the post template. Any block that gets used inside the query loop can access the current post id, post type, and query id via the block context. A block only needs to set the [`usesContext` property in the `block.json`](https://developer.wordpress.org/block-editor/reference-guides/block-api/block-metadata/#context) file to `[ "postId", "postType" ]`. These values can then be accessed via the `context` property passed into the block via the `props` and then used within the `` to make them available for any of the post level components nested within. ```js import { PostContext, PostTitle } from '@10up/block-components'; From b715084e2069af120d7cf8b8316f43ceb0439060 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20Ka=CC=88gy?= Date: Wed, 15 Feb 2023 11:49:14 +0100 Subject: [PATCH 099/112] add more context to PostContext readme about updating external post --- components/post-context/readme.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/components/post-context/readme.md b/components/post-context/readme.md index 84651aea..52e2368f 100644 --- a/components/post-context/readme.md +++ b/components/post-context/readme.md @@ -37,7 +37,9 @@ function BlockEdit(props) { } ``` -*Note: If you enable `isEditable` prop in the `` component for posts that aren't the current post this will actually update the external post. This should be used with caution since it may not be immediately obvious for users.* +*Note: If you enable `isEditable` prop in the `` component for posts that aren't the current post this will create updates the external post. These updates only get applied when the user clicks on the "Save" button at which point they will get shown a list of the different posts they are updating. + +This should be used with caution since it may not be immediately obvious for users.* ![Block Editor Save button showing an indicator for unsaved external changes](../../images/block-editor-unsaved-external-change.png) From e4198d13cc29930aa770830d726d15dd42ac1bc1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20K=C3=A4gy?= Date: Wed, 15 Feb 2023 11:50:12 +0100 Subject: [PATCH 100/112] Update components/post-context/readme.md Co-authored-by: Antonio Laguna --- components/post-context/readme.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/post-context/readme.md b/components/post-context/readme.md index 52e2368f..77f29d1b 100644 --- a/components/post-context/readme.md +++ b/components/post-context/readme.md @@ -1,6 +1,6 @@ # `PostContext` -The `PostContext` component allows you to customize the post object referenced by and of the components referencing the current post object. They are all prefixed with `Post`. +The `PostContext` component allows you to customize the post object referenced by any of the components referencing the current post object. They are all prefixed with `Post`. For example this can be used to build a custom block that gets used inside the core query loop and accesses the passed in post id / post type of that to power the functionality of all the `Post` child components. From 25d251f47db14c86f774e16400c579b783db6089 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20K=C3=A4gy?= Date: Wed, 15 Feb 2023 11:50:46 +0100 Subject: [PATCH 101/112] Update components/post-meta/readme.md Co-authored-by: Antonio Laguna --- components/post-meta/readme.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/post-meta/readme.md b/components/post-meta/readme.md index 414ce50c..a890f2ff 100644 --- a/components/post-meta/readme.md +++ b/components/post-meta/readme.md @@ -27,7 +27,7 @@ If you want to override this automatic type casting you can use the sub-componen > **Warning** > Currently only `string`, `number`, `boolean` for `single` meta values are supported. -You can also completely customize the UI of the meta field by passing a render function to the `PostMeta` component: +You can also completely customize the UI of the meta field by passing a [render function as the children](https://reactpatterns.js.org/docs/function-as-child-component/) of the `PostMeta` component: ```js import { PostMeta } from '@10up/block-components'; From 5d416d99c0d37deb4a01841b58d328d51567f517 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20Ka=CC=88gy?= Date: Wed, 15 Feb 2023 11:52:58 +0100 Subject: [PATCH 102/112] fix indentation of code example in readme --- hooks/use-selected-terms-of-saved-post/readme.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/hooks/use-selected-terms-of-saved-post/readme.md b/hooks/use-selected-terms-of-saved-post/readme.md index e23a49e4..b9112fad 100644 --- a/hooks/use-selected-terms-of-saved-post/readme.md +++ b/hooks/use-selected-terms-of-saved-post/readme.md @@ -10,8 +10,10 @@ import { useSelectedTermsOfSavedPost } from '@10up/block-components'; function BlockEdit(props) { const { context } = props; const { postId } = context; - const [selectedCategoriesOfSavedPost, hasResolvedSelectedCategoriesOfSavedPost] = - useSelectedTermsOfSavedPost('category', postId); + const [ + selectedCategoriesOfSavedPost, + hasResolvedSelectedCategoriesOfSavedPost + ] = useSelectedTermsOfSavedPost('category', postId); return ( ... From 9558467118c061a2b1be6f53ebe6ba7eb56a31c1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20Ka=CC=88gy?= Date: Wed, 15 Feb 2023 11:53:32 +0100 Subject: [PATCH 103/112] fix formatting issues in post featured image block example --- .../src/blocks/post-featured-image/index.js | 38 +++++++++---------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/example/src/blocks/post-featured-image/index.js b/example/src/blocks/post-featured-image/index.js index 65c0efe6..126f043f 100644 --- a/example/src/blocks/post-featured-image/index.js +++ b/example/src/blocks/post-featured-image/index.js @@ -6,26 +6,26 @@ import { PostFeaturedImage } from '@10up/block-components'; const NAMESPACE = 'example'; -registerBlockType( `${ NAMESPACE }/custom-post-featured-image`, { +registerBlockType(`${NAMESPACE}/custom-post-featured-image`, { apiVersion: 2, - title: __( 'Custom Post Featured Image', NAMESPACE ), - icon: 'format-image', - category: 'common', - example: {}, - supports: { - html: false - }, - attributes: {}, - transforms: {}, - variations: [], - usesContext: [ 'postId', 'postType', 'queryId' ], - edit: ({context}) => { + title: __('Custom Post Featured Image', NAMESPACE), + icon: 'format-image', + category: 'common', + example: {}, + supports: { + html: false + }, + attributes: {}, + transforms: {}, + variations: [], + usesContext: ['postId', 'postType', 'queryId'], + edit: ({ context }) => { const blockProps = useBlockProps(); - return ( -
    + return ( +
    - ) - }, - save: () => null -} ); + ) + }, + save: () => null +}); From 27c0ffce7b057bbdc29edb3607fd4eaffefdde41 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20Ka=CC=88gy?= Date: Wed, 15 Feb 2023 11:54:58 +0100 Subject: [PATCH 104/112] fix use defaultProps over inline defaults in PostPrimaryTerm component --- components/post-primary-term/index.js | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/components/post-primary-term/index.js b/components/post-primary-term/index.js index 3a4efaab..d1f10a2c 100644 --- a/components/post-primary-term/index.js +++ b/components/post-primary-term/index.js @@ -3,12 +3,7 @@ import PropTypes from 'prop-types'; import { usePrimaryTerm } from '../../hooks'; export const PostPrimaryTerm = (props) => { - const { - taxonomyName = 'category', - placeholder = __('Select a term', 'tenup'), - isLink = true, - ...rest - } = props; + const { taxonomyName, placeholder, isLink, ...rest } = props; const [primaryTerm, isSupportedTaxonomy] = usePrimaryTerm(taxonomyName); @@ -37,11 +32,12 @@ export const PostPrimaryTerm = (props) => { PostPrimaryTerm.propTypes = { placeholder: PropTypes.string, - taxonomyName: PropTypes.string.isRequired, + taxonomyName: PropTypes.string, isLink: PropTypes.bool, }; PostPrimaryTerm.defaultProps = { placeholder: __('Select a Term', 'tenup'), isLink: true, + taxonomyName: 'category', }; From e278bce9b9aabea97b5cf056e4dc4e06e09f3ced Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20Ka=CC=88gy?= Date: Wed, 15 Feb 2023 11:55:46 +0100 Subject: [PATCH 105/112] fix remove duplicate defaultProps definition in PostPrimaryCategory component --- components/post-primary-category/index.js | 4 ---- 1 file changed, 4 deletions(-) diff --git a/components/post-primary-category/index.js b/components/post-primary-category/index.js index 7fc8977c..32a24c81 100644 --- a/components/post-primary-category/index.js +++ b/components/post-primary-category/index.js @@ -4,10 +4,6 @@ import { PostPrimaryTerm } from '../post-primary-term'; export const PostPrimaryCategory = PostPrimaryTerm; -PostPrimaryCategory.defaultProps = { - placeholder: __('Select a category', 'tenup'), -}; - PostPrimaryCategory.propTypes = { placeholder: PropTypes.string, taxonomyName: PropTypes.string, From c853dff4a098d3465b3bd8f0aa3a333ffd29ce64 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20Ka=CC=88gy?= Date: Wed, 15 Feb 2023 11:56:56 +0100 Subject: [PATCH 106/112] fix rely on defaultProps over inline defaults in PostDate component --- components/post-date/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/post-date/index.js b/components/post-date/index.js index ba29b139..90bf678a 100644 --- a/components/post-date/index.js +++ b/components/post-date/index.js @@ -28,7 +28,7 @@ PostDatePicker.propTypes = { }; export const PostDate = (props) => { - const { placeholder = __('No date set', 'tenup'), format = undefined, ...rest } = props; + const { placeholder, format, ...rest } = props; const { postId, postType, isEditable } = usePost(); From b56e790448ff219de2a83daf88950629489d0b06 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20Ka=CC=88gy?= Date: Wed, 15 Feb 2023 12:08:15 +0100 Subject: [PATCH 107/112] fix rely on defaultProps over inline default in PostExcerpt component --- components/post-excerpt/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/post-excerpt/index.js b/components/post-excerpt/index.js index 1404a71e..321fbe6e 100644 --- a/components/post-excerpt/index.js +++ b/components/post-excerpt/index.js @@ -5,7 +5,7 @@ import PropTypes from 'prop-types'; import { usePost } from '../../hooks'; export const PostExcerpt = (props) => { - const { placeholder = __('Enter excerpt...', 'tenup'), ...rest } = props; + const { placeholder, ...rest } = props; const { postId, postType, isEditable } = usePost(); const [rawExcerpt = '', setExcerpt, fullExcerpt] = useEntityProp( From e6f5599e9399bb82cfea07bf7b8f51c53c4ebbbc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20Ka=CC=88gy?= Date: Wed, 15 Feb 2023 12:10:55 +0100 Subject: [PATCH 108/112] fix rely on defaultProps over inline default in MetaString component --- components/post-meta/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/post-meta/index.js b/components/post-meta/index.js index 27a06f74..2c09b216 100644 --- a/components/post-meta/index.js +++ b/components/post-meta/index.js @@ -29,7 +29,7 @@ PostMeta.propTypes = { }; const MetaString = (props) => { - const { metaKey, tagName = 'p' } = props; + const { metaKey, tagName } = props; const [metaValue, setMetaValue] = usePostMetaValue(metaKey); return ; From dea939620d005ae65c22a336e8c210c4f1bc577a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20Ka=CC=88gy?= Date: Wed, 15 Feb 2023 12:12:33 +0100 Subject: [PATCH 109/112] fix rely on defaultProps over inline default in PostTermList component --- components/post-term-list/index.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/components/post-term-list/index.js b/components/post-term-list/index.js index 7067fae3..ba024dee 100644 --- a/components/post-term-list/index.js +++ b/components/post-term-list/index.js @@ -11,7 +11,7 @@ import { PostTermContext } from './context'; import { ListItem, TermLink } from './item'; export const PostTermList = (props) => { - const { tagName: TagName = 'ul', taxonomyName = 'category', children, ...rest } = props; + const { tagName: TagName, taxonomyName, children, ...rest } = props; const { isEditable } = usePost(); @@ -85,13 +85,14 @@ export const PostTermList = (props) => { PostTermList.propTypes = { children: PropTypes.oneOfType([PropTypes.node, PropTypes.func]), - taxonomyName: PropTypes.string.isRequired, + taxonomyName: PropTypes.string, tagName: PropTypes.string, }; PostTermList.defaultProps = { children: null, tagName: 'ul', + taxonomyName: 'category', }; PostTermList.ListItem = ListItem; From 732d5d19c799350c19fc962103ccc232732ce8df Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20Ka=CC=88gy?= Date: Wed, 15 Feb 2023 12:13:09 +0100 Subject: [PATCH 110/112] fix rely on defaultProps over inline default in ListItem component --- components/post-term-list/item.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/post-term-list/item.js b/components/post-term-list/item.js index df44640f..bdcdaf5d 100644 --- a/components/post-term-list/item.js +++ b/components/post-term-list/item.js @@ -3,7 +3,7 @@ import PropTypes from 'prop-types'; import { PostTermContext } from './context'; export const ListItem = (props) => { - const { tagName: TagName = 'li', children, ...rest } = props; + const { tagName: TagName, children, ...rest } = props; return {children}; }; From e55a455c167c4eb5300f0cb4eef737f0a168a19b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20Ka=CC=88gy?= Date: Wed, 15 Feb 2023 12:13:31 +0100 Subject: [PATCH 111/112] fix rely on defaultProps over inline default in PostTitle component --- components/post-title/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/post-title/index.js b/components/post-title/index.js index 3db54ad6..237c9ecd 100644 --- a/components/post-title/index.js +++ b/components/post-title/index.js @@ -5,7 +5,7 @@ import PropTypes from 'prop-types'; import { usePost } from '../../hooks'; export const PostTitle = (props) => { - const { tagName: TagName = 'h1', ...rest } = props; + const { tagName: TagName, ...rest } = props; const { postId, postType, isEditable } = usePost(); const [rawTitle = '', setTitle, fullTitle] = useEntityProp( From 3682e78c80590de43c82226b0fc6b8c716a88acb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20Ka=CC=88gy?= Date: Wed, 15 Feb 2023 12:15:01 +0100 Subject: [PATCH 112/112] 1.14.6-alpha.5 --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 033a11c8..af30cd10 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@10up/block-components", - "version": "1.14.6-alpha.4", + "version": "1.14.6-alpha.5", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "@10up/block-components", - "version": "1.14.6-alpha.4", + "version": "1.14.6-alpha.5", "license": "GPL-2.0-or-later", "workspaces": [ "./", diff --git a/package.json b/package.json index 0692aa3f..3cb776d9 100644 --- a/package.json +++ b/package.json @@ -3,7 +3,7 @@ "publishConfig": { "access": "public" }, - "version": "1.14.6-alpha.4", + "version": "1.14.6-alpha.5", "description": "10up Components built for the WordPress Block Editor.", "main": "./dist/index.js", "source": "index.js",