Internal tooling for Mac utility for storage management.
Swift
98.7%
JSON
1.1%
Markdown
0.2%
//
// DetailPanelView.swift
// MUA
//
// Created by Mitchel Volkering on 21/12/2025.
//
import SwiftUI
/// Shows detailed info about the selected item
struct DetailPanelView: View {
let item: FileItem?
var body: some View {
Group {
if let item = item {
ScrollView {
VStack(alignment: .leading, spacing: 20) {
// Header with icon and name
headerSection(item)
Divider()
// Size information
sizeSection(item)
if item.isDirectory && !item.children.isEmpty {
Divider()
childrenSection(item)
}
Divider()
// Path info
pathSection(item)
Spacer()
}
.padding()
}
} else {
emptyState
}
}
.frame(minWidth: 260, idealWidth: 280, maxWidth: 320)
.background(.regularMaterial)
}
private func headerSection(_ item: FileItem) -> some View {
HStack(spacing: 16) {
// Large icon with glass effect
ZStack {
Circle()
.fill(
.linearGradient(
colors: [
item.color.opacity(0.6),
item.color.opacity(0.3)
],
startPoint: .topLeading,
endPoint: .bottomTrailing
)
)
.frame(width: 64, height: 64)
.overlay(
Circle()
.fill(
.linearGradient(
colors: [.white.opacity(0.3), .clear],
startPoint: .topLeading,
endPoint: .center
)
)
)
.overlay(
Circle()
.strokeBorder(.white.opacity(0.3), lineWidth: 1)
)
.shadow(color: item.color.opacity(0.3), radius: 8)
Image(systemName: item.icon)
.font(.system(size: 28))
.foregroundStyle(.white)
}
VStack(alignment: .leading, spacing: 4) {
Text(item.name)
.font(.headline)
.lineLimit(2)
Text(item.isDirectory ? "Folder" : item.url.pathExtension.uppercased())
.font(.subheadline)
.foregroundStyle(.secondary)
}
}
}
private func sizeSection(_ item: FileItem) -> some View {
VStack(alignment: .leading, spacing: 12) {
Text("Size")
.font(.subheadline)
.foregroundStyle(.secondary)
HStack(alignment: .firstTextBaseline) {
Text(item.formattedSize)
.font(.system(size: 28, weight: .semibold, design: .rounded))
if item.parent != nil {
Text("(\(String(format: "%.1f", item.percentageOfParent()))% of parent)")
.font(.caption)
.foregroundStyle(.secondary)
}
}
if item.isDirectory {
HStack {
Label("\(item.children.count) items", systemImage: "doc.on.doc")
if item.descendantCount > item.children.count {
Text("(\(item.descendantCount) total)")
.foregroundStyle(.tertiary)
}
}
.font(.caption)
.foregroundStyle(.secondary)
}
}
}
private func childrenSection(_ item: FileItem) -> some View {
VStack(alignment: .leading, spacing: 12) {
Text("Largest Items")
.font(.subheadline)
.foregroundStyle(.secondary)
ForEach(item.topChildren(count: 5)) { child in
HStack {
Image(systemName: child.icon)
.foregroundStyle(child.color)
.frame(width: 20)
Text(child.name)
.lineLimit(1)
.truncationMode(.middle)
Spacer()
Text(child.formattedSize)
.font(.caption)
.foregroundStyle(.secondary)
}
.font(.caption)
}
}
}
private func pathSection(_ item: FileItem) -> some View {
VStack(alignment: .leading, spacing: 8) {
Text("Location")
.font(.subheadline)
.foregroundStyle(.secondary)
Text(item.url.path)
.font(.caption)
.foregroundStyle(.tertiary)
.lineLimit(3)
.textSelection(.enabled)
Button("Show in Finder") {
NSWorkspace.shared.selectFile(item.url.path, inFileViewerRootedAtPath: item.url.deletingLastPathComponent().path)
}
.buttonStyle(.link)
.font(.caption)
}
}
private var emptyState: some View {
VStack(spacing: 12) {
Image(systemName: "square.dashed")
.font(.system(size: 40))
.foregroundStyle(.quaternary)
Text("Select an item")
.font(.subheadline)
.foregroundStyle(.secondary)
Text("Click a bubble to see details")
.font(.caption)
.foregroundStyle(.tertiary)
}
.frame(maxWidth: .infinity, maxHeight: .infinity)
}
}
#Preview("With Item") {
let parent = FileItem(url: URL(fileURLWithPath: "/Users"), isDirectory: true, size: 100_000_000_000)
let item = FileItem(
url: URL(fileURLWithPath: "/Users/mitchel"),
isDirectory: true,
size: 45_000_000_000,
children: [
FileItem(url: URL(fileURLWithPath: "/Users/mitchel/Documents"), isDirectory: true, size: 15_000_000_000),
FileItem(url: URL(fileURLWithPath: "/Users/mitchel/Downloads"), isDirectory: true, size: 12_000_000_000),
FileItem(url: URL(fileURLWithPath: "/Users/mitchel/Library"), isDirectory: true, size: 8_000_000_000),
FileItem(url: URL(fileURLWithPath: "/Users/mitchel/movie.mp4"), isDirectory: false, size: 5_000_000_000),
],
parent: parent
)
DetailPanelView(item: item)
.frame(height: 500)
}
#Preview("Empty") {
DetailPanelView(item: nil)
.frame(height: 400)
}
About
Internal tooling for Mac utility for storage management.
0 stars
0 forks