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
18 changes: 18 additions & 0 deletions specs/027-slider-demo-alignment/acceptance.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# 验收记录

- Flutter 基线:`d2ff7a0aa5317c0f5412848610f2a1ae05b6dfa7`
- 小程序基线:`fe14543572bc7233226b2f08db6fc1424cd81ed2`
- 公开运行页:`https://tdesign.tencent.com/miniprogram/live/m2w/program/miniprogram/#!pages/slider/slider.html`
- 设计基线:Figma `mdBVCCVGERhxoZLle2eLT0`,节点 `24386:5254`;走查标注要求 Gy4 未激活轨道、Gy1 thumb 描边、数值与 thumb 对齐,垂直示例从顶部 0 向下递增。
- API Review:单/双值类型、受控值和禁用入口保持收敛;不新增垂直或胶囊 API。修复 `showThumbValue` 静态展示、显式 `ColorScheme` 优先级、默认 thumb、禁用轨道及禁用数值视觉。

## 验证结果

- Flutter 3.32.0 / 3.47.0:严格 `flutter analyze` 零告警;组件与清单测试各 25 项、Demo 测试各 5 项通过。
- 生产源码覆盖率:`209/209 = 100.00%`。
- 固定 Linux + Flutter 3.32.0:组件 Golden 1 项、Demo 明暗 Golden 2 项通过;更新后均立即无更新复跑。
- 示例代码生成检查通过;GitHub/CNB 共用的组件、Demo 与视觉测试清单自测通过。

## 未验证项

- Android/iOS 系统字体逐像素差异不由 Linux Golden 证明。
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
6 changes: 6 additions & 0 deletions specs/027-slider-demo-alignment/plan.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# Plan

1. 固定 Flutter 与小程序基线并截图。
2. Review 公开 API、静态数值语义和字段级主题优先级,优先 Flutter 受控与主题组合模式。
3. 修复组件默认视觉与主题回退,按 19 个实例重排 Demo,并补行为测试、组件覆盖率门禁、明暗 Golden。
4. 在 Flutter 3.32.0 与 latest 复验后独立提交 PR。
21 changes: 21 additions & 0 deletions specs/027-slider-demo-alignment/spec.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# Slider 公开 Demo 对齐

## 目标

按小程序公开 Demo 的可见矩阵,对齐单/双游标、数值、非零起点、刻度、禁用、胶囊与垂直示例,并建立独立行为与视觉回归。

## API Review

- `TSlider` / `TRangeSlider` 以值类型区分单值与区间,避免 `range` 布尔参数改变 value 类型。
- `value + onChanged` 遵循 Flutter 受控模式,`onChanged == null` 表示禁用,不引入 `defaultValue`。
- 数值和刻度由 `showThumbValue` / `showScaleValue` 与 formatter 负责;`showThumbValue` 持续显示拇指数值,非零起点沿用 `min/max/divisions`。
- 垂直方向由 `RotatedBox` 组合,胶囊外观由 `SliderTheme` 组合;二者不新增与 Flutter 框架重复的 API。
- 视觉字段按局部 `SliderTheme` > 显式 `ColorScheme` > TDesign token 解析;token 默认提供 Gy1 描边 thumb、品牌色轨道、Gy4 未激活轨道、区分前后轨道的禁用色,并以禁用文字 token 绘制禁用态常驻数值。

## 行为契约

- Demo 的 8 个公开区块与内部 19 个 Slider 实例在数量、顺序、类型和默认值上与固定小程序基线一致。
- 所有可交互实例均由页面持有状态;禁用实例 callback 为 null。
- 垂直组合仅旋转轨道和 thumb,数值与刻度文字保持正常阅读方向;最小值位于顶部,数值向下递增,与设计稿一致。
- `TRangeSlider` 在构建时拒绝落在 `min/max` 外的范围值。
- 不新增公开 API;修正既有 `showThumbValue` 语义和默认视觉属于缺陷修复。
7 changes: 7 additions & 0 deletions specs/027-slider-demo-alignment/tasks.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# Tasks

