From 7a0e65ca8904d2efd3c754827a7ede45fbcd1d16 Mon Sep 17 00:00:00 2001 From: Bruno Date: Tue, 13 Aug 2024 03:51:58 +0100 Subject: [PATCH] feat: add Menu options --- src/components/SliderPicker.tsx | 29 ++++++++++++++---- src/components/SplitButton.tsx | 53 +++++++++++++-------------------- 2 files changed, 44 insertions(+), 38 deletions(-) diff --git a/src/components/SliderPicker.tsx b/src/components/SliderPicker.tsx index 92e3cce..6341968 100644 --- a/src/components/SliderPicker.tsx +++ b/src/components/SliderPicker.tsx @@ -10,7 +10,8 @@ import { type SliderProps, } from "@mui/material"; import { useSliderExpand } from "~/hooks/useSliderExpand"; -import type { SliderConfig } from "~/types"; +import type { Mark, SliderConfig } from "~/types"; +import { SplitButton } from "./SplitButton"; export interface SliderPickerProps extends Omit { @@ -38,15 +39,25 @@ const SliderPicker: React.FC = ({ const id = useId(); const sliderProps = useSliderExpand({ min, max, value }); - const marks = buttons - .map((btn) => ({ value: btn.value, label: t(btn.label as any) })) + const marks = buttons.map((btn) => ({ + value: btn.value, + label: t(btn.label as any), + })); + + const visibleMarks = marks .filter((btn) => btn.value < sliderProps.max) .concat({ value: sliderProps.max, label: "+" }); + const handleChange = (val: number) => { + sliderProps.onChange(val); + onChange?.(val); + }; + return (
-
+
} @@ -61,6 +72,14 @@ const SliderPicker: React.FC = ({ } /> + {!selected && ( + { + handleChange?.(val); + }} + /> + )}
= ({ {...sliderProps} aria-labelledby={id} size="small" - marks={marks} + marks={visibleMarks} onChange={(evt, val) => { sliderProps.onChange(val as number); onChange?.(val as number); diff --git a/src/components/SplitButton.tsx b/src/components/SplitButton.tsx index 21fedf5..dd105e9 100644 --- a/src/components/SplitButton.tsx +++ b/src/components/SplitButton.tsx @@ -1,51 +1,38 @@ -import { useEffect, useRef, useState } from "react"; -import { ArrowDropDown } from "@mui/icons-material"; -import { Button, Menu, MenuItem } from "@mui/material"; +import { useRef, useState } from "react"; +import ArrowDropDown from "@mui/icons-material/ArrowDropDown"; +import { IconButton, Menu, MenuItem } from "@mui/material"; +import type { Mark } from "~/types"; export interface SplitButtonProps { - index?: number; - options?: string[]; - onChange?: ( - event: React.MouseEvent | null, - value: string, - ) => void; + options: Mark[]; + onChange: (value: number) => void; } -export const SplitButton = ({ - index = 0, - options = [], - onChange, -}: SplitButtonProps) => { +export const SplitButton = ({ options = [], onChange }: SplitButtonProps) => { const [open, setOpen] = useState(false); - const [selectedIndex, setSelectedIndex] = useState(index); const ref = useRef(null); - useEffect(() => { - setSelectedIndex(index); - }, [index]); - - useEffect(() => { - setOpen(false); - onChange?.(null, options[selectedIndex]!); - }, [selectedIndex, options, onChange]); - return ( <> - + + setOpen(false)}> - {options.map((option, idx) => ( + {options.map(({ value, label }) => ( setSelectedIndex(idx)} + key={label} + value={value} + onClick={() => { + setOpen(false); + onChange(value); + }} > - {option} + {label} ))}