funda-ui 1.0.272

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 (246) hide show
  1. package/BackToTop/index.css +34 -0
  2. package/BackToTop/index.d.ts +11 -0
  3. package/BackToTop/index.js +458 -0
  4. package/CascadingSelect/index.css +159 -0
  5. package/CascadingSelect/index.d.ts +56 -0
  6. package/CascadingSelect/index.js +958 -0
  7. package/CascadingSelectE2E/index.css +159 -0
  8. package/CascadingSelectE2E/index.d.ts +60 -0
  9. package/CascadingSelectE2E/index.js +1126 -0
  10. package/Checkbox/index.d.ts +30 -0
  11. package/Checkbox/index.js +226 -0
  12. package/ColorPicker/index.css +38 -0
  13. package/ColorPicker/index.d.ts +27 -0
  14. package/ColorPicker/index.js +246 -0
  15. package/DigitalClock/index.d.ts +7 -0
  16. package/DigitalClock/index.js +208 -0
  17. package/DropdownMenu/index.css +127 -0
  18. package/DropdownMenu/index.d.ts +37 -0
  19. package/DropdownMenu/index.js +237 -0
  20. package/DynamicFields/index.d.ts +26 -0
  21. package/DynamicFields/index.js +412 -0
  22. package/File/index.d.ts +36 -0
  23. package/File/index.js +473 -0
  24. package/Input/index.d.ts +42 -0
  25. package/Input/index.js +286 -0
  26. package/LiveSearch/index.d.ts +37 -0
  27. package/LiveSearch/index.js +1195 -0
  28. package/ModalDialog/index.d.ts +60 -0
  29. package/ModalDialog/index.js +725 -0
  30. package/ModeSwitch/index.d.ts +17 -0
  31. package/ModeSwitch/index.js +202 -0
  32. package/MultiFuncSelect/index.css +178 -0
  33. package/MultiFuncSelect/index.d.ts +67 -0
  34. package/MultiFuncSelect/index.js +1826 -0
  35. package/MultilevelDropdownMenu/index.css +35 -0
  36. package/MultilevelDropdownMenu/index.d.ts +25 -0
  37. package/MultilevelDropdownMenu/index.js +464 -0
  38. package/Pagination/index.d.ts +49 -0
  39. package/Pagination/index.js +341 -0
  40. package/README.md +108 -0
  41. package/Radio/index.d.ts +31 -0
  42. package/Radio/index.js +246 -0
  43. package/RangeSlider/index.css +149 -0
  44. package/RangeSlider/index.d.ts +21 -0
  45. package/RangeSlider/index.js +730 -0
  46. package/ScrollReveal/index.css +23 -0
  47. package/ScrollReveal/index.d.ts +21 -0
  48. package/ScrollReveal/index.js +216 -0
  49. package/Scrollbar/index.css +168 -0
  50. package/Scrollbar/index.d.ts +15 -0
  51. package/Scrollbar/index.js +605 -0
  52. package/SearchBar/index.d.ts +32 -0
  53. package/SearchBar/index.js +246 -0
  54. package/Select/index.d.ts +34 -0
  55. package/Select/index.js +331 -0
  56. package/ShowMoreLess/index.css +23 -0
  57. package/ShowMoreLess/index.d.ts +30 -0
  58. package/ShowMoreLess/index.js +202 -0
  59. package/Switch/index.d.ts +29 -0
  60. package/Switch/index.js +211 -0
  61. package/Table/index.css +533 -0
  62. package/Table/index.d.ts +25 -0
  63. package/Table/index.js +2113 -0
  64. package/Tabs/index.d.ts +3 -0
  65. package/Tabs/index.js +323 -0
  66. package/TagInput/index.css +90 -0
  67. package/TagInput/index.d.ts +28 -0
  68. package/TagInput/index.js +370 -0
  69. package/Textarea/index.d.ts +30 -0
  70. package/Textarea/index.js +242 -0
  71. package/Toast/index.css +95 -0
  72. package/Toast/index.d.ts +35 -0
  73. package/Toast/index.js +340 -0
  74. package/Tooltip/index.css +240 -0
  75. package/Tooltip/index.d.ts +19 -0
  76. package/Tooltip/index.js +200 -0
  77. package/Tree/index.css +225 -0
  78. package/Tree/index.d.ts +37 -0
  79. package/Tree/index.js +1406 -0
  80. package/all.d.ts +33 -0
  81. package/all.js +35 -0
  82. package/lib/cjs/BackToTop/index.d.ts +11 -0
  83. package/lib/cjs/BackToTop/index.js +458 -0
  84. package/lib/cjs/CascadingSelect/index.d.ts +56 -0
  85. package/lib/cjs/CascadingSelect/index.js +958 -0
  86. package/lib/cjs/CascadingSelectE2E/index.d.ts +60 -0
  87. package/lib/cjs/CascadingSelectE2E/index.js +1126 -0
  88. package/lib/cjs/Checkbox/index.d.ts +30 -0
  89. package/lib/cjs/Checkbox/index.js +226 -0
  90. package/lib/cjs/ColorPicker/index.d.ts +27 -0
  91. package/lib/cjs/ColorPicker/index.js +246 -0
  92. package/lib/cjs/DigitalClock/index.d.ts +7 -0
  93. package/lib/cjs/DigitalClock/index.js +208 -0
  94. package/lib/cjs/DropdownMenu/index.d.ts +37 -0
  95. package/lib/cjs/DropdownMenu/index.js +237 -0
  96. package/lib/cjs/DynamicFields/index.d.ts +26 -0
  97. package/lib/cjs/DynamicFields/index.js +412 -0
  98. package/lib/cjs/File/index.d.ts +36 -0
  99. package/lib/cjs/File/index.js +473 -0
  100. package/lib/cjs/Input/index.d.ts +42 -0
  101. package/lib/cjs/Input/index.js +286 -0
  102. package/lib/cjs/LiveSearch/index.d.ts +37 -0
  103. package/lib/cjs/LiveSearch/index.js +1195 -0
  104. package/lib/cjs/ModalDialog/index.d.ts +60 -0
  105. package/lib/cjs/ModalDialog/index.js +725 -0
  106. package/lib/cjs/ModeSwitch/index.d.ts +17 -0
  107. package/lib/cjs/ModeSwitch/index.js +202 -0
  108. package/lib/cjs/MultiFuncSelect/index.d.ts +67 -0
  109. package/lib/cjs/MultiFuncSelect/index.js +1826 -0
  110. package/lib/cjs/MultilevelDropdownMenu/index.d.ts +25 -0
  111. package/lib/cjs/MultilevelDropdownMenu/index.js +464 -0
  112. package/lib/cjs/Pagination/index.d.ts +49 -0
  113. package/lib/cjs/Pagination/index.js +341 -0
  114. package/lib/cjs/Radio/index.d.ts +31 -0
  115. package/lib/cjs/Radio/index.js +246 -0
  116. package/lib/cjs/RangeSlider/index.d.ts +21 -0
  117. package/lib/cjs/RangeSlider/index.js +730 -0
  118. package/lib/cjs/ScrollReveal/index.d.ts +21 -0
  119. package/lib/cjs/ScrollReveal/index.js +216 -0
  120. package/lib/cjs/Scrollbar/index.d.ts +15 -0
  121. package/lib/cjs/Scrollbar/index.js +605 -0
  122. package/lib/cjs/SearchBar/index.d.ts +32 -0
  123. package/lib/cjs/SearchBar/index.js +246 -0
  124. package/lib/cjs/Select/index.d.ts +34 -0
  125. package/lib/cjs/Select/index.js +331 -0
  126. package/lib/cjs/ShowMoreLess/index.d.ts +30 -0
  127. package/lib/cjs/ShowMoreLess/index.js +202 -0
  128. package/lib/cjs/Switch/index.d.ts +29 -0
  129. package/lib/cjs/Switch/index.js +211 -0
  130. package/lib/cjs/Table/index.d.ts +25 -0
  131. package/lib/cjs/Table/index.js +2113 -0
  132. package/lib/cjs/Tabs/index.d.ts +3 -0
  133. package/lib/cjs/Tabs/index.js +323 -0
  134. package/lib/cjs/TagInput/index.d.ts +28 -0
  135. package/lib/cjs/TagInput/index.js +370 -0
  136. package/lib/cjs/Textarea/index.d.ts +30 -0
  137. package/lib/cjs/Textarea/index.js +242 -0
  138. package/lib/cjs/Toast/index.d.ts +35 -0
  139. package/lib/cjs/Toast/index.js +340 -0
  140. package/lib/cjs/Tooltip/index.d.ts +19 -0
  141. package/lib/cjs/Tooltip/index.js +200 -0
  142. package/lib/cjs/Tree/index.d.ts +37 -0
  143. package/lib/cjs/Tree/index.js +1406 -0
  144. package/lib/cjs/index.d.ts +33 -0
  145. package/lib/cjs/index.js +35 -0
  146. package/lib/css/BackToTop/index.css +34 -0
  147. package/lib/css/CascadingSelect/index.css +159 -0
  148. package/lib/css/CascadingSelectE2E/index.css +159 -0
  149. package/lib/css/ColorPicker/index.css +38 -0
  150. package/lib/css/DropdownMenu/index.css +127 -0
  151. package/lib/css/MultiFuncSelect/index.css +178 -0
  152. package/lib/css/MultilevelDropdownMenu/index.css +35 -0
  153. package/lib/css/RangeSlider/index.css +149 -0
  154. package/lib/css/ScrollReveal/index.css +23 -0
  155. package/lib/css/Scrollbar/index.css +168 -0
  156. package/lib/css/ShowMoreLess/index.css +23 -0
  157. package/lib/css/Table/index.css +533 -0
  158. package/lib/css/TagInput/index.css +90 -0
  159. package/lib/css/Toast/index.css +95 -0
  160. package/lib/css/Tooltip/index.css +240 -0
  161. package/lib/css/Tree/index.css +225 -0
  162. package/lib/esm/BackToTop/index.scss +47 -0
  163. package/lib/esm/BackToTop/index.tsx +182 -0
  164. package/lib/esm/BackToTop/utils/easing.js +200 -0
  165. package/lib/esm/BackToTop/utils/performance.js +52 -0
  166. package/lib/esm/CascadingSelect/Group.tsx +39 -0
  167. package/lib/esm/CascadingSelect/index.scss +214 -0
  168. package/lib/esm/CascadingSelect/index.tsx +922 -0
  169. package/lib/esm/CascadingSelect/utils/performance.js +52 -0
  170. package/lib/esm/CascadingSelectE2E/Group.tsx +39 -0
  171. package/lib/esm/CascadingSelectE2E/index.scss +214 -0
  172. package/lib/esm/CascadingSelectE2E/index.tsx +1091 -0
  173. package/lib/esm/CascadingSelectE2E/utils/performance.js +52 -0
  174. package/lib/esm/Checkbox/index.tsx +160 -0
  175. package/lib/esm/ColorPicker/index.scss +48 -0
  176. package/lib/esm/ColorPicker/index.tsx +187 -0
  177. package/lib/esm/DigitalClock/index.tsx +72 -0
  178. package/lib/esm/DigitalClock/utils/useInterval.js +43 -0
  179. package/lib/esm/DropdownMenu/Option.tsx +27 -0
  180. package/lib/esm/DropdownMenu/index.scss +180 -0
  181. package/lib/esm/DropdownMenu/index.tsx +148 -0
  182. package/lib/esm/DynamicFields/index.tsx +386 -0
  183. package/lib/esm/File/index.tsx +302 -0
  184. package/lib/esm/Input/index.tsx +233 -0
  185. package/lib/esm/LiveSearch/index.tsx +582 -0
  186. package/lib/esm/LiveSearch/utils/performance.js +52 -0
  187. package/lib/esm/LiveSearch/utils/useThrottle.js +36 -0
  188. package/lib/esm/ModalDialog/index.tsx +479 -0
  189. package/lib/esm/ModalDialog/plugins/BSL/bodyScrollLock.es6.js +262 -0
  190. package/lib/esm/ModalDialog/plugins/BSL/index.ts +2 -0
  191. package/lib/esm/ModeSwitch/index.tsx +82 -0
  192. package/lib/esm/MultiFuncSelect/index.scss +269 -0
  193. package/lib/esm/MultiFuncSelect/index.tsx +1597 -0
  194. package/lib/esm/MultiFuncSelect/utils/performance.js +52 -0
  195. package/lib/esm/MultiFuncSelect/utils/tree.js +103 -0
  196. package/lib/esm/MultiFuncSelect/utils/useThrottle.js +36 -0
  197. package/lib/esm/MultilevelDropdownMenu/MenuList.tsx +230 -0
  198. package/lib/esm/MultilevelDropdownMenu/index.scss +75 -0
  199. package/lib/esm/MultilevelDropdownMenu/index.tsx +71 -0
  200. package/lib/esm/MultilevelDropdownMenu/utils/dom.js +81 -0
  201. package/lib/esm/Pagination/index.tsx +230 -0
  202. package/lib/esm/Pagination/pagination-navigators.tsx +60 -0
  203. package/lib/esm/Radio/index.tsx +201 -0
  204. package/lib/esm/RangeSlider/index.scss +184 -0
  205. package/lib/esm/RangeSlider/index.tsx +223 -0
  206. package/lib/esm/ScrollReveal/index.scss +27 -0
  207. package/lib/esm/ScrollReveal/index.tsx +146 -0
  208. package/lib/esm/Scrollbar/index.scss +217 -0
  209. package/lib/esm/Scrollbar/index.tsx +497 -0
  210. package/lib/esm/Scrollbar/utils/performance.js +52 -0
  211. package/lib/esm/SearchBar/index.tsx +181 -0
  212. package/lib/esm/Select/index.tsx +276 -0
  213. package/lib/esm/ShowMoreLess/index.scss +27 -0
  214. package/lib/esm/ShowMoreLess/index.tsx +144 -0
  215. package/lib/esm/Switch/index.tsx +143 -0
  216. package/lib/esm/Table/TableColgroup.tsx +29 -0
  217. package/lib/esm/Table/TableField.tsx +40 -0
  218. package/lib/esm/Table/TableFieldRow.tsx +212 -0
  219. package/lib/esm/Table/TableHeaders.tsx +146 -0
  220. package/lib/esm/Table/TableRow.tsx +127 -0
  221. package/lib/esm/Table/TableSummaries.tsx +36 -0
  222. package/lib/esm/Table/index.scss +364 -0
  223. package/lib/esm/Table/index.tsx +576 -0
  224. package/lib/esm/Table/table-utils.ts +65 -0
  225. package/lib/esm/Table/utils/dom.js +81 -0
  226. package/lib/esm/Table/utils/performance.js +52 -0
  227. package/lib/esm/Tabs/TabList.tsx +42 -0
  228. package/lib/esm/Tabs/TabPanel.tsx +34 -0
  229. package/lib/esm/Tabs/Tabs.tsx +232 -0
  230. package/lib/esm/Tabs/index.tsx +3 -0
  231. package/lib/esm/TagInput/index.scss +125 -0
  232. package/lib/esm/TagInput/index.tsx +314 -0
  233. package/lib/esm/Textarea/index.tsx +178 -0
  234. package/lib/esm/Toast/Item.tsx +75 -0
  235. package/lib/esm/Toast/index.scss +120 -0
  236. package/lib/esm/Toast/index.tsx +249 -0
  237. package/lib/esm/Tooltip/index.scss +327 -0
  238. package/lib/esm/Tooltip/index.tsx +142 -0
  239. package/lib/esm/Tree/TreeList.tsx +503 -0
  240. package/lib/esm/Tree/index.scss +375 -0
  241. package/lib/esm/Tree/index.tsx +301 -0
  242. package/lib/esm/Tree/init-height.tsx +27 -0
  243. package/lib/esm/Tree/utils/convert-tree.js +29 -0
  244. package/lib/esm/Tree/utils/dom.js +81 -0
  245. package/lib/esm/index.js +31 -0
  246. package/package.json +40 -0
