주석화 진행상황 정리하고 핵심 모듈에 한글 주석 추가

This commit is contained in:
JiWoong Sul
2025-09-29 19:39:35 +09:00
parent 9467b8c87f
commit 47c87dc118
82 changed files with 596 additions and 5 deletions

View File

@@ -5,22 +5,27 @@ import 'package:shadcn_ui/shadcn_ui.dart';
class SuperportToast {
SuperportToast._();
/// 성공 처리 완료를 사용자에게 안내한다.
static void success(BuildContext context, String message) {
_show(context, message, _ToastVariant.success);
}
/// 정보성 피드백을 노출한다.
static void info(BuildContext context, String message) {
_show(context, message, _ToastVariant.info);
}
/// 주의가 필요한 상황을 경고한다.
static void warning(BuildContext context, String message) {
_show(context, message, _ToastVariant.warning);
}
/// 오류 발생 시 스낵바를 표시한다.
static void error(BuildContext context, String message) {
_show(context, message, _ToastVariant.error);
}
/// 공통 스낵바 렌더링 로직.
static void _show(
BuildContext context,
String message,
@@ -106,9 +111,13 @@ class SuperportSkeletonList extends StatelessWidget {
this.padding = const EdgeInsets.all(16),
});
/// 렌더링할 스켈레톤 행 개수.
final int itemCount;
/// 각 항목 높이.
final double height;
/// 행 사이 간격.
final double gap;
/// 전체 패딩.
final EdgeInsetsGeometry padding;
@override

View File

@@ -157,8 +157,13 @@ class FilterBarActionConfig {
final Key? applyKey;
final Key? resetKey;
/// 즉시 적용 가능한지 여부.
bool get canApply => applyEnabled ?? hasPendingChanges;
/// Reset 버튼을 노출할지 여부.
bool get shouldShowReset =>
showReset ?? (hasActiveFilters || hasPendingChanges);
/// Reset 버튼이 활성화 가능한지 여부.
bool get canReset => resetEnabled ?? shouldShowReset;
}

View File

@@ -17,12 +17,19 @@ class SuperportFormField extends StatelessWidget {
this.spacing = _kFieldSpacing,
});
/// 폼 필드 라벨 텍스트.
final String label;
/// 입력 영역으로 렌더링할 위젯.
final Widget child;
/// 필수 여부. true면 라벨 옆에 `*` 표시를 추가한다.
final bool required;
/// 보조 설명 문구. 에러가 없을 때만 출력된다.
final String? caption;
/// 에러 메시지. 존재하면 캡션 대신 우선적으로 노출된다.
final String? errorText;
/// 라벨 우측에 배치할 추가 위젯(예: 도움말 버튼).
final Widget? trailing;
/// 라벨과 본문 사이 간격.
final double spacing;
@override
@@ -81,14 +88,23 @@ class SuperportTextInput extends StatelessWidget {
});
final TextEditingController? controller;
/// 입력 없을 때 보여줄 플레이스홀더 위젯.
final Widget? placeholder;
/// 입력 변경 콜백.
final ValueChanged<String>? onChanged;
/// 제출(Enter) 시 호출되는 콜백.
final ValueChanged<String>? onSubmitted;
/// 키보드 타입. 숫자/이메일 등으로 지정 가능.
final TextInputType? keyboardType;
/// 입력 활성 여부.
final bool enabled;
/// 읽기 전용 여부. true면 수정 불가.
final bool readOnly;
/// 최대 줄 수. 1보다 크면 멀티라인 입력을 지원한다.
final int maxLines;
/// 앞에 붙일 위젯 (아이콘 등).
final Widget? leading;
/// 뒤에 붙일 위젯 (버튼 등).
final Widget? trailing;
@override
@@ -118,9 +134,13 @@ class SuperportSwitchField extends StatelessWidget {
this.caption,
});
/// 스위치 현재 상태.
final bool value;
/// 상태 변경 시 호출되는 콜백.
final ValueChanged<bool> onChanged;
/// 스위치 상단에 표시할 제목.
final String? label;
/// 보조 설명 문구.
final String? caption;
@override

View File

