more fixes
This commit is contained in:
@@ -5,6 +5,8 @@
|
||||
// Alpine.js — powers x-data/x-show/@click in Blade layouts (e.g. cookie banner, toasts).
|
||||
// Guard: don't start a second instance if app.js already loaded Alpine on this page.
|
||||
import Alpine from 'alpinejs';
|
||||
import React from 'react';
|
||||
import { createRoot } from 'react-dom/client';
|
||||
if (!window.Alpine) {
|
||||
window.Alpine = Alpine;
|
||||
Alpine.start();
|
||||
@@ -13,6 +15,52 @@ if (!window.Alpine) {
|
||||
// Gallery navigation context: stores artwork list for prev/next on artwork page
|
||||
import './lib/nav-context.js';
|
||||
|
||||
function mountStoryEditor() {
|
||||
var storyEditorRoot = document.getElementById('story-editor-react-root');
|
||||
if (!storyEditorRoot) return;
|
||||
if (storyEditorRoot.dataset.reactMounted === 'true') return;
|
||||
|
||||
var mode = storyEditorRoot.getAttribute('data-mode') || 'create';
|
||||
var storyRaw = storyEditorRoot.getAttribute('data-story') || '{}';
|
||||
var storyTypesRaw = storyEditorRoot.getAttribute('data-story-types') || '[]';
|
||||
var endpointsRaw = storyEditorRoot.getAttribute('data-endpoints') || '{}';
|
||||
var csrfToken = document.querySelector('meta[name="csrf-token"]')?.getAttribute('content') || '';
|
||||
|
||||
var initialStory = {};
|
||||
var storyTypes = [];
|
||||
var endpoints = {};
|
||||
|
||||
try {
|
||||
initialStory = JSON.parse(storyRaw);
|
||||
storyTypes = JSON.parse(storyTypesRaw);
|
||||
endpoints = JSON.parse(endpointsRaw);
|
||||
} catch (_error) {
|
||||
// If parsing fails, the editor falls back to component defaults.
|
||||
}
|
||||
|
||||
storyEditorRoot.dataset.reactMounted = 'true';
|
||||
|
||||
void import('./components/editor/StoryEditor')
|
||||
.then(function (module) {
|
||||
var StoryEditor = module.default;
|
||||
createRoot(storyEditorRoot).render(
|
||||
React.createElement(StoryEditor, {
|
||||
mode: mode,
|
||||
initialStory: initialStory,
|
||||
storyTypes: storyTypes,
|
||||
endpoints: endpoints,
|
||||
csrfToken: csrfToken,
|
||||
})
|
||||
);
|
||||
})
|
||||
.catch(function () {
|
||||
storyEditorRoot.dataset.reactMounted = 'false';
|
||||
storyEditorRoot.innerHTML = '<div class="rounded-xl border border-rose-700 bg-rose-900/20 p-4 text-rose-200">Failed to load editor. Please refresh the page.</div>';
|
||||
});
|
||||
}
|
||||
|
||||
mountStoryEditor();
|
||||
|
||||
(function () {
|
||||
function initBlurPreviewImages() {
|
||||
var selector = 'img[data-blur-preview]';
|
||||
@@ -115,12 +163,23 @@ import './lib/nav-context.js';
|
||||
return document.getElementById('mobileMenu');
|
||||
}
|
||||
|
||||
function setMobileToggleVisual(isOpen) {
|
||||
var toggle = document.querySelector('[data-mobile-toggle]') || document.getElementById('btnSidebar');
|
||||
if (!toggle) return;
|
||||
|
||||
setExpanded(toggle, !!isOpen);
|
||||
|
||||
var hamburgerIcon = toggle.querySelector('[data-mobile-icon-hamburger]');
|
||||
var closeIcon = toggle.querySelector('[data-mobile-icon-close]');
|
||||
if (hamburgerIcon) hamburgerIcon.classList.toggle('hidden', !!isOpen);
|
||||
if (closeIcon) closeIcon.classList.toggle('hidden', !isOpen);
|
||||
}
|
||||
|
||||
function closeMobileMenu() {
|
||||
var menu = getMobileMenu();
|
||||
if (!menu) return;
|
||||
menu.classList.add('hidden');
|
||||
var toggle = document.querySelector('[data-mobile-toggle]');
|
||||
setExpanded(toggle, false);
|
||||
setMobileToggleVisual(false);
|
||||
}
|
||||
|
||||
function toggleMobileMenu() {
|
||||
@@ -132,8 +191,7 @@ import './lib/nav-context.js';
|
||||
closeMobileMenu();
|
||||
} else {
|
||||
menu.classList.remove('hidden');
|
||||
var toggle = document.querySelector('[data-mobile-toggle]');
|
||||
setExpanded(toggle, true);
|
||||
setMobileToggleVisual(true);
|
||||
closeAllDropdowns();
|
||||
}
|
||||
}
|
||||
@@ -196,6 +254,40 @@ import './lib/nav-context.js';
|
||||
return;
|
||||
}
|
||||
|
||||
var mobileSectionToggle = closest(e.target, '[data-mobile-section-toggle]');
|
||||
if (mobileSectionToggle) {
|
||||
e.preventDefault();
|
||||
|
||||
var panelId = mobileSectionToggle.getAttribute('aria-controls');
|
||||
var panel = panelId ? document.getElementById(panelId) : null;
|
||||
if (!panel) return;
|
||||
|
||||
var wasOpen = !panel.classList.contains('hidden');
|
||||
var menuRoot = getMobileMenu();
|
||||
|
||||
// Keep mobile navigation tidy: close all sections first.
|
||||
if (menuRoot) {
|
||||
menuRoot.querySelectorAll('[data-mobile-section-panel]').forEach(function (el) {
|
||||
el.classList.add('hidden');
|
||||
});
|
||||
menuRoot.querySelectorAll('[data-mobile-section-toggle]').forEach(function (btn) {
|
||||
setExpanded(btn, false);
|
||||
var icon = btn.querySelector('[data-mobile-section-icon]');
|
||||
if (icon) icon.classList.remove('rotate-180');
|
||||
});
|
||||
}
|
||||
|
||||
// If it was closed, open it. If it was open, it stays closed (toggle behavior).
|
||||
if (!wasOpen) {
|
||||
panel.classList.remove('hidden');
|
||||
setExpanded(mobileSectionToggle, true);
|
||||
var currentIcon = mobileSectionToggle.querySelector('[data-mobile-section-icon]');
|
||||
if (currentIcon) currentIcon.classList.add('rotate-180');
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// Submenu toggle (touch/click fallback)
|
||||
var submenuToggle = closest(e.target, '[data-submenu-toggle]');
|
||||
if (submenuToggle) {
|
||||
@@ -237,6 +329,13 @@ import './lib/nav-context.js';
|
||||
if (!closest(e.target, '[data-dropdown]')) {
|
||||
closeAllDropdowns();
|
||||
}
|
||||
|
||||
// Close mobile menu when tapping outside of it and outside the hamburger toggle.
|
||||
var mobileMenu = getMobileMenu();
|
||||
var mobileToggle = closest(e.target, '[data-mobile-toggle]') || closest(e.target, '#btnSidebar');
|
||||
if (mobileMenu && !mobileMenu.classList.contains('hidden') && !mobileToggle && !closest(e.target, '#mobileMenu')) {
|
||||
closeMobileMenu();
|
||||
}
|
||||
});
|
||||
|
||||
// Hover-to-open for desktop pointers
|
||||
|
||||
Reference in New Issue
Block a user