- [x] DONE 固定跨端基线并完成 API Review
- [x] DONE 对齐公开 Demo 的 8 个区块与 19 个组件实例
- [x] DONE 修复静态数值、Theme 优先级、thumb 与禁用视觉
- [x] DONE 更新功能测试、Golden、覆盖率并完成双版本验证
- [ ] DOING 提交、推送并远端复核 PR
4 changes: 2 additions & 2 deletions tdesign-component/example/assets/api/slider_api.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
| onChangeStart | ValueChanged<double>? | - | 开始拖动时触发。 |
| scaleFormatter | TSliderThumbFormatter? | - | 刻度值格式化回调。 |
| showScaleValue | bool | false | 是否显示刻度值。 |
| showThumbValue | bool | false | 是否显示拇指上方数值。 |
| showThumbValue | bool | false | 是否持续显示拇指上方数值。 |
| thumbFormatter | TSliderThumbFormatter? | - | 拇指上方数值格式化回调。 |
| value | double | - | 受控滑块值。 |

Expand All @@ -32,7 +32,7 @@
| onChangeStart | ValueChanged<RangeValues>? | - | 开始拖动时触发。 |
| scaleFormatter | TSliderThumbFormatter? | - | 刻度值格式化回调。 |
| showScaleValue | bool | false | 是否显示刻度值。 |
| showThumbValue | bool | false | 是否显示拇指上方数值。 |
| showThumbValue | bool | false | 是否持续显示拇指上方数值。 |
| thumbFormatter | TSliderThumbFormatter? | - | 拇指上方数值格式化回调。 |
| value | RangeValues | - | 受控范围值。 |

Expand Down
18 changes: 0 additions & 18 deletions tdesign-component/example/assets/code/slider._buildAdvanced.txt

This file was deleted.

This file was deleted.

