From b5901b31e363ba492d5818610ee9a1e29917fc5c Mon Sep 17 00:00:00 2001 From: Shinuwa Date: Thu, 24 Sep 2026 14:05:17 +0200 Subject: [PATCH] Allow toolbox tools to collapse into their headers --- DESIGN_SYSTEM.md | 1 + docs/STORAGE_SCHEMA.md | 4 +- tests/static-toolboxes.test.mjs | 21 +- tests/toolbox-modules.test.mjs | 13 ++ .../toolboxes/modules/ModuleShell.jsx | 186 ++++++++++++++++++ .../toolboxes/modules/ToolboxModules.jsx | 158 +-------------- .../toolboxes/storage/toolboxStorage.js | 1 + .../src/styles/toolboxes/_module-shell.scss | 10 +- 8 files changed, 228 insertions(+), 166 deletions(-) create mode 100644 website/src/features/toolboxes/modules/ModuleShell.jsx diff --git a/DESIGN_SYSTEM.md b/DESIGN_SYSTEM.md index 27605ca..7e4b4b1 100644 --- a/DESIGN_SYSTEM.md +++ b/DESIGN_SYSTEM.md @@ -188,6 +188,7 @@ Style courant : - hover violet/violet clair moins intense que les cards ; - pas de mouvement au hover ; - contenu interne au-dessus des pseudo-bordures via `z-index`. +- chevron de repli tout à droite de l'en-tête ; l'état replié conserve uniquement l'en-tête visible et retire son séparateur bas. Le mot visible cote utilisateur est **outil**, pas **module**. Le terme module reste acceptable uniquement dans le code. diff --git a/docs/STORAGE_SCHEMA.md b/docs/STORAGE_SCHEMA.md index e156cbb..a74140e 100644 --- a/docs/STORAGE_SCHEMA.md +++ b/docs/STORAGE_SCHEMA.md @@ -113,7 +113,8 @@ Les toolboxes sont stockées dans `kv/toolboxes`. { "id": "mod1", "type": "checklist", - "title": "Armures" + "title": "Armures", + "collapsed": true } ], "moduleColumns": 2, @@ -137,6 +138,7 @@ Notes : - Chaque identifiant d'outil présent dans `modules` doit apparaître exactement une fois dans `moduleOrder.one` et exactement une fois dans l'une des deux colonnes de `moduleOrder.two`. - Si une ancienne toolbox n'a pas encore `moduleOrder.two`, les outils sont répartis automatiquement depuis l'ordre une colonne avec une moitié en colonne gauche et une moitié en colonne droite. - Les données lourdes des outils ne sont pas stockées dans la toolbox, mais dans `modules`. +- `modules[].collapsed` vaut `true` lorsque seul l'en-tête de l'outil est affiché ; il est omis lorsque l'outil est déplié. - `tutorial` est un indicateur temporaire réservé aux toolboxes créées depuis la prise en main. Il déclenche les premiers repères à l'ouverture, puis il est retiré automatiquement du stockage. ## Liens Jeu / Toolbox diff --git a/tests/static-toolboxes.test.mjs b/tests/static-toolboxes.test.mjs index c4f747f..a1ef905 100644 --- a/tests/static-toolboxes.test.mjs +++ b/tests/static-toolboxes.test.mjs @@ -92,7 +92,8 @@ test("toolbox module registry and modules expose expected behavior", async () => const moduleComponents = await readFile("website/src/features/toolboxes/modules/toolboxModuleComponents.jsx", "utf8"); const addToolControls = await readFile("website/src/features/toolboxes/modules/AddToolControls.jsx", "utf8"); const toolboxModules = await readFile("website/src/features/toolboxes/modules/ToolboxModules.jsx", "utf8"); - const moduleRegistryBundle = `${moduleRegistry}\n${moduleComponents}\n${addToolControls}\n${toolboxModules}`; + const moduleShell = await readFile("website/src/features/toolboxes/modules/ModuleShell.jsx", "utf8"); + const moduleRegistryBundle = `${moduleRegistry}\n${moduleComponents}\n${addToolControls}\n${toolboxModules}\n${moduleShell}`; const moduleMetadataRegistry = await readFile("website/src/features/toolboxes/toolboxModuleRegistry.js", "utf8"); const notepadModule = await readFile("website/src/features/toolboxes/modules/NotepadModule.jsx", "utf8"); const notepadToolbar = await readFile("website/src/features/toolboxes/modules/NotepadToolbar.jsx", "utf8"); @@ -189,6 +190,7 @@ test("toolbox module registry and modules expose expected behavior", async () => [ ["AddToolControls.jsx", addToolControls], ["ToolboxModules.jsx", toolboxModules], + ["ModuleShell.jsx", moduleShell], ["useCalendarController.js", calendarController], ["useCalendarDraftControls.js", calendarDraftControls], ["calendarEventActions.js", calendarEventActions], @@ -212,21 +214,24 @@ test("toolbox module registry and modules expose expected behavior", async () => assert.match(moduleRegistry, /export \{ AddToolControls \}/); assert.match(moduleRegistry, /export \{ ToolboxModules \}/); assert.match(moduleComponents, /MODULE_COMPONENTS/); - assert.match(toolboxModules, /Suspense fallback=\{\}/); + assert.match(moduleShell, /Suspense fallback=\{\}/); assert.match(moduleMetadataRegistry, /Planificateur d'équipements/); assert.match(moduleMetadataRegistry, /Annotation d'images/); - assert.match(toolboxModules, /module-edit-button/); - assert.match(toolboxModules, /itemReorder\.startDrag/); + assert.match(moduleShell, /module-edit-button/); + assert.match(moduleShell, /itemReorder\.startDrag/); assert.match(moduleRegistryBundle, /onPointerDown/); assert.match(toolboxModules, /useGroupedReorder/); - assert.match(toolboxModules, /useInlineEdit/); - assert.match(toolboxModules, /getContentEditableProps/); + assert.match(moduleShell, /useInlineEdit/); + assert.match(moduleShell, /getContentEditableProps/); assert.match(addToolControls, /tool-add-card/); assert.match(addToolControls, /tool-quick-add-button/); assert.match(addToolControls, /tool-add-quick-toggle/); assert.match(moduleMetadataRegistry, /scrollable: true/); - assert.match(toolboxModules, /module-content/); - assert.match(toolboxModules, /module-scroll-button/); + assert.match(moduleShell, /module-content/); + assert.match(moduleShell, /module-scroll-button/); + assert.match(moduleShell, /module-collapse-button/); + assert.match(moduleShell, /aria-expanded=\{!collapsed\}/); + assert.match(moduleShell, /!collapsed &&/); assert.match(addToolControls, /Icon name="dropdown"/); assert.match(addToolControls, /CompactDropdown/); assert.doesNotMatch(source, /