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 { useField } from "@shared/nej-react-components/Parts/Input";
/**
* @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 }) {
export function AutocompleteSelect({ title, titleProps = null, data, nullable = false, renderOption = undefined, onScrollEnd = undefined, onQueryChange = undefined, ...props }) {
const [field, meta, helpers] = useField(props);
const [query, setQuery] = useState(field.value ?? "");
@ -52,14 +45,14 @@ export function AutocompleteSelect({ title, titleProps = null, data, nullable =
})
);
}
} else if(typeof data === "object")
{
setInternalData(Object.values(data).map((value) => {
return {
value: value,
label: value
};
}));
} else if (typeof data === "object") {
// TypeScript enum objects — convert values to { value, label } then filter
const enumItems = Object.values(data).map((value) => ({ value, label: value }));
setInternalData(
!renderOption && query !== ""
? enumItems.filter((item) => String(item.label).toLowerCase().includes(query.toLowerCase()))
: enumItems
);
}
else {
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 {<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 {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 {<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.
* @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({
//validator: validator,