flexium 0.12.13 → 0.12.17

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.
Files changed (101) hide show
  1. package/README.md +149 -92
  2. package/dist/canvas.d.cts +14 -13
  3. package/dist/canvas.d.ts +14 -13
  4. package/dist/canvas.js +1 -1
  5. package/dist/canvas.js.map +1 -1
  6. package/dist/canvas.mjs +1 -1
  7. package/dist/canvas.mjs.map +1 -1
  8. package/dist/chunk-3DKZ2J4D.mjs +2 -0
  9. package/dist/chunk-3DKZ2J4D.mjs.map +1 -0
  10. package/dist/chunk-5PNH2ARD.mjs +2 -0
  11. package/dist/chunk-5PNH2ARD.mjs.map +1 -0
  12. package/dist/{chunk-7BXR4ZFD.js → chunk-6VIRXD2Y.js} +2 -2
  13. package/dist/chunk-6VIRXD2Y.js.map +1 -0
  14. package/dist/chunk-6Z33DLMI.js +2 -0
  15. package/dist/chunk-6Z33DLMI.js.map +1 -0
  16. package/dist/chunk-E75BJDOQ.mjs +2 -0
  17. package/dist/chunk-E75BJDOQ.mjs.map +1 -0
  18. package/dist/chunk-IWFEXW4F.mjs +2 -0
  19. package/dist/chunk-IWFEXW4F.mjs.map +1 -0
  20. package/dist/chunk-JY6CE6RN.mjs +2 -0
  21. package/dist/chunk-JY6CE6RN.mjs.map +1 -0
  22. package/dist/chunk-LTT43APF.js +2 -0
  23. package/dist/chunk-LTT43APF.js.map +1 -0
  24. package/dist/chunk-PSKDIB7J.js +2 -0
  25. package/dist/chunk-PSKDIB7J.js.map +1 -0
  26. package/dist/chunk-UWFVCKRU.js +2 -0
  27. package/dist/chunk-UWFVCKRU.js.map +1 -0
  28. package/dist/chunk-WGKD63GN.mjs +2 -0
  29. package/dist/chunk-WGKD63GN.mjs.map +1 -0
  30. package/dist/chunk-YWTD32NA.js +2 -0
  31. package/dist/chunk-YWTD32NA.js.map +1 -0
  32. package/dist/core.d.cts +91 -15
  33. package/dist/core.d.ts +91 -15
  34. package/dist/core.js +1 -1
  35. package/dist/core.js.map +1 -1
  36. package/dist/core.mjs +1 -1
  37. package/dist/core.mjs.map +1 -1
  38. package/dist/dom.d.cts +154 -9
  39. package/dist/dom.d.ts +154 -9
  40. package/dist/dom.js +1 -1
  41. package/dist/dom.js.map +1 -1
  42. package/dist/dom.mjs +1 -1
  43. package/dist/dom.mjs.map +1 -1
  44. package/dist/index.d.cts +1 -1
  45. package/dist/index.d.ts +1 -1
  46. package/dist/index.js +1 -1
  47. package/dist/index.js.map +1 -1
  48. package/dist/index.mjs +1 -1
  49. package/dist/index.mjs.map +1 -1
  50. package/dist/interactive.d.cts +17 -16
  51. package/dist/interactive.d.ts +17 -16
  52. package/dist/interactive.js +1 -1
  53. package/dist/interactive.js.map +1 -1
  54. package/dist/interactive.mjs +1 -1
  55. package/dist/interactive.mjs.map +1 -1
  56. package/dist/jsx-dev-runtime.d.cts +1 -1
  57. package/dist/jsx-dev-runtime.d.ts +1 -1
  58. package/dist/jsx-runtime.d.cts +1 -1
  59. package/dist/jsx-runtime.d.ts +1 -1
  60. package/dist/metafile-cjs.json +1 -1
  61. package/dist/metafile-esm.json +1 -1
  62. package/dist/render-QZAFAGIM.js +2 -0
  63. package/dist/render-QZAFAGIM.js.map +1 -0
  64. package/dist/render-UIWHIMS2.mjs +2 -0
  65. package/dist/render-UIWHIMS2.mjs.map +1 -0
  66. package/dist/router.d.cts +1 -1
  67. package/dist/router.d.ts +1 -1
  68. package/dist/router.js +1 -1
  69. package/dist/router.js.map +1 -1
  70. package/dist/router.mjs +1 -1
  71. package/dist/router.mjs.map +1 -1
  72. package/dist/server.d.cts +17 -0
  73. package/dist/server.d.ts +17 -0
  74. package/dist/server.js +2 -0
  75. package/dist/server.js.map +1 -0
  76. package/dist/server.mjs +2 -0
  77. package/dist/server.mjs.map +1 -0
  78. package/dist/types-CxlS2F2j.d.cts +19 -0
  79. package/dist/types-CxlS2F2j.d.ts +19 -0
  80. package/dist/types-y2GGaXXk.d.cts +9 -0
  81. package/dist/types-y2GGaXXk.d.ts +9 -0
  82. package/package.json +6 -1
  83. package/dist/chunk-44RZHCII.mjs +0 -2
  84. package/dist/chunk-44RZHCII.mjs.map +0 -1
  85. package/dist/chunk-7BXR4ZFD.js.map +0 -1
  86. package/dist/chunk-APAMPY43.js +0 -2
  87. package/dist/chunk-APAMPY43.js.map +0 -1
  88. package/dist/chunk-CPJRQL2C.mjs +0 -2
  89. package/dist/chunk-CPJRQL2C.mjs.map +0 -1
  90. package/dist/chunk-ECB5HZOQ.mjs +0 -2
  91. package/dist/chunk-ECB5HZOQ.mjs.map +0 -1
  92. package/dist/chunk-ENWGYQNU.js +0 -2
  93. package/dist/chunk-ENWGYQNU.js.map +0 -1
  94. package/dist/chunk-IA4FEBFE.js +0 -2
  95. package/dist/chunk-IA4FEBFE.js.map +0 -1
  96. package/dist/chunk-LUREDEUB.mjs +0 -2
  97. package/dist/chunk-LUREDEUB.mjs.map +0 -1
  98. package/dist/chunk-LUW7DIEW.js +0 -2
  99. package/dist/chunk-LUW7DIEW.js.map +0 -1
  100. package/dist/chunk-S6WF3XNF.mjs +0 -2
  101. package/dist/chunk-S6WF3XNF.mjs.map +0 -1
package/README.md CHANGED
@@ -11,9 +11,9 @@ Flexium is a next-generation UI framework that unifies state management, async d
11
11
  ## Key Features
12
12
 
13
13
  - **Unified State API** - No more `useState`, `useRecoil`, `useQuery` separation. Just `state()`.
14
- - **No Virtual DOM** - Direct DOM updates for maximum performance and minimal memory usage.
15
- - **Tiny Bundle** - ~8KB (min+gzip) including Router and Motion.
16
- - **Cross-Platform** - DOM, Canvas, and SSR renderers included.
14
+ - **No Virtual DOM** - Direct DOM updates via Proxy-based fine-grained reactivity.
15
+ - **Tiny Bundle** - Minimal footprint with tree-shaking support.
16
+ - **Cross-Platform** - DOM, Canvas, Server (SSR) renderers included.
17
17
  - **TypeScript First** - Full type inference out of the box.
18
18
  - **Zero-Config JSX** - Works with standard tooling.
19
19
 
@@ -39,20 +39,20 @@ Flexium unifies all state concepts into one function.
39
39
  ### Local State
40
40
 
