I am making a ControlledInputComponent which has a label and an input inside a div. I wanted to make it as customizeable as possible because I will be using in diverse ways. I have currently included everything I think is needed but it would be nice to be able to accept all other kinds of properties to add.
//These are the classes
const ControlledInputComponentByLabelAndInput = function (props: IInputByComponentAndLabelProps): JSX.Element {
const {label, input, className} = props;
return (
<div className={turnToString(className)}>
{label}
{input}
</div>
);
}
export const ControlledInputComponent = function (props: IInputProps): JSX.Element {
const {name, className, onChange, inputOptions = {}, labelOptions = {}} = props;
const {value = "", type = "text", id: inputId = name, placeholder = name} = inputOptions;
const {content: labelContent = name} = labelOptions;
const label = (<label htmlFor={name}>{labelContent}</label>);
const input = (<input type={type} name={name} value={value} placeholder={placeholder} id={inputId} onChange={onChange}/>);
return (
<ControlledInputComponentByLabelAndInput className={className} label={label} input={input}></ControlledInputComponentByLabelAndInput>
);
}
//These are the current interfaces
interface IInputByComponentAndLabelProps {
className?: ClassName;
label: JSX.Element;
input: JSX.Element;
}
export interface IInputProps {
name: string;
className?: ClassName;
onChange: IEventHandler;
labelOptions?: {content?: string};
inputOptions?: {type?: string, value?: string, id?: string, placeholder?: string};
}
I want to include all kinds of other options in labelOptions which are applicable to the label component (which are the ones applicable to the label HTML element). I want to do the same for the input. Is that somehow possible with TypeScript? I could do it with indexers but that would not tell me that I need label options. Is there an option to do what I've done below but with additionalLabelOptions being of interface ReactLabelComponent (or whatever it would be called).
const additionalLabelOptions = Object.entries(labelOptions).filter(([key])=>key!=="content");
const label = (<label htmlFor={name} {...additionalLabelOptions}>{labelContent}</label>);