@rhavenside/baseline-ui 1.0.19 → 1.0.21

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../src/js/components/modal.js", "../src/js/components/dropdown.js", "../src/js/components/tooltip.js", "../src/js/components/tabs.js", "../src/js/components/alert.js", "../src/js/components/sidebar.js", "../src/js/components/accordion.js", "../src/js/components/toast.js", "../src/js/baseline.js"],
4
- "sourcesContent": ["// ============================================================================\n// Modal Component JavaScript\n// ============================================================================\n\nexport function initModal(modalElement) {\n if (!modalElement) return;\n\n const backdrop = modalElement.querySelector('.bl-modal-backdrop') || document.createElement('div');\n if (!backdrop.classList.contains('bl-modal-backdrop')) {\n backdrop.className = 'bl-modal-backdrop';\n modalElement.insertBefore(backdrop, modalElement.firstChild);\n }\n\n // Open modal buttons\n const modalId = modalElement.id;\n if (modalId) {\n const openButtons = document.querySelectorAll(`[data-modal-open=\"${modalId}\"]`);\n openButtons.forEach(btn => {\n btn.addEventListener('click', () => {\n openModal(modalId);\n });\n });\n }\n\n // Close modal buttons\n const closeButtons = modalElement.querySelectorAll('.bl-modal-close, [data-modal-close]');\n closeButtons.forEach(btn => {\n btn.addEventListener('click', () => {\n closeModal(modalId);\n });\n });\n\n // Close on backdrop click\n backdrop.addEventListener('click', (e) => {\n if (e.target === backdrop) {\n closeModal(modalId);\n }\n });\n\n // Close on ESC key\n const escHandler = (e) => {\n if (e.key === 'Escape' && modalElement.classList.contains('bl-modal-open')) {\n closeModal(modalId);\n }\n };\n document.addEventListener('keydown', escHandler);\n \n // Store handler for cleanup if needed\n modalElement._escHandler = escHandler;\n}\n\nexport function openModal(modalId) {\n const modal = document.getElementById(modalId);\n if (modal) {\n // Remove closing class if present\n modal.classList.remove('bl-modal-closing');\n // Add open class to trigger animation\n modal.classList.add('bl-modal-open');\n document.body.style.overflow = 'hidden';\n }\n}\n\nexport function closeModal(modalId) {\n const modal = document.getElementById(modalId);\n if (modal) {\n // Add closing class to trigger close animation\n modal.classList.add('bl-modal-closing');\n modal.classList.remove('bl-modal-open');\n \n // WICHTIG: Overflow sofort zur\u00FCcksetzen, wenn keine anderen Modals offen sind\n // (Animation l\u00E4uft weiter, aber Scrollen ist wieder m\u00F6glich)\n const openModals = document.querySelectorAll('.bl-modal.bl-modal-open');\n if (openModals.length === 0) {\n document.body.style.overflow = '';\n }\n \n // Wait for animation to complete before cleaning up\n const handleAnimationEnd = () => {\n modal.classList.remove('bl-modal-closing');\n };\n \n // Listen for animation end on dialog (which has the slide animation)\n const dialog = modal.querySelector('.bl-modal-dialog');\n if (dialog) {\n dialog.addEventListener('animationend', handleAnimationEnd, { once: true });\n } else {\n // Fallback: use backdrop animation or timeout\n const backdrop = modal.querySelector('.bl-modal-backdrop');\n if (backdrop) {\n backdrop.addEventListener('animationend', handleAnimationEnd, { once: true });\n } else {\n // Fallback timeout if no animation\n setTimeout(handleAnimationEnd, 200);\n }\n }\n }\n}\n\n", "// ============================================================================\n// Dropdown Component JavaScript\n// ============================================================================\n\nexport function initDropdown(dropdownElement) {\n if (!dropdownElement) return;\n\n const toggle = dropdownElement.querySelector('.bl-dropdown-toggle');\n const menu = dropdownElement.querySelector('.bl-dropdown-menu');\n\n if (!toggle || !menu) return;\n\n toggle.addEventListener('click', (e) => {\n e.preventDefault();\n e.stopPropagation();\n\n // Close all other dropdowns\n document.querySelectorAll('.bl-dropdown-menu.bl-show').forEach(otherMenu => {\n if (otherMenu !== menu) {\n otherMenu.classList.remove('bl-show');\n }\n });\n\n // Toggle current dropdown\n menu.classList.toggle('bl-show');\n });\n\n // Close on outside click\n const outsideClickHandler = (e) => {\n if (!dropdownElement.contains(e.target)) {\n menu.classList.remove('bl-show');\n }\n };\n \n document.addEventListener('click', outsideClickHandler);\n \n // Store handler for cleanup if needed\n dropdownElement._outsideClickHandler = outsideClickHandler;\n}\n\n", "// ============================================================================\n// Tooltip Component JavaScript\n// ============================================================================\n\nexport function initTooltip(tooltipElement) {\n if (!tooltipElement) return;\n\n const trigger = tooltipElement.querySelector('.bl-tooltip-trigger');\n const content = tooltipElement.querySelector('.bl-tooltip-content');\n\n if (!trigger || !content) {\n console.warn('Baseline UI: Tooltip missing trigger or content', tooltipElement);\n return;\n }\n\n // Skip if already initialized\n if (tooltipElement._tooltipInitialized) return;\n\n // Create handlers - use tooltipElement to handle hover on entire tooltip\n const enterHandler = (e) => {\n content.classList.add('bl-show');\n };\n\n const leaveHandler = (e) => {\n // Only hide if mouse leaves the tooltip element (not just the trigger)\n if (!tooltipElement.contains(e.relatedTarget)) {\n content.classList.remove('bl-show');\n }\n };\n\n // Add event listeners to trigger\n trigger.addEventListener('mouseenter', enterHandler);\n trigger.addEventListener('mouseleave', leaveHandler);\n \n // Also handle mouseleave on tooltip element to hide when leaving tooltip area\n tooltipElement.addEventListener('mouseleave', leaveHandler);\n\n // Mark as initialized\n tooltipElement._tooltipInitialized = true;\n tooltipElement._tooltipEnterHandler = enterHandler;\n tooltipElement._tooltipLeaveHandler = leaveHandler;\n}\n\n", "// ============================================================================\n// Tabs Component JavaScript\n// ============================================================================\n\nexport function initTabs(tabsContainer) {\n if (!tabsContainer) return;\n\n const tabLinks = tabsContainer.querySelectorAll('.bl-nav-link[data-tab-target]');\n const tabGroup = tabsContainer.getAttribute('data-tab-group');\n\n tabLinks.forEach(link => {\n link.addEventListener('click', (e) => {\n e.preventDefault();\n\n // Remove active from all tabs in group\n if (tabGroup) {\n document.querySelectorAll(`[data-tab-group=\"${tabGroup}\"] .bl-nav-link`).forEach(l => {\n l.classList.remove('bl-active');\n });\n } else {\n tabsContainer.querySelectorAll('.bl-nav-link').forEach(l => {\n l.classList.remove('bl-active');\n });\n }\n\n // Add active to clicked tab\n link.classList.add('bl-active');\n\n // Show/hide tab content\n const targetId = link.getAttribute('data-tab-target');\n if (targetId) {\n // Find all tab contents - search in parent container or document\n const container = tabsContainer.closest('.docs-example-preview') || \n tabsContainer.parentElement || \n document;\n \n container.querySelectorAll('[data-tab-content]').forEach(content => {\n content.style.display = 'none';\n });\n\n const targetContent = document.getElementById(targetId);\n if (targetContent) {\n targetContent.style.display = 'block';\n }\n }\n });\n });\n}\n\n", "// ============================================================================\n// Alert Component JavaScript\n// ============================================================================\n\nexport function initAlert(alertElement) {\n if (!alertElement) return;\n\n const closeBtn = alertElement.querySelector('.bl-alert-close');\n if (!closeBtn) return;\n\n closeBtn.addEventListener('click', () => {\n dismissAlert(alertElement);\n });\n}\n\nexport function dismissAlert(alertElement) {\n if (!alertElement) return;\n \n alertElement.style.transition = 'opacity 0.3s ease-out';\n alertElement.style.opacity = '0';\n setTimeout(() => {\n alertElement.remove();\n }, 300);\n}\n\n", "// ============================================================================\n// Sidebar Component JavaScript\n// ============================================================================\n\nexport function initSidebar(sidebarElement) {\n if (!sidebarElement) return;\n\n const sidebarId = sidebarElement.id;\n if (!sidebarId) return;\n\n // Create backdrop if it doesn't exist (mobile only)\n let backdrop = document.querySelector('.bl-sidebar-backdrop');\n if (!backdrop) {\n backdrop = document.createElement('div');\n backdrop.className = 'bl-sidebar-backdrop';\n document.body.appendChild(backdrop);\n }\n\n // Close button\n const closeButton = sidebarElement.querySelector('.bl-sidebar-close');\n if (closeButton) {\n closeButton.addEventListener('click', () => {\n closeSidebar(sidebarId);\n });\n }\n\n // Toggle buttons\n const toggleButtons = document.querySelectorAll(`[data-sidebar-toggle=\"${sidebarId}\"]`);\n toggleButtons.forEach(btn => {\n btn.addEventListener('click', () => {\n toggleSidebar(sidebarId);\n });\n });\n\n // Close on backdrop click (mobile only)\n backdrop.addEventListener('click', () => {\n if (isMobile() && sidebarElement.classList.contains('bl-sidebar-open')) {\n closeSidebar(sidebarId);\n }\n });\n\n // Close on ESC key (mobile only)\n const escHandler = (e) => {\n if (e.key === 'Escape' && isMobile() && sidebarElement.classList.contains('bl-sidebar-open')) {\n closeSidebar(sidebarId);\n }\n };\n document.addEventListener('keydown', escHandler);\n \n // Store handler for cleanup if needed\n sidebarElement._escHandler = escHandler;\n\n // Handle window resize (responsive behavior)\n const resizeHandler = () => {\n if (!isMobile() && sidebarElement.classList.contains('bl-sidebar-open')) {\n // On desktop, sidebar is always visible, remove open class\n sidebarElement.classList.remove('bl-sidebar-open');\n }\n };\n window.addEventListener('resize', resizeHandler);\n sidebarElement._resizeHandler = resizeHandler;\n}\n\nexport function toggleSidebar(sidebarId) {\n const sidebar = document.getElementById(sidebarId);\n if (!sidebar) return;\n\n if (sidebar.classList.contains('bl-sidebar-open')) {\n closeSidebar(sidebarId);\n } else {\n openSidebar(sidebarId);\n }\n}\n\nexport function openSidebar(sidebarId) {\n const sidebar = document.getElementById(sidebarId);\n if (!sidebar) return;\n\n sidebar.classList.add('bl-sidebar-open');\n \n // Lock body scroll on mobile\n if (isMobile()) {\n document.body.style.overflow = 'hidden';\n }\n}\n\nexport function closeSidebar(sidebarId) {\n const sidebar = document.getElementById(sidebarId);\n if (!sidebar) return;\n\n sidebar.classList.remove('bl-sidebar-open');\n \n // Unlock body scroll\n document.body.style.overflow = '';\n}\n\n// Helper function to check if mobile\nfunction isMobile() {\n return window.innerWidth < 768;\n}\n\n", "// ============================================================================\n// Accordion Component JavaScript\n// ============================================================================\n\nexport function initAccordion(accordionElement) {\n if (!accordionElement) return;\n\n const items = accordionElement.querySelectorAll('.bl-accordion-item');\n const isSingleMode = accordionElement.classList.contains('bl-accordion-single');\n\n items.forEach(item => {\n const header = item.querySelector('.bl-accordion-header');\n if (!header) return;\n\n header.addEventListener('click', () => {\n toggleAccordionItem(item, isSingleMode, accordionElement);\n });\n });\n}\n\nexport function toggleAccordionItem(itemElement, closeOthers = false, accordionElement = null) {\n if (!itemElement) return;\n\n const isOpen = itemElement.classList.contains('bl-accordion-open');\n\n if (closeOthers && accordionElement) {\n // Close all other items\n const allItems = accordionElement.querySelectorAll('.bl-accordion-item');\n allItems.forEach(item => {\n if (item !== itemElement && item.classList.contains('bl-accordion-open')) {\n item.classList.remove('bl-accordion-open');\n }\n });\n }\n\n // Toggle current item\n if (isOpen) {\n itemElement.classList.remove('bl-accordion-open');\n } else {\n itemElement.classList.add('bl-accordion-open');\n }\n}\n\n", "// ============================================================================\n// Toast Component JavaScript\n// ============================================================================\n\n// Default options\nconst defaultOptions = {\n type: 'info',\n position: 'top-right',\n duration: 5000,\n title: null,\n closable: true\n};\n\n// Get or create toast container\nfunction getToastContainer(position) {\n const containerId = `bl-toast-container-${position}`;\n let container = document.getElementById(containerId);\n \n if (!container) {\n container = document.createElement('div');\n container.id = containerId;\n container.className = `bl-toast-container bl-toast-${position}`;\n document.body.appendChild(container);\n }\n \n return container;\n}\n\n// Create toast element\nfunction createToastElement(message, type, title, closable) {\n const toast = document.createElement('div');\n toast.className = `bl-toast bl-toast-${type}`;\n \n const content = document.createElement('div');\n content.className = 'bl-toast-content';\n \n if (title) {\n const titleEl = document.createElement('div');\n titleEl.className = 'bl-toast-title';\n titleEl.textContent = title;\n content.appendChild(titleEl);\n }\n \n const messageEl = document.createElement('div');\n messageEl.className = 'bl-toast-message';\n messageEl.textContent = message;\n content.appendChild(messageEl);\n \n toast.appendChild(content);\n \n if (closable) {\n const closeBtn = document.createElement('button');\n closeBtn.className = 'bl-toast-close';\n closeBtn.setAttribute('aria-label', 'Close');\n closeBtn.innerHTML = '\u00D7';\n closeBtn.addEventListener('click', () => {\n removeToast(toast);\n });\n toast.appendChild(closeBtn);\n }\n \n return toast;\n}\n\n// Remove toast with animation\nfunction removeToast(toast) {\n toast.classList.add('bl-toast-closing');\n \n toast.addEventListener('animationend', () => {\n toast.remove();\n \n // Remove container if empty\n const container = toast.parentElement;\n if (container && container.classList.contains('bl-toast-container') && container.children.length === 0) {\n container.remove();\n }\n }, { once: true });\n}\n\n// Main showToast function\nexport function showToast(message, type = 'info', options = {}) {\n const opts = { ...defaultOptions, ...options, type };\n const container = getToastContainer(opts.position);\n const toast = createToastElement(message, opts.type, opts.title, opts.closable);\n \n container.appendChild(toast);\n \n // Auto-dismiss after duration\n if (opts.duration > 0) {\n setTimeout(() => {\n if (toast.parentElement) {\n removeToast(toast);\n }\n }, opts.duration);\n }\n \n return toast;\n}\n\n// Convenience functions\nexport function showToastSuccess(message, options = {}) {\n return showToast(message, 'success', { ...options, title: options.title || 'Success' });\n}\n\nexport function showToastError(message, options = {}) {\n return showToast(message, 'error', { ...options, title: options.title || 'Error' });\n}\n\nexport function showToastWarning(message, options = {}) {\n return showToast(message, 'warning', { ...options, title: options.title || 'Warning' });\n}\n\nexport function showToastInfo(message, options = {}) {\n return showToast(message, 'info', { ...options, title: options.title || 'Info' });\n}\n\n", "// ============================================================================\n// Baseline UI JavaScript\n// Main Entry Point\n// ============================================================================\n\nimport { initModal, openModal, closeModal } from './components/modal.js';\nimport { initDropdown } from './components/dropdown.js';\nimport { initTooltip } from './components/tooltip.js';\nimport { initTabs } from './components/tabs.js';\nimport { initAlert, dismissAlert } from './components/alert.js';\nimport { initSidebar, toggleSidebar, openSidebar, closeSidebar } from './components/sidebar.js';\nimport { initAccordion, toggleAccordionItem } from './components/accordion.js';\nimport { showToast, showToastSuccess, showToastError, showToastWarning, showToastInfo } from './components/toast.js';\n\n// Export all functions for manual use\nexport {\n initModal,\n openModal,\n closeModal,\n initDropdown,\n initTooltip,\n initTabs,\n initAlert,\n dismissAlert,\n initSidebar,\n toggleSidebar,\n openSidebar,\n closeSidebar,\n initAccordion,\n toggleAccordionItem,\n showToast,\n showToastSuccess,\n showToastError,\n showToastWarning,\n showToastInfo\n};\n\n// Auto-initialize on DOM ready\nfunction autoInit() {\n // Initialize all modals\n document.querySelectorAll('.bl-modal').forEach(modal => {\n initModal(modal);\n });\n\n // Initialize all dropdowns\n document.querySelectorAll('.bl-dropdown').forEach(dropdown => {\n initDropdown(dropdown);\n });\n\n // Initialize all tooltips\n document.querySelectorAll('.bl-tooltip').forEach(tooltip => {\n initTooltip(tooltip);\n });\n\n // Initialize all tabs\n document.querySelectorAll('.bl-nav-tabs').forEach(tabs => {\n initTabs(tabs);\n });\n\n // Initialize all dismissible alerts\n document.querySelectorAll('.bl-alert-dismissible').forEach(alert => {\n initAlert(alert);\n });\n\n // Initialize all sidebars\n document.querySelectorAll('.bl-sidebar').forEach(sidebar => {\n initSidebar(sidebar);\n });\n\n // Initialize all accordions\n document.querySelectorAll('.bl-accordion').forEach(accordion => {\n initAccordion(accordion);\n });\n}\n\n// Initialize when DOM is ready\n// Use requestAnimationFrame for better timing with ES modules\nif (document.readyState === 'loading') {\n document.addEventListener('DOMContentLoaded', () => {\n // Wait for next frame to ensure all elements are rendered\n requestAnimationFrame(() => {\n requestAnimationFrame(autoInit);\n });\n });\n} else {\n // DOM already loaded, but wait for next frame to ensure everything is ready\n requestAnimationFrame(() => {\n requestAnimationFrame(autoInit);\n });\n}\n\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["// ============================================================================\n// Modal Component JavaScript\n// ============================================================================\n\nexport function initModal(modalElement) {\n if (!modalElement) return;\n\n const backdrop = modalElement.querySelector('.bl-modal-backdrop') || document.createElement('div');\n if (!backdrop.classList.contains('bl-modal-backdrop')) {\n backdrop.className = 'bl-modal-backdrop';\n modalElement.insertBefore(backdrop, modalElement.firstChild);\n }\n\n // Open modal buttons\n const modalId = modalElement.id;\n if (modalId) {\n const openButtons = document.querySelectorAll(`[data-modal-open=\"${modalId}\"]`);\n openButtons.forEach(btn => {\n btn.addEventListener('click', () => {\n openModal(modalId);\n });\n });\n }\n\n // Close modal buttons\n const closeButtons = modalElement.querySelectorAll('.bl-modal-close, [data-modal-close]');\n closeButtons.forEach(btn => {\n btn.addEventListener('click', () => {\n closeModal(modalId);\n });\n });\n\n // Close on backdrop click\n backdrop.addEventListener('click', (e) => {\n if (e.target === backdrop) {\n closeModal(modalId);\n }\n });\n\n // Close on ESC key\n const escHandler = (e) => {\n if (e.key === 'Escape' && modalElement.classList.contains('bl-modal-open')) {\n closeModal(modalId);\n }\n };\n document.addEventListener('keydown', escHandler);\n \n // Store handler for cleanup if needed\n modalElement._escHandler = escHandler;\n}\n\nexport function openModal(modalId) {\n const modal = document.getElementById(modalId);\n if (modal) {\n // Remove closing class if present\n modal.classList.remove('bl-modal-closing');\n // Add open class to trigger animation\n modal.classList.add('bl-modal-open');\n document.body.style.overflow = 'hidden';\n }\n}\n\nexport function closeModal(modalId) {\n const modal = document.getElementById(modalId);\n if (modal) {\n // Add closing class to trigger close animation\n modal.classList.add('bl-modal-closing');\n modal.classList.remove('bl-modal-open');\n \n // WICHTIG: Overflow sofort zur\u00FCcksetzen, wenn keine anderen Modals offen sind\n // (Animation l\u00E4uft weiter, aber Scrollen ist wieder m\u00F6glich)\n const openModals = document.querySelectorAll('.bl-modal.bl-modal-open');\n if (openModals.length === 0) {\n document.body.style.overflow = '';\n }\n \n // Wait for animation to complete before cleaning up\n const handleAnimationEnd = () => {\n modal.classList.remove('bl-modal-closing');\n };\n \n // Listen for animation end on dialog (which has the slide animation)\n const dialog = modal.querySelector('.bl-modal-dialog');\n if (dialog) {\n dialog.addEventListener('animationend', handleAnimationEnd, { once: true });\n } else {\n // Fallback: use backdrop animation or timeout\n const backdrop = modal.querySelector('.bl-modal-backdrop');\n if (backdrop) {\n backdrop.addEventListener('animationend', handleAnimationEnd, { once: true });\n } else {\n // Fallback timeout if no animation\n setTimeout(handleAnimationEnd, 200);\n }\n }\n }\n}\n\n", "// ============================================================================\n// Dropdown Component JavaScript\n// ============================================================================\n\nexport function initDropdown(dropdownElement) {\n if (!dropdownElement) return;\n\n const toggle = dropdownElement.querySelector('.bl-dropdown-toggle');\n const menu = dropdownElement.querySelector('.bl-dropdown-menu');\n\n if (!toggle || !menu) return;\n\n toggle.addEventListener('click', (e) => {\n e.preventDefault();\n e.stopPropagation();\n\n // Close all other dropdowns\n document.querySelectorAll('.bl-dropdown-menu.bl-show').forEach(otherMenu => {\n if (otherMenu !== menu) {\n otherMenu.classList.remove('bl-show');\n }\n });\n\n // Toggle current dropdown\n menu.classList.toggle('bl-show');\n });\n\n // Close on outside click\n const outsideClickHandler = (e) => {\n if (!dropdownElement.contains(e.target)) {\n menu.classList.remove('bl-show');\n }\n };\n \n document.addEventListener('click', outsideClickHandler);\n \n // Store handler for cleanup if needed\n dropdownElement._outsideClickHandler = outsideClickHandler;\n}\n\n", "// ============================================================================\n// Tooltip Component JavaScript\n// ============================================================================\n\nexport function initTooltip(tooltipElement) {\n if (!tooltipElement) return;\n\n const trigger = tooltipElement.querySelector('.bl-tooltip-trigger');\n const content = tooltipElement.querySelector('.bl-tooltip-content');\n\n if (!trigger || !content) {\n console.warn('Baseline UI: Tooltip missing trigger or content', tooltipElement);\n return;\n }\n\n // Skip if already initialized\n if (tooltipElement._tooltipInitialized) return;\n\n // Create handlers - use tooltipElement to handle hover on entire tooltip\n const enterHandler = (e) => {\n content.classList.add('bl-show');\n };\n\n const leaveHandler = (e) => {\n // Only hide if mouse leaves the tooltip element (not just the trigger)\n if (!tooltipElement.contains(e.relatedTarget)) {\n content.classList.remove('bl-show');\n }\n };\n\n // Add event listeners to trigger\n trigger.addEventListener('mouseenter', enterHandler);\n trigger.addEventListener('mouseleave', leaveHandler);\n \n // Also handle mouseleave on tooltip element to hide when leaving tooltip area\n tooltipElement.addEventListener('mouseleave', leaveHandler);\n\n // Mark as initialized\n tooltipElement._tooltipInitialized = true;\n tooltipElement._tooltipEnterHandler = enterHandler;\n tooltipElement._tooltipLeaveHandler = leaveHandler;\n}\n\n", "// ============================================================================\n// Tabs Component JavaScript\n// ============================================================================\n\nexport function initTabs(tabsContainer) {\n if (!tabsContainer) return;\n\n const tabLinks = tabsContainer.querySelectorAll('.bl-nav-link[data-tab-target]');\n const tabGroup = tabsContainer.getAttribute('data-tab-group');\n\n tabLinks.forEach(link => {\n link.addEventListener('click', (e) => {\n e.preventDefault();\n\n // Remove active from all tabs in group\n if (tabGroup) {\n document.querySelectorAll(`[data-tab-group=\"${tabGroup}\"] .bl-nav-link`).forEach(l => {\n l.classList.remove('bl-active');\n });\n } else {\n tabsContainer.querySelectorAll('.bl-nav-link').forEach(l => {\n l.classList.remove('bl-active');\n });\n }\n\n // Add active to clicked tab\n link.classList.add('bl-active');\n\n // Show/hide tab content\n const targetId = link.getAttribute('data-tab-target');\n if (targetId) {\n // Find all tab contents - search in parent container or document\n const container = tabsContainer.closest('.docs-example-preview') || \n tabsContainer.parentElement || \n document;\n \n container.querySelectorAll('[data-tab-content]').forEach(content => {\n content.style.display = 'none';\n });\n\n const targetContent = document.getElementById(targetId);\n if (targetContent) {\n targetContent.style.display = 'block';\n }\n }\n });\n });\n}\n\n", "// ============================================================================\n// Alert Component JavaScript\n// ============================================================================\n\nexport function initAlert(alertElement) {\n if (!alertElement) return;\n\n const closeBtn = alertElement.querySelector('.bl-alert-close');\n if (!closeBtn) return;\n\n closeBtn.addEventListener('click', () => {\n dismissAlert(alertElement);\n });\n}\n\nexport function dismissAlert(alertElement) {\n if (!alertElement) return;\n \n alertElement.style.transition = 'opacity 0.3s ease-out';\n alertElement.style.opacity = '0';\n setTimeout(() => {\n alertElement.remove();\n }, 300);\n}\n\n", "// ============================================================================\n// Sidebar Component JavaScript\n// ============================================================================\n\nexport function initSidebar(sidebarElement) {\n if (!sidebarElement) return;\n\n const sidebarId = sidebarElement.id;\n if (!sidebarId) return;\n\n // Create backdrop if it doesn't exist (mobile only)\n let backdrop = document.querySelector('.bl-sidebar-backdrop');\n if (!backdrop) {\n backdrop = document.createElement('div');\n backdrop.className = 'bl-sidebar-backdrop';\n document.body.appendChild(backdrop);\n }\n\n // Close button\n const closeButton = sidebarElement.querySelector('.bl-sidebar-close');\n if (closeButton) {\n closeButton.addEventListener('click', () => {\n closeSidebar(sidebarId);\n });\n }\n\n // Toggle buttons\n const toggleButtons = document.querySelectorAll(`[data-sidebar-toggle=\"${sidebarId}\"]`);\n toggleButtons.forEach(btn => {\n btn.addEventListener('click', () => {\n toggleSidebar(sidebarId);\n });\n });\n\n // Close on backdrop click (mobile only)\n backdrop.addEventListener('click', () => {\n if (isMobile() && sidebarElement.classList.contains('bl-sidebar-open')) {\n closeSidebar(sidebarId);\n }\n });\n\n // Close on ESC key (mobile only)\n const escHandler = (e) => {\n if (e.key === 'Escape' && isMobile() && sidebarElement.classList.contains('bl-sidebar-open')) {\n closeSidebar(sidebarId);\n }\n };\n document.addEventListener('keydown', escHandler);\n \n // Store handler for cleanup if needed\n sidebarElement._escHandler = escHandler;\n\n // Handle window resize (responsive behavior)\n const resizeHandler = () => {\n if (!isMobile() && sidebarElement.classList.contains('bl-sidebar-open')) {\n // On desktop, sidebar is always visible, remove open class\n sidebarElement.classList.remove('bl-sidebar-open');\n }\n };\n window.addEventListener('resize', resizeHandler);\n sidebarElement._resizeHandler = resizeHandler;\n}\n\nexport function toggleSidebar(sidebarId) {\n const sidebar = document.getElementById(sidebarId);\n if (!sidebar) return;\n\n if (sidebar.classList.contains('bl-sidebar-open')) {\n closeSidebar(sidebarId);\n } else {\n openSidebar(sidebarId);\n }\n}\n\nexport function openSidebar(sidebarId) {\n const sidebar = document.getElementById(sidebarId);\n if (!sidebar) return;\n\n sidebar.classList.add('bl-sidebar-open');\n \n // Add class to body for CSS targeting\n if (isMobile()) {\n document.body.classList.add('bl-sidebar-open');\n document.body.style.overflow = 'hidden';\n }\n}\n\nexport function closeSidebar(sidebarId) {\n const sidebar = document.getElementById(sidebarId);\n if (!sidebar) return;\n\n sidebar.classList.remove('bl-sidebar-open');\n \n // Remove class from body\n document.body.classList.remove('bl-sidebar-open');\n document.body.style.overflow = '';\n}\n\n// Helper function to check if mobile\nfunction isMobile() {\n return window.innerWidth < 768;\n}\n\n", "// ============================================================================\n// Accordion Component JavaScript\n// ============================================================================\n\nexport function initAccordion(accordionElement) {\n if (!accordionElement) return;\n\n const items = accordionElement.querySelectorAll('.bl-accordion-item');\n const isSingleMode = accordionElement.classList.contains('bl-accordion-single');\n\n items.forEach(item => {\n const header = item.querySelector('.bl-accordion-header');\n if (!header) return;\n\n header.addEventListener('click', () => {\n toggleAccordionItem(item, isSingleMode, accordionElement);\n });\n });\n}\n\nexport function toggleAccordionItem(itemElement, closeOthers = false, accordionElement = null) {\n if (!itemElement) return;\n\n const isOpen = itemElement.classList.contains('bl-accordion-open');\n\n if (closeOthers && accordionElement) {\n // Close all other items\n const allItems = accordionElement.querySelectorAll('.bl-accordion-item');\n allItems.forEach(item => {\n if (item !== itemElement && item.classList.contains('bl-accordion-open')) {\n item.classList.remove('bl-accordion-open');\n }\n });\n }\n\n // Toggle current item\n if (isOpen) {\n itemElement.classList.remove('bl-accordion-open');\n } else {\n itemElement.classList.add('bl-accordion-open');\n }\n}\n\n", "// ============================================================================\n// Toast Component JavaScript\n// ============================================================================\n\n// Default options\nconst defaultOptions = {\n type: 'info',\n position: 'top-right',\n duration: 5000,\n title: null,\n closable: true\n};\n\n// Get or create toast container\nfunction getToastContainer(position) {\n const containerId = `bl-toast-container-${position}`;\n let container = document.getElementById(containerId);\n \n if (!container) {\n container = document.createElement('div');\n container.id = containerId;\n container.className = `bl-toast-container bl-toast-${position}`;\n document.body.appendChild(container);\n }\n \n return container;\n}\n\n// Create toast element\nfunction createToastElement(message, type, title, closable) {\n const toast = document.createElement('div');\n toast.className = `bl-toast bl-toast-${type}`;\n \n const content = document.createElement('div');\n content.className = 'bl-toast-content';\n \n if (title) {\n const titleEl = document.createElement('div');\n titleEl.className = 'bl-toast-title';\n titleEl.textContent = title;\n content.appendChild(titleEl);\n }\n \n const messageEl = document.createElement('div');\n messageEl.className = 'bl-toast-message';\n messageEl.textContent = message;\n content.appendChild(messageEl);\n \n toast.appendChild(content);\n \n if (closable) {\n const closeBtn = document.createElement('button');\n closeBtn.className = 'bl-toast-close';\n closeBtn.setAttribute('aria-label', 'Close');\n closeBtn.innerHTML = '\u00D7';\n closeBtn.addEventListener('click', () => {\n removeToast(toast);\n });\n toast.appendChild(closeBtn);\n }\n \n return toast;\n}\n\n// Remove toast with animation\nfunction removeToast(toast) {\n toast.classList.add('bl-toast-closing');\n \n toast.addEventListener('animationend', () => {\n toast.remove();\n \n // Remove container if empty\n const container = toast.parentElement;\n if (container && container.classList.contains('bl-toast-container') && container.children.length === 0) {\n container.remove();\n }\n }, { once: true });\n}\n\n// Main showToast function\nexport function showToast(message, type = 'info', options = {}) {\n const opts = { ...defaultOptions, ...options, type };\n const container = getToastContainer(opts.position);\n const toast = createToastElement(message, opts.type, opts.title, opts.closable);\n \n container.appendChild(toast);\n \n // Auto-dismiss after duration\n if (opts.duration > 0) {\n setTimeout(() => {\n if (toast.parentElement) {\n removeToast(toast);\n }\n }, opts.duration);\n }\n \n return toast;\n}\n\n// Convenience functions\nexport function showToastSuccess(message, options = {}) {\n return showToast(message, 'success', { ...options, title: options.title || 'Success' });\n}\n\nexport function showToastError(message, options = {}) {\n return showToast(message, 'error', { ...options, title: options.title || 'Error' });\n}\n\nexport function showToastWarning(message, options = {}) {\n return showToast(message, 'warning', { ...options, title: options.title || 'Warning' });\n}\n\nexport function showToastInfo(message, options = {}) {\n return showToast(message, 'info', { ...options, title: options.title || 'Info' });\n}\n\n", "// ============================================================================\n// Baseline UI JavaScript\n// Main Entry Point\n// ============================================================================\n\nimport { initModal, openModal, closeModal } from './components/modal.js';\nimport { initDropdown } from './components/dropdown.js';\nimport { initTooltip } from './components/tooltip.js';\nimport { initTabs } from './components/tabs.js';\nimport { initAlert, dismissAlert } from './components/alert.js';\nimport { initSidebar, toggleSidebar, openSidebar, closeSidebar } from './components/sidebar.js';\nimport { initAccordion, toggleAccordionItem } from './components/accordion.js';\nimport { showToast, showToastSuccess, showToastError, showToastWarning, showToastInfo } from './components/toast.js';\n\n// Export all functions for manual use\nexport {\n initModal,\n openModal,\n closeModal,\n initDropdown,\n initTooltip,\n initTabs,\n initAlert,\n dismissAlert,\n initSidebar,\n toggleSidebar,\n openSidebar,\n closeSidebar,\n initAccordion,\n toggleAccordionItem,\n showToast,\n showToastSuccess,\n showToastError,\n showToastWarning,\n showToastInfo\n};\n\n// Auto-initialize on DOM ready\nfunction autoInit() {\n // Initialize all modals\n document.querySelectorAll('.bl-modal').forEach(modal => {\n initModal(modal);\n });\n\n // Initialize all dropdowns\n document.querySelectorAll('.bl-dropdown').forEach(dropdown => {\n initDropdown(dropdown);\n });\n\n // Initialize all tooltips\n document.querySelectorAll('.bl-tooltip').forEach(tooltip => {\n initTooltip(tooltip);\n });\n\n // Initialize all tabs\n document.querySelectorAll('.bl-nav-tabs').forEach(tabs => {\n initTabs(tabs);\n });\n\n // Initialize all dismissible alerts\n document.querySelectorAll('.bl-alert-dismissible').forEach(alert => {\n initAlert(alert);\n });\n\n // Initialize all sidebars\n document.querySelectorAll('.bl-sidebar').forEach(sidebar => {\n initSidebar(sidebar);\n });\n\n // Initialize all accordions\n document.querySelectorAll('.bl-accordion').forEach(accordion => {\n initAccordion(accordion);\n });\n}\n\n// Initialize when DOM is ready\n// Use requestAnimationFrame for better timing with ES modules\nif (document.readyState === 'loading') {\n document.addEventListener('DOMContentLoaded', () => {\n // Wait for next frame to ensure all elements are rendered\n requestAnimationFrame(() => {\n requestAnimationFrame(autoInit);\n });\n });\n} else {\n // DOM already loaded, but wait for next frame to ensure everything is ready\n requestAnimationFrame(() => {\n requestAnimationFrame(autoInit);\n });\n}\n\n"],
5
+ "mappings": "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",
6
6
  "names": ["initModal", "modalElement", "backdrop", "modalId", "btn", "openModal", "closeModal", "e", "escHandler", "modal", "handleAnimationEnd", "dialog", "initDropdown", "dropdownElement", "toggle", "menu", "e", "otherMenu", "outsideClickHandler", "initTooltip", "tooltipElement", "trigger", "content", "enterHandler", "e", "leaveHandler", "initTabs", "tabsContainer", "tabLinks", "tabGroup", "link", "e", "l", "targetId", "content", "targetContent", "initAlert", "alertElement", "closeBtn", "dismissAlert", "initSidebar", "sidebarElement", "sidebarId", "backdrop", "closeButton", "closeSidebar", "btn", "toggleSidebar", "isMobile", "escHandler", "e", "resizeHandler", "sidebar", "openSidebar", "initAccordion", "accordionElement", "items", "isSingleMode", "item", "header", "toggleAccordionItem", "itemElement", "closeOthers", "isOpen", "defaultOptions", "getToastContainer", "position", "containerId", "container", "createToastElement", "message", "type", "title", "closable", "toast", "content", "titleEl", "messageEl", "closeBtn", "removeToast", "showToast", "options", "opts", "showToastSuccess", "showToastError", "showToastWarning", "showToastInfo", "autoInit", "modal", "initModal", "dropdown", "initDropdown", "tooltip", "initTooltip", "tabs", "initTabs", "alert", "initAlert", "sidebar", "initSidebar", "accordion", "initAccordion"]
7
7
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rhavenside/baseline-ui",
3
- "version": "1.0.19",
3
+ "version": "1.0.21",
4
4
  "type": "module",
5
5
  "description": "A technical glass design framework with SCSS source and compiled CSS - minimalist, rectangular forms with milky glass effects",
6
6
  "main": "dist/baseline.css",
@@ -226,27 +226,27 @@
226
226
  // Modal Sizes
227
227
  .bl-modal-sm {
228
228
  .bl-modal-dialog {
229
- @media (min-width: 576px) {
230
- max-width: 300px;
229
+ @media (min-width: 576px) {
230
+ max-width: 300px;
231
231
  }
232
232
  }
233
233
  }
234
234
 
235
235
  .bl-modal-lg {
236
236
  .bl-modal-dialog {
237
- @media (min-width: 1024px) {
238
- max-width: 1000px;
237
+ @media (min-width: 1024px) {
238
+ max-width: 1000px;
239
239
  }
240
240
  }
241
241
  }
242
242
 
243
243
  .bl-modal-xl {
244
244
  .bl-modal-dialog {
245
- @media (min-width: 1024px) {
246
- max-width: 1200px;
247
- }
245
+ @media (min-width: 1024px) {
246
+ max-width: 1200px;
248
247
  }
249
248
  }
249
+ }
250
250
 
251
251
  // Modal Positions - 3x3 Grid
252
252
  // Oben
@@ -52,8 +52,30 @@
52
52
  box-shadow: var(--glass-shadow-lg);
53
53
  transform: translateX(-100%);
54
54
  transition: transform var(--transition-duration-slow) var(--transition-ease-out);
55
- overflow-y: auto;
56
- overflow-x: hidden;
55
+ overflow: hidden; // Let .bl-sidebar-nav handle scrolling
56
+
57
+ // Custom Scrollbar for sidebar container (fallback)
58
+ &::-webkit-scrollbar {
59
+ width: 6px;
60
+ }
61
+
62
+ &::-webkit-scrollbar-track {
63
+ background: transparent;
64
+ }
65
+
66
+ &::-webkit-scrollbar-thumb {
67
+ background: var(--glass-bg-medium);
68
+ border-radius: 3px;
69
+ border: 1px solid var(--glass-border-light);
70
+
71
+ &:hover {
72
+ background: var(--glass-bg-heavy);
73
+ border-color: var(--glass-border-medium);
74
+ }
75
+ }
76
+
77
+ scrollbar-width: thin;
78
+ scrollbar-color: var(--glass-bg-medium) transparent;
57
79
 
58
80
  // Desktop: Always visible, collapsible
59
81
  @media (min-width: 768px) {
@@ -76,11 +98,21 @@
76
98
  width: 64px;
77
99
 
78
100
  .bl-sidebar-header h3,
79
- .bl-sidebar-nav .bl-nav-link span:not(.bl-icon) {
101
+ .bl-sidebar-nav .bl-nav-link span:not(.bl-icon),
102
+ .bl-nav-group-header {
80
103
  opacity: 0;
81
104
  width: 0;
82
105
  overflow: hidden;
83
106
  }
107
+
108
+ .bl-sidebar-nav .bl-nav-link {
109
+ justify-content: center;
110
+ padding: var(--spacing-sm);
111
+
112
+ .bl-icon {
113
+ margin: 0;
114
+ }
115
+ }
84
116
  }
85
117
  }
86
118
 
@@ -106,6 +138,16 @@
106
138
  height: 100vh;
107
139
  min-height: auto;
108
140
  }
141
+
142
+ // On mobile, behave like normal sidebar (with backdrop)
143
+ @media (max-width: 767.98px) {
144
+ position: fixed;
145
+ transform: translateX(-100%);
146
+
147
+ &.bl-sidebar-open {
148
+ transform: translateX(0);
149
+ }
150
+ }
109
151
  }
110
152
  }
