Restore list selection and improve sidebar header clicks

This commit is contained in:
John Burwell 2026-05-29 18:41:25 -05:00
parent f6ab43833c
commit 5a2eea1a3d
2 changed files with 36 additions and 23 deletions

View File

@ -50,11 +50,8 @@ struct ItemListColumnView<MenuContent: View>: View {
.onDrop(of: [UTType.fileURL.identifier], isTargeted: $isDropTargeted, perform: dropAction) .onDrop(of: [UTType.fileURL.identifier], isTargeted: $isDropTargeted, perform: dropAction)
} else { } else {
List(items, selection: $selectedItemID) { item in List(items, selection: $selectedItemID) { item in
ContentRowView(item: item) ContentRowView(item: item, dragProvider: dragProvider)
.tag(item.id) .tag(item.id)
.onDrag {
dragProvider(item)
}
.contextMenu { .contextMenu {
itemContextMenu(item) itemContextMenu(item)
} }
@ -143,10 +140,14 @@ private struct ItemListHeaderView: View {
private struct ContentRowView: View { private struct ContentRowView: View {
let item: MinecraftContentItem let item: MinecraftContentItem
let dragProvider: (MinecraftContentItem) -> NSItemProvider
var body: some View { var body: some View {
HStack(alignment: .center, spacing: 10) { HStack(alignment: .center, spacing: 10) {
ItemThumbnailView(iconURL: item.iconURL) ItemThumbnailView(iconURL: item.iconURL)
.onDrag {
dragProvider(item)
}
VStack(alignment: .leading, spacing: 4) { VStack(alignment: .leading, spacing: 4) {
Text(item.displayName) Text(item.displayName)
@ -164,6 +165,14 @@ private struct ContentRowView: View {
ProgressView() ProgressView()
.controlSize(.small) .controlSize(.small)
} }
Image(systemName: "square.and.arrow.up")
.font(.caption)
.foregroundStyle(.tertiary)
.help("Drag Out as Minecraft Package")
.onDrag {
dragProvider(item)
}
} }
.padding(.vertical, 2) .padding(.vertical, 2)
.contentShape(Rectangle()) .contentShape(Rectangle())

View File

@ -74,6 +74,8 @@ struct SourcesSidebarView: View {
@ViewBuilder @ViewBuilder
private func sourceSectionRows(for source: MinecraftSource) -> some View { private func sourceSectionRows(for source: MinecraftSource) -> some View {
let sourceFilters = filters(source)
SourceHeaderRow( SourceHeaderRow(
source: source, source: source,
isSelected: selection == .source(sourceID: source.id), isSelected: selection == .source(sourceID: source.id),
@ -96,7 +98,7 @@ struct SourcesSidebarView: View {
} }
} }
ForEach(filters(source)) { filter in ForEach(sourceFilters) { filter in
SidebarFilterRow(filter: filter, isIndented: true) SidebarFilterRow(filter: filter, isIndented: true)
.tag(filter.selection as SidebarSelection?) .tag(filter.selection as SidebarSelection?)
} }
@ -154,35 +156,37 @@ private struct SourceHeaderRow: View {
@State private var isHovering = false @State private var isHovering = false
var body: some View { var body: some View {
HStack(spacing: 8) { Button(action: onSelect) {
Image(systemName: headerSymbolName) HStack(spacing: 8) {
.font(.system(size: 14, weight: .semibold)) Image(systemName: headerSymbolName)
.foregroundStyle(titleColor) .font(.system(size: 14, weight: .semibold))
.foregroundStyle(titleColor)
Text(source.displayName) Text(source.displayName)
.font(.subheadline.weight(.semibold)) .font(.subheadline.weight(.semibold))
.foregroundStyle(titleColor) .foregroundStyle(titleColor)
Spacer(minLength: 8) Spacer(minLength: 8)
if let connection { if let connection {
SourceConnectionBadge(connection: connection) SourceConnectionBadge(connection: connection)
} }
if let availabilityBadgeText { if let availabilityBadgeText {
SourceAvailabilityBadge(text: availabilityBadgeText, emphasis: availabilityBadgeEmphasis) SourceAvailabilityBadge(text: availabilityBadgeText, emphasis: availabilityBadgeEmphasis)
} }
if showsStatusIndicator { if showsStatusIndicator {
statusIndicator statusIndicator
.frame(width: 24, height: 24) .frame(width: 24, height: 24)
}
} }
} }
.buttonStyle(.plain)
.padding(.horizontal, 10) .padding(.horizontal, 10)
.padding(.vertical, 8) .padding(.vertical, 8)
.appSidebarRowSurface(isHighlighted: isHovering && !isSelected) .appSidebarRowSurface(isHighlighted: isHovering && !isSelected)
.contentShape(Rectangle()) .contentShape(Rectangle())
.onTapGesture(perform: onSelect)
.onHover { isHovering = $0 } .onHover { isHovering = $0 }
} }