Skip to content

Commit 4a1659f

Browse files
committed
feat: add component input
1 parent 927dafc commit 4a1659f

File tree

10 files changed

+163
-0
lines changed

10 files changed

+163
-0
lines changed
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import { forwardRef } from 'react';
2+
3+
import { cn } from '@/lib/utils';
4+
5+
import { inputVariants } from './input-variants';
6+
import type { InputProps } from './types';
7+
8+
const Input = forwardRef<HTMLInputElement, InputProps>((props, ref) => {
9+
const { className, size, ...rest } = props;
10+
11+
const mergedCls = cn(inputVariants({ size }), className);
12+
13+
return (
14+
<input
15+
className={mergedCls}
16+
data-slot="input"
17+
ref={ref}
18+
{...rest}
19+
/>
20+
);
21+
});
22+
23+
Input.displayName = 'Input';
24+
25+
export default Input;
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
export { default as Input } from './Input';
2+
3+
export * from './types';
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
import { tv } from 'tailwind-variants';
2+
3+
export const inputVariants = tv({
4+
base: [
5+
`flex w-full rounded-md border border-solid border-input bg-background`,
6+
`file:border-0 file:bg-transparent file:font-medium`,
7+
`focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:ring-offset-background focus-visible:ring-primary`,
8+
`disabled:cursor-not-allowed disabled:opacity-50`
9+
],
10+
defaultVariants: {
11+
size: 'md'
12+
},
13+
variants: {
14+
size: {
15+
'2xl': 'h-12 px-4 text-xl file:py-2',
16+
lg: 'h-9 px-3 text-base file:py-1.25',
17+
md: 'h-8 px-2.5 text-sm file:py-1.25',
18+
sm: 'h-7 px-2 text-xs file:py-1.25',
19+
xl: 'h-10 px-3.5 text-lg file:py-1.25',
20+
xs: 'h-6 px-1.5 text-2xs file:py-1.25'
21+
}
22+
}
23+
});
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
import type { ComponentPropsWithRef } from 'react';
2+
3+
import type { BaseNodeProps } from '@/types/other';
4+
5+
export type InputProps = BaseNodeProps<Omit<ComponentPropsWithRef<'input'>, 'size'>>;

packages/ui/src/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,8 @@ export * from './components/hover-card';
4444

4545
export * from './components/icon';
4646

47+
export * from './components/input';
48+
4749
export * from './components/keyboard-key';
4850

4951
export * from './components/label';
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
'use client';
2+
3+
import { useState } from 'react';
4+
import { Card, Input } from 'soybean-react-ui';
5+
6+
const InputDefaultDemo = () => {
7+
const [modelValue, setModelValue] = useState('');
8+
return (
9+
<Card
10+
split
11+
title={`ModelValue : ${modelValue}`}
12+
>
13+
<div className="w-320px lt-sm:w-auto">
14+
<Input
15+
placeholder="Please input"
16+
value={modelValue}
17+
onChange={e => setModelValue(e.target.value)}
18+
/>
19+
</div>
20+
</Card>
21+
);
22+
};
23+
24+
export default InputDefaultDemo;
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
import { Card, Input } from 'soybean-react-ui';
2+
3+
const InputDisabled = () => {
4+
return (
5+
<Card
6+
split
7+
title="Disabled"
8+
>
9+
<div className="w-320px lt-sm:w-auto">
10+
<Input
11+
disabled
12+
placeholder="Please input"
13+
value="the input is disabled"
14+
/>
15+
</div>
16+
</Card>
17+
);
18+
};
19+
20+
export default InputDisabled;
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import { Card, Input } from 'soybean-react-ui';
2+
3+
const InputFile = () => {
4+
return (
5+
<Card
6+
split
7+
title="File"
8+
>
9+
<div className="w-320px lt-sm:w-auto">
10+
<Input type="file" />
11+
</div>
12+
</Card>
13+
);
14+
};
15+
16+
export default InputFile;
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
import type { ThemeSize } from 'soybean-react-ui';
2+
import { Card, Input } from 'soybean-react-ui';
3+
4+
const sizes: ThemeSize[] = ['xs', 'sm', 'md', 'lg', 'xl', '2xl'];
5+
6+
const InputSize = () => {
7+
return (
8+
<Card
9+
split
10+
title="Size"
11+
>
12+
<div className="w-320px flex-c-stretch gap-3 lt-sm:w-auto">
13+
{sizes.map(size => (
14+
<div key={size}>
15+
<div>{size}</div>
16+
17+
<Input
18+
placeholder={`${size} Please input`}
19+
size={size}
20+
/>
21+
</div>
22+
))}
23+
</div>
24+
</Card>
25+
);
26+
};
27+
28+
export default InputSize;
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import InputDefaultDemo from './modules/InputDefaultDemo';
2+
import InputDisabled from './modules/InputDisabled';
3+
import InputFile from './modules/InputFIle';
4+
import InputSize from './modules/InputSize';
5+
6+
const InputPage = () => {
7+
return (
8+
<div className="flex-c gap-4">
9+
<InputDefaultDemo />
10+
<InputDisabled />
11+
<InputFile />
12+
<InputSize />
13+
</div>
14+
);
15+
};
16+
17+
export default InputPage;

0 commit comments

Comments
 (0)