Add the templates for npm
All checks were successful
Build and Deploy on Tag / build-crosslang-shell-and-cpkg (push) Successful in 37s

This commit is contained in:
2026-05-10 20:52:26 -05:00
parent e77b071af1
commit 0459b0a84e
57 changed files with 945 additions and 74 deletions

View File

@@ -0,0 +1,8 @@
.DS_Store
bin
obj
publish
npm/node_modules
npm/package-lock.json
npm/dist
thumbs.db

8
Templates/npmweb/.gitignore vendored Normal file
View File

@@ -0,0 +1,8 @@
.DS_Store
bin
obj
publish
npm/node_modules
npm/package-lock.json
npm/dist
thumbs.db

View File

@@ -0,0 +1,41 @@
{
"$schema": "https:\/\/crosslang.tesseslanguage.com\/\/schema\/cross-json-schema.json",
"info": {
"template_ignored_files": [
".DS_Store",
"bin",
"obj",
"publish",
"npm/node_modules",
"npm/package-lock.json",
"npm/dist",
"thumbs.db"
],
"short_name_pretty": "NPM WebSite",
"maintainer": "Mike Nolan",
"type": "template",
"repo": "https://git.tesses.org/tesses50/crosslangextras",
"homepage": "https://crosslang.tesseslanguage.com/",
"license": "MIT",
"short_name": "npmweb",
"description": "A NPM Website Template with BeerCSS and HTMX",
"template_info": {
"type": "console"
},
"template_prebuild": [
{
"workdir": "npm",
"commands": [
["npm","install"],
["npm","run","publish"]
],
"res": [
"npm/dist"
]
}
]
},
"name": "Tesses.CrossLang.Template.NPMWebsite",
"version": "1.0.0.0-dev"
}

View File

@@ -0,0 +1,12 @@
{
"dependencies": {
"beercss": "^4.0.21",
"htmx.org": "^2.0.10"
},
"devDependencies": {
"esbuild": "^0.28.0"
},
"scripts": {
"publish": "esbuild --minify --sourcemap --define:'process.env.NODE_ENV=\"production\"' --bundle --outdir=dist web.mjs --loader:.svg=file --loader:.woff2=file"
}
}

View File

@@ -0,0 +1,78 @@
:root,
body.light {
--primary:#855400;
--on-primary:#ffffff;
--primary-container:#ffddb7;
--on-primary-container:#2a1700;
--secondary:#705b41;
--on-secondary:#ffffff;
--secondary-container:#fcdebc;
--on-secondary-container:#281805;
--tertiary:#53643e;
--on-tertiary:#ffffff;
--tertiary-container:#d6e9b9;
--on-tertiary-container:#121f03;
--error:#ba1a1a;
--on-error:#ffffff;
--error-container:#ffdad6;
--on-error-container:#410002;
--background:#fffbff;
--on-background:#1f1b16;
--surface:#fff8f4;
--on-surface:#1f1b16;
--surface-variant:#f0e0d0;
--on-surface-variant:#504539;
--outline:#827568;
--outline-variant:#d4c4b5;
--shadow:#000000;
--scrim:#000000;
--inverse-surface:#352f2a;
--inverse-on-surface:#f9efe7;
--inverse-primary:#ffb95c;
--surface-dim:#e2d8d1;
--surface-bright:#fff8f4;
--surface-container-lowest:#ffffff;
--surface-container-low:#fcf2ea;
--surface-container:#f6ece4;
--surface-container-high:#f0e6de;
--surface-container-highest:#ebe1d9;
}
body.dark {
--primary:#ffb95c;
--on-primary:#462a00;
--primary-container:#653e00;
--on-primary-container:#ffddb7;
--secondary:#dfc2a2;
--on-secondary:#3f2d17;
--secondary-container:#57432b;
--on-secondary-container:#fcdebc;
--tertiary:#bacd9f;
--on-tertiary:#263514;
--tertiary-container:#3c4c28;
--on-tertiary-container:#d6e9b9;
--error:#ffb4ab;
--on-error:#690005;
--error-container:#93000a;
--on-error-container:#ffb4ab;
--background:#1f1b16;
--on-background:#ebe1d9;
--surface:#17130e;
--on-surface:#ebe1d9;
--surface-variant:#504539;
--on-surface-variant:#d4c4b5;
--outline:#9c8e80;
--outline-variant:#504539;
--shadow:#000000;
--scrim:#000000;
--inverse-surface:#ebe1d9;
--inverse-on-surface:#352f2a;
--inverse-primary:#855400;
--surface-dim:#17130e;
--surface-bright:#3e3833;
--surface-container-lowest:#110e09;
--surface-container-low:#1f1b16;
--surface-container:#231f1a;
--surface-container-high:#2e2924;
--surface-container-highest:#39342f;
}

View File

@@ -0,0 +1,3 @@
import 'beercss'
import 'htmx.org'
import './web.css'

View File

