diff --git a/component-overview/examples/cards/IllustrationCard-condensed.jsx b/component-overview/examples/cards/IllustrationCard-condensed.jsx new file mode 100644 index 0000000000..a3ac8abd5c --- /dev/null +++ b/component-overview/examples/cards/IllustrationCard-condensed.jsx @@ -0,0 +1,295 @@ +import { IllustrationCard } from '@sb1/ffe-cards-react'; +import React from 'react'; + +() => { + const illustration = ( + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ); + + return ( + + {({ Title, Text }) => ( + <> + Finansieringsbevis + For deg som skal kjøpe ny bolig + + )} + + ); +}; diff --git a/component-overview/examples/cards/IllustrationCard.jsx b/component-overview/examples/cards/IllustrationCard.jsx new file mode 100644 index 0000000000..c95b35ad1b --- /dev/null +++ b/component-overview/examples/cards/IllustrationCard.jsx @@ -0,0 +1,315 @@ +import { IllustrationCard } from '@sb1/ffe-cards-react'; +import React from 'react'; + +() => { + const illustration = ( + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ); + + return ( + + {({ CardName, Title, Subtext, Text }) => ( + <> + Kortnavn + Tittel + En liten undertekst + Her kan man ha tekst + + )} + + ); +}; diff --git a/packages/ffe-cards-react/src/IllustrationCard/IllustrationCard.spec.tsx b/packages/ffe-cards-react/src/IllustrationCard/IllustrationCard.spec.tsx new file mode 100644 index 0000000000..b05acaab6e --- /dev/null +++ b/packages/ffe-cards-react/src/IllustrationCard/IllustrationCard.spec.tsx @@ -0,0 +1,384 @@ +import React from 'react'; +import { IllustrationCard } from './IllustrationCard'; +import { render, screen } from '@testing-library/react'; + +const children =
Hello world
; +const TEST_ID = 'test-id'; +const illustration = ( + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +); + +describe('IllustrationCard', () => { + it('should render correct class and contain a div with body class', () => { + render( + + {children} + , + ); + const card = screen.getByTestId(TEST_ID); + expect(card.classList.contains('ffe-illustration-card')).toBeTruthy(); + expect(card.querySelector('.ffe-illustration-card__body')).toBeTruthy(); + }); + + it('should add modifying classes when modifiers are given', () => { + render( + + {children} + , + ); + const card = screen.getByTestId(TEST_ID); + expect(card.classList.contains('ffe-illustration-card')).toBeTruthy(); + expect( + card.classList.contains('ffe-illustration-card--condensed'), + ).toBeTruthy(); + }); + + it('should render children as a function', () => { + render( + ( + Hello world + )} + />, + ); + const card = screen.getByTestId(TEST_ID); + const p = card.querySelector('p'); + expect(p?.classList.contains('ffe-card-body__text')).toBeTruthy(); + expect(p?.textContent).toEqual('Hello world'); + }); + + it('should render my custom class', () => { + render( + + {children} + , + ); + const card = screen.getByTestId(TEST_ID); + expect(card.classList.contains('ffe-illustration-card')).toBeTruthy(); + expect(card.classList.contains('my-custom-class')).toBeTruthy(); + }); + + it('should render as wished element', () => { + render( + + {children} + , + ); + expect(screen.getByRole('listitem')).toBeInTheDocument(); + }); + + it('should set ref', () => { + const ref = React.createRef(); + render( + + {children} + , + ); + const listitem = screen.getByRole('listitem'); + expect(listitem).toBe(ref.current); + }); +}); diff --git a/packages/ffe-cards-react/src/IllustrationCard/IllustrationCard.tsx b/packages/ffe-cards-react/src/IllustrationCard/IllustrationCard.tsx new file mode 100644 index 0000000000..bf6e6348eb --- /dev/null +++ b/packages/ffe-cards-react/src/IllustrationCard/IllustrationCard.tsx @@ -0,0 +1,61 @@ +import React, { ElementType, ForwardedRef, ReactElement } from 'react'; +import { CardRenderProps, ComponentAsPropParams } from '../types'; +import classNames from 'classnames'; +import { WithCardAction, Text, Subtext, Title, CardName } from '../components'; +import { fixedForwardRef } from '../fixedForwardRef'; + +export type IllustrationCardProps = Omit< + ComponentAsPropParams, + 'children' +> & { + /** Element of illustration */ + img: ReactElement; + /** Smaller illustration and less space */ + condensed?: boolean; + children: + | React.ReactNode + | ((cardRenderProps: CardRenderProps) => React.ReactNode); +}; + +function IllustrationCardWithForwardRef( + props: IllustrationCardProps, + ref: ForwardedRef, +) { + const { className, condensed, img, children, ...rest } = props; + return ( + )} + ref={ref} + > + {({ CardAction }) => ( + <> +
+ {img} +
+
+ {typeof children === 'function' + ? children({ + Text, + Subtext, + Title, + CardName, + CardAction, + }) + : children} +
+ + )} +
+ ); +} + +export const IllustrationCard = fixedForwardRef(IllustrationCardWithForwardRef); diff --git a/packages/ffe-cards-react/src/index.ts b/packages/ffe-cards-react/src/index.ts index ef1befe360..f533fc9703 100644 --- a/packages/ffe-cards-react/src/index.ts +++ b/packages/ffe-cards-react/src/index.ts @@ -1,5 +1,9 @@ export { CardBase, CardBaseProps } from './CardBase'; export { TextCard, TextCardProps } from './TextCard/TextCard'; export { IconCard, IconCardProps } from './IconCard/IconCard'; +export { + IllustrationCard, + IllustrationCardProps, +} from './IllustrationCard/IllustrationCard'; export { ImageCard, ImageCardProps } from './ImageCard/ImageCard'; export { StippledCard, StippledCardProps } from './StippledCard/StippledCard'; diff --git a/packages/ffe-cards/less/cards.less b/packages/ffe-cards/less/cards.less index 3320bad51c..2db588e560 100644 --- a/packages/ffe-cards/less/cards.less +++ b/packages/ffe-cards/less/cards.less @@ -2,5 +2,6 @@ @import 'card-base'; @import 'text-card'; @import 'icon-card'; +@import 'illustration-card'; @import 'image-card'; @import 'stippled-card'; diff --git a/packages/ffe-cards/less/illustration-card.less b/packages/ffe-cards/less/illustration-card.less new file mode 100644 index 0000000000..e36d5a9999 --- /dev/null +++ b/packages/ffe-cards/less/illustration-card.less @@ -0,0 +1,17 @@ +@import 'common-card-styling'; +@import 'components'; + +.ffe-illustration-card { + .common-card-styling(); + + display: grid; + grid-template-columns: auto 1fr; + column-gap: var(--ffe-spacing-md); + padding: var(--ffe-spacing-md); + align-items: center; + + &--condensed { + column-gap: var(--ffe-spacing-sm); + padding: var(--ffe-spacing-sm); + } +}