1
0
Fork 0
mirror of https://github.com/jellyfin/jellyfin-web synced 2025-03-30 19:56:21 +00:00
jellyfin-web/src/elements/InputElement.tsx
2023-09-15 11:08:31 -04:00

74 lines
1.9 KiB
TypeScript

import React, { type FC, useCallback, useEffect, useMemo, useRef } from 'react';
import globalize from '../scripts/globalize';
interface CreateInputElementParams {
type?: string
id?: string
label?: string
initialValue?: string
options?: string
}
const createInputElement = ({ type, id, label, initialValue, options }: CreateInputElementParams) => ({
__html: `<input
is="emby-input"
type="${type}"
id="${id}"
label="${label}"
value="${initialValue}"
${options}
/>`
});
type InputElementProps = {
containerClassName?: string
onChange?: (value: string) => void
} & CreateInputElementParams;
const InputElement: FC<InputElementProps> = ({
containerClassName,
initialValue,
onChange = () => { /* no-op */ },
type,
id,
label,
options = ''
}) => {
const container = useRef<HTMLDivElement>(null);
// NOTE: We need to memoize the input html because any re-render will break the webcomponent
const inputHtml = useMemo(() => (
createInputElement({
type,
id,
label: globalize.translate(label),
initialValue,
options
})
// eslint-disable-next-line react-hooks/exhaustive-deps
), []);
const onInput = useCallback((e: Event) => {
onChange((e.target as HTMLInputElement).value);
}, [ onChange ]);
useEffect(() => {
const inputElement = container?.current?.querySelector<HTMLInputElement>('input');
inputElement?.addEventListener('input', onInput);
return () => {
inputElement?.removeEventListener('input', onInput);
};
}, [ container, onInput ]);
return (
<div
ref={container}
className={containerClassName}
dangerouslySetInnerHTML={inputHtml}
/>
);
};
export default InputElement;