Skip to content

Commit 1bf8bbb

Browse files
authored
Merge pull request #9
Enhance demo with functional buttons and sample content
2 parents 8e6c751 + 3bb9ee6 commit 1bf8bbb

2 files changed

Lines changed: 281 additions & 4 deletions

File tree

‎projects/demo/src/app/app.ts‎

Lines changed: 32 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { Component, inject, signal } from '@angular/core';
22
import { GrapesJsEditorComponent, GrapesJsEditorService } from 'grapesjs-angular';
33
import type { Editor, ProjectData } from 'grapesjs';
4+
import { SAMPLE_HTML, SAMPLE_CSS } from './sample-content';
45

56
@Component({
67
selector: 'demo-root',
@@ -14,7 +15,8 @@ export class App {
1415
protected htmlOutput = signal('');
1516

1617
onEditorReady(editor: Editor): void {
17-
console.log('[Demo] Editor ready', editor);
18+
editor.setComponents(SAMPLE_HTML);
19+
editor.setStyle(SAMPLE_CSS);
1820
}
1921

2022
onProjectSaved(data: ProjectData): void {
@@ -27,16 +29,42 @@ export class App {
2729

2830
save(): void {
2931
const data = this.editorService.getProjectData();
30-
console.log('[Demo] Save:', data);
32+
if (!data) return;
33+
this.downloadFile('grapesjs-project.json', JSON.stringify(data, null, 2), 'application/json');
3134
}
3235

3336
getHtml(): void {
3437
const html = this.editorService.getHtml() ?? '';
35-
this.htmlOutput.set(html);
38+
const css = this.editorService.getCss() ?? '';
39+
const fullHtml = `<!DOCTYPE html>
40+
<html lang="en">
41+
<head>
42+
<meta charset="UTF-8">
43+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
44+
<title>GrapesJS Export</title>
45+
<style>${css}</style>
46+
</head>
47+
<body>${html}</body>
48+
</html>`;
49+
this.htmlOutput.set(fullHtml);
50+
this.downloadFile('grapesjs-export.html', fullHtml, 'text/html');
3651
}
3752

3853
reset(): void {
39-
this.editorService.loadProjectData({} as ProjectData);
54+
const editor = this.editorService.editor();
55+
if (!editor) return;
56+
editor.setComponents(SAMPLE_HTML);
57+
editor.setStyle(SAMPLE_CSS);
4058
this.htmlOutput.set('');
4159
}
60+
61+
private downloadFile(filename: string, content: string, mimeType: string): void {
62+
const blob = new Blob([content], { type: mimeType });
63+
const url = URL.createObjectURL(blob);
64+
const a = document.createElement('a');
65+
a.href = url;
66+
a.download = filename;
67+
a.click();
68+
URL.revokeObjectURL(url);
69+
}
4270
}
Lines changed: 249 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,249 @@
1+
export const SAMPLE_HTML = `
2+
<header class="site-header">
3+
<div class="header-inner">
4+
<span class="site-name">MyWebsite</span>
5+
<nav class="site-nav">
6+
<a href="#features">Features</a>
7+
<a href="#about">About</a>
8+
<a href="#contact">Contact</a>
9+
</nav>
10+
</div>
11+
</header>
12+
13+
<section class="hero">
14+
<h1>Build Something Amazing</h1>
15+
<p class="hero-subtitle">A simple, mobile-friendly website template to get you started. Drag, drop, and customize to make it your own.</p>
16+
<a href="#features" class="cta-button">Explore Features</a>
17+
</section>
18+
19+
<section id="features" class="features">
20+
<h2>Features</h2>
21+
<div class="features-grid">
22+
<div class="feature-card">
23+
<h3>Responsive Design</h3>
24+
<p>Looks great on any device — phone, tablet, or desktop. Built with flexible layouts that adapt to any screen size.</p>
25+
</div>
26+
<div class="feature-card">
27+
<h3>Easy to Customize</h3>
28+
<p>Change colors, text, and layout with the visual editor. No coding required to make this template your own.</p>
29+
</div>
30+
<div class="feature-card">
31+
<h3>Fast & Lightweight</h3>
32+
<p>Clean HTML and CSS with no unnecessary dependencies. Your site loads quickly and runs smoothly.</p>
33+
</div>
34+
</div>
35+
</section>
36+
37+
<section id="about" class="about">
38+
<h2>About Us</h2>
39+
<p>We believe great websites should be accessible to everyone. This template demonstrates what you can build with GrapesJS and a little creativity. Edit any element on this page — change the text, rearrange sections, or add your own components from the block panel.</p>
40+
</section>
41+
42+
<footer id="contact" class="site-footer">
43+
<div class="footer-inner">
44+
<p>&copy; 2026 MyWebsite. All rights reserved.</p>
45+
<nav class="footer-nav">
46+
<a href="#features">Features</a>
47+
<a href="#about">About</a>
48+
<a href="#">Privacy</a>
49+
<a href="#">Terms</a>
50+
</nav>
51+
</div>
52+
</footer>
53+
`;
54+
55+
export const SAMPLE_CSS = `
56+
* {
57+
box-sizing: border-box;
58+
margin: 0;
59+
padding: 0;
60+
}
61+
62+
body {
63+
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
64+
color: #333;
65+
line-height: 1.6;
66+
}
67+
68+
.site-header {
69+
background: #1a1a2e;
70+
color: #fff;
71+
padding: 16px 24px;
72+
}
73+
74+
.header-inner {
75+
max-width: 960px;
76+
margin: 0 auto;
77+
display: flex;
78+
justify-content: space-between;
79+
align-items: center;
80+
flex-wrap: wrap;
81+
gap: 12px;
82+
}
83+
84+
.site-name {
85+
font-size: 20px;
86+
font-weight: 700;
87+
letter-spacing: -0.5px;
88+
}
89+
90+
.site-nav {
91+
display: flex;
92+
gap: 20px;
93+
flex-wrap: wrap;
94+
}
95+
96+
.site-nav a {
97+
color: #ccc;
98+
text-decoration: none;
99+
font-size: 14px;
100+
}
101+
102+
.site-nav a:hover {
103+
color: #fff;
104+
}
105+
106+
.hero {
107+
background: linear-gradient(135deg, #16213e, #0f3460);
108+
color: #fff;
109+
text-align: center;
110+
padding: 80px 24px;
111+
}
112+
113+
.hero h1 {
114+
font-size: 40px;
115+
font-weight: 800;
116+
margin-bottom: 16px;
117+
letter-spacing: -1px;
118+
}
119+
120+
.hero-subtitle {
121+
font-size: 18px;
122+
color: #b8c6db;
123+
max-width: 560px;
124+
margin: 0 auto 32px;
125+
}
126+
127+
.cta-button {
128+
display: inline-block;
129+
background: #e94560;
130+
color: #fff;
131+
padding: 14px 32px;
132+
border-radius: 6px;
133+
text-decoration: none;
134+
font-weight: 600;
135+
font-size: 16px;
136+
}
137+
138+
.cta-button:hover {
139+
background: #c73e54;
140+
}
141+
142+
.features {
143+
padding: 64px 24px;
144+
max-width: 960px;
145+
margin: 0 auto;
146+
}
147+
148+
.features h2 {
149+
text-align: center;
150+
font-size: 28px;
151+
margin-bottom: 40px;
152+
}
153+
154+
.features-grid {
155+
display: grid;
156+
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
157+
gap: 24px;
158+
}
159+
160+
.feature-card {
161+
background: #f8f9fa;
162+
border: 1px solid #e9ecef;
163+
border-radius: 8px;
164+
padding: 32px 24px;
165+
}
166+
167+
.feature-card h3 {
168+
font-size: 18px;
169+
margin-bottom: 12px;
170+
color: #1a1a2e;
171+
}
172+
173+
.feature-card p {
174+
font-size: 14px;
175+
color: #666;
176+
}
177+
178+
.about {
179+
background: #f0f4f8;
180+
padding: 64px 24px;
181+
}
182+
183+
.about h2 {
184+
text-align: center;
185+
font-size: 28px;
186+
margin-bottom: 24px;
187+
}
188+
189+
.about p {
190+
max-width: 640px;
191+
margin: 0 auto;
192+
font-size: 16px;
193+
color: #555;
194+
}
195+
196+
.site-footer {
197+
background: #1a1a2e;
198+
color: #999;
199+
padding: 32px 24px;
200+
}
201+
202+
.footer-inner {
203+
max-width: 960px;
204+
margin: 0 auto;
205+
display: flex;
206+
justify-content: space-between;
207+
align-items: center;
208+
flex-wrap: wrap;
209+
gap: 16px;
210+
}
211+
212+
.footer-inner p {
213+
font-size: 13px;
214+
}
215+
216+
.footer-nav {
217+
display: flex;
218+
gap: 16px;
219+
}
220+
221+
.footer-nav a {
222+
color: #999;
223+
text-decoration: none;
224+
font-size: 13px;
225+
}
226+
227+
.footer-nav a:hover {
228+
color: #fff;
229+
}
230+
231+
@media (max-width: 600px) {
232+
.hero h1 {
233+
font-size: 28px;
234+
}
235+
.hero-subtitle {
236+
font-size: 15px;
237+
}
238+
.hero {
239+
padding: 48px 20px;
240+
}
241+
.features, .about {
242+
padding: 40px 20px;
243+
}
244+
.footer-inner {
245+
flex-direction: column;
246+
text-align: center;
247+
}
248+
}
249+
`;

0 commit comments

Comments
 (0)