Skip to content

Commit

Permalink
Created Accordion functionality for Bootstrap
Browse files Browse the repository at this point in the history
Added support for Bootstrap Button to add children
Created Card support for Bootstrap
Updated Component.id in HTMLComponent to be assigned to element.id
  • Loading branch information
darkfrog26 committed Oct 16, 2018
1 parent d363968 commit 1caab48
Show file tree
Hide file tree
Showing 8 changed files with 169 additions and 3 deletions.
29 changes: 29 additions & 0 deletions ui/js/src/main/scala/io/youi/component/bootstrap/Accordion.scala
@@ -0,0 +1,29 @@
package io.youi.component.bootstrap

import io.youi.component.{Component, Container, HTMLContainer}
import io.youi.dom
import io.youi.theme.Theme
import org.scalajs.dom.html

class Accordion(element: html.Element) extends HTMLContainer[AccordionEntry](element) with BootstrapComponent[html.Element] {
def this() = {
this(dom.create[html.Div]("div"))
}

override protected def defaultParentTheme: Theme = Container
override def componentType: String = "bootstrap.Accordion"

override protected def init(): Unit = {
super.init()

element.classList.add("accordion")
}

def entry(header: Component,
body: Component,
element: html.Element = dom.create[html.Div]("div")): AccordionEntry = {
val e = new AccordionEntry(this, header, body, element)
children += e
e
}
}
@@ -0,0 +1,42 @@
package io.youi.component.bootstrap

import io.youi.component.{Component, Container}
import io.youi.dom
import io.youi.theme.Theme
import org.scalajs.dom.html

class AccordionEntry(accordion: Accordion,
header: Component,
body: Component,
element: html.Element = dom.create[html.Div]("div")) extends Card(element) {
override protected def defaultParentTheme: Theme = Container
override def componentType: String = "bootstrap.AccordionEntry"

override protected def init(): Unit = {
super.init()

val collapsible = new Container {
classList += "collapse"
data("parent") := s"#${accordion.id()}"
children += new CardBody {
children += body
}
}

val cardHeader = new CardHeader {
children += new Button {
`type` := ButtonType.Link
data("toggle") := "collapse"
data("target") := s"#${collapsible.id()}"
aria("expanded") := "false"
aria("controls") := collapsible.id()
children += header
}
}

collapsible.aria("labelledby") := cardHeader.id()

children += cardHeader
children += collapsible
}
}
@@ -1,12 +1,13 @@
package io.youi.component.bootstrap

import io.youi.component.Container
import io.youi.component.extras.HTMLComponent
import io.youi.dom._
import io.youi.theme.{StyleConnect, StyleProp, Theme}
import io.youi.theme.bootstrap.ButtonTheme
import org.scalajs.dom._

class Button(override val element: html.Button) extends BootstrapComponent[html.Button] with ButtonTheme {
class Button(override val element: html.Button) extends Container with BootstrapComponent[html.Element] with ButtonTheme {
def this() = {
this(create[html.Button]("button"))
}
Expand All @@ -16,6 +17,7 @@ class Button(override val element: html.Button) extends BootstrapComponent[html.
override def componentType: String = "bootstrap.Button"

element.classList.add("btn")
element.setAttribute("type", "button")

lazy val value: StyleProp[String] = style[String]("value", "", StyleConnect.content[String], updatesTransform = true)
}
Expand Down
21 changes: 21 additions & 0 deletions ui/js/src/main/scala/io/youi/component/bootstrap/Card.scala
@@ -0,0 +1,21 @@
package io.youi.component.bootstrap

import io.youi.component.Container
import io.youi.dom
import io.youi.theme.Theme
import org.scalajs.dom.html

class Card(element: html.Element) extends Container(element) with BootstrapComponent[html.Element] {
def this() = {
this(dom.create[html.Div]("div"))
}

override protected def defaultParentTheme: Theme = Container
override def componentType: String = "bootstrap.Card"

override protected def init(): Unit = {
super.init()

element.classList.add("card")
}
}
21 changes: 21 additions & 0 deletions ui/js/src/main/scala/io/youi/component/bootstrap/CardBody.scala
@@ -0,0 +1,21 @@
package io.youi.component.bootstrap

import io.youi.component.Container
import io.youi.dom
import io.youi.theme.Theme
import org.scalajs.dom.html

class CardBody(element: html.Element) extends Container(element) with BootstrapComponent[html.Element] {
def this() = {
this(dom.create[html.Div]("div"))
}

override protected def defaultParentTheme: Theme = Container
override def componentType: String = "bootstrap.CardBody"

override protected def init(): Unit = {
super.init()

element.classList.add("card-body")
}
}
21 changes: 21 additions & 0 deletions ui/js/src/main/scala/io/youi/component/bootstrap/CardHeader.scala
@@ -0,0 +1,21 @@
package io.youi.component.bootstrap

import io.youi.component.Container
import io.youi.dom
import io.youi.theme.Theme
import org.scalajs.dom.html

class CardHeader(element: html.Element) extends Container(element) with BootstrapComponent[html.Element] {
def this() = {
this(dom.create[html.Div]("div"))
}

override protected def defaultParentTheme: Theme = Container
override def componentType: String = "bootstrap.CardHeader"

override protected def init(): Unit = {
super.init()

element.classList.add("card-header")
}
}
Expand Up @@ -18,4 +18,4 @@ class Jumbotron(element: html.Element) extends Container(element) with Bootstrap

element.classList.add("jumbotron")
}
}
}
Expand Up @@ -16,6 +16,11 @@ trait HTMLComponent[E <: html.Element] extends Component with HTMLComponentTheme
override lazy val position: HTMLComponentPosition = new HTMLComponentPosition(this)
override lazy val size: HTMLComponentSize = new HTMLComponentSize(this)

Option(element.getAttribute("id")).foreach {
case "" => // Ignore
case s => id := s
}

lazy val classList: Var[List[String]] = {
val v = Var(element.classList.toList)
v.attach { list =>
Expand All @@ -30,12 +35,22 @@ trait HTMLComponent[E <: html.Element] extends Component with HTMLComponentTheme
v
}

object data {
def apply(name: String): Attribute = new Attribute("data", name)
}
object aria {
def apply(name: String): Attribute = new Attribute("aria", name)
}

override val event: EventSupport = new HTMLEvents(this, element)

override protected def init(): Unit = {
super.init()

element.setAttribute("data-youi-id", id())
id.attachAndFire { s =>
element.setAttribute("data-youi-id", id())
element.setAttribute("id", id())
}

if (this != ui) {
parent.attachAndFire {
Expand All @@ -60,6 +75,21 @@ trait HTMLComponent[E <: html.Element] extends Component with HTMLComponentTheme

override protected def measuredWidth: Double = Measurer.measure(element).width
override protected def measuredHeight: Double = Measurer.measure(element).height

class Attribute(attribute: String, name: String) {
lazy val key: String = s"$attribute-$name"

def apply(): Option[String] = Option(element.getAttribute(key))
def :=(value: String): Unit = element.setAttribute(key, value)
def toVar: Var[Option[String]] = {
val v = Var(apply())
v.attach {
case Some(s) => element.setAttribute(key, s)
case None => element.removeAttribute(key)
}
v
}
}
}

object HTMLComponent extends HTMLComponentTheme {
Expand Down

0 comments on commit 1caab48

Please sign in to comment.