Skip to content

Commit

Permalink
Merge pull request #447 from InseeFr/feat/html-validation
Browse files Browse the repository at this point in the history
Feat/html validation
  • Loading branch information
jdirand authored Oct 17, 2023
2 parents 153d987 + 020f3f9 commit ec63145
Show file tree
Hide file tree
Showing 24 changed files with 544 additions and 391 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
"private": true,
"dependencies": {
"@axa-fr/react-oidc": "6.14.0",
"@codegouvfr/react-dsfr": "^0.75.3",
"@codegouvfr/react-dsfr": "^0.78.1",
"@emotion/react": "^11.10.5",
"@emotion/styled": "^11.10.5",
"@inseefr/lunatic": "2.6.2",
Expand Down
2 changes: 1 addition & 1 deletion src/components/DraftBanner/BannerAddress.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,5 @@ export function BannerAddress(props: Props) {
if (!label) {
return null;
}
return <span className={fr.cx('fr-text--bold', 'fr-mr-2w')}>{label}</span>;
return <p className={fr.cx('fr-text--bold', 'fr-mr-2w', 'fr-mb-0')}>{label}</p>;
}
4 changes: 2 additions & 2 deletions src/components/DraftBanner/SaveMessage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,9 @@ export function SaveMessage(props: Props) {
);
}
return (
<span className={fr.cx('fr-col-12', 'fr-col-md-10')}>
<p className={fr.cx('fr-col-12', 'fr-col-md-10', 'fr-mb-0')}>
Vos réponses sont enregistrées automatiquement à chaque chargement de
page.
</span>
</p>
);
}
163 changes: 161 additions & 2 deletions src/components/Header/Header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,10 @@ import { DEFAULT_HEADER } from './default-header';
import ConvertContent from '../../utils/convertContent';
import Button from '@codegouvfr/react-dsfr/Button';
import { fr } from '@codegouvfr/react-dsfr';
import Display from '@codegouvfr/react-dsfr/Display/Display';
import { Link } from 'react-router-dom';
import Sun from '@codegouvfr/react-dsfr/dsfr/artwork/pictograms/environment/sun.svg';
import Moon from '@codegouvfr/react-dsfr/dsfr/artwork/pictograms/environment/moon.svg';
import System from '@codegouvfr/react-dsfr/dsfr/artwork/pictograms/system/system.svg';

