remove customize-gas modal and related code that is no longer used (#16004)
parent
8e736e39d8
commit
99808eb02c
@ -1,11 +1,11 @@ |
||||
import { connect } from 'react-redux'; |
||||
import { decGWEIToHexWEI } from '../../../../helpers/utils/conversions.util'; |
||||
import { getNetworkSupportsSettingGasFees } from '../../../../selectors/selectors'; |
||||
import { MIN_GAS_LIMIT_DEC } from '../../../../pages/send/send.constants'; |
||||
import { decGWEIToHexWEI } from '../../../helpers/utils/conversions.util'; |
||||
import { getNetworkSupportsSettingGasFees } from '../../../selectors/selectors'; |
||||
import { MIN_GAS_LIMIT_DEC } from '../../../pages/send/send.constants'; |
||||
import { |
||||
decimalToHex, |
||||
hexWEIToDecGWEI, |
||||
} from '../../../../../shared/lib/transactions-controller-utils'; |
||||
} from '../../../../shared/lib/transactions-controller-utils'; |
||||
import AdvancedGasInputs from './advanced-gas-inputs.component'; |
||||
|
||||
function convertGasPriceForInputs(gasPriceInHexWEI) { |
@ -1,7 +1,7 @@ |
||||
import React from 'react'; |
||||
import sinon from 'sinon'; |
||||
import { renderWithProvider, fireEvent } from '../../../../../test/jest'; |
||||
import configureStore from '../../../../store/store'; |
||||
import { renderWithProvider, fireEvent } from '../../../../test/jest'; |
||||
import configureStore from '../../../store/store'; |
||||
import AdvancedGasInputs from '.'; |
||||
|
||||
describe('AdvancedGasInputs', () => { |
@ -1,91 +0,0 @@ |
||||
import React from 'react'; |
||||
import sinon from 'sinon'; |
||||
import { shallowWithContext } from '../../../../../../test/lib/render-helpers'; |
||||
import AdvancedTabContent from './advanced-tab-content.component'; |
||||
|
||||
describe('AdvancedTabContent Component', () => { |
||||
let wrapper; |
||||
|
||||
beforeEach(() => { |
||||
const propsMethodSpies = { |
||||
updateCustomGasPrice: sinon.spy(), |
||||
updateCustomGasLimit: sinon.spy(), |
||||
}; |
||||
sinon.spy(AdvancedTabContent.prototype, 'renderDataSummary'); |
||||
|
||||
wrapper = shallowWithContext( |
||||
<AdvancedTabContent |
||||
updateCustomGasPrice={propsMethodSpies.updateCustomGasPrice} |
||||
updateCustomGasLimit={propsMethodSpies.updateCustomGasLimit} |
||||
customModalGasPriceInHex="11" |
||||
customModalGasLimitInHex="23456" |
||||
transactionFee="$0.25" |
||||
insufficientBalance={false} |
||||
customPriceIsSafe |
||||
isSpeedUp={false} |
||||
customPriceIsExcessive={false} |
||||
/>, |
||||
); |
||||
}); |
||||
|
||||
afterEach(() => { |
||||
sinon.restore(); |
||||
}); |
||||
|
||||
describe('render()', () => { |
||||
it('should render the advanced-tab root node', () => { |
||||
expect(wrapper.hasClass('advanced-tab')).toStrictEqual(true); |
||||
}); |
||||
|
||||
it('should render the expected child of the advanced-tab div', () => { |
||||
const advancedTabChildren = wrapper.children(); |
||||
expect(advancedTabChildren).toHaveLength(2); |
||||
|
||||
expect( |
||||
advancedTabChildren |
||||
.at(0) |
||||
.hasClass('advanced-tab__transaction-data-summary'), |
||||
).toStrictEqual(true); |
||||
}); |
||||
|
||||
it('should call renderDataSummary with the expected params', () => { |
||||
const renderDataSummaryArgs = |
||||
AdvancedTabContent.prototype.renderDataSummary.getCall(0).args; |
||||
expect(renderDataSummaryArgs).toStrictEqual(['$0.25']); |
||||
}); |
||||
}); |
||||
|
||||
describe('renderDataSummary()', () => { |
||||
let dataSummary; |
||||
|
||||
beforeEach(() => { |
||||
dataSummary = shallowWithContext( |
||||
wrapper.instance().renderDataSummary('mockTotalFee'), |
||||
); |
||||
}); |
||||
|
||||
it('should render the transaction-data-summary root node', () => { |
||||
expect( |
||||
dataSummary.hasClass('advanced-tab__transaction-data-summary'), |
||||
).toStrictEqual(true); |
||||
}); |
||||
|
||||
it('should render titles of the data', () => { |
||||
const titlesNode = dataSummary.children().at(0); |
||||
expect( |
||||
titlesNode.hasClass('advanced-tab__transaction-data-summary__titles'), |
||||
).toStrictEqual(true); |
||||
expect(titlesNode.children().at(0).text()).toStrictEqual( |
||||
'newTransactionFee', |
||||
); |
||||
}); |
||||
|
||||
it('should render the data', () => { |
||||
const dataNode = dataSummary.children().at(1); |
||||
expect( |
||||
dataNode.hasClass('advanced-tab__transaction-data-summary__container'), |
||||
).toStrictEqual(true); |
||||
expect(dataNode.children().at(0).text()).toStrictEqual('mockTotalFee'); |
||||
}); |
||||
}); |
||||
}); |
@ -1,76 +0,0 @@ |
||||
import React, { Component } from 'react'; |
||||
import PropTypes from 'prop-types'; |
||||
import AdvancedGasInputs from '../../advanced-gas-inputs'; |
||||
|
||||
export default class AdvancedTabContent extends Component { |
||||
static contextTypes = { |
||||
t: PropTypes.func, |
||||
}; |
||||
|
||||
static propTypes = { |
||||
updateCustomGasPrice: PropTypes.func, |
||||
updateCustomGasLimit: PropTypes.func, |
||||
customModalGasPriceInHex: PropTypes.string, |
||||
customModalGasLimitInHex: PropTypes.string, |
||||
transactionFee: PropTypes.string, |
||||
insufficientBalance: PropTypes.bool, |
||||
customPriceIsSafe: PropTypes.bool, |
||||
isSpeedUp: PropTypes.bool, |
||||
customGasLimitMessage: PropTypes.string, |
||||
minimumGasLimit: PropTypes.number, |
||||
customPriceIsExcessive: PropTypes.bool.isRequired, |
||||
}; |
||||
|
||||
renderDataSummary(transactionFee) { |
||||
return ( |
||||
<div className="advanced-tab__transaction-data-summary"> |
||||
<div className="advanced-tab__transaction-data-summary__titles"> |
||||
<span>{this.context.t('newTransactionFee')}</span> |
||||
</div> |
||||
<div className="advanced-tab__transaction-data-summary__container"> |
||||
<div className="advanced-tab__transaction-data-summary__fee"> |
||||
{transactionFee} |
||||
</div> |
||||
</div> |
||||
</div> |
||||
); |
||||
} |
||||
|
||||
render() { |
||||
const { |
||||
updateCustomGasPrice, |
||||
updateCustomGasLimit, |
||||
customModalGasPriceInHex, |
||||
customModalGasLimitInHex, |
||||
insufficientBalance, |
||||
customPriceIsSafe, |
||||
isSpeedUp, |
||||
transactionFee, |
||||
customGasLimitMessage, |
||||
minimumGasLimit, |
||||
customPriceIsExcessive, |
||||
} = this.props; |
||||
|
||||
return ( |
||||
<div className="advanced-tab"> |
||||
{this.renderDataSummary(transactionFee)} |
||||
<div className="advanced-tab__fee-chart"> |
||||
<div className="advanced-tab__gas-inputs"> |
||||
<AdvancedGasInputs |
||||
updateCustomGasPrice={updateCustomGasPrice} |
||||
updateCustomGasLimit={updateCustomGasLimit} |
||||
customGasPrice={customModalGasPriceInHex} |
||||
customGasLimit={customModalGasLimitInHex} |
||||
insufficientBalance={insufficientBalance} |
||||
customPriceIsSafe={customPriceIsSafe} |
||||
isSpeedUp={isSpeedUp} |
||||
customGasLimitMessage={customGasLimitMessage} |
||||
minimumGasLimit={minimumGasLimit} |
||||
customPriceIsExcessive={customPriceIsExcessive} |
||||
/> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
); |
||||
} |
||||
} |
@ -1 +0,0 @@ |
||||
export { default } from './advanced-tab-content.component'; |
@ -1,112 +0,0 @@ |
||||
.advanced-tab { |
||||
display: flex; |
||||
flex-flow: column; |
||||
|
||||
&__transaction-data-summary { |
||||
padding-left: 24px; |
||||
padding-right: 24px; |
||||
} |
||||
|
||||
&__transaction-data-summary { |
||||
display: flex; |
||||
flex-flow: column; |
||||
color: var(--color-text-alternative); |
||||
margin-top: 12px; |
||||
padding-left: 18px; |
||||
padding-right: 18px; |
||||
|
||||
&__titles, |
||||
&__container { |
||||
@include H7; |
||||
|
||||
display: flex; |
||||
flex-flow: row; |
||||
justify-content: space-between; |
||||
color: var(--color-text-muted); |
||||
} |
||||
|
||||
&__container { |
||||
@include Paragraph; |
||||
|
||||
margin-top: 0; |
||||
} |
||||
|
||||
&__fee { |
||||
@include Paragraph; |
||||
|
||||
color: var(--color-text-alternative); |
||||
} |
||||
|
||||
&__time-remaining { |
||||
@include Paragraph; |
||||
|
||||
/*rtl:ignore*/ |
||||
direction: ltr; |
||||
color: var(--color-text-alternative); |
||||
|
||||
.minutes-num, |
||||
.seconds-num { |
||||
@include Paragraph; |
||||
} |
||||
|
||||
.seconds-num { |
||||
@include Paragraph; |
||||
|
||||
margin-left: 7px; |
||||
} |
||||
|
||||
.minutes-label, |
||||
.seconds-label { |
||||
@include Paragraph; |
||||
} |
||||
} |
||||
} |
||||
|
||||
&__fee-chart { |
||||
margin-top: 8px; |
||||
height: 265px; |
||||
background: var(--color-background-alternative); |
||||
border-bottom: 1px solid var(--color-border-muted); |
||||
border-top: 1px solid var(--color-border-muted); |
||||
position: relative; |
||||
|
||||
&__title { |
||||
@include H7; |
||||
|
||||
color: var(--color-text-alternative); |
||||
margin-left: 22px; |
||||
} |
||||
|
||||
&__speed-buttons { |
||||
@include H8; |
||||
|
||||
position: absolute; |
||||
bottom: 13px; |
||||
display: flex; |
||||
justify-content: space-between; |
||||
padding-left: 20px; |
||||
padding-right: 19px; |
||||
width: 100%; |
||||
color: var(--color-text-alternative); |
||||
} |
||||
|
||||
.loading-overlay { |
||||
height: auto; |
||||
} |
||||
} |
||||
|
||||
&__slider-container { |
||||
padding-left: 27px; |
||||
padding-right: 27px; |
||||
} |
||||
|
||||
&__gas-inputs { |
||||
display: flex; |
||||
flex-flow: row; |
||||
justify-content: space-between; |
||||
margin-left: 20px; |
||||
margin-right: 10px; |
||||
margin-top: 10px; |
||||
margin-bottom: 20px; |
||||
} |
||||
} |
@ -1,103 +0,0 @@ |
||||
import React from 'react'; |
||||
import GasPriceButtonGroup from '../../gas-price-button-group'; |
||||
import Loading from '../../../../ui/loading-screen'; |
||||
import { GAS_ESTIMATE_TYPES } from '../../../../../helpers/constants/common'; |
||||
import { shallowWithContext } from '../../../../../../test/lib/render-helpers'; |
||||
import BasicTabContent from './basic-tab-content.component'; |
||||
|
||||
const mockGasPriceButtonGroupProps = { |
||||
buttonDataLoading: false, |
||||
className: 'gas-price-button-group', |
||||
gasButtonInfo: [ |
||||
{ |
||||
feeInPrimaryCurrency: '$0.52', |
||||
feeInSecondaryCurrency: '0.0048 ETH', |
||||
timeEstimate: '~ 1 min 0 sec', |
||||
priceInHexWei: '0xa1b2c3f', |
||||
gasEstimateType: GAS_ESTIMATE_TYPES.AVERAGE, |
||||
}, |
||||
{ |
||||
feeInPrimaryCurrency: '$0.39', |
||||
feeInSecondaryCurrency: '0.004 ETH', |
||||
timeEstimate: '~ 1 min 30 sec', |
||||
priceInHexWei: '0xa1b2c39', |
||||
gasEstimateType: GAS_ESTIMATE_TYPES.AVERAGE, |
||||
}, |
||||
{ |
||||
feeInPrimaryCurrency: '$0.30', |
||||
feeInSecondaryCurrency: '0.00354 ETH', |
||||
timeEstimate: '~ 2 min 1 sec', |
||||
priceInHexWei: '0xa1b2c30', |
||||
gasEstimateType: GAS_ESTIMATE_TYPES.AVERAGE, |
||||
}, |
||||
], |
||||
handleGasPriceSelection: ({ gasPrice }) => |
||||
console.log('NewPrice: ', gasPrice), |
||||
noButtonActiveByDefault: true, |
||||
showCheck: true, |
||||
}; |
||||
|
||||
describe('BasicTabContent Component', () => { |
||||
describe('render', () => { |
||||
let wrapper; |
||||
|
||||
beforeEach(() => { |
||||
wrapper = shallowWithContext( |
||||
<BasicTabContent |
||||
gasPriceButtonGroupProps={mockGasPriceButtonGroupProps} |
||||
/>, |
||||
); |
||||
}); |
||||
|
||||
it('should have a title', () => { |
||||
expect( |
||||
wrapper |
||||
.find('.basic-tab-content') |
||||
.childAt(0) |
||||
.hasClass('basic-tab-content__title'), |
||||
).toStrictEqual(true); |
||||
}); |
||||
|
||||
it('should render a GasPriceButtonGroup compenent', () => { |
||||
expect(wrapper.find(GasPriceButtonGroup)).toHaveLength(1); |
||||
}); |
||||
|
||||
it('should pass correct props to GasPriceButtonGroup', () => { |
||||
const { |
||||
buttonDataLoading, |
||||
className, |
||||
gasButtonInfo, |
||||
handleGasPriceSelection, |
||||
noButtonActiveByDefault, |
||||
showCheck, |
||||
} = wrapper.find(GasPriceButtonGroup).props(); |
||||
expect(wrapper.find(GasPriceButtonGroup)).toHaveLength(1); |
||||
expect(buttonDataLoading).toStrictEqual( |
||||
mockGasPriceButtonGroupProps.buttonDataLoading, |
||||
); |
||||
expect(className).toStrictEqual(mockGasPriceButtonGroupProps.className); |
||||
expect(noButtonActiveByDefault).toStrictEqual( |
||||
mockGasPriceButtonGroupProps.noButtonActiveByDefault, |
||||
); |
||||
expect(showCheck).toStrictEqual(mockGasPriceButtonGroupProps.showCheck); |
||||
expect(gasButtonInfo).toStrictEqual( |
||||
mockGasPriceButtonGroupProps.gasButtonInfo, |
||||
); |
||||
expect(handleGasPriceSelection).toStrictEqual( |
||||
mockGasPriceButtonGroupProps.handleGasPriceSelection, |
||||
); |
||||
}); |
||||
|
||||
it('should render a loading component instead of the GasPriceButtonGroup if gasPriceButtonGroupProps.loading is true', () => { |
||||
wrapper.setProps({ |
||||
gasPriceButtonGroupProps: { |
||||
...mockGasPriceButtonGroupProps, |
||||
loading: true, |
||||
}, |
||||
}); |
||||
|
||||
expect(wrapper.find(GasPriceButtonGroup)).toHaveLength(0); |
||||
expect(wrapper.find(Loading)).toHaveLength(1); |
||||
}); |
||||
}); |
||||
}); |
@ -1,42 +0,0 @@ |
||||
import React, { Component } from 'react'; |
||||
import PropTypes from 'prop-types'; |
||||
import Loading from '../../../../ui/loading-screen'; |
||||
import GasPriceButtonGroup from '../../gas-price-button-group'; |
||||
|
||||
export default class BasicTabContent extends Component { |
||||
static contextTypes = { |
||||
t: PropTypes.func, |
||||
}; |
||||
|
||||
static propTypes = { |
||||
gasPriceButtonGroupProps: PropTypes.object, |
||||
}; |
||||
|
||||
render() { |
||||
const { t } = this.context; |
||||
const { gasPriceButtonGroupProps } = this.props; |
||||
|
||||
return ( |
||||
<div className="basic-tab-content"> |
||||
<div className="basic-tab-content__title"> |
||||
{t('estimatedProcessingTimes')} |
||||
</div> |
||||
<div className="basic-tab-content__blurb"> |
||||
{t('selectAHigherGasFee')} |
||||
</div> |
||||
{gasPriceButtonGroupProps.loading ? ( |
||||
<Loading /> |
||||
) : ( |
||||
<GasPriceButtonGroup |
||||
className="gas-price-button-group--alt" |
||||
showCheck |
||||
{...gasPriceButtonGroupProps} |
||||
/> |
||||
)} |
||||
<div className="basic-tab-content__footer-blurb"> |
||||
{t('acceleratingATransaction')} |
||||
</div> |
||||
</div> |
||||
); |
||||
} |
||||
} |
@ -1 +0,0 @@ |
||||
export { default } from './basic-tab-content.component'; |
@ -1,33 +0,0 @@ |
||||
.basic-tab-content { |
||||
display: flex; |
||||
flex-direction: column; |
||||
align-items: flex-start; |
||||
padding-left: 21px; |
||||
height: 324px; |
||||
background: var(--color-background-alternative); |
||||
border-bottom: 1px solid var(--color-border-default); |
||||
|
||||
&__title { |
||||
@include Paragraph; |
||||
|
||||
margin-top: 19px; |
||||
color: var(--color-text-default); |
||||
} |
||||
|
||||
&__blurb { |
||||
@include H7; |
||||
|
||||
width: 95%; |
||||
color: var(--color-text-default); |
||||
margin-top: 5px; |
||||
margin-bottom: 15px; |
||||
} |
||||
|
||||
&__footer-blurb { |
||||
@include H7; |
||||
|
||||
width: 95%; |
||||
color: var(--color-text-alternative); |
||||
margin-top: 15px; |
||||
} |
||||
} |
@ -1,272 +0,0 @@ |
||||
import React from 'react'; |
||||
import sinon from 'sinon'; |
||||
import { shallowWithContext } from '../../../../../test/lib/render-helpers'; |
||||
import { getGasFeeEstimatesAndStartPolling } from '../../../../store/actions'; |
||||
|
||||
import PageContainer from '../../../ui/page-container'; |
||||
|
||||
import { Tab } from '../../../ui/tabs'; |
||||
import GasModalPageContainer from './gas-modal-page-container.component'; |
||||
|
||||
jest.mock('../../../../store/actions', () => ({ |
||||
disconnectGasFeeEstimatePoller: jest.fn(), |
||||
getGasFeeEstimatesAndStartPolling: jest |
||||
.fn() |
||||
.mockImplementation(() => Promise.resolve()), |
||||
addPollingTokenToAppState: jest.fn(), |
||||
})); |
||||
|
||||
const propsMethodSpies = { |
||||
cancelAndClose: sinon.spy(), |
||||
onSubmit: sinon.spy(), |
||||
}; |
||||
|
||||
const mockGasPriceButtonGroupProps = { |
||||
buttonDataLoading: false, |
||||
className: 'gas-price-button-group', |
||||
gasButtonInfo: [ |
||||
{ |
||||
feeInPrimaryCurrency: '$0.52', |
||||
feeInSecondaryCurrency: '0.0048 ETH', |
||||
timeEstimate: '~ 1 min 0 sec', |
||||
priceInHexWei: '0xa1b2c3f', |
||||
}, |
||||
{ |
||||
feeInPrimaryCurrency: '$0.39', |
||||
feeInSecondaryCurrency: '0.004 ETH', |
||||
timeEstimate: '~ 1 min 30 sec', |
||||
priceInHexWei: '0xa1b2c39', |
||||
}, |
||||
{ |
||||
feeInPrimaryCurrency: '$0.30', |
||||
feeInSecondaryCurrency: '0.00354 ETH', |
||||
timeEstimate: '~ 2 min 1 sec', |
||||
priceInHexWei: '0xa1b2c30', |
||||
}, |
||||
], |
||||
handleGasPriceSelection: 'mockSelectionFunction', |
||||
noButtonActiveByDefault: true, |
||||
showCheck: true, |
||||
newTotalFiat: 'mockNewTotalFiat', |
||||
newTotalEth: 'mockNewTotalEth', |
||||
}; |
||||
const mockInfoRowProps = { |
||||
originalTotalFiat: 'mockOriginalTotalFiat', |
||||
originalTotalEth: 'mockOriginalTotalEth', |
||||
newTotalFiat: 'mockNewTotalFiat', |
||||
newTotalEth: 'mockNewTotalEth', |
||||
sendAmount: 'mockSendAmount', |
||||
transactionFee: 'mockTransactionFee', |
||||
extraInfoRow: { label: 'mockLabel', value: 'mockValue' }, |
||||
}; |
||||
|
||||
const GP = GasModalPageContainer.prototype; |
||||
describe('GasModalPageContainer Component', () => { |
||||
let wrapper; |
||||
|
||||
beforeEach(() => { |
||||
wrapper = shallowWithContext( |
||||
<GasModalPageContainer |
||||
cancelAndClose={propsMethodSpies.cancelAndClose} |
||||
onSubmit={propsMethodSpies.onSubmit} |
||||
updateCustomGasPrice={() => 'mockupdateCustomGasPrice'} |
||||
updateCustomGasLimit={() => 'mockupdateCustomGasLimit'} |
||||
gasPriceButtonGroupProps={mockGasPriceButtonGroupProps} |
||||
infoRowProps={mockInfoRowProps} |
||||
customGasPriceInHex="mockCustomGasPriceInHex" |
||||
customGasLimitInHex="mockCustomGasLimitInHex" |
||||
insufficientBalance={false} |
||||
disableSave={false} |
||||
customPriceIsExcessive={false} |
||||
/>, |
||||
); |
||||
}); |
||||
|
||||
afterEach(() => { |
||||
propsMethodSpies.cancelAndClose.resetHistory(); |
||||
jest.clearAllMocks(); |
||||
}); |
||||
|
||||
describe('componentDidMount', () => { |
||||
it('should call getGasFeeEstimatesAndStartPolling', () => { |
||||
jest.clearAllMocks(); |
||||
expect(getGasFeeEstimatesAndStartPolling).not.toHaveBeenCalled(); |
||||
wrapper.instance().componentDidMount(); |
||||
expect(getGasFeeEstimatesAndStartPolling).toHaveBeenCalled(); |
||||
}); |
||||
}); |
||||
|
||||
describe('render', () => { |
||||
it('should render a PageContainer compenent', () => { |
||||
expect(wrapper.find(PageContainer)).toHaveLength(1); |
||||
}); |
||||
|
||||
it('should pass correct props to PageContainer', () => { |
||||
const { title, subtitle, disabled } = wrapper.find(PageContainer).props(); |
||||
expect(title).toStrictEqual('customGas'); |
||||
expect(subtitle).toStrictEqual('customGasSubTitle'); |
||||
expect(disabled).toStrictEqual(false); |
||||
}); |
||||
|
||||
it('should pass the correct onCancel and onClose methods to PageContainer', () => { |
||||
const { onCancel, onClose } = wrapper.find(PageContainer).props(); |
||||
expect(propsMethodSpies.cancelAndClose.callCount).toStrictEqual(0); |
||||
onCancel(); |
||||
expect(propsMethodSpies.cancelAndClose.callCount).toStrictEqual(1); |
||||
onClose(); |
||||
expect(propsMethodSpies.cancelAndClose.callCount).toStrictEqual(2); |
||||
}); |
||||
|
||||
it('should pass the correct renderTabs property to PageContainer', () => { |
||||
jest |
||||
.spyOn(GasModalPageContainer.prototype, 'renderTabs') |
||||
.mockImplementation(() => 'mockTabs'); |
||||
const renderTabsWrapperTester = shallowWithContext( |
||||
<GasModalPageContainer customPriceIsExcessive={false} />, |
||||
{ context: { t: (str1, str2) => (str2 ? str1 + str2 : str1) } }, |
||||
); |
||||
const { tabsComponent } = renderTabsWrapperTester |
||||
.find(PageContainer) |
||||
.props(); |
||||
expect(tabsComponent).toStrictEqual('mockTabs'); |
||||
GasModalPageContainer.prototype.renderTabs.mockClear(); |
||||
}); |
||||
}); |
||||
|
||||
describe('renderTabs', () => { |
||||
beforeEach(() => { |
||||
sinon.spy(GP, 'renderBasicTabContent'); |
||||
sinon.spy(GP, 'renderAdvancedTabContent'); |
||||
sinon.spy(GP, 'renderInfoRows'); |
||||
}); |
||||
|
||||
afterEach(() => { |
||||
GP.renderBasicTabContent.restore(); |
||||
GP.renderAdvancedTabContent.restore(); |
||||
GP.renderInfoRows.restore(); |
||||
}); |
||||
|
||||
it('should render a Tabs component with "Basic" and "Advanced" tabs', () => { |
||||
const renderTabsResult = wrapper.instance().renderTabs(); |
||||
const renderedTabs = shallowWithContext(renderTabsResult); |
||||
expect(renderedTabs.props().className).toStrictEqual('tabs'); |
||||
|
||||
const tabs = renderedTabs.find(Tab); |
||||
expect(tabs).toHaveLength(2); |
||||
|
||||
expect(tabs.at(0).props().name).toStrictEqual('basic'); |
||||
expect(tabs.at(1).props().name).toStrictEqual('advanced'); |
||||
|
||||
expect(tabs.at(0).childAt(0).props().className).toStrictEqual( |
||||
'gas-modal-content', |
||||
); |
||||
expect(tabs.at(1).childAt(0).props().className).toStrictEqual( |
||||
'gas-modal-content', |
||||
); |
||||
}); |
||||
|
||||
it('should call renderInfoRows with the expected props', () => { |
||||
expect(GP.renderInfoRows.callCount).toStrictEqual(0); |
||||
|
||||
wrapper.instance().renderTabs(); |
||||
|
||||
expect(GP.renderInfoRows.callCount).toStrictEqual(2); |
||||
|
||||
expect(GP.renderInfoRows.getCall(0).args).toStrictEqual([ |
||||
'mockNewTotalFiat', |
||||
'mockNewTotalEth', |
||||
'mockSendAmount', |
||||
'mockTransactionFee', |
||||
]); |
||||
expect(GP.renderInfoRows.getCall(1).args).toStrictEqual([ |
||||
'mockNewTotalFiat', |
||||
'mockNewTotalEth', |
||||
'mockSendAmount', |
||||
'mockTransactionFee', |
||||
]); |
||||
}); |
||||
|
||||
it('should not render the basic tab if hideBasic is true', () => { |
||||
wrapper = shallowWithContext( |
||||
<GasModalPageContainer |
||||
cancelAndClose={propsMethodSpies.cancelAndClose} |
||||
onSubmit={propsMethodSpies.onSubmit} |
||||
updateCustomGasPrice={() => 'mockupdateCustomGasPrice'} |
||||
updateCustomGasLimit={() => 'mockupdateCustomGasLimit'} |
||||
gasPriceButtonGroupProps={mockGasPriceButtonGroupProps} |
||||
infoRowProps={mockInfoRowProps} |
||||
customGasPriceInHex="mockCustomGasPriceInHex" |
||||
customGasLimitInHex="mockCustomGasLimitInHex" |
||||
insufficientBalance={false} |
||||
disableSave={false} |
||||
customPriceIsExcessive={false} |
||||
hideBasic |
||||
/>, |
||||
); |
||||
const renderTabsResult = wrapper.instance().renderTabs(); |
||||
|
||||
const renderedTabs = shallowWithContext(renderTabsResult); |
||||
const tabs = renderedTabs.find(Tab); |
||||
expect(tabs).toHaveLength(1); |
||||
expect(tabs.at(0).props().name).toStrictEqual('advanced'); |
||||
}); |
||||
}); |
||||
|
||||
describe('renderBasicTabContent', () => { |
||||
it('should render', () => { |
||||
const renderBasicTabContentResult = wrapper |
||||
.instance() |
||||
.renderBasicTabContent(mockGasPriceButtonGroupProps); |
||||
|
||||
expect( |
||||
renderBasicTabContentResult.props.gasPriceButtonGroupProps, |
||||
).toStrictEqual(mockGasPriceButtonGroupProps); |
||||
}); |
||||
}); |
||||
|
||||
describe('renderInfoRows', () => { |
||||
it('should render the info rows with the passed data', () => { |
||||
const baseClassName = 'gas-modal-content__info-row'; |
||||
const renderedInfoRowsContainer = shallowWithContext( |
||||
wrapper |
||||
.instance() |
||||
.renderInfoRows( |
||||
'mockNewTotalFiat', |
||||
' mockNewTotalEth', |
||||
' mockSendAmount', |
||||
' mockTransactionFee', |
||||
), |
||||
); |
||||
|
||||
expect( |
||||
renderedInfoRowsContainer.childAt(0).hasClass(baseClassName), |
||||
).toStrictEqual(true); |
||||
|
||||
const renderedInfoRows = renderedInfoRowsContainer.childAt(0).children(); |
||||
expect(renderedInfoRows).toHaveLength(4); |
||||
expect( |
||||
renderedInfoRows.at(0).hasClass(`${baseClassName}__send-info`), |
||||
).toStrictEqual(true); |
||||
expect( |
||||
renderedInfoRows.at(1).hasClass(`${baseClassName}__transaction-info`), |
||||
).toStrictEqual(true); |
||||
expect( |
||||
renderedInfoRows.at(2).hasClass(`${baseClassName}__total-info`), |
||||
).toStrictEqual(true); |
||||
expect( |
||||
renderedInfoRows.at(3).hasClass(`${baseClassName}__fiat-total-info`), |
||||
).toStrictEqual(true); |
||||
|
||||
expect(renderedInfoRows.at(0).text()).toStrictEqual( |
||||
'sendAmount mockSendAmount', |
||||
); |
||||
expect(renderedInfoRows.at(1).text()).toStrictEqual( |
||||
'transactionFee mockTransactionFee', |
||||
); |
||||
expect(renderedInfoRows.at(2).text()).toStrictEqual( |
||||
'newTotal mockNewTotalEth', |
||||
); |
||||
expect(renderedInfoRows.at(3).text()).toStrictEqual('mockNewTotalFiat'); |
||||
}); |
||||
}); |
||||
}); |
@ -1,274 +0,0 @@ |
||||
import sinon from 'sinon'; |
||||
|
||||
import { hideModal } from '../../../../store/actions'; |
||||
|
||||
import { |
||||
setCustomGasPrice, |
||||
setCustomGasLimit, |
||||
resetCustomData, |
||||
} from '../../../../ducks/gas/gas.duck'; |
||||
|
||||
import { |
||||
useCustomGas, |
||||
updateGasLimit, |
||||
updateGasPrice, |
||||
} from '../../../../ducks/send'; |
||||
|
||||
let mapDispatchToProps; |
||||
let mergeProps; |
||||
|
||||
jest.mock('react-redux', () => ({ |
||||
connect: (_, md, mp) => { |
||||
mapDispatchToProps = md; |
||||
mergeProps = mp; |
||||
return () => ({}); |
||||
}, |
||||
})); |
||||
|
||||
jest.mock('../../../../selectors', () => ({ |
||||
getBasicGasEstimateLoadingStatus: (s) => |
||||
`mockBasicGasEstimateLoadingStatus:${Object.keys(s).length}`, |
||||
getRenderableBasicEstimateData: (s) => |
||||
`mockRenderableBasicEstimateData:${Object.keys(s).length}`, |
||||
getDefaultActiveButtonIndex: (a, b) => a + b, |
||||
getCurrentEthBalance: (state) => state.metamask.balance || '0x0', |
||||
getCustomGasPrice: (state) => state.gas.customData.price || '0x0', |
||||
getCustomGasLimit: (state) => state.gas.customData.limit || '0x0', |
||||
getCurrentCurrency: jest.fn().mockReturnValue('usd'), |
||||
conversionRateSelector: jest.fn().mockReturnValue(50), |
||||
getSendMaxModeState: jest.fn().mockReturnValue(false), |
||||
getPreferences: jest.fn(() => ({ |
||||
showFiatInTestnets: false, |
||||
})), |
||||
getIsMainnet: jest.fn().mockReturnValue(false), |
||||
isCustomPriceSafe: jest.fn().mockReturnValue(true), |
||||
})); |
||||
|
||||
jest.mock('../../../../store/actions', () => ({ |
||||
hideModal: jest.fn(), |
||||
updateTransaction: jest.fn(), |
||||
})); |
||||
|
||||
jest.mock('../../../../ducks/metamask/metamask.js', () => ({ |
||||
updateTransactionGasFees: jest.fn(), |
||||
})); |
||||
|
||||
jest.mock('../../../../ducks/gas/gas.duck', () => ({ |
||||
setCustomGasPrice: jest.fn(), |
||||
setCustomGasLimit: jest.fn(), |
||||
resetCustomData: jest.fn(), |
||||
})); |
||||
|
||||
jest.mock('../../../../ducks/send', () => { |
||||
const { ASSET_TYPES } = jest.requireActual( |
||||
'../../../../../shared/constants/transaction', |
||||
); |
||||
return { |
||||
useCustomGas: jest.fn(), |
||||
updateGasLimit: jest.fn(), |
||||
updateGasPrice: jest.fn(), |
||||
getSendAsset: jest.fn(() => ({ type: ASSET_TYPES.NATIVE })), |
||||
}; |
||||
}); |
||||
|
||||
require('./gas-modal-page-container.container'); |
||||
|
||||
describe('gas-modal-page-container container', () => { |
||||
describe('mapDispatchToProps()', () => { |
||||
let dispatchSpy; |
||||
let mapDispatchToPropsObject; |
||||
|
||||
beforeEach(() => { |
||||
dispatchSpy = sinon.spy(); |
||||
mapDispatchToPropsObject = mapDispatchToProps(dispatchSpy); |
||||
}); |
||||
|
||||
afterEach(() => { |
||||
dispatchSpy.resetHistory(); |
||||
jest.clearAllMocks(); |
||||
}); |
||||
|
||||
describe('useCustomGas()', () => { |
||||
it('should dispatch a useCustomGas action', () => { |
||||
mapDispatchToPropsObject.useCustomGas(); |
||||
expect(dispatchSpy.calledOnce).toStrictEqual(true); |
||||
expect(useCustomGas).toHaveBeenCalled(); |
||||
}); |
||||
}); |
||||
|
||||
describe('cancelAndClose()', () => { |
||||
it('should dispatch a hideModal action', () => { |
||||
mapDispatchToPropsObject.cancelAndClose(); |
||||
expect(dispatchSpy.calledTwice).toStrictEqual(true); |
||||
expect(hideModal).toHaveBeenCalled(); |
||||
expect(resetCustomData).toHaveBeenCalled(); |
||||
}); |
||||
}); |
||||
|
||||
describe('updateCustomGasPrice()', () => { |
||||
it('should dispatch a setCustomGasPrice action with the arg passed to updateCustomGasPrice hex prefixed', () => { |
||||
mapDispatchToPropsObject.updateCustomGasPrice('ffff'); |
||||
expect(dispatchSpy.calledOnce).toStrictEqual(true); |
||||
expect(setCustomGasPrice).toHaveBeenCalled(); |
||||
expect(setCustomGasPrice).toHaveBeenCalledWith('0xffff'); |
||||
// expect(
|
||||
// setCustomGasPrice.getCall(0).args[0],
|
||||
// '0xffff',
|
||||
// );
|
||||
}); |
||||
|
||||
it('should dispatch a setCustomGasPrice action', () => { |
||||
mapDispatchToPropsObject.updateCustomGasPrice('0xffff'); |
||||
expect(dispatchSpy.calledOnce).toStrictEqual(true); |
||||
expect(setCustomGasPrice).toHaveBeenCalled(); |
||||
expect(setCustomGasPrice).toHaveBeenCalledWith('0xffff'); |
||||
}); |
||||
}); |
||||
|
||||
describe('updateCustomGasLimit()', () => { |
||||
it('should dispatch a setCustomGasLimit action', () => { |
||||
mapDispatchToPropsObject.updateCustomGasLimit('0x10'); |
||||
expect(dispatchSpy.calledOnce).toStrictEqual(true); |
||||
expect(setCustomGasLimit).toHaveBeenCalled(); |
||||
expect(setCustomGasLimit).toHaveBeenCalledWith('0x10'); |
||||
}); |
||||
}); |
||||
|
||||
describe('setGasData()', () => { |
||||
it('should dispatch a updateGasPrice and updateGasLimit action with the correct props', () => { |
||||
mapDispatchToPropsObject.setGasData('ffff', 'aaaa'); |
||||
expect(dispatchSpy.calledTwice).toStrictEqual(true); |
||||
expect(updateGasPrice).toHaveBeenCalled(); |
||||
expect(updateGasLimit).toHaveBeenCalled(); |
||||
expect(updateGasLimit).toHaveBeenCalledWith('ffff'); |
||||
expect(updateGasPrice).toHaveBeenCalledWith('aaaa'); |
||||
}); |
||||
}); |
||||
}); |
||||
|
||||
describe('mergeProps', () => { |
||||
let stateProps; |
||||
let dispatchProps; |
||||
let ownProps; |
||||
|
||||
beforeEach(() => { |
||||
stateProps = { |
||||
gasPriceButtonGroupProps: { |
||||
someGasPriceButtonGroupProp: 'foo', |
||||
anotherGasPriceButtonGroupProp: 'bar', |
||||
}, |
||||
isConfirm: true, |
||||
someOtherStateProp: 'baz', |
||||
transaction: {}, |
||||
}; |
||||
dispatchProps = { |
||||
updateCustomGasPrice: sinon.spy(), |
||||
useCustomGas: sinon.spy(), |
||||
setGasData: sinon.spy(), |
||||
updateTransactionGasFees: sinon.spy(), |
||||
someOtherDispatchProp: sinon.spy(), |
||||
createSpeedUpTransaction: sinon.spy(), |
||||
hideModal: sinon.spy(), |
||||
cancelAndClose: sinon.spy(), |
||||
}; |
||||
ownProps = { someOwnProp: 123 }; |
||||
}); |
||||
|
||||
it('should return the expected props when isConfirm is true', () => { |
||||
const result = mergeProps(stateProps, dispatchProps, ownProps); |
||||
|
||||
expect(result.isConfirm).toStrictEqual(true); |
||||
expect(result.someOtherStateProp).toStrictEqual('baz'); |
||||
expect( |
||||
result.gasPriceButtonGroupProps.someGasPriceButtonGroupProp, |
||||
).toStrictEqual('foo'); |
||||
expect( |
||||
result.gasPriceButtonGroupProps.anotherGasPriceButtonGroupProp, |
||||
).toStrictEqual('bar'); |
||||
expect(result.someOwnProp).toStrictEqual(123); |
||||
|
||||
expect(dispatchProps.updateTransactionGasFees.callCount).toStrictEqual(0); |
||||
expect(dispatchProps.setGasData.callCount).toStrictEqual(0); |
||||
expect(dispatchProps.useCustomGas.callCount).toStrictEqual(0); |
||||
expect(dispatchProps.hideModal.callCount).toStrictEqual(0); |
||||
|
||||
result.onSubmit(); |
||||
|
||||
expect(dispatchProps.updateTransactionGasFees.callCount).toStrictEqual(1); |
||||
expect(dispatchProps.setGasData.callCount).toStrictEqual(0); |
||||
expect(dispatchProps.useCustomGas.callCount).toStrictEqual(0); |
||||
expect(dispatchProps.hideModal.callCount).toStrictEqual(1); |
||||
|
||||
expect(dispatchProps.updateCustomGasPrice.callCount).toStrictEqual(0); |
||||
result.gasPriceButtonGroupProps.handleGasPriceSelection({ |
||||
gasPrice: '0x0', |
||||
}); |
||||
expect(dispatchProps.updateCustomGasPrice.callCount).toStrictEqual(1); |
||||
|
||||
expect(dispatchProps.someOtherDispatchProp.callCount).toStrictEqual(0); |
||||
result.someOtherDispatchProp(); |
||||
expect(dispatchProps.someOtherDispatchProp.callCount).toStrictEqual(1); |
||||
}); |
||||
|
||||
it('should return the expected props when isConfirm is false', () => { |
||||
const result = mergeProps( |
||||
{ ...stateProps, isConfirm: false }, |
||||
dispatchProps, |
||||
ownProps, |
||||
); |
||||
|
||||
expect(result.isConfirm).toStrictEqual(false); |
||||
expect(result.someOtherStateProp).toStrictEqual('baz'); |
||||
expect( |
||||
result.gasPriceButtonGroupProps.someGasPriceButtonGroupProp, |
||||
).toStrictEqual('foo'); |
||||
expect( |
||||
result.gasPriceButtonGroupProps.anotherGasPriceButtonGroupProp, |
||||
).toStrictEqual('bar'); |
||||
expect(result.someOwnProp).toStrictEqual(123); |
||||
|
||||
expect(dispatchProps.updateTransactionGasFees.callCount).toStrictEqual(0); |
||||
expect(dispatchProps.setGasData.callCount).toStrictEqual(0); |
||||
expect(dispatchProps.useCustomGas.callCount).toStrictEqual(0); |
||||
expect(dispatchProps.cancelAndClose.callCount).toStrictEqual(0); |
||||
|
||||
result.onSubmit('mockNewLimit', 'mockNewPrice'); |
||||
|
||||
expect(dispatchProps.updateTransactionGasFees.callCount).toStrictEqual(0); |
||||
expect(dispatchProps.setGasData.callCount).toStrictEqual(1); |
||||
expect(dispatchProps.setGasData.getCall(0).args).toStrictEqual([ |
||||
'mockNewLimit', |
||||
'mockNewPrice', |
||||
]); |
||||
expect(dispatchProps.useCustomGas.callCount).toStrictEqual(1); |
||||
expect(dispatchProps.cancelAndClose.callCount).toStrictEqual(1); |
||||
|
||||
expect(dispatchProps.updateCustomGasPrice.callCount).toStrictEqual(0); |
||||
result.gasPriceButtonGroupProps.handleGasPriceSelection({ |
||||
gasPrice: '0x0', |
||||
}); |
||||
expect(dispatchProps.updateCustomGasPrice.callCount).toStrictEqual(1); |
||||
|
||||
expect(dispatchProps.someOtherDispatchProp.callCount).toStrictEqual(0); |
||||
result.someOtherDispatchProp(); |
||||
expect(dispatchProps.someOtherDispatchProp.callCount).toStrictEqual(1); |
||||
}); |
||||
|
||||
it('should dispatch the expected actions from obSubmit when isConfirm is false and isSpeedUp is true', () => { |
||||
const result = mergeProps( |
||||
{ ...stateProps, isSpeedUp: true, isConfirm: false }, |
||||
dispatchProps, |
||||
ownProps, |
||||
); |
||||
|
||||
result.onSubmit(); |
||||
|
||||
expect(dispatchProps.updateTransactionGasFees.callCount).toStrictEqual(0); |
||||
expect(dispatchProps.setGasData.callCount).toStrictEqual(0); |
||||
expect(dispatchProps.useCustomGas.callCount).toStrictEqual(0); |
||||
expect(dispatchProps.cancelAndClose.callCount).toStrictEqual(1); |
||||
|
||||
expect(dispatchProps.createSpeedUpTransaction.callCount).toStrictEqual(1); |
||||
}); |
||||
}); |
||||
}); |
@ -1,240 +0,0 @@ |
||||
import React, { Component } from 'react'; |
||||
import PropTypes from 'prop-types'; |
||||
import PageContainer from '../../../ui/page-container'; |
||||
import { Tabs, Tab } from '../../../ui/tabs'; |
||||
import { |
||||
disconnectGasFeeEstimatePoller, |
||||
getGasFeeEstimatesAndStartPolling, |
||||
addPollingTokenToAppState, |
||||
removePollingTokenFromAppState, |
||||
} from '../../../../store/actions'; |
||||
import { EVENT } from '../../../../../shared/constants/metametrics'; |
||||
import AdvancedTabContent from './advanced-tab-content'; |
||||
import BasicTabContent from './basic-tab-content'; |
||||
|
||||
export default class GasModalPageContainer extends Component { |
||||
static contextTypes = { |
||||
t: PropTypes.func, |
||||
trackEvent: PropTypes.func, |
||||
}; |
||||
|
||||
static propTypes = { |
||||
hideBasic: PropTypes.bool, |
||||
updateCustomGasPrice: PropTypes.func, |
||||
updateCustomGasLimit: PropTypes.func, |
||||
insufficientBalance: PropTypes.bool, |
||||
gasPriceButtonGroupProps: PropTypes.object, |
||||
infoRowProps: PropTypes.shape({ |
||||
originalTotalFiat: PropTypes.string, |
||||
originalTotalEth: PropTypes.string, |
||||
newTotalFiat: PropTypes.string, |
||||
newTotalEth: PropTypes.string, |
||||
sendAmount: PropTypes.string, |
||||
transactionFee: PropTypes.string, |
||||
}), |
||||
onSubmit: PropTypes.func, |
||||
customModalGasPriceInHex: PropTypes.string, |
||||
customModalGasLimitInHex: PropTypes.string, |
||||
cancelAndClose: PropTypes.func, |
||||
customPriceIsSafe: PropTypes.bool, |
||||
isSpeedUp: PropTypes.bool, |
||||
isRetry: PropTypes.bool, |
||||
disableSave: PropTypes.bool, |
||||
customPriceIsExcessive: PropTypes.bool.isRequired, |
||||
}; |
||||
|
||||
constructor(props) { |
||||
super(props); |
||||
this.state = { |
||||
pollingToken: undefined, |
||||
}; |
||||
} |
||||
|
||||
componentDidMount() { |
||||
this._isMounted = true; |
||||
getGasFeeEstimatesAndStartPolling().then((pollingToken) => { |
||||
if (this._isMounted) { |
||||
addPollingTokenToAppState(pollingToken); |
||||
this.setState({ pollingToken }); |
||||
} else { |
||||
disconnectGasFeeEstimatePoller(pollingToken); |
||||
removePollingTokenFromAppState(pollingToken); |
||||
} |
||||
}); |
||||
window.addEventListener('beforeunload', this._beforeUnload); |
||||
} |
||||
|
||||
_beforeUnload = () => { |
||||
this._isMounted = false; |
||||
if (this.state.pollingToken) { |
||||
disconnectGasFeeEstimatePoller(this.state.pollingToken); |
||||
removePollingTokenFromAppState(this.state.pollingToken); |
||||
} |
||||
}; |
||||
|
||||
componentWillUnmount() { |
||||
this._beforeUnload(); |
||||
window.removeEventListener('beforeunload', this._beforeUnload); |
||||
} |
||||
|
||||
renderBasicTabContent(gasPriceButtonGroupProps) { |
||||
return ( |
||||
<BasicTabContent gasPriceButtonGroupProps={gasPriceButtonGroupProps} /> |
||||
); |
||||
} |
||||
|
||||
renderAdvancedTabContent() { |
||||
const { |
||||
updateCustomGasPrice, |
||||
updateCustomGasLimit, |
||||
customModalGasPriceInHex, |
||||
customModalGasLimitInHex, |
||||
insufficientBalance, |
||||
customPriceIsSafe, |
||||
isSpeedUp, |
||||
isRetry, |
||||
customPriceIsExcessive, |
||||
infoRowProps: { transactionFee }, |
||||
} = this.props; |
||||
|
||||
return ( |
||||
<AdvancedTabContent |
||||
updateCustomGasPrice={updateCustomGasPrice} |
||||
updateCustomGasLimit={updateCustomGasLimit} |
||||
customModalGasPriceInHex={customModalGasPriceInHex} |
||||
customModalGasLimitInHex={customModalGasLimitInHex} |
||||
transactionFee={transactionFee} |
||||
insufficientBalance={insufficientBalance} |
||||
customPriceIsSafe={customPriceIsSafe} |
||||
isSpeedUp={isSpeedUp} |
||||
isRetry={isRetry} |
||||
customPriceIsExcessive={customPriceIsExcessive} |
||||
/> |
||||
); |
||||
} |
||||
|
||||
renderInfoRows(newTotalFiat, newTotalEth, sendAmount, transactionFee) { |
||||
return ( |
||||
<div className="gas-modal-content__info-row-wrapper"> |
||||
<div className="gas-modal-content__info-row"> |
||||
<div className="gas-modal-content__info-row__send-info"> |
||||
<span className="gas-modal-content__info-row__send-info__label"> |
||||
{this.context.t('sendAmount')} |
||||
</span> |
||||
<span className="gas-modal-content__info-row__send-info__value"> |
||||
{sendAmount} |
||||
</span> |
||||
</div> |
||||
<div className="gas-modal-content__info-row__transaction-info"> |
||||
<span className="gas-modal-content__info-row__transaction-info__label"> |
||||
{this.context.t('transactionFee')} |
||||
</span> |
||||
<span className="gas-modal-content__info-row__transaction-info__value"> |
||||
{transactionFee} |
||||
</span> |
||||
</div> |
||||
<div className="gas-modal-content__info-row__total-info"> |
||||
<span className="gas-modal-content__info-row__total-info__label"> |
||||
{this.context.t('newTotal')} |
||||
</span> |
||||
<span className="gas-modal-content__info-row__total-info__value"> |
||||
{newTotalEth} |
||||
</span> |
||||
</div> |
||||
<div className="gas-modal-content__info-row__fiat-total-info"> |
||||
<span className="gas-modal-content__info-row__fiat-total-info__value"> |
||||
{newTotalFiat} |
||||
</span> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
); |
||||
} |
||||
|
||||
renderTabs() { |
||||
const { |
||||
gasPriceButtonGroupProps, |
||||
hideBasic, |
||||
infoRowProps: { newTotalFiat, newTotalEth, sendAmount, transactionFee }, |
||||
} = this.props; |
||||
|
||||
let tabsToRender; |
||||
if (hideBasic) { |
||||
tabsToRender = [ |
||||
{ |
||||
name: this.context.t('advanced'), |
||||
content: this.renderAdvancedTabContent(), |
||||
}, |
||||
]; |
||||
} else { |
||||
tabsToRender = [ |
||||
{ |
||||
name: this.context.t('basic'), |
||||
content: this.renderBasicTabContent(gasPriceButtonGroupProps), |
||||
}, |
||||
{ |
||||
name: this.context.t('advanced'), |
||||
content: this.renderAdvancedTabContent(), |
||||
}, |
||||
]; |
||||
} |
||||
|
||||
return ( |
||||
<Tabs> |
||||
{tabsToRender.map(({ name, content }, i) => ( |
||||
<Tab name={name} key={`gas-modal-tab-${i}`}> |
||||
<div className="gas-modal-content"> |
||||
{content} |
||||
{this.renderInfoRows( |
||||
newTotalFiat, |
||||
newTotalEth, |
||||
sendAmount, |
||||
transactionFee, |
||||
)} |
||||
</div> |
||||
</Tab> |
||||
))} |
||||
</Tabs> |
||||
); |
||||
} |
||||
|
||||
render() { |
||||
const { |
||||
cancelAndClose, |
||||
onSubmit, |
||||
customModalGasPriceInHex, |
||||
customModalGasLimitInHex, |
||||
disableSave, |
||||
isSpeedUp, |
||||
} = this.props; |
||||
|
||||
return ( |
||||
<div className="gas-modal-page-container"> |
||||
<PageContainer |
||||
title={this.context.t('customGas')} |
||||
subtitle={this.context.t('customGasSubTitle')} |
||||
tabsComponent={this.renderTabs()} |
||||
disabled={disableSave} |
||||
onCancel={() => cancelAndClose()} |
||||
onClose={() => cancelAndClose()} |
||||
onSubmit={() => { |
||||
if (isSpeedUp) { |
||||
this.context.trackEvent({ |
||||
category: EVENT.CATEGORIES.NAVIGATION, |
||||
event: 'Saved "Speed Up"', |
||||
properties: { |
||||
action: 'Activity Log', |
||||
legacy_event: true, |
||||
}, |
||||
}); |
||||
} |
||||
onSubmit(customModalGasLimitInHex, customModalGasPriceInHex); |
||||
}} |
||||
submitText={this.context.t('save')} |
||||
headerCloseText={this.context.t('close')} |
||||
hideCancel |
||||
/> |
||||
</div> |
||||
); |
||||
} |
||||
} |
@ -1,330 +0,0 @@ |
||||
import { connect } from 'react-redux'; |
||||
import { addHexPrefix } from '../../../../../app/scripts/lib/util'; |
||||
import { |
||||
hideModal, |
||||
createRetryTransaction, |
||||
createSpeedUpTransaction, |
||||
} from '../../../../store/actions'; |
||||
import { |
||||
setCustomGasPrice, |
||||
setCustomGasLimit, |
||||
resetCustomData, |
||||
} from '../../../../ducks/gas/gas.duck'; |
||||
import { |
||||
getSendMaxModeState, |
||||
getGasLimit, |
||||
getGasPrice, |
||||
getSendAmount, |
||||
updateGasLimit, |
||||
updateGasPrice, |
||||
useCustomGas, |
||||
getSendAsset, |
||||
} from '../../../../ducks/send'; |
||||
import { |
||||
conversionRateSelector as getConversionRate, |
||||
getCurrentCurrency, |
||||
getCurrentEthBalance, |
||||
getIsMainnet, |
||||
getIsTestnet, |
||||
getBasicGasEstimateLoadingStatus, |
||||
getCustomGasLimit, |
||||
getCustomGasPrice, |
||||
getDefaultActiveButtonIndex, |
||||
getRenderableBasicEstimateData, |
||||
isCustomPriceSafe, |
||||
isCustomPriceSafeForCustomNetwork, |
||||
getAveragePriceEstimateInHexWEI, |
||||
isCustomPriceExcessive, |
||||
getIsGasEstimatesFetched, |
||||
getShouldShowFiat, |
||||
getIsCustomNetworkGasPriceFetched, |
||||
} from '../../../../selectors'; |
||||
|
||||
import { |
||||
addHexes, |
||||
subtractHexWEIsToDec, |
||||
getValueFromWeiHex, |
||||
sumHexWEIsToRenderableFiat, |
||||
} from '../../../../helpers/utils/conversions.util'; |
||||
import { formatETHFee } from '../../../../helpers/utils/formatters'; |
||||
import { isBalanceSufficient } from '../../../../pages/send/send.utils'; |
||||
import { MIN_GAS_LIMIT_DEC } from '../../../../pages/send/send.constants'; |
||||
import { |
||||
ASSET_TYPES, |
||||
TRANSACTION_STATUSES, |
||||
} from '../../../../../shared/constants/transaction'; |
||||
import { GAS_LIMITS } from '../../../../../shared/constants/gas'; |
||||
import { updateGasFees } from '../../../../ducks/metamask/metamask'; |
||||
import { |
||||
calcGasTotal, |
||||
hexWEIToDecGWEI, |
||||
} from '../../../../../shared/lib/transactions-controller-utils'; |
||||
import GasModalPageContainer from './gas-modal-page-container.component'; |
||||
|
||||
const mapStateToProps = (state, ownProps) => { |
||||
const gasLimit = getGasLimit(state); |
||||
const gasPrice = getGasPrice(state); |
||||
const amount = getSendAmount(state); |
||||
const { currentNetworkTxList } = state.metamask; |
||||
const { modalState: { props: modalProps } = {} } = state.appState.modal || {}; |
||||
const { txData = {} } = modalProps || {}; |
||||
const { transaction = {}, onSubmit } = ownProps; |
||||
const selectedTransaction = currentNetworkTxList.find( |
||||
({ id }) => id === (transaction.id || txData.id), |
||||
); |
||||
const buttonDataLoading = getBasicGasEstimateLoadingStatus(state); |
||||
const asset = getSendAsset(state); |
||||
|
||||
// a "default" txParams is used during the send flow, since the transaction doesn't exist yet in that case
|
||||
const txParams = selectedTransaction?.txParams |
||||
? selectedTransaction.txParams |
||||
: { |
||||
gas: gasLimit || GAS_LIMITS.SIMPLE, |
||||
gasPrice: gasPrice || getAveragePriceEstimateInHexWEI(state, true), |
||||
value: asset.type === ASSET_TYPES.TOKEN ? '0x0' : amount, |
||||
}; |
||||
|
||||
const { gasPrice: currentGasPrice, gas: currentGasLimit } = txParams; |
||||
const value = ownProps.transaction?.txParams?.value || txParams.value; |
||||
const customModalGasPriceInHex = getCustomGasPrice(state) || currentGasPrice; |
||||
const customModalGasLimitInHex = |
||||
getCustomGasLimit(state) || currentGasLimit || GAS_LIMITS.SIMPLE; |
||||
const customGasTotal = calcGasTotal( |
||||
customModalGasLimitInHex, |
||||
customModalGasPriceInHex, |
||||
); |
||||
|
||||
const gasButtonInfo = getRenderableBasicEstimateData( |
||||
state, |
||||
customModalGasLimitInHex, |
||||
); |
||||
|
||||
const currentCurrency = getCurrentCurrency(state); |
||||
const conversionRate = getConversionRate(state); |
||||
const newTotalFiat = sumHexWEIsToRenderableFiat( |
||||
[value, customGasTotal], |
||||
currentCurrency, |
||||
conversionRate, |
||||
); |
||||
|
||||
const { hideBasic } = state.appState.modal.modalState.props; |
||||
|
||||
const customGasPrice = calcCustomGasPrice(customModalGasPriceInHex); |
||||
|
||||
const maxModeOn = getSendMaxModeState(state); |
||||
|
||||
const balance = getCurrentEthBalance(state); |
||||
|
||||
const isMainnet = getIsMainnet(state); |
||||
const isTestnet = getIsTestnet(state); |
||||
const showFiat = getShouldShowFiat(state); |
||||
|
||||
const newTotalEth = |
||||
maxModeOn && asset.type === ASSET_TYPES.NATIVE |
||||
? sumHexWEIsToRenderableEth([balance, '0x0']) |
||||
: sumHexWEIsToRenderableEth([value, customGasTotal]); |
||||
|
||||
const sendAmount = |
||||
maxModeOn && asset.type === ASSET_TYPES.NATIVE |
||||
? subtractHexWEIsFromRenderableEth(balance, customGasTotal) |
||||
: sumHexWEIsToRenderableEth([value, '0x0']); |
||||
|
||||
const insufficientBalance = maxModeOn |
||||
? false |
||||
: !isBalanceSufficient({ |
||||
amount: value, |
||||
gasTotal: customGasTotal, |
||||
balance, |
||||
conversionRate, |
||||
}); |
||||
const isGasEstimate = getIsGasEstimatesFetched(state); |
||||
const customNetworkEstimateWasFetched = |
||||
getIsCustomNetworkGasPriceFetched(state); |
||||
|
||||
let customPriceIsSafe = true; |
||||
if ((isMainnet || process.env.IN_TEST) && isGasEstimate) { |
||||
customPriceIsSafe = isCustomPriceSafe(state); |
||||
} else if ( |
||||
!(isMainnet || process.env.IN_TEST || isTestnet) && |
||||
customNetworkEstimateWasFetched |
||||
) { |
||||
customPriceIsSafe = isCustomPriceSafeForCustomNetwork(state); |
||||
} |
||||
|
||||
return { |
||||
hideBasic, |
||||
isConfirm: isConfirm(state), |
||||
customModalGasPriceInHex, |
||||
customModalGasLimitInHex, |
||||
customGasPrice, |
||||
customGasLimit: calcCustomGasLimit(customModalGasLimitInHex), |
||||
customGasTotal, |
||||
newTotalFiat, |
||||
customPriceIsSafe, |
||||
customPriceIsExcessive: isCustomPriceExcessive(state), |
||||
maxModeOn, |
||||
gasPriceButtonGroupProps: { |
||||
buttonDataLoading, |
||||
defaultActiveButtonIndex: getDefaultActiveButtonIndex( |
||||
gasButtonInfo, |
||||
customModalGasPriceInHex, |
||||
), |
||||
gasButtonInfo, |
||||
}, |
||||
infoRowProps: { |
||||
originalTotalFiat: sumHexWEIsToRenderableFiat( |
||||
[value, customGasTotal], |
||||
currentCurrency, |
||||
conversionRate, |
||||
), |
||||
originalTotalEth: sumHexWEIsToRenderableEth([value, customGasTotal]), |
||||
newTotalFiat: showFiat ? newTotalFiat : '', |
||||
newTotalEth, |
||||
transactionFee: sumHexWEIsToRenderableEth(['0x0', customGasTotal]), |
||||
sendAmount, |
||||
}, |
||||
transaction: txData || transaction, |
||||
isSpeedUp: transaction.status === TRANSACTION_STATUSES.SUBMITTED, |
||||
isRetry: transaction.status === TRANSACTION_STATUSES.FAILED, |
||||
txId: transaction.id, |
||||
insufficientBalance, |
||||
isMainnet, |
||||
balance, |
||||
conversionRate, |
||||
value, |
||||
onSubmit, |
||||
}; |
||||
}; |
||||
|
||||
const mapDispatchToProps = (dispatch) => { |
||||
const updateCustomGasPrice = (newPrice) => |
||||
dispatch(setCustomGasPrice(addHexPrefix(newPrice))); |
||||
|
||||
return { |
||||
cancelAndClose: () => { |
||||
dispatch(resetCustomData()); |
||||
dispatch(hideModal()); |
||||
}, |
||||
hideModal: () => dispatch(hideModal()), |
||||
useCustomGas: () => dispatch(useCustomGas()), |
||||
updateTransactionGasFees: (gasFees) => { |
||||
dispatch(updateGasFees({ ...gasFees, expectHexWei: true })); |
||||
}, |
||||
updateCustomGasPrice, |
||||
updateCustomGasLimit: (newLimit) => |
||||
dispatch(setCustomGasLimit(addHexPrefix(newLimit))), |
||||
setGasData: (newLimit, newPrice) => { |
||||
dispatch(updateGasLimit(newLimit)); |
||||
dispatch(updateGasPrice(newPrice)); |
||||
}, |
||||
createRetryTransaction: (txId, customGasSettings) => { |
||||
return dispatch(createRetryTransaction(txId, customGasSettings)); |
||||
}, |
||||
createSpeedUpTransaction: (txId, customGasSettings) => { |
||||
return dispatch(createSpeedUpTransaction(txId, customGasSettings)); |
||||
}, |
||||
}; |
||||
}; |
||||
|
||||
const mergeProps = (stateProps, dispatchProps, ownProps) => { |
||||
const { |
||||
gasPriceButtonGroupProps, |
||||
// eslint-disable-next-line no-shadow
|
||||
isConfirm, |
||||
txId, |
||||
isSpeedUp, |
||||
isRetry, |
||||
insufficientBalance, |
||||
customGasPrice, |
||||
customGasLimit, |
||||
transaction, |
||||
} = stateProps; |
||||
const { |
||||
useCustomGas: dispatchUseCustomGas, |
||||
setGasData: dispatchSetGasData, |
||||
createSpeedUpTransaction: dispatchCreateSpeedUpTransaction, |
||||
createRetryTransaction: dispatchCreateRetryTransaction, |
||||
updateTransactionGasFees: dispatchUpdateTransactionGasFees, |
||||
cancelAndClose: dispatchCancelAndClose, |
||||
hideModal: dispatchHideModal, |
||||
...otherDispatchProps |
||||
} = dispatchProps; |
||||
|
||||
return { |
||||
...stateProps, |
||||
...otherDispatchProps, |
||||
...ownProps, |
||||
onSubmit: (gasLimit, gasPrice) => { |
||||
if (ownProps.onSubmit) { |
||||
dispatchCancelAndClose(); |
||||
ownProps.onSubmit({ gasLimit, gasPrice }); |
||||
return; |
||||
} |
||||
if (isConfirm) { |
||||
dispatchUpdateTransactionGasFees({ |
||||
gasLimit, |
||||
gasPrice, |
||||
transaction, |
||||
isModal: true, |
||||
}); |
||||
dispatchHideModal(); |
||||
dispatchCancelAndClose(); |
||||
} else if (isSpeedUp) { |
||||
dispatchCreateSpeedUpTransaction(txId, { gasPrice, gasLimit }); |
||||
dispatchCancelAndClose(); |
||||
} else if (isRetry) { |
||||
dispatchCreateRetryTransaction(txId, { gasPrice, gasLimit }); |
||||
dispatchCancelAndClose(); |
||||
} else { |
||||
dispatchSetGasData(gasLimit, gasPrice); |
||||
dispatchUseCustomGas(); |
||||
dispatchCancelAndClose(); |
||||
} |
||||
}, |
||||
gasPriceButtonGroupProps: { |
||||
...gasPriceButtonGroupProps, |
||||
handleGasPriceSelection: ({ gasPrice }) => |
||||
otherDispatchProps.updateCustomGasPrice(gasPrice), |
||||
}, |
||||
cancelAndClose: () => { |
||||
dispatchCancelAndClose(); |
||||
}, |
||||
disableSave: |
||||
insufficientBalance || |
||||
(isSpeedUp && customGasPrice === 0) || |
||||
customGasLimit < Number(MIN_GAS_LIMIT_DEC), |
||||
}; |
||||
}; |
||||
|
||||
export default connect( |
||||
mapStateToProps, |
||||
mapDispatchToProps, |
||||
mergeProps, |
||||
)(GasModalPageContainer); |
||||
|
||||
function isConfirm(state) { |
||||
return Boolean(Object.keys(state.confirmTransaction.txData).length); |
||||
} |
||||
|
||||
function calcCustomGasPrice(customGasPriceInHex) { |
||||
return Number(hexWEIToDecGWEI(customGasPriceInHex)); |
||||
} |
||||
|
||||
function calcCustomGasLimit(customGasLimitInHex) { |
||||
return parseInt(customGasLimitInHex, 16); |
||||
} |
||||
|
||||
function sumHexWEIsToRenderableEth(hexWEIs) { |
||||
const hexWEIsSum = hexWEIs.filter(Boolean).reduce(addHexes); |
||||
return formatETHFee( |
||||
getValueFromWeiHex({ |
||||
value: hexWEIsSum, |
||||
toCurrency: 'ETH', |
||||
numberOfDecimals: 6, |
||||
}), |
||||
); |
||||
} |
||||
|
||||
function subtractHexWEIsFromRenderableEth(aHexWEI, bHexWEI) { |
||||
return formatETHFee(subtractHexWEIsToDec(aHexWEI, bHexWEI)); |
||||
} |
@ -1 +0,0 @@ |
||||
export { default } from './gas-modal-page-container.container'; |
@ -1,160 +0,0 @@ |
||||
@import './advanced-tab-content/index'; |
||||
@import './basic-tab-content/index'; |
||||
|
||||
.gas-modal-page-container { |
||||
.page-container { |
||||
max-width: 391px; |
||||
min-height: 585px; |
||||
overflow-y: initial; |
||||
|
||||
@include screen-sm-max { |
||||
&__content { |
||||
display: flex; |
||||
overflow-y: initial; |
||||
} |
||||
} |
||||
|
||||
&__header { |
||||
padding: 0; |
||||
padding-top: 16px; |
||||
|
||||
&--no-padding-bottom { |
||||
padding-bottom: 0; |
||||
} |
||||
} |
||||
|
||||
&__footer { |
||||
footer { |
||||
padding-top: 12px; |
||||
padding-bottom: 12px; |
||||
} |
||||
} |
||||
|
||||
&__header-close-text { |
||||
@include H6; |
||||
|
||||
color: var(--color-primary-default); |
||||
position: absolute; |
||||
font-size: 0.75rem; |
||||
top: 8px; |
||||
right: 16px; |
||||
cursor: pointer; |
||||
overflow: hidden; |
||||
width: min-content; |
||||
} |
||||
|
||||
&__title { |
||||
@include H5; |
||||
|
||||
color: var(--color-text-default); |
||||
font-weight: 500; |
||||
display: flex; |
||||
justify-content: center; |
||||
align-items: flex-start; |
||||
margin-right: 0; |
||||
} |
||||
|
||||
&__subtitle { |
||||
display: none; |
||||
} |
||||
|
||||
&__tab { |
||||
margin-right: 0; |
||||
} |
||||
|
||||
&__tabs { |
||||
margin-top: 0; |
||||
} |
||||
|
||||
&__tab { |
||||
@include H6; |
||||
|
||||
width: 100%; |
||||
|
||||
&:last-of-type { |
||||
margin-right: 0; |
||||
} |
||||
|
||||
& button { |
||||
font-size: unset; |
||||
} |
||||
|
||||
&.tab--active button { |
||||
color: var(--color-primary-default); |
||||
} |
||||
} |
||||
} |
||||
} |
||||
|
||||
.gas-modal-content { |
||||
@include screen-sm-max { |
||||
width: 100%; |
||||
} |
||||
|
||||
&__basic-tab { |
||||
height: 219px; |
||||
} |
||||
|
||||
|
||||
&__info-row, |
||||
&__info-row--fade { |
||||
@include H7; |
||||
|
||||
width: 100%; |
||||
background: var(--color-background-alternative); |
||||
padding: 15px 21px; |
||||
display: flex; |
||||
flex-flow: column; |
||||
color: var(--color-text-alternative); |
||||
|
||||
&__send-info, |
||||
&__transaction-info, |
||||
&__total-info, |
||||
&__fiat-total-info { |
||||
display: flex; |
||||
flex-flow: row; |
||||
justify-content: space-between; |
||||
} |
||||
|
||||
&__fiat-total-info { |
||||
justify-content: flex-end; |
||||
} |
||||
|
||||
&__total-info { |
||||
&__label { |
||||
@include Paragraph; |
||||
|
||||
@include screen-sm-max { |
||||
@include H6; |
||||
} |
||||
} |
||||
|
||||
&__value { |
||||
@include Paragraph; |
||||
|
||||
font-weight: bold; |
||||
|
||||
@include screen-sm-max { |
||||
@include H6; |
||||
} |
||||
} |
||||
} |
||||
|
||||
&__transaction-info, |
||||
&__send-info { |
||||
&__label { |
||||
@include H7; |
||||
} |
||||
|
||||
&__value { |
||||
@include H6; |
||||
} |
||||
} |
||||
} |
||||
|
||||
&__info-row--fade { |
||||
background: var(--color-background-default); |
||||
color: var(--color-text-muted); |
||||
border-top: 1px solid var(--color-border-muted); |
||||
} |
||||
} |
@ -1,308 +0,0 @@ |
||||
import React from 'react'; |
||||
import sinon from 'sinon'; |
||||
import { shallowWithContext } from '../../../../../test/lib/render-helpers'; |
||||
import { GAS_ESTIMATE_TYPES } from '../../../../helpers/constants/common'; |
||||
|
||||
import ButtonGroup from '../../../ui/button-group'; |
||||
import GasPriceButtonGroup from './gas-price-button-group.component'; |
||||
|
||||
describe('GasPriceButtonGroup Component', () => { |
||||
let mockButtonPropsAndFlags; |
||||
let mockGasPriceButtonGroupProps; |
||||
let wrapper; |
||||
|
||||
beforeEach(() => { |
||||
mockGasPriceButtonGroupProps = { |
||||
buttonDataLoading: false, |
||||
className: 'gas-price-button-group', |
||||
gasButtonInfo: [ |
||||
{ |
||||
gasEstimateType: GAS_ESTIMATE_TYPES.SLOW, |
||||
feeInPrimaryCurrency: '$0.52', |
||||
feeInSecondaryCurrency: '0.0048 ETH', |
||||
timeEstimate: '~ 1 min 0 sec', |
||||
priceInHexWei: '0xa1b2c3f', |
||||
}, |
||||
{ |
||||
gasEstimateType: GAS_ESTIMATE_TYPES.AVERAGE, |
||||
feeInPrimaryCurrency: '$0.39', |
||||
feeInSecondaryCurrency: '0.004 ETH', |
||||
timeEstimate: '~ 1 min 30 sec', |
||||
priceInHexWei: '0xa1b2c39', |
||||
}, |
||||
{ |
||||
gasEstimateType: GAS_ESTIMATE_TYPES.FAST, |
||||
feeInPrimaryCurrency: '$0.30', |
||||
feeInSecondaryCurrency: '0.00354 ETH', |
||||
timeEstimate: '~ 2 min 1 sec', |
||||
priceInHexWei: '0xa1b2c30', |
||||
}, |
||||
], |
||||
handleGasPriceSelection: sinon.spy(), |
||||
noButtonActiveByDefault: true, |
||||
defaultActiveButtonIndex: 2, |
||||
showCheck: true, |
||||
}; |
||||
|
||||
mockButtonPropsAndFlags = { |
||||
className: mockGasPriceButtonGroupProps.className, |
||||
handleGasPriceSelection: |
||||
mockGasPriceButtonGroupProps.handleGasPriceSelection, |
||||
showCheck: mockGasPriceButtonGroupProps.showCheck, |
||||
}; |
||||
|
||||
sinon.spy(GasPriceButtonGroup.prototype, 'renderButton'); |
||||
sinon.spy(GasPriceButtonGroup.prototype, 'renderButtonContent'); |
||||
|
||||
wrapper = shallowWithContext( |
||||
<GasPriceButtonGroup {...mockGasPriceButtonGroupProps} />, |
||||
); |
||||
}); |
||||
|
||||
afterEach(() => { |
||||
sinon.restore(); |
||||
}); |
||||
|
||||
describe('render', () => { |
||||
it('should render a ButtonGroup', () => { |
||||
expect(wrapper.is(ButtonGroup)).toStrictEqual(true); |
||||
}); |
||||
|
||||
it('should render the correct props on the ButtonGroup', () => { |
||||
const { className, defaultActiveButtonIndex, noButtonActiveByDefault } = |
||||
wrapper.props(); |
||||
expect(className).toStrictEqual('gas-price-button-group'); |
||||
expect(defaultActiveButtonIndex).toStrictEqual(2); |
||||
expect(noButtonActiveByDefault).toStrictEqual(true); |
||||
}); |
||||
|
||||
function renderButtonArgsTest(i, mockPropsAndFlags) { |
||||
expect( |
||||
GasPriceButtonGroup.prototype.renderButton.getCall(i).args, |
||||
).toStrictEqual([ |
||||
{ ...mockGasPriceButtonGroupProps.gasButtonInfo[i] }, |
||||
mockPropsAndFlags, |
||||
i, |
||||
]); |
||||
} |
||||
|
||||
it('should call this.renderButton 3 times, with the correct args', () => { |
||||
expect( |
||||
GasPriceButtonGroup.prototype.renderButton.callCount, |
||||
).toStrictEqual(3); |
||||
renderButtonArgsTest(0, mockButtonPropsAndFlags); |
||||
renderButtonArgsTest(1, mockButtonPropsAndFlags); |
||||
renderButtonArgsTest(2, mockButtonPropsAndFlags); |
||||
}); |
||||
|
||||
it('should show loading if buttonDataLoading', () => { |
||||
wrapper.setProps({ buttonDataLoading: true }); |
||||
expect(wrapper.is('div')).toStrictEqual(true); |
||||
expect( |
||||
wrapper.hasClass('gas-price-button-group__loading-container'), |
||||
).toStrictEqual(true); |
||||
expect(wrapper.text()).toStrictEqual('loading'); |
||||
}); |
||||
}); |
||||
|
||||
describe('renderButton', () => { |
||||
let wrappedRenderButtonResult; |
||||
|
||||
beforeEach(() => { |
||||
GasPriceButtonGroup.prototype.renderButtonContent.resetHistory(); |
||||
const renderButtonResult = wrapper |
||||
.instance() |
||||
.renderButton( |
||||
{ ...mockGasPriceButtonGroupProps.gasButtonInfo[0] }, |
||||
mockButtonPropsAndFlags, |
||||
); |
||||
wrappedRenderButtonResult = shallowWithContext(renderButtonResult); |
||||
}); |
||||
|
||||
it('should render a button', () => { |
||||
expect(wrappedRenderButtonResult.type()).toStrictEqual('button'); |
||||
}); |
||||
|
||||
it('should call the correct method when clicked', () => { |
||||
expect( |
||||
mockGasPriceButtonGroupProps.handleGasPriceSelection.callCount, |
||||
).toStrictEqual(0); |
||||
wrappedRenderButtonResult.props().onClick(); |
||||
expect( |
||||
mockGasPriceButtonGroupProps.handleGasPriceSelection.callCount, |
||||
).toStrictEqual(1); |
||||
expect( |
||||
mockGasPriceButtonGroupProps.handleGasPriceSelection.getCall(0).args, |
||||
).toStrictEqual([ |
||||
{ |
||||
gasPrice: mockGasPriceButtonGroupProps.gasButtonInfo[0].priceInHexWei, |
||||
gasEstimateType: |
||||
mockGasPriceButtonGroupProps.gasButtonInfo[0].gasEstimateType, |
||||
}, |
||||
]); |
||||
}); |
||||
|
||||
it('should call this.renderButtonContent with the correct args', () => { |
||||
expect( |
||||
GasPriceButtonGroup.prototype.renderButtonContent.callCount, |
||||
).toStrictEqual(1); |
||||
const { |
||||
feeInPrimaryCurrency, |
||||
feeInSecondaryCurrency, |
||||
timeEstimate, |
||||
gasEstimateType, |
||||
} = mockGasPriceButtonGroupProps.gasButtonInfo[0]; |
||||
const { showCheck, className } = mockGasPriceButtonGroupProps; |
||||
expect( |
||||
GasPriceButtonGroup.prototype.renderButtonContent.getCall(0).args, |
||||
).toStrictEqual([ |
||||
{ |
||||
gasEstimateType, |
||||
feeInPrimaryCurrency, |
||||
feeInSecondaryCurrency, |
||||
timeEstimate, |
||||
}, |
||||
{ |
||||
showCheck, |
||||
className, |
||||
}, |
||||
]); |
||||
}); |
||||
}); |
||||
|
||||
describe('renderButtonContent', () => { |
||||
it('should render a label if passed a gasEstimateType', () => { |
||||
const renderButtonContentResult = wrapper.instance().renderButtonContent( |
||||
{ |
||||
gasEstimateType: 'SLOW', |
||||
}, |
||||
{ |
||||
className: 'someClass', |
||||
}, |
||||
); |
||||
const wrappedRenderButtonContentResult = shallowWithContext( |
||||
renderButtonContentResult, |
||||
); |
||||
expect( |
||||
wrappedRenderButtonContentResult.childAt(0).children(), |
||||
).toHaveLength(1); |
||||
expect( |
||||
wrappedRenderButtonContentResult.find('.someClass__label').text(), |
||||
).toStrictEqual('slow'); |
||||
}); |
||||
|
||||
it('should render a feeInPrimaryCurrency if passed a feeInPrimaryCurrency', () => { |
||||
const renderButtonContentResult = |
||||
GasPriceButtonGroup.prototype.renderButtonContent( |
||||
{ |
||||
feeInPrimaryCurrency: 'mockFeeInPrimaryCurrency', |
||||
}, |
||||
{ |
||||
className: 'someClass', |
||||
}, |
||||
); |
||||
const wrappedRenderButtonContentResult = shallowWithContext( |
||||
renderButtonContentResult, |
||||
); |
||||
expect( |
||||
wrappedRenderButtonContentResult.childAt(0).children(), |
||||
).toHaveLength(1); |
||||
expect( |
||||
wrappedRenderButtonContentResult |
||||
.find('.someClass__primary-currency') |
||||
.text(), |
||||
).toStrictEqual('mockFeeInPrimaryCurrency'); |
||||
}); |
||||
|
||||
it('should render a feeInSecondaryCurrency if passed a feeInSecondaryCurrency', () => { |
||||
const renderButtonContentResult = |
||||
GasPriceButtonGroup.prototype.renderButtonContent( |
||||
{ |
||||
feeInSecondaryCurrency: 'mockFeeInSecondaryCurrency', |
||||
}, |
||||
{ |
||||
className: 'someClass', |
||||
}, |
||||
); |
||||
const wrappedRenderButtonContentResult = shallowWithContext( |
||||
renderButtonContentResult, |
||||
); |
||||
expect( |
||||
wrappedRenderButtonContentResult.childAt(0).children(), |
||||
).toHaveLength(1); |
||||
expect( |
||||
wrappedRenderButtonContentResult |
||||
.find('.someClass__secondary-currency') |
||||
.text(), |
||||
).toStrictEqual('mockFeeInSecondaryCurrency'); |
||||
}); |
||||
|
||||
it('should render a timeEstimate if passed a timeEstimate', () => { |
||||
const renderButtonContentResult = |
||||
GasPriceButtonGroup.prototype.renderButtonContent( |
||||
{ |
||||
timeEstimate: 'mockTimeEstimate', |
||||
}, |
||||
{ |
||||
className: 'someClass', |
||||
}, |
||||
); |
||||
const wrappedRenderButtonContentResult = shallowWithContext( |
||||
renderButtonContentResult, |
||||
); |
||||
expect( |
||||
wrappedRenderButtonContentResult.childAt(0).children(), |
||||
).toHaveLength(1); |
||||
expect( |
||||
wrappedRenderButtonContentResult |
||||
.find('.someClass__time-estimate') |
||||
.text(), |
||||
).toStrictEqual('mockTimeEstimate'); |
||||
}); |
||||
|
||||
it('should render a check if showCheck is true', () => { |
||||
const renderButtonContentResult = |
||||
GasPriceButtonGroup.prototype.renderButtonContent( |
||||
{}, |
||||
{ |
||||
className: 'someClass', |
||||
showCheck: true, |
||||
}, |
||||
); |
||||
const wrappedRenderButtonContentResult = shallowWithContext( |
||||
renderButtonContentResult, |
||||
); |
||||
expect(wrappedRenderButtonContentResult.find('.fa-check')).toHaveLength( |
||||
1, |
||||
); |
||||
}); |
||||
|
||||
it('should render all elements if all args passed', () => { |
||||
const renderButtonContentResult = wrapper.instance().renderButtonContent( |
||||
{ |
||||
gasEstimateType: 'SLOW', |
||||
feeInPrimaryCurrency: 'mockFeeInPrimaryCurrency', |
||||
feeInSecondaryCurrency: 'mockFeeInSecondaryCurrency', |
||||
timeEstimate: 'mockTimeEstimate', |
||||
}, |
||||
{ |
||||
className: 'someClass', |
||||
showCheck: true, |
||||
}, |
||||
); |
||||
const wrappedRenderButtonContentResult = shallowWithContext( |
||||
renderButtonContentResult, |
||||
); |
||||
expect(wrappedRenderButtonContentResult.children()).toHaveLength(5); |
||||
}); |
||||
|
||||
it('should render no elements if all args passed', () => { |
||||
const renderButtonContentResult = |
||||
GasPriceButtonGroup.prototype.renderButtonContent({}, {}); |
||||
const wrappedRenderButtonContentResult = shallowWithContext( |
||||
renderButtonContentResult, |
||||
); |
||||
expect(wrappedRenderButtonContentResult.children()).toHaveLength(0); |
||||
}); |
||||
}); |
||||
}); |
@ -1,139 +0,0 @@ |
||||
import React, { Component } from 'react'; |
||||
import PropTypes from 'prop-types'; |
||||
import ButtonGroup from '../../../ui/button-group'; |
||||
import Button from '../../../ui/button'; |
||||
import { GAS_ESTIMATE_TYPES } from '../../../../helpers/constants/common'; |
||||
|
||||
const GAS_OBJECT_PROPTYPES_SHAPE = { |
||||
gasEstimateType: PropTypes.oneOf(Object.values(GAS_ESTIMATE_TYPES)) |
||||
.isRequired, |
||||
feeInPrimaryCurrency: PropTypes.string, |
||||
feeInSecondaryCurrency: PropTypes.string, |
||||
timeEstimate: PropTypes.string, |
||||
priceInHexWei: PropTypes.string, |
||||
}; |
||||
|
||||
export default class GasPriceButtonGroup extends Component { |
||||
static contextTypes = { |
||||
t: PropTypes.func, |
||||
}; |
||||
|
||||
static propTypes = { |
||||
buttonDataLoading: PropTypes.bool, |
||||
className: PropTypes.string, |
||||
defaultActiveButtonIndex: PropTypes.number, |
||||
gasButtonInfo: PropTypes.arrayOf( |
||||
PropTypes.shape(GAS_OBJECT_PROPTYPES_SHAPE), |
||||
), |
||||
handleGasPriceSelection: PropTypes.func, |
||||
newActiveButtonIndex: PropTypes.number, |
||||
noButtonActiveByDefault: PropTypes.bool, |
||||
showCheck: PropTypes.bool, |
||||
}; |
||||
|
||||
gasEstimateTypeLabel(gasEstimateType) { |
||||
if (gasEstimateType === GAS_ESTIMATE_TYPES.SLOW) { |
||||
return this.context.t('slow'); |
||||
} else if (gasEstimateType === GAS_ESTIMATE_TYPES.AVERAGE) { |
||||
return this.context.t('average'); |
||||
} else if (gasEstimateType === GAS_ESTIMATE_TYPES.FAST) { |
||||
return this.context.t('fast'); |
||||
} else if (gasEstimateType === GAS_ESTIMATE_TYPES.FASTEST) { |
||||
return this.context.t('fastest'); |
||||
} |
||||
throw new Error(`Unrecognized gas estimate type: ${gasEstimateType}`); |
||||
} |
||||
|
||||
renderButtonContent( |
||||
{ |
||||
gasEstimateType, |
||||
feeInPrimaryCurrency, |
||||
feeInSecondaryCurrency, |
||||
timeEstimate, |
||||
}, |
||||
{ className, showCheck }, |
||||
) { |
||||
return ( |
||||
<div> |
||||
{gasEstimateType && ( |
||||
<div className={`${className}__label`}> |
||||
{this.gasEstimateTypeLabel(gasEstimateType)} |
||||
</div> |
||||
)} |
||||
{timeEstimate && ( |
||||
<div className={`${className}__time-estimate`}>{timeEstimate}</div> |
||||
)} |
||||
{feeInPrimaryCurrency && ( |
||||
<div className={`${className}__primary-currency`}> |
||||
{feeInPrimaryCurrency} |
||||
</div> |
||||
)} |
||||
{feeInSecondaryCurrency && ( |
||||
<div className={`${className}__secondary-currency`}> |
||||
{feeInSecondaryCurrency} |
||||
</div> |
||||
)} |
||||
{showCheck && ( |
||||
<div className="button-check-wrapper"> |
||||
<i className="fa fa-check fa-sm" /> |
||||
</div> |
||||
)} |
||||
</div> |
||||
); |
||||
} |
||||
|
||||
renderButton( |
||||
{ priceInHexWei, ...renderableGasInfo }, |
||||
{ |
||||
buttonDataLoading: _, |
||||
handleGasPriceSelection, |
||||
...buttonContentPropsAndFlags |
||||
}, |
||||
index, |
||||
) { |
||||
return ( |
||||
<Button |
||||
onClick={() => |
||||
handleGasPriceSelection({ |
||||
gasPrice: priceInHexWei, |
||||
gasEstimateType: renderableGasInfo.gasEstimateType, |
||||
}) |
||||
} |
||||
key={`gas-price-button-${index}`} |
||||
> |
||||
{this.renderButtonContent( |
||||
renderableGasInfo, |
||||
buttonContentPropsAndFlags, |
||||
)} |
||||
</Button> |
||||
); |
||||
} |
||||
|
||||
render() { |
||||
const { |
||||
gasButtonInfo, |
||||
defaultActiveButtonIndex = 1, |
||||
newActiveButtonIndex, |
||||
noButtonActiveByDefault = false, |
||||
buttonDataLoading, |
||||
...buttonPropsAndFlags |
||||
} = this.props; |
||||
|
||||
return buttonDataLoading ? ( |
||||
<div className={`${buttonPropsAndFlags.className}__loading-container`}> |
||||
{this.context.t('loading')} |
||||
</div> |
||||
) : ( |
||||
<ButtonGroup |
||||
className={buttonPropsAndFlags.className} |
||||
defaultActiveButtonIndex={defaultActiveButtonIndex} |
||||
newActiveButtonIndex={newActiveButtonIndex} |
||||
noButtonActiveByDefault={noButtonActiveByDefault} |
||||
> |
||||
{gasButtonInfo.map((obj, index) => |
||||
this.renderButton(obj, buttonPropsAndFlags, index), |
||||
)} |
||||
</ButtonGroup> |
||||
); |
||||
} |
||||
} |
@ -1,47 +0,0 @@ |
||||
import React from 'react'; |
||||
import { GAS_ESTIMATE_TYPES } from '../../../../helpers/constants/common'; |
||||
import GasPriceButtonGroup from '.'; |
||||
|
||||
export default { |
||||
title: 'Components/App/GasCustomization/GasPriceButtonGroup', |
||||
id: __filename, |
||||
argTypes: { |
||||
handleGasPriceSelection: { |
||||
action: 'handleGasPriceSelection', |
||||
}, |
||||
}, |
||||
args: { |
||||
buttonDataLoading: false, |
||||
className: 'gas-price-button-group', |
||||
gasButtonInfo: [ |
||||
{ |
||||
gasEstimateType: GAS_ESTIMATE_TYPES.SLOW, |
||||
feeInPrimaryCurrency: '$0.52', |
||||
feeInSecondaryCurrency: '0.0048 ETH', |
||||
timeEstimate: '~ 1 min 0 sec', |
||||
priceInHexWei: '0xa1b2c3f', |
||||
}, |
||||
{ |
||||
gasEstimateType: GAS_ESTIMATE_TYPES.AVERAGE, |
||||
feeInPrimaryCurrency: '$0.39', |
||||
feeInSecondaryCurrency: '0.004 ETH', |
||||
timeEstimate: '~ 1 min 30 sec', |
||||
priceInHexWei: '0xa1b2c39', |
||||
}, |
||||
{ |
||||
gasEstimateType: GAS_ESTIMATE_TYPES.FAST, |
||||
feeInPrimaryCurrency: '$0.30', |
||||
feeInSecondaryCurrency: '0.00354 ETH', |
||||
timeEstimate: '~ 2 min 1 sec', |
||||
priceInHexWei: '0xa1b2c30', |
||||
}, |
||||
], |
||||
noButtonActiveByDefault: true, |
||||
defaultActiveButtonIndex: 2, |
||||
showCheck: true, |
||||
}, |
||||
}; |
||||
|
||||
export const DefaultStory = (args) => <GasPriceButtonGroup {...args} />; |
||||
|
||||
DefaultStory.storyName = 'Default'; |
@ -1 +0,0 @@ |
||||
export { default } from './gas-price-button-group.component'; |
@ -1,251 +0,0 @@ |
||||
.gas-price-button-group { |
||||
margin-top: 22px; |
||||
display: flex; |
||||
justify-content: space-evenly; |
||||
width: 100%; |
||||
padding-left: 20px; |
||||
padding-right: 20px; |
||||
|
||||
&__primary-currency { |
||||
@include H4; |
||||
|
||||
height: 20.5px; |
||||
margin-bottom: 7.5px; |
||||
} |
||||
|
||||
&__time-estimate { |
||||
margin-top: 5.5px; |
||||
color: var(--color-text-alternative); |
||||
height: 15.4px; |
||||
} |
||||
|
||||
&__loading-container { |
||||
height: 130px; |
||||
} |
||||
|
||||
.button-group__button, |
||||
.button-group__button--active { |
||||
@include H7; |
||||
|
||||
height: 130px; |
||||
max-width: 108px; |
||||
flex-direction: column; |
||||
align-items: center; |
||||
display: flex; |
||||
padding-top: 17px; |
||||
border-radius: 4px; |
||||
border-color: var(--color-primary-muted); |
||||
background: var(--color-background-default); |
||||
color: var(--color-text-alternative); |
||||
|
||||
div { |
||||
display: flex; |
||||
flex-direction: column; |
||||
align-items: center; |
||||
} |
||||
|
||||
i { |
||||
&:last-child { |
||||
display: none; |
||||
} |
||||
} |
||||
} |
||||
|
||||
.button-group__button--active { |
||||
border-color: var(--color-primary-default); |
||||
color: var(--color-text-alternative); |
||||
|
||||
i { |
||||
&:last-child { |
||||
display: flex; |
||||
color: var(--color-primary-default); |
||||
margin-top: 8px; |
||||
} |
||||
} |
||||
} |
||||
} |
||||
|
||||
.gas-price-button-group--small { |
||||
display: flex; |
||||
justify-content: stretch; |
||||
min-height: 54px; |
||||
|
||||
@include screen-sm-max { |
||||
max-width: 260px; |
||||
} |
||||
|
||||
&__button-fiat-price { |
||||
@include H6; |
||||
} |
||||
|
||||
&__button-label { |
||||
@include Paragraph; |
||||
} |
||||
|
||||
&__label { |
||||
font-weight: 500; |
||||
line-height: 16px; |
||||
padding-bottom: 4px; |
||||
} |
||||
|
||||
&__primary-currency { |
||||
@include H7; |
||||
|
||||
padding-bottom: 2px; |
||||
|
||||
@include screen-sm-max { |
||||
@include H8; |
||||
} |
||||
} |
||||
|
||||
&__secondary-currency { |
||||
@include H7; |
||||
|
||||
padding-bottom: 2px; |
||||
|
||||
@include screen-sm-max { |
||||
@include H8; |
||||
} |
||||
} |
||||
|
||||
&__loading-container { |
||||
height: 54px; |
||||
} |
||||
|
||||
.button-group__button, |
||||
.button-group__button--active { |
||||
background: var(--color-background-default); |
||||
color: var(--color-text-alternative); |
||||
padding: 4px; |
||||
|
||||
div { |
||||
display: flex; |
||||
flex-flow: column; |
||||
align-items: flex-start; |
||||
justify-content: flex-start; |
||||
} |
||||
|
||||
i { |
||||
&:last-child { |
||||
display: none; |
||||
} |
||||
} |
||||
} |
||||
|
||||
.button-group__button--active { |
||||
color: var(--color-background-default); |
||||
background: var(--color-primary-muted); |
||||
|
||||
i { |
||||
&:last-child { |
||||
display: flex; |
||||
color: var(--color-primary-default); |
||||
margin-top: 10px; |
||||
} |
||||
} |
||||
} |
||||
} |
||||
|
||||
.gas-price-button-group--alt { |
||||
display: flex; |
||||
justify-content: stretch; |
||||
width: 95%; |
||||
|
||||
&__button-fiat-price { |
||||
@include H6; |
||||
} |
||||
|
||||
&__button-label { |
||||
@include Paragraph; |
||||
} |
||||
|
||||
&__label { |
||||
@include H8; |
||||
|
||||
font-weight: 500; |
||||
text-transform: capitalize; |
||||
} |
||||
|
||||
&__primary-currency { |
||||
@include H7; |
||||
|
||||
margin-top: 3px; |
||||
} |
||||
|
||||
&__secondary-currency { |
||||
@include H7; |
||||
} |
||||
|
||||
&__loading-container { |
||||
height: 78px; |
||||
} |
||||
|
||||
&__time-estimate { |
||||
@include H7; |
||||
|
||||
font-weight: 500; |
||||
margin-top: 4px; |
||||
color: var(--color-text-default); |
||||
} |
||||
|
||||
.button-group__button, |
||||
.button-group__button--active { |
||||
height: 78px; |
||||
background: var(--color-background-default); |
||||
color: var(--color-text-default); |
||||
width: 108px; |
||||
height: 97px; |
||||
box-shadow: var(--shadow-size-sm) var(--color-shadow-default); |
||||
border-radius: 6px; |
||||
border: none; |
||||
|
||||
div { |
||||
display: flex; |
||||
flex-flow: column; |
||||
align-items: flex-start; |
||||
justify-content: flex-start; |
||||
position: relative; |
||||
} |
||||
|
||||
.button-check-wrapper { |
||||
display: none; |
||||
} |
||||
|
||||
&:first-child { |
||||
margin-right: 6px; |
||||
} |
||||
|
||||
&:last-child { |
||||
margin-left: 6px; |
||||
} |
||||
} |
||||
|
||||
.button-group__button--active { |
||||
background: var(--color-background-alternative); |
||||
border-color: var(--color-primary-default); |
||||
|
||||
&:first-child { |
||||
border-color: var(--color-primary-default); |
||||
} |
||||
|
||||
.button-check-wrapper { |
||||
height: 16px; |
||||
width: 16px; |
||||
border-radius: 8px; |
||||
position: absolute; |
||||
top: -11px; |
||||
right: -10px; |
||||
background: var(--color-background-alternative); |
||||
display: flex; |
||||
flex-flow: row; |
||||
justify-content: center; |
||||
align-items: center; |
||||
} |
||||
|
||||
i { |
||||
display: flex; |
||||
color: var(--color-primary-default); |
||||
font-weight: 900; |
||||
} |
||||
} |
||||
} |
@ -1,40 +0,0 @@ |
||||
import React, { Component } from 'react'; |
||||
import PropTypes from 'prop-types'; |
||||
|
||||
export default class GasSlider extends Component { |
||||
static propTypes = { |
||||
onChange: PropTypes.func, |
||||
lowLabel: PropTypes.string, |
||||
highLabel: PropTypes.string, |
||||
value: PropTypes.number, |
||||
step: PropTypes.number, |
||||
max: PropTypes.number, |
||||
min: PropTypes.number, |
||||
}; |
||||
|
||||
render() { |
||||
const { onChange, lowLabel, highLabel, value, step, max, min } = this.props; |
||||
|
||||
return ( |
||||
<div className="gas-slider"> |
||||
<input |
||||
className="gas-slider__input" |
||||
type="range" |
||||
step={step} |
||||
max={max} |
||||
min={min} |
||||
value={value} |
||||
id="gasSlider" |
||||
onChange={(event) => onChange(event.target.value)} |
||||
/> |
||||
<div className="gas-slider__bar"> |
||||
<div className="gas-slider__colored" /> |
||||
</div> |
||||
<div className="gas-slider__labels"> |
||||
<span>{lowLabel}</span> |
||||
<span>{highLabel}</span> |
||||
</div> |
||||
</div> |
||||
); |
||||
} |
||||
} |
@ -1,34 +0,0 @@ |
||||
import React from 'react'; |
||||
import GasSlider from '.'; |
||||
|
||||
export default { |
||||
title: 'Components/App/GasCustomization/GasSlider', |
||||
id: __filename, |
||||
argTypes: { |
||||
onChange: { |
||||
action: 'onChange', |
||||
}, |
||||
lowLabel: { |
||||
control: 'text', |
||||
}, |
||||
highLabel: { |
||||
control: 'text', |
||||
}, |
||||
value: { |
||||
control: 'number', |
||||
}, |
||||
step: { |
||||
control: 'number', |
||||
}, |
||||
max: { |
||||
control: 'number', |
||||
}, |
||||
min: { |
||||
control: 'number', |
||||
}, |
||||
}, |
||||
}; |
||||
|
||||
export const DefaultStory = () => <GasSlider />; |
||||
|
||||
DefaultStory.storyName = 'Default'; |
@ -1 +0,0 @@ |
||||
export { default } from './gas-slider.component'; |
@ -1,54 +0,0 @@ |
||||
.gas-slider { |
||||
position: relative; |
||||
width: 322px; |
||||
|
||||
&__input { |
||||
width: 322px; |
||||
margin-left: -2px; |
||||
z-index: 2; |
||||
} |
||||
|
||||
input[type=range] { |
||||
-webkit-appearance: none !important; |
||||
} |
||||
|
||||
input[type=range]::-webkit-slider-thumb { |
||||
-webkit-appearance: none !important; |
||||
height: 34px; |
||||
width: 34px; |
||||
background-color: var(--color-primary-default); |
||||
border-radius: 50%; |
||||
position: relative; |
||||
z-index: 10; |
||||
} |
||||
|
||||
&__bar { |
||||
height: 6px; |
||||
width: 322px; |
||||
background: var(--color-background-alternative); |
||||
display: flex; |
||||
justify-content: space-between; |
||||
position: absolute; |
||||
top: 16px; |
||||
z-index: 0; |
||||
border-radius: 4px; |
||||
} |
||||
|
||||
&__colored { |
||||
height: 6px; |
||||
border-radius: 4px; |
||||
margin-left: 102px; |
||||
width: 322px; |
||||
z-index: 1; |
||||
background-color: var(--color-primary-muted); |
||||
} |
||||
|
||||
&__labels { |
||||
@include H7; |
||||
|
||||
display: flex; |
||||
justify-content: space-between; |
||||
margin-top: -6px; |
||||
color: var(--color-text-alternative); |
||||
} |
||||
} |
@ -1,3 +0,0 @@ |
||||
@import './gas-slider/index'; |
||||
@import './gas-modal-page-container/index'; |
||||
@import './advanced-gas-inputs/index'; |
Loading…
Reference in new issue