2025-07-03
- étoffe le fichier `JOURNAL` avec les nouveaux changements majeurs. - propose une tâche _Justfile_ pour un rechargement à chaud primitif lors de changements CSS. - ne précompresse pas et ne propose plus de versions « legacy » des scripts JS en methodes développement. - appose correctement `aria-current` sur le lien de la page courante dans les deux menus de navigation. - remplace une image statique « Scroll down » avec une animation SVG reposant sur du texte et des chemins. - renomme moultes choses.
This commit is contained in:
parent
b85a03a141
commit
d30b83d093
49 changed files with 830 additions and 359 deletions
|
|
@ -1 +1,4 @@
|
||||||
{ "dictionaries": ["fr-fr", "en-gb"], "words": ["oxlint", "Vali", "mobily", "valibot", "GLITCHTIP"] }
|
{
|
||||||
|
"dictionaries": ["fr-fr", "en-gb"],
|
||||||
|
"words": ["GLITCHTIP", "Vali", "fdir", "mobily", "oxlint", "valibot", "zstandard", "Eles", "logtape"]
|
||||||
|
}
|
||||||
|
|
|
||||||
36
docs/JOURNAL.md
Normal file
36
docs/JOURNAL.md
Normal file
|
|
@ -0,0 +1,36 @@
|
||||||
|
# Journal de développement
|
||||||
|
|
||||||
|
## 2025-06-13
|
||||||
|
|
||||||
|
### Informations produit sous forme de grille
|
||||||
|
|
||||||
|
- L'idée est de réimplémenter les informations essentiels du produit (nom, prix), le sélecteur de variation, les textes de détail, de conditions et d'entretien, et le bouton d'ajout au Panier.
|
||||||
|
- Plutôt qu'un encart flottant, contenant tout, il n'y aurait qu'une barre pleine longueur comprenant nom, prix et sélecteur de variation (`.essentiel-produit`).
|
||||||
|
- Il flotterait en bas de l'écran jusqu'à ce se poser à la fin des photos.
|
||||||
|
- Une nouvelle section, statique elle et faisant suite à la fois aux photos et à la barre, s'afficherait en pleine longueur sous forme d'accordéon, avec les anciens onglets comme sections.
|
||||||
|
- Par défaut, la section « Détails » serait développée.
|
||||||
|
- `<details>` et `<summary>` sont aujourd'hui pris en charge par les navigateurs (niveau _Baseline_), mais l'attribut `name` permettant l'ouverture exclusive d'une section par accordéon (p. ex. le développement d'une ferme toutes les autres) n'a que récemment été implémentée (2024 pour _Firefox_).
|
||||||
|
- Une implémentation en _JavaScript_ est donc pour l'instant nécessaire.
|
||||||
|
|
||||||
|
### Remaniement du défilement des photos de la page Produit
|
||||||
|
|
||||||
|
- Les flèches de défilement sont supprimées.
|
||||||
|
- À la place, les photos ne s'affichent plus en pleine longueur.
|
||||||
|
- Elles le sont à ~93%, pour que l'on perçoive sur les bords la photo précédente/suivante et signale à l'Utilisateur qu'il est possible de défiler.
|
||||||
|
|
||||||
|
## 2025-06-30
|
||||||
|
|
||||||
|
- Test de _LogTape_ comme librairie de journalisation.
|
||||||
|
|
||||||
|
## 2025-07-03
|
||||||
|
|
||||||
|
- Création d'une animation SVG avec des `<text>` défilants sur un `<path>`.
|
||||||
|
- Le redimensionnement dynamique du conteneur de l'animation se fait via JavaScript.
|
||||||
|
- Le script récupère la longueur d'une image au redimensionnement de la vue.
|
||||||
|
- Il injecte un attribut CSS `inline-size` dans le HTML de la page correspondant à cette nouvelle longueur.
|
||||||
|
- Il n'est pas encore possible de mettre en pause l'animation au survol de la souris, qui est une bonne pratique pour ce style d'éléments visuels.
|
||||||
|
- Le `<svg>` doit être d'une longueur supérieure au conteneur (ici `120%`) pour que le texte disparaisse de façon progressive, qu'il ne soit pas « coupé » brutalement aux extrémités.
|
||||||
|
- Début de l'implémentation d'une classe `no-js` pour un affichage adapté en cas d'absence de JavaScript.
|
||||||
|
- Développement d'un script `fish` qui lance un onglet Cromite en mode sans-tête avec profile Invité sur le site Haiku Atelier.
|
||||||
|
- Il est possible, en utilisant le débogueur à distance Chromium, de rafraîchir un onglet via le terminal en passant par `fx` et `websocat` pour l'interface _WebSocket_.
|
||||||
|
- Cela offre une forme primitive de « hot reload » (rechargement à chaud) pour éviter d'avoir manuellement taper F5 à chaque changement.
|
||||||
|
|
@ -12,16 +12,23 @@
|
||||||
- Champs
|
- Champs
|
||||||
- Utiliser un polyfill pour BroadcastChannel
|
- Utiliser un polyfill pour BroadcastChannel
|
||||||
- PAGE SHOP
|
- PAGE SHOP
|
||||||
- [ ] Faire apparaître le menu des catégories de Produits quand on scroll vers le haut
|
|
||||||
- PAGE PANIER
|
- PAGE PANIER
|
||||||
- Erreur lorsque l'on ajoute deux variations d'un même produit et que l'on essaie d'en supprimer une.
|
- Erreur lorsque l'on ajoute deux variations d'un même produit et que l'on essaie d'en supprimer une.
|
||||||
- Il semblerait que supprimer une variation supprime toutes les entrées du même produit.
|
- Il semblerait que supprimer une variation supprime toutes les entrées du même produit.
|
||||||
- MÉTHODES DE LIVRAISON
|
- MÉTHODES DE LIVRAISON
|
||||||
- [ ] Proposer la livraison à domicile en Belgique et en France pour le coût unique de 8 euros, quel que soit le montant de la commande
|
- [ ] Proposer la livraison à domicile en Belgique et en France pour le coût unique de 8 euros, quel que soit le montant de la commande
|
||||||
|
- [ ] Proposer la livraison aux États-Unis.
|
||||||
- PAGE PRODUIT
|
- PAGE PRODUIT
|
||||||
- PIED DE PAGE
|
- PIED DE PAGE
|
||||||
- TOUTES LES PAGES
|
- TOUTES LES PAGES
|
||||||
- Trouver la source des bordures superflues.
|
- Trouver la source des bordures superflues.
|
||||||
|
- Sur Chromium : box-shadow sur <article> ?
|
||||||
|
|
||||||
|
- MODE VACANCES
|
||||||
|
- Pour l'été, superposer à la page SHOP un calque gris sur lequel défile une animation d'un texte indiquant que la boutique est en vacances.
|
||||||
|
- La page doit rester défilable.
|
||||||
|
- MODE NO JS
|
||||||
|
- Laisser la page normalement défilable avec les images les une après les autres quand _JavaScript_ n'est pas présent.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,9 +0,0 @@
|
||||||
# Informations produit sous forme de grille
|
|
||||||
|
|
||||||
- L'idée est de réimplémenter les informations essentiels du produit (nom, prix), le sélecteur de variation, les textes de détail, de conditions et d'entretien, et le bouton d'ajout au Panier.
|
|
||||||
- Plutôt qu'un encart flottant, contenant tout, il n'y aurait qu'une barre pleine longueur comprenant nom, prix et sélecteur de variation (`.essentiel-produit`).
|
|
||||||
- Il flotterait en bas de l'écran jusqu'à ce se poser à la fin des photos.
|
|
||||||
- Une nouvelle section, statique elle et faisant suite à la fois aux photos et à la barre, s'afficherait en pleine longueur sous forme d'accordéon, avec les anciens onglets comme sections.
|
|
||||||
- Par défaut, la section « Détails » serait développée.
|
|
||||||
- `<details>` et `<summary>` sont aujourd'hui pris en charge par les navigateurs (niveau _Baseline_), mais l'attribut `name` permettant l'ouverture exclusive d'une section par accordéon (p. ex. le développement d'une ferme toutes les autres) n'a que récemment été implémentée (2024 pour _Firefox_).
|
|
||||||
- Une implémentation en _JavaScript_ est donc pour l'instant nécessaire.
|
|
||||||
|
|
@ -1,5 +0,0 @@
|
||||||
# Remaniement du défilement des photos de la page Produit
|
|
||||||
|
|
||||||
- Les flèches de défilement sont supprimées.
|
|
||||||
- À la place, les photos ne s'affichent plus en pleine longueur.
|
|
||||||
- Elles le sont à ~93%, pour que l'on perçoive sur les bords la photo précédente/suivante et signale à l'utilisteur qu'il est possible de défiler.
|
|
||||||
|
|
@ -46,12 +46,8 @@ export default tseslint.config(
|
||||||
"@typescript-eslint/no-misused-promises": "off",
|
"@typescript-eslint/no-misused-promises": "off",
|
||||||
/* Cette règle empêche l'usage de génériques précisant les types de retour de fonctions. */
|
/* Cette règle empêche l'usage de génériques précisant les types de retour de fonctions. */
|
||||||
"@typescript-eslint/no-unnecessary-type-parameters": "off",
|
"@typescript-eslint/no-unnecessary-type-parameters": "off",
|
||||||
"@typescript-eslint/no-unused-expressions": [
|
// Pour utiliser LogTape.
|
||||||
"error",
|
"@typescript-eslint/no-unused-expressions": "off",
|
||||||
{
|
|
||||||
allowTernary: true,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
/* Cette règle est doublon avec les règles noUnused* de TypeScript. */
|
/* Cette règle est doublon avec les règles noUnused* de TypeScript. */
|
||||||
"@typescript-eslint/no-unused-vars": "off",
|
"@typescript-eslint/no-unused-vars": "off",
|
||||||
/* Cette règle empêche de lever des erreurs génériques (p.ex. `E extends Error`). */
|
/* Cette règle empêche de lever des erreurs génériques (p.ex. `E extends Error`). */
|
||||||
|
|
|
||||||
31
justfile
31
justfile
|
|
@ -9,18 +9,10 @@ stylelintCacheFile := "stylelintcache"
|
||||||
list:
|
list:
|
||||||
@just --list --list-heading 'Recettes disponibles :'\n'' --unsorted
|
@just --list --list-heading 'Recettes disponibles :'\n'' --unsorted
|
||||||
|
|
||||||
# Démarre le conteneur ddev
|
|
||||||
start:
|
|
||||||
ddev start
|
|
||||||
|
|
||||||
# Arrête le conteneur ddev
|
|
||||||
stop:
|
|
||||||
ddev stop
|
|
||||||
|
|
||||||
# Met à jour les dépendances composer et npm
|
# Met à jour les dépendances composer et npm
|
||||||
update:
|
update:
|
||||||
composer update
|
composer update
|
||||||
bun update
|
bun update
|
||||||
|
|
||||||
# Formatte avec Prettier et dprint
|
# Formatte avec Prettier et dprint
|
||||||
format:
|
format:
|
||||||
|
|
@ -76,10 +68,8 @@ build-css:
|
||||||
|
|
||||||
# Compile le CSS à chaque changement de fichier
|
# Compile le CSS à chaque changement de fichier
|
||||||
watch-css:
|
watch-css:
|
||||||
bunx sass \
|
@just dev
|
||||||
--update \
|
@watchexec -w "web/app/themes/haiku-atelier-2024/src/sass" -- just build-css reload-tab
|
||||||
--watch \
|
|
||||||
"web/app/themes/haiku-atelier-2024/src/sass":"web/app/themes/haiku-atelier-2024/assets/css"
|
|
||||||
|
|
||||||
# Compile TypeScript en JavaScript
|
# Compile TypeScript en JavaScript
|
||||||
build-js:
|
build-js:
|
||||||
|
|
@ -112,8 +102,17 @@ lint-code-mort:
|
||||||
squash-and-push:
|
squash-and-push:
|
||||||
-jj squash --ignore-immutable && jj bookmark set principale -r @- --allow-backwards && jj git push
|
-jj squash --ignore-immutable && jj bookmark set principale -r @- --allow-backwards && jj git push
|
||||||
|
|
||||||
# Compile, analyse statiquement (avec corrections automatiques) et formate le CSS
|
# Analyse statiquement, compile et formate le CSS
|
||||||
build-lint-format-css:
|
lint-build-format-css:
|
||||||
-just build-css
|
|
||||||
-just lint-css
|
-just lint-css
|
||||||
|
-just build-css
|
||||||
-just format
|
-just format
|
||||||
|
|
||||||
|
dev:
|
||||||
|
@/opt/cromite/chrome --remote-debugging-address=127.0.0.1 --remote-debugging-port=9222 --profile-directory=Guest "https://haikuatelier.gcch.local" &
|
||||||
|
|
||||||
|
reload-tab:
|
||||||
|
#!/usr/bin/fish
|
||||||
|
set -f WSURL (curl -s http://127.1:9222/json | fx '.[0].webSocketDebuggerUrl')
|
||||||
|
set -f REQUEST '{ "id": 2, "method": "Page.reload", "params": { "ignoreCache": true, "scriptToEvaluateOnLoad": "" } }'
|
||||||
|
echo $REQUEST | websocat $WSURL
|
||||||
|
|
|
||||||
|
|
@ -17,13 +17,40 @@ const SRC_TYPESCRIPT_PATHS = new fdir()
|
||||||
.crawl(`web/app/themes/${SLUG_THEME}/src/scripts`)
|
.crawl(`web/app/themes/${SLUG_THEME}/src/scripts`)
|
||||||
.withPromise();
|
.withPromise();
|
||||||
|
|
||||||
/* Voir le fichier vite.env.d.ts */
|
// Voir le fichier vite.env.d.ts.
|
||||||
const SCHEMA_ENVIRONNEMENT = v.object({
|
const SCHEMA_ENVIRONNEMENT = v.object({
|
||||||
VITE_GLITCHTIP_NSD: v.pipe(v.string(), v.url(), v.readonly()),
|
VITE_GLITCHTIP_NSD: v.pipe(v.string(), v.url(), v.readonly()),
|
||||||
VITE_MODE: v.pipe(v.string(), v.readonly()),
|
VITE_MODE: v.pipe(v.string(), v.readonly()),
|
||||||
VITE_URL: v.pipe(v.string(), v.nonEmpty(), v.url(), v.readonly()),
|
VITE_URL: v.pipe(v.string(), v.nonEmpty(), v.url(), v.readonly()),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const basePlugins = [
|
||||||
|
// Permet de valider les variables d'environnements définies à partir d'un schéma Valibot
|
||||||
|
valibot(SCHEMA_ENVIRONNEMENT),
|
||||||
|
manifestSRI({ algorithms: ["sha512"] }),
|
||||||
|
nodePolyfills({
|
||||||
|
include: [],
|
||||||
|
protocolImports: true,
|
||||||
|
}),
|
||||||
|
];
|
||||||
|
// Les extensions activées en production.
|
||||||
|
const prodPlugins = [
|
||||||
|
legacy({
|
||||||
|
modernPolyfills: true,
|
||||||
|
modernTargets:
|
||||||
|
"chrome >0 and last 3 years, edge >0 and last 3 years, safari >0 and last 3 years, firefox >0 and last 3 years, and_chr >0 and last 3 years, and_ff >0 and last 3 years, ios >0 and last 3 years",
|
||||||
|
renderLegacyChunks: true,
|
||||||
|
}),
|
||||||
|
compression({
|
||||||
|
algorithms: [
|
||||||
|
"brotliCompress",
|
||||||
|
"gzip",
|
||||||
|
"zstandard",
|
||||||
|
],
|
||||||
|
threshold: 1000,
|
||||||
|
}),
|
||||||
|
];
|
||||||
|
|
||||||
export default defineConfig(async ({ mode }) => {
|
export default defineConfig(async ({ mode }) => {
|
||||||
const env = loadEnv(mode, process.cwd(), "VITE");
|
const env = loadEnv(mode, process.cwd(), "VITE");
|
||||||
|
|
||||||
|
|
@ -32,9 +59,9 @@ export default defineConfig(async ({ mode }) => {
|
||||||
build: {
|
build: {
|
||||||
assetsDir: ".",
|
assetsDir: ".",
|
||||||
emptyOutDir: true,
|
emptyOutDir: true,
|
||||||
/* Génère un fichier manifeste dans outDir */
|
// Génère un fichier manifeste dans outDir.
|
||||||
manifest: true,
|
manifest: true,
|
||||||
minify: env.VITE_MODE === "production",
|
minify: env["VITE_MODE"] === "production",
|
||||||
outDir: resolve("./web/app/themes/haiku-atelier-2024/assets/js"),
|
outDir: resolve("./web/app/themes/haiku-atelier-2024/assets/js"),
|
||||||
reportCompressedSize: true,
|
reportCompressedSize: true,
|
||||||
rollupOptions: {
|
rollupOptions: {
|
||||||
|
|
@ -42,39 +69,17 @@ export default defineConfig(async ({ mode }) => {
|
||||||
output: {
|
output: {
|
||||||
assetFileNames: "[name].[hash].[extname]",
|
assetFileNames: "[name].[hash].[extname]",
|
||||||
chunkFileNames: "[name].[hash].js",
|
chunkFileNames: "[name].[hash].js",
|
||||||
compact: env.VITE_MODE === "production",
|
compact: env["VITE_MODE"] === "production",
|
||||||
entryFileNames: "[name].js",
|
entryFileNames: "[name].js",
|
||||||
validate: true,
|
validate: true,
|
||||||
},
|
},
|
||||||
treeshake: true,
|
treeshake: true,
|
||||||
},
|
},
|
||||||
sourcemap: env.VITE_MODE === "production",
|
sourcemap: env["VITE_MODE"] === "production",
|
||||||
target: "es2020",
|
target: "es2020",
|
||||||
write: true,
|
write: true,
|
||||||
},
|
},
|
||||||
mode: env.VITE_MODE ?? "production",
|
mode: env["VITE_MODE"] ?? "production",
|
||||||
plugins: [
|
plugins: env["VITE_MODE"] === "production" ? [...basePlugins, ...prodPlugins] : [...basePlugins],
|
||||||
// Permet de valider les variables d'environnements définies à partir d'un schéma Valibot
|
|
||||||
valibot(SCHEMA_ENVIRONNEMENT),
|
|
||||||
manifestSRI({ algorithms: ["sha512"] }),
|
|
||||||
nodePolyfills({
|
|
||||||
include: [],
|
|
||||||
protocolImports: true,
|
|
||||||
}),
|
|
||||||
legacy({
|
|
||||||
modernPolyfills: true,
|
|
||||||
modernTargets:
|
|
||||||
"chrome >0 and last 3 years, edge >0 and last 3 years, safari >0 and last 3 years, firefox >0 and last 3 years, and_chr >0 and last 3 years, and_ff >0 and last 3 years, ios >0 and last 3 years",
|
|
||||||
renderLegacyChunks: true,
|
|
||||||
}),
|
|
||||||
compression({
|
|
||||||
algorithms: [
|
|
||||||
"brotliCompress",
|
|
||||||
"gzip",
|
|
||||||
"zstandard",
|
|
||||||
],
|
|
||||||
threshold: 1000,
|
|
||||||
}),
|
|
||||||
],
|
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -52,6 +52,7 @@
|
||||||
--hauteur-ligne-compacte: 1.1;
|
--hauteur-ligne-compacte: 1.1;
|
||||||
--hauteur-ligne-rapprochee: 1;
|
--hauteur-ligne-rapprochee: 1;
|
||||||
/* Espacements entre les lettres */
|
/* Espacements entre les lettres */
|
||||||
|
--espacement-inter-lettres-rapproche-m: -1px;
|
||||||
--espacement-inter-lettres-rapproche-s: -0.5px;
|
--espacement-inter-lettres-rapproche-s: -0.5px;
|
||||||
--espacement-inter-lettres-etendu-s: 0.5px;
|
--espacement-inter-lettres-etendu-s: 0.5px;
|
||||||
--espacement-inter-lettres-etendu-m: 1px;
|
--espacement-inter-lettres-etendu-m: 1px;
|
||||||
|
|
@ -66,7 +67,7 @@
|
||||||
);
|
);
|
||||||
--contenu-page-hauteur-minimale-avec-categories: calc(
|
--contenu-page-hauteur-minimale-avec-categories: calc(
|
||||||
100svh - var(--en-tete-hauteur) - var(--pied-de-page-hauteur)
|
100svh - var(--en-tete-hauteur) - var(--pied-de-page-hauteur)
|
||||||
- var(--menu-categories-produits-hauteur)
|
- var(--menu-categories-produits-hauteur)
|
||||||
);
|
);
|
||||||
/* Espacements */
|
/* Espacements */
|
||||||
--espace-xs: 0.25rem;
|
--espace-xs: 0.25rem;
|
||||||
|
|
@ -109,6 +110,7 @@ html {
|
||||||
* 2. Utilise la couleur primaire du site.
|
* 2. Utilise la couleur primaire du site.
|
||||||
*/
|
*/
|
||||||
body {
|
body {
|
||||||
|
overscroll-behavior: none;
|
||||||
accent-color: var(--couleur-jaune); /* 2 */
|
accent-color: var(--couleur-jaune); /* 2 */
|
||||||
background: var(--couleur-gris); /* 1 */
|
background: var(--couleur-gris); /* 1 */
|
||||||
}
|
}
|
||||||
|
|
@ -688,14 +690,17 @@ body:has(#menu-mobile:not([aria-hidden=true])) {
|
||||||
/* Dispositions */
|
/* Dispositions */
|
||||||
--liste-puce-cercle-puce-position-horizontale: 3.5ch; /* 3 */
|
--liste-puce-cercle-puce-position-horizontale: 3.5ch; /* 3 */
|
||||||
}
|
}
|
||||||
|
#en-tete .menu-navigation__entree:has(a[aria-current=page]) {
|
||||||
|
background: url("/app/themes/haiku-atelier-2024/assets/img/icons/cloud-penche.svg") center/auto 90% no-repeat;
|
||||||
|
}
|
||||||
|
#en-tete .menu-navigation__entree--courante {
|
||||||
|
background: url("/app/themes/haiku-atelier-2024/assets/img/icons/cloud-penche.svg") center/auto 90% no-repeat;
|
||||||
|
}
|
||||||
#en-tete .menu-navigation__entree a {
|
#en-tete .menu-navigation__entree a {
|
||||||
display: inline-block; /* 1 */
|
display: inline-block; /* 1 */
|
||||||
padding: var(--nav-entree-marges-internes-bloc) var(--nav-entree-marges-internes-ligne); /* 2 */
|
padding: var(--nav-entree-marges-internes-bloc) var(--nav-entree-marges-internes-ligne); /* 2 */
|
||||||
text-align: center; /* 4 */
|
text-align: center; /* 4 */
|
||||||
}
|
}
|
||||||
#en-tete .menu-navigation__entree--courante {
|
|
||||||
background: url("/app/themes/haiku-atelier-2024/assets/img/icons/cloud-penche.svg") center/auto 90% no-repeat;
|
|
||||||
}
|
|
||||||
@media (hover: hover) {
|
@media (hover: hover) {
|
||||||
#en-tete .menu-navigation__entree:hover {
|
#en-tete .menu-navigation__entree:hover {
|
||||||
background: url("/app/themes/haiku-atelier-2024/assets/img/icons/cloud-penche.svg") center/auto 90% no-repeat;
|
background: url("/app/themes/haiku-atelier-2024/assets/img/icons/cloud-penche.svg") center/auto 90% no-repeat;
|
||||||
|
|
@ -1230,9 +1235,6 @@ body:has(#menu-mobile:not([aria-hidden=true])) {
|
||||||
.details-produit__textes .section-textuelle:not(:last-of-type) {
|
.details-produit__textes .section-textuelle:not(:last-of-type) {
|
||||||
border-block-end: 1px solid var(--couleur-noir);
|
border-block-end: 1px solid var(--couleur-noir);
|
||||||
}
|
}
|
||||||
.details-produit__textes .section-textuelle:has(button[aria-expanded=true]) button {
|
|
||||||
/* padding: initial; */
|
|
||||||
}
|
|
||||||
.details-produit__textes .section-textuelle:has(button[aria-expanded=false]) .section-textuelle__contenu {
|
.details-produit__textes .section-textuelle:has(button[aria-expanded=false]) .section-textuelle__contenu {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
@ -1263,7 +1265,7 @@ body:has(#menu-mobile:not([aria-hidden=true])) {
|
||||||
.details-produit__actions {
|
.details-produit__actions {
|
||||||
--section-marges-internes: var(--espace-l);
|
--section-marges-internes: var(--espace-l);
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
border: 1px solid var(--couleur-noir);
|
border-block: 1px solid var(--couleur-noir);
|
||||||
background: var(--couleur-jaune);
|
background: var(--couleur-jaune);
|
||||||
transition: 0.2s background;
|
transition: 0.2s background;
|
||||||
}
|
}
|
||||||
|
|
@ -1286,6 +1288,7 @@ body:has(#menu-mobile:not([aria-hidden=true])) {
|
||||||
.produits-similaires {
|
.produits-similaires {
|
||||||
--carte-produit-longueur-minimale: 448px;
|
--carte-produit-longueur-minimale: 448px;
|
||||||
--carte-produit-longueur-maximale: 1000px;
|
--carte-produit-longueur-maximale: 1000px;
|
||||||
|
--en-tete-flottante-hauteur: calc(1rem + var(--espace-l) * 2 + 1px);
|
||||||
position: relative;
|
position: relative;
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-areas: "en-tete en-tete en-tete" "produits produits produits";
|
grid-template-areas: "en-tete en-tete en-tete" "produits produits produits";
|
||||||
|
|
@ -1297,10 +1300,10 @@ body:has(#menu-mobile:not([aria-hidden=true])) {
|
||||||
.produits-similaires header {
|
.produits-similaires header {
|
||||||
position: sticky;
|
position: sticky;
|
||||||
z-index: 10;
|
z-index: 10;
|
||||||
top: calc(1lh + var(--espace-l) + var(--espace-m));
|
top: var(--en-tete-flottante-hauteur);
|
||||||
grid-area: en-tete;
|
grid-area: en-tete;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
padding: var(--espace-l) 0 var(--espace-m);
|
padding: var(--espace-l) 0;
|
||||||
color: var(--couleur-blanc);
|
color: var(--couleur-blanc);
|
||||||
text-align: center;
|
text-align: center;
|
||||||
background: var(--couleur-noir);
|
background: var(--couleur-noir);
|
||||||
|
|
|
||||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
|
@ -1,45 +1,115 @@
|
||||||
|
@charset "UTF-8";
|
||||||
#page-accueil {
|
#page-accueil {
|
||||||
--hauteur-conteneur: var(--contenu-page-hauteur-minimale-sans-categories);
|
--hauteur-conteneur: var(--contenu-page-hauteur-minimale-sans-categories);
|
||||||
--page-marges-bloc-debut: var(--en-tete-hauteur);
|
--page-marges-bloc-debut: var(--en-tete-hauteur);
|
||||||
|
--conteneur-marges-internes-ligne: var(--espace-xl);
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-flow: column nowrap;
|
flex-flow: column nowrap;
|
||||||
min-height: var(--hauteur-conteneur);
|
min-block-size: var(--hauteur-conteneur);
|
||||||
max-height: var(--hauteur-conteneur);
|
max-block-size: var(--hauteur-conteneur);
|
||||||
margin-top: var(--page-marges-bloc-debut);
|
margin-top: var(--page-marges-bloc-debut);
|
||||||
}
|
}
|
||||||
#page-accueil .storytelling {
|
#page-accueil .storytelling {
|
||||||
overflow-y: scroll;
|
overflow-y: scroll;
|
||||||
place-items: center;
|
overscroll-behavior: none;
|
||||||
min-height: inherit;
|
min-block-size: inherit;
|
||||||
max-height: inherit;
|
max-block-size: inherit;
|
||||||
}
|
}
|
||||||
#page-accueil .storytelling__conteneur {
|
#page-accueil .storytelling__conteneur {
|
||||||
|
overscroll-behavior: inherit;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-flow: column nowrap;
|
flex-flow: column nowrap;
|
||||||
min-height: calc(var(--hauteur-conteneur) * 13);
|
place-items: center;
|
||||||
padding: 0 var(--espace-xl);
|
min-block-size: calc(var(--hauteur-conteneur) * 13);
|
||||||
|
padding: 0 var(--conteneur-marges-internes-ligne);
|
||||||
|
}
|
||||||
|
#page-accueil .storytelling__animation {
|
||||||
|
--hauteur-animation: 90px;
|
||||||
|
--taille-police: calc(var(--espace-xl) * 2.5);
|
||||||
|
pointer-events: none;
|
||||||
|
position: absolute;
|
||||||
|
z-index: 3;
|
||||||
|
top: 0;
|
||||||
|
right: 0;
|
||||||
|
left: 0;
|
||||||
|
overflow: hidden;
|
||||||
|
display: grid;
|
||||||
|
place-content: center;
|
||||||
|
place-items: center;
|
||||||
|
block-size: 100%;
|
||||||
|
margin: auto;
|
||||||
|
visibility: visible;
|
||||||
|
opacity: 1;
|
||||||
|
transition: 1s opacity ease-in-out, 1s visibility ease-in-out;
|
||||||
|
mask-image: linear-gradient(var(--mask-direction, to right), hsla(0, 0%, 0%, 0), hsl(0, 0%, 0%) 20%, hsl(0, 0%, 0%) 80%, hsla(0, 0%, 0%, 0));
|
||||||
|
}
|
||||||
|
#page-accueil .storytelling__animation[hidden] {
|
||||||
|
display: grid !important;
|
||||||
|
/* visibility: hidden;
|
||||||
|
opacity: 0; */
|
||||||
|
transition: 1s opacity ease-in-out, 1s visibility ease-in-out;
|
||||||
|
}
|
||||||
|
#page-accueil .storytelling__animation.no-js {
|
||||||
|
/* visibility: hidden;
|
||||||
|
opacity: 0; */
|
||||||
|
transition: 1s opacity ease-in-out, 1s visibility ease-in-out;
|
||||||
|
}
|
||||||
|
#page-accueil .storytelling__animation .animation-conteneur {
|
||||||
|
overflow: visible;
|
||||||
|
inline-size: 120%;
|
||||||
|
block-size: var(--hauteur-animation);
|
||||||
|
}
|
||||||
|
#page-accueil .storytelling__animation .animation-texte {
|
||||||
|
overflow: visible;
|
||||||
|
font-size: var(--taille-police);
|
||||||
|
font-weight: 600;
|
||||||
|
text-shadow: 4px 4px 0 var(--couleur-blanc);
|
||||||
|
text-transform: uppercase;
|
||||||
|
letter-spacing: var(--espacement-inter-lettres-rapproche-s);
|
||||||
}
|
}
|
||||||
#page-accueil .storytelling__image {
|
#page-accueil .storytelling__image {
|
||||||
position: sticky;
|
position: sticky;
|
||||||
top: 0;
|
top: 0;
|
||||||
align-content: center;
|
align-content: center;
|
||||||
width: 100%;
|
inline-size: max-content;
|
||||||
min-height: var(--hauteur-conteneur);
|
max-inline-size: 100%;
|
||||||
max-height: var(--hauteur-conteneur);
|
min-block-size: var(--hauteur-conteneur);
|
||||||
|
max-block-size: var(--hauteur-conteneur);
|
||||||
}
|
}
|
||||||
#page-accueil .storytelling__image[data-cache] {
|
#page-accueil .storytelling__image[data-caché] {
|
||||||
display: none;
|
display: none !important;
|
||||||
}
|
}
|
||||||
#page-accueil .storytelling__image picture {
|
#page-accueil .storytelling__image picture {
|
||||||
max-height: inherit;
|
max-block-size: inherit;
|
||||||
}
|
}
|
||||||
#page-accueil .storytelling__image img {
|
#page-accueil .storytelling__image img {
|
||||||
scale: 0.9;
|
scale: 0.95;
|
||||||
max-height: inherit;
|
max-block-size: inherit;
|
||||||
margin: auto;
|
margin: auto;
|
||||||
object-fit: contain;
|
object-fit: contain;
|
||||||
background: transparent;
|
background: transparent;
|
||||||
}
|
}
|
||||||
|
@media (scripting: none) {
|
||||||
|
#page-accueil .storytelling__animation {
|
||||||
|
visibility: hidden;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@media (width <= 700px) {
|
||||||
|
#page-accueil {
|
||||||
|
--conteneur-marges-internes-ligne: var(--espace-l);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@media (width <= 500px) {
|
||||||
|
#page-accueil {
|
||||||
|
--conteneur-marges-internes-ligne: var(--espace-m);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@supports (-moz-appearance: none) {
|
||||||
|
#page-accueil .storytelling__animation {
|
||||||
|
--taille-police: calc(var(--espace-xl) * 2.2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*# sourceMappingURL=page-accueil.css.map */
|
/*# sourceMappingURL=page-accueil.css.map */
|
||||||
|
|
|
||||||
|
|
@ -1 +1 @@
|
||||||
{"version":3,"sourceRoot":"","sources":["../../../src/sass/pages/page-accueil.scss"],"names":[],"mappings":"AAEA;EAEE;EAGA;EAEA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;;AAGF;EACE;;AAGF;EACE;EACA;EACA;EACA;EACA","file":"page-accueil.css"}
|
{"version":3,"sourceRoot":"","sources":["../../../src/sass/pages/page-accueil.scss"],"names":[],"mappings":";AAEA;EAEE;EAGA;EACA;EAEA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA;EACA;EACA;;AAIF;EACE;EACA;EAEA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAQA;EACE;AAEA;AAAA;EAEA;;AAIF;AACE;AAAA;EAEA;;AAGF;EACE;EAGA;EACA;;AAGF;EACE;EAGA;EACA;EAGA;EACA;EACA;;AAIJ;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;;AAGF;EACE;;AAGF;EACE;EACA;EACA;EACA;EACA;;AAMN;EACE;IACE;;;AAIJ;EAjIF;IAkII;;;AAGF;EArIF;IAsII;;;;AAKJ;EACE;IACE","file":"page-accueil.css"}
|
||||||
|
|
@ -1 +1 @@
|
||||||
#page-accueil{--hauteur-conteneur:var(--contenu-page-hauteur-minimale-sans-categories);--page-marges-bloc-debut:var(--en-tete-hauteur);min-height:var(--hauteur-conteneur);max-height:var(--hauteur-conteneur);margin-top:var(--page-marges-bloc-debut);flex-flow:column;display:flex;overflow:hidden}#page-accueil .storytelling{min-height:inherit;max-height:inherit;place-items:center;overflow-y:scroll}#page-accueil .storytelling__conteneur{min-height:calc(var(--hauteur-conteneur)*13);padding:0 var(--espace-xl);flex-flow:column;display:flex}#page-accueil .storytelling__image{width:100%;min-height:var(--hauteur-conteneur);max-height:var(--hauteur-conteneur);align-content:center;position:sticky;top:0}#page-accueil .storytelling__image[data-cache]{display:none}#page-accueil .storytelling__image picture{max-height:inherit}#page-accueil .storytelling__image img{max-height:inherit;object-fit:contain;background:0 0;margin:auto;scale:.9}
|
#page-accueil{--hauteur-conteneur:var(--contenu-page-hauteur-minimale-sans-categories);--page-marges-bloc-debut:var(--en-tete-hauteur);--conteneur-marges-internes-ligne:var(--espace-xl);min-block-size:var(--hauteur-conteneur);max-block-size:var(--hauteur-conteneur);margin-top:var(--page-marges-bloc-debut);flex-flow:column;display:flex;overflow:hidden}#page-accueil .storytelling{overscroll-behavior:none;min-block-size:inherit;max-block-size:inherit;overflow-y:scroll}#page-accueil .storytelling__conteneur{overscroll-behavior:inherit;min-block-size:calc(var(--hauteur-conteneur)*13);padding:0 var(--conteneur-marges-internes-ligne);flex-flow:column;place-items:center;display:flex}#page-accueil .storytelling__animation{--hauteur-animation:90px;--taille-police:calc(var(--espace-xl)*2.5);pointer-events:none;z-index:3;visibility:visible;opacity:1;block-size:100%;mask-image:linear-gradient(var(--mask-direction,to right),#0000,#000 20%,#000 80%,#0000);place-content:center;place-items:center;margin:auto;transition:opacity 1s ease-in-out,visibility 1s ease-in-out;display:grid;position:absolute;top:0;left:0;right:0;overflow:hidden}#page-accueil .storytelling__animation[hidden]{transition:opacity 1s ease-in-out,visibility 1s ease-in-out;display:grid!important}#page-accueil .storytelling__animation.no-js{transition:opacity 1s ease-in-out,visibility 1s ease-in-out}#page-accueil .storytelling__animation .animation-conteneur{inline-size:120%;block-size:var(--hauteur-animation);overflow:visible}#page-accueil .storytelling__animation .animation-texte{font-size:var(--taille-police);text-shadow:4px 4px 0 var(--couleur-blanc);text-transform:uppercase;letter-spacing:var(--espacement-inter-lettres-rapproche-s);font-weight:600;overflow:visible}#page-accueil .storytelling__image{inline-size:max-content;max-inline-size:100%;min-block-size:var(--hauteur-conteneur);max-block-size:var(--hauteur-conteneur);align-content:center;position:sticky;top:0}#page-accueil .storytelling__image[data-caché]{display:none!important}#page-accueil .storytelling__image picture{max-block-size:inherit}#page-accueil .storytelling__image img{max-block-size:inherit;object-fit:contain;background:0 0;margin:auto;scale:.95}@media (scripting:none){#page-accueil .storytelling__animation{visibility:hidden}}@media (width<=700px){#page-accueil{--conteneur-marges-internes-ligne:var(--espace-l)}}@media (width<=500px){#page-accueil{--conteneur-marges-internes-ligne:var(--espace-m)}}@supports ((-moz-appearance:none)){#page-accueil .storytelling__animation{--taille-police:calc(var(--espace-xl)*2.2)}}
|
||||||
25
web/app/themes/haiku-atelier-2024/src/gleam/README.md
Normal file
25
web/app/themes/haiku-atelier-2024/src/gleam/README.md
Normal file
|
|
@ -0,0 +1,25 @@
|
||||||
|
# haiku_gleam
|
||||||
|
|
||||||
|
[](https://hex.pm/packages/haiku_gleam)
|
||||||
|
[](https://hexdocs.pm/haiku_gleam/)
|
||||||
|
|
||||||
|
```sh
|
||||||
|
gleam add haiku_gleam@1
|
||||||
|
```
|
||||||
|
|
||||||
|
```gleam
|
||||||
|
import haiku_gleam
|
||||||
|
|
||||||
|
pub fn main() -> Nil {
|
||||||
|
// TODO: An example of the project in use
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Further documentation can be found at <https://hexdocs.pm/haiku_gleam>.
|
||||||
|
|
||||||
|
## Development
|
||||||
|
|
||||||
|
```sh
|
||||||
|
gleam run # Run the project
|
||||||
|
gleam test # Run the tests
|
||||||
|
```
|
||||||
11
web/app/themes/haiku-atelier-2024/src/gleam/gleam.toml
Normal file
11
web/app/themes/haiku-atelier-2024/src/gleam/gleam.toml
Normal file
|
|
@ -0,0 +1,11 @@
|
||||||
|
name = "haiku_gleam"
|
||||||
|
target = "javascript"
|
||||||
|
version = "0.0.1"
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
gleam_javascript = ">= 1.0.0 and < 2.0.0"
|
||||||
|
gleam_stdlib = ">= 0.44.0 and < 2.0.0"
|
||||||
|
plinth = ">= 0.6.1 and < 1.0.0"
|
||||||
|
|
||||||
|
[dev-dependencies]
|
||||||
|
gleeunit = ">= 1.0.0 and < 2.0.0"
|
||||||
16
web/app/themes/haiku-atelier-2024/src/gleam/manifest.toml
Normal file
16
web/app/themes/haiku-atelier-2024/src/gleam/manifest.toml
Normal file
|
|
@ -0,0 +1,16 @@
|
||||||
|
# This file was generated by Gleam
|
||||||
|
# You typically do not need to edit this file
|
||||||
|
|
||||||
|
packages = [
|
||||||
|
{ name = "gleam_javascript", version = "1.0.0", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "gleam_javascript", source = "hex", outer_checksum = "EF6C77A506F026C6FB37941889477CD5E4234FCD4337FF0E9384E297CB8F97EB" },
|
||||||
|
{ name = "gleam_json", version = "3.0.1", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "gleam_json", source = "hex", outer_checksum = "5BA154440B22D9800955B1AB854282FA37B97F30F409D76B0824D0A60C934188" },
|
||||||
|
{ name = "gleam_stdlib", version = "0.60.0", build_tools = ["gleam"], requirements = [], otp_app = "gleam_stdlib", source = "hex", outer_checksum = "621D600BB134BC239CB2537630899817B1A42E60A1D46C5E9F3FAE39F88C800B" },
|
||||||
|
{ name = "gleeunit", version = "1.5.1", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "gleeunit", source = "hex", outer_checksum = "D33B7736CF0766ED3065F64A1EBB351E72B2E8DE39BAFC8ADA0E35E92A6A934F" },
|
||||||
|
{ name = "plinth", version = "0.6.1", build_tools = ["gleam"], requirements = ["gleam_javascript", "gleam_json", "gleam_stdlib"], otp_app = "plinth", source = "hex", outer_checksum = "02D6421A27795CDC5C3A452240E21D5D3CB8217219020BB247917132E36CC8F1" },
|
||||||
|
]
|
||||||
|
|
||||||
|
[requirements]
|
||||||
|
gleam_javascript = { version = ">= 1.0.0 and < 2.0.0" }
|
||||||
|
gleam_stdlib = { version = ">= 0.44.0 and < 2.0.0" }
|
||||||
|
gleeunit = { version = ">= 1.0.0 and < 2.0.0" }
|
||||||
|
plinth = { version = ">= 0.6.1 and < 1.0.0" }
|
||||||
|
|
@ -0,0 +1,5 @@
|
||||||
|
import gleam/io
|
||||||
|
|
||||||
|
pub fn main() -> Nil {
|
||||||
|
io.println("Hello from haiku_gleam!")
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,16 @@
|
||||||
|
/**
|
||||||
|
* @param {IntersectionObserverInit} options
|
||||||
|
* @param {IntersectionObserverCallback} callback
|
||||||
|
* @returns {IntersectionObserver}
|
||||||
|
*/
|
||||||
|
export const new_intersection_observer = (options, callback) => {
|
||||||
|
return new IntersectionObserver(callback, options);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {IntersectionObserver} observer
|
||||||
|
* @param {Element} element
|
||||||
|
*/
|
||||||
|
export const observe_element = (observer, element) => {
|
||||||
|
observer.observe(element);
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,22 @@
|
||||||
|
import gleam/option.{type Option}
|
||||||
|
import plinth/browser/document
|
||||||
|
import plinth/browser/element
|
||||||
|
|
||||||
|
pub type IntersectionObserver
|
||||||
|
|
||||||
|
pub type ObservableElement {
|
||||||
|
Element(element.Element)
|
||||||
|
Document(document.Document)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub type Threshold {
|
||||||
|
Threshold(values: List(Int))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub type IntersectionObserverOptions {
|
||||||
|
IntersectionObserverOptions(
|
||||||
|
root: ObservableElement,
|
||||||
|
root_margin: Option(String),
|
||||||
|
threshold: Threshold,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,13 @@
|
||||||
|
import gleeunit
|
||||||
|
|
||||||
|
pub fn main() -> Nil {
|
||||||
|
gleeunit.main()
|
||||||
|
}
|
||||||
|
|
||||||
|
// gleeunit test functions end in `_test`
|
||||||
|
pub fn hello_world_test() {
|
||||||
|
let name = "Joe"
|
||||||
|
let greeting = "Hello, " <> name <> "!"
|
||||||
|
|
||||||
|
assert greeting == "Hello, Joe!"
|
||||||
|
}
|
||||||
|
|
@ -24,6 +24,7 @@
|
||||||
--hauteur-ligne-rapprochee: 1;
|
--hauteur-ligne-rapprochee: 1;
|
||||||
|
|
||||||
/* Espacements entre les lettres */
|
/* Espacements entre les lettres */
|
||||||
|
--espacement-inter-lettres-rapproche-m: -1px;
|
||||||
--espacement-inter-lettres-rapproche-s: -0.5px;
|
--espacement-inter-lettres-rapproche-s: -0.5px;
|
||||||
--espacement-inter-lettres-etendu-s: 0.5px;
|
--espacement-inter-lettres-etendu-s: 0.5px;
|
||||||
--espacement-inter-lettres-etendu-m: 1px;
|
--espacement-inter-lettres-etendu-m: 1px;
|
||||||
|
|
|
||||||
|
|
@ -36,6 +36,7 @@ html {
|
||||||
* 2. Utilise la couleur primaire du site.
|
* 2. Utilise la couleur primaire du site.
|
||||||
*/
|
*/
|
||||||
body {
|
body {
|
||||||
|
overscroll-behavior: none;
|
||||||
accent-color: var(--couleur-jaune); /* 2 */
|
accent-color: var(--couleur-jaune); /* 2 */
|
||||||
background: var(--couleur-gris); /* 1 */
|
background: var(--couleur-gris); /* 1 */
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -85,6 +85,18 @@
|
||||||
/* Dispositions */
|
/* Dispositions */
|
||||||
--liste-puce-cercle-puce-position-horizontale: 3.5ch; /* 3 */
|
--liste-puce-cercle-puce-position-horizontale: 3.5ch; /* 3 */
|
||||||
|
|
||||||
|
// BASELINE001: Marchera seulement pour les navigateurs > 2023.
|
||||||
|
&:has(a[aria-current="page"]) {
|
||||||
|
background: url("/app/themes/haiku-atelier-2024/assets/img/icons/cloud-penche.svg")
|
||||||
|
center/auto 90% no-repeat;
|
||||||
|
}
|
||||||
|
|
||||||
|
// COMPAT001: Pour les navigateurs < 2023.
|
||||||
|
&--courante {
|
||||||
|
background: url("/app/themes/haiku-atelier-2024/assets/img/icons/cloud-penche.svg")
|
||||||
|
center/auto 90% no-repeat;
|
||||||
|
}
|
||||||
|
|
||||||
a {
|
a {
|
||||||
display: inline-block; /* 1 */
|
display: inline-block; /* 1 */
|
||||||
padding: var(--nav-entree-marges-internes-bloc)
|
padding: var(--nav-entree-marges-internes-bloc)
|
||||||
|
|
@ -93,11 +105,6 @@
|
||||||
text-align: center; /* 4 */
|
text-align: center; /* 4 */
|
||||||
}
|
}
|
||||||
|
|
||||||
&--courante {
|
|
||||||
background: url("/app/themes/haiku-atelier-2024/assets/img/icons/cloud-penche.svg")
|
|
||||||
center/auto 90% no-repeat;
|
|
||||||
}
|
|
||||||
|
|
||||||
@media (hover: hover) {
|
@media (hover: hover) {
|
||||||
&:hover {
|
&:hover {
|
||||||
background: url("/app/themes/haiku-atelier-2024/assets/img/icons/cloud-penche.svg")
|
background: url("/app/themes/haiku-atelier-2024/assets/img/icons/cloud-penche.svg")
|
||||||
|
|
|
||||||
|
|
@ -182,13 +182,6 @@
|
||||||
border-block-end: 1px solid var(--couleur-noir);
|
border-block-end: 1px solid var(--couleur-noir);
|
||||||
}
|
}
|
||||||
|
|
||||||
// La section est dépliée.
|
|
||||||
&:has(button[aria-expanded="true"]) {
|
|
||||||
button {
|
|
||||||
/* padding: initial; */
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// La section est fermée.
|
// La section est fermée.
|
||||||
&:has(button[aria-expanded="false"]) .section-textuelle__contenu {
|
&:has(button[aria-expanded="false"]) .section-textuelle__contenu {
|
||||||
display: none;
|
display: none;
|
||||||
|
|
@ -233,7 +226,7 @@
|
||||||
--section-marges-internes: var(--espace-l);
|
--section-marges-internes: var(--espace-l);
|
||||||
|
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
border: 1px solid var(--couleur-noir);
|
border-block: 1px solid var(--couleur-noir);
|
||||||
background: var(--couleur-jaune);
|
background: var(--couleur-jaune);
|
||||||
transition: 0.2s background;
|
transition: 0.2s background;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@
|
||||||
// Dimensions
|
// Dimensions
|
||||||
--carte-produit-longueur-minimale: 448px;
|
--carte-produit-longueur-minimale: 448px;
|
||||||
--carte-produit-longueur-maximale: 1000px;
|
--carte-produit-longueur-maximale: 1000px;
|
||||||
|
--en-tete-flottante-hauteur: calc(1rem + var(--espace-l) * 2 + 1px);
|
||||||
|
|
||||||
position: relative;
|
position: relative;
|
||||||
display: grid;
|
display: grid;
|
||||||
|
|
@ -18,10 +19,10 @@
|
||||||
header {
|
header {
|
||||||
position: sticky;
|
position: sticky;
|
||||||
z-index: 10;
|
z-index: 10;
|
||||||
top: calc(1lh + var(--espace-l) + var(--espace-m));
|
top: var(--en-tete-flottante-hauteur);
|
||||||
grid-area: en-tete;
|
grid-area: en-tete;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
padding: var(--espace-l) 0 var(--espace-m);
|
padding: var(--espace-l) 0;
|
||||||
color: var(--couleur-blanc);
|
color: var(--couleur-blanc);
|
||||||
text-align: center;
|
text-align: center;
|
||||||
background: var(--couleur-noir);
|
background: var(--couleur-noir);
|
||||||
|
|
|
||||||
|
|
@ -6,50 +6,141 @@
|
||||||
|
|
||||||
// Marges
|
// Marges
|
||||||
--page-marges-bloc-debut: var(--en-tete-hauteur);
|
--page-marges-bloc-debut: var(--en-tete-hauteur);
|
||||||
|
--conteneur-marges-internes-ligne: var(--espace-xl);
|
||||||
|
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-flow: column nowrap;
|
flex-flow: column nowrap;
|
||||||
min-height: var(--hauteur-conteneur);
|
min-block-size: var(--hauteur-conteneur);
|
||||||
max-height: var(--hauteur-conteneur);
|
max-block-size: var(--hauteur-conteneur);
|
||||||
margin-top: var(--page-marges-bloc-debut);
|
margin-top: var(--page-marges-bloc-debut);
|
||||||
|
|
||||||
.storytelling {
|
.storytelling {
|
||||||
overflow-y: scroll;
|
overflow-y: scroll;
|
||||||
place-items: center;
|
overscroll-behavior: none;
|
||||||
min-height: inherit;
|
min-block-size: inherit;
|
||||||
max-height: inherit;
|
max-block-size: inherit;
|
||||||
|
|
||||||
&__conteneur {
|
&__conteneur {
|
||||||
|
overscroll-behavior: inherit;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-flow: column nowrap;
|
flex-flow: column nowrap;
|
||||||
min-height: calc(var(--hauteur-conteneur) * 13);
|
place-items: center;
|
||||||
padding: 0 var(--espace-xl);
|
min-block-size: calc(var(--hauteur-conteneur) * 13);
|
||||||
|
padding: 0 var(--conteneur-marges-internes-ligne);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Texte animé indiquant à l'Utilisateur de défiler vers le bas.
|
||||||
|
&__animation {
|
||||||
|
--hauteur-animation: 90px;
|
||||||
|
--taille-police: calc(var(--espace-xl) * 2.5);
|
||||||
|
|
||||||
|
pointer-events: none;
|
||||||
|
position: absolute;
|
||||||
|
z-index: 3;
|
||||||
|
top: 0;
|
||||||
|
right: 0;
|
||||||
|
left: 0;
|
||||||
|
overflow: hidden;
|
||||||
|
display: grid;
|
||||||
|
place-content: center;
|
||||||
|
place-items: center;
|
||||||
|
block-size: 100%;
|
||||||
|
margin: auto;
|
||||||
|
visibility: visible;
|
||||||
|
opacity: 1;
|
||||||
|
transition: 1s opacity ease-in-out, 1s visibility ease-in-out;
|
||||||
|
mask-image: linear-gradient(
|
||||||
|
var(--mask-direction, to right),
|
||||||
|
hsl(0deg 0% 0% / 0%),
|
||||||
|
hsl(0deg 0% 0% / 100%) 20%,
|
||||||
|
hsl(0deg 0% 0% / 100%) 80%,
|
||||||
|
hsl(0deg 0% 0% / 0%)
|
||||||
|
);
|
||||||
|
|
||||||
|
&[hidden] {
|
||||||
|
display: grid !important;
|
||||||
|
|
||||||
|
/* visibility: hidden;
|
||||||
|
opacity: 0; */
|
||||||
|
transition: 1s opacity ease-in-out, 1s visibility ease-in-out;
|
||||||
|
}
|
||||||
|
|
||||||
|
// N'affiche rien si JavaScript n'est pas activé.
|
||||||
|
&.no-js {
|
||||||
|
/* visibility: hidden;
|
||||||
|
opacity: 0; */
|
||||||
|
transition: 1s opacity ease-in-out, 1s visibility ease-in-out;
|
||||||
|
}
|
||||||
|
|
||||||
|
.animation-conteneur {
|
||||||
|
overflow: visible;
|
||||||
|
|
||||||
|
// Nécessaire pour que les lettres apparaissent « en douceur » dans la vue.
|
||||||
|
inline-size: 120%;
|
||||||
|
block-size: var(--hauteur-animation);
|
||||||
|
}
|
||||||
|
|
||||||
|
.animation-texte {
|
||||||
|
overflow: visible;
|
||||||
|
|
||||||
|
// TODO: Pourquoi y-a-t'il une telle difference de rendu entre Chromium et FF ?
|
||||||
|
font-size: var(--taille-police);
|
||||||
|
font-weight: 600;
|
||||||
|
|
||||||
|
// TODO: Pourquoi y-a-t'il une telle difference de rendu entre Chromium et FF ?
|
||||||
|
text-shadow: 4px 4px 0 var(--couleur-blanc);
|
||||||
|
text-transform: uppercase;
|
||||||
|
letter-spacing: var(--espacement-inter-lettres-rapproche-s);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
&__image {
|
&__image {
|
||||||
position: sticky;
|
position: sticky;
|
||||||
top: 0;
|
top: 0;
|
||||||
align-content: center;
|
align-content: center;
|
||||||
width: 100%;
|
inline-size: max-content;
|
||||||
min-height: var(--hauteur-conteneur);
|
max-inline-size: 100%;
|
||||||
max-height: var(--hauteur-conteneur);
|
min-block-size: var(--hauteur-conteneur);
|
||||||
|
max-block-size: var(--hauteur-conteneur);
|
||||||
|
|
||||||
&[data-cache] {
|
&[data-caché] {
|
||||||
display: none;
|
display: none !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
picture {
|
picture {
|
||||||
max-height: inherit;
|
max-block-size: inherit;
|
||||||
}
|
}
|
||||||
|
|
||||||
img {
|
img {
|
||||||
scale: 0.9;
|
scale: 0.95;
|
||||||
max-height: inherit;
|
max-block-size: inherit;
|
||||||
margin: auto;
|
margin: auto;
|
||||||
object-fit: contain;
|
object-fit: contain;
|
||||||
background: transparent;
|
background: transparent;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Désactive l'animation si JavaScript n'est pas disponible.
|
||||||
|
@media (scripting: none) {
|
||||||
|
.storytelling__animation {
|
||||||
|
visibility: hidden;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (width <= 700px) {
|
||||||
|
--conteneur-marges-internes-ligne: var(--espace-l);
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (width <= 500px) {
|
||||||
|
--conteneur-marges-internes-ligne: var(--espace-m);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: Réduit la taille de la police de l'animation sur FF car elle apparaît plus grande...
|
||||||
|
@supports (-moz-appearance: none) {
|
||||||
|
#page-accueil .storytelling__animation {
|
||||||
|
--taille-police: calc(var(--espace-xl) * 2.2);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,11 @@
|
||||||
/** Constantes de valeurs pour la manipulation du DOM : sélecteurs et attributs. */
|
/** Constantes de valeurs pour la manipulation du DOM : sélecteurs et attributs. */
|
||||||
|
|
||||||
|
export const ATTRIBUT_ACTIF = "data-actif";
|
||||||
export const ATTRIBUT_ARIA_CONTROLS = "aria-controls";
|
export const ATTRIBUT_ARIA_CONTROLS = "aria-controls";
|
||||||
export const ATTRIBUT_ARIA_EXPANDED = "aria-expanded";
|
export const ATTRIBUT_ARIA_EXPANDED = "aria-expanded";
|
||||||
export const ATTRIBUT_ARIA_HIDDEN = "aria-hidden";
|
export const ATTRIBUT_ARIA_HIDDEN = "aria-hidden";
|
||||||
export const ATTRIBUT_ARIA_SELECTED = "aria-selected";
|
export const ATTRIBUT_ARIA_SELECTED = "aria-selected";
|
||||||
export const ATTRIBUT_CACHE = "data-cache";
|
export const ATTRIBUT_CACHÉ = "data-caché";
|
||||||
export const ATTRIBUT_ACTIF = "data-actif";
|
|
||||||
export const ATTRIBUT_CHARGEMENT = "data-chargement";
|
export const ATTRIBUT_CHARGEMENT = "data-chargement";
|
||||||
export const ATTRIBUT_CLE_PANIER = "data-cle-panier";
|
export const ATTRIBUT_CLE_PANIER = "data-cle-panier";
|
||||||
export const ATTRIBUT_CODE_PROMO_PRESENT = "data-code-promo-present";
|
export const ATTRIBUT_CODE_PROMO_PRESENT = "data-code-promo-present";
|
||||||
|
|
@ -24,61 +24,61 @@ export const ATTRIBUT_PRIX = "data-prix";
|
||||||
export const ATTRIBUT_TABINDEX = "tabindex";
|
export const ATTRIBUT_TABINDEX = "tabindex";
|
||||||
|
|
||||||
// En-tête
|
// En-tête
|
||||||
export const SELECTEUR_BOUTON_MENU_MOBILE = "#bouton-menu-mobile";
|
export const DOM_BOUTON_MENU_MOBILE = "#bouton-menu-mobile";
|
||||||
export const SELECTEUR_BOUTON_PANIER = ".compte-panier a[rel='cart']";
|
export const DOM_BOUTON_PANIER = ".compte-panier a[rel='cart']";
|
||||||
export const SELECTEUR_ENTREE_MENU_CATEGORIES_PRODUITS = "#menu-categories-produits ul li a";
|
export const DOM_ENTREE_MENU_CATEGORIES_PRODUITS = "#menu-categories-produits ul li a";
|
||||||
export const SELECTEUR_FLECHE_DROITE_CATEGORIES_PRODUITS = "#fleche-defilement-categories-produits-droite";
|
export const DOM_MENU_CATEGORIES_PRODUITS = "#menu-categories-produits";
|
||||||
export const SELECTEUR_FLECHE_GAUCHE_CATEGORIES_PRODUITS = "#fleche-defilement-categories-produits-gauche";
|
export const DOM_MENU_MOBILE = "#menu-mobile";
|
||||||
export const SELECTEUR_MENU_CATEGORIES_PRODUITS = "#menu-categories-produits";
|
|
||||||
export const SELECTEUR_MENU_MOBILE = "#menu-mobile";
|
|
||||||
|
|
||||||
// Panier
|
// Panier
|
||||||
export const SELECTEUR_BOUTON_ACTIONS_FORMULAIRE = "#panneau-informations-client .panneau__pied-de-page button";
|
export const DOM_BOUTON_ACTIONS_FORMULAIRE = "#panneau-informations-client .panneau__pied-de-page button";
|
||||||
export const SELECTEUR_BOUTON_ADDITION_QUANTITE = "button.detail-produit__actions__addition";
|
export const DOM_BOUTON_ADDITION_QUANTITE = "button.detail-produit__actions__addition";
|
||||||
export const SELECTEUR_BOUTON_CODE_PROMO = "#panneau-panier #bouton-code-promo";
|
export const DOM_BOUTON_CODE_PROMO = "#panneau-panier #bouton-code-promo";
|
||||||
export const SELECTEUR_BOUTON_SEPARATION_ADRESSES = "#separation-adresses";
|
export const DOM_BOUTON_SEPARATION_ADRESSES = "#separation-adresses";
|
||||||
export const SELECTEUR_BOUTON_SOUSTRACTION_QUANTITE = "button.detail-produit__actions__soustraction";
|
export const DOM_BOUTON_SOUSTRACTION_QUANTITE = "button.detail-produit__actions__soustraction";
|
||||||
export const SELECTEUR_BOUTON_SUPPRESSION_PANIER = "button.detail-produit__actions__suppression";
|
export const DOM_BOUTON_SUPPRESSION_PANIER = "button.detail-produit__actions__suppression";
|
||||||
export const SELECTEUR_CHAMP_CODE_PROMO = "#panneau-panier #champ-code-promo";
|
export const DOM_CHAMP_CODE_PROMO = "#panneau-panier #champ-code-promo";
|
||||||
export const SELECTEUR_CHAMP_QUANTITE_LIGNE_PANIER = "input";
|
export const DOM_CHAMP_QUANTITE_LIGNE_PANIER = "input";
|
||||||
export const SELECTEUR_CONTENEUR_METHODES_LIVRAISON = "#panneau-panier #choix-methode-livraison";
|
export const DOM_CONTENEUR_METHODES_LIVRAISON = "#panneau-panier #choix-methode-livraison";
|
||||||
export const SELECTEUR_ENSEMBLE_CODE_PROMO = "#panneau-panier #ensemble-code-promo";
|
export const DOM_ENSEMBLE_CODE_PROMO = "#panneau-panier #ensemble-code-promo";
|
||||||
export const SELECTEUR_ENTREES_PANIER = "article";
|
export const DOM_ENTREES_PANIER = "article";
|
||||||
export const SELECTEUR_FORMULAIRE_FACTURATION = "#panneau-informations-client .panneau__formulaires__facturation";
|
export const DOM_FORMULAIRE_FACTURATION = "#panneau-informations-client .panneau__formulaires__facturation";
|
||||||
export const SELECTEUR_FORMULAIRE_LIVRAISON = "#panneau-informations-client .panneau__formulaires__livraison";
|
export const DOM_FORMULAIRE_LIVRAISON = "#panneau-informations-client .panneau__formulaires__livraison";
|
||||||
export const SELECTEUR_FORMULAIRE_PANIER = "#panneau-informations-client form";
|
export const DOM_FORMULAIRE_PANIER = "#panneau-informations-client form";
|
||||||
export const SELECTEUR_INSTRUCTIONS_CLIENT = "#panneau-panier #instructions-client";
|
export const DOM_INSTRUCTIONS_CLIENT = "#panneau-panier #instructions-client";
|
||||||
export const SELECTEUR_MESSAGE_CODE_PROMO = "#panneau-panier .panneau__instructions-code-promo__code-promo__message";
|
export const DOM_MESSAGE_CODE_PROMO = "#panneau-panier .panneau__instructions-code-promo__code-promo__message";
|
||||||
export const SELECTEUR_MESSAGE_FORMULAIRE_ADRESSES = "#panneau-informations-client #message-formulaire-adresses";
|
export const DOM_MESSAGE_FORMULAIRE_ADRESSES = "#panneau-informations-client #message-formulaire-adresses";
|
||||||
export const SELECTEUR_PRIX_LIGNE_PANIER = ".detail-produit__nom-prix span";
|
export const DOM_PRIX_LIGNE_PANIER = ".detail-produit__nom-prix span";
|
||||||
export const SELECTEUR_SOUS_TOTAL_LIVRAISON_COUT = "#panneau-panier #sous-total-livraison strong";
|
export const DOM_SOUS_TOTAL_LIVRAISON_COUT = "#panneau-panier #sous-total-livraison strong";
|
||||||
export const SELECTEUR_SOUS_TOTAL_LIVRAISON_PRESTATAIRE = "#panneau-panier #sous-total-livraison span";
|
export const DOM_SOUS_TOTAL_LIVRAISON_PRESTATAIRE = "#panneau-panier #sous-total-livraison span";
|
||||||
export const SELECTEUR_SOUS_TOTAL_PRODUITS = "#panneau-panier #sous-total-produits strong";
|
export const DOM_SOUS_TOTAL_PRODUITS = "#panneau-panier #sous-total-produits strong";
|
||||||
export const SELECTEUR_TOTAL_PANIER = "#panneau-panier .panneau__pied-de-page p span";
|
export const DOM_TOTAL_PANIER = "#panneau-panier .panneau__pied-de-page p span";
|
||||||
export const SELECTEUR_TOTAL_REDUCTION = "#panneau-panier #sous-total-reduction";
|
export const DOM_TOTAL_REDUCTION = "#panneau-panier #sous-total-reduction";
|
||||||
export const SELECTEUR_TOTAL_REDUCTION_VALEUR = "#panneau-panier #sous-total-reduction strong";
|
export const DOM_TOTAL_REDUCTION_VALEUR = "#panneau-panier #sous-total-reduction strong";
|
||||||
|
|
||||||
// Accueil
|
// Accueil
|
||||||
export const SELECTEUR_CONTENEUR_STORYTELLING = ".storytelling";
|
export const DOM_CONTENEUR_ANIMATION = ".storytelling__animation";
|
||||||
export const SELECTEUR_IMAGES_STORYTELLING = ".storytelling__image";
|
export const DOM_CONTENEUR_STORYTELLING = ".storytelling";
|
||||||
|
export const DOM_GARDE_FOU_JS = "no-js";
|
||||||
|
export const DOM_IMAGES_STORYTELLING = ".storytelling__image";
|
||||||
|
|
||||||
// Boutique
|
// Boutique
|
||||||
export const SELECTEUR_BOUTON_PLUS_PRODUITS = "#page-boutique #bouton-plus-de-produits";
|
export const DOM_BOUTON_PLUS_PRODUITS = "#page-boutique #bouton-plus-de-produits";
|
||||||
export const SELECTEUR_GRILLE_PRODUITS = "#page-boutique .grille-produits";
|
export const DOM_GRILLE_PRODUITS = "#page-boutique .grille-produits";
|
||||||
|
|
||||||
// À propos
|
// À propos
|
||||||
export const CLASS_BOITE_TEXTE = "boite-texte";
|
export const CLASS_BOITE_TEXTE = "boite-texte";
|
||||||
export const CLASS_BOUTON_FERMETURE_BOITE_TEXTE = "boite-texte__bouton-fermeture";
|
export const CLASS_BOUTON_FERMETURE_BOITE_TEXTE = "boite-texte__bouton-fermeture";
|
||||||
export const CLASS_EPINGLE = "epingle";
|
export const CLASS_EPINGLE = "epingle";
|
||||||
export const SELECTEUR_BOITE_TEXTE = `.${CLASS_BOITE_TEXTE}`;
|
export const DOM_BOITE_TEXTE = `.${CLASS_BOITE_TEXTE}`;
|
||||||
export const SELECTEUR_BOUTON_FERMETURE_BOITE_TEXTE = `.${CLASS_BOUTON_FERMETURE_BOITE_TEXTE}`;
|
export const DOM_BOUTON_FERMETURE_BOITE_TEXTE = `.${CLASS_BOUTON_FERMETURE_BOITE_TEXTE}`;
|
||||||
export const SELECTEUR_CONTENEUR_STORYTELLING_A_PROPOS = ".storytelling__conteneur";
|
export const DOM_CONTENEUR_STORYTELLING_A_PROPOS = ".storytelling__conteneur";
|
||||||
export const SELECTEUR_EPINGLE = `.${CLASS_EPINGLE}`;
|
export const DOM_EPINGLE = `.${CLASS_EPINGLE}`;
|
||||||
|
|
||||||
// Produit
|
// Produit
|
||||||
export const SELECTEUR_BOUTON_AJOUT_PANIER = "#bouton-ajout-panier";
|
export const DOM_BOUTON_AJOUT_PANIER = "#bouton-ajout-panier";
|
||||||
export const SELECTEUR_CONTENEUR_PANIER = "#page-panier";
|
export const DOM_CONTENEUR_PANIER = "#page-panier";
|
||||||
export const SELECTEUR_PRIX_PRODUIT = ".selecteur-produit__prix";
|
export const DOM_PRIX_PRODUIT = ".selecteur-produit__prix";
|
||||||
export const SELECTEUR_SELECTEUR_QUANTITE = "#selecteur-variation";
|
export const DOM_DOM_QUANTITE = "#selecteur-variation";
|
||||||
export const SELECTEUR_BOUTONS_ACCORDEON = ".section-textuelle button";
|
export const DOM_BOUTONS_ACCORDEON = ".section-textuelle button";
|
||||||
export const SELECTEUR_CONTENUS_ACCORDEON = ".section-textuelle__contenu";
|
export const DOM_CONTENUS_ACCORDEON = ".section-textuelle__contenu";
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
|
import { configureSync, getConsoleSink, getLogger } from "@logtape/logtape";
|
||||||
import chalk from "chalk";
|
import chalk from "chalk";
|
||||||
import log, { type Logger } from "loglevel";
|
import log, { type Logger } from "loglevel";
|
||||||
import prefix from "loglevel-plugin-prefix";
|
import prefix from "loglevel-plugin-prefix";
|
||||||
|
|
@ -19,3 +20,17 @@ prefix.apply(logger, {
|
||||||
return `${chalk.gray(`[${timestamp}]`)} ${colors[level.toUpperCase()](level)}`;
|
return `${chalk.gray(`[${timestamp}]`)} ${colors[level.toUpperCase()](level)}`;
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const HAIKU_ATELIER_LOGGER = "haiku-atelier";
|
||||||
|
configureSync({
|
||||||
|
loggers: [
|
||||||
|
{
|
||||||
|
category: HAIKU_ATELIER_LOGGER,
|
||||||
|
lowestLevel: "debug",
|
||||||
|
sinks: ["console"],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
sinks: { console: getConsoleSink() },
|
||||||
|
});
|
||||||
|
|
||||||
|
export const nuLogger = getLogger(HAIKU_ATELIER_LOGGER);
|
||||||
|
|
@ -4,12 +4,12 @@ import { Either, identity, Left, Right } from "purify-ts";
|
||||||
import type { ParentElement } from "./types/dom.d.ts";
|
import type { ParentElement } from "./types/dom.d.ts";
|
||||||
|
|
||||||
import { ATTRIBUT_CHARGEMENT, ATTRIBUT_DESACTIVE } from "../constantes/dom.ts";
|
import { ATTRIBUT_CHARGEMENT, ATTRIBUT_DESACTIVE } from "../constantes/dom.ts";
|
||||||
import { logger } from "../logging.ts";
|
import { logger } from "../journalisation.ts";
|
||||||
import { lanceAnimationCycleLoading } from "./animations.ts";
|
import { lanceAnimationCycleLoading } from "./animations.ts";
|
||||||
import {
|
import {
|
||||||
BadRequestError,
|
BadRequestError,
|
||||||
creeSyntaxError,
|
creeSyntaxError,
|
||||||
ERREUR_SELECTEUR_INEXISTANT,
|
ERREUR_DOM_INEXISTANT,
|
||||||
ERREUR_SYNTAXE_INVALIDE,
|
ERREUR_SYNTAXE_INVALIDE,
|
||||||
ForbiddenError,
|
ForbiddenError,
|
||||||
NotFoundError,
|
NotFoundError,
|
||||||
|
|
@ -26,9 +26,7 @@ export const recupereElementAvecSelecteur =
|
||||||
// Transforme le Left en une erreur plus sympathique
|
// Transforme le Left en une erreur plus sympathique
|
||||||
.mapLeft(_ => creeSyntaxError(ERREUR_SYNTAXE_INVALIDE(selecteur)))
|
.mapLeft(_ => creeSyntaxError(ERREUR_SYNTAXE_INVALIDE(selecteur)))
|
||||||
// Retourne une SyntaxError si l'Élément est null
|
// Retourne une SyntaxError si l'Élément est null
|
||||||
.chain((e: E | null) =>
|
.chain((e: E | null) => G.isNotNullable(e) ? Right(e) : Left(creeSyntaxError(ERREUR_DOM_INEXISTANT(selecteur))));
|
||||||
G.isNotNullable(e) ? Right(e) : Left(creeSyntaxError(ERREUR_SELECTEUR_INEXISTANT(selecteur)))
|
|
||||||
);
|
|
||||||
|
|
||||||
export const getDOMElementsWithSelector =
|
export const getDOMElementsWithSelector =
|
||||||
(parent: ParentElement) => <E extends Element = Element>(selecteur: string): Either<SyntaxError, Array<E>> =>
|
(parent: ParentElement) => <E extends Element = Element>(selecteur: string): Either<SyntaxError, Array<E>> =>
|
||||||
|
|
@ -38,7 +36,7 @@ export const getDOMElementsWithSelector =
|
||||||
// Transforme le Left en une erreur plus sympathique
|
// Transforme le Left en une erreur plus sympathique
|
||||||
.mapLeft(_ => creeSyntaxError(ERREUR_SYNTAXE_INVALIDE(selecteur)))
|
.mapLeft(_ => creeSyntaxError(ERREUR_SYNTAXE_INVALIDE(selecteur)))
|
||||||
// Retourne une SyntaxError si le tableau est vide
|
// Retourne une SyntaxError si le tableau est vide
|
||||||
.chain((e: Array<E>) => A.isEmpty(e) ? Left(creeSyntaxError(ERREUR_SELECTEUR_INEXISTANT(selecteur))) : Right(e));
|
.chain((e: Array<E>) => A.isEmpty(e) ? Left(creeSyntaxError(ERREUR_DOM_INEXISTANT(selecteur))) : Right(e));
|
||||||
|
|
||||||
export const recupereElementOuLeve = <E extends Element = Element>(elementOuErreur: Either<SyntaxError, E>): E =>
|
export const recupereElementOuLeve = <E extends Element = Element>(elementOuErreur: Either<SyntaxError, E>): E =>
|
||||||
elementOuErreur.caseOf({
|
elementOuErreur.caseOf({
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@ import { ErreurAdresseInvalide } from "./erreurs/adresses";
|
||||||
|
|
||||||
/* Messages d'erreur */
|
/* Messages d'erreur */
|
||||||
export const ERREUR_SYNTAXE_INVALIDE = (selecteur: string): string => `Le selecteur "${selecteur}" est invalide`;
|
export const ERREUR_SYNTAXE_INVALIDE = (selecteur: string): string => `Le selecteur "${selecteur}" est invalide`;
|
||||||
export const ERREUR_SELECTEUR_INEXISTANT = (selecteur: string): string =>
|
export const ERREUR_DOM_INEXISTANT = (selecteur: string): string =>
|
||||||
`La requête "${selecteur}" n'a retourné aucun Élément.`;
|
`La requête "${selecteur}" n'a retourné aucun Élément.`;
|
||||||
|
|
||||||
/* Création d'erreurs */
|
/* Création d'erreurs */
|
||||||
|
|
|
||||||
|
|
@ -40,7 +40,7 @@ import { WCStoreCartUpdateCustomerArgsSchema } from "../lib/schemas/api/cart-upd
|
||||||
import { estWCAddressError } from "../lib/schemas/api/erreurs";
|
import { estWCAddressError } from "../lib/schemas/api/erreurs";
|
||||||
import { WCV3OrdersArgsSchema, WCV3OrderSchema } from "../lib/schemas/api/v3/orders";
|
import { WCV3OrdersArgsSchema, WCV3OrderSchema } from "../lib/schemas/api/v3/orders";
|
||||||
import { safeSchemaParse } from "../lib/validation";
|
import { safeSchemaParse } from "../lib/validation";
|
||||||
import { logger } from "../logging";
|
import { logger } from "../journalisation.ts";
|
||||||
import { E } from "./scripts-page-panier-elements";
|
import { E } from "./scripts-page-panier-elements";
|
||||||
import { getShippingRatesLS } from "./scripts-page-panier-local-storage";
|
import { getShippingRatesLS } from "./scripts-page-panier-local-storage";
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,7 @@ import {
|
||||||
ATTRIBUT_CODE_PROMO_PRESENT,
|
ATTRIBUT_CODE_PROMO_PRESENT,
|
||||||
ATTRIBUT_DESACTIVE,
|
ATTRIBUT_DESACTIVE,
|
||||||
ATTRIBUT_HIDDEN,
|
ATTRIBUT_HIDDEN,
|
||||||
SELECTEUR_BOUTON_CODE_PROMO,
|
DOM_BOUTON_CODE_PROMO,
|
||||||
} from "../constantes/dom";
|
} from "../constantes/dom";
|
||||||
import { NOM_CANAL_REVALIDATION_LIVRAISON } from "../constantes/messages";
|
import { NOM_CANAL_REVALIDATION_LIVRAISON } from "../constantes/messages";
|
||||||
import { lanceAnimationCycleLoading } from "../lib/animations";
|
import { lanceAnimationCycleLoading } from "../lib/animations";
|
||||||
|
|
@ -59,7 +59,7 @@ export const initialiseElementsCodePromo = (): void => {
|
||||||
.with(
|
.with(
|
||||||
{
|
{
|
||||||
cible: P.when((cible: EventTarget | null) =>
|
cible: P.when((cible: EventTarget | null) =>
|
||||||
targetMatchesSelector<HTMLButtonElement>(cible, SELECTEUR_BOUTON_CODE_PROMO)
|
targetMatchesSelector<HTMLButtonElement>(cible, DOM_BOUTON_CODE_PROMO)
|
||||||
),
|
),
|
||||||
codePromoPresent: false,
|
codePromoPresent: false,
|
||||||
valeurCodePromo: P.string,
|
valeurCodePromo: P.string,
|
||||||
|
|
@ -170,7 +170,7 @@ export const initialiseElementsCodePromo = (): void => {
|
||||||
// Un code promo est présent sous forme de chaîne
|
// Un code promo est présent sous forme de chaîne
|
||||||
.with(
|
.with(
|
||||||
{
|
{
|
||||||
cible: P.when(cible => targetMatchesSelector<HTMLButtonElement>(cible, SELECTEUR_BOUTON_CODE_PROMO)),
|
cible: P.when(cible => targetMatchesSelector<HTMLButtonElement>(cible, DOM_BOUTON_CODE_PROMO)),
|
||||||
codePromoPresent: true,
|
codePromoPresent: true,
|
||||||
valeurCodePromo: P.string,
|
valeurCodePromo: P.string,
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -1,48 +1,48 @@
|
||||||
import {
|
import {
|
||||||
SELECTEUR_BOUTON_ACTIONS_FORMULAIRE,
|
DOM_BOUTON_ACTIONS_FORMULAIRE,
|
||||||
SELECTEUR_BOUTON_CODE_PROMO,
|
DOM_BOUTON_CODE_PROMO,
|
||||||
SELECTEUR_BOUTON_SEPARATION_ADRESSES,
|
DOM_BOUTON_SEPARATION_ADRESSES,
|
||||||
SELECTEUR_CHAMP_CODE_PROMO,
|
DOM_CHAMP_CODE_PROMO,
|
||||||
SELECTEUR_CONTENEUR_METHODES_LIVRAISON,
|
DOM_CONTENEUR_METHODES_LIVRAISON,
|
||||||
SELECTEUR_CONTENEUR_PANIER,
|
DOM_CONTENEUR_PANIER,
|
||||||
SELECTEUR_ENSEMBLE_CODE_PROMO,
|
DOM_ENSEMBLE_CODE_PROMO,
|
||||||
SELECTEUR_ENTREES_PANIER,
|
DOM_ENTREES_PANIER,
|
||||||
SELECTEUR_FORMULAIRE_FACTURATION,
|
DOM_FORMULAIRE_FACTURATION,
|
||||||
SELECTEUR_FORMULAIRE_PANIER,
|
DOM_FORMULAIRE_PANIER,
|
||||||
SELECTEUR_INSTRUCTIONS_CLIENT,
|
DOM_INSTRUCTIONS_CLIENT,
|
||||||
SELECTEUR_MESSAGE_CODE_PROMO,
|
DOM_MESSAGE_CODE_PROMO,
|
||||||
SELECTEUR_MESSAGE_FORMULAIRE_ADRESSES,
|
DOM_MESSAGE_FORMULAIRE_ADRESSES,
|
||||||
SELECTEUR_SOUS_TOTAL_LIVRAISON_COUT,
|
DOM_SOUS_TOTAL_LIVRAISON_COUT,
|
||||||
SELECTEUR_SOUS_TOTAL_PRODUITS,
|
DOM_SOUS_TOTAL_PRODUITS,
|
||||||
SELECTEUR_TOTAL_PANIER,
|
DOM_TOTAL_PANIER,
|
||||||
SELECTEUR_TOTAL_REDUCTION,
|
DOM_TOTAL_REDUCTION,
|
||||||
SELECTEUR_TOTAL_REDUCTION_VALEUR,
|
DOM_TOTAL_REDUCTION_VALEUR,
|
||||||
} from "../constantes/dom";
|
} from "../constantes/dom";
|
||||||
import { mustGetEleInDocument, recupereElementsDocumentEither } from "../lib/dom";
|
import { mustGetEleInDocument, recupereElementsDocumentEither } from "../lib/dom";
|
||||||
|
|
||||||
export const E = {
|
export const E = {
|
||||||
BOUTON_ACTIONS_FORMULAIRE: mustGetEleInDocument<HTMLButtonElement>(SELECTEUR_BOUTON_ACTIONS_FORMULAIRE),
|
BOUTON_ACTIONS_FORMULAIRE: mustGetEleInDocument<HTMLButtonElement>(DOM_BOUTON_ACTIONS_FORMULAIRE),
|
||||||
BOUTON_CODE_PROMO: mustGetEleInDocument<HTMLButtonElement>(SELECTEUR_BOUTON_CODE_PROMO),
|
BOUTON_CODE_PROMO: mustGetEleInDocument<HTMLButtonElement>(DOM_BOUTON_CODE_PROMO),
|
||||||
BOUTON_SEPARATION_ADRESSES: mustGetEleInDocument<HTMLInputElement>(SELECTEUR_BOUTON_SEPARATION_ADRESSES),
|
BOUTON_SEPARATION_ADRESSES: mustGetEleInDocument<HTMLInputElement>(DOM_BOUTON_SEPARATION_ADRESSES),
|
||||||
CHAMP_CODE_PROMO: mustGetEleInDocument<HTMLInputElement>(SELECTEUR_CHAMP_CODE_PROMO),
|
CHAMP_CODE_PROMO: mustGetEleInDocument<HTMLInputElement>(DOM_CHAMP_CODE_PROMO),
|
||||||
CONTENEUR_METHODES_LIVRAISON: mustGetEleInDocument<HTMLFieldSetElement>(SELECTEUR_CONTENEUR_METHODES_LIVRAISON),
|
CONTENEUR_METHODES_LIVRAISON: mustGetEleInDocument<HTMLFieldSetElement>(DOM_CONTENEUR_METHODES_LIVRAISON),
|
||||||
CONTENEUR_PANIER: mustGetEleInDocument<HTMLElement>(SELECTEUR_CONTENEUR_PANIER),
|
CONTENEUR_PANIER: mustGetEleInDocument<HTMLElement>(DOM_CONTENEUR_PANIER),
|
||||||
ENSEMBLE_CODE_PROMO: mustGetEleInDocument<HTMLFormElement>(SELECTEUR_ENSEMBLE_CODE_PROMO),
|
ENSEMBLE_CODE_PROMO: mustGetEleInDocument<HTMLFormElement>(DOM_ENSEMBLE_CODE_PROMO),
|
||||||
ENTREES_PANIER: recupereElementsDocumentEither<HTMLElement>(
|
ENTREES_PANIER: recupereElementsDocumentEither<HTMLElement>(
|
||||||
SELECTEUR_ENTREES_PANIER,
|
DOM_ENTREES_PANIER,
|
||||||
),
|
),
|
||||||
FORMULAIRE_FACTURATION: mustGetEleInDocument<HTMLDivElement>(SELECTEUR_FORMULAIRE_FACTURATION),
|
FORMULAIRE_FACTURATION: mustGetEleInDocument<HTMLDivElement>(DOM_FORMULAIRE_FACTURATION),
|
||||||
FORMULAIRE_PANIER: mustGetEleInDocument<HTMLFormElement>(SELECTEUR_FORMULAIRE_PANIER),
|
FORMULAIRE_PANIER: mustGetEleInDocument<HTMLFormElement>(DOM_FORMULAIRE_PANIER),
|
||||||
INSTRUCTIONS_CLIENT: mustGetEleInDocument<HTMLTextAreaElement>(SELECTEUR_INSTRUCTIONS_CLIENT),
|
INSTRUCTIONS_CLIENT: mustGetEleInDocument<HTMLTextAreaElement>(DOM_INSTRUCTIONS_CLIENT),
|
||||||
MESSAGE_ADRESSES: mustGetEleInDocument<HTMLParagraphElement>(SELECTEUR_MESSAGE_FORMULAIRE_ADRESSES),
|
MESSAGE_ADRESSES: mustGetEleInDocument<HTMLParagraphElement>(DOM_MESSAGE_FORMULAIRE_ADRESSES),
|
||||||
MESSAGE_CODE_PROMO: mustGetEleInDocument<HTMLParagraphElement>(SELECTEUR_MESSAGE_CODE_PROMO),
|
MESSAGE_CODE_PROMO: mustGetEleInDocument<HTMLParagraphElement>(DOM_MESSAGE_CODE_PROMO),
|
||||||
SOUS_TOTAL_LIVRAISON_VALEUR: mustGetEleInDocument<HTMLElement>(SELECTEUR_SOUS_TOTAL_LIVRAISON_COUT),
|
SOUS_TOTAL_LIVRAISON_VALEUR: mustGetEleInDocument<HTMLElement>(DOM_SOUS_TOTAL_LIVRAISON_COUT),
|
||||||
SOUS_TOTAL_PRODUITS: mustGetEleInDocument<HTMLElement>(SELECTEUR_SOUS_TOTAL_PRODUITS),
|
SOUS_TOTAL_PRODUITS: mustGetEleInDocument<HTMLElement>(DOM_SOUS_TOTAL_PRODUITS),
|
||||||
SOUS_TOTAL_PRODUITS_VALEUR: mustGetEleInDocument<HTMLElement>(SELECTEUR_SOUS_TOTAL_PRODUITS),
|
SOUS_TOTAL_PRODUITS_VALEUR: mustGetEleInDocument<HTMLElement>(DOM_SOUS_TOTAL_PRODUITS),
|
||||||
SOUS_TOTAL_REDUCTION: mustGetEleInDocument<HTMLSpanElement>(SELECTEUR_TOTAL_REDUCTION_VALEUR),
|
SOUS_TOTAL_REDUCTION: mustGetEleInDocument<HTMLSpanElement>(DOM_TOTAL_REDUCTION_VALEUR),
|
||||||
SOUS_TOTAL_REDUCTION_VALEUR: mustGetEleInDocument<HTMLSpanElement>(SELECTEUR_TOTAL_REDUCTION_VALEUR),
|
SOUS_TOTAL_REDUCTION_VALEUR: mustGetEleInDocument<HTMLSpanElement>(DOM_TOTAL_REDUCTION_VALEUR),
|
||||||
TOTAL_PANIER: mustGetEleInDocument<HTMLParagraphElement>(SELECTEUR_TOTAL_PANIER),
|
TOTAL_PANIER: mustGetEleInDocument<HTMLParagraphElement>(DOM_TOTAL_PANIER),
|
||||||
TOTAL_PANIER_VALEUR: mustGetEleInDocument<HTMLSpanElement>(SELECTEUR_TOTAL_PANIER),
|
TOTAL_PANIER_VALEUR: mustGetEleInDocument<HTMLSpanElement>(DOM_TOTAL_PANIER),
|
||||||
TOTAL_REDUCTION_LIGNE: mustGetEleInDocument<HTMLDivElement>(SELECTEUR_TOTAL_REDUCTION),
|
TOTAL_REDUCTION_LIGNE: mustGetEleInDocument<HTMLDivElement>(DOM_TOTAL_REDUCTION),
|
||||||
TOTAL_REDUCTION_VALEUR: mustGetEleInDocument<HTMLSpanElement>(SELECTEUR_TOTAL_REDUCTION_VALEUR),
|
TOTAL_REDUCTION_VALEUR: mustGetEleInDocument<HTMLSpanElement>(DOM_TOTAL_REDUCTION_VALEUR),
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@ import { ADRESSES_MAJ, CODE_PROMO_MAJ, SHIPPING_RATES_UPDATED, TOTALS_UPDATED }
|
||||||
import { reporteEtJournaliseErreur } from "../lib/erreurs";
|
import { reporteEtJournaliseErreur } from "../lib/erreurs";
|
||||||
import { formateEnEuros } from "../lib/nombres";
|
import { formateEnEuros } from "../lib/nombres";
|
||||||
import { eitherSetSessionStorage } from "../lib/session-storage";
|
import { eitherSetSessionStorage } from "../lib/session-storage";
|
||||||
import { logger } from "../logging";
|
import { logger } from "../journalisation.ts";
|
||||||
import { E } from "./scripts-page-panier-elements";
|
import { E } from "./scripts-page-panier-elements";
|
||||||
import { generateShippingRatesHTML } from "./scripts-page-panier-methodes-livraison";
|
import { generateShippingRatesHTML } from "./scripts-page-panier-methodes-livraison";
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,7 @@ import { formateEnEuros } from "../lib/nombres";
|
||||||
import { find } from "../lib/safe-arrays";
|
import { find } from "../lib/safe-arrays";
|
||||||
import { WCStoreCartTotalsSchema } from "../lib/schemas/api/cart";
|
import { WCStoreCartTotalsSchema } from "../lib/schemas/api/cart";
|
||||||
import { getSessionStorageByKey } from "../lib/session-storage";
|
import { getSessionStorageByKey } from "../lib/session-storage";
|
||||||
import { logger } from "../logging";
|
import { logger } from "../journalisation.ts";
|
||||||
import { E } from "./scripts-page-panier-elements";
|
import { E } from "./scripts-page-panier-elements";
|
||||||
import { getShippingRatesLS } from "./scripts-page-panier-local-storage";
|
import { getShippingRatesLS } from "./scripts-page-panier-local-storage";
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -16,10 +16,10 @@ import { ROUTE_API_MAJ_ARTICLE_PANIER, ROUTE_API_RETIRE_ARTICLE_PANIER } from ".
|
||||||
import {
|
import {
|
||||||
ATTRIBUT_CLE_PANIER,
|
ATTRIBUT_CLE_PANIER,
|
||||||
ATTRIBUT_DESACTIVE,
|
ATTRIBUT_DESACTIVE,
|
||||||
SELECTEUR_BOUTON_ADDITION_QUANTITE,
|
DOM_BOUTON_ADDITION_QUANTITE,
|
||||||
SELECTEUR_BOUTON_SOUSTRACTION_QUANTITE,
|
DOM_BOUTON_SOUSTRACTION_QUANTITE,
|
||||||
SELECTEUR_BOUTON_SUPPRESSION_PANIER,
|
DOM_BOUTON_SUPPRESSION_PANIER,
|
||||||
SELECTEUR_CHAMP_QUANTITE_LIGNE_PANIER,
|
DOM_CHAMP_QUANTITE_LIGNE_PANIER,
|
||||||
} from "../constantes/dom";
|
} from "../constantes/dom";
|
||||||
import { NOM_CANAL_REVALIDATION_LIVRAISON } from "../constantes/messages";
|
import { NOM_CANAL_REVALIDATION_LIVRAISON } from "../constantes/messages";
|
||||||
import { mustGetEleInParent } from "../lib/dom";
|
import { mustGetEleInParent } from "../lib/dom";
|
||||||
|
|
@ -51,10 +51,10 @@ type CartEntryInteractiveElements = {
|
||||||
const getCartEntryInteractiveEles = (entree: HTMLElement): CartEntryInteractiveElements => {
|
const getCartEntryInteractiveEles = (entree: HTMLElement): CartEntryInteractiveElements => {
|
||||||
const mustGetEle = mustGetEleInParent(entree);
|
const mustGetEle = mustGetEleInParent(entree);
|
||||||
return {
|
return {
|
||||||
additionButton: mustGetEle<HTMLButtonElement>(SELECTEUR_BOUTON_ADDITION_QUANTITE),
|
additionButton: mustGetEle<HTMLButtonElement>(DOM_BOUTON_ADDITION_QUANTITE),
|
||||||
deletionButton: mustGetEle<HTMLButtonElement>(SELECTEUR_BOUTON_SUPPRESSION_PANIER),
|
deletionButton: mustGetEle<HTMLButtonElement>(DOM_BOUTON_SUPPRESSION_PANIER),
|
||||||
quantityInput: mustGetEle<HTMLInputElement>(SELECTEUR_CHAMP_QUANTITE_LIGNE_PANIER),
|
quantityInput: mustGetEle<HTMLInputElement>(DOM_CHAMP_QUANTITE_LIGNE_PANIER),
|
||||||
substractionButton: mustGetEle<HTMLButtonElement>(SELECTEUR_BOUTON_SOUSTRACTION_QUANTITE),
|
substractionButton: mustGetEle<HTMLButtonElement>(DOM_BOUTON_SOUSTRACTION_QUANTITE),
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -102,7 +102,7 @@ export const initialiseActionsEntreesPanier = (): void => {
|
||||||
.with(P.nullish, () => console.error(event.target))
|
.with(P.nullish, () => console.error(event.target))
|
||||||
// Clic sur le Bouton d'addition
|
// Clic sur le Bouton d'addition
|
||||||
.when(
|
.when(
|
||||||
(target: EventTarget) => (target as HTMLElement).matches(SELECTEUR_BOUTON_ADDITION_QUANTITE),
|
(target: EventTarget) => (target as HTMLElement).matches(DOM_BOUTON_ADDITION_QUANTITE),
|
||||||
(): void => {
|
(): void => {
|
||||||
void EitherAsync
|
void EitherAsync
|
||||||
.liftEither(
|
.liftEither(
|
||||||
|
|
@ -174,7 +174,7 @@ export const initialiseActionsEntreesPanier = (): void => {
|
||||||
)
|
)
|
||||||
// Bouton de soustraction
|
// Bouton de soustraction
|
||||||
.when(
|
.when(
|
||||||
(cible: EventTarget) => (cible as HTMLElement).matches(SELECTEUR_BOUTON_SOUSTRACTION_QUANTITE),
|
(cible: EventTarget) => (cible as HTMLElement).matches(DOM_BOUTON_SOUSTRACTION_QUANTITE),
|
||||||
(): void => {
|
(): void => {
|
||||||
Maybe
|
Maybe
|
||||||
// Nécessaire pour que l'on ait une valeur à incrémenter
|
// Nécessaire pour que l'on ait une valeur à incrémenter
|
||||||
|
|
@ -258,7 +258,7 @@ export const initialiseActionsEntreesPanier = (): void => {
|
||||||
)
|
)
|
||||||
// Bouton de suppression
|
// Bouton de suppression
|
||||||
.when(
|
.when(
|
||||||
(cible: EventTarget) => (cible as HTMLElement).matches(SELECTEUR_BOUTON_SUPPRESSION_PANIER),
|
(cible: EventTarget) => (cible as HTMLElement).matches(DOM_BOUTON_SUPPRESSION_PANIER),
|
||||||
(): void => {
|
(): void => {
|
||||||
Maybe
|
Maybe
|
||||||
// TODO: Pourquoi ?
|
// TODO: Pourquoi ?
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@
|
||||||
|
|
||||||
import type { MessageMajBoutonPanier } from "./lib/types/messages";
|
import type { MessageMajBoutonPanier } from "./lib/types/messages";
|
||||||
|
|
||||||
import { ATTRIBUT_CONTIENT_ARTICLES, SELECTEUR_BOUTON_PANIER } from "./constantes/dom.ts";
|
import { ATTRIBUT_CONTIENT_ARTICLES, DOM_BOUTON_PANIER } from "./constantes/dom.ts";
|
||||||
import { NOM_CANAL_BOUTON_PANIER } from "./constantes/messages.ts";
|
import { NOM_CANAL_BOUTON_PANIER } from "./constantes/messages.ts";
|
||||||
import { mustGetEleInDocument } from "./lib/dom.ts";
|
import { mustGetEleInDocument } from "./lib/dom.ts";
|
||||||
import { valideMessageMajBoutonPanier } from "./lib/messages.ts";
|
import { valideMessageMajBoutonPanier } from "./lib/messages.ts";
|
||||||
|
|
@ -16,7 +16,7 @@ import { valideMessageMajBoutonPanier } from "./lib/messages.ts";
|
||||||
*/
|
*/
|
||||||
const initialiseBoutonPanier = (): void => {
|
const initialiseBoutonPanier = (): void => {
|
||||||
/** Le « Bouton » vers le Panier avec un indicateur de la quantité de Produits ajoutés. */
|
/** Le « Bouton » vers le Panier avec un indicateur de la quantité de Produits ajoutés. */
|
||||||
const BOUTON_PANIER: HTMLAnchorElement = mustGetEleInDocument<HTMLAnchorElement>(SELECTEUR_BOUTON_PANIER);
|
const BOUTON_PANIER: HTMLAnchorElement = mustGetEleInDocument<HTMLAnchorElement>(DOM_BOUTON_PANIER);
|
||||||
const CANAL_BOUTON_PANIER: BroadcastChannel = new BroadcastChannel(NOM_CANAL_BOUTON_PANIER);
|
const CANAL_BOUTON_PANIER: BroadcastChannel = new BroadcastChannel(NOM_CANAL_BOUTON_PANIER);
|
||||||
|
|
||||||
CANAL_BOUTON_PANIER.onmessage = (evenementMessage: MessageEvent<unknown>): void => {
|
CANAL_BOUTON_PANIER.onmessage = (evenementMessage: MessageEvent<unknown>): void => {
|
||||||
|
|
|
||||||
|
|
@ -4,16 +4,11 @@ import { pipe } from "@mobily/ts-belt";
|
||||||
import { head as arrayHead } from "@mobily/ts-belt/Array";
|
import { head as arrayHead } from "@mobily/ts-belt/Array";
|
||||||
import { tap as optionTap } from "@mobily/ts-belt/Option";
|
import { tap as optionTap } from "@mobily/ts-belt/Option";
|
||||||
|
|
||||||
import {
|
import { ATTRIBUT_ACTIF, ATTRIBUT_ARIA_HIDDEN, ATTRIBUT_TABINDEX, DOM_BOUTON_MENU_MOBILE } from "./constantes/dom";
|
||||||
ATTRIBUT_ACTIF,
|
|
||||||
ATTRIBUT_ARIA_HIDDEN,
|
|
||||||
ATTRIBUT_TABINDEX,
|
|
||||||
SELECTEUR_BOUTON_MENU_MOBILE,
|
|
||||||
} from "./constantes/dom";
|
|
||||||
import { mustGetEleInDocument } from "./lib/dom";
|
import { mustGetEleInDocument } from "./lib/dom";
|
||||||
|
|
||||||
const E = {
|
const E = {
|
||||||
BOUTON_MENU_MOBILE: mustGetEleInDocument<HTMLButtonElement>(SELECTEUR_BOUTON_MENU_MOBILE),
|
BOUTON_MENU_MOBILE: mustGetEleInDocument<HTMLButtonElement>(DOM_BOUTON_MENU_MOBILE),
|
||||||
BOUTON_RETOUR_SOMMET: mustGetEleInDocument<HTMLButtonElement>("#bouton-retour-haut"),
|
BOUTON_RETOUR_SOMMET: mustGetEleInDocument<HTMLButtonElement>("#bouton-retour-haut"),
|
||||||
CORPS_HTML: mustGetEleInDocument<HTMLBodyElement>("body"),
|
CORPS_HTML: mustGetEleInDocument<HTMLBodyElement>("body"),
|
||||||
IMAGE_BOUTON: mustGetEleInDocument<HTMLImageElement>("#bouton-retour-haut img"),
|
IMAGE_BOUTON: mustGetEleInDocument<HTMLImageElement>("#bouton-retour-haut img"),
|
||||||
|
|
|
||||||
|
|
@ -3,13 +3,13 @@
|
||||||
import { A } from "@mobily/ts-belt";
|
import { A } from "@mobily/ts-belt";
|
||||||
import { match } from "ts-pattern";
|
import { match } from "ts-pattern";
|
||||||
|
|
||||||
import { SELECTEUR_ENTREE_MENU_CATEGORIES_PRODUITS, SELECTEUR_MENU_CATEGORIES_PRODUITS } from "./constantes/dom.ts";
|
import { DOM_ENTREE_MENU_CATEGORIES_PRODUITS, DOM_MENU_CATEGORIES_PRODUITS } from "./constantes/dom.ts";
|
||||||
import { mustGetEleInDocument, mustGetElesInDocument } from "./lib/dom.ts";
|
import { mustGetEleInDocument, mustGetElesInDocument } from "./lib/dom.ts";
|
||||||
|
|
||||||
document.addEventListener("DOMContentLoaded", (): void => {
|
document.addEventListener("DOMContentLoaded", (): void => {
|
||||||
const MENU_CATEGORIES_PRODUITS: HTMLElement = mustGetEleInDocument(SELECTEUR_MENU_CATEGORIES_PRODUITS);
|
const MENU_CATEGORIES_PRODUITS: HTMLElement = mustGetEleInDocument(DOM_MENU_CATEGORIES_PRODUITS);
|
||||||
const ENTREES_MENU_CATEGORIES_PRODUITS: Array<HTMLAnchorElement> = mustGetElesInDocument(
|
const ENTREES_MENU_CATEGORIES_PRODUITS: Array<HTMLAnchorElement> = mustGetElesInDocument(
|
||||||
SELECTEUR_ENTREE_MENU_CATEGORIES_PRODUITS,
|
DOM_ENTREE_MENU_CATEGORIES_PRODUITS,
|
||||||
);
|
);
|
||||||
|
|
||||||
A.forEachWithIndex(
|
A.forEachWithIndex(
|
||||||
|
|
|
||||||
|
|
@ -5,14 +5,14 @@
|
||||||
import { A, O, pipe } from "@mobily/ts-belt";
|
import { A, O, pipe } from "@mobily/ts-belt";
|
||||||
import A11yDialog from "a11y-dialog";
|
import A11yDialog from "a11y-dialog";
|
||||||
|
|
||||||
import { ATTRIBUT_MENU_MOBILE_ACTIVE, SELECTEUR_BOUTON_MENU_MOBILE, SELECTEUR_MENU_MOBILE } from "./constantes/dom.ts";
|
import { ATTRIBUT_MENU_MOBILE_ACTIVE, DOM_BOUTON_MENU_MOBILE, DOM_MENU_MOBILE } from "./constantes/dom.ts";
|
||||||
import { mustGetEleInDocument } from "./lib/dom.ts";
|
import { mustGetEleInDocument } from "./lib/dom.ts";
|
||||||
|
|
||||||
// Éléments d'intérêt
|
// Éléments d'intérêt
|
||||||
const E = {
|
const E = {
|
||||||
BOUTON_MENU_MOBILE: mustGetEleInDocument<HTMLButtonElement>(SELECTEUR_BOUTON_MENU_MOBILE),
|
BOUTON_MENU_MOBILE: mustGetEleInDocument<HTMLButtonElement>(DOM_BOUTON_MENU_MOBILE),
|
||||||
CORPS_HTML: mustGetEleInDocument<HTMLBodyElement>("body"),
|
CORPS_HTML: mustGetEleInDocument<HTMLBodyElement>("body"),
|
||||||
MENU_MOBILE: mustGetEleInDocument<HTMLDivElement>(SELECTEUR_MENU_MOBILE),
|
MENU_MOBILE: mustGetEleInDocument<HTMLDivElement>(DOM_MENU_MOBILE),
|
||||||
};
|
};
|
||||||
|
|
||||||
const initialiseBoutonMenuMobile = (): void => {
|
const initialiseBoutonMenuMobile = (): void => {
|
||||||
|
|
|
||||||
|
|
@ -9,20 +9,20 @@ import {
|
||||||
ATTRIBUT_ID_ENSEMBLE_EPINGLE_BOITE,
|
ATTRIBUT_ID_ENSEMBLE_EPINGLE_BOITE,
|
||||||
CLASS_BOUTON_FERMETURE_BOITE_TEXTE,
|
CLASS_BOUTON_FERMETURE_BOITE_TEXTE,
|
||||||
CLASS_EPINGLE,
|
CLASS_EPINGLE,
|
||||||
SELECTEUR_BOITE_TEXTE,
|
DOM_BOITE_TEXTE,
|
||||||
SELECTEUR_CONTENEUR_STORYTELLING_A_PROPOS,
|
DOM_CONTENEUR_STORYTELLING_A_PROPOS,
|
||||||
SELECTEUR_EPINGLE,
|
DOM_EPINGLE,
|
||||||
} from "./constantes/dom.ts";
|
} from "./constantes/dom.ts";
|
||||||
import { mustGetEleInDocument, mustGetElesInDocument } from "./lib/dom.ts";
|
import { mustGetEleInDocument, mustGetElesInDocument } from "./lib/dom.ts";
|
||||||
|
|
||||||
/** Le Conteneur des images du storytelling. */
|
/** Le Conteneur des images du storytelling. */
|
||||||
const CONTENEUR_STORYTELLING = mustGetEleInDocument<HTMLElement>(
|
const CONTENEUR_STORYTELLING = mustGetEleInDocument<HTMLElement>(
|
||||||
SELECTEUR_CONTENEUR_STORYTELLING_A_PROPOS,
|
DOM_CONTENEUR_STORYTELLING_A_PROPOS,
|
||||||
);
|
);
|
||||||
/** */
|
/** */
|
||||||
const EPINGLES = mustGetElesInDocument<HTMLButtonElement>(SELECTEUR_EPINGLE);
|
const EPINGLES = mustGetElesInDocument<HTMLButtonElement>(DOM_EPINGLE);
|
||||||
/** */
|
/** */
|
||||||
const BOITES_TEXTE = mustGetElesInDocument<HTMLDivElement>(SELECTEUR_BOITE_TEXTE);
|
const BOITES_TEXTE = mustGetElesInDocument<HTMLDivElement>(DOM_BOITE_TEXTE);
|
||||||
/** */
|
/** */
|
||||||
const ENSEMBLES_EPINGLES_BOITES_TEXTE = new Map<string, [HTMLButtonElement, HTMLDivElement]>();
|
const ENSEMBLES_EPINGLES_BOITES_TEXTE = new Map<string, [HTMLButtonElement, HTMLDivElement]>();
|
||||||
A.forEachWithIndex(EPINGLES, (index, epingle) => {
|
A.forEachWithIndex(EPINGLES, (index, epingle) => {
|
||||||
|
|
|
||||||
|
|
@ -3,78 +3,131 @@
|
||||||
import { A, O, pipe } from "@mobily/ts-belt";
|
import { A, O, pipe } from "@mobily/ts-belt";
|
||||||
|
|
||||||
import {
|
import {
|
||||||
ATTRIBUT_ARIA_HIDDEN,
|
ATTRIBUT_CACHÉ,
|
||||||
ATTRIBUT_CACHE,
|
ATTRIBUT_HIDDEN,
|
||||||
SELECTEUR_CONTENEUR_STORYTELLING,
|
DOM_CONTENEUR_ANIMATION,
|
||||||
SELECTEUR_IMAGES_STORYTELLING,
|
DOM_CONTENEUR_STORYTELLING,
|
||||||
|
DOM_GARDE_FOU_JS,
|
||||||
|
DOM_IMAGES_STORYTELLING,
|
||||||
} from "./constantes/dom.ts";
|
} from "./constantes/dom.ts";
|
||||||
|
import { nuLogger } from "./journalisation.ts";
|
||||||
import { mustGetEleInDocument, mustGetElesInDocument } from "./lib/dom.ts";
|
import { mustGetEleInDocument, mustGetElesInDocument } from "./lib/dom.ts";
|
||||||
import { estEntreDeuxNombres } from "./lib/nombres.ts";
|
import { estEntreDeuxNombres } from "./lib/nombres.ts";
|
||||||
|
|
||||||
const initialiseScrollStorytelling = (): void => {
|
const E = {
|
||||||
const E = {
|
/** Le bloc contenant l'animation. */
|
||||||
/** Le conteneur des images du storytelling. */
|
CONTENEUR_ANIMATION: mustGetEleInDocument<HTMLDivElement>(DOM_CONTENEUR_ANIMATION),
|
||||||
CONTENEUR_STORYTELLING: mustGetEleInDocument<HTMLElement>(".storytelling__conteneur"),
|
/** Le conteneur des images du storytelling. */
|
||||||
/** Les images du storytelling. */
|
CONTENEUR_STORYTELLING: mustGetEleInDocument<HTMLElement>(".storytelling__conteneur"),
|
||||||
IMAGES_STORYTELLING: mustGetElesInDocument<HTMLDivElement>(SELECTEUR_IMAGES_STORYTELLING),
|
/** Les images du storytelling. */
|
||||||
/** Le bloc contenant le storytelling. */
|
IMAGES_STORYTELLING: mustGetElesInDocument<HTMLDivElement>(DOM_IMAGES_STORYTELLING),
|
||||||
STORYTELLING: mustGetEleInDocument<HTMLElement>(SELECTEUR_CONTENEUR_STORYTELLING),
|
/** Le bloc contenant le storytelling. */
|
||||||
};
|
STORYTELLING: mustGetEleInDocument<HTMLElement>(DOM_CONTENEUR_STORYTELLING),
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retire la classe garde-fou `.js` cachant les éléments nécessitant JavaScript pour s'afficher/fonctionner correctement.
|
||||||
|
*/
|
||||||
|
const retireClasseGardeFouJs = (): void => {
|
||||||
|
E.CONTENEUR_ANIMATION.classList.remove(DOM_GARDE_FOU_JS);
|
||||||
|
};
|
||||||
|
|
||||||
|
const initDefilementStorytelling = (): void => {
|
||||||
/** La hauteur d'une image du storytelling. */
|
/** La hauteur d'une image du storytelling. */
|
||||||
let hauteurImage = E.IMAGES_STORYTELLING.at(0)?.getBoundingClientRect().height ?? 0;
|
let dimensionsImage = {
|
||||||
|
height: E.IMAGES_STORYTELLING.at(0)?.getBoundingClientRect().height ?? 0,
|
||||||
|
width: E.IMAGES_STORYTELLING.at(0)?.getBoundingClientRect().width ?? 0,
|
||||||
|
};
|
||||||
/** La position du défilement (en pixels) du Conteneur des images du storytelling. */
|
/** La position du défilement (en pixels) du Conteneur des images du storytelling. */
|
||||||
let positionDefilementConteneur = 0;
|
let positionDefilementConteneur = 0;
|
||||||
|
|
||||||
|
nuLogger.debug`initStorytellingScroll | dimensionsImages ${dimensionsImage.height}`;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* TODO
|
* Bascule la visibilité d'une image en
|
||||||
* @param image
|
* @param image
|
||||||
* @param visible
|
* @param estVisible
|
||||||
*/
|
*/
|
||||||
const changeVisibiliteImage = (image: HTMLDivElement, visible: boolean) => {
|
const basculeVisibilitéImage = (image: HTMLDivElement, estVisible: boolean) => {
|
||||||
image.toggleAttribute(ATTRIBUT_CACHE, visible);
|
image.toggleAttribute(ATTRIBUT_CACHÉ, estVisible);
|
||||||
image.toggleAttribute(ATTRIBUT_ARIA_HIDDEN, visible);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* TODO
|
* TODO
|
||||||
*/
|
*/
|
||||||
const majDimensions = (): void => {
|
const majDimensionsStorytelling = (): void => {
|
||||||
hauteurImage = pipe(
|
dimensionsImage = pipe(
|
||||||
A.getBy(E.IMAGES_STORYTELLING, (i: HTMLDivElement) => !i.hasAttribute(ATTRIBUT_CACHE)),
|
A.getBy(E.IMAGES_STORYTELLING, (i: HTMLDivElement) => !i.hasAttribute(ATTRIBUT_CACHÉ)),
|
||||||
O.map((i: HTMLDivElement) => i.getBoundingClientRect().height),
|
O.map((i: HTMLDivElement) => ({
|
||||||
O.getWithDefault(0),
|
height: i.getBoundingClientRect().height,
|
||||||
|
width: i.getBoundingClientRect().width,
|
||||||
|
})),
|
||||||
|
O.getWithDefault({ height: 0, width: 0 }),
|
||||||
);
|
);
|
||||||
E.CONTENEUR_STORYTELLING.style.minHeight = `${String(hauteurImage * E.IMAGES_STORYTELLING.length + 61)}px`;
|
nuLogger.debug`majDimensions | dimensionsImage ${dimensionsImage}`;
|
||||||
E.CONTENEUR_STORYTELLING.style.maxHeight = `${String(hauteurImage * E.IMAGES_STORYTELLING.length + 61)}px`;
|
|
||||||
|
// Adapte la longueur du conteneur d'animation à la nouvelle longueur d'une image.
|
||||||
|
E.CONTENEUR_ANIMATION.style.inlineSize = `${String(dimensionsImage.width)}px`;
|
||||||
|
|
||||||
|
// Adapte la hauteur du conteneur des images pour un défilement « seamless ».
|
||||||
|
const nouvelleHauteurMax = `${String(dimensionsImage.height * E.IMAGES_STORYTELLING.length + 61)}px`;
|
||||||
|
E.CONTENEUR_STORYTELLING.style.minHeight = nouvelleHauteurMax;
|
||||||
|
E.CONTENEUR_STORYTELLING.style.maxHeight = nouvelleHauteurMax;
|
||||||
|
nuLogger.debug`majDimensions | nouvelleHauteurMax ${nouvelleHauteurMax}`;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* TODO
|
* TODO
|
||||||
*/
|
*/
|
||||||
const majImages = (): void => {
|
const majVisibilitéImagesStorytelling = (): void => {
|
||||||
// Met à jour la position du défilement dans le Conteneur
|
// Met à jour la position du défilement dans le Conteneur.
|
||||||
positionDefilementConteneur = E.STORYTELLING.scrollTop;
|
positionDefilementConteneur = E.STORYTELLING.scrollTop;
|
||||||
|
|
||||||
// Met à jour l'attribut de visibilité des images en fonction du défilement
|
// Met à jour l'attribut de visibilité des images en fonction du défilement.
|
||||||
E.IMAGES_STORYTELLING.forEach((image: HTMLDivElement, index: number): void => {
|
E.IMAGES_STORYTELLING.forEach((image: HTMLDivElement, index: number): void => {
|
||||||
const debutYImage = hauteurImage * index;
|
const debutYImage = dimensionsImage.height * index;
|
||||||
const finYImage = hauteurImage * (index + 1);
|
const finYImage = dimensionsImage.height * (index + 1);
|
||||||
|
|
||||||
changeVisibiliteImage(image, !estEntreDeuxNombres(positionDefilementConteneur, debutYImage, finYImage));
|
basculeVisibilitéImage(image, !estEntreDeuxNombres(positionDefilementConteneur, debutYImage, finYImage));
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
// Initialise l'Observateur de Redimensionnement (ResizeObserver)
|
// Initialise l'Observateur de Redimensionnement (ResizeObserver).
|
||||||
new ResizeObserver((): void => {
|
new ResizeObserver((): void => {
|
||||||
majDimensions();
|
majDimensionsStorytelling();
|
||||||
majImages();
|
majVisibilitéImagesStorytelling();
|
||||||
}).observe(E.STORYTELLING);
|
}).observe(E.STORYTELLING);
|
||||||
|
|
||||||
// Initialise la mise à jour des images au défilement sur le Conteneur
|
// Initialise la mise à jour des images au défilement sur le Conteneur.
|
||||||
E.STORYTELLING.addEventListener("scroll", (): void => majImages());
|
E.STORYTELLING.addEventListener("scroll", (): void => majVisibilitéImagesStorytelling());
|
||||||
|
};
|
||||||
|
|
||||||
|
const initGestionAnimation = (): void => {
|
||||||
|
pipe(
|
||||||
|
A.at(E.IMAGES_STORYTELLING, 0),
|
||||||
|
O.tap(img => {
|
||||||
|
const options: IntersectionObserverInit = {
|
||||||
|
root: null,
|
||||||
|
rootMargin: "0px",
|
||||||
|
threshold: 0,
|
||||||
|
};
|
||||||
|
const callback = (entries: Array<IntersectionObserverEntry>) => {
|
||||||
|
A.forEach(entries, e => {
|
||||||
|
e.intersectionRatio === 1
|
||||||
|
? E.CONTENEUR_ANIMATION.removeAttribute(ATTRIBUT_HIDDEN)
|
||||||
|
: E.CONTENEUR_ANIMATION.setAttribute(ATTRIBUT_HIDDEN, "");
|
||||||
|
|
||||||
|
nuLogger.debug`initGestionAnimation | estCache ${e.intersectionRatio === 1} | ${e}`;
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
new IntersectionObserver(callback, options).observe(img);
|
||||||
|
}),
|
||||||
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
document.addEventListener("DOMContentLoaded", (): void => {
|
document.addEventListener("DOMContentLoaded", (): void => {
|
||||||
initialiseScrollStorytelling();
|
retireClasseGardeFouJs();
|
||||||
|
initDefilementStorytelling();
|
||||||
|
initGestionAnimation();
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -19,8 +19,8 @@ import {
|
||||||
ATTRIBUT_HIDDEN,
|
ATTRIBUT_HIDDEN,
|
||||||
ATTRIBUT_ID_CATEGORIE_PRODUITS,
|
ATTRIBUT_ID_CATEGORIE_PRODUITS,
|
||||||
ATTRIBUT_PAGE,
|
ATTRIBUT_PAGE,
|
||||||
SELECTEUR_BOUTON_PLUS_PRODUITS,
|
DOM_BOUTON_PLUS_PRODUITS,
|
||||||
SELECTEUR_GRILLE_PRODUITS,
|
DOM_GRILLE_PRODUITS,
|
||||||
} from "./constantes/dom.ts";
|
} from "./constantes/dom.ts";
|
||||||
import { lanceAnimationCycleLoading } from "./lib/animations.ts";
|
import { lanceAnimationCycleLoading } from "./lib/animations.ts";
|
||||||
import { html, mustGetEleInDocument } from "./lib/dom.ts";
|
import { html, mustGetEleInDocument } from "./lib/dom.ts";
|
||||||
|
|
@ -43,8 +43,8 @@ const PRODUCTS_PER_PAGE = 12;
|
||||||
|
|
||||||
// Éléments d'intérêt
|
// Éléments d'intérêt
|
||||||
const E = {
|
const E = {
|
||||||
BOUTON_PLUS_DE_PRODUITS: mustGetEleInDocument<HTMLButtonElement>(SELECTEUR_BOUTON_PLUS_PRODUITS),
|
BOUTON_PLUS_DE_PRODUITS: mustGetEleInDocument<HTMLButtonElement>(DOM_BOUTON_PLUS_PRODUITS),
|
||||||
GRILLE_PRODUITS: mustGetEleInDocument<HTMLDivElement>(SELECTEUR_GRILLE_PRODUITS),
|
GRILLE_PRODUITS: mustGetEleInDocument<HTMLDivElement>(DOM_GRILLE_PRODUITS),
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -13,11 +13,11 @@ import {
|
||||||
ATTRIBUT_CONTIENT_ARTICLES,
|
ATTRIBUT_CONTIENT_ARTICLES,
|
||||||
ATTRIBUT_DESACTIVE,
|
ATTRIBUT_DESACTIVE,
|
||||||
ATTRIBUT_HIDDEN,
|
ATTRIBUT_HIDDEN,
|
||||||
SELECTEUR_BOUTON_ADDITION_QUANTITE,
|
DOM_BOUTON_ADDITION_QUANTITE,
|
||||||
SELECTEUR_BOUTON_SOUSTRACTION_QUANTITE,
|
DOM_BOUTON_SOUSTRACTION_QUANTITE,
|
||||||
SELECTEUR_BOUTON_SUPPRESSION_PANIER,
|
DOM_BOUTON_SUPPRESSION_PANIER,
|
||||||
SELECTEUR_CHAMP_QUANTITE_LIGNE_PANIER,
|
DOM_CHAMP_QUANTITE_LIGNE_PANIER,
|
||||||
SELECTEUR_PRIX_LIGNE_PANIER,
|
DOM_PRIX_LIGNE_PANIER,
|
||||||
} from "./constantes/dom.ts";
|
} from "./constantes/dom.ts";
|
||||||
import { NOM_CANAL_BOUTON_PANIER, NOM_CANAL_CONTENU_PANIER } from "./constantes/messages.ts";
|
import { NOM_CANAL_BOUTON_PANIER, NOM_CANAL_CONTENU_PANIER } from "./constantes/messages.ts";
|
||||||
import { getDOMElementsWithSelector, recupereElementAvecSelecteur, recupereElementOuLeve } from "./lib/dom.ts";
|
import { getDOMElementsWithSelector, recupereElementAvecSelecteur, recupereElementOuLeve } from "./lib/dom.ts";
|
||||||
|
|
@ -73,10 +73,10 @@ const majEtatsActivationBoutons = (entrees: Array<HTMLElement>): void =>
|
||||||
const recupereElementDansEntree = recupereElementDansEntreePanierOuLeve(entree);
|
const recupereElementDansEntree = recupereElementDansEntreePanierOuLeve(entree);
|
||||||
|
|
||||||
const elements: ElementsEntreePanier = {
|
const elements: ElementsEntreePanier = {
|
||||||
boutonAddition: recupereElementDansEntree<HTMLButtonElement>(SELECTEUR_BOUTON_ADDITION_QUANTITE),
|
boutonAddition: recupereElementDansEntree<HTMLButtonElement>(DOM_BOUTON_ADDITION_QUANTITE),
|
||||||
boutonSoustraction: recupereElementDansEntree<HTMLButtonElement>(SELECTEUR_BOUTON_SOUSTRACTION_QUANTITE),
|
boutonSoustraction: recupereElementDansEntree<HTMLButtonElement>(DOM_BOUTON_SOUSTRACTION_QUANTITE),
|
||||||
boutonSuppression: recupereElementDansEntree<HTMLButtonElement>(SELECTEUR_BOUTON_SUPPRESSION_PANIER),
|
boutonSuppression: recupereElementDansEntree<HTMLButtonElement>(DOM_BOUTON_SUPPRESSION_PANIER),
|
||||||
champQuantite: recupereElementDansEntree<HTMLInputElement>(SELECTEUR_CHAMP_QUANTITE_LIGNE_PANIER),
|
champQuantite: recupereElementDansEntree<HTMLInputElement>(DOM_CHAMP_QUANTITE_LIGNE_PANIER),
|
||||||
};
|
};
|
||||||
|
|
||||||
Number(elements.champQuantite?.value) === 1
|
Number(elements.champQuantite?.value) === 1
|
||||||
|
|
@ -115,9 +115,9 @@ const initialiseMajContenuPanier = (): void => {
|
||||||
const recupereElementDansEntree = recupereElementDansEntreePanierOuLeve(entree);
|
const recupereElementDansEntree = recupereElementDansEntreePanierOuLeve(entree);
|
||||||
|
|
||||||
// Récupère les Éléments à mettre à jour
|
// Récupère les Éléments à mettre à jour
|
||||||
const prixLigne = recupereElementDansEntree<HTMLSpanElement>(SELECTEUR_PRIX_LIGNE_PANIER);
|
const prixLigne = recupereElementDansEntree<HTMLSpanElement>(DOM_PRIX_LIGNE_PANIER);
|
||||||
const champQuantite = recupereElementDansEntree<HTMLInputElement>(
|
const champQuantite = recupereElementDansEntree<HTMLInputElement>(
|
||||||
SELECTEUR_CHAMP_QUANTITE_LIGNE_PANIER,
|
DOM_CHAMP_QUANTITE_LIGNE_PANIER,
|
||||||
);
|
);
|
||||||
|
|
||||||
// Met à jour les valeurs
|
// Met à jour les valeurs
|
||||||
|
|
|
||||||
|
|
@ -20,11 +20,11 @@ import {
|
||||||
ATTRIBUT_DESACTIVE,
|
ATTRIBUT_DESACTIVE,
|
||||||
ATTRIBUT_HIDDEN,
|
ATTRIBUT_HIDDEN,
|
||||||
ATTRIBUT_PRIX,
|
ATTRIBUT_PRIX,
|
||||||
SELECTEUR_BOUTON_AJOUT_PANIER,
|
DOM_BOUTON_AJOUT_PANIER,
|
||||||
SELECTEUR_BOUTONS_ACCORDEON,
|
DOM_BOUTONS_ACCORDEON,
|
||||||
SELECTEUR_CONTENUS_ACCORDEON,
|
DOM_CONTENUS_ACCORDEON,
|
||||||
SELECTEUR_PRIX_PRODUIT,
|
DOM_PRIX_PRODUIT,
|
||||||
SELECTEUR_SELECTEUR_QUANTITE,
|
DOM_DOM_QUANTITE,
|
||||||
} from "./constantes/dom.ts";
|
} from "./constantes/dom.ts";
|
||||||
import { lanceAnimationCycleLoading } from "./lib/animations.ts";
|
import { lanceAnimationCycleLoading } from "./lib/animations.ts";
|
||||||
import { mustGetEleInDocument, mustGetElesInDocument, recupereElementDocumentEither } from "./lib/dom.ts";
|
import { mustGetEleInDocument, mustGetElesInDocument, recupereElementDocumentEither } from "./lib/dom.ts";
|
||||||
|
|
@ -61,11 +61,11 @@ const deplieToutesSections = (ensembleLiensContenus: Array<EnsembleLienContenu>)
|
||||||
|
|
||||||
// Éléments d'intérêt
|
// Éléments d'intérêt
|
||||||
const E = {
|
const E = {
|
||||||
BOUTON_AJOUT_PANIER: mustGetEleInDocument<HTMLButtonElement>(SELECTEUR_BOUTON_AJOUT_PANIER),
|
BOUTON_AJOUT_PANIER: mustGetEleInDocument<HTMLButtonElement>(DOM_BOUTON_AJOUT_PANIER),
|
||||||
BOUTONS_ACCORDEON: mustGetElesInDocument<HTMLAnchorElement>(SELECTEUR_BOUTONS_ACCORDEON),
|
BOUTONS_ACCORDEON: mustGetElesInDocument<HTMLAnchorElement>(DOM_BOUTONS_ACCORDEON),
|
||||||
CONTENUS_ACCORDEON: mustGetElesInDocument<HTMLDivElement>(SELECTEUR_CONTENUS_ACCORDEON),
|
CONTENUS_ACCORDEON: mustGetElesInDocument<HTMLDivElement>(DOM_CONTENUS_ACCORDEON),
|
||||||
PRIX_PRODUIT: mustGetEleInDocument<HTMLParagraphElement>(SELECTEUR_PRIX_PRODUIT),
|
PRIX_PRODUIT: mustGetEleInDocument<HTMLParagraphElement>(DOM_PRIX_PRODUIT),
|
||||||
SELECTEUR_VARIATION: recupereElementDocumentEither<HTMLSelectElement>(SELECTEUR_SELECTEUR_QUANTITE),
|
DOM_VARIATION: recupereElementDocumentEither<HTMLSelectElement>(DOM_DOM_QUANTITE),
|
||||||
};
|
};
|
||||||
|
|
||||||
const gereAccordeonDetailsProduit = (): void => {
|
const gereAccordeonDetailsProduit = (): void => {
|
||||||
|
|
@ -99,7 +99,7 @@ const gereAccordeonDetailsProduit = (): void => {
|
||||||
});
|
});
|
||||||
|
|
||||||
// Ajoute des Écouteurs d'Événements
|
// Ajoute des Écouteurs d'Événements
|
||||||
E.SELECTEUR_VARIATION.ifRight((selecteur): void =>
|
E.DOM_VARIATION.ifRight((selecteur): void =>
|
||||||
selecteur.addEventListener("change", (evenement: Event): void => {
|
selecteur.addEventListener("change", (evenement: Event): void => {
|
||||||
const cibleSelecteur: Maybe<HTMLSelectElement> = Maybe
|
const cibleSelecteur: Maybe<HTMLSelectElement> = Maybe
|
||||||
.fromNullable(evenement.target)
|
.fromNullable(evenement.target)
|
||||||
|
|
@ -125,7 +125,7 @@ const gereAccordeonDetailsProduit = (): void => {
|
||||||
const ajouteProduitAuPanier = (): void => {
|
const ajouteProduitAuPanier = (): void => {
|
||||||
// Construis les arguments de la requête au backend
|
// Construis les arguments de la requête au backend
|
||||||
const argsRequete: WCStoreCartAddItemArgs = {
|
const argsRequete: WCStoreCartAddItemArgs = {
|
||||||
id: E.SELECTEUR_VARIATION
|
id: E.DOM_VARIATION
|
||||||
.map((selecteur: HTMLSelectElement): number => Number(selecteur.value))
|
.map((selecteur: HTMLSelectElement): number => Number(selecteur.value))
|
||||||
// Récupère l'ID du Produit de la Page pour les Produits simples
|
// Récupère l'ID du Produit de la Page pour les Produits simples
|
||||||
.orDefault(ETATS_PAGE.idProduit),
|
.orDefault(ETATS_PAGE.idProduit),
|
||||||
|
|
|
||||||
|
|
@ -2,21 +2,117 @@
|
||||||
{% import "macros/images.twig" as images %}
|
{% import "macros/images.twig" as images %}
|
||||||
|
|
||||||
{% block contenu %}
|
{% block contenu %}
|
||||||
<main id="page-accueil">
|
<main
|
||||||
|
id="page-accueil"
|
||||||
|
aria-label="Scroll down to navigate through the pictures"
|
||||||
|
>
|
||||||
<div class="storytelling">
|
<div class="storytelling">
|
||||||
<div class="storytelling__conteneur">
|
<div
|
||||||
<div
|
aria-hidden="true"
|
||||||
class="storytelling__image"
|
class="storytelling__conteneur"
|
||||||
data-index="0"
|
inert
|
||||||
>
|
>
|
||||||
{{
|
{# Animation #}
|
||||||
images.genere_source_img_multi_formats("#{ site.theme.link }/assets/img/storytelling/scroll0", "", 903, 1080, "image-scroll0")
|
<div class="storytelling__animation no-js">
|
||||||
}}
|
<svg
|
||||||
|
class="animation-conteneur"
|
||||||
|
height="90px"
|
||||||
|
preserveAspectRatio="xMidYMin"
|
||||||
|
viewBox="0 0 1200 90"
|
||||||
|
width="100%"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
>
|
||||||
|
<svg
|
||||||
|
y="50%"
|
||||||
|
class="animation-texte"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
d="m0 0c600-90 600 90 1200 0"
|
||||||
|
fill="transparent"
|
||||||
|
id="curve-1"
|
||||||
|
/>
|
||||||
|
|
||||||
|
{# TODO: Créer une fonction pour générer les images #}
|
||||||
|
<text dominant-baseline="middle">
|
||||||
|
<textPath
|
||||||
|
id="text-path-1"
|
||||||
|
xlink:href="#curve-1"
|
||||||
|
>
|
||||||
|
Scroll down
|
||||||
|
</textPath>
|
||||||
|
<animate
|
||||||
|
attributeName="startOffset"
|
||||||
|
dur="5s"
|
||||||
|
fill="remove"
|
||||||
|
from="-50%"
|
||||||
|
to="0%"
|
||||||
|
repeatCount="indefinite"
|
||||||
|
xlink:href="#text-path-1"
|
||||||
|
/>
|
||||||
|
</text>
|
||||||
|
|
||||||
|
<text dominant-baseline="middle">
|
||||||
|
<textPath
|
||||||
|
id="text-path-2"
|
||||||
|
xlink:href="#curve-1"
|
||||||
|
>
|
||||||
|
Scroll down
|
||||||
|
</textPath>
|
||||||
|
<animate
|
||||||
|
attributeName="startOffset"
|
||||||
|
dur="5s"
|
||||||
|
fill="remove"
|
||||||
|
from="0%"
|
||||||
|
to="50%"
|
||||||
|
repeatCount="indefinite"
|
||||||
|
xlink:href="#text-path-2"
|
||||||
|
/>
|
||||||
|
</text>
|
||||||
|
|
||||||
|
<text dominant-baseline="middle">
|
||||||
|
<textPath
|
||||||
|
id="text-path-3"
|
||||||
|
xlink:href="#curve-1"
|
||||||
|
>
|
||||||
|
Scroll down
|
||||||
|
</textPath>
|
||||||
|
<animate
|
||||||
|
attributeName="startOffset"
|
||||||
|
dur="5s"
|
||||||
|
fill="remove"
|
||||||
|
from="50%"
|
||||||
|
to="100%"
|
||||||
|
repeatCount="indefinite"
|
||||||
|
xlink:href="#text-path-3"
|
||||||
|
/>
|
||||||
|
</text>
|
||||||
|
|
||||||
|
<text dominant-baseline="middle">
|
||||||
|
<textPath
|
||||||
|
id="text-path-4"
|
||||||
|
xlink:href="#curve-1"
|
||||||
|
>
|
||||||
|
Scroll down
|
||||||
|
</textPath>
|
||||||
|
<animate
|
||||||
|
attributeName="startOffset"
|
||||||
|
dur="5s"
|
||||||
|
fill="remove"
|
||||||
|
from="100%"
|
||||||
|
to="150%"
|
||||||
|
repeatCount="indefinite"
|
||||||
|
xlink:href="#text-path-4"
|
||||||
|
/>
|
||||||
|
</text>
|
||||||
|
</svg>
|
||||||
|
</svg>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
{# Images #}
|
||||||
<div
|
<div
|
||||||
class="storytelling__image"
|
class="storytelling__image"
|
||||||
data-index="1"
|
data-index="1"
|
||||||
|
tabindex="-1"
|
||||||
>
|
>
|
||||||
{{
|
{{
|
||||||
images.genere_source_img_multi_formats("#{ site.theme.link }/assets/img/storytelling/scroll1", "", 903, 1080, "image-scroll1")
|
images.genere_source_img_multi_formats("#{ site.theme.link }/assets/img/storytelling/scroll1", "", 903, 1080, "image-scroll1")
|
||||||
|
|
@ -24,10 +120,10 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div
|
<div
|
||||||
aria-hidden
|
|
||||||
class="storytelling__image"
|
class="storytelling__image"
|
||||||
data-cache
|
data-caché
|
||||||
data-index="2"
|
data-index="2"
|
||||||
|
tabindex="-1"
|
||||||
>
|
>
|
||||||
{{
|
{{
|
||||||
images.genere_source_img_multi_formats("#{ site.theme.link }/assets/img/storytelling/scroll2", "", 903, 1080, "image-scroll2")
|
images.genere_source_img_multi_formats("#{ site.theme.link }/assets/img/storytelling/scroll2", "", 903, 1080, "image-scroll2")
|
||||||
|
|
@ -35,10 +131,10 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div
|
<div
|
||||||
aria-hidden
|
|
||||||
class="storytelling__image"
|
class="storytelling__image"
|
||||||
data-cache
|
data-caché
|
||||||
data-index="3"
|
data-index="3"
|
||||||
|
tabindex="-1"
|
||||||
>
|
>
|
||||||
{{
|
{{
|
||||||
images.genere_source_img_multi_formats("#{ site.theme.link }/assets/img/storytelling/scroll3", "", 903, 1080, "image-scroll3")
|
images.genere_source_img_multi_formats("#{ site.theme.link }/assets/img/storytelling/scroll3", "", 903, 1080, "image-scroll3")
|
||||||
|
|
@ -46,10 +142,10 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div
|
<div
|
||||||
aria-hidden
|
|
||||||
class="storytelling__image"
|
class="storytelling__image"
|
||||||
data-cache
|
data-caché
|
||||||
data-index="4"
|
data-index="4"
|
||||||
|
tabindex="-1"
|
||||||
>
|
>
|
||||||
{{
|
{{
|
||||||
images.genere_source_img_multi_formats("#{ site.theme.link }/assets/img/storytelling/scroll4", "", 903, 1080, "image-scroll4")
|
images.genere_source_img_multi_formats("#{ site.theme.link }/assets/img/storytelling/scroll4", "", 903, 1080, "image-scroll4")
|
||||||
|
|
@ -57,10 +153,10 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div
|
<div
|
||||||
aria-hidden
|
|
||||||
class="storytelling__image"
|
class="storytelling__image"
|
||||||
data-cache
|
data-caché
|
||||||
data-index="5"
|
data-index="5"
|
||||||
|
tabindex="-1"
|
||||||
>
|
>
|
||||||
{{
|
{{
|
||||||
images.genere_source_img_multi_formats("#{ site.theme.link }/assets/img/storytelling/scroll5", "", 903, 1080, "image-scroll5")
|
images.genere_source_img_multi_formats("#{ site.theme.link }/assets/img/storytelling/scroll5", "", 903, 1080, "image-scroll5")
|
||||||
|
|
@ -68,10 +164,10 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div
|
<div
|
||||||
aria-hidden
|
|
||||||
class="storytelling__image"
|
class="storytelling__image"
|
||||||
data-cache
|
data-caché
|
||||||
data-index="6"
|
data-index="6"
|
||||||
|
tabindex="-1"
|
||||||
>
|
>
|
||||||
{{
|
{{
|
||||||
images.genere_source_img_multi_formats("#{ site.theme.link }/assets/img/storytelling/scroll6", "", 903, 1080, "image-scroll6")
|
images.genere_source_img_multi_formats("#{ site.theme.link }/assets/img/storytelling/scroll6", "", 903, 1080, "image-scroll6")
|
||||||
|
|
@ -79,10 +175,10 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div
|
<div
|
||||||
aria-hidden
|
|
||||||
class="storytelling__image"
|
class="storytelling__image"
|
||||||
data-cache
|
data-caché
|
||||||
data-index="7"
|
data-index="7"
|
||||||
|
tabindex="-1"
|
||||||
>
|
>
|
||||||
{{
|
{{
|
||||||
images.genere_source_img_multi_formats("#{ site.theme.link }/assets/img/storytelling/scroll7", "", 903, 1080, "image-scroll7")
|
images.genere_source_img_multi_formats("#{ site.theme.link }/assets/img/storytelling/scroll7", "", 903, 1080, "image-scroll7")
|
||||||
|
|
@ -90,10 +186,10 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div
|
<div
|
||||||
aria-hidden
|
|
||||||
class="storytelling__image"
|
class="storytelling__image"
|
||||||
data-cache
|
data-caché
|
||||||
data-index="8"
|
data-index="8"
|
||||||
|
tabindex="-1"
|
||||||
>
|
>
|
||||||
{{
|
{{
|
||||||
images.genere_source_img_multi_formats("#{ site.theme.link }/assets/img/storytelling/scroll8", "", 903, 1080, "image-scroll8")
|
images.genere_source_img_multi_formats("#{ site.theme.link }/assets/img/storytelling/scroll8", "", 903, 1080, "image-scroll8")
|
||||||
|
|
@ -101,10 +197,10 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div
|
<div
|
||||||
aria-hidden
|
|
||||||
class="storytelling__image"
|
class="storytelling__image"
|
||||||
data-cache
|
data-caché
|
||||||
data-index="9"
|
data-index="9"
|
||||||
|
tabindex="-1"
|
||||||
>
|
>
|
||||||
{{
|
{{
|
||||||
images.genere_source_img_multi_formats("#{ site.theme.link }/assets/img/storytelling/scroll9", "", 903, 1080, "image-scroll9")
|
images.genere_source_img_multi_formats("#{ site.theme.link }/assets/img/storytelling/scroll9", "", 903, 1080, "image-scroll9")
|
||||||
|
|
@ -112,10 +208,10 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div
|
<div
|
||||||
aria-hidden
|
|
||||||
class="storytelling__image"
|
class="storytelling__image"
|
||||||
data-cache
|
data-caché
|
||||||
data-index="10"
|
data-index="10"
|
||||||
|
tabindex="-1"
|
||||||
>
|
>
|
||||||
{{
|
{{
|
||||||
images.genere_source_img_multi_formats("#{ site.theme.link }/assets/img/storytelling/scroll10", "", 903, 1080, "image-scroll10")
|
images.genere_source_img_multi_formats("#{ site.theme.link }/assets/img/storytelling/scroll10", "", 903, 1080, "image-scroll10")
|
||||||
|
|
@ -123,10 +219,10 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div
|
<div
|
||||||
aria-hidden
|
|
||||||
class="storytelling__image"
|
class="storytelling__image"
|
||||||
data-cache
|
data-caché
|
||||||
data-index="11"
|
data-index="11"
|
||||||
|
tabindex="-1"
|
||||||
>
|
>
|
||||||
{{
|
{{
|
||||||
images.genere_source_img_multi_formats("#{ site.theme.link }/assets/img/storytelling/scroll11", "", 903, 1080, "image-scroll11")
|
images.genere_source_img_multi_formats("#{ site.theme.link }/assets/img/storytelling/scroll11", "", 903, 1080, "image-scroll11")
|
||||||
|
|
@ -134,10 +230,10 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div
|
<div
|
||||||
aria-hidden
|
|
||||||
class="storytelling__image"
|
class="storytelling__image"
|
||||||
data-cache
|
data-caché
|
||||||
data-index="12"
|
data-index="12"
|
||||||
|
tabindex="-1"
|
||||||
>
|
>
|
||||||
{{
|
{{
|
||||||
images.genere_source_img_multi_formats("#{ site.theme.link }/assets/img/storytelling/scroll12", "", 903, 1080, "image-scroll12")
|
images.genere_source_img_multi_formats("#{ site.theme.link }/assets/img/storytelling/scroll12", "", 903, 1080, "image-scroll12")
|
||||||
|
|
@ -145,10 +241,10 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div
|
<div
|
||||||
aria-hidden
|
|
||||||
class="storytelling__image"
|
class="storytelling__image"
|
||||||
data-cache
|
data-caché
|
||||||
data-index="13"
|
data-index="13"
|
||||||
|
tabindex="-1"
|
||||||
>
|
>
|
||||||
{{
|
{{
|
||||||
images.genere_source_img_multi_formats("#{ site.theme.link }/assets/img/storytelling/scroll13", "", 903, 1080, "image-scroll13")
|
images.genere_source_img_multi_formats("#{ site.theme.link }/assets/img/storytelling/scroll13", "", 903, 1080, "image-scroll13")
|
||||||
|
|
|
||||||
|
|
@ -26,7 +26,7 @@
|
||||||
id="bouton-plus-de-produits"
|
id="bouton-plus-de-produits"
|
||||||
type="button"
|
type="button"
|
||||||
>
|
>
|
||||||
Show more products
|
Show more
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</main>
|
</main>
|
||||||
|
|
|
||||||
|
|
@ -16,8 +16,7 @@
|
||||||
</button>
|
</button>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
{# TODO: Utiliser un Menu WordPress #}
|
{# TODO: Utiliser un Menu WordPress ? #}
|
||||||
{# TODO: Utiliser des <span> À L'INTÉRIEUR de <li> #}
|
|
||||||
<nav
|
<nav
|
||||||
class="menu-navigation"
|
class="menu-navigation"
|
||||||
id="menu-navigation-en-tete"
|
id="menu-navigation-en-tete"
|
||||||
|
|
@ -28,6 +27,7 @@
|
||||||
>
|
>
|
||||||
<span>
|
<span>
|
||||||
<a
|
<a
|
||||||
|
{{ page_courante == pages.home.lien ? "aria-current=page" : ""}}
|
||||||
class="lien-menu"
|
class="lien-menu"
|
||||||
href="{{ pages.home.lien }}"
|
href="{{ pages.home.lien }}"
|
||||||
>
|
>
|
||||||
|
|
@ -40,6 +40,7 @@
|
||||||
>
|
>
|
||||||
<span>
|
<span>
|
||||||
<a
|
<a
|
||||||
|
{{ est_page_boutique ? "aria-current=page" : ""}}
|
||||||
class="lien-menu"
|
class="lien-menu"
|
||||||
href="{{ pages.shop.lien }}"
|
href="{{ pages.shop.lien }}"
|
||||||
>
|
>
|
||||||
|
|
@ -52,6 +53,7 @@
|
||||||
>
|
>
|
||||||
<span>
|
<span>
|
||||||
<a
|
<a
|
||||||
|
{{ page_courante == pages.about.lien ? "aria-current=page" : ""}}
|
||||||
class="lien-menu"
|
class="lien-menu"
|
||||||
href="{{ pages.about.lien }}"
|
href="{{ pages.about.lien }}"
|
||||||
>
|
>
|
||||||
|
|
@ -65,6 +67,7 @@
|
||||||
>
|
>
|
||||||
<span>
|
<span>
|
||||||
<a
|
<a
|
||||||
|
{{ page_courante == pages.contact.lien ? "aria-current=page" : ""}}
|
||||||
class="lien-menu"
|
class="lien-menu"
|
||||||
href="{{ pages.contact.lien }}"
|
href="{{ pages.contact.lien }}"
|
||||||
>
|
>
|
||||||
|
|
@ -110,6 +113,7 @@
|
||||||
>
|
>
|
||||||
<span>
|
<span>
|
||||||
<a
|
<a
|
||||||
|
{{ page_courante == pages.home.lien ? "aria-current=page" : ""}}
|
||||||
class="lien-menu"
|
class="lien-menu"
|
||||||
href="{{ pages.home.lien }}"
|
href="{{ pages.home.lien }}"
|
||||||
>
|
>
|
||||||
|
|
@ -123,6 +127,7 @@
|
||||||
>
|
>
|
||||||
<span>
|
<span>
|
||||||
<a
|
<a
|
||||||
|
{{ est_page_boutique ? "aria-current=page" : ""}}
|
||||||
class="lien-menu"
|
class="lien-menu"
|
||||||
href="{{ pages.shop.lien }}"
|
href="{{ pages.shop.lien }}"
|
||||||
>
|
>
|
||||||
|
|
@ -136,6 +141,7 @@
|
||||||
>
|
>
|
||||||
<span>
|
<span>
|
||||||
<a
|
<a
|
||||||
|
{{ page_courante == pages.about.lien ? "aria-current=page" : ""}}
|
||||||
class="lien-menu"
|
class="lien-menu"
|
||||||
href="{{ pages.about.lien }}"
|
href="{{ pages.about.lien }}"
|
||||||
>
|
>
|
||||||
|
|
@ -149,6 +155,7 @@
|
||||||
>
|
>
|
||||||
<span>
|
<span>
|
||||||
<a
|
<a
|
||||||
|
{{ page_courante == pages.contact.lien ? "aria-current=page" : ""}}
|
||||||
class="lien-menu"
|
class="lien-menu"
|
||||||
href="{{ pages.contact.lien }}"
|
href="{{ pages.contact.lien }}"
|
||||||
>
|
>
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue