buner 0.0.2 → 1.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 (175) hide show
  1. package/.env +15 -0
  2. package/.env.development +6 -0
  3. package/.env.eshn +5 -0
  4. package/README.md +141 -5
  5. package/bin/buner.js +566 -0
  6. package/cli/README.md +1 -0
  7. package/cli/buner.ts +234 -0
  8. package/cli/cli.ts +125 -0
  9. package/cli/create-app.ts +59 -0
  10. package/cli/helpers/copy.ts +62 -0
  11. package/cli/helpers/format-files.ts +189 -0
  12. package/cli/helpers/git.ts +77 -0
  13. package/cli/helpers/install.ts +26 -0
  14. package/cli/helpers/is-folder-empty.ts +40 -0
  15. package/cli/helpers/is-writeable.ts +14 -0
  16. package/cli/helpers/make-dir.ts +7 -0
  17. package/cli/helpers/validate-pkg.ts +17 -0
  18. package/cli/install-template.ts +77 -0
  19. package/eslint.config.mjs +187 -0
  20. package/index.html +44 -0
  21. package/integration.ts +179 -0
  22. package/migrate-scss.ts +42 -0
  23. package/package.json +135 -7
  24. package/prerender.ts +229 -0
  25. package/public/.nojekyll +1 -0
  26. package/public/400.html +1 -0
  27. package/public/401.html +21 -0
  28. package/public/403.html +252 -0
  29. package/public/404.css +51 -0
  30. package/public/404.html +29 -0
  31. package/public/__images__/awww.jpeg +0 -0
  32. package/public/__images__/bat-body.png +0 -0
  33. package/public/__images__/bat-wing.png +0 -0
  34. package/public/__images__/haunted-house-background.png +0 -0
  35. package/public/__images__/haunted-house-foreground.png +0 -0
  36. package/public/assets/fonts/crimson-text/CrimsonText-Bold.ttf +0 -0
  37. package/public/assets/fonts/crimson-text/CrimsonText-BoldItalic.ttf +0 -0
  38. package/public/assets/fonts/crimson-text/CrimsonText-Italic.ttf +0 -0
  39. package/public/assets/fonts/crimson-text/CrimsonText-Regular.ttf +0 -0
  40. package/public/assets/fonts/crimson-text/CrimsonText-SemiBold.ttf +0 -0
  41. package/public/assets/fonts/crimson-text/CrimsonText-SemiBoldItalic.ttf +0 -0
  42. package/public/assets/fonts/crimson-text/CrimsonText.woff2 +0 -0
  43. package/public/assets/fonts/crimson-text/OFL.txt +93 -0
  44. package/public/assets/fonts/work-sans/OFL.txt +93 -0
  45. package/public/assets/fonts/work-sans/README.txt +81 -0
  46. package/public/assets/fonts/work-sans/WorkSans-Italic-VariableFont_wght.ttf +0 -0
  47. package/public/assets/fonts/work-sans/WorkSans-VariableFont_wght.ttf +0 -0
  48. package/public/assets/fonts/work-sans/WorkSans.woff2 +0 -0
  49. package/public/assets/fonts/work-sans/static/WorkSans-Black.ttf +0 -0
  50. package/public/assets/fonts/work-sans/static/WorkSans-BlackItalic.ttf +0 -0
  51. package/public/assets/fonts/work-sans/static/WorkSans-Bold.ttf +0 -0
  52. package/public/assets/fonts/work-sans/static/WorkSans-BoldItalic.ttf +0 -0
  53. package/public/assets/fonts/work-sans/static/WorkSans-ExtraBold.ttf +0 -0
  54. package/public/assets/fonts/work-sans/static/WorkSans-ExtraBoldItalic.ttf +0 -0
  55. package/public/assets/fonts/work-sans/static/WorkSans-ExtraLight.ttf +0 -0
  56. package/public/assets/fonts/work-sans/static/WorkSans-ExtraLightItalic.ttf +0 -0
  57. package/public/assets/fonts/work-sans/static/WorkSans-Italic.ttf +0 -0
  58. package/public/assets/fonts/work-sans/static/WorkSans-Light.ttf +0 -0
  59. package/public/assets/fonts/work-sans/static/WorkSans-LightItalic.ttf +0 -0
  60. package/public/assets/fonts/work-sans/static/WorkSans-Medium.ttf +0 -0
  61. package/public/assets/fonts/work-sans/static/WorkSans-MediumItalic.ttf +0 -0
  62. package/public/assets/fonts/work-sans/static/WorkSans-Regular.ttf +0 -0
  63. package/public/assets/fonts/work-sans/static/WorkSans-SemiBold.ttf +0 -0
  64. package/public/assets/fonts/work-sans/static/WorkSans-SemiBoldItalic.ttf +0 -0
  65. package/public/assets/fonts/work-sans/static/WorkSans-Thin.ttf +0 -0
  66. package/public/assets/fonts/work-sans/static/WorkSans-ThinItalic.ttf +0 -0
  67. package/public/assets/images/icons.svg +67 -0
  68. package/public/assets/images/logo.svg +14 -0
  69. package/public/assets/images/root.svg +49 -0
  70. package/public/assets/vendors/axios@0.24.0/axios.js +2275 -0
  71. package/public/assets/vendors/axios@0.24.0/axios.map +1 -0
  72. package/public/assets/vendors/axios@0.24.0/axios.min.js +2 -0
  73. package/public/assets/vendors/axios@0.24.0/axios.min.map +1 -0
  74. package/public/favicon.ico +0 -0
  75. package/public/favicon.svg +3 -0
  76. package/public/icon-128.png +0 -0
  77. package/public/icon-16.png +0 -0
  78. package/public/icon-192.png +0 -0
  79. package/public/icon-48.png +0 -0
  80. package/public/icon-512.png +0 -0
  81. package/public/json/avatar.json +42 -0
  82. package/public/manifest.webmanifest +29 -0
  83. package/public/mockServiceWorker.js +349 -0
  84. package/public/pl-states.svg +4 -0
  85. package/public/samples/01.svg +1 -0
  86. package/public/samples/Airbnb.svg +3 -0
  87. package/public/samples/Facebook.svg +3 -0
  88. package/public/samples/Google.svg +8 -0
  89. package/public/samples/Microsoft.svg +7 -0
  90. package/public/samples/Spotify.svg +3 -0
  91. package/public/samples/alexandra-stolz.svg +35 -0
  92. package/public/samples/browserconfig.xml +9 -0
  93. package/public/samples/cliff-curtis.jpg +0 -0
  94. package/public/samples/emilia-clarke.jpg +0 -0
  95. package/public/samples/favicon.ico +0 -0
  96. package/public/samples/icons/android-chrome-192x192.png +0 -0
  97. package/public/samples/icons/apple-touch-icon.png +0 -0
  98. package/public/samples/icons/favicon-144x144.png +0 -0
  99. package/public/samples/icons/favicon-150x150.png +0 -0
  100. package/public/samples/icons/favicon-16x16.png +0 -0
  101. package/public/samples/icons/favicon-32x32.png +0 -0
  102. package/public/samples/icons/favicon-48x48.png +0 -0
  103. package/public/samples/icons/favicon-70x70.png +0 -0
  104. package/public/samples/icons/favicon.ico +0 -0
  105. package/public/samples/image-1.svg +166 -0
  106. package/public/samples/image-2.svg +110 -0
  107. package/public/samples/image-3.svg +113 -0
  108. package/public/samples/janet-bray.svg +36 -0
  109. package/public/samples/kate-winslet.jpg +0 -0
  110. package/public/samples/manifest.json +19 -0
  111. package/public/samples/michelle-yeoh.jpg +0 -0
  112. package/public/samples/peg-legge.svg +37 -0
  113. package/public/samples/richard-guerra.svg +42 -0
  114. package/public/samples/rose-leslie.jpg +0 -0
  115. package/public/samples/sample-1.svg +365 -0
  116. package/public/samples/sample-2.svg +129 -0
  117. package/public/samples/sample-3.svg +93 -0
  118. package/public/samples/sample-4.svg +168 -0
  119. package/public/samples/sample-5.svg +155 -0
  120. package/public/samples/sample-6.svg +445 -0
  121. package/public/samples/sample-7.svg +404 -0
  122. package/public/samples/sample-8.png +0 -0
  123. package/public/staticwebapp.config.json +138 -0
  124. package/scripts.ts +56 -0
  125. package/server.ts +29 -0
  126. package/states.ts +63 -0
  127. package/styles.ts +232 -0
  128. package/tsconfig.json +71 -25
  129. package/types.d.ts +54 -0
  130. package/vite.config.ts +3 -0
  131. package/xpack/alias.ts +21 -0
  132. package/xpack/config.ts +59 -0
  133. package/xpack/create-server.ts +68 -0
  134. package/xpack/create-vite-dev-server.ts +33 -0
  135. package/xpack/deploy/deploy-inte.ts +3 -0
  136. package/xpack/filename.ts +43 -0
  137. package/xpack/hooks/build-start.ts +17 -0
  138. package/xpack/hooks/close-bundle.ts +19 -0
  139. package/xpack/hooks/handle-hot-update.ts +22 -0
  140. package/xpack/hooks/options.ts +55 -0
  141. package/xpack/hooks/resolve-dynamic-import.ts +18 -0
  142. package/xpack/hooks/transform-index-html.ts +18 -0
  143. package/xpack/hooks/transform.ts +72 -0
  144. package/xpack/hooks/write-bundle.ts +16 -0
  145. package/xpack/manual-chunk.ts +56 -0
  146. package/xpack/paths.ts +30 -0
  147. package/xpack/renderer.ts +141 -0
  148. package/xpack/root/active-item-options.tsx +98 -0
  149. package/xpack/root/frame-controls.tsx +139 -0
  150. package/xpack/root/index.tsx +107 -0
  151. package/xpack/root/rendered-item.tsx +25 -0
  152. package/xpack/root/root-context.ts +22 -0
  153. package/xpack/root/root-nav.tsx +162 -0
  154. package/xpack/root/state-animation-html.tsx +18 -0
  155. package/xpack/root/template.tsx +23 -0
  156. package/xpack/root/use-click-outside.ts +37 -0
  157. package/xpack/scripts/color-mode.entry.ts +28 -0
  158. package/xpack/scripts/mock-api.entry.ts +11 -0
  159. package/xpack/scripts/pl-states.entry.ts +321 -0
  160. package/xpack/scripts/root.entry.ts +135 -0
  161. package/xpack/scripts/theme-critical.entry.ts +20 -0
  162. package/xpack/states.schema.json +61 -0
  163. package/xpack/styles/_border.scss +22 -0
  164. package/xpack/styles/_breakpoint.scss +117 -0
  165. package/xpack/styles/_form.scss +23 -0
  166. package/xpack/styles/_px2rem.scss +5 -0
  167. package/xpack/styles/_reset.scss +134 -0
  168. package/xpack/styles/_state-toggle.scss +121 -0
  169. package/xpack/styles/_theme.scss +68 -0
  170. package/xpack/styles/_top-panel.scss +87 -0
  171. package/xpack/styles/_xpack-root.scss +322 -0
  172. package/xpack/styles/pl-states.scss +308 -0
  173. package/xpack/styles/root.scss +129 -0
  174. package/.github/workflows/deploy.yaml +0 -32
  175. package/index.ts +0 -1
