1717
1818import java .util .ArrayList ;
1919import java .util .Arrays ;
20+ import java .util .Collections ;
2021import java .util .List ;
22+ import java .util .Objects ;
23+ import java .util .function .BiFunction ;
24+ import java .util .stream .Stream ;
2125
2226import com .vaadin .flow .component .UI ;
2327import com .vaadin .flow .component .dependency .CssImport ;
@@ -33,11 +37,12 @@ public class Breadcrumbs extends HorizontalLayout
3337{
3438 protected static final String DELIMITER_URL = "/" ;
3539
36- protected static final String I18N_PREFIX = "breadcrumb_" ;
37-
3840 protected static final String BREADCRUMB_CLASS = "breadcrumb" ;
3941 protected static final String BREADCRUMBS_CONTAINER_CLASS = "breadcrumbs-container" ;
4042
43+ protected String homeBreadcrumbName = "Home" ;
44+ protected BiFunction <List <String >, String , String > breadcrumbNameResolver = (parts , part ) -> part ;
45+
4146 public Breadcrumbs (final String path )
4247 {
4348 this ();
@@ -49,6 +54,18 @@ public Breadcrumbs()
4954 this .addClassName (BREADCRUMBS_CONTAINER_CLASS );
5055 }
5156
57+ public Breadcrumbs withHomeBreadcrumbName (final String name )
58+ {
59+ this .homeBreadcrumbName = Objects .requireNonNull (name );
60+ return this ;
61+ }
62+
63+ public Breadcrumbs withBreadcrumbNameResolver (final BiFunction <List <String >, String , String > breadcrumbNameResolver )
64+ {
65+ this .breadcrumbNameResolver = Objects .requireNonNull (breadcrumbNameResolver );
66+ return this ;
67+ }
68+
5269 /**
5370 * Initializes the breadcrumb navigation based on the given URL path. It splits the path, creates breadcrumb items
5471 * for each part, and updates the view.
@@ -57,26 +74,30 @@ public Breadcrumbs()
5774 */
5875 public void updatePath (final String path )
5976 {
60- final List <Breadcrumb > breadcrumbs = new ArrayList <>();
61- breadcrumbs .add (new Breadcrumb (this .getTranslation (I18N_PREFIX + "home" ), DELIMITER_URL ));
62-
63- final List <String > parts = new ArrayList <>(Arrays .asList (path .split (DELIMITER_URL )));
64-
65- final StringBuilder hrefBuilder = new StringBuilder ();
66- for (final String part : parts )
67- {
68- if (!part .isEmpty ())
69- {
70- // append to full link
71- hrefBuilder .append (DELIMITER_URL ).append (part );
72-
73- final String title = this .getTranslation (I18N_PREFIX + part .toLowerCase ());
74-
75- breadcrumbs .add (new Breadcrumb (title , hrefBuilder .toString ()));
76- }
77- }
77+ this .updateView (
78+ Stream .concat (
79+ Stream .of (new Breadcrumb (this .homeBreadcrumbName , DELIMITER_URL )),
80+ this .buildBreadcrumbs (Arrays .asList (path .split (DELIMITER_URL ))).stream ()
81+ ).toList ()
82+ );
83+ }
84+
85+ protected List <Breadcrumb > buildBreadcrumbs (final List <String > parts )
86+ {
87+ final List <String > currentPaths = new ArrayList <>();
7888
79- this .updateView (breadcrumbs );
89+ return parts .stream ()
90+ .filter (s -> !s .isEmpty ())
91+ .map (part -> {
92+ currentPaths .add (part );
93+ return new Breadcrumb (
94+ this .breadcrumbNameResolver .apply (
95+ // Use unmodifiable so that it can be accidentally modified by user
96+ Collections .unmodifiableList (currentPaths ),
97+ part ),
98+ String .join (DELIMITER_URL , currentPaths ));
99+ })
100+ .toList ();
80101 }
81102
82103 /**
0 commit comments