@clyrex-digital/clyrex-controls-dev 0.8.1-dev.20260818060820 → 0.8.1-dev.20260824072352

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (31) hide show
  1. package/dist/DataBindingControls-QZ7ES2AS.mjs +205 -0
  2. package/dist/DataBindingControls-XCAIDMDC.mjs +209 -0
  3. package/dist/{InputControlClient-XR37ZIQ2.mjs → InputControlClient-4M2BZXQO.mjs} +5 -3
  4. package/dist/InputControlClient-AORN4DRF.mjs +1921 -0
  5. package/dist/{LinkNodeButton-AOEDCCL7.mjs → LinkNodeButton-BEAX4I4C.mjs} +1 -1
  6. package/dist/LinkNodeButton-IT2CELKO.mjs +225 -0
  7. package/dist/{Pagination-YKNCYVXV.mjs → Pagination-GL6B4MNO.mjs} +5 -3
  8. package/dist/{Pagination-6OFACRMQ.mjs → Pagination-ZQO3EUKB.mjs} +27 -71
  9. package/dist/chunk-2R26M6CK.mjs +30 -0
  10. package/dist/{chunk-KL2YKXXS.mjs → chunk-4P4HO663.mjs} +30 -6
  11. package/dist/chunk-4R7F7LBL.mjs +36 -0
  12. package/dist/chunk-6PW2RLUJ.mjs +52 -0
  13. package/dist/chunk-E4VOFO5Q.mjs +39 -0
  14. package/dist/{chunk-YDPISYMP.mjs → chunk-GCG4OYDJ.mjs} +0 -34
  15. package/dist/{chunk-65QPOTZ4.mjs → chunk-GJOJX2O3.mjs} +1 -1
  16. package/dist/chunk-GKI42H4B.mjs +13 -0
  17. package/dist/{chunk-TVL6KVD5.mjs → chunk-Q46GMD3P.mjs} +31 -37
  18. package/dist/chunk-RHVNJMS4.mjs +251 -0
  19. package/dist/{chunk-WEV5U33G.mjs → chunk-TKDSRAM6.mjs} +36 -20
  20. package/dist/chunk-TQ6BXQ3A.mjs +24 -0
  21. package/dist/{chunk-3GWLDT7C.mjs → chunk-WXZMRMRS.mjs} +36 -20
  22. package/dist/index.d.mts +17 -6
  23. package/dist/index.d.ts +17 -6
  24. package/dist/index.js +616 -311
  25. package/dist/index.mjs +101 -54
  26. package/dist/server.d.mts +17 -6
  27. package/dist/server.d.ts +17 -6
  28. package/dist/server.js +2717 -298
  29. package/dist/server.mjs +86 -52
  30. package/package.json +1 -1
  31. package/dist/LinkNodeButton-KZRNRJRI.mjs +0 -467
