beta/code-blocks (#1)

Reviewed-on: #1
Co-authored-by: obvTiger <obvtiger@epilogue.team>
Co-committed-by: obvTiger <obvtiger@epilogue.team>
This commit is contained in:
obvTiger 2025-04-01 15:22:15 +02:00 committed by obvtiger
parent 362b7aa15e
commit d125640fe7
26 changed files with 1816 additions and 102 deletions

View file

@ -0,0 +1,190 @@
page(favicon:"/favicon.ico") {
title { "Blueprint - Reactive Example" }
description { "Example of reactive values in Blueprint" }
keywords { "blueprint, javascript, reactive, state" }
author { "Blueprint Team" }
}
navbar {
horizontal {
link(href:index) { text(bold) { "Blueprint" } }
links {
link(href:index) { "Home" }
link(href:examples) { "Examples" }
link(href:docs) { "Docs" }
}
}
}
section(wide, centered) {
vertical(centered) {
title(huge) { "Reactive Values Demo" }
text { "Demonstration of reactive state management in Blueprint" }
}
}
section(wide) {
title { "Counter Example" }
vertical(centered) {
// Notice the ID uses underscore format. - is not allowed
text(id:counter_value) { "0" }
horizontal(centered) {
button-secondary(id:decrease_btn) {
"Decrease"
@client {
// Use the reactive counter_value with numberValue
const currentValue = counter_value.numberValue;
counter_value.setNumber(currentValue - 1);
console.log("Counter decreased to", currentValue - 1);
}
}
button(id:increase_btn) {
"Increase"
@client {
// Use the reactive counter_value with numberValue
const currentValue = counter_value.numberValue;
counter_value.setNumber(currentValue + 1);
console.log("Counter increased to", currentValue + 1);
}
}
}
}
}
section(wide) {
title { "Color Changer with Reactive Elements" }
vertical(centered) {
// Element with explicit ID that will be styled
card(id:color_target, raised) {
title { "Change My Background" }
text { "Click the buttons below to change my background color" }
}
// Display the current color
text(subtle, id:color_display) { "Current color: None" }
horizontal(centered) {
button-secondary(id:red_btn) {
"Red"
@client {
// Using reactive methods
color_target.setStyle("backgroundColor", "#e74c3c");
color_display.set("Current color: Red");
}
}
button-secondary(id:green_btn) {
"Green"
@client {
// Using reactive methods
color_target.setStyle("backgroundColor", "#2ecc71");
color_display.set("Current color: Green");
}
}
button-secondary(id:blue_btn) {
"Blue"
@client {
// Using reactive methods
color_target.setStyle("backgroundColor", "#3498db");
color_display.set("Current color: Blue");
}
}
button-secondary(id:reset_btn) {
"Reset"
@client {
// Using reactive methods
color_target.setStyle("backgroundColor", "");
color_display.set("Current color: None");
}
}
}
}
}
section(wide) {
title { "Data Types Example" }
vertical(centered) {
horizontal(centered) {
vertical {
text(bold) { "Number:" }
text(id:number_display) { "42" }
}
vertical {
text(bold) { "Text:" }
text(id:text_display) { "Hello Blueprint" }
}
vertical {
text(bold) { "Boolean:" }
text(id:boolean_display) { "true" }
}
}
horizontal(centered) {
button-secondary(id:modify_values_btn) {
"Modify Values"
@client {
// Use type-specific methods
number_display.setNumber(number_display.numberValue * 2);
text_display.set(text_display.value + "!");
boolean_display.set(!boolean_display.booleanValue);
console.log("Number value:", number_display.numberValue);
console.log("Text value:", text_display.textValue);
console.log("Boolean value:", boolean_display.booleanValue);
}
}
button-secondary(id:reset_values_btn) {
"Reset Values"
@client {
number_display.setNumber(42);
text_display.set("Hello Blueprint");
boolean_display.set("true");
}
}
}
}
}
section(wide) {
title { "Subscription Example" }
vertical(centered) {
// Input and subscribed elements
input(id:user_input) { "Type something..." }
text(bold) { "Live Preview:" }
text(id:preview_output) { "Type something..." }
// Add a client block to handle typing
@client {
// Set up the input to update the preview on input
user_input.element.addEventListener("input", function(e) {
// Use the reactive API to update the preview
preview_output.set(e.target.value);
});
// Example of subscription - will log changes to the console
preview_output.subscribe(function(newValue) {
console.log("Preview content changed to:", newValue);
});
}
}
}

View file

@ -0,0 +1,163 @@
page(favicon:"/favicon.ico") {
title { "Blueprint - Server Form Example" }
description { "Example of server-side form processing in Blueprint" }
keywords { "blueprint, javascript, server, api, form" }
author { "Blueprint Team" }
}
navbar {
horizontal {
link(href:index) { text(bold) { "Blueprint" } }
links {
link(href:index) { "Home" }
link(href:examples) { "Examples" }
link(href:docs) { "Docs" }
}
}
}
section(wide, centered) {
vertical(centered) {
title(huge) { "Server-Side Form Processing" }
text { "Demonstration of server-side form handling with Blueprint" }
}
}
section(wide) {
title { "Contact Form Example" }
vertical(centered) {
card(raised) {
title { "Submit a Message" }
text { "Fill out the form below to submit a message to the server." }
vertical {
text(bold) { "Your Name" }
input(id:user_name) { "John Doe" }
text(bold) { "Your Email" }
input(id:user_email) { "john@example.com" }
text(bold) { "Your Message" }
textarea(id:user_message) { "Hello from Blueprint!" }
// Display the server response
text(id:form_result) { "" }
button(id:submit_form) {
"Submit Form"
// Server block with parameters specifying which input values to include
@server(user_name, user_email, user_message) {
console.log("Form submission received:");
console.log("Name:", user_name);
console.log("Email:", user_email);
console.log("Message:", user_message);
// Validate inputs
const errors = [];
if (!user_name || user_name.length < 2) {
errors.push("Name is too short");
}
if (!user_email || !user_email.includes('@')) {
errors.push("Invalid email address");
}
if (!user_message || user_message.length < 5) {
errors.push("Message is too short");
}
// Return error message if validation fails
if (errors.length > 0) {
return res.status(400).json({
form_result: "Error: " + errors.join(", ")
});
}
// Process the form (in a real app, this might save to a database)
const timestamp = new Date().toISOString();
// Return success response that will update the form_result element
return res.status(200).json({
form_result: `Thank you, ${user_name}! Your message was received at ${timestamp}.`
});
}
}
}
}
}
}
section(wide) {
title { "User Registration Example" }
vertical(centered) {
card(raised) {
title { "Register a New Account" }
text { "Fill out the form below to register a new account." }
vertical {
text(bold) { "Username" }
input(id:username) { "newuser123" }
text(bold) { "Email" }
input(id:email) { "newuser@example.com" }
text(bold) { "Password" }
input(id:password) { "password123" }
text(bold) { "Confirm Password" }
input(id:confirm_password) { "password123" }
// Display the registration status
text(id:registration_status) { "" }
button(id:register_user) {
"Register"
@server(username, email, password, confirm_password) {
console.log("Registration request for username:", username);
// Validate username
if (!username || username.length < 4) {
return res.status(400).json({
registration_status: "Error: Username must be at least 4 characters"
});
}
// Validate email
if (!email || !email.includes('@')) {
return res.status(400).json({
registration_status: "Error: Invalid email address"
});
}
// Validate password
if (!password || password.length < 8) {
return res.status(400).json({
registration_status: "Error: Password must be at least 8 characters"
});
}
// Check password matching
if (password !== confirm_password) {
return res.status(400).json({
registration_status: "Error: Passwords do not match"
});
}
// In a real app, this would create the user account
const userId = Math.floor(Math.random() * 10000);
// Return success response
return res.status(200).json({
registration_status: `Success! User ${username} registered with ID #${userId}`
});
}
}
}
}
}
}