1919 */
2020package com .flowingcode .vaadin .addons .demo ;
2121
22+ import java .util .Optional ;
2223import com .flowingcode .vaadin .addons .GithubLink ;
2324import com .vaadin .flow .component .Component ;
25+ import com .vaadin .flow .component .HasElement ;
2426import com .vaadin .flow .component .checkbox .Checkbox ;
2527import com .vaadin .flow .component .dependency .StyleSheet ;
28+ import com .vaadin .flow .component .html .Div ;
2629import com .vaadin .flow .component .orderedlayout .HorizontalLayout ;
2730import com .vaadin .flow .component .orderedlayout .VerticalLayout ;
2831import com .vaadin .flow .component .splitlayout .SplitLayout .Orientation ;
29- import com .vaadin .flow .component . tabs . Tab ;
30- import com .vaadin .flow .component . tabs . Tabs ;
32+ import com .vaadin .flow .router . BeforeEnterEvent ;
33+ import com .vaadin .flow .router . BeforeEnterObserver ;
3134import com .vaadin .flow .router .PageTitle ;
32- import java . util . HashMap ;
33- import java . util . Map ;
34- import java . util . Optional ;
35+ import com . vaadin . flow . router . Route ;
36+ import com . vaadin . flow . router . RouterLayout ;
37+ import com . vaadin . flow . router . RouterLink ;
3538
3639@ StyleSheet ("context://frontend/styles/commons-demo/shared-styles.css" )
3740@ SuppressWarnings ("serial" )
38- public class TabbedDemo extends VerticalLayout {
41+ public class TabbedDemo extends VerticalLayout implements RouterLayout , BeforeEnterObserver {
3942
40- private Tabs tabs ;
43+ private RouteTabs tabs ;
4144 private HorizontalLayout footer ;
4245 private SplitLayoutDemo currentLayout ;
43- private Map <Tab , Component > demos ;
4446 private Checkbox orientationCB ;
4547 private Checkbox codeCB ;
4648
4749 public TabbedDemo () {
48- tabs = new Tabs ();
49- demos = new HashMap <>();
50+ tabs = new RouteTabs ();
5051 tabs .setWidthFull ();
5152
5253 // Footer
@@ -68,22 +69,10 @@ public TabbedDemo() {
6869 footer .setWidthFull ();
6970 footer .setJustifyContentMode (JustifyContentMode .END );
7071 footer .add (codeCB , orientationCB );
71-
72- tabs .addSelectedChangeListener (
73- e -> {
74- removeAll ();
75- Component currentDemo = demos .get (tabs .getSelectedTab ());
76- this .add (tabs , currentDemo );
77- if (currentDemo instanceof SplitLayoutDemo ) {
78- currentLayout = (SplitLayoutDemo ) currentDemo ;
79- this .add (footer );
80- updateSplitterPosition ();
81- updateSplitterOrientation ();
82- } else {
83- currentLayout = null ;
84- }
85- });
86-
72+
73+ this .add (tabs );
74+ this .add (new Div ());
75+ this .add (footer );
8776 setSizeFull ();
8877 }
8978
@@ -118,26 +107,60 @@ public void addDemo(Component demo) {
118107
119108 /**
120109 * @param demo the demo instance
121- * @param name the demo name (tab label)
110+ * @param label the demo name (tab label)
122111 * @param sourceCodeUrl the url of the demo, <b>null</b> to not show source code section.
123112 */
113+ @ Deprecated
124114 public void addDemo (Component demo , String label , String sourceCodeUrl ) {
125- if (!demo .getId ().isPresent ()) {
126- demo .setId ("content" );
127- }
128- Tab tab = new Tab (label );
129- if (sourceCodeUrl != null ) {
130- demos .put (tab , new SplitLayoutDemo (demo , sourceCodeUrl ));
131- } else {
132- demos .put (tab , demo );
115+ this .addDemo (demo .getClass (), label , sourceCodeUrl );
116+ }
117+
118+ public void addDemo (Class <? extends Component > clazz , String label , String sourceCodeUrl ){
119+ if (!clazz .isAnnotationPresent (Route .class )) {
120+ throw new IllegalArgumentException (clazz + " must be annotated as Route" );
133121 }
122+ RouterLink tab = new RouterLink (label , clazz );
134123 tabs .add (tab );
135124 }
136125
137126 public void addDemo (Component demo , String label ) {
138127 addDemo (demo , label , null );
139128 }
140129
130+ @ Override
131+ public void showRouterLayoutContent (HasElement content ) {
132+ Component demo = (Component )content ;
133+ if (!demo .getId ().isPresent ()) {
134+ demo .setId ("content" );
135+ }
136+
137+ DemoSource demoSource = demo .getClass ().getAnnotation (DemoSource .class );
138+ String sourceCodeUrl = null ;
139+ if (demoSource != null ) {
140+ sourceCodeUrl = demoSource .value ();
141+ if (sourceCodeUrl .equals (DemoSource .GITHUB_SOURCE )) {
142+ sourceCodeUrl = Optional .ofNullable (this .getClass ().getAnnotation (GithubLink .class ))
143+ .map (githubLink -> githubLink .value () + "/blob/master/src/test/java/"
144+ + demo .getClass ().getName ().replace ('.' , '/' ) + ".java" )
145+ .orElse (null );
146+ }
147+ content = new SplitLayoutDemo (demo , sourceCodeUrl );
148+ currentLayout = (SplitLayoutDemo ) content ;
149+ updateSplitterPosition ();
150+ updateSplitterOrientation ();
151+ this .footer .setVisible (true );
152+ } else {
153+ currentLayout = null ;
154+ this .footer .setVisible (false );
155+ }
156+ this .getElement ().insertChild (1 , content .getElement ());
157+ }
158+
159+ @ Override
160+ public void removeRouterLayoutContent (HasElement oldContent ) {
161+ this .getElement ().removeChild (1 );
162+ }
163+
141164 private void updateSplitterPosition () {
142165 boolean b = codeCB .getValue ();
143166 if (b ) {
@@ -157,4 +180,15 @@ private void updateSplitterOrientation() {
157180 currentLayout .setOrientation (Orientation .VERTICAL );
158181 }
159182 }
183+
184+ @ Override
185+ public void beforeEnter (BeforeEnterEvent event ) {
186+ if (TabbedDemo .class .isAssignableFrom (event .getNavigationTarget ())) {
187+ RouterLink first = tabs .getFirstRoute ();
188+ if (first != null ) {
189+ event .forwardTo (first .getHref ());
190+ }
191+ }
192+ }
193+
160194}
0 commit comments