From b9571918209aeb6f159bf2ba89ff64e8df7053b2 Mon Sep 17 00:00:00 2001 From: Ryan Welcher Date: Wed, 18 Aug 2021 10:12:09 -0400 Subject: [PATCH 1/9] Introduce useReqestData hook. --- README.md | 36 +++++++++++++++++++++++++++++++++++- hooks/use-request-data.js | 34 ++++++++++++++++++++++++++++++++++ index.js | 1 + 3 files changed, 70 insertions(+), 1 deletion(-) create mode 100644 hooks/use-request-data.js diff --git a/README.md b/README.md index 54c135fc..e52e274f 100644 --- a/README.md +++ b/README.md @@ -108,7 +108,41 @@ function BlockEdit( props ) { ) } ``` - +## useRequestData +Custom hook to to make a request using getEntityRecords that provides `data`, `isLoading` and `invalidator`. +Parameters: +* {string} entity The entity to retrieve. ie. postType +* {string} kind The entity kind to retrieve. ie. posts +* {Object} query Optional query to pass to the request. + +Returns: +* {Array} + * {array} Array containing the requested entity kind. + * {Boolean} Representing if the request is resolving + * {Function} This function will invalidate the resolver and re-run the query. +### Usage +```js +const ExampleBockEdit = ({ className }) => { + const [data, isLoading, invalidateRequest ] = useRequestData('postType', 'post', { per_page: 5 }); + + if (isLoading) { + return

Loading...

; + } + return ( +
+ + +
+ ); +}; +``` ## IsAdmin A wrapper component that only renders child components if the current user has admin capabilities. The usecase for this component is when you have a certain setting that should be restricted to administrators only. For example when you have a block that requires an API token or crenentials you might only want Administrators to edit these. See [10up/maps-block-apple](https://github.com/10up/maps-block-apple/blob/774c6509eabb7ac48dcebea551f32ac7ddc5d246/src/Settings/AuthenticationSettings.js) for a real world example. diff --git a/hooks/use-request-data.js b/hooks/use-request-data.js new file mode 100644 index 00000000..aa83c407 --- /dev/null +++ b/hooks/use-request-data.js @@ -0,0 +1,34 @@ +/** + * WordPress dependencies + */ + import { useSelect, useDispatch } from '@wordpress/data'; + + /** + * Hook for retrieving data from the WordPress REST API. + * + * @param {string} entity The entity to retrieve. ie. postType + * @param {string} kind The entity kind to retrieve. ie. posts + * @param {Object} query Optional query to pass to the request. + * @return {Array} The data returned from the request. + */ + export const useRequestData = (entity, kind, query) => { + const { invalidateResolution } = useDispatch('core/data'); + const { data, isLoading } = useSelect((select) => { + return { + data: select('core').getEntityRecords(entity, kind, query), + isLoading: select('core/data').isResolving('core', 'getEntityRecords', [ + entity, + kind, + query, + ]), + }; + }); + + const invalidateResolver = () => { + invalidateResolution('core', 'getEntityRecords', [entity, kind, query]); + }; + + return [data, isLoading, invalidateResolver]; + }; + + \ No newline at end of file diff --git a/index.js b/index.js index 6b86ae0b..91081dfd 100644 --- a/index.js +++ b/index.js @@ -2,4 +2,5 @@ export { ContentPicker } from './components/ContentPicker'; export { ContentSearch } from './components/ContentSearch'; export { IsAdmin } from './components/is-admin'; export { useHasSelectedInnerBlock } from './hooks/use-has-selected-inner-block'; +export { useRequestData } from './hooks/use-request-data' export { default as CustomBlockAppender } from './components/CustomBlockAppender'; From 223d091b20008cd7e64996b00da69e01886f3427 Mon Sep 17 00:00:00 2001 From: Ryan Welcher Date: Wed, 25 Aug 2021 10:11:27 -0400 Subject: [PATCH 2/9] Adding more information for invalidator function. --- README.md | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index e52e274f..8fef6919 100644 --- a/README.md +++ b/README.md @@ -109,17 +109,18 @@ function BlockEdit( props ) { } ``` ## useRequestData -Custom hook to to make a request using getEntityRecords that provides `data`, `isLoading` and `invalidator`. +Custom hook to to make a request using `getEntityRecords` that provides `data`, `isLoading` and `invalidator` function. The `invalidator` function, when dispatched, will tell the datastore to invalidate the resolver associated with the request made by getEntityRecords. This will trigger the request to be re-run as if it was being requested for the first time. This is not always needed but is very useful for components that need to update the data after an event. For example, displaying a list of uploaded media after a new item has been uploaded. + Parameters: -* {string} entity The entity to retrieve. ie. postType -* {string} kind The entity kind to retrieve. ie. posts -* {Object} query Optional query to pass to the request. +* `{string}` entity The entity to retrieve. ie. postType +* `{string}` kind The entity kind to retrieve. ie. posts +* `{Object}` query Optional query to pass to the request. Returns: -* {Array} - * {array} Array containing the requested entity kind. - * {Boolean} Representing if the request is resolving - * {Function} This function will invalidate the resolver and re-run the query. +* `{Array}` + * `{Array} ` Array containing the requested entity kind. + * `{Boolean}` Representing if the request is resolving + * `{Function}` This function will invalidate the resolver and re-run the query. ### Usage ```js const ExampleBockEdit = ({ className }) => { From 7907b9366edd63ad1965a930840a110c65f3948f Mon Sep 17 00:00:00 2001 From: Ryan Welcher Date: Wed, 25 Aug 2021 11:26:01 -0400 Subject: [PATCH 3/9] Correct spelling. --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 8fef6919..321133b0 100644 --- a/README.md +++ b/README.md @@ -146,7 +146,7 @@ const ExampleBockEdit = ({ className }) => { ``` ## IsAdmin -A wrapper component that only renders child components if the current user has admin capabilities. The usecase for this component is when you have a certain setting that should be restricted to administrators only. For example when you have a block that requires an API token or crenentials you might only want Administrators to edit these. See [10up/maps-block-apple](https://github.com/10up/maps-block-apple/blob/774c6509eabb7ac48dcebea551f32ac7ddc5d246/src/Settings/AuthenticationSettings.js) for a real world example. +A wrapper component that only renders child components if the current user has admin capabilities. The use case for this component is when you have a certain setting that should be restricted to administrators only. For example when you have a block that requires an API token or credentials you might only want Administrators to edit these. See [10up/maps-block-apple](https://github.com/10up/maps-block-apple/blob/774c6509eabb7ac48dcebea551f32ac7ddc5d246/src/Settings/AuthenticationSettings.js) for a real world example. ### Usage ```js From ad143909e4fe74e3638cc8119b7a55eee9bc001a Mon Sep 17 00:00:00 2001 From: Ryan Welcher Date: Thu, 26 Aug 2021 12:11:15 -0400 Subject: [PATCH 4/9] Updates the hook to work with either single or multiple pieces of data. --- README.md | 28 +++++++++++++++++++-- hooks/use-request-data.js | 53 ++++++++++++++++++++++----------------- 2 files changed, 56 insertions(+), 25 deletions(-) diff --git a/README.md b/README.md index 321133b0..2ec448df 100644 --- a/README.md +++ b/README.md @@ -109,12 +109,14 @@ function BlockEdit( props ) { } ``` ## useRequestData -Custom hook to to make a request using `getEntityRecords` that provides `data`, `isLoading` and `invalidator` function. The `invalidator` function, when dispatched, will tell the datastore to invalidate the resolver associated with the request made by getEntityRecords. This will trigger the request to be re-run as if it was being requested for the first time. This is not always needed but is very useful for components that need to update the data after an event. For example, displaying a list of uploaded media after a new item has been uploaded. +Custom hook to to make a request using `getEntityRecords` or `getEntityRecord` that provides `data`, `isLoading` and `invalidator` function. The hook determines which selector to use based on the query parameter. If a number is passed, it will use `getEntityRecord` to retrieve a single item. If an object is passed, it will use that as the query for `getEntityRecords` to retrieve multiple pieces of data. + +The `invalidator` function, when dispatched, will tell the datastore to invalidate the resolver associated with the request made by getEntityRecords. This will trigger the request to be re-run as if it was being requested for the first time. This is not always needed but is very useful for components that need to update the data after an event. For example, displaying a list of uploaded media after a new item has been uploaded. Parameters: * `{string}` entity The entity to retrieve. ie. postType * `{string}` kind The entity kind to retrieve. ie. posts -* `{Object}` query Optional query to pass to the request. +* `{Object|Number}` Optional. Query to pass to the geEntityRecords request. Defaults to an empty object. If a number is passed, it is used as the ID of the entity to retrieve via getEntityRecord. Returns: * `{Array}` @@ -122,6 +124,8 @@ Returns: * `{Boolean}` Representing if the request is resolving * `{Function}` This function will invalidate the resolver and re-run the query. ### Usage + +#### Multiple pieces of data. ```js const ExampleBockEdit = ({ className }) => { const [data, isLoading, invalidateRequest ] = useRequestData('postType', 'post', { per_page: 5 }); @@ -144,6 +148,26 @@ const ExampleBockEdit = ({ className }) => { ); }; ``` +#### Single piece of data +```js +const ExampleBockEdit = ({ className }) => { + const [data, isLoading, invalidateRequest ] = useRequestData('postType', 'post', 59); + + if (isLoading) { + return

