Skip to content

Commit

Permalink
feat(forms): add labelDescription prop to fields (labelSecondary go…
Browse files Browse the repository at this point in the history
…t removed) (#3251)

`labelDescription` was a part of forms before, but where removed in this
PR #3209.

But it turns out, UX wants this for form fields. This time it gets
officially included. We need to consider to add this to FormLabel at a
later stage. But that involves a lot more work.

Also, `Exipry` needed a larger rewrite in order to make
`labelDescription` work. This change will be included in this PR #3252
  • Loading branch information
tujoworker authored Jan 22, 2024
1 parent 2c9a397 commit 00c278c
Show file tree
Hide file tree
Showing 37 changed files with 120 additions and 20 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,16 @@ export const Widths = () => {
)
}

export const WithDescription = () => {
return (
<ComponentBox data-visual-test="forms-field-block-label-description">
<FieldBlock label="Label text" labelDescription="Description text">
Input features goes here
</FieldBlock>
</ComponentBox>
)
}

export const GroupMultipleFields = () => {
return (
<ComponentBox>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,10 @@ import * as Examples from './Examples'

<Examples.HorizontalWithInfo />

### With description (vertical only)

<Examples.WithDescription />

### Group multiple fields

<Examples.GroupMultipleFields />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import { OmitTableProperties } from 'dnb-design-system-portal/src/shared/tags/Ta
| `name` | `string` | _(optional)_ Outer DOM element name attribute. |
| `layout` | `string` | _(optional)_ Layout for the label and input. Can be `horizontal` or `vertical`. |
| `label` | `string` | _(optional)_ Field label to show above / before the input feature. |
| `labelDescription` | `string` | _(optional)_ A more discreet text displayed beside the label (i.e for "(optional)"). |
| `placeholder` | `string` | _(optional)_ Text showing in place of the value if no value is given. |
| `path` | `string` | _(optional)_ JSON Pointer for where the data for this input is located in the source dataset (when using Form.Handler or DataContext). The `path` will also be set as the `name` attribute for the [string](/uilib/extensions/forms/base-fields/String/)-field. |
| `info` | `Error` or `string` | _(optional)_ Info message shown below / after the input. |
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,7 @@ import DataValueReadwriteProperties from '../../data-value-readwrite-properties.
| `width` | `string` or `false` | _(optional)_ `large` for predefined standard width, `stretch` for fill available width. |
| [Space](/uilib/layout/space/properties) | Various | _(optional)_ Spacing properties like `top` or `bottom` are supported. |

<DataValueReadwriteProperties type="string" omit={['layout', 'label']} />
<DataValueReadwriteProperties
type="string"
omit={['layout', 'label', 'labelDescription']}
/>
2 changes: 1 addition & 1 deletion packages/dnb-eufemia/src/components/textarea/Textarea.js
Original file line number Diff line number Diff line change
Expand Up @@ -549,7 +549,7 @@ export default class Textarea extends React.PureComponent {

{characterCounter && maxLength > 0 && (
<TextCounter
variant="down"
variant={characterCounter}
text={value}
max={maxLength}
bypassAriaLive={textareaState === 'virgin'}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -306,23 +306,23 @@ describe('Textarea component', () => {
const textarea = document.querySelector('textarea')
const ariaLive = document.querySelector('.dnb-aria-live')

expect(counter).toHaveTextContent('5 av 8 tegn gjenstår')
expect(counter).toHaveTextContent('3 av 8 tegn gjenstår')
expect(ariaLive).toHaveTextContent('')

await userEvent.type(textarea, 'bar')

expect(counter).toHaveTextContent('2 av 8 tegn gjenstår')
expect(ariaLive).toHaveTextContent('2 av 8 tegn gjenstår')
expect(counter).toHaveTextContent('6 av 8 tegn gjenstår')
expect(ariaLive).toHaveTextContent('6 av 8 tegn gjenstår')

rerender(
<Textarea maxLength={8} characterCounter value="foo" lang="en-GB" />
)

expect(counter).toHaveTextContent('2 of 8 characters remaining')
expect(counter).toHaveTextContent('6 of 8 characters remaining')

await userEvent.type(textarea, 'baz')

expect(ariaLive).toHaveTextContent('0 of 8 characters remaining')
expect(ariaLive).toHaveTextContent('8 of 8 characters remaining')
})
})

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -971,8 +971,6 @@ describe('DataContext.Provider', () => {
const id = React.useId()
const { data, update } = Form.useData<{ count: number }>(id)

console.log('data', data)

const increment = React.useCallback(() => {
update('/count', (count) => {
return count + 1
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ function ArraySelection(props: Props) {
layout = 'vertical',
optionsLayout = 'vertical',
label,
labelDescription,
value,
error,
hasError,
Expand All @@ -52,6 +53,7 @@ function ArraySelection(props: Props) {
error,
layout,
label,
labelDescription,
...pickSpacingProps(props),
}

Expand Down
2 changes: 2 additions & 0 deletions packages/dnb-eufemia/src/extensions/forms/Field/Date/Date.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ function DateComponent(props: Props) {
id,
className,
label,
labelDescription,
value,
help,
info,
Expand All @@ -79,6 +80,7 @@ function DateComponent(props: Props) {
className={classnames('dnb-forms-field-string', className)}
forId={id}
label={label ?? sharedContext?.translation.Forms.dateLabel}
labelDescription={labelDescription}
info={info}
warning={warning}
disabled={disabled}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ function Expiry(props: ExpiryProps) {
help,
disabled,
value = '',
labelDescription,
layout = 'vertical',
ariaAttributes,
handleFocus,
Expand Down Expand Up @@ -80,6 +81,7 @@ function Expiry(props: ExpiryProps) {
forId={`${id}-input-month`}
label={label}
layout={layout}
labelDescription={labelDescription}
info={info}
warning={warning}
error={error}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,7 @@ function NumberComponent(props: Props) {
layout,
placeholder,
label,
labelDescription,
value,
minimum = Number.MIN_SAFE_INTEGER,
maximum = Number.MAX_SAFE_INTEGER,
Expand Down Expand Up @@ -235,6 +236,7 @@ function NumberComponent(props: Props) {
forId: id,
layout,
label,
labelDescription,
info,
warning,
error,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ function Selection(props: Props) {
variant = 'dropdown',
clear,
label,
labelDescription,
layout = 'vertical',
optionsLayout = 'vertical',
placeholder,
Expand Down Expand Up @@ -109,6 +110,7 @@ function Selection(props: Props) {
error,
layout,
label,
labelDescription,
}

const getStatus = useCallback(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,7 @@ function StringComponent(props: Props) {
type,
placeholder,
label,
labelDescription,
value,
info,
warning,
Expand Down Expand Up @@ -184,6 +185,7 @@ function StringComponent(props: Props) {
forId={id}
layout={layout}
label={label}
labelDescription={labelDescription}
info={info}
warning={warning}
disabled={disabled}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -821,13 +821,13 @@ describe('Field.String', () => {
const textarea = document.querySelector('textarea')
const ariaLive = document.querySelector('.dnb-aria-live')

expect(counter).toHaveTextContent('5 av 8 tegn gjenstår')
expect(counter).toHaveTextContent('3 av 8 tegn gjenstår')
expect(ariaLive).toHaveTextContent('')

await userEvent.type(textarea, 'bar')

expect(counter).toHaveTextContent('2 av 8 tegn gjenstår')
expect(ariaLive).toHaveTextContent('2 av 8 tegn gjenstår')
expect(counter).toHaveTextContent('6 av 8 tegn gjenstår')
expect(ariaLive).toHaveTextContent('6 av 8 tegn gjenstår')

rerender(
<Provider locale="en-GB">
Expand All @@ -840,11 +840,11 @@ describe('Field.String', () => {
</Provider>
)

expect(counter).toHaveTextContent('2 of 8 characters remaining')
expect(counter).toHaveTextContent('6 of 8 characters remaining')

await userEvent.type(textarea, 'baz')

expect(ariaLive).toHaveTextContent('0 of 8 characters remaining')
expect(ariaLive).toHaveTextContent('8 of 8 characters remaining')
})

it('gets valid ref element', () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ function Toggle(props: Props) {
variant,
disabled,
label,
labelDescription,
textOn,
textOff,
value,
Expand Down Expand Up @@ -68,6 +69,7 @@ function Toggle(props: Props) {
...fieldBlockPropsWithoutLabel,
layout,
label,
labelDescription,
disabled,
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ export type Props = Pick<
| keyof ComponentProps
| 'layout'
| 'label'
| 'labelDescription'
| 'info'
| 'warning'
| 'error'
Expand All @@ -37,6 +38,7 @@ function FieldBlock(props: Props) {
forId,
layout = 'vertical',
label,
labelDescription,
asFieldset,
info,
warning,
Expand Down Expand Up @@ -164,7 +166,24 @@ function FieldBlock(props: Props) {
{...rest}
>
<div className={gridClasses}>
{label && <FormLabel {...labelProps}>{label}</FormLabel>}
{labelDescription ? (
<div className="dnb-forms-field-block__label">
{label || labelDescription ? (
<FormLabel {...labelProps}>
{label}
{labelDescription && (
<span className="dnb-forms-field-block__label-description">
{labelDescription}
</span>
)}
</FormLabel>
) : (
<>&nbsp;</>
)}
</div>
) : (
label && <FormLabel {...labelProps}>{label}</FormLabel>
)}

<div
className={classnames(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,9 @@ import {
setupPageScreenshot,
} from '../../../../core/jest/jestSetupScreenshots'

describe('FieldBlock', () => {
describe.each(['ui', 'sbanken'])('FieldBlock for %s', (themeName) => {
setupPageScreenshot({
themeName,
url: '/uilib/extensions/forms/create-component/FieldBlock/demos/',
})

Expand All @@ -26,4 +27,11 @@ describe('FieldBlock', () => {
})
expect(screenshot).toMatchImageSnapshot()
})

it('have to match label description', async () => {
const screenshot = await makeScreenshot({
selector: '[data-visual-test="forms-field-block-label-description"]',
})
expect(screenshot).toMatchImageSnapshot()
})
})
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,22 @@ describe('FieldBlock', () => {
expect(labelElement.textContent).toBe('A Label')
})

it('should render a "labelDescription"', () => {
render(
<FieldBlock labelDescription="A Label Description">
content
</FieldBlock>
)

const labelElement = document.querySelector('label')

expect(labelElement).toBeInTheDocument()
expect(labelElement.className).toBe(
'dnb-form-label dnb-space__right--small dnb-space__top--zero dnb-space__bottom--x-small'
)
expect(labelElement.textContent).toBe('A Label Description')
})

it('click on label should set focus on input after value change', async () => {
const MockComponent = () => {
const fromInput = React.useCallback(({ value }) => value, [])
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file not shown.
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,10 @@ fieldset.dnb-forms-field-block {
align-items: center;
}

&__label-description {
margin-left: 0.3em;
}

&__status {
grid-area: status;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
.dnb-forms-field-block {
&__label-description {
color: var(--color-gray-dark);
font-size: var(--font-size-small);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
.dnb-forms-field-block {
&__label-description {
color: var(--color-black-55);
font-size: var(--font-size-small);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ function ArrayComponent(props: Props) {
layout = 'vertical',
placeholder,
label,
labelDescription,
path,
value: arrayValue,
info,
Expand Down Expand Up @@ -79,6 +80,7 @@ function ArrayComponent(props: Props) {
className={classnames('dnb-forms-field-number', className)}
layout={layout}
label={label}
labelDescription={labelDescription}
info={info}
warning={warning}
error={error}
Expand Down
2 changes: 2 additions & 0 deletions packages/dnb-eufemia/src/extensions/forms/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,8 @@ export interface FieldProps<
layout?: 'horizontal' | 'vertical'
/** Main label text */
label?: React.ReactNode
/** A more discreet text displayed beside the label */
labelDescription?: React.ReactNode
/** Text showing in place of the value if no value is given */
placeholder?: string
autoComplete?:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,10 +43,11 @@ export default function TextCounter(localProps: TextCounterProps) {

return context
.getTranslation(localProps)
.TextCounter[`character${toPascalCase(variant || 'down')}`].replace(
'%count',
String(count)
)
.TextCounter[
`character${toPascalCase(
/up|down/.test(String(variant)) ? variant : 'down'
)}`
].replace('%count', String(count))
.replace('%max', String(max))
}, [variant, max, length, context, localProps])

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,5 @@ $THEME_FALLBACK: 'ui';
*/

@import '../../../extensions/forms/Field/Number/style/themes/dnb-number-theme-ui.scss';
@import '../../../extensions/forms/FieldBlock/style/themes/dnb-field-block-theme-ui.scss';
@import '../../../extensions/payment-card/style/themes/dnb-payment-card-theme-ui.scss';
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,4 @@ $THEME_FALLBACK: 'ui';
*/

@import '../../../extensions/forms/Field/Number/style/themes/dnb-number-theme-ui.scss';
@import '../../../extensions/forms/FieldBlock/style/themes/dnb-field-block-theme-ui.scss';
Loading

0 comments on commit 00c278c

Please sign in to comment.