diff --git a/ui/src/main/scala/scommons/client/ui/list/ListBox.scala b/ui/src/main/scala/scommons/client/ui/list/ListBox.scala index da201da..9d10b96 100644 --- a/ui/src/main/scala/scommons/client/ui/list/ListBox.scala +++ b/ui/src/main/scala/scommons/client/ui/list/ListBox.scala @@ -1,31 +1,28 @@ package scommons.client.ui.list -import io.github.shogowada.scalajs.reactjs.React import io.github.shogowada.scalajs.reactjs.React.Self -import io.github.shogowada.scalajs.reactjs.VirtualDOM._ -import io.github.shogowada.scalajs.reactjs.classes.ReactClass import io.github.shogowada.scalajs.reactjs.events.MouseSyntheticEvent import scommons.client.ui.ImageLabelWrapper import scommons.client.ui.list.ListBoxCss._ -import scommons.react.UiComponent +import scommons.react._ case class ListBoxProps(items: List[ListBoxData], selectedIds: Set[String] = Set.empty, onSelect: Set[String] => Unit = _ => ()) -object ListBox extends UiComponent[ListBoxProps] { +object ListBox extends ClassComponent[ListBoxProps] { private type ListBoxSelf = Self[PropsType, ListBoxState] private case class ListBoxState(selectedIds: Set[String]) - protected def create(): ReactClass = React.createClass[PropsType, ListBoxState]( + protected def create(): ReactClass = createClass[ListBoxState]( getInitialState = { self => ListBoxState(self.props.wrapped.selectedIds) }, - componentWillReceiveProps = { (self, nextProps) => - val props = nextProps.wrapped - if (self.props.wrapped.selectedIds != props.selectedIds) { + componentDidUpdate = { (self, prevProps, _) => + val props = self.props.wrapped + if (prevProps.wrapped.selectedIds != props.selectedIds) { self.setState(_.copy(selectedIds = props.selectedIds)) } }, @@ -47,7 +44,7 @@ object ListBox extends UiComponent[ListBoxProps] { ) } - <.div()( + <.>()( items ) } diff --git a/ui/src/test/scala/scommons/client/ui/list/ListBoxSpec.scala b/ui/src/test/scala/scommons/client/ui/list/ListBoxSpec.scala index 491093d..1ae970a 100644 --- a/ui/src/test/scala/scommons/client/ui/list/ListBoxSpec.scala +++ b/ui/src/test/scala/scommons/client/ui/list/ListBoxSpec.scala @@ -1,17 +1,20 @@ package scommons.client.ui.list +import org.scalactic.source.Position +import org.scalajs.dom import scommons.client.ui.list.ListBoxCss._ import scommons.client.ui.{ButtonImagesCss, ImageLabelWrapper} +import scommons.react._ import scommons.react.test.TestSpec -import scommons.react.test.dom.raw.ReactTestUtils -import scommons.react.test.dom.raw.ReactTestUtils._ import scommons.react.test.dom.util.TestDOMUtils import scommons.react.test.raw.ShallowInstance import scommons.react.test.util.ShallowRendererUtils import scala.scalajs.js.Dynamic.literal -class ListBoxSpec extends TestSpec with ShallowRendererUtils with TestDOMUtils { +class ListBoxSpec extends TestSpec + with ShallowRendererUtils + with TestDOMUtils { it should "call onSelect once and select single item when onClick" in { //given @@ -20,8 +23,8 @@ class ListBoxSpec extends TestSpec with ShallowRendererUtils with TestDOMUtils { ListBoxData("1", "Test"), ListBoxData("2", "Test2") ), onSelect = onSelect) - val comp = renderIntoDocument(<(ListBox())(^.wrapped := props)()) - val items = scryRenderedDOMComponentsWithClass(comp, listBoxItem) + domRender(<(ListBox())(^.wrapped := props)()) + val items = domContainer.querySelectorAll(s".$listBoxItem") items.length shouldBe props.items.size val nextSelectIndex = 0 @@ -29,12 +32,16 @@ class ListBoxSpec extends TestSpec with ShallowRendererUtils with TestDOMUtils { onSelect.expects(Set(props.items(nextSelectIndex).id)).once() //when & then - ReactTestUtils.Simulate.click(items(nextSelectIndex), literal(ctrlKey = false, metaKey = false)) - items(nextSelectIndex).className shouldBe s"$listBoxItem $listBoxSelectedItem" + fireDomEvent(Simulate.click(items(nextSelectIndex), literal(ctrlKey = false, metaKey = false))) + items.item(nextSelectIndex).asInstanceOf[dom.Element].getAttribute("class") shouldBe { + s"$listBoxItem $listBoxSelectedItem" + } //when & then - ReactTestUtils.Simulate.click(items(nextSelectIndex), literal(ctrlKey = false, metaKey = false)) - items(nextSelectIndex).className shouldBe s"$listBoxItem $listBoxSelectedItem" + fireDomEvent(Simulate.click(items(nextSelectIndex), literal(ctrlKey = false, metaKey = false))) + items.item(nextSelectIndex).asInstanceOf[dom.Element].getAttribute("class") shouldBe { + s"$listBoxItem $listBoxSelectedItem" + } } it should "select/deselect multiple items when onClick with ctrlKey or metaKey" in { @@ -44,8 +51,8 @@ class ListBoxSpec extends TestSpec with ShallowRendererUtils with TestDOMUtils { ListBoxData("1", "Test"), ListBoxData("2", "Test2") ), onSelect = onSelect) - val comp = renderIntoDocument(<(ListBox())(^.wrapped := props)()) - val items = scryRenderedDOMComponentsWithClass(comp, listBoxItem) + domRender(<(ListBox())(^.wrapped := props)()) + val items = domContainer.querySelectorAll(s".$listBoxItem") items.length shouldBe props.items.size //then @@ -55,41 +62,43 @@ class ListBoxSpec extends TestSpec with ShallowRendererUtils with TestDOMUtils { onSelect.expects(Set.empty[String]) //when & then - ReactTestUtils.Simulate.click(items(0), literal(ctrlKey = true, metaKey = false)) - items(0).className shouldBe s"$listBoxItem $listBoxSelectedItem" + fireDomEvent(Simulate.click(items(0), literal(ctrlKey = true, metaKey = false))) + items.item(0).asInstanceOf[dom.Element].getAttribute("class") shouldBe s"$listBoxItem $listBoxSelectedItem" //when & then - ReactTestUtils.Simulate.click(items(1), literal(ctrlKey = false, metaKey = true)) - items(1).className shouldBe s"$listBoxItem $listBoxSelectedItem" + fireDomEvent(Simulate.click(items(1), literal(ctrlKey = false, metaKey = true))) + items.item(1).asInstanceOf[dom.Element].getAttribute("class") shouldBe s"$listBoxItem $listBoxSelectedItem" //when & then - ReactTestUtils.Simulate.click(items(1), literal(ctrlKey = false, metaKey = true)) - items(1).className shouldBe s"$listBoxItem " + fireDomEvent(Simulate.click(items(1), literal(ctrlKey = false, metaKey = true))) + items.item(1).asInstanceOf[dom.Element].getAttribute("class") shouldBe s"$listBoxItem " //when & then - ReactTestUtils.Simulate.click(items(0), literal(ctrlKey = true, metaKey = false)) - items(0).className shouldBe s"$listBoxItem " + fireDomEvent(Simulate.click(items(0), literal(ctrlKey = true, metaKey = false))) + items.item(0).asInstanceOf[dom.Element].getAttribute("class") shouldBe s"$listBoxItem " } - it should "reset selectedIds when componentWillReceiveProps" in { + it should "reset selectedIds when update" in { //given val prevProps = ListBoxProps(List( ListBoxData("1", "Test"), ListBoxData("2", "Test2") )) - val renderer = createRenderer() - renderer.render(<(ListBox())(^.wrapped := prevProps)()) - val comp = renderer.getRenderOutput() - assertListBox(comp, prevProps) + domRender(<(ListBox())(^.wrapped := prevProps)()) + val items = domContainer.querySelectorAll(s".$listBoxItem") + items.length shouldBe prevProps.items.size + fireDomEvent(Simulate.click(items(1), literal(ctrlKey = false, metaKey = false))) + items.item(0).asInstanceOf[dom.Element].getAttribute("class") shouldBe s"$listBoxItem " + items.item(1).asInstanceOf[dom.Element].getAttribute("class") shouldBe s"$listBoxItem $listBoxSelectedItem" val props = prevProps.copy(selectedIds = Set("1")) //when - renderer.render(<(ListBox())(^.wrapped := props)()) + domRender(<(ListBox())(^.wrapped := props)()) //then - val compV2 = renderer.getRenderOutput() - assertListBox(compV2, props) + items.item(0).asInstanceOf[dom.Element].getAttribute("class") shouldBe s"$listBoxItem $listBoxSelectedItem" + items.item(1).asInstanceOf[dom.Element].getAttribute("class") shouldBe s"$listBoxItem " } it should "render component" in { @@ -98,10 +107,9 @@ class ListBoxSpec extends TestSpec with ShallowRendererUtils with TestDOMUtils { ListBoxData("1", "Test"), ListBoxData("2", "Test2", Some(ButtonImagesCss.accept)) )) - val comp = <(ListBox())(^.wrapped := props)() //when - val result = shallowRender(comp) + val result = shallowRender(<(ListBox())(^.wrapped := props)()) //then assertListBox(result, props) @@ -117,16 +125,15 @@ class ListBoxSpec extends TestSpec with ShallowRendererUtils with TestDOMUtils { ), selectedIds = Set("1", "3") ) - val comp = <(ListBox())(^.wrapped := props)() //when - val result = shallowRender(comp) + val result = shallowRender(<(ListBox())(^.wrapped := props)()) //then assertListBox(result, props) } - private def assertListBox(result: ShallowInstance, props: ListBoxProps): Unit = { + private def assertListBox(result: ShallowInstance, props: ListBoxProps)(implicit pos: Position): Unit = { val expectedItems = props.items.map { data => val selectedClass = if (props.selectedIds.contains(data.id)) listBoxSelectedItem else "" @@ -141,6 +148,6 @@ class ListBoxSpec extends TestSpec with ShallowRendererUtils with TestDOMUtils { ) } - assertNativeComponent(result, <.div()(expectedItems)) + assertNativeComponent(result, <.>()(expectedItems)) } }