@rango-dev/ui 0.1.10-next.78 → 0.1.10-next.81

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 (40) hide show
  1. package/dist/components/Alert/Alert.d.ts +2 -2
  2. package/dist/components/Alert/Alert.stories.d.ts +2 -1
  3. package/dist/components/BestRoute/BestRoute.d.ts +4 -1
  4. package/dist/components/SecondaryPage/SecondaryPage.d.ts +3 -5
  5. package/dist/components/SelectableWalletList/SelectableWalletList.d.ts +1 -1
  6. package/dist/components/Settings/Settings.d.ts +2 -0
  7. package/dist/components/TextField/TextField.stories.d.ts +1 -1
  8. package/dist/containers/ConfirmSwap/ConfirmSwap.d.ts +8 -4
  9. package/dist/containers/ConfirmWallets/ConfirmWallets.d.ts +4 -2
  10. package/dist/containers/History/types.d.ts +1 -0
  11. package/dist/helper/index.d.ts +0 -5
  12. package/dist/types/wallet.d.ts +8 -0
  13. package/dist/ui.cjs.development.js +301 -263
  14. package/dist/ui.cjs.development.js.map +1 -1
  15. package/dist/ui.cjs.production.min.js +1 -1
  16. package/dist/ui.cjs.production.min.js.map +1 -1
  17. package/dist/ui.esm.js +301 -263
  18. package/dist/ui.esm.js.map +1 -1
  19. package/package.json +1 -1
  20. package/src/components/Alert/Alert.tsx +5 -9
  21. package/src/components/BestRoute/BestRoute.tsx +55 -21
  22. package/src/components/BlockchainSelector/BlockchainSelector.tsx +13 -11
  23. package/src/components/LiquiditySourceList/LiquiditySourceList.tsx +21 -20
  24. package/src/components/LiquiditySourcesSelector/LiquiditySourcesSelector.tsx +3 -2
  25. package/src/components/Radio/Radio.tsx +1 -0
  26. package/src/components/SecondaryPage/SecondaryPage.tsx +5 -6
  27. package/src/components/SelectableWalletList/SelectableWalletList.tsx +1 -1
  28. package/src/components/Settings/Settings.tsx +26 -13
  29. package/src/components/SwapContainer/SwapContainer.tsx +1 -0
  30. package/src/components/Switch/Switch.tsx +1 -0
  31. package/src/components/TokenSelector/TokenSelector.tsx +3 -2
  32. package/src/containers/ConfirmSwap/ConfirmSwap.tsx +92 -54
  33. package/src/containers/ConfirmWallets/ConfirmWallets.tsx +66 -62
  34. package/src/containers/History/History.tsx +3 -2
  35. package/src/containers/History/types.tsx +10 -1
  36. package/src/containers/SwapHistory/SwapHistory.tsx +87 -95
  37. package/src/helper/index.ts +1 -22
  38. package/src/types/wallet.ts +9 -0
  39. package/dist/containers/ConfirmWallets/types.d.ts +0 -9
  40. package/src/containers/ConfirmWallets/types.ts +0 -10
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rango-dev/ui",
3
- "version": "0.1.10-next.78",
3
+ "version": "0.1.10-next.81",
4
4
  "license": "MIT",
5
5
  "main": "dist/index.js",
6
6
  "typings": "dist/index.d.ts",
@@ -1,4 +1,4 @@
1
- import React from 'react';
1
+ import React, { PropsWithChildren } from 'react';
2
2
  import { CheckCircleIcon, InfoCircleIcon, WarningIcon } from '../Icon';
3
3
  import { Typography } from '../Typography';
4
4
  import { darkTheme, styled } from '../../theme';
@@ -30,10 +30,7 @@ const MainContainer = styled('div', {
30
30
  },
31
31
  });
32
32
 
33
- const ContentContainer = styled('div', {
34
- display: 'flex',
35
- flexDirection: 'column',
36
- });
33
+ const ContentContainer = styled('div', {});
37
34
 
