diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 3f26c6c..04bebae 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -46,3 +46,21 @@ jobs: run: yarn install - name: Run tests run: yarn lint + format: + runs-on: ubuntu-20.04 + steps: + - uses: actions/checkout@v2 + - uses: actions/setup-node@v3 + with: + node-version: 20.x + - uses: actions/cache@v3 + id: yarn-cache + with: + path: .yarn/cache + key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }} + restore-keys: | + ${{ runner.os }}-yarn- + - name: Install Dependencies + run: yarn install + - name: Run tests + run: yarn check-format diff --git a/.prettierrc.json b/.prettierrc.json index 5b7ea64..9093935 100644 --- a/.prettierrc.json +++ b/.prettierrc.json @@ -1,4 +1,6 @@ { + "plugins": ["prettier-plugin-svelte"], + "overrides": [{ "files": "*.svelte", "options": { "parser": "svelte" } }], "tabWidth": 2, "semi": false, "singleQuote": true, diff --git a/.yarn/install-state.gz b/.yarn/install-state.gz index 1c0e2b1..b206b74 100644 Binary files a/.yarn/install-state.gz and b/.yarn/install-state.gz differ diff --git a/package.json b/package.json index 4422fd1..2430470 100644 --- a/package.json +++ b/package.json @@ -8,6 +8,7 @@ "build": "turbo run build", "test": "turbo run test", "lint": "eslint packages/*/src", + "check-format": "prettier -c packages/**/src/*", "dev": "turbo run dev", "storybook": "storybook dev -p 6005", "storybook-packages": "turbo run storybook", @@ -19,6 +20,7 @@ "@typescript-eslint/parser": "^6.7.0", "eslint": "^8.49.0", "prettier": "^3.0.3", + "prettier-plugin-svelte": "^3.1.2", "storybook": "^7.4.1", "turbo": "^1.10.13", "typescript": "^5.2.2", diff --git a/packages/core/src/constructor.test.ts b/packages/core/src/constructor.test.ts index d73dbcd..a742ff3 100644 --- a/packages/core/src/constructor.test.ts +++ b/packages/core/src/constructor.test.ts @@ -1,32 +1,43 @@ -import type { Compile, Style, TeilerComponent } from '.' +import type { HTMLElements, StyleDefinition, TeilerComponent } from '.' import { describe, expect, jest, test } from '@jest/globals' -import { component, createStyleSheet, global, keyframes, styled } from '.' +import { component, global, keyframes, styled } from '.' -const createComponent = (compile: Compile, tag: Target, styles: Array>): TeilerComponent => { +const createComponent = (styles: StyleDefinition): TeilerComponent => { return { - tag, - styles, + styleDefinition: styles, } } describe('styled', () => { test('should create component', () => { - const createComponentBinded = createComponent.bind(null, null, 'div') const template = ['color: red;'] const test = jest.fn(styled) - test(createComponentBinded, template) + test('div', component, createComponent, template) - expect(test).toHaveReturnedWith({ styles: [[['color: red;'], []]], tag: 'div' }) + expect(test).toHaveReturnedWith({ + styleDefinition: { + id: 'twq229y', + styles: [[['color: red;'], []]], + tag: 'div', + type: 'component', + }, + }) }) test('should extend component', () => { - const createComponentBinded = createComponent.bind(null, null, 'div') const template = ['background: blue;'] - const component: TeilerComponent<'div', {}> = { tag: 'div', styles: [[['color: red;'], []]] } + const existingComponent: TeilerComponent<'div', {}> = { + styleDefinition: { + type: 'component', + id: 'a', + tag: 'div', + styles: [[['color: red;'], []]], + }, + } - const extend = styled(createComponentBinded, component) + const extend = styled('div', component, createComponent, existingComponent) type Callable = Extract @@ -35,54 +46,72 @@ describe('styled', () => { test(template) expect(test).toHaveReturnedWith({ - styles: [ - [['color: red;'], []], - [['background: blue;'], []], - ], - tag: 'div', + styleDefinition: { + id: 't18maiqm', + styles: [ + [['color: red;'], []], + [['background: blue;'], []], + ], + tag: 'div', + type: 'component', + }, }) }) }) describe('component', () => { - test('should create style from styles', () => { - const styleSheet = createStyleSheet({}) + test('should create style definition from styles', () => { const test = jest.fn(component) - test(styleSheet, [[['color: red;'], []]], {}) + test('div', [[['color: red;'], []]]) - expect(test).toHaveReturnedWith(['teiler-wq229y']) + expect(test).toHaveReturnedWith({ + id: 'twq229y', + styles: [[['color: red;'], []]], + tag: 'div', + type: 'component', + }) }) - test('should create style from styles with props', () => { - const styleSheet = createStyleSheet({}) - const test = jest.fn(component<{ color: string }>) + test('should create style definition from styles with props', () => { + const test = jest.fn(component<'div', { color: string }>) - test(styleSheet, [[['color: ', ';'], [({ color }) => color]]], { color: 'blue' }) + test('div', [[['color: ', ';'], [({ color }) => color]]]) - expect(test).toHaveReturnedWith(['teiler-1r77qux']) + expect(test).toHaveReturnedWith({ + id: 't10upe3l', + styles: [[['color: ', ';'], [expect.any(Function)]]], + tag: 'div', + type: 'component', + }) }) }) describe('global', () => { - test('should create style from styles', () => { - const styleSheet = createStyleSheet({}) + test('should create style definition from styles', () => { const test = jest.fn(global) - test(styleSheet, [[['body { color: red; }'], []]], {}) + test(null, [[['body { color: red; }'], []]]) - expect(test).toHaveReturnedWith(undefined) - expect(styleSheet.dump()).toContain(' body{color:red;}') + expect(test).toHaveReturnedWith({ + id: 'tytz3vv', + styles: [[['body { color: red; }'], []]], + tag: null, + type: 'global', + }) }) - test('should create style from styles with props', () => { - const styleSheet = createStyleSheet({}) - const test = jest.fn(global<{ color: string }>) + test('should create style definition from styles with props', () => { + const test = jest.fn(global) - test(styleSheet, [[['body { color: ', '; }'], [({ color }) => color]]], { color: 'blue' }) + test(null, [[['body { color: ', '; }'], [({ color }) => color]]]) - expect(test).toHaveReturnedWith(undefined) - expect(styleSheet.dump()).toContain(' body{color:blue;}') + expect(test).toHaveReturnedWith({ + id: 't1420fqd', + styles: [[['body { color: ', '; }'], [expect.any(Function)]]], + tag: null, + type: 'global', + }) }) }) @@ -91,9 +120,9 @@ describe('keyframes', () => { const keyframesDefinition = keyframes`from { background-color: red; } to { background-color: green; }` expect(keyframesDefinition).toStrictEqual({ - css: `@keyframes teiler-keyframes-1ep7axc { from { background-color: red; } to { background-color: green; } }`, - id: '1ep7axc', - name: 'teiler-keyframes-1ep7axc', + id: 'teiler-1ep7axc', + styles: [[['from { background-color: red; } to { background-color: green; }'], []]], + tag: null, type: 'keyframes', }) }) @@ -107,9 +136,14 @@ describe('keyframes', () => { const keyframesDefinition = keyframes`from { background-color: ${props.from}; } to { background-color: ${props.to}; }` expect(keyframesDefinition).toEqual({ - css: '@keyframes teiler-keyframes-14uknit { from { background-color: yellow; } to { background-color: red; } }', - id: '14uknit', - name: 'teiler-keyframes-14uknit', + id: 'teiler-1vxhd59', + styles: [ + [ + ['from { background-color: ', '; } to { background-color: ', '; }'], + ['yellow', 'red'], + ], + ], + tag: null, type: 'keyframes', }) }) diff --git a/packages/core/src/constructor.ts b/packages/core/src/constructor.ts index 960d5f1..2af4793 100644 --- a/packages/core/src/constructor.ts +++ b/packages/core/src/constructor.ts @@ -1,107 +1,115 @@ import type { Sheet } from './sheet' import type { HTMLElements } from './tags' -import { compile, transpile } from './css' import hash from './hash' +import { compile, transpile } from './css' -type DefaultTheme = {[key: string]: string | boolean} +type DefaultTheme = { [key: string]: string | boolean } type Arguments = { theme?: DefaultTheme } & Props type Expression = (props: Arguments) => string | boolean -type StyleDefinition = { - id: string - name: string - css: string - type: 'component' | 'global' | 'keyframes' -} type Raw = string | number -type Properties = Expression | StyleDefinition | Raw +type Properties = Expression | StyleDefinition | TeilerComponent | Raw type Style = [string[], Properties[]] -type TeilerComponent = { +type StyleDefinition = { + type: 'component' | 'global' | 'keyframes' + id: string styles: Array> - tag: Target + tag: Target | null } -type CreateCallback> = (styles: Array>) => Type -type ExtendCallback> = (string: ReadonlyArray, ...properties: Properties[]) => Type +type TeilerComponent = { + styleDefinition: StyleDefinition +} + +type CreateCallback, Props> = (styles: StyleDefinition) => Type +type ExtendCallback, Props> = (string: ReadonlyArray, ...properties: Properties[]) => Type function styled>( - createComponent: CreateCallback, + tag: HTMLElements, + compiler: Compiler, + createComponent: CreateCallback, stringOrBinded: TeilerComponent | ReadonlyArray, ...properties: Properties[] -): ExtendCallback | Type { +): ExtendCallback | Type { if (Array.isArray(stringOrBinded)) { const strings = stringOrBinded as ReadonlyArray const style: Style = [Array.from(strings), properties] - return createComponent([style]) + const styleDefinition = compiler(tag, [style]) + return createComponent(styleDefinition) } else { const binded = stringOrBinded as TeilerComponent return (strings: ReadonlyArray, ...properties: Expression[]) => { const style: Style = [Array.from(strings), properties] - return createComponent([...binded.styles, style]) + const styleDefinition = compiler(binded.styleDefinition.tag, [...binded.styleDefinition.styles, style]) + return createComponent(styleDefinition) } } } -type Compile = (sheet: Sheet, styles: Array>, props: Props) => string[] | void - -function insert(sheet: Sheet, definitions: StyleDefinition[]): string[] { - return definitions.reduce((classes, { id, name, css, type }) => { - if (type === 'component') { - const result = transpile(`.${name} { ${css} }`).join(' ') - sheet.insert(id, result) +type Compiler = (tag: Target, styles: Array>) => StyleDefinition - classes = [...classes, name] - } else { - const result = transpile(css).join(' ') - sheet.insert(id, result) - } +const component: Compiler = (tag: Target, styles: Array>): StyleDefinition => { + const id = styles.reduce((acc, [strings]) => acc + strings.join(''), '') - return classes; - }, []) + return { + type: 'component', + id: 't' + hash(id), + styles, + tag, + } } -function component(sheet: Sheet, styles: Array>, props: Arguments): string[] { - const {css, definitions} = compile(styles, props) +const global: Compiler = (tag: null, styles: Array>): StyleDefinition => { + const id = styles.reduce((acc, [strings]) => acc + strings.join(''), '') - const id = hash(css) - const definition: StyleDefinition = { - id: id, - name: 'teiler-' + id, - css, - type: 'component' + return { + type: 'global', + id: 't' + hash(id), + styles, + tag, } - - return insert(sheet, [...definitions, definition]) } -function global(sheet: Sheet, styles: Array>, props: Arguments): void { - const {css, definitions} = compile(styles, props) +function keyframes(strings: ReadonlyArray, ...properties: Raw[]): StyleDefinition { + const style: Style<{}> = [Array.from(strings), properties] + const id = strings.join('') - const id = hash(css) - const definition: StyleDefinition = { - id: id, - name: 'teiler-' + id, - css, - type: 'global' + return { + type: 'keyframes', + id: 'teiler-' + hash(id), + styles: [style], + tag: null, } - - insert(sheet, [...definitions, definition]) } -function keyframes(strings: ReadonlyArray, ...properties: Raw[]): StyleDefinition { - const style: Style<{}> = [Array.from(strings), properties] +function insert(sheet: Sheet, definition: StyleDefinition, props: Arguments): string | null { + const { styles, type } = definition + const { css, definitions } = compile(styles, props) + const compiledId = hash(css) + + definitions.forEach((definition) => insert(sheet, definition, props)) + + if (type === 'component') { + const transpiled = transpile(`.teiler-${compiledId} { ${css} }`) + sheet.insert(compiledId, transpiled) - const { css } = compile([style], {}) - const id = hash(css) - const name = `teiler-keyframes-${id}` + return `teiler-${compiledId}` + } else if (type === 'keyframes') { + const { id: definitionId } = definition + const transpiled = transpile(`@keyframes ${definitionId} { ${css} }`) + sheet.insert(compiledId, transpiled) + } else { + const transpiled = transpile(`${css}`) + sheet.insert(compiledId, transpiled) + } - return { id, name, css: `@keyframes ${name} { ${css} }`, type: 'keyframes' } + return null } -export type { Arguments, Compile, DefaultTheme, Properties, Sheet, Style, StyleDefinition, TeilerComponent, HTMLElements } -export { keyframes, component, global, styled } +export type { Arguments, Compiler, CreateCallback, DefaultTheme, Properties, Sheet, Style, StyleDefinition, TeilerComponent, HTMLElements } +export { component, global, insert, keyframes, styled } diff --git a/packages/core/src/css.test.ts b/packages/core/src/css.test.ts index 88e6aa8..2a3a5c9 100644 --- a/packages/core/src/css.test.ts +++ b/packages/core/src/css.test.ts @@ -5,22 +5,20 @@ import { Style, StyleDefinition } from '.' describe('transpile', () => { test('should return an empty array if the CSS string is empty', () => { const css = '' - const results = transpile(css) - expect(results).toHaveLength(0) + const result = transpile(css) + expect(result).toHaveLength(0) }) test('should return an array of CSS strings with comments removed', () => { const css = '/* This is a comment */ p { color: red; } /* This is another comment */' - const results = transpile(css) - expect(results).toHaveLength(1) - expect(results.at(0)).toBe('p{color:red;}') + const result = transpile(css) + expect(result).toBe('p{color:red;}') }) test('should return button with hover from nasted selector ', () => { - const css = 'button { color: blue; &:hover: { color: red; } }' - const results = transpile(css) - expect(results).toHaveLength(2) - expect(results).toEqual(['button{color:blue;}', 'button:hover:{color:red;}']) + const css = 'button { color: blue; &:hover { color: red; } }' + const result = transpile(css) + expect(result).toEqual('button{color:blue;} button:hover{color:red;}') }) }) @@ -42,10 +40,15 @@ describe('compile', () => { }) test('with object', () => { - const keyframes: StyleDefinition = { - css: '@keyframes test { from { background-color: yellow; } to { background-color: red; } }', - id: '14uknit', - name: 'teiler-keyframes-14uknit', + const keyframes: StyleDefinition = { + tag: null, + id: 'teiler-1vxhd59', + styles: [ + [ + ['from { background-color: ', '; } to { background-color: ', '; }'], + ['yellow', 'red'], + ], + ], type: 'keyframes', } @@ -53,7 +56,7 @@ describe('compile', () => { const compiled = compile<{}>([style], {}) expect(compiled).toEqual({ - css: 'animation: teiler-keyframes-14uknit 5s;', + css: 'animation: teiler-1vxhd59 5s;', definitions: [keyframes], }) }) diff --git a/packages/core/src/css.ts b/packages/core/src/css.ts index cf200f4..88cb555 100644 --- a/packages/core/src/css.ts +++ b/packages/core/src/css.ts @@ -1,50 +1,60 @@ -import type { Arguments } from './constructor' +import type { Arguments, HTMLElements } from './constructor' import type { Style, StyleDefinition } from '.' import { middleware, prefixer, rulesheet, serialize, stringify, compile as stylisCompile } from 'stylis' const isFalsish = (chunk: unknown): chunk is undefined | null | false | '' => chunk === undefined || chunk === null || chunk === false || chunk === '' -type CompileResult = { - css: string, - definitions: StyleDefinition[] +type CompileResult = { + css: string + definitions: StyleDefinition[] } -function compile(styles: Array>, props: Arguments): CompileResult { - return styles.reduce((result, [strings, properties]) => { - const compiled = strings - .reduce((acc, strings, index) => { - acc = [...acc, strings] +function compile(styles: Array>, props: Arguments): CompileResult { + return styles.reduce( + (result, [strings, properties]) => { + const compiled = strings + .reduce((acc, strings, index) => { + acc = [...acc, strings] - const property = properties.at(index) + const property = properties.at(index) - if (property) { - let value = null - if (typeof property === 'function') { - value = property(props) - } else if (typeof property === 'object') { - result.definitions = [...result.definitions, property] - value = property.name - } else { - value = property - } + if (property) { + let value = null + if (typeof property === 'function') { + if ('styleDefinition' in property) { + const styleDefinition = property.styleDefinition as StyleDefinition + result.definitions = [...result.definitions, styleDefinition] + value = '.' + styleDefinition.id + } else { + value = property(props) + } + } else if (typeof property === 'object') { + const styleDefinition = property as StyleDefinition + result.definitions = [...result.definitions, styleDefinition] + value = styleDefinition.id + } else { + value = property + } - if (isFalsish(value) === false) { - acc = [...acc, value] + if (isFalsish(value) === false) { + acc = [...acc, value] + } } - } - return acc - }, []) - .join('') + return acc + }, []) + .join('') - result.css = result.css + compiled; + result.css = result.css + compiled - return result - }, {css: '', definitions: []}) + return result + }, + { css: '', definitions: [] }, + ) } -function transpile(css: string): string[] { +function transpile(css: string): string { const results = [] serialize( @@ -58,7 +68,7 @@ function transpile(css: string): string[] { ]), ) - return results + return results.join(' ') } export { transpile, compile } diff --git a/packages/core/src/index.ts b/packages/core/src/index.ts index b3d3077..4f86889 100644 --- a/packages/core/src/index.ts +++ b/packages/core/src/index.ts @@ -1,7 +1,7 @@ export type { HTMLElements } from './tags' -export type { Compile, DefaultTheme, Properties, Sheet, Style, StyleDefinition, TeilerComponent } from './constructor' +export type { Compiler, DefaultTheme, Properties, Sheet, Style, StyleDefinition, TeilerComponent } from './constructor' export { default as tags } from './tags' export { default as createStyleSheet } from './sheet' export { pattern, sew } from './pattern' -export { component, global, keyframes, styled } from './constructor' +export { component, global, insert, keyframes, styled } from './constructor' diff --git a/packages/core/src/pattern.test.ts b/packages/core/src/pattern.test.ts index 6fc0d03..ff9938e 100644 --- a/packages/core/src/pattern.test.ts +++ b/packages/core/src/pattern.test.ts @@ -1,9 +1,9 @@ import type { Pattern } from './pattern' -import type { Compile, Style, TeilerComponent } from '.' +import type { HTMLElements, StyleDefinition, TeilerComponent } from '.' import { describe, expect, test } from '@jest/globals' import { pattern, sew } from './pattern' -import { createStyleSheet } from '.' +import { createStyleSheet, insert } from '.' describe('pattern', () => { test('should create a pattern for a div', () => { @@ -35,7 +35,7 @@ describe('pattern', () => { }) test('should create a pattern with params', () => { - const button = pattern.button<{color: string}>`background: ${({ color }) => color};` + const button = pattern.button<{ color: string }>`background: ${({ color }) => color};` expect(button).toMatchObject({ styles: [[['background: ', ';'], [expect.any(Function)]]], tag: 'button', @@ -46,25 +46,27 @@ describe('pattern', () => { test('should create a pattern for a global component', () => { const global = pattern.global`background: blue;` expect(global).toEqual({ - styles: [[Array('background: blue;'), []]], + styles: [[['background: blue;'], []]], tag: null, __teiler__: true, }) }) }) -type TestComponent = TeilerComponent & { +type TestComponent = TeilerComponent & { render(): string } -const createComponent = (compile: Compile, tag: Target, styles: Array>): TestComponent => { +const sheet = createStyleSheet({}) + +const createComponent = (styles: StyleDefinition): TestComponent => { return { - tag, - styles, + styleDefinition: styles, render() { - const classes = compile(createStyleSheet({}), styles, {}) - if (classes) { - return `<${tag} class="${classes.join(' ')}">component` + const className = insert(sheet, styles, {}) + + if (className) { + return `<${styles.tag} class="${className}">component` } else { return '' } diff --git a/packages/core/src/pattern.ts b/packages/core/src/pattern.ts index 775d021..baed25a 100644 --- a/packages/core/src/pattern.ts +++ b/packages/core/src/pattern.ts @@ -1,8 +1,8 @@ -import type { Compile, Properties, Style, TeilerComponent } from './constructor' +import type { Properties, Style, StyleDefinition, TeilerComponent } from './constructor' import type { HTMLElements } from './tags' -import { component, global } from './constructor' import tags from './tags' +import hash from './hash' type Pattern = { styles: Style[]; tag: Target; __teiler__: true } type ExtendCallback = (string: ReadonlyArray, ...properties: Properties>[]) => Pattern> @@ -21,7 +21,7 @@ const construct = (tag: HTMLElements) => { if ('__teiler__' in stringOrPattern) { return (strings: ReadonlyArray, ...properties: Properties>[]) => { const style: Style = [Array.from(strings), properties] - return { styles: [...stringOrPattern.styles, style], tag, __teiler__: true } + return { styles: [...stringOrPattern.styles, style], tag: stringOrPattern.tag, __teiler__: true } } } else { const strings = stringOrPattern as ReadonlyArray @@ -41,11 +41,17 @@ pattern['global'] = construct(null) const binded = pattern as ConstructorWithTags -type CreateFunction> = (compile: Compile, tag: Target, styles: Array>) => Type +type CreateCallback, Props> = (styles: StyleDefinition) => Type -function sew>(pattern: Pattern, createComponent: CreateFunction): Type { - const compiler = pattern.tag === null ? global : component - return createComponent(compiler, pattern.tag, pattern.styles) +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), + styles: pattern.styles, + tag: pattern.tag, + }) } export { binded as pattern, sew } diff --git a/packages/core/src/tags.ts b/packages/core/src/tags.ts index 21807c8..722e17e 100644 --- a/packages/core/src/tags.ts +++ b/packages/core/src/tags.ts @@ -132,7 +132,7 @@ const elements = [ 'svg', 'text', 'tspan', -] as const; +] as const -export default new Set(elements); -export type HTMLElements = (typeof elements)[number]; \ No newline at end of file +export default new Set(elements) +export type HTMLElements = (typeof elements)[number] diff --git a/packages/svelte/src/Styled.svelte b/packages/svelte/src/Styled.svelte index fde7320..090b415 100644 --- a/packages/svelte/src/Styled.svelte +++ b/packages/svelte/src/Styled.svelte @@ -1,22 +1,21 @@ - + diff --git a/packages/svelte/src/component.ts b/packages/svelte/src/component.ts index 83332d2..53647ce 100644 --- a/packages/svelte/src/component.ts +++ b/packages/svelte/src/component.ts @@ -1,24 +1,21 @@ -import type { Compile, HTMLElements, Properties, Style, TeilerComponent } from '@teiler/core' +import type { Compiler, HTMLElements, Properties, StyleDefinition, TeilerComponent } from '@teiler/core' import type { ComponentType, SvelteComponent } from 'svelte' import { component, global, keyframes, styled, tags } from '@teiler/core' import Styled from './Styled.svelte' -type SvelteTeilerComponent = TeilerComponent & ComponentType +type SvelteTeilerComponent = TeilerComponent & ComponentType -const createComponent = (compile: Compile, tag: Target, styles: Array>): SvelteTeilerComponent => { +const createComponent = (styleDefinition: StyleDefinition): SvelteTeilerComponent => { return class extends Styled { - static styles = styles - static tag = tag + static styleDefinition = styleDefinition constructor(options) { super({ ...options, props: { ...options.props, - compile, - tag, - styles, + styleDefinition, }, }) } @@ -34,15 +31,14 @@ type Component = { } type Global = { - (string: TemplateStringsArray, ...properties: Properties[]): SvelteTeilerComponent + (string: TemplateStringsArray, ...properties: Properties[]): SvelteTeilerComponent } type ComponentWithTags = Component<'div'> & { [K in HTMLElements]: Component } -const construct = (tag: Target, compile: Compile) => { - return (stringOrBinded: TeilerComponent | TemplateStringsArray, ...properties: Properties[]) => { - const binded = createComponent.bind(null, compile, (stringOrBinded as TeilerComponent).tag || tag) - return styled>(binded, stringOrBinded, ...properties) +const construct = (tag: HTMLElements, compiler: Compiler) => { + return (stringOrBinded: TeilerComponent | TemplateStringsArray, ...properties: Properties[]) => { + return styled>(tag, compiler, createComponent, stringOrBinded, ...properties) } } diff --git a/packages/svelte/src/sheet.ts b/packages/svelte/src/sheet.ts index 2071a57..a87ca68 100644 --- a/packages/svelte/src/sheet.ts +++ b/packages/svelte/src/sheet.ts @@ -1,10 +1,10 @@ -import { type Sheet, createStyleSheet } from "@teiler/core"; -import { getContext } from "svelte"; +import { type Sheet, createStyleSheet } from '@teiler/core' +import { getContext } from 'svelte' export const styleSheet = createStyleSheet({}) export const StyleSheet = 'STYLE_SHEET' export function getStyleSheet(): Sheet { - return getContext(StyleSheet) || styleSheet; + return getContext(StyleSheet) || styleSheet } diff --git a/packages/svelte/stories/ComponentSelector.stories.svelte b/packages/svelte/stories/ComponentSelector.stories.svelte new file mode 100644 index 0000000..8defff0 --- /dev/null +++ b/packages/svelte/stories/ComponentSelector.stories.svelte @@ -0,0 +1,20 @@ + + + + + + + diff --git a/packages/svelte/stories/ComponentSelector.svelte b/packages/svelte/stories/ComponentSelector.svelte new file mode 100644 index 0000000..cc309d1 --- /dev/null +++ b/packages/svelte/stories/ComponentSelector.svelte @@ -0,0 +1,7 @@ + + + +Default component +Same component with color override \ No newline at end of file diff --git a/packages/svelte/stories/componentSelector.ts b/packages/svelte/stories/componentSelector.ts new file mode 100644 index 0000000..bfc282f --- /dev/null +++ b/packages/svelte/stories/componentSelector.ts @@ -0,0 +1,19 @@ +import { component } from '@teiler/svelte' + +const Component = component.div` + color: black; + background: #efefef; + border-radius: 5px; + padding: 10px 12px; + display: inline-block; +` + +const InnerComponent = component` + display: inline-block; + + & ${Component} { + color: red !important; + } +` + +export { Component, InnerComponent } diff --git a/yarn.lock b/yarn.lock index 67bc06f..0adf6e1 100644 --- a/yarn.lock +++ b/yarn.lock @@ -12519,6 +12519,16 @@ __metadata: languageName: node linkType: hard +"prettier-plugin-svelte@npm:^3.1.2": + version: 3.1.2 + resolution: "prettier-plugin-svelte@npm:3.1.2" + peerDependencies: + prettier: ^3.0.0 + svelte: ^3.2.0 || ^4.0.0-next.0 || ^5.0.0-next.0 + checksum: ab242195b61f5e9abda9adf251367ba88c01fd0c58abb3bf5227dcb0f426f22cc071f586229bc73119cc4197f28a54fa60af39ae71255a293a8e9d58710a4067 + languageName: node + linkType: hard + "prettier@npm:^2.7.1, prettier@npm:^2.8.0": version: 2.8.8 resolution: "prettier@npm:2.8.8" @@ -13386,6 +13396,7 @@ __metadata: "@typescript-eslint/parser": ^6.7.0 eslint: ^8.49.0 prettier: ^3.0.3 + prettier-plugin-svelte: ^3.1.2 storybook: ^7.4.1 turbo: ^1.10.13 typescript: ^5.2.2