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.
@@ -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
- function InfinitySelect({ value, searchValue, defaultSearchValue, nothingFoundMessage, infinity, defaultValue, onChange, onSearchChange, renderOption, onOptionSubmit, getOptionLabel, getOptionValue, onSelectedOptionChange, selectedOption, comboboxProps, searchable = true, defaultSelectedOption = null, loadMoreButtonProps, ...props }) {
12
- const combobox = (0, _mantine_core.useCombobox)();
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 _reset = () => {
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) _reset();
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: () => 40,
56
+ estimateSize: () => OPTION_HEIGHT,
57
+ getItemKey: (index) => getOptionValue(data[index]),
47
58
  overscan: 7,
48
59
  getScrollElement: () => scrollRef.current
49
60
  });
50
- const scrollRef = (0, react.useRef)(null);
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
- onOptionSubmit: (val) => {
55
- const selectedOption = data.find((i) => i && getOptionValue(i) === val);
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: props.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, {}),
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: value ? void 0 : "none",
68
- readOnly: !searchable || props.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 (!props.readOnly) searchable ? combobox.openDropdown() : combobox.toggleDropdown();
130
+ if (!readOnly) searchable ? combobox.openDropdown() : combobox.toggleDropdown();
78
131
  props.onClick?.(event);
79
132
  },
80
133
  onFocus: (event) => {
81
- if (!props.readOnly && searchable) combobox.openDropdown();
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: props.readOnly ? "filled" : "default"
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,EAAqB,MAAM,OAAO,CAAA;AACzD,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,iBAAiB,CAAA;AAE9D,OAAO,EAA0B,KAAK,2BAA2B,EAAE,MAAM,2BAA2B,CAAA;AAEpG,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,GAAG,KAAK,EACT,EAAE,mBAAmB,CAAC,CAAC,CAAC,2CAuKxB"}
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, useCombobox } from "@mantine/core";
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
- function InfinitySelect({ value, searchValue, defaultSearchValue, nothingFoundMessage, infinity, defaultValue, onChange, onSearchChange, renderOption, onOptionSubmit, getOptionLabel, getOptionValue, onSelectedOptionChange, selectedOption, comboboxProps, searchable = true, defaultSelectedOption = null, loadMoreButtonProps, ...props }) {
11
- const combobox = useCombobox();
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 _reset = () => {
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) _reset();
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: () => 40,
55
+ estimateSize: () => OPTION_HEIGHT,
56
+ getItemKey: (index) => getOptionValue(data[index]),
46
57
  overscan: 7,
47
58
  getScrollElement: () => scrollRef.current
48
59
  });
49
- const scrollRef = useRef(null);
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
- onOptionSubmit: (val) => {
54
- const selectedOption = data.find((i) => i && getOptionValue(i) === val);
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: props.readOnly ? null : value ? /* @__PURE__ */ jsx(Input.ClearButton, { onClick: _reset }) : /* @__PURE__ */ jsx(Combobox.Chevron, {}),
115
+ rightSection: readOnly ? null : _value ? /* @__PURE__ */ jsx(Input.ClearButton, { onClick: _reset }) : /* @__PURE__ */ jsx(Combobox.Chevron, {}),
65
116
  component: "input",
66
- rightSectionPointerEvents: value ? void 0 : "none",
67
- readOnly: !searchable || props.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 (!props.readOnly) searchable ? combobox.openDropdown() : combobox.toggleDropdown();
129
+ if (!readOnly) searchable ? combobox.openDropdown() : combobox.toggleDropdown();
77
130
  props.onClick?.(event);
78
131
  },
79
132
  onFocus: (event) => {
80
- if (!props.readOnly && searchable) combobox.openDropdown();
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: props.readOnly ? "filled" : "default"
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.0",
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.3.0",
56
- "@mantine/dates": "^9.3.0",
57
- "@mantine/hooks": "^9.3.0",
58
- "@mantine/notifications": "^9.3.0",
59
- "@tanstack/react-query": "^5.101.0",
60
- "@tanstack/react-virtual": "^3.14.2",
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.7",
63
+ "next": "^16.2.9",
64
64
  "react": "^19.2.7",
65
65
  "react-dom": "^19.2.7",
66
- "react-hook-form": "^7.77.0",
66
+ "react-hook-form": "^7.80.0",
67
67
  "react-query-kit": "^3.3.4",
68
68
  "zod": "^4.4.3"
69
69
  },