@swan-io/lake 11.1.7 → 11.1.9

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": "11.1.7",
3
+ "version": "11.1.9",
4
4
  "engines": {
5
5
  "node": ">=20.9.0",
6
6
  "pnpm": "^9.13.0"
@@ -125,7 +125,10 @@ export declare const CenteredCell: (props: Except<CellProps, "align">) => import
125
125
  * @deprecated Use `<Cell align="right" />` instead
126
126
  */
127
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;
128
+ /**
129
+ * @deprecated Use `<Cell align="right" />` instead
130
+ */
131
+ export declare const ActionCell: (props: CellProps) => import("react/jsx-runtime").JSX.Element;
129
132
  /**
130
133
  * @deprecated Use <ActionCell /> instead
131
134
  */
@@ -29,14 +29,14 @@ const justifyContentStyles = StyleSheet.create({
29
29
  right: { justifyContent: "flex-end" },
30
30
  });
31
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]})`;
32
+ const fadeOnLeftMask = `linear-gradient(to right, ${invariantColors.transparent}, ${invariantColors.black} ${spacings[8]})`;
33
+ const fadeOnRightMask = `linear-gradient(to left, ${invariantColors.transparent}, ${invariantColors.black} ${spacings[8]})`;
34
34
  const styles = StyleSheet.create({
35
35
  cell: {
36
36
  flexDirection: "row",
37
37
  flexGrow: 1,
38
38
  flexShrink: 1,
39
- paddingHorizontal: spacings[16],
39
+ paddingHorizontal: spacings[8],
40
40
  },
41
41
  cellContentContainer: {
42
42
  flexGrow: 1,
@@ -98,10 +98,6 @@ const styles = StyleSheet.create({
98
98
  paddingRight: 0,
99
99
  paddingLeft: spacings[8],
100
100
  },
101
- actionCell: {
102
- paddingVertical: spacings[16],
103
- paddingHorizontal: spacings[8],
104
- },
105
101
  });
106
102
  export const Cell = ({ children, align = "left", direction = "row", fadeOn, style, contentContainerStyle, }) => (_jsx(View, { style: [styles.cell, style], children: _jsx(View, { style: [
107
103
  styles.cellContentContainer,
@@ -196,7 +192,10 @@ export const CenteredCell = (props) => (_jsx(Cell, { align: "center", ...props }
196
192
  * @deprecated Use `<Cell align="right" />` instead
197
193
  */
198
194
  export const EndAlignedCell = (props) => (_jsx(Cell, { align: "right", ...props }));
199
- export const ActionCell = ({ style, ...props }) => (_jsx(Cell, { ...props, style: [styles.actionCell, style] }));
195
+ /**
196
+ * @deprecated Use `<Cell align="right" />` instead
197
+ */
198
+ export const ActionCell = (props) => _jsx(Cell, { align: "right", ...props });
200
199
  /**
201
200
  * @deprecated Use <ActionCell /> instead
202
201
  */
@@ -196,7 +196,7 @@ export const MultiSelect = ({ color = "gray", disabled = false, emptyResultText,
196
196
  }, [filteredItems]);
197
197
  const ListHeaderComponent = useMemo(() => (_jsxs(Box, { direction: "row", alignItems: "center", style: styles.filterContainer, children: [_jsx(TextInput, { autoComplete: "off", inputMode: "search", multiline: false, rows: 1, onChangeText: filterValue => setFilter(filterValue), placeholder: filterPlaceholder, value: filter, onFocus: setFilterFocused.on, onBlur: setFilterFocused.off, style: [styles.filterInput, filterFocused && styles.filterFocused] }), _jsx(Icon, { name: "search-filled", color: colors[color].primary, size: 20, style: styles.searchIcon })] })), [filter, filterFocused, setFilterFocused, filterPlaceholder, color]);
198
198
  const ListEmptyComponent = useMemo(() => (_jsxs(Box, { justifyContent: "center", alignItems: "center", style: styles.emptyList, children: [_jsx(Icon, { name: "clipboard-search-regular", size: 24, color: colors.gray.primary }), isNotNullishOrEmpty(emptyResultText) && (_jsxs(_Fragment, { children: [_jsx(Space, { height: 8 }), _jsx(Text, { style: styles.emptyListText, children: emptyResultText })] }))] })), [emptyResultText]);
199
- return (_jsxs(View, { style: style, children: [_jsxs(Pressable, { id: id, ref: inputRef, "aria-haspopup": "listbox", role: "button", "aria-expanded": visible, disabled: disabled, onPress: open, style: ({ hovered, focused }) => [
199
+ return (_jsxs(View, { style: style, children: [_jsxs(Pressable, { id: id, ref: inputRef, "aria-haspopup": "listbox", "aria-expanded": visible, disabled: disabled, onPress: open, style: ({ hovered, focused }) => [
200
200
  styles.base,
201
201
  hovered && styles.hovered,
202
202
  (focused || visible) && styles.focused,
@@ -26,10 +26,10 @@ const styles = StyleSheet.create({
26
26
  flexDirection: "row",
27
27
  alignItems: "stretch",
28
28
  overflow: "hidden",
29
- paddingHorizontal: spacings[8],
29
+ paddingHorizontal: spacings[16],
30
30
  },
31
31
  segmentLarge: {
32
- paddingHorizontal: spacings[24],
32
+ paddingHorizontal: spacings[32],
33
33
  },
34
34
  row: {
35
35
  boxShadow: `inset 0 -1px ${colors.gray[100]}`,
@@ -7,9 +7,6 @@ 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
10
  isHovered: boolean;
14
11
  index: number;
15
12
  extraInfo: ExtraInfo;
@@ -7,7 +7,7 @@ import { backgroundColor as backgroundColorVariants, colors, spacings } from "..
7
7
  import { useHover } from "../hooks/useHover";
8
8
  import { ScrollView } from "./ScrollView";
9
9
  import { Space } from "./Space";
10
- const HORIZONTAL_ROW_PADDING = 8;
10
+ const HORIZONTAL_ROW_PADDING = 16;
11
11
  const styles = StyleSheet.create({
12
12
  container: {
13
13
  ...commonStyles.fill,
@@ -441,7 +441,7 @@ const RawVirtualizedRow = ({ viewId, rowHeight, absoluteIndex, variant, stickedT
441
441
  item,
442
442
  index: absoluteIndex,
443
443
  extraInfo,
444
- isHovered: false,
444
+ isHovered,
445
445
  }) }, columnId));
446
446
  }) })))
447
447
  .toNull(), _jsx(View, { style: [
@@ -466,7 +466,7 @@ const RawVirtualizedRow = ({ viewId, rowHeight, absoluteIndex, variant, stickedT
466
466
  item,
467
467
  index: absoluteIndex,
468
468
  extraInfo,
469
- isHovered: false,
469
+ isHovered,
470
470
  }) }, columnId));
471
471
  }) }), Option.fromNullable(stickedToEndColumns)
472
472
  .map(columns => (_jsx(View, { style: [
@@ -488,7 +488,7 @@ const RawVirtualizedRow = ({ viewId, rowHeight, absoluteIndex, variant, stickedT
488
488
  item,
489
489
  index: absoluteIndex,
490
490
  extraInfo,
491
- isHovered: false,
491
+ isHovered,
492
492
  }) }, columnId));
493
493
  }) })))
494
494
  .toNull()] })),
@@ -1 +1 @@
1
- export declare const usePersistedState: <T>(key: string, defaultValue: T) => readonly [T, (state: T) => void];
1
+ export declare const usePersistedState: <T>(key: string, defaultValue: T) => readonly [T, (value: T | null) => void];
@@ -1,21 +1,55 @@
1
1
  import { Option, Result } from "@swan-io/boxed";
2
- import { useCallback, useState } from "react";
2
+ import { useCallback, useEffect, useState } from "react";
3
+ const getItem = (key) => Result.fromExecution(() => localStorage.getItem(key)).getOr(null);
4
+ const parseRawValue = (rawValue, defaultValue) => Result.fromExecution(() => (rawValue != null ? JSON.parse(rawValue) : rawValue))
5
+ .toOption()
6
+ .flatMap(Option.fromNullable)
7
+ .getOr(defaultValue);
3
8
  export const usePersistedState = (key, defaultValue) => {
4
9
  const [state, setState] = useState(() => {
5
- return Result.fromExecution(() => localStorage.getItem(key))
6
- .toOption()
7
- .flatMap(Option.fromNullable)
8
- .map(value => JSON.parse(value))
9
- .getOr(defaultValue);
10
+ const rawValue = getItem(key);
11
+ const value = parseRawValue(rawValue, defaultValue);
12
+ return { defaultValue, value, rawValue };
10
13
  });
11
- const setPersistedState = useCallback((state) => {
12
- setState(state);
14
+ const updateRawValue = useCallback((rawValue) => {
15
+ setState(prevState => {
16
+ if (rawValue === prevState.rawValue) {
17
+ return prevState; // skip update if rawValue didn't changed
18
+ }
19
+ else {
20
+ const { defaultValue } = prevState;
21
+ const value = parseRawValue(rawValue, defaultValue);
22
+ return { defaultValue, value, rawValue };
23
+ }
24
+ });
25
+ }, []);
26
+ const setPersistedState = useCallback((value) => {
13
27
  try {
14
- localStorage.setItem(key, JSON.stringify(state));
28
+ if (value != null) {
29
+ const rawValue = JSON.stringify(value);
30
+ updateRawValue(rawValue);
31
+ localStorage.setItem(key, rawValue);
32
+ }
33
+ else {
34
+ updateRawValue(null);
35
+ localStorage.removeItem(key);
36
+ }
15
37
  }
16
38
  catch {
17
39
  // ignore
18
40
  }
19
- }, [key]);
20
- return [state, setPersistedState];
41
+ }, [key, updateRawValue]);
42
+ useEffect(() => {
43
+ const listener = (event) => {
44
+ if (event.storageArea === localStorage && (event.key === key || event.key === null)) {
45
+ const rawValue = getItem(key);
46
+ updateRawValue(rawValue);
47
+ }
48
+ };
49
+ window.addEventListener("storage", listener);
50
+ return () => {
51
+ window.removeEventListener("storage", listener);
52
+ };
53
+ }, [key, updateRawValue]);
54
+ return [state.value, setPersistedState];
21
55
  };