ContentReducer
This function is used to reduce the content to a certain limit. It is useful when you want to show only a certain number of items and hide the rest. It returns the content that can be shown and the remaining content that is hidden.
Installation
To use the ContentReducer component in your project, you can install it via npm.
npx rosalana-dev@latest add ContentReducer
API
The function accepts the following parameters:
content: An array of items that you want to reduce.limit: The number of items that you want to show.options: An object with the following properties:firstAndLast: Iftrue, the first and last items will always be visible.renderRemainingCount: Iftrue, it will render the number of remaining items.
The function returns an object with the following properties:
content: The items that can be shown.remaining: The items that are hidden.remainingCount: The number of hidden items.cutIndex: The index where the content was cut.
Usage
Basic Cut
Example of the basic usage:
const someListofItems = [
{ id: 1, name: 'Item 1' },
{ id: 2, name: 'Item 2' },
{ id: 3, name: 'Item 3' },
{ id: 4, name: 'Item 4' },
{ id: 5, name: 'Item 5' },
{ id: 6, name: 'Item 6' },
{ id: 7, name: 'Item 7' },
{ id: 8, name: 'Item 8' },
{ id: 9, name: 'Item 9' },
{ id: 10, name: 'Item 10' },
]
const { content, remaining, remainingCount, cutIndex } = contentReducer(someListofItems, 5);
console.log(content)
// [
// { id: 1, name: 'Item 1' },
// { id: 2, name: 'Item 2' },
// { id: 3, name: 'Item 3' },
// { id: 4, name: 'Item 4' },
// { id: 5, name: 'Item 5' },
// ]
console.log(remaining)
// [
// { id: 6, name: 'Item 6' },
// { id: 7, name: 'Item 7' },
// { id: 8, name: 'Item 8' },
// { id: 9, name: 'Item 9' },
// { id: 10, name: 'Item 10' },
// ]
console.log(remainingCount)
// 5
console.log(cutIndex)
// 5
First and Last
Example of usage with firstAndLast option:
const { content, remaining, remainingCount, cutIndex } = contentReducer(someListofItems, 5, { firstAndLast: true });
console.log(content)
// [
// { id: 1, name: 'Item 1' },
// { id: 2, name: 'Item 2' },
// { id: 3, name: 'Item 3' },
// { id: 4, name: 'Item 4' },
// { id: 10, name: 'Item 10' },
// ]
console.log(remaining)
// [
// { id: 5, name: 'Item 5' },
// { id: 6, name: 'Item 6' },
// { id: 7, name: 'Item 7' },
// { id: 8, name: 'Item 8' },
// { id: 9, name: 'Item 9' },
// ]
console.log(remainingCount)
// 5
console.log(cutIndex)
// 4
Use cutIndex
When you get the cutIndex you can use it to show a "show more" button that will show the remaining items.
if (cutIndex !== undefined && remainingCount > 0) {
content.splice(cutIndex, 0, {
id: 'show-more',
name: 'Show more',
onClick: () => {
// show the remaining items
}
});
}
Render Remaining Count (default option)
Use the renderRemainingCount option if you are cutting the content in the h function and want to show the number of remaining items.
const { content, remaining, remainingCount, cutIndex } = contentReducer(someListofItems, 5, { renderRemainingCount: true });
console.log(content)
// [
// { id: 1, name: 'Item 1' },
// { id: 2, name: 'Item 2' },
// { id: 3, name: 'Item 3' },
// { id: 4, name: 'Item 4' },
// { id: 5, name: 'Item 5' },
// h('span' , { class: 'text-gray-500 text-sm' }, `+5 more`)
// ]
Code
/**
* Reduce content rendering to limit
* @param content any[]
* @param limit number
* @param options { smartOffset?: boolean, renderRemainingCount?: boolean }
* @returns { content: any[], remaining: any[], remainingCount: number }
*/
type ContentReducerOptions = {
firstAndLast?: boolean,
renderRemainingCount?: boolean
}
type ContentReducerReturn = {
content: any[],
remaining?: any[],
remainingCount?: number
cutIndex?: number
}
export function contentReducer(content: any[], limit: number = 5, options?: ContentReducerOptions): ContentReducerReturn {
if (!Array.isArray(content)) {
console.warn("contentReducer: input is not an array");
return content;
}
if (content.length <= limit) {
return { content };
}
let reducedContent = [];
let remainingItems = [];
let cutIndex = limit;
// be ware thet first element and last element are always visible
if (options?.firstAndLast) {
const limitedLength = limit - 2;
reducedContent = content.slice(1, limitedLength + 1); // get all items that can be shown except first and last
reducedContent.unshift(content[0]); // add first item
reducedContent.push(content[content.length - 1]); // add last item
remainingItems = content.slice(limitedLength + 1, content.length - 1); // get all items that are not shown
cutIndex = limitedLength + 1;
} else {
reducedContent = content.slice(0, limit); // get all items that can be shown
remainingItems = content.slice(limit); // get all items that are not shown
}
const remainingCount = remainingItems.length;
if (options?.renderRemainingCount && remainingCount > 0) {
reducedContent.push(
h('span' , { class: 'text-gray-500 text-sm' }, `+${remainingCount} more`)
)
}
return {
content: reducedContent,
remaining: remainingItems,
remainingCount,
cutIndex
}
}