diff --git a/src/components/global/CustomButton/CustomButton.tsx b/src/components/global/CustomButton/CustomButton.tsx
index 1efbc578..da3f531f 100644
--- a/src/components/global/CustomButton/CustomButton.tsx
+++ b/src/components/global/CustomButton/CustomButton.tsx
@@ -2,7 +2,6 @@
import React from 'react';
import styled, { css, keyframes } from 'styled-components';
import { colors } from '../../../style/color';
-
interface CustomButtonProps {
/**
* 버튼 내부 텍스트
@@ -55,6 +54,7 @@ const Button = styled.button<{
transition: all 0.2s ease-in-out;
cursor: pointer;
width: ${props => props.$fullWidth ? '100%' : 'auto'};
+ color: ${colors.white};
// 크기 설정
${props => {
@@ -62,19 +62,19 @@ const Button = styled.button<{
case 'small':
return css`
padding: 8px 16px;
- font-size: 14px;
+ font-size: 10px;
height: 32px;
`;
case 'large':
return css`
padding: 16px 32px;
- font-size: 18px;
+ font-size: 12px;
height: 48px;
`;
default: // medium
return css`
padding: 12px 24px;
- font-size: 16px;
+ font-size: 12px;
height: 40px;
`;
}
@@ -114,14 +114,13 @@ const Button = styled.button<{
default: // primary
return css`
background-color: ${colors.blue200};
- color: white;
border: none;
- box-shadow: 0 2px 4px rgba(79, 70, 229, 0.1);
+ box-shadow: 0 2px 4px ${colors.blue100};
&:hover:not(:disabled) {
- background-color:blue;
+ background-color: ${colors.blue200};
transform: translateY(-1px);
- box-shadow: 0 4px 6px rgba(79, 70, 229, 0.2);
+ box-shadow: 0 4px 6px ${colors.blue100};
}
&:active:not(:disabled) {
@@ -138,7 +137,7 @@ const Button = styled.button<{
&:focus {
outline: none;
- box-shadow: 0 0 0 3px rgba(79, 70, 229, 0.3);
+ box-shadow: 0 0 0 3px ${colors.blue100};
}
`;
diff --git a/src/components/global/CustomInput/CustomInput.stories.tsx b/src/components/global/CustomInput/CustomInput.stories.tsx
index 02a84ee7..0f104af3 100644
--- a/src/components/global/CustomInput/CustomInput.stories.tsx
+++ b/src/components/global/CustomInput/CustomInput.stories.tsx
@@ -1,7 +1,7 @@
// CustomInput.stories.tsx
import type { Meta, StoryObj } from '@storybook/react';
import { CustomInput } from './CustomInput';
-
+import { CustomButton } from '../CustomButton/CustomButton';
const meta = {
title: 'Components/CustomInput',
component: CustomInput,
@@ -113,4 +113,18 @@ export const Playground: Story = {
error: '',
hint: '',
},
+};
+
+
+export const WithSuffix: Story = {
+ args: {
+ label: '제목',
+ placeholder: '값을 입력해주세요',
+ variant: 'underlined',
+ suffix: (
+
+ 확인
+
+ ),
+ },
};
\ No newline at end of file
diff --git a/src/components/global/CustomInput/CustomInput.tsx b/src/components/global/CustomInput/CustomInput.tsx
index da9f18c2..90a93832 100644
--- a/src/components/global/CustomInput/CustomInput.tsx
+++ b/src/components/global/CustomInput/CustomInput.tsx
@@ -1,7 +1,9 @@
-// CustomInput.tsx
-import { InputHTMLAttributes } from 'react';
+
+import React, { InputHTMLAttributes, ReactNode } from 'react';
import styled, { css, keyframes } from 'styled-components';
+import { typography } from '../../../style/typography';
import { colors } from '../../../style/color';
+import theme from '../../../style/theme';
interface CustomInputProps extends Omit, 'size'> {
/**
@@ -20,10 +22,18 @@ interface CustomInputProps extends Omit, '
* 너비를 100%로 설정
*/
fullWidth?: boolean;
- /**
+ /**
* 입력 필드 스타일 변형
*/
variant?: 'outlined' | 'underlined';
+ /**
+ * 입력 필드 오른쪽에 추가할 요소
+ */
+ suffix?: ReactNode;
+ /**
+ * 버튼을 포함하는 경우, marginBottom 설정
+ */
+ hasButton?: boolean;
}
const fadeIn = keyframes`
@@ -37,67 +47,105 @@ const fadeIn = keyframes`
}
`;
-const Container = styled.div<{ $fullWidth: boolean }>`
+const Container = styled.div<{ $fullWidth: boolean; $hasButton: boolean }>`
display: flex;
flex-direction: column;
- width: ${props => props.$fullWidth ? '100%' : 'auto'};
+ width: ${({ $fullWidth }) => ($fullWidth ? '100%' : theme.size.maxWidth || 'auto')};
+ ${({ $hasButton }) => $hasButton && css`
+ margin-bottom: 10px; /* 버튼이 있을 때 margin-bottom을 10px 추가 */
+ `}
`;
const Label = styled.label`
font-weight: 500;
- color: ${colors.gray300};
- margin-bottom: 4px;
+ color: #374151;
+ margin-bottom: 5px;
+ font-size: ${typography.body2};
`;
-const StyledInput = styled.input<{
- $error: boolean;
- $fullWidth: boolean;
- $variant: string;
-}>`
- display: block;
- width: ${props => props.$fullWidth ? '100%' : 'auto'};
- transition: all 0.2s ease-in-out;
+const InputWrapper = styled.div<{ $variant: string; $error: boolean; $disabled: boolean }>`
+ display: flex;
+ align-items: center;
+ width: 100%;
+ background-color: ${(props) => (props.$disabled ? colors.gray100 : 'transparent')};
+ ${({ $variant, $error, $disabled }) =>
+ $variant === 'outlined'
+ ? css`
+ border-radius: 5px;
+ border: ${$disabled ? 'none' : `1px solid ${$error ? colors.red200 : colors.gray300}`};
+ padding: 0px 10px;
+ height: 40px;
+
+ &:focus-within {
+ border-color: ${$error ? colors.red200 : colors.blue200};
+ box-shadow: 0 0 0 3px ${$error ? colors.red100 : colors.blue100};
+ }
+ `
+ : css`
+ border: none;
+ border-bottom: 1px solid ${$error ? colors.red200 : colors.gray300};
+ border-radius: 0;
+ padding: 5px 10px;
+ height: 32px;
+
+ &:focus-within {
+ border-bottom-color: ${$error ? colors.red200 : colors.blue200};
+ }
+ `}
+`;
+
+const StyledInput = styled.input<{ $error: boolean }>`
+ flex: 1;
+ border: none;
outline: none;
- background-color: ${colors.white};
+ background-color: transparent;
font-size: 14px;
&::placeholder {
- color: ${colors.gray200};
+ color: #9ca3af;
+ font-size: ${typography.body6};
}
&:disabled {
- background-color: ${colors.gray100};
+ color: ${colors.gray300};
cursor: not-allowed;
+ font-size: 12px;
}
+`;
- ${({ $variant, $error }) => $variant === 'outlined' ? css`
- border-radius: 20px;
- border: 2px solid ${$error ? colors.red300 : colors.gray200};
- padding: 8px 16px;
- height: 32px;
-
- &:focus {
- border-color: ${$error ? colors.red300 : colors.blue200};
- box-shadow: 0 0 0 3px ${$error ? 'rgba(239, 68, 68, 0.1)' : 'rgba(79, 70, 229, 0.1)'};
- }
- ` : css`
- border: none;
- border-bottom: 2px solid ${$error ? colors.red300 : colors.gray200};
- border-radius: 0;
- padding: 4px 0;
- height: 24px;
-
- &:focus {
- border-bottom-color: ${$error ? colors.red300 : colors.blue200};
- }
- `}
+const SuffixContainer = styled.div<{ $variant: string; $error: boolean }>`
+ margin-left: 8px;
+ margin-bottom: 10px;
+ ${({ $variant, $error }) => $variant === 'outlined'
+ ? css`
+ border-radius: 20px;
+ border: 2px solid ${$error ? colors.red300 : colors.gray200};
+ padding: 8px 16px;
+ height: 32px;
+
+ &:focus {
+ border-color: ${$error ? colors.red300 : colors.blue200};
+ box-shadow: 0 0 0 3px ${$error ? 'rgba(239, 68, 68, 0.1)' : 'rgba(79, 70, 229, 0.1)'};
+ }
+ `
+ : css`
+ border: none;
+ border-bottom: 2px solid ${$error ? colors.red300 : colors.gray200};
+ border-radius: 0;
+ padding: 4px 0;
+ height: 24px;
+
+ &:focus {
+ border-bottom-color: ${$error ? colors.red300 : colors.blue200};
+ }
+ `}
`;
const Message = styled.p<{ $error?: boolean }>`
- font-size: 14px;
+ font-size: ${typography.body6};
margin-top: 4px;
- color: ${props => props.$error ? colors.red300 : colors.gray200};
- animation: ${fadeIn} 0.2s ease-in-out;
+ color: ${(props) => (props.$error ? colors.red300 : '#6b7280')};
+ animation: ${fadeIn} 0.3s ease-in-out; /* 애니메이션 시간 증가 */
`;
export function CustomInput({
@@ -107,23 +155,19 @@ export function CustomInput({
fullWidth = false,
disabled = false,
variant = 'outlined',
+ suffix,
+ hasButton = false,
...props
}: CustomInputProps) {
return (
-
+
{label && }
-
- {(error || hint) && (
-
- {error || hint}
-
- )}
+
+
+ {suffix && {suffix}}
+
+ {(error || hint) && {error || hint}}
);
-}
+};
+