@lystech/sections 0.5.0 → 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -16,4 +16,4 @@ export { adaptateurI18next, appliquerAuxTextes } from './sourceTexte';
16
16
  export type { Dictionnaire, SourceTexte } from './sourceTexte';
17
17
  export { useSection, useSectionList } from './useSection';
18
18
  export type { BlocDeclare, ChampDeclare, SectionPubliee, TypeDeChamp, } from './types';
19
- export type { AncrageEdition, ResultatSection } from './useSection';
19
+ export type { AncrageEdition, ChampEdition, ResultatSection } from './useSection';
package/dist/index.js CHANGED
@@ -1,22 +1,22 @@
1
1
  import { s as W, a as D, b as u } from "./morceaux/constantes-BPZxUYge.js";
2
- import { C as lt } from "./morceaux/constantes-BPZxUYge.js";
3
- import { jsx as C, jsxs as J, Fragment as q } from "react/jsx-runtime";
4
- import { useState as p, useRef as x, useEffect as A, useCallback as b, useMemo as L, useContext as Z, createContext as G } from "react";
2
+ import { C as dt } from "./morceaux/constantes-BPZxUYge.js";
3
+ import { jsx as I, jsxs as J, Fragment as q } from "react/jsx-runtime";
4
+ import { useState as p, useRef as x, useEffect as A, useCallback as C, useMemo as L, useContext as Z, createContext as G } from "react";
5
5
  import { appliquerAuxTextes as K } from "./morceaux/sourceTexte-BMPMpNg9.js";
6
- import { adaptateurI18next as ft } from "./morceaux/sourceTexte-BMPMpNg9.js";
6
+ import { adaptateurI18next as ht } from "./morceaux/sourceTexte-BMPMpNg9.js";
7
7
  const M = G(null), Q = "https://api.lystech.ca/api";
