'Custom BANano View class
'Uncomment the events you want to show to the user and implement the HandleEvents in DesignerCreateView
'#Event: Focus (event As BANanoEvent)
'#Event: Blur (event As BANanoEvent)
'#Event: Resize (event As BANanoEvent)
'#Event: Scroll (event As BANanoEvent)
'#Event: Keydown (event As BANanoEvent)
'#Event: KeyPress (event As BANanoEvent)
'#Event: KeyUp (event As BANanoEvent)
#Event: Click (panelID As string)
'#Event: ContextMenu (event As BANanoEvent)
'#Event: Dblclick (event As BANanoEvent)
'#Event: MouseDown (event As BANanoEvent)
'#Event: MouseEnter (event As BANanoEvent)
'#Event: MouseLeave (event As BANanoEvent)
'#Event: MouseMove (event As BANanoEvent)
'#Event: MouseOver (event As BANanoEvent)
'#Event: MouseOut (event As BANanoEvent)
'#Event: MouseUp (event As BANanoEvent)
'#Event: Wheel (event As BANanoEvent)
'#Event: Drag (event As BANanoEvent)
'#Event: DragEnd (event As BANanoEvent)
'#Event: DragEnter (event As BANanoEvent)
'#Event: DragStart (event As BANanoEvent)
'#Event: DragLeave (event As BANanoEvent)
'#Event: DragOver (event As BANanoEvent)
'#Event: Drop (event As BANanoEvent)
'#Event: TouchCancel (event As BANanoEvent)
'#Event: TouchEnd (event As BANanoEvent)
'#Event: TouchEnter (event As BANanoEvent)
'#Event: TouchLeave (event As BANanoEvent)
'#Event: TouchMove (event As BANanoEvent)
'#Event: TouchStart (event As BANanoEvent)
'#Event: Change (event As BANanoEvent)
' Properties that will be show in the ABStract Designer.  They will be passed in the props map in DesignerCreateView (Case Sensitive!)
#DesignerProperty: Key: Classes, DisplayName: Classes, FieldType: String, DefaultValue: , Description: Classes added to the HTML tag.
#DesignerProperty: Key: Style, DisplayName: Style, FieldType: String, DefaultValue: , Description: Styles added to the HTML tag. Must be a json String.
#DesignerProperty: Key: MarginLeft, DisplayName: Margin Left, FieldType: String, DefaultValue: , Description: Margin Left
#DesignerProperty: Key: MarginRight, DisplayName: Margin Right, FieldType: String, DefaultValue: , Description: Margin Right
#DesignerProperty: Key: MarginTop, DisplayName: Margin Top, FieldType: String, DefaultValue: , Description: Margin Top
#DesignerProperty: Key: MarginBottom, DisplayName: Margin Bottom, FieldType: String, DefaultValue: , Description: Margin Bottom
#DesignerProperty: Key: PaddingLeft, DisplayName: Padding Left, FieldType: String, DefaultValue: , Description: Padding Left
#DesignerProperty: Key: PaddingRight, DisplayName: Padding Right, FieldType: String, DefaultValue: , Description: Padding Right
#DesignerProperty: Key: PaddingTop, DisplayName: Padding Top, FieldType: String, DefaultValue: , Description: Padding Top
#DesignerProperty: Key: PaddingBottom, DisplayName: Padding Bottom, FieldType: String, DefaultValue: , Description: Padding Bottom
#DesignerProperty: Key: OnlyOne, DisplayName: Only one open, FieldType: Boolean, DefaultValue: false, Description: Only allow one panel open at the same time
Sub Class_Globals
    Private BANano As BANano 'ignore
    Private mName As String 'ignore
    Private mEventName As String 'ignore
    Private mCallBack As Object 'ignore
    Private mTarget As BANanoElement 'ignore
    Private mElement As BANanoElement 'ignore
 
 
    Private mClasses As String = ""
    Private mStyle As String = ""
    Public MarginLeft As String = ""
    Public MarginRight As String = ""
    Public MarginTop As String = ""
    Public MarginBottom As String = ""
    Public PaddingLeft As String = ""
    Public PaddingRight As String = ""
    Public PaddingTop As String = ""
    Public PaddingBottom As String = ""
    Private mOnlyOne As Boolean = False
    
    Private Checkeds As Map
