diff --git a/ui/pages/import-token/README.mdx b/ui/pages/import-token/README.mdx new file mode 100644 index 000000000..83daea8ff --- /dev/null +++ b/ui/pages/import-token/README.mdx @@ -0,0 +1,31 @@ +import { Story, Canvas, ArgsTable } from '@storybook/addon-docs'; + +import ImportToken from './import-token.component'; + +import testData from '../../../.storybook/test-data'; +import configureStore from '../../store/store'; +const store = configureStore(testData); +const { metamask } = store.getState(); + +export const PersonalAddress = () => {metamask.selectedAddress} + +# ImportToken + +The `ImportToken` component allows a user to import custom tokens in one of two ways: +1. By searching for one +2. By importing one by `Token Contract Address` + + + + + +## Example inputs + +An example input that works, to enable the `Add Custom Token` button is `0xAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA`. + +### Personal address error +To show the personal address detected error, input the address in the `Token Contract Address` field. + +## Component API + + diff --git a/ui/pages/import-token/import-token.component.js b/ui/pages/import-token/import-token.component.js index 33e0a0bb2..647829575 100644 --- a/ui/pages/import-token/import-token.component.js +++ b/ui/pages/import-token/import-token.component.js @@ -36,19 +36,77 @@ class ImportToken extends Component { }; static propTypes = { + /** + * History object of the router. + */ history: PropTypes.object, + + /** + * Set the state of `pendingTokens`, called when adding a token. + */ setPendingTokens: PropTypes.func, + + /** + * The current list of pending tokens to be added. + */ pendingTokens: PropTypes.object, + + /** + * Clear the list of pending tokens. Called when closing the modal. + */ clearPendingTokens: PropTypes.func, + + /** + * The list of already added tokens. + */ tokens: PropTypes.array, + + /** + * The identities/accounts that are currently added to the wallet. + */ identities: PropTypes.object, + + /** + * Boolean flag that shows/hides the search tab. + */ showSearchTab: PropTypes.bool.isRequired, + + /** + * The most recent overview page route, which is 'navigated' to when closing the modal. + */ mostRecentOverviewPage: PropTypes.string.isRequired, + + /** + * The active chainId in use. + */ chainId: PropTypes.string, + + /** + * The rpc preferences to use for the current provider. + */ rpcPrefs: PropTypes.object, + + /** + * The list of tokens available for search. + */ tokenList: PropTypes.object, + + /** + * Boolean flag indicating whether token detection is enabled or not. + * When disabled, shows an information alert in the search tab informing the + * user of the availability of this feature. + */ useTokenDetection: PropTypes.bool, + + /** + * Function called to fetch information about the token standard and + * details, see `actions.js`. + */ getTokenStandardAndDetails: PropTypes.func, + + /** + * The currently selected active address. + */ selectedAddress: PropTypes.string, }; diff --git a/ui/pages/import-token/import-token.stories.js b/ui/pages/import-token/import-token.stories.js index e6b1e089b..1b619804b 100644 --- a/ui/pages/import-token/import-token.stories.js +++ b/ui/pages/import-token/import-token.stories.js @@ -1,15 +1,120 @@ import React from 'react'; -import { boolean } from '@storybook/addon-knobs'; +import { Provider } from 'react-redux'; +import { action } from '@storybook/addon-actions'; +import { DEFAULT_ROUTE } from '../../helpers/constants/routes'; +import configureStore from '../../store/store'; +import testData from '../../../.storybook/test-data'; import ImportToken from './import-token.component'; +import README from './README.mdx'; + +const store = configureStore(testData); +const { metamask } = store.getState(); + +const { + frequentRpcListDetail, + identities, + pendingTokens, + selectedAddress, + tokenList, + tokens, +} = metamask; export default { title: 'Pages/ImportToken', id: __filename, + decorators: [(story) => {story()}], + component: ImportToken, + parameters: { + docs: { + page: README, + }, + }, + argTypes: { + history: { + control: { + type: 'object', + }, + }, + setPendingTokens: { + action: 'setPendingTokens', + }, + pendingTokens: { + control: { + type: 'object', + }, + }, + clearPendingTokens: { + action: 'clearPendingTokens', + }, + tokens: { + control: { + type: 'object', + }, + }, + identities: { + control: { + type: 'object', + }, + }, + showSearchTab: { + control: { + type: 'boolean', + }, + }, + mostRecentOverviewPage: { + control: { + type: 'text', + }, + }, + chainId: { + control: { + type: 'text', + }, + }, + rpcPrefs: { + control: { + type: 'object', + }, + }, + tokenList: { + control: { + type: 'object', + }, + }, + useTokenDetection: { + control: { + type: 'boolean', + }, + }, + getTokenStandardAndDetails: { + action: 'getTokenStandardAndDetails', + }, + selectedAddress: { + control: { + type: 'text', + }, + }, + }, + args: { + history: { + push: action('history.push()'), + }, + pendingTokens, + tokens, + identities, + showSearchTab: true, + mostRecentOverviewPage: DEFAULT_ROUTE, + chainId: frequentRpcListDetail[0].chainId, + rpcPrefs: frequentRpcListDetail[0].rpcPrefs, + tokenList, + useTokenDetection: false, + selectedAddress, + }, }; -export const DefaultStory = () => { - return ; +export const DefaultStory = (args) => { + return ; }; DefaultStory.storyName = 'Default';