This works for me for all cases I managed to test:
( I have to keep track of the EOL and BOL to ensure that we don't jump to parents or children. )
(defun heex--treesit-largest-node-at-point (&optional node)
"Find the largest node at point or from specified NODE."
(save-excursion
(forward-comment (point-max))
(let ((node-list
(cl-loop for node = (or node (treesit-node-at (point)))
then (treesit-node-parent node)
while (and node (not (equal (treesit-node-type node) "fragment")))
if (eq (treesit-node-start node)
(point))
collect node)))
(car (last node-list)))))
(defun heex--treesit-backward-sexp ()
"Forward sexp for Heex using treesit."
(let ((node
(save-excursion
(forward-comment (- (point-max)))
(let ((bol (pos-bol))
(end-node (treesit-search-forward-goto
(treesit-node-at (point))
(rx (or "end_tag" "end_component" "end_slot")) t t)))
(if (and end-node (> (treesit-node-end end-node) bol))
(treesit-node-start (treesit-node-parent end-node)))))))
(when node (goto-char node))))
(defun heex--treesit-forward-sexp ()
"Forward sexp for Heex using treesit."
(let* ((node (heex--treesit-largest-node-at-point))
(sibling (treesit-node-next-sibling node)))
(if sibling
(progn
(goto-char (treesit-node-start sibling))
(forward-comment (- (point-max))))
(when node
(pcase (treesit-node-type node)
((or "end_tag" "end_component" "end_slot") nil)
(_ (goto-char (treesit-node-end node))))))))