@teiler/svelte 0.0.29 → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +169 -15
- package/dist/Styled.svelte +39 -0
- package/dist/Styled.svelte.d.ts +12 -0
- package/dist/ThemeProvider.svelte +12 -0
- package/dist/ThemeProvider.svelte.d.ts +9 -0
- package/dist/component.d.ts +36 -0
- package/dist/component.js +25 -0
- package/{src/index.ts → dist/index.d.ts} +2 -2
- package/dist/index.js +2 -0
- package/dist/sheet.d.ts +4 -0
- package/dist/sheet.js +14 -0
- package/dist/theme.d.ts +5 -0
- package/dist/theme.js +8 -0
- package/package.json +46 -48
- package/CHANGELOG.md +0 -212
- package/dist/teiler-svelte.cjs.js +0 -2
- package/dist/teiler-svelte.cjs.js.map +0 -1
- package/dist/teiler-svelte.d.ts +0 -24
- package/dist/teiler-svelte.esm.js +0 -2
- package/dist/teiler-svelte.esm.js.map +0 -1
- package/dist/teiler-svelte.umd.js +0 -2
- package/dist/teiler-svelte.umd.js.map +0 -1
- package/jest.config.js +0 -34
- package/src/Styled.svelte +0 -145
- package/src/ThemeProvider.svelte +0 -19
- package/src/ThemeProvider.svelte.d.ts +0 -5
- package/src/ThemeProvider.test.svelte +0 -17
- package/src/component.ts +0 -57
- package/src/global.d.ts +0 -3
- package/src/index.test.ts +0 -149
- package/src/sheet.ts +0 -20
- package/svelte.config.js +0 -7
- package/tsconfig.json +0 -31
- package/vite.config.mjs +0 -6
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
The MIT License (MIT)
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2023-present, NERDSLABS
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in
|
|
13
|
+
all copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
21
|
+
THE SOFTWARE.
|
package/README.md
CHANGED
|
@@ -4,9 +4,16 @@
|
|
|
4
4
|
|
|
5
5
|
**Teiler** is an open source library that simplifies the creation of stylish components for various frameworks.
|
|
6
6
|
|
|
7
|
-
Currently in the **alpha phase**, the library is actively being developed and improved.
|
|
7
|
+
Currently in the **alpha phase**, the library is actively being developed and improved. This package is the **Svelte 5** adapter and supports both CSR (Client-Side Rendering) and SSR (Server-Side Rendering).
|
|
8
8
|
|
|
9
|
-
Join our community on our [Discord Server](https://discord.gg/J6Sv9sQ64t) to stay informed about the latest developments, exchange ideas, and connect with fellow developers. We are continuously working on expanding our support to include more frameworks, allowing developers to effortlessly create components across various environments.
|
|
9
|
+
Join our community on our [Discord Server](https://discord.gg/J6Sv9sQ64t) to stay informed about the latest developments, exchange ideas, and connect with fellow developers. We are continuously working on expanding our support to include more frameworks, allowing developers to effortlessly create components across various environments.
|
|
10
|
+
|
|
11
|
+
## Requirements
|
|
12
|
+
|
|
13
|
+
- `svelte` `^5.16.0`
|
|
14
|
+
- A Svelte-aware bundler (Vite with `@sveltejs/vite-plugin-svelte`, SvelteKit, `rollup-plugin-svelte`, …)
|
|
15
|
+
|
|
16
|
+
The package ships uncompiled `.svelte` files through the `svelte` export condition, so your bundler compiles them for the right target (client or server) with the same Svelte version as your application.
|
|
10
17
|
|
|
11
18
|
### Example
|
|
12
19
|
|
|
@@ -33,6 +40,19 @@ const Button = component.button<{
|
|
|
33
40
|
`
|
|
34
41
|
```
|
|
35
42
|
|
|
43
|
+
```svelte
|
|
44
|
+
<Button _primary={primary} onclick={() => count++}>Clicked {count} times</Button>
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
Props prefixed with `_` are used only for styles and are not forwarded to the DOM. Every other prop, including event handlers (`onclick`, `oninput`, …) and `class`, is forwarded to the rendered element.
|
|
48
|
+
|
|
49
|
+
## Migrating from Svelte 4 (`@teiler/svelte` 0.0.x)
|
|
50
|
+
|
|
51
|
+
- Svelte 5 is required (`svelte` `^5.16.0`); Svelte 4 is no longer supported.
|
|
52
|
+
- Event handlers are props: `<Button onclick={handler}>` instead of `<Button on:click={handler}>`.
|
|
53
|
+
- If you provide the theme through context yourself, the `THEME` context holds a getter (`() => theme`) instead of a writable store. `ThemeProvider` usage is unchanged.
|
|
54
|
+
- UMD/CJS bundles are gone; the package is consumed as Svelte source by your bundler.
|
|
55
|
+
|
|
36
56
|
## Keyframes
|
|
37
57
|
|
|
38
58
|
```typescript
|
|
@@ -67,31 +87,88 @@ const Button = component.button<{}>`
|
|
|
67
87
|
`
|
|
68
88
|
```
|
|
69
89
|
|
|
70
|
-
##
|
|
90
|
+
## Extending
|
|
71
91
|
|
|
72
|
-
|
|
92
|
+
Pass an existing component to `component` to add styles to it. The new component keeps the element of the extended one, unless you pick another element with `component.<tag>`:
|
|
73
93
|
|
|
74
94
|
```typescript
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
95
|
+
import { component } from '@teiler/svelte'
|
|
96
|
+
|
|
97
|
+
const Button = component.button`
|
|
98
|
+
display: inline-block;
|
|
99
|
+
border-radius: 4px;
|
|
100
|
+
`
|
|
101
|
+
|
|
102
|
+
// renders <button>
|
|
103
|
+
const PrimaryButton = component(Button)`
|
|
104
|
+
background: #CBCBCB;
|
|
105
|
+
`
|
|
106
|
+
|
|
107
|
+
// renders <a> with Button styles
|
|
108
|
+
const ButtonLink = component.a(Button)`
|
|
109
|
+
text-decoration: none;
|
|
110
|
+
`
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
## `as` prop
|
|
114
|
+
|
|
115
|
+
Use `as` to render a component as a different element or another component without creating a new styled component. Styles stay the same, `as` is not passed to the rendered element:
|
|
116
|
+
|
|
117
|
+
```svelte
|
|
118
|
+
<script lang="ts">
|
|
119
|
+
import { Button } from './components'
|
|
120
|
+
import Link from './Link.svelte'
|
|
80
121
|
</script>
|
|
122
|
+
|
|
123
|
+
<Button as="a" href="/docs">Docs</Button>
|
|
124
|
+
<Button as={Link} to="/home">Home</Button>
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
When `as` is a component, it receives `class`, `children` and every other forwarded prop. Svelte has no attribute fallthrough, so the component has to apply `class` to its root element:
|
|
128
|
+
|
|
129
|
+
```svelte
|
|
130
|
+
<!-- Link.svelte -->
|
|
81
131
|
<script lang="ts">
|
|
132
|
+
import type { Snippet } from 'svelte'
|
|
133
|
+
import type { ClassValue } from 'svelte/elements'
|
|
134
|
+
|
|
135
|
+
const { to, class: className, children }: { to: string; class?: ClassValue; children?: Snippet } = $props()
|
|
136
|
+
</script>
|
|
137
|
+
|
|
138
|
+
<a href={to} class={className}>{@render children?.()}</a>
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
Props are typed from `as`: `as="a"` accepts anchor attributes, `as={Link}` accepts the props of `Link` and requires its required props. Without `as`, the component accepts the attributes of its own element. `svelte-check` reports an unknown tag in `as` and attributes the target does not accept:
|
|
142
|
+
|
|
143
|
+
```svelte
|
|
144
|
+
<Button as="a" href="/docs">Docs</Button> <!-- ok -->
|
|
145
|
+
<Button href="/docs">Docs</Button> <!-- error: href is not a button attribute -->
|
|
146
|
+
<Button as={Link}>Home</Button> <!-- error: to is required -->
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
> [!NOTE]
|
|
150
|
+
> `mount()` and `render()` called from TypeScript cannot infer `as`, so there props are typed from the element of the styled component.
|
|
151
|
+
|
|
152
|
+
## Theme
|
|
153
|
+
|
|
154
|
+
```svelte
|
|
155
|
+
<!-- App.svelte -->
|
|
156
|
+
<script lang="ts">
|
|
157
|
+
import type { CustomTheme } from './theme'
|
|
158
|
+
|
|
82
159
|
import { ThemeProvider } from '@teiler/svelte'
|
|
83
|
-
import { Component } from './
|
|
160
|
+
import { Component } from './components'
|
|
84
161
|
|
|
85
|
-
|
|
86
|
-
fontColor: 'red',
|
|
87
|
-
}
|
|
162
|
+
let theme: CustomTheme = $state({ fontColor: 'red' })
|
|
88
163
|
</script>
|
|
89
164
|
|
|
90
165
|
<ThemeProvider {theme}>
|
|
91
166
|
<Component>Some test text</Component>
|
|
92
167
|
</ThemeProvider>
|
|
168
|
+
```
|
|
93
169
|
|
|
94
|
-
|
|
170
|
+
```typescript
|
|
171
|
+
// components.ts
|
|
95
172
|
import { component } from '@teiler/svelte'
|
|
96
173
|
|
|
97
174
|
const Component = component.div`
|
|
@@ -102,14 +179,77 @@ export { Component }
|
|
|
102
179
|
```
|
|
103
180
|
|
|
104
181
|
To add typing for Typescript applications you need to add `extend` inside declaration file (`d.ts`)
|
|
182
|
+
|
|
105
183
|
```typescript
|
|
106
|
-
import type { CustomTheme } from
|
|
184
|
+
import type { CustomTheme } from './theme'
|
|
107
185
|
|
|
108
186
|
declare module '@teiler/core' {
|
|
109
187
|
export interface DefaultTheme extends CustomTheme {}
|
|
110
188
|
}
|
|
111
189
|
```
|
|
112
190
|
|
|
191
|
+
## Server-Side Rendering
|
|
192
|
+
|
|
193
|
+
Styles are collected into a style sheet provided through the `STYLE_SHEET` context. Create one sheet per request, render, then put the extracted CSS into the document head.
|
|
194
|
+
|
|
195
|
+
```typescript
|
|
196
|
+
import { createStyleSheet } from '@teiler/core'
|
|
197
|
+
import { render } from 'svelte/server'
|
|
198
|
+
import App from './App.svelte'
|
|
199
|
+
|
|
200
|
+
const sheet = createStyleSheet({})
|
|
201
|
+
const { body } = render(App, { context: new Map([['STYLE_SHEET', sheet]]) })
|
|
202
|
+
const { css, ids } = sheet.extract()
|
|
203
|
+
|
|
204
|
+
const styleTag = `<style data-teiler="${ids.join(' ')}">${css}</style>`
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
Read `body` before calling `extract()`: styles are inserted while the component tree renders.
|
|
208
|
+
|
|
209
|
+
> [!WARNING]
|
|
210
|
+
> Always provide a style sheet through the `STYLE_SHEET` context on the server. Without it, every request shares one module-level style sheet, so styles accumulate across requests.
|
|
211
|
+
|
|
212
|
+
## Hydration
|
|
213
|
+
|
|
214
|
+
On the client, pass the ids rendered by the server to `hydrate`, so styles that are already in the document are not inserted again. Provide the same style sheet to the app through context:
|
|
215
|
+
|
|
216
|
+
```typescript
|
|
217
|
+
import { createStyleSheet } from '@teiler/core'
|
|
218
|
+
import { hydrate } from 'svelte'
|
|
219
|
+
import App from './App.svelte'
|
|
220
|
+
|
|
221
|
+
const sheet = createStyleSheet({})
|
|
222
|
+
const element = document.querySelector<HTMLStyleElement>('style[data-teiler]')
|
|
223
|
+
|
|
224
|
+
sheet.hydrate(element?.dataset.teiler?.split(' ') ?? [])
|
|
225
|
+
|
|
226
|
+
hydrate(App, { target: document.body, context: new Map([['STYLE_SHEET', sheet]]) })
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
## Content Security Policy
|
|
230
|
+
|
|
231
|
+
With a strict `style-src` policy, pass a `nonce` to the style sheet and provide it through the `STYLE_SHEET` context. Without an explicit `nonce` no attribute is set, and the default style sheet never has one.
|
|
232
|
+
|
|
233
|
+
On the server, `extract` returns the nonce, so it can be set on the rendered `<style>` tag:
|
|
234
|
+
|
|
235
|
+
```typescript
|
|
236
|
+
const sheet = createStyleSheet({ nonce })
|
|
237
|
+
const { body } = render(App, { context: new Map([['STYLE_SHEET', sheet]]) })
|
|
238
|
+
const { css, ids } = sheet.extract()
|
|
239
|
+
|
|
240
|
+
const styleTag = `<style data-teiler="${ids.join(' ')}" nonce="${nonce}">${css}</style>`
|
|
241
|
+
```
|
|
242
|
+
|
|
243
|
+
On the client, read the nonce from the server rendered tag before creating the style sheet:
|
|
244
|
+
|
|
245
|
+
```typescript
|
|
246
|
+
const element = document.querySelector<HTMLStyleElement>('style[data-teiler]')
|
|
247
|
+
const sheet = createStyleSheet({ nonce: element?.nonce })
|
|
248
|
+
```
|
|
249
|
+
|
|
250
|
+
> [!NOTE]
|
|
251
|
+
> Use the `nonce` property, not `getAttribute('nonce')`. Browsers hide the attribute when the policy is sent in a header, so `getAttribute` returns an empty string.
|
|
252
|
+
|
|
113
253
|
## Sew a Pattern
|
|
114
254
|
|
|
115
255
|
This tool simplifies the creation of consistent and reusable visual styles for components across various web frameworks. It provides a pattern-based approach, where patterns serve as blueprints for defining the visual style of components.
|
|
@@ -140,3 +280,17 @@ const Button = sew(ButtonPattern, createComponent)
|
|
|
140
280
|
|
|
141
281
|
export default Button
|
|
142
282
|
```
|
|
283
|
+
|
|
284
|
+
Patterns can be extended the same way as components. `pattern(ButtonPattern)` keeps the element of the extended pattern, `pattern.<tag>(ButtonPattern)` changes it:
|
|
285
|
+
|
|
286
|
+
```typescript
|
|
287
|
+
import { pattern } from '@teiler/core'
|
|
288
|
+
|
|
289
|
+
const PrimaryButtonPattern = pattern(ButtonPattern)`
|
|
290
|
+
background: #CBCBCB;
|
|
291
|
+
`
|
|
292
|
+
|
|
293
|
+
const ButtonLinkPattern = pattern.a(ButtonPattern)`
|
|
294
|
+
text-decoration: none;
|
|
295
|
+
`
|
|
296
|
+
```
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import type { DefaultTheme, HTMLElements, StyleDefinition } from '@teiler/core'
|
|
3
|
+
import type { Component, Snippet } from 'svelte'
|
|
4
|
+
|
|
5
|
+
import { clsx } from 'clsx'
|
|
6
|
+
import { insert } from '@teiler/core'
|
|
7
|
+
import { getStyleSheet } from './sheet.js'
|
|
8
|
+
import { getTheme } from './theme.js'
|
|
9
|
+
|
|
10
|
+
type Props = {
|
|
11
|
+
styleDefinition: StyleDefinition<HTMLElements, unknown>
|
|
12
|
+
as?: Exclude<HTMLElements, null> | Component<any>
|
|
13
|
+
class?: string
|
|
14
|
+
children?: Snippet
|
|
15
|
+
[key: string]: unknown
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
const { styleDefinition, as, class: className, children, ...props }: Props = $props()
|
|
19
|
+
|
|
20
|
+
const sheet = getStyleSheet()
|
|
21
|
+
const theme = getTheme()
|
|
22
|
+
|
|
23
|
+
const styleClassName = $derived(insert(sheet, styleDefinition, { ...props, theme: theme?.() ?? ({} as DefaultTheme) }))
|
|
24
|
+
|
|
25
|
+
const classes = $derived(clsx(styleClassName, styleDefinition.id, className))
|
|
26
|
+
|
|
27
|
+
const attributes = $derived(Object.fromEntries(Object.entries(props).filter(([key]) => key[0] !== '_')))
|
|
28
|
+
</script>
|
|
29
|
+
|
|
30
|
+
{#if styleClassName && styleDefinition.tag}
|
|
31
|
+
{@const Target = as ?? styleDefinition.tag}
|
|
32
|
+
{#if typeof Target === 'function'}
|
|
33
|
+
<Target class={classes} {...attributes} {children} />
|
|
34
|
+
{:else if children}
|
|
35
|
+
<svelte:element this={Target} class={classes} {...attributes}>{@render children()}</svelte:element>
|
|
36
|
+
{:else}
|
|
37
|
+
<svelte:element this={Target} class={classes} {...attributes} />
|
|
38
|
+
{/if}
|
|
39
|
+
{/if}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { HTMLElements, StyleDefinition } from '@teiler/core';
|
|
2
|
+
import type { Component, Snippet } from 'svelte';
|
|
3
|
+
type Props = {
|
|
4
|
+
styleDefinition: StyleDefinition<HTMLElements, unknown>;
|
|
5
|
+
as?: Exclude<HTMLElements, null> | Component<any>;
|
|
6
|
+
class?: string;
|
|
7
|
+
children?: Snippet;
|
|
8
|
+
[key: string]: unknown;
|
|
9
|
+
};
|
|
10
|
+
declare const Styled: Component<Props, {}, "">;
|
|
11
|
+
type Styled = ReturnType<typeof Styled>;
|
|
12
|
+
export default Styled;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import type { DefaultTheme } from '@teiler/core'
|
|
3
|
+
import type { Snippet } from 'svelte'
|
|
4
|
+
|
|
5
|
+
import { setTheme } from './theme.js'
|
|
6
|
+
|
|
7
|
+
const { theme, children }: { theme: DefaultTheme; children?: Snippet } = $props()
|
|
8
|
+
|
|
9
|
+
setTheme(() => theme)
|
|
10
|
+
</script>
|
|
11
|
+
|
|
12
|
+
{@render children?.()}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { DefaultTheme } from '@teiler/core';
|
|
2
|
+
import type { Snippet } from 'svelte';
|
|
3
|
+
type $$ComponentProps = {
|
|
4
|
+
theme: DefaultTheme;
|
|
5
|
+
children?: Snippet;
|
|
6
|
+
};
|
|
7
|
+
declare const ThemeProvider: import("svelte").Component<$$ComponentProps, {}, "">;
|
|
8
|
+
type ThemeProvider = ReturnType<typeof ThemeProvider>;
|
|
9
|
+
export default ThemeProvider;
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import type { HTMLElements, Properties, StyleDefinition, TeilerComponent } from '@teiler/core';
|
|
2
|
+
import type { ComponentConstructorOptions, ComponentInternals, Snippet, Component as SvelteComponent, SvelteComponent as SvelteComponentInstance } from 'svelte';
|
|
3
|
+
import type { ClassValue, SvelteHTMLElements } from 'svelte/elements';
|
|
4
|
+
import { keyframes } from '@teiler/core';
|
|
5
|
+
type Tag = Exclude<HTMLElements, null>;
|
|
6
|
+
type ElementProps<Target> = Target extends keyof SvelteHTMLElements ? SvelteHTMLElements[Target] : {};
|
|
7
|
+
type AsTarget = Tag | SvelteComponent<never>;
|
|
8
|
+
type TargetProps<As> = As extends SvelteComponent<infer Props> ? Omit<Props, 'class' | 'children'> & {
|
|
9
|
+
class?: ClassValue;
|
|
10
|
+
children?: Snippet;
|
|
11
|
+
} : ElementProps<As>;
|
|
12
|
+
type PolymorphicProps<Target extends HTMLElements, Props, As> = Props & {
|
|
13
|
+
as?: As;
|
|
14
|
+
} & ([As] extends [never] ? ElementProps<Target> : [AsTarget] extends [As] ? ElementProps<Target> : TargetProps<As>);
|
|
15
|
+
interface SvelteTeilerComponent<Target extends HTMLElements, Props extends object> extends TeilerComponent<Target, Props> {
|
|
16
|
+
<As extends AsTarget = never>(internals: ComponentInternals, props: PolymorphicProps<Target, Props, As>): {};
|
|
17
|
+
new <As extends AsTarget = never>(options: ComponentConstructorOptions<PolymorphicProps<Target, Props, As>>): SvelteComponentInstance<PolymorphicProps<Target, Props, As>>;
|
|
18
|
+
}
|
|
19
|
+
type SvelteGlobalComponent<Props extends object> = TeilerComponent<null, Props> & SvelteComponent<Props>;
|
|
20
|
+
declare const createComponent: <Target extends HTMLElements, Props extends object = {}>(styleDefinition: StyleDefinition<Target, Props>) => SvelteTeilerComponent<Target, Props>;
|
|
21
|
+
type InferProps<Component, Props> = Component extends TeilerComponent<HTMLElements, infer P> ? P & Props : Props;
|
|
22
|
+
type InferComponent<Component, Props extends object, Extended> = Component extends TeilerComponent<infer E, infer P extends object> ? SvelteTeilerComponent<Extended extends HTMLElements ? Extended : E, Props & P> : SvelteTeilerComponent<HTMLElements, Props>;
|
|
23
|
+
type Component<Target extends HTMLElements, Extended extends HTMLElements | undefined = Target> = {
|
|
24
|
+
<Props extends object = {}>(string: TemplateStringsArray, ...properties: Properties<Props>[]): SvelteTeilerComponent<Target, Props>;
|
|
25
|
+
<Component>(binded: Component): <Props extends object = {}>(string: TemplateStringsArray, ...properties: Properties<InferProps<Component, Props>>[]) => InferComponent<Component, Props, Extended>;
|
|
26
|
+
};
|
|
27
|
+
type Global = {
|
|
28
|
+
<Props extends object = {}>(string: TemplateStringsArray, ...properties: Properties<Props>[]): SvelteGlobalComponent<Props>;
|
|
29
|
+
};
|
|
30
|
+
type ComponentWithTags = Component<'div', undefined> & {
|
|
31
|
+
[K in Exclude<HTMLElements, null>]: Component<K>;
|
|
32
|
+
};
|
|
33
|
+
declare const svelteComponent: ComponentWithTags;
|
|
34
|
+
declare const svelteGlobal: Global;
|
|
35
|
+
export type { SvelteGlobalComponent, SvelteTeilerComponent };
|
|
36
|
+
export { svelteComponent as component, svelteGlobal as global, keyframes, createComponent };
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { component, global, keyframes, styled, tags } from '@teiler/core';
|
|
2
|
+
import Styled from './Styled.svelte';
|
|
3
|
+
const withStyleDefinition = (props, styleDefinition) => {
|
|
4
|
+
return new Proxy(props, {
|
|
5
|
+
get: (target, key) => (key === 'styleDefinition' ? styleDefinition : Reflect.get(target, key)),
|
|
6
|
+
has: (target, key) => key === 'styleDefinition' || Reflect.has(target, key),
|
|
7
|
+
});
|
|
8
|
+
};
|
|
9
|
+
const createComponent = (styleDefinition) => {
|
|
10
|
+
const wrapped = (internals, props) => Styled(internals, withStyleDefinition(props, styleDefinition));
|
|
11
|
+
return Object.assign(wrapped, { styleDefinition });
|
|
12
|
+
};
|
|
13
|
+
const construct = (tag, compiler) => {
|
|
14
|
+
return (stringOrBinded, ...properties) => {
|
|
15
|
+
return styled(tag, compiler, createComponent, stringOrBinded, ...properties);
|
|
16
|
+
};
|
|
17
|
+
};
|
|
18
|
+
const svelteComponent = construct(undefined, component);
|
|
19
|
+
tags.forEach((tag) => {
|
|
20
|
+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
21
|
+
// @ts-expect-error
|
|
22
|
+
svelteComponent[tag] = construct(tag, component);
|
|
23
|
+
});
|
|
24
|
+
const svelteGlobal = construct(null, global);
|
|
25
|
+
export { svelteComponent as component, svelteGlobal as global, keyframes, createComponent };
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export { component, global, keyframes, createComponent } from './component'
|
|
2
|
-
export { default as ThemeProvider } from './ThemeProvider.svelte'
|
|
1
|
+
export { component, global, keyframes, createComponent } from './component.js';
|
|
2
|
+
export { default as ThemeProvider } from './ThemeProvider.svelte';
|
package/dist/index.js
ADDED
package/dist/sheet.d.ts
ADDED
package/dist/sheet.js
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { createStyleSheet } from '@teiler/core';
|
|
2
|
+
import { getContext } from 'svelte';
|
|
3
|
+
export let styleSheet = null;
|
|
4
|
+
export const StyleSheet = 'STYLE_SHEET';
|
|
5
|
+
export function getStyleSheet() {
|
|
6
|
+
const fromContext = getContext(StyleSheet);
|
|
7
|
+
if (fromContext) {
|
|
8
|
+
return fromContext;
|
|
9
|
+
}
|
|
10
|
+
if (styleSheet === null) {
|
|
11
|
+
styleSheet = createStyleSheet({});
|
|
12
|
+
}
|
|
13
|
+
return styleSheet;
|
|
14
|
+
}
|
package/dist/theme.d.ts
ADDED
package/dist/theme.js
ADDED
package/package.json
CHANGED
|
@@ -1,63 +1,61 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@teiler/svelte",
|
|
3
|
-
"version": "0.0
|
|
3
|
+
"version": "0.1.0",
|
|
4
4
|
"repository": {
|
|
5
|
-
"
|
|
5
|
+
"type": "git",
|
|
6
|
+
"url": "git+https://github.com/nerdslabs/teiler.git",
|
|
6
7
|
"directory": "packages/svelte"
|
|
7
8
|
},
|
|
8
9
|
"homepage": "https://github.com/nerdslabs/teiler/tree/master/packages/svelte#readme",
|
|
9
10
|
"type": "module",
|
|
10
|
-
"
|
|
11
|
-
"
|
|
12
|
-
"types": "./dist/teiler-svelte.d.ts",
|
|
11
|
+
"svelte": "./dist/index.js",
|
|
12
|
+
"types": "./dist/index.d.ts",
|
|
13
13
|
"exports": {
|
|
14
14
|
".": {
|
|
15
|
-
"
|
|
16
|
-
"
|
|
17
|
-
"
|
|
15
|
+
"types": "./dist/index.d.ts",
|
|
16
|
+
"svelte": "./dist/index.js",
|
|
17
|
+
"default": "./dist/index.js"
|
|
18
18
|
}
|
|
19
19
|
},
|
|
20
|
-
"
|
|
21
|
-
"
|
|
22
|
-
"
|
|
23
|
-
"
|
|
24
|
-
|
|
25
|
-
"storybook-test": "test-storybook --url http://localhost:6006",
|
|
26
|
-
"build-storybook": "storybook build"
|
|
27
|
-
},
|
|
20
|
+
"files": [
|
|
21
|
+
"dist",
|
|
22
|
+
"!dist/**/*.test.*",
|
|
23
|
+
"!dist/**/*.fixture.*"
|
|
24
|
+
],
|
|
28
25
|
"dependencies": {
|
|
29
|
-
"@teiler/core": "0.0
|
|
30
|
-
"
|
|
26
|
+
"@teiler/core": "0.1.0",
|
|
27
|
+
"clsx": "^2.1.1"
|
|
28
|
+
},
|
|
29
|
+
"peerDependencies": {
|
|
30
|
+
"svelte": "^5.16.0"
|
|
31
31
|
},
|
|
32
32
|
"devDependencies": {
|
|
33
|
-
"@chromatic-com/storybook": "^3.
|
|
34
|
-
"@
|
|
35
|
-
"@
|
|
36
|
-
"@
|
|
37
|
-
"@
|
|
38
|
-
"@
|
|
39
|
-
"@
|
|
40
|
-
"@
|
|
41
|
-
"@
|
|
42
|
-
"@
|
|
43
|
-
"
|
|
44
|
-
"
|
|
45
|
-
"
|
|
46
|
-
"
|
|
47
|
-
"
|
|
48
|
-
"
|
|
49
|
-
"
|
|
50
|
-
"
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
"
|
|
54
|
-
"
|
|
55
|
-
"
|
|
56
|
-
"
|
|
57
|
-
"storybook": "
|
|
58
|
-
"
|
|
59
|
-
"
|
|
60
|
-
"svelte-preprocess": "^5.1.4",
|
|
61
|
-
"typescript": "^5.8.3"
|
|
33
|
+
"@chromatic-com/storybook": "^5.3.1",
|
|
34
|
+
"@storybook/addon-links": "^10.6.0",
|
|
35
|
+
"@storybook/addon-vitest": "^10.6.0",
|
|
36
|
+
"@storybook/svelte": "^10.6.0",
|
|
37
|
+
"@storybook/svelte-vite": "^10.6.0",
|
|
38
|
+
"@sveltejs/package": "^2.5.8",
|
|
39
|
+
"@sveltejs/vite-plugin-svelte": "^7.3.1",
|
|
40
|
+
"@testing-library/svelte": "^5.4.2",
|
|
41
|
+
"@vitest/browser-playwright": "^4.1.11",
|
|
42
|
+
"@vitest/coverage-v8": "^4.1.11",
|
|
43
|
+
"jsdom": "^30.1.1",
|
|
44
|
+
"playwright": "^1.63.0",
|
|
45
|
+
"storybook": "^10.6.0",
|
|
46
|
+
"svelte": "^5.57.1",
|
|
47
|
+
"svelte-check": "^4.7.6",
|
|
48
|
+
"typescript": "^6.0.3",
|
|
49
|
+
"vite": "^8.3.1",
|
|
50
|
+
"vitest": "^4.1.11"
|
|
51
|
+
},
|
|
52
|
+
"scripts": {
|
|
53
|
+
"build": "svelte-package -i src -o dist",
|
|
54
|
+
"dev": "svelte-package -i src -o dist --watch",
|
|
55
|
+
"test": "vitest run --project client --project server",
|
|
56
|
+
"typecheck": "node scripts/typecheck.js",
|
|
57
|
+
"storybook": "storybook dev -p 6006 --no-open",
|
|
58
|
+
"storybook-test": "vitest run --project storybook",
|
|
59
|
+
"build-storybook": "storybook build"
|
|
62
60
|
}
|
|
63
|
-
}
|
|
61
|
+
}
|