diff --git a/packages/dnb-design-system-portal/gatsby-browser.tsx b/packages/dnb-design-system-portal/gatsby-browser.tsx index 6e172992f73..c422cb4dfa4 100644 --- a/packages/dnb-design-system-portal/gatsby-browser.tsx +++ b/packages/dnb-design-system-portal/gatsby-browser.tsx @@ -5,6 +5,7 @@ import { applyPageFocus } from '@dnb/eufemia/src/shared/helpers' import { rootElement, pageElement } from './src/core/PortalProviders' +import { scrollToHash } from '@dnb/eufemia/src/components/Anchor' import ReactDOM from 'react-dom/client' if (typeof window !== 'undefined') { @@ -53,5 +54,8 @@ export const onRouteUpdate = ({ location, prevLocation }) => { // then we apply the page content focus for accessibility if (prevLocation && prevLocation?.pathname !== location?.pathname) { applyPageFocus('content') + if (location.hash) { + scrollToHash(location.hash) + } } } diff --git a/packages/dnb-design-system-portal/src/docs/uilib/components/anchor/info.mdx b/packages/dnb-design-system-portal/src/docs/uilib/components/anchor/info.mdx index 8fca0c6d4a5..06b36b0f6de 100644 --- a/packages/dnb-design-system-portal/src/docs/uilib/components/anchor/info.mdx +++ b/packages/dnb-design-system-portal/src/docs/uilib/components/anchor/info.mdx @@ -48,6 +48,20 @@ render( ) ``` +Or with the `scrollToHash` helper function: + +```jsx +import Anchor, { scrollToHash } from '@dnb/eufemia/components/Anchor' + +scrollToHash('/path#hash-id') + +render( + +
element to scroll to
+
, +) +``` + ## Blank target **NB:** If you only use a vanilla HTML anchor element including `target="_blank"` then you have to ensure you add a `title` attribute that includes `Opens a new Window` or as a part of the text: diff --git a/packages/dnb-design-system-portal/src/docs/uilib/extensions/forms/Form/FieldProps/Examples.tsx b/packages/dnb-design-system-portal/src/docs/uilib/extensions/forms/Form/FieldProps/Examples.tsx index 87fa534772b..52902b8713a 100644 --- a/packages/dnb-design-system-portal/src/docs/uilib/extensions/forms/Form/FieldProps/Examples.tsx +++ b/packages/dnb-design-system-portal/src/docs/uilib/extensions/forms/Form/FieldProps/Examples.tsx @@ -10,7 +10,8 @@ export const Required = () => { - + + diff --git a/packages/dnb-design-system-portal/src/docs/uilib/extensions/forms/Value/SummaryList/info.mdx b/packages/dnb-design-system-portal/src/docs/uilib/extensions/forms/Value/SummaryList/info.mdx index b079b06f66d..97f3fe3fbaf 100644 --- a/packages/dnb-design-system-portal/src/docs/uilib/extensions/forms/Value/SummaryList/info.mdx +++ b/packages/dnb-design-system-portal/src/docs/uilib/extensions/forms/Value/SummaryList/info.mdx @@ -4,13 +4,14 @@ showTabs: true ## Description -`Value.SummaryList` uses definition lists to semantically make content consumable for screen readers. +The `Value.SummaryList` component ensures that the wrapped `Value.*` components are rendered as definition lists, which helps maintain semantic correctness. ```jsx import { Value } from '@dnb/eufemia/extensions/forms' render( - - + + + , ) ``` diff --git a/packages/dnb-design-system-portal/src/docs/uilib/extensions/forms/about-forms.mdx b/packages/dnb-design-system-portal/src/docs/uilib/extensions/forms/about-forms.mdx index cd077f76f0d..2d4aa00cd9a 100644 --- a/packages/dnb-design-system-portal/src/docs/uilib/extensions/forms/about-forms.mdx +++ b/packages/dnb-design-system-portal/src/docs/uilib/extensions/forms/about-forms.mdx @@ -10,7 +10,6 @@ import QuickStart from './quick-start.mdx' - [Philosophy](#philosophy) - [Features](#features) -- [First steps](#first-steps) - [Quick start](#quick-start) - [Create your own component](#create-your-own-component) diff --git a/packages/dnb-design-system-portal/src/shared/tags/Anchor.tsx b/packages/dnb-design-system-portal/src/shared/tags/Anchor.tsx index 4aa099049e9..9dd19221ee0 100644 --- a/packages/dnb-design-system-portal/src/shared/tags/Anchor.tsx +++ b/packages/dnb-design-system-portal/src/shared/tags/Anchor.tsx @@ -3,7 +3,7 @@ * */ -import React from 'react' +import React, { useCallback } from 'react' import { Anchor as EufemiaAnchor } from '@dnb/eufemia/src' import { AnchorAllProps as Props, @@ -25,6 +25,16 @@ const PortalLink = React.forwardRef(function Link( { href, onClick = null, ...props }: AnchorProps, ref, ) { + const clickHandler = useCallback( + (event: React.MouseEvent) => { + startPageTransition() + if (onClick) { + onClick(event) + } + }, + [onClick], + ) + return ( ( onClick={clickHandler} /> ) - - function clickHandler(event: React.MouseEvent) { - startPageTransition() - if (onClick) { - onClick(event) - } - } }) export { PortalLink as Link } @@ -69,6 +72,25 @@ export default function Anchor({ const element = (isAbsoluteUrl ? 'a' : PortalLink) as Props['element'] + const clickHandler = useCallback( + (event: React.MouseEvent) => { + if (onClick) { + onClick(event) + } + try { + const element = scrollToHashHandler(event)?.element?.parentElement + + if (element) { + element.classList.add('focus') + setTimeout(() => element.classList.remove('focus'), 3000) + } + } catch (error) { + console.error(error) + } + }, + [onClick], + ) + return ( ) - - function clickHandler(event: React.MouseEvent) { - if (onClick) { - onClick(event) - } - try { - const element = scrollToHashHandler(event)?.element?.parentElement - - if (element) { - element.classList.add('focus') - setTimeout(() => element.classList.remove('focus'), 3000) - } - } catch (error) { - console.error(error) - } - } } diff --git a/packages/dnb-eufemia/src/components/accordion/Accordion.tsx b/packages/dnb-eufemia/src/components/accordion/Accordion.tsx index 5a7835c7c93..e8de29f580b 100644 --- a/packages/dnb-eufemia/src/components/accordion/Accordion.tsx +++ b/packages/dnb-eufemia/src/components/accordion/Accordion.tsx @@ -147,7 +147,6 @@ export type AccordionProps = Omit, 'ref'> & */ icon_size?: IconSize attributes?: AccordionAttributes - class?: string className?: string children?: React.ReactNode /** @@ -326,7 +325,6 @@ function Accordion({ const { variant, className, - class: _className, prerender, prevent_rerender, prevent_rerender_conditional, @@ -364,8 +362,7 @@ function Accordion({ variant && `dnb-accordion__variant--${variant}`, prerender && 'dnb-accordion--prerender', createSpacingClasses(extendedProps), - className, - _className + className ), } as HTMLProps diff --git a/packages/dnb-eufemia/src/components/accordion/AccordionGroup.tsx b/packages/dnb-eufemia/src/components/accordion/AccordionGroup.tsx index 648c9019058..8d637986c15 100644 --- a/packages/dnb-eufemia/src/components/accordion/AccordionGroup.tsx +++ b/packages/dnb-eufemia/src/components/accordion/AccordionGroup.tsx @@ -67,7 +67,6 @@ const AccordionGroup = (props: AccordionGroupProps) => { group, // eslint-disable-line onInit, // eslint-disable-line className, - class: _className, id: _id, // eslint-disable-line children, // eslint-disable-line @@ -79,8 +78,7 @@ const AccordionGroup = (props: AccordionGroupProps) => { 'dnb-accordion-group', isTrue(single_container) && 'dnb-accordion-group--single-container', createSpacingClasses(extendedProps), - className, - _className + className ) const params = { diff --git a/packages/dnb-eufemia/src/components/anchor/Anchor.tsx b/packages/dnb-eufemia/src/components/anchor/Anchor.tsx index f95ec190ede..a795dfb6e22 100644 --- a/packages/dnb-eufemia/src/components/anchor/Anchor.tsx +++ b/packages/dnb-eufemia/src/components/anchor/Anchor.tsx @@ -183,23 +183,32 @@ export function scrollToHashHandler( // Only continue, when we are sure we are on the same page, // because, the same ID may exists occasionally on the current page. if (isSamePath) { - const id = href.split(/#/g).reverse()[0] - const anchorElem = document.getElementById(id) - - if (anchorElem instanceof HTMLElement) { - try { - const scrollPadding = parseFloat( - window.getComputedStyle(document.documentElement) - .scrollPaddingTop - ) - const top = getOffsetTop(anchorElem) - scrollPadding || 0 - - window.scroll({ top }) - - return { element: anchorElem } - } catch (error) { - console.error(error) - } + return scrollToHash(href) + } +} + +export function scrollToHash(hash: string) { + if (typeof document === 'undefined' || !hash || !hash.includes('#')) { + return // stop here + } + + // Only continue, when we are sure we are on the same page, + // because, the same ID may exists occasionally on the current page. + const id = hash.split(/#/g).reverse()[0] + const anchorElem = document.getElementById(id) + + if (anchorElem instanceof HTMLElement) { + try { + const scrollPadding = parseFloat( + window.getComputedStyle(document.documentElement).scrollPaddingTop + ) + const top = getOffsetTop(anchorElem) - scrollPadding || 0 + + window.scroll({ top }) + + return { element: anchorElem } + } catch (error) { + console.error(error) } } } diff --git a/packages/dnb-eufemia/src/components/anchor/__tests__/AnchorScroll.test.tsx b/packages/dnb-eufemia/src/components/anchor/__tests__/AnchorScroll.test.tsx index b791ee170ca..79791e104d9 100644 --- a/packages/dnb-eufemia/src/components/anchor/__tests__/AnchorScroll.test.tsx +++ b/packages/dnb-eufemia/src/components/anchor/__tests__/AnchorScroll.test.tsx @@ -5,7 +5,33 @@ import React from 'react' import { fireEvent, render } from '@testing-library/react' -import Anchor, { scrollToHashHandler } from '../Anchor' +import Anchor, { scrollToHash, scrollToHashHandler } from '../Anchor' + +describe('Anchor with scrollToHash', () => { + it('should call window.scroll', () => { + const onScroll = jest.fn() + + jest.spyOn(window, 'scroll').mockImplementationOnce(onScroll) + + render( + <> + scrollToHash('/path#hash-id')}>text + + + ) + + fireEvent.click(document.querySelector('a')) + + expect(onScroll).toHaveBeenCalledTimes(1) + expect(onScroll).toHaveBeenCalledWith({ top: 0 }) + }) + + it('should support undefined', () => { + expect(() => { + scrollToHash(undefined) + }).not.toThrow() + }) +}) describe('Anchor with scrollToHashHandler', () => { let location: Location diff --git a/packages/dnb-eufemia/src/components/autocomplete/Autocomplete.js b/packages/dnb-eufemia/src/components/autocomplete/Autocomplete.js index a59fc9da070..64da2f289eb 100644 --- a/packages/dnb-eufemia/src/components/autocomplete/Autocomplete.js +++ b/packages/dnb-eufemia/src/components/autocomplete/Autocomplete.js @@ -326,7 +326,6 @@ export default class Autocomplete extends React.PureComponent { observer_element: null, enable_body_lock: false, - class: null, className: null, children: null, @@ -1756,7 +1755,6 @@ class AutocompleteInstance extends React.PureComponent { drawer_class, input_ref, // eslint-disable-line className, - class: _className, disabled, stretch, skeleton, @@ -1819,7 +1817,6 @@ class AutocompleteInstance extends React.PureComponent { showStatus && 'dnb-autocomplete__form-status', 'dnb-form-component', createSpacingClasses(props), - _className, className ), } diff --git a/packages/dnb-eufemia/src/components/button/Button.d.ts b/packages/dnb-eufemia/src/components/button/Button.d.ts index bc31398b02e..81ef447c487 100644 --- a/packages/dnb-eufemia/src/components/button/Button.d.ts +++ b/packages/dnb-eufemia/src/components/button/Button.d.ts @@ -97,10 +97,6 @@ export type ButtonProps = { */ globalStatus?: GlobalStatusConfigObject; id?: string; - /** - * Any extra modifying class. - */ - class?: string; /** * If you want the button to behave as a link. Use with caution! A link should normally visually be a link and not a button. */ diff --git a/packages/dnb-eufemia/src/components/button/Button.js b/packages/dnb-eufemia/src/components/button/Button.js index 82199cb5954..c50c4a1886c 100644 --- a/packages/dnb-eufemia/src/components/button/Button.js +++ b/packages/dnb-eufemia/src/components/button/Button.js @@ -105,7 +105,6 @@ export default class Button extends React.PureComponent { ) const { - class: class_name, className, variant, size, @@ -208,7 +207,6 @@ export default class Button extends React.PureComponent { this.context ), createSpacingClasses(props), - class_name, className, props.href || props.to ? '' : null, // dnb-anchor--no-underline dnb-anchor--no-hover Element === Anchor && 'dnb-anchor--no-style' @@ -311,7 +309,6 @@ Button.propTypes = { message: PropTypes.oneOfType([PropTypes.string, PropTypes.node]), }), id: PropTypes.string, - class: PropTypes.string, href: PropTypes.string, target: PropTypes.string, rel: PropTypes.string, @@ -360,7 +357,6 @@ Button.defaultProps = { rel: null, to: null, id: null, - class: null, custom_content: null, wrap: null, bounding: null, diff --git a/packages/dnb-eufemia/src/components/date-picker/DatePicker.d.ts b/packages/dnb-eufemia/src/components/date-picker/DatePicker.d.ts index 4b93c6d0358..042256ba200 100644 --- a/packages/dnb-eufemia/src/components/date-picker/DatePicker.d.ts +++ b/packages/dnb-eufemia/src/components/date-picker/DatePicker.d.ts @@ -231,7 +231,6 @@ export interface DatePickerProps * Use `right` to change the calendar alignment direction. Defaults to `left`. */ align_picker?: DatePickerAlignPicker; - class?: string; className?: string; /** * Will be called right before every new calendar view gets rendered. See the example above. diff --git a/packages/dnb-eufemia/src/components/date-picker/DatePicker.js b/packages/dnb-eufemia/src/components/date-picker/DatePicker.js index d4111300828..9d23ea70212 100644 --- a/packages/dnb-eufemia/src/components/date-picker/DatePicker.js +++ b/packages/dnb-eufemia/src/components/date-picker/DatePicker.js @@ -174,7 +174,6 @@ export default class DatePicker extends React.PureComponent { no_animation: PropTypes.oneOfType([PropTypes.string, PropTypes.bool]), direction: PropTypes.oneOf(['auto', 'top', 'bottom']), align_picker: PropTypes.oneOf(['auto', 'left', 'right']), - class: PropTypes.string, className: PropTypes.string, ...spacingPropTypes, @@ -247,7 +246,6 @@ export default class DatePicker extends React.PureComponent { no_animation: false, direction: 'auto', align_picker: null, - class: null, className: null, on_days_render: null, @@ -540,7 +538,6 @@ export default class DatePicker extends React.PureComponent { direction: _direction, // eslint-disable-line id: _id, // eslint-disable-line className, - class: _className, show_submit_button, // eslint-disable-line show_cancel_button, // eslint-disable-line show_reset_button, // eslint-disable-line @@ -596,7 +593,6 @@ export default class DatePicker extends React.PureComponent { 'dnb-form-component', size && `dnb-date-picker--${size}`, createSpacingClasses(props), - _className, className ), } diff --git a/packages/dnb-eufemia/src/components/dropdown/Dropdown.js b/packages/dnb-eufemia/src/components/dropdown/Dropdown.js index 1bbbd56f289..d65408e9f4d 100644 --- a/packages/dnb-eufemia/src/components/dropdown/Dropdown.js +++ b/packages/dnb-eufemia/src/components/dropdown/Dropdown.js @@ -156,7 +156,6 @@ export default class Dropdown extends React.PureComponent { disabled: PropTypes.oneOfType([PropTypes.string, PropTypes.bool]), stretch: PropTypes.oneOfType([PropTypes.string, PropTypes.bool]), skeleton: PropTypes.oneOfType([PropTypes.string, PropTypes.bool]), - class: PropTypes.string, className: PropTypes.string, children: PropTypes.oneOfType([ @@ -218,7 +217,6 @@ export default class Dropdown extends React.PureComponent { disabled: null, stretch: null, skeleton: null, - class: null, className: null, children: null, @@ -458,7 +456,6 @@ class DropdownInstance extends React.PureComponent { max_height, default_value, className, - class: _className, disabled, stretch, skeleton, @@ -524,7 +521,6 @@ class DropdownInstance extends React.PureComponent { showStatus && 'dnb-dropdown__form-status', 'dnb-form-component', createSpacingClasses(props), - _className, className ), } diff --git a/packages/dnb-eufemia/src/components/form-row/FormRow.d.ts b/packages/dnb-eufemia/src/components/form-row/FormRow.d.ts index 7592ce4784d..c68f00ea4ea 100644 --- a/packages/dnb-eufemia/src/components/form-row/FormRow.d.ts +++ b/packages/dnb-eufemia/src/components/form-row/FormRow.d.ts @@ -32,7 +32,6 @@ export interface FormRowProps responsive?: boolean; disabled?: boolean; skeleton?: SkeletonShow; - class?: string; skipContentWrapperIfNested?: boolean; className?: string; children?: FormRowChildren; diff --git a/packages/dnb-eufemia/src/components/form-row/FormRow.js b/packages/dnb-eufemia/src/components/form-row/FormRow.js index 2a79d30ea3c..55d34734b2b 100644 --- a/packages/dnb-eufemia/src/components/form-row/FormRow.js +++ b/packages/dnb-eufemia/src/components/form-row/FormRow.js @@ -52,7 +52,6 @@ export const formRowPropTypes = { responsive: PropTypes.oneOfType([PropTypes.string, PropTypes.bool]), disabled: PropTypes.oneOfType([PropTypes.string, PropTypes.bool]), skeleton: PropTypes.oneOfType([PropTypes.string, PropTypes.bool]), - class: PropTypes.string, skipContentWrapperIfNested: PropTypes.bool, @@ -86,7 +85,6 @@ export const formRowDefaultProps = { responsive: null, disabled: null, skeleton: null, - class: null, skipContentWrapperIfNested: false, className: null, @@ -162,7 +160,6 @@ export default class FormRow extends React.PureComponent { skeleton, wrap, className, - class: _className, skipContentWrapperIfNested, id: _id, // eslint-disable-line @@ -200,8 +197,7 @@ export default class FormRow extends React.PureComponent { centered && 'dnb-form-row--centered', isNested && 'dnb-form-row--nested', createSpacingClasses(props), - className, - _className + className ), ...attributes, } diff --git a/packages/dnb-eufemia/src/components/form-set/FormSet.d.ts b/packages/dnb-eufemia/src/components/form-set/FormSet.d.ts index bdbbf162741..7e4346d52ce 100644 --- a/packages/dnb-eufemia/src/components/form-set/FormSet.d.ts +++ b/packages/dnb-eufemia/src/components/form-set/FormSet.d.ts @@ -35,7 +35,6 @@ export interface FormSetProps section_spacing?: SectionSpacing; globalStatus?: GlobalStatusConfigObject; responsive?: boolean; - class?: string; skipContentWrapperIfNested?: boolean; className?: string; children?: FormSetChildren; diff --git a/packages/dnb-eufemia/src/components/form-set/FormSet.js b/packages/dnb-eufemia/src/components/form-set/FormSet.js index 96e0dfafb25..6b1f07f428e 100644 --- a/packages/dnb-eufemia/src/components/form-set/FormSet.js +++ b/packages/dnb-eufemia/src/components/form-set/FormSet.js @@ -81,7 +81,6 @@ export default class FormSet extends React.PureComponent { prevent_submit, // eslint-disable-line id, // eslint-disable-line className, - class: _className, ...rest } = props @@ -108,8 +107,7 @@ export default class FormSet extends React.PureComponent { className: classnames( 'dnb-form-set', createSpacingClasses(this.props), - className, - _className + className ), ...attributes, } diff --git a/packages/dnb-eufemia/src/components/form-status/FormStatus.d.ts b/packages/dnb-eufemia/src/components/form-status/FormStatus.d.ts index 08e894c09f7..059d41ac1e4 100644 --- a/packages/dnb-eufemia/src/components/form-status/FormStatus.d.ts +++ b/packages/dnb-eufemia/src/components/form-status/FormStatus.d.ts @@ -68,7 +68,6 @@ export interface FormStatusProps text_id?: string; width_selector?: string; width_element?: Record; - class?: string; /** * NB: Animation is disabled as of now. use `true` to omit the animation on content visibility. Defaults to `false`. */ diff --git a/packages/dnb-eufemia/src/components/form-status/FormStatus.js b/packages/dnb-eufemia/src/components/form-status/FormStatus.js index 8f37155a46a..c88bda7b6eb 100644 --- a/packages/dnb-eufemia/src/components/form-status/FormStatus.js +++ b/packages/dnb-eufemia/src/components/form-status/FormStatus.js @@ -68,7 +68,6 @@ export default class FormStatus extends React.PureComponent { text_id: PropTypes.string, width_selector: PropTypes.string, width_element: PropTypes.object, - class: PropTypes.string, no_animation: PropTypes.oneOfType([PropTypes.string, PropTypes.bool]), skeleton: PropTypes.oneOfType([PropTypes.string, PropTypes.bool]), stretch: PropTypes.oneOfType([PropTypes.string, PropTypes.bool]), @@ -100,7 +99,6 @@ export default class FormStatus extends React.PureComponent { text_id: null, width_selector: null, width_element: null, - class: null, no_animation: null, skeleton: null, stretch: null, @@ -354,7 +352,6 @@ export default class FormStatus extends React.PureComponent { className, stretch, shellSpace, - class: _className, text_id, show, // eslint-disable-line @@ -394,8 +391,7 @@ export default class FormStatus extends React.PureComponent { stretch && 'dnb-form-status--stretch', hasStringContent ? 'dnb-form-status--has-content' : null, createSpacingClasses(props), - className, - _className + className ), id: !String(id).startsWith('null') ? this.state.id : null, title, diff --git a/packages/dnb-eufemia/src/components/global-status/GlobalStatus.d.ts b/packages/dnb-eufemia/src/components/global-status/GlobalStatus.d.ts index 58f22d9378a..5bbb528749d 100644 --- a/packages/dnb-eufemia/src/components/global-status/GlobalStatus.d.ts +++ b/packages/dnb-eufemia/src/components/global-status/GlobalStatus.d.ts @@ -94,7 +94,6 @@ export interface GlobalStatusProps */ status_anchor_text?: React.ReactNode; skeleton?: SkeletonShow; - class?: string; className?: string; /** * The text appears as the status content. Besides plain text, you can send in a React component as well. Defaults to `null`. diff --git a/packages/dnb-eufemia/src/components/global-status/GlobalStatus.js b/packages/dnb-eufemia/src/components/global-status/GlobalStatus.js index 44ec06c77df..049dab9fe3d 100644 --- a/packages/dnb-eufemia/src/components/global-status/GlobalStatus.js +++ b/packages/dnb-eufemia/src/components/global-status/GlobalStatus.js @@ -85,7 +85,6 @@ export default class GlobalStatus extends React.PureComponent { ...spacingPropTypes, - class: PropTypes.string, className: PropTypes.string, children: PropTypes.oneOfType([ PropTypes.string, @@ -121,7 +120,6 @@ export default class GlobalStatus extends React.PureComponent { delay: null, status_anchor_text: null, skeleton: null, - class: null, className: null, children: null, @@ -574,7 +572,6 @@ export default class GlobalStatus extends React.PureComponent { no_animation, hide_close_button, close_text, - class: _className, status_anchor_text, skeleton, @@ -601,8 +598,7 @@ export default class GlobalStatus extends React.PureComponent { 'dnb-no-focus', createSkeletonClass('font', skeleton, this.context), createSpacingClasses(props), - className, - _className + className ), 'aria-live': isActive ? 'assertive' : 'off', onKeyDown: this.onKeyDownHandler, diff --git a/packages/dnb-eufemia/src/components/help-button/HelpButtonInstance.tsx b/packages/dnb-eufemia/src/components/help-button/HelpButtonInstance.tsx index 55815930f96..671e32f6ffa 100644 --- a/packages/dnb-eufemia/src/components/help-button/HelpButtonInstance.tsx +++ b/packages/dnb-eufemia/src/components/help-button/HelpButtonInstance.tsx @@ -28,21 +28,13 @@ export default function HelpButtonInstance(localProps: ButtonProps) { context.HelpButton ) - const { - size, - icon, - on_click, - className, - class: _className, - ...rest - } = props + const { size, icon, on_click, className, ...rest } = props const params = { className: classnames( 'dnb-help-button', createSpacingClasses(props), - className, - _className + className ), size, icon, diff --git a/packages/dnb-eufemia/src/components/icon/Icon.js b/packages/dnb-eufemia/src/components/icon/Icon.js index 42a4fc512cb..8a43f48d54e 100644 --- a/packages/dnb-eufemia/src/components/icon/Icon.js +++ b/packages/dnb-eufemia/src/components/icon/Icon.js @@ -313,7 +313,6 @@ export const prepareIcon = (props, context) => { alt, title, skeleton, - class: _className, className, ...attributes } = props @@ -365,7 +364,6 @@ export const prepareIcon = (props, context) => { sizeAsString ? `dnb-icon--${sizeAsString}` : 'dnb-icon--default', createSkeletonClass(null, skeleton, context), createSpacingClasses(props), - _className, className ) diff --git a/packages/dnb-eufemia/src/components/input-masked/InputMasked.d.ts b/packages/dnb-eufemia/src/components/input-masked/InputMasked.d.ts index b4121ab6906..1accf77c2a9 100644 --- a/packages/dnb-eufemia/src/components/input-masked/InputMasked.d.ts +++ b/packages/dnb-eufemia/src/components/input-masked/InputMasked.d.ts @@ -150,7 +150,6 @@ export interface InputMaskedProps stretch?: boolean; disabled?: boolean; skeleton?: SkeletonShow; - class?: string; input_class?: string; input_attributes?: InputInputAttributes; input_element?: InputInputElement; diff --git a/packages/dnb-eufemia/src/components/input/Input.d.ts b/packages/dnb-eufemia/src/components/input/Input.d.ts index 462ebc35e10..e83b9be53d9 100644 --- a/packages/dnb-eufemia/src/components/input/Input.d.ts +++ b/packages/dnb-eufemia/src/components/input/Input.d.ts @@ -120,7 +120,6 @@ export interface InputProps * If set to `true`, an overlaying skeleton with animation will be shown. */ skeleton?: SkeletonShow; - class?: string; /** * In case we have to set a custom input class. */ diff --git a/packages/dnb-eufemia/src/components/input/Input.js b/packages/dnb-eufemia/src/components/input/Input.js index 4b9d2b0f64b..48e5085f3fe 100644 --- a/packages/dnb-eufemia/src/components/input/Input.js +++ b/packages/dnb-eufemia/src/components/input/Input.js @@ -90,7 +90,6 @@ export const inputPropTypes = { stretch: PropTypes.oneOfType([PropTypes.string, PropTypes.bool]), disabled: PropTypes.oneOfType([PropTypes.string, PropTypes.bool]), skeleton: PropTypes.oneOfType([PropTypes.string, PropTypes.bool]), - class: PropTypes.string, input_class: PropTypes.string, input_attributes: PropTypes.oneOfType([ PropTypes.string, @@ -166,7 +165,6 @@ export default class Input extends React.PureComponent { disabled: null, skeleton: null, input_class: null, - class: null, input_attributes: null, input_element: null, inner_ref: null, @@ -378,7 +376,6 @@ export default class Input extends React.PureComponent { icon, icon_position, icon_size, - class: _className, className, id: _id, //eslint-disable-line @@ -429,7 +426,6 @@ export default class Input extends React.PureComponent { isTrue(keep_placeholder) && 'dnb-input--keep-placeholder', 'dnb-form-component', createSpacingClasses(props), - _className, className ), 'data-input-state': inputState, diff --git a/packages/dnb-eufemia/src/components/logo/Logo.js b/packages/dnb-eufemia/src/components/logo/Logo.js index e327dadca69..2dec94a286a 100644 --- a/packages/dnb-eufemia/src/components/logo/Logo.js +++ b/packages/dnb-eufemia/src/components/logo/Logo.js @@ -31,7 +31,6 @@ export default class Logo extends React.PureComponent { alt: PropTypes.string, color: PropTypes.string, inherit_color: PropTypes.bool, - class: PropTypes.string, ...spacingPropTypes, @@ -48,7 +47,6 @@ export default class Logo extends React.PureComponent { alt: 'DNB Logo', color: null, inherit_color: null, - class: null, className: null, } @@ -86,7 +84,6 @@ export default class Logo extends React.PureComponent { inherit_color, alt, className, - class: _className, ...rest } = props @@ -120,7 +117,6 @@ export default class Logo extends React.PureComponent { className: classnames( 'dnb-logo', className, - _className, createSpacingClasses(props), (width > 0 || height > 0) && 'dnb-logo--has-size', size === 'inherit' && 'dnb-logo--inherit-size', @@ -136,7 +132,6 @@ export default class Logo extends React.PureComponent { className: classnames( 'sbanken-logo', className, - _className, createSpacingClasses(props), (width > 0 || height > 0) && 'sbanken-logo--has-size', size === 'inherit' && 'sbanken-logo--inherit-size', diff --git a/packages/dnb-eufemia/src/components/modal/Modal.tsx b/packages/dnb-eufemia/src/components/modal/Modal.tsx index d94f0145948..dc6b15dc048 100644 --- a/packages/dnb-eufemia/src/components/modal/Modal.tsx +++ b/packages/dnb-eufemia/src/components/modal/Modal.tsx @@ -107,7 +107,6 @@ class Modal extends React.PureComponent< container_placement: null, open_state: null, direct_dom_return: false, - class: null, root_id: 'root', omit_trigger_button: false, @@ -488,7 +487,6 @@ class Modal extends React.PureComponent< className={classnames( 'dnb-modal__trigger', createSpacingClasses(props), - triggerAttributes.class, triggerAttributes.className )} /> diff --git a/packages/dnb-eufemia/src/components/modal/types.ts b/packages/dnb-eufemia/src/components/modal/types.ts index 2390eb59308..152f46340a6 100644 --- a/packages/dnb-eufemia/src/components/modal/types.ts +++ b/packages/dnb-eufemia/src/components/modal/types.ts @@ -254,11 +254,6 @@ export interface ModalContentProps { */ container_placement?: 'left' | 'right' | 'top' | 'bottom' - /** - * Give the inner Dialog or Drawer component a class (only works with mode) - */ - class?: string - /** * Give the content wrapper a custom class name (maps to `dnb-modal__content`). */ diff --git a/packages/dnb-eufemia/src/components/number-format/NumberFormat.js b/packages/dnb-eufemia/src/components/number-format/NumberFormat.js index b73d8c06b33..aabb94802c6 100644 --- a/packages/dnb-eufemia/src/components/number-format/NumberFormat.js +++ b/packages/dnb-eufemia/src/components/number-format/NumberFormat.js @@ -105,7 +105,6 @@ export default class NumberFormat extends React.PureComponent { ...spacingPropTypes, - class: PropTypes.string, className: PropTypes.string, children: PropTypes.oneOfType([PropTypes.node, PropTypes.func]), } @@ -137,7 +136,6 @@ export default class NumberFormat extends React.PureComponent { element: 'span', // span or abbr tooltip: null, skeleton: null, - class: null, className: null, children: null, @@ -284,7 +282,6 @@ export default class NumberFormat extends React.PureComponent { clean_copy_value, srLabel, element, - class: _className, className, ..._rest } = props @@ -378,7 +375,6 @@ export default class NumberFormat extends React.PureComponent { className: classnames( 'dnb-number-format', className, - _className, (isTrue(currency) || typeof currency === 'string') && 'dnb-number-format--currency', isTrue(selectall) && 'dnb-number-format--selectall', diff --git a/packages/dnb-eufemia/src/components/pagination/Pagination.d.ts b/packages/dnb-eufemia/src/components/pagination/Pagination.d.ts index b6a59d06149..ac55d2d1725 100644 --- a/packages/dnb-eufemia/src/components/pagination/Pagination.d.ts +++ b/packages/dnb-eufemia/src/components/pagination/Pagination.d.ts @@ -146,7 +146,6 @@ export interface PaginationProps * Used during infinity mode. If `use_load_button` is set to `true`, then a button is show on the bottom. If the `startup_page` is higher than 1. Defaults to `Vis mer innhold`. */ load_button_text?: string; - class?: string; className?: string; /** * The given content can be either a function or a React node, depending on your needs. A function contains several helper functions. More details down below and have a look at the examples in the demos section. @@ -328,7 +327,6 @@ interface PaginationInstanceProps extends SpacingProps { * Used during infinity mode. If `use_load_button` is set to true, then a button is show on the bottom. If the `startup_page` is higher than 1. Defaults to `Vis mer innhold`. */ load_button_text?: string; - class?: string; className?: string; /** * The given content can be either a function or a React node, depending on your needs. A function contains several helper functions. More details down below and have a look at the examples in the demos section. @@ -504,7 +502,6 @@ interface InfinityMarkerProps extends SpacingProps { * Used during infinity mode. If `use_load_button` is set to true, then a button is show on the bottom. If the `startup_page` is higher than 1. Defaults to `Vis mer innhold`. */ load_button_text?: string; - class?: string; className?: string; /** * The given content can be either a function or a React node, depending on your needs. A function contains several helper functions. More details down below and have a look at the examples in the demos section. diff --git a/packages/dnb-eufemia/src/components/pagination/Pagination.js b/packages/dnb-eufemia/src/components/pagination/Pagination.js index 50ccd765d16..8d01817e876 100644 --- a/packages/dnb-eufemia/src/components/pagination/Pagination.js +++ b/packages/dnb-eufemia/src/components/pagination/Pagination.js @@ -95,7 +95,6 @@ const paginationPropTypes = { ...spacingPropTypes, - class: PropTypes.string, className: PropTypes.string, children: PropTypes.oneOfType([PropTypes.node, PropTypes.func]), @@ -133,7 +132,6 @@ const paginationDefaultProps = { disabled: null, skeleton: null, - class: null, className: null, children: null, @@ -183,7 +181,6 @@ class PaginationInstance extends React.PureComponent { align, children, className, - class: _className, disabled: _disabled, // eslint-disable-line skeleton: _skeleton, // eslint-disable-line @@ -210,8 +207,7 @@ class PaginationInstance extends React.PureComponent { 'dnb-pagination', align && `dnb-pagination--${align}`, createSpacingClasses(props), - className, - _className + className ), ...attributes, } diff --git a/packages/dnb-eufemia/src/components/radio/Radio.d.ts b/packages/dnb-eufemia/src/components/radio/Radio.d.ts index d63aec5dd41..5ae0bd4911e 100644 --- a/packages/dnb-eufemia/src/components/radio/Radio.d.ts +++ b/packages/dnb-eufemia/src/components/radio/Radio.d.ts @@ -75,7 +75,6 @@ export interface RadioProps attributes?: RadioAttributes; skeleton?: SkeletonShow; readOnly?: boolean; - class?: string; className?: string; children?: RadioChildren; /** diff --git a/packages/dnb-eufemia/src/components/radio/Radio.js b/packages/dnb-eufemia/src/components/radio/Radio.js index e30f1800612..55b675fb4c9 100644 --- a/packages/dnb-eufemia/src/components/radio/Radio.js +++ b/packages/dnb-eufemia/src/components/radio/Radio.js @@ -85,7 +85,6 @@ export default class Radio extends React.PureComponent { ...spacingPropTypes, - class: PropTypes.string, className: PropTypes.string, children: PropTypes.oneOfType([PropTypes.string, PropTypes.func]), @@ -113,7 +112,6 @@ export default class Radio extends React.PureComponent { attributes: null, readOnly: false, skeleton: null, - class: null, className: null, children: null, @@ -306,7 +304,6 @@ export default class Radio extends React.PureComponent { readOnly, skeleton, className, - class: _className, id: _id, // eslint-disable-line group: _group, // eslint-disable-line value: _value, // eslint-disable-line @@ -348,8 +345,7 @@ export default class Radio extends React.PureComponent { label && `dnb-radio--label-position-${label_position || 'right'}`, createSpacingClasses(props), - className, - _className + className ), } diff --git a/packages/dnb-eufemia/src/components/radio/RadioGroup.d.ts b/packages/dnb-eufemia/src/components/radio/RadioGroup.d.ts index 09e04085b30..3405157fb2f 100644 --- a/packages/dnb-eufemia/src/components/radio/RadioGroup.d.ts +++ b/packages/dnb-eufemia/src/components/radio/RadioGroup.d.ts @@ -70,7 +70,6 @@ export interface RadioGroupProps */ value?: string; attributes?: RadioGroupAttributes; - class?: string; className?: string; children?: RadioGroupChildren; /** diff --git a/packages/dnb-eufemia/src/components/radio/RadioGroup.js b/packages/dnb-eufemia/src/components/radio/RadioGroup.js index 25639384594..e5e8b336d8c 100644 --- a/packages/dnb-eufemia/src/components/radio/RadioGroup.js +++ b/packages/dnb-eufemia/src/components/radio/RadioGroup.js @@ -80,7 +80,6 @@ export default class RadioGroup extends React.PureComponent { ...spacingPropTypes, - class: PropTypes.string, className: PropTypes.string, children: PropTypes.oneOfType([ PropTypes.string, @@ -112,7 +111,6 @@ export default class RadioGroup extends React.PureComponent { layout_direction: 'row', value: undefined, attributes: null, - class: null, className: null, children: null, @@ -182,7 +180,6 @@ export default class RadioGroup extends React.PureComponent { disabled, skeleton, className, - class: _className, id: _id, // eslint-disable-line name: _name, // eslint-disable-line @@ -204,8 +201,7 @@ export default class RadioGroup extends React.PureComponent { `dnb-radio-group--${layout_direction}`, 'dnb-form-component', createSpacingClasses(props), - className, - _className + className ) const params = { diff --git a/packages/dnb-eufemia/src/components/skeleton/Skeleton.d.ts b/packages/dnb-eufemia/src/components/skeleton/Skeleton.d.ts index b277b211d6d..843aa67bbb5 100644 --- a/packages/dnb-eufemia/src/components/skeleton/Skeleton.d.ts +++ b/packages/dnb-eufemia/src/components/skeleton/Skeleton.d.ts @@ -36,7 +36,6 @@ export interface SkeletonProps * Set any HTML element type you have to use. A couple of aria attributes will be set on this element while active. Defaults to `div`. */ element?: React.ReactNode; - class?: string; className?: string; children?: SkeletonChildren; } diff --git a/packages/dnb-eufemia/src/components/skeleton/Skeleton.js b/packages/dnb-eufemia/src/components/skeleton/Skeleton.js index 4a3051dff04..111029a6d46 100644 --- a/packages/dnb-eufemia/src/components/skeleton/Skeleton.js +++ b/packages/dnb-eufemia/src/components/skeleton/Skeleton.js @@ -39,7 +39,6 @@ export default class Skeleton extends React.PureComponent { ...spacingPropTypes, - class: PropTypes.string, className: PropTypes.string, children: PropTypes.oneOfType([ PropTypes.string, @@ -56,7 +55,6 @@ export default class Skeleton extends React.PureComponent { aria_busy: null, aria_ready: null, element: null, - class: null, className: null, children: null, } @@ -127,7 +125,6 @@ export default class Skeleton extends React.PureComponent { aria_busy, aria_ready, // eslint-disable-line className, - class: _className, children, ...attributes @@ -146,8 +143,7 @@ export default class Skeleton extends React.PureComponent { isTrue(showSkeleton) && 'dnb-skeleton', isTrue(no_animation) && 'dnb-skeleton--no-animation', createSpacingClasses(props), - className, - _className + className ), // role: 'status',// is not needed as for now 'aria-busy': showSkeleton, diff --git a/packages/dnb-eufemia/src/components/switch/Switch.d.ts b/packages/dnb-eufemia/src/components/switch/Switch.d.ts index 979eb8e3e8d..f3a03421af9 100644 --- a/packages/dnb-eufemia/src/components/switch/Switch.d.ts +++ b/packages/dnb-eufemia/src/components/switch/Switch.d.ts @@ -72,7 +72,6 @@ export interface SwitchProps * If set to `true`, an overlaying skeleton with animation will be shown. */ skeleton?: SkeletonShow; - class?: string; className?: string; children?: SwitchChildren; /** diff --git a/packages/dnb-eufemia/src/components/switch/Switch.js b/packages/dnb-eufemia/src/components/switch/Switch.js index b21b132c661..82308f73f87 100644 --- a/packages/dnb-eufemia/src/components/switch/Switch.js +++ b/packages/dnb-eufemia/src/components/switch/Switch.js @@ -82,7 +82,6 @@ export default class Switch extends React.PureComponent { ...spacingPropTypes, - class: PropTypes.string, className: PropTypes.string, children: PropTypes.oneOfType([PropTypes.string, PropTypes.func]), @@ -110,7 +109,6 @@ export default class Switch extends React.PureComponent { attributes: null, readOnly: false, skeleton: null, - class: null, className: null, children: null, @@ -233,7 +231,6 @@ export default class Switch extends React.PureComponent { readOnly, skeleton, className, - class: _className, id: _id, // eslint-disable-line checked: _checked, // eslint-disable-line @@ -259,8 +256,7 @@ export default class Switch extends React.PureComponent { 'dnb-form-component', createSkeletonClass(null, skeleton), createSpacingClasses(props), - className, - _className + className ), } diff --git a/packages/dnb-eufemia/src/components/tabs/Tabs.d.ts b/packages/dnb-eufemia/src/components/tabs/Tabs.d.ts index a63cc842020..4de27aa2ef9 100644 --- a/packages/dnb-eufemia/src/components/tabs/Tabs.d.ts +++ b/packages/dnb-eufemia/src/components/tabs/Tabs.d.ts @@ -100,7 +100,6 @@ export interface TabsProps */ skeleton?: SkeletonShow; id?: string; - class?: string; className?: string; /** * the content to render. Can be a function, returning the current tab content `(key) => ('Current tab')`, a React Component or an object with the keys and content `{key1: 'Current tab'}`. diff --git a/packages/dnb-eufemia/src/components/tabs/Tabs.js b/packages/dnb-eufemia/src/components/tabs/Tabs.js index 42001fecda7..bde964df5f7 100644 --- a/packages/dnb-eufemia/src/components/tabs/Tabs.js +++ b/packages/dnb-eufemia/src/components/tabs/Tabs.js @@ -102,7 +102,6 @@ export default class Tabs extends React.PureComponent { ...spacingPropTypes, - class: PropTypes.string, className: PropTypes.string, children: PropTypes.oneOfType([ PropTypes.object, @@ -136,7 +135,6 @@ export default class Tabs extends React.PureComponent { scroll: null, skeleton: null, id: null, - class: null, className: null, children: null, diff --git a/packages/dnb-eufemia/src/components/tabs/TabsCustomContent.d.ts b/packages/dnb-eufemia/src/components/tabs/TabsCustomContent.d.ts index f435b5f9946..9690cbe2793 100644 --- a/packages/dnb-eufemia/src/components/tabs/TabsCustomContent.d.ts +++ b/packages/dnb-eufemia/src/components/tabs/TabsCustomContent.d.ts @@ -17,7 +17,6 @@ export interface CustomContentProps disabled?: boolean; children?: CustomContentChildren; className?: string; - class?: string; } export default class CustomContent extends React.Component< CustomContentProps, diff --git a/packages/dnb-eufemia/src/components/tabs/TabsCustomContent.js b/packages/dnb-eufemia/src/components/tabs/TabsCustomContent.js index 208264726bd..377fd235132 100644 --- a/packages/dnb-eufemia/src/components/tabs/TabsCustomContent.js +++ b/packages/dnb-eufemia/src/components/tabs/TabsCustomContent.js @@ -31,7 +31,6 @@ export default class CustomContent extends React.PureComponent { children: PropTypes.oneOfType([PropTypes.node, PropTypes.func]), className: PropTypes.string, - class: PropTypes.string, } static defaultProps = { displayName: 'CustomContent', @@ -41,7 +40,6 @@ export default class CustomContent extends React.PureComponent { disabled: null, children: null, className: null, - class: null, } render() { const { @@ -51,7 +49,6 @@ export default class CustomContent extends React.PureComponent { selected, // eslint-disable-line disabled, // eslint-disable-line className, - class: _className, ...rest } = this.props @@ -64,8 +61,7 @@ export default class CustomContent extends React.PureComponent { className={classnames( 'dnb-tabs__content__inner', createSpacingClasses(rest), - className, - _className + className )} > {this.props.children} diff --git a/packages/dnb-eufemia/src/components/textarea/Textarea.d.ts b/packages/dnb-eufemia/src/components/textarea/Textarea.d.ts index de77abd7947..f539ca32f41 100644 --- a/packages/dnb-eufemia/src/components/textarea/Textarea.d.ts +++ b/packages/dnb-eufemia/src/components/textarea/Textarea.d.ts @@ -105,7 +105,6 @@ export interface TextareaProps * Set a number to define how many rows the Textarea can auto grow. */ autoresize_max_rows?: TextareaAutoresizeMaxRows; - class?: string; textarea_class?: string; textarea_attributes?: TextareaTextareaAttributes; readOnly?: boolean; diff --git a/packages/dnb-eufemia/src/components/textarea/Textarea.js b/packages/dnb-eufemia/src/components/textarea/Textarea.js index 051535aa08a..ab38401b3e7 100644 --- a/packages/dnb-eufemia/src/components/textarea/Textarea.js +++ b/packages/dnb-eufemia/src/components/textarea/Textarea.js @@ -94,7 +94,6 @@ export default class Textarea extends React.PureComponent { PropTypes.string, PropTypes.number, ]), - class: PropTypes.string, textarea_class: PropTypes.string, textarea_attributes: PropTypes.oneOfType([ PropTypes.string, @@ -145,7 +144,6 @@ export default class Textarea extends React.PureComponent { autoresize_max_rows: null, characterCounter: null, textarea_class: null, - class: null, textarea_attributes: null, readOnly: false, rows: null, @@ -410,7 +408,6 @@ export default class Textarea extends React.PureComponent { textarea_class, readOnly, textarea_attributes, - class: _className, className, autoresize, characterCounter, @@ -488,7 +485,6 @@ export default class Textarea extends React.PureComponent { 'dnb-form-component', createSkeletonClass(null, skeleton), createSpacingClasses(props), - _className, className ), } diff --git a/packages/dnb-eufemia/src/components/toggle-button/ToggleButton.d.ts b/packages/dnb-eufemia/src/components/toggle-button/ToggleButton.d.ts index 6881f9ac278..5646f55f092 100644 --- a/packages/dnb-eufemia/src/components/toggle-button/ToggleButton.d.ts +++ b/packages/dnb-eufemia/src/components/toggle-button/ToggleButton.d.ts @@ -91,7 +91,6 @@ export interface ToggleButtonProps icon_size?: IconSize; attributes?: ToggleButtonAttributes; readOnly?: boolean; - class?: string; className?: string; children?: ToggleButtonChildren; /** diff --git a/packages/dnb-eufemia/src/components/toggle-button/ToggleButton.js b/packages/dnb-eufemia/src/components/toggle-button/ToggleButton.js index 77eb4e1735c..0b3e4057d58 100644 --- a/packages/dnb-eufemia/src/components/toggle-button/ToggleButton.js +++ b/packages/dnb-eufemia/src/components/toggle-button/ToggleButton.js @@ -100,7 +100,6 @@ export default class ToggleButton extends React.PureComponent { ...spacingPropTypes, - class: PropTypes.string, className: PropTypes.string, children: PropTypes.oneOfType([PropTypes.string, PropTypes.func]), @@ -133,7 +132,6 @@ export default class ToggleButton extends React.PureComponent { icon_size: null, attributes: null, readOnly: false, - class: null, className: null, children: null, @@ -308,7 +306,6 @@ export default class ToggleButton extends React.PureComponent { title, readOnly, className, - class: _className, disabled, skeleton, variant, @@ -364,8 +361,7 @@ export default class ToggleButton extends React.PureComponent { checked && `dnb-toggle-button--checked`, label_direction && `dnb-toggle-button--${label_direction}`, createSpacingClasses(props), - className, - _className + className ), } diff --git a/packages/dnb-eufemia/src/components/toggle-button/ToggleButtonGroup.d.ts b/packages/dnb-eufemia/src/components/toggle-button/ToggleButtonGroup.d.ts index 0664921e8fc..c295e725950 100644 --- a/packages/dnb-eufemia/src/components/toggle-button/ToggleButtonGroup.d.ts +++ b/packages/dnb-eufemia/src/components/toggle-button/ToggleButtonGroup.d.ts @@ -81,7 +81,6 @@ export interface ToggleButtonGroupProps */ values?: ToggleButtonGroupValues; attributes?: ToggleButtonGroupAttributes; - class?: string; className?: string; children?: ToggleButtonGroupChildren; /** diff --git a/packages/dnb-eufemia/src/components/toggle-button/ToggleButtonGroup.js b/packages/dnb-eufemia/src/components/toggle-button/ToggleButtonGroup.js index 3e2d690486f..8adce93a85e 100644 --- a/packages/dnb-eufemia/src/components/toggle-button/ToggleButtonGroup.js +++ b/packages/dnb-eufemia/src/components/toggle-button/ToggleButtonGroup.js @@ -84,7 +84,6 @@ export default class ToggleButtonGroup extends React.PureComponent { ...spacingPropTypes, - class: PropTypes.string, className: PropTypes.string, children: PropTypes.oneOfType([ PropTypes.string, @@ -118,7 +117,6 @@ export default class ToggleButtonGroup extends React.PureComponent { value: undefined, values: undefined, attributes: null, - class: null, className: null, children: null, @@ -218,7 +216,6 @@ export default class ToggleButtonGroup extends React.PureComponent { disabled, skeleton, className, - class: _className, multiselect, id: _id, // eslint-disable-line @@ -243,8 +240,7 @@ export default class ToggleButtonGroup extends React.PureComponent { `dnb-toggle-button-group--${layout_direction}`, 'dnb-form-component', createSpacingClasses(props), - className, - _className + className ) const params = { diff --git a/packages/dnb-eufemia/src/extensions/forms/Field/Boolean/Boolean.tsx b/packages/dnb-eufemia/src/extensions/forms/Field/Boolean/Boolean.tsx index 3b74e13704f..44c87c87100 100644 --- a/packages/dnb-eufemia/src/extensions/forms/Field/Boolean/Boolean.tsx +++ b/packages/dnb-eufemia/src/extensions/forms/Field/Boolean/Boolean.tsx @@ -1,7 +1,7 @@ import React from 'react' import ToggleField, { Props as ToggleFieldProps } from '../Toggle' import useTranslation from '../../hooks/useTranslation' -import { FieldProps, Path } from '../../types' +import { FieldHelpProps, FieldProps, Path } from '../../types' type BooleanProps = { trueText?: string @@ -16,7 +16,7 @@ type NeverBooleanProps = { export type IndeterminateProps = FieldProps & { dependencePaths: Array } & NeverBooleanProps -export type Props = FieldProps & BooleanProps +export type Props = FieldHelpProps & FieldProps & BooleanProps function BooleanComponent(props: Props | IndeterminateProps) { const { trueText, falseText, ...restProps } = props diff --git a/packages/dnb-eufemia/src/extensions/forms/Field/Boolean/__tests__/Boolean.test.tsx b/packages/dnb-eufemia/src/extensions/forms/Field/Boolean/__tests__/Boolean.test.tsx index 1f7fde7276a..68135b93018 100644 --- a/packages/dnb-eufemia/src/extensions/forms/Field/Boolean/__tests__/Boolean.test.tsx +++ b/packages/dnb-eufemia/src/extensions/forms/Field/Boolean/__tests__/Boolean.test.tsx @@ -11,6 +11,26 @@ describe('Field.Boolean', () => { expect(screen.getByLabelText('Boolean label')).toBeInTheDocument() }) + it('renders help', () => { + render( + + ) + expect(document.querySelector('input')).toHaveAttribute( + 'aria-describedby' + ) + expect( + document.querySelector('input').getAttribute('aria-describedby') + ).toBe(document.querySelector('.dnb-checkbox__suffix').id) + expect( + document + .querySelector('.dnb-help-button') + .getAttribute('aria-describedby') + ).toBe(document.querySelector('.dnb-tooltip__content').id) + }) + it('renders error', () => { render( { expect(screen.getByText('Boolean label')).toBeInTheDocument() }) + it('renders help', () => { + render( + + ) + expect(document.querySelector('button')).toHaveAttribute( + 'aria-describedby' + ) + expect( + document.querySelector('button').getAttribute('aria-describedby') + ).toBe(document.querySelector('.dnb-toggle-button__suffix').id) + expect( + document + .querySelector('.dnb-help-button') + .getAttribute('aria-describedby') + ).toBe(document.querySelector('.dnb-tooltip__content').id) + }) + it('renders error', () => { render( { expect(screen.getByText('Boolean label')).toBeInTheDocument() }) + it('renders help', () => { + render( + + ) + expect(document.querySelector('button')).toHaveAttribute( + 'aria-describedby' + ) + expect( + document.querySelector('button').getAttribute('aria-describedby') + ).toBe(document.querySelector('.dnb-toggle-button__suffix').id) + expect( + document + .querySelector('.dnb-help-button') + .getAttribute('aria-describedby') + ).toBe(document.querySelector('.dnb-tooltip__content').id) + }) + it('renders error', () => { render( { expect(screen.getByText('Boolean label')).toBeInTheDocument() }) + it('renders help', () => { + render( + + ) + expect(document.querySelector('button')).toHaveAttribute( + 'aria-describedby' + ) + expect( + document.querySelector('button').getAttribute('aria-describedby') + ).toBe(document.querySelector('.dnb-toggle-button__suffix').id) + expect( + document + .querySelector('.dnb-help-button') + .getAttribute('aria-describedby') + ).toBe(document.querySelector('.dnb-tooltip__content').id) + }) + it('has no selected value by default', () => { render() const buttons = document.querySelectorAll('button') diff --git a/packages/dnb-eufemia/src/extensions/forms/Field/Boolean/stories/Boolean.stories.tsx b/packages/dnb-eufemia/src/extensions/forms/Field/Boolean/stories/Boolean.stories.tsx index 0f67a94e17c..e4af973ced9 100644 --- a/packages/dnb-eufemia/src/extensions/forms/Field/Boolean/stories/Boolean.stories.tsx +++ b/packages/dnb-eufemia/src/extensions/forms/Field/Boolean/stories/Boolean.stories.tsx @@ -25,6 +25,7 @@ export function Boolean() { label="Has Employees" path="/hasEmployees" validateInitially + help={{ title: 'Help title', content: 'Help content' }} /> diff --git a/packages/dnb-eufemia/src/extensions/forms/Field/Number/__tests__/Number.test.tsx b/packages/dnb-eufemia/src/extensions/forms/Field/Number/__tests__/Number.test.tsx index f070f69aea1..b6fe120b167 100644 --- a/packages/dnb-eufemia/src/extensions/forms/Field/Number/__tests__/Number.test.tsx +++ b/packages/dnb-eufemia/src/extensions/forms/Field/Number/__tests__/Number.test.tsx @@ -20,6 +20,25 @@ describe('Field.Number', () => { ).toBeInTheDocument() }) + it('renders help', () => { + render( + + ) + expect(document.querySelector('input')).toHaveAttribute( + 'aria-describedby' + ) + expect( + document.querySelector('input').getAttribute('aria-describedby') + ).toBe(document.querySelector('.dnb-input__suffix').id) + expect( + document + .querySelector('.dnb-help-button') + .getAttribute('aria-describedby') + ).toBe(document.querySelector('.dnb-tooltip__content').id) + }) + it('renders label', () => { render() expect(screen.getByLabelText('Number label')).toBeInTheDocument() diff --git a/packages/dnb-eufemia/src/extensions/forms/Field/Number/__tests__/__image_snapshots__/fieldnumber-have-to-match-widths.snap.png b/packages/dnb-eufemia/src/extensions/forms/Field/Number/__tests__/__image_snapshots__/fieldnumber-have-to-match-widths.snap.png index 8714247f75c..d15b498de28 100644 Binary files a/packages/dnb-eufemia/src/extensions/forms/Field/Number/__tests__/__image_snapshots__/fieldnumber-have-to-match-widths.snap.png and b/packages/dnb-eufemia/src/extensions/forms/Field/Number/__tests__/__image_snapshots__/fieldnumber-have-to-match-widths.snap.png differ diff --git a/packages/dnb-eufemia/src/extensions/forms/Field/Number/stories/Number.stories.tsx b/packages/dnb-eufemia/src/extensions/forms/Field/Number/stories/Number.stories.tsx index 1bf0c9264d1..25de54498cb 100644 --- a/packages/dnb-eufemia/src/extensions/forms/Field/Number/stories/Number.stories.tsx +++ b/packages/dnb-eufemia/src/extensions/forms/Field/Number/stories/Number.stories.tsx @@ -1,4 +1,5 @@ import { Field } from '../../..' +import { Flex } from '../../../../../components' export default { title: 'Eufemia/Extensions/Forms/Number', @@ -6,8 +7,8 @@ export default { export const Number = () => { return ( - <> - + + { // validateInitially disabled /> - + + ) } diff --git a/packages/dnb-eufemia/src/extensions/forms/Field/Number/style/dnb-number.scss b/packages/dnb-eufemia/src/extensions/forms/Field/Number/style/dnb-number.scss index a6d181c511a..340b0b6590b 100644 --- a/packages/dnb-eufemia/src/extensions/forms/Field/Number/style/dnb-number.scss +++ b/packages/dnb-eufemia/src/extensions/forms/Field/Number/style/dnb-number.scss @@ -127,5 +127,16 @@ width: var(--number-control-button-width--large); } } + &--has-controls.dnb-forms-field-block__contents--width-stretch { + .dnb-button--control-before, + .dnb-button--control-after { + width: var(--number-control-button-width--large); + } + + /* stylelint-disable-next-line no-descending-specificity */ + .dnb-input__border { + flex-grow: 1; + } + } } } diff --git a/packages/dnb-eufemia/src/extensions/forms/Field/Password/Password.tsx b/packages/dnb-eufemia/src/extensions/forms/Field/Password/Password.tsx index f6dc843f4ea..df2bce2d23f 100644 --- a/packages/dnb-eufemia/src/extensions/forms/Field/Password/Password.tsx +++ b/packages/dnb-eufemia/src/extensions/forms/Field/Password/Password.tsx @@ -143,7 +143,6 @@ function Password({ ? IconView : IconViewOff } - // status={hasError ? 'error' : undefined} disabled={disabled} skeleton={sharedContext.skeleton} onClick={toggleVisibility} @@ -170,6 +169,7 @@ function Password({ aria-describedby={id + '-submit-button'} submitElement={} disabled={disabled} + size={size} {...props} /> ) diff --git a/packages/dnb-eufemia/src/extensions/forms/Field/Password/__tests__/Password.test.tsx b/packages/dnb-eufemia/src/extensions/forms/Field/Password/__tests__/Password.test.tsx index c2a05498572..3ca113bd1f3 100644 --- a/packages/dnb-eufemia/src/extensions/forms/Field/Password/__tests__/Password.test.tsx +++ b/packages/dnb-eufemia/src/extensions/forms/Field/Password/__tests__/Password.test.tsx @@ -84,6 +84,14 @@ describe('Password component', () => { ) }) + it('sets correct class when size prop is large', () => { + render() + + expect(document.querySelector('.dnb-input')).toHaveClass( + 'dnb-input--large' + ) + }) + it('has aria-describedby and aria-controls', () => { render() diff --git a/packages/dnb-eufemia/src/extensions/forms/Field/Password/stories/Password.stories.tsx b/packages/dnb-eufemia/src/extensions/forms/Field/Password/stories/Password.stories.tsx index 7b8786590ff..e23f0b3056c 100644 --- a/packages/dnb-eufemia/src/extensions/forms/Field/Password/stories/Password.stories.tsx +++ b/packages/dnb-eufemia/src/extensions/forms/Field/Password/stories/Password.stories.tsx @@ -1,4 +1,5 @@ -import { Field } from '../../../' +import { Field, Form } from '../../../' +import { Flex } from '../../../../../components' import InputPassword from '../../../../../components/input/InputPassword' import { Provider } from '../../../../../shared' @@ -8,39 +9,48 @@ export default { export const Password = () => { return ( - <> - console.log('Gjemmer seg', e)} - on_show_password={(e) => console.log('Viser seg', e)} - /> - - console.log('onChange', e)} - onFocus={(e) => console.log('onBlur', e)} - onBlur={(e) => console.log('onFocus', e)} - onShowPassword={(e) => console.log('show camel', e)} - onHidePassword={(e) => console.log('hide camel', e)} - on_show_password={(e) => console.log('show snake', e)} - on_hide_password={(e) => console.log('hide snake', e)} + + + console.log('Gjemmer seg', e)} + on_show_password={(e) => console.log('Viser seg', e)} /> - - - console.log('onChange', e)} - onFocus={(e) => console.log('onBlur', e)} - onBlur={(e) => console.log('onFocus', e)} - onShowPassword={(e) => console.log('show camel', e)} - onHidePassword={(e) => console.log('hide camel', e)} - on_show_password={(e) => console.log('show snake', e)} - on_hide_password={(e) => console.log('hide snake', e)} - /> - - + + console.log('onChange', e)} + onFocus={(e) => console.log('onBlur', e)} + onBlur={(e) => console.log('onFocus', e)} + onShowPassword={(e) => console.log('show camel', e)} + onHidePassword={(e) => console.log('hide camel', e)} + on_show_password={(e) => console.log('show snake', e)} + on_hide_password={(e) => console.log('hide snake', e)} + /> + + + console.log('onChange', e)} + onFocus={(e) => console.log('onBlur', e)} + onBlur={(e) => console.log('onFocus', e)} + onShowPassword={(e) => console.log('show camel', e)} + onHidePassword={(e) => console.log('hide camel', e)} + on_show_password={(e) => console.log('show snake', e)} + on_hide_password={(e) => console.log('hide snake', e)} + /> + + + + + ) } diff --git a/packages/dnb-eufemia/src/extensions/forms/Field/String/__tests__/String.test.tsx b/packages/dnb-eufemia/src/extensions/forms/Field/String/__tests__/String.test.tsx index b3824a8201b..dcd7668eef5 100644 --- a/packages/dnb-eufemia/src/extensions/forms/Field/String/__tests__/String.test.tsx +++ b/packages/dnb-eufemia/src/extensions/forms/Field/String/__tests__/String.test.tsx @@ -52,6 +52,25 @@ describe('Field.String', () => { ).toBeInTheDocument() }) + it('renders help', () => { + render( + + ) + expect(document.querySelector('input')).toHaveAttribute( + 'aria-describedby' + ) + expect( + document.querySelector('input').getAttribute('aria-describedby') + ).toBe(document.querySelector('.dnb-input__suffix').id) + expect( + document + .querySelector('.dnb-help-button') + .getAttribute('aria-describedby') + ).toBe(document.querySelector('.dnb-tooltip__content').id) + }) + it('renders label once', () => { render() expect(screen.getByLabelText('The label')).toBeInTheDocument() diff --git a/packages/dnb-eufemia/src/extensions/forms/Field/Toggle/Toggle.tsx b/packages/dnb-eufemia/src/extensions/forms/Field/Toggle/Toggle.tsx index 85710eadbab..ae30c839b0b 100644 --- a/packages/dnb-eufemia/src/extensions/forms/Field/Toggle/Toggle.tsx +++ b/packages/dnb-eufemia/src/extensions/forms/Field/Toggle/Toggle.tsx @@ -1,11 +1,11 @@ import React, { useCallback } from 'react' import classnames from 'classnames' -import { Checkbox, ToggleButton } from '../../../../components' +import { Checkbox, HelpButton, ToggleButton } from '../../../../components' import ButtonRow from '../../Form/ButtonRow' import FieldBlock from '../../FieldBlock' import { useFieldProps } from '../../hooks' -import { FieldProps } from '../../types' +import { FieldHelpProps, FieldProps } from '../../types' import { pickSpacingProps } from '../../../../components/flex/utils' import ToggleButtonGroupContext from '../../../../components/toggle-button/ToggleButtonGroupContext' import useTranslation from '../../hooks/useTranslation' @@ -18,7 +18,7 @@ export type ToggleProps = { textOff?: string } -export type Props = FieldProps & ToggleProps +export type Props = FieldHelpProps & FieldProps & ToggleProps function Toggle(props: Props) { const translations = useTranslation().BooleanField @@ -41,6 +41,7 @@ function Toggle(props: Props) { textOn, textOff, value, + help, info, warning, error, @@ -82,6 +83,10 @@ function Toggle(props: Props) { disabled, } + const suffix = help ? ( + {help.content} + ) : undefined + const isOn = value === valueOn const isOff = value === valueOff @@ -102,6 +107,7 @@ function Toggle(props: Props) { checked={isOn} disabled={disabled} status={hasError ? 'error' : undefined} + suffix={suffix} onChange={handleCheckboxChange} {...htmlAttributes} /> @@ -120,6 +126,7 @@ function Toggle(props: Props) { checked={isOn} disabled={disabled} status={hasError ? 'error' : undefined} + suffix={suffix} value={value ? 'true' : 'false'} on_change={handleCheckboxChange} {...htmlAttributes} @@ -136,6 +143,7 @@ function Toggle(props: Props) { onChange: handleToggleChange, status: hasError ? 'error' : undefined, disabled, + suffix, }} > { describe('variants', () => { describe('button', () => { + it('renders label', () => { + render( + + ) + expect(screen.getByText('Toggle label')).toBeInTheDocument() + }) + + it('renders help', () => { + render( + + ) + expect(document.querySelector('button')).toHaveAttribute( + 'aria-describedby' + ) + expect( + document.querySelector('button').getAttribute('aria-describedby') + ).toBe(document.querySelector('.dnb-toggle-button__suffix').id) + expect( + document + .querySelector('.dnb-help-button') + .getAttribute('aria-describedby') + ).toBe(document.querySelector('.dnb-tooltip__content').id) + }) + it('should render correct HTML', () => { const onChange = jest.fn() @@ -167,6 +201,40 @@ describe('Field.Toggle', () => { }) describe('buttons', () => { + it('renders label', () => { + render( + + ) + expect(screen.getByText('Toggle label')).toBeInTheDocument() + }) + + it('renders help', () => { + render( + + ) + expect(document.querySelector('button')).toHaveAttribute( + 'aria-describedby' + ) + expect( + document.querySelector('button').getAttribute('aria-describedby') + ).toBe(document.querySelector('.dnb-toggle-button__suffix').id) + expect( + document + .querySelector('.dnb-help-button') + .getAttribute('aria-describedby') + ).toBe(document.querySelector('.dnb-tooltip__content').id) + }) + it('should render correct HTML', () => { const onChange = jest.fn() @@ -342,6 +410,40 @@ describe('Field.Toggle', () => { }) describe('checkbox-button', () => { + it('renders label', () => { + render( + + ) + expect(screen.getByText('Toggle label')).toBeInTheDocument() + }) + + it('renders help', () => { + render( + + ) + expect(document.querySelector('button')).toHaveAttribute( + 'aria-describedby' + ) + expect( + document.querySelector('button').getAttribute('aria-describedby') + ).toBe(document.querySelector('.dnb-toggle-button__suffix').id) + expect( + document + .querySelector('.dnb-help-button') + .getAttribute('aria-describedby') + ).toBe(document.querySelector('.dnb-tooltip__content').id) + }) + it('should render correct HTML', () => { const onChange = jest.fn() @@ -473,6 +575,40 @@ describe('Field.Toggle', () => { }) describe('checkbox', () => { + it('renders label', () => { + render( + + ) + expect(screen.getByLabelText('Toggle label')).toBeInTheDocument() + }) + + it('renders help', () => { + render( + + ) + expect(document.querySelector('input')).toHaveAttribute( + 'aria-describedby' + ) + expect( + document.querySelector('input').getAttribute('aria-describedby') + ).toBe(document.querySelector('.dnb-checkbox__suffix').id) + expect( + document + .querySelector('.dnb-help-button') + .getAttribute('aria-describedby') + ).toBe(document.querySelector('.dnb-tooltip__content').id) + }) + it('should render correct HTML', () => { const onChange = jest.fn() diff --git a/packages/dnb-eufemia/src/extensions/forms/Form/Appearance/Appearance.tsx b/packages/dnb-eufemia/src/extensions/forms/Form/Appearance/Appearance.tsx index 8c145db55b8..51c4bb9b23d 100644 --- a/packages/dnb-eufemia/src/extensions/forms/Form/Appearance/Appearance.tsx +++ b/packages/dnb-eufemia/src/extensions/forms/Form/Appearance/Appearance.tsx @@ -21,4 +21,5 @@ function FormAppearance({ children, size = null, ...rest }: Props) { ) } +FormAppearance._supportsSpacingProps = 'children' export default FormAppearance diff --git a/packages/dnb-eufemia/src/extensions/forms/Form/Appearance/__tests__/Appearance.test.tsx b/packages/dnb-eufemia/src/extensions/forms/Form/Appearance/__tests__/Appearance.test.tsx index ac159025a5c..0a9644c899e 100644 --- a/packages/dnb-eufemia/src/extensions/forms/Form/Appearance/__tests__/Appearance.test.tsx +++ b/packages/dnb-eufemia/src/extensions/forms/Form/Appearance/__tests__/Appearance.test.tsx @@ -3,6 +3,10 @@ import { render } from '@testing-library/react' import { Form, Field } from '../../..' describe('Form.Appearance', () => { + it('should have constant of _supportsSpacingProps="children"', () => { + expect(Form.Appearance._supportsSpacingProps).toBe('children') + }) + describe('size', () => { it('String', () => { const { rerender } = render( diff --git a/packages/dnb-eufemia/src/extensions/forms/Form/FieldProps/FieldProps.tsx b/packages/dnb-eufemia/src/extensions/forms/Form/FieldProps/FieldProps.tsx index 0335456b8a9..736075b4b03 100644 --- a/packages/dnb-eufemia/src/extensions/forms/Form/FieldProps/FieldProps.tsx +++ b/packages/dnb-eufemia/src/extensions/forms/Form/FieldProps/FieldProps.tsx @@ -39,7 +39,7 @@ export type FieldPropsProps = FieldProps & { FormStatus?: { globalStatus: FormStatusProps } } -export default function FieldPropsProvider(props: FieldPropsProps) { +function FieldPropsProvider(props: FieldPropsProps) { const { children, formElement, @@ -175,3 +175,6 @@ function transformTranslations( return result } + +FieldPropsProvider._supportsSpacingProps = 'children' +export default FieldPropsProvider diff --git a/packages/dnb-eufemia/src/extensions/forms/Form/FieldProps/__tests__/FieldProps.test.tsx b/packages/dnb-eufemia/src/extensions/forms/Form/FieldProps/__tests__/FieldProps.test.tsx index 9c52661421d..8aa7406b9d7 100644 --- a/packages/dnb-eufemia/src/extensions/forms/Form/FieldProps/__tests__/FieldProps.test.tsx +++ b/packages/dnb-eufemia/src/extensions/forms/Form/FieldProps/__tests__/FieldProps.test.tsx @@ -6,6 +6,10 @@ import nbNO from '../../../constants/locales/nb-NO' const nb = nbNO['nb-NO'] describe('Form.FieldProps', () => { + it('should have constant of _supportsSpacingProps="children"', () => { + expect(Form.FieldProps._supportsSpacingProps).toBe('children') + }) + describe('disable', () => { it('should disable the input and button', () => { render( diff --git a/packages/dnb-eufemia/src/extensions/forms/Form/Section/__tests__/Section.test.tsx b/packages/dnb-eufemia/src/extensions/forms/Form/Section/__tests__/Section.test.tsx index 6b2c6103e03..2940364137e 100644 --- a/packages/dnb-eufemia/src/extensions/forms/Form/Section/__tests__/Section.test.tsx +++ b/packages/dnb-eufemia/src/extensions/forms/Form/Section/__tests__/Section.test.tsx @@ -44,6 +44,10 @@ describe('Form.Section', () => { ) } + it('should have constant of _supportsSpacingProps="children"', () => { + expect(Form.Section._supportsSpacingProps).toBe('children') + }) + it('should throw then "path" without slash was given', () => { const log = jest.spyOn(console, 'error').mockImplementation() diff --git a/packages/dnb-eufemia/src/extensions/forms/Wizard/Container/WizardContainer.tsx b/packages/dnb-eufemia/src/extensions/forms/Wizard/Container/WizardContainer.tsx index 91f9c9d1c55..2204e207db3 100644 --- a/packages/dnb-eufemia/src/extensions/forms/Wizard/Container/WizardContainer.tsx +++ b/packages/dnb-eufemia/src/extensions/forms/Wizard/Container/WizardContainer.tsx @@ -300,7 +300,7 @@ function WizardContainer(props: Props) { useLayoutEffect(() => { updateTitlesRef.current?.() // eslint-disable-next-line react-hooks/exhaustive-deps - }, [children]) + }, [titlesRef.current]) if (!hasContext) { warn('You may wrap Wizard.Container in Form.Handler') diff --git a/packages/dnb-eufemia/src/extensions/forms/Wizard/Container/__tests__/WizardContainer.test.tsx b/packages/dnb-eufemia/src/extensions/forms/Wizard/Container/__tests__/WizardContainer.test.tsx index 3e6608112dd..f6438969a97 100644 --- a/packages/dnb-eufemia/src/extensions/forms/Wizard/Container/__tests__/WizardContainer.test.tsx +++ b/packages/dnb-eufemia/src/extensions/forms/Wizard/Container/__tests__/WizardContainer.test.tsx @@ -451,108 +451,179 @@ describe('Wizard.Container', () => { }) }) - it('should not render inactive steps', async () => { - render( - - - Step 1 - + describe('dynamic steps', () => { + it('should not render inactive steps', () => { + render( + + + Step 1 + - - Step 2 - - - ) + + Step 2 + + + ) - expect(output()).toHaveTextContent('Step 2') - expect( - document.querySelectorAll('.dnb-step-indicator__item') - ).toHaveLength(1) - }) + expect(output()).toHaveTextContent('Step 2') + expect( + document.querySelectorAll('.dnb-step-indicator__item') + ).toHaveLength(1) + }) - it('should render dynamically enabled steps', async () => { - const { rerender } = render( - - - Step 1 - + it('should render dynamically enabled steps', () => { + const { rerender } = render( + + + Step 1 + - - Step 2 - - - ) + + Step 2 + + + ) - expect(output()).toHaveTextContent('Step 2') - expect( - document.querySelector('.dnb-step-indicator') - ).toHaveTextContent('Steg 1 av 1') - expect( - document.querySelectorAll('.dnb-step-indicator__item') - ).toHaveLength(1) + expect(output()).toHaveTextContent('Step 2') + expect( + document.querySelector('.dnb-step-indicator') + ).toHaveTextContent('Steg 1 av 1') + expect( + document.querySelectorAll('.dnb-step-indicator__item') + ).toHaveLength(1) + + rerender( + + + Step 1 + + - rerender( - - - Step 1 - - + + Step 2 + + + ) - - Step 2 - - - ) + expect(output()).toHaveTextContent('Step 1') + expect( + document.querySelector('.dnb-step-indicator') + ).toHaveTextContent('Steg 2 av 2') + expect( + document.querySelectorAll('.dnb-step-indicator__item') + ).toHaveLength(2) + + rerender( + + + Step 1 + + - expect(output()).toHaveTextContent('Step 1') - expect( - document.querySelector('.dnb-step-indicator') - ).toHaveTextContent('Steg 2 av 2') - expect( - document.querySelectorAll('.dnb-step-indicator__item') - ).toHaveLength(2) + + Step 2 + + + ) - rerender( - - - Step 1 - - + expect(output()).toHaveTextContent('Step 2') + expect( + document.querySelector('.dnb-step-indicator') + ).toHaveTextContent('Steg 1 av 1') + expect( + document.querySelectorAll('.dnb-step-indicator__item') + ).toHaveLength(1) + + rerender( + + + Step 1 + + - - Step 2 - - - ) + + Step 2 + + + ) - expect(output()).toHaveTextContent('Step 2') - expect( - document.querySelector('.dnb-step-indicator') - ).toHaveTextContent('Steg 1 av 1') - expect( - document.querySelectorAll('.dnb-step-indicator__item') - ).toHaveLength(1) + expect(output()).toBeNull() + expect( + document.querySelector('.dnb-step-indicator') + ).toHaveTextContent('') + expect( + document.querySelectorAll('.dnb-step-indicator__item') + ).toHaveLength(0) + }) - rerender( - - - Step 1 - - + it('should update active steps without rerendering', async () => { + const initialData = { + showStep1: true, + showStep2: true, + } - - Step 2 - - - ) + const Step1 = () => { + const { data } = Form.useData() + return ( + + Step 1 + + + + ) + } - expect(output()).toBeNull() - expect( - document.querySelector('.dnb-step-indicator') - ).toHaveTextContent('') - expect( - document.querySelectorAll('.dnb-step-indicator__item') - ).toHaveLength(0) + const Step2 = () => { + const { data } = Form.useData() + return ( + + Step 2 + + + + ) + } + + const MyForm = () => { + return ( + + + + + + + ) + } + + render() + + expect(output()).toHaveTextContent('Step 1') + expect( + document.querySelectorAll('.dnb-step-indicator__item') + ).toHaveLength(2) + expect( + document.querySelector('.dnb-forms-next-button') + ).toBeInTheDocument() + + await userEvent.click(document.querySelector('#toggleStep2')) + + expect(output()).toHaveTextContent('Step 1') + expect( + document.querySelectorAll('.dnb-step-indicator__item') + ).toHaveLength(1) + expect( + document.querySelector('.dnb-forms-next-button') + ).not.toBeInTheDocument() + + await userEvent.click(document.querySelector('#toggleStep2')) + + expect( + document.querySelectorAll('.dnb-step-indicator__item') + ).toHaveLength(2) + expect( + document.querySelector('.dnb-forms-next-button') + ).toBeInTheDocument() + }) }) it('should support drawer variant', () => { diff --git a/packages/dnb-eufemia/src/extensions/forms/Wizard/Step/Step.tsx b/packages/dnb-eufemia/src/extensions/forms/Wizard/Step/Step.tsx index bce03d825c7..9046dce024d 100644 --- a/packages/dnb-eufemia/src/extensions/forms/Wizard/Step/Step.tsx +++ b/packages/dnb-eufemia/src/extensions/forms/Wizard/Step/Step.tsx @@ -80,7 +80,7 @@ function Step(props: Props) { if (activeIndex !== index || active === false) { // Another step is active - return null + return <> } const fieldProps = diff --git a/packages/dnb-eufemia/src/extensions/forms/Wizard/stories/Wizard.stories.tsx b/packages/dnb-eufemia/src/extensions/forms/Wizard/stories/Wizard.stories.tsx index 0cae066f97d..8d92fc97fa1 100644 --- a/packages/dnb-eufemia/src/extensions/forms/Wizard/stories/Wizard.stories.tsx +++ b/packages/dnb-eufemia/src/extensions/forms/Wizard/stories/Wizard.stories.tsx @@ -41,10 +41,24 @@ export const Basic = () => { ) } -const Step1 = (props) => { +const Step1 = () => { + const { data } = Form.useData() return ( - + Heading Step 1 + + +

Contents

Contents

@@ -57,9 +71,10 @@ const Step1 = (props) => {
) } -const Step2 = (props) => { +const Step2 = () => { + const { data } = Form.useData() return ( - + Heading Step 2

Contents

@@ -69,11 +84,12 @@ const Step2 = (props) => {
) } -const Step3 = (props) => { +const Step3 = () => { + const { data } = Form.useData() const { summaryTitle } = Form.useLocale().Step return ( - + Summary

Contents

@@ -85,47 +101,23 @@ const Step3 = (props) => { ) } -export const WizardContainerFlex = () => { - const [step1, setStep1] = React.useState(true) - const [step2, setStep2] = React.useState(true) - const [step3, setStep3] = React.useState(true) +const initialData = { + step1: true, + step2: true, + step3: true, +} + +export const WizardDynamicSteps = () => { return ( <> - { - setStep1(!step1) - }} - /> - { - setStep2(!step2) - }} - /> - { - setStep3(!step3) - }} - /> - + - {/* - - */} - {step1 && } - {step2 && } - {step3 && } + + + + {/* {data?.step1 && } + {data?.step2 && } + {data?.step3 && } */} diff --git a/packages/dnb-eufemia/src/extensions/payment-card/PaymentCard.js b/packages/dnb-eufemia/src/extensions/payment-card/PaymentCard.js index 1fe13ce0b0c..68678b8d4a8 100644 --- a/packages/dnb-eufemia/src/extensions/payment-card/PaymentCard.js +++ b/packages/dnb-eufemia/src/extensions/payment-card/PaymentCard.js @@ -84,7 +84,6 @@ export default class PaymentCard extends React.PureComponent { ...spacingPropTypes, - class: PropTypes.string, className: PropTypes.string, children: PropTypes.oneOfType([ PropTypes.string, @@ -103,7 +102,6 @@ export default class PaymentCard extends React.PureComponent { raw_data: null, skeleton: false, - class: null, className: null, children: null, diff --git a/packages/dnb-eufemia/src/fragments/drawer-list/DrawerList.d.ts b/packages/dnb-eufemia/src/fragments/drawer-list/DrawerList.d.ts index 3b9d4aae20a..ee8fbc06e87 100644 --- a/packages/dnb-eufemia/src/fragments/drawer-list/DrawerList.d.ts +++ b/packages/dnb-eufemia/src/fragments/drawer-list/DrawerList.d.ts @@ -145,7 +145,6 @@ export interface DrawerListProps { */ skip_keysearch?: boolean; opened?: boolean; - class?: string; /** * The data we want to fill the list with. Provide the data as a JSON string, array, or object in the specified data structure. If you don't have to define a value, you can also send in a function which will be called once the user opens the DrawerList. */ diff --git a/packages/dnb-eufemia/src/fragments/drawer-list/DrawerList.js b/packages/dnb-eufemia/src/fragments/drawer-list/DrawerList.js index 2b8d89f087f..5a75351f918 100644 --- a/packages/dnb-eufemia/src/fragments/drawer-list/DrawerList.js +++ b/packages/dnb-eufemia/src/fragments/drawer-list/DrawerList.js @@ -164,7 +164,6 @@ class DrawerListInstance extends React.PureComponent { ignore_events, options_render, className, - class: _className, cache_hash: _cache_hash, // eslint-disable-line wrapper_element: _wrapper_element, // eslint-disable-line triangle_position: _triangle_position, // eslint-disable-line @@ -224,7 +223,6 @@ class DrawerListInstance extends React.PureComponent { isTrue(no_scroll_animation) && 'dnb-drawer-list--no-scroll-animation', createSpacingClasses(props), - _className, className ), ...attributes, @@ -411,7 +409,6 @@ DrawerList.Options = React.memo( const { children, className, - class: _className, triangleRef = null, cache_hash, // eslint-disable-line showFocusRing, @@ -423,8 +420,7 @@ DrawerList.Options = React.memo( className={classnames( 'dnb-drawer-list__options', showFocusRing && 'dnb-drawer-list__options--focusring', - className, - _className + className )} {...rest} ref={ref} @@ -452,14 +448,12 @@ DrawerList.Options.propTypes = { cache_hash: PropTypes.string, showFocusRing: PropTypes.bool, className: PropTypes.string, - class: PropTypes.string, triangleRef: PropTypes.object, } DrawerList.Options.defaultProps = { cache_hash: null, showFocusRing: false, className: null, - class: null, triangleRef: null, } @@ -470,7 +464,6 @@ DrawerList.Item = React.forwardRef((props, ref) => { hash, // eslint-disable-line children, // eslint-disable-line className, // eslint-disable-line - class: _className, // eslint-disable-line on_click, // eslint-disable-line selected, // eslint-disable-line active, // eslint-disable-line @@ -481,7 +474,6 @@ DrawerList.Item = React.forwardRef((props, ref) => { const params = { className: classnames( className, - _className, 'dnb-drawer-list__option', selected && 'dnb-drawer-list__option--selected', active && 'dnb-drawer-list__option--focus' @@ -527,7 +519,6 @@ DrawerList.Item.propTypes = { PropTypes.object, ]).isRequired, className: PropTypes.string, - class: PropTypes.string, on_click: PropTypes.func, selected: PropTypes.bool, active: PropTypes.bool, @@ -537,7 +528,6 @@ DrawerList.Item.defaultProps = { role: 'option', hash: '', className: null, - class: null, on_click: null, selected: null, active: null, diff --git a/packages/dnb-eufemia/src/fragments/drawer-list/DrawerListHelpers.js b/packages/dnb-eufemia/src/fragments/drawer-list/DrawerListHelpers.js index f9d905b8ce7..dbf53de5c02 100644 --- a/packages/dnb-eufemia/src/fragments/drawer-list/DrawerListHelpers.js +++ b/packages/dnb-eufemia/src/fragments/drawer-list/DrawerListHelpers.js @@ -62,7 +62,6 @@ export const drawerListPropTypes = { prevent_focus: PropTypes.oneOfType([PropTypes.string, PropTypes.bool]), skip_keysearch: PropTypes.oneOfType([PropTypes.string, PropTypes.bool]), opened: PropTypes.oneOfType([PropTypes.string, PropTypes.bool]), - class: PropTypes.string, data: PropTypes.oneOfType([ PropTypes.oneOfType([ PropTypes.string, @@ -157,7 +156,6 @@ export const drawerListDefaultProps = { independent_width: false, skip_keysearch: false, opened: null, - class: null, data: null, prepared_data: null, raw_data: null,