feat: Add qwik-react (#103)

This adds the following pages:

The landing page (/)
The pricing page (/pricing)
The contact page (/contact)
The changelog page (/changelog)
Terms Of Service page (/terms)
Privacy Policy (/privacy)
This commit is contained in:
Wanjohi
2024-08-30 16:19:58 +03:00
committed by GitHub
parent d13d3dc5d8
commit 73cec51728
102 changed files with 5096 additions and 105 deletions

View File

@@ -0,0 +1,178 @@
// The solid and outlined variants are based on CSS Pro 3D Buttons code (https://csspro.com/css-3d-buttons/)
import { tv } from "tailwind-variants";
export type ButtonVariantProps = {
variant?: keyof typeof buttonVariants | undefined;
intent?: keyof typeof solid.variants.intent;
size?: keyof typeof baseButton.variants.size;
};
export type ButtonVariantIconProps = {
type?: keyof typeof buttonIcon.variants.type;
size?: keyof typeof buttonIcon.variants.size;
};
const baseButton = tv({
base: "group font-title flex justify-center select-none gap-1.5 items-center rounded-lg outline-2 outline-offset-2 focus-visible:outline outline-primary-6000 disabled:text-gray-400 disabled:border disabled:border-gray-300 dark:disabled:bg-gray-500/10 disabled:bg-gray-200 disabled:shadow-none disabled:hover:brightness-100 dark:disabled:text-gray-700 dark:disabled:shadow-none disabled:cursor-not-allowed dark:disabled:border dark:disabled:border-gray-700", // dark:disabled:[background-image:none]
variants: {
size: {
xs: "text-sm h-7 px-3",
sm: "text-sm h-8 px-3.5",
md: "text-base h-9 px-4",
lg: "text-base h-10 px-5",
xl: "text-lg h-12 px-6",
},
iconOnlyButtonSize: {
xs: "size-7",
sm: "size-8",
md: "size-9",
lg: "size-10",
xl: "size-12",
},
defaultVariants: {
intent: "primary",
size: "md",
},
},
});
const link = tv({
// extend: baseButton,
// base: "group transition-shadows relative ml-1.5 font-medium shadow-[inset_0_-0.2em_0_0_theme(colors.primary.200)] dark:shadow-[inset_0_-0.2em_0_0_theme(colors.primary.600)] duration-300 ease-out hover:shadow-[inset_0_-1em_0_0_theme(colors.primary.200)] dark:hover:shadow-[inset_0_-1em_0_0_theme(colors.primary.600)] text-primary-950 font-medium dark:text-primary-50", //"relative text-primary-950 font-medium dark:text-primary-50 hover:after:w-[calc(100%+2px)] focus:after:w-[calc(100%+2px)] px-1 after:-bottom-1 transition-all duration-[.2s] ease-[cubic-bezier(.165,.84,.44,1)] after:w-0 after:h-0.5 after:bg-primary-950 dark:after:bg-primary-50 after:absolute after:left-0 after:transition-[width] after:duration-[.2s] focus:shadow-none outline-none"
base: "group relative ml-1.5 font-medium border-b-2 border-primary-950 dark:border-primary-50 hover:border-primary-950/60 dark:hover:border-primary-50/60 hover:text-primary-950/70 dark:hover:text-primary-50/70 text-primary-950 font-medium dark:text-primary-50", //"relative text-primary-950 font-medium dark:text-primary-50 hover:after:w-[calc(100%+2px)] focus:after:w-[calc(100%+2px)] px-1 after:-bottom-1 transition-all duration-[.2s] ease-[cubic-bezier(.165,.84,.44,1)] after:w-0 after:h-0.5 after:bg-primary-950 dark:after:bg-primary-50 after:absolute after:left-0 after:transition-[width] after:duration-[.2s] focus:shadow-none outline-none"
variants: {
size: {
xs: "text-sm h-7 px-3",
sm: "text-sm h-8 px-3.5",
md: "text-base h-9 px-4",
lg: "text-base h-10 px-5",
xl: "text-lg h-12 px-6",
},
iconOnlyButtonSize: {
xs: "size-7",
sm: "size-8",
md: "size-9",
lg: "size-10",
xl: "size-12",
},
defaultVariants: {
intent: "primary",
size: "md",
},
},
});
const solid = tv({
extend: baseButton,
base: "bg-gradient-to-b [box-shadow:rgba(255,255,255,0.25)_0px_1px_0px_0px_inset,var(--btn-border-color)_0px_0px_0px_1px] text-white hover:brightness-[1.1] transition-[filter] duration-150 ease-in-out active:brightness-95 dark:border-t dark:shadow-white/10 disabled:from-gray-200 disabled:to-gray-200 dark:disabled:text-gray-400 dark:disabled:from-gray-800 dark:disabled:to-gray-800",
variants: {
intent: {
primary:
"from-primary-500 to-primary-600 [--btn-border-color:theme(colors.primary.600)] dark:border-primary-500/75",
secondary:
"from-secondary-500 to-secondary-600 [--btn-border-color:theme(colors.secondary.700)] dark:border-secondary-400/75",
accent: "from-accent-500 to-accent-600 [--btn-border-color:theme(colors.accent.700)] dark:border-accent-400/75",
danger: "from-danger-500 to-danger-600 [--btn-border-color:theme(colors.danger.700)] dark:border-danger-400/75",
info: "from-info-500 to-info-600 [--btn-border-color:theme(colors.info.700)] dark:border-info-400/75",
success:
"from-success-500 to-success-600 [--btn-border-color:theme(colors.success.700)] dark:border-success-400/75",
warning:
"from-warning-400 to-warning-500 text-warning-950 [--btn-border-color:theme(colors.warning.600)] dark:border-warning-300",
gray: "from-gray-500 to-gray-600 [--btn-border-color:theme(colors.gray.700)] dark:border-gray-500",
neutral:
"bg-gray-900 [background-image:radial-gradient(76%_151%_at_52%_-52%,rgba(255,255,255,0.5)_0%,transparent_100%)] [box-shadow:rgba(255,255,255,0.3)_0px_1px_0px_0px_inset,theme(colors.gray.950)_0px_0px_0px_1px] hover:brightness-125 dark:bg-white dark:text-gray-950 dark:border-gray-300",
},
},
});
const outlined = tv({
extend: baseButton,
base: "[--outline-radial-opacity:0.6] dark:[background-image:none] [--inner-border-color:1] dark:[--inner-border-color:0] dark:[--outline-radial-opacity:0.2] [background-image:radial-gradient(76%_151%_at_52%_-52%,rgba(255,255,255,var(--outline-radial-opacity))_0%,transparent_100%)] [box-shadow:rgba(255,255,255,var(--inner-border-color))_0px_1px_0px_0px_inset,var(--btn-border-color)_0px_0px_0px_1px,0px_1px_2px_rgba(0,0,0,0.1)] hover:brightness-[0.98] active:brightness-100 transtion-[filter] ease-in-out duration-150",
variants: {
intent: {
primary:
"[--btn-border-color:theme(colors.primary.200)] dark:[--btn-border-color:theme(colors.primary.500/0.3)] text-primary-800 bg-primary-50 dark:text-primary-300 dark:bg-primary-500/5 dark:hover:bg-primary-500/10 dark:active:bg-primary-500/5",
secondary:
"[--btn-border-color:theme(colors.secondary.200)] dark:[--btn-border-color:theme(colors.secondary.500/0.3)] text-secondary-800 bg-secondary-50 dark:text-secondary-300 dark:bg-secondary-500/5 dark:hover:bg-secondary-500/10 dark:active:bg-secondary-500/5",
accent: "[--btn-border-color:theme(colors.accent.200)] dark:[--btn-border-color:theme(colors.accent.500/0.3)] text-accent-800 bg-accent-50 dark:text-accent-300 dark:bg-accent-500/5 dark:hover:bg-accent-500/10 dark:active:bg-accent-500/5",
danger: "[--btn-border-color:theme(colors.danger.200)] dark:[--btn-border-color:theme(colors.danger.500/0.3)] text-danger-800 bg-danger-50 dark:text-danger-300 dark:bg-danger-500/5 dark:hover:bg-danger-500/10 dark:active:bg-danger-500/5",
info: "[--btn-border-color:theme(colors.info.200)] dark:[--btn-border-color:theme(colors.info.500/0.3)] text-info-800 bg-info-50 dark:text-info-300 dark:bg-info-500/5 dark:hover:bg-info-500/10 dark:active:bg-info-500/5",
success:
"[--btn-border-color:theme(colors.success.200)] dark:[--btn-border-color:theme(colors.success.500/0.3)] text-success-800 bg-success-100 dark:text-success-300 dark:bg-success-500/5 dark:hover:bg-success-500/10 dark:active:bg-success-500/5",
warning:
"[--btn-border-color:theme(colors.warning.200)] dark:[--btn-border-color:theme(colors.warning.500/0.3)] text-warning-800 bg-warning-50 dark:text-warning-300 dark:bg-warning-500/5 dark:hover:bg-warning-500/10 dark:active:bg-warning-500/5",
gray: "[--btn-border-color:theme(colors.gray.200)] dark:[--btn-border-color:theme(colors.gray.500/0.3)] text-gray-800 bg-gray-50 dark:text-gray-300 dark:bg-gray-500/5 dark:hover:bg-gray-500/10 dark:active:bg-gray-500/5",
neutral:
"[--btn-border-color:theme(colors.gray.300)] dark:[--btn-border-color:theme(colors.gray.700)] text-gray-800 bg-gray-100 dark:text-white dark:bg-gray-500/5 dark:hover:bg-gray-500/10 dark:active:bg-gray-500/5",
},
},
});
const soft = tv({
extend: baseButton,
variants: {
intent: {
primary:
"text-primary-700 bg-primary-100 hover:bg-primary-200/75 active:bg-primary-100 dark:text-primary-300 dark:bg-primary-500/10 dark:hover:bg-primary-500/15 dark:active:bg-primary-500/10",
secondary:
"text-secondary-700 bg-secondary-100 hover:bg-secondary-200/75 active:bg-secondary-100 dark:text-secondary-300 dark:bg-secondary-500/10 dark:hover:bg-secondary-500/15 dark:active:bg-secondary-500/10",
accent: "text-accent-700 bg-accent-100 hover:bg-accent-200/75 active:bg-accent-100 dark:text-accent-300 dark:bg-accent-500/10 dark:hover:bg-accent-500/15 dark:active:bg-accent-500/10",
danger: "text-danger-700 bg-danger-100 hover:bg-danger-200/75 active:bg-danger-100 dark:text-danger-300 dark:bg-danger-500/10 dark:hover:bg-danger-500/15 dark:active:bg-danger-500/10",
info: "text-info-700 bg-info-100 hover:bg-info-200/75 active:bg-info-100 dark:text-info-300 dark:bg-info-500/10 dark:hover:bg-info-500/15 dark:active:bg-info-500/10",
success:
"text-success-700 bg-success-100 hover:bg-success-200/75 active:bg-success-100 dark:text-success-300 dark:bg-success-500/10 dark:hover:bg-success-500/15 dark:active:bg-success-500/10",
warning:
"text-warning-700 bg-warning-100 hover:bg-warning-200/75 active:bg-warning-100 dark:text-warning-300 dark:bg-warning-500/10 dark:hover:bg-warning-500/15 dark:active:bg-warning-500/10",
gray: "text-gray-800 bg-gray-100 hover:bg-gray-200/75 active:bg-gray-100 dark:text-gray-300 dark:bg-gray-500/10 dark:hover:bg-gray-500/15 dark:active:bg-gray-500/10",
neutral:
"text-gray-950 bg-gray-100 hover:bg-gray-950 hover:text-white active:text-white active:bg-gray-900 dark:text-gray-300 dark:bg-gray-500/10 dark:hover:bg-white dark:hover:text-gray-950 dark:active:bg-gray-200 dark:active:text-gray-950",
},
},
});
const ghost = tv({
extend: baseButton,
variants: {
intent: {
primary:
"hover:bg-gray-100 active:bg-primary-200/75 dark:hover:bg-gray-800 dark:active:bg-primary-500/15",
secondary:
"text-secondary-600 hover:bg-secondary-100 active:bg-secondary-200/75 dark:text-secondary-400 dark:hover:bg-secondary-500/10 dark:active:bg-secondary-500/15",
accent: "text-accent-600 hover:bg-accent-100 active:bg-accent-200/75 dark:text-accent-400 dark:hover:bg-accent-500/10 dark:active:bg-accent-500/15",
danger: "text-danger-600 hover:bg-danger-100 active:bg-danger-200/75 dark:text-danger-400 dark:hover:bg-danger-500/10 dark:active:bg-danger-500/15",
info: "text-info-600 hover:bg-info-100 active:bg-info-200/75 dark:text-info-400 dark:hover:bg-info-500/10 dark:active:bg-info-500/15",
success:
"text-success-600 hover:bg-success-100 active:bg-success-200/75 dark:text-success-400 dark:hover:bg-success-500/10 dark:active:bg-success-500/15",
warning:
"text-warning-600 hover:bg-warning-100 active:bg-warning-200/75 dark:text-warning-400 dark:hover:bg-warning-500/10 dark:active:bg-warning-500/15",
gray: "text-gray-800 hover:bg-gray-100 active:bg-gray-200/75 dark:text-gray-300 dark:hover:bg-gray-500/10 dark:active:bg-gray-500/15",
neutral:
"text-gray-950 hover:bg-gray-950 hover:text-white active:text-white active:bg-gray-900 dark:text-white dark:hover:bg-white dark:hover:text-gray-950 dark:active:bg-gray-200 dark:active:text-gray-950",
},
},
});
export const buttonIcon = tv({
variants: {
type: {
leading: "-ml-1",
trailing: "-mr-1",
only: "m-auto",
},
size: {
xs: "size-3.5",
sm: "size-4",
md: "size-[1.125rem]",
lg: "size-5",
xl: "size-6",
},
},
});
export const buttonVariants = {
solid,
outlined,
soft,
ghost,
link
};

View File

@@ -0,0 +1,215 @@
import { tv } from "tailwind-variants";
export const form = tv({
slots: {
label: "text-nowrap text-[--title-text-color]",
input: "[--btn-radius:lg] w-full px-[--input-px] bg-transparent peer transition-[outline] placeholder-[--placeholder-text-color] text-[--title-text-color] rounded-[--btn-radius] disabled:opacity-50",
message: "mt-2 text-[--caption-text-color]",
icon: "absolute inset-y-0 my-auto text-[--placeholder-text-color] pointer-events-none",
field: "relative group *:has-[:disabled]:opacity-50 *:has-[:disabled]:pointer-events-none data-[invalid]:[--caption-text-color:theme(colors.danger.600)] dark:data-[invalid]:[--caption-text-color:theme(colors.danger.400)] data-[valid]:[--caption-text-color:theme(colors.success.600)] dark:data-[valid]:[--caption-text-color:theme(colors.success.400)]",
textarea: "py-[calc(var(--input-px)/1.5)] h-auto",
},
variants: {
variant: {
outlined: {
input: "outline-2 focus:outline-primary-600 -outline-offset-1 focus:outline border data-[invalid]:border-danger-600 focus:data-[invalid]:outline-danger-600 dark:data-[invalid]:border-danger-500 dark:focus:data-[invalid]:outline-danger-500 data-[valid]:border-success-600 focus:data-[valid]:outline-success-600 dark:data-[valid]:border-success-500 dark:focus:data-[valid]:outline-success-500",
},
soft: {
input: "outline-none bg-[--ui-soft-bg] focus:brightness-95 dark:focus:brightness-105 data-[invalid]:[--ui-soft-bg:theme(colors.danger.100)] dark:data-[invalid]:[--ui-soft-bg:theme(colors.danger.800/0.25)] data-[valid]:[--ui-soft-bg:theme(colors.success.100)] dark:data-[valid]:[--ui-soft-bg:theme(colors.success.800/0.25)]",
},
mixed: {
input: "placeholder-gray-950/50 dark:placeholder-gray-50/50 shadow-sm hover:shadow-lg dark:hover:shadow-sm shadow-gray-950/50 dark:shadow-gray-50 outline-2 focus:outline-primary-600 focus:outline -outline-offset-1 border border-primary-950 dark:border-primary-50 bg-gray-100 dark:bg-gray-800 data-[invalid]:border-2 data-[invalid]:border-danger-600 focus:data-[invalid]:outline-danger-600 dark:data-[invalid]:border-danger-500 dark:focus:data-[invalid]:outline-danger-500 data-[valid]:border-success-600 focus:data-[valid]:outline-success-600 dark:data-[valid]:border-success-500 dark:focus:data-[valid]:outline-success-500",
},
plain: {
input: "rounded-none px-0 outline-none bg-transparent invalid:text-danger-600 dark:invalid:text-danger-400",
},
bottomOutlined: {
input: "rounded-none transition-[border] px-0 focus:outline-none border-b focus:border-b-2 focus:border-primary-600 data-[invalid]:border-danger-400 dark:data-[invalid]:border-danger-600 data-[valid]:border-success-400 dark:data-[valid]:border-success-600",
},
},
size: {
xs: {
message: "text-xs",
},
sm: {
label: "text-sm",
message: "text-sm",
input: "text-sm h-8 [--input-px:theme(spacing[2.5])]",
field: "[--input-px:theme(spacing[2.5])]",
},
md: {
label: "text-base",
message: "text-base",
input: "text-sm h-9 [--input-px:theme(spacing[3])]",
field: "[--input-px:theme(spacing[3])]",
},
lg: {
label: "text-lg",
input: "text-base h-10 [--input-px:theme(spacing[4])]",
field: "[--input-px:theme(spacing[4])]",
},
xl: {
label: "text-xl",
input: "text-base h-12 [--input-px:theme(spacing[5])]",
field: "[--input-px:theme(spacing[5])]",
},
},
fancy: {
true: {
input: "shadow-inner shadow-gray-950/5 dark:shadow-gray-950/35",
}
},
floating: {
true: {
label: "absolute block inset-y-0 text-base left-[--input-px] h-fit text-nowrap my-auto text-[--caption-text-color] pointer-events-none transition duration-150 scale-[.8] origin-top-left peer-placeholder-shown:scale-100 peer-focus:scale-[.8] peer-placeholder-shown:translate-y-0",
},
},
asTextarea: {
true: {
label: "top-[calc(var(--input-px)/1.5)] mt-0",
},
},
},
compoundVariants: [
{
floating: true,
variant: ["bottomOutlined", "plain"],
class: {
input: "px-0",
label: "left-0",
},
},
{
floating: true,
variant: ["outlined", "soft", "bottomOutlined", "mixed"],
size: "xl",
class: {
field: "[--input-px:theme(spacing[2.5])]",
input: "pt-3.5 h-14",
label: "-translate-y-2.5 peer-focus:-translate-y-2.5",
},
},
{
floating: true,
variant: ["soft", "bottomOutlined"],
size: "lg",
class: {
input: "pt-4 h-12",
label: "-translate-y-2 peer-focus:-translate-y-2",
},
},
{
floating: true,
variant: ["outlined", "mixed"],
size: "lg",
class: {
input: "h-12",
label: "-translate-y-[21.5px] peer-focus:-translate-y-[21.5px]",
},
},
{
floating: true,
variant: ["outlined", "bottomOutlined", "mixed"],
size: "md",
class: {
input: "h-9",
label: "-translate-y-[15.5px] peer-focus:-translate-y-[15.5px]",
},
},
{
floating: true,
variant: ["outlined", "bottomOutlined", "mixed"],
size: "sm",
class: {
input: "h-8",
label: "text-base -translate-y-[13.5px] peer-focus:-translate-y-[13.5px] peer-placeholder-shown:text-sm peer-focus:text-base",
},
},
{
floating: true,
size: ["sm", "md", "lg"],
variant: ["outlined", "mixed"],
class: {
label: "peer-placeholder-shown:before:scale-x-0 peer-focus:before:scale-x-100 before:scale-x-100 before:absolute peer-placeholder-shown:before:transition-none before:transition-none peer-focus:before:transition peer-focus:before:delay-[.01s] before:duration-500 before:-z-[1] peer-placeholder-shown:before:-top-[9px] before:top-[48%] peer-focus:before:top-[44%] before:-inset-x-1 before:h-0.5 before:my-auto group-has-[:focus]:before:h-[3px] before:bg-white dark:before:bg-[--ui-bg]",
},
},
{
floating: true,
variant: ["outlined", "mixed"],
class: {
label: "translate-x-px",
},
},
{
floating: true,
asTextarea: true,
size: ["lg", "xl"],
variant: "bottomOutlined",
class: {
input: "pt-0",
},
},
{
variant: "plain",
class: {
input: "py-0",
},
},
{
floating: true,
asTextarea: true,
size: ["xl"],
class: {
input: "pt-7",
label: "-translate-y-1 peer-focus:-translate-y-1",
},
},
{
floating: true,
asTextarea: true,
size: ["lg"],
class: {
input: "pt-6",
label: "-translate-y-1 peer-focus:-translate-y-1 before:hidden",
},
},
{
floating: true,
asTextarea: true,
size: ["md"],
variant: ["outlined", "bottomOutlined", "mixed"],
class: {
label: "-translate-y-[17.5px] peer-focus:-translate-y-[17.5px]",
},
},
{
floating: true,
asTextarea: true,
size: ["sm"],
variant: ["outlined", "bottomOutlined", "mixed"],
class: {
label: "-translate-y-4 peer-focus:-translate-y-4",
},
},
],
});
export type FormProps = {
variant?: keyof typeof form.variants.variant;
size?: keyof typeof form.variants.size;
floating?: boolean;
asTextarea?: boolean;
};
export type InputProps = Omit<FormProps, "asTextarea"> & {
size?: Exclude<FormProps["size"], "xs">;
fancy?: boolean;
};
export type LabelProps = FormProps & {
size?: Exclude<FormProps["size"], "xs">;
};
export type MessageProps = {
size?: Exclude<FormProps["size"], "lg" | "xl">;
};

View File

@@ -0,0 +1,4 @@
export * from "./button-variants"
export * from "./typography"
export * from "./utils"
export * from "./form"

View File

@@ -0,0 +1,401 @@
import { tv } from "tailwind-variants";
export const base = tv({
variants: {
weight: {
black: "font-black",
bold: "font-bold",
semibold: "font-semibold",
medium: "font-medium",
normal: "font-normal",
},
align: {
left: "text-left",
center: "text-center",
right: "text-right",
},
},
defaultVariants: {
size: "xl",
weight: "normal",
},
});
export const caption = tv(
{
extend: base,
base: "text-gray-500",
variants: {
size: {
xs: "text-xs",
sm: "text-sm",
base: "text-base",
},
neutral: {
true: "text-gray-950 dark:text-white",
},
},
defaultVariants: {
size: "sm",
weight: "normal",
},
},
{
responsiveVariants: ["sm", "md", "lg", "xl", "2xl"],
},
);
export const text = tv(
{
extend: base,
base: "text-gray-700",
variants: {
size: {
sm: "text-sm",
base: "text-base",
lg: "text-lg",
xl: "text-xl",
},
neutral: {
true: "text-gray-950 dark:text-white",
},
},
defaultVariants: {
size: "base",
weight: "normal",
},
},
{
responsiveVariants: ["sm", "md", "lg", "xl", "2xl"],
},
);
export const list = tv(
{
extend: text,
base: "list-outside pl-4",
variants: {
type: {
disc: "list-disc",
decimal: "list-decimal",
none: "list-none",
},
inside: {
true: "list-outside pl-0",
},
},
defaultVariants: {
size: "base",
type: "disc",
weight: "normal",
inside: false,
},
},
{
responsiveVariants: ["sm", "md", "lg", "xl", "2xl"],
},
);
export const link = tv(
{
extend: base,
base: "transition",
variants: {
size: {
xs: "text-xs",
sm: "text-sm",
base: "text-base",
lg: "text-lg",
xl: "text-xl",
},
intent: {
primary:
"text-primary-600 hover:text-primary-700 dark:text-primary-400 dark:hover:text-primary-500",
secondary:
"text-secondary-600 hover:text-secondary-700 dark:text-secondary-400 dark:hover:text-secondary-500",
accent: "text-accent-600 hover:text-accent-700 dark:text-accent-400 dark:hover:text-accent-500",
info: "text-info-600 hover:text-info-700 dark:text-info-400 dark:hover:text-info-500",
danger: "text-danger-600 hover:text-danger-700 dark:text-danger-400 dark:hover:text-danger-500",
success:
"text-success-600 hover:text-success-700 dark:text-success-400 dark:hover:text-success-500",
warning:
"text-warning-700 hover:text-warning-600 dark:text-warning-400 dark:hover:text-warning-500",
gray: "text-gray-700",
neutral:
"text-gray-950 hover:text-gray-800 dark:text-white dark:hover:text-gray-200",
},
variant: {
plain: "",
underlined: "underline",
ghost: "hover:underline",
animated:
"relative before:absolute before:inset-x-0 before:bottom-0 before:h-px before:scale-x-0 before:origin-right hover:before:origin-left hover:before:scale-x-100 before:transition before:duration-200",
},
visited: {
true: "visited:text-accent-600 dark:visited:text-accent-400",
},
},
compoundVariants: [
{
variant: ["plain", "ghost", "underlined"],
intent: "gray",
class: "hover:text-gray-950 dark:hover:text-white",
},
{
variant: "animated",
intent: "primary",
class: "before:bg-primary-600/50 dark:before:bg-primary-400/50",
},
{
variant: "animated",
intent: "info",
class: "before:bg-info-600/50 dark:before:bg-info-400/50",
},
{
variant: "animated",
intent: "neutral",
class: "before:bg-gray-950/50 dark:before:bg-white/50",
},
{
variant: "animated",
intent: "gray",
class: "before:bg-gray-600/50 dark:before:bg-gray-400/50",
},
{
variant: "animated",
intent: "secondary",
class: "before:bg-secondary-600/50 dark:before:bg-secondary-400/50",
},
{
variant: "animated",
intent: "accent",
class: "before:bg-accent-600/50 dark:before:bg-accent-400/50",
},
{
variant: "animated",
intent: "danger",
class: "before:bg-danger-600/50 dark:before:bg-danger-400/50",
},
{
variant: "animated",
intent: "success",
class: "before:bg-success-600/50 dark:before:bg-success-400/50",
},
{
variant: "animated",
intent: "warning",
class: "before:bg-warning-600/50 dark:before:bg-warning-400/50",
},
{
variant: "underlined",
intent: "primary",
class: "decoration-primary-600/50 dark:decoration-primary-400/50",
},
{
variant: "underlined",
intent: "info",
class: "decoration-info-600/50 dark:decoration-info-400/50",
},
{
variant: "underlined",
intent: "gray",
class: "decoration-gray-600/50 dark:decoration-gray-400/50",
},
{
variant: "underlined",
intent: "neutral",
class: "decoration-gray-950/25 dark:decoration-white/25",
},
{
variant: "underlined",
intent: "secondary",
class: "decoration-secondary-600/50 dark:decoration-secondary-400/50",
},
{
variant: "underlined",
intent: "accent",
class: "decoration-accent-600/50 dark:decoration-accent-400/50",
},
{
variant: "underlined",
intent: "danger",
class: "decoration-danger-600/50 dark:decoration-danger-400/50",
},
{
variant: "underlined",
intent: "success",
class: "decoration-success-600/50 dark:decoration-success-400/50",
},
{
variant: "underlined",
intent: "warning",
class: "decoration-warning-600/50 dark:decoration-warning-400/50",
},
],
defaultVariants: {
intent: "primary",
variant: "ghost",
size: "base",
},
},
{
responsiveVariants: ["sm", "md", "lg", "xl", "2xl"],
},
);
export const display = tv(
{
extend: base,
base: "block text-gray-950 dark:text-gray-50",
variants: {
size: {
"4xl": "text-4xl",
"5xl": "text-5xl",
"6xl": "text-6xl",
"7xl": "text-7xl",
"8xl": "text-8xl",
"9xl": "text-9xl",
},
},
defaultVariants: {
size: "6xl",
weight: "bold",
},
},
{
responsiveVariants: ["sm", "md", "lg", "xl", "2xl"],
},
);
export const title = tv(
{
extend: base,
base: "block text-gray-950",
variants: {
size: {
base: "text-base",
lg: "text-lg",
xl: "text-xl",
"2xl": "text-2xl",
"3xl": "text-3xl",
},
},
defaultVariants: {
size: "xl",
weight: "semibold",
},
},
{
responsiveVariants: ["sm", "md", "lg", "xl", "2xl"],
},
);
export const codeTheme = tv({
base: "text-sm inline-block border rounded-md py-px px-1",
variants: {
intent: {
primary:
"bg-primary-50 text-primary-600 dark:text-primary-300 border-primary-200 dark:border-primary-500/20 dark:bg-primary-500/5",
secondary:
"bg-secondary-50 text-secondary-600 dark:text-secondary-300 border-secondary-200 dark:border-secondary-500/20 dark:bg-secondary-500/5",
accent: "bg-accent-50 text-accent-600 dark:text-accent-300 border-accent-200 dark:border-accent-500/20 dark:bg-accent-500/5",
gray: "bg-gray-50 text-gray-700 dark:border-gray-500/20 dark:bg-gray-500/5 dark:border-gray-500/20",
neutral: "bg-gray-50 text-gray-950 dark:text-white dark:bg-gray-500/5 dark:border-gray-500/20",
},
},
defaultVariants: {
intent: "gray",
},
});
export const kbdTheme = tv({
base: "inline-flex items-center justify-center text-gray-800 dark:text-white h-5 text-[11px] min-w-5 px-1.5 rounded font-sans bg-gray-100 dark:bg-white/10 ring-1 border-b border-t border-t-white border-b-gray-200 dark:border-t-transparent dark:border-b-gray-950 ring-gray-300 dark:ring-white/15",
});
export type CodeThemeProps = {
intent?: keyof typeof codeTheme.variants.intent;
};
export type Weight = keyof typeof base.variants.weight;
export type Align = keyof typeof base.variants.align;
type BaseTextProps = {
weight?: Weight;
align?: Align;
};
export type CaptionProps = BaseTextProps & {
size?: keyof typeof caption.variants.size;
neutral?: boolean;
};
export type TextProps = BaseTextProps & {
size?: keyof typeof text.variants.size;
neutral?: boolean;
};
export type ListProps = BaseTextProps & {
size?: keyof typeof text.variants.size;
type?: keyof typeof list.variants.type;
inside?: boolean;
neutral?: boolean;
};
export type LinkProps = BaseTextProps & {
size?: keyof typeof text.variants.size | keyof typeof link.variants.size;
variant?: keyof typeof link.variants.variant;
intent?: keyof typeof link.variants.intent;
visited?: boolean;
};
export type TitleProps = BaseTextProps & {
size?: keyof typeof title.variants.size;
};
export type TitleSizeProp =
| TitleProps["size"]
| {
initial?: TitleProps["size"];
sm?: TitleProps["size"];
md?: TitleProps["size"];
lg?: TitleProps["size"];
xl?: TitleProps["size"];
xxl?: TitleProps["size"];
};
export type TextSizeProp =
| TextProps["size"]
| {
initial?: TextProps["size"];
sm?: TextProps["size"];
md?: TextProps["size"];
lg?: TextProps["size"];
xl?: TextProps["size"];
xxl?: TextProps["size"];
};
export type DisplayProps = BaseTextProps & {
size?: keyof typeof display.variants.size;
};
export type TextWeightProp =
| Weight
| {
initial?: Weight;
sm?: Weight;
md?: Weight;
lg?: Weight;
xl?: Weight;
xxl?: Weight;
};
export type TextAlignProp =
| Align
| {
initial?: Align;
sm?: Align;
md?: Align;
lg?: Align;
xl?: Align;
xxl?: Align;
};

View File

@@ -0,0 +1,6 @@
import { type ClassValue, clsx } from "clsx"
import { twMerge } from "tailwind-merge"
export function cn(...inputs: ClassValue[]) {
return twMerge(clsx(inputs))
}