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 CHANGED
@@ -1,101 +1,172 @@
1
- # FiboUI
1
+ # 🏗️ FiboUI v1.0.0
2
2
 
3
- A Flutter/SwiftUI-inspired React UI framework with builder pattern and theme system.
3
+ **A Flutter & SwiftUI-inspired React UI framework featuring a powerful Assembly Pattern and high-fidelity reactivity.**
4
4
 
5
- ## Installation
5
+ FiboUI brings the expressive, chainable syntax of modern mobile frameworks to React. Build complex, beautiful, and highly-performant UIs with **zero boilerplate** and **maximum readability**.
6
+
7
+ ---
8
+
9
+ ## ✨ Features
10
+
11
+ - 🏗️ **The Assembly Pattern** - Components return builders for endless chaining.
12
+ - ⚡ **Zero-Build Children** - Pass builders directly to `.children()`; they build implicitly.
13
+ - 🔬 **Fine-Grained Reactivity** - Native support for Signals, Computed, and Observables.
14
+ - 🎭 **Dynamic Multi-Theme** - Material, Cupertino, and Web themes with instant global switching.
15
+ - 🎨 **Premium Aesthetics** - Built-in glassmorphism, micro-animations, and sleek dark modes.
16
+ - 🔷 **100% Type-Safe** - Built with TypeScript for the best developer experience.
17
+
18
+ ---
19
+
20
+ ## 🚀 Installation
6
21
 
7
22
  ```bash
8
23
  npm install fiboui
9
24
  ```
10
25
 
11
- ## Quick Start
26
+ Import the styles in your main entry file:
12
27
 
13
28
  ```tsx
14
- import { FiboThemeProvider, Container, Text, Button, Row } from 'fiboui';
15
29
  import 'fiboui/dist/style.css';
30
+ ```
16
31
 
17
- function App() {
18
- return (
19
- <FiboThemeProvider theme="material">
20
- {Container()
21
- .padding("8")
22
- .children([
23
- Text("Hello FiboUI!")
24
- .type("h1")
25
- .fontSize(32)
26
- .fontWeight("bold"),
27
-
28
- Row()
29
- .spacing("4")
30
- .children([
31
- Button("Click me")
32
- .variant("elevated")
33
- .onPress(() => console.log("Clicked!")),
34
-
35
- Button("Outlined")
36
- .variant("outlined")
37
- ])
38
- ])
39
- .build()}
40
- </FiboThemeProvider>
41
- );
42
- }
32
+ ---
33
+
34
+ ## 🏗️ The Assembly Pattern
35
+
36
+ ### 1. Components as Builders
37
+ Components return builder instances, allowing customization before rendering.
38
+
39
+ ```tsx
40
+ StakentCard()
41
+ .className("p-8 hover:border-indigo-500/50")
42
+ .style({ backgroundColor: '#111' })
43
+ .children([ ... ])
44
+ .build()
43
45
  ```
44
46
 
45
- ## Features
47
+ ### 2. Implicit Construction
48
+ Builders in `.children()` are automatically finalized.
46
49
 
47
- - 🎨 **SwiftUI-Style Builder Pattern** - Chainable, expressive component composition
48
- - 🎭 **Multi-Theme System** - Material, Cupertino, and Web themes with dynamic switching
49
- - ⚡ **Tailwind CSS Integration** - Native Tailwind support with theme consistency
50
- - 📱 **Responsive Design** - Built-in responsive styling system
51
- - 🔷 **TypeScript-First** - Full type safety and IntelliSense support
50
+ ```tsx
51
+ Column().children([
52
+ Text("Title").variant("h1"),
53
+ Button("Action").onClick(handlePress)
54
+ ]).build()
55
+ ```
52
56
 
53
- ## Themes
57
+ ---
54
58
 
55
- Switch between themes dynamically:
59
+ ## ⚡ Reactivity & State
56
60
 
61
+ ### Signals (Primitives)
57
62
  ```tsx
58
- import { useFiboTheme } from 'fiboui';
63
+ const count = signal(0);
64
+
65
+ Box()
66
+ .bindSignal(count)
67
+ .children([
68
+ Text(`Count: ${count.value}`),
69
+ Button("+").onPress(() => count.value++)
70
+ ])
71
+ .build()
72
+ ```
59
73
 
