Skip to content

Commit

Permalink
feat(LinkCard & ServiceCard): correction clic sur la carte (#3329)
Browse files Browse the repository at this point in the history
* feat(LinkCard): correction du clic sur la carte

* feat(ServiceCard): correction du clic sur la carte

* Update src/client/components/features/ServiceCard/Card/ServiceCard.module.scss

Co-authored-by: Gauthier Fiorentino <[email protected]>

* Update src/client/components/features/ServiceCard/Card/ServiceCard.module.scss

Co-authored-by: Gauthier Fiorentino <[email protected]>

* Update src/client/components/features/ServiceCard/Card/ServiceCard.module.scss

Co-authored-by: Gauthier Fiorentino <[email protected]>

* Update src/client/components/ui/Card/Link/LinkCard.tsx

Co-authored-by: Gauthier Fiorentino <[email protected]>

* Update src/client/components/ui/Card/Link/LinkCard.tsx

Co-authored-by: Gauthier Fiorentino <[email protected]>

* Update src/client/components/features/ServiceCard/Card/ServiceCard.tsx

Co-authored-by: Gauthier Fiorentino <[email protected]>

* Update src/client/components/ui/Card/Link/LinkCard.tsx

Co-authored-by: Gauthier Fiorentino <[email protected]>

* fix(ServiceCard): fix test

* fix(LinkCard): correction a11y

* fix(test): corrections tests cassés

* wip: Fix test peu explicite

* wip: Fix le mock du router dans chaque test

* refactor: Supprime le FakeLink

* refactor: Passe les props du LinkCardTitle au composant

* fix: Fix le libellé du lien des LinkCards

* fix: Fix title invalide pour les liens internes

* tests: Fix les noms des liens dans les tests

---------

Co-authored-by: Gauthier Fiorentino <[email protected]>
  • Loading branch information
sylviamoreno and Mintoo200 authored Oct 9, 2024
1 parent 4abf273 commit d58b4fd
Show file tree
Hide file tree
Showing 8 changed files with 203 additions and 153 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ describe('RechercherMission', () => {
beforeEach(() => {
mockSmallScreen();
mockScrollIntoView();
mockUseRouter({});
});

afterEach(() => {
Expand Down Expand Up @@ -325,18 +326,18 @@ describe('RechercherMission', () => {
);

const serviceCardsUl = await screen.findByRole('list', { name: 'Liste des partenaires et des services' });
const serviceCards = within(serviceCardsUl).getAllByRole('link');
const serviceCards = within(serviceCardsUl).getAllByTestId(/^card-.*$/);
expect(serviceCards).toHaveLength(2);
expect(within(serviceCards[0]).getByRole('heading', {
level: 3,
name: 'Pourquoi faire un service civique ?',
})).toBeVisible();
expect(serviceCards[0]).toHaveAttribute('href', '/articles/faire-un-service-civique');
expect(within(serviceCards[0]).getByRole('link')).toHaveAttribute('href', '/articles/faire-un-service-civique');
expect(within(serviceCards[1]).getByRole('heading', {
level: 3,
name: "L'impact du service civique sur les jeunes",
})).toBeVisible();
expect(serviceCards[1]).toHaveAttribute('href', '/articles/service-civique-jeunes');
expect(within(serviceCards[1]).getByRole('link')).toHaveAttribute('href', '/articles/service-civique-jeunes');
});
});
describe('lorsque le page est celle du bénévolat', () => {
Expand All @@ -349,13 +350,13 @@ describe('RechercherMission', () => {
);

const serviceCardsUl = await screen.findByRole('list', { name: 'Liste des partenaires et des services' });
const serviceCards = within(serviceCardsUl).getAllByRole('link');
const serviceCards = within(serviceCardsUl).getAllByTestId(/^card-.*$/);
expect(serviceCards).toHaveLength(1);
expect(within(serviceCards[0]).getByRole('heading', {
level: 3,
name: 'Des missions de bénévolat toujours disponibles',
})).toBeVisible();
expect(serviceCards[0]).toHaveAttribute('href', '/articles/des-missions-de-benevolat-toujours-disponibles');
expect(within(serviceCards[0]).getByRole('link')).toHaveAttribute('href', '/articles/des-missions-de-benevolat-toujours-disponibles');
});
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -123,10 +123,14 @@ describe('StatistiquesFormation', () => {
it('affiche un article inserjeunes', () => {
render(<StatistiquesFormationAlternance statistiques={statistiques()} />);

const article = screen.getByRole('link');
expect(article).toHaveTextContent('Découvrez le dispositif InserJeunes');
expect(article).toBeVisible();

const partenaires = screen.getByRole('list', { name: 'Liste des partenaires et des services' });
const titre = within(partenaires).getByRole('heading', { name: 'Découvrez le dispositif InserJeunes' });
expect(titre).toBeVisible();
const lien = within(partenaires).getByRole('link');
expect(lien).toBeVisible();
expect(lien).toHaveTextContent("Lire l'article");
expect(lien).toHaveAccessibleName(expect.stringContaining('Découvrez le dispositif InserJeunes'));
expect(lien).toHaveAccessibleName(expect.stringContaining("Lire l'article"));
});

});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,42 +30,45 @@ $card-border-color: utilities.$color-background-border;
}
}

.cardContainer {
display: block;
.serviceCard {
position: relative;
border: 1px solid $card-border-color;
border-radius: 20px;
display: grid;
grid-template-rows: 7.75rem 1fr;

& .serviceCard {
display: grid;
grid-template-rows: 7.75rem 1fr;
@include utilities.media(small) {
grid-template-rows: unset;
grid-template-columns: 18.875rem 1fr;
grid-auto-flow: column;
}

& .cardLogo {
align-self: center;
justify-self: center;
min-height: 92px;
min-width: min(310px, 100%);

@include utilities.media(small) {
grid-template-rows: unset;
grid-template-columns: 18.875rem 1fr;
grid-auto-flow: column;
width: 100%;
min-width: 140px;
border: 0;
}
}

& .cardLogo {
align-self: center;
justify-self: center;
align-items: center;
justify-content: center;
min-height: 92px;
min-width: min(310px, 100%);

@include utilities.media(small) {
width: 100%;
min-width: 140px;
flex-shrink: 0;
border: 0;
}
img {
object-fit: contain;
@include utilities.media(small) {
padding: 0 64px;
}
}

img {
object-fit: contain;
@include utilities.media(small) {
padding: 0 64px;
}
a {
&::before {
content: '';
position: absolute;
inset: 0;
background-color: transparent;
}
}

Expand Down Expand Up @@ -112,7 +115,7 @@ $card-border-color: utilities.$color-background-border;
}

& .cardAction {
@extend %linkWithRightIcon;
align-self: flex-end;
}
}
}
52 changes: 27 additions & 25 deletions src/client/components/features/ServiceCard/Card/ServiceCard.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
import classNames from 'classnames';
import React, { useMemo } from 'react';
import React, { useId } from 'react';

import { HtmlHeadingTag } from '~/client/components/props';
import { Card } from '~/client/components/ui/Card/Card';
import { Icon } from '~/client/components/ui/Icon/Icon';
import { Link } from '~/client/components/ui/Link/Link';
import { useIsInternalLink } from '~/client/hooks/useIsInternalLink';

Expand Down Expand Up @@ -45,33 +44,36 @@ export function ServiceCard(props: ServiceCardProps & React.HTMLAttributes<HTMLL
const {
className, imageFit = 'contain', logo, logoAlt = '', link, linkLabel, title, titleAs, children,
} = props;
const idLink = useId();
const idIntitulé = useId();

const isInternalLink = useIsInternalLink(link);
const linkTitle = !isInternalLink ? `${linkLabel} - nouvelle fenêtre` : undefined;
const icon = useMemo(function () {
return <Icon name={isInternalLink ? 'arrow-right' : 'external-redirection'} />;
}, [isInternalLink]);


// TODO remplacer link sur toute la card par un lien avec un ::before pour rendre toute la card cliquable
return (
<Link href={link} title={linkTitle} className={classNames(styles.cardContainer, className, 'underline-none')}>
<Card
layout={'vertical'}
className={classNames(
styles.card,
className,
styles.serviceCard,
imageFit === 'cover' && styles.cardCover)}>
<Card.Image className={styles.cardLogo} src={logo} alt={logoAlt} />
<Card.Content className={styles.cardBody}>
<Card.Title titleAs={titleAs} className={styles.cardTitle}>{title}</Card.Title>
<p>{children}</p>
<span className={styles.cardAction}>
<Card.FakeLink appearance={'quaternary'} label={linkLabel} icon={icon} />
</span>
</Card.Content>
</Card>
</Link>
<Card
layout={'vertical'}
data-testid={`card-${idIntitulé}`}
className={classNames(
styles.card,
className,
styles.serviceCard,
imageFit === 'cover' && styles.cardCover)}>
<Card.Image className={styles.cardLogo} src={logo} alt={logoAlt} />
<Card.Content className={styles.cardBody}>
<Card.Title id={idIntitulé} titleAs={titleAs} className={styles.cardTitle}>{title}</Card.Title>
<p>{children}</p>
<Link
href={link}
title={linkTitle}
aria-labelledby={`${idIntitulé} ${idLink}`}
className={styles.cardAction}
appearance="asQuaternaryButton"
id={idLink}>
{linkLabel}
<Link.Icon />
</Link>
</Card.Content>
</Card>
);
}
134 changes: 69 additions & 65 deletions src/client/components/ui/Card/Link/LinkCard.module.scss
Original file line number Diff line number Diff line change
@@ -1,81 +1,85 @@
@use "@styles/utilities-deprecated";
@use "@styles/utilities";

.card {
position: relative;
border-radius: 20px;
box-shadow: 10px 10px 20px rgba(22, 22, 22, 0.05);
background-color: utilities.$color-background-primary;
padding: 1rem;
max-height: calc(250px + 8.75rem);
overflow: hidden;

display: inline-block;
width: 100%;
&ImageWrapper {
border-radius: 20px;
min-height: 150px;
max-height: 150px;
flex: 0 1 200px;
overflow: hidden;

&Article {
border-radius: 20px;
box-shadow: 10px 10px 20px rgba(22, 22, 22, 0.05) !important;
background-color: utilities-deprecated.$color-on-primary;
position: relative;
border-radius: 20px;
display: flex;
flex-direction: column;
padding: 1rem;
max-height: calc(250px + 8.75rem);
overflow: hidden;
img {
height: 180px;
width: 328px;
}
&ImageWrapper {
position: relative;
border-radius: 20px;
min-height: 150px;
max-height: 150px;
flex: 0 1 200px;
overflow: hidden;
}

img {
height: 180px;
width: 328px;
}
}
&Content {
min-height: 9rem;
padding-top: 0.75rem;
overflow: auto;
&Header {
margin-bottom: 0.25rem;
display: flex;
justify-content: space-between;
}
&Content {
min-height: 9rem;
padding-top: 0.75rem;
overflow: auto;
&Header {
margin-bottom: 0.25rem;
display: flex;
justify-content: space-between;
}
}

&Title {
font-size: 1em;
font-weight: bold;
line-height: 1.2;
margin-bottom: 0;
}
&Title {
font-size: 1em;
font-weight: bold;
line-height: 1.2;
margin-bottom: 0;
}

&Description > * {
font-size: 1em;
padding-right: 2rem;
margin: 0;
}
&Description > * {
font-size: 1em;
padding-right: 2rem;
margin: 0;
}

&Action {
background-color: utilities.$color-primary;
border-radius: 50%;
padding: 0.25rem;
color: utilities.$color-cta-texte-primary;
width: 2rem;
height: 2rem;

&Action {
background-color: utilities-deprecated.$color-primary;
border-radius: 50%;
padding: 0.25rem;
color: utilities-deprecated.$color-on-primary;
width: 2rem;
height: 2rem;
& > a {
&::before {
content: '';
position: absolute;
left: 0;
right: 0;
top: 0;
bottom: 0;
background-color: rgba(0, 0, 0, 0);
}
}
}
}

@include utilities-deprecated.media(medium) {
.card {
&ImageWrapper {
min-height: 180px;
max-height: 180px;
}
@include utilities.media(medium) {
.card {
&ImageWrapper {
min-height: 180px;
max-height: 180px;
}

&Content {
padding-top: 1.25rem;
}
&Title {
font-size: 1.25rem;
}
&Content {
padding-top: 1.25rem;
}
&Title {
font-size: 1.25rem;
}
}
}
29 changes: 29 additions & 0 deletions src/client/components/ui/Card/Link/LinkCard.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
/**
* @jest-environment jsdom
*/

import {
render,
screen,
} from '@testing-library/react';

import { LinkCard } from '~/client/components/ui/Card/Link/LinkCard';

describe('LinkCard', () => {
const defaultProps = {
imageUrl: 'https://example.com/image.jpg',
link: 'https://example.com',
linkLabel: 'En savoir plus',
title: 'Titre de test',
};

it('affiche une carte lien avec tous les éléments', () => {
render(<LinkCard {...defaultProps} />);

expect(screen.getByRole('heading', { name: defaultProps.title })).toBeVisible();
expect(screen.getByRole('link')).toHaveAttribute('href', defaultProps.link);
expect(screen.getByText(defaultProps.linkLabel)).toBeVisible();
expect(screen.getByText(defaultProps.linkLabel)).toHaveClass('sr-only');
expect(screen.getByRole('presentation')).toHaveAttribute('alt', '');
});
});
Loading

0 comments on commit d58b4fd

Please sign in to comment.