@appcorp/stellar-solutions-modules 0.1.53 → 0.1.55
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/global-modules/bank/bank.js +4 -8
- package/global-modules/bank/context.js +15 -14
- package/global-modules/bank/drawer.js +2 -2
- package/global-modules/bank/form.js +2 -2
- package/global-modules/bank/types.d.ts +1 -1
- package/global-modules/branch/branch.js +3 -7
- package/global-modules/branch/constants.d.ts +0 -11
- package/global-modules/branch/constants.js +1 -15
- package/global-modules/branch/context.js +16 -15
- package/global-modules/branch/drawer.js +2 -2
- package/global-modules/branch/form.js +2 -2
- package/global-modules/branch/types.d.ts +1 -1
- package/global-modules/payment-mode/context.js +16 -15
- package/global-modules/payment-mode/drawer.js +2 -2
- package/global-modules/payment-mode/form.js +2 -2
- package/global-modules/payment-mode/payment-mode.js +16 -20
- package/global-modules/payment-mode/types.d.ts +1 -1
- package/global-modules/preferences/context.js +14 -13
- package/global-modules/preferences/currency.js +2 -2
- package/global-modules/tax/context.js +16 -15
- package/global-modules/tax/drawer.js +2 -2
- package/global-modules/tax/form.js +2 -2
- package/global-modules/tax/tax.js +4 -8
- package/global-modules/tax/types.d.ts +1 -1
- package/index.d.ts +0 -30
- package/index.js +0 -46
- package/lib/toast-utils.d.ts +0 -44
- package/lib/toast-utils.js +240 -212
- package/lib/utils.d.ts +0 -2
- package/lib/utils.js +5 -12
- package/package.json +6 -7
- package/components/theme-provider.d.ts +0 -9
- package/components/theme-provider.js +0 -122
- package/components/theme-switcher.d.ts +0 -4
- package/components/theme-switcher.js +0 -60
- package/components/ui/badge.d.ts +0 -9
- package/components/ui/badge.js +0 -82
- package/components/ui/button.d.ts +0 -10
- package/components/ui/button.js +0 -91
- package/components/ui/card.d.ts +0 -9
- package/components/ui/card.js +0 -94
- package/components/ui/carousel.d.ts +0 -19
- package/components/ui/carousel.js +0 -168
- package/components/ui/checkbox.d.ts +0 -9
- package/components/ui/checkbox.js +0 -87
- package/components/ui/combobox.d.ts +0 -70
- package/components/ui/combobox.js +0 -315
- package/components/ui/command.d.ts +0 -18
- package/components/ui/command.js +0 -115
- package/components/ui/dialog.d.ts +0 -15
- package/components/ui/dialog.js +0 -118
- package/components/ui/drawer.d.ts +0 -13
- package/components/ui/drawer.js +0 -115
- package/components/ui/dropdown-menu.d.ts +0 -25
- package/components/ui/dropdown-menu.js +0 -148
- package/components/ui/enhanced-dropzone.d.ts +0 -21
- package/components/ui/enhanced-dropzone.js +0 -187
- package/components/ui/enhanced-table-footer-action.d.ts +0 -34
- package/components/ui/enhanced-table-footer-action.js +0 -117
- package/components/ui/enhanced-table-footer-page.d.ts +0 -32
- package/components/ui/enhanced-table-footer-page.js +0 -140
- package/components/ui/enhanced-table-footer-pagination.d.ts +0 -36
- package/components/ui/enhanced-table-footer-pagination.js +0 -122
- package/components/ui/enhanced-table-header-action.d.ts +0 -7
- package/components/ui/enhanced-table-header-action.js +0 -21
- package/components/ui/enhanced-table-header-search.d.ts +0 -12
- package/components/ui/enhanced-table-header-search.js +0 -17
- package/components/ui/enhanced-table.d.ts +0 -75
- package/components/ui/enhanced-table.js +0 -196
- package/components/ui/form.d.ts +0 -24
- package/components/ui/form.js +0 -125
- package/components/ui/input.d.ts +0 -8
- package/components/ui/input.js +0 -86
- package/components/ui/label.d.ts +0 -7
- package/components/ui/label.js +0 -68
- package/components/ui/popover.d.ts +0 -7
- package/components/ui/popover.js +0 -82
- package/components/ui/select.d.ts +0 -15
- package/components/ui/select.js +0 -127
- package/components/ui/separator.d.ts +0 -4
- package/components/ui/separator.js +0 -66
- package/components/ui/shadcn-io/color-picker/index.d.ts +0 -43
- package/components/ui/shadcn-io/color-picker/index.js +0 -304
- package/components/ui/shadcn-io/dropzone/index.d.ts +0 -19
- package/components/ui/shadcn-io/dropzone/index.js +0 -131
- package/components/ui/sonner.d.ts +0 -4
- package/components/ui/sonner.js +0 -54
- package/components/ui/switch.d.ts +0 -9
- package/components/ui/switch.js +0 -89
- package/components/ui/table.d.ts +0 -10
- package/components/ui/table.js +0 -101
- package/components/ui/textarea.d.ts +0 -8
- package/components/ui/textarea.js +0 -86
|
@@ -1,187 +0,0 @@
|
|
|
1
|
-
"use client";
|
|
2
|
-
"use strict";
|
|
3
|
-
var __assign = (this && this.__assign) || function () {
|
|
4
|
-
__assign = Object.assign || function(t) {
|
|
5
|
-
for (var s, i = 1, n = arguments.length; i < n; i++) {
|
|
6
|
-
s = arguments[i];
|
|
7
|
-
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
|
|
8
|
-
t[p] = s[p];
|
|
9
|
-
}
|
|
10
|
-
return t;
|
|
11
|
-
};
|
|
12
|
-
return __assign.apply(this, arguments);
|
|
13
|
-
};
|
|
14
|
-
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
15
|
-
if (k2 === undefined) k2 = k;
|
|
16
|
-
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
17
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
18
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
19
|
-
}
|
|
20
|
-
Object.defineProperty(o, k2, desc);
|
|
21
|
-
}) : (function(o, m, k, k2) {
|
|
22
|
-
if (k2 === undefined) k2 = k;
|
|
23
|
-
o[k2] = m[k];
|
|
24
|
-
}));
|
|
25
|
-
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
26
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
27
|
-
}) : function(o, v) {
|
|
28
|
-
o["default"] = v;
|
|
29
|
-
});
|
|
30
|
-
var __importStar = (this && this.__importStar) || (function () {
|
|
31
|
-
var ownKeys = function(o) {
|
|
32
|
-
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
33
|
-
var ar = [];
|
|
34
|
-
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
35
|
-
return ar;
|
|
36
|
-
};
|
|
37
|
-
return ownKeys(o);
|
|
38
|
-
};
|
|
39
|
-
return function (mod) {
|
|
40
|
-
if (mod && mod.__esModule) return mod;
|
|
41
|
-
var result = {};
|
|
42
|
-
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
43
|
-
__setModuleDefault(result, mod);
|
|
44
|
-
return result;
|
|
45
|
-
};
|
|
46
|
-
})();
|
|
47
|
-
var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
|
|
48
|
-
if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
|
|
49
|
-
if (ar || !(i in from)) {
|
|
50
|
-
if (!ar) ar = Array.prototype.slice.call(from, 0, i);
|
|
51
|
-
ar[i] = from[i];
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
return to.concat(ar || Array.prototype.slice.call(from));
|
|
55
|
-
};
|
|
56
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
57
|
-
exports.EnhancedDropzone = void 0;
|
|
58
|
-
var react_1 = __importStar(require("react"));
|
|
59
|
-
var react_dropzone_1 = require("react-dropzone");
|
|
60
|
-
var utils_1 = require("../../lib/utils");
|
|
61
|
-
var carousel_1 = require("./carousel");
|
|
62
|
-
var button_1 = require("./button");
|
|
63
|
-
var lucide_react_1 = require("lucide-react");
|
|
64
|
-
var EnhancedDropzone = function (_a) {
|
|
65
|
-
var id = _a.id, label = _a.label, info = _a.info, error = _a.error, accept = _a.accept, _b = _a.maxFiles, maxFiles = _b === void 0 ? 10 : _b, maxSize = _a.maxSize, minSize = _a.minSize, disabled = _a.disabled, _c = _a.value, value = _c === void 0 ? [] : _c, onChange = _a.onChange, onRemoveRemote = _a.onRemoveRemote, className = _a.className;
|
|
66
|
-
// Local files selected by user
|
|
67
|
-
var _d = (0, react_1.useState)([]), localFiles = _d[0], setLocalFiles = _d[1];
|
|
68
|
-
// Track object URLs created for local files
|
|
69
|
-
var localPreviewsRef = (0, react_1.useRef)(new Map());
|
|
70
|
-
// Create object URLs for local files synchronously to avoid loading state
|
|
71
|
-
var createObjectURLs = (0, react_1.useCallback)(function () {
|
|
72
|
-
var map = localPreviewsRef.current;
|
|
73
|
-
// Create URLs for new files
|
|
74
|
-
localFiles.forEach(function (file) {
|
|
75
|
-
if (!map.has(file)) {
|
|
76
|
-
try {
|
|
77
|
-
var url = URL.createObjectURL(file);
|
|
78
|
-
map.set(file, url);
|
|
79
|
-
}
|
|
80
|
-
catch (error) {
|
|
81
|
-
console.error("Failed to create object URL:", error);
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
|
-
});
|
|
85
|
-
// Clean up URLs for removed files
|
|
86
|
-
var currentFiles = new Set(localFiles);
|
|
87
|
-
Array.from(map.entries()).forEach(function (_a) {
|
|
88
|
-
var file = _a[0], url = _a[1];
|
|
89
|
-
if (!currentFiles.has(file)) {
|
|
90
|
-
URL.revokeObjectURL(url);
|
|
91
|
-
map.delete(file);
|
|
92
|
-
}
|
|
93
|
-
});
|
|
94
|
-
}, [localFiles]);
|
|
95
|
-
// Run synchronously on every render to avoid "loading" flash
|
|
96
|
-
createObjectURLs();
|
|
97
|
-
// Cleanup on unmount
|
|
98
|
-
(0, react_1.useEffect)(function () {
|
|
99
|
-
var map = localPreviewsRef.current;
|
|
100
|
-
return function () {
|
|
101
|
-
Array.from(map.values()).forEach(function (url) {
|
|
102
|
-
URL.revokeObjectURL(url);
|
|
103
|
-
});
|
|
104
|
-
map.clear();
|
|
105
|
-
};
|
|
106
|
-
}, []);
|
|
107
|
-
var dropzoneOptions = {
|
|
108
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
109
|
-
accept: (Array.isArray(accept) ? undefined : accept) || undefined,
|
|
110
|
-
maxFiles: maxFiles,
|
|
111
|
-
maxSize: maxSize,
|
|
112
|
-
minSize: minSize,
|
|
113
|
-
disabled: disabled,
|
|
114
|
-
onDrop: (0, react_1.useCallback)(function (acceptedFiles) {
|
|
115
|
-
setLocalFiles(function (prev) {
|
|
116
|
-
var combined = __spreadArray(__spreadArray([], prev, true), acceptedFiles, true);
|
|
117
|
-
var limited = maxFiles ? combined.slice(0, maxFiles) : combined;
|
|
118
|
-
onChange === null || onChange === void 0 ? void 0 : onChange(limited);
|
|
119
|
-
return limited;
|
|
120
|
-
});
|
|
121
|
-
}, [maxFiles, onChange]),
|
|
122
|
-
};
|
|
123
|
-
var _e = (0, react_dropzone_1.useDropzone)(dropzoneOptions), getRootProps = _e.getRootProps, getInputProps = _e.getInputProps, isDragActive = _e.isDragActive;
|
|
124
|
-
// Remove remote URL
|
|
125
|
-
var handleRemoveRemote = (0, react_1.useCallback)(function (url) {
|
|
126
|
-
onRemoveRemote === null || onRemoveRemote === void 0 ? void 0 : onRemoveRemote(url);
|
|
127
|
-
}, [onRemoveRemote]);
|
|
128
|
-
// Remove local file
|
|
129
|
-
var handleRemoveLocal = (0, react_1.useCallback)(function (index) {
|
|
130
|
-
setLocalFiles(function (prev) {
|
|
131
|
-
var updated = prev.filter(function (_, i) { return i !== index; });
|
|
132
|
-
onChange === null || onChange === void 0 ? void 0 : onChange(updated);
|
|
133
|
-
return updated;
|
|
134
|
-
});
|
|
135
|
-
}, [onChange]);
|
|
136
|
-
// Get all preview URLs (remote + local)
|
|
137
|
-
var allPreviews = __spreadArray(__spreadArray([], value.map(function (url) { return ({ type: "remote", url: url, index: 0 }); }), true), localFiles.map(function (file, index) { return ({
|
|
138
|
-
type: "local",
|
|
139
|
-
url: localPreviewsRef.current.get(file) || "",
|
|
140
|
-
index: index,
|
|
141
|
-
}); }), true);
|
|
142
|
-
return (react_1.default.createElement("div", { className: (0, utils_1.cn)("w-full", className) },
|
|
143
|
-
label && (react_1.default.createElement("label", { className: "mb-2 block text-sm font-medium" }, label)),
|
|
144
|
-
react_1.default.createElement("div", __assign({}, getRootProps(), { className: (0, utils_1.cn)("relative w-full rounded-md border border-dashed p-6 text-center min-h-[280px] flex items-center justify-center", isDragActive && "ring-2 ring-ring ring-offset-2", disabled && "opacity-60 pointer-events-none") }),
|
|
145
|
-
react_1.default.createElement("input", __assign({}, getInputProps(), { id: id })),
|
|
146
|
-
allPreviews.length > 0 ? (react_1.default.createElement("div", { className: "flex flex-col items-center w-full" },
|
|
147
|
-
react_1.default.createElement("div", { className: "relative w-full max-w-md" },
|
|
148
|
-
react_1.default.createElement(carousel_1.Carousel, { className: "w-full" },
|
|
149
|
-
react_1.default.createElement(carousel_1.CarouselPrevious, { type: "button", onClick: function (e) { return e.stopPropagation(); }, onPointerDown: function (e) { return e.stopPropagation(); }, onMouseDown: function (e) { return e.stopPropagation(); } }),
|
|
150
|
-
react_1.default.createElement(carousel_1.CarouselNext, { type: "button", onClick: function (e) { return e.stopPropagation(); }, onPointerDown: function (e) { return e.stopPropagation(); }, onMouseDown: function (e) { return e.stopPropagation(); } }),
|
|
151
|
-
react_1.default.createElement(carousel_1.CarouselContent, { className: "ml-0" }, allPreviews.map(function (preview, idx) { return (react_1.default.createElement(carousel_1.CarouselItem, { key: "".concat(preview.type, "-").concat(preview.url, "-").concat(idx), className: "pl-4" },
|
|
152
|
-
react_1.default.createElement("div", { className: "relative aspect-square w-full max-w-xs mx-auto" }, preview.url ? (react_1.default.createElement(react_1.default.Fragment, null,
|
|
153
|
-
react_1.default.createElement("img", { src: preview.url, alt: "Preview ".concat(idx + 1), className: "h-full w-full rounded-lg object-cover", onClick: function (e) { return e.stopPropagation(); } }),
|
|
154
|
-
react_1.default.createElement(button_1.Button, { type: "button", size: "icon", variant: "destructive", onClick: function (e) {
|
|
155
|
-
e.stopPropagation();
|
|
156
|
-
if (preview.type === "remote") {
|
|
157
|
-
handleRemoveRemote(preview.url);
|
|
158
|
-
}
|
|
159
|
-
else {
|
|
160
|
-
handleRemoveLocal(preview.index);
|
|
161
|
-
}
|
|
162
|
-
}, className: "absolute right-2 top-2 h-8 w-8 rounded-full", "aria-label": "Remove image" },
|
|
163
|
-
react_1.default.createElement(lucide_react_1.XIcon, { className: "h-4 w-4" })))) : (react_1.default.createElement("div", { className: "flex h-full w-full items-center justify-center rounded-lg bg-muted text-muted-foreground" },
|
|
164
|
-
react_1.default.createElement("span", { className: "text-sm" }, "Loading...")))))); })))),
|
|
165
|
-
react_1.default.createElement("p", { className: "mt-4 text-sm font-medium text-muted-foreground" },
|
|
166
|
-
allPreviews.length,
|
|
167
|
-
" image",
|
|
168
|
-
allPreviews.length !== 1 ? "s" : "",
|
|
169
|
-
" ",
|
|
170
|
-
"selected"))) : (react_1.default.createElement("div", { className: "flex flex-col items-center justify-center gap-2" },
|
|
171
|
-
react_1.default.createElement("div", { className: "flex h-12 w-12 items-center justify-center rounded-lg bg-muted text-muted-foreground" },
|
|
172
|
-
react_1.default.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", width: "24", height: "24", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", className: "lucide lucide-image" },
|
|
173
|
-
react_1.default.createElement("rect", { width: "18", height: "18", x: "3", y: "3", rx: "2", ry: "2" }),
|
|
174
|
-
react_1.default.createElement("circle", { cx: "9", cy: "9", r: "2" }),
|
|
175
|
-
react_1.default.createElement("path", { d: "m21 15-3.086-3.086a2 2 0 0 0-2.828 0L6 21" }))),
|
|
176
|
-
react_1.default.createElement("div", { className: "space-y-1 text-center" },
|
|
177
|
-
react_1.default.createElement("p", { className: "font-medium text-sm" },
|
|
178
|
-
"Upload ",
|
|
179
|
-
maxFiles === 1 ? "an image" : "images"),
|
|
180
|
-
react_1.default.createElement("p", { className: "text-muted-foreground text-xs" }, "Drag and drop or click to browse"),
|
|
181
|
-
maxFiles > 1 && (react_1.default.createElement("p", { className: "text-muted-foreground text-xs" },
|
|
182
|
-
"Up to ",
|
|
183
|
-
maxFiles,
|
|
184
|
-
" files")))))),
|
|
185
|
-
(error || info) && (react_1.default.createElement("div", { className: "mt-2" }, error ? (react_1.default.createElement("p", { className: "text-xs text-destructive" }, error)) : info ? (react_1.default.createElement("p", { className: "text-xs text-blue-600 dark:text-blue-400" }, info)) : null))));
|
|
186
|
-
};
|
|
187
|
-
exports.EnhancedDropzone = EnhancedDropzone;
|
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Enhanced Table Footer Action Component
|
|
3
|
-
*
|
|
4
|
-
* Navigation buttons for table pagination with RTL/LTR support.
|
|
5
|
-
* Automatically adjusts arrow directions and button order based on locale.
|
|
6
|
-
*
|
|
7
|
-
* Features:
|
|
8
|
-
* - RTL/LTR arrow direction adjustment
|
|
9
|
-
* - Button order reversal for RTL layouts
|
|
10
|
-
* - Accessibility attributes
|
|
11
|
-
* - Internationalized aria labels
|
|
12
|
-
* - Disabled state handling
|
|
13
|
-
* - Loading state support
|
|
14
|
-
*/
|
|
15
|
-
import { FC } from "react";
|
|
16
|
-
interface EnhancedTableFooterActionProps {
|
|
17
|
-
/** Handler for next page navigation */
|
|
18
|
-
handleNextOnClick: () => void;
|
|
19
|
-
/** Handler for previous page navigation */
|
|
20
|
-
handlePreviousOnClick: () => void;
|
|
21
|
-
/** Whether next button should be disabled */
|
|
22
|
-
isNextDisabled?: boolean;
|
|
23
|
-
/** Whether previous button should be disabled */
|
|
24
|
-
isPreviousDisabled?: boolean;
|
|
25
|
-
/** Loading state indicator */
|
|
26
|
-
loading?: boolean;
|
|
27
|
-
/** Custom aria labels for accessibility */
|
|
28
|
-
ariaLabels?: {
|
|
29
|
-
next?: string;
|
|
30
|
-
previous?: string;
|
|
31
|
-
};
|
|
32
|
-
}
|
|
33
|
-
export declare const EnhancedTableFooterAction: FC<EnhancedTableFooterActionProps>;
|
|
34
|
-
export {};
|
|
@@ -1,117 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
/**
|
|
3
|
-
* Enhanced Table Footer Action Component
|
|
4
|
-
*
|
|
5
|
-
* Navigation buttons for table pagination with RTL/LTR support.
|
|
6
|
-
* Automatically adjusts arrow directions and button order based on locale.
|
|
7
|
-
*
|
|
8
|
-
* Features:
|
|
9
|
-
* - RTL/LTR arrow direction adjustment
|
|
10
|
-
* - Button order reversal for RTL layouts
|
|
11
|
-
* - Accessibility attributes
|
|
12
|
-
* - Internationalized aria labels
|
|
13
|
-
* - Disabled state handling
|
|
14
|
-
* - Loading state support
|
|
15
|
-
*/
|
|
16
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
17
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
18
|
-
};
|
|
19
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
20
|
-
exports.EnhancedTableFooterAction = void 0;
|
|
21
|
-
var react_1 = __importDefault(require("react"));
|
|
22
|
-
var lucide_react_1 = require("lucide-react");
|
|
23
|
-
var next_intl_1 = require("next-intl");
|
|
24
|
-
var button_1 = require("./button");
|
|
25
|
-
var use_rtl_1 = require("../../hooks/use-rtl");
|
|
26
|
-
var EnhancedTableFooterAction = function (_a) {
|
|
27
|
-
var handleNextOnClick = _a.handleNextOnClick, handlePreviousOnClick = _a.handlePreviousOnClick, isNextDisabled = _a.isNextDisabled, isPreviousDisabled = _a.isPreviousDisabled, loading = _a.loading, ariaLabels = _a.ariaLabels;
|
|
28
|
-
var t = (0, next_intl_1.useTranslations)();
|
|
29
|
-
var isRTL = (0, use_rtl_1.useRTL)();
|
|
30
|
-
// Get translated aria labels with fallbacks
|
|
31
|
-
var previousLabel = (ariaLabels === null || ariaLabels === void 0 ? void 0 : ariaLabels.previous) || t("common.previousPage") || "Previous page";
|
|
32
|
-
var nextLabel = (ariaLabels === null || ariaLabels === void 0 ? void 0 : ariaLabels.next) || t("common.nextPage") || "Next page";
|
|
33
|
-
// In RTL, arrows should be swapped:
|
|
34
|
-
// Previous should show → (ChevronRight) as it goes to the right in RTL reading order
|
|
35
|
-
// Next should show ← (ChevronLeft) as it goes to the left in RTL reading order
|
|
36
|
-
var PreviousIcon = isRTL ? lucide_react_1.ChevronRight : lucide_react_1.ChevronLeft;
|
|
37
|
-
var NextIcon = isRTL ? lucide_react_1.ChevronLeft : lucide_react_1.ChevronRight;
|
|
38
|
-
return (react_1.default.createElement("div", { className: "flex gap-1 ".concat(isRTL ? "flex-row-reverse" : "") },
|
|
39
|
-
react_1.default.createElement(button_1.Button, { variant: "outline", size: "icon", onClick: handlePreviousOnClick, disabled: isPreviousDisabled || loading, "aria-label": previousLabel, title: previousLabel, className: "".concat(isRTL ? "rotate-180" : "") },
|
|
40
|
-
react_1.default.createElement(PreviousIcon, { className: "h-4 w-4" })),
|
|
41
|
-
react_1.default.createElement(button_1.Button, { variant: "outline", size: "icon", onClick: handleNextOnClick, disabled: isNextDisabled || loading, "aria-label": nextLabel, title: nextLabel, className: "".concat(isRTL ? "rotate-180" : "") },
|
|
42
|
-
react_1.default.createElement(NextIcon, { className: "h-4 w-4" }))));
|
|
43
|
-
};
|
|
44
|
-
exports.EnhancedTableFooterAction = EnhancedTableFooterAction;
|
|
45
|
-
// ============================================================================
|
|
46
|
-
// USAGE EXAMPLES
|
|
47
|
-
// ============================================================================
|
|
48
|
-
/*
|
|
49
|
-
Example 1: Basic usage with automatic i18n and RTL support
|
|
50
|
-
<EnhancedTableFooterAction
|
|
51
|
-
handlePreviousOnClick={() => setCurrentPage(prev => prev - 1)}
|
|
52
|
-
handleNextOnClick={() => setCurrentPage(prev => prev + 1)}
|
|
53
|
-
isPreviousDisabled={currentPage === 1}
|
|
54
|
-
isNextDisabled={currentPage === totalPages}
|
|
55
|
-
loading={false}
|
|
56
|
-
/>
|
|
57
|
-
|
|
58
|
-
Example 2: With custom aria labels
|
|
59
|
-
<EnhancedTableFooterAction
|
|
60
|
-
handlePreviousOnClick={handlePrevious}
|
|
61
|
-
handleNextOnClick={handleNext}
|
|
62
|
-
isPreviousDisabled={isPreviousDisabled}
|
|
63
|
-
isNextDisabled={isNextDisabled}
|
|
64
|
-
loading={isLoading}
|
|
65
|
-
ariaLabels={{
|
|
66
|
-
previous: "Go to previous page",
|
|
67
|
-
next: "Go to next page"
|
|
68
|
-
}}
|
|
69
|
-
/>
|
|
70
|
-
|
|
71
|
-
Example 3: Loading state
|
|
72
|
-
<EnhancedTableFooterAction
|
|
73
|
-
handlePreviousOnClick={handlePrevious}
|
|
74
|
-
handleNextOnClick={handleNext}
|
|
75
|
-
loading={true} // Both buttons will be disabled
|
|
76
|
-
/>
|
|
77
|
-
|
|
78
|
-
RTL Behavior:
|
|
79
|
-
- In LTR languages (English): Previous (←) | Next (→)
|
|
80
|
-
- In RTL languages (Arabic/Urdu): Previous (→) | Next (←)
|
|
81
|
-
- Button order is reversed in RTL: [Next] [Previous]
|
|
82
|
-
- Arrows automatically adjust to reading direction
|
|
83
|
-
*/
|
|
84
|
-
// ============================================================================
|
|
85
|
-
// COMPONENT ENHANCEMENTS SUMMARY
|
|
86
|
-
// ============================================================================
|
|
87
|
-
/*
|
|
88
|
-
Enhancements Applied:
|
|
89
|
-
|
|
90
|
-
1. **RTL/LTR Layout Support**
|
|
91
|
-
- Automatic arrow direction adjustment based on locale
|
|
92
|
-
- Button order reversal for RTL layouts (flex-row-reverse)
|
|
93
|
-
- Direction-aware icon selection (ChevronLeft/Right swap)
|
|
94
|
-
- Proper navigation flow for both reading directions
|
|
95
|
-
|
|
96
|
-
2. **Internationalization (i18n)**
|
|
97
|
-
- Translation support using next-intl
|
|
98
|
-
- Fallback aria labels for accessibility
|
|
99
|
-
- Custom aria label override capability
|
|
100
|
-
- Tooltip support with title attributes
|
|
101
|
-
|
|
102
|
-
3. **Accessibility Improvements**
|
|
103
|
-
- ARIA labels for screen readers
|
|
104
|
-
- Title attributes for tooltips
|
|
105
|
-
- Proper button semantics
|
|
106
|
-
- Keyboard navigation support
|
|
107
|
-
|
|
108
|
-
4. **Visual Consistency**
|
|
109
|
-
- Maintains button spacing and alignment
|
|
110
|
-
- Consistent with existing table footer components
|
|
111
|
-
- Proper disabled state handling
|
|
112
|
-
- Loading state support
|
|
113
|
-
|
|
114
|
-
Translation Keys Added:
|
|
115
|
-
- common.previousPage: "Previous page" / "پچھلا صفحہ"
|
|
116
|
-
- common.nextPage: "Next page" / "اگلا صفحہ"
|
|
117
|
-
*/
|
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Enhanced Table Footer Page Component
|
|
3
|
-
*
|
|
4
|
-
* Displays pagination information with internationalization and RTL/LTR support.
|
|
5
|
-
* Automatically adapts text direction and order based on locale.
|
|
6
|
-
*
|
|
7
|
-
* Features:
|
|
8
|
-
* - Full i18n support with fallback text
|
|
9
|
-
* - RTL/LTR layout adaptation
|
|
10
|
-
* - Loading state indicator
|
|
11
|
-
* - Accessibility attributes
|
|
12
|
-
* - Custom translation overrides
|
|
13
|
-
*/
|
|
14
|
-
import { FC } from "react";
|
|
15
|
-
interface EnhancedTableFooterPageProps {
|
|
16
|
-
/** Current active page number */
|
|
17
|
-
currentPage: number;
|
|
18
|
-
/** Loading state indicator */
|
|
19
|
-
loading: boolean;
|
|
20
|
-
/** Total number of pages available */
|
|
21
|
-
totalPages: number;
|
|
22
|
-
/** Optional translation map for custom text overrides */
|
|
23
|
-
translationMap?: {
|
|
24
|
-
pageLabel?: string;
|
|
25
|
-
ofLabel?: string;
|
|
26
|
-
loadingLabel?: string;
|
|
27
|
-
};
|
|
28
|
-
/** Optional CSS classes for custom styling */
|
|
29
|
-
className?: string;
|
|
30
|
-
}
|
|
31
|
-
export declare const EnhancedTableFooterPage: FC<EnhancedTableFooterPageProps>;
|
|
32
|
-
export {};
|
|
@@ -1,140 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
/**
|
|
3
|
-
* Enhanced Table Footer Page Component
|
|
4
|
-
*
|
|
5
|
-
* Displays pagination information with internationalization and RTL/LTR support.
|
|
6
|
-
* Automatically adapts text direction and order based on locale.
|
|
7
|
-
*
|
|
8
|
-
* Features:
|
|
9
|
-
* - Full i18n support with fallback text
|
|
10
|
-
* - RTL/LTR layout adaptation
|
|
11
|
-
* - Loading state indicator
|
|
12
|
-
* - Accessibility attributes
|
|
13
|
-
* - Custom translation overrides
|
|
14
|
-
*/
|
|
15
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
16
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
17
|
-
};
|
|
18
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
19
|
-
exports.EnhancedTableFooterPage = void 0;
|
|
20
|
-
var react_1 = __importDefault(require("react"));
|
|
21
|
-
var next_intl_1 = require("next-intl");
|
|
22
|
-
var use_rtl_1 = require("../../hooks/use-rtl");
|
|
23
|
-
var EnhancedTableFooterPage = function (_a) {
|
|
24
|
-
var currentPage = _a.currentPage, loading = _a.loading, totalPages = _a.totalPages, translationMap = _a.translationMap, _b = _a.className, className = _b === void 0 ? "" : _b;
|
|
25
|
-
var t = (0, next_intl_1.useTranslations)();
|
|
26
|
-
var isRTL = (0, use_rtl_1.useRTL)();
|
|
27
|
-
// Get translated text with fallbacks
|
|
28
|
-
var pageLabel = (translationMap === null || translationMap === void 0 ? void 0 : translationMap.pageLabel) || t("common.page") || "Page";
|
|
29
|
-
var ofLabel = (translationMap === null || translationMap === void 0 ? void 0 : translationMap.ofLabel) || t("common.of") || "of";
|
|
30
|
-
var loadingLabel = (translationMap === null || translationMap === void 0 ? void 0 : translationMap.loadingLabel) || t("common.loading") || "Loading";
|
|
31
|
-
return (react_1.default.createElement("div", { className: "flex items-center gap-2 ".concat(isRTL ? "rtl" : "ltr", " ").concat(className), dir: isRTL ? "rtl" : "ltr", role: "status", "aria-live": "polite", "aria-label": "".concat(pageLabel, " ").concat(currentPage, " ").concat(ofLabel, " ").concat(totalPages) },
|
|
32
|
-
react_1.default.createElement("span", { className: "text-sm text-muted-foreground" }, isRTL ? (
|
|
33
|
-
// RTL layout: Numbers read right-to-left but maintain logical order
|
|
34
|
-
react_1.default.createElement("span", { className: "inline-flex items-center gap-1" },
|
|
35
|
-
react_1.default.createElement("span", null, totalPages),
|
|
36
|
-
react_1.default.createElement("span", null, ofLabel),
|
|
37
|
-
react_1.default.createElement("span", null, currentPage),
|
|
38
|
-
react_1.default.createElement("span", null, pageLabel))) : (
|
|
39
|
-
// LTR layout: "Page currentPage of totalPages"
|
|
40
|
-
react_1.default.createElement("span", { className: "inline-flex items-center gap-1" },
|
|
41
|
-
react_1.default.createElement("span", null, pageLabel),
|
|
42
|
-
react_1.default.createElement("span", null, currentPage),
|
|
43
|
-
react_1.default.createElement("span", null, ofLabel),
|
|
44
|
-
react_1.default.createElement("span", null, totalPages)))),
|
|
45
|
-
loading && (react_1.default.createElement("div", { className: "flex items-center gap-2 ".concat(isRTL ? "order-first" : "order-last"), "aria-label": loadingLabel },
|
|
46
|
-
react_1.default.createElement("div", { className: "w-4 h-4 border-2 border-primary border-t-transparent rounded-full animate-spin", role: "progressbar", "aria-label": loadingLabel })))));
|
|
47
|
-
};
|
|
48
|
-
exports.EnhancedTableFooterPage = EnhancedTableFooterPage;
|
|
49
|
-
// ============================================================================
|
|
50
|
-
// USAGE EXAMPLES
|
|
51
|
-
// ============================================================================
|
|
52
|
-
/*
|
|
53
|
-
Example 1: Basic usage with automatic i18n
|
|
54
|
-
<EnhancedTableFooterPage
|
|
55
|
-
currentPage={2}
|
|
56
|
-
totalPages={10}
|
|
57
|
-
loading={false}
|
|
58
|
-
/>
|
|
59
|
-
|
|
60
|
-
Example 2: With custom translations
|
|
61
|
-
<EnhancedTableFooterPage
|
|
62
|
-
currentPage={1}
|
|
63
|
-
totalPages={5}
|
|
64
|
-
loading={true}
|
|
65
|
-
translationMap={{
|
|
66
|
-
pageLabel: "صفحہ", // Urdu for "Page"
|
|
67
|
-
ofLabel: "کا", // Urdu for "of"
|
|
68
|
-
loadingLabel: "لوڈ ہو رہا ہے" // Urdu for "Loading"
|
|
69
|
-
}}
|
|
70
|
-
/>
|
|
71
|
-
|
|
72
|
-
Example 3: With custom styling
|
|
73
|
-
<EnhancedTableFooterPage
|
|
74
|
-
currentPage={3}
|
|
75
|
-
totalPages={7}
|
|
76
|
-
loading={false}
|
|
77
|
-
className="bg-gray-50 p-2 rounded-md"
|
|
78
|
-
/>
|
|
79
|
-
|
|
80
|
-
Translation Keys (Already Added to messages files):
|
|
81
|
-
English (en.json):
|
|
82
|
-
{
|
|
83
|
-
"common": {
|
|
84
|
-
"page": "Page",
|
|
85
|
-
"of": "of",
|
|
86
|
-
"loading": "Loading"
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
Urdu (ur.json):
|
|
91
|
-
{
|
|
92
|
-
"common": {
|
|
93
|
-
"page": "صفحہ",
|
|
94
|
-
"of": "کا",
|
|
95
|
-
"loading": "لوڈ ہو رہا ہے"
|
|
96
|
-
}
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
RTL Layout Features:
|
|
100
|
-
- Automatic text direction detection and application
|
|
101
|
-
- Proper order of page information in RTL languages
|
|
102
|
-
- RTL-aware loading indicator positioning
|
|
103
|
-
- Accessibility attributes for screen readers
|
|
104
|
-
- Direction-specific CSS classes and DOM attributes
|
|
105
|
-
*/
|
|
106
|
-
// ============================================================================
|
|
107
|
-
// COMPONENT ENHANCEMENTS SUMMARY
|
|
108
|
-
// ============================================================================
|
|
109
|
-
/*
|
|
110
|
-
Enhancements Applied:
|
|
111
|
-
|
|
112
|
-
1. **Internationalization (i18n)**
|
|
113
|
-
- Full translation support using next-intl
|
|
114
|
-
- Fallback text for missing translations
|
|
115
|
-
- Custom translation override capability
|
|
116
|
-
|
|
117
|
-
2. **RTL/LTR Layout Support**
|
|
118
|
-
- Automatic layout detection using useRTL hook
|
|
119
|
-
- Proper text ordering for RTL languages
|
|
120
|
-
- Direction-aware CSS classes and attributes
|
|
121
|
-
- RTL-appropriate visual element positioning
|
|
122
|
-
|
|
123
|
-
3. **Accessibility Improvements**
|
|
124
|
-
- ARIA labels for screen readers
|
|
125
|
-
- Role attributes for semantic meaning
|
|
126
|
-
- Live region announcements for dynamic content
|
|
127
|
-
- Proper labeling of interactive elements
|
|
128
|
-
|
|
129
|
-
4. **Developer Experience**
|
|
130
|
-
- Comprehensive JSDoc documentation
|
|
131
|
-
- Usage examples and patterns
|
|
132
|
-
- TypeScript interface improvements
|
|
133
|
-
- Flexible customization options
|
|
134
|
-
|
|
135
|
-
5. **Code Quality**
|
|
136
|
-
- Clean, readable component structure
|
|
137
|
-
- Consistent naming conventions
|
|
138
|
-
- Performance-optimized rendering
|
|
139
|
-
- Maintainable and extensible design
|
|
140
|
-
*/
|
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Enhanced Table Footer Pagination Component
|
|
3
|
-
*
|
|
4
|
-
* Displays rows per page selector with internationalization and RTL/LTR support.
|
|
5
|
-
* Automatically adapts text direction and layout based on locale.
|
|
6
|
-
*
|
|
7
|
-
* Features:
|
|
8
|
-
* - Full i18n support with fallback text
|
|
9
|
-
* - RTL/LTR layout adaptation
|
|
10
|
-
* - Loading state handling
|
|
11
|
-
* - Accessibility attributes
|
|
12
|
-
* - Custom translation overrides
|
|
13
|
-
* - Responsive design
|
|
14
|
-
*/
|
|
15
|
-
import { FC } from "react";
|
|
16
|
-
import { PageLimitOption } from "./enhanced-table";
|
|
17
|
-
interface EnhancedTableFooterPageProps {
|
|
18
|
-
/** Handler for page limit selection changes */
|
|
19
|
-
handleOnSelect: (node: string, value: object) => void;
|
|
20
|
-
/** Array of page limit options to display */
|
|
21
|
-
listOptions: PageLimitOption[];
|
|
22
|
-
/** Loading state indicator */
|
|
23
|
-
loading: boolean;
|
|
24
|
-
/** Node key for the select handler */
|
|
25
|
-
nodeSelectKey?: string;
|
|
26
|
-
/** Current page limit value */
|
|
27
|
-
pageLimit: number;
|
|
28
|
-
/** Total number of pages (unused but kept for compatibility) */
|
|
29
|
-
totalPages: number;
|
|
30
|
-
/** Optional translation override for the label text */
|
|
31
|
-
labelText?: string;
|
|
32
|
-
/** Optional CSS classes for custom styling */
|
|
33
|
-
className?: string;
|
|
34
|
-
}
|
|
35
|
-
export declare const EnhancedTableFooterPagination: FC<EnhancedTableFooterPageProps>;
|
|
36
|
-
export {};
|
|
@@ -1,122 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
/**
|
|
3
|
-
* Enhanced Table Footer Pagination Component
|
|
4
|
-
*
|
|
5
|
-
* Displays rows per page selector with internationalization and RTL/LTR support.
|
|
6
|
-
* Automatically adapts text direction and layout based on locale.
|
|
7
|
-
*
|
|
8
|
-
* Features:
|
|
9
|
-
* - Full i18n support with fallback text
|
|
10
|
-
* - RTL/LTR layout adaptation
|
|
11
|
-
* - Loading state handling
|
|
12
|
-
* - Accessibility attributes
|
|
13
|
-
* - Custom translation overrides
|
|
14
|
-
* - Responsive design
|
|
15
|
-
*/
|
|
16
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
17
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
18
|
-
};
|
|
19
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
20
|
-
exports.EnhancedTableFooterPagination = void 0;
|
|
21
|
-
var select_1 = require("./select");
|
|
22
|
-
var react_1 = __importDefault(require("react"));
|
|
23
|
-
var next_intl_1 = require("next-intl");
|
|
24
|
-
var use_rtl_1 = require("../../hooks/use-rtl");
|
|
25
|
-
var EnhancedTableFooterPagination = function (_a) {
|
|
26
|
-
var handleOnSelect = _a.handleOnSelect, listOptions = _a.listOptions, loading = _a.loading, nodeSelectKey = _a.nodeSelectKey, pageLimit = _a.pageLimit, labelText = _a.labelText, _b = _a.className, className = _b === void 0 ? "" : _b;
|
|
27
|
-
var t = (0, next_intl_1.useTranslations)();
|
|
28
|
-
var isRTL = (0, use_rtl_1.useRTL)();
|
|
29
|
-
// Get translated label text with fallback
|
|
30
|
-
var rowsPerPageLabel = labelText || t("common.rowsPerPage") || "Rows per page:";
|
|
31
|
-
return (react_1.default.createElement("div", { className: "flex items-center gap-2 ".concat(className), dir: isRTL ? "rtl" : "ltr" },
|
|
32
|
-
react_1.default.createElement("label", { htmlFor: "page-limit-select-".concat(nodeSelectKey), className: "text-sm text-muted-foreground whitespace-nowrap" }, rowsPerPageLabel),
|
|
33
|
-
react_1.default.createElement(select_1.Select, { value: String(pageLimit), onValueChange: function (value) {
|
|
34
|
-
return handleOnSelect(nodeSelectKey, { option: value });
|
|
35
|
-
}, disabled: loading },
|
|
36
|
-
react_1.default.createElement(select_1.SelectTrigger, { id: "page-limit-select-".concat(nodeSelectKey), className: "w-20", "aria-label": "".concat(rowsPerPageLabel, " ").concat(pageLimit) },
|
|
37
|
-
react_1.default.createElement(select_1.SelectValue, null)),
|
|
38
|
-
react_1.default.createElement(select_1.SelectContent, null, listOptions.map(function (option) { return (react_1.default.createElement(select_1.SelectItem, { key: option.option, value: option.option, "aria-label": "".concat(option.option, " rows per page") }, option.option)); })))));
|
|
39
|
-
};
|
|
40
|
-
exports.EnhancedTableFooterPagination = EnhancedTableFooterPagination;
|
|
41
|
-
// ============================================================================
|
|
42
|
-
// USAGE EXAMPLES
|
|
43
|
-
// ============================================================================
|
|
44
|
-
/*
|
|
45
|
-
Example 1: Basic usage with automatic i18n
|
|
46
|
-
<EnhancedTableFooterPagination
|
|
47
|
-
handleOnSelect={(key, value) => console.log(key, value)}
|
|
48
|
-
listOptions={[{ option: "10" }, { option: "25" }, { option: "50" }]}
|
|
49
|
-
loading={false}
|
|
50
|
-
nodeSelectKey="pageLimit"
|
|
51
|
-
pageLimit={10}
|
|
52
|
-
totalPages={5}
|
|
53
|
-
/>
|
|
54
|
-
|
|
55
|
-
Example 2: With custom label text
|
|
56
|
-
<EnhancedTableFooterPagination
|
|
57
|
-
handleOnSelect={handlePageLimitChange}
|
|
58
|
-
listOptions={pageLimitOptions}
|
|
59
|
-
loading={isLoading}
|
|
60
|
-
nodeSelectKey="pageLimit"
|
|
61
|
-
pageLimit={currentPageLimit}
|
|
62
|
-
totalPages={totalPages}
|
|
63
|
-
labelText="Items per page:"
|
|
64
|
-
/>
|
|
65
|
-
|
|
66
|
-
Example 3: With custom styling and RTL support
|
|
67
|
-
<EnhancedTableFooterPagination
|
|
68
|
-
handleOnSelect={handlePageLimitChange}
|
|
69
|
-
listOptions={pageLimitOptions}
|
|
70
|
-
loading={false}
|
|
71
|
-
nodeSelectKey="pageLimit"
|
|
72
|
-
pageLimit={25}
|
|
73
|
-
totalPages={10}
|
|
74
|
-
className="bg-gray-50 p-2 rounded-md"
|
|
75
|
-
/>
|
|
76
|
-
|
|
77
|
-
RTL Layout Features:
|
|
78
|
-
- Automatic text direction detection and application
|
|
79
|
-
- Element order reversal for RTL languages
|
|
80
|
-
- Proper label-select association
|
|
81
|
-
- Accessibility attributes for screen readers
|
|
82
|
-
- Direction-specific CSS classes and DOM attributes
|
|
83
|
-
*/
|
|
84
|
-
// ============================================================================
|
|
85
|
-
// COMPONENT ENHANCEMENTS SUMMARY
|
|
86
|
-
// ============================================================================
|
|
87
|
-
/*
|
|
88
|
-
Enhancements Applied:
|
|
89
|
-
|
|
90
|
-
1. **Internationalization (i18n)**
|
|
91
|
-
- Translation support using next-intl
|
|
92
|
-
- Fallback text for missing translations
|
|
93
|
-
- Custom label text override capability
|
|
94
|
-
- Translatable "Rows per page:" label
|
|
95
|
-
|
|
96
|
-
2. **RTL/LTR Layout Support**
|
|
97
|
-
- Automatic layout detection using useRTL hook
|
|
98
|
-
- Element order reversal for RTL languages (flex-row-reverse)
|
|
99
|
-
- Direction-aware CSS classes and attributes
|
|
100
|
-
- Proper text direction handling
|
|
101
|
-
|
|
102
|
-
3. **Accessibility Improvements**
|
|
103
|
-
- Proper label-select association with htmlFor/id
|
|
104
|
-
- ARIA labels for screen readers
|
|
105
|
-
- Descriptive aria-label for select options
|
|
106
|
-
- Semantic HTML structure with label element
|
|
107
|
-
|
|
108
|
-
4. **Developer Experience**
|
|
109
|
-
- Comprehensive JSDoc documentation
|
|
110
|
-
- Usage examples and patterns
|
|
111
|
-
- TypeScript interface improvements
|
|
112
|
-
- Flexible customization options
|
|
113
|
-
|
|
114
|
-
5. **Code Quality**
|
|
115
|
-
- Clean, readable component structure
|
|
116
|
-
- Consistent naming conventions
|
|
117
|
-
- Performance-optimized rendering
|
|
118
|
-
- Maintainable and extensible design
|
|
119
|
-
|
|
120
|
-
Translation Key Required:
|
|
121
|
-
- common.rowsPerPage: "Rows per page:" / "ہر صفحے میں قطاریں:"
|
|
122
|
-
*/
|