diff --git a/libs/form-component/src/app-components/Button/Button.tsx b/libs/form-component/src/app-components/Button/Button.tsx index 22dd3b88b76..393dfaa7c73 100644 --- a/libs/form-component/src/app-components/Button/Button.tsx +++ b/libs/form-component/src/app-components/Button/Button.tsx @@ -1,4 +1,4 @@ -import React from 'react' +import React from 'react'; import type { PropsWithChildren, Ref } from 'react'; import { Button as DesignSystemButton } from '@digdir/designsystemet-react'; diff --git a/libs/form-component/src/app-components/DisplayText/DisplayText.module.css b/libs/form-component/src/app-components/DisplayText/DisplayText.module.css new file mode 100644 index 00000000000..275a50ceb0f --- /dev/null +++ b/libs/form-component/src/app-components/DisplayText/DisplayText.module.css @@ -0,0 +1,4 @@ +.icon { + width: 24px; + margin-right: 12px; +} diff --git a/libs/form-component/src/app-components/DisplayText/DisplayText.stories.tsx b/libs/form-component/src/app-components/DisplayText/DisplayText.stories.tsx new file mode 100644 index 00000000000..d07a176c44b --- /dev/null +++ b/libs/form-component/src/app-components/DisplayText/DisplayText.stories.tsx @@ -0,0 +1,42 @@ +import type { Meta, StoryObj } from '@storybook/react-vite'; + +import { DisplayText } from './DisplayText'; + +const meta = { + title: 'AppComponents/DisplayText', + component: DisplayText, + args: { + value: 'Hello world', + }, +} satisfies Meta; + +export default meta; + +type Story = StoryObj; + +export const Preview: Story = {}; + +export const WithIcon: Story = { + args: { + iconUrl: 'https://altinncdn.no/orgs/digdir/digdir.png', + iconAltText: 'Info icon', + }, +}; + +export const WithLabel: Story = { + args: { + labelId: 'text-label', + }, + render: (args) => ( + <> + Description + + + ), +}; + +export const EmptyValue: Story = { + args: { + value: '', + }, +}; diff --git a/libs/form-component/src/app-components/DisplayText/DisplayText.test.tsx b/libs/form-component/src/app-components/DisplayText/DisplayText.test.tsx new file mode 100644 index 00000000000..04537a96625 --- /dev/null +++ b/libs/form-component/src/app-components/DisplayText/DisplayText.test.tsx @@ -0,0 +1,30 @@ +import { render, screen } from '@testing-library/react'; + +import { DisplayText } from './DisplayText'; + +describe('DisplayText', () => { + it('renders the value inside a span', () => { + render(); + + expect(screen.getByText('Hello world')).toBeInTheDocument(); + }); + + it('renders an icon with alt text when iconUrl is provided', () => { + render(); + + const icon = screen.getByRole('img', { name: 'Info icon' }); + expect(icon).toHaveAttribute('src', '/icon.svg'); + }); + + it('omits the icon when iconUrl is not provided', () => { + render(); + + expect(screen.queryByRole('img')).not.toBeInTheDocument(); + }); + + it('associates the value span with labelId via aria-labelledby', () => { + render(); + + expect(screen.getByText('Hello world')).toHaveAttribute('aria-labelledby', 'text-label'); + }); +}); diff --git a/libs/form-component/src/app-components/DisplayText/DisplayText.tsx b/libs/form-component/src/app-components/DisplayText/DisplayText.tsx new file mode 100644 index 00000000000..8c95f984101 --- /dev/null +++ b/libs/form-component/src/app-components/DisplayText/DisplayText.tsx @@ -0,0 +1,17 @@ +import classes from './DisplayText.module.css'; + +export type DisplayTextProps = { + value: string; + iconUrl?: string; + iconAltText?: string; + labelId?: string; +}; + +export function DisplayText({ value, iconUrl, iconAltText, labelId }: DisplayTextProps) { + return ( + <> + {iconUrl && {iconAltText}} + {value} + + ); +} diff --git a/libs/form-component/src/app-components/DisplayText/index.ts b/libs/form-component/src/app-components/DisplayText/index.ts new file mode 100644 index 00000000000..a5dc4928d30 --- /dev/null +++ b/libs/form-component/src/app-components/DisplayText/index.ts @@ -0,0 +1,2 @@ +export { DisplayText } from './DisplayText'; +export type { DisplayTextProps } from './DisplayText'; diff --git a/libs/form-component/src/app-components/Input/index.ts b/libs/form-component/src/app-components/Input/index.ts index cff21c209c8..30fb16ed18b 100644 --- a/libs/form-component/src/app-components/Input/index.ts +++ b/libs/form-component/src/app-components/Input/index.ts @@ -2,4 +2,3 @@ export { Input } from './Input'; export type { InputProps } from './Input'; export { FormattedInput } from './FormattedInput'; export { NumericInput } from './NumericInput'; - diff --git a/libs/form-component/src/app-components/index.ts b/libs/form-component/src/app-components/index.ts index e76c00f2d5d..74d39cbea91 100644 --- a/libs/form-component/src/app-components/index.ts +++ b/libs/form-component/src/app-components/index.ts @@ -6,6 +6,7 @@ export * from './Flex'; export * from './Input'; export * from './hooks'; export * from './DisplayDate'; +export * from './DisplayText'; export * from './DisplayNumber'; export * from './Spinner'; export * from './TextArea'; diff --git a/src/App/frontend/src/app-components/Text/DisplayText.tsx b/src/App/frontend/src/app-components/Text/DisplayText.tsx deleted file mode 100644 index a27cb1c84de..00000000000 --- a/src/App/frontend/src/app-components/Text/DisplayText.tsx +++ /dev/null @@ -1,29 +0,0 @@ -import React from 'react'; - -import { useTranslation } from 'src/app-components/AppComponentsProvider'; -import classes from 'src/app-components/Text/Text.module.css'; -import type { TranslationKey } from 'src/app-components/types'; - -interface TextProps { - value: string; - iconUrl?: string; - iconAltText?: TranslationKey; - labelId?: string; -} - -export const DisplayText = ({ value, iconUrl, iconAltText, labelId }: TextProps) => { - const { translate } = useTranslation(); - return ( - <> - {iconUrl && ( - {iconAltText - )} - {labelId && {value}} - {!labelId && {value}} - - ); -}; diff --git a/src/App/frontend/src/app-components/Text/Text.module.css b/src/App/frontend/src/layout/Text/Text.module.css similarity index 82% rename from src/App/frontend/src/app-components/Text/Text.module.css rename to src/App/frontend/src/layout/Text/Text.module.css index 8b977c353c6..70946328563 100644 --- a/src/App/frontend/src/app-components/Text/Text.module.css +++ b/src/App/frontend/src/layout/Text/Text.module.css @@ -7,11 +7,6 @@ .label span { font-size: var(--ds-body-md-font-size); } - -.icon { - width: 24px; - margin-right: 12px; -} .vertical { flex-direction: column; } diff --git a/src/App/frontend/src/layout/Text/TextComponent.tsx b/src/App/frontend/src/layout/Text/TextComponent.tsx index 7d87fd22d70..b41f182279b 100644 --- a/src/App/frontend/src/layout/Text/TextComponent.tsx +++ b/src/App/frontend/src/layout/Text/TextComponent.tsx @@ -1,18 +1,19 @@ import React from 'react'; +import { DisplayText } from '@app/form-component'; import cn from 'classnames'; -import { DisplayText } from 'src/app-components/Text/DisplayText'; -import classes from 'src/app-components/Text/Text.module.css'; -import { translationKey } from 'src/AppComponentsBridge'; import { getLabelId } from 'src/components/label/Label'; +import { useLanguage } from 'src/features/language/useLanguage'; import { ComponentStructureWrapper } from 'src/layout/ComponentStructureWrapper'; +import classes from 'src/layout/Text/Text.module.css'; import { useItemWhenType } from 'src/utils/layout/useNodeItem'; import type { PropsFromGenericComponent } from 'src/layout'; export const TextComponent = ({ baseComponentId }: PropsFromGenericComponent<'Text'>) => { const { id, textResourceBindings, value, icon, direction: _direction } = useItemWhenType(baseComponentId, 'Text'); const direction = _direction ?? 'horizontal'; + const { langAsString } = useLanguage(); if (!textResourceBindings?.title) { return ; @@ -34,7 +35,7 @@ export const TextComponent = ({ baseComponentId }: PropsFromGenericComponent<'Te