[Refactor] Improve slider logic flexibility.(Adjust to Vr section)
This commit is contained in:
@@ -206,20 +206,21 @@ export const useConfigFunctions = (Category) => {
|
|||||||
import { useState, useEffect, useCallback, useMemo } from "react";
|
import { useState, useEffect, useCallback, useMemo } from "react";
|
||||||
|
|
||||||
export const useSliderLogic = ({
|
export const useSliderLogic = ({
|
||||||
current_value,
|
variable,
|
||||||
setterFunction,
|
setterFunction,
|
||||||
postUpdateAction,
|
postUpdateAction,
|
||||||
min,
|
min,
|
||||||
max,
|
max,
|
||||||
step = 1,
|
step = 1,
|
||||||
show_label_values = [],
|
show_label_values = null,
|
||||||
marks_step,
|
marks_step,
|
||||||
|
setter_timing = "on_change_committed",
|
||||||
}) => {
|
}) => {
|
||||||
if (marks_step === undefined) {
|
if (marks_step === undefined) {
|
||||||
marks_step = step;
|
marks_step = step;
|
||||||
}
|
}
|
||||||
|
|
||||||
const [ui_value, setUiValue] = useState(current_value.data);
|
const [ui_value, setUiValue] = useState(variable);
|
||||||
|
|
||||||
const decimalPlaces = marks_step.toString().includes('.')
|
const decimalPlaces = marks_step.toString().includes('.')
|
||||||
? marks_step.toString().split('.')[1].length
|
? marks_step.toString().split('.')[1].length
|
||||||
@@ -234,25 +235,43 @@ export const useSliderLogic = ({
|
|||||||
}, [show_label_values, decimalPlaces]);
|
}, [show_label_values, decimalPlaces]);
|
||||||
|
|
||||||
const marks = useMemo(() => {
|
const marks = useMemo(() => {
|
||||||
|
if (show_label_values === null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
return createMarks(min, max, marks_step, labelFormatter);
|
return createMarks(min, max, marks_step, labelFormatter);
|
||||||
}, [min, max, marks_step, labelFormatter]);
|
}, [min, max, marks_step, labelFormatter, show_label_values]);
|
||||||
|
|
||||||
const onchangeFunction = useCallback((value) => {
|
let onchangeFunction;
|
||||||
setUiValue(value);
|
let onchangeCommittedFunction;
|
||||||
}, []);
|
|
||||||
|
|
||||||
const onchangeCommittedFunction = useCallback((value) => {
|
if (setter_timing === "on_change") {
|
||||||
setterFunction(value);
|
onchangeFunction = useCallback((value) => {
|
||||||
}, [setterFunction]);
|
setUiValue(value);
|
||||||
|
setterFunction(value);
|
||||||
|
}, [setterFunction]);
|
||||||
|
|
||||||
|
onchangeCommittedFunction = null;
|
||||||
|
|
||||||
|
} else if (setter_timing === "on_change_committed") {
|
||||||
|
onchangeFunction = useCallback((value) => {
|
||||||
|
setUiValue(value);
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
onchangeCommittedFunction = useCallback((value) => {
|
||||||
|
setterFunction(value);
|
||||||
|
}, [setterFunction]);
|
||||||
|
} else {
|
||||||
|
console.error(`Invalid 'setter_timing' value provided to useSliderLogic. Expected 'on_change' or 'on_change_committed'. Received: ${setter_timing}`);
|
||||||
|
}
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (current_value.data !== ui_value) {
|
if (variable !== ui_value) {
|
||||||
setUiValue(current_value.data);
|
setUiValue(variable);
|
||||||
}
|
}
|
||||||
if (postUpdateAction) {
|
if (postUpdateAction) {
|
||||||
postUpdateAction();
|
postUpdateAction();
|
||||||
}
|
}
|
||||||
}, [current_value.data]);
|
}, [variable]);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
ui_value,
|
ui_value,
|
||||||
@@ -264,15 +283,15 @@ export const useSliderLogic = ({
|
|||||||
|
|
||||||
const createMarks = (min, max, marks_step = 1, labelFormatter = (value) => value) => {
|
const createMarks = (min, max, marks_step = 1, labelFormatter = (value) => value) => {
|
||||||
const marks = [];
|
const marks = [];
|
||||||
let current_value = min;
|
let variable = min;
|
||||||
|
|
||||||
for (let i = 0; current_value <= max; i++) {
|
for (let i = 0; variable <= max; i++) {
|
||||||
const fixedValue = parseFloat(current_value.toFixed(10));
|
const fixedValue = parseFloat(variable.toFixed(10));
|
||||||
|
|
||||||
marks.push({ value: fixedValue, label: `${labelFormatter(fixedValue)}` });
|
marks.push({ value: fixedValue, label: `${labelFormatter(fixedValue)}` });
|
||||||
|
|
||||||
current_value += marks_step;
|
variable += marks_step;
|
||||||
current_value = parseFloat(current_value.toFixed(10));
|
variable = parseFloat(variable.toFixed(10));
|
||||||
|
|
||||||
if (i > 1000) {
|
if (i > 1000) {
|
||||||
console.error("Loop limit exceeded (1000 iterations). createMarks()");
|
console.error("Loop limit exceeded (1000 iterations). createMarks()");
|
||||||
|
|||||||
@@ -7,15 +7,15 @@ import { useSliderLogic } from "@logics_configs";
|
|||||||
|
|
||||||
export const Slider = (props) => {
|
export const Slider = (props) => {
|
||||||
const location = props.valueLabelDisplayLocation || "top";
|
const location = props.valueLabelDisplayLocation || "top";
|
||||||
|
|
||||||
const {
|
const {
|
||||||
ui_value,
|
ui_value,
|
||||||
onchangeFunction,
|
onchangeFunction,
|
||||||
onchangeCommittedFunction,
|
onchangeCommittedFunction,
|
||||||
marks
|
marks
|
||||||
} = useSliderLogic({
|
} = useSliderLogic({
|
||||||
current_value: props.current_value,
|
variable: props.variable,
|
||||||
setterFunction: props.setterFunction,
|
setterFunction: props.setterFunction,
|
||||||
|
setter_timing: props.setter_timing,
|
||||||
postUpdateAction: props.postUpdateAction,
|
postUpdateAction: props.postUpdateAction,
|
||||||
min: props.min,
|
min: props.min,
|
||||||
max: props.max,
|
max: props.max,
|
||||||
|
|||||||
@@ -11,8 +11,6 @@ import {
|
|||||||
|
|
||||||
import {
|
import {
|
||||||
useAppearance,
|
useAppearance,
|
||||||
|
|
||||||
useSliderLogic,
|
|
||||||
} from "@logics_configs";
|
} from "@logics_configs";
|
||||||
|
|
||||||
import {
|
import {
|
||||||
@@ -61,7 +59,7 @@ const UiScalingContainer = () => {
|
|||||||
return (
|
return (
|
||||||
<SliderContainer
|
<SliderContainer
|
||||||
label={t("config_page.appearance.ui_size.label") + " (%)"}
|
label={t("config_page.appearance.ui_size.label") + " (%)"}
|
||||||
current_value={currentUiScaling}
|
variable={currentUiScaling.data}
|
||||||
setterFunction={setUiScaling}
|
setterFunction={setUiScaling}
|
||||||
postUpdateAction={asyncUpdateBreakPoint}
|
postUpdateAction={asyncUpdateBreakPoint}
|
||||||
min={40}
|
min={40}
|
||||||
@@ -80,7 +78,7 @@ export const MessageLogUiScalingContainer = () => {
|
|||||||
return (
|
return (
|
||||||
<SliderContainer
|
<SliderContainer
|
||||||
label={t("config_page.appearance.textbox_ui_size.label") + " (%)"}
|
label={t("config_page.appearance.textbox_ui_size.label") + " (%)"}
|
||||||
current_value={currentMessageLogUiScaling}
|
variable={currentMessageLogUiScaling.data}
|
||||||
setterFunction={setMessageLogUiScaling}
|
setterFunction={setMessageLogUiScaling}
|
||||||
min={40}
|
min={40}
|
||||||
max={200}
|
max={200}
|
||||||
@@ -152,7 +150,7 @@ const TransparencyContainer = () => {
|
|||||||
return (
|
return (
|
||||||
<SliderContainer
|
<SliderContainer
|
||||||
label={t("config_page.appearance.transparency.label") + " (%)"}
|
label={t("config_page.appearance.transparency.label") + " (%)"}
|
||||||
current_value={currentTransparency}
|
variable={currentTransparency.data}
|
||||||
setterFunction={setTransparency}
|
setterFunction={setTransparency}
|
||||||
min={40}
|
min={40}
|
||||||
max={100}
|
max={100}
|
||||||
|
|||||||
@@ -476,7 +476,7 @@ export const MicAvgLogprobContainer = () => {
|
|||||||
<SliderContainer
|
<SliderContainer
|
||||||
label="Mic Avg Logprob"
|
label="Mic Avg Logprob"
|
||||||
desc="Default: -0.8"
|
desc="Default: -0.8"
|
||||||
current_value={currentMicAvgLogprob}
|
variable={currentMicAvgLogprob.data}
|
||||||
setterFunction={setMicAvgLogprob}
|
setterFunction={setMicAvgLogprob}
|
||||||
min={-2}
|
min={-2}
|
||||||
max={0}
|
max={0}
|
||||||
@@ -494,7 +494,7 @@ export const MicNoSpeechProbContainer = () => {
|
|||||||
<SliderContainer
|
<SliderContainer
|
||||||
label="Mic No Speech Prob"
|
label="Mic No Speech Prob"
|
||||||
desc="Default: 0.6"
|
desc="Default: 0.6"
|
||||||
current_value={currentMicNoSpeechProb}
|
variable={currentMicNoSpeechProb.data}
|
||||||
setterFunction={setMicNoSpeechProb}
|
setterFunction={setMicNoSpeechProb}
|
||||||
min={0}
|
min={0}
|
||||||
max={1}
|
max={1}
|
||||||
@@ -511,7 +511,7 @@ export const SpeakerAvgLogprobContainer = () => {
|
|||||||
<SliderContainer
|
<SliderContainer
|
||||||
label="Speaker Avg Logprob"
|
label="Speaker Avg Logprob"
|
||||||
desc="Default: -0.8"
|
desc="Default: -0.8"
|
||||||
current_value={currentSpeakerAvgLogprob}
|
variable={currentSpeakerAvgLogprob.data}
|
||||||
setterFunction={setSpeakerAvgLogprob}
|
setterFunction={setSpeakerAvgLogprob}
|
||||||
min={-2}
|
min={-2}
|
||||||
max={0}
|
max={0}
|
||||||
@@ -529,7 +529,7 @@ export const SpeakerNoSpeechProbContainer = () => {
|
|||||||
<SliderContainer
|
<SliderContainer
|
||||||
label="Speaker No Speech Prob"
|
label="Speaker No Speech Prob"
|
||||||
desc="Default: 0.6"
|
desc="Default: 0.6"
|
||||||
current_value={currentSpeakerNoSpeechProb}
|
variable={currentSpeakerNoSpeechProb.data}
|
||||||
setterFunction={setSpeakerNoSpeechProb}
|
setterFunction={setSpeakerNoSpeechProb}
|
||||||
min={0}
|
min={0}
|
||||||
max={1}
|
max={1}
|
||||||
|
|||||||
@@ -25,7 +25,6 @@ import TriangleSvg from "@images/triangle.svg?react";
|
|||||||
import { randomIntMinMax } from "@utils";
|
import { randomIntMinMax } from "@utils";
|
||||||
|
|
||||||
export const Vr = () => {
|
export const Vr = () => {
|
||||||
return null;
|
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
const [is_opened_small_settings, setIsOpenedSmallSettings] = useState(true);
|
const [is_opened_small_settings, setIsOpenedSmallSettings] = useState(true);
|
||||||
const toggleIsOpenedSmallSettings = () => {
|
const toggleIsOpenedSmallSettings = () => {
|
||||||
@@ -64,7 +63,7 @@ export const Vr = () => {
|
|||||||
ui_configs={ui_configs.overlay_small_log}
|
ui_configs={ui_configs.overlay_small_log}
|
||||||
default_ui_configs={ui_configs.overlay_small_log_default_settings}
|
default_ui_configs={ui_configs.overlay_small_log_default_settings}
|
||||||
current_overlay_settings={currentOverlaySmallLogSettings.data}
|
current_overlay_settings={currentOverlaySmallLogSettings.data}
|
||||||
set_overlay_settings={setOverlaySmallLogSettings}
|
setOverlaySettings={setOverlaySmallLogSettings}
|
||||||
current_is_enabled_overlay={currentIsEnabledOverlaySmallLog}
|
current_is_enabled_overlay={currentIsEnabledOverlaySmallLog}
|
||||||
toggle_is_enabled_overlay={toggleIsEnabledOverlaySmallLog}
|
toggle_is_enabled_overlay={toggleIsEnabledOverlaySmallLog}
|
||||||
/>
|
/>
|
||||||
@@ -74,7 +73,7 @@ export const Vr = () => {
|
|||||||
ui_configs={ui_configs.overlay_large_log}
|
ui_configs={ui_configs.overlay_large_log}
|
||||||
default_ui_configs={ui_configs.overlay_large_log_default_settings}
|
default_ui_configs={ui_configs.overlay_large_log_default_settings}
|
||||||
current_overlay_settings={currentOverlayLargeLogSettings.data}
|
current_overlay_settings={currentOverlayLargeLogSettings.data}
|
||||||
set_overlay_settings={setOverlayLargeLogSettings}
|
setOverlaySettings={setOverlayLargeLogSettings}
|
||||||
current_is_enabled_overlay={currentIsEnabledOverlayLargeLog}
|
current_is_enabled_overlay={currentIsEnabledOverlayLargeLog}
|
||||||
toggle_is_enabled_overlay={toggleIsEnabledOverlayLargeLog}
|
toggle_is_enabled_overlay={toggleIsEnabledOverlayLargeLog}
|
||||||
/>
|
/>
|
||||||
@@ -93,21 +92,21 @@ export const Vr = () => {
|
|||||||
|
|
||||||
const OverlaySettingsContainer = ({
|
const OverlaySettingsContainer = ({
|
||||||
current_overlay_settings,
|
current_overlay_settings,
|
||||||
set_overlay_settings,
|
setOverlaySettings,
|
||||||
current_is_enabled_overlay,
|
current_is_enabled_overlay,
|
||||||
toggle_is_enabled_overlay,
|
toggle_is_enabled_overlay,
|
||||||
ui_configs,
|
ui_configs,
|
||||||
default_ui_configs,
|
default_ui_configs,
|
||||||
id
|
id
|
||||||
}) => {
|
}) => {
|
||||||
|
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
|
const [settings, setSettings] = useState(current_overlay_settings);
|
||||||
|
const [timeout_id, setTimeoutId] = useState(null);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
setSettings(current_overlay_settings);
|
setSettings(current_overlay_settings);
|
||||||
}, [current_overlay_settings]);
|
}, [current_overlay_settings]);
|
||||||
|
|
||||||
const [settings, setSettings] = useState(current_overlay_settings);
|
|
||||||
const [timeout_id, setTimeoutId] = useState(null);
|
|
||||||
|
|
||||||
const [is_opened_position_controller, setIsOpenedPositionController] = useState(true);
|
const [is_opened_position_controller, setIsOpenedPositionController] = useState(true);
|
||||||
const togglePositionRotationController = () => {
|
const togglePositionRotationController = () => {
|
||||||
@@ -119,17 +118,17 @@ const OverlaySettingsContainer = ({
|
|||||||
|
|
||||||
if (timeout_id) clearTimeout(timeout_id);
|
if (timeout_id) clearTimeout(timeout_id);
|
||||||
|
|
||||||
const newTimeoutId = setTimeout(() => {
|
const new_timeout_id = setTimeout(() => {
|
||||||
const new_data = { ...settings, [key]: value };
|
const new_data = { ...settings, [key]: value };
|
||||||
set_overlay_settings(new_data);
|
setOverlaySettings(new_data);
|
||||||
}, 50);
|
}, 50);
|
||||||
|
|
||||||
setTimeoutId(newTimeoutId);
|
setTimeoutId(new_timeout_id);
|
||||||
};
|
};
|
||||||
|
|
||||||
const selectFunction = (key, value) => {
|
const selectFunction = (key, value) => {
|
||||||
const new_data = { ...settings, [key]: value };
|
const new_data = { ...settings, [key]: value };
|
||||||
set_overlay_settings(new_data);
|
setOverlaySettings(new_data);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@@ -235,7 +234,8 @@ export const PositionControls = ({ settings, onchangeFunction, selectFunction, u
|
|||||||
step={ui_configs.x_pos.step}
|
step={ui_configs.x_pos.step}
|
||||||
min={ui_configs.x_pos.min}
|
min={ui_configs.x_pos.min}
|
||||||
max={ui_configs.x_pos.max}
|
max={ui_configs.x_pos.max}
|
||||||
onchangeFunction={(value) => onchangeFunction("x_pos", value)}
|
setterFunction={(value) => onchangeFunction("x_pos", value)}
|
||||||
|
setter_timing="on_change"
|
||||||
valueLabelDisplay={x_variable_display}
|
valueLabelDisplay={x_variable_display}
|
||||||
valueLabelDisplayLocation="top"
|
valueLabelDisplayLocation="top"
|
||||||
/>
|
/>
|
||||||
@@ -260,7 +260,8 @@ export const PositionControls = ({ settings, onchangeFunction, selectFunction, u
|
|||||||
step={ui_configs.y_pos.step}
|
step={ui_configs.y_pos.step}
|
||||||
min={ui_configs.y_pos.min}
|
min={ui_configs.y_pos.min}
|
||||||
max={ui_configs.y_pos.max}
|
max={ui_configs.y_pos.max}
|
||||||
onchangeFunction={(value) => onchangeFunction("y_pos", value)}
|
setterFunction={(value) => onchangeFunction("y_pos", value)}
|
||||||
|
setter_timing="on_change"
|
||||||
orientation="vertical"
|
orientation="vertical"
|
||||||
valueLabelDisplay={y_variable_display}
|
valueLabelDisplay={y_variable_display}
|
||||||
valueLabelDisplayLocation="right"
|
valueLabelDisplayLocation="right"
|
||||||
@@ -286,7 +287,8 @@ export const PositionControls = ({ settings, onchangeFunction, selectFunction, u
|
|||||||
step={ui_configs.z_pos.step}
|
step={ui_configs.z_pos.step}
|
||||||
min={ui_configs.z_pos.min}
|
min={ui_configs.z_pos.min}
|
||||||
max={ui_configs.z_pos.max}
|
max={ui_configs.z_pos.max}
|
||||||
onchangeFunction={(value) => onchangeFunction("z_pos", value)}
|
setterFunction={(value) => onchangeFunction("z_pos", value)}
|
||||||
|
setter_timing="on_change"
|
||||||
orientation="vertical"
|
orientation="vertical"
|
||||||
valueLabelDisplay={z_variable_display}
|
valueLabelDisplay={z_variable_display}
|
||||||
valueLabelDisplayLocation="left"
|
valueLabelDisplayLocation="left"
|
||||||
@@ -345,7 +347,8 @@ export const RotationControls = ({ settings, onchangeFunction, selectFunction, u
|
|||||||
step={ui_configs.x_rotation.step}
|
step={ui_configs.x_rotation.step}
|
||||||
min={ui_configs.x_rotation.min}
|
min={ui_configs.x_rotation.min}
|
||||||
max={ui_configs.x_rotation.max}
|
max={ui_configs.x_rotation.max}
|
||||||
onchangeFunction={(value) => onchangeFunction("x_rotation", -value)}
|
setterFunction={(value) => onchangeFunction("x_rotation", -value)}
|
||||||
|
setter_timing="on_change"
|
||||||
orientation="vertical"
|
orientation="vertical"
|
||||||
valueLabelDisplay={x_variable_display}
|
valueLabelDisplay={x_variable_display}
|
||||||
valueLabelDisplayLocation="right"
|
valueLabelDisplayLocation="right"
|
||||||
@@ -371,7 +374,8 @@ export const RotationControls = ({ settings, onchangeFunction, selectFunction, u
|
|||||||
step={ui_configs.y_rotation.step}
|
step={ui_configs.y_rotation.step}
|
||||||
min={ui_configs.y_rotation.min}
|
min={ui_configs.y_rotation.min}
|
||||||
max={ui_configs.y_rotation.max}
|
max={ui_configs.y_rotation.max}
|
||||||
onchangeFunction={(value) => onchangeFunction("y_rotation", value)}
|
setterFunction={(value) => onchangeFunction("y_rotation", value)}
|
||||||
|
setter_timing="on_change"
|
||||||
valueLabelDisplay={y_variable_display}
|
valueLabelDisplay={y_variable_display}
|
||||||
valueLabelDisplayLocation="top"
|
valueLabelDisplayLocation="top"
|
||||||
/>
|
/>
|
||||||
@@ -396,7 +400,8 @@ export const RotationControls = ({ settings, onchangeFunction, selectFunction, u
|
|||||||
step={ui_configs.z_rotation.step}
|
step={ui_configs.z_rotation.step}
|
||||||
min={ui_configs.z_rotation.min}
|
min={ui_configs.z_rotation.min}
|
||||||
max={ui_configs.z_rotation.max}
|
max={ui_configs.z_rotation.max}
|
||||||
onchangeFunction={(value) => onchangeFunction("z_rotation", value)}
|
setterFunction={(value) => onchangeFunction("z_rotation", value)}
|
||||||
|
setter_timing="on_change"
|
||||||
orientation="vertical"
|
orientation="vertical"
|
||||||
valueLabelDisplay={z_variable_display}
|
valueLabelDisplay={z_variable_display}
|
||||||
valueLabelDisplayLocation="left"
|
valueLabelDisplayLocation="left"
|
||||||
@@ -464,7 +469,8 @@ const OtherControls = ({settings, onchangeFunction, ui_configs}) => {
|
|||||||
step={5}
|
step={5}
|
||||||
min={10}
|
min={10}
|
||||||
max={100}
|
max={100}
|
||||||
onchangeFunction={(value) => onchangeFunction("opacity", value / 100)}
|
setterFunction={(value) => onchangeFunction("opacity", value / 100)}
|
||||||
|
setter_timing="on_change"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div className={styles.other_controls_wrapper}>
|
<div className={styles.other_controls_wrapper}>
|
||||||
@@ -479,7 +485,8 @@ const OtherControls = ({settings, onchangeFunction, ui_configs}) => {
|
|||||||
step={ui_configs.ui_scaling.step}
|
step={ui_configs.ui_scaling.step}
|
||||||
min={ui_configs.ui_scaling.min}
|
min={ui_configs.ui_scaling.min}
|
||||||
max={ui_configs.ui_scaling.max}
|
max={ui_configs.ui_scaling.max}
|
||||||
onchangeFunction={(value) => onchangeFunction("ui_scaling", value / 100)}
|
setterFunction={(value) => onchangeFunction("ui_scaling", value / 100)}
|
||||||
|
setter_timing="on_change"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div className={styles.other_controls_wrapper}>
|
<div className={styles.other_controls_wrapper}>
|
||||||
@@ -492,7 +499,8 @@ const OtherControls = ({settings, onchangeFunction, ui_configs}) => {
|
|||||||
step={1}
|
step={1}
|
||||||
min={1}
|
min={1}
|
||||||
max={60}
|
max={60}
|
||||||
onchangeFunction={(value) => onchangeFunction("display_duration", value)}
|
setterFunction={(value) => onchangeFunction("display_duration", value)}
|
||||||
|
setter_timing="on_change"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div className={styles.other_controls_wrapper}>
|
<div className={styles.other_controls_wrapper}>
|
||||||
@@ -505,7 +513,8 @@ const OtherControls = ({settings, onchangeFunction, ui_configs}) => {
|
|||||||
step={1}
|
step={1}
|
||||||
min={0}
|
min={0}
|
||||||
max={5}
|
max={5}
|
||||||
onchangeFunction={(value) => onchangeFunction("fadeout_duration", value)}
|
setterFunction={(value) => onchangeFunction("fadeout_duration", value)}
|
||||||
|
setter_timing="on_change"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Reference in New Issue
Block a user