route-search-component
Version:
A lightweight, framework-agnostic web component for searchable route navigation with keyboard shortcuts
290 lines (223 loc) • 7.33 kB
Markdown
# 🚀 Route Search Web Component
A lightweight, framework-agnostic web component that provides a searchable route dialog accessible via keyboard shortcut (Cmd+Space / Ctrl+Space). Perfect for integrating into Angular, React, Vue, or any web application.
## ✨ Features
- **🔍 Global Search**: Press `Cmd+K` (Mac) or `Ctrl+K` (Windows/Linux) from anywhere in your app
- **⚡ Fast Autocomplete**: Real-time filtering of routes by name or path
- **🎯 Smart Navigation**: Automatically prepends base URL to route paths
- **⌨️ Keyboard Friendly**: Full keyboard navigation support
- **🎨 Modern UI**: Clean, responsive design with smooth animations
- **🔒 Framework Agnostic**: Works in any web application
- **📱 Responsive**: Mobile-friendly design
- **🔄 Dynamic Routes**: Update routes at runtime via attributes
## 🚀 Quick Start
### 1. Include the Component
```html
<script src="route-search-component.js"></script>
```
### 2. Initialize with Routes
```javascript
const routes = [
{ label: "home", path: "seller/engage360" },
{ label: "orders", path: "seller/orders" },
{ label: "templates", path: "seller/channels/whatsapp/your-templates" }
];
// Create component instance
const routeSearch = document.createElement('global-route-search');
routeSearch.setAttribute('routes', JSON.stringify(routes));
document.body.appendChild(routeSearch);
```
### 3. Use the Component
Press `Cmd+K` (Mac) or `Ctrl+K` (Windows/Linux) to open the search dialog!
## 📋 API Reference
### Component Attributes
| Attribute | Type | Description | Required |
|-----------|------|-------------|----------|
| `routes` | String | JSON string containing routes array | Yes |
### Route Object Structure
```javascript
{
label: "Route Display Name", // String - Human-readable route name
path: "actual/route/path" // String - URL path (without base URL)
}
```
### Methods
| Method | Description |
|--------|-------------|
| `setAttribute('routes', routesJson)` | Update routes data |
| `remove()` | Remove component from DOM |
## 🎮 Usage Examples
### Basic HTML Integration
```html
<!DOCTYPE html>
<html>
<head>
<title>My App</title>
</head>
<body>
<h1>Welcome to My App</h1>
<!-- Include the component -->
<script src="route-search-component.js"></script>
<!-- Initialize -->
<script>
const routes = [
{ label: "Dashboard", path: "dashboard" },
{ label: "User Profile", path: "user/profile" },
{ label: "Settings", path: "settings" }
];
const routeSearch = document.createElement('global-route-search');
routeSearch.setAttribute('routes', JSON.stringify(routes));
document.body.appendChild(routeSearch);
</script>
</body>
</html>
```
### Dynamic Route Updates
```javascript
// Update routes at runtime
function updateRoutes(newRoutes) {
const routeSearch = document.querySelector('global-route-search');
if (routeSearch) {
routeSearch.setAttribute('routes', JSON.stringify(newRoutes));
}
}
// Example usage
updateRoutes([
{ label: "New Route", path: "new/route" },
{ label: "Another Route", path: "another/route" }
]);
```
## 🔧 Framework Integration
### Angular
```typescript
// app.component.ts
import { Component, OnInit } from '@angular/core';
@Component({
selector: 'app-root',
template: `<global-route-search [attr.routes]="routesJson"></global-route-search>`
})
export class AppComponent implements OnInit {
routes = [
{ label: "Home", path: "home" },
{ label: "About", path: "about" }
];
get routesJson(): string {
return JSON.stringify(this.routes);
}
}
```
### React
```jsx
// App.jsx
import React, { useEffect } from 'react';
function App() {
useEffect(() => {
const routes = [
{ label: "Home", path: "home" },
{ label: "About", path: "about" }
];
const routeSearch = document.createElement('global-route-search');
routeSearch.setAttribute('routes', JSON.stringify(routes));
document.body.appendChild(routeSearch);
}, []);
return <div>My React App</div>;
}
```
### Vue
```vue
<!-- App.vue -->
<template>
<div id="app">
<global-route-search :routes="routesJson" />
</div>
</template>
<script>
export default {
data() {
return {
routes: [
{ label: "Home", path: "home" },
{ label: "About", path: "about" }
]
};
},
computed: {
routesJson() {
return JSON.stringify(this.routes);
}
}
};
</script>
```
## ⌨️ Keyboard Shortcuts
| Shortcut | Action |
|----------|--------|
| `Cmd+K` (Mac) / `Ctrl+K` (Win/Linux) | Open/close search dialog |
| `Escape` | Close dialog |
| `↑` / `↓` | Navigate through results |
| `Enter` | Select highlighted result |
| `Click outside` | Close dialog |
## 🎨 Customization
The component uses Shadow DOM for encapsulation, but you can customize the appearance by modifying the CSS variables or extending the component.
### CSS Customization
```javascript
// Extend the component to add custom styles
class CustomRouteSearch extends RouteSearchComponent {
render() {
// Add custom CSS or modify existing styles
const customStyles = `
.route-search-dialog {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
color: white;
}
`;
// Call parent render method or implement custom rendering
super.render();
}
}
```
## 📱 Browser Support
- ✅ Chrome 67+
- ✅ Firefox 63+
- ✅ Safari 10.1+
- ✅ Edge 79+
## 🔍 How It Works
1. **Global Listener**: Component listens for `Cmd+K` / `Ctrl+K` globally
2. **Route Filtering**: Real-time filtering based on user input
3. **Smart Navigation**: Automatically constructs full URLs by prepending `window.location.origin`
4. **Shadow DOM**: Encapsulated styling and behavior
5. **Event Handling**: Proper cleanup and memory management
## 🚨 Important Notes
- **Base URL**: Routes are automatically prepended with `window.location.origin`
- **Global Shortcut**: The keyboard shortcut works globally across the entire application
- **Single Instance**: Only one instance of the component should be active per page
- **Route Format**: Ensure routes have both `label` and `path` properties
## 🐛 Troubleshooting
### Common Issues
1. **Shortcut not working**: Ensure the component script is loaded before use
2. **Routes not showing**: Check that routes data is valid JSON
3. **Navigation issues**: Verify route paths are correct and don't include leading slashes
### Debug Mode
```javascript
// Enable debug logging
const routeSearch = document.querySelector('global-route-search');
if (routeSearch) {
console.log('Routes:', routeSearch.routes);
console.log('Component state:', routeSearch.isOpen);
}
```
## 🤝 Contributing
1. Fork the repository
2. Create a feature branch
3. Make your changes
4. Add tests if applicable
5. Submit a pull request
## 📄 License
MIT License - feel free to use in your projects!
## 🆘 Support
If you encounter any issues or have questions:
1. Check the troubleshooting section
2. Review the integration examples
3. Open an issue on GitHub
4. Check browser console for errors
---
**Happy coding! 🎉**