8
8
  function V() {
9
9
  if (typeof window > "u") return null;
10
- const t = (r) => {
10
+ const t = (e) => {
11
11
  try {
12
- window.localStorage.setItem(u, r);
12
+ window.localStorage.setItem(u, e);
13
13
  } catch {
14
14
  try {
15
- window.sessionStorage.setItem(u, r);
15
+ window.sessionStorage.setItem(u, e);
16
16
  } catch {
17
17
  }
18
18
  }
19
- return r;
19
+ return e;
20
20
  };
21
21
  try {
22
22
  if (window.localStorage.getItem(D)) {
@@ -27,9 +27,9 @@ function V() {
27
27
  }
28
28
  return null;
29
29
  }
30
- const r = window.location.hash.replace(/^#/, "");
31
- if (r.includes(u + "=")) {
32
- const c = new URLSearchParams(r), o = c.get(u);
30
+ const e = window.location.hash.replace(/^#/, "");
31
+ if (e.includes(u + "=")) {
32
+ const c = new URLSearchParams(e), o = c.get(u);
33
33
  if (o) {
34
34
  c.delete(u);
35
35
  const a = c.toString();
@@ -40,16 +40,16 @@ function V() {
40
40
  ), t(o);
41
41
  }
42
42
  }
43
- const e = new URL(window.location.href), n = e.searchParams.get(u);
44
- return n ? (e.searchParams.delete(u), window.history.replaceState({}, "", e.toString()), t(n)) : window.localStorage.getItem(u) ?? window.sessionStorage.getItem(u);
43
+ const r = new URL(window.location.href), n = r.searchParams.get(u);
44
+ return n ? (r.searchParams.delete(u), window.history.replaceState({}, "", r.toString()), t(n)) : window.localStorage.getItem(u) ?? window.sessionStorage.getItem(u);
45
45
  } catch {
46
46
  return null;
47
47
  }
48
48
  }
49
- function ot({
49
+ function ct({
50
50
  site: t,
51
- page: r,
52
- langue: e = "fr",
51
+ page: e,
52
+ langue: r = "fr",
53
53
  apiBaseUrl: n = Q,
54
54
  sectionsInitiales: c,
55
55
  sourceTexte: o,
@@ -60,13 +60,13 @@ function ot({
60
60
  c ?? []
61
61
  ), [w, g] = p(
62
62
  c?.length ? "pret" : "chargement"
63
- ), [j, y] = p(0), [S, T] = p({}), [P, $] = p(!1), U = x(null);
63
+ ), [j, y] = p(0), [S, k] = p({}), [P, N] = p(!1), U = x(null);
64
64
  A(() => {
65
- if (!t || !r) return;
65
+ if (!t || !e) return;
66
66
  U.current?.abort();
67
67
  const s = new AbortController();
68
68
  U.current = s, g("chargement");
69
- const l = n + "/site-sections/public/" + encodeURIComponent(t) + "/" + encodeURIComponent([r, ...a ?? []].join(","));
69
+ const l = n + "/site-sections/public/" + encodeURIComponent(t) + "/" + encodeURIComponent([e, ...a ?? []].join(","));
70
70
  return fetch(l, { signal: s.signal }).then(
71
71
  (i) => i.ok ? i.json() : Promise.reject(new Error(String(i.status)))
72
72
  ).then((i) => {
@@ -74,29 +74,29 @@ function ot({
74
74
  }).catch((i) => {
75
75
  s.signal.aborted || i?.name === "AbortError" || g("erreur");
76
76
  }), () => s.abort();
77
- }, [t, r, n, j, (a ?? []).join(",")]);
78
- const R = b(() => y((s) => s + 1), []), z = x({}), k = b((s, l) => {
79
- z.current[s] = l;
77
+ }, [t, e, n, j, (a ?? []).join(",")]);
78
+ const R = C(() => y((s) => s + 1), []), $ = x({}), z = C((s, l) => {
79
+ $.current[s] = l;
80
80
  }, []);
81
81
  A(() => {
82
82
  !o || !d.length || K(d, o);
83
83
  }, [d, o]);
84
- const _ = b(
85
- (s, l) => T((i) => ({ ...i, [s]: l })),
84
+ const _ = C(
85
+ (s, l) => k((i) => ({ ...i, [s]: l })),
86
86
  []
87
87
  ), f = x({
88
88
  site: t,
89
- page: r,
90
- langue: e,
89
+ page: e,
90
+ langue: r,
91
91
  poserApercu: () => {
92
92
  },
93
93
  recharger: () => {
94
94
  }
95
95
  });
96
- f.current.site = t, f.current.page = r, f.current.langue = e, f.current.poserApercu = _, f.current.sourceTexte = o, f.current.replis = z.current, f.current.recharger = R, A(() => {
97
- f.current.surChangementDePage?.(r);
98
- }, [r]);
99
- const v = x(null), F = b(
96
+ f.current.site = t, f.current.page = e, f.current.langue = r, f.current.poserApercu = _, f.current.sourceTexte = o, f.current.replis = $.current, f.current.recharger = R, A(() => {
97
+ f.current.surChangementDePage?.(e);
98
+ }, [e]);
99
+ const v = x(null), F = C(
100
100
  async (s, l = {}) => {
101
101
  const i = v.current;
102
102
  if (!i) throw new Error("Aucune connexion d'édition active.");
@@ -116,7 +116,7 @@ function ot({
116
116
  if (!s) return;
117
117
  let l = !0, i;
118
118
  return import("@lystech/sections/editeur").then((h) => {
119
- l && (v.current = s, $(!0), i = h.monterEditeur({
119
+ l && (v.current = s, N(!0), i = h.monterEditeur({
120
120
  jeton: s,
121
121
  site: t,
122
122
  apiBaseUrl: n,
@@ -128,11 +128,11 @@ function ot({
128
128
  l = !1, v.current = null, i?.();
129
129
  };
130
130
  }, [t, n]);
131
- const N = L(
131
+ const T = L(
132
132
  () => ({
133
133
  site: t,
134
- page: r,
135
- langue: e,
134
+ page: e,
135
+ langue: r,
136
136
  apiBaseUrl: n,
137
137
  sections: d,
138
138
  etat: w,
@@ -140,13 +140,13 @@ function ot({
140
140
  apercu: S,
141
141
  poserApercu: _,
142
142
  modeEdition: P,
143
- declarerRepli: k,
143
+ declarerRepli: z,
144
144
  appelEdition: F
145
145
  }),
146
146
  [
147
147
  t,
148
- r,
149
148
  e,
149
+ r,
150
150
  n,
151
151
  d,
152
152
  w,
@@ -154,25 +154,25 @@ function ot({
154
154
  S,
155
155
  _,
156
156
  P,
157
- k,
157
+ z,
158
158
  F
159
159
  ]
160
160
  );
161
- return /* @__PURE__ */ C(M.Provider, { value: N, children: m });
161
+ return /* @__PURE__ */ I(M.Provider, { value: T, children: m });
162
162
  }
163
163
  function O() {
164
164
  return Z(M);
165
165
  }
166
166
  const X = "https://api.lystech.ca/api";
167
- function ct({
167
+ function st({
168
168
  site: t,
169
- apiBaseUrl: r,
170
- className: e,
169
+ apiBaseUrl: e,
170
+ className: r,
171
171
  mention: n = "Réalisé avec Lystech",
172
172
  connexion: c = "Connexion",
173
173
  methodes: o
174
174
  }) {
175
- const a = O(), m = t ?? a?.site ?? "", d = r ?? a?.apiBaseUrl ?? X, [E, w] = p(!1);
175
+ const a = O(), m = t ?? a?.site ?? "", d = e ?? a?.apiBaseUrl ?? X, [E, w] = p(!1);
176
176
  if (!m) return null;
177
177
  const g = async () => {
178
178
  if (!E) {
@@ -210,7 +210,7 @@ function ct({
210
210
  return /* @__PURE__ */ J(
211
211
  "div",
212
212
  {
213
- className: e,
213
+ className: r,
214
214
  style: {
215
215
  display: "flex",
216
216
  flexWrap: "wrap",
@@ -221,7 +221,7 @@ function ct({
221
221
  lineHeight: 1.5
222
222
  },
223
223
  children: [
224
- n !== null && /* @__PURE__ */ C(
224
+ n !== null && /* @__PURE__ */ I(
225
225
  "a",
226
226
  {
227
227
  href: "https://lystech.ca",
@@ -232,94 +232,98 @@ function ct({
232
232
  }
233
233
  ),
234
234
  !a?.modeEdition && /* @__PURE__ */ J(q, { children: [
235
- n !== null && /* @__PURE__ */ C("span", { "aria-hidden": "true", children: "·" }),
236
- /* @__PURE__ */ C("button", { type: "button", style: j, onClick: g, children: E ? "…" : c })
235
+ n !== null && /* @__PURE__ */ I("span", { "aria-hidden": "true", children: "·" }),
236
+ /* @__PURE__ */ I("button", { type: "button", style: j, onClick: g, children: E ? "…" : c })
237
237
  ] })
238
238
  ]
239
239
  }
240
240
  );
241
241
  }
242
242
  function Y(t) {
243
- return !!t && typeof t == "object" && !Array.isArray(t) && Object.keys(t).every((r) => /^[a-z]{2}(-[A-Za-z]{2})?$/.test(r));
243
+ return !!t && typeof t == "object" && !Array.isArray(t) && Object.keys(t).every((e) => /^[a-z]{2}(-[A-Za-z]{2})?$/.test(e));
244
244
  }
245
- function I(t, r) {
246
- if (Array.isArray(t)) return t.map((e) => I(e, r));
245
+ function b(t, e) {
246
+ if (Array.isArray(t)) return t.map((r) => b(r, e));
247
247
  if (Y(t)) {
248
- const e = t, n = r.slice(0, 2);
249
- return e[r] ?? e[n] ?? Object.values(e).find((o) => o != null) ?? "";
248
+ const r = t, n = e.slice(0, 2);
249
+ return r[e] ?? r[n] ?? Object.values(r).find((o) => o != null) ?? "";
250
250
  }
251
251
  if (t && typeof t == "object") {
252
- const e = {};
252
+ const r = {};
253
253
  for (const [n, c] of Object.entries(t))
254
- e[n] = I(c, r);
255
- return e;
254
+ r[n] = b(c, e);
255
+ return r;
256
256
  }
257
257
  return t;
258
258
  }
259
- function B(t, r) {
260
- if (!r || typeof r != "object" || Array.isArray(r))
259
+ function B(t, e) {
260
+ if (!e || typeof e != "object" || Array.isArray(e))
261
261
  return t;
262
- const e = { ...t };
263
- for (const [n, c] of Object.entries(r))
264
- c != null && (e[n] = c);
265
- return e;
262
+ const r = { ...t };
263
+ for (const [n, c] of Object.entries(e))
264
+ c != null && (r[n] = c);
265
+ return r;
266
+ }
267
+ function tt(t) {
268
+ return (e) => ({ "data-lystech-champ": `${t}:${e}` });
266
269
  }
267
- function st(t, r) {
268
- const e = O(), n = e?.apercu?.[t], c = e?.declarerRepli;
270
+ function it(t, e) {
271
+ const r = O(), n = r?.apercu?.[t], c = r?.declarerRepli;
269
272
  return A(() => {
270
- c?.(t, r.defaut);
271
- }, [c, t, r.defaut]), L(() => {
272
- const o = e?.sections.find(
273
+ c?.(t, e.defaut);
274
+ }, [c, t, e.defaut]), L(() => {
275
+ const o = r?.sections.find(
273
276
  (d) => d.blockType === t
274
- ), a = n ?? o?.data ?? null, m = a ? I(a, e?.langue ?? "fr") : null;
277
+ ), a = n ?? o?.data ?? null, m = a ? b(a, r?.langue ?? "fr") : null;
275
278
  return {
276
- contenu: B(r.defaut, m),
279
+ contenu: B(e.defaut, m),
277
280
  publie: !!o?.data,
278
281
  UID: o?.UID ?? null,
279
- chargement: e?.etat === "chargement",
280
- ancrage: { "data-lystech-section": t }
282
+ chargement: r?.etat === "chargement",
283
+ ancrage: { "data-lystech-section": t },
284
+ champ: tt(t)
281
285
  };
282
286
  }, [
283
- e?.sections,
284
- e?.langue,
285
- e?.etat,
287
+ r?.sections,
288
+ r?.langue,
289
+ r?.etat,
286
290
  n,
287
291
  t,
288
- r.defaut
292
+ e.defaut
289
293
  ]);
290
294
  }
291
- function it(t, r) {
292
- const e = O();
295
+ function at(t, e) {
296
+ const r = O();
293
297
  return L(() => {
294
- const n = { "data-lystech-section": t }, c = (e?.sections ?? []).filter(
298
+ const n = { "data-lystech-section": t }, c = (r?.sections ?? []).filter(
295
299
  (o) => o.blockType === t
296
300
  );
297
301
  return c.length === 0 ? {
298
- items: (r?.defaut ?? []).map((o, a) => ({
302
+ items: (e?.defaut ?? []).map((o, a) => ({
299
303
  ...o,
300
304
  __uid: `defaut-${a}`
301
305
  })),
302
306
  publie: !1,
303
- chargement: e?.etat === "chargement",
307
+ chargement: r?.etat === "chargement",
304
308
  ancrage: n
305
309
  } : {
306
310
  items: c.map((o) => ({
307
- ...I(o.data ?? {}, e?.langue ?? "fr"),
311
+ ...b(o.data ?? {}, r?.langue ?? "fr"),
308
312
  __uid: o.UID
309
313
  })),
310
314
  publie: !0,
311
- chargement: e?.etat === "chargement",
315
+ chargement: r?.etat === "chargement",
312
316
  ancrage: n
313
317
  };
314
- }, [e?.sections, e?.langue, e?.etat, t, r?.defaut]);
318
+ }, [r?.sections, r?.langue, r?.etat, t, e?.defaut]);
315
319
  }
316
320
  export {
317
- lt as CLASSE_HORS_EDITION,
318
- ot as SectionsProvider,
319
- ct as SignatureLystech,
320
- ft as adaptateurI18next,
321
+ dt as CLASSE_HORS_EDITION,
322
+ ct as SectionsProvider,
323
+ st as SignatureLystech,
324
+ ht as adaptateurI18next,
321
325
  K as appliquerAuxTextes,
322
- st as useSection,
323
- it as useSectionList,
326
+ it as useSection,
327
+ at as useSectionList,
324
328
  O as useSectionsContext
325
329
  };
@@ -16,6 +16,25 @@
16
16
  export type AncrageEdition = {
17
17
  "data-lystech-section": string;
18
18
  };
19
+ /**
20
+ * LES ATTRIBUTS À POSER SUR L'ÉLÉMENT QUI AFFICHE UN CHAMP — un prix, un
21
+ * numéro, une adresse.
22
+ *
23
+ * Un texte traduit se retrouve tout seul dans la page : l'éditeur connaît
24
+ * le dictionnaire du site. Un NOMBRE, lui, se fond dans un format (« 85 $ »,
25
+ * « $85 ») : rien ne permet de deviner que ce 85 est le prix de la séance.
26
+ * Le site le dit en étalant ces attributs sur l'élément qui ne contient QUE
27
+ * la valeur :
28
+ *
29
+ * const { contenu, champ } = useSection("tarifs", { defaut });
30
+ * return <p><span {...champ("seance")}>{contenu.seance}</span> $</p>;
31
+ *
32
+ * En mode édition, un clic dessus permet de corriger la valeur sur place.
33
+ * Pour un visiteur, c'est un attribut `data-` inerte.
34
+ */
35
+ export type ChampEdition = {
36
+ "data-lystech-champ": string;
37
+ };
19
38
  export type ResultatSection<T> = {
20
39
  /** Le contenu à afficher : aperçu, sinon publié, sinon défaut. */
21
40
  contenu: T;
@@ -26,6 +45,8 @@ export type ResultatSection<T> = {
26
45
  chargement: boolean;
27
46
  /** À étaler sur le conteneur pour que l'éditeur puisse le situer. */
28
47
  ancrage: AncrageEdition;
48
+ /** À étaler sur l'élément qui affiche UN champ, pour le corriger sur place. */
49
+ champ: (nom: keyof T & string) => ChampEdition;
29
50
  };
30
51
  /**
31
52
  * Le contenu d'un type de bloc sur la page courante.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lystech/sections",
3
- "version": "0.5.0",
3
+ "version": "0.6.0",
4
4
  "description": "Contenu de site editable par le client — lecture legere, edition chargee a la demande.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",