All Downloads are FREE. Search and download functionalities are using the official Maven repository.

lucuma.ui.components.SideTabs.scala Maven / Gradle / Ivy

There is a newer version: 0.123.0
Show newest version
// Copyright (c) 2016-2023 Association of Universities for Research in Astronomy, Inc. (AURA)
// For license information see LICENSE or https://opensource.org/licenses/BSD-3-Clause

package lucuma.ui.components

import cats.syntax.all.*
import crystal.react.View
import eu.timepit.refined.types.string.NonEmptyString
import japgolly.scalajs.react.*
import japgolly.scalajs.react.vdom.html_<^.*
import lucuma.core.util.Display
import lucuma.core.util.Enumerated
import lucuma.react.common.Css
import lucuma.react.common.ReactFnProps
import lucuma.ui.primereact.*
import lucuma.ui.primereact.given
import lucuma.ui.syntax.all.given

/**
 * Component to display side tabs based on an enumerated (Order is important) Each tab can be
 * selected and will be highlighted and it will push a page possibly via Routing
 *
 * The `separatorAfter` function is used to determine if a separator should be displayed after the
 * tab, allowing for the existence of groups
 */
case class SideTabs[A](
  id:             NonEmptyString,
  tab:            View[A],
  pageUrl:        A => String,
  separatorAfter: A => Boolean,
  filterPred:     A => Boolean = (_: A) => true
)(using val enumerated: Enumerated[A], val display: Display[A])
    extends ReactFnProps(SideTabs.component)

object SideTabs:
  private type AnyF[_] = Any

  private type Props[A] = SideTabs[A]

  private def buildComponent[V[_], A] =
    ScalaFnComponent[Props[A]]: p =>
      import p.given

      <.div(
        SideTabsStyles.SideTabs,
        <.div(
          SideTabsStyles.SideTabsVertical,
          SelectButtonEnumView(
            p.id,
            p.tab,
            buttonClass = SideTabsStyles.SideButton,
            filterPred = p.filterPred,
            itemTemplate = tab =>
              <.div(
                SideTabsStyles.RotationWrapperOuter |+|
                  SideTabsStyles.SideTabGroup.when_(p.separatorAfter(tab.value)),
                <.div(
                  SideTabsStyles.RotationWrapperInner,
                  <.a(
                    ^.onClick ==> ((e: ReactEvent) => e.preventDefaultCB),
                    ^.href := p.pageUrl(tab.value),
                    SideTabsStyles.VerticalButton,
                    p.display.shortName(tab.value)
                  )
                )
              )
          )
        ),
        <.div(
          SideTabsStyles.SideTabsHorizontalContainer,
          SelectButtonEnumView(
            p.id,
            p.tab,
            groupClass = SideTabsStyles.SideTabsHorizontal,
            buttonClass = SideTabsStyles.TabSelector,
            filterPred = p.filterPred,
            itemTemplate = tab =>
              <.a(
                ^.onClick ==> ((e: ReactEvent) => e.preventDefaultCB),
                ^.href := p.pageUrl(tab.value),
                p.display.shortName(tab.value)
              )
          )
        )
      )

  private val component = buildComponent[AnyF, Any]

object SideTabsStyles:
  val SideTabs: Css                    = Css("sidetabs")
  val SideTabsVertical: Css            = Css("sidetabs-body-vertical")
  val SideButton: Css                  = Css("side-button")
  val RotationWrapperOuter: Css        = Css("rotation-wrapper-outer")
  val RotationWrapperInner: Css        = Css("rotation-wrapper-inner")
  val SideTabGroup: Css                = Css("side-tabs-group")
  val SideTabsHorizontalContainer: Css = Css("sidetabs-body-horizontal-container")
  val VerticalButton: Css              = Css("vertical-button")
  val SideTabsHorizontal: Css          = Css("sidetabs-body-horizontal")
  val TabSelector: Css                 = Css("bottom-tab-selector")




© 2015 - 2024 Weber Informatics LLC | Privacy Policy