import type { FilterRangeTypeInput } from '@graphcommerce/graphql-mesh' import { Money } from '@graphcommerce/magento-store' import { extendableComponent, filterNonNullableKeys, sxx } from '@graphcommerce/next-ui' import type { SxProps, Theme } from '@mui/material' import { Box, Slider, useEventCallback } from '@mui/material' import { useCallback } from 'react' import type { FilterProps } from './ProductFiltersProAggregations' export type PriceSliderProps = { value: FilterRangeTypeInput | null | undefined // eslint-disable-next-line @typescript-eslint/no-explicit-any onChange: (...event: any[]) => void sx?: SxProps options: FilterProps['aggregation']['options'] } const { classes } = extendableComponent('PriceSlider', ['container', 'slider'] as const) export function getMinMaxFromOptions(options: PriceSliderProps['options']) { const totalRange: [number, number][] = filterNonNullableKeys(options, ['label']).map( (v) => v.value.split('_').map((mv) => Number(mv)) as [number, number], ) const min = totalRange[0][0] const max = totalRange[totalRange.length - 1][1] return [Math.floor(min), Math.ceil(max)] as [number, number] } export function PriceSlider(props: PriceSliderProps) { const { options, value, onChange, sx = [] } = props const [min, max] = getMinMaxFromOptions(options) const from = value?.from ? Number(value?.from) : min const to = value?.to ? Number(value?.to) : max const renderMoney = useCallback((v: number) => , []) return ( ({ pt: theme.spacings.md, pb: theme.spacings.xs, px: theme.spacings.xxs, }), sx, )} className={classes.container} > { if (!Array.isArray(sliderValues)) throw Error('not a range') const [newFrom, newTo] = sliderValues // When the range is the same as the default, set the value to null let newVal: Required | null = null if (newFrom !== min || newTo !== max) { newVal = { from: String(newFrom), to: String(newTo) } } // Both values are null, no need to update if (!value && !newVal) return // All values are the same, no need to update if (value && newVal && value.from === newVal.from && value.to === newVal.to) return // The value has changed, rerender onChange(newVal) })} valueLabelDisplay='on' valueLabelFormat={renderMoney} className={classes.slider} step={1} /> ) }