@etus/ui 0.4.0-beta.3 → 0.4.0-beta.4

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 (165) hide show
  1. package/dist/chunk-2HM5Z2YP.js +834 -0
  2. package/dist/chunk-2HM5Z2YP.js.map +1 -0
  3. package/dist/{chunk-LMTNDUIP.js → chunk-2Y7PQ6ZL.js} +4 -4
  4. package/dist/{chunk-LMTNDUIP.js.map → chunk-2Y7PQ6ZL.js.map} +1 -1
  5. package/dist/{chunk-SAKW2OKH.js → chunk-32IJQOUV.js} +15 -26
  6. package/dist/chunk-32IJQOUV.js.map +1 -0
  7. package/dist/{chunk-CXHA5D3I.js → chunk-33JGPMUW.js} +4 -4
  8. package/dist/{chunk-CXHA5D3I.js.map → chunk-33JGPMUW.js.map} +1 -1
  9. package/dist/{chunk-JLVL76SW.js → chunk-36XTKR3B.js} +4 -4
  10. package/dist/{chunk-JLVL76SW.js.map → chunk-36XTKR3B.js.map} +1 -1
  11. package/dist/{chunk-CUWQUGGB.js → chunk-4GQN76L7.js} +3 -3
  12. package/dist/{chunk-CUWQUGGB.js.map → chunk-4GQN76L7.js.map} +1 -1
  13. package/dist/{chunk-7BAL24EU.js → chunk-5XQIH6WM.js} +4 -4
  14. package/dist/{chunk-7BAL24EU.js.map → chunk-5XQIH6WM.js.map} +1 -1
  15. package/dist/chunk-5ZWFIDO2.js +3 -0
  16. package/dist/{chunk-NNOGFX66.js.map → chunk-5ZWFIDO2.js.map} +1 -1
  17. package/dist/{chunk-CCUCWL6M.js → chunk-AB3S55W5.js} +11 -6
  18. package/dist/chunk-AB3S55W5.js.map +1 -0
  19. package/dist/{chunk-43SINRHH.js → chunk-AUCDXPWH.js} +5 -5
  20. package/dist/{chunk-43SINRHH.js.map → chunk-AUCDXPWH.js.map} +1 -1
  21. package/dist/{chunk-4HRQX2IA.js → chunk-AWYOWR5N.js} +3 -3
  22. package/dist/{chunk-4HRQX2IA.js.map → chunk-AWYOWR5N.js.map} +1 -1
  23. package/dist/{chunk-YTGYSNFR.js → chunk-B4ETIQOO.js} +4 -4
  24. package/dist/{chunk-YTGYSNFR.js.map → chunk-B4ETIQOO.js.map} +1 -1
  25. package/dist/{chunk-D5DM6GZB.js → chunk-D6TH3EGA.js} +12 -12
  26. package/dist/chunk-D6TH3EGA.js.map +1 -0
  27. package/dist/{chunk-ZJVZ3LQS.js → chunk-DDM2I5C6.js} +3 -3
  28. package/dist/{chunk-ZJVZ3LQS.js.map → chunk-DDM2I5C6.js.map} +1 -1
  29. package/dist/{chunk-3JIXCWJO.js → chunk-DDR24GOP.js} +3 -3
  30. package/dist/{chunk-3JIXCWJO.js.map → chunk-DDR24GOP.js.map} +1 -1
  31. package/dist/{chunk-GBTVAO4V.js → chunk-EGYWK2XX.js} +3 -3
  32. package/dist/{chunk-GBTVAO4V.js.map → chunk-EGYWK2XX.js.map} +1 -1
  33. package/dist/{chunk-KNH7JW6E.js → chunk-IBVCSZCH.js} +3 -3
  34. package/dist/{chunk-KNH7JW6E.js.map → chunk-IBVCSZCH.js.map} +1 -1
  35. package/dist/{chunk-VJITPUUS.js → chunk-ICM45N2K.js} +4 -4
  36. package/dist/{chunk-VJITPUUS.js.map → chunk-ICM45N2K.js.map} +1 -1
  37. package/dist/{chunk-GLEKBJLR.js → chunk-ILAV2AZ4.js} +3 -3
  38. package/dist/{chunk-GLEKBJLR.js.map → chunk-ILAV2AZ4.js.map} +1 -1
  39. package/dist/{chunk-MDQFZEIC.js → chunk-J62TFQHR.js} +6 -6
  40. package/dist/chunk-J62TFQHR.js.map +1 -0
  41. package/dist/{chunk-AWWBBMMY.js → chunk-JKYB5QAP.js} +5 -5
  42. package/dist/{chunk-AWWBBMMY.js.map → chunk-JKYB5QAP.js.map} +1 -1
  43. package/dist/{chunk-UKC3Q6OA.js → chunk-JMZ4CO6R.js} +3 -3
  44. package/dist/{chunk-UKC3Q6OA.js.map → chunk-JMZ4CO6R.js.map} +1 -1
  45. package/dist/{chunk-POZNQWZE.js → chunk-KC6CHPT3.js} +4 -4
  46. package/dist/{chunk-POZNQWZE.js.map → chunk-KC6CHPT3.js.map} +1 -1
  47. package/dist/{chunk-4J6DHPYY.js → chunk-KPNNSUXM.js} +3 -3
  48. package/dist/{chunk-4J6DHPYY.js.map → chunk-KPNNSUXM.js.map} +1 -1
  49. package/dist/{chunk-RPV77BCQ.js → chunk-ONQCNOLU.js} +4 -9
  50. package/dist/chunk-ONQCNOLU.js.map +1 -0
  51. package/dist/{chunk-QSY52N3A.js → chunk-OWOVCGUZ.js} +3 -3
  52. package/dist/{chunk-QSY52N3A.js.map → chunk-OWOVCGUZ.js.map} +1 -1
  53. package/dist/{chunk-QWRHPNBY.js → chunk-QIETN4UU.js} +4 -4
  54. package/dist/{chunk-QWRHPNBY.js.map → chunk-QIETN4UU.js.map} +1 -1
  55. package/dist/{chunk-NWFRMVI2.js → chunk-QZWKXUZP.js} +3 -3
  56. package/dist/{chunk-NWFRMVI2.js.map → chunk-QZWKXUZP.js.map} +1 -1
  57. package/dist/{chunk-7QDWREVG.js → chunk-R4UOT76L.js} +3 -3
  58. package/dist/{chunk-7QDWREVG.js.map → chunk-R4UOT76L.js.map} +1 -1
  59. package/dist/{chunk-HIEOL77G.js → chunk-RVUO7SDG.js} +4 -4
  60. package/dist/{chunk-HIEOL77G.js.map → chunk-RVUO7SDG.js.map} +1 -1
  61. package/dist/{chunk-XPVKJIWY.js → chunk-SCGKQ5RE.js} +3 -3
  62. package/dist/{chunk-XPVKJIWY.js.map → chunk-SCGKQ5RE.js.map} +1 -1
  63. package/dist/{chunk-UCGT2IR4.js → chunk-SJSYKUCL.js} +3 -3
  64. package/dist/{chunk-UCGT2IR4.js.map → chunk-SJSYKUCL.js.map} +1 -1
  65. package/dist/{chunk-KOTCWE7V.js → chunk-TNROOKX3.js} +11 -4
  66. package/dist/chunk-TNROOKX3.js.map +1 -0
  67. package/dist/{chunk-PGTCXLGY.js → chunk-U6EOAIPK.js} +3 -3
  68. package/dist/chunk-U6EOAIPK.js.map +1 -0
  69. package/dist/{chunk-KXSJSLPJ.js → chunk-V7XHE25E.js} +4 -4
  70. package/dist/{chunk-KXSJSLPJ.js.map → chunk-V7XHE25E.js.map} +1 -1
  71. package/dist/{chunk-FUCQNVJL.js → chunk-XLTSCY22.js} +10 -7
  72. package/dist/chunk-XLTSCY22.js.map +1 -0
  73. package/dist/{chunk-K3J7YLL4.js → chunk-XOGMDABS.js} +5 -6
  74. package/dist/chunk-XOGMDABS.js.map +1 -0
  75. package/dist/{chunk-53RWD44Z.js → chunk-XRMKL43Y.js} +3 -3
  76. package/dist/{chunk-53RWD44Z.js.map → chunk-XRMKL43Y.js.map} +1 -1
  77. package/dist/{chunk-DZALMUQD.js → chunk-Y3BOERVB.js} +3 -3
  78. package/dist/{chunk-DZALMUQD.js.map → chunk-Y3BOERVB.js.map} +1 -1
  79. package/dist/{chunk-AV5YQ2Z4.js → chunk-Y7UFBSAD.js} +3 -3
  80. package/dist/{chunk-AV5YQ2Z4.js.map → chunk-Y7UFBSAD.js.map} +1 -1
  81. package/dist/{chunk-HNYBLROK.js → chunk-YP2ATSXP.js} +11 -28
  82. package/dist/chunk-YP2ATSXP.js.map +1 -0
  83. package/dist/{chunk-75QBUI2P.js → chunk-ZO2EKJZM.js} +16 -8
  84. package/dist/chunk-ZO2EKJZM.js.map +1 -0
  85. package/dist/{chunk-VOCA4KZB.js → chunk-ZS2WS5NJ.js} +4 -4
  86. package/dist/{chunk-VOCA4KZB.js.map → chunk-ZS2WS5NJ.js.map} +1 -1
  87. package/dist/components/advanced/Calendar/index.js +3 -3
  88. package/dist/components/advanced/EventCalendar/index.js +3 -3
  89. package/dist/components/advanced/FilterBuilder/index.js +3 -3
  90. package/dist/components/advanced/ReportBuilder/index.js +11 -0
  91. package/dist/components/advanced/ReportBuilder/index.js.map +1 -0
  92. package/dist/components/advanced/index.js +12 -8
  93. package/dist/components/data-display/Callout/index.js +1 -1
  94. package/dist/components/data-display/Carousel/index.js +3 -3
  95. package/dist/components/data-display/ChartCard/index.js +2 -2
  96. package/dist/components/data-display/DashboardFilterbar/index.js +5 -5
  97. package/dist/components/data-display/DataTable/FilterBuilder/index.js +3 -3
  98. package/dist/components/data-display/DataTable/index.js +5 -5
  99. package/dist/components/data-display/KPICard/index.js +3 -2
  100. package/dist/components/data-display/List/index.js +3 -3
  101. package/dist/components/data-display/SingleStat/index.js +1 -1
  102. package/dist/components/data-display/VirtualTable/index.js +2 -2
  103. package/dist/components/data-display/index.js +30 -30
  104. package/dist/components/feedback/AlertDialog/index.js +3 -3
  105. package/dist/components/feedback/ConfirmModal/index.js +4 -4
  106. package/dist/components/feedback/Notification/index.js +2 -2
  107. package/dist/components/feedback/index.js +8 -8
  108. package/dist/components/forms/DatePicker/index.js +4 -4
  109. package/dist/components/forms/DateRangePicker/index.js +4 -4
  110. package/dist/components/forms/Field/index.js +2 -2
  111. package/dist/components/forms/Form/index.js +2 -2
  112. package/dist/components/forms/InputGroup/index.js +4 -4
  113. package/dist/components/forms/InputOTPField/index.js +3 -3
  114. package/dist/components/forms/NativeSelect/index.js +1 -1
  115. package/dist/components/forms/TagsInput/index.js +2 -2
  116. package/dist/components/forms/Textarea/index.js +1 -1
  117. package/dist/components/forms/TextareaField/index.js +4 -4
  118. package/dist/components/forms/index.js +28 -28
  119. package/dist/components/index.js +97 -96
  120. package/dist/components/layout/index.js +2 -2
  121. package/dist/components/navigation/AccountSwitch/index.js +3 -3
  122. package/dist/components/navigation/MobileSidebar/index.js +2 -2
  123. package/dist/components/navigation/Pagination/index.js +3 -3
  124. package/dist/components/navigation/Sidebar/index.js +4 -4
  125. package/dist/components/navigation/index.js +11 -11
  126. package/dist/components/primitives/Avatar/index.js +1 -1
  127. package/dist/components/primitives/Badge/index.js +1 -1
  128. package/dist/components/primitives/Button/index.js +2 -2
  129. package/dist/components/primitives/ConfirmButton/index.js +4 -4
  130. package/dist/components/primitives/Label/index.js +1 -1
  131. package/dist/components/primitives/SplitButton/index.js +1 -1
  132. package/dist/components/primitives/index.js +13 -13
  133. package/dist/components/workflow/ApprovalFlow/index.js +4 -4
  134. package/dist/components/workflow/CommentSystem/index.js +5 -5
  135. package/dist/components/workflow/Dashboard/index.js +3 -3
  136. package/dist/components/workflow/DashboardBuilder/index.js +4 -4
  137. package/dist/components/workflow/KanbanBoard/index.js +4 -4
  138. package/dist/components/workflow/ReportGenerator/index.js +4 -4
  139. package/dist/components/workflow/Wizard/index.js +3 -3
  140. package/dist/components/workflow/index.js +14 -14
  141. package/dist/fonts/inter-OFL.txt +92 -0
  142. package/dist/fonts/inter-latin-400-normal.woff2 +0 -0
  143. package/dist/fonts/inter-latin-500-normal.woff2 +0 -0
  144. package/dist/fonts/inter-latin-600-normal.woff2 +0 -0
  145. package/dist/fonts/inter-latin-700-normal.woff2 +0 -0
  146. package/dist/fonts/jetbrains-mono-OFL.txt +93 -0
  147. package/dist/fonts/jetbrains-mono-latin-400-normal.woff2 +0 -0
  148. package/dist/fonts/jetbrains-mono-latin-500-normal.woff2 +0 -0
  149. package/dist/fonts/jetbrains-mono-latin-700-normal.woff2 +0 -0
  150. package/dist/index.d.ts +114 -27
  151. package/dist/index.js +97 -96
  152. package/dist/styles.css +284 -7
  153. package/package.json +2 -2
  154. package/dist/chunk-75QBUI2P.js.map +0 -1
  155. package/dist/chunk-CCUCWL6M.js.map +0 -1
  156. package/dist/chunk-D5DM6GZB.js.map +0 -1
  157. package/dist/chunk-FUCQNVJL.js.map +0 -1
  158. package/dist/chunk-HNYBLROK.js.map +0 -1
  159. package/dist/chunk-K3J7YLL4.js.map +0 -1
  160. package/dist/chunk-KOTCWE7V.js.map +0 -1
  161. package/dist/chunk-MDQFZEIC.js.map +0 -1
  162. package/dist/chunk-NNOGFX66.js +0 -3
  163. package/dist/chunk-PGTCXLGY.js.map +0 -1
  164. package/dist/chunk-RPV77BCQ.js.map +0 -1
  165. package/dist/chunk-SAKW2OKH.js.map +0 -1
