Skip to content

Commit

Permalink
fix(FieldBlock): label can be clicked after focusing input (#3190)
Browse files Browse the repository at this point in the history
Fixes #2979

The label was an internal component and was re-initialized on each re-render of FieldBlock. Fixed by removing the internal component and instead just generating the props.

---------

Co-authored-by: Tobias Høegh <[email protected]>
  • Loading branch information
snorrekim and tujoworker authored Jan 9, 2024
1 parent 16ed821 commit 95b37e7
Show file tree
Hide file tree
Showing 3 changed files with 69 additions and 16 deletions.
25 changes: 10 additions & 15 deletions packages/dnb-eufemia/src/extensions/forms/FieldBlock/FieldBlock.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { Space, FormLabel, FormStatus } from '../../../components'
import { FormError, ComponentProps, FieldProps } from '../types'
import FieldBlockContext from './FieldBlockContext'
import { findElementInChildren } from '../../../shared/component-helper'
import type { FormLabelAllProps } from '../../../components/FormLabel'

export type Props = Pick<
FieldProps,
Expand Down Expand Up @@ -146,18 +147,12 @@ function FieldBlock(props: Props) {
? 'info'
: null

const Label = ({ children }) => {
return (
<FormLabel
element={enableFieldset ? 'legend' : 'label'}
forId={enableFieldset ? undefined : forId}
space={{ top: 0, bottom: 'x-small' }}
size={size}
disabled={disabled}
>
{children}
</FormLabel>
)
const labelProps: FormLabelAllProps = {
element: enableFieldset ? 'legend' : 'label',
forId: enableFieldset ? undefined : forId,
space: { top: 0, bottom: 'x-small' },
size,
disabled,
}

return (
Expand All @@ -176,14 +171,14 @@ function FieldBlock(props: Props) {
{labelDescription || labelSecondary ? (
<div className="dnb-forms-field-block__label">
{label || labelDescription ? (
<Label>
<FormLabel {...labelProps}>
{label}
{labelDescription && (
<span className="dnb-forms-field-block__label-description">
{labelDescription}
</span>
)}
</Label>
</FormLabel>
) : (
<>&nbsp;</>
)}
Expand All @@ -194,7 +189,7 @@ function FieldBlock(props: Props) {
)}
</div>
) : (
label && <Label>{label}</Label>
label && <FormLabel {...labelProps}>{label}</FormLabel>
)}

<div
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import React from 'react'
import { render } from '@testing-library/react'
import { render, waitFor } from '@testing-library/react'
import { Input } from '../../../../components'
import FieldBlock from '../FieldBlock'
import { FormError } from '../../types'
import userEvent from '@testing-library/user-event'
import { useDataValue } from '../../hooks'

describe('FieldBlock', () => {
it('should forward HTML attributes', () => {
Expand Down Expand Up @@ -144,6 +146,34 @@ describe('FieldBlock', () => {
expect(labelElement.textContent).toBe('A Secondary Label')
})

it('click on label should set focus on input after value change', async () => {
const MockComponent = () => {
const fromInput = React.useCallback(({ value }) => value, [])
const { value, handleChange } = useDataValue({
value: '',
fromInput,
})

return (
<FieldBlock label="Label" forId="unique">
<Input id="unique" value={value} on_change={handleChange} />
</FieldBlock>
)
}

render(<MockComponent />)

const label = document.querySelector('label')
const input = document.querySelector('input')

await userEvent.type(input, 'foo')
await userEvent.click(label)

await waitFor(() => {
expect(input).toHaveFocus()
})
})

it('should not use fieldset/legend elements when no label is given', () => {
render(
<FieldBlock>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import React, { useCallback } from 'react'
import FieldBlock from '../FieldBlock'
import Input from '../../../../components/Input'
import { useDataValue } from '../../hooks'

export default {
title: 'Eufemia/Extensions/Forms/FieldBlock',
}

export function FieldBlockLabel() {
const fromInput = useCallback(({ value }) => value, [])
const { value, handleChange, handleFocus, handleBlur } = useDataValue({
value: 'foo',
fromInput,
})

return (
<FieldBlock label="Label" forId="unique">
<Input
id="unique"
value={value}
on_change={handleChange}
on_focus={handleFocus}
on_blur={handleBlur}
/>
</FieldBlock>
)
}

0 comments on commit 95b37e7

Please sign in to comment.