Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 26 additions & 0 deletions .github/workflows/storybook-tests.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
name: Storybook Tests
on:
push:
branches: [main, develop]
pull_request:
branches: [main, develop]

jobs:
test-storybook:
timeout-minutes: 60
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: '20'
- name: Setup pnpm
uses: pnpm/action-setup@v4
with:
version: 10
- name: Install dependencies
run: pnpm install
- name: Install Playwright Browsers
run: pnpm exec playwright install --with-deps
- name: Run Storybook tests
run: pnpm test:storybook:ci
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ node_modules
dist
build
out
storybook-static

# Misc
.DS_Store
Expand Down
49 changes: 49 additions & 0 deletions .storybook/main.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import type { StorybookConfig } from "@storybook/react-vite";
import { mergeConfig } from 'vite';
import path from 'path';

const config: StorybookConfig = {
stories: ["../packages/**/src/**/*.mdx", "../packages/**/src/**/*.stories.@(js|jsx|mjs|ts|tsx)"],
addons: [
"@storybook/addon-links",
"@storybook/addon-essentials",
"@storybook/addon-interactions",
],
framework: {
name: "@storybook/react-vite",
options: {},
},
docs: {
autodocs: "tag",
},
async viteFinal(config) {
return mergeConfig(config, {
resolve: {
alias: {
// Alias components package to source to avoid circular dependency during build
'@object-ui/core': path.resolve(__dirname, '../packages/core/src/index.ts'),
'@object-ui/react': path.resolve(__dirname, '../packages/react/src/index.ts'),
'@object-ui/components': path.resolve(__dirname, '../packages/components/src/index.ts'),
'@object-ui/fields': path.resolve(__dirname, '../packages/fields/src/index.tsx'),
'@object-ui/layout': path.resolve(__dirname, '../packages/layout/src/index.ts'),
// Alias plugin packages for Storybook to resolve them from workspace
'@object-ui/plugin-aggrid': path.resolve(__dirname, '../packages/plugin-aggrid/src/index.tsx'),
'@object-ui/plugin-calendar': path.resolve(__dirname, '../packages/plugin-calendar/src/index.tsx'),
'@object-ui/plugin-charts': path.resolve(__dirname, '../packages/plugin-charts/src/index.tsx'),
'@object-ui/plugin-chatbot': path.resolve(__dirname, '../packages/plugin-chatbot/src/index.tsx'),
'@object-ui/plugin-dashboard': path.resolve(__dirname, '../packages/plugin-dashboard/src/index.tsx'),
'@object-ui/plugin-editor': path.resolve(__dirname, '../packages/plugin-editor/src/index.tsx'),
'@object-ui/plugin-form': path.resolve(__dirname, '../packages/plugin-form/src/index.tsx'),
'@object-ui/plugin-gantt': path.resolve(__dirname, '../packages/plugin-gantt/src/index.tsx'),
'@object-ui/plugin-grid': path.resolve(__dirname, '../packages/plugin-grid/src/index.tsx'),
'@object-ui/plugin-kanban': path.resolve(__dirname, '../packages/plugin-kanban/src/index.tsx'),
'@object-ui/plugin-map': path.resolve(__dirname, '../packages/plugin-map/src/index.tsx'),
'@object-ui/plugin-markdown': path.resolve(__dirname, '../packages/plugin-markdown/src/index.tsx'),
'@object-ui/plugin-timeline': path.resolve(__dirname, '../packages/plugin-timeline/src/index.tsx'),
'@object-ui/plugin-view': path.resolve(__dirname, '../packages/plugin-view/src/index.tsx'),
},
},
});
},
};
export default config;
Comment on lines +1 to +49
Copy link

Copilot AI Jan 28, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

According to Guideline #2 (Documentation Driven Development), any feature implemented or refactored must include corresponding documentation updates. This PR adds:

  • New Storybook configuration at the repository root
  • 14 new plugin story files
  • Moves Storybook from package-level to monorepo-level

However, there are no documentation updates in content/docs/guide/ to explain:

  • How to run Storybook (the new pnpm storybook command)
  • The new Storybook structure and organization
  • How to add new stories for future components

Consider adding documentation in content/docs/guide/ or updating the relevant package README files to reflect the new Storybook setup and usage patterns.

Copilot generated this review using guidance from repository custom instructions.
49 changes: 49 additions & 0 deletions .storybook/preview.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import type { Preview } from '@storybook/react-vite'
import '../packages/components/src/index.css';
import { ComponentRegistry } from '@object-ui/core';
import * as components from '../packages/components/src/index';

// Register all base components for Storybook
Object.values(components);

