feat(design): the field family, the dropdown trigger, native controls, the no-raw-input lint rule (E28 S3c)
- ui/Input, Textarea, InnerInput + fieldClass (A4): the >= 3:1 edge, a 2px accent focus edge, the danger edge for invalid, md/sm/xs/heading rungs, 1rem and 44 on touch - ui/SelectTrigger (A5): SortControl, FilterSelect, the view switcher and the date filter on one trigger, a pill in a toolbar, r8 in a form - ui/NativeControls (A6): Checkbox, CheckRow, Slider, ColorInput - every raw input swept (~100 sites); inputCls retired; local/input-primitive - useReturnFocus: an in-place editor hands the focus back to its trigger on Enter/Escape (the playlist and Plex title renames, the priority number); the Plex playlist rename gains Escape and an accessible name - back to top: a round 48 FAB (owner decision); DESIGN.md A2 and the log
This commit is contained in:
@@ -4,6 +4,7 @@ import { useTranslation } from "react-i18next";
|
||||
import { Slider, Toggle } from "./plexPlayerControls";
|
||||
import { clockParts, type PlexPlayerPrefs } from "../lib/plexPlayerPrefs";
|
||||
import { Pressable } from "./ui/Pressable";
|
||||
import { ColorInput, Checkbox } from "./ui/NativeControls";
|
||||
|
||||
type SettingsTab = "sync" | "playback" | "subtitle" | "clock";
|
||||
|
||||
@@ -160,36 +161,24 @@ export function PlexPlayerSettings(props: {
|
||||
/>
|
||||
<div className="flex items-center justify-between px-1 py-1.5">
|
||||
<span className="text-[0.75rem] text-white/80">{t("plex.player.subColor")}</span>
|
||||
<input
|
||||
type="color"
|
||||
value={prefs.subColor}
|
||||
onChange={(e) => patchPrefs({ subColor: e.target.value })}
|
||||
className="h-6 w-10 cursor-pointer rounded-sm bg-transparent"
|
||||
/>
|
||||
<ColorInput value={prefs.subColor} onChange={(v) => patchPrefs({ subColor: v })} />
|
||||
</div>
|
||||
<div className="flex items-center justify-between px-1 py-1.5">
|
||||
<span className="text-[0.75rem] text-white/80">{t("plex.player.subBg")}</span>
|
||||
<div className="flex items-center gap-2">
|
||||
<label className="flex items-center gap-1 text-2xs text-white/70">
|
||||
<input
|
||||
type="checkbox"
|
||||
<Checkbox
|
||||
checked={prefs.subBg === "transparent"}
|
||||
onChange={(e) =>
|
||||
onChange={(checked) =>
|
||||
patchPrefs({
|
||||
subBg: e.target.checked ? "transparent" : "#000000",
|
||||
subBg: checked ? "transparent" : "#000000",
|
||||
})
|
||||
}
|
||||
className="accent-accent"
|
||||
/>
|
||||
{t("plex.player.subBgNone")}
|
||||
</label>
|
||||
{prefs.subBg !== "transparent" && (
|
||||
<input
|
||||
type="color"
|
||||
value={prefs.subBg}
|
||||
onChange={(e) => patchPrefs({ subBg: e.target.value })}
|
||||
className="h-6 w-10 cursor-pointer rounded-sm bg-transparent"
|
||||
/>
|
||||
<ColorInput value={prefs.subBg} onChange={(v) => patchPrefs({ subBg: v })} />
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
@@ -207,11 +196,9 @@ export function PlexPlayerSettings(props: {
|
||||
<span className="text-[0.75rem] text-white/80">
|
||||
{t("plex.player.subShadowColor")}
|
||||
</span>
|
||||
<input
|
||||
type="color"
|
||||
<ColorInput
|
||||
value={prefs.subShadowColor}
|
||||
onChange={(e) => patchPrefs({ subShadowColor: e.target.value })}
|
||||
className="h-6 w-10 cursor-pointer rounded-sm bg-transparent"
|
||||
onChange={(v) => patchPrefs({ subShadowColor: v })}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
@@ -241,12 +228,7 @@ export function PlexPlayerSettings(props: {
|
||||
/>
|
||||
<div className="flex items-center justify-between px-1 py-1.5">
|
||||
<span className="text-[0.75rem] text-white/80">{t("plex.player.clockColor")}</span>
|
||||
<input
|
||||
type="color"
|
||||
value={prefs.clockColor}
|
||||
onChange={(e) => patchPrefs({ clockColor: e.target.value })}
|
||||
className="h-6 w-10 cursor-pointer rounded-sm bg-transparent"
|
||||
/>
|
||||
<ColorInput value={prefs.clockColor} onChange={(v) => patchPrefs({ clockColor: v })} />
|
||||
</div>
|
||||
<Toggle
|
||||
label={t("plex.player.clockDate")}
|
||||
|
||||
Reference in New Issue
Block a user