From 0b00428f90a6fe9f59bb65b9e2404abbd06d749f Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Loi=CC=88c=20Correnson?= <loic.correnson@cea.fr>
Date: Thu, 9 Nov 2023 19:48:39 +0100
Subject: [PATCH] [ivette/sidebar] refactor all

---
 ivette/src/frama-c/index.tsx          |  60 +++----
 ivette/src/ivette/index.tsx           |  73 +++++----
 ivette/src/renderer/Application.tsx   |  16 +-
 ivette/src/renderer/Extensions.tsx    |  36 ++---
 ivette/src/renderer/Sidebar.tsx       | 124 +++++++++++++++
 ivette/src/sandbox/sidebar.tsx        | 219 +++++---------------------
 ivette/src/sandbox/sidebarMocking.tsx |  75 ---------
 7 files changed, 253 insertions(+), 350 deletions(-)
 create mode 100644 ivette/src/renderer/Sidebar.tsx
 delete mode 100644 ivette/src/sandbox/sidebarMocking.tsx

diff --git a/ivette/src/frama-c/index.tsx b/ivette/src/frama-c/index.tsx
index 22e06943d76..67192985b75 100644
--- a/ivette/src/frama-c/index.tsx
+++ b/ivette/src/frama-c/index.tsx
@@ -20,9 +20,9 @@
 /*                                                                          */
 /* ************************************************************************ */
 
-/* --------------------------------------------------------------------------*/
-/* --- Frama-C Registry                                                   ---*/
-/* --------------------------------------------------------------------------*/
+/* -------------------------------------------------------------------------- */
+/* --- Frama-C Registry                                                   --- */
+/* -------------------------------------------------------------------------- */
 
 import React from 'react';
 import * as Ivette from 'ivette';
@@ -37,9 +37,6 @@ import PivotTable from 'frama-c/kernel/PivotTable';
 import Locations from 'frama-c/kernel/Locations';
 import Properties from 'frama-c/kernel/Properties';
 import Messages from 'frama-c/kernel/Messages';
-import * as SideBar from '../sandbox/sidebar';
-
-import funcIco from '../sandbox/icons/function.png';
 
 import 'frama-c/kernel/style.css';
 
@@ -47,20 +44,27 @@ import * as Menu from 'frama-c/menu';
 
 Menu.init();
 
