|
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143 |
- import { css as gooberCss } from 'goober';
- import { PropertiesHyphenFallback } from 'csstype';
-
- interface CssString {
- // TODO stricter type checking
- toString(): string
- }
-
- export class CssStringImpl implements CssString {
- private css: string
-
- constructor(s: TemplateStringsArray) {
- this.css = s.raw[0]
- .trim()
- .replace(/[ ][ ]+/g, ' ')
- .replace(/:[ ]/g, ':')
- .replace(/\n/g, '')
- .replace(/;[ ]/g, ';');
- }
-
- toString() {
- return this.css
- }
- }
-
- interface CssIf {
- (b: boolean): (...a: CssString[]) => CssIfString
- }
-
- interface CssElse {
- (...c: CssString[]): CssString
- if: CssIf
- }
-
- interface CssIfString extends CssString {
- else: CssElse
- }
-
- const cssIf: CssIf = (b: boolean) => (...a: CssString[]) => new CssIfStringImpl(b, ...a);
-
- export class CssIfStringImpl implements CssIfString {
- readonly else: CssElse
- private readonly cssStrings: CssString[]
-
- constructor(private readonly condition: boolean, ...cssStrings: CssString[]) {
- this.cssStrings = cssStrings
-
- const elseFn = (...c: CssString[]) => {
- if (this.condition) {
- return {
- toString: () => {
- return this.cssStrings.map((c2) => c2.toString()).join('');
- }
- }
- }
- return {
- toString: () => {
- return c.map((cc) => cc.toString()).join('')
- }
- };
- }
- elseFn.if = cssIf
-
- this.else = elseFn
- }
-
- toString() {
- if (this.condition) {
- return this.cssStrings.map((c2) => c2.toString()).join('');
- }
- return '';
- }
- }
-
- interface CssNest {
- (selector: string): (...a: CssString[]) => CssString
- }
-
- const cssNest: CssNest = (selector) => (...a) => {
- return {
- toString: () => `${selector}{${a.map(aa => aa.toString()).join('')}}`
- }
- }
-
- interface CssDynamic {
- (a: PropertiesHyphenFallback): CssString
- }
-
- const cssDynamic: CssDynamic = (a: PropertiesHyphenFallback) => {
- return {
- toString(): string {
- return Object
- .entries(a)
- .map(([key, value]) => `${key}:${value.toString()};`)
- .join('')
- }
- };
- };
-
- interface CssMedia {
- (raw: string): any
- }
-
- const cssMedia: CssMedia = (arg1: string) => {
- return (...body: CssString[]) => {
- return {
- toString(): string {
- return `@media ${arg1}{${body.map(b => b.toString()).join('')}}`
- }
- }
- }
- }
-
- const cssCompile = (...strings: CssString[]) => {
- return strings
- .filter((s) => ['string', 'object'].includes(typeof s))
- .map((s) => {
- if (typeof s === 'object') {
- return gooberCss`${s.toString()}`
- }
-
- return s
- })
- .join(' ')
- }
-
- interface Css {
- (s: TemplateStringsArray): CssString
- if: CssIf
- nest: CssNest
- dynamic: CssDynamic
- media: CssMedia
- cx(...strings: CssString[]): string
- }
-
- const _css: Partial<Css> = (s: TemplateStringsArray) => new CssStringImpl(s);
- _css.if = cssIf;
- _css.nest = cssNest;
- _css.dynamic = cssDynamic;
- _css.media = cssMedia;
- _css.cx = cssCompile;
-
- export const css = _css as Css;
|