End Sub
Public Sub Initialize (CallBack As Object, Name As String, EventName As String)
    mName = Name
    mEventName = EventName.ToLowerCase
    mCallBack = CallBack
    
    Checkeds.Initialize
End Sub
' returns the BANanoElement
public Sub getElement() As BANanoElement
    Return mElement
End Sub
' returns the tag id
public Sub getID() As String
    Return mName
End Sub
' this is the place where you create the view in html and run initialize javascript
Public Sub DesignerCreateView (Target As BANanoElement, Props As Map)
    mTarget = Target
    If Props <> Null Then
        mClasses = Props.Get("Classes")
        mStyle = Props.Get("Style")
        MarginLeft = Props.Get("MarginLeft")
        MarginRight = Props.Get("MarginRight")
        MarginTop = Props.Get("MarginTop")
        MarginBottom = Props.Get("MarginBottom")
        PaddingLeft = Props.Get("PaddingLeft")
        PaddingRight = Props.Get("PaddingRight")
        PaddingTop = Props.Get("PaddingTop")
        PaddingBottom = Props.Get("PaddingBottom")
   
        mOnlyOne = Props.Get("OnlyOne")
    End If
 
    Dim exStyle As String = BuildExStyle
 
    mElement = mTarget.Append($"<div id="${mName}" class="skcoll-tabs ${mClasses}" style="${exStyle}${mStyle}">"$).Get("#" & mName)
End Sub
public Sub AddToParent(targetID As String)
    mTarget = BANano.GetElement("#" & targetID.ToLowerCase)
    DesignerCreateView(mTarget, Null)
End Sub
public Sub Remove()
    mTarget.Empty
    BANano.SetMeToNull
End Sub
public Sub Trigger(event As String, params() As String)
    If mElement <> Null Then
        mElement.Trigger(event, params)
    End If
End Sub
public Sub BuildExStyle() As String
    Dim sb As StringBuilder
    sb.Initialize
    If MarginLeft <> "" Then sb.Append("margin-left: " & MarginLeft & ";")
    If MarginRight <> "" Then sb.Append("margin-right: " & MarginRight & ";")
    If MarginTop <> "" Then sb.Append("margin-top: " & MarginTop & ";")
    If MarginBottom <> "" Then sb.Append("margin-bottom: " & MarginBottom & ";")
    If PaddingLeft <> "" Then sb.Append("padding-left: " & PaddingLeft & ";")
    If PaddingRight <> "" Then sb.Append("padding-right: " & PaddingRight & ";")
    If PaddingTop <> "" Then sb.Append("padding-top: " & PaddingTop & ";")
    If PaddingBottom <> "" Then sb.Append("padding-bottom: " & PaddingBottom & ";")
    Return sb.ToString
End Sub
#Region Property Getters and Setters
public Sub setClasses(Classes As String)
    If mElement <> Null Then
        mElement.AddClass(Classes)
    End If
    mClasses = Classes
End Sub
public Sub getClasses() As String
    Return mClasses
End Sub
public Sub setStyle(Style As String)
    If mElement <> Null Then
        mElement.SetStyle(Style)
    End If
    mStyle = Style
End Sub
public Sub getStyle() As String
    Return mStyle
