Add the templates for npm
All checks were successful
Build and Deploy on Tag / build-crosslang-shell-and-cpkg (push) Successful in 37s
All checks were successful
Build and Deploy on Tag / build-crosslang-shell-and-cpkg (push) Successful in 37s
This commit is contained in:
8
Templates/npmwebapp/.crossarchiveignore
Normal file
8
Templates/npmwebapp/.crossarchiveignore
Normal file
@@ -0,0 +1,8 @@
|
||||
.DS_Store
|
||||
bin
|
||||
obj
|
||||
publish
|
||||
npm/node_modules
|
||||
npm/package-lock.json
|
||||
npm/dist
|
||||
thumbs.db
|
||||
8
Templates/npmwebapp/.gitignore
vendored
Normal file
8
Templates/npmwebapp/.gitignore
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
.DS_Store
|
||||
bin
|
||||
obj
|
||||
publish
|
||||
npm/node_modules
|
||||
npm/package-lock.json
|
||||
npm/dist
|
||||
thumbs.db
|
||||
43
Templates/npmwebapp/cross.json
Normal file
43
Templates/npmwebapp/cross.json
Normal file
@@ -0,0 +1,43 @@
|
||||
{
|
||||
"$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 WebApp",
|
||||
"maintainer": "Mike Nolan",
|
||||
"type": "template",
|
||||
"repo": "https://git.tesses.org/tesses50/crosslangextras",
|
||||
"homepage": "https://crosslang.tesseslanguage.com/",
|
||||
"license": "MIT",
|
||||
"short_name": "npmwebapp",
|
||||
"description": "A NPM WebApp Template with BeerCSS and HTMX",
|
||||
"template_info": {
|
||||
"type": "webapp",
|
||||
"short_name": "changeme",
|
||||
"short_name_pretty": "Change Me"
|
||||
},
|
||||
"template_prebuild": [
|
||||
{
|
||||
"workdir": "npm",
|
||||
"commands": [
|
||||
["npm","install"],
|
||||
["npm","run","publish"]
|
||||
],
|
||||
"res": [
|
||||
"npm/dist"
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"name": "Tesses.CrossLang.Template.NPMWebApp",
|
||||
"version": "1.0.0.0-dev"
|
||||
|
||||
}
|
||||
12
Templates/npmwebapp/npm/package.json
Normal file
12
Templates/npmwebapp/npm/package.json
Normal 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"
|
||||
}
|
||||
}
|
||||
78
Templates/npmwebapp/npm/web.css
Normal file
78
Templates/npmwebapp/npm/web.css
Normal 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;
|
||||
}
|
||||
3
Templates/npmwebapp/npm/web.mjs
Normal file
3
Templates/npmwebapp/npm/web.mjs
Normal file
@@ -0,0 +1,3 @@
|
||||
import 'beercss'
|
||||
import 'htmx.org'
|
||||
import './web.css'
|
||||
78
Templates/npmwebapp/src/components/shell.tcross
Normal file
78
Templates/npmwebapp/src/components/shell.tcross
Normal 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>
|
||||
}
|
||||
33
Templates/npmwebapp/src/pages/about.tcross
Normal file
33
Templates/npmwebapp/src/pages/about.tcross
Normal 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;
|
||||
}
|
||||
30
Templates/npmwebapp/src/pages/counter.tcross
Normal file
30
Templates/npmwebapp/src/pages/counter.tcross
Normal 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;
|
||||
}
|
||||
35
Templates/npmwebapp/src/pages/echo.tcross
Normal file
35
Templates/npmwebapp/src/pages/echo.tcross
Normal 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;
|
||||
}
|
||||
42
Templates/npmwebapp/src/pages/index.tcross
Normal file
42
Templates/npmwebapp/src/pages/index.tcross
Normal 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;
|
||||
}
|
||||
37
Templates/npmwebapp/src/program.tcross
Normal file
37
Templates/npmwebapp/src/program.tcross
Normal file
@@ -0,0 +1,37 @@
|
||||
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 WebAppMain(args)
|
||||
{
|
||||
return new MyWebApp();
|
||||
}
|
||||
Reference in New Issue
Block a user