@turtleclub/core 0.1.0-beta.12 → 0.1.0-beta.121
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/index.cjs +195 -61
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +19 -10
- package/dist/index.d.ts +19 -10
- package/dist/index.js +234 -85
- package/dist/index.js.map +1 -1
- package/package.json +11 -9
- package/src/filters/RangeSliderFilter.tsx +135 -8
- package/src/selectors/ChainSelector.tsx +4 -1
- package/src/selectors/ChainsSelector.tsx +4 -1
- package/src/selectors/OpportunitiesSelector.tsx +4 -27
- package/src/selectors/OpportunitySelector.tsx +4 -27
- package/src/selectors/TokenSelector.tsx +2 -2
- package/src/selectors/TokensSelector.tsx +2 -2
- package/src/wrappers/FiltersPopover.tsx +36 -8
- package/src/wrappers/FiltersWrapper.tsx +36 -11
package/dist/index.js
CHANGED
|
@@ -1,8 +1,17 @@
|
|
|
1
1
|
// src/filters/RangeSliderFilter.tsx
|
|
2
2
|
import { useEffect, useState } from "react";
|
|
3
|
-
import {
|
|
3
|
+
import {
|
|
4
|
+
Slider,
|
|
5
|
+
Label,
|
|
6
|
+
Input,
|
|
7
|
+
Popover,
|
|
8
|
+
PopoverTrigger,
|
|
9
|
+
PopoverContent,
|
|
10
|
+
buttonVariants,
|
|
11
|
+
cn
|
|
12
|
+
} from "@turtleclub/ui";
|
|
4
13
|
import { useQueryState, parseAsInteger } from "nuqs";
|
|
5
|
-
import { jsx, jsxs } from "react/jsx-runtime";
|
|
14
|
+
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
6
15
|
var defaultFormatter = (value) => {
|
|
7
16
|
return value.toLocaleString();
|
|
8
17
|
};
|
|
@@ -16,13 +25,18 @@ function RangeSliderFilter({
|
|
|
16
25
|
label = "Range",
|
|
17
26
|
showValues = true,
|
|
18
27
|
formatValue = defaultFormatter,
|
|
19
|
-
className = ""
|
|
28
|
+
className = "",
|
|
29
|
+
usePopover = false
|
|
20
30
|
}) {
|
|
21
31
|
const [minValue, setMinValue] = useQueryState(minQueryKey, parseAsInteger.withDefault(min));
|
|
22
32
|
const [maxValue, setMaxValue] = useQueryState(maxQueryKey, parseAsInteger.withDefault(max));
|
|
23
33
|
const [localRange, setLocalRange] = useState([minValue, maxValue]);
|
|
34
|
+
const [minInputValue, setMinInputValue] = useState(minValue.toString());
|
|
35
|
+
const [maxInputValue, setMaxInputValue] = useState(maxValue.toString());
|
|
24
36
|
useEffect(() => {
|
|
25
37
|
setLocalRange([minValue, maxValue]);
|
|
38
|
+
setMinInputValue(minValue.toString());
|
|
39
|
+
setMaxInputValue(maxValue.toString());
|
|
26
40
|
}, [minValue, maxValue]);
|
|
27
41
|
const handleRangeChange = (values) => {
|
|
28
42
|
setLocalRange(values);
|
|
@@ -36,8 +50,46 @@ function RangeSliderFilter({
|
|
|
36
50
|
setMaxValue(newMax === max ? null : newMax);
|
|
37
51
|
}
|
|
38
52
|
};
|
|
53
|
+
const handleMinInputChange = (e) => {
|
|
54
|
+
setMinInputValue(e.target.value);
|
|
55
|
+
};
|
|
56
|
+
const handleMaxInputChange = (e) => {
|
|
57
|
+
setMaxInputValue(e.target.value);
|
|
58
|
+
};
|
|
59
|
+
const handleMinInputBlur = () => {
|
|
60
|
+
const numValue = parseInt(minInputValue, 10);
|
|
61
|
+
if (!isNaN(numValue)) {
|
|
62
|
+
const clampedValue = Math.max(min, Math.min(numValue, localRange[1]));
|
|
63
|
+
setLocalRange([clampedValue, localRange[1]]);
|
|
64
|
+
handleRangeCommit([clampedValue, localRange[1]]);
|
|
65
|
+
setMinInputValue(clampedValue.toString());
|
|
66
|
+
} else {
|
|
67
|
+
setMinInputValue(localRange[0].toString());
|
|
68
|
+
}
|
|
69
|
+
};
|
|
70
|
+
const handleMaxInputBlur = () => {
|
|
71
|
+
const numValue = parseInt(maxInputValue, 10);
|
|
72
|
+
if (!isNaN(numValue)) {
|
|
73
|
+
const clampedValue = Math.min(max, Math.max(numValue, localRange[0]));
|
|
74
|
+
setLocalRange([localRange[0], clampedValue]);
|
|
75
|
+
handleRangeCommit([localRange[0], clampedValue]);
|
|
76
|
+
setMaxInputValue(clampedValue.toString());
|
|
77
|
+
} else {
|
|
78
|
+
setMaxInputValue(localRange[1].toString());
|
|
79
|
+
}
|
|
80
|
+
};
|
|
81
|
+
const handleMinInputKeyDown = (e) => {
|
|
82
|
+
if (e.key === "Enter") {
|
|
83
|
+
handleMinInputBlur();
|
|
84
|
+
}
|
|
85
|
+
};
|
|
86
|
+
const handleMaxInputKeyDown = (e) => {
|
|
87
|
+
if (e.key === "Enter") {
|
|
88
|
+
handleMaxInputBlur();
|
|
89
|
+
}
|
|
90
|
+
};
|
|
39
91
|
const isDefaultRange = localRange[0] === min && localRange[1] === max;
|
|
40
|
-
|
|
92
|
+
const filterContent = /* @__PURE__ */ jsxs("div", { className: "space-y-3", children: [
|
|
41
93
|
/* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between", children: [
|
|
42
94
|
/* @__PURE__ */ jsx(Label, { className: "text-sm font-medium", children: label }),
|
|
43
95
|
showValues && /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1 text-xs text-muted-foreground", children: [
|
|
@@ -59,15 +111,53 @@ function RangeSliderFilter({
|
|
|
59
111
|
className: "w-full"
|
|
60
112
|
}
|
|
61
113
|
) }),
|
|
62
|
-
|
|
63
|
-
/* @__PURE__ */
|
|
64
|
-
|
|
114
|
+
/* @__PURE__ */ jsxs("div", { className: "flex justify-between gap-2", children: [
|
|
115
|
+
/* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-1 flex-1", children: [
|
|
116
|
+
/* @__PURE__ */ jsx(Label, { htmlFor: "min-input", className: "text-xs text-muted-foreground", children: "Min" }),
|
|
117
|
+
/* @__PURE__ */ jsx(
|
|
118
|
+
Input,
|
|
119
|
+
{
|
|
120
|
+
id: "min-input",
|
|
121
|
+
type: "number",
|
|
122
|
+
value: minInputValue,
|
|
123
|
+
onChange: handleMinInputChange,
|
|
124
|
+
onBlur: handleMinInputBlur,
|
|
125
|
+
onKeyDown: handleMinInputKeyDown,
|
|
126
|
+
min,
|
|
127
|
+
max: localRange[1],
|
|
128
|
+
step,
|
|
129
|
+
disabled,
|
|
130
|
+
className: "h-7 text-xs [appearance:textfield] [&::-webkit-outer-spin-button]:m-0 [&::-webkit-outer-spin-button]:[-webkit-appearance:none] [&::-webkit-inner-spin-button]:m-0 [&::-webkit-inner-spin-button]:[-webkit-appearance:none]"
|
|
131
|
+
}
|
|
132
|
+
)
|
|
133
|
+
] }),
|
|
134
|
+
/* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-1 flex-1", children: [
|
|
135
|
+
/* @__PURE__ */ jsx(Label, { htmlFor: "max-input", className: "text-xs text-muted-foreground text-right", children: "Max" }),
|
|
136
|
+
/* @__PURE__ */ jsx(
|
|
137
|
+
Input,
|
|
138
|
+
{
|
|
139
|
+
id: "max-input",
|
|
140
|
+
type: "number",
|
|
141
|
+
value: maxInputValue,
|
|
142
|
+
onChange: handleMaxInputChange,
|
|
143
|
+
onBlur: handleMaxInputBlur,
|
|
144
|
+
onKeyDown: handleMaxInputKeyDown,
|
|
145
|
+
min: localRange[0],
|
|
146
|
+
max,
|
|
147
|
+
step,
|
|
148
|
+
disabled,
|
|
149
|
+
className: "h-7 text-xs [appearance:textfield] [&::-webkit-outer-spin-button]:m-0 [&::-webkit-outer-spin-button]:[-webkit-appearance:none] [&::-webkit-inner-spin-button]:m-0 [&::-webkit-inner-spin-button]:[-webkit-appearance:none]"
|
|
150
|
+
}
|
|
151
|
+
)
|
|
152
|
+
] })
|
|
65
153
|
] }),
|
|
66
154
|
!isDefaultRange && /* @__PURE__ */ jsx("div", { className: "flex justify-end", children: /* @__PURE__ */ jsx(
|
|
67
155
|
"button",
|
|
68
156
|
{
|
|
69
157
|
onClick: () => {
|
|
70
158
|
setLocalRange([min, max]);
|
|
159
|
+
setMinInputValue(min.toString());
|
|
160
|
+
setMaxInputValue(max.toString());
|
|
71
161
|
handleRangeCommit([min, max]);
|
|
72
162
|
},
|
|
73
163
|
className: "text-xs text-muted-foreground hover:text-foreground transition-colors",
|
|
@@ -76,6 +166,40 @@ function RangeSliderFilter({
|
|
|
76
166
|
}
|
|
77
167
|
) })
|
|
78
168
|
] });
|
|
169
|
+
if (usePopover) {
|
|
170
|
+
return /* @__PURE__ */ jsxs(Popover, { children: [
|
|
171
|
+
/* @__PURE__ */ jsxs(
|
|
172
|
+
PopoverTrigger,
|
|
173
|
+
{
|
|
174
|
+
className: cn(
|
|
175
|
+
buttonVariants({
|
|
176
|
+
variant: "default",
|
|
177
|
+
size: "default",
|
|
178
|
+
border: "bordered"
|
|
179
|
+
}),
|
|
180
|
+
"!bg-neutral-alpha-2",
|
|
181
|
+
className
|
|
182
|
+
),
|
|
183
|
+
disabled,
|
|
184
|
+
children: [
|
|
185
|
+
/* @__PURE__ */ jsxs("span", { className: "font-medium", children: [
|
|
186
|
+
label,
|
|
187
|
+
":"
|
|
188
|
+
] }),
|
|
189
|
+
/* @__PURE__ */ jsx("span", { className: "text-muted-foreground", children: showValues && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
190
|
+
"[",
|
|
191
|
+
formatValue(localRange[0]),
|
|
192
|
+
" - ",
|
|
193
|
+
formatValue(localRange[1]),
|
|
194
|
+
"]"
|
|
195
|
+
] }) })
|
|
196
|
+
]
|
|
197
|
+
}
|
|
198
|
+
),
|
|
199
|
+
/* @__PURE__ */ jsx(PopoverContent, { className: "min-w-96", children: filterContent })
|
|
200
|
+
] });
|
|
201
|
+
}
|
|
202
|
+
return /* @__PURE__ */ jsx("div", { className, children: filterContent });
|
|
79
203
|
}
|
|
80
204
|
|
|
81
205
|
// src/filters/BooleanFilter.tsx
|
|
@@ -105,30 +229,30 @@ function BooleanFilter({
|
|
|
105
229
|
|
|
106
230
|
// src/filters/Filter.tsx
|
|
107
231
|
import { useQueryState as useQueryState3, parseAsString } from "nuqs";
|
|
108
|
-
import { Fragment, jsx as jsx3 } from "react/jsx-runtime";
|
|
232
|
+
import { Fragment as Fragment2, jsx as jsx3 } from "react/jsx-runtime";
|
|
109
233
|
function Filter({ queryKey, children, onValueChange }) {
|
|
110
234
|
const [value, setValue] = useQueryState3(queryKey, parseAsString.withDefault(""));
|
|
111
235
|
const handleValueChange = (newValue) => {
|
|
112
236
|
setValue(newValue || null);
|
|
113
237
|
onValueChange?.(newValue);
|
|
114
238
|
};
|
|
115
|
-
return /* @__PURE__ */ jsx3(
|
|
239
|
+
return /* @__PURE__ */ jsx3(Fragment2, { children: children({ value, onValueChange: handleValueChange }) });
|
|
116
240
|
}
|
|
117
241
|
|
|
118
242
|
// src/filters/MultiSelectFilter.tsx
|
|
119
243
|
import { useQueryState as useQueryState4, parseAsArrayOf, parseAsString as parseAsString2 } from "nuqs";
|
|
120
|
-
import { Fragment as
|
|
244
|
+
import { Fragment as Fragment3, jsx as jsx4 } from "react/jsx-runtime";
|
|
121
245
|
function MultiSelectFilter({ queryKey, children, onValueChange }) {
|
|
122
246
|
const [value, setValue] = useQueryState4(queryKey, parseAsArrayOf(parseAsString2).withDefault([]));
|
|
123
247
|
const handleValueChange = (newValue) => {
|
|
124
248
|
setValue(newValue.length > 0 ? newValue : null);
|
|
125
249
|
onValueChange?.(newValue);
|
|
126
250
|
};
|
|
127
|
-
return /* @__PURE__ */ jsx4(
|
|
251
|
+
return /* @__PURE__ */ jsx4(Fragment3, { children: children({ value, onValueChange: handleValueChange }) });
|
|
128
252
|
}
|
|
129
253
|
|
|
130
254
|
// src/wrappers/FiltersGrid.tsx
|
|
131
|
-
import { cn } from "@turtleclub/ui";
|
|
255
|
+
import { cn as cn2 } from "@turtleclub/ui";
|
|
132
256
|
import { jsx as jsx5, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
133
257
|
function FiltersGrid({
|
|
134
258
|
filters,
|
|
@@ -152,12 +276,12 @@ function FiltersGrid({
|
|
|
152
276
|
{}
|
|
153
277
|
);
|
|
154
278
|
const sectionNames = Object.keys(sections);
|
|
155
|
-
return /* @__PURE__ */ jsx5("div", { className:
|
|
279
|
+
return /* @__PURE__ */ jsx5("div", { className: cn2("space-y-4", className), children: sectionNames.map((sectionName, sectionIndex) => /* @__PURE__ */ jsxs3("div", { children: [
|
|
156
280
|
sectionIndex > 0 && /* @__PURE__ */ jsx5("div", { className: "border-t border-border mb-4" }),
|
|
157
281
|
/* @__PURE__ */ jsx5(
|
|
158
282
|
"div",
|
|
159
283
|
{
|
|
160
|
-
className:
|
|
284
|
+
className: cn2("grid gap-2", sectionClassName),
|
|
161
285
|
style: {
|
|
162
286
|
gridTemplateColumns: `repeat(${columns}, minmax(0, 1fr))`
|
|
163
287
|
},
|
|
@@ -168,8 +292,13 @@ function FiltersGrid({
|
|
|
168
292
|
}
|
|
169
293
|
|
|
170
294
|
// src/wrappers/FiltersPopover.tsx
|
|
171
|
-
import {
|
|
172
|
-
|
|
295
|
+
import {
|
|
296
|
+
Popover as Popover2,
|
|
297
|
+
PopoverContent as PopoverContent2,
|
|
298
|
+
PopoverTrigger as PopoverTrigger2,
|
|
299
|
+
buttonVariants as buttonVariants2,
|
|
300
|
+
cn as cn3
|
|
301
|
+
} from "@turtleclub/ui";
|
|
173
302
|
import { jsx as jsx6, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
174
303
|
function FiltersPopover({
|
|
175
304
|
filters,
|
|
@@ -177,7 +306,9 @@ function FiltersPopover({
|
|
|
177
306
|
columns = 2,
|
|
178
307
|
className,
|
|
179
308
|
popoverClassName,
|
|
180
|
-
sectionClassName
|
|
309
|
+
sectionClassName,
|
|
310
|
+
align = "start",
|
|
311
|
+
onClearAll
|
|
181
312
|
}) {
|
|
182
313
|
const enabledFilters = filters.filter((filter) => filter.enabled);
|
|
183
314
|
if (enabledFilters.length === 0) {
|
|
@@ -195,24 +326,45 @@ function FiltersPopover({
|
|
|
195
326
|
{}
|
|
196
327
|
);
|
|
197
328
|
const sectionNames = Object.keys(sections);
|
|
198
|
-
return /* @__PURE__ */ jsxs4(
|
|
199
|
-
/* @__PURE__ */ jsx6(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsxs4(Button, { variant: "outline", className: cn2(className), children: [
|
|
200
|
-
/* @__PURE__ */ jsx6(SlidersHorizontal, { className: "mr-2 h-4 w-4" }),
|
|
201
|
-
triggerLabel
|
|
202
|
-
] }) }),
|
|
329
|
+
return /* @__PURE__ */ jsxs4(Popover2, { children: [
|
|
203
330
|
/* @__PURE__ */ jsx6(
|
|
204
|
-
|
|
331
|
+
PopoverTrigger2,
|
|
205
332
|
{
|
|
206
|
-
className:
|
|
207
|
-
|
|
333
|
+
className: cn3(
|
|
334
|
+
buttonVariants2({
|
|
335
|
+
variant: "default",
|
|
336
|
+
size: "default",
|
|
337
|
+
border: "bordered"
|
|
338
|
+
}),
|
|
339
|
+
"!bg-neutral-alpha-2",
|
|
340
|
+
className
|
|
341
|
+
),
|
|
342
|
+
children: triggerLabel
|
|
343
|
+
}
|
|
344
|
+
),
|
|
345
|
+
/* @__PURE__ */ jsx6(
|
|
346
|
+
PopoverContent2,
|
|
347
|
+
{
|
|
348
|
+
className: cn3("w-auto min-w-[400px] max-w-[600px]", popoverClassName),
|
|
349
|
+
align,
|
|
208
350
|
children: /* @__PURE__ */ jsxs4("div", { className: "space-y-4", children: [
|
|
209
|
-
/* @__PURE__ */
|
|
351
|
+
/* @__PURE__ */ jsxs4("div", { className: "flex items-center justify-between", children: [
|
|
352
|
+
/* @__PURE__ */ jsx6("h4", { className: "font-medium text-sm", children: "Filters" }),
|
|
353
|
+
onClearAll && /* @__PURE__ */ jsx6(
|
|
354
|
+
"button",
|
|
355
|
+
{
|
|
356
|
+
onClick: onClearAll,
|
|
357
|
+
className: "text-xs text-muted-foreground hover:text-foreground transition-colors",
|
|
358
|
+
children: "Reset all"
|
|
359
|
+
}
|
|
360
|
+
)
|
|
361
|
+
] }),
|
|
210
362
|
/* @__PURE__ */ jsx6("div", { className: "space-y-4", children: sectionNames.map((sectionName, sectionIndex) => /* @__PURE__ */ jsxs4("div", { children: [
|
|
211
363
|
sectionIndex > 0 && /* @__PURE__ */ jsx6("div", { className: "border-t border-border mb-4" }),
|
|
212
364
|
/* @__PURE__ */ jsx6(
|
|
213
365
|
"div",
|
|
214
366
|
{
|
|
215
|
-
className:
|
|
367
|
+
className: cn3("grid gap-2", sectionClassName),
|
|
216
368
|
style: {
|
|
217
369
|
gridTemplateColumns: `repeat(${columns}, minmax(0, 1fr))`
|
|
218
370
|
},
|
|
@@ -228,9 +380,9 @@ function FiltersPopover({
|
|
|
228
380
|
|
|
229
381
|
// src/wrappers/ActiveFilterBadges.tsx
|
|
230
382
|
import { useMemo } from "react";
|
|
231
|
-
import { Badge as Badge2, Button
|
|
383
|
+
import { Badge as Badge2, Button, cn as cn4 } from "@turtleclub/ui";
|
|
232
384
|
import { X } from "lucide-react";
|
|
233
|
-
import { Fragment as
|
|
385
|
+
import { Fragment as Fragment4, jsx as jsx7, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
234
386
|
function ActiveFilterBadges({
|
|
235
387
|
filters,
|
|
236
388
|
className,
|
|
@@ -250,7 +402,7 @@ function ActiveFilterBadges({
|
|
|
250
402
|
if (activeFilters.length === 0) {
|
|
251
403
|
return null;
|
|
252
404
|
}
|
|
253
|
-
return /* @__PURE__ */ jsxs5("div", { className:
|
|
405
|
+
return /* @__PURE__ */ jsxs5("div", { className: cn4("flex flex-wrap items-center gap-2", className), children: [
|
|
254
406
|
activeFilters.map((filter) => {
|
|
255
407
|
return /* @__PURE__ */ jsx7(
|
|
256
408
|
FilterBadge,
|
|
@@ -262,7 +414,7 @@ function ActiveFilterBadges({
|
|
|
262
414
|
filter.key
|
|
263
415
|
);
|
|
264
416
|
}),
|
|
265
|
-
showClearAll && activeFilters.length > 1 && /* @__PURE__ */ jsx7(
|
|
417
|
+
showClearAll && activeFilters.length > 1 && /* @__PURE__ */ jsx7(Button, { variant: "ghost", size: "sm", onClick: clearAll, className: "h-7 px-2 text-xs", children: clearAllLabel })
|
|
266
418
|
] });
|
|
267
419
|
}
|
|
268
420
|
function FilterBadge({ filter, renderBadge, onClearFilter }) {
|
|
@@ -270,7 +422,7 @@ function FilterBadge({ filter, renderBadge, onClearFilter }) {
|
|
|
270
422
|
onClearFilter(filter.queryKeys);
|
|
271
423
|
};
|
|
272
424
|
if (renderBadge) {
|
|
273
|
-
return /* @__PURE__ */ jsx7(
|
|
425
|
+
return /* @__PURE__ */ jsx7(Fragment4, { children: renderBadge(filter, clearFilter) });
|
|
274
426
|
}
|
|
275
427
|
return /* @__PURE__ */ jsxs5(Badge2, { className: "flex items-center gap-1 pr-1 border-border border", children: [
|
|
276
428
|
/* @__PURE__ */ jsxs5("span", { className: "text-xs", children: [
|
|
@@ -291,19 +443,23 @@ function FilterBadge({ filter, renderBadge, onClearFilter }) {
|
|
|
291
443
|
}
|
|
292
444
|
|
|
293
445
|
// src/wrappers/FiltersWrapper.tsx
|
|
294
|
-
import { cn as
|
|
295
|
-
import { jsx as jsx8, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
446
|
+
import { cn as cn5 } from "@turtleclub/ui";
|
|
447
|
+
import { Fragment as Fragment5, jsx as jsx8, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
296
448
|
function FiltersWrapper({
|
|
297
449
|
filters,
|
|
298
450
|
activeFilters,
|
|
299
451
|
layout,
|
|
300
452
|
className,
|
|
301
453
|
badgesClassName,
|
|
454
|
+
slotClassName,
|
|
455
|
+
leftSlot,
|
|
456
|
+
rightSlot,
|
|
302
457
|
columns = 3,
|
|
303
458
|
triggerLabel = "Filters",
|
|
304
459
|
popoverColumns = 2,
|
|
305
460
|
popoverClassName,
|
|
306
461
|
popoverContentClassName,
|
|
462
|
+
align = "start",
|
|
307
463
|
clearAllLabel = "Clear All",
|
|
308
464
|
showClearAll = true,
|
|
309
465
|
renderBadge,
|
|
@@ -312,17 +468,26 @@ function FiltersWrapper({
|
|
|
312
468
|
onClearAll
|
|
313
469
|
}) {
|
|
314
470
|
const hasActiveFilters = activeFilters.some((filter) => filter.isActive && filter.value);
|
|
315
|
-
return /* @__PURE__ */ jsxs6("div", { className:
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
{
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
471
|
+
return /* @__PURE__ */ jsxs6("div", { className: cn5("space-y-3", className), children: [
|
|
472
|
+
/* @__PURE__ */ jsxs6("div", { className: cn5("flex items-center gap-2", slotClassName), children: [
|
|
473
|
+
leftSlot,
|
|
474
|
+
/* @__PURE__ */ jsx8(Fragment5, { children: layout === "grid" ? /* @__PURE__ */ jsx8(FiltersGrid, { filters, columns, className: popoverClassName }) : /* @__PURE__ */ jsx8(
|
|
475
|
+
FiltersPopover,
|
|
476
|
+
{
|
|
477
|
+
filters,
|
|
478
|
+
triggerLabel,
|
|
479
|
+
columns: popoverColumns,
|
|
480
|
+
className: popoverClassName,
|
|
481
|
+
popoverClassName: popoverContentClassName,
|
|
482
|
+
align,
|
|
483
|
+
onClearAll: () => {
|
|
484
|
+
const allQueryKeys = activeFilters.map((filter) => filter.queryKeys).filter((keys) => keys !== void 0);
|
|
485
|
+
onClearAll(allQueryKeys);
|
|
486
|
+
}
|
|
487
|
+
}
|
|
488
|
+
) }),
|
|
489
|
+
rightSlot
|
|
490
|
+
] }),
|
|
326
491
|
showActiveBadges && hasActiveFilters && /* @__PURE__ */ jsx8(
|
|
327
492
|
ActiveFilterBadges,
|
|
328
493
|
{
|
|
@@ -548,7 +713,11 @@ function ChainsSelector({
|
|
|
548
713
|
closeOnSelect = true,
|
|
549
714
|
searchable = true
|
|
550
715
|
}) {
|
|
551
|
-
const { chains, isLoading } = useSupportedChains(
|
|
716
|
+
const { chains, isLoading } = useSupportedChains({
|
|
717
|
+
page: 1,
|
|
718
|
+
limit: 100
|
|
719
|
+
// High limit to fetch all chains
|
|
720
|
+
});
|
|
552
721
|
const chainOptions = useMemo4(() => {
|
|
553
722
|
if (!chains || chains.length === 0) return [];
|
|
554
723
|
const filteredChains = chains.filter((chain) => chain.status === "active");
|
|
@@ -601,8 +770,8 @@ function TokensSelector({
|
|
|
601
770
|
}) {
|
|
602
771
|
const isChainSelected = !!chainId && chainId.trim() !== "";
|
|
603
772
|
const { tokens, isLoading } = useSupportedTokens({
|
|
604
|
-
|
|
605
|
-
limit:
|
|
773
|
+
chainId: isChainSelected ? chainId : "",
|
|
774
|
+
limit: 9e3,
|
|
606
775
|
enabled: isChainSelected
|
|
607
776
|
});
|
|
608
777
|
const tokenOptions = useMemo5(() => {
|
|
@@ -694,14 +863,13 @@ function ProductsSelector({
|
|
|
694
863
|
}
|
|
695
864
|
|
|
696
865
|
// src/selectors/OpportunitiesSelector.tsx
|
|
697
|
-
import { useMemo as useMemo7
|
|
866
|
+
import { useMemo as useMemo7 } from "react";
|
|
698
867
|
import { MultiSelect as MultiSelect4 } from "@turtleclub/ui";
|
|
699
868
|
import { useOpportunities } from "@turtleclub/hooks";
|
|
700
869
|
import { jsx as jsx12 } from "react/jsx-runtime";
|
|
701
870
|
function OpportunitiesSelector({
|
|
702
871
|
value,
|
|
703
872
|
onValueChange,
|
|
704
|
-
productId,
|
|
705
873
|
placeholder = "Select opportunities",
|
|
706
874
|
disabled = false,
|
|
707
875
|
className,
|
|
@@ -709,13 +877,7 @@ function OpportunitiesSelector({
|
|
|
709
877
|
closeOnSelect = true,
|
|
710
878
|
searchable = true
|
|
711
879
|
}) {
|
|
712
|
-
const
|
|
713
|
-
const { data: opportunitiesData, isLoading } = useOpportunities({
|
|
714
|
-
filters: {
|
|
715
|
-
productId
|
|
716
|
-
},
|
|
717
|
-
enabled: isProductSelected
|
|
718
|
-
});
|
|
880
|
+
const { data: opportunitiesData, isLoading } = useOpportunities();
|
|
719
881
|
const opportunities = useMemo7(
|
|
720
882
|
() => opportunitiesData?.opportunities ?? [],
|
|
721
883
|
[opportunitiesData?.opportunities]
|
|
@@ -739,11 +901,6 @@ function OpportunitiesSelector({
|
|
|
739
901
|
) : void 0
|
|
740
902
|
}));
|
|
741
903
|
}, [opportunities]);
|
|
742
|
-
useEffect3(() => {
|
|
743
|
-
if (!isProductSelected && value.length > 0) {
|
|
744
|
-
onValueChange([]);
|
|
745
|
-
}
|
|
746
|
-
}, [isProductSelected, value, onValueChange]);
|
|
747
904
|
return /* @__PURE__ */ jsx12(
|
|
748
905
|
MultiSelect4,
|
|
749
906
|
{
|
|
@@ -751,8 +908,8 @@ function OpportunitiesSelector({
|
|
|
751
908
|
options: opportunityOptions,
|
|
752
909
|
value,
|
|
753
910
|
onValueChange,
|
|
754
|
-
disabled: disabled || isLoading
|
|
755
|
-
placeholder:
|
|
911
|
+
disabled: disabled || isLoading,
|
|
912
|
+
placeholder: isLoading ? "Loading opportunities..." : placeholder,
|
|
756
913
|
closeOnSelect,
|
|
757
914
|
maxCount,
|
|
758
915
|
className
|
|
@@ -774,7 +931,11 @@ function ChainSelector({
|
|
|
774
931
|
closeOnSelect = true,
|
|
775
932
|
searchable = true
|
|
776
933
|
}) {
|
|
777
|
-
const { chains, isLoading } = useSupportedChains2(
|
|
934
|
+
const { chains, isLoading } = useSupportedChains2({
|
|
935
|
+
page: 1,
|
|
936
|
+
limit: 100
|
|
937
|
+
// High limit to fetch all chains
|
|
938
|
+
});
|
|
778
939
|
const chainOptions = useMemo8(() => {
|
|
779
940
|
if (!chains || chains.length === 0) return [];
|
|
780
941
|
const filteredChains = chains.filter((chain) => chain.status === "active");
|
|
@@ -809,7 +970,7 @@ function ChainSelector({
|
|
|
809
970
|
}
|
|
810
971
|
|
|
811
972
|
// src/selectors/TokenSelector.tsx
|
|
812
|
-
import { useEffect as
|
|
973
|
+
import { useEffect as useEffect3, useMemo as useMemo9 } from "react";
|
|
813
974
|
import { Combobox as Combobox2 } from "@turtleclub/ui";
|
|
814
975
|
import { useSupportedTokens as useSupportedTokens2 } from "@turtleclub/hooks";
|
|
815
976
|
import { jsx as jsx14 } from "react/jsx-runtime";
|
|
@@ -825,8 +986,8 @@ function TokenSelector({
|
|
|
825
986
|
}) {
|
|
826
987
|
const isChainSelected = !!chainId && chainId.trim() !== "";
|
|
827
988
|
const { tokens, isLoading } = useSupportedTokens2({
|
|
828
|
-
|
|
829
|
-
limit:
|
|
989
|
+
chainId: isChainSelected ? chainId : "",
|
|
990
|
+
limit: 9e3,
|
|
830
991
|
enabled: isChainSelected
|
|
831
992
|
});
|
|
832
993
|
const tokenOptions = useMemo9(() => {
|
|
@@ -846,7 +1007,7 @@ function TokenSelector({
|
|
|
846
1007
|
) : void 0
|
|
847
1008
|
}));
|
|
848
1009
|
}, [tokens]);
|
|
849
|
-
|
|
1010
|
+
useEffect3(() => {
|
|
850
1011
|
if (!isChainSelected && value) {
|
|
851
1012
|
onValueChange("");
|
|
852
1013
|
}
|
|
@@ -915,27 +1076,20 @@ function ProductSelector({
|
|
|
915
1076
|
}
|
|
916
1077
|
|
|
917
1078
|
// src/selectors/OpportunitySelector.tsx
|
|
918
|
-
import { useMemo as useMemo11
|
|
1079
|
+
import { useMemo as useMemo11 } from "react";
|
|
919
1080
|
import { Combobox as Combobox4 } from "@turtleclub/ui";
|
|
920
1081
|
import { useOpportunities as useOpportunities2 } from "@turtleclub/hooks";
|
|
921
1082
|
import { jsx as jsx16 } from "react/jsx-runtime";
|
|
922
1083
|
function OpportunitySelector({
|
|
923
1084
|
value,
|
|
924
1085
|
onValueChange,
|
|
925
|
-
productId,
|
|
926
1086
|
placeholder = "Select opportunity",
|
|
927
1087
|
disabled = false,
|
|
928
1088
|
className,
|
|
929
1089
|
closeOnSelect = true,
|
|
930
1090
|
searchable = true
|
|
931
1091
|
}) {
|
|
932
|
-
const
|
|
933
|
-
const { data: opportunitiesData, isLoading } = useOpportunities2({
|
|
934
|
-
filters: {
|
|
935
|
-
productId
|
|
936
|
-
},
|
|
937
|
-
enabled: isProductSelected
|
|
938
|
-
});
|
|
1092
|
+
const { data: opportunitiesData, isLoading } = useOpportunities2();
|
|
939
1093
|
const opportunities = useMemo11(
|
|
940
1094
|
() => opportunitiesData?.opportunities ?? [],
|
|
941
1095
|
[opportunitiesData?.opportunities]
|
|
@@ -959,11 +1113,6 @@ function OpportunitySelector({
|
|
|
959
1113
|
) : void 0
|
|
960
1114
|
}));
|
|
961
1115
|
}, [opportunities]);
|
|
962
|
-
useEffect5(() => {
|
|
963
|
-
if (!isProductSelected && value) {
|
|
964
|
-
onValueChange("");
|
|
965
|
-
}
|
|
966
|
-
}, [isProductSelected, value, onValueChange]);
|
|
967
1116
|
return /* @__PURE__ */ jsx16(
|
|
968
1117
|
Combobox4,
|
|
969
1118
|
{
|
|
@@ -971,8 +1120,8 @@ function OpportunitySelector({
|
|
|
971
1120
|
options: opportunityOptions,
|
|
972
1121
|
value,
|
|
973
1122
|
onValueChange,
|
|
974
|
-
disabled: disabled || isLoading
|
|
975
|
-
placeholder:
|
|
1123
|
+
disabled: disabled || isLoading,
|
|
1124
|
+
placeholder: isLoading ? "Loading opportunities..." : placeholder,
|
|
976
1125
|
closeOnSelect,
|
|
977
1126
|
className
|
|
978
1127
|
}
|