71 changes: 71 additions & 0 deletions tdesign-component/example/assets/code/slider._buildCapsule.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
Widget _buildCapsule(BuildContext context) {
final capsuleTheme = SliderTheme.of(context).copyWith(
trackHeight: 16,
thumbShape: const RoundSliderThumbShape(enabledThumbRadius: 8),
rangeThumbShape: const RoundRangeSliderThumbShape(enabledThumbRadius: 8),
overlayShape: const RoundSliderOverlayShape(overlayRadius: 18),
);

Widget capsule(Widget slider) => Padding(
padding: const EdgeInsets.symmetric(vertical: 8),
child: SliderTheme(data: capsuleTheme, child: slider),
);

return Column(
children: [
capsule(
TSlider(
key: const ValueKey('slider-capsule'),
value: _capsule,
min: 0,
max: 100,
onChanged: (value) => setState(() => _capsule = value),
),
),
capsule(
TRangeSlider(
key: const ValueKey('slider-capsule-range'),
value: _capsuleRange,
min: 0,
max: 100,
onChanged: (value) => setState(() => _capsuleRange = value),
),
),
capsule(
TRangeSlider(
key: const ValueKey('slider-capsule-labeled-range'),
value: _capsuleLabeledRange,
min: 0,
max: 100,
showThumbValue: true,
thumbFormatter: _percent,
onChanged: (value) => setState(() => _capsuleLabeledRange = value),
),
),
capsule(
TSlider(
key: const ValueKey('slider-capsule-scale'),
value: _capsuleScale,
min: 0,
max: 100,
divisions: 5,
showScaleValue: true,
scaleFormatter: _integer,
onChanged: (value) => setState(() => _capsuleScale = value),
),
),
capsule(
TRangeSlider(
key: const ValueKey('slider-capsule-scale-range'),
value: _capsuleScaleRange,
min: 0,
max: 100,
divisions: 5,
showScaleValue: true,
scaleFormatter: _integer,
onChanged: (value) => setState(() => _capsuleScaleRange = value),
),
),
],
);
}
35 changes: 28 additions & 7 deletions tdesign-component/example/assets/code/slider._buildDisabled.txt
Original file line number Diff line number Diff line change
@@ -1,11 +1,32 @@
Widget _buildDisabled(BuildContext context) => const Column(
mainAxisSize: MainAxisSize.min,
children: [
TSlider(key: ValueKey('slider-disabled'), value: 35, min: 0, max: 100),
SizedBox(height: 16),
Row(
children: [
TSlider(value: 40, min: 0, max: 100),
TRangeSlider(
value: RangeValues(20, 70),
min: 0,
max: 100,
TText('0%'),
Expanded(
child: TRangeSlider(
key: ValueKey('slider-disabled-labeled-range'),
value: RangeValues(40, 60),
min: 0,
max: 100,
showThumbValue: true,
thumbFormatter: _percent,
),
),
TText('100%'),
],
);
),
SizedBox(height: 16),
TRangeSlider(
key: ValueKey('slider-disabled-scale-range'),
value: RangeValues(20, 60),
min: 0,
max: 100,
divisions: 5,
showScaleValue: true,
scaleFormatter: _integer,
),
],
);
36 changes: 36 additions & 0 deletions tdesign-component/example/assets/code/slider._buildLabeled.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
Widget _buildLabeled(BuildContext context) {
return Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
_panel(
TSlider(
key: const ValueKey('slider-labeled'),
value: _labeled,
min: 0,
max: 100,
showThumbValue: true,
thumbFormatter: _percent,
onChanged: (value) => setState(() => _labeled = value),
),
),
_subsection(context, '带数值双游标滑块'),
Row(
children: [
const TText('0%'),
Expanded(
child: TRangeSlider(
key: const ValueKey('slider-labeled-range'),
value: _labeledRange,
min: 0,
max: 100,
showThumbValue: true,
thumbFormatter: _percent,
onChanged: (value) => setState(() => _labeledRange = value),
),
),
const TText('100%'),
],
),
],
);
}
12 changes: 12 additions & 0 deletions tdesign-component/example/assets/code/slider._buildNonZero.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
Widget _buildNonZero(BuildContext context) => _panel(
TSlider(
key: const ValueKey('slider-non-zero'),
value: _nonZero,
min: 20,
max: 100,
divisions: 4,
showScaleValue: true,
scaleFormatter: _integer,
onChanged: (value) => setState(() => _nonZero = value),
),
);
21 changes: 9 additions & 12 deletions tdesign-component/example/assets/code/slider._buildRange.txt
Original file line number Diff line number Diff line change
@@ -1,12 +1,9 @@
Widget _buildRange(BuildContext context) => _withValueLabel(
context,
label:
'当前范围:${rangeValue.start.toStringAsFixed(0)} - ${rangeValue.end.toStringAsFixed(0)}',
child: TRangeSlider(
value: rangeValue,
min: 0,
max: 100,
divisions: 100,
onChanged: (next) => setState(() => rangeValue = next),
),
);
Widget _buildRange(BuildContext context) => _panel(
TRangeSlider(
key: const ValueKey('slider-range'),
value: _range,
min: 0,
max: 100,
onChanged: (value) => setState(() => _range = value),
),
);
32 changes: 32 additions & 0 deletions tdesign-component/example/assets/code/slider._buildScale.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
Widget _buildScale(BuildContext context) {
return Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
_panel(
TSlider(
key: const ValueKey('slider-scale'),
value: _scale,
min: 0,
max: 100,
divisions: 5,
showScaleValue: true,
scaleFormatter: _integer,
onChanged: (value) => setState(() => _scale = value),
),
),
_subsection(context, '带刻度双游标滑块'),
_panel(
TRangeSlider(
key: const ValueKey('slider-scale-range'),
value: _scaleRange,
min: 0,
max: 100,
divisions: 5,
showScaleValue: true,
scaleFormatter: _integer,
onChanged: (value) => setState(() => _scaleRange = value),
),
),
],
);
}
19 changes: 9 additions & 10 deletions tdesign-component/example/assets/code/slider._buildSingle.txt
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
Widget _buildSingle(BuildContext context) => _withValueLabel(
context,
label: '当前值:${singleValue.toStringAsFixed(0)}',
child: TSlider(
value: singleValue,
min: 0,
max: 100,
onChanged: (next) => setState(() => singleValue = next),
),
);
Widget _buildSingle(BuildContext context) => _panel(
TSlider(
key: const ValueKey('slider-single'),
value: _single,
min: 0,
max: 100,
onChanged: (value) => setState(() => _single = value),
),
);
27 changes: 0 additions & 27 deletions tdesign-component/example/assets/code/slider._buildTheme.txt

This file was deleted.

Loading
Loading