@@ -0,0 +1,18 @@
1
+ export default function StateAnimationHtml(model: { keyExist: boolean }) {
2
+ return model.keyExist ? (
3
+ <></>
4
+ ) : (
5
+ <div className="pl-state-toggle__circles">
6
+ <div className="pl-state-toggle__circle" />
7
+ <div className="pl-state-toggle__circle" />
8
+ <div className="pl-state-toggle__circle" />
9
+ <div className="pl-state-toggle__circle" />
10
+ <div className="pl-state-toggle__circle" />
11
+ <div className="pl-state-toggle__circle" />
12
+ <div className="pl-state-toggle__circle" />
13
+ <div className="pl-state-toggle__circle" />
14
+ <div className="pl-state-toggle__circle" />
15
+ <div className="pl-state-toggle__circle" />
16
+ </div>
17
+ );
18
+ }
@@ -0,0 +1,23 @@
1
+ import { RootModel } from '@_types/types';
2
+ import RequireJs from '@helpers/RequireJs';
3
+ import ReactSection from '@helpers/ReactSection';
4
+
5
+ export default function Template(model: RootModel) {
6
+ return (
7
+ <main className="xpack-t-root">
8
+ {model && <ReactSection css={'root'} data={model} type="root" />}
9
+
10
+ <div className="xpack-t-root__target-wrapper" id="root-iframe-wrapper">
11
+ <iframe
12
+ className="xpack-t-root__target"
13
+ id="root-iframe"
14
+ name="inner"
15
+ sandbox="allow-same-origin allow-scripts allow-popups allow-forms allow-modals allow-downloads allow-popups-to-escape-sandbox allow-presentation allow-top-navigation"
16
+ title="Pages"
17
+ />
18
+ <div className="xpack-t-root__target-resizer" id="root-iframe-resizer" />
19
+ <RequireJs defer path="root" />
20
+ </div>
21
+ </main>
22
+ );
23
+ }
@@ -0,0 +1,37 @@
1
+ import { RefObject, useEffect } from 'react';
2
+
3
+ export function useOnClickOutside(
4
+ ref: RefObject<HTMLElement | null>,
5
+ handler: (event?: MouseEvent | TouchEvent) => void,
6
+ otherDependenceRef?: RefObject<HTMLElement | null>[]
7
+ ) {
8
+ useEffect(() => {
9
+ const listener = (event: MouseEvent | TouchEvent) => {
10
+ // Do nothing if clicking ref's element or descendent elements
11
+ if (!event.target || !ref.current || ref.current.contains(event.target as Node)) {
12
+ return;
13
+ }
14
+
15
+ if (otherDependenceRef && otherDependenceRef.some((r) => r.current?.contains(event.target as Node))) {
16
+ return;
17
+ }
18
+
19
+ handler(event);
20
+ };
21
+
22
+ const handleWindowBlur = () => {
23
+ handler();
24
+ };
25
+
26
+ document.addEventListener('mousedown', listener);
27
+ document.addEventListener('touchstart', listener);
28
+ window.addEventListener('blur', handleWindowBlur);
29
+
30
+ // Cleanup the event listeners on component unmount
31
+ return () => {
32
+ document.removeEventListener('mousedown', listener);
33
+ document.removeEventListener('touchstart', listener);
34
+ window.removeEventListener('blur', handleWindowBlur);
35
+ };
36
+ }, [ref, handler, otherDependenceRef]);
37
+ }
@@ -0,0 +1,28 @@
1
+ import { THEME_KEY, switchTheme } from '@helpers/handleTheme';
2
+
3
+ /**
4
+ * Handle storage change
5
+ */
6
+ const handleStorageChange = (event: StorageEvent) => {
7
+ switch (event.key) {
8
+ case THEME_KEY: {
9
+ document.documentElement.setAttribute('data-theme', event.newValue as string);
10
+ break;
11
+ }
12
+ }
13
+ };
14
+
15
+ const handleToggleTheme = () => {
16
+ switchTheme();
17
+ };
18
+
19
+ const themeToggle = document.querySelector('.zzz-o-header__theme-toggle');
20
+
21
+ if (themeToggle) {
22
+ themeToggle.addEventListener('click', () => {
23
+ switchTheme();
24
+ });
25
+ }
26
+
27
+ window.addEventListener('storage', handleStorageChange);
28
+ window.addEventListener('toggleTheme', handleToggleTheme);
@@ -0,0 +1,11 @@
1
+ import { worker } from '@mocks/browser';
2
+
3
+ worker.start({
4
+ serviceWorker: {
5
+ url: `${import.meta.env.VITE_BASE_URL}mockServiceWorker.js`,
6
+ options: {
7
+ scope: `${import.meta.env.VITE_BASE_URL}`,
8
+ },
9
+ },
10
+ onUnhandledRequest: 'bypass',
11
+ });
@@ -0,0 +1,321 @@
1
+ interface Theme {
2
+ value: string;
3
+ name: string;
4
+ }
5
+
6
+ interface StateOption {
7
+ name: string;
8
+ value: string;
9
+ }
10
+
11
+ interface State {
12
+ name: string;
13
+ options?: StateOption[];
14
+ multiple?: boolean;
15
+ }
16
+
17
+ interface StateButton {
18
+ parentSelector?: string;
19
+ styleModifier: string;
20
+ zIndex?: number;
21
+ }
22
+
23
+ interface ComponentState {
24
+ name: string;
25
+ selector: string;
26
+ button?: StateButton;
27
+ states: State[];
28
+ }
29
+
30
+ let index = 100000;
31
+
32
+ const themes: Theme[] = [
33
+ {
34
+ value: 'theme-blue-p',
35
+ name: 'Blue',
36
+ },
37
+ {
38
+ value: 'theme-white-p',
39
+ name: 'White',
40
+ },
41
+ {
42
+ value: 'theme-sand-s',
43
+ name: 'Sand',
44
+ },
45
+ {
46
+ value: 'theme-flow-25',
47
+ name: 'Flow 25',
48
+ },
49
+ {
50
+ value: 'theme-wave-ac',
51
+ name: 'Wave',
52
+ },
53
+ {
54
+ value: 'theme-wave-50',
55
+ name: 'Wave 50',
56
+ },
57
+ {
58
+ value: 'theme-pearl-s',
59
+ name: 'Pearl',
60
+ },
61
+ {
62
+ value: 'theme-pebble-s',
63
+ name: 'Pebble',
64
+ },
65
+ ];
66
+
67
+ const newId = () => {
68
+ return 'pl-state-id-' + index++;
69
+ };
70
+
71
+ const createSelect = (state: State, classList: DOMTokenList) => {
72
+ if (!state.options) {
73
+ return '';
74
+ }
75
+
76
+ const options = state.options;
77
+ const name = newId();
78
+ const header = state.multiple ? 'Select many...' : (options.find((o) => classList.contains(o.value))?.name ?? '---');
79
+ const type = state.multiple ? 'checkbox' : 'radio';
80
+
81
+ let optionsHtml = '';
82
+
83
+ options.forEach((option: StateOption) => {
84
+ const selectedHtml = classList.contains(option.value) ? 'checked' : '';
85
+ const id = newId();
86
+
87
+ optionsHtml +=
88
+ `<input name="${name}" class="pl-state-bar__input" type="${type}" id="${id}" data-name="${option.name}" value="${option.value}" ${selectedHtml}/>` +
89
+ `<label class="pl-state-bar__label" for="${id}"><span>${option.name}</span></label>`;
90
+ });
91
+
92
+ const html =
93
+ '<div class="pl-state-bar__group">' +
94
+ `<div>${state.name}:</div>` +
95
+ `<div class="pl-state-bar__group-header">${header}</div>` +
96
+ `<div class="pl-state-bar__checkbox-group">${optionsHtml}</div>` +
97
+ '</div>';
98
+
99
+ return html;
100
+ };
101
+
102
+ const deactiveStateButtons = () => {
103
+ const stateButtons = [...document.querySelectorAll('.pl-state__button')];
104
+
105
+ stateButtons.forEach((stateButton) => stateButton.classList.remove('active'));
106
+ };
107
+
108
+ const closeButtonClickHandler = (stateBar: HTMLElement) => {
109
+ stateBar.classList.remove('expand');
110
+ document.body.classList.remove('pl-state-expand');
111
+ deactiveStateButtons();
112
+ window.dispatchEvent(new Event('resize'));
113
+ };
114
+
115
+ const stateButtonClickHandler = (item: HTMLElement, stateButton: HTMLElement, plState: ComponentState) => {
116
+ deactiveStateButtons();
117
+
118
+ const stateBar: HTMLElement | null = document.querySelector('.pl-state-bar');
119
+
120
+ if (!stateBar) {
121
+ return;
122
+ }
123
+
124
+ if (stateButton.classList.contains('active')) {
125
+ closeButtonClickHandler(stateBar);
126
+
127
+ return;
128
+ }
129
+
130
+ const stateBarContent = stateBar.querySelector('.pl-state-bar__content');
131
+
132
+ if (stateBarContent) {
133
+ let stateBarContentHtml = '';
134
+ let index = 0;
135
+
136
+ plState.states.forEach((state) => {
137
+ const combinedState = state.name === 'Theme' && !state.options ? { ...state, options: themes } : state;
138
+
139
+ stateBarContentHtml += createSelect(combinedState, item.classList);
140
+
141
+ index++;
142
+
143
+ if (index == 1) {
144
+ stateBarContentHtml += stateBarCloseButtonHtml();
145
+ }
146
+ });
147
+ stateBarContent.innerHTML = stateBarContentHtml;
148
+
149
+ const closeButton = stateBarContent.querySelector('.pl-state-bar__close-button');
150
+
151
+ if (closeButton) {
152
+ closeButton.addEventListener('click', () => closeButtonClickHandler(stateBar));
153
+ }
154
+
155
+ const stateBarGroups = [...stateBarContent.querySelectorAll('.pl-state-bar__group')];
156
+
157
+ stateBarGroups.forEach((stateBarGroup) => {
158
+ const stateBarGroupHeader = stateBarGroup.querySelector('.pl-state-bar__group-header');
159
+ const checkboxGroup = stateBarGroup.querySelector('.pl-state-bar__checkbox-group');
160
+
161
+ if (!stateBarGroupHeader || !checkboxGroup) {
162
+ return;
163
+ }
164
+
165
+ if (stateBarGroupHeader) {
166
+ stateBarGroupHeader.addEventListener('click', () => {
167
+ checkboxGroup.classList.toggle('expand');
168
+ });
169
+ document.addEventListener('click', (e: MouseEvent) => {
170
+ if (!e.target) {
171
+ return;
172
+ }
173
+
174
+ const node = e.target as Node;
175
+
176
+ if (!checkboxGroup.contains(node) && !stateBarGroupHeader.contains(node)) {
177
+ checkboxGroup.classList.remove('expand');
178
+ }
179
+ });
180
+ }
181
+
182
+ const checkboxes = stateBarGroup.querySelectorAll("input[type='checkbox']");
183
+
184
+ [].forEach.call(checkboxes, (checkbox: HTMLInputElement) => {
185
+ checkbox.addEventListener('change', () => {
186
+ if (!checkbox.value) {
187
+ return;
188
+ }
189
+
190
+ if (checkbox.checked) {
191
+ item.classList.add(checkbox.value);
192
+ } else {
193
+ item.classList.remove(checkbox.value);
194
+ }
195
+ window.dispatchEvent(new Event('resize'));
196
+ });
197
+ });
198
+
199
+ const radios = stateBarGroup.querySelectorAll("input[type='radio']");
200
+
201
+ [].forEach.call(radios, (radio: HTMLInputElement) => {
202
+ radio.addEventListener('change', () => {
203
+ [].forEach.call(radios, (r: HTMLInputElement) => {
204
+ if (r.value) {
205
+ item.classList.remove(r.value);
206
+ }
207
+ });
208
+ if (radio.value) {
209
+ item.classList.add(radio.value);
210
+ }
211
+ stateBarGroupHeader.textContent = radio.getAttribute('data-name');
212
+ checkboxGroup.classList.remove('expand');
213
+ });
214
+ });
215
+
216
+ const radioLabels = [...stateBarGroup.querySelectorAll("input[type='radio'] + label")];
217
+
218
+ radioLabels.forEach((radioLabel) => {
219
+ radioLabel.addEventListener('click', () => {
220
+ checkboxGroup.classList.remove('expand');
221
+ });
222
+ });
223
+ });
224
+
225
+ stateBar.classList.add('expand');
226
+ stateButton.classList.add('active');
227
+ document.body.classList.add('pl-state-expand');
228
+ window.dispatchEvent(new Event('resize'));
229
+ }
230
+ };
231
+ const stateBarCloseButtonHtml = () => {
232
+ return '<div class="pl-state-bar__buttons"><a class="pl-state-bar__close-button"></a></div>';
233
+ };
234
+
235
+ const appendButtons = (states: ComponentState[]) => {
236
+ const stateBarHtml = `<div class="pl-state-bar"><div class="pl-state-bar__content"></div>${stateBarCloseButtonHtml()}</div>`;
237
+
238
+ document.body.insertAdjacentHTML('beforeend', stateBarHtml);
239
+ const stateBar: HTMLElement | null = document.querySelector('.pl-state-bar');
240
+
241
+ if (!stateBar) {
242
+ return;
243
+ }
244
+
245
+ const closeButton = stateBar.querySelector('.pl-state-bar__close-button');
246
+
247
+ if (closeButton) {
248
+ closeButton.addEventListener('click', () => closeButtonClickHandler(stateBar));
249
+ }
250
+
251
+ [].forEach.call(states, (plState: ComponentState) => {
252
+ if (!plState || !plState.selector) {
253
+ return;
254
+ }
255
+
256
+ const buttonModifier = plState.button?.styleModifier ?? '';
257
+ const buttonTitle = plState.name ? `title="Show state modifier for: ${plState.name}"` : '';
258
+ const buttonZIndex = plState.button?.zIndex ? `style="z-index: ${plState.button.zIndex};"` : '';
259
+
260
+ const items = document.querySelectorAll(plState.selector);
261
+
262
+ [].forEach.call(items, (item: HTMLElement) => {
263
+ const html =
264
+ `<div class="pl-state ${buttonModifier}" ${buttonZIndex}>` +
265
+ '<div class="pl-state__controls">' +
266
+ `<button class="pl-state__button" ${buttonTitle}>` +
267
+ `<img src="${import.meta.env.BASE_URL}pl-states.svg" loading="async">` +
268
+ '</button></div></div>';
269
+
270
+ const stateButtonParent = plState.button?.parentSelector ? item.querySelector(plState.button.parentSelector) : item;
271
+
272
+ if (!stateButtonParent) {
273
+ return;
274
+ }
275
+ stateButtonParent.insertAdjacentHTML('beforeend', html);
276
+
277
+ const stateContainer: HTMLElement | null = stateButtonParent.querySelector(':scope > .pl-state');
278
+
279
+ if (!stateContainer) {
280
+ return;
281
+ }
282
+
283
+ const stateButton: HTMLElement | null = stateContainer.querySelector('.pl-state__button');
284
+
285
+ if (stateButton) {
286
+ stateButton.addEventListener('click', () => {
287
+ stateButtonClickHandler(item, stateButton, plState);
288
+ });
289
+ }
290
+ });
291
+ });
292
+
293
+ addEventListener('resize', function () {
294
+ const stateBar = document.querySelector('.pl-state-bar');
295
+
296
+ if (!stateBar) {
297
+ return;
298
+ }
299
+
300
+ const stateBarRect = stateBar.getBoundingClientRect();
301
+
302
+ document.documentElement.style.setProperty('--pl-state-bar-height', Math.ceil(stateBarRect.height) + 'px');
303
+ });
304
+ };
305
+
306
+ const init = () => {
307
+ const localStorageKey = 'pl-show-state-selector';
308
+ const showStateSelector = localStorage.getItem(localStorageKey);
309
+
310
+ if (!showStateSelector) {
311
+ return;
312
+ }
313
+
314
+ fetch(import.meta.env.BASE_URL + 'pl-states.json')
315
+ .then((response) => response.json())
316
+ .then((data) => appendButtons(data));
317
+ };
318
+
319
+ init();
320
+
321
+ export {};
@@ -0,0 +1,135 @@
1
+ const BORDER_SIZE = 20;
2
+ const MIN_FRAME_SIZE = 350;
3
+ const MSG_IFRAME_SIZE = 'MSG_IFRAME_SIZE';
4
+
5
+ let orgWidth: number;
6
+ let pos: number;
7
+
8
+ const wrapper = document.getElementById('root-iframe-wrapper');
9
+ const frame = document.getElementById('root-iframe');
10
+ const resizer = document.getElementById('root-iframe-resizer');
11
+
12
+ let iframeSize = sessionStorage.getItem(MSG_IFRAME_SIZE);
13
+
14
+ const setIFrameWidth = (width?: number) => {
15
+ if (!wrapper) {
16
+ return;
17
+ }
18
+
19
+ if (width) {
20
+ wrapper.style.maxWidth = `min(100%, ${width}px)`;
21
+ } else {
22
+ wrapper.style.removeProperty('max-width');
23
+ }
24
+ };
25
+
26
+ const resize = (e: globalThis.MouseEvent) => {
27
+ e.stopPropagation();
28
+ e.preventDefault();
29
+ const dx = (e.x - pos) * 2;
30
+
31
+ const size = Math.max(MIN_FRAME_SIZE, orgWidth + dx);
32
+
33
+ setIFrameWidth(size);
34
+ iframeSize = size + '';
35
+
36
+ return false;
37
+ };
38
+
39
+ const mouseUp = () => {
40
+ if (!wrapper || !frame) {
41
+ return;
42
+ }
43
+
44
+ wrapper.style.removeProperty('transition');
45
+ frame.style.removeProperty('pointer-events');
46
+ iframeSize && sessionStorage.setItem(MSG_IFRAME_SIZE, iframeSize);
47
+
48
+ document.removeEventListener('mousemove', resize, false);
49
+ };
50
+
51
+ const handleResizerMouseDown = (e: MouseEvent) => {
52
+ if (!wrapper || !frame || e.offsetX >= BORDER_SIZE) {
53
+ return;
54
+ }
55
+
56
+ wrapper.style.transition = 'none';
57
+ frame.style.pointerEvents = 'none';
58
+ pos = e.x;
59
+ orgWidth = parseInt(getComputedStyle(wrapper, '').width);
60
+ document.addEventListener('mousemove', resize, false);
61
+ document.addEventListener('mouseup', mouseUp, false);
62
+ };
63
+
64
+ const initTopPanel = () => {
65
+ const isTopPanel = localStorage.getItem('MSG_IS_TOP_PANEL') === 'true';
66
+ const rootEl = document.querySelector('.xpack-t-root');
67
+
68
+ if (!rootEl) {
69
+ return;
70
+ }
71
+ if (isTopPanel) {
72
+ rootEl.classList.add('top-panel');
73
+ }
74
+ };
75
+
76
+ const handleStoreModified = (event: StorageEvent) => {
77
+ switch (event.key) {
78
+ case 'MSG_IS_TOP_PANEL': {
79
+ const isTopPanel = event.newValue === 'true';
80
+ const rootEl = document.querySelector('.xpack-t-root');
81
+
82
+ if (!rootEl) {
83
+ return;
84
+ }
85
+
86
+ if (isTopPanel) {
87
+ rootEl.classList.add('top-panel');
88
+ } else {
89
+ rootEl.classList.remove('top-panel');
90
+ }
91
+ break;
92
+ }
93
+ }
94
+ };
95
+
96
+ const addStoreEvent = () => {
97
+ window.addEventListener('storage', handleStoreModified);
98
+ };
99
+
100
+ const setup = () => {
101
+ if (!resizer || !frame) {
102
+ return;
103
+ }
104
+
105
+ resizer.onmousedown = handleResizerMouseDown;
106
+ setIFrameWidth(iframeSize ? parseInt(iframeSize) : undefined);
107
+
108
+ const getIFrameActualWidth = () => {
109
+ const el = document.getElementById('root-actual-iframe-width');
110
+
111
+ if (el) {
112
+ el.textContent = Math.ceil(parseInt(getComputedStyle(frame).width)) + 'px';
113
+ }
114
+ };
115
+
116
+ frame.onload = getIFrameActualWidth;
117
+
118
+ if ('ResizeObserver' in window) {
119
+ // create an Observer instance
120
+ const resizeObserver = new ResizeObserver(getIFrameActualWidth);
121
+
122
+ // start observing a DOM node
123
+ resizeObserver.observe(frame);
124
+ }
125
+ initTopPanel();
126
+ addStoreEvent();
127
+
128
+ if (wrapper) {
129
+ window.onload = () => wrapper.classList.add('initialized');
130
+ }
131
+ };
132
+
133
+ setup();
134
+
135
+ export {};
@@ -0,0 +1,20 @@
1
+ (() => {
2
+ // enforce local storage setting but also fallback to user-agent preferences
3
+
4
+ const THEME_KEY = 'MSG_THEME';
5
+
6
+ const urlParams = new URLSearchParams(window.location.search);
7
+ const theme = urlParams.get('theme');
8
+
9
+ if (theme === 'dark' || theme == 'light') {
10
+ document.documentElement.setAttribute('data-theme', theme);
11
+
12
+ return;
13
+ }
14
+
15
+ if (localStorage.getItem(THEME_KEY) === 'dark' || (!localStorage.getItem(THEME_KEY) && window.matchMedia('(prefers-color-scheme: dark)').matches)) {
16
+ document.documentElement.setAttribute('data-theme', 'dark');
17
+ }
18
+ })();
19
+
20
+ export {};
@@ -0,0 +1,61 @@
1
+ {
2
+ "$schema": "http://json-schema.org/draft-04/schema#",
3
+ "type": "object",
4
+ "properties": {
5
+ "name": {
6
+ "type": "string"
7
+ },
8
+ "selector": {
9
+ "type": "string"
10
+ },
11
+ "button": {
12
+ "type": "object",
13
+ "properties": {
14
+ "parentSelector": {
15
+ "type": "string"
16
+ },
17
+ "styleModifier": {
18
+ "type": "string"
19
+ },
20
+ "zIndex": {
21
+ "type": "integer"
22
+ }
23
+ }
24
+ },
25
+ "states": {
26
+ "type": "array",
27
+ "items": [
28
+ {
29
+ "type": "object",
30
+ "properties": {
31
+ "name": {
32
+ "type": "string"
33
+ },
34
+ "options": {
35
+ "type": "array",
36
+ "items": [
37
+ {
38
+ "type": "object",
39
+ "properties": {
40
+ "value": {
41
+ "type": "string"
42
+ },
43
+ "name": {
44
+ "type": "string"
45
+ }
46
+ },
47
+ "required": ["name"]
48
+ }
49
+ ]
50
+ },
51
+ "multiple": {
52
+ "type": "boolean"
53
+ }
54
+ },
55
+ "required": ["name"]
56
+ }
57
+ ]
58
+ }
59
+ },
60
+ "required": ["name", "selector", "states"]
61
+ }
@@ -0,0 +1,22 @@
1
+ @use 'px2rem' as *;
2
+ @use 'theme' as *;
3
+
4
+ @mixin border {
5
+ border: px2rem(1px) solid $border-color;
6
+ }
7
+
8
+ @mixin border-top {
9
+ border-top: px2rem(1px) solid $border-color;
10
+ }
11
+
12
+ @mixin border-bottom {
13
+ border-bottom: px2rem(1px) solid $border-color;
14
+ }
15
+
16
+ @mixin border-left {
17
+ border-left: px2rem(1px) solid $border-color;
18
+ }
19
+
20
+ @mixin border-right {
21
+ border-right: px2rem(1px) solid $border-color;
22
+ }