From 8b2067fe18492988d1d2341cb176ca5bf8fcf526 Mon Sep 17 00:00:00 2001 From: Simon_Wzy <1691663479@qq.com> Date: Tue, 24 Sep 2024 18:54:57 +0800 Subject: [PATCH 01/46] =?UTF-8?q?=E6=96=87=E4=BB=B6=E6=A0=BC=E5=BC=8F?= =?UTF-8?q?=E5=BC=80=E5=A7=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../lib/base/intl_resource_delegate.dart | 2 +- tdesign-component/example/lib/config.dart | 3 + .../lib/gen_l10n/app_localizations.dart | 391 ++++++++++++++++++ .../lib/gen_l10n/app_localizations_en.dart | 138 +++++++ .../lib/gen_l10n/app_localizations_zh.dart | 138 +++++++ tdesign-component/example/lib/home.dart | 4 +- tdesign-component/example/lib/main.dart | 2 +- .../example/lib/page/td_form_page.dart | 188 +++++++++ tdesign-component/example/pubspec.lock | 202 ++++++++- .../lib/src/components/form/td_form.dart | 0 .../lib/src/components/form/td_form_item.dart | 21 + tdesign-component/pubspec.lock | 288 +++++++++++-- tdesign-component/pubspec.yaml | 1 + tdesign-site/package-lock.json | 7 +- tdesign-site/package.json | 5 +- 15 files changed, 1358 insertions(+), 32 deletions(-) create mode 100644 tdesign-component/example/lib/gen_l10n/app_localizations.dart create mode 100644 tdesign-component/example/lib/gen_l10n/app_localizations_en.dart create mode 100644 tdesign-component/example/lib/gen_l10n/app_localizations_zh.dart create mode 100644 tdesign-component/example/lib/page/td_form_page.dart create mode 100644 tdesign-component/lib/src/components/form/td_form.dart create mode 100644 tdesign-component/lib/src/components/form/td_form_item.dart diff --git a/tdesign-component/example/lib/base/intl_resource_delegate.dart b/tdesign-component/example/lib/base/intl_resource_delegate.dart index 0b5eb9c98..5ea23f097 100644 --- a/tdesign-component/example/lib/base/intl_resource_delegate.dart +++ b/tdesign-component/example/lib/base/intl_resource_delegate.dart @@ -1,5 +1,5 @@ import 'package:flutter/cupertino.dart'; -import 'package:flutter_gen/gen_l10n/app_localizations.dart'; +import '../gen_l10n/app_localizations.dart'; import 'package:tdesign_flutter/tdesign_flutter.dart'; /// 国际化资源代理 diff --git a/tdesign-component/example/lib/config.dart b/tdesign-component/example/lib/config.dart index fa515e92c..d835d332d 100644 --- a/tdesign-component/example/lib/config.dart +++ b/tdesign-component/example/lib/config.dart @@ -29,6 +29,7 @@ import 'page/td_icon_page.dart'; import 'page/td_image_page.dart'; import 'page/td_image_viewer_page.dart'; import 'page/td_input_page.dart'; +import 'page/td_form_page.dart'; import 'page/td_link_page.dart'; import 'page/td_loading_page.dart'; import 'page/td_navbar_page.dart'; @@ -120,6 +121,8 @@ Map> exampleMap = { name: 'date-time-picker', pageName: 'data_picker', pageBuilder: _wrapInheritedTheme((context) => const TDDatePickerPage())), + ExamplePageModel( + text: 'Form 表单', name: 'form', pageBuilder: _wrapInheritedTheme((context) => const TDFormPage())), ExamplePageModel( text: 'Input 输入框', name: 'input', pageBuilder: _wrapInheritedTheme((context) => const TDInputViewPage())), ExamplePageModel( diff --git a/tdesign-component/example/lib/gen_l10n/app_localizations.dart b/tdesign-component/example/lib/gen_l10n/app_localizations.dart new file mode 100644 index 000000000..605cf7aea --- /dev/null +++ b/tdesign-component/example/lib/gen_l10n/app_localizations.dart @@ -0,0 +1,391 @@ +import 'dart:async'; + +import 'package:flutter/foundation.dart'; +import 'package:flutter/widgets.dart'; +import 'package:flutter_localizations/flutter_localizations.dart'; +import 'package:intl/intl.dart' as intl; + +import 'app_localizations_en.dart'; +import 'app_localizations_zh.dart'; + +/// Callers can lookup localized strings with an instance of AppLocalizations +/// returned by `AppLocalizations.of(context)`. +/// +/// Applications need to include `AppLocalizations.delegate()` in their app's +/// `localizationDelegates` list, and the locales they support in the app's +/// `supportedLocales` list. For example: +/// +/// ```dart +/// import 'gen_l10n/app_localizations.dart'; +/// +/// return MaterialApp( +/// localizationsDelegates: AppLocalizations.localizationsDelegates, +/// supportedLocales: AppLocalizations.supportedLocales, +/// home: MyApplicationHome(), +/// ); +/// ``` +/// +/// ## Update pubspec.yaml +/// +/// Please make sure to update your pubspec.yaml to include the following +/// packages: +/// +/// ```yaml +/// dependencies: +/// # Internationalization support. +/// flutter_localizations: +/// sdk: flutter +/// intl: any # Use the pinned version from flutter_localizations +/// +/// # Rest of dependencies +/// ``` +/// +/// ## iOS Applications +/// +/// iOS applications define key application metadata, including supported +/// locales, in an Info.plist file that is built into the application bundle. +/// To configure the locales supported by your app, you’ll need to edit this +/// file. +/// +/// First, open your project’s ios/Runner.xcworkspace Xcode workspace file. +/// Then, in the Project Navigator, open the Info.plist file under the Runner +/// project’s Runner folder. +/// +/// Next, select the Information Property List item, select Add Item from the +/// Editor menu, then select Localizations from the pop-up menu. +/// +/// Select and expand the newly-created Localizations item then, for each +/// locale your application supports, add a new item and select the locale +/// you wish to add from the pop-up menu in the Value field. This list should +/// be consistent with the languages listed in the AppLocalizations.supportedLocales +/// property. +abstract class AppLocalizations { + AppLocalizations(String locale) : localeName = intl.Intl.canonicalizedLocale(locale.toString()); + + final String localeName; + + static AppLocalizations? of(BuildContext context) { + return Localizations.of(context, AppLocalizations); + } + + static const LocalizationsDelegate delegate = _AppLocalizationsDelegate(); + + /// A list of this localizations delegate along with the default localizations + /// delegates. + /// + /// Returns a list of localizations delegates containing this delegate along with + /// GlobalMaterialLocalizations.delegate, GlobalCupertinoLocalizations.delegate, + /// and GlobalWidgetsLocalizations.delegate. + /// + /// Additional delegates can be added by appending to this list in + /// MaterialApp. This list does not have to be used at all if a custom list + /// of delegates is preferred or required. + static const List> localizationsDelegates = >[ + delegate, + GlobalMaterialLocalizations.delegate, + GlobalCupertinoLocalizations.delegate, + GlobalWidgetsLocalizations.delegate, + ]; + + /// A list of this localizations delegate's supported locales. + static const List supportedLocales = [ + Locale('en'), + Locale('zh') + ]; + + /// No description provided for @components. + /// + /// In en, this message translates to: + /// **'TD Flutter Components'** + String get components; + + /// No description provided for @about. + /// + /// In en, this message translates to: + /// **'About'** + String get about; + + /// No description provided for @defaultTheme. + /// + /// In en, this message translates to: + /// **'defaultTheme'** + String get defaultTheme; + + /// No description provided for @greenTheme. + /// + /// In en, this message translates to: + /// **'greenTheme'** + String get greenTheme; + + /// No description provided for @redTheme. + /// + /// In en, this message translates to: + /// **'redTheme'** + String get redTheme; + + /// No description provided for @cancel. + /// + /// In en, this message translates to: + /// **'cancel'** + String get cancel; + + /// No description provided for @confirm. + /// + /// In en, this message translates to: + /// **'confirm'** + String get confirm; + + /// No description provided for @switchClose. + /// + /// In en, this message translates to: + /// **'C'** + String get switchClose; + + /// No description provided for @switchOpen. + /// + /// In en, this message translates to: + /// **'O'** + String get switchOpen; + + /// No description provided for @knew. + /// + /// In en, this message translates to: + /// **'knew'** + String get knew; + + /// No description provided for @loading. + /// + /// In en, this message translates to: + /// **'loading'** + String get loading; + + /// No description provided for @loadingWithPoint. + /// + /// In en, this message translates to: + /// **'loading...'** + String get loadingWithPoint; + + /// No description provided for @other. + /// + /// In en, this message translates to: + /// **'other'** + String get other; + + /// No description provided for @refreshing. + /// + /// In en, this message translates to: + /// **'refreshing'** + String get refreshing; + + /// No description provided for @releaseRefresh. + /// + /// In en, this message translates to: + /// **'releaseRefresh'** + String get releaseRefresh; + + /// No description provided for @reset. + /// + /// In en, this message translates to: + /// **'reset'** + String get reset; + + /// No description provided for @days. + /// + /// In en, this message translates to: + /// **'days'** + String get days; + + /// No description provided for @hours. + /// + /// In en, this message translates to: + /// **'hours'** + String get hours; + + /// No description provided for @minutes. + /// + /// In en, this message translates to: + /// **'minutes'** + String get minutes; + + /// No description provided for @seconds. + /// + /// In en, this message translates to: + /// **'seconds'** + String get seconds; + + /// No description provided for @milliseconds. + /// + /// In en, this message translates to: + /// **'milliseconds'** + String get milliseconds; + + /// No description provided for @sunday. + /// + /// In en, this message translates to: + /// **'SUN'** + String get sunday; + + /// No description provided for @monday. + /// + /// In en, this message translates to: + /// **'MON'** + String get monday; + + /// No description provided for @tuesday. + /// + /// In en, this message translates to: + /// **'TUE'** + String get tuesday; + + /// No description provided for @wednesday. + /// + /// In en, this message translates to: + /// **'WED'** + String get wednesday; + + /// No description provided for @thursday. + /// + /// In en, this message translates to: + /// **'THU'** + String get thursday; + + /// No description provided for @friday. + /// + /// In en, this message translates to: + /// **'FRI'** + String get friday; + + /// No description provided for @saturday. + /// + /// In en, this message translates to: + /// **'SAT'** + String get saturday; + + /// No description provided for @year. + /// + /// In en, this message translates to: + /// **''** + String get year; + + /// No description provided for @january. + /// + /// In en, this message translates to: + /// **'January'** + String get january; + + /// No description provided for @february. + /// + /// In en, this message translates to: + /// **'February'** + String get february; + + /// No description provided for @march. + /// + /// In en, this message translates to: + /// **'March'** + String get march; + + /// No description provided for @april. + /// + /// In en, this message translates to: + /// **'April'** + String get april; + + /// No description provided for @may. + /// + /// In en, this message translates to: + /// **'May'** + String get may; + + /// No description provided for @june. + /// + /// In en, this message translates to: + /// **'June'** + String get june; + + /// No description provided for @july. + /// + /// In en, this message translates to: + /// **'July'** + String get july; + + /// No description provided for @august. + /// + /// In en, this message translates to: + /// **'August'** + String get august; + + /// No description provided for @september. + /// + /// In en, this message translates to: + /// **'September'** + String get september; + + /// No description provided for @october. + /// + /// In en, this message translates to: + /// **'October'** + String get october; + + /// No description provided for @november. + /// + /// In en, this message translates to: + /// **'November'** + String get november; + + /// No description provided for @december. + /// + /// In en, this message translates to: + /// **'December'** + String get december; + + /// No description provided for @time. + /// + /// In en, this message translates to: + /// **'Time'** + String get time; + + /// No description provided for @start. + /// + /// In en, this message translates to: + /// **'Start'** + String get start; + + /// No description provided for @end. + /// + /// In en, this message translates to: + /// **'End'** + String get end; +} + +class _AppLocalizationsDelegate extends LocalizationsDelegate { + const _AppLocalizationsDelegate(); + + @override + Future load(Locale locale) { + return SynchronousFuture(lookupAppLocalizations(locale)); + } + + @override + bool isSupported(Locale locale) => ['en', 'zh'].contains(locale.languageCode); + + @override + bool shouldReload(_AppLocalizationsDelegate old) => false; +} + +AppLocalizations lookupAppLocalizations(Locale locale) { + + + // Lookup logic when only language code is specified. + switch (locale.languageCode) { + case 'en': return AppLocalizationsEn(); + case 'zh': return AppLocalizationsZh(); + } + + throw FlutterError( + 'AppLocalizations.delegate failed to load unsupported locale "$locale". This is likely ' + 'an issue with the localizations generation tool. Please file an issue ' + 'on GitHub with a reproducible sample app and the gen-l10n configuration ' + 'that was used.' + ); +} diff --git a/tdesign-component/example/lib/gen_l10n/app_localizations_en.dart b/tdesign-component/example/lib/gen_l10n/app_localizations_en.dart new file mode 100644 index 000000000..3ab94e7c4 --- /dev/null +++ b/tdesign-component/example/lib/gen_l10n/app_localizations_en.dart @@ -0,0 +1,138 @@ +import 'app_localizations.dart'; + +/// The translations for English (`en`). +class AppLocalizationsEn extends AppLocalizations { + AppLocalizationsEn([String locale = 'en']) : super(locale); + + @override + String get components => 'TD Flutter Components'; + + @override + String get about => 'About'; + + @override + String get defaultTheme => 'defaultTheme'; + + @override + String get greenTheme => 'greenTheme'; + + @override + String get redTheme => 'redTheme'; + + @override + String get cancel => 'cancel'; + + @override + String get confirm => 'confirm'; + + @override + String get switchClose => 'C'; + + @override + String get switchOpen => 'O'; + + @override + String get knew => 'knew'; + + @override + String get loading => 'loading'; + + @override + String get loadingWithPoint => 'loading...'; + + @override + String get other => 'other'; + + @override + String get refreshing => 'refreshing'; + + @override + String get releaseRefresh => 'releaseRefresh'; + + @override + String get reset => 'reset'; + + @override + String get days => 'days'; + + @override + String get hours => 'hours'; + + @override + String get minutes => 'minutes'; + + @override + String get seconds => 'seconds'; + + @override + String get milliseconds => 'milliseconds'; + + @override + String get sunday => 'SUN'; + + @override + String get monday => 'MON'; + + @override + String get tuesday => 'TUE'; + + @override + String get wednesday => 'WED'; + + @override + String get thursday => 'THU'; + + @override + String get friday => 'FRI'; + + @override + String get saturday => 'SAT'; + + @override + String get year => ''; + + @override + String get january => 'January'; + + @override + String get february => 'February'; + + @override + String get march => 'March'; + + @override + String get april => 'April'; + + @override + String get may => 'May'; + + @override + String get june => 'June'; + + @override + String get july => 'July'; + + @override + String get august => 'August'; + + @override + String get september => 'September'; + + @override + String get october => 'October'; + + @override + String get november => 'November'; + + @override + String get december => 'December'; + + @override + String get time => 'Time'; + + @override + String get start => 'Start'; + + @override + String get end => 'End'; +} diff --git a/tdesign-component/example/lib/gen_l10n/app_localizations_zh.dart b/tdesign-component/example/lib/gen_l10n/app_localizations_zh.dart new file mode 100644 index 000000000..bb77f6c00 --- /dev/null +++ b/tdesign-component/example/lib/gen_l10n/app_localizations_zh.dart @@ -0,0 +1,138 @@ +import 'app_localizations.dart'; + +/// The translations for Chinese (`zh`). +class AppLocalizationsZh extends AppLocalizations { + AppLocalizationsZh([String locale = 'zh']) : super(locale); + + @override + String get components => 'TDesign Flutter 组件库'; + + @override + String get about => '关于'; + + @override + String get defaultTheme => '默认主题'; + + @override + String get greenTheme => '绿色主题'; + + @override + String get redTheme => '红色主题'; + + @override + String get cancel => '取消'; + + @override + String get confirm => '确认'; + + @override + String get switchClose => '关'; + + @override + String get switchOpen => '开'; + + @override + String get knew => '知道了'; + + @override + String get loading => '加载中'; + + @override + String get loadingWithPoint => '加载中...'; + + @override + String get other => '其它'; + + @override + String get refreshing => '正在刷新'; + + @override + String get releaseRefresh => '松开刷新'; + + @override + String get reset => '重置'; + + @override + String get days => '天'; + + @override + String get hours => '时'; + + @override + String get minutes => '分'; + + @override + String get seconds => '秒'; + + @override + String get milliseconds => '毫秒'; + + @override + String get sunday => '日'; + + @override + String get monday => '一'; + + @override + String get tuesday => '二'; + + @override + String get wednesday => '三'; + + @override + String get thursday => '四'; + + @override + String get friday => '五'; + + @override + String get saturday => '六'; + + @override + String get year => ' 年'; + + @override + String get january => '1 月'; + + @override + String get february => '2 月'; + + @override + String get march => '3 月'; + + @override + String get april => '4 月'; + + @override + String get may => '5 月'; + + @override + String get june => '6 月'; + + @override + String get july => '7 月'; + + @override + String get august => '8 月'; + + @override + String get september => '9 月'; + + @override + String get october => '10 月'; + + @override + String get november => '11 月'; + + @override + String get december => '12 月'; + + @override + String get time => '时间'; + + @override + String get start => '开始'; + + @override + String get end => '结束'; +} diff --git a/tdesign-component/example/lib/home.dart b/tdesign-component/example/lib/home.dart index e28808419..b42ac630c 100644 --- a/tdesign-component/example/lib/home.dart +++ b/tdesign-component/example/lib/home.dart @@ -1,8 +1,8 @@ import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; -import 'package:flutter_gen/gen_l10n/app_localizations.dart'; +import 'package:tdesign_flutter/src/util/log.dart'; import 'package:tdesign_flutter/tdesign_flutter.dart'; - +import 'gen_l10n/app_localizations.dart'; import 'base/example_base.dart'; import 'base/example_route.dart'; import 'base/web_md_tool.dart'; diff --git a/tdesign-component/example/lib/main.dart b/tdesign-component/example/lib/main.dart index 763298943..c05d0d502 100644 --- a/tdesign-component/example/lib/main.dart +++ b/tdesign-component/example/lib/main.dart @@ -1,6 +1,6 @@ import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; -import 'package:flutter_gen/gen_l10n/app_localizations.dart'; +import 'gen_l10n/app_localizations.dart'; import 'package:tdesign_flutter/src/util/log.dart'; import 'package:tdesign_flutter/tdesign_flutter.dart'; diff --git a/tdesign-component/example/lib/page/td_form_page.dart b/tdesign-component/example/lib/page/td_form_page.dart new file mode 100644 index 000000000..c72dc29bb --- /dev/null +++ b/tdesign-component/example/lib/page/td_form_page.dart @@ -0,0 +1,188 @@ +import 'package:flutter/material.dart'; +import 'package:tdesign_flutter/tdesign_flutter.dart'; + +import '../../annotation/demo.dart'; +import '../../base/example_widget.dart'; + +class TDFormPage extends StatelessWidget { + const TDFormPage({Key? key}) : super(key: key); + + final exampleTxt = '文本Text'; + + @override + Widget build(BuildContext context) { + // debugPaintBaselinesEnabled = true; + return ExamplePage( + padding: const EdgeInsets.all(8), + title: tdTitle(context), + exampleCodeGroup: 'text', + children: [ + ExampleModule(title: '使用示例', children: [ + ExampleItem(desc: '系统Text:', builder: _buildSystemText), + ExampleItem(desc: '普通TDText:', builder: _buildNormalTDText), + ExampleItem(desc: '指定常用属性:', builder: _buildGeneralProp), + ExampleItem( + desc: 'style覆盖textColor,不覆盖font:', + builder: _buildStyleCoverColor), + ExampleItem( + desc: 'style覆盖textColor和font:', + builder: _buildStyleCoverColorAndFont), + ExampleItem(desc: 'TDText.rich测试:', builder: _buildRichText), + ExampleItem(desc: '获取系统Text:', builder: _getSystemText), + ExampleItem( + desc: '中文居中:(带有英文可能不居中)', builder: _buildVerticalCenterText), + ExampleItem(desc: '自定义内部padding:', builder: _buildCustomPaddingText), + ]), + ], + test: [ + ExampleItem( + desc: '中文居中-系统字体', + builder: (context){ + return Container( + color: TDTheme.of(context).brandFocusColor, + child: Text(exampleTxt), + ); + }), + ExampleItem( + desc: '中文居中-TD字体', + builder: (context){ + return Container( + color: TDTheme.of(context).brandFocusColor, + child: TDText(exampleTxt, forceVerticalCenter: true,), + ); + }), + ], + ); + } + + @Demo(group: 'text') + Widget _buildNormalTDText(BuildContext context) { + return TDText( + exampleTxt, + ); + } + + @Demo(group: 'text') + Widget _buildSystemText(BuildContext context) { + return Text( + exampleTxt, + ); + } + + @Demo(group: 'text') + Widget _buildGeneralProp(BuildContext context) { + return TDText( + exampleTxt, + font: TDTheme.of(context).fontHeadlineLarge, + textColor: TDTheme.of(context).brandNormalColor, + backgroundColor: TDTheme.of(context).brandFocusColor, + ); + } + + @Demo(group: 'text') + Widget _buildStyleCoverColor(BuildContext context) { + return TDText( + exampleTxt, + font: TDTheme.of(context).fontBodyLarge, + textColor: TDTheme.of(context).brandNormalColor, + style: TextStyle(color: TDTheme.of(context).errorNormalColor), + ); + } + + @Demo(group: 'text') + Widget _buildStyleCoverColorAndFont(BuildContext context) { + return TDText( + exampleTxt, + font: TDTheme.of(context).fontBodyLarge, + textColor: TDTheme.of(context).brandNormalColor, + ); + } + + @Demo(group: 'text') + Widget _buildRichText(BuildContext context) { + return TDText.rich( + TextSpan(children: [ + TDTextSpan( + text: 'TDTextSpan1', + font: TDTheme.of(context).fontTitleExtraLarge, + textColor: TDTheme.of(context).warningNormalColor, + isTextThrough: true, + lineThroughColor: TDTheme.of(context).brandNormalColor, + style: TextStyle(color: TDTheme.of(context).errorNormalColor)), + TextSpan( + text: 'TextSpan2', + style: TextStyle( + fontSize: 14, color: TDTheme.of(context).brandNormalColor)), + const WidgetSpan( + child: Icon( + TDIcons.setting, + size: 24, + )), + ]), + font: TDTheme.of(context).fontBodyLarge, + textColor: TDTheme.of(context).brandNormalColor, + style: + TextStyle(color: TDTheme.of(context).errorNormalColor, fontSize: 32), + ); + } + + @Demo(group: 'text') + Widget _getSystemText(BuildContext context) { + return TDText( + exampleTxt, + backgroundColor: TDTheme.of(context).brandFocusColor, + ).getRawText(context: context); + } + + @Demo(group: 'text') + Widget _buildVerticalCenterText(BuildContext context) { + return TDText( + '中华人民共和国腾讯科技', + // font: Font(size: 100, lineHeight: 100), + forceVerticalCenter: true, + backgroundColor: TDTheme.of(context).brandFocusColor, + ); + } + + @Demo(group: 'text') + Widget _buildCustomPaddingText(BuildContext context) { + return TDTextConfiguration( + paddingConfig: CustomTextPaddingConfig(), + child: const CustomPaddingText(), + ); + } +} + +/// 自定义控件,内部的context可拿到外部TDTextConfiguration的配置信息 +class CustomPaddingText extends StatelessWidget { + const CustomPaddingText({Key? key}) : super(key: key); + + @override + Widget build(BuildContext context) { + return Column( + mainAxisSize: MainAxisSize.min, + children: [ + TDText( + '中华人民共和国腾讯科技fgjpqy', + forceVerticalCenter: true, + backgroundColor: TDTheme.of(context).brandFocusColor, + ), + TDText( + 'English', + font: TDTheme.of(context).fontHeadlineLarge, + forceVerticalCenter: true, + backgroundColor: TDTheme.of(context).brandFocusColor, + ), + ], + ); + } +} + +/// 重写内部padding方法 +class CustomTextPaddingConfig extends TDTextPaddingConfig { + @override + EdgeInsetsGeometry getPadding(String? data, double fontSize, double height) { + var supperPadding = super.getPadding(data, fontSize, height); + return EdgeInsets.only(left: 30, top: supperPadding.vertical.toDouble()); + } +} diff --git a/tdesign-component/example/pubspec.lock b/tdesign-component/example/pubspec.lock index a208e30dd..e5af407b6 100644 --- a/tdesign-component/example/pubspec.lock +++ b/tdesign-component/example/pubspec.lock @@ -1,6 +1,22 @@ # Generated by pub # See https://dart.dev/tools/pub/glossary#lockfile packages: + _fe_analyzer_shared: + dependency: transitive + description: + name: _fe_analyzer_shared + sha256: eb376e9acf6938204f90eb3b1f00b578640d3188b4c8a8ec054f9f479af8d051 + url: "https://pub.dev" + source: hosted + version: "64.0.0" + analyzer: + dependency: transitive + description: + name: analyzer + sha256: "69f54f967773f6c26c7dcb13e93d7ccee8b17a641689da39e878d5cf13b06893" + url: "https://pub.dev" + source: hosted + version: "6.2.0" args: dependency: transitive description: @@ -49,6 +65,30 @@ packages: url: "https://pub.dev" source: hosted version: "1.17.1" + color: + dependency: transitive + description: + name: color + sha256: ddcdf1b3badd7008233f5acffaf20ca9f5dc2cd0172b75f68f24526a5f5725cb + url: "https://pub.dev" + source: hosted + version: "3.0.0" + convert: + dependency: transitive + description: + name: convert + sha256: "0f08b14755d163f6e2134cb58222dd25ea2a2ee8a195e53983d57c075324d592" + url: "https://pub.dev" + source: hosted + version: "3.1.1" + crypto: + dependency: transitive + description: + name: crypto + sha256: ff625774173754681d66daaf4a448684fb04b78f902da9cb3d308c19cc5e8bab + url: "https://pub.dev" + source: hosted + version: "3.0.3" cupertino_icons: dependency: "direct main" description: @@ -57,6 +97,22 @@ packages: url: "https://pub.dev" source: hosted version: "1.0.6" + dart_style: + dependency: transitive + description: + name: dart_style + sha256: "99e066ce75c89d6b29903d788a7bb9369cf754f7b24bf70bf4b6d6d6b26853b9" + url: "https://pub.dev" + source: hosted + version: "2.3.6" + dartx: + dependency: transitive + description: + name: dartx + sha256: "8b25435617027257d43e6508b5fe061012880ddfdaa75a71d607c3de2a13d244" + url: "https://pub.dev" + source: hosted + version: "1.2.0" fake_async: dependency: transitive description: @@ -73,6 +129,14 @@ packages: url: "https://pub.dev" source: hosted version: "2.1.0" + file: + dependency: transitive + description: + name: file + sha256: "5fc22d7c25582e38ad9a8515372cd9a93834027aacf1801cf01164dac0ffa08c" + url: "https://pub.dev" + source: hosted + version: "7.0.0" flutter: dependency: "direct main" description: flutter @@ -86,6 +150,22 @@ packages: url: "https://pub.dev" source: hosted version: "2.2.2" + flutter_gen: + dependency: transitive + description: + name: flutter_gen + sha256: "7a5f9e14a151664422d37498daa0b63cda8e1068ae2c95d32d46515cb69cd227" + url: "https://pub.dev" + source: hosted + version: "5.7.0" + flutter_gen_core: + dependency: transitive + description: + name: flutter_gen_core + sha256: "638d518897f1aefc55a24278968027591d50223a6943b6ae9aa576fe1494d99d" + url: "https://pub.dev" + source: hosted + version: "5.7.0" flutter_lints: dependency: "direct dev" description: @@ -128,6 +208,22 @@ packages: description: flutter source: sdk version: "0.0.0" + glob: + dependency: transitive + description: + name: glob + sha256: "0e7014b3b7d4dac1ca4d6114f82bf1782ee86745b9b42a92c9289c23d8a0ab63" + url: "https://pub.dev" + source: hosted + version: "2.1.2" + hashcodes: + dependency: transitive + description: + name: hashcodes + sha256: "80f9410a5b3c8e110c4b7604546034749259f5d6dcca63e0d3c17c9258f1a651" + url: "https://pub.dev" + source: hosted + version: "2.0.0" http: dependency: "direct main" description: @@ -144,6 +240,14 @@ packages: url: "https://pub.dev" source: hosted version: "4.0.2" + image_size_getter: + dependency: transitive + description: + name: image_size_getter + sha256: f98c4246144e9b968899d2dfde69091e22a539bb64bc9b0bea51505fbb490e57 + url: "https://pub.dev" + source: hosted + version: "2.1.3" intl: dependency: "direct main" description: @@ -160,6 +264,14 @@ packages: url: "https://pub.dev" source: hosted version: "0.6.7" + json_annotation: + dependency: transitive + description: + name: json_annotation + sha256: "1ce844379ca14835a50d2f019a3099f419082cfdd231cd86a142af94dd5c6bb1" + url: "https://pub.dev" + source: hosted + version: "4.9.0" lints: dependency: transitive description: @@ -200,6 +312,22 @@ packages: url: "https://pub.dev" source: hosted version: "1.9.1" + mime: + dependency: transitive + description: + name: mime + sha256: e4ff8e8564c03f255408decd16e7899da1733852a9110a58fe6d1b817684a63e + url: "https://pub.dev" + source: hosted + version: "1.0.4" + package_config: + dependency: transitive + description: + name: package_config + sha256: "1c5b77ccc91e4823a5af61ee74e6b972db1ef98c2ff5a18d3161c982a55448bd" + url: "https://pub.dev" + source: hosted + version: "2.1.0" path: dependency: transitive description: @@ -208,6 +336,14 @@ packages: url: "https://pub.dev" source: hosted version: "1.8.3" + path_parsing: + dependency: transitive + description: + name: path_parsing + sha256: e3e67b1629e6f7e8100b367d3db6ba6af4b1f0bb80f64db18ef1fbabd2fa9ccf + url: "https://pub.dev" + source: hosted + version: "1.0.1" path_provider: dependency: "direct main" description: @@ -256,6 +392,14 @@ packages: url: "https://pub.dev" source: hosted version: "2.2.1" + petitparser: + dependency: transitive + description: + name: petitparser + sha256: cb3798bef7fc021ac45b308f4b51208a152792445cce0448c9a4ba5879dd8750 + url: "https://pub.dev" + source: hosted + version: "5.4.0" platform: dependency: transitive description: @@ -272,6 +416,14 @@ packages: url: "https://pub.dev" source: hosted version: "2.1.8" + pub_semver: + dependency: transitive + description: + name: pub_semver + sha256: "40d3ab1bbd474c4c2328c91e3a7df8c6dd629b79ece4c4bd04bee496a224fb0c" + url: "https://pub.dev" + source: hosted + version: "2.1.4" sky_engine: dependency: transitive description: flutter @@ -315,7 +467,7 @@ packages: path: ".." relative: true source: path - version: "0.1.5" + version: "0.1.6" term_glyph: dependency: transitive description: @@ -332,6 +484,14 @@ packages: url: "https://pub.dev" source: hosted version: "0.5.1" + time: + dependency: transitive + description: + name: time + sha256: ad8e018a6c9db36cb917a031853a1aae49467a93e0d464683e029537d848c221 + url: "https://pub.dev" + source: hosted + version: "2.1.4" typed_data: dependency: transitive description: @@ -340,6 +500,22 @@ packages: url: "https://pub.dev" source: hosted version: "1.3.2" + vector_graphics_codec: + dependency: transitive + description: + name: vector_graphics_codec + sha256: c86987475f162fadff579e7320c7ddda04cd2fdeffbe1129227a85d9ac9e03da + url: "https://pub.dev" + source: hosted + version: "1.1.11+1" + vector_graphics_compiler: + dependency: transitive + description: + name: vector_graphics_compiler + sha256: "12faff3f73b1741a36ca7e31b292ddeb629af819ca9efe9953b70bd63fc8cd81" + url: "https://pub.dev" + source: hosted + version: "1.1.11+1" vector_math: dependency: transitive description: @@ -348,6 +524,14 @@ packages: url: "https://pub.dev" source: hosted version: "2.1.4" + watcher: + dependency: transitive + description: + name: watcher + sha256: "3d2ad6751b3c16cf07c7fca317a1413b3f26530319181b37e3b9039b84fc01d8" + url: "https://pub.dev" + source: hosted + version: "1.1.0" win32: dependency: transitive description: @@ -364,6 +548,22 @@ packages: url: "https://pub.dev" source: hosted version: "1.0.4" + xml: + dependency: transitive + description: + name: xml + sha256: "5bc72e1e45e941d825fd7468b9b4cc3b9327942649aeb6fc5cdbf135f0a86e84" + url: "https://pub.dev" + source: hosted + version: "6.3.0" + yaml: + dependency: transitive + description: + name: yaml + sha256: "75769501ea3489fca56601ff33454fe45507ea3bfb014161abc3b43ae25989d5" + url: "https://pub.dev" + source: hosted + version: "3.1.2" sdks: dart: ">=3.0.0 <4.0.0" flutter: ">=3.10.0" diff --git a/tdesign-component/lib/src/components/form/td_form.dart b/tdesign-component/lib/src/components/form/td_form.dart new file mode 100644 index 000000000..e69de29bb diff --git a/tdesign-component/lib/src/components/form/td_form_item.dart b/tdesign-component/lib/src/components/form/td_form_item.dart new file mode 100644 index 000000000..c2f4ba5cd --- /dev/null +++ b/tdesign-component/lib/src/components/form/td_form_item.dart @@ -0,0 +1,21 @@ +import 'package:flutter/material.dart'; + +class TDForm_items extends StatefulWidget { + const TDForm_items({ + Key?key, + this.label, +}); + + /// 表格内标签 内容填充 + final String? label; + + @override + State createState() => _TDForm_itemsState(); +} + +class _TDForm_itemsState extends State { + @override + Widget build(BuildContext context) { + return const Placeholder(); + } +} \ No newline at end of file diff --git a/tdesign-component/pubspec.lock b/tdesign-component/pubspec.lock index 1a1978a1c..9ff5c7995 100644 --- a/tdesign-component/pubspec.lock +++ b/tdesign-component/pubspec.lock @@ -1,6 +1,30 @@ # Generated by pub # See https://dart.dev/tools/pub/glossary#lockfile packages: + _fe_analyzer_shared: + dependency: transitive + description: + name: _fe_analyzer_shared + sha256: "0b2f2bd91ba804e53a61d757b986f89f1f9eaed5b11e4b2f5a2468d86d6c9fc7" + url: "https://pub.dev" + source: hosted + version: "67.0.0" + analyzer: + dependency: transitive + description: + name: analyzer + sha256: "37577842a27e4338429a1cbc32679d508836510b056f1eedf0c8d20e39c1383d" + url: "https://pub.dev" + source: hosted + version: "6.4.1" + args: + dependency: transitive + description: + name: args + sha256: "7cf60b9f0cc88203c5a190b4cd62a99feea42759a7fa695010eb5de1c0b2252a" + url: "https://pub.dev" + source: hosted + version: "2.5.0" async: dependency: transitive description: @@ -37,10 +61,50 @@ packages: dependency: transitive description: name: collection - sha256: "4a07be6cb69c84d677a6c3096fcf960cc3285a8330b4603e0d463d15d9bd934c" + sha256: ee67cb0715911d28db6bf4af1026078bd6f0128b07a5f66fb2ed94ec6783c09a + url: "https://pub.dev" + source: hosted + version: "1.18.0" + color: + dependency: transitive + description: + name: color + sha256: ddcdf1b3badd7008233f5acffaf20ca9f5dc2cd0172b75f68f24526a5f5725cb + url: "https://pub.dev" + source: hosted + version: "3.0.0" + convert: + dependency: transitive + description: + name: convert + sha256: "0f08b14755d163f6e2134cb58222dd25ea2a2ee8a195e53983d57c075324d592" + url: "https://pub.dev" + source: hosted + version: "3.1.1" + crypto: + dependency: transitive + description: + name: crypto + sha256: ec30d999af904f33454ba22ed9a86162b35e52b44ac4807d1d93c288041d7d27 + url: "https://pub.dev" + source: hosted + version: "3.0.5" + dart_style: + dependency: transitive + description: + name: dart_style + sha256: "99e066ce75c89d6b29903d788a7bb9369cf754f7b24bf70bf4b6d6d6b26853b9" + url: "https://pub.dev" + source: hosted + version: "2.3.6" + dartx: + dependency: transitive + description: + name: dartx + sha256: "8b25435617027257d43e6508b5fe061012880ddfdaa75a71d607c3de2a13d244" url: "https://pub.dev" source: hosted - version: "1.17.1" + version: "1.2.0" fake_async: dependency: transitive description: @@ -49,6 +113,14 @@ packages: url: "https://pub.dev" source: hosted version: "1.3.1" + file: + dependency: transitive + description: + name: file + sha256: "5fc22d7c25582e38ad9a8515372cd9a93834027aacf1801cf01164dac0ffa08c" + url: "https://pub.dev" + source: hosted + version: "7.0.0" flutter: dependency: "direct main" description: flutter @@ -62,6 +134,22 @@ packages: url: "https://pub.dev" source: hosted version: "2.2.2" + flutter_gen: + dependency: "direct main" + description: + name: flutter_gen + sha256: "7a5f9e14a151664422d37498daa0b63cda8e1068ae2c95d32d46515cb69cd227" + url: "https://pub.dev" + source: hosted + version: "5.7.0" + flutter_gen_core: + dependency: transitive + description: + name: flutter_gen_core + sha256: "638d518897f1aefc55a24278968027591d50223a6943b6ae9aa576fe1494d99d" + url: "https://pub.dev" + source: hosted + version: "5.7.0" flutter_lints: dependency: "direct dev" description: @@ -91,14 +179,62 @@ packages: description: flutter source: sdk version: "0.0.0" - js: + glob: dependency: transitive description: - name: js - sha256: f2c445dce49627136094980615a031419f7f3eb393237e4ecd97ac15dea343f3 + name: glob + sha256: "0e7014b3b7d4dac1ca4d6114f82bf1782ee86745b9b42a92c9289c23d8a0ab63" url: "https://pub.dev" source: hosted - version: "0.6.7" + version: "2.1.2" + hashcodes: + dependency: transitive + description: + name: hashcodes + sha256: "80f9410a5b3c8e110c4b7604546034749259f5d6dcca63e0d3c17c9258f1a651" + url: "https://pub.dev" + source: hosted + version: "2.0.0" + image_size_getter: + dependency: transitive + description: + name: image_size_getter + sha256: f98c4246144e9b968899d2dfde69091e22a539bb64bc9b0bea51505fbb490e57 + url: "https://pub.dev" + source: hosted + version: "2.1.3" + json_annotation: + dependency: transitive + description: + name: json_annotation + sha256: "1ce844379ca14835a50d2f019a3099f419082cfdd231cd86a142af94dd5c6bb1" + url: "https://pub.dev" + source: hosted + version: "4.9.0" + leak_tracker: + dependency: transitive + description: + name: leak_tracker + sha256: "7f0df31977cb2c0b88585095d168e689669a2cc9b97c309665e3386f3e9d341a" + url: "https://pub.dev" + source: hosted + version: "10.0.4" + leak_tracker_flutter_testing: + dependency: transitive + description: + name: leak_tracker_flutter_testing + sha256: "06e98f569d004c1315b991ded39924b21af84cf14cc94791b8aea337d25b57f8" + url: "https://pub.dev" + source: hosted + version: "3.0.3" + leak_tracker_testing: + dependency: transitive + description: + name: leak_tracker_testing + sha256: "6ba465d5d76e67ddf503e1161d1f4a6bc42306f9d66ca1e8f079a47290fb06d3" + url: "https://pub.dev" + source: hosted + version: "3.0.1" lints: dependency: transitive description: @@ -111,34 +247,74 @@ packages: dependency: transitive description: name: matcher - sha256: "6501fbd55da300384b768785b83e5ce66991266cec21af89ab9ae7f5ce1c4cbb" + sha256: d2323aa2060500f906aa31a895b4030b6da3ebdcc5619d14ce1aada65cd161cb url: "https://pub.dev" source: hosted - version: "0.12.15" + version: "0.12.16+1" material_color_utilities: dependency: transitive description: name: material_color_utilities - sha256: d92141dc6fe1dad30722f9aa826c7fbc896d021d792f80678280601aff8cf724 + sha256: "0e0a020085b65b6083975e499759762399b4475f766c21668c4ecca34ea74e5a" url: "https://pub.dev" source: hosted - version: "0.2.0" + version: "0.8.0" meta: dependency: transitive description: name: meta - sha256: "3c74dbf8763d36539f114c799d8a2d87343b5067e9d796ca22b5eb8437090ee3" + sha256: "7687075e408b093f36e6bbf6c91878cc0d4cd10f409506f7bc996f68220b9136" + url: "https://pub.dev" + source: hosted + version: "1.12.0" + mime: + dependency: transitive + description: + name: mime + sha256: "801fd0b26f14a4a58ccb09d5892c3fbdeff209594300a542492cf13fba9d247a" + url: "https://pub.dev" + source: hosted + version: "1.0.6" + package_config: + dependency: transitive + description: + name: package_config + sha256: "1c5b77ccc91e4823a5af61ee74e6b972db1ef98c2ff5a18d3161c982a55448bd" url: "https://pub.dev" source: hosted - version: "1.9.1" + version: "2.1.0" path: dependency: transitive description: name: path - sha256: "8829d8a55c13fc0e37127c29fedf290c102f4e40ae94ada574091fe0ff96c917" + sha256: "087ce49c3f0dc39180befefc60fdb4acd8f8620e5682fe2476afd0b3688bb4af" url: "https://pub.dev" source: hosted - version: "1.8.3" + version: "1.9.0" + path_parsing: + dependency: transitive + description: + name: path_parsing + sha256: e3e67b1629e6f7e8100b367d3db6ba6af4b1f0bb80f64db18ef1fbabd2fa9ccf + url: "https://pub.dev" + source: hosted + version: "1.0.1" + petitparser: + dependency: transitive + description: + name: petitparser + sha256: c15605cd28af66339f8eb6fbe0e541bfe2d1b72d5825efc6598f3e0a31b9ad27 + url: "https://pub.dev" + source: hosted + version: "6.0.2" + pub_semver: + dependency: transitive + description: + name: pub_semver + sha256: "40d3ab1bbd474c4c2328c91e3a7df8c6dd629b79ece4c4bd04bee496a224fb0c" + url: "https://pub.dev" + source: hosted + version: "2.1.4" sky_engine: dependency: transitive description: flutter @@ -148,26 +324,26 @@ packages: dependency: transitive description: name: source_span - sha256: dd904f795d4b4f3b870833847c461801f6750a9fa8e61ea5ac53f9422b31f250 + sha256: "53e943d4206a5e30df338fd4c6e7a077e02254531b138a15aec3bd143c1a8b3c" url: "https://pub.dev" source: hosted - version: "1.9.1" + version: "1.10.0" stack_trace: dependency: transitive description: name: stack_trace - sha256: c3c7d8edb15bee7f0f74debd4b9c5f3c2ea86766fe4178eb2a18eb30a0bdaed5 + sha256: "73713990125a6d93122541237550ee3352a2d84baad52d375a4cad2eb9b7ce0b" url: "https://pub.dev" source: hosted - version: "1.11.0" + version: "1.11.1" stream_channel: dependency: transitive description: name: stream_channel - sha256: "83615bee9045c1d322bbbd1ba209b7a749c2cbcdcb3fdd1df8eb488b3279c1c8" + sha256: ba2aa5d8cc609d96bbb2899c28934f9e1af5cddbd60a827822ea467161eb54e7 url: "https://pub.dev" source: hosted - version: "2.1.1" + version: "2.1.2" string_scanner: dependency: transitive description: @@ -188,10 +364,42 @@ packages: dependency: transitive description: name: test_api - sha256: eb6ac1540b26de412b3403a163d919ba86f6a973fe6cc50ae3541b80092fdcfb + sha256: "9955ae474176f7ac8ee4e989dadfb411a58c30415bcfb648fa04b2b8a03afa7f" + url: "https://pub.dev" + source: hosted + version: "0.7.0" + time: + dependency: transitive + description: + name: time + sha256: ad8e018a6c9db36cb917a031853a1aae49467a93e0d464683e029537d848c221 + url: "https://pub.dev" + source: hosted + version: "2.1.4" + typed_data: + dependency: transitive + description: + name: typed_data + sha256: facc8d6582f16042dd49f2463ff1bd6e2c9ef9f3d5da3d9b087e244a7b564b3c + url: "https://pub.dev" + source: hosted + version: "1.3.2" + vector_graphics_codec: + dependency: transitive + description: + name: vector_graphics_codec + sha256: c86987475f162fadff579e7320c7ddda04cd2fdeffbe1129227a85d9ac9e03da + url: "https://pub.dev" + source: hosted + version: "1.1.11+1" + vector_graphics_compiler: + dependency: transitive + description: + name: vector_graphics_compiler + sha256: "12faff3f73b1741a36ca7e31b292ddeb629af819ca9efe9953b70bd63fc8cd81" url: "https://pub.dev" source: hosted - version: "0.5.1" + version: "1.1.11+1" vector_math: dependency: transitive description: @@ -200,6 +408,38 @@ packages: url: "https://pub.dev" source: hosted version: "2.1.4" + vm_service: + dependency: transitive + description: + name: vm_service + sha256: "3923c89304b715fb1eb6423f017651664a03bf5f4b29983627c4da791f74a4ec" + url: "https://pub.dev" + source: hosted + version: "14.2.1" + watcher: + dependency: transitive + description: + name: watcher + sha256: "3d2ad6751b3c16cf07c7fca317a1413b3f26530319181b37e3b9039b84fc01d8" + url: "https://pub.dev" + source: hosted + version: "1.1.0" + xml: + dependency: transitive + description: + name: xml + sha256: b015a8ad1c488f66851d762d3090a21c600e479dc75e68328c52774040cf9226 + url: "https://pub.dev" + source: hosted + version: "6.5.0" + yaml: + dependency: transitive + description: + name: yaml + sha256: "75769501ea3489fca56601ff33454fe45507ea3bfb014161abc3b43ae25989d5" + url: "https://pub.dev" + source: hosted + version: "3.1.2" sdks: - dart: ">=3.0.0-0 <4.0.0" - flutter: ">=3.7.0" + dart: ">=3.4.0 <4.0.0" + flutter: ">=3.18.0-18.0.pre.54" diff --git a/tdesign-component/pubspec.yaml b/tdesign-component/pubspec.yaml index 276ba7b99..29392a3a9 100644 --- a/tdesign-component/pubspec.yaml +++ b/tdesign-component/pubspec.yaml @@ -19,6 +19,7 @@ dependencies: # 滑动单元格组件 flutter_slidable: 3.1.0 + flutter_gen: ^5.7.0 # # 相册选择组件 # image_picker: 1.1.2 diff --git a/tdesign-site/package-lock.json b/tdesign-site/package-lock.json index e36d40a4c..a1004a38b 100644 --- a/tdesign-site/package-lock.json +++ b/tdesign-site/package-lock.json @@ -9,7 +9,8 @@ "version": "0.1.2", "license": "MIT", "dependencies": { - "dayjs": "^1.10.7" + "dayjs": "^1.10.7", + "tdesign-flutter": "file:" }, "devDependencies": { "@babel/core": "^7.12.10", @@ -22551,6 +22552,10 @@ "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", "dev": true }, + "node_modules/tdesign-flutter": { + "resolved": "", + "link": true + }, "node_modules/tdesign-icons-svg": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/tdesign-icons-svg/-/tdesign-icons-svg-0.0.1.tgz", diff --git a/tdesign-site/package.json b/tdesign-site/package.json index 0d73de3f0..82da512da 100644 --- a/tdesign-site/package.json +++ b/tdesign-site/package.json @@ -121,6 +121,7 @@ ] }, "dependencies": { - "dayjs": "^1.10.7" + "dayjs": "^1.10.7", + "tdesign-flutter": "file:" } -} \ No newline at end of file +} From f71b44352ece8596b3444037f7025895140a656e Mon Sep 17 00:00:00 2001 From: Simon_Wzy <1691663479@qq.com> Date: Wed, 25 Sep 2024 10:33:37 +0800 Subject: [PATCH 02/46] =?UTF-8?q?API=E5=88=9B=E5=BB=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../lib/src/components/form/td_form.dart | 80 +++++++++++++++++++ .../lib/src/components/form/td_form_item.dart | 53 ++++++++++-- 2 files changed, 126 insertions(+), 7 deletions(-) diff --git a/tdesign-component/lib/src/components/form/td_form.dart b/tdesign-component/lib/src/components/form/td_form.dart index e69de29bb..ef17bff11 100644 --- a/tdesign-component/lib/src/components/form/td_form.dart +++ b/tdesign-component/lib/src/components/form/td_form.dart @@ -0,0 +1,80 @@ +import 'package:flutter/material.dart'; + +class TDForm extends StatefulWidget { + const TDForm({ + Key?key, + this.colon = false, + this.contentAlign = 'left', + this.data, + this.disabled = false, + this.errorMessage, + this.labelAlign = 'right', + this.labelWidth = '81px', + this.preventSubmitDefault = true, + this.requiredMark = true, // 此处必填项有小问题 + this.resetType = 'empty', + this.rules, + this.scrollToFirstError, + this.showErrorMessage = true, + this.submitWithWarningMessage = false, + }): super(key: key); + + /// 是否在表单标签字段右侧显示冒号 + final bool? colon; + + /// 表单内容对齐方式: 左对齐、右对齐 + /// 可选项: left/right + final String? contentAlign; + + /// 表单数据 + final Object? data; + + /// 是否禁用整个表单 + final bool? disabled; + + /// 表单信息错误信息配置 + final Object? errorMessage; + + /// 表单字段标签的对齐方式: + /// 左对齐、右对齐、顶部对齐 + /// 可选项: left/right/top + final String? labelAlign; + + /// 可以整体设置 label 标签宽度,默认为 81px + final String? labelWidth; + + /// 是否阻止表单提交默认事件(表单提交默认事件会刷新页面) + /// 设置为 true 可以避免刷新 + final bool? preventSubmitDefault; + + /// 是否显示必填符号(*),默认显示 + final bool? requiredMark; + + /// 重置表单的方式,值为 empty 表示重置表单为空,值为 initial 表示重置表单数据为初始值 + /// 可选项:empty/initial + final String? resetType; + + /// 表单字段校验规则 + final Object? rules; + + /// 表单校验不通过时,是否自动滚动到第一个校验不通过的字段,平滑滚动或是瞬间直达。 + /// 值为空则表示不滚动。可选项:''/smooth/auto + final String? scrollToFirstError; + + /// 校验不通过时,是否显示错误提示信息,统一控制全部表单项 + /// 如果希望控制单个表单项,请给 FormItem 设置该属性 + final bool? showErrorMessage; + + /// 【讨论中】当校验结果只有告警信息时,是否触发 submit 提交事件 + final bool? submitWithWarningMessage; + + @override + State createState() => _TDFormState(); +} + +class _TDFormState extends State { + @override + Widget build(BuildContext context) { + return const Placeholder(); + } +} \ No newline at end of file diff --git a/tdesign-component/lib/src/components/form/td_form_item.dart b/tdesign-component/lib/src/components/form/td_form_item.dart index c2f4ba5cd..ccc021291 100644 --- a/tdesign-component/lib/src/components/form/td_form_item.dart +++ b/tdesign-component/lib/src/components/form/td_form_item.dart @@ -1,19 +1,58 @@ import 'package:flutter/material.dart'; -class TDForm_items extends StatefulWidget { - const TDForm_items({ +class TDFormIems extends StatelessWidget { + const TDFormIems({ Key?key, this.label, -}); + this.name, + this.arrow = false, + this.contentAlign = 'left', + this.help, + this.labelAlign, + this.labelWidth, + this.requiredMark, + this.rules, + this.showErrowMessage, + }): super(key: key); + /// 表单内容对齐方式: + /// 左对齐、右对齐 + /// 可选项:left/right + final String? contentAlign; + + /// 是否显示右箭头 + final bool? arrow; + + /// 表单说明内容 ???? + final help; + /// 表格内标签 内容填充 final String? label; + + /// 表单字段标签对齐方式: + /// 左对齐、右对齐、顶部对齐 + /// 默认使用 Form 的对齐方式,其优先级高于 Form.labelAlign + /// 可选项: left/right.top + final String? labelAlign; - @override - State createState() => _TDForm_itemsState(); -} + /// 可以整体调整标签宽度 + /// 优先级高于 Form.labelWidth + final String? labelWidth; + + /// 表格标识 + final String? name; + + /// 是否显示必填符号 (*) + /// 优先级高于 Form.requiredMark + final bool? requiredMark; + + /// 表单字段校验规则 ??? + final List? rules; -class _TDForm_itemsState extends State { + /// 校验不通过时,是否显示错误提示信息 + /// 优先级高于 Form.showErrowMessage + final bool? showErrowMessage; + @override Widget build(BuildContext context) { return const Placeholder(); From ef17cbce8b7d6904cd496c7594d36c1bc4ddff55 Mon Sep 17 00:00:00 2001 From: hkaikai <617760820@qq.com> Date: Wed, 25 Sep 2024 11:24:30 +0800 Subject: [PATCH 03/46] =?UTF-8?q?rate=E7=BB=84=E4=BB=B6=E5=88=9D=E5=A7=8B?= =?UTF-8?q?=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tdesign-component/example/lib/config.dart | 3 +- .../example/lib/page/td_rate_page.dart | 43 ++++++++++ .../lib/src/components/rate/td_rate.dart | 83 +++++++++++++++++++ tdesign-component/lib/tdesign_flutter.dart | 7 +- 4 files changed, 132 insertions(+), 4 deletions(-) create mode 100644 tdesign-component/example/lib/page/td_rate_page.dart create mode 100644 tdesign-component/lib/src/components/rate/td_rate.dart diff --git a/tdesign-component/example/lib/config.dart b/tdesign-component/example/lib/config.dart index 9002eb153..188b20acc 100644 --- a/tdesign-component/example/lib/config.dart +++ b/tdesign-component/example/lib/config.dart @@ -38,6 +38,7 @@ import 'page/td_picker_page.dart'; import 'page/td_popup_page.dart'; import 'page/td_radio_page.dart'; import 'page/td_radius_page.dart'; +import 'page/td_rate_page.dart'; import 'page/td_refresh_page.dart'; import 'page/td_search_bar_page.dart'; import 'page/td_shadows_page.dart'; @@ -127,7 +128,7 @@ Map> exampleMap = { ExamplePageModel( text: 'Radio 单选框', name: 'radio', pageBuilder: _wrapInheritedTheme((context) => const TDRadioPage())), ExamplePageModel( - text: 'Rate 评分', name: 'rate', isTodo: true, pageBuilder: _wrapInheritedTheme((context) => const TodoPage())), + text: 'Rate 评分', name: 'rate', pageBuilder: _wrapInheritedTheme((context) => const TDRatePage())), ExamplePageModel( text: 'Search 搜索框', name: 'search', pageBuilder: _wrapInheritedTheme((context) => const TDSearchBarPage())), ExamplePageModel( diff --git a/tdesign-component/example/lib/page/td_rate_page.dart b/tdesign-component/example/lib/page/td_rate_page.dart new file mode 100644 index 000000000..0d5dba515 --- /dev/null +++ b/tdesign-component/example/lib/page/td_rate_page.dart @@ -0,0 +1,43 @@ +import 'package:flutter/material.dart'; +import 'package:tdesign_flutter/tdesign_flutter.dart'; + +import '../annotation/demo.dart'; +import '../base/example_widget.dart'; + +/// +/// TDRadio演示 +/// +class TDRatePage extends StatefulWidget { + const TDRatePage({Key? key}) : super(key: key); + + @override + State createState() { + return TDRatePageState(); + } +} + +class TDRatePageState extends State { + @override + void initState() { + super.initState(); + } + + @override + Widget build(BuildContext context) { + return ExamplePage( + title: tdTitle(), + desc: '用于对某行为/事物进行打分。', + exampleCodeGroup: 'rate', + backgroundColor: TDTheme.of(context).grayColor2, + children: [ + ExampleModule(title: '组件类型', children: [ + ExampleItem(desc: '实心评分', builder: _buildFilledRate), + ]), + ]); + } + + @Demo(group: 'rate') + Widget _buildFilledRate(BuildContext context) { + return Container(); + } +} diff --git a/tdesign-component/lib/src/components/rate/td_rate.dart b/tdesign-component/lib/src/components/rate/td_rate.dart new file mode 100644 index 000000000..a917ed22a --- /dev/null +++ b/tdesign-component/lib/src/components/rate/td_rate.dart @@ -0,0 +1,83 @@ +import 'package:flutter/material.dart'; + +import '../../../tdesign_flutter.dart'; + +enum PlacementEnum { + none, + top, + bottom, +} + +/// 评分组件 +class TDRate extends StatefulWidget { + const TDRate({ + super.key, + this.allowHalf = false, + this.color, + this.count = 5, + this.disabled = false, + this.gap, + this.icon, + this.iconWidget, + this.placement = PlacementEnum.top, + this.showText = false, + this.size = 24.0, + this.texts = const ['极差', '失望', '一般', '满意', '惊喜'], + this.defaultValue = 0, + this.onChange, + }); + + /// 是否允许半选 + final bool? allowHalf; + + /// 评分图标的颜色,示例:[选中颜色] / [选中颜色,未选中颜色],默认:[TDTheme.of(context).warningColor5, TDTheme.of(context).grayColor4] + final List? color; + + /// 评分的数量 + final int? count; + + /// 是否禁用评分 + final bool? disabled; + + /// 评分图标的间距,默认:TDTheme.of(context).spacer8 + final double? gap; + + /// 自定义评分图标,[选中和未选中图标] / [选中图标,未选中图标],默认:[TDIcons.star_filled] + final List? icon; + + /// 自定义评分图标组件,[选中和未选中图标] / [选中图标,未选中图标],设置此值会忽略[color]/[icon]/[size] + final List? iconWidget; + + /// 选择评分弹框的位置,值为[PlacementEnum.none]表示不显示评分弹框。 + final PlacementEnum? placement; + + /// 是否显示对应的辅助文字 + final bool? showText; + + /// 评分图标的大小 + final double? size; + + /// 评分等级对应的辅助文字,长度应与[count]一致。自定义值示例:['1分', '2分', '3分', '4分', '5分']。 + final List? texts; + + /// 选择评分的默认值 + final double? defaultValue; + + /// 评分数改变时触发 + final void Function(double value)? onChange; + + @override + _TDRateState createState() => _TDRateState(); +} + +class _TDRateState extends State { + @override + void initState() { + super.initState(); + } + + @override + Widget build(BuildContext context) { + return Container(); + } +} diff --git a/tdesign-component/lib/tdesign_flutter.dart b/tdesign-component/lib/tdesign_flutter.dart index 7cd90df95..788caff4c 100644 --- a/tdesign-component/lib/tdesign_flutter.dart +++ b/tdesign-component/lib/tdesign_flutter.dart @@ -14,9 +14,6 @@ export 'src/components/checkbox/td_check_box.dart'; export 'src/components/checkbox/td_check_box_group.dart'; export 'src/components/collapse/td_collapse.dart'; export 'src/components/collapse/td_collapse_panel.dart'; -export 'src/components/time_counter/td_time_counter.dart'; -export 'src/components/time_counter/td_time_counter_controller.dart'; -export 'src/components/time_counter/td_time_counter_style.dart'; export 'src/components/dialog/td_dialog.dart'; export 'src/components/divider/td_divider.dart'; export 'src/components/drawer/td_drawer.dart'; @@ -46,6 +43,7 @@ export 'src/components/picker/td_picker.dart'; export 'src/components/popup/td_popup_panel.dart'; export 'src/components/popup/td_popup_route.dart'; export 'src/components/radio/td_radio.dart'; +export 'src/components/rate/td_rate.dart'; export 'src/components/refresh/td_refresh_header.dart'; export 'src/components/search/td_search_bar.dart'; export 'src/components/sidebar/td_sidebar.dart'; @@ -72,6 +70,9 @@ export 'src/components/tag/td_tag_styles.dart'; export 'src/components/text/td_font_loader.dart'; export 'src/components/text/td_text.dart'; export 'src/components/textarea/td_textarea.dart'; +export 'src/components/time_counter/td_time_counter.dart'; +export 'src/components/time_counter/td_time_counter_controller.dart'; +export 'src/components/time_counter/td_time_counter_style.dart'; export 'src/components/toast/td_toast.dart'; export 'src/components/tree/td_tree_select.dart'; export 'src/theme/basic.dart'; From bb5b80b1b3d98d640b4cd3d18eb2391d04ddc72c Mon Sep 17 00:00:00 2001 From: Simon_Wzy <1691663479@qq.com> Date: Wed, 25 Sep 2024 14:38:49 +0800 Subject: [PATCH 04/46] formitem1.0 --- .../example/lib/page/td_form_page.dart | 198 ++++-------------- .../lib/src/components/form/td_form_item.dart | 55 ++++- tdesign-component/lib/tdesign_flutter.dart | 4 +- 3 files changed, 86 insertions(+), 171 deletions(-) diff --git a/tdesign-component/example/lib/page/td_form_page.dart b/tdesign-component/example/lib/page/td_form_page.dart index c72dc29bb..38c1bf07b 100644 --- a/tdesign-component/example/lib/page/td_form_page.dart +++ b/tdesign-component/example/lib/page/td_form_page.dart @@ -18,171 +18,51 @@ class TDFormPage extends StatelessWidget { exampleCodeGroup: 'text', children: [ ExampleModule(title: '使用示例', children: [ - ExampleItem(desc: '系统Text:', builder: _buildSystemText), - ExampleItem(desc: '普通TDText:', builder: _buildNormalTDText), - ExampleItem(desc: '指定常用属性:', builder: _buildGeneralProp), - ExampleItem( - desc: 'style覆盖textColor,不覆盖font:', - builder: _buildStyleCoverColor), - ExampleItem( - desc: 'style覆盖textColor和font:', - builder: _buildStyleCoverColorAndFont), - ExampleItem(desc: 'TDText.rich测试:', builder: _buildRichText), - ExampleItem(desc: '获取系统Text:', builder: _getSystemText), - ExampleItem( - desc: '中文居中:(带有英文可能不居中)', builder: _buildVerticalCenterText), - ExampleItem(desc: '自定义内部padding:', builder: _buildCustomPaddingText), + ExampleItem(desc: '自定义内部padding:', builder: _buildUserNameItem), ]), ], - test: [ - ExampleItem( - desc: '中文居中-系统字体', - builder: (context){ - return Container( - color: TDTheme.of(context).brandFocusColor, - child: Text(exampleTxt), - ); - }), - ExampleItem( - desc: '中文居中-TD字体', - builder: (context){ - return Container( - color: TDTheme.of(context).brandFocusColor, - child: TDText(exampleTxt, forceVerticalCenter: true,), - ); - }), - ], - ); - } - - @Demo(group: 'text') - Widget _buildNormalTDText(BuildContext context) { - return TDText( - exampleTxt, - ); - } - - @Demo(group: 'text') - Widget _buildSystemText(BuildContext context) { - return Text( - exampleTxt, - ); - } - - @Demo(group: 'text') - Widget _buildGeneralProp(BuildContext context) { - return TDText( - exampleTxt, - font: TDTheme.of(context).fontHeadlineLarge, - textColor: TDTheme.of(context).brandNormalColor, - backgroundColor: TDTheme.of(context).brandFocusColor, - ); - } - - @Demo(group: 'text') - Widget _buildStyleCoverColor(BuildContext context) { - return TDText( - exampleTxt, - font: TDTheme.of(context).fontBodyLarge, - textColor: TDTheme.of(context).brandNormalColor, - style: TextStyle(color: TDTheme.of(context).errorNormalColor), - ); - } - - @Demo(group: 'text') - Widget _buildStyleCoverColorAndFont(BuildContext context) { - return TDText( - exampleTxt, - font: TDTheme.of(context).fontBodyLarge, - textColor: TDTheme.of(context).brandNormalColor, - ); - } - - @Demo(group: 'text') - Widget _buildRichText(BuildContext context) { - return TDText.rich( - TextSpan(children: [ - TDTextSpan( - text: 'TDTextSpan1', - font: TDTheme.of(context).fontTitleExtraLarge, - textColor: TDTheme.of(context).warningNormalColor, - isTextThrough: true, - lineThroughColor: TDTheme.of(context).brandNormalColor, - style: TextStyle(color: TDTheme.of(context).errorNormalColor)), - TextSpan( - text: 'TextSpan2', - style: TextStyle( - fontSize: 14, color: TDTheme.of(context).brandNormalColor)), - const WidgetSpan( - child: Icon( - TDIcons.setting, - size: 24, - )), - ]), - font: TDTheme.of(context).fontBodyLarge, - textColor: TDTheme.of(context).brandNormalColor, - style: - TextStyle(color: TDTheme.of(context).errorNormalColor, fontSize: 32), - ); - } - - @Demo(group: 'text') - Widget _getSystemText(BuildContext context) { - return TDText( - exampleTxt, - backgroundColor: TDTheme.of(context).brandFocusColor, - ).getRawText(context: context); - } - - @Demo(group: 'text') - Widget _buildVerticalCenterText(BuildContext context) { - return TDText( - '中华人民共和国腾讯科技', - // font: Font(size: 100, lineHeight: 100), - forceVerticalCenter: true, - backgroundColor: TDTheme.of(context).brandFocusColor, - ); - } - - @Demo(group: 'text') - Widget _buildCustomPaddingText(BuildContext context) { - return TDTextConfiguration( - paddingConfig: CustomTextPaddingConfig(), - child: const CustomPaddingText(), ); } } -/// 自定义控件,内部的context可拿到外部TDTextConfiguration的配置信息 -class CustomPaddingText extends StatelessWidget { - const CustomPaddingText({Key? key}) : super(key: key); - @override - Widget build(BuildContext context) { - return Column( - mainAxisSize: MainAxisSize.min, - children: [ - TDText( - '中华人民共和国腾讯科技fgjpqy', - forceVerticalCenter: true, - backgroundColor: TDTheme.of(context).brandFocusColor, - ), - TDText( - 'English', - font: TDTheme.of(context).fontHeadlineLarge, - forceVerticalCenter: true, - backgroundColor: TDTheme.of(context).brandFocusColor, - ), - ], - ); - } -} +@Demo(group: 'form') +Widget _buildUserNameItem(BuildContext buildContext) { + + return TDFormItem(); -/// 重写内部padding方法 -class CustomTextPaddingConfig extends TDTextPaddingConfig { - @override - EdgeInsetsGeometry getPadding(String? data, double fontSize, double height) { - var supperPadding = super.getPadding(data, fontSize, height); - return EdgeInsets.only(left: 30, top: supperPadding.vertical.toDouble()); - } } + +// /// 自定义控件,内部的context可拿到外部TDTextConfiguration的配置信息 +// class CustomPaddingText extends StatelessWidget { +// const CustomPaddingText({Key? key}) : super(key: key); + +// @override +// Widget build(BuildContext context) { +// return Column( +// mainAxisSize: MainAxisSize.min, +// children: [ +// TDText( +// '中华人民共和国腾讯科技fgjpqy', +// forceVerticalCenter: true, +// backgroundColor: TDTheme.of(context).brandFocusColor, +// ), +// TDText( +// 'English', +// font: TDTheme.of(context).fontHeadlineLarge, +// forceVerticalCenter: true, +// backgroundColor: TDTheme.of(context).brandFocusColor, +// ), +// ], +// ); +// } +// } + +// /// 重写内部padding方法 +// class CustomTextPaddingConfig extends TDTextPaddingConfig { +// @override +// EdgeInsetsGeometry getPadding(String? data, double fontSize, double height) { +// var supperPadding = super.getPadding(data, fontSize, height); +// return EdgeInsets.only(left: 30, top: supperPadding.vertical.toDouble()); +// } +// } diff --git a/tdesign-component/lib/src/components/form/td_form_item.dart b/tdesign-component/lib/src/components/form/td_form_item.dart index ccc021291..d23eb5859 100644 --- a/tdesign-component/lib/src/components/form/td_form_item.dart +++ b/tdesign-component/lib/src/components/form/td_form_item.dart @@ -1,8 +1,8 @@ import 'package:flutter/material.dart'; -class TDFormIems extends StatelessWidget { - const TDFormIems({ - Key?key, +class TDFormItem extends StatelessWidget { + const TDFormItem({ + Key? key, this.label, this.name, this.arrow = false, @@ -13,22 +13,22 @@ class TDFormIems extends StatelessWidget { this.requiredMark, this.rules, this.showErrowMessage, - }): super(key: key); + }) : super(key: key); /// 表单内容对齐方式: /// 左对齐、右对齐 /// 可选项:left/right final String? contentAlign; - + /// 是否显示右箭头 final bool? arrow; - + /// 表单说明内容 ???? final help; - + /// 表格内标签 内容填充 final String? label; - + /// 表单字段标签对齐方式: /// 左对齐、右对齐、顶部对齐 /// 默认使用 Form 的对齐方式,其优先级高于 Form.labelAlign @@ -52,9 +52,42 @@ class TDFormIems extends StatelessWidget { /// 校验不通过时,是否显示错误提示信息 /// 优先级高于 Form.showErrowMessage final bool? showErrowMessage; - + @override Widget build(BuildContext context) { - return const Placeholder(); + return Row( + mainAxisAlignment: contentAlign == 'right' + ? MainAxisAlignment.end + : MainAxisAlignment.start, + children: [ + // 标签 + Container( + width: labelWidth != null ? double.parse(labelWidth!) : null, + alignment: labelAlign == 'right' + ? Alignment.centerRight + : labelAlign == 'top' + ? Alignment.topLeft + : Alignment.centerLeft, + child: Text( + label ?? '', + style: TextStyle( + fontWeight: + requiredMark == true ? FontWeight.bold : FontWeight.normal, + ), + ), + ), + const SizedBox(width: 8), // 标签与输入框的间距 + // 输入框 + Expanded( + child: TextFormField( + decoration: InputDecoration( + hintText: help, + suffixIcon: arrow == true ? Icon(Icons.arrow_forward) : null, + ), + // 可添加更多属性,如 validator 等 + ), + ), + ], + ); } -} \ No newline at end of file +} diff --git a/tdesign-component/lib/tdesign_flutter.dart b/tdesign-component/lib/tdesign_flutter.dart index c995c207f..a3cd067c1 100644 --- a/tdesign-component/lib/tdesign_flutter.dart +++ b/tdesign-component/lib/tdesign_flutter.dart @@ -23,6 +23,8 @@ export 'src/components/dropdown_menu/td_dropdown_item.dart'; export 'src/components/dropdown_menu/td_dropdown_menu.dart'; export 'src/components/empty/td_empty.dart'; export 'src/components/fab/td_fab.dart'; +export 'src/components/form/td_form.dart'; +export 'src/components/form/td_form_item.dart'; export 'src/components/icon/td_icons.dart'; export 'src/components/image/image_widget.dart'; export 'src/components/image/td_image.dart'; @@ -81,4 +83,4 @@ export 'src/theme/td_radius.dart'; export 'src/theme/td_shadows.dart'; export 'src/theme/td_spacers.dart'; export 'src/theme/td_theme.dart'; -export 'src/util/platform_util.dart'; +export 'src/util/platform_util.dart'; \ No newline at end of file From 73b34616c375c31c0f0b56d3884faff4ef0f1d9f Mon Sep 17 00:00:00 2001 From: hkaikai <617760820@qq.com> Date: Wed, 25 Sep 2024 18:15:31 +0800 Subject: [PATCH 05/46] =?UTF-8?q?=E4=B8=BB=E4=BD=93=E9=80=BB=E8=BE=91?= =?UTF-8?q?=E5=BC=80=E5=8F=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../lib/base/intl_resource_delegate.dart | 3 + tdesign-component/example/lib/l10n/app_en.arb | 3 +- tdesign-component/example/lib/l10n/app_zh.arb | 3 +- .../example/lib/page/td_rate_page.dart | 2 +- .../lib/src/components/rate/td_rate.dart | 175 +++++++++++++++++- .../lib/src/theme/resource_delegate.dart | 6 + 6 files changed, 180 insertions(+), 12 deletions(-) diff --git a/tdesign-component/example/lib/base/intl_resource_delegate.dart b/tdesign-component/example/lib/base/intl_resource_delegate.dart index b6e216db0..4a2e072dc 100644 --- a/tdesign-component/example/lib/base/intl_resource_delegate.dart +++ b/tdesign-component/example/lib/base/intl_resource_delegate.dart @@ -132,4 +132,7 @@ class IntlResourceDelegate extends TDResourceDelegate { @override String get end => AppLocalizations.of(context)!.end; + + @override + String get notRated => AppLocalizations.of(context)!.notRated; } diff --git a/tdesign-component/example/lib/l10n/app_en.arb b/tdesign-component/example/lib/l10n/app_en.arb index aa60c8588..b3b64430f 100644 --- a/tdesign-component/example/lib/l10n/app_en.arb +++ b/tdesign-component/example/lib/l10n/app_en.arb @@ -42,5 +42,6 @@ "december": "December", "time": "Time", "start": "Start", - "end": "End" + "end": "End", + "notRated": "Not rated" } \ No newline at end of file diff --git a/tdesign-component/example/lib/l10n/app_zh.arb b/tdesign-component/example/lib/l10n/app_zh.arb index 9400960a3..0972f1381 100644 --- a/tdesign-component/example/lib/l10n/app_zh.arb +++ b/tdesign-component/example/lib/l10n/app_zh.arb @@ -42,5 +42,6 @@ "december": "12 月", "time": "时间", "start": "开始", - "end": "结束" + "end": "结束", + "notRated": "未评分" } \ No newline at end of file diff --git a/tdesign-component/example/lib/page/td_rate_page.dart b/tdesign-component/example/lib/page/td_rate_page.dart index 0d5dba515..577e0dcfb 100644 --- a/tdesign-component/example/lib/page/td_rate_page.dart +++ b/tdesign-component/example/lib/page/td_rate_page.dart @@ -38,6 +38,6 @@ class TDRatePageState extends State { @Demo(group: 'rate') Widget _buildFilledRate(BuildContext context) { - return Container(); + return const Padding(padding: EdgeInsets.all(50), child: TDRate()); } } diff --git a/tdesign-component/lib/src/components/rate/td_rate.dart b/tdesign-component/lib/src/components/rate/td_rate.dart index a917ed22a..7d15329fa 100644 --- a/tdesign-component/lib/src/components/rate/td_rate.dart +++ b/tdesign-component/lib/src/components/rate/td_rate.dart @@ -1,6 +1,9 @@ import 'package:flutter/material.dart'; +import 'package:flutter/rendering.dart'; import '../../../tdesign_flutter.dart'; +import '../../util/context_extension.dart'; +import '../../util/iterable_ext.dart'; enum PlacementEnum { none, @@ -18,13 +21,15 @@ class TDRate extends StatefulWidget { this.disabled = false, this.gap, this.icon, - this.iconWidget, this.placement = PlacementEnum.top, this.showText = false, this.size = 24.0, this.texts = const ['极差', '失望', '一般', '满意', '惊喜'], - this.defaultValue = 0, + this.builderText, + this.value = 0, this.onChange, + this.iconTextAlignment = MainAxisAlignment.start, + this.iconTextGap, }); /// 是否允许半选 @@ -45,9 +50,6 @@ class TDRate extends StatefulWidget { /// 自定义评分图标,[选中和未选中图标] / [选中图标,未选中图标],默认:[TDIcons.star_filled] final List? icon; - /// 自定义评分图标组件,[选中和未选中图标] / [选中图标,未选中图标],设置此值会忽略[color]/[icon]/[size] - final List? iconWidget; - /// 选择评分弹框的位置,值为[PlacementEnum.none]表示不显示评分弹框。 final PlacementEnum? placement; @@ -57,27 +59,182 @@ class TDRate extends StatefulWidget { /// 评分图标的大小 final double? size; - /// 评分等级对应的辅助文字,长度应与[count]一致。自定义值示例:['1分', '2分', '3分', '4分', '5分']。 + /// 评分等级对应的辅助文字, + /// 当[allowHalf]为false时长度应与[count]一致, + /// 当[allowHalf]为true时长度应为[count]的两倍, + /// 自定义值示例:['1分', '2分', '3分', '4分', '5分']。 final List? texts; - /// 选择评分的默认值 - final double? defaultValue; + /// 评分等级对应的辅助文字自定义构建,优先级高于[texts] + final Widget Function(BuildContext context, double value)? builderText; + + /// 选择评分的值 + final double? value; /// 评分数改变时触发 final void Function(double value)? onChange; + /// 评分图标与辅助文字的对齐方式 + final MainAxisAlignment? iconTextAlignment; + + /// 评分图标与辅助文字的间距,默认:[TDTheme.of(context).spacer16] + final double? iconTextGap; + @override _TDRateState createState() => _TDRateState(); } class _TDRateState extends State { + late double _activeValue; + late Map _globalKeys; + var _showTip = false; @override void initState() { super.initState(); + _activeValue = widget.value ?? 0; + _globalKeys = List.generate((widget.count ?? 5) * 2, (index) => index / 2 + 1) + .asMap() + .map((index, e) => MapEntry(e, GlobalKey())); + } + + @override + void didUpdateWidget(TDRate oldWidget) { + super.didUpdateWidget(oldWidget); + if (widget.value != oldWidget.value) { + _activeValue = widget.value ?? 0; + } + if (widget.count != oldWidget.count) { + _globalKeys = List.generate((widget.count ?? 5) * 2, (index) => index / 2 + 1) + .asMap() + .map((index, e) => MapEntry(e, GlobalKey())); + } } @override Widget build(BuildContext context) { - return Container(); + return Row( + mainAxisAlignment: widget.iconTextAlignment ?? MainAxisAlignment.start, + children: [ + GestureDetector( + behavior: HitTestBehavior.opaque, + onVerticalDragUpdate: (details) { + _changeSelect(details.globalPosition); + }, + onTapUp: (details) { + _changeSelect(details.globalPosition); + _hideTip(); + }, + onVerticalDragEnd: (details) { + _hideTip(); + }, + child: Row( + children: List.generate(widget.count ?? 5, (index) { + final isLast = index == (widget.count ?? 5) - 1; + final icon = widget.icon?.getOrNull(index) ?? TDIcons.star_filled; + return Padding( + padding: EdgeInsets.only(right: isLast ? 0 : widget.gap ?? TDTheme.of(context).spacer8), + child: Stack( + clipBehavior: Clip.none, + children: [ + Row( + children: [ + ClipRect( + key: _globalKeys[index + 0.5], + child: Align( + alignment: Alignment.centerLeft, + widthFactor: 0.5, + child: Icon( + icon, + size: widget.size ?? 24, + color: _getIconColor(index + 0.5), + ), + ), + ), + ClipRect( + key: _globalKeys[index + 1.0], + child: Align( + alignment: Alignment.centerRight, + widthFactor: 0.5, + child: Icon( + icon, + size: widget.size ?? 24, + color: _getIconColor(index + 1.0), + ), + ), + ), + ], + ), + ], + ), + ); + }), + ), + ), + if (widget.showText ?? false) widget.builderText?.call(context, _activeValue) ?? _getDefText() + ], + ); + } + + void _changeSelect(Offset globalPosition) { + final newIndex = _fingerInsideContainer(globalPosition); + if (newIndex != null && newIndex != _activeValue) { + setState(() { + _activeValue = newIndex; + _showTip = newIndex == 0 ? false : true; + }); + widget.onChange?.call(newIndex); + } + } + + double? _fingerInsideContainer(Offset globalPosition) { + final rateBox = context.findRenderObject() as RenderBox?; + if (rateBox == null) { + return null; + } + final rateOffset = rateBox.localToGlobal(Offset.zero); + if (globalPosition.dx < rateOffset.dx) { + return 0; + } + for (var entry in _globalKeys.entries) { + final renderBox = entry.value.currentContext?.findRenderObject() as RenderBox?; + if (renderBox != null) { + final localPosition = renderBox.globalToLocal(globalPosition); + final isIn = renderBox.hitTest(BoxHitTestResult(), position: localPosition); + if (isIn) { + return (widget.allowHalf ?? false) ? entry.key : entry.key.ceil().toDouble(); + } + } + } + return null; + } + + void _hideTip() { + Future.delayed( + const Duration(seconds: 1), + () { + setState(() { + _showTip = false; + }); + }, + ); + } + + Widget _getDefText() { + final notRated = _activeValue == 0; + final textIndex = (widget.allowHalf ?? false) ? _activeValue : _activeValue * 2; + return Padding( + padding: EdgeInsets.only(left: widget.iconTextGap ?? TDTheme.of(context).spacer16), + child: TDText( + notRated ? context.resource.notRated : widget.texts?.getOrNull(textIndex.toInt()) ?? _activeValue, + font: notRated ? TDTheme.of(context).fontBodyLarge : TDTheme.of(context).fontTitleMedium, + textColor: notRated ? TDTheme.of(context).fontGyColor4 : TDTheme.of(context).fontGyColor1, + ), + ); + } + + Color _getIconColor(double value) { + return _activeValue >= value + ? widget.color?.getOrNull(0) ?? TDTheme.of(context).warningColor5 + : widget.color?.getOrNull(1) ?? TDTheme.of(context).grayColor4; } } diff --git a/tdesign-component/lib/src/theme/resource_delegate.dart b/tdesign-component/lib/src/theme/resource_delegate.dart index 093e20018..d354e941a 100644 --- a/tdesign-component/lib/src/theme/resource_delegate.dart +++ b/tdesign-component/lib/src/theme/resource_delegate.dart @@ -169,6 +169,9 @@ abstract class TDResourceDelegate { /// [TDCalendar] 结束 String get end; + + /// [TDRate] 未评分 + String get notRated; } /// 如果用户要重写,就应该全部重写,不开放只重新部分资源 @@ -292,4 +295,7 @@ class _DefaultResourceDelegate extends TDResourceDelegate { @override String get end => '结束'; + + @override + String get notRated => '未评分'; } From 5f1ccc84d7ba3b646f84892eed0e6b4f274bc55b Mon Sep 17 00:00:00 2001 From: hkaikai <617760820@qq.com> Date: Fri, 27 Sep 2024 17:00:24 +0800 Subject: [PATCH 06/46] =?UTF-8?q?rate=20demo=E7=BC=96=E5=86=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../lib/page/td_dropdown_menu_page.dart | 2 +- .../example/lib/page/td_rate_page.dart | 50 ++++- .../dropdown_menu/td_dropdown_item.dart | 4 + .../dropdown_menu/td_dropdown_menu.dart | 4 +- .../components/indexes/td_indexes_list.dart | 12 +- .../lib/src/components/rate/td_rate.dart | 126 +++++++++--- .../lib/src/components/rate/td_rate_tips.dart | 190 ++++++++++++++++++ 7 files changed, 357 insertions(+), 31 deletions(-) create mode 100644 tdesign-component/lib/src/components/rate/td_rate_tips.dart diff --git a/tdesign-component/example/lib/page/td_dropdown_menu_page.dart b/tdesign-component/example/lib/page/td_dropdown_menu_page.dart index 761970abe..a9f93ba6c 100644 --- a/tdesign-component/example/lib/page/td_dropdown_menu_page.dart +++ b/tdesign-component/example/lib/page/td_dropdown_menu_page.dart @@ -396,7 +396,7 @@ TDDropdownMenu _buildOverflow(BuildContext context) { tabBarWidth: 200, tabBarAlign: MainAxisAlignment.start, options: [ - TDDropdownItemOption(label: '选项1', value: '1', selected: true), + TDDropdownItemOption(label: '选项1选项1选项1选项1选项1选项1选项1', value: '1', selected: true), TDDropdownItemOption(label: '选项2', value: '2'), ], ), diff --git a/tdesign-component/example/lib/page/td_rate_page.dart b/tdesign-component/example/lib/page/td_rate_page.dart index 577e0dcfb..bc51bfba3 100644 --- a/tdesign-component/example/lib/page/td_rate_page.dart +++ b/tdesign-component/example/lib/page/td_rate_page.dart @@ -32,12 +32,60 @@ class TDRatePageState extends State { children: [ ExampleModule(title: '组件类型', children: [ ExampleItem(desc: '实心评分', builder: _buildFilledRate), + ExampleItem(desc: '自定义评分', builder: _buildCusRate), + ExampleItem(desc: '自定义评分数量', builder: _buildNumRate), + ExampleItem(desc: '带描述评分', builder: _buildMsgRate), + ExampleItem(desc: '评分弹框位置', builder: _buildDRate), + ]), + ExampleModule(title: '组件状态', children: [ + ExampleItem(desc: '只可选全星时', builder: _buildFullRate), + ExampleItem(desc: '可选半星时', builder: _buildHalfRate), ]), ]); } @Demo(group: 'rate') Widget _buildFilledRate(BuildContext context) { - return const Padding(padding: EdgeInsets.all(50), child: TDRate()); + return const TDCell(title: '实心评分', noteWidget: TDRate(value: 3)); + } + + @Demo(group: 'rate') + Widget _buildCusRate(BuildContext context) { + return const TDCell(title: '自定义评分', noteWidget: TDRate(value: 3, icon: [TDIcons.thumb_up])); + } + + @Demo(group: 'rate') + Widget _buildNumRate(BuildContext context) { + return const TDCell(title: '自定义评分数量', noteWidget: TDRate(value: 2, count: 3,)); + } + + @Demo(group: 'rate') + Widget _buildMsgRate(BuildContext context) { + return Column(children: const [ + TDCell(title: '带描述评分', noteWidget: TDRate(value: 3, showText: true, texts: ['很差', '差', '一般', '好评', '优秀'])), + SizedBox(height: 16), + TDCell(title: '带描述评分', noteWidget: TDRate(value: 3, showText: true)) + ]); + } + + @Demo(group: 'rate') + Widget _buildDRate(BuildContext context) { + return Column(children: const [ + TDCell(title: '顶部显示', noteWidget: TDRate(placement: PlacementEnum.top)), + SizedBox(height: 16), + TDCell(title: '不显示', noteWidget: TDRate(placement: PlacementEnum.none)), + SizedBox(height: 16), + TDCell(title: '底部显示', noteWidget: TDRate(placement: PlacementEnum.bottom)), + ]); + } + + @Demo(group: 'rate') + Widget _buildFullRate(BuildContext context) { + return const TDCell(title: '点击活滑动', noteWidget: TDRate(value: 3)); + } + + @Demo(group: 'rate') + Widget _buildHalfRate(BuildContext context) { + return const TDCell(title: '点击活滑动', noteWidget: TDRate(value: 3, allowHalf: true)); } } diff --git a/tdesign-component/lib/src/components/dropdown_menu/td_dropdown_item.dart b/tdesign-component/lib/src/components/dropdown_menu/td_dropdown_item.dart index ba7afec93..3ad893eaa 100644 --- a/tdesign-component/lib/src/components/dropdown_menu/td_dropdown_item.dart +++ b/tdesign-component/lib/src/components/dropdown_menu/td_dropdown_item.dart @@ -46,6 +46,7 @@ class TDDropdownItem extends StatefulWidget { this.maxHeight, this.tabBarWidth, this.tabBarAlign, + this.tabBarFlex = 1, }) : super(key: key); /// 是否禁用 @@ -90,6 +91,9 @@ class TDDropdownItem extends StatefulWidget { /// [label]和[arrowIcon]/[TDDropdownMenu.arrowIcon]的对齐方式 final MainAxisAlignment? tabBarAlign; + /// 该item在menu上的宽度占比,仅在[TDDropdownMenu.isScrollable]为false时有效 + final int? tabBarFlex; + static const double operateHeight = 73; double? get minContentHeight => diff --git a/tdesign-component/lib/src/components/dropdown_menu/td_dropdown_menu.dart b/tdesign-component/lib/src/components/dropdown_menu/td_dropdown_menu.dart index de0045961..037cb4ba8 100644 --- a/tdesign-component/lib/src/components/dropdown_menu/td_dropdown_menu.dart +++ b/tdesign-component/lib/src/components/dropdown_menu/td_dropdown_menu.dart @@ -130,6 +130,7 @@ class _TDDropdownMenuState extends State with TickerProviderStat _items?.length ?? 0, (index) { return Expanded( + flex: _items![index].tabBarFlex ?? 1, child: _tabBarContent(index), ); }, @@ -196,8 +197,9 @@ class _TDDropdownMenuState extends State with TickerProviderStat _isOpened[index] ? await Navigator.maybePop(context) : _openMenu(index); }, child: Row( + mainAxisSize: MainAxisSize.min, mainAxisAlignment: _items![index].tabBarAlign ?? widget.tabBarAlign ?? MainAxisAlignment.center, - children: [_getText(index), _getIcon(index)], + children: [Flexible(child: _getText(index)), _getIcon(index)], ), ); } diff --git a/tdesign-component/lib/src/components/indexes/td_indexes_list.dart b/tdesign-component/lib/src/components/indexes/td_indexes_list.dart index 244491580..1bff3360b 100644 --- a/tdesign-component/lib/src/components/indexes/td_indexes_list.dart +++ b/tdesign-component/lib/src/components/indexes/td_indexes_list.dart @@ -1,3 +1,5 @@ +import 'dart:async'; + import 'package:flutter/material.dart'; import 'package:flutter/rendering.dart'; import 'package:flutter/scheduler.dart'; @@ -40,6 +42,7 @@ class TDIndexesList extends StatefulWidget { class _TDIndexesListState extends State { late Map _containerKeys; final _indexSize = 20.0; + Timer? _hideTipTimer; var _showTip = false; @override @@ -56,6 +59,12 @@ class _TDIndexesListState extends State { } } + @override + void dispose() { + _hideTipTimer?.cancel(); + super.dispose(); + } + @override Widget build(BuildContext context) { return Positioned( @@ -176,7 +185,8 @@ class _TDIndexesListState extends State { } void _hideTip() { - Future.delayed( + _hideTipTimer?.cancel(); + _hideTipTimer = Timer( const Duration(seconds: 1), () { setState(() { diff --git a/tdesign-component/lib/src/components/rate/td_rate.dart b/tdesign-component/lib/src/components/rate/td_rate.dart index 7d15329fa..6fd85e71e 100644 --- a/tdesign-component/lib/src/components/rate/td_rate.dart +++ b/tdesign-component/lib/src/components/rate/td_rate.dart @@ -1,9 +1,12 @@ +import 'dart:async'; + import 'package:flutter/material.dart'; import 'package:flutter/rendering.dart'; import '../../../tdesign_flutter.dart'; import '../../util/context_extension.dart'; import '../../util/iterable_ext.dart'; +import 'td_rate_tips.dart'; enum PlacementEnum { none, @@ -25,10 +28,13 @@ class TDRate extends StatefulWidget { this.showText = false, this.size = 24.0, this.texts = const ['极差', '失望', '一般', '满意', '惊喜'], + this.textWidth = 48.0, this.builderText, this.value = 0, this.onChange, - this.iconTextAlignment = MainAxisAlignment.start, + this.direction = Axis.horizontal, + this.mainAxisAlignment = MainAxisAlignment.start, + this.crossAxisAlignment = CrossAxisAlignment.center, this.iconTextGap, }); @@ -65,6 +71,9 @@ class TDRate extends StatefulWidget { /// 自定义值示例:['1分', '2分', '3分', '4分', '5分']。 final List? texts; + /// 评分等级对应的辅助文字宽度 + final double? textWidth; + /// 评分等级对应的辅助文字自定义构建,优先级高于[texts] final Widget Function(BuildContext context, double value)? builderText; @@ -74,8 +83,14 @@ class TDRate extends StatefulWidget { /// 评分数改变时触发 final void Function(double value)? onChange; - /// 评分图标与辅助文字的对齐方式 - final MainAxisAlignment? iconTextAlignment; + /// 评分图标与辅助文字的布局方向 + final Axis? direction; + + /// 评分图标与辅助文字的主轴对齐方式 + final MainAxisAlignment? mainAxisAlignment; + + /// 评分图标与辅助文字的交叉轴对齐方式 + final CrossAxisAlignment? crossAxisAlignment; /// 评分图标与辅助文字的间距,默认:[TDTheme.of(context).spacer16] final double? iconTextGap; @@ -87,12 +102,25 @@ class TDRate extends StatefulWidget { class _TDRateState extends State { late double _activeValue; late Map _globalKeys; + Timer? _hideTipTimer; + + /// 控制显示弹框 var _showTip = false; + + /// 组件高度 + var _height = 0.0; + + /// 当前弹框宽度 + var _tipWidth = 0.0; + + /// 当前选中的评分宽度 + var _rateWidth = 0.0; + @override void initState() { super.initState(); _activeValue = widget.value ?? 0; - _globalKeys = List.generate((widget.count ?? 5) * 2, (index) => index / 2 + 1) + _globalKeys = List.generate((widget.count ?? 5) * 2, (index) => index / 2 + 0.5) .asMap() .map((index, e) => MapEntry(e, GlobalKey())); } @@ -104,33 +132,40 @@ class _TDRateState extends State { _activeValue = widget.value ?? 0; } if (widget.count != oldWidget.count) { - _globalKeys = List.generate((widget.count ?? 5) * 2, (index) => index / 2 + 1) + _globalKeys = List.generate((widget.count ?? 5) * 2, (index) => index / 2 + 0.5) .asMap() .map((index, e) => MapEntry(e, GlobalKey())); } } + @override + void dispose() { + _hideTipTimer?.cancel(); + super.dispose(); + } + @override Widget build(BuildContext context) { - return Row( - mainAxisAlignment: widget.iconTextAlignment ?? MainAxisAlignment.start, + return Flex( + direction: widget.direction ?? Axis.horizontal, + mainAxisAlignment: widget.mainAxisAlignment ?? MainAxisAlignment.start, + crossAxisAlignment: widget.crossAxisAlignment ?? CrossAxisAlignment.center, children: [ - GestureDetector( + Listener( behavior: HitTestBehavior.opaque, - onVerticalDragUpdate: (details) { - _changeSelect(details.globalPosition); + onPointerMove: (details) { + _changeSelect(details.position); }, - onTapUp: (details) { - _changeSelect(details.globalPosition); + onPointerUp: (details) { + _changeSelect(details.position); _hideTip(); }, - onVerticalDragEnd: (details) { + onPointerCancel: (details) { _hideTip(); }, child: Row( children: List.generate(widget.count ?? 5, (index) { final isLast = index == (widget.count ?? 5) - 1; - final icon = widget.icon?.getOrNull(index) ?? TDIcons.star_filled; return Padding( padding: EdgeInsets.only(right: isLast ? 0 : widget.gap ?? TDTheme.of(context).spacer8), child: Stack( @@ -144,9 +179,9 @@ class _TDRateState extends State { alignment: Alignment.centerLeft, widthFactor: 0.5, child: Icon( - icon, + _getIcon(value: index + 0.5), size: widget.size ?? 24, - color: _getIconColor(index + 0.5), + color: _getIconColor(value: index + 0.5), ), ), ), @@ -156,14 +191,37 @@ class _TDRateState extends State { alignment: Alignment.centerRight, widthFactor: 0.5, child: Icon( - icon, + _getIcon(value: index + 1.0), size: widget.size ?? 24, - color: _getIconColor(index + 1.0), + color: _getIconColor(value: index + 1.0), ), ), ), ], ), + if (widget.placement != PlacementEnum.none && + _showTip && + (index + 0.5 == _activeValue || index + 1 == _activeValue)) + Positioned( + bottom: widget.placement == PlacementEnum.top ? _height + TDTheme.of(context).spacer8 : null, + top: widget.placement == PlacementEnum.bottom ? _height + TDTheme.of(context).spacer8 : null, + left: -(_tipWidth - _rateWidth) / 2, + child: TDRateTips( + allowHalf: widget.allowHalf, + index: index, + activeValue: _activeValue, + icon: _getIcon(isActive: true), + size: widget.size, + getIconColor: _getIconColor, + withCall: (width) { + if (_tipWidth != width) { + setState(() { + _tipWidth = width; + }); + } + }, + ), + ), ], ), ); @@ -188,6 +246,7 @@ class _TDRateState extends State { double? _fingerInsideContainer(Offset globalPosition) { final rateBox = context.findRenderObject() as RenderBox?; + _height = rateBox?.size.height ?? 0; if (rateBox == null) { return null; } @@ -201,6 +260,7 @@ class _TDRateState extends State { final localPosition = renderBox.globalToLocal(globalPosition); final isIn = renderBox.hitTest(BoxHitTestResult(), position: localPosition); if (isIn) { + _rateWidth = renderBox.size.width * 2; return (widget.allowHalf ?? false) ? entry.key : entry.key.ceil().toDouble(); } } @@ -209,7 +269,8 @@ class _TDRateState extends State { } void _hideTip() { - Future.delayed( + _hideTipTimer?.cancel(); + _hideTipTimer = Timer( const Duration(seconds: 1), () { setState(() { @@ -221,20 +282,31 @@ class _TDRateState extends State { Widget _getDefText() { final notRated = _activeValue == 0; - final textIndex = (widget.allowHalf ?? false) ? _activeValue : _activeValue * 2; + final textIndex = (widget.allowHalf == true ? _activeValue * 2 : _activeValue) - 1; return Padding( - padding: EdgeInsets.only(left: widget.iconTextGap ?? TDTheme.of(context).spacer16), - child: TDText( - notRated ? context.resource.notRated : widget.texts?.getOrNull(textIndex.toInt()) ?? _activeValue, - font: notRated ? TDTheme.of(context).fontBodyLarge : TDTheme.of(context).fontTitleMedium, - textColor: notRated ? TDTheme.of(context).fontGyColor4 : TDTheme.of(context).fontGyColor1, + padding: widget.direction == Axis.horizontal + ? EdgeInsets.only(left: widget.iconTextGap ?? TDTheme.of(context).spacer16) + : EdgeInsets.only(top: widget.iconTextGap ?? TDTheme.of(context).spacer8), + child: SizedBox( + width: widget.textWidth ?? 50, + child: TDText( + notRated ? context.resource.notRated : widget.texts?.getOrNull(textIndex.toInt()) ?? '$_activeValue', + font: notRated ? TDTheme.of(context).fontBodyLarge : TDTheme.of(context).fontTitleMedium, + textColor: notRated ? TDTheme.of(context).fontGyColor4 : TDTheme.of(context).fontGyColor1, + ), ), ); } - Color _getIconColor(double value) { - return _activeValue >= value + Color _getIconColor({double? value, bool? isActive}) { + return (value != null && _activeValue >= value) || (isActive != null && isActive) ? widget.color?.getOrNull(0) ?? TDTheme.of(context).warningColor5 : widget.color?.getOrNull(1) ?? TDTheme.of(context).grayColor4; } + + IconData _getIcon({double? value, bool? isActive}) { + final selectIcon = widget.icon?.getOrNull(0) ?? TDIcons.star_filled; + final icon = [selectIcon, widget.icon?.getOrNull(1) ?? selectIcon]; + return (value != null && _activeValue >= value) || (isActive != null && isActive) ? icon[0] : icon[1]; + } } diff --git a/tdesign-component/lib/src/components/rate/td_rate_tips.dart b/tdesign-component/lib/src/components/rate/td_rate_tips.dart new file mode 100644 index 000000000..6dd5b5000 --- /dev/null +++ b/tdesign-component/lib/src/components/rate/td_rate_tips.dart @@ -0,0 +1,190 @@ +import 'package:flutter/material.dart'; + +import '../../../tdesign_flutter.dart'; + +/// 评分提示组件 +class TDRateTips extends StatelessWidget { + const TDRateTips({ + Key? key, + this.allowHalf = false, + required this.index, + required this.activeValue, + required this.icon, + this.size, + required this.getIconColor, + required this.withCall, + }) : super(key: key); + + final bool? allowHalf; + final int index; + final double activeValue; + final IconData icon; + final double? size; + final Color Function({double? value, bool? isActive}) getIconColor; + final void Function(double width) withCall; + + @override + Widget build(BuildContext context) { + final _tipKey = GlobalKey(); + WidgetsBinding.instance.addPostFrameCallback((_) { + final renderBox = _tipKey.currentContext?.findRenderObject() as RenderBox?; + withCall(renderBox?.size.width ?? 0.0); + }); + return Container( + key: _tipKey, + decoration: BoxDecoration( + color: TDTheme.of(context).whiteColor1, + boxShadow: const [ + BoxShadow( + color: Color.fromRGBO(0, 0, 0, 0.12), + offset: Offset(0, 2), + blurRadius: 4, + spreadRadius: -1, + ), + BoxShadow( + color: Color.fromRGBO(0, 0, 0, 0.08), + offset: Offset(0, 4), + blurRadius: 5, + spreadRadius: 0, + ), + BoxShadow( + color: Color.fromRGBO(0, 0, 0, 0.05), + offset: Offset(0, 1), + blurRadius: 10, + spreadRadius: 0, + ), + ], + borderRadius: BorderRadius.circular(TDTheme.of(context).radiusDefault), + ), + padding: EdgeInsets.all(TDTheme.of(context).spacer4), + child: Row( + children: [ + Container( + decoration: BoxDecoration( + color: (allowHalf ?? false) == false || index + 0.5 != activeValue + ? TDTheme.of(context).whiteColor1 + : TDTheme.of(context).grayColor3, + borderRadius: BorderRadius.circular(TDTheme.of(context).radiusSmall), + ), + padding: EdgeInsets.only(left: TDTheme.of(context).spacer4, right: TDTheme.of(context).spacer4), + child: Column( + children: [ + Row( + children: [ + ClipRect( + child: Align( + alignment: Alignment.centerLeft, + widthFactor: 0.5, + child: Icon( + icon, + size: size ?? 24, + color: getIconColor(isActive: true), + ), + ), + ), + ClipRect( + child: Align( + alignment: Alignment.centerRight, + widthFactor: 0.5, + child: Icon( + icon, + size: size ?? 24, + color: allowHalf == true ? getIconColor(isActive: false) : getIconColor(isActive: true), + ), + ), + ), + ], + ), + Center( + child: TDText( + allowHalf == true ? '${index + 0.5}' : '${index + 1}', + font: TDTheme.of(context).fontBodySmall, + textColor: TDTheme.of(context).fontGyColor1, + ), + ), + ], + ), + ), + if (allowHalf == true) SizedBox(width: TDTheme.of(context).spacer4), + if (allowHalf == true) + Container( + decoration: BoxDecoration( + color: index + 1 != activeValue ? TDTheme.of(context).whiteColor1 : TDTheme.of(context).grayColor3, + borderRadius: BorderRadius.circular(TDTheme.of(context).radiusSmall), + ), + padding: EdgeInsets.only(left: TDTheme.of(context).spacer4, right: TDTheme.of(context).spacer4), + child: Column( + children: [ + Icon( + icon, + size: size ?? 24, + color: getIconColor(isActive: true), + ), + Center( + child: TDText( + '${index + 1}', + font: TDTheme.of(context).fontBodySmall, + textColor: TDTheme.of(context).fontGyColor1, + ), + ), + ], + ), + ), + ], + ), + ); + } +} + +// import 'package:flutter/material.dart'; + +// class MyWidget extends StatelessWidget { +// @override +// Widget build(BuildContext context) { +// return MaterialApp( +// home: Scaffold( +// appBar: AppBar( +// title: Text('Positioned Offset Example'), +// ), +// body: Center( +// child: Stack( +// fit: StackFit.expand, +// children: [ +// Container( +// color: Colors.blue.withOpacity(0.5), +// ), +// LayoutBuilder( +// builder: (BuildContext context, BoxConstraints constraints) { +// return _CustomPositionedWidget(constraints.maxWidth); +// }, +// ), +// ], +// ), +// ), +// ), +// ); +// } +// } + +// class _CustomPositionedWidget extends StatelessWidget { +// final double maxWidth; + +// _CustomPositionedWidget(this.maxWidth); + +// @override +// Widget build(BuildContext context) { +// return Positioned( +// top: 100, +// left: maxWidth * 0.5, +// child: Container( +// width: maxWidth, +// height: 100, +// color: Colors.red, +// ), +// ); +// } +// } + +// void main() { +// runApp(MyWidget()); +// } \ No newline at end of file From 6bf9d66465b3036f7421e48f8174ff807a49ad34 Mon Sep 17 00:00:00 2001 From: hkaikai <617760820@qq.com> Date: Mon, 30 Sep 2024 13:09:08 +0800 Subject: [PATCH 07/46] =?UTF-8?q?=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../lib/src/components/rate/td_rate.dart | 23 +++-- .../lib/src/components/rate/td_rate_tips.dart | 89 ++++++------------- 2 files changed, 47 insertions(+), 65 deletions(-) diff --git a/tdesign-component/lib/src/components/rate/td_rate.dart b/tdesign-component/lib/src/components/rate/td_rate.dart index 6fd85e71e..9dc80780c 100644 --- a/tdesign-component/lib/src/components/rate/td_rate.dart +++ b/tdesign-component/lib/src/components/rate/td_rate.dart @@ -116,6 +116,9 @@ class _TDRateState extends State { /// 当前选中的评分宽度 var _rateWidth = 0.0; + /// 是否点击,否则是滑动 + var _isClick = true; + @override void initState() { super.initState(); @@ -152,17 +155,18 @@ class _TDRateState extends State { crossAxisAlignment: widget.crossAxisAlignment ?? CrossAxisAlignment.center, children: [ Listener( - behavior: HitTestBehavior.opaque, + // behavior: HitTestBehavior.opaque, + onPointerDown: (event) { + _isClick = true; + }, onPointerMove: (details) { + _isClick = false; _changeSelect(details.position); }, onPointerUp: (details) { _changeSelect(details.position); _hideTip(); }, - onPointerCancel: (details) { - _hideTip(); - }, child: Row( children: List.generate(widget.count ?? 5, (index) { final isLast = index == (widget.count ?? 5) - 1; @@ -213,6 +217,7 @@ class _TDRateState extends State { icon: _getIcon(isActive: true), size: widget.size, getIconColor: _getIconColor, + isClick: _isClick, withCall: (width) { if (_tipWidth != width) { setState(() { @@ -220,6 +225,13 @@ class _TDRateState extends State { }); } }, + tipClick: (value) { + setState(() { + _showTip = false; + _isClick = true; + _activeValue = value; + }); + }, ), ), ], @@ -271,10 +283,11 @@ class _TDRateState extends State { void _hideTip() { _hideTipTimer?.cancel(); _hideTipTimer = Timer( - const Duration(seconds: 1), + Duration(seconds: _isClick && widget.allowHalf == true ? 3 : 1), () { setState(() { _showTip = false; + _isClick = true; }); }, ); diff --git a/tdesign-component/lib/src/components/rate/td_rate_tips.dart b/tdesign-component/lib/src/components/rate/td_rate_tips.dart index 6dd5b5000..42e400af8 100644 --- a/tdesign-component/lib/src/components/rate/td_rate_tips.dart +++ b/tdesign-component/lib/src/components/rate/td_rate_tips.dart @@ -13,6 +13,8 @@ class TDRateTips extends StatelessWidget { this.size, required this.getIconColor, required this.withCall, + required this.isClick, + required this.tipClick, }) : super(key: key); final bool? allowHalf; @@ -22,6 +24,8 @@ class TDRateTips extends StatelessWidget { final double? size; final Color Function({double? value, bool? isActive}) getIconColor; final void Function(double width) withCall; + final bool isClick; + final void Function(double value) tipClick; @override Widget build(BuildContext context) { @@ -59,11 +63,18 @@ class TDRateTips extends StatelessWidget { padding: EdgeInsets.all(TDTheme.of(context).spacer4), child: Row( children: [ + // GestureDetector( + // onTap: () { + // if (allowHalf == true && isClick) { + // tipClick(index + 0.5); + // } + // }, + // child: Container( decoration: BoxDecoration( - color: (allowHalf ?? false) == false || index + 0.5 != activeValue - ? TDTheme.of(context).whiteColor1 - : TDTheme.of(context).grayColor3, + color: allowHalf == true && index + 0.5 == activeValue && isClick + ? TDTheme.of(context).grayColor3 + : TDTheme.of(context).whiteColor1, borderRadius: BorderRadius.circular(TDTheme.of(context).radiusSmall), ), padding: EdgeInsets.only(left: TDTheme.of(context).spacer4, right: TDTheme.of(context).spacer4), @@ -89,7 +100,9 @@ class TDRateTips extends StatelessWidget { child: Icon( icon, size: size ?? 24, - color: allowHalf == true ? getIconColor(isActive: false) : getIconColor(isActive: true), + color: allowHalf == true + ? (isClick ? getIconColor(isActive: false) : getIconColor(value: index + 1)) + : getIconColor(isActive: true), ), ), ), @@ -97,7 +110,7 @@ class TDRateTips extends StatelessWidget { ), Center( child: TDText( - allowHalf == true ? '${index + 0.5}' : '${index + 1}', + allowHalf == true ? (isClick ? '${index + 0.5}' : '${activeValue}') : '${index + 1}', font: TDTheme.of(context).fontBodySmall, textColor: TDTheme.of(context).fontGyColor1, ), @@ -105,8 +118,16 @@ class TDRateTips extends StatelessWidget { ], ), ), - if (allowHalf == true) SizedBox(width: TDTheme.of(context).spacer4), - if (allowHalf == true) + // ), + if (allowHalf == true && isClick) SizedBox(width: TDTheme.of(context).spacer4), + if (allowHalf == true && isClick) + // GestureDetector( + // onTap: () { + // if (allowHalf == true && isClick) { + // tipClick(index + 1.0); + // } + // }, + // child: Container( decoration: BoxDecoration( color: index + 1 != activeValue ? TDTheme.of(context).whiteColor1 : TDTheme.of(context).grayColor3, @@ -130,61 +151,9 @@ class TDRateTips extends StatelessWidget { ], ), ), + // ), ], ), ); } } - -// import 'package:flutter/material.dart'; - -// class MyWidget extends StatelessWidget { -// @override -// Widget build(BuildContext context) { -// return MaterialApp( -// home: Scaffold( -// appBar: AppBar( -// title: Text('Positioned Offset Example'), -// ), -// body: Center( -// child: Stack( -// fit: StackFit.expand, -// children: [ -// Container( -// color: Colors.blue.withOpacity(0.5), -// ), -// LayoutBuilder( -// builder: (BuildContext context, BoxConstraints constraints) { -// return _CustomPositionedWidget(constraints.maxWidth); -// }, -// ), -// ], -// ), -// ), -// ), -// ); -// } -// } - -// class _CustomPositionedWidget extends StatelessWidget { -// final double maxWidth; - -// _CustomPositionedWidget(this.maxWidth); - -// @override -// Widget build(BuildContext context) { -// return Positioned( -// top: 100, -// left: maxWidth * 0.5, -// child: Container( -// width: maxWidth, -// height: 100, -// color: Colors.red, -// ), -// ); -// } -// } - -// void main() { -// runApp(MyWidget()); -// } \ No newline at end of file From eb280e58b57be69a7524642098f719a9351e3db8 Mon Sep 17 00:00:00 2001 From: Simon_Wzy <1691663479@qq.com> Date: Mon, 30 Sep 2024 14:13:10 +0800 Subject: [PATCH 08/46] =?UTF-8?q?=E5=88=9D=E6=AD=A5=E5=AE=9E=E7=8E=B0?= =?UTF-8?q?=E4=BA=86=E5=9B=9B=E4=B8=AA=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../example/android/build.gradle | 2 +- .../example/lib/page/td_form_page.dart | 107 +++++++++----- .../lib/src/components/form/td_form_item.dart | 139 +++++++++++++----- tdesign-component/pubspec.lock | 104 +++++-------- 4 files changed, 209 insertions(+), 143 deletions(-) diff --git a/tdesign-component/example/android/build.gradle b/tdesign-component/example/android/build.gradle index 38f569bae..53e7c1ac5 100644 --- a/tdesign-component/example/android/build.gradle +++ b/tdesign-component/example/android/build.gradle @@ -1,5 +1,5 @@ buildscript { - ext.kotlin_version = '1.6.21' + ext.kotlin_version = '1.9.0' ext { diff --git a/tdesign-component/example/lib/page/td_form_page.dart b/tdesign-component/example/lib/page/td_form_page.dart index 38c1bf07b..6238935ee 100644 --- a/tdesign-component/example/lib/page/td_form_page.dart +++ b/tdesign-component/example/lib/page/td_form_page.dart @@ -7,62 +7,91 @@ import '../../base/example_widget.dart'; class TDFormPage extends StatelessWidget { const TDFormPage({Key? key}) : super(key: key); - final exampleTxt = '文本Text'; - @override Widget build(BuildContext context) { // debugPaintBaselinesEnabled = true; return ExamplePage( - padding: const EdgeInsets.all(8), title: tdTitle(context), - exampleCodeGroup: 'text', + exampleCodeGroup: 'form', + backgroundColor: const Color(0xfff6f6f6), children: [ - ExampleModule(title: '使用示例', children: [ - ExampleItem(desc: '自定义内部padding:', builder: _buildUserNameItem), + ExampleModule(title: '禁用态开关', children: [ + ExampleItem(desc: '基础开关', builder: _buildSwitchWithBase), + ]), + ExampleModule(title: 'Form', children: [ + ExampleItem(desc: '', builder: _buildUserNameItem), + ExampleItem(desc: '', builder: _buildPassWordItem), + ExampleItem(desc: '', builder: _buildhorizontalRadiosItem), ]), ], ); } } - @Demo(group: 'form') Widget _buildUserNameItem(BuildContext buildContext) { - return TDFormItem(); + return TDFormItem(label:'用户名', + name: 'name', + help:'请输入用户名'); +} + +@Demo(group: 'form') +Widget _buildPassWordItem(BuildContext buildContext) { + return TDFormItem(label:'密码', + name: 'password', + help:'请输入密码'); } -// /// 自定义控件,内部的context可拿到外部TDTextConfiguration的配置信息 -// class CustomPaddingText extends StatelessWidget { -// const CustomPaddingText({Key? key}) : super(key: key); +@Demo(group: 'form') +Widget _buildhorizontalRadiosItem(BuildContext buildContext) { -// @override -// Widget build(BuildContext context) { -// return Column( -// mainAxisSize: MainAxisSize.min, -// children: [ -// TDText( -// '中华人民共和国腾讯科技fgjpqy', -// forceVerticalCenter: true, -// backgroundColor: TDTheme.of(context).brandFocusColor, -// ), -// TDText( -// 'English', -// font: TDTheme.of(context).fontHeadlineLarge, -// forceVerticalCenter: true, -// backgroundColor: TDTheme.of(context).brandFocusColor, -// ), -// ], -// ); -// } -// } + return TDFormItem(label:'性别', + name: 'gender', + ); +} -// /// 重写内部padding方法 -// class CustomTextPaddingConfig extends TDTextPaddingConfig { -// @override -// EdgeInsetsGeometry getPadding(String? data, double fontSize, double height) { -// var supperPadding = super.getPadding(data, fontSize, height); -// return EdgeInsets.only(left: 30, top: supperPadding.vertical.toDouble()); -// } -// } +@Demo(group: 'switch') +Widget _buildSwitchWithBase(BuildContext context) { + return _buildItem( + context, + const TDSwitch(), + title: '禁用态', + ); +} + +/// 每一项的封装 +@Demo(group: 'switch') +Widget _buildItem(BuildContext context, Widget switchItem, + {String? title, String? desc}) { + final theme = TDTheme.of(context); + Widget current = Row( + children: [ + Expanded( + child: TDText( + title ?? '', + textColor: theme.fontGyColor1, + )), + TDText( + desc ?? '', + textColor: theme.grayColor6, + ), + SizedBox(child: switchItem) + ], + ); + current = Padding( + padding: const EdgeInsets.symmetric(vertical: 8), + child: SizedBox( + child: Container( + child: Padding( + padding: const EdgeInsets.symmetric(horizontal: 16.0), + child: current, + ), + color: Colors.white, + ), + height: 56, + ), + ); + return Column(mainAxisSize: MainAxisSize.min, children: [current]); +} diff --git a/tdesign-component/lib/src/components/form/td_form_item.dart b/tdesign-component/lib/src/components/form/td_form_item.dart index d23eb5859..4613cb456 100644 --- a/tdesign-component/lib/src/components/form/td_form_item.dart +++ b/tdesign-component/lib/src/components/form/td_form_item.dart @@ -1,8 +1,9 @@ import 'package:flutter/material.dart'; +import '../../../tdesign_flutter.dart'; +import '../input/td_input.dart'; -class TDFormItem extends StatelessWidget { - const TDFormItem({ - Key? key, +class TDFormItem extends StatefulWidget { + TDFormItem({ this.label, this.name, this.arrow = false, @@ -13,8 +14,12 @@ class TDFormItem extends StatelessWidget { this.requiredMark, this.rules, this.showErrowMessage, + Key? key, }) : super(key: key); + /// 表格内标签 内容填充 + final String? label; + /// 表单内容对齐方式: /// 左对齐、右对齐 /// 可选项:left/right @@ -23,11 +28,9 @@ class TDFormItem extends StatelessWidget { /// 是否显示右箭头 final bool? arrow; - /// 表单说明内容 ???? - final help; - - /// 表格内标签 内容填充 - final String? label; + /// 表单说明内容 + /// 表单的默认输入字符 + final String? help; /// 表单字段标签对齐方式: /// 左对齐、右对齐、顶部对齐 @@ -53,41 +56,99 @@ class TDFormItem extends StatelessWidget { /// 优先级高于 Form.showErrowMessage final bool? showErrowMessage; + @override + _TDFormItemState createState() => _TDFormItemState(); +} + +class _TDFormItemState extends State { + /// 实现密码右侧的可见按钮 + bool browseOn = false; + + /// 实现输入框的 controller + var controller = []; + + @override + void initState() { + for (var i = 0; i < 10; i++) { + controller.add(TextEditingController()); + } + super.initState(); + } + @override Widget build(BuildContext context) { - return Row( - mainAxisAlignment: contentAlign == 'right' - ? MainAxisAlignment.end - : MainAxisAlignment.start, - children: [ - // 标签 - Container( - width: labelWidth != null ? double.parse(labelWidth!) : null, - alignment: labelAlign == 'right' - ? Alignment.centerRight - : labelAlign == 'top' - ? Alignment.topLeft - : Alignment.centerLeft, - child: Text( - label ?? '', - style: TextStyle( - fontWeight: - requiredMark == true ? FontWeight.bold : FontWeight.normal, - ), + if (widget.name == 'name') { + return Column( + children: [ + TDInput( + leftLabel: widget.label, + required: true, + controller: controller[0], + backgroundColor: Colors.white, + hintText: widget.help, ), - ), - const SizedBox(width: 8), // 标签与输入框的间距 - // 输入框 - Expanded( - child: TextFormField( - decoration: InputDecoration( - hintText: help, - suffixIcon: arrow == true ? Icon(Icons.arrow_forward) : null, + const SizedBox( + height: 16, + ), + ], + ); + } else if (widget.name == 'password') { + return Column( + children: [ + TDInput( + type: TDInputType.normal, + controller: controller[1], + obscureText: !browseOn, + leftLabel: widget.label, + hintText: widget.help, + backgroundColor: Colors.white, + rightBtn: browseOn + ? Icon( + TDIcons.browse, + color: TDTheme.of(context).fontGyColor3, + ) + : Icon( + TDIcons.browse_off, + color: TDTheme.of(context).fontGyColor3, ), - // 可添加更多属性,如 validator 等 + onBtnTap: () { + setState(() { + browseOn = !browseOn; + }); + }, + needClear: false, + ), + const SizedBox( + height: 16, + ), + ], + ); + } else if(widget.name == 'gender'){ + return TDRadioGroup( + selectId: 'index:1', + direction: Axis.horizontal, + directionalTdRadios: const [ + TDRadio( + id: '0', + title: '男', + radioStyle: TDRadioStyle.circle, + showDivider: false, + ), + TDRadio( + id: '1', + title: '女', + radioStyle: TDRadioStyle.circle, + showDivider: false, + ), + TDRadio( + id: '2', + title: '保密', + radioStyle: TDRadioStyle.circle, + showDivider: false, ), - ), - ], - ); + ], + ); + } + return Column(); } } diff --git a/tdesign-component/pubspec.lock b/tdesign-component/pubspec.lock index 9ff5c7995..134be1f97 100644 --- a/tdesign-component/pubspec.lock +++ b/tdesign-component/pubspec.lock @@ -5,18 +5,18 @@ packages: dependency: transitive description: name: _fe_analyzer_shared - sha256: "0b2f2bd91ba804e53a61d757b986f89f1f9eaed5b11e4b2f5a2468d86d6c9fc7" + sha256: eb376e9acf6938204f90eb3b1f00b578640d3188b4c8a8ec054f9f479af8d051 url: "https://pub.dev" source: hosted - version: "67.0.0" + version: "64.0.0" analyzer: dependency: transitive description: name: analyzer - sha256: "37577842a27e4338429a1cbc32679d508836510b056f1eedf0c8d20e39c1383d" + sha256: "69f54f967773f6c26c7dcb13e93d7ccee8b17a641689da39e878d5cf13b06893" url: "https://pub.dev" source: hosted - version: "6.4.1" + version: "6.2.0" args: dependency: transitive description: @@ -61,10 +61,10 @@ packages: dependency: transitive description: name: collection - sha256: ee67cb0715911d28db6bf4af1026078bd6f0128b07a5f66fb2ed94ec6783c09a + sha256: "4a07be6cb69c84d677a6c3096fcf960cc3285a8330b4603e0d463d15d9bd934c" url: "https://pub.dev" source: hosted - version: "1.18.0" + version: "1.17.1" color: dependency: transitive description: @@ -85,10 +85,10 @@ packages: dependency: transitive description: name: crypto - sha256: ec30d999af904f33454ba22ed9a86162b35e52b44ac4807d1d93c288041d7d27 + sha256: ff625774173754681d66daaf4a448684fb04b78f902da9cb3d308c19cc5e8bab url: "https://pub.dev" source: hosted - version: "3.0.5" + version: "3.0.3" dart_style: dependency: transitive description: @@ -203,38 +203,22 @@ packages: url: "https://pub.dev" source: hosted version: "2.1.3" - json_annotation: - dependency: transitive - description: - name: json_annotation - sha256: "1ce844379ca14835a50d2f019a3099f419082cfdd231cd86a142af94dd5c6bb1" - url: "https://pub.dev" - source: hosted - version: "4.9.0" - leak_tracker: - dependency: transitive - description: - name: leak_tracker - sha256: "7f0df31977cb2c0b88585095d168e689669a2cc9b97c309665e3386f3e9d341a" - url: "https://pub.dev" - source: hosted - version: "10.0.4" - leak_tracker_flutter_testing: + js: dependency: transitive description: - name: leak_tracker_flutter_testing - sha256: "06e98f569d004c1315b991ded39924b21af84cf14cc94791b8aea337d25b57f8" + name: js + sha256: f2c445dce49627136094980615a031419f7f3eb393237e4ecd97ac15dea343f3 url: "https://pub.dev" source: hosted - version: "3.0.3" - leak_tracker_testing: + version: "0.6.7" + json_annotation: dependency: transitive description: - name: leak_tracker_testing - sha256: "6ba465d5d76e67ddf503e1161d1f4a6bc42306f9d66ca1e8f079a47290fb06d3" + name: json_annotation + sha256: "1ce844379ca14835a50d2f019a3099f419082cfdd231cd86a142af94dd5c6bb1" url: "https://pub.dev" source: hosted - version: "3.0.1" + version: "4.9.0" lints: dependency: transitive description: @@ -247,34 +231,34 @@ packages: dependency: transitive description: name: matcher - sha256: d2323aa2060500f906aa31a895b4030b6da3ebdcc5619d14ce1aada65cd161cb + sha256: "6501fbd55da300384b768785b83e5ce66991266cec21af89ab9ae7f5ce1c4cbb" url: "https://pub.dev" source: hosted - version: "0.12.16+1" + version: "0.12.15" material_color_utilities: dependency: transitive description: name: material_color_utilities - sha256: "0e0a020085b65b6083975e499759762399b4475f766c21668c4ecca34ea74e5a" + sha256: d92141dc6fe1dad30722f9aa826c7fbc896d021d792f80678280601aff8cf724 url: "https://pub.dev" source: hosted - version: "0.8.0" + version: "0.2.0" meta: dependency: transitive description: name: meta - sha256: "7687075e408b093f36e6bbf6c91878cc0d4cd10f409506f7bc996f68220b9136" + sha256: "3c74dbf8763d36539f114c799d8a2d87343b5067e9d796ca22b5eb8437090ee3" url: "https://pub.dev" source: hosted - version: "1.12.0" + version: "1.9.1" mime: dependency: transitive description: name: mime - sha256: "801fd0b26f14a4a58ccb09d5892c3fbdeff209594300a542492cf13fba9d247a" + sha256: e4ff8e8564c03f255408decd16e7899da1733852a9110a58fe6d1b817684a63e url: "https://pub.dev" source: hosted - version: "1.0.6" + version: "1.0.4" package_config: dependency: transitive description: @@ -287,10 +271,10 @@ packages: dependency: transitive description: name: path - sha256: "087ce49c3f0dc39180befefc60fdb4acd8f8620e5682fe2476afd0b3688bb4af" + sha256: "8829d8a55c13fc0e37127c29fedf290c102f4e40ae94ada574091fe0ff96c917" url: "https://pub.dev" source: hosted - version: "1.9.0" + version: "1.8.3" path_parsing: dependency: transitive description: @@ -303,10 +287,10 @@ packages: dependency: transitive description: name: petitparser - sha256: c15605cd28af66339f8eb6fbe0e541bfe2d1b72d5825efc6598f3e0a31b9ad27 + sha256: cb3798bef7fc021ac45b308f4b51208a152792445cce0448c9a4ba5879dd8750 url: "https://pub.dev" source: hosted - version: "6.0.2" + version: "5.4.0" pub_semver: dependency: transitive description: @@ -324,26 +308,26 @@ packages: dependency: transitive description: name: source_span - sha256: "53e943d4206a5e30df338fd4c6e7a077e02254531b138a15aec3bd143c1a8b3c" + sha256: dd904f795d4b4f3b870833847c461801f6750a9fa8e61ea5ac53f9422b31f250 url: "https://pub.dev" source: hosted - version: "1.10.0" + version: "1.9.1" stack_trace: dependency: transitive description: name: stack_trace - sha256: "73713990125a6d93122541237550ee3352a2d84baad52d375a4cad2eb9b7ce0b" + sha256: c3c7d8edb15bee7f0f74debd4b9c5f3c2ea86766fe4178eb2a18eb30a0bdaed5 url: "https://pub.dev" source: hosted - version: "1.11.1" + version: "1.11.0" stream_channel: dependency: transitive description: name: stream_channel - sha256: ba2aa5d8cc609d96bbb2899c28934f9e1af5cddbd60a827822ea467161eb54e7 + sha256: "83615bee9045c1d322bbbd1ba209b7a749c2cbcdcb3fdd1df8eb488b3279c1c8" url: "https://pub.dev" source: hosted - version: "2.1.2" + version: "2.1.1" string_scanner: dependency: transitive description: @@ -364,10 +348,10 @@ packages: dependency: transitive description: name: test_api - sha256: "9955ae474176f7ac8ee4e989dadfb411a58c30415bcfb648fa04b2b8a03afa7f" + sha256: eb6ac1540b26de412b3403a163d919ba86f6a973fe6cc50ae3541b80092fdcfb url: "https://pub.dev" source: hosted - version: "0.7.0" + version: "0.5.1" time: dependency: transitive description: @@ -408,14 +392,6 @@ packages: url: "https://pub.dev" source: hosted version: "2.1.4" - vm_service: - dependency: transitive - description: - name: vm_service - sha256: "3923c89304b715fb1eb6423f017651664a03bf5f4b29983627c4da791f74a4ec" - url: "https://pub.dev" - source: hosted - version: "14.2.1" watcher: dependency: transitive description: @@ -428,10 +404,10 @@ packages: dependency: transitive description: name: xml - sha256: b015a8ad1c488f66851d762d3090a21c600e479dc75e68328c52774040cf9226 + sha256: "5bc72e1e45e941d825fd7468b9b4cc3b9327942649aeb6fc5cdbf135f0a86e84" url: "https://pub.dev" source: hosted - version: "6.5.0" + version: "6.3.0" yaml: dependency: transitive description: @@ -441,5 +417,5 @@ packages: source: hosted version: "3.1.2" sdks: - dart: ">=3.4.0 <4.0.0" - flutter: ">=3.18.0-18.0.pre.54" + dart: ">=3.0.0 <4.0.0" + flutter: ">=3.7.0" From 4f870d6d150931353318c6756f17de84e57601f0 Mon Sep 17 00:00:00 2001 From: Simon_Wzy <1691663479@qq.com> Date: Mon, 30 Sep 2024 19:37:10 +0800 Subject: [PATCH 09/46] =?UTF-8?q?=E5=88=9D=E6=AD=A5=E5=AE=9E=E7=8E=B0?= =?UTF-8?q?=E4=BA=86=E8=AE=A1=E6=95=B0=E5=99=A8=E5=92=8C=E5=8D=8A=E4=B8=AA?= =?UTF-8?q?=E6=97=A5=E6=9C=9F=E9=80=89=E6=8B=A9=E5=99=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../example/lib/page/td_form_page.dart | 168 +++++++++++------- .../lib/src/components/form/td_form_item.dart | 105 +++++++++-- 2 files changed, 197 insertions(+), 76 deletions(-) diff --git a/tdesign-component/example/lib/page/td_form_page.dart b/tdesign-component/example/lib/page/td_form_page.dart index 6238935ee..f55f48b98 100644 --- a/tdesign-component/example/lib/page/td_form_page.dart +++ b/tdesign-component/example/lib/page/td_form_page.dart @@ -4,14 +4,30 @@ import 'package:tdesign_flutter/tdesign_flutter.dart'; import '../../annotation/demo.dart'; import '../../base/example_widget.dart'; -class TDFormPage extends StatelessWidget { +class TDFormPage extends StatefulWidget { const TDFormPage({Key? key}) : super(key: key); + @override + _TDFormPageState createState() => _TDFormPageState(); +} + +class _TDFormPageState extends State { + + var controller = []; + String selected_1 = ''; + + @override + void initState() { + for (var i = 0; i < 28; i++) { + controller.add(TextEditingController()); + } + super.initState(); + } + @override Widget build(BuildContext context) { - // debugPaintBaselinesEnabled = true; return ExamplePage( - title: tdTitle(context), + title: tdTitle(), exampleCodeGroup: 'form', backgroundColor: const Color(0xfff6f6f6), children: [ @@ -22,76 +38,104 @@ class TDFormPage extends StatelessWidget { ExampleItem(desc: '', builder: _buildUserNameItem), ExampleItem(desc: '', builder: _buildPassWordItem), ExampleItem(desc: '', builder: _buildhorizontalRadiosItem), + ExampleItem(desc: '', builder: _buildDateItem), + ExampleItem(desc: '', builder: _buildStepperItem), ]), ], ); } -} -@Demo(group: 'form') -Widget _buildUserNameItem(BuildContext buildContext) { - - return TDFormItem(label:'用户名', - name: 'name', - help:'请输入用户名'); -} - -@Demo(group: 'form') -Widget _buildPassWordItem(BuildContext buildContext) { + @Demo(group: 'form') + Widget _buildUserNameItem(BuildContext buildContext) { + return TDFormItem( + label: '用户名', + name: 'name', + help: '请输入用户名', + controller: controller[0], + ); + } - return TDFormItem(label:'密码', + @Demo(group: 'form') + Widget _buildPassWordItem(BuildContext buildContext) { + return TDFormItem( + label: '密码', name: 'password', - help:'请输入密码'); -} - -@Demo(group: 'form') -Widget _buildhorizontalRadiosItem(BuildContext buildContext) { + help: '请输入密码', + controller: controller[1], + ); + } - return TDFormItem(label:'性别', + @Demo(group: 'form') + Widget _buildhorizontalRadiosItem(BuildContext buildContext) { + return TDFormItem( + label: '性别', name: 'gender', - ); -} + /// 扩展一下数量和选项内容 + ); + } -@Demo(group: 'switch') -Widget _buildSwitchWithBase(BuildContext context) { - return _buildItem( - context, - const TDSwitch(), - title: '禁用态', - ); -} + @Demo(group: 'form') + Widget _buildDateItem(BuildContext buildContext){ + return TDFormItem( + label: '生日', + name: 'date', + /// 引入需要的日期数据 + select: selected_1, + ); + } -/// 每一项的封装 -@Demo(group: 'switch') -Widget _buildItem(BuildContext context, Widget switchItem, - {String? title, String? desc}) { - final theme = TDTheme.of(context); - Widget current = Row( - children: [ - Expanded( - child: TDText( - title ?? '', - textColor: theme.fontGyColor1, - )), - TDText( - desc ?? '', - textColor: theme.grayColor6, - ), - SizedBox(child: switchItem) - ], - ); - current = Padding( - padding: const EdgeInsets.symmetric(vertical: 8), - child: SizedBox( - child: Container( - child: Padding( - padding: const EdgeInsets.symmetric(horizontal: 16.0), - child: current, + @Demo(group: 'form') + Widget _buildStepperItem(BuildContext buildContext){ + return TDFormItem( + label: '年限', + name: 'age', + /// 为 TDStepper 预留其他设置 + ); + } + + @Demo(group: 'switch') + Widget _buildSwitchWithBase(BuildContext context) { + return _buildItem( + context, + const TDSwitch(), + title: '禁用态', + ); + } + + /// 每一项的封装 + @Demo(group: 'switch') + Widget _buildItem(BuildContext context, Widget switchItem, + {String? title, String? desc}) { + final theme = TDTheme.of(context); + Widget current = Row( + children: [ + Expanded( + child: TDText( + title ?? '', + textColor: theme.fontGyColor1, + )), + TDText( + desc ?? '', + textColor: theme.grayColor6, + ), + SizedBox(child: switchItem) + ], + ); + current = Padding( + padding: const EdgeInsets.symmetric(vertical: 8), + child: SizedBox( + child: Container( + child: Padding( + padding: const EdgeInsets.symmetric(horizontal: 16.0), + child: current, + ), + color: Colors.white, ), - color: Colors.white, + height: 56, ), - height: 56, - ), - ); - return Column(mainAxisSize: MainAxisSize.min, children: [current]); + ); + return Column(mainAxisSize: MainAxisSize.min, children: [current]); + } } + + diff --git a/tdesign-component/lib/src/components/form/td_form_item.dart b/tdesign-component/lib/src/components/form/td_form_item.dart index 4613cb456..a9e94c9c2 100644 --- a/tdesign-component/lib/src/components/form/td_form_item.dart +++ b/tdesign-component/lib/src/components/form/td_form_item.dart @@ -4,6 +4,8 @@ import '../input/td_input.dart'; class TDFormItem extends StatefulWidget { TDFormItem({ + this.controller, + this.select = '', this.label, this.name, this.arrow = false, @@ -45,11 +47,17 @@ class TDFormItem extends StatefulWidget { /// 表格标识 final String? name; + /// 表格的 controller + var controller; + + /// 日期选择需要展示的内容 + String select; + /// 是否显示必填符号 (*) /// 优先级高于 Form.requiredMark final bool? requiredMark; - /// 表单字段校验规则 ??? + /// 表单字段校验规则 final List? rules; /// 校验不通过时,是否显示错误提示信息 @@ -60,21 +68,49 @@ class TDFormItem extends StatefulWidget { _TDFormItemState createState() => _TDFormItemState(); } +Widget buildSelectRow(BuildContext context, String output, String title) { + return Container( + color: TDTheme.of(context).whiteColor1, + height: 56, + child: Stack( + alignment: Alignment.bottomCenter, + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Padding( + padding: const EdgeInsets.only(left: 16, top: 16, bottom: 16), + child: TDText(title, font: TDTheme.of(context).fontBodyLarge,), + ), + Padding( + padding: const EdgeInsets.only(right: 16), + child: Row( + children: [ + TDText( + output, + font: TDTheme.of(context).fontBodyLarge, + textColor: TDTheme.of(context).fontGyColor3.withOpacity(0.4),), + Padding( + padding: const EdgeInsets.only(left: 2), + child: Icon( + TDIcons.chevron_right, + color: TDTheme.of(context).fontGyColor3.withOpacity(0.4),), + ), + ], + ), + ), + ], + ), + const TDDivider(margin: EdgeInsets.only(left: 16, ),) + ], + ), + ); +} + class _TDFormItemState extends State { /// 实现密码右侧的可见按钮 bool browseOn = false; - /// 实现输入框的 controller - var controller = []; - - @override - void initState() { - for (var i = 0; i < 10; i++) { - controller.add(TextEditingController()); - } - super.initState(); - } - @override Widget build(BuildContext context) { if (widget.name == 'name') { @@ -83,7 +119,7 @@ class _TDFormItemState extends State { TDInput( leftLabel: widget.label, required: true, - controller: controller[0], + controller: widget.controller, backgroundColor: Colors.white, hintText: widget.help, ), @@ -97,7 +133,7 @@ class _TDFormItemState extends State { children: [ TDInput( type: TDInputType.normal, - controller: controller[1], + controller: widget.controller, obscureText: !browseOn, leftLabel: widget.label, hintText: widget.help, @@ -148,7 +184,48 @@ class _TDFormItemState extends State { ), ], ); + } else if(widget.name == 'date'){ + return GestureDetector( + onTap: (){ + TDPicker.showDatePicker(context, title: '选择时间', + onConfirm: (selected) { + setState(() { + widget.select = '${selected['year'].toString().padLeft(4, '0')}-${selected['month'].toString().padLeft(2, '0')}-${selected['day'].toString().padLeft(2, '0')}'; + }); + Navigator.of(context).pop(); + }, + dateStart: [1999, 01, 01], + dateEnd: [2023, 12, 31], + initialDate: [2012, 1, 1]); + }, + child: buildSelectRow(context, widget.select, '选择时间'), + ); + }else if(widget.name == 'age'){ + final theme = TDTheme.of(context); + + return Container( + decoration: BoxDecoration( + color: theme.whiteColor1, + ), + child: Padding( + padding: const EdgeInsets.all(16), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, // 左右分布 + children: [ + TDText( + widget.label, // 左侧的文本 + style: TextStyle(fontSize: 16), // 可根据需要设置样式 + ), + TDStepper( + theme: TDStepperTheme.filled, // 右侧的步进器 + ), + ], + ), + ), + ); } + + return Column(); } } From 8881f8123fe546e32883b82c1346d6e3aecc93b7 Mon Sep 17 00:00:00 2001 From: Simon_Wzy <1691663479@qq.com> Date: Tue, 1 Oct 2024 09:43:18 +0800 Subject: [PATCH 10/46] =?UTF-8?q?=E5=88=9D=E6=AD=A5=E5=AE=9E=E7=8E=B0?= =?UTF-8?q?=E4=BA=86=E5=9E=82=E7=9B=B4=E5=A4=9A=E7=BA=A7=E8=81=94=E5=90=88?= =?UTF-8?q?=E9=80=89=E6=8B=A9=E5=99=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../example/lib/page/td_form_page.dart | 81 ++++++++++++++++++ .../lib/src/components/form/td_form_item.dart | 85 ++++++++++++++++++- 2 files changed, 164 insertions(+), 2 deletions(-) diff --git a/tdesign-component/example/lib/page/td_form_page.dart b/tdesign-component/example/lib/page/td_form_page.dart index f55f48b98..71b3b3431 100644 --- a/tdesign-component/example/lib/page/td_form_page.dart +++ b/tdesign-component/example/lib/page/td_form_page.dart @@ -15,6 +15,76 @@ class _TDFormPageState extends State { var controller = []; String selected_1 = ''; + List _data = [ + { + "label": '北京市', + "value": '110000', + "children": [ + { + "value": '110100', + "label": '北京市', + "children": [ + {"value": '110101', "label": '东城区'}, + {"value": '1101022', "label": '东区'}, + {"value": '110102', "label": '西城区'}, + {"value": '110105', "label": '朝阳区'}, + {"value": '110106', "label": '丰台区'}, + {"value": '110107', "label": '石景山区'}, + {"value": '110108', "label": '海淀区'}, + {"value": '110109', "label": '门头沟区'}, + ], + }, + ], + }, + { + "label": '天津市', + "value": '120000', + "children": [ + { + "value": '120100', + "label": '天津市', + "children": [ + { + "value": '120101', + "label": '和平区', + }, + { + "value": '120102', + "label": '河东区', + }, + { + "value": '120103', + "label": '河西区', + }, + { + "value": '120104', + "label": '南开区', + }, + { + "value": '120105', + "label": '河北区', + }, + { + "value": '120106', + "label": '红桥区', + }, + { + "value": '120110', + "label": '东丽区', + }, + { + "value": '120111', + "label": '西青区', + }, + { + "value": '120112', + "label": '津南区', + }, + ], + }, + ], + }, + ]; @override void initState() { @@ -39,6 +109,7 @@ class _TDFormPageState extends State { ExampleItem(desc: '', builder: _buildPassWordItem), ExampleItem(desc: '', builder: _buildhorizontalRadiosItem), ExampleItem(desc: '', builder: _buildDateItem), + ExampleItem(desc: '', builder: _buildCascaderItem), ExampleItem(desc: '', builder: _buildStepperItem), ]), ], @@ -84,6 +155,16 @@ class _TDFormPageState extends State { ); } + @Demo(group: 'form') + Widget _buildCascaderItem(BuildContext buildContext){ + return TDFormItem( + label: '籍贯', + name: 'local', + /// 引入需要的地点数据 + localData: _data, + ); + } + @Demo(group: 'form') Widget _buildStepperItem(BuildContext buildContext){ return TDFormItem( diff --git a/tdesign-component/lib/src/components/form/td_form_item.dart b/tdesign-component/lib/src/components/form/td_form_item.dart index a9e94c9c2..c726c636b 100644 --- a/tdesign-component/lib/src/components/form/td_form_item.dart +++ b/tdesign-component/lib/src/components/form/td_form_item.dart @@ -4,8 +4,10 @@ import '../input/td_input.dart'; class TDFormItem extends StatefulWidget { TDFormItem({ + /// 需要从 page 外部传入的参数 this.controller, this.select = '', + List? localData, this.label, this.name, this.arrow = false, @@ -17,7 +19,8 @@ class TDFormItem extends StatefulWidget { this.rules, this.showErrowMessage, Key? key, - }) : super(key: key); + }) : localData = localData ?? const [], + super(key: key); /// 表格内标签 内容填充 final String? label; @@ -53,6 +56,9 @@ class TDFormItem extends StatefulWidget { /// 日期选择需要展示的内容 String select; + /// 组相联选择器需要的数据 + final List localData; + /// 是否显示必填符号 (*) /// 优先级高于 Form.requiredMark final bool? requiredMark; @@ -111,6 +117,10 @@ class _TDFormItemState extends State { /// 实现密码右侧的可见按钮 bool browseOn = false; + /// 垂直联级选择器 + String? _initData; + String _selected_1 = ''; + @override Widget build(BuildContext context) { if (widget.name == 'name') { @@ -223,9 +233,80 @@ class _TDFormItemState extends State { ), ), ); + }else if(widget.name == 'local'){ + return GestureDetector( + onTap: () { + TDCascader.showMultiCascader(context, title: '选择地址', data: widget.localData, initialData: _initData, theme: 'step', + onChange: (List selectData) { + setState(() { + List result = []; + int len = selectData.length; + _initData = selectData[len - 1].value!; + selectData.forEach((element) { + result.add(element.label); + }); + _selected_1 = result.join('/'); + }); + }, onClose: () { + Navigator.of(context).pop(); + }); + }, + child: _buildSelectRow(context, _selected_1, '选择地区'), + ); } + return Column(); + } - return Column(); + Widget _buildSelectRow(BuildContext context, String output, String title) { + return Container( + color: TDTheme.of(context).whiteColor1, + height: 56, + child: Stack( + alignment: Alignment.bottomCenter, + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Padding( + padding: const EdgeInsets.only(left: 16, top: 16, bottom: 16), + child: TDText( + title, + font: TDTheme.of(context).fontBodyLarge, + ), + ), + Expanded( + child: Padding( + padding: const EdgeInsets.only(right: 16, left: 16), + child: Row( + children: [ + Expanded( + child: TDText( + output, + font: TDTheme.of(context).fontBodyLarge, + textColor: TDTheme.of(context).fontGyColor3.withOpacity(0.4), + maxLines: 1, + overflow: TextOverflow.ellipsis, + )), + Padding( + padding: const EdgeInsets.only(left: 2), + child: Icon( + TDIcons.chevron_right, + color: TDTheme.of(context).fontGyColor3.withOpacity(0.4), + ), + ), + ], + ), + )), + ], + ), + const TDDivider( + margin: EdgeInsets.only( + left: 16, + ), + ) + ], + ), + ); } } From f5101bc88f72687af71c35eee21bd61f32e4d40c Mon Sep 17 00:00:00 2001 From: Simon_Wzy <1691663479@qq.com> Date: Thu, 3 Oct 2024 19:29:50 +0800 Subject: [PATCH 11/46] =?UTF-8?q?=E5=88=9D=E6=AD=A5=E5=AE=9E=E7=8E=B0?= =?UTF-8?q?=E4=BA=86Form=E7=9A=84=E6=9E=84=E5=BB=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../example/lib/page/td_cell_page.dart | 46 +++- .../example/lib/page/td_form_page.dart | 204 ++++++++++------ .../lib/src/components/button/td_button.dart | 45 ++-- .../src/components/cell/td_cell_group.dart | 29 ++- .../lib/src/components/form/td_form.dart | 24 +- .../lib/src/components/form/td_form_item.dart | 220 +++++++++++------- 6 files changed, 376 insertions(+), 192 deletions(-) diff --git a/tdesign-component/example/lib/page/td_cell_page.dart b/tdesign-component/example/lib/page/td_cell_page.dart index 9ec21100d..0ae83a49d 100644 --- a/tdesign-component/example/lib/page/td_cell_page.dart +++ b/tdesign-component/example/lib/page/td_cell_page.dart @@ -72,8 +72,12 @@ Widget _buildSimple(BuildContext context) { cells: [ TDCell(arrow: true, title: '单行标题'), TDCell(arrow: true, title: '单行标题', required: true), - TDCell(arrow: true, title: '单行标题', noteWidget: TDBadge(TDBadgeType.message, count: '8')), - TDCell(arrow: false, title: '单行标题', rightIconWidget: TDSwitch(isOn: true)), + TDCell( + arrow: true, + title: '单行标题', + noteWidget: TDBadge(TDBadgeType.message, count: '8')), + TDCell( + arrow: false, title: '单行标题', rightIconWidget: TDSwitch(isOn: true)), TDCell(arrow: true, title: '单行标题', note: '辅助信息'), TDCell(arrow: true, title: '单行标题', leftIcon: TDIcons.lock_on), TDCell(arrow: false, title: '单行标题'), @@ -86,14 +90,36 @@ Widget _buildDesSimple(BuildContext context) { return const TDCellGroup( cells: [ TDCell(arrow: true, title: '单行标题', description: '一段很长很长的内容文字'), - TDCell(arrow: true, title: '单行标题', description: '一段很长很长的内容文字', required: true), TDCell( - arrow: true, title: '单行标题', description: '一段很长很长的内容文字', noteWidget: TDBadge(TDBadgeType.message, count: '8')), - TDCell(arrow: false, title: '单行标题', description: '一段很长很长的内容文字', rightIconWidget: TDSwitch(isOn: true)), - TDCell(arrow: true, title: '单行标题', description: '一段很长很长的内容文字', note: '辅助信息'), - TDCell(arrow: true, title: '单行标题', description: '一段很长很长的内容文字一段很长很长的内容文字一段很长很长的内', leftIcon: TDIcons.lock_on), - TDCell(arrow: false, title: '单行标题', description: '一段很长很长的内容文字一段很长很长的内容文字一段很长很长的内'), - TDCell(arrow: false, title: '多行高度不定,长文本自动换行,该选项的描述是一段很长的内容', description: '一段很长很长的内容文字一段很长很长的内容文字一段很长很长的内'), + arrow: true, + title: '单行标题', + description: '一段很长很长的内容文字', + required: true), + TDCell( + arrow: true, + title: '单行标题', + description: '一段很长很长的内容文字', + noteWidget: TDBadge(TDBadgeType.message, count: '8')), + TDCell( + arrow: false, + title: '单行标题', + description: '一段很长很长的内容文字', + rightIconWidget: TDSwitch(isOn: true)), + TDCell( + arrow: true, title: '单行标题', description: '一段很长很长的内容文字', note: '辅助信息'), + TDCell( + arrow: true, + title: '单行标题', + description: '一段很长很长的内容文字一段很长很长的内容文字一段很长很长的内', + leftIcon: TDIcons.lock_on), + TDCell( + arrow: false, + title: '单行标题', + description: '一段很长很长的内容文字一段很长很长的内容文字一段很长很长的内'), + TDCell( + arrow: false, + title: '多行高度不定,长文本自动换行,该选项的描述是一段很长的内容', + description: '一段很长很长的内容文字一段很长很长的内容文字一段很长很长的内'), TDCell( arrow: true, title: '多行带头像', @@ -150,4 +176,4 @@ Widget _buildCard(BuildContext context) { // TDCell(title: 'item', leftIcon: TDIcons.app), // ], // ); -// } \ No newline at end of file +// } diff --git a/tdesign-component/example/lib/page/td_form_page.dart b/tdesign-component/example/lib/page/td_form_page.dart index 71b3b3431..50ef3cab6 100644 --- a/tdesign-component/example/lib/page/td_form_page.dart +++ b/tdesign-component/example/lib/page/td_form_page.dart @@ -12,9 +12,16 @@ class TDFormPage extends StatefulWidget { } class _TDFormPageState extends State { - var controller = []; String selected_1 = ''; + + Color verticalTextColor = Colors.black; + Color horizontalTextColor = Colors.red; + Color verticalButtonColor = Colors.blueGrey; + Color horizontalButtonColor = Colors.blue; + + Map _radios = {"0": "男", "1": "女", "2": "保密"}; + List _data = [ { "label": '北京市', @@ -97,81 +104,138 @@ class _TDFormPageState extends State { @override Widget build(BuildContext context) { return ExamplePage( - title: tdTitle(), - exampleCodeGroup: 'form', - backgroundColor: const Color(0xfff6f6f6), - children: [ - ExampleModule(title: '禁用态开关', children: [ - ExampleItem(desc: '基础开关', builder: _buildSwitchWithBase), - ]), - ExampleModule(title: 'Form', children: [ - ExampleItem(desc: '', builder: _buildUserNameItem), - ExampleItem(desc: '', builder: _buildPassWordItem), - ExampleItem(desc: '', builder: _buildhorizontalRadiosItem), - ExampleItem(desc: '', builder: _buildDateItem), - ExampleItem(desc: '', builder: _buildCascaderItem), - ExampleItem(desc: '', builder: _buildStepperItem), - ]), - ], - ); + title: tdTitle(), + exampleCodeGroup: 'form', + desc: '基础表单', + backgroundColor: const Color(0xfff6f6f6), + children: [ + ExampleModule(title: '基础类型', children: [ + ExampleItem(desc: '基础表单', builder: _buildArrangementSwitch), + ExampleItem(desc: '', builder: _buildSwitchWithBase), + ExampleItem(builder: (BuildContext context) { + return CodeWrapper(builder: _buildForm); + }) + ]), + ]); } @Demo(group: 'form') - Widget _buildUserNameItem(BuildContext buildContext) { - return TDFormItem( - label: '用户名', - name: 'name', - help: '请输入用户名', - controller: controller[0], - ); - } + Widget _buildForm(BuildContext context) { + return TDForm(items: [ + TDFormItem( + label: '用户名', + name: 'name', + help: '请输入用户名', + controller: controller[0], + ), + TDFormItem( + label: '密码', + name: 'password', + help: '请输入密码', + controller: controller[1], + ), + TDFormItem( + label: '性别', + name: 'radios', - @Demo(group: 'form') - Widget _buildPassWordItem(BuildContext buildContext) { - return TDFormItem( - label: '密码', - name: 'password', - help: '请输入密码', - controller: controller[1], - ); - } + /// 扩展一下数量和选项内容 + radios: _radios, + ), + TDFormItem( + label: '生日', + name: 'date', - @Demo(group: 'form') - Widget _buildhorizontalRadiosItem(BuildContext buildContext) { - return TDFormItem( - label: '性别', - name: 'gender', - /// 扩展一下数量和选项内容 - ); - } + /// 引入需要的日期数据 + select: selected_1, + ), + TDFormItem( + label: '籍贯', + name: 'local', - @Demo(group: 'form') - Widget _buildDateItem(BuildContext buildContext){ - return TDFormItem( - label: '生日', - name: 'date', - /// 引入需要的日期数据 - select: selected_1, - ); - } + /// 引入需要的地点数据 + localData: _data, + ), + TDFormItem( + label: '年限', + name: 'age', - @Demo(group: 'form') - Widget _buildCascaderItem(BuildContext buildContext){ - return TDFormItem( - label: '籍贯', - name: 'local', - /// 引入需要的地点数据 - localData: _data, - ); + /// 为 TDStepper 预留其他设置 + ), + TDFormItem( + label: '个人简介', + name: 'textarea', + help: '请输入个人简介', + controller: controller[2], + + /// 为 TDTextarea 长文本其他参数做预留 API + maxLength: 500, + indicator: true, + ) + ]); } + /// 横 竖 排版模式切换 @Demo(group: 'form') - Widget _buildStepperItem(BuildContext buildContext){ - return TDFormItem( - label: '年限', - name: 'age', - /// 为 TDStepper 预留其他设置 - ); + Widget _buildArrangementSwitch(BuildContext buildContext) { + final theme = TDTheme.of(context); + return Container( + decoration: BoxDecoration( + color: theme.whiteColor1, + ), + child: Padding( + padding: const EdgeInsets.all(16), + child: Row( + children: [ + Expanded( + child: TDButton( + text: '水平排布', + shape: TDButtonShape.round, + style: + TDButtonStyle(backgroundColor: horizontalButtonColor), + textStyle: TextStyle( + fontWeight: FontWeight.w700, + color: horizontalTextColor, + ), + onTap: () { + setState(() { + print("____1"); + final currentVerticalColor = verticalButtonColor; + verticalButtonColor = horizontalButtonColor; + horizontalButtonColor = currentVerticalColor; + + final currentTextColor = verticalTextColor; + verticalTextColor = horizontalTextColor; + horizontalTextColor = currentTextColor; + }); + }, + ), + ), + SizedBox(width: 8), + Expanded( + child: TDButton( + text: '竖直排布', + shape: TDButtonShape.round, + style: TDButtonStyle(backgroundColor: verticalButtonColor), + textStyle: TextStyle( + fontWeight: FontWeight.w700, + color: verticalTextColor, + ), + onTap: () { + setState(() { + print("____2"); + final currentVerticalColor = verticalButtonColor; + verticalButtonColor = horizontalButtonColor; + horizontalButtonColor = currentVerticalColor; + + final currentTextColor = verticalTextColor; + verticalTextColor = horizontalTextColor; + horizontalTextColor = currentTextColor; + }); + }, + ), + ), + ], + ))); } @Demo(group: 'switch') @@ -192,9 +256,9 @@ class _TDFormPageState extends State { children: [ Expanded( child: TDText( - title ?? '', - textColor: theme.fontGyColor1, - )), + title ?? '', + textColor: theme.fontGyColor1, + )), TDText( desc ?? '', textColor: theme.grayColor6, @@ -218,5 +282,3 @@ class _TDFormPageState extends State { return Column(mainAxisSize: MainAxisSize.min, children: [current]); } } - - diff --git a/tdesign-component/lib/src/components/button/td_button.dart b/tdesign-component/lib/src/components/button/td_button.dart index db4070f6f..c7b1c3b67 100644 --- a/tdesign-component/lib/src/components/button/td_button.dart +++ b/tdesign-component/lib/src/components/button/td_button.dart @@ -121,14 +121,17 @@ class _TDButtonState extends State { double? _iconSize; _updateParams() async { - _buttonStatus = widget.disabled ? TDButtonStatus.disable : TDButtonStatus.defaultState; + _buttonStatus = + widget.disabled ? TDButtonStatus.disable : TDButtonStatus.defaultState; _innerDefaultStyle = widget.style; _innerActiveStyle = widget.activeStyle; _innerDisableStyle = widget.disableStyle; _width = _getWidth(); _height = _getHeight(); _margin = _getMargin(); - _alignment = widget.shape == TDButtonShape.filled || widget.isBlock ? Alignment.center : null; + _alignment = widget.shape == TDButtonShape.filled || widget.isBlock + ? Alignment.center + : null; if (widget.text != null) { _textStyle = widget.disabled ? widget.disableTextStyle : widget.textStyle; } @@ -187,7 +190,7 @@ class _TDButtonState extends State { }, onTapUp: (TapUpDetails details) { Future.delayed(const Duration(milliseconds: 100), () { - if (mounted&&!widget.disabled) { + if (mounted && !widget.disabled) { setState(() { _buttonStatus = TDButtonStatus.defaultState; }); @@ -277,13 +280,17 @@ class _TDButtonState extends State { Font _getTextFont() { switch (widget.size) { case TDButtonSize.large: - return TDTheme.of(context).fontMarkLarge ?? Font(size: 16, lineHeight: 24); + return TDTheme.of(context).fontMarkLarge ?? + Font(size: 16, lineHeight: 24); case TDButtonSize.medium: - return TDTheme.of(context).fontMarkLarge ?? Font(size: 16, lineHeight: 24); + return TDTheme.of(context).fontMarkLarge ?? + Font(size: 16, lineHeight: 24); case TDButtonSize.small: - return TDTheme.of(context).fontMarkMedium ?? Font(size: 14, lineHeight: 22); + return TDTheme.of(context).fontMarkMedium ?? + Font(size: 14, lineHeight: 22); case TDButtonSize.extraSmall: - return TDTheme.of(context).fontMarkMedium ?? Font(size: 14, lineHeight: 22); + return TDTheme.of(context).fontMarkMedium ?? + Font(size: 14, lineHeight: 22); } } @@ -291,7 +298,9 @@ class _TDButtonState extends State { if (widget.width != null) { return widget.width; } - if (!widget.isBlock && (widget.shape == TDButtonShape.square || widget.shape == TDButtonShape.circle)) { + if (!widget.isBlock && + (widget.shape == TDButtonShape.square || + widget.shape == TDButtonShape.circle)) { switch (widget.size) { case TDButtonSize.large: return 48; @@ -346,7 +355,8 @@ class _TDButtonState extends State { if (widget.padding != null) { return widget.padding; } - var equalSide = widget.shape == TDButtonShape.square || widget.shape == TDButtonShape.circle; + var equalSide = widget.shape == TDButtonShape.square || + widget.shape == TDButtonShape.circle; double horizontalPadding; double verticalPadding; @@ -379,7 +389,10 @@ class _TDButtonState extends State { } } return EdgeInsets.only( - left: horizontalPadding, right: horizontalPadding, bottom: verticalPadding, top: verticalPadding); + left: horizontalPadding, + right: horizontalPadding, + bottom: verticalPadding, + top: verticalPadding); } @override @@ -391,13 +404,17 @@ class _TDButtonState extends State { TDButtonStyle _generateInnerStyle() { switch (widget.type) { case TDButtonType.fill: - return TDButtonStyle.generateFillStyleByTheme(context, widget.theme, _buttonStatus); + return TDButtonStyle.generateFillStyleByTheme( + context, widget.theme, _buttonStatus); case TDButtonType.outline: - return TDButtonStyle.generateOutlineStyleByTheme(context, widget.theme, _buttonStatus); + return TDButtonStyle.generateOutlineStyleByTheme( + context, widget.theme, _buttonStatus); case TDButtonType.text: - return TDButtonStyle.generateTextStyleByTheme(context, widget.theme, _buttonStatus); + return TDButtonStyle.generateTextStyleByTheme( + context, widget.theme, _buttonStatus); case TDButtonType.ghost: - return TDButtonStyle.generateGhostStyleByTheme(context, widget.theme, _buttonStatus); + return TDButtonStyle.generateGhostStyleByTheme( + context, widget.theme, _buttonStatus); } } diff --git a/tdesign-component/lib/src/components/cell/td_cell_group.dart b/tdesign-component/lib/src/components/cell/td_cell_group.dart index 98454285e..758267658 100644 --- a/tdesign-component/lib/src/components/cell/td_cell_group.dart +++ b/tdesign-component/lib/src/components/cell/td_cell_group.dart @@ -3,7 +3,8 @@ import 'package:flutter/material.dart'; import '../../../tdesign_flutter.dart'; import 'td_cell_inherited.dart'; -typedef CellBuilder = Widget Function(BuildContext context, TDCell cell, int index); +typedef CellBuilder = Widget Function( + BuildContext context, TDCell cell, int index); enum TDCellGroupTheme { defaultTheme, cardTheme } @@ -76,25 +77,32 @@ class _TDCellGroupState extends State { top: TDTheme.of(context).spacer24, bottom: TDTheme.of(context).spacer8, ), - child: widget.titleWidget ?? TDText(widget.title!, style: style.groupTitleStyle), + child: widget.titleWidget ?? + TDText(widget.title!, style: style.groupTitleStyle), ), Flexible( child: Container( padding: widget.theme == TDCellGroupTheme.cardTheme ? EdgeInsets.only(left: spacer16, right: spacer16) : EdgeInsets.zero, - decoration: BoxDecoration(border: _getBordered(style), borderRadius: radius), + decoration: BoxDecoration( + border: _getBordered(style), borderRadius: radius), child: ClipRRect( borderRadius: radius, child: ListView.separated( padding: EdgeInsets.zero, shrinkWrap: widget.scrollable == false, // 设置为true以避免无限制地增长 - physics: widget.scrollable == false ? const NeverScrollableScrollPhysics() : null, // 禁用ListView的滚动 + physics: widget.scrollable == false + ? const NeverScrollableScrollPhysics() + : null, // 禁用ListView的滚动 itemCount: itemCount, itemBuilder: (context, index) { final item = widget.cells[index]; - final cell = widget.builder == null ? item : widget.builder!(context, item, index); - if (itemCount - 1 == index && (widget.isShowLastBordered ?? false)) { + final cell = widget.builder == null + ? item + : widget.builder!(context, item, index); + if (itemCount - 1 == index && + (widget.isShowLastBordered ?? false)) { return Column(children: [cell, _borderWidget(style)]); } return cell; @@ -135,9 +143,14 @@ class _TDCellGroupState extends State { Widget _borderWidget(TDCellStyle style) { return Row( children: [ - Container(height: 0.5, width: TDTheme.of(context).spacer16, color: style.backgroundColor), + Container( + height: 0.5, + width: TDTheme.of(context).spacer16, + color: style.backgroundColor), Expanded( - child: Container(height: 0.5, color: style.borderedColor ?? TDTheme.of(context).grayColor3), + child: Container( + height: 0.5, + color: style.borderedColor ?? TDTheme.of(context).grayColor3), ), ], ); diff --git a/tdesign-component/lib/src/components/form/td_form.dart b/tdesign-component/lib/src/components/form/td_form.dart index ef17bff11..6fdd5ffd1 100644 --- a/tdesign-component/lib/src/components/form/td_form.dart +++ b/tdesign-component/lib/src/components/form/td_form.dart @@ -1,8 +1,10 @@ import 'package:flutter/material.dart'; +import '../../../tdesign_flutter.dart'; class TDForm extends StatefulWidget { const TDForm({ - Key?key, + Key? key, + required this.items, this.colon = false, this.contentAlign = 'left', this.data, @@ -17,7 +19,10 @@ class TDForm extends StatefulWidget { this.scrollToFirstError, this.showErrorMessage = true, this.submitWithWarningMessage = false, - }): super(key: key); + }) : super(key: key); + + /// 表单内容 items + final List items; /// 是否在表单标签字段右侧显示冒号 final bool? colon; @@ -75,6 +80,17 @@ class TDForm extends StatefulWidget { class _TDFormState extends State { @override Widget build(BuildContext context) { - return const Placeholder(); + return Container( + child: ListView.separated( + shrinkWrap: true, + itemCount: widget.items.length, + itemBuilder: (context, index) { + return widget.items[index]; + }, + separatorBuilder: (context, index) { + return SizedBox(height: 1); + }, + ), + ); } -} \ No newline at end of file +} diff --git a/tdesign-component/lib/src/components/form/td_form_item.dart b/tdesign-component/lib/src/components/form/td_form_item.dart index c726c636b..03d3f95b3 100644 --- a/tdesign-component/lib/src/components/form/td_form_item.dart +++ b/tdesign-component/lib/src/components/form/td_form_item.dart @@ -1,6 +1,5 @@ import 'package:flutter/material.dart'; import '../../../tdesign_flutter.dart'; -import '../input/td_input.dart'; class TDFormItem extends StatefulWidget { TDFormItem({ @@ -8,6 +7,7 @@ class TDFormItem extends StatefulWidget { this.controller, this.select = '', List? localData, + Map? radios, this.label, this.name, this.arrow = false, @@ -18,8 +18,11 @@ class TDFormItem extends StatefulWidget { this.requiredMark, this.rules, this.showErrowMessage, + this.maxLength, + this.indicator, Key? key, }) : localData = localData ?? const [], + radios = radios ?? const {}, super(key: key); /// 表格内标签 内容填充 @@ -59,6 +62,9 @@ class TDFormItem extends StatefulWidget { /// 组相联选择器需要的数据 final List localData; + /// 单选框数据 + final Map radios; + /// 是否显示必填符号 (*) /// 优先级高于 Form.requiredMark final bool? requiredMark; @@ -70,6 +76,10 @@ class TDFormItem extends StatefulWidget { /// 优先级高于 Form.showErrowMessage final bool? showErrowMessage; + /// TDTextarea 预留API + final int? maxLength; + final bool? indicator; + @override _TDFormItemState createState() => _TDFormItemState(); } @@ -86,7 +96,10 @@ Widget buildSelectRow(BuildContext context, String output, String title) { children: [ Padding( padding: const EdgeInsets.only(left: 16, top: 16, bottom: 16), - child: TDText(title, font: TDTheme.of(context).fontBodyLarge,), + child: TDText( + title, + font: TDTheme.of(context).fontBodyLarge, + ), ), Padding( padding: const EdgeInsets.only(right: 16), @@ -95,19 +108,26 @@ Widget buildSelectRow(BuildContext context, String output, String title) { TDText( output, font: TDTheme.of(context).fontBodyLarge, - textColor: TDTheme.of(context).fontGyColor3.withOpacity(0.4),), + textColor: + TDTheme.of(context).fontGyColor3.withOpacity(0.4), + ), Padding( padding: const EdgeInsets.only(left: 2), child: Icon( TDIcons.chevron_right, - color: TDTheme.of(context).fontGyColor3.withOpacity(0.4),), + color: TDTheme.of(context).fontGyColor3.withOpacity(0.4), + ), ), ], ), ), ], ), - const TDDivider(margin: EdgeInsets.only(left: 16, ),) + const TDDivider( + margin: EdgeInsets.only( + left: 16, + ), + ) ], ), ); @@ -128,7 +148,6 @@ class _TDFormItemState extends State { children: [ TDInput( leftLabel: widget.label, - required: true, controller: widget.controller, backgroundColor: Colors.white, hintText: widget.help, @@ -150,13 +169,13 @@ class _TDFormItemState extends State { backgroundColor: Colors.white, rightBtn: browseOn ? Icon( - TDIcons.browse, - color: TDTheme.of(context).fontGyColor3, - ) + TDIcons.browse, + color: TDTheme.of(context).fontGyColor3, + ) : Icon( - TDIcons.browse_off, - color: TDTheme.of(context).fontGyColor3, - ), + TDIcons.browse_off, + color: TDTheme.of(context).fontGyColor3, + ), onBtnTap: () { setState(() { browseOn = !browseOn; @@ -169,48 +188,61 @@ class _TDFormItemState extends State { ), ], ); - } else if(widget.name == 'gender'){ - return TDRadioGroup( - selectId: 'index:1', - direction: Axis.horizontal, - directionalTdRadios: const [ - TDRadio( - id: '0', - title: '男', - radioStyle: TDRadioStyle.circle, - showDivider: false, - ), - TDRadio( - id: '1', - title: '女', - radioStyle: TDRadioStyle.circle, - showDivider: false, - ), - TDRadio( - id: '2', - title: '保密', - radioStyle: TDRadioStyle.circle, - showDivider: false, + } else if (widget.name == 'radios') { + final theme = TDTheme.of(context); + return Container( + height: 80.0, + decoration: BoxDecoration( + color: theme.whiteColor1, + ), + child: Padding( + padding: const EdgeInsets.all(16), + child: Row( + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + // 左侧的文本 + TDText( + widget.label ?? '', + style: const TextStyle(fontSize: 16), + ), + const SizedBox(width: 16), // 间隔 + // 右侧的单选按钮组,使用 Expanded 包裹 + Expanded( + child: TDRadioGroup( + selectId: 'index:1', + direction: Axis.horizontal, + directionalTdRadios: widget.radios.entries.map((entry) { + return TDRadio( + id: entry.key, + title: entry.value, + radioStyle: TDRadioStyle.circle, + showDivider: false, + ); + }).toList(), + ), + ), + ], ), - ], + ), ); - } else if(widget.name == 'date'){ - return GestureDetector( - onTap: (){ - TDPicker.showDatePicker(context, title: '选择时间', - onConfirm: (selected) { - setState(() { - widget.select = '${selected['year'].toString().padLeft(4, '0')}-${selected['month'].toString().padLeft(2, '0')}-${selected['day'].toString().padLeft(2, '0')}'; - }); - Navigator.of(context).pop(); - }, - dateStart: [1999, 01, 01], - dateEnd: [2023, 12, 31], - initialDate: [2012, 1, 1]); + } else if (widget.name == 'date') { + return GestureDetector( + onTap: () { + TDPicker.showDatePicker(context, title: '选择时间', + onConfirm: (selected) { + setState(() { + widget.select = + '${selected['year'].toString().padLeft(4, '0')}-${selected['month'].toString().padLeft(2, '0')}-${selected['day'].toString().padLeft(2, '0')}'; + }); + Navigator.of(context).pop(); }, - child: buildSelectRow(context, widget.select, '选择时间'), - ); - }else if(widget.name == 'age'){ + dateStart: [1999, 01, 01], + dateEnd: [2023, 12, 31], + initialDate: [2012, 1, 1]); + }, + child: buildSelectRow(context, widget.select, '选择时间'), + ); + } else if (widget.name == 'age') { final theme = TDTheme.of(context); return Container( @@ -233,31 +265,47 @@ class _TDFormItemState extends State { ), ), ); - }else if(widget.name == 'local'){ + } else if (widget.name == 'local') { return GestureDetector( onTap: () { - TDCascader.showMultiCascader(context, title: '选择地址', data: widget.localData, initialData: _initData, theme: 'step', + TDCascader.showMultiCascader(context, + title: '选择地址', + data: widget.localData, + initialData: _initData, + theme: 'step', onChange: (List selectData) { - setState(() { - List result = []; - int len = selectData.length; - _initData = selectData[len - 1].value!; - selectData.forEach((element) { - result.add(element.label); - }); - _selected_1 = result.join('/'); - }); - }, onClose: () { - Navigator.of(context).pop(); + setState(() { + List result = []; + int len = selectData.length; + _initData = selectData[len - 1].value!; + selectData.forEach((element) { + result.add(element.label); }); + _selected_1 = result.join('/'); + }); + }, onClose: () { + Navigator.of(context).pop(); + }); }, child: _buildSelectRow(context, _selected_1, '选择地区'), ); + } else if (widget.name == 'textarea') { + return TDTextarea( + /// 背景颜色未完成 + backgroundColor: Colors.white, + controller: widget.controller, + label: widget.label, + hintText: widget.help, + maxLength: widget.maxLength, + indicator: widget.indicator, + onChanged: (value) { + setState(() {}); + }, + ); } return Column(); } - Widget _buildSelectRow(BuildContext context, String output, String title) { return Container( color: TDTheme.of(context).whiteColor1, @@ -277,27 +325,29 @@ class _TDFormItemState extends State { ), Expanded( child: Padding( - padding: const EdgeInsets.only(right: 16, left: 16), - child: Row( - children: [ - Expanded( - child: TDText( - output, - font: TDTheme.of(context).fontBodyLarge, - textColor: TDTheme.of(context).fontGyColor3.withOpacity(0.4), - maxLines: 1, - overflow: TextOverflow.ellipsis, - )), - Padding( - padding: const EdgeInsets.only(left: 2), - child: Icon( - TDIcons.chevron_right, - color: TDTheme.of(context).fontGyColor3.withOpacity(0.4), - ), - ), - ], + padding: const EdgeInsets.only(right: 16, left: 16), + child: Row( + children: [ + Expanded( + child: TDText( + output, + font: TDTheme.of(context).fontBodyLarge, + textColor: + TDTheme.of(context).fontGyColor3.withOpacity(0.4), + maxLines: 1, + overflow: TextOverflow.ellipsis, + )), + Padding( + padding: const EdgeInsets.only(left: 2), + child: Icon( + TDIcons.chevron_right, + color: + TDTheme.of(context).fontGyColor3.withOpacity(0.4), + ), ), - )), + ], + ), + )), ], ), const TDDivider( From 6f29591e51666c1bd8472d1507d1a974ab0b8b93 Mon Sep 17 00:00:00 2001 From: Simon_Wzy <1691663479@qq.com> Date: Sun, 6 Oct 2024 11:03:31 +0800 Subject: [PATCH 12/46] =?UTF-8?q?=E5=88=9D=E6=AD=A5=E5=AE=9E=E7=8E=B0?= =?UTF-8?q?=E4=BA=86Form=E7=9A=84=E6=9E=84=E5=BB=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../example/lib/page/td_form_page.dart | 64 +++++++++++++------ .../lib/src/components/form/td_form.dart | 25 ++++---- .../components/form/td_form_inherited.dart | 18 ++++++ .../lib/src/components/form/td_form_item.dart | 10 +-- 4 files changed, 76 insertions(+), 41 deletions(-) create mode 100644 tdesign-component/lib/src/components/form/td_form_inherited.dart diff --git a/tdesign-component/example/lib/page/td_form_page.dart b/tdesign-component/example/lib/page/td_form_page.dart index 50ef3cab6..aadb0e096 100644 --- a/tdesign-component/example/lib/page/td_form_page.dart +++ b/tdesign-component/example/lib/page/td_form_page.dart @@ -15,14 +15,22 @@ class _TDFormPageState extends State { var controller = []; String selected_1 = ''; - Color verticalTextColor = Colors.black; - Color horizontalTextColor = Colors.red; - Color verticalButtonColor = Colors.blueGrey; - Color horizontalButtonColor = Colors.blue; + /// 设置按钮是否可点击状态 + /// true 表示处于 active 状态 + bool horizontalButton = false; + bool verticalButton = true; + + Color activeButtonColor = Color(0xFFF0F1FD); + Color defaultButtonColor = Color(0xFFE5E5E5); + + Color verticalTextColor = Color(0xFF1A1A1A); + Color horizontalTextColor = Color(0xFF0A58D9); + Color verticalButtonColor = Color(0xFFE5E5E5); + Color horizontalButtonColor = Color(0xFFF0F1FD); Map _radios = {"0": "男", "1": "女", "2": "保密"}; - List _data = [ + static const List _data = [ { "label": '北京市', "value": '110000', @@ -171,7 +179,7 @@ class _TDFormPageState extends State { maxLength: 500, indicator: true, ) - ]); + ], disabled: false); } /// 横 竖 排版模式切换 @@ -198,14 +206,21 @@ class _TDFormPageState extends State { ), onTap: () { setState(() { - print("____1"); - final currentVerticalColor = verticalButtonColor; - verticalButtonColor = horizontalButtonColor; - horizontalButtonColor = currentVerticalColor; + if (horizontalButton) { + /// 置换按钮状态 + horizontalButton = false; + verticalButton = true; - final currentTextColor = verticalTextColor; - verticalTextColor = horizontalTextColor; - horizontalTextColor = currentTextColor; + /// 置换按钮颜色 + final currentVerticalColor = verticalButtonColor; + verticalButtonColor = horizontalButtonColor; + horizontalButtonColor = currentVerticalColor; + + /// 置换文字颜色 + final currentTextColor = verticalTextColor; + verticalTextColor = horizontalTextColor; + horizontalTextColor = currentTextColor; + } }); }, ), @@ -222,14 +237,21 @@ class _TDFormPageState extends State { ), onTap: () { setState(() { - print("____2"); - final currentVerticalColor = verticalButtonColor; - verticalButtonColor = horizontalButtonColor; - horizontalButtonColor = currentVerticalColor; + if (verticalButton) { + /// 置换按钮状态 + horizontalButton = true; + verticalButton = false; + + /// 置换按钮颜色 + final currentVerticalColor = verticalButtonColor; + verticalButtonColor = horizontalButtonColor; + horizontalButtonColor = currentVerticalColor; - final currentTextColor = verticalTextColor; - verticalTextColor = horizontalTextColor; - horizontalTextColor = currentTextColor; + /// 置换文字颜色 + final currentTextColor = verticalTextColor; + verticalTextColor = horizontalTextColor; + horizontalTextColor = currentTextColor; + } }); }, ), @@ -267,7 +289,7 @@ class _TDFormPageState extends State { ], ); current = Padding( - padding: const EdgeInsets.symmetric(vertical: 8), + padding: const EdgeInsets.symmetric(vertical: 1), child: SizedBox( child: Container( child: Padding( diff --git a/tdesign-component/lib/src/components/form/td_form.dart b/tdesign-component/lib/src/components/form/td_form.dart index 6fdd5ffd1..4c7c40436 100644 --- a/tdesign-component/lib/src/components/form/td_form.dart +++ b/tdesign-component/lib/src/components/form/td_form.dart @@ -1,4 +1,5 @@ import 'package:flutter/material.dart'; +import 'package:tdesign_flutter/src/components/form/td_form_inherited.dart'; import '../../../tdesign_flutter.dart'; class TDForm extends StatefulWidget { @@ -35,7 +36,7 @@ class TDForm extends StatefulWidget { final Object? data; /// 是否禁用整个表单 - final bool? disabled; + final bool disabled; /// 表单信息错误信息配置 final Object? errorMessage; @@ -80,16 +81,18 @@ class TDForm extends StatefulWidget { class _TDFormState extends State { @override Widget build(BuildContext context) { - return Container( - child: ListView.separated( - shrinkWrap: true, - itemCount: widget.items.length, - itemBuilder: (context, index) { - return widget.items[index]; - }, - separatorBuilder: (context, index) { - return SizedBox(height: 1); - }, + return TDFormInherited( + disabled: widget.disabled, + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: widget.items + .map((item) => Column( + children: [ + item, + SizedBox(height: 1), + ], + )) + .toList(), ), ); } diff --git a/tdesign-component/lib/src/components/form/td_form_inherited.dart b/tdesign-component/lib/src/components/form/td_form_inherited.dart new file mode 100644 index 000000000..ac6c102dd --- /dev/null +++ b/tdesign-component/lib/src/components/form/td_form_inherited.dart @@ -0,0 +1,18 @@ +import 'package:flutter/cupertino.dart'; + +class TDFormInherited extends InheritedWidget { + const TDFormInherited( + {required Widget child, required this.disabled, Key? key}) + : super(child: child, key: key); + + final bool disabled; + + @override + bool updateShouldNotify(covariant TDFormInherited oldWidget) { + return true; + } + + static TDFormInherited? of(BuildContext context) { + return context.dependOnInheritedWidgetOfExactType(); + } +} diff --git a/tdesign-component/lib/src/components/form/td_form_item.dart b/tdesign-component/lib/src/components/form/td_form_item.dart index 03d3f95b3..71735384f 100644 --- a/tdesign-component/lib/src/components/form/td_form_item.dart +++ b/tdesign-component/lib/src/components/form/td_form_item.dart @@ -152,9 +152,6 @@ class _TDFormItemState extends State { backgroundColor: Colors.white, hintText: widget.help, ), - const SizedBox( - height: 16, - ), ], ); } else if (widget.name == 'password') { @@ -183,15 +180,11 @@ class _TDFormItemState extends State { }, needClear: false, ), - const SizedBox( - height: 16, - ), ], ); } else if (widget.name == 'radios') { final theme = TDTheme.of(context); return Container( - height: 80.0, decoration: BoxDecoration( color: theme.whiteColor1, ), @@ -205,8 +198,7 @@ class _TDFormItemState extends State { widget.label ?? '', style: const TextStyle(fontSize: 16), ), - const SizedBox(width: 16), // 间隔 - // 右侧的单选按钮组,使用 Expanded 包裹 + const SizedBox(width: 16), Expanded( child: TDRadioGroup( selectId: 'index:1', From a66f0e80f8d94090cef2487c4c565439ba590c67 Mon Sep 17 00:00:00 2001 From: Simon_Wzy <1691663479@qq.com> Date: Mon, 7 Oct 2024 13:50:26 +0800 Subject: [PATCH 13/46] =?UTF-8?q?=E5=88=9D=E6=AD=A5=E5=AE=9E=E7=8E=B0?= =?UTF-8?q?=E4=BA=86Form=E7=9A=84=E6=9E=84=E5=BB=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../example/lib/page/td_search_bar_page.dart | 72 ++++++++++--------- .../lib/src/components/form/td_form_item.dart | 2 +- 2 files changed, 39 insertions(+), 35 deletions(-) diff --git a/tdesign-component/example/lib/page/td_search_bar_page.dart b/tdesign-component/example/lib/page/td_search_bar_page.dart index 85cba87b0..cf2908cd5 100644 --- a/tdesign-component/example/lib/page/td_search_bar_page.dart +++ b/tdesign-component/example/lib/page/td_search_bar_page.dart @@ -19,27 +19,29 @@ class _TDSearchBarPageState extends State { @override Widget build(BuildContext context) { return ExamplePage( - title: tdTitle(), - desc: '用于一组预设数据中的选择。', - exampleCodeGroup: 'search', - backgroundColor: TDTheme.of(context).grayColor2, - children: [ - ExampleModule( - title: '组件类型', - children: [ - ExampleItem(desc: '基础搜索框', builder: _buildDefaultSearchBar), - ExampleItem(desc: '获取焦点后显示取消按钮', builder: _buildFocusSearchBar), - ], - ), - ExampleModule(title: '组件样式', children: [ - ExampleItem(desc: '搜索框形状', builder: _buildSearchBarWithShape), - ExampleItem(desc: '默认状态其他对齐方式', builder: _buildCenterSearchBar), - ]), - ], + title: tdTitle(), + desc: '用于一组预设数据中的选择。', + exampleCodeGroup: 'search', + backgroundColor: TDTheme.of(context).grayColor2, + children: [ + ExampleModule( + title: '组件类型', + children: [ + ExampleItem(desc: '基础搜索框', builder: _buildDefaultSearchBar), + ExampleItem(desc: '获取焦点后显示取消按钮', builder: _buildFocusSearchBar), + ], + ), + ExampleModule(title: '组件样式', children: [ + ExampleItem(desc: '搜索框形状', builder: _buildSearchBarWithShape), + ExampleItem(desc: '默认状态其他对齐方式', builder: _buildCenterSearchBar), + ]), + ], test: [ ExampleItem(desc: '获取焦点后显示自定义操作按钮', builder: _buildSearchBarWithAction), - ExampleItem(desc: '自定义获取焦点后显示按钮', builder: _buildFocusSearchBarWithAction), - ],); + ExampleItem( + desc: '自定义获取焦点后显示按钮', builder: _buildFocusSearchBarWithAction), + ], + ); } @Demo(group: 'search') @@ -141,7 +143,9 @@ class _TDSearchBarPageState extends State { }); }, ), - const SizedBox(height: 10,), + const SizedBox( + height: 10, + ), Container( padding: const EdgeInsets.only(left: 15), alignment: Alignment.centerLeft, @@ -152,7 +156,7 @@ class _TDSearchBarPageState extends State { ], ); } - + @Demo(group: 'search') Widget _buildFocusSearchBarWithAction(BuildContext context) { return TDSearchBar( @@ -160,19 +164,19 @@ class _TDSearchBarPageState extends State { action: '搜索', needCancel: true, controller: inputController, - onActionClick: () { - showGeneralDialog( - context: context, - pageBuilder: (BuildContext buildContext, Animation animation, - Animation secondaryAnimation) { - return TDConfirmDialog( - content: inputController.text.isNotEmpty - ? '搜索关键词:${inputController.text}' - : '搜索关键词为空', - ); - }, - ); - }, + // onActionClick: () { + // showGeneralDialog( + // context: context, + // pageBuilder: (BuildContext buildContext, Animation animation, + // Animation secondaryAnimation) { + // return TDConfirmDialog( + // content: inputController.text.isNotEmpty + // ? '搜索关键词:${inputController.text}' + // : '搜索关键词为空', + // ); + // }, + // ); + // }, ); } } diff --git a/tdesign-component/lib/src/components/form/td_form_item.dart b/tdesign-component/lib/src/components/form/td_form_item.dart index 71735384f..43b0f6fb1 100644 --- a/tdesign-component/lib/src/components/form/td_form_item.dart +++ b/tdesign-component/lib/src/components/form/td_form_item.dart @@ -284,7 +284,7 @@ class _TDFormItemState extends State { } else if (widget.name == 'textarea') { return TDTextarea( /// 背景颜色未完成 - backgroundColor: Colors.white, + backgroundColor: Colors.red, controller: widget.controller, label: widget.label, hintText: widget.help, From 2fe5516df5d0da454965ca966a2cb0f8c1c70026 Mon Sep 17 00:00:00 2001 From: Simon_Wzy <1691663479@qq.com> Date: Tue, 8 Oct 2024 21:18:36 +0800 Subject: [PATCH 14/46] =?UTF-8?q?=E5=88=9D=E6=AD=A5=E5=AE=9E=E7=8E=B0?= =?UTF-8?q?=E4=BA=86Form=E7=9A=84=E6=9E=84=E5=BB=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../example/lib/page/td_form_page.dart | 3 +++ .../lib/src/components/form/td_form_item.dart | 23 +++++++++++++++++-- 2 files changed, 24 insertions(+), 2 deletions(-) diff --git a/tdesign-component/example/lib/page/td_form_page.dart b/tdesign-component/example/lib/page/td_form_page.dart index aadb0e096..f99a34cdd 100644 --- a/tdesign-component/example/lib/page/td_form_page.dart +++ b/tdesign-component/example/lib/page/td_form_page.dart @@ -134,12 +134,15 @@ class _TDFormPageState extends State { label: '用户名', name: 'name', help: '请输入用户名', + additionInfo: '输入用户名', + inputPadding: 15.0, controller: controller[0], ), TDFormItem( label: '密码', name: 'password', help: '请输入密码', + inputPadding: 35.0, controller: controller[1], ), TDFormItem( diff --git a/tdesign-component/lib/src/components/form/td_form_item.dart b/tdesign-component/lib/src/components/form/td_form_item.dart index 43b0f6fb1..3314b8b83 100644 --- a/tdesign-component/lib/src/components/form/td_form_item.dart +++ b/tdesign-component/lib/src/components/form/td_form_item.dart @@ -20,6 +20,8 @@ class TDFormItem extends StatefulWidget { this.showErrowMessage, this.maxLength, this.indicator, + this.additionInfo, + this.inputPadding = 10.0, Key? key, }) : localData = localData ?? const [], radios = radios ?? const {}, @@ -36,10 +38,16 @@ class TDFormItem extends StatefulWidget { /// 是否显示右箭头 final bool? arrow; + /// TDInput 框的辅助说明文字 + final String? additionInfo; + /// 表单说明内容 /// 表单的默认输入字符 final String? help; + /// input 框默认文本的左侧 padding + final double inputPadding; + /// 表单字段标签对齐方式: /// 左对齐、右对齐、顶部对齐 /// 默认使用 Form 的对齐方式,其优先级高于 Form.labelAlign @@ -147,10 +155,16 @@ class _TDFormItemState extends State { return Column( children: [ TDInput( + inputDecoration: InputDecoration( + hintText: widget.help, + contentPadding: + EdgeInsets.only(left: widget.inputPadding), // 左侧内边距20像素 + border: InputBorder.none, + ), leftLabel: widget.label, controller: widget.controller, backgroundColor: Colors.white, - hintText: widget.help, + additionInfo: widget.additionInfo, ), ], ); @@ -158,11 +172,16 @@ class _TDFormItemState extends State { return Column( children: [ TDInput( + inputDecoration: InputDecoration( + hintText: widget.help, + contentPadding: + EdgeInsets.only(left: widget.inputPadding), // 左侧内边距20像素 + border: InputBorder.none, + ), type: TDInputType.normal, controller: widget.controller, obscureText: !browseOn, leftLabel: widget.label, - hintText: widget.help, backgroundColor: Colors.white, rightBtn: browseOn ? Icon( From aba552fcf086bbc73ae44e6321c5434513066985 Mon Sep 17 00:00:00 2001 From: hkaikai <617760820@qq.com> Date: Wed, 9 Oct 2024 23:58:21 +0800 Subject: [PATCH 15/46] =?UTF-8?q?rate=20=E5=BC=B9=E6=A1=86=E7=82=B9?= =?UTF-8?q?=E5=87=BB=E4=BA=8B=E4=BB=B6=E5=AE=8C=E5=96=84=EF=BC=8C=E6=94=B9?= =?UTF-8?q?overlay?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../example/lib/page/td_rate_page.dart | 24 ++- .../lib/src/components/rate/td_rate.dart | 182 ++++++++++-------- .../src/components/rate/td_rate_overlay.dart | 31 +++ .../lib/src/components/rate/td_rate_tips.dart | 154 ++++++++------- tdesign-component/lib/src/util/throttle.dart | 23 +++ 5 files changed, 251 insertions(+), 163 deletions(-) create mode 100644 tdesign-component/lib/src/components/rate/td_rate_overlay.dart create mode 100644 tdesign-component/lib/src/util/throttle.dart diff --git a/tdesign-component/example/lib/page/td_rate_page.dart b/tdesign-component/example/lib/page/td_rate_page.dart index bc51bfba3..49dd90f35 100644 --- a/tdesign-component/example/lib/page/td_rate_page.dart +++ b/tdesign-component/example/lib/page/td_rate_page.dart @@ -41,6 +41,10 @@ class TDRatePageState extends State { ExampleItem(desc: '只可选全星时', builder: _buildFullRate), ExampleItem(desc: '可选半星时', builder: _buildHalfRate), ]), + ExampleModule(title: '组件样式', children: [ + ExampleItem(desc: '评分大小', builder: _buildSizeRate), + ExampleItem(desc: '设置评分颜色', builder: _buildColorRate), + ]), ]); } @@ -67,7 +71,7 @@ class TDRatePageState extends State { TDCell(title: '带描述评分', noteWidget: TDRate(value: 3, showText: true)) ]); } - + @Demo(group: 'rate') Widget _buildDRate(BuildContext context) { return Column(children: const [ @@ -88,4 +92,22 @@ class TDRatePageState extends State { Widget _buildHalfRate(BuildContext context) { return const TDCell(title: '点击活滑动', noteWidget: TDRate(value: 3, allowHalf: true)); } + + @Demo(group: 'rate') + Widget _buildSizeRate(BuildContext context) { + return Column(children: const [ + TDCell(title: '默认尺寸24', noteWidget: TDRate(value: 3)), + SizedBox(height: 16), + TDCell(title: '小尺寸20', noteWidget: TDRate(value: 3, size: 20)), + ]); + } + + @Demo(group: 'rate') + Widget _buildColorRate(BuildContext context) { + return Column(children: const [ + TDCell(title: '填充评分', noteWidget: TDRate(value: 2.5, allowHalf: true, color: [Color(0xFFFFC51C), Color(0xFFE8E8E8)],)), + SizedBox(height: 16), + TDCell(title: '线描评分', noteWidget: TDRate(value: 2.5, allowHalf: true, color: [Color(0xFF00A870)])), + ]); + } } diff --git a/tdesign-component/lib/src/components/rate/td_rate.dart b/tdesign-component/lib/src/components/rate/td_rate.dart index 9dc80780c..ddfb860fe 100644 --- a/tdesign-component/lib/src/components/rate/td_rate.dart +++ b/tdesign-component/lib/src/components/rate/td_rate.dart @@ -6,6 +6,8 @@ import 'package:flutter/rendering.dart'; import '../../../tdesign_flutter.dart'; import '../../util/context_extension.dart'; import '../../util/iterable_ext.dart'; +import '../../util/throttle.dart'; +import 'td_rate_overlay.dart'; import 'td_rate_tips.dart'; enum PlacementEnum { @@ -100,21 +102,23 @@ class TDRate extends StatefulWidget { } class _TDRateState extends State { + final _throttle = Throttle(delay: const Duration(milliseconds: 100)); late double _activeValue; late Map _globalKeys; + late TDRateOverlay _overlay; Timer? _hideTipTimer; /// 控制显示弹框 var _showTip = false; - /// 组件高度 - var _height = 0.0; + /// 弹框的尺寸 + var _tipSize = Size.zero; - /// 当前弹框宽度 - var _tipWidth = 0.0; + /// 当前选中的评分的位置 + var _rateOffset = Offset.zero; - /// 当前选中的评分宽度 - var _rateWidth = 0.0; + /// 当前选中的评分的大小 + var _rateSize = Size.zero; /// 是否点击,否则是滑动 var _isClick = true; @@ -126,6 +130,7 @@ class _TDRateState extends State { _globalKeys = List.generate((widget.count ?? 5) * 2, (index) => index / 2 + 0.5) .asMap() .map((index, e) => MapEntry(e, GlobalKey())); + _overlay = TDRateOverlay(context: context, builder: (context) => _buildOverlay())..show(); } @override @@ -143,6 +148,7 @@ class _TDRateState extends State { @override void dispose() { + _overlay.hide(); _hideTipTimer?.cancel(); super.dispose(); } @@ -154,17 +160,19 @@ class _TDRateState extends State { mainAxisAlignment: widget.mainAxisAlignment ?? MainAxisAlignment.start, crossAxisAlignment: widget.crossAxisAlignment ?? CrossAxisAlignment.center, children: [ - Listener( - // behavior: HitTestBehavior.opaque, - onPointerDown: (event) { + GestureDetector( + onTapDown: (event) { _isClick = true; }, - onPointerMove: (details) { + onTapUp: (details) { + _changeSelect(details.globalPosition, true); + _hideTip(); + }, + onHorizontalDragUpdate: (details) { _isClick = false; - _changeSelect(details.position); + _changeSelect(details.globalPosition); }, - onPointerUp: (details) { - _changeSelect(details.position); + onHorizontalDragEnd: (details) { _hideTip(); }, child: Row( @@ -172,68 +180,32 @@ class _TDRateState extends State { final isLast = index == (widget.count ?? 5) - 1; return Padding( padding: EdgeInsets.only(right: isLast ? 0 : widget.gap ?? TDTheme.of(context).spacer8), - child: Stack( - clipBehavior: Clip.none, + child: Row( children: [ - Row( - children: [ - ClipRect( - key: _globalKeys[index + 0.5], - child: Align( - alignment: Alignment.centerLeft, - widthFactor: 0.5, - child: Icon( - _getIcon(value: index + 0.5), - size: widget.size ?? 24, - color: _getIconColor(value: index + 0.5), - ), - ), - ), - ClipRect( - key: _globalKeys[index + 1.0], - child: Align( - alignment: Alignment.centerRight, - widthFactor: 0.5, - child: Icon( - _getIcon(value: index + 1.0), - size: widget.size ?? 24, - color: _getIconColor(value: index + 1.0), - ), - ), + ClipRect( + key: _globalKeys[index + 0.5], + child: Align( + alignment: Alignment.centerLeft, + widthFactor: 0.5, + child: Icon( + _getIcon(value: index + 0.5), + size: widget.size ?? 24, + color: _getIconColor(value: index + 0.5), ), - ], + ), ), - if (widget.placement != PlacementEnum.none && - _showTip && - (index + 0.5 == _activeValue || index + 1 == _activeValue)) - Positioned( - bottom: widget.placement == PlacementEnum.top ? _height + TDTheme.of(context).spacer8 : null, - top: widget.placement == PlacementEnum.bottom ? _height + TDTheme.of(context).spacer8 : null, - left: -(_tipWidth - _rateWidth) / 2, - child: TDRateTips( - allowHalf: widget.allowHalf, - index: index, - activeValue: _activeValue, - icon: _getIcon(isActive: true), - size: widget.size, - getIconColor: _getIconColor, - isClick: _isClick, - withCall: (width) { - if (_tipWidth != width) { - setState(() { - _tipWidth = width; - }); - } - }, - tipClick: (value) { - setState(() { - _showTip = false; - _isClick = true; - _activeValue = value; - }); - }, + ClipRect( + key: _globalKeys[index + 1.0], + child: Align( + alignment: Alignment.centerRight, + widthFactor: 0.5, + child: Icon( + _getIcon(value: index + 1.0), + size: widget.size ?? 24, + color: _getIconColor(value: index + 1.0), ), ), + ), ], ), ); @@ -245,20 +217,27 @@ class _TDRateState extends State { ); } - void _changeSelect(Offset globalPosition) { - final newIndex = _fingerInsideContainer(globalPosition); - if (newIndex != null && newIndex != _activeValue) { - setState(() { + void _changeSelect(Offset globalPosition, [bool? isTap]) { + _throttle.call(() { + final newIndex = _fingerInsideContainer(globalPosition); + if (newIndex == null) { + return; + } + final diff = newIndex != _activeValue; + if (diff || isTap == true) { _activeValue = newIndex; _showTip = newIndex == 0 ? false : true; - }); - widget.onChange?.call(newIndex); - } + _overlay.update(); + if (diff) { + setState(() {}); + widget.onChange?.call(newIndex); + } + } + }); } double? _fingerInsideContainer(Offset globalPosition) { final rateBox = context.findRenderObject() as RenderBox?; - _height = rateBox?.size.height ?? 0; if (rateBox == null) { return null; } @@ -272,8 +251,10 @@ class _TDRateState extends State { final localPosition = renderBox.globalToLocal(globalPosition); final isIn = renderBox.hitTest(BoxHitTestResult(), position: localPosition); if (isIn) { - _rateWidth = renderBox.size.width * 2; - return (widget.allowHalf ?? false) ? entry.key : entry.key.ceil().toDouble(); + final parentRenderBox = renderBox.parent as RenderBox; + _rateOffset = parentRenderBox.localToGlobal(Offset.zero); + _rateSize = parentRenderBox.size; + return widget.allowHalf == true ? entry.key : entry.key.ceil().toDouble(); } } } @@ -285,10 +266,9 @@ class _TDRateState extends State { _hideTipTimer = Timer( Duration(seconds: _isClick && widget.allowHalf == true ? 3 : 1), () { - setState(() { - _showTip = false; - _isClick = true; - }); + _showTip = false; + _isClick = true; + _overlay.update(); }, ); } @@ -322,4 +302,38 @@ class _TDRateState extends State { final icon = [selectIcon, widget.icon?.getOrNull(1) ?? selectIcon]; return (value != null && _activeValue >= value) || (isActive != null && isActive) ? icon[0] : icon[1]; } + + Widget _buildOverlay() { + return widget.placement != PlacementEnum.none && _showTip + ? Positioned( + top: widget.placement == PlacementEnum.top + ? _rateOffset.dy - TDTheme.of(context).spacer8 - _tipSize.height + : _rateOffset.dy + TDTheme.of(context).spacer8 + _rateSize.height, + left: _rateOffset.dx - (_tipSize.width - _rateSize.width) / 2, + child: TDRateTips( + allowHalf: widget.allowHalf, + activeValue: _activeValue, + icon: _getIcon(isActive: true), + size: widget.size, + getIconColor: _getIconColor, + isClick: _isClick, + sizeCall: (size) { + if (_tipSize.width != size.width || _tipSize.height != size.height) { + _tipSize = size; + _overlay.update(); + } + }, + tipClick: (value) { + _showTip = false; + _isClick = true; + _overlay.update(); + if (value != _activeValue) { + _activeValue = value; + setState(() {}); + } + }, + ), + ) + : const SizedBox.shrink(); + } } diff --git a/tdesign-component/lib/src/components/rate/td_rate_overlay.dart b/tdesign-component/lib/src/components/rate/td_rate_overlay.dart new file mode 100644 index 000000000..1b7d94668 --- /dev/null +++ b/tdesign-component/lib/src/components/rate/td_rate_overlay.dart @@ -0,0 +1,31 @@ +import 'package:flutter/widgets.dart'; + +class TDRateOverlay { + TDRateOverlay({ + required this.context, + required this.builder, + + }); + final BuildContext context; + final WidgetBuilder builder; + + OverlayEntry? _overlayEntry; + + void show() { + WidgetsBinding.instance.addPostFrameCallback((_) { + _overlayEntry = OverlayEntry( + builder: builder, + ); + + Overlay.of(context).insert(_overlayEntry!); + }); + } + + void update() { + _overlayEntry?.markNeedsBuild(); + } + + void hide() { + _overlayEntry?.remove(); + } +} \ No newline at end of file diff --git a/tdesign-component/lib/src/components/rate/td_rate_tips.dart b/tdesign-component/lib/src/components/rate/td_rate_tips.dart index 42e400af8..0155cf427 100644 --- a/tdesign-component/lib/src/components/rate/td_rate_tips.dart +++ b/tdesign-component/lib/src/components/rate/td_rate_tips.dart @@ -7,32 +7,32 @@ class TDRateTips extends StatelessWidget { const TDRateTips({ Key? key, this.allowHalf = false, - required this.index, required this.activeValue, required this.icon, this.size, required this.getIconColor, - required this.withCall, + required this.sizeCall, required this.isClick, required this.tipClick, }) : super(key: key); final bool? allowHalf; - final int index; final double activeValue; final IconData icon; final double? size; final Color Function({double? value, bool? isActive}) getIconColor; - final void Function(double width) withCall; + final void Function(Size size) sizeCall; final bool isClick; final void Function(double value) tipClick; + int get index => (activeValue - 0.5).floor(); + @override Widget build(BuildContext context) { final _tipKey = GlobalKey(); WidgetsBinding.instance.addPostFrameCallback((_) { final renderBox = _tipKey.currentContext?.findRenderObject() as RenderBox?; - withCall(renderBox?.size.width ?? 0.0); + sizeCall(renderBox?.size ?? Size.zero); }); return Container( key: _tipKey, @@ -63,87 +63,53 @@ class TDRateTips extends StatelessWidget { padding: EdgeInsets.all(TDTheme.of(context).spacer4), child: Row( children: [ - // GestureDetector( - // onTap: () { - // if (allowHalf == true && isClick) { - // tipClick(index + 0.5); - // } - // }, - // child: - Container( - decoration: BoxDecoration( - color: allowHalf == true && index + 0.5 == activeValue && isClick - ? TDTheme.of(context).grayColor3 - : TDTheme.of(context).whiteColor1, - borderRadius: BorderRadius.circular(TDTheme.of(context).radiusSmall), - ), - padding: EdgeInsets.only(left: TDTheme.of(context).spacer4, right: TDTheme.of(context).spacer4), - child: Column( - children: [ - Row( - children: [ - ClipRect( - child: Align( - alignment: Alignment.centerLeft, - widthFactor: 0.5, - child: Icon( - icon, - size: size ?? 24, - color: getIconColor(isActive: true), - ), - ), - ), - ClipRect( - child: Align( - alignment: Alignment.centerRight, - widthFactor: 0.5, - child: Icon( - icon, - size: size ?? 24, - color: allowHalf == true - ? (isClick ? getIconColor(isActive: false) : getIconColor(value: index + 1)) - : getIconColor(isActive: true), - ), - ), - ), - ], - ), - Center( - child: TDText( - allowHalf == true ? (isClick ? '${index + 0.5}' : '${activeValue}') : '${index + 1}', - font: TDTheme.of(context).fontBodySmall, - textColor: TDTheme.of(context).fontGyColor1, - ), - ), - ], - ), - ), - // ), - if (allowHalf == true && isClick) SizedBox(width: TDTheme.of(context).spacer4), - if (allowHalf == true && isClick) - // GestureDetector( - // onTap: () { - // if (allowHalf == true && isClick) { - // tipClick(index + 1.0); - // } - // }, - // child: - Container( + GestureDetector( + onTap: () { + if (allowHalf == true && isClick) { + tipClick(index + 0.5); + } + }, + child: Container( decoration: BoxDecoration( - color: index + 1 != activeValue ? TDTheme.of(context).whiteColor1 : TDTheme.of(context).grayColor3, + color: allowHalf == true && index + 0.5 == activeValue && isClick + ? TDTheme.of(context).grayColor3 + : TDTheme.of(context).whiteColor1, borderRadius: BorderRadius.circular(TDTheme.of(context).radiusSmall), ), padding: EdgeInsets.only(left: TDTheme.of(context).spacer4, right: TDTheme.of(context).spacer4), child: Column( children: [ - Icon( - icon, - size: size ?? 24, - color: getIconColor(isActive: true), + Row( + children: [ + ClipRect( + child: Align( + alignment: Alignment.centerLeft, + widthFactor: 0.5, + child: Icon( + icon, + size: size ?? 24, + color: getIconColor(isActive: true), + ), + ), + ), + ClipRect( + child: Align( + alignment: Alignment.centerRight, + widthFactor: 0.5, + child: Icon( + icon, + size: size ?? 24, + color: allowHalf == true + ? (isClick ? getIconColor(isActive: false) : getIconColor(value: index + 1)) + : getIconColor(isActive: true), + ), + ), + ), + ], ), Center( child: TDText( - '${index + 1}', + allowHalf == true ? (isClick ? '${index + 0.5}' : '${activeValue}') : '${index + 1}', font: TDTheme.of(context).fontBodySmall, textColor: TDTheme.of(context).fontGyColor1, ), @@ -151,7 +117,39 @@ class TDRateTips extends StatelessWidget { ], ), ), - // ), + ), + if (allowHalf == true && isClick) SizedBox(width: TDTheme.of(context).spacer4), + if (allowHalf == true && isClick) + GestureDetector( + onTap: () { + if (allowHalf == true && isClick) { + tipClick(index + 1.0); + } + }, + child: Container( + decoration: BoxDecoration( + color: index + 1 != activeValue ? TDTheme.of(context).whiteColor1 : TDTheme.of(context).grayColor3, + borderRadius: BorderRadius.circular(TDTheme.of(context).radiusSmall), + ), + padding: EdgeInsets.only(left: TDTheme.of(context).spacer4, right: TDTheme.of(context).spacer4), + child: Column( + children: [ + Icon( + icon, + size: size ?? 24, + color: getIconColor(isActive: true), + ), + Center( + child: TDText( + '${index + 1}', + font: TDTheme.of(context).fontBodySmall, + textColor: TDTheme.of(context).fontGyColor1, + ), + ), + ], + ), + ), + ), ], ), ); diff --git a/tdesign-component/lib/src/util/throttle.dart b/tdesign-component/lib/src/util/throttle.dart new file mode 100644 index 000000000..adf1e88a4 --- /dev/null +++ b/tdesign-component/lib/src/util/throttle.dart @@ -0,0 +1,23 @@ +import 'dart:async'; + +import 'package:flutter/widgets.dart'; + +class Throttle { + Duration delay; + Timer? _timer; + + Throttle({required this.delay}); + + void call(VoidCallback callback) { + if (_timer?.isActive ?? false) { + // 如果 _timer 正在运行,则不执行任何操作 + return; + } + + // 创建一个新的计时器 + _timer = Timer(delay, () { + callback(); + _timer = null; // 计时器执行完毕后,将其置为 null + }); + } +} \ No newline at end of file From 9f4ae12e2a8e63aa814fa0ae51c444e0fced1c4d Mon Sep 17 00:00:00 2001 From: hkaikai <617760820@qq.com> Date: Thu, 10 Oct 2024 12:32:42 +0800 Subject: [PATCH 16/46] =?UTF-8?q?=E5=AE=8C=E6=88=90=E7=BB=84=E4=BB=B6?= =?UTF-8?q?=E5=92=8Cdemo=E5=BC=80=E5=8F=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../example/lib/page/td_rate_page.dart | 52 +++++++++- .../lib/src/components/rate/td_rate.dart | 94 ++++++++++++++----- 2 files changed, 119 insertions(+), 27 deletions(-) diff --git a/tdesign-component/example/lib/page/td_rate_page.dart b/tdesign-component/example/lib/page/td_rate_page.dart index 49dd90f35..8ae35dd81 100644 --- a/tdesign-component/example/lib/page/td_rate_page.dart +++ b/tdesign-component/example/lib/page/td_rate_page.dart @@ -45,6 +45,9 @@ class TDRatePageState extends State { ExampleItem(desc: '评分大小', builder: _buildSizeRate), ExampleItem(desc: '设置评分颜色', builder: _buildColorRate), ]), + ExampleModule(title: '特殊样式', children: [ + ExampleItem(desc: '竖向带描述评分', builder: _buildOtherRate), + ]), ]); } @@ -60,7 +63,12 @@ class TDRatePageState extends State { @Demo(group: 'rate') Widget _buildNumRate(BuildContext context) { - return const TDCell(title: '自定义评分数量', noteWidget: TDRate(value: 2, count: 3,)); + return const TDCell( + title: '自定义评分数量', + noteWidget: TDRate( + value: 2, + count: 3, + )); } @Demo(group: 'rate') @@ -105,9 +113,49 @@ class TDRatePageState extends State { @Demo(group: 'rate') Widget _buildColorRate(BuildContext context) { return Column(children: const [ - TDCell(title: '填充评分', noteWidget: TDRate(value: 2.5, allowHalf: true, color: [Color(0xFFFFC51C), Color(0xFFE8E8E8)],)), + TDCell( + title: '填充评分', + noteWidget: TDRate( + value: 2.5, + allowHalf: true, + color: [Color(0xFFFFC51C), Color(0xFFE8E8E8)], + )), SizedBox(height: 16), TDCell(title: '线描评分', noteWidget: TDRate(value: 2.5, allowHalf: true, color: [Color(0xFF00A870)])), ]); } + + @Demo(group: 'rate') + Widget _buildOtherRate(BuildContext context) { + var texts = ['非常糟糕', '有些糟糕', '可以尝试', '可以前往', '推荐前往']; + return Container( + width: double.infinity, + child: Center( + child: TDRate( + value: 2, + size: 30, + showText: true, + // texts: ['非常糟糕', '有些糟糕', '可以尝试', '可以前往', '推荐前往'], + direction: Axis.vertical, + // mainAxisAlignment: MainAxisAlignment.center, + // textWidth: 64, + builderText: (context, value) { + return value == 0 + ? const SizedBox.shrink() + : Padding( + padding: EdgeInsets.only(top: TDTheme.of(context).spacer8), + child: TDText( + texts[(value - 1).toInt()], + font: TDTheme.of(context).fontTitleMedium, + textColor: TDTheme.of(context).warningColor5, + ), + ); + }, + ), + ), + + padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 12), + color: Colors.white, + ); + } } diff --git a/tdesign-component/lib/src/components/rate/td_rate.dart b/tdesign-component/lib/src/components/rate/td_rate.dart index ddfb860fe..44bb4e980 100644 --- a/tdesign-component/lib/src/components/rate/td_rate.dart +++ b/tdesign-component/lib/src/components/rate/td_rate.dart @@ -37,6 +37,7 @@ class TDRate extends StatefulWidget { this.direction = Axis.horizontal, this.mainAxisAlignment = MainAxisAlignment.start, this.crossAxisAlignment = CrossAxisAlignment.center, + this.mainAxisSize = MainAxisSize.min, this.iconTextGap, }); @@ -77,6 +78,7 @@ class TDRate extends StatefulWidget { final double? textWidth; /// 评分等级对应的辅助文字自定义构建,优先级高于[texts] + /// 配置后,会忽略[texts],[textWidth],[iconTextGap] final Widget Function(BuildContext context, double value)? builderText; /// 选择评分的值 @@ -94,6 +96,9 @@ class TDRate extends StatefulWidget { /// 评分图标与辅助文字的交叉轴对齐方式 final CrossAxisAlignment? crossAxisAlignment; + /// 评分图标与辅助文字主轴方向上如何占用空间 + final MainAxisSize? mainAxisSize; + /// 评分图标与辅助文字的间距,默认:[TDTheme.of(context).spacer16] final double? iconTextGap; @@ -101,11 +106,13 @@ class TDRate extends StatefulWidget { _TDRateState createState() => _TDRateState(); } -class _TDRateState extends State { +class _TDRateState extends State with TickerProviderStateMixin { final _throttle = Throttle(delay: const Duration(milliseconds: 100)); late double _activeValue; late Map _globalKeys; late TDRateOverlay _overlay; + late List _controller; + late List> _animation; Timer? _hideTipTimer; /// 控制显示弹框 @@ -131,6 +138,12 @@ class _TDRateState extends State { .asMap() .map((index, e) => MapEntry(e, GlobalKey())); _overlay = TDRateOverlay(context: context, builder: (context) => _buildOverlay())..show(); + _tipSize = Size(widget.allowHalf == true ? 76 : 40, 52); + _controller = List.generate(widget.count ?? 5, ((index) => AnimationController( + duration: const Duration(milliseconds: 300), + vsync: this, + ))); + _animation = List.generate(widget.count ?? 5, ((index) => Tween(begin: 1.0, end: 1.33).animate(_controller[index]))); } @override @@ -144,12 +157,16 @@ class _TDRateState extends State { .asMap() .map((index, e) => MapEntry(e, GlobalKey())); } + if (widget.allowHalf != oldWidget.allowHalf) { + _tipSize = Size(widget.allowHalf == true ? 76 : 40, 52); + } } @override void dispose() { _overlay.hide(); _hideTipTimer?.cancel(); + _controller.forEach((controller) => controller.dispose()); super.dispose(); } @@ -159,6 +176,7 @@ class _TDRateState extends State { direction: widget.direction ?? Axis.horizontal, mainAxisAlignment: widget.mainAxisAlignment ?? MainAxisAlignment.start, crossAxisAlignment: widget.crossAxisAlignment ?? CrossAxisAlignment.center, + mainAxisSize: widget.mainAxisSize ?? MainAxisSize.min, children: [ GestureDetector( onTapDown: (event) { @@ -176,37 +194,47 @@ class _TDRateState extends State { _hideTip(); }, child: Row( + mainAxisSize: MainAxisSize.min, children: List.generate(widget.count ?? 5, (index) { final isLast = index == (widget.count ?? 5) - 1; return Padding( padding: EdgeInsets.only(right: isLast ? 0 : widget.gap ?? TDTheme.of(context).spacer8), - child: Row( - children: [ - ClipRect( - key: _globalKeys[index + 0.5], - child: Align( - alignment: Alignment.centerLeft, - widthFactor: 0.5, - child: Icon( - _getIcon(value: index + 0.5), - size: widget.size ?? 24, - color: _getIconColor(value: index + 0.5), + child: AnimatedBuilder( + animation: _animation[index], + builder: (context, child) { + return Transform.scale( + scale: _animation[index].value, + child: child, + ); + }, + child: Row( + children: [ + ClipRect( + key: _globalKeys[index + 0.5], + child: Align( + alignment: Alignment.centerLeft, + widthFactor: 0.5, + child: Icon( + _getIcon(value: index + 0.5), + size: widget.size ?? 24, + color: _getIconColor(value: index + 0.5), + ), ), ), - ), - ClipRect( - key: _globalKeys[index + 1.0], - child: Align( - alignment: Alignment.centerRight, - widthFactor: 0.5, - child: Icon( - _getIcon(value: index + 1.0), - size: widget.size ?? 24, - color: _getIconColor(value: index + 1.0), + ClipRect( + key: _globalKeys[index + 1.0], + child: Align( + alignment: Alignment.centerRight, + widthFactor: 0.5, + child: Icon( + _getIcon(value: index + 1.0), + size: widget.size ?? 24, + color: _getIconColor(value: index + 1.0), + ), ), ), - ), - ], + ], + ), ), ); }), @@ -227,6 +255,7 @@ class _TDRateState extends State { if (diff || isTap == true) { _activeValue = newIndex; _showTip = newIndex == 0 ? false : true; + _forward(); _overlay.update(); if (diff) { setState(() {}); @@ -236,6 +265,19 @@ class _TDRateState extends State { }); } + void _forward() { + _controller.forEach((element) { + element.reverse(); + }); + _controller.getOrNull((_activeValue - 0.5).floor())?.forward(); + } + + void _reverse() { + _controller.forEach((element) { + element.reverse(); + }); + } + double? _fingerInsideContainer(Offset globalPosition) { final rateBox = context.findRenderObject() as RenderBox?; if (rateBox == null) { @@ -264,10 +306,11 @@ class _TDRateState extends State { void _hideTip() { _hideTipTimer?.cancel(); _hideTipTimer = Timer( - Duration(seconds: _isClick && widget.allowHalf == true ? 3 : 1), + Duration(milliseconds: _isClick && widget.allowHalf == true ? 3000 : 1000), () { _showTip = false; _isClick = true; + _reverse(); _overlay.update(); }, ); @@ -326,6 +369,7 @@ class _TDRateState extends State { tipClick: (value) { _showTip = false; _isClick = true; + _reverse(); _overlay.update(); if (value != _activeValue) { _activeValue = value; From 13dccc32afbeb313683135213321b083efa7ba77 Mon Sep 17 00:00:00 2001 From: hkaikai <617760820@qq.com> Date: Thu, 10 Oct 2024 14:59:44 +0800 Subject: [PATCH 17/46] =?UTF-8?q?=E4=BC=98=E5=8C=96=E5=BC=B9=E6=A1=86?= =?UTF-8?q?=E4=BD=8D=E7=BD=AE=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../lib/src/components/rate/td_rate.dart | 122 +++++++++++------- 1 file changed, 75 insertions(+), 47 deletions(-) diff --git a/tdesign-component/lib/src/components/rate/td_rate.dart b/tdesign-component/lib/src/components/rate/td_rate.dart index 44bb4e980..bd5bf8606 100644 --- a/tdesign-component/lib/src/components/rate/td_rate.dart +++ b/tdesign-component/lib/src/components/rate/td_rate.dart @@ -107,12 +107,26 @@ class TDRate extends StatefulWidget { } class _TDRateState extends State with TickerProviderStateMixin { + /// 节流 final _throttle = Throttle(delay: const Duration(milliseconds: 100)); + + /// 当前选中的评分值 late double _activeValue; + + /// 根据评分值,获取所在评分的索引 + int _index([double? value]) => ((value ?? _activeValue) - 0.5).floor(); + + /// 每半个评分的GlobalKey late Map _globalKeys; + + /// 弹框 late TDRateOverlay _overlay; + + /// 动画 late List _controller; late List> _animation; + + /// 隐藏弹框的定时器 Timer? _hideTipTimer; /// 控制显示弹框 @@ -121,11 +135,11 @@ class _TDRateState extends State with TickerProviderStateMixin { /// 弹框的尺寸 var _tipSize = Size.zero; - /// 当前选中的评分的位置 - var _rateOffset = Offset.zero; + /// 每个评分(Row)的Size:<索引, Size> + final _rateSize = {}; - /// 当前选中的评分的大小 - var _rateSize = Size.zero; + /// 每个评分(Row)的Offset:<索引, Offset> + final _rateOffset = {}; /// 是否点击,否则是滑动 var _isClick = true; @@ -139,11 +153,14 @@ class _TDRateState extends State with TickerProviderStateMixin { .map((index, e) => MapEntry(e, GlobalKey())); _overlay = TDRateOverlay(context: context, builder: (context) => _buildOverlay())..show(); _tipSize = Size(widget.allowHalf == true ? 76 : 40, 52); - _controller = List.generate(widget.count ?? 5, ((index) => AnimationController( - duration: const Duration(milliseconds: 300), - vsync: this, - ))); - _animation = List.generate(widget.count ?? 5, ((index) => Tween(begin: 1.0, end: 1.33).animate(_controller[index]))); + _controller = List.generate( + widget.count ?? 5, + ((index) => AnimationController( + duration: const Duration(milliseconds: 300), + vsync: this, + ))); + _animation = + List.generate(widget.count ?? 5, ((index) => Tween(begin: 1.0, end: 1.33).animate(_controller[index]))); } @override @@ -269,11 +286,11 @@ class _TDRateState extends State with TickerProviderStateMixin { _controller.forEach((element) { element.reverse(); }); - _controller.getOrNull((_activeValue - 0.5).floor())?.forward(); + _controller.getOrNull(_index())?.forward(); } void _reverse() { - _controller.forEach((element) { + _controller.forEach((element) { element.reverse(); }); } @@ -293,10 +310,14 @@ class _TDRateState extends State with TickerProviderStateMixin { final localPosition = renderBox.globalToLocal(globalPosition); final isIn = renderBox.hitTest(BoxHitTestResult(), position: localPosition); if (isIn) { - final parentRenderBox = renderBox.parent as RenderBox; - _rateOffset = parentRenderBox.localToGlobal(Offset.zero); - _rateSize = parentRenderBox.size; - return widget.allowHalf == true ? entry.key : entry.key.ceil().toDouble(); + var value = widget.allowHalf == true ? entry.key : entry.key.ceil().toDouble(); + var index = _index(value); + if (!_rateSize.containsKey(index) || !_rateOffset.containsKey(index)) { + final parentRenderBox = renderBox.parent as RenderBox; + _rateSize[index] = parentRenderBox.size; + _rateOffset[index] = parentRenderBox.localToGlobal(Offset.zero); + } + return value; } } } @@ -347,37 +368,44 @@ class _TDRateState extends State with TickerProviderStateMixin { } Widget _buildOverlay() { - return widget.placement != PlacementEnum.none && _showTip - ? Positioned( - top: widget.placement == PlacementEnum.top - ? _rateOffset.dy - TDTheme.of(context).spacer8 - _tipSize.height - : _rateOffset.dy + TDTheme.of(context).spacer8 + _rateSize.height, - left: _rateOffset.dx - (_tipSize.width - _rateSize.width) / 2, - child: TDRateTips( - allowHalf: widget.allowHalf, - activeValue: _activeValue, - icon: _getIcon(isActive: true), - size: widget.size, - getIconColor: _getIconColor, - isClick: _isClick, - sizeCall: (size) { - if (_tipSize.width != size.width || _tipSize.height != size.height) { - _tipSize = size; - _overlay.update(); - } - }, - tipClick: (value) { - _showTip = false; - _isClick = true; - _reverse(); - _overlay.update(); - if (value != _activeValue) { - _activeValue = value; - setState(() {}); - } - }, - ), - ) - : const SizedBox.shrink(); + if (widget.placement == PlacementEnum.none || !_showTip || _activeValue == 0) { + return const SizedBox.shrink(); + } + var index = _index(); + var rateSize = _rateSize[index]; + var rateOffset = _rateOffset[index]; + if (rateSize == null || rateOffset == null) { + return const SizedBox.shrink(); + } + return Positioned( + top: widget.placement == PlacementEnum.top + ? rateOffset.dy - TDTheme.of(context).spacer8 - _tipSize.height + : rateOffset.dy + TDTheme.of(context).spacer8 + rateSize.height, + left: rateOffset.dx - (_tipSize.width - rateSize.width) / 2, + child: TDRateTips( + allowHalf: widget.allowHalf, + activeValue: _activeValue, + icon: _getIcon(isActive: true), + size: widget.size, + getIconColor: _getIconColor, + isClick: _isClick, + sizeCall: (size) { + if (_tipSize.width != size.width || _tipSize.height != size.height) { + _tipSize = size; + _overlay.update(); + } + }, + tipClick: (value) { + _showTip = false; + _isClick = true; + _reverse(); + _overlay.update(); + if (value != _activeValue) { + _activeValue = value; + setState(() {}); + } + }, + ), + ); } } From 9952df009f69c1c5094fbf5d35a7e9e1ee975581 Mon Sep 17 00:00:00 2001 From: Luozf12345 <2515187986@qq.com> Date: Sun, 13 Oct 2024 14:34:02 +0800 Subject: [PATCH 18/46] =?UTF-8?q?=E6=B5=81=E6=B0=B4=E7=BA=BF=E6=8F=90?= =?UTF-8?q?=E4=BA=A4=E7=94=9F=E6=88=90=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../assets/code/calendar._buildBlock.txt | 9 + .../assets/code/calendar._buildSimple.txt | 159 +++++++++++ .../assets/code/calendar._buildStyle.txt | 97 +++++++ ...scader._buildHorizontalCompanyCascader.txt | 2 +- ...ascader._buildHorizontalLetterCascader.txt | 8 +- ...ader._buildTestVerticalCompanyCascader.txt | 25 ++ ...cascader._buildVerticalCompanyCascader.txt | 2 +- .../assets/code/cell._buildPadding.txt | 11 + .../code/datetimePicker._customStartTime.txt | 30 ++ .../code/dialog._customContentAndBtn.txt | 32 +++ .../assets/code/drawer._buildColorSimple.txt | 22 ++ .../code/dropdownMenu._buildOverflow.txt | 71 +++++ .../code/image_viewer._actionImageViewer.txt | 6 +- .../assets/code/indexes._buildOther.txt | 39 +++ .../assets/code/indexes._buildSimple.txt | 38 +++ .../code/input._inputStatusLongLabel.txt | 2 + .../assets/code/input._onTapOutside.txt | 30 ++ .../assets/code/input._verticalStyle.txt | 1 + .../assets/code/navbar._shadowNavbar.txt | 17 ++ .../assets/code/noticeBar._cardNoticeBar.txt | 54 ++++ .../assets/code/noticeBar._closeNoticeBar.txt | 8 + .../code/noticeBar._customNoticeBar.txt | 9 + .../code/noticeBar._entranceNoticeBar1.txt | 15 + .../code/noticeBar._entranceNoticeBar2.txt | 11 + .../assets/code/noticeBar._errorNoticeBar.txt | 8 + .../assets/code/noticeBar._iconNoticeBar.txt | 7 + .../assets/code/noticeBar._leftNoticeBar.txt | 15 + .../code/noticeBar._normalNoticeBar.txt | 8 + .../code/noticeBar._scrollIconNoticeBar.txt | 12 + .../code/noticeBar._scrollNoticeBar.txt | 8 + .../assets/code/noticeBar._stepNoticeBar.txt | 9 + .../code/noticeBar._successNoticeBar.txt | 8 + .../assets/code/noticeBar._tapNoticeBar.txt | 11 + .../assets/code/noticeBar._textNoticeBar.txt | 4 + .../code/noticeBar._warningNoticeBar.txt | 8 + .../code/picker.buildCustomLeftRightText.txt | 35 +++ .../code/radio._horizontalCardStyle.txt | 1 + .../code/result._buildBasicResultDefault.txt | 2 +- .../code/result._buildBasicResultError.txt | 2 +- .../code/result._buildBasicResultSuccess.txt | 2 +- .../code/result._buildBasicResultWarning.txt | 2 +- .../code/result._buildCustomResultContent.txt | 9 +- ...ult._buildResultWithDescriptionDefault.txt | 2 +- ...esult._buildResultWithDescriptionError.txt | 2 +- ...ult._buildResultWithDescriptionSuccess.txt | 2 +- ...ult._buildResultWithDescriptionWarning.txt | 2 +- .../search._buildFocusSearchBarWithAction.txt | 2 +- .../code/search._buildSearchBarWithAction.txt | 58 ++-- .../code/sideBar._buildLoadingSideBar.txt | 41 +++ .../example/assets/code/table._basicTable.txt | 12 + .../assets/code/table._borderTable.txt | 13 + .../assets/code/table._centerTable.txt | 12 + .../example/assets/code/table._emptyTable.txt | 11 + .../assets/code/table._fixedEndColTable.txt | 37 +++ .../assets/code/table._fixedFirstColTable.txt | 12 + .../assets/code/table._fixedHeaderTable.txt | 14 + .../assets/code/table._fixedScrollTable.txt | 37 +++ .../code/table._horizontalScrollTable.txt | 11 + .../assets/code/table._loadingTable.txt | 12 + .../assets/code/table._operationBtnTable.txt | 40 +++ .../assets/code/table._operationIconTable.txt | 24 ++ .../assets/code/table._sortableTable.txt | 12 + .../assets/code/table._stripeTable.txt | 13 + .../assets/code/timeCounter._buildControl.txt | 60 ++++ .../code/timeCounter._buildCustomNum.txt | 7 + .../timeCounter._buildCustomUnitLargeSize.txt | 10 + ...timeCounter._buildCustomUnitMediumSize.txt | 10 + .../timeCounter._buildCustomUnitSimple.txt | 6 + .../timeCounter._buildCustomUnitSmallSize.txt | 10 + .../code/timeCounter._buildLargeSize.txt | 7 + .../code/timeCounter._buildMediumSize.txt | 7 + .../timeCounter._buildMillisecondSimple.txt | 4 + .../code/timeCounter._buildRoundLargeSize.txt | 8 + .../timeCounter._buildRoundMediumSize.txt | 8 + .../code/timeCounter._buildRoundSimple.txt | 4 + .../code/timeCounter._buildRoundSmallSize.txt | 8 + .../assets/code/timeCounter._buildSimple.txt | 4 + .../code/timeCounter._buildSmallSize.txt | 7 + .../timeCounter._buildSquareLargeSize.txt | 8 + .../timeCounter._buildSquareMediumSize.txt | 8 + .../code/timeCounter._buildSquareSimple.txt | 4 + .../timeCounter._buildSquareSmallSize.txt | 8 + .../code/timeCounter._buildUnitLargeSize.txt | 9 + .../code/timeCounter._buildUnitMediumSize.txt | 9 + .../code/timeCounter._buildUnitSimple.txt | 4 + .../code/timeCounter._buildUnitSmallSize.txt | 9 + .../code/timeCounter._buildUpSimple.txt | 8 + .../assets/code/toast._preventTapToast.txt | 14 + tdesign-site/src/indexes/README.md | 266 ++++++++++++++++++ 89 files changed, 1678 insertions(+), 47 deletions(-) create mode 100644 tdesign-component/example/assets/code/calendar._buildBlock.txt create mode 100644 tdesign-component/example/assets/code/calendar._buildSimple.txt create mode 100644 tdesign-component/example/assets/code/calendar._buildStyle.txt create mode 100644 tdesign-component/example/assets/code/cascader._buildTestVerticalCompanyCascader.txt create mode 100644 tdesign-component/example/assets/code/cell._buildPadding.txt create mode 100644 tdesign-component/example/assets/code/datetimePicker._customStartTime.txt create mode 100644 tdesign-component/example/assets/code/dialog._customContentAndBtn.txt create mode 100644 tdesign-component/example/assets/code/drawer._buildColorSimple.txt create mode 100644 tdesign-component/example/assets/code/dropdownMenu._buildOverflow.txt create mode 100644 tdesign-component/example/assets/code/indexes._buildOther.txt create mode 100644 tdesign-component/example/assets/code/indexes._buildSimple.txt create mode 100644 tdesign-component/example/assets/code/input._onTapOutside.txt create mode 100644 tdesign-component/example/assets/code/navbar._shadowNavbar.txt create mode 100644 tdesign-component/example/assets/code/noticeBar._cardNoticeBar.txt create mode 100644 tdesign-component/example/assets/code/noticeBar._closeNoticeBar.txt create mode 100644 tdesign-component/example/assets/code/noticeBar._customNoticeBar.txt create mode 100644 tdesign-component/example/assets/code/noticeBar._entranceNoticeBar1.txt create mode 100644 tdesign-component/example/assets/code/noticeBar._entranceNoticeBar2.txt create mode 100644 tdesign-component/example/assets/code/noticeBar._errorNoticeBar.txt create mode 100644 tdesign-component/example/assets/code/noticeBar._iconNoticeBar.txt create mode 100644 tdesign-component/example/assets/code/noticeBar._leftNoticeBar.txt create mode 100644 tdesign-component/example/assets/code/noticeBar._normalNoticeBar.txt create mode 100644 tdesign-component/example/assets/code/noticeBar._scrollIconNoticeBar.txt create mode 100644 tdesign-component/example/assets/code/noticeBar._scrollNoticeBar.txt create mode 100644 tdesign-component/example/assets/code/noticeBar._stepNoticeBar.txt create mode 100644 tdesign-component/example/assets/code/noticeBar._successNoticeBar.txt create mode 100644 tdesign-component/example/assets/code/noticeBar._tapNoticeBar.txt create mode 100644 tdesign-component/example/assets/code/noticeBar._textNoticeBar.txt create mode 100644 tdesign-component/example/assets/code/noticeBar._warningNoticeBar.txt create mode 100644 tdesign-component/example/assets/code/picker.buildCustomLeftRightText.txt create mode 100644 tdesign-component/example/assets/code/sideBar._buildLoadingSideBar.txt create mode 100644 tdesign-component/example/assets/code/table._basicTable.txt create mode 100644 tdesign-component/example/assets/code/table._borderTable.txt create mode 100644 tdesign-component/example/assets/code/table._centerTable.txt create mode 100644 tdesign-component/example/assets/code/table._emptyTable.txt create mode 100644 tdesign-component/example/assets/code/table._fixedEndColTable.txt create mode 100644 tdesign-component/example/assets/code/table._fixedFirstColTable.txt create mode 100644 tdesign-component/example/assets/code/table._fixedHeaderTable.txt create mode 100644 tdesign-component/example/assets/code/table._fixedScrollTable.txt create mode 100644 tdesign-component/example/assets/code/table._horizontalScrollTable.txt create mode 100644 tdesign-component/example/assets/code/table._loadingTable.txt create mode 100644 tdesign-component/example/assets/code/table._operationBtnTable.txt create mode 100644 tdesign-component/example/assets/code/table._operationIconTable.txt create mode 100644 tdesign-component/example/assets/code/table._sortableTable.txt create mode 100644 tdesign-component/example/assets/code/table._stripeTable.txt create mode 100644 tdesign-component/example/assets/code/timeCounter._buildControl.txt create mode 100644 tdesign-component/example/assets/code/timeCounter._buildCustomNum.txt create mode 100644 tdesign-component/example/assets/code/timeCounter._buildCustomUnitLargeSize.txt create mode 100644 tdesign-component/example/assets/code/timeCounter._buildCustomUnitMediumSize.txt create mode 100644 tdesign-component/example/assets/code/timeCounter._buildCustomUnitSimple.txt create mode 100644 tdesign-component/example/assets/code/timeCounter._buildCustomUnitSmallSize.txt create mode 100644 tdesign-component/example/assets/code/timeCounter._buildLargeSize.txt create mode 100644 tdesign-component/example/assets/code/timeCounter._buildMediumSize.txt create mode 100644 tdesign-component/example/assets/code/timeCounter._buildMillisecondSimple.txt create mode 100644 tdesign-component/example/assets/code/timeCounter._buildRoundLargeSize.txt create mode 100644 tdesign-component/example/assets/code/timeCounter._buildRoundMediumSize.txt create mode 100644 tdesign-component/example/assets/code/timeCounter._buildRoundSimple.txt create mode 100644 tdesign-component/example/assets/code/timeCounter._buildRoundSmallSize.txt create mode 100644 tdesign-component/example/assets/code/timeCounter._buildSimple.txt create mode 100644 tdesign-component/example/assets/code/timeCounter._buildSmallSize.txt create mode 100644 tdesign-component/example/assets/code/timeCounter._buildSquareLargeSize.txt create mode 100644 tdesign-component/example/assets/code/timeCounter._buildSquareMediumSize.txt create mode 100644 tdesign-component/example/assets/code/timeCounter._buildSquareSimple.txt create mode 100644 tdesign-component/example/assets/code/timeCounter._buildSquareSmallSize.txt create mode 100644 tdesign-component/example/assets/code/timeCounter._buildUnitLargeSize.txt create mode 100644 tdesign-component/example/assets/code/timeCounter._buildUnitMediumSize.txt create mode 100644 tdesign-component/example/assets/code/timeCounter._buildUnitSimple.txt create mode 100644 tdesign-component/example/assets/code/timeCounter._buildUnitSmallSize.txt create mode 100644 tdesign-component/example/assets/code/timeCounter._buildUpSimple.txt create mode 100644 tdesign-component/example/assets/code/toast._preventTapToast.txt create mode 100644 tdesign-site/src/indexes/README.md diff --git a/tdesign-component/example/assets/code/calendar._buildBlock.txt b/tdesign-component/example/assets/code/calendar._buildBlock.txt new file mode 100644 index 000000000..6e28cf74a --- /dev/null +++ b/tdesign-component/example/assets/code/calendar._buildBlock.txt @@ -0,0 +1,9 @@ + +Widget _buildBlock(BuildContext context) { + final size = MediaQuery.of(context).size; + return TDCalendar( + title: '请选择日期', + value: [DateTime.now().millisecondsSinceEpoch], + height: size.height * 0.6 + 176, + ); +} \ No newline at end of file diff --git a/tdesign-component/example/assets/code/calendar._buildSimple.txt b/tdesign-component/example/assets/code/calendar._buildSimple.txt new file mode 100644 index 000000000..20e961ff7 --- /dev/null +++ b/tdesign-component/example/assets/code/calendar._buildSimple.txt @@ -0,0 +1,159 @@ + +Widget _buildSimple(BuildContext context) { + final size = MediaQuery.of(context).size; + final selected = ValueNotifier>([DateTime.now().millisecondsSinceEpoch]); + return ValueListenableBuilder( + valueListenable: selected, + builder: (context, value, child) { + final date = DateTime.fromMillisecondsSinceEpoch(value[0]); + return TDCellGroup( + cells: [ + TDCell( + title: '单个选择日历', + arrow: true, + note: '${date.year}-${date.month}-${date.day}', + onClick: (cell) { + TDCalendarPopup( + context, + visible: true, + onConfirm: (value) { + print('onConfirm:$value'); + selected.value = value; + }, + onClose: () { + print('onClose'); + }, + child: TDCalendar( + title: '请选择日期', + value: value, + height: size.height * 0.6 + 176, + onCellClick: (value, type, tdate) { + print('onCellClick:$value'); + }, + onCellLongPress: (value, type, tdate) { + print('onCellLongPress:$value'); + }, + onHeanderClick: (index, week) { + print('onHeanderClick:$week'); + }, + onChange: (value) { + print('onChange:$value'); + }, + ), + ); + }, + ), + TDCell( + title: '多个选择日历', + arrow: true, + onClick: (cell) { + TDCalendarPopup( + context, + visible: true, + child: TDCalendar( + title: '请选择日期', + type: CalendarType.multiple, + value: [DateTime.now().millisecondsSinceEpoch], + height: size.height * 0.6 + 176, + ), + ); + }, + ), + TDCell( + title: '区间选择日历', + arrow: true, + onClick: (cell) { + TDCalendarPopup( + context, + visible: true, + child: TDCalendar( + title: '请选择日期区间', + type: CalendarType.range, + value: [ + DateTime.now().millisecondsSinceEpoch, + DateTime.now().add(const Duration(days: 6)).millisecondsSinceEpoch, + ], + height: size.height * 0.6 + 176, + ), + ); + }, + ), + TDCell( + title: '单个选择日历和时间', + arrow: true, + note: '${date.year}-${date.month}-${date.day} ${date.hour}:${date.minute}', + onClick: (cell) { + TDCalendarPopup( + context, + visible: true, + onConfirm: (value) { + print('onConfirm:$value'); + selected.value = value; + }, + onClose: () { + print('onClose'); + }, + child: TDCalendar( + title: '请选择日期和时间', + value: value, + height: size.height * 0.92, + useTimePicker: true, + onCellClick: (value, type, tdate) { + print('onCellClick:$value'); + }, + onCellLongPress: (value, type, tdate) { + print('onCellLongPress:$value'); + }, + onHeanderClick: (index, week) { + print('onHeanderClick:$week'); + }, + onChange: (value) { + print('onChange:$value'); + }, + ), + ); + }, + ), + TDCell( + title: '区间选择日历和时间', + arrow: true, + onClick: (cell) { + TDCalendarPopup( + context, + visible: true, + onConfirm: (value) { + print('onConfirm:$value'); + }, + onClose: () { + print('onClose'); + }, + child: TDCalendar( + title: '请选择日期和时间区间', + height: size.height * 0.92, + type: CalendarType.range, + value: [ + DateTime.now().millisecondsSinceEpoch, + DateTime.now().add(const Duration(days: 3)).millisecondsSinceEpoch, + ], + useTimePicker: true, + onCellClick: (value, type, tdate) { + print('onCellClick:$value'); + }, + onCellLongPress: (value, type, tdate) { + print('onCellLongPress:$value'); + }, + onHeanderClick: (index, week) { + print('onHeanderClick:$week'); + }, + onChange: (value) { + print('onChange:$value'); + }, + ), + ); + }, + ), + ], + ); + }, + ); +} \ No newline at end of file diff --git a/tdesign-component/example/assets/code/calendar._buildStyle.txt b/tdesign-component/example/assets/code/calendar._buildStyle.txt new file mode 100644 index 000000000..c75c1d656 --- /dev/null +++ b/tdesign-component/example/assets/code/calendar._buildStyle.txt @@ -0,0 +1,97 @@ + +Widget _buildStyle(BuildContext context) { + final size = MediaQuery.of(context).size; + const map = { + 1: '初一', + 2: '初二', + 3: '初三', + 14: '情人节', + 15: '元宵节', + }; + return TDCellGroup( + cells: [ + TDCell( + title: '自定义文案', + arrow: true, + onClick: (cell) { + TDCalendarPopup( + context, + visible: true, + child: TDCalendar( + title: '请选择日期', + height: size.height * 0.6 + 176, + minDate: DateTime(2022, 1, 1).millisecondsSinceEpoch, + maxDate: DateTime(2022, 2, 15).millisecondsSinceEpoch, + format: (day) { + day?.suffix = '¥60'; + if (day?.date.month == 2) { + if (map.keys.contains(day?.date.day)) { + day?.suffix = '¥100'; + day?.prefix = map[day.date.day]; + day?.style = TextStyle( + fontSize: TDTheme.of(context).fontTitleMedium?.size, + height: TDTheme.of(context).fontTitleMedium?.height, + fontWeight: TDTheme.of(context).fontTitleMedium?.fontWeight, + color: TDTheme.of(context).errorColor6, + ); + if (day?.typeNotifier.value == DateSelectType.selected) { + day?.style = day.style?.copyWith(color: TDTheme.of(context).fontWhColor1); + } + } + } + return null; + }, + ), + ); + }, + ), + TDCell( + title: '自定义按钮', + arrow: true, + onClick: (cell) { + late final TDCalendarPopup calendar; + calendar = TDCalendarPopup( + context, + visible: true, + confirmBtn: Padding( + padding: EdgeInsets.symmetric(vertical: TDTheme.of(context).spacer16), + child: TDButton( + theme: TDButtonTheme.danger, + shape: TDButtonShape.round, + text: 'ok', + isBlock: true, + size: TDButtonSize.large, + onTap: () { + print(calendar.selected); + calendar.close(); + }, + ), + ), + child: TDCalendar( + title: '请选择日期', + value: [DateTime.now().millisecondsSinceEpoch], + height: size.height * 0.6 + 176, + ), + ); + }, + ), + TDCell( + title: '自定义日期区间', + arrow: true, + onClick: (cell) { + TDCalendarPopup( + context, + visible: true, + child: TDCalendar( + title: '请选择日期', + minDate: DateTime(2022, 1, 1).millisecondsSinceEpoch, + maxDate: DateTime(2022, 1, 31).millisecondsSinceEpoch, + value: [DateTime(2022, 1, 15).millisecondsSinceEpoch], + height: size.height * 0.6 + 176, + ), + ); + }, + ), + ], + ); +} \ No newline at end of file diff --git a/tdesign-component/example/assets/code/cascader._buildHorizontalCompanyCascader.txt b/tdesign-component/example/assets/code/cascader._buildHorizontalCompanyCascader.txt index 37c618f5f..15b965593 100644 --- a/tdesign-component/example/assets/code/cascader._buildHorizontalCompanyCascader.txt +++ b/tdesign-component/example/assets/code/cascader._buildHorizontalCompanyCascader.txt @@ -2,7 +2,7 @@ Widget _buildHorizontalCompanyCascader(BuildContext context) { return GestureDetector( onTap: () { - TDCascader.showMultiCascader(context, title: '选择部门人员', data: _data_3, initialData: _initData_3, theme: 'tab', + TDCascader.showMultiCascader(context, title: '选择部门人员', data: _data_3,isLetterSort: true, initialData: _initData_3, theme: 'tab', onChange: (List selectData) { setState(() { List result = []; diff --git a/tdesign-component/example/assets/code/cascader._buildHorizontalLetterCascader.txt b/tdesign-component/example/assets/code/cascader._buildHorizontalLetterCascader.txt index 276900a17..c86996f7d 100644 --- a/tdesign-component/example/assets/code/cascader._buildHorizontalLetterCascader.txt +++ b/tdesign-component/example/assets/code/cascader._buildHorizontalLetterCascader.txt @@ -2,8 +2,12 @@ Widget _buildHorizontalLetterCascader(BuildContext context) { return GestureDetector( onTap: () { - TDCascader.showMultiCascader(context, title: '选择地址', data: _data_2, initialData: _initData_2, theme: 'tab', - onChange: (List selectData) { + TDCascader.showMultiCascader(context, + title: '选择地址', + data: _data_2, + initialData: _initData_2, + isLetterSort: true, + theme: 'tab', onChange: (List selectData) { setState(() { List result = []; int len = selectData.length; diff --git a/tdesign-component/example/assets/code/cascader._buildTestVerticalCompanyCascader.txt b/tdesign-component/example/assets/code/cascader._buildTestVerticalCompanyCascader.txt new file mode 100644 index 000000000..64043774d --- /dev/null +++ b/tdesign-component/example/assets/code/cascader._buildTestVerticalCompanyCascader.txt @@ -0,0 +1,25 @@ + + Widget _buildTestVerticalCompanyCascader(BuildContext context) { + return GestureDetector( + onTap: () { + TDCascader.showMultiCascader(context, + title: '选择部门人员', + data: _data_4, + initialData: _initData, + theme: 'step', onChange: (List selectData) { + setState(() { + List result = []; + int len = selectData.length; + _initData = selectData[len - 1].value!; + selectData.forEach((element) { + result.add(element.label); + }); + _selected_4 = result.join('/'); + }); + }, onClose: () { + Navigator.of(context).pop(); + }); + }, + child: _buildSelectRow(context, _selected_4, '选择部门人员'), + ); + } \ No newline at end of file diff --git a/tdesign-component/example/assets/code/cascader._buildVerticalCompanyCascader.txt b/tdesign-component/example/assets/code/cascader._buildVerticalCompanyCascader.txt index f4aa74e56..f4443ed81 100644 --- a/tdesign-component/example/assets/code/cascader._buildVerticalCompanyCascader.txt +++ b/tdesign-component/example/assets/code/cascader._buildVerticalCompanyCascader.txt @@ -2,7 +2,7 @@ Widget _buildVerticalCompanyCascader(BuildContext context) { return GestureDetector( onTap: () { - TDCascader.showMultiCascader(context, title: '选择部门人员', data: _data_3, initialData: _initData_3, theme: 'step', + TDCascader.showMultiCascader(context, title: '选择部门人员', data: _data_3,isLetterSort: true, initialData: _initData_3, theme: 'step', onChange: (List selectData) { setState(() { List result = []; diff --git a/tdesign-component/example/assets/code/cell._buildPadding.txt b/tdesign-component/example/assets/code/cell._buildPadding.txt new file mode 100644 index 000000000..e5c4bf7cd --- /dev/null +++ b/tdesign-component/example/assets/code/cell._buildPadding.txt @@ -0,0 +1,11 @@ + +Widget _buildPadding(BuildContext context) { + var style = TDCellStyle.cellStyle(context); + style.padding = const EdgeInsets.all(30); + return TDCellGroup( + theme: TDCellGroupTheme.cardTheme, + cells: [ + TDCell(arrow: true, title: 'padding-all-30', style: style,), + ], + ); +} \ No newline at end of file diff --git a/tdesign-component/example/assets/code/datetimePicker._customStartTime.txt b/tdesign-component/example/assets/code/datetimePicker._customStartTime.txt new file mode 100644 index 000000000..4a43d170a --- /dev/null +++ b/tdesign-component/example/assets/code/datetimePicker._customStartTime.txt @@ -0,0 +1,30 @@ + + Widget _customStartTime(BuildContext context) { + + return GestureDetector( + onTap: (){ + TDPicker.showDatePicker(context, title: '选择时间', + onConfirm: (selected) { + setState(() { + selected_5 = '${selected['year'].toString().padLeft(4, '0')}-' + '${selected['month'].toString().padLeft(2, '0')}-' + '${selected['day'].toString().padLeft(2, '0')} ' + '${selected['hour'].toString().padLeft(2, '0')}:' + '${selected['minute'].toString().padLeft(2, '0')}:' + '${selected['second'].toString().padLeft(2, '0')}'; + }); + Navigator.of(context).pop(); + }, + useYear: true, + useMonth: true, + useDay: true, + useHour: true, + useMinute: true, + useSecond: true, + dateStart: [2012,1, 15,12,28,11], + dateEnd: [2012, 6, 15,12,48,32], + initialDate: [2012, 1, 15,13,20]); + }, + child: buildSelectRow(context, selected_5, '选择时间'), + ); + } \ No newline at end of file diff --git a/tdesign-component/example/assets/code/dialog._customContentAndBtn.txt b/tdesign-component/example/assets/code/dialog._customContentAndBtn.txt new file mode 100644 index 000000000..f12b6d4f2 --- /dev/null +++ b/tdesign-component/example/assets/code/dialog._customContentAndBtn.txt @@ -0,0 +1,32 @@ + + Widget _customContentAndBtn(BuildContext context) { + return TDButton( + text: '自定义边距和按钮', + size: TDButtonSize.large, + type: TDButtonType.outline, + theme: TDButtonTheme.primary, + onTap: () { + showGeneralDialog( + context: context, + pageBuilder: (BuildContext buildContext, Animation animation, + Animation secondaryAnimation) { + return TDConfirmDialog( + title: _dialogTitle, + content: _commonContent, + padding: const EdgeInsets.fromLTRB(8, 8, 8, 0), + buttonWidget: Container( + padding: const EdgeInsets.fromLTRB(0, 16, 0, 16), + child: TDButton( + text: '自定义按钮', + theme: TDButtonTheme.primary, + onTap: () { + Navigator.of(context).pop(); + }, + ), + ), + ); + } + ); + } + ); + } \ No newline at end of file diff --git a/tdesign-component/example/assets/code/drawer._buildColorSimple.txt b/tdesign-component/example/assets/code/drawer._buildColorSimple.txt new file mode 100644 index 000000000..5b4109820 --- /dev/null +++ b/tdesign-component/example/assets/code/drawer._buildColorSimple.txt @@ -0,0 +1,22 @@ + +Widget _buildColorSimple(BuildContext context) { + var renderBox = navBarkey.currentContext?.findRenderObject() as RenderBox?; + return TDButton( + text: '自定义背景色', + isBlock: true, + type: TDButtonType.outline, + theme: TDButtonTheme.primary, + size: TDButtonSize.large, + onTap: () { + TDDrawer( + context, + visible: true, + drawerTop: renderBox?.size.height, + title: '标题', + backgroundColor: TDTheme.of(context).grayColor1, + placement: TDDrawerPlacement.right, + items: List.generate(10, (index) => TDDrawerItem(title: '菜单${_nums[index]}')).toList(), + ); + }, + ); +} \ No newline at end of file diff --git a/tdesign-component/example/assets/code/dropdownMenu._buildOverflow.txt b/tdesign-component/example/assets/code/dropdownMenu._buildOverflow.txt new file mode 100644 index 000000000..e1b86c72b --- /dev/null +++ b/tdesign-component/example/assets/code/dropdownMenu._buildOverflow.txt @@ -0,0 +1,71 @@ + +TDDropdownMenu _buildOverflow(BuildContext context) { + return TDDropdownMenu( + isScrollable: true, + tabBarAlign: MainAxisAlignment.spaceAround, + direction: TDDropdownMenuDirection.up, + onMenuOpened: (value) { + print('打开第$value个菜单'); + }, + onMenuClosed: (value) { + print('关闭第$value个菜单'); + }, + builder: (context) { + return [ + TDDropdownItem( + label: '最大高度限制', + multiple: true, + maxHeight: 200, + tabBarWidth: 200, + options: [ + TDDropdownItemOption(label: '选项1', value: '1', selected: true), + TDDropdownItemOption(label: '选项2', value: '2', selected: true), + TDDropdownItemOption(label: '选项3', value: '3', selected: true), + TDDropdownItemOption(label: '选项4', value: '4'), + TDDropdownItemOption(label: '选项5', value: '5'), + TDDropdownItemOption(label: '选项6', value: '6'), + TDDropdownItemOption(label: '选项7', value: '7'), + TDDropdownItemOption(label: '选项8', value: '8'), + TDDropdownItemOption(label: '选项9', value: '9'), + TDDropdownItemOption(label: '禁用选项', value: '10', disabled: true), + TDDropdownItemOption(label: '禁用选项', value: '11', disabled: true), + TDDropdownItemOption(label: '禁用选项', value: '12', disabled: true), + ], + onChange: (value) { + print('选择:$value'); + }, + ), + TDDropdownItem( + maxHeight: 200, + tabBarWidth: 200, + tabBarAlign: MainAxisAlignment.start, + options: [ + TDDropdownItemOption(label: '选项1', value: '1', selected: true), + TDDropdownItemOption(label: '选项2', value: '2'), + ], + ), + TDDropdownItem( + maxHeight: 200, + options: [ + TDDropdownItemOption(label: '选项1', value: '1', selected: true), + TDDropdownItemOption(label: '选项2', value: '2'), + ], + ), + TDDropdownItem( + maxHeight: 200, + options: [ + TDDropdownItemOption(label: '选项1', value: '1', selected: true), + TDDropdownItemOption(label: '选项2', value: '2'), + ], + ), + TDDropdownItem( + maxHeight: 200, + options: [ + TDDropdownItemOption(label: '选项1', value: '1', selected: true), + TDDropdownItemOption(label: '选项2', value: '2'), + ], + ), + ]; + }, + ); +} \ No newline at end of file diff --git a/tdesign-component/example/assets/code/image_viewer._actionImageViewer.txt b/tdesign-component/example/assets/code/image_viewer._actionImageViewer.txt index 77b74be73..d513b8d7b 100644 --- a/tdesign-component/example/assets/code/image_viewer._actionImageViewer.txt +++ b/tdesign-component/example/assets/code/image_viewer._actionImageViewer.txt @@ -1,5 +1,9 @@ Widget _actionImageViewer(BuildContext context) { + var delImages = [ + 'https://tdesign.gtimg.com/mobile/demos/swiper1.png', + 'https://tdesign.gtimg.com/mobile/demos/swiper2.png', + ]; return TDButton( type: TDButtonType.ghost, theme: TDButtonTheme.primary, @@ -9,7 +13,7 @@ onTap: () { TDImageViewer.showImageViewer( context: context, - images: images, + images: delImages, showIndex: true, deleteBtn: true, ); diff --git a/tdesign-component/example/assets/code/indexes._buildOther.txt b/tdesign-component/example/assets/code/indexes._buildOther.txt new file mode 100644 index 000000000..1ce807683 --- /dev/null +++ b/tdesign-component/example/assets/code/indexes._buildOther.txt @@ -0,0 +1,39 @@ + +Widget _buildOther(BuildContext context) { + final renderBox = navBarkey.currentContext?.findRenderObject() as RenderBox?; + final indexList = _list.map((item) => item['index'] as String).toList(); + return TDButton( + text: '胶囊索引', + isBlock: true, + size: TDButtonSize.large, + theme: TDButtonTheme.primary, + type: TDButtonType.outline, + onTap: () { + Navigator.of(context).push( + TDSlidePopupRoute( + slideTransitionFrom: SlideTransitionFrom.right, + modalTop: renderBox?.size.height, + builder: (context) { + return Container( + color: Colors.white, + child: TDIndexes( + indexList: indexList, + capsuleTheme: true, + builderContent: (context, index) { + final list = _list.firstWhere((element) => element['index'] == index)['children'] as List; + return TDCellGroup( + cells: list + .map((e) => TDCell( + title: e, + )) + .toList(), + ); + }, + ), + ); + }, + ), + ); + }, + ); +} \ No newline at end of file diff --git a/tdesign-component/example/assets/code/indexes._buildSimple.txt b/tdesign-component/example/assets/code/indexes._buildSimple.txt new file mode 100644 index 000000000..c2563b24d --- /dev/null +++ b/tdesign-component/example/assets/code/indexes._buildSimple.txt @@ -0,0 +1,38 @@ + +Widget _buildSimple(BuildContext context) { + final renderBox = navBarkey.currentContext?.findRenderObject() as RenderBox?; + final indexList = _list.map((item) => item['index'] as String).toList(); + return TDButton( + text: '基础用法', + isBlock: true, + size: TDButtonSize.large, + theme: TDButtonTheme.primary, + type: TDButtonType.outline, + onTap: () { + Navigator.of(context).push( + TDSlidePopupRoute( + slideTransitionFrom: SlideTransitionFrom.right, + modalTop: renderBox?.size.height, + builder: (context) { + return Container( + color: Colors.white, + child: TDIndexes( + indexList: indexList, + builderContent: (context, index) { + final list = _list.firstWhere((element) => element['index'] == index)['children'] as List; + return TDCellGroup( + cells: list + .map((e) => TDCell( + title: e, + )) + .toList(), + ); + }, + ), + ); + }, + ), + ); + }, + ); +} \ No newline at end of file diff --git a/tdesign-component/example/assets/code/input._inputStatusLongLabel.txt b/tdesign-component/example/assets/code/input._inputStatusLongLabel.txt index f3f6b3fb7..0548a20b2 100644 --- a/tdesign-component/example/assets/code/input._inputStatusLongLabel.txt +++ b/tdesign-component/example/assets/code/input._inputStatusLongLabel.txt @@ -3,6 +3,8 @@ return Column( children: [ TDInput( + leftInfoWidth: 80, + spacer: TDInputSpacer(iconLabelSpace: 4), leftLabel: '标签超长时最多十个字', controller: controller[18], backgroundColor: Colors.white, diff --git a/tdesign-component/example/assets/code/input._onTapOutside.txt b/tdesign-component/example/assets/code/input._onTapOutside.txt new file mode 100644 index 000000000..02be7f62c --- /dev/null +++ b/tdesign-component/example/assets/code/input._onTapOutside.txt @@ -0,0 +1,30 @@ + + Widget _onTapOutside(BuildContext context) { + var controller = TextEditingController(); + return Container( + color: Colors.yellow, + alignment: Alignment.center, + height: 90, + child: SizedBox( + height: 60, + child: TDInput( + size: TDInputSize.small, + leftLabel: '标签文字', + controller: controller, + backgroundColor: Colors.white, + hintText: '请输入文字', + onChanged: (text) { + setState(() {}); + }, + onClearTap: () { + controller.clear(); + setState(() {}); + }, + onTapOutside: (event) { + TDToast.showText('点击输入框外部区域', context: context); + print('on tap outside ${event}'); + }, + ), + ), + ); + } \ No newline at end of file diff --git a/tdesign-component/example/assets/code/input._verticalStyle.txt b/tdesign-component/example/assets/code/input._verticalStyle.txt index a29720add..03792d921 100644 --- a/tdesign-component/example/assets/code/input._verticalStyle.txt +++ b/tdesign-component/example/assets/code/input._verticalStyle.txt @@ -1,6 +1,7 @@ Widget _verticalStyle(BuildContext context) { return TDInput( + spacer: TDInputSpacer(iconLabelSpace: 0), type: TDInputType.twoLine, leftLabel: '标签文字', controller: controller[20], diff --git a/tdesign-component/example/assets/code/navbar._shadowNavbar.txt b/tdesign-component/example/assets/code/navbar._shadowNavbar.txt new file mode 100644 index 000000000..cbcc7e006 --- /dev/null +++ b/tdesign-component/example/assets/code/navbar._shadowNavbar.txt @@ -0,0 +1,17 @@ + + Widget _shadowNavbar(BuildContext context) { + return TDNavBar( + height: 48, + titleFontWeight: FontWeight.w600, + title: titleText, + screenAdaptation: false, + useDefaultBack: true, + boxShadow: [ + BoxShadow( + blurRadius: 4, + offset: const Offset(0, 4), + color: TDTheme.of(context).grayColor5, + ) + ], + ); + } \ No newline at end of file diff --git a/tdesign-component/example/assets/code/noticeBar._cardNoticeBar.txt b/tdesign-component/example/assets/code/noticeBar._cardNoticeBar.txt new file mode 100644 index 000000000..df57b978e --- /dev/null +++ b/tdesign-component/example/assets/code/noticeBar._cardNoticeBar.txt @@ -0,0 +1,54 @@ + +Widget _cardNoticeBar(BuildContext context) { + var size = MediaQuery.of(context).size; + return Container( + margin: const EdgeInsets.symmetric(horizontal: 16), + decoration: BoxDecoration( + color: TDNoticeBarStyle.generateTheme(context).backgroundColor, + borderRadius: const BorderRadius.all(Radius.circular(9)), + boxShadow: const [ + BoxShadow( + color: Color(0x0d000000), + blurRadius: 8, + spreadRadius: 2, + offset: Offset(0, 2), + ), + BoxShadow( + color: Color(0x0f000000), + blurRadius: 10, + spreadRadius: 1, + offset: Offset(0, 8), + ), + BoxShadow( + color: Color(0x1a000000), + blurRadius: 5, + spreadRadius: -3, + offset: Offset(0, 5), + ), + ], + ), + child: Column( + children: [ + Container( + width: size.width - 32, + decoration: const BoxDecoration( + borderRadius: BorderRadius.all(Radius.circular(12)), + ), + clipBehavior: Clip.hardEdge, + child: const TDNoticeBar( + context: '这是一条普通的通知信息', + prefixIcon: TDIcons.error_circle_filled, + suffixIcon: TDIcons.chevron_right, + ), + ), + Container( + height: 150, + decoration: const BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.all(Radius.circular(12)), + ), + ) + ], + ), + ); +} \ No newline at end of file diff --git a/tdesign-component/example/assets/code/noticeBar._closeNoticeBar.txt b/tdesign-component/example/assets/code/noticeBar._closeNoticeBar.txt new file mode 100644 index 000000000..72079a158 --- /dev/null +++ b/tdesign-component/example/assets/code/noticeBar._closeNoticeBar.txt @@ -0,0 +1,8 @@ + +Widget _closeNoticeBar(BuildContext context) { + return const TDNoticeBar( + context: '这是一条普通的通知信息', + prefixIcon: TDIcons.error_circle_filled, + suffixIcon: TDIcons.close, + ); +} \ No newline at end of file diff --git a/tdesign-component/example/assets/code/noticeBar._customNoticeBar.txt b/tdesign-component/example/assets/code/noticeBar._customNoticeBar.txt new file mode 100644 index 000000000..90bf32b21 --- /dev/null +++ b/tdesign-component/example/assets/code/noticeBar._customNoticeBar.txt @@ -0,0 +1,9 @@ + +Widget _customNoticeBar(BuildContext context) { + return TDNoticeBar( + context: '这是一条普通的通知信息', + prefixIcon: TDIcons.notification, + suffixIcon: TDIcons.chevron_right, + style: TDNoticeBarStyle(backgroundColor: TDTheme.of(context).grayColor3), + ); +} \ No newline at end of file diff --git a/tdesign-component/example/assets/code/noticeBar._entranceNoticeBar1.txt b/tdesign-component/example/assets/code/noticeBar._entranceNoticeBar1.txt new file mode 100644 index 000000000..500443ec4 --- /dev/null +++ b/tdesign-component/example/assets/code/noticeBar._entranceNoticeBar1.txt @@ -0,0 +1,15 @@ + +Widget _entranceNoticeBar1(BuildContext context) { + return const TDNoticeBar( + context: '这是一条普通的通知信息', + prefixIcon: TDIcons.error_circle_filled, + right: TDButton( + text: '文字按钮', + type: TDButtonType.text, + theme: TDButtonTheme.primary, + size: TDButtonSize.extraSmall, + height: 22, + padding: EdgeInsets.symmetric(vertical: 0, horizontal: 0), + ), + ); +} \ No newline at end of file diff --git a/tdesign-component/example/assets/code/noticeBar._entranceNoticeBar2.txt b/tdesign-component/example/assets/code/noticeBar._entranceNoticeBar2.txt new file mode 100644 index 000000000..40d2a5bc6 --- /dev/null +++ b/tdesign-component/example/assets/code/noticeBar._entranceNoticeBar2.txt @@ -0,0 +1,11 @@ + +Widget _entranceNoticeBar2(BuildContext context) { + return const Padding( + padding: EdgeInsets.only(top: 16), + child: TDNoticeBar( + context: '这是一条普通的通知信息', + prefixIcon: TDIcons.error_circle_filled, + suffixIcon: TDIcons.chevron_right, + ), + ); +} \ No newline at end of file diff --git a/tdesign-component/example/assets/code/noticeBar._errorNoticeBar.txt b/tdesign-component/example/assets/code/noticeBar._errorNoticeBar.txt new file mode 100644 index 000000000..831330e17 --- /dev/null +++ b/tdesign-component/example/assets/code/noticeBar._errorNoticeBar.txt @@ -0,0 +1,8 @@ + +Widget _errorNoticeBar(BuildContext context) { + return const TDNoticeBar( + context: '这是一条普通的通知信息', + prefixIcon: TDIcons.error_circle_filled, + theme: TDNoticeBarTheme.error, + ); +} \ No newline at end of file diff --git a/tdesign-component/example/assets/code/noticeBar._iconNoticeBar.txt b/tdesign-component/example/assets/code/noticeBar._iconNoticeBar.txt new file mode 100644 index 000000000..65ea94bb3 --- /dev/null +++ b/tdesign-component/example/assets/code/noticeBar._iconNoticeBar.txt @@ -0,0 +1,7 @@ + +Widget _iconNoticeBar(BuildContext context) { + return const TDNoticeBar( + context: '这是一条普通的通知信息', + prefixIcon: TDIcons.error_circle_filled, + ); +} \ No newline at end of file diff --git a/tdesign-component/example/assets/code/noticeBar._leftNoticeBar.txt b/tdesign-component/example/assets/code/noticeBar._leftNoticeBar.txt new file mode 100644 index 000000000..f8e0d026b --- /dev/null +++ b/tdesign-component/example/assets/code/noticeBar._leftNoticeBar.txt @@ -0,0 +1,15 @@ + +Widget _leftNoticeBar(BuildContext context) { + return const TDNoticeBar( + context: '这是一条普通的通知信息', + suffixIcon: TDIcons.chevron_right, + left: TDButton( + text: '文本', + type: TDButtonType.text, + theme: TDButtonTheme.primary, + size: TDButtonSize.extraSmall, + height: 22, + padding: EdgeInsets.symmetric(vertical: 0, horizontal: 0), + ), + ); +} \ No newline at end of file diff --git a/tdesign-component/example/assets/code/noticeBar._normalNoticeBar.txt b/tdesign-component/example/assets/code/noticeBar._normalNoticeBar.txt new file mode 100644 index 000000000..1fd7bd8d3 --- /dev/null +++ b/tdesign-component/example/assets/code/noticeBar._normalNoticeBar.txt @@ -0,0 +1,8 @@ + +Widget _normalNoticeBar(BuildContext context) { + return const TDNoticeBar( + context: '这是一条普通的通知信息', + prefixIcon: TDIcons.error_circle_filled, + theme: TDNoticeBarTheme.info, + ); +} \ No newline at end of file diff --git a/tdesign-component/example/assets/code/noticeBar._scrollIconNoticeBar.txt b/tdesign-component/example/assets/code/noticeBar._scrollIconNoticeBar.txt new file mode 100644 index 000000000..ad9666ec4 --- /dev/null +++ b/tdesign-component/example/assets/code/noticeBar._scrollIconNoticeBar.txt @@ -0,0 +1,12 @@ + +Widget _scrollIconNoticeBar(BuildContext context) { + return const Padding( + padding: EdgeInsets.only(top: 16), + child: TDNoticeBar( + context: '提示文字描述提示文字描述提示文字描述提示文字描述提示文字', + speed: 50, + prefixIcon: TDIcons.sound, + marquee: true, + ), + ); +} \ No newline at end of file diff --git a/tdesign-component/example/assets/code/noticeBar._scrollNoticeBar.txt b/tdesign-component/example/assets/code/noticeBar._scrollNoticeBar.txt new file mode 100644 index 000000000..ebdb515c8 --- /dev/null +++ b/tdesign-component/example/assets/code/noticeBar._scrollNoticeBar.txt @@ -0,0 +1,8 @@ + +Widget _scrollNoticeBar(BuildContext context) { + return const TDNoticeBar( + context: '提示文字描述提示文字描述提示文字描述提示文字描述提示文字', + marquee: true, + speed: 50, + ); +} \ No newline at end of file diff --git a/tdesign-component/example/assets/code/noticeBar._stepNoticeBar.txt b/tdesign-component/example/assets/code/noticeBar._stepNoticeBar.txt new file mode 100644 index 000000000..ff29ca57e --- /dev/null +++ b/tdesign-component/example/assets/code/noticeBar._stepNoticeBar.txt @@ -0,0 +1,9 @@ + +Widget _stepNoticeBar(BuildContext context) { + return const TDNoticeBar( + context: ['君不见黄河之水天上来', '奔流到海不复回', '君不见'], + direction: Axis.vertical, + prefixIcon: TDIcons.sound, + marquee: true, + ); +} \ No newline at end of file diff --git a/tdesign-component/example/assets/code/noticeBar._successNoticeBar.txt b/tdesign-component/example/assets/code/noticeBar._successNoticeBar.txt new file mode 100644 index 000000000..227263ceb --- /dev/null +++ b/tdesign-component/example/assets/code/noticeBar._successNoticeBar.txt @@ -0,0 +1,8 @@ + +Widget _successNoticeBar(BuildContext context) { + return const TDNoticeBar( + context: '这是一条普通的通知信息', + prefixIcon: TDIcons.error_circle_filled, + theme: TDNoticeBarTheme.success, + ); +} \ No newline at end of file diff --git a/tdesign-component/example/assets/code/noticeBar._tapNoticeBar.txt b/tdesign-component/example/assets/code/noticeBar._tapNoticeBar.txt new file mode 100644 index 000000000..b5f6a0b43 --- /dev/null +++ b/tdesign-component/example/assets/code/noticeBar._tapNoticeBar.txt @@ -0,0 +1,11 @@ + +Widget _tapNoticeBar(BuildContext context) { + return TDNoticeBar( + context: '这是一条普通的通知信息', + prefixIcon: TDIcons.error_circle_filled, + suffixIcon: TDIcons.chevron_right, + onTap: (trigger) { + TDToast.showText('tap:$trigger', context: context); + }, + ); +} \ No newline at end of file diff --git a/tdesign-component/example/assets/code/noticeBar._textNoticeBar.txt b/tdesign-component/example/assets/code/noticeBar._textNoticeBar.txt new file mode 100644 index 000000000..a68bb06bb --- /dev/null +++ b/tdesign-component/example/assets/code/noticeBar._textNoticeBar.txt @@ -0,0 +1,4 @@ + +Widget _textNoticeBar(BuildContext context) { + return const TDNoticeBar(context: '这是一条普通的通知信息'); +} \ No newline at end of file diff --git a/tdesign-component/example/assets/code/noticeBar._warningNoticeBar.txt b/tdesign-component/example/assets/code/noticeBar._warningNoticeBar.txt new file mode 100644 index 000000000..34b9137d4 --- /dev/null +++ b/tdesign-component/example/assets/code/noticeBar._warningNoticeBar.txt @@ -0,0 +1,8 @@ + +Widget _warningNoticeBar(BuildContext context) { + return const TDNoticeBar( + context: '这是一条普通的通知信息', + prefixIcon: TDIcons.error_circle_filled, + theme: TDNoticeBarTheme.warning, + ); +} \ No newline at end of file diff --git a/tdesign-component/example/assets/code/picker.buildCustomLeftRightText.txt b/tdesign-component/example/assets/code/picker.buildCustomLeftRightText.txt new file mode 100644 index 000000000..ff0ec571c --- /dev/null +++ b/tdesign-component/example/assets/code/picker.buildCustomLeftRightText.txt @@ -0,0 +1,35 @@ + + Widget buildCustomLeftRightText(BuildContext context) { + return Column( + children: [ + GestureDetector( + onTap: () { + TDPicker.showMultiPicker(context, + leftText: '自定义取消', + rightText: '自定义确认', + title: '基础选择器', onConfirm: (selected) { + setState(() { + selected_5 = '${data_1[selected[0]]}'; + }); + Navigator.of(context).pop(); + }, data: [data_1]); + }, + child: buildSelectRow(context, selected_5, '基础选择器'), + ), + GestureDetector( + onTap: () { + TDPicker.showMultiLinkedPicker(context, + leftText: '自定义取消', + rightText: '自定义确认', + title: '联动选择器', onConfirm: (selected) { + setState(() { + selected_3 = '${selected[0]} ${selected[1]} ${selected[2]}'; + }); + Navigator.of(context).pop(); + }, data: data_3, columnNum: 3, initialData: ['浙江省', '杭州市', '西湖区']); + }, + child: buildSelectRow(context, selected_3, '联动选择器'), + ) + ], + ); + } \ No newline at end of file diff --git a/tdesign-component/example/assets/code/radio._horizontalCardStyle.txt b/tdesign-component/example/assets/code/radio._horizontalCardStyle.txt index 125c83095..6f09ced88 100644 --- a/tdesign-component/example/assets/code/radio._horizontalCardStyle.txt +++ b/tdesign-component/example/assets/code/radio._horizontalCardStyle.txt @@ -4,6 +4,7 @@ selectId: 'index:1', cardMode: true, direction: Axis.horizontal, + rowCount: 2, directionalTdRadios: const [ TDRadio( id: 'index:0', diff --git a/tdesign-component/example/assets/code/result._buildBasicResultDefault.txt b/tdesign-component/example/assets/code/result._buildBasicResultDefault.txt index 8ea334a47..02aca64c2 100644 --- a/tdesign-component/example/assets/code/result._buildBasicResultDefault.txt +++ b/tdesign-component/example/assets/code/result._buildBasicResultDefault.txt @@ -1,4 +1,4 @@ - + TDResult _buildBasicResultDefault(BuildContext context) { return const TDResult( title: '默认状态', diff --git a/tdesign-component/example/assets/code/result._buildBasicResultError.txt b/tdesign-component/example/assets/code/result._buildBasicResultError.txt index 44d787a05..2b657efef 100644 --- a/tdesign-component/example/assets/code/result._buildBasicResultError.txt +++ b/tdesign-component/example/assets/code/result._buildBasicResultError.txt @@ -1,4 +1,4 @@ - + TDResult _buildBasicResultError(BuildContext context) { return const TDResult( title: '失败状态', diff --git a/tdesign-component/example/assets/code/result._buildBasicResultSuccess.txt b/tdesign-component/example/assets/code/result._buildBasicResultSuccess.txt index f59a5bbe8..c5d82281e 100644 --- a/tdesign-component/example/assets/code/result._buildBasicResultSuccess.txt +++ b/tdesign-component/example/assets/code/result._buildBasicResultSuccess.txt @@ -1,4 +1,4 @@ - + TDResult _buildBasicResultSuccess(BuildContext context) { return const TDResult( title: '成功状态', diff --git a/tdesign-component/example/assets/code/result._buildBasicResultWarning.txt b/tdesign-component/example/assets/code/result._buildBasicResultWarning.txt index 40d86016f..29d30c0d9 100644 --- a/tdesign-component/example/assets/code/result._buildBasicResultWarning.txt +++ b/tdesign-component/example/assets/code/result._buildBasicResultWarning.txt @@ -1,4 +1,4 @@ - + TDResult _buildBasicResultWarning(BuildContext context) { return const TDResult( title: '警示状态', diff --git a/tdesign-component/example/assets/code/result._buildCustomResultContent.txt b/tdesign-component/example/assets/code/result._buildCustomResultContent.txt index 4aab5bec2..ae24433bd 100644 --- a/tdesign-component/example/assets/code/result._buildCustomResultContent.txt +++ b/tdesign-component/example/assets/code/result._buildCustomResultContent.txt @@ -1,7 +1,8 @@ - Widget _buildCustomResult(BuildContext context) { + TDResult _buildCustomResultContent(BuildContext context) { return TDResult( - title: '自定义结果', - icon: Image.asset('assets/img/illustration.png'), - description: '描述文字'); + title: '自定义结果', + icon: Image.asset('assets/img/illustration.png'), + description: '描述文字', + ); } \ No newline at end of file diff --git a/tdesign-component/example/assets/code/result._buildResultWithDescriptionDefault.txt b/tdesign-component/example/assets/code/result._buildResultWithDescriptionDefault.txt index 3fee21945..a3dea4fa6 100644 --- a/tdesign-component/example/assets/code/result._buildResultWithDescriptionDefault.txt +++ b/tdesign-component/example/assets/code/result._buildResultWithDescriptionDefault.txt @@ -1,4 +1,4 @@ - + TDResult _buildResultWithDescriptionDefault(BuildContext context) { return const TDResult( title: '默认状态', diff --git a/tdesign-component/example/assets/code/result._buildResultWithDescriptionError.txt b/tdesign-component/example/assets/code/result._buildResultWithDescriptionError.txt index c0740422a..d690ab258 100644 --- a/tdesign-component/example/assets/code/result._buildResultWithDescriptionError.txt +++ b/tdesign-component/example/assets/code/result._buildResultWithDescriptionError.txt @@ -1,4 +1,4 @@ - + TDResult _buildResultWithDescriptionError(BuildContext context) { return const TDResult( title: '失败状态', diff --git a/tdesign-component/example/assets/code/result._buildResultWithDescriptionSuccess.txt b/tdesign-component/example/assets/code/result._buildResultWithDescriptionSuccess.txt index 48522d226..2405d702b 100644 --- a/tdesign-component/example/assets/code/result._buildResultWithDescriptionSuccess.txt +++ b/tdesign-component/example/assets/code/result._buildResultWithDescriptionSuccess.txt @@ -1,4 +1,4 @@ - + TDResult _buildResultWithDescriptionSuccess(BuildContext context) { return const TDResult( title: '成功状态', diff --git a/tdesign-component/example/assets/code/result._buildResultWithDescriptionWarning.txt b/tdesign-component/example/assets/code/result._buildResultWithDescriptionWarning.txt index dde3581e5..a5ef713b5 100644 --- a/tdesign-component/example/assets/code/result._buildResultWithDescriptionWarning.txt +++ b/tdesign-component/example/assets/code/result._buildResultWithDescriptionWarning.txt @@ -1,4 +1,4 @@ - + TDResult _buildResultWithDescriptionWarning(BuildContext context) { return const TDResult( title: '警示状态', diff --git a/tdesign-component/example/assets/code/search._buildFocusSearchBarWithAction.txt b/tdesign-component/example/assets/code/search._buildFocusSearchBarWithAction.txt index 95050bcea..79934dc70 100644 --- a/tdesign-component/example/assets/code/search._buildFocusSearchBarWithAction.txt +++ b/tdesign-component/example/assets/code/search._buildFocusSearchBarWithAction.txt @@ -5,7 +5,7 @@ action: '搜索', needCancel: true, controller: inputController, - onActionClick: () { + onActionClick: (value) { showGeneralDialog( context: context, pageBuilder: (BuildContext buildContext, Animation animation, diff --git a/tdesign-component/example/assets/code/search._buildSearchBarWithAction.txt b/tdesign-component/example/assets/code/search._buildSearchBarWithAction.txt index bfab4d164..0a7ccf922 100644 --- a/tdesign-component/example/assets/code/search._buildSearchBarWithAction.txt +++ b/tdesign-component/example/assets/code/search._buildSearchBarWithAction.txt @@ -1,30 +1,30 @@ - - Widget _buildSearchBarWithAction(BuildContext context) { - return Column( - children: [ - TDSearchBar( - placeHolder: '搜索预设文案', - alignment: TDSearchAlignment.left, - action: '搜索', - onActionClick: (String text) { - setState(() { - searchText = text; - }); - }, - onTextChanged: (String text) { - setState(() { - inputText = text; - }); - }, - ), - const SizedBox(height: 10,), - Container( - padding: const EdgeInsets.only(left: 15), - alignment: Alignment.centerLeft, - child: TDText( - '搜索框输入的内容:${searchText ?? ''}', - ), - ) - ], - ); + + Widget _buildSearchBarWithAction(BuildContext context) { + return Column( + children: [ + TDSearchBar( + placeHolder: '搜索预设文案', + alignment: TDSearchAlignment.left, + action: '搜索', + onActionClick: (String text) { + setState(() { + searchText = text; + }); + }, + onTextChanged: (String text) { + setState(() { + inputText = text; + }); + }, + ), + const SizedBox(height: 10,), + Container( + padding: const EdgeInsets.only(left: 15), + alignment: Alignment.centerLeft, + child: TDText( + '搜索框输入的内容:${searchText ?? ''}', + ), + ) + ], + ); } \ No newline at end of file diff --git a/tdesign-component/example/assets/code/sideBar._buildLoadingSideBar.txt b/tdesign-component/example/assets/code/sideBar._buildLoadingSideBar.txt new file mode 100644 index 000000000..a137c9589 --- /dev/null +++ b/tdesign-component/example/assets/code/sideBar._buildLoadingSideBar.txt @@ -0,0 +1,41 @@ + + Widget _buildLoadingSideBar(BuildContext context) { + // 延迟加载 + Future.delayed(const Duration(seconds: 3), _initData); + var size = MediaQuery.of(context).size; + var demoHeight = size.height; + + return Row( + children: [ + SizedBox( + width: list.isEmpty ? size.width : 110, + child: TDSideBar( + height: demoHeight, + style: TDSideBarStyle.normal, + value: currentValue, + controller: _sideBarController, + loading: true, + children: list + .map((ele) => TDSideBarItem( + label: ele.label ?? '', + badge: ele.badge, + value: ele.value, + icon: ele.icon)) + .toList(), + onChanged: onChanged, + onSelected: onSelected, + ), + ), + Expanded( + child: SizedBox( + height: demoHeight, + child: SingleChildScrollView( + controller: _demoScroller, + child: Column( + children: pages, + ), + ), + )) + ], + ); + } \ No newline at end of file diff --git a/tdesign-component/example/assets/code/table._basicTable.txt b/tdesign-component/example/assets/code/table._basicTable.txt new file mode 100644 index 000000000..b66105746 --- /dev/null +++ b/tdesign-component/example/assets/code/table._basicTable.txt @@ -0,0 +1,12 @@ + + Widget _basicTable(BuildContext context) { + return TDTable( + columns: [ + TDTableCol(title: '标题', colKey: 'title1', ellipsis: true), + TDTableCol(title: '标题', colKey: 'title2'), + TDTableCol(title: '标题', colKey: 'title3'), + TDTableCol(title: '标题', colKey: 'title4') + ], + data: _getData(9), + ); + } \ No newline at end of file diff --git a/tdesign-component/example/assets/code/table._borderTable.txt b/tdesign-component/example/assets/code/table._borderTable.txt new file mode 100644 index 000000000..82b1f433a --- /dev/null +++ b/tdesign-component/example/assets/code/table._borderTable.txt @@ -0,0 +1,13 @@ + + Widget _borderTable(BuildContext context) { + return TDTable( + bordered: true, + columns: [ + TDTableCol(title: '标题', colKey: 'title1', ellipsis: true), + TDTableCol(title: '标题', colKey: 'title2'), + TDTableCol(title: '标题', colKey: 'title3'), + TDTableCol(title: '标题', colKey: 'title4') + ], + data: _getData(9), + ); + } \ No newline at end of file diff --git a/tdesign-component/example/assets/code/table._centerTable.txt b/tdesign-component/example/assets/code/table._centerTable.txt new file mode 100644 index 000000000..8bbe11c9f --- /dev/null +++ b/tdesign-component/example/assets/code/table._centerTable.txt @@ -0,0 +1,12 @@ + + Widget _centerTable(BuildContext context) { + return TDTable( + columns: [ + TDTableCol(title: '标题', colKey: 'title1', align: TDTableColAlign.center), + TDTableCol(title: '标题', colKey: 'title2', align: TDTableColAlign.center), + TDTableCol(title: '标题', colKey: 'title3', align: TDTableColAlign.center), + TDTableCol(title: '标题', colKey: 'title4', align: TDTableColAlign.center) + ], + data: _getData(10), + ); + } \ No newline at end of file diff --git a/tdesign-component/example/assets/code/table._emptyTable.txt b/tdesign-component/example/assets/code/table._emptyTable.txt new file mode 100644 index 000000000..8b0ce5ce3 --- /dev/null +++ b/tdesign-component/example/assets/code/table._emptyTable.txt @@ -0,0 +1,11 @@ + + Widget _emptyTable(BuildContext context) { + return TDTable( + columns: [ + TDTableCol(title: '标题', colKey: 'title1'), + TDTableCol(title: '标题', colKey: 'title2'), + TDTableCol(title: '标题', colKey: 'title3'), + TDTableCol(title: '标题', colKey: 'title4') + ], + ); + } \ No newline at end of file diff --git a/tdesign-component/example/assets/code/table._fixedEndColTable.txt b/tdesign-component/example/assets/code/table._fixedEndColTable.txt new file mode 100644 index 000000000..792c69a63 --- /dev/null +++ b/tdesign-component/example/assets/code/table._fixedEndColTable.txt @@ -0,0 +1,37 @@ + + Widget _fixedEndColTable(BuildContext context) { + return TDTable( + columns: [ + TDTableCol(title: '标题', colKey: 'title1'), + TDTableCol(title: '标题', colKey: 'title2'), + TDTableCol(title: '标题', colKey: 'title3'), + TDTableCol( + title: '标题', + colKey: 'title4', + fixed: TDTableColFixed.right, + cellBuilder: (BuildContext context) { + return Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + TDText( + '修改', + style: TextStyle( + color: TDTheme.of(context).brandNormalColor, + fontSize: 14, + ), + ), + TDText( + '通过', + style: TextStyle( + color: TDTheme.of(context).brandNormalColor, + fontSize: 14, + ), + ), + ], + ); + }, + ), + ], + data: _getData(10), + ); + } \ No newline at end of file diff --git a/tdesign-component/example/assets/code/table._fixedFirstColTable.txt b/tdesign-component/example/assets/code/table._fixedFirstColTable.txt new file mode 100644 index 000000000..fb6fd8b71 --- /dev/null +++ b/tdesign-component/example/assets/code/table._fixedFirstColTable.txt @@ -0,0 +1,12 @@ + + Widget _fixedFirstColTable(BuildContext context) { + return TDTable( + columns: [ + TDTableCol(title: '标题', colKey: 'title1'), + TDTableCol(title: '标题', colKey: 'title2'), + TDTableCol(title: '标题', colKey: 'title3'), + TDTableCol(title: '标题', colKey: 'title4', fixed: TDTableColFixed.left), + ], + data: _getData(10), + ); + } \ No newline at end of file diff --git a/tdesign-component/example/assets/code/table._fixedHeaderTable.txt b/tdesign-component/example/assets/code/table._fixedHeaderTable.txt new file mode 100644 index 000000000..10b24f605 --- /dev/null +++ b/tdesign-component/example/assets/code/table._fixedHeaderTable.txt @@ -0,0 +1,14 @@ + + Widget _fixedHeaderTable(BuildContext context) { + return TDTable( + bordered: true, + height: 240, + columns: [ + TDTableCol(title: '标题', colKey: 'title1', ellipsis: true), + TDTableCol(title: '标题', colKey: 'title2'), + TDTableCol(title: '标题', colKey: 'title3'), + TDTableCol(title: '标题', colKey: 'title4') + ], + data: _getData(9), + ); + } \ No newline at end of file diff --git a/tdesign-component/example/assets/code/table._fixedScrollTable.txt b/tdesign-component/example/assets/code/table._fixedScrollTable.txt new file mode 100644 index 000000000..b85cb633a --- /dev/null +++ b/tdesign-component/example/assets/code/table._fixedScrollTable.txt @@ -0,0 +1,37 @@ + + Widget _fixedScrollTable(BuildContext context) { + return TDTable( + columns: [ + TDTableCol(title: '标题', colKey: 'title1', width: 200), + TDTableCol(title: '标题', colKey: 'title2', width: 160), + TDTableCol(title: '标题', colKey: 'title3', width: 160), + TDTableCol( + title: '标题', + colKey: 'title4', + fixed: TDTableColFixed.right, + cellBuilder: (BuildContext context) { + return Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + TDText( + '修改', + style: TextStyle( + color: TDTheme.of(context).brandNormalColor, + fontSize: 14, + ), + ), + TDText( + '通过', + style: TextStyle( + color: TDTheme.of(context).brandNormalColor, + fontSize: 14, + ), + ), + ], + ); + }, + ), + ], + data: _getData2(), + ); + } \ No newline at end of file diff --git a/tdesign-component/example/assets/code/table._horizontalScrollTable.txt b/tdesign-component/example/assets/code/table._horizontalScrollTable.txt new file mode 100644 index 000000000..7c286f690 --- /dev/null +++ b/tdesign-component/example/assets/code/table._horizontalScrollTable.txt @@ -0,0 +1,11 @@ + + Widget _horizontalScrollTable(BuildContext context) { + return TDTable( + columns: [ + TDTableCol(title: '标题', colKey: 'title1', width: 160), + TDTableCol(title: '标题', colKey: 'title2', width: 160), + TDTableCol(title: '标题', colKey: 'title3', width: 160), + ], + data: _getData2(), + ); + } \ No newline at end of file diff --git a/tdesign-component/example/assets/code/table._loadingTable.txt b/tdesign-component/example/assets/code/table._loadingTable.txt new file mode 100644 index 000000000..081f3d06c --- /dev/null +++ b/tdesign-component/example/assets/code/table._loadingTable.txt @@ -0,0 +1,12 @@ + + Widget _loadingTable(BuildContext context) { + return TDTable( + columns: [ + TDTableCol(title: '标题', colKey: 'title1'), + TDTableCol(title: '标题', colKey: 'title2'), + TDTableCol(title: '标题', colKey: 'title3'), + TDTableCol(title: '标题', colKey: 'title4') + ], + loading: true, + ); + } \ No newline at end of file diff --git a/tdesign-component/example/assets/code/table._operationBtnTable.txt b/tdesign-component/example/assets/code/table._operationBtnTable.txt new file mode 100644 index 000000000..d14017e63 --- /dev/null +++ b/tdesign-component/example/assets/code/table._operationBtnTable.txt @@ -0,0 +1,40 @@ + + Widget _operationBtnTable(BuildContext context) { + return TDTable( + columns: [ + TDTableCol(title: '标题', colKey: 'title1', ellipsis: true), + TDTableCol(title: '标题', colKey: 'title2'), + TDTableCol(title: '标题', colKey: 'title3'), + TDTableCol( + title: '标题', + colKey: 'title4', + cellBuilder: (BuildContext context) { + return Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + TDText( + '修改', + forceVerticalCenter: true, + style: TextStyle( + color: TDTheme.of(context).brandNormalColor, + fontSize: 14, + height: 1, + ), + ), + TDText( + '通过', + forceVerticalCenter: true, + style: TextStyle( + color: TDTheme.of(context).brandNormalColor, + fontSize: 14, + height: 1, + ), + ), + ], + ); + }, + ) + ], + data: _getData(9), + ); + } \ No newline at end of file diff --git a/tdesign-component/example/assets/code/table._operationIconTable.txt b/tdesign-component/example/assets/code/table._operationIconTable.txt new file mode 100644 index 000000000..3e09aa7d4 --- /dev/null +++ b/tdesign-component/example/assets/code/table._operationIconTable.txt @@ -0,0 +1,24 @@ + + Widget _operationIconTable(BuildContext context) { + return TDTable( + columns: [ + TDTableCol(title: '标题', colKey: 'title1', ellipsis: true), + TDTableCol(title: '标题', colKey: 'title2'), + TDTableCol(title: '标题', colKey: 'title3'), + TDTableCol( + title: '标题', + colKey: 'title4', + cellBuilder: (BuildContext context) { + return Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Icon(TDIcons.upload, color: TDTheme.of(context).brandNormalColor, size: 16), + Icon(TDIcons.delete, color: TDTheme.of(context).brandNormalColor, size: 16), + ], + ); + }, + ) + ], + data: _getData(9), + ); + } \ No newline at end of file diff --git a/tdesign-component/example/assets/code/table._sortableTable.txt b/tdesign-component/example/assets/code/table._sortableTable.txt new file mode 100644 index 000000000..45d02a01b --- /dev/null +++ b/tdesign-component/example/assets/code/table._sortableTable.txt @@ -0,0 +1,12 @@ + + Widget _sortableTable(BuildContext context) { + return TDTable( + columns: [ + TDTableCol(title: '标题', colKey: 'title1', ellipsis: true, sortable: true), + TDTableCol(title: '标题', colKey: 'title2', sortable: true), + TDTableCol(title: '标题', colKey: 'title3', sortable: true), + TDTableCol(title: '标题', colKey: 'title4', sortable: true) + ], + data: _getData(9), + ); + } \ No newline at end of file diff --git a/tdesign-component/example/assets/code/table._stripeTable.txt b/tdesign-component/example/assets/code/table._stripeTable.txt new file mode 100644 index 000000000..72d669925 --- /dev/null +++ b/tdesign-component/example/assets/code/table._stripeTable.txt @@ -0,0 +1,13 @@ + + Widget _stripeTable(BuildContext context) { + return TDTable( + stripe: true, + columns: [ + TDTableCol(title: '标题', colKey: 'title1', ellipsis: true), + TDTableCol(title: '标题', colKey: 'title2'), + TDTableCol(title: '标题', colKey: 'title3'), + TDTableCol(title: '标题', colKey: 'title4') + ], + data: _getData(9), + ); + } \ No newline at end of file diff --git a/tdesign-component/example/assets/code/timeCounter._buildControl.txt b/tdesign-component/example/assets/code/timeCounter._buildControl.txt new file mode 100644 index 000000000..fa9fe57b2 --- /dev/null +++ b/tdesign-component/example/assets/code/timeCounter._buildControl.txt @@ -0,0 +1,60 @@ + +Widget _buildControl(BuildContext context) { + var controller = TDTimeCounterController(); + return Wrap( + direction: Axis.vertical, + spacing: 8, + children: [ + Wrap( + spacing: 8, + children: [ + TDButton( + text: '开始', + size: TDButtonSize.extraSmall, + theme: TDButtonTheme.primary, + onTap: () { + controller.start(); + }, + ), + TDButton( + text: '结束', + size: TDButtonSize.extraSmall, + theme: TDButtonTheme.primary, + onTap: () { + controller.reset(0); + }, + ), + TDButton( + text: '重置', + size: TDButtonSize.extraSmall, + theme: TDButtonTheme.primary, + onTap: () { + controller.reset(); + }, + ), + TDButton( + text: '暂停', + size: TDButtonSize.extraSmall, + theme: TDButtonTheme.primary, + onTap: () { + controller.pause(); + }, + ), + TDButton( + text: '继续', + size: TDButtonSize.extraSmall, + theme: TDButtonTheme.primary, + onTap: () { + controller.resume(); + }, + ), + ], + ), + TDTimeCounter( + time: 60 * 60 * 1000, + controller: controller, + // autoStart: false, + ), + ], + ); +} \ No newline at end of file diff --git a/tdesign-component/example/assets/code/timeCounter._buildCustomNum.txt b/tdesign-component/example/assets/code/timeCounter._buildCustomNum.txt new file mode 100644 index 000000000..beed84e3a --- /dev/null +++ b/tdesign-component/example/assets/code/timeCounter._buildCustomNum.txt @@ -0,0 +1,7 @@ + +TDTimeCounter _buildCustomNum(BuildContext context) { + return const TDTimeCounter( + time: 2000 * 60 * 1000, + format: 'mmmmmmm分sss秒', + ); +} \ No newline at end of file diff --git a/tdesign-component/example/assets/code/timeCounter._buildCustomUnitLargeSize.txt b/tdesign-component/example/assets/code/timeCounter._buildCustomUnitLargeSize.txt new file mode 100644 index 000000000..e1189ab90 --- /dev/null +++ b/tdesign-component/example/assets/code/timeCounter._buildCustomUnitLargeSize.txt @@ -0,0 +1,10 @@ + +TDTimeCounter _buildCustomUnitLargeSize(BuildContext context) { + var style = TDTimeCounterStyle.generateStyle(context, size: TDTimeCounterSize.large); + style.timeColor = TDTheme.of(context).errorColor6; + return TDTimeCounter( + time: 60 * 60 * 1000, + splitWithUnit: true, + style: style, + ); +} \ No newline at end of file diff --git a/tdesign-component/example/assets/code/timeCounter._buildCustomUnitMediumSize.txt b/tdesign-component/example/assets/code/timeCounter._buildCustomUnitMediumSize.txt new file mode 100644 index 000000000..b8ce13c60 --- /dev/null +++ b/tdesign-component/example/assets/code/timeCounter._buildCustomUnitMediumSize.txt @@ -0,0 +1,10 @@ + +TDTimeCounter _buildCustomUnitMediumSize(BuildContext context) { + var style = TDTimeCounterStyle.generateStyle(context, size: TDTimeCounterSize.medium); + style.timeColor = TDTheme.of(context).errorColor6; + return TDTimeCounter( + time: 60 * 60 * 1000, + splitWithUnit: true, + style: style, + ); +} \ No newline at end of file diff --git a/tdesign-component/example/assets/code/timeCounter._buildCustomUnitSimple.txt b/tdesign-component/example/assets/code/timeCounter._buildCustomUnitSimple.txt new file mode 100644 index 000000000..7ec660046 --- /dev/null +++ b/tdesign-component/example/assets/code/timeCounter._buildCustomUnitSimple.txt @@ -0,0 +1,6 @@ + +TDTimeCounter _buildCustomUnitSimple(BuildContext context) { + var style = TDTimeCounterStyle.generateStyle(context); + style.timeColor = TDTheme.of(context).errorColor6; + return TDTimeCounter(time: 60 * 60 * 1000, splitWithUnit: true, style: style); +} \ No newline at end of file diff --git a/tdesign-component/example/assets/code/timeCounter._buildCustomUnitSmallSize.txt b/tdesign-component/example/assets/code/timeCounter._buildCustomUnitSmallSize.txt new file mode 100644 index 000000000..f164f750d --- /dev/null +++ b/tdesign-component/example/assets/code/timeCounter._buildCustomUnitSmallSize.txt @@ -0,0 +1,10 @@ + +TDTimeCounter _buildCustomUnitSmallSize(BuildContext context) { + var style = TDTimeCounterStyle.generateStyle(context, size: TDTimeCounterSize.small); + style.timeColor = TDTheme.of(context).errorColor6; + return TDTimeCounter( + time: 60 * 60 * 1000, + splitWithUnit: true, + style: style, + ); +} \ No newline at end of file diff --git a/tdesign-component/example/assets/code/timeCounter._buildLargeSize.txt b/tdesign-component/example/assets/code/timeCounter._buildLargeSize.txt new file mode 100644 index 000000000..7c4bcf4c8 --- /dev/null +++ b/tdesign-component/example/assets/code/timeCounter._buildLargeSize.txt @@ -0,0 +1,7 @@ + +TDTimeCounter _buildLargeSize(BuildContext context) { + return const TDTimeCounter( + time: 60 * 60 * 1000, + size: TDTimeCounterSize.large, + ); +} \ No newline at end of file diff --git a/tdesign-component/example/assets/code/timeCounter._buildMediumSize.txt b/tdesign-component/example/assets/code/timeCounter._buildMediumSize.txt new file mode 100644 index 000000000..2f97c30f2 --- /dev/null +++ b/tdesign-component/example/assets/code/timeCounter._buildMediumSize.txt @@ -0,0 +1,7 @@ + +TDTimeCounter _buildMediumSize(BuildContext context) { + return const TDTimeCounter( + time: 60 * 60 * 1000, + size: TDTimeCounterSize.medium, + ); +} \ No newline at end of file diff --git a/tdesign-component/example/assets/code/timeCounter._buildMillisecondSimple.txt b/tdesign-component/example/assets/code/timeCounter._buildMillisecondSimple.txt new file mode 100644 index 000000000..341aeb12e --- /dev/null +++ b/tdesign-component/example/assets/code/timeCounter._buildMillisecondSimple.txt @@ -0,0 +1,4 @@ + +TDTimeCounter _buildMillisecondSimple(BuildContext context) { + return const TDTimeCounter(time: 60 * 60 * 1000, millisecond: true); +} \ No newline at end of file diff --git a/tdesign-component/example/assets/code/timeCounter._buildRoundLargeSize.txt b/tdesign-component/example/assets/code/timeCounter._buildRoundLargeSize.txt new file mode 100644 index 000000000..768c718d3 --- /dev/null +++ b/tdesign-component/example/assets/code/timeCounter._buildRoundLargeSize.txt @@ -0,0 +1,8 @@ + +TDTimeCounter _buildRoundLargeSize(BuildContext context) { + return const TDTimeCounter( + time: 60 * 60 * 1000, + size: TDTimeCounterSize.large, + theme: TDTimeCounterTheme.round, + ); +} \ No newline at end of file diff --git a/tdesign-component/example/assets/code/timeCounter._buildRoundMediumSize.txt b/tdesign-component/example/assets/code/timeCounter._buildRoundMediumSize.txt new file mode 100644 index 000000000..3bb10ef22 --- /dev/null +++ b/tdesign-component/example/assets/code/timeCounter._buildRoundMediumSize.txt @@ -0,0 +1,8 @@ + +TDTimeCounter _buildRoundMediumSize(BuildContext context) { + return const TDTimeCounter( + time: 60 * 60 * 1000, + size: TDTimeCounterSize.medium, + theme: TDTimeCounterTheme.round, + ); +} \ No newline at end of file diff --git a/tdesign-component/example/assets/code/timeCounter._buildRoundSimple.txt b/tdesign-component/example/assets/code/timeCounter._buildRoundSimple.txt new file mode 100644 index 000000000..87f879b32 --- /dev/null +++ b/tdesign-component/example/assets/code/timeCounter._buildRoundSimple.txt @@ -0,0 +1,4 @@ + +TDTimeCounter _buildRoundSimple(BuildContext context) { + return const TDTimeCounter(time: 60 * 60 * 1000, theme: TDTimeCounterTheme.round); +} \ No newline at end of file diff --git a/tdesign-component/example/assets/code/timeCounter._buildRoundSmallSize.txt b/tdesign-component/example/assets/code/timeCounter._buildRoundSmallSize.txt new file mode 100644 index 000000000..4bc0a95c9 --- /dev/null +++ b/tdesign-component/example/assets/code/timeCounter._buildRoundSmallSize.txt @@ -0,0 +1,8 @@ + +TDTimeCounter _buildRoundSmallSize(BuildContext context) { + return const TDTimeCounter( + time: 60 * 60 * 1000, + size: TDTimeCounterSize.small, + theme: TDTimeCounterTheme.round, + ); +} \ No newline at end of file diff --git a/tdesign-component/example/assets/code/timeCounter._buildSimple.txt b/tdesign-component/example/assets/code/timeCounter._buildSimple.txt new file mode 100644 index 000000000..95273fbbd --- /dev/null +++ b/tdesign-component/example/assets/code/timeCounter._buildSimple.txt @@ -0,0 +1,4 @@ + +TDTimeCounter _buildSimple(BuildContext context) { + return const TDTimeCounter(time: 60 * 60 * 1000); +} \ No newline at end of file diff --git a/tdesign-component/example/assets/code/timeCounter._buildSmallSize.txt b/tdesign-component/example/assets/code/timeCounter._buildSmallSize.txt new file mode 100644 index 000000000..89c9ff579 --- /dev/null +++ b/tdesign-component/example/assets/code/timeCounter._buildSmallSize.txt @@ -0,0 +1,7 @@ + +TDTimeCounter _buildSmallSize(BuildContext context) { + return const TDTimeCounter( + time: 60 * 60 * 1000, + size: TDTimeCounterSize.small, + ); +} \ No newline at end of file diff --git a/tdesign-component/example/assets/code/timeCounter._buildSquareLargeSize.txt b/tdesign-component/example/assets/code/timeCounter._buildSquareLargeSize.txt new file mode 100644 index 000000000..ab190a089 --- /dev/null +++ b/tdesign-component/example/assets/code/timeCounter._buildSquareLargeSize.txt @@ -0,0 +1,8 @@ + +TDTimeCounter _buildSquareLargeSize(BuildContext context) { + return const TDTimeCounter( + time: 60 * 60 * 1000, + size: TDTimeCounterSize.large, + theme: TDTimeCounterTheme.square, + ); +} \ No newline at end of file diff --git a/tdesign-component/example/assets/code/timeCounter._buildSquareMediumSize.txt b/tdesign-component/example/assets/code/timeCounter._buildSquareMediumSize.txt new file mode 100644 index 000000000..b484e694b --- /dev/null +++ b/tdesign-component/example/assets/code/timeCounter._buildSquareMediumSize.txt @@ -0,0 +1,8 @@ + +TDTimeCounter _buildSquareMediumSize(BuildContext context) { + return const TDTimeCounter( + time: 60 * 60 * 1000, + size: TDTimeCounterSize.medium, + theme: TDTimeCounterTheme.square, + ); +} \ No newline at end of file diff --git a/tdesign-component/example/assets/code/timeCounter._buildSquareSimple.txt b/tdesign-component/example/assets/code/timeCounter._buildSquareSimple.txt new file mode 100644 index 000000000..fbdabeb7a --- /dev/null +++ b/tdesign-component/example/assets/code/timeCounter._buildSquareSimple.txt @@ -0,0 +1,4 @@ + +TDTimeCounter _buildSquareSimple(BuildContext context) { + return const TDTimeCounter(time: 60 * 60 * 1000, theme: TDTimeCounterTheme.square); +} \ No newline at end of file diff --git a/tdesign-component/example/assets/code/timeCounter._buildSquareSmallSize.txt b/tdesign-component/example/assets/code/timeCounter._buildSquareSmallSize.txt new file mode 100644 index 000000000..b71918c80 --- /dev/null +++ b/tdesign-component/example/assets/code/timeCounter._buildSquareSmallSize.txt @@ -0,0 +1,8 @@ + +TDTimeCounter _buildSquareSmallSize(BuildContext context) { + return const TDTimeCounter( + time: 60 * 60 * 1000, + size: TDTimeCounterSize.small, + theme: TDTimeCounterTheme.square, + ); +} \ No newline at end of file diff --git a/tdesign-component/example/assets/code/timeCounter._buildUnitLargeSize.txt b/tdesign-component/example/assets/code/timeCounter._buildUnitLargeSize.txt new file mode 100644 index 000000000..9ae518ea0 --- /dev/null +++ b/tdesign-component/example/assets/code/timeCounter._buildUnitLargeSize.txt @@ -0,0 +1,9 @@ + +TDTimeCounter _buildUnitLargeSize(BuildContext context) { + return const TDTimeCounter( + time: 60 * 60 * 1000, + size: TDTimeCounterSize.large, + theme: TDTimeCounterTheme.square, + splitWithUnit: true, + ); +} \ No newline at end of file diff --git a/tdesign-component/example/assets/code/timeCounter._buildUnitMediumSize.txt b/tdesign-component/example/assets/code/timeCounter._buildUnitMediumSize.txt new file mode 100644 index 000000000..04f480130 --- /dev/null +++ b/tdesign-component/example/assets/code/timeCounter._buildUnitMediumSize.txt @@ -0,0 +1,9 @@ + +TDTimeCounter _buildUnitMediumSize(BuildContext context) { + return const TDTimeCounter( + time: 60 * 60 * 1000, + size: TDTimeCounterSize.medium, + theme: TDTimeCounterTheme.square, + splitWithUnit: true, + ); +} \ No newline at end of file diff --git a/tdesign-component/example/assets/code/timeCounter._buildUnitSimple.txt b/tdesign-component/example/assets/code/timeCounter._buildUnitSimple.txt new file mode 100644 index 000000000..cab7f72cd --- /dev/null +++ b/tdesign-component/example/assets/code/timeCounter._buildUnitSimple.txt @@ -0,0 +1,4 @@ + +TDTimeCounter _buildUnitSimple(BuildContext context) { + return const TDTimeCounter(time: 60 * 60 * 1000, theme: TDTimeCounterTheme.square, splitWithUnit: true); +} \ No newline at end of file diff --git a/tdesign-component/example/assets/code/timeCounter._buildUnitSmallSize.txt b/tdesign-component/example/assets/code/timeCounter._buildUnitSmallSize.txt new file mode 100644 index 000000000..c762a3c5f --- /dev/null +++ b/tdesign-component/example/assets/code/timeCounter._buildUnitSmallSize.txt @@ -0,0 +1,9 @@ + +TDTimeCounter _buildUnitSmallSize(BuildContext context) { + return const TDTimeCounter( + time: 60 * 60 * 1000, + size: TDTimeCounterSize.small, + theme: TDTimeCounterTheme.square, + splitWithUnit: true, + ); +} \ No newline at end of file diff --git a/tdesign-component/example/assets/code/timeCounter._buildUpSimple.txt b/tdesign-component/example/assets/code/timeCounter._buildUpSimple.txt new file mode 100644 index 000000000..a090d55a1 --- /dev/null +++ b/tdesign-component/example/assets/code/timeCounter._buildUpSimple.txt @@ -0,0 +1,8 @@ + +TDTimeCounter _buildUpSimple(BuildContext context) { + return const TDTimeCounter( + time: 60 * 60 * 1000, + millisecond: true, + direction: TDTimeCounterDirection.up, + ); +} \ No newline at end of file diff --git a/tdesign-component/example/assets/code/toast._preventTapToast.txt b/tdesign-component/example/assets/code/toast._preventTapToast.txt new file mode 100644 index 000000000..755b3ccae --- /dev/null +++ b/tdesign-component/example/assets/code/toast._preventTapToast.txt @@ -0,0 +1,14 @@ + + Widget _preventTapToast(BuildContext context) { + return TDButton( + onTap: () { + TDToast.showText('轻提示文字内容', + context: context, preventTap: true); + }, + size: TDButtonSize.large, + type: TDButtonType.outline, + theme: TDButtonTheme.primary, + isBlock: true, + text: '禁止滚动+点击', + ); + } \ No newline at end of file diff --git a/tdesign-site/src/indexes/README.md b/tdesign-site/src/indexes/README.md new file mode 100644 index 000000000..12b8f9c09 --- /dev/null +++ b/tdesign-site/src/indexes/README.md @@ -0,0 +1,266 @@ +--- +title: Indexes 索引 +description: 用于页面中信息快速检索,可以根据目录中的页码快速找到所需的内容。 +spline: base +isComponent: true +--- + + +## 引入 + +在tdesign_flutter/tdesign_flutter.dart中有所有组件的路径。 + +```dart +import 'package:tdesign_flutter/tdesign_flutter.dart'; +``` + +## 代码演示 + +[td_indexes_page.dart](https://github.com/Tencent/tdesign-flutter/blob/main/tdesign-component/example/lib/page/td_indexes_page.dart) + +### 1 组件类型 + +基础索引类型 + + + + +
+Widget _buildSimple(BuildContext context) {
+  final renderBox = navBarkey.currentContext?.findRenderObject() as RenderBox?;
+  final indexList = _list.map((item) => item['index'] as String).toList();
+  return TDButton(
+    text: '基础用法',
+    isBlock: true,
+    size: TDButtonSize.large,
+    theme: TDButtonTheme.primary,
+    type: TDButtonType.outline,
+    onTap: () {
+      Navigator.of(context).push(
+        TDSlidePopupRoute(
+          slideTransitionFrom: SlideTransitionFrom.right,
+          modalTop: renderBox?.size.height,
+          builder: (context) {
+            return Container(
+              color: Colors.white,
+              child: TDIndexes(
+                indexList: indexList,
+                builderContent: (context, index) {
+                  final list = _list.firstWhere((element) => element['index'] == index)['children'] as List;
+                  return TDCellGroup(
+                    cells: list
+                        .map((e) => TDCell(
+                              title: e,
+                            ))
+                        .toList(),
+                  );
+                },
+              ),
+            );
+          },
+        ),
+      );
+    },
+  );
+}
+ +
+ + + + + +
+Widget _buildSimple(BuildContext context) {
+  final renderBox = navBarkey.currentContext?.findRenderObject() as RenderBox?;
+  final indexList = _list.map((item) => item['index'] as String).toList();
+  return TDButton(
+    text: '基础用法',
+    isBlock: true,
+    size: TDButtonSize.large,
+    theme: TDButtonTheme.primary,
+    type: TDButtonType.outline,
+    onTap: () {
+      Navigator.of(context).push(
+        TDSlidePopupRoute(
+          slideTransitionFrom: SlideTransitionFrom.right,
+          modalTop: renderBox?.size.height,
+          builder: (context) {
+            return Container(
+              color: Colors.white,
+              child: TDIndexes(
+                indexList: indexList,
+                builderContent: (context, index) {
+                  final list = _list.firstWhere((element) => element['index'] == index)['children'] as List;
+                  return TDCellGroup(
+                    cells: list
+                        .map((e) => TDCell(
+                              title: e,
+                            ))
+                        .toList(),
+                  );
+                },
+              ),
+            );
+          },
+        ),
+      );
+    },
+  );
+}
+ +
+ +### 1 组件样式 + +其他索引类型 + + + + +
+Widget _buildOther(BuildContext context) {
+  final renderBox = navBarkey.currentContext?.findRenderObject() as RenderBox?;
+  final indexList = _list.map((item) => item['index'] as String).toList();
+  return TDButton(
+    text: '胶囊索引',
+    isBlock: true,
+    size: TDButtonSize.large,
+    theme: TDButtonTheme.primary,
+    type: TDButtonType.outline,
+    onTap: () {
+      Navigator.of(context).push(
+        TDSlidePopupRoute(
+          slideTransitionFrom: SlideTransitionFrom.right,
+          modalTop: renderBox?.size.height,
+          builder: (context) {
+            return Container(
+              color: Colors.white,
+              child: TDIndexes(
+                indexList: indexList,
+                capsuleTheme: true,
+                builderContent: (context, index) {
+                  final list = _list.firstWhere((element) => element['index'] == index)['children'] as List;
+                  return TDCellGroup(
+                    cells: list
+                        .map((e) => TDCell(
+                              title: e,
+                            ))
+                        .toList(),
+                  );
+                },
+              ),
+            );
+          },
+        ),
+      );
+    },
+  );
+}
+ +
+ + + + + +
+Widget _buildOther(BuildContext context) {
+  final renderBox = navBarkey.currentContext?.findRenderObject() as RenderBox?;
+  final indexList = _list.map((item) => item['index'] as String).toList();
+  return TDButton(
+    text: '胶囊索引',
+    isBlock: true,
+    size: TDButtonSize.large,
+    theme: TDButtonTheme.primary,
+    type: TDButtonType.outline,
+    onTap: () {
+      Navigator.of(context).push(
+        TDSlidePopupRoute(
+          slideTransitionFrom: SlideTransitionFrom.right,
+          modalTop: renderBox?.size.height,
+          builder: (context) {
+            return Container(
+              color: Colors.white,
+              child: TDIndexes(
+                indexList: indexList,
+                capsuleTheme: true,
+                builderContent: (context, index) {
+                  final list = _list.firstWhere((element) => element['index'] == index)['children'] as List;
+                  return TDCellGroup(
+                    cells: list
+                        .map((e) => TDCell(
+                              title: e,
+                            ))
+                        .toList(),
+                  );
+                },
+              ),
+            );
+          },
+        ),
+      );
+    },
+  );
+}
+ +
+ + + +## API +### TDIndexes +#### 简介 +索引 +#### 默认构造方法 + +| 参数 | 类型 | 默认值 | 说明 | +| --- | --- | --- | --- | +| key | | - | | +| indexList | List? | - | 索引字符列表。不传默认 A-Z | +| indexListMaxHeight | double? | 0.8 | 索引列表最大高度(父容器高度的百分比,默认0.8) | +| sticky | bool? | true | 锚点是否吸顶 | +| stickyOffset | double? | 0 | 锚点吸顶时与顶部的距离 | +| capsuleTheme | bool? | false | 锚点是否为胶囊式样式 | +| reverse | bool? | false | 反方向滚动置顶 | +| scrollController | ScrollController? | - | 滚动控制器 | +| onChange | void Function(String index)? | - | 索引发生变更时触发事件 | +| onSelect | void Function(String index)? | - | 点击侧边栏时触发事件 | +| builderContent | Widget? Function(BuildContext context, String index) | - | 内容自定义构建 | +| builderAnchor | Widget? Function(BuildContext context, String index, bool isPinnedToTop)? | - | 锚点自定义构建 | +| builderIndex | Widget Function(BuildContext context, String index, bool isActive)? | - | 索引文本自定义构建,包括索引激活左侧提示 | + +``` +``` + ### TDIndexesList +#### 简介 +索引 +#### 默认构造方法 + +| 参数 | 类型 | 默认值 | 说明 | +| --- | --- | --- | --- | +| key | | - | | +| indexList | List | - | 索引字符列表。不传默认 A-Z | +| indexListMaxHeight | double | 0.8 | 索引列表最大高度(父容器高度的百分比,默认0.8) | +| activeIndex | ValueNotifier | - | 选中索引 | +| onSelect | void Function(String index, bool isUp) | - | 点击侧边栏时触发事件 | +| builderIndex | Widget Function(BuildContext context, String index, bool isActive)? | - | 索引文本自定义构建,包括索引激活左侧提示 | + +``` +``` + ### TDIndexesAnchor +#### 简介 +索引锚点 +#### 默认构造方法 + +| 参数 | 类型 | 默认值 | 说明 | +| --- | --- | --- | --- | +| key | | - | | +| sticky | bool | - | 索引是否吸顶 | +| text | String | - | 锚点文本 | +| capsuleTheme | bool | - | 是否为胶囊式样式 | +| builderAnchor | Widget? Function(BuildContext context, String index, bool isPinnedToTop)? | - | 索引锚点构建 | +| activeIndex | ValueNotifier | - | 选中索引 | + + + \ No newline at end of file From 6bde895738e0a4fa5f0eb40dedb4de3b2c891556 Mon Sep 17 00:00:00 2001 From: Luozf12345 <2515187986@qq.com> Date: Sun, 13 Oct 2024 14:51:13 +0800 Subject: [PATCH 19/46] =?UTF-8?q?=E7=94=9F=E6=88=90API=E6=96=87=E6=A1=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../example/assets/api/button_api.md | 1 + .../example/assets/api/calendar_api.md | 2 + .../example/assets/api/cascader_api.md | 1 + .../example/assets/api/cell_api.md | 1 + .../assets/api/date-time-picker_api.md | 7 ++-- .../example/assets/api/dialog_api.md | 9 +++++ .../example/assets/api/drawer_api.md | 3 ++ .../example/assets/api/indexes_api.md | 2 +- .../example/assets/api/input_api.md | 3 +- .../example/assets/api/loading_api.md | 2 +- .../example/assets/api/navbar_api.md | 2 + .../example/assets/api/picker_api.md | 10 +++-- .../example/assets/api/popup_api.md | 2 + .../example/assets/api/radio_api.md | 1 + .../example/assets/api/search_api.md | 40 ++++++++++--------- .../example/assets/api/side-bar_api.md | 2 + .../example/assets/api/time-counter_api.md | 12 +++--- .../example/assets/api/toast_api.md | 14 +++---- 18 files changed, 73 insertions(+), 41 deletions(-) diff --git a/tdesign-component/example/assets/api/button_api.md b/tdesign-component/example/assets/api/button_api.md index 8b0a5f8fd..318aeebb6 100644 --- a/tdesign-component/example/assets/api/button_api.md +++ b/tdesign-component/example/assets/api/button_api.md @@ -46,6 +46,7 @@ | onTap | TDButtonEvent? | - | 点击事件 | | icon | IconData? | - | 图标icon | | iconWidget | Widget? | - | 自定义图标icon控件 | +| iconTextSpacing | double? | - | 自定义图标与文本之间距离 | | onLongPress | TDButtonEvent? | - | 长按事件 | | margin | EdgeInsetsGeometry? | - | 自定义margin | | padding | EdgeInsetsGeometry? | - | 自定义padding | diff --git a/tdesign-component/example/assets/api/calendar_api.md b/tdesign-component/example/assets/api/calendar_api.md index a53ab6e46..1b027660f 100644 --- a/tdesign-component/example/assets/api/calendar_api.md +++ b/tdesign-component/example/assets/api/calendar_api.md @@ -49,6 +49,8 @@ | onCellClick | void Function(int value, DateSelectType type, TDate tdate)? | - | 点击日期时触发 | | onCellLongPress | void Function(int value, DateSelectType type, TDate tdate)? | - | 长安日期时触发 | | onHeanderClick | void Function(int index, String week)? | - | 点击周时触发 | +| useTimePicker | bool? | false | 是否显示时间选择器 | +| timePickerModel | List? | - | 自定义时间选择器 | ``` ``` diff --git a/tdesign-component/example/assets/api/cascader_api.md b/tdesign-component/example/assets/api/cascader_api.md index abb08d16d..16ec9d98c 100644 --- a/tdesign-component/example/assets/api/cascader_api.md +++ b/tdesign-component/example/assets/api/cascader_api.md @@ -16,5 +16,6 @@ | backgroundColor | Color? | - | 背景颜色 | | topRadius | double? | - | 顶部圆角 | | closeText | String? | - | 关闭按钮文本 | +| isLetterSort | bool | false | 是否开启字母排序 | | onClose | Function? | - | 选择器关闭按钮回调 | | onChange | MultiCascaderCallback | - | 值发生变更时触发 | diff --git a/tdesign-component/example/assets/api/cell_api.md b/tdesign-component/example/assets/api/cell_api.md index 51cd50355..de0adc738 100644 --- a/tdesign-component/example/assets/api/cell_api.md +++ b/tdesign-component/example/assets/api/cell_api.md @@ -15,6 +15,7 @@ | borderedColor | Color? | - | 单元格边框颜色 | | groupBorderedColor | Color? | - | 单元格组边框颜色 | | backgroundColor | Color? | - | 默认状态背景颜色 | +| padding | EdgeInsets? | - | 单元格内边距 | #### 工厂构造方法 diff --git a/tdesign-component/example/assets/api/date-time-picker_api.md b/tdesign-component/example/assets/api/date-time-picker_api.md index 7894b1743..2dc188bec 100644 --- a/tdesign-component/example/assets/api/date-time-picker_api.md +++ b/tdesign-component/example/assets/api/date-time-picker_api.md @@ -25,6 +25,7 @@ | showTitle | bool | true | 是否展示标题 | | pickerHeight | double | 200 | 选择器List的视窗高度,默认200 | | pickerItemCount | int | - | 选择器List视窗中item个数,pickerHeight / pickerItemCount即item高度 | +| onSelectedItemChanged | void Function(int index)? | - | 选择器选中项改变回调 | | key | | - | | ``` @@ -35,6 +36,6 @@ | 名称 | 返回类型 | 参数 | 说明 | | --- | --- | --- | --- | -| showDatePicker | | required null context, required String title, required DatePickerCallback? onConfirm, DatePickerCallback? onCancel, bool useYear, bool useMonth, bool useDay, bool useHour, bool useMinute, bool useSecond, bool useWeekDay, Color? barrierColor, List dateStart, List? dateEnd, List? initialDate, String? rightText, String? leftText, Duration duration, double pickerHeight, int pickerItemCount, | 显示时间选择器 | -| showMultiPicker | | required null context, String? title, required MultiPickerCallback? onConfirm, MultiPickerCallback? onCancel, required List> data, List? initialIndexes, Duration duration, Color? barrierColor, double pickerHeight, int pickerItemCount, | 显示多级选择器 | -| showMultiLinkedPicker | | required null context, String? title, required MultiPickerCallback? onConfirm, MultiPickerCallback? onCancel, required Map data, required int columnNum, required List initialData, Duration duration, Color? barrierColor, double pickerHeight, int pickerItemCount, | 显示多级联动选择器 | +| showDatePicker | | required null context, required String title, required DatePickerCallback? onConfirm, DatePickerCallback? onCancel, bool useYear, bool useMonth, bool useDay, bool useHour, bool useMinute, bool useSecond, bool useWeekDay, Color? barrierColor, List dateStart, List? dateEnd, List? initialDate, String? rightText, String? leftText, TextStyle? leftTextStyle, TextStyle? centerTextStyle, TextStyle? rightTextStyle, Color? titleDividerColor, Duration duration, double pickerHeight, int pickerItemCount, | 显示时间选择器 | +| showMultiPicker | | required null context, String? title, required MultiPickerCallback? onConfirm, MultiPickerCallback? onCancel, required List> data, List? initialIndexes, Duration duration, Color? barrierColor, double pickerHeight, String? rightText, String? leftText, TextStyle? leftTextStyle, TextStyle? centerTextStyle, TextStyle? rightTextStyle, Color? titleDividerColor, double? topPadding, int pickerItemCount, | 显示多级选择器 | +| showMultiLinkedPicker | | required null context, String? title, required MultiPickerCallback? onConfirm, MultiPickerCallback? onCancel, required Map data, required int columnNum, required List initialData, Duration duration, Color? barrierColor, String? rightText, String? leftText, TextStyle? leftTextStyle, TextStyle? centerTextStyle, TextStyle? rightTextStyle, double pickerHeight, Color? titleDividerColor, double? topPadding, int pickerItemCount, | 显示多级联动选择器 | diff --git a/tdesign-component/example/assets/api/dialog_api.md b/tdesign-component/example/assets/api/dialog_api.md index f23be75ba..232fec0a2 100644 --- a/tdesign-component/example/assets/api/dialog_api.md +++ b/tdesign-component/example/assets/api/dialog_api.md @@ -18,6 +18,8 @@ | leftBtn | TDDialogButtonOptions? | - | 左侧按钮配置 | | rightBtn | TDDialogButtonOptions? | - | 右侧按钮配置 | | showCloseButton | bool? | - | 显示右上角关闭按钮 | +| padding | EdgeInsets? | - | 内容内边距 | +| buttonWidget | Widget? | - | 自定义按钮 | ``` ``` @@ -57,6 +59,8 @@ | buttonTextColor | Color? | - | 按钮文字颜色 | | buttonStyle | TDDialogButtonStyle | TDDialogButtonStyle.normal | 按钮样式 | | showCloseButton | bool? | - | 右上角关闭按钮 | +| padding | EdgeInsets? | const EdgeInsets.fromLTRB(24, 32, 24, 0) | 内容内边距 | +| buttonWidget | Widget? | - | 自定义按钮 | ``` ``` @@ -79,6 +83,9 @@ | leftBtn | TDDialogButtonOptions? | - | 左侧按钮配置 | | rightBtn | TDDialogButtonOptions? | - | 右侧按钮配置 | | showCloseButton | bool? | - | 显示右上角关闭按钮 | +| padding | EdgeInsets? | const EdgeInsets.fromLTRB(24, 32, 24, 0) | 内容内边距 | +| buttonWidget | Widget? | - | 自定义按钮 | +| customInputWidget | Widget? | - | 自定义输入框 | ``` ``` @@ -103,6 +110,8 @@ | rightBtnAction | Function()? | - | 右侧按钮默认点击 | | showCloseButton | bool? | - | 显示右上角关闭按钮 | | buttonStyle | | TDDialogButtonStyle.normal | | +| padding | EdgeInsets? | const EdgeInsets.fromLTRB(24, 32, 24, 0) | 内容内边距 | +| buttonWidget | Widget? | - | 自定义按钮 | #### 工厂构造方法 diff --git a/tdesign-component/example/assets/api/drawer_api.md b/tdesign-component/example/assets/api/drawer_api.md index 3aca451ac..7dfc8a5d4 100644 --- a/tdesign-component/example/assets/api/drawer_api.md +++ b/tdesign-component/example/assets/api/drawer_api.md @@ -21,6 +21,9 @@ | drawerTop | double? | - | 距离顶部的距离 | | style | TDCellStyle? | - | 列表自定义样式 | | hover | bool? | true | 是否开启点击反馈 | +| backgroundColor | Color? | - | 组件背景颜色 | +| bordered | bool? | true | 是否显示边框 | +| isShowLastBordered | bool? | true | 是否显示最后一行分割线 | ``` ``` diff --git a/tdesign-component/example/assets/api/indexes_api.md b/tdesign-component/example/assets/api/indexes_api.md index 2bfc1f540..9557fe75f 100644 --- a/tdesign-component/example/assets/api/indexes_api.md +++ b/tdesign-component/example/assets/api/indexes_api.md @@ -33,7 +33,7 @@ | indexList | List | - | 索引字符列表。不传默认 A-Z | | indexListMaxHeight | double | 0.8 | 索引列表最大高度(父容器高度的百分比,默认0.8) | | activeIndex | ValueNotifier | - | 选中索引 | -| onSelect | void Function(String index, bool isUp) | - | 点击侧边栏时触发事件 | +| onSelect | void Function(String newIndex, String oldIndex) | - | 点击侧边栏时触发事件 | | builderIndex | Widget Function(BuildContext context, String index, bool isActive)? | - | 索引文本自定义构建,包括索引激活左侧提示 | ``` diff --git a/tdesign-component/example/assets/api/input_api.md b/tdesign-component/example/assets/api/input_api.md index 31f94df72..2dc18b515 100644 --- a/tdesign-component/example/assets/api/input_api.md +++ b/tdesign-component/example/assets/api/input_api.md @@ -11,7 +11,7 @@ | decoration | Decoration? | - | 输入框样式 | | leftIcon | Widget? | - | 带图标的输入框 | | leftLabel | String? | - | 输入框左侧文案 | -| leftLabelStyle | TextStyle? | - | 左侧标签样式 | +| leftLabelStyle | TextStyle? | - | 左侧标签样式 设置该值是若出现像素溢出,请设置letterSpacing: 0 | | leftLabelSpace | double? | - | 输入框左侧文案间距 | | required | bool? | - | 是否必填标志(红色*) | | readOnly | bool | false | 是否只读 | @@ -53,3 +53,4 @@ | inputAction | TextInputAction? | - | 键盘动作类型 | | spacer | TDInputSpacer | - | 组件各模块间间距 | | cardStyleBottomText | String? | - | 卡片模式下方文字 | +| onTapOutside | TapRegionCallback? | - | 点击输入框外部区域回调 | diff --git a/tdesign-component/example/assets/api/loading_api.md b/tdesign-component/example/assets/api/loading_api.md index 96c2ecbfb..162c46a31 100644 --- a/tdesign-component/example/assets/api/loading_api.md +++ b/tdesign-component/example/assets/api/loading_api.md @@ -6,7 +6,7 @@ | --- | --- | --- | --- | | key | | - | | | size | TDLoadingSize | - | 尺寸 | -| icon | TDLoadingIcon? | - | 图标,支持圆形、点状、菊花状 | +| icon | TDLoadingIcon? | TDLoadingIcon.circle | 图标,支持圆形、点状、菊花状 | | iconColor | Color? | - | 图标颜色 | | axis | Axis | Axis.vertical | 文案和图标相对方向 | | text | String? | - | 文案 | diff --git a/tdesign-component/example/assets/api/navbar_api.md b/tdesign-component/example/assets/api/navbar_api.md index 293047c57..65f0dc748 100644 --- a/tdesign-component/example/assets/api/navbar_api.md +++ b/tdesign-component/example/assets/api/navbar_api.md @@ -25,6 +25,8 @@ | useBorderStyle | bool | false | 是否使用边框模式 | | border | TDNavBarItemBorder? | - | 边框 | | belowTitleWidget | Widget? | - | belowTitleWidget navbar 下方的widget | +| boxShadow | List? | - | 底部阴影 | +| flexibleSpace | Widget? | - | 固定背景 | ``` ``` diff --git a/tdesign-component/example/assets/api/picker_api.md b/tdesign-component/example/assets/api/picker_api.md index a139e8825..6d88cd8d3 100644 --- a/tdesign-component/example/assets/api/picker_api.md +++ b/tdesign-component/example/assets/api/picker_api.md @@ -11,6 +11,8 @@ | pickerHeight | double | - | | | pickerItemCount | int | - | 选择器List视窗中item个数,pickerHeight / pickerItemCount即item高度 | | initialIndexes | List? | - | 若为null表示全部从零开始 | +| rightText | String? | - | 右侧按钮文案 | +| leftText | String? | - | 左侧按钮文案 | | leftTextStyle | TextStyle? | - | 自定义左侧文案样式 | | rightTextStyle | TextStyle? | - | 自定义右侧文案样式 | | centerTextStyle | TextStyle? | - | 自定义中间文案样式 | @@ -42,6 +44,8 @@ | pickerHeight | double | 200 | | | pickerItemCount | int | 5 | 选择器List视窗中item个数,pickerHeight / pickerItemCount即item高度 | | customSelectWidget | Widget? | - | 自定义选择框样式 | +| rightText | String? | - | 右侧按钮文案 | +| leftText | String? | - | 左侧按钮文案 | | leftTextStyle | TextStyle? | - | 自定义左侧文案样式 | | rightTextStyle | TextStyle? | - | 自定义右侧文案样式 | | centerTextStyle | TextStyle? | - | 自定义中间文案样式 | @@ -75,6 +79,6 @@ | 名称 | 返回类型 | 参数 | 说明 | | --- | --- | --- | --- | -| showDatePicker | | required null context, required String title, required DatePickerCallback? onConfirm, DatePickerCallback? onCancel, bool useYear, bool useMonth, bool useDay, bool useHour, bool useMinute, bool useSecond, bool useWeekDay, Color? barrierColor, List dateStart, List? dateEnd, List? initialDate, String? rightText, String? leftText, Duration duration, double pickerHeight, int pickerItemCount, | 显示时间选择器 | -| showMultiPicker | | required null context, String? title, required MultiPickerCallback? onConfirm, MultiPickerCallback? onCancel, required List> data, List? initialIndexes, Duration duration, Color? barrierColor, double pickerHeight, int pickerItemCount, | 显示多级选择器 | -| showMultiLinkedPicker | | required null context, String? title, required MultiPickerCallback? onConfirm, MultiPickerCallback? onCancel, required Map data, required int columnNum, required List initialData, Duration duration, Color? barrierColor, double pickerHeight, int pickerItemCount, | 显示多级联动选择器 | +| showDatePicker | | required null context, required String title, required DatePickerCallback? onConfirm, DatePickerCallback? onCancel, bool useYear, bool useMonth, bool useDay, bool useHour, bool useMinute, bool useSecond, bool useWeekDay, Color? barrierColor, List dateStart, List? dateEnd, List? initialDate, String? rightText, String? leftText, TextStyle? leftTextStyle, TextStyle? centerTextStyle, TextStyle? rightTextStyle, Color? titleDividerColor, Duration duration, double pickerHeight, int pickerItemCount, | 显示时间选择器 | +| showMultiPicker | | required null context, String? title, required MultiPickerCallback? onConfirm, MultiPickerCallback? onCancel, required List> data, List? initialIndexes, Duration duration, Color? barrierColor, double pickerHeight, String? rightText, String? leftText, TextStyle? leftTextStyle, TextStyle? centerTextStyle, TextStyle? rightTextStyle, Color? titleDividerColor, double? topPadding, int pickerItemCount, | 显示多级选择器 | +| showMultiLinkedPicker | | required null context, String? title, required MultiPickerCallback? onConfirm, MultiPickerCallback? onCancel, required Map data, required int columnNum, required List initialData, Duration duration, Color? barrierColor, String? rightText, String? leftText, TextStyle? leftTextStyle, TextStyle? centerTextStyle, TextStyle? rightTextStyle, double pickerHeight, Color? titleDividerColor, double? topPadding, int pickerItemCount, | 显示多级联动选择器 | diff --git a/tdesign-component/example/assets/api/popup_api.md b/tdesign-component/example/assets/api/popup_api.md index 30556d520..dd98f8b79 100644 --- a/tdesign-component/example/assets/api/popup_api.md +++ b/tdesign-component/example/assets/api/popup_api.md @@ -18,6 +18,8 @@ | modalLeft | double? | 0 | 弹出框左侧距离 | | open | VoidCallback? | - | 打开前事件 | | opened | VoidCallback? | - | 打开后事件 | +| close | VoidCallback? | - | 关闭前事件 | +| barrierClick | VoidCallback? | - | 蒙层点击事件,仅在[modalBarrierFull]为false时触发 | ``` ``` diff --git a/tdesign-component/example/assets/api/radio_api.md b/tdesign-component/example/assets/api/radio_api.md index b8519036e..8dc678298 100644 --- a/tdesign-component/example/assets/api/radio_api.md +++ b/tdesign-component/example/assets/api/radio_api.md @@ -56,6 +56,7 @@ RadioGroup分组对象,继承自TDCheckboxGroup,字段含义与父类一致 | customIconBuilder | | - | | | customContentBuilder | | - | | | spacing | | - | | +| rowCount | int | 1 | 每行几列 | | contentDirection | | - | | | onRadioGroupChange | | - | | | showDivider | bool | false | 是否显示下划线 | diff --git a/tdesign-component/example/assets/api/search_api.md b/tdesign-component/example/assets/api/search_api.md index ef431c51f..df881270e 100644 --- a/tdesign-component/example/assets/api/search_api.md +++ b/tdesign-component/example/assets/api/search_api.md @@ -2,22 +2,24 @@ ### TDSearchBar #### 默认构造方法 -| 参数 | 类型 | 默认值 | 说明 | -|-----------------|------------------------|-----------------------------------------|---------------| -| key | | - | | -| placeHolder | String? | - | 预设文案 | -| style | TDSearchStyle? | TDSearchStyle.square | 样式 | -| alignment | TDSearchAlignment? | TDSearchAlignment.left | 对齐方式,居中或这头部对齐 | -| onTextChanged | TDSearchBarEvent? | - | 文字改变回调 | -| onSubmitted | TDSearchBarEvent? | - | 提交回调 | -| onEditComplete | TDSearchBarCallBack? | - | 编辑完成回调 | -| autoHeight | bool | false | 是否自动计算高度 | -| padding | EdgeInsets | const EdgeInsets.fromLTRB(16, 8, 16, 8) | 内部填充 | -| autoFocus | bool | false | 是否自动获取焦点 | -| mediumStyle | bool | false | 是否在导航栏中的样式 | -| needCancel | bool | false | 是否需要取消按钮 | -| action | String | ‘’ | 右侧操作按钮文字 | -| onActionClick | TDSearchBarEvent? | - | 右侧操作按钮点击回调 | -| controller | TextEditingController? | - | 控制器 | -| backgroundColor | Color? | Colors.white | 背景颜色 | - +| 参数 | 类型 | 默认值 | 说明 | +| --- | --- | --- | --- | +| key | | - | | +| placeHolder | String? | - | 预设文案 | +| style | TDSearchStyle? | TDSearchStyle.square | 样式 | +| alignment | TDSearchAlignment? | TDSearchAlignment.left | 对齐方式,居中或这头部对齐 | +| onTextChanged | TDSearchBarEvent? | - | 文字改变回调 | +| onSubmitted | TDSearchBarEvent? | - | 提交回调 | +| onEditComplete | TDSearchBarCallBack? | - | 编辑完成回调 | +| autoHeight | bool | false | 是否自动计算高度 | +| padding | EdgeInsets | const EdgeInsets.fromLTRB(16, 8, 16, 8) | 内部填充 | +| autoFocus | bool | false | 是否自动获取焦点 | +| mediumStyle | bool | false | 是否在导航栏中的样式 | +| cursorHeight | double? | - | 光标的高 | +| needCancel | bool | false | 是否需要取消按钮 | +| controller | TextEditingController? | - | 控制器 | +| backgroundColor | Color? | Colors.white | 背景颜色 | +| action | String | '' | 自定义操作文字 | +| onActionClick | TDSearchBarEvent? | - | 自定义操作回调 | +| onClearClick | TDSearchBarClearEvent? | - | 自定义操作回调 | +| focusNode | FocusNode? | - | 自定义焦点 | diff --git a/tdesign-component/example/assets/api/side-bar_api.md b/tdesign-component/example/assets/api/side-bar_api.md index e5ca7def3..a7741fb57 100644 --- a/tdesign-component/example/assets/api/side-bar_api.md +++ b/tdesign-component/example/assets/api/side-bar_api.md @@ -31,3 +31,5 @@ | contentPadding | EdgeInsetsGeometry? | - | 自定义文本框内边距 | | selectedTextStyle | TextStyle? | - | 选中样式 | | style | TDSideBarStyle | TDSideBarStyle.normal | 样式 | +| loading | bool? | - | 加载效果 | +| loadingWidget | Widget? | - | 自定义加载动画 | diff --git a/tdesign-component/example/assets/api/time-counter_api.md b/tdesign-component/example/assets/api/time-counter_api.md index e11954222..e7d229cdc 100644 --- a/tdesign-component/example/assets/api/time-counter_api.md +++ b/tdesign-component/example/assets/api/time-counter_api.md @@ -1,7 +1,7 @@ ## API ### TDTimeCounter #### 简介 -倒计时组件 +计时组件 #### 默认构造方法 | 参数 | 类型 | 默认值 | 说明 | @@ -11,13 +11,13 @@ | content | dynamic | 'default' | 'default' / Widget Function(int time) / Widget | | format | String | 'HH:mm:ss' | 时间格式,DD-日,HH-时,mm-分,ss-秒,SSS-毫秒(分隔符必须为长度为1的非空格的字符) | | millisecond | bool | false | 是否开启毫秒级渲染 | -| size | TDTimeCounterSize | TDTimeCounterSize.medium | 倒计时尺寸 | +| size | TDTimeCounterSize | TDTimeCounterSize.medium | 尺寸 | | splitWithUnit | bool | false | 使用时间单位分割 | -| theme | TDTimeCounterTheme | TDTimeCounterTheme.defaultTheme | 倒计时风格 | -| time | int | - | 必需;倒计时时长,单位毫秒 | +| theme | TDTimeCounterTheme | TDTimeCounterTheme.defaultTheme | 风格 | +| time | int | - | 必需;计时时长,单位毫秒 | | style | TDTimeCounterStyle? | - | 自定义样式,有则优先用它,没有则根据size和theme选取 | | onChange | Function(int time)? | - | 时间变化时触发回调 | -| onFinish | VoidCallback? | - | 倒计时结束时触发回调 | +| onFinish | VoidCallback? | - | 计时结束时触发回调 | | direction | TDTimeCounterDirection | TDTimeCounterDirection.down | 计时方向,默认倒计时 | | controller | TDTimeCounterController? | - | 控制器,可控制开始/暂停/继续/重置 | @@ -25,7 +25,7 @@ ``` ### TDTimeCounterStyle #### 简介 -倒计时组件样式 +计时组件样式 #### 默认构造方法 | 参数 | 类型 | 默认值 | 说明 | diff --git a/tdesign-component/example/assets/api/toast_api.md b/tdesign-component/example/assets/api/toast_api.md index 23ddd65bc..e67cbaa30 100644 --- a/tdesign-component/example/assets/api/toast_api.md +++ b/tdesign-component/example/assets/api/toast_api.md @@ -5,11 +5,11 @@ | 名称 | 返回类型 | 参数 | 说明 | | --- | --- | --- | --- | -| showText | | required String? text, required BuildContext context, Duration duration, int? maxLines, BoxConstraints? constraints, | 普通文本Toast | -| showIconText | | required String? text, IconData? icon, IconTextDirection direction, required BuildContext context, Duration duration, | 带图标的Toast | -| showSuccess | | required String? text, IconTextDirection direction, required BuildContext context, Duration duration, | 成功提示Toast | -| showWarning | | required String? text, IconTextDirection direction, required BuildContext context, Duration duration, | 警告Toast | -| showFail | | required String? text, IconTextDirection direction, required BuildContext context, Duration duration, | 失败提示Toast | -| showLoading | | required BuildContext context, String? text, Duration duration, | 带文案的加载Toast | -| showLoadingWithoutText | | required BuildContext context, String? text, Duration duration, | 不带文案的加载Toast | +| showText | | required String? text, required BuildContext context, Duration duration, int? maxLines, BoxConstraints? constraints, bool? preventTap, | 普通文本Toast | +| showIconText | | required String? text, IconData? icon, IconTextDirection direction, required BuildContext context, Duration duration, bool? preventTap, | 带图标的Toast | +| showSuccess | | required String? text, IconTextDirection direction, required BuildContext context, Duration duration, bool? preventTap, | 成功提示Toast | +| showWarning | | required String? text, IconTextDirection direction, required BuildContext context, Duration duration, bool? preventTap, | 警告Toast | +| showFail | | required String? text, IconTextDirection direction, required BuildContext context, Duration duration, bool? preventTap, | 失败提示Toast | +| showLoading | | required BuildContext context, String? text, Duration duration, bool? preventTap, | 带文案的加载Toast | +| showLoadingWithoutText | | required BuildContext context, String? text, Duration duration, bool? preventTap, | 不带文案的加载Toast | | dismissLoading | | | 关闭加载Toast | From f001d2e8771cecd54d9945632596a9aefea08676 Mon Sep 17 00:00:00 2001 From: Luozf12345 <2515187986@qq.com> Date: Sun, 13 Oct 2024 15:25:22 +0800 Subject: [PATCH 20/46] =?UTF-8?q?=E7=94=9F=E6=88=90=E6=BC=94=E7=A4=BA?= =?UTF-8?q?=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...scader._buildHorizontalCompanyCascader.txt | 2 +- ...ascader._buildHorizontalLetterCascader.txt | 8 ++- ...cascader._buildVerticalCompanyCascader.txt | 2 +- .../code/image_viewer._actionImageViewer.txt | 6 +- .../code/input._inputStatusLongLabel.txt | 2 + .../assets/code/input._verticalStyle.txt | 1 + .../code/radio._horizontalCardStyle.txt | 1 + .../code/result._buildBasicResultDefault.txt | 2 +- .../code/result._buildBasicResultError.txt | 2 +- .../code/result._buildBasicResultSuccess.txt | 2 +- .../code/result._buildBasicResultWarning.txt | 2 +- .../code/result._buildCustomResultContent.txt | 9 +-- ...ult._buildResultWithDescriptionDefault.txt | 2 +- ...esult._buildResultWithDescriptionError.txt | 2 +- ...ult._buildResultWithDescriptionSuccess.txt | 2 +- ...ult._buildResultWithDescriptionWarning.txt | 2 +- .../search._buildFocusSearchBarWithAction.txt | 2 +- .../code/search._buildSearchBarWithAction.txt | 58 +++++++++---------- 18 files changed, 60 insertions(+), 47 deletions(-) diff --git a/tdesign-component/example/assets/code/cascader._buildHorizontalCompanyCascader.txt b/tdesign-component/example/assets/code/cascader._buildHorizontalCompanyCascader.txt index 37c618f5f..15b965593 100644 --- a/tdesign-component/example/assets/code/cascader._buildHorizontalCompanyCascader.txt +++ b/tdesign-component/example/assets/code/cascader._buildHorizontalCompanyCascader.txt @@ -2,7 +2,7 @@ Widget _buildHorizontalCompanyCascader(BuildContext context) { return GestureDetector( onTap: () { - TDCascader.showMultiCascader(context, title: '选择部门人员', data: _data_3, initialData: _initData_3, theme: 'tab', + TDCascader.showMultiCascader(context, title: '选择部门人员', data: _data_3,isLetterSort: true, initialData: _initData_3, theme: 'tab', onChange: (List selectData) { setState(() { List result = []; diff --git a/tdesign-component/example/assets/code/cascader._buildHorizontalLetterCascader.txt b/tdesign-component/example/assets/code/cascader._buildHorizontalLetterCascader.txt index 276900a17..c86996f7d 100644 --- a/tdesign-component/example/assets/code/cascader._buildHorizontalLetterCascader.txt +++ b/tdesign-component/example/assets/code/cascader._buildHorizontalLetterCascader.txt @@ -2,8 +2,12 @@ Widget _buildHorizontalLetterCascader(BuildContext context) { return GestureDetector( onTap: () { - TDCascader.showMultiCascader(context, title: '选择地址', data: _data_2, initialData: _initData_2, theme: 'tab', - onChange: (List selectData) { + TDCascader.showMultiCascader(context, + title: '选择地址', + data: _data_2, + initialData: _initData_2, + isLetterSort: true, + theme: 'tab', onChange: (List selectData) { setState(() { List result = []; int len = selectData.length; diff --git a/tdesign-component/example/assets/code/cascader._buildVerticalCompanyCascader.txt b/tdesign-component/example/assets/code/cascader._buildVerticalCompanyCascader.txt index f4aa74e56..f4443ed81 100644 --- a/tdesign-component/example/assets/code/cascader._buildVerticalCompanyCascader.txt +++ b/tdesign-component/example/assets/code/cascader._buildVerticalCompanyCascader.txt @@ -2,7 +2,7 @@ Widget _buildVerticalCompanyCascader(BuildContext context) { return GestureDetector( onTap: () { - TDCascader.showMultiCascader(context, title: '选择部门人员', data: _data_3, initialData: _initData_3, theme: 'step', + TDCascader.showMultiCascader(context, title: '选择部门人员', data: _data_3,isLetterSort: true, initialData: _initData_3, theme: 'step', onChange: (List selectData) { setState(() { List result = []; diff --git a/tdesign-component/example/assets/code/image_viewer._actionImageViewer.txt b/tdesign-component/example/assets/code/image_viewer._actionImageViewer.txt index 77b74be73..d513b8d7b 100644 --- a/tdesign-component/example/assets/code/image_viewer._actionImageViewer.txt +++ b/tdesign-component/example/assets/code/image_viewer._actionImageViewer.txt @@ -1,5 +1,9 @@ Widget _actionImageViewer(BuildContext context) { + var delImages = [ + 'https://tdesign.gtimg.com/mobile/demos/swiper1.png', + 'https://tdesign.gtimg.com/mobile/demos/swiper2.png', + ]; return TDButton( type: TDButtonType.ghost, theme: TDButtonTheme.primary, @@ -9,7 +13,7 @@ onTap: () { TDImageViewer.showImageViewer( context: context, - images: images, + images: delImages, showIndex: true, deleteBtn: true, ); diff --git a/tdesign-component/example/assets/code/input._inputStatusLongLabel.txt b/tdesign-component/example/assets/code/input._inputStatusLongLabel.txt index f3f6b3fb7..0548a20b2 100644 --- a/tdesign-component/example/assets/code/input._inputStatusLongLabel.txt +++ b/tdesign-component/example/assets/code/input._inputStatusLongLabel.txt @@ -3,6 +3,8 @@ return Column( children: [ TDInput( + leftInfoWidth: 80, + spacer: TDInputSpacer(iconLabelSpace: 4), leftLabel: '标签超长时最多十个字', controller: controller[18], backgroundColor: Colors.white, diff --git a/tdesign-component/example/assets/code/input._verticalStyle.txt b/tdesign-component/example/assets/code/input._verticalStyle.txt index a29720add..03792d921 100644 --- a/tdesign-component/example/assets/code/input._verticalStyle.txt +++ b/tdesign-component/example/assets/code/input._verticalStyle.txt @@ -1,6 +1,7 @@ Widget _verticalStyle(BuildContext context) { return TDInput( + spacer: TDInputSpacer(iconLabelSpace: 0), type: TDInputType.twoLine, leftLabel: '标签文字', controller: controller[20], diff --git a/tdesign-component/example/assets/code/radio._horizontalCardStyle.txt b/tdesign-component/example/assets/code/radio._horizontalCardStyle.txt index 125c83095..6f09ced88 100644 --- a/tdesign-component/example/assets/code/radio._horizontalCardStyle.txt +++ b/tdesign-component/example/assets/code/radio._horizontalCardStyle.txt @@ -4,6 +4,7 @@ selectId: 'index:1', cardMode: true, direction: Axis.horizontal, + rowCount: 2, directionalTdRadios: const [ TDRadio( id: 'index:0', diff --git a/tdesign-component/example/assets/code/result._buildBasicResultDefault.txt b/tdesign-component/example/assets/code/result._buildBasicResultDefault.txt index 8ea334a47..02aca64c2 100644 --- a/tdesign-component/example/assets/code/result._buildBasicResultDefault.txt +++ b/tdesign-component/example/assets/code/result._buildBasicResultDefault.txt @@ -1,4 +1,4 @@ - + TDResult _buildBasicResultDefault(BuildContext context) { return const TDResult( title: '默认状态', diff --git a/tdesign-component/example/assets/code/result._buildBasicResultError.txt b/tdesign-component/example/assets/code/result._buildBasicResultError.txt index 44d787a05..2b657efef 100644 --- a/tdesign-component/example/assets/code/result._buildBasicResultError.txt +++ b/tdesign-component/example/assets/code/result._buildBasicResultError.txt @@ -1,4 +1,4 @@ - + TDResult _buildBasicResultError(BuildContext context) { return const TDResult( title: '失败状态', diff --git a/tdesign-component/example/assets/code/result._buildBasicResultSuccess.txt b/tdesign-component/example/assets/code/result._buildBasicResultSuccess.txt index f59a5bbe8..c5d82281e 100644 --- a/tdesign-component/example/assets/code/result._buildBasicResultSuccess.txt +++ b/tdesign-component/example/assets/code/result._buildBasicResultSuccess.txt @@ -1,4 +1,4 @@ - + TDResult _buildBasicResultSuccess(BuildContext context) { return const TDResult( title: '成功状态', diff --git a/tdesign-component/example/assets/code/result._buildBasicResultWarning.txt b/tdesign-component/example/assets/code/result._buildBasicResultWarning.txt index 40d86016f..29d30c0d9 100644 --- a/tdesign-component/example/assets/code/result._buildBasicResultWarning.txt +++ b/tdesign-component/example/assets/code/result._buildBasicResultWarning.txt @@ -1,4 +1,4 @@ - + TDResult _buildBasicResultWarning(BuildContext context) { return const TDResult( title: '警示状态', diff --git a/tdesign-component/example/assets/code/result._buildCustomResultContent.txt b/tdesign-component/example/assets/code/result._buildCustomResultContent.txt index 4aab5bec2..ae24433bd 100644 --- a/tdesign-component/example/assets/code/result._buildCustomResultContent.txt +++ b/tdesign-component/example/assets/code/result._buildCustomResultContent.txt @@ -1,7 +1,8 @@ - Widget _buildCustomResult(BuildContext context) { + TDResult _buildCustomResultContent(BuildContext context) { return TDResult( - title: '自定义结果', - icon: Image.asset('assets/img/illustration.png'), - description: '描述文字'); + title: '自定义结果', + icon: Image.asset('assets/img/illustration.png'), + description: '描述文字', + ); } \ No newline at end of file diff --git a/tdesign-component/example/assets/code/result._buildResultWithDescriptionDefault.txt b/tdesign-component/example/assets/code/result._buildResultWithDescriptionDefault.txt index 3fee21945..a3dea4fa6 100644 --- a/tdesign-component/example/assets/code/result._buildResultWithDescriptionDefault.txt +++ b/tdesign-component/example/assets/code/result._buildResultWithDescriptionDefault.txt @@ -1,4 +1,4 @@ - + TDResult _buildResultWithDescriptionDefault(BuildContext context) { return const TDResult( title: '默认状态', diff --git a/tdesign-component/example/assets/code/result._buildResultWithDescriptionError.txt b/tdesign-component/example/assets/code/result._buildResultWithDescriptionError.txt index c0740422a..d690ab258 100644 --- a/tdesign-component/example/assets/code/result._buildResultWithDescriptionError.txt +++ b/tdesign-component/example/assets/code/result._buildResultWithDescriptionError.txt @@ -1,4 +1,4 @@ - + TDResult _buildResultWithDescriptionError(BuildContext context) { return const TDResult( title: '失败状态', diff --git a/tdesign-component/example/assets/code/result._buildResultWithDescriptionSuccess.txt b/tdesign-component/example/assets/code/result._buildResultWithDescriptionSuccess.txt index 48522d226..2405d702b 100644 --- a/tdesign-component/example/assets/code/result._buildResultWithDescriptionSuccess.txt +++ b/tdesign-component/example/assets/code/result._buildResultWithDescriptionSuccess.txt @@ -1,4 +1,4 @@ - + TDResult _buildResultWithDescriptionSuccess(BuildContext context) { return const TDResult( title: '成功状态', diff --git a/tdesign-component/example/assets/code/result._buildResultWithDescriptionWarning.txt b/tdesign-component/example/assets/code/result._buildResultWithDescriptionWarning.txt index dde3581e5..a5ef713b5 100644 --- a/tdesign-component/example/assets/code/result._buildResultWithDescriptionWarning.txt +++ b/tdesign-component/example/assets/code/result._buildResultWithDescriptionWarning.txt @@ -1,4 +1,4 @@ - + TDResult _buildResultWithDescriptionWarning(BuildContext context) { return const TDResult( title: '警示状态', diff --git a/tdesign-component/example/assets/code/search._buildFocusSearchBarWithAction.txt b/tdesign-component/example/assets/code/search._buildFocusSearchBarWithAction.txt index 95050bcea..79934dc70 100644 --- a/tdesign-component/example/assets/code/search._buildFocusSearchBarWithAction.txt +++ b/tdesign-component/example/assets/code/search._buildFocusSearchBarWithAction.txt @@ -5,7 +5,7 @@ action: '搜索', needCancel: true, controller: inputController, - onActionClick: () { + onActionClick: (value) { showGeneralDialog( context: context, pageBuilder: (BuildContext buildContext, Animation animation, diff --git a/tdesign-component/example/assets/code/search._buildSearchBarWithAction.txt b/tdesign-component/example/assets/code/search._buildSearchBarWithAction.txt index bfab4d164..0a7ccf922 100644 --- a/tdesign-component/example/assets/code/search._buildSearchBarWithAction.txt +++ b/tdesign-component/example/assets/code/search._buildSearchBarWithAction.txt @@ -1,30 +1,30 @@ - - Widget _buildSearchBarWithAction(BuildContext context) { - return Column( - children: [ - TDSearchBar( - placeHolder: '搜索预设文案', - alignment: TDSearchAlignment.left, - action: '搜索', - onActionClick: (String text) { - setState(() { - searchText = text; - }); - }, - onTextChanged: (String text) { - setState(() { - inputText = text; - }); - }, - ), - const SizedBox(height: 10,), - Container( - padding: const EdgeInsets.only(left: 15), - alignment: Alignment.centerLeft, - child: TDText( - '搜索框输入的内容:${searchText ?? ''}', - ), - ) - ], - ); + + Widget _buildSearchBarWithAction(BuildContext context) { + return Column( + children: [ + TDSearchBar( + placeHolder: '搜索预设文案', + alignment: TDSearchAlignment.left, + action: '搜索', + onActionClick: (String text) { + setState(() { + searchText = text; + }); + }, + onTextChanged: (String text) { + setState(() { + inputText = text; + }); + }, + ), + const SizedBox(height: 10,), + Container( + padding: const EdgeInsets.only(left: 15), + alignment: Alignment.centerLeft, + child: TDText( + '搜索框输入的内容:${searchText ?? ''}', + ), + ) + ], + ); } \ No newline at end of file From 44374025b137ef2d3b64b99dcd456441400787e7 Mon Sep 17 00:00:00 2001 From: Luozf12345 <2515187986@qq.com> Date: Sun, 13 Oct 2024 15:26:29 +0800 Subject: [PATCH 21/46] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E6=96=B0=E7=94=9F?= =?UTF-8?q?=E6=88=90=E7=9A=84api=E5=92=8C=E6=BC=94=E7=A4=BA=E4=BB=A3?= =?UTF-8?q?=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../example/assets/api/table_api.md | 21 +++ .../assets/code/calendar._buildBlock.txt | 9 + .../assets/code/calendar._buildSimple.txt | 159 ++++++++++++++++++ .../assets/code/calendar._buildStyle.txt | 97 +++++++++++ ...ader._buildTestVerticalCompanyCascader.txt | 25 +++ .../assets/code/cell._buildPadding.txt | 11 ++ .../code/datetimePicker._customStartTime.txt | 30 ++++ .../code/dialog._customContentAndBtn.txt | 32 ++++ .../assets/code/drawer._buildColorSimple.txt | 22 +++ .../code/dropdownMenu._buildOverflow.txt | 71 ++++++++ .../assets/code/indexes._buildOther.txt | 39 +++++ .../assets/code/indexes._buildSimple.txt | 38 +++++ .../assets/code/input._onTapOutside.txt | 30 ++++ .../assets/code/navbar._shadowNavbar.txt | 17 ++ .../assets/code/noticeBar._cardNoticeBar.txt | 54 ++++++ .../assets/code/noticeBar._closeNoticeBar.txt | 8 + .../code/noticeBar._customNoticeBar.txt | 9 + .../code/noticeBar._entranceNoticeBar1.txt | 15 ++ .../code/noticeBar._entranceNoticeBar2.txt | 11 ++ .../assets/code/noticeBar._errorNoticeBar.txt | 8 + .../assets/code/noticeBar._iconNoticeBar.txt | 7 + .../assets/code/noticeBar._leftNoticeBar.txt | 15 ++ .../code/noticeBar._normalNoticeBar.txt | 8 + .../code/noticeBar._scrollIconNoticeBar.txt | 12 ++ .../code/noticeBar._scrollNoticeBar.txt | 8 + .../assets/code/noticeBar._stepNoticeBar.txt | 9 + .../code/noticeBar._successNoticeBar.txt | 8 + .../assets/code/noticeBar._tapNoticeBar.txt | 11 ++ .../assets/code/noticeBar._textNoticeBar.txt | 4 + .../code/noticeBar._warningNoticeBar.txt | 8 + .../code/picker.buildCustomLeftRightText.txt | 35 ++++ .../code/sideBar._buildLoadingSideBar.txt | 41 +++++ .../example/assets/code/table._basicTable.txt | 12 ++ .../assets/code/table._borderTable.txt | 13 ++ .../assets/code/table._centerTable.txt | 12 ++ .../example/assets/code/table._emptyTable.txt | 11 ++ .../assets/code/table._fixedEndColTable.txt | 37 ++++ .../assets/code/table._fixedFirstColTable.txt | 12 ++ .../assets/code/table._fixedHeaderTable.txt | 14 ++ .../assets/code/table._fixedScrollTable.txt | 37 ++++ .../code/table._horizontalScrollTable.txt | 11 ++ .../assets/code/table._loadingTable.txt | 12 ++ .../assets/code/table._operationBtnTable.txt | 40 +++++ .../assets/code/table._operationIconTable.txt | 24 +++ .../assets/code/table._sortableTable.txt | 12 ++ .../assets/code/table._stripeTable.txt | 13 ++ .../assets/code/timeCounter._buildControl.txt | 60 +++++++ .../code/timeCounter._buildCustomNum.txt | 7 + .../timeCounter._buildCustomUnitLargeSize.txt | 10 ++ ...timeCounter._buildCustomUnitMediumSize.txt | 10 ++ .../timeCounter._buildCustomUnitSimple.txt | 6 + .../timeCounter._buildCustomUnitSmallSize.txt | 10 ++ .../code/timeCounter._buildLargeSize.txt | 7 + .../code/timeCounter._buildMediumSize.txt | 7 + .../timeCounter._buildMillisecondSimple.txt | 4 + .../code/timeCounter._buildRoundLargeSize.txt | 8 + .../timeCounter._buildRoundMediumSize.txt | 8 + .../code/timeCounter._buildRoundSimple.txt | 4 + .../code/timeCounter._buildRoundSmallSize.txt | 8 + .../assets/code/timeCounter._buildSimple.txt | 4 + .../code/timeCounter._buildSmallSize.txt | 7 + .../timeCounter._buildSquareLargeSize.txt | 8 + .../timeCounter._buildSquareMediumSize.txt | 8 + .../code/timeCounter._buildSquareSimple.txt | 4 + .../timeCounter._buildSquareSmallSize.txt | 8 + .../code/timeCounter._buildUnitLargeSize.txt | 9 + .../code/timeCounter._buildUnitMediumSize.txt | 9 + .../code/timeCounter._buildUnitSimple.txt | 4 + .../code/timeCounter._buildUnitSmallSize.txt | 9 + .../code/timeCounter._buildUpSimple.txt | 8 + .../assets/code/toast._preventTapToast.txt | 14 ++ 71 files changed, 1373 insertions(+) create mode 100644 tdesign-component/example/assets/api/table_api.md create mode 100644 tdesign-component/example/assets/code/calendar._buildBlock.txt create mode 100644 tdesign-component/example/assets/code/calendar._buildSimple.txt create mode 100644 tdesign-component/example/assets/code/calendar._buildStyle.txt create mode 100644 tdesign-component/example/assets/code/cascader._buildTestVerticalCompanyCascader.txt create mode 100644 tdesign-component/example/assets/code/cell._buildPadding.txt create mode 100644 tdesign-component/example/assets/code/datetimePicker._customStartTime.txt create mode 100644 tdesign-component/example/assets/code/dialog._customContentAndBtn.txt create mode 100644 tdesign-component/example/assets/code/drawer._buildColorSimple.txt create mode 100644 tdesign-component/example/assets/code/dropdownMenu._buildOverflow.txt create mode 100644 tdesign-component/example/assets/code/indexes._buildOther.txt create mode 100644 tdesign-component/example/assets/code/indexes._buildSimple.txt create mode 100644 tdesign-component/example/assets/code/input._onTapOutside.txt create mode 100644 tdesign-component/example/assets/code/navbar._shadowNavbar.txt create mode 100644 tdesign-component/example/assets/code/noticeBar._cardNoticeBar.txt create mode 100644 tdesign-component/example/assets/code/noticeBar._closeNoticeBar.txt create mode 100644 tdesign-component/example/assets/code/noticeBar._customNoticeBar.txt create mode 100644 tdesign-component/example/assets/code/noticeBar._entranceNoticeBar1.txt create mode 100644 tdesign-component/example/assets/code/noticeBar._entranceNoticeBar2.txt create mode 100644 tdesign-component/example/assets/code/noticeBar._errorNoticeBar.txt create mode 100644 tdesign-component/example/assets/code/noticeBar._iconNoticeBar.txt create mode 100644 tdesign-component/example/assets/code/noticeBar._leftNoticeBar.txt create mode 100644 tdesign-component/example/assets/code/noticeBar._normalNoticeBar.txt create mode 100644 tdesign-component/example/assets/code/noticeBar._scrollIconNoticeBar.txt create mode 100644 tdesign-component/example/assets/code/noticeBar._scrollNoticeBar.txt create mode 100644 tdesign-component/example/assets/code/noticeBar._stepNoticeBar.txt create mode 100644 tdesign-component/example/assets/code/noticeBar._successNoticeBar.txt create mode 100644 tdesign-component/example/assets/code/noticeBar._tapNoticeBar.txt create mode 100644 tdesign-component/example/assets/code/noticeBar._textNoticeBar.txt create mode 100644 tdesign-component/example/assets/code/noticeBar._warningNoticeBar.txt create mode 100644 tdesign-component/example/assets/code/picker.buildCustomLeftRightText.txt create mode 100644 tdesign-component/example/assets/code/sideBar._buildLoadingSideBar.txt create mode 100644 tdesign-component/example/assets/code/table._basicTable.txt create mode 100644 tdesign-component/example/assets/code/table._borderTable.txt create mode 100644 tdesign-component/example/assets/code/table._centerTable.txt create mode 100644 tdesign-component/example/assets/code/table._emptyTable.txt create mode 100644 tdesign-component/example/assets/code/table._fixedEndColTable.txt create mode 100644 tdesign-component/example/assets/code/table._fixedFirstColTable.txt create mode 100644 tdesign-component/example/assets/code/table._fixedHeaderTable.txt create mode 100644 tdesign-component/example/assets/code/table._fixedScrollTable.txt create mode 100644 tdesign-component/example/assets/code/table._horizontalScrollTable.txt create mode 100644 tdesign-component/example/assets/code/table._loadingTable.txt create mode 100644 tdesign-component/example/assets/code/table._operationBtnTable.txt create mode 100644 tdesign-component/example/assets/code/table._operationIconTable.txt create mode 100644 tdesign-component/example/assets/code/table._sortableTable.txt create mode 100644 tdesign-component/example/assets/code/table._stripeTable.txt create mode 100644 tdesign-component/example/assets/code/timeCounter._buildControl.txt create mode 100644 tdesign-component/example/assets/code/timeCounter._buildCustomNum.txt create mode 100644 tdesign-component/example/assets/code/timeCounter._buildCustomUnitLargeSize.txt create mode 100644 tdesign-component/example/assets/code/timeCounter._buildCustomUnitMediumSize.txt create mode 100644 tdesign-component/example/assets/code/timeCounter._buildCustomUnitSimple.txt create mode 100644 tdesign-component/example/assets/code/timeCounter._buildCustomUnitSmallSize.txt create mode 100644 tdesign-component/example/assets/code/timeCounter._buildLargeSize.txt create mode 100644 tdesign-component/example/assets/code/timeCounter._buildMediumSize.txt create mode 100644 tdesign-component/example/assets/code/timeCounter._buildMillisecondSimple.txt create mode 100644 tdesign-component/example/assets/code/timeCounter._buildRoundLargeSize.txt create mode 100644 tdesign-component/example/assets/code/timeCounter._buildRoundMediumSize.txt create mode 100644 tdesign-component/example/assets/code/timeCounter._buildRoundSimple.txt create mode 100644 tdesign-component/example/assets/code/timeCounter._buildRoundSmallSize.txt create mode 100644 tdesign-component/example/assets/code/timeCounter._buildSimple.txt create mode 100644 tdesign-component/example/assets/code/timeCounter._buildSmallSize.txt create mode 100644 tdesign-component/example/assets/code/timeCounter._buildSquareLargeSize.txt create mode 100644 tdesign-component/example/assets/code/timeCounter._buildSquareMediumSize.txt create mode 100644 tdesign-component/example/assets/code/timeCounter._buildSquareSimple.txt create mode 100644 tdesign-component/example/assets/code/timeCounter._buildSquareSmallSize.txt create mode 100644 tdesign-component/example/assets/code/timeCounter._buildUnitLargeSize.txt create mode 100644 tdesign-component/example/assets/code/timeCounter._buildUnitMediumSize.txt create mode 100644 tdesign-component/example/assets/code/timeCounter._buildUnitSimple.txt create mode 100644 tdesign-component/example/assets/code/timeCounter._buildUnitSmallSize.txt create mode 100644 tdesign-component/example/assets/code/timeCounter._buildUpSimple.txt create mode 100644 tdesign-component/example/assets/code/toast._preventTapToast.txt diff --git a/tdesign-component/example/assets/api/table_api.md b/tdesign-component/example/assets/api/table_api.md new file mode 100644 index 000000000..55a59ebec --- /dev/null +++ b/tdesign-component/example/assets/api/table_api.md @@ -0,0 +1,21 @@ +## API +### TDTable +#### 默认构造方法 + +| 参数 | 类型 | 默认值 | 说明 | +| --- | --- | --- | --- | +| key | | - | | +| bordered | bool? | - | 是否显示表格边框 | +| columns | List | - | 列配置 | +| data | List? | - | 数据源 | +| empty | TDTableEmpty? | - | 空表格呈现样式 | +| height | double? | - | 表格高度,超出后会出现滚动条 | +| loading | bool? | false | 加载中状态 | +| loadingWidget | Widget? | - | 自定义加载中状态 | +| showHeader | bool? | true | 是否显示表头 | +| stripe | bool? | false | 斑马纹 | +| backgroundColor | Color? | - | 表格背景色 | +| width | double? | - | 表格宽度 | +| defaultSort | String? | - | 默认排序 | +| onCellTap | OnCellTap? | - | 单元格点击事件 | +| onScroll | OnScroll? | - | 表格滚动事件 | diff --git a/tdesign-component/example/assets/code/calendar._buildBlock.txt b/tdesign-component/example/assets/code/calendar._buildBlock.txt new file mode 100644 index 000000000..6e28cf74a --- /dev/null +++ b/tdesign-component/example/assets/code/calendar._buildBlock.txt @@ -0,0 +1,9 @@ + +Widget _buildBlock(BuildContext context) { + final size = MediaQuery.of(context).size; + return TDCalendar( + title: '请选择日期', + value: [DateTime.now().millisecondsSinceEpoch], + height: size.height * 0.6 + 176, + ); +} \ No newline at end of file diff --git a/tdesign-component/example/assets/code/calendar._buildSimple.txt b/tdesign-component/example/assets/code/calendar._buildSimple.txt new file mode 100644 index 000000000..20e961ff7 --- /dev/null +++ b/tdesign-component/example/assets/code/calendar._buildSimple.txt @@ -0,0 +1,159 @@ + +Widget _buildSimple(BuildContext context) { + final size = MediaQuery.of(context).size; + final selected = ValueNotifier>([DateTime.now().millisecondsSinceEpoch]); + return ValueListenableBuilder( + valueListenable: selected, + builder: (context, value, child) { + final date = DateTime.fromMillisecondsSinceEpoch(value[0]); + return TDCellGroup( + cells: [ + TDCell( + title: '单个选择日历', + arrow: true, + note: '${date.year}-${date.month}-${date.day}', + onClick: (cell) { + TDCalendarPopup( + context, + visible: true, + onConfirm: (value) { + print('onConfirm:$value'); + selected.value = value; + }, + onClose: () { + print('onClose'); + }, + child: TDCalendar( + title: '请选择日期', + value: value, + height: size.height * 0.6 + 176, + onCellClick: (value, type, tdate) { + print('onCellClick:$value'); + }, + onCellLongPress: (value, type, tdate) { + print('onCellLongPress:$value'); + }, + onHeanderClick: (index, week) { + print('onHeanderClick:$week'); + }, + onChange: (value) { + print('onChange:$value'); + }, + ), + ); + }, + ), + TDCell( + title: '多个选择日历', + arrow: true, + onClick: (cell) { + TDCalendarPopup( + context, + visible: true, + child: TDCalendar( + title: '请选择日期', + type: CalendarType.multiple, + value: [DateTime.now().millisecondsSinceEpoch], + height: size.height * 0.6 + 176, + ), + ); + }, + ), + TDCell( + title: '区间选择日历', + arrow: true, + onClick: (cell) { + TDCalendarPopup( + context, + visible: true, + child: TDCalendar( + title: '请选择日期区间', + type: CalendarType.range, + value: [ + DateTime.now().millisecondsSinceEpoch, + DateTime.now().add(const Duration(days: 6)).millisecondsSinceEpoch, + ], + height: size.height * 0.6 + 176, + ), + ); + }, + ), + TDCell( + title: '单个选择日历和时间', + arrow: true, + note: '${date.year}-${date.month}-${date.day} ${date.hour}:${date.minute}', + onClick: (cell) { + TDCalendarPopup( + context, + visible: true, + onConfirm: (value) { + print('onConfirm:$value'); + selected.value = value; + }, + onClose: () { + print('onClose'); + }, + child: TDCalendar( + title: '请选择日期和时间', + value: value, + height: size.height * 0.92, + useTimePicker: true, + onCellClick: (value, type, tdate) { + print('onCellClick:$value'); + }, + onCellLongPress: (value, type, tdate) { + print('onCellLongPress:$value'); + }, + onHeanderClick: (index, week) { + print('onHeanderClick:$week'); + }, + onChange: (value) { + print('onChange:$value'); + }, + ), + ); + }, + ), + TDCell( + title: '区间选择日历和时间', + arrow: true, + onClick: (cell) { + TDCalendarPopup( + context, + visible: true, + onConfirm: (value) { + print('onConfirm:$value'); + }, + onClose: () { + print('onClose'); + }, + child: TDCalendar( + title: '请选择日期和时间区间', + height: size.height * 0.92, + type: CalendarType.range, + value: [ + DateTime.now().millisecondsSinceEpoch, + DateTime.now().add(const Duration(days: 3)).millisecondsSinceEpoch, + ], + useTimePicker: true, + onCellClick: (value, type, tdate) { + print('onCellClick:$value'); + }, + onCellLongPress: (value, type, tdate) { + print('onCellLongPress:$value'); + }, + onHeanderClick: (index, week) { + print('onHeanderClick:$week'); + }, + onChange: (value) { + print('onChange:$value'); + }, + ), + ); + }, + ), + ], + ); + }, + ); +} \ No newline at end of file diff --git a/tdesign-component/example/assets/code/calendar._buildStyle.txt b/tdesign-component/example/assets/code/calendar._buildStyle.txt new file mode 100644 index 000000000..c75c1d656 --- /dev/null +++ b/tdesign-component/example/assets/code/calendar._buildStyle.txt @@ -0,0 +1,97 @@ + +Widget _buildStyle(BuildContext context) { + final size = MediaQuery.of(context).size; + const map = { + 1: '初一', + 2: '初二', + 3: '初三', + 14: '情人节', + 15: '元宵节', + }; + return TDCellGroup( + cells: [ + TDCell( + title: '自定义文案', + arrow: true, + onClick: (cell) { + TDCalendarPopup( + context, + visible: true, + child: TDCalendar( + title: '请选择日期', + height: size.height * 0.6 + 176, + minDate: DateTime(2022, 1, 1).millisecondsSinceEpoch, + maxDate: DateTime(2022, 2, 15).millisecondsSinceEpoch, + format: (day) { + day?.suffix = '¥60'; + if (day?.date.month == 2) { + if (map.keys.contains(day?.date.day)) { + day?.suffix = '¥100'; + day?.prefix = map[day.date.day]; + day?.style = TextStyle( + fontSize: TDTheme.of(context).fontTitleMedium?.size, + height: TDTheme.of(context).fontTitleMedium?.height, + fontWeight: TDTheme.of(context).fontTitleMedium?.fontWeight, + color: TDTheme.of(context).errorColor6, + ); + if (day?.typeNotifier.value == DateSelectType.selected) { + day?.style = day.style?.copyWith(color: TDTheme.of(context).fontWhColor1); + } + } + } + return null; + }, + ), + ); + }, + ), + TDCell( + title: '自定义按钮', + arrow: true, + onClick: (cell) { + late final TDCalendarPopup calendar; + calendar = TDCalendarPopup( + context, + visible: true, + confirmBtn: Padding( + padding: EdgeInsets.symmetric(vertical: TDTheme.of(context).spacer16), + child: TDButton( + theme: TDButtonTheme.danger, + shape: TDButtonShape.round, + text: 'ok', + isBlock: true, + size: TDButtonSize.large, + onTap: () { + print(calendar.selected); + calendar.close(); + }, + ), + ), + child: TDCalendar( + title: '请选择日期', + value: [DateTime.now().millisecondsSinceEpoch], + height: size.height * 0.6 + 176, + ), + ); + }, + ), + TDCell( + title: '自定义日期区间', + arrow: true, + onClick: (cell) { + TDCalendarPopup( + context, + visible: true, + child: TDCalendar( + title: '请选择日期', + minDate: DateTime(2022, 1, 1).millisecondsSinceEpoch, + maxDate: DateTime(2022, 1, 31).millisecondsSinceEpoch, + value: [DateTime(2022, 1, 15).millisecondsSinceEpoch], + height: size.height * 0.6 + 176, + ), + ); + }, + ), + ], + ); +} \ No newline at end of file diff --git a/tdesign-component/example/assets/code/cascader._buildTestVerticalCompanyCascader.txt b/tdesign-component/example/assets/code/cascader._buildTestVerticalCompanyCascader.txt new file mode 100644 index 000000000..64043774d --- /dev/null +++ b/tdesign-component/example/assets/code/cascader._buildTestVerticalCompanyCascader.txt @@ -0,0 +1,25 @@ + + Widget _buildTestVerticalCompanyCascader(BuildContext context) { + return GestureDetector( + onTap: () { + TDCascader.showMultiCascader(context, + title: '选择部门人员', + data: _data_4, + initialData: _initData, + theme: 'step', onChange: (List selectData) { + setState(() { + List result = []; + int len = selectData.length; + _initData = selectData[len - 1].value!; + selectData.forEach((element) { + result.add(element.label); + }); + _selected_4 = result.join('/'); + }); + }, onClose: () { + Navigator.of(context).pop(); + }); + }, + child: _buildSelectRow(context, _selected_4, '选择部门人员'), + ); + } \ No newline at end of file diff --git a/tdesign-component/example/assets/code/cell._buildPadding.txt b/tdesign-component/example/assets/code/cell._buildPadding.txt new file mode 100644 index 000000000..e5c4bf7cd --- /dev/null +++ b/tdesign-component/example/assets/code/cell._buildPadding.txt @@ -0,0 +1,11 @@ + +Widget _buildPadding(BuildContext context) { + var style = TDCellStyle.cellStyle(context); + style.padding = const EdgeInsets.all(30); + return TDCellGroup( + theme: TDCellGroupTheme.cardTheme, + cells: [ + TDCell(arrow: true, title: 'padding-all-30', style: style,), + ], + ); +} \ No newline at end of file diff --git a/tdesign-component/example/assets/code/datetimePicker._customStartTime.txt b/tdesign-component/example/assets/code/datetimePicker._customStartTime.txt new file mode 100644 index 000000000..4a43d170a --- /dev/null +++ b/tdesign-component/example/assets/code/datetimePicker._customStartTime.txt @@ -0,0 +1,30 @@ + + Widget _customStartTime(BuildContext context) { + + return GestureDetector( + onTap: (){ + TDPicker.showDatePicker(context, title: '选择时间', + onConfirm: (selected) { + setState(() { + selected_5 = '${selected['year'].toString().padLeft(4, '0')}-' + '${selected['month'].toString().padLeft(2, '0')}-' + '${selected['day'].toString().padLeft(2, '0')} ' + '${selected['hour'].toString().padLeft(2, '0')}:' + '${selected['minute'].toString().padLeft(2, '0')}:' + '${selected['second'].toString().padLeft(2, '0')}'; + }); + Navigator.of(context).pop(); + }, + useYear: true, + useMonth: true, + useDay: true, + useHour: true, + useMinute: true, + useSecond: true, + dateStart: [2012,1, 15,12,28,11], + dateEnd: [2012, 6, 15,12,48,32], + initialDate: [2012, 1, 15,13,20]); + }, + child: buildSelectRow(context, selected_5, '选择时间'), + ); + } \ No newline at end of file diff --git a/tdesign-component/example/assets/code/dialog._customContentAndBtn.txt b/tdesign-component/example/assets/code/dialog._customContentAndBtn.txt new file mode 100644 index 000000000..f12b6d4f2 --- /dev/null +++ b/tdesign-component/example/assets/code/dialog._customContentAndBtn.txt @@ -0,0 +1,32 @@ + + Widget _customContentAndBtn(BuildContext context) { + return TDButton( + text: '自定义边距和按钮', + size: TDButtonSize.large, + type: TDButtonType.outline, + theme: TDButtonTheme.primary, + onTap: () { + showGeneralDialog( + context: context, + pageBuilder: (BuildContext buildContext, Animation animation, + Animation secondaryAnimation) { + return TDConfirmDialog( + title: _dialogTitle, + content: _commonContent, + padding: const EdgeInsets.fromLTRB(8, 8, 8, 0), + buttonWidget: Container( + padding: const EdgeInsets.fromLTRB(0, 16, 0, 16), + child: TDButton( + text: '自定义按钮', + theme: TDButtonTheme.primary, + onTap: () { + Navigator.of(context).pop(); + }, + ), + ), + ); + } + ); + } + ); + } \ No newline at end of file diff --git a/tdesign-component/example/assets/code/drawer._buildColorSimple.txt b/tdesign-component/example/assets/code/drawer._buildColorSimple.txt new file mode 100644 index 000000000..5b4109820 --- /dev/null +++ b/tdesign-component/example/assets/code/drawer._buildColorSimple.txt @@ -0,0 +1,22 @@ + +Widget _buildColorSimple(BuildContext context) { + var renderBox = navBarkey.currentContext?.findRenderObject() as RenderBox?; + return TDButton( + text: '自定义背景色', + isBlock: true, + type: TDButtonType.outline, + theme: TDButtonTheme.primary, + size: TDButtonSize.large, + onTap: () { + TDDrawer( + context, + visible: true, + drawerTop: renderBox?.size.height, + title: '标题', + backgroundColor: TDTheme.of(context).grayColor1, + placement: TDDrawerPlacement.right, + items: List.generate(10, (index) => TDDrawerItem(title: '菜单${_nums[index]}')).toList(), + ); + }, + ); +} \ No newline at end of file diff --git a/tdesign-component/example/assets/code/dropdownMenu._buildOverflow.txt b/tdesign-component/example/assets/code/dropdownMenu._buildOverflow.txt new file mode 100644 index 000000000..e1b86c72b --- /dev/null +++ b/tdesign-component/example/assets/code/dropdownMenu._buildOverflow.txt @@ -0,0 +1,71 @@ + +TDDropdownMenu _buildOverflow(BuildContext context) { + return TDDropdownMenu( + isScrollable: true, + tabBarAlign: MainAxisAlignment.spaceAround, + direction: TDDropdownMenuDirection.up, + onMenuOpened: (value) { + print('打开第$value个菜单'); + }, + onMenuClosed: (value) { + print('关闭第$value个菜单'); + }, + builder: (context) { + return [ + TDDropdownItem( + label: '最大高度限制', + multiple: true, + maxHeight: 200, + tabBarWidth: 200, + options: [ + TDDropdownItemOption(label: '选项1', value: '1', selected: true), + TDDropdownItemOption(label: '选项2', value: '2', selected: true), + TDDropdownItemOption(label: '选项3', value: '3', selected: true), + TDDropdownItemOption(label: '选项4', value: '4'), + TDDropdownItemOption(label: '选项5', value: '5'), + TDDropdownItemOption(label: '选项6', value: '6'), + TDDropdownItemOption(label: '选项7', value: '7'), + TDDropdownItemOption(label: '选项8', value: '8'), + TDDropdownItemOption(label: '选项9', value: '9'), + TDDropdownItemOption(label: '禁用选项', value: '10', disabled: true), + TDDropdownItemOption(label: '禁用选项', value: '11', disabled: true), + TDDropdownItemOption(label: '禁用选项', value: '12', disabled: true), + ], + onChange: (value) { + print('选择:$value'); + }, + ), + TDDropdownItem( + maxHeight: 200, + tabBarWidth: 200, + tabBarAlign: MainAxisAlignment.start, + options: [ + TDDropdownItemOption(label: '选项1', value: '1', selected: true), + TDDropdownItemOption(label: '选项2', value: '2'), + ], + ), + TDDropdownItem( + maxHeight: 200, + options: [ + TDDropdownItemOption(label: '选项1', value: '1', selected: true), + TDDropdownItemOption(label: '选项2', value: '2'), + ], + ), + TDDropdownItem( + maxHeight: 200, + options: [ + TDDropdownItemOption(label: '选项1', value: '1', selected: true), + TDDropdownItemOption(label: '选项2', value: '2'), + ], + ), + TDDropdownItem( + maxHeight: 200, + options: [ + TDDropdownItemOption(label: '选项1', value: '1', selected: true), + TDDropdownItemOption(label: '选项2', value: '2'), + ], + ), + ]; + }, + ); +} \ No newline at end of file diff --git a/tdesign-component/example/assets/code/indexes._buildOther.txt b/tdesign-component/example/assets/code/indexes._buildOther.txt new file mode 100644 index 000000000..1ce807683 --- /dev/null +++ b/tdesign-component/example/assets/code/indexes._buildOther.txt @@ -0,0 +1,39 @@ + +Widget _buildOther(BuildContext context) { + final renderBox = navBarkey.currentContext?.findRenderObject() as RenderBox?; + final indexList = _list.map((item) => item['index'] as String).toList(); + return TDButton( + text: '胶囊索引', + isBlock: true, + size: TDButtonSize.large, + theme: TDButtonTheme.primary, + type: TDButtonType.outline, + onTap: () { + Navigator.of(context).push( + TDSlidePopupRoute( + slideTransitionFrom: SlideTransitionFrom.right, + modalTop: renderBox?.size.height, + builder: (context) { + return Container( + color: Colors.white, + child: TDIndexes( + indexList: indexList, + capsuleTheme: true, + builderContent: (context, index) { + final list = _list.firstWhere((element) => element['index'] == index)['children'] as List; + return TDCellGroup( + cells: list + .map((e) => TDCell( + title: e, + )) + .toList(), + ); + }, + ), + ); + }, + ), + ); + }, + ); +} \ No newline at end of file diff --git a/tdesign-component/example/assets/code/indexes._buildSimple.txt b/tdesign-component/example/assets/code/indexes._buildSimple.txt new file mode 100644 index 000000000..c2563b24d --- /dev/null +++ b/tdesign-component/example/assets/code/indexes._buildSimple.txt @@ -0,0 +1,38 @@ + +Widget _buildSimple(BuildContext context) { + final renderBox = navBarkey.currentContext?.findRenderObject() as RenderBox?; + final indexList = _list.map((item) => item['index'] as String).toList(); + return TDButton( + text: '基础用法', + isBlock: true, + size: TDButtonSize.large, + theme: TDButtonTheme.primary, + type: TDButtonType.outline, + onTap: () { + Navigator.of(context).push( + TDSlidePopupRoute( + slideTransitionFrom: SlideTransitionFrom.right, + modalTop: renderBox?.size.height, + builder: (context) { + return Container( + color: Colors.white, + child: TDIndexes( + indexList: indexList, + builderContent: (context, index) { + final list = _list.firstWhere((element) => element['index'] == index)['children'] as List; + return TDCellGroup( + cells: list + .map((e) => TDCell( + title: e, + )) + .toList(), + ); + }, + ), + ); + }, + ), + ); + }, + ); +} \ No newline at end of file diff --git a/tdesign-component/example/assets/code/input._onTapOutside.txt b/tdesign-component/example/assets/code/input._onTapOutside.txt new file mode 100644 index 000000000..02be7f62c --- /dev/null +++ b/tdesign-component/example/assets/code/input._onTapOutside.txt @@ -0,0 +1,30 @@ + + Widget _onTapOutside(BuildContext context) { + var controller = TextEditingController(); + return Container( + color: Colors.yellow, + alignment: Alignment.center, + height: 90, + child: SizedBox( + height: 60, + child: TDInput( + size: TDInputSize.small, + leftLabel: '标签文字', + controller: controller, + backgroundColor: Colors.white, + hintText: '请输入文字', + onChanged: (text) { + setState(() {}); + }, + onClearTap: () { + controller.clear(); + setState(() {}); + }, + onTapOutside: (event) { + TDToast.showText('点击输入框外部区域', context: context); + print('on tap outside ${event}'); + }, + ), + ), + ); + } \ No newline at end of file diff --git a/tdesign-component/example/assets/code/navbar._shadowNavbar.txt b/tdesign-component/example/assets/code/navbar._shadowNavbar.txt new file mode 100644 index 000000000..cbcc7e006 --- /dev/null +++ b/tdesign-component/example/assets/code/navbar._shadowNavbar.txt @@ -0,0 +1,17 @@ + + Widget _shadowNavbar(BuildContext context) { + return TDNavBar( + height: 48, + titleFontWeight: FontWeight.w600, + title: titleText, + screenAdaptation: false, + useDefaultBack: true, + boxShadow: [ + BoxShadow( + blurRadius: 4, + offset: const Offset(0, 4), + color: TDTheme.of(context).grayColor5, + ) + ], + ); + } \ No newline at end of file diff --git a/tdesign-component/example/assets/code/noticeBar._cardNoticeBar.txt b/tdesign-component/example/assets/code/noticeBar._cardNoticeBar.txt new file mode 100644 index 000000000..df57b978e --- /dev/null +++ b/tdesign-component/example/assets/code/noticeBar._cardNoticeBar.txt @@ -0,0 +1,54 @@ + +Widget _cardNoticeBar(BuildContext context) { + var size = MediaQuery.of(context).size; + return Container( + margin: const EdgeInsets.symmetric(horizontal: 16), + decoration: BoxDecoration( + color: TDNoticeBarStyle.generateTheme(context).backgroundColor, + borderRadius: const BorderRadius.all(Radius.circular(9)), + boxShadow: const [ + BoxShadow( + color: Color(0x0d000000), + blurRadius: 8, + spreadRadius: 2, + offset: Offset(0, 2), + ), + BoxShadow( + color: Color(0x0f000000), + blurRadius: 10, + spreadRadius: 1, + offset: Offset(0, 8), + ), + BoxShadow( + color: Color(0x1a000000), + blurRadius: 5, + spreadRadius: -3, + offset: Offset(0, 5), + ), + ], + ), + child: Column( + children: [ + Container( + width: size.width - 32, + decoration: const BoxDecoration( + borderRadius: BorderRadius.all(Radius.circular(12)), + ), + clipBehavior: Clip.hardEdge, + child: const TDNoticeBar( + context: '这是一条普通的通知信息', + prefixIcon: TDIcons.error_circle_filled, + suffixIcon: TDIcons.chevron_right, + ), + ), + Container( + height: 150, + decoration: const BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.all(Radius.circular(12)), + ), + ) + ], + ), + ); +} \ No newline at end of file diff --git a/tdesign-component/example/assets/code/noticeBar._closeNoticeBar.txt b/tdesign-component/example/assets/code/noticeBar._closeNoticeBar.txt new file mode 100644 index 000000000..72079a158 --- /dev/null +++ b/tdesign-component/example/assets/code/noticeBar._closeNoticeBar.txt @@ -0,0 +1,8 @@ + +Widget _closeNoticeBar(BuildContext context) { + return const TDNoticeBar( + context: '这是一条普通的通知信息', + prefixIcon: TDIcons.error_circle_filled, + suffixIcon: TDIcons.close, + ); +} \ No newline at end of file diff --git a/tdesign-component/example/assets/code/noticeBar._customNoticeBar.txt b/tdesign-component/example/assets/code/noticeBar._customNoticeBar.txt new file mode 100644 index 000000000..90bf32b21 --- /dev/null +++ b/tdesign-component/example/assets/code/noticeBar._customNoticeBar.txt @@ -0,0 +1,9 @@ + +Widget _customNoticeBar(BuildContext context) { + return TDNoticeBar( + context: '这是一条普通的通知信息', + prefixIcon: TDIcons.notification, + suffixIcon: TDIcons.chevron_right, + style: TDNoticeBarStyle(backgroundColor: TDTheme.of(context).grayColor3), + ); +} \ No newline at end of file diff --git a/tdesign-component/example/assets/code/noticeBar._entranceNoticeBar1.txt b/tdesign-component/example/assets/code/noticeBar._entranceNoticeBar1.txt new file mode 100644 index 000000000..500443ec4 --- /dev/null +++ b/tdesign-component/example/assets/code/noticeBar._entranceNoticeBar1.txt @@ -0,0 +1,15 @@ + +Widget _entranceNoticeBar1(BuildContext context) { + return const TDNoticeBar( + context: '这是一条普通的通知信息', + prefixIcon: TDIcons.error_circle_filled, + right: TDButton( + text: '文字按钮', + type: TDButtonType.text, + theme: TDButtonTheme.primary, + size: TDButtonSize.extraSmall, + height: 22, + padding: EdgeInsets.symmetric(vertical: 0, horizontal: 0), + ), + ); +} \ No newline at end of file diff --git a/tdesign-component/example/assets/code/noticeBar._entranceNoticeBar2.txt b/tdesign-component/example/assets/code/noticeBar._entranceNoticeBar2.txt new file mode 100644 index 000000000..40d2a5bc6 --- /dev/null +++ b/tdesign-component/example/assets/code/noticeBar._entranceNoticeBar2.txt @@ -0,0 +1,11 @@ + +Widget _entranceNoticeBar2(BuildContext context) { + return const Padding( + padding: EdgeInsets.only(top: 16), + child: TDNoticeBar( + context: '这是一条普通的通知信息', + prefixIcon: TDIcons.error_circle_filled, + suffixIcon: TDIcons.chevron_right, + ), + ); +} \ No newline at end of file diff --git a/tdesign-component/example/assets/code/noticeBar._errorNoticeBar.txt b/tdesign-component/example/assets/code/noticeBar._errorNoticeBar.txt new file mode 100644 index 000000000..831330e17 --- /dev/null +++ b/tdesign-component/example/assets/code/noticeBar._errorNoticeBar.txt @@ -0,0 +1,8 @@ + +Widget _errorNoticeBar(BuildContext context) { + return const TDNoticeBar( + context: '这是一条普通的通知信息', + prefixIcon: TDIcons.error_circle_filled, + theme: TDNoticeBarTheme.error, + ); +} \ No newline at end of file diff --git a/tdesign-component/example/assets/code/noticeBar._iconNoticeBar.txt b/tdesign-component/example/assets/code/noticeBar._iconNoticeBar.txt new file mode 100644 index 000000000..65ea94bb3 --- /dev/null +++ b/tdesign-component/example/assets/code/noticeBar._iconNoticeBar.txt @@ -0,0 +1,7 @@ + +Widget _iconNoticeBar(BuildContext context) { + return const TDNoticeBar( + context: '这是一条普通的通知信息', + prefixIcon: TDIcons.error_circle_filled, + ); +} \ No newline at end of file diff --git a/tdesign-component/example/assets/code/noticeBar._leftNoticeBar.txt b/tdesign-component/example/assets/code/noticeBar._leftNoticeBar.txt new file mode 100644 index 000000000..f8e0d026b --- /dev/null +++ b/tdesign-component/example/assets/code/noticeBar._leftNoticeBar.txt @@ -0,0 +1,15 @@ + +Widget _leftNoticeBar(BuildContext context) { + return const TDNoticeBar( + context: '这是一条普通的通知信息', + suffixIcon: TDIcons.chevron_right, + left: TDButton( + text: '文本', + type: TDButtonType.text, + theme: TDButtonTheme.primary, + size: TDButtonSize.extraSmall, + height: 22, + padding: EdgeInsets.symmetric(vertical: 0, horizontal: 0), + ), + ); +} \ No newline at end of file diff --git a/tdesign-component/example/assets/code/noticeBar._normalNoticeBar.txt b/tdesign-component/example/assets/code/noticeBar._normalNoticeBar.txt new file mode 100644 index 000000000..1fd7bd8d3 --- /dev/null +++ b/tdesign-component/example/assets/code/noticeBar._normalNoticeBar.txt @@ -0,0 +1,8 @@ + +Widget _normalNoticeBar(BuildContext context) { + return const TDNoticeBar( + context: '这是一条普通的通知信息', + prefixIcon: TDIcons.error_circle_filled, + theme: TDNoticeBarTheme.info, + ); +} \ No newline at end of file diff --git a/tdesign-component/example/assets/code/noticeBar._scrollIconNoticeBar.txt b/tdesign-component/example/assets/code/noticeBar._scrollIconNoticeBar.txt new file mode 100644 index 000000000..ad9666ec4 --- /dev/null +++ b/tdesign-component/example/assets/code/noticeBar._scrollIconNoticeBar.txt @@ -0,0 +1,12 @@ + +Widget _scrollIconNoticeBar(BuildContext context) { + return const Padding( + padding: EdgeInsets.only(top: 16), + child: TDNoticeBar( + context: '提示文字描述提示文字描述提示文字描述提示文字描述提示文字', + speed: 50, + prefixIcon: TDIcons.sound, + marquee: true, + ), + ); +} \ No newline at end of file diff --git a/tdesign-component/example/assets/code/noticeBar._scrollNoticeBar.txt b/tdesign-component/example/assets/code/noticeBar._scrollNoticeBar.txt new file mode 100644 index 000000000..ebdb515c8 --- /dev/null +++ b/tdesign-component/example/assets/code/noticeBar._scrollNoticeBar.txt @@ -0,0 +1,8 @@ + +Widget _scrollNoticeBar(BuildContext context) { + return const TDNoticeBar( + context: '提示文字描述提示文字描述提示文字描述提示文字描述提示文字', + marquee: true, + speed: 50, + ); +} \ No newline at end of file diff --git a/tdesign-component/example/assets/code/noticeBar._stepNoticeBar.txt b/tdesign-component/example/assets/code/noticeBar._stepNoticeBar.txt new file mode 100644 index 000000000..ff29ca57e --- /dev/null +++ b/tdesign-component/example/assets/code/noticeBar._stepNoticeBar.txt @@ -0,0 +1,9 @@ + +Widget _stepNoticeBar(BuildContext context) { + return const TDNoticeBar( + context: ['君不见黄河之水天上来', '奔流到海不复回', '君不见'], + direction: Axis.vertical, + prefixIcon: TDIcons.sound, + marquee: true, + ); +} \ No newline at end of file diff --git a/tdesign-component/example/assets/code/noticeBar._successNoticeBar.txt b/tdesign-component/example/assets/code/noticeBar._successNoticeBar.txt new file mode 100644 index 000000000..227263ceb --- /dev/null +++ b/tdesign-component/example/assets/code/noticeBar._successNoticeBar.txt @@ -0,0 +1,8 @@ + +Widget _successNoticeBar(BuildContext context) { + return const TDNoticeBar( + context: '这是一条普通的通知信息', + prefixIcon: TDIcons.error_circle_filled, + theme: TDNoticeBarTheme.success, + ); +} \ No newline at end of file diff --git a/tdesign-component/example/assets/code/noticeBar._tapNoticeBar.txt b/tdesign-component/example/assets/code/noticeBar._tapNoticeBar.txt new file mode 100644 index 000000000..b5f6a0b43 --- /dev/null +++ b/tdesign-component/example/assets/code/noticeBar._tapNoticeBar.txt @@ -0,0 +1,11 @@ + +Widget _tapNoticeBar(BuildContext context) { + return TDNoticeBar( + context: '这是一条普通的通知信息', + prefixIcon: TDIcons.error_circle_filled, + suffixIcon: TDIcons.chevron_right, + onTap: (trigger) { + TDToast.showText('tap:$trigger', context: context); + }, + ); +} \ No newline at end of file diff --git a/tdesign-component/example/assets/code/noticeBar._textNoticeBar.txt b/tdesign-component/example/assets/code/noticeBar._textNoticeBar.txt new file mode 100644 index 000000000..a68bb06bb --- /dev/null +++ b/tdesign-component/example/assets/code/noticeBar._textNoticeBar.txt @@ -0,0 +1,4 @@ + +Widget _textNoticeBar(BuildContext context) { + return const TDNoticeBar(context: '这是一条普通的通知信息'); +} \ No newline at end of file diff --git a/tdesign-component/example/assets/code/noticeBar._warningNoticeBar.txt b/tdesign-component/example/assets/code/noticeBar._warningNoticeBar.txt new file mode 100644 index 000000000..34b9137d4 --- /dev/null +++ b/tdesign-component/example/assets/code/noticeBar._warningNoticeBar.txt @@ -0,0 +1,8 @@ + +Widget _warningNoticeBar(BuildContext context) { + return const TDNoticeBar( + context: '这是一条普通的通知信息', + prefixIcon: TDIcons.error_circle_filled, + theme: TDNoticeBarTheme.warning, + ); +} \ No newline at end of file diff --git a/tdesign-component/example/assets/code/picker.buildCustomLeftRightText.txt b/tdesign-component/example/assets/code/picker.buildCustomLeftRightText.txt new file mode 100644 index 000000000..ff0ec571c --- /dev/null +++ b/tdesign-component/example/assets/code/picker.buildCustomLeftRightText.txt @@ -0,0 +1,35 @@ + + Widget buildCustomLeftRightText(BuildContext context) { + return Column( + children: [ + GestureDetector( + onTap: () { + TDPicker.showMultiPicker(context, + leftText: '自定义取消', + rightText: '自定义确认', + title: '基础选择器', onConfirm: (selected) { + setState(() { + selected_5 = '${data_1[selected[0]]}'; + }); + Navigator.of(context).pop(); + }, data: [data_1]); + }, + child: buildSelectRow(context, selected_5, '基础选择器'), + ), + GestureDetector( + onTap: () { + TDPicker.showMultiLinkedPicker(context, + leftText: '自定义取消', + rightText: '自定义确认', + title: '联动选择器', onConfirm: (selected) { + setState(() { + selected_3 = '${selected[0]} ${selected[1]} ${selected[2]}'; + }); + Navigator.of(context).pop(); + }, data: data_3, columnNum: 3, initialData: ['浙江省', '杭州市', '西湖区']); + }, + child: buildSelectRow(context, selected_3, '联动选择器'), + ) + ], + ); + } \ No newline at end of file diff --git a/tdesign-component/example/assets/code/sideBar._buildLoadingSideBar.txt b/tdesign-component/example/assets/code/sideBar._buildLoadingSideBar.txt new file mode 100644 index 000000000..a137c9589 --- /dev/null +++ b/tdesign-component/example/assets/code/sideBar._buildLoadingSideBar.txt @@ -0,0 +1,41 @@ + + Widget _buildLoadingSideBar(BuildContext context) { + // 延迟加载 + Future.delayed(const Duration(seconds: 3), _initData); + var size = MediaQuery.of(context).size; + var demoHeight = size.height; + + return Row( + children: [ + SizedBox( + width: list.isEmpty ? size.width : 110, + child: TDSideBar( + height: demoHeight, + style: TDSideBarStyle.normal, + value: currentValue, + controller: _sideBarController, + loading: true, + children: list + .map((ele) => TDSideBarItem( + label: ele.label ?? '', + badge: ele.badge, + value: ele.value, + icon: ele.icon)) + .toList(), + onChanged: onChanged, + onSelected: onSelected, + ), + ), + Expanded( + child: SizedBox( + height: demoHeight, + child: SingleChildScrollView( + controller: _demoScroller, + child: Column( + children: pages, + ), + ), + )) + ], + ); + } \ No newline at end of file diff --git a/tdesign-component/example/assets/code/table._basicTable.txt b/tdesign-component/example/assets/code/table._basicTable.txt new file mode 100644 index 000000000..b66105746 --- /dev/null +++ b/tdesign-component/example/assets/code/table._basicTable.txt @@ -0,0 +1,12 @@ + + Widget _basicTable(BuildContext context) { + return TDTable( + columns: [ + TDTableCol(title: '标题', colKey: 'title1', ellipsis: true), + TDTableCol(title: '标题', colKey: 'title2'), + TDTableCol(title: '标题', colKey: 'title3'), + TDTableCol(title: '标题', colKey: 'title4') + ], + data: _getData(9), + ); + } \ No newline at end of file diff --git a/tdesign-component/example/assets/code/table._borderTable.txt b/tdesign-component/example/assets/code/table._borderTable.txt new file mode 100644 index 000000000..82b1f433a --- /dev/null +++ b/tdesign-component/example/assets/code/table._borderTable.txt @@ -0,0 +1,13 @@ + + Widget _borderTable(BuildContext context) { + return TDTable( + bordered: true, + columns: [ + TDTableCol(title: '标题', colKey: 'title1', ellipsis: true), + TDTableCol(title: '标题', colKey: 'title2'), + TDTableCol(title: '标题', colKey: 'title3'), + TDTableCol(title: '标题', colKey: 'title4') + ], + data: _getData(9), + ); + } \ No newline at end of file diff --git a/tdesign-component/example/assets/code/table._centerTable.txt b/tdesign-component/example/assets/code/table._centerTable.txt new file mode 100644 index 000000000..8bbe11c9f --- /dev/null +++ b/tdesign-component/example/assets/code/table._centerTable.txt @@ -0,0 +1,12 @@ + + Widget _centerTable(BuildContext context) { + return TDTable( + columns: [ + TDTableCol(title: '标题', colKey: 'title1', align: TDTableColAlign.center), + TDTableCol(title: '标题', colKey: 'title2', align: TDTableColAlign.center), + TDTableCol(title: '标题', colKey: 'title3', align: TDTableColAlign.center), + TDTableCol(title: '标题', colKey: 'title4', align: TDTableColAlign.center) + ], + data: _getData(10), + ); + } \ No newline at end of file diff --git a/tdesign-component/example/assets/code/table._emptyTable.txt b/tdesign-component/example/assets/code/table._emptyTable.txt new file mode 100644 index 000000000..8b0ce5ce3 --- /dev/null +++ b/tdesign-component/example/assets/code/table._emptyTable.txt @@ -0,0 +1,11 @@ + + Widget _emptyTable(BuildContext context) { + return TDTable( + columns: [ + TDTableCol(title: '标题', colKey: 'title1'), + TDTableCol(title: '标题', colKey: 'title2'), + TDTableCol(title: '标题', colKey: 'title3'), + TDTableCol(title: '标题', colKey: 'title4') + ], + ); + } \ No newline at end of file diff --git a/tdesign-component/example/assets/code/table._fixedEndColTable.txt b/tdesign-component/example/assets/code/table._fixedEndColTable.txt new file mode 100644 index 000000000..792c69a63 --- /dev/null +++ b/tdesign-component/example/assets/code/table._fixedEndColTable.txt @@ -0,0 +1,37 @@ + + Widget _fixedEndColTable(BuildContext context) { + return TDTable( + columns: [ + TDTableCol(title: '标题', colKey: 'title1'), + TDTableCol(title: '标题', colKey: 'title2'), + TDTableCol(title: '标题', colKey: 'title3'), + TDTableCol( + title: '标题', + colKey: 'title4', + fixed: TDTableColFixed.right, + cellBuilder: (BuildContext context) { + return Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + TDText( + '修改', + style: TextStyle( + color: TDTheme.of(context).brandNormalColor, + fontSize: 14, + ), + ), + TDText( + '通过', + style: TextStyle( + color: TDTheme.of(context).brandNormalColor, + fontSize: 14, + ), + ), + ], + ); + }, + ), + ], + data: _getData(10), + ); + } \ No newline at end of file diff --git a/tdesign-component/example/assets/code/table._fixedFirstColTable.txt b/tdesign-component/example/assets/code/table._fixedFirstColTable.txt new file mode 100644 index 000000000..fb6fd8b71 --- /dev/null +++ b/tdesign-component/example/assets/code/table._fixedFirstColTable.txt @@ -0,0 +1,12 @@ + + Widget _fixedFirstColTable(BuildContext context) { + return TDTable( + columns: [ + TDTableCol(title: '标题', colKey: 'title1'), + TDTableCol(title: '标题', colKey: 'title2'), + TDTableCol(title: '标题', colKey: 'title3'), + TDTableCol(title: '标题', colKey: 'title4', fixed: TDTableColFixed.left), + ], + data: _getData(10), + ); + } \ No newline at end of file diff --git a/tdesign-component/example/assets/code/table._fixedHeaderTable.txt b/tdesign-component/example/assets/code/table._fixedHeaderTable.txt new file mode 100644 index 000000000..10b24f605 --- /dev/null +++ b/tdesign-component/example/assets/code/table._fixedHeaderTable.txt @@ -0,0 +1,14 @@ + + Widget _fixedHeaderTable(BuildContext context) { + return TDTable( + bordered: true, + height: 240, + columns: [ + TDTableCol(title: '标题', colKey: 'title1', ellipsis: true), + TDTableCol(title: '标题', colKey: 'title2'), + TDTableCol(title: '标题', colKey: 'title3'), + TDTableCol(title: '标题', colKey: 'title4') + ], + data: _getData(9), + ); + } \ No newline at end of file diff --git a/tdesign-component/example/assets/code/table._fixedScrollTable.txt b/tdesign-component/example/assets/code/table._fixedScrollTable.txt new file mode 100644 index 000000000..b85cb633a --- /dev/null +++ b/tdesign-component/example/assets/code/table._fixedScrollTable.txt @@ -0,0 +1,37 @@ + + Widget _fixedScrollTable(BuildContext context) { + return TDTable( + columns: [ + TDTableCol(title: '标题', colKey: 'title1', width: 200), + TDTableCol(title: '标题', colKey: 'title2', width: 160), + TDTableCol(title: '标题', colKey: 'title3', width: 160), + TDTableCol( + title: '标题', + colKey: 'title4', + fixed: TDTableColFixed.right, + cellBuilder: (BuildContext context) { + return Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + TDText( + '修改', + style: TextStyle( + color: TDTheme.of(context).brandNormalColor, + fontSize: 14, + ), + ), + TDText( + '通过', + style: TextStyle( + color: TDTheme.of(context).brandNormalColor, + fontSize: 14, + ), + ), + ], + ); + }, + ), + ], + data: _getData2(), + ); + } \ No newline at end of file diff --git a/tdesign-component/example/assets/code/table._horizontalScrollTable.txt b/tdesign-component/example/assets/code/table._horizontalScrollTable.txt new file mode 100644 index 000000000..7c286f690 --- /dev/null +++ b/tdesign-component/example/assets/code/table._horizontalScrollTable.txt @@ -0,0 +1,11 @@ + + Widget _horizontalScrollTable(BuildContext context) { + return TDTable( + columns: [ + TDTableCol(title: '标题', colKey: 'title1', width: 160), + TDTableCol(title: '标题', colKey: 'title2', width: 160), + TDTableCol(title: '标题', colKey: 'title3', width: 160), + ], + data: _getData2(), + ); + } \ No newline at end of file diff --git a/tdesign-component/example/assets/code/table._loadingTable.txt b/tdesign-component/example/assets/code/table._loadingTable.txt new file mode 100644 index 000000000..081f3d06c --- /dev/null +++ b/tdesign-component/example/assets/code/table._loadingTable.txt @@ -0,0 +1,12 @@ + + Widget _loadingTable(BuildContext context) { + return TDTable( + columns: [ + TDTableCol(title: '标题', colKey: 'title1'), + TDTableCol(title: '标题', colKey: 'title2'), + TDTableCol(title: '标题', colKey: 'title3'), + TDTableCol(title: '标题', colKey: 'title4') + ], + loading: true, + ); + } \ No newline at end of file diff --git a/tdesign-component/example/assets/code/table._operationBtnTable.txt b/tdesign-component/example/assets/code/table._operationBtnTable.txt new file mode 100644 index 000000000..d14017e63 --- /dev/null +++ b/tdesign-component/example/assets/code/table._operationBtnTable.txt @@ -0,0 +1,40 @@ + + Widget _operationBtnTable(BuildContext context) { + return TDTable( + columns: [ + TDTableCol(title: '标题', colKey: 'title1', ellipsis: true), + TDTableCol(title: '标题', colKey: 'title2'), + TDTableCol(title: '标题', colKey: 'title3'), + TDTableCol( + title: '标题', + colKey: 'title4', + cellBuilder: (BuildContext context) { + return Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + TDText( + '修改', + forceVerticalCenter: true, + style: TextStyle( + color: TDTheme.of(context).brandNormalColor, + fontSize: 14, + height: 1, + ), + ), + TDText( + '通过', + forceVerticalCenter: true, + style: TextStyle( + color: TDTheme.of(context).brandNormalColor, + fontSize: 14, + height: 1, + ), + ), + ], + ); + }, + ) + ], + data: _getData(9), + ); + } \ No newline at end of file diff --git a/tdesign-component/example/assets/code/table._operationIconTable.txt b/tdesign-component/example/assets/code/table._operationIconTable.txt new file mode 100644 index 000000000..3e09aa7d4 --- /dev/null +++ b/tdesign-component/example/assets/code/table._operationIconTable.txt @@ -0,0 +1,24 @@ + + Widget _operationIconTable(BuildContext context) { + return TDTable( + columns: [ + TDTableCol(title: '标题', colKey: 'title1', ellipsis: true), + TDTableCol(title: '标题', colKey: 'title2'), + TDTableCol(title: '标题', colKey: 'title3'), + TDTableCol( + title: '标题', + colKey: 'title4', + cellBuilder: (BuildContext context) { + return Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Icon(TDIcons.upload, color: TDTheme.of(context).brandNormalColor, size: 16), + Icon(TDIcons.delete, color: TDTheme.of(context).brandNormalColor, size: 16), + ], + ); + }, + ) + ], + data: _getData(9), + ); + } \ No newline at end of file diff --git a/tdesign-component/example/assets/code/table._sortableTable.txt b/tdesign-component/example/assets/code/table._sortableTable.txt new file mode 100644 index 000000000..45d02a01b --- /dev/null +++ b/tdesign-component/example/assets/code/table._sortableTable.txt @@ -0,0 +1,12 @@ + + Widget _sortableTable(BuildContext context) { + return TDTable( + columns: [ + TDTableCol(title: '标题', colKey: 'title1', ellipsis: true, sortable: true), + TDTableCol(title: '标题', colKey: 'title2', sortable: true), + TDTableCol(title: '标题', colKey: 'title3', sortable: true), + TDTableCol(title: '标题', colKey: 'title4', sortable: true) + ], + data: _getData(9), + ); + } \ No newline at end of file diff --git a/tdesign-component/example/assets/code/table._stripeTable.txt b/tdesign-component/example/assets/code/table._stripeTable.txt new file mode 100644 index 000000000..72d669925 --- /dev/null +++ b/tdesign-component/example/assets/code/table._stripeTable.txt @@ -0,0 +1,13 @@ + + Widget _stripeTable(BuildContext context) { + return TDTable( + stripe: true, + columns: [ + TDTableCol(title: '标题', colKey: 'title1', ellipsis: true), + TDTableCol(title: '标题', colKey: 'title2'), + TDTableCol(title: '标题', colKey: 'title3'), + TDTableCol(title: '标题', colKey: 'title4') + ], + data: _getData(9), + ); + } \ No newline at end of file diff --git a/tdesign-component/example/assets/code/timeCounter._buildControl.txt b/tdesign-component/example/assets/code/timeCounter._buildControl.txt new file mode 100644 index 000000000..fa9fe57b2 --- /dev/null +++ b/tdesign-component/example/assets/code/timeCounter._buildControl.txt @@ -0,0 +1,60 @@ + +Widget _buildControl(BuildContext context) { + var controller = TDTimeCounterController(); + return Wrap( + direction: Axis.vertical, + spacing: 8, + children: [ + Wrap( + spacing: 8, + children: [ + TDButton( + text: '开始', + size: TDButtonSize.extraSmall, + theme: TDButtonTheme.primary, + onTap: () { + controller.start(); + }, + ), + TDButton( + text: '结束', + size: TDButtonSize.extraSmall, + theme: TDButtonTheme.primary, + onTap: () { + controller.reset(0); + }, + ), + TDButton( + text: '重置', + size: TDButtonSize.extraSmall, + theme: TDButtonTheme.primary, + onTap: () { + controller.reset(); + }, + ), + TDButton( + text: '暂停', + size: TDButtonSize.extraSmall, + theme: TDButtonTheme.primary, + onTap: () { + controller.pause(); + }, + ), + TDButton( + text: '继续', + size: TDButtonSize.extraSmall, + theme: TDButtonTheme.primary, + onTap: () { + controller.resume(); + }, + ), + ], + ), + TDTimeCounter( + time: 60 * 60 * 1000, + controller: controller, + // autoStart: false, + ), + ], + ); +} \ No newline at end of file diff --git a/tdesign-component/example/assets/code/timeCounter._buildCustomNum.txt b/tdesign-component/example/assets/code/timeCounter._buildCustomNum.txt new file mode 100644 index 000000000..beed84e3a --- /dev/null +++ b/tdesign-component/example/assets/code/timeCounter._buildCustomNum.txt @@ -0,0 +1,7 @@ + +TDTimeCounter _buildCustomNum(BuildContext context) { + return const TDTimeCounter( + time: 2000 * 60 * 1000, + format: 'mmmmmmm分sss秒', + ); +} \ No newline at end of file diff --git a/tdesign-component/example/assets/code/timeCounter._buildCustomUnitLargeSize.txt b/tdesign-component/example/assets/code/timeCounter._buildCustomUnitLargeSize.txt new file mode 100644 index 000000000..e1189ab90 --- /dev/null +++ b/tdesign-component/example/assets/code/timeCounter._buildCustomUnitLargeSize.txt @@ -0,0 +1,10 @@ + +TDTimeCounter _buildCustomUnitLargeSize(BuildContext context) { + var style = TDTimeCounterStyle.generateStyle(context, size: TDTimeCounterSize.large); + style.timeColor = TDTheme.of(context).errorColor6; + return TDTimeCounter( + time: 60 * 60 * 1000, + splitWithUnit: true, + style: style, + ); +} \ No newline at end of file diff --git a/tdesign-component/example/assets/code/timeCounter._buildCustomUnitMediumSize.txt b/tdesign-component/example/assets/code/timeCounter._buildCustomUnitMediumSize.txt new file mode 100644 index 000000000..b8ce13c60 --- /dev/null +++ b/tdesign-component/example/assets/code/timeCounter._buildCustomUnitMediumSize.txt @@ -0,0 +1,10 @@ + +TDTimeCounter _buildCustomUnitMediumSize(BuildContext context) { + var style = TDTimeCounterStyle.generateStyle(context, size: TDTimeCounterSize.medium); + style.timeColor = TDTheme.of(context).errorColor6; + return TDTimeCounter( + time: 60 * 60 * 1000, + splitWithUnit: true, + style: style, + ); +} \ No newline at end of file diff --git a/tdesign-component/example/assets/code/timeCounter._buildCustomUnitSimple.txt b/tdesign-component/example/assets/code/timeCounter._buildCustomUnitSimple.txt new file mode 100644 index 000000000..7ec660046 --- /dev/null +++ b/tdesign-component/example/assets/code/timeCounter._buildCustomUnitSimple.txt @@ -0,0 +1,6 @@ + +TDTimeCounter _buildCustomUnitSimple(BuildContext context) { + var style = TDTimeCounterStyle.generateStyle(context); + style.timeColor = TDTheme.of(context).errorColor6; + return TDTimeCounter(time: 60 * 60 * 1000, splitWithUnit: true, style: style); +} \ No newline at end of file diff --git a/tdesign-component/example/assets/code/timeCounter._buildCustomUnitSmallSize.txt b/tdesign-component/example/assets/code/timeCounter._buildCustomUnitSmallSize.txt new file mode 100644 index 000000000..f164f750d --- /dev/null +++ b/tdesign-component/example/assets/code/timeCounter._buildCustomUnitSmallSize.txt @@ -0,0 +1,10 @@ + +TDTimeCounter _buildCustomUnitSmallSize(BuildContext context) { + var style = TDTimeCounterStyle.generateStyle(context, size: TDTimeCounterSize.small); + style.timeColor = TDTheme.of(context).errorColor6; + return TDTimeCounter( + time: 60 * 60 * 1000, + splitWithUnit: true, + style: style, + ); +} \ No newline at end of file diff --git a/tdesign-component/example/assets/code/timeCounter._buildLargeSize.txt b/tdesign-component/example/assets/code/timeCounter._buildLargeSize.txt new file mode 100644 index 000000000..7c4bcf4c8 --- /dev/null +++ b/tdesign-component/example/assets/code/timeCounter._buildLargeSize.txt @@ -0,0 +1,7 @@ + +TDTimeCounter _buildLargeSize(BuildContext context) { + return const TDTimeCounter( + time: 60 * 60 * 1000, + size: TDTimeCounterSize.large, + ); +} \ No newline at end of file diff --git a/tdesign-component/example/assets/code/timeCounter._buildMediumSize.txt b/tdesign-component/example/assets/code/timeCounter._buildMediumSize.txt new file mode 100644 index 000000000..2f97c30f2 --- /dev/null +++ b/tdesign-component/example/assets/code/timeCounter._buildMediumSize.txt @@ -0,0 +1,7 @@ + +TDTimeCounter _buildMediumSize(BuildContext context) { + return const TDTimeCounter( + time: 60 * 60 * 1000, + size: TDTimeCounterSize.medium, + ); +} \ No newline at end of file diff --git a/tdesign-component/example/assets/code/timeCounter._buildMillisecondSimple.txt b/tdesign-component/example/assets/code/timeCounter._buildMillisecondSimple.txt new file mode 100644 index 000000000..341aeb12e --- /dev/null +++ b/tdesign-component/example/assets/code/timeCounter._buildMillisecondSimple.txt @@ -0,0 +1,4 @@ + +TDTimeCounter _buildMillisecondSimple(BuildContext context) { + return const TDTimeCounter(time: 60 * 60 * 1000, millisecond: true); +} \ No newline at end of file diff --git a/tdesign-component/example/assets/code/timeCounter._buildRoundLargeSize.txt b/tdesign-component/example/assets/code/timeCounter._buildRoundLargeSize.txt new file mode 100644 index 000000000..768c718d3 --- /dev/null +++ b/tdesign-component/example/assets/code/timeCounter._buildRoundLargeSize.txt @@ -0,0 +1,8 @@ + +TDTimeCounter _buildRoundLargeSize(BuildContext context) { + return const TDTimeCounter( + time: 60 * 60 * 1000, + size: TDTimeCounterSize.large, + theme: TDTimeCounterTheme.round, + ); +} \ No newline at end of file diff --git a/tdesign-component/example/assets/code/timeCounter._buildRoundMediumSize.txt b/tdesign-component/example/assets/code/timeCounter._buildRoundMediumSize.txt new file mode 100644 index 000000000..3bb10ef22 --- /dev/null +++ b/tdesign-component/example/assets/code/timeCounter._buildRoundMediumSize.txt @@ -0,0 +1,8 @@ + +TDTimeCounter _buildRoundMediumSize(BuildContext context) { + return const TDTimeCounter( + time: 60 * 60 * 1000, + size: TDTimeCounterSize.medium, + theme: TDTimeCounterTheme.round, + ); +} \ No newline at end of file diff --git a/tdesign-component/example/assets/code/timeCounter._buildRoundSimple.txt b/tdesign-component/example/assets/code/timeCounter._buildRoundSimple.txt new file mode 100644 index 000000000..87f879b32 --- /dev/null +++ b/tdesign-component/example/assets/code/timeCounter._buildRoundSimple.txt @@ -0,0 +1,4 @@ + +TDTimeCounter _buildRoundSimple(BuildContext context) { + return const TDTimeCounter(time: 60 * 60 * 1000, theme: TDTimeCounterTheme.round); +} \ No newline at end of file diff --git a/tdesign-component/example/assets/code/timeCounter._buildRoundSmallSize.txt b/tdesign-component/example/assets/code/timeCounter._buildRoundSmallSize.txt new file mode 100644 index 000000000..4bc0a95c9 --- /dev/null +++ b/tdesign-component/example/assets/code/timeCounter._buildRoundSmallSize.txt @@ -0,0 +1,8 @@ + +TDTimeCounter _buildRoundSmallSize(BuildContext context) { + return const TDTimeCounter( + time: 60 * 60 * 1000, + size: TDTimeCounterSize.small, + theme: TDTimeCounterTheme.round, + ); +} \ No newline at end of file diff --git a/tdesign-component/example/assets/code/timeCounter._buildSimple.txt b/tdesign-component/example/assets/code/timeCounter._buildSimple.txt new file mode 100644 index 000000000..95273fbbd --- /dev/null +++ b/tdesign-component/example/assets/code/timeCounter._buildSimple.txt @@ -0,0 +1,4 @@ + +TDTimeCounter _buildSimple(BuildContext context) { + return const TDTimeCounter(time: 60 * 60 * 1000); +} \ No newline at end of file diff --git a/tdesign-component/example/assets/code/timeCounter._buildSmallSize.txt b/tdesign-component/example/assets/code/timeCounter._buildSmallSize.txt new file mode 100644 index 000000000..89c9ff579 --- /dev/null +++ b/tdesign-component/example/assets/code/timeCounter._buildSmallSize.txt @@ -0,0 +1,7 @@ + +TDTimeCounter _buildSmallSize(BuildContext context) { + return const TDTimeCounter( + time: 60 * 60 * 1000, + size: TDTimeCounterSize.small, + ); +} \ No newline at end of file diff --git a/tdesign-component/example/assets/code/timeCounter._buildSquareLargeSize.txt b/tdesign-component/example/assets/code/timeCounter._buildSquareLargeSize.txt new file mode 100644 index 000000000..ab190a089 --- /dev/null +++ b/tdesign-component/example/assets/code/timeCounter._buildSquareLargeSize.txt @@ -0,0 +1,8 @@ + +TDTimeCounter _buildSquareLargeSize(BuildContext context) { + return const TDTimeCounter( + time: 60 * 60 * 1000, + size: TDTimeCounterSize.large, + theme: TDTimeCounterTheme.square, + ); +} \ No newline at end of file diff --git a/tdesign-component/example/assets/code/timeCounter._buildSquareMediumSize.txt b/tdesign-component/example/assets/code/timeCounter._buildSquareMediumSize.txt new file mode 100644 index 000000000..b484e694b --- /dev/null +++ b/tdesign-component/example/assets/code/timeCounter._buildSquareMediumSize.txt @@ -0,0 +1,8 @@ + +TDTimeCounter _buildSquareMediumSize(BuildContext context) { + return const TDTimeCounter( + time: 60 * 60 * 1000, + size: TDTimeCounterSize.medium, + theme: TDTimeCounterTheme.square, + ); +} \ No newline at end of file diff --git a/tdesign-component/example/assets/code/timeCounter._buildSquareSimple.txt b/tdesign-component/example/assets/code/timeCounter._buildSquareSimple.txt new file mode 100644 index 000000000..fbdabeb7a --- /dev/null +++ b/tdesign-component/example/assets/code/timeCounter._buildSquareSimple.txt @@ -0,0 +1,4 @@ + +TDTimeCounter _buildSquareSimple(BuildContext context) { + return const TDTimeCounter(time: 60 * 60 * 1000, theme: TDTimeCounterTheme.square); +} \ No newline at end of file diff --git a/tdesign-component/example/assets/code/timeCounter._buildSquareSmallSize.txt b/tdesign-component/example/assets/code/timeCounter._buildSquareSmallSize.txt new file mode 100644 index 000000000..b71918c80 --- /dev/null +++ b/tdesign-component/example/assets/code/timeCounter._buildSquareSmallSize.txt @@ -0,0 +1,8 @@ + +TDTimeCounter _buildSquareSmallSize(BuildContext context) { + return const TDTimeCounter( + time: 60 * 60 * 1000, + size: TDTimeCounterSize.small, + theme: TDTimeCounterTheme.square, + ); +} \ No newline at end of file diff --git a/tdesign-component/example/assets/code/timeCounter._buildUnitLargeSize.txt b/tdesign-component/example/assets/code/timeCounter._buildUnitLargeSize.txt new file mode 100644 index 000000000..9ae518ea0 --- /dev/null +++ b/tdesign-component/example/assets/code/timeCounter._buildUnitLargeSize.txt @@ -0,0 +1,9 @@ + +TDTimeCounter _buildUnitLargeSize(BuildContext context) { + return const TDTimeCounter( + time: 60 * 60 * 1000, + size: TDTimeCounterSize.large, + theme: TDTimeCounterTheme.square, + splitWithUnit: true, + ); +} \ No newline at end of file diff --git a/tdesign-component/example/assets/code/timeCounter._buildUnitMediumSize.txt b/tdesign-component/example/assets/code/timeCounter._buildUnitMediumSize.txt new file mode 100644 index 000000000..04f480130 --- /dev/null +++ b/tdesign-component/example/assets/code/timeCounter._buildUnitMediumSize.txt @@ -0,0 +1,9 @@ + +TDTimeCounter _buildUnitMediumSize(BuildContext context) { + return const TDTimeCounter( + time: 60 * 60 * 1000, + size: TDTimeCounterSize.medium, + theme: TDTimeCounterTheme.square, + splitWithUnit: true, + ); +} \ No newline at end of file diff --git a/tdesign-component/example/assets/code/timeCounter._buildUnitSimple.txt b/tdesign-component/example/assets/code/timeCounter._buildUnitSimple.txt new file mode 100644 index 000000000..cab7f72cd --- /dev/null +++ b/tdesign-component/example/assets/code/timeCounter._buildUnitSimple.txt @@ -0,0 +1,4 @@ + +TDTimeCounter _buildUnitSimple(BuildContext context) { + return const TDTimeCounter(time: 60 * 60 * 1000, theme: TDTimeCounterTheme.square, splitWithUnit: true); +} \ No newline at end of file diff --git a/tdesign-component/example/assets/code/timeCounter._buildUnitSmallSize.txt b/tdesign-component/example/assets/code/timeCounter._buildUnitSmallSize.txt new file mode 100644 index 000000000..c762a3c5f --- /dev/null +++ b/tdesign-component/example/assets/code/timeCounter._buildUnitSmallSize.txt @@ -0,0 +1,9 @@ + +TDTimeCounter _buildUnitSmallSize(BuildContext context) { + return const TDTimeCounter( + time: 60 * 60 * 1000, + size: TDTimeCounterSize.small, + theme: TDTimeCounterTheme.square, + splitWithUnit: true, + ); +} \ No newline at end of file diff --git a/tdesign-component/example/assets/code/timeCounter._buildUpSimple.txt b/tdesign-component/example/assets/code/timeCounter._buildUpSimple.txt new file mode 100644 index 000000000..a090d55a1 --- /dev/null +++ b/tdesign-component/example/assets/code/timeCounter._buildUpSimple.txt @@ -0,0 +1,8 @@ + +TDTimeCounter _buildUpSimple(BuildContext context) { + return const TDTimeCounter( + time: 60 * 60 * 1000, + millisecond: true, + direction: TDTimeCounterDirection.up, + ); +} \ No newline at end of file diff --git a/tdesign-component/example/assets/code/toast._preventTapToast.txt b/tdesign-component/example/assets/code/toast._preventTapToast.txt new file mode 100644 index 000000000..755b3ccae --- /dev/null +++ b/tdesign-component/example/assets/code/toast._preventTapToast.txt @@ -0,0 +1,14 @@ + + Widget _preventTapToast(BuildContext context) { + return TDButton( + onTap: () { + TDToast.showText('轻提示文字内容', + context: context, preventTap: true); + }, + size: TDButtonSize.large, + type: TDButtonType.outline, + theme: TDButtonTheme.primary, + isBlock: true, + text: '禁止滚动+点击', + ); + } \ No newline at end of file From c5f5c441f88be0948743d3f152898775ed834116 Mon Sep 17 00:00:00 2001 From: Luozf12345 <2515187986@qq.com> Date: Sun, 13 Oct 2024 15:31:27 +0800 Subject: [PATCH 22/46] =?UTF-8?q?=E6=B5=81=E6=B0=B4=E7=BA=BF=E6=8F=90?= =?UTF-8?q?=E4=BA=A4=E7=94=9F=E6=88=90=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tdesign-site/src/button/README.md | 1 + tdesign-site/src/drawer/README.md | 3 +++ tdesign-site/src/indexes/README.md | 2 +- tdesign-site/src/navbar/README.md | 2 ++ tdesign-site/src/side-bar/README.md | 2 ++ 5 files changed, 9 insertions(+), 1 deletion(-) diff --git a/tdesign-site/src/button/README.md b/tdesign-site/src/button/README.md index 135907068..775c5052d 100644 --- a/tdesign-site/src/button/README.md +++ b/tdesign-site/src/button/README.md @@ -788,6 +788,7 @@ import 'package:tdesign_flutter/tdesign_flutter.dart'; | onTap | TDButtonEvent? | - | 点击事件 | | icon | IconData? | - | 图标icon | | iconWidget | Widget? | - | 自定义图标icon控件 | +| iconTextSpacing | double? | - | 自定义图标与文本之间距离 | | onLongPress | TDButtonEvent? | - | 长按事件 | | margin | EdgeInsetsGeometry? | - | 自定义margin | | padding | EdgeInsetsGeometry? | - | 自定义padding | diff --git a/tdesign-site/src/drawer/README.md b/tdesign-site/src/drawer/README.md index c414e2ade..7eb01e9b1 100644 --- a/tdesign-site/src/drawer/README.md +++ b/tdesign-site/src/drawer/README.md @@ -295,6 +295,9 @@ Widget _buildBottomSimple(BuildContext context) { | drawerTop | double? | - | 距离顶部的距离 | | style | TDCellStyle? | - | 列表自定义样式 | | hover | bool? | true | 是否开启点击反馈 | +| backgroundColor | Color? | - | 组件背景颜色 | +| bordered | bool? | true | 是否显示边框 | +| isShowLastBordered | bool? | true | 是否显示最后一行分割线 | ``` ``` diff --git a/tdesign-site/src/indexes/README.md b/tdesign-site/src/indexes/README.md index 12b8f9c09..7ac4a98d7 100644 --- a/tdesign-site/src/indexes/README.md +++ b/tdesign-site/src/indexes/README.md @@ -243,7 +243,7 @@ Widget _buildOther(BuildContext context) { | indexList | List | - | 索引字符列表。不传默认 A-Z | | indexListMaxHeight | double | 0.8 | 索引列表最大高度(父容器高度的百分比,默认0.8) | | activeIndex | ValueNotifier | - | 选中索引 | -| onSelect | void Function(String index, bool isUp) | - | 点击侧边栏时触发事件 | +| onSelect | void Function(String newIndex, String oldIndex) | - | 点击侧边栏时触发事件 | | builderIndex | Widget Function(BuildContext context, String index, bool isActive)? | - | 索引文本自定义构建,包括索引激活左侧提示 | ``` diff --git a/tdesign-site/src/navbar/README.md b/tdesign-site/src/navbar/README.md index cf0204e6c..042b1e7cb 100644 --- a/tdesign-site/src/navbar/README.md +++ b/tdesign-site/src/navbar/README.md @@ -310,6 +310,8 @@ import 'package:tdesign_flutter/tdesign_flutter.dart'; | useBorderStyle | bool | false | 是否使用边框模式 | | border | TDNavBarItemBorder? | - | 边框 | | belowTitleWidget | Widget? | - | belowTitleWidget navbar 下方的widget | +| boxShadow | List? | - | 底部阴影 | +| flexibleSpace | Widget? | - | 固定背景 | ``` ``` diff --git a/tdesign-site/src/side-bar/README.md b/tdesign-site/src/side-bar/README.md index 83b1a75fc..2d832e2af 100644 --- a/tdesign-site/src/side-bar/README.md +++ b/tdesign-site/src/side-bar/README.md @@ -688,6 +688,8 @@ import 'package:tdesign_flutter/tdesign_flutter.dart'; | contentPadding | EdgeInsetsGeometry? | - | 自定义文本框内边距 | | selectedTextStyle | TextStyle? | - | 选中样式 | | style | TDSideBarStyle | TDSideBarStyle.normal | 样式 | +| loading | bool? | - | 加载效果 | +| loadingWidget | Widget? | - | 自定义加载动画 | \ No newline at end of file From a83bf650f38aca237a5be903492fc032774af1d7 Mon Sep 17 00:00:00 2001 From: Luozf12345 <2515187986@qq.com> Date: Sun, 13 Oct 2024 16:10:03 +0800 Subject: [PATCH 23/46] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E6=96=87=E6=A1=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../lib/component_test/tabbar_test.dart | 178 +++++ .../example/lib/component_test/test_app.dart | 200 +++--- tdesign-component/example/pubspec.lock | 74 +- tdesign-component/example/pubspec.yaml | 2 + .../example/test/widget_test.dart | 2 +- tdesign-component/publish.sh | 1 + tdesign-site/site/plugin-tdoc/component.vue | 2 +- tdesign-site/site/site.config.mjs | 49 +- tdesign-site/src/button/README.md | 1 + tdesign-site/src/calendar/README.md | 509 ++++++++++++++ tdesign-site/src/cascader/README.md | 13 +- tdesign-site/src/cell/README.md | 1 + tdesign-site/src/date-time-picker/README.md | 7 +- tdesign-site/src/dialog/README.md | 9 + tdesign-site/src/drawer/README.md | 3 + tdesign-site/src/dropdown-menu/README.md | 160 +---- tdesign-site/src/image-viewer/README.md | 6 +- tdesign-site/src/indexes/README.md | 2 +- tdesign-site/src/input/README.md | 6 +- tdesign-site/src/loading/README.md | 2 +- tdesign-site/src/navbar/README.md | 2 + tdesign-site/src/notice-bar/README.md | 326 +++++++++ tdesign-site/src/picker/README.md | 10 +- tdesign-site/src/popup/README.md | 2 + tdesign-site/src/radio/README.md | 2 + tdesign-site/src/result/README.md | 314 +++++++++ tdesign-site/src/search/README.md | 5 + tdesign-site/src/side-bar/README.md | 2 + tdesign-site/src/table/README.md | 294 ++++++++ tdesign-site/src/time-counter/README.md | 655 ++++++++++++++++++ tdesign-site/src/toast/README.md | 14 +- 31 files changed, 2541 insertions(+), 312 deletions(-) create mode 100644 tdesign-component/example/lib/component_test/tabbar_test.dart create mode 100644 tdesign-component/publish.sh create mode 100644 tdesign-site/src/calendar/README.md create mode 100644 tdesign-site/src/notice-bar/README.md create mode 100644 tdesign-site/src/result/README.md create mode 100644 tdesign-site/src/table/README.md create mode 100644 tdesign-site/src/time-counter/README.md diff --git a/tdesign-component/example/lib/component_test/tabbar_test.dart b/tdesign-component/example/lib/component_test/tabbar_test.dart new file mode 100644 index 000000000..1bd118624 --- /dev/null +++ b/tdesign-component/example/lib/component_test/tabbar_test.dart @@ -0,0 +1,178 @@ +import 'package:extended_nested_scroll_view/extended_nested_scroll_view.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_screenutil/flutter_screenutil.dart'; +import 'package:tdesign_flutter/tdesign_flutter.dart'; +import 'package:tdesign_flutter/src/util/string_util.dart'; +// import 'package:xjy_study/utils/color_util.dart'; + +class StudyDetail extends StatefulWidget { + const StudyDetail({super.key}); + + @override + State createState() => _StudyDetailState(); +} + +class _StudyDetailState extends State with SingleTickerProviderStateMixin { + final List _tabs = const ['待上课时', '已上课时']; + + late TabController _tabController; + + @override + void initState() { + super.initState(); + _tabController = TabController(length: _tabs.length, vsync: this); + } + + @override + void didChangeDependencies() { + super.didChangeDependencies(); + _getQueryParams(); + } + + @override + void dispose() { + super.dispose(); + } + + void _getQueryParams() { + // final ModalRoute? currentRoute = ModalRoute.of(context); + // if (currentRoute != null) { + // final Map params = currentRoute.settings.arguments as Map; + // print('aa=${params}'); + // } + } + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + title: const Text('课程详情'), + leadingWidth: 40.w, + ), + body: ExtendedNestedScrollView( + onlyOneScrollInBody: true, + physics: ClampingScrollPhysics(), + headerSliverBuilder: (BuildContext context, bool innerBoxIsScrolled) { + return [ + SliverToBoxAdapter( + child: _CourseItemDetail(), + ) + ]; + }, + body: Column( + children: [ + TDTabBar( + controller: _tabController, + height: 44.h, + backgroundColor: Colors.white, + indicatorColor: TDTheme.of().brandNormalColor, + // labelColor:TDTheme.of().brandNormalColor, + unselectedLabelStyle: TextStyle(fontSize: 12.sp, color: Colors.red), + labelStyle: TextStyle( + fontSize: 28.sp, + color: Colors.deepPurpleAccent, + fontWeight: FontWeight.w500), + indicatorWidth: 16.w, + showIndicator: true, + tabs: _tabs + .map((e) => TDTab( + text: '$e', + )) + .toList()), + Expanded( + child: TDTabBarView( + isSlideSwitch: true, + controller: _tabController, + children: _tabs + .map((e) => Center( + child: Text('data$e'), + )) + .toList())) + ], + ), + ), + ); + } +} + +/// 课程详情描述 +class _CourseItemDetail extends StatelessWidget { + const _CourseItemDetail(); + + @override + Widget build(BuildContext context) { + return Container( + padding: EdgeInsets.fromLTRB(15.w, 10.h, 15.w, 8.h), + color: Colors.white, + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Container( + margin: EdgeInsets.only(top: 3.h), + height: 16.h, + alignment: Alignment.center, + padding: EdgeInsets.symmetric(horizontal: 6.w), + decoration: BoxDecoration( + borderRadius: BorderRadius.all(Radius.circular(4)), + gradient: LinearGradient(colors: [ + Color(0xFFFFB442), + Color(0xFFFF9A00), + ])), + child: Text( + '数学', + style: TextStyle(color: Colors.white, fontSize: 12.sp, height: 1.h), + ), + ), + SizedBox( + width: 8.w, + ), + Expanded( + child: Text( + '集合图形离开撒娇的案例三等奖集合图形离开撒娇的案例', + style: TextStyle( + color: TDTheme.of().fontGyColor1, + fontSize: 14.sp, + overflow: TextOverflow.ellipsis, + height: 1.5.h), + maxLines: 2, + )) + ], + ), + Padding( + padding: EdgeInsets.only(top: 5.h, bottom: 12.h), + child: Text( + '2020年8月15日开始,共20节课', + style: TextStyle(fontSize: 12.sp, color: TDTheme.of().fontGyColor2,), + ), + ), + Row( + children: [ + ClipRRect( + borderRadius: BorderRadius.circular(28.w), + child: Container( + width: 28.w, + height: 28.w, + color: Colors.grey, + ), + ), + SizedBox( + width: 10.w, + ), + Text( + '某某老师', + maxLines: 1, + style: TextStyle( + fontSize: 12.sp, + color: TDTheme.of().fontGyColor2, + overflow: TextOverflow.ellipsis), + ) + ], + ) + ], + ), + ); + } +} \ No newline at end of file diff --git a/tdesign-component/example/lib/component_test/test_app.dart b/tdesign-component/example/lib/component_test/test_app.dart index 862990368..21c062d92 100644 --- a/tdesign-component/example/lib/component_test/test_app.dart +++ b/tdesign-component/example/lib/component_test/test_app.dart @@ -1,7 +1,10 @@ import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; +import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:tdesign_flutter/tdesign_flutter.dart'; +import 'tabbar_test.dart'; + void main() async { kTextNeedGlobalFontFamily = true; WidgetsFlutterBinding.ensureInitialized(); @@ -23,68 +26,13 @@ void main() async { data: ThemeData(extensions: [themeData!]), child: Builder( builder: (context) { + + ScreenUtil.init(context); return Scaffold( - // appBar: TDNavBar(), appBar: _buildAppBar(context), - body: Padding( - padding: const EdgeInsets.all(16), - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - // 先显示再加载 - TDText( - '测试文案', - textColor: TDTheme.of(context).brandNormalColor, - fontFamilyUrl: - 'https://xinyue.qq.com/m/flutter_web/assets/packages/flutter_component/fonts/FZLanTingHeiS-EB-GB.ttf', - fontFamily: FontFamily(fontFamily: 'test'), - ), - // // 先加载再显示 - // child: FutureBuilder( - // future:TDFontLoader.load(name: 'test1', fontFamilyUrl: 'https://xinyue.qq.com/m/flutter_web/assets/packages/flutter_component/fonts/FZLanTingHeiS-EB-GB.ttf'), - // initialData: false, - // builder: (_,data)=>TDText( - // (data.data ?? false) ? '测试文案' : '', - // textColor: TDTheme.of(context).brandNormalColor, - // fontFamilyUrl: 'https://xinyue.qq.com/m/flutter_web/assets/packages/flutter_component/fonts/FZLanTingHeiS-EB-GB.ttf', - // fontFamily: FontFamily(fontFamily: 'test1'), - // ), - // ), - TDInput( - // leftLabel: '标签文字', - // controller: controller[0], - type: TDInputType.cardStyle, - backgroundColor: Colors.white, - cardStyle: TDCardStyle.topTextWithBlueBorder, - hintText: '请输入文字', - cardStyleTopText: '标签文字', - // onChanged: (text) { - // setState(() {}); - // }, - // onClearTap: () { - // controller[0].clear(); - // setState(() {}); - // }, - ), - const SizedBox( - height: 16, - ), - const TDTextarea( - label: '标签文字', - hintText: '请输入文字', - maxLines: 4, - minLines: 4, - maxLength: 500, - padding: EdgeInsets.zero, - indicator: true, - // backgroundColor: Colors.white, - // textInputBackgroundColor: Colors.white, - layout: TDTextareaLayout.vertical, - bordered: true, - ) - ], - ), - ), + // appBar: _buildAppBar(context), + // body: StudyDetail(), + body: body(context), bottomNavigationBar: _buildBottomTabBar(), ); }, @@ -93,37 +41,107 @@ void main() async { )); } -PreferredSize _buildAppBar(BuildContext context) { - return PreferredSize( - preferredSize: Size( - MediaQuery.of(context).size.width, MediaQuery.of(context).size.height + MediaQuery.of(context).padding.top), - child: Container( - padding: EdgeInsets.only(top: MediaQuery.of(context).padding.top), - color: Colors.red, - child: TDNavBar( - useDefaultBack: false, - // screenAdaptation: false, - opacity: 0, - centerTitle: false, - titleMargin: 0, - titleWidget: TDSearchBar( - needCancel: false, - autoHeight: true, - backgroundColor: Colors.transparent, - padding: const EdgeInsets.fromLTRB(0, 2, 0, 2), - placeHolder: '搜索预设文案', - mediumStyle: true, - style: TDSearchStyle.round, - onTextChanged: (String text) { - print('input:$text'); - }, - ), - rightBarItems: [ - TDNavBarItem(icon: TDIcons.home, iconSize: 24), - TDNavBarItem(icon: TDIcons.ellipsis, iconSize: 24) - ]), - ), - ); +Padding body(BuildContext context) { + return Padding( + padding: const EdgeInsets.all(16), + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + + TDButton(text: "ixanshi ",onTap: (){ + TDLoadingController.show(context); + + TDLoadingController.dismiss(); + },), + // 先显示再加载 + TDText( + '测试文案', + textColor: TDTheme.of(context).brandNormalColor, + fontFamilyUrl: + 'https://xinyue.qq.com/m/flutter_web/assets/packages/flutter_component/fonts/FZLanTingHeiS-EB-GB.ttf', + fontFamily: FontFamily(fontFamily: 'test'), + ), + // // 先加载再显示 + // child: FutureBuilder( + // future:TDFontLoader.load(name: 'test1', fontFamilyUrl: 'https://xinyue.qq.com/m/flutter_web/assets/packages/flutter_component/fonts/FZLanTingHeiS-EB-GB.ttf'), + // initialData: false, + // builder: (_,data)=>TDText( + // (data.data ?? false) ? '测试文案' : '', + // textColor: TDTheme.of(context).brandNormalColor, + // fontFamilyUrl: 'https://xinyue.qq.com/m/flutter_web/assets/packages/flutter_component/fonts/FZLanTingHeiS-EB-GB.ttf', + // fontFamily: FontFamily(fontFamily: 'test1'), + // ), + // ), + TDInput( + // leftLabel: '标签文字', + // controller: controller[0], + type: TDInputType.cardStyle, + backgroundColor: Colors.white, + cardStyle: TDCardStyle.topTextWithBlueBorder, + hintText: '请输入文字', + cardStyleTopText: '标签文字', + // onChanged: (text) { + // setState(() {}); + // }, + // onClearTap: () { + // controller[0].clear(); + // setState(() {}); + // }, + ), + const SizedBox( + height: 16, + ), + const TDTextarea( + label: '标签文字', + hintText: '请输入文字', + maxLines: 4, + minLines: 4, + maxLength: 500, + padding: EdgeInsets.zero, + indicator: true, + // backgroundColor: Colors.white, + // textInputBackgroundColor: Colors.white, + layout: TDTextareaLayout.vertical, + bordered: true, + ) + ], + ), + ); +} + +PreferredSizeWidget _buildAppBar(BuildContext context) { + return TDNavBar( + useDefaultBack: false, + // screenAdaptation: false, + flexibleSpace: Container( + decoration: const BoxDecoration( + gradient: LinearGradient( + colors: [ + Colors.red, Colors.green + ] + ) + ), + ), + // opacity: 0, + backgroundColor: Colors.red, + centerTitle: false, + titleMargin: 0, + titleWidget: TDSearchBar( + needCancel: false, + autoHeight: true, + backgroundColor: Colors.transparent, + padding: const EdgeInsets.fromLTRB(0, 2, 0, 2), + placeHolder: '搜索预设文案', + mediumStyle: true, + style: TDSearchStyle.round, + onTextChanged: (String text) { + print('input:$text'); + }, + ), + rightBarItems: [ + TDNavBarItem(icon: TDIcons.home, iconSize: 24), + TDNavBarItem(icon: TDIcons.ellipsis, iconSize: 24) + ]); } TDBottomTabBar _buildBottomTabBar() { diff --git a/tdesign-component/example/pubspec.lock b/tdesign-component/example/pubspec.lock index a208e30dd..3bc1c1e38 100644 --- a/tdesign-component/example/pubspec.lock +++ b/tdesign-component/example/pubspec.lock @@ -5,10 +5,10 @@ packages: dependency: transitive description: name: args - sha256: "7cf60b9f0cc88203c5a190b4cd62a99feea42759a7fa695010eb5de1c0b2252a" + sha256: eef6c46b622e0494a36c5a12d10d77fb4e855501a91c1b9ef9339326e58f0596 url: "https://pub.dev" source: hosted - version: "2.5.0" + version: "2.4.2" async: dependency: transitive description: @@ -57,6 +57,14 @@ packages: url: "https://pub.dev" source: hosted version: "1.0.6" + extended_nested_scroll_view: + dependency: "direct main" + description: + name: extended_nested_scroll_view + sha256: fc55b8f7e2c78701320d7eccda3b256387290b8498f0363d8ffd6f16760949d7 + url: "https://pub.dev" + source: hosted + version: "6.0.0" fake_async: dependency: transitive description: @@ -69,10 +77,10 @@ packages: dependency: transitive description: name: ffi - sha256: "7bf0adc28a23d395f19f3f1eb21dd7cfd1dd9f8e1c50051c069122e6853bc878" + sha256: ed5337a5660c506388a9f012be0288fb38b49020ce2b45fe1f8b8323fe429f99 url: "https://pub.dev" source: hosted - version: "2.1.0" + version: "2.0.2" flutter: dependency: "direct main" description: flutter @@ -103,10 +111,18 @@ packages: dependency: "direct main" description: name: flutter_markdown - sha256: "21b085a1c185e46701373866144ced56cfb7a0c33f63c916bb8fe2d0c1491278" + sha256: dc6d5258653f6857135b32896ccda7f7af0c54dcec832495ad6835154c6c77c0 url: "https://pub.dev" source: hosted - version: "0.6.19" + version: "0.6.15" + flutter_screenutil: + dependency: "direct main" + description: + name: flutter_screenutil + sha256: "0a122936b450324cbdfd51be0819cc6fcebb093eb65585e9cd92263f7a1a8a39" + url: "https://pub.dev" + source: hosted + version: "5.7.0" flutter_slidable: dependency: transitive description: @@ -212,26 +228,26 @@ packages: dependency: "direct main" description: name: path_provider - sha256: b27217933eeeba8ff24845c34003b003b2b22151de3c908d0e679e8fe1aa078b + sha256: a1aa8aaa2542a6bc57e381f132af822420216c80d4781f7aa085ca3229208aaa url: "https://pub.dev" source: hosted - version: "2.1.2" + version: "2.1.1" path_provider_android: dependency: transitive description: name: path_provider_android - sha256: "477184d672607c0a3bf68fbbf601805f92ef79c82b64b4d6eb318cbca4c48668" + sha256: e595b98692943b4881b219f0a9e3945118d3c16bd7e2813f98ec6e532d905f72 url: "https://pub.dev" source: hosted - version: "2.2.2" + version: "2.2.1" path_provider_foundation: dependency: transitive description: name: path_provider_foundation - sha256: "5a7999be66e000916500be4f15a3633ebceb8302719b47b9cc49ce924125350f" + sha256: "19314d595120f82aca0ba62787d58dde2cc6b5df7d2f0daf72489e38d1b57f2d" url: "https://pub.dev" source: hosted - version: "2.3.2" + version: "2.3.1" path_provider_linux: dependency: transitive description: @@ -244,10 +260,10 @@ packages: dependency: transitive description: name: path_provider_platform_interface - sha256: "88f5779f72ba699763fa3a3b06aa4bf6de76c8e5de842cf6f29e2e06476c2334" + sha256: "94b1e0dd80970c1ce43d5d4e050a9918fce4f4a775e6142424c30a29a363265c" url: "https://pub.dev" source: hosted - version: "2.1.2" + version: "2.1.1" path_provider_windows: dependency: transitive description: @@ -260,18 +276,18 @@ packages: dependency: transitive description: name: platform - sha256: "12220bb4b65720483f8fa9450b4332347737cf8213dd2840d8b2c823e47243ec" + sha256: "0a279f0707af40c890e80b1e9df8bb761694c074ba7e1d4ab1bc4b728e200b59" url: "https://pub.dev" source: hosted - version: "3.1.4" + version: "3.1.3" plugin_platform_interface: dependency: transitive description: name: plugin_platform_interface - sha256: "4820fbfdb9478b1ebae27888254d445073732dae3d6ea81f0b7e06d5dedc3f02" + sha256: da3fdfeccc4d4ff2da8f8c556704c08f912542c5fb3cf2233ed75372384a034d url: "https://pub.dev" source: hosted - version: "2.1.8" + version: "2.1.6" sky_engine: dependency: transitive description: flutter @@ -315,7 +331,7 @@ packages: path: ".." relative: true source: path - version: "0.1.5" + version: "0.1.6" term_glyph: dependency: transitive description: @@ -348,22 +364,30 @@ packages: url: "https://pub.dev" source: hosted version: "2.1.4" + visibility_detector: + dependency: transitive + description: + name: visibility_detector + sha256: "15c54a459ec2c17b4705450483f3d5a2858e733aee893dcee9d75fd04814940d" + url: "https://pub.dev" + source: hosted + version: "0.3.3" win32: dependency: transitive description: name: win32 - sha256: "350a11abd2d1d97e0cc7a28a81b781c08002aa2864d9e3f192ca0ffa18b06ed3" + sha256: "5a751eddf9db89b3e5f9d50c20ab8612296e4e8db69009788d6c8b060a84191c" url: "https://pub.dev" source: hosted - version: "5.0.9" + version: "4.1.4" xdg_directories: dependency: transitive description: name: xdg_directories - sha256: faea9dee56b520b55a566385b84f2e8de55e7496104adada9962e0bd11bcff1d + sha256: "589ada45ba9e39405c198fe34eb0f607cddb2108527e658136120892beac46d2" url: "https://pub.dev" source: hosted - version: "1.0.4" + version: "1.0.3" sdks: - dart: ">=3.0.0 <4.0.0" - flutter: ">=3.10.0" + dart: ">=3.0.0-0 <4.0.0" + flutter: ">=3.7.0" diff --git a/tdesign-component/example/pubspec.yaml b/tdesign-component/example/pubspec.yaml index 050fdbb5c..f357c8558 100644 --- a/tdesign-component/example/pubspec.yaml +++ b/tdesign-component/example/pubspec.yaml @@ -43,6 +43,8 @@ dependencies: tdesign_flutter: path: ../ path_provider: ^2.1.1 + extended_nested_scroll_view: any + flutter_screenutil: any dev_dependencies: flutter_test: sdk: flutter diff --git a/tdesign-component/example/test/widget_test.dart b/tdesign-component/example/test/widget_test.dart index 00956cccd..22cbae602 100644 --- a/tdesign-component/example/test/widget_test.dart +++ b/tdesign-component/example/test/widget_test.dart @@ -44,7 +44,7 @@ void main() async { } -var changeList = ['Drawer 抽屉','Tabs 选项卡','Input 输入框','Stepper 步进器','Badge 徽标','Empty 空状态','Dialog 对话框','Swipecell 滑动操作']; +var changeList = ['Drawer 抽屉','TabBar 标签栏','Checkbox 多选框','Search 搜索框','TreeSelect 树形选择器','TimeCounter 计时器','Result 结果','DropdownMenu 下拉菜单','Swipecell 滑动操作']; Finder? lastFinder; Future _testComponent(WidgetTester tester, String name) async { diff --git a/tdesign-component/publish.sh b/tdesign-component/publish.sh new file mode 100644 index 000000000..c9d9bff1d --- /dev/null +++ b/tdesign-component/publish.sh @@ -0,0 +1 @@ +~/tools/flutter/bin/flutter packages pub publish --server=https://pub.dartlang.org \ No newline at end of file diff --git a/tdesign-site/site/plugin-tdoc/component.vue b/tdesign-site/site/plugin-tdoc/component.vue index 1e6574751..25d76b16e 100644 --- a/tdesign-site/site/plugin-tdoc/component.vue +++ b/tdesign-site/site/plugin-tdoc/component.vue @@ -67,7 +67,7 @@ export default defineComponent({ const { path } = this.$route; const name = path.slice(path.lastIndexOf('/') + 1); // new URL(): https://cn.vitejs.dev/guide/assets.html#new-url-url-import-meta-url - return new URL(`../public/assets/qrcode/tdesign_apk_qrcode.png`, import.meta.url).href; + return new URL(`../public/assets/qrcode/td_apk_qrcode.png`, import.meta.url).href; }, }, diff --git a/tdesign-site/site/site.config.mjs b/tdesign-site/site/site.config.mjs index 715e2abee..580634a2c 100644 --- a/tdesign-site/site/site.config.mjs +++ b/tdesign-site/site/site.config.mjs @@ -121,13 +121,13 @@ export default { path: '/flutter/components/drawer', component: () => import('@/drawer/README.md'), }, - // { - // title: 'Indexes 索引', - // name: 'indexes', - // meta: { docType: 'navigation' }, - // path: '/flutter/components/indexes', - // component: () => import('@/indexes/README.md'), - // }, + { + title: 'Indexes 索引', + name: 'indexes', + meta: { docType: 'navigation' }, + path: '/flutter/components/indexes', + component: () => import('@/indexes/README.md'), + }, { title: 'Navbar 导航栏', name: 'navbar', @@ -169,13 +169,13 @@ export default { title: '输入', type: 'component', children: [ - // { - // title: 'Calendar 日历', - // name: 'calendar', - // meta: { docType: 'form' }, - // path: '/flutter/components/calendar', - // component: () => import('@/calendar/README.md'), - // }, + { + title: 'Calendar 日历', + name: 'calendar', + meta: { docType: 'form' }, + path: '/flutter/components/calendar', + component: () => import('@/calendar/README.md'), + }, { title: 'Cascader 级联选择器', name: 'cascader', @@ -385,6 +385,13 @@ export default { path: '/flutter/components/swiper', component: () => import('@/swiper/README.md'), }, + { + title: 'Table 表格', + name: 'table', + meta: { docType: 'data' }, + path: '/flutter/components/table', + component: () => import('@/table/README.md'), + }, { title: 'Tag 标签', name: 'tag', @@ -433,13 +440,13 @@ export default { // path: '/flutter/components/message', // component: () => import('@/message/README.md'), // }, - // { - // title: 'NoticeBar 公告栏', - // name: 'noticebar', - // meta: { docType: 'message' }, - // path: '/flutter/components/notice-bar', - // component: () => import('@/notice-bar/README.md'), - // }, + { + title: 'NoticeBar 公告栏', + name: 'noticebar', + meta: { docType: 'message' }, + path: '/flutter/components/notice-bar', + component: () => import('@/notice-bar/README.md'), + }, // { // title: 'Overlay 遮罩层', // name: 'overlay', diff --git a/tdesign-site/src/button/README.md b/tdesign-site/src/button/README.md index 135907068..775c5052d 100644 --- a/tdesign-site/src/button/README.md +++ b/tdesign-site/src/button/README.md @@ -788,6 +788,7 @@ import 'package:tdesign_flutter/tdesign_flutter.dart'; | onTap | TDButtonEvent? | - | 点击事件 | | icon | IconData? | - | 图标icon | | iconWidget | Widget? | - | 自定义图标icon控件 | +| iconTextSpacing | double? | - | 自定义图标与文本之间距离 | | onLongPress | TDButtonEvent? | - | 长按事件 | | margin | EdgeInsetsGeometry? | - | 自定义margin | | padding | EdgeInsetsGeometry? | - | 自定义padding | diff --git a/tdesign-site/src/calendar/README.md b/tdesign-site/src/calendar/README.md new file mode 100644 index 000000000..a6e4cd590 --- /dev/null +++ b/tdesign-site/src/calendar/README.md @@ -0,0 +1,509 @@ +--- +title: Calendar 日历 +description: 按照日历形式展示数据或日期的容器。 +spline: base +isComponent: true +--- + + +## 引入 + +在tdesign_flutter/tdesign_flutter.dart中有所有组件的路径。 + +```dart +import 'package:tdesign_flutter/tdesign_flutter.dart'; +``` + +## 代码演示 + +[td_calendar_page.dart](https://github.com/Tencent/tdesign-flutter/blob/main/tdesign-component/example/lib/page/td_calendar_page.dart) + +### 1 组件类型 + + + + + + +
+Widget _buildSimple(BuildContext context) {
+  final size = MediaQuery.of(context).size;
+  final selected = ValueNotifier>([DateTime.now().millisecondsSinceEpoch]);
+  return ValueListenableBuilder(
+    valueListenable: selected,
+    builder: (context, value, child) {
+      final date = DateTime.fromMillisecondsSinceEpoch(value[0]);
+      return TDCellGroup(
+        cells: [
+          TDCell(
+            title: '单个选择日历',
+            arrow: true,
+            note: '${date.year}-${date.month}-${date.day}',
+            onClick: (cell) {
+              TDCalendarPopup(
+                context,
+                visible: true,
+                onConfirm: (value) {
+                  print('onConfirm:$value');
+                  selected.value = value;
+                },
+                onClose: () {
+                  print('onClose');
+                },
+                child: TDCalendar(
+                  title: '请选择日期',
+                  value: value,
+                  height: size.height * 0.6 + 176,
+                  onCellClick: (value, type, tdate) {
+                    print('onCellClick:$value');
+                  },
+                  onCellLongPress: (value, type, tdate) {
+                    print('onCellLongPress:$value');
+                  },
+                  onHeanderClick: (index, week) {
+                    print('onHeanderClick:$week');
+                  },
+                  onChange: (value) {
+                    print('onChange:$value');
+                  },
+                ),
+              );
+            },
+          ),
+          TDCell(
+            title: '多个选择日历',
+            arrow: true,
+            onClick: (cell) {
+              TDCalendarPopup(
+                context,
+                visible: true,
+                child: TDCalendar(
+                  title: '请选择日期',
+                  type: CalendarType.multiple,
+                  value: [DateTime.now().millisecondsSinceEpoch],
+                  height: size.height * 0.6 + 176,
+                ),
+              );
+            },
+          ),
+          TDCell(
+            title: '区间选择日历',
+            arrow: true,
+            onClick: (cell) {
+              TDCalendarPopup(
+                context,
+                visible: true,
+                child: TDCalendar(
+                  title: '请选择日期区间',
+                  type: CalendarType.range,
+                  value: [
+                    DateTime.now().millisecondsSinceEpoch,
+                    DateTime.now().add(const Duration(days: 6)).millisecondsSinceEpoch,
+                  ],
+                  height: size.height * 0.6 + 176,
+                ),
+              );
+            },
+          ),
+          TDCell(
+            title: '单个选择日历和时间',
+            arrow: true,
+            note: '${date.year}-${date.month}-${date.day} ${date.hour}:${date.minute}',
+            onClick: (cell) {
+              TDCalendarPopup(
+                context,
+                visible: true,
+                onConfirm: (value) {
+                  print('onConfirm:$value');
+                  selected.value = value;
+                },
+                onClose: () {
+                  print('onClose');
+                },
+                child: TDCalendar(
+                  title: '请选择日期和时间',
+                  value: value,
+                  height: size.height * 0.92,
+                  useTimePicker: true,
+                  onCellClick: (value, type, tdate) {
+                    print('onCellClick:$value');
+                  },
+                  onCellLongPress: (value, type, tdate) {
+                    print('onCellLongPress:$value');
+                  },
+                  onHeanderClick: (index, week) {
+                    print('onHeanderClick:$week');
+                  },
+                  onChange: (value) {
+                    print('onChange:$value');
+                  },
+                ),
+              );
+            },
+          ),
+          TDCell(
+            title: '区间选择日历和时间',
+            arrow: true,
+            onClick: (cell) {
+              TDCalendarPopup(
+                context,
+                visible: true,
+                onConfirm: (value) {
+                  print('onConfirm:$value');
+                },
+                onClose: () {
+                  print('onClose');
+                },
+                child: TDCalendar(
+                  title: '请选择日期和时间区间',
+                  height: size.height * 0.92,
+                  type: CalendarType.range,
+                  value: [
+                    DateTime.now().millisecondsSinceEpoch,
+                    DateTime.now().add(const Duration(days: 3)).millisecondsSinceEpoch,
+                  ],
+                  useTimePicker: true,
+                  onCellClick: (value, type, tdate) {
+                    print('onCellClick:$value');
+                  },
+                  onCellLongPress: (value, type, tdate) {
+                    print('onCellLongPress:$value');
+                  },
+                  onHeanderClick: (index, week) {
+                    print('onHeanderClick:$week');
+                  },
+                  onChange: (value) {
+                    print('onChange:$value');
+                  },
+                ),
+              );
+            },
+          ),
+        ],
+      );
+    },
+  );
+}
+ +
+ +### 1 组件样式 + +可以自由定义想要的风格 + + + + +
+Widget _buildStyle(BuildContext context) {
+  final size = MediaQuery.of(context).size;
+  const map = {
+    1: '初一',
+    2: '初二',
+    3: '初三',
+    14: '情人节',
+    15: '元宵节',
+  };
+  return TDCellGroup(
+    cells: [
+      TDCell(
+        title: '自定义文案',
+        arrow: true,
+        onClick: (cell) {
+          TDCalendarPopup(
+            context,
+            visible: true,
+            child: TDCalendar(
+              title: '请选择日期',
+              height: size.height * 0.6 + 176,
+              minDate: DateTime(2022, 1, 1).millisecondsSinceEpoch,
+              maxDate: DateTime(2022, 2, 15).millisecondsSinceEpoch,
+              format: (day) {
+                day?.suffix = '¥60';
+                if (day?.date.month == 2) {
+                  if (map.keys.contains(day?.date.day)) {
+                    day?.suffix = '¥100';
+                    day?.prefix = map[day.date.day];
+                    day?.style = TextStyle(
+                      fontSize: TDTheme.of(context).fontTitleMedium?.size,
+                      height: TDTheme.of(context).fontTitleMedium?.height,
+                      fontWeight: TDTheme.of(context).fontTitleMedium?.fontWeight,
+                      color: TDTheme.of(context).errorColor6,
+                    );
+                    if (day?.typeNotifier.value == DateSelectType.selected) {
+                      day?.style = day.style?.copyWith(color: TDTheme.of(context).fontWhColor1);
+                    }
+                  }
+                }
+                return null;
+              },
+            ),
+          );
+        },
+      ),
+      TDCell(
+        title: '自定义按钮',
+        arrow: true,
+        onClick: (cell) {
+          late final TDCalendarPopup calendar;
+          calendar = TDCalendarPopup(
+            context,
+            visible: true,
+            confirmBtn: Padding(
+              padding: EdgeInsets.symmetric(vertical: TDTheme.of(context).spacer16),
+              child: TDButton(
+                theme: TDButtonTheme.danger,
+                shape: TDButtonShape.round,
+                text: 'ok',
+                isBlock: true,
+                size: TDButtonSize.large,
+                onTap: () {
+                  print(calendar.selected);
+                  calendar.close();
+                },
+              ),
+            ),
+            child: TDCalendar(
+              title: '请选择日期',
+              value: [DateTime.now().millisecondsSinceEpoch],
+              height: size.height * 0.6 + 176,
+            ),
+          );
+        },
+      ),
+      TDCell(
+        title: '自定义日期区间',
+        arrow: true,
+        onClick: (cell) {
+          TDCalendarPopup(
+            context,
+            visible: true,
+            child: TDCalendar(
+              title: '请选择日期',
+              minDate: DateTime(2022, 1, 1).millisecondsSinceEpoch,
+              maxDate: DateTime(2022, 1, 31).millisecondsSinceEpoch,
+              value: [DateTime(2022, 1, 15).millisecondsSinceEpoch],
+              height: size.height * 0.6 + 176,
+            ),
+          );
+        },
+      ),
+    ],
+  );
+}
+ +
+ + + + + +
+Widget _buildStyle(BuildContext context) {
+  final size = MediaQuery.of(context).size;
+  const map = {
+    1: '初一',
+    2: '初二',
+    3: '初三',
+    14: '情人节',
+    15: '元宵节',
+  };
+  return TDCellGroup(
+    cells: [
+      TDCell(
+        title: '自定义文案',
+        arrow: true,
+        onClick: (cell) {
+          TDCalendarPopup(
+            context,
+            visible: true,
+            child: TDCalendar(
+              title: '请选择日期',
+              height: size.height * 0.6 + 176,
+              minDate: DateTime(2022, 1, 1).millisecondsSinceEpoch,
+              maxDate: DateTime(2022, 2, 15).millisecondsSinceEpoch,
+              format: (day) {
+                day?.suffix = '¥60';
+                if (day?.date.month == 2) {
+                  if (map.keys.contains(day?.date.day)) {
+                    day?.suffix = '¥100';
+                    day?.prefix = map[day.date.day];
+                    day?.style = TextStyle(
+                      fontSize: TDTheme.of(context).fontTitleMedium?.size,
+                      height: TDTheme.of(context).fontTitleMedium?.height,
+                      fontWeight: TDTheme.of(context).fontTitleMedium?.fontWeight,
+                      color: TDTheme.of(context).errorColor6,
+                    );
+                    if (day?.typeNotifier.value == DateSelectType.selected) {
+                      day?.style = day.style?.copyWith(color: TDTheme.of(context).fontWhColor1);
+                    }
+                  }
+                }
+                return null;
+              },
+            ),
+          );
+        },
+      ),
+      TDCell(
+        title: '自定义按钮',
+        arrow: true,
+        onClick: (cell) {
+          late final TDCalendarPopup calendar;
+          calendar = TDCalendarPopup(
+            context,
+            visible: true,
+            confirmBtn: Padding(
+              padding: EdgeInsets.symmetric(vertical: TDTheme.of(context).spacer16),
+              child: TDButton(
+                theme: TDButtonTheme.danger,
+                shape: TDButtonShape.round,
+                text: 'ok',
+                isBlock: true,
+                size: TDButtonSize.large,
+                onTap: () {
+                  print(calendar.selected);
+                  calendar.close();
+                },
+              ),
+            ),
+            child: TDCalendar(
+              title: '请选择日期',
+              value: [DateTime.now().millisecondsSinceEpoch],
+              height: size.height * 0.6 + 176,
+            ),
+          );
+        },
+      ),
+      TDCell(
+        title: '自定义日期区间',
+        arrow: true,
+        onClick: (cell) {
+          TDCalendarPopup(
+            context,
+            visible: true,
+            child: TDCalendar(
+              title: '请选择日期',
+              minDate: DateTime(2022, 1, 1).millisecondsSinceEpoch,
+              maxDate: DateTime(2022, 1, 31).millisecondsSinceEpoch,
+              value: [DateTime(2022, 1, 15).millisecondsSinceEpoch],
+              height: size.height * 0.6 + 176,
+            ),
+          );
+        },
+      ),
+    ],
+  );
+}
+ +
+ + +不使用Popup + + + + +
+Widget _buildBlock(BuildContext context) {
+  final size = MediaQuery.of(context).size;
+  return TDCalendar(
+    title: '请选择日期',
+    value: [DateTime.now().millisecondsSinceEpoch],
+    height: size.height * 0.6 + 176,
+  );
+}
+ +
+ + + + + +
+Widget _buildBlock(BuildContext context) {
+  final size = MediaQuery.of(context).size;
+  return TDCalendar(
+    title: '请选择日期',
+    value: [DateTime.now().millisecondsSinceEpoch],
+    height: size.height * 0.6 + 176,
+  );
+}
+ +
+ + + +## API +### TDCalendarStyle +#### 默认构造方法 + +| 参数 | 类型 | 默认值 | 说明 | +| --- | --- | --- | --- | +| decoration | | - | | +| titleStyle | TextStyle? | - | header区域 [TDCalendar.title]的样式 | +| titleMaxLine | int? | - | header区域 [TDCalendar.title]的行数 | +| titleCloseColor | Color? | - | header区域 关闭图标的颜色 | +| weekdayStyle | TextStyle? | - | header区域 周 文字样式 | +| monthTitleStyle | TextStyle? | - | body区域 年月文字样式 | +| cellStyle | TextStyle? | - | 日期样式 | +| centreColor | Color? | - | 日期范围内背景样式 | +| cellDecoration | BoxDecoration? | - | 日期decoration | +| cellPrefixStyle | TextStyle? | - | 日期前面的字符串的样式 | +| cellSuffixStyle | TextStyle? | - | 日期后面的字符串的样式 | + + +#### 工厂构造方法 + +| 名称 | 说明 | +| --- | --- | +| TDCalendarStyle.generateStyle | 生成默认样式 | +| TDCalendarStyle.cellStyle | 日期样式 | + +``` +``` + ### TDCalendar +#### 默认构造方法 + +| 参数 | 类型 | 默认值 | 说明 | +| --- | --- | --- | --- | +| key | | - | | +| firstDayOfWeek | int? | 0 | 第一天从星期几开始,默认 0 = 周日 | +| format | CalendarFormat? | - | 用于格式化日期的函数,可定义日期前后的显示内容和日期样式 | +| maxDate | int? | - | 最大可选的日期(fromMillisecondsSinceEpoch),不传则默认半年后 | +| minDate | int? | - | 最小可选的日期(fromMillisecondsSinceEpoch),不传则默认今天 | +| title | String? | - | 标题 | +| titleWidget | Widget? | - | 标题组件 | +| type | CalendarType? | CalendarType.single | 日历的选择类型,single = 单选;multiple = 多选; range = 区间选择 | +| value | List? | - | 当前选择的日期(fromMillisecondsSinceEpoch),不传则默认今天,当 type = single 时数组长度为1 | +| displayFormat | String? | 'year month' | 年月显示格式,`year`表示年,`month`表示月,如`year month`表示年在前、月在后、中间隔一个空格 | +| cellHeight | double? | 60 | 日期高度 | +| height | double? | - | 高度 | +| width | double? | - | 宽度 | +| style | TDCalendarStyle? | - | 自定义样式 | +| onChange | void Function(List value)? | - | 选中值变化时触发 | +| onCellClick | void Function(int value, DateSelectType type, TDate tdate)? | - | 点击日期时触发 | +| onCellLongPress | void Function(int value, DateSelectType type, TDate tdate)? | - | 长安日期时触发 | +| onHeanderClick | void Function(int index, String week)? | - | 点击周时触发 | +| useTimePicker | bool? | false | 是否显示时间选择器 | +| timePickerModel | List? | - | 自定义时间选择器 | + +``` +``` + ### TDCalendarPopup +#### 默认构造方法 + +| 参数 | 类型 | 默认值 | 说明 | +| --- | --- | --- | --- | +| context | BuildContext | context | 上下文 | +| top | double? | - | 距离顶部的距离 | +| autoClose | bool? | true | 自动关闭;在点击关闭按钮、确认按钮、遮罩层时自动关闭 | +| confirmBtn | Widget? | - | 自定义确认按钮 | +| visible | bool? | - | 默认是否显示日历 | +| onClose | VoidCallback? | - | 关闭时触发 | +| onConfirm | void Function(List value)? | - | 点击确认按钮时触发 | +| builder | CalendarBuilder? | - | 控件构建器,优先级高于[child] | +| child | TDCalendar? | - | 日历控件 | + + + \ No newline at end of file diff --git a/tdesign-site/src/cascader/README.md b/tdesign-site/src/cascader/README.md index 42b00f3e8..cc04a4290 100644 --- a/tdesign-site/src/cascader/README.md +++ b/tdesign-site/src/cascader/README.md @@ -122,8 +122,12 @@ import 'package:tdesign_flutter/tdesign_flutter.dart'; Widget _buildHorizontalLetterCascader(BuildContext context) { return GestureDetector( onTap: () { - TDCascader.showMultiCascader(context, title: '选择地址', data: _data_2, initialData: _initData_2, theme: 'tab', - onChange: (List selectData) { + TDCascader.showMultiCascader(context, + title: '选择地址', + data: _data_2, + initialData: _initData_2, + isLetterSort: true, + theme: 'tab', onChange: (List selectData) { setState(() { List result = []; int len = selectData.length; @@ -152,7 +156,7 @@ import 'package:tdesign_flutter/tdesign_flutter.dart'; Widget _buildHorizontalCompanyCascader(BuildContext context) { return GestureDetector( onTap: () { - TDCascader.showMultiCascader(context, title: '选择部门人员', data: _data_3, initialData: _initData_3, theme: 'tab', + TDCascader.showMultiCascader(context, title: '选择部门人员', data: _data_3,isLetterSort: true, initialData: _initData_3, theme: 'tab', onChange: (List selectData) { setState(() { List result = []; @@ -182,7 +186,7 @@ import 'package:tdesign_flutter/tdesign_flutter.dart'; Widget _buildVerticalCompanyCascader(BuildContext context) { return GestureDetector( onTap: () { - TDCascader.showMultiCascader(context, title: '选择部门人员', data: _data_3, initialData: _initData_3, theme: 'step', + TDCascader.showMultiCascader(context, title: '选择部门人员', data: _data_3,isLetterSort: true, initialData: _initData_3, theme: 'step', onChange: (List selectData) { setState(() { List result = []; @@ -223,6 +227,7 @@ import 'package:tdesign_flutter/tdesign_flutter.dart'; | backgroundColor | Color? | - | 背景颜色 | | topRadius | double? | - | 顶部圆角 | | closeText | String? | - | 关闭按钮文本 | +| isLetterSort | bool | false | 是否开启字母排序 | | onClose | Function? | - | 选择器关闭按钮回调 | | onChange | MultiCascaderCallback | - | 值发生变更时触发 | diff --git a/tdesign-site/src/cell/README.md b/tdesign-site/src/cell/README.md index 10f80948e..ae079f56c 100644 --- a/tdesign-site/src/cell/README.md +++ b/tdesign-site/src/cell/README.md @@ -197,6 +197,7 @@ Widget _buildCard(BuildContext context) { | borderedColor | Color? | - | 单元格边框颜色 | | groupBorderedColor | Color? | - | 单元格组边框颜色 | | backgroundColor | Color? | - | 默认状态背景颜色 | +| padding | EdgeInsets? | - | 单元格内边距 | #### 工厂构造方法 diff --git a/tdesign-site/src/date-time-picker/README.md b/tdesign-site/src/date-time-picker/README.md index 82051a184..d9c545145 100644 --- a/tdesign-site/src/date-time-picker/README.md +++ b/tdesign-site/src/date-time-picker/README.md @@ -285,6 +285,7 @@ import 'package:tdesign_flutter/tdesign_flutter.dart'; | showTitle | bool | true | 是否展示标题 | | pickerHeight | double | 200 | 选择器List的视窗高度,默认200 | | pickerItemCount | int | - | 选择器List视窗中item个数,pickerHeight / pickerItemCount即item高度 | +| onSelectedItemChanged | void Function(int index)? | - | 选择器选中项改变回调 | | key | | - | | ``` @@ -295,9 +296,9 @@ import 'package:tdesign_flutter/tdesign_flutter.dart'; | 名称 | 返回类型 | 参数 | 说明 | | --- | --- | --- | --- | -| showDatePicker | | required null context, required String title, required DatePickerCallback? onConfirm, DatePickerCallback? onCancel, bool useYear, bool useMonth, bool useDay, bool useHour, bool useMinute, bool useSecond, bool useWeekDay, Color? barrierColor, List dateStart, List? dateEnd, List? initialDate, String? rightText, String? leftText, Duration duration, double pickerHeight, int pickerItemCount, | 显示时间选择器 | -| showMultiPicker | | required null context, String? title, required MultiPickerCallback? onConfirm, MultiPickerCallback? onCancel, required List> data, List? initialIndexes, Duration duration, Color? barrierColor, double pickerHeight, int pickerItemCount, | 显示多级选择器 | -| showMultiLinkedPicker | | required null context, String? title, required MultiPickerCallback? onConfirm, MultiPickerCallback? onCancel, required Map data, required int columnNum, required List initialData, Duration duration, Color? barrierColor, double pickerHeight, int pickerItemCount, | 显示多级联动选择器 | +| showDatePicker | | required null context, required String title, required DatePickerCallback? onConfirm, DatePickerCallback? onCancel, bool useYear, bool useMonth, bool useDay, bool useHour, bool useMinute, bool useSecond, bool useWeekDay, Color? barrierColor, List dateStart, List? dateEnd, List? initialDate, String? rightText, String? leftText, TextStyle? leftTextStyle, TextStyle? centerTextStyle, TextStyle? rightTextStyle, Color? titleDividerColor, Duration duration, double pickerHeight, int pickerItemCount, | 显示时间选择器 | +| showMultiPicker | | required null context, String? title, required MultiPickerCallback? onConfirm, MultiPickerCallback? onCancel, required List> data, List? initialIndexes, Duration duration, Color? barrierColor, double pickerHeight, String? rightText, String? leftText, TextStyle? leftTextStyle, TextStyle? centerTextStyle, TextStyle? rightTextStyle, Color? titleDividerColor, double? topPadding, int pickerItemCount, | 显示多级选择器 | +| showMultiLinkedPicker | | required null context, String? title, required MultiPickerCallback? onConfirm, MultiPickerCallback? onCancel, required Map data, required int columnNum, required List initialData, Duration duration, Color? barrierColor, String? rightText, String? leftText, TextStyle? leftTextStyle, TextStyle? centerTextStyle, TextStyle? rightTextStyle, double pickerHeight, Color? titleDividerColor, double? topPadding, int pickerItemCount, | 显示多级联动选择器 | \ No newline at end of file diff --git a/tdesign-site/src/dialog/README.md b/tdesign-site/src/dialog/README.md index c3927e16b..e4dfb8a3f 100644 --- a/tdesign-site/src/dialog/README.md +++ b/tdesign-site/src/dialog/README.md @@ -722,6 +722,8 @@ import 'package:tdesign_flutter/tdesign_flutter.dart'; | leftBtn | TDDialogButtonOptions? | - | 左侧按钮配置 | | rightBtn | TDDialogButtonOptions? | - | 右侧按钮配置 | | showCloseButton | bool? | - | 显示右上角关闭按钮 | +| padding | EdgeInsets? | - | 内容内边距 | +| buttonWidget | Widget? | - | 自定义按钮 | ``` ``` @@ -761,6 +763,8 @@ import 'package:tdesign_flutter/tdesign_flutter.dart'; | buttonTextColor | Color? | - | 按钮文字颜色 | | buttonStyle | TDDialogButtonStyle | TDDialogButtonStyle.normal | 按钮样式 | | showCloseButton | bool? | - | 右上角关闭按钮 | +| padding | EdgeInsets? | const EdgeInsets.fromLTRB(24, 32, 24, 0) | 内容内边距 | +| buttonWidget | Widget? | - | 自定义按钮 | ``` ``` @@ -783,6 +787,9 @@ import 'package:tdesign_flutter/tdesign_flutter.dart'; | leftBtn | TDDialogButtonOptions? | - | 左侧按钮配置 | | rightBtn | TDDialogButtonOptions? | - | 右侧按钮配置 | | showCloseButton | bool? | - | 显示右上角关闭按钮 | +| padding | EdgeInsets? | const EdgeInsets.fromLTRB(24, 32, 24, 0) | 内容内边距 | +| buttonWidget | Widget? | - | 自定义按钮 | +| customInputWidget | Widget? | - | 自定义输入框 | ``` ``` @@ -807,6 +814,8 @@ import 'package:tdesign_flutter/tdesign_flutter.dart'; | rightBtnAction | Function()? | - | 右侧按钮默认点击 | | showCloseButton | bool? | - | 显示右上角关闭按钮 | | buttonStyle | | TDDialogButtonStyle.normal | | +| padding | EdgeInsets? | const EdgeInsets.fromLTRB(24, 32, 24, 0) | 内容内边距 | +| buttonWidget | Widget? | - | 自定义按钮 | #### 工厂构造方法 diff --git a/tdesign-site/src/drawer/README.md b/tdesign-site/src/drawer/README.md index c414e2ade..7eb01e9b1 100644 --- a/tdesign-site/src/drawer/README.md +++ b/tdesign-site/src/drawer/README.md @@ -295,6 +295,9 @@ Widget _buildBottomSimple(BuildContext context) { | drawerTop | double? | - | 距离顶部的距离 | | style | TDCellStyle? | - | 列表自定义样式 | | hover | bool? | true | 是否开启点击反馈 | +| backgroundColor | Color? | - | 组件背景颜色 | +| bordered | bool? | true | 是否显示边框 | +| isShowLastBordered | bool? | true | 是否显示最后一行分割线 | ``` ``` diff --git a/tdesign-site/src/dropdown-menu/README.md b/tdesign-site/src/dropdown-menu/README.md index 71819657a..e667769fb 100644 --- a/tdesign-site/src/dropdown-menu/README.md +++ b/tdesign-site/src/dropdown-menu/README.md @@ -23,43 +23,6 @@ import 'package:tdesign_flutter/tdesign_flutter.dart'; 单选下拉菜单 - - -
-TDDropdownMenu _buildDownSimple(BuildContext context) {
-  return TDDropdownMenu(
-    direction: TDDropdownMenuDirection.down,
-    onMenuOpened: (value) {
-      print('打开第$value个菜单');
-    },
-    onMenuClosed: (value) {
-      print('关闭第$value个菜单');
-    },
-    items: [
-      TDDropdownItem(
-        options: [
-          TDDropdownItemOption(label: '全部产品', value: 'all', selected: true),
-          TDDropdownItemOption(label: '最新产品', value: 'new'),
-          TDDropdownItemOption(label: '最火产品', value: 'hot'),
-        ],
-        onChange: (value) {
-          print('选择:$value');
-        },
-      ),
-      TDDropdownItem(
-        options: [
-          TDDropdownItemOption(label: '默认排序', value: 'default', selected: true),
-          TDDropdownItemOption(label: '价格从高到低', value: 'price'),
-        ],
-      ),
-    ],
-  );
-}
- -
- - -
@@ -99,81 +62,6 @@ TDDropdownMenu _buildDownSimple(BuildContext context) {
 分栏下拉菜单
 
           
-
-
-  
-TDDropdownMenu _buildDownChunk(BuildContext context) {
-  return TDDropdownMenu(
-    direction: TDDropdownMenuDirection.down,
-    items: [
-      TDDropdownItem(
-        label: '单列多选',
-        multiple: true,
-        options: [
-          TDDropdownItemOption(label: '选项1', value: '1', selected: true),
-          TDDropdownItemOption(label: '选项2', value: '2'),
-          TDDropdownItemOption(label: '选项3', value: '3'),
-          TDDropdownItemOption(label: '选项4', value: '4'),
-          TDDropdownItemOption(label: '选项5', value: '5'),
-          TDDropdownItemOption(label: '选项6', value: '6'),
-          TDDropdownItemOption(label: '选项7', value: '7'),
-          TDDropdownItemOption(label: '选项8', value: '8'),
-          TDDropdownItemOption(label: '禁用选项', value: '9', disabled: true),
-        ],
-        onChange: (value) {
-          print('选择:$value');
-        },
-        onConfirm: (value) {
-          print('确定选择:$value');
-        },
-        onReset: () {
-          print('清空选择');
-        },
-      ),
-      TDDropdownItem(
-        label: '双列多选',
-        multiple: true,
-        optionsColumns: 2,
-        options: [
-          TDDropdownItemOption(label: '选项1', value: '1', selected: true),
-          TDDropdownItemOption(label: '选项2', value: '2', selected: true),
-          TDDropdownItemOption(label: '选项3', value: '3'),
-          TDDropdownItemOption(label: '选项4', value: '4'),
-          TDDropdownItemOption(label: '选项5', value: '5'),
-          TDDropdownItemOption(label: '选项6', value: '6'),
-          TDDropdownItemOption(label: '选项7', value: '7'),
-          TDDropdownItemOption(label: '选项8', value: '8'),
-          TDDropdownItemOption(label: '禁用选项', value: '9', disabled: true),
-          TDDropdownItemOption(label: '禁用选项', value: '10', disabled: true),
-        ],
-      ),
-      TDDropdownItem(
-        label: '三列多选',
-        multiple: true,
-        optionsColumns: 3,
-        options: [
-          TDDropdownItemOption(label: '选项1', value: '1', selected: true),
-          TDDropdownItemOption(label: '选项2', value: '2', selected: true),
-          TDDropdownItemOption(label: '选项3', value: '3', selected: true),
-          TDDropdownItemOption(label: '选项4', value: '4'),
-          TDDropdownItemOption(label: '选项5', value: '5'),
-          TDDropdownItemOption(label: '选项6', value: '6'),
-          TDDropdownItemOption(label: '选项7', value: '7'),
-          TDDropdownItemOption(label: '选项8', value: '8'),
-          TDDropdownItemOption(label: '选项9', value: '9'),
-          TDDropdownItemOption(label: '禁用选项', value: '10', disabled: true),
-          TDDropdownItemOption(label: '禁用选项', value: '11', disabled: true),
-          TDDropdownItemOption(label: '禁用选项', value: '12', disabled: true),
-        ],
-      ),
-    ],
-  );
-}
- -
- - -
@@ -251,45 +139,6 @@ TDDropdownMenu _buildDownChunk(BuildContext context) {
 向上展开
 
           
-
-
-  
-TDDropdownMenu _buildUp(BuildContext context) {
-  return TDDropdownMenu(
-    direction: TDDropdownMenuDirection.up,
-    onMenuOpened: (value) {
-      print('打开第$value个菜单');
-    },
-    onMenuClosed: (value) {
-      print('关闭第$value个菜单');
-    },
-    builder: (context) {
-      return [
-        TDDropdownItem(
-          options: [
-            TDDropdownItemOption(label: '全部产品', value: 'all', selected: true),
-            TDDropdownItemOption(label: '最新产品', value: 'new'),
-            TDDropdownItemOption(label: '最火产品', value: 'hot'),
-          ],
-          onChange: (value) {
-            print('选择:$value');
-          },
-        ),
-        TDDropdownItem(
-          options: [
-            TDDropdownItemOption(label: '默认排序', value: 'default', selected: true),
-            TDDropdownItemOption(label: '价格从高到低', value: 'price'),
-          ],
-        ),
-      ];
-    },
-  );
-}
- -
- - -
@@ -479,14 +328,18 @@ TDDropdownMenu _buildGroup(BuildContext context) {
 | showOverlay | bool? | true | 是否显示遮罩层 |
 | isScrollable | bool | false | 是否开启滚动列表 |
 | arrowIcon | IconData? | - | 自定义箭头图标 |
+| labelBuilder | LabelBuilder? | - | 自定义标签内容 |
 | onMenuOpened | ValueChanged? | - | 展开菜单事件 |
 | onMenuClosed | ValueChanged? | - | 关闭菜单事件 |
+| width | double? | - | menu的宽度 |
+| height | double? | 48 | menu的高度 |
+| tabBarAlign | MainAxisAlignment? | MainAxisAlignment.center | [TDDropdownItem.label]和[arrowIcon]/[TDDropdownItem.arrowIcon]的对齐方式 |
 
 ```
 ```
  ### TDDropdownItem
 #### 简介
-下拉菜单
+下拉菜单内容
 #### 默认构造方法
 
 | 参数 | 类型 | 默认值 | 说明 |
@@ -494,6 +347,7 @@ TDDropdownMenu _buildGroup(BuildContext context) {
 | key |  | - |  |
 | disabled | bool? | false | 是否禁用 |
 | label | String? | - | 标题 |
+| arrowIcon | IconData? | - | 自定义箭头图标 |
 | multiple | bool? | false | 是否多选 |
 | options | List? | const [] | 选项数据 |
 | builder | TDDropdownItemContentBuilder? | - | 完全自定义展示内容 |
@@ -503,6 +357,8 @@ TDDropdownMenu _buildGroup(BuildContext context) {
 | onReset | VoidCallback? | - | 点击重置时触发 |
 | minHeight | double? | - | 内容最小高度 |
 | maxHeight | double? | - | 内容最大高度 |
+| tabBarWidth | double? | - | 该item在menu上的宽度,仅在[TDDropdownMenu.isScrollable]为true时有效 |
+| tabBarAlign | MainAxisAlignment? | - | [label]和[arrowIcon]/[TDDropdownMenu.arrowIcon]的对齐方式 |
 
 ```
 ```
diff --git a/tdesign-site/src/image-viewer/README.md b/tdesign-site/src/image-viewer/README.md
index b71225f44..dfabdfd90 100644
--- a/tdesign-site/src/image-viewer/README.md
+++ b/tdesign-site/src/image-viewer/README.md
@@ -47,6 +47,10 @@ import 'package:tdesign_flutter/tdesign_flutter.dart';
 
   
   Widget _actionImageViewer(BuildContext context) {
+    var delImages = [
+      'https://tdesign.gtimg.com/mobile/demos/swiper1.png',
+      'https://tdesign.gtimg.com/mobile/demos/swiper2.png',
+    ];
     return TDButton(
       type: TDButtonType.ghost,
       theme: TDButtonTheme.primary,
@@ -56,7 +60,7 @@ import 'package:tdesign_flutter/tdesign_flutter.dart';
       onTap: () {
         TDImageViewer.showImageViewer(
           context: context,
-          images: images,
+          images: delImages,
           showIndex: true,
           deleteBtn: true,
         );
diff --git a/tdesign-site/src/indexes/README.md b/tdesign-site/src/indexes/README.md
index 12b8f9c09..7ac4a98d7 100644
--- a/tdesign-site/src/indexes/README.md
+++ b/tdesign-site/src/indexes/README.md
@@ -243,7 +243,7 @@ Widget _buildOther(BuildContext context) {
 | indexList | List | - | 索引字符列表。不传默认 A-Z |
 | indexListMaxHeight | double | 0.8 | 索引列表最大高度(父容器高度的百分比,默认0.8) |
 | activeIndex | ValueNotifier | - | 选中索引 |
-| onSelect | void Function(String index, bool isUp) | - | 点击侧边栏时触发事件 |
+| onSelect | void Function(String newIndex, String oldIndex) | - | 点击侧边栏时触发事件 |
 | builderIndex | Widget Function(BuildContext context, String index, bool isActive)? | - | 索引文本自定义构建,包括索引激活左侧提示 |
 
 ```
diff --git a/tdesign-site/src/input/README.md b/tdesign-site/src/input/README.md
index 55998bf26..d21130386 100644
--- a/tdesign-site/src/input/README.md
+++ b/tdesign-site/src/input/README.md
@@ -668,6 +668,8 @@ import 'package:tdesign_flutter/tdesign_flutter.dart';
     return Column(
       children: [
         TDInput(
+          leftInfoWidth: 80,
+          spacer: TDInputSpacer(iconLabelSpace: 4),
           leftLabel: '标签超长时最多十个字',
           controller: controller[18],
           backgroundColor: Colors.white,
@@ -815,6 +817,7 @@ import 'package:tdesign_flutter/tdesign_flutter.dart';
   
   Widget _verticalStyle(BuildContext context) {
     return TDInput(
+      spacer: TDInputSpacer(iconLabelSpace: 0),
       type: TDInputType.twoLine,
       leftLabel: '标签文字',
       controller: controller[20],
@@ -947,7 +950,7 @@ import 'package:tdesign_flutter/tdesign_flutter.dart';
 | decoration | Decoration? | - | 输入框样式 |
 | leftIcon | Widget? | - | 带图标的输入框 |
 | leftLabel | String? | - | 输入框左侧文案 |
-| leftLabelStyle | TextStyle? | - | 左侧标签样式 |
+| leftLabelStyle | TextStyle? | - | 左侧标签样式 设置该值是若出现像素溢出,请设置letterSpacing: 0 |
 | leftLabelSpace | double? | - | 输入框左侧文案间距 |
 | required | bool? | - | 是否必填标志(红色*) |
 | readOnly | bool | false | 是否只读 |
@@ -989,6 +992,7 @@ import 'package:tdesign_flutter/tdesign_flutter.dart';
 | inputAction | TextInputAction? | - | 键盘动作类型 |
 | spacer | TDInputSpacer | - | 组件各模块间间距 |
 | cardStyleBottomText | String? | - | 卡片模式下方文字 |
+| onTapOutside | TapRegionCallback? | - | 点击输入框外部区域回调 |
 
 
   
\ No newline at end of file
diff --git a/tdesign-site/src/loading/README.md b/tdesign-site/src/loading/README.md
index cc8441f38..40d0a28ee 100644
--- a/tdesign-site/src/loading/README.md
+++ b/tdesign-site/src/loading/README.md
@@ -240,7 +240,7 @@ import 'package:tdesign_flutter/tdesign_flutter.dart';
 | --- | --- | --- | --- |
 | key |  | - |  |
 | size | TDLoadingSize | - | 尺寸 |
-| icon | TDLoadingIcon? | - | 图标,支持圆形、点状、菊花状 |
+| icon | TDLoadingIcon? | TDLoadingIcon.circle | 图标,支持圆形、点状、菊花状 |
 | iconColor | Color? | - | 图标颜色 |
 | axis | Axis | Axis.vertical | 文案和图标相对方向 |
 | text | String? | - | 文案 |
diff --git a/tdesign-site/src/navbar/README.md b/tdesign-site/src/navbar/README.md
index cf0204e6c..042b1e7cb 100644
--- a/tdesign-site/src/navbar/README.md
+++ b/tdesign-site/src/navbar/README.md
@@ -310,6 +310,8 @@ import 'package:tdesign_flutter/tdesign_flutter.dart';
 | useBorderStyle | bool | false | 是否使用边框模式 |
 | border | TDNavBarItemBorder? | - | 边框 |
 | belowTitleWidget | Widget? | - | belowTitleWidget navbar 下方的widget |
+| boxShadow | List? | - | 底部阴影 |
+| flexibleSpace | Widget? | - | 固定背景 |
 
 ```
 ```
diff --git a/tdesign-site/src/notice-bar/README.md b/tdesign-site/src/notice-bar/README.md
new file mode 100644
index 000000000..e60424ae1
--- /dev/null
+++ b/tdesign-site/src/notice-bar/README.md
@@ -0,0 +1,326 @@
+---
+title: NoticeBar 公告栏
+description: 在导航栏下方,用于给用户显示提示消息。
+spline: base
+isComponent: true
+---
+
+
+## 引入
+
+在tdesign_flutter/tdesign_flutter.dart中有所有组件的路径。
+
+```dart
+import 'package:tdesign_flutter/tdesign_flutter.dart';
+```
+
+## 代码演示
+
+[td_notice-bar_page.dart](https://github.com/Tencent/tdesign-flutter/blob/main/tdesign-component/example/lib/page/td_notice-bar_page.dart)
+
+### 1 组件类型
+
+纯文字的公告栏
+            
+
+
+  
+Widget _textNoticeBar(BuildContext context) {
+  return const TDNoticeBar(context: '这是一条普通的通知信息');
+}
+ +
+ + +可滚动的公告栏 + + + +
+Widget _scrollNoticeBar(BuildContext context) {
+  return const TDNoticeBar(
+    context: '提示文字描述提示文字描述提示文字描述提示文字描述提示文字',
+    marquee: true,
+    speed: 50,
+  );
+}
+ +
+ + + + + + +
+Widget _scrollIconNoticeBar(BuildContext context) {
+  return const Padding(
+    padding: EdgeInsets.only(top: 16),
+    child: TDNoticeBar(
+      context: '提示文字描述提示文字描述提示文字描述提示文字描述提示文字',
+      speed: 50,
+      prefixIcon: TDIcons.sound,
+      marquee: true,
+    ),
+  );
+}
+ +
+ + +带图标的公告栏 + + + +
+Widget _iconNoticeBar(BuildContext context) {
+  return const TDNoticeBar(
+    context: '这是一条普通的通知信息',
+    prefixIcon: TDIcons.error_circle_filled,
+  );
+}
+ +
+ + +带关闭的公告栏 + + + +
+Widget _closeNoticeBar(BuildContext context) {
+  return const TDNoticeBar(
+    context: '这是一条普通的通知信息',
+    prefixIcon: TDIcons.error_circle_filled,
+    suffixIcon: TDIcons.close,
+  );
+}
+ +
+ + +带入口的公告栏 + + + +
+Widget _entranceNoticeBar1(BuildContext context) {
+  return const TDNoticeBar(
+    context: '这是一条普通的通知信息',
+    prefixIcon: TDIcons.error_circle_filled,
+    right: TDButton(
+      text: '文字按钮',
+      type: TDButtonType.text,
+      theme: TDButtonTheme.primary,
+      size: TDButtonSize.extraSmall,
+      height: 22,
+      padding: EdgeInsets.symmetric(vertical: 0, horizontal: 0),
+    ),
+  );
+}
+ +
+ + + + + + +
+Widget _entranceNoticeBar2(BuildContext context) {
+  return const Padding(
+    padding: EdgeInsets.only(top: 16),
+    child: TDNoticeBar(
+      context: '这是一条普通的通知信息',
+      prefixIcon: TDIcons.error_circle_filled,
+      suffixIcon: TDIcons.chevron_right,
+    ),
+  );
+}
+ +
+ + +自定义样式的公告栏 + + + +
+Widget _customNoticeBar(BuildContext context) {
+  return TDNoticeBar(
+    context: '这是一条普通的通知信息',
+    prefixIcon: TDIcons.notification,
+    suffixIcon: TDIcons.chevron_right,
+    style: TDNoticeBarStyle(backgroundColor: TDTheme.of(context).grayColor3),
+  );
+}
+ +
+ +### 1 组件状态 + +普通通知 + + + +
+Widget _normalNoticeBar(BuildContext context) {
+  return const TDNoticeBar(
+    context: '这是一条普通的通知信息',
+    prefixIcon: TDIcons.error_circle_filled,
+    theme: TDNoticeBarTheme.info,
+  );
+}
+ +
+ + +成功通知 + + + +
+Widget _successNoticeBar(BuildContext context) {
+  return const TDNoticeBar(
+    context: '这是一条普通的通知信息',
+    prefixIcon: TDIcons.error_circle_filled,
+    theme: TDNoticeBarTheme.success,
+  );
+}
+ +
+ + +警示通知 + + + +
+Widget _warningNoticeBar(BuildContext context) {
+  return const TDNoticeBar(
+    context: '这是一条普通的通知信息',
+    prefixIcon: TDIcons.error_circle_filled,
+    theme: TDNoticeBarTheme.warning,
+  );
+}
+ +
+ + +错误通知 + + + +
+Widget _errorNoticeBar(BuildContext context) {
+  return const TDNoticeBar(
+    context: '这是一条普通的通知信息',
+    prefixIcon: TDIcons.error_circle_filled,
+    theme: TDNoticeBarTheme.error,
+  );
+}
+ +
+ +### 1 组件样式 + +卡片顶部 + + + +
+Widget _cardNoticeBar(BuildContext context) {
+  var size = MediaQuery.of(context).size;
+  return Container(
+    margin: const EdgeInsets.symmetric(horizontal: 16),
+    decoration: BoxDecoration(
+      color: TDNoticeBarStyle.generateTheme(context).backgroundColor,
+      borderRadius: const BorderRadius.all(Radius.circular(9)),
+      boxShadow: const [
+        BoxShadow(
+          color: Color(0x0d000000),
+          blurRadius: 8,
+          spreadRadius: 2,
+          offset: Offset(0, 2),
+        ),
+        BoxShadow(
+          color: Color(0x0f000000),
+          blurRadius: 10,
+          spreadRadius: 1,
+          offset: Offset(0, 8),
+        ),
+        BoxShadow(
+          color: Color(0x1a000000),
+          blurRadius: 5,
+          spreadRadius: -3,
+          offset: Offset(0, 5),
+        ),
+      ],
+    ),
+    child: Column(
+      children: [
+        Container(
+          width: size.width - 32,
+          decoration: const BoxDecoration(
+            borderRadius: BorderRadius.all(Radius.circular(12)),
+          ),
+          clipBehavior: Clip.hardEdge,
+          child: const TDNoticeBar(
+            context: '这是一条普通的通知信息',
+            prefixIcon: TDIcons.error_circle_filled,
+            suffixIcon: TDIcons.chevron_right,
+          ),
+        ),
+        Container(
+          height: 150,
+          decoration: const BoxDecoration(
+            color: Colors.white,
+            borderRadius: BorderRadius.all(Radius.circular(12)),
+          ),
+        )
+      ],
+    ),
+  );
+}
+ +
+ + + +## API +### TDNoticeBar +#### 默认构造方法 + +| 参数 | 类型 | 默认值 | 说明 | +| --- | --- | --- | --- | +| key | | - | | +| context | dynamic | - | 文本内容 | +| style | TDNoticeBarStyle? | - | 公告栏样式 | +| left | Widget? | - | 左侧内容(自定义左侧内容,优先级高于prefixIcon) | +| right | Widget? | - | 侧内容(自定义右侧内容,优先级高于suffixIcon) | +| marquee | bool? | false | 跑马灯效果 | +| speed | double? | 50 | 滚动速度 | +| interval | int? | 3000 | 步进滚动间隔时间(毫秒) | +| direction | Axis? | Axis.horizontal | 滚动方向 | +| theme | TDNoticeBarThemez? | TDNoticeBarThemez.info | 主题 | +| prefixIcon | IconData? | - | 左侧图标 | +| suffixIcon | IconData? | - | 右侧图标 | +| onTap | ValueChanged? | - | 点击事件 | + +``` +``` +### TDNoticeBarStyle +#### 默认构造方法 + +| 参数 | 类型 | 默认值 | 说明 | +| --- | --- | --- | --- | +| context | BuildContext? | - | 上下文 | +| backgroundColor | Color? | - | 公告栏的背景色 | +| leftIconColor | Color? | - | 公告栏左侧图标的颜色 | +| rightIconColor | Color? | - | 公告栏右侧图标的颜色 | +| padding | EdgeInsetsGeometry? | EdgeInsets.only(top: 13, bottom: 13, left: 16, right: 12) | 公告栏的内边距 | +| textStyle | TextStyle? | TextStyle(color: TDTheme.of(context).fontGyColor1, fontSize: 16, height: 1) | 公告栏内容的文本样式 | + + + + \ No newline at end of file diff --git a/tdesign-site/src/picker/README.md b/tdesign-site/src/picker/README.md index 4093b2a59..e6ffcdd33 100644 --- a/tdesign-site/src/picker/README.md +++ b/tdesign-site/src/picker/README.md @@ -153,6 +153,8 @@ import 'package:tdesign_flutter/tdesign_flutter.dart'; | pickerHeight | double | - | | | pickerItemCount | int | - | 选择器List视窗中item个数,pickerHeight / pickerItemCount即item高度 | | initialIndexes | List? | - | 若为null表示全部从零开始 | +| rightText | String? | - | 右侧按钮文案 | +| leftText | String? | - | 左侧按钮文案 | | leftTextStyle | TextStyle? | - | 自定义左侧文案样式 | | rightTextStyle | TextStyle? | - | 自定义右侧文案样式 | | centerTextStyle | TextStyle? | - | 自定义中间文案样式 | @@ -184,6 +186,8 @@ import 'package:tdesign_flutter/tdesign_flutter.dart'; | pickerHeight | double | 200 | | | pickerItemCount | int | 5 | 选择器List视窗中item个数,pickerHeight / pickerItemCount即item高度 | | customSelectWidget | Widget? | - | 自定义选择框样式 | +| rightText | String? | - | 右侧按钮文案 | +| leftText | String? | - | 左侧按钮文案 | | leftTextStyle | TextStyle? | - | 自定义左侧文案样式 | | rightTextStyle | TextStyle? | - | 自定义右侧文案样式 | | centerTextStyle | TextStyle? | - | 自定义中间文案样式 | @@ -217,9 +221,9 @@ import 'package:tdesign_flutter/tdesign_flutter.dart'; | 名称 | 返回类型 | 参数 | 说明 | | --- | --- | --- | --- | -| showDatePicker | | required null context, required String title, required DatePickerCallback? onConfirm, DatePickerCallback? onCancel, bool useYear, bool useMonth, bool useDay, bool useHour, bool useMinute, bool useSecond, bool useWeekDay, Color? barrierColor, List dateStart, List? dateEnd, List? initialDate, String? rightText, String? leftText, Duration duration, double pickerHeight, int pickerItemCount, | 显示时间选择器 | -| showMultiPicker | | required null context, String? title, required MultiPickerCallback? onConfirm, MultiPickerCallback? onCancel, required List> data, List? initialIndexes, Duration duration, Color? barrierColor, double pickerHeight, int pickerItemCount, | 显示多级选择器 | -| showMultiLinkedPicker | | required null context, String? title, required MultiPickerCallback? onConfirm, MultiPickerCallback? onCancel, required Map data, required int columnNum, required List initialData, Duration duration, Color? barrierColor, double pickerHeight, int pickerItemCount, | 显示多级联动选择器 | +| showDatePicker | | required null context, required String title, required DatePickerCallback? onConfirm, DatePickerCallback? onCancel, bool useYear, bool useMonth, bool useDay, bool useHour, bool useMinute, bool useSecond, bool useWeekDay, Color? barrierColor, List dateStart, List? dateEnd, List? initialDate, String? rightText, String? leftText, TextStyle? leftTextStyle, TextStyle? centerTextStyle, TextStyle? rightTextStyle, Color? titleDividerColor, Duration duration, double pickerHeight, int pickerItemCount, | 显示时间选择器 | +| showMultiPicker | | required null context, String? title, required MultiPickerCallback? onConfirm, MultiPickerCallback? onCancel, required List> data, List? initialIndexes, Duration duration, Color? barrierColor, double pickerHeight, String? rightText, String? leftText, TextStyle? leftTextStyle, TextStyle? centerTextStyle, TextStyle? rightTextStyle, Color? titleDividerColor, double? topPadding, int pickerItemCount, | 显示多级选择器 | +| showMultiLinkedPicker | | required null context, String? title, required MultiPickerCallback? onConfirm, MultiPickerCallback? onCancel, required Map data, required int columnNum, required List initialData, Duration duration, Color? barrierColor, String? rightText, String? leftText, TextStyle? leftTextStyle, TextStyle? centerTextStyle, TextStyle? rightTextStyle, double pickerHeight, Color? titleDividerColor, double? topPadding, int pickerItemCount, | 显示多级联动选择器 | \ No newline at end of file diff --git a/tdesign-site/src/popup/README.md b/tdesign-site/src/popup/README.md index 629150ab7..b945664ef 100644 --- a/tdesign-site/src/popup/README.md +++ b/tdesign-site/src/popup/README.md @@ -477,6 +477,8 @@ import 'package:tdesign_flutter/tdesign_flutter.dart'; | modalLeft | double? | 0 | 弹出框左侧距离 | | open | VoidCallback? | - | 打开前事件 | | opened | VoidCallback? | - | 打开后事件 | +| close | VoidCallback? | - | 关闭前事件 | +| barrierClick | VoidCallback? | - | 蒙层点击事件,仅在[modalBarrierFull]为false时触发 | ``` ``` diff --git a/tdesign-site/src/radio/README.md b/tdesign-site/src/radio/README.md index b6155eac7..c8af5dddf 100644 --- a/tdesign-site/src/radio/README.md +++ b/tdesign-site/src/radio/README.md @@ -281,6 +281,7 @@ import 'package:tdesign_flutter/tdesign_flutter.dart'; selectId: 'index:1', cardMode: true, direction: Axis.horizontal, + rowCount: 2, directionalTdRadios: const [ TDRadio( id: 'index:0', @@ -368,6 +369,7 @@ RadioGroup分组对象,继承自TDCheckboxGroup,字段含义与父类一致 | customIconBuilder | | - | | | customContentBuilder | | - | | | spacing | | - | | +| rowCount | int | 1 | 每行几列 | | contentDirection | | - | | | onRadioGroupChange | | - | | | showDivider | bool | false | 是否显示下划线 | diff --git a/tdesign-site/src/result/README.md b/tdesign-site/src/result/README.md new file mode 100644 index 000000000..03862d6b2 --- /dev/null +++ b/tdesign-site/src/result/README.md @@ -0,0 +1,314 @@ +--- +title: Result 结果 +description: 反馈结果状态。 +spline: base +isComponent: true +--- + + +## 引入 + +在tdesign_flutter/tdesign_flutter.dart中有所有组件的路径。 + +```dart +import 'package:tdesign_flutter/tdesign_flutter.dart'; +``` + +## 代码演示 + +[td_result_page.dart](https://github.com/Tencent/tdesign-flutter/blob/main/tdesign-component/example/lib/page/td_result_page.dart) + +### 1 组件类型 + +基础结果 + + + + +
+  TDResult _buildBasicResultSuccess(BuildContext context) {
+    return const TDResult(
+      title: '成功状态',
+      theme: TDResultTheme.success,
+    );
+  }
+ +
+ + + + + +
+  TDResult _buildBasicResultError(BuildContext context) {
+    return const TDResult(
+      title: '失败状态',
+      theme: TDResultTheme.error,
+    );
+  }
+ +
+ + + + + +
+  TDResult _buildBasicResultWarning(BuildContext context) {
+    return const TDResult(
+      title: '警示状态',
+      theme: TDResultTheme.warning,
+    );
+  }
+ +
+ + + + + +
+  TDResult _buildBasicResultDefault(BuildContext context) {
+    return const TDResult(
+      title: '默认状态',
+      theme: TDResultTheme.defaultTheme,
+    );
+  }
+ +
+ + + + + +
+  TDResult _buildBasicResultSuccess(BuildContext context) {
+    return const TDResult(
+      title: '成功状态',
+      theme: TDResultTheme.success,
+    );
+  }
+ +
+ + + + + +
+  TDResult _buildBasicResultError(BuildContext context) {
+    return const TDResult(
+      title: '失败状态',
+      theme: TDResultTheme.error,
+    );
+  }
+ +
+ + + + + +
+  TDResult _buildBasicResultWarning(BuildContext context) {
+    return const TDResult(
+      title: '警示状态',
+      theme: TDResultTheme.warning,
+    );
+  }
+ +
+ + + + + +
+  TDResult _buildBasicResultDefault(BuildContext context) {
+    return const TDResult(
+      title: '默认状态',
+      theme: TDResultTheme.defaultTheme,
+    );
+  }
+ +
+ + +带描述的结果 + + + + +
+  TDResult _buildResultWithDescriptionSuccess(BuildContext context) {
+    return const TDResult(
+      title: '成功状态',
+      theme: TDResultTheme.success,
+      description: '描述文字',
+    );
+  }
+ +
+ + + + + +
+  TDResult _buildResultWithDescriptionError(BuildContext context) {
+    return const TDResult(
+      title: '失败状态',
+      theme: TDResultTheme.error,
+      description: '描述文字',
+    );
+  }
+ +
+ + + + + +
+  TDResult _buildResultWithDescriptionWarning(BuildContext context) {
+    return const TDResult(
+      title: '警示状态',
+      theme: TDResultTheme.warning,
+      description: '描述文字',
+    );
+  }
+ +
+ + + + + +
+  TDResult _buildResultWithDescriptionDefault(BuildContext context) {
+    return const TDResult(
+      title: '默认状态',
+      theme: TDResultTheme.defaultTheme,
+      description: '描述文字',
+    );
+  }
+ +
+ + + + + +
+  TDResult _buildResultWithDescriptionSuccess(BuildContext context) {
+    return const TDResult(
+      title: '成功状态',
+      theme: TDResultTheme.success,
+      description: '描述文字',
+    );
+  }
+ +
+ + + + + +
+  TDResult _buildResultWithDescriptionError(BuildContext context) {
+    return const TDResult(
+      title: '失败状态',
+      theme: TDResultTheme.error,
+      description: '描述文字',
+    );
+  }
+ +
+ + + + + +
+  TDResult _buildResultWithDescriptionWarning(BuildContext context) {
+    return const TDResult(
+      title: '警示状态',
+      theme: TDResultTheme.warning,
+      description: '描述文字',
+    );
+  }
+ +
+ + + + + +
+  TDResult _buildResultWithDescriptionDefault(BuildContext context) {
+    return const TDResult(
+      title: '默认状态',
+      theme: TDResultTheme.defaultTheme,
+      description: '描述文字',
+    );
+  }
+ +
+ + +自定义结果 + + + + +
+  TDResult _buildCustomResultContent(BuildContext context) {
+    return TDResult(
+      title: '自定义结果',
+      icon: Image.asset('assets/img/illustration.png'),
+      description: '描述文字',
+    );
+  }
+ +
+ + + + + +
+  TDResult _buildCustomResultContent(BuildContext context) {
+    return TDResult(
+      title: '自定义结果',
+      icon: Image.asset('assets/img/illustration.png'),
+      description: '描述文字',
+    );
+  }
+ +
+ + +页面示例 + + + +
暂无演示代码
+ +
+ + + +## API +### TDResult +#### 默认构造方法 + +| 参数 | 类型 | 默认值 | 说明 | +| --- | --- | --- | --- | +| description | String? | - | 描述文本,用于提供额外信息 | +| icon | Widget? | - | 图标组件,用于在结果中显示一个图标 | +| titleStyle | TextStyle? | - | 自定义字体样式,用于设置标题文本的样式 | +| theme | TDResultTheme | - | 主题样式,定义了结果组件的视觉风格 | +| title | String | - | 标题文本,显示结果的主要信息 | + + + \ No newline at end of file diff --git a/tdesign-site/src/search/README.md b/tdesign-site/src/search/README.md index f48dbb35c..ff5fe5e29 100644 --- a/tdesign-site/src/search/README.md +++ b/tdesign-site/src/search/README.md @@ -135,9 +135,14 @@ import 'package:tdesign_flutter/tdesign_flutter.dart'; | padding | EdgeInsets | const EdgeInsets.fromLTRB(16, 8, 16, 8) | 内部填充 | | autoFocus | bool | false | 是否自动获取焦点 | | mediumStyle | bool | false | 是否在导航栏中的样式 | +| cursorHeight | double? | - | 光标的高 | | needCancel | bool | false | 是否需要取消按钮 | | controller | TextEditingController? | - | 控制器 | | backgroundColor | Color? | Colors.white | 背景颜色 | +| action | String | '' | 自定义操作文字 | +| onActionClick | TDSearchBarEvent? | - | 自定义操作回调 | +| onClearClick | TDSearchBarClearEvent? | - | 自定义操作回调 | +| focusNode | FocusNode? | - | 自定义焦点 | \ No newline at end of file diff --git a/tdesign-site/src/side-bar/README.md b/tdesign-site/src/side-bar/README.md index 83b1a75fc..2d832e2af 100644 --- a/tdesign-site/src/side-bar/README.md +++ b/tdesign-site/src/side-bar/README.md @@ -688,6 +688,8 @@ import 'package:tdesign_flutter/tdesign_flutter.dart'; | contentPadding | EdgeInsetsGeometry? | - | 自定义文本框内边距 | | selectedTextStyle | TextStyle? | - | 选中样式 | | style | TDSideBarStyle | TDSideBarStyle.normal | 样式 | +| loading | bool? | - | 加载效果 | +| loadingWidget | Widget? | - | 自定义加载动画 | \ No newline at end of file diff --git a/tdesign-site/src/table/README.md b/tdesign-site/src/table/README.md new file mode 100644 index 000000000..a8c67cec9 --- /dev/null +++ b/tdesign-site/src/table/README.md @@ -0,0 +1,294 @@ +--- +title: Table 表格 +description: 表格常用于展示同类结构下的多种数据,易于组织、对比和分析等,并可对数据进行搜索、筛选、排序等操作。一般包括表头、数据行和表尾三部分。 +spline: base +isComponent: true +--- + + +## 引入 + +在tdesign_flutter/tdesign_flutter.dart中有所有组件的路径。 + +```dart +import 'package:tdesign_flutter/tdesign_flutter.dart'; +``` + +## 代码演示 + +[td_table_page.dart](https://github.com/Tencent/tdesign-flutter/blob/main/tdesign-component/example/lib/page/td_table_page.dart) + +### 1 组件类型 + +基础表格 + + + +
+  Widget _basicTable(BuildContext context) {
+    return TDTable(
+      columns: [
+        TDTableCol(title: '标题', colKey: 'title1', ellipsis: true),
+        TDTableCol(title: '标题', colKey: 'title2'),
+        TDTableCol(title: '标题', colKey: 'title3'),
+        TDTableCol(title: '标题', colKey: 'title4')
+      ],
+      data: _getData(9),
+    );
+  }
+ +
+ + +可排序表格 + + + +
+  Widget _sortableTable(BuildContext context) {
+    return TDTable(
+      columns: [
+        TDTableCol(title: '标题', colKey: 'title1', ellipsis: true, sortable: true),
+        TDTableCol(title: '标题', colKey: 'title2', sortable: true),
+        TDTableCol(title: '标题', colKey: 'title3', sortable: true),
+        TDTableCol(title: '标题', colKey: 'title4', sortable: true)
+      ],
+      data: _getData(9),
+    );
+  }
+ +
+ + +带操作或按钮表格 + + + +
+  Widget _operationBtnTable(BuildContext context) {
+    return TDTable(
+      columns: [
+        TDTableCol(title: '标题', colKey: 'title1', ellipsis: true),
+        TDTableCol(title: '标题', colKey: 'title2'),
+        TDTableCol(title: '标题', colKey: 'title3'),
+        TDTableCol(
+          title: '标题',
+          colKey: 'title4',
+          cellBuilder: (BuildContext context) {
+            return Row(
+              mainAxisAlignment: MainAxisAlignment.spaceBetween,
+              children: [
+                TDText(
+                  '修改',
+                  forceVerticalCenter: true,
+                  style: TextStyle(
+                    color: TDTheme.of(context).brandNormalColor,
+                    fontSize: 14,
+                    height: 1,
+                  ),
+                ),
+                TDText(
+                  '通过',
+                  forceVerticalCenter: true,
+                  style: TextStyle(
+                    color: TDTheme.of(context).brandNormalColor,
+                    fontSize: 14,
+                    height: 1,
+                  ),
+                ),
+              ],
+            );
+          },
+        )
+      ],
+      data: _getData(9),
+    );
+  }
+ +
+ + + + + + +
+  Widget _operationIconTable(BuildContext context) {
+    return TDTable(
+      columns: [
+        TDTableCol(title: '标题', colKey: 'title1', ellipsis: true),
+        TDTableCol(title: '标题', colKey: 'title2'),
+        TDTableCol(title: '标题', colKey: 'title3'),
+        TDTableCol(
+          title: '标题',
+          colKey: 'title4',
+          cellBuilder: (BuildContext context) {
+            return Row(
+              mainAxisAlignment: MainAxisAlignment.spaceBetween,
+              children: [
+                Icon(TDIcons.upload, color: TDTheme.of(context).brandNormalColor, size: 16),
+                Icon(TDIcons.delete, color: TDTheme.of(context).brandNormalColor, size: 16),
+              ],
+            );
+          },
+        )
+      ],
+      data: _getData(9),
+    );
+  }
+ +
+ + +可固定首列表格 + + + +
+  Widget _fixedFirstColTable(BuildContext context) {
+    return TDTable(
+      columns: [
+        TDTableCol(title: '标题', colKey: 'title1'),
+        TDTableCol(title: '标题', colKey: 'title2'),
+        TDTableCol(title: '标题', colKey: 'title3'),
+        TDTableCol(title: '标题', colKey: 'title4', fixed: TDTableColFixed.left),
+      ],
+      data: _getData(10),
+    );
+  }
+ +
+ + +可固定尾列表格 + + + +
+  Widget _fixedEndColTable(BuildContext context) {
+    return TDTable(
+      columns: [
+        TDTableCol(title: '标题', colKey: 'title1'),
+        TDTableCol(title: '标题', colKey: 'title2'),
+        TDTableCol(title: '标题', colKey: 'title3'),
+        TDTableCol(
+          title: '标题',
+          colKey: 'title4',
+          fixed: TDTableColFixed.right,
+          cellBuilder: (BuildContext context) {
+            return Row(
+              mainAxisAlignment: MainAxisAlignment.spaceBetween,
+              children: [
+                TDText(
+                  '修改',
+                  style: TextStyle(
+                    color: TDTheme.of(context).brandNormalColor,
+                    fontSize: 14,
+                  ),
+                ),
+                TDText(
+                  '通过',
+                  style: TextStyle(
+                    color: TDTheme.of(context).brandNormalColor,
+                    fontSize: 14,
+                  ),
+                ),
+              ],
+            );
+          },
+        ),
+      ],
+      data: _getData(10),
+    );
+  }
+ +
+ + +横向平铺可滚动表格 + + + +
+  Widget _horizontalScrollTable(BuildContext context) {
+    return TDTable(
+      columns: [
+        TDTableCol(title: '标题', colKey: 'title1', width: 160),
+        TDTableCol(title: '标题', colKey: 'title2', width: 160),
+        TDTableCol(title: '标题', colKey: 'title3', width: 160),
+      ],
+      data: _getData2(),
+    );
+  }
+ +
+ +### 1 组件样式 + +带斑马纹表格样式 + + + +
+  Widget _stripeTable(BuildContext context) {
+    return TDTable(
+      stripe: true,
+      columns: [
+        TDTableCol(title: '标题', colKey: 'title1', ellipsis: true),
+        TDTableCol(title: '标题', colKey: 'title2'),
+        TDTableCol(title: '标题', colKey: 'title3'),
+        TDTableCol(title: '标题', colKey: 'title4')
+      ],
+      data: _getData(9),
+    );
+  }
+ +
+ + +带边框表格样式 + + + +
+  Widget _borderTable(BuildContext context) {
+    return TDTable(
+      bordered: true,
+      columns: [
+        TDTableCol(title: '标题', colKey: 'title1', ellipsis: true),
+        TDTableCol(title: '标题', colKey: 'title2'),
+        TDTableCol(title: '标题', colKey: 'title3'),
+        TDTableCol(title: '标题', colKey: 'title4')
+      ],
+      data: _getData(9),
+    );
+  }
+ +
+ + + +## API +### TDTable +#### 默认构造方法 + +| 参数 | 类型 | 默认值 | 说明 | +| --- | --- | --- | --- | +| key | | - | | +| bordered | bool? | - | 是否显示表格边框 | +| columns | List | - | 列配置 | +| data | List? | - | 数据源 | +| empty | TDTableEmpty? | - | 空表格呈现样式 | +| height | double? | - | 表格高度,超出后会出现滚动条 | +| loading | bool? | false | 加载中状态 | +| loadingWidget | Widget? | - | 自定义加载中状态 | +| showHeader | bool? | true | 是否显示表头 | +| stripe | bool? | false | 斑马纹 | +| backgroundColor | Color? | - | 表格背景色 | +| width | double? | - | 表格宽度 | +| defaultSort | String? | - | 默认排序 | +| onCellTap | OnCellTap? | - | 单元格点击事件 | +| onScroll | OnScroll? | - | 表格滚动事件 | + + + \ No newline at end of file diff --git a/tdesign-site/src/time-counter/README.md b/tdesign-site/src/time-counter/README.md new file mode 100644 index 000000000..57b976275 --- /dev/null +++ b/tdesign-site/src/time-counter/README.md @@ -0,0 +1,655 @@ +--- +title: TimeCounter 计时器 +description: 用于实时展示计时数值。 +spline: base +isComponent: true +--- + + +## 引入 + +在tdesign_flutter/tdesign_flutter.dart中有所有组件的路径。 + +```dart +import 'package:tdesign_flutter/tdesign_flutter.dart'; +``` + +## 代码演示 + +[td_time-counter_page.dart](https://github.com/Tencent/tdesign-flutter/blob/main/tdesign-component/example/lib/page/td_time-counter_page.dart) + +### 1 组件类型 + +时分秒 + + + + +
+TDTimeCounter _buildSimple(BuildContext context) {
+  return const TDTimeCounter(time: 60 * 60 * 1000);
+}
+ +
+ + +带毫秒 + + + + +
+TDTimeCounter _buildMillisecondSimple(BuildContext context) {
+  return const TDTimeCounter(time: 60 * 60 * 1000, millisecond: true);
+}
+ +
+ + +正向计时 + + + + +
+TDTimeCounter _buildUpSimple(BuildContext context) {
+  return const TDTimeCounter(
+    time: 60 * 60 * 1000,
+    millisecond: true,
+    direction: TDTimeCounterDirection.up,
+  );
+}
+ +
+ + +带方形底 + + + + +
+TDTimeCounter _buildSquareSimple(BuildContext context) {
+  return const TDTimeCounter(time: 60 * 60 * 1000, theme: TDTimeCounterTheme.square);
+}
+ +
+ + +带圆形底 + + + + +
+TDTimeCounter _buildRoundSimple(BuildContext context) {
+  return const TDTimeCounter(time: 60 * 60 * 1000, theme: TDTimeCounterTheme.round);
+}
+ +
+ + +带单位 + + + + +
+TDTimeCounter _buildUnitSimple(BuildContext context) {
+  return const TDTimeCounter(time: 60 * 60 * 1000, theme: TDTimeCounterTheme.square, splitWithUnit: true);
+}
+ +
+ + +无底色带单位 + + + + +
+TDTimeCounter _buildCustomUnitSimple(BuildContext context) {
+  var style = TDTimeCounterStyle.generateStyle(context);
+  style.timeColor = TDTheme.of(context).errorColor6;
+  return TDTimeCounter(time: 60 * 60 * 1000, splitWithUnit: true, style: style);
+}
+ +
+ +### 1 组件尺寸 + +纯数字 + + + + +
+TDTimeCounter _buildSmallSize(BuildContext context) {
+  return const TDTimeCounter(
+    time: 60 * 60 * 1000,
+    size: TDTimeCounterSize.small,
+  );
+}
+ +
+ + + + + +
+TDTimeCounter _buildMediumSize(BuildContext context) {
+  return const TDTimeCounter(
+    time: 60 * 60 * 1000,
+    size: TDTimeCounterSize.medium,
+  );
+}
+ +
+ + + + + +
+TDTimeCounter _buildLargeSize(BuildContext context) {
+  return const TDTimeCounter(
+    time: 60 * 60 * 1000,
+    size: TDTimeCounterSize.large,
+  );
+}
+ +
+ + + + + +
+TDTimeCounter _buildSmallSize(BuildContext context) {
+  return const TDTimeCounter(
+    time: 60 * 60 * 1000,
+    size: TDTimeCounterSize.small,
+  );
+}
+ +
+ + + + + +
+TDTimeCounter _buildMediumSize(BuildContext context) {
+  return const TDTimeCounter(
+    time: 60 * 60 * 1000,
+    size: TDTimeCounterSize.medium,
+  );
+}
+ +
+ + + + + +
+TDTimeCounter _buildLargeSize(BuildContext context) {
+  return const TDTimeCounter(
+    time: 60 * 60 * 1000,
+    size: TDTimeCounterSize.large,
+  );
+}
+ +
+ + +带方形底 + + + + +
+TDTimeCounter _buildSquareSmallSize(BuildContext context) {
+  return const TDTimeCounter(
+    time: 60 * 60 * 1000,
+    size: TDTimeCounterSize.small,
+    theme: TDTimeCounterTheme.square,
+  );
+}
+ +
+ + + + + +
+TDTimeCounter _buildSquareMediumSize(BuildContext context) {
+  return const TDTimeCounter(
+    time: 60 * 60 * 1000,
+    size: TDTimeCounterSize.medium,
+    theme: TDTimeCounterTheme.square,
+  );
+}
+ +
+ + + + + +
+TDTimeCounter _buildSquareLargeSize(BuildContext context) {
+  return const TDTimeCounter(
+    time: 60 * 60 * 1000,
+    size: TDTimeCounterSize.large,
+    theme: TDTimeCounterTheme.square,
+  );
+}
+ +
+ + + + + +
+TDTimeCounter _buildSquareSmallSize(BuildContext context) {
+  return const TDTimeCounter(
+    time: 60 * 60 * 1000,
+    size: TDTimeCounterSize.small,
+    theme: TDTimeCounterTheme.square,
+  );
+}
+ +
+ + + + + +
+TDTimeCounter _buildSquareMediumSize(BuildContext context) {
+  return const TDTimeCounter(
+    time: 60 * 60 * 1000,
+    size: TDTimeCounterSize.medium,
+    theme: TDTimeCounterTheme.square,
+  );
+}
+ +
+ + + + + +
+TDTimeCounter _buildSquareLargeSize(BuildContext context) {
+  return const TDTimeCounter(
+    time: 60 * 60 * 1000,
+    size: TDTimeCounterSize.large,
+    theme: TDTimeCounterTheme.square,
+  );
+}
+ +
+ + +带圆形底 + + + + +
+TDTimeCounter _buildRoundSmallSize(BuildContext context) {
+  return const TDTimeCounter(
+    time: 60 * 60 * 1000,
+    size: TDTimeCounterSize.small,
+    theme: TDTimeCounterTheme.round,
+  );
+}
+ +
+ + + + + +
+TDTimeCounter _buildRoundMediumSize(BuildContext context) {
+  return const TDTimeCounter(
+    time: 60 * 60 * 1000,
+    size: TDTimeCounterSize.medium,
+    theme: TDTimeCounterTheme.round,
+  );
+}
+ +
+ + + + + +
+TDTimeCounter _buildRoundLargeSize(BuildContext context) {
+  return const TDTimeCounter(
+    time: 60 * 60 * 1000,
+    size: TDTimeCounterSize.large,
+    theme: TDTimeCounterTheme.round,
+  );
+}
+ +
+ + + + + +
+TDTimeCounter _buildRoundSmallSize(BuildContext context) {
+  return const TDTimeCounter(
+    time: 60 * 60 * 1000,
+    size: TDTimeCounterSize.small,
+    theme: TDTimeCounterTheme.round,
+  );
+}
+ +
+ + + + + +
+TDTimeCounter _buildRoundMediumSize(BuildContext context) {
+  return const TDTimeCounter(
+    time: 60 * 60 * 1000,
+    size: TDTimeCounterSize.medium,
+    theme: TDTimeCounterTheme.round,
+  );
+}
+ +
+ + + + + +
+TDTimeCounter _buildRoundLargeSize(BuildContext context) {
+  return const TDTimeCounter(
+    time: 60 * 60 * 1000,
+    size: TDTimeCounterSize.large,
+    theme: TDTimeCounterTheme.round,
+  );
+}
+ +
+ + +带单位 + + + + +
+TDTimeCounter _buildUnitSmallSize(BuildContext context) {
+  return const TDTimeCounter(
+    time: 60 * 60 * 1000,
+    size: TDTimeCounterSize.small,
+    theme: TDTimeCounterTheme.square,
+    splitWithUnit: true,
+  );
+}
+ +
+ + + + + +
+TDTimeCounter _buildUnitMediumSize(BuildContext context) {
+  return const TDTimeCounter(
+    time: 60 * 60 * 1000,
+    size: TDTimeCounterSize.medium,
+    theme: TDTimeCounterTheme.square,
+    splitWithUnit: true,
+  );
+}
+ +
+ + + + + +
+TDTimeCounter _buildUnitLargeSize(BuildContext context) {
+  return const TDTimeCounter(
+    time: 60 * 60 * 1000,
+    size: TDTimeCounterSize.large,
+    theme: TDTimeCounterTheme.square,
+    splitWithUnit: true,
+  );
+}
+ +
+ + + + + +
+TDTimeCounter _buildUnitSmallSize(BuildContext context) {
+  return const TDTimeCounter(
+    time: 60 * 60 * 1000,
+    size: TDTimeCounterSize.small,
+    theme: TDTimeCounterTheme.square,
+    splitWithUnit: true,
+  );
+}
+ +
+ + + + + +
+TDTimeCounter _buildUnitMediumSize(BuildContext context) {
+  return const TDTimeCounter(
+    time: 60 * 60 * 1000,
+    size: TDTimeCounterSize.medium,
+    theme: TDTimeCounterTheme.square,
+    splitWithUnit: true,
+  );
+}
+ +
+ + + + + +
+TDTimeCounter _buildUnitLargeSize(BuildContext context) {
+  return const TDTimeCounter(
+    time: 60 * 60 * 1000,
+    size: TDTimeCounterSize.large,
+    theme: TDTimeCounterTheme.square,
+    splitWithUnit: true,
+  );
+}
+ +
+ + +无底色带单位 + + + + +
+TDTimeCounter _buildCustomUnitSmallSize(BuildContext context) {
+  var style = TDTimeCounterStyle.generateStyle(context, size: TDTimeCounterSize.small);
+  style.timeColor = TDTheme.of(context).errorColor6;
+  return TDTimeCounter(
+    time: 60 * 60 * 1000,
+    splitWithUnit: true,
+    style: style,
+  );
+}
+ +
+ + + + + +
+TDTimeCounter _buildCustomUnitMediumSize(BuildContext context) {
+  var style = TDTimeCounterStyle.generateStyle(context, size: TDTimeCounterSize.medium);
+  style.timeColor = TDTheme.of(context).errorColor6;
+  return TDTimeCounter(
+    time: 60 * 60 * 1000,
+    splitWithUnit: true,
+    style: style,
+  );
+}
+ +
+ + + + + +
+TDTimeCounter _buildCustomUnitLargeSize(BuildContext context) {
+  var style = TDTimeCounterStyle.generateStyle(context, size: TDTimeCounterSize.large);
+  style.timeColor = TDTheme.of(context).errorColor6;
+  return TDTimeCounter(
+    time: 60 * 60 * 1000,
+    splitWithUnit: true,
+    style: style,
+  );
+}
+ +
+ + + + + +
+TDTimeCounter _buildCustomUnitSmallSize(BuildContext context) {
+  var style = TDTimeCounterStyle.generateStyle(context, size: TDTimeCounterSize.small);
+  style.timeColor = TDTheme.of(context).errorColor6;
+  return TDTimeCounter(
+    time: 60 * 60 * 1000,
+    splitWithUnit: true,
+    style: style,
+  );
+}
+ +
+ + + + + +
+TDTimeCounter _buildCustomUnitMediumSize(BuildContext context) {
+  var style = TDTimeCounterStyle.generateStyle(context, size: TDTimeCounterSize.medium);
+  style.timeColor = TDTheme.of(context).errorColor6;
+  return TDTimeCounter(
+    time: 60 * 60 * 1000,
+    splitWithUnit: true,
+    style: style,
+  );
+}
+ +
+ + + + + +
+TDTimeCounter _buildCustomUnitLargeSize(BuildContext context) {
+  var style = TDTimeCounterStyle.generateStyle(context, size: TDTimeCounterSize.large);
+  style.timeColor = TDTheme.of(context).errorColor6;
+  return TDTimeCounter(
+    time: 60 * 60 * 1000,
+    splitWithUnit: true,
+    style: style,
+  );
+}
+ +
+ + + +## API +### TDTimeCounter +#### 简介 +计时组件 +#### 默认构造方法 + +| 参数 | 类型 | 默认值 | 说明 | +| --- | --- | --- | --- | +| key | | - | | +| autoStart | bool | true | 是否自动开始倒计时 | +| content | dynamic | 'default' | 'default' / Widget Function(int time) / Widget | +| format | String | 'HH:mm:ss' | 时间格式,DD-日,HH-时,mm-分,ss-秒,SSS-毫秒(分隔符必须为长度为1的非空格的字符) | +| millisecond | bool | false | 是否开启毫秒级渲染 | +| size | TDTimeCounterSize | TDTimeCounterSize.medium | 尺寸 | +| splitWithUnit | bool | false | 使用时间单位分割 | +| theme | TDTimeCounterTheme | TDTimeCounterTheme.defaultTheme | 风格 | +| time | int | - | 必需;计时时长,单位毫秒 | +| style | TDTimeCounterStyle? | - | 自定义样式,有则优先用它,没有则根据size和theme选取 | +| onChange | Function(int time)? | - | 时间变化时触发回调 | +| onFinish | VoidCallback? | - | 计时结束时触发回调 | +| direction | TDTimeCounterDirection | TDTimeCounterDirection.down | 计时方向,默认倒计时 | +| controller | TDTimeCounterController? | - | 控制器,可控制开始/暂停/继续/重置 | + +``` +``` + ### TDTimeCounterStyle +#### 简介 +计时组件样式 +#### 默认构造方法 + +| 参数 | 类型 | 默认值 | 说明 | +| --- | --- | --- | --- | +| timeWidth | double? | - | 时间容器宽度 | +| timeHeight | double? | - | 时间容器高度 | +| timePadding | EdgeInsets? | - | 时间容器内边距 | +| timeMargin | EdgeInsets? | - | 时间容器外边距 | +| timeBox | BoxDecoration? | - | 时间容器装饰 | +| timeFontFamily | FontFamily? | - | 时间字体 | +| timeFontSize | double? | - | 时间字体尺寸 | +| timeFontHeight | double? | - | 时间字体行高 | +| timeFontWeight | FontWeight? | - | 时间字体粗细 | +| timeColor | Color? | - | 时间字体颜色 | +| splitFontSize | double? | - | 分隔符字体尺寸 | +| splitFontHeight | double? | - | 分隔符字体行高 | +| splitFontWeight | FontWeight? | - | 分隔符字体粗细 | +| splitColor | Color? | - | 分隔符字体颜色 | +| space | double? | - | 时间与分隔符的间隔 | + + +#### 工厂构造方法 + +| 名称 | 说明 | +| --- | --- | +| TDTimeCounterStyle.generateStyle | 生成默认样式 | + +``` +``` + ### TDTimeCounterController +#### 简介 +倒计时组件控制器,可控制开始(`start()`)/暂停(`pause()`)/继续(`resume()`)/重置(`reset([int? time])`) + + \ No newline at end of file diff --git a/tdesign-site/src/toast/README.md b/tdesign-site/src/toast/README.md index 4951b78e5..4d36098d0 100644 --- a/tdesign-site/src/toast/README.md +++ b/tdesign-site/src/toast/README.md @@ -309,13 +309,13 @@ import 'package:tdesign_flutter/tdesign_flutter.dart'; | 名称 | 返回类型 | 参数 | 说明 | | --- | --- | --- | --- | -| showText | | required String? text, required BuildContext context, Duration duration, int? maxLines, BoxConstraints? constraints, | 普通文本Toast | -| showIconText | | required String? text, IconData? icon, IconTextDirection direction, required BuildContext context, Duration duration, | 带图标的Toast | -| showSuccess | | required String? text, IconTextDirection direction, required BuildContext context, Duration duration, | 成功提示Toast | -| showWarning | | required String? text, IconTextDirection direction, required BuildContext context, Duration duration, | 警告Toast | -| showFail | | required String? text, IconTextDirection direction, required BuildContext context, Duration duration, | 失败提示Toast | -| showLoading | | required BuildContext context, String? text, Duration duration, | 带文案的加载Toast | -| showLoadingWithoutText | | required BuildContext context, String? text, Duration duration, | 不带文案的加载Toast | +| showText | | required String? text, required BuildContext context, Duration duration, int? maxLines, BoxConstraints? constraints, bool? preventTap, | 普通文本Toast | +| showIconText | | required String? text, IconData? icon, IconTextDirection direction, required BuildContext context, Duration duration, bool? preventTap, | 带图标的Toast | +| showSuccess | | required String? text, IconTextDirection direction, required BuildContext context, Duration duration, bool? preventTap, | 成功提示Toast | +| showWarning | | required String? text, IconTextDirection direction, required BuildContext context, Duration duration, bool? preventTap, | 警告Toast | +| showFail | | required String? text, IconTextDirection direction, required BuildContext context, Duration duration, bool? preventTap, | 失败提示Toast | +| showLoading | | required BuildContext context, String? text, Duration duration, bool? preventTap, | 带文案的加载Toast | +| showLoadingWithoutText | | required BuildContext context, String? text, Duration duration, bool? preventTap, | 不带文案的加载Toast | | dismissLoading | | | 关闭加载Toast | From bbe8471ebafe2c0130d04085cbc63d9f30087ff6 Mon Sep 17 00:00:00 2001 From: Luozf12345 <2515187986@qq.com> Date: Sun, 13 Oct 2024 16:26:10 +0800 Subject: [PATCH 24/46] update override --- tdesign-site/site/docs/overview.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/tdesign-site/site/docs/overview.md b/tdesign-site/site/docs/overview.md index a0ca0a670..1da453b81 100644 --- a/tdesign-site/site/docs/overview.md +++ b/tdesign-site/site/docs/overview.md @@ -79,13 +79,13 @@ spline: explain

Drawer 抽屉

- + + --> -
+ +
-->
From 9022043b5f5e290fe3cd12a532dc5d95c25887fd Mon Sep 17 00:00:00 2001 From: hkaikai <617760820@qq.com> Date: Mon, 14 Oct 2024 15:31:36 +0800 Subject: [PATCH 25/46] =?UTF-8?q?demo=20=E6=96=87=E6=A1=88=E8=B0=83?= =?UTF-8?q?=E6=95=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tdesign-component/example/lib/page/td_rate_page.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tdesign-component/example/lib/page/td_rate_page.dart b/tdesign-component/example/lib/page/td_rate_page.dart index 8ae35dd81..968562299 100644 --- a/tdesign-component/example/lib/page/td_rate_page.dart +++ b/tdesign-component/example/lib/page/td_rate_page.dart @@ -74,7 +74,7 @@ class TDRatePageState extends State { @Demo(group: 'rate') Widget _buildMsgRate(BuildContext context) { return Column(children: const [ - TDCell(title: '带描述评分', noteWidget: TDRate(value: 3, showText: true, texts: ['很差', '差', '一般', '好评', '优秀'])), + TDCell(title: '带描述评分', noteWidget: TDRate(value: 3, showText: true, texts: ['1分', '2分', '3分', '4分', '5分'])), SizedBox(height: 16), TDCell(title: '带描述评分', noteWidget: TDRate(value: 3, showText: true)) ]); From 4215751828435216d4711ba9cdf5e98ae81d1d64 Mon Sep 17 00:00:00 2001 From: Simon_Wzy <1691663479@qq.com> Date: Mon, 14 Oct 2024 19:04:44 +0800 Subject: [PATCH 26/46] =?UTF-8?q?=E5=AE=8C=E5=96=84=20Form=20=E7=9A=84?= =?UTF-8?q?=E7=AB=96=E7=9B=B4UI=20=E7=A6=81=E7=94=A8=E6=80=81=20=E6=8F=90?= =?UTF-8?q?=E4=BA=A4=E9=87=8D=E7=BD=AE=E6=8C=89=E9=92=AE=20TODO:=20?= =?UTF-8?q?=E6=8F=90=E4=BA=A4=E9=80=BB=E8=BE=91=20=E9=87=8D=E7=BD=AE?= =?UTF-8?q?=E9=80=BB=E8=BE=91=20Problem:=20TDTextare=20=E8=83=8C=E6=99=AF?= =?UTF-8?q?=E9=A2=9C=E8=89=B2=E9=97=AE=E9=A2=98=20TDRadioGroup=20=E9=AB=98?= =?UTF-8?q?=E5=BA=A6=E9=97=AE=E9=A2=98=20TDInput=20=E7=AB=96=E7=9B=B4?= =?UTF-8?q?=E6=80=81=20additionInfo=20=E4=B8=8D=E6=98=BE=E7=A4=BA=E9=97=AE?= =?UTF-8?q?=E9=A2=98=20=E7=AB=96=E7=9B=B4=E6=80=81=E6=96=87=E5=AD=97?= =?UTF-8?q?=E5=AF=B9=E9=BD=90=20padding=20=E9=97=AE=E9=A2=98=20=E7=BB=84?= =?UTF-8?q?=E7=9B=B8=E8=BF=9E=E9=80=89=E6=8B=A9=E5=99=A8=20=20=E6=97=B6?= =?UTF-8?q?=E9=97=B4=E9=80=89=E6=8B=A9=E5=99=A8=20=E6=B2=A1=E6=9C=89=20?= =?UTF-8?q?=E7=A6=81=E7=94=A8=E6=80=81=20=E7=AB=96=E7=9B=B4=E6=80=81?= =?UTF-8?q?=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../example/lib/page/td_button_page.dart | 7 +- .../example/lib/page/td_form_page.dart | 198 +++-- .../example/lib/page/td_input_page.dart | 11 +- .../lib/src/components/form/td_form.dart | 12 +- .../components/form/td_form_inherited.dart | 23 +- .../lib/src/components/form/td_form_item.dart | 678 ++++++++++++------ 6 files changed, 613 insertions(+), 316 deletions(-) diff --git a/tdesign-component/example/lib/page/td_button_page.dart b/tdesign-component/example/lib/page/td_button_page.dart index 6c539e7f0..7c31b9983 100644 --- a/tdesign-component/example/lib/page/td_button_page.dart +++ b/tdesign-component/example/lib/page/td_button_page.dart @@ -382,14 +382,15 @@ class _TDButtonPageState extends State { ExampleItem( ignoreCode: true, desc: '按钮中路由跳转', - builder: (context){ + builder: (context) { return TDButton( text: '点击跳转', size: TDButtonSize.large, // type: TDButtonType.text, shape: TDButtonShape.rectangle, - onTap: () async{ - var result = await Navigator.of(context).pushNamedAndRemoveUntil('divider',(router){ + onTap: () async { + var result = await Navigator.of(context) + .pushNamedAndRemoveUntil('divider', (router) { return true; }); print('pushNamedAndRemoveUntil result: $result'); diff --git a/tdesign-component/example/lib/page/td_form_page.dart b/tdesign-component/example/lib/page/td_form_page.dart index f99a34cdd..58f1fd078 100644 --- a/tdesign-component/example/lib/page/td_form_page.dart +++ b/tdesign-component/example/lib/page/td_form_page.dart @@ -15,6 +15,12 @@ class _TDFormPageState extends State { var controller = []; String selected_1 = ''; + /// form 禁用的状态 + bool _formDisableState = false; + + /// form 排列方式是否为水平 + bool _isFormHorizontal = true; + /// 设置按钮是否可点击状态 /// true 表示处于 active 状态 bool horizontalButton = false; @@ -112,80 +118,88 @@ class _TDFormPageState extends State { @override Widget build(BuildContext context) { return ExamplePage( - title: tdTitle(), - exampleCodeGroup: 'form', - desc: '基础表单', - backgroundColor: const Color(0xfff6f6f6), - children: [ - ExampleModule(title: '基础类型', children: [ - ExampleItem(desc: '基础表单', builder: _buildArrangementSwitch), - ExampleItem(desc: '', builder: _buildSwitchWithBase), - ExampleItem(builder: (BuildContext context) { - return CodeWrapper(builder: _buildForm); - }) - ]), - ]); + title: tdTitle(), + exampleCodeGroup: 'form', + desc: '基础表单', + backgroundColor: const Color(0xfff6f6f6), + children: [ + ExampleModule(title: '基础类型', children: [ + ExampleItem(desc: '基础表单', builder: _buildArrangementSwitch), + ExampleItem(desc: '', builder: _buildSwitchWithBase), + ExampleItem(builder: (BuildContext context) { + return CodeWrapper(builder: _buildForm); + }), + ExampleItem( + ignoreCode: true, + desc: '', + builder: (_) => CodeWrapper(builder: _buildCombinationButtons)), + ]), + ], + ); } @Demo(group: 'form') Widget _buildForm(BuildContext context) { - return TDForm(items: [ - TDFormItem( - label: '用户名', - name: 'name', - help: '请输入用户名', - additionInfo: '输入用户名', - inputPadding: 15.0, - controller: controller[0], - ), - TDFormItem( - label: '密码', - name: 'password', - help: '请输入密码', - inputPadding: 35.0, - controller: controller[1], - ), - TDFormItem( - label: '性别', - name: 'radios', + return TDForm( + disabled: _formDisableState, + isHoeizontal: _isFormHorizontal, + items: [ + TDFormItem( + label: '用户名', + name: 'name', + help: '请输入用户名', + additionInfo: '输入用户名', + labelWidth: 15.0, + controller: controller[0], + ), + TDFormItem( + label: '密码', + name: 'password', + help: '请输入密码', + labelWidth: 35.0, + controller: controller[1], + ), + TDFormItem( + label: '性别', + name: 'radios', - /// 扩展一下数量和选项内容 - radios: _radios, - ), - TDFormItem( - label: '生日', - name: 'date', + /// 扩展一下数量和选项内容 + radios: _radios, + ), + TDFormItem( + label: '生日', + name: 'date', - /// 引入需要的日期数据 - select: selected_1, - ), - TDFormItem( - label: '籍贯', - name: 'local', + /// 引入需要的日期数据 + select: selected_1, + ), + TDFormItem( + label: '籍贯', + name: 'local', - /// 引入需要的地点数据 - localData: _data, - ), - TDFormItem( - label: '年限', - name: 'age', + /// 引入需要的地点数据 + localData: _data, + ), + TDFormItem( + label: '年限', + name: 'stepper', - /// 为 TDStepper 预留其他设置 - ), - TDFormItem( - label: '个人简介', - name: 'textarea', - help: '请输入个人简介', - controller: controller[2], + /// 为 TDStepper 预留其他设置 + ), + TDFormItem( + label: '个人简介', + name: 'textarea', + help: '请输入个人简介', + controller: controller[2], - /// 为 TDTextarea 长文本其他参数做预留 API - maxLength: 500, - indicator: true, - ) - ], disabled: false); + /// 为 TDTextarea 长文本其他参数做预留 API + maxLength: 500, + indicator: true, + ) + ]); } - /// 横 竖 排版模式切换 + /// 横 竖 排版模式切换按钮 @Demo(group: 'form') Widget _buildArrangementSwitch(BuildContext buildContext) { final theme = TDTheme.of(context); @@ -223,6 +237,8 @@ class _TDFormPageState extends State { final currentTextColor = verticalTextColor; verticalTextColor = horizontalTextColor; horizontalTextColor = currentTextColor; + _isFormHorizontal = true; + print(_isFormHorizontal); } }); }, @@ -254,6 +270,9 @@ class _TDFormPageState extends State { final currentTextColor = verticalTextColor; verticalTextColor = horizontalTextColor; horizontalTextColor = currentTextColor; + + _isFormHorizontal = false; + print(_isFormHorizontal); } }); }, @@ -267,12 +286,19 @@ class _TDFormPageState extends State { Widget _buildSwitchWithBase(BuildContext context) { return _buildItem( context, - const TDSwitch(), + TDSwitch( + isOn: _formDisableState, + onChanged: (value) { + setState(() { + _formDisableState = value; + }); + return false; + }, + ), title: '禁用态', ); } - /// 每一项的封装 @Demo(group: 'switch') Widget _buildItem(BuildContext context, Widget switchItem, {String? title, String? desc}) { @@ -306,4 +332,46 @@ class _TDFormPageState extends State { ); return Column(mainAxisSize: MainAxisSize.min, children: [current]); } + + /// 提交按钮 + @Demo(group: 'button') + Widget _buildCombinationButtons(BuildContext context) { + final theme = TDTheme.of(context); + return Container( + decoration: BoxDecoration( + color: theme.whiteColor1, + ), + child: Padding( + padding: const EdgeInsets.all(16), + child: Row( + children: [ + SizedBox( + width: 16, + ), + Expanded( + child: TDButton( + text: '提交', + size: TDButtonSize.large, + type: TDButtonType.fill, + theme: TDButtonTheme.primary, + shape: TDButtonShape.rectangle, + )), + SizedBox( + width: 16, + ), + Expanded( + child: TDButton( + text: '重置', + size: TDButtonSize.large, + type: TDButtonType.fill, + shape: TDButtonShape.rectangle, + theme: TDButtonTheme.defaultTheme, + )), + SizedBox( + width: 16, + ), + ], + )), + ); + } } diff --git a/tdesign-component/example/lib/page/td_input_page.dart b/tdesign-component/example/lib/page/td_input_page.dart index 77c65bb5d..6d85ea198 100644 --- a/tdesign-component/example/lib/page/td_input_page.dart +++ b/tdesign-component/example/lib/page/td_input_page.dart @@ -72,7 +72,8 @@ class _TDInputViewPageState extends State { ExampleItem(desc: '带操作输入框', builder: _basicTypeWithHandleIconOne), ExampleItem(builder: _basicTypeWithHandleIconTwo), ExampleItem(builder: _basicTypeWithHandleIconThree), - ExampleItem(desc: '带图标输入框', builder: _basicTypeWithLeftIconLeftLabel), + ExampleItem( + desc: '带图标输入框', builder: _basicTypeWithLeftIconLeftLabel), ExampleItem(builder: _basicTypeWithLeftIcon), ExampleItem(desc: '特定类型输入框', builder: _specialTypePassword), ExampleItem(builder: _specialTypeVerifyCode), @@ -104,7 +105,8 @@ class _TDInputViewPageState extends State { ExampleItem(desc: '长文本样式', builder: _customLongTextStyle), ExampleItem(desc: '隐藏底部分割线', builder: _hideBottomDivider), ExampleItem(desc: '自定义高度-使用SizeBox', builder: _customHeight), - ExampleItem(desc: '获取焦点时点击外部区域事件响应-onTapOutside', builder: _onTapOutside) + ExampleItem( + desc: '获取焦点时点击外部区域事件响应-onTapOutside', builder: _onTapOutside) ], ); } @@ -138,7 +140,7 @@ class _TDInputViewPageState extends State { return Column( children: [ TDInput( - leftLabel: '标签文字', + leftLabel: '标签文字123', required: true, controller: controller[1], backgroundColor: Colors.white, @@ -513,7 +515,8 @@ class _TDInputViewPageState extends State { '${countDownText}(${_countdownTime}秒)', textColor: TDTheme.of(context).fontGyColor4, ) - : TDText(confirmText, textColor: TDTheme.of(context).brandNormalColor), + : TDText(confirmText, + textColor: TDTheme.of(context).brandNormalColor), ], ), ), diff --git a/tdesign-component/lib/src/components/form/td_form.dart b/tdesign-component/lib/src/components/form/td_form.dart index 4c7c40436..c6727fbf0 100644 --- a/tdesign-component/lib/src/components/form/td_form.dart +++ b/tdesign-component/lib/src/components/form/td_form.dart @@ -9,10 +9,11 @@ class TDForm extends StatefulWidget { this.colon = false, this.contentAlign = 'left', this.data, + this.isHoeizontal = true, this.disabled = false, this.errorMessage, this.labelAlign = 'right', - this.labelWidth = '81px', + this.labelWidth = 20.0, this.preventSubmitDefault = true, this.requiredMark = true, // 此处必填项有小问题 this.resetType = 'empty', @@ -35,6 +36,9 @@ class TDForm extends StatefulWidget { /// 表单数据 final Object? data; + /// 表单排列方式是否为 水平方向 + final bool isHoeizontal; + /// 是否禁用整个表单 final bool disabled; @@ -46,8 +50,8 @@ class TDForm extends StatefulWidget { /// 可选项: left/right/top final String? labelAlign; - /// 可以整体设置 label 标签宽度,默认为 81px - final String? labelWidth; + /// 可以整体设置 label 标签宽度 + final double? labelWidth; /// 是否阻止表单提交默认事件(表单提交默认事件会刷新页面) /// 设置为 true 可以避免刷新 @@ -83,6 +87,8 @@ class _TDFormState extends State { Widget build(BuildContext context) { return TDFormInherited( disabled: widget.disabled, + labelWidth: widget.labelWidth, + isHorizontal: widget.isHoeizontal, child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: widget.items diff --git a/tdesign-component/lib/src/components/form/td_form_inherited.dart b/tdesign-component/lib/src/components/form/td_form_inherited.dart index ac6c102dd..86be39ee9 100644 --- a/tdesign-component/lib/src/components/form/td_form_inherited.dart +++ b/tdesign-component/lib/src/components/form/td_form_inherited.dart @@ -1,18 +1,25 @@ import 'package:flutter/cupertino.dart'; class TDFormInherited extends InheritedWidget { - const TDFormInherited( - {required Widget child, required this.disabled, Key? key}) - : super(child: child, key: key); - final bool disabled; + final double? labelWidth; + final bool isHorizontal; - @override - bool updateShouldNotify(covariant TDFormInherited oldWidget) { - return true; - } + const TDFormInherited({ + required Widget child, + required this.disabled, + required this.isHorizontal, + this.labelWidth, + }) : super(child: child); static TDFormInherited? of(BuildContext context) { return context.dependOnInheritedWidgetOfExactType(); } + + @override + bool updateShouldNotify(TDFormInherited oldWidget) { + return disabled != oldWidget.disabled || + labelWidth != oldWidget.labelWidth || + isHorizontal != oldWidget.isHorizontal; + } } diff --git a/tdesign-component/lib/src/components/form/td_form_item.dart b/tdesign-component/lib/src/components/form/td_form_item.dart index 3314b8b83..7aa7b631e 100644 --- a/tdesign-component/lib/src/components/form/td_form_item.dart +++ b/tdesign-component/lib/src/components/form/td_form_item.dart @@ -1,9 +1,10 @@ import 'package:flutter/material.dart'; +import 'package:tdesign_flutter/src/components/form/td_form_inherited.dart'; import '../../../tdesign_flutter.dart'; class TDFormItem extends StatefulWidget { TDFormItem({ - /// 需要从 page 外部传入的参数 + // External parameters this.controller, this.select = '', List? localData, @@ -21,70 +22,57 @@ class TDFormItem extends StatefulWidget { this.maxLength, this.indicator, this.additionInfo, - this.inputPadding = 10.0, Key? key, }) : localData = localData ?? const [], radios = radios ?? const {}, super(key: key); - /// 表格内标签 内容填充 + // Form label content final String? label; - /// 表单内容对齐方式: - /// 左对齐、右对齐 - /// 可选项:left/right + // Form content alignment: 'left' or 'right' final String? contentAlign; - /// 是否显示右箭头 + // Whether to show the right arrow final bool? arrow; - /// TDInput 框的辅助说明文字 + // Auxiliary information for TDInput final String? additionInfo; - /// 表单说明内容 - /// 表单的默认输入字符 + // Help text for the form field final String? help; - /// input 框默认文本的左侧 padding - final double inputPadding; - - /// 表单字段标签对齐方式: - /// 左对齐、右对齐、顶部对齐 - /// 默认使用 Form 的对齐方式,其优先级高于 Form.labelAlign - /// 可选项: left/right.top + // Label alignment: 'left', 'right', or 'top' final String? labelAlign; - /// 可以整体调整标签宽度 - /// 优先级高于 Form.labelWidth - final String? labelWidth; + // Label width, overrides the Form's labelWidth if provided + final double? labelWidth; - /// 表格标识 + // Form field identifier final String? name; - /// 表格的 controller + // Controller for the form field var controller; - /// 日期选择需要展示的内容 + // Selected value for date picker or similar String select; - /// 组相联选择器需要的数据 + // Data for cascader or other selection widgets final List localData; - /// 单选框数据 + // Data for radio buttons final Map radios; - /// 是否显示必填符号 (*) - /// 优先级高于 Form.requiredMark + // Whether to display the required mark (*) final bool? requiredMark; - /// 表单字段校验规则 + // Validation rules for the form field final List? rules; - /// 校验不通过时,是否显示错误提示信息 - /// 优先级高于 Form.showErrowMessage + // Whether to show error messages final bool? showErrowMessage; - /// TDTextarea 预留API + // Properties for TDTextarea final int? maxLength; final bool? indicator; @@ -92,134 +80,304 @@ class TDFormItem extends StatefulWidget { _TDFormItemState createState() => _TDFormItemState(); } -Widget buildSelectRow(BuildContext context, String output, String title) { - return Container( - color: TDTheme.of(context).whiteColor1, - height: 56, - child: Stack( - alignment: Alignment.bottomCenter, - children: [ - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Padding( - padding: const EdgeInsets.only(left: 16, top: 16, bottom: 16), - child: TDText( - title, - font: TDTheme.of(context).fontBodyLarge, - ), - ), - Padding( - padding: const EdgeInsets.only(right: 16), - child: Row( - children: [ - TDText( - output, - font: TDTheme.of(context).fontBodyLarge, - textColor: - TDTheme.of(context).fontGyColor3.withOpacity(0.4), - ), - Padding( - padding: const EdgeInsets.only(left: 2), - child: Icon( - TDIcons.chevron_right, - color: TDTheme.of(context).fontGyColor3.withOpacity(0.4), - ), - ), - ], - ), - ), - ], - ), - const TDDivider( - margin: EdgeInsets.only( - left: 16, - ), - ) - ], - ), - ); -} - class _TDFormItemState extends State { - /// 实现密码右侧的可见按钮 + double get LabelWidth { + final inherited = TDFormInherited.of(context); + final double defaultLabelWidth = 8.0; // Default label width + + // 优先使用 widget.labelWidth,如果不为空直接返回 + if (widget.labelWidth != null) { + return widget.labelWidth as double; + } + + // 如果 widget.labelWidth 为空,使用 inherited.labelWidth + if (inherited?.labelWidth != null) { + return inherited!.labelWidth as double; + } + + // 如果两者都为空,返回默认值 + return defaultLabelWidth; + } + + bool get FormState { + final inherited = TDFormInherited.of(context); + if (inherited?.disabled != null) { + return inherited!.disabled; + } + return false; + } + + bool get FormIsHorizontal { + final inherited = TDFormInherited.of(context); + if (inherited?.isHorizontal != null) { + return inherited!.isHorizontal; + } + return false; + } + bool browseOn = false; - /// 垂直联级选择器 String? _initData; String _selected_1 = ''; @override Widget build(BuildContext context) { - if (widget.name == 'name') { - return Column( - children: [ - TDInput( - inputDecoration: InputDecoration( - hintText: widget.help, - contentPadding: - EdgeInsets.only(left: widget.inputPadding), // 左侧内边距20像素 - border: InputBorder.none, - ), - leftLabel: widget.label, - controller: widget.controller, - backgroundColor: Colors.white, - additionInfo: widget.additionInfo, + if (FormIsHorizontal) { + if (widget.name == 'name') { + return TDInput( + inputDecoration: InputDecoration( + hintText: widget.help, + contentPadding: EdgeInsets.only(left: LabelWidth), + border: InputBorder.none, ), - ], - ); - } else if (widget.name == 'password') { - return Column( - children: [ - TDInput( - inputDecoration: InputDecoration( - hintText: widget.help, - contentPadding: - EdgeInsets.only(left: widget.inputPadding), // 左侧内边距20像素 - border: InputBorder.none, - ), - type: TDInputType.normal, - controller: widget.controller, - obscureText: !browseOn, - leftLabel: widget.label, - backgroundColor: Colors.white, - rightBtn: browseOn - ? Icon( - TDIcons.browse, - color: TDTheme.of(context).fontGyColor3, - ) - : Icon( - TDIcons.browse_off, - color: TDTheme.of(context).fontGyColor3, + leftLabel: widget.label, + controller: widget.controller, + backgroundColor: Colors.white, + additionInfo: widget.additionInfo, + readOnly: FormState, + ); + } else if (widget.name == 'password') { + return TDInput( + inputDecoration: InputDecoration( + hintText: widget.help, + contentPadding: EdgeInsets.only(left: LabelWidth), + border: InputBorder.none, + ), + type: TDInputType.normal, + controller: widget.controller, + obscureText: !browseOn, + leftLabel: widget.label, + backgroundColor: Colors.white, + rightBtn: browseOn + ? Icon( + TDIcons.browse, + color: TDTheme.of(context).fontGyColor3, + ) + : Icon( + TDIcons.browse_off, + color: TDTheme.of(context).fontGyColor3, + ), + onBtnTap: () { + setState(() { + browseOn = !browseOn; + }); + }, + needClear: false, + readOnly: FormState, + ); + } else if (widget.name == 'radios') { + final theme = TDTheme.of(context); + return Container( + decoration: BoxDecoration( + color: theme.whiteColor1, + ), + child: Padding( + padding: EdgeInsets.all(16), + child: Row( + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + TDText( + widget.label ?? '', + style: const TextStyle(fontSize: 16), + ), + const SizedBox(width: 16), + Expanded( + child: TDRadioGroup( + selectId: 'index:1', + direction: Axis.horizontal, + directionalTdRadios: widget.radios.entries.map((entry) { + return TDRadio( + id: entry.key, + title: entry.value, + radioStyle: TDRadioStyle.circle, + showDivider: false, + enable: !FormState, + ); + }).toList(), ), - onBtnTap: () { + ), + ], + ), + ), + ); + } else if (widget.name == 'date') { + return GestureDetector( + onTap: () { + TDPicker.showDatePicker(context, title: '选择时间', + onConfirm: (selected) { setState(() { - browseOn = !browseOn; + widget.select = + '${selected['year'].toString().padLeft(4, '0')}-${selected['month'].toString().padLeft(2, '0')}-${selected['day'].toString().padLeft(2, '0')}'; }); + Navigator.of(context).pop(); }, - needClear: false, + dateStart: [1999, 01, 01], + dateEnd: [2023, 12, 31], + initialDate: [2012, 1, 1]); + }, + child: buildSelectRow(context, widget.select, '选择时间'), + ); + } else if (widget.name == 'radios') { + final theme = TDTheme.of(context); + return Container( + decoration: BoxDecoration( + color: theme.whiteColor1, ), - ], - ); - } else if (widget.name == 'radios') { - final theme = TDTheme.of(context); - return Container( - decoration: BoxDecoration( - color: theme.whiteColor1, - ), - child: Padding( - padding: const EdgeInsets.all(16), - child: Row( - crossAxisAlignment: CrossAxisAlignment.center, - children: [ - // 左侧的文本 - TDText( - widget.label ?? '', - style: const TextStyle(fontSize: 16), + child: Padding( + padding: EdgeInsets.all(16), + child: Row( + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + TDText( + widget.label ?? '', + style: const TextStyle(fontSize: 16), + ), + const SizedBox(width: 16), + Expanded( + child: TDRadioGroup( + selectId: 'index:1', + direction: Axis.horizontal, + directionalTdRadios: widget.radios.entries.map((entry) { + return TDRadio( + id: entry.key, + title: entry.value, + radioStyle: TDRadioStyle.circle, + showDivider: false, + enable: !FormState, + ); + }).toList(), + ), + ), + ], + ), + ), + ); + } else if (widget.name == 'local') { + return GestureDetector( + onTap: () { + TDCascader.showMultiCascader(context, + title: '选择地址', + data: widget.localData, + initialData: _initData, + theme: 'step', + onChange: (List selectData) { + setState(() { + List result = []; + int len = selectData.length; + _initData = selectData[len - 1].value!; + selectData.forEach((element) { + result.add(element.label); + }); + _selected_1 = result.join('/'); + }); + }, onClose: () { + Navigator.of(context).pop(); + }); + }, + child: _buildSelectRow(context, _selected_1, '选择地区'), + ); + } else if (widget.name == 'stepper') { + final theme = TDTheme.of(context); + return Container( + decoration: BoxDecoration( + color: theme.whiteColor1, + ), + child: Padding( + padding: EdgeInsets.all(16), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + TDText( + widget.label, + style: TextStyle(fontSize: 16), + ), + TDStepper( + theme: TDStepperTheme.filled, + disabled: FormState, + ), + ], + ), + ), + ); + } else if (widget.name == 'textarea') { + return TDTextarea( + backgroundColor: Colors.red, + controller: widget.controller, + label: widget.label, + hintText: widget.help, + maxLength: widget.maxLength, + indicator: widget.indicator, + readOnly: FormState, + onChanged: (value) { + setState(() {}); + }, + ); + } + } else { + if (widget.name == 'name') { + return TDInput( + type: TDInputType.twoLine, + inputDecoration: InputDecoration( + hintText: widget.help, + border: InputBorder.none, + ), + leftLabel: widget.label, + controller: widget.controller, + backgroundColor: Colors.white, + + /// 竖直态的 TDInput 没用 additionInfo? + additionInfo: widget.additionInfo, + readOnly: FormState, + ); + } else if (widget.name == 'password') { + return Column( + children: [ + TDInput( + inputDecoration: InputDecoration( + hintText: widget.help, + // contentPadding: EdgeInsets.only(left: LabelWidth), + border: InputBorder.none, ), - const SizedBox(width: 16), - Expanded( - child: TDRadioGroup( + type: TDInputType.twoLine, + controller: widget.controller, + obscureText: !browseOn, + leftLabel: widget.label, + backgroundColor: Colors.white, + rightBtn: browseOn + ? Icon( + TDIcons.browse, + color: TDTheme.of(context).fontGyColor3, + ) + : Icon( + TDIcons.browse_off, + color: TDTheme.of(context).fontGyColor3, + ), + onBtnTap: () { + setState(() { + browseOn = !browseOn; + }); + }, + needClear: false, + readOnly: FormState, + ), + ], + ); + } else if (widget.name == 'radios') { + final theme = TDTheme.of(context); + return Container( + decoration: BoxDecoration( + color: theme.whiteColor1, + ), + child: Padding( + padding: EdgeInsets.all(16), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + TDText( + widget.label ?? '', + style: const TextStyle(fontSize: 16), + ), + TDRadioGroup( selectId: 'index:1', direction: Axis.horizontal, directionalTdRadios: widget.radios.entries.map((entry) { @@ -228,96 +386,100 @@ class _TDFormItemState extends State { title: entry.value, radioStyle: TDRadioStyle.circle, showDivider: false, + enable: !FormState, ); }).toList(), ), - ), - ], + ], + ), ), - ), - ); - } else if (widget.name == 'date') { - return GestureDetector( - onTap: () { - TDPicker.showDatePicker(context, title: '选择时间', - onConfirm: (selected) { - setState(() { - widget.select = - '${selected['year'].toString().padLeft(4, '0')}-${selected['month'].toString().padLeft(2, '0')}-${selected['day'].toString().padLeft(2, '0')}'; - }); - Navigator.of(context).pop(); + ); + } else if (widget.name == 'date') { + return GestureDetector( + onTap: () { + TDPicker.showDatePicker(context, title: '选择时间', + onConfirm: (selected) { + setState(() { + widget.select = + '${selected['year'].toString().padLeft(4, '0')}-${selected['month'].toString().padLeft(2, '0')}-${selected['day'].toString().padLeft(2, '0')}'; + }); + Navigator.of(context).pop(); + }, + dateStart: [1999, 01, 01], + dateEnd: [2023, 12, 31], + initialDate: [2012, 1, 1]); }, - dateStart: [1999, 01, 01], - dateEnd: [2023, 12, 31], - initialDate: [2012, 1, 1]); - }, - child: buildSelectRow(context, widget.select, '选择时间'), - ); - } else if (widget.name == 'age') { - final theme = TDTheme.of(context); - - return Container( - decoration: BoxDecoration( - color: theme.whiteColor1, - ), - child: Padding( - padding: const EdgeInsets.all(16), - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, // 左右分布 - children: [ - TDText( - widget.label, // 左侧的文本 - style: TextStyle(fontSize: 16), // 可根据需要设置样式 - ), - TDStepper( - theme: TDStepperTheme.filled, // 右侧的步进器 - ), - ], - ), - ), - ); - } else if (widget.name == 'local') { - return GestureDetector( - onTap: () { - TDCascader.showMultiCascader(context, - title: '选择地址', - data: widget.localData, - initialData: _initData, - theme: 'step', - onChange: (List selectData) { - setState(() { - List result = []; - int len = selectData.length; - _initData = selectData[len - 1].value!; - selectData.forEach((element) { - result.add(element.label); + child: buildSelectRow(context, widget.select, '选择时间'), + ); + } else if (widget.name == 'local') { + return GestureDetector( + onTap: () { + TDCascader.showMultiCascader(context, + title: '选择地址', + data: widget.localData, + initialData: _initData, + theme: 'step', + onChange: (List selectData) { + setState(() { + List result = []; + int len = selectData.length; + _initData = selectData[len - 1].value!; + selectData.forEach((element) { + result.add(element.label); + }); + _selected_1 = result.join('/'); }); - _selected_1 = result.join('/'); + }, onClose: () { + Navigator.of(context).pop(); }); - }, onClose: () { - Navigator.of(context).pop(); - }); - }, - child: _buildSelectRow(context, _selected_1, '选择地区'), - ); - } else if (widget.name == 'textarea') { - return TDTextarea( - /// 背景颜色未完成 - backgroundColor: Colors.red, - controller: widget.controller, - label: widget.label, - hintText: widget.help, - maxLength: widget.maxLength, - indicator: widget.indicator, - onChanged: (value) { - setState(() {}); - }, - ); + }, + child: _buildSelectRow(context, _selected_1, '选择地区'), + ); + } else if (widget.name == 'stepper') { + final theme = TDTheme.of(context); + return Container( + decoration: BoxDecoration( + color: theme.whiteColor1, + ), + child: Padding( + padding: EdgeInsets.all(16), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, // 使内容左对齐 + children: [ + TDText( + widget.label, + style: TextStyle(fontSize: 16), + ), + SizedBox(height: 8), + TDStepper( + theme: TDStepperTheme.filled, + disabled: FormState, + ), + ], + ), + ), + ); + } else if (widget.name == 'textarea') { + return TDTextarea( + backgroundColor: Colors.red, + controller: widget.controller, + label: widget.label, + hintText: widget.help, + maxLength: widget.maxLength, + indicator: widget.indicator, + readOnly: FormState, + layout: TDTextareaLayout.vertical, + onChanged: (value) { + setState(() {}); + }, + ); + } } + return Column(); } - Widget _buildSelectRow(BuildContext context, String output, String title) { + Widget buildSelectRow(BuildContext context, String output, String title) { return Container( color: TDTheme.of(context).whiteColor1, height: 56, @@ -328,26 +490,22 @@ class _TDFormItemState extends State { mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Padding( - padding: const EdgeInsets.only(left: 16, top: 16, bottom: 16), + padding: EdgeInsets.only(left: 16, top: 16, bottom: 16), child: TDText( title, font: TDTheme.of(context).fontBodyLarge, ), ), - Expanded( - child: Padding( - padding: const EdgeInsets.only(right: 16, left: 16), + Padding( + padding: const EdgeInsets.only(right: 16), child: Row( children: [ - Expanded( - child: TDText( + TDText( output, font: TDTheme.of(context).fontBodyLarge, textColor: TDTheme.of(context).fontGyColor3.withOpacity(0.4), - maxLines: 1, - overflow: TextOverflow.ellipsis, - )), + ), Padding( padding: const EdgeInsets.only(left: 2), child: Icon( @@ -358,7 +516,61 @@ class _TDFormItemState extends State { ), ], ), - )), + ), + ], + ), + const TDDivider( + margin: EdgeInsets.only( + left: 16, + ), + ) + ], + ), + ); + } + + Widget _buildSelectRow(BuildContext context, String output, String title) { + return Container( + color: TDTheme.of(context).whiteColor1, + height: 56, + child: Stack( + alignment: Alignment.bottomCenter, + children: [ + Row( + children: [ + Padding( + padding: EdgeInsets.only(left: 16, top: 16, bottom: 16), + child: TDText( + title, + font: TDTheme.of(context).fontBodyLarge, + ), + ), + Expanded( + child: Padding( + padding: const EdgeInsets.only(right: 16, left: 16), + child: Row( + children: [ + Expanded( + child: TDText( + output, + font: TDTheme.of(context).fontBodyLarge, + textColor: + TDTheme.of(context).fontGyColor3.withOpacity(0.4), + maxLines: 1, + overflow: TextOverflow.ellipsis, + )), + Padding( + padding: const EdgeInsets.only(left: 2), + child: Icon( + TDIcons.chevron_right, + color: + TDTheme.of(context).fontGyColor3.withOpacity(0.4), + ), + ), + ], + ), + ), + ), ], ), const TDDivider( From 5136d404da3f944553bc02547a1f5ecb717ccff6 Mon Sep 17 00:00:00 2001 From: Simon_Wzy <1691663479@qq.com> Date: Mon, 14 Oct 2024 19:20:47 +0800 Subject: [PATCH 27/46] =?UTF-8?q?TODO:=20=E6=8F=90=E4=BA=A4=E9=80=BB?= =?UTF-8?q?=E8=BE=91=20=E9=87=8D=E7=BD=AE=E9=80=BB=E8=BE=91=20Problem:=20T?= =?UTF-8?q?DTextare=20=E8=83=8C=E6=99=AF=E9=A2=9C=E8=89=B2=E9=97=AE?= =?UTF-8?q?=E9=A2=98=20TDRadioGroup=20=E9=AB=98=E5=BA=A6=E9=97=AE=E9=A2=98?= =?UTF-8?q?=20TDInput=20=E7=AB=96=E7=9B=B4=E6=80=81=20additionInfo=20?= =?UTF-8?q?=E4=B8=8D=E6=98=BE=E7=A4=BA=E9=97=AE=E9=A2=98=20=E7=AB=96?= =?UTF-8?q?=E7=9B=B4=E6=80=81=E6=96=87=E5=AD=97=E5=AF=B9=E9=BD=90=20paddin?= =?UTF-8?q?g=20=E9=97=AE=E9=A2=98=20=E7=BB=84=E7=9B=B8=E8=BF=9E=E9=80=89?= =?UTF-8?q?=E6=8B=A9=E5=99=A8=20=20=E6=97=B6=E9=97=B4=E9=80=89=E6=8B=A9?= =?UTF-8?q?=E5=99=A8=20=E6=B2=A1=E6=9C=89=20=E7=A6=81=E7=94=A8=E6=80=81=20?= =?UTF-8?q?=E7=AB=96=E7=9B=B4=E6=80=81=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../example/lib/page/td_form_page.dart | 125 ++++++++++++------ .../lib/src/components/form/td_form.dart | 8 +- .../lib/src/components/form/td_form_item.dart | 66 ++++----- 3 files changed, 122 insertions(+), 77 deletions(-) diff --git a/tdesign-component/example/lib/page/td_form_page.dart b/tdesign-component/example/lib/page/td_form_page.dart index 58f1fd078..f45fb26c1 100644 --- a/tdesign-component/example/lib/page/td_form_page.dart +++ b/tdesign-component/example/lib/page/td_form_page.dart @@ -34,12 +34,12 @@ class _TDFormPageState extends State { Color verticalButtonColor = Color(0xFFE5E5E5); Color horizontalButtonColor = Color(0xFFF0F1FD); - Map _radios = {"0": "男", "1": "女", "2": "保密"}; + final Map _radios = {'0': '男', '1': '女', '3': '保密'}; static const List _data = [ { - "label": '北京市', - "value": '110000', + 'label': '北京市', + 'value': '110000', "children": [ { "value": '110100', @@ -109,7 +109,7 @@ class _TDFormPageState extends State { @override void initState() { - for (var i = 0; i < 28; i++) { + for (var i = 0; i < 3; i++) { controller.add(TextEditingController()); } super.initState(); @@ -142,7 +142,7 @@ class _TDFormPageState extends State { Widget _buildForm(BuildContext context) { return TDForm( disabled: _formDisableState, - isHoeizontal: _isFormHorizontal, + isHorizontal: _isFormHorizontal, items: [ TDFormItem( label: '用户名', @@ -244,7 +244,7 @@ class _TDFormPageState extends State { }, ), ), - SizedBox(width: 8), + const SizedBox(width: 8), Expanded( child: TDButton( text: '竖直排布', @@ -337,41 +337,82 @@ class _TDFormPageState extends State { @Demo(group: 'button') Widget _buildCombinationButtons(BuildContext context) { final theme = TDTheme.of(context); - return Container( - decoration: BoxDecoration( - color: theme.whiteColor1, - ), - child: Padding( - padding: const EdgeInsets.all(16), - child: Row( - children: [ - SizedBox( - width: 16, - ), - Expanded( - child: TDButton( - text: '提交', - size: TDButtonSize.large, - type: TDButtonType.fill, - theme: TDButtonTheme.primary, - shape: TDButtonShape.rectangle, - )), - SizedBox( - width: 16, - ), - Expanded( - child: TDButton( - text: '重置', - size: TDButtonSize.large, - type: TDButtonType.fill, - shape: TDButtonShape.rectangle, - theme: TDButtonTheme.defaultTheme, - )), - SizedBox( - width: 16, - ), - ], - )), - ); + if (!_formDisableState) { + return Container( + decoration: BoxDecoration( + color: theme.whiteColor1, + ), + child: const Padding( + padding: EdgeInsets.all(16), + child: Row( + children: [ + SizedBox( + width: 16, + ), + Expanded( + child: TDButton( + text: '提交', + size: TDButtonSize.large, + type: TDButtonType.fill, + theme: TDButtonTheme.primary, + shape: TDButtonShape.rectangle, + )), + SizedBox( + width: 16, + ), + Expanded( + child: TDButton( + text: '重置', + size: TDButtonSize.large, + type: TDButtonType.fill, + shape: TDButtonShape.rectangle, + theme: TDButtonTheme.defaultTheme, + )), + SizedBox( + width: 16, + ), + ], + )), + ); + } else { + return Container( + decoration: BoxDecoration( + color: theme.whiteColor1, + ), + child: const Padding( + padding: EdgeInsets.all(16), + child: Row( + children: [ + SizedBox( + width: 16, + ), + Expanded( + child: TDButton( + text: '提交', + size: TDButtonSize.large, + type: TDButtonType.fill, + theme: TDButtonTheme.primary, + shape: TDButtonShape.rectangle, + disabled: true, + )), + SizedBox( + width: 16, + ), + Expanded( + child: TDButton( + text: '重置', + size: TDButtonSize.large, + type: TDButtonType.fill, + shape: TDButtonShape.rectangle, + theme: TDButtonTheme.defaultTheme, + disabled: true, + )), + SizedBox( + width: 16, + ), + ], + )), + ); + } } } diff --git a/tdesign-component/lib/src/components/form/td_form.dart b/tdesign-component/lib/src/components/form/td_form.dart index c6727fbf0..5f815c17f 100644 --- a/tdesign-component/lib/src/components/form/td_form.dart +++ b/tdesign-component/lib/src/components/form/td_form.dart @@ -1,5 +1,5 @@ import 'package:flutter/material.dart'; -import 'package:tdesign_flutter/src/components/form/td_form_inherited.dart'; +import 'td_form_inherited.dart'; import '../../../tdesign_flutter.dart'; class TDForm extends StatefulWidget { @@ -9,7 +9,7 @@ class TDForm extends StatefulWidget { this.colon = false, this.contentAlign = 'left', this.data, - this.isHoeizontal = true, + this.isHorizontal = true, this.disabled = false, this.errorMessage, this.labelAlign = 'right', @@ -37,7 +37,7 @@ class TDForm extends StatefulWidget { final Object? data; /// 表单排列方式是否为 水平方向 - final bool isHoeizontal; + final bool isHorizontal; /// 是否禁用整个表单 final bool disabled; @@ -88,7 +88,7 @@ class _TDFormState extends State { return TDFormInherited( disabled: widget.disabled, labelWidth: widget.labelWidth, - isHorizontal: widget.isHoeizontal, + isHorizontal: widget.isHorizontal, child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: widget.items diff --git a/tdesign-component/lib/src/components/form/td_form_item.dart b/tdesign-component/lib/src/components/form/td_form_item.dart index 7aa7b631e..a0a0fe428 100644 --- a/tdesign-component/lib/src/components/form/td_form_item.dart +++ b/tdesign-component/lib/src/components/form/td_form_item.dart @@ -1,14 +1,9 @@ import 'package:flutter/material.dart'; -import 'package:tdesign_flutter/src/components/form/td_form_inherited.dart'; +import 'td_form_inherited.dart'; import '../../../tdesign_flutter.dart'; class TDFormItem extends StatefulWidget { TDFormItem({ - // External parameters - this.controller, - this.select = '', - List? localData, - Map? radios, this.label, this.name, this.arrow = false, @@ -22,58 +17,65 @@ class TDFormItem extends StatefulWidget { this.maxLength, this.indicator, this.additionInfo, + this.controller, + this.select = '', + List? localData, + Map? radios, Key? key, }) : localData = localData ?? const [], radios = radios ?? const {}, super(key: key); - // Form label content + /// 表单项标签内容 final String? label; - // Form content alignment: 'left' or 'right' + /// 表单内容对齐方式:'left' 或 'right' final String? contentAlign; - // Whether to show the right arrow + /// 是否显示右侧箭头 final bool? arrow; - // Auxiliary information for TDInput + /// TDInput的辅助信息 final String? additionInfo; - // Help text for the form field + /// TDInput 默认显示文字 final String? help; - // Label alignment: 'left', 'right', or 'top' + /// 标签对齐方式:'left', 'right', 或 'top' final String? labelAlign; - // Label width, overrides the Form's labelWidth if provided + /// 标签宽度,如果提供则覆盖Form的labelWidth final double? labelWidth; - // Form field identifier + /// 表单项标识符 final String? name; - // Controller for the form field + /// Input 控制器 var controller; - // Selected value for date picker or similar + /// 选择器 适用于日期选择器等 String select; - // Data for cascader or other selection widgets + /// 传入数据 适用于级联选择器等 final List localData; - // Data for radio buttons + /// 单选按钮数据 + /// < 序号 , 名称 > final Map radios; - // Whether to display the required mark (*) + /// 是否显示必填标记(*) final bool? requiredMark; - // Validation rules for the form field + /// 表单项验证规则 final List? rules; - // Whether to show error messages + /// 是否显示错误信息 final bool? showErrowMessage; - // Properties for TDTextarea + /// TDTextarea的属性,最大长度 final int? maxLength; + + /// TDTextarea的属性,指示器 final bool? indicator; @override @@ -283,13 +285,13 @@ class _TDFormItemState extends State { color: theme.whiteColor1, ), child: Padding( - padding: EdgeInsets.all(16), + padding: const EdgeInsets.all(16), child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ TDText( widget.label, - style: TextStyle(fontSize: 16), + style: const TextStyle(fontSize: 16), ), TDStepper( theme: TDStepperTheme.filled, @@ -369,7 +371,7 @@ class _TDFormItemState extends State { color: theme.whiteColor1, ), child: Padding( - padding: EdgeInsets.all(16), + padding: const EdgeInsets.all(16), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ @@ -377,6 +379,7 @@ class _TDFormItemState extends State { widget.label ?? '', style: const TextStyle(fontSize: 16), ), + const SizedBox(width: 20), TDRadioGroup( selectId: 'index:1', direction: Axis.horizontal, @@ -442,15 +445,15 @@ class _TDFormItemState extends State { color: theme.whiteColor1, ), child: Padding( - padding: EdgeInsets.all(16), + padding: const EdgeInsets.all(16), child: Column( crossAxisAlignment: CrossAxisAlignment.start, // 使内容左对齐 children: [ TDText( widget.label, - style: TextStyle(fontSize: 16), + style: const TextStyle(fontSize: 16), ), - SizedBox(height: 8), + const SizedBox(height: 8), TDStepper( theme: TDStepperTheme.filled, disabled: FormState, @@ -476,7 +479,8 @@ class _TDFormItemState extends State { } } - return Column(); + /// TODO: 构建错误的提示页面 + return const Column(); } Widget buildSelectRow(BuildContext context, String output, String title) { @@ -490,7 +494,7 @@ class _TDFormItemState extends State { mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Padding( - padding: EdgeInsets.only(left: 16, top: 16, bottom: 16), + padding: const EdgeInsets.only(left: 16, top: 16, bottom: 16), child: TDText( title, font: TDTheme.of(context).fontBodyLarge, @@ -539,7 +543,7 @@ class _TDFormItemState extends State { Row( children: [ Padding( - padding: EdgeInsets.only(left: 16, top: 16, bottom: 16), + padding: const EdgeInsets.only(left: 16, top: 16, bottom: 16), child: TDText( title, font: TDTheme.of(context).fontBodyLarge, From 8ff8b1103f60bca816d971bc41c50cf24d4b2dfe Mon Sep 17 00:00:00 2001 From: Simon_Wzy <1691663479@qq.com> Date: Mon, 14 Oct 2024 19:22:08 +0800 Subject: [PATCH 28/46] =?UTF-8?q?TODO:=20=E6=8F=90=E4=BA=A4=E9=80=BB?= =?UTF-8?q?=E8=BE=91=20=E9=87=8D=E7=BD=AE=E9=80=BB=E8=BE=91=20Problem:=20T?= =?UTF-8?q?DTextare=20=E8=83=8C=E6=99=AF=E9=A2=9C=E8=89=B2=E9=97=AE?= =?UTF-8?q?=E9=A2=98=20TDRadioGroup=20=E9=AB=98=E5=BA=A6=E9=97=AE=E9=A2=98?= =?UTF-8?q?=20TDInput=20=E7=AB=96=E7=9B=B4=E6=80=81=20additionInfo=20?= =?UTF-8?q?=E4=B8=8D=E6=98=BE=E7=A4=BA=E9=97=AE=E9=A2=98=20=E7=AB=96?= =?UTF-8?q?=E7=9B=B4=E6=80=81=E6=96=87=E5=AD=97=E5=AF=B9=E9=BD=90=20paddin?= =?UTF-8?q?g=20=E9=97=AE=E9=A2=98=20=E7=BB=84=E7=9B=B8=E8=BF=9E=E9=80=89?= =?UTF-8?q?=E6=8B=A9=E5=99=A8=20=20=E6=97=B6=E9=97=B4=E9=80=89=E6=8B=A9?= =?UTF-8?q?=E5=99=A8=20=E6=B2=A1=E6=9C=89=20=E7=A6=81=E7=94=A8=E6=80=81=20?= =?UTF-8?q?=E7=AB=96=E7=9B=B4=E6=80=81=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tdesign-component/example/android/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tdesign-component/example/android/build.gradle b/tdesign-component/example/android/build.gradle index 53e7c1ac5..38f569bae 100644 --- a/tdesign-component/example/android/build.gradle +++ b/tdesign-component/example/android/build.gradle @@ -1,5 +1,5 @@ buildscript { - ext.kotlin_version = '1.9.0' + ext.kotlin_version = '1.6.21' ext { From ff5ad725757f719b93cd9999d9b2341539bbf0cf Mon Sep 17 00:00:00 2001 From: Luozf12345 <2515187986@qq.com> Date: Tue, 15 Oct 2024 22:06:58 +0800 Subject: [PATCH 29/46] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E6=96=87=E6=A1=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tdesign-component/demo_tool/all_build.sh | 1 + .../example/assets/api/dropdown-menu_api.md | 1 + .../example/assets/api/rate_api.md | 26 ++ ...ction_sheet._buildBadgeGridActionSheet.txt | 25 ++ ...ction_sheet._buildBadgeListActionSheet.txt | 22 ++ ...sheet._buildBadgeListCenterActionSheet.txt | 22 ++ ...n_sheet._buildBadgeListLeftActionSheet.txt | 23 ++ ...action_sheet._buildBaseGridActionSheet.txt | 19 ++ ...action_sheet._buildBaseListActionSheet.txt | 17 ++ ...n_sheet._buildBaseListStateActionSheet.txt | 40 +++ ...action_sheet._buildDescGridActionSheet.txt | 20 ++ ...action_sheet._buildDescListActionSheet.txt | 18 ++ ...action_sheet._buildIconListActionSheet.txt | 22 ++ ..._sheet._buildIconListCenterActionSheet.txt | 22 ++ ...on_sheet._buildIconListLeftActionSheet.txt | 23 ++ ...n_sheet._buildIconListStateActionSheet.txt | 44 ++++ ..._sheet._buildPaginationGridActionSheet.txt | 38 +++ .../code/badge._buildButtonNumberBadge.txt | 29 +++ ...ge._buildCustomBadgeShowingNumberEight.txt | 32 +++ ...dge._buildCustomBadgeShowingNumberZero.txt | 32 +++ ...ildCustomBadgeWithoutShowingNumberZero.txt | 33 +++ .../code/badge._buildIconNumberBadge.txt | 24 ++ .../badge._buildLessThanMaxCountBadge.txt | 30 +++ .../code/badge._buildMessageNumberBadge.txt | 27 ++ .../badge._buildMoreThanMaxCountBadge.txt | 30 +++ .../code/badge._buildRedPointButtonBadge.txt | 27 ++ .../code/badge._buildRedPointIconBadge.txt | 21 ++ .../code/badge._buildRedPointMessageBadge.txt | 24 ++ .../code/dropdownMenu._buildOverflow.txt | 2 +- .../assets/code/footer._buildBrandFooter.txt | 9 + .../assets/code/footer._buildFooter.txt | 11 + .../assets/code/footer._buildLinksFooter.txt | 17 ++ .../code/footer._buildSingleLinkFooter.txt | 13 + .../code/message._buildErrorMessage.txt | 20 ++ .../code/message._buildIconTextMessage.txt | 20 ++ .../assets/code/message._buildInfoMessage.txt | 21 ++ .../assets/code/message._buildLinkMessage.txt | 23 ++ .../message._buildMessageWithCloseButton.txt | 25 ++ .../code/message._buildPlainTextMessage.txt | 24 ++ .../code/message._buildRollingMessage.txt | 23 ++ .../code/message._buildSuccessMessage.txt | 21 ++ .../code/message._buildWarningMessage.txt | 20 ++ .../assets/code/progress._buildButton.txt | 9 + .../assets/code/progress._buildCircle.txt | 4 + .../code/progress._buildCircleDanger.txt | 7 + .../code/progress._buildCirclePrimary.txt | 7 + .../code/progress._buildCircleSuccess.txt | 7 + .../code/progress._buildCircleWarning.txt | 7 + .../assets/code/progress._buildDanger.txt | 9 + .../code/progress._buildInsideLabelLinear.txt | 4 + .../assets/code/progress._buildMicro.txt | 4 + .../code/progress._buildMicroButton.txt | 10 + .../assets/code/progress._buildPrimary.txt | 9 + .../code/progress._buildRightLabelLinear.txt | 8 + .../assets/code/progress._buildSuccess.txt | 9 + .../assets/code/progress._buildWarning.txt | 9 + .../assets/code/rate._buildColorRate.txt | 14 ++ .../assets/code/rate._buildCusRate.txt | 4 + .../example/assets/code/rate._buildDRate.txt | 10 + .../assets/code/rate._buildFilledRate.txt | 4 + .../assets/code/rate._buildFullRate.txt | 4 + .../assets/code/rate._buildHalfRate.txt | 4 + .../assets/code/rate._buildMsgRate.txt | 8 + .../assets/code/rate._buildNumRate.txt | 9 + .../assets/code/rate._buildOtherRate.txt | 33 +++ .../assets/code/rate._buildSizeRate.txt | 8 + .../code/sideBar._buildAnchorSideBar.txt | 1 + .../code/slider._buildCapsuleDoubleHandle.txt | 12 + ...er._buildCapsuleDoubleHandleWithNumber.txt | 15 ++ ...der._buildCapsuleDoubleHandleWithScale.txt | 17 ++ .../code/slider._buildCapsuleSingleHandle.txt | 14 ++ ...er._buildCapsuleSingleHandleWithNumber.txt | 13 + ...der._buildCapsuleSingleHandleWithScale.txt | 19 ++ ...er._buildDisableDoubleHandleWithNumber.txt | 14 ++ ...der._buildDisableDoubleHandleWithScale.txt | 13 + .../code/slider._buildDisableSingleHandle.txt | 12 + .../example/test/widget_test.dart | 28 +-- tdesign-site/src/dropdown-menu/README.md | 1 + tdesign-site/src/rate/README.md | 233 ++++++++++++++++++ tdesign-site/src/side-bar/README.md | 2 + 80 files changed, 1520 insertions(+), 16 deletions(-) create mode 100644 tdesign-component/example/assets/api/rate_api.md create mode 100644 tdesign-component/example/assets/code/action_sheet._buildBadgeGridActionSheet.txt create mode 100644 tdesign-component/example/assets/code/action_sheet._buildBadgeListActionSheet.txt create mode 100644 tdesign-component/example/assets/code/action_sheet._buildBadgeListCenterActionSheet.txt create mode 100644 tdesign-component/example/assets/code/action_sheet._buildBadgeListLeftActionSheet.txt create mode 100644 tdesign-component/example/assets/code/action_sheet._buildBaseGridActionSheet.txt create mode 100644 tdesign-component/example/assets/code/action_sheet._buildBaseListActionSheet.txt create mode 100644 tdesign-component/example/assets/code/action_sheet._buildBaseListStateActionSheet.txt create mode 100644 tdesign-component/example/assets/code/action_sheet._buildDescGridActionSheet.txt create mode 100644 tdesign-component/example/assets/code/action_sheet._buildDescListActionSheet.txt create mode 100644 tdesign-component/example/assets/code/action_sheet._buildIconListActionSheet.txt create mode 100644 tdesign-component/example/assets/code/action_sheet._buildIconListCenterActionSheet.txt create mode 100644 tdesign-component/example/assets/code/action_sheet._buildIconListLeftActionSheet.txt create mode 100644 tdesign-component/example/assets/code/action_sheet._buildIconListStateActionSheet.txt create mode 100644 tdesign-component/example/assets/code/action_sheet._buildPaginationGridActionSheet.txt create mode 100644 tdesign-component/example/assets/code/badge._buildButtonNumberBadge.txt create mode 100644 tdesign-component/example/assets/code/badge._buildCustomBadgeShowingNumberEight.txt create mode 100644 tdesign-component/example/assets/code/badge._buildCustomBadgeShowingNumberZero.txt create mode 100644 tdesign-component/example/assets/code/badge._buildCustomBadgeWithoutShowingNumberZero.txt create mode 100644 tdesign-component/example/assets/code/badge._buildIconNumberBadge.txt create mode 100644 tdesign-component/example/assets/code/badge._buildLessThanMaxCountBadge.txt create mode 100644 tdesign-component/example/assets/code/badge._buildMessageNumberBadge.txt create mode 100644 tdesign-component/example/assets/code/badge._buildMoreThanMaxCountBadge.txt create mode 100644 tdesign-component/example/assets/code/badge._buildRedPointButtonBadge.txt create mode 100644 tdesign-component/example/assets/code/badge._buildRedPointIconBadge.txt create mode 100644 tdesign-component/example/assets/code/badge._buildRedPointMessageBadge.txt create mode 100644 tdesign-component/example/assets/code/footer._buildBrandFooter.txt create mode 100644 tdesign-component/example/assets/code/footer._buildFooter.txt create mode 100644 tdesign-component/example/assets/code/footer._buildLinksFooter.txt create mode 100644 tdesign-component/example/assets/code/footer._buildSingleLinkFooter.txt create mode 100644 tdesign-component/example/assets/code/message._buildErrorMessage.txt create mode 100644 tdesign-component/example/assets/code/message._buildIconTextMessage.txt create mode 100644 tdesign-component/example/assets/code/message._buildInfoMessage.txt create mode 100644 tdesign-component/example/assets/code/message._buildLinkMessage.txt create mode 100644 tdesign-component/example/assets/code/message._buildMessageWithCloseButton.txt create mode 100644 tdesign-component/example/assets/code/message._buildPlainTextMessage.txt create mode 100644 tdesign-component/example/assets/code/message._buildRollingMessage.txt create mode 100644 tdesign-component/example/assets/code/message._buildSuccessMessage.txt create mode 100644 tdesign-component/example/assets/code/message._buildWarningMessage.txt create mode 100644 tdesign-component/example/assets/code/progress._buildButton.txt create mode 100644 tdesign-component/example/assets/code/progress._buildCircle.txt create mode 100644 tdesign-component/example/assets/code/progress._buildCircleDanger.txt create mode 100644 tdesign-component/example/assets/code/progress._buildCirclePrimary.txt create mode 100644 tdesign-component/example/assets/code/progress._buildCircleSuccess.txt create mode 100644 tdesign-component/example/assets/code/progress._buildCircleWarning.txt create mode 100644 tdesign-component/example/assets/code/progress._buildDanger.txt create mode 100644 tdesign-component/example/assets/code/progress._buildInsideLabelLinear.txt create mode 100644 tdesign-component/example/assets/code/progress._buildMicro.txt create mode 100644 tdesign-component/example/assets/code/progress._buildMicroButton.txt create mode 100644 tdesign-component/example/assets/code/progress._buildPrimary.txt create mode 100644 tdesign-component/example/assets/code/progress._buildRightLabelLinear.txt create mode 100644 tdesign-component/example/assets/code/progress._buildSuccess.txt create mode 100644 tdesign-component/example/assets/code/progress._buildWarning.txt create mode 100644 tdesign-component/example/assets/code/rate._buildColorRate.txt create mode 100644 tdesign-component/example/assets/code/rate._buildCusRate.txt create mode 100644 tdesign-component/example/assets/code/rate._buildDRate.txt create mode 100644 tdesign-component/example/assets/code/rate._buildFilledRate.txt create mode 100644 tdesign-component/example/assets/code/rate._buildFullRate.txt create mode 100644 tdesign-component/example/assets/code/rate._buildHalfRate.txt create mode 100644 tdesign-component/example/assets/code/rate._buildMsgRate.txt create mode 100644 tdesign-component/example/assets/code/rate._buildNumRate.txt create mode 100644 tdesign-component/example/assets/code/rate._buildOtherRate.txt create mode 100644 tdesign-component/example/assets/code/rate._buildSizeRate.txt create mode 100644 tdesign-component/example/assets/code/slider._buildCapsuleDoubleHandle.txt create mode 100644 tdesign-component/example/assets/code/slider._buildCapsuleDoubleHandleWithNumber.txt create mode 100644 tdesign-component/example/assets/code/slider._buildCapsuleDoubleHandleWithScale.txt create mode 100644 tdesign-component/example/assets/code/slider._buildCapsuleSingleHandle.txt create mode 100644 tdesign-component/example/assets/code/slider._buildCapsuleSingleHandleWithNumber.txt create mode 100644 tdesign-component/example/assets/code/slider._buildCapsuleSingleHandleWithScale.txt create mode 100644 tdesign-component/example/assets/code/slider._buildDisableDoubleHandleWithNumber.txt create mode 100644 tdesign-component/example/assets/code/slider._buildDisableDoubleHandleWithScale.txt create mode 100644 tdesign-component/example/assets/code/slider._buildDisableSingleHandle.txt create mode 100644 tdesign-site/src/rate/README.md diff --git a/tdesign-component/demo_tool/all_build.sh b/tdesign-component/demo_tool/all_build.sh index 8deb1d455..51a48fcef 100644 --- a/tdesign-component/demo_tool/all_build.sh +++ b/tdesign-component/demo_tool/all_build.sh @@ -49,6 +49,7 @@ # radio ./bin/demo_tool generate --file ../lib/src/components/radio/td_radio.dart --name TDRadioStyle,TDRadio,TDRadioGroup --folder-name radio --output ../example/assets/api/ --only-api --get-comments # rate +./bin/demo_tool generate --file ../lib/src/components/rate/td_rate.dart --name TDRate --folder-name rate --output ../example/assets/api/ --only-api # search ./bin/demo_tool generate --file ../lib/src/components/search/td_search_bar.dart --name TDSearchBar --folder-name search --output ../example/assets/api/ --only-api # slider diff --git a/tdesign-component/example/assets/api/dropdown-menu_api.md b/tdesign-component/example/assets/api/dropdown-menu_api.md index c4e98f3c7..bdcd6a2a5 100644 --- a/tdesign-component/example/assets/api/dropdown-menu_api.md +++ b/tdesign-component/example/assets/api/dropdown-menu_api.md @@ -46,6 +46,7 @@ | maxHeight | double? | - | 内容最大高度 | | tabBarWidth | double? | - | 该item在menu上的宽度,仅在[TDDropdownMenu.isScrollable]为true时有效 | | tabBarAlign | MainAxisAlignment? | - | [label]和[arrowIcon]/[TDDropdownMenu.arrowIcon]的对齐方式 | +| tabBarFlex | int? | 1 | 该item在menu上的宽度占比,仅在[TDDropdownMenu.isScrollable]为false时有效 | ``` ``` diff --git a/tdesign-component/example/assets/api/rate_api.md b/tdesign-component/example/assets/api/rate_api.md new file mode 100644 index 000000000..502a4b326 --- /dev/null +++ b/tdesign-component/example/assets/api/rate_api.md @@ -0,0 +1,26 @@ +## API +### TDRate +#### 默认构造方法 + +| 参数 | 类型 | 默认值 | 说明 | +| --- | --- | --- | --- | +| key | | - | | +| allowHalf | bool? | false | 是否允许半选 | +| color | List? | - | 评分图标的颜色,示例:[选中颜色] / [选中颜色,未选中颜色],默认:[TDTheme.of(context).warningColor5, TDTheme.of(context).grayColor4] | +| count | int? | 5 | 评分的数量 | +| disabled | bool? | false | 是否禁用评分 | +| gap | double? | - | 评分图标的间距,默认:TDTheme.of(context).spacer8 | +| icon | List? | - | 自定义评分图标,[选中和未选中图标] / [选中图标,未选中图标],默认:[TDIcons.star_filled] | +| placement | PlacementEnum? | PlacementEnum.top | 选择评分弹框的位置,值为[PlacementEnum.none]表示不显示评分弹框。 | +| showText | bool? | false | 是否显示对应的辅助文字 | +| size | double? | 24.0 | 评分图标的大小 | +| texts | List? | const ['极差', '失望', '一般', '满意', '惊喜'] | 评分等级对应的辅助文字, | +| textWidth | double? | 48.0 | 评分等级对应的辅助文字宽度 | +| builderText | Widget Function(BuildContext context, double value)? | - | 评分等级对应的辅助文字自定义构建,优先级高于[texts] | +| value | double? | 0 | 选择评分的值 | +| onChange | void Function(double value)? | - | 评分数改变时触发 | +| direction | Axis? | Axis.horizontal | 评分图标与辅助文字的布局方向 | +| mainAxisAlignment | MainAxisAlignment? | MainAxisAlignment.start | 评分图标与辅助文字的主轴对齐方式 | +| crossAxisAlignment | CrossAxisAlignment? | CrossAxisAlignment.center | 评分图标与辅助文字的交叉轴对齐方式 | +| mainAxisSize | MainAxisSize? | MainAxisSize.min | 评分图标与辅助文字主轴方向上如何占用空间 | +| iconTextGap | double? | - | 评分图标与辅助文字的间距,默认:[TDTheme.of(context).spacer16] | diff --git a/tdesign-component/example/assets/code/action_sheet._buildBadgeGridActionSheet.txt b/tdesign-component/example/assets/code/action_sheet._buildBadgeGridActionSheet.txt new file mode 100644 index 000000000..1a70495bf --- /dev/null +++ b/tdesign-component/example/assets/code/action_sheet._buildBadgeGridActionSheet.txt @@ -0,0 +1,25 @@ + +Widget _buildBadgeGridActionSheet(BuildContext context) { + return TDButton( + text: '带徽标宫格型', + isBlock: true, + type: TDButtonType.outline, + theme: TDButtonTheme.primary, + size: TDButtonSize.large, + onTap: () { + TDActionSheet( + context, + visible: true, + theme: TDActionSheetTheme.grid, + count: 8, + items: _gridItems + .map((e) => TDActionSheetItem( + label: e.label, + icon: e.icon, + badge: TDBadge(TDBadgeType.redPoint), + )) + .toList(), + ); + }, + ); +} \ No newline at end of file diff --git a/tdesign-component/example/assets/code/action_sheet._buildBadgeListActionSheet.txt b/tdesign-component/example/assets/code/action_sheet._buildBadgeListActionSheet.txt new file mode 100644 index 000000000..2723a7b82 --- /dev/null +++ b/tdesign-component/example/assets/code/action_sheet._buildBadgeListActionSheet.txt @@ -0,0 +1,22 @@ + +Widget _buildBadgeListActionSheet(BuildContext context) { + return TDButton( + text: '带徽标列表型', + isBlock: true, + type: TDButtonType.outline, + theme: TDButtonTheme.primary, + size: TDButtonSize.large, + onTap: () { + TDActionSheet( + context, + visible: true, + items: _nums + .map((e) => TDActionSheetItem( + label: '选项$e', + badge: TDBadge(TDBadgeType.redPoint), + )) + .toList(), + ); + }, + ); +} \ No newline at end of file diff --git a/tdesign-component/example/assets/code/action_sheet._buildBadgeListCenterActionSheet.txt b/tdesign-component/example/assets/code/action_sheet._buildBadgeListCenterActionSheet.txt new file mode 100644 index 000000000..048d1b8c3 --- /dev/null +++ b/tdesign-component/example/assets/code/action_sheet._buildBadgeListCenterActionSheet.txt @@ -0,0 +1,22 @@ + +Widget _buildBadgeListCenterActionSheet(BuildContext context) { + return TDButton( + text: '居中带徽标列表型', + isBlock: true, + type: TDButtonType.outline, + theme: TDButtonTheme.primary, + size: TDButtonSize.large, + onTap: () { + TDActionSheet( + context, + visible: true, + items: _nums + .map((e) => TDActionSheetItem( + label: '选项$e', + badge: TDBadge(TDBadgeType.redPoint), + )) + .toList(), + ); + }, + ); +} \ No newline at end of file diff --git a/tdesign-component/example/assets/code/action_sheet._buildBadgeListLeftActionSheet.txt b/tdesign-component/example/assets/code/action_sheet._buildBadgeListLeftActionSheet.txt new file mode 100644 index 000000000..14d3ec44e --- /dev/null +++ b/tdesign-component/example/assets/code/action_sheet._buildBadgeListLeftActionSheet.txt @@ -0,0 +1,23 @@ + +Widget _buildBadgeListLeftActionSheet(BuildContext context) { + return TDButton( + text: '左对齐带徽标列表型', + isBlock: true, + type: TDButtonType.outline, + theme: TDButtonTheme.primary, + size: TDButtonSize.large, + onTap: () { + TDActionSheet( + context, + visible: true, + align: TDActionSheetAlign.left, + items: _nums + .map((e) => TDActionSheetItem( + label: '选项$e', + badge: TDBadge(TDBadgeType.redPoint), + )) + .toList(), + ); + }, + ); +} \ No newline at end of file diff --git a/tdesign-component/example/assets/code/action_sheet._buildBaseGridActionSheet.txt b/tdesign-component/example/assets/code/action_sheet._buildBaseGridActionSheet.txt new file mode 100644 index 000000000..f5ecfd123 --- /dev/null +++ b/tdesign-component/example/assets/code/action_sheet._buildBaseGridActionSheet.txt @@ -0,0 +1,19 @@ + +Widget _buildBaseGridActionSheet(BuildContext context) { + return TDButton( + text: '常规宫格型', + isBlock: true, + type: TDButtonType.outline, + theme: TDButtonTheme.primary, + size: TDButtonSize.large, + onTap: () { + TDActionSheet( + context, + visible: true, + theme: TDActionSheetTheme.grid, + count: 8, + items: _gridItems, + ); + }, + ); +} \ No newline at end of file diff --git a/tdesign-component/example/assets/code/action_sheet._buildBaseListActionSheet.txt b/tdesign-component/example/assets/code/action_sheet._buildBaseListActionSheet.txt new file mode 100644 index 000000000..1cad7e743 --- /dev/null +++ b/tdesign-component/example/assets/code/action_sheet._buildBaseListActionSheet.txt @@ -0,0 +1,17 @@ + +Widget _buildBaseListActionSheet(BuildContext context) { + return TDButton( + text: '常规列表型', + isBlock: true, + type: TDButtonType.outline, + theme: TDButtonTheme.primary, + size: TDButtonSize.large, + onTap: () { + TDActionSheet( + context, + visible: true, + items: _nums.map((e) => TDActionSheetItem(label: '选项$e')).toList(), + ); + }, + ); +} \ No newline at end of file diff --git a/tdesign-component/example/assets/code/action_sheet._buildBaseListStateActionSheet.txt b/tdesign-component/example/assets/code/action_sheet._buildBaseListStateActionSheet.txt new file mode 100644 index 000000000..666cae229 --- /dev/null +++ b/tdesign-component/example/assets/code/action_sheet._buildBaseListStateActionSheet.txt @@ -0,0 +1,40 @@ + +Widget _buildBaseListStateActionSheet(BuildContext context) { + return TDButton( + text: '列表型选项状态', + isBlock: true, + type: TDButtonType.outline, + theme: TDButtonTheme.primary, + size: TDButtonSize.large, + onTap: () { + TDActionSheet( + context, + visible: true, + items: [ + TDActionSheetItem( + label: '默认选项', + ), + TDActionSheetItem( + label: '自定义选项', + textStyle: TextStyle( + color: TDTheme.of(context).brandNormalColor, + ), + ), + TDActionSheetItem( + label: '失效选项', + disabled: true, + ), + TDActionSheetItem( + label: '警告选项', + textStyle: TextStyle( + color: Colors.red, + ), + ), + ], + onSelected: (item, index) { + print('选中了:${item.label}'); + }, + ); + }, + ); +} \ No newline at end of file diff --git a/tdesign-component/example/assets/code/action_sheet._buildDescGridActionSheet.txt b/tdesign-component/example/assets/code/action_sheet._buildDescGridActionSheet.txt new file mode 100644 index 000000000..10908bfd1 --- /dev/null +++ b/tdesign-component/example/assets/code/action_sheet._buildDescGridActionSheet.txt @@ -0,0 +1,20 @@ + +Widget _buildDescGridActionSheet(BuildContext context) { + return TDButton( + text: '带描述宫格型', + isBlock: true, + type: TDButtonType.outline, + theme: TDButtonTheme.primary, + size: TDButtonSize.large, + onTap: () { + TDActionSheet( + context, + visible: true, + theme: TDActionSheetTheme.grid, + count: 8, + description: '动作面板描述文字', + items: _gridItems, + ); + }, + ); +} \ No newline at end of file diff --git a/tdesign-component/example/assets/code/action_sheet._buildDescListActionSheet.txt b/tdesign-component/example/assets/code/action_sheet._buildDescListActionSheet.txt new file mode 100644 index 000000000..184558582 --- /dev/null +++ b/tdesign-component/example/assets/code/action_sheet._buildDescListActionSheet.txt @@ -0,0 +1,18 @@ + +Widget _buildDescListActionSheet(BuildContext context) { + return TDButton( + text: '带描述列表型', + isBlock: true, + type: TDButtonType.outline, + theme: TDButtonTheme.primary, + size: TDButtonSize.large, + onTap: () { + TDActionSheet( + context, + visible: true, + description: '动作面板描述文字', + items: _nums.map((e) => TDActionSheetItem(label: '选项$e')).toList(), + ); + }, + ); +} \ No newline at end of file diff --git a/tdesign-component/example/assets/code/action_sheet._buildIconListActionSheet.txt b/tdesign-component/example/assets/code/action_sheet._buildIconListActionSheet.txt new file mode 100644 index 000000000..4723259ed --- /dev/null +++ b/tdesign-component/example/assets/code/action_sheet._buildIconListActionSheet.txt @@ -0,0 +1,22 @@ + +Widget _buildIconListActionSheet(BuildContext context) { + return TDButton( + text: '带图标列表型', + isBlock: true, + type: TDButtonType.outline, + theme: TDButtonTheme.primary, + size: TDButtonSize.large, + onTap: () { + TDActionSheet( + context, + visible: true, + items: _nums + .map((e) => TDActionSheetItem( + label: '选项$e', + icon: const Icon(TDIcons.app), + )) + .toList(), + ); + }, + ); +} \ No newline at end of file diff --git a/tdesign-component/example/assets/code/action_sheet._buildIconListCenterActionSheet.txt b/tdesign-component/example/assets/code/action_sheet._buildIconListCenterActionSheet.txt new file mode 100644 index 000000000..a7fe8473d --- /dev/null +++ b/tdesign-component/example/assets/code/action_sheet._buildIconListCenterActionSheet.txt @@ -0,0 +1,22 @@ + +Widget _buildIconListCenterActionSheet(BuildContext context) { + return TDButton( + text: '居中带图标列表型', + isBlock: true, + type: TDButtonType.outline, + theme: TDButtonTheme.primary, + size: TDButtonSize.large, + onTap: () { + TDActionSheet( + context, + visible: true, + items: _nums + .map((e) => TDActionSheetItem( + label: '选项$e', + icon: const Icon(TDIcons.app), + )) + .toList(), + ); + }, + ); +} \ No newline at end of file diff --git a/tdesign-component/example/assets/code/action_sheet._buildIconListLeftActionSheet.txt b/tdesign-component/example/assets/code/action_sheet._buildIconListLeftActionSheet.txt new file mode 100644 index 000000000..057daee83 --- /dev/null +++ b/tdesign-component/example/assets/code/action_sheet._buildIconListLeftActionSheet.txt @@ -0,0 +1,23 @@ + +Widget _buildIconListLeftActionSheet(BuildContext context) { + return TDButton( + text: '左对齐带图标列表型', + isBlock: true, + type: TDButtonType.outline, + theme: TDButtonTheme.primary, + size: TDButtonSize.large, + onTap: () { + TDActionSheet( + context, + visible: true, + align: TDActionSheetAlign.left, + items: _nums + .map((e) => TDActionSheetItem( + label: '选项$e', + icon: const Icon(TDIcons.app), + )) + .toList(), + ); + }, + ); +} \ No newline at end of file diff --git a/tdesign-component/example/assets/code/action_sheet._buildIconListStateActionSheet.txt b/tdesign-component/example/assets/code/action_sheet._buildIconListStateActionSheet.txt new file mode 100644 index 000000000..b1d3c5eed --- /dev/null +++ b/tdesign-component/example/assets/code/action_sheet._buildIconListStateActionSheet.txt @@ -0,0 +1,44 @@ + +Widget _buildIconListStateActionSheet(BuildContext context) { + return TDButton( + text: '列表型带图标状态', + isBlock: true, + type: TDButtonType.outline, + theme: TDButtonTheme.primary, + size: TDButtonSize.large, + onTap: () { + TDActionSheet( + context, + visible: true, + items: [ + TDActionSheetItem( + label: '默认选项', + icon: Icon(TDIcons.app), + ), + TDActionSheetItem( + label: '自定义选项', + icon: Icon(TDIcons.app), + textStyle: TextStyle( + color: TDTheme.of(context).brandNormalColor, + ), + ), + TDActionSheetItem( + label: '失效选项', + icon: Icon(TDIcons.app), + disabled: true, + ), + TDActionSheetItem( + label: '警告选项', + icon: Icon(TDIcons.app), + textStyle: TextStyle( + color: Colors.red, + ), + ), + ], + onSelected: (item, index) { + print('选中了:${item.label}'); + }, + ); + }, + ); +} \ No newline at end of file diff --git a/tdesign-component/example/assets/code/action_sheet._buildPaginationGridActionSheet.txt b/tdesign-component/example/assets/code/action_sheet._buildPaginationGridActionSheet.txt new file mode 100644 index 000000000..2035daf4b --- /dev/null +++ b/tdesign-component/example/assets/code/action_sheet._buildPaginationGridActionSheet.txt @@ -0,0 +1,38 @@ + +Widget _buildPaginationGridActionSheet(BuildContext context) { + return TDButton( + text: '带分页宫格型', + isBlock: true, + type: TDButtonType.outline, + theme: TDButtonTheme.primary, + size: TDButtonSize.large, + onTap: () { + TDActionSheet( + context, + visible: true, + theme: TDActionSheetTheme.grid, + count: 8, + showPagination: true, + items: [ + ..._gridItems, + TDActionSheetItem( + label: '安卓', + icon: IconWithBackground(icon: TDIcons.logo_android), + ), + TDActionSheetItem( + label: 'Apple', + icon: IconWithBackground(icon: TDIcons.logo_apple), + ), + TDActionSheetItem( + label: 'Chrome', + icon: IconWithBackground(icon: TDIcons.logo_chrome), + ), + TDActionSheetItem( + label: 'Github', + icon: IconWithBackground(icon: TDIcons.logo_github), + ), + ], + ); + }, + ); +} \ No newline at end of file diff --git a/tdesign-component/example/assets/code/badge._buildButtonNumberBadge.txt b/tdesign-component/example/assets/code/badge._buildButtonNumberBadge.txt new file mode 100644 index 000000000..422ed4929 --- /dev/null +++ b/tdesign-component/example/assets/code/badge._buildButtonNumberBadge.txt @@ -0,0 +1,29 @@ + + Widget _buildButtonNumberBadge(BuildContext context) { + return Container( + alignment: Alignment.bottomLeft, + margin: const EdgeInsets.only(left: 16), + child: SizedBox( + width: 86, + height: 54, + child: Stack( + alignment: Alignment.bottomLeft, + children: [ + TDButton( + width: 80, + height: 48, + text: '按钮', + size: TDButtonSize.large, + ), + Positioned( + child: TDBadge( + TDBadgeType.message, + count: '8', + ), + right: 0, + top: 0, + ) + ], + ), + )); + } \ No newline at end of file diff --git a/tdesign-component/example/assets/code/badge._buildCustomBadgeShowingNumberEight.txt b/tdesign-component/example/assets/code/badge._buildCustomBadgeShowingNumberEight.txt new file mode 100644 index 000000000..0eef08ec8 --- /dev/null +++ b/tdesign-component/example/assets/code/badge._buildCustomBadgeShowingNumberEight.txt @@ -0,0 +1,32 @@ + + Widget _buildCustomBadgeShowingNumberEight(BuildContext context) { + return Container( + alignment: Alignment.bottomLeft, + margin: const EdgeInsets.only(top: 8, left: 16, right: 16, bottom: 8), + child: SizedBox( + width: 64, + height: 56, + child: Stack( + alignment: Alignment.bottomLeft, + children: [ + Container( + child: const Icon(TDIcons.notification), + decoration: BoxDecoration( + color: TDTheme.of(context).grayColor2, + borderRadius: BorderRadius.circular( + TDTheme.of(context).radiusDefault)), + height: 48, + width: 48, + ), + const Positioned( + child: TDBadge( + TDBadgeType.message, + count: '8', + ), + right: 0, + top: 0, + ) + ], + ), + )); + } \ No newline at end of file diff --git a/tdesign-component/example/assets/code/badge._buildCustomBadgeShowingNumberZero.txt b/tdesign-component/example/assets/code/badge._buildCustomBadgeShowingNumberZero.txt new file mode 100644 index 000000000..698856498 --- /dev/null +++ b/tdesign-component/example/assets/code/badge._buildCustomBadgeShowingNumberZero.txt @@ -0,0 +1,32 @@ + + Widget _buildCustomBadgeShowingNumberZero(BuildContext context) { + return Container( + alignment: Alignment.bottomLeft, + margin: const EdgeInsets.only(top: 8, left: 16, right: 16, bottom: 8), + child: SizedBox( + width: 64, + height: 56, + child: Stack( + alignment: Alignment.bottomLeft, + children: [ + Container( + child: const Icon(TDIcons.notification), + decoration: BoxDecoration( + color: TDTheme.of(context).grayColor2, + borderRadius: BorderRadius.circular( + TDTheme.of(context).radiusDefault)), + height: 48, + width: 48, + ), + const Positioned( + child: TDBadge( + TDBadgeType.message, + count: '0', + ), + right: 0, + top: 0, + ) + ], + ), + )); + } \ No newline at end of file diff --git a/tdesign-component/example/assets/code/badge._buildCustomBadgeWithoutShowingNumberZero.txt b/tdesign-component/example/assets/code/badge._buildCustomBadgeWithoutShowingNumberZero.txt new file mode 100644 index 000000000..78f2ab4fc --- /dev/null +++ b/tdesign-component/example/assets/code/badge._buildCustomBadgeWithoutShowingNumberZero.txt @@ -0,0 +1,33 @@ + + Widget _buildCustomBadgeWithoutShowingNumberZero(BuildContext context) { + return Container( + alignment: Alignment.bottomLeft, + margin: const EdgeInsets.only(top: 8, left: 16, right: 16, bottom: 8), + child: SizedBox( + width: 64, + height: 56, + child: Stack( + alignment: Alignment.bottomLeft, + children: [ + Container( + child: const Icon(TDIcons.notification), + decoration: BoxDecoration( + color: TDTheme.of(context).grayColor2, + borderRadius: BorderRadius.circular( + TDTheme.of(context).radiusDefault)), + height: 48, + width: 48, + ), + const Positioned( + child: TDBadge( + TDBadgeType.message, + count: '0', + showZero: false, + ), + right: 0, + top: 0, + ) + ], + ), + )); + } \ No newline at end of file diff --git a/tdesign-component/example/assets/code/badge._buildIconNumberBadge.txt b/tdesign-component/example/assets/code/badge._buildIconNumberBadge.txt new file mode 100644 index 000000000..00d9013b2 --- /dev/null +++ b/tdesign-component/example/assets/code/badge._buildIconNumberBadge.txt @@ -0,0 +1,24 @@ + + Widget _buildIconNumberBadge(BuildContext context) { + return Container( + alignment: Alignment.bottomLeft, + margin: const EdgeInsets.only(left: 16), + child: SizedBox( + width: 42, + height: 36, + child: Stack( + alignment: Alignment.bottomLeft, + children: [ + Icon(TDIcons.notification), + Positioned( + child: TDBadge( + TDBadgeType.message, + count: '8', + ), + left: 18, + bottom: 18, + ) + ], + ), + )); + } \ No newline at end of file diff --git a/tdesign-component/example/assets/code/badge._buildLessThanMaxCountBadge.txt b/tdesign-component/example/assets/code/badge._buildLessThanMaxCountBadge.txt new file mode 100644 index 000000000..7dd4245cf --- /dev/null +++ b/tdesign-component/example/assets/code/badge._buildLessThanMaxCountBadge.txt @@ -0,0 +1,30 @@ + + Widget _buildLessThanMaxCountBadge(BuildContext context) { + return Container( + alignment: Alignment.bottomLeft, + margin: const EdgeInsets.only(left: 16, right: 16, bottom: 8), + child: SizedBox( + width: 60, + height: 50, + child: Stack( + children: [ + Positioned( + left: 0, + bottom: 0, + child: Icon(TDIcons.notification), + ), + Positioned( + child: TDBadge( + TDBadgeType.square, + count: '8888', + maxCount: '9000', + size: TDBadgeSize.large, + border: TDBadgeBorder.large, + ), + left: 18, + bottom: 18, + ), + ], + ), + )); + } \ No newline at end of file diff --git a/tdesign-component/example/assets/code/badge._buildMessageNumberBadge.txt b/tdesign-component/example/assets/code/badge._buildMessageNumberBadge.txt new file mode 100644 index 000000000..36de3237b --- /dev/null +++ b/tdesign-component/example/assets/code/badge._buildMessageNumberBadge.txt @@ -0,0 +1,27 @@ + + Widget _buildMessageNumberBadge(BuildContext context) { + return Container( + alignment: Alignment.bottomLeft, + margin: const EdgeInsets.only(left: 16), + child: SizedBox( + width: 54, + height: 36, + child: Stack( + alignment: Alignment.bottomLeft, + children: [ + TDText( + '消息', + font: TDTheme.of(context).fontBodyLarge, + ), + const Positioned( + child: TDBadge( + TDBadgeType.message, + count: '8', + ), + left: 28, + bottom: 18, + ) + ], + ), + )); + } \ No newline at end of file diff --git a/tdesign-component/example/assets/code/badge._buildMoreThanMaxCountBadge.txt b/tdesign-component/example/assets/code/badge._buildMoreThanMaxCountBadge.txt new file mode 100644 index 000000000..7f836cddd --- /dev/null +++ b/tdesign-component/example/assets/code/badge._buildMoreThanMaxCountBadge.txt @@ -0,0 +1,30 @@ + + Widget _buildMoreThanMaxCountBadge(BuildContext context) { + return Container( + alignment: Alignment.bottomLeft, + margin: const EdgeInsets.only(left: 16, right: 16, bottom: 8), + child: SizedBox( + width: 60, + height: 50, + child: Stack( + children: [ + Positioned( + left: 0, + bottom: 0, + child: Icon(TDIcons.notification), + ), + Positioned( + child: TDBadge( + TDBadgeType.square, + count: '888', + maxCount: '99', + size: TDBadgeSize.large, + border: TDBadgeBorder.large, + ), + left: 18, + bottom: 18, + ), + ], + ), + )); + } \ No newline at end of file diff --git a/tdesign-component/example/assets/code/badge._buildRedPointButtonBadge.txt b/tdesign-component/example/assets/code/badge._buildRedPointButtonBadge.txt new file mode 100644 index 000000000..5bd2ec6cd --- /dev/null +++ b/tdesign-component/example/assets/code/badge._buildRedPointButtonBadge.txt @@ -0,0 +1,27 @@ + + Widget _buildRedPointButtonBadge(BuildContext context) { + return Container( + alignment: Alignment.bottomLeft, + margin: const EdgeInsets.only(left: 16, right: 16), + child: SizedBox( + width: 83, + height: 48, + child: Stack( + alignment: Alignment.bottomLeft, + children: [ + TDButton( + width: 80, + height: 48, + text: '按钮', + size: TDButtonSize.large, + type: TDButtonType.fill, + ), + Positioned( + child: TDBadge(TDBadgeType.redPoint), + right: 0, + top: 0, + ) + ], + ), + )); + } \ No newline at end of file diff --git a/tdesign-component/example/assets/code/badge._buildRedPointIconBadge.txt b/tdesign-component/example/assets/code/badge._buildRedPointIconBadge.txt new file mode 100644 index 000000000..2b1ccf711 --- /dev/null +++ b/tdesign-component/example/assets/code/badge._buildRedPointIconBadge.txt @@ -0,0 +1,21 @@ + + Widget _buildRedPointIconBadge(BuildContext context) { + return Container( + alignment: Alignment.bottomLeft, + margin: const EdgeInsets.only(left: 16, right: 16), + child: SizedBox( + width: 27, + height: 27, + child: Stack( + alignment: Alignment.bottomLeft, + children: [ + Icon(TDIcons.notification), + Positioned( + child: TDBadge(TDBadgeType.redPoint), + right: 0, + top: 0, + ) + ], + ), + )); + } \ No newline at end of file diff --git a/tdesign-component/example/assets/code/badge._buildRedPointMessageBadge.txt b/tdesign-component/example/assets/code/badge._buildRedPointMessageBadge.txt new file mode 100644 index 000000000..8638aed98 --- /dev/null +++ b/tdesign-component/example/assets/code/badge._buildRedPointMessageBadge.txt @@ -0,0 +1,24 @@ + + Widget _buildRedPointMessageBadge(BuildContext context) { + return Container( + alignment: Alignment.bottomLeft, + margin: const EdgeInsets.only(left: 16, right: 16), + child: SizedBox( + width: 40, + height: 24, + child: Stack( + alignment: Alignment.bottomLeft, + children: [ + TDText( + '消息', + font: TDTheme.of(context).fontBodyLarge, + ), + const Positioned( + child: TDBadge(TDBadgeType.redPoint), + right: 0, + top: 0, + ) + ], + ), + )); + } \ No newline at end of file diff --git a/tdesign-component/example/assets/code/dropdownMenu._buildOverflow.txt b/tdesign-component/example/assets/code/dropdownMenu._buildOverflow.txt index e1b86c72b..4e8806d4e 100644 --- a/tdesign-component/example/assets/code/dropdownMenu._buildOverflow.txt +++ b/tdesign-component/example/assets/code/dropdownMenu._buildOverflow.txt @@ -40,7 +40,7 @@ TDDropdownMenu _buildOverflow(BuildContext context) { tabBarWidth: 200, tabBarAlign: MainAxisAlignment.start, options: [ - TDDropdownItemOption(label: '选项1', value: '1', selected: true), + TDDropdownItemOption(label: '选项1选项1选项1选项1选项1选项1选项1', value: '1', selected: true), TDDropdownItemOption(label: '选项2', value: '2'), ], ), diff --git a/tdesign-component/example/assets/code/footer._buildBrandFooter.txt b/tdesign-component/example/assets/code/footer._buildBrandFooter.txt new file mode 100644 index 000000000..225ac72cb --- /dev/null +++ b/tdesign-component/example/assets/code/footer._buildBrandFooter.txt @@ -0,0 +1,9 @@ + + Widget _buildBrandFooter(BuildContext context) { + return TDFooter( + TDFooterType.brand, + logo: 'assets/img/td_brand.png', + width: 204, + height: 48, + ); + } \ No newline at end of file diff --git a/tdesign-component/example/assets/code/footer._buildFooter.txt b/tdesign-component/example/assets/code/footer._buildFooter.txt new file mode 100644 index 000000000..f0f3c7e97 --- /dev/null +++ b/tdesign-component/example/assets/code/footer._buildFooter.txt @@ -0,0 +1,11 @@ + + Widget _buildFooter(BuildContext context) { + return SizedBox( + height: 30, + child: TDFooter( + TDFooterType.text, + text: 'Copyright © 2019-2023 TDesign.All Rights Reserved.', + ), + ); + + } \ No newline at end of file diff --git a/tdesign-component/example/assets/code/footer._buildLinksFooter.txt b/tdesign-component/example/assets/code/footer._buildLinksFooter.txt new file mode 100644 index 000000000..571ade591 --- /dev/null +++ b/tdesign-component/example/assets/code/footer._buildLinksFooter.txt @@ -0,0 +1,17 @@ + + Widget _buildLinksFooter(BuildContext context) { + final links = [ + LinkObj(name: '底部链接', uri: Uri.parse('https://example.com')), + LinkObj(name: '底部链接', uri: Uri.parse('https://example.com')), + ]; + return Column( + children: [ + SizedBox(height: 12), + TDFooter( + TDFooterType.link, + links: links, + text: 'Copyright © 2019-2023 TDesign.All Rights Reserved.', + ) + ], + ); + } \ No newline at end of file diff --git a/tdesign-component/example/assets/code/footer._buildSingleLinkFooter.txt b/tdesign-component/example/assets/code/footer._buildSingleLinkFooter.txt new file mode 100644 index 000000000..da4c88f30 --- /dev/null +++ b/tdesign-component/example/assets/code/footer._buildSingleLinkFooter.txt @@ -0,0 +1,13 @@ + + Widget _buildSingleLinkFooter(BuildContext context) { + // 示例链接列表 + final singleLink = [ + LinkObj(name: '底部链接', uri: Uri.parse('https://example.com')), + ]; + + return TDFooter( + TDFooterType.link, + links: singleLink, + text: 'Copyright © 2019-2023 TDesign.All Rights Reserved.', + ); + } \ No newline at end of file diff --git a/tdesign-component/example/assets/code/message._buildErrorMessage.txt b/tdesign-component/example/assets/code/message._buildErrorMessage.txt new file mode 100644 index 000000000..2b54c710b --- /dev/null +++ b/tdesign-component/example/assets/code/message._buildErrorMessage.txt @@ -0,0 +1,20 @@ + + Widget _buildErrorMessage(BuildContext context) { + return TDButton( + isBlock: true, + text: '错误通知', + size: TDButtonSize.large, + type: TDButtonType.outline, + width: 450, + theme: TDButtonTheme.primary, + onTap: () { + TDMessage.showMessage( + context: context, + visible: true, + icon: true, + content: _commonContent, + theme: MessageTheme.error, + duration: 3000, + ); + }); + } \ No newline at end of file diff --git a/tdesign-component/example/assets/code/message._buildIconTextMessage.txt b/tdesign-component/example/assets/code/message._buildIconTextMessage.txt new file mode 100644 index 000000000..40c1861eb --- /dev/null +++ b/tdesign-component/example/assets/code/message._buildIconTextMessage.txt @@ -0,0 +1,20 @@ + + Widget _buildIconTextMessage(BuildContext context) { + return TDButton( + isBlock: true, + text: '带图标的通知', + size: TDButtonSize.large, + type: TDButtonType.outline, + width: 450, + theme: TDButtonTheme.primary, + onTap: () { + TDMessage.showMessage( + context: context, + content: _commonContent, + visible: true, + icon: true, + theme: MessageTheme.info, + duration: 3000, + ); + }); + } \ No newline at end of file diff --git a/tdesign-component/example/assets/code/message._buildInfoMessage.txt b/tdesign-component/example/assets/code/message._buildInfoMessage.txt new file mode 100644 index 000000000..02b57a378 --- /dev/null +++ b/tdesign-component/example/assets/code/message._buildInfoMessage.txt @@ -0,0 +1,21 @@ + + Widget _buildInfoMessage(BuildContext context) { + return TDButton( + isBlock: true, + text: '普通通知', + size: TDButtonSize.large, + type: TDButtonType.outline, + width: 450, + theme: TDButtonTheme.primary, + onTap: () { + TDMessage.showMessage( + context: context, + visible: true, + icon: true, + content: _commonContent, + theme: MessageTheme.info, + duration: 3000, + ); + }, + ); + } \ No newline at end of file diff --git a/tdesign-component/example/assets/code/message._buildLinkMessage.txt b/tdesign-component/example/assets/code/message._buildLinkMessage.txt new file mode 100644 index 000000000..75df9e155 --- /dev/null +++ b/tdesign-component/example/assets/code/message._buildLinkMessage.txt @@ -0,0 +1,23 @@ + + Widget _buildLinkMessage(BuildContext context) { + return TDButton( + isBlock: true, + text: '带按钮的通知', + size: TDButtonSize.large, + type: TDButtonType.outline, + width: 450, + theme: TDButtonTheme.primary, + onTap: () { + TDMessage.showMessage( + context: context, + visible: true, + icon: true, + content: _commonContent, + theme: MessageTheme.info, + duration: 3000, + link: '按钮', + onLinkClick: () { + print('link clicked!'); + }); + }); + } \ No newline at end of file diff --git a/tdesign-component/example/assets/code/message._buildMessageWithCloseButton.txt b/tdesign-component/example/assets/code/message._buildMessageWithCloseButton.txt new file mode 100644 index 000000000..3da4c175b --- /dev/null +++ b/tdesign-component/example/assets/code/message._buildMessageWithCloseButton.txt @@ -0,0 +1,25 @@ + + Widget _buildMessageWithCloseButton(BuildContext context) { + return TDButton( + isBlock: true, + text: '带关闭的通知', + size: TDButtonSize.large, + type: TDButtonType.outline, + width: 450, + theme: TDButtonTheme.primary, + onTap: () { + TDMessage.showMessage( + context: context, + visible: true, + icon: true, + content: _commonContent, + theme: MessageTheme.info, + duration: 300000, + closeBtn: true, + link: MessageLink(name: '按钮', uri: Uri.parse('www.example.com')), + onCloseBtnClick: () { + print('Close button clicked!'); + }, + ); + }); + } \ No newline at end of file diff --git a/tdesign-component/example/assets/code/message._buildPlainTextMessage.txt b/tdesign-component/example/assets/code/message._buildPlainTextMessage.txt new file mode 100644 index 000000000..d199ef5d1 --- /dev/null +++ b/tdesign-component/example/assets/code/message._buildPlainTextMessage.txt @@ -0,0 +1,24 @@ + + Widget _buildPlainTextMessage(BuildContext context) { + return TDButton( + isBlock: true, + text: '纯文字的通知', + size: TDButtonSize.large, + type: TDButtonType.outline, + width: 450, + theme: TDButtonTheme.primary, + onTap: () { + TDMessage.showMessage( + context: context, + content: _commonContent, + visible: true, + icon: false, + theme: MessageTheme.info, + duration: 3000, + onDurationEnd: () { + print('message end'); + }, + ); + }, + ); + } \ No newline at end of file diff --git a/tdesign-component/example/assets/code/message._buildRollingMessage.txt b/tdesign-component/example/assets/code/message._buildRollingMessage.txt new file mode 100644 index 000000000..a935a353c --- /dev/null +++ b/tdesign-component/example/assets/code/message._buildRollingMessage.txt @@ -0,0 +1,23 @@ + + Widget _buildRollingMessage(BuildContext context) { + return TDButton( + isBlock: true, + text: '可滚动的通知', + size: TDButtonSize.large, + type: TDButtonType.outline, + width: 450, + theme: TDButtonTheme.primary, + onTap: () { + TDMessage.showMessage( + context: context, + visible: true, + icon: false, + marquee: MessageMarquee(speed: 5000, loop: 1, delay: 300), + content: longContent, + theme: MessageTheme.info, + duration: 8000, + onCloseBtnClick: () { + print('Close button clicked!'); + }); + }); + } \ No newline at end of file diff --git a/tdesign-component/example/assets/code/message._buildSuccessMessage.txt b/tdesign-component/example/assets/code/message._buildSuccessMessage.txt new file mode 100644 index 000000000..4c7de921f --- /dev/null +++ b/tdesign-component/example/assets/code/message._buildSuccessMessage.txt @@ -0,0 +1,21 @@ + + Widget _buildSuccessMessage(BuildContext context) { + return TDButton( + isBlock: true, + text: '成功通知', + size: TDButtonSize.large, + type: TDButtonType.outline, + width: 450, + theme: TDButtonTheme.primary, + onTap: () { + TDMessage.showMessage( + context: context, + visible: true, + icon: true, + content: _commonContent, + theme: MessageTheme.success, + duration: 3000, + ); + }, + ); + } \ No newline at end of file diff --git a/tdesign-component/example/assets/code/message._buildWarningMessage.txt b/tdesign-component/example/assets/code/message._buildWarningMessage.txt new file mode 100644 index 000000000..08d6b8a0d --- /dev/null +++ b/tdesign-component/example/assets/code/message._buildWarningMessage.txt @@ -0,0 +1,20 @@ + + Widget _buildWarningMessage(BuildContext context) { + return TDButton( + isBlock: true, + text: '警示通知', + size: TDButtonSize.large, + type: TDButtonType.outline, + width: 450, + theme: TDButtonTheme.primary, + onTap: () { + TDMessage.showMessage( + context: context, + visible: true, + icon: true, + content: _commonContent, + theme: MessageTheme.warning, + duration: 3000, + ); + }); + } \ No newline at end of file diff --git a/tdesign-component/example/assets/code/progress._buildButton.txt b/tdesign-component/example/assets/code/progress._buildButton.txt new file mode 100644 index 000000000..ccedf6a25 --- /dev/null +++ b/tdesign-component/example/assets/code/progress._buildButton.txt @@ -0,0 +1,9 @@ + + Widget _buildButton(BuildContext context) { + return TDProgress( + type: TDProgressType.button, + onTap: _toggleProgress, + onLongPress: _resetProgress, + value: progressValue, + label: buttonLabel); + } \ No newline at end of file diff --git a/tdesign-component/example/assets/code/progress._buildCircle.txt b/tdesign-component/example/assets/code/progress._buildCircle.txt new file mode 100644 index 000000000..22c92dfcb --- /dev/null +++ b/tdesign-component/example/assets/code/progress._buildCircle.txt @@ -0,0 +1,4 @@ + + Widget _buildCircle(BuildContext context) { + return TDProgress(type: TDProgressType.circular, value: 0.3); + } \ No newline at end of file diff --git a/tdesign-component/example/assets/code/progress._buildCircleDanger.txt b/tdesign-component/example/assets/code/progress._buildCircleDanger.txt new file mode 100644 index 000000000..48cad74a7 --- /dev/null +++ b/tdesign-component/example/assets/code/progress._buildCircleDanger.txt @@ -0,0 +1,7 @@ + + Widget _buildCircleDanger(BuildContext context) { + return TDProgress( + type: TDProgressType.circular, + progressStatus: TDProgressStatus.danger, + value: 0.3); + } \ No newline at end of file diff --git a/tdesign-component/example/assets/code/progress._buildCirclePrimary.txt b/tdesign-component/example/assets/code/progress._buildCirclePrimary.txt new file mode 100644 index 000000000..d81b5ea61 --- /dev/null +++ b/tdesign-component/example/assets/code/progress._buildCirclePrimary.txt @@ -0,0 +1,7 @@ + + Widget _buildCirclePrimary(BuildContext context) { + return TDProgress( + type: TDProgressType.circular, + progressStatus: TDProgressStatus.primary, + value: 0.3); + } \ No newline at end of file diff --git a/tdesign-component/example/assets/code/progress._buildCircleSuccess.txt b/tdesign-component/example/assets/code/progress._buildCircleSuccess.txt new file mode 100644 index 000000000..813a2074d --- /dev/null +++ b/tdesign-component/example/assets/code/progress._buildCircleSuccess.txt @@ -0,0 +1,7 @@ + + Widget _buildCircleSuccess(BuildContext context) { + return TDProgress( + type: TDProgressType.circular, + progressStatus: TDProgressStatus.success, + value: 1); + } \ No newline at end of file diff --git a/tdesign-component/example/assets/code/progress._buildCircleWarning.txt b/tdesign-component/example/assets/code/progress._buildCircleWarning.txt new file mode 100644 index 000000000..eb7d2ad3c --- /dev/null +++ b/tdesign-component/example/assets/code/progress._buildCircleWarning.txt @@ -0,0 +1,7 @@ + + Widget _buildCircleWarning(BuildContext context) { + return TDProgress( + type: TDProgressType.circular, + progressStatus: TDProgressStatus.warning, + value: 0.3); + } \ No newline at end of file diff --git a/tdesign-component/example/assets/code/progress._buildDanger.txt b/tdesign-component/example/assets/code/progress._buildDanger.txt new file mode 100644 index 000000000..3e7359cbe --- /dev/null +++ b/tdesign-component/example/assets/code/progress._buildDanger.txt @@ -0,0 +1,9 @@ + + Widget _buildDanger(BuildContext context) { + return TDProgress( + type: TDProgressType.linear, + progressStatus: TDProgressStatus.danger, + value: 0.8, + strokeWidth: 6, + progressLabelPosition: TDProgressLabelPosition.right); + } \ No newline at end of file diff --git a/tdesign-component/example/assets/code/progress._buildInsideLabelLinear.txt b/tdesign-component/example/assets/code/progress._buildInsideLabelLinear.txt new file mode 100644 index 000000000..a91ab5cab --- /dev/null +++ b/tdesign-component/example/assets/code/progress._buildInsideLabelLinear.txt @@ -0,0 +1,4 @@ + + Widget _buildInsideLabelLinear(BuildContext context) { + return TDProgress(type: TDProgressType.linear, value: 0.8); + } \ No newline at end of file diff --git a/tdesign-component/example/assets/code/progress._buildMicro.txt b/tdesign-component/example/assets/code/progress._buildMicro.txt new file mode 100644 index 000000000..da6311ba9 --- /dev/null +++ b/tdesign-component/example/assets/code/progress._buildMicro.txt @@ -0,0 +1,4 @@ + + Widget _buildMicro(BuildContext context) { + return TDProgress(type: TDProgressType.micro, value: 0.75); + } \ No newline at end of file diff --git a/tdesign-component/example/assets/code/progress._buildMicroButton.txt b/tdesign-component/example/assets/code/progress._buildMicroButton.txt new file mode 100644 index 000000000..3df1ebc81 --- /dev/null +++ b/tdesign-component/example/assets/code/progress._buildMicroButton.txt @@ -0,0 +1,10 @@ + + Widget _buildMicroButton(BuildContext context) { + return TDProgress( + type: TDProgressType.micro, + value: microProgressValue, + onTap: _toggleMicroProgress, + label: TDIconLabel(isPlaying ? Icons.pause : Icons.play_arrow, + color: TDTheme.of(context).brandNormalColor), + ); + } \ No newline at end of file diff --git a/tdesign-component/example/assets/code/progress._buildPrimary.txt b/tdesign-component/example/assets/code/progress._buildPrimary.txt new file mode 100644 index 000000000..86557ac70 --- /dev/null +++ b/tdesign-component/example/assets/code/progress._buildPrimary.txt @@ -0,0 +1,9 @@ + + Widget _buildPrimary(BuildContext context) { + return TDProgress( + type: TDProgressType.linear, + progressStatus: TDProgressStatus.primary, + value: 0.8, + strokeWidth: 6, + progressLabelPosition: TDProgressLabelPosition.right); + } \ No newline at end of file diff --git a/tdesign-component/example/assets/code/progress._buildRightLabelLinear.txt b/tdesign-component/example/assets/code/progress._buildRightLabelLinear.txt new file mode 100644 index 000000000..c20d98b64 --- /dev/null +++ b/tdesign-component/example/assets/code/progress._buildRightLabelLinear.txt @@ -0,0 +1,8 @@ + + Widget _buildRightLabelLinear(BuildContext context) { + return TDProgress( + type: TDProgressType.linear, + value: 0.8, + strokeWidth: 6, + progressLabelPosition: TDProgressLabelPosition.right); + } \ No newline at end of file diff --git a/tdesign-component/example/assets/code/progress._buildSuccess.txt b/tdesign-component/example/assets/code/progress._buildSuccess.txt new file mode 100644 index 000000000..9db1910c5 --- /dev/null +++ b/tdesign-component/example/assets/code/progress._buildSuccess.txt @@ -0,0 +1,9 @@ + + Widget _buildSuccess(BuildContext context) { + return TDProgress( + type: TDProgressType.linear, + progressStatus: TDProgressStatus.success, + value: 0.8, + strokeWidth: 6, + progressLabelPosition: TDProgressLabelPosition.right); + } \ No newline at end of file diff --git a/tdesign-component/example/assets/code/progress._buildWarning.txt b/tdesign-component/example/assets/code/progress._buildWarning.txt new file mode 100644 index 000000000..e1eddec92 --- /dev/null +++ b/tdesign-component/example/assets/code/progress._buildWarning.txt @@ -0,0 +1,9 @@ + + Widget _buildWarning(BuildContext context) { + return TDProgress( + type: TDProgressType.linear, + progressStatus: TDProgressStatus.warning, + value: 0.8, + strokeWidth: 6, + progressLabelPosition: TDProgressLabelPosition.right); + } \ No newline at end of file diff --git a/tdesign-component/example/assets/code/rate._buildColorRate.txt b/tdesign-component/example/assets/code/rate._buildColorRate.txt new file mode 100644 index 000000000..9b7763be5 --- /dev/null +++ b/tdesign-component/example/assets/code/rate._buildColorRate.txt @@ -0,0 +1,14 @@ + + Widget _buildColorRate(BuildContext context) { + return Column(children: const [ + TDCell( + title: '填充评分', + noteWidget: TDRate( + value: 2.5, + allowHalf: true, + color: [Color(0xFFFFC51C), Color(0xFFE8E8E8)], + )), + SizedBox(height: 16), + TDCell(title: '线描评分', noteWidget: TDRate(value: 2.5, allowHalf: true, color: [Color(0xFF00A870)])), + ]); + } \ No newline at end of file diff --git a/tdesign-component/example/assets/code/rate._buildCusRate.txt b/tdesign-component/example/assets/code/rate._buildCusRate.txt new file mode 100644 index 000000000..4d8f1bea8 --- /dev/null +++ b/tdesign-component/example/assets/code/rate._buildCusRate.txt @@ -0,0 +1,4 @@ + + Widget _buildCusRate(BuildContext context) { + return const TDCell(title: '自定义评分', noteWidget: TDRate(value: 3, icon: [TDIcons.thumb_up])); + } \ No newline at end of file diff --git a/tdesign-component/example/assets/code/rate._buildDRate.txt b/tdesign-component/example/assets/code/rate._buildDRate.txt new file mode 100644 index 000000000..10d479cfe --- /dev/null +++ b/tdesign-component/example/assets/code/rate._buildDRate.txt @@ -0,0 +1,10 @@ + + Widget _buildDRate(BuildContext context) { + return Column(children: const [ + TDCell(title: '顶部显示', noteWidget: TDRate(placement: PlacementEnum.top)), + SizedBox(height: 16), + TDCell(title: '不显示', noteWidget: TDRate(placement: PlacementEnum.none)), + SizedBox(height: 16), + TDCell(title: '底部显示', noteWidget: TDRate(placement: PlacementEnum.bottom)), + ]); + } \ No newline at end of file diff --git a/tdesign-component/example/assets/code/rate._buildFilledRate.txt b/tdesign-component/example/assets/code/rate._buildFilledRate.txt new file mode 100644 index 000000000..aef3d6f74 --- /dev/null +++ b/tdesign-component/example/assets/code/rate._buildFilledRate.txt @@ -0,0 +1,4 @@ + + Widget _buildFilledRate(BuildContext context) { + return const TDCell(title: '实心评分', noteWidget: TDRate(value: 3)); + } \ No newline at end of file diff --git a/tdesign-component/example/assets/code/rate._buildFullRate.txt b/tdesign-component/example/assets/code/rate._buildFullRate.txt new file mode 100644 index 000000000..52da296e3 --- /dev/null +++ b/tdesign-component/example/assets/code/rate._buildFullRate.txt @@ -0,0 +1,4 @@ + + Widget _buildFullRate(BuildContext context) { + return const TDCell(title: '点击活滑动', noteWidget: TDRate(value: 3)); + } \ No newline at end of file diff --git a/tdesign-component/example/assets/code/rate._buildHalfRate.txt b/tdesign-component/example/assets/code/rate._buildHalfRate.txt new file mode 100644 index 000000000..abcdcdff9 --- /dev/null +++ b/tdesign-component/example/assets/code/rate._buildHalfRate.txt @@ -0,0 +1,4 @@ + + Widget _buildHalfRate(BuildContext context) { + return const TDCell(title: '点击活滑动', noteWidget: TDRate(value: 3, allowHalf: true)); + } \ No newline at end of file diff --git a/tdesign-component/example/assets/code/rate._buildMsgRate.txt b/tdesign-component/example/assets/code/rate._buildMsgRate.txt new file mode 100644 index 000000000..b95761407 --- /dev/null +++ b/tdesign-component/example/assets/code/rate._buildMsgRate.txt @@ -0,0 +1,8 @@ + + Widget _buildMsgRate(BuildContext context) { + return Column(children: const [ + TDCell(title: '带描述评分', noteWidget: TDRate(value: 3, showText: true, texts: ['1分', '2分', '3分', '4分', '5分'])), + SizedBox(height: 16), + TDCell(title: '带描述评分', noteWidget: TDRate(value: 3, showText: true)) + ]); + } \ No newline at end of file diff --git a/tdesign-component/example/assets/code/rate._buildNumRate.txt b/tdesign-component/example/assets/code/rate._buildNumRate.txt new file mode 100644 index 000000000..ff120d913 --- /dev/null +++ b/tdesign-component/example/assets/code/rate._buildNumRate.txt @@ -0,0 +1,9 @@ + + Widget _buildNumRate(BuildContext context) { + return const TDCell( + title: '自定义评分数量', + noteWidget: TDRate( + value: 2, + count: 3, + )); + } \ No newline at end of file diff --git a/tdesign-component/example/assets/code/rate._buildOtherRate.txt b/tdesign-component/example/assets/code/rate._buildOtherRate.txt new file mode 100644 index 000000000..4744c6da5 --- /dev/null +++ b/tdesign-component/example/assets/code/rate._buildOtherRate.txt @@ -0,0 +1,33 @@ + + Widget _buildOtherRate(BuildContext context) { + var texts = ['非常糟糕', '有些糟糕', '可以尝试', '可以前往', '推荐前往']; + return Container( + width: double.infinity, + child: Center( + child: TDRate( + value: 2, + size: 30, + showText: true, + // texts: ['非常糟糕', '有些糟糕', '可以尝试', '可以前往', '推荐前往'], + direction: Axis.vertical, + // mainAxisAlignment: MainAxisAlignment.center, + // textWidth: 64, + builderText: (context, value) { + return value == 0 + ? const SizedBox.shrink() + : Padding( + padding: EdgeInsets.only(top: TDTheme.of(context).spacer8), + child: TDText( + texts[(value - 1).toInt()], + font: TDTheme.of(context).fontTitleMedium, + textColor: TDTheme.of(context).warningColor5, + ), + ); + }, + ), + ), + + padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 12), + color: Colors.white, + ); + } \ No newline at end of file diff --git a/tdesign-component/example/assets/code/rate._buildSizeRate.txt b/tdesign-component/example/assets/code/rate._buildSizeRate.txt new file mode 100644 index 000000000..39cf44b76 --- /dev/null +++ b/tdesign-component/example/assets/code/rate._buildSizeRate.txt @@ -0,0 +1,8 @@ + + Widget _buildSizeRate(BuildContext context) { + return Column(children: const [ + TDCell(title: '默认尺寸24', noteWidget: TDRate(value: 3)), + SizedBox(height: 16), + TDCell(title: '小尺寸20', noteWidget: TDRate(value: 3, size: 20)), + ]); + } \ No newline at end of file diff --git a/tdesign-component/example/assets/code/sideBar._buildAnchorSideBar.txt b/tdesign-component/example/assets/code/sideBar._buildAnchorSideBar.txt index ebdac2b55..050c705f2 100644 --- a/tdesign-component/example/assets/code/sideBar._buildAnchorSideBar.txt +++ b/tdesign-component/example/assets/code/sideBar._buildAnchorSideBar.txt @@ -25,6 +25,7 @@ ); var demoHeight = MediaQuery.of(context).size.height; + _sideBarController.init(list); return Row( children: [ diff --git a/tdesign-component/example/assets/code/slider._buildCapsuleDoubleHandle.txt b/tdesign-component/example/assets/code/slider._buildCapsuleDoubleHandle.txt new file mode 100644 index 000000000..3ab964513 --- /dev/null +++ b/tdesign-component/example/assets/code/slider._buildCapsuleDoubleHandle.txt @@ -0,0 +1,12 @@ + + Widget _buildCapsuleDoubleHandle(BuildContext context) { + return TDRangeSlider( + sliderThemeData: TDSliderThemeData.capsule( + min: 0, + max: 100, + scaleFormatter: (value) => value.toInt().toString(), + ), + value: const RangeValues(20, 60), + onChanged: (value) {}, + ); + } \ No newline at end of file diff --git a/tdesign-component/example/assets/code/slider._buildCapsuleDoubleHandleWithNumber.txt b/tdesign-component/example/assets/code/slider._buildCapsuleDoubleHandleWithNumber.txt new file mode 100644 index 000000000..0a2d40c9c --- /dev/null +++ b/tdesign-component/example/assets/code/slider._buildCapsuleDoubleHandleWithNumber.txt @@ -0,0 +1,15 @@ + + Widget _buildCapsuleDoubleHandleWithNumber(BuildContext context) { + return TDRangeSlider( + sliderThemeData: TDSliderThemeData.capsule( + showThumbValue: true, + min: 0, + max: 100, + scaleFormatter: (value) => value.toInt().toString(), + ), + leftLabel: '0', + rightLabel: '100', + value: const RangeValues(20, 60), + onChanged: (value) {}, + ); + } \ No newline at end of file diff --git a/tdesign-component/example/assets/code/slider._buildCapsuleDoubleHandleWithScale.txt b/tdesign-component/example/assets/code/slider._buildCapsuleDoubleHandleWithScale.txt new file mode 100644 index 000000000..6e4730424 --- /dev/null +++ b/tdesign-component/example/assets/code/slider._buildCapsuleDoubleHandleWithScale.txt @@ -0,0 +1,17 @@ + + Widget _buildCapsuleDoubleHandleWithScale(BuildContext context) { + return TDRangeSlider( + sliderThemeData: TDSliderThemeData.capsule( + showScaleValue: true, + divisions: 5, + min: 0, + max: 100, + scaleFormatter: (value) => value.toInt().toString(), + )..updateSliderThemeData((data) => data.copyWith( + activeTickMarkColor: const Color(0xFFE7E7E7), + inactiveTickMarkColor: const Color(0xFFE7E7E7), + )), + value: const RangeValues(20, 60), + onChanged: (value) {}, + ); + } \ No newline at end of file diff --git a/tdesign-component/example/assets/code/slider._buildCapsuleSingleHandle.txt b/tdesign-component/example/assets/code/slider._buildCapsuleSingleHandle.txt new file mode 100644 index 000000000..51951cd94 --- /dev/null +++ b/tdesign-component/example/assets/code/slider._buildCapsuleSingleHandle.txt @@ -0,0 +1,14 @@ + + Widget _buildCapsuleSingleHandle(BuildContext context) { + return TDSlider( + sliderThemeData: TDSliderThemeData.capsule( + min: 0, + max: 100, + scaleFormatter: (value) => value.toInt().toString(), + ), + leftLabel: '0', + rightLabel: '100', + value: 40, + onChanged: (value) {}, + ); + } \ No newline at end of file diff --git a/tdesign-component/example/assets/code/slider._buildCapsuleSingleHandleWithNumber.txt b/tdesign-component/example/assets/code/slider._buildCapsuleSingleHandleWithNumber.txt new file mode 100644 index 000000000..ea19709cf --- /dev/null +++ b/tdesign-component/example/assets/code/slider._buildCapsuleSingleHandleWithNumber.txt @@ -0,0 +1,13 @@ + + Widget _buildCapsuleSingleHandleWithNumber(BuildContext context) { + return TDSlider( + sliderThemeData: TDSliderThemeData.capsule( + showThumbValue: true, + min: 0, + max: 100, + scaleFormatter: (value) => value.toInt().toString(), + ), + value: 40, + onChanged: (value) {}, + ); + } \ No newline at end of file diff --git a/tdesign-component/example/assets/code/slider._buildCapsuleSingleHandleWithScale.txt b/tdesign-component/example/assets/code/slider._buildCapsuleSingleHandleWithScale.txt new file mode 100644 index 000000000..34d7b7fbf --- /dev/null +++ b/tdesign-component/example/assets/code/slider._buildCapsuleSingleHandleWithScale.txt @@ -0,0 +1,19 @@ + + Widget _buildCapsuleSingleHandleWithScale(BuildContext context) { + return TDSlider( + sliderThemeData: TDSliderThemeData.capsule( + showScaleValue: true, + divisions: 5, + min: 0, + max: 100, + scaleFormatter: (value) => value.toInt().toString(), + ) + ..updateSliderThemeData((data) => + data.copyWith( + activeTickMarkColor: const Color(0xFFE7E7E7), + inactiveTickMarkColor: const Color(0xFFE7E7E7), + )), + value: 60, + onChanged: (value) {}, + ); + } \ No newline at end of file diff --git a/tdesign-component/example/assets/code/slider._buildDisableDoubleHandleWithNumber.txt b/tdesign-component/example/assets/code/slider._buildDisableDoubleHandleWithNumber.txt new file mode 100644 index 000000000..fef24e6f4 --- /dev/null +++ b/tdesign-component/example/assets/code/slider._buildDisableDoubleHandleWithNumber.txt @@ -0,0 +1,14 @@ + + Widget _buildDisableDoubleHandleWithNumber(BuildContext context) { + return TDRangeSlider( + sliderThemeData: TDSliderThemeData( + showThumbValue: true, + min: 0, + max: 100, + scaleFormatter: (value) => value.toInt().toString(), + ), + leftLabel: '0', + rightLabel: '100', + value: const RangeValues(20, 60), + ); + } \ No newline at end of file diff --git a/tdesign-component/example/assets/code/slider._buildDisableDoubleHandleWithScale.txt b/tdesign-component/example/assets/code/slider._buildDisableDoubleHandleWithScale.txt new file mode 100644 index 000000000..cb7952433 --- /dev/null +++ b/tdesign-component/example/assets/code/slider._buildDisableDoubleHandleWithScale.txt @@ -0,0 +1,13 @@ + + Widget _buildDisableDoubleHandleWithScale(BuildContext context) { + return TDRangeSlider( + sliderThemeData: TDSliderThemeData( + showScaleValue: true, + divisions: 5, + min: 0, + max: 100, + scaleFormatter: (value) => value.toInt().toString(), + ), + value: const RangeValues(20, 60), + ); + } \ No newline at end of file diff --git a/tdesign-component/example/assets/code/slider._buildDisableSingleHandle.txt b/tdesign-component/example/assets/code/slider._buildDisableSingleHandle.txt new file mode 100644 index 000000000..fa15ed0ac --- /dev/null +++ b/tdesign-component/example/assets/code/slider._buildDisableSingleHandle.txt @@ -0,0 +1,12 @@ + + Widget _buildDisableSingleHandle(BuildContext context) { + return TDSlider( + sliderThemeData: TDSliderThemeData( + min: 0, + max: 100, + ), + leftLabel: '0', + rightLabel: '100', + value: 40, + ); + } \ No newline at end of file diff --git a/tdesign-component/example/test/widget_test.dart b/tdesign-component/example/test/widget_test.dart index 22cbae602..577557407 100644 --- a/tdesign-component/example/test/widget_test.dart +++ b/tdesign-component/example/test/widget_test.dart @@ -22,35 +22,33 @@ void main() async { WebMdTool.needGenerateWebMd = true; await tester.pumpWidget(const MyApp()); - exampleMap.forEach((key, value) { - value.forEach((model) { + for(var i =0 ;i < exampleMap.length; i++){ + var value = exampleMap.values.elementAt(i); + for(var j =0 ;j < value.length; j++){ + var model = value.elementAt(j); if (!model.isTodo) { - examplePageList.add(model); + if(model.text == '颜色'){ + // 测试结束 + throw Exception('<===============执行完成!!!!=================>'); + } + await _testComponent(tester, model.text); } - }); - }); - for(var element in examplePageList){ - // Build our app and trigger a frame. - if(element.text == '颜色'){ - // 测试结束 - break; } - await _testComponent(tester, element.text); + count++; } - // throw Exception('<===============执行完成!!!!=================>'); }); } -var changeList = ['Drawer 抽屉','TabBar 标签栏','Checkbox 多选框','Search 搜索框','TreeSelect 树形选择器','TimeCounter 计时器','Result 结果','DropdownMenu 下拉菜单','Swipecell 滑动操作']; Finder? lastFinder; +int count = 0; Future _testComponent(WidgetTester tester, String name) async { print('\n\n当前组件==============>:$name'); - - if(changeList.contains(name) && lastFinder != null){ + count++; + if(count % 5 == 0 && lastFinder != null){ await tester.fling(lastFinder!, const Offset(0, -300), 2); try { await tester.pumpAndSettle(); diff --git a/tdesign-site/src/dropdown-menu/README.md b/tdesign-site/src/dropdown-menu/README.md index e667769fb..dfe800067 100644 --- a/tdesign-site/src/dropdown-menu/README.md +++ b/tdesign-site/src/dropdown-menu/README.md @@ -359,6 +359,7 @@ TDDropdownMenu _buildGroup(BuildContext context) { | maxHeight | double? | - | 内容最大高度 | | tabBarWidth | double? | - | 该item在menu上的宽度,仅在[TDDropdownMenu.isScrollable]为true时有效 | | tabBarAlign | MainAxisAlignment? | - | [label]和[arrowIcon]/[TDDropdownMenu.arrowIcon]的对齐方式 | +| tabBarFlex | int? | 1 | 该item在menu上的宽度占比,仅在[TDDropdownMenu.isScrollable]为false时有效 | ``` ``` diff --git a/tdesign-site/src/rate/README.md b/tdesign-site/src/rate/README.md new file mode 100644 index 000000000..857245a9b --- /dev/null +++ b/tdesign-site/src/rate/README.md @@ -0,0 +1,233 @@ +--- +title: Rate 评分 +description: 用于对某行为/事物进行打分。 +spline: base +isComponent: true +--- + + +## 引入 + +在tdesign_flutter/tdesign_flutter.dart中有所有组件的路径。 + +```dart +import 'package:tdesign_flutter/tdesign_flutter.dart'; +``` + +## 代码演示 + +[td_rate_page.dart](https://github.com/Tencent/tdesign-flutter/blob/main/tdesign-component/example/lib/page/td_rate_page.dart) + +### 1 组件类型 + +实心评分 + + + +
+  Widget _buildFilledRate(BuildContext context) {
+    return const TDCell(title: '实心评分', noteWidget: TDRate(value: 3));
+  }
+ +
+ + +自定义评分 + + + +
+  Widget _buildCusRate(BuildContext context) {
+    return const TDCell(title: '自定义评分', noteWidget: TDRate(value: 3, icon: [TDIcons.thumb_up]));
+  }
+ +
+ + +自定义评分数量 + + + +
+  Widget _buildNumRate(BuildContext context) {
+    return const TDCell(
+        title: '自定义评分数量',
+        noteWidget: TDRate(
+          value: 2,
+          count: 3,
+        ));
+  }
+ +
+ + +带描述评分 + + + +
+  Widget _buildMsgRate(BuildContext context) {
+    return Column(children: const [
+      TDCell(title: '带描述评分', noteWidget: TDRate(value: 3, showText: true, texts: ['1分', '2分', '3分', '4分', '5分'])),
+      SizedBox(height: 16),
+      TDCell(title: '带描述评分', noteWidget: TDRate(value: 3, showText: true))
+    ]);
+  }
+ +
+ + +评分弹框位置 + + + +
+  Widget _buildDRate(BuildContext context) {
+    return Column(children: const [
+      TDCell(title: '顶部显示', noteWidget: TDRate(placement: PlacementEnum.top)),
+      SizedBox(height: 16),
+      TDCell(title: '不显示', noteWidget: TDRate(placement: PlacementEnum.none)),
+      SizedBox(height: 16),
+      TDCell(title: '底部显示', noteWidget: TDRate(placement: PlacementEnum.bottom)),
+    ]);
+  }
+ +
+ +### 1 组件状态 + +只可选全星时 + + + +
+  Widget _buildFullRate(BuildContext context) {
+    return const TDCell(title: '点击活滑动', noteWidget: TDRate(value: 3));
+  }
+ +
+ + +可选半星时 + + + +
+  Widget _buildHalfRate(BuildContext context) {
+    return const TDCell(title: '点击活滑动', noteWidget: TDRate(value: 3, allowHalf: true));
+  }
+ +
+ +### 1 组件样式 + +评分大小 + + + +
+  Widget _buildSizeRate(BuildContext context) {
+    return Column(children: const [
+      TDCell(title: '默认尺寸24', noteWidget: TDRate(value: 3)),
+      SizedBox(height: 16),
+      TDCell(title: '小尺寸20', noteWidget: TDRate(value: 3, size: 20)),
+    ]);
+  }
+ +
+ + +设置评分颜色 + + + +
+  Widget _buildColorRate(BuildContext context) {
+    return Column(children: const [
+      TDCell(
+          title: '填充评分',
+          noteWidget: TDRate(
+            value: 2.5,
+            allowHalf: true,
+            color: [Color(0xFFFFC51C), Color(0xFFE8E8E8)],
+          )),
+      SizedBox(height: 16),
+      TDCell(title: '线描评分', noteWidget: TDRate(value: 2.5, allowHalf: true, color: [Color(0xFF00A870)])),
+    ]);
+  }
+ +
+ +### 1 特殊样式 + +竖向带描述评分 + + + +
+  Widget _buildOtherRate(BuildContext context) {
+    var texts = ['非常糟糕', '有些糟糕', '可以尝试', '可以前往', '推荐前往'];
+    return Container(
+      width: double.infinity,
+      child: Center(
+        child: TDRate(
+        value: 2,
+        size: 30,
+        showText: true,
+        // texts: ['非常糟糕', '有些糟糕', '可以尝试', '可以前往', '推荐前往'],
+        direction: Axis.vertical,
+        // mainAxisAlignment: MainAxisAlignment.center,
+        // textWidth: 64,
+        builderText: (context, value) {
+          return value == 0
+              ? const SizedBox.shrink()
+              : Padding(
+                  padding: EdgeInsets.only(top: TDTheme.of(context).spacer8),
+                  child: TDText(
+                    texts[(value - 1).toInt()],
+                    font: TDTheme.of(context).fontTitleMedium,
+                    textColor: TDTheme.of(context).warningColor5,
+                  ),
+                );
+        },
+      ),
+      ),
+      
+      padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 12),
+      color: Colors.white,
+    );
+  }
+ +
+ + + +## API +### TDRate +#### 默认构造方法 + +| 参数 | 类型 | 默认值 | 说明 | +| --- | --- | --- | --- | +| key | | - | | +| allowHalf | bool? | false | 是否允许半选 | +| color | List? | - | 评分图标的颜色,示例:[选中颜色] / [选中颜色,未选中颜色],默认:[TDTheme.of(context).warningColor5, TDTheme.of(context).grayColor4] | +| count | int? | 5 | 评分的数量 | +| disabled | bool? | false | 是否禁用评分 | +| gap | double? | - | 评分图标的间距,默认:TDTheme.of(context).spacer8 | +| icon | List? | - | 自定义评分图标,[选中和未选中图标] / [选中图标,未选中图标],默认:[TDIcons.star_filled] | +| placement | PlacementEnum? | PlacementEnum.top | 选择评分弹框的位置,值为[PlacementEnum.none]表示不显示评分弹框。 | +| showText | bool? | false | 是否显示对应的辅助文字 | +| size | double? | 24.0 | 评分图标的大小 | +| texts | List? | const ['极差', '失望', '一般', '满意', '惊喜'] | 评分等级对应的辅助文字, | +| textWidth | double? | 48.0 | 评分等级对应的辅助文字宽度 | +| builderText | Widget Function(BuildContext context, double value)? | - | 评分等级对应的辅助文字自定义构建,优先级高于[texts] | +| value | double? | 0 | 选择评分的值 | +| onChange | void Function(double value)? | - | 评分数改变时触发 | +| direction | Axis? | Axis.horizontal | 评分图标与辅助文字的布局方向 | +| mainAxisAlignment | MainAxisAlignment? | MainAxisAlignment.start | 评分图标与辅助文字的主轴对齐方式 | +| crossAxisAlignment | CrossAxisAlignment? | CrossAxisAlignment.center | 评分图标与辅助文字的交叉轴对齐方式 | +| mainAxisSize | MainAxisSize? | MainAxisSize.min | 评分图标与辅助文字主轴方向上如何占用空间 | +| iconTextGap | double? | - | 评分图标与辅助文字的间距,默认:[TDTheme.of(context).spacer16] | + + + \ No newline at end of file diff --git a/tdesign-site/src/side-bar/README.md b/tdesign-site/src/side-bar/README.md index 2d832e2af..98e348685 100644 --- a/tdesign-site/src/side-bar/README.md +++ b/tdesign-site/src/side-bar/README.md @@ -60,6 +60,7 @@ import 'package:tdesign_flutter/tdesign_flutter.dart'; ); var demoHeight = MediaQuery.of(context).size.height; + _sideBarController.init(list); return Row( children: [ @@ -197,6 +198,7 @@ import 'package:tdesign_flutter/tdesign_flutter.dart'; ); var demoHeight = MediaQuery.of(context).size.height; + _sideBarController.init(list); return Row( children: [ From 0cc2e2250a442468a6cef4980d85432f5fa47ee4 Mon Sep 17 00:00:00 2001 From: Luozf12345 <2515187986@qq.com> Date: Tue, 15 Oct 2024 22:09:24 +0800 Subject: [PATCH 30/46] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E7=BB=84=E4=BB=B6?= =?UTF-8?q?=E6=95=B0=E9=87=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tdesign-site/site/docs/overview.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tdesign-site/site/docs/overview.md b/tdesign-site/site/docs/overview.md index 1da453b81..c1895c3f3 100644 --- a/tdesign-site/site/docs/overview.md +++ b/tdesign-site/site/docs/overview.md @@ -63,7 +63,7 @@ spline: explain
-

导航7

+

导航8

-

输入12

+

输入14

-->
-

数据展示10

+

数据展示12

-

反馈7

+

反馈8

+
diff --git a/tdesign-site/site/site.config.mjs b/tdesign-site/site/site.config.mjs index 580634a2c..fd9278b5d 100644 --- a/tdesign-site/site/site.config.mjs +++ b/tdesign-site/site/site.config.mjs @@ -218,13 +218,13 @@ export default { path: '/flutter/components/radio', component: () => import('@/radio/README.md'), }, - // { - // title: 'Rate 评分', - // name: 'rate', - // meta: { docType: 'form' }, - // path: '/flutter/components/rate', - // component: () => import('@/rate/README.md'), - // }, + { + title: 'Rate 评分', + name: 'rate', + meta: { docType: 'form' }, + path: '/flutter/components/rate', + component: () => import('@/rate/README.md'), + }, { title: 'Search 搜索框', name: 'search', From 9a3a422d58df274938d815be038fad46a0a0452a Mon Sep 17 00:00:00 2001 From: Luozf12345 <2515187986@qq.com> Date: Wed, 16 Oct 2024 15:13:08 +0800 Subject: [PATCH 36/46] =?UTF-8?q?=E6=B7=BB=E5=8A=A0ChangeLog?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tdesign-component/CHANGELOG.md | 49 ++++++++++++++++++++++++++++++++++ tdesign-component/README.md | 2 +- 2 files changed, 50 insertions(+), 1 deletion(-) diff --git a/tdesign-component/CHANGELOG.md b/tdesign-component/CHANGELOG.md index 8e61f36e3..2193faa1e 100644 --- a/tdesign-component/CHANGELOG.md +++ b/tdesign-component/CHANGELOG.md @@ -1,3 +1,52 @@ +## 🌈 0.1.7 `2024-10-16` +### 🚀 Features +- `TDNoticeBar`: Added noticeBar component @ccXxx1aoBai ([#162](https://github.com/Tencent/tdesign-flutter/pull/162)) +- `Result`: Added Result component @shinyina ([#220](https://github.com/Tencent/tdesign-flutter/pull/220)) +- `TimeCounter`: Timer component supports time display beyond conversion units, original TDCountDown component renamed to TimeCounter @hkaikai ([#272](https://github.com/Tencent/tdesign-flutter/pull/272)) +- `Calendar`: Added Calendar component @hkaikai ([#271](https://github.com/Tencent/tdesign-flutter/pull/271)) +- `Indexes`: Added Indexes component @hkaikai ([#321](https://github.com/Tencent/tdesign-flutter/pull/321)) +- `Table`: Added table component @ccXxx1aoBai ([#244](https://github.com/Tencent/tdesign-flutter/pull/244)) +- `Rate`: Added Rate component @hkaikai ([#338](https://github.com/Tencent/tdesign-flutter/pull/338)) +- `Dialog`: Supports custom content padding and buttons @ccXxx1aoBai ([#289](https://github.com/Tencent/tdesign-flutter/pull/289)) +- `Drawer`: Supports controlling the visibility of the divider, custom drawer background color, and controlling the display of the last divider @ccXxx1aoBai ([#278](https://github.com/Tencent/tdesign-flutter/pull/278)) +- `DropdownMenu`: Added control parameters for icon/width/height/icon and text alignment @hkaikai ([#297](https://github.com/Tencent/tdesign-flutter/pull/297)) +- `Search`: Added action and onActionClick properties @Ezer015 ([#263](https://github.com/Tencent/tdesign-flutter/pull/263)) +- `Avatar`: Added onTap event @ccXxx1aoBai ([#344](https://github.com/Tencent/tdesign-flutter/pull/344)) +- `TDDropdownMenu`: Added tabBarFlex parameter to TDDropdownItem to control width ratio @hkaikai ([#338](https://github.com/Tencent/tdesign-flutter/pull/338)) +- `SearchBar`: Feature/td searchbarfix added cursor height property @shizhe2018 ([#337](https://github.com/Tencent/tdesign-flutter/pull/337)) +- `TimeCounter`: Added forward timing function @epoll-j ([#246](https://github.com/Tencent/tdesign-flutter/pull/246)) +- `NavBar`: [NavBar] supports setting bottom shadow @ccXxx1aoBai ([#284](https://github.com/Tencent/tdesign-flutter/pull/284)) +- `Cell`: Added custom padding parameter @epoll-j ([#276](https://github.com/Tencent/tdesign-flutter/pull/276)) +- `Input`: Added onTapOutside callback @epoll-j ([#280](https://github.com/Tencent/tdesign-flutter/pull/280)) +- `Picker`: Added custom leftText, rightText @epoll-j ([#301](https://github.com/Tencent/tdesign-flutter/pull/301)) +- `Slider`: Feature/tdslider added text wrapping function @shizhe2018 ([#329](https://github.com/Tencent/tdesign-flutter/pull/329)) +- `Radio`: Feature/tdRadioGroup added built-in line wrapping, set number of rows and columns @shizhe2018 ([#331](https://github.com/Tencent/tdesign-flutter/pull/331)) +- `Dialog`: Added custom input box @shizhe2018 ([#333](https://github.com/Tencent/tdesign-flutter/pull/333)) +- `TDNavBar`: Added flexibleSpace parameter @Luozf12345 ([#341](https://github.com/Tencent/tdesign-flutter/pull/341)) +- `TDSearch`: Added search box focus acquisition and clear events @Luozf12345 ([#342](https://github.com/Tencent/tdesign-flutter/pull/342)) + +### 🐞 Bug Fixes +- `ImageViewer`: Fixed defaultIndex invalid issue @ccXxx1aoBai ([#292](https://github.com/Tencent/tdesign-flutter/pull/292)) +- `TimeCounter`: Fixed issue where it could not be reset repeatedly @hkaikai ([#272](https://github.com/Tencent/tdesign-flutter/pull/272)) +- `DropdownMenu`: Adjusted popup layer logic, fixed issue where back button could not be listened to @hkaikai ([#297](https://github.com/Tencent/tdesign-flutter/pull/297)) +- `DatePicker`: Removed monitoring on year, month, and day when destroyed to avoid memory leaks; added onSelectedItemChanged event @hkaikai ([#300](https://github.com/Tencent/tdesign-flutter/pull/300)) +- `SideBar`: Fixed issue where custom selected style text was not centered @ccXxx1aoBai ([#313](https://github.com/Tencent/tdesign-flutter/pull/313)) +- `Popup`: Fixed issue where multiple returns occurred when quickly clicking the mask @ccXxx1aoBai ([#318](https://github.com/Tencent/tdesign-flutter/pull/318)) +- `ImageViewer`: Fixed issue where deleting the first image caused display anomalies @ccXxx1aoBai ([#322](https://github.com/Tencent/tdesign-flutter/pull/322)) +- `SideBar`: Fixed issue where delayed loading components caused anchor point function anomalies @ccXxx1aoBai ([#343](https://github.com/Tencent/tdesign-flutter/pull/343)) +- `TDDropdownMenu`: Optimized menu display text to show ellipsis when exceeding display limit @hkaikai ([#338](https://github.com/Tencent/tdesign-flutter/pull/338)) +- `NoticeBar`: Fixed issue where it could not follow the theme color @ccXxx1aoBai ([#350](https://github.com/Tencent/tdesign-flutter/pull/350)) +- `Button`: Fixed overflow issue when setting shape to square or circle @epoll-j ([#257](https://github.com/Tencent/tdesign-flutter/pull/257)) +- `Slider`: Bugfix: Fixed issue where tb_slider setState did not update @arvinwli ([#298](https://github.com/Tencent/tdesign-flutter/pull/298)) +- `Cascader`: Fixed list sorting issue @shizhe2018 ([#303](https://github.com/Tencent/tdesign-flutter/pull/303)) +- `Popup`: Fixed issue where the keyboard would cover the input box in the Popup @epoll-j ([#264](https://github.com/Tencent/tdesign-flutter/pull/264)) +- `Cascader`: Fixed linkage time limit range logic @shizhe2018 ([#242](https://github.com/Tencent/tdesign-flutter/pull/242)) +- `Loading`: Fixed issue where dismissing Loading immediately after showing did not take effect @Luozf12345 ([#340](https://github.com/Tencent/tdesign-flutter/pull/340)) + +### 🚧 Others +- fix: remove useless output. @Ives7 ([#311](https://github.com/Tencent/tdesign-flutter/pull/311)) + + ## 🌈 0.1.6 `2024-07-24` diff --git a/tdesign-component/README.md b/tdesign-component/README.md index 717af01e1..69875af7c 100644 --- a/tdesign-component/README.md +++ b/tdesign-component/README.md @@ -51,7 +51,7 @@ flutter: ">=3.7.0" # Feedback - feedback + feedback # Open source agreement: From ff4ae7b406815548c9ef9a18971253a168699df1 Mon Sep 17 00:00:00 2001 From: Luozf12345 <2515187986@qq.com> Date: Wed, 16 Oct 2024 15:32:03 +0800 Subject: [PATCH 37/46] =?UTF-8?q?=E6=B7=BB=E5=8A=A0ChangeLog?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tdesign-site/CHANGELOG.md | 109 ++++++++++++++++++++++++++++---------- 1 file changed, 81 insertions(+), 28 deletions(-) diff --git a/tdesign-site/CHANGELOG.md b/tdesign-site/CHANGELOG.md index 151333f91..5a2b8faa8 100644 --- a/tdesign-site/CHANGELOG.md +++ b/tdesign-site/CHANGELOG.md @@ -5,34 +5,87 @@ toc: false docClass: timeline --- -## 🌈 0.1.6 `2024-07-24` -### 🚀 Features -- `Cell`: 新增 Cell 单元格 组件 @hkaikai ([#150](https://github.com/Tencent/tdesign-flutter/pull/150)) -- `Drawer`: 新增Drawer 抽屉 组件 @hkaikai ([#178](https://github.com/Tencent/tdesign-flutter/pull/178)) -- `SwipeCell`: 新增SwipeCell 滑动操作 组件 @hkaikai ([#218](https://github.com/Tencent/tdesign-flutter/pull/218)) -- `Steps`: 新增 Steps 步骤条 组件 @aaronmhl ([#199](https://github.com/Tencent/tdesign-flutter/pull/199)) -- `ImageViewer`: 新增ImageViewer 图片预览 组件 @ccXxx1aoBai ([#187](https://github.com/Tencent/tdesign-flutter/pull/187)) -- `Cascader`:新增 Cascader 级联选择器 组件@shizhe2018 ([#195](https://github.com/Tencent/tdesign-flutter/pull/195)) -- `Fab`:新增 Fab 悬浮按钮 组件 @TingShine ([#239](https://github.com/Tencent/tdesign-flutter/pull/239)) -- `BackTop`:新增 BackTop 返回顶部 组件 @TingShine ([#239](https://github.com/Tencent/tdesign-flutter/pull/239)) -- `TreeSelect`:新增 TreeSelect 树形选择器 组件 @TingShine ([#239](https://github.com/Tencent/tdesign-flutter/pull/239)) -- `Collapse`:新增 Collapse 折叠面板 组件 @dorayx ([#239](https://github.com/Tencent/tdesign-flutter/pull/239)) -- `Input`: 新增inputAction API,支持设置键盘行为;新增spacer API,可自定义组件间距 @ccXxx1aoBai ([#184](https://github.com/Tencent/tdesign-flutter/pull/184)) -- `Text`: 增加全局字体配置和加载网络字体的能力 @Luozf12345 ([#232](https://github.com/Tencent/tdesign-flutter/pull/232)) -- `CountDown`: 添加 开始/重置/暂停/继续 的控制功能 @hkaikai ([#175](https://github.com/Tencent/tdesign-flutter/pull/175)) -- `Popup`: 支持位置,大小设置 @hkaikai ([#191](https://github.com/Tencent/tdesign-flutter/pull/191)) -### 🐞 Bug Fixes -- `Toast`: 解决duration属性无效问题 @ccXxx1aoBai ([#167](https://github.com/Tencent/tdesign-flutter/pull/167)) -- `Tnput`: 解决label溢出问题 @ccXxx1aoBai ([#184](https://github.com/Tencent/tdesign-flutter/pull/184)) -- `Tabs`:tabs组件outlineType为capsule支持设置选中和未选中tab背景色,outlineType为card支持设置选中tab背景色 @ccXxx1aoBai -- `Button`: 修复setState方法下属性无法改变的问题 @shizhe2018 ([#201](https://github.com/Tencent/tdesign-flutter/pull/201)) -- `SearchBar`:搜索框增加控制器,允许外部清除搜索文本 @shizhe2018 ([#194](https://github.com/Tencent/tdesign-flutter/pull/194)) -- `Slider`: 新增自定义Decoration样式 @shizhe2018 ([#198](https://github.com/Tencent/tdesign-flutter/pull/198)) -- `Empty`: 新增文字大小样式 api @shizhe2018 ([#219](https://github.com/Tencent/tdesign-flutter/pull/219)) -- `Dialog`: 新增input类型背景 @shizhe2018 ([#238](https://github.com/Tencent/tdesign-flutter/pull/238)) -### 🚧 Others -- 鸿蒙编译支持 @hkaikai ([#233](https://github.com/Tencent/tdesign-flutter/pull/233)) -- 修改主题适配工具 @Luozf12345 + +## 🌈 0.1.7 `2024-10-16` +### 🚀 Features +- `TDNoticeBar`: 新增noticeBar组件 @ccXxx1aoBai ([#162](https://github.com/Tencent/tdesign-flutter/pull/162)) +- `Result`: 新增Result结果组件 @shinyina ([#220](https://github.com/Tencent/tdesign-flutter/pull/220)) +- `TimeCounter`: 计时组件支持超过转换单位的时间展示,原TDCountDown组件改名为TimeCounter @hkaikai ([#272](https://github.com/Tencent/tdesign-flutter/pull/272)) +- `Calendar`: 新增Calendar 日历组件 @hkaikai ([#271](https://github.com/Tencent/tdesign-flutter/pull/271)) +- `Indexes`: 新增索引组件 @hkaikai ([#321](https://github.com/Tencent/tdesign-flutter/pull/321)) +- `Table`: 新增table组件 @ccXxx1aoBai ([#244](https://github.com/Tencent/tdesign-flutter/pull/244)) +- `Rate`: 新增Rate组件 @ hkaikai ([#338](https://github.com/Tencent/tdesign-flutter/pull/338)) +- `Dialog`: 支持自定义内容内边距和按钮 @ccXxx1aoBai ([#289](https://github.com/Tencent/tdesign-flutter/pull/289)) +- `Drawer`: 支持控制分割线显隐,支持自定义抽屉背景色,支持控制显示最后一条分割线 @ccXxx1aoBai ([#278](https://github.com/Tencent/tdesign-flutter/pull/278)) +- `DropdownMenu`: 新增 图标/宽度/高度/图标和文字的对齐方式 控制参数 @hkaikai ([#297](https://github.com/Tencent/tdesign-flutter/pull/297)) +- `Search`: 增加action和onActionClick属性 @Ezer015 ([#263](https://github.com/Tencent/tdesign-flutter/pull/263)) +- `Avatar`: 增加onTap事件 @ccXxx1aoBai ([#344](https://github.com/Tencent/tdesign-flutter/pull/344)) +- `TDDropdownMenu`: TDDropdownItem新增tabBarFlex参数,控制宽度占比 @hkaikai ([#338](https://github.com/Tencent/tdesign-flutter/pull/338)) +- `SearchBar`:Feature/td searchbarfix 新增光标高属性 @shizhe2018 ([#337](https://github.com/Tencent/tdesign-flutter/pull/337)) +- `TimeCounter`: 添加正向计时功能 @epoll-j ([#246](https://github.com/Tencent/tdesign-flutter/pull/246)) +- `NavBar `:[NavBar]支持设置底部阴影 @ccXxx1aoBai ([#284](https://github.com/Tencent/tdesign-flutter/pull/284)) +- `Cell`: 添加自定义padding参数 @epoll-j ([#276](https://github.com/Tencent/tdesign-flutter/pull/276)) +- `Input`: 增加onTapOutside回调 @epoll-j ([#280](https://github.com/Tencent/tdesign-flutter/pull/280)) +- `Picker`: 增加自定义leftText、rightText @epoll-j ([#301](https://github.com/Tencent/tdesign-flutter/pull/301)) +- `Slider`:Feature/tdslider 新增文本换行功能 @shizhe2018 ([#329](https://github.com/Tencent/tdesign-flutter/pull/329)) +- `Radio`:Feature/tdRadioGroup 新增自带换行,设置行列数 @shizhe2018 ([#331](https://github.com/Tencent/tdesign-flutter/pull/331)) +- `Dialog`:新增自定义输入框 @shizhe2018 ([#333](https://github.com/Tencent/tdesign-flutter/pull/333)) +- `TDNavBar`:添加flexibleSpace参数 @Luozf12345 ([#341](https://github.com/Tencent/tdesign-flutter/pull/341)) +- `TDSearch`:添加搜索框焦点获取及清除事件 @Luozf12345 ([#342](https://github.com/Tencent/tdesign-flutter/pull/342)) + + +### 🐞 Bug Fixes +- `ImageViewer`: 解决defaultIndex无效问题 @ccXxx1aoBai ([#292](https://github.com/Tencent/tdesign-flutter/pull/292)) +- `TimeCounter`: 修复无法重复重置问题 @hkaikai ([#272](https://github.com/Tencent/tdesign-flutter/pull/272)) +- `DropdownMenu`: 调整弹出层逻辑,修复无法监听后退问题; @hkaikai ([#297](https://github.com/Tencent/tdesign-flutter/pull/297)) +- `DatePicker`: 销毁时移除年月日上监控,避免内存泄露;新增onSelectedItemChanged事件 @hkaikai ([#300](https://github.com/Tencent/tdesign-flutter/pull/300)) +- `SideBar`: 解决自定义选中样式文字不居中问题 @ccXxx1aoBai ([#313](https://github.com/Tencent/tdesign-flutter/pull/313)) +- `Popup`: 解决快速点击蒙层多次返回问题 @ccXxx1aoBai ([#318](https://github.com/Tencent/tdesign-flutter/pull/318)) +- `ImageViewer`: 解决删除首位图片显示异常问题 @ccXxx1aoBai ([#322](https://github.com/Tencent/tdesign-flutter/pull/322)) +- `SideBar`: 解决延迟加载组件导致瞄点功能异常问题 @ccXxx1aoBai ([#343](https://github.com/Tencent/tdesign-flutter/pull/343)) +- `TDDropdownMenu`: 优化menu显示文字超出显示省略号 @hkaikai ([#338](https://github.com/Tencent/tdesign-flutter/pull/338)) +- `NoticeBar`: 解决无法跟随主题色问题 @ccXxx1aoBai ([#350](https://github.com/Tencent/tdesign-flutter/pull/350)) +- `Button`: 修复设置shape为square或circle时出现overflow @epoll-j ([#257](https://github.com/Tencent/tdesign-flutter/pull/257)) +- `Slider`: bugfix:修复tb_slider setState不更新问题 @arvinwli ([#298](https://github.com/Tencent/tdesign-flutter/pull/298)) +- `Cascader`: 修改列表排序问题 @shizhe2018 ([#303](https://github.com/Tencent/tdesign-flutter/pull/303)) +- `Popup`:解决键盘出现会遮挡Popup里的输入框 @epoll-j ([#264](https://github.com/Tencent/tdesign-flutter/pull/264)) +- `Cascader`:修改联动时间限制范围逻辑 @shizhe2018 ([#242](https://github.com/Tencent/tdesign-flutter/pull/242)) +- `Loading`:修复Loading显示后立即dismiss无法生效的问题 @Luozf12345 ([#340](https://github.com/Tencent/tdesign-flutter/pull/340)) + + +### 🚧 Others +- fix: remove useless output. @Ives7 ([#311](https://github.com/Tencent/tdesign-flutter/pull/311)) + + + +## 🌈 0.1.6 `2024-07-24` +### 🚀 Features +- `Cell`: 新增 Cell 单元格 组件 @hkaikai ([#150](https://github.com/Tencent/tdesign-flutter/pull/150)) +- `Drawer`: 新增Drawer 抽屉 组件 @hkaikai ([#178](https://github.com/Tencent/tdesign-flutter/pull/178)) +- `SwipeCell`: 新增SwipeCell 滑动操作 组件 @hkaikai ([#218](https://github.com/Tencent/tdesign-flutter/pull/218)) +- `Steps`: 新增 Steps 步骤条 组件 @aaronmhl ([#199](https://github.com/Tencent/tdesign-flutter/pull/199)) +- `ImageViewer`: 新增ImageViewer 图片预览 组件 @ccXxx1aoBai ([#187](https://github.com/Tencent/tdesign-flutter/pull/187)) +- `Cascader`:新增 Cascader 级联选择器 组件@shizhe2018 ([#195](https://github.com/Tencent/tdesign-flutter/pull/195)) +- `Fab`:新增 Fab 悬浮按钮 组件 @TingShine ([#239](https://github.com/Tencent/tdesign-flutter/pull/239)) +- `BackTop`:新增 BackTop 返回顶部 组件 @TingShine ([#239](https://github.com/Tencent/tdesign-flutter/pull/239)) +- `TreeSelect`:新增 TreeSelect 树形选择器 组件 @TingShine ([#239](https://github.com/Tencent/tdesign-flutter/pull/239)) +- `Collapse`:新增 Collapse 折叠面板 组件 @dorayx ([#239](https://github.com/Tencent/tdesign-flutter/pull/239)) +- `Input`: 新增inputAction API,支持设置键盘行为;新增spacer API,可自定义组件间距 @ccXxx1aoBai ([#184](https://github.com/Tencent/tdesign-flutter/pull/184)) +- `Text`: 增加全局字体配置和加载网络字体的能力 @Luozf12345 ([#232](https://github.com/Tencent/tdesign-flutter/pull/232)) +- `CountDown`: 添加 开始/重置/暂停/继续 的控制功能 @hkaikai ([#175](https://github.com/Tencent/tdesign-flutter/pull/175)) +- `Popup`: 支持位置,大小设置 @hkaikai ([#191](https://github.com/Tencent/tdesign-flutter/pull/191)) +### 🐞 Bug Fixes +- `Toast`: 解决duration属性无效问题 @ccXxx1aoBai ([#167](https://github.com/Tencent/tdesign-flutter/pull/167)) +- `Tnput`: 解决label溢出问题 @ccXxx1aoBai ([#184](https://github.com/Tencent/tdesign-flutter/pull/184)) +- `Tabs`:tabs组件outlineType为capsule支持设置选中和未选中tab背景色,outlineType为card支持设置选中tab背景色 @ccXxx1aoBai +- `Button`: 修复setState方法下属性无法改变的问题 @shizhe2018 ([#201](https://github.com/Tencent/tdesign-flutter/pull/201)) +- `SearchBar`:搜索框增加控制器,允许外部清除搜索文本 @shizhe2018 ([#194](https://github.com/Tencent/tdesign-flutter/pull/194)) +- `Slider`: 新增自定义Decoration样式 @shizhe2018 ([#198](https://github.com/Tencent/tdesign-flutter/pull/198)) +- `Empty`: 新增文字大小样式 api @shizhe2018 ([#219](https://github.com/Tencent/tdesign-flutter/pull/219)) +- `Dialog`: 新增input类型背景 @shizhe2018 ([#238](https://github.com/Tencent/tdesign-flutter/pull/238)) +### 🚧 Others +- 鸿蒙编译支持 @hkaikai ([#233](https://github.com/Tencent/tdesign-flutter/pull/233)) +- 修改主题适配工具 @Luozf12345 - 演示代码新增完整页面的github链接 @Luozf12345 ## 🌈 0.1.5 `2024-05-31` From b0556fc9df353916c348de5a1778b54524cac027 Mon Sep 17 00:00:00 2001 From: ccXxx1aoBai <1426169428@qq.com> Date: Wed, 16 Oct 2024 17:49:30 +0800 Subject: [PATCH 38/46] =?UTF-8?q?=E8=A7=A3=E5=86=B3web=E7=AB=AF=E6=96=87?= =?UTF-8?q?=E5=AD=97=E9=AB=98=E5=BA=A6=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../components/notice_bar/td_notice_bar.dart | 34 +++++++++++++------ 1 file changed, 24 insertions(+), 10 deletions(-) diff --git a/tdesign-component/lib/src/components/notice_bar/td_notice_bar.dart b/tdesign-component/lib/src/components/notice_bar/td_notice_bar.dart index cc4039ed0..b78777f51 100644 --- a/tdesign-component/lib/src/components/notice_bar/td_notice_bar.dart +++ b/tdesign-component/lib/src/components/notice_bar/td_notice_bar.dart @@ -241,6 +241,14 @@ class _TDNoticeBarState extends State { (_size!.width - _style!.getPadding.horizontal); } + /// 获取文字高度 + double _getTextHeight() { + if(identical(0, 0.0)) { + return widget.height; + } + return _getFontSize().height; + } + /// 内容区域 Widget _contextWidget() { var valid = false; @@ -251,11 +259,14 @@ class _TDNoticeBarState extends State { height: widget.height, child: Align( alignment: Alignment.centerLeft, - child: TDText( - widget.context, - style: _style?.getTextStyle, - maxLines: 1, - forceVerticalCenter: true, + child: SizedBox( + height: _getTextHeight(), + child: TDText( + widget.context, + style: _style?.getTextStyle, + maxLines: 1, + forceVerticalCenter: true, + ), ), ), ); @@ -266,11 +277,14 @@ class _TDNoticeBarState extends State { height: widget.height, child: Align( alignment: Alignment.centerLeft, - child: TDText( - widget.context[0], - style: _style?.getTextStyle, - maxLines: 1, - forceVerticalCenter: true, + child: SizedBox( + height: _getTextHeight(), + child: TDText( + widget.context[0], + style: _style?.getTextStyle, + maxLines: 1, + forceVerticalCenter: true, + ), ), ), ); From 4241db39e3c74680280375562a5bea77ea59b908 Mon Sep 17 00:00:00 2001 From: v_szheshi Date: Fri, 18 Oct 2024 16:54:20 +0800 Subject: [PATCH 39/46] =?UTF-8?q?=E6=96=B0=E5=A2=9E=E7=AC=AC=E4=B8=80?= =?UTF-8?q?=E5=B1=82=E7=82=B9=E5=87=BB=E9=80=89=E6=8B=A9=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../lib/src/components/cascader/td_multi_cascader.dart | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tdesign-component/lib/src/components/cascader/td_multi_cascader.dart b/tdesign-component/lib/src/components/cascader/td_multi_cascader.dart index f793f95ae..c81b01b7d 100644 --- a/tdesign-component/lib/src/components/cascader/td_multi_cascader.dart +++ b/tdesign-component/lib/src/components/cascader/td_multi_cascader.dart @@ -353,7 +353,7 @@ class _TDMultiCascaderState extends State with TickerProviderSt return GestureDetector( onTap: () { int level = 0; - if (_tabListData.length > 2 && _currentTabIndex == 0) { + if (item.level ==0 && _currentTabIndex == 0) { _tabListData.clear(); _tabListData.add(MultiCascaderListModel( label: '选择选项', @@ -439,7 +439,7 @@ class _TDMultiCascaderState extends State with TickerProviderSt void _getChildrenListData(int level, String value) { //查询层级数据 - var selectLevelData = _listData.where((element) => element.level == (level)).toList(); + var selectLevelData = _listData.where((element) => element.level == (level)&&element.parentValue==value).toList(); //判断下级是否存在 if (selectLevelData.isNotEmpty) { //获取下级数据 From 7b5daab623437fe58f7aee059623235fd6d8161f Mon Sep 17 00:00:00 2001 From: hkaikai <617760820@qq.com> Date: Sat, 19 Oct 2024 19:19:37 +0800 Subject: [PATCH 40/46] =?UTF-8?q?disabled=20=E5=8A=9F=E8=83=BD=E6=94=AF?= =?UTF-8?q?=E6=8C=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../lib/src/components/rate/td_rate.dart | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/tdesign-component/lib/src/components/rate/td_rate.dart b/tdesign-component/lib/src/components/rate/td_rate.dart index bd5bf8606..06dc1e567 100644 --- a/tdesign-component/lib/src/components/rate/td_rate.dart +++ b/tdesign-component/lib/src/components/rate/td_rate.dart @@ -197,17 +197,29 @@ class _TDRateState extends State with TickerProviderStateMixin { children: [ GestureDetector( onTapDown: (event) { + if (widget.disabled == true) { + return; + } _isClick = true; }, onTapUp: (details) { + if (widget.disabled == true) { + return; + } _changeSelect(details.globalPosition, true); _hideTip(); }, onHorizontalDragUpdate: (details) { + if (widget.disabled == true) { + return; + } _isClick = false; _changeSelect(details.globalPosition); }, onHorizontalDragEnd: (details) { + if (widget.disabled == true) { + return; + } _hideTip(); }, child: Row( From b1ec23648e27e672218f4eef2737d30d644ca4d5 Mon Sep 17 00:00:00 2001 From: Simon_Wzy <1691663479@qq.com> Date: Tue, 22 Oct 2024 10:54:05 +0800 Subject: [PATCH 41/46] =?UTF-8?q?TODO:=20=E6=96=B0=E5=A2=9E=20TDRated=20?= =?UTF-8?q?=E8=AE=BE=E8=AE=A1=E7=A8=BF=E5=AF=B9=E6=AF=94=20=E6=B5=8B?= =?UTF-8?q?=E8=AF=95=E7=BB=84=E4=BB=B6=20API=20=E8=A1=A5=E5=85=A8=20Proble?= =?UTF-8?q?m:=20TDTextare=20=E8=83=8C=E6=99=AF=E9=A2=9C=E8=89=B2=E9=97=AE?= =?UTF-8?q?=E9=A2=98=20TDRadioGroup=20=E9=AB=98=E5=BA=A6=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 竖直态文字对齐 padding 问题 组相连选择器 时间选择器 没有 禁用态 竖直态问题 --- .../example/android/build.gradle | 2 +- .../example/lib/page/td_form_page.dart | 16 +- .../lib/src/components/form/td_form_item.dart | 639 +++++++++--------- 3 files changed, 317 insertions(+), 340 deletions(-) diff --git a/tdesign-component/example/android/build.gradle b/tdesign-component/example/android/build.gradle index 38f569bae..53e7c1ac5 100644 --- a/tdesign-component/example/android/build.gradle +++ b/tdesign-component/example/android/build.gradle @@ -1,5 +1,5 @@ buildscript { - ext.kotlin_version = '1.6.21' + ext.kotlin_version = '1.9.0' ext { diff --git a/tdesign-component/example/lib/page/td_form_page.dart b/tdesign-component/example/lib/page/td_form_page.dart index f45fb26c1..bb3bc9d4e 100644 --- a/tdesign-component/example/lib/page/td_form_page.dart +++ b/tdesign-component/example/lib/page/td_form_page.dart @@ -146,49 +146,49 @@ class _TDFormPageState extends State { items: [ TDFormItem( label: '用户名', - name: 'name', + type: TDFormItemType.input, help: '请输入用户名', - additionInfo: '输入用户名', + // additionInfo: '输入用户名', labelWidth: 15.0, controller: controller[0], ), TDFormItem( label: '密码', - name: 'password', + type: TDFormItemType.password, help: '请输入密码', labelWidth: 35.0, controller: controller[1], ), TDFormItem( label: '性别', - name: 'radios', + type: TDFormItemType.radios, /// 扩展一下数量和选项内容 radios: _radios, ), TDFormItem( label: '生日', - name: 'date', + type: TDFormItemType.dateTimePicker, /// 引入需要的日期数据 select: selected_1, ), TDFormItem( label: '籍贯', - name: 'local', + type: TDFormItemType.cascader, /// 引入需要的地点数据 localData: _data, ), TDFormItem( label: '年限', - name: 'stepper', + type: TDFormItemType.stepper, /// 为 TDStepper 预留其他设置 ), TDFormItem( label: '个人简介', - name: 'textarea', + type: TDFormItemType.textarea, help: '请输入个人简介', controller: controller[2], diff --git a/tdesign-component/lib/src/components/form/td_form_item.dart b/tdesign-component/lib/src/components/form/td_form_item.dart index a0a0fe428..83b51e1ec 100644 --- a/tdesign-component/lib/src/components/form/td_form_item.dart +++ b/tdesign-component/lib/src/components/form/td_form_item.dart @@ -4,8 +4,8 @@ import '../../../tdesign_flutter.dart'; class TDFormItem extends StatefulWidget { TDFormItem({ + required this.type, this.label, - this.name, this.arrow = false, this.contentAlign = 'left', this.help, @@ -29,6 +29,9 @@ class TDFormItem extends StatefulWidget { /// 表单项标签内容 final String? label; + /// 表格单元需要使用的组件类型 + final TDFormItemType type; + /// 表单内容对齐方式:'left' 或 'right' final String? contentAlign; @@ -47,9 +50,6 @@ class TDFormItem extends StatefulWidget { /// 标签宽度,如果提供则覆盖Form的labelWidth final double? labelWidth; - /// 表单项标识符 - final String? name; - /// Input 控制器 var controller; @@ -82,6 +82,17 @@ class TDFormItem extends StatefulWidget { _TDFormItemState createState() => _TDFormItemState(); } +/// 表格单元选用组件类型的枚举 +enum TDFormItemType { + input, + password, + radios, + dateTimePicker, + cascader, + stepper, + textarea +} + class _TDFormItemState extends State { double get LabelWidth { final inherited = TDFormInherited.of(context); @@ -125,118 +136,229 @@ class _TDFormItemState extends State { @override Widget build(BuildContext context) { if (FormIsHorizontal) { - if (widget.name == 'name') { - return TDInput( - inputDecoration: InputDecoration( - hintText: widget.help, - contentPadding: EdgeInsets.only(left: LabelWidth), - border: InputBorder.none, - ), - leftLabel: widget.label, - controller: widget.controller, - backgroundColor: Colors.white, - additionInfo: widget.additionInfo, - readOnly: FormState, - ); - } else if (widget.name == 'password') { - return TDInput( - inputDecoration: InputDecoration( - hintText: widget.help, - contentPadding: EdgeInsets.only(left: LabelWidth), - border: InputBorder.none, - ), - type: TDInputType.normal, - controller: widget.controller, - obscureText: !browseOn, - leftLabel: widget.label, - backgroundColor: Colors.white, - rightBtn: browseOn - ? Icon( - TDIcons.browse, - color: TDTheme.of(context).fontGyColor3, - ) - : Icon( - TDIcons.browse_off, - color: TDTheme.of(context).fontGyColor3, - ), - onBtnTap: () { - setState(() { - browseOn = !browseOn; - }); - }, - needClear: false, - readOnly: FormState, - ); - } else if (widget.name == 'radios') { - final theme = TDTheme.of(context); - return Container( - decoration: BoxDecoration( - color: theme.whiteColor1, - ), - child: Padding( - padding: EdgeInsets.all(16), - child: Row( - crossAxisAlignment: CrossAxisAlignment.center, - children: [ - TDText( - widget.label ?? '', - style: const TextStyle(fontSize: 16), - ), - const SizedBox(width: 16), - Expanded( - child: TDRadioGroup( - selectId: 'index:1', - direction: Axis.horizontal, - directionalTdRadios: widget.radios.entries.map((entry) { - return TDRadio( - id: entry.key, - title: entry.value, - radioStyle: TDRadioStyle.circle, - showDivider: false, - enable: !FormState, - ); - }).toList(), - ), - ), - ], + switch (widget.type) { + case TDFormItemType.input: + return TDInput( + inputDecoration: InputDecoration( + hintText: widget.help, + contentPadding: EdgeInsets.only(left: LabelWidth), + border: InputBorder.none, ), - ), - ); - } else if (widget.name == 'date') { - return GestureDetector( - onTap: () { - TDPicker.showDatePicker(context, title: '选择时间', - onConfirm: (selected) { + leftLabel: widget.label, + controller: widget.controller, + backgroundColor: Colors.white, + // additionInfo: widget.additionInfo, + readOnly: FormState, + ); + case TDFormItemType.password: + return TDInput( + inputDecoration: InputDecoration( + hintText: widget.help, + contentPadding: EdgeInsets.only(left: LabelWidth), + border: InputBorder.none, + ), + type: TDInputType.normal, + controller: widget.controller, + obscureText: !browseOn, + leftLabel: widget.label, + backgroundColor: Colors.white, + rightBtn: browseOn + ? Icon( + TDIcons.browse, + color: TDTheme.of(context).fontGyColor3, + ) + : Icon( + TDIcons.browse_off, + color: TDTheme.of(context).fontGyColor3, + ), + onBtnTap: () { setState(() { - widget.select = - '${selected['year'].toString().padLeft(4, '0')}-${selected['month'].toString().padLeft(2, '0')}-${selected['day'].toString().padLeft(2, '0')}'; + browseOn = !browseOn; }); - Navigator.of(context).pop(); }, - dateStart: [1999, 01, 01], - dateEnd: [2023, 12, 31], - initialDate: [2012, 1, 1]); - }, - child: buildSelectRow(context, widget.select, '选择时间'), - ); - } else if (widget.name == 'radios') { - final theme = TDTheme.of(context); - return Container( - decoration: BoxDecoration( - color: theme.whiteColor1, - ), - child: Padding( - padding: EdgeInsets.all(16), - child: Row( - crossAxisAlignment: CrossAxisAlignment.center, - children: [ - TDText( - widget.label ?? '', - style: const TextStyle(fontSize: 16), + needClear: false, + readOnly: FormState, + ); + case TDFormItemType.radios: + final theme = TDTheme.of(context); + return Container( + decoration: BoxDecoration( + color: theme.whiteColor1, + ), + child: Padding( + padding: EdgeInsets.all(16), + child: Row( + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + TDText( + widget.label ?? '', + style: const TextStyle(fontSize: 16), + ), + const SizedBox(width: 16), + Expanded( + child: TDRadioGroup( + selectId: 'index:1', + direction: Axis.horizontal, + directionalTdRadios: widget.radios.entries.map((entry) { + return TDRadio( + id: entry.key, + title: entry.value, + radioStyle: TDRadioStyle.circle, + showDivider: false, + enable: !FormState, + ); + }).toList(), + ), + ), + ], + ), + ), + ); + case TDFormItemType.dateTimePicker: + return GestureDetector( + onTap: () { + TDPicker.showDatePicker(context, title: '选择时间', + onConfirm: (selected) { + setState(() { + widget.select = + '${selected['year'].toString().padLeft(4, '0')}-${selected['month'].toString().padLeft(2, '0')}-${selected['day'].toString().padLeft(2, '0')}'; + }); + Navigator.of(context).pop(); + }, + dateStart: [1999, 01, 01], + dateEnd: [2023, 12, 31], + initialDate: [2012, 1, 1]); + }, + child: buildSelectRow(context, widget.select, '选择时间'), + ); + case TDFormItemType.cascader: + return GestureDetector( + onTap: () { + TDCascader.showMultiCascader(context, + title: '选择地址', + data: widget.localData, + initialData: _initData, + theme: 'step', + onChange: (List selectData) { + setState(() { + List result = []; + int len = selectData.length; + _initData = selectData[len - 1].value!; + selectData.forEach((element) { + result.add(element.label); + }); + _selected_1 = result.join('/'); + }); + }, onClose: () { + Navigator.of(context).pop(); + }); + }, + child: _buildSelectRow(context, _selected_1, '选择地区'), + ); + case TDFormItemType.stepper: + final theme = TDTheme.of(context); + return Container( + decoration: BoxDecoration( + color: theme.whiteColor1, + ), + child: Padding( + padding: const EdgeInsets.all(16), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + TDText( + widget.label, + style: const TextStyle(fontSize: 16), + ), + TDStepper( + theme: TDStepperTheme.filled, + disabled: FormState, + ), + ], + ), + ), + ); + case TDFormItemType.textarea: + return TDTextarea( + backgroundColor: Colors.red, + controller: widget.controller, + label: widget.label, + hintText: widget.help, + maxLength: widget.maxLength, + indicator: widget.indicator, + readOnly: FormState, + onChanged: (value) { + setState(() {}); + }, + ); + } + } else { + switch (widget.type) { + case TDFormItemType.input: + return TDInput( + type: TDInputType.twoLine, + inputDecoration: InputDecoration( + hintText: widget.help, + border: InputBorder.none, + ), + leftLabel: widget.label, + controller: widget.controller, + backgroundColor: Colors.white, + + /// 竖直态的 TDInput 没用 additionInfo? + additionInfo: widget.additionInfo, + readOnly: FormState, + ); + case TDFormItemType.password: + return Column( + children: [ + TDInput( + inputDecoration: InputDecoration( + hintText: widget.help, + // contentPadding: EdgeInsets.only(left: LabelWidth), + border: InputBorder.none, ), - const SizedBox(width: 16), - Expanded( - child: TDRadioGroup( + type: TDInputType.twoLine, + controller: widget.controller, + obscureText: !browseOn, + leftLabel: widget.label, + backgroundColor: Colors.white, + rightBtn: browseOn + ? Icon( + TDIcons.browse, + color: TDTheme.of(context).fontGyColor3, + ) + : Icon( + TDIcons.browse_off, + color: TDTheme.of(context).fontGyColor3, + ), + onBtnTap: () { + setState(() { + browseOn = !browseOn; + }); + }, + needClear: false, + readOnly: FormState, + ), + ], + ); + case TDFormItemType.radios: + final theme = TDTheme.of(context); + return Container( + decoration: BoxDecoration( + color: theme.whiteColor1, + ), + child: Padding( + padding: const EdgeInsets.all(16), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + TDText( + widget.label ?? '', + style: const TextStyle(fontSize: 16), + ), + const SizedBox(width: 20), + TDRadioGroup( selectId: 'index:1', direction: Axis.horizontal, directionalTdRadios: widget.radios.entries.map((entry) { @@ -249,238 +371,93 @@ class _TDFormItemState extends State { ); }).toList(), ), - ), - ], - ), - ), - ); - } else if (widget.name == 'local') { - return GestureDetector( - onTap: () { - TDCascader.showMultiCascader(context, - title: '选择地址', - data: widget.localData, - initialData: _initData, - theme: 'step', - onChange: (List selectData) { - setState(() { - List result = []; - int len = selectData.length; - _initData = selectData[len - 1].value!; - selectData.forEach((element) { - result.add(element.label); - }); - _selected_1 = result.join('/'); - }); - }, onClose: () { - Navigator.of(context).pop(); - }); - }, - child: _buildSelectRow(context, _selected_1, '选择地区'), - ); - } else if (widget.name == 'stepper') { - final theme = TDTheme.of(context); - return Container( - decoration: BoxDecoration( - color: theme.whiteColor1, - ), - child: Padding( - padding: const EdgeInsets.all(16), - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - TDText( - widget.label, - style: const TextStyle(fontSize: 16), - ), - TDStepper( - theme: TDStepperTheme.filled, - disabled: FormState, - ), - ], - ), - ), - ); - } else if (widget.name == 'textarea') { - return TDTextarea( - backgroundColor: Colors.red, - controller: widget.controller, - label: widget.label, - hintText: widget.help, - maxLength: widget.maxLength, - indicator: widget.indicator, - readOnly: FormState, - onChanged: (value) { - setState(() {}); - }, - ); - } - } else { - if (widget.name == 'name') { - return TDInput( - type: TDInputType.twoLine, - inputDecoration: InputDecoration( - hintText: widget.help, - border: InputBorder.none, - ), - leftLabel: widget.label, - controller: widget.controller, - backgroundColor: Colors.white, - - /// 竖直态的 TDInput 没用 additionInfo? - additionInfo: widget.additionInfo, - readOnly: FormState, - ); - } else if (widget.name == 'password') { - return Column( - children: [ - TDInput( - inputDecoration: InputDecoration( - hintText: widget.help, - // contentPadding: EdgeInsets.only(left: LabelWidth), - border: InputBorder.none, + ], ), - type: TDInputType.twoLine, - controller: widget.controller, - obscureText: !browseOn, - leftLabel: widget.label, - backgroundColor: Colors.white, - rightBtn: browseOn - ? Icon( - TDIcons.browse, - color: TDTheme.of(context).fontGyColor3, - ) - : Icon( - TDIcons.browse_off, - color: TDTheme.of(context).fontGyColor3, - ), - onBtnTap: () { + ), + ); + case TDFormItemType.dateTimePicker: + return GestureDetector( + onTap: () { + TDPicker.showDatePicker(context, title: '选择时间', + onConfirm: (selected) { setState(() { - browseOn = !browseOn; + widget.select = + '${selected['year'].toString().padLeft(4, '0')}-${selected['month'].toString().padLeft(2, '0')}-${selected['day'].toString().padLeft(2, '0')}'; }); + Navigator.of(context).pop(); }, - needClear: false, - readOnly: FormState, - ), - ], - ); - } else if (widget.name == 'radios') { - final theme = TDTheme.of(context); - return Container( - decoration: BoxDecoration( - color: theme.whiteColor1, - ), - child: Padding( - padding: const EdgeInsets.all(16), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - TDText( - widget.label ?? '', - style: const TextStyle(fontSize: 16), - ), - const SizedBox(width: 20), - TDRadioGroup( - selectId: 'index:1', - direction: Axis.horizontal, - directionalTdRadios: widget.radios.entries.map((entry) { - return TDRadio( - id: entry.key, - title: entry.value, - radioStyle: TDRadioStyle.circle, - showDivider: false, - enable: !FormState, - ); - }).toList(), - ), - ], - ), - ), - ); - } else if (widget.name == 'date') { - return GestureDetector( - onTap: () { - TDPicker.showDatePicker(context, title: '选择时间', - onConfirm: (selected) { - setState(() { - widget.select = - '${selected['year'].toString().padLeft(4, '0')}-${selected['month'].toString().padLeft(2, '0')}-${selected['day'].toString().padLeft(2, '0')}'; - }); - Navigator.of(context).pop(); + dateStart: [1999, 01, 01], + dateEnd: [2023, 12, 31], + initialDate: [2012, 1, 1]); }, - dateStart: [1999, 01, 01], - dateEnd: [2023, 12, 31], - initialDate: [2012, 1, 1]); - }, - child: buildSelectRow(context, widget.select, '选择时间'), - ); - } else if (widget.name == 'local') { - return GestureDetector( - onTap: () { - TDCascader.showMultiCascader(context, - title: '选择地址', - data: widget.localData, - initialData: _initData, - theme: 'step', - onChange: (List selectData) { - setState(() { - List result = []; - int len = selectData.length; - _initData = selectData[len - 1].value!; - selectData.forEach((element) { - result.add(element.label); + child: buildSelectRow(context, widget.select, '选择时间'), + ); + case TDFormItemType.cascader: + return GestureDetector( + onTap: () { + TDCascader.showMultiCascader(context, + title: '选择地址', + data: widget.localData, + initialData: _initData, + theme: 'step', + onChange: (List selectData) { + setState(() { + List result = []; + int len = selectData.length; + _initData = selectData[len - 1].value!; + selectData.forEach((element) { + result.add(element.label); + }); + _selected_1 = result.join('/'); }); - _selected_1 = result.join('/'); + }, onClose: () { + Navigator.of(context).pop(); }); - }, onClose: () { - Navigator.of(context).pop(); - }); - }, - child: _buildSelectRow(context, _selected_1, '选择地区'), - ); - } else if (widget.name == 'stepper') { - final theme = TDTheme.of(context); - return Container( - decoration: BoxDecoration( - color: theme.whiteColor1, - ), - child: Padding( - padding: const EdgeInsets.all(16), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, // 使内容左对齐 - children: [ - TDText( - widget.label, - style: const TextStyle(fontSize: 16), - ), - const SizedBox(height: 8), - TDStepper( - theme: TDStepperTheme.filled, - disabled: FormState, - ), - ], + }, + child: _buildSelectRow(context, _selected_1, '选择地区'), + ); + case TDFormItemType.stepper: + final theme = TDTheme.of(context); + return Container( + decoration: BoxDecoration( + color: theme.whiteColor1, ), - ), - ); - } else if (widget.name == 'textarea') { - return TDTextarea( - backgroundColor: Colors.red, - controller: widget.controller, - label: widget.label, - hintText: widget.help, - maxLength: widget.maxLength, - indicator: widget.indicator, - readOnly: FormState, - layout: TDTextareaLayout.vertical, - onChanged: (value) { - setState(() {}); - }, - ); + child: Padding( + padding: const EdgeInsets.all(16), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, // 使内容左对齐 + children: [ + TDText( + widget.label, + style: const TextStyle(fontSize: 16), + ), + const SizedBox(height: 8), + TDStepper( + theme: TDStepperTheme.filled, + disabled: FormState, + ), + ], + ), + ), + ); + case TDFormItemType.textarea: + return TDTextarea( + backgroundColor: Colors.red, + controller: widget.controller, + label: widget.label, + hintText: widget.help, + maxLength: widget.maxLength, + indicator: widget.indicator, + readOnly: FormState, + layout: TDTextareaLayout.vertical, + onChanged: (value) { + setState(() {}); + }, + ); } } /// TODO: 构建错误的提示页面 - return const Column(); } Widget buildSelectRow(BuildContext context, String output, String title) { From df878282b6b54e3d7c961a77d3cfae24903e3e64 Mon Sep 17 00:00:00 2001 From: Simon_Wzy <1691663479@qq.com> Date: Tue, 22 Oct 2024 10:54:58 +0800 Subject: [PATCH 42/46] =?UTF-8?q?TODO:=20=E6=96=B0=E5=A2=9E=20TDRated=20?= =?UTF-8?q?=E8=AE=BE=E8=AE=A1=E7=A8=BF=E5=AF=B9=E6=AF=94=20=E6=B5=8B?= =?UTF-8?q?=E8=AF=95=E7=BB=84=E4=BB=B6=20API=20=E8=A1=A5=E5=85=A8=20Proble?= =?UTF-8?q?m:=20TDTextare=20=E8=83=8C=E6=99=AF=E9=A2=9C=E8=89=B2=E9=97=AE?= =?UTF-8?q?=E9=A2=98=20TDRadioGroup=20=E9=AB=98=E5=BA=A6=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 竖直态文字对齐 padding 问题 组相连选择器 时间选择器 没有 禁用态 竖直态问题 --- tdesign-component/lib/src/components/form/td_form_item.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tdesign-component/lib/src/components/form/td_form_item.dart b/tdesign-component/lib/src/components/form/td_form_item.dart index 83b51e1ec..07db67887 100644 --- a/tdesign-component/lib/src/components/form/td_form_item.dart +++ b/tdesign-component/lib/src/components/form/td_form_item.dart @@ -26,7 +26,7 @@ class TDFormItem extends StatefulWidget { radios = radios ?? const {}, super(key: key); - /// 表单项标签内容 + /// 表单项标签左侧展示的内容 final String? label; /// 表格单元需要使用的组件类型 From 03086a87b5aecb0358f0fd5eda0c417e9d985a08 Mon Sep 17 00:00:00 2001 From: Simon_Wzy <1691663479@qq.com> Date: Tue, 22 Oct 2024 11:46:56 +0800 Subject: [PATCH 43/46] =?UTF-8?q?rebase=20=E5=88=86=E6=94=AF=20develop?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tdesign-component/example/pubspec.lock | 569 +++++++++++++++++++++++++ 1 file changed, 569 insertions(+) diff --git a/tdesign-component/example/pubspec.lock b/tdesign-component/example/pubspec.lock index e69de29bb..f12b08469 100644 --- a/tdesign-component/example/pubspec.lock +++ b/tdesign-component/example/pubspec.lock @@ -0,0 +1,569 @@ +# Generated by pub +# See https://dart.dev/tools/pub/glossary#lockfile +packages: + _fe_analyzer_shared: + dependency: transitive + description: + name: _fe_analyzer_shared + sha256: eb376e9acf6938204f90eb3b1f00b578640d3188b4c8a8ec054f9f479af8d051 + url: "https://pub.dev" + source: hosted + version: "64.0.0" + analyzer: + dependency: transitive + description: + name: analyzer + sha256: "69f54f967773f6c26c7dcb13e93d7ccee8b17a641689da39e878d5cf13b06893" + url: "https://pub.dev" + source: hosted + version: "6.2.0" + args: + dependency: transitive + description: + name: args + sha256: "7cf60b9f0cc88203c5a190b4cd62a99feea42759a7fa695010eb5de1c0b2252a" + url: "https://pub.dev" + source: hosted + version: "2.5.0" + async: + dependency: transitive + description: + name: async + sha256: "947bfcf187f74dbc5e146c9eb9c0f10c9f8b30743e341481c1e2ed3ecc18c20c" + url: "https://pub.dev" + source: hosted + version: "2.11.0" + boolean_selector: + dependency: transitive + description: + name: boolean_selector + sha256: "6cfb5af12253eaf2b368f07bacc5a80d1301a071c73360d746b7f2e32d762c66" + url: "https://pub.dev" + source: hosted + version: "2.1.1" + characters: + dependency: transitive + description: + name: characters + sha256: "04a925763edad70e8443c99234dc3328f442e811f1d8fd1a72f1c8ad0f69a605" + url: "https://pub.dev" + source: hosted + version: "1.3.0" + clock: + dependency: transitive + description: + name: clock + sha256: cb6d7f03e1de671e34607e909a7213e31d7752be4fb66a86d29fe1eb14bfb5cf + url: "https://pub.dev" + source: hosted + version: "1.1.1" + collection: + dependency: transitive + description: + name: collection + sha256: "4a07be6cb69c84d677a6c3096fcf960cc3285a8330b4603e0d463d15d9bd934c" + url: "https://pub.dev" + source: hosted + version: "1.17.1" + color: + dependency: transitive + description: + name: color + sha256: ddcdf1b3badd7008233f5acffaf20ca9f5dc2cd0172b75f68f24526a5f5725cb + url: "https://pub.dev" + source: hosted + version: "3.0.0" + convert: + dependency: transitive + description: + name: convert + sha256: "0f08b14755d163f6e2134cb58222dd25ea2a2ee8a195e53983d57c075324d592" + url: "https://pub.dev" + source: hosted + version: "3.1.1" + crypto: + dependency: transitive + description: + name: crypto + sha256: ff625774173754681d66daaf4a448684fb04b78f902da9cb3d308c19cc5e8bab + url: "https://pub.dev" + source: hosted + version: "3.0.3" + cupertino_icons: + dependency: "direct main" + description: + name: cupertino_icons + sha256: d57953e10f9f8327ce64a508a355f0b1ec902193f66288e8cb5070e7c47eeb2d + url: "https://pub.dev" + source: hosted + version: "1.0.6" + dart_style: + dependency: transitive + description: + name: dart_style + sha256: "99e066ce75c89d6b29903d788a7bb9369cf754f7b24bf70bf4b6d6d6b26853b9" + url: "https://pub.dev" + source: hosted + version: "2.3.6" + dartx: + dependency: transitive + description: + name: dartx + sha256: "8b25435617027257d43e6508b5fe061012880ddfdaa75a71d607c3de2a13d244" + url: "https://pub.dev" + source: hosted + version: "1.2.0" + fake_async: + dependency: transitive + description: + name: fake_async + sha256: "511392330127add0b769b75a987850d136345d9227c6b94c96a04cf4a391bf78" + url: "https://pub.dev" + source: hosted + version: "1.3.1" + ffi: + dependency: transitive + description: + name: ffi + sha256: "7bf0adc28a23d395f19f3f1eb21dd7cfd1dd9f8e1c50051c069122e6853bc878" + url: "https://pub.dev" + source: hosted + version: "2.1.0" + file: + dependency: transitive + description: + name: file + sha256: a3b4f84adafef897088c160faf7dfffb7696046cb13ae90b508c2cbc95d3b8d4 + url: "https://pub.dev" + source: hosted + version: "7.0.1" + flutter: + dependency: "direct main" + description: flutter + source: sdk + version: "0.0.0" + flutter_easyrefresh: + dependency: transitive + description: + name: flutter_easyrefresh + sha256: "5d161ee5dcac34da9065116568147d742dd25fb9bff3b10024d9054b195087ad" + url: "https://pub.dev" + source: hosted + version: "2.2.2" + flutter_gen: + dependency: transitive + description: + name: flutter_gen + sha256: d7e4e57f606d73628b97765a67fdfb5a97e24cd2183e170afa8d1f62e48a9d5c + url: "https://pub.dev" + source: hosted + version: "5.8.0" + flutter_gen_core: + dependency: transitive + description: + name: flutter_gen_core + sha256: "46ecf0e317413dd065547887c43f93f55e9653e83eb98dc13dd07d40dd225325" + url: "https://pub.dev" + source: hosted + version: "5.8.0" + flutter_lints: + dependency: "direct dev" + description: + name: flutter_lints + sha256: b543301ad291598523947dc534aaddc5aaad597b709d2426d3a0e0d44c5cb493 + url: "https://pub.dev" + source: hosted + version: "1.0.4" + flutter_localizations: + dependency: "direct dev" + description: flutter + source: sdk + version: "0.0.0" + flutter_markdown: + dependency: "direct main" + description: + name: flutter_markdown + sha256: "21b085a1c185e46701373866144ced56cfb7a0c33f63c916bb8fe2d0c1491278" + url: "https://pub.dev" + source: hosted + version: "0.6.19" + flutter_slidable: + dependency: transitive + description: + name: flutter_slidable + sha256: "673403d2eeef1f9e8483bd6d8d92aae73b1d8bd71f382bc3930f699c731bc27c" + url: "https://pub.dev" + source: hosted + version: "3.1.0" + flutter_swiper_null_safety: + dependency: "direct main" + description: + name: flutter_swiper_null_safety + sha256: "5a855e0080d035c08e82f8b7fd2f106344943a30c9ab483b2584860a2f22eaaf" + url: "https://pub.dev" + source: hosted + version: "1.0.2" + flutter_test: + dependency: "direct dev" + description: flutter + source: sdk + version: "0.0.0" + glob: + dependency: transitive + description: + name: glob + sha256: "0e7014b3b7d4dac1ca4d6114f82bf1782ee86745b9b42a92c9289c23d8a0ab63" + url: "https://pub.dev" + source: hosted + version: "2.1.2" + hashcodes: + dependency: transitive + description: + name: hashcodes + sha256: "80f9410a5b3c8e110c4b7604546034749259f5d6dcca63e0d3c17c9258f1a651" + url: "https://pub.dev" + source: hosted + version: "2.0.0" + http: + dependency: "direct main" + description: + name: http + sha256: "5895291c13fa8a3bd82e76d5627f69e0d85ca6a30dcac95c4ea19a5d555879c2" + url: "https://pub.dev" + source: hosted + version: "0.13.6" + http_parser: + dependency: transitive + description: + name: http_parser + sha256: "2aa08ce0341cc9b354a498388e30986515406668dbcc4f7c950c3e715496693b" + url: "https://pub.dev" + source: hosted + version: "4.0.2" + image_size_getter: + dependency: transitive + description: + name: image_size_getter + sha256: "0511799498340b70993d2dfb34b55a2247b5b801d75a6cdd4543acfcafdb12b0" + url: "https://pub.dev" + source: hosted + version: "2.2.0" + intl: + dependency: "direct main" + description: + name: intl + sha256: a3715e3bc90294e971cb7dc063fbf3cd9ee0ebf8604ffeafabd9e6f16abbdbe6 + url: "https://pub.dev" + source: hosted + version: "0.18.0" + js: + dependency: transitive + description: + name: js + sha256: f2c445dce49627136094980615a031419f7f3eb393237e4ecd97ac15dea343f3 + url: "https://pub.dev" + source: hosted + version: "0.6.7" + json_annotation: + dependency: transitive + description: + name: json_annotation + sha256: "1ce844379ca14835a50d2f019a3099f419082cfdd231cd86a142af94dd5c6bb1" + url: "https://pub.dev" + source: hosted + version: "4.9.0" + lints: + dependency: transitive + description: + name: lints + sha256: a2c3d198cb5ea2e179926622d433331d8b58374ab8f29cdda6e863bd62fd369c + url: "https://pub.dev" + source: hosted + version: "1.0.1" + markdown: + dependency: transitive + description: + name: markdown + sha256: acf35edccc0463a9d7384e437c015a3535772e09714cf60e07eeef3a15870dcd + url: "https://pub.dev" + source: hosted + version: "7.1.1" + matcher: + dependency: transitive + description: + name: matcher + sha256: "6501fbd55da300384b768785b83e5ce66991266cec21af89ab9ae7f5ce1c4cbb" + url: "https://pub.dev" + source: hosted + version: "0.12.15" + material_color_utilities: + dependency: transitive + description: + name: material_color_utilities + sha256: d92141dc6fe1dad30722f9aa826c7fbc896d021d792f80678280601aff8cf724 + url: "https://pub.dev" + source: hosted + version: "0.2.0" + meta: + dependency: transitive + description: + name: meta + sha256: "3c74dbf8763d36539f114c799d8a2d87343b5067e9d796ca22b5eb8437090ee3" + url: "https://pub.dev" + source: hosted + version: "1.9.1" + mime: + dependency: transitive + description: + name: mime + sha256: e4ff8e8564c03f255408decd16e7899da1733852a9110a58fe6d1b817684a63e + url: "https://pub.dev" + source: hosted + version: "1.0.4" + package_config: + dependency: transitive + description: + name: package_config + sha256: "1c5b77ccc91e4823a5af61ee74e6b972db1ef98c2ff5a18d3161c982a55448bd" + url: "https://pub.dev" + source: hosted + version: "2.1.0" + path: + dependency: transitive + description: + name: path + sha256: "8829d8a55c13fc0e37127c29fedf290c102f4e40ae94ada574091fe0ff96c917" + url: "https://pub.dev" + source: hosted + version: "1.8.3" + path_parsing: + dependency: transitive + description: + name: path_parsing + sha256: e3e67b1629e6f7e8100b367d3db6ba6af4b1f0bb80f64db18ef1fbabd2fa9ccf + url: "https://pub.dev" + source: hosted + version: "1.0.1" + path_provider: + dependency: "direct main" + description: + name: path_provider + sha256: b27217933eeeba8ff24845c34003b003b2b22151de3c908d0e679e8fe1aa078b + url: "https://pub.dev" + source: hosted + version: "2.1.2" + path_provider_android: + dependency: transitive + description: + name: path_provider_android + sha256: "477184d672607c0a3bf68fbbf601805f92ef79c82b64b4d6eb318cbca4c48668" + url: "https://pub.dev" + source: hosted + version: "2.2.2" + path_provider_foundation: + dependency: transitive + description: + name: path_provider_foundation + sha256: "5a7999be66e000916500be4f15a3633ebceb8302719b47b9cc49ce924125350f" + url: "https://pub.dev" + source: hosted + version: "2.3.2" + path_provider_linux: + dependency: transitive + description: + name: path_provider_linux + sha256: f7a1fe3a634fe7734c8d3f2766ad746ae2a2884abe22e241a8b301bf5cac3279 + url: "https://pub.dev" + source: hosted + version: "2.2.1" + path_provider_platform_interface: + dependency: transitive + description: + name: path_provider_platform_interface + sha256: "88f5779f72ba699763fa3a3b06aa4bf6de76c8e5de842cf6f29e2e06476c2334" + url: "https://pub.dev" + source: hosted + version: "2.1.2" + path_provider_windows: + dependency: transitive + description: + name: path_provider_windows + sha256: "8bc9f22eee8690981c22aa7fc602f5c85b497a6fb2ceb35ee5a5e5ed85ad8170" + url: "https://pub.dev" + source: hosted + version: "2.2.1" + petitparser: + dependency: transitive + description: + name: petitparser + sha256: cb3798bef7fc021ac45b308f4b51208a152792445cce0448c9a4ba5879dd8750 + url: "https://pub.dev" + source: hosted + version: "5.4.0" + platform: + dependency: transitive + description: + name: platform + sha256: "12220bb4b65720483f8fa9450b4332347737cf8213dd2840d8b2c823e47243ec" + url: "https://pub.dev" + source: hosted + version: "3.1.4" + plugin_platform_interface: + dependency: transitive + description: + name: plugin_platform_interface + sha256: "4820fbfdb9478b1ebae27888254d445073732dae3d6ea81f0b7e06d5dedc3f02" + url: "https://pub.dev" + source: hosted + version: "2.1.8" + pub_semver: + dependency: transitive + description: + name: pub_semver + sha256: "40d3ab1bbd474c4c2328c91e3a7df8c6dd629b79ece4c4bd04bee496a224fb0c" + url: "https://pub.dev" + source: hosted + version: "2.1.4" + sky_engine: + dependency: transitive + description: flutter + source: sdk + version: "0.0.99" + source_span: + dependency: transitive + description: + name: source_span + sha256: dd904f795d4b4f3b870833847c461801f6750a9fa8e61ea5ac53f9422b31f250 + url: "https://pub.dev" + source: hosted + version: "1.9.1" + stack_trace: + dependency: transitive + description: + name: stack_trace + sha256: c3c7d8edb15bee7f0f74debd4b9c5f3c2ea86766fe4178eb2a18eb30a0bdaed5 + url: "https://pub.dev" + source: hosted + version: "1.11.0" + stream_channel: + dependency: transitive + description: + name: stream_channel + sha256: "83615bee9045c1d322bbbd1ba209b7a749c2cbcdcb3fdd1df8eb488b3279c1c8" + url: "https://pub.dev" + source: hosted + version: "2.1.1" + string_scanner: + dependency: transitive + description: + name: string_scanner + sha256: "556692adab6cfa87322a115640c11f13cb77b3f076ddcc5d6ae3c20242bedcde" + url: "https://pub.dev" + source: hosted + version: "1.2.0" + tdesign_flutter: + dependency: "direct main" + description: + path: ".." + relative: true + source: path + version: "0.1.6" + term_glyph: + dependency: transitive + description: + name: term_glyph + sha256: a29248a84fbb7c79282b40b8c72a1209db169a2e0542bce341da992fe1bc7e84 + url: "https://pub.dev" + source: hosted + version: "1.2.1" + test_api: + dependency: transitive + description: + name: test_api + sha256: eb6ac1540b26de412b3403a163d919ba86f6a973fe6cc50ae3541b80092fdcfb + url: "https://pub.dev" + source: hosted + version: "0.5.1" + time: + dependency: transitive + description: + name: time + sha256: ad8e018a6c9db36cb917a031853a1aae49467a93e0d464683e029537d848c221 + url: "https://pub.dev" + source: hosted + version: "2.1.4" + typed_data: + dependency: transitive + description: + name: typed_data + sha256: facc8d6582f16042dd49f2463ff1bd6e2c9ef9f3d5da3d9b087e244a7b564b3c + url: "https://pub.dev" + source: hosted + version: "1.3.2" + vector_graphics_codec: + dependency: transitive + description: + name: vector_graphics_codec + sha256: c86987475f162fadff579e7320c7ddda04cd2fdeffbe1129227a85d9ac9e03da + url: "https://pub.dev" + source: hosted + version: "1.1.11+1" + vector_graphics_compiler: + dependency: transitive + description: + name: vector_graphics_compiler + sha256: "12faff3f73b1741a36ca7e31b292ddeb629af819ca9efe9953b70bd63fc8cd81" + url: "https://pub.dev" + source: hosted + version: "1.1.11+1" + vector_math: + dependency: transitive + description: + name: vector_math + sha256: "80b3257d1492ce4d091729e3a67a60407d227c27241d6927be0130c98e741803" + url: "https://pub.dev" + source: hosted + version: "2.1.4" + watcher: + dependency: transitive + description: + name: watcher + sha256: "3d2ad6751b3c16cf07c7fca317a1413b3f26530319181b37e3b9039b84fc01d8" + url: "https://pub.dev" + source: hosted + version: "1.1.0" + win32: + dependency: transitive + description: + name: win32 + sha256: "350a11abd2d1d97e0cc7a28a81b781c08002aa2864d9e3f192ca0ffa18b06ed3" + url: "https://pub.dev" + source: hosted + version: "5.0.9" + xdg_directories: + dependency: transitive + description: + name: xdg_directories + sha256: faea9dee56b520b55a566385b84f2e8de55e7496104adada9962e0bd11bcff1d + url: "https://pub.dev" + source: hosted + version: "1.0.4" + xml: + dependency: transitive + description: + name: xml + sha256: "5bc72e1e45e941d825fd7468b9b4cc3b9327942649aeb6fc5cdbf135f0a86e84" + url: "https://pub.dev" + source: hosted + version: "6.3.0" + yaml: + dependency: transitive + description: + name: yaml + sha256: "75769501ea3489fca56601ff33454fe45507ea3bfb014161abc3b43ae25989d5" + url: "https://pub.dev" + source: hosted + version: "3.1.2" +sdks: + dart: ">=3.0.0 <4.0.0" + flutter: ">=3.10.0" From a33274321d4f5bb0598275cbce2c62a4e3555b53 Mon Sep 17 00:00:00 2001 From: Simon_Wzy <1691663479@qq.com> Date: Tue, 22 Oct 2024 15:04:54 +0800 Subject: [PATCH 44/46] =?UTF-8?q?=E4=BC=98=E5=8C=96=20TDFormItem=20type=20?= =?UTF-8?q?=E6=9E=9A=E4=B8=BE=E5=80=BC=20API=20=E6=B7=BB=E5=8A=A0=20TDRate?= =?UTF-8?q?=20=E8=BF=9B=E5=85=A5=E8=A1=A8=E5=8D=95=E7=BB=84=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../example/lib/page/td_form_page.dart | 4 ++ .../lib/src/components/form/td_form_item.dart | 46 ++++++++++++++++--- 2 files changed, 44 insertions(+), 6 deletions(-) diff --git a/tdesign-component/example/lib/page/td_form_page.dart b/tdesign-component/example/lib/page/td_form_page.dart index bb3bc9d4e..2fa075f61 100644 --- a/tdesign-component/example/lib/page/td_form_page.dart +++ b/tdesign-component/example/lib/page/td_form_page.dart @@ -186,6 +186,10 @@ class _TDFormPageState extends State { /// 为 TDStepper 预留其他设置 ), + TDFormItem( + label: '自我评价', + type: TDFormItemType.rate, + ), TDFormItem( label: '个人简介', type: TDFormItemType.textarea, diff --git a/tdesign-component/lib/src/components/form/td_form_item.dart b/tdesign-component/lib/src/components/form/td_form_item.dart index 07db67887..cfa86ea7e 100644 --- a/tdesign-component/lib/src/components/form/td_form_item.dart +++ b/tdesign-component/lib/src/components/form/td_form_item.dart @@ -90,7 +90,8 @@ enum TDFormItemType { dateTimePicker, cascader, stepper, - textarea + rate, + textarea, } class _TDFormItemState extends State { @@ -278,6 +279,14 @@ class _TDFormItemState extends State { ), ), ); + case TDFormItemType.rate: + return TDCell( + title: widget.label, + noteWidget: TDRate( + value: 3, + allowHalf: true, + disabled: FormState, + )); case TDFormItemType.textarea: return TDTextarea( backgroundColor: Colors.red, @@ -296,8 +305,10 @@ class _TDFormItemState extends State { switch (widget.type) { case TDFormItemType.input: return TDInput( + spacer: TDInputSpacer(iconLabelSpace: 0), type: TDInputType.twoLine, inputDecoration: InputDecoration( + contentPadding: EdgeInsets.only(left: LabelWidth), hintText: widget.help, border: InputBorder.none, ), @@ -306,7 +317,7 @@ class _TDFormItemState extends State { backgroundColor: Colors.white, /// 竖直态的 TDInput 没用 additionInfo? - additionInfo: widget.additionInfo, + // additionInfo: widget.additionInfo, readOnly: FormState, ); case TDFormItemType.password: @@ -315,7 +326,7 @@ class _TDFormItemState extends State { TDInput( inputDecoration: InputDecoration( hintText: widget.help, - // contentPadding: EdgeInsets.only(left: LabelWidth), + contentPadding: EdgeInsets.only(left: LabelWidth), border: InputBorder.none, ), type: TDInputType.twoLine, @@ -417,15 +428,14 @@ class _TDFormItemState extends State { child: _buildSelectRow(context, _selected_1, '选择地区'), ); case TDFormItemType.stepper: - final theme = TDTheme.of(context); return Container( decoration: BoxDecoration( - color: theme.whiteColor1, + color: TDTheme.of(context).whiteColor1, ), child: Padding( padding: const EdgeInsets.all(16), child: Column( - crossAxisAlignment: CrossAxisAlignment.start, // 使内容左对齐 + crossAxisAlignment: CrossAxisAlignment.start, children: [ TDText( widget.label, @@ -440,6 +450,30 @@ class _TDFormItemState extends State { ), ), ); + case TDFormItemType.rate: + return Container( + width: double.infinity, // 设置宽度为无限,横向占满父容器 + decoration: BoxDecoration( + color: TDTheme.of(context).whiteColor1, + ), + child: Padding( + padding: const EdgeInsets.all(16), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + TDText( + widget.label, + style: const TextStyle(fontSize: 16), + ), + const SizedBox(height: 8), + TDRate( + value: 3, + allowHalf: true, + disabled: FormState, + ), + ], + ), + )); case TDFormItemType.textarea: return TDTextarea( backgroundColor: Colors.red, From 43bdafe2f850f22ae48de827d5b363811f52b9ac Mon Sep 17 00:00:00 2001 From: Simon_Wzy <1691663479@qq.com> Date: Thu, 24 Oct 2024 10:48:20 +0800 Subject: [PATCH 45/46] =?UTF-8?q?=E8=A7=A3=E5=86=B3=20Input=20padding=20?= =?UTF-8?q?=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../example/lib/page/td_form_page.dart | 86 +++++---- .../lib/src/components/form/td_form_item.dart | 57 +++--- .../lib/src/components/input/td_input.dart | 179 +++++++++++++----- 3 files changed, 214 insertions(+), 108 deletions(-) diff --git a/tdesign-component/example/lib/page/td_form_page.dart b/tdesign-component/example/lib/page/td_form_page.dart index 2fa075f61..f1b475b25 100644 --- a/tdesign-component/example/lib/page/td_form_page.dart +++ b/tdesign-component/example/lib/page/td_form_page.dart @@ -34,8 +34,10 @@ class _TDFormPageState extends State { Color verticalButtonColor = Color(0xFFE5E5E5); Color horizontalButtonColor = Color(0xFFF0F1FD); + /// radios 传入参数 final Map _radios = {'0': '男', '1': '女', '3': '保密'}; + /// 级联选择器 传入参数 static const List _data = [ { 'label': '北京市', @@ -107,6 +109,52 @@ class _TDFormPageState extends State { }, ]; + /// 表单校验规则 + final Map>> _rules = { + 'name': [ + { + 'validator': (String? val) => val != null && val.length == 8, + 'message': '只能输入8个字符英文', + }, + ], + 'password': [ + { + 'validator': (String? val) => val != null && val.length > 6, + 'message': '长度大于6个字符', + }, + ], + 'gender': [ + { + 'validator': (String? val) => val != null && val.isNotEmpty, + 'message': '不能为空', + }, + ], + 'birth': [ + { + 'validator': (String? val) => val != null && val.isNotEmpty, + 'message': '不能为空', + }, + ], + 'place': [ + { + 'validator': (String? val) => val != null && val.isNotEmpty, + 'message': '不能为空', + }, + ], + 'description': [ + { + 'validator': (int? val) => val != null && val > 3, + 'message': '分数过低会影响整体评价', + }, + ], + 'resume': [ + { + 'validator': (String? val) => val != null && val.isNotEmpty, + 'message': '不能为空', + }, + ], + }; + @override void initState() { for (var i = 0; i < 3; i++) { @@ -148,20 +196,23 @@ class _TDFormPageState extends State { label: '用户名', type: TDFormItemType.input, help: '请输入用户名', - // additionInfo: '输入用户名', - labelWidth: 15.0, + // additionInfo: '只能输入8个字符英文', + labelWidth: 43.0, controller: controller[0], + // requiredMark: true, ), TDFormItem( label: '密码', type: TDFormItemType.password, help: '请输入密码', - labelWidth: 35.0, + // additionInfo: '只能输入数字', + labelWidth: 60.0, controller: controller[1], ), TDFormItem( label: '性别', type: TDFormItemType.radios, + labelWidth: 50.0, /// 扩展一下数量和选项内容 radios: _radios, @@ -361,20 +412,6 @@ class _TDFormPageState extends State { theme: TDButtonTheme.primary, shape: TDButtonShape.rectangle, )), - SizedBox( - width: 16, - ), - Expanded( - child: TDButton( - text: '重置', - size: TDButtonSize.large, - type: TDButtonType.fill, - shape: TDButtonShape.rectangle, - theme: TDButtonTheme.defaultTheme, - )), - SizedBox( - width: 16, - ), ], )), ); @@ -399,21 +436,6 @@ class _TDFormPageState extends State { shape: TDButtonShape.rectangle, disabled: true, )), - SizedBox( - width: 16, - ), - Expanded( - child: TDButton( - text: '重置', - size: TDButtonSize.large, - type: TDButtonType.fill, - shape: TDButtonShape.rectangle, - theme: TDButtonTheme.defaultTheme, - disabled: true, - )), - SizedBox( - width: 16, - ), ], )), ); diff --git a/tdesign-component/lib/src/components/form/td_form_item.dart b/tdesign-component/lib/src/components/form/td_form_item.dart index cfa86ea7e..ca8e68b54 100644 --- a/tdesign-component/lib/src/components/form/td_form_item.dart +++ b/tdesign-component/lib/src/components/form/td_form_item.dart @@ -35,6 +35,7 @@ class TDFormItem extends StatefulWidget { /// 表单内容对齐方式:'left' 或 'right' final String? contentAlign; + /// TODO: /// 是否显示右侧箭头 final bool? arrow; @@ -149,6 +150,7 @@ class _TDFormItemState extends State { controller: widget.controller, backgroundColor: Colors.white, // additionInfo: widget.additionInfo, + // additionInfoColor: TDTheme.of(context).errorColor6, readOnly: FormState, ); case TDFormItemType.password: @@ -179,6 +181,8 @@ class _TDFormItemState extends State { }, needClear: false, readOnly: FormState, + // additionInfo: widget.additionInfo, + // additionInfoColor: TDTheme.of(context).errorColor6, ); case TDFormItemType.radios: final theme = TDTheme.of(context); @@ -195,7 +199,7 @@ class _TDFormItemState extends State { widget.label ?? '', style: const TextStyle(fontSize: 16), ), - const SizedBox(width: 16), + SizedBox(width: LabelWidth), Expanded( child: TDRadioGroup( selectId: 'index:1', @@ -308,10 +312,11 @@ class _TDFormItemState extends State { spacer: TDInputSpacer(iconLabelSpace: 0), type: TDInputType.twoLine, inputDecoration: InputDecoration( - contentPadding: EdgeInsets.only(left: LabelWidth), + contentPadding: EdgeInsets.only(left: 16), hintText: widget.help, border: InputBorder.none, ), + leftLabelSpace: 16, leftLabel: widget.label, controller: widget.controller, backgroundColor: Colors.white, @@ -326,9 +331,10 @@ class _TDFormItemState extends State { TDInput( inputDecoration: InputDecoration( hintText: widget.help, - contentPadding: EdgeInsets.only(left: LabelWidth), + contentPadding: EdgeInsets.only(left: 16), border: InputBorder.none, ), + leftLabelSpace: 16, type: TDInputType.twoLine, controller: widget.controller, obscureText: !browseOn, @@ -359,33 +365,34 @@ class _TDFormItemState extends State { decoration: BoxDecoration( color: theme.whiteColor1, ), - child: Padding( - padding: const EdgeInsets.all(16), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - TDText( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Padding( + padding: const EdgeInsets.all(16), // 仅作用于 TDText + child: TDText( widget.label ?? '', style: const TextStyle(fontSize: 16), ), - const SizedBox(width: 20), - TDRadioGroup( - selectId: 'index:1', - direction: Axis.horizontal, - directionalTdRadios: widget.radios.entries.map((entry) { - return TDRadio( - id: entry.key, - title: entry.value, - radioStyle: TDRadioStyle.circle, - showDivider: false, - enable: !FormState, - ); - }).toList(), - ), - ], - ), + ), + const SizedBox(width: 20), + TDRadioGroup( + selectId: 'index:1', + direction: Axis.horizontal, + directionalTdRadios: widget.radios.entries.map((entry) { + return TDRadio( + id: entry.key, + title: entry.value, + radioStyle: TDRadioStyle.circle, + showDivider: false, + enable: !FormState, + ); + }).toList(), + ), + ], ), ); + case TDFormItemType.dateTimePicker: return GestureDetector( onTap: () { diff --git a/tdesign-component/lib/src/components/input/td_input.dart b/tdesign-component/lib/src/components/input/td_input.dart index a24893103..bd56897b3 100644 --- a/tdesign-component/lib/src/components/input/td_input.dart +++ b/tdesign-component/lib/src/components/input/td_input.dart @@ -5,7 +5,14 @@ import 'package:flutter/services.dart'; import '../../../tdesign_flutter.dart'; -enum TDInputType { normal, twoLine, longText, special, normalMaxTwoLine, cardStyle } +enum TDInputType { + normal, + twoLine, + longText, + special, + normalMaxTwoLine, + cardStyle +} enum TDInputSize { small, large } @@ -87,9 +94,12 @@ class TDInput extends StatelessWidget { ((leftLabel == null && leftIcon == null && !(required ?? false)) ? 0 : ((leftLabel?.length == null ? 0 : leftLabel!.length) * - (leftLabelStyle != null ? (leftLabelStyle.fontSize ?? 16) : 16) + + (leftLabelStyle != null + ? (leftLabelStyle.fontSize ?? 16) + : 16) + 1 + - (leftIcon != null ? 1 : 0) * ((leftIcon is Icon) ? (leftIcon.size ?? 24) : 24)) + + (leftIcon != null ? 1 : 0) * + ((leftIcon is Icon) ? (leftIcon.size ?? 24) : 24)) + (required == true ? 1 : 0) * 14), super(key: key); @@ -273,16 +283,21 @@ class TDInput extends StatelessWidget { Widget buildNormalInput(BuildContext context) { var cardStyleDecoration = _getCardStylePreDecoration(context); - var hasLeftWidget = leftLabel != null || leftIcon != null || (required ?? false); + var hasLeftWidget = + leftLabel != null || leftIcon != null || (required ?? false); return Stack( alignment: Alignment.bottomCenter, children: [ Container( alignment: Alignment.centerLeft, - color: (cardStyleDecoration != null || decoration != null) ? null : backgroundColor, + color: (cardStyleDecoration != null || decoration != null) + ? null + : backgroundColor, decoration: cardStyleDecoration ?? decoration, child: Row( - crossAxisAlignment: additionInfo != '' ? CrossAxisAlignment.start : CrossAxisAlignment.center, + crossAxisAlignment: additionInfo != '' + ? CrossAxisAlignment.start + : CrossAxisAlignment.center, children: [ Visibility( visible: hasLeftWidget, @@ -306,13 +321,16 @@ class TDInput extends StatelessWidget { child: Container( constraints: BoxConstraints(maxWidth: _leftLabelWidth), padding: EdgeInsets.only( - left: leftIcon != null ? (spacer.iconLabelSpace ?? 4) : 0, + left: leftIcon != null + ? (spacer.iconLabelSpace ?? 4) + : 0, top: getInputPadding(), bottom: getInputPadding()), child: TDText( leftLabel, maxLines: 2, - style: leftLabelStyle ?? const TextStyle(letterSpacing: 0), + style: leftLabelStyle ?? + const TextStyle(letterSpacing: 0), font: TDTheme.of(context).fontBodyLarge, fontWeight: FontWeight.w400, ), @@ -329,7 +347,8 @@ class TDInput extends StatelessWidget { child: TDText( '*', maxLines: 1, - style: TextStyle(color: TDTheme.of(context).errorColor6), + style: TextStyle( + color: TDTheme.of(context).errorColor6), font: TDTheme.of(context).fontBodyLarge, fontWeight: FontWeight.w400, ), @@ -343,7 +362,8 @@ class TDInput extends StatelessWidget { crossAxisAlignment: CrossAxisAlignment.start, children: [ TDInputView( - textStyle: textStyle ?? TextStyle(color: TDTheme.of(context).fontGyColor1), + textStyle: textStyle ?? + TextStyle(color: TDTheme.of(context).fontGyColor1), readOnly: readOnly, autofocus: autofocus, obscureText: obscureText, @@ -360,25 +380,32 @@ class TDInput extends StatelessWidget { focusNode: focusNode, isCollapsed: true, textAlign: contentAlignment, - hintTextStyle: hintTextStyle ?? TextStyle(color: TDTheme.of(context).fontGyColor3), + hintTextStyle: hintTextStyle ?? + TextStyle(color: TDTheme.of(context).fontGyColor3), cursorColor: cursorColor, textInputBackgroundColor: textInputBackgroundColor, controller: controller, contentPadding: contentPadding ?? EdgeInsets.only( left: spacer.labelInputSpace ?? 16, - right: spacer.inputRightSpace != null ? spacer.inputRightSpace! / 2 : 16, - bottom: additionInfo != '' ? 4 : getInputPadding(), + right: spacer.inputRightSpace != null + ? spacer.inputRightSpace! / 2 + : 16, + bottom: + additionInfo != '' ? 4 : getInputPadding(), top: getInputPadding()), inputAction: inputAction, ), Visibility( child: Padding( - padding: EdgeInsets.only(left: spacer.additionInfoSpace ?? 16, bottom: getInputPadding()), + padding: EdgeInsets.only( + left: spacer.additionInfoSpace ?? 16, + bottom: getInputPadding()), child: TDText( additionInfo, font: TDTheme.of(context).fontBodySmall, - textColor: additionInfoColor ?? TDTheme.of(context).fontGyColor3, + textColor: additionInfoColor ?? + TDTheme.of(context).fontGyColor3, ), ), visible: additionInfo != '', @@ -389,22 +416,31 @@ class TDInput extends StatelessWidget { Visibility( visible: rightWidget != null, child: Container( - margin: EdgeInsets.only(top: getInputPadding(), bottom: getInputPadding(), right: 16), + margin: EdgeInsets.only( + top: getInputPadding(), + bottom: getInputPadding(), + right: 16), child: rightWidget, ), ), Visibility( - visible: controller != null && controller!.text.isNotEmpty && needClear && rightWidget == null, + visible: controller != null && + controller!.text.isNotEmpty && + needClear && + rightWidget == null, child: GestureDetector( child: Container( margin: EdgeInsets.only( - left: spacer.inputRightSpace != null ? spacer.inputRightSpace! / 2 : 8, + left: spacer.inputRightSpace != null + ? spacer.inputRightSpace! / 2 + : 8, right: spacer.rightSpace ?? 16, top: additionInfo != '' ? getInputPadding() : 0), child: Icon( size: clearIconSize, TDIcons.close_circle_filled, - color: clearBtnColor ?? TDTheme.of(context).fontGyColor3, + color: + clearBtnColor ?? TDTheme.of(context).fontGyColor3, ), ), onTap: onClearTap ?? @@ -417,7 +453,9 @@ class TDInput extends StatelessWidget { onTap: onBtnTap, child: Container( margin: EdgeInsets.only( - left: spacer.inputRightSpace != null ? spacer.inputRightSpace! / 2 : 8, + left: spacer.inputRightSpace != null + ? spacer.inputRightSpace! / 2 + : 8, right: spacer.rightSpace ?? 16, top: additionInfo != '' ? getInputPadding() : 0), child: rightBtn, @@ -454,17 +492,20 @@ class TDInput extends StatelessWidget { case TDCardStyle.topTextWithBlueBorder: cardStyleDecoration = BoxDecoration( color: Colors.white, - border: Border.all(color: TDTheme.of(context).brandNormalColor, width: 1.5), + border: Border.all( + color: TDTheme.of(context).brandNormalColor, width: 1.5), borderRadius: BorderRadius.circular(6)); break; case TDCardStyle.errorStyle: cardStyleDecoration = BoxDecoration( color: Colors.white, - border: Border.all(color: TDTheme.of(context).errorColor6, width: 1.5), + border: Border.all( + color: TDTheme.of(context).errorColor6, width: 1.5), borderRadius: BorderRadius.circular(6)); break; default: - cardStyleDecoration = BoxDecoration(color: Colors.white, borderRadius: BorderRadius.circular(6)); + cardStyleDecoration = BoxDecoration( + color: Colors.white, borderRadius: BorderRadius.circular(6)); break; } } @@ -489,14 +530,18 @@ class TDInput extends StatelessWidget { Visibility( visible: leftLabel != null, child: Container( - constraints: BoxConstraints(maxWidth: _leftLabelWidth + (leftLabelSpace ?? 12)), - padding: EdgeInsets.only(left: leftLabelSpace ?? 12.0, top: 10.0), + constraints: BoxConstraints( + maxWidth: + _leftLabelWidth + (leftLabelSpace ?? 12)), + padding: EdgeInsets.only( + left: leftLabelSpace ?? 12.0, top: 10.0), child: Column( children: [ TDText( leftLabel, maxLines: 2, - style: leftLabelStyle ?? const TextStyle(letterSpacing: 0), + style: leftLabelStyle ?? + const TextStyle(letterSpacing: 0), font: TDTheme.of(context).fontBodyLarge, fontWeight: FontWeight.w400, ), @@ -515,7 +560,8 @@ class TDInput extends StatelessWidget { child: TDText( '*', maxLines: 1, - style: TextStyle(color: TDTheme.of(context).errorColor6), + style: TextStyle( + color: TDTheme.of(context).errorColor6), font: TDTheme.of(context).fontBodyLarge, fontWeight: FontWeight.w400, ), @@ -536,7 +582,8 @@ class TDInput extends StatelessWidget { Expanded( flex: 1, child: TDInputView( - textStyle: textStyle ?? TextStyle(color: TDTheme.of(context).fontGyColor1), + textStyle: textStyle ?? + TextStyle(color: TDTheme.of(context).fontGyColor1), readOnly: readOnly, autofocus: autofocus, obscureText: obscureText, @@ -551,30 +598,38 @@ class TDInput extends StatelessWidget { isCollapsed: true, maxLines: maxLines, focusNode: focusNode, - hintTextStyle: hintTextStyle ?? TextStyle(color: TDTheme.of(context).fontGyColor3), + hintTextStyle: hintTextStyle ?? + TextStyle(color: TDTheme.of(context).fontGyColor3), cursorColor: cursorColor, textInputBackgroundColor: textInputBackgroundColor, controller: controller, contentPadding: contentPadding ?? EdgeInsets.only( - left: spacer.labelInputSpace ?? 16, - right: spacer.inputRightSpace != null ? spacer.inputRightSpace! / 2 : 8, + left: spacer.labelInputSpace ?? 16, + right: spacer.inputRightSpace != null + ? spacer.inputRightSpace! / 2 + : 8, ), inputAction: inputAction, ), ), Visibility( - visible: controller != null && controller!.text.isNotEmpty && needClear, + visible: controller != null && + controller!.text.isNotEmpty && + needClear, child: GestureDetector( child: Container( margin: EdgeInsets.only( - left: spacer.inputRightSpace != null ? spacer.inputRightSpace! / 2 : 8, - right: spacer.rightSpace ?? 16, + left: spacer.inputRightSpace != null + ? spacer.inputRightSpace! / 2 + : 8, + right: spacer.rightSpace ?? 16, ), child: Icon( size: clearIconSize, TDIcons.close_circle_filled, - color: clearBtnColor ?? TDTheme.of(context).fontGyColor3, + color: clearBtnColor ?? + TDTheme.of(context).fontGyColor3, ), ), onTap: onClearTap, @@ -585,8 +640,10 @@ class TDInput extends StatelessWidget { onTap: onBtnTap, child: Container( margin: EdgeInsets.only( - left: spacer.inputRightSpace != null ? spacer.inputRightSpace! / 2 : 8, - right: spacer.rightSpace ?? 16, + left: spacer.inputRightSpace != null + ? spacer.inputRightSpace! / 2 + : 8, + right: spacer.rightSpace ?? 16, ), child: rightBtn, ), @@ -624,7 +681,10 @@ class TDInput extends StatelessWidget { crossAxisAlignment: CrossAxisAlignment.start, children: [ Padding( - padding: EdgeInsets.only(left: 16, top: getInputPadding(), bottom: getInputPadding()), + padding: EdgeInsets.only( + left: 16, + top: getInputPadding(), + bottom: getInputPadding()), child: TDText( leftLabel, maxLines: 2, @@ -642,7 +702,8 @@ class TDInput extends StatelessWidget { Expanded( flex: 1, child: TDInputView( - textStyle: textStyle ?? TextStyle(color: TDTheme.of(context).fontGyColor1), + textStyle: textStyle ?? + TextStyle(color: TDTheme.of(context).fontGyColor1), readOnly: readOnly, autofocus: autofocus, obscureText: obscureText, @@ -652,15 +713,19 @@ class TDInput extends StatelessWidget { inputType: inputType, textAlign: textAlign, onChanged: onChanged, - inputFormatters: inputFormatters ?? [LengthLimitingTextInputFormatter(maxLength)], + inputFormatters: inputFormatters ?? + [LengthLimitingTextInputFormatter(maxLength)], inputDecoration: inputDecoration, maxLines: maxLines, focusNode: focusNode, - hintTextStyle: hintTextStyle ?? TextStyle(color: TDTheme.of(context).fontGyColor3), + hintTextStyle: hintTextStyle ?? + TextStyle(color: TDTheme.of(context).fontGyColor3), cursorColor: cursorColor, textInputBackgroundColor: textInputBackgroundColor, controller: controller, - contentPadding: contentPadding ?? const EdgeInsets.only(left: 16, right: 16, top: 12, bottom: 12), + contentPadding: contentPadding ?? + const EdgeInsets.only( + left: 16, right: 16, top: 12, bottom: 12), inputAction: inputAction, ), ), @@ -692,8 +757,10 @@ class TDInput extends StatelessWidget { Visibility( visible: leftLabel != null, child: Padding( - padding: - EdgeInsets.only(left: leftLabelSpace ?? 16, top: getInputPadding(), bottom: getInputPadding()), + padding: EdgeInsets.only( + left: leftLabelSpace ?? 16, + top: getInputPadding(), + bottom: getInputPadding()), child: leftInfoWidth != null ? SizedBox( width: _leftLabelWidth, @@ -721,7 +788,8 @@ class TDInput extends StatelessWidget { child: Padding( padding: EdgeInsets.only(left: spacer.labelInputSpace!), child: TDInputView( - textStyle: textStyle ?? TextStyle(color: TDTheme.of(context).fontGyColor1), + textStyle: textStyle ?? + TextStyle(color: TDTheme.of(context).fontGyColor1), readOnly: readOnly, autofocus: autofocus, obscureText: obscureText, @@ -735,14 +803,17 @@ class TDInput extends StatelessWidget { maxLines: maxLines, focusNode: focusNode, isCollapsed: true, - hintTextStyle: hintTextStyle ?? TextStyle(color: TDTheme.of(context).fontGyColor3), + hintTextStyle: hintTextStyle ?? + TextStyle(color: TDTheme.of(context).fontGyColor3), cursorColor: cursorColor, textInputBackgroundColor: textInputBackgroundColor, controller: controller, textAlign: textAlign, contentPadding: contentPadding ?? EdgeInsets.only( - right: spacer.inputRightSpace!, bottom: getInputPadding(), top: getInputPadding()), + right: spacer.inputRightSpace!, + bottom: getInputPadding(), + top: getInputPadding()), inputAction: inputAction, ), ), @@ -750,7 +821,10 @@ class TDInput extends StatelessWidget { Visibility( visible: rightWidget != null, child: Container( - margin: EdgeInsets.only(top: getInputPadding(), bottom: getInputPadding(), right: spacer.rightSpace!), + margin: EdgeInsets.only( + top: getInputPadding(), + bottom: getInputPadding(), + right: spacer.rightSpace!), child: rightWidget, ), ), @@ -841,7 +915,8 @@ class Chinese2Formatter extends TextInputFormatter { final _regExp = r'^[\u4E00-\u9FA5A-Za-z0-9_]+$'; @override - TextEditingValue formatEditUpdate(TextEditingValue oldValue, TextEditingValue newValue) { + TextEditingValue formatEditUpdate( + TextEditingValue oldValue, TextEditingValue newValue) { var newValueLength = newValue.text.length; var count = 0; if (newValueLength == 0) { @@ -858,11 +933,13 @@ class Chinese2Formatter extends TextInputFormatter { return newValue.copyWith( text: text, composing: TextRange.empty, - selection: TextSelection.fromPosition(TextPosition(offset: i, affinity: TextAffinity.downstream))); + selection: TextSelection.fromPosition( + TextPosition(offset: i, affinity: TextAffinity.downstream))); } } } - if (newValueLength > 0 && RegExp(_regExp).firstMatch(newValue.text) != null) { + if (newValueLength > 0 && + RegExp(_regExp).firstMatch(newValue.text) != null) { if (newValueLength + count <= maxLength) { return newValue; } From 44d8709e7ee84c182f72c6a70cedccd74137da49 Mon Sep 17 00:00:00 2001 From: Simon_Wzy <1691663479@qq.com> Date: Thu, 24 Oct 2024 16:22:05 +0800 Subject: [PATCH 46/46] =?UTF-8?q?=E5=AE=9E=E7=8E=B0=E6=80=BB=E8=A1=A8?= =?UTF-8?q?=E5=8D=95=E7=9A=84=E6=A0=A1=E9=AA=8C=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../example/lib/page/td_form_page.dart | 97 +++++++------- .../example/lib/page/td_input_page.dart | 2 +- .../lib/src/components/form/td_form.dart | 13 +- .../components/form/td_form_inherited.dart | 23 +++- .../lib/src/components/form/td_form_item.dart | 126 ++++++++++++++---- .../components/form/td_form_validation.dart | 23 ++++ tdesign-component/lib/tdesign_flutter.dart | 3 +- 7 files changed, 198 insertions(+), 89 deletions(-) create mode 100644 tdesign-component/lib/src/components/form/td_form_validation.dart diff --git a/tdesign-component/example/lib/page/td_form_page.dart b/tdesign-component/example/lib/page/td_form_page.dart index f1b475b25..6b01bb659 100644 --- a/tdesign-component/example/lib/page/td_form_page.dart +++ b/tdesign-component/example/lib/page/td_form_page.dart @@ -1,3 +1,5 @@ +import 'dart:math'; + import 'package:flutter/material.dart'; import 'package:tdesign_flutter/tdesign_flutter.dart'; @@ -21,6 +23,9 @@ class _TDFormPageState extends State { /// form 排列方式是否为水平 bool _isFormHorizontal = true; + /// 控制是否进行表单校验 + bool _validateForm = false; + /// 设置按钮是否可点击状态 /// true 表示处于 active 状态 bool horizontalButton = false; @@ -109,51 +114,43 @@ class _TDFormPageState extends State { }, ]; - /// 表单校验规则 - final Map>> _rules = { - 'name': [ - { - 'validator': (String? val) => val != null && val.length == 8, - 'message': '只能输入8个字符英文', - }, - ], - 'password': [ - { - 'validator': (String? val) => val != null && val.length > 6, - 'message': '长度大于6个字符', - }, - ], - 'gender': [ - { - 'validator': (String? val) => val != null && val.isNotEmpty, - 'message': '不能为空', - }, - ], - 'birth': [ - { - 'validator': (String? val) => val != null && val.isNotEmpty, - 'message': '不能为空', - }, - ], - 'place': [ - { - 'validator': (String? val) => val != null && val.isNotEmpty, - 'message': '不能为空', - }, - ], - 'description': [ - { - 'validator': (int? val) => val != null && val > 3, - 'message': '分数过低会影响整体评价', - }, - ], - 'resume': [ - { - 'validator': (String? val) => val != null && val.isNotEmpty, - 'message': '不能为空', - }, - ], - }; + /// 按钮点击事件:改变 _validate 值,从而触发校验 + void _onSubmit() { + setState(() { + _validateForm = true; + }); + } + + /// 定义整个校验规则 + final List _validationRules = [ + TDFormValidation( + validate: (value) => value == null || value.isEmpty ? 'empty' : null, + errorMessage: '输入不能为空', + type: TDFormItemType.input, + ), + TDFormValidation( + validate: (value) => + RegExp(r'^[a-zA-Z]{8}$').hasMatch(value ?? '') ? null : 'invalid', + errorMessage: '只能输入8个字符英文', + type: TDFormItemType.input, + ), + TDFormValidation( + validate: (value) => value == null || value.isEmpty ? 'empty' : null, + errorMessage: '输入不能为空', + type: TDFormItemType.password, + ), + TDFormValidation( + validate: (value) => + RegExp(r'^\d+$').hasMatch(value ?? '') ? null : 'invalid', + errorMessage: '只能输入数字', + type: TDFormItemType.password, + ), + TDFormValidation( + validate: (value) => value == null || value.isEmpty ? 'empty' : null, + errorMessage: '输入不能为空', + type: TDFormItemType.textarea, + ), + ]; @override void initState() { @@ -191,6 +188,8 @@ class _TDFormPageState extends State { return TDForm( disabled: _formDisableState, isHorizontal: _isFormHorizontal, + isValidate: _validateForm, + rules: _validationRules, items: [ TDFormItem( label: '用户名', @@ -397,13 +396,10 @@ class _TDFormPageState extends State { decoration: BoxDecoration( color: theme.whiteColor1, ), - child: const Padding( - padding: EdgeInsets.all(16), + child: Padding( + padding: const EdgeInsets.all(16), child: Row( children: [ - SizedBox( - width: 16, - ), Expanded( child: TDButton( text: '提交', @@ -411,6 +407,7 @@ class _TDFormPageState extends State { type: TDButtonType.fill, theme: TDButtonTheme.primary, shape: TDButtonShape.rectangle, + onTap: _onSubmit, )), ], )), diff --git a/tdesign-component/example/lib/page/td_input_page.dart b/tdesign-component/example/lib/page/td_input_page.dart index 6d85ea198..c55d6b0ea 100644 --- a/tdesign-component/example/lib/page/td_input_page.dart +++ b/tdesign-component/example/lib/page/td_input_page.dart @@ -140,7 +140,7 @@ class _TDInputViewPageState extends State { return Column( children: [ TDInput( - leftLabel: '标签文字123', + leftLabel: '标签文字', required: true, controller: controller[1], backgroundColor: Colors.white, diff --git a/tdesign-component/lib/src/components/form/td_form.dart b/tdesign-component/lib/src/components/form/td_form.dart index 5f815c17f..11fa015ae 100644 --- a/tdesign-component/lib/src/components/form/td_form.dart +++ b/tdesign-component/lib/src/components/form/td_form.dart @@ -1,4 +1,5 @@ import 'package:flutter/material.dart'; +import 'package:tdesign_flutter/src/components/form/td_form_validation.dart'; import 'td_form_inherited.dart'; import '../../../tdesign_flutter.dart'; @@ -17,7 +18,8 @@ class TDForm extends StatefulWidget { this.preventSubmitDefault = true, this.requiredMark = true, // 此处必填项有小问题 this.resetType = 'empty', - this.rules, + required this.rules, + this.isValidate = false, this.scrollToFirstError, this.showErrorMessage = true, this.submitWithWarningMessage = false, @@ -64,8 +66,11 @@ class TDForm extends StatefulWidget { /// 可选项:empty/initial final String? resetType; - /// 表单字段校验规则 - final Object? rules; + /// 整个表单字段校验规则 + final List rules; + + /// 是否对整个 form 进行校验 + final bool isValidate; /// 表单校验不通过时,是否自动滚动到第一个校验不通过的字段,平滑滚动或是瞬间直达。 /// 值为空则表示不滚动。可选项:''/smooth/auto @@ -89,6 +94,8 @@ class _TDFormState extends State { disabled: widget.disabled, labelWidth: widget.labelWidth, isHorizontal: widget.isHorizontal, + isValidate: widget.isValidate, + rules: widget.rules, child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: widget.items diff --git a/tdesign-component/lib/src/components/form/td_form_inherited.dart b/tdesign-component/lib/src/components/form/td_form_inherited.dart index 86be39ee9..2af0cec98 100644 --- a/tdesign-component/lib/src/components/form/td_form_inherited.dart +++ b/tdesign-component/lib/src/components/form/td_form_inherited.dart @@ -1,16 +1,23 @@ import 'package:flutter/cupertino.dart'; +import '../../../tdesign_flutter.dart'; + class TDFormInherited extends InheritedWidget { final bool disabled; final double? labelWidth; final bool isHorizontal; + final bool isValidate; + final List rules; - const TDFormInherited({ - required Widget child, - required this.disabled, - required this.isHorizontal, - this.labelWidth, - }) : super(child: child); + const TDFormInherited( + {super.key, + required Widget child, + required this.disabled, + required this.isHorizontal, + required this.isValidate, + this.labelWidth, + required this.rules}) + : super(child: child); static TDFormInherited? of(BuildContext context) { return context.dependOnInheritedWidgetOfExactType(); @@ -20,6 +27,8 @@ class TDFormInherited extends InheritedWidget { bool updateShouldNotify(TDFormInherited oldWidget) { return disabled != oldWidget.disabled || labelWidth != oldWidget.labelWidth || - isHorizontal != oldWidget.isHorizontal; + isHorizontal != oldWidget.isHorizontal || + isValidate != oldWidget.isValidate || + rules != oldWidget.rules; } } diff --git a/tdesign-component/lib/src/components/form/td_form_item.dart b/tdesign-component/lib/src/components/form/td_form_item.dart index ca8e68b54..f5d273659 100644 --- a/tdesign-component/lib/src/components/form/td_form_item.dart +++ b/tdesign-component/lib/src/components/form/td_form_item.dart @@ -2,6 +2,18 @@ import 'package:flutter/material.dart'; import 'td_form_inherited.dart'; import '../../../tdesign_flutter.dart'; +/// 表格单元选用组件类型的枚举 +enum TDFormItemType { + input, + password, + radios, + dateTimePicker, + cascader, + stepper, + rate, + textarea, +} + class TDFormItem extends StatefulWidget { TDFormItem({ required this.type, @@ -12,8 +24,9 @@ class TDFormItem extends StatefulWidget { this.labelAlign, this.labelWidth, this.requiredMark, - this.rules, - this.showErrowMessage, + this.formRules, + this.itemRule, + this.showErrorMessage = true, this.maxLength, this.indicator, this.additionInfo, @@ -51,6 +64,9 @@ class TDFormItem extends StatefulWidget { /// 标签宽度,如果提供则覆盖Form的labelWidth final double? labelWidth; + /// TODO: + /// 竖直状态的两侧 padding + /// Input 控制器 var controller; @@ -67,11 +83,14 @@ class TDFormItem extends StatefulWidget { /// 是否显示必填标记(*) final bool? requiredMark; + /// 整个表单的校验规则 + final List? formRules; + /// 表单项验证规则 - final List? rules; + final List? itemRule; /// 是否显示错误信息 - final bool? showErrowMessage; + final bool showErrorMessage; /// TDTextarea的属性,最大长度 final int? maxLength; @@ -83,37 +102,27 @@ class TDFormItem extends StatefulWidget { _TDFormItemState createState() => _TDFormItemState(); } -/// 表格单元选用组件类型的枚举 -enum TDFormItemType { - input, - password, - radios, - dateTimePicker, - cascader, - stepper, - rate, - textarea, -} - class _TDFormItemState extends State { + /// 从 TDForm 继承获取整个表单的参数 + /// 获取真正的 LabelWidth double get LabelWidth { final inherited = TDFormInherited.of(context); - final double defaultLabelWidth = 8.0; // Default label width + final double defaultLabelWidth = 8.0; - // 优先使用 widget.labelWidth,如果不为空直接返回 + /// 如果 item 传入定制的 labelWidth 则使用 if (widget.labelWidth != null) { return widget.labelWidth as double; } - // 如果 widget.labelWidth 为空,使用 inherited.labelWidth + /// 使用 form 整体传入的 labelWidth if (inherited?.labelWidth != null) { return inherited!.labelWidth as double; } - // 如果两者都为空,返回默认值 return defaultLabelWidth; } + /// 获取 form 是否被禁用的状态 bool get FormState { final inherited = TDFormInherited.of(context); if (inherited?.disabled != null) { @@ -122,6 +131,7 @@ class _TDFormItemState extends State { return false; } + /// 获取 form 是否为水平排列的状态 bool get FormIsHorizontal { final inherited = TDFormInherited.of(context); if (inherited?.isHorizontal != null) { @@ -130,13 +140,54 @@ class _TDFormItemState extends State { return false; } - bool browseOn = false; + /// 获取 form 整体是否校验的信号状态 + bool get FormValidate { + final inherited = TDFormInherited.of(context); + return inherited!.isValidate; + } + + /// 获取整个表单的校验规则 + List get FormRules { + final inherited = TDFormInherited.of(context); + return inherited!.rules; + } + bool browseOn = false; String? _initData; String _selected_1 = ''; + /// 表单 item 的校验错误提示信息 + String? errorMessage; + + // 调用校验方法 + void startValidation() { + setState(() { + errorMessage = validate(); + }); + } + + /// 遍历校验规则并执行 + String? validate() { + String? value = widget.controller?.text; + + for (var rule in FormRules!) { + /// 只对类型匹配的项进行校验 + if (rule.type == widget.type) { + final result = rule.check(value); + if (result != null) { + /// 返回第一个不通过的错误信息 + return result; + } + } + } + return null; + } + @override Widget build(BuildContext context) { + if (FormValidate) { + startValidation(); + } if (FormIsHorizontal) { switch (widget.type) { case TDFormItemType.input: @@ -145,13 +196,23 @@ class _TDFormItemState extends State { hintText: widget.help, contentPadding: EdgeInsets.only(left: LabelWidth), border: InputBorder.none, + errorText: widget.showErrorMessage == true ? errorMessage : null, ), + + /// TODO: + /// 校验失败的提示 icon + // rightBtn: widget.showErrowMessage == true + // ? Icon( + // TDIcons.error_circle_filled, + // color: TDTheme.of(context).fontGyColor3, + // ) + // : null, leftLabel: widget.label, controller: widget.controller, backgroundColor: Colors.white, - // additionInfo: widget.additionInfo, - // additionInfoColor: TDTheme.of(context).errorColor6, + additionInfoColor: TDTheme.of(context).errorColor6, readOnly: FormState, + // required: widget.requiredMark, ); case TDFormItemType.password: return TDInput( @@ -159,6 +220,7 @@ class _TDFormItemState extends State { hintText: widget.help, contentPadding: EdgeInsets.only(left: LabelWidth), border: InputBorder.none, + errorText: widget.showErrorMessage == true ? errorMessage : null, ), type: TDInputType.normal, controller: widget.controller, @@ -191,7 +253,7 @@ class _TDFormItemState extends State { color: theme.whiteColor1, ), child: Padding( - padding: EdgeInsets.all(16), + padding: const EdgeInsets.all(16), child: Row( crossAxisAlignment: CrossAxisAlignment.center, children: [ @@ -300,6 +362,11 @@ class _TDFormItemState extends State { maxLength: widget.maxLength, indicator: widget.indicator, readOnly: FormState, + + /// TODO: + /// TDTextarea 目前没用实现提示词 ? 存在调用问题 + additionInfo: widget.showErrorMessage == true ? errorMessage : null, + additionInfoColor: TDTheme.of(context).errorColor6, onChanged: (value) { setState(() {}); }, @@ -312,7 +379,7 @@ class _TDFormItemState extends State { spacer: TDInputSpacer(iconLabelSpace: 0), type: TDInputType.twoLine, inputDecoration: InputDecoration( - contentPadding: EdgeInsets.only(left: 16), + contentPadding: const EdgeInsets.only(left: 16), hintText: widget.help, border: InputBorder.none, ), @@ -331,7 +398,7 @@ class _TDFormItemState extends State { TDInput( inputDecoration: InputDecoration( hintText: widget.help, - contentPadding: EdgeInsets.only(left: 16), + contentPadding: const EdgeInsets.only(left: 16), border: InputBorder.none, ), leftLabelSpace: 16, @@ -459,7 +526,7 @@ class _TDFormItemState extends State { ); case TDFormItemType.rate: return Container( - width: double.infinity, // 设置宽度为无限,横向占满父容器 + width: double.infinity, decoration: BoxDecoration( color: TDTheme.of(context).whiteColor1, ), @@ -491,6 +558,11 @@ class _TDFormItemState extends State { indicator: widget.indicator, readOnly: FormState, layout: TDTextareaLayout.vertical, + + /// TODO: + /// TDTextarea 目前没用实现提示词 ? 存在调用问题 + additionInfo: widget.showErrorMessage == true ? errorMessage : null, + additionInfoColor: TDTheme.of(context).errorColor6, onChanged: (value) { setState(() {}); }, diff --git a/tdesign-component/lib/src/components/form/td_form_validation.dart b/tdesign-component/lib/src/components/form/td_form_validation.dart new file mode 100644 index 000000000..2b5846d56 --- /dev/null +++ b/tdesign-component/lib/src/components/form/td_form_validation.dart @@ -0,0 +1,23 @@ +import '../../../tdesign_flutter.dart'; + +class TDFormValidation { + final String? Function(String?) validate; // 校验方法 + final String errorMessage; + + /// 校验对象的类型 + final TDFormItemType type; + + TDFormValidation({ + required this.validate, + required this.errorMessage, + required this.type, + }); + + // 执行校验逻辑 + String? check(String? value) { + if (validate(value) != null) { + return errorMessage; + } + return null; // 校验通过时返回 null + } +} diff --git a/tdesign-component/lib/tdesign_flutter.dart b/tdesign-component/lib/tdesign_flutter.dart index c2cd74ff7..03ab4d161 100644 --- a/tdesign-component/lib/tdesign_flutter.dart +++ b/tdesign-component/lib/tdesign_flutter.dart @@ -95,4 +95,5 @@ export 'src/theme/td_radius.dart'; export 'src/theme/td_shadows.dart'; export 'src/theme/td_spacers.dart'; export 'src/theme/td_theme.dart'; -export 'src/util/platform_util.dart'; \ No newline at end of file +export 'src/util/platform_util.dart'; +export 'src/components/form/td_form_validation.dart';