pxengine 0.1.12 → 0.1.14

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 (186) hide show
  1. package/dist/index.cjs +227 -291
  2. package/dist/index.d.cts +15 -11
  3. package/dist/index.d.ts +15 -11
  4. package/dist/index.js +225 -287
  5. package/dist/registry.json +20 -22
  6. package/package.json +2 -4
  7. package/config/tailwind-preset.js +0 -106
  8. package/src/atoms/AccordionAtom.tsx +0 -44
  9. package/src/atoms/AlertAtom.tsx +0 -48
  10. package/src/atoms/AlertDialogAtom.tsx +0 -66
  11. package/src/atoms/AspectRatioAtom.tsx +0 -27
  12. package/src/atoms/AvatarAtom.tsx +0 -21
  13. package/src/atoms/BadgeAtom.tsx +0 -35
  14. package/src/atoms/BreadcrumbAtom.tsx +0 -36
  15. package/src/atoms/ButtonAtom.tsx +0 -65
  16. package/src/atoms/CalendarAtom.tsx +0 -24
  17. package/src/atoms/CardAtom.tsx +0 -66
  18. package/src/atoms/CarouselAtom.tsx +0 -40
  19. package/src/atoms/ChartAtom.tsx +0 -192
  20. package/src/atoms/CheckboxAtom.tsx +0 -33
  21. package/src/atoms/CollapsibleAtom.tsx +0 -44
  22. package/src/atoms/CommandAtom.tsx +0 -46
  23. package/src/atoms/ContextMenuAtom.tsx +0 -49
  24. package/src/atoms/DialogAtom.tsx +0 -68
  25. package/src/atoms/DrawerAtom.tsx +0 -49
  26. package/src/atoms/DropdownMenuAtom.tsx +0 -49
  27. package/src/atoms/FormInputAtom.tsx +0 -101
  28. package/src/atoms/FormSelectAtom.tsx +0 -110
  29. package/src/atoms/FormTextareaAtom.tsx +0 -93
  30. package/src/atoms/InputAtom.tsx +0 -216
  31. package/src/atoms/InputOTPAtom.tsx +0 -49
  32. package/src/atoms/KbdAtom.tsx +0 -25
  33. package/src/atoms/LabelAtom.tsx +0 -23
  34. package/src/atoms/LayoutAtom.tsx +0 -45
  35. package/src/atoms/PaginationAtom.tsx +0 -49
  36. package/src/atoms/PopoverAtom.tsx +0 -40
  37. package/src/atoms/ProgressAtom.tsx +0 -15
  38. package/src/atoms/RadioGroupAtom.tsx +0 -31
  39. package/src/atoms/RatingAtom.tsx +0 -37
  40. package/src/atoms/ResizableAtom.tsx +0 -51
  41. package/src/atoms/ScrollAreaAtom.tsx +0 -31
  42. package/src/atoms/SeparatorAtom.tsx +0 -16
  43. package/src/atoms/SheetAtom.tsx +0 -72
  44. package/src/atoms/SkeletonAtom.tsx +0 -22
  45. package/src/atoms/SliderAtom.tsx +0 -32
  46. package/src/atoms/SpinnerAtom.tsx +0 -26
  47. package/src/atoms/SwitchAtom.tsx +0 -32
  48. package/src/atoms/TableAtom.tsx +0 -60
  49. package/src/atoms/TabsAtom.tsx +0 -40
  50. package/src/atoms/TextAtom.tsx +0 -36
  51. package/src/atoms/TextareaAtom.tsx +0 -42
  52. package/src/atoms/TimelineAtom.tsx +0 -77
  53. package/src/atoms/ToggleAtom.tsx +0 -36
  54. package/src/atoms/TooltipAtom.tsx +0 -39
  55. package/src/atoms/VideoAtom.tsx +0 -34
  56. package/src/atoms/index.ts +0 -49
  57. package/src/components/index.ts +0 -178
  58. package/src/components/ui/accordion.tsx +0 -56
  59. package/src/components/ui/alert-dialog.tsx +0 -139
  60. package/src/components/ui/alert.tsx +0 -59
  61. package/src/components/ui/aspect-ratio.tsx +0 -5
  62. package/src/components/ui/avatar.tsx +0 -50
  63. package/src/components/ui/badge.tsx +0 -36
  64. package/src/components/ui/breadcrumb.tsx +0 -115
  65. package/src/components/ui/button-group.tsx +0 -83
  66. package/src/components/ui/button.tsx +0 -56
  67. package/src/components/ui/calendar.tsx +0 -213
  68. package/src/components/ui/card.tsx +0 -79
  69. package/src/components/ui/carousel.tsx +0 -260
  70. package/src/components/ui/chart.tsx +0 -367
  71. package/src/components/ui/checkbox.tsx +0 -28
  72. package/src/components/ui/collapsible.tsx +0 -11
  73. package/src/components/ui/command.tsx +0 -153
  74. package/src/components/ui/context-menu.tsx +0 -198
  75. package/src/components/ui/dialog.tsx +0 -122
  76. package/src/components/ui/drawer.tsx +0 -116
  77. package/src/components/ui/dropdown-menu.tsx +0 -200
  78. package/src/components/ui/empty.tsx +0 -104
  79. package/src/components/ui/field.tsx +0 -244
  80. package/src/components/ui/form.tsx +0 -176
  81. package/src/components/ui/hover-card.tsx +0 -27
  82. package/src/components/ui/index.ts +0 -54
  83. package/src/components/ui/input-group.tsx +0 -168
  84. package/src/components/ui/input-otp.tsx +0 -69
  85. package/src/components/ui/input.tsx +0 -22
  86. package/src/components/ui/item.tsx +0 -193
  87. package/src/components/ui/kbd.tsx +0 -28
  88. package/src/components/ui/label.tsx +0 -26
  89. package/src/components/ui/menubar.tsx +0 -254
  90. package/src/components/ui/navigation-menu.tsx +0 -128
  91. package/src/components/ui/pagination.tsx +0 -117
  92. package/src/components/ui/popover.tsx +0 -29
  93. package/src/components/ui/progress.tsx +0 -28
  94. package/src/components/ui/radio-group.tsx +0 -42
  95. package/src/components/ui/resizable.tsx +0 -44
  96. package/src/components/ui/scroll-area.tsx +0 -46
  97. package/src/components/ui/select.tsx +0 -160
  98. package/src/components/ui/separator.tsx +0 -29
  99. package/src/components/ui/sheet.tsx +0 -140
  100. package/src/components/ui/sidebar.tsx +0 -771
  101. package/src/components/ui/skeleton.tsx +0 -15
  102. package/src/components/ui/slider.tsx +0 -26
  103. package/src/components/ui/sonner.tsx +0 -45
  104. package/src/components/ui/spinner.tsx +0 -16
  105. package/src/components/ui/switch.tsx +0 -27
  106. package/src/components/ui/table.tsx +0 -117
  107. package/src/components/ui/tabs.tsx +0 -53
  108. package/src/components/ui/textarea.tsx +0 -22
  109. package/src/components/ui/toggle-group.tsx +0 -61
  110. package/src/components/ui/toggle.tsx +0 -43
  111. package/src/components/ui/tooltip.tsx +0 -30
  112. package/src/hooks/use-mobile.tsx +0 -19
  113. package/src/index.ts +0 -24
  114. package/src/lib/countries.ts +0 -203
  115. package/src/lib/index.ts +0 -2
  116. package/src/lib/utils.ts +0 -15
  117. package/src/lib/validators/index.ts +0 -1
  118. package/src/lib/validators/theme.ts +0 -148
  119. package/src/molecules/creator-discovery/AudienceDemographicsCard/AudienceDemographicsCard.tsx +0 -44
  120. package/src/molecules/creator-discovery/AudienceDemographicsCard/index.ts +0 -1
  121. package/src/molecules/creator-discovery/AudienceMetricCard/AudienceMetricCard.tsx +0 -50
  122. package/src/molecules/creator-discovery/AudienceMetricCard/index.ts +0 -1
  123. package/src/molecules/creator-discovery/BrandAffinityGroup/BrandAffinityGroup.tsx +0 -36
  124. package/src/molecules/creator-discovery/BrandAffinityGroup/index.ts +0 -1
  125. package/src/molecules/creator-discovery/CampaignSeedCard/CampaignSeedCard.tsx +0 -123
  126. package/src/molecules/creator-discovery/CampaignSeedCard/CampaignSeedCard.types.ts +0 -13
  127. package/src/molecules/creator-discovery/CampaignSeedCard/index.ts +0 -2
  128. package/src/molecules/creator-discovery/ContentPreviewGallery/ContentPreviewGallery.tsx +0 -41
  129. package/src/molecules/creator-discovery/ContentPreviewGallery/index.ts +0 -1
  130. package/src/molecules/creator-discovery/CreatorActionHeader/CreatorActionHeader.tsx +0 -77
  131. package/src/molecules/creator-discovery/CreatorActionHeader/index.ts +0 -1
  132. package/src/molecules/creator-discovery/CreatorGridCard/CreatorGridCard.tsx +0 -104
  133. package/src/molecules/creator-discovery/CreatorGridCard/index.ts +0 -1
  134. package/src/molecules/creator-discovery/CreatorProfileSummary/CreatorProfileSummary.tsx +0 -65
  135. package/src/molecules/creator-discovery/CreatorProfileSummary/index.ts +0 -1
  136. package/src/molecules/creator-discovery/GrowthChartCard/GrowthChartCard.tsx +0 -58
  137. package/src/molecules/creator-discovery/GrowthChartCard/index.ts +0 -1
  138. package/src/molecules/creator-discovery/MCQCard/MCQCard.tsx +0 -165
  139. package/src/molecules/creator-discovery/MCQCard/MCQCard.types.ts +0 -71
  140. package/src/molecules/creator-discovery/MCQCard/index.ts +0 -2
  141. package/src/molecules/creator-discovery/PlatformIconGroup/PlatformIconGroup.tsx +0 -72
  142. package/src/molecules/creator-discovery/PlatformIconGroup/index.ts +0 -1
  143. package/src/molecules/creator-discovery/SearchSpecCard/CustomFieldRenderers.tsx +0 -334
  144. package/src/molecules/creator-discovery/SearchSpecCard/SearchSpecCard.tsx +0 -111
  145. package/src/molecules/creator-discovery/SearchSpecCard/SearchSpecCard.types.ts +0 -18
  146. package/src/molecules/creator-discovery/SearchSpecCard/index.ts +0 -3
  147. package/src/molecules/creator-discovery/TopPostsGrid/TopPostsGrid.tsx +0 -49
  148. package/src/molecules/creator-discovery/TopPostsGrid/index.ts +0 -1
  149. package/src/molecules/creator-discovery/index.ts +0 -13
  150. package/src/molecules/generic/ActionButton/ActionButton.tsx +0 -137
  151. package/src/molecules/generic/ActionButton/ActionButton.types.ts +0 -68
  152. package/src/molecules/generic/ActionButton/index.ts +0 -2
  153. package/src/molecules/generic/DataGrid/DataGrid.tsx +0 -102
  154. package/src/molecules/generic/DataGrid/index.ts +0 -1
  155. package/src/molecules/generic/EditableField/EditableField.tsx +0 -229
  156. package/src/molecules/generic/EditableField/EditableField.types.ts +0 -73
  157. package/src/molecules/generic/EditableField/index.ts +0 -2
  158. package/src/molecules/generic/EmptyState/EmptyState.tsx +0 -61
  159. package/src/molecules/generic/EmptyState/index.ts +0 -1
  160. package/src/molecules/generic/FileUpload/FileUpload.tsx +0 -62
  161. package/src/molecules/generic/FileUpload/index.ts +0 -1
  162. package/src/molecules/generic/FilterBar/FilterBar.tsx +0 -54
  163. package/src/molecules/generic/FilterBar/index.ts +0 -1
  164. package/src/molecules/generic/FormCard/FormCard.tsx +0 -136
  165. package/src/molecules/generic/FormCard/FormCard.types.ts +0 -93
  166. package/src/molecules/generic/FormCard/index.ts +0 -2
  167. package/src/molecules/generic/LoadingOverlay/LoadingOverlay.tsx +0 -39
  168. package/src/molecules/generic/LoadingOverlay/index.ts +0 -1
  169. package/src/molecules/generic/NotificationList/NotificationList.tsx +0 -80
  170. package/src/molecules/generic/NotificationList/index.ts +0 -1
  171. package/src/molecules/generic/StatsGrid/StatsGrid.tsx +0 -80
  172. package/src/molecules/generic/StatsGrid/index.ts +0 -1
  173. package/src/molecules/generic/StepWizard/StepWizard.tsx +0 -67
  174. package/src/molecules/generic/StepWizard/index.ts +0 -1
  175. package/src/molecules/generic/TagCloud/TagCloud.tsx +0 -32
  176. package/src/molecules/generic/TagCloud/index.ts +0 -1
  177. package/src/molecules/generic/index.ts +0 -12
  178. package/src/molecules/index.ts +0 -2
  179. package/src/render/PXEngineRenderer.tsx +0 -458
  180. package/src/render/index.ts +0 -1
  181. package/src/styles/globals.css +0 -146
  182. package/src/types/atoms.ts +0 -450
  183. package/src/types/common.ts +0 -116
  184. package/src/types/index.ts +0 -3
  185. package/src/types/molecules.ts +0 -279
  186. package/src/types/schema.ts +0 -12
