funda-ui 4.7.625 → 4.7.711

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 (90) hide show
  1. package/CascadingSelect/index.js +2 -2
  2. package/CascadingSelectE2E/index.js +2 -2
  3. package/Chatbox/index.js +3 -17
  4. package/Checkbox/index.js +3 -3
  5. package/ColorPicker/index.js +3 -18
  6. package/Date/index.js +3 -18
  7. package/EventCalendarTimeline/index.d.ts +2 -2
  8. package/EventCalendarTimeline/index.js +24 -6
  9. package/File/index.d.ts +9 -0
  10. package/File/index.js +245 -93
  11. package/Input/index.js +3 -18
  12. package/LiveSearch/index.js +3 -18
  13. package/NativeSelect/index.js +3 -3
  14. package/NumberInput/index.js +3 -18
  15. package/Popover/index.css +198 -0
  16. package/Popover/index.d.ts +4 -0
  17. package/Popover/index.js +1808 -0
  18. package/README.md +1 -0
  19. package/Radio/index.js +3 -3
  20. package/RangeSlider/index.js +3 -18
  21. package/SearchBar/index.js +3 -18
  22. package/Select/index.js +3 -2
  23. package/Switch/index.js +3 -3
  24. package/TagInput/index.css +31 -31
  25. package/TagInput/index.js +12 -23
  26. package/Textarea/index.js +3 -17
  27. package/Utils/usePageVisibility.d.ts +5 -0
  28. package/Utils/usePageVisibility.js +166 -0
  29. package/Utils/useSSE.d.ts +50 -0
  30. package/Utils/useSSE.js +235 -0
  31. package/all.d.ts +1 -0
  32. package/all.js +1 -0
  33. package/lib/cjs/CascadingSelect/index.js +2 -2
  34. package/lib/cjs/CascadingSelectE2E/index.js +2 -2
  35. package/lib/cjs/Chatbox/index.js +3 -17
  36. package/lib/cjs/Checkbox/index.js +3 -3
  37. package/lib/cjs/ColorPicker/index.js +3 -18
  38. package/lib/cjs/Date/index.js +3 -18
  39. package/lib/cjs/EventCalendarTimeline/index.d.ts +2 -2
  40. package/lib/cjs/EventCalendarTimeline/index.js +24 -6
  41. package/lib/cjs/File/index.d.ts +9 -0
  42. package/lib/cjs/File/index.js +245 -93
  43. package/lib/cjs/Input/index.js +3 -18
  44. package/lib/cjs/LiveSearch/index.js +3 -18
  45. package/lib/cjs/NativeSelect/index.js +3 -3
  46. package/lib/cjs/NumberInput/index.js +3 -18
  47. package/lib/cjs/Popover/index.d.ts +4 -0
  48. package/lib/cjs/Popover/index.js +1808 -0
  49. package/lib/cjs/Radio/index.js +3 -3
  50. package/lib/cjs/RangeSlider/index.js +3 -18
  51. package/lib/cjs/SearchBar/index.js +3 -18
  52. package/lib/cjs/Select/index.js +3 -2
  53. package/lib/cjs/Switch/index.js +3 -3
  54. package/lib/cjs/TagInput/index.js +12 -23
  55. package/lib/cjs/Textarea/index.js +3 -17
  56. package/lib/cjs/Utils/usePageVisibility.d.ts +5 -0
  57. package/lib/cjs/Utils/usePageVisibility.js +166 -0
  58. package/lib/cjs/Utils/useSSE.d.ts +50 -0
  59. package/lib/cjs/Utils/useSSE.js +235 -0
  60. package/lib/cjs/index.d.ts +1 -0
  61. package/lib/cjs/index.js +1 -0
  62. package/lib/css/Popover/index.css +198 -0
  63. package/lib/css/TagInput/index.css +31 -31
  64. package/lib/esm/CascadingSelect/index.tsx +2 -2
  65. package/lib/esm/CascadingSelectE2E/index.tsx +2 -2
  66. package/lib/esm/Checkbox/index.tsx +3 -3
  67. package/lib/esm/ColorPicker/index.tsx +4 -15
  68. package/lib/esm/EventCalendarTimeline/index.tsx +30 -13
  69. package/lib/esm/File/index.tsx +148 -23
  70. package/lib/esm/Input/index.tsx +6 -17
  71. package/lib/esm/ModalDialog/index.tsx +0 -1
  72. package/lib/esm/NativeSelect/index.tsx +3 -3
  73. package/lib/esm/NumberInput/index.tsx +7 -15
  74. package/lib/esm/Popover/Popover.tsx +251 -0
  75. package/lib/esm/Popover/PopoverClose.tsx +51 -0
  76. package/lib/esm/Popover/PopoverContent.tsx +72 -0
  77. package/lib/esm/Popover/PopoverTrigger.tsx +62 -0
  78. package/lib/esm/Popover/index.scss +272 -0
  79. package/lib/esm/Popover/index.tsx +4 -0
  80. package/lib/esm/Radio/index.tsx +3 -3
  81. package/lib/esm/SearchBar/index.tsx +8 -12
  82. package/lib/esm/Select/index.tsx +2 -2
  83. package/lib/esm/Switch/index.tsx +3 -3
  84. package/lib/esm/TagInput/index.scss +24 -24
  85. package/lib/esm/TagInput/index.tsx +13 -20
  86. package/lib/esm/Textarea/index.tsx +6 -14
  87. package/lib/esm/Utils/hooks/usePageVisibility.tsx +84 -0
  88. package/lib/esm/Utils/hooks/useSSE.tsx +134 -0
  89. package/lib/esm/index.js +1 -0
  90. package/package.json +1 -1
