@ledgerhq/native-ui 0.39.0 → 0.40.0-nightly.1

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.
Files changed (59) hide show
  1. package/lib/components/Form/TabSelector/index.d.ts.map +1 -1
  2. package/lib/components/Form/TabSelector/index.js +1 -1
  3. package/lib/pre-ldls/components/AssetItem/AssetItem.d.ts +14 -0
  4. package/lib/pre-ldls/components/AssetItem/AssetItem.d.ts.map +1 -0
  5. package/lib/pre-ldls/components/AssetItem/AssetItem.js +50 -0
  6. package/lib/pre-ldls/components/AssetItem/AssetItem.stories.d.ts +11 -0
  7. package/lib/pre-ldls/components/AssetItem/AssetItem.stories.d.ts.map +1 -0
  8. package/lib/pre-ldls/components/AssetItem/AssetItem.stories.js +55 -0
  9. package/lib/pre-ldls/components/AssetTypeList/AssetList.d.ts +10 -0
  10. package/lib/pre-ldls/components/AssetTypeList/AssetList.d.ts.map +1 -0
  11. package/lib/pre-ldls/components/AssetTypeList/AssetList.js +36 -0
  12. package/lib/pre-ldls/components/AssetTypeList/AssetList.stories.d.ts +10 -0
  13. package/lib/pre-ldls/components/AssetTypeList/AssetList.stories.d.ts.map +1 -0
  14. package/lib/pre-ldls/components/AssetTypeList/AssetList.stories.js +62 -0
  15. package/lib/pre-ldls/components/CryptoIcon/CryptoIcon.d.ts +1 -1
  16. package/lib/pre-ldls/components/CryptoIcon/CryptoIcon.d.ts.map +1 -1
  17. package/lib/pre-ldls/components/CryptoIcon/CryptoIcon.js +1 -1
  18. package/lib/pre-ldls/components/CryptoIcon/CryptoIcon.stories.d.ts.map +1 -1
  19. package/lib/pre-ldls/components/CryptoIcon/CryptoIcon.stories.js +1 -0
  20. package/lib/pre-ldls/components/NetworkItem/NetworkItem.d.ts +14 -0
  21. package/lib/pre-ldls/components/NetworkItem/NetworkItem.d.ts.map +1 -0
  22. package/lib/pre-ldls/components/NetworkItem/NetworkItem.js +46 -0
  23. package/lib/pre-ldls/components/NetworkItem/NetworkItem.stories.d.ts +10 -0
  24. package/lib/pre-ldls/components/NetworkItem/NetworkItem.stories.d.ts.map +1 -0
  25. package/lib/pre-ldls/components/NetworkItem/NetworkItem.stories.js +32 -0
  26. package/lib/pre-ldls/components/NetworkList/NetworkList.d.ts +10 -0
  27. package/lib/pre-ldls/components/NetworkList/NetworkList.d.ts.map +1 -0
  28. package/lib/pre-ldls/components/NetworkList/NetworkList.js +35 -0
  29. package/lib/pre-ldls/components/NetworkList/NetwrokList.stories.d.ts +8 -0
  30. package/lib/pre-ldls/components/NetworkList/NetwrokList.stories.d.ts.map +1 -0
  31. package/lib/pre-ldls/components/NetworkList/NetwrokList.stories.js +30 -0
  32. package/lib/pre-ldls/components/Search/Search.d.ts +9 -0
  33. package/lib/pre-ldls/components/Search/Search.d.ts.map +1 -0
  34. package/lib/pre-ldls/components/Search/Search.js +26 -0
  35. package/lib/pre-ldls/components/Search/Search.stories.d.ts +8 -0
  36. package/lib/pre-ldls/components/Search/Search.stories.d.ts.map +1 -0
  37. package/lib/pre-ldls/components/Search/Search.stories.js +29 -0
  38. package/lib/pre-ldls/components/Tag/Tag.d.ts +7 -0
  39. package/lib/pre-ldls/components/Tag/Tag.d.ts.map +1 -0
  40. package/lib/pre-ldls/components/Tag/Tag.js +14 -0
  41. package/lib/pre-ldls/components/index.d.ts +6 -0
  42. package/lib/pre-ldls/components/index.d.ts.map +1 -1
  43. package/lib/pre-ldls/components/index.js +6 -0
  44. package/lib/pre-ldls/components/sharedStoryBook.d.ts +6 -0
  45. package/lib/pre-ldls/components/sharedStoryBook.d.ts.map +1 -0
  46. package/lib/pre-ldls/components/sharedStoryBook.js +13 -0
  47. package/lib/pre-ldls/hooks/index.d.ts +2 -0
  48. package/lib/pre-ldls/hooks/index.d.ts.map +1 -0
  49. package/lib/pre-ldls/hooks/index.js +1 -0
  50. package/lib/pre-ldls/hooks/useDebouncedCallback.d.ts +2 -0
  51. package/lib/pre-ldls/hooks/useDebouncedCallback.d.ts.map +1 -0
  52. package/lib/pre-ldls/hooks/useDebouncedCallback.js +15 -0
  53. package/lib/pre-ldls/hooks/useDebouncedCallback.stories.d.ts +14 -0
  54. package/lib/pre-ldls/hooks/useDebouncedCallback.stories.d.ts.map +1 -0
  55. package/lib/pre-ldls/hooks/useDebouncedCallback.stories.js +41 -0
  56. package/lib/pre-ldls/libs/index.d.ts +2 -1
  57. package/lib/pre-ldls/libs/index.d.ts.map +1 -1
  58. package/lib/pre-ldls/libs/index.js +13 -6
  59. 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,CAyEnC"}
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 { CryptoIcon as Icon } from "@ledgerhq/crypto-icons";
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,EAAE,UAAU,IAAI,IAAI,EAAE,MAAM,wBAAwB,CAAC;AAE5D,wBAAgB,UAAU,CAAC,KAAK,EAAE,UAAU,CAAC,OAAO,IAAI,CAAC,CAAC,CAAC,CAAC,qBAE3D"}
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,5 +1,5 @@
1
1
  import React from "react";
