funda-ui 4.5.657 → 4.5.671

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 (73) hide show
  1. package/ColorPicker/index.js +3 -1
  2. package/Date/index.d.ts +1 -0
  3. package/Date/index.js +17 -2
  4. package/DragDropList/index.css +188 -0
  5. package/DragDropList/index.d.ts +44 -0
  6. package/DragDropList/index.js +1587 -0
  7. package/Input/index.d.ts +2 -0
  8. package/Input/index.js +14 -1
  9. package/LICENSE +21 -0
  10. package/MasonryLayout/index.d.ts +2 -0
  11. package/MasonryLayout/index.js +115 -5
  12. package/MultipleSelect/index.css +237 -144
  13. package/MultipleSelect/index.d.ts +24 -10
  14. package/MultipleSelect/index.js +2240 -1225
  15. package/README.md +3 -1
  16. package/RangeSlider/index.js +14 -1
  17. package/Textarea/index.d.ts +2 -0
  18. package/Textarea/index.js +14 -1
  19. package/Tree/index.d.ts +1 -0
  20. package/Tree/index.js +29 -0
  21. package/Utils/useBoundedDrag.d.ts +125 -0
  22. package/Utils/useBoundedDrag.js +380 -0
  23. package/Utils/useDragDropPosition.d.ts +169 -0
  24. package/Utils/useDragDropPosition.js +456 -0
  25. package/Utils/useIsMobile.d.ts +2 -0
  26. package/Utils/useIsMobile.js +168 -0
  27. package/all.d.ts +1 -0
  28. package/all.js +1 -1
  29. package/lib/cjs/ColorPicker/index.js +3 -1
  30. package/lib/cjs/Date/index.d.ts +1 -0
  31. package/lib/cjs/Date/index.js +17 -2
  32. package/lib/cjs/DragDropList/index.d.ts +44 -0
  33. package/lib/cjs/DragDropList/index.js +1587 -0
  34. package/lib/cjs/Input/index.d.ts +2 -0
  35. package/lib/cjs/Input/index.js +14 -1
  36. package/lib/cjs/MasonryLayout/index.d.ts +2 -0
  37. package/lib/cjs/MasonryLayout/index.js +115 -5
  38. package/lib/cjs/MultipleSelect/index.d.ts +24 -10
  39. package/lib/cjs/MultipleSelect/index.js +2240 -1225
  40. package/lib/cjs/RangeSlider/index.js +14 -1
  41. package/lib/cjs/Textarea/index.d.ts +2 -0
  42. package/lib/cjs/Textarea/index.js +14 -1
  43. package/lib/cjs/Tree/index.d.ts +1 -0
  44. package/lib/cjs/Tree/index.js +29 -0
  45. package/lib/cjs/Utils/useBoundedDrag.d.ts +125 -0
  46. package/lib/cjs/Utils/useBoundedDrag.js +380 -0
  47. package/lib/cjs/Utils/useDragDropPosition.d.ts +169 -0
  48. package/lib/cjs/Utils/useDragDropPosition.js +456 -0
  49. package/lib/cjs/Utils/useIsMobile.d.ts +2 -0
  50. package/lib/cjs/Utils/useIsMobile.js +168 -0
  51. package/lib/cjs/index.d.ts +1 -0
  52. package/lib/cjs/index.js +1 -1
  53. package/lib/css/DragDropList/index.css +188 -0
  54. package/lib/css/MultipleSelect/index.css +237 -144
  55. package/lib/esm/ColorPicker/index.tsx +53 -49
  56. package/lib/esm/Date/index.tsx +3 -0
  57. package/lib/esm/DragDropList/index.scss +245 -0
  58. package/lib/esm/DragDropList/index.tsx +494 -0
  59. package/lib/esm/Input/index.tsx +17 -3
  60. package/lib/esm/MasonryLayout/index.tsx +125 -7
  61. package/lib/esm/MultipleSelect/index.scss +288 -183
  62. package/lib/esm/MultipleSelect/index.tsx +305 -166
  63. package/lib/esm/MultipleSelect/utils/func.ts +21 -1
  64. package/lib/esm/Tabs/Tabs.tsx +1 -1
  65. package/lib/esm/Textarea/index.tsx +18 -1
  66. package/lib/esm/Tree/TreeList.tsx +32 -0
  67. package/lib/esm/Tree/index.tsx +3 -0
  68. package/lib/esm/Utils/hooks/useBoundedDrag.tsx +301 -0
  69. package/lib/esm/Utils/hooks/useDragDropPosition.tsx +420 -0
  70. package/lib/esm/Utils/hooks/useIsMobile.tsx +56 -0
  71. package/lib/esm/index.js +1 -0
  72. package/package.json +1 -1
  73. package/lib/esm/MultipleSelect/ItemList.tsx +0 -323
@@ -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
- const perBrickWidth = wrapperWidth/colCount; // Prevent the width of the internal elements from overflowing
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
- items.forEach((el: React.ReactNode, i: number) => {
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}>{el}</div>
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
- {columnWrapper[`${itemWrapperKey}${i}`]}
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