Skip to content

Commit

Permalink
create hook for using label
Browse files Browse the repository at this point in the history
  • Loading branch information
cammiida committed Nov 21, 2024
1 parent 8a9543a commit e0e79a9
Show file tree
Hide file tree
Showing 8 changed files with 142 additions and 182 deletions.
11 changes: 4 additions & 7 deletions src/app-components/Label/Label.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import React from 'react';
import type { PropsWithChildren, ReactElement } from 'react';
import type { JSX, PropsWithChildren, ReactElement } from 'react';

import { Label as DesignsystemetLabel } from '@digdir/designsystemet-react';
import { Grid, type GridProps } from '@material-ui/core';
Expand All @@ -10,19 +10,16 @@ import classes from 'src/app-components/Label/Label.module.css';

type GridSize = Pick<GridProps, 'xs' | 'sm' | 'md' | 'lg' | 'xl'>;

type RequiredIndicatorProps =
| { required: true; requiredIndicator: ReactElement }
| { required?: false; requiredIndicator?: ReactElement };

type LabelProps = {
label: string | undefined;
optionalIndicator?: ReactElement;
help?: ReactElement;
description?: ReactElement;
className?: string;
grid?: GridSize;
} & RequiredIndicatorProps &
Pick<DesignsystemetLabelProps, 'htmlFor' | 'style'>;
required?: boolean;
requiredIndicator?: JSX.Element;
} & Pick<DesignsystemetLabelProps, 'htmlFor' | 'style'>;

