Exemples de ce que Pathou ajoute à une trace — une alternative, un balcon, un passage difficile — posés autour de la question de l’accueil, avec les composants mêmes de la vue trace.
stableÀ valider
// Titre : Balcon (BalconyExample)
import { BalconyExample } from '@pathou/components/HomeFeatures';
export default function Exemple() {
return (
<div style={{ width: 340 }}>
<BalconyExample />
</div>
);
}
Installation
Copie le fichier dans ton projet, ainsi que les tokens qu’il utilise.
import { WAY_COLOR, gradeColor } from '../lib/colors';
import { WAY_CLASS_LABEL } from '../lib/osm/classify';
import BalconyFigure, { FIG_H } from './BalconyFigure';
import { WalkIcon } from './DetourBlock';
import { colStyle } from './techStyle';
import DetourGlyph from './DetourGlyph';
/** Exemples de ce que Pathou ajoute à la trace, posés autour de la question de l'accueil (composants de la vue trace). */
export function DetourExample() {
return (
<aside className="hp-feat hp-feat-detour" aria-label="Exemple d’alternative à un passage trop dur">
<div className="detour-top">
<DetourGlyph kind="praticable" />
<div className="detour-head">
Alternative praticable
<small>contourne la descente technique</small>
</div>
</div>
<div className="detour-stats">
<div>
<b>+540 m</b>
<span>distance</span>
</div>
<div>
<b>+25 m</b>
<span>D+</span>
</div>
<span className="detour-chip">
<i style={{ background: WAY_COLOR.piste_roulante }} />
{WAY_CLASS_LABEL.piste_roulante}
</span>
</div>
</aside>
);
}
/** Pente illustrative (pas un relevé de la trace d'exemple) : un balcon franc, sous le seuil « exposé ». */
const BALCONY_SLOPE = 84;
export function BalconyExample() {
const deg = Math.round((Math.atan(BALCONY_SLOPE / 100) * 180) / Math.PI);
return (
<aside className="hp-feat hp-feat-balcony" aria-label="Exemple de sentier en balcon">
<span className="alert-head">
<span className="alert-name">Sentier en balcon</span>
<span className="alert-len">180 m</span>
</span>
<span className="alert-balcony">
<BalconyFigure slope={BALCONY_SLOPE} side="droit" />
<span className="alert-stats">
<span>
<b>{BALCONY_SLOPE} % ({deg}°)</b>
<small>sous le sentier, vide à droite</small>
</span>
</span>
</span>
</aside>
);
}
/**
* Profil illustratif d'un point d'attention (pas un relevé de la trace d'exemple) : abords en gris, passage coloré par la pente,
* comme dans la vue trace. Abscisses en part de la largeur (0–100), altitudes en mètres.
*/
const PASSAGE_PROFILE: [number, number][] = [
[0, 0], [8, 2], [16, 5], [24, 7], [30, 9], [36, 15], [42, 23], [48, 31], [54, 39], [60, 46], [66, 51], [70, 53], [78, 55], [86, 56], [100, 57],
];
const PASSAGE_X0 = 30;
const PASSAGE_X1 = 70;
/** Pente de chaque segment du passage (%), pour le dégradé : 190 m pour ~44 m de dénivelé. */
const PASSAGE_GRADES = [12, 18, 22, 21, 19, 14, 9];
export function PassageExample() {
const top = Math.max(...PASSAGE_PROFILE.map(([, z]) => z));
const y = (z: number) => 1.5 + (FIG_H - 3) * (1 - z / top);
const line = (pts: [number, number][]) => pts.map(([x, z], k) => `${k ? 'L' : 'M'}${x} ${y(z)}`).join('');
const inside = PASSAGE_PROFILE.filter(([x]) => x >= PASSAGE_X0 && x <= PASSAGE_X1);
const passage = line(inside);
return (
<aside className="hp-feat hp-feat-passage" aria-label="Exemple de point d’attention : poussage probable">
<span className="alert-head">
<span className="alert-km">km 18,4</span>
<span className="alert-name">Poussage probable</span>
<span className="alert-len">190 m</span>
</span>
<span className="alert-figure">
<svg className="alert-shape" viewBox={`0 0 100 ${FIG_H}`} preserveAspectRatio="none" style={{ height: FIG_H }} aria-hidden="true">
<defs>
<linearGradient id="hp-passage-grad" x1="0" x2="1" y1="0" y2="0">
{PASSAGE_GRADES.map((g, k) => (
<stop key={k} offset={k / (PASSAGE_GRADES.length - 1)} stopColor={gradeColor(g)} />
))}
</linearGradient>
</defs>
<path className="alert-context" d={`${line(PASSAGE_PROFILE)}L100 ${FIG_H}L0 ${FIG_H}Z`} />
<path className="alert-context-line" d={line(PASSAGE_PROFILE)} vectorEffect="non-scaling-stroke" />
<path d={`${passage}L${PASSAGE_X1} ${FIG_H}L${PASSAGE_X0} ${FIG_H}Z`} fill="url(#hp-passage-grad)" fillOpacity="0.3" />
<path d={passage} fill="none" stroke="url(#hp-passage-grad)" strokeWidth="2.5" strokeLinejoin="round" vectorEffect="non-scaling-stroke" />
<line className="alert-bound" x1={PASSAGE_X0} x2={PASSAGE_X0} y1="0" y2={FIG_H} vectorEffect="non-scaling-stroke" />
<line className="alert-bound" x1={PASSAGE_X1} x2={PASSAGE_X1} y1="0" y2={FIG_H} vectorEffect="non-scaling-stroke" />
</svg>
<span className="climb-push" aria-hidden="true">
<i style={{ left: '38%', width: '24%' }} />
</span>
</span>
<span className="alert-stats">
<span>
<b>
<i style={{ background: gradeColor(22) }} />
22 %
</b>
<small>pente max</small>
</span>
<span>
<b>26 %</b>
<small>rampe sur 50 m</small>
</span>
<span>
<b>
<WalkIcon />
~120 m
</b>
<small>à pied</small>
</span>
</span>
<span className="alert-chips">
<span className="pill-tech tech-pill" style={colStyle(1)}>
S1
</span>
<span className="detour-chip">
<i style={{ background: WAY_COLOR.sentier }} />
{WAY_CLASS_LABEL.sentier}
</span>
</span>
</aside>
);
}
Tokens : --panel --text --muted --detour --detour-ink --line --accent --chip --exigeant --ease-out --tech-black --tech-black-ink
Utilisation
import { BalconyExample, DetourExample, PassageExample } from './components/HomeFeatures';
<DetourExample />Exemples
Alternative (DetourExample)
// Titre : Alternative (DetourExample)
import { DetourExample } from '@pathou/components/HomeFeatures';
export default function Exemple() {
return (
<div style={{ width: 340 }}>
<DetourExample />
</div>
);
}
Passage difficile (PassageExample)
// Titre : Passage difficile (PassageExample)
import { PassageExample } from '@pathou/components/HomeFeatures';
export default function Exemple() {
return (
<div style={{ width: 340 }}>
<PassageExample />
</div>
);
}
Guidelines
- MUSTConstruire ces exemples avec les composants de la vue trace (DetourBlock, BalconyFigure…), pour que l’accueil montre ce que l’on verra vraiment.
- SHOULDSignaler dans le code une valeur illustrative (pente du balcon) qui n’est pas un relevé.
Référence de l’API
DetourExample
Aucune prop.
BalconyExample
Aucune prop.
PassageExample
Aucune prop.