fiboui 1.0.0 → 1.0.1
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/README.md +144 -73
- package/dist/core/StateWrapper.d.ts +3 -0
- package/dist/core/builder.d.ts +4 -1
- package/dist/core/effects.d.ts +4 -3
- package/dist/core/hooks.d.ts +5 -0
- package/dist/core/index.d.ts +1 -0
- package/dist/core/state.d.ts +76 -27
- package/dist/effects-D16XdB_d.mjs +10 -0
- package/dist/index.esm.js +1181 -1026
- package/dist/index.umd.js +4 -4
- package/dist/interactive/TextField/index.d.ts +3 -2
- package/dist/style.css +1 -1
- package/package.json +1 -1
- package/src/core/StateWrapper.tsx +28 -2
- package/src/core/builder.ts +48 -10
- package/src/core/effects.ts +3 -3
- package/src/core/hooks.ts +48 -0
- package/src/core/index.ts +1 -0
- package/src/core/state.ts +203 -139
- package/src/demo.tsx +5 -0
- package/src/interactive/Button/index.ts +2 -1
- package/src/interactive/TextField/index.ts +29 -6
- package/src/structure/Box/index.ts +3 -2
- package/dist/effects-Co9C_Dyx.mjs +0 -9
- package/dist/examples/ScaffoldExamples.d.ts +0 -3
- package/dist/examples/StateExamples.d.ts +0 -5
- package/src/examples/ScaffoldExamples.tsx +0 -299
- package/src/examples/StateExamples.tsx +0 -149
package/src/core/state.ts
CHANGED
|
@@ -1,233 +1,297 @@
|
|
|
1
|
+
export type Listener<T> = (value: T) => void;
|
|
2
|
+
export type Unsubscribe = () => void;
|
|
1
3
|
|
|
4
|
+
// --- Dependency Tracking System ---
|
|
2
5
|
|
|
6
|
+
let activeEffect: Effect | null = null;
|
|
3
7
|
|
|
8
|
+
export interface Subscribable<T> {
|
|
9
|
+
subscribe(listener: Listener<T>): Unsubscribe;
|
|
10
|
+
subscribeEffect(effect: Effect): void;
|
|
11
|
+
unsubscribeEffect(effect: Effect): void;
|
|
12
|
+
}
|
|
4
13
|
|
|
14
|
+
export class Effect {
|
|
15
|
+
private dependencies = new Set<Subscribable<any>>();
|
|
16
|
+
private _onDispose?: () => void;
|
|
5
17
|
|
|
18
|
+
constructor(private fn: () => void) {
|
|
19
|
+
this.run();
|
|
20
|
+
}
|
|
6
21
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
22
|
+
run() {
|
|
23
|
+
const prevEffect = activeEffect;
|
|
24
|
+
activeEffect = this;
|
|
25
|
+
try {
|
|
26
|
+
this.cleanup();
|
|
27
|
+
this.fn();
|
|
28
|
+
} finally {
|
|
29
|
+
activeEffect = prevEffect;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
12
32
|
|
|
33
|
+
track(dep: Subscribable<any>) {
|
|
34
|
+
this.dependencies.add(dep);
|
|
35
|
+
dep.subscribeEffect(this);
|
|
36
|
+
}
|
|
13
37
|
|
|
38
|
+
trigger() {
|
|
39
|
+
this.run();
|
|
40
|
+
}
|
|
14
41
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
}
|
|
42
|
+
cleanup() {
|
|
43
|
+
this.dependencies.forEach(dep => dep.unsubscribeEffect(this));
|
|
44
|
+
this.dependencies.clear();
|
|
45
|
+
}
|
|
19
46
|
|
|
20
|
-
|
|
21
|
-
|
|
47
|
+
dispose() {
|
|
48
|
+
this.cleanup();
|
|
49
|
+
this._onDispose?.();
|
|
50
|
+
}
|
|
22
51
|
}
|
|
23
52
|
|
|
24
|
-
|
|
25
|
-
|
|
53
|
+
export class Tracker {
|
|
54
|
+
private dependencies = new Set<Subscribable<any>>();
|
|
26
55
|
|
|
27
|
-
|
|
28
|
-
private _value: T;
|
|
29
|
-
private subscribers = new Set<(value: T) => void>();
|
|
56
|
+
constructor(private _onInvalidate: () => void) {}
|
|
30
57
|
|
|
31
|
-
|
|
32
|
-
|
|
58
|
+
execute<T>(fn: () => T): T {
|
|
59
|
+
const prevEffect = activeEffect;
|
|
60
|
+
activeEffect = this as any; // Cast because implementation matches behavior we need
|
|
61
|
+
|
|
62
|
+
try {
|
|
63
|
+
this.cleanup();
|
|
64
|
+
return fn();
|
|
65
|
+
} finally {
|
|
66
|
+
activeEffect = prevEffect;
|
|
67
|
+
}
|
|
33
68
|
}
|
|
34
69
|
|
|
35
|
-
|
|
36
|
-
|
|
70
|
+
// Called by Signals when they are accessed
|
|
71
|
+
track(dep: Subscribable<any>) {
|
|
72
|
+
this.dependencies.add(dep);
|
|
73
|
+
dep.subscribeEffect(this as any);
|
|
37
74
|
}
|
|
38
75
|
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
this.notify();
|
|
43
|
-
}
|
|
76
|
+
// Called by Signals when they change
|
|
77
|
+
trigger() {
|
|
78
|
+
this._onInvalidate();
|
|
44
79
|
}
|
|
45
80
|
|
|
46
|
-
|
|
47
|
-
this.
|
|
48
|
-
|
|
81
|
+
cleanup() {
|
|
82
|
+
this.dependencies.forEach(dep => dep.unsubscribeEffect(this as any));
|
|
83
|
+
this.dependencies.clear();
|
|
49
84
|
}
|
|
50
85
|
|
|
51
|
-
|
|
52
|
-
this.
|
|
86
|
+
dispose() {
|
|
87
|
+
this.cleanup();
|
|
53
88
|
}
|
|
54
89
|
}
|
|
55
90
|
|
|
91
|
+
// --- Signals ---
|
|
56
92
|
|
|
57
|
-
class
|
|
58
|
-
private
|
|
59
|
-
private
|
|
60
|
-
private dependencies = new Set<Signal<any>>();
|
|
61
|
-
private unsubscribers: (() => void)[] = [];
|
|
93
|
+
export class Signal<T> implements Subscribable<T> {
|
|
94
|
+
private listeners = new Set<Listener<T>>();
|
|
95
|
+
private effects = new Set<Effect>();
|
|
62
96
|
|
|
63
|
-
constructor(private
|
|
64
|
-
this._value = this.recompute();
|
|
65
|
-
}
|
|
97
|
+
constructor(private _value: T) {}
|
|
66
98
|
|
|
67
99
|
get value(): T {
|
|
100
|
+
if (activeEffect) {
|
|
101
|
+
activeEffect.track(this);
|
|
102
|
+
}
|
|
68
103
|
return this._value;
|
|
69
104
|
}
|
|
70
105
|
|
|
71
|
-
|
|
72
|
-
this.subscribers.add(callback);
|
|
73
|
-
return () => this.subscribers.delete(callback);
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
private recompute(): T {
|
|
77
|
-
|
|
78
|
-
this.unsubscribers.forEach(unsub => unsub());
|
|
79
|
-
this.unsubscribers = [];
|
|
80
|
-
this.dependencies.clear();
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
const newValue = this.compute();
|
|
84
|
-
|
|
106
|
+
set value(newValue: T) {
|
|
85
107
|
if (this._value !== newValue) {
|
|
86
108
|
this._value = newValue;
|
|
87
109
|
this.notify();
|
|
88
110
|
}
|
|
111
|
+
}
|
|
89
112
|
|
|
90
|
-
|
|
113
|
+
subscribe(listener: Listener<T>): Unsubscribe {
|
|
114
|
+
this.listeners.add(listener);
|
|
115
|
+
return () => this.listeners.delete(listener);
|
|
91
116
|
}
|
|
92
117
|
|
|
93
|
-
|
|
94
|
-
this.
|
|
118
|
+
subscribeEffect(effect: Effect) {
|
|
119
|
+
this.effects.add(effect);
|
|
95
120
|
}
|
|
96
|
-
}
|
|
97
121
|
|
|
122
|
+
unsubscribeEffect(effect: Effect) {
|
|
123
|
+
this.effects.delete(effect);
|
|
124
|
+
}
|
|
98
125
|
|
|
99
|
-
|
|
100
|
-
|
|
126
|
+
private notify() {
|
|
127
|
+
const effectsToRun = Array.from(this.effects);
|
|
128
|
+
const listenersToRun = Array.from(this.listeners);
|
|
129
|
+
|
|
130
|
+
effectsToRun.forEach(e => e.trigger());
|
|
131
|
+
listenersToRun.forEach(l => l(this._value));
|
|
132
|
+
}
|
|
101
133
|
}
|
|
102
134
|
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
return new ComputedSignalImpl(fn);
|
|
135
|
+
export function signal<T>(initialValue: T): Signal<T> {
|
|
136
|
+
return new Signal(initialValue);
|
|
106
137
|
}
|
|
107
138
|
|
|
139
|
+
// --- Computed ---
|
|
140
|
+
|
|
141
|
+
export class ComputedSignal<T> implements Subscribable<T> {
|
|
142
|
+
private listeners = new Set<Listener<T>>();
|
|
143
|
+
private effects = new Set<Effect>();
|
|
144
|
+
private _value!: T;
|
|
145
|
+
private _dirty = true;
|
|
146
|
+
private internalEffect: Effect;
|
|
147
|
+
|
|
148
|
+
constructor(private fn: () => T) {
|
|
149
|
+
this.internalEffect = new Effect(() => {
|
|
150
|
+
if (!this._dirty) {
|
|
151
|
+
this._dirty = true;
|
|
152
|
+
this.notify();
|
|
153
|
+
}
|
|
154
|
+
});
|
|
155
|
+
}
|
|
108
156
|
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
const run = () => {
|
|
113
|
-
if (typeof cleanup === 'function') {
|
|
114
|
-
cleanup();
|
|
157
|
+
get value(): T {
|
|
158
|
+
if (activeEffect) {
|
|
159
|
+
activeEffect.track(this);
|
|
115
160
|
}
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
161
|
+
if (this._dirty) {
|
|
162
|
+
const prevEffect = activeEffect;
|
|
163
|
+
activeEffect = this.internalEffect;
|
|
164
|
+
try {
|
|
165
|
+
this.internalEffect.cleanup();
|
|
166
|
+
this._value = this.fn();
|
|
167
|
+
this._dirty = false;
|
|
168
|
+
} finally {
|
|
169
|
+
activeEffect = prevEffect;
|
|
170
|
+
}
|
|
124
171
|
}
|
|
125
|
-
|
|
126
|
-
}
|
|
172
|
+
return this._value;
|
|
173
|
+
}
|
|
127
174
|
|
|
175
|
+
subscribe(listener: Listener<T>): Unsubscribe {
|
|
176
|
+
this.listeners.add(listener);
|
|
177
|
+
return () => this.listeners.delete(listener);
|
|
178
|
+
}
|
|
128
179
|
|
|
180
|
+
subscribeEffect(effect: Effect) {
|
|
181
|
+
this.effects.add(effect);
|
|
182
|
+
}
|
|
129
183
|
|
|
184
|
+
unsubscribeEffect(effect: Effect) {
|
|
185
|
+
this.effects.delete(effect);
|
|
186
|
+
}
|
|
130
187
|
|
|
188
|
+
private notify() {
|
|
189
|
+
const effectsToRun = Array.from(this.effects);
|
|
190
|
+
const listenersToRun = Array.from(this.listeners);
|
|
191
|
+
|
|
192
|
+
effectsToRun.forEach(e => e.trigger());
|
|
193
|
+
listenersToRun.forEach(l => l(this._value));
|
|
194
|
+
}
|
|
195
|
+
}
|
|
131
196
|
|
|
132
|
-
export
|
|
133
|
-
|
|
134
|
-
set(value: T): void;
|
|
135
|
-
subscribe(listener: (value: T) => void): () => void;
|
|
197
|
+
export function computed<T>(fn: () => T): ComputedSignal<T> {
|
|
198
|
+
return new ComputedSignal(fn);
|
|
136
199
|
}
|
|
137
200
|
|
|
138
|
-
|
|
139
|
-
private _value: T;
|
|
140
|
-
private listeners = new Set<(value: T) => void>();
|
|
201
|
+
// --- Observables ---
|
|
141
202
|
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
203
|
+
export class Observable<T> implements Subscribable<T> {
|
|
204
|
+
private listeners = new Set<Listener<T>>();
|
|
205
|
+
private effects = new Set<Effect>();
|
|
206
|
+
|
|
207
|
+
constructor(private _value: T) {}
|
|
145
208
|
|
|
146
209
|
get(): T {
|
|
210
|
+
if (activeEffect) {
|
|
211
|
+
activeEffect.track(this);
|
|
212
|
+
}
|
|
147
213
|
return this._value;
|
|
148
214
|
}
|
|
149
215
|
|
|
150
|
-
set(
|
|
151
|
-
if (this._value !==
|
|
152
|
-
this._value =
|
|
153
|
-
this.
|
|
216
|
+
set(newValue: T) {
|
|
217
|
+
if (this._value !== newValue) {
|
|
218
|
+
this._value = newValue;
|
|
219
|
+
this.notify();
|
|
154
220
|
}
|
|
155
221
|
}
|
|
156
222
|
|
|
157
|
-
subscribe(listener:
|
|
223
|
+
subscribe(listener: Listener<T>): Unsubscribe {
|
|
158
224
|
this.listeners.add(listener);
|
|
159
225
|
return () => this.listeners.delete(listener);
|
|
160
226
|
}
|
|
161
|
-
}
|
|
162
227
|
|
|
228
|
+
subscribeEffect(effect: Effect) {
|
|
229
|
+
this.effects.add(effect);
|
|
230
|
+
}
|
|
163
231
|
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
}
|
|
167
|
-
|
|
232
|
+
unsubscribeEffect(effect: Effect) {
|
|
233
|
+
this.effects.delete(effect);
|
|
234
|
+
}
|
|
168
235
|
|
|
236
|
+
private notify() {
|
|
237
|
+
Array.from(this.effects).forEach(e => e.trigger());
|
|
238
|
+
Array.from(this.listeners).forEach(l => l(this._value));
|
|
239
|
+
}
|
|
240
|
+
}
|
|
169
241
|
|
|
242
|
+
export function observable<T>(initialValue: T): Observable<T> {
|
|
243
|
+
return new Observable(initialValue);
|
|
244
|
+
}
|
|
170
245
|
|
|
246
|
+
// --- Store ---
|
|
171
247
|
|
|
172
|
-
export interface Store<T> {
|
|
248
|
+
export interface Store<T> extends Subscribable<T> {
|
|
173
249
|
getState(): T;
|
|
174
|
-
setState(
|
|
175
|
-
subscribe(listener: (state: T) => void): () => void;
|
|
250
|
+
setState(fn: Partial<T> | ((state: T) => Partial<T>)): void;
|
|
176
251
|
}
|
|
177
252
|
|
|
178
|
-
class StoreImpl<T> implements Store<T> {
|
|
179
|
-
private
|
|
180
|
-
private
|
|
253
|
+
export class StoreImpl<T> implements Store<T> {
|
|
254
|
+
private listeners = new Set<Listener<T>>();
|
|
255
|
+
private effects = new Set<Effect>();
|
|
181
256
|
|
|
182
|
-
constructor(
|
|
183
|
-
this.state = initialState;
|
|
184
|
-
}
|
|
257
|
+
constructor(private state: T) {}
|
|
185
258
|
|
|
186
259
|
getState(): T {
|
|
260
|
+
if (activeEffect) {
|
|
261
|
+
activeEffect.track(this);
|
|
262
|
+
}
|
|
187
263
|
return this.state;
|
|
188
264
|
}
|
|
189
265
|
|
|
190
|
-
setState(
|
|
191
|
-
const
|
|
192
|
-
|
|
193
|
-
|
|
266
|
+
setState(partial: Partial<T> | ((state: T) => Partial<T>)): void {
|
|
267
|
+
const next = typeof partial === 'function' ? (partial as any)(this.state) : partial;
|
|
268
|
+
const newState = { ...this.state, ...next };
|
|
269
|
+
|
|
270
|
+
if (this.state !== newState) {
|
|
271
|
+
this.state = newState;
|
|
272
|
+
this.notify();
|
|
273
|
+
}
|
|
194
274
|
}
|
|
195
275
|
|
|
196
|
-
subscribe(listener:
|
|
276
|
+
subscribe(listener: Listener<T>): Unsubscribe {
|
|
197
277
|
this.listeners.add(listener);
|
|
198
278
|
return () => this.listeners.delete(listener);
|
|
199
279
|
}
|
|
200
|
-
}
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
export function createStore<T extends object>(initialState: T): Store<T> {
|
|
204
|
-
return new StoreImpl(initialState);
|
|
205
|
-
}
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
280
|
|
|
281
|
+
subscribeEffect(effect: Effect) {
|
|
282
|
+
this.effects.add(effect);
|
|
283
|
+
}
|
|
210
284
|
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
}
|
|
215
|
-
|
|
216
|
-
export interface ConsumerConfig {
|
|
217
|
-
key: string;
|
|
218
|
-
}
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
const providerRegistry = new Map<string, any>();
|
|
222
|
-
|
|
223
|
-
export function registerProvider<T>(key: string, value: T): void {
|
|
224
|
-
providerRegistry.set(key, value);
|
|
225
|
-
}
|
|
285
|
+
unsubscribeEffect(effect: Effect) {
|
|
286
|
+
this.effects.delete(effect);
|
|
287
|
+
}
|
|
226
288
|
|
|
227
|
-
|
|
228
|
-
|
|
289
|
+
private notify() {
|
|
290
|
+
Array.from(this.effects).forEach(e => e.trigger());
|
|
291
|
+
Array.from(this.listeners).forEach(l => l(this.state));
|
|
292
|
+
}
|
|
229
293
|
}
|
|
230
294
|
|
|
231
|
-
export function
|
|
232
|
-
|
|
295
|
+
export function createStore<T>(initialState: T): Store<T> {
|
|
296
|
+
return new StoreImpl(initialState);
|
|
233
297
|
}
|
package/src/demo.tsx
CHANGED
|
@@ -48,12 +48,17 @@ import {
|
|
|
48
48
|
Progress
|
|
49
49
|
} from './index';
|
|
50
50
|
|
|
51
|
+
|
|
52
|
+
|
|
51
53
|
const Gallery = () => {
|
|
52
54
|
const { setTheme } = useFiboTheme();
|
|
53
55
|
|
|
54
56
|
return (
|
|
55
57
|
Box().classNames(['bg-gray-50', 'min-h-screen', 'p-12']).gap(14).children([
|
|
56
58
|
|
|
59
|
+
// --- CLEAN ARCHITECTURE DEMO ---
|
|
60
|
+
|
|
61
|
+
|
|
57
62
|
|
|
58
63
|
Row().alignItems("center").justifyContent("between").classNames(['mb-12']).children([
|
|
59
64
|
Column().gap(8).children([
|
|
@@ -102,8 +102,9 @@ const ButtonInner = React.memo((props: any) => {
|
|
|
102
102
|
if (!disabled) {
|
|
103
103
|
|
|
104
104
|
if (document.documentElement.classList.contains('fibo-theme-material')) {
|
|
105
|
+
const target = e.currentTarget;
|
|
105
106
|
import('../../core/effects').then(({ createRipple }) => {
|
|
106
|
-
createRipple(e);
|
|
107
|
+
createRipple(e, target);
|
|
107
108
|
});
|
|
108
109
|
}
|
|
109
110
|
onPress?.();
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import React, { ReactElement, ChangeEvent } from 'react';
|
|
1
|
+
import React, { ReactElement, ChangeEvent, useEffect, useState } from 'react';
|
|
2
2
|
import { FiboBuilder, createBuilder } from '../../core/builder';
|
|
3
3
|
import { BaseProps } from '../../core/types';
|
|
4
|
+
import { Signal } from '../../core/state';
|
|
4
5
|
|
|
5
6
|
const applyMask = (value: string, mask: string) => {
|
|
6
7
|
let i = 0;
|
|
@@ -31,10 +32,27 @@ const TextFieldInner = React.memo((props: any) => {
|
|
|
31
32
|
error,
|
|
32
33
|
mask,
|
|
33
34
|
type,
|
|
35
|
+
value, // Can be string or Signal
|
|
34
36
|
onChange,
|
|
35
37
|
...inputRest
|
|
36
38
|
} = props;
|
|
37
39
|
|
|
40
|
+
// Handle Signal or primitive value
|
|
41
|
+
const isSignal = value instanceof Signal;
|
|
42
|
+
const [localValue, setLocalValue] = useState(isSignal ? value.value : value);
|
|
43
|
+
|
|
44
|
+
// Sync with Signal updates
|
|
45
|
+
useEffect(() => {
|
|
46
|
+
if (isSignal) {
|
|
47
|
+
const unsubscribe = value.subscribe((val: string) => {
|
|
48
|
+
setLocalValue(val);
|
|
49
|
+
});
|
|
50
|
+
return unsubscribe;
|
|
51
|
+
} else {
|
|
52
|
+
setLocalValue(value);
|
|
53
|
+
}
|
|
54
|
+
}, [value, isSignal]);
|
|
55
|
+
|
|
38
56
|
const isPassword = type === 'password';
|
|
39
57
|
const effectiveType = isPassword && showPassword ? 'text' : type;
|
|
40
58
|
|
|
@@ -51,8 +69,14 @@ const TextFieldInner = React.memo((props: any) => {
|
|
|
51
69
|
}
|
|
52
70
|
} as React.ChangeEvent<HTMLInputElement>;
|
|
53
71
|
|
|
72
|
+
if (isSignal) {
|
|
73
|
+
value.value = newValue; // Update signal
|
|
74
|
+
}
|
|
54
75
|
onChange?.(syntheticEvent);
|
|
55
76
|
} else {
|
|
77
|
+
if (isSignal) {
|
|
78
|
+
value.value = newValue; // Update signal
|
|
79
|
+
}
|
|
56
80
|
onChange?.(e);
|
|
57
81
|
}
|
|
58
82
|
};
|
|
@@ -67,6 +91,7 @@ const TextFieldInner = React.memo((props: any) => {
|
|
|
67
91
|
className: 'fibo-textfield-input',
|
|
68
92
|
type: effectiveType,
|
|
69
93
|
onChange: handleChange,
|
|
94
|
+
value: localValue,
|
|
70
95
|
...inputRest
|
|
71
96
|
}),
|
|
72
97
|
label && React.createElement(
|
|
@@ -107,7 +132,7 @@ const TextFieldInner = React.memo((props: any) => {
|
|
|
107
132
|
});
|
|
108
133
|
|
|
109
134
|
class TextFieldBuilder extends FiboBuilder {
|
|
110
|
-
private _value: string = '';
|
|
135
|
+
private _value: string | Signal<string> = '';
|
|
111
136
|
private _label: string = '';
|
|
112
137
|
private _placeholder: string = '';
|
|
113
138
|
private _type: string = 'text';
|
|
@@ -121,7 +146,7 @@ class TextFieldBuilder extends FiboBuilder {
|
|
|
121
146
|
this._value = value;
|
|
122
147
|
}
|
|
123
148
|
|
|
124
|
-
value(val: string): this {
|
|
149
|
+
value(val: string | Signal<string>): this {
|
|
125
150
|
this._value = val;
|
|
126
151
|
return this;
|
|
127
152
|
}
|
|
@@ -186,12 +211,10 @@ class TextFieldBuilder extends FiboBuilder {
|
|
|
186
211
|
}
|
|
187
212
|
}
|
|
188
213
|
|
|
189
|
-
|
|
190
|
-
|
|
191
214
|
export const TextField = createBuilder(TextFieldBuilder);
|
|
192
215
|
|
|
193
216
|
export interface TextFieldProps extends BaseProps {
|
|
194
|
-
value: string
|
|
217
|
+
value: string | Signal<string>;
|
|
195
218
|
label?: string;
|
|
196
219
|
placeholder?: string;
|
|
197
220
|
onChange?: (value: string) => void;
|
|
@@ -25,8 +25,10 @@ class BoxBuilder extends FiboBuilder {
|
|
|
25
25
|
|
|
26
26
|
const className = classes.filter(Boolean).join(' ');
|
|
27
27
|
const style = this.getStyle();
|
|
28
|
-
const children = this.processChildren();
|
|
29
28
|
|
|
29
|
+
// Universal builder handles observer logic now.
|
|
30
|
+
// processChildren handles function execution if present.
|
|
31
|
+
const children = this.processChildren();
|
|
30
32
|
|
|
31
33
|
const props = {
|
|
32
34
|
className,
|
|
@@ -39,7 +41,6 @@ class BoxBuilder extends FiboBuilder {
|
|
|
39
41
|
}
|
|
40
42
|
}
|
|
41
43
|
|
|
42
|
-
|
|
43
44
|
export const Box = createBuilder(BoxBuilder);
|
|
44
45
|
|
|
45
46
|
export interface BoxProps extends ChildrenProps {}
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
const c = (n, r = "rgba(255, 255, 255, 0.3)") => {
|
|
2
|
-
const t = n.currentTarget, e = document.createElement("span"), i = Math.max(t.clientWidth, t.clientHeight), o = i / 2, l = t.getBoundingClientRect();
|
|
3
|
-
e.style.width = e.style.height = `${i}px`, e.style.left = `${n.clientX - l.left - o}px`, e.style.top = `${n.clientY - l.top - o}px`, e.style.position = "absolute", e.style.borderRadius = "50%", e.style.transform = "scale(0)", e.style.animation = "fibo-ripple 600ms linear", e.style.backgroundColor = r, e.style.pointerEvents = "none", (t.querySelector(".fibo-ripple-container") || t).appendChild(e), setTimeout(() => {
|
|
4
|
-
e.remove();
|
|
5
|
-
}, 600);
|
|
6
|
-
};
|
|
7
|
-
export {
|
|
8
|
-
c as createRipple
|
|
9
|
-
};
|
|
@@ -1,3 +0,0 @@
|
|
|
1
|
-
export declare function App(): import('react').ReactElement<any, string | import('react').JSXElementConstructor<any>>;
|
|
2
|
-
export declare function EcommerceApp(): import('react').ReactElement<any, string | import('react').JSXElementConstructor<any>>;
|
|
3
|
-
export declare function DashboardApp(): import('react').ReactElement<any, string | import('react').JSXElementConstructor<any>>;
|
|
@@ -1,5 +0,0 @@
|
|
|
1
|
-
export declare function SignalCounterExample(): import('react').ReactElement<any, string | import('react').JSXElementConstructor<any>>;
|
|
2
|
-
export declare function ObservableExample(): import('react').ReactElement<any, string | import('react').JSXElementConstructor<any>>;
|
|
3
|
-
export declare function StoreExample(): import('react').ReactElement<any, string | import('react').JSXElementConstructor<any>>;
|
|
4
|
-
export declare function ProviderExample(): import('react').ReactElement<any, string | import('react').JSXElementConstructor<any>>;
|
|
5
|
-
export declare function LocalStateExample(): import('react').ReactElement<any, string | import('react').JSXElementConstructor<any>>;
|