mirror of
https://github.com/kremalicious/metamask-extension.git
synced 2024-12-23 09:52:26 +01:00
parent
2e2bd0fce5
commit
180ead8175
3
ui/components/ui/slider/index.js
Normal file
3
ui/components/ui/slider/index.js
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
import Slider from './slider.component';
|
||||||
|
|
||||||
|
export default Slider;
|
48
ui/components/ui/slider/index.scss
Normal file
48
ui/components/ui/slider/index.scss
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
.slider {
|
||||||
|
display: inline-block;
|
||||||
|
width: 100%;
|
||||||
|
|
||||||
|
&__heading,
|
||||||
|
&__footer {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__heading-title {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
> p {
|
||||||
|
margin-left: 10px;
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&__heading-detail > p {
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__footer-info {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
> p {
|
||||||
|
font-size: 12px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&__footer-edit > button {
|
||||||
|
border: none;
|
||||||
|
background: none;
|
||||||
|
font-size: 12px;
|
||||||
|
color: $Blue-500;
|
||||||
|
|
||||||
|
&:focus {
|
||||||
|
outline: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
h6 {
|
||||||
|
margin-inline-end: 6px;
|
||||||
|
}
|
||||||
|
}
|
135
ui/components/ui/slider/slider.component.js
Normal file
135
ui/components/ui/slider/slider.component.js
Normal file
@ -0,0 +1,135 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import PropTypes from 'prop-types';
|
||||||
|
import MaterialSlider from '@material-ui/core/Slider';
|
||||||
|
import { withStyles } from '@material-ui/core/styles';
|
||||||
|
|
||||||
|
import {
|
||||||
|
COLORS,
|
||||||
|
FONT_WEIGHT,
|
||||||
|
TYPOGRAPHY,
|
||||||
|
} from '../../../helpers/constants/design-system';
|
||||||
|
|
||||||
|
import InfoTooltip from '../info-tooltip/info-tooltip';
|
||||||
|
import Typography from '../typography/typography';
|
||||||
|
|
||||||
|
const styles = {
|
||||||
|
root: {
|
||||||
|
height: 6,
|
||||||
|
padding: '6px 0',
|
||||||
|
},
|
||||||
|
rail: {
|
||||||
|
borderRadius: 50,
|
||||||
|
background: '#D6D9DC',
|
||||||
|
height: 6,
|
||||||
|
},
|
||||||
|
track: {
|
||||||
|
borderRadius: 50,
|
||||||
|
background: '#037DD6',
|
||||||
|
height: 6,
|
||||||
|
},
|
||||||
|
thumb: {
|
||||||
|
'height': 20,
|
||||||
|
'width': 20,
|
||||||
|
'marginTop': -7,
|
||||||
|
'marginLeft': -7,
|
||||||
|
'backgroundColor': '#037DD6',
|
||||||
|
'border': '1px solid #EAF6FF',
|
||||||
|
'boxSizing': 'border-box',
|
||||||
|
'boxShadow': '0px 0px 14px 0px rgba(0, 0, 0, 0.18)',
|
||||||
|
'&:focus, &$active': {
|
||||||
|
height: 20,
|
||||||
|
width: 20,
|
||||||
|
marginTop: -7,
|
||||||
|
marginLeft: -7,
|
||||||
|
boxShadow: '0px 0px 14px 0px rgba(0, 0, 0, 0.18)',
|
||||||
|
},
|
||||||
|
'&:hover': {
|
||||||
|
height: 22,
|
||||||
|
width: 22,
|
||||||
|
marginTop: -8,
|
||||||
|
marginLeft: -8,
|
||||||
|
border: 'none',
|
||||||
|
boxShadow: '0px 0px 14px 0px rgba(0, 0, 0, 0.18)',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
const Slider = ({
|
||||||
|
editText,
|
||||||
|
infoText,
|
||||||
|
onEdit,
|
||||||
|
titleDetail,
|
||||||
|
titleText,
|
||||||
|
tooltipText,
|
||||||
|
valueText,
|
||||||
|
...rest
|
||||||
|
}) => (
|
||||||
|
<div className="slider">
|
||||||
|
<div className="slider__heading">
|
||||||
|
<div className="slider__heading-title">
|
||||||
|
{titleText && (
|
||||||
|
<Typography
|
||||||
|
tag={TYPOGRAPHY.H6}
|
||||||
|
fontWeight={FONT_WEIGHT.BOLD}
|
||||||
|
variant={TYPOGRAPHY.H6}
|
||||||
|
>
|
||||||
|
{titleText}
|
||||||
|
</Typography>
|
||||||
|
)}
|
||||||
|
{tooltipText && (
|
||||||
|
<InfoTooltip position="top" contentText={tooltipText} />
|
||||||
|
)}
|
||||||
|
{valueText && (
|
||||||
|
<Typography tag={TYPOGRAPHY.Paragraph} color={COLORS.UI4}>
|
||||||
|
{valueText}
|
||||||
|
</Typography>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
{titleDetail && (
|
||||||
|
<div className="slider__heading-detail">
|
||||||
|
<Typography tag={TYPOGRAPHY.Paragraph} color={COLORS.UI4}>
|
||||||
|
{titleDetail}
|
||||||
|
</Typography>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
<MaterialSlider {...rest} />
|
||||||
|
<div className="slider__footer">
|
||||||
|
<div className="slider__footer-info">
|
||||||
|
{infoText && (
|
||||||
|
<Typography tag={TYPOGRAPHY.Paragraph} color={COLORS.UI4}>
|
||||||
|
{infoText}
|
||||||
|
</Typography>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
<div className="slider__footer-edit">
|
||||||
|
{onEdit && (
|
||||||
|
<button onClick={onEdit} aria-label="edit as numeric input">
|
||||||
|
{editText}
|
||||||
|
</button>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
|
||||||
|
Slider.defaultProps = {
|
||||||
|
editText: 'Edit',
|
||||||
|
};
|
||||||
|
|
||||||
|
Slider.propTypes = {
|
||||||
|
editText: PropTypes.oneOfType([PropTypes.string, PropTypes.node]),
|
||||||
|
infoText: PropTypes.oneOfType([PropTypes.string, PropTypes.node]),
|
||||||
|
titleDetail: PropTypes.oneOfType([PropTypes.string, PropTypes.node]),
|
||||||
|
titleText: PropTypes.oneOfType([PropTypes.string, PropTypes.node]),
|
||||||
|
tooltipText: PropTypes.oneOfType([PropTypes.string, PropTypes.node]),
|
||||||
|
valueText: PropTypes.oneOfType([PropTypes.string, PropTypes.node]),
|
||||||
|
max: PropTypes.number,
|
||||||
|
min: PropTypes.number,
|
||||||
|
onChange: PropTypes.func,
|
||||||
|
onEdit: PropTypes.func,
|
||||||
|
step: PropTypes.number,
|
||||||
|
value: PropTypes.number,
|
||||||
|
};
|
||||||
|
|
||||||
|
export default withStyles(styles)(Slider);
|
58
ui/components/ui/slider/slider.component.test.js
Normal file
58
ui/components/ui/slider/slider.component.test.js
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import { fireEvent, render } from '@testing-library/react';
|
||||||
|
|
||||||
|
import Slider from './slider.component';
|
||||||
|
|
||||||
|
describe('Slider Component', () => {
|
||||||
|
describe('rendering', () => {
|
||||||
|
it('should render properly', () => {
|
||||||
|
expect(() => {
|
||||||
|
render(<Slider />);
|
||||||
|
}).not.toThrow();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should contain passed header props', () => {
|
||||||
|
const wrapper = render(
|
||||||
|
<Slider
|
||||||
|
titleText="Slider Title Text"
|
||||||
|
tooltipText="Slider Tooltip Text"
|
||||||
|
valueText="$ 00.00"
|
||||||
|
titleDetail="100 GWEI"
|
||||||
|
/>,
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(wrapper.getAllByText('Slider Title Text')).toBeDefined();
|
||||||
|
expect(wrapper.getAllByText('$ 00.00')).toBeDefined();
|
||||||
|
expect(wrapper.getAllByText('100 GWEI')).toBeDefined();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should contain passed footer props', () => {
|
||||||
|
const wrapper = render(
|
||||||
|
<Slider
|
||||||
|
infoText="Footer Info Text"
|
||||||
|
editText="Edit GWEI"
|
||||||
|
onEdit={() => {
|
||||||
|
console.log('on edit click');
|
||||||
|
}}
|
||||||
|
/>,
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(wrapper.getAllByText('Footer Info Text')).toBeDefined();
|
||||||
|
expect(
|
||||||
|
wrapper.getByRole('button', { name: 'edit as numeric input' }),
|
||||||
|
).toBeDefined();
|
||||||
|
expect(wrapper.getAllByText('Edit GWEI')).toBeDefined();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should call onEdit callback when edit button is clicked', () => {
|
||||||
|
const mockEditFn = jest.fn();
|
||||||
|
const wrapper = render(
|
||||||
|
<Slider infoText="Footer Info Text" onEdit={mockEditFn} />,
|
||||||
|
);
|
||||||
|
|
||||||
|
const editButton = wrapper.getByRole('button');
|
||||||
|
fireEvent.click(editButton);
|
||||||
|
expect(mockEditFn).toHaveBeenCalledTimes(1);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
33
ui/components/ui/slider/slider.stories.js
Normal file
33
ui/components/ui/slider/slider.stories.js
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import Slider from '.';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
title: 'Slider',
|
||||||
|
id: __filename,
|
||||||
|
};
|
||||||
|
|
||||||
|
export const slider = () => <Slider />;
|
||||||
|
|
||||||
|
export const sliderWithSteps = () => <Slider step={10} />;
|
||||||
|
|
||||||
|
export const sliderWithHeader = () => (
|
||||||
|
<Slider
|
||||||
|
titleText="Slider Title Text"
|
||||||
|
tooltipText="Slider Tooltip Text"
|
||||||
|
valueText="$ 00.00"
|
||||||
|
titleDetail="100 GWEI"
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
|
||||||
|
export const sliderWithFooter = () => (
|
||||||
|
<Slider
|
||||||
|
titleText="Slider Title Text"
|
||||||
|
tooltipText="Slider Tooltip Text"
|
||||||
|
valueText="$ 00.00"
|
||||||
|
titleDetail="100 GWEI"
|
||||||
|
infoText="Footer Info Text"
|
||||||
|
onEdit={() => {
|
||||||
|
console.log('on edit click');
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
);
|
@ -45,6 +45,7 @@
|
|||||||
@import 'readonly-input/index';
|
@import 'readonly-input/index';
|
||||||
@import 'sender-to-recipient/index';
|
@import 'sender-to-recipient/index';
|
||||||
@import 'snackbar/index';
|
@import 'snackbar/index';
|
||||||
|
@import 'slider/index';
|
||||||
@import 'tabs/index';
|
@import 'tabs/index';
|
||||||
@import 'toggle-button/index';
|
@import 'toggle-button/index';
|
||||||
@import 'token-balance/index';
|
@import 'token-balance/index';
|
||||||
|
@ -45,7 +45,7 @@ export const TYPOGRAPHY = {
|
|||||||
H7: 'h7',
|
H7: 'h7',
|
||||||
H8: 'h8',
|
H8: 'h8',
|
||||||
H9: 'h9',
|
H9: 'h9',
|
||||||
Paragraph: 'paragraph',
|
Paragraph: 'p',
|
||||||
};
|
};
|
||||||
|
|
||||||
const NONE = 'none';
|
const NONE = 'none';
|
||||||
|
Loading…
Reference in New Issue
Block a user