File size: 2,231 Bytes
cf86710 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 | import React, { createContext, use, useCallback, useState } from "react";
import { DayPicker, type DropdownProps } from "react-day-picker";
import {
Select,
SelectContent,
SelectGroup,
SelectItem,
SelectStyles,
SelectTrigger,
SelectValue,
} from "./Select";
const ContainerContext = createContext<HTMLDivElement | null>(null);
export function CustomSelectDropdown(props: DropdownProps) {
const { options, value, onChange, "aria-label": ariaLabel } = props;
const container = use(ContainerContext);
const handleValueChange = (newValue: string) => {
if (onChange) {
const syntheticEvent = {
target: {
value: newValue,
},
} as React.ChangeEvent<HTMLSelectElement>;
onChange(syntheticEvent);
}
};
return (
<Select value={value?.toString()} onValueChange={handleValueChange}>
<SelectTrigger aria-label={ariaLabel}>
<SelectValue />
</SelectTrigger>
<SelectContent container={container}>
<SelectGroup>
{options?.map((option) => (
<SelectItem
key={option.value}
value={option.value.toString()}
disabled={option.disabled}
>
{option.label}
</SelectItem>
))}
</SelectGroup>
</SelectContent>
</Select>
);
}
export function CustomDropdown() {
const [selected, setSelected] = useState<Date | undefined>();
// Use explicit container to make the example work in the docs with shadow DOM
const [container, setContainer] = useState<HTMLDivElement | null>(null);
const handleRef = useCallback((element: HTMLDivElement | null) => {
setContainer(element);
}, []);
return (
<div ref={handleRef}>
<SelectStyles />
<ContainerContext.Provider value={container}>
<DayPicker
captionLayout="dropdown"
components={{ Dropdown: CustomSelectDropdown }}
mode="single"
selected={selected}
onSelect={setSelected}
footer={
selected
? `Selected: ${selected.toLocaleDateString()}`
: "Pick a day."
}
/>
</ContainerContext.Provider>
</div>
);
}
|