feat: Enhance UI components and add command palette
- Updated dropdown component styles and transitions for improved UX. - Refined checkbox, input, radio, select, and textarea components with consistent error messaging and styling. - Introduced a new card component for better layout options. - Added a stat card component for displaying metrics with trends. - Implemented a command palette for global search and navigation, accessible via Cmd/Ctrl+K. - Enhanced modal and navigation components with new styles and transitions. - Improved layout styles for better responsiveness and visual appeal.
This commit is contained in:
@@ -16,37 +16,86 @@ document.addEventListener('livewire:init', () => {
|
||||
|
||||
Alpine.store('notifications', {
|
||||
notifications: [],
|
||||
|
||||
|
||||
init() {
|
||||
Livewire.on('notify', (e) => {
|
||||
this.addNotification(e);
|
||||
});
|
||||
},
|
||||
|
||||
|
||||
addNotification(notification) {
|
||||
notification = notification[0];
|
||||
notification.show = false;
|
||||
notification.id = Date.now() + Math.floor(Math.random() * 1000);
|
||||
notification.type = notification.type || 'success';
|
||||
notification.actions = Array.isArray(notification.actions) ? notification.actions : [];
|
||||
notification.position = notification.position || 'bottom-right';
|
||||
notification.timeout = notification.timeout || 5000;
|
||||
notification.paused = false;
|
||||
notification._remaining = notification.timeout;
|
||||
notification._startedAt = Date.now();
|
||||
this.notifications.push(notification);
|
||||
|
||||
requestAnimationFrame(() => {
|
||||
this.notifications = this.notifications.map(n => {
|
||||
if (n.id === notification.id) {
|
||||
n.show = true;
|
||||
}
|
||||
if (n.id === notification.id) n.show = true;
|
||||
return n;
|
||||
});
|
||||
});
|
||||
|
||||
setTimeout(() => {
|
||||
this.removeNotification(notification.id);
|
||||
}, notification.timeout || 5000);
|
||||
this._scheduleDismiss(notification);
|
||||
},
|
||||
|
||||
|
||||
_scheduleDismiss(n) {
|
||||
if (n._timer) clearTimeout(n._timer);
|
||||
n._startedAt = Date.now();
|
||||
n._timer = setTimeout(() => {
|
||||
if (!n.paused) this.removeNotification(n.id);
|
||||
}, n._remaining);
|
||||
},
|
||||
|
||||
pauseNotification(id) {
|
||||
const n = this.notifications.find(x => x.id === id);
|
||||
if (!n || n.paused) return;
|
||||
n.paused = true;
|
||||
n._remaining -= (Date.now() - n._startedAt);
|
||||
if (n._timer) { clearTimeout(n._timer); n._timer = null; }
|
||||
},
|
||||
|
||||
resumeNotification(id) {
|
||||
const n = this.notifications.find(x => x.id === id);
|
||||
if (!n || !n.paused) return;
|
||||
n.paused = false;
|
||||
this._scheduleDismiss(n);
|
||||
},
|
||||
|
||||
invokeAction(id, actionIdx) {
|
||||
const n = this.notifications.find(x => x.id === id);
|
||||
if (!n) return;
|
||||
const action = n.actions?.[actionIdx];
|
||||
if (!action) return;
|
||||
if (action.event) {
|
||||
const detail = { notificationId: id, payload: action.payload || null };
|
||||
window.dispatchEvent(new CustomEvent(action.event, { detail }));
|
||||
if (window.Livewire && typeof window.Livewire.dispatch === 'function') {
|
||||
try { window.Livewire.dispatch(action.event, [detail]); } catch (_) {}
|
||||
}
|
||||
}
|
||||
if (action.href) {
|
||||
if (window.Livewire && typeof window.Livewire.navigate === 'function') {
|
||||
window.Livewire.navigate(action.href);
|
||||
} else {
|
||||
window.location.href = action.href;
|
||||
}
|
||||
}
|
||||
if (action.dismiss !== false) this.removeNotification(id);
|
||||
},
|
||||
|
||||
removeNotification(id) {
|
||||
this.notifications = this.notifications.filter(n => {
|
||||
if (n.id === id) {
|
||||
n.show = false;
|
||||
if (n._timer) clearTimeout(n._timer);
|
||||
}
|
||||
return n.show;
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user