[Refactor] Separate SwitchBox into _atom and wrapper, add secondary label support.

This commit is contained in:
Sakamoto Shiina
2025-11-12 15:27:10 +09:00
parent d529ed8962
commit ddcd19d5eb
6 changed files with 106 additions and 82 deletions

View File

@@ -0,0 +1,44 @@
import clsx from "clsx";
import { useState } from "react";
import styles from "./_SwitchBox.module.scss";
export const _SwitchBox = (props) => {
const [is_hovered, setIsHovered] = useState(false);
const [is_mouse_down, setIsMouseDown] = useState(false);
const is_pending = (props.variable.state === "pending");
const getClassNames = (base_class) => clsx(base_class, {
[styles.is_active]: (props.variable.data === true),
[styles.is_pending]: is_pending,
[styles.is_hovered]: is_hovered,
[styles.is_mouse_down]: is_mouse_down,
});
const onMouseEnter = () => setIsHovered(true);
const onMouseLeave = () => setIsHovered(false);
const onMouseDown = () => setIsMouseDown(true);
const onMouseUp = () => setIsMouseDown(false);
const toggleFunction = () => {
props.toggleFunction();
};
return (
<div className={styles.switchbox_container}>
<div className={getClassNames(styles.switchbox_wrapper)}
onMouseEnter={onMouseEnter}
onMouseLeave={onMouseLeave}
onMouseDown={onMouseDown}
onMouseUp={onMouseUp}
onClick={toggleFunction}
>
<div className={getClassNames(styles.toggle_control)}>
<span className={getClassNames(styles.control)}></span>
{is_pending && <span className={styles.loader}></span>}
</div>
</div>
</div>
);
};

View File

@@ -0,0 +1,33 @@
@import "@scss_mixins";
.switchbox_container {
display: flex;
justify-content: end;
align-items: center;
height: 2rem;
}
.switchbox_wrapper {
display: flex;
justify-content: center;
align-items: center;
cursor: pointer;
padding: 2rem;
height: 100%;
flex-shrink: 0;
&.is_pending {
pointer-events: none;
}
}
.toggle_control {
position: relative;
@include toggle_control_styles;
display: flex;
justify-content: center;
align-items: center;
}
.loader {
@include loader(2rem, 0.2rem, right, -4rem);
}

View File

@@ -1,44 +1,13 @@
import clsx from "clsx";
import { useState } from "react";
import styles from "./SwitchBox.module.scss";
import { _SwitchBox } from "../_atoms/_switch_box/_SwitchBox";
export const SwitchBox = (props) => {
const [is_hovered, setIsHovered] = useState(false);
const [is_mouse_down, setIsMouseDown] = useState(false);
const is_pending = (props.variable.state === "pending");
const getClassNames = (base_class) => clsx(base_class, {
[styles.is_active]: (props.variable.data === true),
[styles.is_pending]: is_pending,
[styles.is_hovered]: is_hovered,
[styles.is_mouse_down]: is_mouse_down,
});
const onMouseEnter = () => setIsHovered(true);
const onMouseLeave = () => setIsHovered(false);
const onMouseDown = () => setIsMouseDown(true);
const onMouseUp = () => setIsMouseDown(false);
const toggleFunction = () => {
props.toggleFunction();
};
return (
<div className={styles.switchbox_container}>
<div className={getClassNames(styles.switchbox_wrapper)}
onMouseEnter={onMouseEnter}
onMouseLeave={onMouseLeave}
onMouseDown={onMouseDown}
onMouseUp={onMouseUp}
onClick={toggleFunction}
>
<div className={getClassNames(styles.toggle_control)}>
<span className={getClassNames(styles.control)}></span>
{is_pending && <span className={styles.loader}></span>}
</div>
</div>
<div className={styles.container}>
{props.secondary_label && <p className={styles.secondary_label}>{props.secondary_label}</p>}
<_SwitchBox {...props} />
</div>
);
};

View File

