diff --git a/packages/dnb-design-system-portal/src/docs/uilib/components/pagination/properties.mdx b/packages/dnb-design-system-portal/src/docs/uilib/components/pagination/properties.mdx index 553df00697a..7577804f262 100644 --- a/packages/dnb-design-system-portal/src/docs/uilib/components/pagination/properties.mdx +++ b/packages/dnb-design-system-portal/src/docs/uilib/components/pagination/properties.mdx @@ -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. | diff --git a/packages/dnb-eufemia/src/components/pagination/Pagination.d.ts b/packages/dnb-eufemia/src/components/pagination/Pagination.d.ts index ac55d2d1725..167e199f922 100644 --- a/packages/dnb-eufemia/src/components/pagination/Pagination.d.ts +++ b/packages/dnb-eufemia/src/components/pagination/Pagination.d.ts @@ -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; @@ -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, 'ref'>, SpacingProps { @@ -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. @@ -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. @@ -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. */ @@ -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. diff --git a/packages/dnb-eufemia/src/components/pagination/Pagination.js b/packages/dnb-eufemia/src/components/pagination/Pagination.js index d2d9e72141d..55d86d3c96b 100644 --- a/packages/dnb-eufemia/src/components/pagination/Pagination.js +++ b/packages/dnb-eufemia/src/components/pagination/Pagination.js @@ -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, @@ -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, diff --git a/packages/dnb-eufemia/src/components/pagination/PaginationInfinity.js b/packages/dnb-eufemia/src/components/pagination/PaginationInfinity.js index cbb435b8d11..509644d5620 100644 --- a/packages/dnb-eufemia/src/components/pagination/PaginationInfinity.js +++ b/packages/dnb-eufemia/src/components/pagination/PaginationInfinity.js @@ -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 @@ -351,8 +353,14 @@ export default class InfinityScroller extends React.PureComponent { pageNumber > 1 && pageNumber <= startupPage && ( this.getNewContent(pageNumber - 1, { position: 'before', @@ -379,7 +387,13 @@ export default class InfinityScroller extends React.PureComponent { (typeof pageCount === 'undefined' || pageNumber < pageCount) && ( this.getNewContent(pageNumber + 1, { @@ -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) => { @@ -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' @@ -554,8 +572,10 @@ export class InfinityLoadButton extends React.PureComponent { + )} + /> + ) + + 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', () => {