Symbolleiste professioneller gestaltet: echte SVG-Icons statt Unicode/Emoji
Neue ToolbarIcon.vue (hand-gezeichnete Strich-Icons: Einstellungen, Rückgängig/
Wiederholen, Tabelle/Diagramm/Text einfügen, Benannte Bereiche) ersetzt die
bisherigen ⚙ ↶ ↷ ▦ ▤ ¶ 🏷 Glyphen. Buttons sind jetzt in dezente,
segmentierte Gruppen ("Pills") statt einzeln umrandeter Kästchen mit dünnen
Trennstrichen gefasst, mit Ghost-Stil in Ruhe und Hover-/Aktiv-Zuständen.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
+112
-74
@@ -7,6 +7,7 @@ import BaseModal from './BaseModal.vue';
|
||||
import CustomFunctionsModal from './CustomFunctionsModal.vue';
|
||||
import NamedRangesModal from './NamedRangesModal.vue';
|
||||
import TheLogo from './TheLogo.vue';
|
||||
import ToolbarIcon from './ToolbarIcon.vue';
|
||||
import { WICOM, WICOM_SOCIAL } from '../config/brand';
|
||||
import {
|
||||
exportJson,
|
||||
@@ -210,55 +211,60 @@ function onReset() {
|
||||
aria-label="Einstellungen"
|
||||
@click="store.ui.settingsOpen = !store.ui.settingsOpen"
|
||||
>
|
||||
⚙
|
||||
<ToolbarIcon name="settings" />
|
||||
</button>
|
||||
|
||||
<span class="divider" />
|
||||
<button
|
||||
class="btn"
|
||||
title="Rückgängig (Strg/Cmd+Z)"
|
||||
:disabled="!store.canUndo.value"
|
||||
@click="store.undo()"
|
||||
>
|
||||
↶
|
||||
</button>
|
||||
<button
|
||||
class="btn"
|
||||
title="Wiederholen (Strg/Cmd+Y)"
|
||||
:disabled="!store.canRedo.value"
|
||||
@click="store.redo()"
|
||||
>
|
||||
↷
|
||||
</button>
|
||||
<div class="tgroup">
|
||||
<button
|
||||
class="ibtn"
|
||||
title="Rückgängig (Strg/Cmd+Z)"
|
||||
aria-label="Rückgängig"
|
||||
:disabled="!store.canUndo.value"
|
||||
@click="store.undo()"
|
||||
>
|
||||
<ToolbarIcon name="undo" />
|
||||
</button>
|
||||
<button
|
||||
class="ibtn"
|
||||
title="Wiederholen (Strg/Cmd+Y)"
|
||||
aria-label="Wiederholen"
|
||||
:disabled="!store.canRedo.value"
|
||||
@click="store.redo()"
|
||||
>
|
||||
<ToolbarIcon name="redo" />
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<span class="divider" />
|
||||
<button class="btn accent icon-btn" title="Tabelle einfügen" aria-label="Tabelle einfügen" @click="insertTable">
|
||||
▦
|
||||
</button>
|
||||
<button class="btn accent icon-btn" title="Diagramm einfügen" aria-label="Diagramm einfügen" @click="insertChart">
|
||||
▤
|
||||
</button>
|
||||
<button class="btn accent icon-btn" title="Text einfügen" aria-label="Text einfügen" @click="insertText">
|
||||
¶
|
||||
</button>
|
||||
<div class="tgroup accent">
|
||||
<button class="ibtn" title="Tabelle einfügen" aria-label="Tabelle einfügen" @click="insertTable">
|
||||
<ToolbarIcon name="table" />
|
||||
</button>
|
||||
<button class="ibtn" title="Diagramm einfügen" aria-label="Diagramm einfügen" @click="insertChart">
|
||||
<ToolbarIcon name="chart" />
|
||||
</button>
|
||||
<button class="ibtn" title="Text einfügen" aria-label="Text einfügen" @click="insertText">
|
||||
<ToolbarIcon name="text" />
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<span class="divider" />
|
||||
<button
|
||||
class="btn accent icon-btn"
|
||||
title="Benutzerdefinierte Funktionen"
|
||||
aria-label="Benutzerdefinierte Funktionen"
|
||||
@click="functionsOpen = true"
|
||||
>
|
||||
𝑓
|
||||
</button>
|
||||
<button
|
||||
class="btn accent icon-btn"
|
||||
title="Benannte Bereiche"
|
||||
aria-label="Benannte Bereiche"
|
||||
@click="namedRangesOpen = true"
|
||||
>
|
||||
🏷
|
||||
</button>
|
||||
<div class="tgroup accent">
|
||||
<button
|
||||
class="ibtn fx"
|
||||
title="Benutzerdefinierte Funktionen"
|
||||
aria-label="Benutzerdefinierte Funktionen"
|
||||
@click="functionsOpen = true"
|
||||
>
|
||||
<em>fx</em>
|
||||
</button>
|
||||
<button
|
||||
class="ibtn"
|
||||
title="Benannte Bereiche"
|
||||
aria-label="Benannte Bereiche"
|
||||
@click="namedRangesOpen = true"
|
||||
>
|
||||
<ToolbarIcon name="tag" />
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div class="spacer" />
|
||||
|
||||
@@ -410,8 +416,8 @@ function onReset() {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
flex-wrap: wrap;
|
||||
gap: 8px;
|
||||
padding: 10px 14px;
|
||||
gap: 10px;
|
||||
padding: 9px 16px;
|
||||
background: var(--surface);
|
||||
border-bottom: 1px solid var(--border);
|
||||
box-shadow: var(--shadow-sm);
|
||||
@@ -513,26 +519,72 @@ function onReset() {
|
||||
color: var(--accent);
|
||||
}
|
||||
.gear {
|
||||
border: 1px solid var(--border);
|
||||
background: var(--surface);
|
||||
border-radius: 8px;
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
font-size: 15px;
|
||||
line-height: 1;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
border: 1px solid transparent;
|
||||
background: transparent;
|
||||
border-radius: 9px;
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
cursor: pointer;
|
||||
color: var(--text-dim);
|
||||
transition: background-color 0.12s ease, color 0.12s ease, border-color 0.12s ease;
|
||||
}
|
||||
.gear:hover {
|
||||
background: var(--surface-2);
|
||||
color: var(--text);
|
||||
}
|
||||
.gear:hover,
|
||||
.gear.on {
|
||||
background: var(--accent-weak);
|
||||
border-color: var(--accent);
|
||||
color: var(--accent);
|
||||
}
|
||||
.divider {
|
||||
width: 1px;
|
||||
align-self: stretch;
|
||||
background: var(--border);
|
||||
margin: 2px 4px;
|
||||
|
||||
/* --- grouped icon-button clusters (segmented-control look) --- */
|
||||
.tgroup {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 2px;
|
||||
padding: 3px;
|
||||
background: var(--surface-2);
|
||||
border: 1px solid var(--border);
|
||||
border-radius: 10px;
|
||||
}
|
||||
.ibtn {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 30px;
|
||||
height: 28px;
|
||||
border: 0;
|
||||
border-radius: 7px;
|
||||
background: transparent;
|
||||
color: var(--text-dim);
|
||||
cursor: pointer;
|
||||
transition: background-color 0.12s ease, color 0.12s ease;
|
||||
}
|
||||
.tgroup.accent .ibtn {
|
||||
color: var(--accent);
|
||||
}
|
||||
.ibtn:hover {
|
||||
background: var(--surface);
|
||||
color: var(--text);
|
||||
box-shadow: var(--shadow-sm);
|
||||
}
|
||||
.tgroup.accent .ibtn:hover {
|
||||
color: var(--accent);
|
||||
}
|
||||
.ibtn:disabled {
|
||||
opacity: 0.35;
|
||||
cursor: default;
|
||||
pointer-events: none;
|
||||
}
|
||||
.ibtn.fx em {
|
||||
font-style: italic;
|
||||
font-weight: 700;
|
||||
font-size: 14px;
|
||||
font-family: Georgia, 'Times New Roman', serif;
|
||||
}
|
||||
.spacer {
|
||||
flex: 1;
|
||||
@@ -554,20 +606,6 @@ function onReset() {
|
||||
cursor: default;
|
||||
pointer-events: none;
|
||||
}
|
||||
.btn.accent {
|
||||
border-color: var(--accent);
|
||||
color: var(--accent);
|
||||
font-weight: 600;
|
||||
}
|
||||
.icon-btn {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 34px;
|
||||
padding: 6px 0;
|
||||
font-size: 14px;
|
||||
line-height: 1;
|
||||
}
|
||||
.menu-wrap {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,88 @@
|
||||
<script setup lang="ts">
|
||||
/**
|
||||
* Small hand-drawn line-icon set for the toolbar (no icon library/font —
|
||||
* consistent with this project's "nothing off the shelf" approach). One
|
||||
* shared <svg> shell (24x24, stroke-only) with a name-keyed set of shapes,
|
||||
* since every icon needs the exact same viewBox/stroke setup and only the
|
||||
* inner geometry differs.
|
||||
*/
|
||||
export type ToolbarIconName =
|
||||
| 'settings'
|
||||
| 'undo'
|
||||
| 'redo'
|
||||
| 'table'
|
||||
| 'chart'
|
||||
| 'text'
|
||||
| 'tag';
|
||||
|
||||
defineProps<{ name: ToolbarIconName }>();
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<svg
|
||||
class="ti"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
stroke-width="1.75"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
aria-hidden="true"
|
||||
>
|
||||
<template v-if="name === 'settings'">
|
||||
<line x1="3" y1="6" x2="21" y2="6" />
|
||||
<circle cx="9" cy="6" r="2" fill="currentColor" />
|
||||
<line x1="3" y1="12" x2="21" y2="12" />
|
||||
<circle cx="15" cy="12" r="2" fill="currentColor" />
|
||||
<line x1="3" y1="18" x2="21" y2="18" />
|
||||
<circle cx="7" cy="18" r="2" fill="currentColor" />
|
||||
</template>
|
||||
|
||||
<template v-else-if="name === 'undo'">
|
||||
<path d="M7 10 H15 a4 4 0 0 1 0 8 h-3" />
|
||||
<polyline points="7 10 11 6" />
|
||||
<polyline points="7 10 11 14" />
|
||||
</template>
|
||||
|
||||
<template v-else-if="name === 'redo'">
|
||||
<path d="M17 10 H9 a4 4 0 0 0 0 8 h3" />
|
||||
<polyline points="17 10 13 6" />
|
||||
<polyline points="17 10 13 14" />
|
||||
</template>
|
||||
|
||||
<template v-else-if="name === 'table'">
|
||||
<rect x="3" y="4" width="18" height="16" rx="2" />
|
||||
<line x1="3" y1="10" x2="21" y2="10" />
|
||||
<line x1="3" y1="16" x2="21" y2="16" />
|
||||
<line x1="9" y1="4" x2="9" y2="20" />
|
||||
<line x1="15" y1="4" x2="15" y2="20" />
|
||||
</template>
|
||||
|
||||
<template v-else-if="name === 'chart'">
|
||||
<line x1="4" y1="20" x2="20" y2="20" />
|
||||
<rect x="6" y="13" width="3" height="7" />
|
||||
<rect x="11" y="9" width="3" height="11" />
|
||||
<rect x="16" y="5" width="3" height="15" />
|
||||
</template>
|
||||
|
||||
<template v-else-if="name === 'text'">
|
||||
<rect x="4" y="4" width="16" height="16" rx="2" />
|
||||
<line x1="7" y1="9" x2="17" y2="9" />
|
||||
<line x1="7" y1="13" x2="17" y2="13" />
|
||||
<line x1="7" y1="17" x2="13" y2="17" />
|
||||
</template>
|
||||
|
||||
<template v-else-if="name === 'tag'">
|
||||
<polygon points="4,5 14,5 20,11 14,17 4,17" />
|
||||
<circle cx="9" cy="9" r="1.6" fill="currentColor" />
|
||||
</template>
|
||||
</svg>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.ti {
|
||||
width: 17px;
|
||||
height: 17px;
|
||||
display: block;
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user