Skip to content

Commit 9db4425

Browse files
authored
Merge pull request #201 from objectstack-ai/copilot/audit-non-standard-components
2 parents 2b4fdf9 + 4bb512f commit 9db4425

File tree

18 files changed

+486
-145
lines changed

18 files changed

+486
-145
lines changed

packages/components/src/__tests__/complex-disclosure-renderers.test.tsx

Lines changed: 0 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -101,45 +101,6 @@ describe('Disclosure Renderers - Display Issue Detection', () => {
101101
* Comprehensive tests for complex renderer components
102102
*/
103103
describe('Complex Renderers - Display Issue Detection', () => {
104-
describe('Timeline Renderer', () => {
105-
it('should be properly registered', () => {
106-
const validation = validateComponentRegistration('timeline');
107-
expect(validation.isRegistered).toBe(true);
108-
});
109-
110-
it('should render timeline with events', () => {
111-
const { container } = renderComponent({
112-
type: 'timeline',
113-
items: [
114-
{
115-
title: 'Event 1',
116-
description: 'Description 1',
117-
time: '2024-01-01',
118-
},
119-
{
120-
title: 'Event 2',
121-
description: 'Description 2',
122-
time: '2024-01-02',
123-
},
124-
],
125-
});
126-
127-
expect(container.textContent).toContain('Event 1');
128-
expect(container.textContent).toContain('Event 2');
129-
});
130-
131-
it('should handle empty timeline', () => {
132-
const { container } = renderComponent({
133-
type: 'timeline',
134-
items: [],
135-
});
136-
137-
const domCheck = checkDOMStructure(container);
138-
// Empty timeline is acceptable
139-
expect(domCheck).toBeDefined();
140-
});
141-
});
142-
143104
describe('Data Table Renderer', () => {
144105
it('should be properly registered', () => {
145106
const validation = validateComponentRegistration('data-table');
@@ -188,36 +149,6 @@ describe('Complex Renderers - Display Issue Detection', () => {
188149
});
189150
});
190151

191-
describe('Chatbot Renderer', () => {
192-
it('should be properly registered', () => {
193-
const validation = validateComponentRegistration('chatbot');
194-
expect(validation.isRegistered).toBe(true);
195-
});
196-
197-
it('should render chatbot interface', () => {
198-
const { container } = renderComponent({
199-
type: 'chatbot',
200-
messages: [
201-
{ role: 'user', content: 'Hello' },
202-
{ role: 'assistant', content: 'Hi there!' },
203-
],
204-
});
205-
206-
expect(container.textContent).toContain('Hello');
207-
expect(container.textContent).toContain('Hi there!');
208-
});
209-
210-
it('should handle empty messages', () => {
211-
const { container } = renderComponent({
212-
type: 'chatbot',
213-
messages: [],
214-
});
215-
216-
const domCheck = checkDOMStructure(container);
217-
expect(domCheck).toBeDefined();
218-
});
219-
});
220-
221152
describe('Carousel Renderer', () => {
222153
it('should be properly registered', () => {
223154
const validation = validateComponentRegistration('carousel');

packages/components/src/new-components.test.ts

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -70,13 +70,4 @@ describe('New Components Registration', () => {
7070
expect(component?.label).toBe('Loading');
7171
});
7272
});
73-
74-
describe('Complex Components', () => {
75-
it('should register timeline component', () => {
76-
const component = ComponentRegistry.getConfig('timeline');
77-
expect(component).toBeDefined();
78-
expect(component?.label).toBe('Timeline');
79-
expect(component?.category).toBe('data-display');
80-
});
81-
});
8273
});

packages/components/src/renderers/complex/chatbot.test.ts

Lines changed: 0 additions & 52 deletions
This file was deleted.

packages/components/src/renderers/complex/index.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@ import './filter-builder';
1212
import './scroll-area';
1313
import './resizable';
1414
import './table';
15-
import './chatbot';
1615
import './data-table';
17-
import './timeline';
16+
1817

packages/components/src/ui/index.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@ export * from './calendar';
1919
export * from './calendar-view';
2020
export * from './card';
2121
export * from './carousel';
22-
export * from './chatbot';
2322
export * from './checkbox';
2423
export * from './collapsible';
2524
export * from './combobox';
@@ -60,7 +59,6 @@ export * from './switch';
6059
export * from './table';
6160
export * from './tabs';
6261
export * from './textarea';
63-
export * from './timeline';
6462
export * from './toast';
6563
export { Toaster as ToastNotifier } from './toaster';
6664
export * from './toggle-group';

packages/plugin-chatbot/README.md

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
# @object-ui/plugin-chatbot
2+
3+
Chatbot interface plugin for Object UI.
4+
5+
## Installation
6+
7+
```bash
8+
npm install @object-ui/plugin-chatbot
9+
```
10+
11+
## Usage
12+
13+
```tsx
14+
import { Chatbot } from '@object-ui/plugin-chatbot';
15+
16+
function App() {
17+
const [messages, setMessages] = useState([
18+
{
19+
id: '1',
20+
role: 'assistant',
21+
content: 'Hello! How can I help you today?'
22+
}
23+
]);
24+
25+
const handleSend = (content: string) => {
26+
const newMessage = {
27+
id: Date.now().toString(),
28+
role: 'user',
29+
content
30+
};
31+
setMessages([...messages, newMessage]);
32+
};
33+
34+
return (
35+
<Chatbot
36+
messages={messages}
37+
onSendMessage={handleSend}
38+
placeholder="Type your message..."
39+
/>
40+
);
41+
}
42+
```
43+
44+
## Schema-Driven Usage
45+
46+
This plugin automatically registers with ObjectUI's component registry when imported:
47+
48+
```tsx
49+
import '@object-ui/plugin-chatbot';
50+
51+
const schema = {
52+
component: 'chatbot',
53+
messages: [
54+
{ id: '1', role: 'assistant', content: 'Hello!' }
55+
],
56+
placeholder: 'Type your message...',
57+
autoResponse: true
58+
};
59+
```
60+
61+
## License
62+
63+
MIT © ObjectStack Inc.
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
{
2+
"name": "@object-ui/plugin-chatbot",
3+
"version": "0.3.0",
4+
"type": "module",
5+
"license": "MIT",
6+
"description": "Chatbot interface plugin for Object UI",
7+
"homepage": "https://www.objectui.org",
8+
"repository": {
9+
"type": "git",
10+
"url": "https://github.com/objectstack-ai/objectui.git",
11+
"directory": "packages/plugin-chatbot"
12+
},
13+
"bugs": {
14+
"url": "https://github.com/objectstack-ai/objectui/issues"
15+
},
16+
"main": "dist/index.umd.cjs",
17+
"module": "dist/index.js",
18+
"types": "dist/index.d.ts",
19+
"exports": {
20+
".": {
21+
"types": "./dist/index.d.ts",
22+
"import": "./dist/index.js",
23+
"require": "./dist/index.umd.cjs"
24+
}
25+
},
26+
"scripts": {
27+
"build": "vite build",
28+
"test": "vitest run",
29+
"test:watch": "vitest",
30+
"type-check": "tsc --noEmit",
31+
"lint": "eslint ."
32+
},
33+
"dependencies": {
34+
"@object-ui/components": "workspace:*",
35+
"@object-ui/core": "workspace:*",
36+
"@object-ui/react": "workspace:*",
37+
"@object-ui/types": "workspace:*",
38+
"lucide-react": "^0.468.0"
39+
},
40+
"peerDependencies": {
41+
"react": "^18.0.0 || ^19.0.0",
42+
"react-dom": "^18.0.0 || ^19.0.0"
43+
},
44+
"devDependencies": {
45+
"@types/react": "^19.0.6",
46+
"@types/react-dom": "^19.0.3",
47+
"@vitejs/plugin-react": "^4.2.1",
48+
"typescript": "^5.9.3",
49+
"vite": "^7.3.1",
50+
"vite-plugin-dts": "^4.5.4"
51+
}
52+
}
Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,8 @@
77
*/
88

99
import * as React from "react"
10-
import { cn } from "../lib/utils"
11-
import { Button } from "./button"
12-
import { Input } from "./input"
13-
import { ScrollArea } from "./scroll-area"
14-
import { Avatar, AvatarFallback, AvatarImage } from "./avatar"
10+
import { cn } from "@object-ui/components"
11+
import { Button, Input, ScrollArea, Avatar, AvatarFallback, AvatarImage } from "@object-ui/components"
1512
import { Send } from "lucide-react"
1613

1714
// Message type definition
@@ -246,3 +243,6 @@ const TypingIndicator = React.forwardRef<HTMLDivElement, TypingIndicatorProps>(
246243
TypingIndicator.displayName = "TypingIndicator"
247244

248245
export { Chatbot, TypingIndicator }
246+
247+
// Export renderer to register the component with ObjectUI
248+
export * from './renderer';

packages/components/src/renderers/complex/chatbot.tsx renamed to packages/plugin-chatbot/src/renderer.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88

99
import { ComponentRegistry } from '@object-ui/core';
1010
import type { ChatbotSchema, ChatMessage } from '@object-ui/types';
11-
import { Chatbot } from '../../ui';
11+
import { Chatbot } from './index';
1212
import { useState } from 'react';
1313

1414
/**
@@ -41,7 +41,7 @@ ComponentRegistry.register('chatbot',
4141
const handleSendMessage = (content: string) => {
4242
// Create user message with robust ID generation
4343
const userMessage: ChatMessage = {
44-
id: crypto.randomUUID(),
44+
id: crypto?.randomUUID?.() || `msg-${Date.now()}-${Math.random().toString(36).slice(2)}`,
4545
role: 'user',
4646
content,
4747
timestamp: schema.showTimestamp ? new Date().toLocaleTimeString() : undefined,
@@ -59,7 +59,7 @@ ComponentRegistry.register('chatbot',
5959
if (schema.autoResponse) {
6060
setTimeout(() => {
6161
const assistantMessage: ChatMessage = {
62-
id: crypto.randomUUID(),
62+
id: crypto?.randomUUID?.() || `msg-${Date.now()}-${Math.random().toString(36).slice(2)}`,
6363
role: 'assistant',
6464
content: schema.autoResponseText || 'Thank you for your message!',
6565
timestamp: schema.showTimestamp ? new Date().toLocaleTimeString() : undefined,
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
{
2+
"extends": "../../tsconfig.json",
3+
"compilerOptions": {
4+
"outDir": "dist",
5+
"jsx": "react-jsx",
6+
"baseUrl": ".",
7+
"paths": {
8+
"@/*": ["src/*"]
9+
},
10+
"noEmit": false,
11+
"declaration": true,
12+
"composite": true,
13+
"declarationMap": true,
14+
"skipLibCheck": true
15+
},
16+
"include": ["src"],
17+
"exclude": ["node_modules", "dist", "**/*.test.ts", "**/*.test.tsx"]
18+
}

0 commit comments

Comments
 (0)