gale shadow wrapper

This commit is contained in:
Seth Trowbridge 2025-04-11 13:26:36 -04:00
parent 365bfea866
commit 5ba5a4e6e3
9 changed files with 24 additions and 52 deletions

3
.vscode/settings.json vendored Normal file
View File

@ -0,0 +1,3 @@
{
"liveServer.settings.port": 5501
}

10
app.js
View File

@ -1,4 +1,4 @@
const {DOM, Tag, H} = Gale({
const {DOM, Tag, H, App} = Gale({
Form:{
padding: "20px"
},
@ -32,6 +32,9 @@ const {DOM, Tag, H} = Gale({
padding:"0.5rem",
background:"yellow",
color:"black",
":hover":{
color:"white"
}
},
Delete:{
fontSize:"0.6rem",
@ -98,8 +101,9 @@ function List()
));
}
van.add(
document.body, H.Form
App("body",
H.Form
(
H.Title("todos"),
Form(),

1
dist/core.d.ts vendored
View File

@ -87,6 +87,7 @@ declare global
type CreateSheet = <T extends UserSheet>(sheet:UserSheet&T, hash?:string)=>{
Tag:(...args:CrossMultiplyRecord<T>[])=>string,
CSS:string,
App:(selector:string, ...elements:Van.ChildDom[])=>ShadowRoot,
DOM:Elemental<CrossMultiplyRecord<T>>,
H:Circular<CrossMultiplyRecord<T>, Van.TagFunc<HTMLDivElement>>
}

2
dist/core.js vendored
View File

@ -8,7 +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};
//gale
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]})}};
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]})}};
//boot
((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"; ')}))})();

1
dist/index.html vendored
View File

@ -3,7 +3,6 @@
<head>
<meta charset="UTF-8">
<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>
<body></body>
</html>

View File

@ -3,7 +3,6 @@
<head>
<meta charset="UTF-8">
<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>
<script src="./dist/core.js"></script>
<script src="./src/gale.js"></script>
</head>

View File

@ -1,43 +0,0 @@
<!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>

View File

@ -9,7 +9,7 @@
const path=imports[n];
path.startsWith("./")&&(imports[n]=root+path.substring(2))
}
n("importmap",JSON.stringify({imports})),
n("module",'import "entry"; ')
n("importmap",JSON.stringify({imports}));
n("module",'import "entry"; ');
})
)();

View File

@ -60,13 +60,22 @@ globalThis.Gale = (sheet, hash="")=>
const id = hash ? "_"+hash : "";
const css = Object.keys(sheet).map(key=>Tier("."+key+id, sheet[key], id)).join(`\n`);
globalThis.document?.head.insertAdjacentHTML("beforeend", `<style data-sheet="${id}">${css}</style>`);
const style = document.createElement('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 {
Tag(...args){
return args.map((arg)=>extractLast(KeyGroup, extractLast(KeyChild, arg))).join(id+" ")+id;
},
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(
{},
{