Vue Code Completion Component
This challenge involves building a robust code completion component for a Vue.js application using TypeScript. Code completion is a fundamental feature in modern development tools, significantly improving developer productivity by suggesting relevant code snippets as users type. Your task is to create a reusable and performant component that can handle dynamic suggestion lists.
Problem Description
You need to develop a Vue 3 component written in TypeScript that provides inline code completion suggestions. The component should render a list of suggestions to the user based on their input in a text area or input field.
Key Requirements:
- Input Handling: The component should monitor user input in a designated text area or input field.
- Suggestion Generation: Based on the current input and a provided list of possible suggestions, the component should filter and display relevant options.
- Suggestion Display: Suggestions should be displayed in a dropdown or popover list below the input area.
- Selection: Users should be able to select a suggestion using either keyboard navigation (arrow keys) or mouse clicks.
- Insertion: Upon selection, the chosen suggestion should be inserted into the input field at the current cursor position, and the suggestion list should be hidden.
- Dynamic Suggestions: The list of suggestions should be passed as a prop and can be dynamically updated.
- TypeScript Integration: The entire component, including props and internal logic, must be written in TypeScript.
Expected Behavior:
- As the user types, if their input matches any part of a suggestion (case-insensitive is a good starting point), those suggestions should appear.
- The suggestion list should be hidden when there are no matching suggestions or when the input field loses focus.
- Arrow keys (Up/Down) should navigate through the suggestion list.
- Enter or Tab key should select the currently highlighted suggestion.
- Clicking on a suggestion should also select it.
- The component should be easily integrable into various Vue applications.
Edge Cases to Consider:
- Empty input string.
- Input string that matches no suggestions.
- Large lists of suggestions.
- Suggestions that contain special characters.
- Maintaining cursor position correctly after insertion.
- Handling focus loss from the input field to the suggestion list and back.
Examples
Example 1:
Input:
- A text input field is focused.
- The component is given a list of suggestions: ["apple", "apricot", "banana", "application", "apply"]
- The user types "app" into the input field.
Output:
- A dropdown appears below the input field.
- The dropdown displays the following suggestions: ["apple", "application", "apply"]
- The suggestions are highlighted or can be navigated.
Explanation: The component filters the provided suggestions based on the input "app" (case-insensitively).
Example 2:
Input:
- Continuing from Example 1, the user has typed "app" and the suggestions ["apple", "application", "apply"] are displayed.
- The user presses the Down arrow key twice.
Output:
- The suggestion "apply" is now visually highlighted (e.g., different background color).
Explanation: Keyboard navigation highlights the next suggestion in the list.
Example 3:
Input:
- Continuing from Example 2, "apply" is highlighted.
- The user presses the Enter key.
- The current cursor position in the input field is at the end of "app".
Output:
- The input field now contains "apply".
- The suggestion list is hidden.
Explanation: The highlighted suggestion "apply" is inserted into the input field at the cursor's position, replacing any partial match if applicable (though in this simple case, it's appended). The suggestion list is dismissed.
Example 4 (Insertion with existing text):
Input:
- A text input field contains "Hello ".
- The component is given suggestions: ["world", "there", "beautiful"]
- The user types "wo" after "Hello ". The cursor is after "o".
Output:
- The suggestion list shows: ["world"]
- The user clicks on "world".
Explanation: The suggestion "world" is inserted after "Hello ", resulting in the input field containing "Hello world".
Constraints
- The component must be built using Vue 3 Composition API and TypeScript.
- The suggestion list prop should accept an array of strings.
- The component should aim for reasonable performance, especially with lists of up to 100 suggestions.
- The component should not introduce significant DOM manipulation overhead.
- Accessibility considerations (keyboard navigation, ARIA attributes) are encouraged.
Notes
- Consider how to handle partial matches (e.g., "app" matching "apple", "application", "apply"). A simple
includes()check is a good starting point, but you might want to explore more sophisticated matching later. - Think about debouncing input to avoid excessive filtering on every keystroke, especially for larger suggestion lists or complex filtering logic.
- The component should emit an event when a suggestion is selected to allow the parent component to react to the inserted text.
- Consider the styling of the suggestion list; while the core logic is the focus, a basic visual representation is needed for testing. You can use inline styles or basic CSS classes.
- For insertion, you'll likely need to interact with the DOM's
selectionStartandselectionEndproperties to accurately place the selected text.