Conversation
|
The latest updates on your projects. Learn more about Vercel for Git ↗︎
|
Walkthrough이 변경사항에서는 Flutter 애플리케이션이 새롭게 도입되어, 커스텀 버튼의 다양한 변형(variant)과 라이트/다크 테마를 시연합니다. 주요 색상 상수가 정의되며, 📜 Recent review detailsConfiguration used: CodeRabbit UI 📒 Files selected for processing (1)
🧰 Additional context used🧠 Learnings (2)📓 Common learningslib/custom button.dart (3)Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed help? Create a ticket on our support page for assistance with any issues or questions. Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
CodeRabbit Configuration File (
|
There was a problem hiding this comment.
Actionable comments posted: 0
🧹 Nitpick comments (3)
lib/custom button.dart (3)
70-70: 타입 안전성을 위해 enum 사용을 고려해보세요.
variant매개변수가 String 타입으로 되어 있어 런타임 에러 가능성이 있습니다.다음과 같이 enum을 사용하는 것을 고려해보세요:
+enum ButtonVariant { surface, outline } + class CustomButton extends StatelessWidget { - final String variant; + final ButtonVariant variant; final bool disabled;그리고 사용하는 부분에서:
- final bool isOutline = variant == 'outline'; + final bool isOutline = variant == ButtonVariant.outline;
89-89: onPressed 콜백을 더 의미있게 만들어보세요.현재 빈 콜백
() {}는 실제 사용에서 유용하지 않습니다.다음과 같이 외부에서 콜백을 받도록 수정하는 것을 고려해보세요:
class CustomButton extends StatelessWidget { final String variant; final bool disabled; + final VoidCallback? onPressed; const CustomButton({ super.key, required this.variant, required this.disabled, + this.onPressed, });그리고 버튼에서:
- onPressed: disabled ? null : () {}, + onPressed: disabled ? null : onPressed,
119-119: 버튼 텍스트를 매개변수화하는 것을 고려해보세요.하드코딩된 'Button' 텍스트는 재사용성을 제한합니다.
다음과 같이 텍스트를 매개변수로 받도록 수정하는 것을 고려해보세요:
class CustomButton extends StatelessWidget { final String variant; final bool disabled; + final String text; const CustomButton({ super.key, required this.variant, required this.disabled, + this.text = 'Button', });그리고 버튼에서:
- child: const Text('Button', style: TextStyle(fontSize: 12)), + child: Text(text, style: const TextStyle(fontSize: 12)),
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (1)
pubspec.lockis excluded by!**/*.lock
📒 Files selected for processing (1)
lib/custom button.dart(1 hunks)
🧰 Additional context used
🧠 Learnings (1)
lib/custom button.dart (1)
Learnt from: hoony6134
PR: route-five/fliggle-fe#45
File: lib/app/view/auth/register/step_4.dart:12-12
Timestamp: 2025-07-16T08:47:49.421Z
Learning: The user hoony6134 prefers to handle hardcoded color values like `Colors.white` in `lib/app/view/auth/register/step_4.dart` as part of a separate issue focusing on the color theme system, rather than making immediate changes in individual PRs.
🔇 Additional comments (4)
lib/custom button.dart (4)
1-5: 표준적인 Flutter 앱 구조입니다.임포트와 메인 함수가 올바르게 구현되어 있습니다.
7-13: 색상 상수들이 잘 정의되어 있습니다.라이트/다크 테마를 위한 색상 상수들이 일관된 네이밍 패턴으로 정의되어 있습니다. 향후 테마 시스템으로 통합될 수 있을 것 같습니다.
15-42: 잘 구성된 앱 설정입니다.Material 3 디자인과 시스템 테마 모드를 사용하며, 라이트/다크 테마 모두 올바르게 구성되어 있습니다.
44-67: 데모 페이지가 명확하게 구성되어 있습니다.다양한 버튼 변형과 상태를 보여주는 구조가 잘 정리되어 있습니다.
hoony6134
left a comment
There was a problem hiding this comment.
요청한 수정 사항 반영해 주세요. 또한, 파일 이름을 명명법에 맞게 수정해 주시고, 위치 또한 이동해주세요. app/core/components/custom_button.dart로 수정해야 합니다.
| const Color lightPrimaryColor = Color(0xFF6C98FF); | ||
| const Color lightSecondaryColor = Color(0xFF87A9F7); | ||
|
|
||
| const Color darkPrimaryColor = Color(0xFF497BEE); | ||
| const Color darkSecondaryColor = Color(0xFF6C98FF); | ||
|
|
||
| const Color disabledColor = Color(0xFF808080); |
There was a problem hiding this comment.
이미 app/view/core/design에 색상들이 정의된 파일을 생성해 두었습니다. 그 파일을 이용해 주시고, app/view/register/step_4.dart 파일과 app/view/core/components/custom_text_field.dart에서 사용한 방식을 참고해 주세요.
| void main() { | ||
| runApp(const MyApp()); | ||
| } |
There was a problem hiding this comment.
preview화면을 요청한 것이 아닌, 컴포넌트만 정의된 파일을 의미했습니다. 작동 확인할 수 있는 화면은 제거해 주시고 본 파일에는 컴포넌트 관련 코드만 남겨주세요.
| theme: ThemeData( | ||
| useMaterial3: true, | ||
| brightness: Brightness.light, | ||
| colorScheme: ColorScheme.light( | ||
| primary: lightPrimaryColor, | ||
| secondary: lightSecondaryColor, | ||
| ), | ||
| ), | ||
| darkTheme: ThemeData( | ||
| useMaterial3: true, | ||
| brightness: Brightness.dark, | ||
| colorScheme: ColorScheme.dark( | ||
| primary: darkPrimaryColor, | ||
| secondary: darkSecondaryColor, | ||
| ), | ||
| ), |
There was a problem hiding this comment.
theme, darkTheme 모두 app/view/core/design/fliggle_theme_data.dart에 관련 스타일이 정의되어 있습니다. 만약 추가적인 스타일이 필요하다면 app/view/core/design 폴더 내에 있는 요소를 변경하거나, 추가해 주세요.
There was a problem hiding this comment.
또한, 위에서 언급드린 것처럼 app은 건들지 말아주세요. app.dart에 수정 사항이 필요하다면 app/app.dart의 내용을 수정해 주세요.
| final colorScheme = Theme.of(context).colorScheme; | ||
| final Color primary = colorScheme.primary; |
There was a problem hiding this comment.
이것 또한 별도로 구현해 놓은 FliggleThemeData 및 FliggleColors를 이용해 주세요.
| class ButtonDemoPage extends StatelessWidget { | ||
| const ButtonDemoPage({super.key}); | ||
|
|
||
| @override | ||
| Widget build(BuildContext context) { | ||
| return Scaffold( | ||
| appBar: AppBar(title: const Text("Button Variants")), | ||
| body: Padding( | ||
| padding: const EdgeInsets.all(16.0), | ||
| child: Column( | ||
| children: const [ | ||
| CustomButton(variant: 'surface', disabled: false), | ||
| SizedBox(height: 10), | ||
| CustomButton(variant: 'surface', disabled: true), | ||
| SizedBox(height: 10), | ||
| CustomButton(variant: 'outline', disabled: false), | ||
| SizedBox(height: 10), | ||
| CustomButton(variant: 'outline', disabled: true), | ||
| ], | ||
| ), | ||
| ), | ||
| ); | ||
| } | ||
| } |
| return SizedBox( | ||
| width: 120, | ||
| height: 34, | ||
| child: ElevatedButton( | ||
| onPressed: disabled ? null : () {}, | ||
| style: ButtonStyle( | ||
| backgroundColor: WidgetStateProperty.resolveWith<Color>((states) { | ||
| if (states.contains(WidgetState.disabled)) { | ||
| return isOutline ? Colors.white : disabledColor; | ||
| } | ||
| return isOutline ? Colors.white : primary; | ||
| }), | ||
| foregroundColor: WidgetStateProperty.resolveWith<Color>((states) { | ||
| if (states.contains(WidgetState.disabled)) { | ||
| return isOutline ? disabledColor : Colors.white; | ||
| } | ||
| return isOutline ? primary : Colors.white; | ||
| }), | ||
| side: WidgetStateProperty.resolveWith<BorderSide>((states) { | ||
| if (!isOutline) return BorderSide.none; | ||
| return BorderSide( | ||
| color: states.contains(WidgetState.disabled) | ||
| ? disabledColor | ||
| : primary, | ||
| ); | ||
| }), | ||
| padding: WidgetStateProperty.all( | ||
| const EdgeInsets.symmetric(vertical: 8, horizontal: 12), | ||
| ), | ||
| elevation: WidgetStateProperty.all(0), | ||
| shape: WidgetStateProperty.all( | ||
| RoundedRectangleBorder(borderRadius: BorderRadius.circular(8)), | ||
| ), | ||
| ), | ||
| child: const Text('Button', style: TextStyle(fontSize: 12)), | ||
| ), | ||
| ); |
| width: 120, | ||
| height: 34, | ||
| child: ElevatedButton( | ||
| onPressed: disabled ? null : () {}, |
There was a problem hiding this comment.
onTap을 property로 넘길 수 있게 해주세요
| ), | ||
| elevation: WidgetStateProperty.all(0), | ||
| shape: WidgetStateProperty.all( | ||
| RoundedRectangleBorder(borderRadius: BorderRadius.circular(8)), |
There was a problem hiding this comment.
| RoundedRectangleBorder(borderRadius: BorderRadius.circular(8)), | |
| RoundedRectangleBorder(borderRadius: BorderRadius.circular(12)), |
피그마와 동일하게 맞춰주세요
| onPressed: disabled ? null : () {}, | ||
| style: ButtonStyle( | ||
| backgroundColor: WidgetStateProperty.resolveWith<Color>((states) { | ||
| if (states.contains(WidgetState.disabled)) { | ||
| return isOutline ? Colors.white : disabledColor; | ||
| } | ||
| return isOutline ? Colors.white : primary; | ||
| }), |
There was a problem hiding this comment.
위젯의 disabled 값과 WidgetState.disabled가 혼용되는 것 같아요 코드 전체에서
| ); | ||
| }), | ||
| padding: WidgetStateProperty.all( | ||
| const EdgeInsets.symmetric(vertical: 8, horizontal: 12), |
| RoundedRectangleBorder(borderRadius: BorderRadius.circular(8)), | ||
| ), | ||
| ), | ||
| child: const Text('Button', style: TextStyle(fontSize: 12)), |
There was a problem hiding this comment.
text를 property로 넘길 수 있게 해주세요
| width: 120, | ||
| height: 34, |
There was a problem hiding this comment.
text에 따라 위젯의 크기가 동적으로 변할 수 있습니다. SizedBox를 제거해주세요
|
@coderabbitai full review |
✅ Actions performedFull review triggered. |
Summary by CodeRabbit