Add textarea component

This commit is contained in:
Bartłomiej Głownia 2022-03-01 12:27:40 +01:00 committed by Matthew Russell
parent cdb5856983
commit 1f91ebe86f
10 changed files with 221 additions and 2 deletions

View File

@ -151,6 +151,7 @@ module.exports = {
extend: {
boxShadow: {
callout: '5px 5px 0 1px rgba(0, 0, 0, 0.05)',
focus: '0px 0px 0px 1px #000000, 0px 0px 3px 2px #FFE600',
},
},
};

View File

@ -1,6 +1,6 @@
import { render } from '@testing-library/react';
import Button from './Button';
import Button from './button';
describe('Button', () => {
it('should render successfully', () => {

View File

@ -1,5 +1,5 @@
import { Story, Meta } from '@storybook/react';
import { Button } from './Button';
import { Button } from './button';
export default {
component: Button,

View File

@ -0,0 +1,10 @@
import { render } from '@testing-library/react';
import Input from './input';
describe('Input', () => {
it('should render successfully', () => {
const { baseElement } = render(<Input />);
expect(baseElement).toBeTruthy();
});
});

View File

@ -0,0 +1,22 @@
import { Story, Meta } from '@storybook/react';
import { Input } from './input';
export default {
component: Input,
title: 'Input',
} as Meta;
const Template: Story = (args) => <Input {...args} value="I type words" />;
export const Default = Template.bind({});
Default.args = {};
export const WithError = Template.bind({});
WithError.args = {
hasError: true,
};
export const Disabled = Template.bind({});
Disabled.args = {
disabled: true,
};

View File

@ -0,0 +1,75 @@
import classNames from 'classnames';
/* eslint-disable-next-line */
export interface InputProps {
onChange?: React.FormEventHandler<HTMLInputElement>;
hasError?: boolean;
disabled?: boolean;
className?: string;
value?: string | number;
}
export const inputClassNames = ({
hasError,
disabled,
className,
}: {
hasError?: boolean;
disabled?: boolean;
className?: string;
}) =>
classNames(
[
'inline-flex',
'items-center',
'box-border',
'h-28',
'pl-8',
'pr-8',
'border',
'border-light-gray-50',
'bg-neutral-753',
'text-light-gray-50',
'text-ui',
'focus-visible:shadow-focus',
'focus-visible:outline-0',
],
{
'border-vega-pink': hasError,
'text-disabled': disabled,
'bg-transparent': disabled,
},
className
);
export const inputStyle = ({ disabled }: { disabled?: boolean }) => {
const style: React.CSSProperties = {};
if (disabled) {
style.backgroundImage =
'url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAYAAAAGCAYAAADgzO9IAAAAAXNSR0IArs4c6QAAACNJREFUGFdjtLS0/M8ABcePH2eEsRlJl4BpBdHIuuFmEi0BABqjEQVjx/LTAAAAAElFTkSuQmCC)';
}
return style;
};
export function Input({
hasError,
onChange,
disabled,
className,
value,
}: InputProps) {
return (
<input
onChange={onChange}
className={classNames(
inputClassNames({ hasError, disabled, className }),
'h-28'
)}
value={value}
disabled={disabled}
style={inputStyle({ disabled })}
/>
);
}
export default Input;

View File

@ -0,0 +1,10 @@
import { render } from '@testing-library/react';
import TextArea from './textArea';
describe('TextArea', () => {
it('should render successfully', () => {
const { baseElement } = render(<TextArea />);
expect(baseElement).toBeTruthy();
});
});

View File

@ -0,0 +1,26 @@
import { Story, Meta } from '@storybook/react';
import { TextArea } from './textArea';
export default {
component: TextArea,
title: 'TextArea',
} as Meta;
const Template: Story = (args) => (
<TextArea {...args} className="h-48">
I type words
</TextArea>
);
export const Default = Template.bind({});
Default.args = {};
export const WithError = Template.bind({});
WithError.args = {
hasError: true,
};
export const Disabled = Template.bind({});
Disabled.args = {
disabled: true,
};

View File

@ -0,0 +1,73 @@
import classNames from 'classnames';
/* eslint-disable-next-line */
export interface TextAreaProps {
onChange?: React.FormEventHandler<HTMLTextAreaElement>;
hasError?: boolean;
disabled?: boolean;
className?: string;
value?: string | number;
children?: React.ReactNode;
}
export const inputClassNames = ({
hasError,
disabled,
className,
}: {
hasError?: boolean;
disabled?: boolean;
className?: string;
}) =>
classNames(
[
'inline-flex',
'items-center',
'box-border',
'pl-8',
'pr-8',
'border',
'border-light-gray-50',
'bg-neutral-753',
'text-light-gray-50',
'text-ui',
'focus-visible:shadow-focus',
'focus-visible:outline-0',
],
{
'border-vega-pink': hasError,
'text-disabled': disabled,
'bg-transparent': disabled,
},
className
);
export const inputStyle = ({ disabled }: { disabled?: boolean }) => {
const style: React.CSSProperties = {};
if (disabled) {
style.backgroundImage =
'url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAYAAAAGCAYAAADgzO9IAAAAAXNSR0IArs4c6QAAACNJREFUGFdjtLS0/M8ABcePH2eEsRlJl4BpBdHIuuFmEi0BABqjEQVjx/LTAAAAAElFTkSuQmCC)';
}
return style;
};
export function TextArea({
hasError,
onChange,
disabled,
className,
children,
}: TextAreaProps) {
return (
<textarea
onChange={onChange}
className={inputClassNames({ hasError, disabled, className })}
disabled={disabled}
style={inputStyle({ disabled })}
>
{children}
</textarea>
);
}
export default TextArea;

View File

@ -1,5 +1,7 @@
import * as EthereumUtils from './utils/web3';
export { Callout } from './components/callout';
export { Button } from './components/button/button';
export { Input } from './components/input/input';
export { EtherscanLink } from './components/etherscan-link';
export { EthereumUtils };