mirror of https://github.com/langgenius/dify.git
feat: enhance form components with additional props for validation and tooltips; add OptionsField component
This commit is contained in:
parent
0345eb4659
commit
6eef5990c9
|
|
@ -2,18 +2,26 @@ import React from 'react'
|
|||
import { useFieldContext } from '../..'
|
||||
import Label from '../label'
|
||||
import cn from '@/utils/classnames'
|
||||
import type { InputNumberProps } from '../../../input-number'
|
||||
import { InputNumber } from '../../../input-number'
|
||||
|
||||
type TextFieldProps = {
|
||||
label: string
|
||||
isRequired?: boolean
|
||||
showOptional?: boolean
|
||||
tooltip?: string
|
||||
className?: string
|
||||
labelClassName?: string
|
||||
}
|
||||
} & Omit<InputNumberProps, 'id' | 'value' | 'onChange' | 'onBlur'>
|
||||
|
||||
const NumberInputField = ({
|
||||
label,
|
||||
isRequired,
|
||||
showOptional,
|
||||
tooltip,
|
||||
className,
|
||||
labelClassName,
|
||||
...inputProps
|
||||
}: TextFieldProps) => {
|
||||
const field = useFieldContext<number | undefined>()
|
||||
|
||||
|
|
@ -22,13 +30,17 @@ const NumberInputField = ({
|
|||
<Label
|
||||
htmlFor={field.name}
|
||||
label={label}
|
||||
labelClassName={labelClassName}
|
||||
isRequired={isRequired}
|
||||
showOptional={showOptional}
|
||||
tooltip={tooltip}
|
||||
className={labelClassName}
|
||||
/>
|
||||
<InputNumber
|
||||
id={field.name}
|
||||
value={field.state.value}
|
||||
onChange={value => field.handleChange(value)}
|
||||
onBlur={field.handleBlur}
|
||||
{...inputProps}
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
|
|
|
|||
|
|
@ -0,0 +1,34 @@
|
|||
import cn from '@/utils/classnames'
|
||||
import { useFieldContext } from '../..'
|
||||
import Label from '../label'
|
||||
import ConfigSelect from '@/app/components/app/configuration/config-var/config-select'
|
||||
|
||||
type OptionsFieldProps = {
|
||||
label: string;
|
||||
className?: string;
|
||||
labelClassName?: string;
|
||||
}
|
||||
|
||||
const OptionsField = ({
|
||||
label,
|
||||
className,
|
||||
labelClassName,
|
||||
}: OptionsFieldProps) => {
|
||||
const field = useFieldContext<string[]>()
|
||||
|
||||
return (
|
||||
<div className={cn('flex flex-col gap-y-0.5', className)}>
|
||||
<Label
|
||||
htmlFor={field.name}
|
||||
label={label}
|
||||
className={labelClassName}
|
||||
/>
|
||||
<ConfigSelect
|
||||
options={field.state.value}
|
||||
onChange={value => field.handleChange(value)}
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default OptionsField
|
||||
|
|
@ -11,6 +11,9 @@ type SelectOption = {
|
|||
type SelectFieldProps = {
|
||||
label: string
|
||||
options: SelectOption[]
|
||||
isRequired?: boolean
|
||||
showOptional?: boolean
|
||||
tooltip?: string
|
||||
className?: string
|
||||
labelClassName?: string
|
||||
}
|
||||
|
|
@ -18,6 +21,9 @@ type SelectFieldProps = {
|
|||
const SelectField = ({
|
||||
label,
|
||||
options,
|
||||
isRequired,
|
||||
showOptional,
|
||||
tooltip,
|
||||
className,
|
||||
labelClassName,
|
||||
}: SelectFieldProps) => {
|
||||
|
|
@ -27,8 +33,11 @@ const SelectField = ({
|
|||
<div className={cn('flex flex-col gap-y-0.5', className)}>
|
||||
<Label
|
||||
htmlFor={field.name}
|
||||
className={labelClassName}
|
||||
label={label}
|
||||
isRequired={isRequired}
|
||||
showOptional={showOptional}
|
||||
tooltip={tooltip}
|
||||
className={labelClassName}
|
||||
/>
|
||||
<PureSelect
|
||||
value={field.state.value}
|
||||
|
|
|
|||
|
|
@ -1,19 +1,26 @@
|
|||
import React from 'react'
|
||||
import { useFieldContext } from '../..'
|
||||
import Input from '../../../input'
|
||||
import Input, { type InputProps } from '../../../input'
|
||||
import Label from '../label'
|
||||
import cn from '@/utils/classnames'
|
||||
|
||||
type TextFieldProps = {
|
||||
label: string
|
||||
isRequired?: boolean
|
||||
showOptional?: boolean
|
||||
tooltip?: string
|
||||
className?: string
|
||||
labelClassName?: string
|
||||
}
|
||||
} & Omit<InputProps, 'className' | 'onChange' | 'onBlur' | 'value' | 'id'>
|
||||
|
||||
const TextField = ({
|
||||
label,
|
||||
isRequired,
|
||||
showOptional,
|
||||
tooltip,
|
||||
className,
|
||||
labelClassName,
|
||||
...inputProps
|
||||
}: TextFieldProps) => {
|
||||
const field = useFieldContext<string>()
|
||||
|
||||
|
|
@ -22,13 +29,17 @@ const TextField = ({
|
|||
<Label
|
||||
htmlFor={field.name}
|
||||
label={label}
|
||||
labelClassName={labelClassName}
|
||||
isRequired={isRequired}
|
||||
showOptional={showOptional}
|
||||
tooltip={tooltip}
|
||||
className={labelClassName}
|
||||
/>
|
||||
<Input
|
||||
id={field.name}
|
||||
value={field.state.value}
|
||||
onChange={e => field.handleChange(e.target.value)}
|
||||
onBlur={field.handleBlur}
|
||||
{...inputProps}
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
|
|
|
|||
|
|
@ -1,14 +1,14 @@
|
|||
import cn from '@/utils/classnames'
|
||||
import Tooltip from '../../tooltip'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
|
||||
type LabelProps = {
|
||||
export type LabelProps = {
|
||||
htmlFor: string
|
||||
label: string
|
||||
isRequired?: boolean
|
||||
showOptional?: boolean
|
||||
tooltip?: string
|
||||
className?: string
|
||||
labelClassName?: string
|
||||
}
|
||||
|
||||
const Label = ({
|
||||
|
|
@ -17,17 +17,19 @@ const Label = ({
|
|||
isRequired,
|
||||
showOptional,
|
||||
tooltip,
|
||||
labelClassName,
|
||||
className,
|
||||
}: LabelProps) => {
|
||||
const { t } = useTranslation()
|
||||
|
||||
return (
|
||||
<div className='flex h-6 items-center'>
|
||||
<label
|
||||
htmlFor={htmlFor}
|
||||
className={cn('system-sm-medium text-text-secondary', labelClassName)}
|
||||
className={cn('system-sm-medium text-text-secondary', className)}
|
||||
>
|
||||
{label}
|
||||
</label>
|
||||
{showOptional && <div className='system-xs-regular ml-1 text-text-tertiary'>(Optional)</div>}
|
||||
{showOptional && <div className='system-xs-regular ml-1 text-text-tertiary'>{t('common.label.optional')}</div>}
|
||||
{isRequired && <div className='system-xs-regular ml-1 text-text-destructive-secondary'>*</div>}
|
||||
{tooltip && (
|
||||
<Tooltip
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ import TextField from './components/field/text'
|
|||
import NumberInputField from './components/field/number-input'
|
||||
import CheckboxField from './components/field/checkbox'
|
||||
import SelectField from './components/field/select'
|
||||
import OptionsField from './components/field/options'
|
||||
import SubmitButton from './components/form/submit-button'
|
||||
|
||||
export const { fieldContext, useFieldContext, formContext, useFormContext }
|
||||
|
|
@ -14,6 +15,7 @@ export const { useAppForm, withForm } = createFormHook({
|
|||
NumberInputField,
|
||||
CheckboxField,
|
||||
SelectField,
|
||||
OptionsField,
|
||||
},
|
||||
formComponents: {
|
||||
SubmitButton,
|
||||
|
|
|
|||
Loading…
Reference in New Issue