from fasthtml.components import * from myfasthtml.core.bindings import Binding from myfasthtml.core.commands import Command from myfasthtml.core.utils import merge_classes class Ids: # Please keep the alphabetical order Root = "mf-root" UserSession = "mf-user_session" class mk: @staticmethod def button(element, command: Command = None, binding: Binding = None, **kwargs): """ Defines a static method for creating a Button object with specific configurations. This method constructs a Button instance by wrapping an element with additional configurations such as commands and bindings. Any extra keyword arguments are passed when creating the Button. :param element: The underlying widget or element to be wrapped in a Button. :param command: An optional command to associate with the Button. Defaults to None. :param binding: An optional event binding to associate with the Button. Defaults to None. :param kwargs: Additional keyword arguments to further configure the Button. :return: A fully constructed Button instance with the specified configurations. """ return mk.mk(Button(element, **kwargs), command=command, binding=binding) @staticmethod def dialog_buttons(ok_title: str = "OK", cancel_title: str = "Cancel", on_ok: Command = None, on_cancel: Command = None, cls=None): return Div( Div( mk.button(ok_title, cls="btn btn-primary btn-sm mr-2", command=on_ok), mk.button(cancel_title, cls="btn btn-ghost btn-sm", command=on_cancel), cls="flex justify-end" ), cls=merge_classes("flex justify-end w-full mt-1", cls) ) @staticmethod def icon(icon, size=20, can_select=True, can_hover=False, tooltip=None, cls='', command: Command = None, binding: Binding = None, **kwargs): """ Generates an icon element with customizable properties for size, class, and interactivity. This method creates an icon element wrapped in a container with optional classes and event bindings. The icon can be styled and its behavior defined using the parameters provided, allowing for dynamic and reusable UI components. :param icon: The icon to display inside the container. :param size: The size of the icon, specified in pixels. Defaults to 20. :param can_select: Indicates whether the icon can be selected. Defaults to True. :param can_hover: Indicates whether the icon reacts to hovering. Defaults to False. :param tooltip: :param cls: A string of custom CSS classes to be added to the icon container. :param command: The command object defining the function to be executed on icon interaction. :param binding: The binding object for configuring additional event listeners on the icon. :param kwargs: Additional keyword arguments for configuring attributes and behaviors of the icon element. :return: A styled and interactive icon element embedded inside a container, configured with the defined classes, size, and behaviors. """ merged_cls = merge_classes(f"mf-icon-{size}", 'icon-btn' if can_select else '', 'mmt-btn' if can_hover else '', cls, kwargs) if tooltip: merged_cls = merge_classes(merged_cls, "mf-tooltip") kwargs["data-tooltip"] = tooltip return mk.mk(Div(icon, cls=merged_cls, **kwargs), command=command, binding=binding) @staticmethod def label(text: str, icon=None, size: str = "sm", cls='', command: Command = None, binding: Binding = None, **kwargs): merged_cls = merge_classes("flex", cls, kwargs) icon_part = Span(icon, cls=f"mf-icon-{mk.convert_size(size)} mr-1") if icon else None text_part = Span(text, cls=f"text-{size}") return mk.mk(Label(icon_part, text_part, cls=merged_cls, **kwargs), command=command, binding=binding) @staticmethod def convert_size(size: str): return (size.replace("xs", "16"). replace("sm", "20"). replace("md", "24"). replace("lg", "28"). replace("xl", "32")) @staticmethod def manage_command(ft, command: Command): if command: ft = command.bind_ft(ft) return ft @staticmethod def manage_binding(ft, binding: Binding, ft_attr=None, init_binding=True): if not binding: return ft binding.bind_ft(ft, ft_attr) if init_binding: binding.init() # as it is the first binding, remove the hx-swap-oob if "hx-swap-oob" in ft.attrs: del ft.attrs["hx-swap-oob"] return ft @staticmethod def mk(ft, command: Command = None, binding: Binding = None, init_binding=True): ft = mk.manage_command(ft, command) if command else ft ft = mk.manage_binding(ft, binding, init_binding=init_binding) if binding else ft return ft