@firedesktop/react-base 2.1.24 → 3.0.0

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 (114) hide show
  1. package/LICENSE +162 -0
  2. package/README.md +174 -94
  3. package/dist/components/AppIcon.d.ts +20 -20
  4. package/dist/components/AppIcon.js +64 -53
  5. package/dist/components/AppIcon.js.map +1 -1
  6. package/dist/components/AppInput.d.ts +20 -20
  7. package/dist/components/AppInput.js +18 -7
  8. package/dist/components/AppInput.js.map +1 -1
  9. package/dist/components/AppPagination.d.ts +11 -11
  10. package/dist/components/AppPagination.js +74 -63
  11. package/dist/components/AppPagination.js.map +1 -1
  12. package/dist/components/Spin.d.ts +6 -6
  13. package/dist/components/Spin.js +21 -17
  14. package/dist/components/Spin.js.map +1 -1
  15. package/dist/components/Toaster/Toaster.d.ts +7 -7
  16. package/dist/components/Toaster/Toaster.js +41 -29
  17. package/dist/components/Toaster/Toaster.js.map +1 -1
  18. package/dist/components/Toaster/Types.d.ts +6 -6
  19. package/dist/components/Toaster/Types.js +1 -1
  20. package/dist/components/index.d.ts +7 -7
  21. package/dist/components/index.js +7 -7
  22. package/dist/index.d.ts +8 -7
  23. package/dist/index.js +8 -7
  24. package/dist/index.js.map +1 -1
  25. package/dist/utils/CurrencyUtiles.d.ts +4 -4
  26. package/dist/utils/CurrencyUtiles.js +35 -30
  27. package/dist/utils/CurrencyUtiles.js.map +1 -1
  28. package/dist/utils/DateUtils.d.ts +7 -7
  29. package/dist/utils/DateUtils.js +111 -100
  30. package/dist/utils/DateUtils.js.map +1 -1
  31. package/dist/utils/FileUtils.d.ts +5 -5
  32. package/dist/utils/FileUtils.js +73 -73
  33. package/dist/utils/FileUtils.js.map +1 -1
  34. package/dist/utils/Logger.d.ts +13 -0
  35. package/dist/utils/Logger.js +44 -0
  36. package/dist/utils/Logger.js.map +1 -0
  37. package/dist/utils/RegExValidation.d.ts +4 -4
  38. package/dist/utils/RegExValidation.js +19 -19
  39. package/dist/utils/UrlUtils.d.ts +4 -4
  40. package/dist/utils/UrlUtils.js +15 -15
  41. package/dist/utils/UrlUtils.js.map +1 -1
  42. package/dist/utils/configuration/ConfigurationLoader.d.ts +6 -6
  43. package/dist/utils/configuration/ConfigurationLoader.js +76 -75
  44. package/dist/utils/configuration/ConfigurationLoader.js.map +1 -1
  45. package/dist/utils/configuration/ConfigurationManager.d.ts +5 -5
  46. package/dist/utils/configuration/ConfigurationManager.js +96 -89
  47. package/dist/utils/configuration/ConfigurationManager.js.map +1 -1
  48. package/dist/utils/configuration/ConfigurationReturner.d.ts +9 -9
  49. package/dist/utils/configuration/ConfigurationReturner.js +70 -69
  50. package/dist/utils/configuration/ConfigurationReturner.js.map +1 -1
  51. package/dist/utils/configuration/index.d.ts +4 -4
  52. package/dist/utils/configuration/index.js +4 -4
  53. package/dist/utils/fetch/Types.d.ts +10 -10
  54. package/dist/utils/fetch/Types.js +1 -1
  55. package/dist/utils/fetch/fetchWrapper.d.ts +14 -14
  56. package/dist/utils/fetch/fetchWrapper.js +239 -262
  57. package/dist/utils/fetch/fetchWrapper.js.map +1 -1
  58. package/dist/utils/fetch/index.d.ts +3 -3
  59. package/dist/utils/fetch/index.js +3 -3
  60. package/dist/utils/index.d.ts +10 -9
  61. package/dist/utils/index.js +10 -9
  62. package/dist/utils/index.js.map +1 -1
  63. package/dist/utils/labels/LanguageLoader.d.ts +7 -7
  64. package/dist/utils/labels/LanguageLoader.js +130 -100
  65. package/dist/utils/labels/LanguageLoader.js.map +1 -1
  66. package/dist/utils/labels/LanguageManager.d.ts +6 -6
  67. package/dist/utils/labels/LanguageManager.js +118 -110
  68. package/dist/utils/labels/LanguageManager.js.map +1 -1
  69. package/dist/utils/labels/LanguageReturner.d.ts +10 -10
  70. package/dist/utils/labels/LanguageReturner.js +70 -69
  71. package/dist/utils/labels/LanguageReturner.js.map +1 -1
  72. package/dist/utils/labels/index.d.ts +4 -4
  73. package/dist/utils/labels/index.js +4 -4
  74. package/docs/APP_ICON.md +82 -0
  75. package/docs/APP_INPUT.md +81 -0
  76. package/docs/APP_PAGINATION.md +61 -0
  77. package/docs/CONFIGURATION.md +105 -0
  78. package/docs/FETCH_WRAPPER.md +163 -0
  79. package/docs/LABELS.md +148 -0
  80. package/docs/LOGGER.md +112 -0
  81. package/docs/SECURITY_AUDIT_2026-02-05.md +468 -0
  82. package/docs/SPIN.md +45 -0
  83. package/docs/TOASTER.md +75 -0
  84. package/docs/UTILITIES.md +177 -0
  85. package/package.json +25 -35
  86. package/src/App.css +0 -12
  87. package/src/lib/components/AppIcon.tsx +0 -784
  88. package/src/lib/components/AppInput.tsx +0 -66
  89. package/src/lib/components/AppPagination.tsx +0 -124
  90. package/src/lib/components/Spin.tsx +0 -31
  91. package/src/lib/components/Toaster/Toaster.tsx +0 -50
  92. package/src/lib/components/Toaster/Types.ts +0 -11
  93. package/src/lib/components/index.ts +0 -8
  94. package/src/lib/index.ts +0 -15
  95. package/src/lib/styles/base.css +0 -392
  96. package/src/lib/styles/syncfusion_bootstrap4.css +0 -10
  97. package/src/lib/styles/toaster.css +0 -50
  98. package/src/lib/utils/CurrencyUtiles.ts +0 -48
  99. package/src/lib/utils/DateUtils.ts +0 -135
  100. package/src/lib/utils/FileUtils.ts +0 -40
  101. package/src/lib/utils/RegExValidation.ts +0 -49
  102. package/src/lib/utils/UrlUtils.ts +0 -17
  103. package/src/lib/utils/configuration/ConfigurationLoader.tsx +0 -43
  104. package/src/lib/utils/configuration/ConfigurationManager.ts +0 -38
  105. package/src/lib/utils/configuration/ConfigurationReturner.tsx +0 -39
  106. package/src/lib/utils/configuration/index.ts +0 -9
  107. package/src/lib/utils/fetch/Types.ts +0 -11
  108. package/src/lib/utils/fetch/fetchWrapper.ts +0 -174
  109. package/src/lib/utils/fetch/index.ts +0 -4
  110. package/src/lib/utils/index.ts +0 -11
  111. package/src/lib/utils/labels/LanguageLoader.tsx +0 -69
  112. package/src/lib/utils/labels/LanguageManager.ts +0 -61
  113. package/src/lib/utils/labels/LanguageReturner.tsx +0 -41
  114. package/src/lib/utils/labels/index.ts +0 -9
