@schalkneethling/miyagi-core 4.0.2

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 (138) hide show
  1. package/LICENSE.md +21 -0
  2. package/README.md +43 -0
  3. package/api/app.js +39 -0
  4. package/api/index.js +236 -0
  5. package/bin/miyagi.js +2 -0
  6. package/dist/css/iframe.css +31 -0
  7. package/dist/css/main.css +1 -0
  8. package/dist/js/_iframe-links-DdifIr4P.js +1 -0
  9. package/dist/js/_mock-data-Dypo4Bl_.js +1 -0
  10. package/dist/js/_prism-By3NMwUd.js +1 -0
  11. package/dist/js/iframe.build.js +1 -0
  12. package/dist/js/iframe.js +1 -0
  13. package/dist/js/index-BKDKaBC6.js +1 -0
  14. package/dist/js/jsontree.js +1 -0
  15. package/dist/js/main.build.js +1 -0
  16. package/dist/js/main.js +1 -0
  17. package/frontend/assets/css/iframe/accordion-tabs.css +77 -0
  18. package/frontend/assets/css/iframe/jsontree.js.css +325 -0
  19. package/frontend/assets/css/iframe/prism.css +132 -0
  20. package/frontend/assets/css/iframe/styleguide/colors.css +61 -0
  21. package/frontend/assets/css/iframe/styleguide/fonts.css +37 -0
  22. package/frontend/assets/css/iframe/styleguide/index.css +109 -0
  23. package/frontend/assets/css/iframe/styleguide/spacings.css +21 -0
  24. package/frontend/assets/css/iframe.css +410 -0
  25. package/frontend/assets/css/main/menu/config-switcher.css +49 -0
  26. package/frontend/assets/css/main/menu/config-switchers.css +67 -0
  27. package/frontend/assets/css/main/menu/goto.css +24 -0
  28. package/frontend/assets/css/main/menu/nav.css +113 -0
  29. package/frontend/assets/css/main/menu/search.css +64 -0
  30. package/frontend/assets/css/main/menu/title.css +40 -0
  31. package/frontend/assets/css/main/menu.css +114 -0
  32. package/frontend/assets/css/main/reset.css +217 -0
  33. package/frontend/assets/css/main.css +71 -0
  34. package/frontend/assets/css/shared.css +34 -0
  35. package/frontend/assets/css/tokens.css +112 -0
  36. package/frontend/assets/favicon.ico +0 -0
  37. package/frontend/assets/js/_accordion-tabs.js +403 -0
  38. package/frontend/assets/js/_goto.js +63 -0
  39. package/frontend/assets/js/_iframe-links.js +19 -0
  40. package/frontend/assets/js/_is-triggered.js +15 -0
  41. package/frontend/assets/js/_main.js +379 -0
  42. package/frontend/assets/js/_mock-data.js +13 -0
  43. package/frontend/assets/js/_prism.js +1098 -0
  44. package/frontend/assets/js/_search.js +190 -0
  45. package/frontend/assets/js/_socket.js +9 -0
  46. package/frontend/assets/js/config-switcher/development-mode.js +49 -0
  47. package/frontend/assets/js/config-switcher/index.js +63 -0
  48. package/frontend/assets/js/config-switcher/text-direction.js +30 -0
  49. package/frontend/assets/js/config-switcher/theme.js +87 -0
  50. package/frontend/assets/js/iframe.build.js +43 -0
  51. package/frontend/assets/js/iframe.js +52 -0
  52. package/frontend/assets/js/jsontree.js +979 -0
  53. package/frontend/assets/js/main.build.js +40 -0
  54. package/frontend/assets/js/main.js +42 -0
  55. package/frontend/assets/js/styleguide/color-converter.js +741 -0
  56. package/frontend/assets/js/styleguide/index.js +119 -0
  57. package/frontend/views/component_variation.twig.miyagi +57 -0
  58. package/frontend/views/design-tokens/colors.twig.miyagi +43 -0
  59. package/frontend/views/design-tokens/sizes.twig.miyagi +35 -0
  60. package/frontend/views/design-tokens/typography.twig.miyagi +38 -0
  61. package/frontend/views/iframe_component.twig.miyagi +141 -0
  62. package/frontend/views/iframe_component_variation.twig.miyagi +55 -0
  63. package/frontend/views/iframe_index.twig.miyagi +14 -0
  64. package/frontend/views/layouts/iframe_default.twig.miyagi +22 -0
  65. package/frontend/views/main.twig.miyagi +24 -0
  66. package/frontend/views/menu/config-switchers.twig.miyagi +83 -0
  67. package/frontend/views/menu/goto.twig.miyagi +9 -0
  68. package/frontend/views/menu/menu.twig.miyagi +21 -0
  69. package/frontend/views/menu/nav.twig.miyagi +95 -0
  70. package/frontend/views/menu/search.twig.miyagi +13 -0
  71. package/frontend/views/menu/title.twig.miyagi +24 -0
  72. package/index.js +3 -0
  73. package/lib/build/index.js +1020 -0
  74. package/lib/cli/app.js +38 -0
  75. package/lib/cli/component.js +56 -0
  76. package/lib/cli/index.js +5 -0
  77. package/lib/cli/lint.js +180 -0
  78. package/lib/config.js +74 -0
  79. package/lib/default-config.js +105 -0
  80. package/lib/generator/component.js +199 -0
  81. package/lib/generator/mocks.js +201 -0
  82. package/lib/helpers.js +184 -0
  83. package/lib/i18n/en.js +91 -0
  84. package/lib/i18n/index.js +17 -0
  85. package/lib/index.js +166 -0
  86. package/lib/init/args.js +55 -0
  87. package/lib/init/config.js +330 -0
  88. package/lib/init/engines.js +65 -0
  89. package/lib/init/index.js +102 -0
  90. package/lib/init/rendering.js +12 -0
  91. package/lib/init/router.js +249 -0
  92. package/lib/init/static.js +133 -0
  93. package/lib/init/twing/cache.js +34 -0
  94. package/lib/init/twing/functions.js +51 -0
  95. package/lib/init/views.js +19 -0
  96. package/lib/init/watcher.js +402 -0
  97. package/lib/logger.js +94 -0
  98. package/lib/mocks/get.js +111 -0
  99. package/lib/mocks/index.js +9 -0
  100. package/lib/mocks/resolve/ref.js +484 -0
  101. package/lib/mocks/resolve/tpl.js +246 -0
  102. package/lib/mocks/resolve.js +205 -0
  103. package/lib/render/helpers.js +51 -0
  104. package/lib/render/index.js +38 -0
  105. package/lib/render/views/iframe/component.docs.js +77 -0
  106. package/lib/render/views/iframe/component.js +338 -0
  107. package/lib/render/views/iframe/design-tokens/colors.js +52 -0
  108. package/lib/render/views/iframe/design-tokens/index.js +9 -0
  109. package/lib/render/views/iframe/design-tokens/sizes.js +49 -0
  110. package/lib/render/views/iframe/design-tokens/typography.js +52 -0
  111. package/lib/render/views/iframe/docs.js +68 -0
  112. package/lib/render/views/iframe/index.js +44 -0
  113. package/lib/render/views/iframe/variation.js +116 -0
  114. package/lib/render/views/iframe/variation.standalone.js +89 -0
  115. package/lib/render/views/main/component.docs.js +53 -0
  116. package/lib/render/views/main/component.js +74 -0
  117. package/lib/render/views/main/design-tokens.js +53 -0
  118. package/lib/render/views/main/docs.js +47 -0
  119. package/lib/render/views/main/index.js +46 -0
  120. package/lib/state/components.js +132 -0
  121. package/lib/state/css.js +50 -0
  122. package/lib/state/docs.js +111 -0
  123. package/lib/state/file-contents.js +207 -0
  124. package/lib/state/helpers.js +86 -0
  125. package/lib/state/index.js +56 -0
  126. package/lib/state/menu/index.js +275 -0
  127. package/lib/state/menu/structure.js +146 -0
  128. package/lib/state/partials.js +23 -0
  129. package/lib/state/source-tree.js +75 -0
  130. package/lib/styleguide/color-names.js +150 -0
  131. package/lib/styleguide/colors.js +135 -0
  132. package/lib/styleguide/helpers.js +37 -0
  133. package/lib/styleguide/index.js +17 -0
  134. package/lib/styleguide/media-queries.js +26 -0
  135. package/lib/styleguide/spacings.js +35 -0
  136. package/lib/styleguide/typography.js +61 -0
  137. package/lib/validator/mocks.js +105 -0
  138. package/package.json +117 -0
