1 Commits

Author SHA1 Message Date
eb14f9fa37 fix(deps): update dependency recharts to v3
Some checks failed
renovate/stability-days Updates have met minimum release age requirement
Lint / Lint and Typecheck (push) Failing after 28s
Lint / Lint and Typecheck (pull_request) Failing after 22s
2025-11-15 02:03:43 +00:00
18 changed files with 754 additions and 993 deletions

View File

@@ -13,7 +13,7 @@ jobs:
steps: steps:
- name: Checkout code - name: Checkout code
uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5 uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5
- name: Install pnpm - name: Install pnpm
uses: pnpm/action-setup@41ff72655975bd51cab0327fa583b6e92b6d3061 # v4 uses: pnpm/action-setup@41ff72655975bd51cab0327fa583b6e92b6d3061 # v4
@@ -27,5 +27,5 @@ jobs:
- name: Install dependencies - name: Install dependencies
run: pnpm install run: pnpm install
- name: Run lint - name: Run check
run: pnpm run lint run: pnpm run check

View File

@@ -1,6 +0,0 @@
{
"tabWidth": 2,
"singleQuote": true,
"printWidth": 105,
"plugins": ["prettier-plugin-tailwindcss"]
}

48
eslint.config.js Normal file
View File

@@ -0,0 +1,48 @@
import { FlatCompat } from "@eslint/eslintrc";
import tseslint from "typescript-eslint";
const compat = new FlatCompat({
baseDirectory: import.meta.dirname,
});
export default tseslint.config(
{
ignores: [".next"],
},
...compat.extends("next/core-web-vitals"),
{
files: ["**/*.ts", "**/*.tsx"],
extends: [
...tseslint.configs.recommended,
...tseslint.configs.recommendedTypeChecked,
...tseslint.configs.stylisticTypeChecked,
],
rules: {
"@typescript-eslint/array-type": "off",
"@typescript-eslint/consistent-type-definitions": "off",
"@typescript-eslint/consistent-type-imports": [
"warn",
{ prefer: "type-imports", fixStyle: "inline-type-imports" },
],
"@typescript-eslint/no-unused-vars": [
"warn",
{ argsIgnorePattern: "^_" },
],
"@typescript-eslint/require-await": "off",
"@typescript-eslint/no-misused-promises": [
"error",
{ checksVoidReturn: { attributes: false } },
],
},
},
{
linterOptions: {
reportUnusedDisableDirectives: true,
},
languageOptions: {
parserOptions: {
projectService: true,
},
},
},
);

View File

@@ -1,37 +0,0 @@
// @ts-check
import { defineConfig, globalIgnores } from "eslint/config";
import nextVitals from "eslint-config-next/core-web-vitals";
import nextTs from "eslint-config-next/typescript";
import tseslint from "typescript-eslint";
const eslintConfig = defineConfig([
// Next.js core-web-vitals and TypeScript configs
...nextVitals,
...nextTs,
// Add strict TypeScript rules on top
...tseslint.configs.strictTypeChecked,
...tseslint.configs.stylisticTypeChecked,
// Configure TypeScript parser options
{
files: ["**/*.{ts,tsx}"],
languageOptions: {
parserOptions: {
projectService: true,
tsconfigRootDir: import.meta.dirname,
},
},
},
// Override default ignores of eslint-config-next
globalIgnores([
// Default ignores of eslint-config-next:
".next/**",
"out/**",
"build/**",
"next-env.d.ts",
// Additional ignores:
"*.mjs",
"tailwind.config.ts",
]),
]);
export default eslintConfig;

View File

@@ -2,7 +2,7 @@
* Run `build` or `dev` with `SKIP_ENV_VALIDATION` to skip env validation. This is especially useful * Run `build` or `dev` with `SKIP_ENV_VALIDATION` to skip env validation. This is especially useful
* for Docker builds. * for Docker builds.
*/ */
import './src/env.ts'; import "./src/env.js";
/** @type {import("next").NextConfig} */ /** @type {import("next").NextConfig} */
const config = {}; const config = {};

