-
Notifications
You must be signed in to change notification settings - Fork 0
feat: complete monorepo migration with documentation system and usage-meter components #4
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Large diffs are not rendered by default.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -3,15 +3,17 @@ | |
| "name": "usage-meter-base", | ||
| "title": "Usage Meter (Base)", | ||
| "description": "A lightweight linear progress meter for displaying usage/quota information without Radix dependency.", | ||
| "dependencies": [], | ||
| "registryDependencies": [], | ||
| "registryDependencies": [ | ||
| "https://usage-ui.vercel.app/r/usage-meter-base.json", | ||
| "https://registry-starter.vercel.app/r/theme.json" | ||
|
Comment on lines
+6
to
+8
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Circular dependency and wrong file provided - should contain actual Prompt To Fix With AIThis is a comment left during a code review.
Path: apps/www/public/r/usage-meter-base.json
Line: 6:8
Comment:
Circular dependency and wrong file provided - should contain actual `usage-meter-base` component code, not a layout template
How can I resolve this? If you propose a fix, please make it concise. |
||
| ], | ||
| "files": [ | ||
| { | ||
| "path": "src/components/registry/usage-meter/usage-meter-base.tsx", | ||
| "content": "\"use client\";\n\nimport * as React from \"react\";\n\nimport { cn } from \"@/lib/utils\";\n\nconst meterVariants = {\n default: \"bg-primary\",\n success: \"bg-chart-2\",\n warning: \"bg-chart-4\",\n danger: \"bg-destructive\",\n} as const;\n\nconst meterSizes = {\n sm: \"h-2\",\n default: \"h-3\",\n lg: \"h-4\",\n} as const;\n\ninterface UsageMeterBaseProps extends React.HTMLAttributes<HTMLDivElement> {\n /** Current value (required) */\n value: number;\n /** Maximum value (default: 100) */\n max?: number;\n /** Visual variant */\n variant?: keyof typeof meterVariants;\n /** Size variant */\n size?: keyof typeof meterSizes;\n /** Optional label text */\n label?: string;\n /** Show percentage (default: true) */\n showPercentage?: boolean;\n}\n\nconst UsageMeterBase = React.forwardRef<HTMLDivElement, UsageMeterBaseProps>(\n (\n {\n className,\n value,\n max = 100,\n variant = \"default\",\n size = \"default\",\n label,\n showPercentage = true,\n ...props\n },\n ref,\n ) => {\n // Guard against max being 0 or negative to avoid NaN/Infinity\n const percentage = max > 0 ? Math.round((value / max) * 100) : 0;\n const clampedPercentage = Math.min(100, Math.max(0, percentage));\n\n return (\n <div data-slot=\"usage-meter-base-root\" className=\"w-full\">\n {(label || showPercentage) && (\n <div\n data-slot=\"usage-meter-base-header\"\n className=\"mb-1.5 flex items-center justify-between text-sm\"\n >\n {label && (\n <span\n data-slot=\"usage-meter-base-label\"\n className=\"font-medium text-foreground\"\n >\n {label}\n </span>\n )}\n {showPercentage && (\n <span\n data-slot=\"usage-meter-base-percentage\"\n className=\"text-muted-foreground tabular-nums\"\n >\n {clampedPercentage}%\n </span>\n )}\n </div>\n )}\n <div\n ref={ref}\n data-slot=\"usage-meter-base\"\n role=\"progressbar\"\n tabIndex={0}\n aria-valuenow={value}\n aria-valuemin={0}\n aria-valuemax={max}\n aria-valuetext={`${clampedPercentage}%`}\n aria-label={label}\n className={cn(\n \"relative w-full overflow-hidden rounded-full bg-secondary\",\n meterSizes[size],\n className,\n )}\n {...props}\n >\n <div\n data-slot=\"usage-meter-base-indicator\"\n className={cn(\n \"h-full transition-all duration-300 ease-in-out\",\n meterVariants[variant],\n )}\n style={{ width: `${clampedPercentage}%` }}\n />\n </div>\n </div>\n );\n },\n);\nUsageMeterBase.displayName = \"UsageMeterBase\";\n\nexport {\n UsageMeterBase,\n meterVariants as meterBaseVariants,\n meterSizes as meterBaseSizes,\n};\nexport type { UsageMeterBaseProps };\n", | ||
| "type": "registry:component", | ||
| "target": "components/ui/usage-meter-base.tsx" | ||
| "path": "src/layouts/minimal-layout.tsx", | ||
| "content": "import { Geist, Geist_Mono, Montserrat } from \"next/font/google\";\nimport React, { type ReactNode } from \"react\";\n\nimport { cn } from \"@/lib/utils\";\n\nimport \"@/app/globals.css\";\n\nconst GeistSans = Geist({\n subsets: [\"latin\"],\n variable: \"--font-sans\",\n});\n\nconst GeistMono = Geist_Mono({\n subsets: [\"latin\"],\n variable: \"--font-mono\",\n});\n\nconst MontserratSerif = Montserrat({\n subsets: [\"latin\"],\n variable: \"--font-serif\",\n});\n\nexport default function RootLayout({\n children,\n}: Readonly<{\n children: ReactNode;\n}>) {\n return (\n <html\n lang=\"en\"\n className={cn(\n GeistSans.variable,\n GeistMono.variable,\n MontserratSerif.variable,\n \"bg-background text-foreground\",\n )}\n >\n <body>\n <main className=\"mt-16 flex w-full justify-center\">\n <div className=\"container\">{children}</div>\n </main>\n </body>\n </html>\n );\n}\n", | ||
| "type": "registry:file", | ||
| "target": "app/layout.tsx" | ||
| } | ||
| ], | ||
| "type": "registry:component" | ||
| "type": "registry:ui" | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -3,17 +3,17 @@ | |
| "name": "usage-meter", | ||
| "title": "Usage Meter", | ||
| "description": "A linear progress meter for displaying usage/quota information with full Radix accessibility support.", | ||
| "dependencies": [ | ||
| "radix-ui" | ||
| "registryDependencies": [ | ||
| "https://usage-ui.vercel.app/r/usage-meter.json", | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. P2: Avoid making a registry entry depend on itself; this creates a circular dependency during installation. Prompt for AI agents |
||
| "https://registry-starter.vercel.app/r/theme.json" | ||
|
Comment on lines
+6
to
+8
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Circular dependency and wrong file provided - should contain actual Prompt To Fix With AIThis is a comment left during a code review.
Path: apps/www/public/r/usage-meter.json
Line: 6:8
Comment:
Circular dependency and wrong file provided - should contain actual `usage-meter` component code, not a layout template
How can I resolve this? If you propose a fix, please make it concise. |
||
| ], | ||
| "registryDependencies": [], | ||
| "files": [ | ||
| { | ||
| "path": "src/components/registry/usage-meter/usage-meter.tsx", | ||
| "content": "\"use client\";\n\nimport { Progress as ProgressPrimitive } from \"radix-ui\";\nimport * as React from \"react\";\n\nimport { cn } from \"@/lib/utils\";\n\nconst meterVariants = {\n default: \"bg-primary\",\n success: \"bg-chart-2\",\n warning: \"bg-chart-4\",\n danger: \"bg-destructive\",\n} as const;\n\nconst meterSizes = {\n sm: \"h-2\",\n default: \"h-3\",\n lg: \"h-4\",\n} as const;\n\ninterface UsageMeterProps\n extends Omit<\n React.ComponentProps<typeof ProgressPrimitive.Root>,\n \"value\" | \"max\"\n > {\n /** Current value (required) */\n value: number;\n /** Maximum value (default: 100) */\n max?: number;\n /** Visual variant */\n variant?: keyof typeof meterVariants;\n /** Size variant */\n size?: keyof typeof meterSizes;\n /** Optional label text */\n label?: string;\n /** Show percentage (default: true) */\n showPercentage?: boolean;\n}\n\nconst UsageMeter = React.forwardRef<\n React.ComponentRef<typeof ProgressPrimitive.Root>,\n UsageMeterProps\n>(\n (\n {\n className,\n value,\n max = 100,\n variant = \"default\",\n size = \"default\",\n label,\n showPercentage = true,\n ...props\n },\n ref,\n ) => {\n // Guard against max <= 0 to prevent division by zero and invalid progress state\n const safeMax = Math.max(1, max);\n const percentage = Math.round((value / safeMax) * 100);\n const clampedPercentage = Math.min(100, Math.max(0, percentage));\n\n return (\n <div data-slot=\"usage-meter-root\" className=\"w-full\">\n {(label || showPercentage) && (\n <div\n data-slot=\"usage-meter-header\"\n className=\"mb-1.5 flex items-center justify-between text-sm\"\n >\n {label && (\n <span\n data-slot=\"usage-meter-label\"\n className=\"font-medium text-foreground\"\n >\n {label}\n </span>\n )}\n {showPercentage && (\n <span\n data-slot=\"usage-meter-percentage\"\n className=\"text-muted-foreground tabular-nums\"\n >\n {clampedPercentage}%\n </span>\n )}\n </div>\n )}\n <ProgressPrimitive.Root\n ref={ref}\n data-slot=\"usage-meter\"\n value={value}\n max={safeMax}\n className={cn(\n \"relative w-full overflow-hidden rounded-full bg-secondary\",\n meterSizes[size],\n className,\n )}\n {...props}\n >\n <ProgressPrimitive.Indicator\n data-slot=\"usage-meter-indicator\"\n className={cn(\n \"h-full w-full flex-1 transition-all duration-300 ease-in-out\",\n meterVariants[variant],\n )}\n style={{ transform: `translateX(-${100 - clampedPercentage}%)` }}\n />\n </ProgressPrimitive.Root>\n </div>\n );\n },\n);\nUsageMeter.displayName = \"UsageMeter\";\n\nexport { UsageMeter, meterVariants, meterSizes };\nexport type { UsageMeterProps };\n", | ||
| "type": "registry:component", | ||
| "target": "components/ui/usage-meter.tsx" | ||
| "path": "src/layouts/minimal-layout.tsx", | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. P1: This registry entry no longer installs the usage-meter component; it installs a layout file instead. That will break consumers expecting the usage-meter component to be added. Prompt for AI agents |
||
| "content": "import { Geist, Geist_Mono, Montserrat } from \"next/font/google\";\nimport React, { type ReactNode } from \"react\";\n\nimport { cn } from \"@/lib/utils\";\n\nimport \"@/app/globals.css\";\n\nconst GeistSans = Geist({\n subsets: [\"latin\"],\n variable: \"--font-sans\",\n});\n\nconst GeistMono = Geist_Mono({\n subsets: [\"latin\"],\n variable: \"--font-mono\",\n});\n\nconst MontserratSerif = Montserrat({\n subsets: [\"latin\"],\n variable: \"--font-serif\",\n});\n\nexport default function RootLayout({\n children,\n}: Readonly<{\n children: ReactNode;\n}>) {\n return (\n <html\n lang=\"en\"\n className={cn(\n GeistSans.variable,\n GeistMono.variable,\n MontserratSerif.variable,\n \"bg-background text-foreground\",\n )}\n >\n <body>\n <main className=\"mt-16 flex w-full justify-center\">\n <div className=\"container\">{children}</div>\n </main>\n </body>\n </html>\n );\n}\n", | ||
| "type": "registry:file", | ||
| "target": "app/layout.tsx" | ||
| } | ||
| ], | ||
| "type": "registry:component" | ||
| "type": "registry:ui" | ||
| } | ||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -13,11 +13,29 @@ export default function RegistryLayout({ | |||||||||||||||||||||||||
| children: ReactNode; | ||||||||||||||||||||||||||
| }>) { | ||||||||||||||||||||||||||
| return ( | ||||||||||||||||||||||||||
| <SidebarProvider> | ||||||||||||||||||||||||||
| <MobileSidebarTrigger /> | ||||||||||||||||||||||||||
| <RegistrySidebar /> | ||||||||||||||||||||||||||
| <main className="flex w-full justify-center">{children}</main> | ||||||||||||||||||||||||||
| <Toaster /> | ||||||||||||||||||||||||||
| </SidebarProvider> | ||||||||||||||||||||||||||
| <div className="container-wrapper flex min-h-svh flex-1 flex-col px-2"> | ||||||||||||||||||||||||||
| <SidebarProvider | ||||||||||||||||||||||||||
| className="flex min-h-min w-full flex-1 items-start px-0 lg:grid lg:grid-cols-[var(--sidebar-width)_minmax(0,1fr)]" | ||||||||||||||||||||||||||
| style={ | ||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||
| "--sidebar-width": "calc(var(--spacing) * 64)", | ||||||||||||||||||||||||||
| "--top-spacing": "0", | ||||||||||||||||||||||||||
| } as React.CSSProperties | ||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||
|
Comment on lines
+19
to
+24
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time! Prompt To Fix With AIThis is a comment left during a code review.
Path: apps/www/src/app/(registry)/layout.tsx
Line: 19:24
Comment:
`React.CSSProperties` requires importing `React`
```suggestion
style={
{
"--sidebar-width": "calc(var(--spacing) * 64)",
"--top-spacing": "0",
} as import("react").CSSProperties
}
```
<sub>Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!</sub>
How can I resolve this? If you propose a fix, please make it concise. |
||||||||||||||||||||||||||
| > | ||||||||||||||||||||||||||
| <MobileSidebarTrigger /> | ||||||||||||||||||||||||||
| <RegistrySidebar /> | ||||||||||||||||||||||||||
| {/* Content wrapper - matches shadcn docs pattern */} | ||||||||||||||||||||||||||
| <div className="h-full w-full"> | ||||||||||||||||||||||||||
| <div | ||||||||||||||||||||||||||
| data-slot="docs" | ||||||||||||||||||||||||||
| className="flex scroll-mt-24 items-stretch pb-8 text-[1.05rem] sm:text-[15px] xl:w-full" | ||||||||||||||||||||||||||
| > | ||||||||||||||||||||||||||
| <main className="flex min-w-0 flex-1 flex-col">{children}</main> | ||||||||||||||||||||||||||
| </div> | ||||||||||||||||||||||||||
| </div> | ||||||||||||||||||||||||||
| <Toaster /> | ||||||||||||||||||||||||||
| </SidebarProvider> | ||||||||||||||||||||||||||
| </div> | ||||||||||||||||||||||||||
| ); | ||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
P2: Avoid self-referencing the registry entry in registryDependencies; it creates a circular dependency for installers.
Prompt for AI agents