feat: Add brand identity import to theme system#146
feat: Add brand identity import to theme system#146LucasSantana-Dev wants to merge 5 commits intomainfrom
Conversation
|
Warning Rate limit exceeded
⌛ How to resolve this issue?After the wait time has elapsed, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout. Please see our FAQ for further information. 📒 Files selected for processing (4)
WalkthroughThis PR introduces brand identity import functionality and metadata support throughout the application. It adds a new Changes
Sequence DiagramsequenceDiagram
participant User
participant ThemeSelector
participant ThemeStore
participant DesignContext
participant API as Generate API
User->>ThemeSelector: Paste brand JSON
ThemeSelector->>ThemeStore: importBrand(json)
ThemeStore->>ThemeStore: parseBrandIdentity(json)
ThemeStore->>ThemeStore: createTheme(brandTheme)
ThemeStore-->>ThemeSelector: Return theme ID
ThemeSelector->>ThemeSelector: Set as active theme
DesignContext->>ThemeStore: useThemeStore(projectId)
ThemeStore-->>DesignContext: Return activeTheme.brandMeta
DesignContext->>DesignContext: Render BrandInfo
User->>API: Generate with design context
API->>API: Include brandHeadingFont, brandBodyFont, brandSemanticColors
API-->>User: Design generated with brand styling
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Possibly related PRs
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Comment |
Connect branding-mcp output to the siza webapp generation pipeline. Users can now paste BrandIdentity JSON into the existing Import Theme flow — auto-detected by checking for colors.primary.hex. Maps brand colors, typography, spacing, and border radius to SizaTheme values, stores extra BrandMeta (font names, semantic colors, neutrals) for richer AI prompt context. Brand themes show a "brand" badge in the selector and display font info in the design panel. - Add BrandMeta interface and brandMeta field to SizaTheme - Add parseBrandIdentity() with font/spacing/radius mapping - Add importBrand() store action - Smart import: try brand first, fall back to theme format - Pass brandHeadingFont, brandBodyFont, brandSemanticColors to API - Extend Zod schema and design context block in route.ts - 13 new tests for parseBrandIdentity and importBrand (33 total)
de473f0 to
4b0d686
Compare
Add brand identity CHANGELOG entry and bump version to 0.15.0.
| else if (spacingUnit >= 12) spacing = 'spacious'; | ||
|
|
||
| const radiusMd = data.borders?.radii?.md ?? 8; | ||
| let borderRadius: SizaTheme['borderRadius'] = 'medium'; |
Check warning
Code scanning / CodeQL
Useless assignment to local variable Warning
There was a problem hiding this comment.
🧹 Nitpick comments (2)
apps/web/src/components/generator/DesignContext.tsx (1)
82-91: Consider memoizing the selector to avoid potential re-renders.The current pattern
useThemeStore((s) => s.getActiveTheme)(projectId)invokes the action on every render. While functionally correct, this creates a new function reference each time. Consider usinguseMemoor restructuring if performance becomes a concern.♻️ Alternative pattern using useMemo
function BrandInfo({ projectId }: { projectId: string }) { - const activeTheme = useThemeStore((s) => s.getActiveTheme)(projectId); + const getActiveTheme = useThemeStore((s) => s.getActiveTheme); + const activeTheme = useMemo(() => getActiveTheme(projectId), [getActiveTheme, projectId]); if (!activeTheme?.brandMeta) return null;Note: This requires importing
useMemofrom React.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@apps/web/src/components/generator/DesignContext.tsx` around lines 82 - 91, The BrandInfo component creates a new selector function each render by calling useThemeStore((s) => s.getActiveTheme)(projectId); change this to memoize the selector so the selector reference is stable: import useMemo from React and create const selectActiveTheme = useMemo(() => (s) => s.getActiveTheme(projectId), [projectId]); then call const activeTheme = useThemeStore(selectActiveTheme); this keeps BrandInfo, useThemeStore and getActiveTheme usage but prevents a new function reference on every render.apps/web/src/components/generator/ThemeSelector.tsx (1)
137-154: Extract shared post-import success handling to avoid duplication.Both brand and theme import branches repeat the same success steps. Pull that into a helper to reduce drift risk.
♻️ Suggested refactor
+ const applyImportedTheme = (themeId: string) => { + setImporting(false); + setImportJson(''); + setActiveTheme(projectId, themeId); + const newTheme = getThemes().find((t) => t.id === themeId); + if (newTheme) onSelectTheme(themeToValues(newTheme)); + setOpen(false); + }; + const handleImportSubmit = () => { setImportError(''); const brandResult = importBrand(importJson); if (brandResult) { - setImporting(false); - setImportJson(''); - setActiveTheme(projectId, brandResult); - const newTheme = getThemes().find((t) => t.id === brandResult); - if (newTheme) onSelectTheme(themeToValues(newTheme)); - setOpen(false); + applyImportedTheme(brandResult); return; } const id = importTheme(importJson); if (id) { - setImporting(false); - setImportJson(''); - setActiveTheme(projectId, id); - const newTheme = getThemes().find((t) => t.id === id); - if (newTheme) onSelectTheme(themeToValues(newTheme)); - setOpen(false); + applyImportedTheme(id); } else { setImportError('Invalid theme or brand identity JSON'); } };🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@apps/web/src/components/generator/ThemeSelector.tsx` around lines 137 - 154, Both import branches repeat the same post-success steps; extract them into a helper (e.g., handleImportSuccess) that accepts the theme/brand id and performs setImporting(false), setImportJson(''), setActiveTheme(projectId, id), finds the theme via getThemes().find(t => t.id === id) and calls onSelectTheme(themeToValues(theme)) if found, then setOpen(false); replace the duplicated blocks after importBrand(importJson) and importTheme(importJson) to call this helper with the returned id.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Nitpick comments:
In `@apps/web/src/components/generator/DesignContext.tsx`:
- Around line 82-91: The BrandInfo component creates a new selector function
each render by calling useThemeStore((s) => s.getActiveTheme)(projectId); change
this to memoize the selector so the selector reference is stable: import useMemo
from React and create const selectActiveTheme = useMemo(() => (s) =>
s.getActiveTheme(projectId), [projectId]); then call const activeTheme =
useThemeStore(selectActiveTheme); this keeps BrandInfo, useThemeStore and
getActiveTheme usage but prevents a new function reference on every render.
In `@apps/web/src/components/generator/ThemeSelector.tsx`:
- Around line 137-154: Both import branches repeat the same post-success steps;
extract them into a helper (e.g., handleImportSuccess) that accepts the
theme/brand id and performs setImporting(false), setImportJson(''),
setActiveTheme(projectId, id), finds the theme via getThemes().find(t => t.id
=== id) and calls onSelectTheme(themeToValues(theme)) if found, then
setOpen(false); replace the duplicated blocks after importBrand(importJson) and
importTheme(importJson) to call this helper with the returned id.
ℹ️ Review info
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (1)
CHANGELOG.mdis excluded by!**/*.md
📒 Files selected for processing (9)
apps/web/package.jsonapps/web/src/__tests__/stores/theme-store.test.tsapps/web/src/app/api/generate/route.tsapps/web/src/components/generator/DesignContext.tsxapps/web/src/components/generator/GeneratorForm.tsxapps/web/src/components/generator/ThemeSelector.tsxapps/web/src/lib/api/generation.tsapps/web/src/stores/theme-store.tspackage.json
|
Closing: the generate route brand fields were merged via #148 (v0.15.0). The theme store brand import and UI features need a fresh branch based on current main — the service layer refactoring makes this PR unrebaseable. |
Summary
colors.primary.hex, falls back to standard theme formatbrandHeadingFont,brandBodyFont,brandSemanticColorsto generation APITest plan
parseBrandIdentity()andimportBrand()(33 total in theme-store)🤖 Generated with Claude Code
Summary by CodeRabbit
Release Notes - Version 0.15.0