diff --git a/app.js b/app.js index c5a91ce..a112139 100644 --- a/app.js +++ b/app.js @@ -1,4 +1,4 @@ -import Styles from "./styles.dev.js"; +import Styles from "./gale.js"; const sheet = Styles({ diff --git a/deno.json b/deno.json index bee32bd..e1aa6b8 100644 --- a/deno.json +++ b/deno.json @@ -5,6 +5,6 @@ "deno.window", "DOM" ], - "types": ["./drill.d.ts", "./types.d.ts"] + "types": ["./types.d.ts"] } } \ No newline at end of file diff --git a/drill.d.ts b/drill.d.ts deleted file mode 100644 index eb905e5..0000000 --- a/drill.d.ts +++ /dev/null @@ -1,11 +0,0 @@ - -export {} -declare global { - namespace Gale - { - type Elemental = {[K in keyof HTMLElementTagNameMap]: Circular} - type Circular = { - [K in Keys]: Circular&Van.TagFunc; - }; - } -} \ No newline at end of file diff --git a/gale.js b/gale.js index 4646e3a..a26253d 100644 --- a/gale.js +++ b/gale.js @@ -1,4 +1,3 @@ -// @ts-check const KeyQuery = "@"; const KeyPseudo = ":"; const KeyChild = "."; @@ -51,8 +50,41 @@ const Tier=(selector, obj)=> return `${selector}{${styles.join("\n")}}`; } + +/** @type {(ref:T)=>Gale.Elemental>} */ +function MakeElemental(ref) +{ + let pending = false; + let classes = []; + + const collector = new Proxy((...args)=>{ + console.log("original func invoked!", pending, classes); + const element = van.tags[pending](...args); + element.className = classes.join(" "); + return element + }, + { + get(target, prop, rec) + { + classes.push(prop); + return collector; + } + } + ); + + const obj = new Proxy({}, {get(target, prop, rec) + { + pending = prop; + classes = []; + return collector; + } + }); + + return obj; +} + let i = 0; -/** @type {(sheet:UserSheet&T)=> ((...args:CrossMultiplyRecord[])=>string)&{css:string}} */ +/** @type {(sheet:UserSheet&T)=> ((...args:CrossMultiplyRecord[])=>string)&{css:string, dom:Gale.Elemental>} } */ export default (sheet)=> { const id = i ? "_"+i : ""; @@ -68,5 +100,6 @@ export default (sheet)=> return args.map((arg)=>extractLast(KeyGroup, extractLast(KeyChild, arg))).join(id+" ")+id; } classes.css = css; + classes.dom = MakeElemental(sheet); return classes; } \ No newline at end of file diff --git a/styles.dev.js b/styles.dev.js deleted file mode 100644 index a26253d..0000000 --- a/styles.dev.js +++ /dev/null @@ -1,105 +0,0 @@ -const KeyQuery = "@"; -const KeyPseudo = ":"; -const KeyChild = "."; -const KeyGroup = "^"; - -/** @typedef { Partial & {[key: `${KeyQuery|KeyPseudo|KeyChild|KeyGroup}${string}`]: UserStyles } } UserStyles */ -/** @typedef {Record} UserSheet */ - - -/** - * @template Obj - * @typedef { { [Key in keyof Obj]: Obj[Key] extends object ? Key | CollectKeys : Key }[keyof Obj] } CollectKeys - */ - -/** - * @template Keys - * @typedef { Keys extends `${KeyChild|KeyGroup}${infer Rest}` ? Keys : never } FilterKeys - */ -/** - * @template A - * @template B - * @typedef {A extends string ? B extends string ? `${A}${B}` : never : never } CrossMultiply - */ - -/** - * @template Rec - * @typedef { keyof Rec | { [K in keyof Rec]: K extends string ? CrossMultiply>> : never }[keyof Rec] } CrossMultiplyRecord - */ - - -/** @type {(selector:string, obj:UserStyles)=>string} */ -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")}}`; -} - - -/** @type {(ref:T)=>Gale.Elemental>} */ -function MakeElemental(ref) -{ - let pending = false; - let classes = []; - - const collector = new Proxy((...args)=>{ - console.log("original func invoked!", pending, classes); - const element = van.tags[pending](...args); - element.className = classes.join(" "); - return element - }, - { - get(target, prop, rec) - { - classes.push(prop); - return collector; - } - } - ); - - const obj = new Proxy({}, {get(target, prop, rec) - { - pending = prop; - classes = []; - return collector; - } - }); - - return obj; -} - -let i = 0; -/** @type {(sheet:UserSheet&T)=> ((...args:CrossMultiplyRecord[])=>string)&{css:string, dom:Gale.Elemental>} } */ -export default (sheet)=> -{ - const id = i ? "_"+i : ""; - i++; - const css = Object.keys(sheet).map(key=>Tier("."+key, sheet[key])).join(`\n`); - globalThis.document?.head.insertAdjacentHTML("beforeend", ``); - 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; - } - classes.css = css; - classes.dom = MakeElemental(sheet); - return classes; -} \ No newline at end of file diff --git a/types.d.ts b/types.d.ts index f29e88b..8926512 100644 --- a/types.d.ts +++ b/types.d.ts @@ -80,6 +80,12 @@ declare global type CrossMultiplyRecord = keyof Rec | { [K in keyof Rec]: K extends string ? CrossMultiply>> : never }[keyof Rec] type Tier = (selector:string, obj:UserStyles)=>string; type CreateSheet = (sheet:UserSheet&T)=> ((...args:CrossMultiplyRecord[])=>string)&{css:string} + + type Elemental = {[K in keyof HTMLElementTagNameMap]: Circular} + type Circular = { + [K in Keys]: Circular&Van.TagFunc; + }; + } const Gale:Gale.CreateSheet