@sqrzro/ui 4.0.0-alpha.3 → 4.0.0-alpha.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/forms/components/Autocomplete/index.d.ts +11 -0
- package/dist/forms/components/Autocomplete/index.js +37 -0
- package/dist/forms/components/Dropdown/index.js +1 -1
- package/dist/forms/components/DropdownList/index.js +3 -1
- package/dist/forms/components/FormFields/index.d.ts +9 -0
- package/dist/forms/components/FormFields/index.js +18 -0
- package/dist/forms/components/MoneyInput/index.d.ts +5 -0
- package/dist/forms/components/MoneyInput/index.js +22 -0
- package/dist/forms/components/NumberInput/index.d.ts +7 -0
- package/dist/forms/components/NumberInput/index.js +27 -0
- package/dist/forms/components/StaticTextInput/index.d.ts +1 -2
- package/dist/forms/components/StaticTextInput/index.js +2 -2
- package/dist/forms/components/TextInput/index.d.ts +1 -1
- package/dist/forms/components/TextInput/index.js +2 -2
- package/dist/forms/hooks/useAutocomplete.d.ts +8 -0
- package/dist/forms/hooks/useAutocomplete.js +31 -0
- package/dist/forms/index.d.ts +9 -2
- package/dist/forms/index.js +5 -1
- package/dist/forms/interfaces.d.ts +1 -0
- package/dist/hooks/index.d.ts +1 -0
- package/dist/hooks/index.js +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { ClassNameProps } from '../../../styles/interfaces';
|
|
2
|
+
import type { DropdownObject, InputProps } from '../../interfaces';
|
|
3
|
+
import { DropdownClassNames, DropdownComponentProps } from '../Dropdown';
|
|
4
|
+
export interface AutocompleteComponentProps<T> extends DropdownComponentProps<T> {
|
|
5
|
+
isLoading?: boolean;
|
|
6
|
+
onSearch?: (search: string) => void;
|
|
7
|
+
selected?: DropdownObject<T> | null;
|
|
8
|
+
}
|
|
9
|
+
export type AutocompleteProps<T> = ClassNameProps<DropdownClassNames> & InputProps<T | null> & AutocompleteComponentProps<T>;
|
|
10
|
+
declare function Autocomplete<T>({ hasError, isDisabled, isLoading, isOptional, name, onChange, onSearch, options, selected, placeholder, value, }: Readonly<AutocompleteProps<T>>): React.ReactElement;
|
|
11
|
+
export default Autocomplete;
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { Fragment, useRef, useState } from 'react';
|
|
4
|
+
import Popover from '../../../components/utility/Popover';
|
|
5
|
+
import useClickOutside from '../../../hooks/useClickOutside';
|
|
6
|
+
import DropdownList from '../DropdownList';
|
|
7
|
+
import StaticTextInput from '../StaticTextInput';
|
|
8
|
+
import TextInput from '../TextInput';
|
|
9
|
+
function Autocomplete({ hasError, isDisabled, isLoading, isOptional, name, onChange, onSearch, options, selected, placeholder, value, }) {
|
|
10
|
+
const inputRef = useRef(null);
|
|
11
|
+
const [search, setSearch] = useState('');
|
|
12
|
+
const [isOpen, setIsOpen, ref] = useClickOutside();
|
|
13
|
+
function handleChange(event) {
|
|
14
|
+
if (onChange) {
|
|
15
|
+
onChange(event);
|
|
16
|
+
}
|
|
17
|
+
setIsOpen(false);
|
|
18
|
+
setSearch('');
|
|
19
|
+
}
|
|
20
|
+
function handleSearch(event) {
|
|
21
|
+
setSearch(event.target.value ?? '');
|
|
22
|
+
setIsOpen(true);
|
|
23
|
+
if (onSearch) {
|
|
24
|
+
onSearch(event.target.value ?? '');
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
function handleReset() {
|
|
28
|
+
if (onChange) {
|
|
29
|
+
onChange({ target: { name, value: null } });
|
|
30
|
+
}
|
|
31
|
+
setTimeout(() => {
|
|
32
|
+
inputRef.current?.focus();
|
|
33
|
+
}, 10);
|
|
34
|
+
}
|
|
35
|
+
return (_jsx("div", { ref: ref, className: "relative", children: selected ? (_jsx(StaticTextInput, { details: selected.details, hasError: hasError, isDisabled: isDisabled, isOptional: isOptional, label: selected.label, name: name, onClick: handleReset, placeholder: placeholder || 'Select...', value: value ? String(value) : '' })) : (_jsxs(Fragment, { children: [_jsx(TextInput, { ref: inputRef, hasError: hasError, isDisabled: isDisabled, name: `${name}_search`, onChange: handleSearch, onFocus: () => setIsOpen(Boolean(options?.length)), placeholder: "Start typing...", value: search }), _jsx(Popover, { align: "center", isOpen: isOpen, isScrollable: true, children: options?.length ? (_jsx(DropdownList, { name: name, onChange: handleChange, options: options ?? [], value: value })) : isLoading ? (_jsx("div", { children: "Loading..." })) : (_jsx("div", { children: "No results" })) })] })) }));
|
|
36
|
+
}
|
|
37
|
+
export default Autocomplete;
|
|
@@ -36,6 +36,6 @@ function Dropdown({ classNames, classNameProps, hasError, isDisabled, isOptional
|
|
|
36
36
|
return (_jsxs("div", { ref: node, className: tw('relative', componentClassNames?.root?.default, hasError ? componentClassNames?.root?.error : null, isOpen && !isDisabled ? componentClassNames?.root?.focused : null), children: [_jsx(StaticTextInput, { classNames: {
|
|
37
37
|
clear: componentClassNames?.clear,
|
|
38
38
|
icon: componentClassNames?.icon,
|
|
39
|
-
}, details: renderDetails(options, value), hasError: hasError, isDisabled: isDisabled || !options?.length,
|
|
39
|
+
}, details: renderDetails(options, value), hasError: hasError, isDisabled: isDisabled || !options?.length, isOptional: isOptional, label: renderLabel(options, value), name: name, onClear: handleClear, onClick: toggleIsOpen, placeholder: placeholder || 'Select...', value: value ? String(value) : '' }), _jsx(Popover, { align: "center", isOpen: isOpen ? !isDisabled : false, isScrollable: true, children: _jsx(DropdownList, { name: name, onChange: handleChange, options: options, value: value }) })] }));
|
|
40
40
|
}
|
|
41
41
|
export default Dropdown;
|
|
@@ -15,6 +15,8 @@ function DropdownList({ classNames, classNameProps, name, onChange, options, val
|
|
|
15
15
|
});
|
|
16
16
|
};
|
|
17
17
|
}
|
|
18
|
-
return (_jsx("ul", { className: componentClassNames?.list, role: "listbox", children: options.map((item, index) => (_jsx("li", { "aria-selected": isSelected(item.value, value), className: tw('relative', item.isDisabled ? 'pointer-events-none opacity-30' : null, componentClassNames?.item?.default, isSelected(item.value, value)
|
|
18
|
+
return (_jsx("ul", { className: componentClassNames?.list, role: "listbox", children: options.map((item, index) => (_jsx("li", { "aria-selected": isSelected(item.value, value), role: "option", children: _jsxs("button", { className: tw('relative w-full text-left', item.isDisabled ? 'pointer-events-none opacity-30' : null, componentClassNames?.item?.default, isSelected(item.value, value)
|
|
19
|
+
? componentClassNames?.item?.selected
|
|
20
|
+
: null), onClick: handleChange(item), tabIndex: -1, type: "button", children: [_jsx("span", { className: tw('whitespace-nowrap' /*componentClassNames?.label*/), children: item.label }), item.details ? (_jsx("small", { className: tw(componentClassNames?.details), children: item.details })) : null] }) }, index))) }));
|
|
19
21
|
}
|
|
20
22
|
export default DropdownList;
|
|
@@ -1,9 +1,18 @@
|
|
|
1
1
|
import type { FormFieldComponentProps } from '../../interfaces';
|
|
2
|
+
import type { AutocompleteComponentProps } from '../Autocomplete';
|
|
2
3
|
import type { DropdownComponentProps } from '../Dropdown';
|
|
4
|
+
import type { MoneyInputComponentProps } from '../MoneyInput';
|
|
5
|
+
import type { NumberInputComponentProps } from '../NumberInput';
|
|
3
6
|
import type { PasswordInputComponentProps } from '../PasswordInput';
|
|
4
7
|
import type { TextInputComponentProps } from '../TextInput';
|
|
8
|
+
export type AutocompleteFormFieldProps<T> = FormFieldComponentProps<T | null> & AutocompleteComponentProps<T>;
|
|
9
|
+
export declare function AutocompleteFormField<T>(props: Readonly<AutocompleteFormFieldProps<T>>): React.ReactElement;
|
|
5
10
|
export type DropdownFormFieldProps<T> = FormFieldComponentProps<T | null> & DropdownComponentProps<T>;
|
|
6
11
|
export declare function DropdownFormField<T>(props: Readonly<DropdownFormFieldProps<T>>): React.ReactElement;
|
|
12
|
+
export type MoneyFormFieldProps = FormFieldComponentProps<number> & MoneyInputComponentProps;
|
|
13
|
+
export declare function MoneyFormField(props: Readonly<MoneyFormFieldProps>): React.ReactElement;
|
|
14
|
+
export type NumberFormFieldProps = FormFieldComponentProps<number> & NumberInputComponentProps;
|
|
15
|
+
export declare function NumberFormField(props: Readonly<NumberFormFieldProps>): React.ReactElement;
|
|
7
16
|
export type PasswordFormFieldProps = FormFieldComponentProps<string> & PasswordInputComponentProps;
|
|
8
17
|
export declare function PasswordFormField(props: Readonly<PasswordFormFieldProps>): React.ReactElement;
|
|
9
18
|
export type TextFormFieldProps = FormFieldComponentProps<string> & TextInputComponentProps;
|
|
@@ -1,15 +1,33 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
2
|
import { useCallback } from 'react';
|
|
3
3
|
import extractInputProps from '../../utility/extract-input-props';
|
|
4
|
+
import Autocomplete from '../Autocomplete';
|
|
4
5
|
import Dropdown from '../Dropdown';
|
|
5
6
|
import FormField from '../FormField';
|
|
7
|
+
import MoneyInput from '../MoneyInput';
|
|
8
|
+
import NumberInput from '../NumberInput';
|
|
6
9
|
import PasswordInput from '../PasswordInput';
|
|
7
10
|
import TextInput from '../TextInput';
|
|
11
|
+
export function AutocompleteFormField(props) {
|
|
12
|
+
const { fieldProps, inputProps } = extractInputProps(props);
|
|
13
|
+
const renderInput = useCallback((renderProps) => (_jsx(Autocomplete, { ...renderProps, ...inputProps })), [inputProps]);
|
|
14
|
+
return _jsx(FormField, { ...fieldProps, render: renderInput });
|
|
15
|
+
}
|
|
8
16
|
export function DropdownFormField(props) {
|
|
9
17
|
const { fieldProps, inputProps } = extractInputProps(props);
|
|
10
18
|
const renderInput = useCallback((renderProps) => (_jsx(Dropdown, { ...renderProps, ...inputProps })), [inputProps]);
|
|
11
19
|
return _jsx(FormField, { ...fieldProps, render: renderInput });
|
|
12
20
|
}
|
|
21
|
+
export function MoneyFormField(props) {
|
|
22
|
+
const { fieldProps, inputProps } = extractInputProps(props);
|
|
23
|
+
const renderInput = useCallback((renderProps) => (_jsx(MoneyInput, { ...renderProps, ...inputProps })), [inputProps]);
|
|
24
|
+
return _jsx(FormField, { ...fieldProps, render: renderInput });
|
|
25
|
+
}
|
|
26
|
+
export function NumberFormField(props) {
|
|
27
|
+
const { fieldProps, inputProps } = extractInputProps(props);
|
|
28
|
+
const renderInput = useCallback((renderProps) => (_jsx(NumberInput, { ...renderProps, ...inputProps })), [inputProps]);
|
|
29
|
+
return _jsx(FormField, { ...fieldProps, render: renderInput });
|
|
30
|
+
}
|
|
13
31
|
export function PasswordFormField(props) {
|
|
14
32
|
const { fieldProps, inputProps } = extractInputProps(props);
|
|
15
33
|
const renderInput = useCallback((renderProps) => (_jsx(PasswordInput, { ...renderProps, ...inputProps })), [inputProps]);
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { NumberInputComponentProps, NumberInputProps } from '../NumberInput';
|
|
2
|
+
export type MoneyInputComponentProps = NumberInputComponentProps;
|
|
3
|
+
export type MoneyInputProps = NumberInputProps;
|
|
4
|
+
declare function MoneyInput({ name, onChange, prefix, value, ...props }: Readonly<MoneyInputProps>): React.ReactElement;
|
|
5
|
+
export default MoneyInput;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import NumberInput from '../NumberInput';
|
|
3
|
+
const FACTOR = 100;
|
|
4
|
+
function setValue(value) {
|
|
5
|
+
if (typeof value === 'undefined') {
|
|
6
|
+
return value;
|
|
7
|
+
}
|
|
8
|
+
return Math.round(value * FACTOR);
|
|
9
|
+
}
|
|
10
|
+
function getValue(value) {
|
|
11
|
+
if (typeof value === 'undefined') {
|
|
12
|
+
return value;
|
|
13
|
+
}
|
|
14
|
+
return value / FACTOR;
|
|
15
|
+
}
|
|
16
|
+
function MoneyInput({ name, onChange, prefix = '£', value, ...props }) {
|
|
17
|
+
function handleChange(event) {
|
|
18
|
+
onChange?.({ target: { name, value: setValue(event.target.value) } });
|
|
19
|
+
}
|
|
20
|
+
return (_jsx(NumberInput, { prefix: prefix, ...props, name: name, onChange: handleChange, value: getValue(value) }));
|
|
21
|
+
}
|
|
22
|
+
export default MoneyInput;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { ClassNameProps } from '../../../styles/interfaces';
|
|
2
|
+
import type { InputProps } from '../../interfaces';
|
|
3
|
+
import type { TextInputClassNames, TextInputComponentProps } from '../TextInput';
|
|
4
|
+
export type NumberInputComponentProps = TextInputComponentProps;
|
|
5
|
+
export type NumberInputProps = ClassNameProps<TextInputClassNames> & InputProps<number> & NumberInputComponentProps;
|
|
6
|
+
declare function NumberInput({ onChange, value, ...props }: Readonly<NumberInputProps>): React.ReactElement;
|
|
7
|
+
export default NumberInput;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
3
|
+
import { useEffect, useRef } from 'react';
|
|
4
|
+
import TextInput from '../TextInput';
|
|
5
|
+
function NumberInput({ onChange, value, ...props }) {
|
|
6
|
+
const ref = useRef(null);
|
|
7
|
+
function handleChange(event) {
|
|
8
|
+
onChange?.({ target: { name: event.target.name, value: Number(event.target.value) } });
|
|
9
|
+
}
|
|
10
|
+
function disableScroll() {
|
|
11
|
+
if (ref.current) {
|
|
12
|
+
ref.current.blur();
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
useEffect(() => {
|
|
16
|
+
if (ref.current) {
|
|
17
|
+
ref.current.addEventListener('wheel', disableScroll, { passive: false });
|
|
18
|
+
}
|
|
19
|
+
return () => {
|
|
20
|
+
if (ref.current) {
|
|
21
|
+
ref.current.removeEventListener('wheel', disableScroll);
|
|
22
|
+
}
|
|
23
|
+
};
|
|
24
|
+
}, []);
|
|
25
|
+
return (_jsx(TextInput, { ...props, ref: ref, onChange: handleChange, type: "number", value: value ? String(value) : '' }));
|
|
26
|
+
}
|
|
27
|
+
export default NumberInput;
|
|
@@ -12,11 +12,10 @@ export interface StaticTextInputProps extends ClassNameProps<StaticTextInputClas
|
|
|
12
12
|
details?: string | null;
|
|
13
13
|
label: string;
|
|
14
14
|
icon?: React.ReactNode;
|
|
15
|
-
isOpen?: boolean;
|
|
16
15
|
isOptional?: boolean;
|
|
17
16
|
onClear?: () => void;
|
|
18
17
|
onClick?: React.MouseEventHandler<HTMLButtonElement>;
|
|
19
18
|
placeholder?: string;
|
|
20
19
|
}
|
|
21
|
-
declare function StaticTextInput({ classNames, classNameProps, details, hasError, icon, isDisabled,
|
|
20
|
+
declare function StaticTextInput({ classNames, classNameProps, details, hasError, icon, isDisabled, isOptional, label, name, onClear, onClick, onKeyDown, placeholder, value, }: Readonly<StaticTextInputProps>): React.ReactElement;
|
|
22
21
|
export default StaticTextInput;
|
|
@@ -9,7 +9,7 @@ function hasValue(value) {
|
|
|
9
9
|
}
|
|
10
10
|
return Boolean(value);
|
|
11
11
|
}
|
|
12
|
-
function StaticTextInput({ classNames, classNameProps, details, hasError, icon, isDisabled,
|
|
12
|
+
function StaticTextInput({ classNames, classNameProps, details, hasError, icon, isDisabled, isOptional, label, name, onClear, onClick, onKeyDown, placeholder = 'Select...', value, }) {
|
|
13
13
|
const componentClassNames = {
|
|
14
14
|
...getClassNames('staticTextInput')?.(classNameProps),
|
|
15
15
|
...classNames,
|
|
@@ -17,6 +17,6 @@ function StaticTextInput({ classNames, classNameProps, details, hasError, icon,
|
|
|
17
17
|
function handleClear() {
|
|
18
18
|
onClear?.();
|
|
19
19
|
}
|
|
20
|
-
return (_jsxs("div", { className: tw('relative', isDisabled ? 'pointer-events-none opacity-30' : null, componentClassNames.root?.default, hasError ? componentClassNames.root?.error : null), children: [_jsx("input", { name: name, type: "hidden", value: value ? value.toString() : '' }), label ? (_jsxs(Fragment, { children: [_jsx("span", { className: tw(componentClassNames.label), children: label }), details ? (_jsx("small", { className: tw(componentClassNames.details), children: details })) : null] })) : (_jsx("span", { className: tw(componentClassNames.placeholder), children: placeholder })), onClick ? (_jsx("button", { className: "absolute -bottom-px -left-px -right-px -top-px", disabled: isDisabled, onClick: onClick, onKeyDown: onKeyDown, tabIndex: 0, type: "button", children: _jsx(Assistive, { children:
|
|
20
|
+
return (_jsxs("div", { className: tw('relative', isDisabled ? 'pointer-events-none opacity-30' : null, componentClassNames.root?.default, hasError ? componentClassNames.root?.error : null), children: [_jsx("input", { name: name, type: "hidden", value: value ? value.toString() : '' }), label ? (_jsxs(Fragment, { children: [_jsx("span", { className: tw(componentClassNames.label), children: label }), details ? (_jsx("small", { className: tw(componentClassNames.details), children: details })) : null] })) : (_jsx("span", { className: tw(componentClassNames.placeholder), children: placeholder })), onClick ? (_jsx("button", { className: "absolute -bottom-px -left-px -right-px -top-px", disabled: isDisabled, onClick: onClick, onKeyDown: onKeyDown, tabIndex: 0, type: "button", children: _jsx(Assistive, { children: "Toggle" }) })) : null, _jsxs("div", { className: "absolute bottom-0 right-0 top-0 flex w-0 items-center justify-end", children: [isOptional && hasValue(value) ? (_jsx("button", { className: tw('flex-none', componentClassNames.clear), onClick: handleClear, type: "button", children: _jsx(Assistive, { children: "Clear" }) })) : null, icon && !isDisabled ? (_jsx("i", { className: tw('pointer-events-none flex-none', componentClassNames.icon) })) : null] })] }));
|
|
21
21
|
}
|
|
22
22
|
export default StaticTextInput;
|
|
@@ -30,5 +30,5 @@ export type TextInputProps = ClassNameProps<TextInputClassNames> & InputProps<st
|
|
|
30
30
|
* | clear | The wrapper around the 'clear' button of the input, if one exists. The style of the
|
|
31
31
|
* button itself is handled by the `renderClear` prop. | `string` |
|
|
32
32
|
*/
|
|
33
|
-
declare function TextInput({ classNames, classNameProps, hasError, id, isAutocomplete, isDisabled, name, onBlur, onChange, onFocus, onKeyDown, placeholder, prefix, suffix, type, value, }: Readonly<TextInputProps>): React.ReactElement;
|
|
33
|
+
declare function TextInput({ classNames, classNameProps, hasError, id, isAutocomplete, isDisabled, name, onBlur, onChange, onFocus, onKeyDown, placeholder, prefix, ref, suffix, type, value, }: Readonly<TextInputProps>): React.ReactElement;
|
|
34
34
|
export default TextInput;
|
|
@@ -13,7 +13,7 @@ import tw from '../../../styles/tw';
|
|
|
13
13
|
* | clear | The wrapper around the 'clear' button of the input, if one exists. The style of the
|
|
14
14
|
* button itself is handled by the `renderClear` prop. | `string` |
|
|
15
15
|
*/
|
|
16
|
-
function TextInput({ classNames, classNameProps, hasError, id, isAutocomplete, isDisabled, name, onBlur, onChange, onFocus, onKeyDown, placeholder, prefix, suffix, type, value, }) {
|
|
16
|
+
function TextInput({ classNames, classNameProps, hasError, id, isAutocomplete, isDisabled, name, onBlur, onChange, onFocus, onKeyDown, placeholder, prefix, ref, suffix, type, value, }) {
|
|
17
17
|
const componentClassNames = classNames || getClassNames('textInput')?.(classNameProps);
|
|
18
18
|
function handleChange(event) {
|
|
19
19
|
if (onChange) {
|
|
@@ -21,7 +21,7 @@ function TextInput({ classNames, classNameProps, hasError, id, isAutocomplete, i
|
|
|
21
21
|
onChange({ target });
|
|
22
22
|
}
|
|
23
23
|
}
|
|
24
|
-
return (_jsxs("div", { className: tw('relative', prefix ? 'flex flex-row-reverse' : null, (!prefix && suffix) || value ? 'flex' : null, isDisabled ? 'pointer-events-none opacity-30' : null), children: [prefix ? _jsx("div", { children: prefix }) : null, _jsx("input", { "aria-invalid": hasError, "aria-labelledby": hasError
|
|
24
|
+
return (_jsxs("div", { className: tw('relative', prefix ? 'flex flex-row-reverse' : null, (!prefix && suffix) || value ? 'flex' : null, isDisabled ? 'pointer-events-none opacity-30' : null), children: [prefix ? _jsx("div", { children: prefix }) : null, _jsx("input", { ref: ref, "aria-invalid": hasError, "aria-labelledby": hasError
|
|
25
25
|
? `${id || name}_err`
|
|
26
26
|
: undefined /* eslint-disable-line no-undefined */, autoComplete: isAutocomplete === false
|
|
27
27
|
? 'one-time-code'
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { DropdownObject } from '../interfaces';
|
|
2
|
+
import { AutocompleteFormFieldProps } from '../components/FormFields';
|
|
3
|
+
interface UseAutocompleteArgs<T extends string> {
|
|
4
|
+
searchFn: (search: string) => Promise<DropdownObject<T>[]>;
|
|
5
|
+
selectFn: (id: T) => Promise<DropdownObject<T> | null>;
|
|
6
|
+
}
|
|
7
|
+
declare function useAutocomplete<T extends string>(props: AutocompleteFormFieldProps<T>, { searchFn, selectFn }: UseAutocompleteArgs<T>): AutocompleteFormFieldProps<T>;
|
|
8
|
+
export default useAutocomplete;
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { useEffect, useState } from 'react';
|
|
3
|
+
function useAutocomplete(props, { searchFn, selectFn }) {
|
|
4
|
+
const [isLoading, setIsLoading] = useState(false);
|
|
5
|
+
const [options, setOptions] = useState([]);
|
|
6
|
+
const [selected, setSelected] = useState(null);
|
|
7
|
+
async function handleSelect(value) {
|
|
8
|
+
if (!value) {
|
|
9
|
+
setSelected(null);
|
|
10
|
+
return;
|
|
11
|
+
}
|
|
12
|
+
const response = await selectFn(value);
|
|
13
|
+
setOptions([]);
|
|
14
|
+
setSelected(response);
|
|
15
|
+
}
|
|
16
|
+
async function handleSearch(search) {
|
|
17
|
+
if (search.length < 3) {
|
|
18
|
+
setOptions([]);
|
|
19
|
+
return;
|
|
20
|
+
}
|
|
21
|
+
setIsLoading(true);
|
|
22
|
+
const response = await searchFn(search);
|
|
23
|
+
setOptions(response);
|
|
24
|
+
setIsLoading(false);
|
|
25
|
+
}
|
|
26
|
+
useEffect(() => {
|
|
27
|
+
void handleSelect(props.value);
|
|
28
|
+
}, [props.value]);
|
|
29
|
+
return { ...props, isLoading, onSearch: handleSearch, options, selected };
|
|
30
|
+
}
|
|
31
|
+
export default useAutocomplete;
|
package/dist/forms/index.d.ts
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
export * from './interfaces';
|
|
2
|
+
export type { AutocompleteProps } from './components/Autocomplete';
|
|
3
|
+
export { default as Autocomplete } from './components/Autocomplete';
|
|
2
4
|
export type { DropdownClassNames, DropdownProps } from './components/Dropdown';
|
|
3
5
|
export { default as Dropdown } from './components/Dropdown';
|
|
4
6
|
export type { EditableFormClassNames, EditableFormProps } from './components/EditableForm';
|
|
@@ -13,14 +15,19 @@ export type { FormSubmitProps } from './components/FormSubmit';
|
|
|
13
15
|
export { default as FormSubmit } from './components/FormSubmit';
|
|
14
16
|
export type { ModalFormProps } from './components/ModalForm';
|
|
15
17
|
export { default as ModalForm } from './components/ModalForm';
|
|
18
|
+
export type { MoneyInputProps } from './components/MoneyInput';
|
|
19
|
+
export { default as MoneyInput } from './components/MoneyInput';
|
|
20
|
+
export type { NumberInputProps } from './components/NumberInput';
|
|
21
|
+
export { default as NumberInput } from './components/NumberInput';
|
|
16
22
|
export type { PasswordInputClassNames, PasswordInputProps } from './components/PasswordInput';
|
|
17
23
|
export { default as PasswordInput } from './components/PasswordInput';
|
|
18
24
|
export type { TextInputClassNames, TextInputProps } from './components/TextInput';
|
|
19
25
|
export { default as TextInput } from './components/TextInput';
|
|
20
26
|
export type { EditableDropdownFormFieldProps, EditableTextFormFieldProps, } from './components/EditableFormFields';
|
|
21
27
|
export { EditableDropdownFormField, EditableTextFormField } from './components/EditableFormFields';
|
|
22
|
-
export type { DropdownFormFieldProps, PasswordFormFieldProps, TextFormFieldProps, } from './components/FormFields';
|
|
23
|
-
export { DropdownFormField, PasswordFormField, TextFormField } from './components/FormFields';
|
|
28
|
+
export type { AutocompleteFormFieldProps, DropdownFormFieldProps, MoneyFormFieldProps, NumberFormFieldProps, PasswordFormFieldProps, TextFormFieldProps, } from './components/FormFields';
|
|
29
|
+
export { AutocompleteFormField, DropdownFormField, MoneyFormField, NumberFormField, PasswordFormField, TextFormField, } from './components/FormFields';
|
|
30
|
+
export { default as useAutocomplete } from './hooks/useAutocomplete';
|
|
24
31
|
export { default as useDropdown } from './hooks/useDropdown';
|
|
25
32
|
export { default as useEditableForm } from './hooks/useEditableForm';
|
|
26
33
|
export { default as useForm } from './hooks/useForm';
|
package/dist/forms/index.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
export * from './interfaces';
|
|
2
|
+
export { default as Autocomplete } from './components/Autocomplete';
|
|
2
3
|
export { default as Dropdown } from './components/Dropdown';
|
|
3
4
|
export { default as EditableForm } from './components/EditableForm';
|
|
4
5
|
export { default as EditableFormField } from './components/EditableFormField';
|
|
@@ -6,11 +7,14 @@ export { default as Form } from './components/Form';
|
|
|
6
7
|
export { default as FormField } from './components/FormField';
|
|
7
8
|
export { default as FormSubmit } from './components/FormSubmit';
|
|
8
9
|
export { default as ModalForm } from './components/ModalForm';
|
|
10
|
+
export { default as MoneyInput } from './components/MoneyInput';
|
|
11
|
+
export { default as NumberInput } from './components/NumberInput';
|
|
9
12
|
export { default as PasswordInput } from './components/PasswordInput';
|
|
10
13
|
export { default as TextInput } from './components/TextInput';
|
|
11
14
|
export { EditableDropdownFormField, EditableTextFormField } from './components/EditableFormFields';
|
|
12
|
-
export { DropdownFormField, PasswordFormField, TextFormField } from './components/FormFields';
|
|
15
|
+
export { AutocompleteFormField, DropdownFormField, MoneyFormField, NumberFormField, PasswordFormField, TextFormField, } from './components/FormFields';
|
|
13
16
|
// Hooks
|
|
17
|
+
export { default as useAutocomplete } from './hooks/useAutocomplete';
|
|
14
18
|
export { default as useDropdown } from './hooks/useDropdown';
|
|
15
19
|
export { default as useEditableForm } from './hooks/useEditableForm';
|
|
16
20
|
export { default as useForm } from './hooks/useForm';
|
package/dist/hooks/index.d.ts
CHANGED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default as useClickOutside } from './useClickOutside';
|
package/dist/hooks/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
export { default as useClickOutside } from './useClickOutside';
|