Commit 127f1e19 by asranov0003

feat: add cdeviceselect

parent fc09caf6
.cdeviceselect-container {
width: 100%;
border-radius: 10px;
padding: 0.75rem 1rem;
background: var(--background-color);
color: var(--text-color);
border: 1px solid var(--gray-color);
cursor: pointer;
user-select: none;
position: relative;
transition: 0.3s;
}
.cdeviceselect-disabled {
background: var(--light-gray-color);
cursor: not-allowed;
opacity: 0.6;
}
.cdeviceselect-selected {
display: flex;
align-items: center;
justify-content: space-between;
}
.cdeviceselect-img {
width: 20px;
height: 20px;
margin-right: 8px;
border-radius: 50%;
object-fit: cover;
}
.cdeviceselect-dropdown {
position: absolute;
top: 100%;
left: 0;
right: 0;
background: var(--background-color);
border-radius: 10px;
margin-top: 4px;
z-index: 100;
box-shadow: 0 2px 6px rgba(0, 0, 0, 0.1);
max-height: 200px;
overflow-y: auto;
}
.cdeviceselect-option {
padding: 0.75rem 1rem;
display: flex;
align-items: center;
cursor: pointer;
transition: 0.2s;
}
.cdeviceselect-option:hover {
background: rgba(0, 0, 0, 0.05);
}
.cdeviceselect-option.selected {
background: var(--primary-color);
color: var(--on-text-color);
}
.cdeviceselect-arrow {
margin-left: auto;
font-size: 0.8rem;
}
.cdeviceselect-img {
width: 20px;
height: 20px;
margin-right: 8px;
display: flex;
align-items: center;
justify-content: center;
}
.cdeviceselect-option.disabled {
color: #888;
pointer-events: none;
cursor: default;
}
\ No newline at end of file
import React, { useEffect, useRef, useState } from "react";
import "./CDeviceSelect.css";
import type { CDeviceSelectProps } from "./CDeviceSelect.types";
import { FaChevronDown, FaChevronUp } from "react-icons/fa";
const CDeviceSelect: React.FC<CDeviceSelectProps> = ({
devices,
selectedDevice,
onDeviceChange,
disabled,
style,
className,
placeholder = "Select Device",
}) => {
const [open, setOpen] = useState(false);
const ref = useRef<HTMLDivElement>(null);
useEffect(() => {
const handleClickOutside = (e: MouseEvent) => {
if (ref.current && !ref.current.contains(e.target as Node)) {
setOpen(false);
}
};
document.addEventListener("mousedown", handleClickOutside);
return () => document.removeEventListener("mousedown", handleClickOutside);
}, []);
return (
<>
<div
ref={ref}
className={`cdeviceselect-container ${className || ""} ${
disabled ? "cdeviceselect-disabled" : ""
}`}
style={style}
onClick={() => !disabled && setOpen(!open)}
>
<div className="cdeviceselect-selected">
<span>{selectedDevice?.name || placeholder}</span>
<span className="cdeviceselect-arrow">
{open ? <FaChevronUp /> : <FaChevronDown />}
</span>
</div>
{open && (
<div className="cdeviceselect-dropdown">
{devices.map((device) => (
<div
key={device.id}
className={`cdeviceselect-option ${
device.name === selectedDevice?.name ? "selected" : ""
}`}
onClick={(e) => {
e.stopPropagation();
onDeviceChange?.(device.id);
setOpen(false);
}}
>
<span>{device.name}</span>
</div>
))}
</div>
)}
</div>
</>
);
};
export default CDeviceSelect;
import type { IDevice } from "../../types/device.types";
export interface CDeviceSelectProps {
devices: IDevice[];
selectedDevice: IDevice | null;
onDeviceChange: (deviceId: string) => void;
disabled?: boolean;
style?: React.CSSProperties;
className?: string;
placeholder?: string;
}
export { default } from "./CDeviceSelect";
......@@ -23,6 +23,7 @@ import {
fetchDevices,
setSelectedDevice,
} from "../../stores/slices/deviceSlice";
import CDeviceSelect from "../../components/CDeviceSelect";
const Header: React.FC = () => {
const [isSidebarOpen, setIsSidebarOpen] = useState(false);
......@@ -73,16 +74,14 @@ const Header: React.FC = () => {
</div>
<div className="header__devices">
<select
onChange={(e) => dispatch(setSelectedDevice(e.target.value))}
defaultValue={selectedDevice?.id}
>
{devices.map((device) => (
<option key={device.id} value={device.id}>
{device.name}
</option>
))}
</select>
<CDeviceSelect
devices={devices}
selectedDevice={selectedDevice}
onDeviceChange={(name) => dispatch(setSelectedDevice(name))}
disabled={!devices.length}
style={{ width: "220px" }}
className="header__device-select"
/>
</div>
</div>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment