Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
67 changes: 67 additions & 0 deletions apps/desktop/src/components/ui/simple-select.tsx

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can we swap this to the shadcn select?

https://ui.shadcn.com/docs/components/radix/select

Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
import { useState, useRef, useEffect } from "react";
import { ChevronDown } from "lucide-react";

interface Option {
value: string;
label: string;
}

interface SimpleSelectProps {
id?: string;
value: string;
options: Option[];
onChange: (value: string) => void;
className?: string;
}

export function SimpleSelect({ value, options, onChange, className = "", id }: SimpleSelectProps) {
const [isOpen, setIsOpen] = useState(false);
const containerRef = useRef<HTMLDivElement>(null);

useEffect(() => {
function handleClickOutside(event: MouseEvent) {
if (containerRef.current && !containerRef.current.contains(event.target as Node)) {
setIsOpen(false);
}
}
document.addEventListener("mousedown", handleClickOutside);
return () => document.removeEventListener("mousedown", handleClickOutside);
}, []);

const selectedOption = options.find(opt => opt.value === value) || options[0];

return (
<div className={`relative ${className}`} ref={containerRef}>
<button
id={id}
type="button"
className="w-full h-full p-1 pl-2 pr-1 rounded border bg-zinc-800 text-white outline-none focus:ring-0 cursor-pointer flex items-center justify-between gap-2"
onClick={() => setIsOpen(!isOpen)}
>
<span className="truncate whitespace-nowrap text-sm">{selectedOption?.label}</span>
<ChevronDown className="h-4 w-4 opacity-50 flex-shrink-0" />
</button>

{isOpen && (
<div className="absolute z-50 w-full min-w-max right-0 mt-1 rounded-md border bg-zinc-800 text-white shadow-md outline-none">
<ul className="py-1 max-h-60 overflow-auto">
{options.map(option => (
<li
key={option.value}
className={`relative flex w-full cursor-pointer select-none items-center rounded-sm py-1.5 pl-2 pr-8 text-sm outline-none hover:bg-zinc-700 focus:bg-zinc-700 ${
option.value === value ? "bg-zinc-700" : ""
}`}
onClick={() => {
onChange(option.value);
setIsOpen(false);
}}
>
{option.label}
</li>
))}
</ul>
</div>
)}
</div>
);
}
2 changes: 1 addition & 1 deletion apps/desktop/src/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ export const DEFAULT_OVERLAYED_CONFIG: OverlayedConfig = {
pin: false,
horizontal: "right",
// TODO: vertical alignment? i.e., if aligned to bottom, then the navbar should be at the bottom (and corner radius changes appropriately)
vertical: "bottom",
vertical: "top",
telemetry: true,
joinHistoryNotifications: false,
showOnlyTalkingUsers: false,
Expand Down
68 changes: 29 additions & 39 deletions apps/desktop/src/views/settings/configuration.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import Config from "@/config";
import { useConfigValue } from "@/hooks/use-config-value";
import { emit } from "@tauri-apps/api/event";
import { invoke } from "@tauri-apps/api/core";
import { SimpleSelect } from "@/components/ui/simple-select";

export const Configuration = () => {
const { value: showOnlyTalkingUsers } = useConfigValue("showOnlyTalkingUsers");
Expand Down Expand Up @@ -68,27 +69,22 @@ export const Configuration = () => {
>
Anchor horizontal
</label>
<select
<SimpleSelect
id="horizontal"
value={horizontal}
onChange={async event => {
const newTarget = event.target.value as "left" | "center" | "right";
onChange={async val => {
const newTarget = val as "left" | "center" | "right";
await Config.set("horizontal", newTarget);

await emit("config_update", await Config.getConfig());
}}
className="w-40 p-1 rounded border bg-zinc-800 text-white outline-none focus:ring-0 cursor-pointer"
>
<option value="left" className="bg-zinc-800 text-white">
Left
</option>
<option value="center" className="bg-zinc-800 text-white">
Center
</option>
<option value="right" className="bg-zinc-800 text-white">
Right
</option>
</select>
options={[
{ value: "left", label: "Left" },
{ value: "center", label: "Center" },
{ value: "right", label: "Right" },
]}
className="w-40"
/>
</div>
<div className="flex items-center justify-between h-8 mx-2">
<label
Expand All @@ -97,24 +93,21 @@ export const Configuration = () => {
>
Anchor vertical
</label>
<select
<SimpleSelect
id="vertical"
value={vertical}
onChange={async event => {
const newTarget = event.target.value as "top" | "bottom";
onChange={async val => {
const newTarget = val as "top" | "bottom";
await Config.set("vertical", newTarget);

await emit("config_update", await Config.getConfig());
}}
className="w-40 p-1 rounded border bg-zinc-800 text-white outline-none focus:ring-0 cursor-pointer"
>
<option value="top" className="bg-zinc-800 text-white">
Top
</option>
<option value="bottom" className="bg-zinc-800 text-white">
Bottom
</option>
</select>
options={[
{ value: "top", label: "Top" },
{ value: "bottom", label: "Bottom" },
]}
className="w-40"
/>
</div>
<div className="flex items-center justify-between h-8 mx-2">
<label
Expand All @@ -123,24 +116,21 @@ export const Configuration = () => {
>
Opacity target
</label>
<select
<SimpleSelect
id="opacityTarget"
value={opacityTarget}
onChange={async event => {
const newTarget = event.target.value as "all" | "username-box";
onChange={async val => {
const newTarget = val as "all" | "username-box";
await Config.set("opacityTarget", newTarget);

await emit("config_update", await Config.getConfig());
}}
className="p-1 rounded border bg-zinc-800 text-white outline-none focus:ring-0 cursor-pointer"
>
<option value="all" className="bg-zinc-800 text-white">
Everything
</option>
<option value="username-box" className="bg-zinc-800 text-white">
Username background only
</option>
</select>
options={[
{ value: "all", label: "Everything" },
{ value: "username-box", label: "Username background only" },
]}
className="w-56"
/>
</div>
<div className="flex items-center justify-between h-8 mx-2">
<label
Expand Down
Loading