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
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -48,3 +48,6 @@ docs/.vitepress/cache
apps/site/.next
apps/site/.map.ts
apps/site/.source

# Test artifacts
test-screenshots
2 changes: 1 addition & 1 deletion packages/components/src/renderers/basic/button-group.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ ComponentRegistry.register('button-group',

return (
<div
className={cn('inline-flex rounded-md shadow-sm', schema.className)}
className={cn('flex flex-wrap sm:inline-flex rounded-md shadow-sm', schema.className)}
role="group"
{...buttonGroupProps}
{...{ 'data-obj-id': dataObjId, 'data-obj-type': dataObjType, style }}
Expand Down
2 changes: 1 addition & 1 deletion packages/components/src/renderers/basic/div.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ ComponentRegistry.register('div',
{ name: 'className', type: 'string', label: 'CSS Class' }
],
defaultProps: {
className: 'p-4 border border-dashed border-gray-300 rounded min-h-[100px]'
className: 'p-2 sm:p-4 border border-dashed border-gray-300 rounded min-h-[100px]'
}
}
);
5 changes: 4 additions & 1 deletion packages/components/src/renderers/basic/image.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,9 @@ ComponentRegistry.register('image',
{ name: 'src', type: 'string', label: 'Source URL' },
{ name: 'alt', type: 'string', label: 'Alt Text' },
{ name: 'className', type: 'string', label: 'Classes' }
]
],
defaultProps: {
className: 'max-w-full h-auto'
}
Comment on lines +43 to +46
Copy link

Copilot AI Jan 23, 2026

Choose a reason for hiding this comment

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

The added defaultProps.className improves the designer “dropped” defaults, but SchemaRenderer does not apply defaultProps at runtime (packages/react/src/SchemaRenderer.tsx:30-37). As a result, schemas that omit className will still render <img> without max-w-full h-auto, so this change may not fully deliver the stated responsive default behavior outside the designer. If the goal is a true runtime default, set a fallback class in the renderer when className is empty and merge it with the provided className.

