gale/gale.js
2025-02-13 14:27:41 -05:00

77 lines
2.1 KiB
JavaScript

const KeyQuery = "@";
const KeyPseudo = ":";
const KeyChild = ".";
const KeyGroup = "^";
/** @type {Gale.Tier} */
const Tier=(selector, obj)=>
{
const styles = Object.keys(obj).map((key)=>
{
const value = obj[key];
switch(key[0])
{
case KeyQuery :
return Tier(`@media(max-width:${key.substring(KeyQuery.length)})`, value);
case KeyPseudo :
return Tier(`&${key}`, value);
case KeyChild :
return Tier(`${key}`, value);
case KeyGroup :
return Tier(`&:hover .${key.substring(KeyGroup.length)}`, value);
}
return `${ key.replace(/([a-z])([A-Z])/g, '$1-$2') }: ${value};`
});
return `${selector}{${styles.join("\n")}}`;
}
let i = 0;
/** @type {Gale.CreateSheet} */
const Gale = (sheet)=>
{
const id = i ? "_"+i : "";
i++;
const css = Object.keys(sheet).map(key=>Tier("."+key, sheet[key])).join(`\n`);
globalThis.document?.head.insertAdjacentHTML("beforeend", `<style data-sheet="${i}">${css}</style>`);
const classes =(...args)=>{
/** @type {(needle:string, str:string)=>string} */
const extractLast =(needle, str)=>{
const ind = str.lastIndexOf(needle)+needle.length;
return ind ? str.substring(ind) : str;
}
return args.map((arg)=>extractLast(KeyGroup, extractLast(KeyChild, arg))).join(id+" ")+id;
}
let pending = false;
let mentioned = [];
const collector = new Proxy(
(...args)=>
{
const element = van.tags[pending](...args);
element.className = mentioned.join(" ");
return element;
},
{
get(_, prop)
{
mentioned.push(prop.substring(prop.lastIndexOf(".")+1));
return collector;
}
}
);
classes.CSS = css;
classes.DOM = new Proxy(
{},
{get(_, prop)
{
pending = prop;
mentioned = [];
return collector;
}
}
);
return classes;
}