@lystech/sections 0.4.5 → 0.5.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
@@ -9,6 +9,7 @@
9
9
  * Le paquet ne dépend PAS de @lystech/core : une clinique qui veut modifier
10
10
  * trois textes n'a aucune raison de charger un magasin, un panier et PayPal.
11
11
  */
12
+ export { CLASSE_HORS_EDITION } from './constantes';
12
13
  export { SectionsProvider, useSectionsContext } from './SectionsProvider';
13
14
  export { SignatureLystech } from './SignatureLystech';
14
15
  export { adaptateurI18next, appliquerAuxTextes } from './sourceTexte';
package/dist/index.js CHANGED
@@ -1,179 +1,203 @@
1
- import { jsx as x, jsxs as U, Fragment as T } from "react/jsx-runtime";
2
- import { useState as m, useRef as D, useEffect as b, useCallback as O, useMemo as _, useContext as M, createContext as N } from "react";
3
- import { appliquerAuxTextes as q } from "./morceaux/sourceTexte-BMPMpNg9.js";
4
- import { adaptateurI18next as ot } from "./morceaux/sourceTexte-BMPMpNg9.js";
5
- const u = "lystech-edit", P = "lystech-edit-sortie", J = N(null), H = "https://api.lystech.ca/api";
6
- function W() {
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";
5
+ import { appliquerAuxTextes as K } from "./morceaux/sourceTexte-BMPMpNg9.js";
6
+ import { adaptateurI18next as ft } from "./morceaux/sourceTexte-BMPMpNg9.js";
7
+ const M = G(null), Q = "https://api.lystech.ca/api";
8
+ function V() {
7
9
  if (typeof window > "u") return null;
8
- const t = (n) => {
10
+ const t = (r) => {
9
11
  try {
10
- window.localStorage.setItem(u, n);
12
+ window.localStorage.setItem(u, r);
11
13
  } catch {
12
14
  try {
13
- window.sessionStorage.setItem(u, n);
15
+ window.sessionStorage.setItem(u, r);
14
16
  } catch {
15
17
  }
16
18
  }
17
- return n;
19
+ return r;
18
20
  };
19
21
  try {
20
- if (window.localStorage.getItem(P)) {
21
- window.localStorage.removeItem(P), window.localStorage.removeItem(u);
22
+ if (window.localStorage.getItem(D)) {
23
+ window.localStorage.removeItem(D), window.localStorage.removeItem(u);
22
24
  try {
23
25
  window.sessionStorage.removeItem(u);
24
26
  } catch {
25
27
  }
26
28
  return null;
27
29
  }
28
- const n = window.location.hash.replace(/^#/, "");
29
- if (n.includes(u + "=")) {
30
- const o = new URLSearchParams(n), c = o.get(u);
31
- if (c) {
32
- o.delete(u);
33
- const s = o.toString();
30
+ const r = window.location.hash.replace(/^#/, "");
31
+ if (r.includes(u + "=")) {
32
+ const c = new URLSearchParams(r), o = c.get(u);
33
+ if (o) {
34
+ c.delete(u);
35
+ const a = c.toString();
34
36
  return window.history.replaceState(
35
37
  {},
36
38
  "",
37
- window.location.pathname + window.location.search + (s ? "#" + s : "")
38
- ), t(c);
39
+ window.location.pathname + window.location.search + (a ? "#" + a : "")
40
+ ), t(o);
39
41
  }
40
42
  }
41
- const e = new URL(window.location.href), r = e.searchParams.get(u);
42
- return r ? (e.searchParams.delete(u), window.history.replaceState({}, "", e.toString()), t(r)) : window.localStorage.getItem(u) ?? window.sessionStorage.getItem(u);
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
45
  } catch {
44
46
  return null;
45
47
  }
46
48
  }
47
- function Y({
49
+ function ot({
48
50
  site: t,
49
- page: n,
51
+ page: r,
50
52
  langue: e = "fr",
51
- apiBaseUrl: r = H,
52
- sectionsInitiales: o,
53
- sourceTexte: c,
54
- pagesPartagees: s,
55
- children: f
53
+ apiBaseUrl: n = Q,
54
+ sectionsInitiales: c,
55
+ sourceTexte: o,
56
+ pagesPartagees: a,
57
+ children: m
56
58
  }) {
57
- const [d, S] = m(
58
- o ?? []
59
- ), [p, w] = m(
60
- o?.length ? "pret" : "chargement"
61
- ), [E, g] = m(0), [y, $] = m({}), [R, z] = m(!1), L = D(null);
62
- b(() => {
63
- if (!t || !n) return;
64
- L.current?.abort();
65
- const a = new AbortController();
66
- L.current = a, w("chargement");
67
- const h = r + "/site-sections/public/" + encodeURIComponent(t) + "/" + encodeURIComponent([n, ...s ?? []].join(","));
68
- return fetch(h, { signal: a.signal }).then(
59
+ const [d, E] = p(
60
+ c ?? []
61
+ ), [w, g] = p(
62
+ c?.length ? "pret" : "chargement"
63
+ ), [j, y] = p(0), [S, T] = p({}), [P, $] = p(!1), U = x(null);
64
+ A(() => {
65
+ if (!t || !r) return;
66
+ U.current?.abort();
67
+ const s = new AbortController();
68
+ U.current = s, g("chargement");
69
+ const l = n + "/site-sections/public/" + encodeURIComponent(t) + "/" + encodeURIComponent([r, ...a ?? []].join(","));
70
+ return fetch(l, { signal: s.signal }).then(
69
71
  (i) => i.ok ? i.json() : Promise.reject(new Error(String(i.status)))
70
72
  ).then((i) => {
71
- a.signal.aborted || (S(Array.isArray(i) ? i : []), w("pret"));
73
+ s.signal.aborted || (E(Array.isArray(i) ? i : []), g("pret"));
72
74
  }).catch((i) => {
73
- a.signal.aborted || i?.name === "AbortError" || w("erreur");
74
- }), () => a.abort();
75
- }, [t, n, r, E, (s ?? []).join(",")]);
76
- const I = O(() => g((a) => a + 1), []);
77
- b(() => {
78
- !c || !d.length || q(d, c);
79
- }, [d, c]);
80
- const j = O(
81
- (a, h) => $((i) => ({ ...i, [a]: h })),
75
+ s.signal.aborted || i?.name === "AbortError" || g("erreur");
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;
80
+ }, []);
81
+ A(() => {
82
+ !o || !d.length || K(d, o);
83
+ }, [d, o]);
84
+ const _ = b(
85
+ (s, l) => T((i) => ({ ...i, [s]: l })),
82
86
  []
83
- ), l = D({
87
+ ), f = x({
84
88
  site: t,
85
- page: n,
89
+ page: r,
86
90
  langue: e,
87
91
  poserApercu: () => {
88
92
  },
89
93
  recharger: () => {
90
94
  }
91
95
  });
92
- l.current.site = t, l.current.page = n, l.current.langue = e, l.current.poserApercu = j, l.current.sourceTexte = c, l.current.recharger = I, b(() => {
93
- l.current.surChangementDePage?.(n);
94
- }, [n]), b(() => {
95
- const a = W();
96
- if (!a) return;
97
- let h = !0, i;
98
- return import("@lystech/sections/editeur").then((A) => {
99
- h && (z(!0), i = A.monterEditeur({
100
- jeton: a,
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(
100
+ async (s, l = {}) => {
101
+ const i = v.current;
102
+ if (!i) throw new Error("Aucune connexion d'édition active.");
103
+ if (!s.startsWith("/"))
104
+ throw new Error(
105
+ "appelEdition attend un chemin de l'API, ex. « /results/site/droits »."
106
+ );
107
+ const h = new Headers(l.headers);
108
+ h.set("Authorization", "Bearer " + i), typeof l.body == "string" && !h.has("Content-Type") && h.set("Content-Type", "application/json");
109
+ const H = await fetch(n + s, { ...l, headers: h });
110
+ return H.status === 401 && W(), H;
111
+ },
112
+ [n]
113
+ );
114
+ A(() => {
115
+ const s = V();
116
+ if (!s) return;
117
+ let l = !0, i;
118
+ return import("@lystech/sections/editeur").then((h) => {
119
+ l && (v.current = s, $(!0), i = h.monterEditeur({
120
+ jeton: s,
101
121
  site: t,
102
- apiBaseUrl: r,
103
- pont: l.current
122
+ apiBaseUrl: n,
123
+ pont: f.current
104
124
  }));
105
- }).catch((A) => {
106
- console.error("[lystech] éditeur indisponible:", A?.message ?? A);
125
+ }).catch((h) => {
126
+ console.error("[lystech] éditeur indisponible:", h?.message ?? h);
107
127
  }), () => {
108
- h = !1, i?.();
128
+ l = !1, v.current = null, i?.();
109
129
  };
110
- }, [t, r]);
111
- const F = _(
130
+ }, [t, n]);
131
+ const N = L(
112
132
  () => ({
113
133
  site: t,
114
- page: n,
134
+ page: r,
115
135
  langue: e,
116
- apiBaseUrl: r,
136
+ apiBaseUrl: n,
117
137
  sections: d,
118
- etat: p,
119
- recharger: I,
120
- apercu: y,
121
- poserApercu: j,
122
- modeEdition: R
138
+ etat: w,
139
+ recharger: R,
140
+ apercu: S,
141
+ poserApercu: _,
142
+ modeEdition: P,
143
+ declarerRepli: k,
144
+ appelEdition: F
123
145
  }),
124
146
  [
125
147
  t,
126
- n,
127
- e,
128
148
  r,
149
+ e,
150
+ n,
129
151
  d,
130
- p,
131
- I,
132
- y,
133
- j,
134
- R
152
+ w,
153
+ R,
154
+ S,
155
+ _,
156
+ P,
157
+ k,
158
+ F
135
159
  ]
136
160
  );
137
- return /* @__PURE__ */ x(J.Provider, { value: F, children: f });
161
+ return /* @__PURE__ */ C(M.Provider, { value: N, children: m });
138
162
  }
139
- function v() {
140
- return M(J);
163
+ function O() {
164
+ return Z(M);
141
165
  }
142
- const Z = "https://api.lystech.ca/api", k = "lystech-edit";
143
- function B({
166
+ const X = "https://api.lystech.ca/api";
167
+ function ct({
144
168
  site: t,
145
- apiBaseUrl: n,
169
+ apiBaseUrl: r,
146
170
  className: e,
147
- mention: r = "Réalisé avec Lystech",
148
- connexion: o = "Connexion",
149
- methodes: c
171
+ mention: n = "Réalisé avec Lystech",
172
+ connexion: c = "Connexion",
173
+ methodes: o
150
174
  }) {
151
- const s = v(), f = t ?? s?.site ?? "", d = n ?? s?.apiBaseUrl ?? Z, [S, p] = m(!1);
152
- if (!f) return null;
153
- const w = async () => {
154
- if (!S) {
155
- p(!0);
175
+ const a = O(), m = t ?? a?.site ?? "", d = r ?? a?.apiBaseUrl ?? X, [E, w] = p(!1);
176
+ if (!m) return null;
177
+ const g = async () => {
178
+ if (!E) {
179
+ w(!0);
156
180
  try {
157
181
  (await import("@lystech/sections/editeur")).monterConnexion({
158
- site: f,
182
+ site: m,
159
183
  apiBaseUrl: d,
160
- ...c ? { methodes: c } : {},
161
- surJeton: (y) => {
184
+ ...o ? { methodes: o } : {},
185
+ surJeton: (S) => {
162
186
  try {
163
- window.localStorage.removeItem("lystech-edit-sortie"), window.localStorage.setItem(k, y);
187
+ window.localStorage.removeItem(D), window.localStorage.setItem(u, S);
164
188
  } catch {
165
- window.location.hash = k + "=" + encodeURIComponent(y);
189
+ window.location.hash = u + "=" + encodeURIComponent(S);
166
190
  }
167
191
  window.location.reload();
168
192
  }
169
193
  });
170
- } catch (g) {
171
- console.error("[lystech] connexion indisponible:", g?.message ?? g);
194
+ } catch (y) {
195
+ console.error("[lystech] connexion indisponible:", y?.message ?? y);
172
196
  } finally {
173
- p(!1);
197
+ w(!1);
174
198
  }
175
199
  }
176
- }, E = {
200
+ }, j = {
177
201
  color: "inherit",
178
202
  font: "inherit",
179
203
  background: "none",
@@ -183,7 +207,7 @@ function B({
183
207
  textDecoration: "underline",
184
208
  textUnderlineOffset: "0.2em"
185
209
  };
186
- return /* @__PURE__ */ U(
210
+ return /* @__PURE__ */ J(
187
211
  "div",
188
212
  {
189
213
  className: e,
@@ -197,57 +221,59 @@ function B({
197
221
  lineHeight: 1.5
198
222
  },
199
223
  children: [
200
- /* @__PURE__ */ x(
224
+ n !== null && /* @__PURE__ */ C(
201
225
  "a",
202
226
  {
203
227
  href: "https://lystech.ca",
204
228
  target: "_blank",
205
229
  rel: "noreferrer",
206
230
  style: { color: "inherit" },
207
- children: r
231
+ children: n
208
232
  }
209
233
  ),
210
- !s?.modeEdition && /* @__PURE__ */ U(T, { children: [
211
- /* @__PURE__ */ x("span", { "aria-hidden": "true", children: "·" }),
212
- /* @__PURE__ */ x("button", { type: "button", style: E, onClick: w, children: S ? "…" : o })
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 })
213
237
  ] })
214
238
  ]
215
239
  }
216
240
  );
217
241
  }
218
- function G(t) {
219
- return !!t && typeof t == "object" && !Array.isArray(t) && Object.keys(t).every((n) => /^[a-z]{2}(-[A-Za-z]{2})?$/.test(n));
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));
220
244
  }
221
- function C(t, n) {
222
- if (Array.isArray(t)) return t.map((e) => C(e, n));
223
- if (G(t)) {
224
- const e = t, r = n.slice(0, 2);
225
- return e[n] ?? e[r] ?? Object.values(e).find((c) => c != null) ?? "";
245
+ function I(t, r) {
246
+ if (Array.isArray(t)) return t.map((e) => I(e, r));
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) ?? "";
226
250
  }
227
251
  if (t && typeof t == "object") {
228
252
  const e = {};
229
- for (const [r, o] of Object.entries(t))
230
- e[r] = C(o, n);
253
+ for (const [n, c] of Object.entries(t))
254
+ e[n] = I(c, r);
231
255
  return e;
232
256
  }
233
257
  return t;
234
258
  }
235
- function K(t, n) {
236
- if (!n || typeof n != "object" || Array.isArray(n))
259
+ function B(t, r) {
260
+ if (!r || typeof r != "object" || Array.isArray(r))
237
261
  return t;
238
262
  const e = { ...t };
239
- for (const [r, o] of Object.entries(n))
240
- o != null && (e[r] = o);
263
+ for (const [n, c] of Object.entries(r))
264
+ c != null && (e[n] = c);
241
265
  return e;
242
266
  }
243
- function tt(t, n) {
244
- const e = v(), r = e?.apercu?.[t];
245
- return _(() => {
267
+ function st(t, r) {
268
+ const e = O(), n = e?.apercu?.[t], c = e?.declarerRepli;
269
+ return A(() => {
270
+ c?.(t, r.defaut);
271
+ }, [c, t, r.defaut]), L(() => {
246
272
  const o = e?.sections.find(
247
- (f) => f.blockType === t
248
- ), c = r ?? o?.data ?? null, s = c ? C(c, e?.langue ?? "fr") : null;
273
+ (d) => d.blockType === t
274
+ ), a = n ?? o?.data ?? null, m = a ? I(a, e?.langue ?? "fr") : null;
249
275
  return {
250
- contenu: K(n.defaut, s),
276
+ contenu: B(r.defaut, m),
251
277
  publie: !!o?.data,
252
278
  UID: o?.UID ?? null,
253
279
  chargement: e?.etat === "chargement",
@@ -257,42 +283,43 @@ function tt(t, n) {
257
283
  e?.sections,
258
284
  e?.langue,
259
285
  e?.etat,
260
- r,
286
+ n,
261
287
  t,
262
- n.defaut
288
+ r.defaut
263
289
  ]);
264
290
  }
265
- function et(t, n) {
266
- const e = v();
267
- return _(() => {
268
- const r = { "data-lystech-section": t }, o = (e?.sections ?? []).filter(
269
- (c) => c.blockType === t
291
+ function it(t, r) {
292
+ const e = O();
293
+ return L(() => {
294
+ const n = { "data-lystech-section": t }, c = (e?.sections ?? []).filter(
295
+ (o) => o.blockType === t
270
296
  );
271
- return o.length === 0 ? {
272
- items: (n?.defaut ?? []).map((c, s) => ({
273
- ...c,
274
- __uid: `defaut-${s}`
297
+ return c.length === 0 ? {
298
+ items: (r?.defaut ?? []).map((o, a) => ({
299
+ ...o,
300
+ __uid: `defaut-${a}`
275
301
  })),
276
302
  publie: !1,
277
303
  chargement: e?.etat === "chargement",
278
- ancrage: r
304
+ ancrage: n
279
305
  } : {
280
- items: o.map((c) => ({
281
- ...C(c.data ?? {}, e?.langue ?? "fr"),
282
- __uid: c.UID
306
+ items: c.map((o) => ({
307
+ ...I(o.data ?? {}, e?.langue ?? "fr"),
308
+ __uid: o.UID
283
309
  })),
284
310
  publie: !0,
285
311
  chargement: e?.etat === "chargement",
286
- ancrage: r
312
+ ancrage: n
287
313
  };
288
- }, [e?.sections, e?.langue, e?.etat, t, n?.defaut]);
314
+ }, [e?.sections, e?.langue, e?.etat, t, r?.defaut]);
289
315
  }
290
316
  export {
291
- Y as SectionsProvider,
292
- B as SignatureLystech,
293
- ot as adaptateurI18next,
294
- q as appliquerAuxTextes,
295
- tt as useSection,
296
- et as useSectionList,
297
- v as useSectionsContext
317
+ lt as CLASSE_HORS_EDITION,
318
+ ot as SectionsProvider,
319
+ ct as SignatureLystech,
320
+ ft as adaptateurI18next,
321
+ K as appliquerAuxTextes,
322
+ st as useSection,
323
+ it as useSectionList,
324
+ O as useSectionsContext
298
325
  };
@@ -0,0 +1,14 @@
1
+ /** La clé du jeton, dans l'adresse comme dans le stockage. */
2
+ export declare const CLE_JETON = "lystech-edit";
3
+ /** Posée juste avant un rechargement, pour que la sortie soit certaine. */
4
+ export declare const CLE_SORTIE = "lystech-edit-sortie";
5
+ /**
6
+ * SORTIR DU MODE ÉDITION, pour de bon.
7
+ *
8
+ * On efface le jeton ET on pose un marqueur de sortie. Le marqueur est la
9
+ * ceinture : si l'effacement échoue — stockage plein, navigation privée,
10
+ * écriture concurrente — le fournisseur le verra au chargement suivant et
11
+ * nettoiera lui-même. Puis on recharge : la page redevient celle d'un
12
+ * visiteur, et le lien du pied de page permet de se reconnecter.
13
+ */
14
+ export declare function sortirDuModeEdition(): void;
@@ -0,0 +1,19 @@
1
+ const o = "lystech-edit", t = "lystech-edit-sortie";
2
+ function e() {
3
+ try {
4
+ window.localStorage.setItem(t, "1"), window.localStorage.removeItem(o);
5
+ } catch {
6
+ }
7
+ try {
8
+ window.sessionStorage.removeItem(o);
9
+ } catch {
10
+ }
11
+ window.location.reload();
12
+ }
13
+ const s = "lystech-hors-edition";
14
+ export {
15
+ s as C,
16
+ t as a,
17
+ o as b,
18
+ e as s
19
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lystech/sections",
3
- "version": "0.4.5",
3
+ "version": "0.5.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",