@vnejs/plugins.views.settings 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/const/events.js +7 -0
- package/const/params.js +43 -0
- package/index.js +9 -0
- package/modules/controller.js +132 -0
- package/modules/view.js +14 -0
- package/package.json +17 -0
- package/view/components/SettingsControls.jsx +22 -0
- package/view/components/SettingsCross.jsx +13 -0
- package/view/components/SettingsExampleText.jsx +41 -0
- package/view/components/SettingsTabContent.jsx +65 -0
- package/view/components/index.js +4 -0
- package/view/index.jsx +42 -0
package/const/events.js
ADDED
package/const/params.js
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
export const TRANSITION = 500;
|
|
2
|
+
export const ZINDEX = 4000;
|
|
3
|
+
export const LOC_LABEL = "settings";
|
|
4
|
+
|
|
5
|
+
export const BACKGROUND = "Menu/save";
|
|
6
|
+
|
|
7
|
+
export const TABS = {};
|
|
8
|
+
|
|
9
|
+
export const VALUE_MAPS = {};
|
|
10
|
+
|
|
11
|
+
export const VIEW_PROPS = {
|
|
12
|
+
screen: { withBackgroundDark: true, withBackgroundBlur: false, transition: TRANSITION, zIndex: ZINDEX },
|
|
13
|
+
|
|
14
|
+
background: { withDark: true, withBlur: false },
|
|
15
|
+
|
|
16
|
+
cross: { position: { bottom: 90, right: 120 }, svg: { size: 60 } },
|
|
17
|
+
|
|
18
|
+
exampleText: { size: 60, height: 300, color: "var(--vne-color-active)" },
|
|
19
|
+
|
|
20
|
+
fieldsGap: 48,
|
|
21
|
+
|
|
22
|
+
fieldProps: {
|
|
23
|
+
widthTitle: 1440,
|
|
24
|
+
width: 3120,
|
|
25
|
+
|
|
26
|
+
sizeTitle: 96,
|
|
27
|
+
sizeText: 72,
|
|
28
|
+
|
|
29
|
+
gapBetweenItems: 48,
|
|
30
|
+
gapBetweenTitleAndContent: 120,
|
|
31
|
+
gapBetweenInnerItems: 120,
|
|
32
|
+
|
|
33
|
+
rangeHeight: 24,
|
|
34
|
+
|
|
35
|
+
widthInnerLeft: 960,
|
|
36
|
+
widthInnerRight: 240,
|
|
37
|
+
},
|
|
38
|
+
|
|
39
|
+
controls: {
|
|
40
|
+
position: { top: 90, left: 120 },
|
|
41
|
+
props: { textWidth: 660, wrapWidth: 3600, flexGap: 36, flexWithWrap: false, textSize: 96, textAlign: "center" },
|
|
42
|
+
},
|
|
43
|
+
};
|
package/index.js
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { regPlugin } from "@vnejs/shared";
|
|
2
|
+
|
|
3
|
+
import { SUBSCRIBE_EVENTS } from "./const/events";
|
|
4
|
+
import * as params from "./const/params";
|
|
5
|
+
|
|
6
|
+
import { SettingsController } from "./modules/controller";
|
|
7
|
+
import { SettingsView } from "./modules/view";
|
|
8
|
+
|
|
9
|
+
regPlugin("SETTINGS_VIEW", { events: SUBSCRIBE_EVENTS, params }, [SettingsController, SettingsView]);
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
import { ModuleController } from "@vnejs/module.components";
|
|
2
|
+
|
|
3
|
+
const filterTabsToShow = ({ showInSettings = false }) => Boolean(showInSettings);
|
|
4
|
+
|
|
5
|
+
export class SettingsController extends ModuleController {
|
|
6
|
+
name = "settings.controller";
|
|
7
|
+
|
|
8
|
+
emitHide = () => this.emit(this.EVENTS.SETTINGS_VIEW.HIDE);
|
|
9
|
+
|
|
10
|
+
onArrowLeft = () => {
|
|
11
|
+
const { currentTab, currentItemInner, currentItem } = this.state;
|
|
12
|
+
|
|
13
|
+
if (currentItem === null) return;
|
|
14
|
+
|
|
15
|
+
const { settingKey = "", step = 0, min = 0, type = "", options = [] } = this.tabs[currentTab].fields[currentItem];
|
|
16
|
+
|
|
17
|
+
if (options?.length) {
|
|
18
|
+
const newValue = (currentItemInner === 0 ? options.length : currentItemInner) - 1;
|
|
19
|
+
|
|
20
|
+
return this.updateStateAndViewFast({ currentItemInner: newValue });
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
if (type === "toggle") {
|
|
24
|
+
return this.shared.settings[settingKey] === true && this.emit(this.EVENTS.SETTINGS.SET, { name: settingKey, value: false });
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
if (type === "range") {
|
|
28
|
+
const newValue = Number(Number(this.shared.settings[settingKey] - step).toFixed(4));
|
|
29
|
+
|
|
30
|
+
return newValue >= min && this.emit(this.EVENTS.SETTINGS.SET, { name: settingKey, value: newValue });
|
|
31
|
+
}
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
onArrowRight = () => {
|
|
35
|
+
const { currentTab, currentItemInner, currentItem } = this.state;
|
|
36
|
+
|
|
37
|
+
if (currentItem === null) return;
|
|
38
|
+
|
|
39
|
+
const { settingKey = "", step = 0, max = 0, type = "", options = [] } = this.tabs[currentTab].fields[currentItem];
|
|
40
|
+
|
|
41
|
+
if (options?.length) {
|
|
42
|
+
return this.updateStateAndViewFast({ currentItemInner: (currentItemInner + 1) % options.length });
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
if (type === "toggle") {
|
|
46
|
+
return this.shared.settings[settingKey] === false && this.emit(this.EVENTS.SETTINGS.SET, { name: settingKey, value: true });
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
if (type === "range") {
|
|
50
|
+
const newValue = Number(Number(this.shared.settings[settingKey] + step).toFixed(4));
|
|
51
|
+
|
|
52
|
+
return newValue <= max && this.emit(this.EVENTS.SETTINGS.SET, { name: settingKey, value: newValue });
|
|
53
|
+
}
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
onPrevTab = () => this.emit(this.EVENTS.SETTINGS_VIEW.TAB_SET, { tab: (this.state.currentTab === 0 ? this.tabs.length : this.state.currentTab) - 1 });
|
|
57
|
+
onNextTab = () => this.emit(this.EVENTS.SETTINGS_VIEW.TAB_SET, { tab: (this.state.currentTab + 1) % this.tabs.length });
|
|
58
|
+
|
|
59
|
+
onInteract = () => {
|
|
60
|
+
const { currentTab, currentItemInner, currentItem } = this.state;
|
|
61
|
+
|
|
62
|
+
if (currentItem === null) return;
|
|
63
|
+
|
|
64
|
+
const { settingKey = "", type = "", options = [] } = this.tabs[currentTab].fields[currentItem];
|
|
65
|
+
|
|
66
|
+
if (options?.length)
|
|
67
|
+
return options[currentItemInner].action
|
|
68
|
+
? this.PARAMS.SETTINGS_VIEW.ACTIONS[options[currentItemInner].action](this, this.state.locs)
|
|
69
|
+
: this.emit(this.EVENTS.SETTINGS.SET, { name: settingKey, value: options[currentItemInner].value });
|
|
70
|
+
|
|
71
|
+
if (type === "toggle") return this.emit(this.EVENTS.SETTINGS.SET, { name: settingKey, value: !this.shared.settings[settingKey] });
|
|
72
|
+
};
|
|
73
|
+
|
|
74
|
+
bgName = this.PARAMS.SETTINGS_VIEW.BACKGROUND;
|
|
75
|
+
|
|
76
|
+
updateEvent = this.EVENTS.SETTINGS_VIEW.UPDATE;
|
|
77
|
+
controls = {
|
|
78
|
+
[this.CONST.CONTROLS.BUTTONS.BACK]: this.emitHide,
|
|
79
|
+
[this.CONST.CONTROLS.BUTTONS.MENU]: this.emitHide,
|
|
80
|
+
[this.CONST.CONTROLS.BUTTONS.GAMEMENU]: this.emitHide,
|
|
81
|
+
[this.CONST.CONTROLS.BUTTONS.INTERACT]: this.onInteract,
|
|
82
|
+
[this.CONST.CONTROLS.BUTTONS.ACCEPT]: this.onInteract,
|
|
83
|
+
[this.CONST.CONTROLS.BUTTONS.TAB_PREV]: this.onPrevTab,
|
|
84
|
+
[this.CONST.CONTROLS.BUTTONS.TAB_NEXT]: this.onNextTab,
|
|
85
|
+
[this.CONST.CONTROLS.BUTTONS.ARROW_LEFT]: this.onArrowLeft,
|
|
86
|
+
[this.CONST.CONTROLS.BUTTONS.ARROW_RIGHT]: this.onArrowRight,
|
|
87
|
+
[this.CONST.CONTROLS.BUTTONS.ARROW_UP]: this.decCurrentItem,
|
|
88
|
+
[this.CONST.CONTROLS.BUTTONS.ARROW_BOTTOM]: this.incCurrentItem,
|
|
89
|
+
};
|
|
90
|
+
controlsIndex = this.PARAMS.SETTINGS_VIEW.ZINDEX;
|
|
91
|
+
|
|
92
|
+
subscribe = () => {
|
|
93
|
+
this.on(this.EVENTS.SETTINGS_VIEW.SHOW, this.onShow);
|
|
94
|
+
this.on(this.EVENTS.SETTINGS_VIEW.HIDE, this.onHide);
|
|
95
|
+
this.on(this.EVENTS.SETTINGS_VIEW.TAB_SET, this.onTabSet);
|
|
96
|
+
this.on(this.EVENTS.SETTINGS_VIEW.PRELOAD, this.loadBgMedia);
|
|
97
|
+
|
|
98
|
+
this.on(this.EVENTS.SETTINGS.CHANGED, this.onSettingChange);
|
|
99
|
+
|
|
100
|
+
this.on(this.EVENTS.LOCS.CHANGED, this.updateViewFast);
|
|
101
|
+
|
|
102
|
+
this.on(this.EVENTS.STATE.SET, this.onHide);
|
|
103
|
+
this.on(this.EVENTS.STATE.CLEAR, this.onHide);
|
|
104
|
+
|
|
105
|
+
this.on(this.EVENTS.MEMORY.CLEARED, this.onMemoryCleared);
|
|
106
|
+
};
|
|
107
|
+
init = () => {
|
|
108
|
+
this.tabs = Object.values(this.PARAMS.SETTINGS_VIEW.TABS).filter(filterTabsToShow);
|
|
109
|
+
|
|
110
|
+
this.setMaxCurrentItemByTabIndex(0);
|
|
111
|
+
|
|
112
|
+
return this.emit(this.EVENTS.SETTINGS.INIT);
|
|
113
|
+
};
|
|
114
|
+
|
|
115
|
+
beforeShow = async () => this.updateState({ bgSrc: (await this.loadBgMedia()).src, tabs: this.tabs, currentTab: 0 });
|
|
116
|
+
afterHide = () => this.setDefaultState();
|
|
117
|
+
|
|
118
|
+
onSettingChange = () => this.isReady && this.state.isShow && this.updateViewFast();
|
|
119
|
+
|
|
120
|
+
onTabSet = ({ tab = 0 } = {}) => {
|
|
121
|
+
this.setMaxCurrentItemByTabIndex(tab);
|
|
122
|
+
this.unsetCurrentItem();
|
|
123
|
+
|
|
124
|
+
return this.updateStateAndViewFast({ currentTab: tab, currentItemInner: 0 });
|
|
125
|
+
};
|
|
126
|
+
|
|
127
|
+
onMemoryCleared = async () => this.updateStateAndViewFast({ bgSrc: (await this.loadBgMedia()).src });
|
|
128
|
+
|
|
129
|
+
setMaxCurrentItemByTabIndex = (i) => {
|
|
130
|
+
this.maxCurrentItem = this.tabs[i].fields.length - 1;
|
|
131
|
+
};
|
|
132
|
+
}
|
package/modules/view.js
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { ModuleView } from "@vnejs/module.components";
|
|
2
|
+
|
|
3
|
+
import { render } from "../view";
|
|
4
|
+
|
|
5
|
+
export class SettingsView extends ModuleView {
|
|
6
|
+
name = "settings.view";
|
|
7
|
+
|
|
8
|
+
locLabel = this.PARAMS.SETTINGS_VIEW.LOC_LABEL;
|
|
9
|
+
animationTime = this.PARAMS.SETTINGS_VIEW.TRANSITION;
|
|
10
|
+
updateEvent = this.EVENTS.SETTINGS_VIEW.UPDATE;
|
|
11
|
+
|
|
12
|
+
renderFunc = render;
|
|
13
|
+
updateHandler = this.onUpdateStoreComponent;
|
|
14
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@vnejs/plugins.views.settings",
|
|
3
|
+
"version": "0.1.1",
|
|
4
|
+
"main": "index.js",
|
|
5
|
+
"scripts": {
|
|
6
|
+
"test": "echo \"Error: no test specified\" && exit 1",
|
|
7
|
+
"publish:major:plugin": "npm run publish:major",
|
|
8
|
+
"publish:minor:plugin": "npm run publish:minor",
|
|
9
|
+
"publish:patch:plugin": "npm run publish:patch",
|
|
10
|
+
"publish:major": "npm version major && npm publish --access public",
|
|
11
|
+
"publish:minor": "npm version minor && npm publish --access public",
|
|
12
|
+
"publish:patch": "npm version patch && npm publish --access public"
|
|
13
|
+
},
|
|
14
|
+
"author": "",
|
|
15
|
+
"license": "ISC",
|
|
16
|
+
"description": ""
|
|
17
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { useCallback, useEffect, useMemo, useState } from "react";
|
|
2
|
+
|
|
3
|
+
import { PositionBox, TextControls } from "@vnejs/uis.react";
|
|
4
|
+
|
|
5
|
+
export const SettingsControls = ({ tabs = [], locs = {}, currentTab = 0, ...props } = {}) => {
|
|
6
|
+
const [texts, setTexts] = useState();
|
|
7
|
+
|
|
8
|
+
useEffect(() => void setTexts(Object.values(tabs).map(({ titleLocKey }, i) => ({ value: i, text: locs[titleLocKey] }))), [locs, tabs]);
|
|
9
|
+
|
|
10
|
+
const onClick = useCallback((tab) => props.emit(props.EVENTS.SETTINGS_VIEW.TAB_SET, { tab }), []);
|
|
11
|
+
|
|
12
|
+
const propsControls = useMemo(
|
|
13
|
+
() => ({ ...props.PARAMS.SETTINGS_VIEW.VIEW_PROPS.controls.props, selectedIndex: currentTab, texts, onClick }),
|
|
14
|
+
[currentTab, texts],
|
|
15
|
+
);
|
|
16
|
+
|
|
17
|
+
return (
|
|
18
|
+
<PositionBox {...props.PARAMS.SETTINGS_VIEW.VIEW_PROPS.controls.position}>
|
|
19
|
+
<TextControls {...propsControls} />
|
|
20
|
+
</PositionBox>
|
|
21
|
+
);
|
|
22
|
+
};
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { useMemo } from "react";
|
|
2
|
+
|
|
3
|
+
import { PositionBox, Svg } from "@vnejs/uis.react";
|
|
4
|
+
|
|
5
|
+
export const SettingsCross = (props = {}) => {
|
|
6
|
+
const propsCross = useMemo(() => ({ ...props.PARAMS.SETTINGS_VIEW.VIEW_PROPS.cross.svg, onClick: () => props.emit(props.EVENTS.SETTINGS_VIEW.HIDE) }), []);
|
|
7
|
+
|
|
8
|
+
return (
|
|
9
|
+
<PositionBox {...props.PARAMS.SETTINGS_VIEW.VIEW_PROPS.cross.position}>
|
|
10
|
+
<Svg.Cross {...propsCross} />
|
|
11
|
+
</PositionBox>
|
|
12
|
+
);
|
|
13
|
+
};
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { useEffect, useMemo, useState } from "react";
|
|
2
|
+
|
|
3
|
+
import { SmoothText } from "@vnejs/uis.react";
|
|
4
|
+
|
|
5
|
+
const EMPTY_ARRAY = [];
|
|
6
|
+
|
|
7
|
+
const mapTokens = (token) => ({ token });
|
|
8
|
+
|
|
9
|
+
export const SettingsExampleText = ({ isShow = false, locs = {}, ...props } = {}) => {
|
|
10
|
+
const [tokens, setTokens] = useState(EMPTY_ARRAY);
|
|
11
|
+
|
|
12
|
+
const isForce = Boolean(props.shared.textNoAnimationSources.length);
|
|
13
|
+
|
|
14
|
+
const text = useMemo(() => locs["fields.text.example"] ?? "", [locs]);
|
|
15
|
+
|
|
16
|
+
useEffect(() => {
|
|
17
|
+
if (!isShow) return;
|
|
18
|
+
|
|
19
|
+
setTokens([...text].map(mapTokens));
|
|
20
|
+
}, [isShow, text]);
|
|
21
|
+
|
|
22
|
+
useEffect(() => {
|
|
23
|
+
if (isShow || isForce) return;
|
|
24
|
+
|
|
25
|
+
const tm = setTimeout(() => setTokens(EMPTY_ARRAY), props.PARAMS.SETTINGS_VIEW.TRANSITION);
|
|
26
|
+
|
|
27
|
+
return () => clearTimeout(tm);
|
|
28
|
+
}, [isShow]);
|
|
29
|
+
|
|
30
|
+
return (
|
|
31
|
+
<SmoothText
|
|
32
|
+
tokens={tokens}
|
|
33
|
+
isForce={isForce}
|
|
34
|
+
charDelay={props.PARAMS.TEXT.TOKEN_RENDER_DELAY / props.shared.settings[props.SETTINGS.TEXT.TOKEN_RENDER_SPEED]}
|
|
35
|
+
size={props.PARAMS.SETTINGS_VIEW.VIEW_PROPS.exampleText.size}
|
|
36
|
+
color={props.PARAMS.SETTINGS_VIEW.VIEW_PROPS.exampleText.color}
|
|
37
|
+
height={props.PARAMS.SETTINGS_VIEW.VIEW_PROPS.exampleText.height}
|
|
38
|
+
scrollBarTextSize={props.shared.settings[props.SETTINGS.TEXTSIZE.VALUE]}
|
|
39
|
+
/>
|
|
40
|
+
);
|
|
41
|
+
};
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { useCallback } from "react";
|
|
2
|
+
|
|
3
|
+
import { PositionBox, Settings, Flex } from "@vnejs/uis.react";
|
|
4
|
+
|
|
5
|
+
import { SettingsExampleText } from "./SettingsExampleText";
|
|
6
|
+
|
|
7
|
+
export const SettingsTabContent = ({ isShow = false, isForce = false, locs = {}, fields = [], ...props } = {}) => {
|
|
8
|
+
const mapFields = useCallback(
|
|
9
|
+
({ locKey = "", type = "", settingKey = "", options = [], titleToggledLocKey = "", titleUntoggledLocKey = "", valueMap = "", ...fieldProps } = {}) => {
|
|
10
|
+
const onChange = (value) => props.emit(props.EVENTS.SETTINGS.SET, { name: settingKey, value });
|
|
11
|
+
|
|
12
|
+
const titles = { title: locs[locKey], titleToggled: locs[titleToggledLocKey], titleUntoggled: locs[titleUntoggledLocKey] };
|
|
13
|
+
const valueMapReal = valueMap ? props.PARAMS.SETTINGS_VIEW.VALUE_MAPS[valueMap] : null;
|
|
14
|
+
|
|
15
|
+
const optionsReal = options.map((option) => {
|
|
16
|
+
const result = { ...option };
|
|
17
|
+
|
|
18
|
+
if (option.locKey) {
|
|
19
|
+
delete result.locKey;
|
|
20
|
+
result.text = locs[option.locKey];
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
if (option.action) {
|
|
24
|
+
delete result.action;
|
|
25
|
+
result.onClick = () => props.PARAMS.SETTINGS_VIEW.ACTIONS[option.action](props, locs);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
return result;
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
return { ...titles, value: props.shared.settings[settingKey], type, onChange, props: fieldProps, options: optionsReal, valueMap: valueMapReal };
|
|
32
|
+
},
|
|
33
|
+
[locs],
|
|
34
|
+
);
|
|
35
|
+
|
|
36
|
+
return (
|
|
37
|
+
<PositionBox
|
|
38
|
+
isCentered={true}
|
|
39
|
+
opacity={isShow ? 1 : 0}
|
|
40
|
+
transition={isForce ? 0 : props.PARAMS.SETTINGS_VIEW.TRANSITION}
|
|
41
|
+
>
|
|
42
|
+
<Flex
|
|
43
|
+
direction={Flex.DIRECTION.COLUMN}
|
|
44
|
+
gap={props.PARAMS.SETTINGS_VIEW.VIEW_PROPS.fieldsGap}
|
|
45
|
+
>
|
|
46
|
+
<Settings
|
|
47
|
+
selectedIndex={isShow ? props.currentItem : -1}
|
|
48
|
+
selectedIndexInner={isShow ? props.currentItemInner : -1}
|
|
49
|
+
transition={isForce ? 0 : props.PARAMS.SETTINGS_VIEW.TRANSITION}
|
|
50
|
+
settings={fields.map(mapFields)}
|
|
51
|
+
{...props.PARAMS.SETTINGS_VIEW.VIEW_PROPS.fieldProps}
|
|
52
|
+
/>
|
|
53
|
+
|
|
54
|
+
{props.showTextExample && (
|
|
55
|
+
<SettingsExampleText
|
|
56
|
+
{...props}
|
|
57
|
+
isShow={isShow}
|
|
58
|
+
isForce={isForce}
|
|
59
|
+
text={locs["fields.text.example"] || ""}
|
|
60
|
+
/>
|
|
61
|
+
)}
|
|
62
|
+
</Flex>
|
|
63
|
+
</PositionBox>
|
|
64
|
+
);
|
|
65
|
+
};
|
package/view/index.jsx
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { useCallback, useEffect, useMemo, useState } from "react";
|
|
2
|
+
import { createRoot } from "react-dom/client";
|
|
3
|
+
|
|
4
|
+
import { Screen } from "@vnejs/uis.react";
|
|
5
|
+
|
|
6
|
+
import { SettingsControls, SettingsCross, SettingsTabContent } from "./components";
|
|
7
|
+
|
|
8
|
+
const Settings = ({ store, onMount, ...props } = {}) => {
|
|
9
|
+
const [state, setState] = useState({});
|
|
10
|
+
|
|
11
|
+
const { isShow = false, isForce = false, bgSrc = "", tabs = [], locs = {}, currentTab = 0, currentItem = null, currentItemInner = null } = state;
|
|
12
|
+
|
|
13
|
+
useEffect(() => store.subscribe(setState), []);
|
|
14
|
+
useEffect(() => void onMount(), []);
|
|
15
|
+
|
|
16
|
+
const propsTab = useMemo(() => ({ ...props, isForce, currentItem, currentItemInner, locs }), [isForce, currentItem, currentItemInner, locs]);
|
|
17
|
+
const propsScreen = useMemo(() => ({ ...props.PARAMS.SETTINGS_VIEW.VIEW_PROPS.screen, isShow, isForce, bgSrc }), [isShow, isForce, bgSrc]);
|
|
18
|
+
const propsControls = useMemo(() => ({ ...props, locs, tabs, currentTab, isForce }), [locs, tabs, currentTab, isForce]);
|
|
19
|
+
|
|
20
|
+
const renderTabContent = useCallback(
|
|
21
|
+
({ fields = [], showTextExample = false } = {}, i) => (
|
|
22
|
+
<SettingsTabContent
|
|
23
|
+
{...propsTab}
|
|
24
|
+
key={i}
|
|
25
|
+
isShow={currentTab === i}
|
|
26
|
+
fields={fields}
|
|
27
|
+
showTextExample={showTextExample}
|
|
28
|
+
/>
|
|
29
|
+
),
|
|
30
|
+
[currentTab, propsTab],
|
|
31
|
+
);
|
|
32
|
+
|
|
33
|
+
return (
|
|
34
|
+
<Screen {...propsScreen}>
|
|
35
|
+
<SettingsCross {...props} />
|
|
36
|
+
<SettingsControls {...propsControls} />
|
|
37
|
+
{Object.values(tabs).map(renderTabContent)}
|
|
38
|
+
</Screen>
|
|
39
|
+
);
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
export const render = (props, root) => createRoot(root).render(<Settings {...props} />);
|