Refine modal focus handling: update tab navigation logic and simplify focus setting in SaveConfirmationModal tests
This commit is contained in:
		
							parent
							
								
									77d8e647f2
								
							
						
					
					
						commit
						1dd54b0cb5
					
				
					 3 changed files with 12 additions and 66 deletions
				
			
		| 
						 | 
				
			
			@ -839,11 +839,16 @@ class HostsManagerApp(App):
 | 
			
		|||
 | 
			
		||||
    def on_key(self, event) -> None:
 | 
			
		||||
        """Handle key events to override default tab behavior in edit mode."""
 | 
			
		||||
        if self.entry_edit_mode and event.key == "tab":
 | 
			
		||||
        # Only handle custom tab navigation if in entry edit mode AND no modal is open
 | 
			
		||||
        if self.entry_edit_mode and len(self.screen_stack) == 1 and event.key == "tab":
 | 
			
		||||
            # Prevent default tab behavior and use our custom navigation
 | 
			
		||||
            event.prevent_default()
 | 
			
		||||
            self.action_next_field()
 | 
			
		||||
        elif self.entry_edit_mode and event.key == "shift+tab":
 | 
			
		||||
        elif (
 | 
			
		||||
            self.entry_edit_mode
 | 
			
		||||
            and len(self.screen_stack) == 1
 | 
			
		||||
            and event.key == "shift+tab"
 | 
			
		||||
        ):
 | 
			
		||||
            # Prevent default shift+tab behavior and use our custom navigation
 | 
			
		||||
            event.prevent_default()
 | 
			
		||||
            self.action_prev_field()
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -95,59 +95,11 @@ class SaveConfirmationModal(ModalScreen):
 | 
			
		|||
                )
 | 
			
		||||
 | 
			
		||||
    def on_mount(self) -> None:
 | 
			
		||||
        """Called when the modal is mounted. Set focus and ensure modal captures input."""
 | 
			
		||||
        # Set focus to the modal screen itself first
 | 
			
		||||
        self.focus()
 | 
			
		||||
        # Then focus on the Save button
 | 
			
		||||
        self.call_after_refresh(self._focus_save_button)
 | 
			
		||||
 | 
			
		||||
    def _focus_save_button(self) -> None:
 | 
			
		||||
        """Focus the save button after refresh."""
 | 
			
		||||
        """Called when the modal is mounted. Set focus to the first button."""
 | 
			
		||||
        # Focus on the Save button by default
 | 
			
		||||
        save_button = self.query_one("#save-button", Button)
 | 
			
		||||
        save_button.focus()
 | 
			
		||||
 | 
			
		||||
    def on_key(self, event) -> None:
 | 
			
		||||
        """Handle key events, ensuring tab navigation works within the modal."""
 | 
			
		||||
        if event.key == "tab":
 | 
			
		||||
            # Get all buttons in order
 | 
			
		||||
            buttons = [
 | 
			
		||||
                self.query_one("#save-button", Button),
 | 
			
		||||
                self.query_one("#discard-button", Button),
 | 
			
		||||
                self.query_one("#cancel-button", Button),
 | 
			
		||||
            ]
 | 
			
		||||
 | 
			
		||||
            # Find currently focused button and move to next
 | 
			
		||||
            for i, button in enumerate(buttons):
 | 
			
		||||
                if button.has_focus:
 | 
			
		||||
                    next_button = buttons[(i + 1) % len(buttons)]
 | 
			
		||||
                    next_button.focus()
 | 
			
		||||
                    event.prevent_default()
 | 
			
		||||
                    return
 | 
			
		||||
 | 
			
		||||
            # If no button has focus, focus the first one
 | 
			
		||||
            buttons[0].focus()
 | 
			
		||||
            event.prevent_default()
 | 
			
		||||
 | 
			
		||||
        elif event.key == "shift+tab":
 | 
			
		||||
            # Get all buttons in order
 | 
			
		||||
            buttons = [
 | 
			
		||||
                self.query_one("#save-button", Button),
 | 
			
		||||
                self.query_one("#discard-button", Button),
 | 
			
		||||
                self.query_one("#cancel-button", Button),
 | 
			
		||||
            ]
 | 
			
		||||
 | 
			
		||||
            # Find currently focused button and move to previous
 | 
			
		||||
            for i, button in enumerate(buttons):
 | 
			
		||||
                if button.has_focus:
 | 
			
		||||
                    prev_button = buttons[(i - 1) % len(buttons)]
 | 
			
		||||
                    prev_button.focus()
 | 
			
		||||
                    event.prevent_default()
 | 
			
		||||
                    return
 | 
			
		||||
 | 
			
		||||
            # If no button has focus, focus the last one
 | 
			
		||||
            buttons[-1].focus()
 | 
			
		||||
            event.prevent_default()
 | 
			
		||||
 | 
			
		||||
    def on_button_pressed(self, event: Button.Pressed) -> None:
 | 
			
		||||
        """Handle button presses."""
 | 
			
		||||
        if event.button.id == "save-button":
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -56,25 +56,14 @@ class TestSaveConfirmationModal:
 | 
			
		|||
 | 
			
		||||
        modal.dismiss.assert_called_once_with("cancel")
 | 
			
		||||
 | 
			
		||||
    @patch.object(SaveConfirmationModal, "call_after_refresh")
 | 
			
		||||
    @patch.object(SaveConfirmationModal, "focus")
 | 
			
		||||
    def test_on_mount_sets_focus(self, mock_focus, mock_call_after_refresh):
 | 
			
		||||
        """Test that on_mount sets focus to the modal and schedules button focus."""
 | 
			
		||||
        modal = SaveConfirmationModal()
 | 
			
		||||
 | 
			
		||||
        modal.on_mount()
 | 
			
		||||
 | 
			
		||||
        mock_focus.assert_called_once()
 | 
			
		||||
        mock_call_after_refresh.assert_called_once()
 | 
			
		||||
 | 
			
		||||
    @patch.object(SaveConfirmationModal, "query_one")
 | 
			
		||||
    def test_focus_save_button(self, mock_query_one):
 | 
			
		||||
        """Test that _focus_save_button focuses the save button."""
 | 
			
		||||
    def test_on_mount_sets_focus(self, mock_query_one):
 | 
			
		||||
        """Test that on_mount sets focus to the save button."""
 | 
			
		||||
        modal = SaveConfirmationModal()
 | 
			
		||||
        mock_save_button = Mock()
 | 
			
		||||
        mock_query_one.return_value = mock_save_button
 | 
			
		||||
 | 
			
		||||
        modal._focus_save_button()
 | 
			
		||||
        modal.on_mount()
 | 
			
		||||
 | 
			
		||||
        mock_query_one.assert_called_once_with("#save-button", Button)
 | 
			
		||||
        mock_save_button.focus.assert_called_once()
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue