@ledgerhq/native-ui 0.39.0 → 0.40.0-nightly.0
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/lib/components/Form/TabSelector/index.d.ts.map +1 -1
- package/lib/components/Form/TabSelector/index.js +1 -1
- package/lib/pre-ldls/components/AssetItem/AssetItem.d.ts +14 -0
- package/lib/pre-ldls/components/AssetItem/AssetItem.d.ts.map +1 -0
- package/lib/pre-ldls/components/AssetItem/AssetItem.js +50 -0
- package/lib/pre-ldls/components/AssetItem/AssetItem.stories.d.ts +11 -0
- package/lib/pre-ldls/components/AssetItem/AssetItem.stories.d.ts.map +1 -0
- package/lib/pre-ldls/components/AssetItem/AssetItem.stories.js +55 -0
- package/lib/pre-ldls/components/AssetTypeList/AssetList.d.ts +10 -0
- package/lib/pre-ldls/components/AssetTypeList/AssetList.d.ts.map +1 -0
- package/lib/pre-ldls/components/AssetTypeList/AssetList.js +36 -0
- package/lib/pre-ldls/components/AssetTypeList/AssetList.stories.d.ts +10 -0
- package/lib/pre-ldls/components/AssetTypeList/AssetList.stories.d.ts.map +1 -0
- package/lib/pre-ldls/components/AssetTypeList/AssetList.stories.js +62 -0
- package/lib/pre-ldls/components/CryptoIcon/CryptoIcon.d.ts +1 -1
- package/lib/pre-ldls/components/CryptoIcon/CryptoIcon.d.ts.map +1 -1
- package/lib/pre-ldls/components/CryptoIcon/CryptoIcon.js +1 -1
- package/lib/pre-ldls/components/CryptoIcon/CryptoIcon.stories.d.ts.map +1 -1
- package/lib/pre-ldls/components/CryptoIcon/CryptoIcon.stories.js +1 -0
- package/lib/pre-ldls/components/NetworkItem/NetworkItem.d.ts +14 -0
- package/lib/pre-ldls/components/NetworkItem/NetworkItem.d.ts.map +1 -0
- package/lib/pre-ldls/components/NetworkItem/NetworkItem.js +46 -0
- package/lib/pre-ldls/components/NetworkItem/NetworkItem.stories.d.ts +10 -0
- package/lib/pre-ldls/components/NetworkItem/NetworkItem.stories.d.ts.map +1 -0
- package/lib/pre-ldls/components/NetworkItem/NetworkItem.stories.js +32 -0
- package/lib/pre-ldls/components/NetworkList/NetworkList.d.ts +10 -0
- package/lib/pre-ldls/components/NetworkList/NetworkList.d.ts.map +1 -0
- package/lib/pre-ldls/components/NetworkList/NetworkList.js +35 -0
- package/lib/pre-ldls/components/NetworkList/NetwrokList.stories.d.ts +8 -0
- package/lib/pre-ldls/components/NetworkList/NetwrokList.stories.d.ts.map +1 -0
- package/lib/pre-ldls/components/NetworkList/NetwrokList.stories.js +30 -0
- package/lib/pre-ldls/components/Search/Search.d.ts +9 -0
- package/lib/pre-ldls/components/Search/Search.d.ts.map +1 -0
- package/lib/pre-ldls/components/Search/Search.js +26 -0
- package/lib/pre-ldls/components/Search/Search.stories.d.ts +8 -0
- package/lib/pre-ldls/components/Search/Search.stories.d.ts.map +1 -0
- package/lib/pre-ldls/components/Search/Search.stories.js +29 -0
- package/lib/pre-ldls/components/Tag/Tag.d.ts +7 -0
- package/lib/pre-ldls/components/Tag/Tag.d.ts.map +1 -0
- package/lib/pre-ldls/components/Tag/Tag.js +14 -0
- package/lib/pre-ldls/components/index.d.ts +6 -0
- package/lib/pre-ldls/components/index.d.ts.map +1 -1
- package/lib/pre-ldls/components/index.js +6 -0
- package/lib/pre-ldls/components/sharedStoryBook.d.ts +6 -0
- package/lib/pre-ldls/components/sharedStoryBook.d.ts.map +1 -0
- package/lib/pre-ldls/components/sharedStoryBook.js +13 -0
- package/lib/pre-ldls/hooks/index.d.ts +2 -0
- package/lib/pre-ldls/hooks/index.d.ts.map +1 -0
- package/lib/pre-ldls/hooks/index.js +1 -0
- package/lib/pre-ldls/hooks/useDebouncedCallback.d.ts +2 -0
- package/lib/pre-ldls/hooks/useDebouncedCallback.d.ts.map +1 -0
- package/lib/pre-ldls/hooks/useDebouncedCallback.js +15 -0
- package/lib/pre-ldls/hooks/useDebouncedCallback.stories.d.ts +14 -0
- package/lib/pre-ldls/hooks/useDebouncedCallback.stories.d.ts.map +1 -0
- package/lib/pre-ldls/hooks/useDebouncedCallback.stories.js +41 -0
- package/package.json +3 -3
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/components/Form/TabSelector/index.tsx"],"names":[],"mappings":";AA8BA,KAAK,gBAAgB,CAAC,CAAC,SAAS,MAAM,IAAI;IACxC,MAAM,EAAE;QAAE,EAAE,EAAE,CAAC,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IACnC,UAAU,CAAC,EAAE,CAAC,SAAS,MAAM,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;IAC3C,QAAQ,EAAE,CAAC,KAAK,EAAE,CAAC,KAAK,IAAI,CAAC;IAC7B,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB,CAAC;AAEF,MAAM,CAAC,OAAO,UAAU,WAAW,CAAC,CAAC,SAAS,MAAM,EAAE,EACpD,MAAM,EACN,UAAU,EACV,QAAQ,EACR,aAAqB,GACtB,EAAE,gBAAgB,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC,OAAO,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/components/Form/TabSelector/index.tsx"],"names":[],"mappings":";AA8BA,KAAK,gBAAgB,CAAC,CAAC,SAAS,MAAM,IAAI;IACxC,MAAM,EAAE;QAAE,EAAE,EAAE,CAAC,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IACnC,UAAU,CAAC,EAAE,CAAC,SAAS,MAAM,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;IAC3C,QAAQ,EAAE,CAAC,KAAK,EAAE,CAAC,KAAK,IAAI,CAAC;IAC7B,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB,CAAC;AAEF,MAAM,CAAC,OAAO,UAAU,WAAW,CAAC,CAAC,SAAS,MAAM,EAAE,EACpD,MAAM,EACN,UAAU,EACV,QAAQ,EACR,aAAqB,GACtB,EAAE,gBAAgB,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC,OAAO,CA0EnC"}
|
|
@@ -66,7 +66,7 @@ export default function TabSelector({ labels, initialTab, onToggle, filledVarian
|
|
|
66
66
|
labels.map((label, index) => (React.createElement(Pressable, { hitSlop: 6, key: label.id, onPress: () => handlePress(label.id, index), style: ({ pressed }) => ({
|
|
67
67
|
opacity: pressed && selectedIndex !== index ? 0.5 : 1,
|
|
68
68
|
flex: 1,
|
|
69
|
-
}) },
|
|
69
|
+
}), testID: `tab-selector-${label.id}` },
|
|
70
70
|
React.createElement(Tab, { "$radius": tabRadius },
|
|
71
71
|
React.createElement(Text, { fontSize: 14, fontWeight: "semiBold", flexShrink: 1, numberOfLines: 1 }, label.value))))))));
|
|
72
72
|
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
export type AssetType = {
|
|
3
|
+
name: string;
|
|
4
|
+
ticker: string;
|
|
5
|
+
id: string;
|
|
6
|
+
leftElement?: React.ReactNode;
|
|
7
|
+
rightElement?: React.ReactNode;
|
|
8
|
+
};
|
|
9
|
+
type AssetItemProps = AssetType & {
|
|
10
|
+
onClick: (asset: AssetType) => void;
|
|
11
|
+
};
|
|
12
|
+
export declare const AssetItem: ({ name, ticker, id, onClick, leftElement, rightElement, }: AssetItemProps) => React.JSX.Element;
|
|
13
|
+
export {};
|
|
14
|
+
//# sourceMappingURL=AssetItem.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AssetItem.d.ts","sourceRoot":"","sources":["../../../../src/pre-ldls/components/AssetItem/AssetItem.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAO1B,MAAM,MAAM,SAAS,GAAG;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,EAAE,EAAE,MAAM,CAAC;IACX,WAAW,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC9B,YAAY,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;CAChC,CAAC;AAEF,KAAK,cAAc,GAAG,SAAS,GAAG;IAChC,OAAO,EAAE,CAAC,KAAK,EAAE,SAAS,KAAK,IAAI,CAAC;CACrC,CAAC;AAwBF,eAAO,MAAM,SAAS,8DAOnB,cAAc,sBAkDhB,CAAC"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { Pressable, View } from "react-native";
|
|
3
|
+
import styled, { useTheme } from "styled-components/native";
|
|
4
|
+
import Text from "../../../components/Text";
|
|
5
|
+
import { CryptoIcon } from "../CryptoIcon/CryptoIcon";
|
|
6
|
+
import { useTokens } from "../../libs";
|
|
7
|
+
const Wrapper = styled(Pressable) `
|
|
8
|
+
flex-direction: row;
|
|
9
|
+
align-items: center;
|
|
10
|
+
overflow: hidden;
|
|
11
|
+
width: 100%;
|
|
12
|
+
`;
|
|
13
|
+
const InfoWrapper = styled(View) `
|
|
14
|
+
flex-direction: column;
|
|
15
|
+
justify-content: center;
|
|
16
|
+
overflow: hidden;
|
|
17
|
+
flex: 1;
|
|
18
|
+
gap: 4px;
|
|
19
|
+
margin-left: 16px;
|
|
20
|
+
`;
|
|
21
|
+
const LeftElementWrapper = styled(View) `
|
|
22
|
+
flex-direction: row;
|
|
23
|
+
align-items: center;
|
|
24
|
+
gap: 4px;
|
|
25
|
+
`;
|
|
26
|
+
export const AssetItem = ({ name, ticker, id, onClick, leftElement, rightElement, }) => {
|
|
27
|
+
const theme = useTheme();
|
|
28
|
+
const colorType = theme.colors.type === "dark" ? "dark" : "light";
|
|
29
|
+
const tokens = useTokens(colorType, [
|
|
30
|
+
"spacing-xxs",
|
|
31
|
+
"margin-s",
|
|
32
|
+
"radius-s",
|
|
33
|
+
"colors-content-default-default",
|
|
34
|
+
"colors-content-subdued-default-default",
|
|
35
|
+
"colors-surface-transparent-default",
|
|
36
|
+
]);
|
|
37
|
+
return (React.createElement(Wrapper, { onPress: () => onClick({ name, ticker, id }), style: ({ pressed }) => ({
|
|
38
|
+
padding: Number(tokens["spacing-xxs"]),
|
|
39
|
+
borderRadius: Number(tokens["radius-s"]),
|
|
40
|
+
backgroundColor: String(tokens["colors-surface-transparent-default"]),
|
|
41
|
+
opacity: pressed ? 0.7 : 1,
|
|
42
|
+
}) },
|
|
43
|
+
React.createElement(CryptoIcon, { size: 48, ledgerId: id, ticker: ticker }),
|
|
44
|
+
React.createElement(InfoWrapper, null,
|
|
45
|
+
React.createElement(Text, { fontSize: "14px", variant: "largeLineHeight", fontWeight: "semiBold", color: String(tokens["colors-content-default-default"]), numberOfLines: 1, ellipsizeMode: "tail" }, name),
|
|
46
|
+
React.createElement(LeftElementWrapper, null,
|
|
47
|
+
React.createElement(Text, { fontSize: "12px", lineHeight: "16px", variant: "bodyLineHeight", fontWeight: "medium", color: String(tokens["colors-content-subdued-default-default"]) }, ticker),
|
|
48
|
+
leftElement)),
|
|
49
|
+
rightElement));
|
|
50
|
+
};
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from "@storybook/react";
|
|
2
|
+
import { AssetItem } from "./AssetItem";
|
|
3
|
+
declare const meta: Meta<typeof AssetItem>;
|
|
4
|
+
export default meta;
|
|
5
|
+
type Story = StoryObj<typeof AssetItem>;
|
|
6
|
+
export declare const Default: Story;
|
|
7
|
+
export declare const WithBalance: Story;
|
|
8
|
+
export declare const WithTag: Story;
|
|
9
|
+
export declare const WithLeftTagAndRightBalance: Story;
|
|
10
|
+
export declare const WithDiscreetModeEnabled: Story;
|
|
11
|
+
//# sourceMappingURL=AssetItem.stories.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AssetItem.stories.d.ts","sourceRoot":"","sources":["../../../../src/pre-ldls/components/AssetItem/AssetItem.stories.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AACvD,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAGxC,QAAA,MAAM,IAAI,EAAE,IAAI,CAAC,OAAO,SAAS,CAkBhC,CAAC;AACF,eAAe,IAAI,CAAC;AAEpB,KAAK,KAAK,GAAG,QAAQ,CAAC,OAAO,SAAS,CAAC,CAAC;AAExC,eAAO,MAAM,OAAO,EAAE,KAAU,CAAC;AAEjC,eAAO,MAAM,WAAW,EAAE,KAOzB,CAAC;AAEF,eAAO,MAAM,OAAO,EAAE,KAOrB,CAAC;AAEF,eAAO,MAAM,0BAA0B,EAAE,KAQxC,CAAC;AAEF,eAAO,MAAM,uBAAuB,EAAE,KAOrC,CAAC"}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { AssetItem } from "./AssetItem";
|
|
2
|
+
import { createRightElement, leftElement } from "../sharedStoryBook";
|
|
3
|
+
const meta = {
|
|
4
|
+
component: AssetItem,
|
|
5
|
+
title: "PreLdls/Components/AssetItem",
|
|
6
|
+
tags: ["autodocs"],
|
|
7
|
+
args: {
|
|
8
|
+
name: "Bitcoin",
|
|
9
|
+
ticker: "BTC",
|
|
10
|
+
id: "bitcoin",
|
|
11
|
+
onClick: () => { },
|
|
12
|
+
},
|
|
13
|
+
parameters: {
|
|
14
|
+
docs: {
|
|
15
|
+
description: {
|
|
16
|
+
component: "AssetItem displays a crypto asset with its name, ticker, icon, and optionally fiat value and balance. Use it to represent selectable assets in lists.",
|
|
17
|
+
},
|
|
18
|
+
},
|
|
19
|
+
},
|
|
20
|
+
};
|
|
21
|
+
export default meta;
|
|
22
|
+
export const Default = {};
|
|
23
|
+
export const WithBalance = {
|
|
24
|
+
args: {
|
|
25
|
+
name: "Bitcoin",
|
|
26
|
+
ticker: "BTC",
|
|
27
|
+
id: "bitcoin",
|
|
28
|
+
rightElement: createRightElement(false),
|
|
29
|
+
},
|
|
30
|
+
};
|
|
31
|
+
export const WithTag = {
|
|
32
|
+
args: {
|
|
33
|
+
name: "Bitcoin",
|
|
34
|
+
ticker: "BTC",
|
|
35
|
+
id: "bitcoin",
|
|
36
|
+
leftElement: leftElement,
|
|
37
|
+
},
|
|
38
|
+
};
|
|
39
|
+
export const WithLeftTagAndRightBalance = {
|
|
40
|
+
args: {
|
|
41
|
+
name: "Bitcoin",
|
|
42
|
+
ticker: "BTC",
|
|
43
|
+
id: "bitcoin",
|
|
44
|
+
leftElement: leftElement,
|
|
45
|
+
rightElement: createRightElement(false),
|
|
46
|
+
},
|
|
47
|
+
};
|
|
48
|
+
export const WithDiscreetModeEnabled = {
|
|
49
|
+
args: {
|
|
50
|
+
name: "Bitcoin",
|
|
51
|
+
ticker: "BTC",
|
|
52
|
+
id: "bitcoin",
|
|
53
|
+
rightElement: createRightElement(true),
|
|
54
|
+
},
|
|
55
|
+
};
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { AssetType } from "../AssetItem/AssetItem";
|
|
3
|
+
export declare const AssetList: ({ assets, onClick, onVisibleItemsScrollEnd, scrollToTop, hasNextPage, }: {
|
|
4
|
+
assets: AssetType[];
|
|
5
|
+
onClick: (asset: AssetType) => void;
|
|
6
|
+
onVisibleItemsScrollEnd?: (() => void) | undefined;
|
|
7
|
+
scrollToTop?: boolean | undefined;
|
|
8
|
+
hasNextPage?: boolean | undefined;
|
|
9
|
+
}) => React.JSX.Element;
|
|
10
|
+
//# sourceMappingURL=AssetList.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AssetList.d.ts","sourceRoot":"","sources":["../../../../src/pre-ldls/components/AssetTypeList/AssetList.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAyC,MAAM,OAAO,CAAC;AAE9D,OAAO,EAAa,SAAS,EAAE,MAAM,wBAAwB,CAAC;AAK9D,eAAO,MAAM,SAAS;YAOZ,SAAS,EAAE;qBACF,SAAS,KAAK,IAAI;qCACH,IAAI;;;uBA0CrC,CAAC"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import React, { useCallback, useEffect, useRef } from "react";
|
|
2
|
+
import { FlatList } from "react-native";
|
|
3
|
+
import { AssetItem } from "../AssetItem/AssetItem";
|
|
4
|
+
const ITEM_PADDING = 8;
|
|
5
|
+
const ITEM_HEIGHT = 48 + ITEM_PADDING * 2;
|
|
6
|
+
export const AssetList = ({ assets, onClick, onVisibleItemsScrollEnd, scrollToTop, hasNextPage, }) => {
|
|
7
|
+
const flatListRef = useRef(null);
|
|
8
|
+
const renderAssetItem = useCallback(({ item }) => React.createElement(AssetItem, { ...item, onClick: onClick }), [onClick]);
|
|
9
|
+
const keyExtractor = useCallback((item, index) => `${item.id}-${index}`, []);
|
|
10
|
+
useEffect(() => {
|
|
11
|
+
if (scrollToTop && flatListRef.current) {
|
|
12
|
+
flatListRef.current.scrollToOffset({ offset: 0, animated: true });
|
|
13
|
+
}
|
|
14
|
+
}, [scrollToTop]);
|
|
15
|
+
const handleEndReached = useCallback(() => {
|
|
16
|
+
if (hasNextPage && onVisibleItemsScrollEnd) {
|
|
17
|
+
onVisibleItemsScrollEnd();
|
|
18
|
+
}
|
|
19
|
+
}, [hasNextPage, onVisibleItemsScrollEnd]);
|
|
20
|
+
const flatListProps = {
|
|
21
|
+
data: assets,
|
|
22
|
+
renderItem: renderAssetItem,
|
|
23
|
+
initialNumToRender: 15,
|
|
24
|
+
keyExtractor,
|
|
25
|
+
getItemLayout: (data, index) => ({
|
|
26
|
+
length: ITEM_HEIGHT,
|
|
27
|
+
offset: ITEM_HEIGHT * index,
|
|
28
|
+
index,
|
|
29
|
+
}),
|
|
30
|
+
...(hasNextPage && {
|
|
31
|
+
onEndReached: handleEndReached,
|
|
32
|
+
onEndReachedThreshold: 0.1,
|
|
33
|
+
}),
|
|
34
|
+
};
|
|
35
|
+
return React.createElement(FlatList, { ref: flatListRef, ...flatListProps });
|
|
36
|
+
};
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from "@storybook/react";
|
|
2
|
+
import { AssetList } from "./AssetList";
|
|
3
|
+
declare const meta: Meta<typeof AssetList>;
|
|
4
|
+
export default meta;
|
|
5
|
+
type Story = StoryObj<typeof AssetList>;
|
|
6
|
+
export declare const Default: Story;
|
|
7
|
+
export declare const WithFiatValue: Story;
|
|
8
|
+
export declare const WithDiscreetModeEnabled: Story;
|
|
9
|
+
export declare const WithLeftTagAndRightBalance: Story;
|
|
10
|
+
//# sourceMappingURL=AssetList.stories.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AssetList.stories.d.ts","sourceRoot":"","sources":["../../../../src/pre-ldls/components/AssetTypeList/AssetList.stories.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAGvD,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAGxC,QAAA,MAAM,IAAI,EAAE,IAAI,CAAC,OAAO,SAAS,CA4BhC,CAAC;AACF,eAAe,IAAI,CAAC;AAEpB,KAAK,KAAK,GAAG,QAAQ,CAAC,OAAO,SAAS,CAAC,CAAC;AAExC,eAAO,MAAM,OAAO,EAAE,KAAU,CAAC;AAEjC,eAAO,MAAM,aAAa,EAAE,KAS3B,CAAC;AAEF,eAAO,MAAM,uBAAuB,EAAE,KASrC,CAAC;AAEF,eAAO,MAAM,0BAA0B,EAAE,KAUxC,CAAC"}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { View } from "react-native";
|
|
3
|
+
import { AssetList } from "./AssetList";
|
|
4
|
+
import { createRightElement, leftElement } from "../sharedStoryBook";
|
|
5
|
+
const meta = {
|
|
6
|
+
component: AssetList,
|
|
7
|
+
title: "PreLdls/Components/AssetList",
|
|
8
|
+
tags: ["autodocs"],
|
|
9
|
+
args: {
|
|
10
|
+
assets: Array.from({ length: 50 }).map((_, i) => ({
|
|
11
|
+
name: `Bitcoin ${i}`,
|
|
12
|
+
ticker: "BTC",
|
|
13
|
+
id: "bitcoin",
|
|
14
|
+
})),
|
|
15
|
+
onClick: () => { },
|
|
16
|
+
scrollToTop: false,
|
|
17
|
+
},
|
|
18
|
+
decorators: [
|
|
19
|
+
(Story) => (React.createElement(View, { style: { height: 600, width: "100%" } },
|
|
20
|
+
React.createElement(Story, null))),
|
|
21
|
+
],
|
|
22
|
+
parameters: {
|
|
23
|
+
docs: {
|
|
24
|
+
description: {
|
|
25
|
+
component: "AssetList displays a list of crypto assets. It supports virtual scrolling for performance with large datasets. Use it to represent selectable assets in lists.",
|
|
26
|
+
},
|
|
27
|
+
},
|
|
28
|
+
},
|
|
29
|
+
};
|
|
30
|
+
export default meta;
|
|
31
|
+
export const Default = {};
|
|
32
|
+
export const WithFiatValue = {
|
|
33
|
+
args: {
|
|
34
|
+
assets: Array.from({ length: 50 }).map((_, i) => ({
|
|
35
|
+
name: `Bitcoin ${i}`,
|
|
36
|
+
ticker: "BTC",
|
|
37
|
+
id: "bitcoin",
|
|
38
|
+
rightElement: createRightElement(false),
|
|
39
|
+
})),
|
|
40
|
+
},
|
|
41
|
+
};
|
|
42
|
+
export const WithDiscreetModeEnabled = {
|
|
43
|
+
args: {
|
|
44
|
+
assets: Array.from({ length: 50 }).map((_, i) => ({
|
|
45
|
+
name: `Bitcoin ${i}`,
|
|
46
|
+
ticker: "BTC",
|
|
47
|
+
id: "bitcoin",
|
|
48
|
+
rightElement: createRightElement(true),
|
|
49
|
+
})),
|
|
50
|
+
},
|
|
51
|
+
};
|
|
52
|
+
export const WithLeftTagAndRightBalance = {
|
|
53
|
+
args: {
|
|
54
|
+
assets: Array.from({ length: 50 }).map((_, i) => ({
|
|
55
|
+
name: `Bitcoin ${i}`,
|
|
56
|
+
ticker: "BTC",
|
|
57
|
+
id: "bitcoin",
|
|
58
|
+
leftElement: leftElement,
|
|
59
|
+
rightElement: createRightElement(false),
|
|
60
|
+
})),
|
|
61
|
+
},
|
|
62
|
+
};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import React from "react";
|
|
2
|
-
import
|
|
2
|
+
import Icon from "@ledgerhq/crypto-icons/native";
|
|
3
3
|
export declare function CryptoIcon(props: Parameters<typeof Icon>[0]): React.JSX.Element;
|
|
4
4
|
//# sourceMappingURL=CryptoIcon.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CryptoIcon.d.ts","sourceRoot":"","sources":["../../../../src/pre-ldls/components/CryptoIcon/CryptoIcon.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,
|
|
1
|
+
{"version":3,"file":"CryptoIcon.d.ts","sourceRoot":"","sources":["../../../../src/pre-ldls/components/CryptoIcon/CryptoIcon.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,IAAI,MAAM,+BAA+B,CAAC;AAEjD,wBAAgB,UAAU,CAAC,KAAK,EAAE,UAAU,CAAC,OAAO,IAAI,CAAC,CAAC,CAAC,CAAC,qBAE3D"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CryptoIcon.stories.d.ts","sourceRoot":"","sources":["../../../../src/pre-ldls/components/CryptoIcon/CryptoIcon.stories.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,IAAI,EAAE,KAAK,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5D,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAE1C,QAAA,MAAM,IAAI,EAAE,IAAI,CAAC,OAAO,UAAU,
|
|
1
|
+
{"version":3,"file":"CryptoIcon.stories.d.ts","sourceRoot":"","sources":["../../../../src/pre-ldls/components/CryptoIcon/CryptoIcon.stories.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,IAAI,EAAE,KAAK,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5D,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAE1C,QAAA,MAAM,IAAI,EAAE,IAAI,CAAC,OAAO,UAAU,CAoBjC,CAAC;AACF,eAAe,IAAI,CAAC;AAEpB,KAAK,KAAK,GAAG,QAAQ,CAAC,OAAO,UAAU,CAAC,CAAC;AAEzC,eAAO,MAAM,OAAO,EAAE,KAErB,CAAC"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
export type Network = {
|
|
3
|
+
name: string;
|
|
4
|
+
id: string;
|
|
5
|
+
ticker: string;
|
|
6
|
+
leftElement?: React.ReactNode;
|
|
7
|
+
rightElement?: React.ReactNode;
|
|
8
|
+
};
|
|
9
|
+
type NetworkItemProps = Network & {
|
|
10
|
+
onClick: () => void;
|
|
11
|
+
};
|
|
12
|
+
export declare const NetworkItem: ({ name, onClick, id, ticker, leftElement, rightElement, }: NetworkItemProps) => React.JSX.Element;
|
|
13
|
+
export {};
|
|
14
|
+
//# sourceMappingURL=NetworkItem.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"NetworkItem.d.ts","sourceRoot":"","sources":["../../../../src/pre-ldls/components/NetworkItem/NetworkItem.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAO1B,MAAM,MAAM,OAAO,GAAG;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC9B,YAAY,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;CAChC,CAAC;AAEF,KAAK,gBAAgB,GAAG,OAAO,GAAG;IAChC,OAAO,EAAE,MAAM,IAAI,CAAC;CACrB,CAAC;AAiCF,eAAO,MAAM,WAAW,8DAOrB,gBAAgB,sBA4BlB,CAAC"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { Pressable, View } from "react-native";
|
|
3
|
+
import styled, { useTheme } from "styled-components/native";
|
|
4
|
+
import { useTokens } from "../../libs";
|
|
5
|
+
import Text from "../../../components/Text";
|
|
6
|
+
import { CryptoIcon } from "../CryptoIcon/CryptoIcon";
|
|
7
|
+
const Wrapper = styled(Pressable) `
|
|
8
|
+
flex-direction: row;
|
|
9
|
+
padding: ${({ tokens }) => tokens["spacing-xxs"]}px;
|
|
10
|
+
border-radius: ${({ tokens }) => tokens["radius-s"]}px;
|
|
11
|
+
align-items: center;
|
|
12
|
+
width: 100%;
|
|
13
|
+
`;
|
|
14
|
+
const InfoWrapper = styled(View) `
|
|
15
|
+
flex-direction: column;
|
|
16
|
+
justify-content: center;
|
|
17
|
+
margin-left: 16px;
|
|
18
|
+
flex: 1;
|
|
19
|
+
`;
|
|
20
|
+
const LeftElementWrapper = styled(View) `
|
|
21
|
+
flex-direction: row;
|
|
22
|
+
align-items: center;
|
|
23
|
+
gap: 4px;
|
|
24
|
+
`;
|
|
25
|
+
const TOKEN_KEYS = [
|
|
26
|
+
"spacing-xxs",
|
|
27
|
+
"margin-s",
|
|
28
|
+
"radius-s",
|
|
29
|
+
"colors-content-default-default",
|
|
30
|
+
"colors-content-subdued-default-default",
|
|
31
|
+
"colors-surface-transparent-hover",
|
|
32
|
+
"colors-surface-transparent-pressed",
|
|
33
|
+
];
|
|
34
|
+
export const NetworkItem = ({ name, onClick, id, ticker, leftElement, rightElement, }) => {
|
|
35
|
+
const theme = useTheme();
|
|
36
|
+
const colorType = theme.colors.type === "dark" ? "dark" : "light";
|
|
37
|
+
const tokens = useTokens(colorType, [...TOKEN_KEYS]);
|
|
38
|
+
return (React.createElement(Wrapper, { tokens: tokens, onPress: onClick, style: ({ pressed }) => ({
|
|
39
|
+
opacity: pressed ? 0.7 : 1,
|
|
40
|
+
}) },
|
|
41
|
+
React.createElement(CryptoIcon, { size: 48, ledgerId: id, ticker: ticker }),
|
|
42
|
+
React.createElement(InfoWrapper, { tokens: tokens },
|
|
43
|
+
React.createElement(Text, { variant: "largeLineHeight", fontWeight: "semiBold", color: String(tokens["colors-content-default-default"]) }, name),
|
|
44
|
+
React.createElement(LeftElementWrapper, null, leftElement)),
|
|
45
|
+
rightElement));
|
|
46
|
+
};
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from "@storybook/react";
|
|
2
|
+
import { NetworkItem } from "./NetworkItem";
|
|
3
|
+
declare const meta: Meta<typeof NetworkItem>;
|
|
4
|
+
export default meta;
|
|
5
|
+
type Story = StoryObj<typeof NetworkItem>;
|
|
6
|
+
export declare const Default: Story;
|
|
7
|
+
export declare const TestNetworkItem: Story;
|
|
8
|
+
export declare const NetworkItemWithLeftElement: Story;
|
|
9
|
+
export declare const NetworkItemWithRightElement: Story;
|
|
10
|
+
//# sourceMappingURL=NetworkItem.stories.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"NetworkItem.stories.d.ts","sourceRoot":"","sources":["../../../../src/pre-ldls/components/NetworkItem/NetworkItem.stories.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AACvD,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAG5C,QAAA,MAAM,IAAI,EAAE,IAAI,CAAC,OAAO,WAAW,CAUlC,CAAC;AACF,eAAe,IAAI,CAAC;AAEpB,KAAK,KAAK,GAAG,QAAQ,CAAC,OAAO,WAAW,CAAC,CAAC;AAE1C,eAAO,MAAM,OAAO,EAAE,KAAU,CAAC;AAEjC,eAAO,MAAM,eAAe,EAAE,KAAU,CAAC;AAEzC,eAAO,MAAM,0BAA0B,EAAE,KAOxC,CAAC;AAEF,eAAO,MAAM,2BAA2B,EAAE,KAOzC,CAAC"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { NetworkItem } from "./NetworkItem";
|
|
2
|
+
import { createRightElement, leftElement } from "../sharedStoryBook";
|
|
3
|
+
const meta = {
|
|
4
|
+
component: NetworkItem,
|
|
5
|
+
title: "PreLdls/Components/NetworkItem",
|
|
6
|
+
tags: ["autodocs"],
|
|
7
|
+
args: {
|
|
8
|
+
name: "Bitcoin",
|
|
9
|
+
id: "bitcoin",
|
|
10
|
+
ticker: "btc",
|
|
11
|
+
onClick: () => console.log("NetworkItem clicked"),
|
|
12
|
+
},
|
|
13
|
+
};
|
|
14
|
+
export default meta;
|
|
15
|
+
export const Default = {};
|
|
16
|
+
export const TestNetworkItem = {};
|
|
17
|
+
export const NetworkItemWithLeftElement = {
|
|
18
|
+
args: {
|
|
19
|
+
name: "Bitcoin",
|
|
20
|
+
id: "bitcoin",
|
|
21
|
+
ticker: "btc",
|
|
22
|
+
leftElement,
|
|
23
|
+
},
|
|
24
|
+
};
|
|
25
|
+
export const NetworkItemWithRightElement = {
|
|
26
|
+
args: {
|
|
27
|
+
name: "Bitcoin",
|
|
28
|
+
id: "bitcoin",
|
|
29
|
+
ticker: "btc",
|
|
30
|
+
rightElement: createRightElement(true),
|
|
31
|
+
},
|
|
32
|
+
};
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { Network } from "../NetworkItem/NetworkItem";
|
|
3
|
+
export declare const NetworkList: ({ networks, onClick, onVisibleItemsScrollEnd, scrollToTop, hasNextPage, }: {
|
|
4
|
+
networks: Network[];
|
|
5
|
+
onClick: (networkId: string) => void;
|
|
6
|
+
onVisibleItemsScrollEnd?: (() => void) | undefined;
|
|
7
|
+
scrollToTop?: boolean | undefined;
|
|
8
|
+
hasNextPage?: boolean | undefined;
|
|
9
|
+
}) => React.JSX.Element;
|
|
10
|
+
//# sourceMappingURL=NetworkList.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"NetworkList.d.ts","sourceRoot":"","sources":["../../../../src/pre-ldls/components/NetworkList/NetworkList.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAyC,MAAM,OAAO,CAAC;AAC9D,OAAO,EAAE,OAAO,EAAe,MAAM,4BAA4B,CAAC;AAMlE,eAAO,MAAM,WAAW;cAOZ,OAAO,EAAE;yBACE,MAAM,KAAK,IAAI;qCACJ,IAAI;;;uBAyCrC,CAAC"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import React, { useCallback, useEffect, useRef } from "react";
|
|
2
|
+
import { NetworkItem } from "../NetworkItem/NetworkItem";
|
|
3
|
+
import { FlatList } from "react-native";
|
|
4
|
+
const ITEM_PADDING = 8;
|
|
5
|
+
const ITEM_HEIGHT = 48 + ITEM_PADDING * 2;
|
|
6
|
+
export const NetworkList = ({ networks, onClick, onVisibleItemsScrollEnd, scrollToTop, hasNextPage, }) => {
|
|
7
|
+
const flatListRef = useRef(null);
|
|
8
|
+
const renderNetworkItem = useCallback(({ item }) => React.createElement(NetworkItem, { ...item, onClick: () => onClick(item.id) }), [onClick]);
|
|
9
|
+
const keyExtractor = useCallback((item, index) => `${item.id}-${index}`, []);
|
|
10
|
+
useEffect(() => {
|
|
11
|
+
if (scrollToTop && flatListRef.current) {
|
|
12
|
+
flatListRef.current.scrollToOffset({ offset: 0, animated: true });
|
|
13
|
+
}
|
|
14
|
+
}, [scrollToTop]);
|
|
15
|
+
const handleEndReached = useCallback(() => {
|
|
16
|
+
if (hasNextPage && onVisibleItemsScrollEnd) {
|
|
17
|
+
onVisibleItemsScrollEnd();
|
|
18
|
+
}
|
|
19
|
+
}, [hasNextPage, onVisibleItemsScrollEnd]);
|
|
20
|
+
const flatListProps = {
|
|
21
|
+
data: networks,
|
|
22
|
+
renderItem: renderNetworkItem,
|
|
23
|
+
keyExtractor,
|
|
24
|
+
getItemLayout: (data, index) => ({
|
|
25
|
+
length: ITEM_HEIGHT,
|
|
26
|
+
offset: ITEM_HEIGHT * index,
|
|
27
|
+
index,
|
|
28
|
+
}),
|
|
29
|
+
...(hasNextPage && {
|
|
30
|
+
onEndReached: handleEndReached,
|
|
31
|
+
onEndReachedThreshold: 0.1,
|
|
32
|
+
}),
|
|
33
|
+
};
|
|
34
|
+
return React.createElement(FlatList, { ref: flatListRef, ...flatListProps });
|
|
35
|
+
};
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from "@storybook/react";
|
|
2
|
+
import { NetworkList } from "./NetworkList";
|
|
3
|
+
declare const meta: Meta<typeof NetworkList>;
|
|
4
|
+
export default meta;
|
|
5
|
+
type Story = StoryObj<typeof NetworkList>;
|
|
6
|
+
export declare const Default: Story;
|
|
7
|
+
export declare const TestNetworkClick: Story;
|
|
8
|
+
//# sourceMappingURL=NetwrokList.stories.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"NetwrokList.stories.d.ts","sourceRoot":"","sources":["../../../../src/pre-ldls/components/NetworkList/NetwrokList.stories.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AACvD,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAI5C,QAAA,MAAM,IAAI,EAAE,IAAI,CAAC,OAAO,WAAW,CAkBlC,CAAC;AACF,eAAe,IAAI,CAAC;AAEpB,KAAK,KAAK,GAAG,QAAQ,CAAC,OAAO,WAAW,CAAC,CAAC;AAE1C,eAAO,MAAM,OAAO,EAAE,KAAU,CAAC;AAEjC,eAAO,MAAM,gBAAgB,EAAE,KAQ9B,CAAC"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { NetworkList } from "./NetworkList";
|
|
2
|
+
import React from "react";
|
|
3
|
+
import { View } from "react-native";
|
|
4
|
+
const meta = {
|
|
5
|
+
component: NetworkList,
|
|
6
|
+
title: "PreLdls/Components/NetworkList",
|
|
7
|
+
tags: ["autodocs"],
|
|
8
|
+
args: {
|
|
9
|
+
networks: Array.from({ length: 50 }, (_, i) => ({
|
|
10
|
+
name: `Bitcoin ${i}`,
|
|
11
|
+
id: `bitcoin`,
|
|
12
|
+
ticker: "btc",
|
|
13
|
+
})),
|
|
14
|
+
},
|
|
15
|
+
decorators: [
|
|
16
|
+
(Story) => (React.createElement(View, { style: { height: 600, width: "100%" } },
|
|
17
|
+
React.createElement(Story, null))),
|
|
18
|
+
],
|
|
19
|
+
};
|
|
20
|
+
export default meta;
|
|
21
|
+
export const Default = {};
|
|
22
|
+
export const TestNetworkClick = {
|
|
23
|
+
args: {
|
|
24
|
+
networks: Array.from({ length: 3 }, (_, i) => ({
|
|
25
|
+
name: `Bitcoin ${i}`,
|
|
26
|
+
id: `bitcoin`,
|
|
27
|
+
ticker: "btc",
|
|
28
|
+
})),
|
|
29
|
+
},
|
|
30
|
+
};
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { TextInputProps } from "react-native";
|
|
3
|
+
type Props = Readonly<TextInputProps & {
|
|
4
|
+
onDebouncedChange?: (current: string, prev: string) => void;
|
|
5
|
+
debounceTime?: number;
|
|
6
|
+
}>;
|
|
7
|
+
export declare function Search({ onDebouncedChange, debounceTime, onChange, ...props }: Props): React.JSX.Element;
|
|
8
|
+
export {};
|
|
9
|
+
//# sourceMappingURL=Search.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Search.d.ts","sourceRoot":"","sources":["../../../../src/pre-ldls/components/Search/Search.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA0B,MAAM,OAAO,CAAC;AAI/C,OAAO,EAAkD,cAAc,EAAE,MAAM,cAAc,CAAC;AAE9F,KAAK,KAAK,GAAG,QAAQ,CACnB,cAAc,GAAG;IACf,iBAAiB,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IAC5D,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB,CACF,CAAC;AAEF,wBAAgB,MAAM,CAAC,EAAE,iBAAiB,EAAE,YAAkB,EAAE,QAAQ,EAAE,GAAG,KAAK,EAAE,EAAE,KAAK,qBAyB1F"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import React, { useMemo, useRef } from "react";
|
|
2
|
+
import { Icons } from "../../../assets";
|
|
3
|
+
import { useDebouncedCallback } from "../../hooks";
|
|
4
|
+
import { Input } from "..";
|
|
5
|
+
export function Search({ onDebouncedChange, debounceTime = 500, onChange, ...props }) {
|
|
6
|
+
const initialValue = props.value ?? props.defaultValue ?? "";
|
|
7
|
+
const prevValue = useRef(String(initialValue));
|
|
8
|
+
const handleDebouncedChange = useDebouncedCallback(useMemo(() => {
|
|
9
|
+
if (!onDebouncedChange)
|
|
10
|
+
return;
|
|
11
|
+
return (current) => {
|
|
12
|
+
onDebouncedChange(current, prevValue.current);
|
|
13
|
+
prevValue.current = current;
|
|
14
|
+
};
|
|
15
|
+
}, [onDebouncedChange]), debounceTime);
|
|
16
|
+
const handleChange = useMemo(() => {
|
|
17
|
+
if (!handleDebouncedChange && !onChange)
|
|
18
|
+
return;
|
|
19
|
+
return (e) => {
|
|
20
|
+
const current = e.nativeEvent.text;
|
|
21
|
+
onChange?.(e);
|
|
22
|
+
handleDebouncedChange?.(current);
|
|
23
|
+
};
|
|
24
|
+
}, [handleDebouncedChange, onChange]);
|
|
25
|
+
return React.createElement(Input, { ...props, icon: Icons.Search, onChange: handleChange });
|
|
26
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { type Meta, type StoryObj } from "@storybook/react";
|
|
2
|
+
import { Search } from "./Search";
|
|
3
|
+
declare const meta: Meta<typeof Search>;
|
|
4
|
+
export default meta;
|
|
5
|
+
type Story = StoryObj<typeof Search>;
|
|
6
|
+
export declare const Default: Story;
|
|
7
|
+
export declare const WithInteraction: Story;
|
|
8
|
+
//# sourceMappingURL=Search.stories.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Search.stories.d.ts","sourceRoot":"","sources":["../../../../src/pre-ldls/components/Search/Search.stories.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,IAAI,EAAE,KAAK,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5D,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAOlC,QAAA,MAAM,IAAI,EAAE,IAAI,CAAC,OAAO,MAAM,CAU7B,CAAC;AACF,eAAe,IAAI,CAAC;AAEpB,KAAK,KAAK,GAAG,QAAQ,CAAC,OAAO,MAAM,CAAC,CAAC;AAErC,eAAO,MAAM,OAAO,EAAE,KAAU,CAAC;AAGjC,eAAO,MAAM,eAAe,EAAE,KAU7B,CAAC"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { Search } from "./Search";
|
|
2
|
+
import { expect, jest } from "@storybook/jest";
|
|
3
|
+
import { within, userEvent } from "@storybook/testing-library";
|
|
4
|
+
const onDebouncedChange = jest.fn();
|
|
5
|
+
const onChange = jest.fn();
|
|
6
|
+
const meta = {
|
|
7
|
+
component: Search,
|
|
8
|
+
title: "PreLdls/Components/Search",
|
|
9
|
+
tags: ["autodocs"],
|
|
10
|
+
args: {
|
|
11
|
+
debounceTime: 500,
|
|
12
|
+
placeholder: "Search",
|
|
13
|
+
onDebouncedChange,
|
|
14
|
+
onChange,
|
|
15
|
+
},
|
|
16
|
+
};
|
|
17
|
+
export default meta;
|
|
18
|
+
export const Default = {};
|
|
19
|
+
// Interaction Testing
|
|
20
|
+
export const WithInteraction = {
|
|
21
|
+
args: {},
|
|
22
|
+
controls: { expanded: true },
|
|
23
|
+
play: async ({ canvasElement }) => {
|
|
24
|
+
const canvas = within(canvasElement);
|
|
25
|
+
const input = canvas.getByRole("textbox");
|
|
26
|
+
await userEvent.type(input, "Write something");
|
|
27
|
+
await expect(input).toHaveValue("Write something");
|
|
28
|
+
},
|
|
29
|
+
};
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import React, { ReactNode } from "react";
|
|
2
|
+
import { TextStyle } from "react-native";
|
|
3
|
+
export declare const Tag: ({ textTransform, children, }: {
|
|
4
|
+
textTransform?: TextStyle["textTransform"];
|
|
5
|
+
children: ReactNode;
|
|
6
|
+
}) => React.JSX.Element;
|
|
7
|
+
//# sourceMappingURL=Tag.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Tag.d.ts","sourceRoot":"","sources":["../../../../src/pre-ldls/components/Tag/Tag.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAEzC,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAWzC,eAAO,MAAM,GAAG;oBAIE,SAAS,CAAC,eAAe,CAAC;cAChC,SAAS;uBAcpB,CAAC"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import styled from "styled-components/native";
|
|
3
|
+
import { Text } from "../../../components";
|
|
4
|
+
const Wrapper = styled.View `
|
|
5
|
+
padding: 1px 4px;
|
|
6
|
+
border-radius: 4px;
|
|
7
|
+
background-color: ${(props) => props.theme.colors.palette.neutral.c30};
|
|
8
|
+
flex-shrink: 0;
|
|
9
|
+
align-self: flex-start;
|
|
10
|
+
`;
|
|
11
|
+
export const Tag = ({ textTransform = "none", children, }) => {
|
|
12
|
+
return (React.createElement(Wrapper, { testID: "tag" },
|
|
13
|
+
React.createElement(Text, { color: "palette.neutral.c70", fontSize: "10px", lineHeight: "16px", textTransform: textTransform }, children)));
|
|
14
|
+
};
|
|
@@ -1,2 +1,8 @@
|
|
|
1
1
|
export * from "./Input/Input";
|
|
2
|
+
export * from "./AssetItem/AssetItem";
|
|
3
|
+
export * from "./AssetTypeList/AssetList";
|
|
4
|
+
export * from "./NetworkItem/NetworkItem";
|
|
5
|
+
export * from "./NetworkList/NetworkList";
|
|
6
|
+
export * from "./Tag/Tag";
|
|
7
|
+
export * from "./Search/Search";
|
|
2
8
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/pre-ldls/components/index.ts"],"names":[],"mappings":"AAAA,cAAc,eAAe,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/pre-ldls/components/index.ts"],"names":[],"mappings":"AAAA,cAAc,eAAe,CAAC;AAC9B,cAAc,uBAAuB,CAAC;AACtC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,2BAA2B,CAAC;AAC1C,cAAc,2BAA2B,CAAC;AAC1C,cAAc,WAAW,CAAC;AAC1B,cAAc,iBAAiB,CAAC"}
|
|
@@ -1 +1,7 @@
|
|
|
1
1
|
export * from "./Input/Input";
|
|
2
|
+
export * from "./AssetItem/AssetItem";
|
|
3
|
+
export * from "./AssetTypeList/AssetList";
|
|
4
|
+
export * from "./NetworkItem/NetworkItem";
|
|
5
|
+
export * from "./NetworkList/NetworkList";
|
|
6
|
+
export * from "./Tag/Tag";
|
|
7
|
+
export * from "./Search/Search";
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
/// <reference types="styled-components-react-native" />
|
|
2
|
+
import React from "react";
|
|
3
|
+
export declare const BalanceContainer: import("styled-components").StyledComponent<typeof import("react-native").View, import("styled-components").DefaultTheme, {}, never>;
|
|
4
|
+
export declare const leftElement: React.JSX.Element;
|
|
5
|
+
export declare const createRightElement: (discreetMode: boolean) => React.JSX.Element;
|
|
6
|
+
//# sourceMappingURL=sharedStoryBook.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sharedStoryBook.d.ts","sourceRoot":"","sources":["../../../src/pre-ldls/components/sharedStoryBook.tsx"],"names":[],"mappings":";AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAK1B,eAAO,MAAM,gBAAgB,sIAI5B,CAAC;AAEF,eAAO,MAAM,WAAW,mBAA2B,CAAC;AAEpD,eAAO,MAAM,kBAAkB,iBAAkB,OAAO,sBAoBvD,CAAC"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import styled from "styled-components/native";
|
|
3
|
+
import { Text } from "../../components";
|
|
4
|
+
import { Tag } from "./Tag/Tag";
|
|
5
|
+
export const BalanceContainer = styled.View `
|
|
6
|
+
flex-direction: column;
|
|
7
|
+
align-items: flex-end;
|
|
8
|
+
gap: 4px;
|
|
9
|
+
`;
|
|
10
|
+
export const leftElement = React.createElement(Tag, null, "1.34% APY");
|
|
11
|
+
export const createRightElement = (discreetMode) => (React.createElement(BalanceContainer, null,
|
|
12
|
+
React.createElement(Text, { fontSize: "14px", variant: "largeLineHeight", fontWeight: "semiBold", color: "palette.neutral.c100" }, discreetMode ? "$***" : "$5,969.83"),
|
|
13
|
+
React.createElement(Text, { fontSize: "12px", lineHeight: "16px", variant: "bodyLineHeight", fontWeight: "medium", color: "palette.neutral.c70" }, discreetMode ? "*** BTC" : "0.118 BTC")));
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/pre-ldls/hooks/index.ts"],"names":[],"mappings":"AAAA,cAAc,wBAAwB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "./useDebouncedCallback";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useDebouncedCallback.d.ts","sourceRoot":"","sources":["../../../src/pre-ldls/hooks/useDebouncedCallback.ts"],"names":[],"mappings":"AAEA,wBAAgB,oBAAoB,CAAC,CAAC,SAAS,OAAO,EAAE,EACtD,QAAQ,EAAE,CAAC,CAAC,GAAG,IAAI,EAAE,CAAC,KAAK,IAAI,CAAC,GAAG,SAAS,EAC5C,KAAK,CAAC,EAAE,MAAM,cAEuD,CAAC,KAAK,IAAI,cAehF"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { useEffect, useRef, useState } from "react";
|
|
2
|
+
export function useDebouncedCallback(callback, delay) {
|
|
3
|
+
const [debouncedCallback, setDebouncedCallback] = useState();
|
|
4
|
+
const timeout = useRef();
|
|
5
|
+
useEffect(() => {
|
|
6
|
+
if (!callback)
|
|
7
|
+
return setDebouncedCallback(undefined);
|
|
8
|
+
setDebouncedCallback(() => (...args) => {
|
|
9
|
+
clearTimeout(timeout.current);
|
|
10
|
+
timeout.current = setTimeout(() => callback(...args), delay);
|
|
11
|
+
});
|
|
12
|
+
return () => clearTimeout(timeout.current);
|
|
13
|
+
}, [callback, delay]);
|
|
14
|
+
return debouncedCallback;
|
|
15
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import type { Meta, StoryObj } from "@storybook/react";
|
|
3
|
+
import { jest } from "@storybook/jest";
|
|
4
|
+
declare const meta: Meta<typeof Template>;
|
|
5
|
+
export default meta;
|
|
6
|
+
type TemplateProps = {
|
|
7
|
+
delay: number;
|
|
8
|
+
callback1: typeof jest.fn;
|
|
9
|
+
callback2: typeof jest.fn;
|
|
10
|
+
};
|
|
11
|
+
declare function Template({ callback1, callback2, delay }: TemplateProps): React.JSX.Element;
|
|
12
|
+
export declare const Default: StoryObj<typeof Template>;
|
|
13
|
+
export declare const WithInteraction: StoryObj<typeof Template>;
|
|
14
|
+
//# sourceMappingURL=useDebouncedCallback.stories.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useDebouncedCallback.stories.d.ts","sourceRoot":"","sources":["../../../src/pre-ldls/hooks/useDebouncedCallback.stories.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAmB,MAAM,OAAO,CAAC;AACxC,OAAO,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAEvD,OAAO,EAAU,IAAI,EAAE,MAAM,iBAAiB,CAAC;AAM/C,QAAA,MAAM,IAAI,EAAE,IAAI,CAAC,OAAO,QAAQ,CAS/B,CAAC;AACF,eAAe,IAAI,CAAC;AAEpB,KAAK,aAAa,GAAG;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,OAAO,IAAI,CAAC,EAAE,CAAC;IAC1B,SAAS,EAAE,OAAO,IAAI,CAAC,EAAE,CAAC;CAC3B,CAAC;AACF,iBAAS,QAAQ,CAAC,EAAE,SAAS,EAAE,SAAS,EAAE,KAAK,EAAE,EAAE,aAAa,qBAoB/D;AAED,eAAO,MAAM,OAAO,EAAE,QAAQ,CAAC,OAAO,QAAQ,CAAM,CAAC;AAErD,eAAO,MAAM,eAAe,EAAE,QAAQ,CAAC,OAAO,QAAQ,CAUrD,CAAC"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import React, { useState } from "react";
|
|
2
|
+
import { useDebouncedCallback } from ".";
|
|
3
|
+
import { expect, jest } from "@storybook/jest";
|
|
4
|
+
import { within, userEvent } from "@storybook/testing-library";
|
|
5
|
+
const callback1 = jest.fn();
|
|
6
|
+
const callback2 = jest.fn();
|
|
7
|
+
const meta = {
|
|
8
|
+
component: Template,
|
|
9
|
+
title: "PreLdls/Hooks/useDebouncedCallback",
|
|
10
|
+
tags: ["!autodocs"],
|
|
11
|
+
args: {
|
|
12
|
+
delay: 1000,
|
|
13
|
+
callback1,
|
|
14
|
+
callback2,
|
|
15
|
+
},
|
|
16
|
+
};
|
|
17
|
+
export default meta;
|
|
18
|
+
function Template({ callback1, callback2, delay }) {
|
|
19
|
+
const [callback, setCallback] = useState(() => callback1);
|
|
20
|
+
const debouncedCallback = useDebouncedCallback(callback, delay);
|
|
21
|
+
const [value, setValue] = useState("");
|
|
22
|
+
return (React.createElement("div", null,
|
|
23
|
+
React.createElement("input", { type: "text", value: value, onChange: (event) => {
|
|
24
|
+
const value = event.target.value;
|
|
25
|
+
setValue(value);
|
|
26
|
+
debouncedCallback?.(value);
|
|
27
|
+
} }),
|
|
28
|
+
React.createElement("button", { onClick: () => setCallback(() => callback1) }, "Use Callback 1"),
|
|
29
|
+
React.createElement("button", { onClick: () => setCallback(() => callback2) }, "Use Callback 2")));
|
|
30
|
+
}
|
|
31
|
+
export const Default = {};
|
|
32
|
+
export const WithInteraction = {
|
|
33
|
+
args: {},
|
|
34
|
+
controls: { expanded: true },
|
|
35
|
+
play: async ({ canvasElement }) => {
|
|
36
|
+
const canvas = within(canvasElement);
|
|
37
|
+
const input = canvas.getByRole("textbox");
|
|
38
|
+
await userEvent.type(input, "Write something");
|
|
39
|
+
await expect(input).toHaveValue("Write something");
|
|
40
|
+
},
|
|
41
|
+
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ledgerhq/native-ui",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.40.0-nightly.0",
|
|
4
4
|
"description": "Ledger Live - Mobile UI",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -35,13 +35,13 @@
|
|
|
35
35
|
"lib/**/*"
|
|
36
36
|
],
|
|
37
37
|
"dependencies": {
|
|
38
|
-
"@ledgerhq/crypto-icons": "1.1.
|
|
38
|
+
"@ledgerhq/crypto-icons": "1.1.2",
|
|
39
39
|
"color": "^4.0.0",
|
|
40
40
|
"react-native-modal": "14.0.0-rc.1",
|
|
41
41
|
"rn-range-slider": "2.1.1",
|
|
42
42
|
"styled-system": "^5.1.5",
|
|
43
43
|
"@ledgerhq/crypto-icons-ui": "^1.16.0",
|
|
44
|
-
"@ledgerhq/icons-ui": "^0.
|
|
44
|
+
"@ledgerhq/icons-ui": "^0.13.0-nightly.0",
|
|
45
45
|
"@ledgerhq/ui-shared": "^0.3.0"
|
|
46
46
|
},
|
|
47
47
|
"peerDependencies": {
|