Skip to content

Commit

Permalink
Add option to propagate to nested components
Browse files Browse the repository at this point in the history
  • Loading branch information
Andrii Kirmas committed Feb 21, 2021
1 parent f829369 commit 824f97d
Show file tree
Hide file tree
Showing 3 changed files with 72 additions and 26 deletions.
10 changes: 10 additions & 0 deletions src/ctx.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -88,4 +88,14 @@ describe(classNamingCtx.name, () => {
className: "App class1 hash4"
}))
})

it("for component", () => expect(classNamingCtx(
{classNames},
{withClassNames: true}
)(
false
)).toStrictEqual({
className: "",
classNames
}))
})
85 changes: 61 additions & 24 deletions src/ctx.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
import type { Falsy, ToggleMap, ClassValue, ClassNamer, ClassNamed } from "./defs"
import type { Falsy, ToggleMap, ClassValue, ClassNamer, ClassNamed, ClassNamesMap } from "./defs"
import { emptize, stringifyClassNamed, truthyKeys } from "./utils"

emptize(classNamer)

//TODO no `className` - no first `true`
interface tClassNaming<ClassKeys extends string> {
/**
* @example classes(true) === props.className
Expand All @@ -17,7 +20,7 @@ interface tClassNaming<ClassKeys extends string> {
: ToggleMap<ClassKeys>
) | ClassKeys | Falsy,
...expressions: (ClassKeys | Falsy)[]
) : ClassNamed
) : ClassNamed & {classNames?: ClassNamesMap<ClassKeys>}
}

export default classNamingCtx
Expand All @@ -27,20 +30,44 @@ export default classNamingCtx
* @example const classes = classNamingCtx({className, classNames})
* @example const classes = classNamingCtx({classNames})
*/
function classNamingCtx<ClassKeys extends string>(ctx: ClassNamer<ClassKeys>): tClassNaming<ClassKeys> {
emptize(ctx.classNames)
function classNamingCtx<ClassKeys extends string/*, withClassNames extends boolean = false*/>(
{classNames, className}: ClassNamer<ClassKeys>,
options?: ClassNamerOptions//<withClassNames>
): tClassNaming<ClassKeys> {
emptize(classNames)

return classNamer.bind(ctx) as tClassNaming<ClassKeys>
return classNamer.bind({classNames, className, ...options}) as tClassNaming<ClassKeys>
}

// type get<T, K> = K extends keyof T ? T[K] : never

type ClassNamerOptions<
// withClassNames extends undefined|boolean = undefined|boolean
> = Partial<{
withClassNames: boolean //withClassNames
// withSelf: boolean
}>

function classNamer<ClassKeys extends string>(
this: ClassNamer<ClassKeys>,
this: ClassNamer<ClassKeys> & ClassNamerOptions,
arg0: true | ToggleMap<ClassKeys> | ClassKeys,
arg1?: ToggleMap<ClassKeys> | ClassKeys,
...args: (ClassKeys | Falsy)[]
): ClassNamed {
const {className, classNames} = this
const withPropagation = arg0 === true
): ClassNamed
& Partial<Pick<typeof this, "classNames">>
// & (
// [Extract<get<typeof this, "withClassNames">, true>] extends [never]
// ? EmptyObject
// : Pick<typeof this, "classNames">
// )
{
const {
className: _propagated,
classNames,
withClassNames,
// withSelf
} = this
, withPropagation = arg0 === true
, allowed: ClassKeys[] = truthyKeys(arg0 === true ? false : arg0)
//@ts-expect-error
.concat(truthyKeys(arg1))
Expand All @@ -51,6 +78,8 @@ function classNamer<ClassKeys extends string>(
Boolean
)

emptize(classNames)

for (let i = allowed.length; i--;) {
const key = allowed[i]
, hash: ClassValue = classNames[key]
Expand All @@ -61,20 +90,28 @@ function classNamer<ClassKeys extends string>(
}

const allowedString = allowed.join(" ")
, propagated = withPropagation && className || ""
, $return = {
className: `${
propagated
}${
propagated && allowedString
? " "
: ""
}${
allowedString
}`
}

stringifyClassNamed($return)
, propagated = withPropagation && _propagated || ""

//TODO Consider undefined|empty|never for type error
, className = `${
propagated
}${
propagated && allowedString
? " "
: ""
}${
allowedString
}`


return $return
if (!withClassNames) {
return stringifyClassNamed({
className
})
} else {
return stringifyClassNamed({
className,
classNames
})
}
}
3 changes: 1 addition & 2 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
/** TBD
* 1. `typeof classNaming === "function"` falls <div className={classNaming()} />
* 2. <div {...{false, undefined, null}}/> falls attributes
* 1. <div {...{false, undefined, null}}/> falls attributes
*/
export type { ClassNames } from "./defs"
import { EMPTY_OBJECT } from "./consts"
Expand Down

0 comments on commit 824f97d

Please sign in to comment.