@clyrex-digital/clyrex-controls-dev 0.8.1-dev.20260824095913 → 0.8.1-dev.20260824103828

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.
@@ -18,6 +18,28 @@ var InputControl_default = InputControl;
18
18
  import { jsx, jsxs } from "react/jsx-runtime";
19
19
  var humanize = (value) => value.replace(/([a-z0-9])([A-Z])/g, "$1 $2").replace(/[_-]+/g, " ").trim();
20
20
  var escapeODataString = (value) => value.replace(/'/g, "''");
21
+ var parseFacetSelections = (filter) => {
22
+ const selections = /* @__PURE__ */ new Map();
23
+ const groupedExpression = /\(\s*([^()]+?)\s+eq\s+'((?:''|[^'])*)'\s*\)/gi;
24
+ for (const match of filter.matchAll(groupedExpression)) {
25
+ selections.set(match[1].trim(), match[2].replace(/''/g, "'"));
26
+ }
27
+ if (selections.size === 0) {
28
+ const singleExpression = filter.match(
29
+ /^\s*([^()]+?)\s+eq\s+'((?:''|[^'])*)'\s*$/i
30
+ );
31
+ if (singleExpression) {
32
+ selections.set(
33
+ singleExpression[1].trim(),
34
+ singleExpression[2].replace(/''/g, "'")
35
+ );
36
+ }
37
+ }
38
+ return selections;
39
+ };
40
+ var buildFacetFilter = (selections) => Array.from(selections.entries()).map(
41
+ ([field, value]) => `(${field} eq '${escapeODataString(value)}')`
42
+ ).join(" and ");
21
43
  var parseODataSearch = (value) => {
22
44
  if (!value) return "";
23
45
  const trimmedValue = value.trim();
@@ -71,6 +93,7 @@ var DataBindingControls = ({
71
93
  const resolvedSortOptions = apiSortOptions.length > 0 ? apiSortOptions : DUMMY_SORT_OPTIONS;
72
94
  const normalizedSortOptions = resolvedSortOptions.map(normalizeSortOption).filter((option) => option.value);
73
95
  const currentFilter = query?.["$filter"] ?? query?.filter ?? "";
96
+ const selectedFacetValues = parseFacetSelections(currentFilter);
74
97
  const currentSort = query?.["$orderby"] ?? query?.orderBy ?? "";
75
98
  const currentSearch = parseODataSearch(query?.["$Search"]);
76
99
  const [searchText, setSearchText] = useState(currentSearch);
@@ -95,10 +118,19 @@ var DataBindingControls = ({
95
118
  },
96
119
  [path, query]
97
120
  );
98
- const getFacetUrl = (field, value) => getQueryUrl({
99
- $filter: value ? `${field} eq '${escapeODataString(value)}'` : void 0,
100
- filter: void 0
101
- });
121
+ const getFacetUrl = (field, value) => {
122
+ const updatedSelections = new Map(selectedFacetValues);
123
+ if (value) {
124
+ updatedSelections.set(field, value);
125
+ } else {
126
+ updatedSelections.delete(field);
127
+ }
128
+ const updatedFilter = buildFacetFilter(updatedSelections);
129
+ return getQueryUrl({
130
+ $filter: updatedFilter || void 0,
131
+ filter: void 0
132
+ });
133
+ };
102
134
  const navigateWithoutReload = useCallback(
103
135
  (url) => {
104
136
  if (lastNavigationUrl.current === url) {
@@ -142,20 +174,20 @@ var DataBindingControls = ({
142
174
  {
143
175
  type: "button",
144
176
  onClick: () => navigateWithoutReload(getFacetUrl(field)),
145
- "aria-pressed": !currentFilter,
146
- className: `px-3 py-2 text-left text-sm ${stacked ? "w-full" : "border"} ${currentFilter ? "" : "bg-primary-base font-semibold"}`,
177
+ "aria-pressed": !selectedFacetValues.has(field),
178
+ className: `px-3 py-2 text-left text-sm ${stacked ? "w-full" : "border"} ${selectedFacetValues.has(field) ? "" : "bg-primary-base font-semibold"}`,
147
179
  children: "All"
148
180
  }
149
181
  ),
150
182
  values.map((facet) => {
151
- const filter = `${field} eq '${escapeODataString(facet.value)}'`;
183
+ const isSelected = selectedFacetValues.get(field) === facet.value;
152
184
  return /* @__PURE__ */ jsxs(
153
185
  "button",
154
186
  {
155
187
  type: "button",
156
188
  onClick: () => navigateWithoutReload(getFacetUrl(field, facet.value)),
157
- "aria-pressed": currentFilter === filter,
158
- className: `px-3 py-2 text-left text-sm ${stacked ? "w-full" : "border"} ${currentFilter === filter ? "bg-primary-base font-semibold" : ""}`,
189
+ "aria-pressed": isSelected,
190
+ className: `px-3 py-2 text-left text-sm ${stacked ? "w-full" : "border"} ${isSelected ? "bg-primary-base font-semibold" : ""}`,
159
191
  children: [
160
192
  facet.value,
161
193
  " (",
@@ -14,6 +14,28 @@ import { useRouter } from "next/navigation";
14
14
  import { jsx, jsxs } from "react/jsx-runtime";
15
15
  var humanize = (value) => value.replace(/([a-z0-9])([A-Z])/g, "$1 $2").replace(/[_-]+/g, " ").trim();
16
16
  var escapeODataString = (value) => value.replace(/'/g, "''");
17
+ var parseFacetSelections = (filter) => {
18
+ const selections = /* @__PURE__ */ new Map();
19
+ const groupedExpression = /\(\s*([^()]+?)\s+eq\s+'((?:''|[^'])*)'\s*\)/gi;
20
+ for (const match of filter.matchAll(groupedExpression)) {
21
+ selections.set(match[1].trim(), match[2].replace(/''/g, "'"));
22
+ }
23
+ if (selections.size === 0) {
24
+ const singleExpression = filter.match(
25
+ /^\s*([^()]+?)\s+eq\s+'((?:''|[^'])*)'\s*$/i
26
+ );
27
+ if (singleExpression) {
28
+ selections.set(
29
+ singleExpression[1].trim(),
30
+ singleExpression[2].replace(/''/g, "'")
31
+ );
32
+ }
33
+ }
34
+ return selections;
35
+ };
36
+ var buildFacetFilter = (selections) => Array.from(selections.entries()).map(
37
+ ([field, value]) => `(${field} eq '${escapeODataString(value)}')`
38
+ ).join(" and ");
17
39
  var parseODataSearch = (value) => {
18
40
  if (!value) return "";
19
41
  const trimmedValue = value.trim();
@@ -67,6 +89,7 @@ var DataBindingControls = ({
67
89
  const resolvedSortOptions = apiSortOptions.length > 0 ? apiSortOptions : DUMMY_SORT_OPTIONS;
68
90
  const normalizedSortOptions = resolvedSortOptions.map(normalizeSortOption).filter((option) => option.value);
69
91
  const currentFilter = query?.["$filter"] ?? query?.filter ?? "";
92
+ const selectedFacetValues = parseFacetSelections(currentFilter);
70
93
  const currentSort = query?.["$orderby"] ?? query?.orderBy ?? "";
71
94
  const currentSearch = parseODataSearch(query?.["$Search"]);
72
95
  const [searchText, setSearchText] = useState(currentSearch);
@@ -91,10 +114,19 @@ var DataBindingControls = ({
91
114
  },
92
115
  [path, query]
93
116
  );
94
- const getFacetUrl = (field, value) => getQueryUrl({
95
- $filter: value ? `${field} eq '${escapeODataString(value)}'` : void 0,
96
- filter: void 0
97
- });
117
+ const getFacetUrl = (field, value) => {
118
+ const updatedSelections = new Map(selectedFacetValues);
119
+ if (value) {
120
+ updatedSelections.set(field, value);
121
+ } else {
122
+ updatedSelections.delete(field);
123
+ }
124
+ const updatedFilter = buildFacetFilter(updatedSelections);
125
+ return getQueryUrl({
126
+ $filter: updatedFilter || void 0,
127
+ filter: void 0
128
+ });
129
+ };
98
130
  const navigateWithoutReload = useCallback(
99
131
  (url) => {
100
132
  if (lastNavigationUrl.current === url) {
@@ -138,20 +170,20 @@ var DataBindingControls = ({
138
170
  {
139
171
  type: "button",
140
172
  onClick: () => navigateWithoutReload(getFacetUrl(field)),
141
- "aria-pressed": !currentFilter,
142
- className: `px-3 py-2 text-left text-sm ${stacked ? "w-full" : "border"} ${currentFilter ? "" : "bg-primary-base font-semibold"}`,
173
+ "aria-pressed": !selectedFacetValues.has(field),
174
+ className: `px-3 py-2 text-left text-sm ${stacked ? "w-full" : "border"} ${selectedFacetValues.has(field) ? "" : "bg-primary-base font-semibold"}`,
143
175
  children: "All"
144
176
  }
145
177
  ),
146
178
  values.map((facet) => {
147
- const filter = `${field} eq '${escapeODataString(facet.value)}'`;
179
+ const isSelected = selectedFacetValues.get(field) === facet.value;
148
180
  return /* @__PURE__ */ jsxs(
149
181
  "button",
150
182
  {
151
183
  type: "button",
152
184
  onClick: () => navigateWithoutReload(getFacetUrl(field, facet.value)),
153
- "aria-pressed": currentFilter === filter,
154
- className: `px-3 py-2 text-left text-sm ${stacked ? "w-full" : "border"} ${currentFilter === filter ? "bg-primary-base font-semibold" : ""}`,
185
+ "aria-pressed": isSelected,
186
+ className: `px-3 py-2 text-left text-sm ${stacked ? "w-full" : "border"} ${isSelected ? "bg-primary-base font-semibold" : ""}`,
155
187
  children: [
156
188
  facet.value,
157
189
  " (",
package/dist/index.js CHANGED
@@ -4506,7 +4506,7 @@ var DataBindingControls_exports = {};
4506
4506
  __export(DataBindingControls_exports, {
4507
4507
  default: () => DataBindingControls_default
4508
4508
  });
4509
- var import_react55, import_navigation, import_jsx_runtime77, humanize, escapeODataString, parseODataSearch, normalizeSortOption, DUMMY_FACETS, DUMMY_SORT_OPTIONS, DataBindingControls, DataBindingControls_default;
4509
+ var import_react55, import_navigation, import_jsx_runtime77, humanize, escapeODataString, parseFacetSelections, buildFacetFilter, parseODataSearch, normalizeSortOption, DUMMY_FACETS, DUMMY_SORT_OPTIONS, DataBindingControls, DataBindingControls_default;
4510
4510
  var init_DataBindingControls = __esm({
4511
4511
  "src/components/pageRenderingEngine/nodes/DataBindingControls.tsx"() {
4512
4512
  "use strict";
@@ -4518,6 +4518,28 @@ var init_DataBindingControls = __esm({
4518
4518
  import_jsx_runtime77 = require("react/jsx-runtime");
4519
4519
  humanize = (value) => value.replace(/([a-z0-9])([A-Z])/g, "$1 $2").replace(/[_-]+/g, " ").trim();
4520
4520
  escapeODataString = (value) => value.replace(/'/g, "''");
4521
+ parseFacetSelections = (filter) => {
4522
+ const selections = /* @__PURE__ */ new Map();
4523
+ const groupedExpression = /\(\s*([^()]+?)\s+eq\s+'((?:''|[^'])*)'\s*\)/gi;
4524
+ for (const match of filter.matchAll(groupedExpression)) {
4525
+ selections.set(match[1].trim(), match[2].replace(/''/g, "'"));
4526
+ }
4527
+ if (selections.size === 0) {
4528
+ const singleExpression = filter.match(
4529
+ /^\s*([^()]+?)\s+eq\s+'((?:''|[^'])*)'\s*$/i
4530
+ );
4531
+ if (singleExpression) {
4532
+ selections.set(
4533
+ singleExpression[1].trim(),
4534
+ singleExpression[2].replace(/''/g, "'")
4535
+ );
4536
+ }
4537
+ }
4538
+ return selections;
4539
+ };
4540
+ buildFacetFilter = (selections) => Array.from(selections.entries()).map(
4541
+ ([field, value]) => `(${field} eq '${escapeODataString(value)}')`
4542
+ ).join(" and ");
4521
4543
  parseODataSearch = (value) => {
4522
4544
  if (!value) return "";
4523
4545
  const trimmedValue = value.trim();
@@ -4571,6 +4593,7 @@ var init_DataBindingControls = __esm({
4571
4593
  const resolvedSortOptions = apiSortOptions.length > 0 ? apiSortOptions : DUMMY_SORT_OPTIONS;
4572
4594
  const normalizedSortOptions = resolvedSortOptions.map(normalizeSortOption).filter((option) => option.value);
4573
4595
  const currentFilter = query?.["$filter"] ?? query?.filter ?? "";
4596
+ const selectedFacetValues = parseFacetSelections(currentFilter);
4574
4597
  const currentSort = query?.["$orderby"] ?? query?.orderBy ?? "";
4575
4598
  const currentSearch = parseODataSearch(query?.["$Search"]);
4576
4599
  const [searchText, setSearchText] = (0, import_react55.useState)(currentSearch);
@@ -4595,10 +4618,19 @@ var init_DataBindingControls = __esm({
4595
4618
  },
4596
4619
  [path, query]
4597
4620
  );
4598
- const getFacetUrl = (field, value) => getQueryUrl({
4599
- $filter: value ? `${field} eq '${escapeODataString(value)}'` : void 0,
4600
- filter: void 0
4601
- });
4621
+ const getFacetUrl = (field, value) => {
4622
+ const updatedSelections = new Map(selectedFacetValues);
4623
+ if (value) {
4624
+ updatedSelections.set(field, value);
4625
+ } else {
4626
+ updatedSelections.delete(field);
4627
+ }
4628
+ const updatedFilter = buildFacetFilter(updatedSelections);
4629
+ return getQueryUrl({
4630
+ $filter: updatedFilter || void 0,
4631
+ filter: void 0
4632
+ });
4633
+ };
4602
4634
  const navigateWithoutReload = (0, import_react55.useCallback)(
4603
4635
  (url) => {
4604
4636
  if (lastNavigationUrl.current === url) {
@@ -4642,20 +4674,20 @@ var init_DataBindingControls = __esm({
4642
4674
  {
4643
4675
  type: "button",
4644
4676
  onClick: () => navigateWithoutReload(getFacetUrl(field)),
4645
- "aria-pressed": !currentFilter,
4646
- className: `px-3 py-2 text-left text-sm ${stacked ? "w-full" : "border"} ${currentFilter ? "" : "bg-primary-base font-semibold"}`,
4677
+ "aria-pressed": !selectedFacetValues.has(field),
4678
+ className: `px-3 py-2 text-left text-sm ${stacked ? "w-full" : "border"} ${selectedFacetValues.has(field) ? "" : "bg-primary-base font-semibold"}`,
4647
4679
  children: "All"
4648
4680
  }
4649
4681
  ),
4650
4682
  values.map((facet) => {
4651
- const filter = `${field} eq '${escapeODataString(facet.value)}'`;
4683
+ const isSelected = selectedFacetValues.get(field) === facet.value;
4652
4684
  return /* @__PURE__ */ (0, import_jsx_runtime77.jsxs)(
4653
4685
  "button",
4654
4686
  {
4655
4687
  type: "button",
4656
4688
  onClick: () => navigateWithoutReload(getFacetUrl(field, facet.value)),
4657
- "aria-pressed": currentFilter === filter,
4658
- className: `px-3 py-2 text-left text-sm ${stacked ? "w-full" : "border"} ${currentFilter === filter ? "bg-primary-base font-semibold" : ""}`,
4689
+ "aria-pressed": isSelected,
4690
+ className: `px-3 py-2 text-left text-sm ${stacked ? "w-full" : "border"} ${isSelected ? "bg-primary-base font-semibold" : ""}`,
4659
4691
  children: [
4660
4692
  facet.value,
4661
4693
  " (",
package/dist/index.mjs CHANGED
@@ -2296,7 +2296,7 @@ var GoogleMapNode_default = GoogleMapNode;
2296
2296
  // src/components/pageRenderingEngine/nodes/DivContainer.tsx
2297
2297
  import { jsx as jsx35, jsxs as jsxs13 } from "react/jsx-runtime";
2298
2298
  var Pagination = dynamic11(() => import("./Pagination-2KVND6JU.mjs"), { ssr: true });
2299
- var DataBindingControls = dynamic11(() => import("./DataBindingControls-GHWIJ5N7.mjs"), {
2299
+ var DataBindingControls = dynamic11(() => import("./DataBindingControls-VTCI7X5Y.mjs"), {
2300
2300
  ssr: true
2301
2301
  });
2302
2302
  var Slider = dynamic11(() => import("./Slider-554BKC7N.mjs"), {
package/dist/server.js CHANGED
@@ -4504,7 +4504,7 @@ var DataBindingControls_exports = {};
4504
4504
  __export(DataBindingControls_exports, {
4505
4505
  default: () => DataBindingControls_default
4506
4506
  });
4507
- var import_react55, import_navigation, import_jsx_runtime77, humanize, escapeODataString, parseODataSearch, normalizeSortOption, DUMMY_FACETS, DUMMY_SORT_OPTIONS, DataBindingControls, DataBindingControls_default;
4507
+ var import_react55, import_navigation, import_jsx_runtime77, humanize, escapeODataString, parseFacetSelections, buildFacetFilter, parseODataSearch, normalizeSortOption, DUMMY_FACETS, DUMMY_SORT_OPTIONS, DataBindingControls, DataBindingControls_default;
4508
4508
  var init_DataBindingControls = __esm({
4509
4509
  "src/components/pageRenderingEngine/nodes/DataBindingControls.tsx"() {
4510
4510
  "use strict";
@@ -4516,6 +4516,28 @@ var init_DataBindingControls = __esm({
4516
4516
  import_jsx_runtime77 = require("react/jsx-runtime");
4517
4517
  humanize = (value) => value.replace(/([a-z0-9])([A-Z])/g, "$1 $2").replace(/[_-]+/g, " ").trim();
4518
4518
  escapeODataString = (value) => value.replace(/'/g, "''");
4519
+ parseFacetSelections = (filter) => {
4520
+ const selections = /* @__PURE__ */ new Map();
4521
+ const groupedExpression = /\(\s*([^()]+?)\s+eq\s+'((?:''|[^'])*)'\s*\)/gi;
4522
+ for (const match of filter.matchAll(groupedExpression)) {
4523
+ selections.set(match[1].trim(), match[2].replace(/''/g, "'"));
4524
+ }
4525
+ if (selections.size === 0) {
4526
+ const singleExpression = filter.match(
4527
+ /^\s*([^()]+?)\s+eq\s+'((?:''|[^'])*)'\s*$/i
4528
+ );
4529
+ if (singleExpression) {
4530
+ selections.set(
4531
+ singleExpression[1].trim(),
4532
+ singleExpression[2].replace(/''/g, "'")
4533
+ );
4534
+ }
4535
+ }
4536
+ return selections;
4537
+ };
4538
+ buildFacetFilter = (selections) => Array.from(selections.entries()).map(
4539
+ ([field, value]) => `(${field} eq '${escapeODataString(value)}')`
4540
+ ).join(" and ");
4519
4541
  parseODataSearch = (value) => {
4520
4542
  if (!value) return "";
4521
4543
  const trimmedValue = value.trim();
@@ -4569,6 +4591,7 @@ var init_DataBindingControls = __esm({
4569
4591
  const resolvedSortOptions = apiSortOptions.length > 0 ? apiSortOptions : DUMMY_SORT_OPTIONS;
4570
4592
  const normalizedSortOptions = resolvedSortOptions.map(normalizeSortOption).filter((option) => option.value);
4571
4593
  const currentFilter = query?.["$filter"] ?? query?.filter ?? "";
4594
+ const selectedFacetValues = parseFacetSelections(currentFilter);
4572
4595
  const currentSort = query?.["$orderby"] ?? query?.orderBy ?? "";
4573
4596
  const currentSearch = parseODataSearch(query?.["$Search"]);
4574
4597
  const [searchText, setSearchText] = (0, import_react55.useState)(currentSearch);
@@ -4593,10 +4616,19 @@ var init_DataBindingControls = __esm({
4593
4616
  },
4594
4617
  [path, query]
4595
4618
  );
4596
- const getFacetUrl = (field, value) => getQueryUrl({
4597
- $filter: value ? `${field} eq '${escapeODataString(value)}'` : void 0,
4598
- filter: void 0
4599
- });
4619
+ const getFacetUrl = (field, value) => {
4620
+ const updatedSelections = new Map(selectedFacetValues);
4621
+ if (value) {
4622
+ updatedSelections.set(field, value);
4623
+ } else {
4624
+ updatedSelections.delete(field);
4625
+ }
4626
+ const updatedFilter = buildFacetFilter(updatedSelections);
4627
+ return getQueryUrl({
4628
+ $filter: updatedFilter || void 0,
4629
+ filter: void 0
4630
+ });
4631
+ };
4600
4632
  const navigateWithoutReload = (0, import_react55.useCallback)(
4601
4633
  (url) => {
4602
4634
  if (lastNavigationUrl.current === url) {
@@ -4640,20 +4672,20 @@ var init_DataBindingControls = __esm({
4640
4672
  {
4641
4673
  type: "button",
4642
4674
  onClick: () => navigateWithoutReload(getFacetUrl(field)),
4643
- "aria-pressed": !currentFilter,
4644
- className: `px-3 py-2 text-left text-sm ${stacked ? "w-full" : "border"} ${currentFilter ? "" : "bg-primary-base font-semibold"}`,
4675
+ "aria-pressed": !selectedFacetValues.has(field),
4676
+ className: `px-3 py-2 text-left text-sm ${stacked ? "w-full" : "border"} ${selectedFacetValues.has(field) ? "" : "bg-primary-base font-semibold"}`,
4645
4677
  children: "All"
4646
4678
  }
4647
4679
  ),
4648
4680
  values.map((facet) => {
4649
- const filter = `${field} eq '${escapeODataString(facet.value)}'`;
4681
+ const isSelected = selectedFacetValues.get(field) === facet.value;
4650
4682
  return /* @__PURE__ */ (0, import_jsx_runtime77.jsxs)(
4651
4683
  "button",
4652
4684
  {
4653
4685
  type: "button",
4654
4686
  onClick: () => navigateWithoutReload(getFacetUrl(field, facet.value)),
4655
- "aria-pressed": currentFilter === filter,
4656
- className: `px-3 py-2 text-left text-sm ${stacked ? "w-full" : "border"} ${currentFilter === filter ? "bg-primary-base font-semibold" : ""}`,
4687
+ "aria-pressed": isSelected,
4688
+ className: `px-3 py-2 text-left text-sm ${stacked ? "w-full" : "border"} ${isSelected ? "bg-primary-base font-semibold" : ""}`,
4657
4689
  children: [
4658
4690
  facet.value,
4659
4691
  " (",
package/dist/server.mjs CHANGED
@@ -2264,7 +2264,7 @@ var GoogleMapNode_default = GoogleMapNode;
2264
2264
  // src/components/pageRenderingEngine/nodes/DivContainer.tsx
2265
2265
  import { jsx as jsx35, jsxs as jsxs13 } from "react/jsx-runtime";
2266
2266
  var Pagination = dynamic11(() => import("./Pagination-PDU7V3HY.mjs"), { ssr: true });
2267
- var DataBindingControls = dynamic11(() => import("./DataBindingControls-AT7I4FSN.mjs"), {
2267
+ var DataBindingControls = dynamic11(() => import("./DataBindingControls-2LHGICW3.mjs"), {
2268
2268
  ssr: true
2269
2269
  });
2270
2270
  var Slider = dynamic11(() => import("./Slider-PEIVH6A5.mjs"), {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@clyrex-digital/clyrex-controls-dev",
3
- "version": "0.8.1-dev.20260824095913",
3
+ "version": "0.8.1-dev.20260824103828",
4
4
  "description": "Reusable React components",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.mjs",