@giddaa-housing/ui 0.1.0 → 1.1.0

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.
Files changed (315) hide show
  1. package/README.md +18 -6
  2. package/css/base.css +37 -0
  3. package/css/components.css +135 -0
  4. package/css/generated/shared.css +1 -0
  5. package/css/giddaa.css +402 -0
  6. package/css/preset.css +77 -0
  7. package/css/styles.css +2 -0
  8. package/css/theme.css +255 -0
  9. package/dist/accordion.d.ts +9 -10
  10. package/dist/accordion.js +41 -117
  11. package/dist/activity-timeline.d.ts +29 -0
  12. package/dist/activity-timeline.js +97 -0
  13. package/dist/alert.d.ts +8 -9
  14. package/dist/alert.js +53 -141
  15. package/dist/auth-layout.d.ts +23 -0
  16. package/dist/auth-layout.js +153 -0
  17. package/dist/avatar.d.ts +6 -6
  18. package/dist/avatar.js +40 -142
  19. package/dist/badge.d.ts +12 -13
  20. package/dist/badge.js +66 -114
  21. package/dist/bar-chart.d.ts +136 -114
  22. package/dist/bar-chart.js +244 -297
  23. package/dist/breadcrumb.d.ts +5 -5
  24. package/dist/breadcrumb.js +56 -148
  25. package/dist/bullet-chart.d.ts +33 -33
  26. package/dist/bullet-chart.js +123 -183
  27. package/dist/button-BZIeyUw6.d.ts +17 -0
  28. package/dist/button-group.d.ts +13 -16
  29. package/dist/button-group.js +38 -163
  30. package/dist/button.d.ts +2 -19
  31. package/dist/button.js +90 -142
  32. package/dist/calendar.d.ts +6 -6
  33. package/dist/calendar.js +134 -288
  34. package/dist/card.d.ts +14 -16
  35. package/dist/card.js +58 -174
  36. package/dist/carousel.d.ts +34 -35
  37. package/dist/carousel.js +319 -378
  38. package/dist/chart.d.ts +58 -59
  39. package/dist/chart.js +350 -466
  40. package/dist/checkbox.d.ts +10 -12
  41. package/dist/checkbox.js +84 -84
  42. package/dist/cn-BI_4DMBf.js +23 -0
  43. package/dist/collapsible.d.ts +7 -8
  44. package/dist/collapsible.js +23 -77
  45. package/dist/combobox.d.ts +10 -10
  46. package/dist/combobox.js +220 -696
  47. package/dist/cta.d.ts +64 -0
  48. package/dist/cta.js +192 -0
  49. package/dist/currency-selector.d.ts +41 -0
  50. package/dist/currency-selector.js +114 -0
  51. package/dist/data-table.d.ts +164 -0
  52. package/dist/data-table.js +673 -0
  53. package/dist/date-picker.d.ts +27 -20
  54. package/dist/date-picker.js +122 -520
  55. package/dist/details-card.d.ts +19 -0
  56. package/dist/details-card.js +118 -0
  57. package/dist/dialog.d.ts +13 -14
  58. package/dist/dialog.js +117 -320
  59. package/dist/dropdown-menu.d.ts +14 -14
  60. package/dist/dropdown-menu.js +170 -365
  61. package/dist/dropzone.d.ts +55 -55
  62. package/dist/dropzone.js +328 -467
  63. package/dist/editorial-card.d.ts +27 -0
  64. package/dist/editorial-card.js +144 -0
  65. package/dist/empty-state.d.ts +8 -9
  66. package/dist/empty-state.js +48 -135
  67. package/dist/field.d.ts +23 -25
  68. package/dist/field.js +111 -327
  69. package/dist/filter.d.ts +118 -0
  70. package/dist/filter.js +775 -0
  71. package/dist/footer.d.ts +40 -0
  72. package/dist/footer.js +227 -0
  73. package/dist/funnel-chart.d.ts +38 -41
  74. package/dist/funnel-chart.js +168 -563
  75. package/dist/gallery-indicator.d.ts +17 -0
  76. package/dist/gallery-indicator.js +75 -0
  77. package/dist/heatmap-chart.d.ts +95 -0
  78. package/dist/heatmap-chart.js +197 -0
  79. package/dist/infotip.d.ts +10 -0
  80. package/dist/infotip.js +40 -0
  81. package/dist/input-CfoEJ8A6.d.ts +12 -0
  82. package/dist/input-group.d.ts +16 -19
  83. package/dist/input-group.js +92 -372
  84. package/dist/input-size-context-C-SFx9sx.d.ts +10 -0
  85. package/dist/input-size-context.d.ts +2 -11
  86. package/dist/input-size-context.js +14 -20
  87. package/dist/input.d.ts +2 -13
  88. package/dist/input.js +23 -79
  89. package/dist/item.d.ts +7 -8
  90. package/dist/item.js +22 -89
  91. package/dist/kpi-card.d.ts +18 -20
  92. package/dist/kpi-card.js +84 -232
  93. package/dist/label.d.ts +6 -6
  94. package/dist/label.js +39 -66
  95. package/dist/line-chart.d.ts +88 -89
  96. package/dist/line-chart.js +143 -262
  97. package/dist/logo.d.ts +4 -4
  98. package/dist/logo.js +87 -141
  99. package/dist/map-indicator.d.ts +13 -0
  100. package/dist/map-indicator.js +83 -0
  101. package/dist/match.d.ts +15 -0
  102. package/dist/match.js +68 -0
  103. package/dist/media-gallery-hero.d.ts +58 -0
  104. package/dist/media-gallery-hero.js +201 -0
  105. package/dist/media-player.d.ts +60 -0
  106. package/dist/media-player.js +919 -0
  107. package/dist/multi-step-form.d.ts +56 -0
  108. package/dist/multi-step-form.js +342 -0
  109. package/dist/number-input.d.ts +34 -34
  110. package/dist/number-input.js +62 -413
  111. package/dist/page-header.d.ts +10 -11
  112. package/dist/page-header.js +34 -107
  113. package/dist/pagination.d.ts +17 -20
  114. package/dist/pagination.js +132 -341
  115. package/dist/password-input.d.ts +5 -12
  116. package/dist/password-input.js +32 -354
  117. package/dist/phone-input.d.ts +19 -19
  118. package/dist/phone-input.js +232 -561
  119. package/dist/photo-gallery.d.ts +20 -20
  120. package/dist/photo-gallery.js +314 -746
  121. package/dist/picker-lzgmsNfG.js +32 -0
  122. package/dist/pie-chart.d.ts +60 -60
  123. package/dist/pie-chart.js +141 -184
  124. package/dist/popover.d.ts +9 -9
  125. package/dist/popover.js +60 -156
  126. package/dist/price-tag.d.ts +34 -0
  127. package/dist/price-tag.js +118 -0
  128. package/dist/progress.d.ts +18 -16
  129. package/dist/progress.js +156 -300
  130. package/dist/property-listing-card.d.ts +29 -0
  131. package/dist/property-listing-card.js +117 -0
  132. package/dist/radar-chart.d.ts +108 -0
  133. package/dist/radar-chart.js +172 -0
  134. package/dist/radio-group.d.ts +11 -13
  135. package/dist/radio-group.js +47 -96
  136. package/dist/review-block.d.ts +18 -0
  137. package/dist/review-block.js +154 -0
  138. package/dist/rich-text-editor.d.ts +30 -14
  139. package/dist/rich-text-editor.js +594 -979
  140. package/dist/scatter-chart.d.ts +140 -0
  141. package/dist/scatter-chart.js +248 -0
  142. package/dist/search-input.d.ts +8 -15
  143. package/dist/search-input.js +58 -408
  144. package/dist/select.d.ts +8 -8
  145. package/dist/select.js +131 -291
  146. package/dist/separator.d.ts +8 -9
  147. package/dist/separator.js +31 -70
  148. package/dist/sheet.d.ts +11 -11
  149. package/dist/sheet.js +84 -262
  150. package/dist/sidebar.d.ts +32 -37
  151. package/dist/sidebar.js +380 -1055
  152. package/dist/size-context-D4mYvcg8.d.ts +10 -0
  153. package/dist/size-context.d.ts +2 -11
  154. package/dist/size-context.js +14 -18
  155. package/dist/skeleton.d.ts +4 -5
  156. package/dist/skeleton.js +9 -45
  157. package/dist/slider.d.ts +27 -0
  158. package/dist/slider.js +81 -0
  159. package/dist/sparkline.d.ts +43 -46
  160. package/dist/sparkline.js +223 -561
  161. package/dist/stepper.d.ts +23 -24
  162. package/dist/stepper.js +149 -276
  163. package/dist/styles.css +9995 -2
  164. package/dist/switch.d.ts +10 -12
  165. package/dist/switch.js +49 -106
  166. package/dist/table-card.d.ts +35 -0
  167. package/dist/table-card.js +125 -0
  168. package/dist/table.d.ts +18 -14
  169. package/dist/table.js +114 -182
  170. package/dist/tabs.d.ts +23 -15
  171. package/dist/tabs.js +62 -149
  172. package/dist/tag.d.ts +22 -23
  173. package/dist/tag.js +104 -156
  174. package/dist/testimonial-block.d.ts +33 -0
  175. package/dist/testimonial-block.js +208 -0
  176. package/dist/textarea-IS_D8pXf.d.ts +11 -0
  177. package/dist/textarea.d.ts +2 -12
  178. package/dist/textarea.js +20 -74
  179. package/dist/time-picker.d.ts +11 -11
  180. package/dist/time-picker.js +247 -464
  181. package/dist/toast.d.ts +16 -18
  182. package/dist/toast.js +154 -310
  183. package/dist/tooltip.d.ts +9 -10
  184. package/dist/tooltip.js +33 -91
  185. package/dist/tree-map.d.ts +54 -57
  186. package/dist/tree-map.js +231 -646
  187. package/dist/use-uncontrolled-CLfM1XbB.js +21 -0
  188. package/dist/waterfall-chart.d.ts +126 -0
  189. package/dist/waterfall-chart.js +480 -0
  190. package/package.json +123 -34
  191. package/dist/accordion.js.map +0 -1
  192. package/dist/alert.js.map +0 -1
  193. package/dist/avatar.js.map +0 -1
  194. package/dist/badge.js.map +0 -1
  195. package/dist/bar-chart.js.map +0 -1
  196. package/dist/base.css +0 -32
  197. package/dist/breadcrumb.js.map +0 -1
  198. package/dist/bullet-chart.js.map +0 -1
  199. package/dist/button-group.js.map +0 -1
  200. package/dist/button.js.map +0 -1
  201. package/dist/calendar.js.map +0 -1
  202. package/dist/card.js.map +0 -1
  203. package/dist/carousel.js.map +0 -1
  204. package/dist/chart.js.map +0 -1
  205. package/dist/checkbox.js.map +0 -1
  206. package/dist/collapsible.js.map +0 -1
  207. package/dist/combobox.js.map +0 -1
  208. package/dist/date-picker.js.map +0 -1
  209. package/dist/dialog.js.map +0 -1
  210. package/dist/dropdown-menu.js.map +0 -1
  211. package/dist/dropzone.js.map +0 -1
  212. package/dist/empty-state.js.map +0 -1
  213. package/dist/field.js.map +0 -1
  214. package/dist/files/red-hat-display-latin-300-italic.woff +0 -0
  215. package/dist/files/red-hat-display-latin-300-italic.woff2 +0 -0
  216. package/dist/files/red-hat-display-latin-300-normal.woff +0 -0
  217. package/dist/files/red-hat-display-latin-300-normal.woff2 +0 -0
  218. package/dist/files/red-hat-display-latin-400-italic.woff +0 -0
  219. package/dist/files/red-hat-display-latin-400-italic.woff2 +0 -0
  220. package/dist/files/red-hat-display-latin-400-normal.woff +0 -0
  221. package/dist/files/red-hat-display-latin-400-normal.woff2 +0 -0
  222. package/dist/files/red-hat-display-latin-500-italic.woff +0 -0
  223. package/dist/files/red-hat-display-latin-500-italic.woff2 +0 -0
  224. package/dist/files/red-hat-display-latin-500-normal.woff +0 -0
  225. package/dist/files/red-hat-display-latin-500-normal.woff2 +0 -0
  226. package/dist/files/red-hat-display-latin-600-italic.woff +0 -0
  227. package/dist/files/red-hat-display-latin-600-italic.woff2 +0 -0
  228. package/dist/files/red-hat-display-latin-600-normal.woff +0 -0
  229. package/dist/files/red-hat-display-latin-600-normal.woff2 +0 -0
  230. package/dist/files/red-hat-display-latin-700-italic.woff +0 -0
  231. package/dist/files/red-hat-display-latin-700-italic.woff2 +0 -0
  232. package/dist/files/red-hat-display-latin-700-normal.woff +0 -0
  233. package/dist/files/red-hat-display-latin-700-normal.woff2 +0 -0
  234. package/dist/files/red-hat-display-latin-800-italic.woff +0 -0
  235. package/dist/files/red-hat-display-latin-800-italic.woff2 +0 -0
  236. package/dist/files/red-hat-display-latin-800-normal.woff +0 -0
  237. package/dist/files/red-hat-display-latin-800-normal.woff2 +0 -0
  238. package/dist/files/red-hat-display-latin-900-italic.woff +0 -0
  239. package/dist/files/red-hat-display-latin-900-italic.woff2 +0 -0
  240. package/dist/files/red-hat-display-latin-900-normal.woff +0 -0
  241. package/dist/files/red-hat-display-latin-900-normal.woff2 +0 -0
  242. package/dist/files/red-hat-display-latin-ext-300-italic.woff +0 -0
  243. package/dist/files/red-hat-display-latin-ext-300-italic.woff2 +0 -0
  244. package/dist/files/red-hat-display-latin-ext-300-normal.woff +0 -0
  245. package/dist/files/red-hat-display-latin-ext-300-normal.woff2 +0 -0
  246. package/dist/files/red-hat-display-latin-ext-400-italic.woff +0 -0
  247. package/dist/files/red-hat-display-latin-ext-400-italic.woff2 +0 -0
  248. package/dist/files/red-hat-display-latin-ext-400-normal.woff +0 -0
  249. package/dist/files/red-hat-display-latin-ext-400-normal.woff2 +0 -0
  250. package/dist/files/red-hat-display-latin-ext-500-italic.woff +0 -0
  251. package/dist/files/red-hat-display-latin-ext-500-italic.woff2 +0 -0
  252. package/dist/files/red-hat-display-latin-ext-500-normal.woff +0 -0
  253. package/dist/files/red-hat-display-latin-ext-500-normal.woff2 +0 -0
  254. package/dist/files/red-hat-display-latin-ext-600-italic.woff +0 -0
  255. package/dist/files/red-hat-display-latin-ext-600-italic.woff2 +0 -0
  256. package/dist/files/red-hat-display-latin-ext-600-normal.woff +0 -0
  257. package/dist/files/red-hat-display-latin-ext-600-normal.woff2 +0 -0
  258. package/dist/files/red-hat-display-latin-ext-700-italic.woff +0 -0
  259. package/dist/files/red-hat-display-latin-ext-700-italic.woff2 +0 -0
  260. package/dist/files/red-hat-display-latin-ext-700-normal.woff +0 -0
  261. package/dist/files/red-hat-display-latin-ext-700-normal.woff2 +0 -0
  262. package/dist/files/red-hat-display-latin-ext-800-italic.woff +0 -0
  263. package/dist/files/red-hat-display-latin-ext-800-italic.woff2 +0 -0
  264. package/dist/files/red-hat-display-latin-ext-800-normal.woff +0 -0
  265. package/dist/files/red-hat-display-latin-ext-800-normal.woff2 +0 -0
  266. package/dist/files/red-hat-display-latin-ext-900-italic.woff +0 -0
  267. package/dist/files/red-hat-display-latin-ext-900-italic.woff2 +0 -0
  268. package/dist/files/red-hat-display-latin-ext-900-normal.woff +0 -0
  269. package/dist/files/red-hat-display-latin-ext-900-normal.woff2 +0 -0
  270. package/dist/funnel-chart.js.map +0 -1
  271. package/dist/index.d.ts +0 -87
  272. package/dist/index.js +0 -10448
  273. package/dist/index.js.map +0 -1
  274. package/dist/input-group.js.map +0 -1
  275. package/dist/input-size-context.js.map +0 -1
  276. package/dist/input.js.map +0 -1
  277. package/dist/item.js.map +0 -1
  278. package/dist/kpi-card.js.map +0 -1
  279. package/dist/label.js.map +0 -1
  280. package/dist/line-chart.js.map +0 -1
  281. package/dist/logo.js.map +0 -1
  282. package/dist/number-input.js.map +0 -1
  283. package/dist/page-header.js.map +0 -1
  284. package/dist/pagination.js.map +0 -1
  285. package/dist/password-input.js.map +0 -1
  286. package/dist/phone-input.js.map +0 -1
  287. package/dist/photo-gallery.js.map +0 -1
  288. package/dist/pie-chart.js.map +0 -1
  289. package/dist/popover.js.map +0 -1
  290. package/dist/progress.js.map +0 -1
  291. package/dist/radio-group.js.map +0 -1
  292. package/dist/red-hat-display.css +0 -2
  293. package/dist/rich-text-editor.js.map +0 -1
  294. package/dist/search-input.js.map +0 -1
  295. package/dist/select.js.map +0 -1
  296. package/dist/separator.js.map +0 -1
  297. package/dist/sheet.js.map +0 -1
  298. package/dist/sidebar.js.map +0 -1
  299. package/dist/size-context.js.map +0 -1
  300. package/dist/skeleton.js.map +0 -1
  301. package/dist/sparkline.js.map +0 -1
  302. package/dist/stepper.js.map +0 -1
  303. package/dist/switch.js.map +0 -1
  304. package/dist/tab-list.d.ts +0 -38
  305. package/dist/tab-list.js +0 -394
  306. package/dist/tab-list.js.map +0 -1
  307. package/dist/table.js.map +0 -1
  308. package/dist/tabs.js.map +0 -1
  309. package/dist/tag.js.map +0 -1
  310. package/dist/textarea.js.map +0 -1
  311. package/dist/theme/giddaa.css +0 -2
  312. package/dist/time-picker.js.map +0 -1
  313. package/dist/toast.js.map +0 -1
  314. package/dist/tooltip.js.map +0 -1
  315. package/dist/tree-map.js.map +0 -1
