'use client'; import { getClassNames, toKebabCase } from '@websolutespa/bom-core'; import { FormArray, FormGroup, mapState_ } from '@websolutespa/bom-mixer-forms'; import { forwardRef, useEffect, useImperativeHandle, useRef } from 'react'; import styled from 'styled-components'; import { ThemeProps, UIComponentWithRef, UIStyledComponentProps } from '../../components/types'; import { getCssResponsive } from '../../components/utils'; import { IThemeFormVariant } from '../../theme'; type Props = { form?: FormGroup | FormArray; variant?: IThemeFormVariant; }; export type FormProps = UIStyledComponentProps; export type FormComponent = UIComponentWithRef; const StyledForm = styled.div` ${props => getForm(props)} ${props => getCssResponsive(props)} `; export const Form: FormComponent = forwardRef(({ className, form, variant, ...props }, ref) => { const innerRef = useRef(null); useImperativeHandle(ref, () => innerRef.current); useEffect(() => { if (form) { const onChange = (value: any) => { // console.log('FormComponent.onChange', form.state); if (innerRef.current !== null) { const formElement = innerRef.current; Object.entries(mapState_(form.state)).forEach(([k, v]) => { formElement.classList.toggle(k, v); }); } }; form.on('change', onChange); return () => form.off('change', onChange); } return; // eslint-disable-next-line react-hooks/exhaustive-deps }, [form]); const classNames = getClassNames('form', className, variant); return ( ); }); Form.displayName = 'Form'; export function getForm(props: FormProps & ThemeProps) { const variant: IThemeFormVariant = props.variant || 'default'; const form = props.theme.form[variant]; if (form) { return Object.keys(form).map((k) => { const key: string = toKebabCase(k); const rule = `--form-${key}: var(--form-${variant}-${key}, --form-${key});`; return rule; }).join('\n'); } else { return undefined; } }