60
- function ThemeSwitcher() {
61
- const { theme, setTheme } = useFiboTheme();
62
-
63
- return Row()
64
- .spacing("md")
65
- .children([
66
- Button("Material").onPress(() => setTheme('material')),
67
- Button("Cupertino").onPress(() => setTheme('cupertino')),
68
- Button("Web").onPress(() => setTheme('web'))
74
+ ### Global Store
75
+ ```tsx
76
+ const store = createStore({ theme: 'dark', user: 'John' });
77
+
78
+ Box().observer().children([
79
+ Text(store.getState().user)
80
+ ])
81
+ ```
82
+
83
+ ---
84
+
85
+ ## 📱 Scaffold & Layout Shells
86
+
87
+ The `Scaffold` and `DashboardLayout` components provide professional-grade app structures.
88
+
89
+ ```tsx
90
+ import { Scaffold, Sidebar, Header, Text, StakentButton } from 'fiboui';
91
+
92
+ Scaffold()
93
+ .header(
94
+ Header().height(80).className("px-6 bg-white shadow-sm").children([
95
+ Text("App Title").variant("h2"),
96
+ StakentButton({ text: "Profile", variant: "outline" })
69
97
  ])
70
- .build();
71
- }
98
+ )
99
+ .sidebar(
100
+ Sidebar().width(240).children([
101
+ StakentSidebarItem({ label: "Home", active: true, icon: "home" }),
102
+ StakentSidebarItem({ label: "Settings", icon: "settings" })
103
+ ])
104
+ )
105
+ .fab(
106
+ Button("+").variant("fab").onPress(() => console.log("Added!"))
107
+ )
108
+ .children([
109
+ Text("Welcome to the main content area.")
110
+ ])
111
+ .build()
72
112
  ```
73
113
 
74
- ## Components
114
+ ---
75
115
 
76
- ### Layout
77
- - `Container` - Flexible container
78
- - `Row` - Horizontal layout
79
- - `Column` - Vertical layout
80
- - `Spacer` - Spacing element
81
- - `Center` - Centering wrapper
82
- - `Line` - Custom horizontal container
116
+ ## 🛒 Full Example: E-commerce Store
83
117
 
84
- ### Content
85
- - `Text` - Text with typography styles
86
- - `Image` - Image with SwiftUI-like methods
118
+ Combine **Signals**, **Store**, and **Builders** for a complete reactive application.
87
119
 
88
- ### Interactive
89
- - `Button` - Button with variants
120
+ ```tsx
121
+ import { signal, computed, createStore, Scaffold, Box, Text, Button, Badge, Row } from 'fiboui';
122
+
123
+ // 1. Global Store
124
+ const appStore = createStore({
125
+ cart: [],
126
+ products: [
127
+ { id: '1', name: 'MacBook Pro', price: 2499, image: '💻' },
128
+ { id: '2', name: 'iPhone 15', price: 999, image: '📱' }
129
+ ]
130
+ });
131
+
132
+ // 2. Reactive Computed Values
133
+ const cartTotal = computed(() => {
134
+ const cart = appStore.getState().cart;
135
+ return cart.reduce((sum, item) => sum + item.price * item.quantity, 0);
136
+ });
137
+
138
+ // 3. UI Component
139
+ export function EcommerceApp() {
140
+ return Scaffold()
141
+ .header(
142
+ Header().children([
143
+ Text('🛒 FiboShop').variant("h2"),
144
+ Row().children([
145
+ Text(`Total: $${cartTotal.value.toFixed(2)}`).bindSignal(cartTotal),
146
+ Badge().text(appStore.getState().cart.length.toString()).observer()
147
+ ])
148
+ ])
149
+ )
150
+ .children([
151
+ Grid().columns(2).gap("md").children(
152
+ appStore.getState().products.map(product =>
153
+ Card().children([
154
+ Text(product.image).fontSize(40),
155
+ Text(product.name).fontWeight("bold"),
156
+ Button(`Add $${product.price}`).onPress(() => {
157
+ // Update Store & Watch UI React!
158
+ appStore.setState(s => ({ cart: [...s.cart, { ...product, quantity: 1 }] }));
159
+ })
160
+ ])
161
+ )
162
+ )
163
+ ])
164
+ .build();
165
+ }
166
+ ```
90
167
 
91
- ### Structure
92
- - `Card` - Information card
93
- - `Banner` - Status banner
94
- - `List` - Icon-title-subtitle list
95
- - `Tags` - Badge tags
96
- - `Box` - Container wrapper
97
- - `Table` - Data table
168
+ ---
98
169
 
99
- ## License
170
+ ## 📄 License
100
171
 
101
- MIT
172
+ MIT © 2025 FiboUI
@@ -1,6 +1,9 @@
1
1
  import { ReactNode } from 'react';
2
2
  import { Observable, Signal } from './state';
3
3
 
4
+ export declare function Observer({ children }: {
5
+ children: () => ReactNode;
6
+ }): import("react/jsx-runtime").JSX.Element;
4
7
  export declare const StateContext: import('react').Context<Map<string, any>>;
5
8
  export declare function useStateContext(): Map<string, any>;
6
9
  interface StateWrapperProps {
@@ -15,6 +15,7 @@ export declare abstract class FiboBuilder {
15
15
  protected _signals: Set<Signal<any>>;
16
16
  protected _isObserver: boolean;
17
17
  id(value: string): this;
18
+ key(value: string | number): this;
18
19
  paddingHorizontal(value: string | number): this;
19
20
  paddingVertical(value: string | number): this;
20
21
  marginHorizontal(value: string | number): this;
@@ -37,10 +38,12 @@ export declare abstract class FiboBuilder {
37
38
  css(styles: CSSProperties): this;
38
39
  style(style: CSSProperties): this;
39
40
  props(props: Record<string, any>): this;
40
- children(children: ReactNode | ReactNode[]): this;
41
+ protected _childFunction?: () => ReactNode;
42
+ children(children: ReactNode | ReactNode[] | (() => ReactNode)): this;
41
43
  protected getClassName(): string;
42
44
  protected getStyle(): CSSProperties;
43
45
  protected processChildren(): ReactNode[];
46
+ protected getChildFunction(): (() => ReactNode) | undefined;
44
47
  abstract build(): ReactElement;
45
48
  }
46
49
  type StyleBuilder<T> = T & {
@@ -1,3 +1,4 @@
1
- import { MouseEvent } from 'react';
2
-
3
- export declare const createRipple: (event: MouseEvent<HTMLElement>, color?: string) => void;
1
+ export declare const createRipple: (event: {
2
+ clientX: number;
3
+ clientY: number;
4
+ }, button: HTMLElement, color?: string) => void;
@@ -0,0 +1,5 @@
1
+ import { Signal, ComputedSignal, Store, Observable } from './state';
2
+
3
+ export declare function useSignal<T>(signal: Signal<T> | ComputedSignal<T>): T;
4
+ export declare function useStore<T>(store: Store<T>): T;
5
+ export declare function useObservable<T>(obs: Observable<T>): T;
@@ -3,3 +3,4 @@ export * from './builder';
3
3
  export * from './component';
4
4
  export * from './state';
5
5
  export * from './StateWrapper';
6
+ export * from './hooks';
@@ -1,37 +1,86 @@
1
- export type StateGetter<T> = () => T;
2
- export type StateSetter<T> = (value: T | ((prev: T) => T)) => void;
3
- export type StateHook<T> = [T, StateSetter<T>];
4
- export interface Signal<T> {
5
- value: T;
6
- subscribe(callback: (value: T) => void): () => void;
1
+ export type Listener<T> = (value: T) => void;
2
+ export type Unsubscribe = () => void;
3
+ export interface Subscribable<T> {
4
+ subscribe(listener: Listener<T>): Unsubscribe;
5
+ subscribeEffect(effect: Effect): void;
6
+ unsubscribeEffect(effect: Effect): void;
7
7
  }
8
- export interface ComputedSignal<T> extends Omit<Signal<T>, 'value'> {
9
- readonly value: T;
8
+ export declare class Effect {
9
+ private fn;
10
+ private dependencies;
11
+ private _onDispose?;
12
+ constructor(fn: () => void);
13
+ run(): void;
14
+ track(dep: Subscribable<any>): void;
15
+ trigger(): void;
16
+ cleanup(): void;
17
+ dispose(): void;
18
+ }
19
+ export declare class Tracker {
20
+ private _onInvalidate;
21
+ private dependencies;
22
+ constructor(_onInvalidate: () => void);
23
+ execute<T>(fn: () => T): T;
24
+ track(dep: Subscribable<any>): void;
25
+ trigger(): void;
26
+ cleanup(): void;
27
+ dispose(): void;
28
+ }
29
+ export declare class Signal<T> implements Subscribable<T> {
30
+ private _value;
31
+ private listeners;
32
+ private effects;
33
+ constructor(_value: T);
34
+ get value(): T;
35
+ set value(newValue: T);
36
+ subscribe(listener: Listener<T>): Unsubscribe;
37
+ subscribeEffect(effect: Effect): void;
38
+ unsubscribeEffect(effect: Effect): void;
39
+ private notify;
10
40
  }
11
- type EffectCleanup = void | (() => void);
12
41
  export declare function signal<T>(initialValue: T): Signal<T>;
42
+ export declare class ComputedSignal<T> implements Subscribable<T> {
43
+ private fn;
44
+ private listeners;
45
+ private effects;
46
+ private _value;
47
+ private _dirty;
48
+ private internalEffect;
49
+ constructor(fn: () => T);
50
+ get value(): T;
51
+ subscribe(listener: Listener<T>): Unsubscribe;
52
+ subscribeEffect(effect: Effect): void;
53
+ unsubscribeEffect(effect: Effect): void;
54
+ private notify;
55
+ }
13
56
  export declare function computed<T>(fn: () => T): ComputedSignal<T>;
14
- export declare function effect(fn: () => EffectCleanup): () => void;
15
- export interface Observable<T> {
57
+ export declare class Observable<T> implements Subscribable<T> {
58
+ private _value;
59
+ private listeners;
60
+ private effects;
61
+ constructor(_value: T);
16
62
  get(): T;
17
- set(value: T): void;
18
- subscribe(listener: (value: T) => void): () => void;
63
+ set(newValue: T): void;
64
+ subscribe(listener: Listener<T>): Unsubscribe;
65
+ subscribeEffect(effect: Effect): void;
66
+ unsubscribeEffect(effect: Effect): void;
67
+ private notify;
19
68
  }
20
69
  export declare function observable<T>(initialValue: T): Observable<T>;
21
- export interface Store<T> {
70
+ export interface Store<T> extends Subscribable<T> {
22
71
  getState(): T;
23
- setState(updater: Partial<T> | ((state: T) => Partial<T>)): void;
24
- subscribe(listener: (state: T) => void): () => void;
72
+ setState(fn: Partial<T> | ((state: T) => Partial<T>)): void;
25
73
  }
26
- export declare function createStore<T extends object>(initialState: T): Store<T>;
27
- export interface ProviderConfig<T = any> {
28
- key: string;
29
- value: T;
30
- }
31
- export interface ConsumerConfig {
32
- key: string;
74
+ export declare class StoreImpl<T> implements Store<T> {
75
+ private state;
76
+ private listeners;
77
+ private effects;
78
+ constructor(state: T);
79
+ getState(): T;
80
+ setState(partial: Partial<T> | ((state: T) => Partial<T>)): void;
81
+ subscribe(listener: Listener<T>): Unsubscribe;
82
+ subscribeEffect(effect: Effect): void;
83
+ unsubscribeEffect(effect: Effect): void;
84
+ private notify;
33
85
  }
34
- export declare function registerProvider<T>(key: string, value: T): void;
35
- export declare function getProvider<T>(key: string): T | undefined;
36
- export declare function clearProviders(): void;
37
- export {};
86
+ export declare function createStore<T>(initialState: T): Store<T>;
@@ -0,0 +1,10 @@
1
+ const c = (i, t, s = "rgba(255, 255, 255, 0.3)") => {
2
+ if (!t) return;
3
+ const e = document.createElement("span"), l = Math.max(t.clientWidth, t.clientHeight), n = l / 2, r = t.getBoundingClientRect();
4
+ e.style.width = e.style.height = `${l}px`, e.style.left = `${i.clientX - r.left - n}px`, e.style.top = `${i.clientY - r.top - n}px`, e.style.position = "absolute", e.style.borderRadius = "50%", e.style.transform = "scale(0)", e.style.animation = "fibo-ripple 600ms linear", e.style.backgroundColor = s, e.style.pointerEvents = "none", (t.querySelector(".fibo-ripple-container") || t).appendChild(e), setTimeout(() => {
5
+ e.remove();
6
+ }, 600);
7
+ };
8
+ export {
9
+ c as createRipple
10
+ };