aliaset
Version:
twind monorepo
105 lines (86 loc) • 2.79 kB
text/typescript
import type { CSSObject, CSSValue, StringLike } from './types'
import { escape, hash } from './utils'
import { tw as tw$ } from './runtime'
import { astish } from './internal/astish'
import { css } from './css'
export interface KeyframesFunction {
(style: CSSObject | string): StringLike
(strings: TemplateStringsArray, ...interpolations: readonly CSSValue[]): StringLike
bind(thisArg?: ((tokens: string) => string) | undefined | void): Keyframes & {
[label: string]: KeyframesFunction
}
call(
thisArg: ((tokens: string) => string) | undefined | void,
style: CSSObject | string,
): StringLike
call(
thisArg: ((tokens: string) => string) | undefined | void,
strings: TemplateStringsArray,
...interpolations: readonly CSSValue[]
): StringLike
apply(
thisArg: ((tokens: string) => string) | undefined | void,
args: [CSSObject | string],
): StringLike
apply(
thisArg: ((tokens: string) => string) | undefined | void,
args:
| [CSSObject | string]
| [strings: TemplateStringsArray, ...interpolations: readonly CSSValue[]],
): StringLike
}
export type Keyframes = KeyframesFunction & {
[label: string]: KeyframesFunction
}
/**
* **Note**: The styles will be injected on first use.
*
* @group Style Injectors
*/
export const keyframes = /* #__PURE__ */ bind()
function bind(thisArg: ((tokens: string) => string) | undefined | void): Keyframes {
return new Proxy(
function keyframes(
strings: CSSObject | string | TemplateStringsArray,
...interpolations: readonly CSSValue[]
): StringLike {
return keyframes$(thisArg, '', strings, interpolations)
} as Keyframes,
{
get(target, name) {
if (name === 'bind') {
return bind
}
if (name in target) return target[name as string]
return function namedKeyframes(
strings: CSSObject | string | TemplateStringsArray,
...interpolations: readonly CSSValue[]
): StringLike {
return keyframes$(thisArg, name as string, strings, interpolations)
}
},
},
)
}
function keyframes$(
thisArg: ((tokens: string) => string) | undefined | void,
name: string,
strings: CSSObject | string | TemplateStringsArray,
interpolations: readonly CSSValue[],
): StringLike {
// lazy inject keyframes
return {
toString() {
// lazy access tw
const tw = typeof thisArg == 'function' ? thisArg : tw$
const ast = astish(strings, interpolations)
const keyframeName = escape(name + hash(JSON.stringify([name, ast])))
tw(
css({
[`@keyframes ${keyframeName}`]: astish(strings, interpolations),
} as unknown as CSSObject),
)
return keyframeName
},
} as StringLike
}