Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
61 changes: 61 additions & 0 deletions .storybook/input.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
import { ThemeProvider } from 'styled-components';
import { Input } from '../src/index';
import { theme } from '../src/theme';
import { GlobalStyles } from '../src/globalStyles';
import type { Meta, StoryObj } from '@storybook/react-vite';
import React from 'react';
import ArrowForwardIos from '@mui/icons-material/ArrowForwardIos';

const meta = {
component: Input,
decorators: [
(Story) => (
<div style={{ width: '100%', display: 'flex', flexDirection: 'column' }}>
<ThemeProvider theme={theme}>
<GlobalStyles />
<Story />
</ThemeProvider>
</div>
),
],
} satisfies Meta<typeof Input>;

export default meta;
type Story = StoryObj<typeof meta>;

export const Default: Story = {
args: {
type: 'text',
placeholder: 'Value...',
},
};

export const WithLabel: Story = {
args: {
type: 'text',
placeholder: 'Value...',
$labelContent: 'Text',
},
};

export const Example: Story = {
args: {
type: 'text',
placeholder: 'eg. Joe Dough',
$labelContent: 'Username',
},
};

export const Multiple: Story = {
render: () => (
<>
<Input type="text" placeholder="eg. Joe Dough" $labelContent="Username" />
<Input type="text" placeholder="eg. *******" $labelContent="Password" />
<Input
type="text"
placeholder="eg. *******"
$labelContent="Confirm Password"
/>
</>
),
};
4 changes: 2 additions & 2 deletions src/components/Button/types.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import type { ComponentPropsWithoutRef, ReactElement } from 'react';
import type { ComponentPropsWithRef, ReactElement } from 'react';

export interface ButtonProps extends ComponentPropsWithoutRef<'button'> {
export interface ButtonProps extends ComponentPropsWithRef<'button'> {
$variant?: ButtonVariant;
$size?: ButtonSize;
$icon?: ReactElement;
Expand Down
20 changes: 20 additions & 0 deletions src/components/Input/Input.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { InputComponent, InputLabelComponent } from './styles.js';
import type { InputProps } from './types.js';
import React from 'react';

export const Input = ({
$fullWidth = false,
$labelContent = undefined,
...props
}: InputProps) => {
return (
<>
{$labelContent !== undefined && (
<InputLabelComponent $fullWidth={$fullWidth} htmlFor={props.id}>
{$labelContent}
</InputLabelComponent>
)}
<InputComponent $fullWidth={$fullWidth} {...props} />
</>
);
};
27 changes: 27 additions & 0 deletions src/components/Input/styles.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import { styled } from 'styled-components';
import { theme } from '../../theme.js';

export const InputLabelComponent = styled.label<{ $fullWidth: boolean }>`
${({ $fullWidth }) => $fullWidth && `width: 100%;`};
font-size: 10pt;
padding: 8px;
color: ${theme.colors.lightGray};

&:has(+ input:focus) {
color: ${theme.colors.primary};
text-decoration: underline;
}
`;

export const InputComponent = styled.input<{ $fullWidth: boolean }>`
${({ $fullWidth }) => ($fullWidth ? `width: 100%;` : `width: fit-content;`)}
padding: 8px;
border: 1px solid ${theme.colors.lightGray};
border-radius: 6px;

&:focus {
border: 1px solid ${theme.colors.primary};
color: ${theme.colors.primary};
outline: none;
}
`;
6 changes: 6 additions & 0 deletions src/components/Input/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import type { ComponentPropsWithRef } from 'react';

export interface InputProps extends ComponentPropsWithRef<'input'> {
$fullWidth?: boolean;
$labelContent?: string;
}
4 changes: 2 additions & 2 deletions src/components/Link/types.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import type { ComponentPropsWithoutRef, ReactElement } from 'react';
import type { ComponentPropsWithRef, ReactElement } from 'react';
import type { IconSide } from '../Button/types.js';

export interface LinkProps extends ComponentPropsWithoutRef<'a'> {
export interface LinkProps extends ComponentPropsWithRef<'a'> {
$color?: string;
$icon?: ReactElement;
$iconSide?: IconSide;
Expand Down
1 change: 1 addition & 0 deletions src/index.tsx
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
export { Button } from './components/Button/Button.js';
export { Link } from './components/Link/Link.js';
export { Input } from './components/Input/Input.js';
1 change: 1 addition & 0 deletions src/theme.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,6 @@ export const theme = createTheme({
primaryDimmed: '#5b489a',
secondary: '#8D86C9',
secondaryDimmed: '#746ea8',
lightGray: '#a0a0a0',
},
});
Loading