stream-chat-react
Version:
React components to create chat conversations or livestream style chat
77 lines (76 loc) • 3.71 kB
JavaScript
import React, { useCallback, useState } from 'react';
import clsx from 'clsx';
import { FieldError } from '../Form/FieldError';
import { useTranslationContext } from '../../context';
export const FormDialog = ({ className, close, fields, onSubmit, shouldDisableSubmitButton, title, }) => {
const { t } = useTranslationContext();
const [fieldErrors, setFieldErrors] = useState({});
const [value, setValue] = useState(() => {
let acc = {};
for (const [id, config] of Object.entries(fields)) {
acc = { ...acc, [id]: config.props.value };
}
return acc;
});
const handleChange = useCallback((event) => {
const fieldId = event.target.id;
const fieldConfig = fields[fieldId];
if (!fieldConfig)
return;
const error = fieldConfig.validator?.(event.target.value);
if (error) {
setFieldErrors((prev) => ({ [fieldId]: error, ...prev }));
}
else {
setFieldErrors((prev) => {
delete prev[fieldId];
return prev;
});
}
setValue((prev) => ({ ...prev, [fieldId]: event.target.value }));
if (!fieldConfig.props.onChange)
return;
if (fieldConfig.element === 'input') {
fieldConfig.props.onChange(event);
}
else if (fieldConfig.element === 'textarea') {
fieldConfig.props.onChange(event);
}
}, [fields]);
const handleSubmit = async () => {
if (!Object.keys(value).length)
return;
const errors = {};
for (const [id, fieldValue] of Object.entries(value)) {
const thisFieldError = fields[id].validator?.(fieldValue);
if (thisFieldError) {
errors[id] = thisFieldError;
}
}
if (Object.keys(errors).length) {
setFieldErrors(errors);
return;
}
await onSubmit(value);
close();
};
return (React.createElement("div", { className: clsx('str-chat__dialog str-chat__dialog--form', className) },
React.createElement("div", { className: 'str-chat__dialog__body' },
title && React.createElement("div", { className: 'str-chat__dialog__title' }, title),
React.createElement("form", { autoComplete: 'off', onSubmit: (e) => {
e.preventDefault();
handleSubmit();
} },
Object.entries(fields).map(([id, fieldConfig]) => (React.createElement("div", { className: 'str-chat__dialog__field', key: `dialog-field-${id}` },
fieldConfig.label && (React.createElement("label", { className: clsx(`str-chat__dialog__title str-chat__dialog__title--${id}`), htmlFor: id }, fieldConfig.label)),
React.createElement(fieldConfig.element, {
id,
...fieldConfig.props,
onChange: handleChange,
value: value[id],
}),
React.createElement(FieldError, { text: fieldErrors[id]?.message })))),
React.createElement("div", { className: 'str-chat__dialog__controls' },
React.createElement("button", { className: 'str-chat__dialog__controls-button str-chat__dialog__controls-button--cancel', onClick: close, type: 'button' }, t('Cancel')),
React.createElement("button", { className: 'str-chat__dialog__controls-button str-chat__dialog__controls-button--submit', disabled: Object.keys(fieldErrors).length > 0 || shouldDisableSubmitButton?.(value), type: 'submit' }, t('Send')))))));
};