@pibit.ai/cure-design-system 0.6.36 → 0.6.38

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 (37) hide show
  1. package/dist/index.d.ts +1 -0
  2. package/dist/index.d.ts.map +1 -1
  3. package/dist/index.js +311 -288
  4. package/dist/patterns/condition-builder/condition-builder.d.ts.map +1 -1
  5. package/dist/patterns/condition-builder/condition-builder.js +47 -47
  6. package/dist/patterns/condition-builder/utils.d.ts.map +1 -1
  7. package/dist/patterns/filter-group/date-adapter.d.ts +20 -0
  8. package/dist/patterns/filter-group/date-adapter.d.ts.map +1 -0
  9. package/dist/patterns/filter-group/date-adapter.js +38 -0
  10. package/dist/patterns/filter-group/document-fields-to-tree.d.ts +33 -0
  11. package/dist/patterns/filter-group/document-fields-to-tree.d.ts.map +1 -0
  12. package/dist/patterns/filter-group/document-fields-to-tree.js +53 -0
  13. package/dist/patterns/filter-group/filter-condition-row.d.ts +47 -0
  14. package/dist/patterns/filter-group/filter-condition-row.d.ts.map +1 -0
  15. package/dist/patterns/filter-group/filter-condition-row.js +642 -0
  16. package/dist/patterns/filter-group/filter-group-builder.d.ts +42 -0
  17. package/dist/patterns/filter-group/filter-group-builder.d.ts.map +1 -0
  18. package/dist/patterns/filter-group/filter-group-builder.js +92 -0
  19. package/dist/patterns/filter-group/filter-group-card.d.ts +25 -0
  20. package/dist/patterns/filter-group/filter-group-card.d.ts.map +1 -0
  21. package/dist/patterns/filter-group/filter-group-card.js +266 -0
  22. package/dist/patterns/filter-group/index.d.ts +11 -0
  23. package/dist/patterns/filter-group/index.d.ts.map +1 -0
  24. package/dist/patterns/filter-group/nested-field-select.d.ts +68 -0
  25. package/dist/patterns/filter-group/nested-field-select.d.ts.map +1 -0
  26. package/dist/patterns/filter-group/nested-field-select.js +431 -0
  27. package/dist/patterns/filter-group/types.d.ts +105 -0
  28. package/dist/patterns/filter-group/types.d.ts.map +1 -0
  29. package/dist/patterns/filter-group/types.js +222 -0
  30. package/dist/patterns/filter-group/use-filter-group.d.ts +38 -0
  31. package/dist/patterns/filter-group/use-filter-group.d.ts.map +1 -0
  32. package/dist/patterns/filter-group/use-filter-group.js +81 -0
  33. package/dist/patterns/filter-group/validation.d.ts +13 -0
  34. package/dist/patterns/filter-group/validation.d.ts.map +1 -0
  35. package/dist/patterns/filter-group/validation.js +19 -0
  36. package/dist/styles/components.css +1 -1
  37. package/package.json +2 -1
