Working on ColumnsManager. Added CycleStateControl and DataGridColumnsManager.
This commit is contained in:
@@ -29,18 +29,43 @@ class DropdownState:
|
||||
|
||||
class Dropdown(MultipleInstance):
|
||||
"""
|
||||
Represents a dropdown component that can be toggled open or closed. This class is used
|
||||
to create interactive dropdown elements, allowing for container and button customization.
|
||||
The dropdown provides functionality to manage its state, including opening, closing, and
|
||||
handling user interactions.
|
||||
Interactive dropdown component that toggles open/closed on button click.
|
||||
|
||||
Provides automatic close behavior when clicking outside or pressing ESC.
|
||||
Supports configurable positioning relative to the trigger button.
|
||||
|
||||
Args:
|
||||
parent: Parent instance (required).
|
||||
content: Content to display in the dropdown panel.
|
||||
button: Trigger element that toggles the dropdown.
|
||||
_id: Custom ID for the instance.
|
||||
position: Vertical position relative to button.
|
||||
- "below" (default): Dropdown appears below the button.
|
||||
- "above": Dropdown appears above the button.
|
||||
align: Horizontal alignment relative to button.
|
||||
- "left" (default): Aligns to the left edge of the button.
|
||||
- "right": Aligns to the right edge of the button.
|
||||
- "center": Centers relative to the button.
|
||||
|
||||
Example:
|
||||
dropdown = Dropdown(
|
||||
parent=root,
|
||||
button=Button("Menu"),
|
||||
content=Ul(Li("Option 1"), Li("Option 2")),
|
||||
position="below",
|
||||
align="right"
|
||||
)
|
||||
"""
|
||||
|
||||
def __init__(self, parent, content=None, button=None, _id=None):
|
||||
|
||||
def __init__(self, parent, content=None, button=None, _id=None,
|
||||
position="below", align="left"):
|
||||
super().__init__(parent, _id=_id)
|
||||
self.button = Div(button) if not isinstance(button, FT) else button
|
||||
self.content = content
|
||||
self.commands = Commands(self)
|
||||
self._state = DropdownState()
|
||||
self._position = position
|
||||
self._align = align
|
||||
|
||||
def toggle(self):
|
||||
self._state.opened = not self._state.opened
|
||||
@@ -50,57 +75,32 @@ class Dropdown(MultipleInstance):
|
||||
self._state.opened = False
|
||||
return self._mk_content()
|
||||
|
||||
def on_click(self, combination, is_inside: bool):
|
||||
def on_click(self, combination, is_inside: bool, is_button: bool = False):
|
||||
if combination == "click":
|
||||
self._state.opened = is_inside
|
||||
if is_button:
|
||||
self._state.opened = not self._state.opened
|
||||
else:
|
||||
self._state.opened = is_inside
|
||||
return self._mk_content()
|
||||
|
||||
def _mk_content(self):
|
||||
position_cls = f"mf-dropdown-{self._position}"
|
||||
align_cls = f"mf-dropdown-{self._align}"
|
||||
return Div(self.content,
|
||||
cls=f"mf-dropdown {'is-visible' if self._state.opened else ''}",
|
||||
cls=f"mf-dropdown {position_cls} {align_cls} {'is-visible' if self._state.opened else ''}",
|
||||
id=f"{self._id}-content"),
|
||||
|
||||
def render(self):
|
||||
return Div(
|
||||
Div(
|
||||
Div(self.button) if self.button else Div("None"),
|
||||
Div(self.button if self.button else "None", cls="mf-dropdown-btn"),
|
||||
self._mk_content(),
|
||||
cls="mf-dropdown-wrapper"
|
||||
),
|
||||
Keyboard(self, _id="-keyboard").add("esc", self.commands.close()),
|
||||
Mouse(self, "-mouse").add("click", self.commands.click()),
|
||||
Mouse(self, "-mouse").add("click", self.commands.click(), hx_vals="js:getDropdownExtra()"),
|
||||
id=self._id
|
||||
)
|
||||
|
||||
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';
|
||||
# }
|
||||
# }
|
||||
# });
|
||||
|
||||
Reference in New Issue
Block a user