diff --git a/packages/dnb-eufemia/src/elements/typography/P.tsx b/packages/dnb-eufemia/src/elements/typography/P.tsx index a2a70320077..f530acc891f 100644 --- a/packages/dnb-eufemia/src/elements/typography/P.tsx +++ b/packages/dnb-eufemia/src/elements/typography/P.tsx @@ -3,7 +3,7 @@ * */ -import React from 'react' +import React, { createContext, useContext } from 'react' import classnames from 'classnames' import { SpacingProps } from '../../components/space/types' import type { DynamicElement } from '../../shared/types' @@ -24,7 +24,7 @@ export type PProps = SpacingProps & * Defines the Element Type, like "p" * Default: p */ - element?: DynamicElement & 'p' + element?: DynamicElement | 'p' /** * Tells the component to use the medium font-weight styling dnb-p--medium defined in paragraphStyle - typography-mixins.scss. Find more details here https://eufemia.dnb.no/uilib/typography/font-weight/ */ @@ -45,16 +45,20 @@ export type PProps = SpacingProps & modifier?: string } -const P = ({ - modifier, - element = 'p', - className, - medium, - bold, - size, - ...props -}: PProps) => { +function P(props: PProps) { + const { + modifier, + element = 'p', + className, + medium, + bold, + size, + children, + ...rest + } = props + const allModifiers = [medium && 'medium', bold && 'bold'] + const paragraphContext = useContext(ParagraphContext) if (modifier) { modifier @@ -73,19 +77,32 @@ const P = ({ }, '') return ( - + + + {children} + + ) } P._supportsSpacingProps = true export default P + +export type ParagraphContextType = { + isNested?: boolean +} + +export const ParagraphContext = + createContext(undefined) diff --git a/packages/dnb-eufemia/src/elements/typography/__tests__/P.test.tsx b/packages/dnb-eufemia/src/elements/typography/__tests__/P.test.tsx index 7784807d148..b5bcb2a4a22 100644 --- a/packages/dnb-eufemia/src/elements/typography/__tests__/P.test.tsx +++ b/packages/dnb-eufemia/src/elements/typography/__tests__/P.test.tsx @@ -14,6 +14,37 @@ const props: PProps = { } describe('P element', () => { + it('has p element as default', () => { + render(

) + + const element = document.querySelector('.dnb-p') + expect(element.tagName).toBe('P') + }) + + it('has span element when nested', () => { + render( +

+

+

+ ) + + const element = document.querySelector('.dnb-p > .dnb-p') + expect(element.tagName).toBe('SPAN') + }) + + it('uses the given element when nested and defined', () => { + const MockComponent = (props) => Mock + + render( +

+

+

+ ) + + const element = document.querySelector('.dnb-p > .dnb-p') + expect(element.tagName).toBe('STRONG') + }) + it('has correct size when size is defined', () => { render(

) const element = document.querySelector('.dnb-p__size--large') @@ -23,6 +54,7 @@ describe('P element', () => { 'dnb-p__size--large', ]) }) + it('has correct style when size and a modifier is defined', () => { render(

) const element = document.querySelector('.dnb-p__size--medium') @@ -33,6 +65,7 @@ describe('P element', () => { 'dnb-p__size--medium', ]) }) + it('has correct style when several modifiers are defined', () => { render(

) const element = document.querySelector('.dnb-p__size--small') @@ -43,6 +76,7 @@ describe('P element', () => { 'dnb-p__size--small', ]) }) + it('has correct style when medium is set to true', () => { render(

) const element = document.querySelector('.dnb-p--medium') @@ -51,12 +85,14 @@ describe('P element', () => { 'dnb-p--medium', ]) }) + it('has correct style when bold is set to true', () => { render(

) const element = document.querySelector('.dnb-p--bold') expect(Array.from(element.classList)).toEqual(['dnb-p', 'dnb-p--bold']) }) + it('should validate with ARIA rules as a p element', async () => { const Comp = render(

) expect(await axeComponent(Comp)).toHaveNoViolations()