@clyrex-digital/clyrex-controls-dev 0.8.1-dev.20260924080906 → 0.8.1-dev.20260924115534
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/DataBindingControls-5H5K5GVR.mjs +477 -0
- package/dist/DataBindingControls-G5TRSVEU.mjs +481 -0
- package/dist/{Slider-JZ5CNHEW.mjs → Slider-42T6THEQ.mjs} +19 -7
- package/dist/{Slider-3JMZZWGT.mjs → Slider-UNNVADVP.mjs} +19 -7
- package/dist/index.js +254 -142
- package/dist/index.mjs +3 -3
- package/dist/server.js +254 -142
- package/dist/server.mjs +3 -3
- package/package.json +1 -1
- package/dist/DataBindingControls-SLNZLI3I.mjs +0 -377
- package/dist/DataBindingControls-UDRT7JFF.mjs +0 -381
|
@@ -0,0 +1,481 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import {
|
|
3
|
+
InputControlType_default
|
|
4
|
+
} from "./chunk-HRDHAIZF.mjs";
|
|
5
|
+
import {
|
|
6
|
+
Button_default
|
|
7
|
+
} from "./chunk-4WMSS6CE.mjs";
|
|
8
|
+
import "./chunk-56HSDML5.mjs";
|
|
9
|
+
|
|
10
|
+
// src/components/pageRenderingEngine/nodes/DataBindingControls.tsx
|
|
11
|
+
import { useCallback, useEffect, useMemo, useState } from "react";
|
|
12
|
+
import { useRouter, useSearchParams } from "next/navigation";
|
|
13
|
+
|
|
14
|
+
// src/components/controls/edit/InputControl.tsx
|
|
15
|
+
import dynamic from "next/dynamic";
|
|
16
|
+
var InputControl = dynamic(() => import("./InputControlClient-NHXG4QBU.mjs"), {
|
|
17
|
+
ssr: false
|
|
18
|
+
});
|
|
19
|
+
var InputControl_default = InputControl;
|
|
20
|
+
|
|
21
|
+
// src/components/pageRenderingEngine/nodes/DataBindingControls.tsx
|
|
22
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
23
|
+
var humanize = (value) => value.replace(/([a-z0-9])([A-Z])/g, "$1 $2").replace(/[_-]+/g, " ").trim();
|
|
24
|
+
var escapeODataString = (value) => value.replace(/'/g, "''");
|
|
25
|
+
var parseFacetSelections = (filter) => {
|
|
26
|
+
const selections = /* @__PURE__ */ new Map();
|
|
27
|
+
if (!filter || !filter.trim()) return selections;
|
|
28
|
+
const expression = /(?:^|[\s()]+(?:and[\s()]+)?)([\w./-]+)\s+eq\s+'((?:''|[^'])*)'/gi;
|
|
29
|
+
for (const match of filter.matchAll(expression)) {
|
|
30
|
+
if (match[1] && match[2] !== void 0) {
|
|
31
|
+
selections.set(match[1].trim(), match[2].replace(/''/g, "'"));
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
return selections;
|
|
35
|
+
};
|
|
36
|
+
var buildFacetFilter = (selections) => Array.from(selections.entries()).map(([field, value]) => `${field} eq '${escapeODataString(value)}'`).join(" and ");
|
|
37
|
+
var parseODataSearch = (value) => {
|
|
38
|
+
if (!value) return "";
|
|
39
|
+
const trimmedValue = value.trim();
|
|
40
|
+
if (trimmedValue.startsWith("'") && trimmedValue.endsWith("'")) {
|
|
41
|
+
return trimmedValue.slice(1, -1).replace(/''/g, "'");
|
|
42
|
+
}
|
|
43
|
+
return trimmedValue;
|
|
44
|
+
};
|
|
45
|
+
var SearchIcon = ({ className = "" }) => /* @__PURE__ */ jsxs(
|
|
46
|
+
"svg",
|
|
47
|
+
{
|
|
48
|
+
"aria-hidden": "true",
|
|
49
|
+
className,
|
|
50
|
+
fill: "none",
|
|
51
|
+
viewBox: "0 0 24 24",
|
|
52
|
+
stroke: "currentColor",
|
|
53
|
+
strokeWidth: "2",
|
|
54
|
+
children: [
|
|
55
|
+
/* @__PURE__ */ jsx("circle", { cx: "11", cy: "11", r: "7" }),
|
|
56
|
+
/* @__PURE__ */ jsx("path", { strokeLinecap: "round", d: "m20 20-4-4" })
|
|
57
|
+
]
|
|
58
|
+
}
|
|
59
|
+
);
|
|
60
|
+
var ResetIcon = ({ className = "" }) => /* @__PURE__ */ jsxs(
|
|
61
|
+
"svg",
|
|
62
|
+
{
|
|
63
|
+
"aria-hidden": "true",
|
|
64
|
+
className,
|
|
65
|
+
fill: "none",
|
|
66
|
+
viewBox: "0 0 24 24",
|
|
67
|
+
stroke: "currentColor",
|
|
68
|
+
strokeWidth: "2",
|
|
69
|
+
children: [
|
|
70
|
+
/* @__PURE__ */ jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M4 4v6h6" }),
|
|
71
|
+
/* @__PURE__ */ jsx(
|
|
72
|
+
"path",
|
|
73
|
+
{
|
|
74
|
+
strokeLinecap: "round",
|
|
75
|
+
strokeLinejoin: "round",
|
|
76
|
+
d: "M5.5 15a8 8 0 1 0 .6-7.8L4 10"
|
|
77
|
+
}
|
|
78
|
+
)
|
|
79
|
+
]
|
|
80
|
+
}
|
|
81
|
+
);
|
|
82
|
+
var FilterSlidersIcon = ({ className = "" }) => /* @__PURE__ */ jsxs(
|
|
83
|
+
"svg",
|
|
84
|
+
{
|
|
85
|
+
"aria-hidden": "true",
|
|
86
|
+
className,
|
|
87
|
+
fill: "none",
|
|
88
|
+
viewBox: "0 0 24 24",
|
|
89
|
+
stroke: "currentColor",
|
|
90
|
+
strokeWidth: "2",
|
|
91
|
+
children: [
|
|
92
|
+
/* @__PURE__ */ jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M3 4h18M3 12h18M3 20h18" }),
|
|
93
|
+
/* @__PURE__ */ jsx("circle", { cx: "8", cy: "4", r: "2", fill: "currentColor" }),
|
|
94
|
+
/* @__PURE__ */ jsx("circle", { cx: "16", cy: "12", r: "2", fill: "currentColor" }),
|
|
95
|
+
/* @__PURE__ */ jsx("circle", { cx: "10", cy: "20", r: "2", fill: "currentColor" })
|
|
96
|
+
]
|
|
97
|
+
}
|
|
98
|
+
);
|
|
99
|
+
var ChevronDownIcon = ({ className = "" }) => /* @__PURE__ */ jsx(
|
|
100
|
+
"svg",
|
|
101
|
+
{
|
|
102
|
+
"aria-hidden": "true",
|
|
103
|
+
className,
|
|
104
|
+
fill: "none",
|
|
105
|
+
viewBox: "0 0 24 24",
|
|
106
|
+
stroke: "currentColor",
|
|
107
|
+
strokeWidth: "2",
|
|
108
|
+
children: /* @__PURE__ */ jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "m19 9-7 7-7-7" })
|
|
109
|
+
}
|
|
110
|
+
);
|
|
111
|
+
var CheckIcon = ({ className = "" }) => /* @__PURE__ */ jsx(
|
|
112
|
+
"svg",
|
|
113
|
+
{
|
|
114
|
+
"aria-hidden": "true",
|
|
115
|
+
className,
|
|
116
|
+
fill: "none",
|
|
117
|
+
viewBox: "0 0 24 24",
|
|
118
|
+
stroke: "currentColor",
|
|
119
|
+
strokeWidth: "2.5",
|
|
120
|
+
children: /* @__PURE__ */ jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M5 13l4 4L19 7" })
|
|
121
|
+
}
|
|
122
|
+
);
|
|
123
|
+
var CloseIcon = ({ className = "" }) => /* @__PURE__ */ jsx(
|
|
124
|
+
"svg",
|
|
125
|
+
{
|
|
126
|
+
"aria-hidden": "true",
|
|
127
|
+
className,
|
|
128
|
+
fill: "none",
|
|
129
|
+
viewBox: "0 0 24 24",
|
|
130
|
+
stroke: "currentColor",
|
|
131
|
+
strokeWidth: "2",
|
|
132
|
+
children: /* @__PURE__ */ jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M6 18L18 6M6 6l12 12" })
|
|
133
|
+
}
|
|
134
|
+
);
|
|
135
|
+
var normalizeSortOption = (option) => {
|
|
136
|
+
const direction = option.direction.trim();
|
|
137
|
+
return {
|
|
138
|
+
label: option.title || humanize(option.name),
|
|
139
|
+
value: [option.name, direction].filter(Boolean).join(" ")
|
|
140
|
+
};
|
|
141
|
+
};
|
|
142
|
+
var DataBindingControls = ({
|
|
143
|
+
path,
|
|
144
|
+
query,
|
|
145
|
+
facets,
|
|
146
|
+
sortOptions,
|
|
147
|
+
showFacets,
|
|
148
|
+
showSortOptions,
|
|
149
|
+
showSearchBar,
|
|
150
|
+
mode = "toolbar"
|
|
151
|
+
}) => {
|
|
152
|
+
const router = useRouter();
|
|
153
|
+
const searchParams = useSearchParams();
|
|
154
|
+
const [collapsedCategories, setCollapsedCategories] = useState({});
|
|
155
|
+
const toggleCategory = (field) => {
|
|
156
|
+
setCollapsedCategories((prev) => ({
|
|
157
|
+
...prev,
|
|
158
|
+
[field]: !prev[field]
|
|
159
|
+
}));
|
|
160
|
+
};
|
|
161
|
+
const searchParamsFilter = searchParams?.get("$filter") ?? searchParams?.get("filter");
|
|
162
|
+
const searchParamsSort = searchParams?.get("$orderby") ?? searchParams?.get("orderBy");
|
|
163
|
+
const searchParamsSearch = searchParams?.get("$search");
|
|
164
|
+
const currentFilter = searchParamsFilter !== void 0 && searchParamsFilter !== null ? searchParamsFilter : query?.["$filter"] ?? query?.filter ?? "";
|
|
165
|
+
const currentSort = searchParamsSort !== void 0 && searchParamsSort !== null ? searchParamsSort : query?.["$orderby"] ?? query?.orderBy ?? "";
|
|
166
|
+
const currentSearch = parseODataSearch(
|
|
167
|
+
searchParamsSearch !== void 0 && searchParamsSearch !== null ? searchParamsSearch : query?.["$search"]
|
|
168
|
+
);
|
|
169
|
+
const [searchText, setSearchText] = useState(currentSearch);
|
|
170
|
+
useEffect(() => {
|
|
171
|
+
setSearchText(currentSearch);
|
|
172
|
+
}, [currentSearch]);
|
|
173
|
+
const selectedFacetValues = useMemo(
|
|
174
|
+
() => parseFacetSelections(currentFilter),
|
|
175
|
+
[currentFilter]
|
|
176
|
+
);
|
|
177
|
+
const activeFacets = useMemo(() => {
|
|
178
|
+
if (!facets) return [];
|
|
179
|
+
return Object.entries(facets).map(([field, values]) => {
|
|
180
|
+
if (!Array.isArray(values)) return null;
|
|
181
|
+
const filteredValues = values.filter(
|
|
182
|
+
(item) => item.count > 0 || selectedFacetValues.get(field) === item.value
|
|
183
|
+
);
|
|
184
|
+
if (filteredValues.length === 0) return null;
|
|
185
|
+
return [field, filteredValues];
|
|
186
|
+
}).filter((group) => group !== null);
|
|
187
|
+
}, [facets, selectedFacetValues]);
|
|
188
|
+
const normalizedSortOptions = (sortOptions ?? []).filter((option) => option?.name && option?.direction).map(normalizeSortOption).filter((option) => option.value);
|
|
189
|
+
const getQueryUrl = useCallback(
|
|
190
|
+
(updates) => {
|
|
191
|
+
const initialParams = searchParams ? searchParams.toString() : "";
|
|
192
|
+
const params = new URLSearchParams(initialParams || query || {});
|
|
193
|
+
Object.entries(updates).forEach(([key, value]) => {
|
|
194
|
+
if (value) {
|
|
195
|
+
params.set(key, value);
|
|
196
|
+
} else {
|
|
197
|
+
params.delete(key);
|
|
198
|
+
}
|
|
199
|
+
});
|
|
200
|
+
params.delete("$skip");
|
|
201
|
+
params.delete("skip");
|
|
202
|
+
const queryString = Array.from(params.entries()).map(
|
|
203
|
+
([key, value]) => key === "$filter" || key === "filter" ? `${key}=${encodeURIComponent(value)}` : `${key}=${value}`
|
|
204
|
+
).join("&");
|
|
205
|
+
return queryString ? `${path}?${queryString}` : path;
|
|
206
|
+
},
|
|
207
|
+
[path, query, searchParams]
|
|
208
|
+
);
|
|
209
|
+
const navigateWithoutReload = useCallback(
|
|
210
|
+
(url) => {
|
|
211
|
+
if (typeof window !== "undefined") {
|
|
212
|
+
const targetUrl = new URL(url, window.location.origin);
|
|
213
|
+
if (targetUrl.pathname === window.location.pathname && targetUrl.search === window.location.search) {
|
|
214
|
+
return;
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
router.push(url, { scroll: false });
|
|
218
|
+
},
|
|
219
|
+
[router]
|
|
220
|
+
);
|
|
221
|
+
const getFacetUrl = (field, value) => {
|
|
222
|
+
const updatedSelections = new Map(selectedFacetValues);
|
|
223
|
+
if (value) {
|
|
224
|
+
if (updatedSelections.get(field) === value) {
|
|
225
|
+
updatedSelections.delete(field);
|
|
226
|
+
} else {
|
|
227
|
+
updatedSelections.set(field, value);
|
|
228
|
+
}
|
|
229
|
+
} else {
|
|
230
|
+
updatedSelections.delete(field);
|
|
231
|
+
}
|
|
232
|
+
const updatedFilter = buildFacetFilter(updatedSelections);
|
|
233
|
+
return getQueryUrl({
|
|
234
|
+
$filter: updatedFilter || void 0,
|
|
235
|
+
filter: void 0
|
|
236
|
+
});
|
|
237
|
+
};
|
|
238
|
+
const clearFacetField = (field) => {
|
|
239
|
+
const updatedSelections = new Map(selectedFacetValues);
|
|
240
|
+
updatedSelections.delete(field);
|
|
241
|
+
const updatedFilter = buildFacetFilter(updatedSelections);
|
|
242
|
+
navigateWithoutReload(
|
|
243
|
+
getQueryUrl({
|
|
244
|
+
$filter: updatedFilter || void 0,
|
|
245
|
+
filter: void 0
|
|
246
|
+
})
|
|
247
|
+
);
|
|
248
|
+
};
|
|
249
|
+
const handleSearch = useCallback(async () => {
|
|
250
|
+
const trimmedSearchText = searchText.trim();
|
|
251
|
+
if (trimmedSearchText === currentSearch.trim()) {
|
|
252
|
+
return { isSuccessful: true };
|
|
253
|
+
}
|
|
254
|
+
navigateWithoutReload(
|
|
255
|
+
getQueryUrl({
|
|
256
|
+
"$search": trimmedSearchText || void 0
|
|
257
|
+
})
|
|
258
|
+
);
|
|
259
|
+
return { isSuccessful: true };
|
|
260
|
+
}, [currentSearch, getQueryUrl, navigateWithoutReload, searchText]);
|
|
261
|
+
const handleClearAll = useCallback(async () => {
|
|
262
|
+
navigateWithoutReload(
|
|
263
|
+
getQueryUrl({
|
|
264
|
+
$filter: void 0,
|
|
265
|
+
filter: void 0,
|
|
266
|
+
$orderby: void 0,
|
|
267
|
+
orderBy: void 0
|
|
268
|
+
})
|
|
269
|
+
);
|
|
270
|
+
return { isSuccessful: true };
|
|
271
|
+
}, [getQueryUrl, navigateWithoutReload]);
|
|
272
|
+
const hasFacetControls = showFacets && activeFacets.length > 0;
|
|
273
|
+
const hasSortControls = showSortOptions && normalizedSortOptions.length > 0;
|
|
274
|
+
const hasActiveFiltersOrSort = Boolean(
|
|
275
|
+
currentFilter.trim() || currentSort.trim()
|
|
276
|
+
);
|
|
277
|
+
const selectedFacetCount = selectedFacetValues.size;
|
|
278
|
+
const shouldShowToolbarClearAll = hasActiveFiltersOrSort && !hasFacetControls;
|
|
279
|
+
const shouldShowToolbar = mode === "toolbar" && (showSearchBar || hasSortControls || shouldShowToolbarClearAll);
|
|
280
|
+
const shouldShowFacets = mode === "facets" && hasFacetControls;
|
|
281
|
+
if (!shouldShowToolbar && !shouldShowFacets) {
|
|
282
|
+
return null;
|
|
283
|
+
}
|
|
284
|
+
const renderFacetItems = (field, values) => /* @__PURE__ */ jsx("div", { className: "flex flex-col gap-1 pt-1 pb-1", children: values.map((facet) => {
|
|
285
|
+
const isSelected = selectedFacetValues.get(field) === facet.value;
|
|
286
|
+
return /* @__PURE__ */ jsxs(
|
|
287
|
+
"button",
|
|
288
|
+
{
|
|
289
|
+
type: "button",
|
|
290
|
+
onClick: () => navigateWithoutReload(getFacetUrl(field, facet.value)),
|
|
291
|
+
"aria-pressed": isSelected,
|
|
292
|
+
className: `group flex w-full cursor-pointer items-center justify-between gap-2.5 rounded-md px-2 py-1.5 text-left text-sm transition-all duration-150 ease-out focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-primary-base ${isSelected ? "bg-neutral-soft font-medium border " : "hover:bg-neutral-weak border border-transparent"}`,
|
|
293
|
+
children: [
|
|
294
|
+
/* @__PURE__ */ jsxs("div", { className: "flex min-w-0 items-center gap-2.5", children: [
|
|
295
|
+
/* @__PURE__ */ jsx(
|
|
296
|
+
"span",
|
|
297
|
+
{
|
|
298
|
+
className: `flex h-4 w-4 shrink-0 items-center justify-center rounded-[3px] border transition-colors duration-150 ${isSelected ? "bg-primary-base border-primary-base" : " group-hover:border-neutral-strong bg-default"}`,
|
|
299
|
+
children: isSelected && /* @__PURE__ */ jsx(CheckIcon, { className: "h-3 w-3" })
|
|
300
|
+
}
|
|
301
|
+
),
|
|
302
|
+
/* @__PURE__ */ jsx("span", { className: "leading-snug break-words", children: facet.value })
|
|
303
|
+
] }),
|
|
304
|
+
/* @__PURE__ */ jsx(
|
|
305
|
+
"span",
|
|
306
|
+
{
|
|
307
|
+
className: `shrink-0 rounded px-1.5 py-0.5 text-xs transition-colors ml-2 ${isSelected ? "bg-neutral-weak font-semibold" : "bg-neutral-weak font-normal"}`,
|
|
308
|
+
children: facet.count
|
|
309
|
+
}
|
|
310
|
+
)
|
|
311
|
+
]
|
|
312
|
+
},
|
|
313
|
+
`${field}-${facet.value}`
|
|
314
|
+
);
|
|
315
|
+
}) });
|
|
316
|
+
return /* @__PURE__ */ jsxs(
|
|
317
|
+
"div",
|
|
318
|
+
{
|
|
319
|
+
className: mode === "toolbar" ? "my-6" : "flex flex-col rounded-md border bg-default p-3.5 shadow-sm",
|
|
320
|
+
children: [
|
|
321
|
+
shouldShowToolbar && /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-3 md:flex-row md:items-center md:justify-between", children: [
|
|
322
|
+
showSearchBar && // <form
|
|
323
|
+
// role="search"
|
|
324
|
+
// className="flex w-full flex-col gap-3 rounded-md border border-info bg-info-soft p-3 sm:flex-row sm:items-center md:min-w-0 md:flex-1"
|
|
325
|
+
// onSubmit={(event) => {
|
|
326
|
+
// event.preventDefault();
|
|
327
|
+
// void handleSearch();
|
|
328
|
+
// }}
|
|
329
|
+
// >
|
|
330
|
+
/* @__PURE__ */ jsxs(
|
|
331
|
+
"form",
|
|
332
|
+
{
|
|
333
|
+
role: "search",
|
|
334
|
+
className: "flex w-full flex-col gap-3 rounded-md sm:flex-row sm:items-center md:min-w-0 md:flex-1",
|
|
335
|
+
onSubmit: (event) => {
|
|
336
|
+
event.preventDefault();
|
|
337
|
+
void handleSearch();
|
|
338
|
+
},
|
|
339
|
+
children: [
|
|
340
|
+
/* @__PURE__ */ jsxs("div", { className: "relative bg-default rounded-md min-w-0 flex-1", children: [
|
|
341
|
+
/* @__PURE__ */ jsx(SearchIcon, { className: "pointer-events-none absolute left-4 top-1/2 z-10 h-5 w-5 -translate-y-1/2" }),
|
|
342
|
+
/* @__PURE__ */ jsx(
|
|
343
|
+
InputControl_default,
|
|
344
|
+
{
|
|
345
|
+
name: "searchText",
|
|
346
|
+
controlType: InputControlType_default.lineTextInput,
|
|
347
|
+
value: searchText,
|
|
348
|
+
callback: (updatedValues) => setSearchText(updatedValues.value),
|
|
349
|
+
attributes: {
|
|
350
|
+
placeholder: "Search discussions, topics, or keywords..."
|
|
351
|
+
},
|
|
352
|
+
inputClasses: "!mt-0 !rounded-md !py-3 !pl-11 !pr-4 !shadow-sm"
|
|
353
|
+
}
|
|
354
|
+
)
|
|
355
|
+
] }),
|
|
356
|
+
/* @__PURE__ */ jsxs(
|
|
357
|
+
Button_default,
|
|
358
|
+
{
|
|
359
|
+
ButtonType: "Primary" /* Solid */,
|
|
360
|
+
onClick: handleSearch,
|
|
361
|
+
className: "!rounded-md !px-6 !py-3 sm:self-stretch",
|
|
362
|
+
children: [
|
|
363
|
+
/* @__PURE__ */ jsx(SearchIcon, { className: "h-5 w-5" }),
|
|
364
|
+
/* @__PURE__ */ jsx("span", { children: "Search" })
|
|
365
|
+
]
|
|
366
|
+
}
|
|
367
|
+
)
|
|
368
|
+
]
|
|
369
|
+
}
|
|
370
|
+
),
|
|
371
|
+
hasSortControls && /* @__PURE__ */ jsxs("div", { className: "flex w-full items-center gap-3 rounded-md border border-info bg-info-soft p-3 text-sm md:ml-auto md:w-auto md:min-w-72 md:self-stretch", children: [
|
|
372
|
+
/* @__PURE__ */ jsx(
|
|
373
|
+
"label",
|
|
374
|
+
{
|
|
375
|
+
htmlFor: "sortOptions",
|
|
376
|
+
className: "shrink-0 whitespace-nowrap font-medium",
|
|
377
|
+
children: "Sort by"
|
|
378
|
+
}
|
|
379
|
+
),
|
|
380
|
+
/* @__PURE__ */ jsx("div", { className: "min-w-0 flex-1 rounded-md bg-default md:min-w-48", children: /* @__PURE__ */ jsx(
|
|
381
|
+
InputControl_default,
|
|
382
|
+
{
|
|
383
|
+
name: "sortOptions",
|
|
384
|
+
controlType: InputControlType_default.select,
|
|
385
|
+
value: currentSort,
|
|
386
|
+
dataset: normalizedSortOptions,
|
|
387
|
+
dataKeyFieldName: "value",
|
|
388
|
+
dataTextFieldName: "label",
|
|
389
|
+
callback: (updatedValues) => {
|
|
390
|
+
const updatedSort = updatedValues.value || "";
|
|
391
|
+
navigateWithoutReload(
|
|
392
|
+
getQueryUrl({
|
|
393
|
+
$orderby: updatedSort || void 0,
|
|
394
|
+
orderBy: void 0
|
|
395
|
+
})
|
|
396
|
+
);
|
|
397
|
+
},
|
|
398
|
+
attributes: { placeholder: "Default" },
|
|
399
|
+
inputClasses: "!mt-0 !rounded-md !border-info !bg-default !px-4 !py-3 !shadow-sm focus:!border-primary focus:!ring-primary-base"
|
|
400
|
+
}
|
|
401
|
+
) })
|
|
402
|
+
] })
|
|
403
|
+
] }),
|
|
404
|
+
shouldShowFacets && /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-3", children: [
|
|
405
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between border-b pb-3", children: [
|
|
406
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
|
|
407
|
+
/* @__PURE__ */ jsx(FilterSlidersIcon, { className: "h-4 w-4" }),
|
|
408
|
+
/* @__PURE__ */ jsx("h2", { className: "text-base font-semibold tracking-tight", children: "Filters" }),
|
|
409
|
+
selectedFacetCount > 0 && /* @__PURE__ */ jsx("span", { className: "flex h-5 items-center justify-center rounded-full bg-primary-base px-2 text-xs font-semibold", children: selectedFacetCount })
|
|
410
|
+
] }),
|
|
411
|
+
hasActiveFiltersOrSort && /* @__PURE__ */ jsxs(
|
|
412
|
+
"button",
|
|
413
|
+
{
|
|
414
|
+
type: "button",
|
|
415
|
+
onClick: () => void handleClearAll(),
|
|
416
|
+
className: "group inline-flex cursor-pointer items-center gap-1.5 rounded-md px-2 py-1 text-xs font-medium transition-colors duration-150 hover:bg-neutral-soft focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-primary-base",
|
|
417
|
+
"aria-label": "Clear all filters and sorting",
|
|
418
|
+
children: [
|
|
419
|
+
/* @__PURE__ */ jsx(ResetIcon, { className: "h-3.5 w-3.5 transition-transform duration-200 group-hover:-rotate-45" }),
|
|
420
|
+
/* @__PURE__ */ jsx("span", { children: "Clear all" })
|
|
421
|
+
]
|
|
422
|
+
}
|
|
423
|
+
)
|
|
424
|
+
] }),
|
|
425
|
+
selectedFacetCount > 0 && /* @__PURE__ */ jsx("div", { className: "flex flex-wrap gap-1.5 pb-2.5 border-b ", children: Array.from(selectedFacetValues.entries()).map(([field, value]) => /* @__PURE__ */ jsxs(
|
|
426
|
+
"button",
|
|
427
|
+
{
|
|
428
|
+
type: "button",
|
|
429
|
+
onClick: () => clearFacetField(field),
|
|
430
|
+
className: "group inline-flex max-w-full cursor-pointer items-center gap-1.5 rounded-md border bg-neutral-weak px-2.5 py-1 text-xs transition-colors hover:bg-neutral-soft",
|
|
431
|
+
title: `Remove filter: ${value}`,
|
|
432
|
+
children: [
|
|
433
|
+
/* @__PURE__ */ jsx("span", { className: "font-medium truncate max-w-[150px]", children: value }),
|
|
434
|
+
/* @__PURE__ */ jsx(CloseIcon, { className: "h-3.5 w-3.5 shrink-0 opacity-60 group-hover:opacity-100" })
|
|
435
|
+
]
|
|
436
|
+
},
|
|
437
|
+
`chip-${field}`
|
|
438
|
+
)) }),
|
|
439
|
+
activeFacets.length === 1 && /* @__PURE__ */ jsx("nav", { "aria-label": `${humanize(activeFacets[0][0])} filters`, children: /* @__PURE__ */ jsxs("div", { className: "py-1", children: [
|
|
440
|
+
/* @__PURE__ */ jsx("div", { className: "px-1 pb-2 font-medium text-sm", children: humanize(activeFacets[0][0]) }),
|
|
441
|
+
renderFacetItems(activeFacets[0][0], activeFacets[0][1])
|
|
442
|
+
] }) }),
|
|
443
|
+
activeFacets.length > 1 && /* @__PURE__ */ jsx("div", { className: "flex flex-col divide-y divide-neutral-soft", children: activeFacets.map(([field, values]) => {
|
|
444
|
+
const isOpen = !collapsedCategories[field];
|
|
445
|
+
return /* @__PURE__ */ jsxs(
|
|
446
|
+
"div",
|
|
447
|
+
{
|
|
448
|
+
className: "py-2 first:pt-0 last:pb-0",
|
|
449
|
+
children: [
|
|
450
|
+
/* @__PURE__ */ jsxs(
|
|
451
|
+
"button",
|
|
452
|
+
{
|
|
453
|
+
type: "button",
|
|
454
|
+
onClick: () => toggleCategory(field),
|
|
455
|
+
className: "flex w-full cursor-pointer items-center justify-between rounded-md px-1.5 py-1.5 text-sm font-semibold transition-colors duration-150 hover:bg-neutral-weak focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-primary-base",
|
|
456
|
+
children: [
|
|
457
|
+
/* @__PURE__ */ jsx("span", { children: humanize(field) }),
|
|
458
|
+
/* @__PURE__ */ jsx(
|
|
459
|
+
ChevronDownIcon,
|
|
460
|
+
{
|
|
461
|
+
className: `h-4 w-4 transition-transform duration-200 ease-out ${isOpen ? "rotate-180" : ""}`
|
|
462
|
+
}
|
|
463
|
+
)
|
|
464
|
+
]
|
|
465
|
+
}
|
|
466
|
+
),
|
|
467
|
+
isOpen && /* @__PURE__ */ jsx("div", { className: "pt-1", children: renderFacetItems(field, values) })
|
|
468
|
+
]
|
|
469
|
+
},
|
|
470
|
+
field
|
|
471
|
+
);
|
|
472
|
+
}) })
|
|
473
|
+
] })
|
|
474
|
+
]
|
|
475
|
+
}
|
|
476
|
+
);
|
|
477
|
+
};
|
|
478
|
+
var DataBindingControls_default = DataBindingControls;
|
|
479
|
+
export {
|
|
480
|
+
DataBindingControls_default as default
|
|
481
|
+
};
|
|
@@ -34,6 +34,7 @@ var Slider = ({
|
|
|
34
34
|
const [isPlaying, setIsPlaying] = useState(autoplay);
|
|
35
35
|
const trackRef = useRef(null);
|
|
36
36
|
console.log("trackRef:", trackRef);
|
|
37
|
+
const [videoProgress, setVideoProgress] = useState(null);
|
|
37
38
|
useEffect(() => {
|
|
38
39
|
if (typeof initialSlidesToShow === "number") {
|
|
39
40
|
setSlidesToShowState(initialSlidesToShow);
|
|
@@ -58,28 +59,36 @@ var Slider = ({
|
|
|
58
59
|
const videoElement = activeSlideElement?.querySelector("video");
|
|
59
60
|
if (videoElement) {
|
|
60
61
|
videoElement.loop = false;
|
|
62
|
+
setVideoProgress(0);
|
|
61
63
|
if (videoElement.ended) {
|
|
62
64
|
videoElement.currentTime = 0;
|
|
63
65
|
}
|
|
64
66
|
videoElement.play().catch(() => {
|
|
65
67
|
});
|
|
66
68
|
const handleTimeUpdate = () => {
|
|
67
|
-
if (videoElement.duration && !isNaN(videoElement.duration)) {
|
|
69
|
+
if (videoElement.duration && !isNaN(videoElement.duration) && videoElement.duration > 0) {
|
|
68
70
|
const pct = videoElement.currentTime / videoElement.duration * 100;
|
|
71
|
+
setVideoProgress(pct);
|
|
69
72
|
}
|
|
70
73
|
};
|
|
71
74
|
const handleVideoEnded = () => {
|
|
75
|
+
setVideoProgress(100);
|
|
72
76
|
nextSlide();
|
|
73
77
|
};
|
|
74
78
|
const handleVideoError = () => {
|
|
75
79
|
nextSlide();
|
|
76
80
|
};
|
|
81
|
+
videoElement.addEventListener("timeupdate", handleTimeUpdate);
|
|
82
|
+
videoElement.addEventListener("loadedmetadata", handleTimeUpdate);
|
|
77
83
|
videoElement.addEventListener("ended", handleVideoEnded, { once: true });
|
|
78
84
|
videoElement.addEventListener("error", handleVideoError, { once: true });
|
|
79
85
|
return () => {
|
|
86
|
+
videoElement.removeEventListener("timeupdate", handleTimeUpdate);
|
|
87
|
+
videoElement.removeEventListener("loadedmetadata", handleTimeUpdate);
|
|
80
88
|
videoElement.removeEventListener("ended", handleVideoEnded);
|
|
81
89
|
videoElement.removeEventListener("error", handleVideoError);
|
|
82
90
|
videoElement.pause();
|
|
91
|
+
setVideoProgress(null);
|
|
83
92
|
};
|
|
84
93
|
}
|
|
85
94
|
const timer = setInterval(() => {
|
|
@@ -178,7 +187,8 @@ var Slider = ({
|
|
|
178
187
|
activeClassName: dotActiveClassName,
|
|
179
188
|
inactiveClassName: dotInactiveClassName,
|
|
180
189
|
currentSlide,
|
|
181
|
-
totalSlides
|
|
190
|
+
totalSlides,
|
|
191
|
+
customProgress: index === currentSlide ? videoProgress : null
|
|
182
192
|
},
|
|
183
193
|
index
|
|
184
194
|
)) }),
|
|
@@ -238,7 +248,8 @@ var Slider = ({
|
|
|
238
248
|
activeClassName: dotActiveClassName,
|
|
239
249
|
inactiveClassName: dotInactiveClassName,
|
|
240
250
|
currentSlide,
|
|
241
|
-
totalSlides
|
|
251
|
+
totalSlides,
|
|
252
|
+
customProgress: index === currentSlide ? videoProgress : null
|
|
242
253
|
},
|
|
243
254
|
index
|
|
244
255
|
)) })
|
|
@@ -274,7 +285,8 @@ var ProgressPill = ({
|
|
|
274
285
|
activeClassName = "",
|
|
275
286
|
inactiveClassName = "",
|
|
276
287
|
currentSlide,
|
|
277
|
-
totalSlides
|
|
288
|
+
totalSlides,
|
|
289
|
+
customProgress = null
|
|
278
290
|
}) => {
|
|
279
291
|
const [progress, setProgress] = useState(0);
|
|
280
292
|
useEffect(() => {
|
|
@@ -283,7 +295,7 @@ var ProgressPill = ({
|
|
|
283
295
|
}
|
|
284
296
|
}, [active, index]);
|
|
285
297
|
useEffect(() => {
|
|
286
|
-
if (!active || !isPlaying) {
|
|
298
|
+
if (!active || !isPlaying || customProgress !== null) {
|
|
287
299
|
if (!active) {
|
|
288
300
|
setProgress(0);
|
|
289
301
|
}
|
|
@@ -301,7 +313,7 @@ var ProgressPill = ({
|
|
|
301
313
|
}
|
|
302
314
|
}, 50);
|
|
303
315
|
return () => clearInterval(interval);
|
|
304
|
-
}, [active, isPlaying, duration, index]);
|
|
316
|
+
}, [active, isPlaying, duration, index, customProgress]);
|
|
305
317
|
const isFilled = index < currentSlide;
|
|
306
318
|
const isActive = index === currentSlide;
|
|
307
319
|
const shouldShowProgress = isActive || style === "cumulative" && isFilled;
|
|
@@ -336,7 +348,7 @@ var ProgressPill = ({
|
|
|
336
348
|
};
|
|
337
349
|
const renderProgressBar = () => {
|
|
338
350
|
if (style === "modern" && isActive || style === "cumulative" && shouldShowProgress) {
|
|
339
|
-
const displayProgress = style === "cumulative" && isFilled ? 100 : progress;
|
|
351
|
+
const displayProgress = style === "cumulative" && isFilled ? 100 : customProgress !== null && customProgress !== void 0 ? customProgress : progress;
|
|
340
352
|
return /* @__PURE__ */ jsx(
|
|
341
353
|
"div",
|
|
342
354
|
{
|
|
@@ -32,6 +32,7 @@ var Slider = ({
|
|
|
32
32
|
const [isPlaying, setIsPlaying] = useState(autoplay);
|
|
33
33
|
const trackRef = useRef(null);
|
|
34
34
|
console.log("trackRef:", trackRef);
|
|
35
|
+
const [videoProgress, setVideoProgress] = useState(null);
|
|
35
36
|
useEffect(() => {
|
|
36
37
|
if (typeof initialSlidesToShow === "number") {
|
|
37
38
|
setSlidesToShowState(initialSlidesToShow);
|
|
@@ -56,28 +57,36 @@ var Slider = ({
|
|
|
56
57
|
const videoElement = activeSlideElement?.querySelector("video");
|
|
57
58
|
if (videoElement) {
|
|
58
59
|
videoElement.loop = false;
|
|
60
|
+
setVideoProgress(0);
|
|
59
61
|
if (videoElement.ended) {
|
|
60
62
|
videoElement.currentTime = 0;
|
|
61
63
|
}
|
|
62
64
|
videoElement.play().catch(() => {
|
|
63
65
|
});
|
|
64
66
|
const handleTimeUpdate = () => {
|
|
65
|
-
if (videoElement.duration && !isNaN(videoElement.duration)) {
|
|
67
|
+
if (videoElement.duration && !isNaN(videoElement.duration) && videoElement.duration > 0) {
|
|
66
68
|
const pct = videoElement.currentTime / videoElement.duration * 100;
|
|
69
|
+
setVideoProgress(pct);
|
|
67
70
|
}
|
|
68
71
|
};
|
|
69
72
|
const handleVideoEnded = () => {
|
|
73
|
+
setVideoProgress(100);
|
|
70
74
|
nextSlide();
|
|
71
75
|
};
|
|
72
76
|
const handleVideoError = () => {
|
|
73
77
|
nextSlide();
|
|
74
78
|
};
|
|
79
|
+
videoElement.addEventListener("timeupdate", handleTimeUpdate);
|
|
80
|
+
videoElement.addEventListener("loadedmetadata", handleTimeUpdate);
|
|
75
81
|
videoElement.addEventListener("ended", handleVideoEnded, { once: true });
|
|
76
82
|
videoElement.addEventListener("error", handleVideoError, { once: true });
|
|
77
83
|
return () => {
|
|
84
|
+
videoElement.removeEventListener("timeupdate", handleTimeUpdate);
|
|
85
|
+
videoElement.removeEventListener("loadedmetadata", handleTimeUpdate);
|
|
78
86
|
videoElement.removeEventListener("ended", handleVideoEnded);
|
|
79
87
|
videoElement.removeEventListener("error", handleVideoError);
|
|
80
88
|
videoElement.pause();
|
|
89
|
+
setVideoProgress(null);
|
|
81
90
|
};
|
|
82
91
|
}
|
|
83
92
|
const timer = setInterval(() => {
|
|
@@ -176,7 +185,8 @@ var Slider = ({
|
|
|
176
185
|
activeClassName: dotActiveClassName,
|
|
177
186
|
inactiveClassName: dotInactiveClassName,
|
|
178
187
|
currentSlide,
|
|
179
|
-
totalSlides
|
|
188
|
+
totalSlides,
|
|
189
|
+
customProgress: index === currentSlide ? videoProgress : null
|
|
180
190
|
},
|
|
181
191
|
index
|
|
182
192
|
)) }),
|
|
@@ -236,7 +246,8 @@ var Slider = ({
|
|
|
236
246
|
activeClassName: dotActiveClassName,
|
|
237
247
|
inactiveClassName: dotInactiveClassName,
|
|
238
248
|
currentSlide,
|
|
239
|
-
totalSlides
|
|
249
|
+
totalSlides,
|
|
250
|
+
customProgress: index === currentSlide ? videoProgress : null
|
|
240
251
|
},
|
|
241
252
|
index
|
|
242
253
|
)) })
|
|
@@ -272,7 +283,8 @@ var ProgressPill = ({
|
|
|
272
283
|
activeClassName = "",
|
|
273
284
|
inactiveClassName = "",
|
|
274
285
|
currentSlide,
|
|
275
|
-
totalSlides
|
|
286
|
+
totalSlides,
|
|
287
|
+
customProgress = null
|
|
276
288
|
}) => {
|
|
277
289
|
const [progress, setProgress] = useState(0);
|
|
278
290
|
useEffect(() => {
|
|
@@ -281,7 +293,7 @@ var ProgressPill = ({
|
|
|
281
293
|
}
|
|
282
294
|
}, [active, index]);
|
|
283
295
|
useEffect(() => {
|
|
284
|
-
if (!active || !isPlaying) {
|
|
296
|
+
if (!active || !isPlaying || customProgress !== null) {
|
|
285
297
|
if (!active) {
|
|
286
298
|
setProgress(0);
|
|
287
299
|
}
|
|
@@ -299,7 +311,7 @@ var ProgressPill = ({
|
|
|
299
311
|
}
|
|
300
312
|
}, 50);
|
|
301
313
|
return () => clearInterval(interval);
|
|
302
|
-
}, [active, isPlaying, duration, index]);
|
|
314
|
+
}, [active, isPlaying, duration, index, customProgress]);
|
|
303
315
|
const isFilled = index < currentSlide;
|
|
304
316
|
const isActive = index === currentSlide;
|
|
305
317
|
const shouldShowProgress = isActive || style === "cumulative" && isFilled;
|
|
@@ -334,7 +346,7 @@ var ProgressPill = ({
|
|
|
334
346
|
};
|
|
335
347
|
const renderProgressBar = () => {
|
|
336
348
|
if (style === "modern" && isActive || style === "cumulative" && shouldShowProgress) {
|
|
337
|
-
const displayProgress = style === "cumulative" && isFilled ? 100 : progress;
|
|
349
|
+
const displayProgress = style === "cumulative" && isFilled ? 100 : customProgress !== null && customProgress !== void 0 ? customProgress : progress;
|
|
338
350
|
return /* @__PURE__ */ jsx(
|
|
339
351
|
"div",
|
|
340
352
|
{
|