@@ -3,6 +3,7 @@ import 'dart:async';
import 'package:flutter/services.dart';
import 'package:flutter/widgets.dart';
/// 다이얼로그에서 ESC/Enter 키를 처리하고 포커스를 트랩하는 래퍼 위젯.
class DialogKeyboardShortcuts extends StatefulWidget {
const DialogKeyboardShortcuts({
super.key,

View File

@@ -1,10 +1,14 @@
import 'package:flutter/widgets.dart';
/// 데스크톱 레이아웃으로 간주할 최소 너비(px).
const double desktopBreakpoint = 1200;
/// 태블릿 레이아웃을 구분하는 최소 너비(px).
const double tabletBreakpoint = 960;
/// 뷰포트 크기별 분기값.
enum DeviceBreakpoint { mobile, tablet, desktop }
/// 현재 화면 너비에 맞는 [DeviceBreakpoint]를 계산한다.
DeviceBreakpoint breakpointForWidth(double width) {
if (width >= desktopBreakpoint) {
return DeviceBreakpoint.desktop;
@@ -15,34 +19,52 @@ DeviceBreakpoint breakpointForWidth(double width) {
return DeviceBreakpoint.mobile;
}
/// 주어진 너비가 데스크톱 분기에 해당하는지 여부.
bool isDesktop(double width) => width >= desktopBreakpoint;
/// 주어진 너비가 태블릿 분기에 해당하는지 여부.
bool isTablet(double width) =>
width >= tabletBreakpoint && width < desktopBreakpoint;
/// 주어진 너비가 모바일 분기에 해당하는지 여부.
bool isMobile(double width) => width < tabletBreakpoint;
/// 컨텍스트 기반으로 데스크톱 범위인지 확인한다.
bool isDesktopContext(BuildContext context) =>
isDesktop(MediaQuery.of(context).size.width);
/// 컨텍스트 기반으로 태블릿 범위인지 확인한다.
bool isTabletContext(BuildContext context) =>
isTablet(MediaQuery.of(context).size.width);
/// 컨텍스트 기반으로 모바일 범위인지 확인한다.
bool isMobileContext(BuildContext context) =>
isMobile(MediaQuery.of(context).size.width);
/// 반응형 분기 정보를 담는 값 객체.
class ResponsiveBreakpoints {
ResponsiveBreakpoints._(this.width) : breakpoint = breakpointForWidth(width);
/// 현재 뷰 가로 너비.
final double width;
/// 너비에서 계산된 분기값.
final DeviceBreakpoint breakpoint;
/// 모바일 범위인지 여부.
bool get isMobile => breakpoint == DeviceBreakpoint.mobile;
/// 태블릿 범위인지 여부.
bool get isTablet => breakpoint == DeviceBreakpoint.tablet;
/// 데스크톱 범위인지 여부.
bool get isDesktop => breakpoint == DeviceBreakpoint.desktop;
/// 현재 컨텍스트에서 [ResponsiveBreakpoints]를 생성한다.
static ResponsiveBreakpoints of(BuildContext context) {
final size = MediaQuery.of(context).size;
return ResponsiveBreakpoints._(size.width);
}
}
/// 기기 타입에 따라 위젯 빌더를 분기 실행하는 레이아웃 헬퍼.
class ResponsiveLayoutBuilder extends StatelessWidget {
const ResponsiveLayoutBuilder({
super.key,
@@ -51,8 +73,11 @@ class ResponsiveLayoutBuilder extends StatelessWidget {
required this.desktop,
});
/// 모바일 뷰에서 사용할 빌더.
final WidgetBuilder mobile;
/// 태블릿 뷰에서 사용할 빌더. 제공되지 않으면 데스크톱 빌더를 재사용한다.
final WidgetBuilder? tablet;
/// 데스크톱 뷰에서 사용할 빌더.
final WidgetBuilder desktop;
@override
@@ -74,6 +99,7 @@ class ResponsiveLayoutBuilder extends StatelessWidget {
}
}
/// 특정 분기에서만 child를 표시하는 헬퍼 위젯.
class ResponsiveVisibility extends StatelessWidget {
const ResponsiveVisibility({
super.key,
@@ -86,8 +112,11 @@ class ResponsiveVisibility extends StatelessWidget {
},
});
/// 조건을 만족할 때 보여줄 실제 위젯.
final Widget child;
/// 조건을 만족하지 않을 때 대체로 렌더링할 위젯.
final Widget replacement;
/// 어떤 분기에서 child를 노출할지 정의한 집합.
final Set<DeviceBreakpoint> visibleOn;
@override

View File

@@ -62,6 +62,7 @@ class SuperportDialog extends StatelessWidget {
final FutureOr<void> Function()? onSubmit;
final bool enableFocusTrap;
/// 공통 다이얼로그를 노출하는 헬퍼. `showDialog`와 동일하게 동작한다.
static Future<T?> show<T>({
required BuildContext context,
required SuperportDialog dialog,
@@ -285,7 +286,7 @@ class _SuperportDialogHeader extends StatelessWidget {
}
}
/// Convenience wrapper around [SuperportDialog.show] to reduce boilerplate in pages.
/// 페이지에서 반복되는 호출 패턴을 줄이기 위한 편의 함수.
Future<T?> showSuperportDialog<T>({
required BuildContext context,
required String title,

View File

@@ -11,7 +11,10 @@ class SuperportTableSortState {
required this.ascending,
});
/// 정렬 대상이 되는 컬럼 인덱스.
final int columnIndex;
/// 오름차순 여부. `false`면 내림차순이다.
final bool ascending;
}
@@ -25,10 +28,19 @@ class SuperportTablePagination {
this.pageSizeOptions = const <int>[10, 20, 50],
});
/// 현재 페이지 번호(1-base).
final int currentPage;
/// 전체 페이지 수.
final int totalPages;
/// 전체 데이터 건수.
final int totalItems;
/// 현재 페이지네이션에서 선택된 페이지 크기.
final int pageSize;
/// 사용자에게 노출할 페이지 크기 옵션 목록.
final List<int> pageSizeOptions;
}
@@ -55,6 +67,7 @@ class SuperportTable extends StatelessWidget {
_headerCells = null,
_rowCells = null;
/// 헤더와 행을 [ShadTableCell] 단위로 직접 전달할 때 사용하는 생성자.
const SuperportTable.fromCells({
super.key,
required List<ShadTableCell> header,