41
41
  ```tsx
42
- import { state } from 'flexium/core';
43
- import { render } from 'flexium/dom';
42
+ import { state } from 'flexium/core'
43
+ import { render } from 'flexium/dom'
44
44
 
45
45
  function Counter() {
46
- const [count, setCount] = state(0);
46
+ const [count, setCount] = state(0)
47
47
 
48
48
  return (
49
49
  <button onclick={() => setCount(c => c + 1)}>
50
50
  Count: {count}
51
51
  </button>
52
- );
52
+ )
53
53
  }
54
54
 
55
- render(<Counter />, document.getElementById('app'));
55
+ render(Counter, document.getElementById('app'))
56
56
  ```
57
57
 
58
58
  ### Global State
@@ -61,16 +61,17 @@ Just add a `key` to share state across components. Keys can be strings or arrays
61
61
 
62
62
  ```tsx
63
63
  // Define global state with array key
64
- const [theme, setTheme] = state('light', { key: ['app', 'theme'] });
64
+ const [theme, setTheme] = state('light', { key: ['app', 'theme'] })
65
65
 
66
66
  function ThemeToggle() {
67
- const [theme, setTheme] = state(undefined, { key: ['app', 'theme'] });
67
+ // Access same state anywhere with the same key
68
+ const [theme, setTheme] = state('light', { key: ['app', 'theme'] })
68
69
 
69
70
  return (
70
71
  <button onclick={() => setTheme(t => t === 'light' ? 'dark' : 'light')}>
71
72
  Theme: {theme}
72
73
  </button>
73
- );
74
+ )
74
75
  }
75
76
  ```
76
77
 
@@ -81,55 +82,40 @@ Pass an async function to handle data fetching automatically.
81
82
  ```tsx
82
83
  function UserProfile({ id }) {
83
84
  const [user, control] = state(async () => {
84
- const res = await fetch(`/api/users/${id}`);
85
- return res.json();
86
- });
85
+ const res = await fetch(`/api/users/${id}`)
86
+ return res.json()
87
+ })
87
88
 
88
- if (control.loading) return <div>Loading...</div>;
89
- if (control.error) return <div>Error!</div>;
89
+ if (control.loading) return <div>Loading...</div>
90
+ if (control.error) return <div>Error!</div>
90
91
 
91
92
  return (
92
93
  <div>
93
94
  <h1>{user.name}</h1>
94
95
  <button onclick={() => control.refetch()}>Reload</button>
95
96
  </div>
96
- );
97
+ )
97
98
  }
98
99
  ```
99
100
 
100
- ### Derived State
101
+ ### Computed/Derived State
101
102
 
102
103
  ```tsx
103
- const [count, setCount] = state(1);
104
- const [double] = state(() => count * 2, { deps: [count] });
105
- ```
106
-
107
- ### Array Keys & Params
108
-
109
- ```tsx
110
- // Array keys for dynamic caching (like TanStack Query)
111
- const [user] = state(fetchUser, { key: ['user', userId] });
112
-
113
- // Explicit params for better DX
114
- const [data] = state(
115
- async ({ userId, postId }) => fetchPost(userId, postId),
116
- {
117
- key: ['posts', userId, postId],
118
- params: { userId, postId }
119
- }
120
- );
104
+ const [count, setCount] = state(1)
105
+ const [doubled] = state(() => count * 2, { deps: [count] })
121
106
  ```
122
107
 
123
108
  ## Package Structure
124
109
 
125
110
  ```
126
111
  flexium
127
- ├── /core # Core reactivity: state(), effect(), batch()
128
- ├── /dom # DOM renderer: render(), Portal
129
- ├── /canvas # Canvas renderer: Canvas, Rect, Circle, Text
130
- ├── /primitives # Cross-platform components: Row, Column, Stack
131
- ├── /router # SPA routing: Router, Route, Link
132
- └── /server # SSR utilities
112
+ ├── /core # Core reactivity: state(), effect(), sync(), context()
113
+ ├── /dom # DOM renderer: render(), hydrate(), Portal, Suspense
114
+ ├── /ref # Ref system: ref(), forwardRef()
115
+ ├── /router # SPA routing: Routes, Route, Link, Outlet
116
+ ├── /server # SSR: renderToString(), renderToStaticMarkup()
117
+ ├── /canvas # Canvas 2D: Canvas, DrawRect, DrawCircle, DrawText
118
+ └── /interactive # Game loop: loop(), keyboard(), mouse()
133
119
  ```
134
120
 
135
121
  ## Control Flow
@@ -138,89 +124,160 @@ Use native JavaScript for control flow - no special components needed:
138
124
 
139
125
  ```tsx
140
126
  // Conditional rendering
141
- {isLoggedIn() ? <Dashboard /> : <Login />}
127
+ {isLoggedIn ? <Dashboard /> : <Login />}
142
128
 
143
129
  // Short-circuit for simple conditions
144
- {isAdmin() && <AdminPanel />}
130
+ {isAdmin && <AdminPanel />}
145
131
 
146
- // List rendering with optimized reconciliation
132
+ // List rendering
147
133
  {items.map(item => <Item key={item.id} data={item} />)}
134
+ ```
135
+
136
+ ## Routing
137
+
138
+ ```tsx
139
+ import { Routes, Route, Link, router } from 'flexium/router'
140
+
141
+ function App() {
142
+ return (
143
+ <Routes>
144
+ <nav>
145
+ <Link to="/">Home</Link>
146
+ <Link to="/about">About</Link>
147
+ </nav>
148
+ <Route path="/" component={Home} />
149
+ <Route path="/about" component={About} />
150
+ <Route path="/users/:id" component={UserProfile} />
151
+ </Routes>
152
+ )
153
+ }
148
154
 
149
- // Pattern matching with ternary chains
150
- {status() === 'loading' ? <Loading /> :
151
- status() === 'error' ? <Error /> :
152
- status() === 'success' ? <Success /> :
153
- <Default />}
155
+ function UserProfile({ params }) {
156
+ return <h1>User: {params.id}</h1>
157
+ }
158
+
159
+ // Or use the router hook
160
+ function UserProfileHook() {
161
+ const r = router()
162
+ return <h1>User: {r.params.id}</h1>
163
+ }
154
164
  ```
155
165
 
156
166
  ## Canvas Rendering
157
167
 
158
168
  ```tsx
159
- import { Canvas, Rect, Circle, Text } from 'flexium/canvas';
169
+ import { Canvas, DrawRect, DrawCircle, DrawText } from 'flexium/canvas'
160
170
 
161
171
  function App() {
162
- const [x, setX] = state(100);
172
+ const [x, setX] = state(100)
163
173
 
164
174
  return (
165
175
  <Canvas width={400} height={300}>
166
- <Rect x={0} y={0} width={400} height={300} fill="#1a1a2e" />
167
- <Circle x={x} y={150} radius={30} fill="#e94560" />
168
- <Text x={200} y={50} text="Hello Canvas!" fill="white" />
176
+ <DrawRect x={0} y={0} width={400} height={300} fill="#1a1a2e" />
177
+ <DrawCircle x={x} y={150} radius={30} fill="#e94560" />
178
+ <DrawText x={200} y={50} text="Hello Canvas!" fill="white" />
169
179
  </Canvas>
170
- );
180
+ )
171
181
  }
172
182
  ```
173
183
 
174
- ## Cross-Platform Primitives
184
+ ## Game Development
175
185
 
