Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add prop pickedOrder for new selected initial order #126

Draft
wants to merge 3 commits into
base: develop
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 19 additions & 8 deletions components/content-picker/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ const ContentPickerWrapper = styled('div')`
* @param {boolean} props.excludeCurrentPost whether or not to exclude the current post from the picker
* @param {number} props.perPage number of items to show per page
* @param {boolean} props.fetchInitialResults whether or not to fetch initial results on mount
* @param {string} props.pickedOrder string determining where the new item fits in the current list
* @returns {*} React JSX
*/
const ContentPicker = ({
Expand All @@ -68,6 +69,7 @@ const ContentPicker = ({
excludeCurrentPost,
perPage,
fetchInitialResults,
pickedOrder,
}) => {
const currentPostId = select('core/editor')?.getCurrentPostId();

Expand All @@ -85,14 +87,21 @@ const ContentPicker = ({
}

const handleSelect = (item) => {
const newItems = [
{
id: item.id,
uuid: uuidv4(),
type: 'subtype' in item ? item.subtype : item.type,
},
...content,
];
const newItem = {
id: item.id,
uuid: uuidv4(),
type: 'subtype' in item ? item.subtype : item.type,
};
let newItems = [];

if (pickedOrder instanceof Function) {
newItems = pickedOrder(newItem, content);
} else if (pickedOrder === 'start') {
newItems = [newItem, ...content];
} else if (pickedOrder === 'end') {
newItems = [...content, newItem];
}

onPickChange(newItems);
};

Expand Down Expand Up @@ -190,6 +199,7 @@ ContentPicker.defaultProps = {
multiPickedLabel: __('You have selected the following items:', '10up-block-components'),
singlePickedLabel: __('You have selected the following item:', '10up-block-components'),
fetchInitialResults: false,
pickedOrder: 'start',
};

ContentPicker.propTypes = {
Expand All @@ -208,6 +218,7 @@ ContentPicker.propTypes = {
maxContentItems: PropTypes.number,
perPage: PropTypes.number,
fetchInitialResults: PropTypes.bool,
pickedOrder: PropTypes.oneOfType([PropTypes.oneOf(['start', 'end']), PropTypes.func]),
};

export { ContentPicker };
28 changes: 15 additions & 13 deletions components/content-picker/readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,19 +26,21 @@ function MyComponent( props ) {

| Name | Type | Default | Description |
|----------------------|------------|----------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `onPickChange` | `function` | `undefined` | Callback function the list of picked content gets changed |
| `queryFilter` | `function` | `undefined` | Function called to allow you to customize the query before is made. It's advisable to use `useCallback` to save this parameter |
| `label` | `string` | `''` | Renders a label for the Search Field. |
| `mode` | `string` | `'post'` | One of: `post`, `user`, `term` |
| `placeholder` | `string` | `''` | Renders placeholder text inside the Search Field. |
| `contentTypes` | `array` | `[ 'post', 'page' ]` | Names of the post types or taxonomies that should get searched |
| `maxContentItems` | `number` | `1` | Max number of items a user can select. |
| `isOrderable` | `bool` | `false` | When true, will allow the user to order items. Must be used in conjunction with `maxContentItems > 1` |
| `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 pre-populate picker with. Must be in the format of: `[{id: 1, type: 'post', uuid: '...',}, {id: 1, uuid: '...', type: 'page'},... ]`. You cannot provide terms and posts to the same picker. `uuid` was added as of version 1.5.0. It is only used as the React component list key in the admin. If it is not included, `id` will be used which will cause errors if you select the same post twice. |
| `perPage` | `number` | `50` | Number of items to show during search
| `fetchInitialResults` | `bool` | `false` | Fetch initial results to present when focusing the search input | |
| `onPickChange` | `function` | `undefined` | Callback function the list of picked content gets changed |
| `queryFilter` | `function` | `undefined` | Function called to allow you to customize the query before is made. It's advisable to use `useCallback` to save this parameter |
| `label` | `string` | `''` | Renders a label for the Search Field. |
| `mode` | `string` | `'post'` | One of: `post`, `user`, `term` |
| `placeholder` | `string` | `''` | Renders placeholder text inside the Search Field. |
| `contentTypes` | `array` | `[ 'post', 'page' ]` | Names of the post types or taxonomies that should get searched |
| `maxContentItems` | `number` | `1` | Max number of items a user can select. |
| `isOrderable` | `bool` | `false` | When true, will allow the user to order items. Must be used in conjunction with `maxContentItems > 1` |
| `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 pre-populate picker with. Must be in the format of: `[{id: 1, type: 'post', uuid: '...',}, {id: 1, uuid: '...', type: 'page'},... ]`. You cannot provide terms and posts to the same picker. `uuid` was added as of version 1.5.0. It is only used as the React component list key in the admin. If it is not included, `id` will be used which will cause errors if you select the same post twice. |
| `perPage` | `number` | `50` | Number of items to show during search |
| `fetchInitialResults` | `bool` | `false` | Fetch initial results to present when focusing the search input | |
| `pickedOrder` | `string|function` | `start` | Where new selected items should be placed within the selected content list. `start` pushes the new item at begining of the list while `end` pushes it to be the last. For more control pass a function to be called with two arguments `(selectedItem, currentContent) => {}`. |

__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`:
Expand Down