🗨️ refactor(VariableForm): use InputCombobox, fix Dropdown Variables (#3692)

* feat: Add SimpleCombobox component

* feat: Add labelClassName and add manual focus handling

* feat: Update VariableForm component to use SimpleCombobox

The VariableForm component in the client/src/components/Prompts/Groups/VariableForm.tsx file has been updated to use the SimpleCombobox component instead of the InputWithDropdown component. This change improves the functionality and styling of the form.

* chore: Update VariableForm component placeholder text

* refactor: Improve VariableForm component

The VariableForm component in the client/src/components/Prompts/Groups/VariableForm.tsx file has been refactored to improve its functionality. The `parseFieldConfig` function now trims the `variable` string before processing it. Additionally, the `onSubmit` function now properly escapes potential regex special chars that may cause issues when replacing text

* refactor: Improve VariableForm using ariakit helpers/custom fields, open menu on input focus

* refactor: rename SimpleCombobox to InputCombobox
This commit is contained in:
Danny Avila 2024-08-18 22:23:19 -04:00 committed by GitHub
parent 8ca1e4f94f
commit 598e2be225
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 134 additions and 14 deletions

View file

@ -15,7 +15,7 @@ import {
extractVariableInfo,
} from '~/utils';
import { useAuthContext, useLocalize, useSubmitMessage } from '~/hooks';
import { TextareaAutosize, InputWithDropdown } from '~/components/ui';
import { TextareaAutosize, InputCombobox } from '~/components/ui';
import { code } from '~/components/Chat/Messages/Content/Markdown';
type FieldType = 'text' | 'select';
@ -51,11 +51,15 @@ type FormValues = {
*/
const parseFieldConfig = (variable: string): FieldConfig => {
const content = variable;
const content = variable.trim();
if (content.includes(':')) {
const [name, options] = content.split(':');
if (options && options.includes('|')) {
return { variable: name, type: 'select', options: options.split('|') };
return {
variable: name.trim(),
type: 'select',
options: options.split('|').map((opt) => opt.trim()),
};
}
}
return { variable: content, type: 'text' };
@ -121,10 +125,13 @@ export default function VariableForm({
const onSubmit = (data: FormValues) => {
let text = mainText;
data.fields.forEach(({ variable, value }) => {
if (value) {
const regex = new RegExp(variable, 'g');
text = text.replace(regex, value);
if (!value) {
return;
}
const escapedVariable = variable.replace(/[|\\{}()[\]^$+*?.]/g, '\\$&');
const regex = new RegExp(escapedVariable, 'g');
text = text.replace(regex, value);
});
submitPrompt(text);
@ -153,22 +160,29 @@ export default function VariableForm({
<Controller
name={`fields.${index}.value`}
control={control}
render={({ field: inputField }) => {
render={({ field: { onChange, onBlur, value, ref } }) => {
if (field.config.type === 'select') {
return (
<InputWithDropdown
{...inputField}
id={`fields.${index}.value`}
className={cn(defaultTextProps, 'focus:bg-surface-tertiary')}
placeholder={localize('com_ui_enter_var', field.config.variable)}
<InputCombobox
options={field.config.options || []}
placeholder={localize('com_ui_enter_var', field.config.variable)}
className={cn(
defaultTextProps,
'rounded px-3 py-2 focus:bg-surface-tertiary',
)}
value={value}
onChange={onChange}
onBlur={onBlur}
/>
);
}
return (
<TextareaAutosize
{...inputField}
ref={ref}
value={value}
onChange={onChange}
onBlur={onBlur}
id={`fields.${index}.value`}
className={cn(
defaultTextProps,