@@ -1,70 +1,71 @@
1
- var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
2
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3
- return new (P || (P = Promise))(function (resolve, reject) {
4
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
5
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
6
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
7
- step((generator = generator.apply(thisArg, _arguments || [])).next());
8
- });
9
- };
10
- var __generator = (this && this.__generator) || function (thisArg, body) {
11
- var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype);
12
- return g.next = verb(0), g["throw"] = verb(1), g["return"] = verb(2), typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
13
- function verb(n) { return function (v) { return step([n, v]); }; }
14
- function step(op) {
15
- if (f) throw new TypeError("Generator is already executing.");
16
- while (g && (g = 0, op[0] && (_ = 0)), _) try {
17
- if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
18
- if (y = 0, t) op = [op[0] & 2, t.value];
19
- switch (op[0]) {
20
- case 0: case 1: t = op; break;
21
- case 4: _.label++; return { value: op[1], done: false };
22
- case 5: _.label++; y = op[1]; op = [0]; continue;
23
- case 7: op = _.ops.pop(); _.trys.pop(); continue;
24
- default:
25
- if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
26
- if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
27
- if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
28
- if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
29
- if (t[2]) _.ops.pop();
30
- _.trys.pop(); continue;
31
- }
32
- op = body.call(thisArg, _);
33
- } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
34
- if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
35
- }
36
- };
37
- import { jsx as _jsx } from "react/jsx-runtime";
38
- import React, { useEffect } from 'react';
39
- import LanguageManager from './LanguageManager';
40
- export default function LanguageReturner(_a) {
41
- var labels = _a.labels, language = _a.language, onLanguageLoad = _a.onLanguageLoad, path = _a.path;
42
- var loadLabels = LanguageManager().loadLabels;
43
- var fullPath = "".concat(path, "/").concat(language, ".json");
44
- useEffect(function () {
45
- function justAsync() {
46
- return __awaiter(this, void 0, void 0, function () {
47
- return __generator(this, function (_a) {
48
- switch (_a.label) {
49
- case 0:
50
- if (!(!labels || !labels.language || labels.language !== language)) return [3, 2];
51
- console.log("Loading Language Labels for this Path: ".concat(path, " in this fullpath: ").concat(fullPath));
52
- return [4, loadLabels(fullPath).then(function (response) {
53
- console.log("Loaded Language Labels for this Path: ".concat(path, " in this fullpath: ").concat(fullPath), response);
54
- onLanguageLoad(response);
55
- }).catch(function (err) {
56
- console.error("Problem loading the Path: ".concat(path, " Language Labels in this fullpath: ").concat(fullPath));
57
- })];
58
- case 1:
59
- _a.sent();
60
- _a.label = 2;
61
- case 2: return [2];
62
- }
63
- });
64
- });
65
- }
66
- justAsync();
67
- }, [language]);
68
- return (_jsx(React.Fragment, {}));
69
- }
1
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
2
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3
+ return new (P || (P = Promise))(function (resolve, reject) {
4
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
5
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
6
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
7
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
8
+ });
9
+ };
10
+ var __generator = (this && this.__generator) || function (thisArg, body) {
11
+ var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
12
+ return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
13
+ function verb(n) { return function (v) { return step([n, v]); }; }
14
+ function step(op) {
15
+ if (f) throw new TypeError("Generator is already executing.");
16
+ while (g && (g = 0, op[0] && (_ = 0)), _) try {
17
+ if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
18
+ if (y = 0, t) op = [op[0] & 2, t.value];
19
+ switch (op[0]) {
20
+ case 0: case 1: t = op; break;
21
+ case 4: _.label++; return { value: op[1], done: false };
22
+ case 5: _.label++; y = op[1]; op = [0]; continue;
23
+ case 7: op = _.ops.pop(); _.trys.pop(); continue;
24
+ default:
25
+ if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
26
+ if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
27
+ if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
28
+ if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
29
+ if (t[2]) _.ops.pop();
30
+ _.trys.pop(); continue;
31
+ }
32
+ op = body.call(thisArg, _);
33
+ } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
34
+ if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
35
+ }
36
+ };
37
+ import { jsx as _jsx } from "react/jsx-runtime";
38
+ import React, { useEffect } from 'react';
39
+ import Logger from '../Logger';
40
+ import LanguageManager from './LanguageManager';
41
+ export default function LanguageReturner(_a) {
42
+ var labels = _a.labels, language = _a.language, onLanguageLoad = _a.onLanguageLoad, path = _a.path;
43
+ var loadLabels = LanguageManager().loadLabels;
44
+ var fullPath = "".concat(path, "/").concat(language, ".json");
45
+ useEffect(function () {
46
+ function justAsync() {
47
+ return __awaiter(this, void 0, void 0, function () {
48
+ return __generator(this, function (_a) {
49
+ switch (_a.label) {
50
+ case 0:
51
+ if (!(!labels || !labels.language || labels.language !== language)) return [3, 2];
52
+ Logger.debug("Loading Language Labels for this Path: ".concat(path, " in this fullpath: ").concat(fullPath));
53
+ return [4, loadLabels(fullPath).then(function (response) {
54
+ Logger.debug("Loaded Language Labels for this Path: ".concat(path, " in this fullpath: ").concat(fullPath), response);
55
+ onLanguageLoad(response);
56
+ }).catch(function (err) {
57
+ Logger.error("Problem loading the Path: ".concat(path, " Language Labels in this fullpath: ").concat(fullPath));
58
+ })];
59
+ case 1:
60
+ _a.sent();
61
+ _a.label = 2;
62
+ case 2: return [2];
63
+ }
64
+ });
65
+ });
66
+ }
67
+ justAsync();
68
+ }, [language]);
69
+ return (_jsx(React.Fragment, {}));
70
+ }
70
71
  //# sourceMappingURL=LanguageReturner.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"LanguageReturner.js","sourceRoot":"","sources":["../../../src/lib/utils/labels/LanguageReturner.tsx"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,OAAO,KAAK,EAAE,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAEzC,OAAO,eAAe,MAAM,mBAAmB,CAAC;AAYhD,MAAM,CAAC,OAAO,UAAU,gBAAgB,CAAC,EAAoE;QAAlE,MAAM,YAAA,EAAE,QAAQ,cAAA,EAAE,cAAc,oBAAA,EAAE,IAAI,UAAA;IACrE,IAAA,UAAU,GAAK,eAAe,EAAE,WAAtB,CAAuB;IAEzC,IAAM,QAAQ,GAAG,UAAG,IAAI,cAAI,QAAQ,UAAO,CAAC;IAG5C,SAAS,CAAC;QACN,SAAe,SAAS;;;;;iCAChB,CAAA,CAAC,MAAM,IAAI,CAAC,MAAM,CAAC,QAAQ,IAAI,MAAM,CAAC,QAAQ,KAAK,QAAQ,CAAA,EAA3D,cAA2D;4BAC3D,OAAO,CAAC,GAAG,CAAC,iDAA0C,IAAI,gCAAsB,QAAQ,CAAE,CAAC,CAAC;4BAC5F,WAAM,UAAU,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,UAAC,QAAa;oCAC1C,OAAO,CAAC,GAAG,CAAC,gDAAyC,IAAI,gCAAsB,QAAQ,CAAE,EAAE,QAAQ,CAAC,CAAC;oCACrG,cAAc,CAAC,QAAQ,CAAC,CAAC;gCAC7B,CAAC,CAAC,CAAC,KAAK,CAAC,UAAC,GAAQ;oCACd,OAAO,CAAC,KAAK,CAAC,oCAA6B,IAAI,gDAAsC,QAAQ,CAAE,CAAC,CAAC;gCACrG,CAAC,CAAC,EAAA;;4BALF,SAKE,CAAC;;;;;;SAEV;QACD,SAAS,EAAE,CAAC;IAEhB,CAAC,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC;IAEf,OAAO,CACH,KAAC,KAAK,CAAC,QAAQ,KACE,CACpB,CAAC;AACN,CAAC"}
