fixup upload and autocomplete

This commit is contained in:
honzapatCZ 2026-05-27 22:55:31 +02:00
parent 5a18a4d33b
commit e46167ea63
2 changed files with 11 additions and 18 deletions

View File

@ -7,14 +7,7 @@ import tw, { styled } from "twin.macro";
import "styled-components/macro"; import "styled-components/macro";
import { useField } from "@shared/nej-react-components/Parts/Input"; import { useField } from "@shared/nej-react-components/Parts/Input";
/** export function AutocompleteSelect({ title, titleProps = null, data, nullable = false, renderOption = undefined, onScrollEnd = undefined, onQueryChange = undefined, ...props }) {
* @param {object} props
* @param {((query: string) => Promise<Array>) | Array} props.data
* @param {(val: any, state: { active: boolean, selected: boolean }) => React.ReactNode} [props.renderOption] - Custom renderer for each option. Receives the raw item and combobox state.
* @param {() => void} [props.onScrollEnd] - Called when the options list is scrolled to the bottom (for infinite scroll).
* @param {(query: string) => void} [props.onQueryChange] - Called when the search input changes. Use this with renderOption to drive server-side filtering.
*/
export function AutocompleteSelect({ title, titleProps = null, data, nullable = false, renderOption, onScrollEnd, onQueryChange, ...props }) {
const [field, meta, helpers] = useField(props); const [field, meta, helpers] = useField(props);
const [query, setQuery] = useState(field.value ?? ""); const [query, setQuery] = useState(field.value ?? "");
@ -52,14 +45,14 @@ export function AutocompleteSelect({ title, titleProps = null, data, nullable =
}) })
); );
} }
} else if(typeof data === "object") } else if (typeof data === "object") {
{ // TypeScript enum objects — convert values to { value, label } then filter
setInternalData(Object.values(data).map((value) => { const enumItems = Object.values(data).map((value) => ({ value, label: value }));
return { setInternalData(
value: value, !renderOption && query !== ""
label: value ? enumItems.filter((item) => String(item.label).toLowerCase().includes(query.toLowerCase()))
}; : enumItems
})); );
} }
else { else {
console.error("data is not an array or function :c"); console.error("data is not an array or function :c");

View File

@ -7,13 +7,13 @@ import { HTMLAttributes, useMemo } from "react";
* @param {Object} props - Component props. * @param {Object} props - Component props.
* @param {<T extends File>(files: T[], event: DropEvent) => void} props.onDrop - Callback function triggered when files are dropped. * @param {<T extends File>(files: T[], event: DropEvent) => void} props.onDrop - Callback function triggered when files are dropped.
* @param {string[]} props.accept - Array of supported file extensions. * @param {string[]} props.accept - Array of supported file extensions.
* @param {Array<File>} props.value - The files to be uploaded. * @param {Array<File> | null} props.value - The files to be uploaded.
* @param {boolean} props.single - Whether to allow only one file to be uploaded. * @param {boolean} props.single - Whether to allow only one file to be uploaded.
* @param {<T extends File>(file: T) => FileError | FileError[] | null} props.validator - The validator function to be used. * @param {<T extends File>(file: T) => FileError | FileError[] | null} props.validator - The validator function to be used.
* @param {string} props.text - The text to be displayed in the dropzone. * @param {string} props.text - The text to be displayed in the dropzone.
* @returns {JSX.Element} - NejDropzone component. * @returns {JSX.Element} - NejDropzone component.
*/ */
export default function NejDropzone({ value, accept, onDrop, validator, single, text, css, children, ...props }: HTMLAttributes<HTMLDivElement> & { value: File | File[], accept?: Accept | string, onDrop: (files: File[]) => void, validator?: (file: File) => FileError | FileError[] | null, single?: boolean, text?: string, css?: any, children?: any }) { export default function NejDropzone({ value = null, accept, onDrop, validator, single, text, css, children, ...props }: HTMLAttributes<HTMLDivElement> & { value?: File | File[] | null, accept?: Accept | string, onDrop: (files: File[]) => void, validator?: (file: File) => FileError | FileError[] | null, single?: boolean, text?: string, css?: any, children?: any }) {
const { getRootProps, getInputProps, isFocused, isDragAccept, isDragReject } = useDropzone({ const { getRootProps, getInputProps, isFocused, isDragAccept, isDragReject } = useDropzone({
//validator: validator, //validator: validator,