diff --git a/src/components/FormSwitch.css b/src/components/FormSwitch.css index 38cbea8d7..129c58475 100644 --- a/src/components/FormSwitch.css +++ b/src/components/FormSwitch.css @@ -1,5 +1,6 @@ .vc-form-switch-wrapper { margin-bottom: 20px; + cursor: pointer; } .vc-form-switch { diff --git a/src/components/FormSwitch.tsx b/src/components/FormSwitch.tsx index 098157626..255f77992 100644 --- a/src/components/FormSwitch.tsx +++ b/src/components/FormSwitch.tsx @@ -26,7 +26,7 @@ export interface FormSwitchProps { export function FormSwitch({ onChange, title, value, description, disabled, className, hideBorder }: FormSwitchProps) { return ( -
+ ); } diff --git a/src/components/Switch.css b/src/components/Switch.css index e809bd500..cc0447a76 100644 --- a/src/components/Switch.css +++ b/src/components/Switch.css @@ -9,13 +9,13 @@ width: 44px; .high-contrast-mode & { - border-color: var(--border-strong) + border-color: var(--border-strong); } } .vc-switch-checked { background: var(--brand-500); - border-color: var(--control-border-primary-default) + border-color: var(--control-border-primary-default); } .vc-switch-disabled { @@ -23,6 +23,11 @@ opacity: 0.3; } +.vc-switch-focusVisible { + /* stylelint-disable-next-line custom-property-pattern */ + box-shadow: 0 0 0 4px var(--__adaptive-focus-ring-color, var(--focus-primary, #00b0f4)); +} + .vc-switch-slider { display: block; height: 20px; @@ -31,10 +36,9 @@ position: absolute; width: 28px; transition: 100ms transform ease-in-out; - overflow: visible + overflow: visible; } - .vc-switch-input { border-radius: 14px; cursor: pointer; @@ -46,7 +50,8 @@ top: 0; width: 100%; - &[disabled] { - pointer-events: none + &:disabled { + pointer-events: none; + cursor: not-allowed } } \ No newline at end of file diff --git a/src/components/Switch.tsx b/src/components/Switch.tsx index 4d59f15bf..df630ca75 100644 --- a/src/components/Switch.tsx +++ b/src/components/Switch.tsx @@ -20,6 +20,8 @@ import "./Switch.css"; import { classNameFactory } from "@api/Styles"; import { classes } from "@utils/misc"; +import { useState } from "@webpack/common"; +import type { FocusEvent } from "react"; const switchCls = classNameFactory("vc-switch-"); @@ -33,9 +35,21 @@ export interface SwitchProps { } export function Switch({ checked, onChange, disabled }: SwitchProps) { + const [focusVisible, setFocusVisible] = useState(false); + + // Due to how we wrap the invisible input, there is no good way to do this with css. + // We need it on the parent, not the input itself. For this, you can use either: + // - :focus-within ~ this shows also when clicking, not just on keyboard focus => SUCKS + // - :has(:focus-visible) ~ works but :has performs terribly inside Discord + // - JS event handlers ~ what we are using now + const handleFocusChange = (event: FocusEvent) => { + const target = event.currentTarget; + setFocusVisible(target.matches(":focus-visible")); + }; + return (
-
+
+ ); diff --git a/src/components/settings/tabs/plugins/components/Common.tsx b/src/components/settings/tabs/plugins/components/Common.tsx index 61c3da529..c7c2471ab 100644 --- a/src/components/settings/tabs/plugins/components/Common.tsx +++ b/src/components/settings/tabs/plugins/components/Common.tsx @@ -38,11 +38,12 @@ interface SettingsSectionProps extends PropsWithChildren { description: string; error?: string | null; inlineSetting?: boolean; + tag?: "label" | "div"; } -export function SettingsSection({ name, description, error, inlineSetting, children }: SettingsSectionProps) { +export function SettingsSection({ tag: Tag = "div", name, description, error, inlineSetting, children }: SettingsSectionProps) { return ( -
+
{name && {wordsToTitle(wordsFromCamel(name))}} @@ -51,6 +52,6 @@ export function SettingsSection({ name, description, error, inlineSetting, child {children}
{error && {error}} -
+
); }