diff --git a/component-overview/examples/cards/IllustrationCard-illustrationPositioned.jsx b/component-overview/examples/cards/IllustrationCard-illustrationPositioned.jsx
new file mode 100644
index 0000000000..9a58c86cf8
--- /dev/null
+++ b/component-overview/examples/cards/IllustrationCard-illustrationPositioned.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/IconCard/IconCard.spec.tsx b/packages/ffe-cards-react/src/IconCard/IconCard.spec.tsx
index b39b1bdab4..ff08e94141 100644
--- a/packages/ffe-cards-react/src/IconCard/IconCard.spec.tsx
+++ b/packages/ffe-cards-react/src/IconCard/IconCard.spec.tsx
@@ -7,19 +7,18 @@ const savingsIconXlarge =
'data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGhlaWdodD0iNDgiIHZpZXdCb3g9IjAgLTk2MCA5NjAgOTYwIiB3aWR0aD0iNDgiPjxwYXRoIGQ9Ik0yNDMuMDc4LTE0MC4wMDFxLTIwLjIzMSAwLTM3LjgxNy0xMy4zNy0xNy41ODYtMTMuMzY5LTIzLjEwNi0zMi43MDctMjUtODcuNTM5LTQwLjk2NS0xNDguMjY2LTE1Ljk2Ni02MC43MjctMjUuMDE5LTEwNC42ODItOS4wNTItNDMuOTU1LTEyLjYxMS03Ni43OTEtMy41NTktMzIuODM2LTMuNTU5LTY0LjM2MyAwLTgzLjM1OCA1OC4yMzEtMTQxLjU4OCA1OC4yMy01OC4yMzEgMTQxLjc2OC01OC4yMzFoMjEwLjAwMXEyNy0zNiA2Ni01OCAzOC45OTktMjIgODMuOTk5LTIyIDE2LjUzOCAwIDI4LjI2OCAxMS43MzEgMTEuNzMxIDExLjczIDExLjczMSAyOC4yNjggMCA0LjA3Ny0xLjExNiA3Ljk2MS0xLjExNSAzLjg4NS0yLjM0NiA3LjczMS00LjM4NSAxMS43NjktOC40NjEgMjUuNDYyLTQuMDc3IDEzLjY5Mi03LjYxNiAzNC43N2wxMDQuMDc4IDEwNC4wNzdoNDYuNjE0cTEyLjM1NiAwIDIwLjYwMSA4LjI0NiA4LjI0NiA4LjI0NSA4LjI0NiAyMC42MDF2MTk0LjMwNXEwIDkuODc4LTUuMjQ2IDE3LjU5NS01LjI0NiA3LjcxNy0xNC45ODUgMTAuMjUxbC04OC44NDkgMjkuNTI4LTUzLjMwNSAxNzguMDFxLTYuMDI2IDE4Ljg0NS0yMS4wNzUgMzAuMTUzLTE1LjA0OSAxMS4zMDktMzQuNjE3IDExLjMwOWgtODQuMjI4cS0yMy41OTYgMC00MC42NDUtMTcuMDQ4LTE3LjA0OC0xNy4wNDktMTcuMDQ4LTQwLjY0NXYtMjIuMzA3SDM3OS45OTl2MjIuMzA3cTAgMjMuNTk2LTE3LjA0OCA0MC42NDUtMTcuMDQ5IDE3LjA0OC00MC42NDUgMTcuMDQ4aC03OS4yMjhabS0zLjg0Ni00NS4zODRoODMuMDc0cTUuMzg1IDAgOC44NDctMy40NjIgMy40NjItMy40NjIgMy40NjItOC44NDd2LTY3LjY5MWgyMTAuNzd2NjcuNjkxcTAgNS4zODUgMy40NjIgOC44NDcgMy40NjIgMy40NjIgOC44NDcgMy40NjJoODQuMjI4cTMuODQ3IDAgNy4xMTYtMi4zMDggMy4yNjktMi4zMDggNC44MDgtNi41MzlsNTkuOTIzLTE5OS45OTkgMTAwLjg0Ni0zNC42MTV2LTE2NS43NjloLTQ4LjkyM0w2MzQuNjE1LTcyNS42OTJxLjYxNS0xNyA0LjczMS00MC43MzEgNC4xMTUtMjMuNzMxIDExLjczLTQ5LjQ5OS0zNy45OTkgOS44NDYtNjguNDk5IDMyLjAzOC0zMC41IDIyLjE5Mi00NS4xMTUgNDkuMjY5SDMwMHEtNjQuMzYzIDAtMTA5LjQ4OSA0NS4xMjZRMTQ1LjM4NS02NDQuMzYyIDE0NS4zODUtNTgwcTAgNDEuMjMxIDIxLjAzOCAxNDEuNjkyIDIxLjAzOSAxMDAuNDYxIDYwLjExNiAyNDMuMzA3IDEuMTU0IDQuMjMxIDQuODA4IDYuOTIzIDMuNjU0IDIuNjkzIDcuODg1IDIuNjkzWk02NDAtNTI0LjYxNnExNC42OTIgMCAyNS4wMzgtMTAuMzQ2VDY3NS4zODQtNTYwcTAtMTQuNjkyLTEwLjM0Ni0yNS4wMzhUNjQwLTU5NS4zODRxLTE0LjY5MiAwLTI1LjAzOCAxMC4zNDZUNjA0LjYxNi01NjBxMCAxNC42OTIgMTAuMzQ2IDI1LjAzOFQ2NDAtNTI0LjYxNlptLTE0Mi42OTItMTAwcTkuNjYzIDAgMTYuMTc4LTYuNTY2UTUyMC02MzcuNzQ5IDUyMC02NDcuNDlxMC05Ljc0LTYuNTE0LTE2LjEyNS02LjUxNS02LjM4NC0xNi4xNzgtNi4zODRIMzQyLjY5MnEtOS42NjMgMC0xNi4xNzggNi41NjZRMzIwLTY1Ni44NjYgMzIwLTY0Ny4xMjVxMCA5Ljc0IDYuNTE0IDE2LjEyNSA2LjUxNSA2LjM4NCAxNi4xNzggNi4zODRoMTU0LjYxNlpNNDgwLTUwMC44NDZaIi8+PC9zdmc+';
const children =
Hello world
;
-const TEST_ID = 'test-id';
describe('IconCard', () => {
it('should render correct class and contain a div with body class', () => {
render(
}
>
{children}
,
);
- const card = screen.getByTestId(TEST_ID);
+ const card = screen.getByRole('listitem');
expect(card.classList.contains('ffe-icon-card')).toBeTruthy();
expect(card.querySelector('.ffe-icon-card__body')).toBeTruthy();
});
@@ -27,7 +26,7 @@ describe('IconCard', () => {
it('should render icon, with an added class', () => {
render(
{
{children}
,
);
- const card = screen.getByTestId(TEST_ID);
+ const card = screen.getByRole('listitem');
const icon = card.querySelector('.ffe-icons');
expect(icon?.classList.contains('ffe-icon-card__icon')).toBe(true);
expect(icon?.classList.contains('my-custom-class')).toBe(true);
@@ -48,14 +47,14 @@ describe('IconCard', () => {
it('should add modifying classes when modifiers are given', () => {
render(
}
>
{children}
,
);
- const card = screen.getByTestId(TEST_ID);
+ const card = screen.getByRole('listitem');
expect(card.classList.contains('ffe-icon-card')).toBeTruthy();
expect(
card.classList.contains('ffe-icon-card--condensed'),
@@ -65,38 +64,36 @@ describe('IconCard', () => {
it('should render icon on the right when modifier iconPosition="right', () => {
render(
}
>
{children}
,
);
- const card = screen.getByTestId(TEST_ID);
+ const card = screen.getByRole('listitem');
+ const body = card.querySelector('.ffe-icon-card__body') as Element;
+ const icon = card.querySelector('.ffe-icon-card__icon') as Element;
expect(card.classList.contains('ffe-icon-card')).toBeTruthy();
+ expect(card.classList.contains('ffe-icon-card--right')).toBeTruthy();
- const icon = card.querySelector('.ffe-icon-card__icon');
- const body = card.querySelector('.ffe-icon-card__body');
-
- if (icon && body) {
- expect(
- body?.compareDocumentPosition(icon) &
- Node.DOCUMENT_POSITION_FOLLOWING,
- ).toBeTruthy();
- }
+ expect(
+ body?.compareDocumentPosition(icon) &
+ Node.DOCUMENT_POSITION_FOLLOWING,
+ ).toBeTruthy();
});
it('should render children as a function', () => {
render(
}
children={Components => (
Hello world
)}
/>,
);
- const card = screen.getByTestId(TEST_ID);
+ const card = screen.getByRole('listitem');
const p = card.querySelector('p');
expect(p?.classList.contains('ffe-card-body__text')).toBeTruthy();
expect(p?.textContent).toEqual('Hello world');
@@ -105,14 +102,14 @@ describe('IconCard', () => {
it('should render my custom class', () => {
render(
}
className="my-custom-class"
>
{children}
,
);
- const card = screen.getByTestId(TEST_ID);
+ const card = screen.getByRole('listitem');
expect(card.classList.contains('ffe-icon-card')).toBeTruthy();
expect(card.classList.contains('my-custom-class')).toBeTruthy();
});
diff --git a/packages/ffe-cards-react/src/IconCard/IconCard.tsx b/packages/ffe-cards-react/src/IconCard/IconCard.tsx
index 87eec8a07c..0fc2f0bffd 100644
--- a/packages/ffe-cards-react/src/IconCard/IconCard.tsx
+++ b/packages/ffe-cards-react/src/IconCard/IconCard.tsx
@@ -25,6 +25,7 @@ function IconCardWithForwardRef(
) {
const { className, condensed, icon, children, iconPosition, ...rest } =
props;
+
return (
(
ref={ref}
>
{({ CardAction }) => {
- const content = [
- React.cloneElement(icon, {
- ...icon.props,
- key: 'icon',
- className: classNames(
- 'ffe-icon-card__icon',
- icon.props.className,
- ),
- }),
-
+ const bodyElement = (
+
{typeof children === 'function'
? children({
Text,
@@ -57,11 +50,26 @@ function IconCardWithForwardRef
(
CardAction,
})
: children}
- ,
- ];
- return (
+
+ );
+
+ const iconElement = React.cloneElement(icon, {
+ ...icon.props,
+ className: classNames(
+ 'ffe-icon-card__icon',
+ icon.props.className,
+ ),
+ });
+
+ return iconPosition === 'right' ? (
+ <>
+ {bodyElement}
+ {iconElement}
+ >
+ ) : (
<>
- {iconPosition === 'right' ? content.reverse() : content}
+ {iconElement}
+ {bodyElement}
>
);
}}
diff --git a/packages/ffe-cards-react/src/IllustrationCard/IllustrationCard.spec.tsx b/packages/ffe-cards-react/src/IllustrationCard/IllustrationCard.spec.tsx
index b05acaab6e..5b15f3167b 100644
--- a/packages/ffe-cards-react/src/IllustrationCard/IllustrationCard.spec.tsx
+++ b/packages/ffe-cards-react/src/IllustrationCard/IllustrationCard.spec.tsx
@@ -13,288 +13,6 @@ const illustration = (
fill="none"
aria-hidden={true}
>
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
{
const listitem = screen.getByRole('listitem');
expect(listitem).toBe(ref.current);
});
+
+ it('should render illustration on the right when modifier iconPosition="right', () => {
+ render(
+
+ {children}
+ ,
+ );
+ const card = screen.getByRole('listitem');
+ const bodyElement = card.querySelector(
+ '.ffe-illustration-card__body',
+ ) as Element;
+ const illustrationElement = card.querySelector(
+ '.ffe-illustration-card__illustration',
+ ) as Element;
+ expect(card.classList.contains('ffe-illustration-card')).toBeTruthy();
+ expect(
+ card.classList.contains('ffe-illustration-card--right'),
+ ).toBeTruthy();
+
+ expect(
+ bodyElement?.compareDocumentPosition(illustrationElement) &
+ Node.DOCUMENT_POSITION_FOLLOWING,
+ ).toBeTruthy();
+ });
});
diff --git a/packages/ffe-cards-react/src/IllustrationCard/IllustrationCard.tsx b/packages/ffe-cards-react/src/IllustrationCard/IllustrationCard.tsx
index 2c2d252e68..5271e9ddb6 100644
--- a/packages/ffe-cards-react/src/IllustrationCard/IllustrationCard.tsx
+++ b/packages/ffe-cards-react/src/IllustrationCard/IllustrationCard.tsx
@@ -12,6 +12,8 @@ export type IllustrationCardProps = Omit<
img: ReactElement;
/** Smaller illustration and less space */
condensed?: boolean;
+ /** Position illustration at left (default) or right of the card content */
+ illustrationPosition?: 'right' | 'left';
children:
| React.ReactNode
| ((cardRenderProps: CardRenderProps) => React.ReactNode);
@@ -21,20 +23,31 @@ function IllustrationCardWithForwardRef(
props: IllustrationCardProps,
ref: ForwardedRef,
) {
- const { className, condensed, img, children, ...rest } = props;
+ const {
+ className,
+ condensed,
+ img,
+ illustrationPosition,
+ children,
+ ...rest
+ } = props;
return (
)}
ref={ref}
>
- {({ CardAction }) => (
- <>
+ {({ CardAction }) => {
+ const illustrationElement = (
(
>
{img}
+ );
+
+ const bodyElement = (
{typeof children === 'function'
? children({
@@ -53,8 +69,20 @@ function IllustrationCardWithForwardRef
(
})
: children}
- >
- )}
+ );
+
+ return illustrationPosition === 'right' ? (
+ <>
+ {bodyElement}
+ {illustrationElement}
+ >
+ ) : (
+ <>
+ {illustrationElement}
+ {bodyElement}
+ >
+ );
+ }}
);
}
diff --git a/packages/ffe-cards/less/icon-card.less b/packages/ffe-cards/less/icon-card.less
index 61e6c84775..868864ddb7 100644
--- a/packages/ffe-cards/less/icon-card.less
+++ b/packages/ffe-cards/less/icon-card.less
@@ -12,28 +12,21 @@
grid-template-columns: auto 1fr;
align-items: center;
padding: var(--ffe-spacing-md);
+ gap: var(--ffe-spacing-xs);
- & > &__icon {
- color: var(--ffe-v-cards-icon-color);
- margin: 0 var(--ffe-spacing-lg) 0 var(--ffe-spacing-xs);
- }
-
- &.ffe-icon-card--right {
- .ffe-icon-card__icon {
- justify-self: end;
- margin: 0 var(--ffe-spacing-xs) 0 var(--ffe-spacing-lg);
- }
+ &--right {
+ grid-template-columns: 1fr auto;
+ justify-content: space-between;
}
@media (min-width: @breakpoint-md) {
- .ffe-icon-card__icon {
- margin: 0 var(--ffe-spacing-md) 0;
+ gap: var(--ffe-spacing-md);
+ &--condensed {
+ gap: var(--ffe-spacing-xs);
}
}
-}
-.ffe-icon-card--condensed {
.ffe-icon-card__icon {
- margin: 0 var(--ffe-spacing-sm) 0 0;
+ color: var(--ffe-v-cards-icon-color);
}
}
diff --git a/packages/ffe-cards/less/illustration-card.less b/packages/ffe-cards/less/illustration-card.less
index 79532c290a..bb60f662a9 100644
--- a/packages/ffe-cards/less/illustration-card.less
+++ b/packages/ffe-cards/less/illustration-card.less
@@ -18,4 +18,9 @@
column-gap: var(--ffe-spacing-sm);
padding: var(--ffe-spacing-sm);
}
+
+ &--right {
+ grid-template-columns: 1fr auto;
+ justify-content: space-between;
+ }
}