Loading...

; + } + return ( +
+ + {data &&(
{data.title.rendered}
)} + + +
+ ); +}; +``` ## IsAdmin A wrapper component that only renders child components if the current user has admin capabilities. The use case for this component is when you have a certain setting that should be restricted to administrators only. For example when you have a block that requires an API token or credentials you might only want Administrators to edit these. See [10up/maps-block-apple](https://github.com/10up/maps-block-apple/blob/774c6509eabb7ac48dcebea551f32ac7ddc5d246/src/Settings/AuthenticationSettings.js) for a real world example. diff --git a/hooks/use-request-data.js b/hooks/use-request-data.js index aa83c407..6ad6d92a 100644 --- a/hooks/use-request-data.js +++ b/hooks/use-request-data.js @@ -1,32 +1,39 @@ +/** + * External dependencies + */ +// eslint-disable-next-line import/no-extraneous-dependencies +import isObject from 'lodash/isObject'; + /** * WordPress dependencies */ import { useSelect, useDispatch } from '@wordpress/data'; /** - * Hook for retrieving data from the WordPress REST API. - * - * @param {string} entity The entity to retrieve. ie. postType - * @param {string} kind The entity kind to retrieve. ie. posts - * @param {Object} query Optional query to pass to the request. - * @return {Array} The data returned from the request. - */ - export const useRequestData = (entity, kind, query) => { - const { invalidateResolution } = useDispatch('core/data'); - const { data, isLoading } = useSelect((select) => { - return { - data: select('core').getEntityRecords(entity, kind, query), - isLoading: select('core/data').isResolving('core', 'getEntityRecords', [ - entity, - kind, - query, - ]), - }; - }); - - const invalidateResolver = () => { - invalidateResolution('core', 'getEntityRecords', [entity, kind, query]); - }; + * Hook for retrieving data from the WordPress REST API. + * + * @param {string} entity The entity to retrieve. ie. postType + * @param {string} kind The entity kind to retrieve. ie. posts + * @param {Object | number} [query] Optional. Query to pass to the geEntityRecords request. Defaults to an empty object. If a number is passed, it is used as the ID of the entity to retrieve via getEntityRecord. + * @return {Array} The data returned from the request. + */ + export const useRequestData = (entity, kind, query = {}) => { + const functionToCall = isObject(query) ? 'getEntityRecords' : 'getEntityRecord'; + const { invalidateResolution } = useDispatch('core/data'); + const { data, isLoading } = useSelect((select) => { + return { + data: select('core')[functionToCall](entity, kind, query), + isLoading: select('core/data').isResolving('core', functionToCall, [ + entity, + kind, + query, + ]), + }; + }); + + const invalidateResolver = () => { + invalidateResolution('core', functionToCall, [entity, kind, query]); + }; return [data, isLoading, invalidateResolver]; }; From 7f2aa078c36cfe8e9bfa4f20c2e3244ba76cbba1 Mon Sep 17 00:00:00 2001 From: Taylor Lovett Date: Fri, 10 Sep 2021 22:45:31 -0400 Subject: [PATCH 5/9] Add property for changing search posts per page --- README.md | 8 ++++---- components/ContentPicker/index.js | 4 ++++ components/ContentSearch/index.js | 15 +++++++++++---- 3 files changed, 19 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index 4d33fc9b..0d49fd82 100644 --- a/README.md +++ b/README.md @@ -46,7 +46,7 @@ function MyComponent( props ) { | `uniqueContentItems` | `bool` | `true` | Prevent duplicate items from being picked. | `excludeCurrentPost` | `bool` | `true` | Don't allow user to pick the current post. Only applicable on the editor screen. | `content` | `array` | `[]` | Array of items to prepopulate picker with. Must be in the format of: `[{id: 1, type: 'post'}, {id: 1, type: 'page'},... ]`. You cannot provide terms and posts to the same picker. Can also take the form `[1, 2, ...]` if only one `contentTypes` is provided. - +| `perPage` | `number` | `10` | Number of items to show during search __NOTE:__ Content picker cannot validate that posts you pass it via `content` prop actually exist. If a post does not exist, it will not render as one of the picked items but will still be passed back as picked items if new items are picked/sorted. Therefore, on save you need to validate that all the picked posts/terms actually exist. The `contentTypes` will get used in a Rest Request to the `search` endpoint as the `subtypes`: @@ -87,7 +87,7 @@ function MyComponent( props ) { | `placeholder` | `string` | `''` | Renders placeholder text inside the Search Field. | | `contentTypes` | `array` | `[ 'post', 'page' ]` | Names of the post types or taxonomies that should get searched | | `excludeItems` | `array` | `[ { id: 1, type: 'post' ]` | Items to exclude from search | - +| `perPage` | `number` | `10` | Number of items to show during search ## useHasSelectedInnerBlock @@ -158,9 +158,9 @@ const ExampleBockEdit = ({ className }) => { } return (
- + {data &&(
{data.title.rendered}
)} - + diff --git a/components/ContentPicker/index.js b/components/ContentPicker/index.js index ec625d6a..683df45f 100644 --- a/components/ContentPicker/index.js +++ b/components/ContentPicker/index.js @@ -55,6 +55,7 @@ const ContentPicker = ({ content: presetContent, uniqueContentItems, excludeCurrentPost, + perPage }) => { const [content, setContent] = useState(presetContent); @@ -110,6 +111,7 @@ const ContentPicker = ({ onSelectItem={handleSelect} contentTypes={contentTypes} mode={mode} + perPage={perPage} /> )} {Boolean(content?.length) > 0 && ( @@ -151,6 +153,7 @@ ContentPicker.defaultProps = { contentTypes: ['post', 'page'], placeholder: '', content: [], + perPage: 10, maxContentItems: 1, uniqueContentItems: true, isOrderable: false, @@ -172,6 +175,7 @@ ContentPicker.propTypes = { uniqueContentItems: PropTypes.bool, excludeCurrentPost: PropTypes.bool, maxContentItems: PropTypes.number, + perPage: PropTypes.number, }; export { ContentPicker }; diff --git a/components/ContentSearch/index.js b/components/ContentSearch/index.js index ff18d09b..35a69c1c 100644 --- a/components/ContentSearch/index.js +++ b/components/ContentSearch/index.js @@ -9,7 +9,7 @@ const NAMESPACE = '10up-content-search'; const searchCache = {}; -const ContentSearch = ({ onSelectItem, placeholder, label, contentTypes, mode, excludeItems }) => { +const ContentSearch = ({ onSelectItem, placeholder, label, contentTypes, mode, excludeItems, perPage }) => { const [searchString, setSearchString] = useState(''); const [searchResults, setSearchResults] = useState([]); const [isLoading, setIsLoading] = useState(false); @@ -77,9 +77,10 @@ const ContentSearch = ({ onSelectItem, placeholder, label, contentTypes, mode, e const searchQuery = `wp/v2/search/?search=${keyword}&subtype=${contentTypes.join( ',', - )}&type=${mode}&_embed`; + )}&type=${mode}&_embed&per_page=${perPage}`; if (searchCache[searchQuery]) { + console.log('Setting search results for ' + keyword); setSearchResults(filterResults(searchCache[searchQuery])); setIsLoading(false); } else { @@ -91,8 +92,12 @@ const ContentSearch = ({ onSelectItem, placeholder, label, contentTypes, mode, e } searchCache[searchQuery] = results; - setSearchResults(filterResults(results)); - setIsLoading(false); + + if (keyword === searchString) { + console.log('Setting search results for ' + keyword); + setSearchResults(filterResults(results)); + setIsLoading(false); + } }); } }; @@ -164,6 +169,7 @@ const ContentSearch = ({ onSelectItem, placeholder, label, contentTypes, mode, e ContentSearch.defaultProps = { contentTypes: ['post', 'page'], placeholder: '', + perPage: 10, label: '', excludeItems: [], mode: 'post', @@ -179,6 +185,7 @@ ContentSearch.propTypes = { placeholder: PropTypes.string, excludeItems: PropTypes.array, label: PropTypes.string, + perPage: PropTypes.number }; export { ContentSearch }; From 55fe836004a994c8937927b3acb8d65c98783cb9 Mon Sep 17 00:00:00 2001 From: Taylor Lovett Date: Fri, 10 Sep 2021 23:44:57 -0400 Subject: [PATCH 6/9] Better error handling for content search; abort previous search request if a new one starts --- components/ContentSearch/index.js | 35 ++++++++++++++++++++++++++----- 1 file changed, 30 insertions(+), 5 deletions(-) diff --git a/components/ContentSearch/index.js b/components/ContentSearch/index.js index 35a69c1c..a16aef09 100644 --- a/components/ContentSearch/index.js +++ b/components/ContentSearch/index.js @@ -14,6 +14,7 @@ const ContentSearch = ({ onSelectItem, placeholder, label, contentTypes, mode, e const [searchResults, setSearchResults] = useState([]); const [isLoading, setIsLoading] = useState(false); const [selectedItem, setSelectedItem] = useState(null); + const abortControllerRef = useRef(); const mounted = useRef(true); @@ -72,7 +73,21 @@ const ContentSearch = ({ onSelectItem, placeholder, label, contentTypes, mode, e * @param {string} keyword search query string */ const handleSearchStringChange = (keyword) => { + if (abortControllerRef.current) { + abortControllerRef.current.abort(); + } + setSearchString(keyword); + + if (keyword.trim() === '') { + setIsLoading(false); + setSearchResults([]); + abortControllerRef.current = null; + return; + } + + abortControllerRef.current = new AbortController(); + setIsLoading(true); const searchQuery = `wp/v2/search/?search=${keyword}&subtype=${contentTypes.join( @@ -80,22 +95,32 @@ const ContentSearch = ({ onSelectItem, placeholder, label, contentTypes, mode, e )}&type=${mode}&_embed&per_page=${perPage}`; if (searchCache[searchQuery]) { - console.log('Setting search results for ' + keyword); + abortControllerRef.current = null; + setSearchResults(filterResults(searchCache[searchQuery])); setIsLoading(false); } else { + apiFetch({ path: searchQuery, + signal: abortControllerRef.current.signal }).then((results) => { if (mounted.current === false) { return; } + abortControllerRef.current = null; + searchCache[searchQuery] = results; - if (keyword === searchString) { - console.log('Setting search results for ' + keyword); - setSearchResults(filterResults(results)); + setSearchResults(filterResults(results)); + + setIsLoading(false); + }).catch((error, code) => { + // fetch_error means the request was aborted + if (error.code !== 'fetch_error') { + setSearchResults([]); + abortControllerRef.current = null; setIsLoading(false); } }); @@ -137,7 +162,7 @@ const ContentSearch = ({ onSelectItem, placeholder, label, contentTypes, mode, e {__('Nothing found.', '10up-block-components')} )} - {searchResults.map((item, index) => { + {!isLoading && searchResults.map((item, index) => { if (!item.title.length) { return null; } From 91af4bcbec2cfaadc2e2147b63a5e474516447f2 Mon Sep 17 00:00:00 2001 From: Taylor Lovett Date: Fri, 10 Sep 2021 23:50:41 -0400 Subject: [PATCH 7/9] Change per page to 50 and add a max height/scroll --- README.md | 4 ++-- components/ContentPicker/index.js | 2 +- components/ContentSearch/index.js | 6 ++++-- 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 0d49fd82..8bf1de21 100644 --- a/README.md +++ b/README.md @@ -46,7 +46,7 @@ function MyComponent( props ) { | `uniqueContentItems` | `bool` | `true` | Prevent duplicate items from being picked. | `excludeCurrentPost` | `bool` | `true` | Don't allow user to pick the current post. Only applicable on the editor screen. | `content` | `array` | `[]` | Array of items to prepopulate picker with. Must be in the format of: `[{id: 1, type: 'post'}, {id: 1, type: 'page'},... ]`. You cannot provide terms and posts to the same picker. Can also take the form `[1, 2, ...]` if only one `contentTypes` is provided. -| `perPage` | `number` | `10` | Number of items to show during search +| `perPage` | `number` | `50` | Number of items to show during search __NOTE:__ Content picker cannot validate that posts you pass it via `content` prop actually exist. If a post does not exist, it will not render as one of the picked items but will still be passed back as picked items if new items are picked/sorted. Therefore, on save you need to validate that all the picked posts/terms actually exist. The `contentTypes` will get used in a Rest Request to the `search` endpoint as the `subtypes`: @@ -87,7 +87,7 @@ function MyComponent( props ) { | `placeholder` | `string` | `''` | Renders placeholder text inside the Search Field. | | `contentTypes` | `array` | `[ 'post', 'page' ]` | Names of the post types or taxonomies that should get searched | | `excludeItems` | `array` | `[ { id: 1, type: 'post' ]` | Items to exclude from search | -| `perPage` | `number` | `10` | Number of items to show during search +| `perPage` | `number` | `50` | Number of items to show during search ## useHasSelectedInnerBlock diff --git a/components/ContentPicker/index.js b/components/ContentPicker/index.js index 683df45f..60ab91e3 100644 --- a/components/ContentPicker/index.js +++ b/components/ContentPicker/index.js @@ -153,7 +153,7 @@ ContentPicker.defaultProps = { contentTypes: ['post', 'page'], placeholder: '', content: [], - perPage: 10, + perPage: 50, maxContentItems: 1, uniqueContentItems: true, isOrderable: false, diff --git a/components/ContentSearch/index.js b/components/ContentSearch/index.js index a16aef09..7df68cee 100644 --- a/components/ContentSearch/index.js +++ b/components/ContentSearch/index.js @@ -92,7 +92,7 @@ const ContentSearch = ({ onSelectItem, placeholder, label, contentTypes, mode, e const searchQuery = `wp/v2/search/?search=${keyword}&subtype=${contentTypes.join( ',', - )}&type=${mode}&_embed&per_page=${perPage}`; + )}&type=${mode}&_embed&per_page=50`; if (searchCache[searchQuery]) { abortControllerRef.current = null; @@ -151,6 +151,8 @@ const ContentSearch = ({ onSelectItem, placeholder, label, contentTypes, mode, e marginLeft: '0', paddingLeft: '0', listStyle: 'none', + maxHeight: '350px', + overflowY: 'scroll' }} > {isLoading && } @@ -194,7 +196,7 @@ const ContentSearch = ({ onSelectItem, placeholder, label, contentTypes, mode, e ContentSearch.defaultProps = { contentTypes: ['post', 'page'], placeholder: '', - perPage: 10, + perPage: 50, label: '', excludeItems: [], mode: 'post', From d65e65cb3d608ead1556d0897162b2c0f4aa9555 Mon Sep 17 00:00:00 2001 From: Taylor Lovett Date: Fri, 24 Sep 2021 10:29:05 -0400 Subject: [PATCH 8/9] Style content search using emotion so it can be overrided --- components/ContentSearch/index.js | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/components/ContentSearch/index.js b/components/ContentSearch/index.js index 7df68cee..6ff39c7d 100644 --- a/components/ContentSearch/index.js +++ b/components/ContentSearch/index.js @@ -4,8 +4,10 @@ import { useState, useRef, useEffect } from '@wordpress/element'; // eslint-disa import PropTypes from 'prop-types'; import { __ } from '@wordpress/i18n'; import SearchItem from './SearchItem'; +/** @jsx jsx */ +import { jsx, css } from '@emotion/react'; -const NAMESPACE = '10up-content-search'; +const NAMESPACE = 'tenup-content-search'; const searchCache = {}; @@ -133,6 +135,12 @@ const ContentSearch = ({ onSelectItem, placeholder, label, contentTypes, mode, e }; }, []); + const listCSS = css` + /* stylelint-disable */ + max-height: 350px; + overflow-y: scroll; + `; + return ( {isLoading && } {!isLoading && !hasSearchResults && ( From e71e9e32685a8de28a9f24af2883b093f31648fa Mon Sep 17 00:00:00 2001 From: Taylor Lovett Date: Fri, 24 Sep 2021 10:31:43 -0400 Subject: [PATCH 9/9] Version bump --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 1e29384f..6969aa9e 100644 --- a/package.json +++ b/package.json @@ -3,7 +3,7 @@ "publishConfig": { "access": "public" }, - "version": "1.3.0", + "version": "1.4.0", "description": "10up Components built for the WordPress Block Editor.", "main": "index.js", "scripts": {