@@ -0,0 +1,642 @@
1
+ import { jsxs as M, jsx as l } from "react/jsx-runtime";
2
+ import { useState as ie, useMemo as g, useCallback as G, useEffect as oe, useRef as $e } from "react";
3
+ import { Trash02 as me } from "@untitledui/icons";
4
+ import { DatePicker as H } from "../../applications/date-picker/date-picker.js";
5
+ import { useListData as Me } from "../../node_modules/react-stately/dist/private/data/useListData.js";
6
+ import { defaultFilterDateAdapter as Ie } from "./date-adapter.js";
7
+ import { DEFAULT_OPERATORS as _e } from "./types.js";
8
+ import { cx as m } from "../../utils/cn.js";
9
+ import { NestedFieldSelect as J } from "./nested-field-select.js";
10
+ import { ReorderDots8x14 as ce } from "../../primitives/custom-icon/icons/reorder-dots-8x14.js";
11
+ import { useDragControls as Ke } from "../../node_modules/framer-motion/dist/es/gestures/drag/use-drag-controls.js";
12
+ import { Select as C } from "../../primitives/select/select.js";
13
+ import { ButtonUtility as fe } from "../../primitives/button/button-utility.js";
14
+ import { EllipsisContentWithTooltip as he } from "../../primitives/tooltip/ellipsis-content.js";
15
+ import { motion as ke } from "../../node_modules/framer-motion/dist/es/render/components/motion/proxy.js";
16
+ import { Input as j } from "../../primitives/input/input.js";
17
+ import { MultiSelect as pe } from "../../primitives/select/multi-select.js";
18
+ import { SearchableSelect as qe } from "../../primitives/select/searchable-select.js";
19
+ import { SelectItem as Re } from "../../primitives/select/select-item.js";
20
+ import { ReorderItem as je } from "../../node_modules/framer-motion/dist/es/components/Reorder/Item.js";
21
+ const Ae = ({
22
+ searchable: r = !1,
23
+ size: x = "sm",
24
+ className: S,
25
+ placeholder: _,
26
+ selectedKey: A,
27
+ onSelectionChange: E,
28
+ items: n,
29
+ isInvalid: K,
30
+ isDisabled: T,
31
+ isLoading: k,
32
+ selectedDisplayValue: d,
33
+ searchPlaceholder: L = "Search..."
34
+ }) => {
35
+ const y = (s) => /* @__PURE__ */ l(Re, { id: s.id, label: s.label, children: s.label }, s.id);
36
+ return r ? /* @__PURE__ */ l(
37
+ qe,
38
+ {
39
+ size: x,
40
+ className: S,
41
+ placeholder: _,
42
+ selectedKey: A || null,
43
+ onSelectionChange: (s) => E(s ?? ""),
44
+ items: n,
45
+ isInvalid: K,
46
+ isDisabled: T,
47
+ isLoading: k,
48
+ selectedDisplayValue: d,
49
+ searchPlaceholder: L,
50
+ renderItem: y
51
+ }
52
+ ) : /* @__PURE__ */ l(
53
+ C,
54
+ {
55
+ size: x,
56
+ className: S,
57
+ placeholder: _,
58
+ selectedKey: A,
59
+ onSelectionChange: (s) => E(s),
60
+ items: n,
61
+ isInvalid: K,
62
+ isDisabled: T,
63
+ children: (s) => /* @__PURE__ */ l(C.Item, { id: s.id, children: s.label })
64
+ }
65
+ );
66
+ }, Ee = [
67
+ { id: "and", label: "And" },
68
+ { id: "or", label: "Or" }
69
+ ], b = "flex-1 w-[154px] h-8 [&>button]:h-8 [&>div]:h-full", sr = ({
70
+ condition: r,
71
+ fields: x,
72
+ operators: S = _e,
73
+ logicalOperator: _,
74
+ isFirst: A,
75
+ showLogicalOperator: E,
76
+ onUpdate: n,
77
+ onDelete: K,
78
+ useFixedPositioning: T = !1,
79
+ onLogicalOperatorChange: k,
80
+ size: d = "sm",
81
+ dragEnabled: L = !0,
82
+ documentFields: y,
83
+ isInvalid: s = !1,
84
+ allowFlexCol: p = !1,
85
+ forceTextInput: B = !1,
86
+ hideLabels: ve = !1,
87
+ multiselectOptions: z,
88
+ searchable: U = !1,
89
+ testIdPrefix: P,
90
+ rowIndex: de,
91
+ dateAdapter: W = Ie
92
+ }) => {
93
+ const Q = Ke(), V = (e) => P ? `${P}-${e}` : void 0, [F, I] = ie(null), [ee, X] = ie(null), re = g(() => F ?? (r.value && typeof r.value == "string" && r.value.trim() ? W.parseDate(r.value) : null), [F, r.value]), ge = g(() => ee ?? (r.value2 && typeof r.value2 == "string" && r.value2.trim() ? W.parseDate(r.value2) : null), [ee, r.value2]), Y = G(
94
+ (e, a, i = []) => {
95
+ if (a.length === 0) return null;
96
+ const [o, ...f] = a, v = e.find((N) => N.key === o);
97
+ if (!v) return null;
98
+ if (f.length === 0)
99
+ return { field: v, ancestorLabels: i };
100
+ if (v.children) {
101
+ const N = Y(v.children, f, [...i, v.label]);
102
+ if (N) return N;
103
+ }
104
+ return null;
105
+ },
106
+ []
107
+ ), t = g(() => {
108
+ const e = x.find((a) => a.id === r.fieldId);
109
+ if (e) return e;
110
+ if (y && r.fieldId) {
111
+ const a = r.fieldId.split("."), i = a[0], o = y[i];
112
+ if (o) {
113
+ const f = a.slice(1), v = Y(o.fields, f);
114
+ if (v && v.field.type) {
115
+ const $ = [o.label, ...v.ancestorLabels, v.field.label].join(" > ");
116
+ return {
117
+ id: r.fieldId,
118
+ label: $,
119
+ type: v.field.type,
120
+ options: v.field.options
121
+ };
122
+ }
123
+ }
124
+ }
125
+ }, [x, r.fieldId, y]), te = g(() => t ? S.filter((e) => e.applicableTo.includes(t.type)) : S, [S, t]), c = g(
126
+ () => S.find((e) => e.id === r.operatorId),
127
+ [S, r.operatorId]
128
+ ), ye = g(() => x.map((e) => ({ id: e.id, label: e.label })), [x]), be = g(() => te.map((e) => ({ id: e.id, label: e.label })), [te]), q = g(() => (t == null ? void 0 : t.type) === "select" && t.options ? t.options.map((e) => ({
129
+ id: e.id,
130
+ label: e.label
131
+ })) : [], [t]), Se = g(() => {
132
+ var e;
133
+ if (r.value)
134
+ return (e = q.find((a) => a.id === r.value)) == null ? void 0 : e.label;
135
+ }, [r.value, q]), R = g(() => !r.value || typeof r.value != "string" ? [] : r.value.split(",").map((e) => e.trim()).filter(Boolean), [r.value]), le = g(
136
+ () => z ?? q,
137
+ [z, q]
138
+ ), w = g(() => le.map((e) => ({ id: e.id, label: e.label })), [le]), Ne = g(
139
+ () => `ms-${r.fieldId}-${r.operatorId}-${w.length}-${r.value}`,
140
+ [r.fieldId, r.operatorId, w.length, r.value]
141
+ ), D = Me({
142
+ initialItems: R.map((e) => w.find((a) => a.id === e)).filter((e) => e !== void 0),
143
+ getKey: (e) => e.id
144
+ });
145
+ oe(() => {
146
+ if (w.length === 0) return;
147
+ const e = new Set(D.items.map((a) => a.id));
148
+ for (const a of R)
149
+ if (!e.has(a)) {
150
+ const i = w.find((o) => o.id === a);
151
+ i && D.append(i);
152
+ }
153
+ }, [w]);
154
+ const ae = $e(r.value);
155
+ oe(() => {
156
+ if (ae.current === r.value) return;
157
+ ae.current = r.value;
158
+ const e = new Set(D.items.map((i) => i.id)), a = new Set(R);
159
+ for (const i of D.items)
160
+ a.has(i.id) || D.remove(i.id);
161
+ for (const i of R)
162
+ if (!e.has(i)) {
163
+ const o = w.find((f) => f.id === i);
164
+ o && D.append(o);
165
+ }
166
+ }, [r.value, R, w, D]);
167
+ const we = G(
168
+ (e) => {
169
+ const a = String(e), i = r.value ? r.value.split(",").map((o) => o.trim()).filter(Boolean) : [];
170
+ if (!i.includes(a)) {
171
+ const o = [...i, a].join(", ");
172
+ n({ value: o });
173
+ }
174
+ },
175
+ [r.value, n]
176
+ ), xe = G(
177
+ (e) => {
178
+ const a = String(e), o = (r.value ? r.value.split(",").map((f) => f.trim()).filter(Boolean) : []).filter((f) => f !== a).join(", ");
179
+ n({ value: o });
180
+ },
181
+ [r.value, n]
182
+ ), Ve = (e) => {
183
+ var o;
184
+ const a = x.find((f) => f.id === e), i = S.filter((f) => f.applicableTo.includes((a == null ? void 0 : a.type) || "string"));
185
+ n({
186
+ fieldId: e,
187
+ operatorId: ((o = i[0]) == null ? void 0 : o.id) || "",
188
+ value: "",
189
+ value2: void 0
190
+ });
191
+ }, De = (e, a, i) => {
192
+ var N;
193
+ const o = y == null ? void 0 : y[a];
194
+ let f = "string";
195
+ if (o) {
196
+ const u = e.split(".").slice(1), h = Y(o.fields, u);
197
+ h && h.field.type && (f = h.field.type);
198
+ }
199
+ const v = S.filter(($) => $.applicableTo.includes(f));
200
+ n({
201
+ fieldId: e,
202
+ operatorId: ((N = v[0]) == null ? void 0 : N.id) || "",
203
+ value: "",
204
+ value2: void 0
205
+ });
206
+ }, se = (e, a, i) => {
207
+ n({ value: e });
208
+ }, Ce = G(
209
+ (e) => {
210
+ const a = S.find((f) => f.id === e), i = c == null ? void 0 : c.requiresMultipleValues, o = a == null ? void 0 : a.requiresMultipleValues;
211
+ n(i !== o ? { operatorId: e, value: "", value2: void 0 } : { operatorId: e });
212
+ },
213
+ [S, c, n]
214
+ ), Z = g(() => (t == null ? void 0 : t.dataType) === "TIMESTAMP", [t]), Te = g(
215
+ () => Z ? W.parseTimestamp(r.value) : null,
216
+ [Z, r.value]
217
+ ), ue = () => {
218
+ var i, o, f, v, N, $;
219
+ if (!(c != null && c.requiresValue))
220
+ return /* @__PURE__ */ l(
221
+ j,
222
+ {
223
+ size: d,
224
+ wrapperClassName: m(p && "w-full"),
225
+ className: b,
226
+ placeholder: "No value needed",
227
+ value: "",
228
+ onChange: () => {
229
+ },
230
+ isDisabled: !0
231
+ }
232
+ );
233
+ if (c != null && c.requiresMultipleValues) {
234
+ if ((t == null ? void 0 : t.type) === "select") {
235
+ const u = !!t.isLoading;
236
+ return /* @__PURE__ */ l(
237
+ "div",
238
+ {
239
+ className: m(
240
+ b,
241
+ // Prevent tags from wrapping to new lines - keep single row with horizontal scroll
242
+ "h-full [&_[role='group']>div]:flex-nowrap [&_[role='group']>div]:overflow-x-auto [&_[role='group']>div]:scrollbar-hide",
243
+ s && "[&>div]:ring-1 [&>div]:ring-error",
244
+ p && "w-full"
245
+ ),
246
+ children: /* @__PURE__ */ l(
247
+ pe,
248
+ {
249
+ placeholder: u ? "Loading options..." : "Select values",
250
+ size: d,
251
+ selectedItems: D,
252
+ items: u ? [] : w,
253
+ onItemInserted: we,
254
+ onItemCleared: xe,
255
+ showAvatar: !1,
256
+ isDisabled: u,
257
+ searchable: U,
258
+ searchPlaceholder: "Search values...",
259
+ children: (h) => /* @__PURE__ */ l(pe.Item, { id: h.id, children: h.label })
260
+ },
261
+ Ne
262
+ )
263
+ }
264
+ );
265
+ }
266
+ return /* @__PURE__ */ l(
267
+ j,
268
+ {
269
+ mode: "tag",
270
+ size: d,
271
+ wrapperClassName: m(
272
+ s && "!ring-error_subtle !ring-2 !ring-error",
273
+ p && "w-full"
274
+ ),
275
+ className: b,
276
+ placeholder: "Type and press Enter",
277
+ value: r.value,
278
+ onChange: (u) => n({ value: u }),
279
+ isInvalid: s
280
+ }
281
+ );
282
+ }
283
+ if (Z && !B)
284
+ return /* @__PURE__ */ l(
285
+ H,
286
+ {
287
+ granularity: "minute",
288
+ value: Te,
289
+ onChange: (u) => n({ value: W.formatTimestamp(u) }),
290
+ showFooter: !1,
291
+ className: m("w-auto", p && "w-full"),
292
+ "aria-label": (t == null ? void 0 : t.label) || "Date and time"
293
+ }
294
+ );
295
+ if (y)
296
+ return c != null && c.requiresTwoValues ? /* @__PURE__ */ M("div", { className: m("flex items-center gap-2 flex-1 min-w-[200px]", p && "w-full"), children: [
297
+ /* @__PURE__ */ l(
298
+ J,
299
+ {
300
+ documentFields: y,
301
+ selectedFieldId: (i = r.value) != null && i.includes(".") ? r.value : "",
302
+ onFieldSelect: se,
303
+ size: d,
304
+ placeholder: "Min",
305
+ className: m(
306
+ b,
307
+ s && "[&>div]:ring-2 [&>div]:ring-error [&>button]:ring-2 [&>button]:ring-error"
308
+ ),
309
+ allowCustomValue: !0,
310
+ customValue: (o = r.value) != null && o.includes(".") ? "" : r.value,
311
+ onCustomValueChange: (u) => n({ value: u }),
312
+ useFixedPositioning: T
313
+ }
314
+ ),
315
+ /* @__PURE__ */ l("span", { className: "text-sm text-tertiary", children: "and" }),
316
+ /* @__PURE__ */ l(
317
+ J,
318
+ {
319
+ documentFields: y,
320
+ selectedFieldId: (f = r.value2) != null && f.includes(".") ? r.value2 : "",
321
+ onFieldSelect: (u) => n({ value2: u }),
322
+ size: d,
323
+ placeholder: "Max",
324
+ className: m(
325
+ b,
326
+ s && "[&>div]:ring-2 [&>div]:ring-error [&>button]:ring-2 [&>button]:ring-error"
327
+ ),
328
+ allowCustomValue: !0,
329
+ customValue: (v = r.value2) != null && v.includes(".") ? "" : r.value2 || "",
330
+ onCustomValueChange: (u) => n({ value2: u }),
331
+ useFixedPositioning: T
332
+ }
333
+ )
334
+ ] }) : /* @__PURE__ */ l(
335
+ J,
336
+ {
337
+ documentFields: y,
338
+ selectedFieldId: (N = r.value) != null && N.includes(".") ? r.value : "",
339
+ onFieldSelect: se,
340
+ size: d,
341
+ placeholder: "Enter value",
342
+ className: m(
343
+ b,
344
+ s && "[&>div]:ring-2 [&>div]:ring-error [&>button]:ring-2 [&>button]:ring-error",
345
+ p && "w-full"
346
+ ),
347
+ allowCustomValue: !0,
348
+ customValue: ($ = r.value) != null && $.includes(".") ? "" : r.value,
349
+ onCustomValueChange: (u) => n({ value: u }),
350
+ useFixedPositioning: T
351
+ }
352
+ );
353
+ if ((t == null ? void 0 : t.type) === "select") {
354
+ const u = !!t.isLoading;
355
+ return /* @__PURE__ */ l(
356
+ Ae,
357
+ {
358
+ searchable: U,
359
+ size: d,
360
+ className: m(
361
+ b,
362
+ s && "[&>button]:ring-2 [&>button]:ring-error",
363
+ p && "w-full"
364
+ ),
365
+ placeholder: u ? "Loading options..." : "Select",
366
+ selectedKey: r.value,
367
+ onSelectionChange: (h) => n({ value: h }),
368
+ items: u ? [] : q,
369
+ isInvalid: s,
370
+ isDisabled: u,
371
+ isLoading: u,
372
+ selectedDisplayValue: Se,
373
+ searchPlaceholder: "Search values..."
374
+ }
375
+ );
376
+ }
377
+ if (c != null && c.requiresTwoValues) {
378
+ if ((t == null ? void 0 : t.type) === "date")
379
+ return /* @__PURE__ */ M("div", { className: m("flex items-center gap-2 flex-1 min-w-[200px] ", p && "w-full"), children: [
380
+ /* @__PURE__ */ l("div", { className: m("flex-1", s && "ring-2 ring-error rounded-lg"), children: /* @__PURE__ */ l(
381
+ H,
382
+ {
383
+ value: re,
384
+ onChange: I,
385
+ onApply: (h) => {
386
+ n(h ? {
387
+ value: `${h.month}/${h.day}/${h.year}`
388
+ } : { value: "" }), I(null);
389
+ },
390
+ onCancel: () => {
391
+ I(null);
392
+ },
393
+ showFooter: !0,
394
+ className: "w-full"
395
+ }
396
+ ) }),
397
+ /* @__PURE__ */ l("span", { className: "text-sm text-tertiary", children: "and" }),
398
+ /* @__PURE__ */ l("div", { className: m("flex-1", s && "ring-2 ring-error rounded-lg"), children: /* @__PURE__ */ l(
399
+ H,
400
+ {
401
+ value: ge,
402
+ onChange: X,
403
+ onApply: (h) => {
404
+ n(h ? {
405
+ value2: `${h.month}/${h.day}/${h.year}`
406
+ } : { value2: "" }), X(null);
407
+ },
408
+ onCancel: () => {
409
+ X(null);
410
+ },
411
+ showFooter: !0,
412
+ className: "w-full"
413
+ }
414
+ ) })
415
+ ] });
416
+ const u = () => (t == null ? void 0 : t.type) === "number" ? "number" : (t == null ? void 0 : t.type) === "date" && B ? "date" : "text";
417
+ return /* @__PURE__ */ M("div", { className: "flex items-center gap-2 flex-1 min-w-[200px]", children: [
418
+ /* @__PURE__ */ l(
419
+ j,
420
+ {
421
+ size: d,
422
+ wrapperClassName: m(s && "!ring-error_subtle !ring-2 !ring-error"),
423
+ className: b,
424
+ placeholder: "Min",
425
+ inputType: u(),
426
+ value: r.value,
427
+ onChange: (h) => n({ value: h }),
428
+ isInvalid: s
429
+ }
430
+ ),
431
+ /* @__PURE__ */ l("span", { className: "text-sm text-tertiary", children: "and" }),
432
+ /* @__PURE__ */ l(
433
+ j,
434
+ {
435
+ size: d,
436
+ wrapperClassName: m(s && "!ring-error_subtle !ring-2 !ring-error"),
437
+ className: b,
438
+ placeholder: "Max",
439
+ inputType: u(),
440
+ value: r.value2 || "",
441
+ onChange: (h) => n({ value2: h }),
442
+ isInvalid: s
443
+ }
444
+ )
445
+ ] });
446
+ }
447
+ if ((t == null ? void 0 : t.type) === "date" && !B)
448
+ return /* @__PURE__ */ l(
449
+ "div",
450
+ {
451
+ className: m(
452
+ "min-w-[140px] flex-1",
453
+ s && "ring-2 ring-error rounded-lg",
454
+ p && "w-full"
455
+ ),
456
+ children: /* @__PURE__ */ l(
457
+ H,
458
+ {
459
+ value: re,
460
+ onChange: I,
461
+ onApply: (u) => {
462
+ n(u ? {
463
+ value: `${u.month}/${u.day}/${u.year}`
464
+ } : { value: "" }), I(null);
465
+ },
466
+ onCancel: () => {
467
+ I(null);
468
+ },
469
+ showFooter: !0,
470
+ className: "w-full"
471
+ }
472
+ )
473
+ }
474
+ );
475
+ const a = () => (t == null ? void 0 : t.type) === "number" ? "number" : (t == null ? void 0 : t.type) === "date" && B ? "date" : "text";
476
+ return /* @__PURE__ */ l(
477
+ j,
478
+ {
479
+ size: d,
480
+ wrapperClassName: m(s && "!ring-error_subtle !ring-2 !ring-error", p && "w-full"),
481
+ className: b,
482
+ placeholder: (t == null ? void 0 : t.type) === "date" ? "Select date" : "Enter value",
483
+ inputType: a(),
484
+ value: r.value,
485
+ onChange: (u) => n({ value: u }),
486
+ isInvalid: s
487
+ }
488
+ );
489
+ }, O = !!(c != null && c.requiresMultipleValues), ne = (e) => P ? /* @__PURE__ */ l("div", { className: "contents", "data-testid": V("value-input"), children: e }) : e;
490
+ return /* @__PURE__ */ M(
491
+ je,
492
+ {
493
+ value: r,
494
+ id: r.id,
495
+ "data-testid": V("row"),
496
+ "data-row-index": P ? de : void 0,
497
+ dragListener: !1,
498
+ dragControls: Q,
499
+ layout: O ? "position" : !0,
500
+ transition: {
501
+ layout: { type: "tween", duration: 0.01, ease: "easeInOut" }
502
+ },
503
+ className: m(
504
+ "flex items-center gap-2 py-2 group select-none",
505
+ p && "flex-col items-start",
506
+ O && "items-start"
507
+ ),
508
+ initial: !1,
509
+ animate: !1,
510
+ style: { position: "relative" },
511
+ children: [
512
+ !ve && /* @__PURE__ */ M("div", { className: m("w-[72px] shrink-0", p && "w-full flex justify-between items-center"), children: [
513
+ A ? /* @__PURE__ */ l("span", { className: "text-sm font-medium text-secondary pl-1", children: "Where" }) : E ? /* @__PURE__ */ l(
514
+ C,
515
+ {
516
+ size: d,
517
+ className: m("h-8 w-full [&>button]:h-8 [&>div]:h-full", p && "w-auto"),
518
+ popoverClassName: "w-auto min-w-max",
519
+ selectedKey: _,
520
+ onSelectionChange: (e) => k == null ? void 0 : k(e),
521
+ items: Ee,
522
+ children: (e) => /* @__PURE__ */ l(C.Item, { id: e.id, children: e.label })
523
+ }
524
+ ) : /* @__PURE__ */ l("span", { className: "text-sm font-medium text-secondary pl-3", children: _ === "or" ? "Or" : "And" }),
525
+ p && /* @__PURE__ */ l(
526
+ fe,
527
+ {
528
+ color: "tertiary",
529
+ size: "xs",
530
+ icon: /* @__PURE__ */ l(me, { size: 18 }),
531
+ "aria-label": "Remove condition",
532
+ onClick: K,
533
+ "data-testid": V("remove-button"),
534
+ className: "text-quaternary hover:bg-secondary_hover hover:text-secondary"
535
+ }
536
+ )
537
+ ] }),
538
+ /* @__PURE__ */ M("div", { className: m("flex relative", p ? "w-full" : "shrink-0"), children: [
539
+ y ? /* @__PURE__ */ l(
540
+ J,
541
+ {
542
+ documentFields: y,
543
+ selectedFieldId: r.fieldId,
544
+ onFieldSelect: De,
545
+ size: d,
546
+ placeholder: "Select field",
547
+ className: m(
548
+ b,
549
+ s && "[&>button]:ring-2 [&>button]:ring-error",
550
+ p && "w-full max-w-none!"
551
+ ),
552
+ useFixedPositioning: T
553
+ }
554
+ ) : /* @__PURE__ */ l(
555
+ C,
556
+ {
557
+ "data-testid": V("field-select"),
558
+ size: d,
559
+ className: m(
560
+ b,
561
+ s && "[&>button]:ring-2 [&>button]:ring-error",
562
+ p && "w-full flex-1 max-w-none!"
563
+ ),
564
+ placeholder: "Select field",
565
+ selectedKey: r.fieldId,
566
+ onSelectionChange: (e) => Ve(e),
567
+ items: ye,
568
+ isInvalid: s,
569
+ children: (e) => /* @__PURE__ */ l(C.Item, { id: e.id, children: /* @__PURE__ */ l(
570
+ he,
571
+ {
572
+ content: e.label ?? String(e.id),
573
+ className: "pointer-events-auto",
574
+ tooltipClassName: "z-[100001]"
575
+ }
576
+ ) })
577
+ }
578
+ ),
579
+ L && p && /* @__PURE__ */ l(
580
+ "div",
581
+ {
582
+ className: "flex opacity-0 group-hover:opacity-100 hover:visible absolute right-[-23px] bottom-1 items-center justify-center cursor-grab active:cursor-grabbing p-1.5 rounded-md transition-colors text-quaternary hover:text-secondary touch-none",
583
+ onPointerDown: (e) => Q.start(e),
584
+ "aria-label": "Drag to reorder",
585
+ "data-testid": V("drag-handle"),
586
+ children: /* @__PURE__ */ l(ce, { color: "currentColor", size: 18 })
587
+ }
588
+ )
589
+ ] }),
590
+ /* @__PURE__ */ l(
591
+ C,
592
+ {
593
+ "data-testid": V("operator-select"),
594
+ size: d,
595
+ className: m(
596
+ b,
597
+ s && "[&>button]:ring-2 [&>button]:ring-error",
598
+ p && "w-full",
599
+ !(c != null && c.requiresValue) && "flex-1"
600
+ ),
601
+ placeholder: "Select operator",
602
+ selectedKey: r.operatorId,
603
+ onSelectionChange: (e) => Ce(e),
604
+ items: be,
605
+ isInvalid: s,
606
+ children: (e) => /* @__PURE__ */ l(C.Item, { id: e.id, children: /* @__PURE__ */ l(he, { content: e.label ?? String(e.id) }) })
607
+ },
608
+ `operator-${r.fieldId}-${t == null ? void 0 : t.type}`
609
+ ),
610
+ O ? /* @__PURE__ */ l(ke.div, { layoutRoot: !0, className: m("min-w-0 flex-1", p && "w-full"), children: ne(ue()) }) : ne(ue()),
611
+ !p && /* @__PURE__ */ M("div", { className: "flex items-center gap-1 shrink-0", children: [
612
+ /* @__PURE__ */ l(
613
+ fe,
614
+ {
615
+ color: "tertiary",
616
+ size: "3xs",
617
+ icon: /* @__PURE__ */ l(me, { size: 16 }),
618
+ "aria-label": "Remove condition",
619
+ onClick: K,
620
+ "data-testid": V("remove-button"),
621
+ className: "text-quaternary hover:bg-secondary_hover hover:text-secondary"
622
+ }
623
+ ),
624
+ L && /* @__PURE__ */ l(
625
+ "div",
626
+ {
627
+ className: "flex items-center justify-center cursor-grab active:cursor-grabbing p-1 hover:bg-secondary_hover rounded-md transition-colors text-quaternary hover:text-secondary touch-none",
628
+ onPointerDown: (e) => Q.start(e),
629
+ "aria-label": "Drag to reorder",
630
+ "data-testid": V("drag-handle"),
631
+ children: /* @__PURE__ */ l(ce, { color: "currentColor", size: 16 })
632
+ }
633
+ )
634
+ ] })
635
+ ]
636
+ }
637
+ );
638
+ };
639
+ export {
640
+ sr as FilterConditionRow,
641
+ sr as default
642
+ };
@@ -0,0 +1,42 @@
1
+ import { default as React } from 'react';
2
+ import { FilterGroupBuilderProps } from './types';
3
+ /**
4
+ * FilterGroupBuilder
5
+ *
6
+ * A powerful filter builder component that supports nested filter groups
7
+ * with And/Or logic operators. Inspired by Airtable, Notion, and similar tools.
8
+ *
9
+ * Features:
10
+ * - Nested filter groups (groups within groups)
11
+ * - And/Or logical operators at each level
12
+ * - Multiple field types (string, number, date, select, boolean)
13
+ * - Configurable operators per field type
14
+ * - Maximum depth control
15
+ * - Drag handles for reordering (visual only, implement with your preferred DnD library)
16
+ *
17
+ * @example
18
+ * ```tsx
19
+ * const [filters, setFilters] = useState<FilterGroup>({
20
+ * id: "root",
21
+ * type: "group",
22
+ * operator: "and",
23
+ * children: [],
24
+ * });
25
+ *
26
+ * const fields: FilterField[] = [
27
+ * { id: "priority", label: "Priority", type: "select", options: [...] },
28
+ * { id: "score", label: "Submission Score", type: "number" },
29
+ * { id: "created_at", label: "Created Date", type: "date" },
30
+ * ];
31
+ *
32
+ * <FilterGroupBuilder
33
+ * fields={fields}
34
+ * value={filters}
35
+ * onChange={setFilters}
36
+ * maxDepth={3}
37
+ * />
38
+ * ```
39
+ */
40
+ export declare const FilterGroupBuilder: React.FC<FilterGroupBuilderProps>;
41
+ export default FilterGroupBuilder;
42
+ //# sourceMappingURL=filter-group-builder.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"filter-group-builder.d.ts","sourceRoot":"","sources":["../../../src/patterns/filter-group/filter-group-builder.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAG1B,OAAO,KAAK,EAAE,uBAAuB,EAAe,MAAM,SAAS,CAAC;AAKpE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoCG;AACH,eAAO,MAAM,kBAAkB,EAAE,KAAK,CAAC,EAAE,CAAC,uBAAuB,CAqGhE,CAAC;AAEF,eAAe,kBAAkB,CAAC"}