diff --git a/__recipes__/index.test.ts b/__recipes__/index.test.ts index b97c6a8..1a5667b 100644 --- a/__recipes__/index.test.ts +++ b/__recipes__/index.test.ts @@ -5,17 +5,15 @@ import type {ClassHash, ReactClassNaming} from "react-classnaming" declare module "react-classnaming" { namespace ReactClassNaming { interface BemOptions { - elementDelimiter: "_"; + // TODO #30 elementDelimiter: "_"; modDelimiter: "-"; - blockModKey: "&"; } } } setOptions({ - elementDelimiter: "_", + // TODO #30 elementDelimiter: "_", modDelimiter: "-", - blockModKey: "&" }) type CssModule = Record< diff --git a/__sandbox__/bem--old.ts b/__sandbox__/bem--old.ts deleted file mode 100644 index 1648118..0000000 --- a/__sandbox__/bem--old.ts +++ /dev/null @@ -1,85 +0,0 @@ -// Can be used on #30 - -import type { Ever0, Extends, PartDeep, Strip } from "src/ts-swiss.types" -import type {ReactClassNaming} from "../src" - -export type BemQuery< - classes extends string, - delE extends string = "elementDelimiter" extends keyof ReactClassNaming.BemOptions - ? ReactClassNaming.BemOptions["elementDelimiter"] - : ReactClassNaming.BemOptions["$default"]["elementDelimiter"], - delM extends string = "modDelimiter" extends keyof ReactClassNaming.BemOptions - ? ReactClassNaming.BemOptions["modDelimiter"] - : ReactClassNaming.BemOptions["$default"]["modDelimiter"], - bModKey extends string = "blockModKey" extends keyof ReactClassNaming.BemOptions - ? ReactClassNaming.BemOptions["blockModKey"] - : ReactClassNaming.BemOptions["$default"]["blockModKey"], -> = string extends classes ? BemInGeneral : PartDeep<{ - [b in Strip, delE>]: boolean - | Exclude, `${string}${delM}${string}`> - | ( - Extends]: boolean - | Exclude, `${string}${delM}${string}`> - | ( - {[m in Strip, delM>]: - false | ( - Ever0< - classes extends `${b}${ - e extends bModKey ? "" : `${delE}${e}` - }${delM}${m}${delM}${infer V}` - ? V : never, - true - > - ) - } - ) - } - > - ) -}> - -type Elements< - classes extends string, - b extends string, - delE extends string = "elementDelimiter" extends keyof ReactClassNaming.BemOptions - ? ReactClassNaming.BemOptions["elementDelimiter"] - : ReactClassNaming.BemOptions["$default"]["elementDelimiter"], - delM extends string = "modDelimiter" extends keyof ReactClassNaming.BemOptions - ? ReactClassNaming.BemOptions["modDelimiter"] - : ReactClassNaming.BemOptions["$default"]["modDelimiter"], - bModKey extends string = "blockModKey" extends keyof ReactClassNaming.BemOptions - ? ReactClassNaming.BemOptions["blockModKey"] - : ReactClassNaming.BemOptions["$default"]["blockModKey"], -> = classes extends `${b}${delE}${infer E}` -? Strip -: classes extends `${b}${delM}${string}` -? bModKey -: never - -type MVs< - classes extends string, - b extends string, - e extends string, - delE extends string = "elementDelimiter" extends keyof ReactClassNaming.BemOptions - ? ReactClassNaming.BemOptions["elementDelimiter"] - : ReactClassNaming.BemOptions["$default"]["elementDelimiter"], - delM extends string = "modDelimiter" extends keyof ReactClassNaming.BemOptions - ? ReactClassNaming.BemOptions["modDelimiter"] - : ReactClassNaming.BemOptions["$default"]["modDelimiter"], - bModKey extends string = "blockModKey" extends keyof ReactClassNaming.BemOptions - ? ReactClassNaming.BemOptions["blockModKey"] - : ReactClassNaming.BemOptions["$default"]["blockModKey"], -> = classes extends `${b}${ - e extends bModKey ? "" : `${delE}${e}` -}${delM}${infer MV}` ? MV : never - -export type BemInGeneral = { - [block: string]: undefined | boolean | string | { - [el: string]: undefined | boolean | string - | { - [mod: string]: undefined | boolean | string - } - } -} diff --git a/__sandbox__/bem.test.ts b/__sandbox__/bem.test.ts index dfe2eca..ecf60ea 100644 --- a/__sandbox__/bem.test.ts +++ b/__sandbox__/bem.test.ts @@ -1,4 +1,5 @@ -// import { Primitive } from "react-classnaming/ts-swiss.defs" +import type { Ever0, Extends, PartDeep } from "src/ts-swiss.types" +import type {ReactClassNaming} from "../src" import { CssModule } from "../src/definitions.types" it("tree2classes", () => { @@ -149,50 +150,106 @@ describe("upon delimiter", () => { }) it("query", () => { + // Can be used on #30 + + type Elements< + classes extends string, + b extends string, + delE extends string = "__" /*"elementDelimiter" extends keyof ReactClassNaming.BemOptions + ? ReactClassNaming.BemOptions["elementDelimiter"] + : ReactClassNaming.BemOptions["$default"]["elementDelimiter"]*/, + delM extends string = "modDelimiter" extends keyof ReactClassNaming.BemOptions + ? ReactClassNaming.BemOptions["modDelimiter"] + : ReactClassNaming.BemOptions["$default"]["modDelimiter"], + bModKey extends string = "$" /*"blockModKey" extends keyof ReactClassNaming.BemOptions + ? ReactClassNaming.BemOptions["blockModKey"] + : ReactClassNaming.BemOptions["$default"]["blockModKey"]*/ + > = classes extends `${b}${delE}${infer E}` + ? Strip + : classes extends `${b}${delM}${string}` + ? bModKey + : never + type BemQuery< - bModKey extends string, - delE extends string, - delM extends string, classes extends string, - BE extends string, - Block extends string - > = { - [b in Block]?: boolean | ( - { - [bmKey in bModKey]?: { - [ - m in classes extends `${b}${delM}${infer MV}` - ? MV extends `${infer M}${delM}${infer _}` ? M : MV - : never - ]?: classes extends `${b}${delM}${m}${delM}${infer V}` - ? false|V - : boolean + delE extends string = "__" /*"elementDelimiter" extends keyof ReactClassNaming.BemOptions + ? ReactClassNaming.BemOptions["elementDelimiter"] + : ReactClassNaming.BemOptions["$default"]["elementDelimiter"]*/, + delM extends string = "modDelimiter" extends keyof ReactClassNaming.BemOptions + ? ReactClassNaming.BemOptions["modDelimiter"] + : ReactClassNaming.BemOptions["$default"]["modDelimiter"], + bModKey extends string = "$" /*"blockModKey" extends keyof ReactClassNaming.BemOptions + ? ReactClassNaming.BemOptions["blockModKey"] + : ReactClassNaming.BemOptions["$default"]["blockModKey"]*/ + > = string extends classes ? BemInGeneral : PartDeep<{ + [b in Strip, delE>]: boolean + | Exclude, `${string}${delM}${string}`> + | ( + Extends]: boolean + | Exclude, `${string}${delM}${string}`> + | ( + {[m in Strip, delM>]: + false | ( + Ever0< + classes extends `${b}${ + e extends bModKey ? "" : `${delE}${e}` + }${delM}${m}${delM}${infer V}` + ? V : never, + true + > + ) + } + ) } - } & { - [e in BE extends `${b}${delE}${infer E}` ? E : never]?: boolean | { - [ - m in classes extends `${b}${delE}${e}${delM}${infer M}${delM}${infer _}` - ? M - : classes extends `${b}${delE}${e}${delM}${infer M}` - ? M - : never - ]?: classes extends `${b}${delE}${e}${delM}${m}${delM}${infer V}` - ? false|V - : boolean - + > + ) + }> + + type MVs< + classes extends string, + b extends string, + e extends string, + delE extends string = "__" /*"elementDelimiter" extends keyof ReactClassNaming.BemOptions + ? ReactClassNaming.BemOptions["elementDelimiter"] + : ReactClassNaming.BemOptions["$default"]["elementDelimiter"]*/, + delM extends string = "modDelimiter" extends keyof ReactClassNaming.BemOptions + ? ReactClassNaming.BemOptions["modDelimiter"] + : ReactClassNaming.BemOptions["$default"]["modDelimiter"], + bModKey extends string = "$" /*"blockModKey" extends keyof ReactClassNaming.BemOptions + ? ReactClassNaming.BemOptions["blockModKey"] + : ReactClassNaming.BemOptions["$default"]["blockModKey"]*/ + > = classes extends `${b}${ + e extends bModKey ? "" : `${delE}${e}` + }${delM}${infer MV}` ? MV : never + + type BemInGeneral = { + [block: string]: undefined | boolean | string | { + [el: string]: undefined | boolean | string + | { + [mod: string]: undefined | boolean | string } - }) - } + } + } + type BemQuerier< ClassNames extends CssModule, - bModKey extends string = "$", delE extends string = "__", - delM extends string = "--" + delM extends string = "--", + bModKey extends string = "$", > = < // classes extends keyof ClassNames, - BE extends StripFromObj, - Q extends BemQuery> + // BE extends StripFromObj, + Q extends BemQuery< + keyof ClassNames, + delE, + delM, + bModKey + // BE, + // Strip + > >(arg: Q) => {[K in {[b in keyof Q]: Q[b] extends boolean ? b : never}[keyof Q] // | {[b in keyof Q]: Q[b] extends Primitive ? never : `${b}${delE}${keyof Q[b]}`}[keyof Q] @@ -211,46 +268,7 @@ describe("upon delimiter", () => { ]: boolean} //@ts-expect-error - const q: BemQuerier = x => { - const $result: Record = {} - - for (const block in x) { - const bVal = x[block] - - if (!bVal) { - //@ts-expect-error - $result[block] = bVal - continue - } - - for (const el in bVal) { - //@ts-expect-error - const eVal = bVal[el] - , be = el === "$" ? block : `${block}__${el}` - - if (!eVal) { - $result[be] = eVal - continue - } - - $result[be] = true - - for (const mod in eVal) { - const value: string|boolean = eVal[mod] - switch (typeof value) { - case "boolean": - $result[`${be}--${mod}`] = value - break - case "string": - $result[`${be}--${mod}--${value}`] = true - break - } - } - } - } - - return $result - } + const q = x => x as unknown as BemQuerier , res = q({ "App": { "Header": false, @@ -272,24 +290,25 @@ describe("upon delimiter", () => { }) , typeCheck: Record = { "exact": { + //@ts-expect-error Footer: true, Btn: true, App: true, } } - expect(res).toStrictEqual({ - "App__Container": true, - "App__Container--loading": true, - "App__Container--status--error": true, - "App__Header": false, - "Btn": true, - "Btn--disabled": false, - "Btn--info--error": true, - "Btn__Icon": true, - "Btn__Icon--big": true, - "Footer": false, - }) + // expect(res).toStrictEqual({ + // "App__Container": true, + // "App__Container--loading": true, + // "App__Container--status--error": true, + // "App__Header": false, + // "Btn": true, + // "Btn--disabled": false, + // "Btn--info--error": true, + // "Btn__Icon": true, + // "Btn__Icon--big": true, + // "Footer": false, + // }) expect(typeCheck).toBeInstanceOf(Object) }) }) diff --git a/src/bem.core.test.ts b/src/bem.core.test.ts index 9c57fc9..8a63c8d 100644 --- a/src/bem.core.test.ts +++ b/src/bem.core.test.ts @@ -36,9 +36,8 @@ describe(bem2arr.name, () => { describe("optioning", () => { const defaultOpts: BemOptions = { - elementDelimiter: "__", + // TODO #30 elementDelimiter: "__", modDelimiter: "--", - blockModKey: "$" } it("default", () => expect( @@ -57,9 +56,8 @@ describe("optioning", () => { it("set another", () => { //TODO #29 test bem with not default options const opts: BemOptions = { - elementDelimiter: "_", + // TODO #30 elementDelimiter: "_", modDelimiter: "-", - blockModKey: "$" } setOptions(opts) diff --git a/src/bem.core.ts b/src/bem.core.ts index 5584a66..f621ec0 100644 --- a/src/bem.core.ts +++ b/src/bem.core.ts @@ -1,13 +1,11 @@ import type { BemInGeneral } from "./bem.types" let modDelimiter = "--" -, elementDelimiter = "__" -, blockModKey = "$" +// TODO #30 , elementDelimiter = "__" export type BemOptions = { - elementDelimiter: string + // TODO #30 elementDelimiter: string modDelimiter: string - blockModKey: string } export { @@ -48,19 +46,15 @@ function bem2arr(query: BemInGeneral) { } function setOptions({ - elementDelimiter: elD = elementDelimiter, - modDelimiter: modDel = modDelimiter, - blockModKey: modKey = blockModKey + // TODO #30 elementDelimiter: elD = elementDelimiter, + modDelimiter: modDel = modDelimiter }: Partial) { - elementDelimiter = elD modDelimiter = modDel - blockModKey = modKey } function getOptions() { return { - elementDelimiter, + // TODO #30 elementDelimiter, modDelimiter, - blockModKey } } \ No newline at end of file diff --git a/src/index.ts b/src/index.ts index 92fc4c7..ecbec70 100644 --- a/src/index.ts +++ b/src/index.ts @@ -18,9 +18,8 @@ export { setOptions } from "./bem.core" export declare namespace ReactClassNaming { export interface BemOptions { $default: { - elementDelimiter: "__" + // TODO #30 elementDelimiter: "__" modDelimiter: "--" - blockModKey: "$" } } }