Skip to content

Commit

Permalink
fix:ControlState should be resolved based on user-defined order (#4556
Browse files Browse the repository at this point in the history
)

* ControlState: rename "" to "default"

* resolve ControlState on user-defined order

* fix failing tests

* remove breaking line
  • Loading branch information
ndonkoHenri authored Dec 12, 2024
1 parent 0378434 commit 0e73586
Show file tree
Hide file tree
Showing 4 changed files with 32 additions and 28 deletions.
42 changes: 21 additions & 21 deletions packages/flet/lib/src/utils/material_state.dart
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import 'dart:collection';
import 'package:flutter/material.dart';

WidgetStateProperty<T?>? getWidgetStateProperty<T>(
Expand All @@ -8,43 +9,42 @@ WidgetStateProperty<T?>? getWidgetStateProperty<T>(
}
var j = jsonDictValue;
if (j is! Map<String, dynamic>) {
j = {"": j};
j = {"default": j};
}
return WidgetStateFromJSON(j, converterFromJson, defaultValue);
}

class WidgetStateFromJSON<T> extends WidgetStateProperty<T?> {
late final Map<String, T> _states;
late final LinkedHashMap<String, T> _states;
late final T? _defaultValue;

WidgetStateFromJSON(Map<String, dynamic>? jsonDictValue,
T Function(dynamic) converterFromJson, T? defaultValue) {
_defaultValue = defaultValue;
_states = {};
if (jsonDictValue != null) {
jsonDictValue.forEach((stateStr, jv) {
stateStr.split(",").map((s) => s.trim().toLowerCase()).forEach((state) {
_states[state] = converterFromJson(jv);
});
});
}

// preserve user-defined order
_states = LinkedHashMap<String, T>.from(
jsonDictValue?.map((key, value) {
var normalizedKey = key.trim().toLowerCase();
// "" is now deprecated; use "default" instead
if (normalizedKey == "") normalizedKey = "default";
return MapEntry(normalizedKey, converterFromJson(value));
}) ??
{},
);
}

@override
T? resolve(Set<WidgetState> states) {
//debugPrint("WidgetStateFromJSON states: $states, _states: $_states");
// find specific state
for (var state in states) {
if (_states.containsKey(state.name)) {
return _states[state.name]!;
// Resolve using user-defined order in _states
for (var stateName in _states.keys) {
if (stateName == "default") continue; // Skip "default"; handled last
if (states.any((state) => state.name == stateName)) {
return _states[stateName];
}
}

// catch-all value
if (_states.containsKey("")) {
return _states[""];
}

return _defaultValue;
// Default state
return _states["default"] ?? _defaultValue;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -285,7 +285,6 @@ def __init__(
self.items = items
self.icon = icon
self.on_cancel = on_cancel
self.on_cancelled = on_cancelled
self.on_open = on_open
self.shape = shape
self.padding = padding
Expand Down
2 changes: 1 addition & 1 deletion sdk/python/packages/flet/src/flet/core/types.py
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ class ControlState(Enum):
SCROLLED_UNDER = "scrolledUnder"
DISABLED = "disabled"
ERROR = "error"
DEFAULT = ""
DEFAULT = "default"


class MainAxisAlignment(Enum):
Expand Down
15 changes: 10 additions & 5 deletions sdk/python/packages/flet/tests/test_datatable.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import flet as ft
from flet.core.protocol import Command

import flet as ft


def test_datatable_instance_no_attrs_set():
r = ft.DataTable(columns=[ft.DataColumn(label=ft.Text("Header"))])
Expand Down Expand Up @@ -38,7 +39,7 @@ def test_datarow_color_literal_material_state_as_string():
indent=0,
name=None,
values=["datarow"],
attrs={"color": '{"":"yellow"}'},
attrs={"color": '{"default":"yellow"}'},
commands=[],
),
Command(indent=2, name=None, values=["datacell"], attrs={}, commands=[]),
Expand All @@ -51,15 +52,19 @@ def test_datarow_color_literal_material_state_as_string():
def test_datarow_color_multiple_material_states_as_strings():
r = ft.DataRow(
cells=[ft.DataCell(content=ft.Text("Cell"))],
color={"selected": "red", "hovered": "blue", "": "yellow"},
color={
ft.ControlState.SELECTED: "red",
ft.ControlState.HOVERED: "blue",
ft.ControlState.DEFAULT: "yellow",
},
)
assert isinstance(r, ft.Control)
assert r._build_add_commands() == [
Command(
indent=0,
name=None,
values=["datarow"],
attrs={"color": '{"selected":"red","hovered":"blue","":"yellow"}'},
attrs={"color": '{"selected":"red","hovered":"blue","default":"yellow"}'},
commands=[],
),
Command(indent=2, name=None, values=["datacell"], attrs={}, commands=[]),
Expand All @@ -84,7 +89,7 @@ def test_datarow_color_multiple_material_states():
indent=0,
name=None,
values=["datarow"],
attrs={"color": '{"selected":"red","hovered":"blue","":"yellow"}'},
attrs={"color": '{"selected":"red","hovered":"blue","default":"yellow"}'},
commands=[],
),
Command(indent=2, name=None, values=["datacell"], attrs={}, commands=[]),
Expand Down

0 comments on commit 0e73586

Please sign in to comment.