I can select range with visual feedback

This commit is contained in:
2026-02-10 23:00:45 +01:00
parent 79c37493af
commit 520a8914fc
7 changed files with 353 additions and 25 deletions

View File

@@ -238,7 +238,9 @@ class DataGrid(MultipleInstance):
# other definitions
self._mouse_support = {
"mousedown>mouseup": {"command": self.commands.on_mouse_selection(), "hx_vals": "js:getCellId()"},
"mousedown>mouseup": {"command": self.commands.on_mouse_selection(),
"hx_vals": "js:getCellId()",
"on_move": "js:highlightDatagridDragRange()"},
"click": {"command": self.commands.on_click(), "hx_vals": "js:getCellId()"},
"ctrl+click": {"command": self.commands.on_click(), "hx_vals": "js:getCellId()"},
"shift+click": {"command": self.commands.on_click(), "hx_vals": "js:getCellId()"},
@@ -500,6 +502,9 @@ class DataGrid(MultipleInstance):
if (is_inside and
cell_id_mousedown and cell_id_mouseup and
cell_id_mousedown.startswith("tcell_") and cell_id_mouseup.startswith("tcell_")):
self._update_current_position(None)
pos_mouse_down = self._get_pos_from_element_id(cell_id_mousedown)
pos_mouse_up = self._get_pos_from_element_id(cell_id_mouseup)

View File

@@ -78,7 +78,8 @@ class Mouse(MultipleInstance):
def add(self, sequence: str, command: Command = None, *,
hx_post: str = None, hx_get: str = None, hx_put: str = None,
hx_delete: str = None, hx_patch: str = None,
hx_target: str = None, hx_swap: str = None, hx_vals=None):
hx_target: str = None, hx_swap: str = None, hx_vals=None,
on_move: str = None):
"""
Add a mouse combination with optional command and HTMX parameters.
@@ -99,6 +100,11 @@ class Mouse(MultipleInstance):
hx_vals: HTMX values dict or "js:functionName()" for dynamic values.
For mousedown>mouseup actions, the JS function is called at both
mousedown and mouseup, with results suffixed ``_mousedown`` and ``_mouseup``.
on_move: Client-side JS function called on each animation frame during a drag,
using ``"js:functionName()"`` format. Only valid with ``mousedown>mouseup``
sequences. The function receives ``(event, combination, mousedown_result)``
where ``mousedown_result`` is the raw result of ``hx_vals`` at mousedown,
or ``None`` if ``hx_vals`` is not set. Return value is ignored.
Returns:
self for method chaining
@@ -117,6 +123,7 @@ class Mouse(MultipleInstance):
"hx_target": hx_target,
"hx_swap": hx_swap,
"hx_vals": hx_vals,
"on_move": on_move,
}
return self
@@ -172,6 +179,15 @@ class Mouse(MultipleInstance):
except json.JSONDecodeError as e:
raise ValueError(f"hx_vals must be a dict or 'js:functionName()', got invalid JSON: {e}")
# Handle on_move - client-side function for real-time drag feedback
on_move = combination_data.get("on_move")
if on_move is not None:
if isinstance(on_move, str) and on_move.startswith("js:"):
func_name = on_move[3:].rstrip("()")
params["on-move"] = func_name
else:
raise ValueError(f"on_move must be 'js:functionName()', got: {on_move!r}")
return params
def render(self):