Skip to content
This repository was archived by the owner on Feb 10, 2023. It is now read-only.

Commit 59acf04

Browse files
authored
Merge pull request #191 from toddburnside/accordion-facade
Add facade for Accordion
2 parents 7ba4427 + 2fc500d commit 59acf04

File tree

8 files changed

+592
-0
lines changed

8 files changed

+592
-0
lines changed
Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
package react.semanticui.modules.accordion
2+
3+
import scala.scalajs.js
4+
import js.annotation._
5+
import js.|
6+
import js.JSConverters._
7+
import japgolly.scalajs.react._
8+
import japgolly.scalajs.react.raw.JsNumber
9+
import japgolly.scalajs.react.raw.React
10+
import react.common._
11+
import react.semanticui._
12+
import japgolly.scalajs.react.vdom.TagMod
13+
14+
final case class Accordion(
15+
as: js.UndefOr[AsC] = js.undefined,
16+
activeIndex: js.UndefOr[JsNumber | js.Array[JsNumber]] = js.undefined,
17+
className: js.UndefOr[String] = js.undefined,
18+
clazz: js.UndefOr[Css] = js.undefined,
19+
defaultActiveIndex: js.UndefOr[Int | Seq[Int]] = js.undefined,
20+
exclusive: js.UndefOr[Boolean] = js.undefined,
21+
fluid: js.UndefOr[Boolean] = js.undefined,
22+
inverted: js.UndefOr[Boolean] = js.undefined,
23+
styled: js.UndefOr[Boolean] = js.undefined,
24+
onTitleClickE: js.UndefOr[AccordionTitle.OnClick] = js.undefined,
25+
onTitleClick: js.UndefOr[Callback] = js.undefined,
26+
panels: js.UndefOr[Seq[AccordionPanel]] = js.undefined,
27+
override val modifiers: Seq[TagMod] = Seq.empty
28+
) extends GenericComponentPA[Accordion.AccordionProps, Accordion] {
29+
override protected def cprops = Accordion.props(this)
30+
override protected val component = Accordion.component
31+
override def addModifiers(modifiers: Seq[TagMod]) = copy(modifiers = this.modifiers ++ modifiers)
32+
}
33+
34+
object Accordion {
35+
@js.native
36+
@JSImport("semantic-ui-react", "Accordion")
37+
object RawComponent extends js.Object
38+
39+
@js.native
40+
trait AccordionProps extends js.Object {
41+
@JSBracketAccess
42+
def apply(key: String): js.Any = js.native
43+
44+
@JSBracketAccess
45+
def update(key: String, v: js.Any): Unit = js.native
46+
47+
/** An element type to render as (string or function). */
48+
var as: js.UndefOr[AsT] = js.native
49+
50+
/** Index of the currently active panel. */
51+
var activeIndex: js.UndefOr[JsNumber | js.Array[JsNumber]] = js.native
52+
53+
/** Primary content. */
54+
var children: js.UndefOr[React.Node] = js.native
55+
56+
/** Additional classes. */
57+
var className: js.UndefOr[String] = js.native
58+
59+
/** Initial activeIndex value. */
60+
var defaultActiveIndex: js.UndefOr[JsNumber | js.Array[JsNumber]] = js.native
61+
62+
/** Only allow one panel open at a time. */
63+
var exclusive: js.UndefOr[Boolean] = js.native
64+
65+
/** Format to take up the width of its container . */
66+
var fluid: js.UndefOr[Boolean] = js.native
67+
68+
/** Format for dark backgrounds. */
69+
var inverted: js.UndefOr[Boolean] = js.native
70+
71+
/** Adds some basic styling to accordion panels. */
72+
var styled: js.UndefOr[Boolean] = js.native
73+
74+
/**
75+
* Called when a panel title is clicked.
76+
*
77+
* @param {SyntheticEvent} event - React's original SyntheticEvent.
78+
* @param {AccordionTitleProps} data - All item props.
79+
*/
80+
var onTitleClick: js.UndefOr[AccordionTitle.RawOnClick]
81+
82+
/** Shorthand array of props for Accordion. */
83+
var panels: js.UndefOr[js.Array[AccordionPanel.AccordionPanelProps]] =
84+
js.native
85+
}
86+
87+
def props(q: Accordion): AccordionProps = {
88+
val p = q.as.toJsObject[AccordionProps]
89+
q.as.toJs.foreach(v => p.as = v)
90+
q.activeIndex.foreach(v => p.activeIndex = v)
91+
(q.className, q.clazz).toJs.foreach(v => p.className = v)
92+
q.defaultActiveIndex
93+
.map[JsNumber | js.Array[JsNumber]] { x =>
94+
(x: Any) match {
95+
case p: Int => p
96+
case p => p.asInstanceOf[Seq[JsNumber]].toJSArray
97+
}
98+
}
99+
.foreach(v => p.defaultActiveIndex = v)
100+
q.exclusive.foreach(v => p.exclusive = v)
101+
q.fluid.foreach(v => p.fluid = v)
102+
q.inverted.foreach(v => p.inverted = v)
103+
q.styled.foreach(v => p.styled = v)
104+
(q.onTitleClickE, q.onTitleClick).toJs.foreach(v => p.onTitleClick = v)
105+
q.panels.map(_.map(_.props).toJSArray).foreach(v => p.panels = v)
106+
p
107+
}
108+
109+
private val component = JsComponent[AccordionProps, Children.None, Null](RawComponent)
110+
111+
def apply(ps: AccordionPanel*): Accordion =
112+
new Accordion(panels = ps)
113+
}
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
package react.semanticui.modules.accordion
2+
3+
import scala.scalajs.js
4+
import js.annotation._
5+
import japgolly.scalajs.react._
6+
import japgolly.scalajs.react.raw.React
7+
import japgolly.scalajs.react.vdom.VdomNode
8+
import react.common._
9+
import react.semanticui.raw._
10+
import react.semanticui._
11+
import japgolly.scalajs.react.vdom.TagMod
12+
13+
final case class AccordionContent(
14+
as: js.UndefOr[AsC] = js.undefined,
15+
active: js.UndefOr[Boolean] = js.undefined,
16+
className: js.UndefOr[String] = js.undefined,
17+
clazz: js.UndefOr[Css] = js.undefined,
18+
content: js.UndefOr[ShorthandS[VdomNode]] = js.undefined,
19+
override val modifiers: Seq[TagMod] = Seq.empty
20+
) extends GenericComponentPAC[AccordionContent.AccordionContentProps, AccordionContent] {
21+
override protected def cprops = AccordionContent.props(this)
22+
override protected val component = AccordionContent.component
23+
override def addModifiers(modifiers: Seq[TagMod]) = copy(modifiers = this.modifiers ++ modifiers)
24+
}
25+
26+
object AccordionContent {
27+
@js.native
28+
@JSImport("semantic-ui-react", "AccordionContent")
29+
object RawComponent extends js.Object
30+
31+
@js.native
32+
trait AccordionContentProps extends js.Object {
33+
@JSBracketAccess
34+
def apply(key: String): js.Any = js.native
35+
36+
@JSBracketAccess
37+
def update(key: String, v: js.Any): Unit = js.native
38+
39+
/** An element type to render as (string or function). */
40+
var as: js.UndefOr[AsT] = js.native
41+
42+
/** Whether or not the content is visible. */
43+
var active: js.UndefOr[Boolean] = js.native
44+
45+
/** Primary content. */
46+
var children: js.UndefOr[React.Node] = js.native
47+
48+
/** Additional classes. */
49+
var className: js.UndefOr[String] = js.native
50+
51+
/** Shorthand for primary content. */
52+
var content: js.UndefOr[SemanticShorthandContent] = js.native
53+
}
54+
55+
def props(q: AccordionContent): AccordionContentProps = {
56+
val p = q.as.toJsObject[AccordionContentProps]
57+
q.as.toJs.foreach(v => p.as = v)
58+
q.active.foreach(v => p.active = v)
59+
(q.className, q.clazz).toJs.foreach(v => p.className = v)
60+
q.content.toJs.foreach(v => p.content = v)
61+
p
62+
}
63+
64+
private val component = JsComponent[AccordionContentProps, Children.Varargs, Null](RawComponent)
65+
66+
def apply(c: ShorthandS[VdomNode]): AccordionContent =
67+
new AccordionContent(content = c)
68+
}
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
package react.semanticui.modules.accordion
2+
3+
import scala.scalajs.js
4+
import js.annotation._
5+
import js.|
6+
import japgolly.scalajs.react._
7+
import japgolly.scalajs.react.raw.JsNumber
8+
import react.common._
9+
import react.semanticui._
10+
import react.semanticui.{ raw => suiraw }
11+
12+
final case class AccordionPanel(
13+
active: js.UndefOr[Boolean] = js.undefined,
14+
content: js.UndefOr[ShorthandS[AccordionContent]] = js.undefined,
15+
index: js.UndefOr[JsNumber | String] = js.undefined,
16+
onTitleClickE: js.UndefOr[AccordionTitle.OnClick] = js.undefined,
17+
onTitleClick: js.UndefOr[Callback] = js.undefined,
18+
title: js.UndefOr[ShorthandS[AccordionTitle]] = js.undefined
19+
) extends GenericComponentP[AccordionPanel.AccordionPanelProps] {
20+
override protected def cprops = AccordionPanel.props(this)
21+
override def render: react.common.Render[AccordionPanel.AccordionPanelProps] =
22+
AccordionPanel.component.applyGeneric(rawProps)()
23+
}
24+
25+
object AccordionPanel {
26+
@js.native
27+
@JSImport("semantic-ui-react", "AccordionPanel")
28+
object RawComponent extends js.Object
29+
30+
@js.native
31+
trait AccordionPanelProps extends js.Object {
32+
@JSBracketAccess
33+
def apply(key: String): js.Any = js.native
34+
35+
@JSBracketAccess
36+
def update(key: String, v: js.Any): Unit = js.native
37+
38+
/** Whether or not the title is in the open state. */
39+
var active: js.UndefOr[Boolean] = js.native
40+
41+
/** Shorthand for Accordion.Content. */
42+
var content: js.UndefOr[suiraw.SemanticShorthandItemS[AccordionContent.AccordionContentProps]] =
43+
js.native
44+
45+
/** A panel index. */
46+
var index: js.UndefOr[JsNumber | String] = js.native
47+
48+
/**
49+
* Called when a panel title is clicked.
50+
*
51+
* @param {SyntheticEvent} event - React's original SyntheticEvent.
52+
* @param {AccordionTitleProps} data - All item props.
53+
*/
54+
var onTitleClick: js.UndefOr[AccordionTitle.RawOnClick]
55+
56+
/** A shorthand for Accordion.Title. */
57+
var title: js.UndefOr[suiraw.SemanticShorthandItemS[AccordionTitle.AccordionTitleProps]] =
58+
js.native
59+
}
60+
61+
def props(q: AccordionPanel): AccordionPanelProps = {
62+
val p = (new js.Object).asInstanceOf[AccordionPanelProps]
63+
q.active.foreach(v => p.active = v)
64+
q.content.toJs.foreach(v => p.content = v)
65+
q.index.foreach(v => p.index = v)
66+
(q.onTitleClickE, q.onTitleClick).toJs.foreach(v => p.onTitleClick = v)
67+
q.title.toJs.foreach(v => p.title = v)
68+
p
69+
}
70+
71+
private val component = JsComponent[AccordionPanelProps, Children.None, Null](RawComponent)
72+
}
Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
package react.semanticui.modules.accordion
2+
3+
import scala.scalajs.js
4+
import js.annotation._
5+
import js.|
6+
import japgolly.scalajs.react._
7+
import japgolly.scalajs.react.raw.JsNumber
8+
import japgolly.scalajs.react.raw.React
9+
import japgolly.scalajs.react.vdom.VdomNode
10+
import react.common._
11+
import react.semanticui.raw._
12+
import react.semanticui.elements.icon.Icon
13+
import react.semanticui.elements.icon.Icon.IconProps
14+
import react.semanticui._
15+
import japgolly.scalajs.react.vdom.TagMod
16+
17+
final case class AccordionTitle(
18+
as: js.UndefOr[AsC] = js.undefined,
19+
active: js.UndefOr[Boolean] = js.undefined,
20+
className: js.UndefOr[String] = js.undefined,
21+
clazz: js.UndefOr[Css] = js.undefined,
22+
content: js.UndefOr[ShorthandS[VdomNode]] = js.undefined,
23+
icon: js.UndefOr[ShorthandS[Icon]] = js.undefined,
24+
index: js.UndefOr[JsNumber | String] = js.undefined,
25+
onClickE: js.UndefOr[AccordionTitle.OnClick] = js.undefined,
26+
onClick: js.UndefOr[Callback] = js.undefined,
27+
override val modifiers: Seq[TagMod] = Seq.empty
28+
) extends GenericComponentPAC[AccordionTitle.AccordionTitleProps, AccordionTitle] {
29+
override protected def cprops = AccordionTitle.props(this)
30+
override protected val component = AccordionTitle.component
31+
override def addModifiers(modifiers: Seq[TagMod]) = copy(modifiers = this.modifiers ++ modifiers)
32+
}
33+
34+
object AccordionTitle {
35+
type OnClick = (ReactMouseEvent, AccordionTitleProps) => Callback
36+
type RawOnClick = js.Function2[ReactMouseEvent, AccordionTitleProps, Unit]
37+
38+
@js.native
39+
@JSImport("semantic-ui-react", "AccordionTitle")
40+
object RawComponent extends js.Object
41+
42+
@js.native
43+
trait AccordionTitleProps extends js.Object {
44+
@JSBracketAccess
45+
def apply(key: String): js.Any = js.native
46+
47+
@JSBracketAccess
48+
def update(key: String, v: js.Any): Unit = js.native
49+
50+
/** An element type to render as (string or function). */
51+
var as: js.UndefOr[AsT] = js.native
52+
53+
/** Whether or not the title is in the open state. */
54+
var active: js.UndefOr[Boolean] = js.native
55+
56+
/** Primary content. */
57+
var children: js.UndefOr[React.Node] = js.native
58+
59+
/** Additional classes. */
60+
var className: js.UndefOr[String] = js.native
61+
62+
/** Shorthand for primary content. */
63+
var content: js.UndefOr[SemanticShorthandContent] = js.native
64+
65+
/** Shorthand for Icon. */
66+
var icon: js.UndefOr[SemanticShorthandItemS[IconProps]] = js.native
67+
68+
/** AccordionTitle index inside Accordion. */
69+
var index: js.UndefOr[JsNumber | String] = js.native
70+
71+
/**
72+
* Called on click.
73+
*
74+
* @param {SyntheticEvent} event - React's original SyntheticEvent.
75+
* @param {object} data - All props.
76+
*/
77+
var onClick: js.UndefOr[RawOnClick]
78+
}
79+
80+
def props(q: AccordionTitle): AccordionTitleProps = {
81+
val p = q.as.toJsObject[AccordionTitleProps]
82+
q.as.toJs.foreach(v => p.as = v)
83+
q.active.foreach(v => p.active = v)
84+
(q.className, q.clazz).toJs.foreach(v => p.className = v)
85+
q.content.toJs.foreach(v => p.content = v)
86+
q.icon.toJs.foreach(v => p.icon = v)
87+
q.index.foreach(v => p.index = v)
88+
(q.onClickE, q.onClick).toJs.foreach(v => p.onClick = v)
89+
p
90+
}
91+
92+
private val component =
93+
JsComponent[AccordionTitleProps, Children.Varargs, Null](RawComponent)
94+
95+
def apply(c: ShorthandS[VdomNode]): AccordionTitle =
96+
new AccordionTitle(content = c)
97+
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
package react.semanticui.modules.accordion
2+
3+
import japgolly.scalajs.react.test._
4+
import utest._
5+
6+
object AccordionContentTests extends TestSuite {
7+
val tests = Tests {
8+
test("content") {
9+
val content = AccordionContent(content = "polka")
10+
ReactTestUtils.withNewBodyElement { mountNode =>
11+
content.renderIntoDOM(mountNode)
12+
assert(mountNode.innerHTML == """<div class="content">polka</div>""")
13+
}
14+
}
15+
test("apply") {
16+
val content = AccordionContent("zydeco")
17+
ReactTestUtils.withNewBodyElement { mountNode =>
18+
content.renderIntoDOM(mountNode)
19+
assert(mountNode.innerHTML == """<div class="content">zydeco</div>""")
20+
}
21+
}
22+
test("active") {
23+
val content = AccordionContent(content = "disco", active = true)
24+
ReactTestUtils.withNewBodyElement { mountNode =>
25+
content.renderIntoDOM(mountNode)
26+
assert(mountNode.innerHTML == """<div class="content active">disco</div>""")
27+
}
28+
}
29+
}
30+
}

0 commit comments

Comments
 (0)