diff --git a/packages/dnb-design-system-portal/src/docs/uilib/extensions/forms/base-fields/Number/Examples.tsx b/packages/dnb-design-system-portal/src/docs/uilib/extensions/forms/base-fields/Number/Examples.tsx index 418a740acac..1d94374cb47 100644 --- a/packages/dnb-design-system-portal/src/docs/uilib/extensions/forms/base-fields/Number/Examples.tsx +++ b/packages/dnb-design-system-portal/src/docs/uilib/extensions/forms/base-fields/Number/Examples.tsx @@ -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 ( - + console.log('onFocus', value)} onBlur={(value) => console.log('onBlur', value)} @@ -104,7 +106,8 @@ export const HorizontalLayout = () => { export const Widths = () => { return ( - + +

Without step controls

{ width="stretch" onChange={(value) => console.log('onChange', value)} /> +

With step controls

+ console.log('onChange', value)} + /> + console.log('onChange', value)} + /> + console.log('onChange', value)} + /> + console.log('onChange', value)} + /> + console.log('onChange', value)} + />
) } @@ -244,3 +282,87 @@ export const ValidateMaximumCustomError = () => {
) } + +export const WithStepControls = () => ( + + + +) + +export const WithStepControlsError = () => ( + + + +) + +export const WithStepControlsDisabled = () => ( + + + +) + +export const WithSlider = () => ( + + {() => { + const Component = () => { + const [value, setValue] = React.useState(50000) + const settings = { + min: 0, + max: 100000, + step: 1000, + } + return ( + + + setValue(value)} + width="stretch" + bottom="small" + /> + + setValue(parseFloat(String(value))) + } + hideButtons + tooltip + /> + + + ) + } + return + }} + +) diff --git a/packages/dnb-design-system-portal/src/docs/uilib/extensions/forms/base-fields/Number/demos.mdx b/packages/dnb-design-system-portal/src/docs/uilib/extensions/forms/base-fields/Number/demos.mdx index 963824edfa8..bcb0687b8ae 100644 --- a/packages/dnb-design-system-portal/src/docs/uilib/extensions/forms/base-fields/Number/demos.mdx +++ b/packages/dnb-design-system-portal/src/docs/uilib/extensions/forms/base-fields/Number/demos.mdx @@ -26,10 +26,6 @@ import * as Examples from './Examples' -### With help - - - ### Horizontal layout @@ -38,6 +34,18 @@ import * as Examples from './Examples' +### With help + + + +### With step controls + + + +### With step controls in conjunction with Slider + + + ### Disabled @@ -69,3 +77,8 @@ import * as Examples from './Examples' ### Percentage + + + + + diff --git a/packages/dnb-design-system-portal/src/docs/uilib/extensions/forms/base-fields/Number/properties.mdx b/packages/dnb-design-system-portal/src/docs/uilib/extensions/forms/base-fields/Number/properties.mdx index 712dc48962a..9a034ff41a0 100644 --- a/packages/dnb-design-system-portal/src/docs/uilib/extensions/forms/base-fields/Number/properties.mdx +++ b/packages/dnb-design-system-portal/src/docs/uilib/extensions/forms/base-fields/Number/properties.mdx @@ -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. | diff --git a/packages/dnb-eufemia/src/components/autocomplete/__tests__/__snapshots__/Autocomplete.test.tsx.snap b/packages/dnb-eufemia/src/components/autocomplete/__tests__/__snapshots__/Autocomplete.test.tsx.snap index 50ef5e14e98..03ee914aaa4 100644 --- a/packages/dnb-eufemia/src/components/autocomplete/__tests__/__snapshots__/Autocomplete.test.tsx.snap +++ b/packages/dnb-eufemia/src/components/autocomplete/__tests__/__snapshots__/Autocomplete.test.tsx.snap @@ -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 */ @@ -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); @@ -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; @@ -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 */ @@ -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); @@ -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; diff --git a/packages/dnb-eufemia/src/components/breadcrumb/__tests__/__snapshots__/Breadcrumb.test.tsx.snap b/packages/dnb-eufemia/src/components/breadcrumb/__tests__/__snapshots__/Breadcrumb.test.tsx.snap index 2bfff9bdcc5..667a3ad624a 100644 --- a/packages/dnb-eufemia/src/components/breadcrumb/__tests__/__snapshots__/Breadcrumb.test.tsx.snap +++ b/packages/dnb-eufemia/src/components/breadcrumb/__tests__/__snapshots__/Breadcrumb.test.tsx.snap @@ -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 */ @@ -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); @@ -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; diff --git a/packages/dnb-eufemia/src/components/button/__tests__/__snapshots__/Button.test.tsx.snap b/packages/dnb-eufemia/src/components/button/__tests__/__snapshots__/Button.test.tsx.snap index 31bd9815bf9..f967354fa6c 100644 --- a/packages/dnb-eufemia/src/components/button/__tests__/__snapshots__/Button.test.tsx.snap +++ b/packages/dnb-eufemia/src/components/button/__tests__/__snapshots__/Button.test.tsx.snap @@ -343,6 +343,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 */ @@ -439,6 +440,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); @@ -493,6 +500,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; @@ -763,6 +776,7 @@ html[data-whatinput=keyboard] .dnb-button--tertiary:hover:focus .dnb-button__tex .dnb-button { --button-background--focus: var(--sb-color-blue-light-3); + --button-border-radius--control-button: 3rem; --button-primary-shadow: var(--sb-shadow-medium); --button-primary-shadow--hover: var(--sb-shadow-medium); --button-primary-color: var(--sb-color-white); @@ -849,6 +863,17 @@ html:not([data-whatintent=touch]) .dnb-button--secondary:hover:not([disabled]) { color: var(--button-secondary-color--active); background-color: var(--button-secondary-background--active); } +.dnb-button--secondary:not(.dnb-button--has-text).dnb-button--control-before, .dnb-button--secondary:not(.dnb-button--has-text).dnb-button--control-after { + box-shadow: none; + border: none; +} +html:not([data-whatintent=touch]) .dnb-button--secondary:not(.dnb-button--has-text).dnb-button--control-before:hover[disabled], html:not([data-whatintent=touch]) .dnb-button--secondary:not(.dnb-button--has-text).dnb-button--control-after:hover[disabled] { + cursor: not-allowed; +} +html:not([data-whatintent=touch]) .dnb-button--secondary:not(.dnb-button--has-text).dnb-button--control-before:hover:not([disabled]), html:not([data-whatintent=touch]) .dnb-button--secondary:not(.dnb-button--has-text).dnb-button--control-after:hover:not([disabled]) { + box-shadow: none; + border: none; +} html:not([data-whatintent=touch]) .dnb-button--primary:focus-visible[disabled], html:not([data-whatintent=touch]) .dnb-button--secondary:focus-visible[disabled] { cursor: not-allowed; } @@ -1349,10 +1374,21 @@ html[data-whatinput=keyboard] .dnb-button--secondary:not(.dnb-button--has-text): box-shadow: 0 0 0 var(--border-width) var(--border-color); border-color: transparent; } -.dnb-button--secondary:not(.dnb-button--has-text):not(.dnb-button--input-button).dnb-button--size-large { +.dnb-button--secondary:not(.dnb-button--has-text):not(.dnb-button--input-button):not(.dnb-button--control-before):not(.dnb-button--control-after).dnb-button--size-large { width: calc(var(--button-width--large) - 0.5rem); line-height: calc(var(--button-height--large) - 0.5rem); } +.dnb-button--secondary:not(.dnb-button--has-text).dnb-button--control-before, .dnb-button--secondary:not(.dnb-button--has-text).dnb-button--control-after { + box-shadow: none; + border: none; +} +html:not([data-whatintent=touch]) .dnb-button--secondary:not(.dnb-button--has-text).dnb-button--control-before:hover[disabled], html:not([data-whatintent=touch]) .dnb-button--secondary:not(.dnb-button--has-text).dnb-button--control-after:hover[disabled] { + cursor: not-allowed; +} +html:not([data-whatintent=touch]) .dnb-button--secondary:not(.dnb-button--has-text).dnb-button--control-before:hover:not([disabled]), html:not([data-whatintent=touch]) .dnb-button--secondary:not(.dnb-button--has-text).dnb-button--control-after:hover:not([disabled]) { + box-shadow: none; + border: none; +} .dnb-button--active { --border-color: var(--color-emerald-green); --border-width: 0.125rem; diff --git a/packages/dnb-eufemia/src/components/button/style/dnb-button.scss b/packages/dnb-eufemia/src/components/button/style/dnb-button.scss index 70e7b7de1b8..6b97e361397 100644 --- a/packages/dnb-eufemia/src/components/button/style/dnb-button.scss +++ b/packages/dnb-eufemia/src/components/button/style/dnb-button.scss @@ -26,6 +26,7 @@ --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; @@ -153,6 +154,12 @@ &--has-text#{&}--icon-position-right#{&}--size-medium { padding-right: 0.5rem; } + &--control-before#{&}--size-medium { + line-height: var(--button-height); + } + &--control-after#{&}--size-medium { + line-height: var(--button-height); + } // size large &--size-large { @@ -230,6 +237,15 @@ width: 100%; } + &--control-before { + border-radius: var(--button-border-radius--control-button) 0 0 + var(--button-border-radius--control-button); + } + &--control-after { + border-radius: 0 var(--button-border-radius--control-button) + var(--button-border-radius--control-button) 0; + } + &--reset { margin: 0; padding: 0; diff --git a/packages/dnb-eufemia/src/components/button/style/themes/dnb-button-theme-sbanken.scss b/packages/dnb-eufemia/src/components/button/style/themes/dnb-button-theme-sbanken.scss index 4c58fdae7e9..7d1522811ff 100644 --- a/packages/dnb-eufemia/src/components/button/style/themes/dnb-button-theme-sbanken.scss +++ b/packages/dnb-eufemia/src/components/button/style/themes/dnb-button-theme-sbanken.scss @@ -13,6 +13,7 @@ .dnb-button { // global --button-background--focus: var(--sb-color-blue-light-3); + --button-border-radius--control-button: 3rem; // primary --button-primary-shadow: var(--sb-shadow-medium); @@ -100,6 +101,15 @@ background-color: var(--button-secondary-background--active); } } + &--secondary:not(#{&}--has-text)#{&}--control-before, + &--secondary:not(#{&}--has-text)#{&}--control-after { + box-shadow: none; + border: none; + @include hover() { + box-shadow: none; + border: none; + } + } &--primary, &--secondary { diff --git a/packages/dnb-eufemia/src/components/button/style/themes/dnb-button-theme-ui.scss b/packages/dnb-eufemia/src/components/button/style/themes/dnb-button-theme-ui.scss index 2e475e2c859..dfc2f2f7953 100644 --- a/packages/dnb-eufemia/src/components/button/style/themes/dnb-button-theme-ui.scss +++ b/packages/dnb-eufemia/src/components/button/style/themes/dnb-button-theme-ui.scss @@ -77,13 +77,22 @@ var(--color-mint-green-50) ); } - &--secondary:not(#{&}--has-text):not( - #{&}--input-button - )#{&}--size-large { + &--secondary:not(#{&}--has-text):not(#{&}--input-button):not( + #{&}--control-before + ):not(#{&}--control-after)#{&}--size-large { // Make exception for icon button as it should be smaller than the original large button width: calc(var(--button-width--large) - 0.5rem); line-height: calc(var(--button-height--large) - 0.5rem); } + &--secondary:not(#{&}--has-text)#{&}--control-before, + &--secondary:not(#{&}--has-text)#{&}--control-after { + box-shadow: none; + border: none; + @include hover() { + box-shadow: none; + border: none; + } + } // simulate active state &--active { diff --git a/packages/dnb-eufemia/src/components/date-picker/__tests__/__snapshots__/DatePicker.test.tsx.snap b/packages/dnb-eufemia/src/components/date-picker/__tests__/__snapshots__/DatePicker.test.tsx.snap index 7cf5714d99a..5759b29526c 100644 --- a/packages/dnb-eufemia/src/components/date-picker/__tests__/__snapshots__/DatePicker.test.tsx.snap +++ b/packages/dnb-eufemia/src/components/date-picker/__tests__/__snapshots__/DatePicker.test.tsx.snap @@ -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 */ @@ -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); @@ -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; @@ -1612,6 +1625,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 */ @@ -1708,6 +1722,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); @@ -1762,6 +1782,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; @@ -2215,6 +2241,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 */ @@ -2311,6 +2338,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); @@ -2365,6 +2398,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; diff --git a/packages/dnb-eufemia/src/components/dialog/__tests__/__snapshots__/Dialog.test.tsx.snap b/packages/dnb-eufemia/src/components/dialog/__tests__/__snapshots__/Dialog.test.tsx.snap index f12f18f1b0c..6e38ccae19f 100644 --- a/packages/dnb-eufemia/src/components/dialog/__tests__/__snapshots__/Dialog.test.tsx.snap +++ b/packages/dnb-eufemia/src/components/dialog/__tests__/__snapshots__/Dialog.test.tsx.snap @@ -364,6 +364,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 */ @@ -460,6 +461,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); @@ -514,6 +521,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; diff --git a/packages/dnb-eufemia/src/components/drawer/__tests__/__snapshots__/Drawer.test.tsx.snap b/packages/dnb-eufemia/src/components/drawer/__tests__/__snapshots__/Drawer.test.tsx.snap index 426f99835cb..c28471b6754 100644 --- a/packages/dnb-eufemia/src/components/drawer/__tests__/__snapshots__/Drawer.test.tsx.snap +++ b/packages/dnb-eufemia/src/components/drawer/__tests__/__snapshots__/Drawer.test.tsx.snap @@ -365,6 +365,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 */ @@ -461,6 +462,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); @@ -515,6 +522,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; diff --git a/packages/dnb-eufemia/src/components/dropdown/__tests__/__snapshots__/Dropdown.test.tsx.snap b/packages/dnb-eufemia/src/components/dropdown/__tests__/__snapshots__/Dropdown.test.tsx.snap index f5bdd3d591a..44181b10bd4 100644 --- a/packages/dnb-eufemia/src/components/dropdown/__tests__/__snapshots__/Dropdown.test.tsx.snap +++ b/packages/dnb-eufemia/src/components/dropdown/__tests__/__snapshots__/Dropdown.test.tsx.snap @@ -436,6 +436,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 */ @@ -532,6 +533,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); @@ -586,6 +593,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; diff --git a/packages/dnb-eufemia/src/components/global-error/__tests__/__snapshots__/GlobalError.test.tsx.snap b/packages/dnb-eufemia/src/components/global-error/__tests__/__snapshots__/GlobalError.test.tsx.snap index 9f4105f3f3f..2b848f86112 100644 --- a/packages/dnb-eufemia/src/components/global-error/__tests__/__snapshots__/GlobalError.test.tsx.snap +++ b/packages/dnb-eufemia/src/components/global-error/__tests__/__snapshots__/GlobalError.test.tsx.snap @@ -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 */ @@ -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); @@ -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; diff --git a/packages/dnb-eufemia/src/components/global-status/__tests__/__snapshots__/GlobalStatus.test.tsx.snap b/packages/dnb-eufemia/src/components/global-status/__tests__/__snapshots__/GlobalStatus.test.tsx.snap index 33f17efa5d7..8e8d5cfed8d 100644 --- a/packages/dnb-eufemia/src/components/global-status/__tests__/__snapshots__/GlobalStatus.test.tsx.snap +++ b/packages/dnb-eufemia/src/components/global-status/__tests__/__snapshots__/GlobalStatus.test.tsx.snap @@ -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 */ @@ -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); @@ -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; diff --git a/packages/dnb-eufemia/src/components/help-button/__tests__/__snapshots__/HelpButton.test.tsx.snap b/packages/dnb-eufemia/src/components/help-button/__tests__/__snapshots__/HelpButton.test.tsx.snap index ea0eb2c2eb9..e1899f5a7b6 100644 --- a/packages/dnb-eufemia/src/components/help-button/__tests__/__snapshots__/HelpButton.test.tsx.snap +++ b/packages/dnb-eufemia/src/components/help-button/__tests__/__snapshots__/HelpButton.test.tsx.snap @@ -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 */ @@ -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); @@ -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; diff --git a/packages/dnb-eufemia/src/components/input-masked/__tests__/__snapshots__/InputMasked.test.tsx.snap b/packages/dnb-eufemia/src/components/input-masked/__tests__/__snapshots__/InputMasked.test.tsx.snap index 1f851f29736..b20501b5bc2 100644 --- a/packages/dnb-eufemia/src/components/input-masked/__tests__/__snapshots__/InputMasked.test.tsx.snap +++ b/packages/dnb-eufemia/src/components/input-masked/__tests__/__snapshots__/InputMasked.test.tsx.snap @@ -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 */ @@ -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); @@ -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; diff --git a/packages/dnb-eufemia/src/components/input/Input.js b/packages/dnb-eufemia/src/components/input/Input.js index 7a782b9a428..b689720bb27 100644 --- a/packages/dnb-eufemia/src/components/input/Input.js +++ b/packages/dnb-eufemia/src/components/input/Input.js @@ -505,10 +505,10 @@ export default class Input extends React.PureComponent { {label && ( diff --git a/packages/dnb-eufemia/src/components/input/__tests__/__snapshots__/Input.test.tsx.snap b/packages/dnb-eufemia/src/components/input/__tests__/__snapshots__/Input.test.tsx.snap index 9413e22bd4a..e399922c2a6 100644 --- a/packages/dnb-eufemia/src/components/input/__tests__/__snapshots__/Input.test.tsx.snap +++ b/packages/dnb-eufemia/src/components/input/__tests__/__snapshots__/Input.test.tsx.snap @@ -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 */ @@ -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); @@ -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; diff --git a/packages/dnb-eufemia/src/components/modal/__tests__/__snapshots__/Modal.test.tsx.snap b/packages/dnb-eufemia/src/components/modal/__tests__/__snapshots__/Modal.test.tsx.snap index df741e13056..8f77824dfef 100644 --- a/packages/dnb-eufemia/src/components/modal/__tests__/__snapshots__/Modal.test.tsx.snap +++ b/packages/dnb-eufemia/src/components/modal/__tests__/__snapshots__/Modal.test.tsx.snap @@ -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 */ @@ -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); @@ -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; diff --git a/packages/dnb-eufemia/src/components/pagination/__tests__/__snapshots__/Pagination.test.tsx.snap b/packages/dnb-eufemia/src/components/pagination/__tests__/__snapshots__/Pagination.test.tsx.snap index 1ccfa2e8088..289526cdd34 100644 --- a/packages/dnb-eufemia/src/components/pagination/__tests__/__snapshots__/Pagination.test.tsx.snap +++ b/packages/dnb-eufemia/src/components/pagination/__tests__/__snapshots__/Pagination.test.tsx.snap @@ -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 */ @@ -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); @@ -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; diff --git a/packages/dnb-eufemia/src/components/skip-content/__tests__/__snapshots__/SkipContent.test.tsx.snap b/packages/dnb-eufemia/src/components/skip-content/__tests__/__snapshots__/SkipContent.test.tsx.snap index bf37f0f9dac..8548097968c 100644 --- a/packages/dnb-eufemia/src/components/skip-content/__tests__/__snapshots__/SkipContent.test.tsx.snap +++ b/packages/dnb-eufemia/src/components/skip-content/__tests__/__snapshots__/SkipContent.test.tsx.snap @@ -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 */ @@ -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); @@ -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; diff --git a/packages/dnb-eufemia/src/components/slider/__tests__/__snapshots__/Slider.test.tsx.snap b/packages/dnb-eufemia/src/components/slider/__tests__/__snapshots__/Slider.test.tsx.snap index 48ea7adf388..b313218e018 100644 --- a/packages/dnb-eufemia/src/components/slider/__tests__/__snapshots__/Slider.test.tsx.snap +++ b/packages/dnb-eufemia/src/components/slider/__tests__/__snapshots__/Slider.test.tsx.snap @@ -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 */ @@ -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); @@ -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; diff --git a/packages/dnb-eufemia/src/components/step-indicator/__tests__/__snapshots__/StepIndicator.test.tsx.snap b/packages/dnb-eufemia/src/components/step-indicator/__tests__/__snapshots__/StepIndicator.test.tsx.snap index 01e91575244..193eb2dd80e 100644 --- a/packages/dnb-eufemia/src/components/step-indicator/__tests__/__snapshots__/StepIndicator.test.tsx.snap +++ b/packages/dnb-eufemia/src/components/step-indicator/__tests__/__snapshots__/StepIndicator.test.tsx.snap @@ -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 */ @@ -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); @@ -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; diff --git a/packages/dnb-eufemia/src/components/tag/__tests__/__snapshots__/Tag.test.tsx.snap b/packages/dnb-eufemia/src/components/tag/__tests__/__snapshots__/Tag.test.tsx.snap index 9f8b2ca94a9..b2764e2e027 100644 --- a/packages/dnb-eufemia/src/components/tag/__tests__/__snapshots__/Tag.test.tsx.snap +++ b/packages/dnb-eufemia/src/components/tag/__tests__/__snapshots__/Tag.test.tsx.snap @@ -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 */ @@ -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); @@ -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; diff --git a/packages/dnb-eufemia/src/components/toggle-button/__tests__/__snapshots__/ToggleButton.test.tsx.snap b/packages/dnb-eufemia/src/components/toggle-button/__tests__/__snapshots__/ToggleButton.test.tsx.snap index 40d093b7a01..666a4d9a122 100644 --- a/packages/dnb-eufemia/src/components/toggle-button/__tests__/__snapshots__/ToggleButton.test.tsx.snap +++ b/packages/dnb-eufemia/src/components/toggle-button/__tests__/__snapshots__/ToggleButton.test.tsx.snap @@ -391,6 +391,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 */ @@ -487,6 +488,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); @@ -541,6 +548,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; diff --git a/packages/dnb-eufemia/src/components/upload/__tests__/__snapshots__/Upload.test.tsx.snap b/packages/dnb-eufemia/src/components/upload/__tests__/__snapshots__/Upload.test.tsx.snap index c5e58e3858a..246af213ccb 100644 --- a/packages/dnb-eufemia/src/components/upload/__tests__/__snapshots__/Upload.test.tsx.snap +++ b/packages/dnb-eufemia/src/components/upload/__tests__/__snapshots__/Upload.test.tsx.snap @@ -436,6 +436,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 */ @@ -532,6 +533,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); @@ -586,6 +593,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; diff --git a/packages/dnb-eufemia/src/extensions/forms/Field/Expiry/__tests__/Expiry.screenshot.test.ts b/packages/dnb-eufemia/src/extensions/forms/Field/Expiry/__tests__/Expiry.screenshot.test.ts index f91508c8c78..5cde95a38c1 100644 --- a/packages/dnb-eufemia/src/extensions/forms/Field/Expiry/__tests__/Expiry.screenshot.test.ts +++ b/packages/dnb-eufemia/src/extensions/forms/Field/Expiry/__tests__/Expiry.screenshot.test.ts @@ -8,7 +8,7 @@ import { setupPageScreenshot, } from '../../../../../core/jest/jestSetupScreenshots' -describe.each(['ui', 'sbanken'])('Anchor for %s', (themeName) => { +describe.each(['ui', 'sbanken'])('Expiry field for %s', (themeName) => { setupPageScreenshot({ themeName, url: '/uilib/extensions/forms/feature-fields/Expiry', diff --git a/packages/dnb-eufemia/src/extensions/forms/Field/Expiry/__tests__/__image_snapshots__/anchor-for-sbanken-have-to-match-expiry-with-help-button.snap.png b/packages/dnb-eufemia/src/extensions/forms/Field/Expiry/__tests__/__image_snapshots__/expiry-field-for-sbanken-have-to-match-expiry-with-help-button.snap.png similarity index 100% rename from packages/dnb-eufemia/src/extensions/forms/Field/Expiry/__tests__/__image_snapshots__/anchor-for-sbanken-have-to-match-expiry-with-help-button.snap.png rename to packages/dnb-eufemia/src/extensions/forms/Field/Expiry/__tests__/__image_snapshots__/expiry-field-for-sbanken-have-to-match-expiry-with-help-button.snap.png diff --git a/packages/dnb-eufemia/src/extensions/forms/Field/Expiry/__tests__/__image_snapshots__/anchor-for-sbanken-have-to-match-the-disabled-state.snap.png b/packages/dnb-eufemia/src/extensions/forms/Field/Expiry/__tests__/__image_snapshots__/expiry-field-for-sbanken-have-to-match-the-disabled-state.snap.png similarity index 100% rename from packages/dnb-eufemia/src/extensions/forms/Field/Expiry/__tests__/__image_snapshots__/anchor-for-sbanken-have-to-match-the-disabled-state.snap.png rename to packages/dnb-eufemia/src/extensions/forms/Field/Expiry/__tests__/__image_snapshots__/expiry-field-for-sbanken-have-to-match-the-disabled-state.snap.png diff --git a/packages/dnb-eufemia/src/extensions/forms/Field/Expiry/__tests__/__image_snapshots__/anchor-for-sbanken-have-to-match-the-empty-state.snap.png b/packages/dnb-eufemia/src/extensions/forms/Field/Expiry/__tests__/__image_snapshots__/expiry-field-for-sbanken-have-to-match-the-empty-state.snap.png similarity index 100% rename from packages/dnb-eufemia/src/extensions/forms/Field/Expiry/__tests__/__image_snapshots__/anchor-for-sbanken-have-to-match-the-empty-state.snap.png rename to packages/dnb-eufemia/src/extensions/forms/Field/Expiry/__tests__/__image_snapshots__/expiry-field-for-sbanken-have-to-match-the-empty-state.snap.png diff --git a/packages/dnb-eufemia/src/extensions/forms/Field/Expiry/__tests__/__image_snapshots__/anchor-for-sbanken-have-to-match-the-error-state.snap.png b/packages/dnb-eufemia/src/extensions/forms/Field/Expiry/__tests__/__image_snapshots__/expiry-field-for-sbanken-have-to-match-the-error-state.snap.png similarity index 100% rename from packages/dnb-eufemia/src/extensions/forms/Field/Expiry/__tests__/__image_snapshots__/anchor-for-sbanken-have-to-match-the-error-state.snap.png rename to packages/dnb-eufemia/src/extensions/forms/Field/Expiry/__tests__/__image_snapshots__/expiry-field-for-sbanken-have-to-match-the-error-state.snap.png diff --git a/packages/dnb-eufemia/src/extensions/forms/Field/Expiry/__tests__/__image_snapshots__/anchor-for-sbanken-have-to-match-the-input-filled-in-value.snap.png b/packages/dnb-eufemia/src/extensions/forms/Field/Expiry/__tests__/__image_snapshots__/expiry-field-for-sbanken-have-to-match-the-input-filled-in-value.snap.png similarity index 100% rename from packages/dnb-eufemia/src/extensions/forms/Field/Expiry/__tests__/__image_snapshots__/anchor-for-sbanken-have-to-match-the-input-filled-in-value.snap.png rename to packages/dnb-eufemia/src/extensions/forms/Field/Expiry/__tests__/__image_snapshots__/expiry-field-for-sbanken-have-to-match-the-input-filled-in-value.snap.png diff --git a/packages/dnb-eufemia/src/extensions/forms/Field/Expiry/__tests__/__image_snapshots__/anchor-for-ui-have-to-match-expiry-with-help-button.snap.png b/packages/dnb-eufemia/src/extensions/forms/Field/Expiry/__tests__/__image_snapshots__/expiry-field-for-ui-have-to-match-expiry-with-help-button.snap.png similarity index 100% rename from packages/dnb-eufemia/src/extensions/forms/Field/Expiry/__tests__/__image_snapshots__/anchor-for-ui-have-to-match-expiry-with-help-button.snap.png rename to packages/dnb-eufemia/src/extensions/forms/Field/Expiry/__tests__/__image_snapshots__/expiry-field-for-ui-have-to-match-expiry-with-help-button.snap.png diff --git a/packages/dnb-eufemia/src/extensions/forms/Field/Expiry/__tests__/__image_snapshots__/anchor-for-ui-have-to-match-the-disabled-state.snap.png b/packages/dnb-eufemia/src/extensions/forms/Field/Expiry/__tests__/__image_snapshots__/expiry-field-for-ui-have-to-match-the-disabled-state.snap.png similarity index 100% rename from packages/dnb-eufemia/src/extensions/forms/Field/Expiry/__tests__/__image_snapshots__/anchor-for-ui-have-to-match-the-disabled-state.snap.png rename to packages/dnb-eufemia/src/extensions/forms/Field/Expiry/__tests__/__image_snapshots__/expiry-field-for-ui-have-to-match-the-disabled-state.snap.png diff --git a/packages/dnb-eufemia/src/extensions/forms/Field/Expiry/__tests__/__image_snapshots__/anchor-for-ui-have-to-match-the-empty-state.snap.png b/packages/dnb-eufemia/src/extensions/forms/Field/Expiry/__tests__/__image_snapshots__/expiry-field-for-ui-have-to-match-the-empty-state.snap.png similarity index 100% rename from packages/dnb-eufemia/src/extensions/forms/Field/Expiry/__tests__/__image_snapshots__/anchor-for-ui-have-to-match-the-empty-state.snap.png rename to packages/dnb-eufemia/src/extensions/forms/Field/Expiry/__tests__/__image_snapshots__/expiry-field-for-ui-have-to-match-the-empty-state.snap.png diff --git a/packages/dnb-eufemia/src/extensions/forms/Field/Expiry/__tests__/__image_snapshots__/anchor-for-ui-have-to-match-the-error-state.snap.png b/packages/dnb-eufemia/src/extensions/forms/Field/Expiry/__tests__/__image_snapshots__/expiry-field-for-ui-have-to-match-the-error-state.snap.png similarity index 100% rename from packages/dnb-eufemia/src/extensions/forms/Field/Expiry/__tests__/__image_snapshots__/anchor-for-ui-have-to-match-the-error-state.snap.png rename to packages/dnb-eufemia/src/extensions/forms/Field/Expiry/__tests__/__image_snapshots__/expiry-field-for-ui-have-to-match-the-error-state.snap.png diff --git a/packages/dnb-eufemia/src/extensions/forms/Field/Expiry/__tests__/__image_snapshots__/anchor-for-ui-have-to-match-the-input-filled-in-value.snap.png b/packages/dnb-eufemia/src/extensions/forms/Field/Expiry/__tests__/__image_snapshots__/expiry-field-for-ui-have-to-match-the-input-filled-in-value.snap.png similarity index 100% rename from packages/dnb-eufemia/src/extensions/forms/Field/Expiry/__tests__/__image_snapshots__/anchor-for-ui-have-to-match-the-input-filled-in-value.snap.png rename to packages/dnb-eufemia/src/extensions/forms/Field/Expiry/__tests__/__image_snapshots__/expiry-field-for-ui-have-to-match-the-input-filled-in-value.snap.png diff --git a/packages/dnb-eufemia/src/extensions/forms/Field/Number/Number.tsx b/packages/dnb-eufemia/src/extensions/forms/Field/Number/Number.tsx index 9d8d549ea67..b291e68f76d 100644 --- a/packages/dnb-eufemia/src/extensions/forms/Field/Number/Number.tsx +++ b/packages/dnb-eufemia/src/extensions/forms/Field/Number/Number.tsx @@ -1,14 +1,16 @@ import React, { useContext, useMemo, useCallback } from 'react' import { JSONSchema7 } from 'json-schema' -import { InputMasked, HelpButton } from '../../../../components' +import { InputMasked, HelpButton, Button } from '../../../../components' import { InputMaskedProps } from '../../../../components/InputMasked' -import { InputAlign } from '../../../../components/Input' +import type { InputAlign, InputSize } from '../../../../components/Input' import SharedContext from '../../../../shared/Context' import classnames from 'classnames' import FieldBlock from '../../FieldBlock' import { useDataValue } from '../../hooks' import { FieldProps, FieldHelpProps } from '../../types' import { pickSpacingProps } from '../../../../components/flex/utils' +import { ButtonProps, ButtonSize } from '../../../../components/Button' +import { clamp } from '../../../../components/slider/SliderHelpers' interface ErrorMessages { required?: string @@ -26,6 +28,7 @@ export type Props = FieldHelpProps & currency?: InputMaskedProps['as_currency'] percent?: InputMaskedProps['as_percent'] mask?: InputMaskedProps['mask'] + step?: number // Formatting thousandSeparator?: string | true decimalSymbol?: string @@ -39,8 +42,10 @@ export type Props = FieldHelpProps & exclusiveMaximum?: number // aka less than multipleOf?: number // Styling + size?: InputSize width?: false | 'small' | 'medium' | 'large' | 'stretch' align?: InputAlign + showStepControls?: boolean } function NumberComponent(props: Props) { @@ -51,11 +56,13 @@ function NumberComponent(props: Props) { currency, percent, mask, + step = 1, thousandSeparator, decimalSymbol, decimalLimit = 12, prefix, suffix, + showStepControls, } = props const errorMessages = useMemo( @@ -99,11 +106,11 @@ function NumberComponent(props: Props) { const fromInput = useCallback( ({ value, numberValue }: { value: string; numberValue: number }) => { if (value === '') { - return emptyValue + return props.emptyValue } return numberValue }, - [] + [props.emptyValue] ) const maskProps: Partial = useMemo(() => { @@ -148,8 +155,11 @@ function NumberComponent(props: Props) { schema, toInput, fromInput, + size: + props.size !== 'small' && props.size !== 'large' + ? 'medium' + : props.size, width: props.width ?? 'medium', - align: props.align ?? 'left', } const { @@ -164,12 +174,14 @@ function NumberComponent(props: Props) { labelDescription, labelSecondary, value, + minimum, + maximum, disabled, info, warning, error, help, - emptyValue, + size, width, align, handleFocus, @@ -177,49 +189,142 @@ function NumberComponent(props: Props) { handleChange, } = useDataValue(preparedProps) + const onKeyDownHandler = useCallback( + ({ key, event }) => { + let numberValue = null + + switch (key) { + case 'ArrowUp': + numberValue = clamp((value as number) + step, minimum, maximum) + break + case 'ArrowDown': + numberValue = clamp((value as number) - step, minimum, maximum) + break + } + + if (numberValue !== null) { + event.persist() + event.preventDefault() + handleChange({ numberValue }) + } + }, + [handleChange, maximum, minimum, step, value] + ) + + const fieldBlockProps = { + className: classnames('dnb-forms-field-number', className), + contentClassName: classnames( + 'dnb-forms-field-number__contents', + showStepControls && 'dnb-forms-field-number__contents--has-controls', + disabled && 'dnb-forms-field-number__contents--is-disabled', + error && 'dnb-forms-field-number__contents--has-error' + ), + forId: id, + layout, + label, + labelDescription, + labelSecondary, + info, + warning, + error, + disabled, + width: width === 'stretch' ? width : undefined, + contentsWidth: width !== false ? width : undefined, + ...pickSpacingProps(props), + } + + const increaseProps: ButtonProps = showStepControls && { + 'aria-hidden': true, + className: 'dnb-button--control-after', + variant: 'secondary', + icon: 'add', + size: convertInputSizeToButtonSize(size), + tabIndex: -1, + disabled: disabled || value >= maximum, + onClick: () => { + handleChange({ + numberValue: clamp((value as number) + step, minimum, maximum), + }) + }, + title: sharedContext?.translation.Slider.addTitle?.replace( + '%s', + String(value + step) + ), + } + + const decreaseProps: ButtonProps = showStepControls && { + ...increaseProps, + className: 'dnb-button--control-before', + icon: 'subtract', + disabled: disabled || value <= minimum, + onClick: () => { + handleChange({ + numberValue: clamp((value as number) - step, minimum, maximum), + }) + }, + title: sharedContext?.translation.Slider.subtractTitle?.replace( + '%s', + String(value - step) + ), + } + + const ariaParams = showStepControls && { + role: 'spinbutton', + 'aria-valuemin': String(minimum), + 'aria-valuemax': String(maximum), + 'aria-valuenow': String(value), // without it, VO will read an invlaid value + 'aria-valuetext': String(value), // without it, VO will read % + } + + const inputProps = { + id, + name, + autoComplete, + className: classnames( + 'dnb-forms-field-number__input', + `dnb-input--${size}`, + inputClassName + ), + step, + placeholder, + value, + align, + ...maskProps, + onKeyDown: onKeyDownHandler, + onFocus: handleFocus, + onBlur: handleBlur, + onChange: handleChange, + disabled, + status: error ? 'error' : undefined, + stretch: width !== undefined, + suffix: + help && !showStepControls ? ( + {help.contents} + ) : undefined, + ...ariaParams, + } + return ( - - {help.contents} - ) : undefined - } - /> + + {showStepControls &&