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. * Root class for ToggleElevatedPill and ActionElevatedPill. * * @component ElevatedPill * @import dashgui/ElevatedPill * @defaultExport * * @prop {ReactNode} [label] - Text shown inside the pill. * @prop {boolean} [active=false] - When true, uses a stronger primary gradient background. * @prop {() => void} [onClick] - Called when the pill is clicked. * * @behaviour Rendered as a pill-shaped (borderRadius 999) inline-flex Box with a subtle primary-tinted gradient and shadow 1. * @behaviour `renderTrailing()` may be overridden by subclasses to append an element (switch / icon). * @behaviour Clicking toggles via onClick — the pill itself is not a form control. */ class ElevatedPill extends Component { renderTrailing() { return null; } render() { const { label, active = false, onClick } = 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()} ); } } /** * ElevatedPill with a trailing MUI Switch bound to `checked` / `onToggle` — * a labelled on/off toggle. * * @component ToggleElevatedPill * @import dashgui/ElevatedPill * * @prop {ReactNode} [label] - Text shown next to the switch. * @prop {boolean} checked - Controlled switch state. * @prop {(next: boolean) => void} onToggle - Called with the new checked value when the switch is toggled. * * @behaviour The switch is styled with a success color when on, grey when off. * @behaviour Controlled: the parent owns `checked` and updates it via `onToggle`. */ 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), }, })} /> ); } } /** * ElevatedPill whose trailing slot is a custom icon — used for clickable pill * buttons. * * @component ActionElevatedPill * @import dashgui/ElevatedPill * * @prop {ReactNode} [label] - Text shown next to the icon. * @prop {ReactNode} [icon] - Icon node rendered as the trailing element. * @prop {boolean} [active=false] - When true, uses the stronger primary gradient background. * @prop {() => void} [onClick] - Called when the pill is clicked. * * @behaviour Clicking the whole pill fires `onClick` — the icon is decorative, not a separate control. * @behaviour `active` gives a pressed/selected look via the stronger gradient. */ export class ActionElevatedPill extends ElevatedPill { renderTrailing() { return this.props.icon; } } export default ElevatedPill;