@@ -0,0 +1,205 @@
1
+ "use client";
2
+
3
+ "use client";
4
+ import {
5
+ InputControl_default
6
+ } from "./chunk-GKI42H4B.mjs";
7
+ import {
8
+ InputControlType_default
9
+ } from "./chunk-E4VOFO5Q.mjs";
10
+
11
+ // src/components/pageRenderingEngine/nodes/DataBindingControls.tsx
12
+ import { useCallback, useEffect, useRef, useState } from "react";
13
+ import { useRouter } from "next/navigation";
14
+ import { jsx, jsxs } from "react/jsx-runtime";
15
+ var humanize = (value) => value.replace(/([a-z0-9])([A-Z])/g, "$1 $2").replace(/[_-]+/g, " ").trim();
16
+ var escapeODataString = (value) => value.replace(/'/g, "''");
17
+ var normalizeSortOption = (option) => {
18
+ const direction = option.direction.trim();
19
+ return {
20
+ label: option.title || humanize(option.name),
21
+ value: [option.name, direction].filter(Boolean).join(" ")
22
+ };
23
+ };
24
+ var DUMMY_FACETS = {
25
+ CategoryTitle: [
26
+ { value: "Career Readiness", count: 2 },
27
+ { value: "Student Learning", count: 2 }
28
+ ],
29
+ Author: [
30
+ { value: "John Smith", count: 2 },
31
+ { value: "Sarah Jones", count: 1 },
32
+ { value: "Emily Brown", count: 1 }
33
+ ]
34
+ };
35
+ var DUMMY_SORT_OPTIONS = [
36
+ { name: "createdDate", title: "Newest First", direction: "desc" },
37
+ { name: "createdDate", title: "Oldest First", direction: "asc" },
38
+ { name: "title", title: "Title A-Z", direction: "asc" },
39
+ { name: "title", title: "Title Z-A", direction: "desc" }
40
+ ];
41
+ var DataBindingControls = ({
42
+ path,
43
+ query,
44
+ facets,
45
+ sortOptions,
46
+ showFacets,
47
+ showSortOptions,
48
+ showSearchBar,
49
+ mode = "toolbar"
50
+ }) => {
51
+ const router = useRouter();
52
+ const apiFacetGroups = Object.entries(facets ?? {}).filter(
53
+ ([, values]) => Array.isArray(values) && values.length > 0
54
+ );
55
+ const facetGroups = apiFacetGroups.length > 0 ? apiFacetGroups : Object.entries(DUMMY_FACETS);
56
+ const apiSortOptions = (sortOptions ?? []).filter(
57
+ (option) => option?.name && option?.direction
58
+ );
59
+ const resolvedSortOptions = apiSortOptions.length > 0 ? apiSortOptions : DUMMY_SORT_OPTIONS;
60
+ const normalizedSortOptions = resolvedSortOptions.map(normalizeSortOption).filter((option) => option.value);
61
+ const currentFilter = query?.["$filter"] ?? query?.filter ?? "";
62
+ const currentSort = query?.["$orderby"] ?? query?.orderBy ?? "";
63
+ const currentSearch = query?.searchTerm ?? query?.searchText ?? "";
64
+ const [searchText, setSearchText] = useState(currentSearch);
65
+ const lastNavigationUrl = useRef(null);
66
+ useEffect(() => {
67
+ setSearchText(currentSearch);
68
+ }, [currentSearch]);
69
+ const getQueryUrl = useCallback(
70
+ (updates) => {
71
+ const params = new URLSearchParams(query ?? {});
72
+ Object.entries(updates).forEach(([key, value]) => {
73
+ if (value) {
74
+ params.set(key, value);
75
+ } else {
76
+ params.delete(key);
77
+ }
78
+ });
79
+ params.delete("$skip");
80
+ params.delete("skip");
81
+ const queryString = params.toString();
82
+ return queryString ? `${path}?${queryString}` : path;
83
+ },
84
+ [path, query]
85
+ );
86
+ const getFacetUrl = (field, value) => getQueryUrl({
87
+ $filter: value ? `${field} eq '${escapeODataString(value)}'` : void 0,
88
+ filter: void 0
89
+ });
90
+ const navigateWithoutReload = useCallback(
91
+ (url) => {
92
+ if (lastNavigationUrl.current === url) {
93
+ return;
94
+ }
95
+ if (typeof window !== "undefined") {
96
+ const targetUrl = new URL(url, window.location.origin);
97
+ if (targetUrl.pathname === window.location.pathname && targetUrl.search === window.location.search) {
98
+ return;
99
+ }
100
+ }
101
+ lastNavigationUrl.current = url;
102
+ router.push(url, { scroll: false });
103
+ },
104
+ [router]
105
+ );
106
+ useEffect(() => {
107
+ const trimmedSearchText = searchText.trim();
108
+ if (trimmedSearchText === currentSearch.trim()) {
109
+ return;
110
+ }
111
+ const timeout = window.setTimeout(() => {
112
+ navigateWithoutReload(
113
+ getQueryUrl({
114
+ searchTerm: trimmedSearchText || void 0,
115
+ searchText: void 0
116
+ })
117
+ );
118
+ }, 500);
119
+ return () => window.clearTimeout(timeout);
120
+ }, [currentSearch, getQueryUrl, navigateWithoutReload, searchText]);
121
+ const hasFacetControls = showFacets && facetGroups.length > 0;
122
+ const hasSortControls = showSortOptions && normalizedSortOptions.length > 0;
123
+ const shouldShowToolbar = mode === "toolbar" && (showSearchBar || hasSortControls);
124
+ const shouldShowFacets = mode === "facets" && hasFacetControls;
125
+ if (!shouldShowToolbar && !shouldShowFacets) {
126
+ return null;
127
+ }
128
+ const renderFacetLinks = (field, values, stacked = false) => /* @__PURE__ */ jsxs("div", { className: stacked ? "flex flex-col gap-1" : "flex flex-wrap gap-2", children: [
129
+ /* @__PURE__ */ jsx(
130
+ "button",
131
+ {
132
+ type: "button",
133
+ onClick: () => navigateWithoutReload(getFacetUrl(field)),
134
+ "aria-pressed": !currentFilter,
135
+ className: `px-3 py-2 text-left text-sm ${stacked ? "w-full" : "border"} ${currentFilter ? "" : "bg-primary-base font-semibold"}`,
136
+ children: "All"
137
+ }
138
+ ),
139
+ values.map((facet) => {
140
+ const filter = `${field} eq '${escapeODataString(facet.value)}'`;
141
+ return /* @__PURE__ */ jsxs(
142
+ "button",
143
+ {
144
+ type: "button",
145
+ onClick: () => navigateWithoutReload(getFacetUrl(field, facet.value)),
146
+ "aria-pressed": currentFilter === filter,
147
+ className: `px-3 py-2 text-left text-sm ${stacked ? "w-full" : "border"} ${currentFilter === filter ? "bg-primary-base font-semibold" : ""}`,
148
+ children: [
149
+ facet.value,
150
+ " (",
151
+ facet.count,
152
+ ")"
153
+ ]
154
+ },
155
+ `${field}-${facet.value}`
156
+ );
157
+ })
158
+ ] });
159
+ return /* @__PURE__ */ jsxs("div", { className: mode === "toolbar" ? "mb-6" : "flex flex-col gap-2", children: [
160
+ shouldShowToolbar && /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-3 md:flex-row md:items-center md:justify-between", children: [
161
+ showSearchBar && /* @__PURE__ */ jsx("div", { className: "w-full max-w-xl", children: /* @__PURE__ */ jsx(
162
+ InputControl_default,
163
+ {
164
+ name: "searchText",
165
+ controlType: InputControlType_default.lineTextInput,
166
+ value: searchText,
167
+ callback: (updatedValues) => setSearchText(updatedValues.value),
168
+ attributes: { placeholder: "Search" },
169
+ inputClasses: "!mt-0"
170
+ }
171
+ ) }),
172
+ hasSortControls && /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 text-sm", children: [
173
+ /* @__PURE__ */ jsx("span", { className: "font-medium", children: "Sort by" }),
174
+ /* @__PURE__ */ jsx(
175
+ InputControl_default,
176
+ {
177
+ name: "sortOptions",
178
+ controlType: InputControlType_default.select,
179
+ value: currentSort,
180
+ dataset: normalizedSortOptions,
181
+ dataKeyFieldName: "value",
182
+ dataTextFieldName: "label",
183
+ callback: (updatedValues) => navigateWithoutReload(
184
+ getQueryUrl({
185
+ $orderby: updatedValues.value || void 0,
186
+ orderBy: void 0
187
+ })
188
+ ),
189
+ attributes: { placeholder: "Default" },
190
+ inputClasses: "!mt-0 min-w-44"
191
+ }
192
+ )
193
+ ] })
194
+ ] }),
195
+ shouldShowFacets && facetGroups.length === 1 && /* @__PURE__ */ jsx("nav", { "aria-label": `${humanize(facetGroups[0][0])} filters`, children: renderFacetLinks(facetGroups[0][0], facetGroups[0][1]) }),
196
+ shouldShowFacets && facetGroups.length > 1 && /* @__PURE__ */ jsx("div", { className: "flex flex-col gap-2", children: facetGroups.map(([field, values]) => /* @__PURE__ */ jsxs("details", { className: "border-b", open: true, children: [
197
+ /* @__PURE__ */ jsx("summary", { className: "cursor-pointer font-semibold", children: humanize(field) }),
198
+ /* @__PURE__ */ jsx("div", { className: "p-2", children: renderFacetLinks(field, values, true) })
199
+ ] }, field)) })
200
+ ] });
201
+ };
202
+ var DataBindingControls_default = DataBindingControls;
203
+ export {
204
+ DataBindingControls_default as default
205
+ };
@@ -0,0 +1,209 @@
1
+ "use client";
2
+ import {
3
+ InputControlType_default
4
+ } from "./chunk-4R7F7LBL.mjs";
5
+
6
+ // src/components/pageRenderingEngine/nodes/DataBindingControls.tsx
7
+ import { useCallback, useEffect, useRef, useState } from "react";
8
+ import { useRouter } from "next/navigation";
9
+
10
+ // src/components/controls/edit/InputControl.tsx
11
+ import dynamic from "next/dynamic";
12
+ var InputControl = dynamic(() => import("./InputControlClient-AORN4DRF.mjs"), {
13
+ ssr: false
14
+ });
15
+ var InputControl_default = InputControl;
16
+
17
+ // src/components/pageRenderingEngine/nodes/DataBindingControls.tsx
18
+ import { jsx, jsxs } from "react/jsx-runtime";
19
+ var humanize = (value) => value.replace(/([a-z0-9])([A-Z])/g, "$1 $2").replace(/[_-]+/g, " ").trim();
20
+ var escapeODataString = (value) => value.replace(/'/g, "''");
21
+ var normalizeSortOption = (option) => {
22
+ const direction = option.direction.trim();
23
+ return {
24
+ label: option.title || humanize(option.name),
25
+ value: [option.name, direction].filter(Boolean).join(" ")
26
+ };
27
+ };
28
+ var DUMMY_FACETS = {
29
+ CategoryTitle: [
30
+ { value: "Career Readiness", count: 2 },
31
+ { value: "Student Learning", count: 2 }
32
+ ],
33
+ Author: [
34
+ { value: "John Smith", count: 2 },
35
+ { value: "Sarah Jones", count: 1 },
36
+ { value: "Emily Brown", count: 1 }
37
+ ]
38
+ };
39
+ var DUMMY_SORT_OPTIONS = [
40
+ { name: "createdDate", title: "Newest First", direction: "desc" },
41
+ { name: "createdDate", title: "Oldest First", direction: "asc" },
42
+ { name: "title", title: "Title A-Z", direction: "asc" },
43
+ { name: "title", title: "Title Z-A", direction: "desc" }
44
+ ];
45
+ var DataBindingControls = ({
46
+ path,
47
+ query,
48
+ facets,
49
+ sortOptions,
50
+ showFacets,
51
+ showSortOptions,
52
+ showSearchBar,
53
+ mode = "toolbar"
54
+ }) => {
55
+ const router = useRouter();
56
+ const apiFacetGroups = Object.entries(facets ?? {}).filter(
57
+ ([, values]) => Array.isArray(values) && values.length > 0
58
+ );
59
+ const facetGroups = apiFacetGroups.length > 0 ? apiFacetGroups : Object.entries(DUMMY_FACETS);
60
+ const apiSortOptions = (sortOptions ?? []).filter(
61
+ (option) => option?.name && option?.direction
62
+ );
63
+ const resolvedSortOptions = apiSortOptions.length > 0 ? apiSortOptions : DUMMY_SORT_OPTIONS;
64
+ const normalizedSortOptions = resolvedSortOptions.map(normalizeSortOption).filter((option) => option.value);
65
+ const currentFilter = query?.["$filter"] ?? query?.filter ?? "";
66
+ const currentSort = query?.["$orderby"] ?? query?.orderBy ?? "";
67
+ const currentSearch = query?.searchTerm ?? query?.searchText ?? "";
68
+ const [searchText, setSearchText] = useState(currentSearch);
69
+ const lastNavigationUrl = useRef(null);
70
+ useEffect(() => {
71
+ setSearchText(currentSearch);
72
+ }, [currentSearch]);
73
+ const getQueryUrl = useCallback(
74
+ (updates) => {
75
+ const params = new URLSearchParams(query ?? {});
76
+ Object.entries(updates).forEach(([key, value]) => {
77
+ if (value) {
78
+ params.set(key, value);
79
+ } else {
80
+ params.delete(key);
81
+ }
82
+ });
83
+ params.delete("$skip");
84
+ params.delete("skip");
85
+ const queryString = params.toString();
86
+ return queryString ? `${path}?${queryString}` : path;
87
+ },
88
+ [path, query]
89
+ );
90
+ const getFacetUrl = (field, value) => getQueryUrl({
91
+ $filter: value ? `${field} eq '${escapeODataString(value)}'` : void 0,
92
+ filter: void 0
93
+ });
94
+ const navigateWithoutReload = useCallback(
95
+ (url) => {
96
+ if (lastNavigationUrl.current === url) {
97
+ return;
98
+ }
99
+ if (typeof window !== "undefined") {
100
+ const targetUrl = new URL(url, window.location.origin);
101
+ if (targetUrl.pathname === window.location.pathname && targetUrl.search === window.location.search) {
102
+ return;
103
+ }
104
+ }
105
+ lastNavigationUrl.current = url;
106
+ router.push(url, { scroll: false });
107
+ },
108
+ [router]
109
+ );
110
+ useEffect(() => {
111
+ const trimmedSearchText = searchText.trim();
112
+ if (trimmedSearchText === currentSearch.trim()) {
113
+ return;
114
+ }
115
+ const timeout = window.setTimeout(() => {
116
+ navigateWithoutReload(
117
+ getQueryUrl({
118
+ searchTerm: trimmedSearchText || void 0,
119
+ searchText: void 0
120
+ })
121
+ );
122
+ }, 500);
123
+ return () => window.clearTimeout(timeout);
124
+ }, [currentSearch, getQueryUrl, navigateWithoutReload, searchText]);
125
+ const hasFacetControls = showFacets && facetGroups.length > 0;
126
+ const hasSortControls = showSortOptions && normalizedSortOptions.length > 0;
127
+ const shouldShowToolbar = mode === "toolbar" && (showSearchBar || hasSortControls);
128
+ const shouldShowFacets = mode === "facets" && hasFacetControls;
129
+ if (!shouldShowToolbar && !shouldShowFacets) {
130
+ return null;
131
+ }
132
+ const renderFacetLinks = (field, values, stacked = false) => /* @__PURE__ */ jsxs("div", { className: stacked ? "flex flex-col gap-1" : "flex flex-wrap gap-2", children: [
133
+ /* @__PURE__ */ jsx(
134
+ "button",
135
+ {
136
+ type: "button",
137
+ onClick: () => navigateWithoutReload(getFacetUrl(field)),
138
+ "aria-pressed": !currentFilter,
139
+ className: `px-3 py-2 text-left text-sm ${stacked ? "w-full" : "border"} ${currentFilter ? "" : "bg-primary-base font-semibold"}`,
140
+ children: "All"
141
+ }
142
+ ),
143
+ values.map((facet) => {
144
+ const filter = `${field} eq '${escapeODataString(facet.value)}'`;
145
+ return /* @__PURE__ */ jsxs(
146
+ "button",
147
+ {
148
+ type: "button",
149
+ onClick: () => navigateWithoutReload(getFacetUrl(field, facet.value)),
150
+ "aria-pressed": currentFilter === filter,
151
+ className: `px-3 py-2 text-left text-sm ${stacked ? "w-full" : "border"} ${currentFilter === filter ? "bg-primary-base font-semibold" : ""}`,
152
+ children: [
153
+ facet.value,
154
+ " (",
155
+ facet.count,
156
+ ")"
157
+ ]
158
+ },
159
+ `${field}-${facet.value}`
160
+ );
161
+ })
162
+ ] });
163
+ return /* @__PURE__ */ jsxs("div", { className: mode === "toolbar" ? "mb-6" : "flex flex-col gap-2", children: [
164
+ shouldShowToolbar && /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-3 md:flex-row md:items-center md:justify-between", children: [
165
+ showSearchBar && /* @__PURE__ */ jsx("div", { className: "w-full max-w-xl", children: /* @__PURE__ */ jsx(
166
+ InputControl_default,
167
+ {
168
+ name: "searchText",
169
+ controlType: InputControlType_default.lineTextInput,
170
+ value: searchText,
171
+ callback: (updatedValues) => setSearchText(updatedValues.value),
172
+ attributes: { placeholder: "Search" },
173
+ inputClasses: "!mt-0"
174
+ }
175
+ ) }),
176
+ hasSortControls && /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 text-sm", children: [
177
+ /* @__PURE__ */ jsx("span", { className: "font-medium", children: "Sort by" }),
178
+ /* @__PURE__ */ jsx(
179
+ InputControl_default,
180
+ {
181
+ name: "sortOptions",
182
+ controlType: InputControlType_default.select,
183
+ value: currentSort,
184
+ dataset: normalizedSortOptions,
185
+ dataKeyFieldName: "value",
186
+ dataTextFieldName: "label",
187
+ callback: (updatedValues) => navigateWithoutReload(
188
+ getQueryUrl({
189
+ $orderby: updatedValues.value || void 0,
190
+ orderBy: void 0
191
+ })
192
+ ),
193
+ attributes: { placeholder: "Default" },
194
+ inputClasses: "!mt-0 min-w-44"
195
+ }
196
+ )
197
+ ] })
198
+ ] }),
199
+ shouldShowFacets && facetGroups.length === 1 && /* @__PURE__ */ jsx("nav", { "aria-label": `${humanize(facetGroups[0][0])} filters`, children: renderFacetLinks(facetGroups[0][0], facetGroups[0][1]) }),
200
+ shouldShowFacets && facetGroups.length > 1 && /* @__PURE__ */ jsx("div", { className: "flex flex-col gap-2", children: facetGroups.map(([field, values]) => /* @__PURE__ */ jsxs("details", { className: "border-b", open: true, children: [
201
+ /* @__PURE__ */ jsx("summary", { className: "cursor-pointer font-semibold", children: humanize(field) }),
202
+ /* @__PURE__ */ jsx("div", { className: "p-2", children: renderFacetLinks(field, values, true) })
203
+ ] }, field)) })
204
+ ] });
205
+ };
206
+ var DataBindingControls_default = DataBindingControls;
207
+ export {
208
+ DataBindingControls_default as default
209
+ };
@@ -21,12 +21,14 @@ import {
21
21
  Select_default,
22
22
  Switcher_default,
23
23
  TimeInput_default
24
- } from "./chunk-65QPOTZ4.mjs";
24
+ } from "./chunk-GJOJX2O3.mjs";
25
25
  import {
26
26
  Hyperlink,
27
- Icon_default,
27
+ Icon_default
28
+ } from "./chunk-GCG4OYDJ.mjs";
29
+ import {
28
30
  InputControlType_default
29
- } from "./chunk-YDPISYMP.mjs";
31
+ } from "./chunk-E4VOFO5Q.mjs";
30
32
  import {
31
33
  Button_default,
32
34
  ClientButton_default