AppNav
Le composant AppNav crée un menu de navigation latéral à partir d'entrées AppNavItem. Les éléments peuvent lier à des vues internes ou à des ressources externes, s'imbriquer sous des éléments parents pour former des menus hiérarchiques, et porter des icônes, des badges ou d'autres composants pour donner aux utilisateurs plus de contexte d'un coup d'œil.
Ajouter et imbriquer des éléments
Les instances AppNavItem sont utilisées pour peupler la structure AppNav. Ces éléments peuvent être des liens simples ou des en-têtes de groupe imbriqués contenant des éléments enfants. Les en-têtes de groupe sans liens agissent comme des conteneurs extensibles.
Utilisez addItem() pour inclure des éléments dans la navigation :
AppNavItem dashboard = new AppNavItem("Tableau de bord", "/dashboard");
AppNavItem admin = new AppNavItem("Admin");
admin.addItem(new AppNavItem("Utilisateurs", "/admin/users"));
admin.addItem(new AppNavItem("Paramètres", "/admin/settings"));
AppNav nav = new AppNav();
nav.addItem(dashboard);
nav.addItem(admin);
Les éléments de premier niveau dans un arbre de navigation sont généralement destinés à être extensibles - pas des liens cliquables. Définir un path sur ces éléments peut troubler les utilisateurs qui s'attendent à ce qu'ils révèlent des sous-éléments au lieu de naviguer ailleurs.
Si vous souhaitez que l'en-tête de groupe déclenche une action personnalisée (comme ouvrir des docs externes), laissez le chemin du groupe vide et ajoutez plutôt un contrôle interactif comme un IconButton à la suffixe de l'élément. Cela maintient l'expérience utilisateur cohérente et propre.
Afficher le code
- AppNavView.java
- AppNavPageView.java
Lier des éléments
Chaque AppNavItem peut naviguer vers une vue interne ou un lien externe. Vous pouvez définir cela en utilisant des chemins statiques ou des classes de vues enregistrées.
Chemins statiques
Utilisez des chemins de chaînes pour définir des liens directement :
AppNavItem docs = new AppNavItem("Docs", "/docs");
AppNavItem help = new AppNavItem("Aide", "https://support.example.com");
Vues enregistrées
Si vos vues sont enregistrées avec le routeur, vous pouvez passer la classe au lieu d'une URL codée en dur :
AppNavItem settings = new AppNavItem("Paramètres", SettingsView.class);
Si votre route annotée prend en charge les paramètres de route, vous pouvez également passer un ParametersBag :
ParametersBag params = ParametersBag.of("id=123");
AppNavItem advanced = new AppNavItem("Utilisateur", UserView.class, params);
Avec des paramètres de requête
Passez un ParametersBag pour inclure des chaînes de requête :
ParametersBag params = ParametersBag.of("param1=value1¶m2=value2");
AppNavItem advanced = new AppNavItem("Avancé", SettingsView.class, params);
advanced.setQueryParameters(params);
Comportement cible
Contrôlez comment les liens s'ouvrent en utilisant setTarget(). C'est particulièrement utile pour les liens externes ou les vues pop-out.
SELF(par défaut) : S'ouvre dans la vue actuelle.BLANK: S'ouvre dans un nouvel onglet ou une nouvelle fenêtre.PARENT: S'ouvre dans le contexte de navigation parent.TOP: S'ouvre dans le contexte de navigation de niveau supérieur.
AppNavItem help = new AppNavItem("Aide", "https://support.example.com");
help.setTarget(AppNavItem.NavigationTarget.BLANK);
Préfixe et suffixe
AppNavItem prend en charge des composants de préfixe et de suffixe. Utilisez-les pour fournir une clarté visuelle avec des icônes, des badges ou des boutons.
- Préfixe : apparaît avant le label, utile pour les icônes.
- Suffixe : apparaît après le label, idéal pour des badges ou des actions.
AppNavItem notifications = new AppNavItem("Alertes");
notifications.setPrefixComponent(TablerIcon.create("alert"));
notifications.setSuffixComponent(TablerIcon.create("link"));
Groupes auto-ouverts
Utilisez setAutoOpen(true) sur le composant AppNav pour étendre automatiquement les groupes imbriqués lorsque l'application est actualisée.
nav.setAutoOpen(true);
Étiquettes de section 26.02
AppNavLabel est un en-tête non interactif qui titre une série d'éléments. Une étiquette s'applique à chaque élément qui la suit, jusqu'à la prochaine étiquette ou la fin du menu, ce qui permet à une longue liste d'éléments de premier niveau de se lire comme quelques groupes nommés sans les imbriquer.
Les étiquettes sont ajoutées avec add() plutôt qu'avec addItem(), et l'ordre des appels définit les sections :
AppNav nav = new AppNav();
nav.addItem(new AppNavItem("Tableau de bord", DashboardView.class, TablerIcon.create("layout-dashboard")));
nav.add(new AppNavLabel("Analytique"));
nav.addItem(new AppNavItem("Vue d'ensemble", OverviewView.class));
nav.addItem(new AppNavItem("Rapports", ReportsView.class));
nav.add(new AppNavLabel("Autre"));
nav.addItem(new AppNavItem("Paramètres", SettingsView.class));
La navigation cache une étiquette automatiquement lorsque sa section n'a pas d'éléments visibles, donc une étiquette disparaît lorsqu'une recherche filtre ses éléments ou lorsque tous sont épinglés en haut du menu.
Préfixe et suffixe de l'étiquette
Comme AppNavItem, une étiquette prend en charge des composants de préfixe et de suffixe. Passez un préfixe au constructeur, ou définissez-en un après :
AppNavLabel analytics = new AppNavLabel("Analytique", TablerIcon.create("chart-pie"));
analytics.setSuffixComponent(new Badge().setText("2").setTheme(BadgeTheme.WARNING));
nav.add(analytics);
L'exemple ci-dessous groupe un menu sous trois étiquettes, dont la première porte un Icon comme préfixe et un Badge comme suffixe. Le tableau de bord se trouve au-dessus de la première étiquette, donc il n'appartient à aucune section.
Afficher le code
- AppNavLabelView.java
- AppNavLabelPageView.java
Épingler 26.01
L'épinglage permet à un utilisateur de soulever les éléments qu'il atteint le plus vers un groupe en haut de la navigation, de sorte qu'un menu profond garde une courte liste de favoris à un clic. Par défaut, c'est désactivé. Activez-le via la configuration d'épinglage :
AppNav nav = new AppNav();
nav.getPinning().setEnabled(true);
Une fois activé, chaque élément feuille navigable montre un bascule de pin. Le bascule est révélé au survol et lors de la mise au point au clavier, afin qu'il reste accessible sans souris. L'activer déplace l'élément dans le groupe épinglé en haut de la navigation.
Quelques règles régissent ce qui peut être épinglé et comment le groupe se comporte :
- Seuls les éléments feuille navigables peuvent être épinglés. Les en-têtes de groupe (éléments avec enfants) ne sont jamais épinglables.
- Le groupe épinglé n'apparaît qu'une fois quelque chose épinglé, et disparaît à nouveau lorsque le dernier élément est désépinglé.
- Désépingler renvoie un élément à sa position d'origine exacte, y compris les éléments imbriqués à plusieurs niveaux à l'intérieur des groupes.
- L'élément est déplacé, pas copié, donc tout contenu de préfixe ou de suffixe et tous les écouteurs qui y sont attachés continuent de fonctionner tant qu'il est dans le groupe épinglé.
La démo ci-dessous a l'épinglage activé avec un titre de groupe personnalisé et le tableau de bord épinglé au chargement. Survolez ou focalisez un élément feuille pour révéler son bascule de pin.
Afficher le code
- AppNavPinningView.java
- AppNavPinningPageView.java
Démarrer un élément épinglé
Démarrez un élément dans le groupe épinglé en définissant son état épinglé. Utilisez isPinned() pour lire l'état actuel.
AppNavItem reports = new AppNavItem("Rapports", "/reports");
reports.setPinned(true);
setPinned(true) n'a d'effet que lorsque l'épinglage est activé sur le AppNav via getPinning().setEnabled(true). Sans cela, l'appel n'a aucun effet.
Titre du groupe épinglé
Le groupe épinglé est étiqueté Épinglé par défaut. Changez-le pour correspondre à votre application :
nav.getPinning().setTitle("Favoris");
Clés de pin
Chaque élément épinglable porte une clé qui l'identifie pour la persistance et pour l'événement de pin. Lorsque vous n'en définissez pas, la clé se rapporte au chemin de l'élément, donc getPinKey() retourne toujours une valeur utilisable.
AppNavItem reports = new AppNavItem("Rapports", "/reports");
reports.setPinKey("reports");
Définissez une clé explicite lorsque le chemin peut changer à l'exécution. Une clé stable maintient un pin associé au bon élément lors des rechargements même si son URL change.
Sauvegarde automatique dans le stockage local
Les épingles vivent uniquement pour la vue de la page actuelle, sauf si vous les persistez. La sauvegarde automatique est l'option la plus simple : elle stocke l'ensemble des éléments épinglés dans le stockage local du navigateur et les restaure au rechargement. Elle est désactivée par défaut. Elle nécessite un id stable (ou nom) sur le composant pour la clé de stockage, et le constructeur AppNav(String id) est le moyen pratique de définir un :
AppNav nav = new AppNav("main-nav"); // donne à la sauvegarde automatique une clé de stockage stable
nav.getPinning().setAutosave(true);
Sans id (ou nom) sur le composant, la sauvegarde automatique ne fait rien silencieusement, car elle n'a pas de clé stable sous laquelle stocker. La persistance est par navigateur, donc les épingles ne suivent pas un utilisateur sur un autre appareil ou navigateur.
Persistance personnalisée
Pour la persistance que vous contrôlez, par exemple par utilisateur sur le serveur, désactivez la sauvegarde automatique et gérez-la vous-même via l'événement de pin et setPinned :
nav.getPinning().setAutosave(false);
// persister l'ensemble actuel des clés épinglées chaque fois qu'il change
nav.onPin(event -> savePins(event.getKeys()));
// au chargement, restaurez chaque clé sauvegardée
restoredKeys.forEach(key -> findItem(key).setPinned(true));
Réagir aux changements de pin
L'événement de pin se déclenche chaque fois qu'un élément est épinglé ou désépinglé. Il porte l'élément qui a changé, sa clé, le nouvel état épinglé et l'ensemble complet ordonné des clés épinglées :
nav.onPin(event -> {
AppNavItem item = event.getItem(); // l'élément qui a changé, ou null s'il n'est plus dans la navigation
boolean pinned = event.isPinned();
String key = event.getKey();
List<String> all = event.getKeys(); // chaque clé épinglée, dans l'ordre épinglé
});
getItem() résout l'élément en faisant correspondre sa clé de pin, et retourne null lorsque l'élément ne fait plus partie de la navigation.
Icônes de pin
Le bascule utilise l'icône intégrée dwc:pin lorsqu'un élément n'est pas épinglé et dwc:pinned-off lorsqu'il est épinglé. Remplacez le vôtre à travers setUnpinnedIcon et setPinnedIcon, qui acceptent n'importe quelle IconDefinition :
nav.getPinning()
.setUnpinnedIcon(TablerIcon.create("pin"))
.setPinnedIcon(TablerIcon.create("pinned-off"));
Bascule de pin sur les écrans tactiles
Les écrans tactiles n'ont pas de survol pour révéler le pin, donc le bascule est caché par défaut. Gardez-le visible et cliquable sur les écrans tactiles avec setTouchVisible(true) :
nav.getPinning().setTouchVisible(true);
Recherche 26.01
Le champ de recherche filtre le menu par label d'élément à mesure que l'utilisateur tape. Il est désactivé par défaut. Vous pouvez l'afficher et lui donner un texte de remplacement à travers la configuration de recherche :
nav.getSearch().setFieldVisible(true);
nav.getSearch().setPlaceholder("Recherche");
À mesure que l'utilisateur tape, la navigation filtre les éléments par label, ouvre tout groupe contenant une correspondance, et montre un message vide lorsque rien ne correspond. Les raccourcis épinglés restent visibles pendant la recherche, donc les favoris d'un utilisateur demeurent à un clic même en milieu de filtrage.
Afficher le code
- AppNavSearchView.java
- AppNavSearchPageView.java
Message vide
Définissez le message affiché lorsqu'une recherche ne retourne aucun résultat. Le texte brut est rendu en tant que texte :
nav.getSearch().setEmptyMessage("Aucun élément trouvé");
Piloter la recherche à partir de votre propre champ
Cachez le champ intégré et alimentez le filtre à partir d'une entrée de votre choix. Poussez le terme actuel dans setTerm :
nav.getSearch().setFieldVisible(false);
myField.onModify(event -> nav.getSearch().setTerm(event.getText()));
Pour réagir à ce que l'utilisateur tape dans le champ intégré, écoutez l'événement de recherche :
nav.onSearch(event -> log(event.getTerm()));