diff --git a/src/App.css b/src/App.css index a026572..c0a659d 100644 --- a/src/App.css +++ b/src/App.css @@ -12,7 +12,7 @@ :root { /* Typography */ - font-size: 16px; + font-size: 15px; line-height: 24px; font-weight: 400; diff --git a/src/components/settings/CorrectWords.tsx b/src/components/settings/CorrectWords.tsx index 1bba17d..451f2d7 100644 --- a/src/components/settings/CorrectWords.tsx +++ b/src/components/settings/CorrectWords.tsx @@ -1,5 +1,7 @@ import React, { useState } from "react"; import { useSettings } from "../../hooks/useSettings"; +import { Input } from "../ui/Input"; +import { Button } from "../ui/Button"; import { SettingContainer } from "../ui/SettingContainer"; interface CorrectWordsProps { @@ -44,39 +46,43 @@ export const CorrectWords: React.FC = React.memo(({ grouped={grouped} >
- setNewWord(e.target.value)} onKeyPress={handleKeyPress} placeholder="Add a word" - className="px-2 py-1 text-sm border border-mid-gray/30 rounded focus:outline-none focus:ring-1 focus:ring-logo-primary focus:border-transparent bg-background" + variant="compact" disabled={isUpdating("correct_words")} /> - +
{correctWords.length > 0 && (
{correctWords.map((word) => ( - + ))}
)} diff --git a/src/components/settings/MicrophoneSelector.tsx b/src/components/settings/MicrophoneSelector.tsx index dc9bccf..2b80342 100644 --- a/src/components/settings/MicrophoneSelector.tsx +++ b/src/components/settings/MicrophoneSelector.tsx @@ -33,10 +33,13 @@ export const MicrophoneSelector: React.FC = React.memo( await resetSetting("selected_microphone"); }; - const microphoneOptions = audioDevices.map(device => ({ - value: device.name, - label: device.name - })); + const microphoneOptions = [ + { value: "Default", label: "Default" }, + ...audioDevices.map(device => ({ + value: device.name, + label: device.name + })) + ]; return ( = React.memo( options={microphoneOptions} selectedValue={selectedMicrophone} onSelect={handleMicrophoneSelect} - placeholder={isLoading ? "Loading..." : "Select microphone..."} + placeholder={isLoading ? "Loading..." : ""} disabled={isUpdating("selected_microphone") || isLoading} onRefresh={refreshAudioDevices} /> diff --git a/src/components/settings/OutputDeviceSelector.tsx b/src/components/settings/OutputDeviceSelector.tsx index 156805e..a13fc64 100644 --- a/src/components/settings/OutputDeviceSelector.tsx +++ b/src/components/settings/OutputDeviceSelector.tsx @@ -34,10 +34,13 @@ export const OutputDeviceSelector: React.FC = React.m await resetSetting("selected_output_device"); }; - const outputDeviceOptions = outputDevices.map(device => ({ - value: device.name, - label: device.name - })); + const outputDeviceOptions = [ + { value: "Default", label: "Default" }, + ...outputDevices.map(device => ({ + value: device.name, + label: device.name + })) + ]; return ( = React.m options={outputDeviceOptions} selectedValue={selectedOutputDevice} onSelect={handleOutputDeviceSelect} - placeholder={isLoading ? "Loading..." : "Select output device..."} + placeholder={isLoading ? "Loading..." : ""} disabled={isUpdating("selected_output_device") || isLoading} onRefresh={refreshOutputDevices} /> diff --git a/src/components/ui/Button.tsx b/src/components/ui/Button.tsx new file mode 100644 index 0000000..0e50734 --- /dev/null +++ b/src/components/ui/Button.tsx @@ -0,0 +1,38 @@ +import React from "react"; + +interface ButtonProps extends React.ButtonHTMLAttributes { + variant?: "primary" | "secondary" | "danger" | "ghost"; + size?: "sm" | "md" | "lg"; +} + +export const Button: React.FC = ({ + children, + className = "", + variant = "primary", + size = "md", + ...props +}) => { + const baseClasses = "font-medium rounded focus:outline-none transition-colors disabled:opacity-50 disabled:cursor-not-allowed"; + + const variantClasses = { + primary: "text-white bg-background-ui hover:bg-background-ui/90 focus:ring-1 focus:ring-background-ui", + secondary: "bg-mid-gray/10 hover:bg-background-ui/30 focus:outline-none", + danger: "text-white bg-red-600 hover:bg-red-700 focus:ring-1 focus:ring-red-500", + ghost: "text-current hover:bg-mid-gray/10 focus:bg-mid-gray/20" + }; + + const sizeClasses = { + sm: "px-2 py-1 text-xs", + md: "px-3 py-1 text-sm", + lg: "px-4 py-2 text-base" + }; + + return ( + + ); +}; \ No newline at end of file diff --git a/src/components/ui/Dropdown.tsx b/src/components/ui/Dropdown.tsx index 5ffb010..8e1cf5c 100644 --- a/src/components/ui/Dropdown.tsx +++ b/src/components/ui/Dropdown.tsx @@ -1,4 +1,4 @@ -import React, { useState, useRef, useEffect } from "react"; +import React, { useEffect, useRef, useState } from "react"; export interface DropdownOption { value: string; @@ -95,7 +95,7 @@ export const Dropdown: React.FC = ({ type="button" className={`w-full px-2 py-1 text-sm text-left hover:bg-logo-primary/10 transition-colors duration-150 ${ selectedValue === option.value - ? "bg-logo-primary/20 text-logo-primary font-semibold" + ? "bg-logo-primary/20 font-semibold" : "" }`} onClick={() => handleSelect(option.value)} diff --git a/src/components/ui/Input.tsx b/src/components/ui/Input.tsx new file mode 100644 index 0000000..282de34 --- /dev/null +++ b/src/components/ui/Input.tsx @@ -0,0 +1,25 @@ +import React from "react"; + +interface InputProps extends React.InputHTMLAttributes { + variant?: "default" | "compact"; +} + +export const Input: React.FC = ({ + className = "", + variant = "default", + ...props +}) => { + const baseClasses = "px-2 py-1 text-sm font-semibold bg-mid-gray/10 border border-mid-gray/80 rounded text-left flex items-center justify-between transition-all duration-150 hover:bg-logo-primary/10 cursor-pointer hover:border-logo-primary focus:outline-none focus:bg-logo-primary/20 focus:border-logo-primary"; + + const variantClasses = { + default: "px-3 py-2", + compact: "px-2 py-1" + }; + + return ( + + ); +}; \ No newline at end of file diff --git a/src/components/ui/SettingContainer.tsx b/src/components/ui/SettingContainer.tsx index 01d06d5..a50f598 100644 --- a/src/components/ui/SettingContainer.tsx +++ b/src/components/ui/SettingContainer.tsx @@ -1,4 +1,4 @@ -import React, { useState, useEffect, useRef } from "react"; +import React, { useEffect, useRef, useState } from "react"; interface SettingContainerProps { title: string;