funda-ui 4.7.625 → 4.7.701
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CascadingSelect/index.js +2 -2
- package/CascadingSelectE2E/index.js +2 -2
- package/Chatbox/index.js +3 -17
- package/Checkbox/index.js +3 -3
- package/ColorPicker/index.js +3 -18
- package/Date/index.js +3 -18
- package/EventCalendarTimeline/index.d.ts +1 -1
- package/EventCalendarTimeline/index.js +11 -1
- package/File/index.d.ts +9 -0
- package/File/index.js +245 -93
- package/Input/index.js +3 -18
- package/LiveSearch/index.js +3 -18
- package/NativeSelect/index.js +3 -3
- package/NumberInput/index.js +3 -18
- package/Popover/index.css +198 -0
- package/Popover/index.d.ts +4 -0
- package/Popover/index.js +1808 -0
- package/README.md +1 -0
- package/Radio/index.js +3 -3
- package/RangeSlider/index.js +3 -18
- package/SearchBar/index.js +3 -18
- package/Select/index.js +3 -2
- package/Switch/index.js +3 -3
- package/TagInput/index.css +31 -31
- package/TagInput/index.js +12 -23
- package/Textarea/index.js +3 -17
- package/Utils/useSSE.d.ts +9 -0
- package/Utils/useSSE.js +211 -0
- package/all.d.ts +1 -0
- package/all.js +1 -0
- package/lib/cjs/CascadingSelect/index.js +2 -2
- package/lib/cjs/CascadingSelectE2E/index.js +2 -2
- package/lib/cjs/Chatbox/index.js +3 -17
- package/lib/cjs/Checkbox/index.js +3 -3
- package/lib/cjs/ColorPicker/index.js +3 -18
- package/lib/cjs/Date/index.js +3 -18
- package/lib/cjs/EventCalendarTimeline/index.d.ts +1 -1
- package/lib/cjs/EventCalendarTimeline/index.js +11 -1
- package/lib/cjs/File/index.d.ts +9 -0
- package/lib/cjs/File/index.js +245 -93
- package/lib/cjs/Input/index.js +3 -18
- package/lib/cjs/LiveSearch/index.js +3 -18
- package/lib/cjs/NativeSelect/index.js +3 -3
- package/lib/cjs/NumberInput/index.js +3 -18
- package/lib/cjs/Popover/index.d.ts +4 -0
- package/lib/cjs/Popover/index.js +1808 -0
- package/lib/cjs/Radio/index.js +3 -3
- package/lib/cjs/RangeSlider/index.js +3 -18
- package/lib/cjs/SearchBar/index.js +3 -18
- package/lib/cjs/Select/index.js +3 -2
- package/lib/cjs/Switch/index.js +3 -3
- package/lib/cjs/TagInput/index.js +12 -23
- package/lib/cjs/Textarea/index.js +3 -17
- package/lib/cjs/Utils/useSSE.d.ts +9 -0
- package/lib/cjs/Utils/useSSE.js +211 -0
- package/lib/cjs/index.d.ts +1 -0
- package/lib/cjs/index.js +1 -0
- package/lib/css/Popover/index.css +198 -0
- package/lib/css/TagInput/index.css +31 -31
- package/lib/esm/CascadingSelect/index.tsx +2 -2
- package/lib/esm/CascadingSelectE2E/index.tsx +2 -2
- package/lib/esm/Checkbox/index.tsx +3 -3
- package/lib/esm/ColorPicker/index.tsx +4 -15
- package/lib/esm/EventCalendarTimeline/index.tsx +11 -2
- package/lib/esm/File/index.tsx +148 -23
- package/lib/esm/Input/index.tsx +6 -17
- package/lib/esm/NativeSelect/index.tsx +3 -3
- package/lib/esm/NumberInput/index.tsx +7 -15
- package/lib/esm/Popover/Popover.tsx +251 -0
- package/lib/esm/Popover/PopoverClose.tsx +51 -0
- package/lib/esm/Popover/PopoverContent.tsx +72 -0
- package/lib/esm/Popover/PopoverTrigger.tsx +62 -0
- package/lib/esm/Popover/index.scss +272 -0
- package/lib/esm/Popover/index.tsx +4 -0
- package/lib/esm/Radio/index.tsx +3 -3
- package/lib/esm/SearchBar/index.tsx +8 -12
- package/lib/esm/Select/index.tsx +2 -2
- package/lib/esm/Switch/index.tsx +3 -3
- package/lib/esm/TagInput/index.scss +24 -24
- package/lib/esm/TagInput/index.tsx +13 -20
- package/lib/esm/Textarea/index.tsx +6 -14
- package/lib/esm/Utils/hooks/useSSE.tsx +109 -0
- package/lib/esm/index.js +1 -0
- package/package.json +1 -1
|
@@ -209,12 +209,6 @@ const TagInput = forwardRef((props: TagInputProps, externalRef: any) => {
|
|
|
209
209
|
function handleChange(event: ChangeEvent<HTMLInputElement>) {
|
|
210
210
|
|
|
211
211
|
const val = event.target.value;
|
|
212
|
-
|
|
213
|
-
//----
|
|
214
|
-
//remove focus style
|
|
215
|
-
if (val === '') {
|
|
216
|
-
rootRef.current?.classList.remove('focus');
|
|
217
|
-
}
|
|
218
212
|
|
|
219
213
|
//
|
|
220
214
|
let _alreadyInItems = alreadyInItems;
|
|
@@ -239,7 +233,8 @@ const TagInput = forwardRef((props: TagInputProps, externalRef: any) => {
|
|
|
239
233
|
|
|
240
234
|
|
|
241
235
|
function handleFocus(event: FocusEvent<HTMLInputElement>) {
|
|
242
|
-
|
|
236
|
+
// tag style
|
|
237
|
+
rootRef.current?.classList.add('focus-floating');
|
|
243
238
|
|
|
244
239
|
//
|
|
245
240
|
onFocus?.(event);
|
|
@@ -250,14 +245,9 @@ const TagInput = forwardRef((props: TagInputProps, externalRef: any) => {
|
|
|
250
245
|
const el = event.target;
|
|
251
246
|
const val = event.target.value;
|
|
252
247
|
|
|
248
|
+
setUserInput('');
|
|
249
|
+
setAlreadyInItems(false);
|
|
253
250
|
|
|
254
|
-
//----
|
|
255
|
-
//remove focus style
|
|
256
|
-
if (val === '') {
|
|
257
|
-
rootRef.current?.classList.remove('focus');
|
|
258
|
-
}
|
|
259
|
-
|
|
260
|
-
//
|
|
261
251
|
onBlur?.(event);
|
|
262
252
|
}
|
|
263
253
|
|
|
@@ -277,16 +267,19 @@ const TagInput = forwardRef((props: TagInputProps, externalRef: any) => {
|
|
|
277
267
|
<>
|
|
278
268
|
|
|
279
269
|
<div className={combinedCls(
|
|
280
|
-
'
|
|
281
|
-
clsWrite(wrapperClassName, 'mb-3 position-relative')
|
|
270
|
+
'taginput__wrapper',
|
|
271
|
+
clsWrite(wrapperClassName, 'mb-3 position-relative'),
|
|
272
|
+
{
|
|
273
|
+
'focus-floating': userInput !== ''
|
|
274
|
+
}
|
|
282
275
|
)} ref={rootRef}>
|
|
283
276
|
|
|
284
277
|
{label ? <>{typeof label === 'string' ? <label htmlFor={`label-${idRes}`} className="form-label" dangerouslySetInnerHTML={{__html: `${label}`}}></label> : <label htmlFor={`label-${idRes}`} className="form-label">{label}</label>}</> : null}
|
|
285
278
|
|
|
286
279
|
|
|
287
|
-
<div className="
|
|
280
|
+
<div className="taginput__control-wrapper">
|
|
288
281
|
<div>
|
|
289
|
-
<ul className="
|
|
282
|
+
<ul className="taginput__list">
|
|
290
283
|
|
|
291
284
|
{/* ITEMS LIST */}
|
|
292
285
|
{typeof renderSelectedValue === 'function' ? <>
|
|
@@ -308,7 +301,7 @@ const TagInput = forwardRef((props: TagInputProps, externalRef: any) => {
|
|
|
308
301
|
|
|
309
302
|
|
|
310
303
|
<div className={combinedCls(
|
|
311
|
-
'
|
|
304
|
+
'taginput__control',
|
|
312
305
|
{
|
|
313
306
|
'disabled': disabled
|
|
314
307
|
}
|
|
@@ -321,7 +314,7 @@ const TagInput = forwardRef((props: TagInputProps, externalRef: any) => {
|
|
|
321
314
|
|
|
322
315
|
// Don't use "name", it's just a container to display the label
|
|
323
316
|
data-name={name?.match(/(\[.*?\])/gi) ? `${name.split('[')[0]}-label[]` : `${name}-label`}
|
|
324
|
-
data-
|
|
317
|
+
data-taginput
|
|
325
318
|
autoComplete={typeof autoComplete === 'undefined' ? 'off' : autoComplete}
|
|
326
319
|
autoCapitalize={typeof autoCapitalize === 'undefined' ? 'off' : autoCapitalize}
|
|
327
320
|
spellCheck={typeof spellCheck === 'undefined' ? false : spellCheck}
|
|
@@ -335,7 +335,6 @@ const Textarea = forwardRef((props: TextareaProps, externalRef: any) => {
|
|
|
335
335
|
|
|
336
336
|
function handleFocus(event: FocusEvent<HTMLTextAreaElement>): void {
|
|
337
337
|
const el = event.target;
|
|
338
|
-
rootRef.current?.classList.add('focus');
|
|
339
338
|
|
|
340
339
|
//
|
|
341
340
|
onFocus?.(event, valRef.current as HTMLTextAreaElement);
|
|
@@ -346,12 +345,6 @@ const Textarea = forwardRef((props: TextareaProps, externalRef: any) => {
|
|
|
346
345
|
|
|
347
346
|
setChangedVal(curVal);
|
|
348
347
|
|
|
349
|
-
//----
|
|
350
|
-
//remove focus style
|
|
351
|
-
if (curVal === '') {
|
|
352
|
-
rootRef.current?.classList.remove('focus');
|
|
353
|
-
}
|
|
354
|
-
|
|
355
348
|
//
|
|
356
349
|
onChange?.(event, valRef.current as HTMLTextAreaElement, curVal);
|
|
357
350
|
|
|
@@ -368,12 +361,6 @@ const Textarea = forwardRef((props: TextareaProps, externalRef: any) => {
|
|
|
368
361
|
const val = el.value;
|
|
369
362
|
|
|
370
363
|
|
|
371
|
-
//----
|
|
372
|
-
//remove focus style
|
|
373
|
-
if (val === '') {
|
|
374
|
-
rootRef.current?.classList.remove('focus');
|
|
375
|
-
}
|
|
376
|
-
|
|
377
364
|
//
|
|
378
365
|
onBlur?.(event, valRef.current as HTMLTextAreaElement);
|
|
379
366
|
|
|
@@ -516,7 +503,12 @@ const Textarea = forwardRef((props: TextareaProps, externalRef: any) => {
|
|
|
516
503
|
return (
|
|
517
504
|
<>
|
|
518
505
|
|
|
519
|
-
<div className={
|
|
506
|
+
<div className={combinedCls(
|
|
507
|
+
clsWrite(wrapperClassName, 'mb-3 position-relative'),
|
|
508
|
+
{
|
|
509
|
+
'focus-floating': changedVal !== ''
|
|
510
|
+
}
|
|
511
|
+
)} ref={rootRef}>
|
|
520
512
|
{label ? <>{typeof label === 'string' ? <label htmlFor={idRes} className="form-label" dangerouslySetInnerHTML={{__html: `${label}`}}></label> : <label htmlFor={idRes} className="form-label">{label}</label>}</> : null}
|
|
521
513
|
|
|
522
514
|
|
|
@@ -0,0 +1,109 @@
|
|
|
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
|
+
import { useEffect, useRef, useState, useCallback } from 'react';
|
|
20
|
+
|
|
21
|
+
const useSSE = (url: string | null | undefined, retryDelay: number = 3000) => {
|
|
22
|
+
const [connected, setConnected] = useState<boolean>(false);
|
|
23
|
+
const [messages, setMessages] = useState<string[]>([]);
|
|
24
|
+
const sourceRef = useRef<EventSource | null>(null);
|
|
25
|
+
const reconnectTimerRef = useRef<NodeJS.Timeout | null>(null);
|
|
26
|
+
const manuallyClosedRef = useRef<boolean>(false);
|
|
27
|
+
|
|
28
|
+
const internalCleanup = useCallback(() => {
|
|
29
|
+
if (reconnectTimerRef.current) {
|
|
30
|
+
clearTimeout(reconnectTimerRef.current);
|
|
31
|
+
reconnectTimerRef.current = null;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
if (sourceRef.current) {
|
|
35
|
+
try {
|
|
36
|
+
sourceRef.current.close();
|
|
37
|
+
} catch (_) {
|
|
38
|
+
// Ignore errors during cleanup
|
|
39
|
+
}
|
|
40
|
+
sourceRef.current = null;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
setConnected(false);
|
|
44
|
+
}, []);
|
|
45
|
+
|
|
46
|
+
const connect = useCallback(() => {
|
|
47
|
+
if (!url || manuallyClosedRef.current) return;
|
|
48
|
+
|
|
49
|
+
// Prevent duplicate connections
|
|
50
|
+
if (sourceRef.current) return;
|
|
51
|
+
|
|
52
|
+
const source = new EventSource(url);
|
|
53
|
+
sourceRef.current = source;
|
|
54
|
+
|
|
55
|
+
source.onopen = () => {
|
|
56
|
+
setConnected(true);
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
source.onmessage = (event: MessageEvent) => {
|
|
60
|
+
setMessages([event.data]);
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
source.onerror = (err: Event) => {
|
|
64
|
+
internalCleanup();
|
|
65
|
+
|
|
66
|
+
if (!manuallyClosedRef.current) {
|
|
67
|
+
reconnectTimerRef.current = setTimeout(() => {
|
|
68
|
+
connect();
|
|
69
|
+
}, retryDelay);
|
|
70
|
+
}
|
|
71
|
+
};
|
|
72
|
+
}, [internalCleanup, retryDelay, url]);
|
|
73
|
+
|
|
74
|
+
const disconnect = useCallback(() => {
|
|
75
|
+
manuallyClosedRef.current = true;
|
|
76
|
+
internalCleanup();
|
|
77
|
+
}, [internalCleanup]);
|
|
78
|
+
|
|
79
|
+
const reconnect = useCallback(() => {
|
|
80
|
+
manuallyClosedRef.current = false;
|
|
81
|
+
internalCleanup();
|
|
82
|
+
connect();
|
|
83
|
+
}, [connect, internalCleanup]);
|
|
84
|
+
|
|
85
|
+
const resetMessages = useCallback(() => setMessages([]), []);
|
|
86
|
+
|
|
87
|
+
useEffect(() => {
|
|
88
|
+
if (!url) return;
|
|
89
|
+
|
|
90
|
+
manuallyClosedRef.current = false;
|
|
91
|
+
connect();
|
|
92
|
+
|
|
93
|
+
return () => {
|
|
94
|
+
// Cleanup on unmount (does not mark manual close)
|
|
95
|
+
internalCleanup();
|
|
96
|
+
};
|
|
97
|
+
}, [url, connect, internalCleanup]);
|
|
98
|
+
|
|
99
|
+
return {
|
|
100
|
+
connected,
|
|
101
|
+
messages,
|
|
102
|
+
disconnect,
|
|
103
|
+
reconnect,
|
|
104
|
+
resetMessages
|
|
105
|
+
} as const;
|
|
106
|
+
};
|
|
107
|
+
|
|
108
|
+
export default useSSE;
|
|
109
|
+
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.
|
|
1
|
+
{"author":"UIUX Lab","email":"uiuxlab@gmail.com","name":"funda-ui","version":"4.7.701","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"}}
|