[Refactor]: Introduce MultiDropdownMenu component for layout consistency.

This commit is contained in:
Sakamoto Shiina
2025-11-12 12:32:18 +09:00
parent 01327fa852
commit 4a852374ab
7 changed files with 119 additions and 124 deletions

View File

@@ -3,8 +3,19 @@ import { _DropdownMenu } from "../_atoms/_dropdown_menu/_DropdownMenu";
export const DropdownMenu = (props) => { export const DropdownMenu = (props) => {
return ( return (
<div className={styles.container}> <div className={styles.each_dropdown_menu_wrapper}>
{props.secondary_label && <p className={styles.secondary_label}>{props.secondary_label}</p>}
<_DropdownMenu {...props} /> <_DropdownMenu {...props} />
</div> </div>
); );
};
export const MultiDropdownMenu = (props) => {
return (
<div className={styles.container}>
{props.settings.map((dropdown_props, index) => (
<DropdownMenu {...dropdown_props} />
))}
</div>
);
}; };

View File

@@ -1,5 +1,26 @@
@import "@scss_mixins"; @import "@scss_mixins";
// .container { .container {
// position: relative; display: flex;
// } flex-direction: row;
gap: 2.8rem;
}
.each_dropdown_menu_wrapper {
display: flex;
flex-direction: column;
gap: 0.6rem;
white-space: nowrap;
max-width: 24rem;
&.is_disabled {
pointer-events: none;
}
}
.secondary_label {
padding-left: 0.2rem;
padding-right: 0.4rem;
font-size: 1.4rem;
color: var(--dark_500_color);
white-space: nowrap;
}

View File

@@ -1,7 +1,7 @@
export { ActionButton } from "./action_button/ActionButton"; export { ActionButton } from "./action_button/ActionButton";
export { ComputeDevice } from "./compute_device/ComputeDevice"; export { ComputeDevice } from "./compute_device/ComputeDevice";
export { DeeplAuthKey, OpenWebpage_DeeplAuthKey } from "./deepl_auth_key/DeeplAuthKey"; export { DeeplAuthKey, OpenWebpage_DeeplAuthKey } from "./deepl_auth_key/DeeplAuthKey";
export { DropdownMenu } from "./dropdown_menu/DropdownMenu"; export { DropdownMenu, MultiDropdownMenu } from "./dropdown_menu/DropdownMenu";
export { Entry } from "./entry/Entry"; export { Entry } from "./entry/Entry";
export { EntryWithSaveButton } from "./entry_with_save_button/EntryWithSaveButton"; export { EntryWithSaveButton } from "./entry_with_save_button/EntryWithSaveButton";
export { HotkeysEntry } from "./hotkeys_entry/HotkeysEntry"; export { HotkeysEntry } from "./hotkeys_entry/HotkeysEntry";

View File