View File

@@ -9,7 +9,7 @@
"dev": "next dev --turbopack", "dev": "next dev --turbopack",
"format:check": "prettier --check \"**/*.{ts,tsx,js,jsx,mdx}\" --cache", "format:check": "prettier --check \"**/*.{ts,tsx,js,jsx,mdx}\" --cache",
"format:write": "prettier --write \"**/*.{ts,tsx,js,jsx,mdx}\" --cache", "format:write": "prettier --write \"**/*.{ts,tsx,js,jsx,mdx}\" --cache",
"lint": "next typegen && eslint . && npx tsc --noEmit", "lint:fix": "next lint --fix",
"preview": "next build && next start", "preview": "next build && next start",
"start": "next start" "start": "next start"
}, },
@@ -24,39 +24,34 @@
"class-variance-authority": "^0.7.1", "class-variance-authority": "^0.7.1",
"clsx": "^2.1.1", "clsx": "^2.1.1",
"lucide-react": "^0.553.0", "lucide-react": "^0.553.0",
"next": "16.0.3", "next": "^15.4.1",
"next-plausible": "^3.12.4", "next-plausible": "^3.12.4",
"react": "19.2.0", "react": "^19.0.0",
"react-dom": "19.2.0", "react-dom": "^19.0.0",
"react-hook-form": "^7.56.1", "react-hook-form": "^7.56.1",
"recharts": "^3.0.0", "recharts": "^3.0.0",
"tailwind-merge": "^3.2.0", "tailwind-merge": "^3.2.0",
"zod": "^4.0.0" "zod": "^4.0.0"
}, },
"devDependencies": { "devDependencies": {
"@eslint/eslintrc": "3.3.1",
"@tailwindcss/postcss": "4.1.17", "@tailwindcss/postcss": "4.1.17",
"@types/node": "24.10.1", "@types/node": "24.10.1",
"@types/react": "19.2.6", "@types/react": "19.2.3",
"@types/react-dom": "19.2.3", "@types/react-dom": "19.2.2",
"eslint": "9.39.1", "eslint": "9.39.1",
"eslint-config-next": "16.0.3", "eslint-config-next": "15.5.6",
"eslint-config-prettier": "^10.1.8", "eslint-plugin-react-hooks": "5.2.0",
"postcss": "8.5.6", "postcss": "8.5.6",
"prettier": "3.6.2", "prettier": "3.6.2",
"prettier-plugin-tailwindcss": "0.7.1", "prettier-plugin-tailwindcss": "0.7.1",
"tailwindcss": "4.1.17", "tailwindcss": "4.1.17",
"tw-animate-css": "1.4.0", "tw-animate-css": "1.4.0",
"typescript": "5.9.3", "typescript": "5.9.3",
"typescript-eslint": "8.47.0" "typescript-eslint": "8.46.3"
}, },
"ct3aMetadata": { "ct3aMetadata": {
"initVersion": "7.39.3" "initVersion": "7.39.3"
}, },
"packageManager": "pnpm@10.22.0", "packageManager": "pnpm@10.20.0"
"pnpm": {
"overrides": {
"@types/react": "19.2.6",
"@types/react-dom": "19.2.3"
}
}
} }

1454
pnpm-lock.yaml generated

File diff suppressed because it is too large Load Diff

4
prettier.config.js Normal file
View File

@@ -0,0 +1,4 @@
/** @type {import('prettier').Config & import('prettier-plugin-tailwindcss').PluginOptions} */
export default {
plugins: ["prettier-plugin-tailwindcss"],
};

View File

