Skip to content

Commit

Permalink
fix(InfinityScroller): forward load button props (#3737)
Browse files Browse the repository at this point in the history
Co-authored-by: Tobias Høegh <[email protected]>
  • Loading branch information
joakbjerk and tujoworker authored Aug 28, 2024
1 parent 416df35 commit 645a7b3
Show file tree
Hide file tree
Showing 5 changed files with 116 additions and 7 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ showTabs: true
| `more_pages` | _(optional)_ The title used in the dots. Relevant for screen-readers. Defaults to `%s flere sider`. |
| `is_loading_text` | _(optional)_ Shown until new content is inserted in to the page. Defaults to `Laster nytt innhold`. |
| `load_button_text` | _(optional)_ Used during infinity mode. If `use_load_button` is set to `true`, then a button is show on the bottom. If the `startup_page` is higher than 1. Defaults to `Vis mer innhold`. |
| `loadButton` | _(optional)_ Used to set load button text and icon aligment. Accepts a function returning a ReactNode too, so you can replace the button with your own component. |
| `disabled` | _(optional)_ if set to `true`, all pagination bar buttons are disabled. |
| `skeleton` | _(optional)_ if set to `true`, an overlaying skeleton with animation will be shown. |
| [Space](/uilib/layout/space/properties) | _(optional)_ spacing properties like `top` or `bottom` are supported. |
Expand Down
34 changes: 32 additions & 2 deletions packages/dnb-eufemia/src/components/pagination/Pagination.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import * as React from 'react';
import type { SkeletonShow } from '../Skeleton';
import type { SpacingProps } from '../space/types';
import PaginationBar from './PaginationBar';
import { ButtonIconPosition } from '../Button';
type PaginationStartupPage = string | number;
type PaginationCurrentPage = string | number;
type PaginationPageCount = string | number;
Expand Down Expand Up @@ -34,6 +35,20 @@ type PaginationIndicatorElement =
| ((...args: any[]) => any)
| string;
type PaginationChildren = React.ReactNode | ((...args: any[]) => any);

type LoadButtonProps =
| (() => React.ReactNode)
| {
/**
* Used during infinity mode. If `use_load_button` is set to true, then a button is show on the bottom. If the `startup_page` is higher than 1. Defaults to `Vis mer innhold`.
*/
text: string;
/**
* Used during infinity mode. Sets the icon position on the `use_load_button`. Default: `left`.
*/
iconPosition: ButtonIconPosition;
};

export interface PaginationProps
extends Omit<React.HTMLProps<HTMLElement>, 'ref'>,
SpacingProps {
Expand Down Expand Up @@ -143,9 +158,14 @@ export interface PaginationProps
*/
is_loading_text?: string;
/**
* Used during infinity mode. If `use_load_button` is set to `true`, then a button is show on the bottom. If the `startup_page` is higher than 1. Defaults to `Vis mer innhold`.
* Used during infinity mode. If `use_load_button` is set to true, then a button is show on the bottom. If the `startup_page` is higher than 1. Defaults to `Vis mer innhold`.
* @deprecated use `loadButtonProps.text` instead
*/
load_button_text?: string;
/**
* Used to set loadButton text and icon aligment. Accepts a function returning a ReactNode too, so you can replace the button with your own component.
*/
loadButton?: LoadButtonProps;
className?: string;
/**
* The given content can be either a function or a React node, depending on your needs. A function contains several helper functions. More details down below and have a look at the examples in the demos section.
Expand Down Expand Up @@ -217,6 +237,7 @@ type PaginationInstanceIndicatorElement =
type PaginationInstanceChildren =
| React.ReactNode
| ((...args: any[]) => any);

interface PaginationInstanceProps extends SpacingProps {
/**
* The page shown in the very beginning. If `current_page` is set, then it may not make too much sense to set this as well.
Expand Down Expand Up @@ -325,9 +346,13 @@ interface PaginationInstanceProps extends SpacingProps {
is_loading_text?: string;
/**
* Used during infinity mode. If `use_load_button` is set to true, then a button is show on the bottom. If the `startup_page` is higher than 1. Defaults to `Vis mer innhold`.
* @deprecated use `loadButtonProps.text` instead
*/
load_button_text?: string;
className?: string;
/**
* Used to set loadButton text and icon aligment. Accepts a function returning a ReactNode too, so you can replace the button with your own component.
*/
loadButton?: LoadButtonProps;
/**
* The given content can be either a function or a React node, depending on your needs. A function contains several helper functions. More details down below and have a look at the examples in the demos section.
*/
Expand Down Expand Up @@ -500,8 +525,13 @@ interface InfinityMarkerProps extends SpacingProps {
is_loading_text?: string;
/**
* Used during infinity mode. If `use_load_button` is set to true, then a button is show on the bottom. If the `startup_page` is higher than 1. Defaults to `Vis mer innhold`.
* @deprecated use `loadButtonProps.text` instead
*/
load_button_text?: string;
/**
* Used to set loadButton text and icon aligment. Accepts a function returning a ReactNode too, so you can replace the button with your own component.
*/
loadButton?: LoadButtonProps;
className?: string;
/**
* The given content can be either a function or a React node, depending on your needs. A function contains several helper functions. More details down below and have a look at the examples in the demos section.
Expand Down
2 changes: 2 additions & 0 deletions packages/dnb-eufemia/src/components/pagination/Pagination.js
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ const paginationPropTypes = {
more_pages: PropTypes.string,
is_loading_text: PropTypes.string,
load_button_text: PropTypes.string,
loadButton: PropTypes.oneOfType([PropTypes.func, PropTypes.object]),

...spacingPropTypes,

Expand Down Expand Up @@ -125,6 +126,7 @@ const paginationDefaultProps = {
more_pages: null,
is_loading_text: null,
load_button_text: null,
loadButton: null,
startup_count: 1,
parallel_load_count: 1,
place_maker_before_content: false,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -282,6 +282,8 @@ export default class InfinityScroller extends React.PureComponent {
fallback_element,
marker_element,
indicator_element,
load_button_text,
loadButton,
} = this.context.pagination

// invoke startup if needed
Expand Down Expand Up @@ -351,8 +353,14 @@ export default class InfinityScroller extends React.PureComponent {
pageNumber > 1 &&
pageNumber <= startupPage && (
<InfinityLoadButton
element={fallback_element}
element={
typeof loadButton === 'function'
? loadButton
: fallback_element
}
icon="arrow_up"
text={load_button_text ?? loadButton?.text}
icon_position={loadButton?.iconPosition}
on_click={(event) =>
this.getNewContent(pageNumber - 1, {
position: 'before',
Expand All @@ -379,7 +387,13 @@ export default class InfinityScroller extends React.PureComponent {
(typeof pageCount === 'undefined' ||
pageNumber < pageCount) && (
<InfinityLoadButton
element={fallback_element}
element={
typeof loadButton === 'function'
? loadButton
: fallback_element
}
text={load_button_text ?? loadButton?.text}
icon_position={loadButton?.iconPosition}
icon="arrow_down"
on_click={(event) =>
this.getNewContent(pageNumber + 1, {
Expand Down Expand Up @@ -528,11 +542,15 @@ export class InfinityLoadButton extends React.PureComponent {
]),
icon: PropTypes.string.isRequired,
on_click: PropTypes.func.isRequired,
text: PropTypes.string,
icon_position: PropTypes.string,
}
static defaultProps = {
element: 'div',
pressed_element: null,
icon: 'arrow_down',
text: null,
icon_position: 'left',
}
state = { isPressed: false }
onClickHandler = (e) => {
Expand All @@ -542,7 +560,7 @@ export class InfinityLoadButton extends React.PureComponent {
}
}
render() {
const { element, icon } = this.props
const { element, icon, text, icon_position } = this.props
const Element = element
const ElementChild = isTrElement(Element) ? 'td' : 'div'

Expand All @@ -554,8 +572,10 @@ export class InfinityLoadButton extends React.PureComponent {
<Button
size="medium"
icon={icon}
icon_position="left"
text={this.context.translation.Pagination.load_button_text}
icon_position={icon_position}
text={
text || this.context.translation.Pagination.load_button_text
}
variant="secondary"
on_click={this.onClickHandler}
/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -746,6 +746,62 @@ describe('Infinity scroller', () => {
document.querySelector('.dnb-pagination__indicator')
).not.toBeInTheDocument()
})

it('should forward load button props', async () => {
const action = ({ pageNumber, setContent }) => {
setContent(pageNumber, <PageItem>{pageNumber}</PageItem>)
}

const on_startup = jest.fn(action)

render(
<Pagination
mode="infinity"
{...props}
on_startup={on_startup}
use_load_button
loadButton={{ text: 'Load please', iconPosition: 'right' }}
/>
)

await waitForComponent()

const loadButton = document.querySelector(
'.dnb-button--secondary'
) as HTMLButtonElement

expect(loadButton).toHaveTextContent('Load please')
expect(loadButton).toHaveClass('dnb-button--icon-position-right')
})

it('should accept custom component as value for loadButton', async () => {
const action = ({ pageNumber, setContent }) => {
setContent(pageNumber, <PageItem>{pageNumber}</PageItem>)
}

const on_startup = jest.fn(action)

render(
<Pagination
mode="infinity"
{...props}
on_startup={on_startup}
use_load_button
loadButton={() => (
<button className="my-cool-button">The best load button</button>
)}
/>
)

await waitForComponent()

const loadButton = document.querySelector(
'.my-cool-button'
) as HTMLButtonElement

expect(loadButton).toHaveTextContent('The best load button')
expect(loadButton.tagName).toBe('BUTTON')
})
})

describe('Pagination ARIA', () => {
Expand Down

0 comments on commit 645a7b3

Please sign in to comment.