176
186
  ```tsx
177
- import { Row, Column, Text, Pressable } from 'flexium/primitives';
187
+ import { state, effect } from 'flexium/core'
188
+ import { Canvas, DrawRect } from 'flexium/canvas'
189
+ import { loop, keyboard, Keys } from 'flexium/interactive'
190
+
191
+ function Game() {
192
+ const [x, setX] = state(100)
193
+ const kb = keyboard()
194
+
195
+ const gameLoop = loop({
196
+ fixedFps: 60,
197
+ onUpdate: (delta) => {
198
+ if (kb.isPressed(Keys.ArrowRight)) setX(x => x + 200 * delta)
199
+ if (kb.isPressed(Keys.ArrowLeft)) setX(x => x - 200 * delta)
200
+ }
201
+ })
202
+
203
+ effect(() => {
204
+ gameLoop.start()
205
+ return () => gameLoop.stop()
206
+ }, [])
178
207
 
179
- function App() {
180
208
  return (
181
- <Column gap={16} padding={20}>
182
- <Text size="xl" weight="bold">Welcome</Text>
183
- <Row gap={8}>
184
- <Pressable onPress={() => console.log('clicked')}>
185
- <Text>Click me</Text>
186
- </Pressable>
187
- </Row>
188
- </Column>
189
- );
209
+ <Canvas width={800} height={600}>
210
+ <DrawRect x={x} y={300} width={50} height={50} fill="red" />
211
+ </Canvas>
212
+ )
190
213
  }
191
214
  ```
192
215
 
193
- ## Routing
216
+ ## Server-Side Rendering
194
217
 
195
218
  ```tsx
196
- import { Routes, Route, Link } from 'flexium/router';
219
+ import { renderToString } from 'flexium/server'
220
+ import { hydrate } from 'flexium/dom'
221
+
222
+ // Server
223
+ const { html, state } = renderToString(App, { hydrate: true })
224
+
225
+ // Client
226
+ hydrate(App, document.getElementById('root'), { state })
227
+ ```
228
+
229
+ ## Built-in Components
230
+
231
+ ### Portal
232
+
233
+ ```tsx
234
+ import { Portal } from 'flexium/dom'
235
+
236
+ <Portal target={document.body}>
237
+ <Modal />
238
+ </Portal>
239
+ ```
240
+
241
+ ### Suspense
242
+
243
+ ```tsx
244
+ import { Suspense, lazy } from 'flexium/dom'
245
+
246
+ const LazyComponent = lazy(() => import('./Heavy'))
247
+
248
+ <Suspense fallback={<Loading />}>
249
+ <LazyComponent />
250
+ </Suspense>
251
+ ```
252
+
253
+ ### ErrorBoundary
254
+
255
+ ```tsx
256
+ import { ErrorBoundary } from 'flexium/dom'
257
+
258
+ <ErrorBoundary fallback={(error) => <Error message={error.message} />}>
259
+ <App />
260
+ </ErrorBoundary>
261
+ ```
262
+
263
+ ## Context API
264
+
265
+ ```tsx
266
+ import { createContext, context } from 'flexium/core'
267
+
268
+ const ThemeCtx = createContext('light')
197
269
 
198
270
  function App() {
199
271
  return (
200
- <Routes>
201
- <nav>
202
- <Link to="/">Home</Link>
203
- <Link to="/about">About</Link>
204
- </nav>
205
- <Route path="/" component={Home} />
206
- <Route path="/about" component={About} />
207
- <Route path="/users/:id" component={UserProfile} />
208
- </Routes>
209
- );
210
- }
211
-
212
- function UserProfile({ params }) {
213
- // Params are passed as props to the component
214
- return <h1>User: {params.id}</h1>;
272
+ <ThemeCtx.Provider value="dark">
273
+ <Child />
274
+ </ThemeCtx.Provider>
275
+ )
215
276
  }
216
277
 
217
- // Or use the router hook
218
- import { router } from 'flexium/router';
219
-
220
- function UserProfileHook() {
221
- const r = router();
222
- // Access params directly from router context
223
- return <h1>User: {r.params.id}</h1>;
278
+ function Child() {
279
+ const theme = context(ThemeCtx)
280
+ return <div>Theme: {theme}</div>
224
281
  }
225
282
  ```
226
283
 
package/dist/canvas.d.cts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { JSX } from './jsx-runtime.cjs';
2
- import './dom.cjs';
2
+ import './types-y2GGaXXk.cjs';
3
3
 
