Skip to content

Commit

Permalink
feat: add Menu options
Browse files Browse the repository at this point in the history
  • Loading branch information
zettca committed Aug 13, 2024
1 parent b23f4fa commit 7a0e65c
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 38 deletions.
29 changes: 24 additions & 5 deletions src/components/SliderPicker.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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<SliderProps, "onChange" | "onChangeCommitted"> {
Expand Down Expand Up @@ -38,15 +39,25 @@ const SliderPicker: React.FC<SliderPickerProps> = ({
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<Mark>((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 (
<section aria-labelledby={id}>
<div className="flex items-center">
<div className="flex items-center gap-1">
<FormControlLabel
className="mr-0"
control={
<Radio size="small" checked={selected} onClick={onLockClick} />
}
Expand All @@ -61,6 +72,14 @@ const SliderPicker: React.FC<SliderPickerProps> = ({
</Typography>
}
/>
{!selected && (
<SplitButton
options={marks}
onChange={(val) => {
handleChange?.(val);
}}
/>
)}
</div>
<Fade in={!selected} timeout={800}>
<Slider
Expand All @@ -69,7 +88,7 @@ const SliderPicker: React.FC<SliderPickerProps> = ({
{...sliderProps}
aria-labelledby={id}
size="small"
marks={marks}
marks={visibleMarks}
onChange={(evt, val) => {
sliderProps.onChange(val as number);
onChange?.(val as number);
Expand Down
53 changes: 20 additions & 33 deletions src/components/SplitButton.tsx
Original file line number Diff line number Diff line change
@@ -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<HTMLLIElement> | 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<HTMLButtonElement>(null);

useEffect(() => {
setSelectedIndex(index);
}, [index]);

useEffect(() => {
setOpen(false);
onChange?.(null, options[selectedIndex]!);
}, [selectedIndex, options, onChange]);

return (
<>
<Button
<IconButton
ref={ref}
color="primary"
size="small"
onClick={() => setOpen((prevOpen) => !prevOpen)}
endIcon={<ArrowDropDown />}
>
{options[selectedIndex]}
</Button>
<ArrowDropDown />
</IconButton>
<Menu anchorEl={ref.current} open={open} onClose={() => setOpen(false)}>
{options.map((option, idx) => (
{options.map(({ value, label }) => (
<MenuItem
key={option}
selected={idx === selectedIndex}
onClick={() => setSelectedIndex(idx)}
key={label}
value={value}
onClick={() => {
setOpen(false);
onChange(value);
}}
>
{option}
{label}
</MenuItem>
))}
</Menu>
Expand Down

0 comments on commit 7a0e65c

Please sign in to comment.