export function Label({
label,
Expand Down
12 changes: 4 additions & 8 deletions src/components/form/OptionalIndicator.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,11 @@ import React from 'react';

import { useLanguage } from 'src/features/language/useLanguage';

type OptionalIndicatorProps = {
export type OptionalIndicatorProps = {
readOnly?: boolean;
} & (
| {
required: true;
showOptionalMarking?: boolean;
}
| { required?: false; showOptionalMarking: boolean }
);
required?: boolean;
showOptionalMarking?: boolean;
};

export const OptionalIndicator = ({ readOnly, required, showOptionalMarking }: OptionalIndicatorProps) => {
const { langAsString } = useLanguage();
Expand Down
47 changes: 14 additions & 33 deletions src/layout/Datepicker/DatepickerComponent.tsx
Original file line number Diff line number Diff line change
@@ -1,17 +1,12 @@
import React, { useState } from 'react';

import { HelpText } from '@digdir/designsystemet-react';
import { Grid } from '@material-ui/core';
import { CalendarIcon } from '@navikt/aksel-icons';
import { formatDate, isValid as isValidDate } from 'date-fns';

import { Button } from 'src/app-components/button/Button';
import { Label } from 'src/app-components/Label/Label';
import { Description } from 'src/components/form/Description';
import { OptionalIndicator } from 'src/components/form/OptionalIndicator';
import { RequiredIndicator } from 'src/components/form/RequiredIndicator';
import { useDataModelBindings } from 'src/features/formData/useDataModelBindings';
import { Lang } from 'src/features/language/Lang';
import { useCurrentLanguage } from 'src/features/language/LanguageProvider';
import { useLanguage } from 'src/features/language/useLanguage';
import { useIsMobile } from 'src/hooks/useDeviceWidths';
Expand All @@ -22,6 +17,7 @@ import { DatePickerDialog } from 'src/layout/Datepicker/DatepickerDialog';
import { DatePickerInput } from 'src/layout/Datepicker/DatePickerInput';
import { getDateConstraint, getDateFormat, getSaveFormattedDateString, strictParseISO } from 'src/utils/dateHelpers';
import { getDatepickerFormat } from 'src/utils/formatDateLocale';
import { useLabel } from 'src/utils/layout/useLabel';
import { useNodeItem } from 'src/utils/layout/useNodeItem';
import type { PropsFromGenericComponent } from 'src/layout';

Expand Down Expand Up @@ -68,41 +64,26 @@ export function DatepickerComponent({ node, overrideDisplay }: IDatepickerProps)
setValue('simpleBinding', isoDateString);
};

const label =
(overrideDisplay?.renderLabel ?? true) && overrideDisplay?.renderedInTable !== true
? langAsString(textResourceBindings?.title)
: undefined;
const { labelText, getRequiredComponent, getOptionalComponent, getHelpTextComponent, getDescriptionComponent } =
useLabel({
overrideDisplay,
textResourceBindings,
readOnly,
required,
showOptionalMarking: !!labelSettings?.optionalIndicator,
});

return (
<>
<Label
htmlFor={id}
label={label}
label={labelText}
grid={grid?.labelGrid}
required={required}
requiredIndicator={<RequiredIndicator required={required} />}
optionalIndicator={
<OptionalIndicator
readOnly={readOnly}
required={required}
showOptionalMarking={!!labelSettings?.optionalIndicator}
/>
}
help={
textResourceBindings?.help ? (
<HelpText
id={`${id}-helptext`}
title={`${langAsString('helptext.button_title_prefix')} ${langAsString(textResourceBindings?.title)}`}
>
<Lang id={textResourceBindings?.help} />
</HelpText>
) : undefined
}
description={
textResourceBindings?.description ? (
<Description description={<Lang id={textResourceBindings?.description} />} />
) : undefined
}
requiredIndicator={getRequiredComponent()}
optionalIndicator={getOptionalComponent()}
help={getHelpTextComponent()}
description={getDescriptionComponent()}
>
<ComponentStructureWrapper node={node}>
<div className={styles.calendarGrid}>
Expand Down
49 changes: 16 additions & 33 deletions src/layout/Dropdown/DropdownComponent.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,10 @@
import React, { useCallback } from 'react';

import { Combobox, HelpText } from '@digdir/designsystemet-react';
import { Combobox } from '@digdir/designsystemet-react';

import { Label } from 'src/app-components/Label/Label';
import { AltinnSpinner } from 'src/components/AltinnSpinner';
import { ConditionalWrapper } from 'src/components/ConditionalWrapper';
import { Description } from 'src/components/form/Description';
import { OptionalIndicator } from 'src/components/form/OptionalIndicator';
import { RequiredIndicator } from 'src/components/form/RequiredIndicator';
import { DeleteWarningPopover } from 'src/features/alertOnChange/DeleteWarningPopover';
import { useAlertOnChange } from 'src/features/alertOnChange/useAlertOnChange';
import { FD } from 'src/features/formData/FormDataWrite';
Expand All @@ -17,6 +14,7 @@ import { useGetOptions } from 'src/features/options/useGetOptions';
import { useIsValid } from 'src/features/validation/selectors/isValid';
import { ComponentStructureWrapper } from 'src/layout/ComponentStructureWrapper';
import comboboxClasses from 'src/styles/combobox.module.css';
import { useLabel } from 'src/utils/layout/useLabel';
import { useNodeItem } from 'src/utils/layout/useNodeItem';
import type { PropsFromGenericComponent } from 'src/layout';

Expand All @@ -28,6 +26,15 @@ export function DropdownComponent({ node, overrideDisplay }: IDropdownProps) {
const { id, readOnly, textResourceBindings, alertOnChange, grid, required, labelSettings } = item;
const { langAsString, lang } = useLanguage(node);

const { labelText, getRequiredComponent, getOptionalComponent, getHelpTextComponent, getDescriptionComponent } =
useLabel({
overrideDisplay,
textResourceBindings,
readOnly,
required,
showOptionalMarking: !!labelSettings?.optionalIndicator,
});

const { options, isFetching, selectedValues, setData } = useGetOptions(node, 'single');
const debounce = FD.useDebounceImmediately();

Expand All @@ -54,11 +61,6 @@ export function DropdownComponent({ node, overrideDisplay }: IDropdownProps) {
return <AltinnSpinner />;
}

const label =
(overrideDisplay?.renderLabel ?? true) && overrideDisplay?.renderedInTable !== true
? langAsString(textResourceBindings?.title)
: undefined;

return (
<ConditionalWrapper
condition={Boolean(alertOnChange)}
Expand All @@ -77,32 +79,13 @@ export function DropdownComponent({ node, overrideDisplay }: IDropdownProps) {
>
<Label
htmlFor={id}
label={label}
label={labelText}
grid={grid?.labelGrid}
required={required}
requiredIndicator={<RequiredIndicator required={required} />}
optionalIndicator={
<OptionalIndicator
readOnly={readOnly}
required={required}
showOptionalMarking={!!labelSettings?.optionalIndicator}
/>
}
help={
textResourceBindings?.help ? (
<HelpText
id={`${id}-helptext`}
title={`${langAsString('helptext.button_title_prefix')} ${langAsString(textResourceBindings?.title)}`}
>
<Lang id={textResourceBindings?.help} />
</HelpText>
) : undefined
}
description={
textResourceBindings?.description ? (
<Description description={<Lang id={textResourceBindings?.description} />} />
) : undefined
}
requiredIndicator={getRequiredComponent()}
optionalIndicator={getOptionalComponent()}
help={getHelpTextComponent()}
description={getDescriptionComponent()}
>
<ComponentStructureWrapper node={node}>
<Combobox
Expand Down
49 changes: 14 additions & 35 deletions src/layout/Input/InputComponent.tsx
Original file line number Diff line number Diff line change
@@ -1,25 +1,20 @@
import React from 'react';

import { HelpText } from '@digdir/designsystemet-react';

import { FormattedInput } from 'src/app-components/Input/FormattedInput';
import { Input } from 'src/app-components/Input/Input';
import { NumericInput } from 'src/app-components/Input/NumericInput';
import { Label } from 'src/app-components/Label/Label';
import { Description } from 'src/components/form/Description';
import { OptionalIndicator } from 'src/components/form/OptionalIndicator';
import { RequiredIndicator } from 'src/components/form/RequiredIndicator';
import { getDescriptionId } from 'src/components/label/Label';
import { FD } from 'src/features/formData/FormDataWrite';
import { useDataModelBindings } from 'src/features/formData/useDataModelBindings';
import { Lang } from 'src/features/language/Lang';
import { useLanguage } from 'src/features/language/useLanguage';
import { useIsValid } from 'src/features/validation/selectors/isValid';
import { useMapToReactNumberConfig } from 'src/hooks/useMapToReactNumberConfig';
import { ComponentStructureWrapper } from 'src/layout/ComponentStructureWrapper';
import classes from 'src/layout/Input/InputComponent.module.css';
import { isNumberFormat, isPatternFormat } from 'src/layout/Input/number-format-helpers';
import { useCharacterLimit } from 'src/utils/inputUtils';
import { useLabel } from 'src/utils/layout/useLabel';
import { useNodeItem } from 'src/utils/layout/useNodeItem';
import type { InputProps } from 'src/app-components/Input/Input';
import type { PropsFromGenericComponent } from 'src/layout';
Expand Down Expand Up @@ -165,43 +160,27 @@ export const InputVariant = ({ node, overrideDisplay }: Pick<IInputProps, 'node'
};

export const InputComponent: React.FunctionComponent<IInputProps> = ({ node, overrideDisplay }) => {
const { langAsString } = useLanguage();
const { textResourceBindings, grid, id, required, readOnly, labelSettings } = useNodeItem(node);

const label =
(overrideDisplay?.renderLabel ?? true) && overrideDisplay?.renderedInTable !== true
? langAsString(textResourceBindings?.title)
: undefined;
const { labelText, getRequiredComponent, getOptionalComponent, getHelpTextComponent, getDescriptionComponent } =
useLabel({
overrideDisplay,
textResourceBindings,
readOnly,
required,
showOptionalMarking: !!labelSettings?.optionalIndicator,
});

return (
<Label
htmlFor={id}
label={label}
label={labelText}
grid={grid?.labelGrid}
required={required}
requiredIndicator={<RequiredIndicator required={required} />}
optionalIndicator={
<OptionalIndicator
readOnly={readOnly}
required={required}
showOptionalMarking={!!labelSettings?.optionalIndicator}
/>
}
help={
textResourceBindings?.help ? (
<HelpText
id={`${id}-helptext`}
title={`${langAsString('helptext.button_title_prefix')} ${langAsString(textResourceBindings?.title)}`}
>
<Lang id={textResourceBindings?.help} />
</HelpText>
) : undefined
}
description={
textResourceBindings?.description ? (
<Description description={<Lang id={textResourceBindings?.description} />} />
) : undefined
}
requiredIndicator={getRequiredComponent()}
optionalIndicator={getOptionalComponent()}
help={getHelpTextComponent()}
description={getDescriptionComponent()}
>
<ComponentStructureWrapper node={node}>
<InputVariant
Expand Down
49 changes: 16 additions & 33 deletions src/layout/MultipleSelect/MultipleSelectComponent.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,10 @@
import React, { useCallback } from 'react';

import { Combobox, HelpText } from '@digdir/designsystemet-react';
import { Combobox } from '@digdir/designsystemet-react';

import { Label } from 'src/app-components/Label/Label';
import { AltinnSpinner } from 'src/components/AltinnSpinner';
import { ConditionalWrapper } from 'src/components/ConditionalWrapper';
import { Description } from 'src/components/form/Description';
import { OptionalIndicator } from 'src/components/form/OptionalIndicator';
import { RequiredIndicator } from 'src/components/form/RequiredIndicator';
import { DeleteWarningPopover } from 'src/features/alertOnChange/DeleteWarningPopover';
import { useAlertOnChange } from 'src/features/alertOnChange/useAlertOnChange';
import { FD } from 'src/features/formData/FormDataWrite';
Expand All @@ -17,6 +14,7 @@ import { useGetOptions } from 'src/features/options/useGetOptions';
import { useIsValid } from 'src/features/validation/selectors/isValid';
import { ComponentStructureWrapper } from 'src/layout/ComponentStructureWrapper';
import comboboxClasses from 'src/styles/combobox.module.css';
import { useLabel } from 'src/utils/layout/useLabel';
import { useNodeItem } from 'src/utils/layout/useNodeItem';
import type { PropsFromGenericComponent } from 'src/layout';

Expand All @@ -29,6 +27,15 @@ export function MultipleSelectComponent({ node, overrideDisplay }: IMultipleSele
const debounce = FD.useDebounceImmediately();
const { langAsString, lang } = useLanguage(node);

const { labelText, getRequiredComponent, getOptionalComponent, getHelpTextComponent, getDescriptionComponent } =
useLabel({
overrideDisplay,
textResourceBindings,
readOnly,
required,
showOptionalMarking: !!labelSettings?.optionalIndicator,
});

const changeMessageGenerator = useCallback(
(values: string[]) => {
const labelsToRemove = options
Expand All @@ -53,11 +60,6 @@ export function MultipleSelectComponent({ node, overrideDisplay }: IMultipleSele
return <AltinnSpinner />;
}

const label =
(overrideDisplay?.renderLabel ?? true) && overrideDisplay?.renderedInTable !== true
? langAsString(textResourceBindings?.title)
: undefined;

return (
<ConditionalWrapper
condition={Boolean(alertOnChange)}
Expand All @@ -76,32 +78,13 @@ export function MultipleSelectComponent({ node, overrideDisplay }: IMultipleSele
>
<Label
htmlFor={id}
label={label}
label={labelText}
grid={grid?.labelGrid}
required={required}
requiredIndicator={<RequiredIndicator required={required} />}
optionalIndicator={
<OptionalIndicator
readOnly={readOnly}
required={required}
showOptionalMarking={!!labelSettings?.optionalIndicator}
/>
}
help={
textResourceBindings?.help ? (
<HelpText
id={`${id}-helptext`}
title={`${langAsString('helptext.button_title_prefix')} ${langAsString(textResourceBindings?.title)}`}
>
<Lang id={textResourceBindings?.help} />
</HelpText>
) : undefined
}
description={
textResourceBindings?.description ? (
<Description description={<Lang id={textResourceBindings?.description} />} />
) : undefined
}
requiredIndicator={getRequiredComponent()}
optionalIndicator={getOptionalComponent()}
help={getHelpTextComponent()}
description={getDescriptionComponent()}
>
<ComponentStructureWrapper node={node}>
<Combobox
Expand Down
Loading

0 comments on commit e0e79a9

Please sign in to comment.