Untitled

 avatar
unknown
plain_text
a month ago
7.6 kB
3
Indexable
import SwiftUI

struct DropdownView: View {
    @StateObject var dropdownState = DropdownState()
    let firstOptions: [String]
    let secondOptions: [String]
    let firstPlaceholder: String
    let secondPlaceholder: String
    let selectedOrder: String

    var body: some View {
        ZStack {
            Color.clear
                .contentShape(Rectangle())
                .onTapGesture {
                    dropdownState.isFirstDropdownVisible = false
                    dropdownState.isSecondDropdownVisible = false
                }

            HStack(spacing: 12) {
                
                VStack {
                    GeometryReader { geometry in
                        Button(action: {
                            dropdownState.isFirstDropdownVisible.toggle()
                            dropdownState.isSecondDropdownVisible = false // Close the second dropdown
                        }) {
                            HStack {
                                Text(dropdownState.selectedFirstOption.isEmpty ? firstPlaceholder : dropdownState.selectedFirstOption)
                                
                                    .font(.plusJakartaSans(size: 15, weight: .semibold)).foregroundColor(Color(hex: "#0F172A"))
                                Spacer()
                                Image(systemName: dropdownState.isFirstDropdownVisible ? "chevron.up" : "chevron.down") .foregroundColor(Color(hex: "#A4ACB9"))
                                    .animation(.easeInOut(duration: 0.1), value: dropdownState.isFirstDropdownVisible)

                            }
                            .padding()
                            .frame(maxWidth: .infinity)
                            .frame(height: 36)
                            .background(Color.green.opacity(0.2))
                            .cornerRadius(8)
                            .overlay(
                                RoundedRectangle(cornerRadius: 8)
                                    .stroke(Color.green, lineWidth: 1)
                            )
                        }

                        dropdownState.isFirstDropdownVisible
                                ? DropdownListView(
                                    options: firstOptions,
                                    selectedOption: $dropdownState.selectedFirstOption, selectedOrder: selectedOrder,
                                    isDropdownVisible: $dropdownState.isFirstDropdownVisible,
                                    buttonFrame: geometry.frame(in: .local)
                                ).environmentObject(dropdownState)
                                : nil
                     }
                    .frame(height: 36)
                }

                // Second Dropdown
                VStack {
                    GeometryReader { geometry in
                        Button(action: {
                            dropdownState.isSecondDropdownVisible.toggle()
                            dropdownState.isFirstDropdownVisible = false // Close the first dropdown
                        }) {
                            HStack {
                                Text(dropdownState.selectedSecondOption.isEmpty ? secondPlaceholder : dropdownState.selectedSecondOption) .font(.plusJakartaSans(size: 15, weight: .semibold)).foregroundColor(Color(hex: "#0F172A"))
                                Spacer()
                                Image(systemName: dropdownState.isSecondDropdownVisible ? "chevron.up" : "chevron.down") .foregroundColor(Color(hex: "#A4ACB9"))
                                    .animation(.easeInOut(duration: 0.1), value: dropdownState.isSecondDropdownVisible)

                            }
                            .padding()
                            .frame(maxWidth: .infinity)
                            .frame(height: 36)
                            .background(Color.green.opacity(0.2))
                            .cornerRadius(8)
                            .overlay(
                                RoundedRectangle(cornerRadius: 8)
                                    .stroke(Color.green, lineWidth: 1)
                            )
                        }

                        dropdownState.isSecondDropdownVisible
                                ? DropdownListView(
                                    options: secondOptions,
                                    selectedOption: $dropdownState.selectedSecondOption, selectedOrder: selectedOrder,
                                    isDropdownVisible: $dropdownState.isSecondDropdownVisible,
                                    buttonFrame: geometry.frame(in: .local)
                                )    .environmentObject(dropdownState)

                                : nil
                     }
                    .frame(height: 36)
                }
            }
            .animation(.easeInOut, value: dropdownState.isFirstDropdownVisible || dropdownState.isSecondDropdownVisible)
        }
    }
}

// Dropdown List as Overlay
struct DropdownListView: View {
    let options: [String]
    @Binding var selectedOption: String
    var selectedOrder: String
    @Binding var isDropdownVisible: Bool
    let buttonFrame: CGRect
    @StateObject var dropdownState = DropdownState() // Instantiate the shared state

    var body: some View {
        VStack(spacing: 0) {
            ForEach(options, id: \.self) { option in
                Button(action: {
                    if dropdownState.isSecondDropdownVisible{
                        dropdownState.selectedSecondOption = option
                         selectedOption = option
                        isDropdownVisible = false

                    }else{
                        dropdownState.selectedFirstOption = option
                        selectedOption = option
                        isDropdownVisible = false

                        
                    }
                }) {
                    HStack(spacing: 12) {
                             Image(selectedOption == option ? "Radio_1" : "Radio_Button") .foregroundColor(Color.black)
//                            Spacer()
                            Text(option)
                            .foregroundColor(Color.black)
                        Spacer()
 
                    }
                    .padding()
                   .frame(maxWidth: .infinity)
                   
                }
                .background(Color.white)
                .overlay(
                    Rectangle()
                        .frame(height: 1)
                        .foregroundColor(Color.gray.opacity(0.2)),
                    alignment: .bottom
                )
//

            }
        }
        .background(Color.white)
        .cornerRadius(8)
        .shadow(radius: 4)
        .position(x: buttonFrame.midX, y: buttonFrame.midY + 150) // Position below button
        .zIndex(1) // Ensure it appears above other elements

    }
}

// ObservableObject to store the dropdown state
class DropdownState: ObservableObject {
    @Published var selectedFirstOption: String = ""
    @Published var selectedSecondOption: String = ""
    @Published var isFirstDropdownVisible: Bool = false
    @Published var isSecondDropdownVisible: Bool = false
}

// Preview
struct DropdownView_Previews: PreviewProvider {
 
    static var previews: some View {
        DropdownView(firstOptions: ["Option 1", "Option 2", "Option 3"], secondOptions: ["Filter 1", "Filter 2", "Filter 3"], firstPlaceholder: "Select Sort", secondPlaceholder: "Select Filter", selectedOrder: "")
        .environmentObject(DropdownState())
    }
}
Leave a Comment