@@ -0,0 +1,84 @@
1
+ /**
2
+ * Watch for to know when a document becomes visible or hidden
3
+ * @param onVisible
4
+ * @param onHidden
5
+ * @param onPageInit executed once when the page first loads visibly
6
+ */
7
+ /*
8
+ @usage:
9
+
10
+ const App = () => {
11
+ usePageVisibility(
12
+ () => console.log("🍏 Page is now visible — current tab is active."),
13
+ () => console.log("🍎 Page is hidden — switched to another tab or minimized."),
14
+ () => console.log("🎬 Page initialized while visible.")
15
+ );
16
+
17
+ return <div>Try switching tabs to see the console output.</div>;
18
+ };
19
+
20
+ */
21
+ import { useEffect, useRef } from "react";
22
+
23
+ type VisibilityCallback = () => void;
24
+
25
+ type UsePageVisibility = (
26
+ onVisible?: VisibilityCallback,
27
+ onHidden?: VisibilityCallback,
28
+ onPageInit?: VisibilityCallback
29
+ ) => void;
30
+
31
+ const usePageVisibility: UsePageVisibility = (
32
+ onVisible,
33
+ onHidden,
34
+ onPageInit
35
+ ) => {
36
+ const visibleRef = useRef<boolean>(document.visibilityState === "visible");
37
+ const onVisibleRef = useRef<VisibilityCallback | undefined>(onVisible);
38
+ const onHiddenRef = useRef<VisibilityCallback | undefined>(onHidden);
39
+ const initialVisibleTriggeredRef = useRef<boolean>(false);
40
+ const onPageInitRef = useRef<VisibilityCallback | undefined>(onPageInit);
41
+
42
+ useEffect(() => {
43
+ onVisibleRef.current = onVisible;
44
+ }, [onVisible]);
45
+
46
+ useEffect(() => {
47
+ onHiddenRef.current = onHidden;
48
+ }, [onHidden]);
49
+
50
+ useEffect(() => {
51
+ onPageInitRef.current = onPageInit;
52
+ }, [onPageInit]);
53
+
54
+ useEffect(() => {
55
+ const handleVisibilityChange = () => {
56
+ const isVisible = document.visibilityState === "visible";
57
+
58
+ if (isVisible && !visibleRef.current) {
59
+ onVisibleRef.current && onVisibleRef.current();
60
+ }
61
+
62
+ if (!isVisible && visibleRef.current) {
63
+ onHiddenRef.current && onHiddenRef.current();
64
+ }
65
+
66
+ visibleRef.current = isVisible;
67
+ };
68
+
69
+ // It retains the original switching monitor, and can ensure that onPageInit will run when the first screen is loaded.
70
+ if (visibleRef.current && !initialVisibleTriggeredRef.current) {
71
+ initialVisibleTriggeredRef.current = true;
72
+ onPageInitRef.current && onPageInitRef.current();
73
+ }
74
+
75
+ document.addEventListener("visibilitychange", handleVisibilityChange);
76
+ return () => {
77
+ document.removeEventListener("visibilitychange", handleVisibilityChange);
78
+ };
79
+ }, []);
80
+ };
81
+
82
+
83
+ export default usePageVisibility;
84
+ export { usePageVisibility };
@@ -0,0 +1,134 @@
1
+ /**
2
+ * SSE
3
+ *
4
+ * @usage:
5
+ *
6
+ const App = () => {
7
+ const { connected, messages, disconnect, reconnect } = useSSE('http://localhost:3000/sse');
8
+
9
+ return (
10
+ <div>
11
+ <p>Status: {connected ? '✅ Connected' : '❌ Disconnected'}</p>
12
+ <button onClick={disconnect}>Disconnect</button>
13
+ <button onClick={reconnect}>Reconnect</button>
14
+ {messages.map((m, i) => <div key={i}>{m}</div>)}
15
+ </div>
16
+ );
17
+ };
18
+
19
+ * It is recommended to use it in conjunction with usePageVisibility, because in HTTP mode,
20
+ * browsers allow a maximum of 6 connections; otherwise, other normal interfaces will be suspended and inaccessible.
21
+
22
+ import usePageVisibility from 'funda-ui/Utils/usePageVisibility';
23
+
24
+ const App = () => {
25
+ const { connected, messages, disconnect, reconnect } = useSSE('http://localhost:3000/sse');
26
+
27
+ // add new
28
+ usePageVisibility(
29
+ () => {
30
+ reconnect();
31
+ },
32
+ () => {
33
+ disconnect();
34
+ },
35
+ () => console.log("🎬 Page initialized while visible.")
36
+ );
37
+
38
+ return '';
39
+ };
40
+
41
+ */
42
+
43
+
44
+ import { useEffect, useRef, useState, useCallback } from 'react';
45
+
46
+ const useSSE = (url: string | null | undefined, retryDelay: number = 3000) => {
47
+ const [connected, setConnected] = useState<boolean>(false);
48
+ const [messages, setMessages] = useState<string[]>([]);
49
+ const sourceRef = useRef<EventSource | null>(null);
50
+ const reconnectTimerRef = useRef<NodeJS.Timeout | null>(null);
51
+ const manuallyClosedRef = useRef<boolean>(false);
52
+
53
+ const internalCleanup = useCallback(() => {
54
+ if (reconnectTimerRef.current) {
55
+ clearTimeout(reconnectTimerRef.current);
56
+ reconnectTimerRef.current = null;
57
+ }
58
+
59
+ if (sourceRef.current) {
60
+ try {
61
+ sourceRef.current.close();
62
+ } catch (_) {
63
+ // Ignore errors during cleanup
64
+ }
65
+ sourceRef.current = null;
66
+ }
67
+
68
+ setConnected(false);
69
+ }, []);
70
+
71
+ const connect = useCallback(() => {
72
+ if (!url || manuallyClosedRef.current) return;
73
+
74
+ // Prevent duplicate connections
75
+ if (sourceRef.current) return;
76
+
77
+ const source = new EventSource(url);
78
+ sourceRef.current = source;
79
+
80
+ source.onopen = () => {
81
+ setConnected(true);
82
+ };
83
+
84
+ source.onmessage = (event: MessageEvent) => {
85
+ setMessages([event.data]);
86
+ };
87
+
88
+ source.onerror = (err: Event) => {
89
+ internalCleanup();
90
+
91
+ if (!manuallyClosedRef.current) {
92
+ reconnectTimerRef.current = setTimeout(() => {
93
+ connect();
94
+ }, retryDelay);
95
+ }
96
+ };
97
+ }, [internalCleanup, retryDelay, url]);
98
+
99
+ const disconnect = useCallback(() => {
100
+ manuallyClosedRef.current = true;
101
+ internalCleanup();
102
+ }, [internalCleanup]);
103
+
104
+ const reconnect = useCallback(() => {
105
+ manuallyClosedRef.current = false;
106
+ internalCleanup();
107
+ connect();
108
+ }, [connect, internalCleanup]);
109
+
110
+ const resetMessages = useCallback(() => setMessages([]), []);
111
+
112
+ useEffect(() => {
113
+ if (!url) return;
114
+
115
+ manuallyClosedRef.current = false;
116
+ connect();
117
+
118
+ return () => {
119
+ // Cleanup on unmount (does not mark manual close)
120
+ internalCleanup();
121
+ };
122
+ }, [url, connect, internalCleanup]);
123
+
124
+ return {
125
+ connected,
126
+ messages,
127
+ disconnect,
128
+ reconnect,
129
+ resetMessages
130
+ } as const;
131
+ };
132
+
133
+ export default useSSE;
134
+ export { useSSE };
package/lib/esm/index.js CHANGED
@@ -25,6 +25,7 @@ export { default as MultipleSelect } from './MultipleSelect';
25
25
  export { default as NativeSelect } from './NativeSelect';
