Skip to content

FletPopover

FletPopover

Bases: ConstrainedControl

A popover is a transient view that appears above other content onscreen when you tap a control or in an area.

Typically, a popover includes an arrow pointing to the location from which it emerged. Popovers can be nonmodal or modal. A nonmodal popover is dismissed by tapping another part of the screen or a button on the popover. A modal popover is dismissed by tapping a Cancel or other button on the popover.

This control wraps the Flutter popover package to provide popover functionality in Flet.

Source code in src\flet_popover\flet_popover.py
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
class FletPopover(ConstrainedControl):
    """
    A popover is a transient view that appears above other content onscreen when you tap a control or in an area.

    Typically, a popover includes an arrow pointing to the location from which it emerged.
    Popovers can be nonmodal or modal. A nonmodal popover is dismissed by tapping another part
    of the screen or a button on the popover. A modal popover is dismissed by tapping a Cancel
    or other button on the popover.

    This control wraps the Flutter popover package to provide popover functionality in Flet.
    """

    def __init__(
        self,
        #
        # ConstrainedControl
        #
        ref=None,
        key=None,
        width: OptionalNumber = None,
        height: OptionalNumber = None,
        left: OptionalNumber = None,
        top: OptionalNumber = None,
        right: OptionalNumber = None,
        bottom: OptionalNumber = None,
        expand: Union[None, bool, int] = None,
        expand_loose: Optional[bool] = None,
        col: Optional[dict] = None,
        opacity: OptionalNumber = None,
        rotate: Optional[dict] = None,
        scale: Optional[dict] = None,
        offset: Optional[dict] = None,
        aspect_ratio: OptionalNumber = None,
        animate_opacity: Optional[dict] = None,
        animate_size: Optional[dict] = None,
        animate_position: Optional[dict] = None,
        animate_rotation: Optional[dict] = None,
        animate_scale: Optional[dict] = None,
        animate_offset: Optional[dict] = None,
        on_animation_end=None,
        tooltip: Optional[str] = None,
        badge: Optional[dict] = None,
        visible: Optional[bool] = None,
        disabled: Optional[bool] = None,
        data: Any = None,
        rtl: Optional[bool] = None,
        #
        # FletPopover specific
        #
        body: Control = None,  # body is now required
        content: Optional[Control] = None,  # content is optional
        direction: Optional[PopoverDirection] = PopoverDirection.BOTTOM,
        transition: Optional[PopoverTransition] = PopoverTransition.SCALE,
        background_color: Optional[ColorValue] = None,
        barrier_color: Optional[ColorValue] = None,
        transition_duration: Optional[Duration] = None,
        radius: OptionalNumber = None,
        border_radius: Optional[BorderRadius] = None,
        arrow_width: OptionalNumber = None,
        arrow_height: OptionalNumber = None,
        arrow_dx_offset: OptionalNumber = None,
        arrow_dy_offset: OptionalNumber = None,
        content_dx_offset: OptionalNumber = None,
        content_dy_offset: OptionalNumber = None,
        barrier_dismissible: Optional[bool] = None,
        modal: Optional[bool] = None,
        on_pop: OptionalControlEventCallable = None,
    ):
        ConstrainedControl.__init__(
            self,
            ref=ref,
            key=key,
            width=width,
            height=height,
            left=left,
            top=top,
            right=right,
            bottom=bottom,
            expand=expand,
            expand_loose=expand_loose,
            col=col,
            opacity=opacity,
            rotate=rotate,
            scale=scale,
            offset=offset,
            aspect_ratio=aspect_ratio,
            animate_opacity=animate_opacity,
            animate_size=animate_size,
            animate_position=animate_position,
            animate_rotation=animate_rotation,
            animate_scale=animate_scale,
            animate_offset=animate_offset,
            on_animation_end=on_animation_end,
            tooltip=tooltip,
            badge=badge,
            visible=visible,
            disabled=disabled,
            data=data,
            rtl=rtl,
        )

        # Initialize private attributes
        self.__content = None
        self.__body = None
        self.__direction = None
        self.__transition = None
        self.__background_color = None
        self.__barrier_color = None

        # Validate required parameters
        if body is None:
            raise ValueError("body parameter is required for FletPopover")

        # Set properties through setters to ensure proper attribute setting
        self.content = content
        self.body = body
        self.direction = direction
        self.transition = transition
        self.background_color = background_color
        self.barrier_color = barrier_color
        self.transition_duration = transition_duration
        self.radius = radius
        self.border_radius = border_radius
        self.arrow_width = arrow_width
        self.arrow_height = arrow_height
        self.arrow_dx_offset = arrow_dx_offset
        self.arrow_dy_offset = arrow_dy_offset
        self.content_dx_offset = content_dx_offset
        self.content_dy_offset = content_dy_offset
        self.barrier_dismissible = barrier_dismissible
        self.modal = modal
        self.on_pop = on_pop

    def _get_control_name(self):
        return "flet_popover"

    def _get_children(self):
        children = []
        # body is required, so it should always be present
        if self.__body is not None:
            self.__body._set_attr_internal("n", "body")
            children.append(self.__body)
        # content is optional
        if self.__content is not None:
            self.__content._set_attr_internal("n", "content")
            children.append(self.__content)
        return children

    # content - the trigger control that when clicked shows the popover
    @property
    def content(self) -> Optional[Control]:
        """
        The control that triggers the popover when clicked.
        """
        return self.__content

    @content.setter
    def content(self, value: Optional[Control]):
        self.__content = value

    # body - the content inside the popover (required)
    @property
    def body(self) -> Control:
        """
        The content to display inside the popover. This is required.
        """
        return self.__body

    @body.setter
    def body(self, value: Control):
        if value is None:
            raise ValueError("body cannot be None - it is required for FletPopover")
        self.__body = value

    # direction
    @property
    def direction(self) -> Optional[PopoverDirection]:
        """
        The direction where the popover should appear relative to the trigger control.
        """
        return self.__direction

    @direction.setter
    def direction(self, value: Optional[PopoverDirection]):
        self.__direction = value
        self._set_attr("direction", value.value if value else None)

    # transition
    @property
    def transition(self) -> Optional[PopoverTransition]:
        """
        The transition animation to use when showing/hiding the popover.
        """
        return self.__transition

    @transition.setter
    def transition(self, value: Optional[PopoverTransition]):
        self.__transition = value
        self._set_attr("transition", value.value if value else None)

    # background_color
    @property
    def background_color(self) -> Optional[ColorValue]:
        """
        The background color of the popover.
        """
        return self.__background_color

    @background_color.setter
    def background_color(self, value: Optional[ColorValue]):
        self.__background_color = value
        self._set_enum_attr("backgroundColor", value, ColorEnums)

    # barrier_color
    @property
    def barrier_color(self) -> Optional[ColorValue]:
        """
        The color of the barrier (overlay) behind the popover.
        """
        return self.__barrier_color

    @barrier_color.setter
    def barrier_color(self, value: Optional[ColorValue]):
        self.__barrier_color = value
        self._set_enum_attr("barrierColor", value, ColorEnums)

    # transition_duration
    @property
    def transition_duration(self) -> Optional[Duration]:
        """
        The duration of the transition animation.
        """
        return self._get_attr("transitionDuration")

    @transition_duration.setter
    def transition_duration(self, value: Optional[Duration]):
        self._set_attr("transitionDuration", value)

    # radius
    @property
    def radius(self) -> OptionalNumber:
        """
        The border radius of the popover.
        """
        return self._get_attr("radius", data_type="float")

    @radius.setter
    def radius(self, value: OptionalNumber):
        self._set_attr("radius", value)

    # border_radius
    @property
    def border_radius(self) -> Optional[BorderRadius]:
        """
        The border radius of the popover (more detailed than radius).
        """
        return self._get_attr("borderRadius")

    @border_radius.setter
    def border_radius(self, value: Optional[BorderRadius]):
        self._set_attr("borderRadius", value)


    @property
    def arrow_width(self) -> OptionalNumber:
        """
        The width of the popover arrow.
        """
        return self._get_attr("arrowWidth", data_type="float")

    @arrow_width.setter
    def arrow_width(self, value: OptionalNumber):
        self._set_attr("arrowWidth", value)

    # arrow_height
    @property
    def arrow_height(self) -> OptionalNumber:
        """
        The height of the popover arrow.
        """
        return self._get_attr("arrowHeight", data_type="float")

    @arrow_height.setter
    def arrow_height(self, value: OptionalNumber):
        self._set_attr("arrowHeight", value)

    # arrow_dx_offset
    @property
    def arrow_dx_offset(self) -> OptionalNumber:
        """
        The horizontal offset of the popover arrow.
        """
        return self._get_attr("arrowDxOffset", data_type="float")

    @arrow_dx_offset.setter
    def arrow_dx_offset(self, value: OptionalNumber):
        self._set_attr("arrowDxOffset", value)

    # arrow_dy_offset
    @property
    def arrow_dy_offset(self) -> OptionalNumber:
        """
        The vertical offset of the popover arrow.
        """
        return self._get_attr("arrowDyOffset", data_type="float")

    @arrow_dy_offset.setter
    def arrow_dy_offset(self, value: OptionalNumber):
        self._set_attr("arrowDyOffset", value)

    # content_dx_offset
    @property
    def content_dx_offset(self) -> OptionalNumber:
        """
        The horizontal offset of the popover content.
        """
        return self._get_attr("contentDxOffset", data_type="float")

    @content_dx_offset.setter
    def content_dx_offset(self, value: OptionalNumber):
        self._set_attr("contentDxOffset", value)

    # content_dy_offset
    @property
    def content_dy_offset(self) -> OptionalNumber:
        """
        The vertical offset of the popover content.
        """
        return self._get_attr("contentDyOffset", data_type="float")

    @content_dy_offset.setter
    def content_dy_offset(self, value: OptionalNumber):
        self._set_attr("contentDyOffset", value)

    # barrier_dismissible
    @property
    def barrier_dismissible(self) -> Optional[bool]:
        """
        Whether the popover can be dismissed by tapping outside of it.
        """
        return self._get_attr("barrierDismissible", data_type="bool")

    @barrier_dismissible.setter
    def barrier_dismissible(self, value: Optional[bool]):
        self._set_attr("barrierDismissible", value)

    # modal
    @property
    def modal(self) -> Optional[bool]:
        """
        Whether the popover should be modal (blocking interaction with other controls).
        """
        return self._get_attr("modal", data_type="bool")

    @modal.setter
    def modal(self, value: Optional[bool]):
        self._set_attr("modal", value)

    # on_pop
    @property
    def on_pop(self) -> OptionalControlEventCallable:
        """
        Event handler called when the popover is dismissed.
        """
        return self._get_event_handler("on_pop")

    @on_pop.setter
    def on_pop(self, handler: OptionalControlEventCallable):
        self._add_event_handler("on_pop", handler)

    # Methods
    def show_popover(self):
        """
        Show the popover programmatically.
        """
        self.invoke_method("show_popover", wait_for_result=False)

    def hide_popover(self):
        """
        Hide the popover programmatically.
        """
        self.invoke_method("hide_popover", wait_for_result=False)

    def open(self):
        """
        Open the popover programmatically. Alias for show_popover().
        """
        self.show_popover()

    def close(self):
        """
        Close the popover programmatically. Alias for hide_popover().
        """
        self.hide_popover()

