From aa543f8631273206b3e6e83477ddb5feda3fa7a0 Mon Sep 17 00:00:00 2001 From: seb Date: Tue, 4 Aug 2026 00:01:51 +0200 Subject: [PATCH] Refactor section title toggles into reusable ElevatedPill components --- src/components/ElevatedPill.jsx | 80 ++++++++++++++++++++++++++++++++ src/components/SectionLayout.jsx | 25 +++++----- 2 files changed, 91 insertions(+), 14 deletions(-) create mode 100644 src/components/ElevatedPill.jsx diff --git a/src/components/ElevatedPill.jsx b/src/components/ElevatedPill.jsx new file mode 100644 index 0000000..1dbd6ee --- /dev/null +++ b/src/components/ElevatedPill.jsx @@ -0,0 +1,80 @@ +import { Component } from 'react'; +import Box from '@mui/material/Box'; +import Switch from '@mui/material/Switch'; +import Typography from '@mui/material/Typography'; +import { alpha } from '@mui/material/styles'; + +/** Base pill with elevation, shared styling, and an overridable trailing element. */ +class ElevatedPill extends Component { + renderTrailing() { + return null; + } + + render() { + const { label, active = false } = this.props; + return ( + ({ + display: 'inline-flex', + alignItems: 'center', + gap: 0.5, + px: 1.5, + py: 0.25, + borderRadius: 999, + background: active + ? `linear-gradient(180deg, ${alpha(theme.palette.primary.main, 0.28)}, ${alpha( + theme.palette.primary.main, + 0.22, + )})` + : `linear-gradient(180deg, ${alpha(theme.palette.primary.main, 0.16)}, ${alpha( + theme.palette.primary.main, + 0.10, + )})`, + color: 'text.primary', + cursor: 'pointer', + userSelect: 'none', + boxShadow: theme.shadows[1], + transition: 'background 150ms ease, box-shadow 150ms ease', + })} + > + + {label} + + {this.renderTrailing()} + + ); + } +} + +export class ToggleElevatedPill extends ElevatedPill { + renderTrailing() { + const { checked, onToggle } = this.props; + return ( + onToggle(event.target.checked)} + sx={(theme) => ({ + '& .MuiSwitch-switchBase': { + color: checked ? 'success.main' : 'grey.300', + }, + '& .Mui-checked': { + color: 'success.main', + }, + '& .Mui-checked + .MuiSwitch-track': { + backgroundColor: alpha(theme.palette.success.main, 0.35), + }, + })} + /> + ); + } +} + +export class ActionElevatedPill extends ElevatedPill { + renderTrailing() { + return this.props.icon; + } +} + +export default ElevatedPill; diff --git a/src/components/SectionLayout.jsx b/src/components/SectionLayout.jsx index e538c96..7c51e0b 100644 --- a/src/components/SectionLayout.jsx +++ b/src/components/SectionLayout.jsx @@ -1,11 +1,12 @@ import { Outlet, useLocation } from 'react-router-dom'; import { useDispatch, useSelector } from 'react-redux'; -import FormControlLabel from '@mui/material/FormControlLabel'; -import Switch from '@mui/material/Switch'; +import Box from '@mui/material/Box'; +import SettingsIcon from '@mui/icons-material/Settings'; import PageLayout from './PageLayout'; import { NAV_ITEMS, SUB_NAV } from '../nav'; import { isKategorienPath } from '../pages/artikel/categoryRoute'; import { selectRenameMode, setRenameMode } from '../store/categorySlice'; +import { ActionElevatedPill, ToggleElevatedPill } from './ElevatedPill'; export default function SectionLayout({ sectionPath }) { const { pathname } = useLocation(); @@ -36,18 +37,14 @@ export default function SectionLayout({ sectionPath }) { const showsRenameSwitch = activeSub?.segment === 'kategorien'; const titleAction = showsRenameSwitch ? ( - dispatch(setRenameMode(event.target.checked))} - /> - } - label="Editieren" - labelPlacement="end" - sx={{ ml: 0 }} - /> + + dispatch(setRenameMode(checked))} + /> + } /> + ) : null; return (