feat(ui): add outline/fill icon-swap pattern for aside icon bar

Introduce data-icon-swap attribute with paired outline/fill <i> elements.
CSS toggles to filled icon on hover and active state. Module slots
auto-derive fill variant from icon name, with explicit icon_fill override
for icons without a fill counterpart (e.g. bi-headset). Add enforcement
script bin/icon-swap-check.sh.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-04-06 22:22:00 +02:00
parent ae509c607b
commit a3d05baffa
3 changed files with 105 additions and 8 deletions

View File

@@ -11,8 +11,9 @@ $hasAdminPanel = layoutHasAdminPanel($layoutAuth);
<li>
<button type="button" id="aside-tab-explorer" data-aside-target="explorer" role="tab"
aria-selected="true" aria-controls="aside-panel-explorer" aria-label="<?php e(t('Explorer')); ?>"
data-tooltip="<?php e(t('Explorer')); ?>" data-tooltip-pos="right">
<i class="bi bi-house"></i>
data-tooltip="<?php e(t('Explorer')); ?>" data-tooltip-pos="right" data-icon-swap>
<i class="bi bi-house" data-icon="outline"></i>
<i class="bi bi-house-fill" data-icon="fill"></i>
</button>
</li>
<?php
@@ -24,6 +25,7 @@ $hasAdminPanel = layoutHasAdminPanel($layoutAuth);
$slotKey = $slot['key'] ?? '';
$slotLabel = $slot['label'] ?? '';
$slotIcon = $slot['icon'] ?? 'bi-puzzle';
$slotIconFill = $slot['icon_fill'] ?? ($slotIcon !== '' ? $slotIcon . '-fill' : 'bi-puzzle-fill');
$slotHref = $slot['href'] ?? '';
$slotPermission = $slot['permission'] ?? '';
if ($slotPermission !== '' && empty($layoutAuth[$slotPermission])) { continue; }
@@ -39,8 +41,9 @@ $hasAdminPanel = layoutHasAdminPanel($layoutAuth);
role="tab" aria-selected="false"
aria-controls="aside-panel-<?php e($slotKey); ?>"
aria-label="<?php e(t($slotLabel)); ?>"
data-tooltip="<?php e(t($slotLabel)); ?>" data-tooltip-pos="right">
<i class="bi <?php e($slotIcon); ?>"></i>
data-tooltip="<?php e(t($slotLabel)); ?>" data-tooltip-pos="right" data-icon-swap>
<i class="bi <?php e($slotIcon); ?>" data-icon="outline"></i>
<i class="bi <?php e($slotIconFill); ?>" data-icon="fill"></i>
</button>
</li>
<?php endforeach; ?>
@@ -49,8 +52,10 @@ $hasAdminPanel = layoutHasAdminPanel($layoutAuth);
<ul role="list">
<li>
<a href="<?php e($accountUrl); ?>" aria-label="<?php e(t('Account')); ?>"
data-tooltip="<?php e($accountTooltip); ?>" data-tooltip-pos="right" data-aside-shortcut="account"><i
class="bi bi-person-circle"></i></a>
data-tooltip="<?php e($accountTooltip); ?>" data-tooltip-pos="right" data-aside-shortcut="account" data-icon-swap>
<i class="bi bi-person" data-icon="outline"></i>
<i class="bi bi-person-fill" data-icon="fill"></i>
</a>
</li>
</ul>
<?php if ($hasAdminPanel): ?>
@@ -58,8 +63,9 @@ $hasAdminPanel = layoutHasAdminPanel($layoutAuth);
<li>
<button type="button" id="aside-tab-admin" data-aside-target="admin" role="tab" aria-selected="false"
aria-controls="aside-panel-admin" aria-label="<?php e(t('Admin')); ?>"
data-tooltip="<?php e(t('Admin')); ?>" data-tooltip-pos="right">
<i class="bi bi-gear"></i>
data-tooltip="<?php e(t('Admin')); ?>" data-tooltip-pos="right" data-icon-swap>
<i class="bi bi-gear" data-icon="outline"></i>
<i class="bi bi-gear-fill" data-icon="fill"></i>
</button>
</li>
</ul>