Merge pull request #30 from WIT-LAB-LLC/system-select-input
system-select-input
This commit is contained in:
commit
d24795a4a6
@ -10,6 +10,7 @@ import {
|
||||
buildTemplateBottomActionButtonProps,
|
||||
} from "@/lib/funnel/mappers";
|
||||
import type { ScreenDefinition } from "@/lib/funnel/types";
|
||||
import { cn } from "@/lib/utils";
|
||||
|
||||
interface TemplateLayoutProps {
|
||||
screen: ScreenDefinition;
|
||||
@ -132,7 +133,7 @@ export function TemplateLayout({
|
||||
|
||||
const autoPrivacyTermsConsent = shouldShowPrivacyTermsConsent ? (
|
||||
<PrivacyTermsConsent
|
||||
className="mt-5"
|
||||
className="mt-2"
|
||||
privacyPolicy={{
|
||||
href: "/privacy",
|
||||
children: "Privacy Policy",
|
||||
@ -170,6 +171,13 @@ export function TemplateLayout({
|
||||
ref={bottomActionButtonRef}
|
||||
childrenAboveButton={childrenAboveButton}
|
||||
childrenUnderButton={finalChildrenUnderButton}
|
||||
gradientBlurProps={
|
||||
shouldShowPrivacyTermsConsent
|
||||
? {
|
||||
className: cn(shouldShowPrivacyTermsConsent && "pb-1"),
|
||||
}
|
||||
: undefined
|
||||
}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
|
||||
84
src/components/ui/SystemSelectInput/SystemSelectInput.tsx
Normal file
84
src/components/ui/SystemSelectInput/SystemSelectInput.tsx
Normal file
@ -0,0 +1,84 @@
|
||||
"use client";
|
||||
|
||||
import { cn } from "@/lib/utils";
|
||||
import { useId } from "react";
|
||||
import Typography from "../Typography/Typography";
|
||||
|
||||
type Option = {
|
||||
value: string | number;
|
||||
label: string;
|
||||
};
|
||||
|
||||
export interface SelectInputProps extends React.ComponentProps<"select"> {
|
||||
error?: boolean;
|
||||
options: Option[];
|
||||
placeholder?: string;
|
||||
label?: string;
|
||||
labelProps?: React.ComponentProps<"label">;
|
||||
errorProps?: React.ComponentProps<typeof Typography>;
|
||||
}
|
||||
|
||||
export default function SelectInput({
|
||||
error,
|
||||
options,
|
||||
placeholder,
|
||||
label,
|
||||
labelProps,
|
||||
errorProps,
|
||||
...props
|
||||
}: SelectInputProps) {
|
||||
const id = useId();
|
||||
|
||||
return (
|
||||
<div className={cn("w-full flex flex-col gap-2")}>
|
||||
{label && (
|
||||
<label
|
||||
htmlFor={id}
|
||||
className={cn(
|
||||
"text-muted-foreground font-inter font-medium text-base",
|
||||
labelProps?.className
|
||||
)}
|
||||
{...labelProps}
|
||||
>
|
||||
{label}
|
||||
</label>
|
||||
)}
|
||||
<select
|
||||
id={id}
|
||||
className={cn(
|
||||
"cursor-pointer",
|
||||
"appearance-none",
|
||||
"w-full min-w-[106px] h-fit! min-h-14",
|
||||
"px-4 py-3.5",
|
||||
"font-inter text-[18px]/[28px] font-medium text-placeholder-foreground",
|
||||
"rounded-2xl outline-2 outline-primary/30",
|
||||
"duration-200",
|
||||
"disabled:opacity-50 disabled:cursor-not-allowed",
|
||||
error &&
|
||||
"outline-destructive focus-visible:shadow-destructive focus-visible:ring-destructive/30"
|
||||
)}
|
||||
{...props}
|
||||
>
|
||||
{placeholder && (
|
||||
<option value="" hidden>
|
||||
{placeholder}
|
||||
</option>
|
||||
)}
|
||||
{options.map((option) => (
|
||||
<option
|
||||
key={option.value}
|
||||
value={option.value}
|
||||
className="text-foreground"
|
||||
>
|
||||
{option.label}
|
||||
</option>
|
||||
))}
|
||||
</select>
|
||||
{error && (
|
||||
<Typography size="xs" color="destructive" {...errorProps}>
|
||||
{errorProps?.children}
|
||||
</Typography>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@ -21,6 +21,8 @@ export interface BottomActionButtonProps extends React.ComponentProps<"div"> {
|
||||
showGradientBlur?: boolean;
|
||||
/** Синхронизировать CSS-переменную --bottom-action-button-height на <html> */
|
||||
syncCssVar?: boolean;
|
||||
|
||||
gradientBlurProps?: React.ComponentProps<typeof GradientBlur>;
|
||||
}
|
||||
|
||||
const BottomActionButton = forwardRef<HTMLDivElement, BottomActionButtonProps>(
|
||||
@ -32,6 +34,7 @@ const BottomActionButton = forwardRef<HTMLDivElement, BottomActionButtonProps>(
|
||||
showGradientBlur = true,
|
||||
className,
|
||||
syncCssVar = true,
|
||||
gradientBlurProps,
|
||||
...props
|
||||
},
|
||||
ref
|
||||
@ -81,7 +84,11 @@ const BottomActionButton = forwardRef<HTMLDivElement, BottomActionButtonProps>(
|
||||
)}
|
||||
{...props}
|
||||
>
|
||||
<GradientBlur className="p-6 pt-11" isActiveBlur={showGradientBlur}>
|
||||
<GradientBlur
|
||||
isActiveBlur={showGradientBlur}
|
||||
{...gradientBlurProps}
|
||||
className={cn("p-6 pt-11", gradientBlurProps?.className)}
|
||||
>
|
||||
{childrenAboveButton && (
|
||||
<div className="w-full flex justify-center">
|
||||
{childrenAboveButton}
|
||||
|
||||
@ -1,15 +1,13 @@
|
||||
"use client";
|
||||
|
||||
import SelectInput, {
|
||||
SelectInputProps,
|
||||
} from "@/components/ui/SelectInput/SelectInput";
|
||||
import SystemSelectInput from "@/components/ui/SystemSelectInput/SystemSelectInput";
|
||||
|
||||
import Typography from "@/components/ui/Typography/Typography";
|
||||
import { useDateInput } from "@/hooks/useDateInput";
|
||||
|
||||
type LocalSelectInputProps = Omit<
|
||||
SelectInputProps,
|
||||
"value" | "onValueChange" | "options"
|
||||
React.ComponentProps<typeof SystemSelectInput>,
|
||||
"value" | "onChange" | "options"
|
||||
>;
|
||||
|
||||
export interface DateInputProps {
|
||||
@ -58,30 +56,30 @@ export default function DateInput({
|
||||
|
||||
const inputs = {
|
||||
d: (
|
||||
<SelectInput
|
||||
<SystemSelectInput
|
||||
key="d"
|
||||
value={day}
|
||||
onValueChange={handleDayChange}
|
||||
onChange={(e) => handleDayChange(e.target.value)}
|
||||
options={dayOptions}
|
||||
placeholder="DD"
|
||||
{...daySelectProps}
|
||||
/>
|
||||
),
|
||||
m: (
|
||||
<SelectInput
|
||||
<SystemSelectInput
|
||||
key="m"
|
||||
value={month}
|
||||
onValueChange={handleMonthChange}
|
||||
onChange={(e) => handleMonthChange(e.target.value)}
|
||||
options={monthOptions}
|
||||
placeholder="MM"
|
||||
{...monthSelectProps}
|
||||
/>
|
||||
),
|
||||
y: (
|
||||
<SelectInput
|
||||
<SystemSelectInput
|
||||
key="y"
|
||||
value={year}
|
||||
onValueChange={handleYearChange}
|
||||
onChange={(e) => handleYearChange(e.target.value)}
|
||||
options={yearOptions}
|
||||
placeholder="YYYY"
|
||||
{...yearSelectProps}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user