lkd-web-kit 0.9.0 → 0.9.2
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/components/EmptyState/index.cjs +3 -0
- package/dist/components/EmptyState/index.d.ts +6 -0
- package/dist/components/EmptyState/index.d.ts.map +1 -1
- package/dist/components/EmptyState/index.js +3 -0
- package/dist/components/InfinitySelect/index.cjs +78 -23
- package/dist/components/InfinitySelect/index.d.ts +1 -1
- package/dist/components/InfinitySelect/index.d.ts.map +1 -1
- package/dist/components/InfinitySelect/index.js +80 -25
- package/package.json +9 -9
|
@@ -8,6 +8,9 @@ var pxBySize = {
|
|
|
8
8
|
md: 60,
|
|
9
9
|
lg: 84
|
|
10
10
|
};
|
|
11
|
+
/**
|
|
12
|
+
* @deprecated Use Mantine's EmptyState from @mantine/core instead.
|
|
13
|
+
*/
|
|
11
14
|
var EmptyState = ({ label, action, icon, size = "md", ...props }) => {
|
|
12
15
|
const { colors } = (0, _mantine_core.useMantineTheme)();
|
|
13
16
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
import { ComponentProps, ReactNode } from 'react';
|
|
2
2
|
import { IconFC } from '../Icon';
|
|
3
|
+
/**
|
|
4
|
+
* @deprecated Use Mantine's EmptyState from @mantine/core instead.
|
|
5
|
+
*/
|
|
3
6
|
export interface EmptyProps extends ComponentProps<'div'> {
|
|
4
7
|
label: ReactNode;
|
|
5
8
|
action?: ReactNode;
|
|
@@ -11,6 +14,9 @@ declare const pxBySize: {
|
|
|
11
14
|
md: number;
|
|
12
15
|
lg: number;
|
|
13
16
|
};
|
|
17
|
+
/**
|
|
18
|
+
* @deprecated Use Mantine's EmptyState from @mantine/core instead.
|
|
19
|
+
*/
|
|
14
20
|
export declare const EmptyState: ({ label, action, icon, size, ...props }: EmptyProps) => import("react/jsx-runtime").JSX.Element;
|
|
15
21
|
export {};
|
|
16
22
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/EmptyState/index.tsx"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AACjD,OAAO,EAAQ,MAAM,EAAE,MAAM,SAAS,CAAA;AAEtC,MAAM,WAAW,UAAW,SAAQ,cAAc,CAAC,KAAK,CAAC;IACvD,KAAK,EAAE,SAAS,CAAA;IAChB,MAAM,CAAC,EAAE,SAAS,CAAA;IAClB,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,IAAI,CAAC,EAAE,MAAM,OAAO,QAAQ,CAAA;CAC7B;AAED,QAAA,MAAM,QAAQ;;;;CAIb,CAAA;AAED,eAAO,MAAM,UAAU,GAAI,yCAAgD,UAAU,4CAkCpF,CAAA"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/EmptyState/index.tsx"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AACjD,OAAO,EAAQ,MAAM,EAAE,MAAM,SAAS,CAAA;AAEtC;;GAEG;AACH,MAAM,WAAW,UAAW,SAAQ,cAAc,CAAC,KAAK,CAAC;IACvD,KAAK,EAAE,SAAS,CAAA;IAChB,MAAM,CAAC,EAAE,SAAS,CAAA;IAClB,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,IAAI,CAAC,EAAE,MAAM,OAAO,QAAQ,CAAA;CAC7B;AAED,QAAA,MAAM,QAAQ;;;;CAIb,CAAA;AAED;;GAEG;AACH,eAAO,MAAM,UAAU,GAAI,yCAAgD,UAAU,4CAkCpF,CAAA"}
|
|
@@ -7,6 +7,9 @@ var pxBySize = {
|
|
|
7
7
|
md: 60,
|
|
8
8
|
lg: 84
|
|
9
9
|
};
|
|
10
|
+
/**
|
|
11
|
+
* @deprecated Use Mantine's EmptyState from @mantine/core instead.
|
|
12
|
+
*/
|
|
10
13
|
var EmptyState = ({ label, action, icon, size = "md", ...props }) => {
|
|
11
14
|
const { colors } = useMantineTheme();
|
|
12
15
|
return /* @__PURE__ */ jsxs("div", {
|
|
@@ -8,8 +8,9 @@ let react_jsx_runtime = require("react/jsx-runtime");
|
|
|
8
8
|
let _mantine_hooks = require("@mantine/hooks");
|
|
9
9
|
let _tanstack_react_virtual = require("@tanstack/react-virtual");
|
|
10
10
|
//#region src/components/InfinitySelect/index.tsx
|
|
11
|
-
|
|
12
|
-
|
|
11
|
+
var OPTION_HEIGHT = 40;
|
|
12
|
+
function InfinitySelect({ value, searchValue, defaultSearchValue, nothingFoundMessage, infinity, defaultValue, onChange, onSearchChange, renderOption, onOptionSubmit, getOptionLabel, getOptionValue, onSelectedOptionChange, selectedOption, comboboxProps, searchable = true, defaultSelectedOption = null, loadMoreButtonProps, resetPageParam, readOnly, ...props }) {
|
|
13
|
+
const isReadOnly = !searchable || readOnly;
|
|
13
14
|
const [_selectedOption, handleSelectedOption] = (0, _mantine_hooks.useUncontrolled)({
|
|
14
15
|
defaultValue: defaultSelectedOption,
|
|
15
16
|
value: selectedOption,
|
|
@@ -25,14 +26,23 @@ function InfinitySelect({ value, searchValue, defaultSearchValue, nothingFoundMe
|
|
|
25
26
|
value: searchValue,
|
|
26
27
|
onChange: onSearchChange
|
|
27
28
|
});
|
|
28
|
-
const data = infinity.data?.pages.flatMap((page) => page.data) ?? [];
|
|
29
|
-
const
|
|
29
|
+
const data = (0, react.useMemo)(() => infinity.data?.pages.flatMap((page) => page.data ?? []) ?? [], [infinity.data]);
|
|
30
|
+
const scrollRef = (0, react.useRef)(null);
|
|
31
|
+
const [selectedOptionIndex, setSelectedOptionIndex] = (0, react.useState)(-1);
|
|
32
|
+
const [activeOptionIndex, setActiveOptionIndex] = (0, react.useState)(-1);
|
|
33
|
+
const resetSelection = (options) => {
|
|
30
34
|
handleSearch("");
|
|
31
35
|
handleValue(null);
|
|
32
36
|
handleSelectedOption(null);
|
|
37
|
+
setActiveOptionIndex(-1);
|
|
38
|
+
setSelectedOptionIndex(-1);
|
|
39
|
+
if (options?.resetPage) resetPageParam?.();
|
|
40
|
+
};
|
|
41
|
+
const _reset = () => {
|
|
42
|
+
resetSelection({ resetPage: true });
|
|
33
43
|
};
|
|
34
44
|
const setSearchAndValue = (option) => {
|
|
35
|
-
if (option === null)
|
|
45
|
+
if (option === null) resetSelection();
|
|
36
46
|
else {
|
|
37
47
|
handleSearch(getOptionLabel(option));
|
|
38
48
|
handleValue(getOptionValue(option));
|
|
@@ -43,42 +53,85 @@ function InfinitySelect({ value, searchValue, defaultSearchValue, nothingFoundMe
|
|
|
43
53
|
}, [_selectedOption]);
|
|
44
54
|
const virtualizer = (0, _tanstack_react_virtual.useVirtualizer)({
|
|
45
55
|
count: data.length,
|
|
46
|
-
estimateSize: () =>
|
|
56
|
+
estimateSize: () => OPTION_HEIGHT,
|
|
57
|
+
getItemKey: (index) => getOptionValue(data[index]),
|
|
47
58
|
overscan: 7,
|
|
48
59
|
getScrollElement: () => scrollRef.current
|
|
49
60
|
});
|
|
50
|
-
const
|
|
61
|
+
const combobox = (0, _mantine_core.useVirtualizedCombobox)({
|
|
62
|
+
onDropdownOpen: () => {
|
|
63
|
+
if (activeOptionIndex >= 0 && activeOptionIndex < data.length) {
|
|
64
|
+
setSelectedOptionIndex(activeOptionIndex);
|
|
65
|
+
requestAnimationFrame(() => {
|
|
66
|
+
virtualizer.scrollToIndex(activeOptionIndex, { align: "auto" });
|
|
67
|
+
});
|
|
68
|
+
} else setSelectedOptionIndex(-1);
|
|
69
|
+
},
|
|
70
|
+
onDropdownClose: () => setSelectedOptionIndex(-1),
|
|
71
|
+
totalOptionsCount: data.length,
|
|
72
|
+
isOptionDisabled: (index) => index < 0 || index >= data.length,
|
|
73
|
+
getOptionId: (index) => {
|
|
74
|
+
return index >= 0 && index < data.length ? getOptionValue(data[index]) : null;
|
|
75
|
+
},
|
|
76
|
+
selectedOptionIndex,
|
|
77
|
+
activeOptionIndex,
|
|
78
|
+
setSelectedOptionIndex: (index) => {
|
|
79
|
+
setSelectedOptionIndex(index);
|
|
80
|
+
if (index !== -1) virtualizer.scrollToIndex(index, { align: "auto" });
|
|
81
|
+
},
|
|
82
|
+
onSelectedOptionSubmit: handleOptionSubmit
|
|
83
|
+
});
|
|
84
|
+
(0, react.useEffect)(() => {
|
|
85
|
+
setActiveOptionIndex(_value ? data.findIndex((option) => getOptionValue(option) === _value) : -1);
|
|
86
|
+
}, [
|
|
87
|
+
_value,
|
|
88
|
+
data,
|
|
89
|
+
getOptionValue
|
|
90
|
+
]);
|
|
91
|
+
(0, react.useEffect)(() => {
|
|
92
|
+
setSelectedOptionIndex(-1);
|
|
93
|
+
scrollRef.current?.scrollTo({ top: 0 });
|
|
94
|
+
}, [_search]);
|
|
95
|
+
(0, react.useEffect)(() => {
|
|
96
|
+
if (selectedOptionIndex >= data.length) setSelectedOptionIndex(-1);
|
|
97
|
+
}, [selectedOptionIndex, data.length]);
|
|
98
|
+
function handleOptionSubmit(index) {
|
|
99
|
+
if (index < 0 || index >= data.length) return;
|
|
100
|
+
const selectedOption = data[index];
|
|
101
|
+
const selectedValue = getOptionValue(selectedOption);
|
|
102
|
+
setSearchAndValue(selectedOption);
|
|
103
|
+
handleSelectedOption(selectedOption);
|
|
104
|
+
setActiveOptionIndex(index);
|
|
105
|
+
onOptionSubmit?.(selectedValue, selectedOption);
|
|
106
|
+
combobox.closeDropdown();
|
|
107
|
+
combobox.resetSelectedOption();
|
|
108
|
+
}
|
|
51
109
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(_mantine_core.Combobox, {
|
|
52
110
|
store: combobox,
|
|
53
111
|
middlewares: { shift: { crossAxis: true } },
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
if (selectedOption) {
|
|
57
|
-
setSearchAndValue(selectedOption);
|
|
58
|
-
handleSelectedOption(selectedOption);
|
|
59
|
-
onOptionSubmit?.(val, selectedOption);
|
|
60
|
-
}
|
|
61
|
-
combobox.closeDropdown();
|
|
62
|
-
},
|
|
112
|
+
resetSelectionOnOptionHover: false,
|
|
113
|
+
keepMounted: true,
|
|
63
114
|
...comboboxProps,
|
|
64
115
|
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(_mantine_core.Combobox.Target, { children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_mantine_core.InputBase, {
|
|
65
|
-
rightSection:
|
|
116
|
+
rightSection: readOnly ? null : _value ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_mantine_core.Input.ClearButton, { onClick: _reset }) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_mantine_core.Combobox.Chevron, {}),
|
|
66
117
|
component: "input",
|
|
67
|
-
rightSectionPointerEvents:
|
|
68
|
-
readOnly:
|
|
118
|
+
rightSectionPointerEvents: _value ? void 0 : "none",
|
|
119
|
+
readOnly: isReadOnly,
|
|
69
120
|
pointer: !searchable,
|
|
70
121
|
value: searchable ? _search : _selectedOption ? getOptionLabel(_selectedOption) : "",
|
|
71
122
|
onChange: searchable ? (event) => {
|
|
72
123
|
if (event.currentTarget.value) combobox.openDropdown();
|
|
73
124
|
else combobox.closeDropdown();
|
|
125
|
+
setSelectedOptionIndex(-1);
|
|
74
126
|
handleSearch(event.currentTarget.value);
|
|
127
|
+
resetPageParam?.();
|
|
75
128
|
} : void 0,
|
|
76
129
|
onClick: (event) => {
|
|
77
|
-
if (!
|
|
130
|
+
if (!readOnly) searchable ? combobox.openDropdown() : combobox.toggleDropdown();
|
|
78
131
|
props.onClick?.(event);
|
|
79
132
|
},
|
|
80
133
|
onFocus: (event) => {
|
|
81
|
-
if (!
|
|
134
|
+
if (!readOnly && searchable) combobox.openDropdown();
|
|
82
135
|
props.onFocus?.(event);
|
|
83
136
|
},
|
|
84
137
|
onBlur: (event) => {
|
|
@@ -87,7 +140,7 @@ function InfinitySelect({ value, searchValue, defaultSearchValue, nothingFoundMe
|
|
|
87
140
|
props.onBlur?.(event);
|
|
88
141
|
},
|
|
89
142
|
...props,
|
|
90
|
-
variant:
|
|
143
|
+
variant: readOnly ? "filled" : "default"
|
|
91
144
|
}) }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_mantine_core.Combobox.Dropdown, { children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_mantine_core.Combobox.Options, {
|
|
92
145
|
mih: 50,
|
|
93
146
|
mah: 200,
|
|
@@ -98,10 +151,12 @@ function InfinitySelect({ value, searchValue, defaultSearchValue, nothingFoundMe
|
|
|
98
151
|
children: virtualizer.getVirtualItems().map((virtualItem) => {
|
|
99
152
|
const option = data[virtualItem.index];
|
|
100
153
|
const virtualItemProps = require_virtual_styles.getVirtualItemProps(virtualItem, virtualizer);
|
|
101
|
-
if (!option) return null;
|
|
102
154
|
return /* @__PURE__ */ (0, react.createElement)(_mantine_core.Combobox.Option, {
|
|
103
155
|
value: getOptionValue(option),
|
|
104
156
|
...virtualItemProps,
|
|
157
|
+
active: virtualItem.index === activeOptionIndex,
|
|
158
|
+
selected: virtualItem.index === selectedOptionIndex,
|
|
159
|
+
onClick: () => handleOptionSubmit(virtualItem.index),
|
|
105
160
|
key: virtualItemProps.key,
|
|
106
161
|
style: {
|
|
107
162
|
...virtualItemProps.style,
|
|
@@ -31,5 +31,5 @@ export interface InfinitySelectProps<T = unknown> extends InputBaseProps, Elemen
|
|
|
31
31
|
ref?: React.Ref<HTMLInputElement>;
|
|
32
32
|
loadMoreButtonProps?: Partial<InfinityLoadMoreButtonProps<T>>;
|
|
33
33
|
}
|
|
34
|
-
export declare function InfinitySelect<T = unknown>({ value, searchValue, defaultSearchValue, nothingFoundMessage, infinity, defaultValue, onChange, onSearchChange, renderOption, onOptionSubmit, getOptionLabel, getOptionValue, onSelectedOptionChange, selectedOption, comboboxProps, searchable, defaultSelectedOption, loadMoreButtonProps, ...props }: InfinitySelectProps<T>): import("react/jsx-runtime").JSX.Element;
|
|
34
|
+
export declare function InfinitySelect<T = unknown>({ value, searchValue, defaultSearchValue, nothingFoundMessage, infinity, defaultValue, onChange, onSearchChange, renderOption, onOptionSubmit, getOptionLabel, getOptionValue, onSelectedOptionChange, selectedOption, comboboxProps, searchable, defaultSelectedOption, loadMoreButtonProps, resetPageParam, readOnly, ...props }: InfinitySelectProps<T>): import("react/jsx-runtime").JSX.Element;
|
|
35
35
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/InfinitySelect/index.tsx"],"names":[],"mappings":"AACA,OAAO,EAGL,KAAK,aAAa,EAClB,KAAK,aAAa,EAClB,KAAK,YAAY,EAGjB,KAAK,cAAc,EAEpB,MAAM,eAAe,CAAA;AAEtB,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAA;AAEzD,OAAO,EAAE,KAAK,SAAS,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/InfinitySelect/index.tsx"],"names":[],"mappings":"AACA,OAAO,EAGL,KAAK,aAAa,EAClB,KAAK,aAAa,EAClB,KAAK,YAAY,EAGjB,KAAK,cAAc,EAEpB,MAAM,eAAe,CAAA;AAEtB,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAA;AAEzD,OAAO,EAAE,KAAK,SAAS,EAAwC,MAAM,OAAO,CAAA;AAC5E,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,iBAAiB,CAAA;AAE9D,OAAO,EAA0B,KAAK,2BAA2B,EAAE,MAAM,2BAA2B,CAAA;AAIpG,MAAM,WAAW,mBAAmB,CAAC,CAAC,GAAG,OAAO,CAC9C,SAAQ,cAAc,EACpB,YAAY,CAAC,OAAO,EAAE,MAAM,cAAc,GAAG,OAAO,GAAG,UAAU,CAAC;IACpE,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACrB,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,kBAAkB,CAAC,EAAE,MAAM,CAAA;IAC3B,mBAAmB,CAAC,EAAE,SAAS,GAAG,CAAC,CAAC,IAAI,EAAE;QAAE,QAAQ,EAAE,aAAa,CAAA;KAAE,KAAK,SAAS,CAAC,CAAA;IACpF,QAAQ,EAAE,uBAAuB,CAAC,YAAY,CAAC;QAAE,IAAI,CAAC,EAAE,CAAC,EAAE,CAAA;KAAE,EAAE,MAAM,CAAC,EAAE,KAAK,CAAC,CAAA;IAC9E,qBAAqB,CAAC,EAAE,CAAC,GAAG,IAAI,CAAA;IAChC,cAAc,CAAC,EAAE,CAAC,GAAG,IAAI,CAAA;IACzB,sBAAsB,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,GAAG,IAAI,KAAK,IAAI,CAAA;IACnD,cAAc,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAA;IACxC,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,KAAK,IAAI,CAAA;IACzC,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE;QAAE,MAAM,EAAE,CAAC,CAAA;KAAE,KAAK,KAAK,CAAC,SAAS,CAAA;IACvD,cAAc,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,KAAK,IAAI,CAAA;IACnD,cAAc,EAAE,CAAC,MAAM,EAAE,CAAC,KAAK,MAAM,CAAA;IACrC,cAAc,EAAE,CAAC,MAAM,EAAE,CAAC,KAAK,MAAM,CAAA;IACrC,cAAc,CAAC,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAA;IACpC,aAAa,CAAC,EAAE,aAAa,CAAA;IAC7B,UAAU,CAAC,EAAE,OAAO,CAAA;IACpB,GAAG,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,gBAAgB,CAAC,CAAA;IACjC,mBAAmB,CAAC,EAAE,OAAO,CAAC,2BAA2B,CAAC,CAAC,CAAC,CAAC,CAAA;CAC9D;AAED,wBAAgB,cAAc,CAAC,CAAC,GAAG,OAAO,EAAE,EAC1C,KAAK,EACL,WAAW,EACX,kBAAkB,EAClB,mBAAmB,EACnB,QAAQ,EACR,YAAY,EACZ,QAAQ,EACR,cAAc,EACd,YAAY,EACZ,cAAc,EACd,cAAc,EACd,cAAc,EACd,sBAAsB,EACtB,cAAc,EACd,aAAa,EACb,UAAiB,EACjB,qBAA4B,EAC5B,mBAAmB,EACnB,cAAc,EACd,QAAQ,EACR,GAAG,KAAK,EACT,EAAE,mBAAmB,CAAC,CAAC,CAAC,2CA8OxB"}
|
|
@@ -1,14 +1,15 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { InfinityLoadMoreButton } from "../InfinityLoadMoreButton/index.js";
|
|
3
3
|
import { getVirtualContainerProps, getVirtualItemProps } from "../../utils/virtual-styles.js";
|
|
4
|
-
import { Center, Combobox, Input, InputBase,
|
|
5
|
-
import { createElement, useEffect, useRef } from "react";
|
|
4
|
+
import { Center, Combobox, Input, InputBase, useVirtualizedCombobox } from "@mantine/core";
|
|
5
|
+
import { createElement, useEffect, useMemo, useRef, useState } from "react";
|
|
6
6
|
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
7
7
|
import { useUncontrolled } from "@mantine/hooks";
|
|
8
8
|
import { useVirtualizer } from "@tanstack/react-virtual";
|
|
9
9
|
//#region src/components/InfinitySelect/index.tsx
|
|
10
|
-
|
|
11
|
-
|
|
10
|
+
var OPTION_HEIGHT = 40;
|
|
11
|
+
function InfinitySelect({ value, searchValue, defaultSearchValue, nothingFoundMessage, infinity, defaultValue, onChange, onSearchChange, renderOption, onOptionSubmit, getOptionLabel, getOptionValue, onSelectedOptionChange, selectedOption, comboboxProps, searchable = true, defaultSelectedOption = null, loadMoreButtonProps, resetPageParam, readOnly, ...props }) {
|
|
12
|
+
const isReadOnly = !searchable || readOnly;
|
|
12
13
|
const [_selectedOption, handleSelectedOption] = useUncontrolled({
|
|
13
14
|
defaultValue: defaultSelectedOption,
|
|
14
15
|
value: selectedOption,
|
|
@@ -24,14 +25,23 @@ function InfinitySelect({ value, searchValue, defaultSearchValue, nothingFoundMe
|
|
|
24
25
|
value: searchValue,
|
|
25
26
|
onChange: onSearchChange
|
|
26
27
|
});
|
|
27
|
-
const data = infinity.data?.pages.flatMap((page) => page.data) ?? [];
|
|
28
|
-
const
|
|
28
|
+
const data = useMemo(() => infinity.data?.pages.flatMap((page) => page.data ?? []) ?? [], [infinity.data]);
|
|
29
|
+
const scrollRef = useRef(null);
|
|
30
|
+
const [selectedOptionIndex, setSelectedOptionIndex] = useState(-1);
|
|
31
|
+
const [activeOptionIndex, setActiveOptionIndex] = useState(-1);
|
|
32
|
+
const resetSelection = (options) => {
|
|
29
33
|
handleSearch("");
|
|
30
34
|
handleValue(null);
|
|
31
35
|
handleSelectedOption(null);
|
|
36
|
+
setActiveOptionIndex(-1);
|
|
37
|
+
setSelectedOptionIndex(-1);
|
|
38
|
+
if (options?.resetPage) resetPageParam?.();
|
|
39
|
+
};
|
|
40
|
+
const _reset = () => {
|
|
41
|
+
resetSelection({ resetPage: true });
|
|
32
42
|
};
|
|
33
43
|
const setSearchAndValue = (option) => {
|
|
34
|
-
if (option === null)
|
|
44
|
+
if (option === null) resetSelection();
|
|
35
45
|
else {
|
|
36
46
|
handleSearch(getOptionLabel(option));
|
|
37
47
|
handleValue(getOptionValue(option));
|
|
@@ -42,42 +52,85 @@ function InfinitySelect({ value, searchValue, defaultSearchValue, nothingFoundMe
|
|
|
42
52
|
}, [_selectedOption]);
|
|
43
53
|
const virtualizer = useVirtualizer({
|
|
44
54
|
count: data.length,
|
|
45
|
-
estimateSize: () =>
|
|
55
|
+
estimateSize: () => OPTION_HEIGHT,
|
|
56
|
+
getItemKey: (index) => getOptionValue(data[index]),
|
|
46
57
|
overscan: 7,
|
|
47
58
|
getScrollElement: () => scrollRef.current
|
|
48
59
|
});
|
|
49
|
-
const
|
|
60
|
+
const combobox = useVirtualizedCombobox({
|
|
61
|
+
onDropdownOpen: () => {
|
|
62
|
+
if (activeOptionIndex >= 0 && activeOptionIndex < data.length) {
|
|
63
|
+
setSelectedOptionIndex(activeOptionIndex);
|
|
64
|
+
requestAnimationFrame(() => {
|
|
65
|
+
virtualizer.scrollToIndex(activeOptionIndex, { align: "auto" });
|
|
66
|
+
});
|
|
67
|
+
} else setSelectedOptionIndex(-1);
|
|
68
|
+
},
|
|
69
|
+
onDropdownClose: () => setSelectedOptionIndex(-1),
|
|
70
|
+
totalOptionsCount: data.length,
|
|
71
|
+
isOptionDisabled: (index) => index < 0 || index >= data.length,
|
|
72
|
+
getOptionId: (index) => {
|
|
73
|
+
return index >= 0 && index < data.length ? getOptionValue(data[index]) : null;
|
|
74
|
+
},
|
|
75
|
+
selectedOptionIndex,
|
|
76
|
+
activeOptionIndex,
|
|
77
|
+
setSelectedOptionIndex: (index) => {
|
|
78
|
+
setSelectedOptionIndex(index);
|
|
79
|
+
if (index !== -1) virtualizer.scrollToIndex(index, { align: "auto" });
|
|
80
|
+
},
|
|
81
|
+
onSelectedOptionSubmit: handleOptionSubmit
|
|
82
|
+
});
|
|
83
|
+
useEffect(() => {
|
|
84
|
+
setActiveOptionIndex(_value ? data.findIndex((option) => getOptionValue(option) === _value) : -1);
|
|
85
|
+
}, [
|
|
86
|
+
_value,
|
|
87
|
+
data,
|
|
88
|
+
getOptionValue
|
|
89
|
+
]);
|
|
90
|
+
useEffect(() => {
|
|
91
|
+
setSelectedOptionIndex(-1);
|
|
92
|
+
scrollRef.current?.scrollTo({ top: 0 });
|
|
93
|
+
}, [_search]);
|
|
94
|
+
useEffect(() => {
|
|
95
|
+
if (selectedOptionIndex >= data.length) setSelectedOptionIndex(-1);
|
|
96
|
+
}, [selectedOptionIndex, data.length]);
|
|
97
|
+
function handleOptionSubmit(index) {
|
|
98
|
+
if (index < 0 || index >= data.length) return;
|
|
99
|
+
const selectedOption = data[index];
|
|
100
|
+
const selectedValue = getOptionValue(selectedOption);
|
|
101
|
+
setSearchAndValue(selectedOption);
|
|
102
|
+
handleSelectedOption(selectedOption);
|
|
103
|
+
setActiveOptionIndex(index);
|
|
104
|
+
onOptionSubmit?.(selectedValue, selectedOption);
|
|
105
|
+
combobox.closeDropdown();
|
|
106
|
+
combobox.resetSelectedOption();
|
|
107
|
+
}
|
|
50
108
|
return /* @__PURE__ */ jsxs(Combobox, {
|
|
51
109
|
store: combobox,
|
|
52
110
|
middlewares: { shift: { crossAxis: true } },
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
if (selectedOption) {
|
|
56
|
-
setSearchAndValue(selectedOption);
|
|
57
|
-
handleSelectedOption(selectedOption);
|
|
58
|
-
onOptionSubmit?.(val, selectedOption);
|
|
59
|
-
}
|
|
60
|
-
combobox.closeDropdown();
|
|
61
|
-
},
|
|
111
|
+
resetSelectionOnOptionHover: false,
|
|
112
|
+
keepMounted: true,
|
|
62
113
|
...comboboxProps,
|
|
63
114
|
children: [/* @__PURE__ */ jsx(Combobox.Target, { children: /* @__PURE__ */ jsx(InputBase, {
|
|
64
|
-
rightSection:
|
|
115
|
+
rightSection: readOnly ? null : _value ? /* @__PURE__ */ jsx(Input.ClearButton, { onClick: _reset }) : /* @__PURE__ */ jsx(Combobox.Chevron, {}),
|
|
65
116
|
component: "input",
|
|
66
|
-
rightSectionPointerEvents:
|
|
67
|
-
readOnly:
|
|
117
|
+
rightSectionPointerEvents: _value ? void 0 : "none",
|
|
118
|
+
readOnly: isReadOnly,
|
|
68
119
|
pointer: !searchable,
|
|
69
120
|
value: searchable ? _search : _selectedOption ? getOptionLabel(_selectedOption) : "",
|
|
70
121
|
onChange: searchable ? (event) => {
|
|
71
122
|
if (event.currentTarget.value) combobox.openDropdown();
|
|
72
123
|
else combobox.closeDropdown();
|
|
124
|
+
setSelectedOptionIndex(-1);
|
|
73
125
|
handleSearch(event.currentTarget.value);
|
|
126
|
+
resetPageParam?.();
|
|
74
127
|
} : void 0,
|
|
75
128
|
onClick: (event) => {
|
|
76
|
-
if (!
|
|
129
|
+
if (!readOnly) searchable ? combobox.openDropdown() : combobox.toggleDropdown();
|
|
77
130
|
props.onClick?.(event);
|
|
78
131
|
},
|
|
79
132
|
onFocus: (event) => {
|
|
80
|
-
if (!
|
|
133
|
+
if (!readOnly && searchable) combobox.openDropdown();
|
|
81
134
|
props.onFocus?.(event);
|
|
82
135
|
},
|
|
83
136
|
onBlur: (event) => {
|
|
@@ -86,7 +139,7 @@ function InfinitySelect({ value, searchValue, defaultSearchValue, nothingFoundMe
|
|
|
86
139
|
props.onBlur?.(event);
|
|
87
140
|
},
|
|
88
141
|
...props,
|
|
89
|
-
variant:
|
|
142
|
+
variant: readOnly ? "filled" : "default"
|
|
90
143
|
}) }), /* @__PURE__ */ jsx(Combobox.Dropdown, { children: /* @__PURE__ */ jsx(Combobox.Options, {
|
|
91
144
|
mih: 50,
|
|
92
145
|
mah: 200,
|
|
@@ -97,10 +150,12 @@ function InfinitySelect({ value, searchValue, defaultSearchValue, nothingFoundMe
|
|
|
97
150
|
children: virtualizer.getVirtualItems().map((virtualItem) => {
|
|
98
151
|
const option = data[virtualItem.index];
|
|
99
152
|
const virtualItemProps = getVirtualItemProps(virtualItem, virtualizer);
|
|
100
|
-
if (!option) return null;
|
|
101
153
|
return /* @__PURE__ */ createElement(Combobox.Option, {
|
|
102
154
|
value: getOptionValue(option),
|
|
103
155
|
...virtualItemProps,
|
|
156
|
+
active: virtualItem.index === activeOptionIndex,
|
|
157
|
+
selected: virtualItem.index === selectedOptionIndex,
|
|
158
|
+
onClick: () => handleOptionSubmit(virtualItem.index),
|
|
104
159
|
key: virtualItemProps.key,
|
|
105
160
|
style: {
|
|
106
161
|
...virtualItemProps.style,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "lkd-web-kit",
|
|
3
|
-
"version": "0.9.
|
|
3
|
+
"version": "0.9.2",
|
|
4
4
|
"description": "A template for creating React component libraries with Vite.",
|
|
5
5
|
"author": "LKD",
|
|
6
6
|
"license": "MIT",
|
|
@@ -52,18 +52,18 @@
|
|
|
52
52
|
"vitest": "^4.1.5"
|
|
53
53
|
},
|
|
54
54
|
"peerDependencies": {
|
|
55
|
-
"@mantine/core": "^9.
|
|
56
|
-
"@mantine/dates": "^9.
|
|
57
|
-
"@mantine/hooks": "^9.
|
|
58
|
-
"@mantine/notifications": "^9.
|
|
59
|
-
"@tanstack/react-query": "^5.101.
|
|
60
|
-
"@tanstack/react-virtual": "^3.14.
|
|
55
|
+
"@mantine/core": "^9.4.1",
|
|
56
|
+
"@mantine/dates": "^9.4.1",
|
|
57
|
+
"@mantine/hooks": "^9.4.1",
|
|
58
|
+
"@mantine/notifications": "^9.4.1",
|
|
59
|
+
"@tanstack/react-query": "^5.101.2",
|
|
60
|
+
"@tanstack/react-virtual": "^3.14.4",
|
|
61
61
|
"clsx": "^2.1.1",
|
|
62
62
|
"ky": "^2.0.2",
|
|
63
|
-
"next": "^16.2.
|
|
63
|
+
"next": "^16.2.9",
|
|
64
64
|
"react": "^19.2.7",
|
|
65
65
|
"react-dom": "^19.2.7",
|
|
66
|
-
"react-hook-form": "^7.
|
|
66
|
+
"react-hook-form": "^7.80.0",
|
|
67
67
|
"react-query-kit": "^3.3.4",
|
|
68
68
|
"zod": "^4.4.3"
|
|
69
69
|
},
|