4
4
  interface CanvasProps {
5
5
  width: number;
@@ -8,8 +8,6 @@ interface CanvasProps {
8
8
  style?: any;
9
9
  ref?: (el: HTMLCanvasElement) => void;
10
10
  }
11
- declare function Canvas(props: CanvasProps): JSX.Element;
12
-
13
11
  interface DrawRectProps {
14
12
  x: number | (() => number);
15
13
  y: number | (() => number);
@@ -20,8 +18,6 @@ interface DrawRectProps {
20
18
  strokeWidth?: number | (() => number);
21
19
  opacity?: number | (() => number);
22
20
  }
23
- declare function DrawRect(props: DrawRectProps): null;
24
-
25
21
  interface DrawCircleProps {
26
22
  x: number | (() => number);
27
23
  y: number | (() => number);
@@ -31,8 +27,6 @@ interface DrawCircleProps {
31
27
  strokeWidth?: number | (() => number);
32
28
  opacity?: number | (() => number);
33
29
  }
34
- declare function DrawCircle(props: DrawCircleProps): null;
35
-
36
30
  interface DrawArcProps {
37
31
  x: number | (() => number);
38
32
  y: number | (() => number);
@@ -45,8 +39,6 @@ interface DrawArcProps {
45
39
  strokeWidth?: number | (() => number);
46
40
  opacity?: number | (() => number);
47
41
  }
48
- declare function DrawArc(props: DrawArcProps): null;
49
-
50
42
  interface DrawLineProps {
51
43
  x1: number | (() => number);
52
44
  y1: number | (() => number);
@@ -56,8 +48,6 @@ interface DrawLineProps {
56
48
  strokeWidth?: number | (() => number);
57
49
  opacity?: number | (() => number);
58
50
  }
59
- declare function DrawLine(props: DrawLineProps): null;
60
-
61
51
  interface DrawTextProps {
62
52
  text: string | (() => string);
63
53
  x: number | (() => number);
@@ -69,8 +59,6 @@ interface DrawTextProps {
69
59
  textAlign?: 'left' | 'center' | 'right';
70
60
  opacity?: number | (() => number);
71
61
  }
72
- declare function DrawText(props: DrawTextProps): null;
73
-
74
62
  interface DrawPathProps {
75
63
  d: string | (() => string);
76
64
  fill?: string | (() => string);
@@ -78,6 +66,19 @@ interface DrawPathProps {
78
66
  strokeWidth?: number | (() => number);
79
67
  opacity?: number | (() => number);
80
68
  }
69
+
70
+ declare function Canvas(props: CanvasProps): JSX.Element;
71
+
72
+ declare function DrawRect(props: DrawRectProps): null;
73
+
74
+ declare function DrawCircle(props: DrawCircleProps): null;
75
+
76
+ declare function DrawArc(props: DrawArcProps): null;
77
+
78
+ declare function DrawLine(props: DrawLineProps): null;
79
+
80
+ declare function DrawText(props: DrawTextProps): null;
81
+
81
82
  declare function DrawPath(props: DrawPathProps): null;
82
83
 
83
84
  export { Canvas, type CanvasProps, DrawArc, type DrawArcProps, DrawCircle, type DrawCircleProps, DrawLine, type DrawLineProps, DrawPath, type DrawPathProps, DrawRect, type DrawRectProps, DrawText, type DrawTextProps };
package/dist/canvas.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { JSX } from './jsx-runtime.js';
2
- import './dom.js';
2
+ import './types-y2GGaXXk.js';
3
3
 
4
4
  interface CanvasProps {
5
5
  width: number;
@@ -8,8 +8,6 @@ interface CanvasProps {
8
8
  style?: any;
9
9
  ref?: (el: HTMLCanvasElement) => void;
10
10
  }
11
- declare function Canvas(props: CanvasProps): JSX.Element;
12
-
13
11
  interface DrawRectProps {
14
12
  x: number | (() => number);
15
13
  y: number | (() => number);
@@ -20,8 +18,6 @@ interface DrawRectProps {
20
18
  strokeWidth?: number | (() => number);
21
19
  opacity?: number | (() => number);
22
20
  }
23
- declare function DrawRect(props: DrawRectProps): null;
24
-
25
21
  interface DrawCircleProps {
26
22
  x: number | (() => number);
27
23
  y: number | (() => number);
@@ -31,8 +27,6 @@ interface DrawCircleProps {
31
27
  strokeWidth?: number | (() => number);
32
28
  opacity?: number | (() => number);
33
29
  }
34
- declare function DrawCircle(props: DrawCircleProps): null;
35
-
36
30
  interface DrawArcProps {
37
31
  x: number | (() => number);
38
32
  y: number | (() => number);
@@ -45,8 +39,6 @@ interface DrawArcProps {
45
39
  strokeWidth?: number | (() => number);
46
40
  opacity?: number | (() => number);
47
41
  }
48
- declare function DrawArc(props: DrawArcProps): null;
49
-
50
42
  interface DrawLineProps {
51
43
  x1: number | (() => number);
52
44
  y1: number | (() => number);
@@ -56,8 +48,6 @@ interface DrawLineProps {
56
48
  strokeWidth?: number | (() => number);
57
49
  opacity?: number | (() => number);
58
50
  }
59
- declare function DrawLine(props: DrawLineProps): null;
60
-
61
51
  interface DrawTextProps {
62
52
  text: string | (() => string);
63
53
  x: number | (() => number);
@@ -69,8 +59,6 @@ interface DrawTextProps {
69
59
  textAlign?: 'left' | 'center' | 'right';
70
60
  opacity?: number | (() => number);
71
61
  }
72
- declare function DrawText(props: DrawTextProps): null;
73
-
74
62
  interface DrawPathProps {
75
63
  d: string | (() => string);
76
64
  fill?: string | (() => string);
@@ -78,6 +66,19 @@ interface DrawPathProps {
78
66
  strokeWidth?: number | (() => number);
79
67
  opacity?: number | (() => number);
80
68
  }
69
+
70
+ declare function Canvas(props: CanvasProps): JSX.Element;
71
+
72
+ declare function DrawRect(props: DrawRectProps): null;
73
+
74
+ declare function DrawCircle(props: DrawCircleProps): null;
75
+
76
+ declare function DrawArc(props: DrawArcProps): null;
77
+
78
+ declare function DrawLine(props: DrawLineProps): null;
79
+
80
+ declare function DrawText(props: DrawTextProps): null;
81
+
81
82
  declare function DrawPath(props: DrawPathProps): null;
82
83
 
83
84
  export { Canvas, type CanvasProps, DrawArc, type DrawArcProps, DrawCircle, type DrawCircleProps, DrawLine, type DrawLineProps, DrawPath, type DrawPathProps, DrawRect, type DrawRectProps, DrawText, type DrawTextProps };
package/dist/canvas.js CHANGED
@@ -1,2 +1,2 @@
1
- 'use strict';var chunkIA4FEBFE_js=require('./chunk-IA4FEBFE.js'),chunk7BXR4ZFD_js=require('./chunk-7BXR4ZFD.js');require('./chunk-ENWGYQNU.js');var chunkEXLNKYSH_js=require('./chunk-EXLNKYSH.js');var h=[];function u(e){h.push(e);}function D(e){let{width:p,height:b,children:r,style:m,ref:a}=e,i,o=null,s=()=>{!i||!o||(o.clearRect(0,0,p,b),h.length=0,Array.isArray(r)?r.forEach(n=>{typeof n=="function"&&n();}):typeof r=="function"&&r(),h.forEach(n=>{P(o,n);}),null);};return chunkIA4FEBFE_js.a(()=>{i&&s();}),chunkEXLNKYSH_js.a("canvas",{ref:n=>{i=n,o=n.getContext("2d"),a&&a(n),s();},width:p,height:b,style:m})}function t(e){return chunk7BXR4ZFD_js.b(e)?e.valueOf?.()??e:e}function P(e,p){let{type:b,props:r}=p,m=t(r.opacity);switch(m!==void 0&&(e.globalAlpha=m),b){case "rect":{let a=t(r.x),i=t(r.y),o=t(r.width),s=t(r.height),n=t(r.fill),f=t(r.stroke),c=t(r.strokeWidth);n&&(e.fillStyle=n,e.fillRect(a,i,o,s)),f&&(e.strokeStyle=f,c&&(e.lineWidth=c),e.strokeRect(a,i,o,s));break}case "circle":{let a=t(r.x),i=t(r.y),o=t(r.radius),s=t(r.fill),n=t(r.stroke),f=t(r.strokeWidth);e.beginPath(),e.arc(a,i,o,0,Math.PI*2),s&&(e.fillStyle=s,e.fill()),n&&(e.strokeStyle=n,f&&(e.lineWidth=f),e.stroke());break}case "arc":{let a=t(r.x),i=t(r.y),o=t(r.radius),s=t(r.startAngle),n=t(r.endAngle),f=t(r.counterclockwise)||false,c=t(r.fill),y=t(r.stroke),g=t(r.strokeWidth);e.beginPath(),e.arc(a,i,o,s,n,f),c&&(e.fillStyle=c,e.fill()),y&&(e.strokeStyle=y,g&&(e.lineWidth=g),e.stroke());break}case "line":{let a=t(r.x1),i=t(r.y1),o=t(r.x2),s=t(r.y2),n=t(r.stroke)||"black",f=t(r.strokeWidth)||1;e.beginPath(),e.moveTo(a,i),e.lineTo(o,s),e.strokeStyle=n,e.lineWidth=f,e.stroke();break}case "text":{let a=t(r.x),i=t(r.y),o=t(r.text),s=t(r.fill)||"black",n=t(r.fontSize)||16,f=t(r.fontFamily)||"sans-serif",c=t(r.fontWeight)||"normal",y=t(r.textAlign)||"left";e.font=`${c} ${n}px ${f}`,e.textAlign=y,e.fillStyle=s,e.fillText(o,a,i);break}case "path":{let a=t(r.d),i=t(r.fill),o=t(r.stroke),s=t(r.strokeWidth),n=new Path2D(a);i&&(e.fillStyle=i,e.fill(n)),o&&(e.strokeStyle=o,s&&(e.lineWidth=s),e.stroke(n));break}}m!==void 0&&(e.globalAlpha=1);}function x(e){return chunkIA4FEBFE_js.a(()=>{u({type:"rect",props:e});}),null}function C(e){return chunkIA4FEBFE_js.a(()=>{u({type:"circle",props:e});}),null}function W(e){return chunkIA4FEBFE_js.a(()=>{u({type:"arc",props:e});}),null}function v(e){return chunkIA4FEBFE_js.a(()=>{u({type:"line",props:e});}),null}function A(e){return chunkIA4FEBFE_js.a(()=>{u({type:"text",props:e});}),null}function S(e){return chunkIA4FEBFE_js.a(()=>{u({type:"path",props:e});}),null}exports.Canvas=D;exports.DrawArc=W;exports.DrawCircle=C;exports.DrawLine=v;exports.DrawPath=S;exports.DrawRect=x;exports.DrawText=A;//# sourceMappingURL=canvas.js.map
1
+ 'use strict';var chunk6VIRXD2Y_js=require('./chunk-6VIRXD2Y.js'),chunkYWTD32NA_js=require('./chunk-YWTD32NA.js');require('./chunk-UWFVCKRU.js');var chunkEXLNKYSH_js=require('./chunk-EXLNKYSH.js');var D=[];function l(t){D.push(t);}function C(t){let{width:u,height:w,children:e,style:y,ref:a}=t,s,n=null,i=()=>{!s||!n||(n.clearRect(0,0,u,w),D.length=0,Array.isArray(e)?e.forEach(o=>{typeof o=="function"&&o();}):typeof e=="function"&&e(),D.forEach(o=>{g(n,o);}),null);};return chunkYWTD32NA_js.e(()=>{s&&i();}),chunkEXLNKYSH_js.a("canvas",{ref:o=>{s=o,n=o.getContext("2d"),a&&a(o),i();},width:u,height:w,style:y})}function r(t){return chunk6VIRXD2Y_js.b(t)?t.valueOf?.()??t:t}function g(t,u){let{type:w,props:e}=u,y=r(e.opacity);switch(y!==void 0&&(t.globalAlpha=y),w){case "rect":{let a=r(e.x),s=r(e.y),n=r(e.width),i=r(e.height),o=r(e.fill),f=r(e.stroke),c=r(e.strokeWidth);o&&(t.fillStyle=o,t.fillRect(a,s,n,i)),f&&(t.strokeStyle=f,c&&(t.lineWidth=c),t.strokeRect(a,s,n,i));break}case "circle":{let a=r(e.x),s=r(e.y),n=r(e.radius),i=r(e.fill),o=r(e.stroke),f=r(e.strokeWidth);t.beginPath(),t.arc(a,s,n,0,Math.PI*2),i&&(t.fillStyle=i,t.fill()),o&&(t.strokeStyle=o,f&&(t.lineWidth=f),t.stroke());break}case "arc":{let a=r(e.x),s=r(e.y),n=r(e.radius),i=r(e.startAngle),o=r(e.endAngle),f=r(e.counterclockwise)||false,c=r(e.fill),m=r(e.stroke),h=r(e.strokeWidth);t.beginPath(),t.arc(a,s,n,i,o,f),c&&(t.fillStyle=c,t.fill()),m&&(t.strokeStyle=m,h&&(t.lineWidth=h),t.stroke());break}case "line":{let a=r(e.x1),s=r(e.y1),n=r(e.x2),i=r(e.y2),o=r(e.stroke)||"black",f=r(e.strokeWidth)||1;t.beginPath(),t.moveTo(a,s),t.lineTo(n,i),t.strokeStyle=o,t.lineWidth=f,t.stroke();break}case "text":{let a=r(e.x),s=r(e.y),n=r(e.text),i=r(e.fill)||"black",o=r(e.fontSize)||16,f=r(e.fontFamily)||"sans-serif",c=r(e.fontWeight)||"normal",m=r(e.textAlign)||"left";t.font=`${c} ${o}px ${f}`,t.textAlign=m,t.fillStyle=i,t.fillText(n,a,s);break}case "path":{let a=r(e.d),s=r(e.fill),n=r(e.stroke),i=r(e.strokeWidth),o=new Path2D(a);s&&(t.fillStyle=s,t.fill(o)),n&&(t.strokeStyle=n,i&&(t.lineWidth=i),t.stroke(o));break}}y!==void 0&&(t.globalAlpha=1);}function x(t){return chunkYWTD32NA_js.e(()=>{l({type:"rect",props:t});}),null}function v(t){return chunkYWTD32NA_js.e(()=>{l({type:"circle",props:t});}),null}function A(t){return chunkYWTD32NA_js.e(()=>{l({type:"arc",props:t});}),null}function W(t){return chunkYWTD32NA_js.e(()=>{l({type:"line",props:t});}),null}function b(t){return chunkYWTD32NA_js.e(()=>{l({type:"text",props:t});}),null}function R(t){return chunkYWTD32NA_js.e(()=>{l({type:"path",props:t});}),null}exports.Canvas=C;exports.DrawArc=A;exports.DrawCircle=v;exports.DrawLine=W;exports.DrawPath=R;exports.DrawRect=x;exports.DrawText=b;//# sourceMappingURL=canvas.js.map
2
2
  //# sourceMappingURL=canvas.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/canvas/Canvas.tsx","../src/canvas/dom/DrawRect.tsx","../src/canvas/dom/DrawCircle.tsx","../src/canvas/dom/DrawArc.tsx","../src/canvas/dom/DrawLine.tsx","../src/canvas/dom/DrawText.tsx","../src/canvas/dom/DrawPath.tsx"],"names":["drawQueue","queueDraw","node","Canvas","props","width","height","children","style","ref","canvas","ctx","render","child","drawNode","effect","jsx","el","getValue","val","isReactive","type","opacity","x","y","w","h","fill","stroke","strokeWidth","radius","startAngle","endAngle","counterclockwise","x1","y1","x2","y2","text","fontSize","fontFamily","fontWeight","textAlign","d","path","DrawRect","DrawCircle","DrawArc","DrawLine","DrawText","DrawPath"],"mappings":"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","file":"canvas.js","sourcesContent":["import { effect } from '../core/lifecycle'\nimport { isReactive } from '../core/reactive'\n\nexport interface CanvasProps {\n width: number\n height: number\n children?: any\n style?: any\n ref?: (el: HTMLCanvasElement) => void\n}\n\ninterface CanvasDrawNode {\n type: 'rect' | 'circle' | 'arc' | 'line' | 'text' | 'path'\n props: any\n}\n\n// Canvas context for children to access\nlet currentCanvasContext: CanvasRenderingContext2D | null = null\nconst drawQueue: CanvasDrawNode[] = []\n\nexport function getCanvasContext() {\n return currentCanvasContext\n}\n\nexport function queueDraw(node: CanvasDrawNode) {\n drawQueue.push(node)\n}\n\nexport function Canvas(props: CanvasProps) {\n const { width, height, children, style, ref } = props\n\n let canvas: HTMLCanvasElement | undefined\n let ctx: CanvasRenderingContext2D | null = null\n\n const render = () => {\n if (!canvas || !ctx) return\n\n // Clear canvas\n ctx.clearRect(0, 0, width, height)\n\n // Clear draw queue\n drawQueue.length = 0\n\n // Set current context for children\n currentCanvasContext = ctx\n\n // Render children (they will queue draw commands)\n if (Array.isArray(children)) {\n children.forEach(child => {\n if (typeof child === 'function') {\n child()\n }\n })\n } else if (typeof children === 'function') {\n children()\n }\n\n // Execute draw queue\n drawQueue.forEach(node => {\n drawNode(ctx!, node)\n })\n\n // Clear context\n currentCanvasContext = null\n }\n\n effect(() => {\n if (canvas) {\n render()\n }\n })\n\n return (\n <canvas\n ref={(el: HTMLCanvasElement) => {\n canvas = el\n ctx = el.getContext('2d')\n if (ref) ref(el)\n render()\n }}\n width={width}\n height={height}\n style={style}\n />\n )\n}\n\nfunction getValue(val: any): any {\n if (isReactive(val)) {\n return val.valueOf?.() ?? val\n }\n return val\n}\n\nfunction drawNode(ctx: CanvasRenderingContext2D, node: CanvasDrawNode) {\n const { type, props } = node\n\n // Apply opacity\n const opacity = getValue(props.opacity)\n if (opacity !== undefined) {\n ctx.globalAlpha = opacity\n }\n\n switch (type) {\n case 'rect': {\n const x = getValue(props.x)\n const y = getValue(props.y)\n const w = getValue(props.width)\n const h = getValue(props.height)\n const fill = getValue(props.fill)\n const stroke = getValue(props.stroke)\n const strokeWidth = getValue(props.strokeWidth)\n\n if (fill) {\n ctx.fillStyle = fill\n ctx.fillRect(x, y, w, h)\n }\n\n if (stroke) {\n ctx.strokeStyle = stroke\n if (strokeWidth) ctx.lineWidth = strokeWidth\n ctx.strokeRect(x, y, w, h)\n }\n break\n }\n\n case 'circle': {\n const x = getValue(props.x)\n const y = getValue(props.y)\n const radius = getValue(props.radius)\n const fill = getValue(props.fill)\n const stroke = getValue(props.stroke)\n const strokeWidth = getValue(props.strokeWidth)\n\n ctx.beginPath()\n ctx.arc(x, y, radius, 0, Math.PI * 2)\n\n if (fill) {\n ctx.fillStyle = fill\n ctx.fill()\n }\n\n if (stroke) {\n ctx.strokeStyle = stroke\n if (strokeWidth) ctx.lineWidth = strokeWidth\n ctx.stroke()\n }\n break\n }\n\n case 'arc': {\n const x = getValue(props.x)\n const y = getValue(props.y)\n const radius = getValue(props.radius)\n const startAngle = getValue(props.startAngle)\n const endAngle = getValue(props.endAngle)\n const counterclockwise = getValue(props.counterclockwise) || false\n const fill = getValue(props.fill)\n const stroke = getValue(props.stroke)\n const strokeWidth = getValue(props.strokeWidth)\n\n ctx.beginPath()\n ctx.arc(x, y, radius, startAngle, endAngle, counterclockwise)\n\n if (fill) {\n ctx.fillStyle = fill\n ctx.fill()\n }\n\n if (stroke) {\n ctx.strokeStyle = stroke\n if (strokeWidth) ctx.lineWidth = strokeWidth\n ctx.stroke()\n }\n break\n }\n\n case 'line': {\n const x1 = getValue(props.x1)\n const y1 = getValue(props.y1)\n const x2 = getValue(props.x2)\n const y2 = getValue(props.y2)\n const stroke = getValue(props.stroke) || 'black'\n const strokeWidth = getValue(props.strokeWidth) || 1\n\n ctx.beginPath()\n ctx.moveTo(x1, y1)\n ctx.lineTo(x2, y2)\n ctx.strokeStyle = stroke\n ctx.lineWidth = strokeWidth\n ctx.stroke()\n break\n }\n\n case 'text': {\n const x = getValue(props.x)\n const y = getValue(props.y)\n const text = getValue(props.text)\n const fill = getValue(props.fill) || 'black'\n const fontSize = getValue(props.fontSize) || 16\n const fontFamily = getValue(props.fontFamily) || 'sans-serif'\n const fontWeight = getValue(props.fontWeight) || 'normal'\n const textAlign = getValue(props.textAlign) || 'left'\n\n ctx.font = `${fontWeight} ${fontSize}px ${fontFamily}`\n ctx.textAlign = textAlign as CanvasTextAlign\n ctx.fillStyle = fill\n ctx.fillText(text, x, y)\n break\n }\n\n case 'path': {\n const d = getValue(props.d)\n const fill = getValue(props.fill)\n const stroke = getValue(props.stroke)\n const strokeWidth = getValue(props.strokeWidth)\n\n // Parse SVG path data\n const path = new Path2D(d)\n\n if (fill) {\n ctx.fillStyle = fill\n ctx.fill(path)\n }\n\n if (stroke) {\n ctx.strokeStyle = stroke\n if (strokeWidth) ctx.lineWidth = strokeWidth\n ctx.stroke(path)\n }\n break\n }\n }\n\n // Reset opacity\n if (opacity !== undefined) {\n ctx.globalAlpha = 1\n }\n}\n","import { effect } from '../../core/lifecycle'\nimport { queueDraw } from '../Canvas'\n\nexport interface DrawRectProps {\n x: number | (() => number)\n y: number | (() => number)\n width: number | (() => number)\n height: number | (() => number)\n fill?: string | (() => string)\n stroke?: string | (() => string)\n strokeWidth?: number | (() => number)\n opacity?: number | (() => number)\n}\n\nexport function DrawRect(props: DrawRectProps) {\n effect(() => {\n queueDraw({\n type: 'rect',\n props\n })\n })\n\n return null\n}\n","import { effect } from '../../core/lifecycle'\nimport { queueDraw } from '../Canvas'\n\nexport interface DrawCircleProps {\n x: number | (() => number)\n y: number | (() => number)\n radius: number | (() => number)\n fill?: string | (() => string)\n stroke?: string | (() => string)\n strokeWidth?: number | (() => number)\n opacity?: number | (() => number)\n}\n\nexport function DrawCircle(props: DrawCircleProps) {\n effect(() => {\n queueDraw({\n type: 'circle',\n props\n })\n })\n\n return null\n}\n","import { effect } from '../../core/lifecycle'\nimport { queueDraw } from '../Canvas'\n\nexport interface DrawArcProps {\n x: number | (() => number)\n y: number | (() => number)\n radius: number | (() => number)\n startAngle: number | (() => number)\n endAngle: number | (() => number)\n counterclockwise?: boolean\n fill?: string | (() => string)\n stroke?: string | (() => string)\n strokeWidth?: number | (() => number)\n opacity?: number | (() => number)\n}\n\nexport function DrawArc(props: DrawArcProps) {\n effect(() => {\n queueDraw({\n type: 'arc',\n props\n })\n })\n\n return null\n}\n","import { effect } from '../../core/lifecycle'\nimport { queueDraw } from '../Canvas'\n\nexport interface DrawLineProps {\n x1: number | (() => number)\n y1: number | (() => number)\n x2: number | (() => number)\n y2: number | (() => number)\n stroke?: string | (() => string)\n strokeWidth?: number | (() => number)\n opacity?: number | (() => number)\n}\n\nexport function DrawLine(props: DrawLineProps) {\n effect(() => {\n queueDraw({\n type: 'line',\n props\n })\n })\n\n return null\n}\n","import { effect } from '../../core/lifecycle'\nimport { queueDraw } from '../Canvas'\n\nexport interface DrawTextProps {\n text: string | (() => string)\n x: number | (() => number)\n y: number | (() => number)\n fill?: string | (() => string)\n fontSize?: number | (() => number)\n fontFamily?: string | (() => string)\n fontWeight?: string | (() => string)\n textAlign?: 'left' | 'center' | 'right'\n opacity?: number | (() => number)\n}\n\nexport function DrawText(props: DrawTextProps) {\n effect(() => {\n queueDraw({\n type: 'text',\n props\n })\n })\n\n return null\n}\n","import { effect } from '../../core/lifecycle'\nimport { queueDraw } from '../Canvas'\n\nexport interface DrawPathProps {\n d: string | (() => string)\n fill?: string | (() => string)\n stroke?: string | (() => string)\n strokeWidth?: number | (() => number)\n opacity?: number | (() => number)\n}\n\nexport function DrawPath(props: DrawPathProps) {\n effect(() => {\n queueDraw({\n type: 'path',\n props\n })\n })\n\n return null\n}\n"]}
1
+ {"version":3,"sources":["../src/canvas/Canvas.tsx","../src/canvas/dom/DrawRect.tsx","../src/canvas/dom/DrawCircle.tsx","../src/canvas/dom/DrawArc.tsx","../src/canvas/dom/DrawLine.tsx","../src/canvas/dom/DrawText.tsx","../src/canvas/dom/DrawPath.tsx"],"names":["drawQueue","queueDraw","node","Canvas","props","width","height","children","style","ref","canvas","ctx","render","child","drawNode","effect","jsx","el","getValue","val","isReactive","type","opacity","x","y","w","h","fill","stroke","strokeWidth","radius","startAngle","endAngle","counterclockwise","x1","y1","x2","y2","text","fontSize","fontFamily","fontWeight","textAlign","d","path","DrawRect","DrawCircle","DrawArc","DrawLine","DrawText","DrawPath"],"mappings":"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","file":"canvas.js","sourcesContent":["import { effect } from '../core/lifecycle'\nimport { isReactive } from '../core/reactive'\nimport type { CanvasProps, CanvasDrawNode } from './types'\n\nexport type { CanvasProps }\n\n// Canvas context for children to access\nlet currentCanvasContext: CanvasRenderingContext2D | null = null\nconst drawQueue: CanvasDrawNode[] = []\n\nexport function getCanvasContext() {\n return currentCanvasContext\n}\n\nexport function queueDraw(node: CanvasDrawNode) {\n drawQueue.push(node)\n}\n\nexport function Canvas(props: CanvasProps) {\n const { width, height, children, style, ref } = props\n\n let canvas: HTMLCanvasElement | undefined\n let ctx: CanvasRenderingContext2D | null = null\n\n const render = () => {\n if (!canvas || !ctx) return\n\n // Clear canvas\n ctx.clearRect(0, 0, width, height)\n\n // Clear draw queue\n drawQueue.length = 0\n\n // Set current context for children\n currentCanvasContext = ctx\n\n // Render children (they will queue draw commands)\n if (Array.isArray(children)) {\n children.forEach(child => {\n if (typeof child === 'function') {\n child()\n }\n })\n } else if (typeof children === 'function') {\n children()\n }\n\n // Execute draw queue\n drawQueue.forEach(node => {\n drawNode(ctx!, node)\n })\n\n // Clear context\n currentCanvasContext = null\n }\n\n effect(() => {\n if (canvas) {\n render()\n }\n })\n\n return (\n <canvas\n ref={(el: HTMLCanvasElement) => {\n canvas = el\n ctx = el.getContext('2d')\n if (ref) ref(el)\n render()\n }}\n width={width}\n height={height}\n style={style}\n />\n )\n}\n\nfunction getValue(val: any): any {\n if (isReactive(val)) {\n return val.valueOf?.() ?? val\n }\n return val\n}\n\nfunction drawNode(ctx: CanvasRenderingContext2D, node: CanvasDrawNode) {\n const { type, props } = node\n\n // Apply opacity\n const opacity = getValue(props.opacity)\n if (opacity !== undefined) {\n ctx.globalAlpha = opacity\n }\n\n switch (type) {\n case 'rect': {\n const x = getValue(props.x)\n const y = getValue(props.y)\n const w = getValue(props.width)\n const h = getValue(props.height)\n const fill = getValue(props.fill)\n const stroke = getValue(props.stroke)\n const strokeWidth = getValue(props.strokeWidth)\n\n if (fill) {\n ctx.fillStyle = fill\n ctx.fillRect(x, y, w, h)\n }\n\n if (stroke) {\n ctx.strokeStyle = stroke\n if (strokeWidth) ctx.lineWidth = strokeWidth\n ctx.strokeRect(x, y, w, h)\n }\n break\n }\n\n case 'circle': {\n const x = getValue(props.x)\n const y = getValue(props.y)\n const radius = getValue(props.radius)\n const fill = getValue(props.fill)\n const stroke = getValue(props.stroke)\n const strokeWidth = getValue(props.strokeWidth)\n\n ctx.beginPath()\n ctx.arc(x, y, radius, 0, Math.PI * 2)\n\n if (fill) {\n ctx.fillStyle = fill\n ctx.fill()\n }\n\n if (stroke) {\n ctx.strokeStyle = stroke\n if (strokeWidth) ctx.lineWidth = strokeWidth\n ctx.stroke()\n }\n break\n }\n\n case 'arc': {\n const x = getValue(props.x)\n const y = getValue(props.y)\n const radius = getValue(props.radius)\n const startAngle = getValue(props.startAngle)\n const endAngle = getValue(props.endAngle)\n const counterclockwise = getValue(props.counterclockwise) || false\n const fill = getValue(props.fill)\n const stroke = getValue(props.stroke)\n const strokeWidth = getValue(props.strokeWidth)\n\n ctx.beginPath()\n ctx.arc(x, y, radius, startAngle, endAngle, counterclockwise)\n\n if (fill) {\n ctx.fillStyle = fill\n ctx.fill()\n }\n\n if (stroke) {\n ctx.strokeStyle = stroke\n if (strokeWidth) ctx.lineWidth = strokeWidth\n ctx.stroke()\n }\n break\n }\n\n case 'line': {\n const x1 = getValue(props.x1)\n const y1 = getValue(props.y1)\n const x2 = getValue(props.x2)\n const y2 = getValue(props.y2)\n const stroke = getValue(props.stroke) || 'black'\n const strokeWidth = getValue(props.strokeWidth) || 1\n\n ctx.beginPath()\n ctx.moveTo(x1, y1)\n ctx.lineTo(x2, y2)\n ctx.strokeStyle = stroke\n ctx.lineWidth = strokeWidth\n ctx.stroke()\n break\n }\n\n case 'text': {\n const x = getValue(props.x)\n const y = getValue(props.y)\n const text = getValue(props.text)\n const fill = getValue(props.fill) || 'black'\n const fontSize = getValue(props.fontSize) || 16\n const fontFamily = getValue(props.fontFamily) || 'sans-serif'\n const fontWeight = getValue(props.fontWeight) || 'normal'\n const textAlign = getValue(props.textAlign) || 'left'\n\n ctx.font = `${fontWeight} ${fontSize}px ${fontFamily}`\n ctx.textAlign = textAlign as CanvasTextAlign\n ctx.fillStyle = fill\n ctx.fillText(text, x, y)\n break\n }\n\n case 'path': {\n const d = getValue(props.d)\n const fill = getValue(props.fill)\n const stroke = getValue(props.stroke)\n const strokeWidth = getValue(props.strokeWidth)\n\n // Parse SVG path data\n const path = new Path2D(d)\n\n if (fill) {\n ctx.fillStyle = fill\n ctx.fill(path)\n }\n\n if (stroke) {\n ctx.strokeStyle = stroke\n if (strokeWidth) ctx.lineWidth = strokeWidth\n ctx.stroke(path)\n }\n break\n }\n }\n\n // Reset opacity\n if (opacity !== undefined) {\n ctx.globalAlpha = 1\n }\n}\n","import { effect } from '../../core/lifecycle'\nimport { queueDraw } from '../Canvas'\nimport type { DrawRectProps } from '../types'\n\nexport type { DrawRectProps }\n\nexport function DrawRect(props: DrawRectProps) {\n effect(() => {\n queueDraw({\n type: 'rect',\n props\n })\n })\n\n return null\n}\n","import { effect } from '../../core/lifecycle'\nimport { queueDraw } from '../Canvas'\nimport type { DrawCircleProps } from '../types'\n\nexport type { DrawCircleProps }\n\nexport function DrawCircle(props: DrawCircleProps) {\n effect(() => {\n queueDraw({\n type: 'circle',\n props\n })\n })\n\n return null\n}\n","import { effect } from '../../core/lifecycle'\nimport { queueDraw } from '../Canvas'\nimport type { DrawArcProps } from '../types'\n\nexport type { DrawArcProps }\n\nexport function DrawArc(props: DrawArcProps) {\n effect(() => {\n queueDraw({\n type: 'arc',\n props\n })\n })\n\n return null\n}\n","import { effect } from '../../core/lifecycle'\nimport { queueDraw } from '../Canvas'\nimport type { DrawLineProps } from '../types'\n\nexport type { DrawLineProps }\n\nexport function DrawLine(props: DrawLineProps) {\n effect(() => {\n queueDraw({\n type: 'line',\n props\n })\n })\n\n return null\n}\n","import { effect } from '../../core/lifecycle'\nimport { queueDraw } from '../Canvas'\nimport type { DrawTextProps } from '../types'\n\nexport type { DrawTextProps }\n\nexport function DrawText(props: DrawTextProps) {\n effect(() => {\n queueDraw({\n type: 'text',\n props\n })\n })\n\n return null\n}\n","import { effect } from '../../core/lifecycle'\nimport { queueDraw } from '../Canvas'\nimport type { DrawPathProps } from '../types'\n\nexport type { DrawPathProps }\n\nexport function DrawPath(props: DrawPathProps) {\n effect(() => {\n queueDraw({\n type: 'path',\n props\n })\n })\n\n return null\n}\n"]}
package/dist/canvas.mjs CHANGED
@@ -1,2 +1,2 @@
1
- import {a as a$1}from'./chunk-S6WF3XNF.mjs';import {b}from'./chunk-CPJRQL2C.mjs';import'./chunk-44RZHCII.mjs';import {a}from'./chunk-ZCO4NIGC.mjs';var h=[];function u(e){h.push(e);}function D(e){let{width:p,height:b,children:r,style:m,ref:a$2}=e,i,o=null,s=()=>{!i||!o||(o.clearRect(0,0,p,b),h.length=0,Array.isArray(r)?r.forEach(n=>{typeof n=="function"&&n();}):typeof r=="function"&&r(),h.forEach(n=>{P(o,n);}),null);};return a$1(()=>{i&&s();}),a("canvas",{ref:n=>{i=n,o=n.getContext("2d"),a$2&&a$2(n),s();},width:p,height:b,style:m})}function t(e){return b(e)?e.valueOf?.()??e:e}function P(e,p){let{type:b,props:r}=p,m=t(r.opacity);switch(m!==void 0&&(e.globalAlpha=m),b){case "rect":{let a=t(r.x),i=t(r.y),o=t(r.width),s=t(r.height),n=t(r.fill),f=t(r.stroke),c=t(r.strokeWidth);n&&(e.fillStyle=n,e.fillRect(a,i,o,s)),f&&(e.strokeStyle=f,c&&(e.lineWidth=c),e.strokeRect(a,i,o,s));break}case "circle":{let a=t(r.x),i=t(r.y),o=t(r.radius),s=t(r.fill),n=t(r.stroke),f=t(r.strokeWidth);e.beginPath(),e.arc(a,i,o,0,Math.PI*2),s&&(e.fillStyle=s,e.fill()),n&&(e.strokeStyle=n,f&&(e.lineWidth=f),e.stroke());break}case "arc":{let a=t(r.x),i=t(r.y),o=t(r.radius),s=t(r.startAngle),n=t(r.endAngle),f=t(r.counterclockwise)||false,c=t(r.fill),y=t(r.stroke),g=t(r.strokeWidth);e.beginPath(),e.arc(a,i,o,s,n,f),c&&(e.fillStyle=c,e.fill()),y&&(e.strokeStyle=y,g&&(e.lineWidth=g),e.stroke());break}case "line":{let a=t(r.x1),i=t(r.y1),o=t(r.x2),s=t(r.y2),n=t(r.stroke)||"black",f=t(r.strokeWidth)||1;e.beginPath(),e.moveTo(a,i),e.lineTo(o,s),e.strokeStyle=n,e.lineWidth=f,e.stroke();break}case "text":{let a=t(r.x),i=t(r.y),o=t(r.text),s=t(r.fill)||"black",n=t(r.fontSize)||16,f=t(r.fontFamily)||"sans-serif",c=t(r.fontWeight)||"normal",y=t(r.textAlign)||"left";e.font=`${c} ${n}px ${f}`,e.textAlign=y,e.fillStyle=s,e.fillText(o,a,i);break}case "path":{let a=t(r.d),i=t(r.fill),o=t(r.stroke),s=t(r.strokeWidth),n=new Path2D(a);i&&(e.fillStyle=i,e.fill(n)),o&&(e.strokeStyle=o,s&&(e.lineWidth=s),e.stroke(n));break}}m!==void 0&&(e.globalAlpha=1);}function x(e){return a$1(()=>{u({type:"rect",props:e});}),null}function C(e){return a$1(()=>{u({type:"circle",props:e});}),null}function W(e){return a$1(()=>{u({type:"arc",props:e});}),null}function v(e){return a$1(()=>{u({type:"line",props:e});}),null}function A(e){return a$1(()=>{u({type:"text",props:e});}),null}function S(e){return a$1(()=>{u({type:"path",props:e});}),null}export{D as Canvas,W as DrawArc,C as DrawCircle,v as DrawLine,S as DrawPath,x as DrawRect,A as DrawText};//# sourceMappingURL=canvas.mjs.map
1
+ import {b as b$1}from'./chunk-JY6CE6RN.mjs';import {e}from'./chunk-IWFEXW4F.mjs';import'./chunk-5PNH2ARD.mjs';import {a}from'./chunk-ZCO4NIGC.mjs';var D=[];function l(t){D.push(t);}function C(t){let{width:u,height:w,children:e$1,style:y,ref:a$1}=t,s,n=null,i=()=>{!s||!n||(n.clearRect(0,0,u,w),D.length=0,Array.isArray(e$1)?e$1.forEach(o=>{typeof o=="function"&&o();}):typeof e$1=="function"&&e$1(),D.forEach(o=>{g(n,o);}),null);};return e(()=>{s&&i();}),a("canvas",{ref:o=>{s=o,n=o.getContext("2d"),a$1&&a$1(o),i();},width:u,height:w,style:y})}function r(t){return b$1(t)?t.valueOf?.()??t:t}function g(t,u){let{type:w,props:e}=u,y=r(e.opacity);switch(y!==void 0&&(t.globalAlpha=y),w){case "rect":{let a=r(e.x),s=r(e.y),n=r(e.width),i=r(e.height),o=r(e.fill),f=r(e.stroke),c=r(e.strokeWidth);o&&(t.fillStyle=o,t.fillRect(a,s,n,i)),f&&(t.strokeStyle=f,c&&(t.lineWidth=c),t.strokeRect(a,s,n,i));break}case "circle":{let a=r(e.x),s=r(e.y),n=r(e.radius),i=r(e.fill),o=r(e.stroke),f=r(e.strokeWidth);t.beginPath(),t.arc(a,s,n,0,Math.PI*2),i&&(t.fillStyle=i,t.fill()),o&&(t.strokeStyle=o,f&&(t.lineWidth=f),t.stroke());break}case "arc":{let a=r(e.x),s=r(e.y),n=r(e.radius),i=r(e.startAngle),o=r(e.endAngle),f=r(e.counterclockwise)||false,c=r(e.fill),m=r(e.stroke),h=r(e.strokeWidth);t.beginPath(),t.arc(a,s,n,i,o,f),c&&(t.fillStyle=c,t.fill()),m&&(t.strokeStyle=m,h&&(t.lineWidth=h),t.stroke());break}case "line":{let a=r(e.x1),s=r(e.y1),n=r(e.x2),i=r(e.y2),o=r(e.stroke)||"black",f=r(e.strokeWidth)||1;t.beginPath(),t.moveTo(a,s),t.lineTo(n,i),t.strokeStyle=o,t.lineWidth=f,t.stroke();break}case "text":{let a=r(e.x),s=r(e.y),n=r(e.text),i=r(e.fill)||"black",o=r(e.fontSize)||16,f=r(e.fontFamily)||"sans-serif",c=r(e.fontWeight)||"normal",m=r(e.textAlign)||"left";t.font=`${c} ${o}px ${f}`,t.textAlign=m,t.fillStyle=i,t.fillText(n,a,s);break}case "path":{let a=r(e.d),s=r(e.fill),n=r(e.stroke),i=r(e.strokeWidth),o=new Path2D(a);s&&(t.fillStyle=s,t.fill(o)),n&&(t.strokeStyle=n,i&&(t.lineWidth=i),t.stroke(o));break}}y!==void 0&&(t.globalAlpha=1);}function x(t){return e(()=>{l({type:"rect",props:t});}),null}function v(t){return e(()=>{l({type:"circle",props:t});}),null}function A(t){return e(()=>{l({type:"arc",props:t});}),null}function W(t){return e(()=>{l({type:"line",props:t});}),null}function b(t){return e(()=>{l({type:"text",props:t});}),null}function R(t){return e(()=>{l({type:"path",props:t});}),null}export{C as Canvas,A as DrawArc,v as DrawCircle,W as DrawLine,R as DrawPath,x as DrawRect,b as DrawText};//# sourceMappingURL=canvas.mjs.map
2
2
  //# sourceMappingURL=canvas.mjs.map