@@ -0,0 +1,403 @@
1
+ customElements.define(
2
+ "accordion-tabs",
3
+ class AccordionTabs extends HTMLElement {
4
+ #accordion;
5
+ #breakpoint;
6
+ #prevMode;
7
+ #resizeObserver;
8
+ #tabs;
9
+
10
+ static get observedAttributes() {
11
+ return ["breakpoint", "current"];
12
+ }
13
+
14
+ constructor() {
15
+ super();
16
+ }
17
+
18
+ connectedCallback() {
19
+ if (this.closest("code")) return;
20
+
21
+ this.content = [];
22
+
23
+ if (this.hasAttribute("breakpoint")) {
24
+ const breakpoint = this.getAttribute("breakpoint");
25
+ const bpParsed = parseInt(breakpoint, 10);
26
+ let result;
27
+
28
+ if (breakpoint.endsWith("rem")) {
29
+ result =
30
+ bpParsed *
31
+ parseInt(
32
+ window.getComputedStyle(document.documentElement).fontSize,
33
+ 10,
34
+ );
35
+ } else if (breakpoint.endsWith("em")) {
36
+ result =
37
+ bpParsed * parseInt(window.getComputedStyle(this).fontSize, 10);
38
+ } else {
39
+ result = bpParsed;
40
+ }
41
+
42
+ this.#breakpoint = result;
43
+ }
44
+
45
+ window.requestAnimationFrame(() => {
46
+ this.details = Array.from(this.children);
47
+
48
+ this.details.forEach((child, i) => {
49
+ const title = child.querySelector("summary");
50
+
51
+ if (child.open) {
52
+ this.index = i;
53
+ }
54
+
55
+ this.content.push({
56
+ title: title.textContent,
57
+ content: [...title.parentElement.children].filter(
58
+ (el) => el.nodeType === 1 && el !== title,
59
+ ),
60
+ });
61
+ });
62
+
63
+ let initialized = false;
64
+
65
+ this.#resizeObserver = new ResizeObserver((entries) => {
66
+ if (initialized) {
67
+ for (const entry of entries) {
68
+ this.#render(entry.borderBoxSize[0].inlineSize);
69
+ }
70
+ }
71
+
72
+ initialized = true;
73
+ });
74
+
75
+ this.#render(this.clientWidth, () => {
76
+ this.#resizeObserver.observe(this);
77
+ });
78
+ });
79
+ }
80
+
81
+ attributeChangedCallback(attr, oldValue, newValue) {
82
+ if (attr === "current") {
83
+ this.index = parseInt(newValue, 10);
84
+ this.#render(this.clientWidth);
85
+ }
86
+ }
87
+
88
+ disconnectedCallback() {
89
+ if (this.#resizeObserver) {
90
+ this.#resizeObserver.disconnect();
91
+ }
92
+ }
93
+
94
+ async #render(width, cb) {
95
+ if (!this.#breakpoint || width < this.#breakpoint) {
96
+ await this.#renderAccordion();
97
+ this.#prevMode = "accordion";
98
+ } else {
99
+ await this.#renderTabs();
100
+ this.#prevMode = "tabs";
101
+ }
102
+
103
+ if (cb) {
104
+ cb();
105
+ }
106
+ }
107
+
108
+ #renderAccordion() {
109
+ if (!this.#accordion) {
110
+ this.#accordion = new AccordionTabsAccordion(this);
111
+ }
112
+
113
+ if (this.#prevMode === "tabs") {
114
+ this.#clear();
115
+
116
+ this.#accordion.setElements();
117
+
118
+ this.#accordion.elements.forEach((detail) => this.appendChild(detail));
119
+ } else {
120
+ this.#accordion.render();
121
+ }
122
+
123
+ return true;
124
+ }
125
+
126
+ async #renderTabs() {
127
+ this.#clear();
128
+
129
+ if (this.#tabs) {
130
+ this.#tabs.index = typeof this.index === "number" ? this.index : 0;
131
+ this.#tabs.setElements();
132
+ } else {
133
+ this.#tabs = new AccordionTabsTabs(this);
134
+ }
135
+
136
+ const [ol, content] = this.#tabs.elements;
137
+
138
+ this.appendChild(ol);
139
+
140
+ content.forEach((item) => {
141
+ this.appendChild(item);
142
+ });
143
+
144
+ return await this.#tabs.render(false);
145
+ }
146
+
147
+ #clear() {
148
+ Array.from(this.children).forEach((child) => this.removeChild(child));
149
+ }
150
+ },
151
+ );
152
+
153
+ class AccordionTabsAccordion {
154
+ constructor(AccordionTabs) {
155
+ this.AccordionTabs = AccordionTabs;
156
+ this.elements = this.AccordionTabs.details;
157
+
158
+ this.elements.forEach((detail, i) => {
159
+ detail
160
+ .querySelector("summary")
161
+ .addEventListener("click", ({ target }) => {
162
+ requestAnimationFrame(() => {
163
+ this.#onToggle(target.closest("details"), i);
164
+ });
165
+ });
166
+ });
167
+
168
+ this.render();
169
+ }
170
+
171
+ setElements() {
172
+ this.elements.forEach((detail, i) => {
173
+ this.AccordionTabs.content[i].content.forEach((item) =>
174
+ detail.appendChild(item),
175
+ );
176
+
177
+ detail.open = i === this.AccordionTabs.index;
178
+ });
179
+ }
180
+
181
+ render() {
182
+ this.elements.forEach((el, i) => {
183
+ el.open = i === this.AccordionTabs.index;
184
+ });
185
+ }
186
+
187
+ #onToggle(element, i) {
188
+ if (element.open) {
189
+ this.elements.forEach((el) => {
190
+ if (element !== el) {
191
+ el.open = false;
192
+ }
193
+ });
194
+ this.AccordionTabs.index = i;
195
+ } else {
196
+ this.AccordionTabs.index = null;
197
+ }
198
+ }
199
+ }
200
+
201
+ class AccordionTabsTabs {
202
+ #AccordionTabs;
203
+ #buttons = [];
204
+ #divs = [];
205
+ #TabsList;
206
+
207
+ constructor(AccordionTabs) {
208
+ this.#AccordionTabs = AccordionTabs;
209
+ this.elements = this.getElements();
210
+ this.index =
211
+ typeof this.#AccordionTabs.index === "number"
212
+ ? this.#AccordionTabs.index
213
+ : 0;
214
+
215
+ this.#TabsList = new AccordionTabsList(this);
216
+ }
217
+
218
+ getElements() {
219
+ const ol = document.createElement("ol");
220
+ const arr = [];
221
+
222
+ this.#AccordionTabs.content.forEach(({ title, content }, i) => {
223
+ const button = document.createElement("button");
224
+ const li = document.createElement("li");
225
+ const div = document.createElement("div");
226
+
227
+ const id = crypto.randomUUID();
228
+ const idTab = `tab-${id}`;
229
+ const idPanel = `panel-${id}`;
230
+
231
+ ol.setAttribute("role", "tablist");
232
+ li.setAttribute("role", "presentation");
233
+
234
+ button.textContent = title;
235
+ button.type = "button";
236
+ button.id = idTab;
237
+ button.setAttribute("aria-selected", i === this.index ? "true" : "false");
238
+ button.setAttribute("tabindex", i === this.index ? 0 : -1);
239
+ button.setAttribute("aria-controls", idPanel);
240
+ button.setAttribute("role", "tab");
241
+ this.#buttons.push(button);
242
+
243
+ li.appendChild(button);
244
+ ol.appendChild(li);
245
+
246
+ content.forEach((item) => {
247
+ div.appendChild(item);
248
+ });
249
+
250
+ div.id = idPanel;
251
+ div.hidden = this.index !== i;
252
+ div.setAttribute("role", "tabpanel");
253
+ div.setAttribute("tabindex", "0");
254
+ div.setAttribute("aria-labelledby", idTab);
255
+
256
+ arr.push(div);
257
+ this.#divs.push(div);
258
+ });
259
+
260
+ return [ol, arr];
261
+ }
262
+
263
+ setElements() {
264
+ this.elements[1].forEach((div, i) => {
265
+ this.#AccordionTabs.content[i].content.forEach((item) =>
266
+ div.appendChild(item),
267
+ );
268
+ });
269
+ }
270
+
271
+ /**
272
+ * @param {number} activeTab
273
+ */
274
+ setActiveTab(activeTab) {
275
+ this.#AccordionTabs.index = this.index = activeTab;
276
+
277
+ this.render();
278
+ }
279
+
280
+ /**
281
+ * @returns {void}
282
+ */
283
+ async render(focus = true) {
284
+ this.elements[1].forEach((tabpanel, i) => {
285
+ tabpanel.hidden = i !== this.index;
286
+ });
287
+
288
+ return await this.#TabsList.render(focus);
289
+ }
290
+ }
291
+
292
+ class AccordionTabsList {
293
+ #Tabs;
294
+ #elements;
295
+
296
+ /**
297
+ * @param {object} Tabs
298
+ */
299
+ constructor(Tabs) {
300
+ this.#Tabs = Tabs;
301
+
302
+ this.#elements = Array.from(
303
+ this.#Tabs.elements[0].querySelectorAll("button"),
304
+ );
305
+
306
+ this.#elements.forEach((button) => {
307
+ button.addEventListener("click", this.#onClick.bind(this));
308
+ button.addEventListener("keydown", this.#onKeydown.bind(this));
309
+ });
310
+ }
311
+
312
+ /**
313
+ * @param {Event} object
314
+ * @param {HTMLButtonElement} object.currentTarget
315
+ */
316
+ #onClick({ currentTarget }) {
317
+ this.#Tabs.setActiveTab(this.#elements.indexOf(currentTarget));
318
+ }
319
+
320
+ /**
321
+ * @param {Event} event
322
+ */
323
+ #onKeydown(event) {
324
+ const { dir } = event.target.closest("[dir]") || document.documentElement;
325
+ let flag = false;
326
+
327
+ switch (event.key) {
328
+ case "ArrowLeft":
329
+ if (dir === "rtl") {
330
+ this.#setNextTab();
331
+ } else {
332
+ this.#setPreviousTab();
333
+ }
334
+ flag = true;
335
+ break;
336
+
337
+ case "ArrowRight":
338
+ if (dir === "rtl") {
339
+ this.#setPreviousTab();
340
+ } else {
341
+ this.#setNextTab();
342
+ }
343
+ flag = true;
344
+ break;
345
+
346
+ case "Home":
347
+ this.#Tabs.setActiveTab(0);
348
+ flag = true;
349
+ break;
350
+
351
+ case "End":
352
+ this.#Tabs.setActiveTab(this.#elements.length - 1);
353
+ flag = true;
354
+ break;
355
+
356
+ default:
357
+ break;
358
+ }
359
+
360
+ if (flag) {
361
+ event.stopPropagation();
362
+ event.preventDefault();
363
+ }
364
+ }
365
+
366
+ /**
367
+ * @returns {void}
368
+ */
369
+ #setNextTab() {
370
+ this.#Tabs.setActiveTab(
371
+ this.#Tabs.index === this.#elements.length - 1 ? 0 : this.#Tabs.index + 1,
372
+ );
373
+ }
374
+
375
+ /**
376
+ * @returns {void}
377
+ */
378
+ #setPreviousTab() {
379
+ this.#Tabs.setActiveTab(
380
+ this.#Tabs.index === 0 ? this.#elements.length - 1 : this.#Tabs.index - 1,
381
+ );
382
+ }
383
+
384
+ /**
385
+ * @returns {void}
386
+ */
387
+ render(focus = true) {
388
+ this.#elements.forEach((button, i) => {
389
+ if (i === this.#Tabs.index) {
390
+ button.setAttribute("aria-selected", "true");
391
+ button.removeAttribute("tabindex");
392
+ if (focus) {
393
+ button.focus();
394
+ }
395
+ } else {
396
+ button.setAttribute("aria-selected", "false");
397
+ button.setAttribute("tabindex", -1);
398
+ }
399
+ });
400
+
401
+ return new Promise((resolve) => setTimeout(resolve, 1000));
402
+ }
403
+ }
@@ -0,0 +1,63 @@
1
+ import { goto as gotoIsTriggered } from "./_is-triggered.js";
2
+
3
+ document.addEventListener("DOMContentLoaded", () => {
4
+ const GOTO = document.querySelector(".GoTo");
5
+ let isOpen = false;
6
+
7
+ if (GOTO) {
8
+ const URL_PATTERN = GOTO.dataset.urlPattern;
9
+ const INPUT = GOTO.querySelector(".GoTo-input");
10
+ const DATA_LIST = GOTO.querySelector("#goto-list");
11
+
12
+ if (INPUT && DATA_LIST) {
13
+ const VALUES = Array.from(DATA_LIST.querySelectorAll("option")).map(
14
+ (el) => el.value,
15
+ );
16
+
17
+ INPUT.addEventListener("input", ({ target }) => {
18
+ const VALUE = target.value;
19
+
20
+ if (VALUES.includes(VALUE)) {
21
+ document.location.href = URL_PATTERN.replace("{{component}}", VALUE);
22
+ }
23
+ });
24
+
25
+ window.addEventListener("keyup", (e) => {
26
+ const { path, originalTarget, target, key } = e;
27
+
28
+ if (key) {
29
+ const el = path ? path[0] : originalTarget || target;
30
+ const lowerCasedKey = key.toLowerCase();
31
+
32
+ if (gotoIsTriggered(el, lowerCasedKey)) {
33
+ openGoto(GOTO, INPUT);
34
+ } else if (isOpen && lowerCasedKey === "escape") {
35
+ closeGoto(GOTO, INPUT);
36
+ }
37
+ }
38
+ });
39
+ window.addEventListener("gotoTriggered", () => openGoto(GOTO, INPUT));
40
+ }
41
+ }
42
+
43
+ /**
44
+ * @param {HTMLFormElement} goto
45
+ * @param {HTMLInputElement} input
46
+ */
47
+ function openGoto(goto, input) {
48
+ goto.classList.remove("u-hiddenVisually");
49
+ input.focus();
50
+ isOpen = true;
51
+ }
52
+
53
+ /**
54
+ * @param {HTMLFormElement} goto
55
+ * @param {HTMLInputElement} input
56
+ */
57
+ function closeGoto(goto, input) {
58
+ GOTO.classList.add("u-hiddenVisually");
59
+ input.value = "";
60
+ input.blur();
61
+ isOpen = false;
62
+ }
63
+ });
@@ -0,0 +1,19 @@
1
+ export default (links) => {
2
+ if (parent.window) {
3
+ const linkClass = "Component-file";
4
+
5
+ links.forEach((link) => {
6
+ link.addEventListener("click", (e) => {
7
+ const el = e.target.closest(`.${linkClass}`);
8
+
9
+ history.replaceState(null, null, el.href); // see http://www.webdeveasy.com/back-button-behavior-on-a-page-with-an-iframe/
10
+
11
+ parent.window.dispatchEvent(
12
+ new CustomEvent("pageChanged", {
13
+ detail: encodeURI(el.getAttribute("href")),
14
+ }),
15
+ );
16
+ });
17
+ });
18
+ }
19
+ };
@@ -0,0 +1,15 @@
1
+ export const search = (target, key) => {
2
+ return !checkIfTriggeredElementWasFormElement(target.tagName) && key === "f";
3
+ };
4
+
5
+ export const goto = (target, key) => {
6
+ return !checkIfTriggeredElementWasFormElement(target.tagName) && key === "g";
7
+ };
8
+
9
+ /**
10
+ * @param {HTMLElement} tagName
11
+ * @returns {boolean}
12
+ */
13
+ function checkIfTriggeredElementWasFormElement(tagName) {
14
+ return ["INPUT", "SELECT", "TEXTAREA"].includes(tagName);
15
+ }