111
153
 
@@ -133,6 +175,14 @@
133
175
  }
134
176
  }
135
177
 
178
+ // Show backdrop when body has class (more reliable, works for nested sidebars)
179
+ body.bl-sidebar-open & {
180
+ @media (max-width: 767.98px) {
181
+ opacity: 1;
182
+ pointer-events: all;
183
+ }
184
+ }
185
+
136
186
  // Hide on desktop
137
187
  @media (min-width: 768px) {
138
188
  display: none;
@@ -144,19 +194,29 @@
144
194
  display: flex;
145
195
  align-items: center;
146
196
  justify-content: space-between;
147
- padding: var(--spacing-md);
148
- border-bottom: 1px solid var(--glass-border-light);
197
+ padding: var(--spacing-lg) var(--spacing-md);
198
+ border-bottom: 1px solid var(--glass-border-medium);
149
199
  background: var(--glass-bg-light);
150
200
  backdrop-filter: blur(var(--glass-blur-sm));
151
201
  -webkit-backdrop-filter: blur(var(--glass-blur-sm));
202
+ flex-shrink: 0; // Prevent header from shrinking
152
203
 
153
204
  h3 {
154
205
  margin: 0;
155
- font-size: var(--font-size-lg);
156
- font-weight: var(--font-weight-semibold);
206
+ font-size: var(--font-size-xl);
207
+ font-weight: var(--font-weight-bold);
157
208
  color: var(--color-text);
209
+ line-height: var(--line-height-tight);
158
210
  transition: var(--transition-base);
159
211
  }
212
+
213
+ // Version info styling (if present)
214
+ .bl-sidebar-version {
215
+ font-size: var(--font-size-xs);
216
+ color: var(--color-text-muted);
217
+ font-weight: var(--font-weight-normal);
218
+ margin-top: var(--spacing-xs);
219
+ }
160
220
  }
