packages/ui: add textarea
fix element container position apps/web: add webkit scroll style move comment element to end of form use textarea element for comment
This commit is contained in:
parent
c3b6e8b046
commit
a8684087cf
@ -1,7 +1,7 @@
|
||||
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||
export type MetaObject = {
|
||||
disabled: boolean;
|
||||
fieldType: 'CHECKBOX' | 'DECIMAL' | 'INT' | 'STRING';
|
||||
fieldType: 'CHECKBOX' | 'DECIMAL' | 'INT' | 'STRING' | 'TEXTAREA';
|
||||
label: string;
|
||||
max: number;
|
||||
min: number;
|
||||
|
||||
@ -18,3 +18,24 @@
|
||||
body {
|
||||
background-color: var(--color-background);
|
||||
}
|
||||
|
||||
/* Scroll bar stylings */
|
||||
::-webkit-scrollbar {
|
||||
width: 6px;
|
||||
height: 6px;
|
||||
}
|
||||
|
||||
/* Track */
|
||||
::-webkit-scrollbar-track {
|
||||
}
|
||||
|
||||
/* Handle */
|
||||
::-webkit-scrollbar-thumb {
|
||||
background: rgba(0, 0, 0, 0.3);
|
||||
border-radius: 2px;
|
||||
}
|
||||
|
||||
/* Handle on hover */
|
||||
::-webkit-scrollbar-thumb:hover {
|
||||
background: rgba(0, 0, 0, 0.4);
|
||||
}
|
||||
|
||||
@ -4,6 +4,13 @@ import { useFormStore } from '@/store/ius/form';
|
||||
import { useEffect } from 'react';
|
||||
import { ElementContainer } from 'ui';
|
||||
|
||||
function compatMetadata(metaData: Props['metaData']) {
|
||||
const { comment, ...meta } = metaData;
|
||||
comment.fieldType = 'TEXTAREA';
|
||||
|
||||
return { ...meta, comment };
|
||||
}
|
||||
|
||||
export function Elements({ data, metaData }: Props) {
|
||||
const { init, setValue, validation, values } = useFormStore();
|
||||
|
||||
@ -13,7 +20,7 @@ export function Elements({ data, metaData }: Props) {
|
||||
|
||||
return (
|
||||
<div className="mt-2 grid auto-rows-auto grid-cols-1 gap-2 gap-x-4 md:grid-cols-2 lg:grid-cols-3">
|
||||
{Object.keys(metaData).map((name) => {
|
||||
{Object.keys(compatMetadata(metaData)).map((name) => {
|
||||
const { fieldType, label, max, min = 0, visible, ...props } = metaData[name];
|
||||
|
||||
if (!visible) return false;
|
||||
@ -22,6 +29,7 @@ export function Elements({ data, metaData }: Props) {
|
||||
|
||||
return (
|
||||
<ElementContainer
|
||||
classNameParent={fieldType === 'TEXTAREA' ? 'col-[span_3]' : undefined}
|
||||
intent={validation[name] ? 'danger' : 'default'}
|
||||
message={validation[name]?.message}
|
||||
key={name}
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
import type { MetaObject } from '@/api/ius/types';
|
||||
import { Checkbox, Input, InputNumber } from 'ui';
|
||||
import { Checkbox, Input, InputNumber, Textarea } from 'ui';
|
||||
|
||||
function wrapMap<C, T extends Record<MetaObject['fieldType'], C>>(arg: T) {
|
||||
return arg;
|
||||
@ -10,4 +10,5 @@ export const mapFieldTypeElement = wrapMap({
|
||||
DECIMAL: InputNumber,
|
||||
INT: InputNumber,
|
||||
STRING: Input,
|
||||
TEXTAREA: Textarea,
|
||||
});
|
||||
|
||||
@ -5,7 +5,9 @@ import { forwardRef, type HTMLAttributes, type PropsWithChildren } from 'react';
|
||||
|
||||
export type ContainerProps = HTMLAttributes<HTMLDivElement> & PropsWithChildren;
|
||||
|
||||
const variants = cva('flex h-9 items-center', {
|
||||
const parentVariants = cva('flex flex-col justify-center');
|
||||
|
||||
const variants = cva('min-h-[36px] flex items-center', {
|
||||
defaultVariants: {
|
||||
intent: 'default',
|
||||
},
|
||||
@ -18,11 +20,28 @@ const variants = cva('flex h-9 items-center', {
|
||||
});
|
||||
|
||||
export type WrapperProps = HTMLAttributes<HTMLDivElement> &
|
||||
VariantProps<typeof variants> & { readonly message?: string };
|
||||
VariantProps<typeof variants> & { readonly classNameParent?: string; readonly message?: string };
|
||||
|
||||
export const ElementContainer = forwardRef<HTMLDivElement, WrapperProps>(
|
||||
({ children, className, id, intent, message = 'Некорректные данные', title, ...props }, ref) => (
|
||||
<div {...props} className="flex flex-col justify-center" ref={ref} {...props}>
|
||||
(
|
||||
{
|
||||
children,
|
||||
className,
|
||||
classNameParent,
|
||||
id,
|
||||
intent,
|
||||
message = 'Некорректные данные',
|
||||
title,
|
||||
...props
|
||||
},
|
||||
ref
|
||||
) => (
|
||||
<div
|
||||
{...props}
|
||||
className={cn(parentVariants({ className: classNameParent }))}
|
||||
ref={ref}
|
||||
{...props}
|
||||
>
|
||||
<label
|
||||
htmlFor={id}
|
||||
className="mb-1 block overflow-hidden overflow-ellipsis whitespace-nowrap text-sm font-medium text-black text-opacity-90"
|
||||
|
||||
@ -12,3 +12,4 @@ export * from './http-error';
|
||||
export * from './icons';
|
||||
export * from './input';
|
||||
export * from './select';
|
||||
export * from './textarea';
|
||||
|
||||
19
packages/ui/textarea.tsx
Normal file
19
packages/ui/textarea.tsx
Normal file
@ -0,0 +1,19 @@
|
||||
import { cn } from './utils';
|
||||
import type { VariantProps } from 'class-variance-authority';
|
||||
import { cva } from 'class-variance-authority';
|
||||
import { forwardRef } from 'react';
|
||||
|
||||
const variants = cva(
|
||||
'focus:ring-0 h-auto hover:border-primary-500 focus:border-primary-500 w-full resize-none rounded-sm border disabled:hover:border-gray-300 border-gray-300 p-2 px-3 text-sm text-gray-900 outline-none transition-all ease-in-out disabled:cursor-not-allowed disabled:text-opacity-30'
|
||||
);
|
||||
|
||||
export type TextAreaProps = React.TextareaHTMLAttributes<HTMLTextAreaElement> &
|
||||
VariantProps<typeof variants> & { readonly loading?: boolean };
|
||||
|
||||
export const Textarea = forwardRef<HTMLTextAreaElement, TextAreaProps>(
|
||||
({ className, loading, ...props }, ref) => {
|
||||
if (loading) return <div className="h-[98px] w-full animate-pulse rounded bg-gray-100" />;
|
||||
|
||||
return <textarea rows={4} ref={ref} className={cn(variants({ className }))} {...props} />;
|
||||
}
|
||||
);
|
||||
Loading…
x
Reference in New Issue
Block a user