@getcoherent/core 0.5.11 → 0.5.13

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -903,10 +903,7 @@ declare const LayoutBlockDefinitionSchema: z.ZodObject<{
903
903
  generatedCode?: string | undefined;
904
904
  }>;
905
905
  type LayoutBlockDefinition = z.infer<typeof LayoutBlockDefinitionSchema>;
906
- /**
907
- * Page layout type
908
- */
909
- declare const PageLayoutSchema: z.ZodEnum<["centered", "sidebar-left", "sidebar-right", "full-width", "grid"]>;
906
+ declare const PageLayoutSchema: z.ZodEffects<z.ZodEnum<["centered", "sidebar-left", "sidebar-right", "full-width", "grid"]>, "centered" | "sidebar-left" | "sidebar-right" | "full-width" | "grid", unknown>;
910
907
  type PageLayout = z.infer<typeof PageLayoutSchema>;
911
908
  /**
912
909
  * Page definition
@@ -956,7 +953,7 @@ declare const PageDefinitionSchema: z.ZodObject<{
956
953
  id: z.ZodPipeline<z.ZodEffects<z.ZodString, string, string>, z.ZodString>;
957
954
  name: z.ZodString;
958
955
  route: z.ZodPipeline<z.ZodEffects<z.ZodString, string, string>, z.ZodString>;
959
- layout: z.ZodEnum<["centered", "sidebar-left", "sidebar-right", "full-width", "grid"]>;
956
+ layout: z.ZodEffects<z.ZodEnum<["centered", "sidebar-left", "sidebar-right", "full-width", "grid"]>, "centered" | "sidebar-left" | "sidebar-right" | "full-width" | "grid", unknown>;
960
957
  sections: z.ZodDefault<z.ZodArray<z.ZodObject<{
961
958
  id: z.ZodString;
962
959
  name: z.ZodString;
@@ -1062,11 +1059,11 @@ declare const PageDefinitionSchema: z.ZodObject<{
1062
1059
  name: string;
1063
1060
  description: string;
1064
1061
  id: string;
1065
- layout: "centered" | "sidebar-left" | "sidebar-right" | "full-width" | "grid";
1066
1062
  createdAt: string;
1067
1063
  updatedAt: string;
1068
1064
  route: string;
1069
1065
  title: string;
1066
+ layout?: unknown;
1070
1067
  sections?: {
1071
1068
  name: string;
1072
1069
  id: string;
@@ -1251,6 +1248,7 @@ type Features = z.infer<typeof FeaturesSchema>;
1251
1248
  * This is the single source of truth
1252
1249
  */
