Updates
This commit is contained in:
parent
25daf1844e
commit
f73b56cdc4
@ -1,4 +1,4 @@
|
|||||||
import { DetailedHTMLProps, HTMLAttributes } from "react";
|
import React, { DetailedHTMLProps, HTMLAttributes } from "react";
|
||||||
import { twMerge } from "tailwind-merge";
|
import { twMerge } from "tailwind-merge";
|
||||||
import Toggle, { TWUI_TOGGLE_PROPS } from "./Toggle";
|
import Toggle, { TWUI_TOGGLE_PROPS } from "./Toggle";
|
||||||
|
|
||||||
@ -8,12 +8,22 @@ export default function ColorSchemeSelector({
|
|||||||
}: DetailedHTMLProps<HTMLAttributes<HTMLDivElement>, HTMLDivElement> & {
|
}: DetailedHTMLProps<HTMLAttributes<HTMLDivElement>, HTMLDivElement> & {
|
||||||
toggleProps?: TWUI_TOGGLE_PROPS;
|
toggleProps?: TWUI_TOGGLE_PROPS;
|
||||||
}) {
|
}) {
|
||||||
|
const [active, setActive] = React.useState(false);
|
||||||
|
|
||||||
|
React.useEffect(() => {
|
||||||
|
if (active) {
|
||||||
|
document.documentElement.className = "dark";
|
||||||
|
} else {
|
||||||
|
document.documentElement.className = "";
|
||||||
|
}
|
||||||
|
}, [active]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
{...props}
|
{...props}
|
||||||
className={twMerge("flex flex-row items-center", props.className)}
|
className={twMerge("flex flex-row items-center", props.className)}
|
||||||
>
|
>
|
||||||
<Toggle {...toggleProps} />
|
<Toggle active={active} setActive={setActive} {...toggleProps} />
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
50
components/elements/Loading.tsx
Normal file
50
components/elements/Loading.tsx
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
import { DetailedHTMLProps, HTMLAttributes } from "react";
|
||||||
|
import { twMerge } from "tailwind-merge";
|
||||||
|
|
||||||
|
type Props = DetailedHTMLProps<
|
||||||
|
HTMLAttributes<HTMLDivElement>,
|
||||||
|
HTMLDivElement
|
||||||
|
> & {
|
||||||
|
size?: "small" | "normal" | "medium" | "large";
|
||||||
|
};
|
||||||
|
|
||||||
|
export default function Loading({ size, ...props }: Props) {
|
||||||
|
const sizeClassName = (() => {
|
||||||
|
switch (size) {
|
||||||
|
case "small":
|
||||||
|
return "w-2 h-2";
|
||||||
|
case "normal":
|
||||||
|
return "w-4 h-4";
|
||||||
|
case "normal":
|
||||||
|
return "w-6 h-6";
|
||||||
|
case "large":
|
||||||
|
return "w-8 h-8";
|
||||||
|
|
||||||
|
default:
|
||||||
|
return "w-4 h-4";
|
||||||
|
}
|
||||||
|
})();
|
||||||
|
return (
|
||||||
|
<div role="status" {...props}>
|
||||||
|
<svg
|
||||||
|
aria-hidden="true"
|
||||||
|
className={twMerge(
|
||||||
|
"text-gray-200 animate-spin dark:text-gray-600 fill-blue-600",
|
||||||
|
sizeClassName
|
||||||
|
)}
|
||||||
|
viewBox="0 0 100 101"
|
||||||
|
fill="none"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
d="M100 50.5908C100 78.2051 77.6142 100.591 50 100.591C22.3858 100.591 0 78.2051 0 50.5908C0 22.9766 22.3858 0.59082 50 0.59082C77.6142 0.59082 100 22.9766 100 50.5908ZM9.08144 50.5908C9.08144 73.1895 27.4013 91.5094 50 91.5094C72.5987 91.5094 90.9186 73.1895 90.9186 50.5908C90.9186 27.9921 72.5987 9.67226 50 9.67226C27.4013 9.67226 9.08144 27.9921 9.08144 50.5908Z"
|
||||||
|
fill="currentColor"
|
||||||
|
/>
|
||||||
|
<path
|
||||||
|
d="M93.9676 39.0409C96.393 38.4038 97.8624 35.9116 97.0079 33.5539C95.2932 28.8227 92.871 24.3692 89.8167 20.348C85.8452 15.1192 80.8826 10.7238 75.2124 7.41289C69.5422 4.10194 63.2754 1.94025 56.7698 1.05124C51.7666 0.367541 46.6976 0.446843 41.7345 1.27873C39.2613 1.69328 37.813 4.19778 38.4501 6.62326C39.0873 9.04874 41.5694 10.4717 44.0505 10.1071C47.8511 9.54855 51.7191 9.52689 55.5402 10.0491C60.8642 10.7766 65.9928 12.5457 70.6331 15.2552C75.2735 17.9648 79.3347 21.5619 82.5849 25.841C84.9175 28.9121 86.7997 32.2913 88.1811 35.8758C89.083 38.2158 91.5421 39.6781 93.9676 39.0409Z"
|
||||||
|
fill="currentFill"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
@ -6,6 +6,7 @@ export type TWUI_TOGGLE_PROPS = DetailedHTMLProps<
|
|||||||
HTMLDivElement
|
HTMLDivElement
|
||||||
> & {
|
> & {
|
||||||
active?: boolean;
|
active?: boolean;
|
||||||
|
setActive?: React.Dispatch<React.SetStateAction<boolean>>;
|
||||||
circleProps?: DetailedHTMLProps<
|
circleProps?: DetailedHTMLProps<
|
||||||
HTMLAttributes<HTMLDivElement>,
|
HTMLAttributes<HTMLDivElement>,
|
||||||
HTMLDivElement
|
HTMLDivElement
|
||||||
@ -20,24 +21,28 @@ export type TWUI_TOGGLE_PROPS = DetailedHTMLProps<
|
|||||||
export default function Toggle({
|
export default function Toggle({
|
||||||
circleProps,
|
circleProps,
|
||||||
active,
|
active,
|
||||||
|
setActive,
|
||||||
...props
|
...props
|
||||||
}: TWUI_TOGGLE_PROPS) {
|
}: TWUI_TOGGLE_PROPS) {
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
{...props}
|
{...props}
|
||||||
className={twMerge(
|
className={twMerge(
|
||||||
"flex flex-row items-center w-full max-w-[200px]",
|
"flex flex-row items-center w-[40px] p-[3px] transition-all",
|
||||||
"border border-slate-300 border-solid rounded-full",
|
"border border-slate-300 dark:border-white/30 border-solid rounded-full",
|
||||||
active ? "" : "",
|
active ? "justify-end" : "justify-start",
|
||||||
"twui-toggle-wrapper",
|
"twui-toggle-wrapper",
|
||||||
props.className
|
props.className
|
||||||
)}
|
)}
|
||||||
|
onClick={() => setActive?.(!active)}
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
{...circleProps}
|
{...circleProps}
|
||||||
className={twMerge(
|
className={twMerge(
|
||||||
"w-20 h-20 rounded-full",
|
"w-3.5 h-3.5 rounded-full ",
|
||||||
active ? "" : "",
|
active
|
||||||
|
? "bg-blue-600 dark:bg-blue-500"
|
||||||
|
: "bg-slate-300 dark:bg-white/40",
|
||||||
"twui-toggle-circle",
|
"twui-toggle-circle",
|
||||||
circleProps?.className
|
circleProps?.className
|
||||||
)}
|
)}
|
||||||
|
|||||||
@ -1,6 +1,10 @@
|
|||||||
import { DetailedHTMLProps, FormHTMLAttributes } from "react";
|
import { DetailedHTMLProps, FormHTMLAttributes } from "react";
|
||||||
import { twMerge } from "tailwind-merge";
|
import { twMerge } from "tailwind-merge";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* # Form Element
|
||||||
|
* @className twui-form
|
||||||
|
*/
|
||||||
export default function Form({
|
export default function Form({
|
||||||
...props
|
...props
|
||||||
}: DetailedHTMLProps<FormHTMLAttributes<HTMLFormElement>, HTMLFormElement>) {
|
}: DetailedHTMLProps<FormHTMLAttributes<HTMLFormElement>, HTMLFormElement>) {
|
||||||
@ -8,10 +12,12 @@ export default function Form({
|
|||||||
<form
|
<form
|
||||||
{...props}
|
{...props}
|
||||||
className={twMerge(
|
className={twMerge(
|
||||||
"flex flex-col items-start gap-4 w-full",
|
"flex flex-col items-stretch gap-2 w-full bg-transparent",
|
||||||
"twui-form",
|
"twui-form",
|
||||||
props.className
|
props.className
|
||||||
)}
|
)}
|
||||||
></form>
|
>
|
||||||
|
{props.children}
|
||||||
|
</form>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,6 +1,10 @@
|
|||||||
import { DetailedHTMLProps, InputHTMLAttributes } from "react";
|
import { DetailedHTMLProps, InputHTMLAttributes } from "react";
|
||||||
import { twMerge } from "tailwind-merge";
|
import { twMerge } from "tailwind-merge";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* # Input Element
|
||||||
|
* @className twui-input
|
||||||
|
*/
|
||||||
export default function Input({
|
export default function Input({
|
||||||
...props
|
...props
|
||||||
}: DetailedHTMLProps<InputHTMLAttributes<HTMLInputElement>, HTMLInputElement>) {
|
}: DetailedHTMLProps<InputHTMLAttributes<HTMLInputElement>, HTMLInputElement>) {
|
||||||
@ -8,7 +12,12 @@ export default function Input({
|
|||||||
<input
|
<input
|
||||||
{...props}
|
{...props}
|
||||||
className={twMerge(
|
className={twMerge(
|
||||||
"w-full px-4 py-2 border border-slate-300 rounded",
|
"w-full px-4 py-2 border rounded-md",
|
||||||
|
"border-slate-300 dark:border-white/20",
|
||||||
|
"focus:border-slate-700 dark:focus:border-white/50",
|
||||||
|
"outline-slate-300 dark:outline-white/20",
|
||||||
|
"focus:outline-slate-700 dark:focus:outline-white/50",
|
||||||
|
"bg-white dark:bg-black",
|
||||||
"twui-input",
|
"twui-input",
|
||||||
props.className
|
props.className
|
||||||
)}
|
)}
|
||||||
|
|||||||
24
components/form/Textarea.tsx
Normal file
24
components/form/Textarea.tsx
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
import { DetailedHTMLProps, TextareaHTMLAttributes } from "react";
|
||||||
|
import { twMerge } from "tailwind-merge";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* # Textarea Component
|
||||||
|
* @className twui-textarea
|
||||||
|
*/
|
||||||
|
export default function Textarea({
|
||||||
|
...props
|
||||||
|
}: DetailedHTMLProps<
|
||||||
|
TextareaHTMLAttributes<HTMLTextAreaElement>,
|
||||||
|
HTMLTextAreaElement
|
||||||
|
>) {
|
||||||
|
return (
|
||||||
|
<textarea
|
||||||
|
{...props}
|
||||||
|
className={twMerge(
|
||||||
|
"w-full px-4 py-2 border border-slate-300 rounded",
|
||||||
|
"twui-textarea",
|
||||||
|
props.className
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
@ -3,25 +3,44 @@ import {
|
|||||||
ButtonHTMLAttributes,
|
ButtonHTMLAttributes,
|
||||||
DetailedHTMLProps,
|
DetailedHTMLProps,
|
||||||
HTMLAttributeAnchorTarget,
|
HTMLAttributeAnchorTarget,
|
||||||
HTMLAttributes,
|
|
||||||
} from "react";
|
} from "react";
|
||||||
import { ClassNameValue, twMerge } from "tailwind-merge";
|
import { twMerge } from "tailwind-merge";
|
||||||
|
import Loading from "../elements/Loading";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* # Buttons
|
||||||
|
* @className twui-button-general
|
||||||
|
* @className twui-button-content-wrapper
|
||||||
|
* @className twui-button-primary
|
||||||
|
* @className twui-button-primary-outlined
|
||||||
|
* @className twui-button-primary-ghost
|
||||||
|
* @className twui-button-secondary
|
||||||
|
* @className twui-button-secondary-outlined
|
||||||
|
* @className twui-button-secondary-ghost
|
||||||
|
* @className twui-button-accent
|
||||||
|
* @className twui-button-accent-outlined
|
||||||
|
* @className twui-button-accent-ghost
|
||||||
|
* @className twui-button-gray
|
||||||
|
* @className twui-button-gray-outlined
|
||||||
|
* @className twui-button-gray-ghost
|
||||||
|
*/
|
||||||
export default function Button({
|
export default function Button({
|
||||||
href,
|
href,
|
||||||
target,
|
target,
|
||||||
variant,
|
variant,
|
||||||
color,
|
color,
|
||||||
linkProps,
|
linkProps,
|
||||||
|
loading,
|
||||||
...props
|
...props
|
||||||
}: DetailedHTMLProps<
|
}: DetailedHTMLProps<
|
||||||
ButtonHTMLAttributes<HTMLButtonElement>,
|
ButtonHTMLAttributes<HTMLButtonElement>,
|
||||||
HTMLButtonElement
|
HTMLButtonElement
|
||||||
> & {
|
> & {
|
||||||
variant?: "normal" | "ghost" | "outlined";
|
variant?: "normal" | "ghost" | "outlined";
|
||||||
color?: "primary" | "secondary" | "accent";
|
color?: "primary" | "secondary" | "accent" | "gray";
|
||||||
href?: string;
|
href?: string;
|
||||||
target?: HTMLAttributeAnchorTarget;
|
target?: HTMLAttributeAnchorTarget;
|
||||||
|
loading?: boolean;
|
||||||
linkProps?: DetailedHTMLProps<
|
linkProps?: DetailedHTMLProps<
|
||||||
AnchorHTMLAttributes<HTMLAnchorElement>,
|
AnchorHTMLAttributes<HTMLAnchorElement>,
|
||||||
HTMLAnchorElement
|
HTMLAnchorElement
|
||||||
@ -29,14 +48,76 @@ export default function Button({
|
|||||||
}) {
|
}) {
|
||||||
const finalClassName: string = (() => {
|
const finalClassName: string = (() => {
|
||||||
if (variant == "normal" || !variant) {
|
if (variant == "normal" || !variant) {
|
||||||
if (color == "primary" || !color) return "bg-blue-500 text-white";
|
if (color == "primary" || !color)
|
||||||
|
return twMerge(
|
||||||
|
"bg-blue-500 hover:bg-blue-600 text-white",
|
||||||
|
"twui-button-primary"
|
||||||
|
);
|
||||||
|
if (color == "secondary")
|
||||||
|
return twMerge(
|
||||||
|
"bg-emerald-500 hover:bg-emerald-600 text-white",
|
||||||
|
"twui-button-secondary"
|
||||||
|
);
|
||||||
|
if (color == "accent")
|
||||||
|
return twMerge(
|
||||||
|
"bg-violet-500 hover:bg-violet-600 text-white",
|
||||||
|
"twui-button-accent"
|
||||||
|
);
|
||||||
|
if (color == "gray")
|
||||||
|
return twMerge(
|
||||||
|
"bg-slate-300 hover:bg-slate-200 text-slate-800",
|
||||||
|
"twui-button-gray"
|
||||||
|
);
|
||||||
} else if (variant == "outlined") {
|
} else if (variant == "outlined") {
|
||||||
if (color == "primary" || !color)
|
if (color == "primary" || !color)
|
||||||
return (
|
return twMerge(
|
||||||
"bg-transparent outline outline-1 outline-blue-500" +
|
"bg-transparent outline outline-1 outline-blue-500",
|
||||||
" text-blue-500"
|
"text-blue-500",
|
||||||
|
"twui-button-primary-outlined"
|
||||||
|
);
|
||||||
|
if (color == "secondary")
|
||||||
|
return twMerge(
|
||||||
|
"bg-transparent outline outline-1 outline-emerald-500",
|
||||||
|
"text-emerald-500",
|
||||||
|
"twui-button-secondary-outlined"
|
||||||
|
);
|
||||||
|
if (color == "accent")
|
||||||
|
return twMerge(
|
||||||
|
"bg-transparent outline outline-1 outline-violet-500",
|
||||||
|
"text-violet-500",
|
||||||
|
"twui-button-accent-outlined"
|
||||||
|
);
|
||||||
|
if (color == "gray")
|
||||||
|
return twMerge(
|
||||||
|
"bg-transparent outline outline-1 outline-slate-300",
|
||||||
|
"text-slate-600",
|
||||||
|
"twui-button-gray-outlined"
|
||||||
);
|
);
|
||||||
} else if (variant == "ghost") {
|
} else if (variant == "ghost") {
|
||||||
|
if (color == "primary" || !color)
|
||||||
|
return twMerge(
|
||||||
|
"bg-transparent outline-none p-2",
|
||||||
|
"text-blue-500",
|
||||||
|
"twui-button-primary-ghost"
|
||||||
|
);
|
||||||
|
if (color == "secondary")
|
||||||
|
return twMerge(
|
||||||
|
"bg-transparent outline-none p-2",
|
||||||
|
"text-emerald-500",
|
||||||
|
"twui-button-secondary-ghost"
|
||||||
|
);
|
||||||
|
if (color == "accent")
|
||||||
|
return twMerge(
|
||||||
|
"bg-transparent outline-none p-2",
|
||||||
|
"text-violet-500",
|
||||||
|
"twui-button-accent-ghost"
|
||||||
|
);
|
||||||
|
if (color == "gray")
|
||||||
|
return twMerge(
|
||||||
|
"bg-transparent outline-none p-2",
|
||||||
|
"text-slate-600",
|
||||||
|
"twui-button-gray-ghost"
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return "";
|
return "";
|
||||||
@ -47,11 +128,23 @@ export default function Button({
|
|||||||
{...props}
|
{...props}
|
||||||
className={twMerge(
|
className={twMerge(
|
||||||
"bg-blue-600 text-white text-base font-medium px-4 py-2 rounded",
|
"bg-blue-600 text-white text-base font-medium px-4 py-2 rounded",
|
||||||
|
"flex items-center justify-center relative transition-all",
|
||||||
|
"twui-button-general",
|
||||||
finalClassName,
|
finalClassName,
|
||||||
props.className
|
props.className,
|
||||||
|
loading ? "pointer-events-none opacity-80" : "l"
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
{props.children}
|
<div
|
||||||
|
className={twMerge(
|
||||||
|
"flex items-center gap-2",
|
||||||
|
loading ? "opacity-0" : "",
|
||||||
|
"twui-button-content-wrapper"
|
||||||
|
)}
|
||||||
|
>
|
||||||
|
{props.children}
|
||||||
|
</div>
|
||||||
|
{loading && <Loading className="absolute" />}
|
||||||
</button>
|
</button>
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
@ -12,7 +12,8 @@ export default function Container({
|
|||||||
<div
|
<div
|
||||||
{...props}
|
{...props}
|
||||||
className={twMerge(
|
className={twMerge(
|
||||||
"flex flex-row items-center w-full max-w-[1200px]",
|
"flex items-center w-full max-w-[1200px] gap-4 justify-between",
|
||||||
|
"flex-wrap flex-col xl:flex-row",
|
||||||
"twui-container",
|
"twui-container",
|
||||||
props.className
|
props.className
|
||||||
)}
|
)}
|
||||||
|
|||||||
27
components/layout/Divider.tsx
Normal file
27
components/layout/Divider.tsx
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
import { DetailedHTMLProps, HTMLAttributes } from "react";
|
||||||
|
import { twMerge } from "tailwind-merge";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* # Vertical and Horizontal Divider
|
||||||
|
* @className twui-divider
|
||||||
|
*/
|
||||||
|
export default function Divider({
|
||||||
|
vertical,
|
||||||
|
...props
|
||||||
|
}: DetailedHTMLProps<HTMLAttributes<HTMLDivElement>, HTMLDivElement> & {
|
||||||
|
vertical?: boolean;
|
||||||
|
}) {
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
{...props}
|
||||||
|
className={twMerge(
|
||||||
|
"border-slate-200 dark:border-white/10",
|
||||||
|
vertical
|
||||||
|
? "border-0 border-l h-full min-h-5"
|
||||||
|
: "border-0 border-t w-full",
|
||||||
|
"twui-divider",
|
||||||
|
props.className
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
@ -1,11 +1,15 @@
|
|||||||
import { DetailedHTMLProps, HTMLAttributes } from "react";
|
import { DetailedHTMLProps, HTMLAttributes } from "react";
|
||||||
import { twMerge } from "tailwind-merge";
|
import { twMerge } from "tailwind-merge";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* # General Footer
|
||||||
|
* @className twui-footer
|
||||||
|
*/
|
||||||
export default function Footer({
|
export default function Footer({
|
||||||
...props
|
...props
|
||||||
}: DetailedHTMLProps<HTMLAttributes<HTMLElement>, HTMLElement>) {
|
}: DetailedHTMLProps<HTMLAttributes<HTMLElement>, HTMLElement>) {
|
||||||
return (
|
return (
|
||||||
<header
|
<footer
|
||||||
{...props}
|
{...props}
|
||||||
className={twMerge(
|
className={twMerge(
|
||||||
"flex flex-col items-center justify-center",
|
"flex flex-col items-center justify-center",
|
||||||
@ -16,6 +20,6 @@ export default function Footer({
|
|||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
{props.children}
|
{props.children}
|
||||||
</header>
|
</footer>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,11 +1,18 @@
|
|||||||
import { DetailedHTMLProps, HTMLAttributes } from "react";
|
import { DetailedHTMLProps, HTMLAttributes } from "react";
|
||||||
import { twMerge } from "tailwind-merge";
|
import { twMerge } from "tailwind-merge";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* # H1 Headers
|
||||||
|
* @className twui-h1
|
||||||
|
*/
|
||||||
export default function H1({
|
export default function H1({
|
||||||
...props
|
...props
|
||||||
}: DetailedHTMLProps<HTMLAttributes<HTMLHeadingElement>, HTMLHeadingElement>) {
|
}: DetailedHTMLProps<HTMLAttributes<HTMLHeadingElement>, HTMLHeadingElement>) {
|
||||||
return (
|
return (
|
||||||
<h1 {...props} className={twMerge("text-5xl mb-4", props.className)}>
|
<h1
|
||||||
|
{...props}
|
||||||
|
className={twMerge("text-5xl mb-4", "twui-h1", props.className)}
|
||||||
|
>
|
||||||
{props.children}
|
{props.children}
|
||||||
</h1>
|
</h1>
|
||||||
);
|
);
|
||||||
|
|||||||
@ -1,11 +1,18 @@
|
|||||||
import { DetailedHTMLProps, HTMLAttributes } from "react";
|
import { DetailedHTMLProps, HTMLAttributes } from "react";
|
||||||
import { twMerge } from "tailwind-merge";
|
import { twMerge } from "tailwind-merge";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* # H2 Headers
|
||||||
|
* @className twui-h2
|
||||||
|
*/
|
||||||
export default function H2({
|
export default function H2({
|
||||||
...props
|
...props
|
||||||
}: DetailedHTMLProps<HTMLAttributes<HTMLHeadingElement>, HTMLHeadingElement>) {
|
}: DetailedHTMLProps<HTMLAttributes<HTMLHeadingElement>, HTMLHeadingElement>) {
|
||||||
return (
|
return (
|
||||||
<h2 {...props} className={twMerge("text-3xl mb-4", props.className)}>
|
<h2
|
||||||
|
{...props}
|
||||||
|
className={twMerge("text-3xl mb-4", "twui-h2", props.className)}
|
||||||
|
>
|
||||||
{props.children}
|
{props.children}
|
||||||
</h2>
|
</h2>
|
||||||
);
|
);
|
||||||
|
|||||||
@ -1,11 +1,18 @@
|
|||||||
import { DetailedHTMLProps, HTMLAttributes } from "react";
|
import { DetailedHTMLProps, HTMLAttributes } from "react";
|
||||||
import { twMerge } from "tailwind-merge";
|
import { twMerge } from "tailwind-merge";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* # H3 Headers
|
||||||
|
* @className twui-h3
|
||||||
|
*/
|
||||||
export default function H3({
|
export default function H3({
|
||||||
...props
|
...props
|
||||||
}: DetailedHTMLProps<HTMLAttributes<HTMLHeadingElement>, HTMLHeadingElement>) {
|
}: DetailedHTMLProps<HTMLAttributes<HTMLHeadingElement>, HTMLHeadingElement>) {
|
||||||
return (
|
return (
|
||||||
<h3 {...props} className={twMerge("text-xl mb-4", props.className)}>
|
<h3
|
||||||
|
{...props}
|
||||||
|
className={twMerge("text-xl mb-4", "twui-h3", props.className)}
|
||||||
|
>
|
||||||
{props.children}
|
{props.children}
|
||||||
</h3>
|
</h3>
|
||||||
);
|
);
|
||||||
|
|||||||
@ -1,11 +1,18 @@
|
|||||||
import { DetailedHTMLProps, HTMLAttributes } from "react";
|
import { DetailedHTMLProps, HTMLAttributes } from "react";
|
||||||
import { twMerge } from "tailwind-merge";
|
import { twMerge } from "tailwind-merge";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* # H4 Headers
|
||||||
|
* @className twui-h4
|
||||||
|
*/
|
||||||
export default function H4({
|
export default function H4({
|
||||||
...props
|
...props
|
||||||
}: DetailedHTMLProps<HTMLAttributes<HTMLHeadingElement>, HTMLHeadingElement>) {
|
}: DetailedHTMLProps<HTMLAttributes<HTMLHeadingElement>, HTMLHeadingElement>) {
|
||||||
return (
|
return (
|
||||||
<h4 {...props} className={twMerge("text-base mb-4", props.className)}>
|
<h4
|
||||||
|
{...props}
|
||||||
|
className={twMerge("text-base mb-4", "twui-h4", props.className)}
|
||||||
|
>
|
||||||
{props.children}
|
{props.children}
|
||||||
</h4>
|
</h4>
|
||||||
);
|
);
|
||||||
|
|||||||
@ -1,11 +1,18 @@
|
|||||||
import { DetailedHTMLProps, HTMLAttributes } from "react";
|
import { DetailedHTMLProps, HTMLAttributes } from "react";
|
||||||
import { twMerge } from "tailwind-merge";
|
import { twMerge } from "tailwind-merge";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* # H5 Headers
|
||||||
|
* @className twui-h5
|
||||||
|
*/
|
||||||
export default function H5({
|
export default function H5({
|
||||||
...props
|
...props
|
||||||
}: DetailedHTMLProps<HTMLAttributes<HTMLHeadingElement>, HTMLHeadingElement>) {
|
}: DetailedHTMLProps<HTMLAttributes<HTMLHeadingElement>, HTMLHeadingElement>) {
|
||||||
return (
|
return (
|
||||||
<h5 {...props} className={twMerge("text-sm mb-4", props.className)}>
|
<h5
|
||||||
|
{...props}
|
||||||
|
className={twMerge("text-sm mb-4", "twui-h5", props.className)}
|
||||||
|
>
|
||||||
{props.children}
|
{props.children}
|
||||||
</h5>
|
</h5>
|
||||||
);
|
);
|
||||||
|
|||||||
@ -1,6 +1,10 @@
|
|||||||
import { DetailedHTMLProps, HTMLAttributes } from "react";
|
import { DetailedHTMLProps, HTMLAttributes } from "react";
|
||||||
import { twMerge } from "tailwind-merge";
|
import { twMerge } from "tailwind-merge";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* # Horizonta Rule (hr)
|
||||||
|
* @className twui-hr
|
||||||
|
*/
|
||||||
export default function HR({
|
export default function HR({
|
||||||
...props
|
...props
|
||||||
}: DetailedHTMLProps<HTMLAttributes<HTMLHRElement>, HTMLHRElement>) {
|
}: DetailedHTMLProps<HTMLAttributes<HTMLHRElement>, HTMLHRElement>) {
|
||||||
@ -8,7 +12,8 @@ export default function HR({
|
|||||||
<hr
|
<hr
|
||||||
{...props}
|
{...props}
|
||||||
className={twMerge(
|
className={twMerge(
|
||||||
"bg-slate-400 w-full dark:bg-white/20 my-4",
|
"border-slate-200 dark:border-white/20 w-full my-4",
|
||||||
|
"twui-hr",
|
||||||
props.className
|
props.className
|
||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
|
|||||||
@ -13,8 +13,8 @@ export default function Header({
|
|||||||
{...props}
|
{...props}
|
||||||
className={twMerge(
|
className={twMerge(
|
||||||
"flex flex-col items-center justify-center",
|
"flex flex-col items-center justify-center",
|
||||||
"px-4 sm:px-10 py-2",
|
"px-4 sm:px-10 py-3 flex-wrap",
|
||||||
"border-0 border-b border-slate-200 border-solid",
|
"border-0 border-b border-slate-200 dark:border-white/10 border-solid",
|
||||||
"twui-header",
|
"twui-header",
|
||||||
props.className
|
props.className
|
||||||
)}
|
)}
|
||||||
|
|||||||
@ -1,6 +1,10 @@
|
|||||||
import { AnchorHTMLAttributes, DetailedHTMLProps } from "react";
|
import { AnchorHTMLAttributes, DetailedHTMLProps } from "react";
|
||||||
import { twMerge } from "tailwind-merge";
|
import { twMerge } from "tailwind-merge";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* # General Anchor Elements
|
||||||
|
* @className twui-a | twui-anchor
|
||||||
|
*/
|
||||||
export default function Link({
|
export default function Link({
|
||||||
...props
|
...props
|
||||||
}: DetailedHTMLProps<
|
}: DetailedHTMLProps<
|
||||||
@ -12,6 +16,10 @@ export default function Link({
|
|||||||
{...props}
|
{...props}
|
||||||
className={twMerge(
|
className={twMerge(
|
||||||
"text-base text-link-500 no-underline hover:text-link-500/50",
|
"text-base text-link-500 no-underline hover:text-link-500/50",
|
||||||
|
"text-blue-600 dark:text-blue-400",
|
||||||
|
"border-0 border-b border-blue-300 border-solid leading-4",
|
||||||
|
"twui-anchor",
|
||||||
|
"twui-a",
|
||||||
props.className
|
props.className
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
|
|||||||
54
components/layout/List.tsx
Normal file
54
components/layout/List.tsx
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
import {
|
||||||
|
AnchorHTMLAttributes,
|
||||||
|
DetailedHTMLProps,
|
||||||
|
HTMLAttributes,
|
||||||
|
OlHTMLAttributes,
|
||||||
|
} from "react";
|
||||||
|
import { twMerge } from "tailwind-merge";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* # Ordered and unorder Lists
|
||||||
|
* @className twui-ol
|
||||||
|
* @className twui-ul
|
||||||
|
*/
|
||||||
|
export default function List({
|
||||||
|
ordered,
|
||||||
|
items,
|
||||||
|
...props
|
||||||
|
}: DetailedHTMLProps<HTMLAttributes<HTMLUListElement>, HTMLUListElement> &
|
||||||
|
DetailedHTMLProps<OlHTMLAttributes<HTMLOListElement>, HTMLOListElement> & {
|
||||||
|
items: {
|
||||||
|
content: React.ReactNode | string;
|
||||||
|
}[];
|
||||||
|
ordered?: boolean;
|
||||||
|
}) {
|
||||||
|
const listContent = (
|
||||||
|
<>
|
||||||
|
{items.map((item, index) => (
|
||||||
|
<li key={index}>{item.content}</li>
|
||||||
|
))}
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
|
||||||
|
const className = "flex flex-col items-start gap-4";
|
||||||
|
|
||||||
|
if (ordered) {
|
||||||
|
return (
|
||||||
|
<ol
|
||||||
|
{...props}
|
||||||
|
className={twMerge(className, "twui-ol", props.className)}
|
||||||
|
>
|
||||||
|
{listContent}
|
||||||
|
</ol>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<ul
|
||||||
|
{...props}
|
||||||
|
className={twMerge(className, "twui-ul", props.className)}
|
||||||
|
>
|
||||||
|
{listContent}
|
||||||
|
</ul>
|
||||||
|
);
|
||||||
|
}
|
||||||
@ -1,6 +1,10 @@
|
|||||||
import { DetailedHTMLProps, HTMLAttributes } from "react";
|
import { DetailedHTMLProps, HTMLAttributes } from "react";
|
||||||
import { twMerge } from "tailwind-merge";
|
import { twMerge } from "tailwind-merge";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* # Main Wrapper
|
||||||
|
* @className twui-h1
|
||||||
|
*/
|
||||||
export default function Main({
|
export default function Main({
|
||||||
...props
|
...props
|
||||||
}: DetailedHTMLProps<HTMLAttributes<HTMLElement>, HTMLElement>) {
|
}: DetailedHTMLProps<HTMLAttributes<HTMLElement>, HTMLElement>) {
|
||||||
@ -8,7 +12,8 @@ export default function Main({
|
|||||||
<main
|
<main
|
||||||
{...props}
|
{...props}
|
||||||
className={twMerge(
|
className={twMerge(
|
||||||
"flex flex-col items-start w-full",
|
"flex flex-col items-center w-full",
|
||||||
|
"twui-main",
|
||||||
props.className
|
props.className
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
|
|||||||
@ -1,11 +1,23 @@
|
|||||||
import { DetailedHTMLProps, HTMLAttributes } from "react";
|
import { DetailedHTMLProps, HTMLAttributes } from "react";
|
||||||
import { twMerge } from "tailwind-merge";
|
import { twMerge } from "tailwind-merge";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* # Paragraph Tag
|
||||||
|
* @className twui-p | twui-paragraph
|
||||||
|
*/
|
||||||
export default function P({
|
export default function P({
|
||||||
...props
|
...props
|
||||||
}: DetailedHTMLProps<HTMLAttributes<HTMLHeadingElement>, HTMLHeadingElement>) {
|
}: DetailedHTMLProps<HTMLAttributes<HTMLHeadingElement>, HTMLHeadingElement>) {
|
||||||
return (
|
return (
|
||||||
<p {...props} className={twMerge("text-base py-4", props.className)}>
|
<p
|
||||||
|
{...props}
|
||||||
|
className={twMerge(
|
||||||
|
"text-base py-4",
|
||||||
|
"twui-p",
|
||||||
|
"twui-paragraph",
|
||||||
|
props.className
|
||||||
|
)}
|
||||||
|
>
|
||||||
{props.children}
|
{props.children}
|
||||||
</p>
|
</p>
|
||||||
);
|
);
|
||||||
|
|||||||
@ -1,6 +1,10 @@
|
|||||||
import { DetailedHTMLProps, HTMLAttributes } from "react";
|
import { DetailedHTMLProps, HTMLAttributes } from "react";
|
||||||
import { twMerge } from "tailwind-merge";
|
import { twMerge } from "tailwind-merge";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* # Flexbox Row
|
||||||
|
* @className twui-row
|
||||||
|
*/
|
||||||
export default function Row({
|
export default function Row({
|
||||||
...props
|
...props
|
||||||
}: DetailedHTMLProps<HTMLAttributes<HTMLDivElement>, HTMLDivElement>) {
|
}: DetailedHTMLProps<HTMLAttributes<HTMLDivElement>, HTMLDivElement>) {
|
||||||
@ -8,7 +12,8 @@ export default function Row({
|
|||||||
<div
|
<div
|
||||||
{...props}
|
{...props}
|
||||||
className={twMerge(
|
className={twMerge(
|
||||||
"flex flex-row items-center gap-2",
|
"flex flex-row items-center gap-2 flex-wrap",
|
||||||
|
"twui-row",
|
||||||
props.className
|
props.className
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
|
|||||||
@ -1,6 +1,10 @@
|
|||||||
import { DetailedHTMLProps, HTMLAttributes } from "react";
|
import { DetailedHTMLProps, HTMLAttributes } from "react";
|
||||||
import { twMerge } from "tailwind-merge";
|
import { twMerge } from "tailwind-merge";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* # General Section
|
||||||
|
* @className twui-section
|
||||||
|
*/
|
||||||
export default function Section({
|
export default function Section({
|
||||||
...props
|
...props
|
||||||
}: DetailedHTMLProps<HTMLAttributes<HTMLElement>, HTMLElement>) {
|
}: DetailedHTMLProps<HTMLAttributes<HTMLElement>, HTMLElement>) {
|
||||||
@ -10,6 +14,7 @@ export default function Section({
|
|||||||
className={twMerge(
|
className={twMerge(
|
||||||
"flex flex-col items-center w-full",
|
"flex flex-col items-center w-full",
|
||||||
"px-4 sm:px-10 py-10",
|
"px-4 sm:px-10 py-10",
|
||||||
|
"twui-section",
|
||||||
props.className
|
props.className
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
|
|||||||
@ -1,11 +1,18 @@
|
|||||||
import { DetailedHTMLProps, HTMLAttributes } from "react";
|
import { DetailedHTMLProps, HTMLAttributes } from "react";
|
||||||
import { twMerge } from "tailwind-merge";
|
import { twMerge } from "tailwind-merge";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* # Span element
|
||||||
|
* @className twui-span
|
||||||
|
*/
|
||||||
export default function Span({
|
export default function Span({
|
||||||
...props
|
...props
|
||||||
}: DetailedHTMLProps<HTMLAttributes<HTMLHeadingElement>, HTMLHeadingElement>) {
|
}: DetailedHTMLProps<HTMLAttributes<HTMLHeadingElement>, HTMLHeadingElement>) {
|
||||||
return (
|
return (
|
||||||
<span {...props} className={twMerge("text-base", props.className)}>
|
<span
|
||||||
|
{...props}
|
||||||
|
className={twMerge("text-base", "twui-span", props.className)}
|
||||||
|
>
|
||||||
{props.children}
|
{props.children}
|
||||||
</span>
|
</span>
|
||||||
);
|
);
|
||||||
|
|||||||
@ -1,13 +1,21 @@
|
|||||||
import { DetailedHTMLProps, HTMLAttributes } from "react";
|
import { DetailedHTMLProps, HTMLAttributes } from "react";
|
||||||
import { twMerge } from "tailwind-merge";
|
import { twMerge } from "tailwind-merge";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* # Flexbox Column
|
||||||
|
* @className twui-stack
|
||||||
|
*/
|
||||||
export default function Stack({
|
export default function Stack({
|
||||||
...props
|
...props
|
||||||
}: DetailedHTMLProps<HTMLAttributes<HTMLDivElement>, HTMLDivElement>) {
|
}: DetailedHTMLProps<HTMLAttributes<HTMLDivElement>, HTMLDivElement>) {
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
{...props}
|
{...props}
|
||||||
className={twMerge("flex flex-col items-start", props.className)}
|
className={twMerge(
|
||||||
|
"flex flex-col items-start",
|
||||||
|
"twui-stack",
|
||||||
|
props.className
|
||||||
|
)}
|
||||||
>
|
>
|
||||||
{props.children}
|
{props.children}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user