From 8e113afc94a6f0e58ece0879bb16b9f8e3380a46 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krystian=20Droz=CC=87dz=CC=87yn=CC=81ski?= Date: Thu, 1 Feb 2024 17:06:29 +0100 Subject: [PATCH] Handle Pattern as nested selector --- packages/core/src/css.ts | 5 ++++- packages/core/src/pattern.test.ts | 14 +++++++++----- packages/core/src/pattern.ts | 20 ++++++++++++-------- 3 files changed, 25 insertions(+), 14 deletions(-) diff --git a/packages/core/src/css.ts b/packages/core/src/css.ts index 88cb555..b68df3f 100644 --- a/packages/core/src/css.ts +++ b/packages/core/src/css.ts @@ -1,5 +1,5 @@ import type { Arguments, HTMLElements } from './constructor' -import type { Style, StyleDefinition } from '.' +import type { Pattern, Style, StyleDefinition } from '.' import { middleware, prefixer, rulesheet, serialize, stringify, compile as stylisCompile } from 'stylis' @@ -29,6 +29,9 @@ function compile(styles: Array>, props: Arguments): C } else { value = property(props) } + } else if (typeof property === 'object' && '__pattern__' in property) { + const pattern = property as Pattern + value = '.' + pattern.id } else if (typeof property === 'object') { const styleDefinition = property as StyleDefinition result.definitions = [...result.definitions, styleDefinition] diff --git a/packages/core/src/pattern.test.ts b/packages/core/src/pattern.test.ts index ff9938e..4e41092 100644 --- a/packages/core/src/pattern.test.ts +++ b/packages/core/src/pattern.test.ts @@ -11,7 +11,8 @@ describe('pattern', () => { expect(div).toEqual({ styles: [[['background: blue;'], []]], tag: 'div', - __teiler__: true, + __pattern__: true, + id: 't1iflo4h', }) }) @@ -19,7 +20,8 @@ describe('pattern', () => { const extend: Pattern<'div', {}> = { styles: [[['background: blue;'], []]], tag: 'div', - __teiler__: true, + __pattern__: true, + id: 't1iflo4h', } const div = pattern<{}>(extend)`color: red;` @@ -30,7 +32,8 @@ describe('pattern', () => { [['color: red;'], []], ], tag: 'div', - __teiler__: true, + __pattern__: true, + id: 'tu2c2va', }) }) @@ -39,7 +42,7 @@ describe('pattern', () => { expect(button).toMatchObject({ styles: [[['background: ', ';'], [expect.any(Function)]]], tag: 'button', - __teiler__: true, + __pattern__: true, }) }) @@ -48,7 +51,8 @@ describe('pattern', () => { expect(global).toEqual({ styles: [[['background: blue;'], []]], tag: null, - __teiler__: true, + __pattern__: true, + id: 't1iflo4h', }) }) }) diff --git a/packages/core/src/pattern.ts b/packages/core/src/pattern.ts index baed25a..fb9a453 100644 --- a/packages/core/src/pattern.ts +++ b/packages/core/src/pattern.ts @@ -4,12 +4,14 @@ import type { HTMLElements } from './tags' import tags from './tags' import hash from './hash' -type Pattern = { styles: Style[]; tag: Target; __teiler__: true } +type PropertiesWithPattern = Properties | Pattern + +type Pattern = { styles: Style[]; tag: Target; id: string; __pattern__: true } type ExtendCallback = (string: ReadonlyArray, ...properties: Properties>[]) => Pattern> type Constructor = { (pattern: Pattern): ExtendCallback - (string: ReadonlyArray, ...properties: Properties[]): Pattern + (string: ReadonlyArray, ...properties: PropertiesWithPattern[]): Pattern } type ConstructorWithTags = Constructor<'div'> & { [K in HTMLElements]: Constructor } & { global: Constructor } @@ -18,15 +20,19 @@ type Inter = Component extends Pattern const construct = (tag: HTMLElements) => { return (stringOrPattern: Pattern | ReadonlyArray, ...properties: Properties[]): Pattern | ExtendCallback => { - if ('__teiler__' in stringOrPattern) { + if ('__pattern__' in stringOrPattern) { return (strings: ReadonlyArray, ...properties: Properties>[]) => { const style: Style = [Array.from(strings), properties] - return { styles: [...stringOrPattern.styles, style], tag: stringOrPattern.tag, __teiler__: true } + const styles = [...stringOrPattern.styles, style] + const id = styles.reduce((acc, [strings]) => acc + strings.join(''), '') + return { styles: styles, id: 't' + hash(id), tag: stringOrPattern.tag, __pattern__: true } } } else { const strings = stringOrPattern as ReadonlyArray const style: Style = [Array.from(strings), properties] - return { styles: [style], tag, __teiler__: true } + const styles = [style] + const id = styles.reduce((acc, [strings]) => acc + strings.join(''), '') + return { styles: styles, id: 't' + hash(id), tag, __pattern__: true } } } } @@ -44,11 +50,9 @@ const binded = pattern as ConstructorWithTags type CreateCallback, Props> = (styles: StyleDefinition) => Type function sew>(pattern: Pattern, createComponent: CreateCallback): Type { - const id = pattern.styles.reduce((acc, [strings]) => acc + strings.join(''), '') - return createComponent({ type: pattern.tag === null ? 'global' : 'component', - id: hash(id), + id: pattern.id, styles: pattern.styles, tag: pattern.tag, })