Kopfleiste: Steckplatz "aktionen" für eigene Knöpfe der Tools

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
Kerim AtilganandClaude Opus 5.5 committed 2026-10-25 10:49:42 +01:00
1 parent 9c6f721e44
commit a3c974c219
2 files changed
+21

No files matched your search

+16
View File
@@ -44,6 +44,22 @@ Eigene Icons können in Authentik hochgeladen werden, sonst nimmt das Portal sei
- `data-auto="false"`: nicht automatisch einfügen, sondern selbst `<hi-topbar app="vvl"></hi-topbar>` platzieren. - `data-auto="false"`: nicht automatisch einfügen, sondern selbst `<hi-topbar app="vvl"></hi-topbar>` platzieren.
- Die Leiste ist 44 px hoch und setzt `--hi-topbar-height` auf `<html>`. Layouts mit `height: 100vh` sollten `calc(100vh - var(--hi-topbar-height, 0px))` verwenden. - Die Leiste ist 44 px hoch und setzt `--hi-topbar-height` auf `<html>`. Layouts mit `height: 100vh` sollten `calc(100vh - var(--hi-topbar-height, 0px))` verwenden.
- Die Leiste nutzt Shadow DOM, CSS-Konflikte mit dem Tool sind also ausgeschlossen. - Die Leiste nutzt Shadow DOM, CSS-Konflikte mit dem Tool sind also ausgeschlossen.
- **Eigene Knöpfe** (z.B. Speichern, Filter, Hilfe) erscheinen rechts vor dem Avatar, wenn sie als Kind mit `slot="aktionen"` in `<hi-topbar>` stehen. Die Leiste ist dunkelviolett, Text erbt Weiß; das Styling der Knöpfe bleibt beim Tool.
```html
<!-- mit data-auto="false" selbst platziert -->
<hi-topbar app="vvl">
<button slot="aktionen" class="mein-knopf">Speichern</button>
</hi-topbar>
```
```js
// oder in die automatisch eingefügte Leiste hängen (nach DOMContentLoaded, in React z.B. im useEffect)
const btn = document.createElement('button');
btn.slot = 'aktionen';
btn.textContent = 'Speichern';
document.querySelector('hi-topbar')?.append(btn);
```
**Content-Security-Policy des Tools erweitern** (sonst blockiert der Browser die Leiste): **Content-Security-Policy des Tools erweitern** (sonst blockiert der Browser die Leiste):
+5
View File
@@ -9,6 +9,9 @@
* Die Höhe steht als CSS-Variable --hi-topbar-height bereit, z.B. für * Die Höhe steht als CSS-Variable --hi-topbar-height bereit, z.B. für
* Layouts mit height: calc(100vh - var(--hi-topbar-height, 0px)). * Layouts mit height: calc(100vh - var(--hi-topbar-height, 0px)).
* *
* Eigene Knöpfe des Tools erscheinen rechts vor dem Avatar, wenn sie als Kind
* mit slot="aktionen" in <hi-topbar> stehen.
*
* Voraussetzung in der CSP des Tools: script-src, connect-src und img-src * Voraussetzung in der CSP des Tools: script-src, connect-src und img-src
* müssen https://portal.handy-insel.de erlauben. * müssen https://portal.handy-insel.de erlauben.
*/ */
@@ -58,6 +61,7 @@ a { color: inherit; text-decoration: none; }
.app-name { opacity: .85; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; min-width: 0; } .app-name { opacity: .85; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; min-width: 0; }
.sep { width: 1px; height: 18px; background: rgba(255,255,255,.3); margin: 0 4px; } .sep { width: 1px; height: 18px; background: rgba(255,255,255,.3); margin: 0 4px; }
.spacer { flex: 1; } .spacer { flex: 1; }
::slotted(*) { flex: none; margin: 0 2px; }
.avatar { width: 30px; height: 30px; border-radius: 50%; background: #fff; color: #2d1b69; font-size: 12px; font-weight: 700; .avatar { width: 30px; height: 30px; border-radius: 50%; background: #fff; color: #2d1b69; font-size: 12px; font-weight: 700;
display: grid; place-items: center; } display: grid; place-items: center; }
.panel { position: absolute; top: ${HEIGHT + 6}px; background: var(--p-bg); color: var(--p-text); border-radius: 12px; .panel { position: absolute; top: ${HEIGHT + 6}px; background: var(--p-bg); color: var(--p-text); border-radius: 12px;
@@ -211,6 +215,7 @@ class HiTopbar extends HTMLElement {
<a class="brand" href="${esc(links.portal)}"><img src="${PORTAL}/insel-logo.png" alt=""><span>Handy-<b>Insel</b></span></a> <a class="brand" href="${esc(links.portal)}"><img src="${PORTAL}/insel-logo.png" alt=""><span>Handy-<b>Insel</b></span></a>
${appName ? `<span class="sep"></span><span class="app-name">${esc(appName)}</span>` : ''} ${appName ? `<span class="sep"></span><span class="app-name">${esc(appName)}</span>` : ''}
<span class="spacer"></span> <span class="spacer"></span>
<slot name="aktionen"></slot>
${ ${
user user
? `<button class="icon-btn" data-toggle="user" aria-haspopup="true" aria-expanded="${this.open === 'user'}" title="${esc(user.name)}"><span class="avatar">${esc(user.initials)}</span></button>` ? `<button class="icon-btn" data-toggle="user" aria-haspopup="true" aria-expanded="${this.open === 'user'}" title="${esc(user.name)}"><span class="avatar">${esc(user.initials)}</span></button>`