Skip to content

Commit 72754d9

Browse files
authored
Merge pull request #137 from objectstack-ai/copilot/fix-unknown-component-error
2 parents 9c5ba6c + 3d84c74 commit 72754d9

5 files changed

Lines changed: 74 additions & 6 deletions

File tree

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,18 @@
11
'use client';
22

33
// Import components to trigger registration
4-
import '@object-ui/components';
4+
import { initializeComponents } from '@object-ui/components';
5+
import { ComponentRegistry } from '@object-ui/core';
6+
import { useEffect } from 'react';
57

68
export function ObjectUIProvider({ children }: { children: React.ReactNode }) {
7-
// Components are auto-registered on import
9+
// Explicitly call init to ensure components are registered
10+
useEffect(() => {
11+
initializeComponents();
12+
// Log registered components for debugging
13+
const componentTypes = ComponentRegistry.getAllTypes();
14+
console.log('[ObjectUIProvider] Registered components:', componentTypes);
15+
}, []);
16+
817
return <>{children}</>;
918
}

packages/components/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
"main": "dist/index.umd.cjs",
1717
"module": "dist/index.js",
1818
"types": "dist/index.d.ts",
19+
"sideEffects": true,
1920
"exports": {
2021
".": {
2122
"types": "./dist/index.d.ts",

packages/components/src/index.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,3 +16,11 @@ export * from './lib/utils';
1616

1717
// Export raw Shadcn UI components
1818
export * from './ui';
19+
20+
// Export an init function to ensure components are registered
21+
// This is a workaround for bundlers that might tree-shake side-effect imports
22+
export function initializeComponents() {
23+
// This function exists to ensure the import side-effects above are executed
24+
// Simply importing this module should register all components
25+
return true;
26+
}

packages/components/src/renderers/basic/icon.tsx

Lines changed: 51 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,15 +10,61 @@ import { ComponentRegistry } from '@object-ui/core';
1010
import type { IconSchema } from '@object-ui/types';
1111
import { icons } from 'lucide-react';
1212
import React, { forwardRef } from 'react';
13+
import { cn } from '../../lib/utils';
14+
15+
// Convert kebab-case to PascalCase for Lucide icon names
16+
// e.g., "arrow-right" -> "ArrowRight", "home" -> "Home"
17+
function toPascalCase(str: string): string {
18+
return str
19+
.split('-')
20+
.map(word => word.charAt(0).toUpperCase() + word.slice(1))
21+
.join('');
22+
}
1323

1424
const IconRenderer = forwardRef<SVGSVGElement, { schema: IconSchema; className?: string; [key: string]: any }>(
1525
({ schema, className, ...props }, ref) => {
16-
const Icon = (icons as any)[schema.name || schema.icon];
17-
if (!Icon) return null;
18-
return <Icon ref={ref} className={className} {...props} />;
26+
// Extract designer-related props
27+
const {
28+
'data-obj-id': dataObjId,
29+
'data-obj-type': dataObjType,
30+
style,
31+
...iconProps
32+
} = props;
33+
34+
// Convert icon name to PascalCase for Lucide lookup
35+
const iconName = toPascalCase(schema.name);
36+
const Icon = (icons as any)[iconName];
37+
38+
if (!Icon) {
39+
console.warn(`Icon "${schema.name}" (lookup: "${iconName}") not found in lucide-react`);
40+
return null;
41+
}
42+
43+
// Build size style
44+
const sizeStyle = schema.size ? { width: schema.size, height: schema.size } : undefined;
45+
46+
// Merge classNames: schema color, schema className, prop className
47+
const mergedClassName = cn(
48+
schema.color,
49+
schema.className,
50+
className
51+
);
52+
53+
return (
54+
<Icon
55+
ref={ref}
56+
className={mergedClassName}
57+
style={{ ...sizeStyle, ...style }}
58+
{...iconProps}
59+
// Apply designer props
60+
{...{ 'data-obj-id': dataObjId, 'data-obj-type': dataObjType }}
61+
/>
62+
);
1963
}
2064
);
2165

66+
IconRenderer.displayName = 'IconRenderer';
67+
2268
ComponentRegistry.register('icon',
2369
IconRenderer,
2470
{
@@ -27,6 +73,8 @@ ComponentRegistry.register('icon',
2773
category: 'basic',
2874
inputs: [
2975
{ name: 'name', type: 'string', label: 'Icon Name', defaultValue: 'smile' },
76+
{ name: 'size', type: 'number', label: 'Size (px)' },
77+
{ name: 'color', type: 'string', label: 'Color Class' },
3078
{ name: 'className', type: 'string', label: 'CSS Class' }
3179
]
3280
}

packages/components/vite.config.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,11 +31,13 @@ export default defineConfig({
3131
fileName: 'index',
3232
},
3333
rollupOptions: {
34-
external: ['react', 'react-dom'],
34+
external: ['react', 'react-dom', '@object-ui/core', '@object-ui/react', '@object-ui/types'],
3535
output: {
3636
globals: {
3737
react: 'React',
3838
'react-dom': 'ReactDOM',
39+
'@object-ui/core': 'ObjectUICore',
40+
'@object-ui/react': 'ObjectUIReact',
3941
},
4042
},
4143
},

0 commit comments

Comments
 (0)