End Sub
#End Region
' add a new panel. Then use GetHeader and GetContent to fill them
public Sub AddPanel(panelID As String, panelStyle As String, HeaderStyle As String, ContentStyle As String)
    mElement.Append($"[BANCLEAN]
        <div id="${mName}${panelID}" class="skcoll-tab" style="${panelStyle}">
            <label id="${mName}${panelID}header" data-panelid="${panelID}" class="skcoll-tab-header" style="${HeaderStyle}"></label>
            <div id="${mName}${panelID}content" class="skcoll-tab-content"  style="${ContentStyle}">
        </div>"$)    
    Dim mElementHeader As BANanoElement
    mElementHeader.Initialize("#" & mName & panelID & "header")
    Dim event As BANanoEvent    
    Checkeds.Put(panelID, False)
    mElementHeader.AddEventListener("click", BANano.CallBack(Me, "HandleClick", event),True)
End Sub
public Sub GetHeader(PanelID As String) As BANanoElement
    Dim tmpElem As BANanoElement
    tmpElem.Initialize("#" & mName & PanelID & "header")
    Return tmpElem
End Sub
public Sub GetContent(PanelID As String) As BANanoElement
    Dim tmpElem As BANanoElement
    tmpElem.Initialize("#" & mName & PanelID & "content")
    Return tmpElem
End Sub
public Sub setOnlyOneOpen(bool As Boolean)
    mOnlyOne = bool
End Sub
public Sub CloseAllPanels()
    Dim inputs() As BANanoElement = mElement.Find(".skcoll-tab-header")
    For i = 0 To inputs.Length - 1
        Dim panelId As String = inputs(i).GetData("panelid")
        inputs(i).RemoveClass("skcoll-input-checked")            
        Checkeds.Put(panelId, False)        
    Next
End Sub
public Sub OpenPanel(panelId As String)
    If mOnlyOne Then
        Dim inputs() As BANanoElement = mElement.Find(".skcoll-tab-header")
        For i = 0 To inputs.Length - 1
            Dim panelId As String = inputs(i).GetData("panelid")
            inputs(i).RemoveClass("skcoll-input-checked")                
            Checkeds.Put(panelId, False)        
        Next
    End If    
    Dim input As BANanoElement
    input.Initialize("#" & mName & panelId & "header")
    input.AddClass("skcoll-input-checked")
    If mOnlyOne Then
        For Each key As String In Checkeds.Keys
            Checkeds.Put(key, False)
        Next
    End If
    Checkeds.Put(panelId, True)
End Sub
#Region Internal Events
private Sub HandleClick(event As BANanoEvent) 'ignore    
    Dim tmpElem As BANanoElement
    tmpElem.Initialize(event.Target)
    Dim panelID As String = tmpElem.GetData("panelid")
    If panelID = Null Then
        Dim elems() As BANanoElement = tmpElem.Closest("label")
        If elems.Length > 0 Then
            panelID = elems(0).GetData("panelid")
        End If
    End If
    Dim WasOpen As Boolean = Checkeds.Get(panelID)
    If mOnlyOne Then
        Dim inputs() As BANanoElement = mElement.Find(".skcoll-tab-header")
        For i = 0 To inputs.Length - 1
            Dim panelID2 As String = inputs(i).GetData("panelid")
            inputs(i).RemoveClass("skcoll-input-checked")
            Checkeds.Put(panelID2, False)            
        Next
    End If    
    tmpElem.Initialize("#" & mName & panelID & "header")
    If WasOpen = False Then
        tmpElem.AddClass("skcoll-input-checked")
        Checkeds.Put(panelID, True)
    Else
        tmpElem.RemoveClass("skcoll-input-checked")
        Checkeds.Put(panelID, False)
    End If
    BANano.CallSub(mCallBack, mEventName & "_click", Array(panelID))
End Sub
#End Region
#if CSS
.skcoll-input {
  position: absolute;
  opacity: 0;
  z-index: -1;
}
.skcoll-tabs {
  overflow: hidden;
}
.skcoll-tab {
  width: 100%;
  overflow: hidden;
}
.skcoll-tab-header {
  display: flex;
  justify-content: space-between;
  padding: 1em;
  cursor: pointer;
}
.skcoll-tab-header::after {
  content: "❯";
  width: 1em;
  height: 1em;
  text-align: center;
  transition: all 0.35s;
}
.skcoll-tab-content {
  max-height: 0;
  padding: 0 1em;
  transition: all 0.35s;
}
.skcoll-input-checked + .skcoll-tab-header::after {
  transform: rotate(90deg);
}
.skcoll-input-checked ~ .skcoll-tab-content {
  max-height: 100vh;
  padding: 1em;
}
#End If