@@ -0,0 +1,78 @@
func Components.Shell(title,pages,body)
{
<return>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="/dist/web.css">
<title>%PROJECT_NAME% - {title}</title>
<script src="/dist/web.js" defer></script>
</head>
<body>
<dialog class="left" id="leftpane">
<header>
<nav>
<img class="circle large" src="/tytd-128.png">
<h6 class="max">%PROJECT_NAME%</h6>
<button hx-on:click="ui('#leftpane')" class="transparent circle large">
<i>close</i>
</button>
</nav>
</header>
<div class="space"></div>
<ul class="list">
<each(var item : pages)>
<if(item.active)>
<true>
<li class="wave round primary" hx-target="body" hx-push-url="true" hx-get={item.link}>
<i>{item.icon}</i>
<span class="max">{item.text}</span>
<b></b>
</li>
</true>
<false>
<li class="wave round" hx-target="body" hx-push-url="true" hx-get={item.route}>
<i>{item.icon}</i>
<span class="max">{item.text}</span>
<b></b>
</li>
</false>
</if>
</each>
</ul>
</dialog>
<header class="fixed primary-container">
<nav>
<button hx-on:click="ui('#leftpane')" class="circle transparent">
<i>menu</i>
</button>
<button hx-target="body" hx-push-url="true" hx-get="/" class="circle transparent">
<i>home</i>
</button>
<div class="max"></div>
<div>
<button class="circle transparent">
<i>more_vert</i>
</button>
<menu class="left no-wrap">
<li><a href="https://beercss.com/">BeerCSS</a></li>
</menu>
</div>
</nav>
<div class="small-padding">
<h5>%PROJECT_NAME%</h5>
</div>
</header>
<main class="responsive">
<raw(body)>
</main>
</body>
</html>
</return>
}

View File

@@ -0,0 +1,33 @@
func Pages.About(ctx)
{
var pages = [
{
active = false,
route = "/",
text = "Home",
icon = "home"
},
{
active = false,
route = "/counter",
text = "Counter",
icon = "exposure_plus_1"
},
{
active = true,
route = "/about",
text = "About",
icon = "info"
}
];
ctx.WithMimeType("text/html").SendText(Components.Shell("About Me",pages,<section>
<h1>About Me</h1>
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
</p>
</section>
));
return true;
}

View File

@@ -0,0 +1,30 @@
var counter = 0;
func Pages.Counter(ctx)
{
var pages = [
{
active = false,
route = "/",
text = "Home",
icon = "home"
},
{
active = true,
route = "/counter",
text = "Counter",
icon = "exposure_plus_1"
},
{
active = false,
route = "/about",
text = "About",
icon = "info"
}
];
ctx.WithMimeType("text/html").SendText(Components.Shell("Counter",pages,<section>
<button hx-get="./counter" hx-target="body" hx-push-url="true">Counter is {++counter}</button>
</section>
));
return true;
}

View File

@@ -0,0 +1,35 @@
func Pages.Echo(ctx)
{
const text = ctx.QueryParams.TryGetFirst("text");
var pages = [
{
active = true,
route = "/",
text = "Home",
icon = "home"
},
{
active = false,
route = "/counter",
text = "Counter",
icon = "exposure_plus_1"
},
{
active = false,
route = "/about",
text = "About",
icon = "info"
}
];
ctx.WithMimeType("text/html").SendText(Components.Shell("Echo",pages,<section>
<if(text != null)>
<true>
<plink(text)>
</true>
<false>
<p>No text available</p>
</false>
</if>
</section>));
return true;
}

View File

@@ -0,0 +1,42 @@
func Pages.Index(ctx)
{
var pages = [
{
active = true,
route = "/",
text = "Home",
icon = "home"
},
{
active = false,
route = "/counter",
text = "Counter",
icon = "exposure_plus_1"
},
{
active = false,
route = "/about",
text = "About",
icon = "info"
}
];
ctx.WithMimeType("text/html").SendText(Components.Shell("Main Page",pages,<section>
<form hx-get="./echo" hx-target="body" hx-push-url="true" action="./echo" method="GET">
<div class="row">
<div class="max">
<div class="field label border">
<input type="text" name="text">
<label>Text to echo</label>
</div>
</div>
<div class="min">
<button type="submit">
Echo
</button>
</div>
</div>
</form>
<p>1 John 4:4: You, dear children, are from God and have overcome them, because the one who is in you is greater than the one who is in the world.</p>
</section>));
return true;
}

View File

@@ -0,0 +1,40 @@
class MyWebApp {
private fileServer;
private mountable;
private pages;
public MyWebApp()
{
this.fileServer = new FileServer(embeddir("/"), true, false);
this.mountable = new MountableServer((ctx)=>{
const page = this.pages.[ctx.Path];
if(TypeIsDefined(page)) return page(ctx);
return false;
});
this.mountable.Mount("/dist/",this.fileServer);
this.pages = {
.["/"] = Pages.Index,
.["/counter"] = Pages.Counter,
.["/about"] = Pages.About,
.["/echo"] = Pages.Echo
};
}
public Handle(ctx)
{
return this.mountable.Handle(ctx);
}
public Close()
{
this.mountable = null;
}
}
func main(args)
{
const webApp=new MyWebApp();
Net.Http.ListenSimpleWithLoop(webApp,4206);
webApp.Close();
}