Skip to content

Commit

Permalink
add Value.Upload component
Browse files Browse the repository at this point in the history
  • Loading branch information
langz committed Nov 6, 2024
1 parent 5600766 commit adb8eef
Show file tree
Hide file tree
Showing 12 changed files with 352 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,16 @@ import ComponentBox from '../../../../../../shared/tags/ComponentBox'
import { Card } from '@dnb/eufemia/src'
import { Field, Form, Value } from '@dnb/eufemia/src/extensions/forms'

function createMockFile(name: string, size: number, type: string) {
const file = new File([], name, { type })
Object.defineProperty(file, 'size', {
get() {
return size
},
})
return file
}

export const DefaultLayout = () => {
return (
<ComponentBox data-visual-test="forms-value-summary-list-default">
Expand Down Expand Up @@ -132,15 +142,24 @@ export function InheritVisibility() {

export function InheritLabel() {
return (
<ComponentBox>
<ComponentBox scope={{ createMockFile }}>
<Form.Handler>
<Card stack>
<Field.String path="/foo" defaultValue="foo" label="foo label" />
<Field.String path="/bar" defaultValue="bar" label="bar label" />
<Field.Upload
path="/baz"
defaultValue={[
{ file: createMockFile('fileName-1.png', 100, 'image/png') },
{ file: createMockFile('fileName-2.png', 200, 'image/png') },
]}
label="baz label"
/>

<Value.SummaryList inheritLabel>
<Value.String path="/foo" />
<Value.String path="/bar" />
<Value.Upload path="/baz" />
</Value.SummaryList>
</Card>
</Form.Handler>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
---
title: 'Upload'
description: '`Value.Upload` will render the selected country.'
componentType: 'feature-value'
showTabs: true
tabs:
- title: Info
key: '/info'
- title: Demos
key: '/demos'
- title: Properties
key: '/properties'
breadcrumb:
- text: Forms
href: /uilib/extensions/forms/
- text: Value
href: /uilib/extensions/forms/Value/
- text: Upload
href: /uilib/extensions/forms/Value/Upload/
---

import Info from 'Docs/uilib/extensions/forms/Value/Upload/info'
import Demos from 'Docs/uilib/extensions/forms/Value/Upload/demos'

<Info />
<Demos />
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
import ComponentBox from '../../../../../../shared/tags/ComponentBox'
import { P } from '@dnb/eufemia/src'
import { Form, Value } from '@dnb/eufemia/src/extensions/forms'

function createMockFile(name: string, size: number, type: string) {
const file = new File([], name, { type })
Object.defineProperty(file, 'size', {
get() {
return size
},
})
return file
}

export const Placeholder = () => {
return (
<ComponentBox>
<Value.Upload placeholder="No values given" />
</ComponentBox>
)
}

export const WithValue = () => {
return (
<ComponentBox scope={{ createMockFile }}>
<Value.Upload
value={[
{ file: createMockFile('fileName-1.png', 100, 'image/png') },
{ file: createMockFile('fileName-2.png', 200, 'image/png') },
]}
/>
</ComponentBox>
)
}

export const Label = () => {
return (
<ComponentBox>
<Value.Upload label="Label text" showEmpty />
</ComponentBox>
)
}

export const LabelAndValue = () => {
return (
<ComponentBox scope={{ createMockFile }}>
<Value.Upload
label="Label text"
value={[
{ file: createMockFile('fileName-1.png', 100, 'image/png') },
{ file: createMockFile('fileName-2.png', 200, 'image/png') },
]}
/>
</ComponentBox>
)
}

export const Inline = () => {
return (
<ComponentBox scope={{ createMockFile }}>
<P>
This is before the component
<Value.Upload
value={[
{ file: createMockFile('fileName-1.png', 100, 'image/png') },
{ file: createMockFile('fileName-2.png', 200, 'image/png') },
]}
inline
/>
This is after the component
</P>
</ComponentBox>
)
}

export const WithPath = () => {
return (
<ComponentBox scope={{ createMockFile }}>
<Form.Handler
data={{
myFiles: [
{ file: createMockFile('fileName-1.png', 100, 'image/png') },
{ file: createMockFile('fileName-2.png', 200, 'image/png') },
],
}}
>
<Value.Upload path="/myFiles" />
</Form.Handler>
</ComponentBox>
)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
---
showTabs: true
---

import * as Examples from './Examples'

## Demos

### Placeholder

<Examples.Placeholder />

### Value

<Examples.WithValue />

### Label

<Examples.Label />

### Label and value

<Examples.LabelAndValue />

### With path

<Examples.WithPath />

### Inline

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

## Description

`Value.SelectCountry` will render the selected country.

```jsx
import { Value } from '@dnb/eufemia/extensions/forms'
render(<Value.SelectCountry path="/country" />)
```

There is a corresponding [Field.SelectCountry](/uilib/extensions/forms/feature-fields/SelectCountry) component.

### The `useCountry` hook

You can use the `Value.SelectCountry.useCountry` hook to get the country name by ISO code. It returns the country name in the current locale.

```tsx
import { Value } from '@dnb/eufemia/extensions/forms'

const MyComponent = () => {
const { getCountryNameByIso } = Value.SelectCountry.useCountry('NO')
}
```

### TransformIn and TransformOut

You can use the `transformIn` and `transformOut` to transform the value before it gets displayed in the field and before it gets sent to the form. The second parameter is the country object. You may have a look at the demo below to see how it works.

```tsx
const transformOut = (value, country) => {
if (value) {
return `${country.name} (${value})`
}
}
const transformIn = (value) => {
return String(value).match(/\((.*)\)/)?.[1]
}
```

### onFocus, onBlur, onChange

These events have an additional parameter with the country object.

```tsx
const onFocus = (value, country) => {}
```

## The country object

```ts
{
cdc: '47',
iso: 'NO',
name: 'Norge',
i18n: { en: 'Norway', nb: 'Norge' },
regions: ['Scandinavia', 'Nordic'],
continent: 'Europe',
}
```
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
---
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 { ValueProperties } from '@dnb/eufemia/src/extensions/forms/Value/ValueDocs'

## Properties

<PropertiesTable props={ValueProperties} />

## Translations

<TranslationsTable localeKey={['Upload', 'Field']} />
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@ breadcrumb:

# Change log

## 10.55

- Added [Value.Upload](/uilib/extensions/forms/Value/Upload/) component to render a file value.

Change log for the Eufemia Forms extension.

## v10.54
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ import { Field } from '@dnb/eufemia/extensions/forms'
render(<Field.Upload />)
```

There is a corresponding [Value.Upload](/uilib/extensions/forms/Value/Upload) component.

## The data and file format

The returned data is an array of objects containing a file object and a unique ID. The file object contains the file itself and some additional properties like an unique ID.
Expand Down
23 changes: 23 additions & 0 deletions packages/dnb-eufemia/src/extensions/forms/Value/Upload/Upload.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import React from 'react'
import classnames from 'classnames'
import ValueBlock from '../../ValueBlock'
import { useValueProps } from '../../hooks'
import { ValueProps } from '../../types'

export type Props = ValueProps<string>

function Upload(props: Props) {
const { value, className, ...rest } = useValueProps(props)
console.log(value)
return (
<ValueBlock
className={classnames('dnb-forms-value-string', className)}
{...rest}
>
{'value'}
</ValueBlock>
)
}

Upload._supportsSpacingProps = true
export default Upload
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
import React from 'react'
import { screen, render } from '@testing-library/react'
import { Value, Form } from '../../..'

describe('Value.SelectCountry', () => {
it('renders string values', () => {
render(<Value.SelectCountry value="NO" />)

expect(
document.querySelector(
'.dnb-forms-value-select-country .dnb-forms-value-block__content'
)
).toHaveTextContent('Norge')
})

it('renders label when showEmpty is true', () => {
render(<Value.SelectCountry showEmpty label="My label" />)
expect(document.querySelector('.dnb-form-label')).toHaveTextContent(
'My label'
)
})

it('renders value and label', () => {
render(<Value.SelectCountry label="My selections" value="NO" />)
expect(
document.querySelector(
'.dnb-forms-value-select-country .dnb-forms-value-block__content'
)
).toHaveTextContent('Norge')

expect(document.querySelector('.dnb-form-label')).toHaveTextContent(
'My selections'
)
})

it('renders custom label', () => {
render(<Value.SelectCountry label="Custom label" showEmpty />)
expect(document.querySelector('.dnb-form-label')).toHaveTextContent(
'Custom label'
)
})

it('renders placeholder', () => {
render(<Value.SelectCountry placeholder="Please select a value" />)
expect(screen.getByText('Please select a value')).toBeInTheDocument()
})

it('renders value from path', () => {
render(
<Form.Handler data={{ myCountry: 'CH' }}>
<Value.SelectCountry path="/myCountry" />
</Form.Handler>
)

expect(
document.querySelector(
'.dnb-forms-value-select-country .dnb-forms-value-block__content'
)
).toHaveTextContent('Sveits')
})

it('formats value in different locale', () => {
render(
<Form.Handler locale="en-GB" data={{ myCountry: 'CH' }}>
<Value.SelectCountry path="/myCountry" />
</Form.Handler>
)

expect(
document.querySelector(
'.dnb-forms-value-select-country .dnb-forms-value-block__content'
)
).toHaveTextContent('Switzerland')
})
})
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export { default } from './Upload'
export * from './Upload'
Loading

0 comments on commit adb8eef

Please sign in to comment.