diff --git a/.appveyor.yml b/.appveyor.yml index 518603e0b..6ba278965 100644 --- a/.appveyor.yml +++ b/.appveyor.yml @@ -63,31 +63,32 @@ environment: - job_name: Test Python 3.7 job_group: python_tests - job_depends_on: build_flet python_stack: python 3.7 APPVEYOR_BUILD_WORKER_IMAGE: Ubuntu - job_name: Test Python 3.8 job_group: python_tests - job_depends_on: build_flet python_stack: python 3.8 APPVEYOR_BUILD_WORKER_IMAGE: Ubuntu - job_name: Test Python 3.9 job_group: python_tests - job_depends_on: build_flet python_stack: python 3.9 APPVEYOR_BUILD_WORKER_IMAGE: Ubuntu - job_name: Test Python 3.10 job_group: python_tests - job_depends_on: build_flet python_stack: python 3.10 APPVEYOR_BUILD_WORKER_IMAGE: Ubuntu + - job_name: Test Python 3.11 + job_group: python_tests + python_stack: python 3.11 + APPVEYOR_BUILD_WORKER_IMAGE: Ubuntu + - job_name: Build Python wheels job_group: python_build - job_depends_on: python_tests + job_depends_on: python_tests, build_flet APPVEYOR_BUILD_WORKER_IMAGE: Ubuntu TWINE_USERNAME: __token__ TWINE_PASSWORD: @@ -109,15 +110,15 @@ for: - job_name: Build Flet package for Flutter install: - - ps: | - if ($env:APPVEYOR_REPO_TAG_NAME) { - $v = $env:APPVEYOR_REPO_TAG_NAME.replace("v", "") - } else { - $cv = [version](git describe --abbrev=0).substring(1) - $v = "$($cv.major).$($cv.minor+1).0+$($env:APPVEYOR_BUILD_NUMBER)" - } - Update-AppveyorBuild -Version $v - - flutter upgrade + - ps: | + if ($env:APPVEYOR_REPO_TAG_NAME) { + $v = $env:APPVEYOR_REPO_TAG_NAME.replace("v", "") + } else { + $cv = [version](git describe --abbrev=0).substring(1) + $v = "$($cv.major).$($cv.minor+1).0+$($env:APPVEYOR_BUILD_NUMBER)" + } + Update-AppveyorBuild -Version $v + - flutter upgrade build_script: - cd package diff --git a/sdk/python/.gitignore b/sdk/python/.gitignore index 75bedb70d..54acaca41 100644 --- a/sdk/python/.gitignore +++ b/sdk/python/.gitignore @@ -1,4 +1,3 @@ -@@ -0,0 +1,125 @@ # Byte-compiled / optimized / DLL files __pycache__/ *.py[cod] diff --git a/sdk/python/flet/__init__.py b/sdk/python/flet/__init__.py index a345ab390..e56608259 100644 --- a/sdk/python/flet/__init__.py +++ b/sdk/python/flet/__init__.py @@ -13,8 +13,8 @@ ) from flet.alert_dialog import AlertDialog from flet.alignment import Alignment -from flet.animated_switcher import AnimatedSwitcher -from flet.animation import Animation +from flet.animated_switcher import AnimatedSwitcher, AnimatedSwitcherTransition +from flet.animation import Animation, AnimationCurve from flet.app_bar import AppBar from flet.audio import Audio from flet.banner import Banner @@ -42,6 +42,7 @@ from flet.elevated_button import ElevatedButton from flet.file_picker import ( FilePicker, + FilePickerFileType, FilePickerResultEvent, FilePickerUploadEvent, FilePickerUploadFile, @@ -51,6 +52,7 @@ from flet.flet import * from flet.flet_app import FletApp from flet.floating_action_button import FloatingActionButton +from flet.form_field_control import InputBorder from flet.gesture_detector import ( DragEndEvent, DragStartEvent, @@ -67,7 +69,12 @@ ScrollEvent, TapEvent, ) -from flet.gradients import LinearGradient, RadialGradient, SweepGradient +from flet.gradients import ( + GradientTileMode, + LinearGradient, + RadialGradient, + SweepGradient, +) from flet.grid_view import GridView from flet.haptic_feedback import HapticFeedback from flet.icon import Icon @@ -76,9 +83,17 @@ from flet.list_tile import ListTile from flet.list_view import ListView from flet.margin import Margin -from flet.markdown import Markdown -from flet.navigation_bar import NavigationBar, NavigationDestination -from flet.navigation_rail import NavigationRail, NavigationRailDestination +from flet.markdown import Markdown, MarkdownExtensionSet +from flet.navigation_bar import ( + NavigationBar, + NavigationBarLabelBehavior, + NavigationDestination, +) +from flet.navigation_rail import ( + NavigationRail, + NavigationRailDestination, + NavigationRailLabelType, +) from flet.outlined_button import OutlinedButton from flet.padding import Padding from flet.page import KeyboardEvent, LoginEvent, Page, RouteChangeEvent, ViewPopEvent @@ -101,14 +116,34 @@ from flet.switch import Switch from flet.tabs import Tab, Tabs from flet.template_route import TemplateRoute -from flet.text import Text +from flet.text import Text, TextOverflow, TextThemeStyle from flet.text_button import TextButton from flet.text_style import TextStyle -from flet.textfield import TextField -from flet.theme import PageTransitionsTheme, Theme +from flet.textfield import KeyboardType, TextCapitalization, TextField +from flet.theme import ( + PageTransitionsTheme, + PageTransitionTheme, + Theme, + ThemeVisualDensity, +) from flet.tooltip import Tooltip from flet.transparent_pointer import TransparentPointer -from flet.types import BoxShape +from flet.types import ( + BlendMode, + BoxShape, + ClipBehavior, + CrossAxisAlignment, + FontWeight, + ImageFit, + ImageRepeat, + LabelPosition, + MainAxisAlignment, + MaterialState, + PageDesignLanguage, + ScrollMode, + TextAlign, + ThemeMode, +) from flet.user_control import UserControl from flet.vertical_divider import VerticalDivider from flet.view import View diff --git a/sdk/python/flet/alert_dialog.py b/sdk/python/flet/alert_dialog.py index 806586777..953177ab2 100644 --- a/sdk/python/flet/alert_dialog.py +++ b/sdk/python/flet/alert_dialog.py @@ -1,11 +1,12 @@ -from typing import Any, List, Optional +from typing import Any, Optional from beartype import beartype +from beartype.typing import List from flet.buttons import OutlinedBorder -from flet.control import Control, MainAxisAlignment +from flet.control import Control from flet.ref import Ref -from flet.types import PaddingValue +from flet.types import MainAxisAlignment, MainAxisAlignmentString, PaddingValue class AlertDialog(Control): @@ -26,7 +27,7 @@ def __init__( content_padding: PaddingValue = None, actions: Optional[List[Control]] = None, actions_padding: PaddingValue = None, - actions_alignment: MainAxisAlignment = None, + actions_alignment: MainAxisAlignment = MainAxisAlignment.NONE, shape: Optional[OutlinedBorder] = None, on_dismiss=None, ): @@ -158,11 +159,18 @@ def actions_padding(self, value: PaddingValue): # actions_alignment @property def actions_alignment(self) -> MainAxisAlignment: - return self._get_attr("actionsAlignment") + return self.__actions_alignment @actions_alignment.setter - @beartype def actions_alignment(self, value: MainAxisAlignment): + self.__actions_alignment = value + if isinstance(value, MainAxisAlignment): + self._set_attr("actionsAlignment", value.value) + else: + self.__set_actions_alignment(value) + + @beartype + def __set_actions_alignment(self, value: MainAxisAlignmentString): self._set_attr("actionsAlignment", value) # shape diff --git a/sdk/python/flet/animated_switcher.py b/sdk/python/flet/animated_switcher.py index fe244dcc7..8a4a4d9b1 100644 --- a/sdk/python/flet/animated_switcher.py +++ b/sdk/python/flet/animated_switcher.py @@ -2,7 +2,9 @@ from beartype import beartype -from flet.animation import Curve, TransitionValue +from enum import Enum + +from flet.animation import AnimationCurveString, AnimationCurve from flet.constrained_control import ConstrainedControl from flet.control import Control, OptionalNumber from flet.ref import Ref @@ -14,6 +16,19 @@ ScaleValue, ) +try: + from typing import Literal +except ImportError: + from typing_extensions import Literal + +TransitionValueString = Literal["fade", "rotation", "scale"] + + +class AnimatedSwitcherTransition(Enum): + FADE = "fade" + ROTATION = "rotation" + SCALE = "scale" + class AnimatedSwitcher(ConstrainedControl): def __init__( @@ -49,9 +64,9 @@ def __init__( # duration: Optional[int] = None, reverse_duration: Optional[int] = None, - switch_in_curve: Optional[Curve] = None, - switch_out_curve: Optional[Curve] = None, - transition: Optional[TransitionValue] = None, + switch_in_curve: Optional[AnimationCurve] = None, + switch_out_curve: Optional[AnimationCurve] = None, + transition: Optional[AnimatedSwitcherTransition] = None, ): ConstrainedControl.__init__( self, @@ -134,30 +149,51 @@ def reverse_duration(self, value: Optional[int]): # switch_in_curve @property - def switch_in_curve(self) -> Optional[Curve]: - return self._get_attr("switchInCurve") + def switch_in_curve(self) -> Optional[AnimationCurve]: + return self.__switch_in_curve @switch_in_curve.setter + def switch_in_curve(self, value: Optional[AnimationCurve]): + self.__switch_in_curve = value + if isinstance(value, AnimationCurve): + self._set_attr("switchInCurve", value.value) + else: + self.__set_switch_in_curve(value) + @beartype - def switch_in_curve(self, value: Optional[Curve]): + def __set_switch_in_curve(self, value: Optional[AnimationCurveString]): self._set_attr("switchInCurve", value) # switch_out_curve @property - def switch_out_curve(self) -> Optional[Curve]: - return self._get_attr("switchOutCurve") + def switch_out_curve(self) -> Optional[AnimationCurve]: + return self.__switch_out_curve @switch_out_curve.setter + def switch_out_curve(self, value: Optional[AnimationCurve]): + self.__switch_out_curve = value + if isinstance(value, AnimationCurve): + self._set_attr("switchOutCurve", value.value) + else: + self.__set_switch_out_curve(value) + @beartype - def switch_out_curve(self, value: Optional[Curve]): + def __set_switch_out_curve(self, value: Optional[AnimationCurveString]): self._set_attr("switchOutCurve", value) # transition @property - def transition(self) -> Optional[TransitionValue]: - return self._get_attr("transition") + def transition(self) -> Optional[AnimatedSwitcherTransition]: + return self.__transition @transition.setter + def transition(self, value: Optional[AnimatedSwitcherTransition]): + self.__transition = value + if isinstance(value, AnimatedSwitcherTransition): + self._set_attr("transition", value.value) + else: + self.__set_transition(value) + @beartype - def transition(self, value: Optional[TransitionValue]): + def __set_transition(self, value: Optional[TransitionValueString]): self._set_attr("transition", value) diff --git a/sdk/python/flet/animation.py b/sdk/python/flet/animation.py index b0982784a..c7cb4ac7b 100644 --- a/sdk/python/flet/animation.py +++ b/sdk/python/flet/animation.py @@ -1,13 +1,14 @@ import dataclasses from dataclasses import field from typing import Optional +from enum import Enum try: from typing import Literal except ImportError: from typing_extensions import Literal -Curve = Literal[ +AnimationCurveString = Literal[ "bounceIn", "bounceInOut", "bounceOut", @@ -52,14 +53,57 @@ "slowMiddle", ] -TransitionValue = Literal["fade", "rotation", "scale"] + +class AnimationCurve(Enum): + BOUNCE_IN = "bounceIn" + BOUNCE_IN_OUT = "bounceInOut" + BOUNCE_OUT = "bounceOut" + DECELERATE = "decelerate" + EASE = "ease" + EASE_IN = "easeIn" + EASE_IN_BACK = "easeInBack" + EASE_IN_CIRC = "easeInCirc" + EASE_IN_CUBIC = "easeInCubic" + EASE_IN_EXPO = "easeInExpo" + EASE_IN_OUT = "easeInOut" + EASE_IN_OUT_BACK = "easeInOutBack" + EASE_IN_OUT_CIRC = "easeInOutCirc" + EASE_IN_OUT_CUBIC = "easeInOutCubic" + EASE_IN_OUT_CUBIC_EMPHASIZED = "easeInOutCubicEmphasized" + EASE_IN_OUT_EXPO = "easeInOutExpo" + EASE_IN_OUT_QUAD = "easeInOutQuad" + EASE_IN_OUT_QUART = "easeInOutQuart" + EASE_IN_OUT_QUINT = "easeInOutQuint" + EASE_IN_OUT_SINE = "easeInOutSine" + EASE_IN_QUAD = "easeInQuad" + EASE_IN_QUART = "easeInQuart" + EASE_IN_QUINT = "easeInQuint" + EASE_IN_SINE = "easeInSine" + EASE_IN_TO_LINEAR = "easeInToLinear" + EASE_OUT = "easeOut" + EASE_OUT_BACK = "easeOutBack" + EASE_OUT_CIRC = "easeOutCirc" + EASE_OUT_CUBIC = "easeOutCubic" + EASE_OUT_EXPO = "easeOutExpo" + EASE_OUT_QUAD = "easeOutQuad" + EASE_OUT_QUART = "easeOutQuart" + EASE_OUT_QUINT = "easeOutQuint" + EASE_OUT_SINE = "easeOutSine" + ELASTIC_IN = "elasticIn" + ELASTIC_IN_OUT = "elasticInOut" + ELASTIC_OUT = "elasticOut" + FAST_LINEAR_TO_SLOW_EASE_IN = "fastLinearToSlowEaseIn" + FAST_OUT_SLOWIN = "fastOutSlowIn" + LINEAR = "linear" + LINEAR_TO_EASE_OUT = "linearToEaseOut" + SLOW_MIDDLE = "slowMiddle" @dataclasses.dataclass class Animation: duration: int = field(default=1) - curve: Optional[Curve] = field(default=None) + curve: Optional[AnimationCurve] = field(default=None) -def implicit(duration: int, curve: Optional[Curve] = None): +def implicit(duration: int, curve: Optional[AnimationCurve] = None): return Animation(duration=duration, curve=curve) diff --git a/sdk/python/flet/banner.py b/sdk/python/flet/banner.py index c12e7c90b..32fe90f43 100644 --- a/sdk/python/flet/banner.py +++ b/sdk/python/flet/banner.py @@ -1,6 +1,7 @@ -from typing import Any, List, Optional +from typing import Any, Optional from beartype import beartype +from beartype.typing import List from flet.control import Control from flet.ref import Ref diff --git a/sdk/python/flet/bottom_sheet.py b/sdk/python/flet/bottom_sheet.py index 60a47d41c..c211c0dac 100644 --- a/sdk/python/flet/bottom_sheet.py +++ b/sdk/python/flet/bottom_sheet.py @@ -1,6 +1,7 @@ -from typing import Any, List, Optional +from typing import Any, Optional from beartype import beartype +from beartype.typing import List from flet.control import Control from flet.ref import Ref diff --git a/sdk/python/flet/checkbox.py b/sdk/python/flet/checkbox.py index 7ea9e4679..9d8bd2c3e 100644 --- a/sdk/python/flet/checkbox.py +++ b/sdk/python/flet/checkbox.py @@ -8,6 +8,8 @@ from flet.ref import Ref from flet.types import ( AnimationValue, + LabelPosition, + LabelPositionString, MaterialState, OffsetValue, ResponsiveNumber, @@ -21,9 +23,6 @@ from typing_extensions import Literal -LabelPosition = Literal[None, "right", "left"] - - class Checkbox(ConstrainedControl): def __init__( self, @@ -56,7 +55,7 @@ def __init__( # Specific # label: Optional[str] = None, - label_position: LabelPosition = None, + label_position: LabelPosition = LabelPosition.NONE, value: Optional[bool] = None, tristate: Optional[bool] = None, autofocus: Optional[bool] = None, @@ -146,11 +145,18 @@ def label(self, value): # label_position @property def label_position(self) -> LabelPosition: - return self._get_attr("labelPosition") + return self.__label_position @label_position.setter - @beartype def label_position(self, value: LabelPosition): + self.__label_position = value + if isinstance(value, LabelPosition): + self._set_attr("labelPosition", value.value) + else: + self.__set_label_position(value) + + @beartype + def __set_label_position(self, value: LabelPositionString): self._set_attr("labelPosition", value) # autofocus diff --git a/sdk/python/flet/column.py b/sdk/python/flet/column.py index ae9229c17..32a607392 100644 --- a/sdk/python/flet/column.py +++ b/sdk/python/flet/column.py @@ -1,22 +1,23 @@ -from typing import Any, List, Optional, Union +from typing import Any, Optional, Union from beartype import beartype +from beartype.typing import List from flet.constrained_control import ConstrainedControl -from flet.control import ( - Control, - CrossAxisAlignment, - MainAxisAlignment, - OptionalNumber, - ScrollMode, -) +from flet.control import Control, OptionalNumber from flet.ref import Ref from flet.types import ( AnimationValue, + CrossAxisAlignment, + CrossAxisAlignmentString, + MainAxisAlignment, + MainAxisAlignmentString, OffsetValue, ResponsiveNumber, RotateValue, ScaleValue, + ScrollMode, + ScrollModeString, ) @@ -51,13 +52,13 @@ def __init__( # # Column specific # - alignment: MainAxisAlignment = None, - horizontal_alignment: CrossAxisAlignment = None, + alignment: MainAxisAlignment = MainAxisAlignment.NONE, + horizontal_alignment: CrossAxisAlignment = CrossAxisAlignment.NONE, spacing: OptionalNumber = None, tight: Optional[bool] = None, wrap: Optional[bool] = None, run_spacing: OptionalNumber = None, - scroll: ScrollMode = None, + scroll: Optional[ScrollMode] = None, auto_scroll: Optional[bool] = None, ): ConstrainedControl.__init__( @@ -88,7 +89,6 @@ def __init__( data=data, ) - self.__controls = [] self.controls = controls self.horizontal_alignment = horizontal_alignment self.alignment = alignment @@ -96,7 +96,6 @@ def __init__( self.tight = tight self.wrap = wrap self.run_spacing = run_spacing - self.__scroll = False self.scroll = scroll self.auto_scroll = auto_scroll @@ -123,21 +122,35 @@ def tight(self, value: Optional[bool]): # alignment @property def alignment(self) -> MainAxisAlignment: - return self._get_attr("alignment") + return self.__alignment @alignment.setter - @beartype def alignment(self, value: MainAxisAlignment): + self.__alignment = value + if isinstance(value, MainAxisAlignment): + self._set_attr("alignment", value.value) + else: + self.__set_alignment(value) + + @beartype + def __set_alignment(self, value: MainAxisAlignmentString): self._set_attr("alignment", value) # horizontal_alignment @property def horizontal_alignment(self) -> CrossAxisAlignment: - return self._get_attr("horizontalAlignment") + return self.__horizontal_alignment @horizontal_alignment.setter - @beartype def horizontal_alignment(self, value: CrossAxisAlignment): + self.__horizontal_alignment = value + if isinstance(value, CrossAxisAlignment): + self._set_attr("horizontalAlignment", value.value) + else: + self.__set_horizontal_alignment(value) + + @beartype + def __set_horizontal_alignment(self, value: CrossAxisAlignmentString): self._set_attr("horizontalAlignment", value) # spacing @@ -172,17 +185,23 @@ def run_spacing(self, value: OptionalNumber): # scroll @property - def scroll(self): + def scroll(self) -> Optional[ScrollMode]: return self.__scroll @scroll.setter - @beartype - def scroll(self, value: ScrollMode): + def scroll(self, value: Optional[ScrollMode]): self.__scroll = value - if value is True: + if isinstance(value, ScrollMode): + self._set_attr("scroll", value.value) + else: + self.__set_scroll(value) + + @beartype + def __set_scroll(self, value: Optional[ScrollModeString]): + if value == True: value = "auto" - elif value is False: - value = "none" + elif value == False: + value = None self._set_attr("scroll", value) # auto_scroll @@ -201,5 +220,6 @@ def controls(self): return self.__controls @controls.setter - def controls(self, value): + @beartype + def controls(self, value: Optional[List[Control]]): self.__controls = value if value is not None else [] diff --git a/sdk/python/flet/container.py b/sdk/python/flet/container.py index 5c0e4fa11..238ed7639 100644 --- a/sdk/python/flet/container.py +++ b/sdk/python/flet/container.py @@ -6,16 +6,23 @@ from flet.alignment import Alignment from flet.border import Border from flet.constrained_control import ConstrainedControl -from flet.control import BlendMode, ClipBehavior, Control, OptionalNumber +from flet.control import Control, OptionalNumber from flet.control_event import ControlEvent from flet.event_handler import EventHandler from flet.gradients import Gradient -from flet.image import ImageFit, ImageRepeat from flet.ref import Ref from flet.types import ( AnimationValue, + BlendMode, + BlendModeString, BorderRadiusValue, BoxShape, + ClipBehavior, + ClipBehaviorString, + ImageFit, + ImageFitString, + ImageRepeat, + ImageRepeatString, MarginValue, OffsetValue, PaddingValue, @@ -77,16 +84,16 @@ def __init__( alignment: Optional[Alignment] = None, bgcolor: Optional[str] = None, gradient: Optional[Gradient] = None, - blend_mode: Optional[BlendMode] = None, + blend_mode: BlendMode = BlendMode.NONE, border: Optional[Border] = None, border_radius: BorderRadiusValue = None, image_src: Optional[str] = None, image_src_base64: Optional[str] = None, - image_repeat: ImageRepeat = None, - image_fit: ImageFit = None, + image_repeat: Optional[ImageRepeat] = None, + image_fit: Optional[ImageFit] = None, image_opacity: OptionalNumber = None, shape: Optional[BoxShape] = None, - clip_behavior: ClipBehavior = None, + clip_behavior: Optional[ClipBehavior] = None, ink: Optional[bool] = None, animate: AnimationValue = None, on_click=None, @@ -227,12 +234,19 @@ def gradient(self, value: Optional[Gradient]): # blend_mode @property - def blend_mode(self) -> Optional[BlendMode]: - return self._get_attr("blendMode") + def blend_mode(self) -> BlendMode: + return self.__blend_mode @blend_mode.setter + def blend_mode(self, value: BlendMode): + self.__blend_mode = value + if isinstance(value, BlendMode): + self._set_attr("blendMode", value.value) + else: + self.__set_blend_mode(value) + @beartype - def blend_mode(self, value: Optional[BlendMode]): + def __set_blend_mode(self, value: BlendModeString): self._set_attr("blendMode", value) # border @@ -275,22 +289,36 @@ def image_src_base64(self, value): # image_fit @property - def image_fit(self): - return self._get_attr("imageFit") + def image_fit(self) -> Optional[ImageFit]: + return self.__image_fit @image_fit.setter + def image_fit(self, value: Optional[ImageFit]): + self.__image_fit = value + if isinstance(value, ImageFit): + self._set_attr("imageFit", value.value) + else: + self.__set_image_fit(value) + @beartype - def image_fit(self, value: ImageFit): + def __set_image_fit(self, value: ImageFitString): self._set_attr("imageFit", value) # image_repeat @property - def image_repeat(self): - return self._get_attr("imageRepeat") + def image_repeat(self) -> Optional[ImageRepeat]: + return self.__image_repeat @image_repeat.setter + def image_repeat(self, value: Optional[ImageRepeat]): + self.__image_repeat = value + if isinstance(value, ImageRepeat): + self._set_attr("imageRepeat", value.value) + else: + self.__set_image_repeat(value) + @beartype - def image_repeat(self, value: ImageRepeat): + def __set_image_repeat(self, value: ImageRepeatString): self._set_attr("imageRepeat", value) # image_opacity @@ -326,11 +354,18 @@ def shape(self, value: Optional[BoxShape]): # clip_behavior @property def clip_behavior(self) -> Optional[ClipBehavior]: - return self._get_attr("clipBehavior") + return self.__clip_behavior @clip_behavior.setter - @beartype def clip_behavior(self, value: Optional[ClipBehavior]): + self.__clip_behavior = value + if isinstance(value, ClipBehavior): + self._set_attr("clipBehavior", value.value) + else: + self.__set_clip_behavior(value) + + @beartype + def __set_clip_behavior(self, value: Optional[ClipBehaviorString]): self._set_attr("clipBehavior", value) # ink diff --git a/sdk/python/flet/control.py b/sdk/python/flet/control.py index f45758137..27e221222 100644 --- a/sdk/python/flet/control.py +++ b/sdk/python/flet/control.py @@ -21,74 +21,8 @@ if TYPE_CHECKING: from .page import Page -MainAxisAlignment = Literal[ - None, - "start", - "end", - "center", - "spaceBetween", - "spaceAround", - "spaceEvenly", -] - -CrossAxisAlignment = Literal[ - None, - "start", - "end", - "center", - "stretch", - "baseline", -] - -BorderStyle = Literal[ - None, - "none", - "solid", -] - -TextAlign = Literal[None, "left", "right", "center", "justify", "start", "end"] - -InputBorder = Literal[None, "outline", "underline", "none"] - OptionalNumber = Union[None, int, float] -ScrollMode = Literal[None, True, False, "none", "auto", "adaptive", "always", "hidden"] - -BlendMode = Literal[ - "clear", - "color", - "colorBurn", - "colorDodge", - "darken", - "difference", - "dst", - "dstATop", - "dstIn", - "dstOut", - "dstOver", - "exclusion", - "hardLight", - "hue", - "lighten", - "luminosity", - "modulate", - "multiply", - "overlay", - "plus", - "saturation", - "screen", - "softLight", - "src", - "srcATop", - "srcIn", - "srcOut", - "srcOver", - "values", - "xor", -] - -ClipBehavior = Literal[None, "none", "antiAlias", "antiAliasWithSaveLayer", "hardEdge"] - class Control: def __init__( diff --git a/sdk/python/flet/dropdown.py b/sdk/python/flet/dropdown.py index cd65cc714..4d64216fe 100644 --- a/sdk/python/flet/dropdown.py +++ b/sdk/python/flet/dropdown.py @@ -2,9 +2,9 @@ from beartype import beartype -from flet.control import Control, InputBorder, OptionalNumber +from flet.control import Control, OptionalNumber from flet.focus import FocusData -from flet.form_field_control import FormFieldControl +from flet.form_field_control import FormFieldControl, InputBorder from flet.ref import Ref from flet.text_style import TextStyle from flet.types import ( @@ -50,7 +50,7 @@ def __init__( label: Optional[str] = None, label_style: Optional[TextStyle] = None, icon: Optional[str] = None, - border: InputBorder = None, + border: Optional[InputBorder] = None, color: Optional[str] = None, bgcolor: Optional[str] = None, border_radius: BorderRadiusValue = None, @@ -180,11 +180,12 @@ def options(self, value): # value @property - def value(self): + def value(self) -> Optional[str]: return self._get_attr("value") @value.setter - def value(self, value): + @beartype + def value(self, value: Optional[str]): self._set_attr("value", value) # autofocus diff --git a/sdk/python/flet/embed_json_encoder.py b/sdk/python/flet/embed_json_encoder.py index 3d2cfbfdc..4045b656e 100644 --- a/sdk/python/flet/embed_json_encoder.py +++ b/sdk/python/flet/embed_json_encoder.py @@ -1,3 +1,4 @@ +import enum import json from typing import Dict @@ -45,5 +46,18 @@ def default(self, obj): return self._cleanup_dict(obj.__dict__) return json.JSONEncoder.default(self, obj) + def encode(self, o): + if isinstance(o, Dict): + o = self._cleanup_dict(o) + return super().encode(o) + def _cleanup_dict(self, d): - return dict(filter(lambda item: item[1] is not None, d.items())) + return dict( + map( + lambda item: ( + item[0] if not isinstance(item[0], enum.Enum) else item[0].value, + item[1] if not isinstance(item[1], enum.Enum) else item[1].value, + ), + filter(lambda item: item[1] is not None, d.items()), + ) + ) diff --git a/sdk/python/flet/file_picker.py b/sdk/python/flet/file_picker.py index 51c906794..076498646 100644 --- a/sdk/python/flet/file_picker.py +++ b/sdk/python/flet/file_picker.py @@ -11,15 +11,26 @@ from flet.event_handler import EventHandler from flet.ref import Ref +from enum import Enum + try: from typing import Literal except ImportError: from typing_extensions import Literal -FileType = Literal["any", "media", "image", "video", "audio", "custom"] +FileTypeString = Literal["any", "media", "image", "video", "audio", "custom"] FilePickerState = Literal["pickFiles", "saveFile", "getDirectoryPath"] +class FilePickerFileType(Enum): + ANY = "any" + MEDIA = "media" + IMAGE = "image" + VIDEO = "video" + AUDIO = "audio" + CUSTOM = "custom" + + @dataclass class FilePickerUploadFile: name: str @@ -106,7 +117,7 @@ def pick_files( self, dialog_title: Optional[str] = None, initial_directory: Optional[str] = None, - file_type: Optional[FileType] = "any", + file_type: FilePickerFileType = FilePickerFileType.ANY, allowed_extensions: Optional[List[str]] = None, allow_multiple: Optional[bool] = False, ): @@ -123,7 +134,7 @@ def save_file( dialog_title: Optional[str] = None, file_name: Optional[str] = None, initial_directory: Optional[str] = None, - file_type: Optional[FileType] = "any", + file_type: FilePickerFileType = FilePickerFileType.ANY, allowed_extensions: Optional[List[str]] = None, ): self.state = "saveFile" @@ -194,12 +205,19 @@ def initial_directory(self, value: Optional[str]): # file_type @property - def file_type(self): - return self._get_attr("fileType") + def file_type(self) -> FilePickerFileType: + return self.__file_type @file_type.setter + def file_type(self, value: FilePickerFileType): + self.__file_type = value + if isinstance(value, FilePickerFileType): + self._set_attr("fileType", value.value) + else: + self.__set_file_type(value) + @beartype - def file_type(self, value: Optional[FileType]): + def __set_file_type(self, value: FileTypeString): self._set_attr("fileType", value) # allowed_extensions diff --git a/sdk/python/flet/flet_app.py b/sdk/python/flet/flet_app.py index ce7075d99..29da0cbc6 100644 --- a/sdk/python/flet/flet_app.py +++ b/sdk/python/flet/flet_app.py @@ -3,15 +3,9 @@ from beartype import beartype from flet.constrained_control import ConstrainedControl -from flet.control import BlendMode, OptionalNumber +from flet.control import OptionalNumber from flet.ref import Ref -from flet.types import ( - AnimationValue, - BorderRadiusValue, - OffsetValue, - RotateValue, - ScaleValue, -) +from flet.types import AnimationValue, OffsetValue, RotateValue, ScaleValue try: from typing import Literal diff --git a/sdk/python/flet/form_field_control.py b/sdk/python/flet/form_field_control.py index a18cd97e5..bb300d2e1 100644 --- a/sdk/python/flet/form_field_control.py +++ b/sdk/python/flet/form_field_control.py @@ -1,9 +1,10 @@ +from enum import Enum from typing import Any, Optional, Union from beartype import beartype from flet.constrained_control import ConstrainedControl -from flet.control import Control, InputBorder, OptionalNumber +from flet.control import Control, OptionalNumber from flet.ref import Ref from flet.text_style import TextStyle from flet.types import ( @@ -16,6 +17,19 @@ ScaleValue, ) +try: + from typing import Literal +except ImportError: + from typing_extensions import Literal + +InputBorderString = Literal[None, "outline", "underline", "none"] + + +class InputBorder(Enum): + NONE = "none" + OUTLINE = "outline" + UNDERLINE = "underline" + class FormFieldControl(ConstrainedControl): def __init__( @@ -53,7 +67,7 @@ def __init__( label: Optional[str] = None, label_style: Optional[TextStyle] = None, icon: Optional[str] = None, - border: InputBorder = None, + border: Optional[InputBorder] = None, color: Optional[str] = None, bgcolor: Optional[str] = None, border_radius: BorderRadiusValue = None, @@ -218,12 +232,19 @@ def icon(self, value): # border @property - def border(self) -> InputBorder: - return self._get_attr("border") + def border(self) -> Optional[InputBorder]: + return self.__border @border.setter + def border(self, value: Optional[InputBorder]): + self.__border = value + if isinstance(value, InputBorder): + self._set_attr("border", value.value) + else: + self.__set_border(value) + @beartype - def border(self, value: InputBorder): + def __set_border(self, value: Optional[InputBorderString]): self._set_attr("border", value) # color diff --git a/sdk/python/flet/gradients.py b/sdk/python/flet/gradients.py index 295f89272..317dd4823 100644 --- a/sdk/python/flet/gradients.py +++ b/sdk/python/flet/gradients.py @@ -1,6 +1,7 @@ import dataclasses import math from dataclasses import field +from enum import Enum from typing import List, Optional, Union from flet import alignment @@ -11,13 +12,18 @@ except ImportError: from typing_extensions import Literal -TileMode = Literal["clamp", "decal", "mirror", "repeated"] + +class GradientTileMode(Enum): + CLAMP = "clamp" + DECAL = "decal" + MIRROR = "mirror" + REPEATED = "repeated" @dataclasses.dataclass class Gradient: colors: List[str] - tile_mode: TileMode = field(default="clamp") + tile_mode: GradientTileMode = field(default=GradientTileMode.CLAMP) rotation: Union[None, float, int] = field(default=None) stops: Optional[List[float]] = field(default=None) diff --git a/sdk/python/flet/grid_view.py b/sdk/python/flet/grid_view.py index e5a7b4619..917dedc3e 100644 --- a/sdk/python/flet/grid_view.py +++ b/sdk/python/flet/grid_view.py @@ -1,6 +1,7 @@ -from typing import Any, List, Optional, Union +from typing import Any, Optional, Union from beartype import beartype +from beartype.typing import List from flet.constrained_control import ConstrainedControl from flet.control import Control, OptionalNumber diff --git a/sdk/python/flet/image.py b/sdk/python/flet/image.py index c2d985128..af5783094 100644 --- a/sdk/python/flet/image.py +++ b/sdk/python/flet/image.py @@ -3,11 +3,17 @@ from beartype import beartype from flet.constrained_control import ConstrainedControl -from flet.control import BlendMode, OptionalNumber +from flet.control import OptionalNumber from flet.ref import Ref from flet.types import ( AnimationValue, + BlendMode, + BlendModeString, BorderRadiusValue, + ImageFit, + ImageFitString, + ImageRepeat, + ImageRepeatString, OffsetValue, ResponsiveNumber, RotateValue, @@ -20,13 +26,6 @@ from typing_extensions import Literal -ImageFit = Literal[ - None, "none", "contain", "cover", "fill", "fitHeight", "fitWidth", "scaleDown" -] - -ImageRepeat = Literal[None, "noRepeat", "repeat", "repeatX", "repeatY"] - - class Image(ConstrainedControl): def __init__( self, @@ -60,11 +59,11 @@ def __init__( # Specific # src_base64: Optional[str] = None, - repeat: ImageRepeat = None, - fit: ImageFit = None, + repeat: Optional[ImageRepeat] = None, + fit: Optional[ImageFit] = None, border_radius: BorderRadiusValue = None, color: Optional[str] = None, - color_blend_mode: Optional[BlendMode] = None, + color_blend_mode: BlendMode = BlendMode.NONE, gapless_playback: Optional[bool] = None, semantics_label: Optional[str] = None, ): @@ -135,22 +134,36 @@ def src_base64(self, value): # fit @property - def fit(self): - return self._get_attr("fit") + def fit(self) -> Optional[ImageFit]: + return self.__fit @fit.setter + def fit(self, value: Optional[ImageFit]): + self.__fit = value + if isinstance(value, ImageFit): + self._set_attr("fit", value.value) + else: + self.__set_fit(value) + @beartype - def fit(self, value: ImageFit): + def __set_fit(self, value: ImageFitString): self._set_attr("fit", value) # repeat @property - def repeat(self): - return self._get_attr("repeat") + def repeat(self) -> Optional[ImageRepeat]: + return self.__repeat @repeat.setter + def repeat(self, value: Optional[ImageRepeat]): + self.__repeat = value + if isinstance(value, ImageRepeat): + self._set_attr("repeat", value.value) + else: + self.__set_repeat(value) + @beartype - def repeat(self, value: ImageRepeat): + def __set_repeat(self, value: ImageRepeatString): self._set_attr("repeat", value) # border_radius @@ -174,12 +187,19 @@ def color(self, value): # color_blend_mode @property - def color_blend_mode(self) -> Optional[BlendMode]: - return self._get_attr("colorBlendMode") + def color_blend_mode(self) -> BlendMode: + return self.__blend_mode @color_blend_mode.setter + def color_blend_mode(self, value: BlendMode): + self.__blend_mode = value + if isinstance(value, BlendMode): + self._set_attr("colorBlendMode", value.value) + else: + self.__set_blend_mode(value) + @beartype - def color_blend_mode(self, value: Optional[BlendMode]): + def __set_blend_mode(self, value: BlendModeString): self._set_attr("colorBlendMode", value) # gapless_playback diff --git a/sdk/python/flet/list_view.py b/sdk/python/flet/list_view.py index 06e896dfa..437260d10 100644 --- a/sdk/python/flet/list_view.py +++ b/sdk/python/flet/list_view.py @@ -1,6 +1,7 @@ -from typing import Any, List, Optional, Union +from typing import Any, Optional, Union from beartype import beartype +from beartype.typing import List from flet.constrained_control import ConstrainedControl from flet.control import Control, OptionalNumber diff --git a/sdk/python/flet/markdown.py b/sdk/python/flet/markdown.py index 8bed89875..45c590b61 100644 --- a/sdk/python/flet/markdown.py +++ b/sdk/python/flet/markdown.py @@ -1,3 +1,4 @@ +from enum import Enum from typing import Any, Optional, Union from beartype import beartype @@ -19,11 +20,18 @@ except ImportError: from typing_extensions import Literal -MarkdownExtensionSet = Literal[ +MarkdownExtensionSetString = Literal[ None, "none", "commonMark", "gitHubWeb", "gitHubFlavored" ] +class MarkdownExtensionSet(Enum): + NONE = "none" + COMMON_MARK = "commonMark" + GITHUB_WEB = "gitHubWeb" + GITHUB_FLAVORED = "gitHubFlavored" + + class Markdown(ConstrainedControl): def __init__( self, @@ -57,7 +65,7 @@ def __init__( # Specific # selectable: Optional[bool] = None, - extension_set: MarkdownExtensionSet = None, + extension_set: Optional[MarkdownExtensionSet] = None, code_theme: Optional[str] = None, code_style: Optional[TextStyle] = None, on_tap_link=None, @@ -107,11 +115,12 @@ def _before_build_command(self): # value @property - def value(self): + def value(self) -> Optional[str]: return self._get_attr("value") @value.setter - def value(self, value): + @beartype + def value(self, value: Optional[str]): self._set_attr("value", value) # selectable @@ -127,11 +136,18 @@ def selectable(self, value: Optional[bool]): # extension_set @property def extension_set(self) -> Optional[MarkdownExtensionSet]: - return self._get_attr("extensionSet") + return self.__extension_set @extension_set.setter - @beartype def extension_set(self, value: Optional[MarkdownExtensionSet]): + self.__extension_set = value + if isinstance(value, MarkdownExtensionSet): + self._set_attr("extensionSet", value.value) + else: + self.__set_extension_set(value) + + @beartype + def __set_extension_set(self, value: MarkdownExtensionSetString): self._set_attr("extensionSet", value) # code_theme diff --git a/sdk/python/flet/navigation_bar.py b/sdk/python/flet/navigation_bar.py index 217d64b7a..7873b4358 100644 --- a/sdk/python/flet/navigation_bar.py +++ b/sdk/python/flet/navigation_bar.py @@ -1,3 +1,4 @@ +from enum import Enum from typing import Any, Optional, Union from beartype import beartype @@ -19,11 +20,17 @@ except ImportError: from typing_extensions import Literal -NavigationBarLabelBehavior = Literal[ +NavigationBarLabelBehaviorString = Literal[ None, "alwaysShow", "alwaysHide", "onlyShowSelected" ] +class NavigationBarLabelBehavior(Enum): + ALWAYS_SHOW = "alwaysShow" + ALWAYS_HIDE = "alwaysHide" + ONLY_SHOW_SELECTED = "onlyShowSelected" + + class NavigationDestination(Control): def __init__( self, @@ -138,7 +145,7 @@ def __init__( destinations: Optional[List[NavigationDestination]] = None, selected_index: Optional[int] = None, bgcolor: Optional[str] = None, - label_behavior: NavigationBarLabelBehavior = None, + label_behavior: Optional[NavigationBarLabelBehavior] = None, elevation: OptionalNumber = None, on_change=None, ): @@ -217,12 +224,19 @@ def selected_index(self, value: Optional[int]): # label_behavior @property - def label_behavior(self) -> NavigationBarLabelBehavior: - return self._get_attr("labelType") + def label_behavior(self) -> Optional[NavigationBarLabelBehavior]: + return self.__label_behavior @label_behavior.setter + def label_behavior(self, value: Optional[NavigationBarLabelBehavior]): + self.__label_behavior = value + if isinstance(value, NavigationBarLabelBehavior): + self._set_attr("labelType", value.value) + else: + self.__set_label_behavior(value) + @beartype - def label_behavior(self, value: NavigationBarLabelBehavior): + def __set_label_behavior(self, value: NavigationBarLabelBehaviorString): self._set_attr("labelType", value) # bgcolor diff --git a/sdk/python/flet/navigation_rail.py b/sdk/python/flet/navigation_rail.py index 2bc39b631..cc2cfb03a 100644 --- a/sdk/python/flet/navigation_rail.py +++ b/sdk/python/flet/navigation_rail.py @@ -1,3 +1,4 @@ +from enum import Enum from typing import Any, Optional, Union from beartype import beartype @@ -20,7 +21,13 @@ except ImportError: from typing_extensions import Literal -NavigationRailLabelType = Literal[None, "none", "all", "selected"] +NavigationRailLabelTypeString = Literal[None, "none", "all", "selected"] + + +class NavigationRailLabelType(Enum): + NONE = "none" + ALL = "all" + SELECTED = "selected" class NavigationRailDestination(Control): @@ -169,7 +176,7 @@ def __init__( destinations: Optional[List[NavigationRailDestination]] = None, selected_index: Optional[int] = None, extended: Optional[bool] = None, - label_type: NavigationRailLabelType = None, + label_type: Optional[NavigationRailLabelType] = None, bgcolor: Optional[str] = None, leading: Optional[Control] = None, trailing: Optional[Control] = None, @@ -266,12 +273,19 @@ def selected_index(self, value: Optional[int]): # label_type @property - def label_type(self) -> NavigationRailLabelType: - return self._get_attr("labelType") + def label_type(self) -> Optional[NavigationRailLabelType]: + return self.__label_type @label_type.setter + def label_type(self, value: Optional[NavigationRailLabelType]): + self.__label_type = value + if isinstance(value, NavigationRailLabelType): + self._set_attr("labelType", value.value) + else: + self.__set_label_type(value) + @beartype - def label_type(self, value: NavigationRailLabelType): + def __set_label_type(self, value: NavigationRailLabelTypeString): self._set_attr("labelType", value) # bgcolor diff --git a/sdk/python/flet/page.py b/sdk/python/flet/page.py index 295adf423..638f53dd1 100644 --- a/sdk/python/flet/page.py +++ b/sdk/python/flet/page.py @@ -18,13 +18,7 @@ from flet.client_storage import ClientStorage from flet.clipboard import Clipboard from flet.connection import Connection -from flet.control import ( - Control, - CrossAxisAlignment, - MainAxisAlignment, - OptionalNumber, - ScrollMode, -) +from flet.control import Control, OptionalNumber from flet.control_event import ControlEvent from flet.event import Event from flet.event_handler import EventHandler @@ -36,7 +30,16 @@ from flet.session_storage import SessionStorage from flet.snack_bar import SnackBar from flet.theme import Theme -from flet.types import PaddingValue +from flet.types import ( + CrossAxisAlignment, + MainAxisAlignment, + PaddingValue, + PageDesignLanguage, + PageDesignString, + ScrollMode, + ThemeMode, + ThemeModeString, +) from flet.view import View try: @@ -45,10 +48,6 @@ from typing_extensions import Literal -PageDesign = Literal[None, "material", "cupertino", "fluent", "macos", "adaptive"] -ThemeMode = Literal[None, "system", "light", "dark"] - - class Page(Control): def __init__(self, conn: Connection, session_id): Control.__init__(self) @@ -453,10 +452,7 @@ def launch_url( self.invoke_method("launchUrl", args) @beartype - def can_launch_url( - self, - url: str - ): + def can_launch_url(self, url: str): args = {"url": url} return self.invoke_method("canLaunchUrl", args, wait_for_result=True) == "true" @@ -615,12 +611,19 @@ def platform(self): # design @property - def design(self): - return self._get_attr("design") + def design(self) -> Optional[PageDesignLanguage]: + return self.__design @design.setter + def design(self, value: Optional[PageDesignLanguage]): + self.__design = value + if isinstance(value, PageDesignLanguage): + self._set_attr("design", value.value) + else: + self.__set_design(value) + @beartype - def design(self, value: PageDesign): + def __set_design(self, value: PageDesignString): self._set_attr("design", value) # fonts @@ -684,7 +687,6 @@ def horizontal_alignment(self) -> CrossAxisAlignment: return self.__default_view.horizontal_alignment @horizontal_alignment.setter - @beartype def horizontal_alignment(self, value: CrossAxisAlignment): self.__default_view.horizontal_alignment = value @@ -694,7 +696,6 @@ def vertical_alignment(self) -> MainAxisAlignment: return self.__default_view.vertical_alignment @vertical_alignment.setter - @beartype def vertical_alignment(self, value: MainAxisAlignment): self.__default_view.vertical_alignment = value @@ -729,12 +730,12 @@ def bgcolor(self, value): # scroll @property - def scroll(self) -> ScrollMode: + def scroll(self) -> Optional[ScrollMode]: return self.__default_view.scroll @scroll.setter @beartype - def scroll(self, value: ScrollMode): + def scroll(self, value: Optional[ScrollMode]): self.__default_view.scroll = value # auto_scroll @@ -800,11 +801,18 @@ def dialog(self, value: Optional[Control]): # theme_mode @property def theme_mode(self) -> Optional[ThemeMode]: - return self._get_attr("themeMode") + return self.__theme_mode @theme_mode.setter - @beartype def theme_mode(self, value: Optional[ThemeMode]): + self.__theme_mode = value + if isinstance(value, ThemeMode): + self._set_attr("themeMode", value.value) + else: + self.__set_theme_mode(value) + + @beartype + def __set_theme_mode(self, value: ThemeModeString): self._set_attr("themeMode", value) # theme diff --git a/sdk/python/flet/radio.py b/sdk/python/flet/radio.py index dc5fd05fa..a565eb7fd 100644 --- a/sdk/python/flet/radio.py +++ b/sdk/python/flet/radio.py @@ -8,6 +8,8 @@ from flet.ref import Ref from flet.types import ( AnimationValue, + LabelPosition, + LabelPositionString, MaterialState, OffsetValue, ResponsiveNumber, @@ -21,9 +23,6 @@ from typing_extensions import Literal -LabelPosition = Literal[None, "right", "left"] - - class Radio(ConstrainedControl): def __init__( self, @@ -56,7 +55,7 @@ def __init__( # Specific # label: Optional[str] = None, - label_position: LabelPosition = None, + label_position: LabelPosition = LabelPosition.NONE, value: Optional[str] = None, autofocus: Optional[bool] = None, fill_color: Union[None, str, Dict[MaterialState, str]] = None, @@ -108,11 +107,12 @@ def _before_build_command(self): # value @property - def value(self): + def value(self) -> Optional[str]: return self._get_attr("value", def_value="") @value.setter - def value(self, value): + @beartype + def value(self, value: Optional[str]): self._set_attr("value", value) # label @@ -127,11 +127,18 @@ def label(self, value): # label_position @property def label_position(self) -> LabelPosition: - return self._get_attr("labelPosition") + return self.__label_position @label_position.setter - @beartype def label_position(self, value: LabelPosition): + self.__label_position = value + if isinstance(value, LabelPosition): + self._set_attr("labelPosition", value.value) + else: + self.__set_label_position(value) + + @beartype + def __set_label_position(self, value: LabelPositionString): self._set_attr("labelPosition", value) # fill_color diff --git a/sdk/python/flet/radio_group.py b/sdk/python/flet/radio_group.py index 3943b90b0..fc3736f51 100644 --- a/sdk/python/flet/radio_group.py +++ b/sdk/python/flet/radio_group.py @@ -49,11 +49,12 @@ def _get_children(self): # value @property - def value(self): + def value(self) -> Optional[str]: return self._get_attr("value") @value.setter - def value(self, value): + @beartype + def value(self, value: Optional[str]): self._set_attr("value", value) # content diff --git a/sdk/python/flet/responsive_row.py b/sdk/python/flet/responsive_row.py index a7ccb9c82..2e5b53c0e 100644 --- a/sdk/python/flet/responsive_row.py +++ b/sdk/python/flet/responsive_row.py @@ -1,13 +1,17 @@ -from typing import Any, List, Optional, Union +from typing import Any, Optional, Union from beartype import beartype -from beartype.typing import Dict +from beartype.typing import List from flet.constrained_control import ConstrainedControl -from flet.control import Control, CrossAxisAlignment, MainAxisAlignment, OptionalNumber +from flet.control import Control, OptionalNumber from flet.ref import Ref from flet.types import ( AnimationValue, + CrossAxisAlignment, + CrossAxisAlignmentString, + MainAxisAlignment, + MainAxisAlignmentString, OffsetValue, ResponsiveNumber, RotateValue, @@ -47,8 +51,8 @@ def __init__( # Row specific # columns: Optional[ResponsiveNumber] = None, - alignment: MainAxisAlignment = None, - vertical_alignment: CrossAxisAlignment = None, + alignment: MainAxisAlignment = MainAxisAlignment.NONE, + vertical_alignment: CrossAxisAlignment = CrossAxisAlignment.NONE, spacing: Optional[ResponsiveNumber] = None, run_spacing: Optional[ResponsiveNumber] = None, ): @@ -106,21 +110,35 @@ def clean(self): # horizontal_alignment @property def alignment(self) -> MainAxisAlignment: - return self._get_attr("alignment") + return self.__alignment @alignment.setter - @beartype def alignment(self, value: MainAxisAlignment): + self.__alignment = value + if isinstance(value, MainAxisAlignment): + self._set_attr("alignment", value.value) + else: + self.__set_alignment(value) + + @beartype + def __set_alignment(self, value: MainAxisAlignmentString): self._set_attr("alignment", value) # vertical_alignment @property def vertical_alignment(self) -> CrossAxisAlignment: - return self._get_attr("verticalAlignment") + return self.__vertical_alignment @vertical_alignment.setter - @beartype def vertical_alignment(self, value: CrossAxisAlignment): + self.__vertical_alignment = value + if isinstance(value, CrossAxisAlignment): + self._set_attr("verticalAlignment", value.value) + else: + self.__set_vertical_alignment(value) + + @beartype + def __set_vertical_alignment(self, value: CrossAxisAlignmentString): self._set_attr("verticalAlignment", value) # columns diff --git a/sdk/python/flet/row.py b/sdk/python/flet/row.py index 8cd920125..bbae4c935 100644 --- a/sdk/python/flet/row.py +++ b/sdk/python/flet/row.py @@ -1,22 +1,23 @@ -from typing import Any, List, Optional, Union +from typing import Any, Optional, Union from beartype import beartype +from beartype.typing import List from flet.constrained_control import ConstrainedControl -from flet.control import ( - Control, - CrossAxisAlignment, - MainAxisAlignment, - OptionalNumber, - ScrollMode, -) +from flet.control import Control, OptionalNumber from flet.ref import Ref from flet.types import ( AnimationValue, + CrossAxisAlignment, + CrossAxisAlignmentString, + MainAxisAlignment, + MainAxisAlignmentString, OffsetValue, ResponsiveNumber, RotateValue, ScaleValue, + ScrollMode, + ScrollModeString, ) @@ -51,13 +52,13 @@ def __init__( # # Row specific # - alignment: MainAxisAlignment = None, - vertical_alignment: CrossAxisAlignment = None, + alignment: MainAxisAlignment = MainAxisAlignment.NONE, + vertical_alignment: CrossAxisAlignment = CrossAxisAlignment.NONE, spacing: OptionalNumber = None, tight: Optional[bool] = None, wrap: Optional[bool] = None, run_spacing: OptionalNumber = None, - scroll: ScrollMode = None, + scroll: Optional[ScrollMode] = None, auto_scroll: Optional[bool] = None, ): ConstrainedControl.__init__( @@ -88,7 +89,6 @@ def __init__( data=data, ) - self.__controls: List[Control] = [] self.controls = controls self.alignment = alignment self.vertical_alignment = vertical_alignment @@ -96,7 +96,6 @@ def __init__( self.tight = tight self.wrap = wrap self.run_spacing = run_spacing - self.__scroll = False self.scroll = scroll self.auto_scroll = auto_scroll @@ -123,21 +122,35 @@ def tight(self, value: Optional[bool]): # horizontal_alignment @property def alignment(self) -> MainAxisAlignment: - return self._get_attr("alignment") + return self.__alignment @alignment.setter - @beartype def alignment(self, value: MainAxisAlignment): + self.__alignment = value + if isinstance(value, MainAxisAlignment): + self._set_attr("alignment", value.value) + else: + self.__set_alignment(value) + + @beartype + def __set_alignment(self, value: MainAxisAlignmentString): self._set_attr("alignment", value) # vertical_alignment @property def vertical_alignment(self) -> CrossAxisAlignment: - return self._get_attr("verticalAlignment") + return self.__vertical_alignment @vertical_alignment.setter - @beartype def vertical_alignment(self, value: CrossAxisAlignment): + self.__vertical_alignment = value + if isinstance(value, CrossAxisAlignment): + self._set_attr("verticalAlignment", value.value) + else: + self.__set_vertical_alignment(value) + + @beartype + def __set_vertical_alignment(self, value: CrossAxisAlignmentString): self._set_attr("verticalAlignment", value) # spacing @@ -172,17 +185,23 @@ def run_spacing(self, value: OptionalNumber): # scroll @property - def scroll(self) -> ScrollMode: + def scroll(self) -> Optional[ScrollMode]: return self.__scroll @scroll.setter - @beartype - def scroll(self, value: ScrollMode): + def scroll(self, value: Optional[ScrollMode]): self.__scroll = value - if value is True: + if isinstance(value, ScrollMode): + self._set_attr("scroll", value.value) + else: + self.__set_scroll(value) + + @beartype + def __set_scroll(self, value: Optional[ScrollModeString]): + if value == True: value = "auto" - elif value is False: - value = "none" + elif value == False: + value = None self._set_attr("scroll", value) # auto_scroll @@ -201,5 +220,6 @@ def controls(self): return self.__controls @controls.setter - def controls(self, value): + @beartype + def controls(self, value: Optional[List[Control]]): self.__controls = value if value is not None else [] diff --git a/sdk/python/flet/shader_mask.py b/sdk/python/flet/shader_mask.py index 58ebc2fad..065bf0788 100644 --- a/sdk/python/flet/shader_mask.py +++ b/sdk/python/flet/shader_mask.py @@ -3,11 +3,13 @@ from beartype import beartype from flet.constrained_control import ConstrainedControl -from flet.control import BlendMode, Control, OptionalNumber +from flet.control import Control, OptionalNumber from flet.gradients import Gradient from flet.ref import Ref from flet.types import ( AnimationValue, + BlendMode, + BlendModeString, BorderRadiusValue, OffsetValue, ResponsiveNumber, @@ -48,7 +50,7 @@ def __init__( # # Specific # - blend_mode: Optional[BlendMode] = None, + blend_mode: BlendMode = BlendMode.NONE, shader: Optional[Gradient] = None, border_radius: BorderRadiusValue = None, ): @@ -113,12 +115,19 @@ def content(self, value: Optional[Control]): # blend_mode @property - def blend_mode(self) -> Optional[BlendMode]: - return self._get_attr("blendMode") + def blend_mode(self) -> BlendMode: + return self.__blend_mode @blend_mode.setter + def blend_mode(self, value: BlendMode): + self.__blend_mode = value + if isinstance(value, BlendMode): + self._set_attr("blendMode", value.value) + else: + self.__set_blend_mode(value) + @beartype - def blend_mode(self, value: Optional[BlendMode]): + def __set_blend_mode(self, value: BlendModeString): self._set_attr("blendMode", value) # shader diff --git a/sdk/python/flet/stack.py b/sdk/python/flet/stack.py index fc7a94f07..e9221cf19 100644 --- a/sdk/python/flet/stack.py +++ b/sdk/python/flet/stack.py @@ -1,12 +1,15 @@ -from typing import Any, List, Optional, Union +from typing import Any, Optional, Union from beartype import beartype +from beartype.typing import List from flet.constrained_control import ConstrainedControl -from flet.control import ClipBehavior, Control, OptionalNumber +from flet.control import Control, OptionalNumber from flet.ref import Ref from flet.types import ( AnimationValue, + ClipBehavior, + ClipBehaviorString, OffsetValue, ResponsiveNumber, RotateValue, @@ -50,7 +53,7 @@ def __init__( # # Stack-specific # - clip_behavior: ClipBehavior = None, + clip_behavior: Optional[ClipBehavior] = None, ): ConstrainedControl.__init__( self, @@ -102,9 +105,16 @@ def controls(self, value): # clip_behavior @property def clip_behavior(self) -> Optional[ClipBehavior]: - return self._get_attr("clipBehavior") + return self.__clip_behavior @clip_behavior.setter - @beartype def clip_behavior(self, value: Optional[ClipBehavior]): + self.__clip_behavior = value + if isinstance(value, ClipBehavior): + self._set_attr("clipBehavior", value.value) + else: + self.__set_clip_behavior(value) + + @beartype + def __set_clip_behavior(self, value: Optional[ClipBehaviorString]): self._set_attr("clipBehavior", value) diff --git a/sdk/python/flet/switch.py b/sdk/python/flet/switch.py index a1be345ee..ac528a2ef 100644 --- a/sdk/python/flet/switch.py +++ b/sdk/python/flet/switch.py @@ -8,6 +8,8 @@ from flet.ref import Ref from flet.types import ( AnimationValue, + LabelPosition, + LabelPositionString, MaterialState, OffsetValue, ResponsiveNumber, @@ -21,9 +23,6 @@ from typing_extensions import Literal -LabelPosition = Literal[None, "right", "left"] - - class Switch(ConstrainedControl): def __init__( self, @@ -56,7 +55,7 @@ def __init__( # Specific # label: Optional[str] = None, - label_position: LabelPosition = None, + label_position: LabelPosition = LabelPosition.NONE, value: Optional[bool] = None, autofocus: Optional[bool] = None, active_color: Optional[str] = None, @@ -141,11 +140,18 @@ def label(self, value): # label_position @property def label_position(self) -> LabelPosition: - return self._get_attr("labelPosition") + return self.__label_position @label_position.setter - @beartype def label_position(self, value: LabelPosition): + self.__label_position = value + if isinstance(value, LabelPosition): + self._set_attr("labelPosition", value.value) + else: + self.__set_label_position(value) + + @beartype + def __set_label_position(self, value: LabelPositionString): self._set_attr("labelPosition", value) # autofocus diff --git a/sdk/python/flet/text.py b/sdk/python/flet/text.py index db4ed2e5b..ea673c4f9 100644 --- a/sdk/python/flet/text.py +++ b/sdk/python/flet/text.py @@ -1,17 +1,21 @@ +from enum import Enum from typing import Any, Optional, Union from beartype import beartype from flet.constrained_control import ConstrainedControl -from flet.control import OptionalNumber, TextAlign +from flet.control import OptionalNumber from flet.ref import Ref from flet.types import ( AnimationValue, FontWeight, + FontWeightString, OffsetValue, ResponsiveNumber, RotateValue, ScaleValue, + TextAlign, + TextAlignString, ) try: @@ -19,9 +23,18 @@ except ImportError: from typing_extensions import Literal -TextOverflow = Literal[None, "clip", "ellipsis", "fade", "visible"] +TextOverflowString = Literal[None, "clip", "ellipsis", "fade", "visible"] -TextThemeStyle = Literal[ + +class TextOverflow(Enum): + NONE = None + CLIP = "clip" + ELLIPSIS = "ellipsis" + FADE = "fade" + VISIBLE = "visible" + + +TextThemeStyleString = Literal[ "displayLarge", "displayMedium", "displaySmall", @@ -40,6 +53,24 @@ ] +class TextThemeStyle(Enum): + DISPLAY_LARGE = "displayLarge" + DISPLAY_MEDIUM = "displayMedium" + DISPLAY_SMALL = "displaySmall" + HEADLINE_LARGE = "headlineLarge" + HEADLINE_MEDIUM = "headlineMedium" + HEADLINE_SMALL = "headlineSmall" + TITLE_LARGE = "titleLarge" + TITLE_MEDIUM = "titleMedium" + TITLE_SMALL = "titleSmall" + LABEL_LARGE = "labelLarge" + LABEL_MEDIUM = "labelMedium" + LABEL_SMALL = "labelSmall" + BODY_LARGE = "bodyLarge" + BODY_MEDIUM = "bodyMedium" + BODY_SMALL = "bodySmall" + + class Text(ConstrainedControl): def __init__( self, @@ -72,14 +103,14 @@ def __init__( # # text-specific # - text_align: TextAlign = None, + text_align: TextAlign = TextAlign.NONE, font_family: Optional[str] = None, size: OptionalNumber = None, - weight: FontWeight = None, + weight: Optional[FontWeight] = None, italic: Optional[bool] = None, style: Optional[TextThemeStyle] = None, max_lines: Optional[int] = None, - overflow: TextOverflow = None, + overflow: TextOverflow = TextOverflow.NONE, selectable: Optional[bool] = None, no_wrap: Optional[bool] = None, color: Optional[str] = None, @@ -136,21 +167,29 @@ def _get_control_name(self): # value @property - def value(self): + def value(self) -> Optional[str]: return self._get_attr("value") @value.setter - def value(self, value): + @beartype + def value(self, value: Optional[str]): self._set_attr("value", value) # text_align @property def text_align(self) -> TextAlign: - return self._get_attr("textAlign") + return self.__text_align @text_align.setter - @beartype def text_align(self, value: TextAlign): + self.__text_align = value + if isinstance(value, TextAlign): + self._set_attr("textAlign", value.value) + else: + self.__set_text_align(value) + + @beartype + def __set_text_align(self, value: TextAlignString): self._set_attr("textAlign", value) # font_family @@ -174,22 +213,36 @@ def size(self, value: OptionalNumber): # weight @property - def weight(self) -> FontWeight: - return self._get_attr("weight") + def weight(self) -> Optional[FontWeight]: + return self.__weight @weight.setter + def weight(self, value: Optional[FontWeight]): + self.__weight = value + if isinstance(value, FontWeight): + self._set_attr("weight", value.value) + else: + self.__set_weight(value) + @beartype - def weight(self, value: FontWeight): + def __set_weight(self, value: FontWeightString): self._set_attr("weight", value) # style @property def style(self) -> Optional[TextThemeStyle]: - return self._get_attr("style") + return self.__style @style.setter - @beartype def style(self, value: Optional[TextThemeStyle]): + self.__style = value + if isinstance(value, TextThemeStyle): + self._set_attr("style", value.value) + else: + self.__set_style(value) + + @beartype + def __set_style(self, value: Optional[TextThemeStyleString]): self._set_attr("style", value) # italic @@ -235,11 +288,18 @@ def max_lines(self, value: Optional[int]): # overflow @property def overflow(self) -> TextOverflow: - return self._get_attr("overflow") + return self.__overflow @overflow.setter - @beartype def overflow(self, value: TextOverflow): + self.__overflow = value + if isinstance(value, TextOverflow): + self._set_attr("overflow", value.value) + else: + self.__set_overflow(value) + + @beartype + def __set_overflow(self, value: TextOverflowString): self._set_attr("overflow", value) # color diff --git a/sdk/python/flet/text_style.py b/sdk/python/flet/text_style.py index 014cb304f..1f0afca4a 100644 --- a/sdk/python/flet/text_style.py +++ b/sdk/python/flet/text_style.py @@ -8,7 +8,7 @@ @dataclasses.dataclass class TextStyle: size: Union[None, int, float] = field(default=None) - weight: FontWeight = field(default=None) + weight: Optional[FontWeight] = field(default=None) italic: Optional[bool] = field(default=None) font_family: Optional[str] = field(default=None) color: Optional[str] = field(default=None) diff --git a/sdk/python/flet/textfield.py b/sdk/python/flet/textfield.py index 072217844..27faf05b2 100644 --- a/sdk/python/flet/textfield.py +++ b/sdk/python/flet/textfield.py @@ -1,10 +1,11 @@ +from enum import Enum from typing import Any, Optional, Union from beartype import beartype -from flet.control import Control, InputBorder, OptionalNumber, TextAlign +from flet.control import Control, OptionalNumber from flet.focus import FocusData -from flet.form_field_control import FormFieldControl +from flet.form_field_control import FormFieldControl, InputBorder from flet.ref import Ref from flet.text_style import TextStyle from flet.types import ( @@ -15,6 +16,8 @@ ResponsiveNumber, RotateValue, ScaleValue, + TextAlign, + TextAlignString, ) try: @@ -22,7 +25,7 @@ except ImportError: from typing_extensions import Literal -TextInputType = Literal[ +KeyboardTypeString = Literal[ None, "text", "multiline", @@ -37,7 +40,29 @@ "none", ] -TextCapitalization = Literal[None, "none", "characters", "words", "sentences"] + +class KeyboardType(Enum): + NONE = "none" + TEXT = "text" + MULTILINE = "multiline" + NUMBER = "number" + PHONE = "phone" + DATETIME = "datetime" + EMAIL = "email" + URL = "url" + VISIBLE_PASSWORD = "visiblePassword" + NAME = "name" + STREET_ADDRESS = "streetAddress" + + +TextCapitalizationString = Literal[None, "none", "characters", "words", "sentences"] + + +class TextCapitalization(Enum): + NONE = None + CHARACTERS = "characters" + WORDS = "words" + SENTENCES = "sentences" class TextField(FormFieldControl): @@ -72,7 +97,7 @@ def __init__( label: Optional[str] = None, label_style: Optional[TextStyle] = None, icon: Optional[str] = None, - border: InputBorder = None, + border: Optional[InputBorder] = None, color: Optional[str] = None, bgcolor: Optional[str] = None, border_radius: BorderRadiusValue = None, @@ -104,7 +129,7 @@ def __init__( # TextField Specific # value: Optional[str] = None, - keyboard_type: TextInputType = None, + keyboard_type: Optional[KeyboardType] = None, multiline: Optional[bool] = None, min_lines: Optional[int] = None, max_lines: Optional[int] = None, @@ -113,9 +138,9 @@ def __init__( can_reveal_password: Optional[bool] = None, read_only: Optional[bool] = None, shift_enter: Optional[bool] = None, - text_align: TextAlign = None, + text_align: TextAlign = TextAlign.NONE, autofocus: Optional[bool] = None, - capitalization: TextCapitalization = None, + capitalization: TextCapitalization = TextCapitalization.NONE, cursor_color: Optional[str] = None, cursor_width: OptionalNumber = None, cursor_height: OptionalNumber = None, @@ -219,31 +244,46 @@ def focus(self): # value @property - def value(self): + def value(self) -> Optional[str]: return self._get_attr("value", def_value="") @value.setter - def value(self, value): + @beartype + def value(self, value: Optional[str]): self._set_attr("value", value) # keyboard_type @property - def keyboard_type(self) -> TextInputType: - return self._get_attr("keyboardType") + def keyboard_type(self) -> Optional[KeyboardType]: + return self.__keyboard_type @keyboard_type.setter + def keyboard_type(self, value: Optional[KeyboardType]): + self.__keyboard_type = value + if isinstance(value, KeyboardType): + self._set_attr("keyboardType", value.value) + else: + self.__set_keyboard_type(value) + @beartype - def keyboard_type(self, value: TextInputType): + def __set_keyboard_type(self, value: KeyboardTypeString): self._set_attr("keyboardType", value) # text_align @property def text_align(self) -> TextAlign: - return self._get_attr("textAlign") + return self.__text_align @text_align.setter - @beartype def text_align(self, value: TextAlign): + self.__text_align = value + if isinstance(value, TextAlign): + self._set_attr("textAlign", value.value) + else: + self.__set_text_align(value) + + @beartype + def __set_text_align(self, value: TextAlignString): self._set_attr("textAlign", value) # multiline @@ -339,11 +379,18 @@ def autofocus(self, value: Optional[bool]): # capitalization @property def capitalization(self) -> TextCapitalization: - return self._get_attr("capitalization") + return self.__capitalization @capitalization.setter - @beartype def capitalization(self, value: TextCapitalization): + self.__capitalization = value + if isinstance(value, TextCapitalization): + self._set_attr("capitalization", value.value) + else: + self.__set_capitalization(value) + + @beartype + def __set_capitalization(self, value: TextCapitalizationString): self._set_attr("capitalization", value) # cursor_color diff --git a/sdk/python/flet/theme.py b/sdk/python/flet/theme.py index 15b12c257..5c2c27975 100644 --- a/sdk/python/flet/theme.py +++ b/sdk/python/flet/theme.py @@ -1,26 +1,43 @@ import dataclasses from dataclasses import field from typing import Optional +from enum import Enum try: from typing import Literal except ImportError: from typing_extensions import Literal -VisualDensity = Literal[ +VisualDensityString = Literal[ None, "standard", "compact", "comfortable", "adaptivePlatformDensity" ] -PageTransition = Literal["fadeUpwards", "openUpwards", "zoom", "cupertino"] + +class ThemeVisualDensity(Enum): + NONE = None + STANDARD = "standard" + COMPACT = "compact" + COMFORTABLE = "comfortable" + ADAPTIVEPLATFORMDENSITY = "adaptivePlatformDensity" + + +PageTransitionString = Literal["fadeUpwards", "openUpwards", "zoom", "cupertino"] + + +class PageTransitionTheme(Enum): + FADE_UPWARDS = "fadeUpwards" + OPEN_UPWARDS = "openUpwards" + ZOOM = "zoom" + CUPERTINO = "cupertino" @dataclasses.dataclass class PageTransitionsTheme: - android: Optional[PageTransition] = field(default=None) - ios: Optional[PageTransition] = field(default=None) - linux: Optional[PageTransition] = field(default=None) - macos: Optional[PageTransition] = field(default=None) - windows: Optional[PageTransition] = field(default=None) + android: Optional[PageTransitionTheme] = field(default=None) + ios: Optional[PageTransitionTheme] = field(default=None) + linux: Optional[PageTransitionTheme] = field(default=None) + macos: Optional[PageTransitionTheme] = field(default=None) + windows: Optional[PageTransitionTheme] = field(default=None) @dataclasses.dataclass @@ -28,5 +45,5 @@ class Theme: color_scheme_seed: Optional[str] = field(default=None) font_family: Optional[str] = field(default=None) use_material3: bool = field(default=True) - visual_density: VisualDensity = field(default="standard") + visual_density: ThemeVisualDensity = field(default=ThemeVisualDensity.STANDARD) page_transitions: PageTransitionsTheme = field(default_factory=PageTransitionsTheme) diff --git a/sdk/python/flet/tooltip.py b/sdk/python/flet/tooltip.py index 3edf37af5..c163ba1e2 100644 --- a/sdk/python/flet/tooltip.py +++ b/sdk/python/flet/tooltip.py @@ -3,11 +3,18 @@ from beartype import beartype from flet.border import Border -from flet.control import Control, OptionalNumber, TextAlign +from flet.control import Control, OptionalNumber from flet.gradients import Gradient from flet.ref import Ref from flet.text_style import TextStyle -from flet.types import BorderRadiusValue, BoxShape, MarginValue, PaddingValue +from flet.types import ( + BorderRadiusValue, + BoxShape, + MarginValue, + PaddingValue, + TextAlign, + TextAlignString, +) class Tooltip(Control): @@ -33,7 +40,7 @@ def __init__( shape: Optional[BoxShape] = None, message: Optional[str] = None, text_style: Optional[TextStyle] = None, - text_align: Optional[TextAlign] = None, + text_align: TextAlign = TextAlign.NONE, prefer_below: Optional[bool] = None, show_duration: Optional[int] = None, wait_duration: Optional[int] = None, @@ -176,11 +183,18 @@ def message(self, value: Optional[str]): # text_align @property def text_align(self) -> TextAlign: - return self._get_attr("textAlign") + return self.__text_align @text_align.setter - @beartype def text_align(self, value: TextAlign): + self.__text_align = value + if isinstance(value, TextAlign): + self._set_attr("textAlign", value.value) + else: + self.__set_text_align(value) + + @beartype + def __set_text_align(self, value: TextAlignString): self._set_attr("textAlign", value) # text_style diff --git a/sdk/python/flet/types.py b/sdk/python/flet/types.py index 1e3227930..22cdf5aa1 100644 --- a/sdk/python/flet/types.py +++ b/sdk/python/flet/types.py @@ -29,7 +29,7 @@ AnimationValue = Union[None, bool, int, Animation] -FontWeight = Literal[ +FontWeightString = Literal[ None, "normal", "bold", @@ -45,6 +45,20 @@ ] +class FontWeight(Enum): + NORMAL = "normal" + BOLD = "bold" + W_100 = "w100" + W_200 = "w200" + W_300 = "w300" + W_400 = "w400" + W_500 = "w500" + W_600 = "w600" + W_700 = "w700" + W_800 = "w800" + W_900 = "w900" + + class BoxShape(Enum): RECTANGLE = "rectangle" CIRCLE = "circle" @@ -52,14 +66,212 @@ class BoxShape(Enum): ResponsiveNumber = Union[Dict[str, Union[int, float]], int, float] -MaterialState = Literal[ - "hovered", - "focused", - "pressed", - "dragged", - "selected", - "scrolledUnder", - "disabled", - "error", - "", + +class MaterialState(Enum): + HOVERED = "hovered" + FOCUSED = "focused" + PRESSED = "pressed" + DRAGGED = "dragged" + SELECTED = "selected" + SCROLLED_UNDER = "scrolledUnder" + DISABLED = "disabled" + ERROR = "error" + DEFAULT = "" + + +MainAxisAlignmentString = Literal[ + None, + "start", + "end", + "center", + "spaceBetween", + "spaceAround", + "spaceEvenly", +] + +CrossAxisAlignmentString = Literal[ + None, + "start", + "end", + "center", + "stretch", + "baseline", ] + + +class MainAxisAlignment(Enum): + NONE = None + START = "start" + END = "end" + CENTER = "center" + SPACE_BETWEEN = "spaceBetween" + SPACE_AROUND = "spaceAround" + SPACE_EVENLY = "spaceEvenly" + + +class CrossAxisAlignment(Enum): + NONE = None + START = "start" + END = "end" + CENTER = "center" + STRETCH = "stretch" + BASELINE = "baseline" + + +LabelPositionString = Literal[None, "right", "left"] + + +class LabelPosition(Enum): + NONE = None + RIGHT = "right" + LEFT = "left" + + +BlendModeString = Literal[ + "clear", + "color", + "colorBurn", + "colorDodge", + "darken", + "difference", + "dst", + "dstATop", + "dstIn", + "dstOut", + "dstOver", + "exclusion", + "hardLight", + "hue", + "lighten", + "luminosity", + "modulate", + "multiply", + "overlay", + "plus", + "saturation", + "screen", + "softLight", + "src", + "srcATop", + "srcIn", + "srcOut", + "srcOver", + "values", + "xor", +] + + +class BlendMode(Enum): + NONE = None + CLEAR = "clear" + COLOR = "color" + COLOR_BURN = "colorBurn" + COLOR_DODGE = "colorDodge" + DARKEN = "darken" + DIFFERENCE = "difference" + DST = "dst" + DST_A_TOP = "dstATop" + DST_IN = "dstIn" + DST_OUT = "dstOut" + DST_OVER = "dstOver" + EXCLUSION = "exclusion" + HARD_LIGHT = "hardLight" + HUE = "hue" + LIGHTEN = "lighten" + LUMINOSITY = "luminosity" + MODULATE = "modulate" + MULTIPLY = "multiply" + OVERLAY = "overlay" + PLUS = "plus" + SATURATION = "saturation" + SCREEN = "screen" + SOFT_LIGHT = "softLight" + SRC = "src" + SRC_A_TOP = "srcATop" + SRC_IN = "srcIn" + SRC_OUT = "srcOut" + SRC_OVER = "srcOver" + VALUES = "values" + XOR = "xor" + + +TextAlignString = Literal[None, "left", "right", "center", "justify", "start", "end"] + + +class TextAlign(Enum): + NONE = None + LEFT = "left" + RIGHT = "right" + CENTER = "center" + JUSTIFY = "justify" + START = "start" + END = "end" + + +ScrollModeString = Literal[ + None, True, False, "none", "auto", "adaptive", "always", "hidden" +] + + +class ScrollMode(Enum): + AUTO = "auto" + ADAPTIVE = "adaptive" + ALWAYS = "always" + HIDDEN = "hidden" + + +ClipBehaviorString = Literal[ + None, "none", "antiAlias", "antiAliasWithSaveLayer", "hardEdge" +] + + +class ClipBehavior(Enum): + NONE = "none" + ANTI_ALIAS = "antiAlias" + ANTI_ALIAS_WITH_SAVE_LAYER = "antiAliasWithSaveLayer" + HARD_EDGE = "hardEdge" + + +ImageFitString = Literal[ + None, "none", "contain", "cover", "fill", "fitHeight", "fitWidth", "scaleDown" +] + + +class ImageFit(Enum): + NONE = "none" + CONTAIN = "contain" + COVER = "cover" + FILL = "fill" + FIT_HEIGHT = "fitHeight" + FIT_WIDTH = "fitWidth" + SCALE_DOWN = "scaleDown" + + +ImageRepeatString = Literal[None, "noRepeat", "repeat", "repeatX", "repeatY"] + + +class ImageRepeat(Enum): + NO_REPEAT = "noRepeat" + REPEAT = "repeat" + REPEAT_X = "repeatX" + REPEAT_Y = "repeatY" + + +PageDesignString = Literal[None, "material", "cupertino", "fluent", "macos", "adaptive"] + + +class PageDesignLanguage(Enum): + MATERIAL = "material" + CUPERTINO = "cupertino" + FLUENT = "fluent" + MACOS = "macos" + ADAPTIVE = "adaptive" + + +ThemeModeString = Literal[None, "system", "light", "dark"] + + +class ThemeMode(Enum): + SYSTEM = "system" + LIGHT = "light" + DARK = "dark" diff --git a/sdk/python/flet/user_control.py b/sdk/python/flet/user_control.py index ecbe467dd..942b5ba03 100644 --- a/sdk/python/flet/user_control.py +++ b/sdk/python/flet/user_control.py @@ -1,4 +1,4 @@ -from typing import List +from beartype.typing import List from flet.control import Control from flet.stack import Stack diff --git a/sdk/python/flet/view.py b/sdk/python/flet/view.py index 6fa8a3083..55f9ff6d4 100644 --- a/sdk/python/flet/view.py +++ b/sdk/python/flet/view.py @@ -3,15 +3,18 @@ from flet import Control from flet.app_bar import AppBar -from flet.control import ( +from flet.control import OptionalNumber +from flet.floating_action_button import FloatingActionButton +from flet.navigation_bar import NavigationBar +from flet.types import ( CrossAxisAlignment, + CrossAxisAlignmentString, MainAxisAlignment, - OptionalNumber, + MainAxisAlignmentString, + PaddingValue, ScrollMode, + ScrollModeString, ) -from flet.floating_action_button import FloatingActionButton -from flet.navigation_bar import NavigationBar -from flet.types import PaddingValue class View(Control): @@ -22,12 +25,12 @@ def __init__( appbar: Optional[AppBar] = None, floating_action_button: Optional[FloatingActionButton] = None, navigation_bar: Optional[NavigationBar] = None, - vertical_alignment: MainAxisAlignment = None, - horizontal_alignment: CrossAxisAlignment = None, + vertical_alignment: MainAxisAlignment = MainAxisAlignment.NONE, + horizontal_alignment: CrossAxisAlignment = CrossAxisAlignment.NONE, spacing: OptionalNumber = None, padding: PaddingValue = None, bgcolor: Optional[str] = None, - scroll: ScrollMode = None, + scroll: Optional[ScrollMode] = None, auto_scroll: Optional[bool] = None, ): Control.__init__(self) @@ -116,21 +119,35 @@ def navigation_bar(self, value: Optional[NavigationBar]): # horizontal_alignment @property def horizontal_alignment(self) -> CrossAxisAlignment: - return self._get_attr("horizontalAlignment") + return self.__horizontal_alignment @horizontal_alignment.setter - @beartype def horizontal_alignment(self, value: CrossAxisAlignment): + self.__horizontal_alignment = value + if isinstance(value, CrossAxisAlignment): + self._set_attr("horizontalAlignment", value.value) + else: + self.__set_horizontal_alignment(value) + + @beartype + def __set_horizontal_alignment(self, value: CrossAxisAlignmentString): self._set_attr("horizontalAlignment", value) # vertical_alignment @property def vertical_alignment(self) -> MainAxisAlignment: - return self._get_attr("verticalAlignment") + return self.__vertical_alignment @vertical_alignment.setter - @beartype def vertical_alignment(self, value: MainAxisAlignment): + self.__vertical_alignment = value + if isinstance(value, MainAxisAlignment): + self._set_attr("verticalAlignment", value.value) + else: + self.__set_vertical_alignment(value) + + @beartype + def __set_vertical_alignment(self, value: MainAxisAlignmentString): self._set_attr("verticalAlignment", value) # spacing @@ -164,17 +181,23 @@ def bgcolor(self, value): # scroll @property - def scroll(self) -> ScrollMode: + def scroll(self) -> Optional[ScrollMode]: return self.__scroll @scroll.setter + def scroll(self, value: Optional[ScrollMode]): + self.__scroll = value + if isinstance(value, ScrollMode): + self._set_attr("scroll", value.value) + else: + self.__set_scroll(value) + @beartype - def scroll(self, value: ScrollMode): - self.__scroll: ScrollMode = value + def __set_scroll(self, value: Optional[ScrollModeString]): if value == True: value = "auto" elif value == False: - value = "none" + value = None self._set_attr("scroll", value) # auto_scroll diff --git a/sdk/python/tests/test_alert_dialog.py b/sdk/python/tests/test_alert_dialog.py new file mode 100644 index 000000000..fb7a88a89 --- /dev/null +++ b/sdk/python/tests/test_alert_dialog.py @@ -0,0 +1,45 @@ +import beartype.roar +import pytest + +import flet as ft +from flet.protocol import Command + + +def test_instance_no_attrs_set(): + r = ft.AlertDialog() + assert isinstance(r, ft.Control) + assert r._build_add_commands() == [ + Command( + indent=0, + name=None, + values=["alertdialog"], + attrs={"modal": "false", "open": "false"}, + commands=[], + ) + ], "Test failed" + + +def test_alignment_enum(): + r = ft.AlertDialog(actions_alignment=ft.MainAxisAlignment.SPACE_AROUND) + assert isinstance(r.actions_alignment, ft.MainAxisAlignment) + assert isinstance(r._get_attr("actionsAlignment"), str) + cmd = r._build_add_commands() + assert cmd[0].attrs["actionsalignment"] == "spaceAround" + + +def test_alignment_str(): + r = ft.AlertDialog(actions_alignment="center") + assert isinstance(r.actions_alignment, str) + assert isinstance(r._get_attr("actionsalignment"), str) + cmd = r._build_add_commands() + assert cmd[0].attrs["actionsalignment"] == "center" + + +def test_alignment_wrong_str_raises_beartype(): + with pytest.raises(beartype.roar.BeartypeCallHintParamViolation): + r = ft.AlertDialog(actions_alignment="center1") + + +def test_alignment_wrong_type_raises_beartype(): + with pytest.raises(beartype.roar.BeartypeCallHintParamViolation): + r = ft.AlertDialog(actions_alignment=1) diff --git a/sdk/python/tests/test_animated_switcher.py b/sdk/python/tests/test_animated_switcher.py new file mode 100644 index 000000000..4143d4787 --- /dev/null +++ b/sdk/python/tests/test_animated_switcher.py @@ -0,0 +1,82 @@ +import beartype.roar +import pytest + +import flet as ft +from flet.protocol import Command + + +def test_instance_no_attrs_set(): + r = ft.AnimatedSwitcher() + assert isinstance(r, ft.Control) + assert r._build_add_commands() == [ + Command( + indent=0, + name=None, + values=["animatedswitcher"], + attrs={}, + commands=[], + ) + ], "Test failed" + + +def test_switch_in_curve_enum(): + r = ft.AnimatedSwitcher() + assert r.switch_in_curve == None + assert r._get_attr("switchInCurve") is None + + r = ft.AnimatedSwitcher(switch_in_curve=ft.AnimationCurve.BOUNCE_IN) + assert isinstance(r.switch_in_curve, ft.AnimationCurve) + assert r.switch_in_curve == ft.AnimationCurve.BOUNCE_IN + assert r._get_attr("switchInCurve") == "bounceIn" + + r = ft.AnimatedSwitcher(switch_in_curve="easeIn") + assert isinstance(r.switch_in_curve, str) + assert r._get_attr("switchInCurve") == "easeIn" + + with pytest.raises(beartype.roar.BeartypeCallHintParamViolation): + r = ft.AnimatedSwitcher(switch_in_curve="something") + + with pytest.raises(beartype.roar.BeartypeCallHintParamViolation): + r = ft.AnimatedSwitcher(switch_in_curve=1) + + +def test_switch_out_curve_enum(): + r = ft.AnimatedSwitcher() + assert r.switch_out_curve == None + assert r._get_attr("switchOutCurve") is None + + r = ft.AnimatedSwitcher(switch_out_curve=ft.AnimationCurve.BOUNCE_IN) + assert isinstance(r.switch_out_curve, ft.AnimationCurve) + assert r.switch_out_curve == ft.AnimationCurve.BOUNCE_IN + assert r._get_attr("switchOutCurve") == "bounceIn" + + r = ft.AnimatedSwitcher(switch_out_curve="easeIn") + assert isinstance(r.switch_out_curve, str) + assert r._get_attr("switchOutCurve") == "easeIn" + + with pytest.raises(beartype.roar.BeartypeCallHintParamViolation): + r = ft.AnimatedSwitcher(switch_out_curve="something") + + with pytest.raises(beartype.roar.BeartypeCallHintParamViolation): + r = ft.AnimatedSwitcher(switch_out_curve=1) + + +def test_transition_enum(): + r = ft.AnimatedSwitcher() + assert r.transition == None + assert r._get_attr("transition") is None + + r = ft.AnimatedSwitcher(transition=ft.AnimatedSwitcherTransition.FADE) + assert isinstance(r.transition, ft.AnimatedSwitcherTransition) + assert r.transition == ft.AnimatedSwitcherTransition.FADE + assert r._get_attr("transition") == "fade" + + r = ft.AnimatedSwitcher(transition="scale") + assert isinstance(r.transition, str) + assert r._get_attr("transition") == "scale" + + with pytest.raises(beartype.roar.BeartypeCallHintParamViolation): + r = ft.AnimatedSwitcher(transition="something") + + with pytest.raises(beartype.roar.BeartypeCallHintParamViolation): + r = ft.AnimatedSwitcher(transition=1) diff --git a/sdk/python/tests/test_checkbox.py b/sdk/python/tests/test_checkbox.py new file mode 100644 index 000000000..91132da46 --- /dev/null +++ b/sdk/python/tests/test_checkbox.py @@ -0,0 +1,45 @@ +import beartype.roar +import pytest + +import flet as ft +from flet.protocol import Command + + +def test_instance_no_attrs_set(): + r = ft.Checkbox() + assert isinstance(r, ft.Control) + assert r._build_add_commands() == [ + Command( + indent=0, + name=None, + values=["checkbox"], + attrs={}, + commands=[], + ) + ], "Test failed" + + +def test_label_position_enum(): + r = ft.Checkbox(label_position=ft.LabelPosition.LEFT) + assert isinstance(r.label_position, ft.LabelPosition) + assert isinstance(r._get_attr("labelPosition"), str) + cmd = r._build_add_commands() + assert cmd[0].attrs["labelposition"] == "left" + + +def test_label_position_str(): + r = ft.Checkbox(label_position="left") + assert isinstance(r.label_position, str) + assert isinstance(r._get_attr("labelPosition"), str) + cmd = r._build_add_commands() + assert cmd[0].attrs["labelposition"] == "left" + + +def test_label_position_wrong_str_raises_beartype(): + with pytest.raises(beartype.roar.BeartypeCallHintParamViolation): + r = ft.Checkbox(label_position="center1") + + +def test_label_position_wrong_type_raises_beartype(): + with pytest.raises(beartype.roar.BeartypeCallHintParamViolation): + r = ft.Checkbox(label_position=1) diff --git a/sdk/python/tests/test_column.py b/sdk/python/tests/test_column.py new file mode 100644 index 000000000..c9039bb5e --- /dev/null +++ b/sdk/python/tests/test_column.py @@ -0,0 +1,100 @@ +import beartype.roar +import pytest + +import flet as ft +from flet.protocol import Command + + +def test_instance_no_attrs_set(): + r = ft.Column() + assert isinstance(r, ft.Control) + assert r._build_add_commands() == [ + Command( + indent=0, + name=None, + values=["column"], + attrs={}, + commands=[], + ) + ], "Test failed" + + +def test_alignment_enum(): + r = ft.Column(alignment=ft.MainAxisAlignment.SPACE_AROUND) + assert isinstance(r.alignment, ft.MainAxisAlignment) + assert isinstance(r._get_attr("alignment"), str) + cmd = r._build_add_commands() + assert cmd[0].attrs["alignment"] == "spaceAround" + + +def test_alignment_str(): + r = ft.Column(alignment="center") + assert isinstance(r.alignment, str) + assert isinstance(r._get_attr("alignment"), str) + cmd = r._build_add_commands() + assert cmd[0].attrs["alignment"] == "center" + + +def test_alignment_wrong_str_raises_beartype(): + with pytest.raises(beartype.roar.BeartypeCallHintParamViolation): + r = ft.Column(alignment="center1") + + +def test_alignment_wrong_type_raises_beartype(): + with pytest.raises(beartype.roar.BeartypeCallHintParamViolation): + r = ft.Column(alignment=1) + + +def test_horizontal_alignment_enum(): + r = ft.Column(horizontal_alignment=ft.CrossAxisAlignment.STRETCH) + assert isinstance(r.horizontal_alignment, ft.CrossAxisAlignment) + assert isinstance(r._get_attr("horizontalAlignment"), str) + cmd = r._build_add_commands() + assert cmd[0].attrs["horizontalalignment"] == "stretch" + + +def test_horizontal_alignment_str(): + r = ft.Column(horizontal_alignment="center") + assert isinstance(r.horizontal_alignment, str) + assert isinstance(r._get_attr("horizontalAlignment"), str) + cmd = r._build_add_commands() + assert cmd[0].attrs["horizontalalignment"] == "center" + + +def test_horizontal_alignment_wrong_str_raises_beartype(): + with pytest.raises(beartype.roar.BeartypeCallHintParamViolation): + r = ft.Column(horizontal_alignment="center1") + + +def test_horizontal_alignment_wrong_type_raises_beartype(): + with pytest.raises(beartype.roar.BeartypeCallHintParamViolation): + r = ft.Column(horizontal_alignment=1) + + +def test_scroll_enum(): + r = ft.Column() + assert r.scroll is None + assert r._get_attr("scroll") is None + + r = ft.Column(scroll=ft.ScrollMode.ALWAYS) + assert isinstance(r.scroll, ft.ScrollMode) + assert r.scroll == ft.ScrollMode.ALWAYS + assert r._get_attr("scroll") == "always" + + r = ft.Column(scroll="adaptive") + assert isinstance(r.scroll, str) + assert r._get_attr("scroll") == "adaptive" + + r = ft.Column(scroll=True) + assert isinstance(r.scroll, bool) + assert r._get_attr("scroll") == "auto" + + r = ft.Column(scroll=False) + assert isinstance(r.scroll, bool) + assert r._get_attr("scroll") is None + + with pytest.raises(beartype.roar.BeartypeCallHintParamViolation): + r = ft.Column(scroll="something") + + with pytest.raises(beartype.roar.BeartypeCallHintParamViolation): + r = ft.Column(scroll=1) diff --git a/sdk/python/tests/test_container.py b/sdk/python/tests/test_container.py new file mode 100644 index 000000000..f390667b5 --- /dev/null +++ b/sdk/python/tests/test_container.py @@ -0,0 +1,145 @@ +import beartype.roar +import pytest + +import flet as ft +from flet.protocol import Command + + +def test_instance_no_attrs_set(): + r = ft.Container() + assert isinstance(r, ft.Control) + assert r._build_add_commands() == [ + Command( + indent=0, + name=None, + values=["container"], + attrs={}, + commands=[], + ) + ], "Test failed" + + +def test_gradient(): + c = ft.Container( + gradient=ft.LinearGradient( + colors=[], + tile_mode="mirror", + ) + ) + cmd = c._build_add_commands() + assert ( + cmd[0].attrs["gradient"] + == '{"colors":[],"tile_mode":"mirror","begin":{"x":-1,"y":0},"end":{"x":1,"y":0},"type":"linear"}' + ) + + c = ft.Container( + gradient=ft.LinearGradient( + colors=[], + tile_mode=ft.GradientTileMode.REPEATED, + ) + ) + cmd = c._build_add_commands() + assert ( + cmd[0].attrs["gradient"] + == '{"colors":[],"tile_mode":"repeated","begin":{"x":-1,"y":0},"end":{"x":1,"y":0},"type":"linear"}' + ) + + c = ft.Container( + gradient=ft.LinearGradient( + colors=[], + ) + ) + cmd = c._build_add_commands() + assert ( + cmd[0].attrs["gradient"] + == '{"colors":[],"tile_mode":"clamp","begin":{"x":-1,"y":0},"end":{"x":1,"y":0},"type":"linear"}' + ) + + +def test_blend_mode_enum(): + r = ft.Container(blend_mode=ft.BlendMode.LIGHTEN) + assert isinstance(r.blend_mode, ft.BlendMode) + assert isinstance(r._get_attr("blendMode"), str) + cmd = r._build_add_commands() + assert cmd[0].attrs["blendmode"] == "lighten" + + +def test_blend_mode_str(): + r = ft.Container(blend_mode="darken") + assert isinstance(r.blend_mode, str) + assert isinstance(r._get_attr("blendMode"), str) + cmd = r._build_add_commands() + assert cmd[0].attrs["blendmode"] == "darken" + + +def test_blend_mode_wrong_str_raises_beartype(): + with pytest.raises(beartype.roar.BeartypeCallHintParamViolation): + r = ft.Container(blend_mode="center1") + + +def test_blend_mode_wrong_type_raises_beartype(): + with pytest.raises(beartype.roar.BeartypeCallHintParamViolation): + r = ft.Container(blend_mode=1) + + +def test_clip_behavior_enum(): + r = ft.Container() + assert r.clip_behavior is None + assert r._get_attr("clipBehavior") is None + + r = ft.Container(clip_behavior=ft.ClipBehavior.ANTI_ALIAS) + assert isinstance(r.clip_behavior, ft.ClipBehavior) + assert r.clip_behavior == ft.ClipBehavior.ANTI_ALIAS + assert r._get_attr("clipBehavior") == "antiAlias" + + r = ft.Container(clip_behavior="none") + assert isinstance(r.clip_behavior, str) + assert r._get_attr("clipBehavior") == "none" + + with pytest.raises(beartype.roar.BeartypeCallHintParamViolation): + r = ft.Container(clip_behavior="something") + + with pytest.raises(beartype.roar.BeartypeCallHintParamViolation): + r = ft.Container(clip_behavior=1) + + +def test_image_repeat_enum(): + r = ft.Container() + assert r.image_repeat is None + assert r._get_attr("imageRepeat") is None + + r = ft.Container(image_repeat=ft.ImageRepeat.REPEAT) + assert isinstance(r.image_repeat, ft.ImageRepeat) + assert r.image_repeat == ft.ImageRepeat.REPEAT + assert r._get_attr("imageRepeat") == "repeat" + + r = ft.Container(image_repeat="repeatX") + assert isinstance(r.image_repeat, str) + assert r._get_attr("imageRepeat") == "repeatX" + + with pytest.raises(beartype.roar.BeartypeCallHintParamViolation): + r = ft.Container(image_repeat="something") + + with pytest.raises(beartype.roar.BeartypeCallHintParamViolation): + r = ft.Container(image_repeat=1) + + +def test_image_fit_enum(): + r = ft.Container() + assert r.image_fit is None + assert r._get_attr("imageFit") is None + + r = ft.Container(image_fit=ft.ImageFit.FILL) + assert isinstance(r.image_fit, ft.ImageFit) + assert r.image_fit == ft.ImageFit.FILL + assert r._get_attr("imageFit") == "fill" + + r = ft.Container(image_fit="none") + assert isinstance(r.image_fit, str) + assert r._get_attr("imageFit") == "none" + + with pytest.raises(beartype.roar.BeartypeCallHintParamViolation): + r = ft.Container(image_fit="something") + + with pytest.raises(beartype.roar.BeartypeCallHintParamViolation): + r = ft.Container(image_fit=1) diff --git a/sdk/python/tests/test_datatable.py b/sdk/python/tests/test_datatable.py new file mode 100644 index 000000000..3b7b07d80 --- /dev/null +++ b/sdk/python/tests/test_datatable.py @@ -0,0 +1,81 @@ +import beartype.roar +import pytest + +import flet as ft +from flet.protocol import Command + + +def test_datatable_instance_no_attrs_set(): + r = ft.DataTable() + assert isinstance(r, ft.Control) + assert r._build_add_commands() == [ + Command( + indent=0, + name=None, + values=["datatable"], + attrs={}, + commands=[], + ) + ], "Test failed" + + +def test_datarow_instance_no_attrs_set(): + r = ft.DataRow() + assert isinstance(r, ft.Control) + assert r._build_add_commands() == [ + Command( + indent=0, + name=None, + values=["r"], + attrs={}, + commands=[], + ) + ], "Test failed" + + +def test_datarow_color_literal_material_state_as_string(): + r = ft.DataRow(color="yellow") + assert isinstance(r, ft.Control) + assert r._build_add_commands() == [ + Command( + indent=0, + name=None, + values=["r"], + attrs={"color": '{"":"yellow"}'}, + commands=[], + ) + ], "Test failed" + + +def test_datarow_color_multiple_material_states_as_strings(): + r = ft.DataRow(color={"selected": "red", "hovered": "blue", "": "yellow"}) + assert isinstance(r, ft.Control) + assert r._build_add_commands() == [ + Command( + indent=0, + name=None, + values=["r"], + attrs={"color": '{"selected":"red","hovered":"blue","":"yellow"}'}, + commands=[], + ) + ], "Test failed" + + +def test_datarow_color_multiple_material_states(): + r = ft.DataRow( + color={ + ft.MaterialState.SELECTED: "red", + ft.MaterialState.HOVERED: "blue", + ft.MaterialState.DEFAULT: "yellow", + } + ) + assert isinstance(r, ft.Control) + assert r._build_add_commands() == [ + Command( + indent=0, + name=None, + values=["r"], + attrs={"color": '{"selected":"red","hovered":"blue","":"yellow"}'}, + commands=[], + ) + ], "Test failed" diff --git a/sdk/python/tests/test_dropdown.py b/sdk/python/tests/test_dropdown.py new file mode 100644 index 000000000..047a3c92e --- /dev/null +++ b/sdk/python/tests/test_dropdown.py @@ -0,0 +1,40 @@ +import beartype.roar +import pytest + +import flet as ft +from flet.protocol import Command + + +def test_instance_no_attrs_set(): + r = ft.Dropdown() + assert isinstance(r, ft.Control) + assert r._build_add_commands() == [ + Command( + indent=0, + name=None, + values=["dropdown"], + attrs={}, + commands=[], + ) + ], "Test failed" + + +def test_border_enum(): + r = ft.Dropdown() + assert r.border is None + assert r._get_attr("border") is None + + r = ft.Dropdown(border=ft.InputBorder.OUTLINE) + assert isinstance(r.border, ft.InputBorder) + assert r.border == ft.InputBorder.OUTLINE + assert r._get_attr("border") == "outline" + + r = ft.Dropdown(border="none") + assert isinstance(r.border, str) + assert r._get_attr("border") == "none" + + with pytest.raises(beartype.roar.BeartypeCallHintParamViolation): + r = ft.Dropdown(border="something") + + with pytest.raises(beartype.roar.BeartypeCallHintParamViolation): + r = ft.Dropdown(border=1) diff --git a/sdk/python/tests/test_file_picker.py b/sdk/python/tests/test_file_picker.py new file mode 100644 index 000000000..718330ea0 --- /dev/null +++ b/sdk/python/tests/test_file_picker.py @@ -0,0 +1,40 @@ +import beartype.roar +import pytest + +import flet as ft +from flet.protocol import Command + + +def test_instance_no_attrs_set(): + r = ft.FilePicker() + assert isinstance(r, ft.Control) + assert r._build_add_commands() == [ + Command( + indent=0, + name=None, + values=["filepicker"], + attrs={"upload": "[]"}, + commands=[], + ) + ], "Test failed" + + +def test_file_type_enum(): + r = ft.FilePicker() + r.file_type = ft.FilePickerFileType.VIDEO + assert isinstance(r.file_type, ft.FilePickerFileType) + assert r.file_type == ft.FilePickerFileType.VIDEO + assert r._get_attr("fileType") == "video" + + r = ft.FilePicker() + r.file_type = "any" + assert isinstance(r.file_type, str) + assert r._get_attr("fileType") == "any" + + with pytest.raises(beartype.roar.BeartypeCallHintParamViolation): + r = ft.FilePicker() + r.file_type = "something" + + with pytest.raises(beartype.roar.BeartypeCallHintParamViolation): + r = ft.FilePicker() + r.file_type = 1 diff --git a/sdk/python/tests/test_image.py b/sdk/python/tests/test_image.py index 6862b27db..11e844770 100644 --- a/sdk/python/tests/test_image.py +++ b/sdk/python/tests/test_image.py @@ -1,14 +1,16 @@ -import flet -from flet import Image +import beartype.roar +import pytest + +import flet as ft from flet.protocol import Command def test_image_add(): - i = Image( + i = ft.Image( src="https://www.w3schools.com/css/img_5terre.jpg", ) - assert isinstance(i, flet.Control) - assert isinstance(i, flet.Image) + assert isinstance(i, ft.Control) + assert isinstance(i, ft.Image) assert i._build_add_commands() == [ Command( indent=0, @@ -20,3 +22,71 @@ def test_image_add(): commands=[], ) ], "Test failed" + + +def test_color_blend_mode_enum(): + r = ft.Image(color_blend_mode=ft.BlendMode.LIGHTEN) + assert isinstance(r.color_blend_mode, ft.BlendMode) + assert isinstance(r._get_attr("colorBlendMode"), str) + cmd = r._build_add_commands() + assert cmd[0].attrs["colorblendmode"] == "lighten" + + +def test_color_blend_mode_str(): + r = ft.Image(color_blend_mode="darken") + assert isinstance(r.color_blend_mode, str) + assert isinstance(r._get_attr("colorBlendMode"), str) + cmd = r._build_add_commands() + assert cmd[0].attrs["colorblendmode"] == "darken" + + +def test_color_blend_mode_wrong_str_raises_beartype(): + with pytest.raises(beartype.roar.BeartypeCallHintParamViolation): + r = ft.Image(color_blend_mode="center1") + + +def test_color_blend_mode_wrong_type_raises_beartype(): + with pytest.raises(beartype.roar.BeartypeCallHintParamViolation): + r = ft.Image(color_blend_mode=1) + + +def test_repeat_enum(): + r = ft.Image() + assert r.repeat is None + assert r._get_attr("repeat") is None + + r = ft.Image(repeat=ft.ImageRepeat.REPEAT) + assert isinstance(r.repeat, ft.ImageRepeat) + assert r.repeat == ft.ImageRepeat.REPEAT + assert r._get_attr("repeat") == "repeat" + + r = ft.Image(repeat="repeatX") + assert isinstance(r.repeat, str) + assert r._get_attr("repeat") == "repeatX" + + with pytest.raises(beartype.roar.BeartypeCallHintParamViolation): + r = ft.Image(repeat="something") + + with pytest.raises(beartype.roar.BeartypeCallHintParamViolation): + r = ft.Image(repeat=1) + + +def test_fit_enum(): + r = ft.Image() + assert r.fit is None + assert r._get_attr("fit") is None + + r = ft.Image(fit=ft.ImageFit.FILL) + assert isinstance(r.fit, ft.ImageFit) + assert r.fit == ft.ImageFit.FILL + assert r._get_attr("fit") == "fill" + + r = ft.Image(fit="none") + assert isinstance(r.fit, str) + assert r._get_attr("fit") == "none" + + with pytest.raises(beartype.roar.BeartypeCallHintParamViolation): + r = ft.Image(fit="something") + + with pytest.raises(beartype.roar.BeartypeCallHintParamViolation): + r = ft.Image(fit=1) diff --git a/sdk/python/tests/test_markdown.py b/sdk/python/tests/test_markdown.py new file mode 100644 index 000000000..a5cc8ee5f --- /dev/null +++ b/sdk/python/tests/test_markdown.py @@ -0,0 +1,40 @@ +import beartype.roar +import pytest + +import flet as ft +from flet.protocol import Command + + +def test_instance_no_attrs_set(): + r = ft.Markdown() + assert isinstance(r, ft.Control) + assert r._build_add_commands() == [ + Command( + indent=0, + name=None, + values=["markdown"], + attrs={}, + commands=[], + ) + ], "Test failed" + + +def test_extension_set_enum(): + r = ft.Markdown() + assert r.extension_set is None + assert r._get_attr("extensionSet") is None + + r = ft.Markdown(extension_set=ft.MarkdownExtensionSet.COMMON_MARK) + assert isinstance(r.extension_set, ft.MarkdownExtensionSet) + assert r.extension_set == ft.MarkdownExtensionSet.COMMON_MARK + assert r._get_attr("extensionSet") == "commonMark" + + r = ft.Markdown(extension_set="none") + assert isinstance(r.extension_set, str) + assert r._get_attr("extensionSet") == "none" + + with pytest.raises(beartype.roar.BeartypeCallHintParamViolation): + r = ft.Markdown(extension_set="something") + + with pytest.raises(beartype.roar.BeartypeCallHintParamViolation): + r = ft.Markdown(extension_set=1) diff --git a/sdk/python/tests/test_navigation_bar.py b/sdk/python/tests/test_navigation_bar.py new file mode 100644 index 000000000..28f30006d --- /dev/null +++ b/sdk/python/tests/test_navigation_bar.py @@ -0,0 +1,40 @@ +import beartype.roar +import pytest + +import flet as ft +from flet.protocol import Command + + +def test_instance_no_attrs_set(): + r = ft.NavigationBar() + assert isinstance(r, ft.Control) + assert r._build_add_commands() == [ + Command( + indent=0, + name=None, + values=["navigationbar"], + attrs={}, + commands=[], + ) + ], "Test failed" + + +def test_extension_set_enum(): + r = ft.NavigationBar() + assert r.label_behavior is None + assert r._get_attr("labelType") is None + + r = ft.NavigationBar(label_behavior=ft.NavigationBarLabelBehavior.ALWAYS_SHOW) + assert isinstance(r.label_behavior, ft.NavigationBarLabelBehavior) + assert r.label_behavior == ft.NavigationBarLabelBehavior.ALWAYS_SHOW + assert r._get_attr("labelType") == "alwaysShow" + + r = ft.NavigationBar(label_behavior="alwaysHide") + assert isinstance(r.label_behavior, str) + assert r._get_attr("labelType") == "alwaysHide" + + with pytest.raises(beartype.roar.BeartypeCallHintParamViolation): + r = ft.NavigationBar(label_behavior="something") + + with pytest.raises(beartype.roar.BeartypeCallHintParamViolation): + r = ft.NavigationBar(label_behavior=1) diff --git a/sdk/python/tests/test_navigation_rail.py b/sdk/python/tests/test_navigation_rail.py new file mode 100644 index 000000000..c3df24e5d --- /dev/null +++ b/sdk/python/tests/test_navigation_rail.py @@ -0,0 +1,40 @@ +import beartype.roar +import pytest + +import flet as ft +from flet.protocol import Command + + +def test_instance_no_attrs_set(): + r = ft.NavigationRail() + assert isinstance(r, ft.Control) + assert r._build_add_commands() == [ + Command( + indent=0, + name=None, + values=["navigationrail"], + attrs={}, + commands=[], + ) + ], "Test failed" + + +def test_extension_set_enum(): + r = ft.NavigationRail() + assert r.label_type is None + assert r._get_attr("labelType") is None + + r = ft.NavigationRail(label_type=ft.NavigationRailLabelType.SELECTED) + assert isinstance(r.label_type, ft.NavigationRailLabelType) + assert r.label_type == ft.NavigationRailLabelType.SELECTED + assert r._get_attr("labelType") == "selected" + + r = ft.NavigationRail(label_type="none") + assert isinstance(r.label_type, str) + assert r._get_attr("labelType") == "none" + + with pytest.raises(beartype.roar.BeartypeCallHintParamViolation): + r = ft.NavigationRail(label_type="something") + + with pytest.raises(beartype.roar.BeartypeCallHintParamViolation): + r = ft.NavigationRail(label_type=1) diff --git a/sdk/python/tests/test_page.py b/sdk/python/tests/test_page.py index 52e9adca9..1bedcaddf 100644 --- a/sdk/python/tests/test_page.py +++ b/sdk/python/tests/test_page.py @@ -1,5 +1,9 @@ +import beartype.roar import pytest +import flet as ft +from flet.protocol import Command + @pytest.mark.skip(reason="no way of currently testing this") def test_page(page): diff --git a/sdk/python/tests/test_radio.py b/sdk/python/tests/test_radio.py new file mode 100644 index 000000000..369bcd7c5 --- /dev/null +++ b/sdk/python/tests/test_radio.py @@ -0,0 +1,45 @@ +import beartype.roar +import pytest + +import flet as ft +from flet.protocol import Command + + +def test_instance_no_attrs_set(): + r = ft.Radio() + assert isinstance(r, ft.Control) + assert r._build_add_commands() == [ + Command( + indent=0, + name=None, + values=["radio"], + attrs={}, + commands=[], + ) + ], "Test failed" + + +def test_label_position_enum(): + r = ft.Radio(label_position=ft.LabelPosition.LEFT) + assert isinstance(r.label_position, ft.LabelPosition) + assert isinstance(r._get_attr("labelPosition"), str) + cmd = r._build_add_commands() + assert cmd[0].attrs["labelposition"] == "left" + + +def test_label_position_str(): + r = ft.Radio(label_position="left") + assert isinstance(r.label_position, str) + assert isinstance(r._get_attr("labelPosition"), str) + cmd = r._build_add_commands() + assert cmd[0].attrs["labelposition"] == "left" + + +def test_label_position_wrong_str_raises_beartype(): + with pytest.raises(beartype.roar.BeartypeCallHintParamViolation): + r = ft.Radio(label_position="center1") + + +def test_label_position_wrong_type_raises_beartype(): + with pytest.raises(beartype.roar.BeartypeCallHintParamViolation): + r = ft.Radio(label_position=1) diff --git a/sdk/python/tests/test_responsive_row.py b/sdk/python/tests/test_responsive_row.py new file mode 100644 index 000000000..6743e6dc7 --- /dev/null +++ b/sdk/python/tests/test_responsive_row.py @@ -0,0 +1,71 @@ +import beartype.roar +import pytest + +import flet as ft +from flet.protocol import Command + + +def test_instance_no_attrs_set(): + r = ft.ResponsiveRow() + assert isinstance(r, ft.Control) + assert r._build_add_commands() == [ + Command( + indent=0, + name=None, + values=["responsiverow"], + attrs={}, + commands=[], + ) + ], "Test failed" + + +def test_alignment_enum(): + r = ft.ResponsiveRow(alignment=ft.MainAxisAlignment.SPACE_AROUND) + assert isinstance(r.alignment, ft.MainAxisAlignment) + assert isinstance(r._get_attr("alignment"), str) + cmd = r._build_add_commands() + assert cmd[0].attrs["alignment"] == "spaceAround" + + +def test_alignment_str(): + r = ft.ResponsiveRow(alignment="center") + assert isinstance(r.alignment, str) + assert isinstance(r._get_attr("alignment"), str) + cmd = r._build_add_commands() + assert cmd[0].attrs["alignment"] == "center" + + +def test_alignment_wrong_str_raises_beartype(): + with pytest.raises(beartype.roar.BeartypeCallHintParamViolation): + r = ft.ResponsiveRow(alignment="center1") + + +def test_alignment_wrong_type_raises_beartype(): + with pytest.raises(beartype.roar.BeartypeCallHintParamViolation): + r = ft.ResponsiveRow(alignment=1) + + +def test_vertical_alignment_enum(): + r = ft.ResponsiveRow(vertical_alignment=ft.CrossAxisAlignment.STRETCH) + assert isinstance(r.vertical_alignment, ft.CrossAxisAlignment) + assert isinstance(r._get_attr("verticalAlignment"), str) + cmd = r._build_add_commands() + assert cmd[0].attrs["verticalalignment"] == "stretch" + + +def test_vertical_alignment_str(): + r = ft.ResponsiveRow(vertical_alignment="center") + assert isinstance(r.vertical_alignment, str) + assert isinstance(r._get_attr("verticalAlignment"), str) + cmd = r._build_add_commands() + assert cmd[0].attrs["verticalalignment"] == "center" + + +def test_vertical_alignment_wrong_str_raises_beartype(): + with pytest.raises(beartype.roar.BeartypeCallHintParamViolation): + r = ft.ResponsiveRow(vertical_alignment="center1") + + +def test_vertical_alignment_wrong_type_raises_beartype(): + with pytest.raises(beartype.roar.BeartypeCallHintParamViolation): + r = ft.ResponsiveRow(vertical_alignment=1) diff --git a/sdk/python/tests/test_row.py b/sdk/python/tests/test_row.py new file mode 100644 index 000000000..6a1317a9f --- /dev/null +++ b/sdk/python/tests/test_row.py @@ -0,0 +1,100 @@ +import beartype.roar +import pytest + +import flet as ft +from flet.protocol import Command + + +def test_instance_no_attrs_set(): + r = ft.Row() + assert isinstance(r, ft.Control) + assert r._build_add_commands() == [ + Command( + indent=0, + name=None, + values=["row"], + attrs={}, + commands=[], + ) + ], "Test failed" + + +def test_alignment_enum(): + r = ft.Row(alignment=ft.MainAxisAlignment.SPACE_AROUND) + assert isinstance(r.alignment, ft.MainAxisAlignment) + assert isinstance(r._get_attr("alignment"), str) + cmd = r._build_add_commands() + assert cmd[0].attrs["alignment"] == "spaceAround" + + +def test_alignment_str(): + r = ft.Row(alignment="center") + assert isinstance(r.alignment, str) + assert isinstance(r._get_attr("alignment"), str) + cmd = r._build_add_commands() + assert cmd[0].attrs["alignment"] == "center" + + +def test_alignment_wrong_str_raises_beartype(): + with pytest.raises(beartype.roar.BeartypeCallHintParamViolation): + r = ft.Row(alignment="center1") + + +def test_alignment_wrong_type_raises_beartype(): + with pytest.raises(beartype.roar.BeartypeCallHintParamViolation): + r = ft.Row(alignment=1) + + +def test_vertical_alignment_enum(): + r = ft.Row(vertical_alignment=ft.CrossAxisAlignment.STRETCH) + assert isinstance(r.vertical_alignment, ft.CrossAxisAlignment) + assert isinstance(r._get_attr("verticalAlignment"), str) + cmd = r._build_add_commands() + assert cmd[0].attrs["verticalalignment"] == "stretch" + + +def test_vertical_alignment_str(): + r = ft.Row(vertical_alignment="center") + assert isinstance(r.vertical_alignment, str) + assert isinstance(r._get_attr("verticalAlignment"), str) + cmd = r._build_add_commands() + assert cmd[0].attrs["verticalalignment"] == "center" + + +def test_vertical_alignment_wrong_str_raises_beartype(): + with pytest.raises(beartype.roar.BeartypeCallHintParamViolation): + r = ft.Row(vertical_alignment="center1") + + +def test_vertical_alignment_wrong_type_raises_beartype(): + with pytest.raises(beartype.roar.BeartypeCallHintParamViolation): + r = ft.Row(vertical_alignment=1) + + +def test_scroll_enum(): + r = ft.Row() + assert r.scroll is None + assert r._get_attr("scroll") is None + + r = ft.Row(scroll=ft.ScrollMode.ALWAYS) + assert isinstance(r.scroll, ft.ScrollMode) + assert r.scroll == ft.ScrollMode.ALWAYS + assert r._get_attr("scroll") == "always" + + r = ft.Row(scroll="adaptive") + assert isinstance(r.scroll, str) + assert r._get_attr("scroll") == "adaptive" + + r = ft.Row(scroll=True) + assert isinstance(r.scroll, bool) + assert r._get_attr("scroll") == "auto" + + r = ft.Row(scroll=False) + assert isinstance(r.scroll, bool) + assert r._get_attr("scroll") is None + + with pytest.raises(beartype.roar.BeartypeCallHintParamViolation): + r = ft.Row(scroll="something") + + with pytest.raises(beartype.roar.BeartypeCallHintParamViolation): + r = ft.Row(scroll=1) diff --git a/sdk/python/tests/test_shader_mask.py b/sdk/python/tests/test_shader_mask.py new file mode 100644 index 000000000..a4c2395ce --- /dev/null +++ b/sdk/python/tests/test_shader_mask.py @@ -0,0 +1,45 @@ +import beartype.roar +import pytest + +import flet as ft +from flet.protocol import Command + + +def test_instance_no_attrs_set(): + r = ft.ShaderMask() + assert isinstance(r, ft.Control) + assert r._build_add_commands() == [ + Command( + indent=0, + name=None, + values=["shadermask"], + attrs={}, + commands=[], + ) + ], "Test failed" + + +def test_blend_mode_enum(): + r = ft.ShaderMask(blend_mode=ft.BlendMode.LIGHTEN) + assert isinstance(r.blend_mode, ft.BlendMode) + assert isinstance(r._get_attr("blendMode"), str) + cmd = r._build_add_commands() + assert cmd[0].attrs["blendmode"] == "lighten" + + +def test_blend_mode_str(): + r = ft.ShaderMask(blend_mode="darken") + assert isinstance(r.blend_mode, str) + assert isinstance(r._get_attr("blendMode"), str) + cmd = r._build_add_commands() + assert cmd[0].attrs["blendmode"] == "darken" + + +def test_blend_mode_wrong_str_raises_beartype(): + with pytest.raises(beartype.roar.BeartypeCallHintParamViolation): + r = ft.ShaderMask(blend_mode="center1") + + +def test_blend_mode_wrong_type_raises_beartype(): + with pytest.raises(beartype.roar.BeartypeCallHintParamViolation): + r = ft.ShaderMask(blend_mode=1) diff --git a/sdk/python/tests/test_stack.py b/sdk/python/tests/test_stack.py new file mode 100644 index 000000000..f9bf63247 --- /dev/null +++ b/sdk/python/tests/test_stack.py @@ -0,0 +1,40 @@ +import beartype.roar +import pytest + +import flet as ft +from flet.protocol import Command + + +def test_instance_no_attrs_set(): + r = ft.Stack() + assert isinstance(r, ft.Control) + assert r._build_add_commands() == [ + Command( + indent=0, + name=None, + values=["stack"], + attrs={}, + commands=[], + ) + ], "Test failed" + + +def test_clip_behavior_enum(): + r = ft.Stack() + assert r.clip_behavior is None + assert r._get_attr("clipBehavior") is None + + r = ft.Stack(clip_behavior=ft.ClipBehavior.ANTI_ALIAS) + assert isinstance(r.clip_behavior, ft.ClipBehavior) + assert r.clip_behavior == ft.ClipBehavior.ANTI_ALIAS + assert r._get_attr("clipBehavior") == "antiAlias" + + r = ft.Stack(clip_behavior="none") + assert isinstance(r.clip_behavior, str) + assert r._get_attr("clipBehavior") == "none" + + with pytest.raises(beartype.roar.BeartypeCallHintParamViolation): + r = ft.Stack(clip_behavior="something") + + with pytest.raises(beartype.roar.BeartypeCallHintParamViolation): + r = ft.Stack(clip_behavior=1) diff --git a/sdk/python/tests/test_switch.py b/sdk/python/tests/test_switch.py new file mode 100644 index 000000000..d70aa58a1 --- /dev/null +++ b/sdk/python/tests/test_switch.py @@ -0,0 +1,45 @@ +import beartype.roar +import pytest + +import flet as ft +from flet.protocol import Command + + +def test_instance_no_attrs_set(): + r = ft.Switch() + assert isinstance(r, ft.Control) + assert r._build_add_commands() == [ + Command( + indent=0, + name=None, + values=["switch"], + attrs={}, + commands=[], + ) + ], "Test failed" + + +def test_label_position_enum(): + r = ft.Switch(label_position=ft.LabelPosition.LEFT) + assert isinstance(r.label_position, ft.LabelPosition) + assert isinstance(r._get_attr("labelPosition"), str) + cmd = r._build_add_commands() + assert cmd[0].attrs["labelposition"] == "left" + + +def test_label_position_str(): + r = ft.Switch(label_position="left") + assert isinstance(r.label_position, str) + assert isinstance(r._get_attr("labelPosition"), str) + cmd = r._build_add_commands() + assert cmd[0].attrs["labelposition"] == "left" + + +def test_label_position_wrong_str_raises_beartype(): + with pytest.raises(beartype.roar.BeartypeCallHintParamViolation): + r = ft.Switch(label_position="center1") + + +def test_label_position_wrong_type_raises_beartype(): + with pytest.raises(beartype.roar.BeartypeCallHintParamViolation): + r = ft.Switch(label_position=1) diff --git a/sdk/python/tests/test_text.py b/sdk/python/tests/test_text.py new file mode 100644 index 000000000..5f9c9464a --- /dev/null +++ b/sdk/python/tests/test_text.py @@ -0,0 +1,103 @@ +import beartype.roar +import pytest + +import flet as ft +from flet.protocol import Command + + +def test_instance_no_attrs_set(): + r = ft.Text() + assert isinstance(r, ft.Control) + assert r._build_add_commands() == [ + Command( + indent=0, + name=None, + values=["text"], + attrs={}, + commands=[], + ) + ], "Test failed" + + +def test_text_align_enum(): + r = ft.Text() + assert r.text_align == ft.TextAlign.NONE + assert r._get_attr("textAlign") is None + + r = ft.Text(text_align=ft.TextAlign.RIGHT) + assert isinstance(r.text_align, ft.TextAlign) + assert r.text_align == ft.TextAlign.RIGHT + assert r._get_attr("textAlign") == "right" + + r = ft.Text(text_align="left") + assert isinstance(r.text_align, str) + assert r._get_attr("textAlign") == "left" + + with pytest.raises(beartype.roar.BeartypeCallHintParamViolation): + r = ft.Text(text_align="something") + + with pytest.raises(beartype.roar.BeartypeCallHintParamViolation): + r = ft.Text(text_align=1) + + +def test_text_style_enum(): + r = ft.Text() + assert r.style == None + assert r._get_attr("style") is None + + r = ft.Text(style=ft.TextThemeStyle.DISPLAY_LARGE) + assert isinstance(r.style, ft.TextThemeStyle) + assert r.style == ft.TextThemeStyle.DISPLAY_LARGE + assert r._get_attr("style") == "displayLarge" + + r = ft.Text(style="bodyMedium") + assert isinstance(r.style, str) + assert r._get_attr("style") == "bodyMedium" + + with pytest.raises(beartype.roar.BeartypeCallHintParamViolation): + r = ft.Text(style="something") + + with pytest.raises(beartype.roar.BeartypeCallHintParamViolation): + r = ft.Text(style=1) + + +def test_text_overflow_enum(): + r = ft.Text() + assert r.overflow == ft.TextOverflow.NONE + assert r._get_attr("overflow") is None + + r = ft.Text(overflow=ft.TextOverflow.ELLIPSIS) + assert isinstance(r.overflow, ft.TextOverflow) + assert r.overflow == ft.TextOverflow.ELLIPSIS + assert r._get_attr("overflow") == "ellipsis" + + r = ft.Text(overflow="fade") + assert isinstance(r.overflow, str) + assert r._get_attr("overflow") == "fade" + + with pytest.raises(beartype.roar.BeartypeCallHintParamViolation): + r = ft.Text(overflow="something") + + with pytest.raises(beartype.roar.BeartypeCallHintParamViolation): + r = ft.Text(overflow=1) + + +def test_weight_enum(): + r = ft.Text() + assert r.weight == None + assert r._get_attr("weight") is None + + r = ft.Text(weight=ft.FontWeight.BOLD) + assert isinstance(r.weight, ft.FontWeight) + assert r.weight == ft.FontWeight.BOLD + assert r._get_attr("weight") == "bold" + + r = ft.Text(weight="w100") + assert isinstance(r.weight, str) + assert r._get_attr("weight") == "w100" + + with pytest.raises(beartype.roar.BeartypeCallHintParamViolation): + r = ft.Text(weight="something") + + with pytest.raises(beartype.roar.BeartypeCallHintParamViolation): + r = ft.Text(weight=1) diff --git a/sdk/python/tests/test_textfield.py b/sdk/python/tests/test_textfield.py new file mode 100644 index 000000000..7fe8ad2c3 --- /dev/null +++ b/sdk/python/tests/test_textfield.py @@ -0,0 +1,108 @@ +import beartype.roar +import pytest + +import flet as ft +from flet.protocol import Command + + +def test_instance_no_attrs_set(): + r = ft.TextField() + assert isinstance(r, ft.Control) + assert r._build_add_commands() == [ + Command( + indent=0, + name=None, + values=["textfield"], + attrs={}, + commands=[], + ) + ], "Test failed" + + +def test_text_align_enum(): + r = ft.TextField(text_align=ft.TextAlign.LEFT) + assert isinstance(r.text_align, ft.TextAlign) + assert isinstance(r._get_attr("textAlign"), str) + cmd = r._build_add_commands() + assert cmd[0].attrs["textalign"] == "left" + + +def test_text_align_str(): + r = ft.TextField(text_align="left") + assert isinstance(r.text_align, str) + assert isinstance(r._get_attr("textAlign"), str) + cmd = r._build_add_commands() + assert cmd[0].attrs["textalign"] == "left" + + +def test_text_align_wrong_str_raises_beartype(): + with pytest.raises(beartype.roar.BeartypeCallHintParamViolation): + r = ft.TextField(text_align="center1") + + +def test_text_align_wrong_type_raises_beartype(): + with pytest.raises(beartype.roar.BeartypeCallHintParamViolation): + r = ft.TextField(text_align=1) + + +def test_keyboard_type_enum(): + r = ft.TextField() + assert r.keyboard_type is None + assert r._get_attr("keyboardType") is None + + r = ft.TextField(keyboard_type=ft.KeyboardType.NONE) + assert isinstance(r.keyboard_type, ft.KeyboardType) + assert r.keyboard_type == ft.KeyboardType.NONE + assert r._get_attr("keyboardType") == "none" + + r = ft.TextField(keyboard_type="phone") + assert isinstance(r.keyboard_type, str) + assert r._get_attr("keyboardType") == "phone" + + with pytest.raises(beartype.roar.BeartypeCallHintParamViolation): + r = ft.TextField(keyboard_type="something") + + with pytest.raises(beartype.roar.BeartypeCallHintParamViolation): + r = ft.TextField(keyboard_type=1) + + +def test_capitalization_enum(): + r = ft.TextField() + assert r.capitalization == ft.TextCapitalization.NONE + assert r._get_attr("capitalization") is None + + r = ft.TextField(capitalization=ft.TextCapitalization.WORDS) + assert isinstance(r.capitalization, ft.TextCapitalization) + assert r.capitalization == ft.TextCapitalization.WORDS + assert r._get_attr("capitalization") == "words" + + r = ft.TextField(capitalization="sentences") + assert isinstance(r.capitalization, str) + assert r._get_attr("capitalization") == "sentences" + + with pytest.raises(beartype.roar.BeartypeCallHintParamViolation): + r = ft.TextField(capitalization="something") + + with pytest.raises(beartype.roar.BeartypeCallHintParamViolation): + r = ft.TextField(capitalization=1) + + +def test_border_enum(): + r = ft.TextField() + assert r.border is None + assert r._get_attr("border") is None + + r = ft.TextField(border=ft.InputBorder.OUTLINE) + assert isinstance(r.border, ft.InputBorder) + assert r.border == ft.InputBorder.OUTLINE + assert r._get_attr("border") == "outline" + + r = ft.TextField(border="none") + assert isinstance(r.border, str) + assert r._get_attr("border") == "none" + + with pytest.raises(beartype.roar.BeartypeCallHintParamViolation): + r = ft.TextField(border="something") + + with pytest.raises(beartype.roar.BeartypeCallHintParamViolation): + r = ft.TextField(border=1) diff --git a/sdk/python/tests/test_tooltip.py b/sdk/python/tests/test_tooltip.py new file mode 100644 index 000000000..52372d391 --- /dev/null +++ b/sdk/python/tests/test_tooltip.py @@ -0,0 +1,40 @@ +import beartype.roar +import pytest + +import flet as ft +from flet.protocol import Command + + +def test_instance_no_attrs_set(): + r = ft.Tooltip() + assert isinstance(r, ft.Control) + assert r._build_add_commands() == [ + Command( + indent=0, + name=None, + values=["tooltip"], + attrs={}, + commands=[], + ) + ], "Test failed" + + +def test_text_align_enum(): + r = ft.Tooltip() + assert r.text_align == ft.TextAlign.NONE + assert r._get_attr("textAlign") is None + + r = ft.Tooltip(text_align=ft.TextAlign.RIGHT) + assert isinstance(r.text_align, ft.TextAlign) + assert r.text_align == ft.TextAlign.RIGHT + assert r._get_attr("textAlign") == "right" + + r = ft.Tooltip(text_align="left") + assert isinstance(r.text_align, str) + assert r._get_attr("textAlign") == "left" + + with pytest.raises(beartype.roar.BeartypeCallHintParamViolation): + r = ft.Tooltip(text_align="something") + + with pytest.raises(beartype.roar.BeartypeCallHintParamViolation): + r = ft.Tooltip(text_align=1) diff --git a/sdk/python/tests/test_view.py b/sdk/python/tests/test_view.py new file mode 100644 index 000000000..0b1199cf0 --- /dev/null +++ b/sdk/python/tests/test_view.py @@ -0,0 +1,100 @@ +import beartype.roar +import pytest + +import flet as ft +from flet.protocol import Command + + +def test_instance_no_attrs_set(): + r = ft.View() + assert isinstance(r, ft.Control) + assert r._build_add_commands() == [ + Command( + indent=0, + name=None, + values=["view"], + attrs={}, + commands=[], + ) + ], "Test failed" + + +def test_horizontal_alignment_enum(): + r = ft.View(horizontal_alignment=ft.CrossAxisAlignment.STRETCH) + assert isinstance(r.horizontal_alignment, ft.CrossAxisAlignment) + assert isinstance(r._get_attr("horizontalAlignment"), str) + cmd = r._build_add_commands() + assert cmd[0].attrs["horizontalalignment"] == "stretch" + + +def test_horizontal_alignment_str(): + r = ft.View(horizontal_alignment="center") + assert isinstance(r.horizontal_alignment, str) + assert isinstance(r._get_attr("horizontalAlignment"), str) + cmd = r._build_add_commands() + assert cmd[0].attrs["horizontalalignment"] == "center" + + +def test_horizontal_alignment_wrong_str_raises_beartype(): + with pytest.raises(beartype.roar.BeartypeCallHintParamViolation): + r = ft.View(horizontal_alignment="center1") + + +def test_horizontal_alignment_wrong_type_raises_beartype(): + with pytest.raises(beartype.roar.BeartypeCallHintParamViolation): + r = ft.View(horizontal_alignment=1) + + +def test_vertical_alignment_enum(): + r = ft.View(vertical_alignment=ft.MainAxisAlignment.CENTER) + assert isinstance(r.vertical_alignment, ft.MainAxisAlignment) + assert isinstance(r._get_attr("verticalAlignment"), str) + cmd = r._build_add_commands() + assert cmd[0].attrs["verticalalignment"] == "center" + + +def test_vertical_alignment_str(): + r = ft.View(vertical_alignment="center") + assert isinstance(r.vertical_alignment, str) + assert isinstance(r._get_attr("verticalAlignment"), str) + cmd = r._build_add_commands() + assert cmd[0].attrs["verticalalignment"] == "center" + + +def test_vertical_alignment_wrong_str_raises_beartype(): + with pytest.raises(beartype.roar.BeartypeCallHintParamViolation): + r = ft.View(vertical_alignment="center1") + + +def test_vertical_alignment_wrong_type_raises_beartype(): + with pytest.raises(beartype.roar.BeartypeCallHintParamViolation): + r = ft.View(vertical_alignment=1) + + +def test_scroll_enum(): + r = ft.View() + assert r.scroll is None + assert r._get_attr("scroll") is None + + r = ft.View(scroll=ft.ScrollMode.ALWAYS) + assert isinstance(r.scroll, ft.ScrollMode) + assert r.scroll == ft.ScrollMode.ALWAYS + assert r._get_attr("scroll") == "always" + + r = ft.View(scroll="adaptive") + assert isinstance(r.scroll, str) + assert r._get_attr("scroll") == "adaptive" + + r = ft.View(scroll=True) + assert isinstance(r.scroll, bool) + assert r._get_attr("scroll") == "auto" + + r = ft.View(scroll=False) + assert isinstance(r.scroll, bool) + assert r._get_attr("scroll") is None + + with pytest.raises(beartype.roar.BeartypeCallHintParamViolation): + r = ft.View(scroll="something") + + with pytest.raises(beartype.roar.BeartypeCallHintParamViolation): + r = ft.View(scroll=1)