funda-ui 4.5.657 → 4.5.676
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/Date/index.d.ts +1 -0
- package/Date/index.js +11 -2
- package/Input/index.d.ts +2 -0
- package/Input/index.js +8 -1
- package/MasonryLayout/index.d.ts +2 -0
- package/MasonryLayout/index.js +115 -5
- package/RangeSlider/index.js +8 -1
- package/Textarea/index.d.ts +2 -0
- package/Textarea/index.js +8 -1
- package/lib/cjs/Date/index.d.ts +1 -0
- package/lib/cjs/Date/index.js +11 -2
- package/lib/cjs/Input/index.d.ts +2 -0
- package/lib/cjs/Input/index.js +8 -1
- package/lib/cjs/MasonryLayout/index.d.ts +2 -0
- package/lib/cjs/MasonryLayout/index.js +115 -5
- package/lib/cjs/RangeSlider/index.js +8 -1
- package/lib/cjs/Textarea/index.d.ts +2 -0
- package/lib/cjs/Textarea/index.js +8 -1
- package/lib/esm/Date/index.tsx +3 -0
- package/lib/esm/Input/index.tsx +11 -0
- package/lib/esm/MasonryLayout/index.tsx +125 -7
- package/lib/esm/Textarea/index.tsx +12 -0
- package/package.json +1 -1
|
@@ -11,10 +11,12 @@ export type MasonryLayoutProps = {
|
|
|
11
11
|
columns?: number;
|
|
12
12
|
gap?: number;
|
|
13
13
|
breakPoints?: Record<number, number>;
|
|
14
|
+
balanceColumnHeights?: boolean;
|
|
14
15
|
/** -- */
|
|
15
16
|
id?: string;
|
|
16
17
|
tabIndex?: number;
|
|
17
18
|
children: React.ReactNode;
|
|
19
|
+
onResize?: (wrapperWidth: number) => void;
|
|
18
20
|
};
|
|
19
21
|
|
|
20
22
|
|
|
@@ -23,8 +25,10 @@ const MasonryLayout = (props: MasonryLayoutProps) => {
|
|
|
23
25
|
columns,
|
|
24
26
|
gap,
|
|
25
27
|
breakPoints,
|
|
28
|
+
balanceColumnHeights = true,
|
|
26
29
|
id,
|
|
27
|
-
children
|
|
30
|
+
children,
|
|
31
|
+
onResize
|
|
28
32
|
} = props;
|
|
29
33
|
|
|
30
34
|
|
|
@@ -33,13 +37,15 @@ const MasonryLayout = (props: MasonryLayoutProps) => {
|
|
|
33
37
|
const rootRef = useRef<any>(null);
|
|
34
38
|
const itemWrapperKey = 'column-';
|
|
35
39
|
const [items, setItems] = useState<React.ReactNode[]>([]);
|
|
40
|
+
const [orginalItems, setOrginalItems] = useState<React.ReactNode[]>([]);
|
|
36
41
|
const COLS = typeof columns !== 'undefined' ? parseFloat(columns as any) : 2;
|
|
37
42
|
const GAP = typeof gap !== 'undefined' ? parseFloat(gap as any) : 15;
|
|
43
|
+
const colsRef = useRef<Record<string, any>>(new Map());
|
|
38
44
|
|
|
39
45
|
const windowResizeUpdate = debounce(handleWindowUpdate, 50);
|
|
40
46
|
let windowWidth = typeof window !== 'undefined' ? window.innerWidth : 0;
|
|
41
47
|
|
|
42
|
-
const calcInit = useCallback((w: number) => {
|
|
48
|
+
const calcInit = useCallback((w: number, minColIndex: number | undefined = undefined, maxColIndex: number | undefined = undefined) => {
|
|
43
49
|
|
|
44
50
|
let colCount = COLS;
|
|
45
51
|
const columnWrapper: any = {};
|
|
@@ -100,27 +106,52 @@ const MasonryLayout = (props: MasonryLayoutProps) => {
|
|
|
100
106
|
items = children;
|
|
101
107
|
}
|
|
102
108
|
|
|
109
|
+
|
|
103
110
|
// get wrapper width
|
|
104
111
|
const wrapperWidth = rootRef.current?.offsetWidth || 0;
|
|
105
|
-
|
|
112
|
+
let perBrickWidth = wrapperWidth/colCount; // Prevent the width of the internal elements from overflowing
|
|
113
|
+
|
|
114
|
+
|
|
115
|
+
// return wrapper width
|
|
116
|
+
onResize?.(wrapperWidth);
|
|
106
117
|
|
|
107
118
|
|
|
108
|
-
|
|
119
|
+
//
|
|
120
|
+
React.Children.forEach(children, (child: any, i: number) => {
|
|
121
|
+
if (!child) return;
|
|
122
|
+
|
|
109
123
|
const columnIndex = i % colCount;
|
|
110
|
-
|
|
124
|
+
const itemRow = Math.floor(i / colCount);
|
|
125
|
+
const itemIndex = itemRow * colCount + columnIndex;
|
|
126
|
+
|
|
127
|
+
//
|
|
111
128
|
columnWrapper[`${itemWrapperKey}${columnIndex}`].push(
|
|
112
129
|
<div
|
|
113
130
|
key={i}
|
|
131
|
+
data-row={itemRow}
|
|
132
|
+
data-col={columnIndex}
|
|
133
|
+
data-index={itemIndex}
|
|
114
134
|
style={{
|
|
115
135
|
marginBottom: `${GAP}px`
|
|
116
136
|
}}
|
|
117
137
|
>
|
|
118
|
-
<div style={perBrickWidth > 0 ? {width: perBrickWidth + 'px'} : undefined}>{
|
|
138
|
+
<div style={perBrickWidth > 0 ? {width: perBrickWidth + 'px'} : undefined}>{child}</div>
|
|
119
139
|
</div>
|
|
120
140
|
);
|
|
121
141
|
});
|
|
122
142
|
|
|
123
143
|
|
|
144
|
+
// Add the item to the shortest column
|
|
145
|
+
if (
|
|
146
|
+
balanceColumnHeights &&
|
|
147
|
+
(typeof minColIndex !== 'undefined' && typeof maxColIndex !== 'undefined') &&
|
|
148
|
+
items.length > COLS
|
|
149
|
+
) {
|
|
150
|
+
const maxColLastElement = columnWrapper[`${itemWrapperKey}${maxColIndex}`].pop();
|
|
151
|
+
columnWrapper[`${itemWrapperKey}${minColIndex}`].push(maxColLastElement);
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
|
|
124
155
|
// STEP 5:
|
|
125
156
|
//=================
|
|
126
157
|
// Wrapping the items in each column with a div and pushing it into the result array
|
|
@@ -133,15 +164,35 @@ const MasonryLayout = (props: MasonryLayoutProps) => {
|
|
|
133
164
|
marginLeft: `${i > 0 ? GAP : 0}px`,
|
|
134
165
|
flex: '0 1 auto'
|
|
135
166
|
}}>
|
|
136
|
-
|
|
167
|
+
<div
|
|
168
|
+
className="masonry-item-inner"
|
|
169
|
+
data-inner-col={i}
|
|
170
|
+
ref={el => {
|
|
171
|
+
if (el) {
|
|
172
|
+
colsRef.current.set(`col-${i}`, el);
|
|
173
|
+
} else {
|
|
174
|
+
colsRef.current.delete(`col-${i}`);
|
|
175
|
+
}
|
|
176
|
+
}}
|
|
177
|
+
>
|
|
178
|
+
{columnWrapper[`${itemWrapperKey}${i}`]}
|
|
179
|
+
</div>
|
|
137
180
|
</div>
|
|
138
181
|
);
|
|
139
182
|
}
|
|
140
183
|
|
|
141
184
|
// STEP 6:
|
|
142
185
|
//=================
|
|
186
|
+
// update items
|
|
143
187
|
setItems(result);
|
|
188
|
+
|
|
189
|
+
// update orginal items
|
|
190
|
+
if (typeof minColIndex === 'undefined' && typeof maxColIndex === 'undefined') {
|
|
191
|
+
setOrginalItems(result);
|
|
192
|
+
}
|
|
193
|
+
|
|
144
194
|
|
|
195
|
+
|
|
145
196
|
}, [children]);
|
|
146
197
|
|
|
147
198
|
|
|
@@ -160,6 +211,73 @@ const MasonryLayout = (props: MasonryLayoutProps) => {
|
|
|
160
211
|
}
|
|
161
212
|
}
|
|
162
213
|
|
|
214
|
+
function adjustPosition() {
|
|
215
|
+
if (rootRef.current === null) return;
|
|
216
|
+
|
|
217
|
+
// Adjust the position of the element
|
|
218
|
+
const initCols = () => {
|
|
219
|
+
|
|
220
|
+
const columnHeights = new Array(COLS).fill(0);
|
|
221
|
+
React.Children.forEach(items, (child: any, i: number) => {
|
|
222
|
+
if (!child) return;
|
|
223
|
+
|
|
224
|
+
const columnIndex = i % COLS;
|
|
225
|
+
|
|
226
|
+
// update column height
|
|
227
|
+
const columnInner = colsRef.current.get(`col-${columnIndex}`);
|
|
228
|
+
if (columnInner) {
|
|
229
|
+
const height = columnInner.offsetHeight;
|
|
230
|
+
columnHeights[columnIndex] = height;
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
});
|
|
234
|
+
|
|
235
|
+
// Find the shortest height column
|
|
236
|
+
const minHeight = Math.min(...columnHeights);
|
|
237
|
+
const maxHeight = Math.max(...columnHeights);
|
|
238
|
+
if (minHeight > 0 && maxHeight > 0 && maxHeight/2 > minHeight) {
|
|
239
|
+
const columnMinHeightIndex = columnHeights.indexOf(minHeight);
|
|
240
|
+
const columnMaxHeightIndex = columnHeights.indexOf(maxHeight);
|
|
241
|
+
calcInit(windowWidth, columnMinHeightIndex, columnMaxHeightIndex);
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
|
|
245
|
+
};
|
|
246
|
+
|
|
247
|
+
const images: NodeListOf<HTMLImageElement> = rootRef.current.querySelectorAll('img');
|
|
248
|
+
const imagePromises: Promise<void>[] = [];
|
|
249
|
+
images.forEach((img: HTMLImageElement) => {
|
|
250
|
+
const imgPromise: Promise<void> = new Promise((resolve, reject) => {
|
|
251
|
+
if (img.complete) {
|
|
252
|
+
resolve();
|
|
253
|
+
} else {
|
|
254
|
+
img.onload = () => resolve();
|
|
255
|
+
img.onerror = () => resolve();
|
|
256
|
+
}
|
|
257
|
+
});
|
|
258
|
+
imagePromises.push(imgPromise);
|
|
259
|
+
});
|
|
260
|
+
|
|
261
|
+
// Wait for all images to load
|
|
262
|
+
if (images.length > 0) {
|
|
263
|
+
Promise.all(imagePromises)
|
|
264
|
+
.then(() => {
|
|
265
|
+
initCols();
|
|
266
|
+
})
|
|
267
|
+
.catch((error: Error) => {
|
|
268
|
+
console.error(error);
|
|
269
|
+
});
|
|
270
|
+
} else {
|
|
271
|
+
initCols();
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
|
|
276
|
+
useEffect(() => {
|
|
277
|
+
adjustPosition();
|
|
278
|
+
}, [orginalItems]);
|
|
279
|
+
|
|
280
|
+
|
|
163
281
|
useEffect(() => {
|
|
164
282
|
|
|
165
283
|
// Initialize items
|
|
@@ -50,6 +50,8 @@ export type TextareaProps = {
|
|
|
50
50
|
onBlur?: (e: any, el: any) => void;
|
|
51
51
|
onFocus?: (e: any, el: any) => void;
|
|
52
52
|
onPressEnter?: (e: any, el: any) => void;
|
|
53
|
+
onKeyDown?: (e: any, el: any) => void;
|
|
54
|
+
onKeyUp?: (e: any, el: any) => void;
|
|
53
55
|
onResize?: (el: any, params: number[]) => void;
|
|
54
56
|
|
|
55
57
|
};
|
|
@@ -96,6 +98,8 @@ const Textarea = forwardRef((props: TextareaProps, externalRef: any) => {
|
|
|
96
98
|
onBlur,
|
|
97
99
|
onFocus,
|
|
98
100
|
onPressEnter,
|
|
101
|
+
onKeyDown,
|
|
102
|
+
onKeyUp,
|
|
99
103
|
onResize,
|
|
100
104
|
...attributes
|
|
101
105
|
} = props;
|
|
@@ -363,6 +367,10 @@ const Textarea = forwardRef((props: TextareaProps, externalRef: any) => {
|
|
|
363
367
|
}
|
|
364
368
|
|
|
365
369
|
function handleKeyPressed(event: KeyboardEvent<HTMLTextAreaElement>) {
|
|
370
|
+
|
|
371
|
+
onKeyDown?.(event, valRef.current);
|
|
372
|
+
|
|
373
|
+
|
|
366
374
|
if (typeof (onKeyPressedCallback) === 'function') {
|
|
367
375
|
const newData: any = onKeyPressedCallback(event, valRef.current);
|
|
368
376
|
if (newData) setChangedVal(newData); // Avoid the error "react checkbox changing an uncontrolled input to be controlled"
|
|
@@ -418,6 +426,9 @@ const Textarea = forwardRef((props: TextareaProps, externalRef: any) => {
|
|
|
418
426
|
|
|
419
427
|
}
|
|
420
428
|
|
|
429
|
+
function handleKeyUp(event: KeyboardEvent<HTMLTextAreaElement>) {
|
|
430
|
+
onKeyUp?.(event, valRef.current);
|
|
431
|
+
}
|
|
421
432
|
|
|
422
433
|
useEffect(() => {
|
|
423
434
|
|
|
@@ -534,6 +545,7 @@ const Textarea = forwardRef((props: TextareaProps, externalRef: any) => {
|
|
|
534
545
|
}
|
|
535
546
|
}}
|
|
536
547
|
onKeyDown={handleKeyPressed}
|
|
548
|
+
onKeyUp={handleKeyUp}
|
|
537
549
|
disabled={disabled || null}
|
|
538
550
|
required={required || null}
|
|
539
551
|
readOnly={readOnly || null}
|
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"author": "UIUX Lab",
|
|
3
3
|
"email": "uiuxlab@gmail.com",
|
|
4
4
|
"name": "funda-ui",
|
|
5
|
-
"version": "4.5.
|
|
5
|
+
"version": "4.5.676",
|
|
6
6
|
"description": "React components using pure Bootstrap 5+ which does not contain any external style and script libraries.",
|
|
7
7
|
"repository": {
|
|
8
8
|
"type": "git",
|