@swan-io/lake 2.7.34 → 2.7.36

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": "2.7.34",
3
+ "version": "2.7.36",
4
4
  "engines": {
5
5
  "node": ">=18.0.0",
6
6
  "yarn": "^1.22.0"
@@ -36,6 +36,7 @@ type Props<T, ExtraInfo> = {
36
36
  breakpoint?: number;
37
37
  withoutScroll?: boolean;
38
38
  stickyOffset?: number;
39
+ headerBackgroundColor?: string;
39
40
  };
40
- export declare const PlainListView: <T, ExtraInfo>({ data: originalData, keyExtractor, rowHeight, groupHeaderHeight, headerHeight, columns, smallColumns, extraInfo, onEndReached, onEndReachedThresholdPx, headerStyle, rowStyle, getRowLink, activeRowId, renderEmptyList, onActiveRowChange, groupBy, loading, breakpoint, withoutScroll, stickyOffset, }: Props<T, ExtraInfo>) => import("react/jsx-runtime").JSX.Element;
41
+ export declare const PlainListView: <T, ExtraInfo>({ data: originalData, keyExtractor, rowHeight, groupHeaderHeight, headerHeight, columns, smallColumns, extraInfo, onEndReached, onEndReachedThresholdPx, headerStyle, rowStyle, getRowLink, activeRowId, renderEmptyList, onActiveRowChange, groupBy, loading, breakpoint, withoutScroll, stickyOffset, headerBackgroundColor, }: Props<T, ExtraInfo>) => import("react/jsx-runtime").JSX.Element;
41
42
  export {};
@@ -44,6 +44,13 @@ const styles = StyleSheet.create({
44
44
  flexDirection: "row",
45
45
  alignItems: "center",
46
46
  },
47
+ header: {
48
+ position: "sticky",
49
+ top: 0,
50
+ flexDirection: "row",
51
+ alignItems: "stretch",
52
+ zIndex: 2,
53
+ },
47
54
  stickyHeader: {
48
55
  position: "sticky",
49
56
  backgroundColor: backgroundColor.default90Transparency,
@@ -106,7 +113,7 @@ const Row = ({ id, item, index, rowHeight, columns, extraInfo, isActive, isHover
106
113
  },
107
114
  ], id: columnId, children: renderCell({ columnId, item, index, extraInfo, isHovered }) }, columnId))) }));
108
115
  };
