@swan-io/lake 12.2.16 → 12.4.0

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@swan-io/lake",
3
- "version": "12.2.16",
3
+ "version": "12.4.0",
4
4
  "engines": {
5
5
  "node": "^22.12.0"
6
6
  },
@@ -44,8 +44,12 @@ export type VirtualizedListProps<T, ExtraInfo> = {
44
44
  isLoading: boolean;
45
45
  count: number;
46
46
  };
47
+ onColumnResize?: (values: {
48
+ id: string;
49
+ width: number;
50
+ }) => void;
47
51
  };
48
- export declare const VirtualizedList: <T, ExtraInfo>({ variant, data, stickedToStartColumns, columns, stickedToEndColumns, headerHeight, rowHeight, renderThreshold, onEndReached, onEndReachedThreshold, loading, extraInfo, keyExtractor, marginHorizontal, renderEmptyList, getRowLink, }: VirtualizedListProps<T, ExtraInfo>) => import("react/jsx-runtime").JSX.Element;
52
+ export declare const VirtualizedList: <T, ExtraInfo>({ variant, data, stickedToStartColumns, columns, stickedToEndColumns, headerHeight, rowHeight, renderThreshold, onEndReached, onEndReachedThreshold, loading, extraInfo, keyExtractor, marginHorizontal, renderEmptyList, onColumnResize, getRowLink, }: VirtualizedListProps<T, ExtraInfo>) => import("react/jsx-runtime").JSX.Element;
49
53
  type VirtualizedListPlaceholderProps = {
50
54
  count: number;
51
55
  rowHeight: number;
@@ -5,6 +5,7 @@ import { StyleSheet, View } from "react-native";
5
5
  import { commonStyles } from "../constants/commonStyles";
6
6
  import { backgroundColor as backgroundColorVariants, colors, spacings } from "../constants/design";
7
7
  import { useHover } from "../hooks/useHover";
8
+ import { Pressable } from "./Pressable";
8
9
  import { ScrollView } from "./ScrollView";
9
10
  import { Space } from "./Space";
10
11
  const HORIZONTAL_ROW_PADDING = 16;
@@ -164,8 +165,108 @@ const styles = StyleSheet.create({
164
165
  smallPlaceholderRow: {
165
166
  width: "10%",
166
167
  },
168
+ resizeHandleZone: {
169
+ position: "absolute",
170
+ cursor: "ew-resize",
171
+ top: 0,
172
+ bottom: 0,
173
+ width: spacings[24],
174
+ },
175
+ resizeHandleZoneStart: {
176
+ right: 0,
177
+ alignItems: "flex-end",
178
+ },
179
+ resizeHandleZoneEnd: {
180
+ right: "auto",
181
+ left: 0,
182
+ alignItems: "flex-start",
183
+ },
184
+ resizeHandleLeft: {
185
+ right: "auto",
186
+ left: 0,
187
+ },
188
+ resizeHandle: {
189
+ backgroundColor: colors.gray[200],
190
+ height: "100%",
191
+ opacity: 0,
192
+ transitionDuration: "200ms",
193
+ transitionProperty: "opacity",
194
+ width: 3,
195
+ },
196
+ resizeHandleActive: {
197
+ opacity: 1,
198
+ },
167
199
  });
168
- export const VirtualizedList = ({ variant, data, stickedToStartColumns, columns, stickedToEndColumns, headerHeight, rowHeight, renderThreshold = 1000, onEndReached, onEndReachedThreshold = 200, loading, extraInfo, keyExtractor, marginHorizontal, renderEmptyList, getRowLink, }) => {
200
+ const ResizeHandle = ({ id, end = false, width, onResize, scrollViewRef }) => {
201
+ const ref = useRef(null);
202
+ const [isDragging, setIsDragging] = useState(false);
203
+ const widthRef = useRef(width);
204
+ const onResizeRef = useRef(onResize);
205
+ useLayoutEffect(() => {
206
+ widthRef.current = width;
207
+ onResizeRef.current = onResize;
208
+ }, [width, onResize]);
209
+ // biome-ignore lint/correctness/useExhaustiveDependencies(scrollViewRef.current.element.style): _
210
+ // biome-ignore lint/correctness/useExhaustiveDependencies(scrollViewRef.current?.element): _
211
+ useEffect(() => {
212
+ const element = ref.current;
213
+ if (element != null) {
214
+ let startX = null;
215
+ let startWidth = null;
216
+ const onMouseMove = (event) => {
217
+ var _a;
218
+ if (startX != null && startWidth != null) {
219
+ (_a = onResizeRef.current) === null || _a === void 0 ? void 0 : _a.call(onResizeRef, {
220
+ id,
221
+ width: Math.max(24, startWidth + (event.clientX - startX) * (end ? -1 : 1)),
222
+ });
223
+ }
224
+ };
225
+ const onMouseUp = (event) => {
226
+ var _a, _b;
227
+ if (((_a = scrollViewRef.current) === null || _a === void 0 ? void 0 : _a.element) != null) {
228
+ scrollViewRef.current.element.style.webkitUserSelect = "";
229
+ }
230
+ if (startX != null && startWidth != null) {
231
+ (_b = onResizeRef.current) === null || _b === void 0 ? void 0 : _b.call(onResizeRef, {
232
+ id,
233
+ width: Math.max(24, startWidth + (event.clientX - startX) * (end ? -1 : 1)),
234
+ });
235
+ }
236
+ startX = null;
237
+ document.documentElement.removeEventListener("mousemove", onMouseMove);
238
+ setIsDragging(false);
239
+ };
240
+ const onMouseDown = (event) => {
241
+ var _a;
242
+ if (((_a = scrollViewRef.current) === null || _a === void 0 ? void 0 : _a.element) != null) {
243
+ scrollViewRef.current.element.style.webkitUserSelect = "none";
244
+ }
245
+ startX = event.clientX;
246
+ startWidth = widthRef.current;
247
+ document.documentElement.addEventListener("mousemove", onMouseMove);
248
+ document.documentElement.addEventListener("mouseup", onMouseUp);
249
+ setIsDragging(true);
250
+ };
251
+ element.addEventListener("mousedown", onMouseDown);
252
+ return () => {
253
+ var _a;
254
+ if (((_a = scrollViewRef.current) === null || _a === void 0 ? void 0 : _a.element) != null) {
255
+ scrollViewRef.current.element.style.webkitUserSelect = "";
256
+ }
257
+ setIsDragging(false);
258
+ element.removeEventListener("mousedown", onMouseDown);
259
+ document.documentElement.removeEventListener("mousemove", onMouseMove);
260
+ document.documentElement.removeEventListener("mouseup", onMouseUp);
261
+ };
262
+ }
263
+ }, [id, end]);
264
+ return (_jsx(Pressable, { ref: ref, role: "none", style: [
265
+ styles.resizeHandleZone,
266
+ end ? styles.resizeHandleZoneEnd : styles.resizeHandleZoneStart,
267
+ ], children: ({ hovered }) => (_jsx(View, { style: [styles.resizeHandle, (hovered || isDragging) && styles.resizeHandleActive] })) }));
268
+ };
269
+ export const VirtualizedList = ({ variant, data, stickedToStartColumns, columns, stickedToEndColumns, headerHeight, rowHeight, renderThreshold = 1000, onEndReached, onEndReachedThreshold = 200, loading, extraInfo, keyExtractor, marginHorizontal, renderEmptyList, onColumnResize, getRowLink, }) => {
169
270
  // Used for unique IDs generation (usefull for header IDs and cells aria-describedBy pointing to them)
170
271
  const viewId = useId();
171
272
  const scrollViewRef = useRef(null);
@@ -301,7 +402,7 @@ export const VirtualizedList = ({ variant, data, stickedToStartColumns, columns,
301
402
  ], children: columns.map(({ id, width, title, renderTitle }, index) => {
302
403
  const columnId = `${viewId}_${id}`;
303
404
  const paddingLeft = index === 0 ? stickedToStartFirstCellLeftPadding : 0;
304
- return (_jsx(View, { style: [styles.headerCell, { width: width + paddingLeft, paddingLeft }], id: columnId, children: renderTitle({ title, extraInfo, id }) }, columnId));
405
+ return (_jsxs(View, { style: [styles.headerCell, { width: width + paddingLeft, paddingLeft }], id: columnId, children: [renderTitle({ title, extraInfo, id }), _jsx(ResizeHandle, { width: width, id: id, onResize: onColumnResize, scrollViewRef: scrollViewRef })] }, columnId));
305
406
  }) })))
