@acoustte-digital-services/digitalstore-controls-dev 0.8.1-dev.20260707162731 → 0.8.1-dev.20260708070033

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.
@@ -22,7 +22,7 @@ import {
22
22
  Hyperlink,
23
23
  Icon_default,
24
24
  InputControlType_default
25
- } from "./chunk-2GSYECIS.mjs";
25
+ } from "./chunk-FI2KJBK2.mjs";
26
26
  import {
27
27
  Button_default,
28
28
  ClientButton_default
@@ -30,7 +30,7 @@ import {
30
30
  import "./chunk-IMNQO57B.mjs";
31
31
 
32
32
  // src/components/controls/edit/InputControlClient.tsx
33
- import React4 from "react";
33
+ import React5 from "react";
34
34
 
35
35
  // src/components/controls/edit/Select.tsx
36
36
  import { useState, useEffect } from "react";
@@ -570,9 +570,81 @@ var AssetUpload = (props) => {
570
570
  };
571
571
  var AssetUpload_default = AssetUpload;
572
572
 
573
+ // src/components/controls/edit/SwitchInput.tsx
574
+ import React4 from "react";
575
+ import { jsx as jsx4, jsxs as jsxs4 } from "react/jsx-runtime";
576
+ var SwitchInput = (props) => {
577
+ const textChangeHandler = (event) => {
578
+ let text = event.target.checked;
579
+ if (props.callback !== void 0) {
580
+ props.callback({
581
+ name: props.name,
582
+ value: text,
583
+ index: props.index,
584
+ groupKey: props.groupKey
585
+ });
586
+ }
587
+ };
588
+ let value = false;
589
+ if (props.value != void 0 && props.value != null && props.value != "" && (props.value == "true" || props.value.toString() == "true")) {
590
+ value = true;
591
+ }
592
+ return /* @__PURE__ */ jsx4(React4.Fragment, { children: /* @__PURE__ */ jsxs4("div", { className: "flex items-start justify-between gap-4 py-3", children: [
593
+ /* @__PURE__ */ jsxs4("div", { className: "min-w-0", children: [
594
+ props?.attributes?.label && /* @__PURE__ */ jsxs4(
595
+ "label",
596
+ {
597
+ htmlFor: props.name,
598
+ className: "inline-block text-sm font-semibold text-slate-800",
599
+ children: [
600
+ props.attributes.label,
601
+ props?.attributes?.required && /* @__PURE__ */ jsx4("span", { className: "bg-error-weak", children: "*" })
602
+ ]
603
+ }
604
+ ),
605
+ /* @__PURE__ */ jsx4("p", { className: "hidden group-[.validated]:peer-invalid:block mt-1 bg-error-weak text-sm", children: props?.attributes?.errorMessage || "" })
606
+ ] }),
607
+ /* @__PURE__ */ jsxs4(
608
+ "label",
609
+ {
610
+ htmlFor: props.name,
611
+ className: "relative inline-flex shrink-0 cursor-pointer items-center peer-disabled:cursor-not-allowed",
612
+ children: [
613
+ /* @__PURE__ */ jsx4(
614
+ "input",
615
+ {
616
+ type: "checkbox",
617
+ name: props.name,
618
+ id: props.name,
619
+ checked: value,
620
+ onChange: textChangeHandler,
621
+ required: props?.attributes?.required,
622
+ disabled: props?.attributes?.readOnly,
623
+ className: "peer sr-only"
624
+ }
625
+ ),
626
+ /* @__PURE__ */ jsx4(
627
+ "div",
628
+ {
629
+ className: "h-6 w-11 rounded-full bg-slate-200 shadow-inner\n transition-colors duration-200 ease-in-out\n peer-checked:bg-blue-600\n peer-focus-visible:ring-2 peer-focus-visible:ring-blue-300 peer-focus-visible:ring-offset-2\n peer-disabled:bg-slate-100"
630
+ }
631
+ ),
632
+ /* @__PURE__ */ jsx4(
633
+ "div",
634
+ {
635
+ className: "absolute left-0.5 top-0.5 h-5 w-5 rounded-full bg-default shadow\n transition-transform duration-200 ease-in-out\n peer-checked:translate-x-5\n peer-disabled:bg-slate-50"
636
+ }
637
+ )
638
+ ]
639
+ }
640
+ )
641
+ ] }) });
642
+ };
643
+ var SwitchInput_default = SwitchInput;
644
+
573
645
  // src/components/controls/edit/InputControlClient.tsx
574
- import { jsx as jsx4 } from "react/jsx-runtime";
575
- var InputControl = React4.forwardRef(
646
+ import { jsx as jsx5 } from "react/jsx-runtime";
647
+ var InputControl = React5.forwardRef(
576
648
  (props, ref) => {
577
649
  const ControlComponents = {
578
650
  [InputControlType_default.lineTextInput]: LineTextInput_default,
@@ -591,10 +663,11 @@ var InputControl = React4.forwardRef(
591
663
  [InputControlType_default.selectWithSearchPanel]: SelectWithSearchPanel_default,
592
664
  [InputControlType_default.booleanSelect]: BooleanSelect_default,
593
665
  [InputControlType_default.timeInput]: TimeInput_default,
594
- [InputControlType_default.asset]: AssetUpload_default
666
+ [InputControlType_default.asset]: AssetUpload_default,
667
+ [InputControlType_default.switchInput]: SwitchInput_default
595
668
  };
596
669
  const SelectedControlComponent = ControlComponents[props.controlType];
597
- return /* @__PURE__ */ jsx4(React4.Fragment, { children: SelectedControlComponent ? /* @__PURE__ */ jsx4(SelectedControlComponent, { ...props }) : "Control not found" });
670
+ return /* @__PURE__ */ jsx5(React5.Fragment, { children: SelectedControlComponent ? /* @__PURE__ */ jsx5(SelectedControlComponent, { ...props }) : "Control not found" });
598
671
  }
599
672
  );
600
673
  InputControl.displayName = "InputControl";
@@ -20,7 +20,7 @@ import {
20
20
  Hyperlink,
21
21
  Icon_default,
22
22
  InputControlType_default
23
- } from "./chunk-CM7LUGCH.mjs";
23
+ } from "./chunk-UWFXFVUU.mjs";
24
24
  import {
25
25
  Button_default,
26
26
  ClientButton_default
@@ -28,7 +28,7 @@ import {
28
28
  import "./chunk-56HSDML5.mjs";
29
29
 
30
30
  // src/components/controls/edit/InputControlClient.tsx
31
- import React4 from "react";
31
+ import React5 from "react";
32
32
 
33
33
  // src/components/controls/edit/Select.tsx
34
34
  import { useState, useEffect } from "react";
@@ -568,9 +568,81 @@ var AssetUpload = (props) => {
568
568
  };
569
569
  var AssetUpload_default = AssetUpload;
570
570
 
571
+ // src/components/controls/edit/SwitchInput.tsx
572
+ import React4 from "react";
573
+ import { jsx as jsx4, jsxs as jsxs4 } from "react/jsx-runtime";
574
+ var SwitchInput = (props) => {
575
+ const textChangeHandler = (event) => {
576
+ let text = event.target.checked;
577
+ if (props.callback !== void 0) {
578
+ props.callback({
579
+ name: props.name,
580
+ value: text,
581
+ index: props.index,
582
+ groupKey: props.groupKey
583
+ });
584
+ }
585
+ };
586
+ let value = false;
587
+ if (props.value != void 0 && props.value != null && props.value != "" && (props.value == "true" || props.value.toString() == "true")) {
588
+ value = true;
589
+ }
590
+ return /* @__PURE__ */ jsx4(React4.Fragment, { children: /* @__PURE__ */ jsxs4("div", { className: "flex items-start justify-between gap-4 py-3", children: [
591
+ /* @__PURE__ */ jsxs4("div", { className: "min-w-0", children: [
592
+ props?.attributes?.label && /* @__PURE__ */ jsxs4(
593
+ "label",
594
+ {
595
+ htmlFor: props.name,
596
+ className: "inline-block text-sm font-semibold text-slate-800",
597
+ children: [
598
+ props.attributes.label,
599
+ props?.attributes?.required && /* @__PURE__ */ jsx4("span", { className: "bg-error-weak", children: "*" })
600
+ ]
601
+ }
602
+ ),
603
+ /* @__PURE__ */ jsx4("p", { className: "hidden group-[.validated]:peer-invalid:block mt-1 bg-error-weak text-sm", children: props?.attributes?.errorMessage || "" })
604
+ ] }),
605
+ /* @__PURE__ */ jsxs4(
606
+ "label",
607
+ {
608
+ htmlFor: props.name,
609
+ className: "relative inline-flex shrink-0 cursor-pointer items-center peer-disabled:cursor-not-allowed",
610
+ children: [
611
+ /* @__PURE__ */ jsx4(
612
+ "input",
613
+ {
614
+ type: "checkbox",
615
+ name: props.name,
616
+ id: props.name,
617
+ checked: value,
618
+ onChange: textChangeHandler,
619
+ required: props?.attributes?.required,
620
+ disabled: props?.attributes?.readOnly,
621
+ className: "peer sr-only"
622
+ }
623
+ ),
624
+ /* @__PURE__ */ jsx4(
625
+ "div",
626
+ {
627
+ className: "h-6 w-11 rounded-full bg-slate-200 shadow-inner\n transition-colors duration-200 ease-in-out\n peer-checked:bg-blue-600\n peer-focus-visible:ring-2 peer-focus-visible:ring-blue-300 peer-focus-visible:ring-offset-2\n peer-disabled:bg-slate-100"
628
+ }
629
+ ),
630
+ /* @__PURE__ */ jsx4(
631
+ "div",
632
+ {
633
+ className: "absolute left-0.5 top-0.5 h-5 w-5 rounded-full bg-default shadow\n transition-transform duration-200 ease-in-out\n peer-checked:translate-x-5\n peer-disabled:bg-slate-50"
634
+ }
635
+ )
636
+ ]
637
+ }
638
+ )
639
+ ] }) });
640
+ };
641
+ var SwitchInput_default = SwitchInput;
642
+
571
643
  // src/components/controls/edit/InputControlClient.tsx
572
- import { jsx as jsx4 } from "react/jsx-runtime";
573
- var InputControl = React4.forwardRef(
644
+ import { jsx as jsx5 } from "react/jsx-runtime";
645
+ var InputControl = React5.forwardRef(
574
646
  (props, ref) => {
575
647
  const ControlComponents = {
576
648
  [InputControlType_default.lineTextInput]: LineTextInput_default,
@@ -589,10 +661,11 @@ var InputControl = React4.forwardRef(
589
661
  [InputControlType_default.selectWithSearchPanel]: SelectWithSearchPanel_default,
590
662
  [InputControlType_default.booleanSelect]: BooleanSelect_default,
591
663
  [InputControlType_default.timeInput]: TimeInput_default,
592
- [InputControlType_default.asset]: AssetUpload_default
664
+ [InputControlType_default.asset]: AssetUpload_default,
665
+ [InputControlType_default.switchInput]: SwitchInput_default
593
666
  };
594
667
  const SelectedControlComponent = ControlComponents[props.controlType];
595
- return /* @__PURE__ */ jsx4(React4.Fragment, { children: SelectedControlComponent ? /* @__PURE__ */ jsx4(SelectedControlComponent, { ...props }) : "Control not found" });
668
+ return /* @__PURE__ */ jsx5(React5.Fragment, { children: SelectedControlComponent ? /* @__PURE__ */ jsx5(SelectedControlComponent, { ...props }) : "Control not found" });
596
669
  }
597
670
  );
598
671
  InputControl.displayName = "InputControl";
@@ -3,7 +3,8 @@ import {
3
3
  ServiceClient_default
4
4
  } from "./chunk-3GWLDT7C.mjs";
5
5
  import {
6
- Button_default
6
+ Button_default,
7
+ ToastService_default
7
8
  } from "./chunk-IKIXEQPV.mjs";
8
9
  import "./chunk-56HSDML5.mjs";
9
10
 
@@ -13,7 +14,6 @@ import { jsx } from "react/jsx-runtime";
13
14
  var LinkNodeButton = (props) => {
14
15
  const { node, dataitem, children, linkText, linkType, linkUrl } = props;
15
16
  const [isLoading, setIsLoading] = useState(false);
16
- const [error, setError] = useState(null);
17
17
  const extractFieldNames = useCallback((template) => {
18
18
  if (!template) return [];
19
19
  const regex = /\{(\{\})?([a-zA-Z_$][a-zA-Z0-9_$]*)(?:\}\})?\}/g;
@@ -67,11 +67,10 @@ var LinkNodeButton = (props) => {
67
67
  }, []);
68
68
  const onClick = useCallback(async (e) => {
69
69
  if (!node.postUrl) {
70
- setError("No POST URL configured for this button");
70
+ ToastService_default.showError("No POST URL configured for this button");
71
71
  return;
72
72
  }
73
73
  setIsLoading(true);
74
- setError(null);
75
74
  try {
76
75
  const resolvedPostUrl = replaceTemplateVariables(node.postUrl);
77
76
  let parsedPayload = {};
@@ -90,10 +89,12 @@ var LinkNodeButton = (props) => {
90
89
  console.log("API Response:", response);
91
90
  if (response && !response.isSuccessful) {
92
91
  const errorMessage = response.message || "API request failed";
93
- setError(errorMessage);
94
92
  setIsLoading(false);
95
93
  return { isSuccessful: false, message: errorMessage };
96
94
  }
95
+ if (response?.message) {
96
+ ToastService_default.showSuccess(response.message);
97
+ }
97
98
  if (response && node.redirectUrl) {
98
99
  const fieldNames = extractFieldNames(node.redirectUrl);
99
100
  console.log("Field names in redirect URL:", fieldNames);
@@ -131,19 +132,18 @@ var LinkNodeButton = (props) => {
131
132
  if (resolvedRedirectUrl && !resolvedRedirectUrl.includes("{")) {
132
133
  window.location.href = resolvedRedirectUrl;
133
134
  }
134
- } else if (response && !response.result && response.message) {
135
- setError(response.message);
136
- throw new Error(response.message);
137
135
  } else if (!response) {
138
- setError("No response from server");
136
+ const errorMessage = "No response from server";
137
+ setIsLoading(false);
138
+ return { isSuccessful: false, message: errorMessage };
139
139
  }
140
140
  setIsLoading(false);
141
- return { isSuccessful: true, response };
141
+ return { isSuccessful: true, message: response?.message, result: response };
142
142
  } catch (err) {
143
143
  console.error("Button API call failed:", err);
144
- setError(err.message || "An unexpected error occurred");
144
+ const errorMessage = err.message || "An unexpected error occurred";
145
145
  setIsLoading(false);
146
- return { isSuccessful: false, message: err.message };
146
+ return { isSuccessful: false, message: errorMessage };
147
147
  }
148
148
  }, [node.postUrl, node.payload, node.redirectUrl, replaceTemplateVariables, extractFieldNames, getNestedValue, props.apiBaseUrl, props.session]);
149
149
  const renderButtonContent = () => {
@@ -203,7 +203,6 @@ import { jsx as jsx4 } from "react/jsx-runtime";
203
203
  var LinkNodeButton = (props) => {
204
204
  const { node, dataitem, children, linkText, linkType, linkUrl } = props;
205
205
  const [isLoading, setIsLoading] = useState3(false);
206
- const [error, setError] = useState3(null);
207
206
  const extractFieldNames = useCallback((template) => {
208
207
  if (!template) return [];
209
208
  const regex = /\{(\{\})?([a-zA-Z_$][a-zA-Z0-9_$]*)(?:\}\})?\}/g;
@@ -257,11 +256,10 @@ var LinkNodeButton = (props) => {
257
256
  }, []);
258
257
  const onClick = useCallback(async (e) => {
259
258
  if (!node.postUrl) {
260
- setError("No POST URL configured for this button");
259
+ ToastService_default.showError("No POST URL configured for this button");
261
260
  return;
262
261
  }
263
262
  setIsLoading(true);
264
- setError(null);
265
263
  try {
266
264
  const resolvedPostUrl = replaceTemplateVariables(node.postUrl);
267
265
  let parsedPayload = {};
@@ -280,10 +278,12 @@ var LinkNodeButton = (props) => {
280
278
  console.log("API Response:", response);
281
279
  if (response && !response.isSuccessful) {
282
280
  const errorMessage = response.message || "API request failed";
283
- setError(errorMessage);
284
281
  setIsLoading(false);
285
282
  return { isSuccessful: false, message: errorMessage };
286
283
  }
284
+ if (response?.message) {
285
+ ToastService_default.showSuccess(response.message);
286
+ }
287
287
  if (response && node.redirectUrl) {
288
288
  const fieldNames = extractFieldNames(node.redirectUrl);
289
289
  console.log("Field names in redirect URL:", fieldNames);
@@ -321,19 +321,18 @@ var LinkNodeButton = (props) => {
321
321
  if (resolvedRedirectUrl && !resolvedRedirectUrl.includes("{")) {
322
322
  window.location.href = resolvedRedirectUrl;
323
323
  }
324
- } else if (response && !response.result && response.message) {
325
- setError(response.message);
326
- throw new Error(response.message);
327
324
  } else if (!response) {
328
- setError("No response from server");
325
+ const errorMessage = "No response from server";
326
+ setIsLoading(false);
327
+ return { isSuccessful: false, message: errorMessage };
329
328
  }
330
329
  setIsLoading(false);
331
- return { isSuccessful: true, response };
330
+ return { isSuccessful: true, message: response?.message, result: response };
332
331
  } catch (err) {
333
332
  console.error("Button API call failed:", err);
334
- setError(err.message || "An unexpected error occurred");
333
+ const errorMessage = err.message || "An unexpected error occurred";
335
334
  setIsLoading(false);
336
- return { isSuccessful: false, message: err.message };
335
+ return { isSuccessful: false, message: errorMessage };
337
336
  }
338
337
  }, [node.postUrl, node.payload, node.redirectUrl, replaceTemplateVariables, extractFieldNames, getNestedValue, props.apiBaseUrl, props.session]);
339
338
  const renderButtonContent = () => {
@@ -5,7 +5,8 @@ import {
5
5
  ServiceClient_default
6
6
  } from "./chunk-WEV5U33G.mjs";
7
7
  import {
8
- Button_default
8
+ Button_default,
9
+ ToastService_default
9
10
  } from "./chunk-67IG5NBU.mjs";
10
11
  import "./chunk-IMNQO57B.mjs";
11
12
 
@@ -15,7 +16,6 @@ import { jsx } from "react/jsx-runtime";
15
16
  var LinkNodeButton = (props) => {
16
17
  const { node, dataitem, children, linkText, linkType, linkUrl } = props;
17
18
  const [isLoading, setIsLoading] = useState(false);
18
- const [error, setError] = useState(null);
19
19
  const extractFieldNames = useCallback((template) => {
20
20
  if (!template) return [];
21
21
  const regex = /\{(\{\})?([a-zA-Z_$][a-zA-Z0-9_$]*)(?:\}\})?\}/g;
@@ -69,11 +69,10 @@ var LinkNodeButton = (props) => {
69
69
  }, []);
70
70
  const onClick = useCallback(async (e) => {
71
71
  if (!node.postUrl) {
72
- setError("No POST URL configured for this button");
72
+ ToastService_default.showError("No POST URL configured for this button");
73
73
  return;
74
74
  }
75
75
  setIsLoading(true);
76
- setError(null);
77
76
  try {
78
77
  const resolvedPostUrl = replaceTemplateVariables(node.postUrl);
79
78
  let parsedPayload = {};
@@ -92,10 +91,12 @@ var LinkNodeButton = (props) => {
92
91
  console.log("API Response:", response);
93
92
  if (response && !response.isSuccessful) {
94
93
  const errorMessage = response.message || "API request failed";
95
- setError(errorMessage);
96
94
  setIsLoading(false);
97
95
  return { isSuccessful: false, message: errorMessage };
98
96
  }
97
+ if (response?.message) {
98
+ ToastService_default.showSuccess(response.message);
99
+ }
99
100
  if (response && node.redirectUrl) {
100
101
  const fieldNames = extractFieldNames(node.redirectUrl);
101
102
  console.log("Field names in redirect URL:", fieldNames);
@@ -133,19 +134,18 @@ var LinkNodeButton = (props) => {
133
134
  if (resolvedRedirectUrl && !resolvedRedirectUrl.includes("{")) {
134
135
  window.location.href = resolvedRedirectUrl;
135
136
  }
136
- } else if (response && !response.result && response.message) {
137
- setError(response.message);
138
- throw new Error(response.message);
139
137
  } else if (!response) {
140
- setError("No response from server");
138
+ const errorMessage = "No response from server";
139
+ setIsLoading(false);
140
+ return { isSuccessful: false, message: errorMessage };
141
141
  }
142
142
  setIsLoading(false);
143
- return { isSuccessful: true, response };
143
+ return { isSuccessful: true, message: response?.message, result: response };
144
144
  } catch (err) {
145
145
  console.error("Button API call failed:", err);
146
- setError(err.message || "An unexpected error occurred");
146
+ const errorMessage = err.message || "An unexpected error occurred";
147
147
  setIsLoading(false);
148
- return { isSuccessful: false, message: err.message };
148
+ return { isSuccessful: false, message: errorMessage };
149
149
  }
150
150
  }, [node.postUrl, node.payload, node.redirectUrl, replaceTemplateVariables, extractFieldNames, getNestedValue, props.apiBaseUrl, props.session]);
151
151
  const renderButtonContent = () => {
@@ -1,12 +1,12 @@
1
1
  "use client";
2
2
  import {
3
3
  OdataBuilder
4
- } from "./chunk-47HD7QP7.mjs";
4
+ } from "./chunk-FYGNBMII.mjs";
5
5
  import {
6
6
  Constants,
7
7
  Hyperlink,
8
8
  Icon_default
9
- } from "./chunk-CM7LUGCH.mjs";
9
+ } from "./chunk-UWFXFVUU.mjs";
10
10
  import "./chunk-56HSDML5.mjs";
11
11
 
12
12
  // src/components/Pagination.tsx
@@ -0,0 +1,183 @@
1
+ "use client";
2
+
3
+ "use client";
4
+ import {
5
+ OdataBuilder
6
+ } from "./chunk-OGGIS4AN.mjs";
7
+ import {
8
+ Constants,
9
+ Hyperlink,
10
+ Icon_default
11
+ } from "./chunk-FI2KJBK2.mjs";
12
+ import "./chunk-IMNQO57B.mjs";
13
+
14
+ // src/components/Pagination.tsx
15
+ import { useMemo } from "react";
16
+ import { jsx, jsxs } from "react/jsx-runtime";
17
+ var Pagination = (props) => {
18
+ const { dataset, path, query, showPageSizeSelector = false, showJumpToPage = false } = props;
19
+ const builder = useMemo(() => {
20
+ const b = new OdataBuilder(path);
21
+ if (query) b.setQuery(query);
22
+ return b;
23
+ }, [path, query]);
24
+ const activePageNumber = builder.getPageNumber(Constants.pagesize);
25
+ const totalItems = dataset?.count || 0;
26
+ const itemsPerPage = parseInt(builder.top || Constants.pagesize.toString());
27
+ const totalPages = Math.ceil(totalItems / itemsPerPage);
28
+ const startItem = totalItems > 0 ? (activePageNumber - 1) * itemsPerPage + 1 : 0;
29
+ const endItem = Math.min(activePageNumber * itemsPerPage, totalItems);
30
+ const getPaginationRange = () => {
31
+ const delta = 1;
32
+ const range = [];
33
+ if (totalPages <= 7) {
34
+ return Array.from({ length: totalPages }, (_, i) => i + 1);
35
+ }
36
+ range.push(1);
37
+ let start = Math.max(2, activePageNumber - delta);
38
+ let end = Math.min(totalPages - 1, activePageNumber + delta);
39
+ if (activePageNumber - delta <= 2) {
40
+ end = Math.min(totalPages - 1, 4);
41
+ }
42
+ if (activePageNumber + delta >= totalPages - 1) {
43
+ start = Math.max(2, totalPages - 4);
44
+ }
45
+ if (start > 2) {
46
+ range.push("...");
47
+ }
48
+ for (let i = start; i <= end; i++) {
49
+ range.push(i);
50
+ }
51
+ if (end < totalPages - 1) {
52
+ range.push("...");
53
+ }
54
+ if (totalPages > 1) {
55
+ range.push(totalPages);
56
+ }
57
+ return range;
58
+ };
59
+ const paginationRange = getPaginationRange();
60
+ const PageButton = ({ page, children }) => /* @__PURE__ */ jsx(
61
+ Hyperlink,
62
+ {
63
+ linkType: "Link" /* Link */,
64
+ className: `
65
+ min-w-[20px] md:min-w-[40px] h-10 flex items-center justify-center px-2.5 md:px-3
66
+ border text-sm font-medium transition-colors duration-150
67
+ ${activePageNumber === page ? "bg-primary-base font-semibold" : ""}
68
+ `,
69
+ href: builder.getNewPageUrl(page),
70
+ children
71
+ }
72
+ );
73
+ const NavigationButton = ({ page, disabled, children }) => {
74
+ if (disabled) {
75
+ return /* @__PURE__ */ jsx("span", { className: "min-w-[20px] md:min-w-[40px] h-10 flex items-center justify-center px-2 md:px-3 border bg-neutral-base cursor-not-allowed", children });
76
+ }
77
+ return /* @__PURE__ */ jsx(
78
+ Hyperlink,
79
+ {
80
+ className: "min-w-[20px] md:min-w-[40px] h-10 flex items-center justify-center px-2 md:px-3 border transition-colors duration-150",
81
+ href: builder.getNewPageUrl(page),
82
+ children
83
+ }
84
+ );
85
+ };
86
+ if (totalPages <= 1 && totalItems === 0) return null;
87
+ return /* @__PURE__ */ jsxs("div", { className: "py-6 border-t bg-default", children: [
88
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-col sm:flex-row items-center justify-between gap-4", children: [
89
+ /* @__PURE__ */ jsxs("div", { className: "text-sm", children: [
90
+ "Showing ",
91
+ /* @__PURE__ */ jsxs("span", { className: "font-semibold", children: [
92
+ startItem,
93
+ "-",
94
+ endItem
95
+ ] }),
96
+ " ",
97
+ "out of ",
98
+ /* @__PURE__ */ jsx("span", { className: "font-semibold", children: totalItems.toLocaleString() }),
99
+ " results"
100
+ ] }),
101
+ totalPages > 1 && /* @__PURE__ */ jsxs("div", { className: "flex items-center space-x-1", children: [
102
+ /* @__PURE__ */ jsxs(
103
+ NavigationButton,
104
+ {
105
+ page: activePageNumber - 1,
106
+ disabled: activePageNumber === 1,
107
+ children: [
108
+ /* @__PURE__ */ jsx("span", { children: /* @__PURE__ */ jsx(Icon_default, { name: "chevronLeft", className: "w-4 h-4 mr-1" }) }),
109
+ /* @__PURE__ */ jsx("span", { className: "text-sm", children: "Prev" })
110
+ ]
111
+ }
112
+ ),
113
+ paginationRange.map((item, index) => {
114
+ if (item === "...") {
115
+ return /* @__PURE__ */ jsx(
116
+ "span",
117
+ {
118
+ className: "min-w-[20px] md:min-w-[40px] h-10 flex items-center justify-center text-gray-500",
119
+ children: "..."
120
+ },
121
+ `ellipsis-${index}`
122
+ );
123
+ }
124
+ const page = item;
125
+ return /* @__PURE__ */ jsx(PageButton, { page, children: page }, page);
126
+ }),
127
+ /* @__PURE__ */ jsxs(
128
+ NavigationButton,
129
+ {
130
+ page: activePageNumber + 1,
131
+ disabled: activePageNumber === totalPages,
132
+ children: [
133
+ /* @__PURE__ */ jsx("span", { className: "text-sm", children: "Next" }),
134
+ /* @__PURE__ */ jsx("span", { children: /* @__PURE__ */ jsx(Icon_default, { name: "chevronRight", className: "w-4 h-4 ml-1" }) })
135
+ ]
136
+ }
137
+ )
138
+ ] }),
139
+ showJumpToPage && totalPages > 5 && /* @__PURE__ */ jsxs("div", { className: "flex items-center space-x-2", children: [
140
+ /* @__PURE__ */ jsx("span", { className: "text-sm", children: "Go to:" }),
141
+ /* @__PURE__ */ jsx("div", { className: "relative", children: /* @__PURE__ */ jsx(
142
+ "input",
143
+ {
144
+ type: "number",
145
+ min: "1",
146
+ max: totalPages,
147
+ defaultValue: activePageNumber,
148
+ className: "w-20 h-10 px-3 border rounded text-sm focus:outline-none focus:ring-2 focus:border-transparent",
149
+ onKeyDown: (e) => {
150
+ if (e.key === "Enter") {
151
+ const input = e.target;
152
+ const page = parseInt(input.value);
153
+ if (page >= 1 && page <= totalPages && page !== activePageNumber) {
154
+ window.location.href = builder.getNewPageUrl(page);
155
+ }
156
+ }
157
+ }
158
+ }
159
+ ) })
160
+ ] })
161
+ ] }),
162
+ showPageSizeSelector && /* @__PURE__ */ jsx("div", { className: "mt-4 pt-4 border-t bg-default", children: /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-center space-x-2", children: [
163
+ /* @__PURE__ */ jsx("span", { className: "text-sm", children: "Show:" }),
164
+ /* @__PURE__ */ jsx("div", { className: "flex space-x-1", children: [10, 25, 50, 100].map((size) => /* @__PURE__ */ jsx(
165
+ Hyperlink,
166
+ {
167
+ className: `
168
+ px-3 py-1 text-sm rounded border transition-colors duration-150
169
+ ${itemsPerPage === size ? "bg-primary-base font-medium" : "bg-neutral-weak"}
170
+ `,
171
+ href: builder.getNewPageSizeUrl(size),
172
+ children: size
173
+ },
174
+ size
175
+ )) }),
176
+ /* @__PURE__ */ jsx("span", { className: "text-sm", children: "per page" })
177
+ ] }) })
178
+ ] });
179
+ };
180
+ var Pagination_default = Pagination;
181
+ export {
182
+ Pagination_default as default
183
+ };