@@ -1,6 +1,5 @@
"use client"; "use client";
import { useState, useEffect } from "react"; import { useState, useEffect } from "react";
import type React from "react";
import { import {
type LucideIcon, type LucideIcon,
HandCoins, HandCoins,
@@ -113,49 +112,46 @@ export default function MultiIconPattern({ opacity = 0.2, spacing = 160 }) {
Target, Target,
]; ];
const [icons, setIcons] = useState<React.ReactElement[]>([]); const renderIcons = ({
rows,
useEffect(() => { columns,
if (rows === 0 || columns === 0) { }: {
setIcons([]); rows: number;
return; columns: number;
} }) => {
const icons = [];
const iconElements: React.ReactElement[] = [];
for (let y = 0; y < rows; y++) { for (let y = 0; y < rows; y++) {
for (let x = 0; x < columns; x++) { for (let x = 0; x < columns; x++) {
// Pick a random icon component from the array // Pick a random icon component from the array
const randomIndex = Math.floor(Math.random() * iconComponents.length); const randomIndex = Math.floor(Math.random() * iconComponents.length);
const IconComponent = iconComponents[randomIndex]; const IconComponent = iconComponents[randomIndex]!;
// Slightly randomize size and position for more organic feel // Slightly randomize size and position for more organic feel
const size = 28 + Math.floor(Math.random() * 8); const size = 28 + Math.floor(Math.random() * 8);
const xOffset = Math.floor(Math.random() * (spacing / 1.618)); const xOffset = Math.floor(Math.random() * (spacing / 1.618));
const yOffset = Math.floor(Math.random() * (spacing / 1.618)); const yOffset = Math.floor(Math.random() * (spacing / 1.618));
const rotation = Math.round((Math.random() - 0.5) * 30);
iconElements.push( icons.push(
<IconComponent <IconComponent
key={`icon-${String(x)}-${String(y)}`} key={`icon-${x}-${y}`}
size={size} size={size}
className="text-primary fixed" className="text-primary fixed"
style={{ style={{
left: `${String(x * spacing + xOffset)}px`, left: `${x * spacing + xOffset}px`,
top: `${String(y * spacing + yOffset)}px`, top: `${y * spacing + yOffset}px`,
opacity: opacity, opacity: opacity,
transform: `rotate(${String(rotation)}deg)`, transform: `rotate(${Math.round((Math.random() - 0.5) * 30)}deg)`,
}} }}
/>, />,
); );
} }
} }
setIcons(iconElements); return icons;
// eslint-disable-next-line react-hooks/exhaustive-deps };
}, [rows, columns, spacing, opacity]);
return ( return (
<div className="absolute h-full w-full"> <div className="absolute h-full w-full">
{width > 0 && icons} {width > 0 && renderIcons({ rows, columns })}
</div> </div>
); );
} }

View File

