mypgs 1.6.0 → 2.0.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.
Files changed (88) hide show
  1. package/AGENTS.md +2 -2
  2. package/assets/javascript/components/_accordion.js +2 -2
  3. package/assets/javascript/components/_modals.js +159 -136
  4. package/assets/javascript/components/_notifications.js +19 -9
  5. package/assets/javascript/components/_search.js +2 -2
  6. package/assets/javascript/components/_slides.js +66 -32
  7. package/assets/javascript/components/_stepTabs.js +4 -4
  8. package/assets/javascript/components/_steps.js +2 -2
  9. package/assets/javascript/components/_summary.js +2 -2
  10. package/assets/javascript/functions/_formValidate.js +97 -53
  11. package/assets/javascript/functions/_scrollY.js +10 -10
  12. package/assets/javascript/layout/_header.js +3 -0
  13. package/assets/scss/base/_html.scss +2 -2
  14. package/assets/scss/base/_variables.scss +2 -2
  15. package/assets/scss/components/_form.scss +2 -2
  16. package/assets/scss/components/_notification.scss +23 -30
  17. package/assets/scss/components/_search.scss +27 -21
  18. package/assets/scss/layout/_pageShell.scss +18 -15
  19. package/assets/scss/mixin/_mx-form.scss +7 -7
  20. package/{templates/html → demo}/demo.html +1 -1
  21. package/demo/demo.js +240 -0
  22. package/dist/css/index.css +86 -92
  23. package/dist/css/index.css.map +1 -1
  24. package/dist/css/index.min.css +1 -1
  25. package/dist/javascript/index.js +356 -255
  26. package/dist/javascript/index.js.map +1 -1
  27. package/dist/javascript/index.min.js +1 -1
  28. package/docs/componenti-e-markup.md +26 -27
  29. package/docs/components/accordion.md +61 -0
  30. package/docs/components/badges.md +67 -0
  31. package/docs/components/breadcumbs.md +43 -0
  32. package/docs/components/button.md +59 -0
  33. package/docs/components/card.md +50 -0
  34. package/docs/components/dropdown.md +135 -0
  35. package/docs/components/form.md +113 -0
  36. package/docs/components/logo.md +36 -0
  37. package/docs/components/menu.md +90 -0
  38. package/docs/components/modal.md +131 -0
  39. package/docs/components/notification.md +81 -0
  40. package/docs/components/search.md +117 -0
  41. package/docs/components/slides.md +85 -0
  42. package/docs/components/stepTabs.md +93 -0
  43. package/docs/components/steps.md +56 -0
  44. package/docs/components/summary.md +49 -0
  45. package/docs/components/table.md +42 -0
  46. package/docs/components/tooltip.md +53 -0
  47. package/docs/helper-javascript.md +68 -3
  48. package/docs/layout/body.md +41 -0
  49. package/docs/layout/flex.md +116 -0
  50. package/docs/layout/footer.md +71 -0
  51. package/docs/layout/grid.md +116 -0
  52. package/docs/layout/header.md +116 -0
  53. package/docs/layout/pageShell.md +94 -0
  54. package/docs/layout/section.md +69 -0
  55. package/docs/patterns/cookieConsent.md +89 -0
  56. package/package.json +2 -1
  57. package/scripts/generate-component-docs.js +557 -0
  58. package/templates/html/components/accordion.html +33 -4
  59. package/templates/html/components/badges.html +23 -0
  60. package/templates/html/components/breadcumbs.html +14 -0
  61. package/templates/html/components/button.html +22 -0
  62. package/templates/html/components/card.html +20 -0
  63. package/templates/html/components/dropdown.html +34 -0
  64. package/templates/html/components/form.html +82 -4
  65. package/templates/html/components/logo.html +21 -0
  66. package/templates/html/components/menu.html +33 -6
  67. package/templates/html/components/modal.html +44 -0
  68. package/templates/html/components/notification.html +68 -32
  69. package/templates/html/components/search.html +76 -0
  70. package/templates/html/components/slides.html +43 -0
  71. package/templates/html/components/stepTabs.html +47 -0
  72. package/templates/html/components/steps.html +24 -0
  73. package/templates/html/components/summary.html +27 -0
  74. package/templates/html/components/table.html +12 -0
  75. package/templates/html/components/tooltip.html +35 -0
  76. package/templates/html/layout/body.html +20 -5
  77. package/templates/html/layout/flex.html +20 -0
  78. package/templates/html/layout/footer.html +29 -1
  79. package/templates/html/layout/grid.html +20 -0
  80. package/templates/html/layout/header.html +41 -0
  81. package/templates/html/layout/pageShell.html +19 -0
  82. package/templates/html/layout/section.html +32 -10
  83. package/templates/html/patterns/cookieConsent.html +31 -0
  84. package/templates/react/components/form.jsx +3 -3
  85. package/templates/react/components/notification.jsx +4 -4
  86. package/templates/react/patterns/footer.jsx +1 -1
  87. package/templates/html/demo.js +0 -130
  88. /package/{templates/html → demo}/demo.css +0 -0