arrow_dx_offset property writable

The horizontal offset of the popover arrow.

arrow_dy_offset property writable

The vertical offset of the popover arrow.

arrow_height property writable

The height of the popover arrow.

arrow_width property writable

The width of the popover arrow.

background_color property writable

The background color of the popover.

barrier_color property writable

The color of the barrier (overlay) behind the popover.

barrier_dismissible property writable

Whether the popover can be dismissed by tapping outside of it.

body property writable

The content to display inside the popover. This is required.

border_radius property writable

The border radius of the popover (more detailed than radius).

content property writable

The control that triggers the popover when clicked.

content_dx_offset property writable

The horizontal offset of the popover content.

content_dy_offset property writable

The vertical offset of the popover content.

direction property writable

The direction where the popover should appear relative to the trigger control.

modal property writable

Whether the popover should be modal (blocking interaction with other controls).

on_pop property writable

Event handler called when the popover is dismissed.

radius property writable

The border radius of the popover.

transition property writable

The transition animation to use when showing/hiding the popover.

transition_duration property writable

The duration of the transition animation.

close()

Close the popover programmatically. Alias for hide_popover().

Source code in src\flet_popover\flet_popover.py
423
424
425
426
427
def close(self):
    """
    Close the popover programmatically. Alias for hide_popover().
    """
    self.hide_popover()

