Registry package scaffold
Adds the shadcn-style copy-paste layer as a new monorepo package. Includes theme token CSS custom properties (light/dark), a cn() class-merging utility with tests, and a reference Dialog styled component wrapping the headless pettyui/dialog primitive with Tailwind classes.
This commit is contained in:
parent
56f06c961d
commit
b4ec99fe4a
19
packages/registry/package.json
Normal file
19
packages/registry/package.json
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
{
|
||||||
|
"name": "pettyui-registry",
|
||||||
|
"version": "0.1.0",
|
||||||
|
"private": true,
|
||||||
|
"description": "PettyUI styled component registry — shadcn model for SolidJS",
|
||||||
|
"type": "module",
|
||||||
|
"scripts": {
|
||||||
|
"test": "vitest run",
|
||||||
|
"typecheck": "tsc --noEmit"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"solid-js": "^1.9.0"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"pettyui": "workspace:*",
|
||||||
|
"solid-js": "^1.9.12",
|
||||||
|
"vitest": "^4.1.2"
|
||||||
|
}
|
||||||
|
}
|
||||||
40
packages/registry/src/components/dialog.tsx
Normal file
40
packages/registry/src/components/dialog.tsx
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
import { Dialog as DialogPrimitive } from "pettyui/dialog";
|
||||||
|
import { cn } from "../utils";
|
||||||
|
import type { JSX } from "solid-js";
|
||||||
|
import { splitProps } from "solid-js";
|
||||||
|
|
||||||
|
const Dialog = DialogPrimitive;
|
||||||
|
const DialogTrigger = DialogPrimitive.Trigger;
|
||||||
|
const DialogClose = DialogPrimitive.Close;
|
||||||
|
const DialogPortal = DialogPrimitive.Portal;
|
||||||
|
const DialogTitle = DialogPrimitive.Title;
|
||||||
|
const DialogDescription = DialogPrimitive.Description;
|
||||||
|
|
||||||
|
/** Renders a dimmed backdrop behind the dialog panel. */
|
||||||
|
function DialogOverlay(props: JSX.HTMLAttributes<HTMLDivElement>): JSX.Element {
|
||||||
|
const [local, rest] = splitProps(props, ["class"]);
|
||||||
|
return (
|
||||||
|
<DialogPrimitive.Overlay
|
||||||
|
class={cn("fixed inset-0 z-50 bg-black/80", local.class)}
|
||||||
|
{...rest}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Pre-composed dialog panel: wraps Content inside Portal with Overlay included. */
|
||||||
|
function DialogContent(props: JSX.HTMLAttributes<HTMLDivElement> & { children?: JSX.Element }): JSX.Element {
|
||||||
|
const [local, rest] = splitProps(props, ["class", "children"]);
|
||||||
|
return (
|
||||||
|
<DialogPortal>
|
||||||
|
<DialogOverlay />
|
||||||
|
<DialogPrimitive.Content
|
||||||
|
class={cn("fixed left-1/2 top-1/2 z-50 grid w-full max-w-lg -translate-x-1/2 -translate-y-1/2 gap-4 rounded-lg border bg-background p-6 shadow-lg", local.class)}
|
||||||
|
{...rest}
|
||||||
|
>
|
||||||
|
{local.children}
|
||||||
|
</DialogPrimitive.Content>
|
||||||
|
</DialogPortal>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export { Dialog, DialogTrigger, DialogContent, DialogOverlay, DialogPortal, DialogClose, DialogTitle, DialogDescription };
|
||||||
44
packages/registry/src/tokens.css
Normal file
44
packages/registry/src/tokens.css
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
:root {
|
||||||
|
--background: 0 0% 100%;
|
||||||
|
--foreground: 0 0% 3.9%;
|
||||||
|
--card: 0 0% 100%;
|
||||||
|
--card-foreground: 0 0% 3.9%;
|
||||||
|
--popover: 0 0% 100%;
|
||||||
|
--popover-foreground: 0 0% 3.9%;
|
||||||
|
--primary: 0 0% 9%;
|
||||||
|
--primary-foreground: 0 0% 98%;
|
||||||
|
--secondary: 0 0% 96.1%;
|
||||||
|
--secondary-foreground: 0 0% 9%;
|
||||||
|
--muted: 0 0% 96.1%;
|
||||||
|
--muted-foreground: 0 0% 45.1%;
|
||||||
|
--accent: 0 0% 96.1%;
|
||||||
|
--accent-foreground: 0 0% 9%;
|
||||||
|
--destructive: 0 84.2% 60.2%;
|
||||||
|
--destructive-foreground: 0 0% 98%;
|
||||||
|
--border: 0 0% 89.8%;
|
||||||
|
--input: 0 0% 89.8%;
|
||||||
|
--ring: 0 0% 3.9%;
|
||||||
|
--radius: 0.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dark {
|
||||||
|
--background: 0 0% 3.9%;
|
||||||
|
--foreground: 0 0% 98%;
|
||||||
|
--card: 0 0% 3.9%;
|
||||||
|
--card-foreground: 0 0% 98%;
|
||||||
|
--popover: 0 0% 3.9%;
|
||||||
|
--popover-foreground: 0 0% 98%;
|
||||||
|
--primary: 0 0% 98%;
|
||||||
|
--primary-foreground: 0 0% 9%;
|
||||||
|
--secondary: 0 0% 14.9%;
|
||||||
|
--secondary-foreground: 0 0% 98%;
|
||||||
|
--muted: 0 0% 14.9%;
|
||||||
|
--muted-foreground: 0 0% 63.9%;
|
||||||
|
--accent: 0 0% 14.9%;
|
||||||
|
--accent-foreground: 0 0% 98%;
|
||||||
|
--destructive: 0 62.8% 30.6%;
|
||||||
|
--destructive-foreground: 0 0% 98%;
|
||||||
|
--border: 0 0% 14.9%;
|
||||||
|
--input: 0 0% 14.9%;
|
||||||
|
--ring: 0 0% 83.1%;
|
||||||
|
}
|
||||||
7
packages/registry/src/utils.ts
Normal file
7
packages/registry/src/utils.ts
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
/**
|
||||||
|
* Merges class name strings, filtering out falsy values (undefined, null, false).
|
||||||
|
* Drop-in replacement for clsx for simple conditional class composition.
|
||||||
|
*/
|
||||||
|
export function cn(...inputs: (string | undefined | null | false)[]): string {
|
||||||
|
return inputs.filter(Boolean).join(" ");
|
||||||
|
}
|
||||||
14
packages/registry/tests/utils.test.ts
Normal file
14
packages/registry/tests/utils.test.ts
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
import { describe, expect, it } from "vitest";
|
||||||
|
import { cn } from "../src/utils";
|
||||||
|
|
||||||
|
describe("cn utility", () => {
|
||||||
|
it("joins class names", () => {
|
||||||
|
expect(cn("foo", "bar")).toBe("foo bar");
|
||||||
|
});
|
||||||
|
it("filters falsy values", () => {
|
||||||
|
expect(cn("foo", undefined, null, false, "bar")).toBe("foo bar");
|
||||||
|
});
|
||||||
|
it("returns empty string for no classes", () => {
|
||||||
|
expect(cn()).toBe("");
|
||||||
|
});
|
||||||
|
});
|
||||||
11
packages/registry/tsconfig.json
Normal file
11
packages/registry/tsconfig.json
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
{
|
||||||
|
"extends": "../../tsconfig.base.json",
|
||||||
|
"compilerOptions": {
|
||||||
|
"outDir": "dist",
|
||||||
|
"rootDir": "src",
|
||||||
|
"paths": {
|
||||||
|
"@/*": ["./src/*"]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"include": ["src"]
|
||||||
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user