Skip to content

Commit

Permalink
feat(Field.Number): add step control functionality (#3140)
Browse files Browse the repository at this point in the history
Adds a new prop `showStepControls` to the Number component. When `true`,
this prop enables control buttons that adhere to a `step` property that
is also added, as well as taking min/max values into account.

This variant of the component is Sbanken-ready, and a number of tests
and screenshot tests has been implemented in relation to it.
  • Loading branch information
Sundfjord authored Jan 5, 2024
1 parent ef65676 commit a9e1697
Show file tree
Hide file tree
Showing 65 changed files with 1,193 additions and 81 deletions.
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
import ComponentBox from '../../../../../../shared/tags/ComponentBox'
import { Slider, Grid } from '@dnb/eufemia/src'
import { Field, FormError } from '@dnb/eufemia/src/extensions/forms'
import React from 'react'

export const Empty = () => {
return (
<ComponentBox>
<ComponentBox data-visual-test="number-input">
<Field.Number
onFocus={(value) => console.log('onFocus', value)}
onBlur={(value) => console.log('onBlur', value)}
Expand Down Expand Up @@ -104,7 +106,8 @@ export const HorizontalLayout = () => {

export const Widths = () => {
return (
<ComponentBox>
<ComponentBox hideCode>
<h4 className="dnb-lead">Without step controls</h4>
<Field.Number
label="Default width (property omitted)"
value={123}
Expand Down Expand Up @@ -134,6 +137,41 @@ export const Widths = () => {
width="stretch"
onChange={(value) => console.log('onChange', value)}
/>
<h4 className="dnb-lead">With step controls</h4>
<Field.Number
showStepControls
label="Default width (property omitted)"
value={123}
onChange={(value) => console.log('onChange', value)}
/>
<Field.Number
showStepControls
label="Small"
value={123}
width="small"
onChange={(value) => console.log('onChange', value)}
/>
<Field.Number
showStepControls
label="Medium"
value={123}
width="medium"
onChange={(value) => console.log('onChange', value)}
/>
<Field.Number
showStepControls
label="Large"
value={123}
width="large"
onChange={(value) => console.log('onChange', value)}
/>
<Field.Number
showStepControls
label="Stretch"
value={123}
width="stretch"
onChange={(value) => console.log('onChange', value)}
/>
</ComponentBox>
)
}
Expand Down Expand Up @@ -244,3 +282,87 @@ export const ValidateMaximumCustomError = () => {
</ComponentBox>
)
}

export const WithStepControls = () => (
<ComponentBox data-visual-test="number-input-step-controls">
<Field.Number
showStepControls
minimum={0}
maximum={100}
step={10}
value={50}
/>
</ComponentBox>
)

export const WithStepControlsError = () => (
<ComponentBox
scope={{ FormError }}
data-visual-test="number-input-step-controls-error"
>
<Field.Number
showStepControls
maximum={100}
value={150}
error={new FormError('You done messed up, A-a-ron!')}
/>
</ComponentBox>
)

export const WithStepControlsDisabled = () => (
<ComponentBox
scope={{ FormError }}
data-visual-test="number-input-step-controls-disabled"
>
<Field.Number showStepControls disabled />
</ComponentBox>
)

export const WithSlider = () => (
<ComponentBox hideCode>
{() => {
const Component = () => {
const [value, setValue] = React.useState(50000)
const settings = {
min: 0,
max: 100000,
step: 1000,
}
return (
<Grid.Container>
<Grid.Item
span={{
small: [1, 12],
medium: [1, 4],
large: [1, 3],
}}
>
<Field.Number
showStepControls
minimum={settings.min}
maximum={settings.max}
step={settings.step}
value={value}
onChange={(value) => setValue(value)}
width="stretch"
bottom="small"
/>
<Slider
min={settings.min}
max={settings.max}
step={settings.step}
value={value}
onChange={({ value }) =>
setValue(parseFloat(String(value)))
}
hideButtons
tooltip
/>
</Grid.Item>
</Grid.Container>
)
}
return <Component />
}}
</ComponentBox>
)
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,6 @@ import * as Examples from './Examples'

<Examples.Alignment />

### With help

<Examples.WithHelp />

### Horizontal layout

<Examples.HorizontalLayout />
Expand All @@ -38,6 +34,18 @@ import * as Examples from './Examples'

<Examples.Widths />

### With help

<Examples.WithHelp />

### With step controls

<Examples.WithStepControls />

### With step controls in conjunction with Slider

<Examples.WithSlider />

### Disabled

<Examples.Disabled />
Expand Down Expand Up @@ -69,3 +77,8 @@ import * as Examples from './Examples'
### Percentage

<Examples.Percentage />

<VisibleWhenVisualTest>
<Examples.WithStepControlsError />
<Examples.WithStepControlsDisabled />
</VisibleWhenVisualTest>
Original file line number Diff line number Diff line change
Expand Up @@ -8,24 +8,27 @@ import DataValueReadwriteProperties from '../../data-value-readwrite-properties.

### Component-specific props

| Property | Type | Description |
| --------------------------------------- | ------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `thousandSeparator` | `string` | _(optional)_ Character to use for separating every three digits. |
| `decimalSymbol` | `string` | _(optional)_ What character to use for separating digits and decimals. Defaults to ','. |
| `decimals` | `number` | _(optional)_ Max number of decimals. Values with more decimals will be rounded. |
| `fixedDecimals` | `number` | _(optional)_ Fixed number of decimals. Will round numbers with more decimals, and add trailing zeros when less. |
| `percent` | `boolean` | _(optional)_ Format a number as percentage. |
| `prefix` | `string` | _(optional)_ Text added before the value input. |
| `suffix` | `string` | _(optional)_ Text added after the value input. |
| `minimum` | `number` | _(optional)_ Validation for inclusive minimum number value (greater than or equal). |
| `maximum` | `number` | _(optional)_ Validation for inclusive maximum number value (less than or equal). |
| `exclusiveMinimum` | `number` | _(optional)_ Validation for exclusive minimum number value (greater than). |
| `exclusiveMaximum` | `number` | _(optional)_ Validation for exclusive maximum number value (less than). |
| `multipleOf` | `number` | _(optional)_ Validation that requires the number to be a multiple of given value. |
| `width` | `string` or `false` | _(optional)_ `false` for no width (use browser default), `small`, `medium` or `large` for predefined standard widths, `stretch` for fill available width. |
| `align` | `string` | _(optional)_ Lateral alignment of contents of input field, one of `left` (default), `center`, or `right`. |
| `help` | `object` | _(optional)_ Provide a help button. Object consisting of `title` and `contents`. |
| `autoComplete` | `on` or `string` | _(optional)_ For HTML `autocomplete` [attributes](https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes/autocomplete). |
| [Space](/uilib/layout/space/properties) | Various | _(optional)_ Spacing properties like `top` or `bottom` are supported. |
| Property | Type | Description |
| --------------------------------------- | -------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `thousandSeparator` | `string` | _(optional)_ Character to use for separating every three digits. |
| `decimalSymbol` | `string` | _(optional)_ What character to use for separating digits and decimals. Defaults to ','. |
| `decimals` | `number` | _(optional)_ Max number of decimals. Values with more decimals will be rounded. |
| `fixedDecimals` | `number` | _(optional)_ Fixed number of decimals. Will round numbers with more decimals, and add trailing zeros when less. |
| `percent` | `boolean` | _(optional)_ Format a number as percentage. |
| `prefix` | `string` | _(optional)_ Text added before the value input. |
| `suffix` | `string` | _(optional)_ Text added after the value input. |
| `minimum` | `number` | _(optional)_ Validation for inclusive minimum number value (greater than or equal). |
| `maximum` | `number` | _(optional)_ Validation for inclusive maximum number value (less than or equal). |
| `exclusiveMinimum` | `number` | _(optional)_ Validation for exclusive minimum number value (greater than). |
| `exclusiveMaximum` | `number` | _(optional)_ Validation for exclusive maximum number value (less than). |
| `multipleOf` | `number` | _(optional)_ Validation that requires the number to be a multiple of given value. |
| `width` | `string` or `false` | _(optional)_ `false` for no width (use browser default), `small`, `medium` or `large` for predefined standard widths, `stretch` for fill available width. |
| `size` | `string` or `number` | _(optional)_ Size of the input field, see Input's properties for available options. Accepts, but will not forward `number` values as input's element attribute. |
| `align` | `string` | _(optional)_ Lateral alignment of contents of input field, one of `left` (default), `center`, or `right`. |
| `help` | `object` | _(optional)_ Provide a help button. Object consisting of `title` and `contents`. |
| `autoComplete` | `on` or `string` | _(optional)_ For HTML `autocomplete` [attributes](https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes/autocomplete). |
| `step` | `number` | _(optional)_ Determines step granularity when in/decreasing value input through step controls buttons or arrow keys. |
| `showStepControls` | `boolean` | _(optional)_ Show buttons that in/decreases value input by the step value. |
| [Space](/uilib/layout/space/properties) | Various | _(optional)_ Spacing properties like `top` or `bottom` are supported. |

<DataValueReadwriteProperties type="number" />
Original file line number Diff line number Diff line change
Expand Up @@ -357,6 +357,7 @@ button .dnb-form-status__text {
--button-border-radius--small: calc(var(--button-height--small) / 2);
--button-border-radius--medium: calc(var(--button-height--medium) / 2);
--button-border-radius--large: calc(var(--button-height--large) / 2);
--button-border-radius--control-button: 0.25rem;
position: relative;
user-select: none;
/* stylelint-disable-next-line */
Expand Down Expand Up @@ -453,6 +454,12 @@ button .dnb-form-status__text {
.dnb-button--has-text.dnb-button--icon-position-right.dnb-button--size-medium {
padding-right: 0.5rem;
}
.dnb-button--control-before.dnb-button--size-medium {
line-height: var(--button-height);
}
.dnb-button--control-after.dnb-button--size-medium {
line-height: var(--button-height);
}
.dnb-button--size-large {
width: var(--button-width--large);
border-radius: var(--button-border-radius--large);
Expand Down Expand Up @@ -507,6 +514,12 @@ button .dnb-form-status__text {
.dnb-button--stretch {
width: 100%;
}
.dnb-button--control-before {
border-radius: var(--button-border-radius--control-button) 0 0 var(--button-border-radius--control-button);
}
.dnb-button--control-after {
border-radius: 0 var(--button-border-radius--control-button) var(--button-border-radius--control-button) 0;
}
.dnb-button--reset {
margin: 0;
padding: 0;
Expand Down Expand Up @@ -1705,6 +1718,7 @@ button .dnb-form-status__text {
--button-border-radius--small: calc(var(--button-height--small) / 2);
--button-border-radius--medium: calc(var(--button-height--medium) / 2);
--button-border-radius--large: calc(var(--button-height--large) / 2);
--button-border-radius--control-button: 0.25rem;
position: relative;
user-select: none;
/* stylelint-disable-next-line */
Expand Down Expand Up @@ -1801,6 +1815,12 @@ button .dnb-form-status__text {
.dnb-button--has-text.dnb-button--icon-position-right.dnb-button--size-medium {
padding-right: 0.5rem;
}
.dnb-button--control-before.dnb-button--size-medium {
line-height: var(--button-height);
}
.dnb-button--control-after.dnb-button--size-medium {
line-height: var(--button-height);
}
.dnb-button--size-large {
width: var(--button-width--large);
border-radius: var(--button-border-radius--large);
Expand Down Expand Up @@ -1855,6 +1875,12 @@ button .dnb-form-status__text {
.dnb-button--stretch {
width: 100%;
}
.dnb-button--control-before {
border-radius: var(--button-border-radius--control-button) 0 0 var(--button-border-radius--control-button);
}
.dnb-button--control-after {
border-radius: 0 var(--button-border-radius--control-button) var(--button-border-radius--control-button) 0;
}
.dnb-button--reset {
margin: 0;
padding: 0;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -350,6 +350,7 @@ button .dnb-form-status__text {
--button-border-radius--small: calc(var(--button-height--small) / 2);
--button-border-radius--medium: calc(var(--button-height--medium) / 2);
--button-border-radius--large: calc(var(--button-height--large) / 2);
--button-border-radius--control-button: 0.25rem;
position: relative;
user-select: none;
/* stylelint-disable-next-line */
Expand Down Expand Up @@ -446,6 +447,12 @@ button .dnb-form-status__text {
.dnb-button--has-text.dnb-button--icon-position-right.dnb-button--size-medium {
padding-right: 0.5rem;
}
.dnb-button--control-before.dnb-button--size-medium {
line-height: var(--button-height);
}
.dnb-button--control-after.dnb-button--size-medium {
line-height: var(--button-height);
}
.dnb-button--size-large {
width: var(--button-width--large);
border-radius: var(--button-border-radius--large);
Expand Down Expand Up @@ -500,6 +507,12 @@ button .dnb-form-status__text {
.dnb-button--stretch {
width: 100%;
}
.dnb-button--control-before {
border-radius: var(--button-border-radius--control-button) 0 0 var(--button-border-radius--control-button);
}
.dnb-button--control-after {
border-radius: 0 var(--button-border-radius--control-button) var(--button-border-radius--control-button) 0;
}
.dnb-button--reset {
margin: 0;
padding: 0;
Expand Down
Loading

0 comments on commit a9e1697

Please sign in to comment.