Open huytrongnguyen opened 6 months ago
import { HTMLAttributes, useEffect, useState } from 'react'; import { DataModel, Rosie } from 'rosie'; export interface EditorFieldProps extends HTMLAttributes<HTMLDivElement> { type?: string, rows?: number, record: DataModel<any>, field: string, label: string, labelSeparator?: string, labelAlign?: 'left' | 'top', labelCol?: number, labelCls?: string, } export function EditorField(props: EditorFieldProps) { const { type = 'text', rows = 3, record, field, label, labelSeparator = ':', labelAlign = 'left', labelCol = 6, labelCls, className, ...others } = props, [readOnly, setReadOnly] = useState(true), [fieldValue, setFieldValue] = useState<any>(''); useEffect(() => { const record$ = props.record.subscribe(value => setFieldValue(value[field])); return () => { record$.unsubscribe(); } }, []) function updateValue() { record.set(field, fieldValue); setReadOnly(true); } if (!readOnly && type === 'textarea') { if (labelAlign === 'top') { return <div className={Rosie.classNames(className)} {...others}> <label className={Rosie.classNames('form-label fw-bold', labelCls)}>{label}</label> <textarea autoFocus rows={rows} className="form-control form-control-sm p-2" onBlur={() => { updateValue() }} value={fieldValue} onChange={e => setFieldValue(e.target.value)} /> </div> } else { return <></> } } if (!readOnly && type === 'text') { if (labelAlign === 'top') { return <></> } else { return <div className={Rosie.classNames('row', className)} {...others}> <label className={Rosie.classNames(`col-${labelCol} col-form-label fw-bold`, labelCls)}>{label}{labelSeparator}</label> <div className={`col-${Rosie.GRID_COLUMNS - labelCol}`}> <input type="text" autoFocus className="form-control form-control-sm" onBlur={() => { updateValue() }} value={fieldValue} onChange={e => setFieldValue(e.target.value)} /> </div> </div> } } if (labelAlign === 'top') { return <div className={Rosie.classNames(className)} {...others}> <label className={Rosie.classNames('form-label fw-bold', labelCls)}>{label}</label> <div className="input-group input-group-sm"> <div className={Rosie.classNames('form-control form-control-sm p-2', {'bg-warning-subtle': record.isModified(field)})}> {fieldValue} </div> <span role="button" className="input-group-text" onClick={() => { setReadOnly(false) }}> <span className="fa fa-pencil" /> </span> </div> </div> } else { return <div className={Rosie.classNames('row', className)} {...others}> <label className={Rosie.classNames(`col-${labelCol} col-form-label fw-bold`, labelCls)}>{label}{labelSeparator}</label> <div className={`col-${Rosie.GRID_COLUMNS - labelCol} py-1`}> <div className="input-group input-group-sm" style={{height:'28px'}}> <div className={Rosie.classNames('form-control', {'bg-warning-subtle': record.isModified(field)})}> {fieldValue} </div> <span role="button" className="input-group-text" onClick={() => { setReadOnly(false) }}> <span className="fa fa-pencil" /> </span> </div> </div> </div> } }