-/* --------------------------------------------------------------------------*/
-/* --- Frama-C Kernel Groups                                              ---*/
-/* --------------------------------------------------------------------------*/
+/* -------------------------------------------------------------------------- */
+/* --- Frama-C Tools                                                      --- */
+/* -------------------------------------------------------------------------- */
+
+Ivette.registerSidebar({
+  id: 'frama-c.globals',
+  label: 'AST',
+  children: <Globals />
+});
+
+Ivette.registerToolbar({ id: 'frama-c.history', children: <History /> });
+Ivette.registerStatusbar({ id: 'frama-c.message', children: <Status /> });
+
+/* -------------------------------------------------------------------------- */
+/* --- Frama-C Kernel Groups                                              --- */
+/* -------------------------------------------------------------------------- */
 
 Ivette.registerGroup({
   id: 'frama-c.kernel',
   label: 'Frama-C Kernel',
 }, () => {
-  Ivette.registerSidebar({
-    id: 'frama-c.sidebar',
-    children: <SideBar.SideBar />
-  });
-  Ivette.registerToolbar({ id: 'frama-c.history', children: <History /> });
-  Ivette.registerStatusbar({ id: 'frama-c.message', children: <Status /> });
   Ivette.registerComponent({
     id: 'frama-c.astinfo',
     label: 'Inspector',
@@ -105,18 +109,18 @@ Ivette.registerGroup({
   });
 });
 
-/* --------------------------------------------------------------------------*/
-/* --- Frama-C Plug-ins Group                                             ---*/
-/* --------------------------------------------------------------------------*/
+/* -------------------------------------------------------------------------- */
+/* --- Frama-C Plug-ins Group                                             --- */
+/* -------------------------------------------------------------------------- */
 
 Ivette.registerGroup({
   id: 'frama-c.plugins',
   label: 'Frama-C Plug-ins',
 });
 
-/* --------------------------------------------------------------------------*/
-/* --- Frama-C Views                                                      ---*/
-/* --------------------------------------------------------------------------*/
+/* -------------------------------------------------------------------------- */
+/* --- Frama-C Views                                                      --- */
+/* -------------------------------------------------------------------------- */
 
 Ivette.registerView({
   id: 'source',
@@ -148,16 +152,4 @@ Ivette.registerView({
   ],
 });
 
-/* --------------------------------------------------------------------------*/
-/* --- Frama-C Categories                                                 ---*/
-/* --------------------------------------------------------------------------*/
-
-Ivette.registerCategory({
-  id: "functions",
-  label: "Functions",
-  iconPath: funcIco,
-  children: <Globals />
-});
-
-
-/* --------------------------------------------------------------------------*/
+/* -------------------------------------------------------------------------- */
diff --git a/ivette/src/ivette/index.tsx b/ivette/src/ivette/index.tsx
index 1bc90a1e9ab..f3169e20e94 100644
--- a/ivette/src/ivette/index.tsx
+++ b/ivette/src/ivette/index.tsx
@@ -20,9 +20,9 @@
 /*                                                                          */
 /* ************************************************************************ */
 
-/* --------------------------------------------------------------------------*/
-/* --- Lab View Component                                                 ---*/
-/* --------------------------------------------------------------------------*/
+/* -------------------------------------------------------------------------- */
+/* --- Lab View Component                                                 --- */
+/* -------------------------------------------------------------------------- */
 
 /**
    @packageDocumentation
@@ -36,11 +36,10 @@ import { DefineElement } from 'dome/layout/dispatch';
 import { GridItem, GridHbox, GridVbox } from 'dome/layout/grids';
 import * as Lab from 'ivette@lab';
 import * as Ext from 'ivette@ext';
-import * as Doublebar from '../sandbox/sidebar';
 
-/* --------------------------------------------------------------------------*/
-/* --- Items                                                              ---*/
-/* --------------------------------------------------------------------------*/
+/* -------------------------------------------------------------------------- */
+/* --- Items                                                              --- */
+/* -------------------------------------------------------------------------- */
 
 export interface ItemProps {
   /** Identifier. */
@@ -58,9 +57,9 @@ export interface ContentProps extends ItemProps {
   children?: React.ReactNode;
 }
 
-/* --------------------------------------------------------------------------*/
-/* --- Groups                                                             ---*/
-/* --------------------------------------------------------------------------*/
+/* -------------------------------------------------------------------------- */
+/* --- Groups                                                             --- */
+/* -------------------------------------------------------------------------- */
 
 let GROUP: string | undefined;
 
@@ -85,9 +84,9 @@ export function registerGroup(group: ItemProps, job?: () => void): void {
   }
 }
 
-/* --------------------------------------------------------------------------*/
-/* --- View Layout                                                        ---*/
-/* --------------------------------------------------------------------------*/
+/* -------------------------------------------------------------------------- */
+/* --- View Layout                                                        --- */
+/* -------------------------------------------------------------------------- */
 
 /**
    Alternating V-split and H-split layouts.
@@ -128,9 +127,9 @@ export function registerView(view: ViewLayoutProps): void {
   });
 }
 
-/* --------------------------------------------------------------------------*/
-/* --- Components                                                         ---*/
-/* --------------------------------------------------------------------------*/
+/* -------------------------------------------------------------------------- */
+/* --- Components                                                         --- */
+/* -------------------------------------------------------------------------- */
 
 export interface ComponentProps extends ContentProps {
   /** Group attachment. */
@@ -178,9 +177,9 @@ export function TitleBar(props: TitleBarProps): JSX.Element | null {
   );
 }
 
-/* --------------------------------------------------------------------------*/
-/* --- Sidebar Panels                                                     ---*/
-/* --------------------------------------------------------------------------*/
+/* -------------------------------------------------------------------------- */
+/* --- Sidebar Panels                                                     --- */
+/* -------------------------------------------------------------------------- */
 
 export interface ToolProps {
   id: string;
@@ -188,34 +187,38 @@ export interface ToolProps {
   children?: React.ReactNode;
 }
 
+/** @ignore */
+export const TOOLBAR = new Ext.ElementRack<ToolProps>();
+
+/** @ignore */
+export const STATUSBAR = new Ext.ElementRack<ToolProps>();
+
 export function registerToolbar(tools: ToolProps): void {
-  Ext.TOOLBAR.register(tools);
+  TOOLBAR.register(tools);
 }
 
 export function registerStatusbar(status: ToolProps): void {
-  Ext.STATUSBAR.register(status);
+  STATUSBAR.register(status);
 }
 
-/* --------------------------------------------------------------------------*/
-/* --- Sidebar                                                         ---*/
-/* --------------------------------------------------------------------------*/
+/* -------------------------------------------------------------------------- */
+/* --- Sidebar                                                           ---  */
+/* -------------------------------------------------------------------------- */
 
-export interface SideBarCategoryProps extends ContentProps{
-  label: string;
+export interface SidebarProps extends ContentProps {
   iconPath?: string;
 }
 
-export function registerSidebar(panel: ToolProps): void {
-  Ext.SIDEBAR.register(panel);
-}
+/** @ignore */
+export const SIDEBAR = new Ext.ElementRack<SidebarProps>();
 
-export function registerCategory(props: SideBarCategoryProps): void {
-  Doublebar.registerCategory(props);
+export function registerSidebar(sidebar: SidebarProps): void {
+  SIDEBAR.register(sidebar);
 }
 
-/* --------------------------------------------------------------------------*/
-/* --- Sandbox                                                            ---*/
-/* --------------------------------------------------------------------------*/
+/* -------------------------------------------------------------------------- */
+/* --- Sandbox                                                            --- */
+/* -------------------------------------------------------------------------- */
 
 if (DEVEL) {
   registerGroup({
@@ -236,4 +239,4 @@ export function registerSandbox(props: ComponentProps): void {
   if (DEVEL) registerComponent({ ...props, group: 'sandbox' });
 }
 
-// --------------------------------------------------------------------------
+/* -------------------------------------------------------------------------- */
diff --git a/ivette/src/renderer/Application.tsx b/ivette/src/renderer/Application.tsx
index c6a1f7276e0..e1b8817d674 100644
--- a/ivette/src/renderer/Application.tsx
+++ b/ivette/src/renderer/Application.tsx
@@ -31,10 +31,11 @@ import * as Dome from 'dome';
 import { Vfill } from 'dome/layout/boxes';
 import { LSplit } from 'dome/layout/splitters';
 import * as Toolbar from 'dome/frame/toolbars';
-import * as Sidebar from 'dome/frame/sidebars';
+import * as Sidebar from './Sidebar';
 import * as Controller from './Controller';
-import * as Extensions from './Extensions';
 import * as Laboratory from './Laboratory';
+import * as Ext from './Extensions';
+import { TOOLBAR, STATUSBAR } from 'ivette';
 import * as IvettePrefs from 'ivette/prefs';
 import * as Studia from 'frama-c/plugins/studia/studia';
 import './loader';
@@ -51,6 +52,8 @@ export default function Application(): JSX.Element {
     Dome.useFlipSettings('frama-c.viewbar.unfold', true);
 
   Studia.useStudiaMode();
+  const tools = Ext.useChildren(TOOLBAR);
+  const status = Ext.useChildren(STATUSBAR);
 
   return (
     <Vfill>
@@ -62,7 +65,7 @@ export default function Application(): JSX.Element {
           onClick={flipSidebar}
         />
         <Controller.Control />
-        <Extensions.Toolbar />
+        <>{tools}</>
         <Toolbar.Filler />
         <IvettePrefs.ThemeSwitchTool />
         <IvettePrefs.FontTools />
@@ -75,10 +78,7 @@ export default function Application(): JSX.Element {
         />
       </Toolbar.ToolBar>
       <LSplit settings="frama-c.sidebar.split" unfold={sidebar}>
-        <Sidebar.SideBar>
-          <div className="sidebar-ruler" />
-          <Extensions.Sidebar />
-        </Sidebar.SideBar>
+        <Sidebar.Panel />
         <Laboratory.LabView
           customize={viewbar}
           settings="frama-c.labview"
@@ -86,7 +86,7 @@ export default function Application(): JSX.Element {
       </LSplit>
       <Toolbar.ToolBar>
         <Controller.Status />
-        <Extensions.Statusbar />
+        <>{status}</>
         <Toolbar.Filler />
         <Controller.Stats />
       </Toolbar.ToolBar>
diff --git a/ivette/src/renderer/Extensions.tsx b/ivette/src/renderer/Extensions.tsx
index 4b8ec17ea0a..3f4a16e55e2 100644
--- a/ivette/src/renderer/Extensions.tsx
+++ b/ivette/src/renderer/Extensions.tsx
@@ -39,7 +39,7 @@ export interface ElementProps {
   children?: React.ReactNode;
 }
 
-function byPanel(p: ElementProps, q: ElementProps): number {
+function byRank(p: ElementProps, q: ElementProps): number {
   const rp = p.rank ?? 0;
   const rq = q.rank ?? 0;
   if (rp < rq) return -1;
@@ -51,38 +51,38 @@ function byPanel(p: ElementProps, q: ElementProps): number {
   return 0;
 }
 
-export class ElementRack {
+export class ElementRack<A extends ElementProps> {
 
   private rank = 1;
-  private readonly items = new Map<string, ElementProps>();
+  private readonly items = new Map<string, A>();
 
-  register(elt: ElementProps): void {
+  register(elt: A): void {
     if (elt.rank === undefined) elt.rank = this.rank;
     this.rank++;
     this.items.set(elt.id, elt);
     UPDATED.emit();
   }
 
-  render(): JSX.Element {
-    const panels: ElementProps[] = [];
-    this.items.forEach((p) => { if (p.children) { panels.push(p); } });
-    const contents = panels.sort(byPanel).map((p) => p.children);
-    return <>{React.Children.toArray(contents)}</>;
+  getElements(): A[] {
+    const buffer: A[] = [];
+    this.items.forEach((p) => { if (p.children) { buffer.push(p); } });
+    return buffer.sort(byRank);
   }
 
 }
 
-export function useRack(E: ElementRack): JSX.Element {
+export function useElements<A extends ElementProps>(
+  E: ElementRack<A>
+): A[] {
   Dome.useUpdate(UPDATED);
-  return E.render();
+  return E.getElements();
 }
 
-export const SIDEBAR = new ElementRack();
-export const TOOLBAR = new ElementRack();
-export const STATUSBAR = new ElementRack();
-
-export function Sidebar(): JSX.Element { return useRack(SIDEBAR); }
-export function Toolbar(): JSX.Element { return useRack(TOOLBAR); }
-export function Statusbar(): JSX.Element { return useRack(STATUSBAR); }
+export function useChildren<A extends ElementProps>(
+  E: ElementRack<A>
+): React.ReactNode {
+  const elements = useElements(E);
+  return React.Children.toArray(elements.map((e) => e.children));
+}
 
 /* --------------------------------------------------------------------------*/
diff --git a/ivette/src/renderer/Sidebar.tsx b/ivette/src/renderer/Sidebar.tsx
new file mode 100644
index 00000000000..61d2ac6af26
--- /dev/null
+++ b/ivette/src/renderer/Sidebar.tsx
@@ -0,0 +1,124 @@
+/* ************************************************************************ */
+/*                                                                          */
+/*   This file is part of Frama-C.                                          */
+/*                                                                          */
+/*   Copyright (C) 2007-2023                                                */
+/*     CEA (Commissariat à l'énergie atomique et aux énergies               */
+/*          alternatives)                                                   */
+/*                                                                          */
+/*   you can redistribute it and/or modify it under the terms of the GNU    */
+/*   Lesser General Public License as published by the Free Software        */
+/*   Foundation, version 2.1.                                               */
+/*                                                                          */
+/*   It is distributed in the hope that it will be useful,                  */
+/*   but WITHOUT ANY WARRANTY; without even the implied warranty of         */
+/*   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the          */
+/*   GNU Lesser General Public License for more details.                    */
+/*                                                                          */
+/*   See the GNU Lesser General Public License version 2.1                  */
+/*   for more details (enclosed in the file licenses/LGPLv2.1).             */
+/*                                                                          */
+/* ************************************************************************ */
+
+// --------------------------------------------------------------------------
+// --- Sidebar Selector
+// --------------------------------------------------------------------------
+
+import React from 'react';
+import { SIDEBAR } from 'ivette';
+import * as Ext from './Extensions';
+
+/*
+   export function SideBar(): JSX.Element {
+   const classNameGlobal = classes(
+   'dome-xSideBar-double',
+   );
+
+   const classNamePrime = classes(
+   'dome-xSideBar-double-primary',
+   'dome-color-frame',
+   );
+
+   const classNamePrimeIcon = classes(
+   'dome-xSideBar-double-primary-icon'
+   );
+
+   const classNamePrimeLabel = classes(
+   'dome-xSideBar-double-primary-label'
+   );
+
+   const classNameSecondary = classes(
+   'dome-xSideBar-double-secondary',
+   'dome-color-frame',
+   );
+
+   const [selectedCategory, setSelectedCategory] = useState(0);
+
+   function updateSelected(key: number): void {
+   setSelectedCategory(key);
+   categories[key].display = true;
+   }
+
+   return (
+   <Catch label={"dome-xSideBar-double-catch"}>
+   <div className={classNameGlobal}>
+   <div className={classNamePrime}>
+   <>
+   {categories.map((item, key) => (
+   <div key={key}>
+   {item.iconPath ?
+   <img
+   className={classNamePrimeIcon}
+   id={item.id}
+   src={item.iconPath}
+   alt={item.label}
+   title={item.label}
+   onClick={
+   () => updateSelected(key)
+   }
+   />
+   :
+   <label
+   className={classNamePrimeLabel}
+   id={item.id}
+   onClick={
+   () => updateSelected(key)
+   }
+   >
+   {item.label.slice(0, 4).toLocaleUpperCase()}
+   </label>
+   }
+   <br/>
+   </div>
+   ))}
+   </>
+   </div>
+   <sb.SideBar className={classNameSecondary +
+   (categories[selectedCategory].display === false ? 'dome-erased' : '')}>
+   {categories[selectedCategory].children}
+   </sb.SideBar>
+   </div>
+   </Catch>
+   );
+   }
+ */
+
+export function Panel(): JSX.Element {
+  const sidebars = Ext.useElements(SIDEBAR);
+  const items = sidebars.map((sb) => (
+    <ul key={sb.id}>
+      {sb.label}
+    </ul>
+  ));
+  return (
+    <div>
+      <div className='sidebar-ruler' />
+      Side Bar Selector
+      <ul>
+        {items}
+      </ul>
+    </div>
+  );
+}
+
+// --------------------------------------------------------------------------
diff --git a/ivette/src/sandbox/sidebar.tsx b/ivette/src/sandbox/sidebar.tsx
index 41bcd992848..dc9b9a5dd31 100644
--- a/ivette/src/sandbox/sidebar.tsx
+++ b/ivette/src/sandbox/sidebar.tsx
@@ -21,193 +21,52 @@
 /* ************************************************************************ */
 
 
-import React, { useState } from 'react';
-import { classes } from 'dome/misc/utils';
+import React from 'react';
 import { Item, Section } from "dome/frame/sidebars";
-import { Catch } from 'dome/errors';
-import { SideBarCategoryProps, registerSandbox } from 'ivette';
-import * as sb from '../../src/dome/renderer/frame/sidebars';
-import './style.css';
+import * as Ivette from 'ivette';
 
 /* -------------------------------------------------------------------------- */
 /* --- Mocking                                                            --- */
 /* -------------------------------------------------------------------------- */
 
-interface Category extends SideBarCategoryProps{
-  display: boolean;
-}
-
-const itemsSection1 = (
-  <div>
-    <Item
-      className="class1.1"
-      label="item 1.1-l"
-      title="item 1.1-t"
-      selected={false}
-    />
-    <Item
-      className="class1.2"
-      label="item 1.2-l"
-      title="item 1.2-t"
-      selected={false}
-    />
-    <Item
-      className="class1.3"
-      label="item 1.3-l"
-      title="item 1.3-t"
-      selected={false}
-    />
-  </div>
-);
-
-const itemsSection2 = (
-  <div>
-    <Item
-      className="class2.1"
-      label="item 2.1-l"
-      title="item 2.1-t"
-      selected={false}
-    />
-    <Item
-      className="class2.2"
-      label="item 2.2-l"
-      title="item 2.2-t"
-      selected={false}
-    />
-    <Item
-      className="class2.3"
-      label="item 2.3-l"
-      title="item 2.3-t"
-      selected={false}
-      />
-  </div>
-);
-
-export const secondaryMenu1 = (
-  <>
-    <Section
-      label="label section1"
-      title="title section1"
-      defaultUnfold
-      settings="frama-c.sidebar.updated"
-      className='globals-function-section'
-    >
-      {itemsSection1}
-    </Section>
-    <Section
-      label="label section2"
-      title="title section2"
-      defaultUnfold={false}
-      settings="frama-c.sidebar.updated2"
-      className='globals-function-section'
-    >
-    {itemsSection2}
-  </Section>
-</>
-);
-
-export const secondaryMenu2 = (
-  <>
-    <Section
-      label="label section1"
-      title="title section1"
-      defaultUnfold={false}
-      settings="frama-c.sidebar.updated2"
-      className='globals-function-section'
-    >
-      {itemsSection2}
-    </Section>
-  </>
-);
-
-const categories: Category[] = [];
-
-export function registerCategory(item: SideBarCategoryProps): void {
-  categories.push({ ...item, display: false });
-}
-
-export function SideBar(): JSX.Element {
-  const classNameGlobal = classes(
-    'dome-xSideBar-double',
-  );
-
-  const classNamePrime = classes(
-    'dome-xSideBar-double-primary',
-    'dome-color-frame',
-  );
-
-  const classNamePrimeIcon = classes(
-    'dome-xSideBar-double-primary-icon'
-  );
-
-  const classNamePrimeLabel = classes(
-    'dome-xSideBar-double-primary-label'
-  );
-
-  const classNameSecondary = classes(
-    'dome-xSideBar-double-secondary',
-    'dome-color-frame',
-  );
-
-  const [selectedCategory, setSelectedCategory] = useState(0);
-
-  function updateSelected(key: number): void {
-    setSelectedCategory(key);
-    categories[key].display = true;
-  }
-
-  return (
-    <Catch label={"dome-xSideBar-double-catch"}>
-    <div className={classNameGlobal}>
-      <div className={classNamePrime}>
-        <>
-          {categories.map((item, key) => (
-            <div key={key}>
-              {item.iconPath ?
-                <img
-                className={classNamePrimeIcon}
-                id={item.id}
-                src={item.iconPath}
-                alt={item.label}
-                title={item.label}
-                onClick={
-                  () => updateSelected(key)
-                }
-                />
-                :
-                <label
-                className={classNamePrimeLabel}
-                id={item.id}
-                onClick={
-                  () => updateSelected(key)
-                }
-                >
-                  {item.label.slice(0, 4).toLocaleUpperCase()}
-                </label>
-              }
-              <br/>
-            </div>
-          ))}
-        </>
-      </div>
-      <sb.SideBar className={classNameSecondary +
-      (categories[selectedCategory].display === false ? 'dome-erased' : '')}>
-        {categories[selectedCategory].children}
-      </sb.SideBar>
-    </div>
-    </Catch>
-  );
-}
-
-
-/* -------------------------------------------------------------------------- */
-/* --- Sandbox                                                            --- */
-/* -------------------------------------------------------------------------- */
+Ivette.registerSidebar({
+  id: 'sandbox.sidebar.a',
+  label: 'SandA',
+  children:
+    <>
+      <Section label='Section A.1'>
+        <Item label='Item A.1.1' />
+        <Item label='Item A.1.2' />
+        <Item label='Item A.1.3' />
+        <Item label='Item A.1.4' />
+      </Section>
+      <Section label='Section A.2'>
+        <Item label='Item A.2.1' />
+        <Item label='Item A.2.2' />
+        <Item label='Item A.2.3' />
+        <Item label='Item A.2.4' />
+      </Section>
+    </>
+});
 
-registerSandbox({
-  id: 'sandbox.sidebar',
-  label: 'Sidebar',
-  children: <SideBar />,
+Ivette.registerSidebar({
+  id: 'sandbox.sidebar.b',
+  label: 'SandB',
+  children:
+    <>
+      <Section label='Section B.1'>
+        <Item label='Item B.1.1' />
+        <Item label='Item B.1.2' />
+        <Item label='Item B.1.3' />
+        <Item label='Item B.1.4' />
+      </Section>
+      <Section label='Section B.2'>
+        <Item label='Item B.2.1' />
+        <Item label='Item B.2.2' />
+        <Item label='Item B.2.3' />
+        <Item label='Item B.2.4' />
+      </Section>
+    </>
 });
 
 /* -------------------------------------------------------------------------- */
diff --git a/ivette/src/sandbox/sidebarMocking.tsx b/ivette/src/sandbox/sidebarMocking.tsx
deleted file mode 100644
index 5b678f03a68..00000000000
--- a/ivette/src/sandbox/sidebarMocking.tsx
+++ /dev/null
@@ -1,75 +0,0 @@
-/* ************************************************************************ */
-/*                                                                          */
-/*   This file is part of Frama-C.                                          */
-/*                                                                          */
-/*   Copyright (C) 2007-2023                                                */
-/*     CEA (Commissariat à l'énergie atomique et aux énergies               */
-/*          alternatives)                                                   */
-/*                                                                          */
-/*   you can redistribute it and/or modify it under the terms of the GNU    */
-/*   Lesser General Public License as published by the Free Software        */
-/*   Foundation, version 2.1.                                               */
-/*                                                                          */
-/*   It is distributed in the hope that it will be useful,                  */
-/*   but WITHOUT ANY WARRANTY; without even the implied warranty of         */
-/*   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the          */
-/*   GNU Lesser General Public License for more details.                    */
-/*                                                                          */
-/*   See the GNU Lesser General Public License version 2.1                  */
-/*   for more details (enclosed in the file licenses/LGPLv2.1).             */
-/*                                                                          */
-/* ************************************************************************ */
-
-
-import React from 'react';
-import * as Ivette from 'ivette';
-import { registerSandbox } from 'ivette';
-import * as SideBar from './sidebar';
-import fileIco from './icons/file.png';
-import folderIco from './icons/folder.png';
-
-/* -------------------------------------------------------------------------- */
-/* --- Mocking                                                            --- */
-/* -------------------------------------------------------------------------- */
-
-export function SideBarMocking(): JSX.Element {
-    Ivette.registerCategory({
-        id: "file",
-        label: "File",
-        iconPath: fileIco,
-        children: SideBar.secondaryMenu1
-      });
-      Ivette.registerCategory({
-        id: "folder",
-        label: "Folder",
-        iconPath: folderIco,
-        children: SideBar.secondaryMenu2
-      });
-      Ivette.registerCategory({
-        id: "lorem",
-        label: "lorem",
-        children: SideBar.secondaryMenu1
-      });
-      Ivette.registerCategory({
-        id: "ipsum",
-        label: "ipsum",
-        children: SideBar.secondaryMenu2
-      });
-
-    return (
-        <SideBar.SideBar></SideBar.SideBar>
-    );
-}
-
-/* -------------------------------------------------------------------------- */
-/* --- Sandbox                                                            --- */
-/* -------------------------------------------------------------------------- */
-
-
-registerSandbox({
-    id: 'sandbox.sidebar-mocking',
-    label: 'Sidebar Mocking',
-    children: <SideBarMocking />,
-  });
-
-/* -------------------------------------------------------------------------- */
-- 
GitLab