Updates
This commit is contained in:
+30
-26
@@ -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,
|
||||
)}
|
||||
/>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user