Skip to content

Commit

Permalink
Handle Pattern as nested selector
Browse files Browse the repository at this point in the history
  • Loading branch information
drozdzynski committed Feb 1, 2024
1 parent 6a4be22 commit 8e113af
Show file tree
Hide file tree
Showing 3 changed files with 25 additions and 14 deletions.
5 changes: 4 additions & 1 deletion packages/core/src/css.ts
Original file line number Diff line number Diff line change
@@ -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'

Expand Down Expand Up @@ -29,6 +29,9 @@ function compile<Props>(styles: Array<Style<Props>>, props: Arguments<Props>): C
} else {
value = property(props)
}
} else if (typeof property === 'object' && '__pattern__' in property) {
const pattern = property as Pattern<HTMLElements, Props>
value = '.' + pattern.id
} else if (typeof property === 'object') {
const styleDefinition = property as StyleDefinition<HTMLElements, Props>
result.definitions = [...result.definitions, styleDefinition]
Expand Down
14 changes: 9 additions & 5 deletions packages/core/src/pattern.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,17 @@ describe('pattern', () => {
expect(div).toEqual({
styles: [[['background: blue;'], []]],
tag: 'div',
__teiler__: true,
__pattern__: true,
id: 't1iflo4h',
})
})

test('should extend a pattern', () => {
const extend: Pattern<'div', {}> = {
styles: [[['background: blue;'], []]],
tag: 'div',
__teiler__: true,
__pattern__: true,
id: 't1iflo4h',
}

const div = pattern<{}>(extend)`color: red;`
Expand All @@ -30,7 +32,8 @@ describe('pattern', () => {
[['color: red;'], []],
],
tag: 'div',
__teiler__: true,
__pattern__: true,
id: 'tu2c2va',
})
})

Expand All @@ -39,7 +42,7 @@ describe('pattern', () => {
expect(button).toMatchObject({
styles: [[['background: ', ';'], [expect.any(Function)]]],
tag: 'button',
__teiler__: true,
__pattern__: true,
})
})

Expand All @@ -48,7 +51,8 @@ describe('pattern', () => {
expect(global).toEqual({
styles: [[['background: blue;'], []]],
tag: null,
__teiler__: true,
__pattern__: true,
id: 't1iflo4h',
})
})
})
Expand Down
20 changes: 12 additions & 8 deletions packages/core/src/pattern.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,14 @@ import type { HTMLElements } from './tags'
import tags from './tags'
import hash from './hash'

type Pattern<Target extends HTMLElements, Props> = { styles: Style<Props>[]; tag: Target; __teiler__: true }
type PropertiesWithPattern<Props> = Properties<Props> | Pattern<HTMLElements, Props>

type Pattern<Target extends HTMLElements, Props> = { styles: Style<Props>[]; tag: Target; id: string; __pattern__: true }
type ExtendCallback<Target extends HTMLElements, Props> = <Component>(string: ReadonlyArray<string>, ...properties: Properties<Inter<Component, Props>>[]) => Pattern<Target, Inter<Component, Props>>

type Constructor<Target extends HTMLElements> = {
<Props>(pattern: Pattern<Target, Props>): ExtendCallback<Target, Props>
<Props>(string: ReadonlyArray<string>, ...properties: Properties<Props>[]): Pattern<Target, Props>
<Props>(string: ReadonlyArray<string>, ...properties: PropertiesWithPattern<Props>[]): Pattern<Target, Props>
}

type ConstructorWithTags = Constructor<'div'> & { [K in HTMLElements]: Constructor<K> } & { global: Constructor<null> }
Expand All @@ -18,15 +20,19 @@ type Inter<Component, Props> = Component extends Pattern<HTMLElements, infer P>

const construct = (tag: HTMLElements) => {
return <Props>(stringOrPattern: Pattern<HTMLElements, Props> | ReadonlyArray<string>, ...properties: Properties<Props>[]): Pattern<HTMLElements, Props> | ExtendCallback<HTMLElements, Props> => {
if ('__teiler__' in stringOrPattern) {
if ('__pattern__' in stringOrPattern) {
return <Component>(strings: ReadonlyArray<string>, ...properties: Properties<Inter<Component, Props>>[]) => {
const style: Style<Props> = [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<string>
const style: Style<Props> = [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 }
}
}
}
Expand All @@ -44,11 +50,9 @@ const binded = pattern as ConstructorWithTags
type CreateCallback<Target extends HTMLElements, Type extends TeilerComponent<Target, Props>, Props> = (styles: StyleDefinition<Target, Props>) => Type

function sew<Target extends HTMLElements, Props, Type extends TeilerComponent<Target, Props>>(pattern: Pattern<Target, Props>, createComponent: CreateCallback<Target, Type, Props>): 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,
})
Expand Down

0 comments on commit 8e113af

Please sign in to comment.