feat: Add CommandLine component with autocomplete stub
This commit is contained in:
@@ -0,0 +1,108 @@
|
|||||||
|
import React, { useState, useRef, useEffect } from 'react';
|
||||||
|
import './CommandLine.css';
|
||||||
|
|
||||||
|
const CommandLine: React.FC = () => {
|
||||||
|
const [command, setCommand] = useState('');
|
||||||
|
const [suggestions, setSuggestions] = useState<string[]>([]);
|
||||||
|
const inputRef = useRef<HTMLInputElement>(null);
|
||||||
|
|
||||||
|
// Mock command suggestions
|
||||||
|
const commandList = [
|
||||||
|
'LINE', 'CIRCLE', 'RECTANGLE', 'POLYGON',
|
||||||
|
'MOVE', 'COPY', 'ROTATE', 'SCALE',
|
||||||
|
'TRIM', 'EXTEND', 'FILLET', 'CHAMFER',
|
||||||
|
'DIMLINEAR', 'DIMALIGNED', 'DIMRADIUS', 'DIMDIAMETER',
|
||||||
|
'TEXT', 'MTEXT', 'INSERT', 'HATCH'
|
||||||
|
];
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
// Focus the input when component mounts
|
||||||
|
if (inputRef.current) {
|
||||||
|
inputRef.current.focus();
|
||||||
|
}
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
const handleInputChange = (e: React.ChangeEvent<HTMLInputElement>) => {
|
||||||
|
const value = e.target.value;
|
||||||
|
setCommand(value);
|
||||||
|
|
||||||
|
// Generate suggestions based on input
|
||||||
|
if (value.length > 0) {
|
||||||
|
const filtered = commandList.filter(cmd =>
|
||||||
|
cmd.toLowerCase().startsWith(value.toLowerCase())
|
||||||
|
);
|
||||||
|
setSuggestions(filtered);
|
||||||
|
} else {
|
||||||
|
setSuggestions([]);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleSuggestionClick = (suggestion: string) => {
|
||||||
|
setCommand(suggestion);
|
||||||
|
setSuggestions([]);
|
||||||
|
// Focus back to input after selection
|
||||||
|
if (inputRef.current) {
|
||||||
|
inputRef.current.focus();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleSubmit = (e: React.FormEvent) => {
|
||||||
|
e.preventDefault();
|
||||||
|
// In a real app, this would dispatch the command
|
||||||
|
console.log('Command submitted:', command);
|
||||||
|
setCommand('');
|
||||||
|
setSuggestions([]);
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="command-line" role="region" aria-label="Command Line">
|
||||||
|
<form onSubmit={handleSubmit} className="command-form">
|
||||||
|
<label htmlFor="command-input" className="command-label">
|
||||||
|
Command:
|
||||||
|
</label>
|
||||||
|
<div className="command-input-container">
|
||||||
|
<input
|
||||||
|
ref={inputRef}
|
||||||
|
id="command-input"
|
||||||
|
type="text"
|
||||||
|
value={command}
|
||||||
|
onChange={handleInputChange}
|
||||||
|
className="command-input"
|
||||||
|
aria-autocomplete="list"
|
||||||
|
aria-controls="command-suggestions"
|
||||||
|
aria-describedby="command-description"
|
||||||
|
placeholder="Enter command..."
|
||||||
|
/>
|
||||||
|
<button type="submit" className="command-submit">
|
||||||
|
Enter
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<div id="command-description" className="sr-only">
|
||||||
|
Type a CAD command and press Enter to execute
|
||||||
|
</div>
|
||||||
|
{suggestions.length > 0 && (
|
||||||
|
<ul
|
||||||
|
id="command-suggestions"
|
||||||
|
className="suggestions-list"
|
||||||
|
role="listbox"
|
||||||
|
aria-label="Command Suggestions"
|
||||||
|
>
|
||||||
|
{suggestions.map((suggestion, index) => (
|
||||||
|
<li
|
||||||
|
key={index}
|
||||||
|
className="suggestion-item"
|
||||||
|
onClick={() => handleSuggestionClick(suggestion)}
|
||||||
|
role="option"
|
||||||
|
aria-selected="false"
|
||||||
|
>
|
||||||
|
{suggestion}
|
||||||
|
</li>
|
||||||
|
))}
|
||||||
|
</ul>
|
||||||
|
)}
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default CommandLine;
|
||||||
Reference in New Issue
Block a user