@mapples/render 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.
Files changed (42) hide show
  1. package/README.md +368 -0
  2. package/dist/components/Render.d.ts +49 -0
  3. package/dist/components/Render.d.ts.map +1 -0
  4. package/dist/components/Render.js +51 -0
  5. package/dist/components/Render.js.map +1 -0
  6. package/dist/components/RenderComponent.d.ts +40 -0
  7. package/dist/components/RenderComponent.d.ts.map +1 -0
  8. package/dist/components/RenderComponent.js +61 -0
  9. package/dist/components/RenderComponent.js.map +1 -0
  10. package/dist/components/RenderProvider.d.ts +31 -0
  11. package/dist/components/RenderProvider.d.ts.map +1 -0
  12. package/dist/components/RenderProvider.js +34 -0
  13. package/dist/components/RenderProvider.js.map +1 -0
  14. package/dist/components/index.d.ts +4 -0
  15. package/dist/components/index.d.ts.map +1 -0
  16. package/dist/components/index.js +4 -0
  17. package/dist/components/index.js.map +1 -0
  18. package/dist/context/RenderContext.d.ts +30 -0
  19. package/dist/context/RenderContext.d.ts.map +1 -0
  20. package/dist/context/RenderContext.js +32 -0
  21. package/dist/context/RenderContext.js.map +1 -0
  22. package/dist/context/index.d.ts +3 -0
  23. package/dist/context/index.d.ts.map +1 -0
  24. package/dist/context/index.js +3 -0
  25. package/dist/context/index.js.map +1 -0
  26. package/dist/hooks/index.d.ts +2 -0
  27. package/dist/hooks/index.d.ts.map +1 -0
  28. package/dist/hooks/index.js +2 -0
  29. package/dist/hooks/index.js.map +1 -0
  30. package/dist/hooks/useRender.d.ts +24 -0
  31. package/dist/hooks/useRender.d.ts.map +1 -0
  32. package/dist/hooks/useRender.js +28 -0
  33. package/dist/hooks/useRender.js.map +1 -0
  34. package/dist/index.d.ts +5 -0
  35. package/dist/index.d.ts.map +1 -0
  36. package/dist/index.js +5 -0
  37. package/dist/index.js.map +1 -0
  38. package/dist/types/index.d.ts +85 -0
  39. package/dist/types/index.d.ts.map +1 -0
  40. package/dist/types/index.js +1 -0
  41. package/dist/types/index.js.map +1 -0
  42. package/package.json +39 -0
