@skalfa/skalfa-component 1.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 (231) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +79 -0
  3. package/dist/accordion/Accordion.component.d.ts +13 -0
  4. package/dist/accordion/Accordion.component.js +25 -0
  5. package/dist/breadcrumb/Breadcrumb.component.d.ts +14 -0
  6. package/dist/breadcrumb/Breadcrumb.component.js +21 -0
  7. package/dist/button/Button.component.d.ts +21 -0
  8. package/dist/button/Button.component.js +19 -0
  9. package/dist/card/AlertCard.component.d.ts +11 -0
  10. package/dist/card/AlertCard.component.js +9 -0
  11. package/dist/card/Card.component.d.ts +5 -0
  12. package/dist/card/Card.component.js +9 -0
  13. package/dist/card/DashboardCard.component.d.ts +9 -0
  14. package/dist/card/DashboardCard.component.js +13 -0
  15. package/dist/card/GalleryCard.component.d.ts +7 -0
  16. package/dist/card/GalleryCard.component.js +13 -0
  17. package/dist/card/ProductCard.component.d.ts +9 -0
  18. package/dist/card/ProductCard.component.js +13 -0
  19. package/dist/card/ProfileCard.component.d.ts +10 -0
  20. package/dist/card/ProfileCard.component.js +13 -0
  21. package/dist/carousel/Carousel.component.d.ts +13 -0
  22. package/dist/carousel/Carousel.component.js +37 -0
  23. package/dist/chip/Chip.component.d.ts +6 -0
  24. package/dist/chip/Chip.component.js +12 -0
  25. package/dist/index.d.ts +56 -0
  26. package/dist/index.js +85 -0
  27. package/dist/input/Checkbox.component.d.ts +13 -0
  28. package/dist/input/Checkbox.component.js +23 -0
  29. package/dist/input/Input.component.d.ts +23 -0
  30. package/dist/input/Input.component.js +134 -0
  31. package/dist/input/InputCheckbox.component.d.ts +27 -0
  32. package/dist/input/InputCheckbox.component.js +53 -0
  33. package/dist/input/InputCurrency.component.d.ts +21 -0
  34. package/dist/input/InputCurrency.component.js +30 -0
  35. package/dist/input/InputDate.component.d.ts +24 -0
  36. package/dist/input/InputDate.component.js +107 -0
  37. package/dist/input/InputDatetime.component.d.ts +17 -0
  38. package/dist/input/InputDatetime.component.js +75 -0
  39. package/dist/input/InputDocument.component.d.ts +22 -0
  40. package/dist/input/InputDocument.component.js +88 -0
  41. package/dist/input/InputImage.component.d.ts +23 -0
  42. package/dist/input/InputImage.component.js +260 -0
  43. package/dist/input/InputMap.component.d.ts +25 -0
  44. package/dist/input/InputMap.component.js +103 -0
  45. package/dist/input/InputNumber.component.d.ts +19 -0
  46. package/dist/input/InputNumber.component.js +40 -0
  47. package/dist/input/InputOtp.component.d.ts +14 -0
  48. package/dist/input/InputOtp.component.js +65 -0
  49. package/dist/input/InputPassword.component.d.ts +17 -0
  50. package/dist/input/InputPassword.component.js +59 -0
  51. package/dist/input/InputRadio.component.d.ts +27 -0
  52. package/dist/input/InputRadio.component.js +56 -0
  53. package/dist/input/InputTime.component.d.ts +23 -0
  54. package/dist/input/InputTime.component.js +73 -0
  55. package/dist/input/InputValues.component.d.ts +9 -0
  56. package/dist/input/InputValues.component.js +19 -0
  57. package/dist/input/Radio.component.d.ts +12 -0
  58. package/dist/input/Radio.component.js +22 -0
  59. package/dist/input/Select.component.d.ts +47 -0
  60. package/dist/input/Select.component.js +275 -0
  61. package/dist/modal/BottomSheet.component.d.ts +12 -0
  62. package/dist/modal/BottomSheet.component.js +161 -0
  63. package/dist/modal/FloatingPage.component.d.ts +12 -0
  64. package/dist/modal/FloatingPage.component.js +27 -0
  65. package/dist/modal/Modal.component.d.ts +12 -0
  66. package/dist/modal/Modal.component.js +27 -0
  67. package/dist/modal/ModalConfirm.component.d.ts +26 -0
  68. package/dist/modal/ModalConfirm.component.js +68 -0
  69. package/dist/modal/Toast.component.d.ts +11 -0
  70. package/dist/modal/Toast.component.js +58 -0
  71. package/dist/nav/Bottombar.component.d.ts +12 -0
  72. package/dist/nav/Bottombar.component.js +32 -0
  73. package/dist/nav/Footer.component.d.ts +37 -0
  74. package/dist/nav/Footer.component.js +49 -0
  75. package/dist/nav/Headbar.component.d.ts +14 -0
  76. package/dist/nav/Headbar.component.js +32 -0
  77. package/dist/nav/Navbar.component.d.ts +22 -0
  78. package/dist/nav/Navbar.component.js +26 -0
  79. package/dist/nav/Sidebar.component.d.ts +33 -0
  80. package/dist/nav/Sidebar.component.js +87 -0
  81. package/dist/nav/Tabbar.component.d.ts +13 -0
  82. package/dist/nav/Tabbar.component.js +17 -0
  83. package/dist/nav/Wizard.component.d.ts +9 -0
  84. package/dist/nav/Wizard.component.js +24 -0
  85. package/dist/src/accordion/Accordion.component.d.ts +13 -0
  86. package/dist/src/accordion/Accordion.component.js +25 -0
  87. package/dist/src/breadcrumb/Breadcrumb.component.d.ts +14 -0
  88. package/dist/src/breadcrumb/Breadcrumb.component.js +21 -0
  89. package/dist/src/button/Button.component.d.ts +21 -0
  90. package/dist/src/button/Button.component.js +19 -0
  91. package/dist/src/card/AlertCard.component.d.ts +11 -0
  92. package/dist/src/card/AlertCard.component.js +9 -0
  93. package/dist/src/card/Card.component.d.ts +5 -0
  94. package/dist/src/card/Card.component.js +9 -0
  95. package/dist/src/card/DashboardCard.component.d.ts +9 -0
  96. package/dist/src/card/DashboardCard.component.js +13 -0
  97. package/dist/src/card/GalleryCard.component.d.ts +7 -0
  98. package/dist/src/card/GalleryCard.component.js +13 -0
  99. package/dist/src/card/ProductCard.component.d.ts +9 -0
  100. package/dist/src/card/ProductCard.component.js +13 -0
  101. package/dist/src/card/ProfileCard.component.d.ts +10 -0
  102. package/dist/src/card/ProfileCard.component.js +13 -0
  103. package/dist/src/carousel/Carousel.component.d.ts +13 -0
  104. package/dist/src/carousel/Carousel.component.js +37 -0
  105. package/dist/src/chip/Chip.component.d.ts +6 -0
  106. package/dist/src/chip/Chip.component.js +12 -0
  107. package/dist/src/index.d.ts +13 -0
  108. package/dist/src/index.js +29 -0
  109. package/dist/src/input/Checkbox.component.d.ts +13 -0
  110. package/dist/src/input/Checkbox.component.js +23 -0
  111. package/dist/src/input/Input.component.d.ts +23 -0
  112. package/dist/src/input/Input.component.js +134 -0
  113. package/dist/src/input/InputCheckbox.component.d.ts +27 -0
  114. package/dist/src/input/InputCheckbox.component.js +53 -0
  115. package/dist/src/input/InputCurrency.component.d.ts +21 -0
  116. package/dist/src/input/InputCurrency.component.js +30 -0
  117. package/dist/src/input/InputDate.component.d.ts +24 -0
  118. package/dist/src/input/InputDate.component.js +107 -0
  119. package/dist/src/input/InputDatetime.component.d.ts +17 -0
  120. package/dist/src/input/InputDatetime.component.js +75 -0
  121. package/dist/src/input/InputDocument.component.d.ts +22 -0
  122. package/dist/src/input/InputDocument.component.js +88 -0
  123. package/dist/src/input/InputImage.component.d.ts +23 -0
  124. package/dist/src/input/InputImage.component.js +260 -0
  125. package/dist/src/input/InputMap.component.d.ts +25 -0
  126. package/dist/src/input/InputMap.component.js +101 -0
  127. package/dist/src/input/InputNumber.component.d.ts +19 -0
  128. package/dist/src/input/InputNumber.component.js +40 -0
  129. package/dist/src/input/InputOtp.component.d.ts +14 -0
  130. package/dist/src/input/InputOtp.component.js +65 -0
  131. package/dist/src/input/InputPassword.component.d.ts +17 -0
  132. package/dist/src/input/InputPassword.component.js +59 -0
  133. package/dist/src/input/InputRadio.component.d.ts +27 -0
  134. package/dist/src/input/InputRadio.component.js +56 -0
  135. package/dist/src/input/InputTime.component.d.ts +23 -0
  136. package/dist/src/input/InputTime.component.js +73 -0
  137. package/dist/src/input/InputValues.component.d.ts +9 -0
  138. package/dist/src/input/InputValues.component.js +19 -0
  139. package/dist/src/input/Radio.component.d.ts +12 -0
  140. package/dist/src/input/Radio.component.js +22 -0
  141. package/dist/src/input/Select.component.d.ts +47 -0
  142. package/dist/src/input/Select.component.js +275 -0
  143. package/dist/src/modal/BottomSheet.component.d.ts +12 -0
  144. package/dist/src/modal/BottomSheet.component.js +161 -0
  145. package/dist/src/modal/FloatingPage.component.d.ts +12 -0
  146. package/dist/src/modal/FloatingPage.component.js +27 -0
  147. package/dist/src/modal/Modal.component.d.ts +12 -0
  148. package/dist/src/modal/Modal.component.js +27 -0
  149. package/dist/src/modal/ModalConfirm.component.d.ts +26 -0
  150. package/dist/src/modal/ModalConfirm.component.js +68 -0
  151. package/dist/src/modal/Toast.component.d.ts +11 -0
  152. package/dist/src/modal/Toast.component.js +58 -0
  153. package/dist/src/nav/Bottombar.component.d.ts +12 -0
  154. package/dist/src/nav/Bottombar.component.js +32 -0
  155. package/dist/src/nav/Footer.component.d.ts +37 -0
  156. package/dist/src/nav/Footer.component.js +49 -0
  157. package/dist/src/nav/Headbar.component.d.ts +14 -0
  158. package/dist/src/nav/Headbar.component.js +32 -0
  159. package/dist/src/nav/Navbar.component.d.ts +22 -0
  160. package/dist/src/nav/Navbar.component.js +26 -0
  161. package/dist/src/nav/Sidebar.component.d.ts +33 -0
  162. package/dist/src/nav/Sidebar.component.js +87 -0
  163. package/dist/src/nav/Tabbar.component.d.ts +13 -0
  164. package/dist/src/nav/Tabbar.component.js +17 -0
  165. package/dist/src/nav/Wizard.component.d.ts +9 -0
  166. package/dist/src/nav/Wizard.component.js +24 -0
  167. package/dist/src/supervision/FormSupervision.component.d.ts +93 -0
  168. package/dist/src/supervision/FormSupervision.component.js +168 -0
  169. package/dist/src/supervision/TableSupervision.component.d.ts +78 -0
  170. package/dist/src/supervision/TableSupervision.component.js +273 -0
  171. package/dist/src/table/ControlBar.component.d.ts +34 -0
  172. package/dist/src/table/ControlBar.component.js +205 -0
  173. package/dist/src/table/FilterComponent.d.ts +45 -0
  174. package/dist/src/table/FilterComponent.js +132 -0
  175. package/dist/src/table/Pagination.component.d.ts +8 -0
  176. package/dist/src/table/Pagination.component.js +32 -0
  177. package/dist/src/table/Table.component.d.ts +61 -0
  178. package/dist/src/table/Table.component.js +101 -0
  179. package/dist/src/typography/TypographyArticle.component.d.ts +8 -0
  180. package/dist/src/typography/TypographyArticle.component.js +7 -0
  181. package/dist/src/typography/TypographyColumn.component.d.ts +6 -0
  182. package/dist/src/typography/TypographyColumn.component.js +7 -0
  183. package/dist/src/typography/TypographyContent.component.d.ts +6 -0
  184. package/dist/src/typography/TypographyContent.component.js +7 -0
  185. package/dist/src/typography/TypographyTips.component.d.ts +6 -0
  186. package/dist/src/typography/TypographyTips.component.js +7 -0
  187. package/dist/src/wrap/Draggable.component.d.ts +34 -0
  188. package/dist/src/wrap/Draggable.component.js +214 -0
  189. package/dist/src/wrap/Image.component.d.ts +2 -0
  190. package/dist/src/wrap/Image.component.js +13 -0
  191. package/dist/src/wrap/OutsideClick.component.d.ts +6 -0
  192. package/dist/src/wrap/OutsideClick.component.js +34 -0
  193. package/dist/src/wrap/ScrollContainer.component.d.ts +10 -0
  194. package/dist/src/wrap/ScrollContainer.component.js +54 -0
  195. package/dist/src/wrap/ShortcutProvider.d.ts +1 -0
  196. package/dist/src/wrap/ShortcutProvider.js +42 -0
  197. package/dist/src/wrap/Swipe.component.d.ts +14 -0
  198. package/dist/src/wrap/Swipe.component.js +61 -0
  199. package/dist/supervision/FormSupervision.component.d.ts +93 -0
  200. package/dist/supervision/FormSupervision.component.js +168 -0
  201. package/dist/supervision/TableSupervision.component.d.ts +78 -0
  202. package/dist/supervision/TableSupervision.component.js +273 -0
  203. package/dist/table/ControlBar.component.d.ts +34 -0
  204. package/dist/table/ControlBar.component.js +205 -0
  205. package/dist/table/FilterComponent.d.ts +45 -0
  206. package/dist/table/FilterComponent.js +132 -0
  207. package/dist/table/Pagination.component.d.ts +8 -0
  208. package/dist/table/Pagination.component.js +32 -0
  209. package/dist/table/Table.component.d.ts +61 -0
  210. package/dist/table/Table.component.js +101 -0
  211. package/dist/typography/TypographyArticle.component.d.ts +8 -0
  212. package/dist/typography/TypographyArticle.component.js +7 -0
  213. package/dist/typography/TypographyColumn.component.d.ts +6 -0
  214. package/dist/typography/TypographyColumn.component.js +7 -0
  215. package/dist/typography/TypographyContent.component.d.ts +6 -0
  216. package/dist/typography/TypographyContent.component.js +7 -0
  217. package/dist/typography/TypographyTips.component.d.ts +6 -0
  218. package/dist/typography/TypographyTips.component.js +7 -0
  219. package/dist/wrap/Draggable.component.d.ts +1 -0
  220. package/dist/wrap/Draggable.component.js +214 -0
  221. package/dist/wrap/Image.component.d.ts +2 -0
  222. package/dist/wrap/Image.component.js +13 -0
  223. package/dist/wrap/OutsideClick.component.d.ts +6 -0
  224. package/dist/wrap/OutsideClick.component.js +34 -0
  225. package/dist/wrap/ScrollContainer.component.d.ts +10 -0
  226. package/dist/wrap/ScrollContainer.component.js +54 -0
  227. package/dist/wrap/ShortcutProvider.d.ts +1 -0
  228. package/dist/wrap/ShortcutProvider.js +42 -0
  229. package/dist/wrap/Swipe.component.d.ts +14 -0
  230. package/dist/wrap/Swipe.component.js +61 -0
  231. package/package.json +44 -0
