2026-01-30 18:28:30 +00:00
|
|
|
import Typography from "@mui/material/Typography";
|
2026-01-29 23:52:21 +00:00
|
|
|
import { forwardRef } from "react";
|
|
|
|
|
import Slider from "@mui/material/Slider";
|
|
|
|
|
import type { SliderProps } from "@mui/material/Slider";
|
|
|
|
|
import { useTheme } from "@mui/material/styles";
|
2026-01-30 00:00:12 +00:00
|
|
|
import Stack from "@mui/material/Stack";
|
|
|
|
|
import { FieldLabel } from "./FieldLabel";
|
2026-01-30 18:28:30 +00:00
|
|
|
import Box from "@mui/material/Box";
|
|
|
|
|
import type { ResponsiveStyleValue } from "@mui/system";
|
2026-01-29 23:52:21 +00:00
|
|
|
|
2026-01-30 18:28:30 +00:00
|
|
|
interface SliderInputProps extends SliderProps {
|
|
|
|
|
sx?: SliderProps["sx"];
|
|
|
|
|
showValue?: boolean;
|
2026-03-09 11:32:01 -07:00
|
|
|
formatDisplayValue?: (value: number) => string;
|
2026-01-30 18:28:30 +00:00
|
|
|
}
|
2026-01-29 23:52:21 +00:00
|
|
|
|
2026-01-30 18:28:30 +00:00
|
|
|
export const SliderInput = forwardRef<HTMLSpanElement, SliderInputProps>(
|
2026-03-09 11:32:01 -07:00
|
|
|
({ sx, showValue = false, formatDisplayValue, ...props }, ref) => {
|
2026-01-30 18:28:30 +00:00
|
|
|
const theme = useTheme();
|
|
|
|
|
const additionalSx = Array.isArray(sx) ? sx : sx ? [sx] : [];
|
|
|
|
|
|
2026-03-09 11:32:01 -07:00
|
|
|
const displayValue =
|
|
|
|
|
showValue && formatDisplayValue && typeof props.value === "number"
|
|
|
|
|
? formatDisplayValue(props.value)
|
|
|
|
|
: props.value;
|
|
|
|
|
|
2026-01-30 18:28:30 +00:00
|
|
|
return (
|
|
|
|
|
<Stack
|
|
|
|
|
gap={theme.spacing(8)}
|
|
|
|
|
direction={"row"}
|
|
|
|
|
alignItems={"center"}
|
|
|
|
|
>
|
2026-03-09 11:32:01 -07:00
|
|
|
{showValue && <Typography>{displayValue}</Typography>}
|
2026-01-30 18:28:30 +00:00
|
|
|
<Slider
|
|
|
|
|
{...props}
|
|
|
|
|
ref={ref}
|
|
|
|
|
sx={[
|
|
|
|
|
{
|
|
|
|
|
"& .MuiSlider-track": {
|
|
|
|
|
backgroundColor: theme.palette.primary.main,
|
|
|
|
|
border: "none",
|
|
|
|
|
},
|
|
|
|
|
"& .MuiSlider-rail": {
|
|
|
|
|
backgroundColor: theme.palette.grey[300],
|
|
|
|
|
opacity: 1,
|
|
|
|
|
},
|
|
|
|
|
"& .MuiSlider-thumb": {
|
|
|
|
|
backgroundColor: "#fff",
|
|
|
|
|
"&:hover, &.Mui-focusVisible": {
|
2026-02-14 01:15:12 +00:00
|
|
|
boxShadow: "none",
|
|
|
|
|
},
|
|
|
|
|
"&:active": {
|
|
|
|
|
boxShadow: "none",
|
2026-01-30 18:28:30 +00:00
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
"& .MuiSlider-valueLabel": {
|
|
|
|
|
backgroundColor: theme.palette.primary.main,
|
|
|
|
|
},
|
2026-01-29 23:52:21 +00:00
|
|
|
},
|
2026-01-30 18:28:30 +00:00
|
|
|
...additionalSx,
|
|
|
|
|
]}
|
|
|
|
|
/>
|
|
|
|
|
</Stack>
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
);
|
2026-01-30 00:00:12 +00:00
|
|
|
|
|
|
|
|
interface SliderWithLabelProps extends SliderProps {
|
|
|
|
|
fieldLabel?: string;
|
|
|
|
|
required?: boolean;
|
|
|
|
|
showValue?: boolean;
|
2026-03-09 11:32:01 -07:00
|
|
|
formatDisplayValue?: (value: number) => string;
|
2026-01-30 18:28:30 +00:00
|
|
|
sliderMaxWidth?: ResponsiveStyleValue<number | string>;
|
2026-01-30 00:00:12 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export const SliderWithLabel = forwardRef<HTMLSpanElement, SliderWithLabelProps>(
|
2026-01-30 18:28:30 +00:00
|
|
|
(
|
2026-03-09 11:32:01 -07:00
|
|
|
{
|
|
|
|
|
fieldLabel,
|
|
|
|
|
required,
|
|
|
|
|
showValue = true,
|
|
|
|
|
formatDisplayValue,
|
|
|
|
|
value,
|
|
|
|
|
sliderMaxWidth = "100%",
|
|
|
|
|
...props
|
|
|
|
|
},
|
2026-01-30 00:00:12 +00:00
|
|
|
ref
|
2026-01-30 18:28:30 +00:00
|
|
|
) => {
|
2026-01-30 00:00:12 +00:00
|
|
|
const theme = useTheme();
|
|
|
|
|
|
2026-01-30 18:28:30 +00:00
|
|
|
const labelText = fieldLabel;
|
2026-01-30 00:00:12 +00:00
|
|
|
|
|
|
|
|
return (
|
|
|
|
|
<Stack spacing={theme.spacing(2)}>
|
|
|
|
|
{fieldLabel && <FieldLabel required={required}>{labelText}</FieldLabel>}
|
2026-01-30 18:28:30 +00:00
|
|
|
<Box maxWidth={sliderMaxWidth}>
|
|
|
|
|
<SliderInput
|
|
|
|
|
{...props}
|
|
|
|
|
showValue={showValue}
|
2026-03-09 11:32:01 -07:00
|
|
|
formatDisplayValue={formatDisplayValue}
|
2026-01-30 18:28:30 +00:00
|
|
|
value={value}
|
|
|
|
|
ref={ref}
|
|
|
|
|
/>
|
|
|
|
|
</Box>
|
2026-01-30 00:00:12 +00:00
|
|
|
</Stack>
|
2026-01-29 23:52:21 +00:00
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
);
|