package/README.md ADDED
@@ -0,0 +1,368 @@
1
+ # @mapples/render
2
+
3
+ A powerful React rendering system that enables dynamic component rendering from JSON-like component definitions. This package provides a flexible way to build dynamic UIs by defining component trees as data structures and rendering them with registered React components.
4
+
5
+ ## Features
6
+
7
+ - 🎨 **Dynamic Component Rendering**: Render React components from JSON-like definitions
8
+ - 📦 **Component Registration**: Register and manage reusable components
9
+ - 🔗 **Data Binding**: Bind dynamic data to component properties
10
+ - 🌳 **Nested Components**: Support for complex component hierarchies
11
+ - âš¡ **Performance Optimized**: Memoized components for optimal rendering performance
12
+ - 📘 **TypeScript Support**: Full TypeScript support with comprehensive type definitions
13
+
14
+ ## Installation
15
+
16
+ ```bash
17
+ npm install @mapples/render
18
+ # or
19
+ yarn add @mapples/render
20
+ ```
21
+
22
+ ## Quick Start
23
+
24
+ ### 1. Register Components
25
+
26
+ First, create a registry of components that can be rendered:
27
+
28
+ ```tsx
29
+ import { Button, Text, View } from 'react-native';
30
+
31
+ const registeredComponents = {
32
+ Button: { Component: Button },
33
+ Text: { Component: Text },
34
+ View: { Component: View },
35
+ // Add more components as needed
36
+ };
37
+ ```
38
+
39
+ ### 2. Wrap with RenderProvider
40
+
41
+ Wrap your application with the `RenderProvider` to make components available:
42
+
43
+ ```tsx
44
+ import { RenderProvider } from '@mapples/render';
45
+
46
+ const App = () => (
47
+ <RenderProvider components={registeredComponents}>
48
+ <YourAppContent />
49
+ </RenderProvider>
50
+ );
51
+ ```
52
+
53
+ ### 3. Define Component Structure
54
+
55
+ Create a component definition object:
56
+
57
+ ```tsx
58
+ const rootComponent = {
59
+ id: 'root',
60
+ type: 'View',
61
+ props: {
62
+ style: { flex: 1, padding: 20 },
63
+ },
64
+ children: ['header', 'content'],
65
+ childComponents: {
66
+ header: {
67
+ id: 'header',
68
+ type: 'Text',
69
+ props: {
70
+ children: 'Welcome to Mapples Render!',
71
+ style: { fontSize: 24, fontWeight: 'bold' },
72
+ },
73
+ children: [],
74
+ childComponents: {},
75
+ },
76
+ content: {
77
+ id: 'content',
78
+ type: 'View',
79
+ props: { style: { marginTop: 20 } },
80
+ children: ['button'],
81
+ childComponents: {
82
+ button: {
83
+ id: 'button',
84
+ type: 'Button',
85
+ props: {
86
+ title: 'Click Me',
87
+ onPress: () => console.log('Button pressed!'),
88
+ },
89
+ children: [],
90
+ childComponents: {},
91
+ },
92
+ },
93
+ },
94
+ },
95
+ };
96
+ ```
97
+
98
+ ### 4. Render the Component
99
+
100
+ Use the `Render` component to render your component tree:
101
+
102
+ ```tsx
103
+ import { Render } from '@mapples/render';
104
+
105
+ const YourAppContent = () => <Render root={rootComponent} />;
106
+ ```
107
+
108
+ ## API Reference
109
+
110
+ ### Components
111
+
112
+ #### `Render`
113
+
114
+ The main component for rendering component trees from definitions.
115
+
116
+ **Props:**
117
+
118
+ - `root: RenderComponentType` - The root component definition to render
119
+ - `CustomRenderComponent?: FC<RenderComponentType>` - Optional custom render component
120
+
121
+ **Example:**
122
+
123
+ ```tsx
124
+ <Render root={componentDefinition} />
125
+ ```
126
+
127
+ #### `RenderProvider`
128
+
129
+ Provider component that makes registered components available to the render system.
130
+
131
+ **Props:**
132
+
133
+ - `components: RegisteredComponents` - Map of registered components
134
+ - `children: ReactNode` - Child components
135
+
136
+ **Example:**
137
+
138
+ ```tsx
139
+ <RenderProvider components={registeredComponents}>
140
+ <App />
141
+ </RenderProvider>
142
+ ```
143
+
144
+ #### `RenderComponent`
145
+
146
+ Default implementation for rendering individual components. This is used internally by the `Render` component.
147
+
148
+ ### Hooks
149
+
150
+ #### `useRender()`
151
+
152
+ Hook to access the render context and registered components.
153
+
154
+ **Returns:**
155
+
156
+ - `RenderContextType` - The render context containing registered components
157
+
158
+ **Example:**
159
+
160
+ ```tsx
161
+ const { components } = useRender();
162
+ const ButtonComponent = components['Button']?.Component;
163
+ ```
164
+
165
+ ### Types
166
+
167
+ #### `RenderComponentType`
168
+
169
+ Core interface representing a renderable component:
170
+
171
+ ```tsx
172
+ interface RenderComponentType {
173
+ id: string; // Unique identifier
174
+ type: string; // Component type name
175
+ props: AnyObject & { zIndex?: number }; // Component props
176
+ children: string[]; // Child component IDs
177
+ childComponents: ChildComponents; // Child component definitions
178
+ dataProps?: DataProps; // Data property bindings
179
+ actionProps?: ActionPropsMap; // Action property configurations
180
+ }
181
+ ```
182
+
183
+ #### `DataProp`
184
+
185
+ Configuration for data properties:
186
+
187
+ ```tsx
188
+ interface DataProp {
189
+ key: string; // Data key identifier
190
+ active: boolean; // Whether the property is active
191
+ }
192
+ ```
193
+
194
+ #### `ActionProps`
195
+
196
+ Configuration for action properties:
197
+
198
+ ```tsx
199
+ interface ActionProps {
200
+ type?: string; // Action type
201
+ dataProp?: string; // Data property key
202
+ }
203
+ ```
204
+
205
+ ## Advanced Usage
206
+
207
+ ### Data Binding
208
+
209
+ Bind dynamic data to component properties using `dataProps`:
210
+
211
+ ```tsx
212
+ const componentWithData = {
213
+ id: 'dynamic-text',
214
+ type: 'Text',
215
+ props: { children: 'Default Text' },
216
+ dataProps: {
217
+ children: {
218
+ key: 'userName',
219
+ active: true,
220
+ },
221
+ },
222
+ children: [],
223
+ childComponents: {},
224
+ };
225
+ ```
226
+
227
+ ### Custom Render Component
228
+
229
+ Override the default rendering behavior with a custom component:
230
+
231
+ ```tsx
232
+ const CustomRenderer = ({ type, props, children }) => (
233
+ <div className={`custom-${type}`} {...props}>
234
+ {children}
235
+ </div>
236
+ );
237
+
238
+ <Render root={componentDefinition} CustomRenderComponent={CustomRenderer} />;
239
+ ```
240
+
241
+ ## Performance Considerations
242
+
243
+ - Components are automatically memoized to prevent unnecessary re-renders
244
+ - Use stable component IDs to maintain proper memoization
245
+ - Consider component tree depth for optimal performance
246
+ - Register only the components you need to reduce bundle size
247
+
248
+ ## Error Handling
249
+
250
+ The render system gracefully handles missing components by returning `null` instead of throwing errors. Always ensure your component types are properly registered in the `RenderProvider`.
251
+
252
+ ## Integration with Other Mapples Packages
253
+
254
+ This package integrates seamlessly with other Mapples packages:
255
+
256
+ - **@mapples/state**: For data binding and state management
257
+ - **@mapples/types**: For shared type definitions
258
+ - **@mapples/ui**: For pre-built UI components
259
+
260
+ ## Examples
261
+
262
+ ### Simple Form
263
+
264
+ ```tsx
265
+ const formComponent = {
266
+ id: 'form',
267
+ type: 'View',
268
+ props: { style: { padding: 20 } },
269
+ children: ['title', 'input', 'button'],
270
+ childComponents: {
271
+ title: {
272
+ id: 'title',
273
+ type: 'Text',
274
+ props: { children: 'Contact Form', style: { fontSize: 20 } },
275
+ children: [],
276
+ childComponents: {},
277
+ },
278
+ input: {
279
+ id: 'input',
280
+ type: 'TextInput',
281
+ props: {
282
+ placeholder: 'Enter your name',
283
+ style: { borderWidth: 1, padding: 10, marginVertical: 10 },
284
+ },
285
+ children: [],
286
+ childComponents: {},
287
+ },
288
+ button: {
289
+ id: 'button',
290
+ type: 'Button',
291
+ props: {
292
+ title: 'Submit',
293
+ onPress: () => console.log('Form submitted'),
294
+ },
295
+ children: [],
296
+ childComponents: {},
297
+ },
298
+ },
299
+ };
300
+ ```
301
+
302
+ ### Nested Layout
303
+
304
+ ```tsx
305
+ const layoutComponent = {
306
+ id: 'layout',
307
+ type: 'View',
308
+ props: { style: { flex: 1 } },
309
+ children: ['header', 'content', 'footer'],
310
+ childComponents: {
311
+ header: {
312
+ id: 'header',
313
+ type: 'View',
314
+ props: { style: { height: 60, backgroundColor: '#f0f0f0' } },
315
+ children: ['header-text'],
316
+ childComponents: {
317
+ 'header-text': {
318
+ id: 'header-text',
319
+ type: 'Text',
320
+ props: {
321
+ children: 'Header',
322
+ style: { textAlign: 'center', marginTop: 20 },
323
+ },
324
+ children: [],
325
+ childComponents: {},
326
+ },
327
+ },
328
+ },
329
+ content: {
330
+ id: 'content',
331
+ type: 'View',
332
+ props: { style: { flex: 1, padding: 20 } },
333
+ children: [],
334
+ childComponents: {},
335
+ },
336
+ footer: {
337
+ id: 'footer',
338
+ type: 'View',
339
+ props: { style: { height: 60, backgroundColor: '#f0f0f0' } },
340
+ children: ['footer-text'],
341
+ childComponents: {
342
+ 'footer-text': {
343
+ id: 'footer-text',
344
+ type: 'Text',
345
+ props: {
346
+ children: 'Footer',
347
+ style: { textAlign: 'center', marginTop: 20 },
348
+ },
349
+ children: [],
350
+ childComponents: {},
351
+ },
352
+ },
353
+ },
354
+ },
355
+ };
356
+ ```
357
+
358
+ ## Contributing
359
+
360
+ Contributions are welcome! Please read our contributing guidelines and submit pull requests to our repository.
361
+
362
+ ## License
363
+
364
+ MIT License - see the LICENSE file for details.
365
+
366
+ ## Support
367
+
368
+ For support and questions, please visit our [GitHub repository](https://github.com/mapplesorg/mapples-kit) or contact us at [mapples.org](https://mapples.org).
@@ -0,0 +1,49 @@
1
+ import { RenderProps } from '../types';
2
+ /**
3
+ * Main render component that renders a component tree from a root component definition.
4
+ *
5
+ * This is the primary entry point for the render system. It takes a root component
6
+ * definition and renders it using either a custom render component or the default
7
+ * RenderComponent implementation.
8
+ *
9
+ * @param {RenderProps} props - The render props
10
+ *
11
+ * @example
12
+ * ```tsx
13
+ * const rootComponent = {
14
+ * id: 'root',
15
+ * type: 'View',
16
+ * props: { style: { flex: 1 } },
17
+ * children: ['child1'],
18
+ * childComponents: {
19
+ * child1: {
20
+ * id: 'child1',
21
+ * type: 'Text',
22
+ * props: { children: 'Hello World' },
23
+ * children: [],
24
+ * childComponents: {}
25
+ * }
26
+ * }
27
+ * };
28
+ *
29
+ * const App = () => (
30
+ * <RenderProvider components={registeredComponents}>
31
+ * <Render root={rootComponent} />
32
+ * </RenderProvider>
33
+ * );
34
+ * ```
35
+ *
36
+ * @example
37
+ * ```tsx
38
+ * // Using a custom render component
39
+ * const CustomRenderer = (props) => <div className="custom">{props.children}</div>;
40
+ *
41
+ * <Render
42
+ * root={rootComponent}
43
+ * CustomRenderComponent={CustomRenderer}
44
+ * />
45
+ * ```
46
+ */
47
+ declare const Render: ({ root, CustomRenderComponent }: RenderProps) => import("react").JSX.Element;
48
+ export default Render;
49
+ //# sourceMappingURL=Render.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Render.d.ts","sourceRoot":"","sources":["../../src/components/Render.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAIvC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4CG;AACH,QAAA,MAAM,MAAM,GAAI,iCAAiC,WAAW,gCAM3D,CAAC;AAEF,eAAe,MAAM,CAAC"}
@@ -0,0 +1,51 @@
1
+ import RenderComponent from './RenderComponent';
2
+ /**
3
+ * Main render component that renders a component tree from a root component definition.
4
+ *
5
+ * This is the primary entry point for the render system. It takes a root component
6
+ * definition and renders it using either a custom render component or the default
7
+ * RenderComponent implementation.
8
+ *
9
+ * @param {RenderProps} props - The render props
10
+ *
11
+ * @example
12
+ * ```tsx
13
+ * const rootComponent = {
14
+ * id: 'root',
15
+ * type: 'View',
16
+ * props: { style: { flex: 1 } },
17
+ * children: ['child1'],
18
+ * childComponents: {
19
+ * child1: {
20
+ * id: 'child1',
21
+ * type: 'Text',
22
+ * props: { children: 'Hello World' },
23
+ * children: [],
24
+ * childComponents: {}
25
+ * }
26
+ * }
27
+ * };
28
+ *
29
+ * const App = () => (
30
+ * <RenderProvider components={registeredComponents}>
31
+ * <Render root={rootComponent} />
32
+ * </RenderProvider>
33
+ * );
34
+ * ```
35
+ *
36
+ * @example
37
+ * ```tsx
38
+ * // Using a custom render component
39
+ * const CustomRenderer = (props) => <div className="custom">{props.children}</div>;
40
+ *
41
+ * <Render
42
+ * root={rootComponent}
43
+ * CustomRenderComponent={CustomRenderer}
44
+ * />
45
+ * ```
46
+ */
47
+ const Render = ({ root, CustomRenderComponent }) => {
48
+ return CustomRenderComponent ? (<CustomRenderComponent {...root}/>) : (<RenderComponent {...root}/>);
49
+ };
50
+ export default Render;
51
+ //# sourceMappingURL=Render.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Render.js","sourceRoot":"","sources":["../../src/components/Render.tsx"],"names":[],"mappings":"AAEA,OAAO,eAAe,MAAM,mBAAmB,CAAC;AAEhD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4CG;AACH,MAAM,MAAM,GAAG,CAAC,EAAE,IAAI,EAAE,qBAAqB,EAAe,EAAE,EAAE;IAC9D,OAAO,qBAAqB,CAAC,CAAC,CAAC,CAC7B,CAAC,qBAAqB,CAAC,IAAI,IAAI,CAAC,EAAG,CACpC,CAAC,CAAC,CAAC,CACF,CAAC,eAAe,CAAC,IAAI,IAAI,CAAC,EAAG,CAC9B,CAAC;AACJ,CAAC,CAAC;AAEF,eAAe,MAAM,CAAC"}
@@ -0,0 +1,40 @@
1
+ import { FC } from 'react';
2
+ import { RenderComponentType } from '../types';
3
+ /**
4
+ * Default implementation of a renderable component.
5
+ *
6
+ * This component handles the rendering of individual components within the render tree.
7
+ * It resolves the component type from registered components, applies data properties,
8
+ * and recursively renders child components.
9
+ *
10
+ * The component is memoized for performance optimization to prevent unnecessary
11
+ * re-renders when props haven't changed.
12
+ *
13
+ * @param {RenderComponentType} props - The component definition
14
+ * @param {string} props.type - The component type name (must be registered)
15
+ * @param {AnyObject & { zIndex?: number }} props.props - Component props
16
+ * @param {DataProps} [props.dataProps] - Optional data property bindings
17
+ * @param {string[]} props.children - Array of child component IDs
18
+ * @param {ChildComponents} props.childComponents - Map of child components
19
+ *
20
+ * @returns {JSX.Element | null} The rendered component or null if component type not found
21
+ *
22
+ * @example
23
+ * ```tsx
24
+ * const componentDef = {
25
+ * id: 'button1',
26
+ * type: 'Button',
27
+ * props: { title: 'Click me', onPress: handlePress },
28
+ * dataProps: { title: { key: 'buttonText', active: true } },
29
+ * children: [],
30
+ * childComponents: {}
31
+ * };
32
+ *
33
+ * <RenderComponent {...componentDef} />
34
+ * ```
35
+ *
36
+ * @throws {Error} If the component type is not registered in the render context
37
+ */
38
+ declare const RenderComponent: FC<RenderComponentType>;
39
+ export default RenderComponent;
40
+ //# sourceMappingURL=RenderComponent.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"RenderComponent.d.ts","sourceRoot":"","sources":["../../src/components/RenderComponent.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,EAAE,EAAQ,MAAM,OAAO,CAAC;AAMjC,OAAO,EAAE,mBAAmB,EAAE,MAAM,UAAU,CAAC;AAE/C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AACH,QAAA,MAAM,eAAe,EAAE,EAAE,CAAC,mBAAmB,CA+B5C,CAAC;AAQF,eAAe,eAAe,CAAC"}
@@ -0,0 +1,61 @@
1
+ import { memo } from 'react';
2
+ import { useDataProps } from '@mapples/state';
3
+ import { map } from 'lodash';
4
+ import { useRender } from '../hooks';
5
+ /**
6
+ * Default implementation of a renderable component.
7
+ *
8
+ * This component handles the rendering of individual components within the render tree.
9
+ * It resolves the component type from registered components, applies data properties,
10
+ * and recursively renders child components.
11
+ *
12
+ * The component is memoized for performance optimization to prevent unnecessary
13
+ * re-renders when props haven't changed.
14
+ *
15
+ * @param {RenderComponentType} props - The component definition
16
+ * @param {string} props.type - The component type name (must be registered)
17
+ * @param {AnyObject & { zIndex?: number }} props.props - Component props
18
+ * @param {DataProps} [props.dataProps] - Optional data property bindings
19
+ * @param {string[]} props.children - Array of child component IDs
20
+ * @param {ChildComponents} props.childComponents - Map of child components
21
+ *
22
+ * @returns {JSX.Element | null} The rendered component or null if component type not found
23
+ *
24
+ * @example
25
+ * ```tsx
26
+ * const componentDef = {
27
+ * id: 'button1',
28
+ * type: 'Button',
29
+ * props: { title: 'Click me', onPress: handlePress },
30
+ * dataProps: { title: { key: 'buttonText', active: true } },
31
+ * children: [],
32
+ * childComponents: {}
33
+ * };
34
+ *
35
+ * <RenderComponent {...componentDef} />
36
+ * ```
37
+ *
38
+ * @throws {Error} If the component type is not registered in the render context
39
+ */
40
+ const RenderComponent = ({ type, props, dataProps, children, childComponents, }) => {
41
+ const { components } = useRender();
42
+ const propsWithData = useDataProps(dataProps);
43
+ const Component = components[type].Component;
44
+ if (!Component) {
45
+ return null;
46
+ }
47
+ const renderChildren = (child) => {
48
+ const renderComponentProps = childComponents[child];
49
+ return (<RenderComponentMemorized {...renderComponentProps} key={renderComponentProps.id}/>);
50
+ };
51
+ return (<Component {...props} {...propsWithData}>
52
+ {map(children, renderChildren)}
53
+ </Component>);
54
+ };
55
+ /**
56
+ * Memoized version of RenderComponent for performance optimization.
57
+ * Prevents unnecessary re-renders when component props haven't changed.
58
+ */
59
+ const RenderComponentMemorized = memo(RenderComponent);
60
+ export default RenderComponent;
61
+ //# sourceMappingURL=RenderComponent.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"RenderComponent.js","sourceRoot":"","sources":["../../src/components/RenderComponent.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAM,IAAI,EAAE,MAAM,OAAO,CAAC;AAEjC,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,EAAE,GAAG,EAAE,MAAM,QAAQ,CAAC;AAE7B,OAAO,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AAGrC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AACH,MAAM,eAAe,GAA4B,CAAC,EAChD,IAAI,EACJ,KAAK,EACL,SAAS,EACT,QAAQ,EACR,eAAe,GAChB,EAAE,EAAE;IACH,MAAM,EAAE,UAAU,EAAE,GAAG,SAAS,EAAE,CAAC;IACnC,MAAM,aAAa,GAAG,YAAY,CAAC,SAAS,CAAC,CAAC;IAE9C,MAAM,SAAS,GAAG,UAAU,CAAC,IAA+B,CAAC,CAAC,SAAS,CAAC;IAExE,IAAI,CAAC,SAAS,EAAE,CAAC;QACf,OAAO,IAAI,CAAC;IACd,CAAC;IAED,MAAM,cAAc,GAAG,CAAC,KAAa,EAAE,EAAE;QACvC,MAAM,oBAAoB,GAAG,eAAe,CAAC,KAAK,CAAC,CAAC;QACpD,OAAO,CACL,CAAC,wBAAwB,CACvB,IAAI,oBAAoB,CAAC,CACzB,GAAG,CAAC,CAAC,oBAAoB,CAAC,EAAE,CAAC,EAC7B,CACH,CAAC;IACJ,CAAC,CAAC;IAEF,OAAO,CACL,CAAC,SAAS,CAAC,IAAI,KAAK,CAAC,CAAC,IAAI,aAAa,CAAC,CACtC;MAAA,CAAC,GAAG,CAAC,QAAQ,EAAE,cAAc,CAAC,CAChC;IAAA,EAAE,SAAS,CAAC,CACb,CAAC;AACJ,CAAC,CAAC;AAEF;;;GAGG;AACH,MAAM,wBAAwB,GAAG,IAAI,CAAC,eAAe,CAAC,CAAC;AAEvD,eAAe,eAAe,CAAC"}
@@ -0,0 +1,31 @@
1
+ import { FC, PropsWithChildren } from 'react';
2
+ import { RenderContextType } from '../types';
3
+ /**
4
+ * Provider component that makes registered components available to the render system.
5
+ *
6
+ * This component wraps your application and provides the registered components
7
+ * to all child components through React context. It's essential for the render
8
+ * system to function properly as it makes components available for dynamic rendering.
9
+ *
10
+ * @param {PropsWithChildren<RenderContextType>} props - The component props
11
+ * @param {RegisteredComponents} props.components - Map of registered components
12
+ * @param {ReactNode} props.children - Child components to render
13
+ *
14
+ * @example
15
+ * ```tsx
16
+ * const registeredComponents = {
17
+ * Button: { Component: MyButton },
18
+ * Text: { Component: MyText },
19
+ * View: { Component: MyView }
20
+ * };
21
+ *
22
+ * const App = () => (
23
+ * <RenderProvider components={registeredComponents}>
24
+ * <Render root={rootComponent} />
25
+ * </RenderProvider>
26
+ * );
27
+ * ```
28
+ */
29
+ declare const RenderProvider: FC<PropsWithChildren<RenderContextType>>;
30
+ export default RenderProvider;
31
+ //# sourceMappingURL=RenderProvider.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"RenderProvider.d.ts","sourceRoot":"","sources":["../../src/components/RenderProvider.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,EAAE,EAAE,iBAAiB,EAAE,MAAM,OAAO,CAAC;AAG9C,OAAO,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAC;AAE7C;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,QAAA,MAAM,cAAc,EAAE,EAAE,CAAC,iBAAiB,CAAC,iBAAiB,CAAC,CAS5D,CAAC;AAEF,eAAe,cAAc,CAAC"}
@@ -0,0 +1,34 @@
1
+ import { RenderContextProvider } from '../context';
2
+ /**
3
+ * Provider component that makes registered components available to the render system.
4
+ *
5
+ * This component wraps your application and provides the registered components
6
+ * to all child components through React context. It's essential for the render
7
+ * system to function properly as it makes components available for dynamic rendering.
8
+ *
9
+ * @param {PropsWithChildren<RenderContextType>} props - The component props
10
+ * @param {RegisteredComponents} props.components - Map of registered components
11
+ * @param {ReactNode} props.children - Child components to render
12
+ *
13
+ * @example
14
+ * ```tsx
15
+ * const registeredComponents = {
16
+ * Button: { Component: MyButton },
17
+ * Text: { Component: MyText },
18
+ * View: { Component: MyView }
19
+ * };
20
+ *
21
+ * const App = () => (
22
+ * <RenderProvider components={registeredComponents}>
23
+ * <Render root={rootComponent} />
24
+ * </RenderProvider>
25
+ * );
26
+ * ```
27
+ */
28
+ const RenderProvider = ({ components, children, }) => {
29
+ return (<RenderContextProvider value={{ components }}>
30
+ {children}
31
+ </RenderContextProvider>);
32
+ };
33
+ export default RenderProvider;
34
+ //# sourceMappingURL=RenderProvider.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"RenderProvider.js","sourceRoot":"","sources":["../../src/components/RenderProvider.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAE,qBAAqB,EAAE,MAAM,YAAY,CAAC;AAGnD;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,MAAM,cAAc,GAA6C,CAAC,EAChE,UAAU,EACV,QAAQ,GACT,EAAE,EAAE;IACH,OAAO,CACL,CAAC,qBAAqB,CAAC,KAAK,CAAC,CAAC,EAAE,UAAU,EAAE,CAAC,CAC3C;MAAA,CAAC,QAAQ,CACX;IAAA,EAAE,qBAAqB,CAAC,CACzB,CAAC;AACJ,CAAC,CAAC;AAEF,eAAe,cAAc,CAAC"}
@@ -0,0 +1,4 @@
1
+ export { default as Render } from './Render';
2
+ export { default as RenderComponent } from './RenderComponent';
3
+ export { default as RenderProvider } from './RenderProvider';
4
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/components/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,IAAI,MAAM,EAAE,MAAM,UAAU,CAAC;AAC7C,OAAO,EAAE,OAAO,IAAI,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAC/D,OAAO,EAAE,OAAO,IAAI,cAAc,EAAE,MAAM,kBAAkB,CAAC"}
@@ -0,0 +1,4 @@
1
+ export { default as Render } from './Render';
2
+ export { default as RenderComponent } from './RenderComponent';
3
+ export { default as RenderProvider } from './RenderProvider';
4
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/components/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,IAAI,MAAM,EAAE,MAAM,UAAU,CAAC;AAC7C,OAAO,EAAE,OAAO,IAAI,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAC/D,OAAO,EAAE,OAAO,IAAI,cAAc,EAAE,MAAM,kBAAkB,CAAC"}
@@ -0,0 +1,30 @@
1
+ import { RenderContextType } from '../types';
2
+ /**
3
+ * React context for the render system.
4
+ * Provides access to registered components throughout the component tree.
5
+ *
6
+ * This context is used by the RenderProvider to make registered components
7
+ * available to all child components in the render tree.
8
+ *
9
+ * @example
10
+ * ```tsx
11
+ * const { components } = useContext(RenderContext);
12
+ * const Component = components['Button']?.Component;
13
+ * ```
14
+ */
15
+ declare const RenderContext: import("react").Context<RenderContextType>;
16
+ /**
17
+ * Provider component for the RenderContext.
18
+ * Use this to wrap your application and provide registered components
19
+ * to the render system.
20
+ *
21
+ * @example
22
+ * ```tsx
23
+ * <RenderContextProvider value={{ components: registeredComponents }}>
24
+ * <App />
25
+ * </RenderContextProvider>
26
+ * ```
27
+ */
28
+ export declare const RenderContextProvider: import("react").Provider<RenderContextType>;
29
+ export default RenderContext;
30
+ //# sourceMappingURL=RenderContext.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"RenderContext.d.ts","sourceRoot":"","sources":["../../src/context/RenderContext.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAC;AAE7C;;;;;;;;;;;;GAYG;AACH,QAAA,MAAM,aAAa,4CAEjB,CAAC;AAEH;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,qBAAqB,6CAAyB,CAAC;AAE5D,eAAe,aAAa,CAAC"}
@@ -0,0 +1,32 @@
1
+ import { createContext } from 'react';
2
+ /**
3
+ * React context for the render system.
4
+ * Provides access to registered components throughout the component tree.
5
+ *
6
+ * This context is used by the RenderProvider to make registered components
7
+ * available to all child components in the render tree.
8
+ *
9
+ * @example
10
+ * ```tsx
11
+ * const { components } = useContext(RenderContext);
12
+ * const Component = components['Button']?.Component;
13
+ * ```
14
+ */
15
+ const RenderContext = createContext({
16
+ components: {},
17
+ });
18
+ /**
19
+ * Provider component for the RenderContext.
20
+ * Use this to wrap your application and provide registered components
21
+ * to the render system.
22
+ *
23
+ * @example
24
+ * ```tsx
25
+ * <RenderContextProvider value={{ components: registeredComponents }}>
26
+ * <App />
27
+ * </RenderContextProvider>
28
+ * ```
29
+ */
30
+ export const RenderContextProvider = RenderContext.Provider;
31
+ export default RenderContext;
32
+ //# sourceMappingURL=RenderContext.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"RenderContext.js","sourceRoot":"","sources":["../../src/context/RenderContext.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,OAAO,CAAC;AAItC;;;;;;;;;;;;GAYG;AACH,MAAM,aAAa,GAAG,aAAa,CAAoB;IACrD,UAAU,EAAE,EAAE;CACf,CAAC,CAAC;AAEH;;;;;;;;;;;GAWG;AACH,MAAM,CAAC,MAAM,qBAAqB,GAAG,aAAa,CAAC,QAAQ,CAAC;AAE5D,eAAe,aAAa,CAAC"}
@@ -0,0 +1,3 @@
1
+ export { default as RenderContext } from './RenderContext';
2
+ export * from './RenderContext';
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/context/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,IAAI,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAC3D,cAAc,iBAAiB,CAAC"}
@@ -0,0 +1,3 @@
1
+ export { default as RenderContext } from './RenderContext';
2
+ export * from './RenderContext';
3
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/context/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,IAAI,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAC3D,cAAc,iBAAiB,CAAC"}
@@ -0,0 +1,2 @@
1
+ export { default as useRender } from './useRender';
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/hooks/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,IAAI,SAAS,EAAE,MAAM,aAAa,CAAC"}
@@ -0,0 +1,2 @@
1
+ export { default as useRender } from './useRender';
2
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/hooks/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,IAAI,SAAS,EAAE,MAAM,aAAa,CAAC"}
@@ -0,0 +1,24 @@
1
+ /**
2
+ * Hook to access the render context.
3
+ *
4
+ * This hook provides access to the registered components and other render
5
+ * context data. It should be used within components that are wrapped by
6
+ * a RenderProvider.
7
+ *
8
+ * @returns {RenderContextType} The render context containing registered components
9
+ *
10
+ * @example
11
+ * ```tsx
12
+ * const MyComponent = () => {
13
+ * const { components } = useRender();
14
+ * const ButtonComponent = components['Button']?.Component;
15
+ *
16
+ * return ButtonComponent ? <ButtonComponent /> : null;
17
+ * };
18
+ * ```
19
+ *
20
+ * @throws {Error} If used outside of a RenderProvider context
21
+ */
22
+ declare const useRender: () => import("..").RenderContextType;
23
+ export default useRender;
24
+ //# sourceMappingURL=useRender.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useRender.d.ts","sourceRoot":"","sources":["../../src/hooks/useRender.ts"],"names":[],"mappings":"AAIA;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,QAAA,MAAM,SAAS,sCAEd,CAAC;AAEF,eAAe,SAAS,CAAC"}
@@ -0,0 +1,28 @@
1
+ import { useContext } from 'react';
2
+ import { RenderContext } from '../context';
3
+ /**
4
+ * Hook to access the render context.
5
+ *
6
+ * This hook provides access to the registered components and other render
7
+ * context data. It should be used within components that are wrapped by
8
+ * a RenderProvider.
9
+ *
10
+ * @returns {RenderContextType} The render context containing registered components
11
+ *
12
+ * @example
13
+ * ```tsx
14
+ * const MyComponent = () => {
15
+ * const { components } = useRender();
16
+ * const ButtonComponent = components['Button']?.Component;
17
+ *
18
+ * return ButtonComponent ? <ButtonComponent /> : null;
19
+ * };
20
+ * ```
21
+ *
22
+ * @throws {Error} If used outside of a RenderProvider context
23
+ */
24
+ const useRender = () => {
25
+ return useContext(RenderContext);
26
+ };
27
+ export default useRender;
28
+ //# sourceMappingURL=useRender.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useRender.js","sourceRoot":"","sources":["../../src/hooks/useRender.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,OAAO,CAAC;AAEnC,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAE3C;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,MAAM,SAAS,GAAG,GAAG,EAAE;IACrB,OAAO,UAAU,CAAC,aAAa,CAAC,CAAC;AACnC,CAAC,CAAC;AAEF,eAAe,SAAS,CAAC"}
@@ -0,0 +1,5 @@
1
+ export * from './types';
2
+ export * from './context';
3
+ export * from './components';
4
+ export * from './hooks';
5
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,SAAS,CAAC;AACxB,cAAc,WAAW,CAAC;AAC1B,cAAc,cAAc,CAAC;AAC7B,cAAc,SAAS,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,5 @@
1
+ export * from './types';
2
+ export * from './context';
3
+ export * from './components';
4
+ export * from './hooks';
5
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,SAAS,CAAC;AACxB,cAAc,WAAW,CAAC;AAC1B,cAAc,cAAc,CAAC;AAC7B,cAAc,SAAS,CAAC"}
@@ -0,0 +1,85 @@
1
+ import { FC } from 'react';
2
+ import { DataProps, RegisteredComponents } from '@mapples/types';
3
+ /**
4
+ * A generic object type that can hold any key-value pairs.
5
+ * Used for component props and other dynamic data structures.
6
+ */
7
+ export type AnyObject = Record<string, any>;
8
+ /**
9
+ * A record of child components indexed by their IDs.
10
+ * Each child component is represented as a RenderComponentType.
11
+ */
12
+ export type ChildComponents = Record<string, RenderComponentType>;
13
+ /**
14
+ * Configuration for action properties that define component interactions.
15
+ *
16
+ * @interface ActionProps
17
+ * @property {string} [type] - The type of action to perform
18
+ * @property {string} [dataProp] - The data property key to bind to this action
19
+ */
20
+ export interface ActionProps {
21
+ type?: string;
22
+ dataProp?: string;
23
+ }
24
+ /**
25
+ * A map of action properties indexed by their names.
26
+ * Each entry contains configuration for component interactions.
27
+ */
28
+ export type ActionPropsMap = Partial<Record<string, ActionProps>>;
29
+ /**
30
+ * Represents a renderable component with all its configuration and children.
31
+ * This is the core type used throughout the render system.
32
+ *
33
+ * @interface RenderComponentType
34
+ * @property {string} id - Unique identifier for this component instance
35
+ * @property {string} type - The component type name (must be registered in components)
36
+ * @property {AnyObject & { zIndex?: number }} props - Component props including optional zIndex
37
+ * @property {AnyObject} [_canvasProps] - Optional drag-and-drop configuration for canvas interactions
38
+ * @property {string[]} children - Array of child component IDs
39
+ * @property {ChildComponents} childComponents - Map of child components by their IDs
40
+ * @property {DataProps} [dataProps] - Optional data property bindings
41
+ * @property {ActionPropsMap} [actionProps] - Optional action property configurations
42
+ */
43
+ export interface RenderComponentType {
44
+ id: string;
45
+ type: string;
46
+ props: AnyObject & {
47
+ zIndex?: number;
48
+ };
49
+ _canvasProps?: AnyObject;
50
+ children: string[];
51
+ childComponents: ChildComponents;
52
+ dataProps?: DataProps;
53
+ actionProps?: ActionPropsMap;
54
+ }
55
+ /**
56
+ * Represents the complete render DOM structure.
57
+ * Extends ChildComponents with a special 'root' component.
58
+ *
59
+ * @interface RenderDom
60
+ * @property {RenderComponentType} root - The root component of the render tree
61
+ */
62
+ export interface RenderDom extends ChildComponents {
63
+ root: RenderComponentType;
64
+ }
65
+ /**
66
+ * Props for the main Render component.
67
+ *
68
+ * @type RenderProps
69
+ * @property {RenderComponentType} root - The root component to render
70
+ * @property {FC<RenderComponentType>} [CustomRenderComponent] - Optional custom render component to override default rendering
71
+ */
72
+ export type RenderProps = Pick<RenderDom, 'root'> & {
73
+ CustomRenderComponent?: FC<RenderComponentType>;
74
+ };
75
+ /**
76
+ * Context type for the render system.
77
+ * Provides access to registered components throughout the component tree.
78
+ *
79
+ * @interface RenderContextType
80
+ * @property {RegisteredComponents} components - Map of registered components available for rendering
81
+ */
82
+ export interface RenderContextType {
83
+ components: RegisteredComponents;
84
+ }
85
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC;AAE3B,OAAO,EAAE,SAAS,EAAE,oBAAoB,EAAE,MAAM,gBAAgB,CAAC;AAEjE;;;GAGG;AAEH,MAAM,MAAM,SAAS,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;AAE5C;;;GAGG;AACH,MAAM,MAAM,eAAe,GAAG,MAAM,CAAC,MAAM,EAAE,mBAAmB,CAAC,CAAC;AAElE;;;;;;GAMG;AACH,MAAM,WAAW,WAAW;IAC1B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED;;;GAGG;AACH,MAAM,MAAM,cAAc,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC,CAAC;AAElE;;;;;;;;;;;;;GAaG;AACH,MAAM,WAAW,mBAAmB;IAClC,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,SAAS,GAAG;QAAE,MAAM,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IACvC,YAAY,CAAC,EAAE,SAAS,CAAC;IACzB,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,eAAe,EAAE,eAAe,CAAC;IACjC,SAAS,CAAC,EAAE,SAAS,CAAC;IACtB,WAAW,CAAC,EAAE,cAAc,CAAC;CAC9B;AAED;;;;;;GAMG;AACH,MAAM,WAAW,SAAU,SAAQ,eAAe;IAChD,IAAI,EAAE,mBAAmB,CAAC;CAC3B;AAED;;;;;;GAMG;AACH,MAAM,MAAM,WAAW,GAAG,IAAI,CAAC,SAAS,EAAE,MAAM,CAAC,GAAG;IAClD,qBAAqB,CAAC,EAAE,EAAE,CAAC,mBAAmB,CAAC,CAAC;CACjD,CAAC;AAEF;;;;;;GAMG;AACH,MAAM,WAAW,iBAAiB;IAChC,UAAU,EAAE,oBAAoB,CAAC;CAClC"}
@@ -0,0 +1 @@
1
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":""}
package/package.json ADDED
@@ -0,0 +1,39 @@
1
+ {
2
+ "name": "@mapples/render",
3
+ "version": "1.0.1",
4
+ "main": "dist/index.js",
5
+ "types": "dist/index.d.ts",
6
+ "scripts": {
7
+ "build": "tsc -b tsconfig.build.json",
8
+ "lint": "eslint .",
9
+ "type-check": "tsc --noEmit",
10
+ "clean": "rm -rf dist"
11
+ },
12
+ "author": {
13
+ "name": "Oleksandr Soloviov",
14
+ "url": "https://mapples.org/people/olek_soloviov"
15
+ },
16
+ "license": "MIT",
17
+ "repository": {
18
+ "type": "git",
19
+ "url": "https://github.com/mapplesorg/mapples-open-kit.git",
20
+ "directory": "packages/@mapples/render"
21
+ },
22
+ "dependencies": {
23
+ "lodash": "^4.17.21"
24
+ },
25
+ "peerDependencies": {
26
+ "react": ">=18.0.0 <20.0.0",
27
+ "react-native": ">=0.71.0"
28
+ },
29
+ "devDependencies": {
30
+ "@types/lodash": "^4.17.0",
31
+ "@types/react": ">=18.0.0 <20.0.0",
32
+ "typescript": "~5.9.2"
33
+ },
34
+ "files": [
35
+ "dist",
36
+ "README.md",
37
+ "package.json"
38
+ ]
39
+ }