@@ -0,0 +1,205 @@
1
+ "use client";
2
+ "use strict";
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ exports.ControlBarComponent = ControlBarComponent;
5
+ const jsx_runtime_1 = require("react/jsx-runtime");
6
+ const react_1 = require("react");
7
+ const react_fontawesome_1 = require("@fortawesome/react-fontawesome");
8
+ const free_solid_svg_icons_1 = require("@fortawesome/free-solid-svg-icons");
9
+ const _utils_1 = require("@utils");
10
+ const _contexts_1 = require("@contexts");
11
+ const _components_1 = require("@components");
12
+ function ControlBarComponent({ id = "", options, className, search, onSearch, searchableOptions, searchable, onSearchable, selectableOptions, selectable, onSelectable, sortableOptions, sort, onSort, filterableColumns, onFilter, filter, onRefresh }) {
13
+ const { toggle, setToggle } = (0, _contexts_1.useToggleContext)();
14
+ const { isSm } = (0, _utils_1.useResponsive)();
15
+ const searchRef = (0, react_1.useRef)(null);
16
+ (0, react_1.useEffect)(() => {
17
+ if (options?.includes("SEARCH")) {
18
+ _utils_1.shortcut.register("ctrl+s", () => {
19
+ searchRef.current?.focus();
20
+ }, "Cari");
21
+ }
22
+ if (options?.includes("FILTER")) {
23
+ _utils_1.shortcut.register("ctrl+f", () => {
24
+ setToggle("FILTER");
25
+ }, "Filter");
26
+ }
27
+ if (options?.includes("SORT")) {
28
+ _utils_1.shortcut.register("ctrl+o", () => {
29
+ setToggle("SORT");
30
+ }, "Urutkan");
31
+ }
32
+ if (options?.includes("SELECTABLE")) {
33
+ _utils_1.shortcut.register("ctrl+l", () => {
34
+ setToggle("SELECTABLE");
35
+ }, "Kolom Ditampilkan");
36
+ }
37
+ if (options?.includes("REFRESH")) {
38
+ _utils_1.shortcut.register("ctrl+shift+r", () => {
39
+ onRefresh?.();
40
+ }, "Refresh Tabel");
41
+ }
42
+ return () => {
43
+ options?.includes("SEARCH") && _utils_1.shortcut.unregister("ctrl+s");
44
+ options?.includes("FILTER") && _utils_1.shortcut.unregister("ctrl+f");
45
+ options?.includes("SORT") && _utils_1.shortcut.unregister("ctrl+o");
46
+ options?.includes("SELECTABLE") && _utils_1.shortcut.unregister("ctrl+l");
47
+ options?.includes("REFRESH") && _utils_1.shortcut.unregister("ctrl+shift+r");
48
+ };
49
+ }, [options]);
50
+ const onChangeSort = (item) => {
51
+ if (!!sort?.find((s) => s.split(" ")?.at(0) == item)) {
52
+ const findSort = sort.find((s) => s.split(" ")?.at(0) == item);
53
+ if (findSort?.split(" ")?.at(1) == "desc") {
54
+ onSort?.(sort.filter((s) => s != findSort));
55
+ }
56
+ else {
57
+ const newSorts = [...sort];
58
+ newSorts[newSorts?.findIndex((s) => s == findSort)] = `${item} desc`;
59
+ onSort?.(newSorts);
60
+ }
61
+ }
62
+ else {
63
+ onSort?.([...(sort || []), `${item} asc`]);
64
+ }
65
+ };
66
+ return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)("div", { className: (0, _utils_1.cn)("control-bar", className), children: (isSm ? [
67
+ ...(options?.filter((op, iop) => iop == 0 || op == "REFRESH") || []),
68
+ ...(options && options?.length > 1 ? ['MOBILE_OPTION'] : [])
69
+ ] : options)?.map((option, key) => {
70
+ {
71
+ // =========================>
72
+ // ## Create button
73
+ // =========================>
74
+ }
75
+ if (option == "CREATE") {
76
+ return ((0, jsx_runtime_1.jsx)("div", { className: "control-bar-create-wrapper", children: (0, jsx_runtime_1.jsx)(_components_1.ButtonComponent, { icon: free_solid_svg_icons_1.faPlus, label: "Tambah Data", size: "sm", onClick: () => setToggle(`MODAL_FORM_${_utils_1.conversion.strSnake(id).toUpperCase()}`) }) }, "button-add"));
77
+ }
78
+ {
79
+ // =========================>
80
+ // ## Search Field
81
+ // =========================>
82
+ }
83
+ if (option == "SEARCH") {
84
+ const searchable = !!options?.find((option) => option == "SEARCHABLE");
85
+ return ((0, jsx_runtime_1.jsx)("div", { className: (0, _utils_1.cn)("control-bar-search-wrapper", searchable ? "control-bar-search-wrapper-searchable" : "control-bar-search-wrapper-standalone"), children: (0, jsx_runtime_1.jsx)(_components_1.InputComponent, { ref: searchRef, name: "search", placeholder: "Cari disini...", rightIcon: free_solid_svg_icons_1.faMagnifyingGlass, value: search, onChange: (e) => onSearch?.(e), className: (0, _utils_1.cn)("control-bar-search-input", searchable && "control-bar-search-input-searchable") }) }, key));
86
+ }
87
+ {
88
+ // =========================>
89
+ // ## Searchable Field
90
+ // =========================>
91
+ }
92
+ if (option == "SEARCHABLE") {
93
+ return searchableOptions?.length ? ((0, jsx_runtime_1.jsx)("div", { className: "control-bar-searchable-wrapper", children: (0, jsx_runtime_1.jsx)(_components_1.SelectComponent, { name: "searchableColumn", leftIcon: free_solid_svg_icons_1.faSearch, options: searchableOptions?.map((column) => {
94
+ return {
95
+ label: column.label,
96
+ value: column.selector,
97
+ };
98
+ }) || [], value: searchable, onChange: (e) => onSearchable?.(e), className: "control-bar-searchable-select", multiple: true }) }, key)) : (0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, {});
99
+ }
100
+ {
101
+ // =========================>
102
+ // ## Selectable Button
103
+ // =========================>
104
+ }
105
+ if (option == "SELECTABLE") {
106
+ return ((0, jsx_runtime_1.jsxs)("div", { className: "control-bar-button-wrapper", children: [(0, jsx_runtime_1.jsx)(_components_1.ButtonComponent, { icon: free_solid_svg_icons_1.faEyeLowVision, variant: "outline", className: "control-bar-icon-button", onClick: () => setToggle("SELECTABLE"), size: "sm" }), (0, jsx_runtime_1.jsx)(_components_1.OutsideClickComponent, { onOutsideClick: () => setToggle("SELECTABLE", false), children: (0, jsx_runtime_1.jsxs)("div", { className: (0, _utils_1.cn)("control-bar-dropdown", !toggle.SELECTABLE && "control-bar-dropdown-hidden"), children: [(0, jsx_runtime_1.jsx)("p", { className: 'control-bar-dropdown-title', children: "Kolom Ditampilkan" }), (0, jsx_runtime_1.jsx)(_components_1.InputCheckboxComponent, { vertical: true, name: "show_column", options: selectableOptions?.map((option) => {
107
+ return {
108
+ label: option.label,
109
+ value: option.selector,
110
+ };
111
+ }), onChange: (e) => onSelectable?.(Array().concat(e).map((val) => String(val))), value: selectable, className: 'control-bar-selectable-checkbox-list', classNameCheckbox: 'control-bar-selectable-checkbox label::text-xs' })] }) })] }, key));
112
+ }
113
+ {
114
+ // =========================>
115
+ // ## Sort Button
116
+ // =========================>
117
+ }
118
+ if (option == "SORT") {
119
+ return sortableOptions?.length ? ((0, jsx_runtime_1.jsxs)("div", { className: "control-bar-button-wrapper", children: [(0, jsx_runtime_1.jsx)(_components_1.ButtonComponent, { icon: free_solid_svg_icons_1.faSort, variant: "outline", className: "control-bar-icon-button", onClick: () => setToggle("SORT"), size: "sm" }), (0, jsx_runtime_1.jsx)(_components_1.OutsideClickComponent, { onOutsideClick: () => setToggle("SORT", false), children: (0, jsx_runtime_1.jsxs)("div", { className: (0, _utils_1.cn)("control-bar-dropdown", !toggle.SORT && "control-bar-dropdown-hidden"), children: [(0, jsx_runtime_1.jsx)("p", { className: 'control-bar-dropdown-title', children: "Urut Berdasarkan" }), (0, jsx_runtime_1.jsx)("div", { className: 'control-bar-sort-list', children: sortableOptions?.map((option, key) => {
120
+ const sortBy = sort?.find((s) => s.split(" ")?.at(0) == option?.selector)?.split(" ")?.at(1) || "";
121
+ return ((0, jsx_runtime_1.jsxs)("div", { className: (0, _utils_1.cn)('control-bar-sort-item', !!sortBy && "control-bar-sort-item-active"), onClick: () => onChangeSort(option.selector), children: [(0, jsx_runtime_1.jsx)("p", { children: option.label }), sortBy && ((0, jsx_runtime_1.jsxs)("div", { className: 'control-bar-sort-active-icon', children: [(0, jsx_runtime_1.jsx)(react_fontawesome_1.FontAwesomeIcon, { icon: sortBy == "desc" ? free_solid_svg_icons_1.faArrowDownZA : free_solid_svg_icons_1.faArrowUpAZ, className: 'control-bar-sort-icon' }), sort?.length && sort?.length > 1 && (0, jsx_runtime_1.jsx)("span", { className: 'control-bar-sort-badge', children: sort.findIndex((s) => s.split(" ")?.at(0) == option?.selector) + 1 })] }))] }, key));
122
+ }) })] }) })] }, key)) : (0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, {});
123
+ }
124
+ {
125
+ // =========================>
126
+ // ## Refresh Button
127
+ // =========================>
128
+ }
129
+ if (option == "REFRESH") {
130
+ return ((0, jsx_runtime_1.jsx)("div", { className: "control-bar-button-wrapper-refresh", children: (0, jsx_runtime_1.jsx)(_components_1.ButtonComponent, { icon: free_solid_svg_icons_1.faRefresh, variant: "outline", className: "control-bar-icon-button", onClick: () => onRefresh?.(), size: "sm" }) }, key));
131
+ }
132
+ {
133
+ // =========================>
134
+ // ## Filter Button
135
+ // =========================>
136
+ }
137
+ if (option == "FILTER") {
138
+ return ((0, jsx_runtime_1.jsx)("div", { className: "control-bar-button-wrapper", children: (0, jsx_runtime_1.jsx)(_components_1.ButtonComponent, { icon: free_solid_svg_icons_1.faSliders, label: "Filter", variant: "outline", className: "control-bar-filter-button", onClick: () => setToggle("FILTER"), size: "sm" }) }, key));
139
+ }
140
+ {
141
+ // =========================>
142
+ // ## Mobile option button
143
+ // =========================>
144
+ }
145
+ if (option == "MOBILE_OPTION") {
146
+ return ((0, jsx_runtime_1.jsx)("div", { className: "control-bar-button-wrapper", children: (0, jsx_runtime_1.jsx)(_components_1.ButtonComponent, { icon: free_solid_svg_icons_1.faEllipsisV, variant: "outline", className: "control-bar-icon-button", onClick: () => setToggle("MOBILE_OPTION"), size: "sm" }) }, key));
147
+ }
148
+ return option;
149
+ }) }), !!filterableColumns && !!filterableColumns?.length && ((0, jsx_runtime_1.jsx)(_components_1.FilterComponent, { className: (0, _utils_1.cn)(!toggle.FILTER ? "control-bar-filter-panel-hidden" : "control-bar-filter-panel"), columns: filterableColumns, onChange: onFilter, value: filter, onMinimize: () => setToggle("FILTER") })), isSm && ((0, jsx_runtime_1.jsx)(_components_1.BottomSheetComponent, { show: !!toggle["MOBILE_OPTION"], onClose: () => setToggle("MOBILE_OPTION", false), maxSize: "98vh", children: (0, jsx_runtime_1.jsx)("div", { className: 'control-bar-mobile-container', children: options?.filter((op, iop) => (iop != 0 && op != "CREATE" && op != "REFRESH"))?.map((option, key) => {
150
+ {
151
+ // =========================>
152
+ // ## Search Field
153
+ // =========================>
154
+ }
155
+ if (option == "SEARCH") {
156
+ return ((0, jsx_runtime_1.jsx)("div", { children: (0, jsx_runtime_1.jsx)(_components_1.InputComponent, { name: "search", placeholder: "Cari disini...", rightIcon: free_solid_svg_icons_1.faMagnifyingGlass, value: search, onChange: (e) => onSearch?.(e) }) }, key));
157
+ }
158
+ {
159
+ // =========================>
160
+ // ## Searchable Field
161
+ // =========================>
162
+ }
163
+ if (option == "SEARCHABLE") {
164
+ return searchableOptions?.length ? ((0, jsx_runtime_1.jsx)("div", { children: (0, jsx_runtime_1.jsx)(_components_1.SelectComponent, { name: "searchableColumn", leftIcon: free_solid_svg_icons_1.faSearch, options: searchableOptions?.map((column) => {
165
+ return {
166
+ label: column.label,
167
+ value: column.selector,
168
+ };
169
+ }) || [], value: searchable, onChange: (e) => onSearchable?.(e), multiple: true }) }, key)) : (0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, {});
170
+ }
171
+ {
172
+ // =========================>
173
+ // ## Selectable Button
174
+ // =========================>
175
+ }
176
+ if (option == "SELECTABLE") {
177
+ return ((0, jsx_runtime_1.jsxs)("div", { children: [(0, jsx_runtime_1.jsx)("p", { className: 'control-bar-mobile-title', children: "Kolom Ditampilkan" }), (0, jsx_runtime_1.jsx)(_components_1.InputCheckboxComponent, { vertical: true, name: "show_column", options: selectableOptions?.map((option) => {
178
+ return {
179
+ label: option.label,
180
+ value: option.selector,
181
+ };
182
+ }), onChange: (e) => onSelectable?.(Array().concat(e).map((val) => String(val))), value: selectable, className: 'control-bar-mobile-checkbox-list', classNameCheckbox: 'control-bar-selectable-checkbox label::text-xs' })] }, key));
183
+ }
184
+ {
185
+ // =========================>
186
+ // ## Sort Button
187
+ // =========================>
188
+ }
189
+ if (option == "SORT") {
190
+ return sortableOptions?.length ? ((0, jsx_runtime_1.jsxs)("div", { children: [(0, jsx_runtime_1.jsx)("p", { className: 'control-bar-mobile-title', children: "Urut Berdasarkan" }), (0, jsx_runtime_1.jsx)("div", { className: 'flex flex-col', children: sortableOptions?.map((option, key) => {
191
+ const sortBy = sort?.find((s) => s.split(" ")?.at(0) == option?.selector)?.split(" ")?.at(1) || "";
192
+ return ((0, jsx_runtime_1.jsxs)("div", { className: (0, _utils_1.cn)('control-bar-mobile-sort-item', !!sortBy && "control-bar-mobile-sort-item-active"), onClick: () => onChangeSort(option.selector), children: [(0, jsx_runtime_1.jsx)("p", { children: option.label }), sortBy && ((0, jsx_runtime_1.jsxs)("div", { className: 'text-primary', children: [(0, jsx_runtime_1.jsx)(react_fontawesome_1.FontAwesomeIcon, { icon: sortBy == "desc" ? free_solid_svg_icons_1.faArrowDownZA : free_solid_svg_icons_1.faArrowUpAZ, className: 'text-xs' }), sort?.length && sort?.length > 1 && (0, jsx_runtime_1.jsx)("span", { className: 'text-[9px] ml-1', children: sort.findIndex((s) => s.split(" ")?.at(0) == option?.selector) + 1 })] }))] }, key));
193
+ }) })] }, key)) : (0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, {});
194
+ }
195
+ {
196
+ // =========================>
197
+ // ## Filter
198
+ // =========================>
199
+ }
200
+ if (option == "FILTER") {
201
+ return ((0, jsx_runtime_1.jsx)("div", { children: filterableColumns && filterableColumns?.length && ((0, jsx_runtime_1.jsx)(_components_1.FilterComponent, { className: 'control-bar-mobile-filter title::text-xs', columns: filterableColumns, onChange: onFilter, value: filter })) }, key));
202
+ }
203
+ return option;
204
+ }) }) }))] }));
205
+ }
@@ -0,0 +1,45 @@
1
+ import { ApiFilterType } from "@utils";
2
+ export type FilterColumnOption = {
3
+ label: string;
4
+ selector: string;
5
+ type: "text" | "number" | "currency" | "date";
6
+ } | {
7
+ label: string;
8
+ selector: string;
9
+ type: "select";
10
+ options: {
11
+ label: string;
12
+ value: any;
13
+ }[];
14
+ };
15
+ export type FilterBookmark = {
16
+ id: string;
17
+ name: string;
18
+ filters: ApiFilterType[];
19
+ createdAt: number;
20
+ };
21
+ export interface AdvancedFilterProps {
22
+ columns: FilterColumnOption[];
23
+ onChange?: (filters: ApiFilterType[]) => void;
24
+ value?: ApiFilterType[];
25
+ onMinimize?: () => void;
26
+ /** Use custom class with: "title::". */
27
+ className?: string;
28
+ }
29
+ export declare function FilterComponent({ columns, onChange, value, onMinimize, className, }: AdvancedFilterProps): import("react").JSX.Element;
30
+ interface FilterInputProps {
31
+ type?: string | null;
32
+ name: string;
33
+ value: string | number | number[] | string[] | null;
34
+ onChange: (value: any) => void;
35
+ options?: {
36
+ label: string;
37
+ value: any;
38
+ }[];
39
+ placeholder?: string;
40
+ className?: string;
41
+ between?: boolean;
42
+ multiple?: boolean;
43
+ }
44
+ export declare function InputFilterValueComponent({ type, name, value, onChange, options, placeholder, className, between, multiple, }: FilterInputProps): import("react").JSX.Element;
45
+ export {};
@@ -0,0 +1,132 @@
1
+ "use client";
2
+ "use strict";
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ exports.FilterComponent = FilterComponent;
5
+ exports.InputFilterValueComponent = InputFilterValueComponent;
6
+ const jsx_runtime_1 = require("react/jsx-runtime");
7
+ const react_1 = require("react");
8
+ const free_solid_svg_icons_1 = require("@fortawesome/free-solid-svg-icons");
9
+ const _utils_1 = require("@utils");
10
+ const _components_1 = require("@components");
11
+ const _contexts_1 = require("@contexts");
12
+ const free_regular_svg_icons_1 = require("@fortawesome/free-regular-svg-icons");
13
+ const FILTER_OPERATORS = [
14
+ { label: "Cari", value: "li" },
15
+ { label: "Sama", value: "eq" },
16
+ { label: "Tidak Sama", value: "ne" },
17
+ { label: "Termasuk", value: "in" },
18
+ { label: "Tidak Termasuk", value: "ni" },
19
+ { label: "Antara", value: "bw" },
20
+ ];
21
+ const LOGIC_OPTIONS = [
22
+ { label: "Dan", value: "and" },
23
+ { label: "Atau", value: "or" },
24
+ ];
25
+ const BOOKMARK_KEY = "filter-bookmarks";
26
+ function FilterComponent({ columns, onChange, value, onMinimize, className = "", }) {
27
+ const { isSm } = (0, _utils_1.useResponsive)();
28
+ const { toggle, setToggle } = (0, _contexts_1.useToggleContext)();
29
+ const [filters, setFilters] = (0, react_1.useState)([]);
30
+ const [bookmarks, setBookmarks] = (0, react_1.useState)([]);
31
+ const handleChange = (index, key, value) => {
32
+ const updated = [...filters];
33
+ updated[index][key] = value;
34
+ if (key === "column") {
35
+ updated[index].type = "";
36
+ updated[index].value = "";
37
+ }
38
+ setFilters(updated);
39
+ };
40
+ const addFilter = () => {
41
+ setFilters([
42
+ ...filters,
43
+ { column: "", type: "", value: "", logic: filters.length ? "and" : undefined },
44
+ ]);
45
+ };
46
+ const removeFilter = (index) => {
47
+ const updated = filters.filter((_, i) => i !== index);
48
+ setFilters(updated);
49
+ };
50
+ (0, react_1.useEffect)(() => {
51
+ if (onChange)
52
+ onChange(filters);
53
+ }, [filters]);
54
+ (0, react_1.useEffect)(() => { }, [value]);
55
+ (0, react_1.useEffect)(() => {
56
+ setBookmarks(JSON.parse(localStorage.getItem(BOOKMARK_KEY) || "[]"));
57
+ }, []);
58
+ (0, react_1.useEffect)(() => {
59
+ localStorage.setItem(BOOKMARK_KEY, JSON.stringify(bookmarks));
60
+ }, [bookmarks]);
61
+ return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsxs)("div", { className: (0, _utils_1.cn)("filter-panel", (0, _utils_1.pcn)(className, "base")), children: [(0, jsx_runtime_1.jsxs)("div", { className: "filter-panel-header", children: [(0, jsx_runtime_1.jsx)("p", { className: (0, _utils_1.cn)((0, _utils_1.pcn)(className, "title")), children: "Filter" }), (0, jsx_runtime_1.jsxs)("div", { className: "filter-panel-controls", children: [(0, jsx_runtime_1.jsxs)("div", { className: "filter-panel-bookmarks-wrapper", children: [(0, jsx_runtime_1.jsx)(_components_1.ButtonComponent, { icon: free_regular_svg_icons_1.faBookmark, variant: "outline", paint: "primary", className: "filter-panel-bookmark-btn icon::text-slate-400", size: "xs", onClick: () => setToggle("MODAL_BOOKMARK", { bookmark_id: "new" }) }), !!bookmarks?.length && ((0, jsx_runtime_1.jsx)(_components_1.ChipComponent, { items: bookmarks.slice(0, 5).map((b) => b.name), onClick: (_, index) => setFilters(bookmarks[index]?.filters), onDelete: (_, index) => setBookmarks(bookmarks.filter((_, bi) => bi != index)) })), bookmarks?.length > 5 && ((0, jsx_runtime_1.jsx)(_components_1.ButtonComponent, { icon: free_solid_svg_icons_1.faEllipsisH, variant: "outline", paint: "primary", className: "filter-panel-bookmark-btn icon::text-slate-400", size: "xs", onClick: () => setToggle("MODAL_BOOKMARK_LIST") }))] }), (0, jsx_runtime_1.jsx)(_components_1.ButtonComponent, { icon: free_solid_svg_icons_1.faRotate, label: "Bersihkan", variant: "outline", paint: "primary", className: "filter-panel-bookmark-btn icon::text-slate-400", size: "xs", onClick: () => setFilters([]) }), onMinimize && ((0, jsx_runtime_1.jsx)(_components_1.ButtonComponent, { icon: free_solid_svg_icons_1.faChevronUp, variant: "outline", paint: "primary", className: "filter-panel-bookmark-btn icon::text-slate-400", size: "xs", onClick: onMinimize }))] })] }), filters.map((f, i) => {
62
+ const column = columns.find((c) => c.selector === f.column);
63
+ return ((0, jsx_runtime_1.jsxs)("div", { className: "filter-row", children: [i > 0 && ((0, jsx_runtime_1.jsx)("div", { className: "filter-col-logic", children: (0, jsx_runtime_1.jsx)(_components_1.SelectComponent, { name: `filter_logic_${i}`, options: LOGIC_OPTIONS, placeholder: "Dan/Atau", value: f.logic, onChange: (e) => handleChange(i, "logic", e), className: "filter-input-field" }) })), (0, jsx_runtime_1.jsx)("div", { className: i > 0 ? "filter-col-column-with-logic" : "filter-col-column", children: (0, jsx_runtime_1.jsx)(_components_1.SelectComponent, { name: `filter_column_${i}`, options: columns.map((c) => ({
64
+ label: c.label,
65
+ value: c.selector,
66
+ })), placeholder: "Kolom", value: f.column, onChange: (e) => handleChange(i, "column", e), className: "filter-input-field" }) }), (0, jsx_runtime_1.jsx)("div", { className: "filter-col-operator", children: (0, jsx_runtime_1.jsx)(_components_1.SelectComponent, { name: `filter_operator_${i}`, options: FILTER_OPERATORS, placeholder: "Operator", value: f.type, onChange: (e) => handleChange(i, "type", e), className: "filter-input-field" }) }), isSm && ((0, jsx_runtime_1.jsx)(_components_1.ButtonComponent, { icon: free_solid_svg_icons_1.faTimes, paint: "danger", variant: "outline", onClick: () => removeFilter(i), size: "xs" })), column && ((0, jsx_runtime_1.jsx)("div", { className: "filter-col-value", children: (0, jsx_runtime_1.jsx)(InputFilterValueComponent, { type: column.type, name: `filter_value_${i}`, placeholder: "...", value: f.value || "", onChange: (e) => handleChange(i, "value", e), options: column.type === "select" && column.options ? column.options : [], className: "filter-input-field", between: f.type === "bw", multiple: ["in", "ni"].includes(f.type || "") }) })), !isSm && ((0, jsx_runtime_1.jsx)(_components_1.ButtonComponent, { icon: free_solid_svg_icons_1.faTimes, paint: "danger", variant: "outline", onClick: () => removeFilter(i), size: "xs" }))] }, i));
67
+ }), (0, jsx_runtime_1.jsx)(_components_1.ButtonComponent, { label: "Tambahkan", icon: free_solid_svg_icons_1.faPlus, variant: "outline", paint: "primary", size: isSm ? "xs" : "sm", onClick: addFilter, className: "filter-add-btn" })] }), (0, jsx_runtime_1.jsx)(_components_1.ModalComponent, { show: !!toggle["MODAL_BOOKMARK_LIST"], onClose: () => setToggle("MODAL_BOOKMARK_LIST", false), title: "Bookmark Filter", children: (0, jsx_runtime_1.jsx)("div", { className: "filter-bookmark-list-container", children: bookmarks?.length ? bookmarks?.map((b, key) => ((0, jsx_runtime_1.jsxs)("div", { className: "filter-bookmark-row", children: [(0, jsx_runtime_1.jsx)("p", { className: "filter-bookmark-name", children: b.name }), (0, jsx_runtime_1.jsxs)("div", { className: "flex gap-2", children: [(0, jsx_runtime_1.jsx)(_components_1.ButtonComponent, { icon: free_solid_svg_icons_1.faPlus, variant: "outline", paint: "primary", className: "", size: "xs", onClick: () => {
68
+ setFilters(b.filters);
69
+ setToggle("MODAL_BOOKMARK_LIST", false);
70
+ } }), (0, jsx_runtime_1.jsx)(_components_1.ButtonComponent, { icon: free_solid_svg_icons_1.faTimes, variant: "outline", paint: "danger", className: "", size: "xs", onClick: () => setBookmarks(bookmarks.filter((_, bi) => bi != key)) })] })] }, key))) : ((0, jsx_runtime_1.jsx)("div", { className: "filter-bookmark-empty-text", children: " -- Tidak ada Bookmark --" })) }) }), (0, jsx_runtime_1.jsx)(_components_1.ModalComponent, { show: !!toggle["MODAL_BOOKMARK"], onClose: () => setToggle("MODAL_BOOKMARK", false), title: "Bookmark Filter", footer: (0, jsx_runtime_1.jsx)("div", { className: "flex justify-end", children: (0, jsx_runtime_1.jsx)(_components_1.ButtonComponent, { label: "Terapkan", onClick: () => {
71
+ let updated = [];
72
+ if (toggle["MODAL_BOOKMARK"]?.bookmark_id == "new") {
73
+ const newBookmark = {
74
+ id: crypto.randomUUID(),
75
+ name: toggle["MODAL_BOOKMARK"]?.bookmark_name || "Tanpa Nama",
76
+ filters,
77
+ createdAt: Date.now(),
78
+ };
79
+ updated = [newBookmark, ...bookmarks];
80
+ }
81
+ else {
82
+ updated = bookmarks.map(b => b.id === toggle["MODAL_BOOKMARK"]?.bookmark_id
83
+ ? { ...b, filters, createdAt: Date.now() }
84
+ : b);
85
+ }
86
+ setBookmarks(updated);
87
+ setToggle("MODAL_BOOKMARK", false);
88
+ } }) }), children: (0, jsx_runtime_1.jsxs)("div", { className: "filter-bookmark-form-container", children: [(0, jsx_runtime_1.jsx)(_components_1.SelectComponent, { name: `bookmark_id`, placeholder: "Pilih bookmark filter...", value: toggle["MODAL_BOOKMARK"]?.bookmark_id ?? "", onChange: e => setToggle("MODAL_BOOKMARK", { ...toggle["MODAL_BOOKMARK"], bookmark_id: e }), options: [
89
+ {
90
+ label: "-- BOOKMARK BARU --",
91
+ value: "new",
92
+ },
93
+ ...bookmarks.map((b) => ({
94
+ label: b.name,
95
+ value: b.id,
96
+ }))
97
+ ] }), toggle["MODAL_BOOKMARK"]?.bookmark_id == "new" && ((0, jsx_runtime_1.jsx)(_components_1.InputComponent, { name: "bookmark_name", placeholder: "Masukkan nama bookmark...", value: toggle["MODAL_BOOKMARK"]?.bookmark_name ?? "", onChange: e => setToggle("MODAL_BOOKMARK", { ...toggle["MODAL_BOOKMARK"], bookmark_name: e }), className: "filter-bookmark-form-input" }))] }) })] }));
98
+ }
99
+ function InputFilterValueComponent({ type, name, value, onChange, options = [], placeholder = "", className = "", between, multiple, }) {
100
+ const resolvedType = type || "text";
101
+ if (!between) {
102
+ switch (resolvedType) {
103
+ case "select":
104
+ return ((0, jsx_runtime_1.jsx)(_components_1.SelectComponent, { name: name, options: options, placeholder: placeholder, value: options.find((o) => o.value === value)?.label, onChange: onChange, className: className }));
105
+ case "number":
106
+ return ((0, jsx_runtime_1.jsx)(_components_1.InputNumberComponent, { name: name, value: Number(value) || 0, onChange: onChange, placeholder: placeholder, className: className, multiple: multiple }));
107
+ case "currency":
108
+ return ((0, jsx_runtime_1.jsx)(_components_1.InputCurrencyComponent, { name: name, value: Number(value) || 0, onChange: onChange, placeholder: placeholder, className: className }));
109
+ case "date":
110
+ return ((0, jsx_runtime_1.jsx)(_components_1.InputDateComponent, { name: name, value: value || "", onChange: onChange, placeholder: placeholder, className: className }));
111
+ default:
112
+ return ((0, jsx_runtime_1.jsx)(_components_1.InputComponent, { name: name, value: value || "", onChange: onChange, placeholder: placeholder, className: className, multiple: multiple }));
113
+ }
114
+ }
115
+ const val = Array.isArray(value) ? value : ["", ""];
116
+ const [from, to] = val;
117
+ const renderInput = (pos) => {
118
+ const currentValue = pos === "from" ? from : to;
119
+ const handle = (v) => onChange(pos === "from" ? [v, to] : [from, v]);
120
+ switch (resolvedType) {
121
+ case "number":
122
+ return ((0, jsx_runtime_1.jsx)(_components_1.InputNumberComponent, { name: `${name}_${pos}`, value: Number(currentValue) || 0, onChange: handle, placeholder: pos === "from" ? "Dari" : "Sampai", className: className }));
123
+ case "currency":
124
+ return ((0, jsx_runtime_1.jsx)(_components_1.InputCurrencyComponent, { name: `${name}_${pos}`, value: Number(currentValue) || 0, onChange: handle, placeholder: pos === "from" ? "Dari" : "Sampai", className: className }));
125
+ case "date":
126
+ return ((0, jsx_runtime_1.jsx)(_components_1.InputDateComponent, { name: `${name}_${pos}`, value: currentValue || "", onChange: handle, placeholder: pos === "from" ? "Dari" : "Sampai", className: className }));
127
+ default:
128
+ return ((0, jsx_runtime_1.jsx)(_components_1.InputComponent, { name: `${name}_${pos}`, value: currentValue || "", onChange: (e) => handle(e.target.value), placeholder: pos === "from" ? "Dari" : "Sampai", className: className }));
129
+ }
130
+ };
131
+ return ((0, jsx_runtime_1.jsxs)("div", { className: "filter-between-container", children: [renderInput("from"), (0, jsx_runtime_1.jsx)("span", { children: "s/d" }), renderInput("to")] }));
132
+ }
@@ -0,0 +1,8 @@
1
+ export interface PaginationProps {
2
+ totalRow: number;
3
+ paginate: number;
4
+ page: number;
5
+ onChange?: (totalRow: number, paginate: number, page: number) => void;
6
+ className?: string;
7
+ }
8
+ export declare function PaginationComponent({ paginate, page, totalRow, onChange, className, }: PaginationProps): import("react").JSX.Element | null;
@@ -0,0 +1,32 @@
1
+ "use client";
2
+ "use strict";
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ exports.PaginationComponent = PaginationComponent;
5
+ const jsx_runtime_1 = require("react/jsx-runtime");
6
+ const react_1 = require("react");
7
+ const free_solid_svg_icons_1 = require("@fortawesome/free-solid-svg-icons");
8
+ const react_fontawesome_1 = require("@fortawesome/react-fontawesome");
9
+ const _utils_1 = require("@utils");
10
+ const _components_1 = require("@components");
11
+ function PaginationComponent({ paginate = 10, page = 1, totalRow = 0, onChange, className = "", }) {
12
+ const [pages, setPages] = (0, react_1.useState)([]);
13
+ const lastPage = Math.ceil(totalRow / paginate);
14
+ (0, react_1.useEffect)(() => {
15
+ let newPages = [];
16
+ if (totalRow > paginate) {
17
+ const start = Math.max(1, page - 1);
18
+ const end = Math.min(lastPage, page + 1);
19
+ newPages = Array.from({ length: end - start + 1 }, (_, i) => start + i);
20
+ }
21
+ else {
22
+ newPages = [1];
23
+ }
24
+ setPages(newPages);
25
+ }, [totalRow, page, paginate]);
26
+ if (!totalRow)
27
+ return null;
28
+ return ((0, jsx_runtime_1.jsxs)("div", { className: (0, _utils_1.cn)("pagination-container", (0, _utils_1.pcn)(className, "base")), children: [(0, jsx_runtime_1.jsxs)("div", { className: "pagination-desktop-wrapper", children: [(0, jsx_runtime_1.jsx)(_components_1.InputRadioComponent, { name: "paginate", options: [10, 20, 50].map((val) => ({
29
+ value: val,
30
+ label: String(val),
31
+ })), value: paginate, onChange: (e) => onChange?.(totalRow, Number(e), 1), className: "pagination-paginate-select" }), totalRow > paginate && ((0, jsx_runtime_1.jsxs)("div", { className: "pagination-desktop-pages", children: [page > 1 && ((0, jsx_runtime_1.jsx)("button", { className: "pagination-overflow", onClick: () => onChange?.(totalRow, paginate, page - 1), children: (0, jsx_runtime_1.jsx)(react_fontawesome_1.FontAwesomeIcon, { icon: free_solid_svg_icons_1.faChevronLeft }) })), page > 2 && ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)("button", { className: (0, _utils_1.cn)("pagination-item", (0, _utils_1.pcn)(className, "item")), onClick: () => onChange?.(totalRow, paginate, 1), children: "1" }), page > 3 && (0, jsx_runtime_1.jsx)("span", { className: "pagination-overflow", children: "..." })] })), pages.map((p) => ((0, jsx_runtime_1.jsx)("button", { className: (0, _utils_1.cn)("pagination-item", (0, _utils_1.pcn)(className, "item"), p === page && (0, _utils_1.cn)("pagination-item-active", (0, _utils_1.pcn)(className, "active"))), onClick: () => onChange?.(totalRow, paginate, p), children: p }, p))), page < lastPage - 1 && ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [page < lastPage - 2 && ((0, jsx_runtime_1.jsx)("span", { className: "pagination-overflow", children: "..." })), (0, jsx_runtime_1.jsx)("button", { className: (0, _utils_1.cn)("pagination-item", (0, _utils_1.pcn)(className, "item")), onClick: () => onChange?.(totalRow, paginate, lastPage), children: lastPage })] })), page < lastPage && ((0, jsx_runtime_1.jsx)("button", { className: "pagination-overflow", onClick: () => onChange?.(totalRow, paginate, page + 1), children: (0, jsx_runtime_1.jsx)(react_fontawesome_1.FontAwesomeIcon, { icon: free_solid_svg_icons_1.faChevronRight }) }))] }))] }), (0, jsx_runtime_1.jsxs)("div", { className: "pagination-desktop-info", children: [Math.min(totalRow, paginate * (page - 1) + 1), " - ", Math.min(totalRow, paginate * page), " / ", totalRow] }), (0, jsx_runtime_1.jsxs)("div", { className: "pagination-mobile-wrapper", children: [(0, jsx_runtime_1.jsxs)("div", { className: "pagination-mobile-info", children: [Math.min(totalRow, paginate * (page - 1) + 1), " - ", Math.min(totalRow, paginate * page), " / ", totalRow] }), totalRow > paginate && ((0, jsx_runtime_1.jsxs)("div", { className: "pagination-mobile-controls", children: [page > 1 && ((0, jsx_runtime_1.jsx)(_components_1.ButtonComponent, { icon: free_solid_svg_icons_1.faChevronLeft, onClick: () => onChange?.(totalRow, paginate, page - 1), size: "sm" })), page < lastPage && ((0, jsx_runtime_1.jsx)(_components_1.ButtonComponent, { icon: free_solid_svg_icons_1.faChevronRight, onClick: () => onChange?.(totalRow, paginate, page + 1), size: "sm" }))] }))] })] }));
32
+ }
@@ -0,0 +1,61 @@
1
+ import { ReactNode } from "react";
2
+ import { ApiFilterType } from "@utils";
3
+ import { ControlBarOptionType, PaginationProps, SwipeActionType } from "@components";
4
+ export interface TableColumnType {
5
+ selector: string;
6
+ label: string | ReactNode;
7
+ width?: string;
8
+ sortable?: boolean;
9
+ searchable?: boolean;
10
+ filterable?: boolean | {
11
+ type: "text" | "number" | "currency" | "date";
12
+ } | {
13
+ type: "select";
14
+ options: {
15
+ label: string;
16
+ value: any;
17
+ }[];
18
+ };
19
+ className?: string;
20
+ item?: (data: any) => string | ReactNode;
21
+ tip?: string | ((data: any) => string);
22
+ }
23
+ export interface TableProps {
24
+ id?: string;
25
+ controlBar?: false | ControlBarOptionType[];
26
+ columns: TableColumnType[];
27
+ data: Record<string, any>[];
28
+ pagination?: PaginationProps | false;
29
+ loading?: boolean;
30
+ sortBy?: string[];
31
+ onChangeSortBy?: (sort: string[]) => void;
32
+ search?: string;
33
+ onChangeSearch?: (search: string) => void;
34
+ searchableColumn?: string[];
35
+ onChangeSearchableColumn?: (column: string) => void;
36
+ filter?: ApiFilterType[];
37
+ onChangeFilter?: (filters: ApiFilterType[]) => void;
38
+ checks?: (string | number)[];
39
+ onChangeChecks?: (checks: (string | number)[]) => void;
40
+ actionBulking?: ((checks: (string | number)[]) => ReactNode) | false;
41
+ focus?: number | null;
42
+ setFocus?: (focus: number | null) => void;
43
+ onRowClick?: (data: Record<string, any>, key: number) => void;
44
+ onRefresh?: () => void;
45
+ block?: boolean;
46
+ noIndex?: boolean;
47
+ responsiveControl?: {
48
+ mobile?: {
49
+ item?: (item: Record<string, any>, key: number) => ReactNode;
50
+ leftActionControl?: Omit<SwipeActionType, "onAction"> & {
51
+ onAction?: (item: Record<string, any>, key?: number) => void;
52
+ };
53
+ rightActionControl?: Omit<SwipeActionType, "onAction"> & {
54
+ onAction?: (item: Record<string, any>, key?: number) => void;
55
+ };
56
+ };
57
+ };
58
+ /** Use custom class with: "controller-bar::", "head-column::", "column::", "floating-action::", "row::". */
59
+ className?: string;
60
+ }
61
+ export declare function TableComponent({ id, controlBar, columns, data, pagination, loading, sortBy, onChangeSortBy, search, onChangeSearch, searchableColumn, onChangeSearchableColumn, filter, onChangeFilter, checks, onChangeChecks, actionBulking, focus, onRowClick, onRefresh, block, noIndex, responsiveControl, className, }: TableProps): import("react").JSX.Element;
@@ -0,0 +1,101 @@
1
+ "use client";
2
+ "use strict";
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ exports.TableComponent = TableComponent;
5
+ const jsx_runtime_1 = require("react/jsx-runtime");
6
+ const react_1 = require("react");
7
+ const react_fontawesome_1 = require("@fortawesome/react-fontawesome");
8
+ const free_solid_svg_icons_1 = require("@fortawesome/free-solid-svg-icons");
9
+ const _utils_1 = require("@utils");
10
+ const _components_1 = require("@components");
11
+ function TableComponent({ id, controlBar, columns, data, pagination, loading, sortBy, onChangeSortBy, search, onChangeSearch, searchableColumn, onChangeSearchableColumn, filter, onChangeFilter, checks, onChangeChecks, actionBulking, focus, onRowClick, onRefresh, block, noIndex, responsiveControl, className = "", }) {
12
+ const [displayColumns, setDisplayColumns] = (0, react_1.useState)([]);
13
+ const [showFloatingAction, setShowFloatingAction] = (0, react_1.useState)(false);
14
+ const [floatingActionActive, setFloatingActionActive] = (0, react_1.useState)(false);
15
+ const [keyword, setKeyword] = (0, react_1.useState)("");
16
+ const [keywordSearch] = (0, _utils_1.useLazySearch)(keyword);
17
+ const { isSm } = (0, _utils_1.useResponsive)();
18
+ const actionColumnRef = (0, react_1.useRef)(null);
19
+ (0, react_1.useEffect)(() => {
20
+ if (columns)
21
+ setDisplayColumns([...columns.map((column) => column.selector)]);
22
+ }, [columns]);
23
+ (0, react_1.useEffect)(() => {
24
+ setKeyword(search || "");
25
+ }, [search]);
26
+ (0, react_1.useEffect)(() => {
27
+ keywordSearch ? onChangeSearch?.(keywordSearch) : onChangeSearch?.("");
28
+ if (pagination != false) {
29
+ pagination?.onChange?.(pagination.totalRow, pagination.paginate, 1);
30
+ }
31
+ }, [keywordSearch]);
32
+ const columnMapping = (0, react_1.useMemo)(() => {
33
+ return (columns?.filter((column) => displayColumns.includes(column.selector)) || []);
34
+ }, [columns, displayColumns]);
35
+ const numberOfRow = (key) => pagination && (pagination?.page || 1) != 1 ? pagination?.paginate * ((pagination?.page || 1) - 1) + key + 1 : key + 1;
36
+ function renderHead() {
37
+ return ((0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, { children: columnMapping?.map((column, key) => {
38
+ const sortColumn = sortBy?.find((e) => e.split(" ")?.at(0) == column.selector)?.split(" ")?.at(0) || "";
39
+ const sortDirection = sortBy?.find((e) => e.split(" ")?.at(0) == column.selector)?.split(" ")?.at(1) || "";
40
+ return ((0, jsx_runtime_1.jsxs)("div", { className: (0, _utils_1.cn)("table-head-column", column.sortable && "cursor-pointer", (0, _utils_1.pcn)(className, "head-column")), style: { width: column.width ? column.width : 200 }, onClick: () => column.sortable && onChangeSortBy?.([`${column.selector} ${sortDirection == "desc" ? "asc" : "desc"}`]), children: [column.label, !!sortColumn && ((0, jsx_runtime_1.jsx)(react_fontawesome_1.FontAwesomeIcon, { icon: sortDirection == "desc" ? free_solid_svg_icons_1.faArrowDownZA : free_solid_svg_icons_1.faArrowUpAZ, className: "text-light-foreground/70" }))] }, key));
41
+ }) }));
42
+ }
43
+ function renderItem(item, itemKey) {
44
+ const itemMapping = columnMapping.map((column) => {
45
+ if (column?.item) {
46
+ return column.item(item);
47
+ }
48
+ const value = item[column.selector];
49
+ if ((0, react_1.isValidElement)(value)) {
50
+ return value;
51
+ }
52
+ if (value === null || value === undefined) {
53
+ return "-";
54
+ }
55
+ if (typeof value === "object") {
56
+ return JSON.stringify(value);
57
+ }
58
+ return value;
59
+ });
60
+ if (!isSm || !responsiveControl?.mobile) {
61
+ return ((0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, { children: itemMapping?.map((one, key) => {
62
+ const column = columnMapping?.[key];
63
+ let title = one;
64
+ if (column?.tip) {
65
+ if (typeof column.tip === "string") {
66
+ title = item[column.tip]?.toString() || "-";
67
+ }
68
+ else if (typeof column.tip === "function") {
69
+ title = column.tip(item);
70
+ }
71
+ }
72
+ return ((0, jsx_runtime_1.jsx)("div", { className: (0, _utils_1.cn)("table-body-column", onRowClick && "cursor-pointer", (0, _utils_1.pcn)(className, "column")), style: { width: columnMapping?.at(key)?.width || 200 }, onClick: () => onRowClick?.(item, itemKey), title: title, children: one }, key));
73
+ }) }));
74
+ }
75
+ else {
76
+ const { onAction: onLeftAction, ...restLeftAction } = responsiveControl?.mobile?.leftActionControl || {};
77
+ const { onAction: onRightAction, ...restRightAction } = responsiveControl?.mobile?.rightActionControl || {};
78
+ return ((0, jsx_runtime_1.jsx)(_components_1.SwipeComponent, { className: "rounded-lg", leftActionControl: !!responsiveControl?.mobile?.leftActionControl ? {
79
+ ...restLeftAction,
80
+ ...(onLeftAction ? { onAction: () => onLeftAction?.(item, itemKey) } : {})
81
+ } : undefined, rightActionControl: !!responsiveControl?.mobile?.rightActionControl ? {
82
+ ...restRightAction,
83
+ ...(onRightAction ? { onAction: () => onRightAction?.(item, itemKey) } : {})
84
+ } : undefined, children: (0, jsx_runtime_1.jsx)("div", { onClick: () => onRowClick?.(item, itemKey), children: responsiveControl?.mobile?.item ? responsiveControl?.mobile?.item(item, itemKey) : ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)("p", { className: "font-semibold", children: Object.values(itemMapping)[0] }), (0, jsx_runtime_1.jsx)("p", { className: "text-sm", children: Object.values(itemMapping)[1] })] })) }) }));
85
+ }
86
+ }
87
+ return ((0, jsx_runtime_1.jsxs)("div", { className: (0, _utils_1.cn)("relative", (0, _utils_1.pcn)(className, "base")), children: [controlBar != false && ((0, jsx_runtime_1.jsx)(_components_1.ControlBarComponent, { id: id, options: !controlBar ? ["SEARCH", "SELECTABLE", "REFRESH"] : controlBar, searchableOptions: columns?.filter((c) => c.searchable), onSearchable: (e) => onChangeSearchableColumn?.(String(e)), searchable: searchableColumn || [], onSearch: (e) => setKeyword(e), search: keyword, selectableOptions: columns, onSelectable: (e) => setDisplayColumns(e), selectable: displayColumns, sortableOptions: columns?.filter((c) => c.sortable), sort: sortBy, onSort: (sort) => onChangeSortBy?.(sort), onRefresh: () => onRefresh?.(), filterableColumns: columns?.filter((c) => !!c?.filterable)?.map((c) => ({
88
+ label: c.label,
89
+ selector: c.selector,
90
+ type: typeof c?.filterable == "object" ? c?.filterable?.type : "text",
91
+ options: typeof c?.filterable == "object" && c?.filterable?.type == "select" ? c?.filterable?.options : undefined
92
+ })), onFilter: (filters) => onChangeFilter?.(filters), filter: filter, className: (0, _utils_1.pcn)(className, "controller-bar") || "" })), (0, jsx_runtime_1.jsx)("div", { className: "relative", children: (0, jsx_runtime_1.jsx)(_components_1.ScrollContainerComponent, { scrollFloating: !isSm && block, className: "w-full", onScroll: (e) => {
93
+ actionColumnRef.current?.clientWidth && e.scrollLeft &&
94
+ setShowFloatingAction(e.scrollLeft + e.clientWidth <= e.scrollWidth - actionColumnRef.current?.clientWidth);
95
+ }, footer: (0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, { children: block && pagination && ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)("div", { className: "py-6" }), (0, jsx_runtime_1.jsx)("div", { className: "my-2 absolute bottom-0 w-full", children: (0, jsx_runtime_1.jsx)(_components_1.PaginationComponent, { ...pagination }) })] })) }), children: loading ? ((0, jsx_runtime_1.jsx)("div", { className: "w-max min-w-full", children: (0, jsx_runtime_1.jsx)("div", { className: "table-loading-container", children: (0, jsx_runtime_1.jsx)("h1", { className: "table-loading-text", children: "Memuat data..." }) }) })) : !data || !data.length ? ((0, jsx_runtime_1.jsx)("div", { className: "table-empty-container", children: (0, jsx_runtime_1.jsx)("h1", { className: "table-empty-text", children: "Belum Ada Data" }) })) : ((0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, { children: !isSm || !responsiveControl?.mobile ? ((0, jsx_runtime_1.jsxs)("div", { className: "w-max min-w-full", children: [(0, jsx_runtime_1.jsxs)("div", { className: (0, _utils_1.cn)("table-head-row", (0, _utils_1.pcn)(className, "row")), children: [!!actionBulking && ((0, jsx_runtime_1.jsx)("div", { className: "table-head-column w-max", children: (0, jsx_runtime_1.jsx)(_components_1.CheckboxComponent, { name: "selected_table", className: "w-5 h-5", checked: data.length > 0 && checks?.length === data.length, onChange: () => data.length > 0 && checks?.length === data.length ? onChangeChecks?.([]) : onChangeChecks?.(data.map((d) => d.id)) }) })), !noIndex && (0, jsx_runtime_1.jsx)("div", { className: (0, _utils_1.cn)("table-head-column w-8", (0, _utils_1.pcn)(className, "head-column")), children: "#" }), renderHead()] }), (0, jsx_runtime_1.jsx)("div", { className: "table-body", children: data.map((item, key) => {
96
+ return ((0, jsx_runtime_1.jsxs)("div", { style: { animationDelay: `${(key + 1) * 0.05}s` }, className: (0, _utils_1.cn)("table-body-row", key % 2 ? "bg-light-primary/10" : "bg-white", focus == key && "bg-light-primary/30", (0, _utils_1.pcn)(className, "row")), children: [!!actionBulking && ((0, jsx_runtime_1.jsx)("div", { className: (0, _utils_1.cn)("table-body-column w-max", (0, _utils_1.pcn)(className, "column")), children: (0, jsx_runtime_1.jsx)(_components_1.CheckboxComponent, { name: "selected_table", className: "w-5 h-5", checked: checks?.includes(item?.id), onChange: () => checks?.includes(item?.id) ? onChangeChecks?.(checks.filter((i) => i !== item?.id)) : onChangeChecks?.([...(checks || []), item?.id]) }) })), !noIndex && (0, jsx_runtime_1.jsx)("div", { className: (0, _utils_1.cn)("table-body-column w-8", (0, _utils_1.pcn)(className, "column")), children: numberOfRow(key) }), renderItem(item, key), (0, jsx_runtime_1.jsx)("div", { ref: actionColumnRef, className: "table-action-column", children: item["action"] }), item["action"] && showFloatingAction && ((0, jsx_runtime_1.jsxs)("div", { className: (0, _utils_1.cn)("table-floating-action", (0, _utils_1.pcn)(className, "floating-action")), onClick: () => floatingActionActive !== false &&
97
+ floatingActionActive == key ? setFloatingActionActive(false) : setFloatingActionActive(key), children: [(0, jsx_runtime_1.jsx)("div", { className: "table-floating-action-icon-wrapper", children: (0, jsx_runtime_1.jsx)(react_fontawesome_1.FontAwesomeIcon, { icon: floatingActionActive === false || floatingActionActive != key ? free_solid_svg_icons_1.faChevronLeft : free_solid_svg_icons_1.faChevronRight }) }), (0, jsx_runtime_1.jsx)("div", { className: (0, _utils_1.cn)("table-floating-action-content", floatingActionActive === key && "table-floating-action-content-active"), children: item["action"] })] }))] }, key));
98
+ }) })] })) : ((0, jsx_runtime_1.jsx)("div", { className: "table-mobile-list", children: data.map((item, key) => {
99
+ return ((0, jsx_runtime_1.jsx)("div", { style: { animationDelay: `${(key + 1) * 0.05}s` }, children: renderItem(item, key) }, key));
100
+ }) })) })) }) }), !!actionBulking && !!checks?.length && ((0, jsx_runtime_1.jsxs)("div", { className: "table-bulk-actions-bar", children: [(0, jsx_runtime_1.jsxs)("div", { className: "table-bulk-actions-title", children: [checks?.length, " Data Terpilih"] }), (0, jsx_runtime_1.jsx)("div", { className: "table-bulk-actions-buttons", children: actionBulking?.(checks) })] })), !block && pagination && ((0, jsx_runtime_1.jsx)("div", { className: "table-pagination-desktop", children: (0, jsx_runtime_1.jsx)(_components_1.PaginationComponent, { ...pagination }) })), pagination && ((0, jsx_runtime_1.jsx)("div", { className: "table-pagination-mobile", children: (0, jsx_runtime_1.jsx)(_components_1.PaginationComponent, { ...pagination }) }))] }));
101
+ }