hide_popover()

Hide the popover programmatically.

Source code in src\flet_popover\flet_popover.py
411
412
413
414
415
def hide_popover(self):
    """
    Hide the popover programmatically.
    """
    self.invoke_method("hide_popover", wait_for_result=False)

open()

Open the popover programmatically. Alias for show_popover().

Source code in src\flet_popover\flet_popover.py
417
418
419
420
421
def open(self):
    """
    Open the popover programmatically. Alias for show_popover().
    """
    self.show_popover()

show_popover()

Show the popover programmatically.

Source code in src\flet_popover\flet_popover.py
405
406
407
408
409
def show_popover(self):
    """
    Show the popover programmatically.
    """
    self.invoke_method("show_popover", wait_for_result=False)

PopoverDirection

Bases: Enum

Popover direction enum.

Source code in src\flet_popover\flet_popover.py
14
15
16
17
18
19
20
21
22
class PopoverDirection(Enum):
    """
    Popover direction enum.
    """

    TOP = "top"
    BOTTOM = "bottom"
    LEFT = "left"
    RIGHT = "right"

PopoverTransition

Bases: Enum

Popover transition enum.

Source code in src\flet_popover\flet_popover.py
25
26
27
28
29
30
31
class PopoverTransition(Enum):
    """
    Popover transition enum.
    """

    SCALE = "scale"
    FADE = "fade"