@squeditor/squeditor-framework 1.0.4 → 1.0.5
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.
- package/README.md +4 -4
- package/package.json +2 -1
- package/project-template/src/assets/css/fonts.css +2 -0
- package/project-template/src/assets/scss/_base.scss +4 -2
- package/project-template/src/assets/scss/_components.scss +1 -8
- package/project-template/src/assets/scss/_tokens.scss +18 -13
- package/project-template/src/config/site-config.php +1 -0
- package/project-template/src/index.php +2 -2
- package/project-template/src/page-templates/head.php +3 -1
- package/project-template/src/sections/cards/cards-horizontal.php +1 -1
- package/project-template/src/sections/cta/cta-banner.php +1 -1
- package/project-template/src/sections/cta/cta-newsletter.php +1 -1
- package/project-template/src/sections/header/layout-01.php +1 -1
- package/project-template/src/sections/hero/hero-split.php +4 -4
- package/project-template/src/template-parts/footer.php +6 -6
- package/project-template/src/template-parts/header.php +5 -5
- package/project-template/src/template-parts/nav.php +2 -2
- package/project-template/src/template-parts/page-title-bar.php +1 -1
- package/project-template/vite.config.js +8 -0
- package/scripts/build-components.js +3 -6
- package/scripts/scaffold.js +30 -9
package/README.md
CHANGED
|
@@ -4,12 +4,12 @@ We implement AI Agents skills to help you build your website easily in minutes.
|
|
|
4
4
|
|
|
5
5
|
### Showcase and Demo
|
|
6
6
|
|
|
7
|
-
[Main Demo](https://squeditor.com/showcase/main-demo/)
|
|
8
|
-
[All Components](https://squeditor.com/showcase/all-components/)
|
|
9
|
-
[Style Guide](https://squeditor.com/showcase/style-guide/)
|
|
7
|
+
[Main Demo](https://squeditor.com/showcase/main-demo/) |
|
|
8
|
+
[All Components](https://squeditor.com/showcase/all-components/) |
|
|
9
|
+
[Style Guide](https://squeditor.com/showcase/style-guide/) |
|
|
10
10
|
[GSAP Animations](https://squeditor.com/showcase/gsap-animations/)
|
|
11
11
|
|
|
12
|
-
[Full Documentation](https://docs.squeditor.com)
|
|
12
|
+
[Full Documentation](https://docs.squeditor.com/framework/getting-started/introduction)
|
|
13
13
|
|
|
14
14
|
### Key Features
|
|
15
15
|
|
package/package.json
CHANGED
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@squeditor/squeditor-framework",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.5",
|
|
4
4
|
"description": "Squeditor Framework is a high-performance, developer-first framework for building lightning-fast, static websites. It combines the power of PHP-style templating with the modern performance of Tailwind CSS, the interactivity of UIKit 3, and the speed of Vite.",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"publishConfig": {
|
|
7
7
|
"access": "public"
|
|
8
8
|
},
|
|
9
9
|
"scripts": {
|
|
10
|
+
"scaffold": "node scripts/scaffold.js",
|
|
10
11
|
"test": "echo \"Error: no test specified\" && exit 1"
|
|
11
12
|
},
|
|
12
13
|
"repository": {
|
|
@@ -24,7 +24,8 @@ h6,
|
|
|
24
24
|
font-family: var(--sq-font-heading);
|
|
25
25
|
color: var(--sq-color-heading-text);
|
|
26
26
|
font-weight: 600;
|
|
27
|
-
line-height: 1.2;
|
|
27
|
+
line-height: var(--sq-heading-line-height, 1.2);
|
|
28
|
+
letter-spacing: var(--sq-heading-letter-spacing, normal);
|
|
28
29
|
}
|
|
29
30
|
|
|
30
31
|
h1 {
|
|
@@ -75,7 +76,8 @@ h6 {
|
|
|
75
76
|
// Only apply paragraph and list styles if the author didn't supply their own layout classes
|
|
76
77
|
p:not([class]) {
|
|
77
78
|
margin-bottom: 1rem;
|
|
78
|
-
line-height: 1.6;
|
|
79
|
+
line-height: var(--sq-body-line-height, 1.6);
|
|
80
|
+
letter-spacing: var(--sq-body-letter-spacing, normal);
|
|
79
81
|
}
|
|
80
82
|
|
|
81
83
|
ul:not([class]),
|
|
@@ -115,7 +115,7 @@
|
|
|
115
115
|
}
|
|
116
116
|
}
|
|
117
117
|
|
|
118
|
-
.sq
|
|
118
|
+
.sq-header {
|
|
119
119
|
z-index: var(--sq-z-sticky);
|
|
120
120
|
|
|
121
121
|
&--sticky {
|
|
@@ -133,7 +133,6 @@
|
|
|
133
133
|
// ---------------------------------------------------------
|
|
134
134
|
// Container + Expand Container
|
|
135
135
|
// ---------------------------------------------------------
|
|
136
|
-
@layer components {
|
|
137
136
|
.container {
|
|
138
137
|
width: 100%;
|
|
139
138
|
|
|
@@ -168,13 +167,9 @@
|
|
|
168
167
|
overflow: visible;
|
|
169
168
|
}
|
|
170
169
|
|
|
171
|
-
}
|
|
172
|
-
|
|
173
170
|
// ---------------------------------------------------------
|
|
174
171
|
// Form icon group
|
|
175
172
|
// ---------------------------------------------------------
|
|
176
|
-
@layer components {
|
|
177
|
-
|
|
178
173
|
/* Base */
|
|
179
174
|
.form-icon-group {
|
|
180
175
|
position: relative;
|
|
@@ -228,8 +223,6 @@
|
|
|
228
223
|
[dir="rtl"] .form-icon-group.form-icon-flip .form-control.form-control-sm { padding-right: 1rem !important; padding-left: 2.25rem !important; }
|
|
229
224
|
[dir="rtl"] .form-icon-group.form-icon-flip .form-control.form-control-xs { padding-right: 1rem !important; padding-left: 1.75rem !important; }
|
|
230
225
|
|
|
231
|
-
}
|
|
232
|
-
|
|
233
226
|
// ---------------------------------------------------------
|
|
234
227
|
// Page Transitions
|
|
235
228
|
// ---------------------------------------------------------
|
|
@@ -1,16 +1,17 @@
|
|
|
1
1
|
// _tokens.scss — Design tokens as CSS custom properties
|
|
2
2
|
|
|
3
3
|
// 1. Define SASS Variables for calculations
|
|
4
|
-
$color-primary: #
|
|
5
|
-
$color-primary-dark: #
|
|
6
|
-
$color-secondary: #
|
|
7
|
-
$color-secondary-dark: #
|
|
8
|
-
$color-accent: #
|
|
9
|
-
$color-accent-dark: #
|
|
4
|
+
$color-primary: #107466 !default;
|
|
5
|
+
$color-primary-dark: #F0FF44 !default;
|
|
6
|
+
$color-secondary: #1c2020 !default;
|
|
7
|
+
$color-secondary-dark: #fef1e7 !default;
|
|
8
|
+
$color-accent: #e5fdc5 !default;
|
|
9
|
+
$color-accent-dark: #e5fdc5 !default;
|
|
10
10
|
$color-white: #FFFFFF !default;
|
|
11
|
-
$color-muted-text: #
|
|
12
|
-
$color-muted-bg: #
|
|
11
|
+
$color-muted-text: #707070 !default;
|
|
12
|
+
$color-muted-bg: #fef1e7 !default;
|
|
13
13
|
$color-light: #f8f8f8 !default;
|
|
14
|
+
$color-dark: #19191b !default;
|
|
14
15
|
$color-body-bg: #FFFFFF !default;
|
|
15
16
|
$color-body-text: #19191b !default;
|
|
16
17
|
$color-heading-text: #19191b !default;
|
|
@@ -28,6 +29,7 @@ $color-border: rgba(138, 138, 138, 0.196) !default;
|
|
|
28
29
|
--sq-color-muted-text: #{$color-muted-text};
|
|
29
30
|
--sq-color-muted-bg: #{$color-muted-bg};
|
|
30
31
|
--sq-color-light: #{$color-light};
|
|
32
|
+
--sq-color-dark: #{$color-dark};
|
|
31
33
|
--sq-color-body-bg: #{$color-body-bg};
|
|
32
34
|
--sq-color-body-text: #{$color-body-text};
|
|
33
35
|
--sq-color-heading-text: #{$color-heading-text};
|
|
@@ -76,12 +78,12 @@ $color-border: rgba(138, 138, 138, 0.196) !default;
|
|
|
76
78
|
// --- Component Tokens ---
|
|
77
79
|
|
|
78
80
|
// Buttons
|
|
79
|
-
--sq-btn-height: 2.
|
|
81
|
+
--sq-btn-height: 2.75rem;
|
|
80
82
|
--sq-btn-bg: transparent;
|
|
81
83
|
--sq-btn-text: var(--sq-color-body-text);
|
|
82
|
-
--sq-btn-radius: var(--sq-radius-
|
|
83
|
-
--sq-btn-font-size: 1rem;
|
|
84
|
-
--sq-btn-font-weight:
|
|
84
|
+
--sq-btn-radius: var(--sq-radius-md);
|
|
85
|
+
--sq-btn-font-size: 1rem;
|
|
86
|
+
--sq-btn-font-weight: 600;
|
|
85
87
|
|
|
86
88
|
--sq-btn-default-bg: var(--sq-color-light);
|
|
87
89
|
--sq-btn-default-text: var(--sq-color-muted-text);
|
|
@@ -113,7 +115,7 @@ $color-border: rgba(138, 138, 138, 0.196) !default;
|
|
|
113
115
|
// Dropdown
|
|
114
116
|
--sq-dropdown-width: 300px;
|
|
115
117
|
--sq-dropdown-padding: 2rem;
|
|
116
|
-
--sq-dropdown-bg: var(--sq-color-
|
|
118
|
+
--sq-dropdown-bg: var(--sq-color-muted-bg);
|
|
117
119
|
--sq-dropdown-text: var(--sq-color-body-text);
|
|
118
120
|
|
|
119
121
|
// Accordion
|
|
@@ -226,4 +228,7 @@ $color-border: rgba(138, 138, 138, 0.196) !default;
|
|
|
226
228
|
--sq-card-bg: #19191b;
|
|
227
229
|
--sq-card-shadow: none;
|
|
228
230
|
--sq-card-shadow-hover: none;
|
|
231
|
+
|
|
232
|
+
// Dropdown
|
|
233
|
+
--sq-dropdown-bg: var(--sq-color-muted-bg);
|
|
229
234
|
}
|
|
@@ -41,10 +41,10 @@ ob_start();
|
|
|
41
41
|
</p>
|
|
42
42
|
|
|
43
43
|
<div class="flex items-center justify-center gap-4" data-gsap="position: '<-0.5'; from: {y: 20, opacity: 0, filter: 'blur(5px)'}">
|
|
44
|
-
<a href="https://squeditor.com/" class="btn btn-lg btn-secondary
|
|
44
|
+
<a href="https://squeditor.com/" class="btn btn-lg btn-secondary hover:scale-105 transition-transform">
|
|
45
45
|
Try Squeditor
|
|
46
46
|
</a>
|
|
47
|
-
<a href="https://docs.squeditor.com/" class="btn btn-lg !
|
|
47
|
+
<a href="https://docs.squeditor.com/" class="btn btn-lg !border !border-1 !border-solid !border-zinc-200 hover:scale-105 transition-transform">
|
|
48
48
|
View Docs
|
|
49
49
|
</a>
|
|
50
50
|
</div>
|
|
@@ -40,14 +40,16 @@ if (file_exists(__DIR__ . '/../config/active-slider.php')) {
|
|
|
40
40
|
<?php if ($is_vite): ?>
|
|
41
41
|
<!-- Vite Development Environment -->
|
|
42
42
|
<script type="module" src="<?= $vite_server ?>/@vite/client"></script>
|
|
43
|
-
<link rel="stylesheet" href="<?= $vite_server ?>/assets/css/
|
|
43
|
+
<link rel="stylesheet" href="<?= $vite_server ?>/assets/css/fonts.css">
|
|
44
44
|
<link rel="stylesheet" href="<?= $vite_server ?>/assets/css/squeditor-icons.css">
|
|
45
|
+
<link rel="stylesheet" href="<?= $vite_server ?>/assets/css/tailwind.css">
|
|
45
46
|
<?php if ($active_slider): ?><link rel="stylesheet" href="<?= $vite_server ?>/assets/css/slider.min.css"><?php endif; ?>
|
|
46
47
|
<script type="module" src="<?= $vite_server ?>/assets/scss/main.scss"></script>
|
|
47
48
|
<style>html.js-fouc { opacity: 0; transition: opacity 0.15s ease-out; }</style>
|
|
48
49
|
<script>document.documentElement.classList.add('js-fouc');</script>
|
|
49
50
|
<?php else: ?>
|
|
50
51
|
<!-- Production Static Assets -->
|
|
52
|
+
<link rel="stylesheet" href="assets/css/fonts.css">
|
|
51
53
|
<link rel="stylesheet" href="assets/css/squeditor-icons.css">
|
|
52
54
|
<link rel="stylesheet" href="assets/css/tailwind.css">
|
|
53
55
|
<?php if ($active_slider): ?><link rel="stylesheet" href="assets/css/slider.min.css"><?php endif; ?>
|
|
@@ -17,7 +17,7 @@ $items = $items ?? [];
|
|
|
17
17
|
<li class="flex items-center gap-2"><i class="sq-icon-chevron-right opacity-30"></i> <?= htmlspecialchars($feature) ?></li>
|
|
18
18
|
<?php endforeach; ?>
|
|
19
19
|
</ul>
|
|
20
|
-
<span class="absolute top-6 end-6 w-10 h-10 p-0 rounded-full flex items-center justify-center
|
|
20
|
+
<span class="absolute top-6 end-6 w-10 h-10 p-0 rounded-full flex items-center justify-center bg-white group-hover:-rotate-45 transition-transform duration-300">
|
|
21
21
|
<i class="sq-icon-arrow-right"></i>
|
|
22
22
|
</span>
|
|
23
23
|
</div>
|
|
@@ -7,7 +7,7 @@ $button_url = $button_url ?? '#';
|
|
|
7
7
|
$secondary_button_text = $secondary_button_text ?? '';
|
|
8
8
|
$hint_text = $hint_text ?? '';
|
|
9
9
|
?>
|
|
10
|
-
<section class="py-32 text-center border-t border-zinc-300 border-opacity-30 dark:border-opacity-5">
|
|
10
|
+
<section class="sq-cta-banner py-16 md:py-24 lg:py-32 text-center border-t border-zinc-300 border-opacity-30 dark:border-opacity-5">
|
|
11
11
|
<div class="max-w-4xl mx-auto px-6">
|
|
12
12
|
<h2 class="text-4xl md:text-5xl font-bold mb-4 tracking-tighter">
|
|
13
13
|
<?= $heading ?>
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
$heading = $heading ?? 'Subscribe to our newsletter';
|
|
4
4
|
$subheading = $subheading ?? 'Get the latest updates and news from our team.';
|
|
5
5
|
?>
|
|
6
|
-
<section class="py-20 bg-
|
|
6
|
+
<section class="py-20 bg-muted dark:bg-opacity-40">
|
|
7
7
|
<div class="max-w-7xl mx-auto px-6 flex flex-col items-center justify-between gap-8">
|
|
8
8
|
<div class="mb-8 md:mb-0 md:w-1/2">
|
|
9
9
|
<h2 class="text-4xl font-bold text-center m-0"><?= htmlspecialchars($heading) ?></h2>
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
$isDark = $isDark ?? false;
|
|
5
5
|
$isFloat = $isFloat ?? false;
|
|
6
6
|
|
|
7
|
-
$headerClasses = 'sq
|
|
7
|
+
$headerClasses = 'sq-header w-full z-[1000]';
|
|
8
8
|
if ($isFloat) $headerClasses .= ' absolute top-0';
|
|
9
9
|
if ($isDark) $headerClasses .= ' dark-mode text-white bg-zinc-900';
|
|
10
10
|
else $headerClasses .= ' bg-white border-b';
|
|
@@ -62,13 +62,13 @@ $processed_heading = str_replace(
|
|
|
62
62
|
</h2>
|
|
63
63
|
|
|
64
64
|
<!-- Subheading -->
|
|
65
|
-
<p class="text-lg md:text-xl text-muted mb-10 max-w-md
|
|
65
|
+
<p class="text-lg md:text-xl text-muted mb-10 max-w-md"
|
|
66
66
|
data-gsap="from: {opacity: 0, y: 20}; duration: 0.8; delay: 0.4">
|
|
67
67
|
<?= htmlspecialchars($args['subheading']) ?>
|
|
68
68
|
</p>
|
|
69
69
|
|
|
70
70
|
<!-- CTA Button -->
|
|
71
|
-
<div data-gsap="from: {opacity: 0, y: 16}; duration: 0.6; delay: 0.7" class="self-start mb-16">
|
|
71
|
+
<div data-gsap="from: {opacity: 0, y: 16}; duration: 0.6; delay: 0.7" class="self-start mb-8 lg:mb-16">
|
|
72
72
|
<a href="<?= htmlspecialchars($args['cta_url']) ?>" class="btn btn-secondary min-h-[48px] !px-8 !py-4 !text-base !shadow-lg !shadow-sq-primary/30 flex items-center gap-2 transition-transform hover:scale-105">
|
|
73
73
|
<?= htmlspecialchars($args['cta_label']) ?>
|
|
74
74
|
<i class="sq-icon sq-icon-arrow-up-right text-lg leading-none mt-0.5"></i>
|
|
@@ -96,8 +96,8 @@ $processed_heading = str_replace(
|
|
|
96
96
|
<div class="relative h-[400px] md:h-[700px]">
|
|
97
97
|
|
|
98
98
|
<!-- Image Wrapper -->
|
|
99
|
-
<div class="h-full rounded-
|
|
100
|
-
<img src="<?= htmlspecialchars($args['image_src']) ?>" alt="<?= htmlspecialchars($args['image_alt']) ?>" class="w-full h-full object-cover
|
|
99
|
+
<div class="h-full rounded-3xl overflow-hidden" data-gsap="from: {clipPath: 'inset(0 0 100% 0)'}; duration: 2; ease: expo.inOut;">
|
|
100
|
+
<img src="<?= htmlspecialchars($args['image_src']) ?>" alt="<?= htmlspecialchars($args['image_alt']) ?>" class="w-full h-full object-cover">
|
|
101
101
|
</div>
|
|
102
102
|
|
|
103
103
|
<!-- Floating Services Container -->
|
|
@@ -9,8 +9,8 @@ if ($layout !== 'default') {
|
|
|
9
9
|
}
|
|
10
10
|
?>
|
|
11
11
|
<!-- Site Footer -->
|
|
12
|
-
<footer id="sq_footer" class="sq
|
|
13
|
-
<div class="sq
|
|
12
|
+
<footer id="sq_footer" class="sq-footer py-12 md:py-18 lg:py-24 border-t dark:border-transparent dark:bg-black/40">
|
|
13
|
+
<div class="sq-footer-inner max-w-7xl mx-auto px-6 grid grid-cols-1 md:grid-cols-5 gap-6 md:gap-8 lg:gap-12">
|
|
14
14
|
<div class="sq--footer--brand md:col-span-2">
|
|
15
15
|
<div class="flex items-center gap-2 mb-6">
|
|
16
16
|
<a href="index.html" class="sq--logo flex items-center gap-2 group">
|
|
@@ -20,7 +20,7 @@ if ($layout !== 'default') {
|
|
|
20
20
|
<h1 class="font-bold text-xl m-0 tracking-tight"><?= htmlspecialchars($site['name']) ?></h1>
|
|
21
21
|
</a>
|
|
22
22
|
</div>
|
|
23
|
-
<p class="text-sm max-w-xs leading-relaxed mb-
|
|
23
|
+
<p class="text-sm max-w-xs leading-relaxed mb-6">
|
|
24
24
|
<?= htmlspecialchars($site['description']) ?>
|
|
25
25
|
</p>
|
|
26
26
|
<div class="flex gap-4">
|
|
@@ -61,11 +61,11 @@ if ($layout !== 'default') {
|
|
|
61
61
|
</ul>
|
|
62
62
|
</div>
|
|
63
63
|
</div>
|
|
64
|
-
<div class="sq
|
|
64
|
+
<div class="sq-footer-divider max-w-7xl mx-auto px-6 mt-8 md:mt-12 lg:mt-16 mb-8">
|
|
65
65
|
<hr>
|
|
66
66
|
</div>
|
|
67
|
-
<div class="sq
|
|
68
|
-
<p>© <?= date('Y') ?> <?= htmlspecialchars($site['name']) ?>. Built
|
|
67
|
+
<div class="sq-footer-bottom max-w-7xl mx-auto px-6 flex flex-col md:flex-row justify-between items-center gap-4 text-sm text-muted">
|
|
68
|
+
<p>© <?= date('Y') ?> <?= htmlspecialchars($site['name']) ?>. Built with ❤️ by Expert Developers.</p>
|
|
69
69
|
<div class="flex gap-8">
|
|
70
70
|
<a href="#" class="hover:text-secondary transition-colors">Terms of Service</a>
|
|
71
71
|
<a href="#" class="hover:text-secondary transition-colors">Privacy Policy</a>
|
|
@@ -11,8 +11,8 @@ if ($layout !== 'default') {
|
|
|
11
11
|
}
|
|
12
12
|
?>
|
|
13
13
|
<!-- Site Header -->
|
|
14
|
-
<header id="sq_header" class="sq
|
|
15
|
-
<div class="sq
|
|
14
|
+
<header id="sq_header" class="sq-header absolute w-full top-0 z-[1000]" data-gsap="from: {y: -80, opacity: 0}; to: {y: 0, opacity: 1}; duration: 1.2; ease: expo.inOut;">
|
|
15
|
+
<div class="sq-header-inner max-w-7xl mx-auto px-6 h-20 flex items-center justify-between">
|
|
16
16
|
|
|
17
17
|
<!-- Logo -->
|
|
18
18
|
<a href="index.html" class="sq--logo flex items-center gap-2 group">
|
|
@@ -23,17 +23,17 @@ if ($layout !== 'default') {
|
|
|
23
23
|
</a>
|
|
24
24
|
|
|
25
25
|
<!-- Desktop Nav (Centered) -->
|
|
26
|
-
<div class="sq
|
|
26
|
+
<div class="sq-header-nav items-center absolute left-1/2 -translate-x-1/2 hidden lg:flex">
|
|
27
27
|
<?php get_template_part('nav'); ?>
|
|
28
28
|
</div>
|
|
29
29
|
|
|
30
30
|
<!-- Right Side / CTA -->
|
|
31
|
-
<div class="sq
|
|
31
|
+
<div class="sq-header-cta flex items-center gap-6">
|
|
32
32
|
<a href="#" class="sq-nav-link text-base font-medium text-zinc-900 dark:text-white !text-opacity-70 hover:text-secondary hover:!text-opacity-100 transition-colors hidden md:inline-block">Log in</a>
|
|
33
33
|
<a href="https://squeditor.com/" class="btn btn-secondary !hidden md:!inline-flex">Try Squeditor</a>
|
|
34
34
|
|
|
35
35
|
<!-- Mobile Toggle -->
|
|
36
|
-
<button class="sq
|
|
36
|
+
<button class="sq-header-mobile-toggle md:hidden" data-gsap-toggle="#sq_offcanvas_creative" type="button" aria-label="Menu">
|
|
37
37
|
<span data-uk-icon="icon: menu; ratio: 1.5"></span>
|
|
38
38
|
</button>
|
|
39
39
|
</div>
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
<?php
|
|
2
2
|
// src/template-parts/nav.php
|
|
3
3
|
$is_mobile = $mobile ?? false;
|
|
4
|
-
$nav_class = $is_mobile ? 'flex flex-col space-y-4' : 'flex space-x-
|
|
4
|
+
$nav_class = $is_mobile ? 'flex flex-col space-y-4' : 'flex space-x-8 items-center m-0 p-0';
|
|
5
5
|
?>
|
|
6
6
|
<nav>
|
|
7
7
|
<ul class="<?= $nav_class ?>">
|
|
8
8
|
<?php foreach ($site['nav'] as $item): ?>
|
|
9
9
|
<li>
|
|
10
|
-
<a href="<?= htmlspecialchars($item['url']) ?>" class="sq-nav-link
|
|
10
|
+
<a href="<?= htmlspecialchars($item['url']) ?>" class="sq-nav-link">
|
|
11
11
|
<?= htmlspecialchars($item['label']) ?>
|
|
12
12
|
</a>
|
|
13
13
|
</li>
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
// src/template-parts/page-title-bar.php
|
|
3
3
|
$title = $title ?? 'Page Title';
|
|
4
4
|
$subtitle = $subtitle ?? '';
|
|
5
|
-
$class = $class ?? 'py-20 text-center bg-
|
|
5
|
+
$class = $class ?? 'py-20 text-center bg-muted dark:bg-opacity-40';
|
|
6
6
|
?>
|
|
7
7
|
<div class="<?= htmlspecialchars($class) ?>">
|
|
8
8
|
<div class="max-w-7xl mx-auto px-6">
|
|
@@ -19,6 +19,7 @@ export default defineConfig({
|
|
|
19
19
|
main_css: path.resolve(__dirname, 'src/assets/scss/main.scss'),
|
|
20
20
|
tailwind: path.resolve(__dirname, 'src/assets/css/tailwind.css'),
|
|
21
21
|
'squeditor-icons': path.resolve(__dirname, 'src/assets/css/squeditor-icons.css'),
|
|
22
|
+
'fonts': path.resolve(__dirname, 'src/assets/css/fonts.css'),
|
|
22
23
|
},
|
|
23
24
|
output: {
|
|
24
25
|
entryFileNames: 'assets/js/[name].js',
|
|
@@ -60,6 +61,13 @@ export default defineConfig({
|
|
|
60
61
|
name: 'php-watch',
|
|
61
62
|
handleHotUpdate({ file, server }) {
|
|
62
63
|
if (file.endsWith('.php')) {
|
|
64
|
+
// Force Vite to invalidate CSS modules so Tailwind generates new classes
|
|
65
|
+
const tailwindModule = server.moduleGraph.getModuleById(path.resolve(__dirname, 'src/assets/css/tailwind.css'));
|
|
66
|
+
if (tailwindModule) server.moduleGraph.invalidateModule(tailwindModule);
|
|
67
|
+
|
|
68
|
+
const scssModule = server.moduleGraph.getModuleById(path.resolve(__dirname, 'src/assets/scss/main.scss'));
|
|
69
|
+
if (scssModule) server.moduleGraph.invalidateModule(scssModule);
|
|
70
|
+
|
|
63
71
|
server.ws.send({ type: 'full-reload' });
|
|
64
72
|
}
|
|
65
73
|
}
|
|
@@ -77,8 +77,7 @@ scssPaths.forEach(f => {
|
|
|
77
77
|
fs.writeFileSync(path.join(outputJsDir, 'uikit-components.js'), jsBundle);
|
|
78
78
|
fs.writeFileSync(path.join(outputScssDir, '_uikit_dynamic.scss'), scssImports);
|
|
79
79
|
|
|
80
|
-
console.log('[Squeditor] ✅
|
|
81
|
-
console.log(` Components included: _core, ${selectedComponents.join(', ')}`);
|
|
80
|
+
console.log('[Squeditor] ✅ UIkit3 components built successfully.');
|
|
82
81
|
|
|
83
82
|
// Generate src/config/active-components.php for the style-guide page
|
|
84
83
|
const phpConfigDir = path.join(projectRoot, 'src/config');
|
|
@@ -128,7 +127,7 @@ if (fs.existsSync(mainScssPath) && config.themes) {
|
|
|
128
127
|
// Ensure exactly one trailing newline
|
|
129
128
|
mainScss = mainScss.trim() + '\n' + themeImports;
|
|
130
129
|
fs.writeFileSync(mainScssPath, mainScss);
|
|
131
|
-
console.log(`[Squeditor] 🎨
|
|
130
|
+
console.log(`[Squeditor] 🎨 Ready themes: ${Object.keys(config.themes).join(', ')}`);
|
|
132
131
|
}
|
|
133
132
|
|
|
134
133
|
// Generate Dynamic Slider Config Import
|
|
@@ -141,7 +140,7 @@ if (sliderConfig.library === 'swiper') {
|
|
|
141
140
|
sliderImportCode += 'import \'./modules/splide-init.js\';\n';
|
|
142
141
|
}
|
|
143
142
|
fs.writeFileSync(dynamicSliderPath, sliderImportCode);
|
|
144
|
-
console.log(`[Squeditor] 🎠
|
|
143
|
+
console.log(`[Squeditor] 🎠 Selected slider library: ${sliderConfig.library || 'none'}`);
|
|
145
144
|
|
|
146
145
|
// Copy slider library CSS to src/assets/css/slider.min.css
|
|
147
146
|
// This keeps the CSS separate from main.js and gives it a clear, descriptive filename
|
|
@@ -150,7 +149,6 @@ if (sliderConfig.library === 'splide') {
|
|
|
150
149
|
const splideCssPath = path.join(projectRoot, 'node_modules/@splidejs/splide/dist/css/splide.min.css');
|
|
151
150
|
if (fs.existsSync(splideCssPath)) {
|
|
152
151
|
fs.copyFileSync(splideCssPath, sliderCssDest);
|
|
153
|
-
console.log('[Squeditor] 📎 Copied Splide CSS → src/assets/css/slider.min.css');
|
|
154
152
|
} else {
|
|
155
153
|
console.warn('[Squeditor] ⚠️ Splide CSS not found at expected path.');
|
|
156
154
|
fs.writeFileSync(sliderCssDest, '/* Splide CSS not found */\n');
|
|
@@ -172,7 +170,6 @@ if (sliderConfig.library === 'splide') {
|
|
|
172
170
|
}
|
|
173
171
|
}
|
|
174
172
|
fs.writeFileSync(sliderCssDest, combinedCss);
|
|
175
|
-
console.log('[Squeditor] 📎 Copied Swiper CSS → src/assets/css/slider.min.css');
|
|
176
173
|
} else {
|
|
177
174
|
// No slider configured — write an empty placeholder so head.php link doesn't 404
|
|
178
175
|
fs.writeFileSync(sliderCssDest, '/* No slider library configured */\n');
|
package/scripts/scaffold.js
CHANGED
|
@@ -14,7 +14,24 @@ if (!projectName) {
|
|
|
14
14
|
let destIndex = args.indexOf('--dest');
|
|
15
15
|
let destPath = destIndex !== -1 ? args[destIndex + 1] : projectName;
|
|
16
16
|
const sourceDir = path.join(__dirname, '..', 'project-template');
|
|
17
|
-
|
|
17
|
+
|
|
18
|
+
// Check if running directly inside the cloned framework repository
|
|
19
|
+
let isInsideRepo = false;
|
|
20
|
+
try {
|
|
21
|
+
const pkgPath = path.join(process.cwd(), 'package.json');
|
|
22
|
+
if (fs.existsSync(pkgPath)) {
|
|
23
|
+
const pkg = require(pkgPath);
|
|
24
|
+
if (pkg.name === '@squeditor/squeditor-framework') {
|
|
25
|
+
isInsideRepo = true;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
} catch (e) {}
|
|
29
|
+
|
|
30
|
+
// If running inside the repo, scaffold as a sibling (../destPath).
|
|
31
|
+
// Otherwise scaffold in the current directory.
|
|
32
|
+
const targetDir = isInsideRepo
|
|
33
|
+
? path.resolve(process.cwd(), '..', destPath)
|
|
34
|
+
: path.resolve(process.cwd(), destPath);
|
|
18
35
|
|
|
19
36
|
if (!fs.existsSync(sourceDir)) {
|
|
20
37
|
console.error(`Source template directory does not exist: ${sourceDir}`);
|
|
@@ -47,14 +64,18 @@ function copyDirectory(src, dest, ignoreList = []) {
|
|
|
47
64
|
console.log(`[Squeditor] Scaffolding new project: ${projectName}...`);
|
|
48
65
|
|
|
49
66
|
// 1. Copy the framework core
|
|
50
|
-
|
|
51
|
-
const
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
67
|
+
if (!isInsideRepo) {
|
|
68
|
+
const frameworkSourceDir = path.join(__dirname, '..');
|
|
69
|
+
const frameworkTargetDir = path.resolve(process.cwd(), 'squeditor-framework');
|
|
70
|
+
|
|
71
|
+
if (!fs.existsSync(frameworkTargetDir)) {
|
|
72
|
+
console.log(`[Squeditor] Installing local framework core at ./squeditor-framework...`);
|
|
73
|
+
// Pass the name of the target directory to the ignore list to prevent infinite loop
|
|
74
|
+
const ignoreCoreList = ['project-template', 'showcase', 'node_modules', '.git', '.github', 'squeditor-framework'];
|
|
75
|
+
copyDirectory(frameworkSourceDir, frameworkTargetDir, ignoreCoreList);
|
|
76
|
+
}
|
|
77
|
+
} else {
|
|
78
|
+
console.log(`[Squeditor] Running inside framework repo. Skipping core installation (using repo).`);
|
|
58
79
|
}
|
|
59
80
|
|
|
60
81
|
// 2. Copy the project template
|