109
- export const PlainListView = ({ data: originalData, keyExtractor, rowHeight, groupHeaderHeight, headerHeight, columns, smallColumns = columns, extraInfo, onEndReached, onEndReachedThresholdPx = 200, headerStyle, rowStyle, getRowLink, activeRowId, renderEmptyList, onActiveRowChange, groupBy, loading, breakpoint = breakpoints.large, withoutScroll = false, stickyOffset = 0, }) => {
116
+ export const PlainListView = ({ data: originalData, keyExtractor, rowHeight, groupHeaderHeight, headerHeight, columns, smallColumns = columns, extraInfo, onEndReached, onEndReachedThresholdPx = 200, headerStyle, rowStyle, getRowLink, activeRowId, renderEmptyList, onActiveRowChange, groupBy, loading, breakpoint = breakpoints.large, withoutScroll = false, stickyOffset = 0, headerBackgroundColor = backgroundColor.default, }) => {
110
117
  const viewId = useId();
111
118
  const scrollTrackerRef = useRef(null);
112
119
  const groups = useMemo(() => {
@@ -165,22 +172,31 @@ export const PlainListView = ({ data: originalData, keyExtractor, rowHeight, gro
165
172
  ] })), [isLoading, loading?.count, rowHeight, totalHeight, withoutScroll]);
166
173
  return (_jsx(ResponsiveContainer, { style: withoutScroll ? (isEmpty ? commonStyles.fill : undefined) : styles.root, breakpoint: breakpoint, children: ({ large }) => {
167
174
  const displayColumns = large ? columns : smallColumns;
168
- return (_jsxs(_Fragment, { children: [!isEmpty && large ? (_jsx(View, { style: [styles.segment, styles.segmentLarge, headerStyle], children: displayColumns.map(({ id, width, title, renderTitle }) => {
169
- const columnId = `${viewId}_${id}`;
170
- return (_jsx(View, { style: [
171
- styles.segmentHeaderCell,
172
- {
173
- width: typeof width === "number" ? width : ONE,
174
- flexGrow: width === "grow" ? ONE : ZERO,
175
- height: headerHeight,
176
- },
177
- ], id: columnId, children: renderTitle({ title, extraInfo, id }) }, columnId));
178
- }) })) : null, cloneElement(listWrapper, {
179
- children: (_jsxs(_Fragment, { children: [Array.from(groups.entries()).map(([groupName, items]) => {
175
+ return (_jsx(_Fragment, { children: cloneElement(listWrapper, {
176
+ children: (_jsxs(_Fragment, { children: [!isEmpty && large ? (_jsx(View, { style: [
177
+ styles.segment,
178
+ styles.segmentLarge,
179
+ styles.header,
180
+ headerStyle,
181
+ { backgroundColor: headerBackgroundColor },
182
+ ], children: displayColumns.map(({ id, width, title, renderTitle }) => {
183
+ const columnId = `${viewId}_${id}`;
184
+ return (_jsx(View, { style: [
185
+ styles.segmentHeaderCell,
186
+ {
187
+ width: typeof width === "number" ? width : ONE,
188
+ flexGrow: width === "grow" ? ONE : ZERO,
189
+ height: headerHeight,
190
+ },
191
+ ], id: columnId, children: renderTitle({ title, extraInfo, id }) }, columnId));
192
+ }) })) : null, _jsx(View, { children: Array.from(groups.entries()).map(([groupName, items]) => {
180
193
  return (_jsxs(Fragment, { children: [groupName != null ? (_jsx(View, { style: [
181
194
  styles.stickyHeader,
182
195
  large && styles.stickyHeaderLarge,
183
- { height: groupHeaderHeight, top: stickyOffset },
196
+ {
197
+ height: groupHeaderHeight,
198
+ top: stickyOffset + groupHeaderHeight,
199
+ },
184
200
  ], children: _jsx(LakeHeading, { level: 3, variant: "h3", children: groupName }) })) : null, items.map((item, index) => {
185
201
  const key = keyExtractor(item, index);
186
202
  const isActive = activeRowId === key;
@@ -197,7 +213,7 @@ export const PlainListView = ({ data: originalData, keyExtractor, rowHeight, gro
197
213
  children: (_jsx(Row, { id: key, rowHeight: rowHeight, columns: displayColumns, item: item, index: index, extraInfo: extraInfo, isActive: isActive, isHovered: isHovered, large: large, style: rowStyle, onMouseEnter: setHoveredRow, onMouseLeave: removeHoveredRow })),
198
214
  });
199
215
  })] }, groupName));
200
- }), _jsx(View, { children: _jsx(View, { "aria-busy": isLoading, style: styles.loadingPlaceholder, children: isLoading ? (_jsx(PlainListViewPlaceholder, { count: loading.count, rowHeight: rowHeight, rowVerticalSpacing: 0, paddingHorizontal: 0 })) : null }) }), isEmpty && isNotNullish(renderEmptyList) && !isLoading ? (_jsx(View, { style: styles.emptyListContainer, children: renderEmptyList() })) : null, _jsx(View, { style: [styles.scrollTracker, { height: onEndReachedThresholdPx }], ref: scrollTrackerRef })] })),
201
- })] }));
216
+ }) }), _jsx(View, { children: _jsx(View, { "aria-busy": isLoading, style: styles.loadingPlaceholder, children: isLoading ? (_jsx(PlainListViewPlaceholder, { count: loading.count, rowHeight: rowHeight, rowVerticalSpacing: 0, paddingHorizontal: 0 })) : null }) }), isEmpty && isNotNullish(renderEmptyList) && !isLoading ? (_jsx(View, { style: styles.emptyListContainer, children: renderEmptyList() })) : null, _jsx(View, { style: [styles.scrollTracker, { height: onEndReachedThresholdPx }], ref: scrollTrackerRef })] })),
217
+ }) }));
202
218
  } }));
203
219
  };
@@ -1,5 +1,5 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { useEffect, useRef, useState } from "react";
2
+ import { useCallback, useEffect, useRef, useState } from "react";
3
3
  import { StyleSheet, View } from "react-native";
4
4
  import { colors } from "../constants/design";
5
5
  import { Box } from "./Box";
