From 52b4e6a8b6f839462292ffd162b4e1274f95d751 Mon Sep 17 00:00:00 2001 From: Kodjo Sossouvi Date: Mon, 24 Nov 2025 22:47:49 +0100 Subject: [PATCH] Working on Dropdown --- src/app.py | 5 +++ src/myfasthtml/assets/myfasthtml.css | 30 ++++++++++++++++- src/myfasthtml/controls/Dropdown.py | 50 ++++++++++++++++++++++++++++ 3 files changed, 84 insertions(+), 1 deletion(-) create mode 100644 src/myfasthtml/controls/Dropdown.py diff --git a/src/app.py b/src/app.py index 97abb4a..98f4212 100644 --- a/src/app.py +++ b/src/app.py @@ -8,6 +8,7 @@ from myfasthtml.controls.FileUpload import FileUpload from myfasthtml.controls.InstancesDebugger import InstancesDebugger from myfasthtml.controls.Keyboard import Keyboard from myfasthtml.controls.Layout import Layout +from myfasthtml.controls.Dropdown import Dropdown from myfasthtml.controls.TabsManager import TabsManager from myfasthtml.controls.helpers import Ids, mk from myfasthtml.core.instances import UniqueInstance @@ -58,11 +59,15 @@ def index(session): command=tabs_manager.commands.add_tab("File Open", FileUpload(layout, _id="-file_upload")), id="file_upload_id") + btn_popup = mk.label("Popup", + command=tabs_manager.commands.add_tab("Popup", Dropdown(layout, "Content", button="button", _id="-popup"))) + layout.header_left.add(tabs_manager.add_tab_btn()) layout.header_right.add(btn_show_right_drawer) layout.left_drawer.add(btn_show_instances_debugger, "Debugger") layout.left_drawer.add(btn_show_commands_debugger, "Debugger") layout.left_drawer.add(btn_file_upload, "Test") + layout.left_drawer.add(btn_popup, "Test") layout.set_main(tabs_manager) keyboard = Keyboard(layout, _id="-keyboard").add("ctrl+o", tabs_manager.commands.add_tab("File Open", diff --git a/src/myfasthtml/assets/myfasthtml.css b/src/myfasthtml/assets/myfasthtml.css index 9302f80..f3805f8 100644 --- a/src/myfasthtml/assets/myfasthtml.css +++ b/src/myfasthtml/assets/myfasthtml.css @@ -14,7 +14,6 @@ } - .mf-icon-16 { width: 16px; min-width: 16px; @@ -440,4 +439,33 @@ margin-top: 0.5rem; max-height: 200px; overflow: auto; +} + +.mf-dropdown-wrapper { + position: relative; /* CRUCIAL for the anchor */ + display: inline-block; +} + +.mf-dropdown-wrapper:hover .mf-dropdown { + display: block; +} + +.mf-dropdown { + display: none; + position: absolute; + top: 100%; + left: 0px; + z-index: 1; + width: 200px; + border: 1px solid black; + padding: 10px; + box-sizing: border-box; + overflow-x: auto; + /*opacity: 0;*/ + /*transition: opacity 0.2s ease-in-out;*/ +} + +.mf-dropdown.is-visible { + display: block; + opacity: 1; } \ No newline at end of file diff --git a/src/myfasthtml/controls/Dropdown.py b/src/myfasthtml/controls/Dropdown.py new file mode 100644 index 0000000..02ab609 --- /dev/null +++ b/src/myfasthtml/controls/Dropdown.py @@ -0,0 +1,50 @@ +from fasthtml.components import Div + +from myfasthtml.core.instances import MultipleInstance + + +class Dropdown(MultipleInstance): + def __init__(self, parent, content, button=None, _id=None): + super().__init__(parent, _id=_id) + self.button = button + self.content = content + + def render(self): + return Div( + Div(self.button) if self.button else Div("None"), + Div(self.content, cls="mf-dropdown"), + cls="mf-dropdown-wrapper" + ) + + def __ft__(self): + return self.render() + +# document.addEventListener('htmx:afterSwap', function(event) { +# const targetElement = event.detail.target; // L'élément qui a été mis à jour (#popup-unique-id) +# +# // Vérifie si c'est bien notre popup +# if (targetElement.classList.contains('mf-popup-container')) { +# +# // Trouver l'élément déclencheur HTMX (le bouton existant) +# // HTMX stocke l'élément déclencheur dans event.detail.elt +# const trigger = document.querySelector('#mon-bouton-existant'); +# +# if (trigger) { +# // Obtenir les coordonnées de l'élément déclencheur par rapport à la fenêtre +# const rect = trigger.getBoundingClientRect(); +# +# // L'élément du popup à positionner +# const popup = targetElement; +# +# // Appliquer la position au conteneur du popup +# // On utilise window.scrollY pour s'assurer que la position est absolue par rapport au document, +# // et non seulement à la fenêtre (car le popup est en position: absolute, pas fixed) +# +# // Top: Juste en dessous de l'élément déclencheur +# popup.style.top = (rect.bottom + window.scrollY) + 'px'; +# +# // Left: Aligner avec le côté gauche de l'élément déclencheur +# popup.style.left = (rect.left + window.scrollX) + 'px'; +# } +# } +# });