diff --git a/packages/react/src/components/Checkbox/Checkbox.stories.mdx b/packages/react/src/components/Checkbox/Checkbox.stories.mdx
index 4d8c4b1580..9f10119fd4 100644
--- a/packages/react/src/components/Checkbox/Checkbox.stories.mdx
+++ b/packages/react/src/components/Checkbox/Checkbox.stories.mdx
@@ -41,6 +41,9 @@ import {ArgsTable} from "@storybook/addon-docs";
description: 'Gir sjekkboksen en rød ramme for å indikere en feil.',
control: {type: 'boolean'}
},
+ helpText: {
+ description: 'Legger på en hjelpe-tekst knapp ved siden av labelen til checkboxen.',
+ },
hideLabel: {
description: 'Skjuler teksten til høyre for sjekkboksen, men gjør den tilgjengelig for verktøy som skjermlesere.',
control: {type: 'boolean'}
@@ -100,6 +103,15 @@ Sjekkboksene kan ha flere forskjellige statuser:
>
{Template.bind({})}
+
+ {Template.bind({})}
+
+### Med hjelpetekst
+
+
+ {Template.bind({})}
+
+
+
### Deaktivert
&
Required>;
@@ -28,6 +28,7 @@ export interface CheckboxGroupProps {
description?: ReactNode;
disabled?: boolean;
error?: ReactNode;
+ helpText?: string;
items: CheckboxGroupItem[];
legend?: ReactNode;
onChange?: (names: CheckedNames) => void;
@@ -57,6 +58,7 @@ export const CheckboxGroup = ({
description,
disabled,
error,
+ helpText,
items,
legend,
onChange,
@@ -93,6 +95,7 @@ export const CheckboxGroup = ({
description={description}
disabled={disabled}
error={error}
+ helpText={helpText}
legend={legend}
size={compact ? FieldSetSize.Xsmall : FieldSetSize.Small}
>
@@ -104,6 +107,7 @@ export const CheckboxGroup = ({
description={item.description}
disabled={disabled || item.disabled}
error={!!error}
+ helpText={item.helpText}
key={item.name}
label={item.label}
name={item.name}
diff --git a/packages/react/src/components/FieldSet/FieldSet.module.css b/packages/react/src/components/FieldSet/FieldSet.module.css
index 2534466939..561d444838 100644
--- a/packages/react/src/components/FieldSet/FieldSet.module.css
+++ b/packages/react/src/components/FieldSet/FieldSet.module.css
@@ -4,6 +4,7 @@
--description-color: var(--component-field_description-color-text-default);
--description-margin_top: var(--component-field_description-space-top-small);
--error_message-margin_top: var(--component-fieldset-space-gap-y-small);
+ --help_text-gap: var(--component-field_description-space-top-small);
--font_size: var(--component-checkbox-font_size-sm);
color: var(--color);
@@ -18,6 +19,7 @@
--content-margin_top: var(--component-fieldset-space-gap-y-xsmall);
--description-margin_top: var(--component-field_description-space-top-xsmall);
--error_message-margin_top: var(--component-fieldset-space-gap-y-xsmall);
+ --help_text-gap: var(--component-field_description-space-top-xsmall);
--font_size: var(--component-checkbox-font_size-xs);
}
@@ -29,11 +31,20 @@
opacity: 1;
}
+.legendAndHelpText {
+ display: flex;
+ gap: var(--help_text-gap);
+ padding: 0;
+}
+
.legend {
- font-weight: bold;
padding: 0;
}
+.legendContent {
+ font-weight: bold;
+}
+
.description {
color: var(--description-color);
margin: 0;
diff --git a/packages/react/src/components/FieldSet/FieldSet.stories.mdx b/packages/react/src/components/FieldSet/FieldSet.stories.mdx
index 15e81db225..fbe0ca7fde 100644
--- a/packages/react/src/components/FieldSet/FieldSet.stories.mdx
+++ b/packages/react/src/components/FieldSet/FieldSet.stories.mdx
@@ -31,7 +31,8 @@ export const Template = (args) => {args.children}
children: Her er det noe innhold.
,
legend: 'Dette er en tittel',
description: 'Dette er en beskrivelse av innholdet.',
- size: FieldSetSize.Small
+ size: FieldSetSize.Small,
+ helpText: 'Help',
}}
>
{Template.bind({})}
@@ -41,8 +42,10 @@ export const Template = (args) => {args.children}
## Egenskaper
Det er mulig å legge til en tittel (`legend`) og en beskrivelse (`description`).
-Man kan også vise en feilmelding relatert til gruppen ved å bruke `error`-attributten.
-Setter man `disabled` til `true`, vil alle feltene i gruppen bli deaktivert.
+Man kan legge til en hjelpetekst som vises ved aktivering av hjelpetekst-knappen
+ved å bruke `helpText`-attributten. Man kan også vise en feilmelding relatert til
+gruppen ved å bruke `error`-attributten. Setter man `disabled` til `true`, vil alle
+feltene i gruppen bli deaktivert.
diff --git a/packages/react/src/components/FieldSet/FieldSet.tsx b/packages/react/src/components/FieldSet/FieldSet.tsx
index 2f3b14e518..64bf34e026 100644
--- a/packages/react/src/components/FieldSet/FieldSet.tsx
+++ b/packages/react/src/components/FieldSet/FieldSet.tsx
@@ -1,7 +1,9 @@
-import React, { ReactNode } from 'react';
+import type { ReactNode } from 'react';
+import React from 'react';
import cn from 'classnames';
-import { ErrorMessage } from '../';
+import { ErrorMessage, HelpText } from '../';
+import { HelpTextSize } from '../HelpText/HelpText';
import classes from './FieldSet.module.css';
@@ -12,6 +14,7 @@ export interface FieldSetProps {
description?: ReactNode;
disabled?: boolean;
error?: ReactNode;
+ helpText?: string;
legend?: ReactNode;
size?: FieldSetSize;
}
@@ -28,20 +31,39 @@ export const FieldSet = ({
description,
disabled,
error,
+ helpText,
legend,
size = FieldSetSize.Small,
-}: FieldSetProps) => (
-
- {legend && {legend} }
- {description && {description}
}
- {children}
- {error && (
-
- {error}
-
- )}
-
-);
+}: FieldSetProps) => {
+ const helpTextSize =
+ size === FieldSetSize.Xsmall ? HelpTextSize.Xsmall : HelpTextSize.Small;
+ return (
+
+ {legend && (
+
+
+ {legend}
+ {helpText && (
+
+ {helpText}
+
+ )}
+
+
+ )}
+ {description && {description}
}
+ {children}
+ {error && (
+
+ {error}
+
+ )}
+
+ );
+};
diff --git a/packages/react/src/components/HelpText/HelpText.module.css b/packages/react/src/components/HelpText/HelpText.module.css
index 454f6a8024..1446701198 100644
--- a/packages/react/src/components/HelpText/HelpText.module.css
+++ b/packages/react/src/components/HelpText/HelpText.module.css
@@ -33,11 +33,21 @@
.helpTextIcon {
color: var(--colors-blue-700);
- width: 24px;
- height: 24px;
+ width: var(--help_text-icon-width);
+ height: var(--help_text-icon-height);
}
.helpTextContent {
font-size: var(--font_size-300);
line-height: var(--typography-default-line-height);
}
+
+.helpTextIcon.small {
+ --help_text-icon-width: 24px;
+ --help_text-icon-height: 24px;
+}
+
+.helpTextIcon.xsmall {
+ --help_text-icon-width: 18px;
+ --help_text-icon-height: 18px;
+}
diff --git a/packages/react/src/components/HelpText/HelpText.stories.mdx b/packages/react/src/components/HelpText/HelpText.stories.mdx
index 4fd0c8c1d0..4e5440f275 100644
--- a/packages/react/src/components/HelpText/HelpText.stories.mdx
+++ b/packages/react/src/components/HelpText/HelpText.stories.mdx
@@ -20,6 +20,9 @@ import {ArgsTable} from "@storybook/addon-docs";
title: {
description: 'Tittel som gis til hjelp-ikonet som kan leses av skjermlesere for tilgjengelighet.',
},
+ size: {
+ description: 'Set the size of the help-text button.',
+ },
placement: {
description: 'Bestemmer hvilken side popoveren skal plasseres på, samt om plasseringen skal rettes inn etter hvor triggeren starter eller slutter.',
},
diff --git a/packages/react/src/components/HelpText/HelpText.tsx b/packages/react/src/components/HelpText/HelpText.tsx
index 7251dfd409..2678b729c8 100644
--- a/packages/react/src/components/HelpText/HelpText.tsx
+++ b/packages/react/src/components/HelpText/HelpText.tsx
@@ -4,12 +4,19 @@ import cn from 'classnames';
import { HelptextFilled, Helptext } from '@navikt/ds-icons';
import { Popover, PopoverVariant } from '../Popover';
+import utilClasses from '../../utils/utility.module.css';
import classes from './HelpText.module.css';
+export enum HelpTextSize {
+ Xsmall = 'xsmall',
+ Small = 'small',
+}
+
export interface HelpTextProps extends ButtonHTMLAttributes {
children: string;
- title?: string;
+ title: string;
+ size?: HelpTextSize;
placement?:
| 'top'
| 'bottom'
@@ -31,6 +38,7 @@ export const HelpText = ({
title,
placement = 'right',
onClick,
+ size = HelpTextSize.Small,
...rest
}: HelpTextProps) => {
const [open, setOpen] = useState(false);
@@ -54,16 +62,18 @@ export const HelpText = ({
className={cn(
classes.helpTextIcon,
classes.helpTextIconFilled,
+ classes[size],
className,
)}
- title={title}
data-state={open ? 'open' : 'closed'}
+ aria-hidden={true}
/>
+ {title}
}
>
diff --git a/packages/react/src/components/RadioButton/RadioButton.stories.mdx b/packages/react/src/components/RadioButton/RadioButton.stories.mdx
index 2cc1de4dac..166016b610 100644
--- a/packages/react/src/components/RadioButton/RadioButton.stories.mdx
+++ b/packages/react/src/components/RadioButton/RadioButton.stories.mdx
@@ -41,6 +41,9 @@ import {ArgsTable} from "@storybook/addon-docs";
description: 'Gir radioknappen en rød ramme for å indikere en feil.',
control: {type: 'boolean'}
},
+ helpText: {
+ description: 'Legger på en hjelpe-tekst knapp ved siden av labelen til radioknappen.',
+ },
hideLabel: {
description: 'Skjuler teksten til høyre for radioknappen, men gjør den tilgjengelig for verktøy som skjermlesere.',
control: {type: 'boolean'}
@@ -99,6 +102,15 @@ Radioknappene kan ha flere forskjellige statuser:
>
{Template.bind({})}
+
+ {Template.bind({})}
+
{Template.bind({})}
@@ -104,7 +107,7 @@ Kun én knapp kan være trykket inn av gangen.
{Template.bind({})}
@@ -114,7 +117,25 @@ Kun én knapp kan være trykket inn av gangen.
+ {Template.bind({})}
+
+
+
+### Med hjelpetekst
+
+
{Template.bind({})}
@@ -124,7 +145,7 @@ Kun én knapp kan være trykket inn av gangen.
{Template.bind({})}
diff --git a/packages/react/src/components/RadioGroup/RadioGroup.tsx b/packages/react/src/components/RadioGroup/RadioGroup.tsx
index 365f151bd4..75c13c7b9a 100644
--- a/packages/react/src/components/RadioGroup/RadioGroup.tsx
+++ b/packages/react/src/components/RadioGroup/RadioGroup.tsx
@@ -29,6 +29,7 @@ export interface RadioGroupProps {
description?: ReactNode;
disabled?: boolean;
error?: ReactNode;
+ helpText?: string;
items: RadioGroupItem[];
legend?: ReactNode;
name: string;
@@ -43,6 +44,7 @@ export const RadioGroup = ({
description,
disabled,
error,
+ helpText,
items,
legend,
name,
@@ -84,6 +86,7 @@ export const RadioGroup = ({
description={description}
disabled={disabled}
error={error}
+ helpText={helpText}
legend={legend}
size={fieldSetSize}
>
@@ -101,6 +104,7 @@ export const RadioGroup = ({
checked={radio.value === checkedValue}
disabled={disabled || radio.disabled}
error={!!error}
+ helpText={radio.helpText}
key={radio.value}
name={name}
onChange={changeHandler(radio.value)}
diff --git a/packages/react/src/components/_CheckboxRadioTemplate/CheckboxRadioTemplate.module.css b/packages/react/src/components/_CheckboxRadioTemplate/CheckboxRadioTemplate.module.css
index c8f1b53b75..27e42d42df 100644
--- a/packages/react/src/components/_CheckboxRadioTemplate/CheckboxRadioTemplate.module.css
+++ b/packages/react/src/components/_CheckboxRadioTemplate/CheckboxRadioTemplate.module.css
@@ -77,6 +77,13 @@
color: var(--label-color);
}
+.labelAndHelpText {
+ display: inline-flex;
+ flex-direction: row;
+ gap: var(--gap);
+ align-items: center;
+}
+
.description {
color: var(--description-color);
}
@@ -88,7 +95,7 @@
}
}
-.template:not(.disabled):has(:focus-visible) {
+.template:not(.disabled):not(:has(button:focus-visible)):has(:focus-visible) {
outline: 2px solid var(--interactive_components-colors-focus_outline);
outline-offset: 2px;
}
diff --git a/packages/react/src/components/_CheckboxRadioTemplate/CheckboxRadioTemplate.tsx b/packages/react/src/components/_CheckboxRadioTemplate/CheckboxRadioTemplate.tsx
index 56be89a7d5..fcfbda6cb4 100644
--- a/packages/react/src/components/_CheckboxRadioTemplate/CheckboxRadioTemplate.tsx
+++ b/packages/react/src/components/_CheckboxRadioTemplate/CheckboxRadioTemplate.tsx
@@ -7,6 +7,9 @@ import type { ChangeEventHandler, ReactNode } from 'react';
import React, { useId } from 'react';
import cn from 'classnames';
+import { HelpText } from '../HelpText';
+import { HelpTextSize } from '../HelpText/HelpText';
+
import classes from './CheckboxRadioTemplate.module.css';
export enum CheckboxRadioTemplateSize {
@@ -20,6 +23,7 @@ export interface CheckboxRadioTemplateProps {
className?: string;
description?: ReactNode;
disabled?: boolean;
+ helpText?: string;
hideInput?: boolean;
hideLabel?: boolean;
inputId?: string;
@@ -39,6 +43,7 @@ export const CheckboxRadioTemplate = ({
className,
description,
disabled,
+ helpText,
hideInput,
hideLabel,
inputId,
@@ -57,6 +62,10 @@ export const CheckboxRadioTemplate = ({
const showLabel = label && !hideLabel;
const shouldHaveClickableLabel = !presentation
|| (typeof label !== 'object' && typeof description !== 'object');
+ const helpTextSize =
+ size === CheckboxRadioTemplateSize.Xsmall
+ ? HelpTextSize.Xsmall
+ : HelpTextSize.Small;
return (
-
- {children}
-
+ {children}
)}
{(showLabel || description) && (
{showLabel && (
-
- {label}
+
+
+ {label}
+
+ {helpText && (
+
+ {helpText}
+
+ )}
)}
{description && (
diff --git a/packages/react/src/utils/utility.module.css b/packages/react/src/utils/utility.module.css
new file mode 100644
index 0000000000..a45d5195be
--- /dev/null
+++ b/packages/react/src/utils/utility.module.css
@@ -0,0 +1,13 @@
+/**
+ * Visually hide an element, but leave it available for screen readers
+ */
+.visuallyHidden {
+ border: 0;
+ clip: rect(0 0 0 0);
+ height: 1px;
+ overflow: hidden;
+ padding: 0;
+ position: absolute;
+ white-space: nowrap;
+ width: 1px;
+}