@tempots/dom 26.11.0 → 28.0.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/dom/browser-context.d.ts +101 -11
- package/dom/dom-context.d.ts +1 -1
- package/index.cjs +1 -1
- package/index.js +619 -474
- package/package.json +1 -1
- package/renderable/ensure.d.ts +72 -9
- package/renderable/foreach.d.ts +56 -6
- package/renderable/not-empty.d.ts +1 -1
- package/renderable/on.d.ts +168 -10
- package/renderable/provider.d.ts +181 -11
- package/renderable/repeat.d.ts +63 -5
- package/renderable/style.d.ts +5 -0
- package/std/signal.d.ts +117 -15
- package/types/domain.d.ts +103 -5
package/renderable/style.d.ts
CHANGED
|
@@ -101,6 +101,7 @@ export declare const style: {
|
|
|
101
101
|
borderTopWidth: (value: NValue<string>) => Renderable;
|
|
102
102
|
borderWidth: (value: NValue<string>) => Renderable;
|
|
103
103
|
bottom: (value: NValue<string>) => Renderable;
|
|
104
|
+
boxDecorationBreak: (value: NValue<string>) => Renderable;
|
|
104
105
|
boxShadow: (value: NValue<string>) => Renderable;
|
|
105
106
|
boxSizing: (value: NValue<string>) => Renderable;
|
|
106
107
|
breakAfter: (value: NValue<string>) => Renderable;
|
|
@@ -379,6 +380,9 @@ export declare const style: {
|
|
|
379
380
|
textAlign: (value: NValue<string>) => Renderable;
|
|
380
381
|
textAlignLast: (value: NValue<string>) => Renderable;
|
|
381
382
|
textAnchor: (value: NValue<string>) => Renderable;
|
|
383
|
+
textBox: (value: NValue<string>) => Renderable;
|
|
384
|
+
textBoxEdge: (value: NValue<string>) => Renderable;
|
|
385
|
+
textBoxTrim: (value: NValue<string>) => Renderable;
|
|
382
386
|
textCombineUpright: (value: NValue<string>) => Renderable;
|
|
383
387
|
textDecoration: (value: NValue<string>) => Renderable;
|
|
384
388
|
textDecorationColor: (value: NValue<string>) => Renderable;
|
|
@@ -418,6 +422,7 @@ export declare const style: {
|
|
|
418
422
|
userSelect: (value: NValue<string>) => Renderable;
|
|
419
423
|
vectorEffect: (value: NValue<string>) => Renderable;
|
|
420
424
|
verticalAlign: (value: NValue<string>) => Renderable;
|
|
425
|
+
viewTransitionClass: (value: NValue<string>) => Renderable;
|
|
421
426
|
viewTransitionName: (value: NValue<string>) => Renderable;
|
|
422
427
|
visibility: (value: NValue<string>) => Renderable;
|
|
423
428
|
webkitAlignContent: (value: NValue<string>) => Renderable;
|
package/std/signal.d.ts
CHANGED
|
@@ -20,21 +20,82 @@ export type ListenerOptions = {
|
|
|
20
20
|
abortSignal?: AbortSignal;
|
|
21
21
|
};
|
|
22
22
|
/**
|
|
23
|
-
*
|
|
24
|
-
*
|
|
23
|
+
* A reactive signal that holds a value and notifies listeners when the value changes.
|
|
24
|
+
*
|
|
25
|
+
* Signals are the foundation of Tempo's reactive system. They provide a way to create
|
|
26
|
+
* reactive data that automatically updates the UI when changed. Signals can be observed,
|
|
27
|
+
* transformed, and composed to create complex reactive behaviors.
|
|
28
|
+
*
|
|
29
|
+
* @example
|
|
30
|
+
* ```typescript
|
|
31
|
+
* // Create a signal with an initial value
|
|
32
|
+
* const count = new Signal(0, (a, b) => a === b)
|
|
33
|
+
*
|
|
34
|
+
* // Listen to changes
|
|
35
|
+
* const unsubscribe = count.on((newValue, oldValue) => {
|
|
36
|
+
* console.log(`Count changed from ${oldValue} to ${newValue}`)
|
|
37
|
+
* })
|
|
38
|
+
*
|
|
39
|
+
* // Transform the signal
|
|
40
|
+
* const doubled = count.map(n => n * 2)
|
|
41
|
+
* const isEven = count.map(n => n % 2 === 0)
|
|
42
|
+
* ```
|
|
43
|
+
*
|
|
44
|
+
* @example
|
|
45
|
+
* ```typescript
|
|
46
|
+
* // Create a signal from a Promise
|
|
47
|
+
* const userSignal = Signal.ofPromise(
|
|
48
|
+
* fetch('/api/user').then(r => r.json()),
|
|
49
|
+
* null, // initial value
|
|
50
|
+
* error => ({ error: error.message }) // error recovery
|
|
51
|
+
* )
|
|
52
|
+
* ```
|
|
53
|
+
*
|
|
54
|
+
* @typeParam T - The type of the value held by the signal
|
|
25
55
|
* @public
|
|
26
56
|
*/
|
|
27
57
|
export declare class Signal<T> {
|
|
28
58
|
readonly equals: (a: T, b: T) => boolean;
|
|
29
59
|
/**
|
|
30
|
-
* Creates a Signal that holds the result of a Promise.
|
|
60
|
+
* Creates a Signal that holds the result of a Promise, with proper error handling.
|
|
61
|
+
*
|
|
62
|
+
* This static method creates a signal that starts with an initial value and updates
|
|
63
|
+
* when the promise resolves. If the promise rejects, an optional recovery function
|
|
64
|
+
* can provide a fallback value.
|
|
65
|
+
*
|
|
66
|
+
* @example
|
|
67
|
+
* ```typescript
|
|
68
|
+
* // Basic usage with API call
|
|
69
|
+
* const userData = Signal.ofPromise(
|
|
70
|
+
* fetch('/api/user').then(r => r.json()),
|
|
71
|
+
* { loading: true }, // initial state
|
|
72
|
+
* error => ({ error: error.message, loading: false }) // error recovery
|
|
73
|
+
* )
|
|
74
|
+
*
|
|
75
|
+
* // Use in UI
|
|
76
|
+
* Ensure(userData,
|
|
77
|
+
* (user) => html.div('Welcome, ', user.map(u => u.name)),
|
|
78
|
+
* () => html.div('Loading...')
|
|
79
|
+
* )
|
|
80
|
+
* ```
|
|
31
81
|
*
|
|
32
|
-
* @
|
|
33
|
-
*
|
|
34
|
-
*
|
|
35
|
-
*
|
|
36
|
-
*
|
|
37
|
-
*
|
|
82
|
+
* @example
|
|
83
|
+
* ```typescript
|
|
84
|
+
* // With custom equality function
|
|
85
|
+
* const config = Signal.ofPromise(
|
|
86
|
+
* loadConfig(),
|
|
87
|
+
* {},
|
|
88
|
+
* () => ({}),
|
|
89
|
+
* (a, b) => JSON.stringify(a) === JSON.stringify(b) // deep equality
|
|
90
|
+
* )
|
|
91
|
+
* ```
|
|
92
|
+
*
|
|
93
|
+
* @typeParam O - The type of the value returned by the Promise
|
|
94
|
+
* @param promise - The Promise to use to feed the Signal
|
|
95
|
+
* @param init - The initial value of the Signal before the Promise resolves
|
|
96
|
+
* @param recover - Optional function to recover from Promise rejection and provide an alternative value
|
|
97
|
+
* @param equals - Function to compare two values for equality (defaults to strict equality)
|
|
98
|
+
* @returns A Signal that represents the result of the Promise
|
|
38
99
|
*/
|
|
39
100
|
static readonly ofPromise: <O>(promise: Promise<O>, init: O, recover?: (error: unknown) => O, equals?: (a: O, b: O) => boolean) => Signal<O>;
|
|
40
101
|
/**
|
|
@@ -120,13 +181,54 @@ export declare class Signal<T> {
|
|
|
120
181
|
*/
|
|
121
182
|
readonly dispose: () => void;
|
|
122
183
|
/**
|
|
123
|
-
*
|
|
124
|
-
* The mapping function is called whenever the value of this Signal changes.
|
|
184
|
+
* Creates a new computed signal by applying a transformation function to this signal's value.
|
|
125
185
|
*
|
|
126
|
-
*
|
|
127
|
-
*
|
|
128
|
-
*
|
|
129
|
-
*
|
|
186
|
+
* The `map` method is one of the most commonly used signal operations. It creates a new
|
|
187
|
+
* computed signal that automatically updates whenever the source signal changes. The
|
|
188
|
+
* transformation function is called with the current value and should return the new value.
|
|
189
|
+
*
|
|
190
|
+
* @example
|
|
191
|
+
* ```typescript
|
|
192
|
+
* const count = prop(5)
|
|
193
|
+
*
|
|
194
|
+
* // Transform to different types
|
|
195
|
+
* const doubled = count.map(n => n * 2)
|
|
196
|
+
* const message = count.map(n => `Count is ${n}`)
|
|
197
|
+
* const isEven = count.map(n => n % 2 === 0)
|
|
198
|
+
*
|
|
199
|
+
* // Use in UI
|
|
200
|
+
* html.div(
|
|
201
|
+
* html.div('Original: ', count.map(String)),
|
|
202
|
+
* html.div('Doubled: ', doubled.map(String)),
|
|
203
|
+
* html.div('Message: ', message),
|
|
204
|
+
* html.div('Is even: ', isEven.map(String))
|
|
205
|
+
* )
|
|
206
|
+
* ```
|
|
207
|
+
*
|
|
208
|
+
* @example
|
|
209
|
+
* ```typescript
|
|
210
|
+
* // Chain multiple transformations
|
|
211
|
+
* const user = prop({ name: 'John', age: 30 })
|
|
212
|
+
* const greeting = user
|
|
213
|
+
* .map(u => u.name)
|
|
214
|
+
* .map(name => name.toUpperCase())
|
|
215
|
+
* .map(name => `Hello, ${name}!`)
|
|
216
|
+
* ```
|
|
217
|
+
*
|
|
218
|
+
* @example
|
|
219
|
+
* ```typescript
|
|
220
|
+
* // With custom equality function for objects
|
|
221
|
+
* const items = prop([{ id: 1, name: 'Item 1' }])
|
|
222
|
+
* const itemNames = items.map(
|
|
223
|
+
* items => items.map(item => item.name),
|
|
224
|
+
* (a, b) => JSON.stringify(a) === JSON.stringify(b) // deep equality
|
|
225
|
+
* )
|
|
226
|
+
* ```
|
|
227
|
+
*
|
|
228
|
+
* @typeParam O - The type of the transformed value
|
|
229
|
+
* @param fn - Function that transforms the signal's value to a new value
|
|
230
|
+
* @param equals - Optional function to determine if two transformed values are equal (defaults to strict equality)
|
|
231
|
+
* @returns A new computed signal with the transformed value
|
|
130
232
|
*/
|
|
131
233
|
readonly map: <O>(fn: (value: T) => O, equals?: (a: O, b: O) => boolean) => Computed<O>;
|
|
132
234
|
/**
|
package/types/domain.d.ts
CHANGED
|
@@ -1,15 +1,113 @@
|
|
|
1
1
|
import { DOMContext } from '../dom/dom-context';
|
|
2
2
|
import { Value } from '../std/value';
|
|
3
3
|
/**
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
4
|
+
* A function that renders content into the DOM and returns a cleanup function.
|
|
5
|
+
*
|
|
6
|
+
* Renderables are the fundamental building blocks of Tempo applications. They receive
|
|
7
|
+
* a DOMContext and use it to create DOM elements, text nodes, or other content.
|
|
8
|
+
* The returned Clear function is called when the renderable needs to be removed
|
|
9
|
+
* from the DOM.
|
|
10
|
+
*
|
|
11
|
+
* @example
|
|
12
|
+
* ```typescript
|
|
13
|
+
* // Simple renderable that creates a div
|
|
14
|
+
* const MyComponent: Renderable = (ctx) => {
|
|
15
|
+
* const divCtx = ctx.makeChildElement('div', undefined)
|
|
16
|
+
* divCtx.makeChildText('Hello, World!')
|
|
17
|
+
*
|
|
18
|
+
* // Return cleanup function
|
|
19
|
+
* return (removeTree) => {
|
|
20
|
+
* if (removeTree) {
|
|
21
|
+
* // Cleanup logic here
|
|
22
|
+
* }
|
|
23
|
+
* }
|
|
24
|
+
* }
|
|
25
|
+
* ```
|
|
26
|
+
*
|
|
27
|
+
* @example
|
|
28
|
+
* ```typescript
|
|
29
|
+
* // Renderable with event listeners
|
|
30
|
+
* const Button: Renderable = (ctx) => {
|
|
31
|
+
* const buttonCtx = ctx.makeChildElement('button', undefined)
|
|
32
|
+
* buttonCtx.makeChildText('Click me')
|
|
33
|
+
*
|
|
34
|
+
* const clearClick = buttonCtx.on('click', () => {
|
|
35
|
+
* console.log('Button clicked!')
|
|
36
|
+
* })
|
|
37
|
+
*
|
|
38
|
+
* return (removeTree) => {
|
|
39
|
+
* clearClick(removeTree)
|
|
40
|
+
* }
|
|
41
|
+
* }
|
|
42
|
+
* ```
|
|
43
|
+
*
|
|
44
|
+
* @template CTX - The type of DOMContext (defaults to DOMContext)
|
|
45
|
+
* @param ctx - The DOM context for rendering
|
|
46
|
+
* @returns A cleanup function that removes the rendered content when called
|
|
7
47
|
* @public
|
|
8
48
|
*/
|
|
9
49
|
export type Renderable<CTX extends DOMContext = DOMContext> = (ctx: CTX) => Clear;
|
|
10
50
|
/**
|
|
11
|
-
*
|
|
12
|
-
*
|
|
51
|
+
* A flexible type representing any content that can be rendered in Tempo.
|
|
52
|
+
*
|
|
53
|
+
* TNode (Template Node) is the union type that encompasses all possible content
|
|
54
|
+
* that can be rendered in a Tempo application. This includes components, text,
|
|
55
|
+
* signals, arrays of content, and null/undefined values for conditional rendering.
|
|
56
|
+
*
|
|
57
|
+
* @example
|
|
58
|
+
* ```typescript
|
|
59
|
+
* // All of these are valid TNode values:
|
|
60
|
+
*
|
|
61
|
+
* // Renderable component
|
|
62
|
+
* const component: TNode = MyComponent()
|
|
63
|
+
*
|
|
64
|
+
* // Static text
|
|
65
|
+
* const text: TNode = 'Hello, World!'
|
|
66
|
+
*
|
|
67
|
+
* // Signal text
|
|
68
|
+
* const dynamicText: TNode = userNameSignal
|
|
69
|
+
*
|
|
70
|
+
* // Array of content
|
|
71
|
+
* const list: TNode = [
|
|
72
|
+
* html.div('Item 1'),
|
|
73
|
+
* html.div('Item 2'),
|
|
74
|
+
* html.div('Item 3')
|
|
75
|
+
* ]
|
|
76
|
+
*
|
|
77
|
+
* // Conditional content
|
|
78
|
+
* const conditional: TNode = isVisible.value ? html.div('Visible') : null
|
|
79
|
+
* ```
|
|
80
|
+
*
|
|
81
|
+
* @example
|
|
82
|
+
* ```typescript
|
|
83
|
+
* // Function that accepts any renderable content
|
|
84
|
+
* function Container(children: TNode): Renderable {
|
|
85
|
+
* return html.div(
|
|
86
|
+
* attr.class('container'),
|
|
87
|
+
* children // Can be any TNode type
|
|
88
|
+
* )
|
|
89
|
+
* }
|
|
90
|
+
*
|
|
91
|
+
* // Usage with different TNode types
|
|
92
|
+
* Container('Simple text')
|
|
93
|
+
* Container(MyComponent())
|
|
94
|
+
* Container([html.p('Paragraph 1'), html.p('Paragraph 2')])
|
|
95
|
+
* Container(isLoading.value ? 'Loading...' : null)
|
|
96
|
+
* ```
|
|
97
|
+
*
|
|
98
|
+
* @example
|
|
99
|
+
* ```typescript
|
|
100
|
+
* // Building complex content with TNode
|
|
101
|
+
* const buildContent = (items: string[]): TNode => {
|
|
102
|
+
* if (items.length === 0) {
|
|
103
|
+
* return html.div('No items found')
|
|
104
|
+
* }
|
|
105
|
+
*
|
|
106
|
+
* return items.map(item => html.div(item))
|
|
107
|
+
* }
|
|
108
|
+
* ```
|
|
109
|
+
*
|
|
110
|
+
* @template CTX - The type of DOMContext (defaults to DOMContext)
|
|
13
111
|
* @public
|
|
14
112
|
*/
|
|
15
113
|
export type TNode<CTX extends DOMContext = DOMContext> = Renderable<CTX> | Value<string> | undefined | null | Renderable<CTX>[];
|