[Refactor] Introduce MultiDropdownMenuContainer template for layout consistency.

This commit is contained in:
Sakamoto Shiina
2025-11-12 14:48:13 +09:00
parent 4a852374ab
commit d529ed8962
7 changed files with 72 additions and 156 deletions

View File

@@ -13,8 +13,8 @@ export const DropdownMenu = (props) => {
export const MultiDropdownMenu = (props) => { export const MultiDropdownMenu = (props) => {
return ( return (
<div className={styles.container}> <div className={styles.container}>
{props.settings.map((dropdown_props, index) => ( {props.dropdown_settings.map((dropdown_props, index) => (
<DropdownMenu {...dropdown_props} /> <DropdownMenu key={dropdown_props.dropdown_id} {...dropdown_props} />
))} ))}
</div> </div>
); );

View File

@@ -5,6 +5,7 @@ import { useStore_IsOpenedDropdownMenu, useStore_IsBreakPoint } from "@store";
import { import {
LabelComponent, LabelComponent,
DropdownMenu, DropdownMenu,
MultiDropdownMenu,
Slider, Slider,
SwitchBox, SwitchBox,
Entry, Entry,
@@ -42,6 +43,22 @@ export const DropdownMenuContainer = (props) => {
); );
}; };
export const MultiDropdownMenuContainer = (props) => {
const { onMouseLeaveFunction } = useOnMouseLeaveDropdownMenu();
const { currentIsBreakPoint } = useStore_IsBreakPoint();
const container_class = clsx(styles.container, {
[styles.is_break_point]: currentIsBreakPoint.data,
});
return (
<div className={container_class} onMouseLeave={onMouseLeaveFunction}>
<LabelComponent label={props.label} desc={props.desc} />
<MultiDropdownMenu dropdown_settings={props.dropdown_settings} />
</div>
);
};
const TemplatesContainerWrapper = ({ const TemplatesContainerWrapper = ({
children, children,
add_break_point = true, add_break_point = true,

View File

@@ -90,7 +90,7 @@ const Mic_Container = () => {
/> />
</div> </div>
<MultiDropdownMenu <MultiDropdownMenu
settings={[ dropdown_settings={[
{ {
dropdown_id: "mic_host", dropdown_id: "mic_host",
secondary_label: t("config_page.device.label_host"), secondary_label: t("config_page.device.label_host"),

View File

@@ -11,6 +11,7 @@ import {
import { import {
WordFilterContainer, WordFilterContainer,
DownloadModelsContainer, DownloadModelsContainer,
MultiDropdownMenuContainer,
RadioButtonContainer, RadioButtonContainer,
DropdownMenuContainer, DropdownMenuContainer,
SliderContainer, SliderContainer,
@@ -282,8 +283,6 @@ const TranscriptionComputeDevice_Box = () => {
currentSelectedTranscriptionComputeType, currentSelectedTranscriptionComputeType,
setSelectedTranscriptionComputeType, setSelectedTranscriptionComputeType,
} = useTranscription(); } = useTranscription();
const { onMouseLeaveFunction } = useOnMouseLeaveDropdownMenu();
const { currentIsBreakPoint } = useStore_IsBreakPoint();
const list_for_ui = transformDeviceArray(currentSelectableTranscriptionComputeDeviceList.data); const list_for_ui = transformDeviceArray(currentSelectableTranscriptionComputeDeviceList.data);
@@ -365,46 +364,34 @@ const TranscriptionComputeDevice_Box = () => {
setSelectedTranscriptionComputeType(selected_data.selected_id); setSelectedTranscriptionComputeType(selected_data.selected_id);
}; };
const device_container_class = clsx(styles.device_container, {
[styles.is_break_point]: currentIsBreakPoint.data,
});
const is_disabled_selector = currentSelectedTranscriptionComputeDevice.state === "pending" || currentSelectedTranscriptionComputeType.state === "pending"; const is_disabled_selector = currentSelectedTranscriptionComputeDevice.state === "pending" || currentSelectedTranscriptionComputeType.state === "pending";
return ( return (
<div className={styles.mic_container}> <MultiDropdownMenuContainer
<div className={device_container_class} onMouseLeave={onMouseLeaveFunction}> label={t("config_page.transcription.transcription_compute_device.label")}
<LabelComponent desc={t("config_page.common.compute_device.desc")}
label={t("config_page.transcription.transcription_compute_device.label")} dropdown_settings={[
desc={t("config_page.common.compute_device.desc")} {
/> secondary_label: t("config_page.common.compute_device.label_device"),
<div className={styles.device_contents}> dropdown_id: "transcription_compute_device",
<MultiDropdownMenu selected_id: target_index,
settings={[ list: list_for_ui,
{ selectFunction: selectFunction_ComputeDevice,
secondary_label: t("config_page.common.compute_device.label_device"), state: currentSelectedTranscriptionComputeDevice.state,
dropdown_id: "transcription_compute_device", style: { maxWidth: "20rem", minWidth: "10rem" },
selected_id: target_index, is_disabled: is_disabled_selector,
list: list_for_ui, },
selectFunction: selectFunction_ComputeDevice, {
state: currentSelectedTranscriptionComputeDevice.state, secondary_label: t("config_page.common.compute_device.label_type"),
style: { maxWidth: "20rem", minWidth: "10rem" }, dropdown_id: "transcription_compute_type",
is_disabled: is_disabled_selector, selected_id: currentSelectedTranscriptionComputeType.data,
}, list: new_compute_types_labels,
{ selectFunction: selectFunction_ComputeType,
secondary_label: t("config_page.common.compute_device.label_type"), state: currentSelectedTranscriptionComputeType.state,
dropdown_id: "transcription_compute_type", is_disabled: is_disabled_selector,
selected_id: currentSelectedTranscriptionComputeType.data, }
list: new_compute_types_labels, ]}
selectFunction: selectFunction_ComputeType, />
state: currentSelectedTranscriptionComputeType.state,
is_disabled: is_disabled_selector,
}
]}
/>
</div>
</div>
</div>
); );
}; };

View File

@@ -85,37 +85,4 @@
justify-content: end; justify-content: end;
padding-left: 2rem; padding-left: 2rem;
gap: 2rem; gap: 2rem;
}
.device_auto_select_wrapper {
display: flex;
flex-direction: column;
gap: 1.2rem;
justify-content: 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

@@ -11,6 +11,7 @@ import {
import { import {
DownloadModelsContainer, DownloadModelsContainer,
DeeplAuthKeyContainer, DeeplAuthKeyContainer,
MultiDropdownMenuContainer,
useOnMouseLeaveDropdownMenu, useOnMouseLeaveDropdownMenu,
} from "../_templates/Templates"; } from "../_templates/Templates";
@@ -180,39 +181,31 @@ const TranslationComputeDevice_Box = () => {
const is_disabled_selector = currentSelectedTranslationComputeDevice.state === "pending" || currentSelectedTranslationComputeType.state === "pending"; const is_disabled_selector = currentSelectedTranslationComputeDevice.state === "pending" || currentSelectedTranslationComputeType.state === "pending";
return ( return (
<div className={styles.mic_container}> <MultiDropdownMenuContainer
<div className={device_container_class} onMouseLeave={onMouseLeaveFunction}> label={t("config_page.translation.translation_compute_device.label")}
<LabelComponent desc={t("config_page.common.compute_device.desc")}
label={t("config_page.translation.translation_compute_device.label")} dropdown_settings={[
desc={t("config_page.common.compute_device.desc")} {
/> dropdown_id: "translation_compute_device",
<div className={styles.device_contents}> secondary_label: t("config_page.common.compute_device.label_device"),
<MultiDropdownMenu selected_id: target_index,
settings={[ list: list_for_ui,
{ selectFunction: selectFunction_ComputeDevice,
dropdown_id: "translation_compute_device", state: currentSelectedTranslationComputeDevice.state,
secondary_label: t("config_page.common.compute_device.label_device"), style: { maxWidth: "20rem", minWidth: "10rem" },
selected_id: target_index, is_disabled: is_disabled_selector,
list: list_for_ui, },
selectFunction: selectFunction_ComputeDevice, {
state: currentSelectedTranslationComputeDevice.state, dropdown_id: "translation_compute_type",
style: { maxWidth: "20rem", minWidth: "10rem" }, secondary_label: t("config_page.common.compute_device.label_type"),
is_disabled: is_disabled_selector, selected_id: currentSelectedTranslationComputeType.data,
}, list: new_compute_types_labels,
{ selectFunction: selectFunction_ComputeType,
dropdown_id: "translation_compute_type", state: currentSelectedTranslationComputeType.state,
secondary_label: t("config_page.common.compute_device.label_type"), is_disabled: is_disabled_selector,
selected_id: currentSelectedTranslationComputeType.data, }
list: new_compute_types_labels, ]}
selectFunction: selectFunction_ComputeType, />
state: currentSelectedTranslationComputeType.state,
is_disabled: is_disabled_selector,
}
]}
/>
</div>
</div>
</div>
); );
}; };

View File

@@ -55,52 +55,4 @@
.threshold_section { .threshold_section {
width: 100%; width: 100%;
}
.device_label {
font-size: 1.8rem;
}
.device_contents {
display: flex;
width: 100%;
justify-content: end;
padding-left: 2rem;
gap: 2rem;
}
.device_auto_select_wrapper {
display: flex;
flex-direction: column;
gap: 1.2rem;
justify-content: 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;
} }