@squeditor/squeditor-framework 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 (77) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +106 -0
  3. package/package.json +36 -0
  4. package/php/functions.php +92 -0
  5. package/project-template/package.json +29 -0
  6. package/project-template/postcss.config.js +6 -0
  7. package/project-template/squeditor.config.js +81 -0
  8. package/project-template/src/404.php +21 -0
  9. package/project-template/src/assets/css/squeditor-icons.css +4719 -0
  10. package/project-template/src/assets/css/tailwind.css +3 -0
  11. package/project-template/src/assets/css/uikit-components.css +14586 -0
  12. package/project-template/src/assets/js/gsap-advanced.js +26 -0
  13. package/project-template/src/assets/js/gsap-init.js +672 -0
  14. package/project-template/src/assets/js/gsap-modules/cursor-preview.js +132 -0
  15. package/project-template/src/assets/js/gsap-modules/cursor.js +456 -0
  16. package/project-template/src/assets/js/gsap-modules/loop-panels.js +78 -0
  17. package/project-template/src/assets/js/gsap-modules/marquee.js +106 -0
  18. package/project-template/src/assets/js/gsap-modules/pinned-panels.js +105 -0
  19. package/project-template/src/assets/js/gsap-modules/scroll-to.js +54 -0
  20. package/project-template/src/assets/js/gsap-modules/swipe-slider.js +121 -0
  21. package/project-template/src/assets/js/gsap-modules/text-mask.js +93 -0
  22. package/project-template/src/assets/js/gsap-modules/tilt.js +70 -0
  23. package/project-template/src/assets/js/main.js +302 -0
  24. package/project-template/src/assets/js/uikit-components.js +18171 -0
  25. package/project-template/src/assets/scss/_base.scss +140 -0
  26. package/project-template/src/assets/scss/_components.scss +165 -0
  27. package/project-template/src/assets/scss/_config.scss +13 -0
  28. package/project-template/src/assets/scss/_functions.scss +81 -0
  29. package/project-template/src/assets/scss/_tokens.scss +229 -0
  30. package/project-template/src/assets/scss/_transitions.scss +36 -0
  31. package/project-template/src/assets/scss/_uikit-overrides.scss +187 -0
  32. package/project-template/src/assets/scss/_uikit_dynamic.scss +43 -0
  33. package/project-template/src/assets/scss/_utilities.scss +31 -0
  34. package/project-template/src/assets/scss/custom.scss +10 -0
  35. package/project-template/src/assets/scss/main.scss +11 -0
  36. package/project-template/src/assets/static/fonts/squeditor-icons/squeditor-icons.eot +0 -0
  37. package/project-template/src/assets/static/fonts/squeditor-icons/squeditor-icons.svg +1183 -0
  38. package/project-template/src/assets/static/fonts/squeditor-icons/squeditor-icons.ttf +0 -0
  39. package/project-template/src/assets/static/fonts/squeditor-icons/squeditor-icons.woff +0 -0
  40. package/project-template/src/config/site-config.php +34 -0
  41. package/project-template/src/data/blog.php +21 -0
  42. package/project-template/src/data/portfolio.php +23 -0
  43. package/project-template/src/data/team.php +23 -0
  44. package/project-template/src/index.php +57 -0
  45. package/project-template/src/init.php +19 -0
  46. package/project-template/src/page-templates/base.php +39 -0
  47. package/project-template/src/page-templates/body-scripts.php +26 -0
  48. package/project-template/src/page-templates/head.php +47 -0
  49. package/project-template/src/page-templates/transition.php +45 -0
  50. package/project-template/src/sections/cards/cards-grid.php +34 -0
  51. package/project-template/src/sections/cards/cards-horizontal.php +28 -0
  52. package/project-template/src/sections/cta/cta-banner.php +34 -0
  53. package/project-template/src/sections/cta/cta-newsletter.php +19 -0
  54. package/project-template/src/sections/footer/layout-01.php +35 -0
  55. package/project-template/src/sections/header/layout-01.php +36 -0
  56. package/project-template/src/sections/hero/hero-centered.php +44 -0
  57. package/project-template/src/sections/hero/hero-split.php +132 -0
  58. package/project-template/src/sections/hero/hero-video.php +22 -0
  59. package/project-template/src/sections/sidebar/sidebar-right.php +11 -0
  60. package/project-template/src/template-parts/breadcrumbs.php +17 -0
  61. package/project-template/src/template-parts/footer.php +74 -0
  62. package/project-template/src/template-parts/header.php +120 -0
  63. package/project-template/src/template-parts/mega-menu.php +7 -0
  64. package/project-template/src/template-parts/nav.php +16 -0
  65. package/project-template/src/template-parts/page-title-bar.php +14 -0
  66. package/project-template/tailwind.config.js +26 -0
  67. package/project-template/vite.config.js +67 -0
  68. package/scripts/build-components.js +109 -0
  69. package/scripts/copy-static.js +150 -0
  70. package/scripts/dev-router.php +23 -0
  71. package/scripts/dev.js +55 -0
  72. package/scripts/get-port.js +27 -0
  73. package/scripts/package-customer.js +278 -0
  74. package/scripts/package-dist.js +54 -0
  75. package/scripts/scaffold.js +72 -0
  76. package/scripts/snapshot.js +74 -0
  77. package/uikit-manifest.json +248 -0