@@ -47,16 +47,17 @@ export const Toggle = ({ onToggle, value, disabled = false, mode = "desktop", on
47
47
  const isMobile = mode === "mobile";
48
48
  const onColor = value ? colors.positive[500] : colors.gray[500];
49
49
  const offColor = !value ? colors.negative[500] : colors.gray[500];
50
- useEffect(() => {
50
+ const reajustLayout = useCallback(() => {
51
51
  (value ? onItemRef : offItemRef).current?.measureLayout(containerRef.current, (left, _, width) => {
52
52
  setHandleStyle(prev => ({
53
53
  transitionProperty: prev ? "width, transform" : "none",
54
54
  width: width + 2 * BORDER_WIDTH,
55
- transform: `translateX(${value ? -BORDER_WIDTH : left - (isMobile ? 2 * BORDER_WIDTH : 0)}px)`,
55
+ transform: `translateX(${value ? -BORDER_WIDTH : left - 2 * BORDER_WIDTH}px)`,
56
56
  }));
57
57
  }, () => { });
58
- }, [value, isMobile, onLabel, offLabel]);
59
- return (_jsxs(Pressable, { style: [styles.switch, disabled && styles.disabled], onPress: () => onToggle(!value), "aria-disabled": disabled, "aria-checked": value, disabled: disabled, ref: containerRef, role: "switch", children: [_jsx(View, { style: [
58
+ }, [value]);
59
+ useEffect(reajustLayout, [reajustLayout, value, isMobile, onLabel, offLabel]);
60
+ return (_jsxs(Pressable, { style: [styles.switch, disabled && styles.disabled], onPress: () => onToggle(!value), "aria-disabled": disabled, "aria-checked": value, disabled: disabled, ref: containerRef, role: "switch", onLayout: reajustLayout, children: [_jsx(View, { style: [
60
61
  styles.handle,
61
62
  handleStyle,
62
63
  {
@@ -0,0 +1,22 @@
1
+ import { Result } from "@swan-io/boxed";
2
+ import { Except, SetRequired } from "type-fest";
3
+ import { AnyVariables, OperationResult, UseQueryArgs, UseQueryResponse, UseQueryState } from "urql";
4
+ export declare const parseOperationResult: <T>({ error, data }: OperationResult<T, AnyVariables>) => T;
5
+ export declare const useQueryWithErrorBoundary: <Data = unknown, Variables extends AnyVariables = AnyVariables>(options: UseQueryArgs<Variables, Data>) => [{
6
+ stale: boolean;
7
+ extensions?: Record<string, any> | undefined;
8
+ operation?: import("@urql/core/dist/urql-core-chunk").Operation<Data, Variables> | undefined;
9
+ data: Data;
10
+ }, import("urql").UseQueryExecute];
11
+ export declare const filterRejectionsToPromise: <T extends {
12
+ __typename: string;
13
+ }>(input: T) => Promise<Exclude<T, {
14
+ __typename: `${string}Rejection`;
15
+ }>>;
16
+ export declare const filterRejectionsToResult: <T extends {
17
+ __typename: string;
18
+ }>(input: T) => Result<Exclude<T, {
19
+ __typename: `${string}Rejection`;
20
+ }>, Extract<T, {
21
+ __typename: `${string}Rejection`;
22
+ }>>;
@@ -0,0 +1,30 @@
1
+ import { Result } from "@swan-io/boxed";
2
+ import { CombinedError, useQuery, } from "urql";
3
+ import { isNotNullish, isNullish } from "./nullish";
4
+ export const parseOperationResult = ({ error, data }) => {
5
+ if (isNotNullish(error)) {
6
+ throw error;
7
+ }
8
+ if (isNullish(data)) {
9
+ throw new CombinedError({
10
+ networkError: new Error("No Content"),
11
+ });
12
+ }
13
+ return data;
14
+ };
15
+ export const useQueryWithErrorBoundary = (options) => {
16
+ const [{ fetching, data, error, ...rest }, reexecuteQuery] = useQuery(options);
17
+ if (isNotNullish(error)) {
18
+ throw error;
19
+ }
20
+ if (isNullish(data)) {
21
+ throw new CombinedError({
22
+ networkError: new Error("No Content"),
23
+ });
24
+ }
25
+ return [{ data, ...rest }, reexecuteQuery];
26
+ };
27
+ export const filterRejectionsToPromise = (input) => (input.__typename.endsWith("Rejection")
28
+ ? Promise.reject(new Error(input.__typename))
29
+ : Promise.resolve(input));
30
+ export const filterRejectionsToResult = (input) => (input.__typename.endsWith("Rejection") ? Result.Error(input) : Result.Ok(input));