This commit is contained in:
2026-10-01 08:02:47 +01:00
parent 6392457ffb
commit 3dc9f12ad4
104 changed files with 6536 additions and 1037 deletions
+30 -26
View File
@@ -1,14 +1,14 @@
import { ChevronDown, Info, LucideProps } from "lucide-react";
import { ChevronDown, Info, type LucideProps } from "lucide-react";
import React, {
ComponentProps,
DetailedHTMLProps,
Dispatch,
InputHTMLAttributes,
LabelHTMLAttributes,
ReactNode,
RefObject,
SelectHTMLAttributes,
SetStateAction,
type ComponentProps,
type DetailedHTMLProps,
type Dispatch,
type InputHTMLAttributes,
type LabelHTMLAttributes,
type ReactNode,
type RefObject,
type SelectHTMLAttributes,
type SetStateAction,
} from "react";
import { twMerge } from "tailwind-merge";
import Row from "../layout/Row";
@@ -18,6 +18,8 @@ import Span from "../layout/Span";
import Stack from "../layout/Stack";
import twuiSlugify from "../utils/slugify";
import twuiSlugToNormalText from "../utils/slug-to-normal-text";
import Input from "./Input";
import Button from "../layout/Button";
export type TWUISelectValidityObject = {
isValid?: boolean;
@@ -26,7 +28,7 @@ export type TWUISelectValidityObject = {
export type TWUISelectOptionObject<
KeyType extends string = string,
T extends { [k: string]: any } = { [k: string]: any }
T extends { [k: string]: any } = { [k: string]: any },
> = {
title?: string;
value: KeyType;
@@ -36,7 +38,7 @@ export type TWUISelectOptionObject<
export type TWUISelectProps<
KeyType extends string,
T extends { [k: string]: any } = { [k: string]: any }
T extends { [k: string]: any } = { [k: string]: any },
> = DetailedHTMLProps<
SelectHTMLAttributes<HTMLSelectElement>,
HTMLSelectElement
@@ -60,11 +62,13 @@ export type TWUISelectProps<
validateValueFn?: (value: string) => Promise<TWUISelectValidityObject>;
dispatchState?: Dispatch<SetStateAction<T | undefined>>;
name?: KeyType;
input_props?: ComponentProps<typeof Input>;
option_button_props?: Omit<ComponentProps<typeof Button>, "title">;
};
export type TWUISelectValueObject<
KeyType extends string,
T extends { [k: string]: any } = { [k: string]: any }
T extends { [k: string]: any } = { [k: string]: any },
> = {
value: KeyType;
data?: T;
@@ -78,7 +82,7 @@ export type TWUISelectValueObject<
*/
export default function Select<
KeyType extends string,
T extends { [k: string]: any } = { [k: string]: any }
T extends { [k: string]: any } = { [k: string]: any },
>({
label,
options,
@@ -102,9 +106,9 @@ export default function Select<
const [value, setValue] = React.useState<TWUISelectValueObject<KeyType, T>>(
{
value: options[0]?.value,
value: options[0]?.value!,
data: options[0]?.data,
}
},
);
React.useEffect(() => {
@@ -128,10 +132,10 @@ export default function Select<
const selectID = label
? twuiSlugify(label)
: props.name
? twuiSlugify(props.name)
: props.title
? twuiSlugify(props.title)
: `select-${Math.round(Math.random() * 1000000)}`;
? twuiSlugify(props.name)
: props.title
? twuiSlugify(props.title)
: `select-${Math.round(Math.random() * 1000000)}`;
return (
<Stack
@@ -148,7 +152,7 @@ export default function Select<
"focus:outline-slate-700 dark:focus:outline-white/50",
"bg-white dark:bg-background-dark",
validity.isValid ? "" : "outline-warning border-warning",
wrapperProps?.className
wrapperProps?.className,
)}
>
{showLabel && (
@@ -159,7 +163,7 @@ export default function Select<
"text-xs absolute -top-2.5 left-2 text-foreground-light/80 bg-background-light",
"dark:text-foreground-dark/70 dark:bg-background-dark px-1.5 rounded-t",
"twui-input-label",
labelProps?.className
labelProps?.className,
)}
>
{label || props.title || props.name}
@@ -174,7 +178,7 @@ export default function Select<
"w-full pl-3 py-2 rounded-default appearance-none pr-8",
"grow !border-none !outline-none",
"twui-select",
props.className
props.className,
)}
ref={selectRef}
value={
@@ -183,7 +187,7 @@ export default function Select<
}
onChange={(e) => {
const targetValue = options.find(
(opt) => opt.value == e.target.value
(opt) => opt.value == e.target.value,
);
if (targetValue) {
@@ -192,7 +196,7 @@ export default function Select<
changeHandler?.(
e.target.value as (typeof options)[number]["value"],
targetValue?.data
targetValue?.data,
);
props.onChange?.(e);
@@ -219,7 +223,7 @@ export default function Select<
{...iconProps}
className={twMerge(
"pointer-events-none -ml-6",
iconProps?.className
iconProps?.className,
)}
/>