@swan-io/lake 8.5.0 → 8.5.2

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": "8.5.0",
3
+ "version": "8.5.2",
4
4
  "engines": {
5
5
  "node": ">=20.9.0",
6
6
  "yarn": "^1.22.0"
@@ -3,12 +3,13 @@ export type Item<T extends string> = {
3
3
  name: string;
4
4
  id: T;
5
5
  icon?: ReactNode;
6
+ activeIcon?: ReactNode;
6
7
  };
7
8
  type Props<T extends string> = {
8
- mode?: "desktop" | "mobile";
9
9
  selected: T;
10
10
  items: ReadonlyArray<Item<T>>;
11
11
  onValueChange: (value: T) => void;
12
+ minItemWidth?: number;
12
13
  };
13
- export declare const SegmentedControl: <T extends string>({ mode, selected, items, onValueChange, }: Props<T>) => import("react/jsx-runtime").JSX.Element;
14
+ export declare const SegmentedControl: <T extends string>({ selected, items, onValueChange, minItemWidth, }: Props<T>) => import("react/jsx-runtime").JSX.Element;
14
15
  export {};
@@ -1,16 +1,22 @@
1
- import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
1
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
+ import { useState } from "react";
2
3
  import { StyleSheet, View } from "react-native";
4
+ import { P, match } from "ts-pattern";
3
5
  import { backgroundColor, colors, radii, spacings, texts } from "../constants/design";
4
6
  import { isNotNullish } from "../utils/nullish";
7
+ import { BottomPanel } from "./BottomPanel";
5
8
  import { Box } from "./Box";
9
+ import { Icon } from "./Icon";
10
+ import { LakeButton } from "./LakeButton";
6
11
  import { LakeText } from "./LakeText";
7
12
  import { Pressable } from "./Pressable";
13
+ import { ResponsiveContainer } from "./ResponsiveContainer";
8
14
  import { Space } from "./Space";
9
15
  const styles = StyleSheet.create({
10
16
  container: {
17
+ padding: spacings[4],
11
18
  backgroundColor: colors.gray[50],
12
19
  borderRadius: radii[8],
13
- padding: spacings[4],
14
20
  },
15
21
  selectedItemIndicator: {
16
22
  position: "absolute",
@@ -25,15 +31,44 @@ const styles = StyleSheet.create({
25
31
  borderRadius: radii[4],
26
32
  backgroundColor: backgroundColor.accented,
27
33
  },
28
- item: {
29
- flexBasis: "0%",
34
+ itemMobile: {
35
+ backgroundColor: backgroundColor.accented,
36
+ borderRadius: radii[4],
37
+ padding: spacings[16],
38
+ flexDirection: "row",
39
+ height: 60,
40
+ alignItems: "center",
41
+ justifyContent: "center",
30
42
  flexGrow: 1,
31
- flexShrink: 1,
43
+ },
44
+ dropdownItem: {
45
+ backgroundColor: backgroundColor.accented,
46
+ borderRadius: radii[4],
47
+ padding: spacings[16],
48
+ flexDirection: "row",
49
+ height: 60,
32
50
  alignItems: "center",
51
+ flexGrow: 1,
52
+ },
53
+ dropdownItemSelected: {
54
+ backgroundColor: colors.gray[50],
55
+ borderRadius: radii[4],
33
56
  padding: spacings[16],
34
- flexDirection: "column",
57
+ flexDirection: "row",
58
+ height: 60,
59
+ alignItems: "center",
60
+ flexGrow: 1,
61
+ },
62
+ button: {
63
+ width: 60,
64
+ height: 60,
35
65
  },
36
66
  itemDesktop: {
67
+ flexBasis: "0%",
68
+ flexGrow: 1,
69
+ flexShrink: 1,
70
+ alignItems: "center",
71
+ padding: spacings[16],
37
72
  flexDirection: "row",
38
73
  justifyContent: "center",
39
74
  },
@@ -41,28 +76,43 @@ const styles = StyleSheet.create({
41
76
  userSelect: "none",
42
77
  lineHeight: texts.regular.fontSize,
43
78
  },
44
- selectedItemMobile: {
45
- right: 0,
46
- },
47
79
  selectedItemDesktop: {
48
80
  bottom: 0,
49
81
  },
50
82
  });
51
- export const SegmentedControl = ({ mode = "desktop", selected, items, onValueChange, }) => {
83
+ export const SegmentedControl = ({ selected, items, onValueChange, minItemWidth = 250, }) => {
52
84
  const selectedItemIndex = items.findIndex(item => item.id === selected);
53
- return (_jsx(Box, { style: styles.container, children: _jsxs(Box, { direction: mode === "mobile" ? "column" : "row", children: [_jsx(View, { role: "none", style: [
85
+ const selectedItem = items[selectedItemIndex];
86
+ const [pressed, setPressed] = useState(false);
87
+ return (_jsx(ResponsiveContainer, { breakpoint: items.length * minItemWidth, style: styles.container, children: ({ small }) => small ? (_jsxs(Box, { direction: "row", alignItems: "center", justifyContent: "spaceBetween", children: [_jsxs(Pressable, { style: styles.itemMobile, onPress: () => {
88
+ setPressed(true);
89
+ }, children: [isNotNullish(selectedItem === null || selectedItem === void 0 ? void 0 : selectedItem.icon) &&
90
+ match(selectedItem)
91
+ .with({ icon: P.nonNullable, activeIcon: P.nonNullable }, () => selectedItem.activeIcon)
92
+ .with({ icon: P.nonNullable }, () => selectedItem.icon)
93
+ .otherwise(() => null), _jsx(Space, { height: 8, width: 12 }), _jsx(LakeText, { color: colors.gray[900], numberOfLines: 1, variant: "regular", style: styles.itemText, children: selectedItem === null || selectedItem === void 0 ? void 0 : selectedItem.name })] }), _jsx(BottomPanel, { visible: pressed === true, onPressClose: () => {
94
+ setPressed(false);
95
+ }, children: items.map(item => (_jsxs(Box, { direction: "row", children: [_jsxs(Pressable, { style: (selectedItem === null || selectedItem === void 0 ? void 0 : selectedItem.id) === item.id
96
+ ? styles.dropdownItemSelected
97
+ : styles.dropdownItem, onPress: () => {
98
+ onValueChange(item.id);
99
+ setPressed(false);
100
+ }, children: [isNotNullish(item.icon) &&
101
+ match(item)
102
+ .with({ icon: P.nonNullable, activeIcon: P.nonNullable }, () => (selectedItem === null || selectedItem === void 0 ? void 0 : selectedItem.id) === item.id ? selectedItem.activeIcon : item.icon)
103
+ .with({ icon: P.nonNullable }, () => item.icon)
104
+ .otherwise(() => null), _jsx(Space, { height: 8, width: 12 }), _jsx(LakeText, { color: colors.gray[900], numberOfLines: 1, variant: "regular", style: styles.itemText, children: item.name })] }), (selectedItem === null || selectedItem === void 0 ? void 0 : selectedItem.id) === item.id && (_jsx(Box, { justifyContent: "center", style: { paddingHorizontal: spacings[24], backgroundColor: colors.gray[50] }, children: _jsx(Icon, { size: 16, name: "lake-check", color: colors.positive[500] }) }))] }, item.id))) }), _jsx(Space, { width: 4 }), _jsx(LakeButton, { mode: "tertiary", style: styles.button, size: "small", icon: "more-horizontal-filled", onPress: () => setPressed(true), ariaLabel: "Previous" })] })) : (_jsxs(Box, { direction: "row", children: [_jsx(View, { role: "none", style: [
54
105
  styles.selectedItemIndicator,
55
- mode === "mobile" ? styles.selectedItemMobile : styles.selectedItemDesktop,
56
- mode === "mobile"
57
- ? {
58
- height: `${(1 / items.length) * 100}%`,
59
- transform: `translateY(${selectedItemIndex * 100}%)`,
60
- }
61
- : {
62
- width: `${(1 / items.length) * 100}%`,
63
- transform: `translateX(${selectedItemIndex * 100}%)`,
64
- },
65
- ] }), items.map(item => (_jsxs(Pressable, { style: [styles.item, mode === "desktop" && styles.itemDesktop], onPress: () => {
106
+ styles.selectedItemDesktop,
107
+ {
108
+ width: `${(1 / items.length) * 100}%`,
109
+ transform: `translateX(${selectedItemIndex * 100}%)`,
110
+ },
111
+ ] }), items.map(item => (_jsxs(Pressable, { style: styles.itemDesktop, onPress: () => {
66
112
  onValueChange(item.id);
67
- }, children: [isNotNullish(item.icon) && (_jsxs(_Fragment, { children: [item.icon, _jsx(Space, { height: 8, width: 12 })] })), _jsx(LakeText, { color: colors.gray[900], numberOfLines: 1, variant: "regular", style: styles.itemText, children: item.name })] }, item.id)))] }) }));
113
+ }, children: [_jsxs(_Fragment, { children: [isNotNullish(item.icon) &&
114
+ match(item)
115
+ .with({ icon: P.nonNullable, activeIcon: P.nonNullable }, () => (selectedItem === null || selectedItem === void 0 ? void 0 : selectedItem.id) === item.id ? selectedItem.activeIcon : item.icon)
116
+ .with({ icon: P.nonNullable }, () => item.icon)
117
+ .otherwise(() => null), _jsx(Space, { height: 8, width: 12 })] }), _jsx(LakeText, { color: colors.gray[900], numberOfLines: 1, variant: "regular", style: styles.itemText, children: item.name })] }, item.id)))] })) }));
68
118
  };