@@ -1,33 +1,17 @@
@import "@scss_mixins";
.switchbox_container {
display: flex;
justify-content: end;
align-items: center;
height: 2rem;
}
.switchbox_wrapper {
.container {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
cursor: pointer;
padding: 2rem;
height: 100%;
flex-shrink: 0;
&.is_pending {
pointer-events: none;
}
gap: 1rem;
}
.toggle_control {
position: relative;
@include toggle_control_styles;
display: flex;
justify-content: center;
align-items: center;
}
.loader {
@include loader(2rem, 0.2rem, right, -4rem);
.secondary_label {
padding-left: 0.2rem;
padding-right: 0.4rem;
font-size: 1.4rem;
color: var(--dark_500_color);
white-space: nowrap;
}

View File

@@ -81,14 +81,11 @@ const Mic_Container = () => {
<div className={device_container_class} onMouseLeave={onMouseLeaveFunction}>
<LabelComponent label={t("config_page.device.mic_host_device.label")} />
<div className={styles.device_contents}>
<div className={styles.device_auto_select_wrapper}>
<p className={styles.device_secondary_label}>{t("config_page.device.label_auto_select")}</p>
<SwitchBox
variable={currentEnableAutoMicSelect}
toggleFunction={toggleEnableAutoMicSelect}
/>
</div>
<SwitchBox
secondary_label={t("config_page.device.label_auto_select")}
variable={currentEnableAutoMicSelect}
toggleFunction={toggleEnableAutoMicSelect}
/>
<MultiDropdownMenu
dropdown_settings={[
{
@@ -178,14 +175,11 @@ const Speaker_Container = () => {
<div className={device_container_class} onMouseLeave={onMouseLeaveFunction}>
<LabelComponent label={t("config_page.device.speaker_device.label")} />
<div className={styles.device_contents}>
<div className={styles.device_auto_select_wrapper}>
<p className={styles.device_secondary_label}>{t("config_page.device.label_auto_select")}</p>
<SwitchBox
variable={currentEnableAutoSpeakerSelect}
toggleFunction={toggleEnableAutoSpeakerSelect}
/>
</div>
<SwitchBox
secondary_label={t("config_page.device.label_auto_select")}
variable={currentEnableAutoSpeakerSelect}
toggleFunction={toggleEnableAutoSpeakerSelect}
/>
<DropdownMenu
dropdown_id="speaker_device"
secondary_label={t("config_page.device.label_device")}

View File

@@ -1,5 +1,5 @@
import { SwitchBox } from "../../_components";
import { _DownloadButton } from "../../_components/_atoms/_download_button/_DownloadButton";
import { _SwitchBox } from "../../_components/_atoms/_switch_box/_SwitchBox";
import styles from "./PluginsControlComponent.module.scss";
import { useI18n } from "@useI18n";
@@ -90,7 +90,7 @@ const DownloadedPluginControl = ({
return (
<div className={styles.container}>
<p>{t("config_page.plugins.no_latest_info")}</p>
<SwitchBox variable={option} toggleFunction={togglePlugin} />
<_SwitchBox variable={option} toggleFunction={togglePlugin} />
</div>
);
} else if (plugin_status.is_latest_version_already) {
@@ -98,7 +98,7 @@ const DownloadedPluginControl = ({
<div className={styles.container}>
<p>{latest_version_label}</p>
<p>{t("config_page.plugins.using_latest_version")}</p>
<SwitchBox variable={option} toggleFunction={togglePlugin} />
<_SwitchBox variable={option} toggleFunction={togglePlugin} />
</div>
);
} else if (plugin_status.is_latest_version_available) {
@@ -107,14 +107,14 @@ const DownloadedPluginControl = ({
<p>{latest_version_label}</p>
<p>{t("config_page.plugins.available_latest_version")}</p>
<_DownloadButton option={option} downloadStartFunction={downloadStartFunction} />
<SwitchBox variable={option} toggleFunction={togglePlugin} />
<_SwitchBox variable={option} toggleFunction={togglePlugin} />
</div>
);
} else {
return (
<div className={styles.container}>
<p>{t("config_page.plugins.available_latest_version")}</p>
<SwitchBox variable={option} toggleFunction={togglePlugin} />
<_SwitchBox variable={option} toggleFunction={togglePlugin} />
</div>
);
}