// Import and register all plugin components for Storybook
// This ensures plugin components are available for the plugin stories
import '@object-ui/plugin-aggrid';
import '@object-ui/plugin-calendar';
import '@object-ui/plugin-charts';
import '@object-ui/plugin-chatbot';
import '@object-ui/plugin-dashboard';
import '@object-ui/plugin-editor';
import '@object-ui/plugin-form';
import '@object-ui/plugin-gantt';
import '@object-ui/plugin-grid';
import '@object-ui/plugin-kanban';
import '@object-ui/plugin-map';
import '@object-ui/plugin-markdown';
import '@object-ui/plugin-timeline';
import '@object-ui/plugin-view';

const preview: Preview = {
parameters: {
options: {
storySort: {
method: 'alphabetical',
order: [
'Introduction',
'Guide',
'Primitives',
'Schema',
['Actions', 'Inputs', 'Layout', 'Data Display', 'Navigation', 'Feedback', 'Plugins']
],
},
},
controls: {
matchers: {
color: /(background|color)$/i,
date: /Date$/i,
},
},
},
};

export default preview;
18 changes: 16 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,10 @@
"lint": "pnpm -r lint",
"cli": "node packages/cli/dist/cli.js",
"objectui": "node packages/cli/dist/cli.js",
"build:storybook": "pnpm --filter @object-ui/components build-storybook",
"storybook": "storybook dev -p 6006",
"build:storybook": "storybook build",
"test:storybook": "test-storybook --testTimeout=90000",
"test:storybook:ci": "concurrently -k -s first \"pnpm storybook --no-open\" \"wait-on tcp:6006 && pnpm test:storybook\"",
"doctor": "node packages/cli/dist/cli.js doctor",
"studio": "node packages/cli/dist/cli.js studio",
"check": "node packages/cli/dist/cli.js check",
Expand All @@ -47,6 +50,13 @@
"devDependencies": {
"@changesets/cli": "^2.29.8",
"@eslint/js": "^9.39.1",
"@storybook/addon-essentials": "^8.6.14",
"@storybook/addon-interactions": "^8.6.14",
"@storybook/addon-links": "^8.6.15",
"@storybook/blocks": "^8.6.14",
"@storybook/react": "^8.6.15",
"@storybook/react-vite": "^8.6.15",
"@storybook/test-runner": "^0.24.2",
"@testing-library/dom": "^10.4.1",
"@testing-library/jest-dom": "^6.9.1",
"@testing-library/react": "^16.3.2",
Expand All @@ -57,22 +67,26 @@
"@vitest/coverage-v8": "^4.0.18",
"@vitest/ui": "^4.0.18",
"autoprefixer": "^10.4.23",
"concurrently": "^9.2.1",
"eslint": "^9.39.2",
"eslint-plugin-react-hooks": "^7.0.1",
"eslint-plugin-react-refresh": "^0.4.24",
"globals": "^17.1.0",
"happy-dom": "^20.3.9",
"jsdom": "^27.4.0",
"playwright": "^1.58.0",
"prettier": "^3.8.1",
"react": "19.2.3",
"react-dom": "19.2.3",
"react-router-dom": "^7.13.0",
"storybook": "^8.6.15",
"tailwindcss": "^4.1.18",
"tslib": "^2.6.0",
"turbo": "^2.7.6",
"typescript": "^5.9.3",
"typescript-eslint": "^8.53.1",
"vitest": "^4.0.18"
"vitest": "^4.0.18",
"wait-on": "^9.0.3"
},
"pnpm": {
"overrides": {
Expand Down
18 changes: 0 additions & 18 deletions packages/components/.storybook/main.ts

This file was deleted.

20 changes: 0 additions & 20 deletions packages/components/.storybook/preview.ts

This file was deleted.

5 changes: 1 addition & 4 deletions packages/components/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,7 @@
"pretest": "pnpm run prebuild",
"test": "vitest run",
"type-check": "tsc --noEmit",
"lint": "eslint .",
"storybook": "storybook dev -p 6006",
"prebuild-storybook": "pnpm run prebuild",
"build-storybook": "storybook build"
"lint": "eslint ."
},
"dependencies": {
"@object-ui/core": "workspace:*",
Expand Down
2 changes: 1 addition & 1 deletion packages/components/src/index.css
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
@import 'tailwindcss';

/* Scan sources for Tailwind classes */
@source './src/**/*.{ts,tsx}';
@source '../src/**/*.{ts,tsx}';
Copy link

Copilot AI Jan 28, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The @source path '../src/**/*.{ts,tsx}' appears incorrect. This file is located at packages/components/src/index.css, so '../src' would resolve to 'packages/components/src/src' which doesn't exist.

The original path './src/**/*.{ts,tsx}' would resolve to 'packages/components/src/src' from the CSS file's location, which also seems wrong unless there's a nested src folder.

Most likely, the @source directive should use a pattern relative to where this CSS file is processed (usually the project root or package root). Consider using './**/*.{ts,tsx}' to scan the current directory and subdirectories, or verify the intended Tailwind v4 @source pattern for this monorepo setup.

Suggested change
@source '../src/**/*.{ts,tsx}';
@source './**/*.{ts,tsx}';

Copilot uses AI. Check for mistakes.

/* Tailwind plugin for animations */
@plugin 'tailwindcss-animate';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ ComponentRegistry.register('toggle-group',
'data-obj-id': dataObjId,
'data-obj-type': dataObjType,
style,
type, // Extract type to prevent overriding the one we set below
...toggleGroupProps
} = props;

Expand Down
51 changes: 4 additions & 47 deletions packages/components/src/renderers/form/toggle.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

import { ComponentRegistry } from '@object-ui/core';
import type { ToggleSchema } from '@object-ui/types';
import { Toggle, ToggleGroup, ToggleGroupItem } from '../../ui';
import { Toggle } from '../../ui';
import { renderChildren } from '../../lib/utils';

ComponentRegistry.register('toggle',
Expand All @@ -28,9 +28,9 @@ ComponentRegistry.register('toggle',
inputs: [
{ name: 'label', type: 'string', label: 'Label' },
{ name: 'pressed', type: 'boolean', label: 'Pressed' },
{ name: 'variant', type: 'enum', enum: ['default', 'outline'], defaultValue: 'default', label: 'Variant' },
{ name: 'size', type: 'enum', enum: ['default', 'sm', 'lg'], defaultValue: 'default', label: 'Size' },
{ name: 'ariaLabel', type: 'string', label: 'Aria Label' }
{ name: 'variant', type: 'enum', index: ['default', 'outline'], defaultValue: 'default', label: 'Variant' },
{ name: 'size', type: 'enum', index: ['default', 'sm', 'lg'], defaultValue: 'default', label: 'Size' },
Comment on lines +31 to +32
Copy link

Copilot AI Jan 28, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The property name should be 'enum' not 'index'. This is inconsistent with the rest of the codebase where 'enum' is used to specify the allowed values for enum type inputs (see button-group.tsx, separator.tsx, carousel.tsx, etc.).

Change 'index' to 'enum' to maintain consistency with the established pattern.

Suggested change
{ name: 'variant', type: 'enum', index: ['default', 'outline'], defaultValue: 'default', label: 'Variant' },
{ name: 'size', type: 'enum', index: ['default', 'sm', 'lg'], defaultValue: 'default', label: 'Size' },
{ name: 'variant', type: 'enum', enum: ['default', 'outline'], defaultValue: 'default', label: 'Variant' },
{ name: 'size', type: 'enum', enum: ['default', 'sm', 'lg'], defaultValue: 'default', label: 'Size' },

Copilot uses AI. Check for mistakes.
{ name: 'ariaLabel', type: 'string', label: 'Aria Label' }
],
defaultProps: {
label: 'Toggle',
Expand All @@ -39,46 +39,3 @@ ComponentRegistry.register('toggle',
}
}
);

ComponentRegistry.register('toggle-group',
({ schema, className, ...props }) => (
<ToggleGroup
type={schema.groupType || 'single'}
variant={schema.variant}
size={schema.size}
className={className}
{...props}
>
{schema.items?.map((item: any) => (
<ToggleGroupItem key={item.value} value={item.value} aria-label={item.label}>
{item.icon || item.label}
</ToggleGroupItem>
))}
</ToggleGroup>
),
{
label: 'Toggle Group',
inputs: [
{ name: 'groupType', type: 'enum', enum: ['single', 'multiple'], defaultValue: 'single', label: 'Type' },
{ name: 'variant', type: 'enum', enum: ['default', 'outline'], defaultValue: 'default', label: 'Variant' },
{ name: 'size', type: 'enum', enum: ['default', 'sm', 'lg'], defaultValue: 'default', label: 'Size' },
{
name: 'items',
type: 'array',
label: 'Items',
description: 'Array of {label, value, icon?} objects'
},
{ name: 'className', type: 'string', label: 'CSS Class' }
],
defaultProps: {
groupType: 'single',
variant: 'default',
size: 'default',
items: [
{ label: 'A', value: 'a' },
{ label: 'B', value: 'b' },
{ label: 'C', value: 'c' }
]
}
}
);
2 changes: 1 addition & 1 deletion packages/components/src/stories-json/accordion.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { SchemaRenderer } from '../SchemaRenderer';
import type { BaseSchema } from '@object-ui/types';

const meta = {
title: 'JSON/Disclosure/Accordion',
title: 'Schema/Data Display/Accordion',
component: SchemaRenderer,
parameters: { layout: 'padded' },
tags: ['autodocs'],
Expand Down
Loading
Loading