1253
1250
  declare const DesignSystemConfigSchema: z.ZodObject<{
1251
+ provider: z.ZodDefault<z.ZodEnum<["shadcn", "custom"]>>;
1254
1252
  version: z.ZodDefault<z.ZodString>;
1255
1253
  coherentVersion: z.ZodOptional<z.ZodString>;
1256
1254
  frameworkVersions: z.ZodOptional<z.ZodObject<{
@@ -1881,7 +1879,7 @@ declare const DesignSystemConfigSchema: z.ZodObject<{
1881
1879
  id: z.ZodPipeline<z.ZodEffects<z.ZodString, string, string>, z.ZodString>;
1882
1880
  name: z.ZodString;
1883
1881
  route: z.ZodPipeline<z.ZodEffects<z.ZodString, string, string>, z.ZodString>;
1884
- layout: z.ZodEnum<["centered", "sidebar-left", "sidebar-right", "full-width", "grid"]>;
1882
+ layout: z.ZodEffects<z.ZodEnum<["centered", "sidebar-left", "sidebar-right", "full-width", "grid"]>, "centered" | "sidebar-left" | "sidebar-right" | "full-width" | "grid", unknown>;
1885
1883
  sections: z.ZodDefault<z.ZodArray<z.ZodObject<{
1886
1884
  id: z.ZodString;
1887
1885
  name: z.ZodString;
@@ -1987,11 +1985,11 @@ declare const DesignSystemConfigSchema: z.ZodObject<{
1987
1985
  name: string;
1988
1986
  description: string;
1989
1987
  id: string;
1990
- layout: "centered" | "sidebar-left" | "sidebar-right" | "full-width" | "grid";
1991
1988
  createdAt: string;
1992
1989
  updatedAt: string;
1993
1990
  route: string;
1994
1991
  title: string;
1992
+ layout?: unknown;
1995
1993
  sections?: {
1996
1994
  name: string;
1997
1995
  id: string;
@@ -2182,6 +2180,7 @@ declare const DesignSystemConfigSchema: z.ZodObject<{
2182
2180
  description: string;
2183
2181
  createdAt: string;
2184
2182
  updatedAt: string;
2183
+ provider: "custom" | "shadcn";
2185
2184
  version: string;
2186
2185
  tokens: {
2187
2186
  colors: {
@@ -2495,11 +2494,11 @@ declare const DesignSystemConfigSchema: z.ZodObject<{
2495
2494
  name: string;
2496
2495
  description: string;
2497
2496
  id: string;
2498
- layout: "centered" | "sidebar-left" | "sidebar-right" | "full-width" | "grid";
2499
2497
  createdAt: string;
2500
2498
  updatedAt: string;
2501
2499
  route: string;
2502
2500
  title: string;
2501
+ layout?: unknown;
2503
2502
  sections?: {
2504
2503
  name: string;
2505
2504
  id: string;
@@ -2567,6 +2566,7 @@ declare const DesignSystemConfigSchema: z.ZodObject<{
2567
2566
  image?: string | undefined;
2568
2567
  } | undefined;
2569
2568
  } | undefined;
2569
+ provider?: "custom" | "shadcn" | undefined;
2570
2570
  version?: string | undefined;
2571
2571
  coherentVersion?: string | undefined;
2572
2572
  frameworkVersions?: {
@@ -2697,6 +2697,32 @@ declare const EXAMPLE_MULTIPAGE_CONFIG: DesignSystemConfig;
2697
2697
  */
2698
2698
  declare const EXAMPLE_SPA_CONFIG: DesignSystemConfig;
2699
2699
 
2700
+ interface ComponentMeta {
2701
+ id: string;
2702
+ name: string;
2703
+ category: 'form' | 'layout' | 'navigation' | 'feedback' | 'data-display' | 'overlay' | 'typography';
2704
+ managed: boolean;
2705
+ }
2706
+ interface ComponentAPI {
2707
+ name: string;
2708
+ subcomponents: string[];
2709
+ importPath: string;
2710
+ keyProps: Record<string, string>;
2711
+ usage: string;
2712
+ antiPatterns: string[];
2713
+ }
2714
+ interface ComponentProvider {
2715
+ id: string;
2716
+ init(projectRoot: string): Promise<void>;
2717
+ install(name: string, projectRoot: string): Promise<void>;
2718
+ has(name: string): boolean;
2719
+ list(): ComponentMeta[];
2720
+ listNames(): string[];
2721
+ getComponentAPI(name: string): ComponentAPI | null;
2722
+ getCssVariables(tokens: DesignTokens): string;
2723
+ getThemeBlock(tokens: DesignTokens): string;
2724
+ }
2725
+
2700
2726
  /**
2701
2727
  * Types for Epic 2: Shared Components manifest (coherent.components.json).
2702
2728
  * See docs/epic-2-shared-components.md.
@@ -3418,7 +3444,7 @@ declare class PageGenerator {
3418
3444
  */
3419
3445
  generateSharedFooterCode(): string;
3420
3446
  /**
3421
- * Generate shared Sidebar component code for components/shared/sidebar.tsx.
3447
+ * Generate shared Sidebar component code using shadcn/ui Sidebar.
3422
3448
  * Used when navigation.type is 'sidebar' or 'both'.
3423
3449
  */
3424
3450
  generateSharedSidebarCode(): string;
@@ -4274,4 +4300,4 @@ interface AuditResult {
4274
4300
  */
4275
4301
  declare function runAudit(projectRoot: string): Promise<AuditResult>;
4276
4302
 
4277
- export { type AuditEntryResult, type AuditResult, type BlogContent, CLI_VERSION, type ChangelogContent, type ColorToken, ColorTokenSchema, type ComponentCriteria, type ComponentDefinition, ComponentDefinitionSchema, type ComponentDependency, ComponentGenerator, ComponentManager, type ComponentSize, ComponentSizeSchema, type ComponentSpec, type ComponentVariant, ComponentVariantSchema, type ContactContent, type CreateSharedComponentInput, type DashboardContent, type DesignSystemConfig, DesignSystemConfigSchema, DesignSystemGenerator, DesignSystemManager, type DesignTokens, DesignTokensSchema, type DiscoveryResult, EXAMPLE_MULTIPAGE_CONFIG, EXAMPLE_SPA_CONFIG, FIGMA_BASE_IDS, FRAMEWORK_VERSIONS, type FaqContent, type Features, FeaturesSchema, type FigmaBaseId, FigmaClient, type FigmaClientOptions, type FigmaColorStyle, type FigmaComponentData, type FigmaComponentMap, type FigmaComponentMeta, type FigmaDocumentNode, type FigmaEffectStyle, type FigmaFileResponse, type FigmaIntermediateData, type FigmaLayout, type FigmaNode, type FigmaNormalizationResult, type FigmaNormalizedEntry, type FigmaPageData, type FigmaProperty, type FigmaRgba, type FigmaStyleMeta, type FigmaTextStyle, type FigmaTokenExtractionResult, type FigmaVariant, type GalleryContent, type GenerateSharedComponentInput, type GenerateSharedComponentResult, type GeneratedPage, type LandingContent, type LayoutBlockDefinition, LayoutBlockDefinitionSchema, type ListingContent, type LoginContent, MANIFEST_FILENAME, type ModificationRequest, type ModificationResult, type Navigation, type NavigationItem, NavigationItemSchema, NavigationSchema, type OnboardingContent, type PageAnalysis, PageAnalysisSchema, type PageContent, type PageDefinition, PageDefinitionSchema, PageGenerator, type PageLayout, PageLayoutSchema, PageManager, type PageSection, PageSectionSchema, type PricingContent, type ProfileContent, ProjectScaffolder, type RadiusToken, RadiusTokenSchema, type RegisterContent, type SettingsContent, type SharedComponentEntry, SharedComponentEntrySchema, type SharedComponentType, SharedComponentTypeSchema, type SharedComponentsManifest, SharedComponentsManifestSchema, type SpacingToken, SpacingTokenSchema, TailwindConfigGenerator, type TemplateOptions, type TypographyToken, TypographyTokenSchema, allocateNextCid, atomicWriteFile, buildCssVariables, componentExists, createEntry, extractConfigObject, extractTokensFromFigma, figmaComponentNameToBaseId, figmaRgbaToHex, findSharedComponent, findSharedComponentByIdOrName, formatCid, generatePageFromFrame, generatePagesFromFigma, generateSharedComponent, generateSharedComponentTsx, getComponent, getManifestPath, getPage, getPageFilePath, getSupportedPageTypes, getTemplateForPageType, integrateSharedLayoutIntoRootLayout, loadManifest, mergeExtractedColorsWithDefaults, normalizeFigmaComponents, pageRouteExists, parseCid, parseFigmaFileResponse, removeEntry, resolveUniqueName, runAudit, saveManifest, setSharedMapping, toSharedFileName, updateEntry, updateUsedIn, validateConfig, validatePartialConfig };
4303
+ export { type AuditEntryResult, type AuditResult, type BlogContent, CLI_VERSION, type ChangelogContent, type ColorToken, ColorTokenSchema, type ComponentAPI, type ComponentCriteria, type ComponentDefinition, ComponentDefinitionSchema, type ComponentDependency, ComponentGenerator, ComponentManager, type ComponentMeta, type ComponentProvider, type ComponentSize, ComponentSizeSchema, type ComponentSpec, type ComponentVariant, ComponentVariantSchema, type ContactContent, type CreateSharedComponentInput, type DashboardContent, type DesignSystemConfig, DesignSystemConfigSchema, DesignSystemGenerator, DesignSystemManager, type DesignTokens, DesignTokensSchema, type DiscoveryResult, EXAMPLE_MULTIPAGE_CONFIG, EXAMPLE_SPA_CONFIG, FIGMA_BASE_IDS, FRAMEWORK_VERSIONS, type FaqContent, type Features, FeaturesSchema, type FigmaBaseId, FigmaClient, type FigmaClientOptions, type FigmaColorStyle, type FigmaComponentData, type FigmaComponentMap, type FigmaComponentMeta, type FigmaDocumentNode, type FigmaEffectStyle, type FigmaFileResponse, type FigmaIntermediateData, type FigmaLayout, type FigmaNode, type FigmaNormalizationResult, type FigmaNormalizedEntry, type FigmaPageData, type FigmaProperty, type FigmaRgba, type FigmaStyleMeta, type FigmaTextStyle, type FigmaTokenExtractionResult, type FigmaVariant, type GalleryContent, type GenerateSharedComponentInput, type GenerateSharedComponentResult, type GeneratedPage, type LandingContent, type LayoutBlockDefinition, LayoutBlockDefinitionSchema, type ListingContent, type LoginContent, MANIFEST_FILENAME, type ModificationRequest, type ModificationResult, type Navigation, type NavigationItem, NavigationItemSchema, NavigationSchema, type OnboardingContent, type PageAnalysis, PageAnalysisSchema, type PageContent, type PageDefinition, PageDefinitionSchema, PageGenerator, type PageLayout, PageLayoutSchema, PageManager, type PageSection, PageSectionSchema, type PricingContent, type ProfileContent, ProjectScaffolder, type RadiusToken, RadiusTokenSchema, type RegisterContent, type SettingsContent, type SharedComponentEntry, SharedComponentEntrySchema, type SharedComponentType, SharedComponentTypeSchema, type SharedComponentsManifest, SharedComponentsManifestSchema, type SpacingToken, SpacingTokenSchema, TailwindConfigGenerator, type TemplateOptions, type TypographyToken, TypographyTokenSchema, allocateNextCid, atomicWriteFile, buildCssVariables, componentExists, createEntry, extractConfigObject, extractTokensFromFigma, figmaComponentNameToBaseId, figmaRgbaToHex, findSharedComponent, findSharedComponentByIdOrName, formatCid, generatePageFromFrame, generatePagesFromFigma, generateSharedComponent, generateSharedComponentTsx, getComponent, getManifestPath, getPage, getPageFilePath, getSupportedPageTypes, getTemplateForPageType, integrateSharedLayoutIntoRootLayout, loadManifest, mergeExtractedColorsWithDefaults, normalizeFigmaComponents, pageRouteExists, parseCid, parseFigmaFileResponse, removeEntry, resolveUniqueName, runAudit, saveManifest, setSharedMapping, toSharedFileName, updateEntry, updateUsedIn, validateConfig, validatePartialConfig };
package/dist/index.js CHANGED
@@ -146,7 +146,7 @@ var LayoutBlockDefinitionSchema = z.object({
146
146
  createdAt: z.string().datetime().optional(),
147
147
  updatedAt: z.string().datetime().optional()
148
148
  });
149
- var PageLayoutSchema = z.enum([
149
+ var PAGE_LAYOUT_ENUM = z.enum([
150
150
  "centered",
151
151
  // Single centered column
152
152
  "sidebar-left",
@@ -158,6 +158,10 @@ var PageLayoutSchema = z.enum([
158
158
  "grid"
159
159
  // CSS Grid layout
160
160
  ]);
161
+ var PageLayoutSchema = z.preprocess((val) => {
162
+ if (val === "sidebar") return "sidebar-left";
163
+ return val;
164
+ }, PAGE_LAYOUT_ENUM);
161
165
  var PageAnalysisSchema = z.object({
162
166
  sections: z.array(
163
167
  z.object({
@@ -244,6 +248,8 @@ var FeaturesSchema = z.object({
244
248
  })
245
249
  });
246
250
  var DesignSystemConfigSchema = z.object({
251
+ // Component provider
252
+ provider: z.enum(["shadcn", "custom"]).default("shadcn"),
247
253
  // Metadata
248
254
  version: z.string().default("1.0.0"),
249
255
  coherentVersion: z.string().optional(),
@@ -314,6 +320,7 @@ function getPage(config, route) {
314
320
  return config.pages.find((p) => p.route === route);
315
321
  }
316
322
  var EXAMPLE_MULTIPAGE_CONFIG = {
323
+ provider: "shadcn",
317
324
  version: "1.0.0",
318
325
  name: "My Multi-page App",
319
326
  description: "A beautiful multi-page application",
@@ -1234,6 +1241,43 @@ function blendColors(hex1, hex2, ratio) {
1234
1241
  const toHex = (n) => n.toString(16).padStart(2, "0");
1235
1242
  return `#${toHex(blend(r1, r2))}${toHex(blend(g1, g2))}${toHex(blend(b1, b2))}`;
1236
1243
  }
1244
+ function hexToHsl(hex) {
1245
+ const c = hex.replace("#", "");
1246
+ const r = parseInt(c.slice(0, 2), 16) / 255;
1247
+ const g = parseInt(c.slice(2, 4), 16) / 255;
1248
+ const b = parseInt(c.slice(4, 6), 16) / 255;
1249
+ const max = Math.max(r, g, b), min = Math.min(r, g, b);
1250
+ const l = (max + min) / 2;
1251
+ if (max === min) return [0, 0, l];
1252
+ const d = max - min;
1253
+ const s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
1254
+ let h = 0;
1255
+ if (max === r) h = ((g - b) / d + (g < b ? 6 : 0)) / 6;
1256
+ else if (max === g) h = ((b - r) / d + 2) / 6;
1257
+ else h = ((r - g) / d + 4) / 6;
1258
+ return [h * 360, s, l];
1259
+ }
1260
+ function hslToHex(h, s, l) {
1261
+ h = (h % 360 + 360) % 360;
1262
+ const a = s * Math.min(l, 1 - l);
1263
+ const f = (n) => {
1264
+ const k = (n + h / 30) % 12;
1265
+ const color = l - a * Math.max(Math.min(k - 3, 9 - k, 1), -1);
1266
+ return Math.round(255 * Math.max(0, Math.min(1, color))).toString(16).padStart(2, "0");
1267
+ };
1268
+ return `#${f(0)}${f(8)}${f(4)}`;
1269
+ }
1270
+ function generateChartColors(primary, secondary) {
1271
+ const [h1, s1, l1] = hexToHsl(primary);
1272
+ const [h2, s2, l2] = hexToHsl(secondary);
1273
+ return [
1274
+ primary,
1275
+ secondary,
1276
+ hslToHex(h1 + 60, s1 * 0.8, l1),
1277
+ hslToHex(h2 + 90, s2 * 0.7, l2),
1278
+ hslToHex(h1 + 180, s1 * 0.6, l1)
1279
+ ];
1280
+ }
1237
1281
  function buildCssVariables(config) {
1238
1282
  const light = config.tokens.colors.light;
1239
1283
  const dark = config.tokens.colors.dark;
@@ -1243,7 +1287,31 @@ function buildCssVariables(config) {
1243
1287
  const accentDarkVars = ` --accent: ${dark.muted};
1244
1288
  --accent-foreground: ${dark.foreground};
1245
1289
  `;
1290
+ const sidebarLightVars = ` --sidebar-background: ${light.background};
1291
+ --sidebar-foreground: ${light.foreground};
1292
+ --sidebar-primary: ${light.primary};
1293
+ --sidebar-primary-foreground: ${contrastFg(light.primary)};
1294
+ --sidebar-accent: ${light.muted};
1295
+ --sidebar-accent-foreground: ${light.foreground};
1296
+ --sidebar-border: ${light.border};
1297
+ --sidebar-ring: ${light.primary};
1298
+ `;
1299
+ const chartLight = generateChartColors(light.primary, light.secondary);
1300
+ const chartDark = generateChartColors(dark.primary, dark.secondary);
1301
+ const chartLightVars = chartLight.map((c, i) => ` --chart-${i + 1}: ${c};`).join("\n") + "\n";
1302
+ const chartDarkVars = chartDark.map((c, i) => ` --chart-${i + 1}: ${c};`).join("\n") + "\n";
1303
+ const sidebarDarkVars = ` --sidebar-background: ${dark.background};
1304
+ --sidebar-foreground: ${dark.foreground};
1305
+ --sidebar-primary: ${dark.primary};
1306
+ --sidebar-primary-foreground: ${contrastFg(dark.primary)};
1307
+ --sidebar-accent: ${dark.muted};
1308
+ --sidebar-accent-foreground: ${dark.foreground};
1309
+ --sidebar-border: ${dark.border};
1310
+ --sidebar-ring: ${dark.primary};
1311
+ `;
1312
+ const radius = config.tokens.radius?.md ?? "0.5rem";
1246
1313
  return `:root {
1314
+ --radius: ${radius};
1247
1315
  --background: ${light.background};
1248
1316
  --foreground: ${light.foreground};
1249
1317
  --primary: ${light.primary};
@@ -1265,7 +1333,7 @@ function buildCssVariables(config) {
1265
1333
  --warning: ${light.warning};
1266
1334
  --error: ${light.error};
1267
1335
  --info: ${light.info || light.primary};
1268
- ${accentVars}}
1336
+ ${accentVars}${sidebarLightVars}${chartLightVars}}
1269
1337
  .dark {
1270
1338
  --background: ${dark.background};
1271
1339
  --foreground: ${dark.foreground};
@@ -1288,7 +1356,7 @@ ${accentVars}}
1288
1356
  --warning: ${dark.warning};
1289
1357
  --error: ${dark.error};
1290
1358
  --info: ${dark.info || dark.primary};
1291
- ${accentDarkVars}}
1359
+ ${accentDarkVars}${sidebarDarkVars}${chartDarkVars}}
1292
1360
  `;
1293
1361
  }
1294
1362
 
@@ -6067,6 +6135,8 @@ ${menuItems}
6067
6135
  <Link href="${signUpItem.route}" className="inline-flex items-center justify-center text-sm font-medium h-9 px-4 rounded-md bg-primary text-primary-foreground hover:bg-primary/90 transition-colors">${signUpItem.label}</Link>` : ""}` : "";
6068
6136
  const dropdownImport = hasDropdowns ? `
6069
6137
  import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger } from '@/components/ui/dropdown-menu'` : "";
6138
+ const sheetImport = `
6139
+ import { Sheet, SheetContent, SheetTrigger } from '@/components/ui/sheet'`;
6070
6140
  const appName = this.escapeString(this.config.name);
6071
6141
  const mobileNavItems = [...ungrouped];
6072
6142
  for (const [, items] of grouped) {
@@ -6086,7 +6156,7 @@ import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigge
6086
6156
 
6087
6157
  import Link from 'next/link'
6088
6158
  import { usePathname } from 'next/navigation'
6089
- import { useEffect, useState } from 'react'${dropdownImport}
6159
+ import { useEffect, useState } from 'react'${dropdownImport}${sheetImport}
6090
6160
 
6091
6161
  function ThemeToggle() {
6092
6162
  const [dark, setDark] = useState(false)
@@ -6135,26 +6205,23 @@ export function Header() {
6135
6205
  </div>
6136
6206
  <div className="flex items-center gap-1">${authButtonsBlock}
6137
6207
  <ThemeToggle />
6138
- <button
6139
- onClick={() => setMobileOpen(!mobileOpen)}
6140
- className="flex md:hidden items-center justify-center w-9 h-9 rounded-md text-muted-foreground hover:text-foreground hover:bg-muted transition-colors"
6141
- aria-label="Toggle menu"
6142
- >
6143
- {mobileOpen ? (
6144
- <svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><path d="M18 6 6 18"/><path d="m6 6 12 12"/></svg>
6145
- ) : (
6146
- <svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><line x1="4" x2="20" y1="12" y2="12"/><line x1="4" x2="20" y1="6" y2="6"/><line x1="4" x2="20" y1="18" y2="18"/></svg>
6147
- )}
6148
- </button>
6208
+ <Sheet open={mobileOpen} onOpenChange={setMobileOpen}>
6209
+ <SheetTrigger asChild>
6210
+ <button
6211
+ className="flex md:hidden items-center justify-center w-9 h-9 rounded-md text-muted-foreground hover:text-foreground hover:bg-muted transition-colors"
6212
+ aria-label="Toggle menu"
6213
+ >
6214
+ <svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><line x1="4" x2="20" y1="12" y2="12"/><line x1="4" x2="20" y1="6" y2="6"/><line x1="4" x2="20" y1="18" y2="18"/></svg>
6215
+ </button>
6216
+ </SheetTrigger>
6217
+ <SheetContent side="right" className="w-72 p-4">
6218
+ <nav className="flex flex-col gap-1 pt-8">
6219
+ ${mobileLinks}${mobileAuthBlock}
6220
+ </nav>
6221
+ </SheetContent>
6222
+ </Sheet>
6149
6223
  </div>
6150
6224
  </div>
6151
- {mobileOpen && (
6152
- <div className="md:hidden border-t bg-background">
6153
- <div className="mx-auto max-w-7xl px-4 py-3 space-y-1">
6154
- ${mobileLinks}${mobileAuthBlock}
6155
- </div>
6156
- </div>
6157
- )}
6158
6225
  </nav>
6159
6226
  <Link
6160
6227
  href="/design-system"
@@ -6245,7 +6312,7 @@ ${companyColumn}
6245
6312
  `;
6246
6313
  }
6247
6314
  /**
6248
- * Generate shared Sidebar component code for components/shared/sidebar.tsx.
6315
+ * Generate shared Sidebar component code using shadcn/ui Sidebar.
6249
6316
  * Used when navigation.type is 'sidebar' or 'both'.
6250
6317
  */
6251
6318
  generateSharedSidebarCode() {
@@ -6276,71 +6343,71 @@ ${companyColumn}
6276
6343
  ungrouped.push(item);
6277
6344
  }
6278
6345
  }
6279
- const linkItems = ungrouped.map(
6280
- (item) => ` <Link
6281
- href="${item.route}"
6282
- className={\`flex items-center gap-3 rounded-md px-3 py-2 text-sm font-medium transition-colors \${pathname === "${item.route}" ? 'bg-muted text-foreground' : 'text-muted-foreground hover:text-foreground hover:bg-muted/50'}\`}
6283
- >
6284
- ${item.label}
6285
- </Link>`
6286
- ).join("\n");
6287
- const groupBlocks = [];
6288
- for (const [groupName, items] of grouped) {
6289
- const groupLinks = items.map(
6290
- (item) => ` <Link
6291
- href="${item.route}"
6292
- className={\`flex items-center gap-3 rounded-md px-3 py-2 text-sm transition-colors \${pathname === "${item.route}" ? 'bg-muted text-foreground font-medium' : 'text-muted-foreground hover:text-foreground hover:bg-muted/50'}\`}
6293
- >
6294
- ${item.label}
6295
- </Link>`
6296
- ).join("\n");
6297
- groupBlocks.push(` <div className="space-y-1">
6298
- <p className="px-3 py-1 text-xs font-semibold uppercase tracking-wider text-muted-foreground/70">${groupName}</p>
6299
- ${groupLinks}
6300
- </div>`);
6301
- }
6302
- const allSections = [linkItems, ...groupBlocks].filter(Boolean).join("\n");
6346
+ const menuItem = (item) => ` <SidebarMenuItem>
6347
+ <SidebarMenuButton asChild isActive={pathname === "${item.route}"}>
6348
+ <Link href="${item.route}">${item.label}</Link>
6349
+ </SidebarMenuButton>
6350
+ </SidebarMenuItem>`;
6351
+ const ungroupedItems = ungrouped.map(menuItem).join("\n");
6352
+ const groupBlocks = Array.from(grouped.entries()).map(([groupName, items]) => {
6353
+ const groupItems = items.map(menuItem).join("\n");
6354
+ return ` <SidebarGroup>
6355
+ <SidebarGroupLabel>${groupName}</SidebarGroupLabel>
6356
+ <SidebarGroupContent>
6357
+ <SidebarMenu>
6358
+ ${groupItems}
6359
+ </SidebarMenu>
6360
+ </SidebarGroupContent>
6361
+ </SidebarGroup>`;
6362
+ }).join("\n");
6363
+ const mainGroup = ungroupedItems ? ` <SidebarGroup>
6364
+ <SidebarGroupContent>
6365
+ <SidebarMenu>
6366
+ ${ungroupedItems}
6367
+ </SidebarMenu>
6368
+ </SidebarGroupContent>
6369
+ </SidebarGroup>` : "";
6370
+ const allGroups = [mainGroup, groupBlocks].filter(Boolean).join("\n");
6303
6371
  const appName = this.escapeString(this.config.name);
6304
6372
  return `'use client'
6305
6373
 
6306
6374
  import Link from 'next/link'
6307
6375
  import { usePathname } from 'next/navigation'
6308
- import { useState } from 'react'
6309
-
6310
- export function Sidebar() {
6376
+ import {
6377
+ Sidebar,
6378
+ SidebarContent,
6379
+ SidebarGroup,
6380
+ SidebarGroupContent,
6381
+ SidebarGroupLabel,
6382
+ SidebarHeader,
6383
+ SidebarMenu,
6384
+ SidebarMenuButton,
6385
+ SidebarMenuItem,
6386
+ SidebarProvider,
6387
+ SidebarTrigger,
6388
+ } from '@/components/ui/sidebar'
6389
+
6390
+ export function AppSidebar() {
6311
6391
  const pathname = usePathname()
6312
- const [collapsed, setCollapsed] = useState(false)
6313
6392
 
6314
6393
  if (pathname?.startsWith('/design-system')) return null
6315
6394
 
6316
6395
  return (
6317
- <aside className={\`shrink-0 border-r bg-muted/30 transition-all duration-200 \${collapsed ? 'w-16' : 'w-64'}\`}>
6318
- <div className="flex h-14 items-center justify-between border-b px-4">
6319
- {!collapsed && (
6320
- <Link href="/" className="text-sm font-semibold text-foreground truncate">
6321
- ${appName}
6322
- </Link>
6323
- )}
6324
- <button
6325
- onClick={() => setCollapsed(!collapsed)}
6326
- className="flex items-center justify-center w-8 h-8 rounded-md text-muted-foreground hover:text-foreground hover:bg-muted transition-colors"
6327
- aria-label={collapsed ? 'Expand sidebar' : 'Collapse sidebar'}
6328
- >
6329
- <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
6330
- {collapsed ? (
6331
- <><path d="m9 18 6-6-6-6"/></>
6332
- ) : (
6333
- <><path d="m15 18-6-6 6-6"/></>
6334
- )}
6335
- </svg>
6336
- </button>
6337
- </div>
6338
- {!collapsed && (
6339
- <nav className="flex flex-col gap-1 p-3">
6340
- ${allSections}
6341
- </nav>
6342
- )}
6343
- </aside>
6396
+ <SidebarProvider>
6397
+ <Sidebar>
6398
+ <SidebarHeader>
6399
+ <div className="flex items-center justify-between px-2 py-1">
6400
+ <Link href="/" className="text-sm font-semibold text-foreground truncate">
6401
+ ${appName}
6402
+ </Link>
6403
+ <SidebarTrigger />
6404
+ </div>
6405
+ </SidebarHeader>
6406
+ <SidebarContent>
6407
+ ${allGroups}
6408
+ </SidebarContent>
6409
+ </Sidebar>
6410
+ </SidebarProvider>
6344
6411
  )
6345
6412
  }
6346
6413
  `;
@@ -7079,6 +7146,19 @@ export default config
7079
7146
  --warning: ${light.warning};
7080
7147
  --error: ${light.error};
7081
7148
  --info: ${light.info || light.primary};
7149
+ --sidebar-background: ${light.background};
7150
+ --sidebar-foreground: ${light.foreground};
7151
+ --sidebar-primary: ${light.primary};
7152
+ --sidebar-primary-foreground: ${_ProjectScaffolder.contrastingForeground(light.primary)};
7153
+ --sidebar-accent: ${light.muted};
7154
+ --sidebar-accent-foreground: ${light.foreground};
7155
+ --sidebar-border: ${light.border};
7156
+ --sidebar-ring: ${light.primary};
7157
+ --chart-1: ${light.primary};
7158
+ --chart-2: ${light.secondary};
7159
+ --chart-3: ${light.success};
7160
+ --chart-4: ${light.warning};
7161
+ --chart-5: ${light.error};
7082
7162
  }
7083
7163
 
7084
7164
  .dark {
@@ -7105,6 +7185,19 @@ export default config
7105
7185
  --warning: ${dark.warning};
7106
7186
  --error: ${dark.error};
7107
7187
  --info: ${dark.info || dark.primary};
7188
+ --sidebar-background: ${dark.background};
7189
+ --sidebar-foreground: ${dark.foreground};
7190
+ --sidebar-primary: ${dark.primary};
7191
+ --sidebar-primary-foreground: ${_ProjectScaffolder.contrastingForeground(dark.primary)};
7192
+ --sidebar-accent: ${dark.muted};
7193
+ --sidebar-accent-foreground: ${dark.foreground};
7194
+ --sidebar-border: ${dark.border};
7195
+ --sidebar-ring: ${dark.primary};
7196
+ --chart-1: ${dark.primary};
7197
+ --chart-2: ${dark.secondary};
7198
+ --chart-3: ${dark.success};
7199
+ --chart-4: ${dark.warning};
7200
+ --chart-5: ${dark.error};
7108
7201
  }
7109
7202
 
7110
7203
  * {
@@ -7212,10 +7305,10 @@ export function cn(...inputs: ClassValue[]) {
7212
7305
  if (navType === "sidebar" || navType === "both") {
7213
7306
  const sidebarCode = this.pageGenerator.generateSharedSidebarCode();
7214
7307
  await generateSharedComponent(this.projectRoot, {
7215
- name: "Sidebar",
7308
+ name: "AppSidebar",
7216
7309
  type: "layout",
7217
7310
  code: sidebarCode,
7218
- description: "Vertical sidebar navigation with collapsible sections",
7311
+ description: "Application sidebar using shadcn/ui Sidebar components",
7219
7312
  usedIn: ["app/(app)/layout.tsx"]
7220
7313
  });
7221
7314
  }
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "publishConfig": {
4
4
  "access": "public"
5
5
  },
6
- "version": "0.5.11",
6
+ "version": "0.5.13",
7
7
  "description": "Core design system engine for Coherent",
8
8
  "type": "module",
9
9
  "main": "./dist/index.js",
@@ -32,6 +32,12 @@
32
32
  ],
33
33
  "author": "Coherent Design Method",
34
34
  "license": "MIT",
35
+ "scripts": {
36
+ "dev": "tsup --watch",
37
+ "build": "tsup",
38
+ "typecheck": "tsc --noEmit",
39
+ "test": "vitest"
40
+ },
35
41
  "dependencies": {
36
42
  "handlebars": "^4.7.8",
37
43
  "zod": "^3.22.4"
@@ -41,11 +47,5 @@
41
47
  "tsup": "^8.0.1",
42
48
  "typescript": "^5.3.3",
43
49
  "vitest": "^1.2.1"
44
- },
45
- "scripts": {
46
- "dev": "tsup --watch",
47
- "build": "tsup",
48
- "typecheck": "tsc --noEmit",
49
- "test": "vitest"
50
50
  }
51
- }
51
+ }
package/LICENSE DELETED
@@ -1,21 +0,0 @@
1
- MIT License
2
-
3
- Copyright (c) 2025 Sergei Kovtun
4
-
5
- Permission is hereby granted, free of charge, to any person obtaining a copy
6
- of this software and associated documentation files (the "Software"), to deal
7
- in the Software without restriction, including without limitation the rights
8
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
- copies of the Software, and to permit persons to whom the Software is
10
- furnished to do so, subject to the following conditions:
11
-
12
- The above copyright notice and this permission notice shall be included in all
13
- copies or substantial portions of the Software.
14
-
15
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
- SOFTWARE.