Copilot uses AI. Check for mistakes.
}
);
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ ComponentRegistry.register('navigation-menu',
<>
<NavigationMenuTrigger>{item.label}</NavigationMenuTrigger>
<NavigationMenuContent>
<ul className="grid w-[400px] gap-3 p-4 md:w-[500px] md:grid-cols-2 lg:w-[600px]">
<ul className="grid w-full gap-3 p-4 sm:w-[400px] md:w-[500px] md:grid-cols-2 lg:w-[600px]">
{item.children.map((child, childIdx) => (
<li key={childIdx}>
<NavigationMenuLink asChild>
Expand Down
2 changes: 1 addition & 1 deletion packages/components/src/renderers/basic/separator.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ ComponentRegistry.register('separator',
],
defaultProps: {
orientation: 'horizontal',
className: 'my-4'
className: 'my-2 sm:my-4'
}
}
);
2 changes: 1 addition & 1 deletion packages/components/src/renderers/basic/span.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ ComponentRegistry.register('span',
{ name: 'className', type: 'string', label: 'CSS Class' }
],
defaultProps: {
className: 'px-2 py-1'
className: 'px-1.5 py-0.5 sm:px-2 sm:py-1'
},
defaultChildren: [
{ type: 'text', content: 'Inline text' }
Expand Down
6 changes: 3 additions & 3 deletions packages/components/src/renderers/complex/carousel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -58,9 +58,9 @@ ComponentRegistry.register('carousel',
orientation: 'horizontal',
showArrows: true,
items: [
[{ type: 'div', className: 'p-8 border rounded bg-slate-50', body: [{ type: 'text', content: 'Slide 1' }] }],
[{ type: 'div', className: 'p-8 border rounded bg-slate-50', body: [{ type: 'text', content: 'Slide 2' }] }],
[{ type: 'div', className: 'p-8 border rounded bg-slate-50', body: [{ type: 'text', content: 'Slide 3' }] }]
[{ type: 'div', className: 'p-4 sm:p-6 md:p-8 border rounded bg-slate-50', body: [{ type: 'text', content: 'Slide 1' }] }],
[{ type: 'div', className: 'p-4 sm:p-6 md:p-8 border rounded bg-slate-50', body: [{ type: 'text', content: 'Slide 2' }] }],
[{ type: 'div', className: 'p-4 sm:p-6 md:p-8 border rounded bg-slate-50', body: [{ type: 'text', content: 'Slide 3' }] }]
],
className: 'w-full max-w-xs'
}
Expand Down
2 changes: 1 addition & 1 deletion packages/components/src/renderers/data-display/kbd.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ ComponentRegistry.register('kbd',
const keys = Array.isArray(schema.keys) ? schema.keys : [schema.keys || schema.label || 'K'];

return (
<div className={cn('inline-flex gap-1', schema.className)}>
<div className={cn('inline-flex flex-wrap gap-1', schema.className)}>
{keys.map((key, idx) => (
<kbd
key={idx}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import { TrendingUp, TrendingDown, Minus } from 'lucide-react';
const StatisticRenderer = ({ schema }: { schema: StatisticSchema }) => {
return (
<div className={cn(
"group relative flex flex-col p-6 rounded-xl border bg-card text-card-foreground shadow-sm",
"group relative flex flex-col p-4 sm:p-5 md:p-6 rounded-xl border bg-card text-card-foreground shadow-sm",
schema.className
)}>
{/* Label */}
Expand Down
4 changes: 2 additions & 2 deletions packages/components/src/renderers/form/file-upload.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ ComponentRegistry.register('file-upload',
<div
onClick={handleClick}
className={cn(
"relative overflow-hidden cursor-pointer rounded-lg border-2 border-dashed transition-all duration-300 min-h-[120px] flex flex-col items-center justify-center p-6 gap-3",
"relative overflow-hidden cursor-pointer rounded-lg border-2 border-dashed transition-all duration-300 min-h-[120px] flex flex-col items-center justify-center p-4 sm:p-6 gap-3",
isUploading
? "border-cyan-400 bg-cyan-950/30"
: "border-slate-700 bg-slate-900/50 hover:bg-slate-900 hover:border-cyan-500/50 hover:shadow-[0_0_20px_-5px_rgba(6,182,212,0.3)]"
Expand Down Expand Up @@ -141,7 +141,7 @@ ComponentRegistry.register('file-upload',

<div className="flex items-center gap-3 z-10">
<CheckCircle2 className="w-4 h-4 text-emerald-500 rounded-full" />
<span className="truncate max-w-[200px] text-muted-foreground group-hover/file:text-foreground font-mono text-xs transition-colors">{file.name}</span>
<span className="truncate max-w-[150px] sm:max-w-[200px] md:max-w-[300px] text-muted-foreground group-hover/file:text-foreground font-mono text-xs transition-colors">{file.name}</span>
</div>

<Button
Expand Down
7 changes: 4 additions & 3 deletions packages/components/src/renderers/form/form.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -126,11 +126,12 @@ ComponentRegistry.register('form',
};

// Determine grid classes based on columns (explicit classes for Tailwind JIT)
// Mobile-first: 1 column on mobile, 2 on sm, then md/lg for larger values
const gridColsClass =
columns === 1 ? '' :
columns === 2 ? 'md:grid-cols-2' :
columns === 3 ? 'md:grid-cols-3' :
'md:grid-cols-4';
columns === 2 ? 'sm:grid-cols-2' :
columns === 3 ? 'sm:grid-cols-2 md:grid-cols-3' :
'sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-4';

const gridClass = columns > 1
? cn('grid gap-4', gridColsClass)
Expand Down
24 changes: 12 additions & 12 deletions packages/components/src/renderers/layout/container.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -36,19 +36,19 @@ const ContainerRenderer = forwardRef<HTMLDivElement, { schema: ContainerSchema;
maxWidth === 'screen' && 'max-w-screen-2xl',
// Centering
centered && 'mx-auto',
// Padding
// Padding - Mobile-first responsive
padding === 0 && 'p-0',
padding === 1 && 'p-1',
padding === 2 && 'p-2',
padding === 3 && 'p-3',
padding === 4 && 'p-4',
padding === 5 && 'p-5',
padding === 6 && 'p-6',
padding === 7 && 'p-7',
padding === 8 && 'p-8',
padding === 10 && 'p-10',
padding === 12 && 'p-12',
padding === 16 && 'p-16',
padding === 1 && 'p-0.5 sm:p-1',
padding === 2 && 'p-1 sm:p-2',
padding === 3 && 'p-2 sm:p-3',
padding === 4 && 'p-2 sm:p-3 md:p-4',
padding === 5 && 'p-3 sm:p-4 md:p-5',
padding === 6 && 'p-3 sm:p-4 md:p-6',
padding === 7 && 'p-4 sm:p-5 md:p-7',
padding === 8 && 'p-4 sm:p-6 md:p-8',
padding === 10 && 'p-5 sm:p-7 md:p-10',
padding === 12 && 'p-6 sm:p-8 md:p-12',
padding === 16 && 'p-8 sm:p-10 md:p-16',
className
);

Expand Down
16 changes: 8 additions & 8 deletions packages/components/src/renderers/layout/flex.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -39,16 +39,16 @@ ComponentRegistry.register('flex',
align === 'center' && 'items-center',
align === 'baseline' && 'items-baseline',
align === 'stretch' && 'items-stretch',
// Gap
// Gap - Mobile-first responsive
gap === 0 && 'gap-0',
gap === 1 && 'gap-1',
gap === 2 && 'gap-2',
gap === 3 && 'gap-3',
gap === 4 && 'gap-4',
gap === 5 && 'gap-5',
gap === 6 && 'gap-6',
gap === 7 && 'gap-7',
gap === 8 && 'gap-8',
gap === 2 && 'gap-1.5 sm:gap-2',
gap === 3 && 'gap-2 sm:gap-3',
gap === 4 && 'gap-2 sm:gap-3 md:gap-4',
gap === 5 && 'gap-3 sm:gap-4 md:gap-5',
gap === 6 && 'gap-3 sm:gap-4 md:gap-6',
gap === 7 && 'gap-4 sm:gap-5 md:gap-7',
gap === 8 && 'gap-4 sm:gap-6 md:gap-8',
Comment on lines +42 to +51
Copy link

Copilot AI Jan 23, 2026

Choose a reason for hiding this comment

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

flex.tsx and stack.tsx now both maintain a long, near-identical responsive gap mapping. This duplication increases the risk of the two components drifting over time (e.g., adding a new gap value or tweaking breakpoints in one but not the other). Consider extracting the mapping into a shared helper/constant (still keeping explicit class strings for Tailwind JIT) and reusing it in both renderers.

Copilot uses AI. Check for mistakes.
// Wrap
wrap && 'flex-wrap',
className
Expand Down
2 changes: 1 addition & 1 deletion packages/components/src/renderers/layout/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ export const PageRenderer: React.FC<{ schema: PageSchema; className?: string; [k

return (
<div
className={cn("min-h-full w-full bg-background p-6 md:p-8", className)}
className={cn("min-h-full w-full bg-background p-4 md:p-6 lg:p-8", className)}
{...pageProps}
// Apply designer props
data-obj-id={dataObjId}
Expand Down
16 changes: 8 additions & 8 deletions packages/components/src/renderers/layout/stack.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -42,16 +42,16 @@ const StackRenderer = forwardRef<HTMLDivElement, { schema: StackSchema; classNam
align === 'center' && 'items-center',
align === 'baseline' && 'items-baseline',
align === 'stretch' && 'items-stretch',
// Gap
// Gap - Mobile-first responsive
gap === 0 && 'gap-0',
gap === 1 && 'gap-1',
gap === 2 && 'gap-2',
gap === 3 && 'gap-3',
gap === 4 && 'gap-4',
gap === 5 && 'gap-5',
gap === 6 && 'gap-6',
gap === 8 && 'gap-8',
gap === 10 && 'gap-10',
gap === 2 && 'gap-1.5 sm:gap-2',
gap === 3 && 'gap-2 sm:gap-3',
gap === 4 && 'gap-2 sm:gap-3 md:gap-4',
gap === 5 && 'gap-3 sm:gap-4 md:gap-5',
gap === 6 && 'gap-3 sm:gap-4 md:gap-6',
gap === 8 && 'gap-4 sm:gap-6 md:gap-8',
gap === 10 && 'gap-5 sm:gap-7 md:gap-10',
Comment on lines +45 to +54
Copy link

Copilot AI Jan 23, 2026

Choose a reason for hiding this comment

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

Same as in flex.tsx: the responsive gap mapping here duplicates the logic in packages/components/src/renderers/layout/flex.tsx (see the gap === ... clauses). Consider centralizing this mapping so the responsive spacing behavior stays consistent across both layout primitives.

Copilot uses AI. Check for mistakes.
// Wrap
wrap && 'flex-wrap',
className
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ import {

ComponentRegistry.register('header-bar',
({ schema }: { schema: HeaderBarSchema }) => (
<header className="flex h-16 shrink-0 items-center gap-2 border-b px-4">
<header className="flex h-14 sm:h-16 shrink-0 items-center gap-2 border-b px-3 sm:px-4">
<SidebarTrigger />
<Separator orientation="vertical" className="mr-2 h-4" />
<Breadcrumb>
Expand Down
2 changes: 1 addition & 1 deletion packages/components/src/renderers/overlay/context-menu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ const renderContextMenuItems = (items: any[]) => {
ComponentRegistry.register('context-menu',
({ schema, className, ...props }: { schema: ContextMenuSchema; className?: string; [key: string]: any }) => {
// Determine classes
const triggerClass = schema.triggerClassName || className || (schema.className as string) || "h-[150px] w-[300px] border border-dashed text-sm flex items-center justify-center";
const triggerClass = schema.triggerClassName || className || (schema.className as string) || "h-[120px] w-full sm:h-[150px] sm:w-[300px] border border-dashed text-sm flex items-center justify-center";
const contentClass = schema.contentClassName;

return (
Comment on lines 55 to 59
Copy link

Copilot AI Jan 23, 2026

Choose a reason for hiding this comment

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

ContextMenuSchema from @object-ui/types (packages/types/src/overlay.ts) only defines items and children, but this renderer reads schema.triggerClassName, schema.trigger, schema.modal, and schema.contentClassName. This is currently type-incompatible and forces unsafe fallbacks like (schema.className as string), and schema.className is being treated as a trigger class even though the meta input labels it as “Content CSS Class”. Consider aligning the renderer to the typed schema (use schema.children as the trigger area, and apply schema.className to ContextMenuContent), or update the ContextMenuSchema type + component meta to include the additional properties you rely on.

Copilot uses AI. Check for mistakes.
Expand Down
Loading