@@ -1,458 +0,0 @@
1
- import React from "react";
2
- import { UIComponent, UISchema } from "../types/schema";
3
- import * as Atoms from "../atoms";
4
- import * as Molecules from "../molecules/index";
5
-
6
- // Import all shadcn UI components
7
- import * as UIComponents from "../components/ui/index";
8
-
9
- /**
10
- * Components that require specific React Context and cannot be rendered in isolation.
11
- * These components will show helpful error messages if used directly in schemas.
12
- */
13
- const CONTEXT_DEPENDENT_COMPONENTS = new Set([
14
- // Form components - require FormField + FormItem context
15
- "FormLabel",
16
- "FormControl",
17
- "FormDescription",
18
- "FormMessage",
19
- "FormItem",
20
- "FormField",
21
- // Select components - require Select parent
22
- "SelectContent",
23
- "SelectItem",
24
- "SelectValue",
25
- "SelectTrigger",
26
- "SelectGroup",
27
- "SelectLabel",
28
- "SelectSeparator",
29
- // Accordion components - require Accordion parent
30
- "AccordionContent",
31
- "AccordionItem",
32
- "AccordionTrigger",
33
- // Tabs components - require Tabs parent
34
- "TabsContent",
35
- "TabsList",
36
- "TabsTrigger",
37
- // Dialog components - require Dialog parent
38
- "DialogContent",
39
- "DialogHeader",
40
- "DialogFooter",
41
- "DialogTitle",
42
- "DialogDescription",
43
- "DialogClose",
44
- // Sheet components - require Sheet parent
45
- "SheetContent",
46
- "SheetHeader",
47
- "SheetFooter",
48
- "SheetTitle",
49
- "SheetDescription",
50
- "SheetClose",
51
- // AlertDialog components - require AlertDialog parent
52
- "AlertDialogContent",
53
- "AlertDialogHeader",
54
- "AlertDialogFooter",
55
- "AlertDialogTitle",
56
- "AlertDialogDescription",
57
- "AlertDialogAction",
58
- "AlertDialogCancel",
59
- // Dropdown components - require DropdownMenu parent
60
- "DropdownMenuContent",
61
- "DropdownMenuItem",
62
- "DropdownMenuLabel",
63
- "DropdownMenuSeparator",
64
- "DropdownMenuCheckboxItem",
65
- "DropdownMenuRadioItem",
66
- "DropdownMenuRadioGroup",
67
- // Popover components - require Popover parent
68
- "PopoverContent",
69
- // Tooltip components - require TooltipProvider parent
70
- "TooltipContent",
71
- // Context Menu components
72
- "ContextMenuContent",
73
- "ContextMenuItem",
74
- // Navigation Menu components
75
- "NavigationMenuContent",
76
- "NavigationMenuItem",
77
- ]);
78
-
79
- /**
80
- * Mapping of problematic components to their Atom alternatives
81
- */
82
- const COMPONENT_SUGGESTIONS: Record<string, string> = {
83
- FormLabel: "FormInputAtom (with label prop)",
84
- FormControl: "FormInputAtom",
85
- FormItem: "FormInputAtom",
86
- FormField: "FormInputAtom",
87
- Select: "FormSelectAtom or InputAtom with inputType='select'",
88
- SelectContent: "FormSelectAtom or InputAtom with inputType='select'",
89
- SelectItem: "FormSelectAtom or InputAtom with inputType='select'",
90
- Tabs: "TabsAtom",
91
- TabsContent: "TabsAtom",
92
- TabsList: "TabsAtom",
93
- Dialog: "DialogAtom",
94
- DialogContent: "DialogAtom",
95
- Sheet: "SheetAtom",
96
- SheetContent: "SheetAtom",
97
- AlertDialog: "AlertDialogAtom",
98
- AlertDialogContent: "AlertDialogAtom",
99
- Accordion: "AccordionAtom",
100
- AccordionItem: "AccordionAtom",
101
- Input: "InputAtom",
102
- Textarea: "InputAtom with inputType='textarea'",
103
- };
104
-
105
- /**
106
- * PXEngineRenderer
107
- *
108
- * Handles both the full schema { version, root } and individual components.
109
- * Dynamically resolves components from Atoms/Molecules/UI Components registry.
110
- * Prevents rendering of context-dependent components to avoid React errors.
111
- */
112
- interface PXEngineRendererProps {
113
- schema: UISchema | UIComponent;
114
- onAction?: (action: string, payload?: any) => void;
115
- }
116
-
117
- /**
118
- * Renders an error message for context-dependent components
119
- */
120
- const renderContextDependentError = (
121
- componentName: string,
122
- normalizedName: string,
123
- key: string,
124
- ): React.ReactNode => {
125
- const suggestion =
126
- COMPONENT_SUGGESTIONS[normalizedName] ||
127
- `${componentName}Atom (if available)`;
128
-
129
- return (
130
- <div
131
- key={key}
132
- className="p-4 border-2 border-amber-500/50 rounded-lg bg-amber-50/80 space-y-2 my-2"
133
- >
134
- <div className="flex items-start gap-2">
135
- <span className="text-amber-600 font-bold text-lg">⚠️</span>
136
- <div className="flex-1">
137
- <p className="text-sm font-semibold text-amber-900">
138
- Invalid Component: {componentName}
139
- </p>
140
- <p className="text-xs text-amber-700 mt-1">
141
- This component requires React Context and cannot be rendered
142
- directly in schemas.
143
- </p>
144
- </div>
145
- </div>
146
- <div className="bg-white/60 p-3 rounded border border-amber-200">
147
- <p className="text-xs font-semibold text-gray-700 mb-1.5">
148
- ✓ Use instead:
149
- </p>
150
- <code className="text-xs text-blue-700 bg-blue-50 px-2 py-1 rounded">
151
- {suggestion}
152
- </code>
153
- </div>
154
- </div>
155
- );
156
- };
157
-
158
- /**
159
- * Renders an error message for components not found in any registry
160
- */
161
- const renderNotFoundError = (
162
- componentName: string,
163
- key: string,
164
- ): React.ReactNode => {
165
- return (
166
- <div
167
- key={key}
168
- className="p-3 border border-dashed border-red-500/50 text-red-500 text-xs rounded bg-red-50/30 my-2"
169
- >
170
- <span className="font-semibold">❌ Unknown Component:</span>{" "}
171
- {componentName}
172
- <p className="text-[10px] text-red-400 mt-1">
173
- Component not found in Atoms, Molecules, or UI Components registry.
174
- </p>
175
- </div>
176
- );
177
- };
178
-
179
- /**
180
- * Normalizes props and extracts dynamic Tailwind-like classes into inline styles.
181
- * This ensures that user-entered colors like bg-[#ff0000] work even if not in the bundle.
182
- */
183
- const normalizeProps = (
184
- props: Record<string, any>,
185
- ): { normalized: Record<string, any>; dynamicStyle: React.CSSProperties } => {
186
- const normalized: Record<string, any> = {};
187
- const dynamicStyle: any = {};
188
-
189
- Object.entries(props).forEach(([key, value]) => {
190
- // 1. Handle className parsing for dynamic styles
191
- if (key === "className" && typeof value === "string") {
192
- // Improved split that handles Tailwind arbitrary values with spaces/underscores inside brackets
193
- const classes = value.match(/(?:[^\s\[]|\[[^\]]*\])+/g) || [];
194
- classes.forEach((cls) => {
195
- // Hex colors: bg-[#...], text-[#...], border-[#...] (supporting opacity/etc)
196
- const hexMatch = cls.match(
197
- /^(bg|text|border)-\[#([0-9a-fA-F]{3,6})(?:\/(\d+))?\]$/,
198
- );
199
- if (hexMatch) {
200
- const [, type, hex, opacity] = hexMatch;
201
- const color = `#${hex}${
202
- opacity
203
- ? Math.round((parseInt(opacity) / 100) * 255)
204
- .toString(16)
205
- .padStart(2, "0")
206
- : ""
207
- }`;
208
- if (type === "bg") dynamicStyle.backgroundColor = color;
209
- if (type === "text") dynamicStyle.color = color;
210
- if (type === "border") dynamicStyle.borderColor = color;
211
- }
212
-
213
- // Arbitrary rounding: rounded-[...]
214
- const roundedMatch = cls.match(/^rounded-\[(.+)\]$/);
215
- if (roundedMatch) {
216
- dynamicStyle.borderRadius = roundedMatch[1].replace(/_/g, " ");
217
- }
218
-
219
- // Arbitrary padding: p-[...], px-[...], py-[...]
220
- const paddingMatch = cls.match(/^(p|px|py)-\[(.+)\]$/);
221
- if (paddingMatch) {
222
- const [, type, val] = paddingMatch;
223
- const cssVal = val.replace(/_/g, " ");
224
- if (type === "p") dynamicStyle.padding = cssVal;
225
- if (type === "px") {
226
- dynamicStyle.paddingLeft = cssVal;
227
- dynamicStyle.paddingRight = cssVal;
228
- }
229
- if (type === "py") {
230
- dynamicStyle.paddingTop = cssVal;
231
- dynamicStyle.paddingBottom = cssVal;
232
- }
233
- }
234
-
235
- // Arbitrary shadows: shadow-[...]
236
- const shadowMatch = cls.match(/^shadow-\[(.+)\]$/);
237
- if (shadowMatch) {
238
- dynamicStyle.boxShadow = shadowMatch[1].replace(/_/g, " ");
239
- }
240
- });
241
- normalized[key] = value;
242
- return;
243
- }
244
-
245
- // Skip technical internal props that shouldn't leak into DOM
246
- if (["type", "component", "name"].includes(key)) {
247
- return;
248
- }
249
-
250
- // 2. Handle stringified booleans
251
- if (value === "true") {
252
- normalized[key] = true;
253
- return;
254
- }
255
- if (value === "false") {
256
- normalized[key] = false;
257
- return;
258
- }
259
-
260
- // 3. Handle stringified numbers
261
- if (
262
- typeof value === "string" &&
263
- value.trim() !== "" &&
264
- !isNaN(Number(value)) &&
265
- (value.includes(".") ||
266
- (value.length < 10 && !value.startsWith("0")) ||
267
- value === "0")
268
- ) {
269
- normalized[key] = Number(value);
270
- return;
271
- }
272
-
273
- normalized[key] = value;
274
- });
275
-
276
- return { normalized, dynamicStyle };
277
- };
278
-
279
- export const PXEngineRenderer: React.FC<PXEngineRendererProps> = ({
280
- schema,
281
- onAction,
282
- }) => {
283
- if (!schema) return null;
284
-
285
- // Extract root if it's a full UISchema
286
- const root = (schema as any).root || (schema as UIComponent);
287
-
288
- const renderRecursive = (
289
- component: UIComponent | string | any,
290
- index?: number,
291
- ): React.ReactNode => {
292
- // 1. Handle text nodes (string or number)
293
- if (typeof component === "string" || typeof component === "number") {
294
- return component;
295
- }
296
-
297
- // 2. Handle already rendered React elements
298
- if (React.isValidElement(component)) {
299
- return component;
300
- }
301
-
302
- if (!component || typeof component !== "object") return null;
303
-
304
- // Support 'component' alias for name/type
305
- const {
306
- type,
307
- name,
308
- component: componentType,
309
- props = {},
310
- children = [],
311
- id,
312
- ...remainingProps
313
- } = component;
314
-
315
- // Determine the component logic name to search for
316
- const componentName = name || type || componentType;
317
- if (!componentName || typeof componentName !== "string") return null;
318
-
319
- // Merge explicit props with flattened props (remainingProps)
320
- // Priority: explicit props > flattened props
321
- const rawProps = { ...remainingProps, ...props };
322
- const { normalized: finalProps, dynamicStyle } = normalizeProps(rawProps);
323
-
324
- // Also pass ID if not already in props
325
- if (id && !finalProps.id) {
326
- finalProps.id = id;
327
- }
328
-
329
- // Generate a unique key from id, index, or random
330
- const uniqueKey =
331
- id ||
332
- `${componentName}-${index || Math.random().toString(36).substr(2, 9)}`;
333
-
334
- // Normalize name to PascalCase for the *primary* identifier
335
- const normalizedName =
336
- componentName.charAt(0).toUpperCase() + componentName.slice(1);
337
-
338
- /**
339
- * Helper to resolve a component by a given identifier string.
340
- * Checks Atoms -> Molecules -> UI Components.
341
- */
342
- const resolveComponent = (identifier: string) => {
343
- const normalized =
344
- identifier.charAt(0).toUpperCase() + identifier.slice(1);
345
- const atomName = normalized.endsWith("Atom")
346
- ? normalized
347
- : `${normalized}Atom`;
348
-
349
- // Priority 1: Atoms
350
- let Comp =
351
- (Atoms as any)[atomName] ||
352
- (Atoms as any)[normalized] ||
353
- (Atoms as any)[identifier];
354
-
355
- // Priority 2: Molecules
356
- if (!Comp) {
357
- Comp = (Molecules as any)[normalized] || (Molecules as any)[identifier];
358
- }
359
-
360
- // Priority 3: UI Components
361
- if (!Comp && !CONTEXT_DEPENDENT_COMPONENTS.has(normalized)) {
362
- Comp =
363
- (UIComponents as any)[normalized] ||
364
- (UIComponents as any)[identifier];
365
- }
366
- return Comp;
367
- };
368
-
369
- // 1. Attempt using 'name' (or 'type' if name matches)
370
- let TargetComponent = resolveComponent(componentName);
371
- let resolvedIdentifier = componentName;
372
-
373
- // 2. FALLBACK: If 'name' failed but 'type' is different, try 'type'
374
- // This allows "name": "Dashboard" (descriptive) with "type": "layout" (functional)
375
- if (!TargetComponent && type && type !== componentName) {
376
- TargetComponent = resolveComponent(type);
377
- if (TargetComponent) {
378
- resolvedIdentifier = type;
379
- }
380
- }
381
-
382
- // 4. Handle component not found or context-dependent
383
- if (!TargetComponent) {
384
- if (CONTEXT_DEPENDENT_COMPONENTS.has(normalizedName)) {
385
- return renderContextDependentError(
386
- componentName,
387
- normalizedName,
388
- uniqueKey,
389
- );
390
- } else {
391
- // Show generic "not found" error
392
- console.warn(
393
- `[PXEngineRenderer] Component not found: ${componentName}`,
394
- );
395
- return renderNotFoundError(componentName, uniqueKey);
396
- }
397
- }
398
-
399
- // Calculate atom name for the *resolved* component to check for render props
400
- const resolvedNormalized =
401
- resolvedIdentifier.charAt(0).toUpperCase() + resolvedIdentifier.slice(1);
402
- const atomName = resolvedNormalized.endsWith("Atom")
403
- ? resolvedNormalized
404
- : `${resolvedNormalized}Atom`;
405
-
406
- // 4. Determine if component expects 'renderComponent' prop (for Atoms with children management)
407
- // Only components that explicitly handle children via renderComponent should get it
408
- const ATOMS_WITH_RENDER = new Set([
409
- "LayoutAtom",
410
- "CardAtom",
411
- "TabsAtom",
412
- "AccordionAtom",
413
- "ScrollAreaAtom",
414
- "CarouselAtom",
415
- "AspectRatioAtom",
416
- "CollapsibleAtom",
417
- "TooltipAtom",
418
- "PopoverAtom",
419
- "DialogAtom",
420
- "SheetAtom",
421
- "ResizableAtom",
422
- ]);
423
- const isAtomWithRenderProp = ATOMS_WITH_RENDER.has(atomName);
424
-
425
- // 5. Render Component
426
- // Merge dynamic style with existing style prop if any
427
- const finalStyle = { ...dynamicStyle, ...(finalProps.style || {}) };
428
-
429
- if (isAtomWithRenderProp) {
430
- // Atoms handle their own children via renderComponent
431
- return (
432
- <TargetComponent
433
- key={uniqueKey}
434
- {...finalProps}
435
- style={finalStyle}
436
- onAction={onAction}
437
- renderComponent={renderRecursive}
438
- children={children}
439
- />
440
- );
441
- } else {
442
- // Standard shadcn components - pass children as React children
443
- return (
444
- <TargetComponent key={uniqueKey} {...finalProps} style={finalStyle}>
445
- {Array.isArray(children)
446
- ? children.map((child, idx) => renderRecursive(child, idx))
447
- : children}
448
- </TargetComponent>
449
- );
450
- }
451
- };
452
-
453
- return (
454
- <div className="px-engine-root relative w-full h-full">
455
- {renderRecursive(root)}
456
- </div>
457
- );
458
- };
@@ -1 +0,0 @@
1
- export * from "./PXEngineRenderer";
@@ -1,146 +0,0 @@
1
- @tailwind base;
2
-
3
- @custom-variant dark (&:is(.dark *));
4
- @tailwind components;
5
- @tailwind utilities;
6
-
7
- @layer base {
8
- :root {
9
- --background: 0 0% 100%;
10
- --foreground: 222.2 84% 4.9%;
11
- --card: 0 0% 100%;
12
- --card-foreground: 222.2 84% 4.9%;
13
- --popover: 0 0% 100%;
14
- --popover-foreground: 222.2 84% 4.9%;
15
- --primary: 222.2 47.4% 11.2%;
16
- --primary-foreground: 210 40% 98%;
17
- --secondary: 210 40% 96.1%;
18
- --secondary-foreground: 222.2 47.4% 11.2%;
19
- --muted: 210 40% 96.1%;
20
- --muted-foreground: 215.4 16.3% 46.9%;
21
- --accent: 210 40% 96.1%;
22
- --accent-foreground: 222.2 47.4% 11.2%;
23
- --destructive: 0 84.2% 60.2%;
24
- --destructive-foreground: 210 40% 98%;
25
- --border: 214.3 31.8% 91.4%;
26
- --input: 214.3 31.8% 91.4%;
27
- --ring: 222.2 84% 4.9%;
28
- --radius: 0.5rem;
29
-
30
- /* Custom theme variables (will be inherited from client) */
31
- --gray25: #fcfcfd;
32
- --gray50: #f9fafb;
33
- --gray100: #f2f4f7;
34
- --gray200: #eaecf0;
35
- --gray300: #d0d5dd;
36
- --gray400: #98a2b3;
37
- --gray500: #667085;
38
- --gray600: #475467;
39
- --gray700: #344054;
40
- --gray800: #1d2939;
41
- --gray900: #101828;
42
- --purple100: #f4f3ff;
43
- --purple200: #988cff;
44
- --purple500: #6941c6;
45
- --purple-text: #7f56d9;
46
- --purple50: #f9f5ff;
47
- --purple20: #f4ebff;
48
- --purple-border: #d6bbfb;
49
- --purpleLight: #f4f3ff;
50
- --purple-text-1: #7f56d9;
51
- --purple-text-2: #6941c6;
52
- }
53
-
54
- .dark {
55
- --background: 222.2 84% 4.9%;
56
- --foreground: 210 40% 98%;
57
- --card: 222.2 84% 4.9%;
58
- --card-foreground: 210 40% 98%;
59
- --popover: 222.2 84% 4.9%;
60
- --popover-foreground: 210 40% 98%;
61
- --primary: 210 40% 98%;
62
- --primary-foreground: 222.2 47.4% 11.2%;
63
- --secondary: 217.2 32.6% 17.5%;
64
- --secondary-foreground: 210 40% 98%;
65
- --muted: 217.2 32.6% 17.5%;
66
- --muted-foreground: 215 20.2% 65.1%;
67
- --accent: 217.2 32.6% 17.5%;
68
- --accent-foreground: 210 40% 98%;
69
- --destructive: 0 62.8% 30.6%;
70
- --destructive-foreground: 210 40% 98%;
71
- --border: 217.2 32.6% 17.5%;
72
- --input: 217.2 32.6% 17.5%;
73
- --ring: 212.7 26.8% 83.9%;
74
- }
75
- }
76
-
77
- @layer base {
78
- * {
79
- @apply border-border;
80
- }
81
- body {
82
- @apply bg-background text-foreground;
83
- }
84
- }
85
-
86
- :root {
87
- --sidebar: hsl(0 0% 98%);
88
- --sidebar-foreground: hsl(240 5.3% 26.1%);
89
- --sidebar-primary: hsl(240 5.9% 10%);
90
- --sidebar-primary-foreground: hsl(0 0% 98%);
91
- --sidebar-accent: hsl(240 4.8% 95.9%);
92
- --sidebar-accent-foreground: hsl(240 5.9% 10%);
93
- --sidebar-border: hsl(220 13% 91%);
94
- --sidebar-ring: hsl(217.2 91.2% 59.8%);
95
- }
96
-
97
- .dark {
98
- --sidebar: hsl(240 5.9% 10%);
99
- --sidebar-foreground: hsl(240 4.8% 95.9%);
100
- --sidebar-primary: hsl(224.3 76.3% 48%);
101
- --sidebar-primary-foreground: hsl(0 0% 100%);
102
- --sidebar-accent: hsl(240 3.7% 15.9%);
103
- --sidebar-accent-foreground: hsl(240 4.8% 95.9%);
104
- --sidebar-border: hsl(240 3.7% 15.9%);
105
- --sidebar-ring: hsl(217.2 91.2% 59.8%);
106
- }
107
-
108
- @theme inline {
109
- --color-sidebar: var(--sidebar);
110
- --color-sidebar-foreground: var(--sidebar-foreground);
111
- --color-sidebar-primary: var(--sidebar-primary);
112
- --color-sidebar-primary-foreground: var(--sidebar-primary-foreground);
113
- --color-sidebar-accent: var(--sidebar-accent);
114
- --color-sidebar-accent-foreground: var(--sidebar-accent-foreground);
115
- --color-sidebar-border: var(--sidebar-border);
116
- --color-sidebar-ring: var(--sidebar-ring);
117
- --animate-accordion-down: accordion-down 0.2s ease-out;
118
- --animate-accordion-up: accordion-up 0.2s ease-out;
119
-
120
- @keyframes accordion-down {
121
- from {
122
- height: 0;
123
- }
124
- to {
125
- height: var(--radix-accordion-content-height);
126
- }
127
- }
128
-
129
- @keyframes accordion-up {
130
- from {
131
- height: var(--radix-accordion-content-height);
132
- }
133
- to {
134
- height: 0;
135
- }
136
- }
137
- }
138
-
139
- @layer base {
140
- * {
141
- @apply border-border outline-ring/50;
142
- }
143
- body {
144
- @apply bg-background text-foreground;
145
- }
146
- }