@swan-io/lake 11.1.3 → 11.1.5

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,9 +1,9 @@
1
1
  {
2
2
  "name": "@swan-io/lake",
3
- "version": "11.1.3",
3
+ "version": "11.1.5",
4
4
  "engines": {
5
5
  "node": ">=20.9.0",
6
- "pnpm": "9.9.0"
6
+ "pnpm": "^9.13.0"
7
7
  },
8
8
  "files": [
9
9
  "LICENSE",
@@ -1,67 +1,134 @@
1
1
  import { ComponentProps, ReactNode } from "react";
2
+ import { StyleProp, ViewStyle } from "react-native";
3
+ import { Except } from "type-fest";
2
4
  import { ColorVariants } from "../constants/design";
3
5
  import { TextVariant } from "./LakeText";
4
6
  import { LakeTooltip } from "./LakeTooltip";
5
- type Justify = "flex-start" | "center" | "flex-end";
7
+ declare const directionStyles: {
8
+ column: {
9
+ flexDirection: "column";
10
+ };
11
+ row: {
12
+ flexDirection: "row";
13
+ };
14
+ };
15
+ type Align = "left" | "center" | "right";
16
+ type FadeOn = "left" | "right";
6
17
  type SortDirection = "Desc" | "Asc";
7
- export declare const SimpleHeaderCell: ({ text, sort, justifyContent, onPress, }: {
8
- text: string;
9
- justifyContent?: Justify;
18
+ type TooltipProp = Except<ComponentProps<typeof LakeTooltip>, "children">;
19
+ type CellProps = {
20
+ children: ReactNode;
21
+ align?: Align;
22
+ direction?: keyof typeof directionStyles;
23
+ fadeOn?: FadeOn;
24
+ style?: StyleProp<ViewStyle>;
25
+ contentContainerStyle?: StyleProp<ViewStyle>;
26
+ };
27
+ export declare const Cell: ({ children, align, direction, fadeOn, style, contentContainerStyle, }: CellProps) => import("react/jsx-runtime").JSX.Element;
28
+ type HeaderCellProps = {
29
+ align?: Align;
10
30
  sort?: SortDirection;
11
- onPress?: (direction: SortDirection) => void;
12
- }) => import("react/jsx-runtime").JSX.Element;
13
- export declare const ColorPatchCell: ({ isHovered, alternativeText, color, }: {
14
- isHovered: boolean;
15
- alternativeText?: string;
16
- color: ColorVariants;
17
- }) => import("react/jsx-runtime").JSX.Element | null;
18
- export declare const SimpleTitleCell: ({ isHighlighted, text, tooltip, }: {
19
- isHighlighted?: boolean;
20
31
  text: string;
21
- tooltip?: Omit<ComponentProps<typeof LakeTooltip>, "children">;
22
- }) => import("react/jsx-runtime").JSX.Element;
23
- export declare const SimpleRegularTextCell: ({ variant, text, textAlign, color, }: {
24
- variant?: TextVariant;
25
- text: string;
26
- textAlign?: "left" | "center" | "right";
32
+ onPress?: (direction: SortDirection) => void;
33
+ };
34
+ export declare const HeaderCell: ({ align, sort, text, onPress }: HeaderCellProps) => import("react/jsx-runtime").JSX.Element;
35
+ type TextCellProps = {
36
+ align?: Align;
27
37
  color?: string;
28
- }) => import("react/jsx-runtime").JSX.Element;
29
- export declare const CopyableRegularTextCell: ({ variant, text, textToCopy, copyWording, copiedWording, tooltip, }: {
38
+ text: string;
39
+ tooltip?: TooltipProp;
30
40
  variant?: TextVariant;
41
+ };
42
+ export declare const TextCell: ({ align, color, text, tooltip, variant, }: TextCellProps) => import("react/jsx-runtime").JSX.Element;
43
+ type CopyableTextCellProps = {
44
+ copiedWording: string;
45
+ copyWording: string;
31
46
  text: string;
32
47
  textToCopy?: string;
33
- copyWording: string;
34
- copiedWording: string;
35
- tooltip?: Omit<ComponentProps<typeof LakeTooltip>, "children">;
36
- }) => import("react/jsx-runtime").JSX.Element;
37
- export declare const BalanceCell: ({ value, currency, originalValue, formatCurrency, textAlign, variant, }: {
38
- value: number;
48
+ tooltip?: TooltipProp;
49
+ variant?: TextVariant;
50
+ };
51
+ export declare const CopyableTextCell: ({ copiedWording, copyWording, text, textToCopy, tooltip, variant, }: CopyableTextCellProps) => import("react/jsx-runtime").JSX.Element;
52
+ type BalanceCellProps = {
53
+ align?: Align;
39
54
  currency: string;
55
+ formatCurrency: (value: number, currency: string) => string;
40
56
  originalValue?: {
41
57
  value: number;
42
58
  currency: string;
43
59
  };
44
- formatCurrency: (value: number, currency: string) => string;
45
- textAlign?: "left" | "center" | "right";
60
+ /**
61
+ * @deprecated Use `align` prop instead
62
+ */
63
+ textAlign?: Align;
64
+ value: number;
46
65
  variant?: TextVariant;
47
- }) => import("react/jsx-runtime").JSX.Element;
48
- export declare const LinkCell: ({ children, external, onPress, variant, tooltip, buttonPosition, }: {
66
+ };
67
+ export declare const BalanceCell: ({ textAlign, align, currency, formatCurrency, originalValue, value, variant, }: BalanceCellProps) => import("react/jsx-runtime").JSX.Element;
68
+ type LinkCellProps = {
69
+ buttonPosition?: "start" | "end";
49
70
  children: ReactNode;
50
- onPress: () => void;
51
71
  external?: boolean;
72
+ fadeOn?: FadeOn;
73
+ onPress: () => void;
74
+ tooltip?: TooltipProp;
52
75
  variant?: TextVariant;
53
- tooltip?: Omit<ComponentProps<typeof LakeTooltip>, "children">;
54
- buttonPosition?: "start" | "end";
55
- }) => import("react/jsx-runtime").JSX.Element;
56
- export declare const StartAlignedCell: ({ children }: {
57
- children: ReactNode;
76
+ };
77
+ export declare const LinkCell: ({ buttonPosition, children, external, fadeOn, onPress, tooltip, variant, }: LinkCellProps) => import("react/jsx-runtime").JSX.Element;
78
+ /**
79
+ * @deprecated Avoid usage
80
+ */
81
+ export declare const ColorPatchCell: ({ alternativeText, color, isHovered, }: {
82
+ alternativeText?: string;
83
+ color: ColorVariants;
84
+ isHovered: boolean;
85
+ }) => import("react/jsx-runtime").JSX.Element | null;
86
+ /**
87
+ * @deprecated Use `HeaderCell` instead
88
+ */
89
+ export declare const SimpleHeaderCell: ({ justifyContent, ...props }: {
90
+ justifyContent?: "flex-start" | "center" | "flex-end";
91
+ text: string;
92
+ sort?: SortDirection;
93
+ onPress?: (direction: SortDirection) => void;
58
94
  }) => import("react/jsx-runtime").JSX.Element;
59
- export declare const CenteredCell: ({ children }: {
60
- children: ReactNode;
95
+ /**
96
+ * @deprecated Use `TextCell` with color={…} and variant="medium" instead
97
+ */
98
+ export declare const SimpleTitleCell: ({ isHighlighted, text, tooltip, }: {
99
+ isHighlighted?: boolean;
100
+ text: string;
101
+ tooltip?: TooltipProp;
61
102
  }) => import("react/jsx-runtime").JSX.Element;
62
- export declare const EndAlignedCell: ({ children }: {
63
- children: ReactNode;
103
+ /**
104
+ * @deprecated Use `TextCell` instead
105
+ */
106
+ export declare const SimpleRegularTextCell: ({ color, text, textAlign, variant, }: {
107
+ color?: string;
108
+ text: string;
109
+ textAlign?: Align;
110
+ variant?: TextVariant;
64
111
  }) => import("react/jsx-runtime").JSX.Element;
112
+ /**
113
+ * @deprecated Use `CopyableTextCell` instead
114
+ */
115
+ export declare const CopyableRegularTextCell: ({ copiedWording, copyWording, text, textToCopy, tooltip, variant, }: CopyableTextCellProps) => import("react/jsx-runtime").JSX.Element;
116
+ /**
117
+ * @deprecated Use `<Cell align="left" />` instead
118
+ */
119
+ export declare const StartAlignedCell: (props: Except<CellProps, "align">) => import("react/jsx-runtime").JSX.Element;
120
+ /**
121
+ * @deprecated Use `<Cell align="center" />` instead
122
+ */
123
+ export declare const CenteredCell: (props: Except<CellProps, "align">) => import("react/jsx-runtime").JSX.Element;
124
+ /**
125
+ * @deprecated Use `<Cell align="right" />` instead
126
+ */
127
+ export declare const EndAlignedCell: (props: Except<CellProps, "align">) => import("react/jsx-runtime").JSX.Element;
128
+ export declare const ActionCell: ({ style, ...props }: CellProps) => import("react/jsx-runtime").JSX.Element;
129
+ /**
130
+ * @deprecated Use <ActionCell /> instead
131
+ */
65
132
  export declare const CellAction: ({ children }: {
66
133
  children: ReactNode;
67
134
  }) => import("react/jsx-runtime").JSX.Element;
@@ -3,8 +3,9 @@ import { useCallback, useState } from "react";
3
3
  import { StyleSheet, View } from "react-native";
4
4
  import { match } from "ts-pattern";
5
5
  import { visuallyHiddenStyle } from "../constants/commonStyles";
6
- import { colors, spacings } from "../constants/design";
6
+ import { colors, invariantColors, negativeSpacings, spacings, } from "../constants/design";
7
7
  import { setClipboardText } from "../utils/clipboard";
8
+ import { identity } from "../utils/function";
8
9
  import { isNotNullish, isNullish } from "../utils/nullish";
9
10
  import { Box } from "./Box";
10
11
  import { Icon } from "./Icon";
@@ -12,113 +13,116 @@ import { LakeText } from "./LakeText";
12
13
  import { LakeTooltip } from "./LakeTooltip";
13
14
  import { Pressable } from "./Pressable";
14
15
  import { Space } from "./Space";
16
+ /* eslint-disable react-native/no-unused-styles */
17
+ const directionStyles = StyleSheet.create({
18
+ column: { flexDirection: "column" },
19
+ row: { flexDirection: "row" },
20
+ });
21
+ const alignItemsStyles = StyleSheet.create({
22
+ left: { alignItems: "flex-start" },
23
+ center: { alignItems: "center" },
24
+ right: { alignItems: "flex-end" },
25
+ });
26
+ const justifyContentStyles = StyleSheet.create({
27
+ left: { justifyContent: "flex-start" },
28
+ center: { justifyContent: "center" },
29
+ right: { justifyContent: "flex-end" },
30
+ });
31
+ /* eslint-enable react-native/no-unused-styles */
32
+ const fadeOnLeftMask = `linear-gradient(to right, ${invariantColors.transparent}, ${invariantColors.black} ${spacings[16]})`;
33
+ const fadeOnRightMask = `linear-gradient(to left, ${invariantColors.transparent}, ${invariantColors.black} ${spacings[16]})`;
15
34
  const styles = StyleSheet.create({
16
- cellContainer: {
17
- display: "flex",
18
- flexGrow: 1,
19
- flexDirection: "row",
20
- alignItems: "center",
21
- },
22
- balanceCellContainer: {
23
- width: "100%",
24
- },
25
35
  cell: {
26
- display: "flex",
27
- paddingHorizontal: spacings[16],
28
- flexGrow: 1,
29
- flexDirection: "row",
30
- alignItems: "center",
31
- },
32
- disabledCellHeader: {
33
- cursor: "text",
34
- },
35
- icon: {
36
- alignSelf: "stretch",
37
- alignItems: "center",
38
- justifyContent: "center",
39
- paddingHorizontal: spacings[4],
40
- },
41
- iconContainer: {
42
36
  flexDirection: "row",
43
- alignSelf: "stretch",
44
- alignItems: "stretch",
45
- justifyContent: "center",
46
- },
47
- centeredCell: {
48
- justifyContent: "center",
49
- },
50
- endAlignedCell: {
51
- justifyContent: "flex-end",
52
- },
53
- regularText: {
54
- overflow: "hidden",
55
- textOverflow: "ellipsis",
56
- width: 1,
57
37
  flexGrow: 1,
58
- whiteSpace: "nowrap",
38
+ flexShrink: 1,
39
+ paddingHorizontal: spacings[16],
59
40
  },
60
- mediumText: {
61
- overflow: "hidden",
62
- textOverflow: "ellipsis",
63
- width: 1,
41
+ cellContentContainer: {
64
42
  flexGrow: 1,
65
- whiteSpace: "nowrap",
66
- flexDirection: "row",
67
- alignItems: "center",
43
+ flexShrink: 1,
44
+ overflow: "hidden",
68
45
  },
69
- colorPatch: {
70
- flexGrow: 1,
46
+ fadeOnLeft: {
47
+ maskImage: fadeOnLeftMask,
48
+ WebkitMaskImage: fadeOnLeftMask,
49
+ },
50
+ fadeOnRight: {
51
+ maskImage: fadeOnRightMask,
52
+ WebkitMaskImage: fadeOnRightMask,
53
+ },
54
+ noCursor: {
55
+ cursor: "text",
71
56
  },
72
- alternativeText: visuallyHiddenStyle,
73
57
  sortIcon: {
74
58
  transitionProperty: "transform",
75
59
  transitionDuration: "300ms",
76
60
  transitionTimingFunction: "ease-in-out",
77
61
  },
78
- sortIconReversed: {
62
+ rotated: {
79
63
  transform: "rotate(-180deg)",
80
64
  },
81
- cellAction: {
82
- paddingVertical: spacings[16],
83
- paddingHorizontal: spacings[8],
84
- },
85
- underline: {
86
- boxShadow: "inset 0 -2px currentColor",
87
- },
88
- sortHorizontalBar: {
65
+ headerUnderline: {
66
+ backgroundColor: colors.gray[900],
67
+ borderBottomColor: colors.current[500],
68
+ bottom: -10,
69
+ height: 2,
89
70
  position: "absolute",
90
71
  width: "100%",
91
- height: 2,
92
- bottom: -10,
72
+ },
73
+ headerUnderlineActive: {
93
74
  backgroundColor: colors.current[500],
94
- borderBottomColor: colors.current[500],
75
+ },
76
+ buttonUnderline: {
77
+ boxShadow: "inset 0 -2px currentColor",
78
+ },
79
+ copyButton: {
80
+ justifyContent: "center",
81
+ alignSelf: "stretch",
82
+ marginHorizontal: negativeSpacings[8],
83
+ },
84
+ copyButtonTooltip: {
85
+ justifyContent: "center",
86
+ height: "100%",
87
+ paddingHorizontal: spacings[8],
88
+ },
89
+ linkButton: {
90
+ justifyContent: "center",
91
+ alignSelf: "stretch",
92
+ marginHorizontal: negativeSpacings[8],
93
+ paddingHorizontal: spacings[8],
94
+ },
95
+ actionCell: {
96
+ paddingVertical: spacings[16],
97
+ paddingHorizontal: spacings[8],
95
98
  },
96
99
  });
97
- export const SimpleHeaderCell = ({ text, sort, justifyContent = "flex-start", onPress, }) => {
100
+ export const Cell = ({ children, align = "left", direction = "row", fadeOn, style, contentContainerStyle, }) => (_jsx(View, { style: [styles.cell, style], children: _jsx(View, { style: [
101
+ styles.cellContentContainer,
102
+ directionStyles[direction],
103
+ alignItemsStyles[direction === "row" ? "center" : align],
104
+ justifyContentStyles[direction === "row" ? align : "center"],
105
+ fadeOn === "left" && styles.fadeOnLeft,
106
+ fadeOn === "right" && styles.fadeOnRight,
107
+ contentContainerStyle,
108
+ ], children: children }) }));
109
+ export const HeaderCell = ({ align = "left", sort, text, onPress }) => {
98
110
  const sortActive = isNotNullish(sort) && isNotNullish(onPress);
99
111
  const disabled = isNullish(onPress);
100
- return (_jsx(Pressable, { onPress: () => {
112
+ return (_jsx(Pressable, { role: "columnheader", disabled: disabled, style: [styles.cell, disabled && styles.noCursor], onPress: () => {
101
113
  onPress === null || onPress === void 0 ? void 0 : onPress(match(sort)
102
114
  .returnType()
103
115
  .with("Desc", () => "Asc")
104
- .with("Asc", () => "Desc")
105
116
  .otherwise(() => "Desc"));
106
- }, disabled: disabled, style: [styles.cellContainer, disabled && styles.disabledCellHeader], role: "columnheader", children: ({ hovered }) => (_jsx(View, { style: [styles.cell, { justifyContent }], children: _jsxs(View, { children: [_jsxs(Box, { direction: "row", alignItems: "center", children: [_jsx(LakeText, { numberOfLines: 1, variant: "medium", color: sortActive ? colors.current[500] : colors.gray[900], style: {
107
- textAlign: match(justifyContent)
108
- .with("flex-start", () => "left")
109
- .with("center", () => "center")
110
- .with("flex-end", () => "right")
111
- .exhaustive(),
112
- }, children: text }), isNotNullish(onPress) ? (_jsxs(_Fragment, { children: [_jsx(Space, { width: 8 }), _jsx(Box, { style: [styles.sortIcon, sort === "Asc" && styles.sortIconReversed], children: _jsx(Icon, { size: 15, color: sortActive ? colors.current[500] : colors.gray[500], name: sortActive ? "arrow-down-filled" : "chevron-up-down-regular" }) })] })) : null] }), sortActive ? (_jsx(View, { style: styles.sortHorizontalBar })) : hovered ? (_jsx(View, { style: [styles.sortHorizontalBar, { backgroundColor: colors.gray[900] }] })) : null] }) })) }));
113
- };
114
- export const ColorPatchCell = ({ isHovered, alternativeText, color, }) => {
115
- return isHovered ? (_jsx(View, { style: [styles.colorPatch, { backgroundColor: colors[color].primary }], children: isNotNullish(alternativeText) ? (_jsx(LakeText, { style: styles.alternativeText, children: alternativeText })) : null })) : null;
116
- };
117
- export const SimpleTitleCell = ({ isHighlighted = false, text, tooltip, }) => (_jsx(View, { style: styles.cell, children: _jsx(LakeText, { numberOfLines: 1, color: isHighlighted ? colors.current.primary : colors.gray[900], style: styles.regularText, variant: "medium", tooltip: tooltip, children: text }) }));
118
- export const SimpleRegularTextCell = ({ variant = "regular", text, textAlign = "left", color = colors.gray[900], }) => {
119
- return (_jsx(View, { style: styles.cell, children: _jsx(LakeText, { align: textAlign, color: color, style: styles.regularText, variant: variant, children: text }) }));
117
+ }, children: ({ hovered }) => (_jsxs(View, { style: [
118
+ styles.cellContentContainer,
119
+ directionStyles["row"],
120
+ alignItemsStyles["center"],
121
+ justifyContentStyles[align],
122
+ ], children: [_jsx(LakeText, { numberOfLines: 1, align: align, color: sortActive ? colors.current[500] : colors.gray[900], variant: "medium", children: text }), isNotNullish(onPress) && (_jsxs(_Fragment, { children: [_jsx(Space, { width: 8 }), _jsx(Icon, { size: 15, color: sortActive ? colors.current[500] : colors.gray[500], name: sortActive ? "arrow-down-filled" : "chevron-up-down-regular", style: [styles.sortIcon, sort === "Asc" && styles.rotated] })] })), (hovered || sortActive) && (_jsx(View, { style: [styles.headerUnderline, sortActive && styles.headerUnderlineActive] }))] })) }));
120
123
  };
121
- export const CopyableRegularTextCell = ({ variant = "regular", text, textToCopy, copyWording, copiedWording, tooltip, }) => {
124
+ export const TextCell = ({ align = "left", color = colors.gray[900], text, tooltip, variant = "regular", }) => (_jsx(Cell, { align: align, children: _jsx(LakeText, { numberOfLines: 1, align: align, color: color, tooltip: tooltip, variant: variant, children: text }) }));
125
+ export const CopyableTextCell = ({ copiedWording, copyWording, text, textToCopy, tooltip, variant = "regular", }) => {
122
126
  const [visibleState, setVisibleState] = useState("copy");
123
127
  const clipboardText = textToCopy !== null && textToCopy !== void 0 ? textToCopy : text;
124
128
  const onPress = useCallback((event) => {
@@ -126,39 +130,68 @@ export const CopyableRegularTextCell = ({ variant = "regular", text, textToCopy,
126
130
  setClipboardText(clipboardText);
127
131
  setVisibleState("copied");
128
132
  }, [clipboardText]);
129
- return (_jsxs(View, { style: styles.cell, children: [_jsx(LakeTooltip, { placement: "right", onHide: () => setVisibleState("copy"), togglableOnFocus: true, content: visibleState === "copy" ? copyWording : copiedWording, containerStyle: styles.iconContainer, children: _jsx(Pressable, { role: "button", "aria-label": copyWording, onPress: onPress, style: ({ hovered }) => [styles.icon, hovered && styles.underline], children: ({ hovered }) => (_jsx(Icon, { name: hovered ? "copy-filled" : "copy-regular", color: "currentColor", size: 14 })) }) }), _jsx(Space, { width: 4 }), _jsx(LakeText, { tooltip: tooltip, color: colors.gray[900], style: styles.regularText, variant: variant, children: text })] }));
133
+ return (_jsxs(Cell, { children: [_jsx(Pressable, { "aria-label": copyWording, role: "button", onPress: onPress, style: ({ hovered }) => [styles.copyButton, hovered && styles.buttonUnderline], children: ({ hovered }) => (_jsx(LakeTooltip, { content: visibleState === "copy" ? copyWording : copiedWording, onHide: () => setVisibleState("copy"), placement: "center", togglableOnFocus: true, containerStyle: styles.copyButtonTooltip, children: _jsx(Icon, { name: hovered ? "copy-filled" : "copy-regular", color: "currentColor", size: 14 }) })) }), _jsx(Space, { width: 8 }), _jsx(LakeText, { numberOfLines: 1, color: colors.gray[900], tooltip: tooltip, variant: variant, children: text })] }));
130
134
  };
131
135
  // TODO: handle `+` sign properly
132
- export const BalanceCell = ({ value, currency, originalValue, formatCurrency, textAlign = "right", variant = "medium", }) => {
133
- return (_jsxs(View, { style: styles.balanceCellContainer, children: [_jsx(View, { style: styles.cell, children: _jsxs(LakeText, { align: textAlign, color: colors.gray[900], variant: variant, style: [
134
- styles.mediumText,
135
- {
136
- justifyContent: match(textAlign)
137
- .with("left", () => "flex-start")
138
- .with("center", () => "center")
139
- .with("right", () => "flex-end")
140
- .exhaustive(),
141
- },
142
- value > 0 && { color: colors.positive.primary },
143
- value < 0 && { color: colors.negative.primary },
144
- ], children: [value > 0 && "+", formatCurrency(value, currency)] }) }), isNotNullish(originalValue) && originalValue.currency !== currency && (_jsx(View, { style: styles.cell, children: _jsxs(LakeText, { style: styles.mediumText, align: textAlign, color: colors.gray[500], variant: "smallRegular", children: [originalValue.value > 0 && "+", formatCurrency(originalValue.value, originalValue.currency)] }) }))] }));
145
- };
146
- export const LinkCell = ({ children, external = false, onPress, variant = "medium", tooltip, buttonPosition = "start", }) => {
147
- const ArrowButton = () => (_jsx(Pressable, { style: ({ hovered }) => [styles.icon, hovered && styles.underline], onPress: event => {
148
- event.preventDefault();
149
- onPress();
150
- }, children: _jsx(Icon, { size: 14, name: external ? "open-regular" : "arrow-right-filled" }) }));
151
- return (_jsxs(View, { style: styles.cell, children: [buttonPosition === "start" && (_jsxs(_Fragment, { children: [_jsx(ArrowButton, {}), _jsx(Space, { width: 8 })] })), _jsx(LakeText, { color: colors.gray[900], variant: variant, style: styles.mediumText, tooltip: tooltip, children: children }), buttonPosition === "end" && (_jsxs(_Fragment, { children: [_jsx(Space, { width: 8 }), _jsx(ArrowButton, {})] }))] }));
152
- };
153
- export const StartAlignedCell = ({ children }) => {
154
- return _jsx(View, { style: styles.cell, children: children });
155
- };
156
- export const CenteredCell = ({ children }) => {
157
- return _jsx(View, { style: [styles.cell, styles.centeredCell], children: children });
158
- };
159
- export const EndAlignedCell = ({ children }) => {
160
- return _jsx(View, { style: [styles.cell, styles.endAlignedCell], children: children });
136
+ export const BalanceCell = ({ textAlign = "right", align = textAlign, currency, formatCurrency, originalValue, value, variant = "medium", }) => (_jsxs(Cell, { align: align, direction: "column", children: [_jsx(LakeText, { numberOfLines: 1, align: align, color: colors.gray[900], variant: variant, style: [
137
+ value > 0 && { color: colors.positive.primary },
138
+ value < 0 && { color: colors.negative.primary },
139
+ ], children: (value > 0 ? "+" : "") + formatCurrency(value, currency) }), isNotNullish(originalValue) && originalValue.currency !== currency && (_jsx(LakeText, { numberOfLines: 1, align: align, color: colors.gray[500], variant: "smallRegular", children: (originalValue.value > 0 ? "+" : "") +
140
+ formatCurrency(originalValue.value, originalValue.currency) }))] }));
141
+ export const LinkCell = ({ buttonPosition = "start", children, external = false, fadeOn, onPress, tooltip, variant = "medium", }) => {
142
+ const elements = [
143
+ _jsx(Pressable, { style: ({ hovered }) => [styles.linkButton, hovered && styles.buttonUnderline], onPress: event => {
144
+ event.preventDefault();
145
+ onPress();
146
+ }, children: _jsx(Icon, { size: 14, name: external ? "open-regular" : "arrow-right-filled" }) }),
147
+ _jsx(Space, { width: 8 }),
148
+ _jsx(LakeText, { numberOfLines: 1, color: colors.gray[900], variant: variant, tooltip: tooltip, children: children }),
149
+ ];
150
+ if (buttonPosition === "end") {
151
+ elements.reverse();
152
+ }
153
+ return _jsx(Cell, { fadeOn: fadeOn, children: elements });
161
154
  };
162
- export const CellAction = ({ children }) => {
163
- return _jsx(View, { style: styles.cellAction, children: children });
155
+ /**
156
+ * @deprecated Avoid usage
157
+ */
158
+ export const ColorPatchCell = ({ alternativeText, color, isHovered, }) => {
159
+ return isHovered ? (_jsx(Box, { grow: 1, style: { backgroundColor: colors[color].primary }, children: isNotNullish(alternativeText) ? (_jsx(LakeText, { style: visuallyHiddenStyle, children: alternativeText })) : null })) : null;
164
160
  };
161
+ /**
162
+ * @deprecated Use `HeaderCell` instead
163
+ */
164
+ export const SimpleHeaderCell = ({ justifyContent = "flex-start", ...props }) => (_jsx(HeaderCell, { ...props, align: match(justifyContent)
165
+ .returnType()
166
+ .with("flex-start", () => "left")
167
+ .with("flex-end", () => "right")
168
+ .otherwise(identity) }));
169
+ /**
170
+ * @deprecated Use `TextCell` with color={…} and variant="medium" instead
171
+ */
172
+ export const SimpleTitleCell = ({ isHighlighted = false, text, tooltip, }) => (_jsx(TextCell, { color: isHighlighted ? colors.current.primary : colors.gray[900], text: text, tooltip: tooltip, variant: "medium" }));
173
+ /**
174
+ * @deprecated Use `TextCell` instead
175
+ */
176
+ export const SimpleRegularTextCell = ({ color = colors.gray[900], text, textAlign = "left", variant = "regular", }) => _jsx(TextCell, { align: textAlign, color: color, text: text, variant: variant });
177
+ /**
178
+ * @deprecated Use `CopyableTextCell` instead
179
+ */
180
+ export const CopyableRegularTextCell = CopyableTextCell;
181
+ /**
182
+ * @deprecated Use `<Cell align="left" />` instead
183
+ */
184
+ export const StartAlignedCell = (props) => (_jsx(Cell, { align: "left", ...props }));
185
+ /**
186
+ * @deprecated Use `<Cell align="center" />` instead
187
+ */
188
+ export const CenteredCell = (props) => (_jsx(Cell, { align: "center", ...props }));
189
+ /**
190
+ * @deprecated Use `<Cell align="right" />` instead
191
+ */
192
+ export const EndAlignedCell = (props) => (_jsx(Cell, { align: "right", ...props }));
193
+ export const ActionCell = ({ style, ...props }) => (_jsx(Cell, { ...props, style: [styles.actionCell, style] }));
194
+ /**
195
+ * @deprecated Use <ActionCell /> instead
196
+ */
197
+ export const CellAction = ({ children }) => (_jsx(ActionCell, { children: children }));
@@ -22,6 +22,8 @@ const styles = StyleSheet.create({
22
22
  minWidth: 90,
23
23
  justifyContent: "center",
24
24
  paddingHorizontal: 20,
25
+ },
26
+ transition: {
25
27
  transitionDuration: "150ms",
26
28
  transitionProperty: "background-color, color",
27
29
  },
@@ -163,6 +165,8 @@ export const LakeButton = memo(forwardRef(({ ariaControls, ariaExpanded, ariaLab
163
165
  const shouldHideContents = loading || progressAnimation.isSome();
164
166
  return (_jsx(Pressable, { href: href, hrefAttrs: hrefAttrs, role: href != null ? "link" : "button", "aria-busy": loading, "aria-disabled": disabled, "aria-controls": ariaControls, "aria-expanded": ariaExpanded, "aria-label": ariaLabel, disabled: loading || disabled || progressAnimation.isSome(), ref: forwardedRef, onPress: onPress, style: ({ hovered, pressed, focused }) => [
165
167
  styles.base,
168
+ (hovered || pressed) && styles.transition,
169
+ grow && styles.grow,
166
170
  isSmall && styles.small,
167
171
  vertical && [styles.vertical, isSmall && styles.verticalSmall],
168
172
  hasIconStart && isSmall ? styles.withIconStartSmall : styles.withIconStart,
@@ -170,7 +174,6 @@ export const LakeButton = memo(forwardRef(({ ariaControls, ariaExpanded, ariaLab
170
174
  hasOnlyIcon && (isSmall ? styles.iconSmallOnly : styles.iconOnly),
171
175
  (disabled || progressAnimation.isSome()) && commonStyles.disabled,
172
176
  disabled && forceBackground && styles.resetOpacity,
173
- grow && styles.grow,
174
177
  match(mode)
175
178
  .with("primary", () => ({
176
179
  backgroundColor: color === "warning"
@@ -1,7 +1,7 @@
1
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
1
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
2
  import { useEffect, useRef, useState } from "react";
3
3
  import { StyleSheet, View } from "react-native";
4
- import { colors } from "../constants/design";
4
+ import { colors, radii } from "../constants/design";
5
5
  import { LakeText } from "./LakeText";
6
6
  import { Pressable } from "./Pressable";
7
7
  import { Space } from "./Space";
@@ -29,6 +29,12 @@ const styles = StyleSheet.create({
29
29
  disabled: {
30
30
  opacity: 0.5,
31
31
  },
32
+ errorPill: {
33
+ width: 5,
34
+ height: 5,
35
+ backgroundColor: colors.negative[500],
36
+ borderRadius: radii[6],
37
+ },
32
38
  });
33
39
  export const LakeCheckbox = ({ value, color = "current", disabled = false, isError = false, }) => {
34
40
  const isFirstRender = useRef(true);
@@ -50,5 +56,5 @@ export const LakeCheckbox = ({ value, color = "current", disabled = false, isErr
50
56
  ], children: [value === true && (_jsx(Svg, { viewBox: "0 0 16 16", children: _jsx(Path, { d: "m3.5 7.5 2.8 3.4 5.6-6.7", stroke: colors[color].contrast, strokeWidth: 1.5, fill: "none", strokeLinecap: "round", strokeLinejoin: "round", strokeDasharray: "20", strokeDashoffset: shouldAnimate ? "20" : "0", children: shouldAnimate && (_jsx(Animate, { attributeName: "stroke-dashoffset", values: "20;0", dur: "150ms", begin: "150ms", fill: "freeze" })) }) })), value === "mixed" && (_jsx(View, { style: [styles.mixed, { backgroundColor: colors[color].contrast }] }))] }));
51
57
  };
52
58
  export const LakeLabelledCheckbox = ({ value, color, label, onValueChange, disabled = false, isError = false, }) => {
53
- return (_jsxs(Pressable, { role: "checkbox", "aria-checked": value, style: styles.labelled, onPress: () => onValueChange(value === true ? false : true), disabled: disabled, children: [_jsx(LakeCheckbox, { value: value, color: color, disabled: disabled, isError: isError }), _jsx(Space, { width: 8 }), _jsx(LakeText, { color: colors.gray[900], userSelect: "none", children: label })] }));
59
+ return (_jsxs(Pressable, { role: "checkbox", "aria-checked": value, style: styles.labelled, onPress: () => onValueChange(value === true ? false : true), disabled: disabled, children: [_jsx(LakeCheckbox, { value: value, color: color, disabled: disabled, isError: isError }), _jsx(Space, { width: 8 }), _jsx(LakeText, { color: colors.gray[900], userSelect: "none", children: label }), isError ? (_jsxs(_Fragment, { children: [_jsx(Space, { width: 8 }), _jsx(View, { style: styles.errorPill })] })) : null] }));
54
60
  };
@@ -1,6 +1,7 @@
1
1
  import { ReactElement, ReactNode } from "react";
2
2
  import { PressableStateCallbackType, ViewStyle } from "react-native";
3
3
  import { ColumnCellConfig, ColumnTitleConfig, LinkConfig } from "./VirtualizedList";
4
+ export type { LinkConfig } from "./VirtualizedList";
4
5
  export type ColumnConfig<T, ExtraInfo> = {
5
6
  id: string;
6
7
  width: number | "grow";
@@ -46,4 +47,3 @@ export declare const PlainListViewPlaceholder: ({ count, rowHeight, groupHeaderH
46
47
  headerHeight?: number;
47
48
  marginHorizontal?: string;
48
49
  }) => import("react/jsx-runtime").JSX.Element;
49
- export {};
@@ -7,9 +7,12 @@ export type ColumnTitleConfig<ExtraInfo> = {
7
7
  export type ColumnCellConfig<T, ExtraInfo> = {
8
8
  columnId: string;
9
9
  item: T;
10
+ /**
11
+ * isHovered is only set for PlainListView
12
+ */
13
+ isHovered: boolean;
10
14
  index: number;
11
15
  extraInfo: ExtraInfo;
12
- isHovered: boolean;
13
16
  };
14
17
  export type ColumnConfig<T, ExtraInfo> = {
15
18
  id: string;
@@ -69,14 +69,12 @@ const styles = StyleSheet.create({
69
69
  transitionTimingFunction: "ease-in-out",
70
70
  },
71
71
  headerCell: {
72
- display: "flex",
73
72
  flexDirection: "row",
74
73
  flexGrow: 1,
75
74
  alignItems: "center",
76
75
  boxShadow: `0 -1px ${colors.gray[100]}`,
77
76
  },
78
77
  cell: {
79
- display: "flex",
80
78
  flexDirection: "row",
81
79
  flexGrow: 1,
82
80
  alignItems: "stretch",