@@ -14,6 +14,7 @@ import {
import { import {
LabelComponent, LabelComponent,
DropdownMenu, DropdownMenu,
MultiDropdownMenu,
ThresholdComponent, ThresholdComponent,
SwitchBox, SwitchBox,
} from "../_components"; } from "../_components";
@@ -88,33 +89,29 @@ const Mic_Container = () => {
toggleFunction={toggleEnableAutoMicSelect} toggleFunction={toggleEnableAutoMicSelect}
/> />
</div> </div>
<MultiDropdownMenu
<div className={styles.device_dropdown_wrapper}> settings={[
<div className={styles.device_dropdown}> {
<p className={styles.device_secondary_label}>{t("config_page.device.label_host")}</p> dropdown_id: "mic_host",
<DropdownMenu secondary_label: t("config_page.device.label_host"),
dropdown_id="mic_host" selected_id: currentSelectedMicHost.data,
selected_id={currentSelectedMicHost.data} list: currentMicHostList.data,
list={currentMicHostList.data} selectFunction: selectFunction_host,
selectFunction={selectFunction_host} state: currentSelectedMicHost.state,
state={currentSelectedMicHost.state} style: { maxWidth: "20rem", minWidth: "10rem" },
style={{ maxWidth: "20rem", minWidth: "10rem" }} is_disabled: is_disabled_selector,
is_disabled={is_disabled_selector} },
/> {
</div> dropdown_id: "mic_device",
secondary_label: t("config_page.device.label_device"),
<div className={styles.device_dropdown}> selected_id: currentSelectedMicDevice.data,
<p className={styles.device_secondary_label}>{t("config_page.device.label_device")}</p> list: currentMicDeviceList.data,
<DropdownMenu selectFunction: selectFunction_device,
dropdown_id="mic_device" state: currentSelectedMicDevice.state,
selected_id={currentSelectedMicDevice.data} is_disabled: is_disabled_selector,
list={currentMicDeviceList.data} }
selectFunction={selectFunction_device} ]}
state={currentSelectedMicDevice.state} />
is_disabled={is_disabled_selector}
/>
</div>
</div>
</div> </div>
</div> </div>
<div className={styles.threshold_container}> <div className={styles.threshold_container}>
@@ -189,19 +186,16 @@ const Speaker_Container = () => {
toggleFunction={toggleEnableAutoSpeakerSelect} toggleFunction={toggleEnableAutoSpeakerSelect}
/> />
</div> </div>
<DropdownMenu
<div className={styles.device_dropdown}> dropdown_id="speaker_device"
<p className={styles.device_secondary_label}>{t("config_page.device.label_device")}</p> secondary_label={t("config_page.device.label_device")}
<DropdownMenu label={t("config_page.device.speaker_device.label")}
dropdown_id="speaker_device" selected_id={currentSelectedSpeakerDevice.data}
label={t("config_page.device.speaker_device.label")} list={currentSpeakerDeviceList.data}
selected_id={currentSelectedSpeakerDevice.data} selectFunction={selectFunction}
list={currentSpeakerDeviceList.data} state={currentSelectedSpeakerDevice.state}
selectFunction={selectFunction} is_disabled={is_disabled_selector}
state={currentSelectedSpeakerDevice.state} />
is_disabled={is_disabled_selector}
/>
</div>
</div> </div>
</div> </div>
<div className={styles.threshold_container}> <div className={styles.threshold_container}>

View File

@@ -77,29 +77,4 @@
gap: 1.2rem; gap: 1.2rem;
justify-content: center; justify-content: center;
align-items: center; align-items: center;
}
.device_dropdown_wrapper {
display: flex;
flex-direction: row;
gap: 2.8rem;
}
.device_dropdown {
display: flex;
flex-direction: column;
gap: 0.6rem;
white-space: nowrap;
max-width: 24rem;
&.is_disabled {
pointer-events: none;
}
}
.device_secondary_label {
padding-left: 0.2rem;
padding-right: 0.4rem;
font-size: 1.4rem;
color: var(--dark_500_color);
white-space: nowrap;
} }

View File

@@ -20,6 +20,7 @@ import {
import { import {
DropdownMenu, DropdownMenu,
MultiDropdownMenu,
LabelComponent, LabelComponent,
SectionLabelComponent, SectionLabelComponent,
} from "../_components"; } from "../_components";
@@ -378,33 +379,29 @@ const TranscriptionComputeDevice_Box = () => {
desc={t("config_page.common.compute_device.desc")} desc={t("config_page.common.compute_device.desc")}
/> />
<div className={styles.device_contents}> <div className={styles.device_contents}>
<MultiDropdownMenu
<div className={styles.device_dropdown_wrapper}> settings={[
<div className={styles.device_dropdown}> {
<p className={styles.device_secondary_label}>{t("config_page.common.compute_device.label_device")}</p> secondary_label: t("config_page.common.compute_device.label_device"),
<DropdownMenu dropdown_id: "transcription_compute_device",
dropdown_id="transcription_compute_device" selected_id: target_index,
selected_id={target_index} list: list_for_ui,
list={list_for_ui} selectFunction: selectFunction_ComputeDevice,
selectFunction={selectFunction_ComputeDevice} state: currentSelectedTranscriptionComputeDevice.state,
state={currentSelectedTranscriptionComputeDevice.state} style: { maxWidth: "20rem", minWidth: "10rem" },
style={{ maxWidth: "20rem", minWidth: "10rem" }} is_disabled: is_disabled_selector,
is_disabled={is_disabled_selector} },
/> {
</div> secondary_label: t("config_page.common.compute_device.label_type"),
dropdown_id: "transcription_compute_type",
<div className={styles.device_dropdown}> selected_id: currentSelectedTranscriptionComputeType.data,
<p className={styles.device_secondary_label}>{t("config_page.common.compute_device.label_type")}</p> list: new_compute_types_labels,
<DropdownMenu selectFunction: selectFunction_ComputeType,
dropdown_id="transcription_compute_type" state: currentSelectedTranscriptionComputeType.state,
selected_id={currentSelectedTranscriptionComputeType.data} is_disabled: is_disabled_selector,
list={new_compute_types_labels} }
selectFunction={selectFunction_ComputeType} ]}
state={currentSelectedTranscriptionComputeType.state} />
is_disabled={is_disabled_selector}
/>
</div>
</div>
</div> </div>
</div> </div>
</div> </div>

View File

@@ -17,6 +17,7 @@ import {
import { import {
DropdownMenu, DropdownMenu,
MultiDropdownMenu,
LabelComponent, LabelComponent,
} from "../_components"; } from "../_components";
@@ -186,33 +187,29 @@ const TranslationComputeDevice_Box = () => {
desc={t("config_page.common.compute_device.desc")} desc={t("config_page.common.compute_device.desc")}
/> />
<div className={styles.device_contents}> <div className={styles.device_contents}>
<MultiDropdownMenu
<div className={styles.device_dropdown_wrapper}> settings={[
<div className={styles.device_dropdown}> {
<p className={styles.device_secondary_label}>{t("config_page.common.compute_device.label_device")}</p> dropdown_id: "translation_compute_device",
<DropdownMenu secondary_label: t("config_page.common.compute_device.label_device"),
dropdown_id="translation_compute_device" selected_id: target_index,
selected_id={target_index} list: list_for_ui,
list={list_for_ui} selectFunction: selectFunction_ComputeDevice,
selectFunction={selectFunction_ComputeDevice} state: currentSelectedTranslationComputeDevice.state,
state={currentSelectedTranslationComputeDevice.state} style: { maxWidth: "20rem", minWidth: "10rem" },
style={{ maxWidth: "20rem", minWidth: "10rem" }} is_disabled: is_disabled_selector,
is_disabled={is_disabled_selector} },
/> {
</div> dropdown_id: "translation_compute_type",
secondary_label: t("config_page.common.compute_device.label_type"),
<div className={styles.device_dropdown}> selected_id: currentSelectedTranslationComputeType.data,
<p className={styles.device_secondary_label}>{t("config_page.common.compute_device.label_type")}</p> list: new_compute_types_labels,
<DropdownMenu selectFunction: selectFunction_ComputeType,
dropdown_id="translation_compute_type" state: currentSelectedTranslationComputeType.state,
selected_id={currentSelectedTranslationComputeType.data} is_disabled: is_disabled_selector,
list={new_compute_types_labels} }
selectFunction={selectFunction_ComputeType} ]}
state={currentSelectedTranslationComputeType.state} />
is_disabled={is_disabled_selector}
/>
</div>
</div>
</div> </div>
</div> </div>
</div> </div>