@@ -0,0 +1,834 @@
1
+ import { NumberInput } from './chunk-U74PNG4S.js';
2
+ import { Select, SelectTrigger, SelectValue, SelectContent, SelectItem } from './chunk-WBE6VQOO.js';
3
+ import { Checkbox } from './chunk-XETKCF73.js';
4
+ import { Dialog, DialogContent, DialogTitle } from './chunk-ZUFM33AV.js';
5
+ import { Popover, PopoverAnchor, PopoverContent } from './chunk-AFCSDND5.js';
6
+ import { cn } from './chunk-HRNDJU7D.js';
7
+ import { Table, Filter, X, Shapes, Search } from 'lucide-react';
8
+ import * as React from 'react';
9
+ import { jsxs, jsx } from 'react/jsx-runtime';
10
+
11
+ var NUMBER_OPS = [
12
+ { v: ">=", l: "\u2265" },
13
+ { v: "<=", l: "\u2264" },
14
+ { v: ">", l: ">" },
15
+ { v: "<", l: "<" },
16
+ { v: "=", l: "=" },
17
+ { v: "between", l: "between" }
18
+ ];
19
+ var GAM_CHECKBOX = "size-[18px] rounded-xs border-2 border-[color:var(--report-builder-fg-subtle)] data-[state=checked]:border-[color:var(--report-builder-accent)] data-[state=checked]:bg-[color:var(--report-builder-accent)] data-[state=checked]:text-[color:var(--report-builder-on-accent)]";
20
+ var GAM_POPUP = "rounded-lg border-0 p-0 [--report-builder-popup-shadow:0_1px_2px_0_var(--report-builder-shadow),0_2px_6px_2px_var(--report-builder-shadow-subtle)] shadow-[var(--report-builder-popup-shadow)]";
21
+ var numFmt = (n) => n == null ? "" : n.toLocaleString("en-US");
22
+ function listFmt(vals) {
23
+ const head = vals.slice(0, 3).join(", ");
24
+ return vals.length > 3 ? `${head} +${String(vals.length - 3)}` : head;
25
+ }
26
+ function editorStateFor(existing) {
27
+ return {
28
+ a: existing?.a != null ? String(existing.a) : "",
29
+ b: existing?.b != null ? String(existing.b) : "",
30
+ op: existing && existing.op !== "anyOf" && existing.op !== "contains" ? existing.op : ">=",
31
+ text: existing?.text ?? "",
32
+ vals: existing?.values ?? []
33
+ };
34
+ }
35
+ function fieldLabel(label, key) {
36
+ return label.toLowerCase() === key.toLowerCase() ? label : `${label} (${key})`;
37
+ }
38
+ function MetricGlyph() {
39
+ return /* @__PURE__ */ jsx("span", { className: "flex h-4 w-[22px] items-center justify-center text-[12px] font-bold leading-none tracking-tighter text-[color:var(--report-builder-positive)]", children: "123" });
40
+ }
41
+ function DimGlyph() {
42
+ return /* @__PURE__ */ jsx(Shapes, { className: "shrink-0 text-[color:var(--report-builder-accent-bright)]", size: 16 });
43
+ }
44
+ function KindGlyph({ kind }) {
45
+ return kind === "metric" ? /* @__PURE__ */ jsx(MetricGlyph, {}) : /* @__PURE__ */ jsx(DimGlyph, {});
46
+ }
47
+ function GamChip({
48
+ icon,
49
+ children,
50
+ active,
51
+ onClick,
52
+ onRemove
53
+ }) {
54
+ return /* @__PURE__ */ jsxs(
55
+ "span",
56
+ {
57
+ className: cn(
58
+ "inline-flex h-[26px] items-center rounded-xl border pl-3 text-[13px] font-medium",
59
+ active ? "border-[color:var(--report-builder-accent-border)] bg-[color:var(--report-builder-accent-bg)] text-[color:var(--report-builder-accent-hover)]" : "border-[color:var(--report-builder-border)] bg-[color:var(--report-builder-surface)] text-[color:var(--report-builder-fg-muted)]",
60
+ !onRemove && "pr-3",
61
+ onClick && "cursor-pointer",
62
+ onClick && !active && "hover:bg-[color:var(--report-builder-surface-subtle)]"
63
+ ),
64
+ onClick,
65
+ children: [
66
+ icon && /* @__PURE__ */ jsx("span", { className: "mr-2 flex items-center", children: icon }),
67
+ /* @__PURE__ */ jsx("span", { className: "whitespace-nowrap", children }),
68
+ onRemove && /* @__PURE__ */ jsx(
69
+ "button",
70
+ {
71
+ className: cn(
72
+ "flex h-6 w-8 items-center justify-center",
73
+ active ? "text-[color:var(--report-builder-accent-hover)]" : "text-[color:var(--report-builder-fg-muted)] hover:text-[color:var(--report-builder-fg-secondary)]"
74
+ ),
75
+ "aria-label": "Remove",
76
+ type: "button",
77
+ onClick: (e) => {
78
+ e.stopPropagation();
79
+ onRemove();
80
+ },
81
+ children: /* @__PURE__ */ jsx(X, { size: 18 })
82
+ }
83
+ )
84
+ ]
85
+ }
86
+ );
87
+ }
88
+ function AllFieldsDialog({
89
+ onOpenChange,
90
+ fields,
91
+ dimensions,
92
+ metrics,
93
+ onSelectionChange
94
+ }) {
95
+ const [draftDims, setDraftDims] = React.useState(dimensions);
96
+ const [draftMets, setDraftMets] = React.useState(metrics);
97
+ const [display, setDisplay] = React.useState("all");
98
+ const [category, setCategory] = React.useState(
99
+ "popular"
100
+ );
101
+ const [search, setSearch] = React.useState("");
102
+ const [hovered, setHovered] = React.useState(null);
103
+ function toggleDraft(kind, key) {
104
+ const [cur, set] = kind === "dimension" ? [draftDims, setDraftDims] : [draftMets, setDraftMets];
105
+ set(cur.includes(key) ? cur.filter((k) => k !== key) : [...cur, key]);
106
+ }
107
+ function apply() {
108
+ onSelectionChange("dimensions", draftDims);
109
+ onSelectionChange("metrics", draftMets);
110
+ onOpenChange(false);
111
+ }
112
+ const match = (l) => l.toLowerCase().includes(search.trim().toLowerCase());
113
+ const items = fields.filter((f) => {
114
+ if (!match(f.label)) return false;
115
+ if (display === "dimensions" && f.kind !== "dimension") return false;
116
+ if (display === "metrics" && f.kind !== "metric") return false;
117
+ if (category === "dimensions" && f.kind !== "dimension") return false;
118
+ if (category === "metrics" && f.kind !== "metric") return false;
119
+ return true;
120
+ });
121
+ const selected = [
122
+ ...draftDims.map((k) => fields.find((f) => f.kind === "dimension" && f.key === k)),
123
+ ...draftMets.map((k) => fields.find((f) => f.kind === "metric" && f.key === k))
124
+ ].filter((f) => !!f);
125
+ const CATS = [
126
+ { k: "popular", l: "Popular" },
127
+ { k: "dimensions", l: "Dimensions" },
128
+ { k: "metrics", l: "Metrics" }
129
+ ];
130
+ const DISPLAYS = [
131
+ { k: "all", l: "All" },
132
+ { k: "dimensions", l: "Dimensions" },
133
+ { k: "metrics", l: "Metrics" }
134
+ ];
135
+ return /* @__PURE__ */ jsx(Dialog, { open: true, onOpenChange, children: /* @__PURE__ */ jsxs(
136
+ DialogContent,
137
+ {
138
+ className: "left-0 top-0 flex h-screen max-h-screen w-[min(1500px,96vw)] max-w-none translate-x-0 translate-y-0 flex-col gap-0 rounded-none border-0 bg-[color:var(--report-builder-surface)] p-0 text-[color:var(--report-builder-fg)]",
139
+ showCloseButton: false,
140
+ children: [
141
+ /* @__PURE__ */ jsxs("div", { className: "flex shrink-0 items-center gap-4 px-4 py-3", children: [
142
+ /* @__PURE__ */ jsx(
143
+ "button",
144
+ {
145
+ "aria-label": "Close",
146
+ className: "rounded-full p-1.5 text-[color:var(--report-builder-fg-muted)] hover:bg-[color:var(--report-builder-surface-hover)]",
147
+ type: "button",
148
+ onClick: () => {
149
+ onOpenChange(false);
150
+ },
151
+ children: /* @__PURE__ */ jsx(X, { size: 20 })
152
+ }
153
+ ),
154
+ /* @__PURE__ */ jsx(DialogTitle, { className: "text-xl font-normal text-[color:var(--report-builder-fg)]", children: "All dimensions and metrics" }),
155
+ /* @__PURE__ */ jsx("div", { className: "flex-1" }),
156
+ /* @__PURE__ */ jsx("span", { className: "text-sm text-[color:var(--report-builder-fg-muted)]", children: "Display" }),
157
+ /* @__PURE__ */ jsx("div", { className: "flex gap-2", children: DISPLAYS.map((d) => /* @__PURE__ */ jsxs(
158
+ "button",
159
+ {
160
+ className: cn(
161
+ "h-8 rounded px-3 text-sm font-medium",
162
+ display === d.k ? "bg-[color:var(--report-builder-accent-bg)] text-[color:var(--report-builder-accent-hover)]" : "border border-[color:var(--report-builder-border)] text-[color:var(--report-builder-fg-secondary)] hover:bg-[color:var(--report-builder-surface-subtle)]"
163
+ ),
164
+ type: "button",
165
+ onClick: () => {
166
+ setDisplay(d.k);
167
+ },
168
+ children: [
169
+ display === d.k ? "\u2713 " : "",
170
+ d.l
171
+ ]
172
+ },
173
+ d.k
174
+ )) })
175
+ ] }),
176
+ /* @__PURE__ */ jsxs("div", { className: "flex shrink-0 items-center gap-3 border-y border-[color:var(--report-builder-border-strong)] px-4 py-2.5", children: [
177
+ /* @__PURE__ */ jsx(Search, { className: "text-[color:var(--report-builder-fg-muted)]", size: 18 }),
178
+ /* @__PURE__ */ jsx(
179
+ "input",
180
+ {
181
+ autoFocus: true,
182
+ className: "w-full bg-transparent text-sm text-[color:var(--report-builder-fg)] outline-none placeholder:text-[color:var(--report-builder-fg-subtle)]",
183
+ placeholder: "Search",
184
+ value: search,
185
+ onChange: (e) => {
186
+ setSearch(e.target.value);
187
+ }
188
+ }
189
+ )
190
+ ] }),
191
+ /* @__PURE__ */ jsxs("div", { className: "flex min-h-0 flex-1", children: [
192
+ /* @__PURE__ */ jsx("div", { className: "w-56 shrink-0 overflow-auto border-r border-[color:var(--report-builder-border-strong)] py-1", children: CATS.map((c) => /* @__PURE__ */ jsx(
193
+ "button",
194
+ {
195
+ className: cn(
196
+ "flex h-9 w-full items-center px-4 text-left text-sm",
197
+ category === c.k ? "bg-[color:var(--report-builder-surface-hover)] text-[color:var(--report-builder-fg)]" : "text-[color:var(--report-builder-fg-secondary)] hover:bg-[color:var(--report-builder-surface-subtle)]"
198
+ ),
199
+ type: "button",
200
+ onClick: () => {
201
+ setCategory(c.k);
202
+ },
203
+ children: c.l
204
+ },
205
+ c.k
206
+ )) }),
207
+ /* @__PURE__ */ jsxs("div", { className: "min-w-0 flex-[1.4] overflow-auto py-1", children: [
208
+ items.map((f) => {
209
+ const sel = f.kind === "dimension" ? draftDims.includes(f.key) : draftMets.includes(f.key);
210
+ return /* @__PURE__ */ jsxs(
211
+ "label",
212
+ {
213
+ className: "flex h-9 cursor-pointer items-center gap-3 px-4 text-[15px] text-[color:var(--report-builder-fg-strong)] hover:bg-[color:var(--report-builder-surface-muted)]",
214
+ onMouseEnter: () => {
215
+ setHovered(`${f.kind}:${f.key}`);
216
+ },
217
+ onMouseLeave: () => {
218
+ setHovered(null);
219
+ },
220
+ onFocus: () => {
221
+ setHovered(`${f.kind}:${f.key}`);
222
+ },
223
+ onBlur: () => {
224
+ setHovered(null);
225
+ },
226
+ children: [
227
+ /* @__PURE__ */ jsx(
228
+ Checkbox,
229
+ {
230
+ checked: sel,
231
+ className: GAM_CHECKBOX,
232
+ onCheckedChange: () => {
233
+ toggleDraft(f.kind, f.key);
234
+ }
235
+ }
236
+ ),
237
+ /* @__PURE__ */ jsxs("span", { className: "flex items-center gap-2", children: [
238
+ /* @__PURE__ */ jsx(KindGlyph, { kind: f.kind }),
239
+ f.label
240
+ ] })
241
+ ]
242
+ },
243
+ `${f.kind}:${f.key}`
244
+ );
245
+ }),
246
+ items.length === 0 && /* @__PURE__ */ jsx("div", { className: "px-4 py-3 text-sm text-[color:var(--report-builder-fg-subtle)]", children: "No matches" })
247
+ ] }),
248
+ /* @__PURE__ */ jsxs("div", { className: "w-96 shrink-0 overflow-auto border-l border-[color:var(--report-builder-border-strong)]", children: [
249
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between px-4 py-3", children: [
250
+ /* @__PURE__ */ jsxs("span", { className: "text-sm font-medium text-[color:var(--report-builder-fg)]", children: [
251
+ selected.length,
252
+ " Selected"
253
+ ] }),
254
+ /* @__PURE__ */ jsx(
255
+ "button",
256
+ {
257
+ className: "text-sm font-medium text-[color:var(--report-builder-accent-hover)] hover:underline",
258
+ type: "button",
259
+ onClick: () => {
260
+ setDraftDims([]);
261
+ setDraftMets([]);
262
+ },
263
+ children: "Clear all"
264
+ }
265
+ )
266
+ ] }),
267
+ selected.map((f) => /* @__PURE__ */ jsxs("div", { className: "px-4 py-1.5", children: [
268
+ /* @__PURE__ */ jsx("div", { className: "text-xs text-[color:var(--report-builder-fg-muted)]", children: f.kind === "dimension" ? "Dimensions" : "Metrics" }),
269
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
270
+ /* @__PURE__ */ jsx(KindGlyph, { kind: f.kind }),
271
+ /* @__PURE__ */ jsx("span", { className: "flex-1 text-sm text-[color:var(--report-builder-fg)]", children: f.label }),
272
+ /* @__PURE__ */ jsx(
273
+ "button",
274
+ {
275
+ "aria-label": `Remove ${f.label}`,
276
+ className: "rounded-full p-1 text-[color:var(--report-builder-fg-muted)] hover:bg-[color:var(--report-builder-surface-hover)]",
277
+ type: "button",
278
+ onClick: () => {
279
+ toggleDraft(f.kind, f.key);
280
+ },
281
+ children: /* @__PURE__ */ jsx(X, { size: 16 })
282
+ }
283
+ )
284
+ ] })
285
+ ] }, `${f.kind}:${f.key}`))
286
+ ] }),
287
+ /* @__PURE__ */ jsx("div", { className: "w-80 shrink-0 overflow-auto border-l border-[color:var(--report-builder-border-strong)] p-4 text-sm text-[color:var(--report-builder-fg)]", children: hovered ? fields.find((f) => `${f.kind}:${f.key}` === hovered)?.description ?? fields.find((f) => `${f.kind}:${f.key}` === hovered)?.label : "Hover over a dimension or metric to see a description" })
288
+ ] }),
289
+ /* @__PURE__ */ jsxs("div", { className: "flex shrink-0 items-center gap-4 border-t border-[color:var(--report-builder-border-strong)] px-4 py-3", children: [
290
+ /* @__PURE__ */ jsx(
291
+ "button",
292
+ {
293
+ className: "rounded bg-[color:var(--report-builder-accent)] px-6 py-2 text-sm font-medium text-[color:var(--report-builder-on-accent)] hover:bg-[color:var(--report-builder-accent-hover)] disabled:cursor-not-allowed disabled:opacity-50",
294
+ disabled: draftDims.length === 0 || draftMets.length === 0,
295
+ type: "button",
296
+ onClick: apply,
297
+ children: "Apply"
298
+ }
299
+ ),
300
+ /* @__PURE__ */ jsx(
301
+ "button",
302
+ {
303
+ className: "rounded px-2 py-2 text-sm font-medium text-[color:var(--report-builder-accent-hover)] hover:bg-[color:var(--report-builder-accent-bg-subtle)]",
304
+ type: "button",
305
+ onClick: () => {
306
+ onOpenChange(false);
307
+ },
308
+ children: "Cancel"
309
+ }
310
+ )
311
+ ] })
312
+ ]
313
+ }
314
+ ) });
315
+ }
316
+ function FieldsBar({
317
+ fields,
318
+ dimensions,
319
+ metrics,
320
+ onSelectionChange
321
+ }) {
322
+ const [open, setOpen] = React.useState(false);
323
+ const [viewAllOpen, setViewAllOpen] = React.useState(false);
324
+ const [search, setSearch] = React.useState("");
325
+ const [hovered, setHovered] = React.useState(null);
326
+ const inputRef = React.useRef(null);
327
+ const byKey = (kind, key) => fields.find((f) => f.kind === kind && f.key === key);
328
+ function toggle(kind, key) {
329
+ const plural = kind === "dimension" ? "dimensions" : "metrics";
330
+ const cur = kind === "dimension" ? dimensions : metrics;
331
+ if (cur.includes(key)) {
332
+ if (cur.length === 1) return;
333
+ onSelectionChange(plural, cur.filter((k) => k !== key));
334
+ } else {
335
+ onSelectionChange(plural, [...cur, key]);
336
+ }
337
+ }
338
+ const match = (l) => l.toLowerCase().includes(search.trim().toLowerCase());
339
+ const items = fields.filter((f) => match(f.label));
340
+ return /* @__PURE__ */ jsxs("div", { className: "flex items-start border-b border-[color:var(--report-builder-border)] bg-[color:var(--report-builder-surface)] py-3", children: [
341
+ /* @__PURE__ */ jsxs(
342
+ Popover,
343
+ {
344
+ open,
345
+ onOpenChange: (o) => {
346
+ setOpen(o);
347
+ if (!o) {
348
+ setSearch("");
349
+ setHovered(null);
350
+ }
351
+ },
352
+ children: [
353
+ /* @__PURE__ */ jsx(PopoverAnchor, { asChild: true, children: /* @__PURE__ */ jsxs("div", { className: "flex min-w-0 flex-1 items-start", children: [
354
+ /* @__PURE__ */ jsx("div", { className: "flex shrink-0 items-center px-3", children: /* @__PURE__ */ jsx(Table, { className: "text-[color:var(--report-builder-fg)]", size: 24, strokeWidth: 1.5 }) }),
355
+ /* @__PURE__ */ jsxs("div", { className: "min-w-0 flex-1", children: [
356
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-wrap items-center gap-x-2 gap-y-1", children: [
357
+ dimensions.map((k) => /* @__PURE__ */ jsx(
358
+ GamChip,
359
+ {
360
+ icon: /* @__PURE__ */ jsx(DimGlyph, {}),
361
+ onRemove: dimensions.length > 1 ? () => {
362
+ toggle("dimension", k);
363
+ } : void 0,
364
+ children: byKey("dimension", k)?.label ?? k
365
+ },
366
+ `d:${k}`
367
+ )),
368
+ metrics.map((k) => /* @__PURE__ */ jsx(
369
+ GamChip,
370
+ {
371
+ icon: /* @__PURE__ */ jsx(MetricGlyph, {}),
372
+ onRemove: metrics.length > 1 ? () => {
373
+ toggle("metric", k);
374
+ } : void 0,
375
+ children: byKey("metric", k)?.label ?? k
376
+ },
377
+ `m:${k}`
378
+ ))
379
+ ] }),
380
+ /* @__PURE__ */ jsx(
381
+ "input",
382
+ {
383
+ ref: inputRef,
384
+ className: "mt-2 w-full max-w-md bg-transparent text-sm text-[color:var(--report-builder-fg)] outline-none placeholder:text-[color:var(--report-builder-fg-subtle)]",
385
+ placeholder: "Select dimensions and metrics",
386
+ value: search,
387
+ onChange: (e) => {
388
+ setSearch(e.target.value);
389
+ if (!open) setOpen(true);
390
+ },
391
+ onFocus: () => {
392
+ setOpen(true);
393
+ }
394
+ }
395
+ )
396
+ ] })
397
+ ] }) }),
398
+ /* @__PURE__ */ jsxs(
399
+ PopoverContent,
400
+ {
401
+ align: "start",
402
+ className: GAM_POPUP,
403
+ sideOffset: 4,
404
+ style: { width: "var(--radix-popper-anchor-width)" },
405
+ onInteractOutside: (e) => {
406
+ if (e.target === inputRef.current) e.preventDefault();
407
+ },
408
+ onOpenAutoFocus: (e) => {
409
+ e.preventDefault();
410
+ },
411
+ children: [
412
+ /* @__PURE__ */ jsxs("div", { className: "flex", children: [
413
+ /* @__PURE__ */ jsxs("div", { className: "max-h-[340px] flex-[1.6] overflow-auto py-1", children: [
414
+ !search.trim() && /* @__PURE__ */ jsx("div", { className: "px-4 pb-1 pt-2 text-xs font-normal text-[color:var(--report-builder-fg-subtle)]", children: "Popular" }),
415
+ items.map((f) => {
416
+ const sel = f.kind === "dimension" ? dimensions.includes(f.key) : metrics.includes(f.key);
417
+ return /* @__PURE__ */ jsxs(
418
+ "label",
419
+ {
420
+ className: "flex h-8 cursor-pointer items-center gap-3 px-4 text-[15px] text-[color:var(--report-builder-fg-strong)] hover:bg-[color:var(--report-builder-surface-muted)]",
421
+ onMouseEnter: () => {
422
+ setHovered(`${f.kind}:${f.key}`);
423
+ },
424
+ onMouseLeave: () => {
425
+ setHovered(null);
426
+ },
427
+ onFocus: () => {
428
+ setHovered(`${f.kind}:${f.key}`);
429
+ },
430
+ onBlur: () => {
431
+ setHovered(null);
432
+ },
433
+ children: [
434
+ /* @__PURE__ */ jsx(
435
+ Checkbox,
436
+ {
437
+ checked: sel,
438
+ className: GAM_CHECKBOX,
439
+ onCheckedChange: () => {
440
+ toggle(f.kind, f.key);
441
+ }
442
+ }
443
+ ),
444
+ /* @__PURE__ */ jsxs("span", { className: "flex items-center gap-2", children: [
445
+ /* @__PURE__ */ jsx(KindGlyph, { kind: f.kind }),
446
+ f.label
447
+ ] })
448
+ ]
449
+ },
450
+ `${f.kind}:${f.key}`
451
+ );
452
+ }),
453
+ items.length === 0 && /* @__PURE__ */ jsx("div", { className: "px-4 py-2 text-sm text-[color:var(--report-builder-fg-subtle)]", children: "No matches" })
454
+ ] }),
455
+ /* @__PURE__ */ jsx("div", { className: "min-h-[200px] flex-1 border-l border-[color:var(--report-builder-border-strong)] p-4 text-sm text-[color:var(--report-builder-fg)]", children: hovered ? fields.find((f) => `${f.kind}:${f.key}` === hovered)?.description ?? fields.find((f) => `${f.kind}:${f.key}` === hovered)?.label : "Hover over a dimension or metric to see a description" })
456
+ ] }),
457
+ /* @__PURE__ */ jsx("div", { className: "border-t border-[color:var(--report-builder-border-strong)] px-4 py-2.5", children: /* @__PURE__ */ jsx(
458
+ "button",
459
+ {
460
+ "aria-label": "View all fields",
461
+ className: "text-sm font-medium text-[color:var(--report-builder-accent-hover)] hover:underline",
462
+ type: "button",
463
+ onClick: () => {
464
+ setOpen(false);
465
+ setViewAllOpen(true);
466
+ },
467
+ children: "View all"
468
+ }
469
+ ) })
470
+ ]
471
+ }
472
+ )
473
+ ]
474
+ }
475
+ ),
476
+ /* @__PURE__ */ jsx("div", { className: "flex shrink-0 items-center self-stretch border-l border-[color:var(--report-builder-border)] px-4", children: /* @__PURE__ */ jsx(
477
+ "button",
478
+ {
479
+ "aria-label": "View all dimensions and metrics",
480
+ className: "text-sm font-medium text-[color:var(--report-builder-accent-hover)] hover:underline",
481
+ type: "button",
482
+ onClick: () => {
483
+ setViewAllOpen(true);
484
+ },
485
+ children: "View all"
486
+ }
487
+ ) }),
488
+ viewAllOpen && /* @__PURE__ */ jsx(
489
+ AllFieldsDialog,
490
+ {
491
+ dimensions,
492
+ fields,
493
+ metrics,
494
+ onOpenChange: setViewAllOpen,
495
+ onSelectionChange
496
+ }
497
+ )
498
+ ] });
499
+ }
500
+ function filterChipLabel(f, ff) {
501
+ const label = ff ? fieldLabel(ff.label, ff.key) : f.field;
502
+ if (f.op === "anyOf") return `${label} is any of ${listFmt(f.values ?? [])}`;
503
+ if (f.op === "contains") return `${label} contains "${f.text ?? ""}"`;
504
+ if (f.op === "between") return `${ff?.label ?? f.field} between ${numFmt(f.a)} and ${numFmt(f.b)}`;
505
+ const op = NUMBER_OPS.find((o) => o.v === f.op)?.l ?? f.op;
506
+ return `${ff?.label ?? f.field} ${op} ${numFmt(f.a)}`;
507
+ }
508
+ function buildFilterEntry(ff, s) {
509
+ if (ff.type === "enum") {
510
+ return s.vals.length ? { field: ff.key, op: "anyOf", values: s.vals } : null;
511
+ }
512
+ if (ff.type === "text") {
513
+ const t = s.text.trim();
514
+ return t ? { field: ff.key, op: "contains", text: t } : null;
515
+ }
516
+ const na = Number.parseFloat(s.a);
517
+ if (Number.isNaN(na)) return "invalid";
518
+ const nb = s.op === "between" ? Number.parseFloat(s.b) : null;
519
+ if (nb != null && Number.isNaN(nb)) return "invalid";
520
+ return { a: na, b: nb, field: ff.key, op: s.op };
521
+ }
522
+ function FiltersBar({
523
+ filterFields,
524
+ filters,
525
+ onFiltersChange
526
+ }) {
527
+ const [open, setOpen] = React.useState(false);
528
+ const [fieldKey, setFieldKey] = React.useState(null);
529
+ const [editIdx, setEditIdx] = React.useState(null);
530
+ const [vals, setVals] = React.useState([]);
531
+ const [text, setText] = React.useState("");
532
+ const [op, setOp] = React.useState(">=");
533
+ const [a, setA] = React.useState("");
534
+ const [b, setB] = React.useState("");
535
+ const [fsearch, setFsearch] = React.useState("");
536
+ const [vsearch, setVsearch] = React.useState("");
537
+ const inputRef = React.useRef(null);
538
+ const fieldOf = (key) => filterFields.find((f) => f.key === key);
539
+ function reset() {
540
+ setFieldKey(null);
541
+ setEditIdx(null);
542
+ setVals([]);
543
+ setText("");
544
+ setOp(">=");
545
+ setA("");
546
+ setB("");
547
+ setFsearch("");
548
+ setVsearch("");
549
+ }
550
+ function openEditor(key, idx) {
551
+ const ff = fieldOf(key);
552
+ if (!ff) return;
553
+ const existingIdx = idx ?? (ff.type === "number" ? -1 : filters.findIndex((x) => x.field === key));
554
+ const seed = editorStateFor(existingIdx >= 0 ? filters[existingIdx] : void 0);
555
+ setFieldKey(key);
556
+ setEditIdx(existingIdx >= 0 ? existingIdx : null);
557
+ setVsearch("");
558
+ setVals(seed.vals);
559
+ setText(seed.text);
560
+ setOp(seed.op);
561
+ setA(seed.a);
562
+ setB(seed.b);
563
+ setOpen(true);
564
+ }
565
+ function apply() {
566
+ const ff = fieldKey ? fieldOf(fieldKey) : null;
567
+ if (!ff) return;
568
+ const entry = buildFilterEntry(ff, { a, b, op, text, vals });
569
+ if (entry === "invalid") return;
570
+ const next = [...filters];
571
+ if (editIdx != null) {
572
+ if (entry) next[editIdx] = entry;
573
+ else next.splice(editIdx, 1);
574
+ } else if (entry) {
575
+ next.push(entry);
576
+ }
577
+ onFiltersChange(next);
578
+ setOpen(false);
579
+ reset();
580
+ }
581
+ const editorField = fieldKey ? fieldOf(fieldKey) : null;
582
+ const valueOptions = editorField?.options ?? [];
583
+ const valueSuggestions = valueOptions.filter(
584
+ (v) => !vals.includes(v) && v.toLowerCase().includes(vsearch.trim().toLowerCase())
585
+ );
586
+ const fieldMatches = (l) => l.toLowerCase().includes(fsearch.trim().toLowerCase());
587
+ return /* @__PURE__ */ jsxs("div", { className: "flex min-h-12 items-center bg-[color:var(--report-builder-surface)] py-2", children: [
588
+ /* @__PURE__ */ jsx("div", { className: "flex shrink-0 items-center px-3", children: /* @__PURE__ */ jsx(Filter, { className: "text-[color:var(--report-builder-accent)]", fill: "currentColor", size: 20, strokeWidth: 0 }) }),
589
+ /* @__PURE__ */ jsxs("div", { className: "flex min-w-0 flex-1 flex-wrap items-center gap-x-2 gap-y-1", children: [
590
+ filters.map((f, i) => /* @__PURE__ */ jsx(
591
+ GamChip,
592
+ {
593
+ active: open && editIdx === i,
594
+ onClick: () => {
595
+ openEditor(f.field, i);
596
+ },
597
+ onRemove: () => {
598
+ onFiltersChange(filters.filter((_, j) => j !== i));
599
+ },
600
+ children: filterChipLabel(f, fieldOf(f.field))
601
+ },
602
+ `${f.field}:${filterChipLabel(f, fieldOf(f.field))}`
603
+ )),
604
+ /* @__PURE__ */ jsxs(
605
+ Popover,
606
+ {
607
+ open,
608
+ onOpenChange: (o) => {
609
+ setOpen(o);
610
+ if (!o) reset();
611
+ },
612
+ children: [
613
+ /* @__PURE__ */ jsx(PopoverAnchor, { asChild: true, children: /* @__PURE__ */ jsx(
614
+ "input",
615
+ {
616
+ ref: inputRef,
617
+ className: "w-28 bg-transparent px-2 py-1 text-sm text-[color:var(--report-builder-fg)] outline-none placeholder:text-[color:var(--report-builder-fg-subtle)]",
618
+ placeholder: "Add filter",
619
+ value: fsearch,
620
+ onChange: (e) => {
621
+ setFsearch(e.target.value);
622
+ if (!open) setOpen(true);
623
+ },
624
+ onFocus: () => {
625
+ if (fieldKey === null) setOpen(true);
626
+ }
627
+ }
628
+ ) }),
629
+ /* @__PURE__ */ jsx(
630
+ PopoverContent,
631
+ {
632
+ align: "start",
633
+ className: cn(fieldKey === null ? "w-72" : "w-[26rem]", GAM_POPUP),
634
+ onInteractOutside: (e) => {
635
+ if (e.target === inputRef.current) e.preventDefault();
636
+ },
637
+ onOpenAutoFocus: (e) => {
638
+ e.preventDefault();
639
+ },
640
+ children: fieldKey === null ? (
641
+ // step 1 — field list (filtered by the inline field's text)
642
+ /* @__PURE__ */ jsx("div", { className: "max-h-80 overflow-auto py-1", children: filterFields.filter((f) => fieldMatches(f.label)).map((f) => /* @__PURE__ */ jsxs(
643
+ "button",
644
+ {
645
+ className: "flex h-8 w-full items-center gap-2 px-4 text-left text-[15px] text-[color:var(--report-builder-fg-strong)] hover:bg-[color:var(--report-builder-surface-muted)]",
646
+ type: "button",
647
+ onClick: () => {
648
+ openEditor(f.key);
649
+ },
650
+ children: [
651
+ /* @__PURE__ */ jsx(KindGlyph, { kind: f.glyph ?? "dimension" }),
652
+ f.label
653
+ ]
654
+ },
655
+ f.key
656
+ )) })
657
+ ) : (
658
+ // step 2 — GAM editor popup: title + ✕, operator, values, Apply
659
+ /* @__PURE__ */ jsxs("div", { children: [
660
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between px-3 pb-1 pt-3", children: [
661
+ /* @__PURE__ */ jsx("span", { className: "text-base text-[color:var(--report-builder-fg)]", children: editorField ? fieldLabel(editorField.label, editorField.key) : fieldKey }),
662
+ /* @__PURE__ */ jsx(
663
+ "button",
664
+ {
665
+ "aria-label": "Close",
666
+ className: "rounded-full p-1 text-[color:var(--report-builder-fg-muted)] hover:bg-[color:var(--report-builder-surface-hover)]",
667
+ type: "button",
668
+ onClick: () => {
669
+ setOpen(false);
670
+ reset();
671
+ },
672
+ children: /* @__PURE__ */ jsx(X, { size: 18 })
673
+ }
674
+ )
675
+ ] }),
676
+ editorField?.type === "text" ? /* @__PURE__ */ jsxs("div", { className: "px-3 py-2", children: [
677
+ /* @__PURE__ */ jsx("div", { className: "mb-2 rounded border border-[color:var(--report-builder-border)] px-3 py-2 text-[13px] text-[color:var(--report-builder-fg-muted)]", children: "contains" }),
678
+ /* @__PURE__ */ jsx(
679
+ "input",
680
+ {
681
+ autoFocus: true,
682
+ className: "w-full border-b border-[color:var(--report-builder-border)] bg-transparent py-1 text-sm text-[color:var(--report-builder-fg)] outline-none placeholder:text-[color:var(--report-builder-fg-subtle)] focus:border-[color:var(--report-builder-accent)]",
683
+ placeholder: "Type to search",
684
+ value: text,
685
+ onChange: (e) => {
686
+ setText(e.target.value);
687
+ }
688
+ }
689
+ )
690
+ ] }) : editorField?.type === "number" ? /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 px-3 py-2", children: [
691
+ /* @__PURE__ */ jsxs(Select, { value: op, onValueChange: setOp, children: [
692
+ /* @__PURE__ */ jsx(SelectTrigger, { className: "w-24", size: "sm", children: /* @__PURE__ */ jsx(SelectValue, {}) }),
693
+ /* @__PURE__ */ jsx(SelectContent, { children: NUMBER_OPS.map((o) => /* @__PURE__ */ jsx(SelectItem, { value: o.v, children: o.l }, o.v)) })
694
+ ] }),
695
+ /* @__PURE__ */ jsx(
696
+ NumberInput,
697
+ {
698
+ placeholder: "value",
699
+ value: a,
700
+ onChange: (e) => {
701
+ setA(e.target.value);
702
+ }
703
+ }
704
+ ),
705
+ op === "between" && /* @__PURE__ */ jsx(
706
+ NumberInput,
707
+ {
708
+ placeholder: "to",
709
+ value: b,
710
+ onChange: (e) => {
711
+ setB(e.target.value);
712
+ }
713
+ }
714
+ )
715
+ ] }) : /* @__PURE__ */ jsxs("div", { className: "px-3 py-2", children: [
716
+ /* @__PURE__ */ jsx("div", { className: "mb-2 rounded border border-[color:var(--report-builder-border)] px-3 py-2 text-[13px] text-[color:var(--report-builder-fg-muted)]", children: "is any of" }),
717
+ vals.length > 0 && /* @__PURE__ */ jsx("div", { className: "mb-1 flex flex-wrap gap-x-2 gap-y-1", children: vals.map((v) => /* @__PURE__ */ jsx(
718
+ GamChip,
719
+ {
720
+ onRemove: () => {
721
+ setVals((p) => p.filter((x) => x !== v));
722
+ },
723
+ children: v
724
+ },
725
+ v
726
+ )) }),
727
+ /* @__PURE__ */ jsx(
728
+ "input",
729
+ {
730
+ autoFocus: true,
731
+ className: "w-full border-b border-[color:var(--report-builder-border)] bg-transparent py-1 text-sm text-[color:var(--report-builder-fg)] outline-none placeholder:text-[color:var(--report-builder-fg-subtle)] focus:border-[color:var(--report-builder-accent)]",
732
+ placeholder: "Type to search",
733
+ value: vsearch,
734
+ onChange: (e) => {
735
+ setVsearch(e.target.value);
736
+ },
737
+ onKeyDown: (e) => {
738
+ const first = valueSuggestions[0];
739
+ if (e.key === "Enter" && first) {
740
+ e.preventDefault();
741
+ setVals((p) => [...p, first]);
742
+ setVsearch("");
743
+ }
744
+ }
745
+ }
746
+ ),
747
+ /* @__PURE__ */ jsx("div", { className: "mt-1 max-h-44 overflow-auto", children: valueSuggestions.map((v) => /* @__PURE__ */ jsx(
748
+ "button",
749
+ {
750
+ className: "flex h-8 w-full items-center px-2 text-left text-sm text-[color:var(--report-builder-fg-strong)] hover:bg-[color:var(--report-builder-surface-muted)]",
751
+ type: "button",
752
+ onClick: () => {
753
+ setVals((p) => [...p, v]);
754
+ setVsearch("");
755
+ },
756
+ children: v
757
+ },
758
+ v
759
+ )) })
760
+ ] }),
761
+ /* @__PURE__ */ jsx("div", { className: "flex justify-end px-3 pb-2 pt-1", children: /* @__PURE__ */ jsx(
762
+ "button",
763
+ {
764
+ className: "rounded px-2 py-1 text-sm font-medium text-[color:var(--report-builder-accent-hover)] hover:bg-[color:var(--report-builder-accent-bg-subtle)]",
765
+ type: "button",
766
+ onClick: apply,
767
+ children: "Apply"
768
+ }
769
+ ) })
770
+ ] })
771
+ )
772
+ }
773
+ )
774
+ ]
775
+ }
776
+ )
777
+ ] }),
778
+ filters.length > 0 && /* @__PURE__ */ jsx(
779
+ "button",
780
+ {
781
+ "aria-label": "Clear all filters",
782
+ className: "mx-2 flex shrink-0 items-center rounded-full p-2 text-[color:var(--report-builder-fg-muted)] hover:bg-[color:var(--report-builder-surface-hover)]",
783
+ type: "button",
784
+ onClick: () => {
785
+ onFiltersChange([]);
786
+ },
787
+ children: /* @__PURE__ */ jsx(X, { size: 20 })
788
+ }
789
+ )
790
+ ] });
791
+ }
792
+ function ReportBuilder({
793
+ fields,
794
+ dimensions,
795
+ metrics,
796
+ onSelectionChange,
797
+ filterFields,
798
+ filters = [],
799
+ onFiltersChange,
800
+ className,
801
+ ...props
802
+ }) {
803
+ return /* @__PURE__ */ jsxs(
804
+ "div",
805
+ {
806
+ className: cn("flex flex-col border border-[color:var(--report-builder-border)] bg-[color:var(--report-builder-surface)]", className),
807
+ "data-slot": "report-builder",
808
+ ...props,
809
+ children: [
810
+ /* @__PURE__ */ jsx(
811
+ FieldsBar,
812
+ {
813
+ dimensions,
814
+ fields,
815
+ metrics,
816
+ onSelectionChange
817
+ }
818
+ ),
819
+ filterFields && filterFields.length > 0 && onFiltersChange && /* @__PURE__ */ jsx(
820
+ FiltersBar,
821
+ {
822
+ filterFields,
823
+ filters,
824
+ onFiltersChange
825
+ }
826
+ )
827
+ ]
828
+ }
829
+ );
830
+ }
831
+
832
+ export { ReportBuilder };
833
+ //# sourceMappingURL=chunk-2HM5Z2YP.js.map
834
+ //# sourceMappingURL=chunk-2HM5Z2YP.js.map