@@ -486,17 +486,17 @@
486
486
  }
487
487
  }
488
488
 
489
- //== formError
490
- @mixin formError() {
489
+ //== formValidate
490
+ @mixin formValidate() {
491
491
 
492
492
  //=== ERROR
493
- &[data-form-status="error"] {
494
- [data-form-field-status="error"] {
493
+ &[pgs-option~="error"] {
494
+ [pgs-option~="error"] {
495
495
  &:not([type=checkbox], [type=radio]) {
496
496
  outline: solid 3px var(--color-error) !important;
497
497
 
498
498
  &::before {
499
- content: "Questo campo è obbligatorio";
499
+ content: "This field is required";
500
500
  color: var(--color-error);
501
501
  font-weight: 500;
502
502
  font-size: 1.7rem;
@@ -507,7 +507,7 @@
507
507
  // button[type=submit] {
508
508
  // --button-background: var(--color-error);
509
509
  // }
510
- label:has(+[data-form-field-status="error"], [data-form-field-status="error"]) {
510
+ label:has(+[pgs-option~="error"], [pgs-option~="error"]) {
511
511
  &:has(input[type=checkbox]) {
512
512
  background-color: var(--color-error) !important;
513
513
  padding: 6px;
@@ -516,7 +516,7 @@
516
516
  }
517
517
  }
518
518
 
519
- fieldset:has(input[type=radio][data-form-field-status="error"]) {
519
+ fieldset:has(input[type=radio][pgs-option~="error"]) {
520
520
  legend {
521
521
  --label-background: var(--color-error) !important;
522
522
  }
@@ -9,7 +9,7 @@
9
9
  <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
10
10
  <link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Urbanist:ital,wght@0,100..900;1,100..900&display=swap">
11
11
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.2/css/all.min.css">
12
- <link rel="stylesheet" href="../../dist/css/index.css">
12
+ <link rel="stylesheet" href="../dist/css/index.css">
13
13
  <link rel="stylesheet" href="demo.css">
14
14
  </head>
15
15
 
package/demo/demo.js ADDED
@@ -0,0 +1,240 @@
1
+ //# DEMO PAGE
2
+
3
+ //= demo Renderer HTML
4
+ const demoRenderer = {
5
+ templateFiles: [
6
+ "components/form.html",
7
+ "components/search.html",
8
+ "components/summary.html",
9
+ "components/menu.html",
10
+ "components/tooltip.html",
11
+ "components/modal.html",
12
+ "components/stepTabs.html",
13
+ "components/accordion.html",
14
+ "components/badges.html",
15
+ "components/breadcumbs.html",
16
+ "components/button.html",
17
+ "components/card.html",
18
+ "components/dropdown.html",
19
+ "components/tooltip.html",
20
+ "components/logo.html",
21
+ "components/slides.html",
22
+ "components/steps.html",
23
+ "components/table.html",
24
+ "components/notification.html",
25
+ "patterns/cookieConsent.html",
26
+ "layout/body.html",
27
+ "layout/flex.html",
28
+ "layout/grid.html",
29
+ "layout/footer.html",
30
+ "layout/header.html",
31
+ "layout/section.html",
32
+ "layout/pageShell.html",
33
+ ],
34
+
35
+ getTemplateTitle(path) {
36
+ return path.replace(".html", "").replace("/", " / ");
37
+ },
38
+
39
+ stripTemplateDocumentation(html) {
40
+ return html.replace(/^\uFEFF?<!--[\t\r\n ]*\/\*\*[\s\S]*?\*\/[\t\r\n ]*-->[\t\r\n ]*/, "");
41
+ },
42
+
43
+ renderSourceTemplate(section, html) {
44
+ const pre = document.createElement("pre");
45
+ const code = document.createElement("code");
46
+ code.textContent = html.trim();
47
+ pre.append(code);
48
+ section.append(pre);
49
+ },
50
+
51
+ renderTemplate(section, path, html) {
52
+ const content = document.createElement("div");
53
+ content.setAttribute("pgs", "container flexColumnElements");
54
+ content.innerHTML = html;
55
+ section.append(content);
56
+ },
57
+
58
+ renderLayout(root, path, html) {
59
+ const template = document.createElement("template");
60
+ template.innerHTML = html.trim();
61
+ root.append(template.content.cloneNode(true));
62
+ },
63
+
64
+ renderTitle(section, path) {
65
+ const title = document.createElement("p");
66
+ title.classList.add("template-title");
67
+ title.innerHTML = "<strong>" + this.getTemplateTitle(path) + "</strong>";
68
+ section.append(title);
69
+ },
70
+
71
+ async loadTemplate(path) {
72
+ const response = await fetch(`../templates/html/${path}`);
73
+ if (!response.ok) throw new Error(`${path}: ${response.status}`);
74
+ return this.stripTemplateDocumentation(await response.text());
75
+ },
76
+
77
+ loadPgsJavascript() {
78
+ return new Promise((resolve, reject) => {
79
+ const script = document.createElement("script");
80
+ script.src = "../dist/javascript/index.js";
81
+ script.addEventListener("load", resolve, { once: true });
82
+ script.addEventListener("error", () => reject(new Error("Bundle PGS non caricato")), { once: true });
83
+ document.body.append(script);
84
+ });
85
+ },
86
+
87
+ async boot() {
88
+ const BEEFORE = document.getElementById("templates-demo-before");
89
+ const MAIN = document.getElementById("templates-demo-main");
90
+ const AFTER = document.getElementById("templates-demo-after");
91
+
92
+ for (const path of this.templateFiles) {
93
+ const isHeader = path === "layout/header.html";
94
+ const isfooter = path === "layout/footer.html";
95
+ const isBody = path === "layout/body.html";
96
+
97
+ if (isHeader || isfooter) {
98
+ try {
99
+ const html = await this.loadTemplate(path);
100
+ this.renderLayout(isHeader ? BEEFORE : AFTER, path, html);
101
+ } catch (error) {
102
+ const message = document.createElement("p");
103
+ message.textContent = `Template non caricato: ${error.message}`;
104
+ (isHeader ? BEEFORE : AFTER).append(message);
105
+ }
106
+ continue;
107
+ }
108
+
109
+ let section;
110
+ const isSection = path !== "layout/section.html" && path !== "layout/pageShell.html"
111
+ isSection ? section = document.createElement("section") : section = document.createElement("div");
112
+
113
+ if (isSection) section.setAttribute("pgs", "section flexColumnElements");
114
+
115
+ section.dataset.template = path;
116
+ this.renderTitle(section, path);
117
+
118
+ if (isBody) {
119
+ const html = await this.loadTemplate(path);
120
+ this.renderSourceTemplate(section, html);
121
+ MAIN.append(section);
122
+ continue;
123
+ }
124
+
125
+ try {
126
+ const html = await this.loadTemplate(path);
127
+ this.renderTemplate(section, path, html);
128
+ } catch (error) {
129
+ const message = document.createElement("p");
130
+ message.textContent = `Template non caricato: ${error.message}`;
131
+ section.append(message);
132
+ }
133
+
134
+ MAIN.append(section);
135
+ if (!isSection) {
136
+ section.style.display = "contents";
137
+ Array.from(section.children).forEach(child => child.style.width = "100%");
138
+ }
139
+ }
140
+
141
+ try {
142
+ //+ ADD FUNCTION
143
+ await this.loadPgsJavascript();
144
+ configureSearchDemo();
145
+ configureFormDemo();
146
+ } catch (error) {
147
+ console.error("Demo PGS non inizializzata.", error);
148
+ }
149
+ },
150
+ };
151
+
152
+ //= Search Demo
153
+ function configureSearchDemo() {
154
+ const pgsApi = globalThis.pgs;
155
+ const section = document.querySelector('[data-template="components/search.html"]');
156
+ if (!pgsApi?.search || !section) return;
157
+
158
+ pgsApi(section).querySelectorAll("search").forEach(search => {
159
+ pgsApi.search.api(search)?.configure({
160
+ minLength: 2,
161
+ debounce: 250,
162
+ source: async ({ query, signal, limit }) => {
163
+ const url = new URL("https://it.wikipedia.org/w/api.php");
164
+ url.search = new URLSearchParams({
165
+ action: "opensearch",
166
+ search: query,
167
+ limit: String(limit),
168
+ namespace: "0",
169
+ format: "json",
170
+ origin: "*",
171
+ });
172
+
173
+ const response = await fetch(url, { signal });
174
+ if (!response.ok) throw new Error(`Wikipedia HTTP ${response.status}`);
175
+
176
+ const payload = await response.json();
177
+ const suggestions = Array.isArray(payload?.[1]) ? payload[1] : [];
178
+ const descriptions = Array.isArray(payload?.[2]) ? payload[2] : [];
179
+ const links = Array.isArray(payload?.[3]) ? payload[3] : [];
180
+
181
+ return suggestions.map((suggestion, index) => ({
182
+ label: suggestion,
183
+ value: suggestion,
184
+ data: {
185
+ description: descriptions[index] ?? "",
186
+ url: links[index] ?? "",
187
+ },
188
+ }));
189
+ },
190
+ });
191
+ });
192
+
193
+ const note = document.createElement("small");
194
+ note.append("Suggerimenti dimostrativi forniti da ");
195
+ const link = document.createElement("a");
196
+ link.href = "https://www.mediawiki.org/wiki/API:Opensearch/it";
197
+ link.target = "_blank";
198
+ link.rel = "noopener noreferrer";
199
+ link.textContent = "Wikipedia OpenSearch";
200
+ note.append(link, ". Prova a scrivere prodotti di o come fare.");
201
+ section.append(note);
202
+ }
203
+
204
+ //= Form Demo
205
+ function configureFormDemo() {
206
+ const pgsApi = globalThis.pgs;
207
+ const section = document.querySelector('[data-template="components/form.html"]');
208
+ const form = section?.querySelector('[pgs~="form"]');
209
+ if (!form) return;
210
+
211
+ const password = form.querySelector('input[name="password"]');
212
+ const confirmPassword = form.querySelector('input[name="confirmPassword"]');
213
+ if (!password || !confirmPassword) return;
214
+
215
+ const formValidate = new pgsApi.formValidate(form, {
216
+ message: {
217
+ fieldError: "Completa questo campo",
218
+ fieldsError: "Completa tutti i campi obbligatori",
219
+ success: "Inviato con successo"
220
+ }
221
+ });
222
+
223
+ //== new roules
224
+ formValidate.addNewRule(() => {
225
+ if (password.value && confirmPassword.value && password.value !== confirmPassword.value) {
226
+ pgsApi(confirmPassword).option.setValueBrackets("message", "Le password non coincidono");
227
+ return [confirmPassword, password];
228
+ }
229
+ });
230
+
231
+ //== validate
232
+ formValidate.validator(event => {
233
+ const values = Object.fromEntries(new FormData(form));
234
+
235
+ //// Sostituisci questo log con l'invio dei dati al tuo backend.
236
+ console.log(values);
237
+ }, "submit");
238
+ }
239
+
240
+ demoRenderer.boot();