diff --git a/packages/dnb-design-system-portal/src/docs/uilib/extensions/forms/feature-fields/NationalIdentityNumber/Examples.tsx b/packages/dnb-design-system-portal/src/docs/uilib/extensions/forms/feature-fields/NationalIdentityNumber/Examples.tsx
index 21f9d6af699..cc800a9ab43 100644
--- a/packages/dnb-design-system-portal/src/docs/uilib/extensions/forms/feature-fields/NationalIdentityNumber/Examples.tsx
+++ b/packages/dnb-design-system-portal/src/docs/uilib/extensions/forms/feature-fields/NationalIdentityNumber/Examples.tsx
@@ -160,3 +160,35 @@ export const ValidationFunction = () => {
)
}
+
+export const ValidationExtendValidator = () => {
+ return (
+
+ {() => {
+ const bornInApril = (value: string) =>
+ value.substring(2, 4) === '04'
+ ? { status: 'valid' }
+ : { status: 'invalid' }
+
+ const myValidator = (value, { validators }) => {
+ const { dnrValidator, fnrValidator } = validators
+ const result = bornInApril(value)
+ if (result.status === 'invalid') {
+ return new Error('My error')
+ }
+
+ return [dnrValidator, fnrValidator]
+ }
+
+ return (
+
+ )
+ }}
+
+ )
+}
diff --git a/packages/dnb-design-system-portal/src/docs/uilib/extensions/forms/feature-fields/NationalIdentityNumber/demos.mdx b/packages/dnb-design-system-portal/src/docs/uilib/extensions/forms/feature-fields/NationalIdentityNumber/demos.mdx
index 097fd7e3b2e..24a8c45cc02 100644
--- a/packages/dnb-design-system-portal/src/docs/uilib/extensions/forms/feature-fields/NationalIdentityNumber/demos.mdx
+++ b/packages/dnb-design-system-portal/src/docs/uilib/extensions/forms/feature-fields/NationalIdentityNumber/demos.mdx
@@ -63,3 +63,9 @@ Below is an example of the error message displayed when there's an invalid D num
You can provide your own validation function.
+
+### Extend validation with custom validation function
+
+You can [extend the existing validations](/uilib/extensions/forms/create-component/useFieldProps/info/#validators)(`dnrValidator` and `fnrValidator`) with your own validation function.
+
+
diff --git a/packages/dnb-design-system-portal/src/docs/uilib/extensions/forms/feature-fields/NationalIdentityNumber/properties.mdx b/packages/dnb-design-system-portal/src/docs/uilib/extensions/forms/feature-fields/NationalIdentityNumber/properties.mdx
index 40cde507d48..850fb75a587 100644
--- a/packages/dnb-design-system-portal/src/docs/uilib/extensions/forms/feature-fields/NationalIdentityNumber/properties.mdx
+++ b/packages/dnb-design-system-portal/src/docs/uilib/extensions/forms/feature-fields/NationalIdentityNumber/properties.mdx
@@ -5,15 +5,13 @@ showTabs: true
import TranslationsTable from 'dnb-design-system-portal/src/shared/parts/TranslationsTable'
import PropertiesTable from 'dnb-design-system-portal/src/shared/parts/PropertiesTable'
import { fieldProperties } from '@dnb/eufemia/src/extensions/forms/Field/FieldDocs'
+import { NationalIdentityNumberProperties } from '@dnb/eufemia/src/extensions/forms/Field/NationalIdentityNumber/NationalIdentityNumberDocs'
## Properties
### Field-specific props
-| Property | Type | Description |
-| ---------- | --------- | ------------------------------------------------------------------------------- |
-| `validate` | `boolean` | _(optional)_ Using this prop you can disable the default validation. |
-| `help` | `object` | _(optional)_ Provide a help button. Object consisting of `title` and `content`. |
+
### General props
diff --git a/packages/dnb-eufemia/src/extensions/forms/Field/NationalIdentityNumber/NationalIdentityNumber.tsx b/packages/dnb-eufemia/src/extensions/forms/Field/NationalIdentityNumber/NationalIdentityNumber.tsx
index 9252e43e553..a3cc7ed9d8b 100644
--- a/packages/dnb-eufemia/src/extensions/forms/Field/NationalIdentityNumber/NationalIdentityNumber.tsx
+++ b/packages/dnb-eufemia/src/extensions/forms/Field/NationalIdentityNumber/NationalIdentityNumber.tsx
@@ -52,7 +52,6 @@ function NationalIdentityNumber(props: Props) {
) {
return Error(errorFnr)
}
- return undefined
},
[errorFnr]
)
@@ -66,7 +65,6 @@ function NationalIdentityNumber(props: Props) {
) {
return Error(errorDnr)
}
- return undefined
},
[errorDnr]
)
@@ -94,6 +92,7 @@ function NationalIdentityNumber(props: Props) {
validator: validate
? props.validator || dnrAndFnrValidator
: undefined,
+ exportValidators: { dnrValidator, fnrValidator },
}
return
diff --git a/packages/dnb-eufemia/src/extensions/forms/Field/NationalIdentityNumber/NationalIdentityNumberDocs.tsx b/packages/dnb-eufemia/src/extensions/forms/Field/NationalIdentityNumber/NationalIdentityNumberDocs.tsx
new file mode 100644
index 00000000000..2445ff8175b
--- /dev/null
+++ b/packages/dnb-eufemia/src/extensions/forms/Field/NationalIdentityNumber/NationalIdentityNumberDocs.tsx
@@ -0,0 +1,14 @@
+import { PropertiesTableProps } from '../../../../shared/types'
+
+export const NationalIdentityNumberProperties: PropertiesTableProps = {
+ validate: {
+ doc: 'Using this prop you can disable the default validation.',
+ type: 'boolean',
+ status: 'optional',
+ },
+ help: {
+ doc: 'Provide a help button. Object consisting of `title` and `content`.',
+ type: 'object',
+ status: 'optional',
+ },
+}
diff --git a/packages/dnb-eufemia/src/extensions/forms/Field/NationalIdentityNumber/__tests__/NationalIdentityNumber.test.tsx b/packages/dnb-eufemia/src/extensions/forms/Field/NationalIdentityNumber/__tests__/NationalIdentityNumber.test.tsx
index 1b41434aaef..d89d405f1b0 100644
--- a/packages/dnb-eufemia/src/extensions/forms/Field/NationalIdentityNumber/__tests__/NationalIdentityNumber.test.tsx
+++ b/packages/dnb-eufemia/src/extensions/forms/Field/NationalIdentityNumber/__tests__/NationalIdentityNumber.test.tsx
@@ -1,7 +1,7 @@
import React from 'react'
import { fireEvent, render, waitFor, screen } from '@testing-library/react'
import { Props } from '..'
-import { Field, Form } from '../../..'
+import { Field, Form, Validator } from '../../..'
import nbNO from '../../../constants/locales/nb-NO'
const nb = nbNO['nb-NO']
@@ -211,6 +211,38 @@ describe('Field.NationalIdentityNumber', () => {
})
})
+ it('should not validate extended validator when validate false', async () => {
+ const invalidFnr = '29040112345'
+
+ const bornInApril = (value: string) =>
+ value.substring(2, 4) === '04'
+ ? { status: 'valid' }
+ : { status: 'invalid' }
+
+ const customValidator: Validator = (value, { validators }) => {
+ const { dnrValidator, fnrValidator } = validators
+ const result = bornInApril(value)
+ if (result.status === 'invalid') {
+ return new Error('custom error')
+ }
+
+ return [dnrValidator, fnrValidator]
+ }
+
+ render(
+
+ )
+ await expectNever(() => {
+ // Can't just waitFor and expect not to be in the document, it would approve the first render before the error might appear async.
+ expect(screen.queryByRole('alert')).toBeInTheDocument()
+ })
+ })
+
describe('should validate Norwegian D number', () => {
const validDNum = [
'53097248016',
@@ -304,4 +336,103 @@ describe('Field.NationalIdentityNumber', () => {
}
)
})
+
+ describe('should extend validation using custom validator', () => {
+ const validFnrNumApril = ['14046512368', '10042223293']
+ const validDNumApril = ['51041678171']
+
+ const validIds = [...validFnrNumApril, ...validDNumApril]
+
+ const invalidFnrNumApril = ['29040112345', '13047248032']
+ const invalidDNumApril = ['69040112345', '53047248032']
+
+ const validFnrNumNotApril = [
+ '58081633086',
+ '53050129159',
+ '65015439860',
+ ]
+ const validDNumNotApril = ['08121312590', '12018503288', '03025742965']
+
+ const invalidIds = [...validFnrNumNotApril, ...validDNumNotApril]
+
+ const bornInApril = (value: string) =>
+ value.substring(2, 4) === '04'
+ ? { status: 'valid' }
+ : { status: 'invalid' }
+
+ const customValidator: Validator = (value, { validators }) => {
+ const { dnrValidator, fnrValidator } = validators
+ const result = bornInApril(value)
+ if (result.status === 'invalid') {
+ return new Error('custom error')
+ }
+
+ return [dnrValidator, fnrValidator]
+ }
+
+ it.each(validIds)('Valid identity number: %s', async (fnrNum) => {
+ render(
+
+ )
+ await expectNever(() => {
+ // Can't just waitFor and expect not to be in the document, it would approve the first render before the error might appear async.
+ expect(screen.queryByRole('alert')).toBeInTheDocument()
+ })
+ })
+
+ it.each(invalidIds)('Invalid identity number: %s', async (id) => {
+ render(
+
+ )
+ await waitFor(() => {
+ expect(screen.queryByRole('alert')).toBeInTheDocument()
+ expect(screen.queryByRole('alert')).toHaveTextContent(
+ 'custom error'
+ )
+ })
+ })
+
+ it.each(invalidDNumApril)('Invalid D number: %s', async (dNum) => {
+ render(
+
+ )
+ await waitFor(() => {
+ expect(screen.queryByRole('alert')).toBeInTheDocument()
+ expect(screen.queryByRole('alert')).toHaveTextContent(
+ nb.NationalIdentityNumber.errorDnr
+ )
+ })
+ })
+
+ it.each(invalidFnrNumApril)(
+ 'Invalid national identity number(fnr): %s',
+ async (fnr) => {
+ render(
+
+ )
+ await waitFor(() => {
+ expect(screen.queryByRole('alert')).toBeInTheDocument()
+ expect(screen.queryByRole('alert')).toHaveTextContent(
+ nb.NationalIdentityNumber.errorFnr
+ )
+ })
+ }
+ )
+ })
})