Add icon to input
This commit is contained in:
parent
e5f96448fc
commit
3f490f03ca
@ -82,8 +82,11 @@ module.exports = {
|
|||||||
4: '0.25rem',
|
4: '0.25rem',
|
||||||
8: '0.5rem',
|
8: '0.5rem',
|
||||||
12: '0.75rem',
|
12: '0.75rem',
|
||||||
|
16: '1rem',
|
||||||
20: '1.25rem',
|
20: '1.25rem',
|
||||||
|
24: '1.5rem',
|
||||||
28: '1.75rem',
|
28: '1.75rem',
|
||||||
|
32: '2rem',
|
||||||
44: '2.75rem',
|
44: '2.75rem',
|
||||||
},
|
},
|
||||||
/*
|
/*
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import { render } from '@testing-library/react';
|
import { render } from '@testing-library/react';
|
||||||
|
|
||||||
import Button from './button';
|
import { Button } from './button';
|
||||||
|
|
||||||
describe('Button', () => {
|
describe('Button', () => {
|
||||||
it('should render successfully', () => {
|
it('should render successfully', () => {
|
||||||
|
@ -85,5 +85,3 @@ export function Button({
|
|||||||
</ButtonTag>
|
</ButtonTag>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export default Button;
|
|
||||||
|
1
libs/ui-toolkit/src/components/button/index.ts
Normal file
1
libs/ui-toolkit/src/components/button/index.ts
Normal file
@ -0,0 +1 @@
|
|||||||
|
export * from './button';
|
@ -1,6 +1,6 @@
|
|||||||
import { render } from '@testing-library/react';
|
import { render } from '@testing-library/react';
|
||||||
|
|
||||||
import Icon from './icon';
|
import { Icon } from './icon';
|
||||||
|
|
||||||
describe('Icon', () => {
|
describe('Icon', () => {
|
||||||
it('should render successfully', () => {
|
it('should render successfully', () => {
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
import { IconSvgPaths20, IconSvgPaths16, IconName } from '@blueprintjs/icons';
|
import { IconSvgPaths20, IconSvgPaths16, IconName } from '@blueprintjs/icons';
|
||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
|
|
||||||
|
export type { IconName } from '@blueprintjs/icons';
|
||||||
|
|
||||||
interface IconProps {
|
interface IconProps {
|
||||||
hasError?: boolean;
|
hasError?: boolean;
|
||||||
disabled?: boolean;
|
disabled?: boolean;
|
||||||
@ -9,11 +11,13 @@ interface IconProps {
|
|||||||
size?: 16 | 20 | 24 | 32 | 48 | 64;
|
size?: 16 | 20 | 24 | 32 | 48 | 64;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const Icon = ({ size = 20, name, className }: IconProps) => {
|
export const Icon = ({ size = 16, name, className }: IconProps) => {
|
||||||
const effectiveClassName = classNames(
|
const effectiveClassName = classNames(
|
||||||
{
|
{
|
||||||
'w-20': size === 20,
|
'w-20': size === 20,
|
||||||
'h-20': size === 20,
|
'h-20': size === 20,
|
||||||
|
'w-16': size === 16,
|
||||||
|
'h-16': size === 16,
|
||||||
},
|
},
|
||||||
className
|
className
|
||||||
);
|
);
|
||||||
@ -21,12 +25,10 @@ export const Icon = ({ size = 20, name, className }: IconProps) => {
|
|||||||
return (
|
return (
|
||||||
<svg className={effectiveClassName} viewBox={viewbox}>
|
<svg className={effectiveClassName} viewBox={viewbox}>
|
||||||
<g>
|
<g>
|
||||||
{(size <= 16 ? IconSvgPaths16 : IconSvgPaths20)[name].map((d) => (
|
{(size <= 16 ? IconSvgPaths16 : IconSvgPaths20)[name].map((d, key) => (
|
||||||
<path fill-rule="evenodd" clip-rule="evenodd" d={d} />
|
<path fillRule="evenodd" clipRule="evenodd" d={d} key={key} />
|
||||||
))}
|
))}
|
||||||
</g>
|
</g>
|
||||||
</svg>
|
</svg>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export default Icon;
|
|
||||||
|
1
libs/ui-toolkit/src/components/icon/index.ts
Normal file
1
libs/ui-toolkit/src/components/icon/index.ts
Normal file
@ -0,0 +1 @@
|
|||||||
|
export * from './icon';
|
1
libs/ui-toolkit/src/components/input/index.ts
Normal file
1
libs/ui-toolkit/src/components/input/index.ts
Normal file
@ -0,0 +1 @@
|
|||||||
|
export * from './input';
|
@ -1,6 +1,6 @@
|
|||||||
import { render } from '@testing-library/react';
|
import { render } from '@testing-library/react';
|
||||||
|
|
||||||
import Input from './input';
|
import { Input } from './input';
|
||||||
|
|
||||||
describe('Input', () => {
|
describe('Input', () => {
|
||||||
it('should render successfully', () => {
|
it('should render successfully', () => {
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
import { Story, Meta } from '@storybook/react';
|
import { Story, Meta } from '@storybook/react';
|
||||||
import { Input } from './input';
|
import { Input } from './input';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
component: Input,
|
component: Input,
|
||||||
title: 'Input',
|
title: 'Input',
|
||||||
@ -20,3 +19,11 @@ export const Disabled = Template.bind({});
|
|||||||
Disabled.args = {
|
Disabled.args = {
|
||||||
disabled: true,
|
disabled: true,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const IconPrepend: Story = () => (
|
||||||
|
<Input value="I type words" prependIconName="search" />
|
||||||
|
);
|
||||||
|
|
||||||
|
export const IconAppend: Story = () => (
|
||||||
|
<Input value="I type words and even more words" appendIconName="search" />
|
||||||
|
);
|
||||||
|
@ -1,10 +1,13 @@
|
|||||||
import { InputHTMLAttributes, forwardRef } from 'react';
|
import { InputHTMLAttributes, forwardRef } from 'react';
|
||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
|
import { Icon, IconName } from '../icon';
|
||||||
|
|
||||||
interface InputProps extends InputHTMLAttributes<HTMLInputElement> {
|
interface InputProps extends InputHTMLAttributes<HTMLInputElement> {
|
||||||
hasError?: boolean;
|
hasError?: boolean;
|
||||||
disabled?: boolean;
|
disabled?: boolean;
|
||||||
className?: string;
|
className?: string;
|
||||||
|
prependIconName?: IconName;
|
||||||
|
appendIconName?: IconName;
|
||||||
}
|
}
|
||||||
export const inputClassNames = ({
|
export const inputClassNames = ({
|
||||||
hasError,
|
hasError,
|
||||||
@ -21,8 +24,6 @@ export const inputClassNames = ({
|
|||||||
'items-center',
|
'items-center',
|
||||||
'box-border',
|
'box-border',
|
||||||
'h-28',
|
'h-28',
|
||||||
'pl-8',
|
|
||||||
'pr-8',
|
|
||||||
'border',
|
'border',
|
||||||
'border-light-gray-50',
|
'border-light-gray-50',
|
||||||
'bg-neutral-753',
|
'bg-neutral-753',
|
||||||
@ -32,6 +33,8 @@ export const inputClassNames = ({
|
|||||||
'focus-visible:outline-0',
|
'focus-visible:outline-0',
|
||||||
],
|
],
|
||||||
{
|
{
|
||||||
|
'pl-8': !className?.match(/(^| )p(l|x)-\d+( |$)/),
|
||||||
|
'pr-8': !className?.match(/(^| )p(r|x)-\d+( |$)/),
|
||||||
'border-vega-pink': hasError,
|
'border-vega-pink': hasError,
|
||||||
'text-disabled': disabled,
|
'text-disabled': disabled,
|
||||||
'bg-transparent': disabled,
|
'bg-transparent': disabled,
|
||||||
@ -54,13 +57,41 @@ export const inputStyle = ({
|
|||||||
}
|
}
|
||||||
: style;
|
: style;
|
||||||
|
|
||||||
export const Input = forwardRef<HTMLInputElement, InputProps>((props, ref) => (
|
export const Input = forwardRef<HTMLInputElement, InputProps>(
|
||||||
<input
|
({ prependIconName, appendIconName, className, ...props }, ref) => {
|
||||||
{...props}
|
className = `${className} h-28`;
|
||||||
ref={ref}
|
if (prependIconName) {
|
||||||
className={classNames(inputClassNames(props), 'h-28')}
|
className += ' pl-28';
|
||||||
style={inputStyle(props)}
|
}
|
||||||
/>
|
if (appendIconName) {
|
||||||
));
|
className += ' pr-28';
|
||||||
|
}
|
||||||
export default Input;
|
const input = (
|
||||||
|
<input
|
||||||
|
{...props}
|
||||||
|
ref={ref}
|
||||||
|
className={classNames(inputClassNames({ className, ...props }))}
|
||||||
|
style={inputStyle(props)}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
const iconName = prependIconName || appendIconName;
|
||||||
|
if (iconName !== undefined) {
|
||||||
|
const iconClassName = classNames(
|
||||||
|
['fill-light-gray-50', 'absolute', 'z-10'],
|
||||||
|
{
|
||||||
|
'left-8': prependIconName,
|
||||||
|
'right-8': appendIconName,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
const icon = <Icon name={iconName} className={iconClassName} size={16} />;
|
||||||
|
return (
|
||||||
|
<div className="inline-flex items-center relative">
|
||||||
|
{prependIconName && icon}
|
||||||
|
{input}
|
||||||
|
{appendIconName && icon}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return input;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
1
libs/ui-toolkit/src/components/inputError/index.ts
Normal file
1
libs/ui-toolkit/src/components/inputError/index.ts
Normal file
@ -0,0 +1 @@
|
|||||||
|
export * from './inputError';
|
@ -1,6 +1,6 @@
|
|||||||
import { render } from '@testing-library/react';
|
import { render } from '@testing-library/react';
|
||||||
|
|
||||||
import InputError from './inputError';
|
import { InputError } from './inputError';
|
||||||
|
|
||||||
describe('InputError', () => {
|
describe('InputError', () => {
|
||||||
it('should render successfully', () => {
|
it('should render successfully', () => {
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
import Icon from '../icon/icon';
|
import { Icon } from '../icon';
|
||||||
|
|
||||||
interface InputErrorProps {
|
interface InputErrorProps {
|
||||||
children?: React.ReactNode;
|
children?: React.ReactNode;
|
||||||
@ -39,5 +39,3 @@ export const InputError = ({
|
|||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export default InputError;
|
|
||||||
|
1
libs/ui-toolkit/src/components/select/index.ts
Normal file
1
libs/ui-toolkit/src/components/select/index.ts
Normal file
@ -0,0 +1 @@
|
|||||||
|
export * from './select';
|
@ -1,6 +1,6 @@
|
|||||||
import { render } from '@testing-library/react';
|
import { render } from '@testing-library/react';
|
||||||
|
|
||||||
import Select from './select';
|
import { Select } from './select';
|
||||||
|
|
||||||
describe('Select', () => {
|
describe('Select', () => {
|
||||||
it('should render successfully', () => {
|
it('should render successfully', () => {
|
||||||
|
@ -32,5 +32,3 @@ export function Select({
|
|||||||
</select>
|
</select>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export default Select;
|
|
||||||
|
1
libs/ui-toolkit/src/components/textArea/index.ts
Normal file
1
libs/ui-toolkit/src/components/textArea/index.ts
Normal file
@ -0,0 +1 @@
|
|||||||
|
export * from './textArea';
|
@ -1,6 +1,6 @@
|
|||||||
import { render } from '@testing-library/react';
|
import { render } from '@testing-library/react';
|
||||||
|
|
||||||
import TextArea from './textArea';
|
import { TextArea } from './textArea';
|
||||||
|
|
||||||
describe('TextArea', () => {
|
describe('TextArea', () => {
|
||||||
it('should render successfully', () => {
|
it('should render successfully', () => {
|
||||||
|
@ -28,5 +28,3 @@ export function TextArea({
|
|||||||
</textarea>
|
</textarea>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export default TextArea;
|
|
||||||
|
@ -1,7 +1,11 @@
|
|||||||
import * as EthereumUtils from './utils/web3';
|
import * as EthereumUtils from './utils/web3';
|
||||||
|
|
||||||
|
export { Button } from './components/button';
|
||||||
export { Callout } from './components/callout';
|
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 };
|
export { EthereumUtils };
|
||||||
|
export { EtherscanLink } from './components/etherscan-link';
|
||||||
|
export { Icon } from './components/icon';
|
||||||
|
export { Input } from './components/input';
|
||||||
|
export { InputError } from './components/inputError';
|
||||||
|
export { Select } from './components/select';
|
||||||
|
export { TextArea } from './components/textArea';
|
||||||
|
Loading…
Reference in New Issue
Block a user