Skip to content

Commit

Permalink
Merge pull request #38 from sonalake/feature/text-input
Browse files Browse the repository at this point in the history
Feature/text input
  • Loading branch information
krzysztoflukawski authored Feb 23, 2022
2 parents 5d933fd + 64cfb62 commit 1e28341
Show file tree
Hide file tree
Showing 10 changed files with 140 additions and 0 deletions.
1 change: 1 addition & 0 deletions .eslintrc
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
"no-nested-ternary": "error",
"react/self-closing-comp": "warn",
"react/button-has-type": "warn",
"arrow-body-style": "error",
"jest/no-focused-tests": "error",
"import/first": "error",
"import/no-duplicates": "error",
Expand Down
1 change: 1 addition & 0 deletions src/ui/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,4 @@ export * from './pagination';
export * from './property-item';
export * from './table';
export * from './typography';
export * from './text-input';
2 changes: 2 additions & 0 deletions src/ui/input/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export * from './input.model';
export * from './input.util';
9 changes: 9 additions & 0 deletions src/ui/input/input.model.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
export type InputSize = 'md' | 'sm';

export type BaseInputProps = {
size?: InputSize;
disabled?: boolean;
readOnly?: boolean;
error?: boolean;
className?: string;
};
29 changes: 29 additions & 0 deletions src/ui/input/input.util.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import clsx from 'clsx';

import { InputSize } from './input.model';

type TextBasedInputClassProps = {
disabled?: boolean;
readOnly?: boolean;
error?: boolean;
size?: InputSize;
};

export const getTextBasedInputClasses = ({
disabled,
readOnly,
error,
size = 'md',
}: TextBasedInputClassProps) =>
clsx(
'appearance-none border rounded focus:outline-none placeholder-primary-300 bg-slate-100',
{
'py-1 px-2 text-sm': size === 'sm',
'py-3 px-4 text-base': size === 'md',
'border-primary-150 focus:shadow-primary-100': !error,
'border-error-100 focus:shadow-error-100': error,
'pointer-events-none': readOnly,
'text-neutral-200': disabled,
'text-black': !disabled,
}
);
1 change: 1 addition & 0 deletions src/ui/text-input/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './text-input.component';
29 changes: 29 additions & 0 deletions src/ui/text-input/text-input.component.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import React, { ComponentPropsWithRef, forwardRef } from 'react';
import clsx from 'clsx';

import { BaseInputProps, getTextBasedInputClasses } from '../input/';

type TextInputProps = Omit<ComponentPropsWithRef<'input'>, 'size'> &
BaseInputProps;

export const TextInput = forwardRef<HTMLInputElement, TextInputProps>(
({ disabled, readOnly, error, size, className, ...rest }, ref) => (
<input
ref={ref}
type="text"
disabled={disabled}
readOnly={readOnly}
aria-invalid={error || undefined}
className={clsx(
getTextBasedInputClasses({
disabled,
readOnly,
error,
size,
}),
className
)}
{...rest}
/>
)
);
16 changes: 16 additions & 0 deletions src/ui/text-input/text-input.spec.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import React from 'react';
import { render, screen } from '@testing-library/react';
import { axe } from 'jest-axe';

import { TextInput } from './text-input.component';

describe('Text-Input', () => {
test('renders an accessible text-input', async () => {
const { container } = render(
<TextInput defaultValue="Test Value" aria-label="test-input" />
);

expect(screen.getByRole('textbox')).toBeInTheDocument();
expect(await axe(container)).toHaveNoViolations();
});
});
47 changes: 47 additions & 0 deletions src/ui/text-input/text-input.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import React from 'react';
import { ComponentMeta, ComponentStory } from '@storybook/react';

import { TextInput } from './text-input.component';

export default {
title: 'Atoms/TextInput',
component: TextInput,
} as ComponentMeta<typeof TextInput>;

const Template: ComponentStory<typeof TextInput> = (args) => (
<TextInput {...args} />
);

export const Default = Template.bind({});
Default.args = {
defaultValue: 'Default',
};

export const WithPlaceholder = Template.bind({});
WithPlaceholder.args = {
placeholder: 'Placeholder',
};

export const Small = Template.bind({});
Small.args = {
size: 'sm',
defaultValue: 'Small',
};

export const WithError = Template.bind({});
WithError.args = {
error: true,
defaultValue: 'Error',
};

export const Disabled = Template.bind({});
Disabled.args = {
disabled: true,
defaultValue: 'Disabled',
};

export const Readonly = Template.bind({});
Readonly.args = {
readOnly: true,
defaultValue: 'Readonly',
};
5 changes: 5 additions & 0 deletions tailwind.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,15 @@ module.exports = {
},
neutral: {
100: '#dfe0dd',
200: '#636161',
},
black: '#1C2B36',
white: '#FFFFFF',
},
boxShadow: {
'primary-100': '0px 0px 5px #45a3db',
'error-100': '0px 0px 5px #e74c3c',
}
},
},
plugins: [],
Expand Down

0 comments on commit 1e28341

Please sign in to comment.