Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(Forms): add variant="filled" and toolbarVariant="custom" to Iterate.EditContainer and Iterate.ViewContainer #4329

Merged
merged 1 commit into from
Nov 25, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import ComponentBox from '../../../../../../shared/tags/ComponentBox'
import { Flex, Table, Td, Th, Tr } from '@dnb/eufemia/src'
import { Avatar, Flex, Table, Td, Th, Tr } from '@dnb/eufemia/src'
import {
Iterate,
Field,
Expand Down Expand Up @@ -565,3 +565,135 @@ export const WithArrayValidator = () => {
</ComponentBox>
)
}

export const FilledViewAndEditContainer = () => {
return (
<ComponentBox
data-visual-test="filled-view-and-edit-container"
hideCode
>
{() => {
const MyEditItemForm = () => {
return (
<Flex.Stack>
<Field.Name.First itemPath="/firstName" required />
<Field.Name.Last itemPath="/lastName" required />
</Flex.Stack>
)
}

const EditItemToolbar = () => {
return (
<Iterate.Toolbar>
<Flex.Horizontal
justify="space-between"
style={{ width: '100%' }}
>
<Flex.Horizontal gap="large">
<Iterate.EditContainer.DoneButton />
<Iterate.EditContainer.CancelButton />
</Flex.Horizontal>
<Iterate.ViewContainer.RemoveButton left={false} />
</Flex.Horizontal>
</Iterate.Toolbar>
)
}

const MyEditItem = (props) => {
return (
<Iterate.EditContainer
variant="filled"
toolbarVariant="custom"
toolbar={<EditItemToolbar />}
{...props}
>
<ValueWithAvatar />
<MyEditItemForm />
</Iterate.EditContainer>
)
}

const CreateNewEntry = () => {
return (
<Iterate.PushContainer
path="/accounts"
title="New account holder"
variant="filled"
openButton={
<Iterate.PushContainer.OpenButton text="Add another account" />
}
showOpenButtonWhen={(list) => list.length > 0}
>
<MyEditItemForm />
</Iterate.PushContainer>
)
}

const ValueWithAvatar = () => {
const { value } = Iterate.useItem()
const firstName = String(value['firstName'] || '')
return (
<Flex.Horizontal align="center">
<Avatar.Group label={firstName}>
<Avatar>{firstName.substring(0, 1).toUpperCase()}</Avatar>
</Avatar.Group>
<Value.String itemPath="/firstName" />
</Flex.Horizontal>
)
}

const MyViewItem = () => {
return (
<Iterate.ViewContainer
variant="filled"
toolbarVariant="custom"
toolbar={<></>}
>
<Flex.Horizontal align="center" justify="space-between">
<ValueWithAvatar />

<Iterate.Toolbar>
<Iterate.ViewContainer.EditButton />
</Iterate.Toolbar>
</Flex.Horizontal>
</Iterate.ViewContainer>
)
}

return (
<Form.Handler
data={{
accounts: [
{
firstName:
'Tony with long name that maybe will wrap over to a new line',
lastName: 'Last',
},
{
firstName: 'Maria',
lastName: 'Last',
},
],
}}
onSubmit={(data) => console.log('onSubmit', data)}
onSubmitRequest={() => console.log('onSubmitRequest')}
>
<Flex.Vertical>
<Form.MainHeading>Accounts</Form.MainHeading>

<Form.Card>
<Iterate.Array path="/accounts" limit={2}>
<MyViewItem />
<MyEditItem />
</Iterate.Array>
<CreateNewEntry />
</Form.Card>

<Form.SubmitButton variant="send" />
</Flex.Vertical>
</Form.Handler>
)
}}
</ComponentBox>
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,13 @@ With an optional `title` and [Iterate.Toolbar](/uilib/extensions/forms/Iterate/T

<Examples.ViewAndEditContainer />

### Customize the view and edit containers

- Using `variant="filled"` will render the [ViewContainer](/uilib/extensions/forms/Iterate/ViewContainer) and [EditContainer](/uilib/extensions/forms/Iterate/EditContainer) with a background color.
- Using `toolbarVariant="custom"` will render the [Toolbar](/uilib/extensions/forms/Iterate/Toolbar/) without any spacing so you can customize it to your needs.

<Examples.FilledViewAndEditContainer />

### Initially open

<Examples.InitiallyOpen />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,8 +55,9 @@ You can get the internal item object by using the `Iterate.useItem` hook.
import { Iterate, Field, Value } from '@dnb/eufemia/extensions/forms'

const MyItemForm = () => {
const item = Iterate.useItem()
console.log('index:', item.index)
// TypeScript type inference
const item = Iterate.useItem<{ foo: string }>()
console.log('My item:', item.index, item.value.foo)

return <Field.String itemPath="/" />
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ export const EditContainerProperties: PropertiesTableProps = {
status: 'optional',
},
variant: {
doc: 'Defines the variant of the container. Can be `outline` or `basic`. Defaults to `outline`.',
doc: 'Defines the variant of the container. Can be `outline`, `filled` or `basic`. Defaults to `outline`.',
type: 'string',
status: 'optional',
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -559,7 +559,7 @@ describe('EditContainer and ViewContainer', () => {
)
})

it('should set variant to "basic" when variant is set to "basic"', async () => {
it('should set correct class for variant "basic"', () => {
render(
<Form.Section>
<Form.Section.ViewContainer variant="basic">
Expand All @@ -579,6 +579,30 @@ describe('EditContainer and ViewContainer', () => {
expect(editBlock).toHaveClass('dnb-forms-section-block--variant-basic')
})

it('should set correct class for variant "filled"', () => {
render(
<Form.Section>
<Form.Section.ViewContainer variant="filled">
View Content
</Form.Section.ViewContainer>

<Form.Section.EditContainer variant="filled">
Edit Content
</Form.Section.EditContainer>
</Form.Section>
)

const [viewBlock, editBlock] = Array.from(
document.querySelectorAll('.dnb-forms-section-block')
)
expect(viewBlock).toHaveClass(
'dnb-forms-section-block--variant-filled'
)
expect(editBlock).toHaveClass(
'dnb-forms-section-block--variant-filled'
)
})

it('should validate on done button click', async () => {
render(
<Form.Section>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ export const ViewContainerProperties: PropertiesTableProps = {
status: 'optional',
},
variant: {
doc: 'Defines the variant of the container. Can be `outline` or `basic`. Defaults to `outline`.',
doc: 'Defines the variant of the container. Can be `outline`, `filled` or `basic`. Defaults to `outline`.',
type: 'string',
status: 'optional',
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ export type SectionContainerProps = {
* Defines the variant of the ViewContainer or EditContainer. Can be `outline`.
* Defaults to `outline`.
*/
variant?: 'outline' | 'basic'
variant?: 'outline' | 'basic' | 'filled'
}

export type Props = {
Expand Down Expand Up @@ -126,6 +126,7 @@ function SectionContainer(props: Props & FlexContainerProps) {
<Card
stack
innerSpace={variant === 'basic' ? false : 'small'}
filled={variant === 'filled'}
className="dnb-forms-section-block__inner"
{...restProps}
aria-label={ariaLabel}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,6 @@
flex-direction: column;
}

&--variant-basic {
--border-color: transparent;
.dnb-card {
--card-outline-color: transparent;
}
}

&__inner {
flex: 1;
outline: none; // for JavaSCript focus
Expand All @@ -43,6 +36,18 @@
}
}

&--variant-basic {
--border-color: transparent;
.dnb-card {
--card-outline-color: transparent;
}
}

&--variant-filled &__inner {
--space: var(--spacing-small);
background-color: var(--color-lavender);
}

&--no-animation &__inner {
transform: translateY(0);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
.dnb-forms-section {
&-block {
&--variant-filled &__inner {
--space: var(--spacing-small);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
.dnb-forms-section {
&-block {
&--variant-filled &__inner {
--space: var(--spacing-small);
background-color: var(--color-lavender);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
/**
* Imports the default theme
*
*/

import './dnb-section-theme-ui.scss'
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,11 @@ const useLayoutEffect =

export type ArrayItemAreaProps = {
/**
* Defines the variant of the ViewContainer, EditContainer or PushContainer. Can be `outline` or `basic`.
* Defines the variant of the ViewContainer, EditContainer or PushContainer. Can be `outline`, `filled` or `basic`.
* Defaults to `outline`.
*/
variant?: 'outline' | 'basic'
variant?: 'outline' | 'basic' | 'filled'
toolbarVariant?: 'minimumOneItem' | 'custom'
}

export type Props = {
Expand All @@ -40,6 +41,7 @@ function ArrayItemArea(props: Props & FlexContainerProps) {
children,
openDelay = 100,
variant = 'outline',
toolbarVariant,
...restProps
} = props

Expand Down Expand Up @@ -168,7 +170,9 @@ function ArrayItemArea(props: Props & FlexContainerProps) {
}, [handleRemove, index, setOpenState])

return (
<ArrayItemAreaContext.Provider value={{ handleRemoveItem }}>
<ArrayItemAreaContext.Provider
value={{ handleRemoveItem, variant, toolbarVariant }}
>
<HeightAnimation
className={classnames(
'dnb-forms-section-block',
Expand All @@ -184,7 +188,8 @@ function ArrayItemArea(props: Props & FlexContainerProps) {
>
<Card
stack
innerSpace="small"
filled={variant === 'filled'}
innerSpace={variant === 'basic' ? false : 'small'}
className="dnb-forms-section-block__inner"
{...restProps}
aria-label={ariaLabel}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
import { createContext } from 'react'
import { ArrayItemAreaProps } from './ArrayItemArea'

type ArrayItemAreaContext = {
handleRemoveItem?: () => void
variant?: ArrayItemAreaProps['variant']
toolbarVariant?: ArrayItemAreaProps['toolbarVariant']
}

const ArrayItemAreaContext = createContext<ArrayItemAreaContext>(null)
Expand Down
Loading
Loading