function getAuthLabel(isAuthenticated: boolean): string {
if (isAuthenticated) {
Expand Down Expand Up @@ -185,6 +187,7 @@ export function Header(props: HeaderProps) {
</Button>
) : (
<Button
iconId={quickAccessItem.iconId}
linkProps={{
target: quickAccessItem.linkProps?.target,
to: quickAccessItem.linkProps?.href,
Expand All @@ -205,7 +208,163 @@ export function Header(props: HeaderProps) {
</div>
</div>
</header>
<Display />
<dialog
id="fr-theme-modal"
className="fr-modal"
aria-labelledby="fr-theme-modal-title"
>
<div className="fr-container fr-container--fluid fr-container-md">
<div className="fr-grid-row fr-grid-row--center">
<div className="fr-col-12 fr-col-md-6 fr-col-lg-4">
<div className="fr-modal__body">
<div className="fr-modal__header">
<button
className="fr-btn--close fr-btn"
aria-controls="fr-theme-modal"
id="button-5622"
title="Fermer"
>
Fermer
</button>
</div>
<div className="fr-modal__content">
<h1 id="fr-theme-modal-title" className="fr-modal__title">
Paramètres d’affichage
</h1>
<div id="fr-display" className="fr-display">
<fieldset className="fr-fieldset" id="display-fieldset">
<legend
className="fr-fieldset__legend--regular fr-fieldset__legend"
id="display-fieldset-legend"
>
Choisissez un thème pour personnaliser l’apparence du
site.
</legend>
<div className="fr-fieldset__element">
<div className="fr-radio-group fr-radio-rich">
<input
value="light"
type="radio"
id="fr-radios-theme-light"
name="fr-radios-theme"
/>
<label
className="fr-label"
htmlFor="fr-radios-theme-light"
>
Thème clair
</label>
<div className="fr-radio-rich__img">
<svg
aria-hidden="true"
className="fr-artwork"
viewBox="0 0 80 80"
width="80px"
height="80px"
>
<use
className="fr-artwork-decorative"
xlinkHref={`${Sun}#artwork-decorative`}
></use>
<use
className="fr-artwork-minor"
xlinkHref={`${Sun}#artwork-minor`}
></use>
<use
className="fr-artwork-major"
xlinkHref={`${Sun}#artwork-major`}
></use>
</svg>
</div>
</div>
</div>
<div className="fr-fieldset__element">
<div className="fr-radio-group fr-radio-rich">
<input
value="dark"
type="radio"
id="fr-radios-theme-dark"
name="fr-radios-theme"
/>
<label
className="fr-label"
htmlFor="fr-radios-theme-dark"
>
Thème sombre
</label>
<div className="fr-radio-rich__img">
<svg
aria-hidden="true"
className="fr-artwork"
viewBox="0 0 80 80"
width="80px"
height="80px"
>
<use
className="fr-artwork-decorative"
xlinkHref={`${Moon}#artwork-decorative`}
></use>
<use
className="fr-artwork-minor"
xlinkHref={`${Moon}#artwork-minor`}
></use>
<use
className="fr-artwork-major"
xlinkHref={`${Moon}#artwork-major`}
></use>
</svg>
</div>
</div>
</div>
<div className="fr-fieldset__element">
<div className="fr-radio-group fr-radio-rich">
<input
value="system"
type="radio"
id="fr-radios-theme-system"
name="fr-radios-theme"
/>
<label
className="fr-label"
htmlFor="fr-radios-theme-system"
>
Système
<span className="fr-hint-text">
Utilise les paramètres système
</span>
</label>
<div className="fr-radio-rich__img">
<svg
aria-hidden="true"
className="fr-artwork"
viewBox="0 0 80 80"
width="80px"
height="80px"
>
<use
className="fr-artwork-decorative"
xlinkHref={`${System}#artwork-decorative`}
></use>
<use
className="fr-artwork-minor"
href={`${System}#artwork-minor`}
></use>
<use
className="fr-artwork-major"
href={`${System}#artwork-major`}
></use>
</svg>
</div>
</div>
</div>
</fieldset>
</div>
</div>
</div>
</div>
</div>
</div>
</dialog>
</>
);
}
4 changes: 2 additions & 2 deletions src/components/Oidc/Authenticating.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,8 @@ export function Authenticating() {
className={fr.cx('fr-artwork')}
aria-hidden="true"
viewBox="0 0 80 80"
width="320px"
height="320px"
width="320"
height="320"
>
<use
className={fr.cx('fr-artwork-decorative')}
Expand Down
4 changes: 2 additions & 2 deletions src/components/Oidc/AuthenticatingError.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,8 @@ export function AuthenticatingError() {
className={fr.cx('fr-artwork')}
aria-hidden="true"
viewBox="0 0 80 80"
width="320px"
height="320px"
width="320"
height="320"
>
<use
className={fr.cx('fr-artwork-decorative')}
Expand Down
4 changes: 2 additions & 2 deletions src/components/Oidc/CallbackSuccess.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,8 @@ export function CallbackSuccess() {
className={fr.cx('fr-artwork')}
aria-hidden="true"
viewBox="0 0 80 80"
width="240px"
height="240px"
width="240"
height="240"
>
<use
className={fr.cx('fr-artwork-decorative')}
Expand Down
4 changes: 2 additions & 2 deletions src/components/Oidc/ServiceWorkerNotSupported.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,8 @@ export function ServiceWorkerNotSupported() {
className={fr.cx('fr-artwork')}
aria-hidden="true"
viewBox="0 0 80 80"
width="320px"
height="320px"
width="320"
height="320"
>
<use
className={fr.cx('fr-artwork-decorative')}
Expand Down
4 changes: 2 additions & 2 deletions src/components/Oidc/SessionLost.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,8 @@ export function SessionLost() {
className={fr.cx('fr-artwork')}
aria-hidden="true"
viewBox="0 0 80 80"
width="320px"
height="320px"
width="320"
height="320"
>
<use
className={fr.cx('fr-artwork-decorative')}
Expand Down
3 changes: 2 additions & 1 deletion src/components/OptionalPage/OptionalPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ export function OptionalPage({ name }: { name?: string }) {
const [metadata, setMetadata] = useState<MetadataSurvey>();
const navigate = useNavigate();


useEffect(() => {
if (name && metadata) {
if (name in metadata?.optionalPages) {
Expand All @@ -66,7 +67,7 @@ export function OptionalPage({ name }: { name?: string }) {

return (
<div
className={fr.cx('fr-col-lg-6', 'fr-col-md-9', 'fr-col-12', 'fr-m-10v')}
className={fr.cx('fr-col-lg-6', 'fr-col-md-9', 'fr-col-11', 'fr-m-10v')}
>
{body}
</div>
Expand Down
18 changes: 10 additions & 8 deletions src/components/OptionalPage/elements/Section.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,36 +3,38 @@ import DOMPurify from 'dompurify';
import { SectionElement } from '../../../typeStromae/type';
import { fr } from '@codegouvfr/react-dsfr';

function Paragraph({ content, id }: { id?: string; content: string }) {
function Paragraph({ content, id, title }: { id?: string; content: string; title?: string }) {
return (
<>
{title && <h4>{title}</h4> }
<p
className={fr.cx('fr-mt-4v', 'fr-mb-0')}
className={fr.cx('fr-mt-4v')}
key={`paragraph-${id}`}
dangerouslySetInnerHTML={{
__html: DOMPurify.sanitize(content, {
ALLOWED_TAGS: ['b', 'i', 'a', 'li', 'ul'],
ALLOWED_TAGS: ['b', 'i', 'a', 'li', 'ul', 'h4'],
ALLOWED_ATTR: ['target', 'href', 'title'],
}),
}}
></p>
}} />
</>
);
}

function getContent(paragraphs: Array<string> | string, id?: string) {
function getContent(paragraphs: Object | string, id?: string) {
if (typeof paragraphs === 'string') {
return <Paragraph id={id} content={paragraphs} />;
}
if (Array.isArray(paragraphs)) {
return paragraphs.map((p, id, index) => {
const idParagraph = `paragraph-${id}-${index}`;
return <Paragraph id={idParagraph} content={p} key={idParagraph} />;
return <Paragraph id={idParagraph} title={p.title} content={p.paragraph || p} key={idParagraph} />;
});
}
return null;
}

export function Section(props: SectionElement) {
const { title, paragraphs = [], id, className } = props;
const { title, paragraphs = {}, id, className } = props;

return (
<section
Expand Down
42 changes: 12 additions & 30 deletions src/components/OptionalPage/elements/Title.tsx
Original file line number Diff line number Diff line change
@@ -1,40 +1,22 @@
import classnames from 'classnames';
import { TitleElement } from '../../../typeStromae/type';
import { fr } from '@codegouvfr/react-dsfr';
import Button from '@codegouvfr/react-dsfr/Button';
import { Link } from 'react-router-dom';
import Breadcrumb from '@codegouvfr/react-dsfr/Breadcrumb';
import { useDocumentTitle } from '../../../utils/useDocumentTitle';

export function Title(props: TitleElement) {
const { title, id, className } = props;
useDocumentTitle(title);
return (
<div>
<nav
role="navigation"
className={fr.cx('fr-breadcrumb')}
aria-label="vous êtes ici :"
>
<Button
className={fr.cx('fr-breadcrumb__button')}
aria-expanded="false"
aria-controls="breadcrumb-1"
>
Voir le fil d’Ariane
</Button>
<div className={fr.cx('fr-collapse')} id="breadcrumb-1">
<ol className={fr.cx('fr-breadcrumb__list')}>
<li>
<Link className={fr.cx('fr-breadcrumb__link')} to="/">
Accueil
</Link>
</li>
<li>
<a className={fr.cx('fr-breadcrumb__link')} aria-current="page">
{title}
</a>
</li>
</ol>
</div>
</nav>
<Breadcrumb
currentPageLabel={title}
homeLinkProps={{
to: '/'
}}
segments={[

]}
/>
<h2 id={id} className={classnames(className)}>
{title}
</h2>
Expand Down
Loading

0 comments on commit ec63145

Please sign in to comment.