Skip to content

Commit

Permalink
Add default theme project
Browse files Browse the repository at this point in the history
* Add switch component
  • Loading branch information
rodleviton committed Sep 23, 2024
1 parent 95f6f72 commit ca8497c
Show file tree
Hide file tree
Showing 34 changed files with 1,000 additions and 26 deletions.
3 changes: 3 additions & 0 deletions packages/theme/.eslintrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"extends": "next/core-web-vitals"
}
36 changes: 36 additions & 0 deletions packages/theme/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.

# dependencies
/node_modules
/.pnp
.pnp.js
.yarn/install-state.gz

# testing
/coverage

# next.js
/.next/
/out/

# production
/build

# misc
.DS_Store
*.pem

# debug
npm-debug.log*
yarn-debug.log*
yarn-error.log*

# local env files
.env*.local

# vercel
.vercel

# typescript
*.tsbuildinfo
next-env.d.ts
36 changes: 36 additions & 0 deletions packages/theme/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
This is a [Next.js](https://nextjs.org/) project bootstrapped with [`create-next-app`](https://github.com/vercel/next.js/tree/canary/packages/create-next-app).

## Getting Started

First, run the development server:

```bash
npm run dev
# or
yarn dev
# or
pnpm dev
# or
bun dev
```

Open [http://localhost:3000](http://localhost:3000) with your browser to see the result.

You can start editing the page by modifying `app/page.tsx`. The page auto-updates as you edit the file.

This project uses [`next/font`](https://nextjs.org/docs/basic-features/font-optimization) to automatically optimize and load Inter, a custom Google Font.

## Learn More

To learn more about Next.js, take a look at the following resources:

- [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js features and API.
- [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial.

You can check out [the Next.js GitHub repository](https://github.com/vercel/next.js/) - your feedback and contributions are welcome!

## Deploy on Vercel

The easiest way to deploy your Next.js app is to use the [Vercel Platform](https://vercel.com/new?utm_medium=default-template&filter=next.js&utm_source=create-next-app&utm_campaign=create-next-app-readme) from the creators of Next.js.

Check out our [Next.js deployment documentation](https://nextjs.org/docs/deployment) for more details.
Binary file added packages/theme/app/favicon.ico
Binary file not shown.
33 changes: 33 additions & 0 deletions packages/theme/app/globals.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
@tailwind base;
@tailwind components;
@tailwind utilities;

:root {
--background: 234 50% 4%;
--foreground: 0 0% 98%;
--primary: 227, 95%, 64%;
--primary-hue: 227;
--primary-saturation: 95%;
--primary-lightness: 64%;
}

body {
@apply font-sans;
color: hsla(var(--primary-hue), var(--primary-saturation), 95%, 0.8);
background: hsl(var(--background));
}

h1,
h2,
h3,
h4,
h5,
h6 {
color: hsla(var(--primary-hue), var(--primary-saturation), 95%, 1);
}

@layer utilities {
.text-balance {
text-wrap: balance;
}
}
30 changes: 30 additions & 0 deletions packages/theme/app/layout.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import "./globals.css";

import { DM_Sans, Fira_Code } from "next/font/google";

import type { Metadata } from "next";

const dmSans = DM_Sans({ subsets: ["latin"], variable: "--font-dm-sans" });
const firaCode = Fira_Code({
subsets: ["latin"],
variable: "--font-fira-code",
});

export const metadata: Metadata = {
title: "Recast Kit",
description: "Recast default components and theme",
};

export default function RootLayout({
children,
}: Readonly<{
children: React.ReactNode;
}>) {
return (
<html lang="en">
<body className={`${dmSans.variable} ${firaCode.variable}`}>
{children}
</body>
</html>
);
}
16 changes: 16 additions & 0 deletions packages/theme/app/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { BlueprintCard } from "@/components/ui/blueprint-card";
import { Switch } from "@/components/ui/switch";

export default function Page() {
return (
<main className="flex grow flex-col min-h-screen p-2 md:p-8 gap-8">
<BlueprintCard
title="Switch"
className="max-w-screen-sm"
description="A control that allows the user to toggle between checked and not checked."
>
<Switch id="mode" />
</BlueprintCard>
</main>
);
}
31 changes: 31 additions & 0 deletions packages/theme/components/ui/animated-number/animated-number.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
"use client";

import { forwardRef, useEffect } from "react";
import { motion, useSpring, useTransform } from "framer-motion";

type Props = React.ComponentPropsWithoutRef<typeof motion.div> & {
value: number;
};

const AnimatedNumber = forwardRef<React.ElementRef<typeof motion.div>, Props>(
({ value, ...props }, ref) => {
let spring = useSpring(value, { mass: 0.8, stiffness: 75, damping: 15 });
let display = useTransform(spring, (current: number) =>
Math.round(current).toLocaleString()
);

useEffect(() => {
spring.set(value);
}, [spring, value]);

return (
<motion.span ref={ref} {...props}>
{display}
</motion.span>
);
}
);

AnimatedNumber.displayName = "AnimatedNumber";

export default AnimatedNumber;
1 change: 1 addition & 0 deletions packages/theme/components/ui/animated-number/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { default as AnimatedNumber } from "./animated-number";
51 changes: 51 additions & 0 deletions packages/theme/components/ui/blueprint-card/blueprint-card.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
"use client";

import React, { forwardRef } from "react";

import { Blueprint } from "../blueprint";
import { Card } from "../card";
import { CardContent } from "../card/card-content";
import { cn } from "@/utils/cn";

type Props = React.ComponentPropsWithoutRef<typeof Card> & {
title: string;
description: string;
};

const BlueprintCard = forwardRef<React.ElementRef<typeof Card>, Props>(
({ children, title, description, className, ...props }, ref) => {
return (
<Card
ref={ref}
className={cn(
"relative overflow-hidden",
"before:bg-[radial-gradient(50%_50%_at_50%_50%,hsla(var(--primary),0.16)_0,hsla(var(--primary),0)_100%)] before:absolute before:inset-0 before:pointer-events-none before:z-10",
className
)}
{...props}
>
<CardContent className="relative flex flex-col md:flex-row gap-8">
<section className="flex flex-col">
<div className="max-w-xl flex flex-col gap-4">
<div className="flex flex-col gap-1 w-min">
<div className="w-full flex gap-2 items-center before:flex-1 before:bg-gradient-to-r before:from-transparent before:to-white/25 before:h-px after:flex-1 after:bg-gradient-to-r after:from-white/25 after:to-transparent after:h-px">
<span className="text-xs font-light">Component</span>
</div>
<h1 className="font-semibold text-4xl">{title}</h1>
</div>

<p className="font-extralight text-balance tracking-wide leading-snug line-clamp-2 max-w-md">
{description}
</p>
</div>
</section>
<Blueprint>{children}</Blueprint>
</CardContent>
</Card>
);
}
);

BlueprintCard.displayName = "BlueprintCard";

export default BlueprintCard;
1 change: 1 addition & 0 deletions packages/theme/components/ui/blueprint-card/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { default as BlueprintCard } from "./blueprint-card";
70 changes: 70 additions & 0 deletions packages/theme/components/ui/blueprint/blueprint.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
"use client";

import React, { forwardRef, useRef } from "react";

import { AnimatedNumber } from "../animated-number";
import { HorizontalGridLine } from "./horizontal-grid-line";
import { VerticalGridLine } from "./vertical-grid-line";
import { cn } from "@/utils/cn";
import { motion } from "framer-motion";
import { useResizeObserver } from "usehooks-ts";

type Props = React.HTMLAttributes<HTMLDivElement>;

const Blueprint = forwardRef<HTMLDivElement, Props>(
({ children, className, ...props }, ref) => {
const blueprintRef = useRef<HTMLDivElement>(null);

const { width = 0, height = 0 } = useResizeObserver({
ref: blueprintRef,
box: "border-box",
});

return (
<div
ref={ref}
className={cn(
"px-20 py-20 relative justify-center flex flex-1 flex-col",
className
)}
{...props}
>
<div className="mx-auto w-auto">
<div className="p-1 relative">
<div className="w-full">
<div className="font-mono text-xs -top-10 left-1/2 transform -translate-x-1/2 absolute">
<AnimatedNumber value={width} />
px
</div>
<motion.div
animate={{ width: width - 8 }}
className="absolute -top-4 h-px bg-neutral-500 transform -translate-x-1/2 left-1/2 before:bg-neutral-500 before:left-0 before:top-1/2 before:transform before:-translate-y-1/2 before:w-px before:h-1.5 before:flex before:absolute after:bg-neutral-500 after:right-0 after:top-1/2 after:transform after:-translate-y-1/2 after:w-px after:h-1.5 after:flex after:absolute"
/>
</div>
<HorizontalGridLine className="-top-1" />
<HorizontalGridLine className="-bottom-1" />
<VerticalGridLine className="-left-1" />
<VerticalGridLine className="-right-1" />
<div className="h-full">
<div className="font-mono text-xs -right-14 top-1/2 transform -translate-y-1/2 absolute">
<AnimatedNumber value={height} />
px
</div>
<motion.div
animate={{ height: height - 8 }}
className="absolute -right-4 w-px bg-neutral-500 transform -translate-y-1/2 top-1/2 before:bg-neutral-500 before:top-0 before:left-1/2 before:transform before:-translate-x-1/2 before:h-px before:w-1.5 before:flex before:absolute after:bg-neutral-500 after:bottom-0 after:left-1/2 after:transform after:-translate-x-1/2 after:h-px after:w-1.5 after:flex after:absolute"
/>
</div>
<div className="flex" ref={blueprintRef}>
{children}
</div>
</div>
</div>
</div>
);
}
);

Blueprint.displayName = "Blueprint";

export default Blueprint;
24 changes: 24 additions & 0 deletions packages/theme/components/ui/blueprint/horizontal-grid-line.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
"use client";

import React, { forwardRef } from "react";

import { cn } from "@/utils/cn";

type Props = React.HTMLAttributes<HTMLSpanElement>;

export const HorizontalGridLine = forwardRef<HTMLSpanElement, Props>(
({ children, className, ...props }, ref) => {
return (
<span
ref={ref}
className={cn(
"absolute -inset-x-64 h-px bg-gradient-to-r from-transparent via-white/15 to-transparent transform -translate-x-1/2 left-1/2",
className
)}
{...props}
/>
);
}
);

HorizontalGridLine.displayName = "HorizontalGridLine";
1 change: 1 addition & 0 deletions packages/theme/components/ui/blueprint/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { default as Blueprint } from "./blueprint";
24 changes: 24 additions & 0 deletions packages/theme/components/ui/blueprint/vertical-grid-line.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
"use client";

import React, { forwardRef } from "react";

import { cn } from "@/utils/cn";

type Props = React.HTMLAttributes<HTMLSpanElement>;

export const VerticalGridLine = forwardRef<HTMLSpanElement, Props>(
({ children, className, ...props }, ref) => {
return (
<span
ref={ref}
className={cn(
"absolute -inset-y-64 w-px bg-gradient-to-b from-transparent via-white/15 to-transparent transform -translate-y-1/2 top-1/2",
className
)}
{...props}
/>
);
}
);

VerticalGridLine.displayName = "VerticalGridLine";
8 changes: 8 additions & 0 deletions packages/theme/components/ui/button/button.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
"use client";

import { recast } from "@rpxl/recast";
import { ButtonPrimitive } from "@rpxl/recast-primitives";

export const Button = recast(ButtonPrimitive, {
base: "",
});
1 change: 1 addition & 0 deletions packages/theme/components/ui/button/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from "./button";
8 changes: 8 additions & 0 deletions packages/theme/components/ui/card/card-content.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
"use client";

import { recast } from "@rpxl/recast";
import { CardContentPrimitive } from "@rpxl/recast-primitives";

export const CardContent = recast(CardContentPrimitive, {
base: ["py-12", "px-8"],
});
Loading

0 comments on commit ca8497c

Please sign in to comment.