beez-ui 0.4.2 → 0.5.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +35 -27
- package/README.md +28 -5
- package/dist/adapters/unpic-image.js +92 -14
- package/dist/components/alert-dialog.js +444 -26
- package/dist/components/alert.js +153 -18
- package/dist/components/animated-theme-toggler.js +215 -76
- package/dist/components/avatar.js +247 -15
- package/dist/components/badge.js +18 -16
- package/dist/components/button.js +85 -28
- package/dist/components/calendar.js +327 -68
- package/dist/components/card.js +39 -9
- package/dist/components/carousel.js +454 -84
- package/dist/components/checkbox.js +50 -3
- package/dist/components/data-table.js +827 -583
- package/dist/components/dialog.js +363 -22
- package/dist/components/dropdown-menu.d.ts +1 -0
- package/dist/components/dropdown-menu.js +544 -32
- package/dist/components/filter-query-bar.js +809 -468
- package/dist/components/filter-query-grammar.js +781 -736
- package/dist/components/form.js +305 -43
- package/dist/components/highlighter.js +142 -87
- package/dist/components/hover-card.js +97 -7
- package/dist/components/input-group.js +261 -41
- package/dist/components/input.js +8 -2
- package/dist/components/label.js +38 -3
- package/dist/components/link.js +45 -7
- package/dist/components/pagination.js +332 -16
- package/dist/components/popover.js +222 -16
- package/dist/components/radio-group.js +85 -5
- package/dist/components/select.js +451 -22
- package/dist/components/separator.js +43 -3
- package/dist/components/sheet.js +345 -22
- package/dist/components/sidebar.js +1385 -193
- package/dist/components/skeleton.js +6 -2
- package/dist/components/svgs/whatsappIcon.js +11 -1
- package/dist/components/switch.js +55 -3
- package/dist/components/table.js +288 -18
- package/dist/components/tabs.js +161 -18
- package/dist/components/textarea.js +7 -2
- package/dist/components/themed-toaster.js +63 -20
- package/dist/components/tooltip.js +128 -9
- package/dist/components/typing-animation.js +335 -150
- package/dist/constants/sidebar.js +1 -4
- package/dist/hooks/use-mobile.js +8 -8
- package/dist/hooks/use-sidebar-persistence.js +27 -27
- package/dist/lib/image-dimensions.js +2 -2
- package/dist/lib/year-month-filter.js +38 -40
- package/dist/next.js +69 -17
- package/dist/providers/beez-ui-provider.js +48 -7
- package/dist/providers/native-provider.js +40 -6
- package/dist/styles.css +1 -1
- package/dist/tanstack.js +35 -23
- package/package.json +4 -1
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import {
|
|
2
|
+
import { c as _c } from "react/compiler-runtime";
|
|
3
3
|
import * as React from "react";
|
|
4
|
-
import { Calendar, Check, CircleDot, CircleMinus, CircleSlash, Folder, Hash, List, Type, User, X
|
|
4
|
+
import { Calendar, Check, CircleDot, CircleMinus, CircleSlash, Folder, Hash, List, Type, User, X } from "lucide-react";
|
|
5
5
|
import { Button } from "./button.js";
|
|
6
6
|
import { Input } from "./input.js";
|
|
7
|
-
import { Popover, PopoverAnchor, PopoverContent
|
|
7
|
+
import { Popover, PopoverAnchor, PopoverContent } from "./popover.js";
|
|
8
8
|
import { cn } from "../lib/utils.js";
|
|
9
|
-
import { getActiveFilterToken, getValueHighlightRanges, normalizeFilterSlug, parseFilterQuery, PRESENCE_HAS_META_KEY, PRESENCE_NO_META_KEY, UNASSIGNED_FOLDER_FILTER_VALUE
|
|
9
|
+
import { getActiveFilterToken, getValueHighlightRanges, normalizeFilterSlug, parseFilterQuery, PRESENCE_HAS_META_KEY, PRESENCE_NO_META_KEY, UNASSIGNED_FOLDER_FILTER_VALUE } from "./filter-query-grammar.js";
|
|
10
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
10
11
|
const DEFAULT_PLACEHOLDER = "Filtrar por campo o palabra clave";
|
|
11
12
|
const DEFAULT_ARIA_LABEL = "Filtrar gastos";
|
|
12
13
|
const CLEAR_FILTER_ARIA_LABEL = "Limpiar todos los filtros";
|
|
@@ -15,512 +16,852 @@ const VALUE_GROUP_LABEL = "Valores";
|
|
|
15
16
|
const LISTBOX_ID = "filter-query-bar-listbox";
|
|
16
17
|
const OPTION_ID_PREFIX = "filter-query-bar-option";
|
|
17
18
|
const NUMBER_RANGE_VALUE_SUGGESTIONS = [
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
19
|
+
{
|
|
20
|
+
label: "Mayor o igual (≥)",
|
|
21
|
+
slug: ">="
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
label: "Menor o igual (≤)",
|
|
25
|
+
slug: "<="
|
|
26
|
+
},
|
|
27
|
+
{
|
|
28
|
+
label: "Rango (100..500)",
|
|
29
|
+
slug: ".."
|
|
30
|
+
}
|
|
21
31
|
];
|
|
22
32
|
/**
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
33
|
+
* Operadores para qualifiers de fecha (mes-año). Reflejan los numéricos: cota
|
|
34
|
+
* inferior (`>=`), cota superior (`<=`) y rango (`..`). La presencia/ausencia de
|
|
35
|
+
* fecha se cubre con las meta-claves `tiene:`/`no:` del bloque universal.
|
|
36
|
+
*/
|
|
27
37
|
const YEAR_MONTH_VALUE_SUGGESTIONS = [
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
38
|
+
{
|
|
39
|
+
keepOpen: true,
|
|
40
|
+
label: "Desde (≥)",
|
|
41
|
+
slug: ">="
|
|
42
|
+
},
|
|
43
|
+
{
|
|
44
|
+
keepOpen: true,
|
|
45
|
+
label: "Hasta (≤)",
|
|
46
|
+
slug: "<="
|
|
47
|
+
},
|
|
48
|
+
{
|
|
49
|
+
keepOpen: true,
|
|
50
|
+
label: "Rango (2026-01..2026-06)",
|
|
51
|
+
slug: ".."
|
|
52
|
+
}
|
|
31
53
|
];
|
|
32
54
|
const TEXT_MATCH_VALUE_SUGGESTIONS = [
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
55
|
+
{
|
|
56
|
+
caretOffset: 0,
|
|
57
|
+
insertText: "*",
|
|
58
|
+
keepOpen: true,
|
|
59
|
+
label: "Empieza por…",
|
|
60
|
+
name: "starts",
|
|
61
|
+
slug: ""
|
|
62
|
+
},
|
|
63
|
+
{
|
|
64
|
+
caretOffset: 1,
|
|
65
|
+
insertText: "**",
|
|
66
|
+
keepOpen: true,
|
|
67
|
+
label: "Contiene…",
|
|
68
|
+
name: "contains",
|
|
69
|
+
slug: ""
|
|
70
|
+
},
|
|
71
|
+
{
|
|
72
|
+
insertText: "*",
|
|
73
|
+
keepOpen: true,
|
|
74
|
+
label: "Termina con…",
|
|
75
|
+
name: "ends",
|
|
76
|
+
slug: ""
|
|
77
|
+
}
|
|
39
78
|
];
|
|
40
79
|
/** Meta-claves de presencia ofrecidas también como campos de primer nivel. */
|
|
41
|
-
const PRESENCE_META_KEY_SUGGESTIONS = [
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
80
|
+
const PRESENCE_META_KEY_SUGGESTIONS = [{
|
|
81
|
+
icon: Check,
|
|
82
|
+
key: PRESENCE_HAS_META_KEY,
|
|
83
|
+
label: "Tiene…"
|
|
84
|
+
}, {
|
|
85
|
+
icon: CircleSlash,
|
|
86
|
+
key: PRESENCE_NO_META_KEY,
|
|
87
|
+
label: "No tiene…"
|
|
88
|
+
}];
|
|
45
89
|
/** Icono representativo de cada tipo de qualifier, mostrado a su izquierda. */
|
|
46
90
|
function getKindIcon(kind) {
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
case "yearMonthRange":
|
|
57
|
-
return Calendar;
|
|
58
|
-
case "folder":
|
|
59
|
-
return Folder;
|
|
60
|
-
default:
|
|
61
|
-
return Type;
|
|
62
|
-
}
|
|
91
|
+
switch (kind) {
|
|
92
|
+
case "numberRange": return Hash;
|
|
93
|
+
case "textMatch": return Type;
|
|
94
|
+
case "enum": return List;
|
|
95
|
+
case "presence": return CircleDot;
|
|
96
|
+
case "yearMonthRange": return Calendar;
|
|
97
|
+
case "folder": return Folder;
|
|
98
|
+
default: return Type;
|
|
99
|
+
}
|
|
63
100
|
}
|
|
64
101
|
/** Iconos por nombre lógico declarado en el qualifier (`config.iconName`). */
|
|
65
|
-
const ICON_BY_NAME = {
|
|
66
|
-
user: User,
|
|
67
|
-
};
|
|
102
|
+
const ICON_BY_NAME = { user: User };
|
|
68
103
|
/** Icono de un qualifier: override por `iconName`, o el icono por defecto del kind. */
|
|
69
104
|
function getQualifierIcon(config) {
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
105
|
+
if (config.iconName && ICON_BY_NAME[config.iconName]) {
|
|
106
|
+
return ICON_BY_NAME[config.iconName];
|
|
107
|
+
}
|
|
108
|
+
return getKindIcon(config.kind);
|
|
74
109
|
}
|
|
75
110
|
function startsWithNormalized(candidate, prefix) {
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
111
|
+
if (!prefix) {
|
|
112
|
+
return true;
|
|
113
|
+
}
|
|
114
|
+
return normalizeFilterSlug(candidate).startsWith(normalizeFilterSlug(prefix));
|
|
80
115
|
}
|
|
81
116
|
/** Etiqueta de la opción raíz de exclusión (arranca un token `-campo:`). */
|
|
82
117
|
const EXCLUDE_ROOT_LABEL = "Excluir";
|
|
83
118
|
function buildKeySuggestions(configs, keyPart, { negated, includeExclude, appliedFilters }) {
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
}));
|
|
116
|
-
// "Excluir" al final (estilo GitHub): inserta `-` y reabre la lista de campos
|
|
117
|
-
// para elegir cuál excluir.
|
|
118
|
-
const excludeSuggestion = includeExclude
|
|
119
|
-
? [
|
|
120
|
-
{
|
|
121
|
-
group: "meta",
|
|
122
|
-
icon: CircleMinus,
|
|
123
|
-
id: `${OPTION_ID_PREFIX}-exclude-root`,
|
|
124
|
-
insertText: "-",
|
|
125
|
-
keepOpen: true,
|
|
126
|
-
label: EXCLUDE_ROOT_LABEL,
|
|
127
|
-
},
|
|
128
|
-
]
|
|
129
|
-
: [];
|
|
130
|
-
return [...fieldSuggestions, ...metaSuggestions, ...excludeSuggestion];
|
|
119
|
+
const prefix = negated ? "-" : "";
|
|
120
|
+
const fieldSuggestions = configs.filter((config) => config.kind !== "text" && config.key).filter((config) => getAppliedPresenceValue(config, appliedFilters) !== "noValue").filter((config) => startsWithNormalized(config.key, keyPart) || startsWithNormalized(config.label, keyPart)).map((config) => ({
|
|
121
|
+
group: "key",
|
|
122
|
+
icon: getQualifierIcon(config),
|
|
123
|
+
id: `${OPTION_ID_PREFIX}-key-${negated ? "neg-" : ""}${config.key}`,
|
|
124
|
+
insertText: `${prefix}${config.key}:`,
|
|
125
|
+
keepOpen: true,
|
|
126
|
+
label: config.label
|
|
127
|
+
}));
|
|
128
|
+
const hasPresenceCapableFields = configs.some((config) => config.kind !== "text" && Boolean(config.key) && config.supportsPresence !== false);
|
|
129
|
+
const metaSuggestions = negated || !hasPresenceCapableFields ? [] : PRESENCE_META_KEY_SUGGESTIONS.filter((meta) => startsWithNormalized(meta.key, keyPart) || startsWithNormalized(meta.label, keyPart)).map((meta) => ({
|
|
130
|
+
group: "meta",
|
|
131
|
+
icon: meta.icon,
|
|
132
|
+
id: `${OPTION_ID_PREFIX}-key-${meta.key}`,
|
|
133
|
+
insertText: `${meta.key}:`,
|
|
134
|
+
keepOpen: true,
|
|
135
|
+
label: meta.label
|
|
136
|
+
}));
|
|
137
|
+
const excludeSuggestion = includeExclude ? [{
|
|
138
|
+
group: "meta",
|
|
139
|
+
icon: CircleMinus,
|
|
140
|
+
id: `${OPTION_ID_PREFIX}-exclude-root`,
|
|
141
|
+
insertText: "-",
|
|
142
|
+
keepOpen: true,
|
|
143
|
+
label: EXCLUDE_ROOT_LABEL
|
|
144
|
+
}] : [];
|
|
145
|
+
return [
|
|
146
|
+
...fieldSuggestions,
|
|
147
|
+
...metaSuggestions,
|
|
148
|
+
...excludeSuggestion
|
|
149
|
+
];
|
|
131
150
|
}
|
|
132
151
|
/**
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
152
|
+
* Sugerencias de valor para una meta-clave de presencia (`tiene:` / `no:`): el
|
|
153
|
+
* "valor" es la clave del campo destino (`tiene:enviados`, `no:carpeta`).
|
|
154
|
+
*/
|
|
136
155
|
function buildMetaValueSuggestions(configs, metaKey, valuePart, appliedFilters) {
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
icon: getQualifierIcon(config),
|
|
146
|
-
id: `${OPTION_ID_PREFIX}-meta-${metaKey}-${config.key}`,
|
|
147
|
-
insertText: `${config.key} `,
|
|
148
|
-
keepOpen: false,
|
|
149
|
-
label: config.label,
|
|
150
|
-
}));
|
|
156
|
+
return configs.filter((config) => config.kind !== "text" && config.key).filter((config) => config.supportsPresence !== false).filter((config) => !hasPresenceMetaFilterAlreadyApplied(config, appliedFilters)).filter((config) => startsWithNormalized(config.key, valuePart) || startsWithNormalized(config.label, valuePart)).map((config) => ({
|
|
157
|
+
group: "value",
|
|
158
|
+
icon: getQualifierIcon(config),
|
|
159
|
+
id: `${OPTION_ID_PREFIX}-meta-${metaKey}-${config.key}`,
|
|
160
|
+
insertText: `${config.key} `,
|
|
161
|
+
keepOpen: false,
|
|
162
|
+
label: config.label
|
|
163
|
+
}));
|
|
151
164
|
}
|
|
152
165
|
/**
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
166
|
+
* Bloque universal que aparece al entrar a cualquier filtro: presencia
|
|
167
|
+
* (`tiene:<clave>`), ausencia (`no:<clave>`) y exclusión de un valor
|
|
168
|
+
* (`-<clave>:`). Reescriben el token completo, por eso usan `replaceTokenStart`.
|
|
169
|
+
*/
|
|
157
170
|
function buildPresenceAndExcludeSuggestions(config, appliedFilters) {
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
insertText: `-${config.key}:`,
|
|
190
|
-
keepOpen: true,
|
|
191
|
-
label: `Excluir ${config.label}…`,
|
|
192
|
-
replaceTokenStart: true,
|
|
193
|
-
});
|
|
194
|
-
}
|
|
195
|
-
return suggestions;
|
|
171
|
+
const appliedPresenceValue = getAppliedPresenceValue(config, appliedFilters);
|
|
172
|
+
const hasAppliedPresence = appliedPresenceValue != null;
|
|
173
|
+
const suggestions = hasAppliedPresence || config.supportsPresence === false ? [] : [{
|
|
174
|
+
group: "meta",
|
|
175
|
+
icon: CircleSlash,
|
|
176
|
+
id: `${OPTION_ID_PREFIX}-presence-no-${config.key}`,
|
|
177
|
+
insertText: `${PRESENCE_NO_META_KEY}:${config.key} `,
|
|
178
|
+
keepOpen: false,
|
|
179
|
+
label: `No tiene ${config.label}`,
|
|
180
|
+
replaceTokenStart: true
|
|
181
|
+
}, {
|
|
182
|
+
group: "meta",
|
|
183
|
+
icon: Check,
|
|
184
|
+
id: `${OPTION_ID_PREFIX}-presence-has-${config.key}`,
|
|
185
|
+
insertText: `${PRESENCE_HAS_META_KEY}:${config.key} `,
|
|
186
|
+
keepOpen: false,
|
|
187
|
+
label: `Tiene ${config.label}`,
|
|
188
|
+
replaceTokenStart: true
|
|
189
|
+
}];
|
|
190
|
+
if (config.kind !== "presence" && appliedPresenceValue !== "noValue") {
|
|
191
|
+
suggestions.push({
|
|
192
|
+
group: "meta",
|
|
193
|
+
icon: CircleMinus,
|
|
194
|
+
id: `${OPTION_ID_PREFIX}-exclude-${config.key}`,
|
|
195
|
+
insertText: `-${config.key}:`,
|
|
196
|
+
keepOpen: true,
|
|
197
|
+
label: `Excluir ${config.label}…`,
|
|
198
|
+
replaceTokenStart: true
|
|
199
|
+
});
|
|
200
|
+
}
|
|
201
|
+
return suggestions;
|
|
196
202
|
}
|
|
197
203
|
function getValueSuggestionSource(config) {
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
return [];
|
|
204
|
+
if (config.kind === "enum" || config.kind === "folder") {
|
|
205
|
+
return (config.options ?? []).map((option) => ({
|
|
206
|
+
label: option.label,
|
|
207
|
+
slug: option.slug,
|
|
208
|
+
value: option.value
|
|
209
|
+
}));
|
|
210
|
+
}
|
|
211
|
+
if (config.kind === "presence") {
|
|
212
|
+
return [];
|
|
213
|
+
}
|
|
214
|
+
if (config.kind === "yearMonthRange") {
|
|
215
|
+
return YEAR_MONTH_VALUE_SUGGESTIONS;
|
|
216
|
+
}
|
|
217
|
+
if (config.kind === "numberRange") {
|
|
218
|
+
return NUMBER_RANGE_VALUE_SUGGESTIONS;
|
|
219
|
+
}
|
|
220
|
+
if (config.kind === "textMatch") {
|
|
221
|
+
return TEXT_MATCH_VALUE_SUGGESTIONS;
|
|
222
|
+
}
|
|
223
|
+
return [];
|
|
219
224
|
}
|
|
220
225
|
function hasPresenceMetaFilterAlreadyApplied(config, appliedFilters) {
|
|
221
|
-
|
|
222
|
-
!appliedFilter.negated &&
|
|
223
|
-
appliedFilter.value.kind === "presence");
|
|
226
|
+
return appliedFilters.some((appliedFilter) => appliedFilter.key === config.key && !appliedFilter.negated && appliedFilter.value.kind === "presence");
|
|
224
227
|
}
|
|
225
228
|
function hasSelectableValueAlreadyApplied(config, option, appliedFilters) {
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
appliedFilter.value.kind === "folder" &&
|
|
234
|
-
appliedFilter.value.folderId === option.value);
|
|
235
|
-
}
|
|
236
|
-
return false;
|
|
229
|
+
if (config.kind === "enum") {
|
|
230
|
+
return appliedFilters.some((appliedFilter) => appliedFilter.key === config.key && appliedFilter.value.kind === "enum" && appliedFilter.value.value === option.value);
|
|
231
|
+
}
|
|
232
|
+
if (config.kind === "folder") {
|
|
233
|
+
return appliedFilters.some((appliedFilter) => appliedFilter.key === config.key && appliedFilter.value.kind === "folder" && appliedFilter.value.folderId === option.value);
|
|
234
|
+
}
|
|
235
|
+
return false;
|
|
237
236
|
}
|
|
238
237
|
function getAppliedPresenceValue(config, appliedFilters) {
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
appliedFilter.value.kind === "presence");
|
|
242
|
-
return presenceFilter?.value.kind === "presence"
|
|
243
|
-
? presenceFilter.value.value
|
|
244
|
-
: null;
|
|
238
|
+
const presenceFilter = appliedFilters.find((appliedFilter) => appliedFilter.key === config.key && !appliedFilter.negated && appliedFilter.value.kind === "presence");
|
|
239
|
+
return presenceFilter?.value.kind === "presence" ? presenceFilter.value.value : null;
|
|
245
240
|
}
|
|
246
241
|
function isSelectableValueCompatibleWithPresence(config, option, appliedFilters) {
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
242
|
+
const presenceValue = getAppliedPresenceValue(config, appliedFilters);
|
|
243
|
+
if (presenceValue === "noValue") {
|
|
244
|
+
return false;
|
|
245
|
+
}
|
|
246
|
+
if (config.kind !== "folder") {
|
|
247
|
+
return true;
|
|
248
|
+
}
|
|
249
|
+
if (presenceValue === "hasValue") {
|
|
250
|
+
return option.value !== UNASSIGNED_FOLDER_FILTER_VALUE;
|
|
251
|
+
}
|
|
252
|
+
return true;
|
|
258
253
|
}
|
|
259
254
|
function buildValueSuggestions(config, valuePart, negated, appliedFilters) {
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
return {
|
|
281
|
-
caretOffset: option.caretOffset,
|
|
282
|
-
group: "value",
|
|
283
|
-
icon: getQualifierIcon(config),
|
|
284
|
-
id: `${OPTION_ID_PREFIX}-value-${config.key}-${option.name ?? option.slug}`,
|
|
285
|
-
insertText,
|
|
286
|
-
keepOpen,
|
|
287
|
-
label: option.label,
|
|
288
|
-
};
|
|
289
|
-
});
|
|
290
|
-
// El bloque universal (No tiene / Tiene / Excluir) encabeza las sugerencias al
|
|
291
|
-
// entrar al filtro (valor vacío) y solo en tokens no negados: dentro de
|
|
292
|
-
// `-clave:` el usuario ya excluye y elige directamente el valor a excluir.
|
|
293
|
-
if (negated || valuePart.length > 0) {
|
|
294
|
-
return valueSuggestions;
|
|
295
|
-
}
|
|
296
|
-
return [
|
|
297
|
-
...buildPresenceAndExcludeSuggestions(config, appliedFilters),
|
|
298
|
-
...valueSuggestions,
|
|
299
|
-
];
|
|
255
|
+
const defaultKeepOpen = config.kind === "numberRange";
|
|
256
|
+
const sourceOptions = config.kind === "textMatch" && valuePart !== "" ? [] : getValueSuggestionSource(config);
|
|
257
|
+
const filterValuePart = config.kind === "enum" || config.kind === "folder" ? valuePart.replace(/^@/, "") : valuePart;
|
|
258
|
+
const valueSuggestions = sourceOptions.filter((option) => !hasSelectableValueAlreadyApplied(config, option, appliedFilters) && isSelectableValueCompatibleWithPresence(config, option, appliedFilters)).filter((option) => startsWithNormalized(option.slug, filterValuePart)).map((option) => {
|
|
259
|
+
const keepOpen = option.keepOpen ?? defaultKeepOpen;
|
|
260
|
+
const insertText = option.insertText ?? (keepOpen ? option.slug : `${option.slug} `);
|
|
261
|
+
return {
|
|
262
|
+
caretOffset: option.caretOffset,
|
|
263
|
+
group: "value",
|
|
264
|
+
icon: getQualifierIcon(config),
|
|
265
|
+
id: `${OPTION_ID_PREFIX}-value-${config.key}-${option.name ?? option.slug}`,
|
|
266
|
+
insertText,
|
|
267
|
+
keepOpen,
|
|
268
|
+
label: option.label
|
|
269
|
+
};
|
|
270
|
+
});
|
|
271
|
+
if (negated || valuePart.length > 0) {
|
|
272
|
+
return valueSuggestions;
|
|
273
|
+
}
|
|
274
|
+
return [...buildPresenceAndExcludeSuggestions(config, appliedFilters), ...valueSuggestions];
|
|
300
275
|
}
|
|
301
276
|
function resolveConfigByKey(configs, rawKey) {
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
277
|
+
const normalized = normalizeFilterSlug(rawKey);
|
|
278
|
+
return configs.find((config) => {
|
|
279
|
+
if (config.kind === "text" || !config.key) {
|
|
280
|
+
return false;
|
|
281
|
+
}
|
|
282
|
+
if (normalizeFilterSlug(config.key) === normalized) {
|
|
283
|
+
return true;
|
|
284
|
+
}
|
|
285
|
+
return (config.aliases ?? []).some((alias) => normalizeFilterSlug(alias) === normalized);
|
|
286
|
+
});
|
|
312
287
|
}
|
|
313
288
|
/**
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
289
|
+
* Parte la query en nodos para el overlay de resaltado: los rangos de valores
|
|
290
|
+
* válidos se pintan con color de acento; el resto queda con el color normal.
|
|
291
|
+
*/
|
|
317
292
|
function renderHighlightedQuery(value, ranges) {
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
293
|
+
if (ranges.length === 0) {
|
|
294
|
+
return value;
|
|
295
|
+
}
|
|
296
|
+
const nodes = [];
|
|
297
|
+
let cursor = 0;
|
|
298
|
+
ranges.forEach((range, index) => {
|
|
299
|
+
if (range.start > cursor) {
|
|
300
|
+
nodes.push(value.slice(cursor, range.start));
|
|
301
|
+
}
|
|
302
|
+
nodes.push(/* @__PURE__ */ _jsx("span", {
|
|
303
|
+
className: "text-primary",
|
|
304
|
+
children: value.slice(range.start, range.end)
|
|
305
|
+
}, `highlight-${index}`));
|
|
306
|
+
cursor = range.end;
|
|
307
|
+
});
|
|
308
|
+
if (cursor < value.length) {
|
|
309
|
+
nodes.push(value.slice(cursor));
|
|
310
|
+
}
|
|
311
|
+
return nodes;
|
|
334
312
|
}
|
|
335
313
|
/**
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
export function FilterQueryBar(
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
314
|
+
* Barra de filtro estilo GitHub Issues: input único con autocompletado de
|
|
315
|
+
* `clave:valor`. Sugiere primero los campos disponibles y luego los valores de
|
|
316
|
+
* cada campo, con navegación por teclado y semántica ARIA de combobox/listbox.
|
|
317
|
+
* La navegación es virtual: el foco real nunca abandona el input.
|
|
318
|
+
*/
|
|
319
|
+
export function FilterQueryBar(t0) {
|
|
320
|
+
const $ = _c(97);
|
|
321
|
+
const { configs, value, onValueChange, placeholder: t1, ariaLabel: t2, className, onFocusChange, trailingAction } = t0;
|
|
322
|
+
const placeholder = t1 === undefined ? DEFAULT_PLACEHOLDER : t1;
|
|
323
|
+
const ariaLabel = t2 === undefined ? DEFAULT_ARIA_LABEL : t2;
|
|
324
|
+
const instanceId = React.useId();
|
|
325
|
+
const listboxId = `${instanceId}-${LISTBOX_ID}`;
|
|
326
|
+
const inputRef = React.useRef(null);
|
|
327
|
+
const highlightOverlayRef = React.useRef(null);
|
|
328
|
+
const pendingCaretRef = React.useRef(null);
|
|
329
|
+
const [caretIndex, setCaretIndex] = React.useState(0);
|
|
330
|
+
const [isOpen, setIsOpen] = React.useState(false);
|
|
331
|
+
const [activeIndex, setActiveIndex] = React.useState(0);
|
|
332
|
+
const [hasNavigatedSuggestions, setHasNavigatedSuggestions] = React.useState(false);
|
|
333
|
+
let t3;
|
|
334
|
+
if ($[0] !== caretIndex || $[1] !== configs || $[2] !== value) {
|
|
335
|
+
bb0: {
|
|
336
|
+
const activeToken = getActiveFilterToken(value, caretIndex);
|
|
337
|
+
const appliedFilters = parseFilterQuery(value, configs).appliedFilters;
|
|
338
|
+
if (activeToken.mode === "key") {
|
|
339
|
+
t3 = buildKeySuggestions(configs, activeToken.keyPart, {
|
|
340
|
+
appliedFilters,
|
|
341
|
+
includeExclude: !activeToken.negated && activeToken.keyPart === "",
|
|
342
|
+
negated: activeToken.negated
|
|
343
|
+
});
|
|
344
|
+
break bb0;
|
|
345
|
+
}
|
|
346
|
+
const normalizedResolvedKey = normalizeFilterSlug(activeToken.resolvedKey ?? "");
|
|
347
|
+
if (normalizedResolvedKey === PRESENCE_HAS_META_KEY || normalizedResolvedKey === PRESENCE_NO_META_KEY) {
|
|
348
|
+
t3 = buildMetaValueSuggestions(configs, normalizedResolvedKey, activeToken.valuePart, appliedFilters);
|
|
349
|
+
break bb0;
|
|
350
|
+
}
|
|
351
|
+
const config = resolveConfigByKey(configs, activeToken.resolvedKey ?? "");
|
|
352
|
+
if (!config) {
|
|
353
|
+
let t4;
|
|
354
|
+
if ($[4] === Symbol.for("react.memo_cache_sentinel")) {
|
|
355
|
+
t4 = [];
|
|
356
|
+
$[4] = t4;
|
|
357
|
+
} else {
|
|
358
|
+
t4 = $[4];
|
|
359
|
+
}
|
|
360
|
+
t3 = t4;
|
|
361
|
+
break bb0;
|
|
362
|
+
}
|
|
363
|
+
t3 = buildValueSuggestions(config, activeToken.valuePart, activeToken.negated, appliedFilters);
|
|
364
|
+
}
|
|
365
|
+
$[0] = caretIndex;
|
|
366
|
+
$[1] = configs;
|
|
367
|
+
$[2] = value;
|
|
368
|
+
$[3] = t3;
|
|
369
|
+
} else {
|
|
370
|
+
t3 = $[3];
|
|
371
|
+
}
|
|
372
|
+
const suggestions = t3;
|
|
373
|
+
let t4;
|
|
374
|
+
if ($[5] !== configs || $[6] !== value) {
|
|
375
|
+
t4 = parseFilterQuery(value, configs);
|
|
376
|
+
$[5] = configs;
|
|
377
|
+
$[6] = value;
|
|
378
|
+
$[7] = t4;
|
|
379
|
+
} else {
|
|
380
|
+
t4 = $[7];
|
|
381
|
+
}
|
|
382
|
+
const invalidTokenCount = t4.invalidTokens.length;
|
|
383
|
+
let t5;
|
|
384
|
+
if ($[8] !== configs || $[9] !== value) {
|
|
385
|
+
t5 = getValueHighlightRanges(value, configs);
|
|
386
|
+
$[8] = configs;
|
|
387
|
+
$[9] = value;
|
|
388
|
+
$[10] = t5;
|
|
389
|
+
} else {
|
|
390
|
+
t5 = $[10];
|
|
391
|
+
}
|
|
392
|
+
const highlightRanges = t5;
|
|
393
|
+
let t6;
|
|
394
|
+
if ($[11] === Symbol.for("react.memo_cache_sentinel")) {
|
|
395
|
+
t6 = () => {
|
|
396
|
+
if (highlightOverlayRef.current && inputRef.current) {
|
|
397
|
+
highlightOverlayRef.current.scrollLeft = inputRef.current.scrollLeft;
|
|
398
|
+
}
|
|
399
|
+
};
|
|
400
|
+
$[11] = t6;
|
|
401
|
+
} else {
|
|
402
|
+
t6 = $[11];
|
|
403
|
+
}
|
|
404
|
+
const syncOverlayScroll = t6;
|
|
405
|
+
let t7;
|
|
406
|
+
if ($[12] !== suggestions.length) {
|
|
407
|
+
t7 = () => {
|
|
408
|
+
setActiveIndex((previousIndex) => previousIndex < suggestions.length ? previousIndex : 0);
|
|
409
|
+
};
|
|
410
|
+
$[12] = suggestions.length;
|
|
411
|
+
$[13] = t7;
|
|
412
|
+
} else {
|
|
413
|
+
t7 = $[13];
|
|
414
|
+
}
|
|
415
|
+
let t8;
|
|
416
|
+
if ($[14] !== suggestions) {
|
|
417
|
+
t8 = [suggestions];
|
|
418
|
+
$[14] = suggestions;
|
|
419
|
+
$[15] = t8;
|
|
420
|
+
} else {
|
|
421
|
+
t8 = $[15];
|
|
422
|
+
}
|
|
423
|
+
React.useEffect(t7, t8);
|
|
424
|
+
let t9;
|
|
425
|
+
if ($[16] === Symbol.for("react.memo_cache_sentinel")) {
|
|
426
|
+
t9 = () => {
|
|
427
|
+
const pendingCaret = pendingCaretRef.current;
|
|
428
|
+
if (pendingCaret == null || !inputRef.current) {
|
|
429
|
+
return;
|
|
430
|
+
}
|
|
431
|
+
inputRef.current.setSelectionRange(pendingCaret, pendingCaret);
|
|
432
|
+
setCaretIndex(pendingCaret);
|
|
433
|
+
pendingCaretRef.current = null;
|
|
434
|
+
};
|
|
435
|
+
$[16] = t9;
|
|
436
|
+
} else {
|
|
437
|
+
t9 = $[16];
|
|
438
|
+
}
|
|
439
|
+
let t10;
|
|
440
|
+
if ($[17] !== value) {
|
|
441
|
+
t10 = [value];
|
|
442
|
+
$[17] = value;
|
|
443
|
+
$[18] = t10;
|
|
444
|
+
} else {
|
|
445
|
+
t10 = $[18];
|
|
446
|
+
}
|
|
447
|
+
React.useLayoutEffect(t9, t10);
|
|
448
|
+
let t11;
|
|
449
|
+
if ($[19] === Symbol.for("react.memo_cache_sentinel")) {
|
|
450
|
+
t11 = () => {
|
|
451
|
+
syncOverlayScroll();
|
|
452
|
+
};
|
|
453
|
+
$[19] = t11;
|
|
454
|
+
} else {
|
|
455
|
+
t11 = $[19];
|
|
456
|
+
}
|
|
457
|
+
let t12;
|
|
458
|
+
if ($[20] !== value) {
|
|
459
|
+
t12 = [syncOverlayScroll, value];
|
|
460
|
+
$[20] = value;
|
|
461
|
+
$[21] = t12;
|
|
462
|
+
} else {
|
|
463
|
+
t12 = $[21];
|
|
464
|
+
}
|
|
465
|
+
React.useLayoutEffect(t11, t12);
|
|
466
|
+
const isPopoverOpen = isOpen && suggestions.length > 0;
|
|
467
|
+
const activeSuggestion = isPopoverOpen ? suggestions[activeIndex] : undefined;
|
|
468
|
+
let t13;
|
|
469
|
+
if ($[22] === Symbol.for("react.memo_cache_sentinel")) {
|
|
470
|
+
t13 = () => {
|
|
471
|
+
if (inputRef.current) {
|
|
472
|
+
setCaretIndex(inputRef.current.selectionStart ?? 0);
|
|
473
|
+
}
|
|
474
|
+
};
|
|
475
|
+
$[22] = t13;
|
|
476
|
+
} else {
|
|
477
|
+
t13 = $[22];
|
|
478
|
+
}
|
|
479
|
+
const syncCaretFromInput = t13;
|
|
480
|
+
let t14;
|
|
481
|
+
if ($[23] !== caretIndex || $[24] !== onValueChange || $[25] !== value) {
|
|
482
|
+
t14 = (suggestion) => {
|
|
483
|
+
const activeToken_0 = getActiveFilterToken(value, inputRef.current?.selectionStart ?? caretIndex);
|
|
484
|
+
const replaceStart = suggestion.replaceTokenStart ? activeToken_0.tokenStart : activeToken_0.replaceStart;
|
|
485
|
+
const before = value.slice(0, replaceStart);
|
|
486
|
+
const after = value.slice(activeToken_0.replaceEnd);
|
|
487
|
+
const nextValue = before + suggestion.insertText + after;
|
|
488
|
+
pendingCaretRef.current = before.length + (suggestion.caretOffset ?? suggestion.insertText.length);
|
|
489
|
+
onValueChange(nextValue);
|
|
490
|
+
setIsOpen(true);
|
|
491
|
+
setActiveIndex(0);
|
|
492
|
+
setHasNavigatedSuggestions(false);
|
|
493
|
+
if (!suggestion.keepOpen) {
|
|
494
|
+
setIsOpen(false);
|
|
495
|
+
}
|
|
496
|
+
};
|
|
497
|
+
$[23] = caretIndex;
|
|
498
|
+
$[24] = onValueChange;
|
|
499
|
+
$[25] = value;
|
|
500
|
+
$[26] = t14;
|
|
501
|
+
} else {
|
|
502
|
+
t14 = $[26];
|
|
503
|
+
}
|
|
504
|
+
const applySuggestion = t14;
|
|
505
|
+
let t15;
|
|
506
|
+
if ($[27] !== activeSuggestion || $[28] !== applySuggestion || $[29] !== hasNavigatedSuggestions || $[30] !== isPopoverOpen || $[31] !== suggestions.length) {
|
|
507
|
+
t15 = (event) => {
|
|
508
|
+
if (event.key === "ArrowDown") {
|
|
509
|
+
event.preventDefault();
|
|
510
|
+
setHasNavigatedSuggestions(true);
|
|
511
|
+
if (!isPopoverOpen) {
|
|
512
|
+
setIsOpen(true);
|
|
513
|
+
return;
|
|
514
|
+
}
|
|
515
|
+
setActiveIndex((previousIndex_0) => suggestions.length === 0 ? 0 : (previousIndex_0 + 1) % suggestions.length);
|
|
516
|
+
return;
|
|
517
|
+
}
|
|
518
|
+
if (event.key === "ArrowUp") {
|
|
519
|
+
event.preventDefault();
|
|
520
|
+
setHasNavigatedSuggestions(true);
|
|
521
|
+
if (!isPopoverOpen) {
|
|
522
|
+
setIsOpen(true);
|
|
523
|
+
return;
|
|
524
|
+
}
|
|
525
|
+
setActiveIndex((previousIndex_1) => suggestions.length === 0 ? 0 : (previousIndex_1 - 1 + suggestions.length) % suggestions.length);
|
|
526
|
+
return;
|
|
527
|
+
}
|
|
528
|
+
if (event.key === "Enter" && activeSuggestion) {
|
|
529
|
+
event.preventDefault();
|
|
530
|
+
applySuggestion(activeSuggestion);
|
|
531
|
+
return;
|
|
532
|
+
}
|
|
533
|
+
if (event.key === "Tab" && hasNavigatedSuggestions && activeSuggestion) {
|
|
534
|
+
event.preventDefault();
|
|
535
|
+
applySuggestion(activeSuggestion);
|
|
536
|
+
return;
|
|
537
|
+
}
|
|
538
|
+
if (event.key === "Escape" && isPopoverOpen) {
|
|
539
|
+
event.preventDefault();
|
|
540
|
+
event.stopPropagation();
|
|
541
|
+
setIsOpen(false);
|
|
542
|
+
}
|
|
543
|
+
};
|
|
544
|
+
$[27] = activeSuggestion;
|
|
545
|
+
$[28] = applySuggestion;
|
|
546
|
+
$[29] = hasNavigatedSuggestions;
|
|
547
|
+
$[30] = isPopoverOpen;
|
|
548
|
+
$[31] = suggestions.length;
|
|
549
|
+
$[32] = t15;
|
|
550
|
+
} else {
|
|
551
|
+
t15 = $[32];
|
|
552
|
+
}
|
|
553
|
+
const handleKeyDown = t15;
|
|
554
|
+
let t16;
|
|
555
|
+
if ($[33] !== onValueChange) {
|
|
556
|
+
t16 = () => {
|
|
557
|
+
onValueChange("");
|
|
558
|
+
pendingCaretRef.current = 0;
|
|
559
|
+
setIsOpen(false);
|
|
560
|
+
inputRef.current?.focus();
|
|
561
|
+
};
|
|
562
|
+
$[33] = onValueChange;
|
|
563
|
+
$[34] = t16;
|
|
564
|
+
} else {
|
|
565
|
+
t16 = $[34];
|
|
566
|
+
}
|
|
567
|
+
const handleClear = t16;
|
|
568
|
+
let t17;
|
|
569
|
+
if ($[35] !== className) {
|
|
570
|
+
t17 = cn("grid w-full gap-2", className);
|
|
571
|
+
$[35] = className;
|
|
572
|
+
$[36] = t17;
|
|
573
|
+
} else {
|
|
574
|
+
t17 = $[36];
|
|
575
|
+
}
|
|
576
|
+
const t18 = activeSuggestion ? `${instanceId}-${activeSuggestion.id}` : undefined;
|
|
577
|
+
const t19 = trailingAction ? "pr-16" : "pr-9";
|
|
578
|
+
let t20;
|
|
579
|
+
if ($[37] !== t19) {
|
|
580
|
+
t20 = cn("w-full text-transparent", t19);
|
|
581
|
+
$[37] = t19;
|
|
582
|
+
$[38] = t20;
|
|
583
|
+
} else {
|
|
584
|
+
t20 = $[38];
|
|
585
|
+
}
|
|
586
|
+
let t21;
|
|
587
|
+
if ($[39] !== onValueChange) {
|
|
588
|
+
t21 = (event_0) => {
|
|
589
|
+
onValueChange(event_0.target.value);
|
|
590
|
+
setIsOpen(true);
|
|
591
|
+
setActiveIndex(0);
|
|
592
|
+
setHasNavigatedSuggestions(false);
|
|
593
|
+
setCaretIndex(event_0.target.selectionStart ?? event_0.target.value.length);
|
|
594
|
+
};
|
|
595
|
+
$[39] = onValueChange;
|
|
596
|
+
$[40] = t21;
|
|
597
|
+
} else {
|
|
598
|
+
t21 = $[40];
|
|
599
|
+
}
|
|
600
|
+
let t22;
|
|
601
|
+
let t23;
|
|
602
|
+
if ($[41] !== onFocusChange) {
|
|
603
|
+
t22 = () => {
|
|
604
|
+
setHasNavigatedSuggestions(false);
|
|
605
|
+
onFocusChange?.(false);
|
|
606
|
+
};
|
|
607
|
+
t23 = () => {
|
|
608
|
+
syncCaretFromInput();
|
|
609
|
+
setIsOpen(true);
|
|
610
|
+
onFocusChange?.(true);
|
|
611
|
+
};
|
|
612
|
+
$[41] = onFocusChange;
|
|
613
|
+
$[42] = t22;
|
|
614
|
+
$[43] = t23;
|
|
615
|
+
} else {
|
|
616
|
+
t22 = $[42];
|
|
617
|
+
t23 = $[43];
|
|
618
|
+
}
|
|
619
|
+
let t24;
|
|
620
|
+
if ($[44] === Symbol.for("react.memo_cache_sentinel")) {
|
|
621
|
+
t24 = { caretColor: "var(--foreground)" };
|
|
622
|
+
$[44] = t24;
|
|
623
|
+
} else {
|
|
624
|
+
t24 = $[44];
|
|
625
|
+
}
|
|
626
|
+
let t25;
|
|
627
|
+
if ($[45] !== ariaLabel || $[46] !== handleKeyDown || $[47] !== isPopoverOpen || $[48] !== listboxId || $[49] !== placeholder || $[50] !== t18 || $[51] !== t20 || $[52] !== t21 || $[53] !== t22 || $[54] !== t23 || $[55] !== value) {
|
|
628
|
+
t25 = /* @__PURE__ */ _jsx(Input, {
|
|
629
|
+
"aria-activedescendant": t18,
|
|
630
|
+
"aria-autocomplete": "list",
|
|
631
|
+
"aria-controls": listboxId,
|
|
632
|
+
"aria-expanded": isPopoverOpen,
|
|
633
|
+
"aria-label": ariaLabel,
|
|
634
|
+
autoComplete: "off",
|
|
635
|
+
className: t20,
|
|
636
|
+
onChange: t21,
|
|
637
|
+
onClick: syncCaretFromInput,
|
|
638
|
+
onBlur: t22,
|
|
639
|
+
onFocus: t23,
|
|
640
|
+
onKeyDown: handleKeyDown,
|
|
641
|
+
onKeyUp: syncCaretFromInput,
|
|
642
|
+
onScroll: syncOverlayScroll,
|
|
643
|
+
placeholder,
|
|
644
|
+
ref: inputRef,
|
|
645
|
+
role: "combobox",
|
|
646
|
+
style: t24,
|
|
647
|
+
type: "text",
|
|
648
|
+
value
|
|
649
|
+
});
|
|
650
|
+
$[45] = ariaLabel;
|
|
651
|
+
$[46] = handleKeyDown;
|
|
652
|
+
$[47] = isPopoverOpen;
|
|
653
|
+
$[48] = listboxId;
|
|
654
|
+
$[49] = placeholder;
|
|
655
|
+
$[50] = t18;
|
|
656
|
+
$[51] = t20;
|
|
657
|
+
$[52] = t21;
|
|
658
|
+
$[53] = t22;
|
|
659
|
+
$[54] = t23;
|
|
660
|
+
$[55] = value;
|
|
661
|
+
$[56] = t25;
|
|
662
|
+
} else {
|
|
663
|
+
t25 = $[56];
|
|
664
|
+
}
|
|
665
|
+
const t26 = trailingAction ? "pr-16" : "pr-9";
|
|
666
|
+
let t27;
|
|
667
|
+
if ($[57] !== t26) {
|
|
668
|
+
t27 = cn("pointer-events-none absolute inset-0 flex items-center overflow-hidden rounded-lg border border-transparent px-2.5 text-base text-foreground select-none md:text-sm", t26);
|
|
669
|
+
$[57] = t26;
|
|
670
|
+
$[58] = t27;
|
|
671
|
+
} else {
|
|
672
|
+
t27 = $[58];
|
|
673
|
+
}
|
|
674
|
+
let t28;
|
|
675
|
+
if ($[59] !== highlightRanges || $[60] !== value) {
|
|
676
|
+
t28 = renderHighlightedQuery(value, highlightRanges);
|
|
677
|
+
$[59] = highlightRanges;
|
|
678
|
+
$[60] = value;
|
|
679
|
+
$[61] = t28;
|
|
680
|
+
} else {
|
|
681
|
+
t28 = $[61];
|
|
682
|
+
}
|
|
683
|
+
let t29;
|
|
684
|
+
if ($[62] !== t28) {
|
|
685
|
+
t29 = /* @__PURE__ */ _jsx("span", {
|
|
686
|
+
className: "whitespace-pre",
|
|
687
|
+
children: t28
|
|
688
|
+
});
|
|
689
|
+
$[62] = t28;
|
|
690
|
+
$[63] = t29;
|
|
691
|
+
} else {
|
|
692
|
+
t29 = $[63];
|
|
693
|
+
}
|
|
694
|
+
let t30;
|
|
695
|
+
if ($[64] !== t27 || $[65] !== t29) {
|
|
696
|
+
t30 = /* @__PURE__ */ _jsx("div", {
|
|
697
|
+
"aria-hidden": "true",
|
|
698
|
+
className: t27,
|
|
699
|
+
ref: highlightOverlayRef,
|
|
700
|
+
children: t29
|
|
701
|
+
});
|
|
702
|
+
$[64] = t27;
|
|
703
|
+
$[65] = t29;
|
|
704
|
+
$[66] = t30;
|
|
705
|
+
} else {
|
|
706
|
+
t30 = $[66];
|
|
707
|
+
}
|
|
708
|
+
let t31;
|
|
709
|
+
if ($[67] !== handleClear || $[68] !== value) {
|
|
710
|
+
t31 = value ? /* @__PURE__ */ _jsx(Button, {
|
|
711
|
+
"aria-label": CLEAR_FILTER_ARIA_LABEL,
|
|
712
|
+
className: "active:-translate-y-0",
|
|
713
|
+
onClick: handleClear,
|
|
714
|
+
size: "icon-xs",
|
|
715
|
+
type: "button",
|
|
716
|
+
variant: "ghost",
|
|
717
|
+
children: /* @__PURE__ */ _jsx(X, { "aria-hidden": "true" })
|
|
718
|
+
}) : null;
|
|
719
|
+
$[67] = handleClear;
|
|
720
|
+
$[68] = value;
|
|
721
|
+
$[69] = t31;
|
|
722
|
+
} else {
|
|
723
|
+
t31 = $[69];
|
|
724
|
+
}
|
|
725
|
+
let t32;
|
|
726
|
+
if ($[70] !== t31 || $[71] !== trailingAction) {
|
|
727
|
+
t32 = /* @__PURE__ */ _jsxs("div", {
|
|
728
|
+
className: "absolute right-1 top-1/2 flex -translate-y-1/2 items-center gap-0.5",
|
|
729
|
+
children: [t31, trailingAction]
|
|
730
|
+
});
|
|
731
|
+
$[70] = t31;
|
|
732
|
+
$[71] = trailingAction;
|
|
733
|
+
$[72] = t32;
|
|
734
|
+
} else {
|
|
735
|
+
t32 = $[72];
|
|
736
|
+
}
|
|
737
|
+
let t33;
|
|
738
|
+
if ($[73] !== t25 || $[74] !== t30 || $[75] !== t32) {
|
|
739
|
+
t33 = /* @__PURE__ */ _jsx(PopoverAnchor, {
|
|
740
|
+
asChild: true,
|
|
741
|
+
children: /* @__PURE__ */ _jsxs("div", {
|
|
742
|
+
className: "relative w-full",
|
|
743
|
+
children: [
|
|
744
|
+
t25,
|
|
745
|
+
t30,
|
|
746
|
+
t32
|
|
747
|
+
]
|
|
748
|
+
})
|
|
749
|
+
});
|
|
750
|
+
$[73] = t25;
|
|
751
|
+
$[74] = t30;
|
|
752
|
+
$[75] = t32;
|
|
753
|
+
$[76] = t33;
|
|
754
|
+
} else {
|
|
755
|
+
t33 = $[76];
|
|
756
|
+
}
|
|
757
|
+
const t34 = suggestions.some(_temp3) ? VALUE_GROUP_LABEL : KEY_GROUP_LABEL;
|
|
758
|
+
let t35;
|
|
759
|
+
if ($[77] !== activeIndex || $[78] !== applySuggestion || $[79] !== instanceId || $[80] !== suggestions) {
|
|
760
|
+
t35 = suggestions.map((suggestion_1, index) => {
|
|
761
|
+
const SuggestionIcon = suggestion_1.icon;
|
|
762
|
+
const showSeparator = index > 0 && suggestions[index - 1].group !== suggestion_1.group;
|
|
763
|
+
return /* @__PURE__ */ _jsxs(React.Fragment, { children: [showSeparator ? /* @__PURE__ */ _jsx("li", {
|
|
764
|
+
"aria-hidden": "true",
|
|
765
|
+
className: "my-1 border-t border-border",
|
|
766
|
+
role: "presentation"
|
|
767
|
+
}) : null, /* @__PURE__ */ _jsxs("li", {
|
|
768
|
+
"aria-selected": index === activeIndex,
|
|
769
|
+
className: cn("flex cursor-pointer items-center gap-2 rounded-md px-2 py-1.5 text-sm", index === activeIndex ? "bg-accent text-accent-foreground" : "text-foreground"),
|
|
770
|
+
id: `${instanceId}-${suggestion_1.id}`,
|
|
771
|
+
onMouseDown: (event_3) => {
|
|
772
|
+
event_3.preventDefault();
|
|
773
|
+
applySuggestion(suggestion_1);
|
|
774
|
+
},
|
|
775
|
+
role: "option",
|
|
776
|
+
children: [/* @__PURE__ */ _jsx(SuggestionIcon, {
|
|
777
|
+
"aria-hidden": "true",
|
|
778
|
+
className: "size-4 shrink-0 text-muted-foreground"
|
|
779
|
+
}), /* @__PURE__ */ _jsx("span", {
|
|
780
|
+
className: "truncate",
|
|
781
|
+
children: suggestion_1.label
|
|
782
|
+
})]
|
|
783
|
+
})] }, suggestion_1.id);
|
|
784
|
+
});
|
|
785
|
+
$[77] = activeIndex;
|
|
786
|
+
$[78] = applySuggestion;
|
|
787
|
+
$[79] = instanceId;
|
|
788
|
+
$[80] = suggestions;
|
|
789
|
+
$[81] = t35;
|
|
790
|
+
} else {
|
|
791
|
+
t35 = $[81];
|
|
792
|
+
}
|
|
793
|
+
let t36;
|
|
794
|
+
if ($[82] !== listboxId || $[83] !== t34 || $[84] !== t35) {
|
|
795
|
+
t36 = /* @__PURE__ */ _jsx(PopoverContent, {
|
|
796
|
+
align: "start",
|
|
797
|
+
className: "w-[250px] max-h-[280px] gap-0 overflow-y-auto p-1",
|
|
798
|
+
onCloseAutoFocus: _temp,
|
|
799
|
+
onOpenAutoFocus: _temp2,
|
|
800
|
+
children: /* @__PURE__ */ _jsx("ul", {
|
|
801
|
+
"aria-label": t34,
|
|
802
|
+
className: "grid gap-0.5",
|
|
803
|
+
id: listboxId,
|
|
804
|
+
role: "listbox",
|
|
805
|
+
children: t35
|
|
806
|
+
})
|
|
807
|
+
});
|
|
808
|
+
$[82] = listboxId;
|
|
809
|
+
$[83] = t34;
|
|
810
|
+
$[84] = t35;
|
|
811
|
+
$[85] = t36;
|
|
812
|
+
} else {
|
|
813
|
+
t36 = $[85];
|
|
814
|
+
}
|
|
815
|
+
let t37;
|
|
816
|
+
if ($[86] !== isPopoverOpen || $[87] !== t33 || $[88] !== t36) {
|
|
817
|
+
t37 = /* @__PURE__ */ _jsxs(Popover, {
|
|
818
|
+
onOpenChange: setIsOpen,
|
|
819
|
+
open: isPopoverOpen,
|
|
820
|
+
children: [t33, t36]
|
|
821
|
+
});
|
|
822
|
+
$[86] = isPopoverOpen;
|
|
823
|
+
$[87] = t33;
|
|
824
|
+
$[88] = t36;
|
|
825
|
+
$[89] = t37;
|
|
826
|
+
} else {
|
|
827
|
+
t37 = $[89];
|
|
828
|
+
}
|
|
829
|
+
const t38 = isPopoverOpen ? `${suggestions.length} sugerencias disponibles` : "";
|
|
830
|
+
const t39 = invalidTokenCount > 0 ? ` ${invalidTokenCount} filtros no aplicados` : "";
|
|
831
|
+
let t40;
|
|
832
|
+
if ($[90] !== t38 || $[91] !== t39) {
|
|
833
|
+
t40 = /* @__PURE__ */ _jsxs("span", {
|
|
834
|
+
"aria-live": "polite",
|
|
835
|
+
className: "sr-only",
|
|
836
|
+
children: [t38, t39]
|
|
837
|
+
});
|
|
838
|
+
$[90] = t38;
|
|
839
|
+
$[91] = t39;
|
|
840
|
+
$[92] = t40;
|
|
841
|
+
} else {
|
|
842
|
+
t40 = $[92];
|
|
843
|
+
}
|
|
844
|
+
let t41;
|
|
845
|
+
if ($[93] !== t17 || $[94] !== t37 || $[95] !== t40) {
|
|
846
|
+
t41 = /* @__PURE__ */ _jsxs("div", {
|
|
847
|
+
className: t17,
|
|
848
|
+
children: [t37, t40]
|
|
849
|
+
});
|
|
850
|
+
$[93] = t17;
|
|
851
|
+
$[94] = t37;
|
|
852
|
+
$[95] = t40;
|
|
853
|
+
$[96] = t41;
|
|
854
|
+
} else {
|
|
855
|
+
t41 = $[96];
|
|
856
|
+
}
|
|
857
|
+
return t41;
|
|
858
|
+
}
|
|
859
|
+
function _temp3(suggestion_0) {
|
|
860
|
+
return suggestion_0.group === "value";
|
|
861
|
+
}
|
|
862
|
+
function _temp2(event_2) {
|
|
863
|
+
return event_2.preventDefault();
|
|
864
|
+
}
|
|
865
|
+
function _temp(event_1) {
|
|
866
|
+
return event_1.preventDefault();
|
|
526
867
|
}
|