@swan-io/lake 2.7.35 → 2.7.37
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 +1 -1
- package/src/components/ChoicePicker.d.ts +2 -1
- package/src/components/ChoicePicker.js +5 -3
- package/src/components/LakeButton.js +2 -5
- package/src/components/LakeSlider.d.ts +2 -1
- package/src/components/LakeSlider.js +6 -2
- package/src/components/PlainListView.d.ts +2 -1
- package/src/components/PlainListView.js +32 -16
- package/src/components/Toggle.js +2 -4
- package/src/constants/commonStyles.d.ts +4 -0
- package/src/constants/commonStyles.js +1 -0
- package/src/utils/urql.d.ts +22 -0
- package/src/utils/urql.js +30 -0
package/package.json
CHANGED
|
@@ -6,6 +6,7 @@ type Props<T> = {
|
|
|
6
6
|
value?: T;
|
|
7
7
|
getId?: (item: T) => unknown;
|
|
8
8
|
onChange: (value: T) => void;
|
|
9
|
+
disabled?: boolean;
|
|
9
10
|
};
|
|
10
|
-
export declare const ChoicePicker: <T>({ items, getId, large, renderItem, value, onChange, }: Props<T>) => import("react/jsx-runtime").JSX.Element;
|
|
11
|
+
export declare const ChoicePicker: <T>({ items, getId, large, renderItem, value, disabled, onChange, }: Props<T>) => import("react/jsx-runtime").JSX.Element;
|
|
11
12
|
export {};
|
|
@@ -2,6 +2,7 @@ import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-run
|
|
|
2
2
|
import { useEffect, useRef, useState } from "react";
|
|
3
3
|
import { ScrollView, StyleSheet, View } from "react-native";
|
|
4
4
|
import { match } from "ts-pattern";
|
|
5
|
+
import { commonStyles } from "../constants/commonStyles";
|
|
5
6
|
import { breakpoints, negativeSpacings, spacings } from "../constants/design";
|
|
6
7
|
import { useResponsive } from "../hooks/useResponsive";
|
|
7
8
|
import { clampValue } from "../utils/math";
|
|
@@ -100,7 +101,7 @@ const styles = StyleSheet.create({
|
|
|
100
101
|
},
|
|
101
102
|
});
|
|
102
103
|
const identity = (x) => x;
|
|
103
|
-
export const ChoicePicker = ({ items, getId = identity, large = false, renderItem, value, onChange, }) => {
|
|
104
|
+
export const ChoicePicker = ({ items, getId = identity, large = false, renderItem, value, disabled = false, onChange, }) => {
|
|
104
105
|
const containerRef = useRef(null);
|
|
105
106
|
const { desktop } = useResponsive(breakpoints.medium);
|
|
106
107
|
const [mobilePosition, setMobilePosition] = useState("start");
|
|
@@ -179,12 +180,13 @@ export const ChoicePicker = ({ items, getId = identity, large = false, renderIte
|
|
|
179
180
|
styles.container,
|
|
180
181
|
!desktop && styles.mobileContainer,
|
|
181
182
|
!desktop && { width: `${items.length * 100}%` },
|
|
182
|
-
], children: items.map((item, index) => (_jsx(Pressable, { style: [
|
|
183
|
+
], children: items.map((item, index) => (_jsx(Pressable, { disabled: disabled, style: [
|
|
183
184
|
styles.item,
|
|
185
|
+
disabled && commonStyles.disabled,
|
|
184
186
|
desktop && styles.itemAnimation,
|
|
185
187
|
desktop && { animationDelay: `${200 + 100 * index}ms` },
|
|
186
188
|
large && styles.itemLarge,
|
|
187
189
|
!desktop && styles.itemSmallViewport,
|
|
188
190
|
!desktop && { width: `${100 / items.length}%` },
|
|
189
|
-
], onPress: () => onChange(item), children: ({ hovered }) => (_jsx(Tile, { hovered: hovered, selected: value != null && getId(item) === getId(value), flexGrow: 1, children: _jsxs(View, { style: styles.tileContents, children: [_jsx(View, { style: styles.tileRenderedContents, children: renderItem(item) }), desktop && (_jsxs(_Fragment, { children: [_jsx(Space, { height: 24 }), _jsx(LakeRadio, { value: value != null && getId(item) === getId(value) })] }))] }) })) }, String(index)))) }) }), !desktop && (_jsx(LakeButton, { icon: "chevron-left-filled", mode: "secondary", forceBackground: true, onPress: onPressPrevious, disabled: mobilePosition === "start", style: styles.leftButton })), !desktop && (_jsx(LakeButton, { icon: "chevron-right-filled", mode: "secondary", forceBackground: true, onPress: onPressNext, disabled: mobilePosition === "end", style: styles.rightButton }))] }));
|
|
191
|
+
], onPress: () => onChange(item), children: ({ hovered }) => (_jsx(Tile, { hovered: hovered, selected: value != null && getId(item) === getId(value), flexGrow: 1, children: _jsxs(View, { style: styles.tileContents, children: [_jsx(View, { style: styles.tileRenderedContents, children: renderItem(item) }), desktop && (_jsxs(_Fragment, { children: [_jsx(Space, { height: 24 }), _jsx(LakeRadio, { value: value != null && getId(item) === getId(value) })] }))] }) })) }, String(index)))) }) }), !desktop && (_jsx(LakeButton, { icon: "chevron-left-filled", mode: "secondary", forceBackground: true, onPress: onPressPrevious, disabled: mobilePosition === "start" || disabled, style: styles.leftButton })), !desktop && (_jsx(LakeButton, { icon: "chevron-right-filled", mode: "secondary", forceBackground: true, onPress: onPressNext, disabled: mobilePosition === "end" || disabled, style: styles.rightButton }))] }));
|
|
190
192
|
};
|
|
@@ -2,6 +2,7 @@ import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-run
|
|
|
2
2
|
import { Children, forwardRef, Fragment, memo } from "react";
|
|
3
3
|
import { ActivityIndicator, StyleSheet, View, } from "react-native";
|
|
4
4
|
import { match } from "ts-pattern";
|
|
5
|
+
import { commonStyles } from "../constants/commonStyles";
|
|
5
6
|
import { backgroundColor, colors, invariantColors, radii, spacings, texts, } from "../constants/design";
|
|
6
7
|
import { isNotNullish, isNullish } from "../utils/nullish";
|
|
7
8
|
import { Icon } from "./Icon";
|
|
@@ -72,10 +73,6 @@ const styles = StyleSheet.create({
|
|
|
72
73
|
},
|
|
73
74
|
text: texts.semibold,
|
|
74
75
|
textSmall: texts.smallSemibold,
|
|
75
|
-
disabled: {
|
|
76
|
-
cursor: "not-allowed",
|
|
77
|
-
opacity: 0.3,
|
|
78
|
-
},
|
|
79
76
|
resetOpacity: {
|
|
80
77
|
opacity: 1,
|
|
81
78
|
},
|
|
@@ -116,7 +113,7 @@ export const LakeButton = memo(forwardRef(({ ariaControls, ariaExpanded, ariaLab
|
|
|
116
113
|
hasIconStart && isSmall ? styles.withIconStartSmall : styles.withIconStart,
|
|
117
114
|
hasIconEnd && (isSmall ? styles.withIconEndSmall : styles.withIconEnd),
|
|
118
115
|
hasOnlyIcon && (isSmall ? styles.iconSmallOnly : styles.iconOnly),
|
|
119
|
-
disabled &&
|
|
116
|
+
disabled && commonStyles.disabled,
|
|
120
117
|
disabled && forceBackground && styles.resetOpacity,
|
|
121
118
|
grow && styles.grow,
|
|
122
119
|
match(mode)
|
|
@@ -5,7 +5,8 @@ export type SliderProps = {
|
|
|
5
5
|
max: number;
|
|
6
6
|
step: number;
|
|
7
7
|
unit: string;
|
|
8
|
+
disabled?: boolean;
|
|
8
9
|
onChange: (value: number) => void;
|
|
9
10
|
};
|
|
10
11
|
export declare const sliderBreakpoint: number;
|
|
11
|
-
export declare const LakeSlider: ({ label, value, min, max, step, unit, onChange }: SliderProps) => import("react/jsx-runtime").JSX.Element;
|
|
12
|
+
export declare const LakeSlider: ({ label, value, min, max, step, unit, disabled, onChange, }: SliderProps) => import("react/jsx-runtime").JSX.Element;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { useCallback, useEffect, useState } from "react";
|
|
3
3
|
import { StyleSheet, View } from "react-native";
|
|
4
|
+
import { commonStyles } from "../constants/commonStyles";
|
|
4
5
|
import { breakpoints } from "../constants/design";
|
|
5
6
|
import { Box } from "./Box";
|
|
6
7
|
import { LakeLabel } from "./LakeLabel";
|
|
@@ -17,7 +18,7 @@ const styles = StyleSheet.create({
|
|
|
17
18
|
},
|
|
18
19
|
});
|
|
19
20
|
export const sliderBreakpoint = breakpoints.tiny;
|
|
20
|
-
export const LakeSlider = ({ label, value, min, max, step, unit, onChange }) => {
|
|
21
|
+
export const LakeSlider = ({ label, value, min, max, step, unit, disabled = false, onChange, }) => {
|
|
21
22
|
const [dirtyValue, setDirtyValue] = useState(String(value));
|
|
22
23
|
useEffect(() => {
|
|
23
24
|
setDirtyValue(String(value));
|
|
@@ -27,5 +28,8 @@ export const LakeSlider = ({ label, value, min, max, step, unit, onChange }) =>
|
|
|
27
28
|
setDirtyValue(String(cleanValue));
|
|
28
29
|
onChange(cleanValue);
|
|
29
30
|
}, [min, max, dirtyValue, onChange]);
|
|
30
|
-
return (_jsx(ResponsiveContainer, { breakpoint: sliderBreakpoint, style: styles.container, children: ({ large }) => (_jsx(_Fragment, { children: large ? (_jsxs(_Fragment, { children: [_jsx(Box, { direction: "row", justifyContent: "end", children: _jsx(View, { children: _jsx(LakeTextInput, { style: styles.input, unit: unit, value: dirtyValue, onChangeText: setDirtyValue, onBlur: sanitizeInput, inputMode: "decimal" }) }) }), _jsx("input", { type: "range", min: min, max: max, step: step, value: value, onChange: event => onChange(Number(event.target.value)), style: {
|
|
31
|
+
return (_jsx(ResponsiveContainer, { breakpoint: sliderBreakpoint, style: styles.container, children: ({ large }) => (_jsx(_Fragment, { children: large ? (_jsxs(_Fragment, { children: [_jsx(Box, { direction: "row", justifyContent: "end", children: _jsx(View, { children: _jsx(LakeTextInput, { style: styles.input, unit: unit, value: dirtyValue, onChangeText: setDirtyValue, onBlur: sanitizeInput, inputMode: "decimal", disabled: disabled }) }) }), _jsx("input", { type: "range", min: min, max: max, step: step, value: value, disabled: disabled, onChange: event => onChange(Number(event.target.value)), style: {
|
|
32
|
+
backgroundSize: `${((value - min) / (max - min)) * 100}% 100%`,
|
|
33
|
+
...(disabled ? commonStyles.disabled : {}),
|
|
34
|
+
} })] })) : (_jsx(LakeLabel, { label: label, render: id => (_jsx(LakeTextInput, { id: id, unit: unit, value: dirtyValue, onChangeText: setDirtyValue, onBlur: sanitizeInput, inputMode: "decimal", disabled: disabled })) })) })) }));
|
|
31
35
|
};
|
|
@@ -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 (
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
styles.
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
}
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
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
|
-
{
|
|
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
|
};
|
package/src/components/Toggle.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { useCallback, useEffect, useRef, useState } from "react";
|
|
3
3
|
import { StyleSheet, View } from "react-native";
|
|
4
|
+
import { commonStyles } from "../constants/commonStyles";
|
|
4
5
|
import { colors } from "../constants/design";
|
|
5
6
|
import { Box } from "./Box";
|
|
6
7
|
import { Icon } from "./Icon";
|
|
@@ -9,9 +10,6 @@ import { Pressable } from "./Pressable";
|
|
|
9
10
|
const HEIGHT = 26;
|
|
10
11
|
const BORDER_WIDTH = 1;
|
|
11
12
|
const styles = StyleSheet.create({
|
|
12
|
-
disabled: {
|
|
13
|
-
opacity: 0.3,
|
|
14
|
-
},
|
|
15
13
|
switch: {
|
|
16
14
|
userSelect: "none",
|
|
17
15
|
flexDirection: "row",
|
|
@@ -57,7 +55,7 @@ export const Toggle = ({ onToggle, value, disabled = false, mode = "desktop", on
|
|
|
57
55
|
}, () => { });
|
|
58
56
|
}, [value]);
|
|
59
57
|
useEffect(reajustLayout, [reajustLayout, value, isMobile, onLabel, offLabel]);
|
|
60
|
-
return (_jsxs(Pressable, { style: [styles.switch, disabled &&
|
|
58
|
+
return (_jsxs(Pressable, { style: [styles.switch, disabled && commonStyles.disabled], onPress: () => onToggle(!value), "aria-disabled": disabled, "aria-checked": value, disabled: disabled, ref: containerRef, role: "switch", onLayout: reajustLayout, children: [_jsx(View, { style: [
|
|
61
59
|
styles.handle,
|
|
62
60
|
handleStyle,
|
|
63
61
|
{
|
|
@@ -32,6 +32,10 @@ export declare const commonStyles: {
|
|
|
32
32
|
readonly hidden: {
|
|
33
33
|
readonly visibility: "hidden";
|
|
34
34
|
};
|
|
35
|
+
readonly disabled: {
|
|
36
|
+
readonly cursor: "not-allowed";
|
|
37
|
+
readonly opacity: 0.5;
|
|
38
|
+
};
|
|
35
39
|
readonly view: {
|
|
36
40
|
readonly alignItems: "stretch";
|
|
37
41
|
readonly backgroundColor: "transparent";
|
|
@@ -41,6 +41,7 @@ export const commonStyles = {
|
|
|
41
41
|
fill: { flexGrow: 1, flexShrink: 1 },
|
|
42
42
|
fillNoShrink: { flexGrow: 1, flexShrink: 0 },
|
|
43
43
|
hidden: { visibility: "hidden" },
|
|
44
|
+
disabled: { cursor: "not-allowed", opacity: 0.5 },
|
|
44
45
|
view: viewStyle,
|
|
45
46
|
visuallyHidden: visuallyHiddenStyle,
|
|
46
47
|
};
|
|
@@ -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));
|