306
407
  .toNull(), _jsx(View, { style: [
307
408
  styles.cellsContainer,
@@ -311,11 +412,11 @@ export const VirtualizedList = ({ variant, data, stickedToStartColumns, columns,
311
412
  const columnId = `${viewId}_${id}`;
312
413
  const paddingLeft = index === 0 ? centerFirstCellLeftPadding : 0;
313
414
  const paddingRight = index === columns.length - 1 ? centerLastCellLeftPadding : 0;
314
- return (_jsx(View, { style: [
415
+ return (_jsxs(View, { style: [
315
416
  styles.headerCell,
316
417
  grow && styles.grow,
317
418
  { width: width + paddingLeft + paddingRight, paddingLeft, paddingRight },
318
- ], id: columnId, children: renderTitle({ title, extraInfo, id }) }, columnId));
419
+ ], id: columnId, children: [renderTitle({ title, extraInfo, id }), _jsx(ResizeHandle, { width: width, id: id, onResize: onColumnResize, scrollViewRef: scrollViewRef })] }, columnId));
319
420
  }) }), Option.fromNullable(stickedToEndColumns)
320
421
  .map(columns => (_jsx(View, { style: [
321
422
  styles.cellsContainer,
@@ -325,7 +426,7 @@ export const VirtualizedList = ({ variant, data, stickedToStartColumns, columns,
325
426
  ], children: columns.map(({ id, width, title, renderTitle }, index) => {
326
427
  const columnId = `${viewId}_${id}`;
327
428
  const paddingRight = index === columns.length - 1 ? stickedToEndLastCellRightPadding : 0;
328
- return (_jsx(View, { style: [styles.headerCell, { width: width + paddingRight, paddingRight }], id: columnId, children: renderTitle({ title, extraInfo, id }) }, columnId));
429
+ return (_jsxs(View, { style: [styles.headerCell, { width: width + paddingRight, paddingRight }], id: columnId, children: [renderTitle({ title, extraInfo, id }), _jsx(ResizeHandle, { end: true, width: width, id: id, onResize: onColumnResize, scrollViewRef: scrollViewRef })] }, columnId));
329
430
  }) })))
330
431
  .toNull()] }));
331
432
  }, [
@@ -344,6 +445,7 @@ export const VirtualizedList = ({ variant, data, stickedToStartColumns, columns,
344
445
  centerFirstCellLeftPadding,
345
446
  centerLastCellLeftPadding,
346
447
  stickedToEndLastCellRightPadding,
448
+ onColumnResize,
347
449
  ]);
348
450
  const startColumnShadow = useMemo(() => {
349
451
  if (stickedToStartColumnsWidth === 0) {