2
- import { CryptoIcon as Icon } from "@ledgerhq/crypto-icons";
2
+ import Icon from "@ledgerhq/crypto-icons/native";
3
3
  export function CryptoIcon(props) {
4
4
  return React.createElement(Icon, { ...props });
5
5
  }
@@ -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,CAmBjC,CAAC;AACF,eAAe,IAAI,CAAC;AAEpB,KAAK,KAAK,GAAG,QAAQ,CAAC,OAAO,UAAU,CAAC,CAAC;AAEzC,eAAO,MAAM,OAAO,EAAE,KAErB,CAAC"}
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"}
@@ -7,6 +7,7 @@ const meta = {
7
7
  ledgerId: "bitcoin",
8
8
  ticker: "BTC",
9
9
  size: 56,
10
+ backgroundColor: "red",
10
11
  network: "",
11
12
  },
12
13
  argTypes: {
@@ -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,2 @@
1
+ export * from "./useDebouncedCallback";
2
+ //# sourceMappingURL=index.d.ts.map
@@ -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,2 @@
1
+ export declare function useDebouncedCallback<T extends unknown[]>(callback: ((...args: T) => void) | undefined, delay?: number): ((...args: T) => void) | undefined;
2
+ //# sourceMappingURL=useDebouncedCallback.d.ts.map
@@ -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
+ };
@@ -26,6 +26,7 @@ declare const overrideColor: {
26
26
  export type Tokens = Record<string, string | number>;
27
27
  type ColorToken = `colors-${keyof ModeColors}` | `colors-${keyof typeof overrideColor.light}` | `colors-${keyof typeof overrideColor.dark}`;
28
28
  type OtherToken = keyof (SpacingScale & typeof overrideOther);
29
- export declare const useTokens: ((theme: "dark" | "light", usedTokens: Array<ColorToken | OtherToken>) => Tokens) & import("lodash").MemoizedFunction;
29
+ type Theme = "dark" | "light";
30
+ export declare const useTokens: ((theme: Theme, usedTokens: Array<ColorToken | OtherToken>) => Tokens) & import("lodash").MemoizedFunction;
30
31
  export {};
31
32
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/pre-ldls/libs/index.ts"],"names":[],"mappings":";AACA,OAAO,EAAe,UAAU,EAAW,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAGjF,QAAA,MAAM,aAAa;;;;;;;;;;;CAWT,CAAC;AAEX,QAAA,MAAM,aAAa;;;;;;;;;;CAUT,CAAC;AAEX,MAAM,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC,CAAC;AAErD,KAAK,UAAU,GACX,UAAU,MAAM,UAAU,EAAE,GAC5B,UAAU,MAAM,OAAO,aAAa,CAAC,KAAK,EAAE,GAC5C,UAAU,MAAM,OAAO,aAAa,CAAC,IAAI,EAAE,CAAC;AAChD,KAAK,UAAU,GAAG,MAAM,CAAC,YAAY,GAAG,OAAO,aAAa,CAAC,CAAC;AAM9D,eAAO,MAAM,SAAS,WACZ,MAAM,GAAG,OAAO,cAAc,MAAM,UAAU,GAAG,UAAU,CAAC,gDA2BrE,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/pre-ldls/libs/index.ts"],"names":[],"mappings":";AACA,OAAO,EAAe,UAAU,EAAW,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAGjF,QAAA,MAAM,aAAa;;;;;;;;;;;CAWT,CAAC;AAEX,QAAA,MAAM,aAAa;;;;;;;;;;CAUT,CAAC;AAEX,MAAM,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC,CAAC;AACrD,KAAK,UAAU,GACX,UAAU,MAAM,UAAU,EAAE,GAC5B,UAAU,MAAM,OAAO,aAAa,CAAC,KAAK,EAAE,GAC5C,UAAU,MAAM,OAAO,aAAa,CAAC,IAAI,EAAE,CAAC;AAEhD,KAAK,UAAU,GAAG,MAAM,CAAC,YAAY,GAAG,OAAO,aAAa,CAAC,CAAC;AAC9D,KAAK,KAAK,GAAG,MAAM,GAAG,OAAO,CAAC;AAY9B,eAAO,MAAM,SAAS,WACZ,KAAK,cAAc,MAAM,UAAU,GAAG,UAAU,CAAC,gDA2B1D,CAAC"}
@@ -1,6 +1,6 @@
1
1
  import memoize from "lodash/memoize";
2
2
  import { dark, light, spacing } from "./design-tokens";
3
- // Override manquants
3
+ // Missing overrides
4
4
  const overrideOther = {
5
5
  "radius-s": "8px",
6
6
  "radius-xs": "4px",
@@ -27,19 +27,24 @@ const overrideColor = {
27
27
  function pxToNumber(value) {
28
28
  return Number(value.replace("px", ""));
29
29
  }
30
+ function getThemeColors(theme) {
31
+ const baseColors = theme === "dark" ? dark : light;
32
+ const overrides = overrideColor[theme];
33
+ return { ...baseColors, ...overrides };
34
+ }
30
35
  export const useTokens = memoize((theme, usedTokens) => {
36
+ if (!usedTokens.length)
37
+ return {};
31
38
  const usedSet = new Set(usedTokens);
32
- const colors = {
33
- dark: { ...dark, ...overrideColor.dark },
34
- light: { ...light, ...overrideColor.light },
35
- }[theme];
36
39
  const tokens = {};
40
+ const colors = getThemeColors(theme);
37
41
  Object.entries(colors).forEach(([key, value]) => {
38
42
  const colorKey = `colors-${key}`;
39
43
  if (usedSet.has(colorKey)) {
40
44
  tokens[colorKey] = value;
41
45
  }
42
46
  });
47
+ // Add spacing and other tokens
43
48
  [spacing, overrideOther].forEach((obj) => {
44
49
  Object.entries(obj).forEach(([key, value]) => {
45
50
  if (usedSet.has(key)) {
@@ -48,4 +53,6 @@ export const useTokens = memoize((theme, usedTokens) => {
48
53
  });
49
54
  });
50
55
  return tokens;
51
- });
56
+ },
57
+ // Simple cache key
58
+ (theme, usedTokens) => `${theme}-${usedTokens.sort().join(",")}`);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ledgerhq/native-ui",
3
- "version": "0.39.0",
3
+ "version": "0.40.0-nightly.1",
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.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.12.0",
44
+ "@ledgerhq/icons-ui": "^0.13.0-nightly.0",
45
45
  "@ledgerhq/ui-shared": "^0.3.0"
46
46
  },
47
47
  "peerDependencies": {