Skip to content

Commit

Permalink
Focus improvements AND better spacing/placement
Browse files Browse the repository at this point in the history
  • Loading branch information
JPKribs committed Mar 2, 2025
1 parent 3597c73 commit a261c4f
Show file tree
Hide file tree
Showing 4 changed files with 52 additions and 38 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ struct FilterButton: View {
private let role: ButtonRole?
private var onSelect: () -> Void

// MARK: - Button Widths
// MARK: - Button Dimensions

private let collapsedWidth: CGFloat = 75

Expand All @@ -44,11 +44,11 @@ struct FilterButton: View {
// MARK: - Button Styles

private var buttonColor: Color {
isSelected ? ((role == .destructive && isFocused) ? .red : accentColor) : Color.secondarySystemFill
isSelected ? ((role == .destructive && isFocused) ? Color.red.opacity(0.2) : accentColor) : Color.secondarySystemFill
}

private var textColor: Color {
isFocused ? ((role == .destructive) ? Color.red.opacity(0.2) : .black) : .primary
isFocused ? ((role == .destructive) ? .red : .black) : .primary
}

// MARK: - Initializer
Expand Down Expand Up @@ -83,48 +83,53 @@ struct FilterButton: View {
// MARK: - Body

var body: some View {
Button {
onSelect()
} label: {
ZStack(alignment: .leading) {
// Visual background that expands/contracts
Capsule()
.foregroundColor(buttonColor)
.brightness(isFocused ? 0.25 : 0)
.opacity(isFocused ? 1 : 0.5)
.frame(width: isFocused ? expandedWidth : collapsedWidth, height: collapsedWidth)
.overlay {
Capsule()
.stroke(buttonColor, lineWidth: 1)
.brightness(isFocused ? 0.25 : 0)
}
.allowsHitTesting(false)

HStack(spacing: 10) {
if let systemName = systemName {
Image(systemName: systemName)
.hoverEffectDisabled()
.focusEffectDisabled()
.foregroundColor(textColor)
.frame(width: collapsedWidth, alignment: .center)
.focusable(false)
}

if isFocused {
Text(title)
.foregroundColor(textColor)
.transition(.move(edge: .leading).combined(with: .opacity))

Spacer(minLength: 0)
}
}
.font(.footnote.weight(.semibold))
.frame(
width: isFocused ? expandedWidth : collapsedWidth,
height: collapsedWidth,
alignment: .leading
)
.background {
Capsule()
.foregroundColor(buttonColor)
.brightness(isFocused ? 0.25 : 0)
.opacity(isFocused ? 1 : 0.5)
}
.overlay {
Capsule()
.stroke(buttonColor, lineWidth: 1)
.brightness(isFocused ? 0.25 : 0)
.frame(height: collapsedWidth)
.allowsHitTesting(false)

Button {
onSelect()
} label: {
Color.clear
.frame(width: collapsedWidth, height: collapsedWidth)
}
.animation(.easeInOut(duration: 0.25), value: isFocused)
.padding(0)
.buttonStyle(.borderless)
.focused($isFocused)
}
.frame(width: collapsedWidth, height: collapsedWidth, alignment: .leading)
.padding(0)
.buttonStyle(.borderless)
.focused($isFocused)
.animation(.easeIn(duration: 0.2), value: isFocused)
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ struct FilterBar: View {
// MARK: - Body

var body: some View {
VStack {
VStack(spacing: 20) {
if viewModel.currentFilters.hasFilters {
FilterButton(
systemName: "line.3.horizontal.decrease.circle.fill",
Expand All @@ -36,6 +36,9 @@ struct FilterBar: View {
viewModel.send(.reset())
}
.environment(\.isSelected, true)
} else {
Spacer()
.frame(width: 75, height: 75)
}

ForEach(filterTypes, id: \.self) { type in
Expand Down
26 changes: 16 additions & 10 deletions Swiftfin tvOS/Extensions/View/Modifiers/LibraryFilterModifier.swift
Original file line number Diff line number Diff line change
Expand Up @@ -11,42 +11,48 @@ import SwiftUI

struct LibraryFilterModifier<Filters: View, Letters: View>: ViewModifier {

// MARK: - Filter Views

let filters: () -> Filters
let letters: () -> Letters?

// MARK: - Focus State

@FocusState
private var isContentFocused: Bool

// MARK: - State Variables

@State
private var safeArea: EdgeInsets = .zero

private let collapsedWidth: CGFloat = 75
private let expandedWidth: CGFloat = 200

@FocusState
private var isFilterFocused: Bool
// MARK: - Body

func body(content: Content) -> some View {
ZStack {
content
.frame(maxWidth: .infinity, maxHeight: .infinity)
.padding(.leading, collapsedWidth + 20)
.padding(.trailing, collapsedWidth + 20)
.padding(.leading, 100)
.padding(.trailing, LetterPickerBar.size + 20)
.focusSection()

HStack(spacing: 0) {
filters()
.frame(width: (isFilterFocused ? expandedWidth : collapsedWidth) + 10, alignment: .leading)
.frame(alignment: .leading)
.padding(.leading, 20)
.padding(.bottom, safeArea.bottom)
.padding(.top, safeArea.top)
.focusSection()
.focused($isFilterFocused)

Spacer()

if let letterPickerBar = letters() {
letterPickerBar
.frame(width: collapsedWidth, alignment: .center)
.frame(alignment: .leading)
.padding(.trailing, 20)
.padding(.bottom, safeArea.bottom)
.padding(.top, safeArea.top)
.focusSection()
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -275,7 +275,7 @@ struct PagingLibraryView<Element: Poster & Identifiable>: View {
listItemView(item: item, posterType: posterType)
}
}
.onReachedBottomEdge(offset: .offset(300)) {
.onReachedBottomEdge(offset: .rows(3)) {
viewModel.send(.getNextPage)
}
.proxy(collectionVGridProxy)
Expand Down

0 comments on commit a261c4f

Please sign in to comment.