diff --git a/README.md b/README.md index 6020539..c822fd5 100644 --- a/README.md +++ b/README.md @@ -11,7 +11,7 @@ Join our community on our [Discord Server](https://discord.gg/J6Sv9sQ64t) to sta ### Example ```typescript -import component from '@teiler/svelte' +import { component } from '@teiler/svelte' const Button = component.button<{ _primary: boolean @@ -50,7 +50,7 @@ These are the frameworks we are currently working on and planning to support in ## Keyframes ```typescript -import component, { keyframes } from '@teiler/svelte' +import { component, keyframes } from '@teiler/svelte' const bouncing = keyframes` from, 20%, 53%, 80%, to { @@ -106,7 +106,7 @@ Example how to use themes. // Component with theme usage -import component from '@teiler/svelte' +import { component } from '@teiler/svelte' const Component = component.div` color: ${({ theme }) => theme.fontColor}; diff --git a/packages/core/src/constructor.ts b/packages/core/src/constructor.ts index 515c83e..960d5f1 100644 --- a/packages/core/src/constructor.ts +++ b/packages/core/src/constructor.ts @@ -1,4 +1,5 @@ import type { Sheet } from './sheet' +import type { HTMLElements } from './tags' import { compile, transpile } from './css' import hash from './hash' @@ -20,19 +21,17 @@ type Raw = string | number type Properties = Expression | StyleDefinition | Raw type Style = [string[], Properties[]] -type Target = string - type TeilerComponent = { styles: Array> tag: Target } -type CreateCallback> = (styles: Array>) => Type -type ExtendCallback> = (string: ReadonlyArray, ...properties: Properties[]) => Type +type CreateCallback> = (styles: Array>) => Type +type ExtendCallback> = (string: ReadonlyArray, ...properties: Properties[]) => Type -function styled>( +function styled>( createComponent: CreateCallback, - stringOrBinded: TeilerComponent | ReadonlyArray, + stringOrBinded: TeilerComponent | ReadonlyArray, ...properties: Properties[] ): ExtendCallback | Type { if (Array.isArray(stringOrBinded)) { @@ -40,7 +39,7 @@ function styled>( const style: Style = [Array.from(strings), properties] return createComponent([style]) } else { - const binded = stringOrBinded as TeilerComponent + const binded = stringOrBinded as TeilerComponent return (strings: ReadonlyArray, ...properties: Expression[]) => { const style: Style = [Array.from(strings), properties] return createComponent([...binded.styles, style]) @@ -104,5 +103,5 @@ function keyframes(strings: ReadonlyArray, ...properties: Raw[]): StyleD return { id, name, css: `@keyframes ${name} { ${css} }`, type: 'keyframes' } } -export type { Arguments, Compile, DefaultTheme, Properties, Sheet, Style, StyleDefinition, TeilerComponent, Target } +export type { Arguments, Compile, DefaultTheme, Properties, Sheet, Style, StyleDefinition, TeilerComponent, HTMLElements } export { keyframes, component, global, styled } diff --git a/packages/core/src/index.ts b/packages/core/src/index.ts index 15d114b..b3d3077 100644 --- a/packages/core/src/index.ts +++ b/packages/core/src/index.ts @@ -1,5 +1,7 @@ -export type { Compile, DefaultTheme, Properties, Sheet, Style, StyleDefinition, TeilerComponent, Target } from './constructor' +export type { HTMLElements } from './tags' +export type { Compile, 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' diff --git a/packages/core/src/pattern.ts b/packages/core/src/pattern.ts index 86517a8..775d021 100644 --- a/packages/core/src/pattern.ts +++ b/packages/core/src/pattern.ts @@ -1,22 +1,23 @@ -import type { Compile, Properties, Style, Target, TeilerComponent } from './constructor' +import type { Compile, Properties, Style, TeilerComponent } from './constructor' +import type { HTMLElements } from './tags' import { component, global } from './constructor' import tags from './tags' -type Pattern = { styles: Style[]; tag: Target; __teiler__: true } -type ExtendCallback = (string: ReadonlyArray, ...properties: Properties>[]) => Pattern> +type Pattern = { styles: Style[]; tag: Target; __teiler__: true } +type ExtendCallback = (string: ReadonlyArray, ...properties: Properties>[]) => Pattern> -type Constructor = { +type Constructor = { (pattern: Pattern): ExtendCallback (string: ReadonlyArray, ...properties: Properties[]): Pattern } -type ConstructorWithTags = Constructor<'div'> & { [K in (typeof tags)[number]]: Constructor } & { global: Constructor } +type ConstructorWithTags = Constructor<'div'> & { [K in HTMLElements]: Constructor } & { global: Constructor } -type Inter = Component extends Pattern ? P & Props : Props +type Inter = Component extends Pattern ? P & Props : Props -const construct = (tag: string) => { - return (stringOrPattern: Pattern | ReadonlyArray, ...properties: Properties[]): Pattern | ExtendCallback => { +const construct = (tag: HTMLElements) => { + return (stringOrPattern: Pattern | ReadonlyArray, ...properties: Properties[]): Pattern | ExtendCallback => { if ('__teiler__' in stringOrPattern) { return (strings: ReadonlyArray, ...properties: Properties>[]) => { const style: Style = [Array.from(strings), properties] @@ -42,7 +43,7 @@ const binded = pattern as ConstructorWithTags type CreateFunction> = (compile: Compile, tag: Target, styles: Array>) => Type -function sew>(pattern: Pattern, createComponent: CreateFunction): Type { +function sew>(pattern: Pattern, createComponent: CreateFunction): Type { const compiler = pattern.tag === null ? global : component return createComponent(compiler, pattern.tag, pattern.styles) } diff --git a/packages/core/src/tags.ts b/packages/core/src/tags.ts index 46fa83c..21807c8 100644 --- a/packages/core/src/tags.ts +++ b/packages/core/src/tags.ts @@ -1,4 +1,4 @@ -const tags = [ +const elements = [ 'a', 'abbr', 'address', @@ -44,7 +44,6 @@ const tags = [ 'h4', 'h5', 'h6', - 'head', 'header', 'hgroup', 'hr', @@ -63,7 +62,6 @@ const tags = [ 'main', 'map', 'mark', - 'marquee', 'menu', 'menuitem', 'meta', @@ -105,16 +103,14 @@ const tags = [ 'th', 'thead', 'time', - 'title', 'tr', 'track', 'u', 'ul', + 'use', 'var', 'video', - 'wbr', - - // SVG + 'wbr', // SVG 'circle', 'clipPath', 'defs', @@ -124,6 +120,7 @@ const tags = [ 'image', 'line', 'linearGradient', + 'marker', 'mask', 'path', 'pattern', @@ -135,6 +132,7 @@ const tags = [ 'svg', 'text', 'tspan', -] as const +] as const; -export default tags +export default new Set(elements); +export type HTMLElements = (typeof elements)[number]; \ No newline at end of file diff --git a/packages/svelte/src/component.ts b/packages/svelte/src/component.ts new file mode 100644 index 0000000..83332d2 --- /dev/null +++ b/packages/svelte/src/component.ts @@ -0,0 +1,59 @@ +import type { Compile, HTMLElements, Properties, Style, 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 + +const createComponent = (compile: Compile, tag: Target, styles: Array>): SvelteTeilerComponent => { + return class extends Styled { + static styles = styles + static tag = tag + + constructor(options) { + super({ + ...options, + props: { + ...options.props, + compile, + tag, + styles, + }, + }) + } + } +} + +type InferProps = Component extends SvelteTeilerComponent ? P & Props : Props +type InferComponent = Component extends SvelteTeilerComponent ? SvelteTeilerComponent : SvelteTeilerComponent + +type Component = { + (string: TemplateStringsArray, ...properties: Properties[]): SvelteTeilerComponent + (binded: Component): (string: TemplateStringsArray, ...properties: Properties>[]) => InferComponent +} + +type Global = { + (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 baseComponent = construct('div', component) + +tags.forEach((tag) => { + baseComponent[tag] = construct(tag, component) +}) + +const svelteComponent = baseComponent as ComponentWithTags + +const svelteGlobal = construct(null, global) as Global + +export { svelteComponent as component, svelteGlobal as global, keyframes, createComponent } diff --git a/packages/svelte/src/index.ts b/packages/svelte/src/index.ts index ebd9e07..9d7cf87 100644 --- a/packages/svelte/src/index.ts +++ b/packages/svelte/src/index.ts @@ -1,59 +1,2 @@ -import type { Compile, Properties, Style, Target, TeilerComponent } from '@teiler/core' -import type { ComponentType, SvelteComponent } from 'svelte' - -import { component, global, keyframes, styled } from '@teiler/core' -import Styled from './Styled.svelte' -import tags from './tags' - -type SvelteTeilerComponent = TeilerComponent & ComponentType - -const createComponent = (compile: Compile, tag: Target, styles: Array>): SvelteTeilerComponent => { - return class extends Styled { - static styles = styles - static tag = tag - - constructor(options) { - super({ - ...options, - props: { - ...options.props, - compile, - tag, - styles, - }, - }) - } - } -} - -type InferProps = Component extends SvelteTeilerComponent ? P & Props : Props -type InferComponent = Component extends SvelteTeilerComponent ? SvelteTeilerComponent : SvelteTeilerComponent - -type Component = { - (string: TemplateStringsArray, ...properties: Properties[]): SvelteTeilerComponent - (binded: Component): (string: TemplateStringsArray, ...properties: Properties>[]) => InferComponent -} - -type Global = { - (string: TemplateStringsArray, ...properties: Properties[]): SvelteTeilerComponent -} - -type ComponentWithTags = Component<'div'> & { [K in (typeof tags)[number]]: Component } - -const construct = (tag: string, 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 svelteComponent = construct('div', component) - -tags.forEach((tag) => { - svelteComponent[tag] = construct(tag, component) -}) - -const svelteGlobal = construct(null, global) as Global - -export { svelteGlobal as global, keyframes, createComponent } -export default svelteComponent as ComponentWithTags +export { component, global, keyframes, createComponent } from './component' +export { default as ThemeProvider } from './ThemeProvider.svelte' diff --git a/packages/svelte/src/tags.ts b/packages/svelte/src/tags.ts deleted file mode 100644 index d49de8a..0000000 --- a/packages/svelte/src/tags.ts +++ /dev/null @@ -1,140 +0,0 @@ -const tags = [ - 'a', - 'abbr', - 'address', - 'area', - 'article', - 'aside', - 'audio', - 'b', - 'base', - 'bdi', - 'bdo', - 'big', - 'blockquote', - 'body', - 'br', - 'button', - 'canvas', - 'caption', - 'cite', - 'code', - 'col', - 'colgroup', - 'data', - 'datalist', - 'dd', - 'del', - 'details', - 'dfn', - 'dialog', - 'div', - 'dl', - 'dt', - 'em', - 'embed', - 'fieldset', - 'figcaption', - 'figure', - 'footer', - 'form', - 'h1', - 'h2', - 'h3', - 'h4', - 'h5', - 'h6', - 'head', - 'header', - 'hgroup', - 'hr', - 'html', - 'i', - 'iframe', - 'img', - 'input', - 'ins', - 'kbd', - 'keygen', - 'label', - 'legend', - 'li', - 'link', - 'main', - 'map', - 'mark', - 'marquee', - 'menu', - 'menuitem', - 'meta', - 'meter', - 'nav', - 'noscript', - 'object', - 'ol', - 'optgroup', - 'option', - 'output', - 'p', - 'param', - 'picture', - 'pre', - 'progress', - 'q', - 'rp', - 'rt', - 'ruby', - 's', - 'samp', - 'script', - 'section', - 'select', - 'small', - 'source', - 'span', - 'strong', - 'style', - 'sub', - 'summary', - 'sup', - 'table', - 'tbody', - 'td', - 'textarea', - 'tfoot', - 'th', - 'thead', - 'time', - 'title', - 'tr', - 'track', - 'u', - 'ul', - 'var', - 'video', - 'wbr', - - // SVG - 'circle', - 'clipPath', - 'defs', - 'ellipse', - 'foreignObject', - 'g', - 'image', - 'line', - 'linearGradient', - 'mask', - 'path', - 'pattern', - 'polygon', - 'polyline', - 'radialGradient', - 'rect', - 'stop', - 'svg', - 'text', - 'tspan' -] as const - -export default tags diff --git a/packages/svelte/stories/component.ts b/packages/svelte/stories/component.ts index 8608f77..fbdda68 100644 --- a/packages/svelte/stories/component.ts +++ b/packages/svelte/stories/component.ts @@ -1,4 +1,4 @@ -import component from '@teiler/svelte' +import { component } from '@teiler/svelte' const Component = component.button<{ _primary: boolean diff --git a/packages/svelte/stories/keyframes.ts b/packages/svelte/stories/keyframes.ts index 09c1ef5..188bdc0 100644 --- a/packages/svelte/stories/keyframes.ts +++ b/packages/svelte/stories/keyframes.ts @@ -1,4 +1,4 @@ -import component, { keyframes } from '@teiler/svelte' +import { component, keyframes } from '@teiler/svelte' const test = "20px" diff --git a/packages/svelte/stories/palette.ts b/packages/svelte/stories/palette.ts index 7bd0642..6fa6ba3 100644 --- a/packages/svelte/stories/palette.ts +++ b/packages/svelte/stories/palette.ts @@ -1,6 +1,6 @@ import { pattern, sew } from '@teiler/core' -import component, { createComponent } from '@teiler/svelte' +import { component, createComponent } from '@teiler/svelte' const Test = pattern.button<{ _primaryColor: string diff --git a/packages/svelte/stories/theme.ts b/packages/svelte/stories/theme.ts index ef58960..27178da 100644 --- a/packages/svelte/stories/theme.ts +++ b/packages/svelte/stories/theme.ts @@ -1,4 +1,4 @@ -import component from '@teiler/svelte' +import { component } from '@teiler/svelte' const Component = component.div` color: ${({ theme }) => theme.fontColor};