38
35
  const TitleContainer = styled('div', {
39
36
  marginBottom: '$8',
@@ -49,12 +46,11 @@ const StyledTypography = styled(Typography, {
49
46
 
50
47
  export interface PropTypes {
51
48
  type: 'primary' | 'secondary' | 'success' | 'warning' | 'error';
52
- description: string;
53
49
  title?: string;
54
50
  }
55
51
 
56
- export function Alert(props: PropTypes) {
57
- const { type, description, title } = props;
52
+ export function Alert(props: PropsWithChildren<PropTypes>) {
53
+ const { type, children, title } = props;
58
54
 
59
55
  const showIcon = (
60
56
  ['error', 'success', 'warning'] as PropTypes['type'][]
@@ -75,7 +71,7 @@ export function Alert(props: PropTypes) {
75
71
  <StyledTypography variant="h6">{title}</StyledTypography>
76
72
  </TitleContainer>
77
73
  )}
78
- <StyledTypography variant="body2">{description}</StyledTypography>
74
+ {children}
79
75
  </ContentContainer>
80
76
  </MainContainer>
81
77
  );
@@ -2,8 +2,7 @@ import React, { Fragment, PropsWithChildren } from 'react';
2
2
  import { GasIcon, TimeIcon } from '../../components/Icon';
3
3
  import { StepDetail } from '../../components/StepDetail';
4
4
  import { Typography } from '../../components/Typography';
5
- import { rawFees, secondsToString, totalArrivalTime } from '../../helper';
6
- import { styled } from '../../theme';
5
+ import { keyframes, styled } from '../../theme';
7
6
  import { Skeleton } from '../Skeleton';
8
7
  import { Spinner } from '../Spinner';
9
8
  import { BestRouteResponse } from 'rango-sdk';
@@ -77,6 +76,18 @@ const ArrowRight = styled('div', {
77
76
  borderLeft: '5px solid $foreground',
78
77
  });
79
78
 
79
+ const pulse = keyframes({
80
+ '0%': {
81
+ opacity: 1,
82
+ },
83
+ '50%': {
84
+ opacity: 0.3,
85
+ },
86
+ '100%': {
87
+ opacity: 1,
88
+ },
89
+ });
90
+
80
91
  const GasContainer = styled('div', {
81
92
  backgroundColor: '$neutrals300',
82
93
  borderRadius: '5px',
@@ -91,6 +102,30 @@ const GasContainer = styled('div', {
91
102
  margin: '$8',
92
103
  },
93
104
  });
105
+
106
+ const FeeContainer = styled('div', {
107
+ display: 'flex',
108
+ flexDirection: 'column',
109
+ alignItems: 'center',
110
+ variants: {
111
+ warning: {
112
+ true: {
113
+ animation: `${pulse} 2s ease-in-out infinite`,
114
+ },
115
+ },
116
+ },
117
+ });
118
+
119
+ const TotalFee = styled(Typography, {
120
+ variants: {
121
+ warning: {
122
+ true: {
123
+ color: '$warning300',
124
+ },
125
+ },
126
+ },
127
+ });
128
+
94
129
  const SkeletonContainer = styled('div', {
95
130
  padding: '$4',
96
131
  '@md': {
@@ -105,22 +140,14 @@ const SwapperContainer = styled('div', {
105
140
 
106
141
  export interface PropTypes {
107
142
  data: BestRouteResponse | null;
143
+ totalFee: string;
144
+ feeWarning: boolean;
145
+ totalTime: string;
108
146
  loading?: boolean;
109
147
  error?: string;
110
148
  }
111
- export function BestRoute({
112
- data,
113
- loading,
114
- error,
115
- }: PropsWithChildren<PropTypes>) {
116
- let fee,
117
- time: string = '';
118
-
119
- if (!!data) {
120
- fee = rawFees(data);
121
- time = secondsToString(totalArrivalTime(data));
122
- }
123
-
149
+ export function BestRoute(props: PropsWithChildren<PropTypes>) {
150
+ const { data, loading, error, totalFee, feeWarning, totalTime } = props;
124
151
  return (
125
152
  <Container>
126
153
  {loading ? (
@@ -129,16 +156,23 @@ export function BestRoute({
129
156
  </SkeletonContainer>
130
157
  ) : (
131
158
  <GasContainer>
132
- <GasIcon size={20} />
133
- <Typography mt={4} align="center" variant="caption">
134
- {error && '-'}
135
- {!!data && `$${fee}`}
136
- </Typography>
159
+ <FeeContainer warning={feeWarning}>
160
+ <GasIcon size={20} color={feeWarning ? 'warning' : undefined} />
161
+ <TotalFee
162
+ mt={4}
163
+ align="center"
164
+ variant="caption"
165
+ warning={feeWarning}
166
+ >
167
+ {error && '-'}
168
+ {!!data && `$${totalFee}`}
169
+ </TotalFee>
170
+ </FeeContainer>
137
171
  <HR />
138
172
  <TimeIcon size={20} />
139
173
  <Typography mt={4} align="center" variant="caption">
140
174
  {error && '-'}
141
- {!!data && `~${time}m`}
175
+ {!!data && `~${totalTime}m`}
142
176
  </Typography>
143
177
  </GasContainer>
144
178
  )}
@@ -7,6 +7,7 @@ import { Spinner } from '../Spinner';
7
7
  import { styled } from '../../theme';
8
8
  import { CSSProperties } from '@stitches/react';
9
9
  import { containsText } from '../../helper';
10
+ import { Typography } from '../Typography';
10
11
 
11
12
  const ListContainer = styled('div', {
12
13
  height: '450px',
@@ -58,20 +59,22 @@ export function BlockchainSelector(props: PropTypes) {
58
59
  textFieldPlaceholder="Search Blockchain By Name"
59
60
  title={`Select ${type} Network`}
60
61
  onBack={onBack}
61
- Content={({ searchedFor }) => {
62
+ >
63
+ {(searchedFor) => {
62
64
  const filteredBlockchains = filterBlockchains(list, searchedFor);
63
65
  return (
64
- <ListContainer style={listContainerStyle}>
66
+ <ListContainer style={listContainerStyle} key="1">
65
67
  {loadingStatus === 'loading' && (
66
68
  <div>
67
69
  <Spinner size={24} />
68
70
  </div>
69
71
  )}
70
72
  {loadingStatus === 'failed' && (
71
- <Alert
72
- type="error"
73
- description="Error connecting server, please reload the app and try again"
74
- />
73
+ <Alert type="error">
74
+ <Typography variant="body2">
75
+ Error connecting server, please reload the app and try again
76
+ </Typography>
77
+ </Alert>
75
78
  )}
76
79
  {loadingStatus === 'success' && (
77
80
  <>
@@ -84,16 +87,15 @@ export function BlockchainSelector(props: PropTypes) {
84
87
  onChange={onChange}
85
88
  />
86
89
  ) : (
87
- <Alert
88
- type="secondary"
89
- description={`${searchedFor} not found`}
90
- />
90
+ <Alert type="secondary">
91
+ <Typography variant="body2">{`${searchedFor} not found`}</Typography>
92
+ </Alert>
91
93
  )}
92
94
  </>
93
95
  )}
94
96
  </ListContainer>
95
97
  );
96
98
  }}
97
- />
99
+ </SecondaryPage>
98
100
  );
99
101
  }
@@ -1,5 +1,5 @@
1
1
  import { CSSProperties } from '@stitches/react';
2
- import React, { useState } from 'react';
2
+ import React, { useEffect, useState } from 'react';
3
3
  import { styled } from '../../theme';
4
4
  import { LiquiditySource } from '../../types/meta';
5
5
  import { Button } from '../Button/Button';
@@ -21,6 +21,7 @@ const groupLiquiditySources = (
21
21
 
22
22
  const LiquiditySourceType = styled(Typography, {
23
23
  position: 'sticky',
24
+ display: 'block',
24
25
  top: '0',
25
26
  marginTop: '$8',
26
27
  marginBottom: '$8',
@@ -55,14 +56,16 @@ export function LiquiditySourceList(props: PropTypes) {
55
56
  if (clickedItem.selected) return [...prevState, clickedItem];
56
57
  return prevState.filter((item) => item.title != clickedItem.title);
57
58
  });
58
- setTimeout(() => {
59
- onChange(clickedItem);
60
- }, 200);
59
+ onChange(clickedItem);
61
60
  };
62
61
 
63
62
  const isSelected = (liquiditySource: LiquiditySource) =>
64
63
  !!selected.find((item) => liquiditySource.title === item.title);
65
64
 
65
+ useEffect(() => {
66
+ setSelected(list.filter((item) => item.selected));
67
+ }, [list]);
68
+
66
69
  return (
67
70
  <div style={{ height: '450px', ...listContainerStyle }}>
68
71
  <div>
@@ -102,19 +105,17 @@ const LiquiditySourceItem = ({
102
105
  liquiditySource: LiquiditySource;
103
106
  selected: boolean;
104
107
  onChange: (clickedItem: LiquiditySource) => void;
105
- }) => {
106
- return (
107
- <Button
108
- size="large"
109
- align="start"
110
- variant="outlined"
111
- prefix={<LiquidityImage src={liquiditySource.logo} />}
112
- suffix={<Switch checked={selected} />}
113
- style={{ marginBottom: '12px' }}
114
- type={selected ? 'primary' : undefined}
115
- onClick={onChange.bind(null, liquiditySource)}
116
- >
117
- <Typography variant="body1">{liquiditySource.title}</Typography>
118
- </Button>
119
- );
120
- };
108
+ }) => (
109
+ <Button
110
+ size="large"
111
+ align="start"
112
+ variant="outlined"
113
+ prefix={<LiquidityImage src={liquiditySource.logo} />}
114
+ suffix={<Switch checked={selected} />}
115
+ style={{ marginBottom: '12px' }}
116
+ type={selected ? 'primary' : undefined}
117
+ onClick={onChange.bind(null, liquiditySource)}
118
+ >
119
+ <Typography variant="body1">{liquiditySource.title}</Typography>
120
+ </Button>
121
+ );
@@ -43,13 +43,14 @@ export function LiquiditySourcesSelector(props: PropTypes) {
43
43
  }
44
44
  hasHeader={hasHeader}
45
45
  onBack={onBack}
46
- Content={({ searchedFor }) => (
46
+ >
47
+ {(searchedFor) => (
47
48
  <LiquiditySourceList
48
49
  listContainerStyle={listContainerStyle}
49
50
  list={filterLiquiditySources(list, searchedFor)}
50
51
  onChange={onChange}
51
52
  />
52
53
  )}
53
- />
54
+ </SecondaryPage>
54
55
  );
55
56
  }
@@ -26,6 +26,7 @@ const ItemContainer = styled('div', {
26
26
  marginRight: '$8',
27
27
  });
28
28
  const StyledItem = styled(RadioGroup.Item, {
29
+ padding: '0',
29
30
  backgroundColor: '$neutrals300',
30
31
  width: '20px',
31
32
  height: '20px',
@@ -1,4 +1,4 @@
1
- import React, { useState } from 'react';
1
+ import React, { ReactNode, useState } from 'react';
2
2
  import { styled } from '../../theme';
3
3
  import { AngleLeftIcon, SearchIcon } from '../Icon';
4
4
  import { TextField } from '../TextField/TextField';
@@ -7,12 +7,12 @@ import { Typography } from '../Typography';
7
7
  export type PropTypes = (
8
8
  | {
9
9
  textField: true;
10
- Content: React.ElementType<{ searchedFor: string }>;
10
+ children?: (searchedFor: string) => ReactNode;
11
11
  textFieldPlaceholder: string;
12
12
  }
13
13
  | {
14
14
  textField: false;
15
- Content: React.ReactNode;
15
+ children?: ReactNode;
16
16
  }
17
17
  ) & {
18
18
  title?: string;
@@ -84,10 +84,9 @@ export function SecondaryPage(props: PropTypes) {
84
84
  </div>
85
85
  )}
86
86
  <ContentContainer>
87
- {props.textField && <props.Content searchedFor={searchedFor} />}
88
- {!props.textField && props.Content}
87
+ {props.textField && props.children?.(searchedFor)}
88
+ {!props.textField && props.children}
89
89
  </ContentContainer>
90
-
91
90
  {Footer}
92
91
  </Container>
93
92
  );
@@ -1,6 +1,6 @@
1
1
  import React, { PropsWithChildren, useEffect, useState } from 'react';
2
- import { SelectableWallet } from '../../containers/ConfirmWallets/types';
3
2
  import { styled } from '../../theme';
3
+ import { SelectableWallet } from '../../types';
4
4
  import { Typography } from '../Typography';
5
5
 
6
6
  const Row = styled('div', {
@@ -7,6 +7,7 @@ import { Chip } from '../Chip';
7
7
  import { LiquiditySource } from '../../types/meta';
8
8
  import { TextField } from '../TextField';
9
9
  import { Radio } from '../Radio';
10
+ import { Switch } from '../Switch';
10
11
 
11
12
  const BaseContainer = styled('div', {
12
13
  borderRadius: '$5',
@@ -14,10 +15,12 @@ const BaseContainer = styled('div', {
14
15
  padding: '$16',
15
16
  });
16
17
 
18
+ const Title = styled(Typography, { marginBottom: '$16' });
19
+
17
20
  const SlippageChipsContainer = styled('div', {
18
- display: 'flex',
19
- flexWrap: 'wrap',
20
- marginTop: '$16',
21
+ display: 'grid',
22
+ rowGap: '$16',
23
+ gridTemplateColumns: 'repeat(auto-fill, 64px)',
21
24
  });
22
25
 
23
26
  const LiquiditySourceContainer = styled(BaseContainer, {
@@ -26,8 +29,13 @@ const LiquiditySourceContainer = styled(BaseContainer, {
26
29
  marginTop: '$32',
27
30
  cursor: 'pointer',
28
31
  });
32
+ const InfiniteContainer = styled(BaseContainer, {
33
+ display: 'flex',
34
+ justifyContent: 'space-between',
35
+ marginTop: '$32',
36
+ });
29
37
 
30
- const StyledAngleRight = styled(AngleRightIcon, { marginLeft: '8px' });
38
+ const StyledAngleRight = styled(AngleRightIcon, { marginLeft: '$8' });
31
39
 
32
40
  const LiquiditySourceNumber = styled('div', {
33
41
  display: 'flex',
@@ -55,6 +63,8 @@ export interface PropTypes {
55
63
  selectedTheme: Theme;
56
64
  onThemeChange: (theme: Theme) => void;
57
65
  onBack: () => void;
66
+ infiniteApprove: boolean;
67
+ toggleInfiniteApprove: (infinite: boolean) => void;
58
68
  }
59
69
 
60
70
  export function Settings(props: PropTypes) {
@@ -71,6 +81,8 @@ export function Settings(props: PropTypes) {
71
81
  minSlippage,
72
82
  selectedTheme,
73
83
  onThemeChange,
84
+ toggleInfiniteApprove,
85
+ infiniteApprove,
74
86
  } = props;
75
87
 
76
88
  const [selectedSlippage, setSelectedSlippage] = useState(
@@ -85,7 +97,7 @@ export function Settings(props: PropTypes) {
85
97
  const PageContent = (
86
98
  <>
87
99
  <BaseContainer>
88
- <Typography variant="body1">Slippage tolerance per swap</Typography>
100
+ <Title variant="body1">Slippage tolerance per swap</Title>
89
101
  <SlippageChipsContainer>
90
102
  {slippages.map((slippage, index) => (
91
103
  <Chip
@@ -126,7 +138,7 @@ export function Settings(props: PropTypes) {
126
138
  </SlippageChipsContainer>
127
139
  </BaseContainer>
128
140
  <ThemesContainer>
129
- <Typography variant="body2">Theme</Typography>
141
+ <Title variant="body2">Theme</Title>
130
142
  <Radio
131
143
  defaultValue={selectedTheme}
132
144
  options={[
@@ -139,9 +151,13 @@ export function Settings(props: PropTypes) {
139
151
  style={{ marginTop: '$24' }}
140
152
  />
141
153
  </ThemesContainer>
154
+ <InfiniteContainer>
155
+ <Typography variant="body1">Infinite Approval</Typography>
156
+ <Switch checked={infiniteApprove} onChange={toggleInfiniteApprove} />
157
+ </InfiniteContainer>
142
158
  <LiquiditySourceContainer onClick={onLiquiditySourcesClick}>
143
159
  <Typography variant="body1">Liquidity Sources</Typography>
144
- <LiquiditySourceNumber onClick={onLiquiditySourcesClick}>
160
+ <LiquiditySourceNumber>
145
161
  <Typography variant="body2">{`( ${selectedLiquiditySources.length} / ${liquiditySources.length} )`}</Typography>
146
162
  <StyledAngleRight />
147
163
  </LiquiditySourceNumber>
@@ -150,11 +166,8 @@ export function Settings(props: PropTypes) {
150
166
  );
151
167
 
152
168
  return (
153
- <SecondaryPage
154
- title="Settings"
155
- textField={false}
156
- Content={PageContent}
157
- onBack={onBack}
158
- />
169
+ <SecondaryPage title="Settings" textField={false} onBack={onBack}>
170
+ {PageContent}
171
+ </SecondaryPage>
159
172
  );
160
173
  }
@@ -14,6 +14,7 @@ const MainContainer = styled('div', {
14
14
  flexDirection: 'column',
15
15
  alignItems: 'end',
16
16
  padding: '$16 $24',
17
+ boxSizing: 'border-box',
17
18
  });
18
19
 
19
20
  const ContentContainer = styled('div', {
@@ -13,6 +13,7 @@ const StyledSwitchRoot = styled(RadixSwitch.Root, {
13
13
  borderColor: '$neutrals400',
14
14
  borderRadius: '99999px',
15
15
  position: 'relative',
16
+ padding: '0',
16
17
  cursor: 'pointer',
17
18
  '&[data-state="checked"]': {
18
19
  backgroundColor: '$primary100',
@@ -33,7 +33,8 @@ export function TokenSelector(props: PropTypes) {
33
33
  title={`Select ${type} Token`}
34
34
  hasHeader={hasHeader}
35
35
  onBack={onBack}
36
- Content={({ searchedFor }) => (
36
+ >
37
+ {(searchedFor) => (
37
38
  <TokenList
38
39
  searchedText={searchedFor}
39
40
  list={list}
@@ -43,6 +44,6 @@ export function TokenSelector(props: PropTypes) {
43
44
  onChange={onChange}
44
45
  />
45
46
  )}
46
- />
47
+ </SecondaryPage>
47
48
  );
48
49
  }