diff --git a/packages/flet/lib/src/utils/theme.dart b/packages/flet/lib/src/utils/theme.dart index 025a0aad6f..5b6b6d8067 100644 --- a/packages/flet/lib/src/utils/theme.dart +++ b/packages/flet/lib/src/utils/theme.dart @@ -136,7 +136,7 @@ ThemeData parseTheme( canvasColor: parseColor(value?["canvas_color"], theme), scaffoldBackgroundColor: parseColor(value?["scaffold_bgcolor"], theme), cardColor: parseColor(value?["card_bgcolor"], theme), - dividerColor: dividerTheme?.color, + dividerColor: parseColor(value?["divider_color"], theme), hintColor: parseColor(value?["hint_color"], theme), shadowColor: colorScheme?.shadow, secondaryHeaderColor: parseColor(value?["secondary_header_color"], theme), diff --git a/sdk/python/examples/apps/routing-navigation/building-views-on-route-change.py b/sdk/python/examples/apps/routing-navigation/building-views-on-route-change.py index ec1c603834..8f219bc935 100644 --- a/sdk/python/examples/apps/routing-navigation/building-views-on-route-change.py +++ b/sdk/python/examples/apps/routing-navigation/building-views-on-route-change.py @@ -6,8 +6,14 @@ def main(page: ft.Page): print("Initial route:", page.route) - def route_change(e): - print("Route change:", e.route) + async def open_mail_settings(e): + await page.push_route("/settings/mail") + + async def open_settings(e): + await page.push_route("/settings") + + def route_change(): + print("Route change:", page.route) page.views.clear() page.views.append( ft.View( @@ -50,22 +56,17 @@ def route_change(e): ) page.update() - def view_pop(e): - print("View pop:", e.view) - page.views.pop() - top_view = page.views[-1] - page.go(top_view.route) + async def view_pop(e): + if e.view is not None: + print("View pop:", e.view) + page.views.remove(e.view) + top_view = page.views[-1] + await page.push_route(top_view.route) page.on_route_change = route_change page.on_view_pop = view_pop - def open_mail_settings(e): - page.go("/settings/mail") - - def open_settings(e): - page.go("/settings") - - page.go(page.route) + route_change() ft.app(target=main, view=ft.AppView.WEB_BROWSER) diff --git a/sdk/python/examples/apps/routing-navigation/home-store.py b/sdk/python/examples/apps/routing-navigation/home-store.py index 475a182eba..8f4e137e73 100644 --- a/sdk/python/examples/apps/routing-navigation/home-store.py +++ b/sdk/python/examples/apps/routing-navigation/home-store.py @@ -1,45 +1,55 @@ +import asyncio + import flet as ft def main(page: ft.Page): page.title = "Routes Example" - def route_change(e): + def route_change(): page.views.clear() page.views.append( ft.View( - "/", - [ + route="/", + controls=[ ft.AppBar( title=ft.Text("Flet app"), bgcolor=ft.Colors.SURFACE_BRIGHT ), - ft.Button("Visit Store", on_click=lambda _: page.go("/store")), + ft.Button( + "Visit Store", + on_click=lambda: asyncio.create_task(page.push_route("/store")), + ), ], ) ) if page.route == "/store": page.views.append( ft.View( - "/store", - [ + route="/store", + controls=[ ft.AppBar( title=ft.Text("Store"), bgcolor=ft.Colors.SURFACE_BRIGHT ), - ft.Button("Go Home", on_click=lambda _: page.go("/")), + ft.Button( + "Go Home", + on_click=lambda: asyncio.create_task(page.push_route("/")), + ), ], ) ) page.update() - def view_pop(e): - page.views.pop() - top_view = page.views[-1] - page.go(top_view.route) + async def view_pop(e): + if e.view is not None: + print("View pop:", e.view) + page.views.remove(e.view) + top_view = page.views[-1] + await page.push_route(top_view.route) page.on_route_change = route_change page.on_view_pop = view_pop - page.go(page.route) + route_change() ft.run(main) diff --git a/sdk/python/examples/apps/routing-navigation/initial-route.py b/sdk/python/examples/apps/routing-navigation/initial-route.py index bd6190cfbb..a41435f5e0 100644 --- a/sdk/python/examples/apps/routing-navigation/initial-route.py +++ b/sdk/python/examples/apps/routing-navigation/initial-route.py @@ -6,4 +6,4 @@ def main(page: Page): page.add(Text(f"Initial route: {page.route}")) -flet.app(target=main, view=flet.AppView.WEB_BROWSER) +flet.run(main) diff --git a/sdk/python/examples/apps/routing-navigation/requirements.txt b/sdk/python/examples/apps/routing-navigation/requirements.txt deleted file mode 100644 index 9f5592458b..0000000000 --- a/sdk/python/examples/apps/routing-navigation/requirements.txt +++ /dev/null @@ -1 +0,0 @@ -flet>=0.25.1 diff --git a/sdk/python/examples/apps/routing-navigation/route-change-event.py b/sdk/python/examples/apps/routing-navigation/route-change-event.py index 77b92a305b..4834915ad7 100644 --- a/sdk/python/examples/apps/routing-navigation/route-change-event.py +++ b/sdk/python/examples/apps/routing-navigation/route-change-event.py @@ -12,4 +12,4 @@ def route_change(e): page.update() -flet.app(target=main, view=flet.AppView.WEB_BROWSER) +flet.run(main) diff --git a/sdk/python/examples/controls/charts/candlestick_chart/example_1.py b/sdk/python/examples/controls/charts/candlestick_chart/example_1.py index 96ace3edad..4cfb62c259 100644 --- a/sdk/python/examples/controls/charts/candlestick_chart/example_1.py +++ b/sdk/python/examples/controls/charts/candlestick_chart/example_1.py @@ -1,5 +1,5 @@ import flet as ft -import flet_charts as ftc +import flet_charts as fch CANDLE_DATA = [ ("Mon", 24.8, 28.6, 23.9, 27.2), @@ -12,19 +12,19 @@ ] -def build_spots() -> list[ftc.CandlestickChartSpot]: +def build_spots() -> list[fch.CandlestickChartSpot]: """Create candlestick spots from the static data.""" - spots: list[ftc.CandlestickChartSpot] = [] + spots: list[fch.CandlestickChartSpot] = [] for index, (label, open_, high, low, close) in enumerate(CANDLE_DATA): spots.append( - ftc.CandlestickChartSpot( + fch.CandlestickChartSpot( x=float(index), open=open_, high=high, low=low, close=close, selected=index == len(CANDLE_DATA) - 1, - tooltip=ftc.CandlestickChartSpotTooltip( + tooltip=fch.CandlestickChartSpotTooltip( text=( f"{label}\n" f"Open: {open_:0.1f}\n" @@ -52,7 +52,7 @@ def main(page: ft.Page): min_y = min(low for _, _, _, low, _ in CANDLE_DATA) - 1 max_y = max(high for _, _, _, _, high in CANDLE_DATA) + 1 - def handle_event(e: ftc.CandlestickChartEvent): + def handle_event(e: fch.CandlestickChartEvent): if e.spot_index is not None and e.spot_index >= 0: label, open_, high, low, close = CANDLE_DATA[e.spot_index] info.value = ( @@ -63,7 +63,7 @@ def handle_event(e: ftc.CandlestickChartEvent): info.value = f"{e.type.value} • outside candlesticks" info.update() - chart = ftc.CandlestickChart( + chart = fch.CandlestickChart( expand=True, min_x=min_x, max_x=max_x, @@ -72,17 +72,17 @@ def handle_event(e: ftc.CandlestickChartEvent): baseline_x=0, baseline_y=min_y, bgcolor=ft.Colors.with_opacity(0.2, ft.Colors.BLUE_GREY_900), - horizontal_grid_lines=ftc.ChartGridLines(interval=2, dash_pattern=[2, 2]), - vertical_grid_lines=ftc.ChartGridLines(interval=1, dash_pattern=[2, 2]), - left_axis=ftc.ChartAxis( + horizontal_grid_lines=fch.ChartGridLines(interval=2, dash_pattern=[2, 2]), + vertical_grid_lines=fch.ChartGridLines(interval=1, dash_pattern=[2, 2]), + left_axis=fch.ChartAxis( label_spacing=2, label_size=60, title=ft.Text("Price (k USD)", color=ft.Colors.GREY_300), show_min=False, ), - bottom_axis=ftc.ChartAxis( + bottom_axis=fch.ChartAxis( labels=[ - ftc.ChartAxisLabel( + fch.ChartAxisLabel( value=index, label=ft.Text(name, color=ft.Colors.GREY_300), ) @@ -94,9 +94,9 @@ def handle_event(e: ftc.CandlestickChartEvent): show_max=False, ), spots=spots, - tooltip=ftc.CandlestickChartTooltip( + tooltip=fch.CandlestickChartTooltip( bgcolor=ft.Colors.BLUE_GREY_800, - horizontal_alignment=ftc.HorizontalAlignment.CENTER, + horizontal_alignment=fch.HorizontalAlignment.CENTER, fit_inside_horizontally=True, ), on_event=handle_event, diff --git a/sdk/python/examples/controls/charts/line_chart/dashboard_declarative.py b/sdk/python/examples/controls/charts/line_chart/dashboard_declarative.py new file mode 100644 index 0000000000..20f7481e19 --- /dev/null +++ b/sdk/python/examples/controls/charts/line_chart/dashboard_declarative.py @@ -0,0 +1,137 @@ +import asyncio +import random +from dataclasses import dataclass, field + +import flet as ft +import flet_charts as ft_charts + +MAX_POINTS = 20 + + +@dataclass +class DataPoint: + x: float + y: float + + +@dataclass +@ft.observable +class ChartData: + x: float = 0.0 + min_y: float = 0.0 + max_y: float = 1.0 + points: list[DataPoint] = field(default_factory=list) + + def __post_init__(self): + for _ in range(MAX_POINTS): + self.add_point() + + def add_point(self): + self.points.append( + DataPoint(x=self.x, y=random.uniform(self.min_y, self.max_y)) + ) + self.x += 0.5 + if len(self.points) > MAX_POINTS: + self.points.pop(0) + + +@ft.component +def Gauge( + min_y: float = 0.0, + max_y: float = 1.0, + width: int = 200, + height: int = 150, + line_color=ft.Colors.BLUE, + bgcolor=ft.Colors.BLUE_100, +): + chart_data, _ = ft.use_state(lambda: ChartData(min_y=min_y, max_y=max_y)) + + async def generate_chart_data(): + for _ in range(0, 100): + chart_data.add_point() + await asyncio.sleep(1.0) + + ft.on_mounted(generate_chart_data) + + return ft_charts.LineChart( + data_series=[ + ft_charts.LineChartData( + stroke_width=2, + color=line_color, + curved=True, + points=[ + ft_charts.LineChartDataPoint( + key=point.x, + x=point.x, + y=point.y, + selected_point=ft_charts.ChartCirclePoint(radius=4), + selected_below_line=False, + tooltip=f"{round(point.y, 2)}%", + ) + for point in chart_data.points + ], + below_line_bgcolor=bgcolor, + ) + ], + border=ft.Border.all(1, ft.Colors.GREY_400), + horizontal_grid_lines=ft_charts.ChartGridLines( + color=ft.Colors.GREY_300, width=1, dash_pattern=[3, 3], interval=0.1 + ), + tooltip=ft_charts.LineChartTooltip( + bgcolor=ft.Colors.BLACK_12, + border_radius=4, + padding=ft.Padding(5), + ), + min_y=0, + max_y=1, + width=width, + height=height, + animation=ft.Animation(duration=0), + ) + + +@ft.component +def App(): + return ft.Row( + controls=[ + ft.Column( + [ + ft.Text("CPU Usage"), + Gauge( + min_y=0.3, + max_y=1.0, + line_color=ft.Colors.BLUE, + bgcolor=ft.Colors.BLUE_100, + ), + ], + horizontal_alignment=ft.CrossAxisAlignment.CENTER, + ), + ft.Column( + [ + ft.Text("Memory Usage"), + Gauge( + min_y=0.2, + max_y=0.5, + line_color=ft.Colors.GREEN, + bgcolor=ft.Colors.GREEN_100, + ), + ], + horizontal_alignment=ft.CrossAxisAlignment.CENTER, + ), + ft.Column( + [ + ft.Text("Disk Usage"), + Gauge( + min_y=0.7, + max_y=0.9, + line_color=ft.Colors.ORANGE, + bgcolor=ft.Colors.ORANGE_100, + ), + ], + horizontal_alignment=ft.CrossAxisAlignment.CENTER, + ), + ] + ) + + +ft.run(lambda page: page.render(App)) diff --git a/sdk/python/examples/controls/charts/pie_chart/example_3.py b/sdk/python/examples/controls/charts/pie_chart/example_3.py index a0dde5dfa6..9c725da6d5 100644 --- a/sdk/python/examples/controls/charts/pie_chart/example_3.py +++ b/sdk/python/examples/controls/charts/pie_chart/example_3.py @@ -1,6 +1,5 @@ -import flet_charts as fch - import flet as ft +import flet_charts as fch NORMAL_RADIUS = 100 HOVER_RADIUS = 110 @@ -11,7 +10,7 @@ size=16, color=ft.Colors.WHITE, weight=ft.FontWeight.BOLD, - shadow=ft.BoxShadow(blur_radius=2, color=ft.Colors.BLACK54), + shadow=ft.BoxShadow(blur_radius=2, color=ft.Colors.BLACK_54), ) NORMAL_BADGE_SIZE = 40 HOVER_BADGE_SIZE = 50 diff --git a/sdk/python/examples/controls/charts/scatter_chart/example_1.py b/sdk/python/examples/controls/charts/scatter_chart/example_1.py index 2e66789b86..175af4319f 100644 --- a/sdk/python/examples/controls/charts/scatter_chart/example_1.py +++ b/sdk/python/examples/controls/charts/scatter_chart/example_1.py @@ -1,10 +1,10 @@ import random import flet as ft -import flet_charts as ftc +import flet_charts as fch -class MySpot(ftc.ScatterChartSpot): +class MySpot(fch.ScatterChartSpot): def __init__( self, x: float, @@ -123,8 +123,8 @@ def get_random_spots(): def main(page: ft.Page): page.horizontal_alignment = ft.CrossAxisAlignment.CENTER - def handle_event(e: ftc.ScatterChartEvent): - if e.type == ftc.ChartEventType.TAP_DOWN: + def handle_event(e: fch.ScatterChartEvent): + if e.type == fch.ChartEventType.TAP_DOWN: e.control.spots = ( flutter_logo_spots if (e.control.spots != flutter_logo_spots) @@ -135,17 +135,17 @@ def handle_event(e: ftc.ScatterChartEvent): ft.Text( "Tap on the chart to toggle between random spots and Flutter logo spots." ), - ftc.ScatterChart( + fch.ScatterChart( expand=True, aspect_ratio=1.0, min_x=0.0, max_x=50.0, min_y=0.0, max_y=50.0, - left_axis=ftc.ChartAxis(show_labels=False), - right_axis=ftc.ChartAxis(show_labels=False), - top_axis=ftc.ChartAxis(show_labels=False), - bottom_axis=ftc.ChartAxis(show_labels=False), + left_axis=fch.ChartAxis(show_labels=False), + right_axis=fch.ChartAxis(show_labels=False), + top_axis=fch.ChartAxis(show_labels=False), + bottom_axis=fch.ChartAxis(show_labels=False), show_tooltips_for_selected_spots_only=False, on_event=handle_event, animation=ft.Animation( diff --git a/sdk/python/packages/flet-charts/src/flet_charts/pie_chart_section.py b/sdk/python/packages/flet-charts/src/flet_charts/pie_chart_section.py index 88f84fa002..f4eb31e51e 100644 --- a/sdk/python/packages/flet-charts/src/flet_charts/pie_chart_section.py +++ b/sdk/python/packages/flet-charts/src/flet_charts/pie_chart_section.py @@ -79,6 +79,10 @@ class PieChartSection(ft.BaseControl): Defines the gradient of section. If specified, overrides the color setting. """ + def init(self): + super().init() + self._internals["skip_properties"] = ["badge"] + def before_update(self): super().before_update() if self.title_position is not None and not (0.0 <= self.title_position <= 1.0): diff --git a/sdk/python/packages/flet-charts/src/flutter/flet_charts/lib/src/utils/pie_chart.dart b/sdk/python/packages/flet-charts/src/flutter/flet_charts/lib/src/utils/pie_chart.dart index e00584528b..7900f20d41 100644 --- a/sdk/python/packages/flet-charts/src/flutter/flet_charts/lib/src/utils/pie_chart.dart +++ b/sdk/python/packages/flet-charts/src/flutter/flet_charts/lib/src/utils/pie_chart.dart @@ -51,7 +51,7 @@ PieChartSectionData parsePieChartSectionData( borderSide: section.getBorderSide("border_side", theme, defaultValue: BorderSide.none)!, titlePositionPercentageOffset: section.getDouble("title_position"), - badgeWidget: section.buildWidget("badge_content"), + badgeWidget: section.buildWidget("badge"), badgePositionPercentageOffset: section.getDouble("badge_position"), ); } diff --git a/sdk/python/packages/flet/docs/contributing.md b/sdk/python/packages/flet/docs/contributing.md new file mode 100644 index 0000000000..fc162802ad --- /dev/null +++ b/sdk/python/packages/flet/docs/contributing.md @@ -0,0 +1 @@ +--8<-- "../../../../CONTRIBUTING.md" diff --git a/sdk/python/packages/flet/docs/controls/switch.md b/sdk/python/packages/flet/docs/controls/switch.md index 08b8028b41..522ab1cda1 100644 --- a/sdk/python/packages/flet/docs/controls/switch.md +++ b/sdk/python/packages/flet/docs/controls/switch.md @@ -2,7 +2,7 @@ class_name: flet.Switch examples: ../../examples/controls/switch example_images: ../test-images/examples/material/golden/macos/switch -example_media: ../../examples/controls/switch/media +example_media: ../examples/controls/switch/media --- {{ class_summary(class_name, example_images + "/image_for_docs.png", image_caption="Basic switch and disabled switch") }} diff --git a/sdk/python/packages/flet/src/flet/components/hooks/use_effect.py b/sdk/python/packages/flet/src/flet/components/hooks/use_effect.py index f6613ac028..4ef92d35d7 100644 --- a/sdk/python/packages/flet/src/flet/components/hooks/use_effect.py +++ b/sdk/python/packages/flet/src/flet/components/hooks/use_effect.py @@ -66,7 +66,8 @@ def on_mounted(fn: Callable[[], Any | Awaitable[Any]]) -> None: Run exactly once after the component mounts. Args: - fn: A function to run after the component mounts. + fn (Callable[[], Any | Awaitable[Any]]): A function to run after the component + mounts. """ use_effect(fn, dependencies=[]) @@ -76,7 +77,8 @@ def on_unmounted(fn: Callable[[], Any | Awaitable[Any]]) -> None: Run exactly once when the component unmounts. Args: - fn: A function to run when the component unmounts. + fn (Callable[[], Any | Awaitable[Any]]): A function to run when the component + unmounts. """ # No-op setup; only need cleanup to fire on unmount use_effect(lambda: None, dependencies=[], cleanup=fn) @@ -91,10 +93,11 @@ def on_updated( on changes. Args: - fn: A function to run after each post-mount render (or when dependencies - change). - dependencies: If present, fn is only run when one of the dependencies has - changed. If absent, fn is run after every render. + fn (Callable[[], Any | Awaitable[Any]]): A function to run after each + post-mount render (or when dependencies change). + dependencies (Sequence[Any] | None): If present, `fn` is only run when one + of the dependencies has changed. If absent, `fn` is run after every + render. """ use_effect(fn, dependencies=dependencies) diff --git a/sdk/python/packages/flet/src/flet/controls/base_control.py b/sdk/python/packages/flet/src/flet/controls/base_control.py index 5e59a24aca..c87fd3a620 100644 --- a/sdk/python/packages/flet/src/flet/controls/base_control.py +++ b/sdk/python/packages/flet/src/flet/controls/base_control.py @@ -46,7 +46,7 @@ def control( *, isolated: Optional[bool] = None, post_init_args: int = 1, - **dataclass_kwargs, + **dataclass_kwargs: Any, ) -> Union[type[T], Callable[[type[T]], type[T]]]: """ Decorator to optionally set widget name and 'isolated' while behaving diff --git a/sdk/python/packages/flet/src/flet/controls/material/expansion_tile.py b/sdk/python/packages/flet/src/flet/controls/material/expansion_tile.py index 3758f72a8f..0b45a7121b 100644 --- a/sdk/python/packages/flet/src/flet/controls/material/expansion_tile.py +++ b/sdk/python/packages/flet/src/flet/controls/material/expansion_tile.py @@ -311,19 +311,19 @@ class ExpansionTile(LayoutControl, AdaptiveControl): If [`AnimationStyle.duration`][flet.] is provided, it will be used to override the expansion animation duration. If it is `None`, then [`AnimationStyle.duration`][flet.] from the - [`ExpansionTileTheme.animation_style`][(c).] will be used. If that is also + [`ExpansionTileTheme.animation_style`][flet.] will be used. If that is also `None`, `Duration(milliseconds=200)` will be used as default. If [`AnimationStyle.curve`][flet.] is provided, it will be used to override the expansion animation curve. If it is `None`, then [`AnimationStyle.curve`][flet.] from the - [`ExpansionTileTheme.animation_style`][(c).] will be used. If that is also - `None`, [`Curves.EASE_IN`][flet.] will be used as default. + [`ExpansionTileTheme.animation_style`][flet.] will be used. If that is also + `None`, [`AnimationCurve.EASE_IN`][flet.] will be used as default. If [`AnimationStyle.reverse_curve`][flet.] is provided, it will be used to override the collapse animation curve. If it is `None`, then [`AnimationStyle.reverse_curve`][flet.] from the - [`ExpansionTileTheme.animation_style`][(c).] will be used. If that is also + [`ExpansionTileTheme.animation_style`][flet.] will be used. If that is also `None`, the expansion curve will be used as default. Tip: diff --git a/sdk/python/packages/flet/src/flet/controls/page.py b/sdk/python/packages/flet/src/flet/controls/page.py index 93b045d406..2958ac5a70 100644 --- a/sdk/python/packages/flet/src/flet/controls/page.py +++ b/sdk/python/packages/flet/src/flet/controls/page.py @@ -603,12 +603,13 @@ async def push_route(self, route: str, **kwargs: Any) -> None: Example: ```python - import flet as ft import asyncio + import flet as ft + def main(page: ft.Page): - page.title = "Push Route Example" + page.title = "Routes Example" def route_change(e): page.views.clear() @@ -617,9 +618,9 @@ def route_change(e): route="/", controls=[ ft.AppBar(title=ft.Text("Flet app")), - ft.ElevatedButton( + ft.Button( "Visit Store", - on_click=lambda _: asyncio.create_task( + on_click=lambda: asyncio.create_task( page.push_route("/store") ), ), @@ -630,26 +631,29 @@ def route_change(e): page.views.append( ft.View( route="/store", - can_pop=True, controls=[ ft.AppBar(title=ft.Text("Store")), - ft.ElevatedButton( + ft.Button( "Go Home", - on_click=lambda _: asyncio.create_task( + on_click=lambda: asyncio.create_task( page.push_route("/") ), ), ], ) ) + page.update() async def view_pop(e): - page.views.pop() - top_view = page.views[-1] - await page.push_route(top_view.route) + if e.view is not None: + page.views.remove(e.view) + top_view = page.views[-1] + await page.push_route(top_view.route) + + page.on_route_change = route_change + page.on_view_pop = view_pop - page.on_route_change = route_change - page.on_view_pop = view_pop + route_change() ft.run(main) diff --git a/sdk/python/packages/flet/src/flet/controls/scrollable_control.py b/sdk/python/packages/flet/src/flet/controls/scrollable_control.py index f216907eb2..56366074a4 100644 --- a/sdk/python/packages/flet/src/flet/controls/scrollable_control.py +++ b/sdk/python/packages/flet/src/flet/controls/scrollable_control.py @@ -93,7 +93,7 @@ async def scroll_to( - Exactly one of `offset`, `delta` or `scroll_key` should be provided. - [`auto_scroll`][(c).] must be `False`. - This method is ineffective for controls (e.g. - [`ListView`][(c).], [`GridView`][(c).]) that build items dynamically. + [`ListView`][flet.], [`GridView`][flet.]) that build items dynamically. Examples: ```python diff --git a/sdk/python/packages/flet/src/flet/controls/theme.py b/sdk/python/packages/flet/src/flet/controls/theme.py index fd61fd118b..2f91b59f4b 100644 --- a/sdk/python/packages/flet/src/flet/controls/theme.py +++ b/sdk/python/packages/flet/src/flet/controls/theme.py @@ -3365,6 +3365,14 @@ class Theme: [`DataTable`][flet.]. """ + divider_color: Optional[ColorValue] = None + """ + Overrides the default color of dividers used in + [`Divider`][flet.], [`VerticalDivider`][flet.], dividers between + [`ListTile`][flet.]s, and dividers between rows in + [`DataTable`][flet.]. + """ + dropdown_theme: Optional[DropdownTheme] = None """ Customizes the appearance of [`Dropdown`][flet.] across the app.