Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions specs/components/009-Feedback-ActionSheet/acceptance.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,9 @@
未绑定唯一候选的结果不作为当前通过证明;旧命令与流水由Git历史追溯。

当前待办见 [tasks.md](./tasks.md);实际执行入口见[贡献规范](../../../CONTRIBUTING.md#组件测试与-ci-回归门禁)。清理不关闭未完成项。

## 2026-10-28 弹层安全区修复验证

列表组件在 showCancel 开关下的安全区实际高度回归、命令式入口及既有 Demo 检查通过;无取消按钮明暗两张 Linux Flutter 3.32.0 Golden 精确通过。以上视觉结论绑定本 PR 缩减前的 9505a2b5;本次保留的安全区实现、示例、测试与四张新基线均未改变,既有 PNG 不更新。本次已移除全部 Dialog 修改,键盘避让与横屏滚动不在交付范围。

缩减后的本地候选在 Flutter 3.32.0 / 3.47.8 各通过 58 项 ActionSheet 与测试调度回归,各通过 33 项相关公开示例测试,组件包严格静态分析无诊断;远端 CI 仍需按更新后的 PR head 核对。未重新执行 Android / iOS 设备验证。
4 changes: 4 additions & 0 deletions specs/components/009-Feedback-ActionSheet/plan.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,7 @@ fixed/paged/scroll 互斥布局各自持有有效参数,选择回调返回稳
4. 结果绑定候选、环境和必要证据,更新 acceptance.md;真实剩余工作只在 tasks.md 维护。

本次文档整理不执行上述实现或候选验收,不据旧命令流水推定当前检查通过。

## 底部安全区修复

将内部列表的安全区移出取消按钮。复用现有列表测试,比较显示/隐藏取消按钮时开启安全区所增加的实际高度;仅补明暗各一张无取消按钮的代表性 Golden,原公开 Demo 基线不刷新。
4 changes: 4 additions & 0 deletions specs/components/009-Feedback-ActionSheet/spec.md
Original file line number Diff line number Diff line change
Expand Up @@ -128,3 +128,7 @@ ActionSheet 当前 Demo 以自定义业务场景取代了官方小程序的公
## Popup 关闭保留的间接影响

showList、showGrid 和 showGridSections 使用 Popup 默认 false 配置,随 Popup 关闭保留修复,内容 State 在关闭后保留,同句柄 open 可重开,所属 Navigator 卸载时释放;直接使用独立面板不涉及该会话缓存。三个入口未提供 destroyOnClose,不能直接配置 true。参数限制与通用资源风险在本站 ActionSheet FAQ 说明,并精准链接 Popup FAQ;完整生命周期风险见 [Popup Spec](../018-Feedback-Popup/spec.md#faq-展示与-actionsheet-间接影响)。本轮只补文档,不修改入口、默认值、回调或绑定规则。

## 底部安全区

内部列表的底部安全区由 `useSafeArea` 决定,不依赖 `showCancel`。命令式入口继续由 Popup 统一避让,内部列表关闭自身避让,避免重复留白;不改变公开入口默认值。
6 changes: 6 additions & 0 deletions specs/components/025-Input-DateTimePicker/acceptance.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,3 +37,9 @@
未绑定唯一候选的结果不作为当前通过证明;旧命令与流水由Git历史追溯。

当前待办见 [tasks.md](./tasks.md);实际执行入口见[贡献规范](../../../CONTRIBUTING.md#组件测试与-ci-回归门禁)。清理不关闭未完成项。

## 2026-10-28 弹层安全区修复验证

9 个公开示例显式开启安全区,现有确认流程测试增加底部安全区几何断言;既有 Linux Flutter 3.32.0 视觉基线原样通过,未增加重复 Golden。以上视觉结论绑定本 PR 缩减前的 9505a2b5;本次保留的安全区实现、示例、测试与四张新基线均未改变,既有 PNG 不更新。本次已移除全部 Dialog 修改,键盘避让与横屏滚动不在交付范围。

缩减后的本地候选在 Flutter 3.32.0 / 3.47.8 各通过 58 项 ActionSheet 与测试调度回归,各通过 33 项相关公开示例测试,组件包严格静态分析无诊断;远端 CI 仍需按更新后的 PR head 核对。未重新执行 Android / iOS 设备验证。
4 changes: 4 additions & 0 deletions specs/components/025-Input-DateTimePicker/spec.md
Original file line number Diff line number Diff line change
Expand Up @@ -89,3 +89,7 @@ Picker 与 DateTimePicker 均在全部滚轮停止后恢复父级未接受的候
验收标准描述应满足的行为,不表示已执行或通过;执行范围与证据见 [acceptance.md](./acceptance.md),剩余事项只在 [tasks.md](./tasks.md) 维护。

跨组件配置职责见 [Theme 契约](../../engineering/048-Theme-configuration-contracts/spec.md),视觉方法见 [Golden 规范](../../engineering/044-Testing-golden-regression/spec.md)。

## 示例的安全区职责

九个日期时间选择器示例通过既有 `TPickerPopup.show(useSafeArea: true)` 显式避让底部系统区域;不改变组件或弹层公开默认值。弹层安全区布局与验证复用 [Picker 契约](../026-Input-Picker/spec.md#示例的安全区职责),在已有确认流程测试中补充底部位置断言,不重复建立相同布局的 Golden 矩阵。
6 changes: 6 additions & 0 deletions specs/components/026-Input-Picker/acceptance.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,3 +39,9 @@
范围:选中/非选中/禁用状态字体、itemBuilder 上下文、布局包装、显式与局部样式以及滚轮布局。

最终候选、双版本功能与视觉结果集中记录在 [Theme 文字槽验收](../../engineering/048-Theme-configuration-contracts/acceptance.md#自定义文字槽统一验收2026-10-22),本组件不重复保存验证流水。既有设备及设计待办继续保留;本地结果不替代当前候选的远端 CI 或真机验证,截图不存 Spec。

## 2026-10-28 弹层安全区修复验证

5 个公开调用入口的现有布局测试补充底部安全区几何断言,代表性地区入口明暗两张 Linux Flutter 3.32.0 Golden 精确通过。以上视觉结论绑定本 PR 缩减前的 9505a2b5;本次保留的安全区实现、示例、测试与四张新基线均未改变,既有 PNG 不更新。本次已移除全部 Dialog 修改,键盘避让与横屏滚动不在交付范围。

缩减后的本地候选在 Flutter 3.32.0 / 3.47.8 各通过 58 项 ActionSheet 与测试调度回归,各通过 33 项相关公开示例测试,组件包严格静态分析无诊断;远端 CI 仍需按更新后的 PR head 核对。未重新执行 Android / iOS 设备验证。
4 changes: 4 additions & 0 deletions specs/components/026-Input-Picker/spec.md
Original file line number Diff line number Diff line change
Expand Up @@ -113,3 +113,7 @@ TPickerThemeData 的 height 必须为有限正数、itemCount 必须大于零(
## destroyOnClose 关闭生命周期

沿用 Popup 的关闭销毁策略,默认 false;true 关闭后释放,false 同一句柄在同一 Navigator 内 open 复用真实 State,所属 Navigator 卸载时自动清理。切换 Navigator 或重新 show 创建新 State。API 和 Controller 规则不变;默认 false 的释放时机改变、旧 true 的遮挡规则改变及长期保留风险见 [Popup Spec](../018-Feedback-Popup/spec.md#destroyonclose-关闭销毁修复独立交付)。Drawer 保持其 1.0.0 一次性关闭释放规则,不适用上述保留策略。

## 示例的安全区职责

公开选择器示例显式使用 `TPickerPopup.show(useSafeArea: true)`,让整个面板避让底部系统区域;保留标准头部与滚轮高度。`TPickerPopup` 的公开默认值仍为 false,业务可选择背景贴边并仅在内容内部处理安全区。复用已有几何测试覆盖五个示例入口,并仅增加明暗两张代表性安全区 Golden。
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ class _DateTimePickerDateExampleState extends State<DateTimePickerDateExample> {
void showPicker() {
var draft = value;
TPickerPopup.show(
useSafeArea: true,
context,
headerBuilder: (_, close) => TPopupHeader(
cancelButton: TToolbarPressable(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ class _DateTimePickerDateTimeExampleState
void showPicker() {
var draft = value;
TPickerPopup.show(
useSafeArea: true,
context,
headerBuilder: (_, close) => TPopupHeader(
cancelButton: TToolbarPressable(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ class _DateTimePickerMinuteExampleState
void showPicker() {
var draft = value;
TPickerPopup.show(
useSafeArea: true,
context,
headerBuilder: (_, close) => TPopupHeader(
cancelButton: TToolbarPressable(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ class _DateTimePickerMonthDayExampleState
void showPicker() {
var draft = value;
TPickerPopup.show(
useSafeArea: true,
context,
headerBuilder: (_, close) => TPopupHeader(
cancelButton: TToolbarPressable(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ class _DateTimePickerMonthExampleState
void showPicker() {
var draft = value;
TPickerPopup.show(
useSafeArea: true,
context,
headerBuilder: (_, close) => TPopupHeader(
cancelButton: TToolbarPressable(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ class _DateTimePickerSecondExampleState
void showPicker() {
var draft = value;
TPickerPopup.show(
useSafeArea: true,
context,
headerBuilder: (_, close) => TPopupHeader(
cancelButton: TToolbarPressable(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ class _DateTimePickerTitleExampleState
void showPicker() {
var draft = value;
TPickerPopup.show(
useSafeArea: true,
context,
headerBuilder: (_, close) => TPopupHeader(
cancelButton: TToolbarPressable(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ class _DateTimePickerWeekExampleState extends State<DateTimePickerWeekExample> {
void showPicker() {
var draft = value;
TPickerPopup.show(
useSafeArea: true,
context,
headerBuilder: (_, close) => TPopupHeader(
cancelButton: TToolbarPressable(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ class _DateTimePickerWithoutTitleExampleState
void showPicker() {
var draft = value;
TPickerPopup.show(
useSafeArea: true,
context,
headerBuilder: (_, close) => TPopupHeader(
cancelButton: TToolbarPressable(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ class _PickerAreaExampleState extends State<PickerAreaExample> {
}) {
var draft = List<Object?>.of(value);
TPickerPopup.show(
useSafeArea: true,
Navigator.of(context).context,
headerBuilder: (_, close) => TPopupHeader(
cancelButton: TToolbarPressable(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ class _PickerBaseExampleState extends State<PickerBaseExample> {
}) {
var draft = List<Object?>.of(value);
TPickerPopup.show(
useSafeArea: true,
Navigator.of(context).context,
headerBuilder: (_, close) => TPopupHeader(
cancelButton: TToolbarPressable(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ class _PickerTimeExampleState extends State<PickerTimeExample> {
}) {
var draft = List<Object?>.of(value);
TPickerPopup.show(
useSafeArea: true,
Navigator.of(context).context,
headerBuilder: (_, close) => TPopupHeader(
cancelButton: TToolbarPressable(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,7 @@ class _PickerTitleExampleState extends State<PickerTitleExample> {
}) {
var draft = List<Object?>.of(value);
TPickerPopup.show(
useSafeArea: true,
Navigator.of(context).context,
headerBuilder: (_, close) => TPopupHeader(
cancelButton: TToolbarPressable(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ class _DateTimePickerDateExampleState extends State<DateTimePickerDateExample> {
void showPicker() {
var draft = value;
TPickerPopup.show(
useSafeArea: true,
context,
headerBuilder: (_, close) => TPopupHeader(
cancelButton: TToolbarPressable(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ class _DateTimePickerDateTimeExampleState
void showPicker() {
var draft = value;
TPickerPopup.show(
useSafeArea: true,
context,
headerBuilder: (_, close) => TPopupHeader(
cancelButton: TToolbarPressable(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ class _DateTimePickerMinuteExampleState
void showPicker() {
var draft = value;
TPickerPopup.show(
useSafeArea: true,
context,
headerBuilder: (_, close) => TPopupHeader(
cancelButton: TToolbarPressable(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ class _DateTimePickerMonthDayExampleState
void showPicker() {
var draft = value;
TPickerPopup.show(
useSafeArea: true,
context,
headerBuilder: (_, close) => TPopupHeader(
cancelButton: TToolbarPressable(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ class _DateTimePickerMonthExampleState
void showPicker() {
var draft = value;
TPickerPopup.show(
useSafeArea: true,
context,
headerBuilder: (_, close) => TPopupHeader(
cancelButton: TToolbarPressable(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ class _DateTimePickerSecondExampleState
void showPicker() {
var draft = value;
TPickerPopup.show(
useSafeArea: true,
context,
headerBuilder: (_, close) => TPopupHeader(
cancelButton: TToolbarPressable(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ class _DateTimePickerTitleExampleState
void showPicker() {
var draft = value;
TPickerPopup.show(
useSafeArea: true,
context,
headerBuilder: (_, close) => TPopupHeader(
cancelButton: TToolbarPressable(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ class _DateTimePickerWeekExampleState extends State<DateTimePickerWeekExample> {
void showPicker() {
var draft = value;
TPickerPopup.show(
useSafeArea: true,
context,
headerBuilder: (_, close) => TPopupHeader(
cancelButton: TToolbarPressable(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ class _DateTimePickerWithoutTitleExampleState
void showPicker() {
var draft = value;
TPickerPopup.show(
useSafeArea: true,
context,
headerBuilder: (_, close) => TPopupHeader(
cancelButton: TToolbarPressable(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ class _PickerAreaExampleState extends State<PickerAreaExample> {
}) {
var draft = List<Object?>.of(value);
TPickerPopup.show(
useSafeArea: true,
Navigator.of(context).context,
headerBuilder: (_, close) => TPopupHeader(
cancelButton: TToolbarPressable(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ class _PickerBaseExampleState extends State<PickerBaseExample> {
}) {
var draft = List<Object?>.of(value);
TPickerPopup.show(
useSafeArea: true,
Navigator.of(context).context,
headerBuilder: (_, close) => TPopupHeader(
cancelButton: TToolbarPressable(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ class _PickerTimeExampleState extends State<PickerTimeExample> {
}) {
var draft = List<Object?>.of(value);
TPickerPopup.show(
useSafeArea: true,
Navigator.of(context).context,
headerBuilder: (_, close) => TPopupHeader(
cancelButton: TToolbarPressable(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,7 @@ class _PickerTitleExampleState extends State<PickerTitleExample> {
}) {
var draft = List<Object?>.of(value);
TPickerPopup.show(
useSafeArea: true,
Navigator.of(context).context,
headerBuilder: (_, close) => TPopupHeader(
cancelButton: TToolbarPressable(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,8 @@ void main() {
testWidgets('DateTimePicker popup commits only after confirm', (
tester,
) async {
tester.view.padding = const FakeViewPadding(bottom: 34);
addTearDown(tester.view.resetPadding);
await pumpFullDemoPage(
tester,
dateTimePickerDemoPageTestSpec,
Expand All @@ -211,6 +213,10 @@ void main() {
await tester.pumpAndSettle();
final panel = find.byKey(const ValueKey('date-time-picker-month-panel'));
expect(tester.getSize(panel).height, 200);
expect(
tester.getBottomLeft(panel).dy,
tester.view.physicalSize.height / tester.view.devicePixelRatio - 34,
);
tester.widget<TDateTimePicker>(panel).onChanged!(
const TDateTimePickerValue(year: 2026, month: 8),
);
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
21 changes: 18 additions & 3 deletions tdesign-component/example/test/picker/picker_demo_golden_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,23 @@ void main() {
}

for (final mode in [ThemeMode.light, ThemeMode.dark]) {
testWidgets('picker ${mode.name} bottom safe area opened golden', (
tester,
) async {
tester.view.padding = const FakeViewPadding(bottom: 34);
addTearDown(tester.view.resetPadding);
await pumpDemoPageAtPhoneViewport(tester, pickerDemoPageTestSpec, mode);
final trigger = find.byKey(const ValueKey('picker-city-trigger'));
await tester.ensureVisible(trigger);
await tester.tap(trigger);
await tester.pumpAndSettle();
await expectLater(
find.byType(Overlay),
matchesGoldenFile('goldens/picker_safe_area_${mode.name}.png'),
);
await disposeDemoPage(tester);
}, tags: 'golden');

testWidgets('picker linked changes ${mode.name} golden', (tester) async {
await pumpDemoPageAtPhoneViewport(tester, pickerDemoPageTestSpec, mode);
final trigger = find.byKey(const ValueKey('picker-area-trigger'));
Expand Down Expand Up @@ -75,9 +92,7 @@ void main() {
expect(tester.takeException(), isNull);
await expectLater(
find.byType(Overlay),
matchesGoldenFile(
'goldens/picker_${id}_opened_${mode.name}.png',
),
matchesGoldenFile('goldens/picker_${id}_opened_${mode.name}.png'),
);
await disposeDemoPage(tester);
}, tags: 'golden');
Expand Down
9 changes: 9 additions & 0 deletions tdesign-component/example/test/picker/picker_demo_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,8 @@ void main() {
testWidgets('all Picker popups share the design geometry in ${mode.name}', (
tester,
) async {
tester.view.padding = const FakeViewPadding(bottom: 34);
addTearDown(tester.view.resetPadding);
await pumpDemoPageAtPhoneViewport(tester, pickerDemoPageTestSpec, mode);
const titles = {
'city': '选择地区',
Expand All @@ -124,6 +126,13 @@ void main() {
await tester.ensureVisible(trigger);
await tester.tap(trigger);
await tester.pumpAndSettle();
expect(
tester
.getBottomLeft(find.byKey(ValueKey('picker-${entry.key}-panel')))
.dy,
778,
reason: '${entry.key} should avoid the bottom system inset',
);
final wheel = find.byType(ListWheelScrollView).first;
expect(tester.getSize(wheel).height, 200, reason: entry.key);
expect(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,11 @@ class TActionSheetList<T> extends StatelessWidget {
if (subtitle?.isNotEmpty ?? false) _buildDescription(context),
Flexible(child: _buildOptionsList(context)),
if (showCancel) _buildCancelButton(context),
if (useSafeArea)
Container(
color: context.tTheme.bgColorContainer,
height: MediaQuery.paddingOf(context).bottom,
),
],
),
),
Expand Down Expand Up @@ -413,15 +418,6 @@ class TActionSheetList<T> extends StatelessWidget {

/// 构建取消按钮
Widget _buildCancelButton(BuildContext context) {
return Column(
children: [
buildCancelButton(context, false, cancelText, onCancel),
if (useSafeArea)
Container(
color: context.tTheme.bgColorContainer,
height: MediaQuery.of(context).padding.bottom,
),
],
);
return buildCancelButton(context, false, cancelText, onCancel);
}
}
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Loading