Compare commits
No commits in common. "restructure" and "master" have entirely different histories.
restructur
...
master
3
.vscode/settings.json
vendored
3
.vscode/settings.json
vendored
@ -1,3 +0,0 @@
|
|||||||
{
|
|
||||||
"liveServer.settings.port": 5501
|
|
||||||
}
|
|
132
app.js
132
app.js
@ -1,113 +1,45 @@
|
|||||||
const {DOM, Tag, H, App} = Gale({
|
const {DOM, Tag, H} = Gale({
|
||||||
Form:{
|
Button: {
|
||||||
padding: "20px"
|
padding: "20px",
|
||||||
},
|
background: "orange",
|
||||||
Input:{
|
".Inner": {
|
||||||
display:"inlnine-block",
|
fontSize: "10rem"
|
||||||
padding:"0.5rem 1rem",
|
|
||||||
borderRadius:"0.5rem",
|
|
||||||
outline:"1px solid #ddd",
|
|
||||||
":focus":{
|
|
||||||
outline: "2px solid green"
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
Button:{
|
Outline: {
|
||||||
display:"inline-block",
|
border: "2px solid orange"
|
||||||
padding:"1rem",
|
|
||||||
background:"green",
|
|
||||||
color:"white",
|
|
||||||
borderRadius:"0.5rem",
|
|
||||||
cursor:"pointer",
|
|
||||||
textTransform:"uppercase",
|
|
||||||
fontWeight:"bolder",
|
|
||||||
":hover":{background:"black"}
|
|
||||||
},
|
},
|
||||||
Complete:{
|
Window:{
|
||||||
fontSize:"0.6rem",
|
height: "100vh",
|
||||||
padding:"0.5rem",
|
border: "2px solid black",
|
||||||
background:"limegreen"
|
display: "flex",
|
||||||
|
flexDirection: "row",
|
||||||
|
alignItems: "end",
|
||||||
|
justifyContent: "center",
|
||||||
|
gap: "10px"
|
||||||
},
|
},
|
||||||
Incomplete:{
|
Ability:{
|
||||||
fontSize:"0.6rem",
|
width: "50px",
|
||||||
padding:"0.5rem",
|
height: "50px",
|
||||||
background:"yellow",
|
background: "red",
|
||||||
color:"black",
|
transition: "all 0.4s",
|
||||||
":hover":{
|
":hover":{
|
||||||
color:"white"
|
transform:"scale(1.1)"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
Delete:{
|
Orange:{
|
||||||
fontSize:"0.6rem",
|
background:"orange"
|
||||||
padding:"0.5rem",
|
|
||||||
background:"tomato"
|
|
||||||
},
|
|
||||||
|
|
||||||
Title:{
|
|
||||||
fontSize: "2rem"
|
|
||||||
},
|
|
||||||
List:{
|
|
||||||
padding:"1rem",
|
|
||||||
background:"#ddd"
|
|
||||||
},
|
|
||||||
Item:{
|
|
||||||
display:"flex",
|
|
||||||
gap:"1rem",
|
|
||||||
alignItems:"center"
|
|
||||||
},
|
|
||||||
Done:{
|
|
||||||
textDecoration:"line-through"
|
|
||||||
}
|
}
|
||||||
});
|
}, "abilities");
|
||||||
|
|
||||||
/** @typedef {{name:string, done:boolean}} Todo */
|
const UI =()=>
|
||||||
|
|
||||||
/** @type {{pending:string, list:Todo[]}} */
|
|
||||||
const InitialState = {pending:"todo name", list:[]};
|
|
||||||
const Store = vanX.Store(InitialState, "todos_v1");
|
|
||||||
|
|
||||||
const PendingCreate=()=>{
|
|
||||||
const newTodo = /** @type {Todo} */({name:Store.pending, done:false});
|
|
||||||
Store.list.unshift(newTodo);
|
|
||||||
Store.pending = "";
|
|
||||||
console.log(Store);
|
|
||||||
}
|
|
||||||
const PendingChange =(/** @type {InputEvent}*/e)=>{
|
|
||||||
console.log(e);
|
|
||||||
Store.pending = /** @type {HTMLInputElement}*/(e.target).value;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
function Form()
|
|
||||||
{
|
{
|
||||||
const input = DOM.input.Input({value:Store.pending, oninput:PendingChange})
|
return H.Window(
|
||||||
return DOM.form.Form(
|
H.Ability({class:Tag("Ability", "Orange")}),
|
||||||
{onsubmit(e){e.preventDefault(); PendingCreate();}},
|
H.Ability(),
|
||||||
()=>
|
H.Ability(),
|
||||||
{
|
H.Ability.Orange(),
|
||||||
input.value = Store.pending;
|
|
||||||
input.setAttribute("data-value", Store.pending);
|
|
||||||
return input;
|
|
||||||
},
|
|
||||||
()=>DOM.button.Button({disabled:Store.pending == ""}, "Create")
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
function List()
|
van.add(document.body, UI());
|
||||||
{
|
|
||||||
return ()=>Store.list.length && vanX.list(DOM.ul.List, Store.list, (v, d)=>DOM.li.Item(
|
|
||||||
v.val.done ? DOM.button.Button.Complete({onclick(){v.val.done = false}}, "Complete") : DOM.button.Button.Incomplete({onclick(){v.val.done = true}}, "Incomplete"),
|
|
||||||
DOM.span({class: v.val.done ? Tag("Done") : ""}, v.val.name),
|
|
||||||
DOM.button.Button.Delete({onclick:d}, "Delete")
|
|
||||||
));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
App("body",
|
|
||||||
H.Form
|
|
||||||
(
|
|
||||||
H.Title("todos"),
|
|
||||||
Form(),
|
|
||||||
List(),
|
|
||||||
()=>H.Item(Store.pending)
|
|
||||||
)
|
|
||||||
);
|
|
1
dist/core.d.ts
vendored
1
dist/core.d.ts
vendored
@ -87,7 +87,6 @@ declare global
|
|||||||
type CreateSheet = <T extends UserSheet>(sheet:UserSheet&T, hash?:string)=>{
|
type CreateSheet = <T extends UserSheet>(sheet:UserSheet&T, hash?:string)=>{
|
||||||
Tag:(...args:CrossMultiplyRecord<T>[])=>string,
|
Tag:(...args:CrossMultiplyRecord<T>[])=>string,
|
||||||
CSS:string,
|
CSS:string,
|
||||||
App:(selector:string, ...elements:Van.ChildDom[])=>ShadowRoot,
|
|
||||||
DOM:Elemental<CrossMultiplyRecord<T>>,
|
DOM:Elemental<CrossMultiplyRecord<T>>,
|
||||||
H:Circular<CrossMultiplyRecord<T>, Van.TagFunc<HTMLDivElement>>
|
H:Circular<CrossMultiplyRecord<T>, Van.TagFunc<HTMLDivElement>>
|
||||||
}
|
}
|
||||||
|
18
dist/core.js
vendored
18
dist/core.js
vendored
@ -8,21 +8,7 @@
|
|||||||
vanX.Store=(e,t)=>{const a=localStorage.getItem(t),r=vanX.reactive(a?JSON.parse(a):e);return van.derive((()=>localStorage.setItem(t,JSON.stringify(vanX.compact(r))))),r};
|
vanX.Store=(e,t)=>{const a=localStorage.getItem(t),r=vanX.reactive(a?JSON.parse(a):e);return van.derive((()=>localStorage.setItem(t,JSON.stringify(vanX.compact(r))))),r};
|
||||||
|
|
||||||
//gale
|
//gale
|
||||||
globalThis.Gale=(e,t="")=>{const n=(e,t,o)=>`${e}{${Object.keys(t).map((e=>{const a=t[e];switch(e[0]){case"@":return n(`@media(max-width:${e.substring(1)})`,a,o);case":":return n(`&${e}`,a,o);case".":return n(`${e}${o}`,a,o);case"^":return n(`&:hover .${e.substring(1)}${o}`,a,o)}return`${e.replace(/([a-z])([A-Z])/g,"$1-$2").toLowerCase()}: ${a};`})).join("\n")}}`,o=(e,t)=>{const n=t.lastIndexOf(e)+e.length;return n?t.substring(n):t},a=e=>{const t=van.tags[e];let n=[];const o=new Proxy(((...e)=>{const o=t(...e);return o.className=n.join(i+" ")+i+" "+o.className,n=[],o}),{get:(e,t)=>(n.push(t.substring(t.lastIndexOf(".")+1)),o)});return o},i=t?"_"+t:"",r=Object.keys(e).map((t=>n("."+t+i,e[t],i))).join("\n"),s=document.createElement("style");return s.setAttribute("data-sheet",i),s.textContent=r+"*{margin:0;padding:0;box-sizing:border-box;}html, :host{height:100%;width:100%;font-family:Arial, sans-serif;line-height:1.6;}body{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;}img, video{max-width:100%;height:auto;}a{text-decoration:none;color:inherit;}ul, ol{list-style:none;}button, input, textarea{font-family:inherit;font-size:inherit;line-height:inherit;border:none;background:none;padding:0;margin:0;outline:none;}table{border-collapse:collapse;width:100%;}",globalThis.document?.head.appendChild(s),{Tag:(...e)=>e.map((e=>o("^",o(".",e)))).join(i+" ")+i,CSS:r,App(e,...t){const n=document.querySelector(e).attachShadow({mode:"open"});return n.appendChild(s),van.add(n,...t),n},DOM:new Proxy({},{get:(e,t)=>a(t)}),H:new Proxy({},{get:(e,t)=>a("div")[t]})}};
|
globalThis.Gale=(e,t="")=>{const n=(e,t,s)=>`${e}{${Object.keys(t).map((e=>{const r=t[e];switch(e[0]){case"@":return n(`@media(max-width:${e.substring(1)})`,r,s);case":":return n(`&${e}`,r,s);case".":return n(`${e}${s}`,r,s);case"^":return n(`&:hover .${e.substring(1)}${s}`,r,s)}return`${e.replace(/([a-z])([A-Z])/g,"$1-$2")}: ${r};`})).join("\n")}}`,s=(e,t)=>{const n=t.lastIndexOf(e)+e.length;return n?t.substring(n):t},r=e=>{const t=van.tags[e];let n=[];const s=new Proxy(((...e)=>{const s=t(...e);return s.className=n.join(a+" ")+a+" "+s.className,n=[],s}),{get:(e,t)=>(n.push(t.substring(t.lastIndexOf(".")+1)),s)});return s},a=t?"_"+t:"",c=Object.keys(e).map((t=>n("."+t+a,e[t],a))).join("\n");return globalThis.document?.head.insertAdjacentHTML("beforeend",`<style data-sheet="${a}">${c}</style>`),{Tag:(...e)=>e.map((e=>s("^",s(".",e)))).join(a+" ")+a,CSS:c,DOM:new Proxy({},{get:(e,t)=>r(t)}),H:new Proxy({},{get:(e,t)=>r("div")[t]})}};
|
||||||
|
|
||||||
//boot
|
//boot
|
||||||
const configFile = import.meta.url.split("?")[1] || window.location+"deno.json";
|
((t="/")=>{fetch(t+"deno.json").then((t=>t.json())).then((e=>{const n=(t,e)=>{let n=document.createElement("script");n.type=t,n.textContent=e,document.head.appendChild(n)},o=e.imports;for(let e in o){const n=o[e];n.startsWith("./")&&(o[e]=t+n.substring(2))}n("importmap",JSON.stringify({imports:o})),n("module",'import "entry"; ')}))})();
|
||||||
const configFolder = configFile.substring(0, configFile.lastIndexOf("/")+1);
|
|
||||||
fetch(configFile)
|
|
||||||
.then(text=>text.json())
|
|
||||||
.then(json=>{
|
|
||||||
const n=(t,e)=>{let n=document.createElement("script");n.type=t,n.textContent=e,document.head.appendChild(n)};
|
|
||||||
const imports = json.imports;
|
|
||||||
for(let n in imports)
|
|
||||||
{
|
|
||||||
const path=imports[n];
|
|
||||||
path.startsWith("./")&&(imports[n]=configFolder+path.substring(2))
|
|
||||||
}
|
|
||||||
n("importmap",JSON.stringify({imports}));
|
|
||||||
n("module",'import "entry"; ');
|
|
||||||
})
|
|
1
dist/index.html
vendored
1
dist/index.html
vendored
@ -3,6 +3,7 @@
|
|||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<!-- css reset --><style>*{margin:0;padding:0;box-sizing:border-box;}html, body{height:100%;width:100%;font-family:Arial, sans-serif;line-height:1.6;}body{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;}img, video{max-width:100%;height:auto;}a{text-decoration:none;color:inherit;}ul, ol{list-style:none;}button, input, textarea{font-family:inherit;font-size:inherit;line-height:inherit;border:none;background:none;padding:0;margin:0;outline:none;}table{border-collapse:collapse;width:100%;}</style>
|
||||||
</head>
|
</head>
|
||||||
<body></body>
|
<body></body>
|
||||||
</html>
|
</html>
|
@ -3,7 +3,8 @@
|
|||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
<script src="./dist/core.js?/deno.json" type="module"></script>
|
<!-- css reset --><style>*{margin:0;padding:0;box-sizing:border-box;}html, body{height:100%;width:100%;font-family:Arial, sans-serif;line-height:1.6;}body{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;}img, video{max-width:100%;height:auto;}a{text-decoration:none;color:inherit;}ul, ol{list-style:none;}button, input, textarea{font-family:inherit;font-size:inherit;line-height:inherit;border:none;background:none;padding:0;margin:0;outline:none;}table{border-collapse:collapse;width:100%;}</style>
|
||||||
|
<script src="./dist/core.js"></script>
|
||||||
<script src="./src/gale.js"></script>
|
<script src="./src/gale.js"></script>
|
||||||
</head>
|
</head>
|
||||||
<body></body>
|
<body></body>
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
|
const bundle = await fetch(import.meta.resolve("../dist/core.js")).then(r=>r.text());
|
||||||
|
const index = await fetch(import.meta.resolve("../dist/index.html")).then(r=>r.text());
|
||||||
|
export const HTML = index.replace(`</head>`, `<script>${bundle}</script></head>`);
|
||||||
export const Root = import.meta.resolve("../");
|
export const Root = import.meta.resolve("../");
|
||||||
const index = await fetch(Root + "dist/index.html").then(r=>r.text());
|
|
||||||
export const HTML = index.replace(`</head>`, `<script type="module" src="${Root + "dist/core.js?/deno.json"}"></script></head>`);
|
|
||||||
export const Load =async(file:string)=> await fetch(Root + file).then(resp=>resp.text());
|
export const Load =async(file:string)=> await fetch(Root + file).then(resp=>resp.text());
|
||||||
export const Save =async(text:string, name:string)=> await Deno.writeTextFile(name, text);
|
export const Save =async(text:string, name:string)=> await Deno.writeTextFile(name, text);
|
@ -12,7 +12,7 @@ try {
|
|||||||
} catch (_) {
|
} catch (_) {
|
||||||
html = HTML;
|
html = HTML;
|
||||||
}
|
}
|
||||||
html = html.replace("</head>", `<script type="module">${devinc}</script></head>`);
|
html = html.replace("</head>", `<script>${devinc}</script></head>`);
|
||||||
|
|
||||||
function extension(path: string): string {
|
function extension(path: string): string {
|
||||||
// Remove trailing slash if it exists
|
// Remove trailing slash if it exists
|
||||||
|
43
shadow.html
Normal file
43
shadow.html
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title>Shadow DOM Example</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
|
||||||
|
|
||||||
|
<script>
|
||||||
|
// Define the custom web component
|
||||||
|
class APP extends HTMLElement {
|
||||||
|
constructor() {
|
||||||
|
super();
|
||||||
|
|
||||||
|
// Attach a shadow root to the custom element
|
||||||
|
const shadowRoot = this.attachShadow({ mode: 'open' });
|
||||||
|
|
||||||
|
// Add custom markup and styles to the shadow root
|
||||||
|
shadowRoot.innerHTML = `
|
||||||
|
<style>
|
||||||
|
.shadow-content {
|
||||||
|
color: white;
|
||||||
|
background-color: black;
|
||||||
|
padding: 10px;
|
||||||
|
border-radius: 5px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<div class="shadow-content">
|
||||||
|
This is content inside the shadow root of a web component.
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Register the custom element
|
||||||
|
customElements.define('gale-app', APP);
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<gale-app></gale-app>
|
||||||
|
</body>
|
||||||
|
</html>
|
15
src/boot.js
Normal file
15
src/boot.js
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
(
|
||||||
|
(root="/")=>fetch(root+"deno.json")
|
||||||
|
.then(text=>text.json())
|
||||||
|
.then(json=>{
|
||||||
|
const n=(t,e)=>{let n=document.createElement("script");n.type=t,n.textContent=e,document.head.appendChild(n)};
|
||||||
|
const imports = json.imports;
|
||||||
|
for(let n in imports)
|
||||||
|
{
|
||||||
|
const path=imports[n];
|
||||||
|
path.startsWith("./")&&(imports[n]=root+path.substring(2))
|
||||||
|
}
|
||||||
|
n("importmap",JSON.stringify({imports})),
|
||||||
|
n("module",'import "entry"; ')
|
||||||
|
})
|
||||||
|
)();
|
13
src/gale.js
13
src/gale.js
@ -23,7 +23,7 @@ globalThis.Gale = (sheet, hash="")=>
|
|||||||
case KeyGroup :
|
case KeyGroup :
|
||||||
return Tier(`&:hover .${key.substring(KeyGroup.length)}${suffix}`, value, suffix);
|
return Tier(`&:hover .${key.substring(KeyGroup.length)}${suffix}`, value, suffix);
|
||||||
}
|
}
|
||||||
return `${ key.replace(/([a-z])([A-Z])/g, '$1-$2').toLowerCase() }: ${value};`
|
return `${ key.replace(/([a-z])([A-Z])/g, '$1-$2') }: ${value};`
|
||||||
});
|
});
|
||||||
|
|
||||||
return `${selector}{${styles.join("\n")}}`;
|
return `${selector}{${styles.join("\n")}}`;
|
||||||
@ -60,22 +60,13 @@ globalThis.Gale = (sheet, hash="")=>
|
|||||||
|
|
||||||
const id = hash ? "_"+hash : "";
|
const id = hash ? "_"+hash : "";
|
||||||
const css = Object.keys(sheet).map(key=>Tier("."+key+id, sheet[key], id)).join(`\n`);
|
const css = Object.keys(sheet).map(key=>Tier("."+key+id, sheet[key], id)).join(`\n`);
|
||||||
const style = document.createElement('style');
|
globalThis.document?.head.insertAdjacentHTML("beforeend", `<style data-sheet="${id}">${css}</style>`);
|
||||||
style.setAttribute("data-sheet", id);
|
|
||||||
style.textContent = css + `*{margin:0;padding:0;box-sizing:border-box;}html, :host{height:100%;width:100%;font-family:Arial, sans-serif;line-height:1.6;}body{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;}img, video{max-width:100%;height:auto;}a{text-decoration:none;color:inherit;}ul, ol{list-style:none;}button, input, textarea{font-family:inherit;font-size:inherit;line-height:inherit;border:none;background:none;padding:0;margin:0;outline:none;}table{border-collapse:collapse;width:100%;}`;
|
|
||||||
globalThis.document?.head.appendChild(style);
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
Tag(...args){
|
Tag(...args){
|
||||||
return args.map((arg)=>extractLast(KeyGroup, extractLast(KeyChild, arg))).join(id+" ")+id;
|
return args.map((arg)=>extractLast(KeyGroup, extractLast(KeyChild, arg))).join(id+" ")+id;
|
||||||
},
|
},
|
||||||
CSS: css,
|
CSS: css,
|
||||||
App(selector, ...elements){
|
|
||||||
const sr = document.querySelector(selector).attachShadow({ mode: 'open' });
|
|
||||||
sr.appendChild(style);
|
|
||||||
van.add(sr, ...elements);
|
|
||||||
return sr;
|
|
||||||
},
|
|
||||||
DOM: new Proxy(
|
DOM: new Proxy(
|
||||||
{},
|
{},
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user