diff --git a/TODO.md b/TODO.md
index a4cf9ad..7dda2c0 100644
--- a/TODO.md
+++ b/TODO.md
@@ -13,7 +13,7 @@
- [ ] di bug: @Singleton toSelf() causes stack overflow
## 0.1.1
-- [ ] `Switch` and `Case` components
+- [x] `Switch` and `Case` components
- [x] Fix bug with multiline nested component attributes.
- [ ] `Each` with `Map`
- [ ] `Each` with children in addition to `render`
diff --git a/web-view-components/src/main/groovy/groowt/view/component/web/DefaultWebViewComponentScope.groovy b/web-view-components/src/main/groovy/groowt/view/component/web/DefaultWebViewComponentScope.groovy
index 9b8c021..030cabe 100644
--- a/web-view-components/src/main/groovy/groowt/view/component/web/DefaultWebViewComponentScope.groovy
+++ b/web-view-components/src/main/groovy/groowt/view/component/web/DefaultWebViewComponentScope.groovy
@@ -10,8 +10,11 @@ class DefaultWebViewComponentScope extends DefaultComponentScope implements WebV
static DefaultWebViewComponentScope getDefaultRootScope() {
new DefaultWebViewComponentScope().tap {
- addWithAttr(Echo)
+ addWithAttr(Case)
+ addWithAttr(DefaultCase)
addWithAttr(Each)
+ addWithAttr(Echo)
+ addWithAttr(Switch)
addWithAttr(WhenNotEmpty)
addWithAttr(WhenNotNull)
}
diff --git a/web-view-components/src/main/groovy/groowt/view/component/web/lib/Case.groovy b/web-view-components/src/main/groovy/groowt/view/component/web/lib/Case.groovy
new file mode 100644
index 0000000..ad5c99c
--- /dev/null
+++ b/web-view-components/src/main/groovy/groowt/view/component/web/lib/Case.groovy
@@ -0,0 +1,26 @@
+package groowt.view.component.web.lib
+
+import groowt.view.View
+import groowt.view.component.runtime.DefaultComponentWriter
+
+class Case extends DelegatingWebViewComponent {
+
+ private final Object match
+
+ Case(Map attr) {
+ match = attr.match
+ }
+
+ @Override
+ protected View getDelegate() {
+ return { Writer w ->
+ def parent = context.getParent(Switch)
+ if (!parent.doneYet && match == parent.item) {
+ parent.doneYet = true
+ def cw = new DefaultComponentWriter(w, context.renderContext, context)
+ children.each { cw << it }
+ }
+ }
+ }
+
+}
diff --git a/web-view-components/src/main/groovy/groowt/view/component/web/lib/DefaultCase.groovy b/web-view-components/src/main/groovy/groowt/view/component/web/lib/DefaultCase.groovy
new file mode 100644
index 0000000..fabea85
--- /dev/null
+++ b/web-view-components/src/main/groovy/groowt/view/component/web/lib/DefaultCase.groovy
@@ -0,0 +1,20 @@
+package groowt.view.component.web.lib
+
+import groowt.view.View
+import groowt.view.component.runtime.DefaultComponentWriter
+
+class DefaultCase extends DelegatingWebViewComponent {
+
+ @Override
+ protected View getDelegate() {
+ return { Writer w ->
+ def parent = context.getParent(Switch)
+ if (!parent.doneYet) {
+ parent.doneYet = true
+ def cw = new DefaultComponentWriter(w, context.renderContext, context)
+ children.each { cw << it }
+ }
+ }
+ }
+
+}
diff --git a/web-view-components/src/main/groovy/groowt/view/component/web/lib/Switch.groovy b/web-view-components/src/main/groovy/groowt/view/component/web/lib/Switch.groovy
new file mode 100644
index 0000000..6bdd6d3
--- /dev/null
+++ b/web-view-components/src/main/groovy/groowt/view/component/web/lib/Switch.groovy
@@ -0,0 +1,23 @@
+package groowt.view.component.web.lib
+
+import groowt.view.View
+import groowt.view.component.runtime.DefaultComponentWriter
+
+class Switch extends DelegatingWebViewComponent {
+
+ final Object item
+ boolean doneYet
+
+ Switch(Map attr) {
+ item = attr.item
+ }
+
+ @Override
+ protected View getDelegate() {
+ return { Writer w ->
+ def cw = new DefaultComponentWriter(w, context.renderContext, context)
+ children.each { cw << it }
+ }
+ }
+
+}
diff --git a/web-view-components/src/test/groovy/groowt/view/component/web/lib/SwitchTests.groovy b/web-view-components/src/test/groovy/groowt/view/component/web/lib/SwitchTests.groovy
new file mode 100644
index 0000000..c15b7c4
--- /dev/null
+++ b/web-view-components/src/test/groovy/groowt/view/component/web/lib/SwitchTests.groovy
@@ -0,0 +1,44 @@
+package groowt.view.component.web.lib
+
+import org.junit.jupiter.api.Test
+
+class SwitchTests extends AbstractWebViewComponentTests {
+
+ @Test
+ void smokeScreen() {
+ doTest('', '')
+ }
+
+ @Test
+ void simpleCase() {
+ doTest(
+ 'Hello, World!',
+ 'Hello, World!'
+ )
+ }
+
+ @Test
+ void multipleCases() {
+ doTest('''
+
+ Hello, Jupiter!
+ Hello, Mars!
+
+ '''.trim(),
+ 'Hello, Mars!'
+ )
+ }
+
+ @Test
+ void withDefaultCase() {
+ doTest('''
+
+ Hello, Mercury!
+ Hello, Not Mercury!
+
+ '''.trim(),
+ 'Hello, Not Mercury!'
+ )
+ }
+
+}