Navigation latérale
Composant affichant un menu de navigation latéral
Sidenav
Ce composant représente une barre de navigation latérale.
NOTE : Techniquement, ce menu peut accueillir autant de sous-niveaux que souhaité, mais l'intégration prévue ne va pas au-delà de 3 niveaux.
Classes utilisables
Modificateurs de niveau
.sidenav__list--level-N: Niveau N du menu secondaire
<%@ page contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" trimDirectiveWhitespaces="true" %>
<%@ taglib prefix="kuik" uri="kuik" %>
<%--@elvariable id="sidenavViewModel" type="fr.kosmos.web.kore.attributes.interfaces.Menu"--%>
<kuik:sidenav menu="${sidenavViewModel}" />
| Name | Type | Required | Description |
|---|---|---|---|
| menu | fr.kosmos.web.kore.attributes.interfaces.Menu | true | Items du menu |
| parentKey | java.lang.String | true | Identifiant unique du menu parent |
| level | java.lang.Integer | true | Niveau du menu |
| open | java.lang.Boolean | false | Ouvre le premier niveau (Défaut: false) |
<%@ tag trimDirectiveWhitespaces="true" dynamic-attributes="dynattrs" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="kuik" uri="kuik" %>
<%@ attribute name="menu" required="true" type="fr.kosmos.web.kore.attributes.interfaces.Menu" description="Items du menu" %>
<%@ attribute name="parentKey" required="true" type="java.lang.String" description="Identifiant unique du menu parent" %>
<%@ attribute name="level" required="true" type="java.lang.Integer" description="Niveau du menu" %>
<%@ attribute name="open" required="false" type="java.lang.Boolean" description="Ouvre le premier niveau (Défaut: false)" %>
<c:if test="${empty pageScope.open}">
<c:set var="open" value="false"/>
</c:if>
<c:if test="${not empty pageScope.menu.items}">
<c:set var="classes" value="sidenav__list sidenav__list--level-${pageScope.level}"/>
<c:set var="subLevel" value="${pageScope.level + 1}"/>
<c:set var="attributes">
<c:forEach items="${dynattrs}" var="a">
<c:choose>
<c:when test="${a.key == 'class'}">
<c:set var="classes" value="${classes} ${a.value}"/>
</c:when>
<c:otherwise>${a.key}="${a.value}" </c:otherwise>
</c:choose>
</c:forEach>
</c:set>
<ul class="${pageScope.classes}" ${pageScope.attributes}>
<c:forEach var="item" items="${pageScope.menu.items}" varStatus="status">
<c:set var="itemKey">${pageScope.parentKey}-${status.index}</c:set>
<c:set var="itemClasses" value="sidenav__item ${item.current ? 'sidenav__item--current' : ''}" />
<c:set var="itemExpanded" value="${pageScope.open or item.current or item.currentAscendant ? 'true' : 'false'}" />
<c:set var="itemAttributes" value=' id="${pageScope.itemKey}"'/>
<c:set var="itemClasses" value="${pageScope.itemClasses}"/>
<c:if test="${not empty pageScope.item.items}">
<c:set var="itemAttributes" value='${pageScope.itemAttributes} aria-expanded="${pageScope.itemExpanded}"'/>
<c:set var="itemClasses" value="${pageScope.itemClasses} js-disclosure-target" />
</c:if>
<li class="${pageScope.itemClasses}" ${pageScope.itemAttributes}>
<kuik:sidenav-item item="${pageScope.item}" level="${pageScope.level}" parentKey="${pageScope.itemKey}"/>
<kuik:sidenav-items menu="${pageScope.item}" level="${pageScope.subLevel}" parentKey="${pageScope.itemKey}"/>
</li>
</c:forEach>
</ul>
</c:if>
@use 'mixins/mixins-customizables' as custom;
@use 'mixins/mixins-lists' as lists;
$prefix-sidenav: 'sidenav';
$prefix-sidenav-item: 'sidenav-item';
.sidenav__list {
@include lists.list-reset;
@include custom.component($prefix-sidenav, true);
font-size: var(--font-size-50);
}
.sidenav__list--level-1 {
@include custom.component($prefix-sidenav);
--sidenav-item-indent-padding: var(--space-0);
font-weight: var(--font-weight-700);
}
.sidenav__list--level-2 {
@include custom.component($prefix-sidenav);
--sidenav-item-indent-padding: var(--space-10);
font-weight: var(--font-weight-400);
}
.sidenav__list--level-3 {
@include custom.component($prefix-sidenav);
--sidenav-item-indent-padding: var(--space-20);
font-weight: var(--font-weight-400);
}
.sidenav__item--current {
@include custom.component($prefix-sidenav);
font-weight: var(--font-weight-700);
}
.sidenav__toggler {
align-self: stretch;
}
.sidenav-item {
@include custom.component($prefix-sidenav-item, true);
display: flex;
&:has(.sidenav-item__label:link):hover {
@include custom.component($prefix-sidenav-item);
}
}
.sidenav-item__label {
align-items: center;
color: inherit;
display: flex;
flex-grow: 1;
font-weight: inherit;
gap: var(--space-2);
padding-inline-start: calc(var(--sidenav-item-indent-padding) + var(--sidenav-item-padding-inline-start, var(--sidenav-item-padding-inline)));
text-decoration: none;
}
[aria-expanded='false'] {
> .sidenav__list {
display: none;
}
> .sidenav-item {
.sidenav-item__icon-collapse {
display: none;
}
}
}
[aria-expanded='true'] {
> .sidenav-item {
@include custom.component($prefix-sidenav-item);
font-weight: var(--font-weight-700);
.sidenav-item__icon-expand {
display: none;
}
}
}