26
26
  export { default as NumberInput } from './NumberInput';
27
27
  export { default as Pagination } from './Pagination';
28
+ export { default as Popover } from './Popover';
28
29
  export { default as Radio } from './Radio';
29
30
  export { default as RangeSlider } from './RangeSlider';
30
31
  export { default as Refresher } from './Refresher';
package/package.json CHANGED
@@ -1 +1 @@
1
- {"author":"UIUX Lab","email":"uiuxlab@gmail.com","name":"funda-ui","version":"4.7.625","description":"React components using pure Bootstrap 5+ which does not contain any external style and script libraries.","repository":{"type":"git","url":"git+https://github.com/xizon/funda-ui.git"},"scripts":{"test":"echo \"Error: no test specified\" && exit 1"},"keywords":["bootstrap","react-bootstrap","react-components","components","components-react","react-bootstrap-components","react","funda-ui","fundaui","uikit","ui-kit","ui-components"],"bugs":{"url":"https://github.com/xizon/funda-ui/issues"},"homepage":"https://github.com/xizon/funda-ui#readme","main":"all.js","license":"MIT","dependencies":{"react":"^18.2.0","react-dom":"^18.2.0"},"types":"all.d.ts","publishConfig":{"directory":"lib"},"directories":{"lib":"lib"}}
1
+ {"author":"UIUX Lab","email":"uiuxlab@gmail.com","name":"funda-ui","version":"4.7.711","description":"React components using pure Bootstrap 5+ which does not contain any external style and script libraries.","repository":{"type":"git","url":"git+https://github.com/xizon/funda-ui.git"},"scripts":{"test":"echo \"Error: no test specified\" && exit 1"},"keywords":["bootstrap","react-bootstrap","react-components","components","components-react","react-bootstrap-components","react","funda-ui","fundaui","uikit","ui-kit","ui-components"],"bugs":{"url":"https://github.com/xizon/funda-ui/issues"},"homepage":"https://github.com/xizon/funda-ui#readme","main":"all.js","license":"MIT","dependencies":{"react":"^18.2.0","react-dom":"^18.2.0"},"types":"all.d.ts","publishConfig":{"directory":"lib"},"directories":{"lib":"lib"}}