Skip to content

Commit

Permalink
feat(ListFormat): add ListFormat component (#4238)
Browse files Browse the repository at this point in the history
  • Loading branch information
langz authored Nov 8, 2024
1 parent 8b96fd1 commit 63613f1
Show file tree
Hide file tree
Showing 25 changed files with 1,603 additions and 141 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
---
title: 'ListFormat'
description: 'A ready to use DNB list formatter.'
showTabs: true
tabs:
- title: Info
key: /uilib/components/list-format/info
- title: Demos
key: /uilib/components/list-format/demos
- title: Properties
key: /uilib/components/list-format/properties
theme: 'sbanken'
status: 'new'
---

import ListFormatInfo from 'Docs/uilib/components/list-format/info'
import ListFormatDemos from 'Docs/uilib/components/list-format/demos'

<ListFormatInfo />
<ListFormatDemos />
Original file line number Diff line number Diff line change
@@ -0,0 +1,221 @@
/**
* UI lib Component Example
*
*/

import React from 'react'
import ComponentBox from '../../../../shared/tags/ComponentBox'
import { Provider } from '@dnb/eufemia/src/shared'
import { ListFormat, P, Badge, Anchor } from '@dnb/eufemia/src'
import { listFormat } from '@dnb/eufemia/src/components/list-format/ListFormat'

export const UsingListFormatFunction = () => {
return (
<ComponentBox
data-visual-test="list-format-function"
scope={{ listFormat }}
>
{listFormat(
[
<React.Fragment key="a">A</React.Fragment>,
<>
<b>B</b>
</>,
<>C</>,
'D',
123,
<Anchor
target="_blank"
href="https://github.com/dnbexperience/eufemia"
rel="noopener noreferrer"
key="github"
>
Link to Eufemia's Github Repo
</Anchor>,
<>
Text <Badge content="Info" variant="information" /> Text
</>,
],
{
format: { type: 'disjunction' },
locale: 'en-US',
},
)}
</ComponentBox>
)
}

export const WithValue = () => {
return (
<ComponentBox data-visual-test="list-format-default">
<ListFormat
value={[
<React.Fragment key="a">A</React.Fragment>,
<>
<b>B</b>
</>,
<>C</>,
'D',
123,
<Anchor
target="_blank"
href="https://github.com/dnbexperience/eufemia"
rel="noopener noreferrer"
key="github"
>
Link to Eufemia's Github Repo
</Anchor>,
<>
Text <Badge content="Info" variant="information" /> Text
</>,
]}
/>
</ComponentBox>
)
}

export const WithChildren = () => {
return (
<ComponentBox>
<ListFormat>
<React.Fragment key="a">A</React.Fragment>
<>
<b>B</b>
</>
<>C</>
<>D</>
123
<Anchor
target="_blank"
href="https://github.com/dnbexperience/eufemia"
rel="noopener noreferrer"
key="github"
>
Link to Eufemia's Github Repo
</Anchor>
<>
Text <Badge content="Info" variant="information" /> Text
</>
</ListFormat>
</ComponentBox>
)
}

export const WithCustomFormat = () => {
return (
<ComponentBox data-visual-test="list-format-custom-format">
<Provider locale="en-GB">
<ListFormat
value={[
<React.Fragment key="a">A</React.Fragment>,
<>
<b>B</b>
</>,
<>C</>,
'D',
123,
<Anchor
target="_blank"
href="https://github.com/dnbexperience/eufemia"
rel="noopener noreferrer"
key="github"
>
Link to Eufemia's Github Repo
</Anchor>,
<>
Text <Badge content="Info" variant="information" /> Text
</>,
]}
format={{ type: 'disjunction' }}
/>
</Provider>
</ComponentBox>
)
}

export const Inline = () => {
return (
<ComponentBox data-visual-test="list-format-inline">
<P>
This is before the component{' '}
<ListFormat
value={[
123,
<Anchor
target="_blank"
href="https://github.com/dnbexperience/eufemia"
rel="noopener noreferrer"
key="github"
>
Link to Eufemia's Github Repo
</Anchor>,
<>
Text <Badge content="Info" variant="information" /> Text
</>,
]}
/>{' '}
This is after the component
</P>
</ComponentBox>
)
}

export const ListVariants = () => {
return (
<ComponentBox data-visual-test="list-format-variants">
<P>Ordered List:</P>
<ListFormat value={['Foo', 'Bar', 'Baz']} variant="ol" />
<P>Unordered List:</P>
<ListFormat value={['Foo', 'Bar', 'Baz']} variant="ul" />
</ComponentBox>
)
}

export const ListTypes = () => {
return (
<ComponentBox data-visual-test="list-format-types">
<P>Ordered List a:</P>
<ListFormat
value={['Foo', 'Bar', 'Baz']}
variant="ol"
listType="a"
/>
<P>Ordered List A:</P>
<ListFormat
value={['Foo', 'Bar', 'Baz']}
variant="ol"
listType="A"
/>
<P>Ordered List i:</P>
<ListFormat
value={['Foo', 'Bar', 'Baz']}
variant="ol"
listType="i"
/>
<P>Ordered List I:</P>
<ListFormat
value={['Foo', 'Bar', 'Baz']}
variant="ol"
listType="I"
/>
<P>Unordered List square:</P>
<ListFormat
value={['Foo', 'Bar', 'Baz']}
variant="ul"
listType="square"
/>
<P>Unordered List circle:</P>
<ListFormat
value={['Foo', 'Bar', 'Baz']}
variant="ul"
listType="circle"
/>
<P>Unordered List unstyled:</P>
<ListFormat
value={['Foo', 'Bar', 'Baz']}
variant="ul"
listType="unstyled"
/>
</ComponentBox>
)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
---
showTabs: true
---

import * as Examples from './Examples'

## Demos

### Basic usage with `value`

<Examples.WithValue />

### Basic usage with `children`

<Examples.WithChildren />

### Custom format

<Examples.WithCustomFormat />

### Inline

<Examples.Inline />

### List variants

<Examples.ListVariants />

### List types

<Examples.ListTypes />

### Using listFormat function

<Examples.UsingListFormatFunction />
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
---
showTabs: true
---

## Import

```tsx
import { ListFormat } from '@dnb/eufemia'
```

## Description

A ready-to-use list formatter. Use it wherever you have to display a list of strings, numbers, or React components (JSX).

Good reasons for why we have this is to:

- Uniform the creation and formatting of lists.
- Supports translation and localization.
- Built on top of web standards.

The component is designed to maximum display 10-20 items.
If you need to display more items than that, consider a different design, and perhaps using [Pagination](/uilib/components/pagination) and/or [InfinityScroller](/uilib/components/pagination/infinity-scroller).

When the `variant` property is set to `text` (default), the browser API [Intl.ListFormat](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/ListFormat) will be used with additional React components (JSX) support.

When the `variant` is set to a non-`text` variant, it uses [Lists](/uilib/elements/lists/) to render the given list.

## Formatting only

You can use the `listFormat` function without using the React Component `ListFormat`, to format strings, numbers, or React components (JSX) as a string. It does not return lists(ol, ul, etc).

```ts
import { listFormat } from '@dnb/eufemia/components/ListFormat'

return listFormat(myList, {
format: { type: 'disjunction' },
locale: 'en-US',
})
```

See the following [demo](/uilib/components/list-format/demos/#using-listformat-function) for a more detailed example.

The `listFormat` function supports an object with `{ format, locale }` as the second parameter. `format` and `locale` will accept the same values as documented in [properties](/uilib/components/list-format/properties/) of the `ListFormat` component.
The function does not support `variant` and `listType`, as it does not return a list, but rather return a string.
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
---
showTabs: true
---

import TranslationsTable from 'dnb-design-system-portal/src/shared/parts/TranslationsTable'
import PropertiesTable from 'dnb-design-system-portal/src/shared/parts/PropertiesTable'
import { ListFormatProperties } from '@dnb/eufemia/src/components/list-format/ListFormatDocs'

## Properties

<PropertiesTable props={ListFormatProperties} />
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ export const ListVariants = () => {

export const ListTypes = () => {
return (
<ComponentBox>
<ComponentBox hideCode>
<Value.ArraySelection
value={['Foo', 'Bar', 'Baz']}
label="Ordered List a"
Expand Down Expand Up @@ -161,6 +161,12 @@ export const ListTypes = () => {
variant="ul"
listType="circle"
/>
<Value.ArraySelection
value={['Foo', 'Bar', 'Baz']}
label="Unordered List unstyled"
variant="ul"
listType="unstyled"
/>
</ComponentBox>
)
}
2 changes: 2 additions & 0 deletions packages/dnb-eufemia/src/components/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ import IconPrimary from './icon-primary/IconPrimary'
import InfoCard from './info-card/InfoCard'
import Input from './input/Input'
import InputMasked from './input-masked/InputMasked'
import ListFormat from './list-format/ListFormat'
import Logo from './logo/Logo'
import Modal from './modal/Modal'
import NumberFormat from './number-format/NumberFormat'
Expand Down Expand Up @@ -99,6 +100,7 @@ export {
InfoCard,
Input,
InputMasked,
ListFormat,
Logo,
Modal,
NumberFormat,
Expand Down
2 changes: 2 additions & 0 deletions packages/dnb-eufemia/src/components/lib.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ import IconPrimary from './icon-primary/IconPrimary'
import InfoCard from './info-card/InfoCard'
import Input from './input/Input'
import InputMasked from './input-masked/InputMasked'
import ListFormat from './list-format/ListFormat'
import Logo from './logo/Logo'
import Modal from './modal/Modal'
import NumberFormat from './number-format/NumberFormat'
Expand Down Expand Up @@ -157,6 +158,7 @@ export const getComponents = () => {
InfoCard,
Input,
InputMasked,
ListFormat,
Logo,
Modal,
NumberFormat,
Expand Down
Loading

0 comments on commit 63613f1

Please sign in to comment.