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 guide for repeater fields #37

Open
fabiankaegy opened this issue Apr 20, 2022 · 6 comments
Open

Add guide for repeater fields #37

fabiankaegy opened this issue Apr 20, 2022 · 6 comments
Labels
Good First Issue Good for newcomers Guide

Comments

@fabiankaegy
Copy link
Member

It is a common pattern across projects to need repeating fields. There should be a guide for folks on how to do it.

@fabiankaegy
Copy link
Member Author

In most cases repeated data structures should use InnerBlocks. Showcase some examples of how that works with inner blocks

Info
The reason for this is that inner blocks allow you to reorder / drag items using both the block itself and the list view. It is how core does it and therefore 90% of the time the correct option.

If that doesn't fit the Repeater component from the block components is a great solution. __Showcase example of something like animation settings where you can layer multiple options in the Inspector area.

Info
As a rule of thumb. If the repeatable content is inside the block editor canvas it should use inner blocks. If it is in the sidebar rethink whether it really should be in the sidebar or whether there is a better way of showcasing it in the actual content area. If you are still sure that it should really live in the inspector, the repeater component is a great fit.

@fabiankaegy fabiankaegy added the Good First Issue Good for newcomers label May 17, 2023
@pdavies88
Copy link
Contributor

Is there an example project that uses the Repeater? I looked at a few different projects that I have been shared and I can't find an example of a team using it. The example in block-components seems to be lacking some information as it looks like the repeater requires an id to be used properly.

@pdavies88
Copy link
Contributor

Edit.js example:

/* eslint-disable react/jsx-no-bind */
/**
 * WordPress dependencies
 */
import { __ } from '@wordpress/i18n';
import { TextControl, Button, PanelBody } from '@wordpress/components';
import { close, plus } from '@wordpress/icons';
import { Repeater } from '@10up/block-components';
import { RichText, useBlockProps, InspectorControls } from '@wordpress/block-editor';

/**
 * Edit component.
 * See https://wordpress.org/gutenberg/handbook/designers-developers/developers/block-api/block-edit-save/#edit
 *
 * @param {object}   props                  The block props.
 * @param {object}   props.attributes       Block attributes.
 * @param {string}   props.attributes.title Custom title to be displayed.
 * @param {string}   props.className        Class name for the block.
 * @param {Function} props.setAttributes    Sets the value for block attributes.
 * @returns {Function} Render the edit screen
 */
const ExampleBlockEdit = (props) => {
	const { attributes, setAttributes } = props;
	const { title } = attributes;

	const blockProps = useBlockProps();

	function customAddButton(addItem) {
		return (
			<div>
				<Button variant="primary" icon={plus} onClick={addItem} />
			</div>
		);
	}

	return (
		<div {...blockProps}>
			<RichText
				className="wp-block-example-block__title"
				tagName="h2"
				placeholder={__('Custom Title')}
				value={title}
				onChange={(title) => setAttributes({ title })}
			/>
			<style>
				{`
				.inspector-repeater {
					display: flex;
					justify-content: space-between;
				}
				.inspector-repeater .components-base-control__field {
					margin-bottom: 0;
				}
				.inspector-repeater .components-text-control__input {
					height: 2.25rem;
				}
				`}
			</style>
			<InspectorControls>
				<PanelBody initialOpen title={__('Topics')}>
					<Repeater attribute="items" addButton={customAddButton}>
						{(item, index, setItem, removeItem) => (
							<div key={index} className="inspector-repeater">
								<TextControl
									value={item.topic}
									onChange={(val) => setItem({ topic: val })}
									key={index}
								/>
								<Button
									icon={close}
									isDestructive
									label={__('Remove')}
									onClick={removeItem}
								/>
							</div>
						)}
					</Repeater>
				</PanelBody>
			</InspectorControls>
		</div>
	);
};
export default ExampleBlockEdit;

@JiveDig
Copy link

JiveDig commented Aug 7, 2023

+1 here. I'm trying to have repeatable RangeControl components but struggling to get them to work. @pdavies88 are you saying that example is or is not working? I'm not understanding how to assign a specific attribute to each the Repeater.

@pdavies88
Copy link
Contributor

@JiveDig I should have deleted that comment I was unable to find the example at the time but it exists here: https://github.com/10up/block-components/tree/develop/example/src/blocks/repeater-component-example

I included the code snippet above for an example edit.js file since that should be a good starting ground for another individual to use this component.

@JiveDig
Copy link

JiveDig commented Aug 7, 2023

Ah-ha! That's what i need. Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Good First Issue Good for newcomers Guide
Projects
None yet
Development

No branches or pull requests

3 participants