src/components/toggle.tsx (75 lines of code) (raw):
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*
*/
import * as React from "react";
import { Check, ChevronDown, Globe, Wifi, WifiOff } from "lucide-react";
import { cn } from "@/lib/utils";
import { Button } from "@/components/ui/button";
import {
DropdownMenu,
DropdownMenuContent,
DropdownMenuItem,
DropdownMenuTrigger,
} from "@/components/ui/dropdown-menu";
export type ModeType = "offline" | "live" | "remote";
const states: {
value: ModeType;
label: string;
disabled: boolean;
icon: React.ComponentType<{ className?: string }>;
}[] = [
{
value: "offline",
label: "Offline",
icon: WifiOff,
disabled: false,
},
{
value: "live",
label: "Live",
icon: Wifi,
disabled: false,
},
{
value: "remote",
label: "Remote",
icon: Globe,
disabled: true,
},
];
export function ToggleState({ state, setState }) {
return (
<DropdownMenu>
<DropdownMenuTrigger asChild>
<Button variant="outline" className="w-[120px] justify-between">
<div className="flex items-center">
{React.createElement(
states.find((s) => s.value === state)
?.icon as React.ComponentType<{ className?: string }>,
{
className: "mr-2 h-4 w-4",
}
)}
{states.find((s) => s.value === state)?.label}
</div>
<ChevronDown className="ml-auto h-4 w-4 shrink-0 opacity-50" />
</Button>
</DropdownMenuTrigger>
<DropdownMenuContent className="w-[120px]">
{states.map((stateOption) => (
<DropdownMenuItem
disabled={stateOption.disabled}
key={stateOption.value}
onClick={() => setState(stateOption.value)}
>
<stateOption.icon className="mr-2 h-4 w-4" />
<span>{stateOption.label}</span>
<Check
className={cn(
"ml-auto h-4 w-4",
stateOption.value === state ? "opacity-100" : "opacity-0"
)}
/>
</DropdownMenuItem>
))}
</DropdownMenuContent>
</DropdownMenu>
);
}