neostack-explorer / script.js
kbastani's picture
Can you please create a demo for me for a start menu feature for a hypothetical OS or even a SPA that demonstrates a radically different but familiar way to organize and to locate files on a OS? The requirements are this: It is a hierarchical explorer structure but it is modernized by being a single top-level set of beautiful squares with icons inside each (that is the top-level), from there when you click, horizontal stack of squares folds into a single deck and a expanse of icons folds out after the top-level icons become stacked left. Then you can hover over each one of the resulting square icons that have expanded left, which will expand squares with icons down at each second-level icon in the horizontal expanded menu.
e5250e4 verified
// Shared JavaScript across all pages
document.addEventListener('DOMContentLoaded', () => {
// Sample data structure for the explorer
const explorerData = [
{
id: 'documents',
name: 'Documents',
icon: 'folder',
children: [
{
id: 'work',
name: 'Work Projects',
icon: 'briefcase',
children: [
{ id: 'project1', name: 'Q3 Report', icon: 'file-text' },
{ id: 'project2', name: 'Budget Plan', icon: 'dollar-sign' },
{ id: 'project3', name: 'Team Meeting', icon: 'users' }
]
},
{
id: 'personal',
name: 'Personal',
icon: 'heart',
children: [
{ id: 'recipe1', name: 'Pasta Recipe', icon: 'book' },
{ id: 'recipe2', name: 'Travel Plans', icon: 'map' }
]
}
]
},
{
id: 'media',
name: 'Media',
icon: 'image',
children: [
{
id: 'photos',
name: 'Photos',
icon: 'camera',
children: [
{ id: 'vacation', name: 'Vacation 2023', icon: 'sun' },
{ id: 'family', name: 'Family Events', icon: 'home' }
]
},
{
id: 'music',
name: 'Music',
icon: 'music',
children: [
{ id: 'playlists', name: 'My Playlists', icon: 'list' },
{ id: 'favorites', name: 'Favorites', icon: 'star' }
]
}
]
},
{
id: 'applications',
name: 'Applications',
icon: 'grid',
children: [
{
id: 'productivity',
name: 'Productivity',
icon: 'clipboard',
children: [
{ id: 'notes', name: 'Notes App', icon: 'edit' },
{ id: 'calendar', name: 'Calendar', icon: 'calendar' }
]
},
{
id: 'creative',
name: 'Creative Tools',
icon: 'pen-tool',
children: [
{ id: 'design', name: 'Design Studio', icon: 'layout' },
{ id: 'video', name: 'Video Editor', icon: 'film' }
]
}
]
},
{
id: 'downloads',
name: 'Downloads',
icon: 'download',
children: [
{
id: 'software',
name: 'Software',
icon: 'package',
children: [
{ id: 'installer1', name: 'App Installer', icon: 'box' }
]
},
{
id: 'resources',
name: 'Resources',
icon: 'archive',
children: [
{ id: 'template1', name: 'Template Pack', icon: 'file' }
]
}
]
}
];
// Render the explorer
const explorerContainer = document.getElementById('explorer-container');
let currentPath = [];
let currentView = 'top'; // 'top' or 'detail'
function renderTopLevel() {
currentView = 'top';
currentPath = [];
let html = '<div class="explorer-grid">';
explorerData.forEach(item => {
html += `
<div class="explorer-item" data-id="${item.id}">
<i data-feather="${item.icon}" class="explorer-icon"></i>
<div class="explorer-label">${item.name}</div>
</div>
`;
});
html += '</div>';
explorerContainer.innerHTML = html;
feather.replace();
// Add event listeners
document.querySelectorAll('.explorer-item').forEach(item => {
item.addEventListener('click', () => {
const id = item.getAttribute('data-id');
const selectedItem = explorerData.find(d => d.id === id);
if (selectedItem) {
renderDetailLevel(selectedItem);
}
});
});
}
function renderDetailLevel(item) {
currentView = 'detail';
currentPath = [item];
let html = `
<div class="breadcrumb">
<span class="breadcrumb-item" data-action="back">Home</span>
<i data-feather="chevron-right" class="breadcrumb-separator"></i>
<span class="breadcrumb-item active">${item.name}</span>
</div>
<div class="level-container">
<div class="level-stack">
<div class="explorer-item active">
<i data-feather="${item.icon}" class="explorer-icon"></i>
<div class="explorer-label">${item.name}</div>
</div>
</div>
<div class="level-expanded">
`;
item.children.forEach(child => {
html += `
<div class="explorer-item relative" data-id="${child.id}">
<i data-feather="${child.icon}" class="explorer-icon"></i>
<div class="explorer-label">${child.name}</div>
${child.children && child.children.length > 0 ? `
<div class="sublevel-container">
<div class="sublevel-grid">
${child.children.map(sub => `
<div class="explorer-item" data-id="${sub.id}">
<i data-feather="${sub.icon}" class="explorer-icon"></i>
<div class="explorer-label">${sub.name}</div>
</div>
`).join('')}
</div>
</div>
` : ''}
</div>
`;
});
html += `
</div>
</div>
`;
explorerContainer.innerHTML = html;
feather.replace();
// Add event listeners for hover effects
document.querySelectorAll('.level-expanded .explorer-item').forEach(item => {
const sublevel = item.querySelector('.sublevel-container');
if (sublevel) {
item.addEventListener('mouseenter', () => {
sublevel.classList.add('visible');
});
item.addEventListener('mouseleave', () => {
sublevel.classList.remove('visible');
});
}
});
// Add breadcrumb event listener
document.querySelector('.breadcrumb-item[data-action="back"]').addEventListener('click', () => {
renderTopLevel();
});
}
// Initialize the explorer
renderTopLevel();
});