@konstructio/ui 0.1.2-alpha.23 → 0.1.2-alpha.24

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.
@@ -1,42 +1,48 @@
1
- import { jsx as t, jsxs as p } from "react/jsx-runtime";
2
- import { forwardRef as n } from "react";
3
- import { DropdownProvider as c } from "./contexts/dropdown.provider.js";
4
- import { Wrapper as x } from "./components/Wrapper.js";
5
- const N = n(
1
+ import { jsx as s, jsxs as w } from "react/jsx-runtime";
2
+ import { forwardRef as h } from "react";
3
+ import { cn as o } from "../../utils/index.js";
4
+ import { DropdownProvider as v } from "./contexts/dropdown.provider.js";
5
+ import { Wrapper as N } from "./components/Wrapper.js";
6
+ const W = h(
6
7
  ({
7
- onChange: r,
8
- onBlur: l,
9
- value: a,
10
- error: s,
11
- helperText: e,
12
- name: o,
13
- highlightSearch: i,
14
- ...d
15
- }, m) => /* @__PURE__ */ t(
16
- c,
8
+ error: t,
9
+ errorClassName: i,
10
+ helperText: r,
11
+ helperTextClassName: m,
12
+ highlightSearch: a,
13
+ mainWrapperClassName: p,
14
+ name: l,
15
+ value: d,
16
+ options: n,
17
+ onChange: c,
18
+ onBlur: e,
19
+ ...f
20
+ }, x) => /* @__PURE__ */ s(
21
+ v,
17
22
  {
18
- highlightSearch: i,
19
- name: o,
20
- value: a,
21
- onBlur: l,
22
- onChange: r,
23
- children: /* @__PURE__ */ p("div", { className: "relative w-full", children: [
24
- /* @__PURE__ */ t(
25
- x,
23
+ highlightSearch: a,
24
+ name: l,
25
+ value: d,
26
+ options: n,
27
+ onBlur: e,
28
+ onChange: c,
29
+ children: /* @__PURE__ */ w("div", { className: o("relative w-full", p), children: [
30
+ /* @__PURE__ */ s(
31
+ N,
26
32
  {
27
- name: o,
28
- error: s,
29
- ref: m,
30
- onBlur: l,
31
- ...d
33
+ error: t,
34
+ name: l,
35
+ ref: x,
36
+ onBlur: e,
37
+ ...f
32
38
  }
33
39
  ),
34
- s ? /* @__PURE__ */ t("span", { className: "text-xs text-red-700", children: s }) : null,
35
- !s && e ? /* @__PURE__ */ t("span", { className: "text-xs text-slate-600", children: e }) : null
40
+ t ? /* @__PURE__ */ s("span", { className: o("text-xs text-red-700", i), children: t }) : null,
41
+ !t && r ? /* @__PURE__ */ s("span", { className: o("text-xs text-slate-600", m), children: r }) : null
36
42
  ] })
37
43
  }
38
44
  )
39
45
  );
40
46
  export {
41
- N as Dropdown
47
+ W as Dropdown
42
48
  };
@@ -1,83 +1,145 @@
1
- import { jsx as l, jsxs as w, Fragment as N } from "react/jsx-runtime";
2
- import { forwardRef as y, useRef as j, useImperativeHandle as C } from "react";
3
- import { cn as t } from "../../../../utils/index.js";
4
- import { useNavigationUlList as O } from "../../hooks/useNavigationList.js";
5
- import { ListItem as i } from "../ListItem/ListItem.js";
6
- import { listVariants as D } from "./List.variants.js";
7
- import { S as E } from "../../../../index-BtQfgaSF.js";
8
- import { useDropdownContext as F } from "../../contexts/dropdown.hook.js";
9
- const I = y(
1
+ import { jsxs as z, jsx as r } from "react/jsx-runtime";
2
+ import { S as A } from "../../../../index-BtQfgaSF.js";
3
+ import { d as H } from "../../../../debounce-BFejQm9P.js";
4
+ import { forwardRef as V, useRef as y, useState as Z, useImperativeHandle as B, useCallback as G, useEffect as J } from "react";
5
+ import { Loading as K } from "../../../Loading/Loading.js";
6
+ import { cn as i } from "../../../../utils/index.js";
7
+ import { useNavigationUlList as Q } from "../../hooks/useNavigationList.js";
8
+ import { ListItem as L } from "../ListItem/ListItem.js";
9
+ import { listVariants as R } from "./List.variants.js";
10
+ import { DEFAULT_LIST_SIZE as W } from "../../constants/pagination.js";
11
+ import { useDropdownContext as X } from "../../contexts/dropdown.hook.js";
12
+ const ie = V(
10
13
  ({
11
- additionalOptions: p,
12
- className: u,
13
- inputRef: r,
14
- isLoading: d,
15
- itemClassName: s,
16
- name: g,
17
- options: c,
18
- searchable: m = !1,
19
- listItemSecondRowClassName: a,
20
- wrapperInputRef: b,
21
- wrapperRef: h
22
- }, v) => {
23
- const o = j(null), { isOpen: L, searchTerm: x } = F();
24
- C(v, () => o.current, [o]), O({
25
- ulRef: o,
26
- wrapperRef: h,
27
- wrapperInputRef: b,
28
- inputRef: r,
29
- searchable: m
14
+ additionalOptions: k,
15
+ className: C,
16
+ inputRef: c,
17
+ isLoading: N,
18
+ itemClassName: f,
19
+ name: F,
20
+ searchable: x = !1,
21
+ listItemSecondRowClassName: u,
22
+ wrapperInputRef: I,
23
+ isInfiniteScrollEnabled: m,
24
+ onFetchMoreOptions: n
25
+ }, j) => {
26
+ const a = y(null), p = y(null), [g, w] = Z(!1), {
27
+ isOpen: E,
28
+ searchTerm: l,
29
+ canFilter: O,
30
+ canContinueFetching: o,
31
+ page: d,
32
+ options: h,
33
+ setOptions: P,
34
+ setPage: S,
35
+ setCanContinueFetching: T
36
+ } = X();
37
+ B(j, () => a.current, [a]);
38
+ const b = x && O ? h.filter((e) => {
39
+ const t = l.toLowerCase();
40
+ return (typeof e.label == "string" ? e.label.toLowerCase() : "").includes(t);
41
+ }) : h;
42
+ Q({
43
+ ulRef: a,
44
+ wrapperInputRef: I,
45
+ searchable: x,
46
+ filteredOptions: b
30
47
  });
31
- const f = m ? c.filter((e) => {
32
- const n = x.toLowerCase();
33
- return (typeof e.label == "string" ? e.label.toLowerCase() : "").includes(n);
34
- }) : c, k = f.length === 0;
35
- return /* @__PURE__ */ l(
48
+ const D = b.filter(
49
+ (e, t, s) => t === s.findIndex((v) => v.value === e.value)
50
+ ), U = b.length === 0, _ = G(
51
+ H(async (e) => {
52
+ const [t] = e;
53
+ if (t.isIntersecting)
54
+ try {
55
+ if (n && !g && o) {
56
+ w(!0);
57
+ const s = d + 1, { data: v, hasMore: q } = await n({
58
+ page: s,
59
+ pageSize: W,
60
+ termOfSearch: l
61
+ });
62
+ S(s), T(q), P([...h, ...v]);
63
+ }
64
+ } catch {
65
+ console.error("Error fetching more options");
66
+ } finally {
67
+ w(!1);
68
+ }
69
+ }, 100),
70
+ [d, n, l, o, g]
71
+ );
72
+ return J(() => {
73
+ if (m && o && p.current) {
74
+ const e = new IntersectionObserver(_, {
75
+ threshold: 0.1
76
+ });
77
+ return e.observe(p.current), () => e.disconnect();
78
+ }
79
+ }, [
80
+ d,
81
+ l,
82
+ m,
83
+ n,
84
+ o,
85
+ g
86
+ ]), /* @__PURE__ */ z(
36
87
  "ul",
37
88
  {
38
- ref: o,
39
- title: g,
89
+ ref: a,
90
+ title: F,
40
91
  role: "listbox",
41
- className: t(D({ className: u })),
42
- "data-state": L ? "open" : "closed",
43
- children: d ? /* @__PURE__ */ l(
44
- i,
45
- {
46
- className: t("select-none", s),
47
- isClickable: !1,
48
- inputRef: r,
49
- value: "Loading...",
50
- label: "Loading...",
51
- listItemSecondRowClassName: a
52
- }
53
- ) : k ? /* @__PURE__ */ l(
54
- i,
55
- {
56
- className: t("select-none", s),
57
- isClickable: !1,
58
- inputRef: r,
59
- value: "No options",
60
- label: "No options",
61
- listItemSecondRowClassName: a
62
- }
63
- ) : /* @__PURE__ */ w(N, { children: [
64
- f.map((e) => /* @__PURE__ */ l(
65
- i,
92
+ className: i(R({ className: C })),
93
+ "data-state": E ? "open" : "closed",
94
+ children: [
95
+ N ? /* @__PURE__ */ r(
96
+ L,
97
+ {
98
+ className: i("select-none", f),
99
+ isClickable: !1,
100
+ inputRef: c,
101
+ value: "Loading...",
102
+ label: "Loading...",
103
+ listItemSecondRowClassName: u
104
+ }
105
+ ) : U ? /* @__PURE__ */ r(
106
+ L,
66
107
  {
67
- className: t("select-none", s),
108
+ className: i("select-none", f),
109
+ isClickable: !1,
110
+ inputRef: c,
111
+ value: "No options",
112
+ label: "No options",
113
+ listItemSecondRowClassName: u
114
+ }
115
+ ) : D.map((e) => /* @__PURE__ */ r(
116
+ L,
117
+ {
118
+ className: i("select-none", f),
68
119
  isClickable: !0,
69
- inputRef: r,
70
- listItemSecondRowClassName: a,
120
+ inputRef: c,
121
+ listItemSecondRowClassName: u,
71
122
  ...e
72
123
  },
73
124
  e.value
74
125
  )),
75
- p?.map((e, n) => /* @__PURE__ */ l("li", { role: "option", "data-action": "true", children: /* @__PURE__ */ l(E, { className: "flex p-2 w-full h-full gap-1 items-center text-sm [&>svg]:w-3.5 [&>svg]:h-3.5 [&>svg]:shrink-0 cursor-pointer select-none hover:bg-gray-50 hover:dark:bg-slate-700 focus:outline-0", children: e }) }, n))
76
- ] })
126
+ m && o && /* @__PURE__ */ r(
127
+ "li",
128
+ {
129
+ ref: p,
130
+ role: "option",
131
+ "data-action": "true",
132
+ className: "flex items-center justify-center py-3",
133
+ onClick: (e) => e.stopPropagation(),
134
+ children: /* @__PURE__ */ r(K, { className: "w-4 h-4 text-aurora-500 select-none" })
135
+ }
136
+ ),
137
+ k?.map((e, t) => /* @__PURE__ */ r("li", { role: "option", "data-action": "true", children: /* @__PURE__ */ r(A, { className: "flex p-2 w-full h-full gap-1 items-center text-sm [&>svg]:w-3.5 [&>svg]:h-3.5 [&>svg]:shrink-0 cursor-pointer select-none hover:bg-gray-50 hover:dark:bg-slate-700 focus:outline-0", children: e }) }, t))
138
+ ]
77
139
  }
78
140
  );
79
141
  }
80
142
  );
81
143
  export {
82
- I as List
144
+ ie as List
83
145
  };
@@ -1,162 +1,161 @@
1
- import { jsxs as h, jsx as a } from "react/jsx-runtime";
2
- import { forwardRef as X, useId as Y, useRef as T, useImperativeHandle as Z, useMemo as B, useEffect as L } from "react";
3
- import { Loading as ee } from "../../Loading/Loading.js";
4
- import { Typography as te } from "../../Typography/Typography.js";
5
- import { cn as c } from "../../../utils/index.js";
6
- import { labelVariants as ae, inputVariants as re, dropdownVariants as ne } from "../Dropdown.variants.js";
7
- import { useDropdown as oe } from "../hooks/useDropdown.js";
8
- import { List as le } from "./List/List.js";
1
+ import { jsxs as m, jsx as t } from "react/jsx-runtime";
2
+ import { forwardRef as Y, useId as Z, useRef as C, useMemo as ee, useImperativeHandle as te, useEffect as ae } from "react";
3
+ import { Loading as re } from "../../Loading/Loading.js";
4
+ import { Typography as ne } from "../../Typography/Typography.js";
5
+ import { cn as s } from "../../../utils/index.js";
6
+ import { labelVariants as oe, inputVariants as se, dropdownVariants as le } from "../Dropdown.variants.js";
7
+ import { useDropdown as ce } from "../hooks/useDropdown.js";
8
+ import { List as ie } from "./List/List.js";
9
9
  import { c as V } from "../../../createLucideIcon-D4r5Phnh.js";
10
- import { useDropdownContext as se } from "../contexts/dropdown.hook.js";
11
- const ce = [["path", { d: "m18 15-6-6-6 6", key: "153udz" }]], ie = V("chevron-up", ce);
12
- const ue = [
10
+ import { useDropdownContext as pe } from "../contexts/dropdown.hook.js";
11
+ const ue = [["path", { d: "m18 15-6-6-6 6", key: "153udz" }]], de = V("chevron-up", ue);
12
+ const fe = [
13
13
  ["path", { d: "m21 21-4.34-4.34", key: "14j7rj" }],
14
14
  ["circle", { cx: "11", cy: "11", r: "8", key: "4ej97u" }]
15
- ], fe = V("search", ue), ge = X(
15
+ ], me = V("search", fe), ze = Y(
16
16
  ({
17
- additionalOptions: _,
18
- className: $,
19
- defaultValue: v,
20
- disabled: r = !1,
21
- error: m,
22
- iconClassName: D,
23
- inputClassName: F,
24
- isLoading: z,
25
- isRequired: w,
26
- label: N,
27
- labelClassName: M,
28
- listClassName: A,
29
- listItemClassName: H,
30
- listItemSecondRowClassName: P,
31
- name: i,
32
- options: o,
33
- placeholder: k,
34
- searchable: C = !1,
35
- onSearchChange: U,
36
- showSearchIcon: g,
37
- theme: W,
38
- wrapperClassName: q,
39
- onBlur: j,
17
+ additionalOptions: R,
18
+ className: _,
19
+ defaultValue: x,
20
+ disabled: a = !1,
21
+ error: u,
22
+ iconClassName: F,
23
+ inputClassName: O,
24
+ isLoading: y,
25
+ isRequired: h,
26
+ label: v,
27
+ labelClassName: T,
28
+ listClassName: $,
29
+ listItemClassName: D,
30
+ listItemSecondRowClassName: E,
31
+ name: d,
32
+ placeholder: N,
33
+ searchable: g = !1,
34
+ showSearchIcon: w,
35
+ theme: M,
36
+ wrapperClassName: W,
37
+ isInfiniteScrollEnabled: H = !1,
38
+ onFetchMoreOptions: P,
39
+ onBlur: U,
40
+ onSearchChange: q,
40
41
  ...I
41
- }, G) => {
42
- const b = Y(), t = T(null), E = T(null), { wrapperRef: u, wrapperInputRef: O, handleOpen: y } = oe({
43
- ulRef: E,
44
- inputRef: t,
45
- disabled: r
46
- }), { isOpen: p, searchTerm: J, value: l, toggleOpen: K, setValue: x, setSearchTerm: R } = se(), f = i ? `${b}-${i}` : b;
47
- Z(G, () => t.current, [t]);
48
- const n = B(() => o.find(({ value: e }) => e === l), [o, l]);
49
- L(() => {
50
- t.current && (t.current.value = l && n?.value || "");
51
- }, [n, l]), L(() => {
52
- if (v && !l) {
53
- const e = o && o.find((s) => s.value === v);
54
- e && x(e.value);
42
+ }, A) => {
43
+ const z = Z(), l = C(null), L = C(null), B = C(0), {
44
+ isOpen: f,
45
+ searchTerm: G,
46
+ value: o,
47
+ // canFilter,
48
+ options: n,
49
+ setValue: c,
50
+ setSearchTerm: J,
51
+ setCanFilter: K
52
+ } = pe(), e = ee(() => n.find(({ value: r }) => r === o), [n, o]), { wrapperRef: Q, wrapperInputRef: j, handleOpen: k } = ce({
53
+ ulRef: L,
54
+ inputRef: l,
55
+ disabled: a,
56
+ internalValue: e,
57
+ onBlur: U
58
+ }), i = d ? `${z}-${d}` : z;
59
+ te(A, () => l.current, [l]), ae(() => {
60
+ if (x && !o) {
61
+ const r = n && n.find((p) => p.value === x);
62
+ r && c(r.value);
55
63
  }
56
- }, [v, o, x, l]), L(() => {
57
- const e = new AbortController();
58
- return u.current?.addEventListener("focusout", (s) => {
59
- const d = s.relatedTarget;
60
- (!d || !u.current?.contains(d)) && (t.current?.value || j?.());
61
- }), () => {
62
- e.abort();
63
- };
64
- }, [K, u, R, j, l]);
65
- const Q = (e) => {
66
- const s = e.target.value;
67
- U?.(s), x(""), R(s || "");
68
- const d = o.find(
69
- (S) => S.value.toLocaleLowerCase() === s.toLocaleLowerCase()
64
+ }, [x, n, c, o]);
65
+ const S = (r) => {
66
+ const p = r.target.value;
67
+ K(!0), q?.(p), c(""), J(p || "");
68
+ const b = n.find(
69
+ (X) => X.value.toLocaleLowerCase() === p.toLocaleLowerCase()
70
70
  );
71
- d && x(d.value);
71
+ c(b ? b.value : e?.value ?? "");
72
72
  };
73
- return /* @__PURE__ */ h(
73
+ return /* @__PURE__ */ m(
74
74
  "div",
75
75
  {
76
- ref: u,
77
- className: c("flex flex-col w-full relative", q),
78
- "data-theme": W,
76
+ ref: Q,
77
+ className: s("flex flex-col w-full relative", W),
78
+ "data-theme": M,
79
79
  children: [
80
- N ? /* @__PURE__ */ h(
80
+ v ? /* @__PURE__ */ m(
81
81
  "label",
82
82
  {
83
- id: f,
84
- className: c(ae({ className: M })),
85
- htmlFor: f,
86
- onClick: () => !r && y(),
83
+ id: i,
84
+ className: s(oe({ className: T })),
85
+ htmlFor: i,
86
+ onClick: () => !a && k(),
87
87
  children: [
88
- N,
89
- w && /* @__PURE__ */ a("span", { className: "text-red-600 ml-1", children: "*" })
88
+ v,
89
+ h && /* @__PURE__ */ t("span", { className: "text-red-600 ml-1", children: "*" })
90
90
  ]
91
91
  }
92
92
  ) : null,
93
- /* @__PURE__ */ h(
93
+ /* @__PURE__ */ m(
94
94
  "div",
95
95
  {
96
- ref: O,
97
- id: f,
98
- className: c(
99
- ne({ className: $, hasError: !!m, disabled: r })
96
+ ref: j,
97
+ id: i,
98
+ className: s(
99
+ le({ className: _, hasError: !!u, disabled: a })
100
100
  ),
101
101
  role: "combobox",
102
- onClick: () => !r && y(),
103
- "aria-expanded": p,
104
- tabIndex: 0,
105
- "aria-labelledby": f,
102
+ onClick: () => !a && k(),
103
+ "aria-expanded": f,
104
+ tabIndex: B.current,
105
+ "aria-labelledby": i,
106
106
  children: [
107
- /* @__PURE__ */ h("div", { className: "flex gap-2.5 items-center flex-1", children: [
108
- n?.leftIcon && !g && /* @__PURE__ */ a("span", { className: "w-4 h-4 flex justify-center items-center dark:text-slate-50", children: n.leftIcon }),
109
- g && /* @__PURE__ */ a(fe, { className: "w-4 h-4 text-zinc-500 select-none dark:text-slate-300 dark:group-focus-within:text-slate-50 transition-colors duration-300" }),
110
- C ? /* @__PURE__ */ a(
107
+ /* @__PURE__ */ m("div", { className: "flex gap-2.5 items-center flex-1", children: [
108
+ e?.leftIcon && !w && /* @__PURE__ */ t("span", { className: "w-4 h-4 flex justify-center items-center dark:text-slate-50", children: e.leftIcon }),
109
+ w && /* @__PURE__ */ t(me, { className: "w-4 h-4 text-zinc-500 select-none dark:text-slate-300 dark:group-focus-within:text-slate-50 transition-colors duration-300" }),
110
+ g ? /* @__PURE__ */ t(
111
111
  "input",
112
112
  {
113
- ref: t,
114
113
  type: "text",
115
- value: p ? J : n?.label || "",
116
- name: i,
117
- onChange: Q,
118
- placeholder: k,
119
- className: c(re({ className: F }), {
120
- "text-red-700 placeholder:text-red-700": !!m
114
+ value: f ? G : e?.label ?? o ?? "",
115
+ onChange: S,
116
+ placeholder: N,
117
+ className: s(se({ className: O }), {
118
+ "text-red-700 placeholder:text-red-700": !!u
121
119
  }),
122
- onClick: (e) => {
123
- e.stopPropagation(), r || y();
120
+ onClick: (r) => {
121
+ r.stopPropagation(), a || k();
124
122
  },
125
- "aria-label": N || k,
126
- "aria-labelledby": f,
127
- required: w,
123
+ "aria-label": v || N,
124
+ "aria-labelledby": i,
125
+ required: h,
128
126
  autoComplete: "off",
129
127
  autoCapitalize: "words",
130
- disabled: r,
128
+ disabled: a,
129
+ tabIndex: -1,
131
130
  ...I
132
131
  }
133
- ) : /* @__PURE__ */ a(
134
- te,
132
+ ) : /* @__PURE__ */ t(
133
+ ne,
135
134
  {
136
135
  variant: "body2",
137
- className: c(
136
+ className: s(
138
137
  "flex-1 text-zinc-400 text-sm dark:text-slate-400",
139
138
  {
140
- "text-red-700": !!m,
141
- "select-none": !n,
142
- "text-slate-800 dark:text-slate-50": n,
143
- "text-slate-400/50 dark:text-slate-50/50": r
139
+ "text-red-700": !!u,
140
+ "select-none": !e,
141
+ "text-slate-800 dark:text-slate-50": e,
142
+ "text-slate-400/50 dark:text-slate-50/50": a
144
143
  }
145
144
  ),
146
- children: n?.label || k
145
+ children: e?.label || N
147
146
  }
148
147
  )
149
148
  ] }),
150
- z ? /* @__PURE__ */ a(ee, { className: "w-4 h-4 text-zinc-500 select-none" }) : !g && /* @__PURE__ */ a(
151
- ie,
149
+ y ? /* @__PURE__ */ t(re, { className: "w-4 h-4 text-zinc-500 select-none" }) : !w && /* @__PURE__ */ t(
150
+ de,
152
151
  {
153
- "data-state": p ? "open" : "closed",
154
- className: c(
152
+ "data-state": f ? "open" : "closed",
153
+ className: s(
155
154
  "w-4 h-4 text-zinc-500 transition-all duration-100 data-[state=open]:rotate-0 data-[state=closed]:rotate-180 select-none dark:group-focus-within:text-slate-50",
156
- D,
155
+ F,
157
156
  {
158
- "text-red-700": !!m,
159
- "text-slate-400/50 dark:group-focus-within:text-zinc-500": r
157
+ "text-red-700": !!u,
158
+ "text-slate-400/50 dark:group-focus-within:text-zinc-500": a
160
159
  }
161
160
  )
162
161
  }
@@ -164,34 +163,36 @@ const ue = [
164
163
  ]
165
164
  }
166
165
  ),
167
- !C && /* @__PURE__ */ a(
166
+ /* @__PURE__ */ t(
168
167
  "input",
169
168
  {
170
- ref: t,
169
+ ref: l,
171
170
  type: "text",
172
- name: i,
171
+ name: d,
173
172
  className: "hidden",
174
173
  "aria-hidden": "true",
175
- required: w,
174
+ required: h,
176
175
  inert: !0,
176
+ defaultValue: e?.value ?? o ?? void 0,
177
177
  ...I
178
178
  }
179
179
  ),
180
- p && /* @__PURE__ */ a(
181
- le,
180
+ f && /* @__PURE__ */ t(
181
+ ie,
182
182
  {
183
- ref: E,
184
- additionalOptions: _,
185
- className: A,
186
- itemClassName: H,
187
- name: i,
188
- wrapperRef: u,
189
- wrapperInputRef: O,
190
- inputRef: t,
191
- options: o,
192
- isLoading: !!z,
193
- searchable: C,
194
- listItemSecondRowClassName: P
183
+ ref: L,
184
+ additionalOptions: R,
185
+ className: $,
186
+ itemClassName: D,
187
+ name: d,
188
+ wrapperInputRef: j,
189
+ inputRef: l,
190
+ options: n,
191
+ isLoading: !!y,
192
+ searchable: g,
193
+ listItemSecondRowClassName: E,
194
+ isInfiniteScrollEnabled: H,
195
+ onFetchMoreOptions: P
195
196
  }
196
197
  )
197
198
  ]
@@ -200,5 +201,5 @@ const ue = [
200
201
  }
201
202
  );
202
203
  export {
203
- ge as Wrapper
204
+ ze as Wrapper
204
205
  };
@@ -0,0 +1,4 @@
1
+ import { DEFAULT_LIST_SIZE as E } from "./pagination.js";
2
+ export {
3
+ E as DEFAULT_LIST_SIZE
4
+ };
@@ -0,0 +1,4 @@
1
+ const o = 10;
2
+ export {
3
+ o as DEFAULT_LIST_SIZE
4
+ };
@@ -4,6 +4,22 @@ const t = e({
4
4
  isOpen: !1,
5
5
  searchTerm: "",
6
6
  value: void 0,
7
+ canFilter: !0,
8
+ canContinueFetching: !0,
9
+ page: 1,
10
+ options: [],
11
+ setOptions() {
12
+ throw new Error("setOptions function must be overridden");
13
+ },
14
+ setPage() {
15
+ throw new Error("setPage function must be overridden");
16
+ },
17
+ setCanContinueFetching() {
18
+ throw new Error("setCanContinueFetching function must be overridden");
19
+ },
20
+ setCanFilter() {
21
+ throw new Error("setCanFilter function must be overridden");
22
+ },
7
23
  setSearchTerm() {
8
24
  throw new Error("setSearchTerm function must be overridden");
9
25
  },
@@ -1,30 +1,53 @@
1
- import { jsx as f } from "react/jsx-runtime";
2
- import { useRef as p, useState as d, useCallback as v } from "react";
3
- import { DropdownContext as S } from "./dropdown.context.js";
4
- import { useToggle as b } from "../../../hooks/useToggle.js";
5
- const D = ({ children: s, value: n, name: e, highlightSearch: c = !1, onChange: r, onBlur: t }) => {
6
- const l = p(c), [h, i] = b(!1), [m, g] = d(""), u = v(
7
- (o, a) => {
8
- a?.current && (a.current.value = o), r?.({ target: { value: o, name: e ?? "" } }), t?.();
1
+ import { jsx as w } from "react/jsx-runtime";
2
+ import { useState as e, useRef as A, useCallback as u, useEffect as I } from "react";
3
+ import { DropdownContext as O } from "./dropdown.context.js";
4
+ import { useToggle as _ } from "../../../hooks/useToggle.js";
5
+ const s = 1, N = ({
6
+ children: p,
7
+ value: m,
8
+ name: c,
9
+ highlightSearch: f = !1,
10
+ options: r,
11
+ onChange: a,
12
+ onBlur: g
13
+ }) => {
14
+ const [d, i] = e(r), C = A(f), [T, l] = _(!1), [E, F] = e(""), [v, P] = e(!0), [S, n] = e(!0), [b, o] = e(s), x = u(
15
+ (t, h) => {
16
+ h?.current && (h.current.value = t), n(!0), o(s), a?.({ target: { value: t, name: c ?? "" } }), g?.();
9
17
  },
10
- [r, e, t]
18
+ [a, c, g]
19
+ ), D = u(
20
+ (t) => {
21
+ l(t), n(!0), o(s);
22
+ },
23
+ [l]
11
24
  );
12
- return /* @__PURE__ */ f(
13
- S.Provider,
25
+ return I(() => {
26
+ i(r);
27
+ }, [r.length]), /* @__PURE__ */ w(
28
+ O.Provider,
14
29
  {
15
30
  value: {
16
- highlightSearchEnabled: l.current,
17
- isOpen: h,
18
- searchTerm: m,
19
- value: n,
20
- setSearchTerm: g,
21
- setValue: u,
22
- toggleOpen: i
31
+ highlightSearchEnabled: C.current,
32
+ isOpen: T,
33
+ searchTerm: E,
34
+ value: m,
35
+ canFilter: v,
36
+ canContinueFetching: S,
37
+ page: b,
38
+ options: d,
39
+ setOptions: i,
40
+ setPage: o,
41
+ setCanContinueFetching: n,
42
+ setCanFilter: P,
43
+ setSearchTerm: F,
44
+ setValue: x,
45
+ toggleOpen: D
23
46
  },
24
- children: s
47
+ children: p
25
48
  }
26
49
  );
27
50
  };
28
51
  export {
29
- D as DropdownProvider
52
+ N as DropdownProvider
30
53
  };
@@ -1,20 +1,22 @@
1
- import { useRef as c, useEffect as u, useCallback as g } from "react";
2
- import { useDropdownContext as m } from "../contexts/dropdown.hook.js";
3
- const b = ({
4
- ulRef: i,
5
- inputRef: l,
6
- disabled: d
1
+ import { useRef as m, useEffect as l, useCallback as b } from "react";
2
+ import { useDropdownContext as L } from "../contexts/dropdown.hook.js";
3
+ const y = ({
4
+ ulRef: f,
5
+ inputRef: t,
6
+ disabled: w,
7
+ internalValue: i,
8
+ onBlur: g
7
9
  }) => {
8
- const o = c(null), t = c(null), { toggleOpen: n } = m();
9
- u(() => {
10
- const e = new AbortController(), s = (a) => {
11
- a.key === "Escape" && n(!1);
12
- }, r = (a) => {
13
- o.current?.contains(a.target) || n(!1);
10
+ const r = m(null), a = m(null), { value: c, setSearchTerm: v, setCanFilter: u, toggleOpen: n } = L();
11
+ l(() => {
12
+ const e = new AbortController(), o = (d) => {
13
+ d.key === "Escape" && n(!1);
14
+ }, s = (d) => {
15
+ r.current?.contains(d.target) || n(!1);
14
16
  };
15
- return document.addEventListener("keydown", s, {
17
+ return document.addEventListener("keydown", o, {
16
18
  signal: e.signal
17
- }), document.addEventListener("mousedown", r, {
19
+ }), document.addEventListener("mousedown", s, {
18
20
  signal: e.signal
19
21
  }), document.addEventListener(
20
22
  "visibilitychange",
@@ -24,39 +26,78 @@ const b = ({
24
26
  {
25
27
  signal: e.signal
26
28
  }
27
- ), t.current?.addEventListener(
28
- "focus",
29
+ ), a.current?.addEventListener(
30
+ "focusin",
29
31
  () => {
30
- d || n(!0);
32
+ w || n(!0);
31
33
  },
32
34
  { signal: e.signal }
33
35
  ), () => {
34
36
  e.abort();
35
37
  };
36
- }, [n, o]), u(() => {
38
+ }, [n, r]), l(() => {
37
39
  const e = new AbortController();
38
- return t.current?.addEventListener(
40
+ return a.current?.addEventListener(
39
41
  "keydown",
40
- (s) => {
41
- if (s.key === "ArrowDown") {
42
- const r = i.current?.querySelector("li");
43
- r && r.focus();
42
+ (o) => {
43
+ if (o.key === "ArrowDown") {
44
+ const s = f.current?.querySelector("li");
45
+ s && s.focus();
44
46
  }
45
47
  },
46
48
  { signal: e.signal }
47
49
  ), () => {
48
50
  e.abort();
49
51
  };
50
- }, [t, i]);
51
- const f = g(() => {
52
- n(!0), requestAnimationFrame(() => l?.current?.focus());
53
- }, [l, n]);
52
+ }, [a, f]), l(() => {
53
+ const e = new AbortController();
54
+ return t?.current?.addEventListener(
55
+ "focusin",
56
+ () => {
57
+ v(i?.value ?? ""), u(!1);
58
+ },
59
+ { signal: e.signal }
60
+ ), t?.current?.addEventListener(
61
+ "focusout",
62
+ () => {
63
+ u(!0);
64
+ },
65
+ { signal: e.signal }
66
+ ), a.current?.addEventListener(
67
+ "focus",
68
+ () => {
69
+ u(!1);
70
+ },
71
+ { signal: e.signal }
72
+ ), r.current?.addEventListener(
73
+ "focusout",
74
+ (o) => {
75
+ r.current?.contains(o.relatedTarget) || n(!1);
76
+ },
77
+ { signal: e.signal }
78
+ ), () => {
79
+ e.abort();
80
+ };
81
+ }, [c]), l(() => {
82
+ t?.current && (t.current.value = c && i?.value || "");
83
+ }, [i, c]), l(() => {
84
+ const e = new AbortController();
85
+ return r.current?.addEventListener("focusout", (o) => {
86
+ const s = o.relatedTarget;
87
+ (!s || !r.current?.contains(s)) && (t?.current?.value || g?.());
88
+ }), () => {
89
+ e.abort();
90
+ };
91
+ }, [n, r, v, g, c]);
92
+ const E = b(() => {
93
+ n(!0), requestAnimationFrame(() => t?.current?.focus());
94
+ }, [t, n]);
54
95
  return {
55
- wrapperRef: o,
56
- wrapperInputRef: t,
57
- handleOpen: f
96
+ wrapperRef: r,
97
+ wrapperInputRef: a,
98
+ handleOpen: E
58
99
  };
59
100
  };
60
101
  export {
61
- b as useDropdown
102
+ y as useDropdown
62
103
  };
@@ -1,62 +1,50 @@
1
- import { useRef as g, useEffect as i } from "react";
2
- import { useDropdownContext as d } from "../contexts/dropdown.hook.js";
3
- const w = ({
4
- inputRef: s,
5
- searchable: l,
6
- ulRef: t,
7
- wrapperInputRef: u,
8
- wrapperRef: a
1
+ import { useRef as g, useEffect as a } from "react";
2
+ import { useDropdownContext as k } from "../contexts/dropdown.hook.js";
3
+ const A = ({
4
+ searchable: o,
5
+ ulRef: n,
6
+ wrapperInputRef: e,
7
+ filteredOptions: f
9
8
  }) => {
10
- const r = g(0), { isOpen: f } = d();
11
- i(() => {
12
- const c = t.current?.querySelectorAll("li") ?? [], e = Array.from(c).filter(
13
- (n) => n.getAttribute("data-action") !== "true"
14
- ), o = new AbortController(), m = () => {
15
- r.current < e.length - 1 ? (r.current = r.current + 1, e[r.current].focus()) : (r.current = 0, e[0].focus());
16
- }, b = () => {
17
- r.current > 0 ? (r.current = r.current - 1, e[r.current].focus()) : (r.current = 0, s?.current && l ? s.current.focus() : u.current?.focus());
9
+ const r = g(0), { isOpen: s } = k();
10
+ a(() => {
11
+ const m = n.current?.querySelectorAll("li") ?? [], t = Array.from(m).filter(
12
+ (c) => c.getAttribute("data-action") !== "true"
13
+ ), u = new AbortController(), i = () => {
14
+ r.current < t.length - 1 ? (r.current = r.current + 1, t[r.current].focus()) : (r.current = 0, t[0].focus());
15
+ }, l = () => {
16
+ r.current > 0 ? (r.current = r.current - 1, t[r.current].focus()) : (r.current = 0, e?.current && o ? e.current.querySelector("input")?.focus() : e.current?.focus());
18
17
  };
19
- return t.current?.addEventListener(
18
+ return n.current?.addEventListener(
20
19
  "keydown",
21
- (n) => {
22
- switch (n.preventDefault(), n.key) {
20
+ (c) => {
21
+ switch (c.preventDefault(), c.key) {
23
22
  case "ArrowDown": {
24
- m();
23
+ i();
25
24
  break;
26
25
  }
27
26
  case "Tab": {
28
- n.shiftKey ? b() : m();
27
+ c.shiftKey ? l() : i();
29
28
  break;
30
29
  }
31
30
  case "ArrowUp": {
32
- r.current === 0 ? u.current?.focus() : b();
31
+ r.current === 0 ? e.current?.focus() : l();
33
32
  break;
34
33
  }
35
34
  case "Enter": {
36
- e[r.current]?.click();
35
+ t[r.current]?.click();
37
36
  break;
38
37
  }
39
38
  }
40
39
  },
41
- { signal: o.signal }
40
+ { signal: u.signal }
42
41
  ), () => {
43
- o.abort();
42
+ u.abort();
44
43
  };
45
- }, [t, r, u, s, l]), i(() => {
46
- const c = new AbortController();
47
- return a.current?.addEventListener(
48
- "mouseenter",
49
- () => {
50
- (t.current?.querySelectorAll("li") ?? []).forEach((o) => o.blur());
51
- },
52
- { signal: c.signal }
53
- ), () => {
54
- c.abort();
55
- };
56
- }, [t, a]), i(() => {
57
- f || (r.current = 0);
58
- }, [f]);
44
+ }, [n, r, e, o, f.length]), a(() => {
45
+ s || (r.current = 0);
46
+ }, [s]);
59
47
  };
60
48
  export {
61
- w as useNavigationUlList
49
+ A as useNavigationUlList
62
50
  };
package/dist/index.d.ts CHANGED
@@ -231,16 +231,32 @@ declare type DropdownProps = VariantProps<typeof dropdownVariants> & Omit<InputH
231
231
  listClassName?: string;
232
232
  listItemClassName?: string;
233
233
  listItemSecondRowClassName?: string;
234
+ mainWrapperClassName?: string;
234
235
  options: Option_3[];
235
236
  searchable?: boolean;
236
237
  showSearchIcon?: boolean;
237
238
  theme?: Theme;
238
239
  value?: string;
239
240
  wrapperClassName?: string;
241
+ errorClassName?: string;
242
+ helperTextClassName?: string;
240
243
  onBlur?: VoidFunction;
241
244
  onChange?: OnChangeFn;
242
245
  onSearchChange?: (searchTerm: string) => void;
243
- };
246
+ } & ({
247
+ isInfiniteScrollEnabled: true;
248
+ onFetchMoreOptions: (params: {
249
+ page: number;
250
+ pageSize: number;
251
+ termOfSearch?: string;
252
+ }) => Promise<{
253
+ data: Option_3[];
254
+ hasMore: boolean;
255
+ }>;
256
+ } | {
257
+ isInfiniteScrollEnabled?: false | undefined;
258
+ onFetchMoreOptions?: never;
259
+ });
244
260
 
245
261
  declare const dropdownVariants: (props?: ({
246
262
  hasError?: boolean | null | undefined;
@@ -451,7 +467,7 @@ declare type Option_2 = {
451
467
  };
452
468
 
453
469
  declare type Option_3 = {
454
- label: string | ReactNode;
470
+ label: string;
455
471
  subLabel?: string | ReactNode;
456
472
  leftIcon?: ReactNode | string;
457
473
  value: string;
package/dist/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "@konstructio/ui",
3
3
  "description": "A set of reusable and customizable React components built for konstruct.io",
4
4
  "private": false,
5
- "version": "0.1.2-alpha.22",
5
+ "version": "0.1.2-alpha.23",
6
6
  "type": "module",
7
7
  "license": "MIT",
8
8
  "main": "dist/index.js",
@@ -72,7 +72,7 @@
72
72
  "cmdk": "^1.1.1",
73
73
  "countries-and-timezones": "^3.8.0",
74
74
  "js-cookie": "^3.0.5",
75
- "lucide-react": "^0.553.0",
75
+ "lucide-react": "^0.554.0",
76
76
  "react-chartjs-2": "^5.3.1",
77
77
  "react-day-picker": "^9.11.1",
78
78
  "react-feather": "^2.0.10",
@@ -115,39 +115,39 @@
115
115
  "devDependencies": {
116
116
  "@faker-js/faker": "^10.1.0",
117
117
  "@rollup/plugin-alias": "^6.0.0",
118
- "@storybook/addon-docs": "^10.0.6",
119
- "@storybook/addon-links": "^10.0.6",
120
- "@storybook/react-vite": "^10.0.6",
118
+ "@storybook/addon-docs": "^10.0.8",
119
+ "@storybook/addon-links": "^10.0.8",
120
+ "@storybook/react-vite": "^10.0.8",
121
121
  "@tailwindcss/vite": "^4.1.17",
122
- "@tanstack/react-query": "^5.90.7",
122
+ "@tanstack/react-query": "^5.90.10",
123
123
  "@testing-library/jest-dom": "^6.9.1",
124
124
  "@testing-library/react": "^16.3.0",
125
125
  "@testing-library/user-event": "^14.6.1",
126
126
  "@types/jest-axe": "^3.5.9",
127
127
  "@types/js-cookie": "^3.0.6",
128
128
  "@types/lodash": "^4.17.20",
129
- "@types/react": "^19.2.2",
130
- "@types/react-dom": "^19.2.2",
131
- "@typescript-eslint/eslint-plugin": "^8.46.4",
132
- "@typescript-eslint/parser": "^8.46.4",
133
- "@vitejs/plugin-react": "^5.1.0",
129
+ "@types/react": "^19.2.6",
130
+ "@types/react-dom": "^19.2.3",
131
+ "@typescript-eslint/eslint-plugin": "^8.47.0",
132
+ "@typescript-eslint/parser": "^8.47.0",
133
+ "@vitejs/plugin-react": "^5.1.1",
134
134
  "@vitest/coverage-v8": "^3.2.4",
135
- "autoprefixer": "^10.4.21",
135
+ "autoprefixer": "^10.4.22",
136
136
  "eslint": "^9.39.1",
137
137
  "eslint-plugin-react": "^7.37.5",
138
138
  "eslint-plugin-react-hooks": "^6.1.1",
139
139
  "eslint-plugin-react-refresh": "^0.4.23",
140
140
  "eslint-plugin-storybook": "^9.1.13",
141
141
  "eslint-plugin-vitest": "^0.5.4",
142
- "glob": "^11.0.3",
142
+ "glob": "^12.0.0",
143
143
  "husky": "^9.1.7",
144
144
  "jest-axe": "^10.0.0",
145
- "jsdom": "^27.1.0",
145
+ "jsdom": "^27.2.0",
146
146
  "lodash": "^4.17.21",
147
147
  "postcss": "^8.5.6",
148
148
  "prettier": "^3.6.2",
149
149
  "rimraf": "^6.1.0",
150
- "storybook": "^10.0.6",
150
+ "storybook": "^10.0.8",
151
151
  "tailwindcss": "^4.1.17",
152
152
  "ts-node": "^10.9.2",
153
153
  "typescript": "^5.9.3",
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "@konstructio/ui",
3
3
  "description": "A set of reusable and customizable React components built for konstruct.io",
4
4
  "private": false,
5
- "version": "0.1.2-alpha.23",
5
+ "version": "0.1.2-alpha.24",
6
6
  "type": "module",
7
7
  "license": "MIT",
8
8
  "main": "dist/index.js",
@@ -72,7 +72,7 @@
72
72
  "cmdk": "^1.1.1",
73
73
  "countries-and-timezones": "^3.8.0",
74
74
  "js-cookie": "^3.0.5",
75
- "lucide-react": "^0.553.0",
75
+ "lucide-react": "^0.554.0",
76
76
  "react-chartjs-2": "^5.3.1",
77
77
  "react-day-picker": "^9.11.1",
78
78
  "react-feather": "^2.0.10",
@@ -115,39 +115,39 @@
115
115
  "devDependencies": {
116
116
  "@faker-js/faker": "^10.1.0",
117
117
  "@rollup/plugin-alias": "^6.0.0",
118
- "@storybook/addon-docs": "^10.0.6",
119
- "@storybook/addon-links": "^10.0.6",
120
- "@storybook/react-vite": "^10.0.6",
118
+ "@storybook/addon-docs": "^10.0.8",
119
+ "@storybook/addon-links": "^10.0.8",
120
+ "@storybook/react-vite": "^10.0.8",
121
121
  "@tailwindcss/vite": "^4.1.17",
122
- "@tanstack/react-query": "^5.90.7",
122
+ "@tanstack/react-query": "^5.90.10",
123
123
  "@testing-library/jest-dom": "^6.9.1",
124
124
  "@testing-library/react": "^16.3.0",
125
125
  "@testing-library/user-event": "^14.6.1",
126
126
  "@types/jest-axe": "^3.5.9",
127
127
  "@types/js-cookie": "^3.0.6",
128
128
  "@types/lodash": "^4.17.20",
129
- "@types/react": "^19.2.2",
130
- "@types/react-dom": "^19.2.2",
131
- "@typescript-eslint/eslint-plugin": "^8.46.4",
132
- "@typescript-eslint/parser": "^8.46.4",
133
- "@vitejs/plugin-react": "^5.1.0",
129
+ "@types/react": "^19.2.6",
130
+ "@types/react-dom": "^19.2.3",
131
+ "@typescript-eslint/eslint-plugin": "^8.47.0",
132
+ "@typescript-eslint/parser": "^8.47.0",
133
+ "@vitejs/plugin-react": "^5.1.1",
134
134
  "@vitest/coverage-v8": "^3.2.4",
135
- "autoprefixer": "^10.4.21",
135
+ "autoprefixer": "^10.4.22",
136
136
  "eslint": "^9.39.1",
137
137
  "eslint-plugin-react": "^7.37.5",
138
138
  "eslint-plugin-react-hooks": "^6.1.1",
139
139
  "eslint-plugin-react-refresh": "^0.4.23",
140
140
  "eslint-plugin-storybook": "^9.1.13",
141
141
  "eslint-plugin-vitest": "^0.5.4",
142
- "glob": "^11.0.3",
142
+ "glob": "^12.0.0",
143
143
  "husky": "^9.1.7",
144
144
  "jest-axe": "^10.0.0",
145
- "jsdom": "^27.1.0",
145
+ "jsdom": "^27.2.0",
146
146
  "lodash": "^4.17.21",
147
147
  "postcss": "^8.5.6",
148
148
  "prettier": "^3.6.2",
149
149
  "rimraf": "^6.1.0",
150
- "storybook": "^10.0.6",
150
+ "storybook": "^10.0.8",
151
151
  "tailwindcss": "^4.1.17",
152
152
  "ts-node": "^10.9.2",
153
153
  "typescript": "^5.9.3",