1
+ {"version":3,"file":"LanguageReturner.js","sourceRoot":"","sources":["../../../src/lib/utils/labels/LanguageReturner.tsx"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,OAAO,KAAK,EAAE,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAEzC,OAAO,MAAM,MAAM,WAAW,CAAC;AAC/B,OAAO,eAAe,MAAM,mBAAmB,CAAC;AAYhD,MAAM,CAAC,OAAO,UAAU,gBAAgB,CAAC,EAAoE;QAAlE,MAAM,YAAA,EAAE,QAAQ,cAAA,EAAE,cAAc,oBAAA,EAAE,IAAI,UAAA;IACrE,IAAA,UAAU,GAAK,eAAe,EAAE,WAAtB,CAAuB;IAEzC,IAAM,QAAQ,GAAG,UAAG,IAAI,cAAI,QAAQ,UAAO,CAAC;IAG5C,SAAS,CAAC;QACN,SAAe,SAAS;;;;;iCAChB,CAAA,CAAC,MAAM,IAAI,CAAC,MAAM,CAAC,QAAQ,IAAI,MAAM,CAAC,QAAQ,KAAK,QAAQ,CAAA,EAA3D,cAA2D;4BAC3D,MAAM,CAAC,KAAK,CAAC,iDAA0C,IAAI,gCAAsB,QAAQ,CAAE,CAAC,CAAC;4BAC7F,WAAM,UAAU,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,UAAC,QAAa;oCAC1C,MAAM,CAAC,KAAK,CAAC,gDAAyC,IAAI,gCAAsB,QAAQ,CAAE,EAAE,QAAQ,CAAC,CAAC;oCACtG,cAAc,CAAC,QAAQ,CAAC,CAAC;gCAC7B,CAAC,CAAC,CAAC,KAAK,CAAC,UAAC,GAAQ;oCACd,MAAM,CAAC,KAAK,CAAC,oCAA6B,IAAI,gDAAsC,QAAQ,CAAE,CAAC,CAAC;gCACpG,CAAC,CAAC,EAAA;;4BALF,SAKE,CAAC;;;;;;SAEV;QACD,SAAS,EAAE,CAAC;IAEhB,CAAC,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC;IAEf,OAAO,CACH,KAAC,KAAK,CAAC,QAAQ,KACE,CACpB,CAAC;AACN,CAAC"}
@@ -1,4 +1,4 @@
1
- import LanguageLoader from './LanguageLoader';
2
- import LanguageManager from './LanguageManager';
3
- import LanguageReturner from './LanguageReturner';
4
- export { LanguageLoader, LanguageManager, LanguageReturner };
1
+ import LanguageLoader from './LanguageLoader';
2
+ import LanguageManager from './LanguageManager';
3
+ import LanguageReturner from './LanguageReturner';
4
+ export { LanguageLoader, LanguageManager, LanguageReturner };
@@ -1,5 +1,5 @@
1
- import LanguageLoader from './LanguageLoader';
2
- import LanguageManager from './LanguageManager';
3
- import LanguageReturner from './LanguageReturner';
4
- export { LanguageLoader, LanguageManager, LanguageReturner };
1
+ import LanguageLoader from './LanguageLoader';
2
+ import LanguageManager from './LanguageManager';
3
+ import LanguageReturner from './LanguageReturner';
4
+ export { LanguageLoader, LanguageManager, LanguageReturner };
5
5
  //# sourceMappingURL=index.js.map
@@ -0,0 +1,82 @@
1
+ # AppIcon
2
+
3
+ SVG icon component with 40+ built-in icon variants.
4
+
5
+ ## Import
6
+
7
+ ```javascript
8
+ import { Components } from '@firedesktop/react-base';
9
+ const { AppIcon } = Components;
10
+ ```
11
+
12
+ ## Props
13
+
14
+ | Prop | Type | Required | Default | Description |
15
+ |------|------|----------|---------|-------------|
16
+ | `name` | `string` (union) | Yes | -- | Icon identifier (see list below) |
17
+ | `className` | `string` | Yes | -- | CSS class applied to the SVG `<path>` elements |
18
+ | `iconClassName` | `string` | Yes | -- | CSS class applied to the `<svg>` element |
19
+ | `iconHeight` | `number` | No | varies | SVG height in pixels |
20
+ | `iconWidth` | `number` | No | varies | SVG width in pixels |
21
+ | `fill` | `string` | No | `'none'` | SVG fill color |
22
+ | `stroke` | `string` | No | -- | SVG stroke color |
23
+ | `onClick` | `(event: React.MouseEvent<SVGSVGElement>) => void` | No | -- | Click handler |
24
+ | `ref` | `React.LegacyRef<SVGSVGElement>` | No | -- | Ref to the SVG element |
25
+
26
+ ## Available Icons
27
+
28
+ ### Actions
29
+ `add`, `edit`, `delete`, `list`, `link`, `unlink`, `shrink`, `upload`, `download`, `share`
30
+
31
+ ### Navigation
32
+ `arrow-first`, `arrow-prev`, `arrow-next`, `arrow-last`, `expand`, `backicon`, `home`
33
+
34
+ ### Form / Auth
35
+ `user`, `password`
36
+
37
+ ### Status
38
+ `tickTrue`, `tickFalse`, `tickStep`, `circle`
39
+
40
+ ### Domain
41
+ `document`, `company`, `plantMonitor`, `plantMissing`, `contact`, `userManagement`, `configurations`, `documentTemplate`, `registry`, `material`, `supply`, `delivery`, `table`
42
+
43
+ ### UI
44
+ `eye`, `search`, `logo-main`, `unPin`, `Pin`, `pin-tilted`
45
+
46
+ ## Usage
47
+
48
+ ```jsx
49
+ <AppIcon
50
+ name="edit"
51
+ className="primary-svg"
52
+ iconClassName="my-icon"
53
+ iconWidth={24}
54
+ iconHeight={24}
55
+ fill="none"
56
+ stroke="#0057ff"
57
+ />
58
+ ```
59
+
60
+ ### With click handler
61
+
62
+ ```jsx
63
+ <AppIcon
64
+ name="delete"
65
+ className="danger-svg"
66
+ iconClassName="action-icon"
67
+ onClick={() => handleDelete(item.id)}
68
+ />
69
+ ```
70
+
71
+ ### Styling with CSS utility classes
72
+
73
+ The library provides utility classes in `base.css` for coloring icons:
74
+
75
+ ```jsx
76
+ {/* Fill-based coloring */}
77
+ <AppIcon name="tickTrue" className="success-svg" iconClassName="" />
78
+ <AppIcon name="tickFalse" className="danger-svg" iconClassName="" />
79
+
80
+ {/* Stroke-based coloring */}
81
+ <AppIcon name="edit" className="primary-svg-stroke" iconClassName="" />
82
+ ```
@@ -0,0 +1,81 @@
1
+ # AppInput
2
+
3
+ Input wrapper component with icon support, built on Bootstrap form classes.
4
+
5
+ ## Import
6
+
7
+ ```javascript
8
+ import { Components } from '@firedesktop/react-base';
9
+ const { AppIcon, AppInput } = Components;
10
+ ```
11
+
12
+ ## Props
13
+
14
+ | Prop | Type | Required | Default | Description |
15
+ |------|------|----------|---------|-------------|
16
+ | `appIcon` | `React.ReactNode` | Yes | -- | Icon element rendered alongside the input |
17
+ | `type` | `AppInputType_Type` | No | `'text'` | HTML input type |
18
+ | `value` | `string \| number` | No | -- | Controlled input value |
19
+ | `placeholder` | `string` | No | -- | Placeholder text |
20
+ | `onChange` | `(event: React.ChangeEvent<HTMLInputElement>) => void` | No | -- | Change handler |
21
+ | `onKeyUp` | `(event: React.KeyboardEvent<HTMLInputElement>) => void` | No | -- | Key up handler |
22
+ | `className` | `string` | No | -- | CSS class for the `<input>` element |
23
+ | `classNameWrapper` | `string` | No | -- | CSS class appended to the wrapper `<div>` |
24
+ | `id` | `string` | No | -- | Input ID attribute |
25
+ | `name` | `string` | No | -- | Input name attribute |
26
+ | `autoFocus` | `boolean` | No | `false` | Auto focus on mount |
27
+ | `autoComplete` | `boolean` | No | `true` | Browser autocomplete (`on`/`off`) |
28
+ | `ariadescribedby` | `string` | No | -- | ARIA described-by attribute |
29
+ | `ref` | `React.LegacyRef<HTMLInputElement>` | No | -- | Ref to the input element |
30
+
31
+ ### Supported input types
32
+
33
+ `button`, `checkbox`, `color`, `date`, `datetime-local`, `email`, `file`, `hidden`, `image`, `month`, `number`, `password`, `radio`, `range`, `reset`, `search`, `submit`, `tel`, `text`, `url`, `week`
34
+
35
+ ## Usage
36
+
37
+ ```jsx
38
+ <AppInput
39
+ appIcon={<AppIcon name="search" className="primary-svg" iconClassName="" />}
40
+ placeholder="Search..."
41
+ value={query}
42
+ onChange={(e) => setQuery(e.target.value)}
43
+ />
44
+ ```
45
+
46
+ ### Password input
47
+
48
+ ```jsx
49
+ <AppInput
50
+ appIcon={<AppIcon name="password" className="primary-svg" iconClassName="" />}
51
+ type="password"
52
+ placeholder="Enter password"
53
+ autoComplete={false}
54
+ />
55
+ ```
56
+
57
+ ### With key handler
58
+
59
+ ```jsx
60
+ <AppInput
61
+ appIcon={<AppIcon name="search" className="primary-svg" iconClassName="" />}
62
+ type="text"
63
+ placeholder="Search and press Enter"
64
+ value={query}
65
+ onChange={(e) => setQuery(e.target.value)}
66
+ onKeyUp={(e) => {
67
+ if (e.key === 'Enter') handleSearch();
68
+ }}
69
+ />
70
+ ```
71
+
72
+ ## HTML Output
73
+
74
+ ```html
75
+ <div class="form-group AppInput_form {classNameWrapper}">
76
+ <input class="form-control {className}" type="text" ... />
77
+ <!-- appIcon rendered here -->
78
+ </div>
79
+ ```
80
+
81
+ Requires Bootstrap `form-group` and `form-control` classes (peer dependency).
@@ -0,0 +1,61 @@
1
+ # AppPagination
2
+
3
+ Bootstrap-based pagination component with smart page range calculation.
4
+
5
+ ## Import
6
+
7
+ ```javascript
8
+ import { Components } from '@firedesktop/react-base';
9
+ const { AppPagination } = Components;
10
+ ```
11
+
12
+ ## Props
13
+
14
+ | Prop | Type | Required | Default | Description |
15
+ |------|------|----------|---------|-------------|
16
+ | `activePage` | `number` | Yes | -- | Current active page (1-based) |
17
+ | `totalItems` | `number` | Yes | -- | Total number of items across all pages |
18
+ | `itemsPerPage` | `number` | Yes | -- | Number of items displayed per page |
19
+ | `onPageChange` | `(page: number) => void` | Yes | -- | Callback when page changes |
20
+ | `maxSize` | `number` | No | `5` | Maximum number of page buttons visible |
21
+ | `pageFontSize` | `number` | No | `14` | Font size for page numbers in pixels |
22
+ | `className` | `string` | No | -- | CSS class for the `<nav>` element |
23
+
24
+ ## Usage
25
+
26
+ ```jsx
27
+ const [page, setPage] = useState(1);
28
+ const itemsPerPage = 10;
29
+ const totalItems = 87;
30
+
31
+ <AppPagination
32
+ activePage={page}
33
+ totalItems={totalItems}
34
+ itemsPerPage={itemsPerPage}
35
+ onPageChange={(newPage) => setPage(newPage)}
36
+ />
37
+ ```
38
+
39
+ ### Custom page window size
40
+
41
+ ```jsx
42
+ <AppPagination
43
+ activePage={page}
44
+ totalItems={200}
45
+ itemsPerPage={25}
46
+ maxSize={3}
47
+ onPageChange={setPage}
48
+ />
49
+ ```
50
+
51
+ ## Behavior
52
+
53
+ - Shows first, previous, next, and last navigation arrows (using `AppIcon`)
54
+ - Displays a centered window of page numbers around the active page
55
+ - Automatically adjusts the window when near the first or last page
56
+ - Active page is highlighted with Bootstrap's `.active` class
57
+ - Navigation arrows are disabled when at boundaries (first/last page)
58
+
59
+ ## Dependencies
60
+
61
+ Requires Bootstrap `pagination` CSS classes (peer dependency).
@@ -0,0 +1,105 @@
1
+ # Configuration
2
+
3
+ Runtime configuration loader that fetches a JSON file and stores it in Redux state or returns it via callback.
4
+
5
+ ## Components
6
+
7
+ ### ConfigurationLoader (Redux)
8
+
9
+ Headless component that loads configuration on mount and dispatches to Redux.
10
+
11
+ ```javascript
12
+ import { ConfigurationLoader } from '@firedesktop/react-base';
13
+ ```
14
+
15
+ #### Props
16
+
17
+ | Prop | Type | Required | Default | Description |
18
+ |------|------|----------|---------|-------------|
19
+ | `updateAppState` | `(name: string, value: object) => any` | Yes | -- | Redux action creator |
20
+ | `path` | `string` | No | `'/configuration/config.json'` | Path to the JSON config file |
21
+
22
+ #### Usage
23
+
24
+ ```jsx
25
+ import { ConfigurationLoader } from '@firedesktop/react-base';
26
+ import { Provider } from 'react-redux';
27
+
28
+ <Provider store={store}>
29
+ <ConfigurationLoader updateAppState={updateAppState} />
30
+ <App />
31
+ </Provider>
32
+ ```
33
+
34
+ With a custom path:
35
+
36
+ ```jsx
37
+ <ConfigurationLoader updateAppState={updateAppState} path="/settings/app.json" />
38
+ ```
39
+
40
+ ### ConfigurationReturner (Callback)
41
+
42
+ For applications not using Redux. Loads configuration and calls a callback.
43
+
44
+ ```javascript
45
+ import { ConfigurationReturner } from '@firedesktop/react-base';
46
+ ```
47
+
48
+ #### Props
49
+
50
+ | Prop | Type | Required | Description |
51
+ |------|------|----------|-------------|
52
+ | `configuration` | `{ loaded: boolean }` | No | Current config state (prevents re-loading) |
53
+ | `onConfigurationLoad` | `(config?) => void` | Yes | Callback receiving the loaded config |
54
+ | `path` | `string` | Yes | Path to the JSON config file |
55
+
56
+ #### Usage
57
+
58
+ ```jsx
59
+ <ConfigurationReturner
60
+ configuration={config}
61
+ onConfigurationLoad={(cfg) => setConfig({ ...cfg, loaded: true })}
62
+ path="/configuration/config.json"
63
+ />
64
+ ```
65
+
66
+ ## Configuration File Format
67
+
68
+ Place a JSON file in `public/configuration/config.json`:
69
+
70
+ ```json
71
+ {
72
+ "apiBaseUrl": "https://api.example.com",
73
+ "appTitle": "My Application",
74
+ "features": {
75
+ "darkMode": true,
76
+ "notifications": false
77
+ }
78
+ }
79
+ ```
80
+
81
+ The response must be a plain JSON object (not an array or primitive).
82
+
83
+ ## Behavior
84
+
85
+ - Fetches with cache-busting timestamp query parameter
86
+ - Sets `Cache-Control`, `pragma`, `Expires`, and `X-Content-Type-Options` headers
87
+ - Validates HTTP status (`res.ok`) before parsing
88
+ - Validates the response is a plain object
89
+ - Dispatches as `updateAppState('configuration', response)` (Redux variant)
90
+ - Loads only once -- skips if `configuration.loaded` is already truthy
91
+ - Errors are logged via [Logger](LOGGER.md) (silent by default)
92
+
93
+ ## Accessing Configuration
94
+
95
+ ```javascript
96
+ import { useSelector } from 'react-redux';
97
+
98
+ function MyComponent() {
99
+ const { configuration } = useSelector(state => state);
100
+
101
+ if (!configuration) return <Spin spinning={true} />;
102
+
103
+ return <div>{configuration.appTitle}</div>;
104
+ }
105
+ ```
@@ -0,0 +1,163 @@
1
+ # FetchWrapper
2
+
3
+ HTTP client class with session-token authentication, configurable error handling, timeout support, and file upload capability.
4
+
5
+ ## Import
6
+
7
+ ```javascript
8
+ import { Utils } from '@firedesktop/react-base';
9
+ const FetchWrapper = Utils.Fetch;
10
+
11
+ const api = new FetchWrapper('v1', customLabels, handle401, handle403);
12
+ ```
13
+
14
+ ## Constructor
15
+
16
+ ```typescript
17
+ new FetchWrapper(
18
+ apiVersion?: string,
19
+ labels?: ILabels,
20
+ status_401?: () => Promise<void>,
21
+ status_403?: () => Promise<void>
22
+ )
23
+ ```
24
+
25
+ | Parameter | Type | Description |
26
+ |-----------|------|-------------|
27
+ | `apiVersion` | `string` | Sent as the `api-version` header on every request |
28
+ | `labels` | `ILabels` | Custom error messages (falls back to defaults if incomplete) |
29
+ | `status_401` | `() => Promise<void>` | Callback for 401 Unauthorized responses |
30
+ | `status_403` | `() => Promise<void>` | Callback for 403 Forbidden responses |
31
+
32
+ ### ILabels
33
+
34
+ ```typescript
35
+ interface ILabels {
36
+ errorBadRequest: string;
37
+ errorGeneric: string;
38
+ errorServerNotAvailable: string;
39
+ errorSessionExpired: string;
40
+ }
41
+ ```
42
+
43
+ Default labels are used if not provided:
44
+
45
+ ```
46
+ errorBadRequest: "Request is not in a valid format"
47
+ errorGeneric: "Sorry we have errors on the remote server"
48
+ errorServerNotAvailable: "Server not available"
49
+ errorSessionExpired: "Your session has expired, please login."
50
+ ```
51
+
52
+ ## Methods
53
+
54
+ All methods share the same signature and return `Promise<any>`.
55
+
56
+ ### `get`, `post`, `put`, `delete`
57
+
58
+ ```typescript
59
+ api.get(url, applicationName?, token?, onGenericServerError?, params?,
60
+ isFile?, isBlobInReturn?, additionalParams?, timeoutInMilli?)
61
+ ```
62
+
63
+ | Parameter | Type | Default | Description |
64
+ |-----------|------|---------|-------------|
65
+ | `url` | `string` | -- | Request URL |
66
+ | `applicationName` | `string` | -- | Sent as `ApplicationName` header |
67
+ | `token` | `string` | -- | Sent as `SessionToken` header |
68
+ | `onGenericServerError` | `(status: number, error?: any) => void` | -- | Error callback for non-401/403 errors |
69
+ | `params` | `Blob \| any` | -- | Request body (JSON-serialized, or Blob for files) |
70
+ | `isFile` | `boolean` | `false` | Send as `FormData` with `file` field |
71
+ | `isBlobInReturn` | `boolean` | `false` | Parse response as `Blob` instead of JSON |
72
+ | `additionalParams` | `AdditionalParamsType[]` | `[]` | Extra form fields when uploading files |
73
+ | `timeoutInMilli` | `number` | `60000` | Request timeout in milliseconds |
74
+
75
+ ### AdditionalParamsType
76
+
77
+ ```typescript
78
+ type AdditionalParamsType = {
79
+ name: string;
80
+ value: string | number;
81
+ };
82
+ ```
83
+
84
+ ## Usage
85
+
86
+ ### Basic GET
87
+
88
+ ```javascript
89
+ const api = new FetchWrapper('v1');
90
+ const data = await api.get('/api/users', 'MyApp', sessionToken);
91
+ ```
92
+
93
+ ### POST with JSON body
94
+
95
+ ```javascript
96
+ const newUser = { name: 'Alice', email: 'alice@example.com' };
97
+ const result = await api.post('/api/users', 'MyApp', sessionToken, null, newUser);
98
+ ```
99
+
100
+ ### File upload
101
+
102
+ ```javascript
103
+ const file = inputElement.files[0];
104
+ const result = await api.post(
105
+ '/api/upload', 'MyApp', sessionToken, null,
106
+ file, true, false,
107
+ [{ name: 'category', value: 'documents' }]
108
+ );
109
+ ```
110
+
111
+ ### Download as Blob
112
+
113
+ ```javascript
114
+ const blob = await api.get(
115
+ '/api/reports/export', 'MyApp', sessionToken,
116
+ null, null, false, true
117
+ );
118
+ const url = URL.createObjectURL(blob);
119
+ ```
120
+
121
+ ### With error handling
122
+
123
+ ```javascript
124
+ const api = new FetchWrapper(
125
+ 'v1',
126
+ { errorBadRequest: 'Bad request', errorGeneric: 'Error', errorServerNotAvailable: 'Offline', errorSessionExpired: 'Session expired' },
127
+ async () => { window.location.href = '/login'; }, // 401
128
+ async () => { alert('Access denied'); } // 403
129
+ );
130
+
131
+ try {
132
+ const data = await api.get('/api/data', 'MyApp', token, (status, error) => {
133
+ console.error(`Server error ${status}`, error);
134
+ });
135
+ } catch (err) {
136
+ // err is the error message string from labels
137
+ }
138
+ ```
139
+
140
+ ## Request Headers
141
+
142
+ Every request includes:
143
+
144
+ | Header | Value |
145
+ |--------|-------|
146
+ | `Cache-Control` | `no-cache, no-store, must-revalidate` |
147
+ | `pragma` | `no-cache` |
148
+ | `Expires` | `0` |
149
+ | `X-Content-Type-Options` | `nosniff` |
150
+ | `Content-Type` | `application/json` (for non-file requests with body) |
151
+ | `api-version` | Constructor `apiVersion` (if provided) |
152
+ | `ApplicationName` | Method `applicationName` (if provided) |
153
+ | `SessionToken` | Method `token` (if provided) |
154
+
155
+ ## Behavior
156
+
157
+ - CORS mode with `credentials: 'include'` (cookies sent on every request)
158
+ - Request timeout via `AbortController` (default 60s)
159
+ - Validates `Content-Type: application/json` before parsing JSON responses
160
+ - Validates HTTP status 2xx before processing the response
161
+ - 401/403 responses routed to constructor callbacks if provided
162
+ - Other errors routed to `onGenericServerError` callback if provided
163
+ - Falls back to throwing error label strings if no callback handles the error