주석화 진행상황 정리하고 핵심 모듈에 한글 주석 추가
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user