Refactor section title toggles into reusable ElevatedPill components
This commit is contained in:
80
src/components/ElevatedPill.jsx
Normal file
80
src/components/ElevatedPill.jsx
Normal file
@@ -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 (
|
||||||
|
<Box
|
||||||
|
component="label"
|
||||||
|
sx={(theme) => ({
|
||||||
|
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',
|
||||||
|
})}
|
||||||
|
>
|
||||||
|
<Typography variant="body2" sx={{ lineHeight: 1 }}>
|
||||||
|
{label}
|
||||||
|
</Typography>
|
||||||
|
{this.renderTrailing()}
|
||||||
|
</Box>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export class ToggleElevatedPill extends ElevatedPill {
|
||||||
|
renderTrailing() {
|
||||||
|
const { checked, onToggle } = this.props;
|
||||||
|
return (
|
||||||
|
<Switch
|
||||||
|
size="small"
|
||||||
|
checked={checked}
|
||||||
|
onChange={(event) => 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;
|
||||||
@@ -1,11 +1,12 @@
|
|||||||
import { Outlet, useLocation } from 'react-router-dom';
|
import { Outlet, useLocation } from 'react-router-dom';
|
||||||
import { useDispatch, useSelector } from 'react-redux';
|
import { useDispatch, useSelector } from 'react-redux';
|
||||||
import FormControlLabel from '@mui/material/FormControlLabel';
|
import Box from '@mui/material/Box';
|
||||||
import Switch from '@mui/material/Switch';
|
import SettingsIcon from '@mui/icons-material/Settings';
|
||||||
import PageLayout from './PageLayout';
|
import PageLayout from './PageLayout';
|
||||||
import { NAV_ITEMS, SUB_NAV } from '../nav';
|
import { NAV_ITEMS, SUB_NAV } from '../nav';
|
||||||
import { isKategorienPath } from '../pages/artikel/categoryRoute';
|
import { isKategorienPath } from '../pages/artikel/categoryRoute';
|
||||||
import { selectRenameMode, setRenameMode } from '../store/categorySlice';
|
import { selectRenameMode, setRenameMode } from '../store/categorySlice';
|
||||||
|
import { ActionElevatedPill, ToggleElevatedPill } from './ElevatedPill';
|
||||||
|
|
||||||
export default function SectionLayout({ sectionPath }) {
|
export default function SectionLayout({ sectionPath }) {
|
||||||
const { pathname } = useLocation();
|
const { pathname } = useLocation();
|
||||||
@@ -36,18 +37,14 @@ export default function SectionLayout({ sectionPath }) {
|
|||||||
const showsRenameSwitch = activeSub?.segment === 'kategorien';
|
const showsRenameSwitch = activeSub?.segment === 'kategorien';
|
||||||
|
|
||||||
const titleAction = showsRenameSwitch ? (
|
const titleAction = showsRenameSwitch ? (
|
||||||
<FormControlLabel
|
<Box sx={{ display: 'inline-flex', gap: 1 }}>
|
||||||
control={
|
<ToggleElevatedPill
|
||||||
<Switch
|
label="Editieren"
|
||||||
size="small"
|
checked={renameMode}
|
||||||
checked={renameMode}
|
onToggle={(checked) => dispatch(setRenameMode(checked))}
|
||||||
onChange={(event) => dispatch(setRenameMode(event.target.checked))}
|
/>
|
||||||
/>
|
<ActionElevatedPill label="Extras" icon={<SettingsIcon sx={{ fontSize: 18 }} />} />
|
||||||
}
|
</Box>
|
||||||
label="Editieren"
|
|
||||||
labelPlacement="end"
|
|
||||||
sx={{ ml: 0 }}
|
|
||||||
/>
|
|
||||||
) : null;
|
) : null;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|||||||
Reference in New Issue
Block a user