Skip to content

Commit ec2f76c

Browse files
ndonkoHenrisyleishere
authored andcommitted
fix:ControlState should be resolved based on user-defined order (#4556)
* ControlState: rename "" to "default" * resolve ControlState on user-defined order * fix failing tests * remove breaking line
1 parent 6b8b9c0 commit ec2f76c

File tree

4 files changed

+32
-28
lines changed

4 files changed

+32
-28
lines changed

Diff for: packages/flet/lib/src/utils/material_state.dart

+21-21
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import 'dart:collection';
12
import 'package:flutter/material.dart';
23

34
WidgetStateProperty<T?>? getWidgetStateProperty<T>(
@@ -8,43 +9,42 @@ WidgetStateProperty<T?>? getWidgetStateProperty<T>(
89
}
910
var j = jsonDictValue;
1011
if (j is! Map<String, dynamic>) {
11-
j = {"": j};
12+
j = {"default": j};
1213
}
1314
return WidgetStateFromJSON(j, converterFromJson, defaultValue);
1415
}
1516

1617
class WidgetStateFromJSON<T> extends WidgetStateProperty<T?> {
17-
late final Map<String, T> _states;
18+
late final LinkedHashMap<String, T> _states;
1819
late final T? _defaultValue;
1920

2021
WidgetStateFromJSON(Map<String, dynamic>? jsonDictValue,
2122
T Function(dynamic) converterFromJson, T? defaultValue) {
2223
_defaultValue = defaultValue;
23-
_states = {};
24-
if (jsonDictValue != null) {
25-
jsonDictValue.forEach((stateStr, jv) {
26-
stateStr.split(",").map((s) => s.trim().toLowerCase()).forEach((state) {
27-
_states[state] = converterFromJson(jv);
28-
});
29-
});
30-
}
24+
25+
// preserve user-defined order
26+
_states = LinkedHashMap<String, T>.from(
27+
jsonDictValue?.map((key, value) {
28+
var normalizedKey = key.trim().toLowerCase();
29+
// "" is now deprecated; use "default" instead
30+
if (normalizedKey == "") normalizedKey = "default";
31+
return MapEntry(normalizedKey, converterFromJson(value));
32+
}) ??
33+
{},
34+
);
3135
}
3236

3337
@override
3438
T? resolve(Set<WidgetState> states) {
35-
//debugPrint("WidgetStateFromJSON states: $states, _states: $_states");
36-
// find specific state
37-
for (var state in states) {
38-
if (_states.containsKey(state.name)) {
39-
return _states[state.name]!;
39+
// Resolve using user-defined order in _states
40+
for (var stateName in _states.keys) {
41+
if (stateName == "default") continue; // Skip "default"; handled last
42+
if (states.any((state) => state.name == stateName)) {
43+
return _states[stateName];
4044
}
4145
}
4246

43-
// catch-all value
44-
if (_states.containsKey("")) {
45-
return _states[""];
46-
}
47-
48-
return _defaultValue;
47+
// Default state
48+
return _states["default"] ?? _defaultValue;
4949
}
5050
}

Diff for: sdk/python/packages/flet/src/flet/core/popup_menu_button.py

-1
Original file line numberDiff line numberDiff line change
@@ -285,7 +285,6 @@ def __init__(
285285
self.items = items
286286
self.icon = icon
287287
self.on_cancel = on_cancel
288-
self.on_cancelled = on_cancelled
289288
self.on_open = on_open
290289
self.shape = shape
291290
self.padding = padding

Diff for: sdk/python/packages/flet/src/flet/core/types.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,7 @@ class ControlState(Enum):
136136
SCROLLED_UNDER = "scrolledUnder"
137137
DISABLED = "disabled"
138138
ERROR = "error"
139-
DEFAULT = ""
139+
DEFAULT = "default"
140140

141141

142142
class MainAxisAlignment(Enum):

Diff for: sdk/python/packages/flet/tests/test_datatable.py

+10-5
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
1-
import flet as ft
21
from flet.core.protocol import Command
32

3+
import flet as ft
4+
45

56
def test_datatable_instance_no_attrs_set():
67
r = ft.DataTable(columns=[ft.DataColumn(label=ft.Text("Header"))])
@@ -38,7 +39,7 @@ def test_datarow_color_literal_material_state_as_string():
3839
indent=0,
3940
name=None,
4041
values=["datarow"],
41-
attrs={"color": '{"":"yellow"}'},
42+
attrs={"color": '{"default":"yellow"}'},
4243
commands=[],
4344
),
4445
Command(indent=2, name=None, values=["datacell"], attrs={}, commands=[]),
@@ -51,15 +52,19 @@ def test_datarow_color_literal_material_state_as_string():
5152
def test_datarow_color_multiple_material_states_as_strings():
5253
r = ft.DataRow(
5354
cells=[ft.DataCell(content=ft.Text("Cell"))],
54-
color={"selected": "red", "hovered": "blue", "": "yellow"},
55+
color={
56+
ft.ControlState.SELECTED: "red",
57+
ft.ControlState.HOVERED: "blue",
58+
ft.ControlState.DEFAULT: "yellow",
59+
},
5560
)
5661
assert isinstance(r, ft.Control)
5762
assert r._build_add_commands() == [
5863
Command(
5964
indent=0,
6065
name=None,
6166
values=["datarow"],
62-
attrs={"color": '{"selected":"red","hovered":"blue","":"yellow"}'},
67+
attrs={"color": '{"selected":"red","hovered":"blue","default":"yellow"}'},
6368
commands=[],
6469
),
6570
Command(indent=2, name=None, values=["datacell"], attrs={}, commands=[]),
@@ -84,7 +89,7 @@ def test_datarow_color_multiple_material_states():
8489
indent=0,
8590
name=None,
8691
values=["datarow"],
87-
attrs={"color": '{"selected":"red","hovered":"blue","":"yellow"}'},
92+
attrs={"color": '{"selected":"red","hovered":"blue","default":"yellow"}'},
8893
commands=[],
8994
),
9095
Command(indent=2, name=None, values=["datacell"], attrs={}, commands=[]),

0 commit comments

Comments
 (0)