diff --git a/.changeset/three-ducks-chew.md b/.changeset/three-ducks-chew.md new file mode 100644 index 0000000000..b92e847bf2 --- /dev/null +++ b/.changeset/three-ducks-chew.md @@ -0,0 +1,6 @@ +--- +"@digdir/designsystemet-css": patch +"@digdir/designsystemet-react": patch +--- + +Fieldset: Style using css attributes diff --git a/packages/css/fieldset.css b/packages/css/fieldset.css index eb399f8d3a..d9c7b73654 100644 --- a/packages/css/fieldset.css +++ b/packages/css/fieldset.css @@ -1,43 +1,44 @@ .ds-fieldset { + --dsc-fieldset-icon-size: 1.2em; + --dsc-fieldset-gap: var(--ds-spacing-2); + margin: 0; padding: 0; border: 0; min-width: 0; -} - -.ds-fieldset--spacing { - display: flex; - flex-direction: column; - gap: var(--ds-spacing-2); -} - -.ds-fieldset__description { - color: var(--ds-color-neutral-text-subtle); - margin-bottom: var(--ds-spacing-2); -} - -.ds-fieldset__legend { - display: contents; -} - -.ds-fieldset--readonly .ds-fieldset__legend__content { - display: inline-flex; -} - -.ds-fieldset:not(:has(.ds-fieldset__description)) .ds-fieldset__legend__content { - margin-bottom: var(--ds-spacing-2); -} - -.ds-fieldset--readonly .ds-fieldset__readonly__icon { - height: 1.2em; - width: 1.2em; -} - -.ds-fieldset:disabled .ds-fieldset__legend, -.ds-fieldset:disabled .ds-fieldset__description { - color: var(--ds-color-neutral-border-subtle); -} -.ds-fieldset__error-message { - display: contents; + & > :not(:last-child) { + margin-bottom: var(--ds-spacing-2); /* Use margin as fieldset does not play nice with display: flex */ + } + + & > legend { + display: inline-flex; + } + + & > legend:empty { + display: none; + } + + &[data-hidelegend] > legend, + &[data-hidelegend] > legend + p { + @composes ds-sr-only from '../css/utilities.css'; + } + + &[data-readonly] > legend::before { + content: ''; + background: currentcolor; + height: var(--dsc-fieldset-icon-size); + mask: center/contain no-repeat + url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' aria-hidden='true' viewBox='0 0 24 24'%3E%3Cpath fill-rule='evenodd' d='M12 2.25A4.75 4.75 0 0 0 7.25 7v2.25H7A1.75 1.75 0 0 0 5.25 11v9c0 .41.34.75.75.75h12a.75.75 0 0 0 .75-.75v-9A1.75 1.75 0 0 0 17 9.25h-.25V7A4.75 4.75 0 0 0 12 2.25m3.25 7V7a3.25 3.25 0 0 0-6.5 0v2.25zM12 13a1.5 1.5 0 0 0-.75 2.8V17a.75.75 0 0 0 1.5 0v-1.2A1.5 1.5 0 0 0 12 13'/%3E%3C/svg%3E"); + width: var(--dsc-fieldset-icon-size); + } + + & > legend + p { + color: var(--ds-color-neutral-text-subtle); + } + + &:disabled > legend, + &:disabled > legend + p { + color: var(--ds-color-neutral-border-subtle); + } } diff --git a/packages/react/src/components/form/Fieldset/Fieldset.tsx b/packages/react/src/components/form/Fieldset/Fieldset.tsx index 7e8878c4c7..08b718c28e 100644 --- a/packages/react/src/components/form/Fieldset/Fieldset.tsx +++ b/packages/react/src/components/form/Fieldset/Fieldset.tsx @@ -1,13 +1,11 @@ -import { PadlockLockedFillIcon } from '@navikt/aksel-icons'; import cl from 'clsx/lite'; import type { FieldsetHTMLAttributes, ReactNode } from 'react'; import { forwardRef, useContext } from 'react'; import { ErrorMessage, Label, Paragraph } from '../../Typography'; -import type { FormFieldProps } from '../useFormField'; +import { type FormFieldProps, useFormField } from '../useFormField'; import { FieldsetContext } from './FieldsetContext'; -import { useFieldset } from './useFieldset'; export type FieldsetProps = { /** A description of the fieldset. This will appear below the legend. */ @@ -27,7 +25,7 @@ export type FieldsetProps = { FieldsetHTMLAttributes; export const Fieldset = forwardRef( - (props, ref) => { + function Fieldset(props, ref) { const { children, legend, @@ -38,71 +36,43 @@ export const Fieldset = forwardRef( ...rest } = props; - const { fieldsetProps, size, readOnly, errorId, hasError, descriptionId } = - useFieldset(props); - const fieldset = useContext(FieldsetContext); + const { inputProps, size, readOnly, errorId, hasError, descriptionId } = + useFormField(props, 'fieldset'); return (
- {description && ( - -
- {description} -
+ {!!description && ( + + {description} )} {children}
{hasError && {error}}
@@ -111,5 +81,3 @@ export const Fieldset = forwardRef( ); }, ); - -Fieldset.displayName = 'Fieldset'; diff --git a/packages/react/src/components/form/Fieldset/useFieldset.ts b/packages/react/src/components/form/Fieldset/useFieldset.ts deleted file mode 100644 index 7236a84182..0000000000 --- a/packages/react/src/components/form/Fieldset/useFieldset.ts +++ /dev/null @@ -1,17 +0,0 @@ -import { useFormField } from '../useFormField'; - -import type { FieldsetProps } from './Fieldset'; - -/** Handles fieldset props and state */ -export const useFieldset = (props: FieldsetProps) => { - const formField = useFormField(props, 'fieldset'); - const { inputProps } = formField; - - return { - ...formField, - fieldsetProps: { - 'aria-invalid': inputProps['aria-invalid'], - 'aria-describedby': inputProps['aria-describedby'], - }, - }; -};