diff --git a/packages/ffe-formatters/src/Formatters.mdx b/packages/ffe-formatters/src/Formatters.mdx new file mode 100644 index 0000000000..f36cd25151 --- /dev/null +++ b/packages/ffe-formatters/src/Formatters.mdx @@ -0,0 +1,34 @@ +import { Meta } from '@storybook/blocks'; +import { Table, TableHead, TableRow, TableDataCell, TableHeaderCell, TableBody, TableCaption } from "@sb1/ffe-tables-react"; + + +# Formateringsprinsipper + +Det finnes mange formateringsprinsipper som er standardisert i Norge, og som bidrar til å øke lesbarheten. I designsystemet har vi komponenter som hjelper med formateringen, så du som utvikler ikke trenger å bekymre deg for at ting ikke vises riktig. + + + Utvalg av ulike formateringer som finnes: + + + Type + Eksempel + + + + {[ + {type :'Datoer', eksempel: '12.11.2024'}, + {type :'Tall', eksempel: '100 000'}, + {type :'Valuta', eksempel: 'kr 1 000,–'}, + {type :'Prosenter', eksempel: '7 %'}, + {type :'Kontonummer', eksempel: '1234 56 78901'}, + {type :'Fødselsnummer', eksempel: '123456 78901'}, + {type :'Avstander', eksempel: '50 km'}, + ].map((it) => ( + + {it.type} + {it.eksempel} + + ))} + +
+ diff --git a/packages/ffe-formatters/src/formatAccountNumber.stories.tsx b/packages/ffe-formatters/src/formatAccountNumber.stories.tsx new file mode 100644 index 0000000000..9847c27e96 --- /dev/null +++ b/packages/ffe-formatters/src/formatAccountNumber.stories.tsx @@ -0,0 +1,22 @@ +import React from 'react'; +import type { StoryObj, Meta } from '@storybook/react'; +import { formatAccountNumber } from './formatAccountNumber'; + +const Demo: React.FC<{ accountNumber: string }> = ({ accountNumber }) => { + return <>{formatAccountNumber(accountNumber)}; +}; + +const meta: Meta = { + title: 'Formattering/formatAccountNumber', + component: Demo, +}; +export default meta; + +type Story = StoryObj; + +export const Standard: Story = { + args: { + accountNumber: '90010012345', + }, + render: args => , +}; diff --git a/packages/ffe-formatters/src/formatCurrency.mdx b/packages/ffe-formatters/src/formatCurrency.mdx new file mode 100644 index 0000000000..3ed054f251 --- /dev/null +++ b/packages/ffe-formatters/src/formatCurrency.mdx @@ -0,0 +1,11 @@ +import { Canvas, Meta, Controls } from '@storybook/blocks'; +import * as formatCurrencyStories from './formatCurrency.stories'; + + + +# formatCurrency + +`formatCurrency` kan gis et objekt som andre argument for å styre prefix og postfix: + + + diff --git a/packages/ffe-formatters/src/formatCurrency.stories.tsx b/packages/ffe-formatters/src/formatCurrency.stories.tsx new file mode 100644 index 0000000000..5f26eff72d --- /dev/null +++ b/packages/ffe-formatters/src/formatCurrency.stories.tsx @@ -0,0 +1,35 @@ +import React from 'react'; +import type { StoryObj, Meta } from '@storybook/react'; +import { formatCurrency } from './formatCurrency'; +import { Locale } from './types'; + +interface DemoParams { + amount: string | number; + prefix?: string; + postfix?: string; + locale: Locale; +} + +const Demo: React.FC = ({ amount, postfix, prefix, locale }) => { + return <>{formatCurrency(amount, { locale, postfix, prefix })}; +}; + +const meta: Meta = { + title: 'Formattering/formatCurrency', + component: Demo, + argTypes: { + prefix: { control: 'text' }, + postfix: { control: 'text' }, + }, +}; +export default meta; + +type Story = StoryObj; + +export const Standard: Story = { + args: { + amount: '1000', + locale: 'nb', + }, + render: args => , +}; diff --git a/packages/ffe-formatters/src/formatCurrency.ts b/packages/ffe-formatters/src/formatCurrency.ts index 9bfe3174bf..5b44a02970 100644 --- a/packages/ffe-formatters/src/formatCurrency.ts +++ b/packages/ffe-formatters/src/formatCurrency.ts @@ -11,9 +11,7 @@ interface Opts { export const formatCurrency = (amount: number | string, opts: Opts) => { const { locale } = opts; - const { prefix, postfix } = { - prefix: `kr${NON_BREAKING_SPACE}`, - postfix: ',–', + const { prefix = `kr${NON_BREAKING_SPACE}`, postfix = ',–' } = { ...opts, }; diff --git a/packages/ffe-formatters/src/formatDate.mdx b/packages/ffe-formatters/src/formatDate.mdx new file mode 100644 index 0000000000..f182f8b163 --- /dev/null +++ b/packages/ffe-formatters/src/formatDate.mdx @@ -0,0 +1,11 @@ +import { Canvas, Meta, Controls } from '@storybook/blocks'; +import * as formatDateStories from './formatDate.stories'; + + + +# formatDate + +`formateDate` støtter bare norsk locale, og formaterer Date-objekter og timestamps. + + + diff --git a/packages/ffe-formatters/src/formatDate.stories.tsx b/packages/ffe-formatters/src/formatDate.stories.tsx new file mode 100644 index 0000000000..de6ef682fa --- /dev/null +++ b/packages/ffe-formatters/src/formatDate.stories.tsx @@ -0,0 +1,29 @@ +import React from 'react'; +import type { StoryObj, Meta } from '@storybook/react'; +import { formatDate } from './formatDate'; + +interface DemoParams { + timestamp: Date | number; +} + +const Demo: React.FC = ({ timestamp }) => { + return <>{formatDate(timestamp)}; +}; + +const meta: Meta = { + title: 'Formattering/formatDate', + component: Demo, + argTypes: { + timestamp: { control: 'date' }, + }, +}; +export default meta; + +type Story = StoryObj; + +export const Standard: Story = { + args: { + timestamp: new Date(), + }, + render: args => , +}; diff --git a/packages/ffe-formatters/src/formatDistance.mdx b/packages/ffe-formatters/src/formatDistance.mdx new file mode 100644 index 0000000000..13555d90f8 --- /dev/null +++ b/packages/ffe-formatters/src/formatDistance.mdx @@ -0,0 +1,9 @@ +import { Canvas, Meta, Controls } from '@storybook/blocks'; +import * as formatDistanceStories from './formatDistance.stories'; + + + +# formatDistance + + + diff --git a/packages/ffe-formatters/src/formatDistance.stories.tsx b/packages/ffe-formatters/src/formatDistance.stories.tsx new file mode 100644 index 0000000000..10c72d7b7e --- /dev/null +++ b/packages/ffe-formatters/src/formatDistance.stories.tsx @@ -0,0 +1,30 @@ +import React from 'react'; +import type { StoryObj, Meta } from '@storybook/react'; +import { formatDistance } from './formatDistance'; + +interface DemoParams { + distance: string | number; + unit?: string; +} + +const Demo: React.FC = ({ unit, distance }) => { + return <>{formatDistance(distance, { unit })}; +}; + +const meta: Meta = { + title: 'Formattering/formatDistance', + component: Demo, + argTypes: { + unit: { control: 'text' }, + }, +}; +export default meta; + +type Story = StoryObj; + +export const Standard: Story = { + args: { + distance: '160 520', + }, + render: args => , +}; diff --git a/packages/ffe-formatters/src/formatDistance.ts b/packages/ffe-formatters/src/formatDistance.ts index 373f87f756..8c785711c1 100644 --- a/packages/ffe-formatters/src/formatDistance.ts +++ b/packages/ffe-formatters/src/formatDistance.ts @@ -6,12 +6,10 @@ interface Opts { unit?: string; } -export const formatDistance = ( - distance: string | number, - opts: Opts = { unit: 'km' }, -) => { +export const formatDistance = (distance: string | number, opts: Opts = {}) => { + const { unit = 'km' } = opts; const toFormat = parseNumber(distance, 'nb'); return toFormat === null ? '' - : `${formatNumber(toFormat, { locale: 'nb' })}${NON_BREAKING_SPACE}${opts.unit}`; + : `${formatNumber(toFormat, { locale: 'nb' })}${NON_BREAKING_SPACE}${unit}`; }; diff --git a/packages/ffe-formatters/src/formatFodselsnummer.mdx b/packages/ffe-formatters/src/formatFodselsnummer.mdx new file mode 100644 index 0000000000..8132740f20 --- /dev/null +++ b/packages/ffe-formatters/src/formatFodselsnummer.mdx @@ -0,0 +1,9 @@ +import { Canvas, Meta, Controls } from '@storybook/blocks'; +import * as formatFodselsnummerStories from './formatFodselsnummer.stories'; + + + +# formatFodselsnummer + + + diff --git a/packages/ffe-formatters/src/formatFodselsnummer.stories.tsx b/packages/ffe-formatters/src/formatFodselsnummer.stories.tsx new file mode 100644 index 0000000000..98fe9a5990 --- /dev/null +++ b/packages/ffe-formatters/src/formatFodselsnummer.stories.tsx @@ -0,0 +1,26 @@ +import React from 'react'; +import type { StoryObj, Meta } from '@storybook/react'; +import { formatFodselsnummer } from './formatFodselsnummer'; + +interface DemoParams { + ssn: string; +} + +const Demo: React.FC = ({ ssn }) => { + return <>{formatFodselsnummer(ssn)}; +}; + +const meta: Meta = { + title: 'Formattering/formatFodselsnummer', + component: Demo, +}; +export default meta; + +type Story = StoryObj; + +export const Standard: Story = { + args: { + ssn: '01010112345', + }, + render: args => , +}; diff --git a/packages/ffe-formatters/src/formatNumber.mdx b/packages/ffe-formatters/src/formatNumber.mdx new file mode 100644 index 0000000000..3c8fcd8380 --- /dev/null +++ b/packages/ffe-formatters/src/formatNumber.mdx @@ -0,0 +1,11 @@ +import { Canvas, Meta, Controls } from '@storybook/blocks'; +import * as formatNumberStories from './formatNumber.stories'; + + + +# formatNumber + +Om ingen av de spesialiserte formateringsfunksjonene passer kan du bruke formatNumber. Denne funksjonen utgjør basen i mange av de andre funksjonene. + + + diff --git a/packages/ffe-formatters/src/formatNumber.stories.tsx b/packages/ffe-formatters/src/formatNumber.stories.tsx new file mode 100644 index 0000000000..8ce302ddba --- /dev/null +++ b/packages/ffe-formatters/src/formatNumber.stories.tsx @@ -0,0 +1,31 @@ +import React from 'react'; +import type { StoryObj, Meta } from '@storybook/react'; +import { formatNumber } from './formatNumber'; +import { Locale } from './types'; + +interface DemoParams { + number: number | string | null | undefined; + locale: Locale; + decimals?: number; +} + +const Demo: React.FC = ({ number, ...rest }) => { + return <>{formatNumber(number, { ...rest })}; +}; + +const meta: Meta = { + title: 'Formattering/formatNumber', + component: Demo, +}; +export default meta; + +type Story = StoryObj; + +export const Standard: Story = { + args: { + number: '1234567890', + locale: 'nb', + decimals: 2, + }, + render: args => , +}; diff --git a/packages/ffe-formatters/src/formatPercentage.mdx b/packages/ffe-formatters/src/formatPercentage.mdx new file mode 100644 index 0000000000..86eaf12c17 --- /dev/null +++ b/packages/ffe-formatters/src/formatPercentage.mdx @@ -0,0 +1,12 @@ +import { Canvas, Meta, Controls } from '@storybook/blocks'; +import * as formatPercentageStories from './formatPercentage.stories'; + + + +# formatPercentage + +`formatPercentage` gir prosenter det riktige mellomrommet mellom tall og % med et non-breaking space. +Runder av til så få desimaler som mulig, med en default cap på to desimaler. Dette kan overstyres i `options`-objektet. + + + diff --git a/packages/ffe-formatters/src/formatPercentage.stories.tsx b/packages/ffe-formatters/src/formatPercentage.stories.tsx new file mode 100644 index 0000000000..12ce7ee98b --- /dev/null +++ b/packages/ffe-formatters/src/formatPercentage.stories.tsx @@ -0,0 +1,32 @@ +import React from 'react'; +import type { StoryObj, Meta } from '@storybook/react'; +import { formatPercentage } from './formatPercentage'; + +interface DemoParams { + amount: number | string; + minDecimals?: number; + maxDecimals?: number; +} + +const Demo: React.FC = ({ amount, ...rest }) => { + return <>{formatPercentage(amount, { ...rest })}; +}; + +const meta: Meta = { + title: 'Formattering/formatPercentage', + component: Demo, + argTypes: { + minDecimals: { control: 'number' }, + maxDecimals: { control: 'number' }, + }, +}; +export default meta; + +type Story = StoryObj; + +export const Standard: Story = { + args: { + amount: '49', + }, + render: args => , +}; diff --git a/packages/ffe-formatters/src/formatPercentage.ts b/packages/ffe-formatters/src/formatPercentage.ts index 6775a78e95..bf71fa0285 100644 --- a/packages/ffe-formatters/src/formatPercentage.ts +++ b/packages/ffe-formatters/src/formatPercentage.ts @@ -13,7 +13,7 @@ export const formatPercentage = ( }, ) => { if (typeof amount !== 'number') { - return ''; + return `${amount.replace('.', ',')}${NON_BREAKING_SPACE}%`; } const percentage = amount.toLocaleString('nb-NO', { diff --git a/packages/ffe-formatters/tsconfig.cjs.json b/packages/ffe-formatters/tsconfig.cjs.json index 6579fd2246..a0ff7c436f 100644 --- a/packages/ffe-formatters/tsconfig.cjs.json +++ b/packages/ffe-formatters/tsconfig.cjs.json @@ -5,5 +5,5 @@ "module": "commonjs" }, "include": ["src/**/*"], - "exclude": ["node_modules", "src/**/*.spec.ts*"] + "exclude": ["node_modules", "src/**/*.spec.ts*", "src/**/*.stories.ts*"] } diff --git a/packages/ffe-formatters/tsconfig.esm.json b/packages/ffe-formatters/tsconfig.esm.json index 8e577796bf..166aa56ab3 100644 --- a/packages/ffe-formatters/tsconfig.esm.json +++ b/packages/ffe-formatters/tsconfig.esm.json @@ -5,5 +5,5 @@ "module": "esnext" }, "include": ["src/**/*"], - "exclude": ["node_modules", "src/**/*.spec.ts*"] + "exclude": ["node_modules", "src/**/*.spec.ts*", "src/**/*.stories.ts*"] } diff --git a/packages/ffe-formatters/tsconfig.types.json b/packages/ffe-formatters/tsconfig.types.json index 3499c0be03..21404f4617 100644 --- a/packages/ffe-formatters/tsconfig.types.json +++ b/packages/ffe-formatters/tsconfig.types.json @@ -6,5 +6,5 @@ "emitDeclarationOnly": true }, "include": ["src/**/*"], - "exclude": ["node_modules", "src/**/*.spec.ts*"] + "exclude": ["node_modules", "src/**/*.spec.ts*", "src/**/*.stories.ts*"] }