@@ -0,0 +1,302 @@
1
+ // src/assets/js/main.js
2
+ import './gsap-init.js';
3
+ import './gsap-advanced.js';
4
+ // SCSS is imported directly in base.php for development (to prevent FOUC) and loaded via <link> in production.
5
+
6
+ // Remove the dev server FOUC shield
7
+ if (document.documentElement.classList.contains('js-fouc')) {
8
+ setTimeout(() => { document.documentElement.classList.remove('js-fouc'); }, 50);
9
+ }
10
+
11
+ // Add custom JavaScript here
12
+
13
+ import { gsap } from 'gsap';
14
+
15
+ function initMathPathTransition(pathSelector) {
16
+ const overlay = document.querySelector('.sq-page-transition');
17
+ const paths = document.querySelectorAll(pathSelector);
18
+ if (!overlay || !paths.length) return null;
19
+
20
+ let numPoints = 10;
21
+ let numPaths = paths.length; // curve=2, wave=1
22
+ let delayPointsMax = 0.3;
23
+ let delayPerPath = 0.25;
24
+ let isRevealing = true;
25
+ let pointsDelay = [];
26
+ let allPoints = [];
27
+
28
+ for (let i = 0; i < numPaths; i++) {
29
+ let points = [];
30
+ allPoints.push(points);
31
+ for (let j = 0; j < numPoints; j++) {
32
+ points.push(100);
33
+ }
34
+ }
35
+
36
+ function render() {
37
+ for (let i = 0; i < numPaths; i++) {
38
+ let path = paths[i];
39
+ let points = allPoints[i];
40
+ let d = "";
41
+
42
+ d += isRevealing ? `M 0 0 V ${points[0]} C` : `M 0 100 V ${points[0]} C`;
43
+
44
+ for (let j = 0; j < numPoints - 1; j++) {
45
+ let p = (j + 1) / (numPoints - 1) * 100;
46
+ let cp = p - (1 / (numPoints - 1) * 100) / 2;
47
+ d += ` ${cp} ${points[j]} ${cp} ${points[j + 1]} ${p} ${points[j + 1]}`;
48
+ }
49
+
50
+ d += isRevealing ? ` V 0 H 0` : ` V 100 H 0`;
51
+ path.setAttribute("d", d);
52
+ }
53
+ }
54
+
55
+ // 1. ENTER ANIMATION
56
+ isRevealing = true;
57
+ for (let i = 0; i < numPaths; i++) {
58
+ for (let j = 0; j < numPoints; j++) { allPoints[i][j] = 100; }
59
+ }
60
+ render();
61
+ overlay.classList.add('is-active');
62
+ ariaHidden(overlay, false);
63
+
64
+ setTimeout(() => {
65
+ const entryTl = gsap.timeline({
66
+ onUpdate: render,
67
+ onComplete: () => {
68
+ overlay.classList.remove('is-active');
69
+ ariaHidden(overlay, true);
70
+ },
71
+ defaults: { ease: "expo.inOut", duration: 1.2 }
72
+ });
73
+
74
+ for (let i = 0; i < numPoints; i++) pointsDelay[i] = Math.random() * delayPointsMax;
75
+
76
+ for (let i = 0; i < numPaths; i++) {
77
+ let points = allPoints[i];
78
+ let pathDelay = delayPerPath * (numPaths - i - 1);
79
+ for (let j = 0; j < numPoints; j++) {
80
+ entryTl.to(points, { [j]: 0, ease: "expo.out" }, pointsDelay[j] + pathDelay);
81
+ }
82
+ }
83
+ }, 100);
84
+
85
+ // 2. RETURN EXIT FUNCTION
86
+ return function playExit(href) {
87
+ isRevealing = false;
88
+ for (let i = 0; i < numPaths; i++) {
89
+ for (let j = 0; j < numPoints; j++) { allPoints[i][j] = 100; }
90
+ }
91
+ render();
92
+
93
+ overlay.classList.add('is-active');
94
+ ariaHidden(overlay, false);
95
+
96
+ const exitTl = gsap.timeline({
97
+ onUpdate: render,
98
+ onComplete: () => { window.location.href = href; },
99
+ defaults: { ease: "expo.inOut", duration: 1.2 }
100
+ });
101
+
102
+ for (let i = 0; i < numPoints; i++) pointsDelay[i] = Math.random() * delayPointsMax;
103
+
104
+ for (let i = 0; i < numPaths; i++) {
105
+ let points = allPoints[i];
106
+ let pathDelay = delayPerPath * i;
107
+ for (let j = 0; j < numPoints; j++) {
108
+ exitTl.to(points, { [j]: 0, ease: "expo.inOut" }, pointsDelay[j] + pathDelay);
109
+ }
110
+ }
111
+ };
112
+ }
113
+
114
+ function initSlideTransition() {
115
+ const overlay = document.querySelector('.sq-page-transition');
116
+ const slide = document.querySelector('.sq-transition-slide');
117
+ if (!overlay || !slide) return null;
118
+
119
+ overlay.classList.add('is-active');
120
+ ariaHidden(overlay, false);
121
+ gsap.set(slide, { yPercent: 0 }); // Covering screen
122
+
123
+ setTimeout(() => {
124
+ gsap.to(slide, {
125
+ yPercent: -100, // Pull up off screen
126
+ duration: 1.2,
127
+ ease: "expo.inOut",
128
+ onComplete: () => {
129
+ overlay.classList.remove('is-active');
130
+ ariaHidden(overlay, true);
131
+ }
132
+ });
133
+ }, 100);
134
+
135
+ return function playExit(href) {
136
+ gsap.set(slide, { yPercent: 100 }); // Stage at bottom
137
+ overlay.classList.add('is-active');
138
+ ariaHidden(overlay, false);
139
+
140
+ gsap.to(slide, {
141
+ yPercent: 0, // Push up to cover screen
142
+ duration: 1.2,
143
+ ease: "expo.inOut",
144
+ onComplete: () => { window.location.href = href; }
145
+ });
146
+ };
147
+ }
148
+
149
+ function initBlindsTransition() {
150
+ const overlay = document.querySelector('.sq-page-transition');
151
+ const blinds = document.querySelectorAll('.blind-strip');
152
+ if (!overlay || !blinds.length) return null;
153
+
154
+ overlay.classList.add('is-active');
155
+ ariaHidden(overlay, false);
156
+ gsap.set(blinds, { yPercent: 0 });
157
+
158
+ setTimeout(() => {
159
+ gsap.to(blinds, {
160
+ yPercent: -100,
161
+ duration: 1.0,
162
+ stagger: 0.1,
163
+ ease: "expo.inOut",
164
+ onComplete: () => {
165
+ overlay.classList.remove('is-active');
166
+ ariaHidden(overlay, true);
167
+ }
168
+ });
169
+ }, 100);
170
+
171
+ return function playExit(href) {
172
+ gsap.set(blinds, { yPercent: 100 });
173
+ overlay.classList.add('is-active');
174
+ ariaHidden(overlay, false);
175
+
176
+ gsap.to(blinds, {
177
+ yPercent: 0,
178
+ duration: 1.0,
179
+ stagger: 0.1,
180
+ ease: "expo.inOut",
181
+ onComplete: () => { window.location.href = href; }
182
+ });
183
+ };
184
+ }
185
+
186
+ function initWaveTransition() {
187
+ const overlay = document.querySelector('.sq-page-transition');
188
+ const path = document.querySelector('.sq-transition-path');
189
+ if (!overlay || !path) return null;
190
+
191
+ // Based on codepen.md logic, but strictly animating properties via GSAP generic object tweening
192
+ // because morphSVG requires both paths to have identical anchor point counts reliably.
193
+
194
+ // We animate a 'progress' value and interpolate the path strings.
195
+ // The curve handles 3 main points: [Left Y, Center Control Y, Right Y]
196
+ // M 0 {L} V {C} Q 50 {CC} 100 {C} V {R} z (approx logic)
197
+
198
+ // Easier approach matching the CodePen but doing the 3 anchor interpolation natively.
199
+ // Mid point pulls up: M 0 100 V 50 Q 50 0 100 50 V 100 z
200
+ let isRevealing = true;
201
+
202
+ // Anchor object to tween
203
+ let wavePoints = {
204
+ sideY: 100,
205
+ curveY: 100
206
+ };
207
+
208
+ function renderWave() {
209
+ // Build the cubic/quad curve natively to avoid MorphSVG shape matching errors
210
+ const d = `M 0 100 V ${wavePoints.sideY} Q 50 ${wavePoints.curveY} 100 ${wavePoints.sideY} V 100 z`;
211
+
212
+ // If we are revealing the page upward, we actually want the shape to pull *off* the top.
213
+ // The above path anchors to the bottom. So to pull off the top, we need to flip the anchor.
214
+ const dReveal = `M 0 0 V ${wavePoints.sideY} Q 50 ${wavePoints.curveY} 100 ${wavePoints.sideY} V 0 z`;
215
+
216
+ path.setAttribute("d", isRevealing ? dReveal : d);
217
+ }
218
+
219
+ // 1. ENTER ANIMATION (Page Load - Reversing the upward sweep)
220
+ isRevealing = true;
221
+ wavePoints.sideY = 100;
222
+ wavePoints.curveY = 100;
223
+ renderWave(); // Fully covered
224
+
225
+ overlay.classList.add('is-active');
226
+ ariaHidden(overlay, false);
227
+
228
+ setTimeout(() => {
229
+ let entryTl = gsap.timeline({
230
+ onUpdate: renderWave,
231
+ onComplete: () => {
232
+ overlay.classList.remove('is-active');
233
+ ariaHidden(overlay, true);
234
+ }
235
+ });
236
+
237
+ // Pull up to -2 over two stages, ensuring it fully clears the screen
238
+ entryTl.to(wavePoints, { sideY: 50, curveY: 100, ease: "power2.in", duration: 0.45 })
239
+ .to(wavePoints, { sideY: -2, curveY: -2, ease: "power2.out", duration: 0.45 });
240
+ }, 100);
241
+
242
+ // 2. RETURN EXIT FUNCTION
243
+ return function playExit(href) {
244
+ isRevealing = false;
245
+ wavePoints.sideY = 100;
246
+ wavePoints.curveY = 100;
247
+ renderWave(); // Start empty at bottom
248
+
249
+ overlay.classList.add('is-active');
250
+ ariaHidden(overlay, false);
251
+
252
+ let exitTl = gsap.timeline({
253
+ onUpdate: renderWave,
254
+ onComplete: () => { window.location.href = href; }
255
+ });
256
+
257
+ // Push up to -2 over two stages to fully clear internal rendering boundaries
258
+ exitTl.to(wavePoints, { sideY: 50, curveY: -2, ease: "power2.in", duration: 0.45 })
259
+ .to(wavePoints, { sideY: -2, curveY: -2, ease: "power2.out", duration: 0.45 });
260
+ };
261
+ }
262
+
263
+ function initPageTransitions() {
264
+ const transitionType = document.body.dataset.sqTransition || 'disabled';
265
+ if (transitionType === 'disabled') return;
266
+
267
+ let triggerExit = null;
268
+
269
+ if (transitionType === 'curve') triggerExit = initMathPathTransition('.shape-overlays__path');
270
+ else if (transitionType === 'wave') triggerExit = initWaveTransition();
271
+ else if (transitionType === 'slide') triggerExit = initSlideTransition();
272
+ else if (transitionType === 'blinds') triggerExit = initBlindsTransition();
273
+
274
+ if (!triggerExit) return;
275
+
276
+ // --- SHARED LINK INTERCEPTION ---
277
+ document.addEventListener('click', (e) => {
278
+ const link = e.target.closest('a');
279
+ if (!link) return;
280
+
281
+ const href = link.getAttribute('href');
282
+ if (!href || href.startsWith('#') || href.startsWith('javascript:') || link.getAttribute('target') === '_blank') return;
283
+
284
+ try {
285
+ const url = new URL(link.href, window.location.origin);
286
+ if (url.origin !== window.location.origin) return;
287
+ if (url.pathname === window.location.pathname && url.hash) return;
288
+ } catch (err) { return; }
289
+
290
+ e.preventDefault();
291
+ triggerExit(href);
292
+ });
293
+ }
294
+
295
+ function ariaHidden(el, bool) {
296
+ if (bool) el.setAttribute('aria-hidden', 'true');
297
+ else el.removeAttribute('aria-hidden');
298
+ }
299
+
300
+ document.addEventListener('DOMContentLoaded', () => {
301
+ initPageTransitions();
302
+ });