package/dist/filter.js ADDED
@@ -0,0 +1,775 @@
1
+ "use client";
2
+ import { t as cn } from "./cn-BI_4DMBf.js";
3
+ import { Button } from "./button.js";
4
+ import { Input } from "./input.js";
5
+ import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "./select.js";
6
+ import { Field, FieldError } from "./field.js";
7
+ import { Plus, X } from "lucide-react";
8
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
9
+ import * as React from "react";
10
+ //#region src/filter.tsx
11
+ const emptyFilterState = {
12
+ appliedCount: 0,
13
+ errors: {},
14
+ ids: [],
15
+ rows: {}
16
+ };
17
+ const conditionsByType = {
18
+ boolean: [{
19
+ id: "equals",
20
+ name: "Equals"
21
+ }],
22
+ date: [
23
+ {
24
+ id: "equals",
25
+ name: "Equals"
26
+ },
27
+ {
28
+ id: "lessThan",
29
+ name: "Less Than"
30
+ },
31
+ {
32
+ id: "greaterThan",
33
+ name: "Greater Than"
34
+ }
35
+ ],
36
+ multiSelect: [{
37
+ id: "equals",
38
+ name: "Equals"
39
+ }],
40
+ number: [
41
+ {
42
+ id: "equals",
43
+ name: "Equals"
44
+ },
45
+ {
46
+ id: "lessThan",
47
+ name: "Less Than"
48
+ },
49
+ {
50
+ id: "greaterThan",
51
+ name: "Greater Than"
52
+ }
53
+ ],
54
+ select: [{
55
+ id: "equals",
56
+ name: "Equals"
57
+ }],
58
+ text: [{
59
+ id: "contains",
60
+ name: "Contains"
61
+ }, {
62
+ id: "equals",
63
+ name: "Equals"
64
+ }]
65
+ };
66
+ const RANGE_CONDITION = "range";
67
+ function getValueError(value) {
68
+ if (typeof value === "undefined") return "Value is required";
69
+ if (Array.isArray(value) && value.length === 0) return "Value is required";
70
+ if (typeof value === "string" && value.trim() === "") return "Value is required";
71
+ if (typeof value === "object" && !Array.isArray(value) && value !== null) {
72
+ const rangeValue = getRangeValue(value);
73
+ if (!rangeValue) return "Value is required";
74
+ if (typeof rangeValue.min === "number" && typeof rangeValue.max === "number" && rangeValue.min > rangeValue.max) return "Min cannot be greater than max";
75
+ }
76
+ }
77
+ function getRowItemError(item, row) {
78
+ if (item === "field") return row.field ? void 0 : "Field is required";
79
+ if (item === "condition") return row.condition ? void 0 : "Condition is required";
80
+ return getValueError(row.value);
81
+ }
82
+ function getRowErrors(row) {
83
+ const errors = {};
84
+ for (const item of [
85
+ "field",
86
+ "condition",
87
+ "value"
88
+ ]) {
89
+ const error = getRowItemError(item, row);
90
+ if (error) errors[item] = error;
91
+ }
92
+ return errors;
93
+ }
94
+ function withRowItemError(errors, id, item, row, clearItems = []) {
95
+ const rowErrors = { ...errors[id] };
96
+ for (const clearItem of clearItems) delete rowErrors[clearItem];
97
+ const itemError = getRowItemError(item, row);
98
+ if (itemError) rowErrors[item] = itemError;
99
+ else delete rowErrors[item];
100
+ const nextErrors = { ...errors };
101
+ if (Object.keys(rowErrors).length) nextErrors[id] = rowErrors;
102
+ else delete nextErrors[id];
103
+ return nextErrors;
104
+ }
105
+ function filterReducer(state, action) {
106
+ switch (action.type) {
107
+ case "replace-state": return action.state;
108
+ case "add-row":
109
+ if (state.ids.includes(action.id)) return state;
110
+ return {
111
+ ...state,
112
+ ids: [...state.ids, action.id],
113
+ rows: {
114
+ ...state.rows,
115
+ [action.id]: action.row
116
+ }
117
+ };
118
+ case "remove-row": {
119
+ const rows = { ...state.rows };
120
+ const errors = { ...state.errors };
121
+ delete rows[action.id];
122
+ delete errors[action.id];
123
+ return {
124
+ ...state,
125
+ errors,
126
+ ids: state.ids.filter((id) => id !== action.id),
127
+ rows
128
+ };
129
+ }
130
+ case "set-row-field": {
131
+ if (!state.rows[action.id]) return state;
132
+ const row = {
133
+ field: action.field,
134
+ condition: action.condition,
135
+ value: void 0
136
+ };
137
+ return {
138
+ ...state,
139
+ errors: withRowItemError(state.errors, action.id, "field", row, ["condition", "value"]),
140
+ rows: {
141
+ ...state.rows,
142
+ [action.id]: row
143
+ }
144
+ };
145
+ }
146
+ case "set-row-condition": {
147
+ const currentRow = state.rows[action.id];
148
+ if (!currentRow) return state;
149
+ const row = {
150
+ ...currentRow,
151
+ condition: action.condition
152
+ };
153
+ return {
154
+ ...state,
155
+ errors: withRowItemError(state.errors, action.id, "condition", row),
156
+ rows: {
157
+ ...state.rows,
158
+ [action.id]: row
159
+ }
160
+ };
161
+ }
162
+ case "set-row-value": {
163
+ const currentRow = state.rows[action.id];
164
+ if (!currentRow) return state;
165
+ const row = {
166
+ ...currentRow,
167
+ value: action.value
168
+ };
169
+ return {
170
+ ...state,
171
+ errors: withRowItemError(state.errors, action.id, "value", row),
172
+ rows: {
173
+ ...state.rows,
174
+ [action.id]: row
175
+ }
176
+ };
177
+ }
178
+ case "apply": {
179
+ const hasErrors = Object.keys(action.errors).length > 0;
180
+ return {
181
+ ...state,
182
+ appliedCount: hasErrors ? state.appliedCount : state.ids.length,
183
+ errors: action.errors
184
+ };
185
+ }
186
+ case "reset": return emptyFilterState;
187
+ }
188
+ }
189
+ const FilterContext = React.createContext(null);
190
+ function useFilterContext() {
191
+ const context = React.useContext(FilterContext);
192
+ if (!context) throw new Error("Filter components must be rendered inside <Filter />.");
193
+ return context;
194
+ }
195
+ function Filter({ children, defaultJoin = "AND", fields, onApply, defaultValue = "" }) {
196
+ const [state, dispatch] = React.useReducer(filterReducer, void 0, () => buildStateFromSerializedFilters(defaultValue, fields));
197
+ const contentRef = React.useRef(null);
198
+ const loadedOptionsCache = React.useRef(/* @__PURE__ */ new Map());
199
+ const fieldsRef = React.useRef(fields);
200
+ fieldsRef.current = fields;
201
+ const fieldSignature = fields.map((field) => `${field.field}:${field.type}`).join("");
202
+ const lastDefaultValueRef = React.useRef(defaultValue);
203
+ const lastFieldSignatureRef = React.useRef(fieldSignature);
204
+ React.useEffect(() => {
205
+ if (lastDefaultValueRef.current === defaultValue && lastFieldSignatureRef.current === fieldSignature) return;
206
+ lastDefaultValueRef.current = defaultValue;
207
+ lastFieldSignatureRef.current = fieldSignature;
208
+ loadedOptionsCache.current.clear();
209
+ dispatch({
210
+ type: "replace-state",
211
+ state: buildStateFromSerializedFilters(defaultValue, fieldsRef.current)
212
+ });
213
+ }, [defaultValue, fieldSignature]);
214
+ const value = React.useMemo(() => ({
215
+ contentRef,
216
+ defaultJoin,
217
+ dispatch,
218
+ fields,
219
+ loadedOptionsCache,
220
+ onApply,
221
+ state
222
+ }), [
223
+ defaultJoin,
224
+ fields,
225
+ onApply,
226
+ state
227
+ ]);
228
+ return /* @__PURE__ */ jsx(FilterContext.Provider, {
229
+ value,
230
+ children
231
+ });
232
+ }
233
+ function FilterTrigger({ children, className, countClassName, hideCountWhenZero = true, render }) {
234
+ const { state } = useFilterContext();
235
+ const appliedCount = state.appliedCount;
236
+ if (render) return /* @__PURE__ */ jsx(Fragment, { children: render({ count: appliedCount }) });
237
+ return /* @__PURE__ */ jsxs("div", {
238
+ className: cn("relative", className),
239
+ children: [children, (appliedCount > 0 || !hideCountWhenZero) && /* @__PURE__ */ jsx("span", {
240
+ className: cn("absolute left-0 top-0 inline-flex size-5 translate-y-[-40%] items-center justify-center rounded-full bg-action-primary text-xs font-bold leading-none text-fg-on-brand", countClassName),
241
+ children: appliedCount
242
+ })]
243
+ });
244
+ }
245
+ let rowIdCounter = 0;
246
+ function createRow(fieldConfig) {
247
+ return {
248
+ field: fieldConfig?.field ?? "",
249
+ condition: fieldConfig?.type === "range" ? RANGE_CONDITION : ""
250
+ };
251
+ }
252
+ function FilterContent({ addFilterLabel = "Add Filter", className, label = "Where" }) {
253
+ const { contentRef, dispatch, fields, state } = useFilterContext();
254
+ return /* @__PURE__ */ jsx("div", {
255
+ ref: contentRef,
256
+ className: cn("max-h-80 space-y-4 overflow-y-auto pb-6", className),
257
+ children: /* @__PURE__ */ jsxs("div", {
258
+ className: "flex flex-col gap-y-4",
259
+ children: [
260
+ /* @__PURE__ */ jsx("p", {
261
+ className: "text-sm font-bold uppercase",
262
+ children: label
263
+ }),
264
+ !!state.ids.length && /* @__PURE__ */ jsx("div", {
265
+ className: "flex w-full flex-col gap-y-4",
266
+ children: state.ids.map((rowId) => /* @__PURE__ */ jsx(FilterRow, { id: rowId }, rowId))
267
+ }),
268
+ /* @__PURE__ */ jsxs(Button, {
269
+ type: "button",
270
+ variant: "ghost",
271
+ className: "w-fit gap-1.5 px-0 text-fg-brand hover:bg-transparent hover:text-action-secondary active:bg-transparent",
272
+ onClick: () => {
273
+ rowIdCounter += 1;
274
+ dispatch({
275
+ type: "add-row",
276
+ id: `filter-row-${rowIdCounter}`,
277
+ row: createRow(fields[0])
278
+ });
279
+ },
280
+ children: [/* @__PURE__ */ jsx(Plus, {}), addFilterLabel]
281
+ })
282
+ ]
283
+ })
284
+ });
285
+ }
286
+ function FilterRow({ id }) {
287
+ const { dispatch, fields, state } = useFilterContext();
288
+ const row = state.rows[id];
289
+ const fieldConfig = fields.find((config) => config.field === row?.field);
290
+ if (!row || !fieldConfig) return null;
291
+ return /* @__PURE__ */ jsxs("div", {
292
+ className: "flex items-start gap-4 md:gap-2",
293
+ children: [/* @__PURE__ */ jsxs("div", {
294
+ className: "grid flex-1 grid-cols-1 gap-4 md:grid-cols-3",
295
+ children: [
296
+ /* @__PURE__ */ jsx(FilterRowField, {
297
+ id,
298
+ row
299
+ }),
300
+ fieldConfig.type !== "range" && /* @__PURE__ */ jsx(FilterRowCondition, {
301
+ id,
302
+ row,
303
+ fieldType: fieldConfig.type
304
+ }),
305
+ /* @__PURE__ */ jsx(FilterRowValue, {
306
+ id,
307
+ row,
308
+ fieldConfig
309
+ })
310
+ ]
311
+ }), /* @__PURE__ */ jsx(Button, {
312
+ type: "button",
313
+ variant: "ghost",
314
+ size: "icon-sm",
315
+ onClick: () => dispatch({
316
+ type: "remove-row",
317
+ id
318
+ }),
319
+ children: /* @__PURE__ */ jsx(X, {})
320
+ })]
321
+ });
322
+ }
323
+ function FilterRowField({ id, row }) {
324
+ const { dispatch, fields, state } = useFilterContext();
325
+ const error = state.errors[id]?.field;
326
+ const options = fields.map((config) => ({
327
+ label: config.label,
328
+ value: config.field
329
+ }));
330
+ return /* @__PURE__ */ jsxs(Field, {
331
+ className: "w-full flex-1",
332
+ children: [/* @__PURE__ */ jsxs(Select, {
333
+ value: row.field,
334
+ onValueChange: (nextValue) => {
335
+ const nextField = typeof nextValue === "string" ? nextValue : "";
336
+ const nextConfig = fields.find((config) => config.field === nextField);
337
+ dispatch({
338
+ type: "set-row-field",
339
+ id,
340
+ field: nextField,
341
+ condition: nextConfig?.type === "range" ? RANGE_CONDITION : ""
342
+ });
343
+ },
344
+ items: options,
345
+ children: [/* @__PURE__ */ jsx(SelectTrigger, {
346
+ className: "w-full",
347
+ "aria-invalid": !!error,
348
+ children: /* @__PURE__ */ jsx(SelectValue, { placeholder: "Select field" })
349
+ }), /* @__PURE__ */ jsx(SelectContent, { children: options.map((option) => /* @__PURE__ */ jsx(SelectItem, {
350
+ value: option.value,
351
+ children: option.label
352
+ }, option.value)) })]
353
+ }), error && /* @__PURE__ */ jsx(FieldError, { children: error })]
354
+ });
355
+ }
356
+ function FilterRowCondition({ id, row, fieldType }) {
357
+ const { dispatch, state } = useFilterContext();
358
+ const error = state.errors[id]?.condition;
359
+ const conditions = fieldType === "range" ? [] : conditionsByType[fieldType] ?? [];
360
+ return /* @__PURE__ */ jsxs(Field, {
361
+ className: "w-full flex-1",
362
+ children: [/* @__PURE__ */ jsxs(Select, {
363
+ value: row.condition,
364
+ onValueChange: (nextValue) => dispatch({
365
+ type: "set-row-condition",
366
+ id,
367
+ condition: typeof nextValue === "string" ? nextValue : ""
368
+ }),
369
+ items: conditions.map((condition) => ({
370
+ value: condition.id,
371
+ label: condition.name
372
+ })),
373
+ children: [/* @__PURE__ */ jsx(SelectTrigger, {
374
+ className: "w-full",
375
+ "aria-invalid": !!error,
376
+ children: /* @__PURE__ */ jsx(SelectValue, { placeholder: "Select condition" })
377
+ }), /* @__PURE__ */ jsx(SelectContent, { children: conditions.map((condition) => /* @__PURE__ */ jsx(SelectItem, {
378
+ value: condition.id,
379
+ children: condition.name
380
+ }, condition.id)) })]
381
+ }), error && /* @__PURE__ */ jsx(FieldError, { children: error })]
382
+ });
383
+ }
384
+ function FilterRowValue({ id, row, fieldConfig }) {
385
+ const { dispatch, state } = useFilterContext();
386
+ const error = state.errors[id]?.value;
387
+ const valueProps = {
388
+ field: fieldConfig,
389
+ value: row.value,
390
+ onChange: (value) => dispatch({
391
+ type: "set-row-value",
392
+ id,
393
+ value
394
+ }),
395
+ invalid: !!error,
396
+ error
397
+ };
398
+ return /* @__PURE__ */ jsxs(Field, {
399
+ className: cn("w-full flex-1", { "md:col-span-2": fieldConfig.type === "range" }),
400
+ children: [fieldConfig.renderValue ? fieldConfig.renderValue(valueProps) : /* @__PURE__ */ jsx(FilterBuiltInValue, { ...valueProps }), error && /* @__PURE__ */ jsx(FieldError, { children: error })]
401
+ });
402
+ }
403
+ function FilterBuiltInValue(props) {
404
+ const { field } = props;
405
+ switch (field.type) {
406
+ case "text": return /* @__PURE__ */ jsx(FilterValueText, {
407
+ ...props,
408
+ placeholder: `Enter ${field.label} value`
409
+ });
410
+ case "number": return /* @__PURE__ */ jsx(FilterValueNumber, {
411
+ ...props,
412
+ placeholder: `Enter ${field.label} value`
413
+ });
414
+ case "date": return /* @__PURE__ */ jsx(FilterValueDate, { ...props });
415
+ case "boolean": return /* @__PURE__ */ jsx(FilterValueBoolean, {
416
+ ...props,
417
+ placeholder: `Select ${field.label}`
418
+ });
419
+ case "range": return /* @__PURE__ */ jsx(FilterValueRange, { ...props });
420
+ case "select":
421
+ case "multiSelect": {
422
+ const multiple = field.type === "multiSelect";
423
+ const placeholder = `Select ${field.label}`;
424
+ if (field.loadOptions) return /* @__PURE__ */ jsx(FilterLoadedValueSelect, {
425
+ ...props,
426
+ multiple,
427
+ placeholder
428
+ });
429
+ return /* @__PURE__ */ jsx(FilterValueSelect, {
430
+ ...props,
431
+ multiple,
432
+ options: field.options ?? [],
433
+ placeholder
434
+ });
435
+ }
436
+ }
437
+ }
438
+ function FilterValueText({ value, onChange, invalid, placeholder }) {
439
+ return /* @__PURE__ */ jsx(Input, {
440
+ type: "text",
441
+ placeholder,
442
+ value: typeof value === "string" ? value : "",
443
+ onChange: (event) => onChange(event.target.value),
444
+ "aria-invalid": !!invalid
445
+ });
446
+ }
447
+ function FilterValueNumber({ value, onChange, invalid, placeholder }) {
448
+ return /* @__PURE__ */ jsx(Input, {
449
+ type: "number",
450
+ placeholder,
451
+ value: typeof value === "number" ? String(value) : "",
452
+ onChange: (event) => onChange(event.target.value === "" ? void 0 : Number(event.target.value)),
453
+ "aria-invalid": !!invalid
454
+ });
455
+ }
456
+ function FilterValueDate({ value, onChange, invalid }) {
457
+ return /* @__PURE__ */ jsx(Input, {
458
+ type: "date",
459
+ value: typeof value === "string" ? value : "",
460
+ onChange: (event) => onChange(event.target.value),
461
+ "aria-invalid": !!invalid
462
+ });
463
+ }
464
+ function FilterValueBoolean({ value, onChange, invalid, placeholder, trueLabel = "Yes", falseLabel = "No" }) {
465
+ const items = [{
466
+ label: trueLabel,
467
+ value: "true"
468
+ }, {
469
+ label: falseLabel,
470
+ value: "false"
471
+ }];
472
+ return /* @__PURE__ */ jsxs(Select, {
473
+ value: typeof value === "boolean" ? String(value) : "",
474
+ onValueChange: (nextValue) => onChange(nextValue === "true"),
475
+ items,
476
+ children: [/* @__PURE__ */ jsx(SelectTrigger, {
477
+ className: "w-full",
478
+ "aria-invalid": !!invalid,
479
+ children: /* @__PURE__ */ jsx(SelectValue, { placeholder })
480
+ }), /* @__PURE__ */ jsx(SelectContent, { children: items.map((item) => /* @__PURE__ */ jsx(SelectItem, {
481
+ value: item.value,
482
+ children: item.label
483
+ }, item.value)) })]
484
+ });
485
+ }
486
+ function FilterValueRange({ value, onChange, invalid }) {
487
+ const rangeValue = getRangeValue(value);
488
+ return /* @__PURE__ */ jsxs("div", {
489
+ className: "flex items-center gap-2",
490
+ children: [
491
+ /* @__PURE__ */ jsx(Input, {
492
+ type: "number",
493
+ placeholder: "Min",
494
+ value: typeof rangeValue?.min === "number" ? rangeValue.min : "",
495
+ onChange: (event) => onChange(mergeRangeValue(rangeValue, "min", event.target.value)),
496
+ className: "flex-1",
497
+ "aria-invalid": !!invalid
498
+ }),
499
+ /* @__PURE__ */ jsx("span", {
500
+ className: "text-sm text-fg-secondary",
501
+ children: "to"
502
+ }),
503
+ /* @__PURE__ */ jsx(Input, {
504
+ type: "number",
505
+ placeholder: "Max",
506
+ value: typeof rangeValue?.max === "number" ? rangeValue.max : "",
507
+ onChange: (event) => onChange(mergeRangeValue(rangeValue, "max", event.target.value)),
508
+ className: "flex-1",
509
+ "aria-invalid": !!invalid
510
+ })
511
+ ]
512
+ });
513
+ }
514
+ function FilterValueSelect({ value, onChange, invalid, placeholder, options, multiple = false, loading = false, emptyMessage = "No options available", open, onOpenChange }) {
515
+ const toOptionValue = (itemValue) => {
516
+ return options.find((entry) => String(entry.value) === itemValue)?.value ?? itemValue;
517
+ };
518
+ return /* @__PURE__ */ jsxs(Select, {
519
+ multiple,
520
+ open,
521
+ onOpenChange,
522
+ value: multiple ? Array.isArray(value) ? value.map(String) : [] : typeof value === "string" || typeof value === "number" ? String(value) : "",
523
+ onValueChange: (nextValue) => {
524
+ if (Array.isArray(nextValue)) {
525
+ onChange(nextValue.map(toOptionValue));
526
+ return;
527
+ }
528
+ onChange(typeof nextValue === "string" ? toOptionValue(nextValue) : void 0);
529
+ },
530
+ items: options.map((option) => ({
531
+ label: option.label,
532
+ value: String(option.value)
533
+ })),
534
+ children: [/* @__PURE__ */ jsx(SelectTrigger, {
535
+ className: "w-full",
536
+ "aria-invalid": !!invalid,
537
+ children: /* @__PURE__ */ jsx(SelectValue, { placeholder })
538
+ }), /* @__PURE__ */ jsx(SelectContent, { children: loading ? /* @__PURE__ */ jsx("div", {
539
+ className: "px-3 py-2 text-sm text-fg-secondary",
540
+ children: "Loading..."
541
+ }) : options.length === 0 ? /* @__PURE__ */ jsx("div", {
542
+ className: "px-3 py-2 text-sm text-fg-secondary",
543
+ children: emptyMessage
544
+ }) : options.map((option) => /* @__PURE__ */ jsx(SelectItem, {
545
+ value: String(option.value),
546
+ children: option.label
547
+ }, option.value)) })]
548
+ });
549
+ }
550
+ /**
551
+ * Select whose options come from `field.loadOptions`. Nothing is fetched
552
+ * until the dropdown opens; results are cached per field on the nearest
553
+ * <Filter /> so other rows using the same field reuse them.
554
+ */
555
+ function FilterLoadedValueSelect({ field, multiple, placeholder, ...props }) {
556
+ const { loadedOptionsCache } = useFilterContext();
557
+ const [open, setOpen] = React.useState(false);
558
+ const [loading, setLoading] = React.useState(false);
559
+ const [loadedOptions, setLoadedOptions] = React.useState(null);
560
+ const mountedRef = React.useRef(true);
561
+ const fieldRef = React.useRef(field.field);
562
+ React.useEffect(() => {
563
+ return () => {
564
+ mountedRef.current = false;
565
+ };
566
+ }, []);
567
+ React.useEffect(() => {
568
+ fieldRef.current = field.field;
569
+ setOpen(false);
570
+ setLoading(false);
571
+ setLoadedOptions(null);
572
+ }, [field.field]);
573
+ const handleOpenChange = (nextOpen) => {
574
+ setOpen(nextOpen);
575
+ if (!nextOpen || loadedOptions || !field.loadOptions) return;
576
+ const cache = loadedOptionsCache.current;
577
+ const pending = cache.get(field.field) ?? field.loadOptions();
578
+ cache.set(field.field, pending);
579
+ setLoading(true);
580
+ pending.then((options) => {
581
+ if (mountedRef.current && fieldRef.current === field.field) setLoadedOptions(options);
582
+ }).catch(() => {
583
+ if (cache.get(field.field) === pending) cache.delete(field.field);
584
+ }).finally(() => {
585
+ if (mountedRef.current && fieldRef.current === field.field) setLoading(false);
586
+ });
587
+ };
588
+ return /* @__PURE__ */ jsx(FilterValueSelect, {
589
+ ...props,
590
+ multiple,
591
+ placeholder,
592
+ options: loadedOptions ?? field.options ?? [],
593
+ loading: loading && !loadedOptions,
594
+ open,
595
+ onOpenChange: handleOpenChange
596
+ });
597
+ }
598
+ function FilterApplyButton({ children = "Apply Filter", className, onApplySuccess }) {
599
+ const { contentRef, defaultJoin, dispatch, fields, onApply, state } = useFilterContext();
600
+ return /* @__PURE__ */ jsx(Button, {
601
+ className,
602
+ onClick: () => {
603
+ const errors = {};
604
+ for (const id of state.ids) {
605
+ const row = state.rows[id];
606
+ if (!row) continue;
607
+ const rowErrors = getRowErrors(row);
608
+ if (Object.keys(rowErrors).length) errors[id] = rowErrors;
609
+ }
610
+ dispatch({
611
+ type: "apply",
612
+ errors
613
+ });
614
+ if (Object.keys(errors).length) {
615
+ focusFirstInvalidFilterItem(contentRef.current);
616
+ return;
617
+ }
618
+ const filters = serializeFilters({
619
+ defaultJoin,
620
+ fields,
621
+ ids: state.ids,
622
+ rows: state.rows
623
+ });
624
+ onApply(filters.length ? JSON.stringify(filters) : "", filters);
625
+ onApplySuccess?.();
626
+ },
627
+ children
628
+ });
629
+ }
630
+ function FilterResetButton({ children = "Reset Filter", className, onReset }) {
631
+ const { dispatch, onApply } = useFilterContext();
632
+ return /* @__PURE__ */ jsx(Button, {
633
+ variant: "tertiary-outline",
634
+ className,
635
+ onClick: () => {
636
+ dispatch({ type: "reset" });
637
+ onApply("", []);
638
+ onReset?.();
639
+ },
640
+ children
641
+ });
642
+ }
643
+ function focusFirstInvalidFilterItem(root) {
644
+ setTimeout(() => {
645
+ const invalidItem = (root ?? document).querySelector("[aria-invalid=true]");
646
+ if (invalidItem instanceof HTMLButtonElement) {
647
+ invalidItem.click();
648
+ return;
649
+ }
650
+ if (invalidItem instanceof HTMLInputElement) invalidItem.focus();
651
+ }, 0);
652
+ }
653
+ function serializeFilters({ defaultJoin, fields, ids, rows }) {
654
+ return ids.flatMap((id) => {
655
+ const row = rows[id];
656
+ if (!row) return [];
657
+ const fieldConfig = fields.find((config) => config.field === row.field);
658
+ if (!fieldConfig) return [];
659
+ return serializeRow(defaultJoin, fieldConfig, row);
660
+ });
661
+ }
662
+ function serializeRow(defaultJoin, fieldConfig, row) {
663
+ if (fieldConfig.type === "range") {
664
+ const rangeValue = getRangeValue(row.value);
665
+ if (!rangeValue) return [];
666
+ return [...typeof rangeValue.min === "number" ? [{
667
+ connector: defaultJoin,
668
+ field: row.field,
669
+ action: "greaterThan",
670
+ value: rangeValue.min
671
+ }] : [], ...typeof rangeValue.max === "number" ? [{
672
+ connector: defaultJoin,
673
+ field: row.field,
674
+ action: "lessThan",
675
+ value: rangeValue.max
676
+ }] : []];
677
+ }
678
+ if (!isFilterCondition(row.condition) || typeof row.value === "undefined") return [];
679
+ return [{
680
+ connector: defaultJoin,
681
+ field: row.field,
682
+ action: row.condition,
683
+ value: row.value
684
+ }];
685
+ }
686
+ /**
687
+ * Parse a serialized filter string (as produced by `onApply`) back into
688
+ * structured filters. Invalid or malformed entries are dropped.
689
+ */
690
+ function parseSerializedFilters(value) {
691
+ if (!value.trim()) return [];
692
+ try {
693
+ const parsed = JSON.parse(value);
694
+ if (!Array.isArray(parsed)) return [];
695
+ return parsed.filter(isSerializedFilter);
696
+ } catch {
697
+ return [];
698
+ }
699
+ }
700
+ function buildStateFromSerializedFilters(value, fields) {
701
+ const parsedFilters = parseSerializedFilters(value);
702
+ if (!parsedFilters.length) return emptyFilterState;
703
+ const ids = [];
704
+ const rows = {};
705
+ for (let index = 0; index < parsedFilters.length; index += 1) {
706
+ const currentFilter = parsedFilters[index];
707
+ const fieldConfig = fields.find((config) => config.field === currentFilter.field);
708
+ if (!fieldConfig) continue;
709
+ const rowId = `${currentFilter.field}-${index}`;
710
+ if (fieldConfig.type === "range") {
711
+ const rangeValue = {};
712
+ if (currentFilter.action === "greaterThan" && typeof currentFilter.value === "number") rangeValue.min = currentFilter.value;
713
+ if (currentFilter.action === "lessThan" && typeof currentFilter.value === "number") rangeValue.max = currentFilter.value;
714
+ const nextFilter = parsedFilters[index + 1];
715
+ if (nextFilter && nextFilter.field === currentFilter.field && nextFilter.connector === currentFilter.connector) {
716
+ if (nextFilter.action === "greaterThan" && typeof nextFilter.value === "number") {
717
+ rangeValue.min = nextFilter.value;
718
+ index += 1;
719
+ } else if (nextFilter.action === "lessThan" && typeof nextFilter.value === "number") {
720
+ rangeValue.max = nextFilter.value;
721
+ index += 1;
722
+ }
723
+ }
724
+ ids.push(rowId);
725
+ rows[rowId] = {
726
+ field: currentFilter.field,
727
+ condition: RANGE_CONDITION,
728
+ value: rangeValue
729
+ };
730
+ continue;
731
+ }
732
+ ids.push(rowId);
733
+ rows[rowId] = {
734
+ field: currentFilter.field,
735
+ condition: currentFilter.action,
736
+ value: currentFilter.value
737
+ };
738
+ }
739
+ return {
740
+ appliedCount: ids.length,
741
+ errors: {},
742
+ ids,
743
+ rows
744
+ };
745
+ }
746
+ function isSerializedFilter(value) {
747
+ if (typeof value !== "object" || value === null) return false;
748
+ const filter = value;
749
+ return (filter.connector === "AND" || filter.connector === "OR") && typeof filter.field === "string" && isFilterCondition(filter.action) && isSerializedFilterValue(filter.value);
750
+ }
751
+ function isFilterCondition(action) {
752
+ return action === "equals" || action === "greaterThan" || action === "lessThan" || action === "contains";
753
+ }
754
+ function isSerializedFilterValue(value) {
755
+ return typeof value === "string" || typeof value === "number" || typeof value === "boolean" || Array.isArray(value) && value.every((item) => typeof item === "string" || typeof item === "number");
756
+ }
757
+ function getRangeValue(value) {
758
+ if (typeof value !== "object" || value === null || Array.isArray(value)) return;
759
+ const rangeValue = value;
760
+ const min = typeof rangeValue.min === "number" && Number.isFinite(rangeValue.min) ? rangeValue.min : void 0;
761
+ const max = typeof rangeValue.max === "number" && Number.isFinite(rangeValue.max) ? rangeValue.max : void 0;
762
+ if (typeof min === "undefined" && typeof max === "undefined") return;
763
+ return {
764
+ min,
765
+ max
766
+ };
767
+ }
768
+ function mergeRangeValue(currentValue, boundary, rawValue) {
769
+ return getRangeValue({
770
+ ...currentValue,
771
+ [boundary]: rawValue === "" ? void 0 : Number(rawValue)
772
+ });
773
+ }
774
+ //#endregion
775
+ export { Filter, FilterApplyButton, FilterContent, FilterResetButton, FilterTrigger, FilterValueBoolean, FilterValueDate, FilterValueNumber, FilterValueRange, FilterValueSelect, FilterValueText, parseSerializedFilters };