@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,119 @@
1
+ import ColorConverter from "./color-converter.js";
2
+
3
+ class Styleguide {
4
+ /**
5
+ * @param {HTMLElement} element
6
+ */
7
+ constructor(element) {
8
+ this.element = element;
9
+ this.items = Array.from(this.element.querySelectorAll(".CustomProp"));
10
+ this.colors = Array.from(this.element.querySelectorAll(".Colors-item"));
11
+ this.fonts = Array.from(this.element.querySelectorAll(".Fonts-item"));
12
+ this.spacings = Array.from(this.element.querySelectorAll(".Spacings-item"));
13
+ this.buttons = Array.from(
14
+ this.element.querySelectorAll(".CustomProp-button"),
15
+ );
16
+ this.details = Array.from(
17
+ this.element.querySelectorAll(".CustomProp-details"),
18
+ );
19
+
20
+ this.renderValues();
21
+ this.element.dataset.mediaQueries.split(",").forEach((mq) => {
22
+ const mql = window.matchMedia(mq);
23
+ mql.addEventListener("change", this.renderValues.bind(this));
24
+ });
25
+
26
+ this.element.addEventListener("click", ({ target }) => {
27
+ const item = target.closest(".CustomProp");
28
+ const button = target.closest(".CustomProp-button");
29
+ const details = target.closest(".CustomProp-details");
30
+
31
+ if (button) {
32
+ this.items.forEach((i) => {
33
+ if (i !== item) i.setAttribute("aria-selected", false);
34
+ });
35
+ this.buttons.forEach((b) => {
36
+ if (b !== button) b.setAttribute("aria-expanded", false);
37
+ });
38
+ this.details.forEach((d) => {
39
+ if (d !== details) d.hidden = true;
40
+ });
41
+
42
+ const isExpanded = button.getAttribute("aria-expanded") === "true";
43
+
44
+ document.getElementById(button.getAttribute("aria-controls")).hidden =
45
+ isExpanded;
46
+
47
+ item.setAttribute("aria-selected", !isExpanded);
48
+ button.setAttribute("aria-expanded", !isExpanded);
49
+ } else {
50
+ if (!item) {
51
+ this.items.forEach((b) => {
52
+ b.setAttribute("aria-selected", false);
53
+ });
54
+ this.buttons.forEach((b) => {
55
+ b.setAttribute("aria-expanded", false);
56
+ });
57
+ this.details.forEach((d) => {
58
+ d.hidden = true;
59
+ });
60
+ }
61
+ }
62
+ });
63
+ }
64
+
65
+ /**
66
+ *
67
+ */
68
+ renderValues() {
69
+ this.renderColorValues();
70
+ this.renderFontValues();
71
+ this.renderSpacingValues();
72
+ }
73
+
74
+ /**
75
+ *
76
+ */
77
+ renderColorValues() {
78
+ this.colors.forEach((item) => {
79
+ const color = getComputedStyle(item).getPropertyValue("--color").trim();
80
+
81
+ item.querySelector('[data-value="RGB"]').textContent =
82
+ ColorConverter(color).toRgbString();
83
+
84
+ item.querySelector('[data-value="Hex"]').textContent =
85
+ ColorConverter(color).toHexString();
86
+
87
+ item.querySelector('[data-value="HSL"]').textContent =
88
+ ColorConverter(color).toHslString();
89
+ });
90
+ }
91
+
92
+ /**
93
+ *
94
+ */
95
+ renderFontValues() {
96
+ this.fonts.forEach((font) => {
97
+ Array.from(font.querySelectorAll("[data-value]")).forEach((item) => {
98
+ item.textContent = getComputedStyle(item)
99
+ .getPropertyValue(item.dataset.value)
100
+ .trim();
101
+ });
102
+ });
103
+ }
104
+
105
+ /**
106
+ *
107
+ */
108
+ renderSpacingValues() {
109
+ this.spacings.forEach((font) => {
110
+ Array.from(font.querySelectorAll("[data-value]")).forEach((item) => {
111
+ item.textContent = getComputedStyle(item)
112
+ .getPropertyValue(item.dataset.value)
113
+ .trim();
114
+ });
115
+ });
116
+ }
117
+ }
118
+
119
+ export default Styleguide;
@@ -0,0 +1,57 @@
1
+ <!DOCTYPE html>
2
+ <html class="theme-{{ userUiConfig.theme }}" lang="{{ componentLanguage }}" dir="{{ userUiConfig.componentTextDirection }}">
3
+ <head>
4
+ <meta charset="utf-8">
5
+ <meta name="viewport" content="initial-scale=1,width=device-width">
6
+ <title>Component</title>
7
+ {% for file in jsFilesHead %}
8
+ {% set type_str = file.type ? ' type="' ~ file.type ~ '"' : "" %}
9
+ {% set defer_str = file.defer ? "defer" : "" %}
10
+ {% set async_str = file.async ? "async" : "" %}
11
+ <script src="{{ file.src }}"{{ type_str ~ defer_str ~ async_str }}></script>
12
+ {% endfor %}
13
+ <script src="{{ projectName }}/js/iframe{% if isBuild %}.build{% endif %}.js" {% if miyagiDev %} type="module"
14
+ {% endif %}{% if prod %} defer{% endif %}></script>
15
+ {% for file in cssFiles %}
16
+ <link rel="stylesheet" href="{{ file }}">
17
+ {% endfor %}
18
+ <style>
19
+ {{ theme.css }}
20
+ </style>
21
+ {% if assets.css %}
22
+ <link href="{{ assets.css }}" rel="stylesheet">
23
+ {% endif %}
24
+ {% if assets.js %}
25
+ <script src="{{ assets.js }}"></script>
26
+ {% endif %}
27
+ <script>
28
+ {{ theme.js }}
29
+
30
+ function sendHeightToParent() {
31
+ window.parent.postMessage({
32
+ id: window.frameElement.parentNode.id,
33
+ height: document.body.offsetHeight
34
+ }, "*");
35
+ }
36
+
37
+ if (window.frameElement) {
38
+ document.addEventListener("DOMContentLoaded", sendHeightToParent);
39
+ window.addEventListener("load", sendHeightToParent);
40
+ }
41
+ </script>
42
+ </head>
43
+
44
+ <body>
45
+ {{ html }}
46
+ {% if error %}
47
+ <p class="Error">{{ error }}</p>
48
+ {% endif %}
49
+ {% for file in jsFilesBody %}
50
+ {% set type_str = file.type ? ' type="' ~ file.type ~ '"' : "" %}
51
+ {% set defer_str = file.defer ? "defer" : "" %}
52
+ {% set async_str = file.async ? "async" : "" %}
53
+ <script src="{{ file.src }}"{{ type_str ~ defer_str ~ async_str }}></script>
54
+ {% endfor %}
55
+ </body>
56
+
57
+ </html>
@@ -0,0 +1,43 @@
1
+ {% extends "@miyagi/layouts/iframe_default.twig.miyagi" %}
2
+ {% block additionalCss %}
3
+ {% for file in additionalCssFiles %}
4
+ <link rel="stylesheet" href="/{{ file }}">
5
+ {% endfor %}
6
+ {% endblock %}
7
+ {% block body %}
8
+ {% if colors %}
9
+ <div class="Wrapper">
10
+ <div class="Styleguide" data-media-queries='{{ mediaQueries }}'>
11
+ <div class="Documentation">
12
+ <h1>Colors</h1>
13
+ </div>
14
+ {% for color in colors %}
15
+ {% if color.styles is not empty %}
16
+ <ul class="CustomPropsGroup Colors Colors--{{ color.type }}">
17
+ {% for style in color.styles %}
18
+ {% if style.customProp %}
19
+ <li class="CustomProp Colors-item"
20
+ style="--color: var({{ style.customProp }});{% if style.isWhite %} --backdrop: #000;{% endif %}">
21
+ <button class="CustomProp-button Colors-button"
22
+ aria-controls="styleguide-color-{{ style.name }}" aria-expanded="false" {% if style.type %}
23
+ data-type="{{ style.type }}" {% endif %}>
24
+ <span class="Colors-prop CustomProp-prop">{{ style.name }}</span>
25
+ </button>
26
+ <dl class="CustomProp-details" id="styleguide-color-{{ style.name }}" hidden>
27
+ <dt class="CustomProp-detailsProperty">Name</dt>
28
+ <dd class="CustomProp-detailsValue">{{ style.customProp }}</dd>
29
+ {% for value in style.values %}
30
+ <dt class="CustomProp-detailsProperty">{{ value }}</dt>
31
+ <dd class="CustomProp-detailsValue" data-value="{{ value }}"></dd>
32
+ {% endfor %}
33
+ </dl>
34
+ </li>
35
+ {% endif %}
36
+ {% endfor %}
37
+ </ul>
38
+ {% endif %}
39
+ {% endfor %}
40
+ </div>
41
+ </div>
42
+ {% endif %}
43
+ {% endblock %}
@@ -0,0 +1,35 @@
1
+ {% extends "@miyagi/layouts/iframe_default.twig.miyagi" %}
2
+ {% block additionalCss %}
3
+ {% for file in additionalCssFiles %}
4
+ <link rel="stylesheet" href="/{{ file }}">
5
+ {% endfor %}
6
+ {% endblock %}
7
+ {% block body %}
8
+ {% if spacings %}
9
+ <div class="Wrapper">
10
+ <div class="Styleguide" data-media-queries='{{ mediaQueries }}'>
11
+ <div class="Documentation">
12
+ <h1>Spacings</h1>
13
+ </div>
14
+ <ul class="CustomPropsGroup Spacings">
15
+ {% for spacing in spacings %}
16
+ {% if spacing[1].customProp %}
17
+ <li class="CustomProp Spacings-item" style="--spacing: var({{ spacing[1].customProp }});">
18
+ <button class="Spacings-button CustomProp-button"
19
+ aria-controls="styleguide-spacings-{{ spacing[0] }}" aria-expanded="false">
20
+ <span class="Spacings-prop CustomProp-prop">{{ spacing[0] }}</span>
21
+ </button>
22
+ <dl class="CustomProp-details" id="styleguide-spacings-{{ spacing[0] }}" hidden>
23
+ <dt class="CustomProp-detailsProperty">Name</dt>
24
+ <dd class="CustomProp-detailsValue">{{ spacing[1].customProp }}</dd>
25
+ <dt class="CustomProp-detailsProperty">Size</dt>
26
+ <dd class="CustomProp-detailsValue" data-value="{{ spacing[1].customProp }}"></dd>
27
+ </dl>
28
+ </li>
29
+ {% endif %}
30
+ {% endfor %}
31
+ </ul>
32
+ </div>
33
+ </div>
34
+ {% endif %}
35
+ {% endblock %}
@@ -0,0 +1,38 @@
1
+ {% extends "@miyagi/layouts/iframe_default.twig.miyagi" %}
2
+ {% block additionalCss %}
3
+ {% for file in additionalCssFiles %}
4
+ <link rel="stylesheet" href="/{{ file }}">
5
+ {% endfor %}
6
+ {% endblock %}
7
+ {% block body %}
8
+ {% if typography %}
9
+ <div class="Wrapper">
10
+ <div class="Styleguide" data-media-queries='{{ mediaQueries }}'>
11
+ <div class="Documentation">
12
+ <h1>Typography</h1>
13
+ </div>
14
+ <ul class="CustomPropsGroup Fonts">
15
+ {% for typo in typography %}
16
+ {% if typo[1].customProp %}
17
+ <li class="CustomProp Fonts-item"
18
+ style='{% for value in typo[1].values %}--{{ value.label }}: var({{ value.value }});{% endfor %}'>
19
+ <button class="Fonts-button CustomProp-button"
20
+ aria-controls="styleguide-fonts-{{ typo[0] }}" aria-expanded="false">
21
+ <span class="Fonts-prop CustomProp-prop">{{ typo[0] }}</span>
22
+ </button>
23
+ <dl class="CustomProp-details" id="styleguide-fonts-{{ typo[0] }}" hidden>
24
+ <dt class="CustomProp-detailsProperty">Name</dt>
25
+ <dd class="CustomProp-detailsValue">{{ typo[1].customProp }}</dd>
26
+ {% for value in typo[1].values %}
27
+ <dt class="CustomProp-detailsProperty">{{ value.label }}</dt>
28
+ <dd class="CustomProp-detailsValue" data-value="{{ value.value }}"></dd>
29
+ {% endfor %}
30
+ </dl>
31
+ </li>
32
+ {% endif %}
33
+ {% endfor %}
34
+ </ul>
35
+ </div>
36
+ </div>
37
+ {% endif %}
38
+ {% endblock %}
@@ -0,0 +1,141 @@
1
+ {% extends "@miyagi/layouts/iframe_default.twig.miyagi" %}
2
+ {% block body %}
3
+ <main class="Wrapper">
4
+ <div class="Documentation">
5
+ {% if name %}
6
+ <h1>{{ name }}</h1>
7
+ {% endif %}
8
+ {% if documentation %}
9
+ {{ documentation }}
10
+ {% endif %}
11
+ </div>
12
+ <div class="DeveloperInformation">
13
+ {% if renderInformation %}
14
+ <h2 class="SectionTitle">Information</h2>
15
+ <dl class="Information">
16
+ <div class="Information-wrapper">
17
+ <dt class="Information-attr">Folder</dt>
18
+ <dd class="Information-val"><code>{{ folder }}</code></dd>
19
+ </div>
20
+ </dl>
21
+ {% endif %}
22
+ {% if renderFileTabs %}
23
+ <h2 class="SectionTitle">Files</h2>
24
+ <div class="Tabs">
25
+ {% if schema %}
26
+ <details class="Tabs-tab">
27
+ <summary>Schema</summary>
28
+ <div id="json-tree-resolved-schema" data-jsontree-js="jsontree.schema"></div>
29
+ </details>
30
+ {% endif %}
31
+ {% if mocks %}
32
+ <details class="Tabs-tab">
33
+ <summary>Mocks</summary>
34
+ <div id="json-tree-resolved-mocks" data-jsontree-js="jsontree.mocks"></div>
35
+ </details>
36
+ {% endif %}
37
+ {% if template %}
38
+ <details class="Tabs-tab">
39
+ <summary>Template</summary>
40
+ <pre class="Code language-{{ template.type }}"><span class="token comment">// {{ template.file }}</span>
41
+
42
+ <code>{{ template.string|escape }}</code></pre>
43
+ </details>
44
+ {% endif %}
45
+ </div>
46
+ {% if schemaError %}
47
+ <p class="ErrorMessage">{{ schemaError }}</p>
48
+ {% endif %}
49
+ {% endif %}
50
+ </div>
51
+ {% if variations %}
52
+ <h2 class="SectionTitle">Variants</h2>
53
+ {% endif %}
54
+ {% for variation in variations %}
55
+ <div class="Component">
56
+ <div class="Component-head">
57
+ <a href="{{ variation.url }}" class="Component-file">{{ variation.variation }}</a>
58
+ <div class="Component-headMeta">
59
+ <div class="DeveloperInformation">
60
+ {% if variation.mockValidation %}
61
+ <button class="Component-mockValidation js-openMockData" aria-controls="{{ variation.normalizedVariation }}">
62
+ <span class="Status Status--{% if variation.mockValidation.valid %}valid{% else %}invalid{% endif %}">{% if variation.mockValidation.valid %}Valid{% else %}Invalid{% endif %} mock data</span>
63
+ </button>
64
+ {% else %}
65
+ <button class="Component-mockValidation js-openMockData" aria-controls="{{ variation.normalizedVariation }}">
66
+ Mock data
67
+ </button>
68
+ {% endif %}
69
+ </div>
70
+ <a class="Iframe-newTabLink" href="{{ variation.standaloneUrl }}" target="_blank" rel="noopener">
71
+ Open
72
+ </a>
73
+ </div>
74
+ <dialog class="Component-mockData" id="{{ variation.normalizedVariation }}">
75
+ <div class="Component-mockDataInner">
76
+ <p class="Component-mockDataHeading"><b>{{ variation.variation }}</b> mock data</p>
77
+ <accordion-tabs breakpoint="24rem">
78
+ <details>
79
+ <summary>Raw</summary>
80
+ <div id="json-tree-{{ loop.index }}" data-jsontree-js="jsontree_{{ variation.normalizedVariation|replace({ '-': '_' }) }}.raw"></div>
81
+ </details>
82
+ <details>
83
+ <summary>Resolved</summary>
84
+ <div id="json-tree-resolved-{{ loop.index }}" data-jsontree-js="jsontree_{{ variation.normalizedVariation|replace({ '-': '_' }) }}.resolved"></div>
85
+ </details>
86
+ </accordion-tabs>
87
+ <form method="dialog">
88
+ <button class="Component-closeMockData">Close</button>
89
+ </form>
90
+ </div>
91
+ </dialog>
92
+ </div>
93
+ <div class="Component-iframeWrapper" id="{{ variation.normalizedVariation }}-iframe">
94
+ <iframe class="Component-iframe" src="{{ variation.standaloneUrl }}" frameborder="0" title="{{ variation.variation }}" id="iframe" loading="lazy"></iframe>
95
+ </div>
96
+ </div>
97
+ <script>
98
+ const jsontree_{{ variation.normalizedVariation|replace({ '-': '_' }) }} = {
99
+ "raw": {
100
+ "data": {{ variation.mockData|default({})|raw }}
101
+ },
102
+ "resolved": {
103
+ "data": {{ variation.mockDataResolved|default({})|replace({'</script>': '<\\/script>'})|raw }}
104
+ }
105
+ };
106
+ </script>
107
+ {% endfor %}
108
+ </main>
109
+ <script src="{{ projectName }}/js/jsontree.js"></script>
110
+ <script>
111
+ const eventMethod = window.addEventListener
112
+ ? "addEventListener"
113
+ : "attachEvent";
114
+ const eventer = window[eventMethod];
115
+ const messageEvent = eventMethod == "attachEvent" ? "onmessage" : "message";
116
+ const windowHeight = window.innerHeight;
117
+
118
+ eventer(
119
+ messageEvent,
120
+ function (e) {
121
+ const el = document.getElementById(e.data.id);
122
+
123
+ if (el && e.data.height < windowHeight) {
124
+ el.classList.add("has-fixedHeight");
125
+ el.style.height = `${e.data.height}px`;
126
+ }
127
+ },
128
+ false
129
+ );
130
+ </script>
131
+ <script>
132
+ const jsontree = {
133
+ "schema": {
134
+ "data": {{ schema|default({})|raw }}
135
+ },
136
+ "mocks": {
137
+ "data": {{ mocks|default({})|replace({'</script>': '<\\/script>'})|raw }}
138
+ }
139
+ };
140
+ </script>
141
+ {% endblock %}
@@ -0,0 +1,55 @@
1
+ {% extends "@miyagi/layouts/iframe_default.twig.miyagi" %}
2
+ {% block body %}
3
+ <div class="Wrapper">
4
+ <div id="Component" class="ComponentView">
5
+ <iframe src="{{ standaloneUrl }}" frameborder="0" class="ComponentView-iframe" title="Variation" id="iframe"></iframe>
6
+ </div>
7
+ </div>
8
+ <div class="Component">
9
+ <div class="Component-variationHeader">
10
+ <div class="DeveloperInformation">
11
+ {% if mockValidation %}
12
+ <button class="Component-mockValidation js-openMockData" aria-controls="{{ normalizedVariation }}">
13
+ <span class="Status Status--{% if mockValidation.valid %}valid{% else %}invalid{% endif %}">{% if mockValidation.valid %}Valid{% else %}Invalid{% endif %} mock data</span>
14
+ </button>
15
+ {% else %}
16
+ <button class="Component-mockValidation js-openMockData" aria-controls="{{ normalizedVariation }}">
17
+ Mock data
18
+ </button>
19
+ {% endif %}
20
+ </div>
21
+ <a class="Iframe-newTabLink" href="{{ standaloneUrl }}" target="_blank" rel="noopener">
22
+ Open
23
+ </a>
24
+ </div>
25
+ <dialog class="Component-mockData" id="{{ normalizedVariation }}">
26
+ <div class="Component-mockDataInner">
27
+ <p class="Component-mockDataHeading"><b>{{ variation }}</b> mock data</p>
28
+ <accordion-tabs breakpoint="24rem">
29
+ <details>
30
+ <summary>Raw</summary>
31
+ <div id="json-tree-mock" data-jsontree-js="jsontree_{{ normalizedVariation|replace({ '-': '_' }) }}.raw"></div>
32
+ </details>
33
+ <details>
34
+ <summary>Resolved</summary>
35
+ <div id="json-tree-resolved-mockResolved" data-jsontree-js="jsontree_{{ normalizedVariation|replace({ '-': '_' }) }}.resolved"></div>
36
+ </details>
37
+ </accordion-tabs>
38
+ <form method="dialog">
39
+ <button class="Component-closeMockData">Close</button>
40
+ </form>
41
+ </div>
42
+ </dialog>
43
+ </div>
44
+ <script src="{{ projectName }}/js/jsontree.js"></script>
45
+ <script>
46
+ const jsontree_{{ normalizedVariation|replace({ '-': '_' }) }} = {
47
+ "raw": {
48
+ "data": {{ mockData|default({})|raw }}
49
+ },
50
+ "resolved": {
51
+ "data": {{ mockDataResolved|default({})|replace({'</script>': '<\\/script>'})|raw }}
52
+ }
53
+ };
54
+ </script>
55
+ {% endblock %}
@@ -0,0 +1,14 @@
1
+ {% extends "@miyagi/layouts/iframe_default.twig.miyagi" %}
2
+ {% block additionalCss %}
3
+ {% for file in additionalCssFiles %}
4
+ <link rel="stylesheet" href="{{ file }}">
5
+ {% endfor %}
6
+ {% endblock %}
7
+ {% block body %}
8
+ <div class="Wrapper">
9
+ <div class="Documentation">
10
+ <h1>{{ userProjectName }}</h1>
11
+ {{ documentation }}
12
+ </div>
13
+ </div>
14
+ {% endblock %}
@@ -0,0 +1,22 @@
1
+ <!DOCTYPE html>
2
+ <html lang="{{ lang }}" class="theme-{{ userUiConfig.theme }}" dir="{{ uiTextDirection }}" data-mode="{{ userUiConfig.mode }}">
3
+ <head>
4
+ <meta charset="utf-8">
5
+ <meta name="viewport" content="initial-scale=1,width=device-width">
6
+ <meta name="color-scheme" content="dark light">
7
+ <title>{{ projectName }}</title>
8
+ <script src="/{{ projectName }}/js/iframe{% if isBuild %}.build{% endif %}.js" {% if miyagiDev %} type="module" {% endif %}{% if prod %}
9
+ defer{% endif %}></script>
10
+ <link rel="stylesheet" href="/{{ projectName }}/css/iframe.css">
11
+ {% block additionalCss %}{% endblock %}
12
+ <style>
13
+ {{ theme.css }}
14
+ </style>
15
+ <script>
16
+ {{ theme.js }}
17
+ </script>
18
+ </head>
19
+ <body>
20
+ {% block body %}{% endblock %}
21
+ </body>
22
+ </html>
@@ -0,0 +1,24 @@
1
+ <!DOCTYPE html>
2
+ <html lang="{{ lang }}" class="theme-{{ userUiConfig.theme }}" dir="{{ uiTextDirection }}">
3
+ <head>
4
+ <meta charset="utf-8">
5
+ <meta name="viewport" content="initial-scale=1,width=device-width">
6
+ <meta name="color-scheme" content="dark light">
7
+ <title>{{ userProjectName }}</title>
8
+ <base href="{{ basePath }}" />
9
+ <script src="{{ projectName }}/js/main{% if isBuild %}.build{% endif %}.js" {% if miyagiDev %}type="module"{% endif %}></script>
10
+ <link rel="stylesheet" href="{{ projectName }}/css/main.css">
11
+ <style>
12
+ {{ theme.css }}
13
+ </style>
14
+ </head>
15
+ <body>
16
+ {% include "@miyagi/menu/menu.twig.miyagi" %}
17
+
18
+ <main class="Content">
19
+ <div class="FrameWrapper">
20
+ <iframe class="Frame" id="iframe" src="{{ iframeSrc }}" name="iframe" title="Components"></iframe>
21
+ </div>
22
+ </main>
23
+ </body>
24
+ </html>
@@ -0,0 +1,83 @@
1
+ <div class="ConfigSwitchers">
2
+ <button class="ConfigSwitchers-toggle" aria-expanded="false" aria-controls="config-switchers">
3
+ <svg class="ConfigSwitchers-toggleOpen" xmlns="http://www.w3.org/2000/svg" fill="none" stroke="currentColor" stroke-width="1.5" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M9.594 3.94c.09-.542.56-.94 1.11-.94h2.593c.55 0 1.02.398 1.11.94l.213 1.281c.063.374.313.686.645.87.074.04.147.083.22.127.325.196.72.257 1.075.124l1.217-.456a1.125 1.125 0 0 1 1.37.49l1.296 2.247a1.125 1.125 0 0 1-.26 1.431l-1.003.827c-.293.241-.438.613-.43.992a7.723 7.723 0 0 1 0 .255c-.008.378.137.75.43.991l1.004.827c.424.35.534.955.26 1.43l-1.298 2.247a1.125 1.125 0 0 1-1.369.491l-1.217-.456c-.355-.133-.75-.072-1.076.124a6.47 6.47 0 0 1-.22.128c-.331.183-.581.495-.644.869l-.213 1.281c-.09.543-.56.94-1.11.94h-2.594c-.55 0-1.019-.398-1.11-.94l-.213-1.281c-.062-.374-.312-.686-.644-.87a6.52 6.52 0 0 1-.22-.127c-.325-.196-.72-.257-1.076-.124l-1.217.456a1.125 1.125 0 0 1-1.369-.49l-1.297-2.247a1.125 1.125 0 0 1 .26-1.431l1.004-.827c.292-.24.437-.613.43-.991a6.932 6.932 0 0 1 0-.255c.007-.38-.138-.751-.43-.992l-1.004-.827a1.125 1.125 0 0 1-.26-1.43l1.297-2.247a1.125 1.125 0 0 1 1.37-.491l1.216.456c.356.133.751.072 1.076-.124.072-.044.146-.086.22-.128.332-.183.582-.495.644-.869l.214-1.28Z"/><path stroke-linecap="round" stroke-linejoin="round" d="M15 12a3 3 0 1 1-6 0 3 3 0 0 1 6 0Z"/></svg>
4
+ <svg class="ConfigSwitchers-toggleClose" xmlns="http://www.w3.org/2000/svg" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24" width="24" height="24"><path stroke-linecap="round" stroke-linejoin="round" d="M6 18 18 6M6 6l12 12"/></svg>
5
+ <span id="config-switcher-label-open">Open Settings</span>
6
+ <span id="config-switcher-label-close" hidden>Close Settings</span>
7
+ </button>
8
+ <script>
9
+ {
10
+ const configSwitcherToggle = document.querySelector(".ConfigSwitchers-toggle");
11
+ const configSwitcherLabelOpen = document.getElementById("config-switcher-label-open");
12
+ const configSwitcherLabelClose = document.getElementById("config-switcher-label-close");
13
+
14
+ if (configSwitcherToggle) {
15
+ configSwitcherToggle.addEventListener("click", () => {
16
+ const shouldOpen = configSwitcherToggle.getAttribute("aria-expanded") === "false";
17
+
18
+ configSwitcherToggle.setAttribute("aria-expanded", shouldOpen ? "true" : "false");
19
+ configSwitcherLabelOpen.hidden = shouldOpen;
20
+ configSwitcherLabelClose.hidden = !shouldOpen;
21
+ });
22
+ }
23
+ }
24
+ </script>
25
+ <div class="ConfigSwitchers-container" id="config-switchers">
26
+ <form class="ConfigSwitcher js-ThemeSwitcher">
27
+ <fieldset class="ConfigSwitcher-wrapper">
28
+ <legend class="ConfigSwitcher-title">Color scheme</legend>
29
+ <div class="ConfigSwitcher-options">
30
+ <div class="ConfigSwitcher-option">
31
+ <input type="radio" name="theme" value="light" id="theme-light"{% if userUiConfig.theme == "light" %} checked{% endif %}>
32
+ <label for="theme-light">
33
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" aria-labelledby="theme-light-title"><title id="theme-light-title">light</title><path d="M24 12.2v.2c-.2.4-.6.7-1.2.8H21c-.6 0-1.1-.6-1.1-1.2 0-.7.5-1.2 1.2-1.2h1.8c.6 0 1 .3 1.2.9v.5zM11.8 24h-.2c-.4-.2-.7-.6-.8-1.2V21c0-.6.6-1.1 1.2-1.1.7 0 1.2.5 1.2 1.2v1.8c0 .6-.3 1-.9 1.2h-.5zM12.2 0h.2c.4.2.7.6.8 1.2V3c0 .6-.6 1.1-1.2 1.1-.7 0-1.2-.5-1.2-1.1V1.2c0-.6.3-1 .9-1.1V0h.5zM0 11.8v-.2c.2-.4.6-.7 1.2-.8H3c.6 0 1.1.6 1.1 1.2 0 .7-.5 1.2-1.1 1.2H1c-.4 0-.8-.3-1-.8l-.1-.2v-.4zM12 18a6 6 0 1 1 0-12 6 6 0 0 1 0 12zM4.4 20.9c-.6 0-1-.3-1.1-.7-.2-.5-.2-.9.1-1.2L5 17.3c.4-.4 1-.3 1.5.1.4.4.5 1 0 1.5l-1.4 1.6-.7.3zM3.2 4.3c0-.4.2-.8.6-1 .5-.2.9-.2 1.3.1L6.6 5c.4.4.3 1-.1 1.5-.4.4-1.1.5-1.5 0L3.4 5.2l-.3-.7zM19.6 3.2c.5 0 .9.2 1.1.6.2.5.2 1-.1 1.3L19 6.6c-.4.4-1 .3-1.5 0-.4-.5-.5-1.2 0-1.6l1.4-1.6.7-.3zM20.9 19.6c0 .5-.3.9-.7 1.1-.4.2-.9.2-1.2-.1L17.4 19c-.4-.4-.3-1 .1-1.5.4-.4 1.1-.5 1.5 0 .6.4 1 1 1.6 1.5l.3.6z"/></svg>
34
+ </label>
35
+ </div>
36
+ <div class="ConfigSwitcher-option">
37
+ <input type="radio" name="theme" value="dark" id="theme-dark"{% if userUiConfig.theme == "dark" %} checked{% endif %}>
38
+ <label for="theme-dark">
39
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" aria-labelledby="theme-dark-title"><title id="theme-dark-title">dark</title><path d="M17.2 18.4c1.9 0 3.6-.5 5.3-1.5.3-.2.5-.2.7 0 .2.1.2.4 0 .7-2 3.5-5 5.6-9 6.2A12.1 12.1 0 0 1 9.4.2c.4-.1.7 0 .8.2.2.2.1.5-.1.8a10.1 10.1 0 0 0 5.2 17l2 .2z"/></svg>
40
+ </label>
41
+ </div>
42
+ <div class="ConfigSwitcher-option">
43
+ <input type="radio" name="theme" value="auto" id="theme-auto"{% if userUiConfig.theme == "auto" %} checked{% endif %}>
44
+ <label for="theme-auto">
45
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" aria-labelledby="theme-auto-title"><title id="theme-auto-title">auto</title><path d="M24 2.3v14.5c-.3 1-1 1.2-1.7 1.2H1.5c-.3 0-.7-.1-1-.4-.3-.2-.4-.5-.5-.8V2.3c.2-.8.9-1.1 1.7-1.1h21c.4 0 .7.1 1 .5l.3.6z"/><path class="st0" d="M8.3 21.4H4.6c-.5 0-.8.3-.8.7 0 .4.3.7.8.7h14.8c.5 0 .8-.3.8-.7 0-.4-.3-.7-.8-.7h-3.7v-2H8.3v2z"/><path d="M8.3 21.4v-2h7.4v2H19.4c.5 0 .8.3.8.7 0 .4-.3.7-.8.7H4.6c-.5 0-.8-.3-.8-.7 0-.4.3-.7.8-.7h3.7z"/></svg>
46
+ </label>
47
+ </div>
48
+ </div>
49
+ </fieldset>
50
+ </form>
51
+
52
+ <form class="ConfigSwitcher js-TextDirectionSwitcher">
53
+ <fieldset class="ConfigSwitcher-wrapper">
54
+ <legend class="ConfigSwitcher-title">Text direction</legend>
55
+ <div class="ConfigSwitcher-options">
56
+ <div class="ConfigSwitcher-option">
57
+ <input type="radio" name="text_direction" value="ltr" id="text-direction-ltr"{% if userUiConfig.componentTextDirection == "ltr" %} checked{% endif %}>
58
+ <label for="text-direction-ltr">
59
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" aria-labelledby="text-direction-ltr-title"><title id="text-direction-ltr-title">left to right</title><path d="M12 24c.5-.1.8-.5 1.2-.8l10-10c.4-.5.6-1 .4-1.7A10075.2 10075.2 0 0 0 12.8.5c-.6-.7-1.6-.7-2.2 0L9.2 1.8c-.7.7-.7 1.6 0 2.3l5.1 5.1.2.2H2c-.7 0-1.2.3-1.5 1l-.2.7V13c0 1 .7 1.7 1.7 1.7h12.5l-.2.2-5 5c-.6.6-.8 1.4-.4 2l2 2 .5.2h.6z"/><</svg>
60
+ </label>
61
+ </div>
62
+ <div class="ConfigSwitcher-option">
63
+ <input type="radio" name="text_direction" value="rtl" id="text-direction-rtl"{% if userUiConfig.componentTextDirection == "rtl" %} checked{% endif %}>
64
+ <label for="text-direction-rtl">
65
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" aria-labelledby="text-direction-rtl-title"><title id="text-direction-rtl-title">right to left</title><path d="M12 24c-.5-.1-.8-.5-1.2-.8l-10-10c-.4-.5-.6-1-.4-1.7 0-.2.2-.5.4-.6L11.2.5c.7-.7 1.6-.7 2.3 0l1.3 1.3c.7.7.7 1.6 0 2.3L9.7 9.2l-.2.2H22c.7 0 1.2.3 1.5 1l.2.7V13c0 1-.7 1.7-1.7 1.7H9.5l.2.2 5 5c.6.6.8 1.4.4 2l-2 2-.5.2H12z"/></svg>
66
+ </label>
67
+ </div>
68
+ </div>
69
+ </fieldset>
70
+ </form>
71
+
72
+ <form class="ConfigSwitcher js-DevelopmentModeSwitcher">
73
+ <div class="ConfigSwitcher-wrapper">
74
+ <label for="development-mode" class="ConfigSwitcher-title">Development mode</label>
75
+ <div class="ConfigSwitcher-options">
76
+ <div class="ConfigSwitcher-option">
77
+ <input type="checkbox" name="mode" value="dev" id="development-mode"{% if userUiConfig.mode == "dev" %} checked{% endif %} switch>
78
+ </div>
79
+ </div>
80
+ </div>
81
+ </form>
82
+ </div>
83
+ </div>
@@ -0,0 +1,9 @@
1
+ <form class="GoTo u-hiddenVisually" data-url-pattern="{{ flatUrlPattern }}" autocomplete="off">
2
+ <label class="GoTo-label" for="goto-input">Go to…</label>
3
+ <input class="GoTo-input" type="text" list="goto-list" id="goto-input">
4
+ <datalist id="goto-list">
5
+ {% for component in components %}
6
+ <option value="{{ component.value }}">{{ component.shortPath }}</option>
7
+ {% endfor %}
8
+ </datalist>
9
+ </form>