@@ -0,0 +1,52 @@
1
+
2
+ /*
3
+ * Debounce
4
+ *
5
+ * @param {Function} fn - A function to be executed within the time limit.
6
+ * @param {Number} limit - Waiting time.
7
+ * @return {Function} - Returns a new function.
8
+ */
9
+ function debounce( fn, limit = 300 ) {
10
+ let timer;
11
+ return function() {
12
+
13
+ //Every time this returned function is called, the timer is cleared to ensure that fn is not executed
14
+ clearTimeout(timer);
15
+
16
+ // When the returned function is called for the last time (that is the user stops a continuous operation)
17
+ // Execute fn after another delay milliseconds
18
+ timer = setTimeout(function() {
19
+ fn.apply(this, arguments);
20
+ }, limit);
21
+ }
22
+ }
23
+
24
+
25
+
26
+
27
+
28
+ /*
29
+ * Throttle
30
+ *
31
+ * @param {Function} fn - A function to be executed within the time limit.
32
+ * @param {Number} limit - Waiting time.
33
+ * @return {Function} - Returns a new function.
34
+ */
35
+ function throttle( fn, limit = 300 ) {
36
+ let waiting = false;
37
+ return function () {
38
+ if (!waiting) {
39
+ fn.apply(this, arguments);
40
+ waiting = true;
41
+ setTimeout(function () {
42
+ waiting = false;
43
+ }, limit);
44
+ }
45
+ }
46
+ }
47
+
48
+
49
+ module.exports = {
50
+ debounce,
51
+ throttle
52
+ }
@@ -0,0 +1,103 @@
1
+ /**
2
+ * Convert Tree
3
+ * @param {Array} arr - Flat array
4
+ * @param {?String | ?Number} parentId - Parent id
5
+ * @param {?String} keyId - Key value of id.
6
+ * @param {?String} keyParentId - Key value of parent id.
7
+ * @returns Array
8
+ */
9
+ function convertTree(arr, parentId = '', keyId = 'id', keyParentId = 'parent_id') {
10
+
11
+ if( !parentId ) {
12
+
13
+ // If there is no parent id (when recursing for the first time), all parents will be queried
14
+ return arr.filter(item => !item[keyParentId]).map(item => {
15
+ // Query all child nodes by parent node ID
16
+ item.children = convertTree(arr, item[keyId], keyId, keyParentId);
17
+ return item;
18
+ })
19
+ } else {
20
+ return arr.filter(item => item[keyParentId] === parentId).map(item => {
21
+ // Query all child nodes by parent node ID
22
+ item.children = convertTree(arr, item[keyId], keyId, keyParentId);
23
+ return item;
24
+ })
25
+ }
26
+ }
27
+
28
+
29
+ /**
30
+ * Flat tree
31
+ * @param {Array} arr - Hierarchical array
32
+ * @returns Array
33
+ */
34
+ function flatTree(arr) {
35
+ const flatData = ({...rest}) => {
36
+ const { children = [] } = rest;
37
+ return [{...rest}, ...children.flatMap(flatData)];
38
+ };
39
+ let result = arr.flatMap(flatData);
40
+
41
+ //remove children from item
42
+ result = result.map((item) => {
43
+ delete item.children;
44
+ return item;
45
+
46
+ });
47
+
48
+ return result;
49
+ }
50
+
51
+
52
+ /**
53
+ * Add depth to each item in the tree
54
+ * @param {Array} arr - Hierarchical array
55
+ * @param {?String | ?Number} parentId - Parent id
56
+ * @param {?String} keyId - Key value of id.
57
+ * @param {?String} keyParentId - Key value of parent id.
58
+ * @param {?Number} depth - Depth of the item.
59
+ * @returns
60
+ */
61
+ function addTreeDepth(arr, parentId = '', keyId = 'id', keyParentId = 'parent_id', depth = 0) {
62
+ arr.forEach((item) => {
63
+ item.depth = depth;
64
+ // Query all child nodes by parent node ID
65
+ if (item.children && item.children.length > 0) {
66
+ addTreeDepth(item.children, item[keyId], keyId, keyParentId, ++depth);
67
+ } else {
68
+ depth = 0;
69
+ }
70
+ });
71
+ }
72
+
73
+
74
+
75
+ /**
76
+ * Add indent placeholder
77
+ * @param {Array} arr - Flat array
78
+ * @param {?String} placeholder - String of placeholder
79
+ * @param {?String} lastPlaceholder - Last String of placeholder
80
+ * @param {?String} keyName - Key value of name.
81
+ * @returns Array
82
+ */
83
+ function addTreeIndent(arr, placeholder = '    ', lastPlaceholder = '', keyName = 'label') {
84
+ arr.forEach((item) => {
85
+ let indent = '';
86
+ if (item.depth) {
87
+ Array(item.depth).fill(0).forEach((k, i) => {
88
+ indent += placeholder;
89
+ if (i === item.depth-1) {
90
+ item[keyName] = indent + lastPlaceholder + item[keyName];
91
+ }
92
+ });
93
+ }
94
+ });
95
+ }
96
+
97
+ module.exports = {
98
+ convertTree,
99
+ flatTree,
100
+ addTreeDepth,
101
+ addTreeIndent
102
+ };
103
+
@@ -0,0 +1,36 @@
1
+ /**
2
+ * Limiting the rate of execution
3
+ *
4
+ * @usage:
5
+
6
+ const App = () => {
7
+ const [count, setCount] = useState(0);
8
+ const handleClick = useThrottle(() => setCount(count + 1), 500, [count]);
9
+
10
+ return (
11
+ <div className="app">
12
+ <button onClick={handleClick}>click</button>
13
+ <p>click {count} time</p>
14
+ </div>
15
+ );
16
+ };
17
+
18
+ */
19
+ import { useRef, useCallback } from "react";
20
+
21
+ const useThrottle = (fn, delay, dependence) => {
22
+ const ref = useRef({ lastTime: 0 });
23
+
24
+ return useCallback((...args) => {
25
+ const now = Date.now();
26
+
27
+ if (now - ref.current.lastTime >= delay) {
28
+ fn(...args);
29
+ ref.current.lastTime = now;
30
+ }
31
+ }, dependence);
32
+ };
33
+
34
+
35
+ export default useThrottle;
36
+
@@ -0,0 +1,230 @@
1
+ import React, { useEffect, useRef } from 'react';
2
+
3
+ import { getNextSiblings } from './utils/dom';
4
+
5
+ /* Recursively nested components to traverse nodes
6
+ -------------------------------------------------*/
7
+ type MenuListProps = {
8
+ alternateCollapse?: boolean;
9
+ first?: boolean;
10
+ arrow?: React.ReactNode;
11
+ childClassName?: string;
12
+ data: any[any];
13
+ routerPath?: string;
14
+ onSelect?: (e: any, val: any) => void;
15
+ };
16
+
17
+ export default function MenuList(props: MenuListProps) {
18
+
19
+ const {
20
+ alternateCollapse,
21
+ first,
22
+ arrow,
23
+ childClassName,
24
+ data,
25
+ routerPath,
26
+ onSelect
27
+ } = props;
28
+
29
+ const rootRef = useRef<any>(null);
30
+ const currentPath = routerPath ? routerPath : '';
31
+
32
+
33
+
34
+ const activeClass = (el: any, mode: string, classname: string = 'active') => {
35
+ if ( mode === 'add' ) {
36
+ el.classList.add(classname);
37
+ } else {
38
+ el.classList.remove(classname);
39
+ }
40
+ };
41
+
42
+ const closeChild = (hyperlink: HTMLElement, ul: HTMLAllCollection) => {
43
+ if ( ul.length === 0 ) return;
44
+
45
+ activeClass(hyperlink, 'remove');
46
+ hyperlink.setAttribute('aria-expanded', 'false');
47
+ activeClass(hyperlink.parentNode, 'remove');
48
+
49
+ //to close
50
+ [].slice.call(ul).forEach(function(element: any){
51
+ element.style.maxHeight = 0;
52
+ });
53
+ };
54
+
55
+ const openChild = (hyperlink: HTMLElement, ul: HTMLAllCollection) => {
56
+ if ( ul.length === 0 ) return;
57
+
58
+ activeClass(hyperlink, 'add');
59
+ hyperlink.setAttribute('aria-expanded', 'true');
60
+ activeClass(hyperlink.parentNode, 'add');
61
+
62
+ // init <ul> height
63
+ [].slice.call(ul).forEach(function(el: any){
64
+ if ( typeof el.querySelectorAll('li')[0] !== 'undefined' ) {
65
+ const calcH = el.querySelectorAll('li').length * el.querySelectorAll('li')[0].scrollHeight;
66
+ el.style.maxHeight = `${calcH}px`;
67
+ }
68
+
69
+ });
70
+
71
+ };
72
+
73
+
74
+
75
+ function handleClick(e: any) {
76
+ e.preventDefault();
77
+ const hyperlink = e.currentTarget;
78
+ const url = hyperlink.getAttribute('href');
79
+ const subElement = getNextSiblings(hyperlink, 'ul');
80
+
81
+
82
+ // route switching
83
+ //=====================
84
+ onSelect?.(e, {
85
+ isRouter: hyperlink.dataset.router,
86
+ slug: hyperlink.dataset.slug,
87
+ link: hyperlink.dataset.link
88
+ });
89
+
90
+
91
+ // hide child if expandedLink doesn't exist, on the contrary
92
+ //=====================
93
+ if ( hyperlink.getAttribute('aria-expanded') === 'false' || hyperlink.getAttribute('aria-expanded') === null ) {
94
+
95
+
96
+ //Hide all other siblings of the selected <ul>
97
+ if ( alternateCollapse ) {
98
+ [].slice.call(rootRef.current.children).forEach(function(li: any){
99
+
100
+ activeClass(li, 'remove');
101
+
102
+ const _li = li.firstChild;
103
+ activeClass(_li, 'remove');
104
+ _li.setAttribute('aria-expanded', false);
105
+
106
+ [].slice.call(getNextSiblings(_li, 'ul')).forEach(function(element: any){
107
+ element.style.maxHeight = 0;
108
+ });
109
+ });
110
+ }
111
+
112
+
113
+ //open current
114
+ openChild(hyperlink, subElement as never);
115
+
116
+ } else {
117
+
118
+ //close current
119
+ closeChild(hyperlink, subElement as never);
120
+ }
121
+
122
+
123
+
124
+ // active current item
125
+ //=====================
126
+ if ( (currentPath === url || currentPath.indexOf(url.replace(/\/[\d]+\.html|\.html/ig,'')) >= 0 && url !== '/') ) {
127
+ activeClass(e.target, 'add');
128
+ activeClass(e.target.parentElement, 'add');
129
+ }
130
+
131
+
132
+ }
133
+
134
+ function arrowGenerator() {
135
+ return arrow ? arrow : <svg viewBox="0 0 22 22" width="8px"><path d="m345.44 248.29l-194.29 194.28c-12.359 12.365-32.397 12.365-44.75 0-12.354-12.354-12.354-32.391 0-44.744l171.91-171.91-171.91-171.9c-12.354-12.359-12.354-32.394 0-44.748 12.354-12.359 32.391-12.359 44.75 0l194.29 194.28c6.177 6.18 9.262 14.271 9.262 22.366 0 8.099-3.091 16.196-9.267 22.373" transform="matrix(.03541-.00013.00013.03541 2.98 3.02)" fill="#a5a5a5" /></svg>;
136
+ }
137
+
138
+
139
+ useEffect(() => {
140
+
141
+
142
+ // Activate current item
143
+ //=====================
144
+ const allItems = rootRef.current ? [].slice.call(document.querySelectorAll(`.${childClassName} a`)).map( (item: any) => {
145
+ return {
146
+ href: item.getAttribute('href'),
147
+ el: item,
148
+ actived: item.parentNode.classList?.contains('active') ? true : false,
149
+ expandedLink: document.body.contains(item.parentNode.parentNode.previousSibling) ? item.parentNode.parentNode.previousSibling : false
150
+ }
151
+ } ) : [];
152
+
153
+
154
+ allItems.forEach( (hyperlink: any) => {
155
+
156
+ // Expand the currently active item by default
157
+ if ( hyperlink.actived ) {
158
+
159
+ hyperlink.el.setAttribute('aria-expanded', 'true');
160
+
161
+ if ( hyperlink.expandedLink ) {
162
+ const expandedLink: any = hyperlink.expandedLink; // <a>
163
+ activeClass(expandedLink.parentNode, 'add');
164
+ expandedLink.setAttribute('aria-expanded', true);
165
+ }
166
+
167
+
168
+ // init <ul> height
169
+ const ul = getNextSiblings(hyperlink.el, 'ul');
170
+ [].slice.call(ul).forEach(function(el: any){
171
+ if ( typeof el.querySelectorAll('li')[0] !== 'undefined' ) {
172
+ const calcH = el.querySelectorAll('li').length * el.querySelectorAll('li')[0].scrollHeight;
173
+ el.style.maxHeight = `${calcH}px`;
174
+ }
175
+
176
+ });
177
+ }
178
+
179
+ });
180
+
181
+ }, [data]);
182
+
183
+
184
+ if ( data ) {
185
+
186
+ return (
187
+ <>
188
+ <ul className={childClassName} ref={rootRef} style={!first ? {maxHeight: '0px'} : {}}>
189
+
190
+ {data.map((item: any, i: number) => {
191
+
192
+ const _matchPath = currentPath === item.link || currentPath.indexOf(item.link.replace(/\/[\d]+\.html|\.html/ig, '')) >= 0 && item.link !== '/';
193
+
194
+ if (item.heading) return (
195
+ <li className="nav-item" key={i}>
196
+ <a tabIndex={-1} className="nav-link disabled" href="#" aria-disabled="true" data-router="false" data-link={item.link} data-slug={item.slug}>
197
+ {item.icon ? item.icon.indexOf('</svg>') < 0 ? <><i className={item.icon}></i> </> : <var dangerouslySetInnerHTML={{ __html: `${item.icon}` }} /> : null}<i dangerouslySetInnerHTML={{ __html: `${item.title}` }}></i>
198
+ </a>
199
+ </li>
200
+ );
201
+
202
+ return (
203
+ <li key={i} className={item.active ? `nav-item active` : (_matchPath ? `nav-item active` : 'nav-item')}>
204
+ <a tabIndex={-1} title={item.title} className={item.active ? `nav-link active` : (_matchPath ? `nav-link active` : 'nav-link')} href={item.link === '#' ? `${item.link}-${i}` : item.link} onClick={handleClick} data-router={item.link.indexOf('#') >= 0 || item.link.indexOf('http') >= 0 ? 'false' : 'true'} data-link={item.link} data-slug={item.slug}>
205
+ {item.icon ? item.icon.indexOf('</svg>') < 0 ? <><i className={item.icon}></i> </> : <var dangerouslySetInnerHTML={{ __html: `${item.icon}` }} /> : null}<i dangerouslySetInnerHTML={{ __html: `${item.title}` }}></i>
206
+ {item.children ? <span className="arrow">{arrowGenerator()}</span> : ''}
207
+ </a>
208
+ {item.children && <MenuList
209
+ data={item.children}
210
+ first={false}
211
+ arrow={arrow}
212
+ onSelect={onSelect}
213
+ routerPath={routerPath}
214
+ />}
215
+ </li>
216
+ );
217
+
218
+ })}
219
+ </ul>
220
+
221
+ </>
222
+ )
223
+ } else {
224
+ return (
225
+ <></>
226
+ )
227
+ }
228
+
229
+ }
230
+
@@ -0,0 +1,75 @@
1
+ /* ======================================================
2
+ <!-- Multi-level Dropdown Menu -->
3
+ /* ====================================================== */
4
+
5
+ .navbar-nav {
6
+
7
+ a {
8
+ position: relative;
9
+ }
10
+
11
+ .arrow {
12
+ transition: .1s ease-in-out;
13
+ display: inline-block;
14
+ text-align: center;
15
+ position: absolute;
16
+ right: 0.5em;
17
+ top: 1.5em;
18
+ transform: translateY(-50%) rotate(0deg);
19
+ }
20
+
21
+ li {
22
+
23
+ position: relative;
24
+
25
+ i {
26
+ font-style: normal;
27
+ }
28
+
29
+ > a {
30
+
31
+ &:hover {
32
+
33
+ }
34
+
35
+ &.active {
36
+
37
+ > .arrow {
38
+ transform: translateY(-50%) rotate(90deg);
39
+ }
40
+
41
+
42
+ }
43
+
44
+ }
45
+
46
+ &.active > a {
47
+
48
+ }
49
+
50
+
51
+ }
52
+
53
+ > li {
54
+
55
+ ul {
56
+ transition: max-height 0.25s ease;
57
+ overflow: hidden;
58
+ position: relative;
59
+ }
60
+ }
61
+
62
+ > li:not(.active) {
63
+
64
+ ul {
65
+ max-height: 0;
66
+ }
67
+ }
68
+
69
+
70
+ > li ul ul {
71
+ margin-top: auto;
72
+ }
73
+
74
+
75
+ }
@@ -0,0 +1,71 @@
1
+ import React, { useState, useEffect, useId, memo } from 'react';
2
+
3
+ import MenuList from './MenuList';
4
+
5
+
6
+ declare module 'react' {
7
+ interface ReactI18NextChildren<T> {
8
+ children?: any;
9
+ }
10
+ }
11
+
12
+ type MultilevelDropdownMenuProps = {
13
+ /** Mutually exclusive alternate expansion between the first levels */
14
+ alternateCollapse?: boolean;
15
+ /** set an arrow */
16
+ arrow?: React.ReactNode;
17
+ /** The class name of the navbar. */
18
+ navbarClassName?: string;
19
+ /** The class name of the child on <ul>. */
20
+ childClassName?: string;
21
+ /** Specify data of Cascading DropDown List as a JSON string format. */
22
+ data?: any[any];
23
+ /** Pass the current routing path into. It is used to determine whether to activate */
24
+ routerPath?: string;
25
+ /** -- */
26
+ id?: string;
27
+ onSelect?: (e: any, val: any) => void;
28
+ };
29
+
30
+
31
+ const MultilevelDropdownMenu = (props: MultilevelDropdownMenuProps) => {
32
+ const {
33
+ alternateCollapse,
34
+ arrow,
35
+ navbarClassName,
36
+ childClassName,
37
+ routerPath,
38
+ data,
39
+ id,
40
+ onSelect
41
+ } = props;
42
+
43
+ const uniqueID = useId();
44
+ const idRes = id || uniqueID;
45
+ const [val, setVal] = useState<any>(null);
46
+
47
+ useEffect(() => {
48
+ setVal(data);
49
+ }, [data]);
50
+
51
+
52
+ return (
53
+ <>
54
+
55
+ <nav id={idRes} className={navbarClassName ? navbarClassName : "navbar"}>
56
+ <MenuList
57
+ alternateCollapse={alternateCollapse}
58
+ first={true}
59
+ arrow={arrow}
60
+ data={val}
61
+ childClassName={childClassName || 'navbar-nav'}
62
+ onSelect={onSelect}
63
+ routerPath={routerPath}
64
+ />
65
+ </nav>
66
+
67
+ </>
68
+ )
69
+ };
70
+
71
+ export default memo(MultilevelDropdownMenu);
@@ -0,0 +1,81 @@
1
+ /**
2
+ * Dom Utilities
3
+ * @param {HTMLElement} el - Element
4
+ * @param {?String} filter - A filter string
5
+ * @returns HtmlElementCollection
6
+ */
7
+ function matches(el, filter) {
8
+ if (el && el.nodeType === 1) {
9
+ if (filter) {
10
+ return el.matches(filter);
11
+ }
12
+ return true;
13
+ }
14
+ return false;
15
+ }
16
+
17
+ // the next siblings
18
+ function getNextSiblings(el, filter = false || '') {
19
+ const sibs = [];
20
+ while (el = el.nextSibling) {
21
+ if (matches(el, filter)) {
22
+ sibs.push(el);
23
+ }
24
+ }
25
+ return sibs;
26
+ }
27
+
28
+ // previous siblings
29
+ function getPreviousSiblings(el, filter = false || '') {
30
+ const sibs = [];
31
+ while (el = el.previousSibling) {
32
+ if (matches(el, filter)) {
33
+ sibs.push(el);
34
+ }
35
+ }
36
+ return sibs;
37
+ }
38
+
39
+ // parent and get all the siblings
40
+ function getAllSiblings(el, filter = false || '') {
41
+ const sibs = [];
42
+ el = el.parentNode.firstChild;
43
+ while (el = el.nextSibling) {
44
+ if (matches(el, filter)) {
45
+ sibs.push(el);
46
+ }
47
+ }
48
+ return sibs;
49
+ }
50
+
51
+ // all parent nodes
52
+ function getParents(el, filter = false || '') {
53
+ const parents = [];
54
+ while (el = el.parentNode) {
55
+ if (matches(el, filter)) {
56
+ parents.push(el);
57
+ }
58
+ }
59
+ return parents;
60
+ }
61
+
62
+ // all child nodes
63
+ function getChildren(el, filter = false || '', all = []) {
64
+ all.push(...el.childNodes);
65
+ for (const child of el.childNodes) {
66
+ getChildren(child, filter, all);
67
+ }
68
+
69
+ const res = all.filter( item => matches(item, filter) );
70
+ return res;
71
+ }
72
+
73
+
74
+ module.exports = {
75
+ getNextSiblings,
76
+ getPreviousSiblings,
77
+ getAllSiblings,
78
+ getParents,
79
+ getChildren
80
+ }
81
+