161
221
 
162
222
  // Sidebar Close Button
@@ -199,10 +259,39 @@
199
259
  // Sidebar Navigation
200
260
  .bl-sidebar-nav {
201
261
  flex: 1;
202
- padding: var(--spacing-sm);
262
+ padding: var(--spacing-md);
203
263
  overflow-y: auto;
204
264
  overflow-x: hidden;
205
265
 
266
+ // Better touch targets on mobile
267
+ @media (max-width: 767.98px) {
268
+ padding: var(--spacing-sm);
269
+ }
270
+
271
+ // Custom Scrollbar (Webkit)
272
+ &::-webkit-scrollbar {
273
+ width: 6px;
274
+ }
275
+
276
+ &::-webkit-scrollbar-track {
277
+ background: transparent;
278
+ }
279
+
280
+ &::-webkit-scrollbar-thumb {
281
+ background: var(--glass-bg-medium);
282
+ border-radius: 3px;
283
+ border: 1px solid var(--glass-border-light);
284
+
285
+ &:hover {
286
+ background: var(--glass-bg-heavy);
287
+ border-color: var(--glass-border-medium);
288
+ }
289
+ }
290
+
291
+ // Firefox Scrollbar
292
+ scrollbar-width: thin;
293
+ scrollbar-color: var(--glass-bg-medium) transparent;
294
+
206
295
  .bl-nav {
207
296
  background: transparent;
208
297
  border: none;
@@ -212,30 +301,127 @@
212
301
  .bl-nav-link {
213
302
  display: flex;
214
303
  align-items: center;
215
- gap: var(--spacing-sm);
304
+ gap: var(--spacing-md);
216
305
  padding: var(--spacing-sm) var(--spacing-md);
306
+ margin-bottom: var(--spacing-xs);
217
307
  border-radius: var(--tech-border-radius-sm);
218
308
  transition: var(--transition-base);
309
+ position: relative;
310
+ font-size: var(--font-size-base);
311
+ line-height: var(--line-height-base);
312
+ color: var(--color-text);
313
+ text-decoration: none;
314
+ min-height: 40px; // Better touch target
315
+
316
+ @media (max-width: 767.98px) {
317
+ padding: var(--spacing-md);
318
+ min-height: 44px; // iOS touch target recommendation
319
+ }
219
320
 
220
321
  span:not(.bl-icon) {
221
322
  transition: var(--transition-base);
323
+ flex: 1;
222
324
  }
223
325
 
224
326
  .bl-icon {
225
327
  flex-shrink: 0;
226
- width: 20px;
227
- height: 20px;
328
+ width: 18px;
329
+ height: 18px;
330
+ color: var(--color-text-muted);
331
+ transition: var(--transition-base);
332
+ }
333
+
334
+ &:hover {
335
+ background: var(--glass-bg-light);
336
+ color: var(--color-text);
337
+ transform: translateX(2px); // Subtle slide animation
338
+
339
+ .bl-icon {
340
+ color: var(--color-text);
341
+ }
342
+ }
343
+
344
+ &:active {
345
+ transform: translateX(1px);
346
+ }
347
+
348
+ &.bl-active {
349
+ background: var(--glass-bg-medium);
350
+ color: var(--color-text);
351
+ font-weight: var(--font-weight-medium);
352
+ padding-left: calc(var(--spacing-md) - 3px);
353
+ transform: translateX(0);
354
+
355
+ &::before {
356
+ content: '';
357
+ position: absolute;
358
+ left: 0;
359
+ top: 0;
360
+ bottom: 0;
361
+ width: 3px;
362
+ background: var(--color-accent);
363
+ border-radius: 0 var(--tech-border-radius-sm) var(--tech-border-radius-sm) 0;
364
+ }
365
+
366
+ .bl-icon {
367
+ color: var(--color-accent);
368
+ }
369
+
370
+ &:hover {
371
+ background: var(--glass-bg-heavy);
372
+ transform: translateX(0); // No slide when active
373
+ }
374
+ }
375
+
376
+ &:focus {
377
+ outline: 1px solid var(--color-border-focus);
378
+ outline-offset: -2px;
228
379
  }
229
380
  }
230
381
  }
231
382
 
383
+ // Navigation Groups (Categories)
384
+ .bl-nav-group {
385
+ margin-bottom: var(--spacing-xl);
386
+
387
+ &:last-child {
388
+ margin-bottom: 0;
389
+ }
390
+
391
+ &:first-child {
392
+ margin-top: 0;
393
+ }
394
+
395
+ // Visual separator between groups (optional)
396
+ + .bl-nav-group {
397
+ padding-top: var(--spacing-md);
398
+ border-top: 1px solid var(--glass-border-light);
399
+ margin-top: var(--spacing-lg);
400
+ }
401
+ }
402
+
403
+ .bl-nav-group-header {
404
+ padding: var(--spacing-sm) var(--spacing-md);
405
+ margin-bottom: var(--spacing-sm);
406
+ margin-top: 0;
407
+ font-size: var(--font-size-xs);
408
+ font-weight: var(--font-weight-semibold);
409
+ color: var(--color-text-muted);
410
+ text-transform: uppercase;
411
+ letter-spacing: var(--letter-spacing-wide);
412
+ line-height: var(--line-height-tight);
413
+ opacity: 0.8; // Subtle appearance
414
+ }
415
+
232
416
  // Sidebar Footer (optional)
233
417
  .bl-sidebar-footer {
234
418
  padding: var(--spacing-md);
235
- border-top: 1px solid var(--glass-border-light);
419
+ border-top: 1px solid var(--glass-border-medium);
236
420
  background: var(--glass-bg-light);
237
421
  backdrop-filter: blur(var(--glass-blur-sm));
238
422
  -webkit-backdrop-filter: blur(var(--glass-blur-sm));
423
+ flex-shrink: 0; // Prevent footer from shrinking
424
+ margin-top: auto; // Push footer to bottom
239
425
  }
240
426
 
241
427
  // Body Scroll Lock (when sidebar is open on mobile)
@@ -78,8 +78,9 @@ export function openSidebar(sidebarId) {
78
78
 
79
79
  sidebar.classList.add('bl-sidebar-open');
80
80
 
81
- // Lock body scroll on mobile
81
+ // Add class to body for CSS targeting
82
82
  if (isMobile()) {
83
+ document.body.classList.add('bl-sidebar-open');
83
84
  document.body.style.overflow = 'hidden';
84
85
  }
85
86
  }
@@ -90,7 +91,8 @@ export function closeSidebar(sidebarId) {
90
91
 
91
92
  sidebar.classList.remove('bl-sidebar-open');
92
93
 
93
- // Unlock body scroll
94
+ // Remove class from body
95
+ document.body.classList.remove('bl-sidebar-open');
94
96
  document.body.style.overflow = '';
95
97
  }
96
98