Skip to content

Commit d5b9071

Browse files
javier-godoypaodb
authored andcommitted
feat: allow multiple source code tabs in TabbedDemo
1 parent 2ff359e commit d5b9071

8 files changed

Lines changed: 134 additions & 28 deletions

File tree

src/main/java/com/flowingcode/vaadin/addons/demo/DemoSource.java

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
import com.flowingcode.vaadin.addons.GithubBranch;
2323
import com.flowingcode.vaadin.addons.GithubLink;
2424
import java.lang.annotation.ElementType;
25+
import java.lang.annotation.Repeatable;
2526
import java.lang.annotation.Retention;
2627
import java.lang.annotation.RetentionPolicy;
2728
import java.lang.annotation.Target;
@@ -37,12 +38,28 @@
3738
*
3839
* @author Javier Godoy / Flowing Code
3940
*/
41+
@Repeatable(DemoSources.class)
4042
@Retention(RetentionPolicy.RUNTIME)
4143
@Target(ElementType.TYPE)
4244
public @interface DemoSource {
4345

4446
static final String GITHUB_SOURCE = "__GITHUB__";
4547

48+
static final String DEFAULT_VALUE = "__DEFAULT__";
49+
4650
/** A link to the source code, if different from the annotated class. */
4751
String value() default GITHUB_SOURCE;
52+
53+
/**
54+
* The caption of the source tab (displayed if several sources are provided). Default to the file
55+
* name.
56+
*/
57+
String caption() default DEFAULT_VALUE;
58+
59+
/**
60+
* The language used to format the sources. By default the language is inferred from the file
61+
* extension.
62+
*/
63+
String language() default DEFAULT_VALUE;
64+
4865
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
package com.flowingcode.vaadin.addons.demo;
2+
3+
import java.lang.annotation.ElementType;
4+
import java.lang.annotation.Retention;
5+
import java.lang.annotation.RetentionPolicy;
6+
import java.lang.annotation.Target;
7+
8+
@Retention(RetentionPolicy.RUNTIME)
9+
@Target(ElementType.TYPE)
10+
public @interface DemoSources {
11+
12+
DemoSource[] value();
13+
14+
}

src/main/java/com/flowingcode/vaadin/addons/demo/SourceCodeTab.java

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,20 @@
22

33
import lombok.AccessLevel;
44
import lombok.AllArgsConstructor;
5+
import lombok.Builder;
56
import lombok.Getter;
7+
import lombok.NonNull;
68
import lombok.RequiredArgsConstructor;
7-
import lombok.With;
89

910
@Getter
10-
@With
11+
@Builder
1112
@RequiredArgsConstructor
1213
@AllArgsConstructor(access = AccessLevel.PRIVATE)
1314
public class SourceCodeTab {
15+
16+
@NonNull
1417
private final String url;
1518
private String caption;
1619
private String language;
20+
1721
}

src/main/java/com/flowingcode/vaadin/addons/demo/SplitLayoutDemo.java

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424
import com.vaadin.flow.component.splitlayout.SplitLayout;
2525
import com.vaadin.flow.component.splitlayout.SplitLayout.Orientation;
2626
import com.vaadin.flow.server.Version;
27-
import java.util.ArrayList;
27+
import java.util.Arrays;
2828
import java.util.HashMap;
2929
import java.util.List;
3030
import java.util.Map;
@@ -35,14 +35,16 @@ class SplitLayoutDemo extends Composite<SplitLayout> {
3535
private MultiSourceCodeViewer code;
3636

3737
public SplitLayoutDemo(Component demo, String sourceUrl) {
38+
this(demo, Arrays.asList(new SourceCodeTab(sourceUrl)));
39+
}
40+
41+
public SplitLayoutDemo(Component demo, List<SourceCodeTab> tabs) {
3842
getContent().setOrientation(Orientation.HORIZONTAL);
3943

4044
Map<String, String> properties = new HashMap<>();
4145
properties.put("vaadin", VaadinVersion.getVaadinVersion());
4246
properties.put("flow", Version.getFullVersion());
4347

44-
List<SourceCodeTab> tabs = new ArrayList<>();
45-
tabs.add(new SourceCodeTab(sourceUrl));
4648
code = new MultiSourceCodeViewer(tabs, properties);
4749
getContent().addToPrimary(demo);
4850
getContent().addToSecondary(code);

src/main/java/com/flowingcode/vaadin/addons/demo/TabbedDemo.java

Lines changed: 49 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,8 @@
4040
import com.vaadin.flow.router.Route;
4141
import com.vaadin.flow.router.RouterLayout;
4242
import com.vaadin.flow.router.RouterLink;
43+
import java.util.ArrayList;
44+
import java.util.List;
4345
import java.util.Objects;
4446
import java.util.Optional;
4547
import org.slf4j.Logger;
@@ -179,29 +181,14 @@ public void showRouterLayoutContent(HasElement content) {
179181
helperButton = null;
180182
}
181183

182-
DemoSource demoSource = demo.getClass().getAnnotation(DemoSource.class);
183-
String sourceCodeUrl = null;
184-
if (demoSource != null) {
185-
sourceCodeUrl = demoSource.value();
186-
187-
String demoFile;
188-
if (sourceCodeUrl.equals(DemoSource.GITHUB_SOURCE)) {
189-
String className = demo.getClass().getName().replace('.', '/');
190-
demoFile = "src/test/java/" + className + ".java";
191-
} else if (sourceCodeUrl.startsWith("/src/test/")) {
192-
demoFile = sourceCodeUrl.substring(1);
193-
} else {
194-
demoFile = null;
195-
}
196-
197-
if (demoFile != null) {
198-
String branch = lookupGithubBranch(this.getClass());
199-
sourceCodeUrl = Optional.ofNullable(this.getClass().getAnnotation(GithubLink.class))
200-
.map(githubLink -> String.format("%s/blob/%s/%s", githubLink.value(),
201-
branch, demoFile))
202-
.orElse(null);
203-
}
204-
content = new SplitLayoutDemo(demo, sourceCodeUrl);
184+
DemoSource demoSources[] = demo.getClass().getAnnotationsByType(DemoSource.class);
185+
List<SourceCodeTab> tabs = new ArrayList<>(demoSources.length);
186+
for (DemoSource demoSource : demoSources) {
187+
createSourceCodeTab(demo.getClass(), demoSource).ifPresent(tabs::add);
188+
}
189+
190+
if (!tabs.isEmpty()) {
191+
content = new SplitLayoutDemo(demo, tabs);
205192
currentLayout = (SplitLayoutDemo) content;
206193
if (splitOrientation != null) {
207194
setOrientation(splitOrientation);
@@ -216,10 +203,49 @@ public void showRouterLayoutContent(HasElement content) {
216203
demo.getElement().getStyle().set("height", "100%");
217204
setupDemoHelperButton(content.getClass());
218205
}
206+
219207
updateFooterButtonsVisibility();
220208
getElement().insertChild(1, content.getElement());
221209
}
222210

211+
private Optional<SourceCodeTab> createSourceCodeTab(Class<?> annotatedClass, DemoSource annotation) {
212+
String demoFile;
213+
String url = annotation.value();
214+
if (url.equals(DemoSource.GITHUB_SOURCE)) {
215+
String className = annotatedClass.getName().replace('.', '/');
216+
demoFile = "src/test/java/" + className + ".java";
217+
} else if (url.startsWith("/src/test/")) {
218+
demoFile = url.substring(1);
219+
} else {
220+
demoFile = null;
221+
}
222+
223+
if (demoFile != null) {
224+
String branch = lookupGithubBranch(this.getClass());
225+
url = Optional.ofNullable(this.getClass().getAnnotation(GithubLink.class))
226+
.map(githubLink -> String.format("%s/blob/%s/%s", githubLink.value(),
227+
branch, demoFile))
228+
.orElse(null);
229+
}
230+
231+
if (url==null) {
232+
return Optional.empty();
233+
}
234+
235+
SourceCodeTab.SourceCodeTabBuilder builder = SourceCodeTab.builder();
236+
builder.url(url);
237+
238+
if (!annotation.caption().equals(DemoSource.DEFAULT_VALUE)) {
239+
builder.caption(annotation.caption());
240+
}
241+
242+
if (!annotation.language().equals(DemoSource.DEFAULT_VALUE)) {
243+
builder.language(annotation.caption());
244+
}
245+
246+
return Optional.of(builder.build());
247+
}
248+
223249
public static String lookupGithubBranch(Class<? extends TabbedDemo> clazz) {
224250
GithubBranch branch = clazz.getAnnotation(GithubBranch.class);
225251
if (branch == null) {

src/test/java/com/flowingcode/vaadin/addons/demo/Demo.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,5 +34,6 @@ public Demo() {
3434
addDemo(SampleDemoDefault.class);
3535
addDemo(SampleDemoHighlight.class);
3636
addDemo(AdHocDemo.class);
37+
addDemo(MultiSourceDemo.class);
3738
}
3839
}
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
/*-
2+
* #%L
3+
* %%
4+
* Copyright (C) 2020 - 2023 Flowing Code
5+
* %%
6+
* Licensed under the Apache License, Version 2.0 (the "License");
7+
* you may not use this file except in compliance with the License.
8+
* You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing, software
13+
* distributed under the License is distributed on an "AS IS" BASIS,
14+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
* See the License for the specific language governing permissions and
16+
* limitations under the License.
17+
* #L%
18+
*/
19+
package com.flowingcode.vaadin.addons.demo;
20+
21+
import com.vaadin.flow.component.dependency.StyleSheet;
22+
import com.vaadin.flow.component.html.Div;
23+
import com.vaadin.flow.component.html.Span;
24+
import com.vaadin.flow.router.PageTitle;
25+
import com.vaadin.flow.router.Route;
26+
27+
@Route(value = "demo/multisource", layout = Demo.class)
28+
@PageTitle("Demo with multiple sources")
29+
@DemoSource
30+
@DemoSource(value = "/src/test/resources/META-INF/resources/frontend/multi-source-demo.css")
31+
@StyleSheet("./multi-source-demo.css")
32+
public class MultiSourceDemo extends Div {
33+
public MultiSourceDemo() {
34+
Span span = new Span("This is the main source");
35+
span.addClassName("custom-style");
36+
add(span);
37+
}
38+
39+
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
.custom-style {
2+
color: red;
3+
}

0 commit comments

Comments
 (0)