diff --git a/packages/dnb-design-system-portal/src/docs/uilib/components/form-status/Examples.js b/packages/dnb-design-system-portal/src/docs/uilib/components/form-status/Examples.js
index 560a0d0b475..66c03302ed7 100644
--- a/packages/dnb-design-system-portal/src/docs/uilib/components/form-status/Examples.js
+++ b/packages/dnb-design-system-portal/src/docs/uilib/components/form-status/Examples.js
@@ -55,7 +55,7 @@ export const FormStatusWithWarn = () => (
)
-export const FormSetDefaultInput = () => (
+export const FormStatusInput = () => (
{() => /* jsx */ `
(
)
+export const FormStatusAnimation = () => (
+
+ {() => /* jsx */ `
+const ToggleAnimation = () => {
+ const [status, setStatus] = React.useState(null)
+ const toggleStatus = () => {
+ setStatus((s) => (!s ? 'You have to fill in this field' : null))
+ }
+ return (
+
+
+
+ Toggle
+
+
+ )
+}
+render()
+`}
+
+)
+
export const FormStatusCustom = () => (
{() => /* jsx */ `
diff --git a/packages/dnb-design-system-portal/src/docs/uilib/components/form-status/demos.md b/packages/dnb-design-system-portal/src/docs/uilib/components/form-status/demos.md
index 3ae91aa1c63..999b6ea7fea 100644
--- a/packages/dnb-design-system-portal/src/docs/uilib/components/form-status/demos.md
+++ b/packages/dnb-design-system-portal/src/docs/uilib/components/form-status/demos.md
@@ -9,7 +9,8 @@ FormStatusDefault,
FormStatusWithInfo,
FormStatusWithStretch,
FormStatusWithWarn,
-FormSetDefaultInput,
+FormStatusInput,
+FormStatusAnimation,
FormStatusCustom,
FormStatusLarge,
FormStatusWithIcons,
@@ -35,15 +36,19 @@ NB: The inner text gets a max width of 47rem to ensure we not exceed 70 characte
-### A form status, used by the Input Component
+### A FormStatus, used by the Input Component
-
+
-### A form status, with a custom styled content
+### FormStatus Animation details
+
+
+
+### A FormStatus, with a custom styled content
-### A form status with plain text/HTML
+### A FormStatus with plain text/HTML
diff --git a/packages/dnb-design-system-portal/src/docs/uilib/components/form-status/properties.md b/packages/dnb-design-system-portal/src/docs/uilib/components/form-status/properties.md
index 5c121ed5a7a..48932537999 100644
--- a/packages/dnb-design-system-portal/src/docs/uilib/components/form-status/properties.md
+++ b/packages/dnb-design-system-portal/src/docs/uilib/components/form-status/properties.md
@@ -17,6 +17,8 @@ redirect_from:
| `icon_size` | _(optional)_ the icon size of the icon shows. Defaults to `medium`. |
| `variant` | _(optional)_ as of now, there is the `flat` and the `outlined` variant. Defaults to `flat`. |
| `stretch` | _(optional)_ if set to `true`, then the FormStatus will be 100% in available `width`. **NB:** Only use this on independent status messages. |
+| `show` | _(optional)_ provide `false` if you want to animate the visibility. Defaults to `true`. |
+| `no_animation` | _(optional)_ use `true` to omit the animation on content visibility. Defaults to `false`. |
| `global_status_id` | _(optional)_ the `status_id` used for the target [GlobalStatus](/uilib/components/global-status). |
| `skeleton` | _(optional)_ if set to `true`, an overlaying skeleton with animation will be shown. |
| [Space](/uilib/components/space/properties) | _(optional)_ spacing properties like `top` or `bottom` are supported. |
diff --git a/packages/dnb-eufemia-sandbox/stories/components/FormStatus.js b/packages/dnb-eufemia-sandbox/stories/components/FormStatus.js
index 1345ffb2b8d..bc3f151c655 100644
--- a/packages/dnb-eufemia-sandbox/stories/components/FormStatus.js
+++ b/packages/dnb-eufemia-sandbox/stories/components/FormStatus.js
@@ -16,7 +16,9 @@ import {
Modal,
Switch,
Button,
+ ToggleButton,
Space,
+ HelpButton,
} from '@dnb/eufemia/src/components'
import { Link } from '@dnb/eufemia/src/elements'
@@ -48,7 +50,6 @@ const SmallWidth = styled(Input)`
// )
export const FormStatuseSandbox = () => {
- const [showError, setShowError] = useState(false)
return (
@@ -137,6 +138,19 @@ export const FormStatuseSandbox = () => {
+
+ )
+}
+
+export const ToggleAnimation = () => {
+ const [status, setStatus] = React.useState(null)
+ const toggleStatus = () => {
+ setStatus((s) => (!s ? 'You have to fill in this field' : null))
+ }
+ const [showError, setShowError] = useState(false)
+
+ return (
+
{
Modal Content}
/>
- Modal Content
-
+ {/*
+ Modal Content
+ */}
+
+
+
+ test}
+ right
+ // size="small"
+ />
+
+ Toggle
+
+
+
)
}
diff --git a/packages/dnb-eufemia-sandbox/stories/components/GlobalStatus.js b/packages/dnb-eufemia-sandbox/stories/components/GlobalStatus.js
index e2aa0a3eec9..18912b39bac 100644
--- a/packages/dnb-eufemia-sandbox/stories/components/GlobalStatus.js
+++ b/packages/dnb-eufemia-sandbox/stories/components/GlobalStatus.js
@@ -91,8 +91,7 @@ export const GlobalStatuseSandbox = () => (
GlobalStatus.Update({
id: 'demo-1',
// id: 'custom-status',
- text:
- 'This is aDui consectetur viverra aenean vestibulum ac tristique sem ligula condimentum',
+ text: 'This is aDui consectetur viverra aenean vestibulum ac tristique sem ligula condimentum',
scrollto_element,
})
}}
@@ -137,7 +136,7 @@ const InputWithError = () => {
setErrorMessage1(value.length >= 3)
}}
right="small"
- // status_animation="fade-in"
+ // status_no_animation
/>
{
setErrorMessage2(value.length >= 3)
}}
right="small"
- // status_animation="fade-in"
+ // status_no_animation
/>
{
setErrorMessage3(checked)
}}
bottom="small"
- // status_animation="fade-in"
+ // status_no_animation
/>
{
setErrorMessage4(checked)
}}
- // status_animation="fade-in"
+ // status_no_animation
/>
@@ -461,13 +460,8 @@ const UpdateDemo = () => {
}
const UpdateDemoStatus = () => {
- const {
- errorA,
- errorB,
- setErrorA,
- setErrorB,
- setVisibility,
- } = React.useContext(Context)
+ const { errorA, errorB, setErrorA, setErrorB, setVisibility } =
+ React.useContext(Context)
return (
<>
diff --git a/packages/dnb-eufemia/src/components/autocomplete/Autocomplete.js b/packages/dnb-eufemia/src/components/autocomplete/Autocomplete.js
index a8b0ab96562..7261af22df1 100644
--- a/packages/dnb-eufemia/src/components/autocomplete/Autocomplete.js
+++ b/packages/dnb-eufemia/src/components/autocomplete/Autocomplete.js
@@ -99,7 +99,10 @@ export default class Autocomplete extends React.PureComponent {
PropTypes.node,
]),
status_state: PropTypes.string,
- status_animation: PropTypes.string,
+ status_no_animation: PropTypes.oneOfType([
+ PropTypes.string,
+ PropTypes.bool,
+ ]),
global_status_id: PropTypes.string,
suffix: PropTypes.oneOfType([
PropTypes.string,
@@ -238,7 +241,7 @@ export default class Autocomplete extends React.PureComponent {
keep_value_and_selection: null,
status: null,
status_state: 'error',
- status_animation: null,
+ status_no_animation: null,
global_status_id: null,
suffix: null,
disable_filter: false,
@@ -1444,7 +1447,7 @@ class AutocompleteInstance extends React.PureComponent {
fixed_position,
status,
status_state,
- status_animation,
+ status_no_animation,
global_status_id,
suffix,
scrollable,
@@ -1655,18 +1658,17 @@ class AutocompleteInstance extends React.PureComponent {
- {showStatus && (
-
- )}
+
diff --git a/packages/dnb-eufemia/src/components/autocomplete/__tests__/__snapshots__/Autocomplete.test.js.snap b/packages/dnb-eufemia/src/components/autocomplete/__tests__/__snapshots__/Autocomplete.test.js.snap
index 5feeab22759..6c00ca2359c 100644
--- a/packages/dnb-eufemia/src/components/autocomplete/__tests__/__snapshots__/Autocomplete.test.js.snap
+++ b/packages/dnb-eufemia/src/components/autocomplete/__tests__/__snapshots__/Autocomplete.test.js.snap
@@ -72,7 +72,7 @@ exports[`Autocomplete markup have to match snapshot 1`] = `
skeleton="skeleton"
skip_portal={true}
status="status"
- status_animation="status_animation"
+ status_no_animation="status_no_animation"
status_state="error"
stretch="stretch"
submit_button_icon="submit_button_icon"
@@ -173,7 +173,7 @@ exports[`Autocomplete markup have to match snapshot 1`] = `
skip_keysearch={true}
skip_portal={true}
status="status"
- status_animation="status_animation"
+ status_no_animation="status_no_animation"
status_state="error"
stretch="stretch"
submit_button_icon="submit_button_icon"
@@ -258,7 +258,7 @@ exports[`Autocomplete markup have to match snapshot 1`] = `
skeleton="skeleton"
skip_portal={true}
status="status"
- status_animation="status_animation"
+ status_no_animation="status_no_animation"
status_state="error"
stretch="stretch"
submit_button_icon="submit_button_icon"
@@ -310,17 +310,17 @@ exports[`Autocomplete markup have to match snapshot 1`] = `
/>
+
@@ -637,7 +660,7 @@ exports[`Autocomplete markup have to match snapshot 1`] = `
size={null}
skeleton={null}
status={null}
- status_animation={null}
+ status_no_animation={null}
status_state="error"
stretch={null}
text={null}
@@ -693,7 +716,7 @@ exports[`Autocomplete markup have to match snapshot 1`] = `
size={null}
skeleton={false}
status={null}
- status_animation={null}
+ status_no_animation={null}
status_state="error"
stretch={null}
text={null}
@@ -729,6 +752,30 @@ exports[`Autocomplete markup have to match snapshot 1`] = `
/>
+
@@ -1097,7 +1144,7 @@ exports[`Autocomplete markup have to match snapshot 1`] = `
"skeleton": "skeleton",
"skip_portal": true,
"status": "status",
- "status_animation": "status_animation",
+ "status_no_animation": "status_no_animation",
"status_state": "error",
"stretch": "stretch",
"submit_button_icon": "submit_button_icon",
@@ -1329,7 +1376,20 @@ exports[`Autocomplete scss have to match snapshot 1`] = `
--form-status-radius: 0.25rem; }
.dnb-form-status {
- display: flex; }
+ display: flex;
+ opacity: 1;
+ transition: height 400ms cubic-bezier(0.42, 0, 0, 1), opacity 400ms cubic-bezier(0.42, 0, 0, 1), margin 400ms cubic-bezier(0.42, 0, 0, 1), padding 400ms cubic-bezier(0.42, 0, 0, 1); }
+ .dnb-form-status--hidden {
+ will-change: height, opacity, margin, padding;
+ width: 0;
+ height: 0;
+ opacity: 0; }
+ .dnb-form-status--is-animating {
+ overflow: hidden;
+ width: auto; }
+ .dnb-form-status--disappear, .dnb-form-status--hidden {
+ margin: 0 !important;
+ padding: 0 !important; }
.dnb-form-status__shell {
display: flex;
justify-content: flex-start;
@@ -1366,16 +1426,9 @@ exports[`Autocomplete scss have to match snapshot 1`] = `
max-width: 47rem; }
.dnb-form-status[hidden] {
display: none; }
- .dnb-form-status__animation--fade-in {
- overflow: hidden;
- max-height: 0;
- animation: form-status-fade-in 2s ease-out 400ms forwards; }
-
-@keyframes form-status-fade-in {
- from {
- max-height: 0; }
- to {
- max-height: calc(var(--input-height) * 8); } }
+ .dnb-form-status--no-animation,
+ .dnb-form-status html[data-visual-test] {
+ transition-duration: 1ms !important; }
@media screen and (-ms-high-contrast: none) {
.dnb-form-status__shell > .dnb-icon {
border-width: 1px; } }
@@ -1859,6 +1912,18 @@ legend.dnb-form-label {
/* IE needs this to stay centered */ }
.dnb-input__submit-button__button {
border-radius: 0 var(--input-border-radius) var(--input-border-radius) 0; }
+ .dnb-input > .dnb-form-label {
+ line-height: var(--line-height-basis); }
+ @media screen and (max-width: 40em) {
+ .dnb-input {
+ flex-wrap: wrap; }
+ .dnb-input > .dnb-form-label {
+ margin-bottom: 0.5rem;
+ margin-top: 0.5rem; } }
+ .dnb-input:not(.dnb-input--vertical)[class*='__status'] {
+ align-items: flex-start; }
+ .dnb-input:not(.dnb-input--vertical)[class*='__status'] > .dnb-form-label {
+ margin-top: 0.25rem; }
.dnb-input--small {
line-height: var(--input-height--small); }
.dnb-input--small .dnb-input__shell,
@@ -2002,18 +2067,6 @@ legend.dnb-form-label {
.dnb-input--icon-size-medium.dnb-input--icon-position-right.dnb-input--has-icon .dnb-input__input,
.dnb-input--icon-size-medium.dnb-input--icon-position-right.dnb-input--has-icon .dnb-input__placeholder {
padding-right: 3rem; }
- .dnb-input > .dnb-form-label {
- line-height: var(--line-height-basis); }
- @media screen and (max-width: 40em) {
- .dnb-input {
- flex-wrap: wrap; }
- .dnb-input > .dnb-form-label {
- margin-bottom: 0.5rem;
- margin-top: 0.5rem; } }
- .dnb-input[class*='__status'] {
- align-items: flex-start; }
- .dnb-input[class*='__status'] > .dnb-form-label {
- margin-top: 0.25rem; }
@media screen and (max-width: 40em) {
.dnb-responsive-component .dnb-input {
display: flex;
@@ -2406,9 +2459,9 @@ legend.dnb-form-label {
display: flex;
flex-direction: column;
align-items: flex-start; }
- .dnb-autocomplete[class*='__status'] {
+ .dnb-autocomplete:not(.dnb-autocomplete--vertical)[class*='__status'] {
align-items: flex-start; }
- .dnb-autocomplete[class*='__status'] > .dnb-form-label {
+ .dnb-autocomplete:not(.dnb-autocomplete--vertical)[class*='__status'] > .dnb-form-label {
margin-top: 0.25rem; }
@media screen and (max-width: 40em) {
.dnb-responsive-component .dnb-autocomplete {
diff --git a/packages/dnb-eufemia/src/components/autocomplete/style/_autocomplete.scss b/packages/dnb-eufemia/src/components/autocomplete/style/_autocomplete.scss
index 3b75749cc86..da6a7bce6db 100644
--- a/packages/dnb-eufemia/src/components/autocomplete/style/_autocomplete.scss
+++ b/packages/dnb-eufemia/src/components/autocomplete/style/_autocomplete.scss
@@ -198,7 +198,7 @@
align-items: flex-start;
}
- &[class*='__status'] {
+ &:not(&--vertical)[class*='__status'] {
align-items: flex-start;
> .dnb-form-label {
// vertical align the current font
diff --git a/packages/dnb-eufemia/src/components/button/Button.js b/packages/dnb-eufemia/src/components/button/Button.js
index a4b3ddc6482..22dd399b879 100644
--- a/packages/dnb-eufemia/src/components/button/Button.js
+++ b/packages/dnb-eufemia/src/components/button/Button.js
@@ -60,7 +60,10 @@ export const buttonPropTypes = {
PropTypes.node,
]),
status_state: PropTypes.string,
- status_animation: PropTypes.string,
+ status_no_animation: PropTypes.oneOfType([
+ PropTypes.string,
+ PropTypes.bool,
+ ]),
global_status_id: PropTypes.string,
id: PropTypes.string,
class: PropTypes.string,
@@ -133,7 +136,7 @@ export default class Button extends React.PureComponent {
tooltip: null,
status: null,
status_state: 'error',
- status_animation: null,
+ status_no_animation: null,
global_status_id: null,
inner_ref: null,
@@ -207,7 +210,7 @@ export default class Button extends React.PureComponent {
tooltip,
status,
status_state,
- status_animation,
+ status_no_animation,
global_status_id,
id, // eslint-disable-line
disabled,
@@ -338,19 +341,20 @@ export default class Button extends React.PureComponent {
skeleton={isTrue(skeleton)}
/>
+
{this.state.afterContent}
- {showStatus && (
-
- )}
+
+
{tooltip && this._ref && (
+
`;
@@ -406,7 +430,7 @@ exports[`Button component have to match href="..." snapshot 1`] = `
size={null}
skeleton="skeleton"
status={null}
- status_animation="status_animation"
+ status_no_animation="status_no_animation"
status_state="status_state"
stretch="stretch"
text={null}
@@ -729,7 +753,7 @@ exports[`Button component have to match href="..." snapshot 1`] = `
size={null}
skeleton={false}
status={null}
- status_animation="status_animation"
+ status_no_animation="status_no_animation"
status_state="status_state"
stretch="stretch"
text={null}
@@ -799,6 +823,30 @@ exports[`Button component have to match href="..." snapshot 1`] = `
+
`;
@@ -1519,7 +1567,20 @@ exports[`Button scss have to match snapshot 1`] = `
--form-status-radius: 0.25rem; }
.dnb-form-status {
- display: flex; }
+ display: flex;
+ opacity: 1;
+ transition: height 400ms cubic-bezier(0.42, 0, 0, 1), opacity 400ms cubic-bezier(0.42, 0, 0, 1), margin 400ms cubic-bezier(0.42, 0, 0, 1), padding 400ms cubic-bezier(0.42, 0, 0, 1); }
+ .dnb-form-status--hidden {
+ will-change: height, opacity, margin, padding;
+ width: 0;
+ height: 0;
+ opacity: 0; }
+ .dnb-form-status--is-animating {
+ overflow: hidden;
+ width: auto; }
+ .dnb-form-status--disappear, .dnb-form-status--hidden {
+ margin: 0 !important;
+ padding: 0 !important; }
.dnb-form-status__shell {
display: flex;
justify-content: flex-start;
@@ -1556,16 +1617,9 @@ exports[`Button scss have to match snapshot 1`] = `
max-width: 47rem; }
.dnb-form-status[hidden] {
display: none; }
- .dnb-form-status__animation--fade-in {
- overflow: hidden;
- max-height: 0;
- animation: form-status-fade-in 2s ease-out 400ms forwards; }
-
-@keyframes form-status-fade-in {
- from {
- max-height: 0; }
- to {
- max-height: calc(var(--input-height) * 8); } }
+ .dnb-form-status--no-animation,
+ .dnb-form-status html[data-visual-test] {
+ transition-duration: 1ms !important; }
@media screen and (-ms-high-contrast: none) {
.dnb-form-status__shell > .dnb-icon {
border-width: 1px; } }
diff --git a/packages/dnb-eufemia/src/components/checkbox/Checkbox.js b/packages/dnb-eufemia/src/components/checkbox/Checkbox.js
index 117588d1af6..5d25918e43e 100644
--- a/packages/dnb-eufemia/src/components/checkbox/Checkbox.js
+++ b/packages/dnb-eufemia/src/components/checkbox/Checkbox.js
@@ -60,7 +60,10 @@ export default class Checkbox extends React.PureComponent {
PropTypes.node,
]),
status_state: PropTypes.string,
- status_animation: PropTypes.string,
+ status_no_animation: PropTypes.oneOfType([
+ PropTypes.string,
+ PropTypes.bool,
+ ]),
global_status_id: PropTypes.string,
suffix: PropTypes.oneOfType([
PropTypes.string,
@@ -96,7 +99,7 @@ export default class Checkbox extends React.PureComponent {
size: null,
status: null,
status_state: 'error',
- status_animation: null,
+ status_no_animation: null,
global_status_id: null,
suffix: null,
value: null,
@@ -194,7 +197,7 @@ export default class Checkbox extends React.PureComponent {
value,
status,
status_state,
- status_animation,
+ status_no_animation,
global_status_id,
suffix,
size,
@@ -263,8 +266,9 @@ export default class Checkbox extends React.PureComponent {
// also used for code markup simulation
validateDOMAttributes(this.props, inputParams)
- const statusComp = showStatus && (
+ const statusComp = (
)
diff --git a/packages/dnb-eufemia/src/components/checkbox/__tests__/__snapshots__/Checkbox.test.js.snap b/packages/dnb-eufemia/src/components/checkbox/__tests__/__snapshots__/Checkbox.test.js.snap
index 69ecbe377dd..913c79ff6bd 100644
--- a/packages/dnb-eufemia/src/components/checkbox/__tests__/__snapshots__/Checkbox.test.js.snap
+++ b/packages/dnb-eufemia/src/components/checkbox/__tests__/__snapshots__/Checkbox.test.js.snap
@@ -26,7 +26,7 @@ exports[`Checkbox component have to match snapshot 1`] = `
"size": "'default'",
"skeleton": "skeleton",
"status": "status",
- "status_animation": "status_animation",
+ "status_no_animation": "status_no_animation",
"status_state": "status_state",
"suffix": "suffix",
"title": "title",
@@ -61,7 +61,7 @@ exports[`Checkbox component have to match snapshot 1`] = `
size={null}
skeleton={null}
status={null}
- status_animation={null}
+ status_no_animation={null}
status_state="error"
suffix={null}
title={null}
@@ -107,6 +107,30 @@ exports[`Checkbox component have to match snapshot 1`] = `
className="dnb-alignment-helper"
/>
+
@@ -408,7 +432,20 @@ legend.dnb-form-label {
--form-status-radius: 0.25rem; }
.dnb-form-status {
- display: flex; }
+ display: flex;
+ opacity: 1;
+ transition: height 400ms cubic-bezier(0.42, 0, 0, 1), opacity 400ms cubic-bezier(0.42, 0, 0, 1), margin 400ms cubic-bezier(0.42, 0, 0, 1), padding 400ms cubic-bezier(0.42, 0, 0, 1); }
+ .dnb-form-status--hidden {
+ will-change: height, opacity, margin, padding;
+ width: 0;
+ height: 0;
+ opacity: 0; }
+ .dnb-form-status--is-animating {
+ overflow: hidden;
+ width: auto; }
+ .dnb-form-status--disappear, .dnb-form-status--hidden {
+ margin: 0 !important;
+ padding: 0 !important; }
.dnb-form-status__shell {
display: flex;
justify-content: flex-start;
@@ -445,16 +482,9 @@ legend.dnb-form-label {
max-width: 47rem; }
.dnb-form-status[hidden] {
display: none; }
- .dnb-form-status__animation--fade-in {
- overflow: hidden;
- max-height: 0;
- animation: form-status-fade-in 2s ease-out 400ms forwards; }
-
-@keyframes form-status-fade-in {
- from {
- max-height: 0; }
- to {
- max-height: calc(var(--input-height) * 8); } }
+ .dnb-form-status--no-animation,
+ .dnb-form-status html[data-visual-test] {
+ transition-duration: 1ms !important; }
@media screen and (-ms-high-contrast: none) {
.dnb-form-status__shell > .dnb-icon {
border-width: 1px; } }
diff --git a/packages/dnb-eufemia/src/components/date-picker/DatePicker.js b/packages/dnb-eufemia/src/components/date-picker/DatePicker.js
index d457282ef3a..b1d32f8f088 100644
--- a/packages/dnb-eufemia/src/components/date-picker/DatePicker.js
+++ b/packages/dnb-eufemia/src/components/date-picker/DatePicker.js
@@ -155,7 +155,10 @@ export default class DatePicker extends React.PureComponent {
PropTypes.node,
]),
status_state: PropTypes.string,
- status_animation: PropTypes.string,
+ status_no_animation: PropTypes.oneOfType([
+ PropTypes.string,
+ PropTypes.bool,
+ ]),
global_status_id: PropTypes.string,
suffix: PropTypes.oneOfType([
PropTypes.string,
@@ -231,7 +234,7 @@ export default class DatePicker extends React.PureComponent {
skeleton: null,
status: null,
status_state: 'error',
- status_animation: null,
+ status_no_animation: null,
global_status_id: null,
suffix: null,
opened: false,
@@ -507,7 +510,7 @@ export default class DatePicker extends React.PureComponent {
skeleton,
status,
status_state,
- status_animation,
+ status_no_animation,
global_status_id,
suffix,
mask_order,
@@ -625,19 +628,20 @@ export default class DatePicker extends React.PureComponent {
{...pickerParams}
>
- {showStatus && (
-
- )}
+
+
+
@@ -454,7 +453,7 @@ exports[`DatePicker component have to match snapshot 1`] = `
size={null}
skeleton={false}
status="error"
- status_animation={null}
+ status_no_animation={null}
status_state="error"
stretch={false}
submit_button_icon="loupe"
@@ -499,6 +498,30 @@ exports[`DatePicker component have to match snapshot 1`] = `
className="dnb-alignment-helper"
/>
+
@@ -1239,7 +1262,7 @@ exports[`DatePicker component have to match snapshot 1`] = `
size={null}
skeleton={null}
status="error"
- status_animation={null}
+ status_no_animation={null}
status_state="error"
stretch={null}
text={null}
@@ -1324,7 +1347,7 @@ exports[`DatePicker component have to match snapshot 1`] = `
size={null}
skeleton={false}
status="error"
- status_animation={null}
+ status_no_animation={null}
status_state="error"
stretch={null}
text={null}
@@ -1382,6 +1405,30 @@ exports[`DatePicker component have to match snapshot 1`] = `
+
@@ -1696,7 +1743,20 @@ exports[`DatePicker scss have to match snapshot 1`] = `
--form-status-radius: 0.25rem; }
.dnb-form-status {
- display: flex; }
+ display: flex;
+ opacity: 1;
+ transition: height 400ms cubic-bezier(0.42, 0, 0, 1), opacity 400ms cubic-bezier(0.42, 0, 0, 1), margin 400ms cubic-bezier(0.42, 0, 0, 1), padding 400ms cubic-bezier(0.42, 0, 0, 1); }
+ .dnb-form-status--hidden {
+ will-change: height, opacity, margin, padding;
+ width: 0;
+ height: 0;
+ opacity: 0; }
+ .dnb-form-status--is-animating {
+ overflow: hidden;
+ width: auto; }
+ .dnb-form-status--disappear, .dnb-form-status--hidden {
+ margin: 0 !important;
+ padding: 0 !important; }
.dnb-form-status__shell {
display: flex;
justify-content: flex-start;
@@ -1733,16 +1793,9 @@ exports[`DatePicker scss have to match snapshot 1`] = `
max-width: 47rem; }
.dnb-form-status[hidden] {
display: none; }
- .dnb-form-status__animation--fade-in {
- overflow: hidden;
- max-height: 0;
- animation: form-status-fade-in 2s ease-out 400ms forwards; }
-
-@keyframes form-status-fade-in {
- from {
- max-height: 0; }
- to {
- max-height: calc(var(--input-height) * 8); } }
+ .dnb-form-status--no-animation,
+ .dnb-form-status html[data-visual-test] {
+ transition-duration: 1ms !important; }
@media screen and (-ms-high-contrast: none) {
.dnb-form-status__shell > .dnb-icon {
border-width: 1px; } }
@@ -2226,6 +2279,18 @@ legend.dnb-form-label {
/* IE needs this to stay centered */ }
.dnb-input__submit-button__button {
border-radius: 0 var(--input-border-radius) var(--input-border-radius) 0; }
+ .dnb-input > .dnb-form-label {
+ line-height: var(--line-height-basis); }
+ @media screen and (max-width: 40em) {
+ .dnb-input {
+ flex-wrap: wrap; }
+ .dnb-input > .dnb-form-label {
+ margin-bottom: 0.5rem;
+ margin-top: 0.5rem; } }
+ .dnb-input:not(.dnb-input--vertical)[class*='__status'] {
+ align-items: flex-start; }
+ .dnb-input:not(.dnb-input--vertical)[class*='__status'] > .dnb-form-label {
+ margin-top: 0.25rem; }
.dnb-input--small {
line-height: var(--input-height--small); }
.dnb-input--small .dnb-input__shell,
@@ -2369,18 +2434,6 @@ legend.dnb-form-label {
.dnb-input--icon-size-medium.dnb-input--icon-position-right.dnb-input--has-icon .dnb-input__input,
.dnb-input--icon-size-medium.dnb-input--icon-position-right.dnb-input--has-icon .dnb-input__placeholder {
padding-right: 3rem; }
- .dnb-input > .dnb-form-label {
- line-height: var(--line-height-basis); }
- @media screen and (max-width: 40em) {
- .dnb-input {
- flex-wrap: wrap; }
- .dnb-input > .dnb-form-label {
- margin-bottom: 0.5rem;
- margin-top: 0.5rem; } }
- .dnb-input[class*='__status'] {
- align-items: flex-start; }
- .dnb-input[class*='__status'] > .dnb-form-label {
- margin-top: 0.25rem; }
@media screen and (max-width: 40em) {
.dnb-responsive-component .dnb-input {
display: flex;
@@ -3272,9 +3325,9 @@ legend.dnb-form-label {
width: 100%; }
.dnb-form-row--horizontal .dnb-date-picker--stretch {
width: 100%; }
- .dnb-date-picker[class*='__status'] {
+ .dnb-date-picker:not(.dnb-date-picker--vertical)[class*='__status'] {
align-items: flex-start; }
- .dnb-date-picker[class*='__status'] > .dnb-form-label {
+ .dnb-date-picker:not(.dnb-date-picker--vertical)[class*='__status'] > .dnb-form-label {
margin-top: 0.25rem; }
.dnb-date-picker:not(.dnb-date-picker--show-input) .dnb-input__submit-button
.dnb-button {
diff --git a/packages/dnb-eufemia/src/components/date-picker/style/_date-picker.scss b/packages/dnb-eufemia/src/components/date-picker/style/_date-picker.scss
index c95fe02777a..70d4302ace8 100644
--- a/packages/dnb-eufemia/src/components/date-picker/style/_date-picker.scss
+++ b/packages/dnb-eufemia/src/components/date-picker/style/_date-picker.scss
@@ -423,7 +423,7 @@
width: 100%;
}
- &[class*='__status'] {
+ &:not(&--vertical)[class*='__status'] {
align-items: flex-start;
> .dnb-form-label {
// vertical align the current font
diff --git a/packages/dnb-eufemia/src/components/dropdown/Dropdown.js b/packages/dnb-eufemia/src/components/dropdown/Dropdown.js
index 59e836ace5c..0fcbdadcf72 100644
--- a/packages/dnb-eufemia/src/components/dropdown/Dropdown.js
+++ b/packages/dnb-eufemia/src/components/dropdown/Dropdown.js
@@ -66,7 +66,10 @@ export default class Dropdown extends React.PureComponent {
PropTypes.node,
]),
status_state: PropTypes.string,
- status_animation: PropTypes.string,
+ status_no_animation: PropTypes.oneOfType([
+ PropTypes.string,
+ PropTypes.bool,
+ ]),
global_status_id: PropTypes.string,
suffix: PropTypes.oneOfType([
PropTypes.string,
@@ -169,7 +172,7 @@ export default class Dropdown extends React.PureComponent {
label_sr_only: null,
status: null,
status_state: 'error',
- status_animation: null,
+ status_no_animation: null,
global_status_id: null,
suffix: null,
scrollable: true,
@@ -432,7 +435,7 @@ class DropdownInstance extends React.PureComponent {
enable_body_lock,
status,
status_state,
- status_animation,
+ status_no_animation,
global_status_id,
suffix,
scrollable,
@@ -585,18 +588,17 @@ class DropdownInstance extends React.PureComponent {
- {showStatus && (
-
- )}
+
diff --git a/packages/dnb-eufemia/src/components/dropdown/__tests__/__snapshots__/Dropdown.test.js.snap b/packages/dnb-eufemia/src/components/dropdown/__tests__/__snapshots__/Dropdown.test.js.snap
index 6a58f92517a..ff0e2ffa53d 100644
--- a/packages/dnb-eufemia/src/components/dropdown/__tests__/__snapshots__/Dropdown.test.js.snap
+++ b/packages/dnb-eufemia/src/components/dropdown/__tests__/__snapshots__/Dropdown.test.js.snap
@@ -92,7 +92,7 @@ exports[`Dropdown markup have to match snapshot 1`] = `
skeleton="skeleton"
skip_portal={true}
status="status"
- status_animation="status_animation"
+ status_no_animation="status_no_animation"
status_state="error"
stretch="stretch"
suffix="suffix"
@@ -211,7 +211,7 @@ exports[`Dropdown markup have to match snapshot 1`] = `
skip_keysearch={false}
skip_portal={true}
status="status"
- status_animation="status_animation"
+ status_no_animation="status_no_animation"
status_state="error"
stretch="stretch"
suffix="suffix"
@@ -315,7 +315,7 @@ exports[`Dropdown markup have to match snapshot 1`] = `
skeleton="skeleton"
skip_portal={true}
status="status"
- status_animation="status_animation"
+ status_no_animation="status_no_animation"
status_state="error"
stretch="stretch"
suffix="suffix"
@@ -366,17 +366,17 @@ exports[`Dropdown markup have to match snapshot 1`] = `
/>
+
.dnb-icon {
border-width: 1px; } }
@@ -2117,9 +2146,9 @@ legend.dnb-form-label {
display: flex;
flex-direction: column;
align-items: flex-start; }
- .dnb-dropdown[class*='__status'] {
+ .dnb-dropdown:not(.dnb-dropdown--vertical)[class*='__status'] {
align-items: flex-start; }
- .dnb-dropdown[class*='__status'] > .dnb-form-label {
+ .dnb-dropdown:not(.dnb-dropdown--vertical)[class*='__status'] > .dnb-form-label {
margin-top: 0.25rem; }
@media screen and (max-width: 40em) {
.dnb-responsive-component .dnb-dropdown {
diff --git a/packages/dnb-eufemia/src/components/dropdown/style/_dropdown.scss b/packages/dnb-eufemia/src/components/dropdown/style/_dropdown.scss
index 2082c15059d..a7ceb7dd58c 100644
--- a/packages/dnb-eufemia/src/components/dropdown/style/_dropdown.scss
+++ b/packages/dnb-eufemia/src/components/dropdown/style/_dropdown.scss
@@ -300,7 +300,7 @@
align-items: flex-start;
}
- &[class*='__status'] {
+ &:not(&--vertical)[class*='__status'] {
align-items: flex-start;
> .dnb-form-label {
// vertical align the current font
diff --git a/packages/dnb-eufemia/src/components/form-status/FormStatus.js b/packages/dnb-eufemia/src/components/form-status/FormStatus.js
index 94fc465cd22..8eaacc98cfb 100644
--- a/packages/dnb-eufemia/src/components/form-status/FormStatus.js
+++ b/packages/dnb-eufemia/src/components/form-status/FormStatus.js
@@ -15,6 +15,7 @@ import {
processChildren,
extendPropsWithContext,
} from '../../shared/component-helper'
+import AnimateHeight from '../../shared/AnimateHeight'
import {
spacingPropTypes,
createSpacingClasses,
@@ -33,6 +34,7 @@ export default class FormStatus extends React.PureComponent {
static propTypes = {
id: PropTypes.string,
title: PropTypes.string,
+ show: PropTypes.oneOfType([PropTypes.string, PropTypes.bool]),
text: PropTypes.oneOfType([
PropTypes.string,
PropTypes.bool,
@@ -61,12 +63,11 @@ export default class FormStatus extends React.PureComponent {
]),
global_status_id: PropTypes.string,
attributes: PropTypes.oneOfType([PropTypes.string, PropTypes.object]),
- hidden: PropTypes.oneOfType([PropTypes.string, PropTypes.bool]),
text_id: PropTypes.string,
width_selector: PropTypes.string,
width_element: PropTypes.object,
class: PropTypes.string,
- animation: PropTypes.string,
+ no_animation: PropTypes.oneOfType([PropTypes.string, PropTypes.bool]),
skeleton: PropTypes.oneOfType([PropTypes.string, PropTypes.bool]),
stretch: PropTypes.oneOfType([PropTypes.string, PropTypes.bool]),
role: PropTypes.string,
@@ -84,6 +85,7 @@ export default class FormStatus extends React.PureComponent {
static defaultProps = {
id: null,
title: null,
+ show: true,
text: null,
label: null,
icon: 'error',
@@ -94,12 +96,11 @@ export default class FormStatus extends React.PureComponent {
status: null, // Deprecated
global_status_id: null,
attributes: null,
- hidden: false,
text_id: null,
width_selector: null,
width_element: null,
class: null,
- animation: null, // could be 'fade-in'
+ no_animation: null,
skeleton: null,
stretch: null,
role: null,
@@ -167,7 +168,7 @@ export default class FormStatus extends React.PureComponent {
}
static getDerivedStateFromProps(props, state) {
- if (state._id !== props.id) {
+ if (state._id !== props.id && props.id) {
state.id = props.id
}
@@ -176,7 +177,7 @@ export default class FormStatus extends React.PureComponent {
return state
}
- state = { id: null }
+ state = { id: null, keepContentInDom: null }
constructor(props) {
super(props)
@@ -184,16 +185,15 @@ export default class FormStatus extends React.PureComponent {
// we do not use a random ID here, as we don't need it for now
this.state.id = props.id || makeUniqueId()
- if (props.status !== 'info') {
- this.gsProvider = GlobalStatusProvider.init(
- props.global_status_id || 'main',
- (provider) => {
- // gets called once ready
+ this._globalStatus = GlobalStatusProvider.init(
+ props.global_status_id || 'main',
+ (provider) => {
+ // gets called once ready
+ if (this.props.state === 'error' && this.isReadyToGetVisible()) {
const { state, text, label } = this.props
provider.add({
state,
- status_id: `${this.state.id}-gs`,
- // show: true,
+ status_id: this.getStatusId(),
item: {
status_id: this.state.id,
text,
@@ -202,17 +202,36 @@ export default class FormStatus extends React.PureComponent {
},
})
}
- )
- }
+ }
+ )
this._ref = React.createRef()
+
+ this._heightAnim = new AnimateHeight({
+ animate: false,
+
+ /** TODO: considder to enable animation by default */
+ // animate: !isTrue(props.no_animation),
+ })
+
+ this._heightAnim.onStart(() => {
+ this.setState({
+ isAnimating: true,
+ keepContentInDom: true,
+ })
+ })
+
+ this._heightAnim.onEnd(() => {
+ this.setState({
+ isAnimating: false,
+ keepContentInDom: isTrue(this.props.show),
+ })
+ })
}
init = () => {
if (this._isMounted) {
- if (this.gsProvider) {
- this.gsProvider.isReady()
- }
+ this._globalStatus.isReady()
this.updateWidth()
}
@@ -229,41 +248,60 @@ export default class FormStatus extends React.PureComponent {
componentWillUnmount() {
this._isMounted = false
- if (this.gsProvider) {
- const status_id = `${this.state.id}-gs`
- this.gsProvider.remove(status_id)
- }
+ const status_id = this.getStatusId()
+ this._globalStatus.remove(status_id)
if (typeof window !== 'undefined') {
window.removeEventListener('load', this.init)
}
+ this._heightAnim.remove()
}
componentDidUpdate(prevProps) {
if (
- this.gsProvider &&
- (prevProps.text !== this.props.text ||
- prevProps.state !== this.props.state)
+ // this._globalStatus &&
+ prevProps.text !== this.props.text ||
+ prevProps.children !== this.props.children ||
+ prevProps.show !== this.props.show ||
+ prevProps.state !== this.props.state
) {
const { state, text, label } = this.props
- const status_id = `${this.state.id}-gs`
- this.gsProvider.update(
- status_id,
- {
- state,
- item: {
- status_id: this.state.id,
- text,
- status_anchor_label: label,
- status_anchor_url: true,
+ const status_id = this.getStatusId()
+
+ if (this.props.state === 'error' && isTrue(this.props.show)) {
+ this._globalStatus.update(
+ status_id,
+ {
+ state,
+ status_id,
+ item: {
+ status_id: this.state.id,
+ text,
+ status_anchor_label: label,
+ status_anchor_url: true,
+ },
},
- },
- {
- preventRestack: true, // because of the internal "close"
+ {
+ preventRestack: true, // because of the internal "close"
+ }
+ )
+ }
+
+ if (this.isReadyToGetVisible()) {
+ this.updateWidth()
+ this._heightAnim.setElement(this._ref.current)
+ this._heightAnim.open()
+ } else {
+ this._heightAnim.close()
+ if (this.props.state === 'error') {
+ const status_id = this.getStatusId()
+ this._globalStatus.remove(status_id)
}
- )
+ }
}
+ }
- this.updateWidth()
+ getStatusId() {
+ return `${this.state.id}-gs`
}
updateWidth() {
@@ -278,7 +316,19 @@ export default class FormStatus extends React.PureComponent {
}
}
+ isReadyToGetVisible(props = this.props) {
+ return isTrue(props.show) && FormStatus.getContent(props)
+ ? true
+ : false
+ }
+
render() {
+ const isReadyToGetVisible = this.isReadyToGetVisible()
+
+ if (!isReadyToGetVisible && !this.state.keepContentInDom) {
+ return null
+ }
+
// use only the props from context, who are available here anyway
const props = extendPropsWithContext(
this.props,
@@ -289,14 +339,14 @@ export default class FormStatus extends React.PureComponent {
)
const {
+ show, // eslint-disable-line
title,
status: rawStatus,
state: rawState,
size,
variant,
- hidden,
className,
- animation,
+ no_animation,
stretch,
class: _className,
text_id,
@@ -319,34 +369,43 @@ export default class FormStatus extends React.PureComponent {
icon,
icon_size,
})
- const contentToRender = FormStatus.getContent(this.props)
- // stop here if we don't have content
- if (contentToRender === null) {
- return <>>
+ const contentToRender =
+ this.state.keepContentInDom && this._cachedContent
+ ? this._cachedContent
+ : FormStatus.getContent(this.props)
+
+ // Add a cache, we use this during the "hide" period when animating
+ if (!this.state.isAnimating) {
+ this._cachedContent = contentToRender
}
const hasStringContent =
typeof contentToRender === 'string' && contentToRender.length > 0
const params = {
- id: this.state.id,
- hidden,
className: classnames(
'dnb-form-status',
`dnb-form-status--${state}`,
`dnb-form-status__size--${size}`,
variant && `dnb-form-status__variant--${variant}`,
- animation ? `dnb-form-status__animation--${animation}` : null,
+ this.state.isAnimating && 'dnb-form-status--is-animating',
+ !isReadyToGetVisible &&
+ !this.state.keepContentInDom &&
+ 'dnb-form-status--hidden',
+ !isReadyToGetVisible &&
+ this.state.keepContentInDom &&
+ 'dnb-form-status--disappear',
+ isTrue(no_animation) && 'dnb-form-status--no-animation',
stretch && 'dnb-form-status--stretch',
hasStringContent ? 'dnb-form-status--has-content' : null,
createSpacingClasses(props),
className,
_className
),
+ id: !String(id).startsWith('null') ? this.state.id : null,
title,
role,
-
...rest,
}
@@ -365,11 +424,7 @@ export default class FormStatus extends React.PureComponent {
'dnb-form-status__text',
createSkeletonClass('font', skeleton, this.context)
),
- id: text_id,
- }
-
- if (hidden) {
- params['aria-hidden'] = hidden
+ id: !String(text_id).startsWith('null') ? text_id : null,
}
skeletonDOMAttributes(params, skeleton, this.context)
diff --git a/packages/dnb-eufemia/src/components/form-status/__tests__/__snapshots__/FormStatus.test.js.snap b/packages/dnb-eufemia/src/components/form-status/__tests__/__snapshots__/FormStatus.test.js.snap
index c77e20c4c17..c6919c32f4c 100644
--- a/packages/dnb-eufemia/src/components/form-status/__tests__/__snapshots__/FormStatus.test.js.snap
+++ b/packages/dnb-eufemia/src/components/form-status/__tests__/__snapshots__/FormStatus.test.js.snap
@@ -6,18 +6,18 @@ exports[`FormStatus component have to match snapshot 1`] = `
Object {
"displayName": "FormStatus",
"props": Object {
- "animation": "animation",
"attributes": "attributes",
"children": "children",
"class": "class",
"className": "className",
"global_status_id": "global_status_id",
- "hidden": "hidden",
"icon": "icon",
"icon_size": "icon_size",
"id": "id",
"label": "label",
+ "no_animation": "no_animation",
"role": "role",
+ "show": "show",
"size": "'default'",
"skeleton": "skeleton",
"state": true,
@@ -56,7 +56,6 @@ exports[`FormStatus component have to match snapshot 1`] = `
},
}
}
- animation={null}
attributes={null}
class={null}
className={null}
@@ -66,7 +65,9 @@ exports[`FormStatus component have to match snapshot 1`] = `
icon_size="medium"
id="form-status"
label={null}
+ no_animation={null}
role={null}
+ show={true}
size="default"
skeleton={null}
state="error"
@@ -302,7 +303,20 @@ exports[`FormStatus scss have to match snapshot 1`] = `
--form-status-radius: 0.25rem; }
.dnb-form-status {
- display: flex; }
+ display: flex;
+ opacity: 1;
+ transition: height 400ms cubic-bezier(0.42, 0, 0, 1), opacity 400ms cubic-bezier(0.42, 0, 0, 1), margin 400ms cubic-bezier(0.42, 0, 0, 1), padding 400ms cubic-bezier(0.42, 0, 0, 1); }
+ .dnb-form-status--hidden {
+ will-change: height, opacity, margin, padding;
+ width: 0;
+ height: 0;
+ opacity: 0; }
+ .dnb-form-status--is-animating {
+ overflow: hidden;
+ width: auto; }
+ .dnb-form-status--disappear, .dnb-form-status--hidden {
+ margin: 0 !important;
+ padding: 0 !important; }
.dnb-form-status__shell {
display: flex;
justify-content: flex-start;
@@ -339,16 +353,9 @@ exports[`FormStatus scss have to match snapshot 1`] = `
max-width: 47rem; }
.dnb-form-status[hidden] {
display: none; }
- .dnb-form-status__animation--fade-in {
- overflow: hidden;
- max-height: 0;
- animation: form-status-fade-in 2s ease-out 400ms forwards; }
-
-@keyframes form-status-fade-in {
- from {
- max-height: 0; }
- to {
- max-height: calc(var(--input-height) * 8); } }
+ .dnb-form-status--no-animation,
+ .dnb-form-status html[data-visual-test] {
+ transition-duration: 1ms !important; }
@media screen and (-ms-high-contrast: none) {
.dnb-form-status__shell > .dnb-icon {
border-width: 1px; } }
diff --git a/packages/dnb-eufemia/src/components/form-status/style/_form-status.scss b/packages/dnb-eufemia/src/components/form-status/style/_form-status.scss
index 7e095528a99..03aeb2edfb6 100644
--- a/packages/dnb-eufemia/src/components/form-status/style/_form-status.scss
+++ b/packages/dnb-eufemia/src/components/form-status/style/_form-status.scss
@@ -10,6 +10,30 @@
.dnb-form-status {
display: flex;
+ opacity: 1;
+
+ transition: height 400ms #{$defaultEasing},
+ opacity 400ms #{$defaultEasing}, margin 400ms #{$defaultEasing},
+ padding 400ms #{$defaultEasing};
+
+ &--hidden {
+ will-change: height, opacity, margin, padding;
+
+ width: 0;
+ height: 0;
+
+ opacity: 0;
+ }
+ &--is-animating {
+ overflow: hidden; // because of animation
+ width: auto;
+ }
+ &--disappear,
+ &--hidden {
+ margin: 0 !important;
+ padding: 0 !important;
+ }
+
&__shell {
display: flex;
justify-content: flex-start;
@@ -83,20 +107,25 @@
display: none;
}
- &__animation--fade-in {
- @keyframes form-status-fade-in {
- from {
- max-height: 0;
- }
- to {
- max-height: calc(var(--input-height) * 8);
- }
- }
- overflow: hidden;
- max-height: 0;
- animation: form-status-fade-in 2s ease-out 400ms forwards;
+ &--no-animation,
+ html[data-visual-test] {
+ transition-duration: 1ms !important;
}
+ // &__animation--fade-in {
+ // @keyframes form-status-fade-in {
+ // from {
+ // max-height: 0;
+ // }
+ // to {
+ // max-height: calc(var(--input-height) * 8);
+ // }
+ // }
+ // overflow: hidden;
+ // max-height: 0;
+ // animation: form-status-fade-in 2s ease-out 400ms forwards;
+ // }
+
@include IS_IE {
&__shell > .dnb-icon {
border-width: 1px;
diff --git a/packages/dnb-eufemia/src/components/global-error/__tests__/__snapshots__/GlobalError.test.js.snap b/packages/dnb-eufemia/src/components/global-error/__tests__/__snapshots__/GlobalError.test.js.snap
index a8874e439e1..0375b723c84 100644
--- a/packages/dnb-eufemia/src/components/global-error/__tests__/__snapshots__/GlobalError.test.js.snap
+++ b/packages/dnb-eufemia/src/components/global-error/__tests__/__snapshots__/GlobalError.test.js.snap
@@ -155,7 +155,20 @@ exports[`GlobalError scss have to match snapshot 1`] = `
--form-status-radius: 0.25rem; }
.dnb-form-status {
- display: flex; }
+ display: flex;
+ opacity: 1;
+ transition: height 400ms cubic-bezier(0.42, 0, 0, 1), opacity 400ms cubic-bezier(0.42, 0, 0, 1), margin 400ms cubic-bezier(0.42, 0, 0, 1), padding 400ms cubic-bezier(0.42, 0, 0, 1); }
+ .dnb-form-status--hidden {
+ will-change: height, opacity, margin, padding;
+ width: 0;
+ height: 0;
+ opacity: 0; }
+ .dnb-form-status--is-animating {
+ overflow: hidden;
+ width: auto; }
+ .dnb-form-status--disappear, .dnb-form-status--hidden {
+ margin: 0 !important;
+ padding: 0 !important; }
.dnb-form-status__shell {
display: flex;
justify-content: flex-start;
@@ -192,16 +205,9 @@ exports[`GlobalError scss have to match snapshot 1`] = `
max-width: 47rem; }
.dnb-form-status[hidden] {
display: none; }
- .dnb-form-status__animation--fade-in {
- overflow: hidden;
- max-height: 0;
- animation: form-status-fade-in 2s ease-out 400ms forwards; }
-
-@keyframes form-status-fade-in {
- from {
- max-height: 0; }
- to {
- max-height: calc(var(--input-height) * 8); } }
+ .dnb-form-status--no-animation,
+ .dnb-form-status html[data-visual-test] {
+ transition-duration: 1ms !important; }
@media screen and (-ms-high-contrast: none) {
.dnb-form-status__shell > .dnb-icon {
border-width: 1px; } }
@@ -584,7 +590,7 @@ exports[`GlobalError snapshot have to match component snapshot 1`] = `
size={null}
skeleton={null}
status={null}
- status_animation={null}
+ status_no_animation={null}
status_state="error"
stretch={null}
text="back"
@@ -802,7 +808,7 @@ exports[`GlobalError snapshot have to match component snapshot 1`] = `
size={null}
skeleton={false}
status={null}
- status_animation={null}
+ status_no_animation={null}
status_state="error"
stretch={null}
text="back"
@@ -873,6 +879,30 @@ exports[`GlobalError snapshot have to match component snapshot 1`] = `
+
@@ -1241,7 +1265,7 @@ Array [
size="large"
skeleton={null}
status={null}
- status_animation={null}
+ status_no_animation={null}
status_state="error"
stretch={null}
text="Lukk"
@@ -1283,7 +1307,7 @@ Array [
size="large"
skeleton={false}
status={null}
- status_animation={null}
+ status_no_animation={null}
status_state="error"
stretch={null}
text="Lukk"
@@ -1350,6 +1374,30 @@ Array [
+
@@ -1424,7 +1472,7 @@ Array [
size={null}
skeleton={null}
status="error-message"
- status_animation={null}
+ status_no_animation={null}
status_state="error"
suffix={null}
title={null}
@@ -1448,12 +1496,10 @@ Array [
/>
}
+ no_animation={null}
role={null}
+ show={true}
size="default"
skeleton={null}
state="error"
@@ -1477,7 +1525,6 @@ Array [
>
diff --git a/packages/dnb-eufemia/src/components/global-status/style/_global-status.scss b/packages/dnb-eufemia/src/components/global-status/style/_global-status.scss
index 1343254356a..22f43c8c6df 100644
--- a/packages/dnb-eufemia/src/components/global-status/style/_global-status.scss
+++ b/packages/dnb-eufemia/src/components/global-status/style/_global-status.scss
@@ -20,15 +20,12 @@
&__shell {
width: 100%;
opacity: 1;
- transform: translate3d(0, 0, 0);
will-change: height;
transition: height 800ms var(--global-status-easing),
- opacity 600ms var(--global-status-easing),
- transform 600ms var(--global-status-easing);
+ opacity 600ms var(--global-status-easing);
}
&--hidden &__shell {
- visibility: hidden;
height: 0;
opacity: 0;
}
@@ -36,11 +33,6 @@
html[data-visual-test] &__shell {
transition-duration: 1ms !important;
}
- &--is-animating:not(.dnb-global-status--visible) &__shell {
- // Is needed in order to have a smooth animation, hiding the content nicely.
- opacity: 0;
- transform: translate3d(0, -20px, 0);
- }
&,
&--no-animation#{&}--visible {
diff --git a/packages/dnb-eufemia/src/components/help-button/__tests__/__snapshots__/HelpButton.test.js.snap b/packages/dnb-eufemia/src/components/help-button/__tests__/__snapshots__/HelpButton.test.js.snap
index f6d25a70bc8..40221b2412c 100644
--- a/packages/dnb-eufemia/src/components/help-button/__tests__/__snapshots__/HelpButton.test.js.snap
+++ b/packages/dnb-eufemia/src/components/help-button/__tests__/__snapshots__/HelpButton.test.js.snap
@@ -41,7 +41,7 @@ exports[`HelpButton component have to match snapshot 1`] = `
size={null}
skeleton={null}
status={null}
- status_animation={null}
+ status_no_animation={null}
status_state="error"
stretch={null}
text={null}
@@ -87,7 +87,7 @@ exports[`HelpButton component have to match snapshot 1`] = `
size={null}
skeleton={false}
status={null}
- status_animation={null}
+ status_no_animation={null}
status_state="error"
stretch={null}
text={null}
@@ -147,6 +147,30 @@ exports[`HelpButton component have to match snapshot 1`] = `
+
diff --git a/packages/dnb-eufemia/src/components/input-masked/__tests__/__snapshots__/InputMasked.test.js.snap b/packages/dnb-eufemia/src/components/input-masked/__tests__/__snapshots__/InputMasked.test.js.snap
index 54d2e8ad956..4cecf52ba9f 100644
--- a/packages/dnb-eufemia/src/components/input-masked/__tests__/__snapshots__/InputMasked.test.js.snap
+++ b/packages/dnb-eufemia/src/components/input-masked/__tests__/__snapshots__/InputMasked.test.js.snap
@@ -53,7 +53,7 @@ exports[`InputMasked component have to match type="text" snapshot 1`] = `
size={null}
skeleton={null}
status={null}
- status_animation={null}
+ status_no_animation={null}
status_state="error"
stretch={null}
submit_button_icon="loupe"
@@ -105,7 +105,7 @@ exports[`InputMasked component have to match type="text" snapshot 1`] = `
size={null}
skeleton={null}
status={null}
- status_animation={null}
+ status_no_animation={null}
status_state="error"
stretch={null}
submit_button_icon="loupe"
@@ -133,6 +133,30 @@ exports[`InputMasked component have to match type="text" snapshot 1`] = `
className="dnb-alignment-helper"
/>
+
@@ -336,7 +360,20 @@ exports[`InputMasked scss have to match snapshot 1`] = `
--form-status-radius: 0.25rem; }
.dnb-form-status {
- display: flex; }
+ display: flex;
+ opacity: 1;
+ transition: height 400ms cubic-bezier(0.42, 0, 0, 1), opacity 400ms cubic-bezier(0.42, 0, 0, 1), margin 400ms cubic-bezier(0.42, 0, 0, 1), padding 400ms cubic-bezier(0.42, 0, 0, 1); }
+ .dnb-form-status--hidden {
+ will-change: height, opacity, margin, padding;
+ width: 0;
+ height: 0;
+ opacity: 0; }
+ .dnb-form-status--is-animating {
+ overflow: hidden;
+ width: auto; }
+ .dnb-form-status--disappear, .dnb-form-status--hidden {
+ margin: 0 !important;
+ padding: 0 !important; }
.dnb-form-status__shell {
display: flex;
justify-content: flex-start;
@@ -373,16 +410,9 @@ exports[`InputMasked scss have to match snapshot 1`] = `
max-width: 47rem; }
.dnb-form-status[hidden] {
display: none; }
- .dnb-form-status__animation--fade-in {
- overflow: hidden;
- max-height: 0;
- animation: form-status-fade-in 2s ease-out 400ms forwards; }
-
-@keyframes form-status-fade-in {
- from {
- max-height: 0; }
- to {
- max-height: calc(var(--input-height) * 8); } }
+ .dnb-form-status--no-animation,
+ .dnb-form-status html[data-visual-test] {
+ transition-duration: 1ms !important; }
@media screen and (-ms-high-contrast: none) {
.dnb-form-status__shell > .dnb-icon {
border-width: 1px; } }
@@ -866,6 +896,18 @@ legend.dnb-form-label {
/* IE needs this to stay centered */ }
.dnb-input__submit-button__button {
border-radius: 0 var(--input-border-radius) var(--input-border-radius) 0; }
+ .dnb-input > .dnb-form-label {
+ line-height: var(--line-height-basis); }
+ @media screen and (max-width: 40em) {
+ .dnb-input {
+ flex-wrap: wrap; }
+ .dnb-input > .dnb-form-label {
+ margin-bottom: 0.5rem;
+ margin-top: 0.5rem; } }
+ .dnb-input:not(.dnb-input--vertical)[class*='__status'] {
+ align-items: flex-start; }
+ .dnb-input:not(.dnb-input--vertical)[class*='__status'] > .dnb-form-label {
+ margin-top: 0.25rem; }
.dnb-input--small {
line-height: var(--input-height--small); }
.dnb-input--small .dnb-input__shell,
@@ -1009,18 +1051,6 @@ legend.dnb-form-label {
.dnb-input--icon-size-medium.dnb-input--icon-position-right.dnb-input--has-icon .dnb-input__input,
.dnb-input--icon-size-medium.dnb-input--icon-position-right.dnb-input--has-icon .dnb-input__placeholder {
padding-right: 3rem; }
- .dnb-input > .dnb-form-label {
- line-height: var(--line-height-basis); }
- @media screen and (max-width: 40em) {
- .dnb-input {
- flex-wrap: wrap; }
- .dnb-input > .dnb-form-label {
- margin-bottom: 0.5rem;
- margin-top: 0.5rem; } }
- .dnb-input[class*='__status'] {
- align-items: flex-start; }
- .dnb-input[class*='__status'] > .dnb-form-label {
- margin-top: 0.25rem; }
@media screen and (max-width: 40em) {
.dnb-responsive-component .dnb-input {
display: flex;
diff --git a/packages/dnb-eufemia/src/components/input/Input.js b/packages/dnb-eufemia/src/components/input/Input.js
index 811e31dbb04..c796a68eed4 100644
--- a/packages/dnb-eufemia/src/components/input/Input.js
+++ b/packages/dnb-eufemia/src/components/input/Input.js
@@ -58,7 +58,10 @@ export const inputPropTypes = {
PropTypes.node,
]),
status_state: PropTypes.string,
- status_animation: PropTypes.string,
+ status_no_animation: PropTypes.oneOfType([
+ PropTypes.string,
+ PropTypes.bool,
+ ]),
input_state: PropTypes.string,
global_status_id: PropTypes.string,
autocomplete: PropTypes.string,
@@ -141,7 +144,7 @@ export default class Input extends React.PureComponent {
label_sr_only: null,
status: null,
status_state: 'error',
- status_animation: null,
+ status_no_animation: null,
input_state: null,
global_status_id: null,
autocomplete: 'off',
@@ -328,7 +331,7 @@ export default class Input extends React.PureComponent {
label_sr_only,
status,
status_state,
- status_animation,
+ status_no_animation,
global_status_id,
disabled,
skeleton,
@@ -491,18 +494,18 @@ export default class Input extends React.PureComponent {
- {showStatus && (
-
- )}
+
+
diff --git a/packages/dnb-eufemia/src/components/input/__tests__/__snapshots__/Input.test.js.snap b/packages/dnb-eufemia/src/components/input/__tests__/__snapshots__/Input.test.js.snap
index e53b9e1b6c2..a99754adee7 100644
--- a/packages/dnb-eufemia/src/components/input/__tests__/__snapshots__/Input.test.js.snap
+++ b/packages/dnb-eufemia/src/components/input/__tests__/__snapshots__/Input.test.js.snap
@@ -43,7 +43,7 @@ exports[`Input component have to match type="search" snapshot 1`] = `
"size": "'default'",
"skeleton": "skeleton",
"status": "status",
- "status_animation": "status_animation",
+ "status_no_animation": "status_no_animation",
"status_state": "status_state",
"stretch": "stretch",
"submit_button_icon": "submit_button_icon",
@@ -128,7 +128,7 @@ exports[`Input component have to match type="search" snapshot 1`] = `
size={null}
skeleton={null}
status={null}
- status_animation={null}
+ status_no_animation={null}
status_state="error"
stretch={null}
submit_button_icon="loupe"
@@ -156,6 +156,30 @@ exports[`Input component have to match type="search" snapshot 1`] = `
className="dnb-alignment-helper"
/>
+
@@ -222,7 +246,7 @@ exports[`Input component have to match type="search" snapshot 1`] = `
"size": "'default'",
"skeleton": "skeleton",
"status": "status",
- "status_animation": "status_animation",
+ "status_no_animation": "status_no_animation",
"status_state": "status_state",
"stretch": "stretch",
"submit_button_icon": "submit_button_icon",
@@ -336,7 +360,7 @@ exports[`Input component have to match type="search" snapshot 1`] = `
"size": "'default'",
"skeleton": "skeleton",
"status": "status",
- "status_animation": "status_animation",
+ "status_no_animation": "status_no_animation",
"status_state": "status_state",
"stretch": "stretch",
"submit_button_icon": "submit_button_icon",
@@ -439,7 +463,7 @@ exports[`Input component have to match type="search" snapshot 1`] = `
size={null}
skeleton={null}
status={null}
- status_animation={null}
+ status_no_animation={null}
status_state="error"
stretch={null}
text={null}
@@ -489,7 +513,7 @@ exports[`Input component have to match type="search" snapshot 1`] = `
size={null}
skeleton={false}
status={null}
- status_animation={null}
+ status_no_animation={null}
status_state="error"
stretch={null}
text={null}
@@ -548,6 +572,30 @@ exports[`Input component have to match type="search" snapshot 1`] = `
+
@@ -602,7 +650,7 @@ exports[`Input component have to match type="text" snapshot 1`] = `
"size": "'default'",
"skeleton": "skeleton",
"status": "status",
- "status_animation": "status_animation",
+ "status_no_animation": "status_no_animation",
"status_state": "status_state",
"stretch": "stretch",
"submit_button_icon": "submit_button_icon",
@@ -687,7 +735,7 @@ exports[`Input component have to match type="text" snapshot 1`] = `
size={null}
skeleton={null}
status={null}
- status_animation={null}
+ status_no_animation={null}
status_state="error"
stretch={null}
submit_button_icon="loupe"
@@ -715,6 +763,30 @@ exports[`Input component have to match type="text" snapshot 1`] = `
className="dnb-alignment-helper"
/>
+
@@ -1007,7 +1079,20 @@ exports[`Input scss have to match snapshot 1`] = `
--form-status-radius: 0.25rem; }
.dnb-form-status {
- display: flex; }
+ display: flex;
+ opacity: 1;
+ transition: height 400ms cubic-bezier(0.42, 0, 0, 1), opacity 400ms cubic-bezier(0.42, 0, 0, 1), margin 400ms cubic-bezier(0.42, 0, 0, 1), padding 400ms cubic-bezier(0.42, 0, 0, 1); }
+ .dnb-form-status--hidden {
+ will-change: height, opacity, margin, padding;
+ width: 0;
+ height: 0;
+ opacity: 0; }
+ .dnb-form-status--is-animating {
+ overflow: hidden;
+ width: auto; }
+ .dnb-form-status--disappear, .dnb-form-status--hidden {
+ margin: 0 !important;
+ padding: 0 !important; }
.dnb-form-status__shell {
display: flex;
justify-content: flex-start;
@@ -1044,16 +1129,9 @@ exports[`Input scss have to match snapshot 1`] = `
max-width: 47rem; }
.dnb-form-status[hidden] {
display: none; }
- .dnb-form-status__animation--fade-in {
- overflow: hidden;
- max-height: 0;
- animation: form-status-fade-in 2s ease-out 400ms forwards; }
-
-@keyframes form-status-fade-in {
- from {
- max-height: 0; }
- to {
- max-height: calc(var(--input-height) * 8); } }
+ .dnb-form-status--no-animation,
+ .dnb-form-status html[data-visual-test] {
+ transition-duration: 1ms !important; }
@media screen and (-ms-high-contrast: none) {
.dnb-form-status__shell > .dnb-icon {
border-width: 1px; } }
@@ -1537,6 +1615,18 @@ legend.dnb-form-label {
/* IE needs this to stay centered */ }
.dnb-input__submit-button__button {
border-radius: 0 var(--input-border-radius) var(--input-border-radius) 0; }
+ .dnb-input > .dnb-form-label {
+ line-height: var(--line-height-basis); }
+ @media screen and (max-width: 40em) {
+ .dnb-input {
+ flex-wrap: wrap; }
+ .dnb-input > .dnb-form-label {
+ margin-bottom: 0.5rem;
+ margin-top: 0.5rem; } }
+ .dnb-input:not(.dnb-input--vertical)[class*='__status'] {
+ align-items: flex-start; }
+ .dnb-input:not(.dnb-input--vertical)[class*='__status'] > .dnb-form-label {
+ margin-top: 0.25rem; }
.dnb-input--small {
line-height: var(--input-height--small); }
.dnb-input--small .dnb-input__shell,
@@ -1680,18 +1770,6 @@ legend.dnb-form-label {
.dnb-input--icon-size-medium.dnb-input--icon-position-right.dnb-input--has-icon .dnb-input__input,
.dnb-input--icon-size-medium.dnb-input--icon-position-right.dnb-input--has-icon .dnb-input__placeholder {
padding-right: 3rem; }
- .dnb-input > .dnb-form-label {
- line-height: var(--line-height-basis); }
- @media screen and (max-width: 40em) {
- .dnb-input {
- flex-wrap: wrap; }
- .dnb-input > .dnb-form-label {
- margin-bottom: 0.5rem;
- margin-top: 0.5rem; } }
- .dnb-input[class*='__status'] {
- align-items: flex-start; }
- .dnb-input[class*='__status'] > .dnb-form-label {
- margin-top: 0.25rem; }
@media screen and (max-width: 40em) {
.dnb-responsive-component .dnb-input {
display: flex;
diff --git a/packages/dnb-eufemia/src/components/input/__tests__/__snapshots__/InputPassword.test.js.snap b/packages/dnb-eufemia/src/components/input/__tests__/__snapshots__/InputPassword.test.js.snap
index edf92a93fc3..2719dabbf64 100644
--- a/packages/dnb-eufemia/src/components/input/__tests__/__snapshots__/InputPassword.test.js.snap
+++ b/packages/dnb-eufemia/src/components/input/__tests__/__snapshots__/InputPassword.test.js.snap
@@ -53,7 +53,7 @@ exports[`InputPassword component have to match snapshot 1`] = `
size={null}
skeleton={null}
status={null}
- status_animation={null}
+ status_no_animation={null}
status_state="error"
stretch={null}
submit_button_icon="loupe"
@@ -130,7 +130,7 @@ exports[`InputPassword component have to match snapshot 1`] = `
size={null}
skeleton={null}
status={null}
- status_animation={null}
+ status_no_animation={null}
status_state="error"
stretch={null}
submit_button_icon="loupe"
@@ -170,6 +170,30 @@ exports[`InputPassword component have to match snapshot 1`] = `
className="dnb-alignment-helper"
/>
+
@@ -256,7 +280,7 @@ exports[`InputPassword component have to match snapshot 1`] = `
size={null}
skeleton={null}
status={null}
- status_animation={null}
+ status_no_animation={null}
status_state="error"
stretch={null}
text={null}
@@ -306,7 +330,7 @@ exports[`InputPassword component have to match snapshot 1`] = `
size={null}
skeleton={false}
status={null}
- status_animation={null}
+ status_no_animation={null}
status_state="error"
stretch={null}
text={null}
@@ -374,6 +398,30 @@ exports[`InputPassword component have to match snapshot 1`] = `
+
diff --git a/packages/dnb-eufemia/src/components/input/style/_input.scss b/packages/dnb-eufemia/src/components/input/style/_input.scss
index d918d88f6b7..0356214b20f 100644
--- a/packages/dnb-eufemia/src/components/input/style/_input.scss
+++ b/packages/dnb-eufemia/src/components/input/style/_input.scss
@@ -180,6 +180,20 @@
}
}
+ > .dnb-form-label {
+ line-height: var(--line-height-basis);
+ }
+ @include formLabelWrap();
+
+ &:not(&--vertical)[class*='__status'] {
+ align-items: flex-start;
+
+ & > .dnb-form-label {
+ // vertical align the current font
+ margin-top: 0.25rem;
+ }
+ }
+
&--small {
line-height: var(--input-height--small);
.dnb-input__shell,
@@ -406,20 +420,6 @@
padding-right: 3rem;
}
- > .dnb-form-label {
- line-height: var(--line-height-basis);
- }
- @include formLabelWrap();
-
- &[class*='__status'] {
- align-items: flex-start;
-
- & > .dnb-form-label {
- // vertical align the current font
- margin-top: 0.25rem;
- }
- }
-
.dnb-responsive-component & {
@media screen and (max-width: 40em) {
display: flex;
diff --git a/packages/dnb-eufemia/src/components/modal/__tests__/__snapshots__/Modal.test.js.snap b/packages/dnb-eufemia/src/components/modal/__tests__/__snapshots__/Modal.test.js.snap
index 639ff98aedf..a15ef616bb7 100644
--- a/packages/dnb-eufemia/src/components/modal/__tests__/__snapshots__/Modal.test.js.snap
+++ b/packages/dnb-eufemia/src/components/modal/__tests__/__snapshots__/Modal.test.js.snap
@@ -232,7 +232,7 @@ exports[`Modal component have to match snapshot 1`] = `
size={null}
skeleton={null}
status={null}
- status_animation={null}
+ status_no_animation={null}
status_state="error"
stretch={null}
text={null}
@@ -318,7 +318,7 @@ exports[`Modal component have to match snapshot 1`] = `
size={null}
skeleton={false}
status={null}
- status_animation={null}
+ status_no_animation={null}
status_state="error"
stretch={null}
text={null}
@@ -378,6 +378,30 @@ exports[`Modal component have to match snapshot 1`] = `
+
+
@@ -1300,7 +1348,20 @@ exports[`Modal scss have to match snapshot 1`] = `
--form-status-radius: 0.25rem; }
.dnb-form-status {
- display: flex; }
+ display: flex;
+ opacity: 1;
+ transition: height 400ms cubic-bezier(0.42, 0, 0, 1), opacity 400ms cubic-bezier(0.42, 0, 0, 1), margin 400ms cubic-bezier(0.42, 0, 0, 1), padding 400ms cubic-bezier(0.42, 0, 0, 1); }
+ .dnb-form-status--hidden {
+ will-change: height, opacity, margin, padding;
+ width: 0;
+ height: 0;
+ opacity: 0; }
+ .dnb-form-status--is-animating {
+ overflow: hidden;
+ width: auto; }
+ .dnb-form-status--disappear, .dnb-form-status--hidden {
+ margin: 0 !important;
+ padding: 0 !important; }
.dnb-form-status__shell {
display: flex;
justify-content: flex-start;
@@ -1337,16 +1398,9 @@ exports[`Modal scss have to match snapshot 1`] = `
max-width: 47rem; }
.dnb-form-status[hidden] {
display: none; }
- .dnb-form-status__animation--fade-in {
- overflow: hidden;
- max-height: 0;
- animation: form-status-fade-in 2s ease-out 400ms forwards; }
-
-@keyframes form-status-fade-in {
- from {
- max-height: 0; }
- to {
- max-height: calc(var(--input-height) * 8); } }
+ .dnb-form-status--no-animation,
+ .dnb-form-status html[data-visual-test] {
+ transition-duration: 1ms !important; }
@media screen and (-ms-high-contrast: none) {
.dnb-form-status__shell > .dnb-icon {
border-width: 1px; } }
diff --git a/packages/dnb-eufemia/src/components/pagination/__tests__/__snapshots__/Pagination.test.js.snap b/packages/dnb-eufemia/src/components/pagination/__tests__/__snapshots__/Pagination.test.js.snap
index a3f41997d7b..a387c84d34c 100644
--- a/packages/dnb-eufemia/src/components/pagination/__tests__/__snapshots__/Pagination.test.js.snap
+++ b/packages/dnb-eufemia/src/components/pagination/__tests__/__snapshots__/Pagination.test.js.snap
@@ -609,7 +609,7 @@ exports[`Pagination bar component have to match snapshot 1`] = `
size="small"
skeleton={null}
status={null}
- status_animation={null}
+ status_no_animation={null}
status_state="error"
stretch={null}
text={null}
@@ -651,7 +651,7 @@ exports[`Pagination bar component have to match snapshot 1`] = `
size="small"
skeleton={false}
status={null}
- status_animation={null}
+ status_no_animation={null}
status_state="error"
stretch={null}
text={null}
@@ -712,6 +712,30 @@ exports[`Pagination bar component have to match snapshot 1`] = `
+
+
@@ -1182,7 +1230,20 @@ exports[`Pagination scss have to match snapshot 1`] = `
--form-status-radius: 0.25rem; }
.dnb-form-status {
- display: flex; }
+ display: flex;
+ opacity: 1;
+ transition: height 400ms cubic-bezier(0.42, 0, 0, 1), opacity 400ms cubic-bezier(0.42, 0, 0, 1), margin 400ms cubic-bezier(0.42, 0, 0, 1), padding 400ms cubic-bezier(0.42, 0, 0, 1); }
+ .dnb-form-status--hidden {
+ will-change: height, opacity, margin, padding;
+ width: 0;
+ height: 0;
+ opacity: 0; }
+ .dnb-form-status--is-animating {
+ overflow: hidden;
+ width: auto; }
+ .dnb-form-status--disappear, .dnb-form-status--hidden {
+ margin: 0 !important;
+ padding: 0 !important; }
.dnb-form-status__shell {
display: flex;
justify-content: flex-start;
@@ -1219,16 +1280,9 @@ exports[`Pagination scss have to match snapshot 1`] = `
max-width: 47rem; }
.dnb-form-status[hidden] {
display: none; }
- .dnb-form-status__animation--fade-in {
- overflow: hidden;
- max-height: 0;
- animation: form-status-fade-in 2s ease-out 400ms forwards; }
-
-@keyframes form-status-fade-in {
- from {
- max-height: 0; }
- to {
- max-height: calc(var(--input-height) * 8); } }
+ .dnb-form-status--no-animation,
+ .dnb-form-status html[data-visual-test] {
+ transition-duration: 1ms !important; }
@media screen and (-ms-high-contrast: none) {
.dnb-form-status__shell > .dnb-icon {
border-width: 1px; } }
diff --git a/packages/dnb-eufemia/src/components/radio/Radio.js b/packages/dnb-eufemia/src/components/radio/Radio.js
index 81a56475e37..3902fee6053 100644
--- a/packages/dnb-eufemia/src/components/radio/Radio.js
+++ b/packages/dnb-eufemia/src/components/radio/Radio.js
@@ -62,7 +62,10 @@ export default class Radio extends React.PureComponent {
PropTypes.node,
]),
status_state: PropTypes.string,
- status_animation: PropTypes.string,
+ status_no_animation: PropTypes.oneOfType([
+ PropTypes.string,
+ PropTypes.bool,
+ ]),
global_status_id: PropTypes.string,
suffix: PropTypes.oneOfType([
PropTypes.string,
@@ -98,7 +101,7 @@ export default class Radio extends React.PureComponent {
group: null,
status: null,
status_state: 'error',
- status_animation: null,
+ status_no_animation: null,
global_status_id: null,
suffix: null,
value: '',
@@ -274,7 +277,7 @@ export default class Radio extends React.PureComponent {
const {
status,
status_state,
- status_animation,
+ status_no_animation,
global_status_id,
suffix,
element,
@@ -380,19 +383,18 @@ export default class Radio extends React.PureComponent {
- {showStatus && (
-
- )}
+
diff --git a/packages/dnb-eufemia/src/components/radio/RadioGroup.js b/packages/dnb-eufemia/src/components/radio/RadioGroup.js
index 905b9ea2ee4..0ac33e47ce4 100644
--- a/packages/dnb-eufemia/src/components/radio/RadioGroup.js
+++ b/packages/dnb-eufemia/src/components/radio/RadioGroup.js
@@ -56,7 +56,10 @@ export default class RadioGroup extends React.PureComponent {
PropTypes.node,
]),
status_state: PropTypes.string,
- status_animation: PropTypes.string,
+ status_no_animation: PropTypes.oneOfType([
+ PropTypes.string,
+ PropTypes.bool,
+ ]),
global_status_id: PropTypes.string,
suffix: PropTypes.oneOfType([
PropTypes.string,
@@ -97,7 +100,7 @@ export default class RadioGroup extends React.PureComponent {
size: null,
status: null,
status_state: 'error',
- status_animation: null,
+ status_no_animation: null,
global_status_id: null,
suffix: null,
vertical: null,
@@ -169,7 +172,7 @@ export default class RadioGroup extends React.PureComponent {
const {
status,
status_state,
- status_animation,
+ status_no_animation,
global_status_id,
suffix,
label,
@@ -275,19 +278,18 @@ export default class RadioGroup extends React.PureComponent {
)}
- {showStatus && (
-
- )}
+
diff --git a/packages/dnb-eufemia/src/components/radio/__tests__/__snapshots__/Radio.test.js.snap b/packages/dnb-eufemia/src/components/radio/__tests__/__snapshots__/Radio.test.js.snap
index b98af89c789..011745e4bf3 100644
--- a/packages/dnb-eufemia/src/components/radio/__tests__/__snapshots__/Radio.test.js.snap
+++ b/packages/dnb-eufemia/src/components/radio/__tests__/__snapshots__/Radio.test.js.snap
@@ -23,7 +23,7 @@ exports[`Radio component have to match snapshot 1`] = `
size={null}
skeleton="skeleton"
status={null}
- status_animation="status_animation"
+ status_no_animation="status_no_animation"
status_state="status_state"
suffix="suffix"
value="value"
@@ -69,6 +69,30 @@ exports[`Radio component have to match snapshot 1`] = `
className="dnb-alignment-helper"
/>
+
@@ -130,7 +154,7 @@ exports[`Radio component have to match snapshot 1`] = `
"size": null,
"skeleton": "skeleton",
"status": null,
- "status_animation": "status_animation",
+ "status_no_animation": "status_no_animation",
"status_state": "status_state",
"suffix": "suffix",
"value": "value",
@@ -200,7 +224,7 @@ exports[`Radio group component have to match group snapshot 1`] = `
size={null}
skeleton={null}
status={null}
- status_animation={null}
+ status_no_animation={null}
status_state="error"
suffix={null}
title={null}
@@ -315,7 +339,7 @@ exports[`Radio group component have to match group snapshot 1`] = `
size={null}
skeleton={null}
status={null}
- status_animation={null}
+ status_no_animation={null}
status_state="error"
suffix={null}
value="first"
@@ -337,6 +361,30 @@ exports[`Radio group component have to match group snapshot 1`] = `
className="dnb-alignment-helper"
/>
+
@@ -419,7 +467,7 @@ exports[`Radio group component have to match group snapshot 1`] = `
size={null}
skeleton={null}
status={null}
- status_animation={null}
+ status_no_animation={null}
status_state="error"
suffix={null}
value="second"
@@ -441,6 +489,30 @@ exports[`Radio group component have to match group snapshot 1`] = `
className="dnb-alignment-helper"
/>
+
@@ -502,6 +574,30 @@ exports[`Radio group component have to match group snapshot 1`] = `
+
@@ -765,7 +861,20 @@ legend.dnb-form-label {
--form-status-radius: 0.25rem; }
.dnb-form-status {
- display: flex; }
+ display: flex;
+ opacity: 1;
+ transition: height 400ms cubic-bezier(0.42, 0, 0, 1), opacity 400ms cubic-bezier(0.42, 0, 0, 1), margin 400ms cubic-bezier(0.42, 0, 0, 1), padding 400ms cubic-bezier(0.42, 0, 0, 1); }
+ .dnb-form-status--hidden {
+ will-change: height, opacity, margin, padding;
+ width: 0;
+ height: 0;
+ opacity: 0; }
+ .dnb-form-status--is-animating {
+ overflow: hidden;
+ width: auto; }
+ .dnb-form-status--disappear, .dnb-form-status--hidden {
+ margin: 0 !important;
+ padding: 0 !important; }
.dnb-form-status__shell {
display: flex;
justify-content: flex-start;
@@ -802,16 +911,9 @@ legend.dnb-form-label {
max-width: 47rem; }
.dnb-form-status[hidden] {
display: none; }
- .dnb-form-status__animation--fade-in {
- overflow: hidden;
- max-height: 0;
- animation: form-status-fade-in 2s ease-out 400ms forwards; }
-
-@keyframes form-status-fade-in {
- from {
- max-height: 0; }
- to {
- max-height: calc(var(--input-height) * 8); } }
+ .dnb-form-status--no-animation,
+ .dnb-form-status html[data-visual-test] {
+ transition-duration: 1ms !important; }
@media screen and (-ms-high-contrast: none) {
.dnb-form-status__shell > .dnb-icon {
border-width: 1px; } }
diff --git a/packages/dnb-eufemia/src/components/skeleton/__tests__/__snapshots__/Skeleton.test.js.snap b/packages/dnb-eufemia/src/components/skeleton/__tests__/__snapshots__/Skeleton.test.js.snap
index 84fd29d85b6..001d4002e27 100644
--- a/packages/dnb-eufemia/src/components/skeleton/__tests__/__snapshots__/Skeleton.test.js.snap
+++ b/packages/dnb-eufemia/src/components/skeleton/__tests__/__snapshots__/Skeleton.test.js.snap
@@ -114,7 +114,7 @@ exports[`Skeleton component have to match snapshot 1`] = `
size={null}
skeleton={null}
status={null}
- status_animation={null}
+ status_no_animation={null}
status_state="error"
stretch={null}
submit_button_icon="loupe"
@@ -165,6 +165,30 @@ exports[`Skeleton component have to match snapshot 1`] = `
className="dnb-alignment-helper"
/>
+
diff --git a/packages/dnb-eufemia/src/components/slider/Slider.js b/packages/dnb-eufemia/src/components/slider/Slider.js
index 0b04ef6bcca..99c4f125dc3 100644
--- a/packages/dnb-eufemia/src/components/slider/Slider.js
+++ b/packages/dnb-eufemia/src/components/slider/Slider.js
@@ -59,7 +59,10 @@ export default class Slider extends React.PureComponent {
PropTypes.node,
]),
status_state: PropTypes.string,
- status_animation: PropTypes.string,
+ status_no_animation: PropTypes.oneOfType([
+ PropTypes.string,
+ PropTypes.bool,
+ ]),
global_status_id: PropTypes.string,
suffix: PropTypes.oneOfType([
PropTypes.string,
@@ -108,7 +111,7 @@ export default class Slider extends React.PureComponent {
label_sr_only: null,
status: null,
status_state: 'error',
- status_animation: null,
+ status_no_animation: null,
global_status_id: null,
suffix: null,
thump_title: null,
@@ -534,7 +537,7 @@ export default class Slider extends React.PureComponent {
label_sr_only,
status,
status_state,
- status_animation,
+ status_no_animation,
global_status_id,
stretch,
suffix,
@@ -696,18 +699,17 @@ export default class Slider extends React.PureComponent {
- {showStatus && (
-
- )}
+
{showButtons && (reverse ? addButton : subtractButton)}
diff --git a/packages/dnb-eufemia/src/components/slider/__tests__/__snapshots__/Slider.test.js.snap b/packages/dnb-eufemia/src/components/slider/__tests__/__snapshots__/Slider.test.js.snap
index fe4fe6edb8b..884bcc8bec7 100644
--- a/packages/dnb-eufemia/src/components/slider/__tests__/__snapshots__/Slider.test.js.snap
+++ b/packages/dnb-eufemia/src/components/slider/__tests__/__snapshots__/Slider.test.js.snap
@@ -28,7 +28,7 @@ exports[`Slider component have to match snapshot 1`] = `
reverse="reverse"
skeleton="skeleton"
status={null}
- status_animation="status_animation"
+ status_no_animation="status_no_animation"
status_state="status_state"
step={10}
stretch="stretch"
@@ -75,6 +75,30 @@ exports[`Slider component have to match snapshot 1`] = `
className="dnb-alignment-helper"
/>
+
@@ -101,7 +125,7 @@ exports[`Slider component have to match snapshot 1`] = `
size="small"
skeleton="skeleton"
status={null}
- status_animation={null}
+ status_no_animation={null}
status_state="error"
stretch={null}
text={null}
@@ -144,7 +168,7 @@ exports[`Slider component have to match snapshot 1`] = `
size="small"
skeleton={false}
status={null}
- status_animation={null}
+ status_no_animation={null}
status_state="error"
stretch={null}
text={null}
@@ -202,6 +226,30 @@ exports[`Slider component have to match snapshot 1`] = `
+
+
+
.dnb-icon {
border-width: 1px; } }
diff --git a/packages/dnb-eufemia/src/components/step-indicator/__tests__/__snapshots__/StepIndicator.test.js.snap b/packages/dnb-eufemia/src/components/step-indicator/__tests__/__snapshots__/StepIndicator.test.js.snap
index 085950220c1..75b34c5be39 100644
--- a/packages/dnb-eufemia/src/components/step-indicator/__tests__/__snapshots__/StepIndicator.test.js.snap
+++ b/packages/dnb-eufemia/src/components/step-indicator/__tests__/__snapshots__/StepIndicator.test.js.snap
@@ -204,7 +204,7 @@ Array [
size={null}
skeleton={null}
status={null}
- status_animation={null}
+ status_no_animation={null}
status_state="error"
stretch={true}
text={null}
@@ -316,7 +316,7 @@ Array [
size={null}
skeleton={false}
status={null}
- status_animation={null}
+ status_no_animation={null}
status_state="error"
stretch={true}
text={null}
@@ -409,6 +409,30 @@ Array [
+
+
+
+
+
+
+
+
+
+
+
+
- {showStatus && (
-
- )}
+
{(label_position === 'right' || !label_position) &&
diff --git a/packages/dnb-eufemia/src/components/switch/__tests__/__snapshots__/Switch.test.js.snap b/packages/dnb-eufemia/src/components/switch/__tests__/__snapshots__/Switch.test.js.snap
index 2fe4d95f5c1..cb994f67891 100644
--- a/packages/dnb-eufemia/src/components/switch/__tests__/__snapshots__/Switch.test.js.snap
+++ b/packages/dnb-eufemia/src/components/switch/__tests__/__snapshots__/Switch.test.js.snap
@@ -22,7 +22,7 @@ exports[`Switch component have to match snapshot 1`] = `
size="default"
skeleton="skeleton"
status={null}
- status_animation="status_animation"
+ status_no_animation="status_no_animation"
status_state="status_state"
suffix="suffix"
title="title"
@@ -69,6 +69,30 @@ exports[`Switch component have to match snapshot 1`] = `
className="dnb-alignment-helper"
/>
+
@@ -135,7 +159,7 @@ exports[`Switch component have to match snapshot 1`] = `
"size": "default",
"skeleton": "skeleton",
"status": null,
- "status_animation": "status_animation",
+ "status_no_animation": "status_no_animation",
"status_state": "status_state",
"suffix": "suffix",
"title": "title",
@@ -481,7 +505,20 @@ legend.dnb-form-label {
--form-status-radius: 0.25rem; }
.dnb-form-status {
- display: flex; }
+ display: flex;
+ opacity: 1;
+ transition: height 400ms cubic-bezier(0.42, 0, 0, 1), opacity 400ms cubic-bezier(0.42, 0, 0, 1), margin 400ms cubic-bezier(0.42, 0, 0, 1), padding 400ms cubic-bezier(0.42, 0, 0, 1); }
+ .dnb-form-status--hidden {
+ will-change: height, opacity, margin, padding;
+ width: 0;
+ height: 0;
+ opacity: 0; }
+ .dnb-form-status--is-animating {
+ overflow: hidden;
+ width: auto; }
+ .dnb-form-status--disappear, .dnb-form-status--hidden {
+ margin: 0 !important;
+ padding: 0 !important; }
.dnb-form-status__shell {
display: flex;
justify-content: flex-start;
@@ -518,16 +555,9 @@ legend.dnb-form-label {
max-width: 47rem; }
.dnb-form-status[hidden] {
display: none; }
- .dnb-form-status__animation--fade-in {
- overflow: hidden;
- max-height: 0;
- animation: form-status-fade-in 2s ease-out 400ms forwards; }
-
-@keyframes form-status-fade-in {
- from {
- max-height: 0; }
- to {
- max-height: calc(var(--input-height) * 8); } }
+ .dnb-form-status--no-animation,
+ .dnb-form-status html[data-visual-test] {
+ transition-duration: 1ms !important; }
@media screen and (-ms-high-contrast: none) {
.dnb-form-status__shell > .dnb-icon {
border-width: 1px; } }
diff --git a/packages/dnb-eufemia/src/components/tabs/__tests__/__snapshots__/Tabs.test.js.snap b/packages/dnb-eufemia/src/components/tabs/__tests__/__snapshots__/Tabs.test.js.snap
index 9cecdbe7d93..b43756391bd 100644
--- a/packages/dnb-eufemia/src/components/tabs/__tests__/__snapshots__/Tabs.test.js.snap
+++ b/packages/dnb-eufemia/src/components/tabs/__tests__/__snapshots__/Tabs.test.js.snap
@@ -80,7 +80,7 @@ exports[`A single Tab component has to work with "Tabs.Content" from outside 1`]
size="medium"
skeleton={null}
status={null}
- status_animation={null}
+ status_no_animation={null}
status_state="error"
stretch={null}
tabIndex="-1"
@@ -127,7 +127,7 @@ exports[`A single Tab component has to work with "Tabs.Content" from outside 1`]
size="medium"
skeleton={false}
status={null}
- status_animation={null}
+ status_no_animation={null}
status_state="error"
stretch={null}
tabIndex="-1"
@@ -193,6 +193,30 @@ exports[`A single Tab component has to work with "Tabs.Content" from outside 1`]
+
@@ -331,7 +355,7 @@ exports[`A single Tab component has to work with "Tabs.Content" from outside 1`]
size="medium"
skeleton={null}
status={null}
- status_animation={null}
+ status_no_animation={null}
status_state="error"
stretch={null}
tabIndex="-1"
@@ -378,7 +402,7 @@ exports[`A single Tab component has to work with "Tabs.Content" from outside 1`]
size="medium"
skeleton={false}
status={null}
- status_animation={null}
+ status_no_animation={null}
status_state="error"
stretch={null}
tabIndex="-1"
@@ -444,6 +468,30 @@ exports[`A single Tab component has to work with "Tabs.Content" from outside 1`]
+
@@ -611,7 +659,7 @@ exports[`Tabs component have to match snapshot 1`] = `
size="medium"
skeleton={null}
status={null}
- status_animation={null}
+ status_no_animation={null}
status_state="error"
stretch={null}
tabIndex="-1"
@@ -658,7 +706,7 @@ exports[`Tabs component have to match snapshot 1`] = `
size="medium"
skeleton={false}
status={null}
- status_animation={null}
+ status_no_animation={null}
status_state="error"
stretch={null}
tabIndex="-1"
@@ -724,6 +772,30 @@ exports[`Tabs component have to match snapshot 1`] = `
+
@@ -862,7 +934,7 @@ exports[`Tabs component have to match snapshot 1`] = `
size="medium"
skeleton={null}
status={null}
- status_animation={null}
+ status_no_animation={null}
status_state="error"
stretch={null}
tabIndex="-1"
@@ -909,7 +981,7 @@ exports[`Tabs component have to match snapshot 1`] = `
size="medium"
skeleton={false}
status={null}
- status_animation={null}
+ status_no_animation={null}
status_state="error"
stretch={null}
tabIndex="-1"
@@ -975,6 +1047,30 @@ exports[`Tabs component have to match snapshot 1`] = `
+
diff --git a/packages/dnb-eufemia/src/components/textarea/Textarea.js b/packages/dnb-eufemia/src/components/textarea/Textarea.js
index 812211e13e7..4438d5d6344 100644
--- a/packages/dnb-eufemia/src/components/textarea/Textarea.js
+++ b/packages/dnb-eufemia/src/components/textarea/Textarea.js
@@ -58,7 +58,10 @@ export default class Textarea extends React.PureComponent {
]),
textarea_state: PropTypes.string,
status_state: PropTypes.string,
- status_animation: PropTypes.string,
+ status_no_animation: PropTypes.oneOfType([
+ PropTypes.string,
+ PropTypes.bool,
+ ]),
global_status_id: PropTypes.string,
suffix: PropTypes.oneOfType([
PropTypes.string,
@@ -114,7 +117,7 @@ export default class Textarea extends React.PureComponent {
status: null,
textarea_state: null,
status_state: 'error',
- status_animation: null,
+ status_no_animation: null,
global_status_id: null,
suffix: null,
placeholder: null,
@@ -352,7 +355,7 @@ export default class Textarea extends React.PureComponent {
label_sr_only,
status,
status_state,
- status_animation,
+ status_no_animation,
global_status_id,
suffix,
disabled,
@@ -492,18 +495,17 @@ export default class Textarea extends React.PureComponent {
- {showStatus && (
-
- )}
+
diff --git a/packages/dnb-eufemia/src/components/textarea/__tests__/__snapshots__/Textarea.test.js.snap b/packages/dnb-eufemia/src/components/textarea/__tests__/__snapshots__/Textarea.test.js.snap
index f611b27e022..b536cfd4f18 100644
--- a/packages/dnb-eufemia/src/components/textarea/__tests__/__snapshots__/Textarea.test.js.snap
+++ b/packages/dnb-eufemia/src/components/textarea/__tests__/__snapshots__/Textarea.test.js.snap
@@ -32,7 +32,7 @@ exports[`Textarea component have to match snapshot 1`] = `
"rows": 1,
"skeleton": "skeleton",
"status": "status",
- "status_animation": "status_animation",
+ "status_no_animation": "status_no_animation",
"status_state": "status_state",
"stretch": "stretch",
"suffix": "suffix",
@@ -69,7 +69,7 @@ exports[`Textarea component have to match snapshot 1`] = `
rows={null}
skeleton={null}
status={null}
- status_animation={null}
+ status_no_animation={null}
status_state="error"
stretch={null}
suffix={null}
@@ -93,6 +93,30 @@ exports[`Textarea component have to match snapshot 1`] = `
className="dnb-alignment-helper"
/>
+
@@ -366,7 +390,20 @@ legend.dnb-form-label {
--form-status-radius: 0.25rem; }
.dnb-form-status {
- display: flex; }
+ display: flex;
+ opacity: 1;
+ transition: height 400ms cubic-bezier(0.42, 0, 0, 1), opacity 400ms cubic-bezier(0.42, 0, 0, 1), margin 400ms cubic-bezier(0.42, 0, 0, 1), padding 400ms cubic-bezier(0.42, 0, 0, 1); }
+ .dnb-form-status--hidden {
+ will-change: height, opacity, margin, padding;
+ width: 0;
+ height: 0;
+ opacity: 0; }
+ .dnb-form-status--is-animating {
+ overflow: hidden;
+ width: auto; }
+ .dnb-form-status--disappear, .dnb-form-status--hidden {
+ margin: 0 !important;
+ padding: 0 !important; }
.dnb-form-status__shell {
display: flex;
justify-content: flex-start;
@@ -403,16 +440,9 @@ legend.dnb-form-label {
max-width: 47rem; }
.dnb-form-status[hidden] {
display: none; }
- .dnb-form-status__animation--fade-in {
- overflow: hidden;
- max-height: 0;
- animation: form-status-fade-in 2s ease-out 400ms forwards; }
-
-@keyframes form-status-fade-in {
- from {
- max-height: 0; }
- to {
- max-height: calc(var(--input-height) * 8); } }
+ .dnb-form-status--no-animation,
+ .dnb-form-status html[data-visual-test] {
+ transition-duration: 1ms !important; }
@media screen and (-ms-high-contrast: none) {
.dnb-form-status__shell > .dnb-icon {
border-width: 1px; } }
@@ -613,9 +643,9 @@ legend.dnb-form-label {
display: flex;
flex-direction: column;
align-items: flex-start; }
- .dnb-textarea[class*='__status'] {
+ .dnb-textarea:not(.dnb-textarea--vertical)[class*='__status'] {
align-items: flex-start; }
- .dnb-textarea[class*='__status'] > .dnb-form-label {
+ .dnb-textarea:not(.dnb-textarea--vertical)[class*='__status'] > .dnb-form-label {
margin-top: 0.25rem; }
@media screen and (max-width: 40em) {
.dnb-textarea {
diff --git a/packages/dnb-eufemia/src/components/textarea/style/_textarea.scss b/packages/dnb-eufemia/src/components/textarea/style/_textarea.scss
index 85477fe47ac..94293d92456 100644
--- a/packages/dnb-eufemia/src/components/textarea/style/_textarea.scss
+++ b/packages/dnb-eufemia/src/components/textarea/style/_textarea.scss
@@ -118,7 +118,7 @@
align-items: flex-start;
}
- &[class*='__status'] {
+ &:not(&--vertical)[class*='__status'] {
align-items: flex-start;
> .dnb-form-label {
// vertical align the current font
diff --git a/packages/dnb-eufemia/src/components/toggle-button/ToggleButton.js b/packages/dnb-eufemia/src/components/toggle-button/ToggleButton.js
index 9beede7f490..a57b50d1332 100644
--- a/packages/dnb-eufemia/src/components/toggle-button/ToggleButton.js
+++ b/packages/dnb-eufemia/src/components/toggle-button/ToggleButton.js
@@ -66,7 +66,10 @@ export default class ToggleButton extends React.PureComponent {
PropTypes.node,
]),
status_state: PropTypes.string,
- status_animation: PropTypes.string,
+ status_no_animation: PropTypes.oneOfType([
+ PropTypes.string,
+ PropTypes.bool,
+ ]),
global_status_id: PropTypes.string,
suffix: PropTypes.oneOfType([
PropTypes.string,
@@ -116,7 +119,7 @@ export default class ToggleButton extends React.PureComponent {
// group: null,
status: null,
status_state: 'error',
- status_animation: null,
+ status_no_animation: null,
global_status_id: null,
suffix: null,
value: '',
@@ -291,7 +294,7 @@ export default class ToggleButton extends React.PureComponent {
const {
status,
status_state,
- status_animation,
+ status_no_animation,
global_status_id,
suffix,
label,
@@ -438,18 +441,17 @@ export default class ToggleButton extends React.PureComponent {
/>
)}
- {showStatus && (
-
- )}
+
diff --git a/packages/dnb-eufemia/src/components/toggle-button/ToggleButtonGroup.js b/packages/dnb-eufemia/src/components/toggle-button/ToggleButtonGroup.js
index 2b29374cc87..ca63fda40ca 100644
--- a/packages/dnb-eufemia/src/components/toggle-button/ToggleButtonGroup.js
+++ b/packages/dnb-eufemia/src/components/toggle-button/ToggleButtonGroup.js
@@ -55,7 +55,10 @@ export default class ToggleButtonGroup extends React.PureComponent {
PropTypes.node,
]),
status_state: PropTypes.string,
- status_animation: PropTypes.string,
+ status_no_animation: PropTypes.oneOfType([
+ PropTypes.string,
+ PropTypes.bool,
+ ]),
global_status_id: PropTypes.string,
suffix: PropTypes.oneOfType([
PropTypes.string,
@@ -103,7 +106,7 @@ export default class ToggleButtonGroup extends React.PureComponent {
name: null,
status: null,
status_state: 'error',
- status_animation: null,
+ status_no_animation: null,
global_status_id: null,
suffix: null,
vertical: null,
@@ -205,7 +208,7 @@ export default class ToggleButtonGroup extends React.PureComponent {
const {
status,
status_state,
- status_animation,
+ status_no_animation,
global_status_id,
suffix,
label_direction,
@@ -325,18 +328,17 @@ export default class ToggleButtonGroup extends React.PureComponent {
role="group"
{...params}
>
- {showStatus && (
-
- )}
+
{children}
diff --git a/packages/dnb-eufemia/src/components/toggle-button/__tests__/__snapshots__/ToggleButton.test.js.snap b/packages/dnb-eufemia/src/components/toggle-button/__tests__/__snapshots__/ToggleButton.test.js.snap
index 45816b777eb..10c7cd0330b 100644
--- a/packages/dnb-eufemia/src/components/toggle-button/__tests__/__snapshots__/ToggleButton.test.js.snap
+++ b/packages/dnb-eufemia/src/components/toggle-button/__tests__/__snapshots__/ToggleButton.test.js.snap
@@ -23,7 +23,7 @@ exports[`ToggleButton component have to match snapshot 1`] = `
readOnly={false}
skeleton="skeleton"
status={null}
- status_animation="status_animation"
+ status_no_animation="status_no_animation"
status_state="status_state"
suffix="suffix"
text="text"
@@ -61,6 +61,30 @@ exports[`ToggleButton component have to match snapshot 1`] = `
+
@@ -104,7 +128,7 @@ exports[`ToggleButton component have to match snapshot 1`] = `
size={null}
skeleton={null}
status={null}
- status_animation={null}
+ status_no_animation={null}
status_state="error"
suffix={null}
title={null}
@@ -131,7 +155,7 @@ exports[`ToggleButton component have to match snapshot 1`] = `
size={null}
skeleton="skeleton"
status={null}
- status_animation={null}
+ status_no_animation={null}
status_state="error"
stretch={null}
text="text"
@@ -187,7 +211,7 @@ exports[`ToggleButton component have to match snapshot 1`] = `
size={null}
skeleton={null}
status={null}
- status_animation={null}
+ status_no_animation={null}
status_state="error"
suffix={null}
title={null}
@@ -215,7 +239,7 @@ exports[`ToggleButton component have to match snapshot 1`] = `
size={null}
skeleton={false}
status={null}
- status_animation={null}
+ status_no_animation={null}
status_state="error"
stretch={null}
text="text"
@@ -251,7 +275,7 @@ exports[`ToggleButton component have to match snapshot 1`] = `
size={null}
skeleton={null}
status={null}
- status_animation={null}
+ status_no_animation={null}
status_state="error"
suffix={null}
title={null}
@@ -320,6 +344,30 @@ exports[`ToggleButton component have to match snapshot 1`] = `
+
@@ -354,6 +402,30 @@ exports[`ToggleButton component have to match snapshot 1`] = `
/>
+
+
@@ -544,7 +640,7 @@ exports[`ToggleButton group component have to match group snapshot 1`] = `
readOnly={false}
skeleton={null}
status={null}
- status_animation={null}
+ status_no_animation={null}
status_state="error"
suffix={null}
text="ToggleButton 1"
@@ -558,6 +654,30 @@ exports[`ToggleButton group component have to match group snapshot 1`] = `
+
@@ -601,7 +721,7 @@ exports[`ToggleButton group component have to match group snapshot 1`] = `
size={null}
skeleton={null}
status={null}
- status_animation={null}
+ status_no_animation={null}
status_state="error"
suffix={null}
title={null}
@@ -628,7 +748,7 @@ exports[`ToggleButton group component have to match group snapshot 1`] = `
size={null}
skeleton={null}
status={null}
- status_animation={null}
+ status_no_animation={null}
status_state="error"
stretch={null}
text="ToggleButton 1"
@@ -682,7 +802,7 @@ exports[`ToggleButton group component have to match group snapshot 1`] = `
size={null}
skeleton={null}
status={null}
- status_animation={null}
+ status_no_animation={null}
status_state="error"
suffix={null}
title={null}
@@ -710,7 +830,7 @@ exports[`ToggleButton group component have to match group snapshot 1`] = `
size={null}
skeleton={false}
status={null}
- status_animation={null}
+ status_no_animation={null}
status_state="error"
stretch={null}
text="ToggleButton 1"
@@ -747,7 +867,7 @@ exports[`ToggleButton group component have to match group snapshot 1`] = `
size={null}
skeleton={null}
status={null}
- status_animation={null}
+ status_no_animation={null}
status_state="error"
suffix={null}
title={null}
@@ -770,6 +890,30 @@ exports[`ToggleButton group component have to match group snapshot 1`] = `
className="dnb-alignment-helper"
/>
+
@@ -821,6 +965,30 @@ exports[`ToggleButton group component have to match group snapshot 1`] = `
+
@@ -848,7 +1016,7 @@ exports[`ToggleButton group component have to match group snapshot 1`] = `
readOnly={false}
skeleton={null}
status={null}
- status_animation={null}
+ status_no_animation={null}
status_state="error"
suffix={null}
text="ToggleButton 2"
@@ -862,6 +1030,30 @@ exports[`ToggleButton group component have to match group snapshot 1`] = `
+
@@ -905,7 +1097,7 @@ exports[`ToggleButton group component have to match group snapshot 1`] = `
size={null}
skeleton={null}
status={null}
- status_animation={null}
+ status_no_animation={null}
status_state="error"
suffix={null}
title={null}
@@ -932,7 +1124,7 @@ exports[`ToggleButton group component have to match group snapshot 1`] = `
size={null}
skeleton={null}
status={null}
- status_animation={null}
+ status_no_animation={null}
status_state="error"
stretch={null}
text="ToggleButton 2"
@@ -986,7 +1178,7 @@ exports[`ToggleButton group component have to match group snapshot 1`] = `
size={null}
skeleton={null}
status={null}
- status_animation={null}
+ status_no_animation={null}
status_state="error"
suffix={null}
title={null}
@@ -1014,7 +1206,7 @@ exports[`ToggleButton group component have to match group snapshot 1`] = `
size={null}
skeleton={false}
status={null}
- status_animation={null}
+ status_no_animation={null}
status_state="error"
stretch={null}
text="ToggleButton 2"
@@ -1051,7 +1243,7 @@ exports[`ToggleButton group component have to match group snapshot 1`] = `
size={null}
skeleton={null}
status={null}
- status_animation={null}
+ status_no_animation={null}
status_state="error"
suffix={null}
title={null}
@@ -1074,6 +1266,30 @@ exports[`ToggleButton group component have to match group snapshot 1`] = `
className="dnb-alignment-helper"
/>
+
@@ -1125,6 +1341,30 @@ exports[`ToggleButton group component have to match group snapshot 1`] = `
+
@@ -1631,7 +1871,20 @@ legend.dnb-form-label {
--form-status-radius: 0.25rem; }
.dnb-form-status {
- display: flex; }
+ display: flex;
+ opacity: 1;
+ transition: height 400ms cubic-bezier(0.42, 0, 0, 1), opacity 400ms cubic-bezier(0.42, 0, 0, 1), margin 400ms cubic-bezier(0.42, 0, 0, 1), padding 400ms cubic-bezier(0.42, 0, 0, 1); }
+ .dnb-form-status--hidden {
+ will-change: height, opacity, margin, padding;
+ width: 0;
+ height: 0;
+ opacity: 0; }
+ .dnb-form-status--is-animating {
+ overflow: hidden;
+ width: auto; }
+ .dnb-form-status--disappear, .dnb-form-status--hidden {
+ margin: 0 !important;
+ padding: 0 !important; }
.dnb-form-status__shell {
display: flex;
justify-content: flex-start;
@@ -1668,16 +1921,9 @@ legend.dnb-form-label {
max-width: 47rem; }
.dnb-form-status[hidden] {
display: none; }
- .dnb-form-status__animation--fade-in {
- overflow: hidden;
- max-height: 0;
- animation: form-status-fade-in 2s ease-out 400ms forwards; }
-
-@keyframes form-status-fade-in {
- from {
- max-height: 0; }
- to {
- max-height: calc(var(--input-height) * 8); } }
+ .dnb-form-status--no-animation,
+ .dnb-form-status html[data-visual-test] {
+ transition-duration: 1ms !important; }
@media screen and (-ms-high-contrast: none) {
.dnb-form-status__shell > .dnb-icon {
border-width: 1px; } }
diff --git a/packages/dnb-eufemia/src/shared/AnimateHeight.js b/packages/dnb-eufemia/src/shared/AnimateHeight.js
index c7406560826..c129d729f4d 100644
--- a/packages/dnb-eufemia/src/shared/AnimateHeight.js
+++ b/packages/dnb-eufemia/src/shared/AnimateHeight.js
@@ -76,11 +76,11 @@ export default class AnimateHeight {
}
}
remove() {
+ this.stop()
this._removeEndEvents()
this.isAnimating = false
this.onStartStack = null
this.onEndStack = null
- this.stop()
this.elem = null
this.state = 'init'
if (this.onResize && this.isInBrowser) {
@@ -146,7 +146,10 @@ export default class AnimateHeight {
return // stop here
}
- if (this.isInBrowser && window.requestAnimationFrame) {
+ if (
+ this.isInBrowser &&
+ typeof window.requestAnimationFrame === 'function'
+ ) {
this.stop()
this.isAnimating = true
@@ -180,7 +183,10 @@ export default class AnimateHeight {
}
}
stop() {
- if (this.isInBrowser && window.requestAnimationFrame) {
+ if (
+ this.isInBrowser &&
+ typeof window.requestAnimationFrame === 'function'
+ ) {
window.cancelAnimationFrame(this.reqId1)
window.cancelAnimationFrame(this.reqId2)
}