First Commit

This commit is contained in:
Benjamin Toby 2024-10-16 15:20:34 +01:00
commit 25daf1844e
30 changed files with 617 additions and 0 deletions

40
.gitignore vendored Normal file
View File

@ -0,0 +1,40 @@
# 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
# Remove test
/pages
/public

40
README.md Normal file
View File

@ -0,0 +1,40 @@
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 `pages/index.tsx`. The page auto-updates as you edit the file.
[API routes](https://nextjs.org/docs/api-routes/introduction) can be accessed on [http://localhost:3000/api/hello](http://localhost:3000/api/hello). This endpoint can be edited in `pages/api/hello.ts`.
The `pages/api` directory is mapped to `/api/*`. Files in this directory are treated as [API routes](https://nextjs.org/docs/api-routes/introduction) instead of React pages.
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.

BIN
bun.lockb Executable file

Binary file not shown.

View File

@ -0,0 +1,19 @@
import { DetailedHTMLProps, HTMLAttributes } from "react";
import { twMerge } from "tailwind-merge";
import Toggle, { TWUI_TOGGLE_PROPS } from "./Toggle";
export default function ColorSchemeSelector({
toggleProps,
...props
}: DetailedHTMLProps<HTMLAttributes<HTMLDivElement>, HTMLDivElement> & {
toggleProps?: TWUI_TOGGLE_PROPS;
}) {
return (
<div
{...props}
className={twMerge("flex flex-row items-center", props.className)}
>
<Toggle {...toggleProps} />
</div>
);
}

View File

@ -0,0 +1,47 @@
import { DetailedHTMLProps, HTMLAttributes } from "react";
import { twMerge } from "tailwind-merge";
export type TWUI_TOGGLE_PROPS = DetailedHTMLProps<
HTMLAttributes<HTMLDivElement>,
HTMLDivElement
> & {
active?: boolean;
circleProps?: DetailedHTMLProps<
HTMLAttributes<HTMLDivElement>,
HTMLDivElement
>;
};
/**
* # Toggle Component
* @className_wrapper twui-toggle-wrapper
* @className_circle twui-toggle-circle
*/
export default function Toggle({
circleProps,
active,
...props
}: TWUI_TOGGLE_PROPS) {
return (
<div
{...props}
className={twMerge(
"flex flex-row items-center w-full max-w-[200px]",
"border border-slate-300 border-solid rounded-full",
active ? "" : "",
"twui-toggle-wrapper",
props.className
)}
>
<div
{...circleProps}
className={twMerge(
"w-20 h-20 rounded-full",
active ? "" : "",
"twui-toggle-circle",
circleProps?.className
)}
></div>
</div>
);
}

17
components/form/Form.tsx Normal file
View File

@ -0,0 +1,17 @@
import { DetailedHTMLProps, FormHTMLAttributes } from "react";
import { twMerge } from "tailwind-merge";
export default function Form({
...props
}: DetailedHTMLProps<FormHTMLAttributes<HTMLFormElement>, HTMLFormElement>) {
return (
<form
{...props}
className={twMerge(
"flex flex-col items-start gap-4 w-full",
"twui-form",
props.className
)}
></form>
);
}

17
components/form/Input.tsx Normal file
View File

@ -0,0 +1,17 @@
import { DetailedHTMLProps, InputHTMLAttributes } from "react";
import { twMerge } from "tailwind-merge";
export default function Input({
...props
}: DetailedHTMLProps<InputHTMLAttributes<HTMLInputElement>, HTMLInputElement>) {
return (
<input
{...props}
className={twMerge(
"w-full px-4 py-2 border border-slate-300 rounded",
"twui-input",
props.className
)}
/>
);
}

View File

@ -0,0 +1,65 @@
import {
AnchorHTMLAttributes,
ButtonHTMLAttributes,
DetailedHTMLProps,
HTMLAttributeAnchorTarget,
HTMLAttributes,
} from "react";
import { ClassNameValue, twMerge } from "tailwind-merge";
export default function Button({
href,
target,
variant,
color,
linkProps,
...props
}: DetailedHTMLProps<
ButtonHTMLAttributes<HTMLButtonElement>,
HTMLButtonElement
> & {
variant?: "normal" | "ghost" | "outlined";
color?: "primary" | "secondary" | "accent";
href?: string;
target?: HTMLAttributeAnchorTarget;
linkProps?: DetailedHTMLProps<
AnchorHTMLAttributes<HTMLAnchorElement>,
HTMLAnchorElement
>;
}) {
const finalClassName: string = (() => {
if (variant == "normal" || !variant) {
if (color == "primary" || !color) return "bg-blue-500 text-white";
} else if (variant == "outlined") {
if (color == "primary" || !color)
return (
"bg-transparent outline outline-1 outline-blue-500" +
" text-blue-500"
);
} else if (variant == "ghost") {
}
return "";
})();
const buttonComponent = (
<button
{...props}
className={twMerge(
"bg-blue-600 text-white text-base font-medium px-4 py-2 rounded",
finalClassName,
props.className
)}
>
{props.children}
</button>
);
if (href)
return (
<a {...linkProps} href={href} target={target}>
{buttonComponent}
</a>
);
return buttonComponent;
}

View File

@ -0,0 +1,23 @@
import { DetailedHTMLProps, HTMLAttributes } from "react";
import { twMerge } from "tailwind-merge";
/**
* # Default Container
* @className twui-container
*/
export default function Container({
...props
}: DetailedHTMLProps<HTMLAttributes<HTMLDivElement>, HTMLDivElement>) {
return (
<div
{...props}
className={twMerge(
"flex flex-row items-center w-full max-w-[1200px]",
"twui-container",
props.className
)}
>
{props.children}
</div>
);
}

View File

@ -0,0 +1,21 @@
import { DetailedHTMLProps, HTMLAttributes } from "react";
import { twMerge } from "tailwind-merge";
export default function Footer({
...props
}: DetailedHTMLProps<HTMLAttributes<HTMLElement>, HTMLElement>) {
return (
<header
{...props}
className={twMerge(
"flex flex-col items-center justify-center",
"px-4 sm:px-10 py-2",
"border-0 border-b border-slate-200 border-solid",
"twui-footer",
props.className
)}
>
{props.children}
</header>
);
}

12
components/layout/H1.tsx Normal file
View File

@ -0,0 +1,12 @@
import { DetailedHTMLProps, HTMLAttributes } from "react";
import { twMerge } from "tailwind-merge";
export default function H1({
...props
}: DetailedHTMLProps<HTMLAttributes<HTMLHeadingElement>, HTMLHeadingElement>) {
return (
<h1 {...props} className={twMerge("text-5xl mb-4", props.className)}>
{props.children}
</h1>
);
}

12
components/layout/H2.tsx Normal file
View File

@ -0,0 +1,12 @@
import { DetailedHTMLProps, HTMLAttributes } from "react";
import { twMerge } from "tailwind-merge";
export default function H2({
...props
}: DetailedHTMLProps<HTMLAttributes<HTMLHeadingElement>, HTMLHeadingElement>) {
return (
<h2 {...props} className={twMerge("text-3xl mb-4", props.className)}>
{props.children}
</h2>
);
}

12
components/layout/H3.tsx Normal file
View File

@ -0,0 +1,12 @@
import { DetailedHTMLProps, HTMLAttributes } from "react";
import { twMerge } from "tailwind-merge";
export default function H3({
...props
}: DetailedHTMLProps<HTMLAttributes<HTMLHeadingElement>, HTMLHeadingElement>) {
return (
<h3 {...props} className={twMerge("text-xl mb-4", props.className)}>
{props.children}
</h3>
);
}

12
components/layout/H4.tsx Normal file
View File

@ -0,0 +1,12 @@
import { DetailedHTMLProps, HTMLAttributes } from "react";
import { twMerge } from "tailwind-merge";
export default function H4({
...props
}: DetailedHTMLProps<HTMLAttributes<HTMLHeadingElement>, HTMLHeadingElement>) {
return (
<h4 {...props} className={twMerge("text-base mb-4", props.className)}>
{props.children}
</h4>
);
}

12
components/layout/H5.tsx Normal file
View File

@ -0,0 +1,12 @@
import { DetailedHTMLProps, HTMLAttributes } from "react";
import { twMerge } from "tailwind-merge";
export default function H5({
...props
}: DetailedHTMLProps<HTMLAttributes<HTMLHeadingElement>, HTMLHeadingElement>) {
return (
<h5 {...props} className={twMerge("text-sm mb-4", props.className)}>
{props.children}
</h5>
);
}

16
components/layout/HR.tsx Normal file
View File

@ -0,0 +1,16 @@
import { DetailedHTMLProps, HTMLAttributes } from "react";
import { twMerge } from "tailwind-merge";
export default function HR({
...props
}: DetailedHTMLProps<HTMLAttributes<HTMLHRElement>, HTMLHRElement>) {
return (
<hr
{...props}
className={twMerge(
"bg-slate-400 w-full dark:bg-white/20 my-4",
props.className
)}
/>
);
}

View File

@ -0,0 +1,25 @@
import { DetailedHTMLProps, HTMLAttributes } from "react";
import { twMerge } from "tailwind-merge";
/**
* # Default Header
* @className twui-header
*/
export default function Header({
...props
}: DetailedHTMLProps<HTMLAttributes<HTMLElement>, HTMLElement>) {
return (
<header
{...props}
className={twMerge(
"flex flex-col items-center justify-center",
"px-4 sm:px-10 py-2",
"border-0 border-b border-slate-200 border-solid",
"twui-header",
props.className
)}
>
{props.children}
</header>
);
}

View File

@ -0,0 +1,21 @@
import { AnchorHTMLAttributes, DetailedHTMLProps } from "react";
import { twMerge } from "tailwind-merge";
export default function Link({
...props
}: DetailedHTMLProps<
AnchorHTMLAttributes<HTMLAnchorElement>,
HTMLAnchorElement
>) {
return (
<a
{...props}
className={twMerge(
"text-base text-link-500 no-underline hover:text-link-500/50",
props.className
)}
>
{props.children}
</a>
);
}

View File

@ -0,0 +1,18 @@
import { DetailedHTMLProps, HTMLAttributes } from "react";
import { twMerge } from "tailwind-merge";
export default function Main({
...props
}: DetailedHTMLProps<HTMLAttributes<HTMLElement>, HTMLElement>) {
return (
<main
{...props}
className={twMerge(
"flex flex-col items-start w-full",
props.className
)}
>
{props.children}
</main>
);
}

12
components/layout/P.tsx Normal file
View File

@ -0,0 +1,12 @@
import { DetailedHTMLProps, HTMLAttributes } from "react";
import { twMerge } from "tailwind-merge";
export default function P({
...props
}: DetailedHTMLProps<HTMLAttributes<HTMLHeadingElement>, HTMLHeadingElement>) {
return (
<p {...props} className={twMerge("text-base py-4", props.className)}>
{props.children}
</p>
);
}

18
components/layout/Row.tsx Normal file
View File

@ -0,0 +1,18 @@
import { DetailedHTMLProps, HTMLAttributes } from "react";
import { twMerge } from "tailwind-merge";
export default function Row({
...props
}: DetailedHTMLProps<HTMLAttributes<HTMLDivElement>, HTMLDivElement>) {
return (
<div
{...props}
className={twMerge(
"flex flex-row items-center gap-2",
props.className
)}
>
{props.children}
</div>
);
}

View File

@ -0,0 +1,19 @@
import { DetailedHTMLProps, HTMLAttributes } from "react";
import { twMerge } from "tailwind-merge";
export default function Section({
...props
}: DetailedHTMLProps<HTMLAttributes<HTMLElement>, HTMLElement>) {
return (
<section
{...props}
className={twMerge(
"flex flex-col items-center w-full",
"px-4 sm:px-10 py-10",
props.className
)}
>
{props.children}
</section>
);
}

View File

@ -0,0 +1,12 @@
import { DetailedHTMLProps, HTMLAttributes } from "react";
import { twMerge } from "tailwind-merge";
export default function Span({
...props
}: DetailedHTMLProps<HTMLAttributes<HTMLHeadingElement>, HTMLHeadingElement>) {
return (
<span {...props} className={twMerge("text-base", props.className)}>
{props.children}
</span>
);
}

View File

@ -0,0 +1,15 @@
import { DetailedHTMLProps, HTMLAttributes } from "react";
import { twMerge } from "tailwind-merge";
export default function Stack({
...props
}: DetailedHTMLProps<HTMLAttributes<HTMLDivElement>, HTMLDivElement>) {
return (
<div
{...props}
className={twMerge("flex flex-col items-start", props.className)}
>
{props.children}
</div>
);
}

6
next.config.mjs Normal file
View File

@ -0,0 +1,6 @@
/** @type {import('next').NextConfig} */
const nextConfig = {
reactStrictMode: true,
};
export default nextConfig;

28
package.json Normal file
View File

@ -0,0 +1,28 @@
{
"name": "tailwind-ui-library",
"version": "0.1.0",
"private": true,
"scripts": {
"dev": "next dev -p 3270",
"build": "next build",
"start": "next start",
"lint": "next lint"
},
"dependencies": {
"tailwind-merge": "^2.5.4",
"postcss": "^8",
"tailwindcss": "^3.4.14"
},
"devDependencies": {
"next": "14.2.15",
"react": "^18",
"react-dom": "^18",
"typescript": "^5",
"@types/node": "^20",
"@types/react": "^18",
"@types/react-dom": "^18"
},
"exports": {
".": "./components"
}
}

8
postcss.config.mjs Normal file
View File

@ -0,0 +1,8 @@
/** @type {import('postcss-load-config').Config} */
const config = {
plugins: {
tailwindcss: {},
},
};
export default config;

29
styles/globals.css Normal file
View File

@ -0,0 +1,29 @@
@tailwind base;
@tailwind components;
@tailwind utilities;
:root {
--background: #ffffff;
--foreground: #171717;
--color-link: #233599;
}
@media (prefers-color-scheme: dark) {
:root {
--background: #0a0a0a;
--foreground: #ededed;
--color-link: #233599;
}
}
body {
color: var(--foreground);
background: var(--background);
font-family: Arial, Helvetica, sans-serif;
}
@layer utilities {
.text-balance {
text-wrap: balance;
}
}

20
tailwind.config.ts Normal file
View File

@ -0,0 +1,20 @@
import type { Config } from "tailwindcss";
const config: Config = {
content: [
"./pages/**/*.{js,ts,jsx,tsx,mdx}",
"./components/**/*.{js,ts,jsx,tsx,mdx}",
"./app/**/*.{js,ts,jsx,tsx,mdx}",
],
theme: {
extend: {
colors: {
background: "var(--background)",
foreground: "var(--foreground)",
link: "var(--link)",
},
},
},
plugins: [],
};
export default config;

21
tsconfig.json Normal file
View File

@ -0,0 +1,21 @@
{
"compilerOptions": {
"lib": ["dom", "dom.iterable", "esnext"],
"allowJs": true,
"skipLibCheck": true,
"strict": true,
"noEmit": true,
"esModuleInterop": true,
"module": "esnext",
"moduleResolution": "bundler",
"resolveJsonModule": true,
"isolatedModules": true,
"jsx": "preserve",
"incremental": true,
"paths": {
"@/*": ["./*"]
}
},
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx"],
"exclude": ["node_modules"]
}