@@ -216,7 +216,7 @@ export default function FireCalculatorForm() {
return [0, 0]; return [0, 0];
})(); })();
if (retirementIndex === -1) { if (retirementIndex === -1 || !retirementData) {
setResult({ setResult({
fireNumber: null, fireNumber: null,
fireNumber4percent: null, fireNumber4percent: null,
@@ -246,13 +246,7 @@ export default function FireCalculatorForm() {
</CardHeader> </CardHeader>
<CardContent> <CardContent>
<Form {...form}> <Form {...form}>
<form <form onSubmit={form.handleSubmit(onSubmit)} className="space-y-8">
onSubmit={(e) => {
e.preventDefault();
void form.handleSubmit(onSubmit)(e);
}}
className="space-y-8"
>
<div className="grid grid-cols-1 gap-6 md:grid-cols-2"> <div className="grid grid-cols-1 gap-6 md:grid-cols-2">
<FormField <FormField
control={form.control} control={form.control}
@@ -271,8 +265,7 @@ export default function FireCalculatorForm() {
? undefined ? undefined
: Number(e.target.value), : Number(e.target.value),
); );
// eslint-disable-next-line @typescript-eslint/no-floating-promises void form.handleSubmit(onSubmit)();
form.handleSubmit(onSubmit)();
}} }}
onBlur={field.onBlur} onBlur={field.onBlur}
name={field.name} name={field.name}
@@ -300,8 +293,7 @@ export default function FireCalculatorForm() {
? undefined ? undefined
: Number(e.target.value), : Number(e.target.value),
); );
// eslint-disable-next-line @typescript-eslint/no-floating-promises void form.handleSubmit(onSubmit)();
form.handleSubmit(onSubmit)();
}} }}
onBlur={field.onBlur} onBlur={field.onBlur}
name={field.name} name={field.name}
@@ -329,8 +321,7 @@ export default function FireCalculatorForm() {
? undefined ? undefined
: Number(e.target.value), : Number(e.target.value),
); );
// eslint-disable-next-line @typescript-eslint/no-floating-promises void form.handleSubmit(onSubmit)();
form.handleSubmit(onSubmit)();
}} }}
onBlur={field.onBlur} onBlur={field.onBlur}
name={field.name} name={field.name}
@@ -358,8 +349,7 @@ export default function FireCalculatorForm() {
? undefined ? undefined
: Number(e.target.value), : Number(e.target.value),
); );
// eslint-disable-next-line @typescript-eslint/no-floating-promises void form.handleSubmit(onSubmit)();
form.handleSubmit(onSubmit)();
}} }}
onBlur={field.onBlur} onBlur={field.onBlur}
name={field.name} name={field.name}
@@ -388,8 +378,7 @@ export default function FireCalculatorForm() {
? undefined ? undefined
: Number(e.target.value), : Number(e.target.value),
); );
// eslint-disable-next-line @typescript-eslint/no-floating-promises void form.handleSubmit(onSubmit)();
form.handleSubmit(onSubmit)();
}} }}
onBlur={field.onBlur} onBlur={field.onBlur}
name={field.name} name={field.name}
@@ -418,8 +407,7 @@ export default function FireCalculatorForm() {
? undefined ? undefined
: Number(e.target.value), : Number(e.target.value),
); );
// eslint-disable-next-line @typescript-eslint/no-floating-promises void form.handleSubmit(onSubmit)();
form.handleSubmit(onSubmit)();
}} }}
onBlur={field.onBlur} onBlur={field.onBlur}
name={field.name} name={field.name}
@@ -449,8 +437,7 @@ export default function FireCalculatorForm() {
? undefined ? undefined
: Number(e.target.value), : Number(e.target.value),
); );
// eslint-disable-next-line @typescript-eslint/no-floating-promises void form.handleSubmit(onSubmit)();
form.handleSubmit(onSubmit)();
}} }}
onBlur={field.onBlur} onBlur={field.onBlur}
name={field.name} name={field.name}
@@ -480,8 +467,7 @@ export default function FireCalculatorForm() {
step={1} step={1}
onValueChange={(value: number[]) => { onValueChange={(value: number[]) => {
field.onChange(value[0]); field.onChange(value[0]);
// eslint-disable-next-line @typescript-eslint/no-floating-promises void form.handleSubmit(onSubmit)();
form.handleSubmit(onSubmit)();
}} }}
className="py-4" className="py-4"
/> />
@@ -662,7 +648,7 @@ export default function FireCalculatorForm() {
)} )}
{result && ( {result && (
<Button <Button
onClick={() => { setShowing4percent(!showing4percent); }} onClick={() => setShowing4percent(!showing4percent)}
variant={showing4percent ? "secondary" : "default"} variant={showing4percent ? "secondary" : "default"}
size={"sm"} size={"sm"}
> >

View File

@@ -66,7 +66,7 @@ export default function HomePage() {
}; };
return ( return (
<main className="text-primary-foreground to-destructive from-secondary flex min-h-screen flex-col items-center bg-linear-to-b p-2"> <main className="text-primary-foreground to-destructive from-secondary flex min-h-screen flex-col items-center bg-gradient-to-b p-2">
<BackgroundPattern /> <BackgroundPattern />
<div className="z-10 mx-auto flex flex-col items-center justify-center gap-4 text-center"> <div className="z-10 mx-auto flex flex-col items-center justify-center gap-4 text-center">
<div className="mt-8 flex flex-row flex-wrap items-center justify-center gap-4 align-middle"> <div className="mt-8 flex flex-row flex-wrap items-center justify-center gap-4 align-middle">
@@ -78,7 +78,7 @@ export default function HomePage() {
width={100} width={100}
height={100} height={100}
/> />
<h1 className="from-primary via-primary-foreground to-primary bg-linear-to-r bg-clip-text text-5xl font-extrabold tracking-tight text-transparent drop-shadow-md sm:text-[5rem]"> <h1 className="from-primary via-primary-foreground to-primary bg-gradient-to-r bg-clip-text text-5xl font-extrabold tracking-tight text-transparent drop-shadow-md sm:text-[5rem]">
InvestingFIRE InvestingFIRE
</h1> </h1>
</div> </div>

View File

@@ -20,9 +20,9 @@ export type ChartConfig = Record<
) )
>; >;
interface ChartContextProps { type ChartContextProps = {
config: ChartConfig; config: ChartConfig;
} };
const ChartContext = React.createContext<ChartContextProps | null>(null); const ChartContext = React.createContext<ChartContextProps | null>(null);
@@ -135,12 +135,12 @@ function ChartTooltipContent({
return null; return null;
} }
const item = payload[0]; const [item] = payload;
const key = labelKey ?? String(item.dataKey ?? item.name ?? "value"); const key = `${labelKey ?? item?.dataKey ?? item?.name ?? "value"}`;
const itemConfig = getPayloadConfigFromPayload(config, item, key); const itemConfig = getPayloadConfigFromPayload(config, item, key);
const value = const value =
!labelKey && typeof label === "string" !labelKey && typeof label === "string"
? (label in config && config[label].label ? config[label].label : undefined) ?? label ? (config[label]?.label ?? label)
: itemConfig?.label; : itemConfig?.label;
if (labelFormatter) { if (labelFormatter) {
@@ -175,14 +175,14 @@ function ChartTooltipContent({
return ( return (
<div <div
className={cn( className={cn(
"border-border/50 bg-background grid min-w-32 items-start gap-1.5 rounded-lg border px-2.5 py-1.5 text-xs shadow-xl", "border-border/50 bg-background grid min-w-[8rem] items-start gap-1.5 rounded-lg border px-2.5 py-1.5 text-xs shadow-xl",
className, className,
)} )}
> >
{!nestLabel ? tooltipLabel : null} {!nestLabel ? tooltipLabel : null}
<div className="grid gap-1.5"> <div className="grid gap-1.5">
{payload.map((item, index) => { {payload.map((item, index) => {
const key = nameKey ?? String(item.name ?? item.dataKey ?? "value"); const key = `${nameKey ?? item.name ?? item.dataKey ?? "value"}`;
const itemConfig = getPayloadConfigFromPayload(config, item, key); const itemConfig = getPayloadConfigFromPayload(config, item, key);
const indicatorColor: string | undefined = const indicatorColor: string | undefined =
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
@@ -196,7 +196,7 @@ function ChartTooltipContent({
indicator === "dot" && "items-center", indicator === "dot" && "items-center",
)} )}
> >
{formatter && item.value !== undefined && item.name ? ( {formatter && item?.value !== undefined && item.name ? (
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument // eslint-disable-next-line @typescript-eslint/no-unsafe-argument
formatter(item.value, item.name, item, index, item.payload) formatter(item.value, item.name, item, index, item.payload)
) : ( ) : (
@@ -207,7 +207,7 @@ function ChartTooltipContent({
!hideIndicator && ( !hideIndicator && (
<div <div
className={cn( className={cn(
"shrink-0 rounded-[2px] border-border bg-(--color-bg)", "shrink-0 rounded-[2px] border-(--color-border) bg-(--color-bg)",
{ {
"h-2.5 w-2.5": indicator === "dot", "h-2.5 w-2.5": indicator === "dot",
"w-1": indicator === "line", "w-1": indicator === "line",

View File

@@ -18,12 +18,12 @@ import { Label } from "@/components/ui/label";
const Form = FormProvider; const Form = FormProvider;
interface FormFieldContextValue< type FormFieldContextValue<
TFieldValues extends FieldValues = FieldValues, TFieldValues extends FieldValues = FieldValues,
TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>, TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>,
> { > = {
name: TName; name: TName;
} };
const FormFieldContext = React.createContext<FormFieldContextValue>( const FormFieldContext = React.createContext<FormFieldContextValue>(
{} as FormFieldContextValue, {} as FormFieldContextValue,
@@ -61,9 +61,9 @@ const useFormField = () => {
}; };
}; };
interface FormItemContextValue { type FormItemContextValue = {
id: string; id: string;
} };
const FormItemContext = React.createContext<FormItemContextValue>( const FormItemContext = React.createContext<FormItemContextValue>(
{} as FormItemContextValue, {} as FormItemContextValue,
@@ -110,7 +110,7 @@ function FormControl({ ...props }: React.ComponentProps<typeof Slot>) {
id={formItemId} id={formItemId}
aria-describedby={ aria-describedby={
!error !error
? formDescriptionId ? `${formDescriptionId}`
: `${formDescriptionId} ${formMessageId}` : `${formDescriptionId} ${formMessageId}`
} }
aria-invalid={!!error} aria-invalid={!!error}
@@ -134,7 +134,7 @@ function FormDescription({ className, ...props }: React.ComponentProps<"p">) {
function FormMessage({ className, ...props }: React.ComponentProps<"p">) { function FormMessage({ className, ...props }: React.ComponentProps<"p">) {
const { error, formMessageId } = useFormField(); const { error, formMessageId } = useFormField();
const body = error ? (error.message ?? "") : props.children; const body = error ? String(error?.message ?? "") : props.children;
if (!body) { if (!body) {
return null; return null;

View File

@@ -37,7 +37,7 @@ function SelectTrigger({
data-slot="select-trigger" data-slot="select-trigger"
data-size={size} data-size={size}
className={cn( className={cn(
"border-input data-placeholder:text-muted-foreground [&_svg:not([class*='text-'])]:text-muted-foreground focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:bg-input/30 dark:hover:bg-input/50 flex w-fit items-center justify-between gap-2 rounded-md border bg-transparent px-3 py-2 text-sm whitespace-nowrap shadow-xs transition-[color,box-shadow] outline-none focus-visible:ring-[3px] disabled:cursor-not-allowed disabled:opacity-50 data-[size=default]:h-9 data-[size=sm]:h-8 *:data-[slot=select-value]:line-clamp-1 *:data-[slot=select-value]:flex *:data-[slot=select-value]:items-center *:data-[slot=select-value]:gap-2 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4", "border-input data-[placeholder]:text-muted-foreground [&_svg:not([class*='text-'])]:text-muted-foreground focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:bg-input/30 dark:hover:bg-input/50 flex w-fit items-center justify-between gap-2 rounded-md border bg-transparent px-3 py-2 text-sm whitespace-nowrap shadow-xs transition-[color,box-shadow] outline-none focus-visible:ring-[3px] disabled:cursor-not-allowed disabled:opacity-50 data-[size=default]:h-9 data-[size=sm]:h-8 *:data-[slot=select-value]:line-clamp-1 *:data-[slot=select-value]:flex *:data-[slot=select-value]:items-center *:data-[slot=select-value]:gap-2 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
className, className,
)} )}
{...props} {...props}
@@ -61,7 +61,7 @@ function SelectContent({
<SelectPrimitive.Content <SelectPrimitive.Content
data-slot="select-content" data-slot="select-content"
className={cn( className={cn(
"bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 relative z-50 max-h-(--radix-select-content-available-height) min-w-32 origin-(--radix-select-content-transform-origin) overflow-x-hidden overflow-y-auto rounded-md border shadow-md", "bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 relative z-50 max-h-(--radix-select-content-available-height) min-w-[8rem] origin-(--radix-select-content-transform-origin) overflow-x-hidden overflow-y-auto rounded-md border shadow-md",
position === "popper" && position === "popper" &&
"data-[side=bottom]:translate-y-1 data-[side=left]:-translate-x-1 data-[side=right]:translate-x-1 data-[side=top]:-translate-y-1", "data-[side=bottom]:translate-y-1 data-[side=left]:-translate-x-1 data-[side=right]:translate-x-1 data-[side=top]:-translate-y-1",
className, className,
@@ -74,7 +74,7 @@ function SelectContent({
className={cn( className={cn(
"p-1", "p-1",
position === "popper" && position === "popper" &&
"h-(--radix-select-trigger-height) w-full min-w-(--radix-select-trigger-width) scroll-my-1", "h-[var(--radix-select-trigger-height)] w-full min-w-[var(--radix-select-trigger-width)] scroll-my-1",
)} )}
> >
{children} {children}
@@ -107,7 +107,7 @@ function SelectItem({
<SelectPrimitive.Item <SelectPrimitive.Item
data-slot="select-item" data-slot="select-item"
className={cn( className={cn(
"focus:bg-accent focus:text-accent-foreground [&_svg:not([class*='text-'])]:text-muted-foreground relative flex w-full cursor-default items-center gap-2 rounded-sm py-1.5 pr-8 pl-2 text-sm outline-hidden select-none data-disabled:pointer-events-none data-disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4 *:[span]:last:flex *:[span]:last:items-center *:[span]:last:gap-2", "focus:bg-accent focus:text-accent-foreground [&_svg:not([class*='text-'])]:text-muted-foreground relative flex w-full cursor-default items-center gap-2 rounded-sm py-1.5 pr-8 pl-2 text-sm outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4 *:[span]:last:flex *:[span]:last:items-center *:[span]:last:gap-2",
className, className,
)} )}
{...props} {...props}

View File

@@ -31,7 +31,7 @@ function Slider({
min={min} min={min}
max={max} max={max}
className={cn( className={cn(
"relative flex w-full touch-none items-center select-none data-disabled:opacity-50 data-[orientation=vertical]:h-full data-[orientation=vertical]:min-h-44 data-[orientation=vertical]:w-auto data-[orientation=vertical]:flex-col", "relative flex w-full touch-none items-center select-none data-[disabled]:opacity-50 data-[orientation=vertical]:h-full data-[orientation=vertical]:min-h-44 data-[orientation=vertical]:w-auto data-[orientation=vertical]:flex-col",
className, className,
)} )}
{...props} {...props}

View File

@@ -1,35 +1,42 @@
{ {
"compilerOptions": { "compilerOptions": {
"lib": ["dom", "dom.iterable", "esnext"], /* Base Options: */
"allowJs": false,
"skipLibCheck": true,
"strict": true,
"noEmit": true,
"esModuleInterop": true, "esModuleInterop": true,
"module": "esnext", "skipLibCheck": true,
"moduleResolution": "bundler", "target": "es2022",
"allowJs": true,
"resolveJsonModule": true, "resolveJsonModule": true,
"moduleDetection": "force",
"isolatedModules": true, "isolatedModules": true,
"jsx": "react-jsx", "verbatimModuleSyntax": true,
/* Strictness */
"strict": true,
"noUncheckedIndexedAccess": true,
"checkJs": true,
/* Bundled projects */
"lib": ["dom", "dom.iterable", "ES2022"],
"noEmit": true,
"module": "ESNext",
"moduleResolution": "Bundler",
"jsx": "preserve",
"plugins": [{ "name": "next" }],
"incremental": true, "incremental": true,
/* Path Aliases */
"baseUrl": ".", "baseUrl": ".",
"paths": { "paths": {
"@/*": ["./src/*"] "@/*": ["./src/*"]
}, }
"target": "ES2022",
"forceConsistentCasingInFileNames": true,
"verbatimModuleSyntax": true,
"noUncheckedIndexedAccess": false,
"exactOptionalPropertyTypes": false,
"noImplicitReturns": false,
"plugins": [{ "name": "next" }]
}, },
"include": [ "include": [
"next-env.d.ts", "next-env.d.ts",
"**/*.ts", "**/*.ts",
"**/*.tsx", "**/*.tsx",
".next/types/**/*.ts", "**/*.cjs",
".next/dev/types/**/*.ts" "**/*.js",
".next/types/**/*.ts"
], ],
"exclude": ["node_modules"] "exclude": ["node_modules"]
} }