Skip to content

Commit

Permalink
Merge pull request #294 from humanmade/inner-block-slider-pages
Browse files Browse the repository at this point in the history
Inner block slider pages
  • Loading branch information
mattheu authored Feb 13, 2025
2 parents 28ff4f0 + 46b73bd commit 50a6665
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 27 deletions.
1 change: 1 addition & 0 deletions src/components/InnerBlockSlider/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,7 @@ The above example code creates a slider using the core image block as each slide
| `slideLimit` | `integer` | `10` | Maximum number of slides. |
| `parentBlockId` | `string` | `''` | Client ID of parent block. This is required. |
| `showNavigation` | `bool` | `true` | Whether to show slide navigation/pagination. |
| `perPage` | `integer` | `1` | Show multiple slides per page. |

## Examples

Expand Down
43 changes: 30 additions & 13 deletions src/components/InnerBlockSlider/inner-block-single-display.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,16 +14,18 @@ import { useInnerBlocksProps } from '@wordpress/block-editor';
* @param {boolean} props.className Class name.
* @param {boolean|React.ReactNode} props.renderAppender Appender.
* @param {boolean} props.captureToolbars Passed through to inner block props.
* @param {number} props.perPage Number of items to display per page.
* @returns {React.ReactNode} Component.
*/
function InnerBlocksDisplaySingle( {
className,
allowedBlocks,
template,
currentItemIndex,
currentItemIndex = 0,
parentBlockId,
renderAppender,
captureToolbars,
renderAppender = false,
captureToolbars = true,
perPage = 1,
} ) {
const styleRef = useRef();

Expand All @@ -42,15 +44,35 @@ function InnerBlocksDisplaySingle( {
}
);

/**
* Construct the CSS for this component.
*
* Hide all slides except the current active slide.
* Account for pages - show current slide + perPage slides.
* Display grid if perPage > 1.
*/
useEffect( () => {
if ( ! styleRef.current ) {
return;
}

styleRef.current.innerHTML = `#inner-block-display-single-${ parentBlockId } > *:not(:nth-child(${
currentItemIndex + 1
}) ) { display: none; }`;
}, [ currentItemIndex, styleRef, parentBlockId ] );
const containerSelector = `#inner-block-display-single-${ parentBlockId }`;

let style = '';

if ( perPage > 1 ) {
style += `${containerSelector} { display: grid; grid-template-columns: repeat(${ perPage }, 1fr); gap: 1em; }`;
}

style += `${containerSelector} > *:not(`;
for ( let i = 1; i <= perPage; i++ ) {
style += `:nth-child(${ currentItemIndex + i }), `;
}
style = style.slice( 0, -2 ) + ')'; // Slice to remove trailing comma and space.
style += '{ display: none; }';

styleRef.current.innerHTML = `${style}`;
}, [ currentItemIndex, styleRef, parentBlockId, perPage ] );

return (
<>
Expand All @@ -60,12 +82,6 @@ function InnerBlocksDisplaySingle( {
);
}

InnerBlocksDisplaySingle.defaultProps = {
currentItemIndex: 0,
renderAppender: false,
captureToolbars: true,
};

InnerBlocksDisplaySingle.propTypes = {
parentBlockId: PropTypes.string.isRequired,
allowedBlocks: PropTypes.arrayOf( PropTypes.string ).isRequired,
Expand All @@ -76,6 +92,7 @@ InnerBlocksDisplaySingle.propTypes = {
PropTypes.bool,
PropTypes.element,
] ),
perPage: PropTypes.number,
};

export default InnerBlocksDisplaySingle;
25 changes: 11 additions & 14 deletions src/components/InnerBlockSlider/inner-block-slider-controlled.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,24 +10,26 @@ import Navigation from './navigation';
/**
* InnerBlockSlider component.
*
* @param {object} props Component props.
* @param {string} props.parentBlockId Parent block clientId.
* @param {string} props.allowedBlock Allowed block type.
* @param {Array} props.template Initial block template.
* @param {number} props.slideLimit Maximum allowed slides.
* @param {number} props.currentItemIndex Override current index, if managing this externally.
* @param {object} props Component props.
* @param {string} props.parentBlockId Parent block clientId.
* @param {string} props.allowedBlock Allowed block type.
* @param {Array} props.template Initial block template.
* @param {number} props.slideLimit Maximum allowed slides.
* @param {number} props.currentItemIndex Override current index, if managing this externally.
* @param {Function} props.setCurrentItemIndex Override set item Index
* @param {Function} props.showNavigation Override display nav
* @param {number} props.perPage Number of items to display per page.
* @returns {React.ReactNode} Component.
*/
const InnerBlockSliderControlled = ( {
parentBlockId,
allowedBlock,
template,
slideLimit,
slideLimit = 10,
currentItemIndex,
setCurrentItemIndex,
showNavigation,
showNavigation = true,
perPage = 1,
} ) => {
const innerBlockTemplate = template || [ [ allowedBlock ] ];

Expand Down Expand Up @@ -104,6 +106,7 @@ const InnerBlockSliderControlled = ( {
className="slides"
currentItemIndex={ currentItemIndex }
parentBlockId={ parentBlockId }
perPage={ perPage }
template={ innerBlockTemplate }
/>

Expand All @@ -124,12 +127,6 @@ const InnerBlockSliderControlled = ( {
);
};

InnerBlockSliderControlled.defaultProps = {
slideLimit: 10,
template: null,
showNavigation: true,
};

InnerBlockSliderControlled.propTypes = {
parentBlockId: PropTypes.string.isRequired,
allowedBlock: PropTypes.string.isRequired,
Expand Down

0 comments on commit 50a6665

Please sign in to comment.