From 15c32c0e6d38afedd72ee42cd800d1e61b518c36 Mon Sep 17 00:00:00 2001 From: dswbx Date: Thu, 18 Sep 2025 10:03:16 +0200 Subject: [PATCH] ui: improve form field components, add support for custom fields, export components Enhanced `FieldLabel` to support tooltips and additional props. Refactored form field components for better customizability and ensured compatibility with new `CustomField`. Updated `onChange` handlers to include context for improved flexibility. Added exports for UI components. --- app/src/ui/components/buttons/IconButton.tsx | 3 +- .../ui/components/form/Formy/components.tsx | 31 +++++++++----- .../form/json-schema-form/Field.tsx | 40 +++++++++++++++---- .../form/json-schema-form/FieldWrapper.tsx | 2 +- .../components/form/json-schema-form/Form.tsx | 27 +++++++------ app/src/ui/index.ts | 8 ++++ .../ui/modules/data/components/EntityForm.tsx | 4 +- .../fields/EntityRelationalFormField.tsx | 8 ++-- 8 files changed, 87 insertions(+), 36 deletions(-) diff --git a/app/src/ui/components/buttons/IconButton.tsx b/app/src/ui/components/buttons/IconButton.tsx index f0f168c..ca0f4a6 100644 --- a/app/src/ui/components/buttons/IconButton.tsx +++ b/app/src/ui/components/buttons/IconButton.tsx @@ -23,7 +23,7 @@ interface IconButtonProps extends ComponentPropsWithoutRef<"button"> { } export const IconButton = forwardRef( - ({ Icon, size, variant = "ghost", onClick, disabled, iconProps, ...rest }, ref) => { + ({ Icon, size, variant = "ghost", onClick, disabled, iconProps, tabIndex, ...rest }, ref) => { const style = styles[size ?? "md"]; return ( @@ -36,6 +36,7 @@ export const IconButton = forwardRef( className={twMerge(style.className, rest.className)} onClick={onClick} disabled={disabled} + tabIndex={tabIndex} /> ); }, diff --git a/app/src/ui/components/form/Formy/components.tsx b/app/src/ui/components/form/Formy/components.tsx index 3e95f00..502a844 100644 --- a/app/src/ui/components/form/Formy/components.tsx +++ b/app/src/ui/components/form/Formy/components.tsx @@ -1,3 +1,4 @@ +import { Tooltip } from "@mantine/core"; import clsx from "clsx"; import { getBrowser } from "core/utils"; import type { Field } from "data/fields"; @@ -6,6 +7,7 @@ import { type ComponentPropsWithoutRef, type ElementType, forwardRef, + Fragment, useEffect, useImperativeHandle, useRef, @@ -66,17 +68,22 @@ export const ErrorMessage: React.FC> = ({ className,
); -export const FieldLabel: React.FC & { field: Field }> = ({ - field, - ...props -}) => { +export const FieldLabel: React.FC< + React.ComponentProps<"label"> & { field: Field; label?: string } +> = ({ field, label, ...props }) => { const desc = field.getDescription(); + const Wrapper = desc + ? (p) => + : (p) => ; + return ( - + + + ); }; @@ -103,6 +110,12 @@ export const TypeAwareInput = forwardRef; } + if ("data-type" in props) { + if (props["data-type"] === "textarea") { + // @ts-ignore + return