Tools + Elements: horizontal tiles in grid + dropdown moved left

- Tile content back to horizontal (icon beside label, left-aligned) while
  keeping the aligned grid columns — per user choice 'Raster + horizontal'
- Wider 'both' column (86px) to fit icon+label in one row, single-row height
- Display-mode dropdown moved to the left (justify-content flex-start)
- icon-only and text-only modes stay centered; hasMenu chevron inline next
  to label (both/text) or as corner indicator (icon-only)
This commit is contained in:
2026-06-06 15:23:52 +02:00
parent c0624c0a62
commit cd87a0b7f4
2 changed files with 23 additions and 19 deletions
+12 -10
View File
@@ -29,8 +29,8 @@ function readTileMode() {
function writeTileMode(m) { function writeTileMode(m) {
try { localStorage.setItem(TILE_MODE_KEY, m) } catch { /* WebView ohne Storage */ } try { localStorage.setItem(TILE_MODE_KEY, m) } catch { /* WebView ohne Storage */ }
} }
const TILE_MIN_COL = { icon: 40, text: 66, both: 58 } const TILE_MIN_COL = { icon: 40, text: 64, both: 86 }
const TILE_MIN_H = { icon: 38, text: 30, both: 46 } const TILE_MIN_H = { icon: 32, text: 30, both: 32 }
function TileModeDropdown({ mode, onChange }) { function TileModeDropdown({ mode, onChange }) {
return ( return (
@@ -89,9 +89,11 @@ function PillButton({ icon, label, hint, onClick, onContextMenu, disabled,
disabled={disabled} disabled={disabled}
title={hint} title={hint}
style={{ style={{
display: 'flex', flexDirection: 'column', display: 'flex', flexDirection: 'row',
alignItems: 'center', justifyContent: 'center', gap: 4, alignItems: 'center',
padding: '6px 4px', justifyContent: mode === 'both' ? 'flex-start' : 'center',
gap: showIcon && showLabel ? 7 : 0,
padding: mode === 'icon' ? '6px' : '5px 11px',
minHeight: TILE_MIN_H[mode], minHeight: TILE_MIN_H[mode],
background: 'var(--bg-input)', background: 'var(--bg-input)',
border: '1px solid var(--border-light)', border: '1px solid var(--border-light)',
@@ -99,7 +101,7 @@ function PillButton({ icon, label, hint, onClick, onContextMenu, disabled,
cursor: disabled ? 'not-allowed' : 'pointer', cursor: disabled ? 'not-allowed' : 'pointer',
opacity: disabled ? 0.4 : 1, opacity: disabled ? 0.4 : 1,
transition: 'background 0.12s, border-color 0.12s', transition: 'background 0.12s, border-color 0.12s',
fontSize: 10, fontWeight: 500, fontSize: 11, fontWeight: 500,
color: 'var(--text-primary)', color: 'var(--text-primary)',
position: 'relative', position: 'relative',
width: '100%', width: '100%',
@@ -115,13 +117,13 @@ function PillButton({ icon, label, hint, onClick, onContextMenu, disabled,
}} }}
> >
{showIcon && ( {showIcon && (
<Icon name={icon} size={mode === 'icon' ? 18 : 16} <Icon name={icon} size={16}
style={{ color: 'var(--accent)', flexShrink: 0 }} /> style={{ color: 'var(--accent)', flexShrink: 0 }} />
)} )}
{showLabel && ( {showLabel && (
<span style={{ <span style={{
display: 'flex', alignItems: 'center', gap: 2, display: 'flex', alignItems: 'center', gap: 2,
maxWidth: '100%', overflow: 'hidden', overflow: 'hidden',
textOverflow: 'ellipsis', whiteSpace: 'nowrap', textOverflow: 'ellipsis', whiteSpace: 'nowrap',
}}> }}>
{label} {label}
@@ -134,7 +136,7 @@ function PillButton({ icon, label, hint, onClick, onContextMenu, disabled,
{/* Im Icon-Modus signalisiert ein kleines Eck-Chevron das Dropdown */} {/* Im Icon-Modus signalisiert ein kleines Eck-Chevron das Dropdown */}
{hasMenu && !showLabel && ( {hasMenu && !showLabel && (
<Icon name="expand_more" size={10} <Icon name="expand_more" size={10}
style={{ position: 'absolute', bottom: 2, right: 2, style={{ position: 'absolute', bottom: 1, right: 3,
color: 'var(--text-muted)' }} /> color: 'var(--text-muted)' }} />
)} )}
{badge && ( {badge && (
@@ -477,7 +479,7 @@ function NeuesElementSection({ noGeschoss, activeName, elementsCount, treppe2DSh
)} )}
</div> </div>
<div style={{ display: 'flex', justifyContent: 'flex-end' }}> <div style={{ display: 'flex', justifyContent: 'flex-start' }}>
<TileModeDropdown mode={tileMode} onChange={changeTileMode} /> <TileModeDropdown mode={tileMode} onChange={changeTileMode} />
</div> </div>
+11 -9
View File
@@ -12,8 +12,8 @@ function readTileMode() {
function writeTileMode(m) { function writeTileMode(m) {
try { localStorage.setItem(TILE_MODE_KEY, m) } catch { /* WebView ohne Storage */ } try { localStorage.setItem(TILE_MODE_KEY, m) } catch { /* WebView ohne Storage */ }
} }
const TILE_MIN_COL = { icon: 40, text: 66, both: 58 } const TILE_MIN_COL = { icon: 40, text: 64, both: 86 }
const TILE_MIN_H = { icon: 38, text: 30, both: 46 } const TILE_MIN_H = { icon: 32, text: 30, both: 32 }
// Tool-Definitionen: [icon, label, rhino-command, tooltip] // Tool-Definitionen: [icon, label, rhino-command, tooltip]
// Material-Symbol-Namen siehe https://fonts.google.com/icons // Material-Symbol-Namen siehe https://fonts.google.com/icons
@@ -81,27 +81,29 @@ function ToolTile({ icon, label, cmd, tip, mode }) {
e.currentTarget.style.background = 'var(--bg-input)' e.currentTarget.style.background = 'var(--bg-input)'
}} }}
style={{ style={{
display: 'flex', flexDirection: 'column', display: 'flex', flexDirection: 'row',
alignItems: 'center', justifyContent: 'center', gap: 4, alignItems: 'center',
padding: '6px 4px', justifyContent: mode === 'both' ? 'flex-start' : 'center',
gap: showIcon && showLabel ? 7 : 0,
padding: mode === 'icon' ? '6px' : '5px 11px',
minHeight: TILE_MIN_H[mode], minHeight: TILE_MIN_H[mode],
background: 'var(--bg-input)', background: 'var(--bg-input)',
border: '1px solid var(--border-light)', border: '1px solid var(--border-light)',
borderRadius: 999, borderRadius: 999,
cursor: 'pointer', cursor: 'pointer',
transition: 'background 0.12s, border-color 0.12s', transition: 'background 0.12s, border-color 0.12s',
fontSize: 10, fontWeight: 500, fontSize: 11, fontWeight: 500,
color: 'var(--text-primary)', color: 'var(--text-primary)',
appearance: 'none', WebkitAppearance: 'none', appearance: 'none', WebkitAppearance: 'none',
}} }}
> >
{showIcon && ( {showIcon && (
<Icon name={icon} size={mode === 'icon' ? 18 : 16} <Icon name={icon} size={16}
style={{ color: 'var(--accent)', flexShrink: 0 }} /> style={{ color: 'var(--accent)', flexShrink: 0 }} />
)} )}
{showLabel && ( {showLabel && (
<span style={{ <span style={{
maxWidth: '100%', overflow: 'hidden', overflow: 'hidden',
textOverflow: 'ellipsis', whiteSpace: 'nowrap', textOverflow: 'ellipsis', whiteSpace: 'nowrap',
}}>{label}</span> }}>{label}</span>
)} )}
@@ -164,7 +166,7 @@ export default function WerkzeugeApp() {
boxSizing: 'border-box', boxSizing: 'border-box',
overflowY: 'auto', overflowX: 'hidden', overflowY: 'auto', overflowX: 'hidden',
}}> }}>
<div style={{ display: 'flex', justifyContent: 'flex-end' }}> <div style={{ display: 'flex', justifyContent: 'flex-start' }}>
<TileModeDropdown mode={mode} onChange={changeMode} /> <TileModeDropdown mode={mode} onChange={changeMode} />
</div> </div>
{groups.map(([title, items]) => ( {groups.map(([title, items]) => (