wenay-react2 1.0.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/lib/common/api.d.ts +17 -0
- package/lib/common/api.js +24 -0
- package/lib/common/src/components/Buttons/MiniButton.d.ts +17 -0
- package/lib/common/src/components/Buttons/MiniButton.js +18 -0
- package/lib/common/src/components/Buttons/index.d.ts +1 -0
- package/lib/common/src/components/Buttons/index.js +1 -0
- package/lib/common/src/components/Dnd/DraggableOutlineDiv.d.ts +1 -0
- package/lib/common/src/components/Dnd/DraggableOutlineDiv.js +31 -0
- package/lib/common/src/components/Dnd/RNDFunc.d.ts +13 -0
- package/lib/common/src/components/Dnd/RNDFunc.js +111 -0
- package/lib/common/src/components/Dnd/RNDFunc3.d.ts +81 -0
- package/lib/common/src/components/Dnd/RNDFunc3.js +380 -0
- package/lib/common/src/components/Dnd/Resizable.d.ts +15 -0
- package/lib/common/src/components/Dnd/Resizable.js +36 -0
- package/lib/common/src/components/Dnd/index.d.ts +4 -0
- package/lib/common/src/components/Dnd/index.js +4 -0
- package/lib/common/src/components/Input.d.ts +28 -0
- package/lib/common/src/components/Input.js +30 -0
- package/lib/common/src/components/Menu/RightMenu.d.ts +22 -0
- package/lib/common/src/components/Menu/RightMenu.js +179 -0
- package/lib/common/src/components/Menu/StickerMenu.d.ts +5 -0
- package/lib/common/src/components/Menu/StickerMenu.js +110 -0
- package/lib/common/src/components/Menu/index.d.ts +2 -0
- package/lib/common/src/components/Menu/index.js +2 -0
- package/lib/common/src/components/Modal/LeftModal.d.ts +58 -0
- package/lib/common/src/components/Modal/LeftModal.js +284 -0
- package/lib/common/src/components/Modal/Modal.d.ts +31 -0
- package/lib/common/src/components/Modal/Modal.js +104 -0
- package/lib/common/src/components/Modal/index.d.ts +2 -0
- package/lib/common/src/components/Modal/index.js +2 -0
- package/lib/common/src/components/MyResizeObserver.d.ts +10 -0
- package/lib/common/src/components/MyResizeObserver.js +94 -0
- package/lib/common/src/components/Other.d.ts +9 -0
- package/lib/common/src/components/Other.js +31 -0
- package/lib/common/src/components/Parameters.d.ts +10 -0
- package/lib/common/src/components/Parameters.js +24 -0
- package/lib/common/src/components/ParametersEngine.d.ts +8 -0
- package/lib/common/src/components/ParametersEngine.js +373 -0
- package/lib/common/src/components/index.d.ts +9 -0
- package/lib/common/src/components/index.js +9 -0
- package/lib/common/src/hooks/index.d.ts +3 -0
- package/lib/common/src/hooks/index.js +3 -0
- package/lib/common/src/hooks/useAddDownAnyKey.d.ts +5 -0
- package/lib/common/src/hooks/useAddDownAnyKey.js +22 -0
- package/lib/common/src/hooks/useDraggable.d.ts +15 -0
- package/lib/common/src/hooks/useDraggable.js +134 -0
- package/lib/common/src/hooks/useOutside.d.ts +40 -0
- package/lib/common/src/hooks/useOutside.js +68 -0
- package/lib/common/src/logs/logs.d.ts +163 -0
- package/lib/common/src/logs/logs.js +249 -0
- package/lib/common/src/logs/logs3.d.ts +63 -0
- package/lib/common/src/logs/logs3.js +245 -0
- package/lib/common/src/logs/miniLogs.d.ts +5 -0
- package/lib/common/src/logs/miniLogs.js +51 -0
- package/lib/common/src/menu/menu.d.ts +72 -0
- package/lib/common/src/menu/menu.js +230 -0
- package/lib/common/src/menu/menuMouse.d.ts +21 -0
- package/lib/common/src/menu/menuMouse.js +32 -0
- package/lib/common/src/menu/menuR.d.ts +17 -0
- package/lib/common/src/menu/menuR.js +116 -0
- package/lib/common/src/myChart/1/myChart.d.ts +40 -0
- package/lib/common/src/myChart/1/myChart.js +306 -0
- package/lib/common/src/myChart/1/myChartTest.d.ts +1 -0
- package/lib/common/src/myChart/1/myChartTest.js +45 -0
- package/lib/common/src/myChart/chartEngine/chartEngineReact.d.ts +164 -0
- package/lib/common/src/myChart/chartEngine/chartEngineReact.js +834 -0
- package/lib/common/src/styles/index.d.ts +1 -0
- package/lib/common/src/styles/index.js +1 -0
- package/lib/common/src/styles/styleGrid.d.ts +20 -0
- package/lib/common/src/styles/styleGrid.js +50 -0
- package/lib/common/src/utils/applyTransactionAsyncUpdate.d.ts +42 -0
- package/lib/common/src/utils/applyTransactionAsyncUpdate.js +97 -0
- package/lib/common/src/utils/arrayPromise.d.ts +5 -0
- package/lib/common/src/utils/arrayPromise.js +16 -0
- package/lib/common/src/utils/cache.d.ts +31 -0
- package/lib/common/src/utils/cache.js +119 -0
- package/lib/common/src/utils/index.d.ts +6 -0
- package/lib/common/src/utils/index.js +6 -0
- package/lib/common/src/utils/inputAutoStep.d.ts +4 -0
- package/lib/common/src/utils/inputAutoStep.js +79 -0
- package/lib/common/src/utils/mapMemory.d.ts +26 -0
- package/lib/common/src/utils/mapMemory.js +72 -0
- package/lib/common/src/utils/pageVisibilityContext.d.ts +5 -0
- package/lib/common/src/utils/pageVisibilityContext.js +18 -0
- package/lib/common/updateBy.d.ts +12 -0
- package/lib/common/updateBy.js +88 -0
- package/lib/index.d.ts +1 -0
- package/lib/index.js +3 -0
- package/lib/style/menuRight.css +139 -0
- package/lib/style/style.css +334 -0
- package/lib/tsconfig.json +6 -0
- package/package.json +50 -0
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
|
3
|
+
import { sleepAsync } from 'wenay-common2';
|
|
4
|
+
import { GetModalFuncJSX } from "../Modal";
|
|
5
|
+
import { DivOutsideClick, useDraggable } from "../../hooks";
|
|
6
|
+
import { DraggableOutlineDiv } from "../Dnd";
|
|
7
|
+
export function DropdownMenu({ elements, style, position: initialPosition = 'right', position2: initialPos2 = 'top' }) {
|
|
8
|
+
const [isOpen, setIsOpen] = useState(false);
|
|
9
|
+
const [isFixed, setIsFixed] = useState(false);
|
|
10
|
+
const [select, setSelect] = useState(null);
|
|
11
|
+
const data = useRef({ m1: false, m2: false });
|
|
12
|
+
// Получаем JSX-функции модального окна
|
|
13
|
+
const jsx = useMemo(GetModalFuncJSX, []);
|
|
14
|
+
const jsxRender = useMemo(() => _jsx(jsx.Render, {}), [jsx]);
|
|
15
|
+
const [position, setPosition] = useState(initialPosition);
|
|
16
|
+
const [isTop, setIsTop] = useState(initialPos2 === 'top');
|
|
17
|
+
const positionLast = useRef({ x: 0, y: 0 });
|
|
18
|
+
const handleDragEnd = useCallback((finalPosition) => {
|
|
19
|
+
// Обработка горизонтального смещения
|
|
20
|
+
if (position === 'left') {
|
|
21
|
+
positionLast.current.x += finalPosition.x;
|
|
22
|
+
if (positionLast.current.x > window.innerWidth * 0.6) {
|
|
23
|
+
positionLast.current.x = window.innerWidth - positionLast.current.x;
|
|
24
|
+
setPosition('right');
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
else if (position === 'right') {
|
|
28
|
+
positionLast.current.x -= finalPosition.x;
|
|
29
|
+
if (positionLast.current.x > window.innerWidth * 0.6) {
|
|
30
|
+
positionLast.current.x = window.innerWidth - positionLast.current.x;
|
|
31
|
+
setPosition('left');
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
// Обработка вертикального смещения
|
|
35
|
+
if (isTop) {
|
|
36
|
+
positionLast.current.y += finalPosition.y;
|
|
37
|
+
if (positionLast.current.y > document.documentElement.clientHeight * 0.6) {
|
|
38
|
+
positionLast.current.y = document.documentElement.clientHeight - positionLast.current.y;
|
|
39
|
+
setIsTop(false);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
else {
|
|
43
|
+
positionLast.current.y -= finalPosition.y;
|
|
44
|
+
if (positionLast.current.y > document.documentElement.clientHeight * 0.6) {
|
|
45
|
+
positionLast.current.y = document.documentElement.clientHeight - positionLast.current.y;
|
|
46
|
+
setIsTop(true);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
}, [position, isTop]);
|
|
50
|
+
const { position: pos, dragProps } = useDraggable(0, 0, 50, handleDragEnd, () => { });
|
|
51
|
+
// Обработчики кликов и наведения
|
|
52
|
+
const handleClickOutside = useCallback(() => {
|
|
53
|
+
setIsOpen(false);
|
|
54
|
+
}, []);
|
|
55
|
+
const handleToggle = useCallback(() => {
|
|
56
|
+
setIsFixed((prev) => !prev);
|
|
57
|
+
setIsOpen((prev) => !prev);
|
|
58
|
+
}, []);
|
|
59
|
+
const handleSelect = useCallback((item, index) => {
|
|
60
|
+
jsx.set(item.subMenuContent);
|
|
61
|
+
setSelect(index);
|
|
62
|
+
}, [jsx]);
|
|
63
|
+
const handleContentMouseEnter = useCallback(() => {
|
|
64
|
+
data.current.m1 = true;
|
|
65
|
+
}, []);
|
|
66
|
+
const handleContentMouseLeave = useCallback(async () => {
|
|
67
|
+
data.current.m1 = false;
|
|
68
|
+
await sleepAsync(50);
|
|
69
|
+
if (!data.current.m1 && !data.current.m2) {
|
|
70
|
+
jsx.set(null);
|
|
71
|
+
setSelect(null);
|
|
72
|
+
}
|
|
73
|
+
}, [jsx]);
|
|
74
|
+
const handleSubmenuMouseEnter = useCallback(() => {
|
|
75
|
+
data.current.m2 = true;
|
|
76
|
+
}, []);
|
|
77
|
+
const handleSubmenuMouseLeave = useCallback(async () => {
|
|
78
|
+
data.current.m2 = false;
|
|
79
|
+
await sleepAsync(50);
|
|
80
|
+
if (!data.current.m1 && !data.current.m2) {
|
|
81
|
+
jsx.set(null);
|
|
82
|
+
setSelect(null);
|
|
83
|
+
}
|
|
84
|
+
}, [jsx]);
|
|
85
|
+
// Отрисовка выпадающего меню (dop)
|
|
86
|
+
const dop = (isFixed || isOpen) && (_jsxs("div", { onMouseEnter: () => {
|
|
87
|
+
data.current.m1 = true;
|
|
88
|
+
}, onMouseLeave: () => {
|
|
89
|
+
data.current.m1 = false;
|
|
90
|
+
jsx.set(null);
|
|
91
|
+
setSelect(null);
|
|
92
|
+
}, className: `dropdown-content2 ${!isTop ? 'dropdown-up' : ''}`, style: {
|
|
93
|
+
display: 'flex',
|
|
94
|
+
[position]: 0,
|
|
95
|
+
right: position === 'left' ? 'auto' : 0,
|
|
96
|
+
flexDirection: position === 'left' ? 'row' : 'row-reverse'
|
|
97
|
+
}, children: [_jsx("div", { className: "dropdown-content", onMouseEnter: handleContentMouseEnter, onMouseLeave: handleContentMouseLeave, children: elements.map((item, index) => (_jsx("div", { className: `menu-item ${select === index ? 'force-hover' : ''}`, onMouseEnter: () => handleSelect(item, index), onClick: () => handleSelect(item, index), children: item.label }, index))) }), _jsx("div", { onMouseEnter: handleSubmenuMouseEnter, onMouseLeave: handleSubmenuMouseLeave, children: jsx.JSX ? (_jsx("div", { className: "submenu", style: { width: '40vw', minHeight: '70vh' }, children: jsxRender })) : null })] }));
|
|
98
|
+
// Вычисление смещений
|
|
99
|
+
const computedX = position === 'left'
|
|
100
|
+
? positionLast.current.x + pos.x
|
|
101
|
+
: positionLast.current.x - pos.x;
|
|
102
|
+
const computedY = isTop
|
|
103
|
+
? positionLast.current.y + pos.y
|
|
104
|
+
: positionLast.current.y - pos.y;
|
|
105
|
+
// Вычисление стилей контейнера меню
|
|
106
|
+
const containerStyle = useMemo(() => {
|
|
107
|
+
const computedStyle = {
|
|
108
|
+
...style,
|
|
109
|
+
display: 'flex'
|
|
110
|
+
};
|
|
111
|
+
// Горизонтальное позиционирование
|
|
112
|
+
if (position === 'left') {
|
|
113
|
+
computedStyle.left = Math.max(0, Math.min(computedX, window.innerWidth - 50));
|
|
114
|
+
computedStyle.right = 'auto';
|
|
115
|
+
}
|
|
116
|
+
else {
|
|
117
|
+
computedStyle.right = Math.max(0, Math.min(computedX, window.innerWidth - 50));
|
|
118
|
+
computedStyle.left = 'auto';
|
|
119
|
+
}
|
|
120
|
+
// Вертикальное позиционирование
|
|
121
|
+
if (isTop) {
|
|
122
|
+
computedStyle.top = Math.max(0, Math.min(computedY, window.innerHeight - 50));
|
|
123
|
+
computedStyle.bottom = 'auto';
|
|
124
|
+
}
|
|
125
|
+
else {
|
|
126
|
+
computedStyle.bottom = Math.max(0, Math.min(computedY, window.innerHeight - 50));
|
|
127
|
+
computedStyle.top = 'auto';
|
|
128
|
+
}
|
|
129
|
+
return computedStyle;
|
|
130
|
+
}, [style, position, isTop, computedX, computedY]);
|
|
131
|
+
return (_jsxs(DivOutsideClick, { outsideClick: handleClickOutside, className: `menu-container ${isFixed ? 'activeM' : ''}`, style: containerStyle, onMouseEnter: () => !isFixed && setIsOpen(true), onMouseLeave: () => !isFixed && setIsOpen(false), children: [_jsx("div", { ...dragProps, className: "menu-button", onClick: handleToggle, children: "\u2630" }), dop] }));
|
|
132
|
+
}
|
|
133
|
+
export function MenuRightApi() {
|
|
134
|
+
const elements = [];
|
|
135
|
+
let render = null;
|
|
136
|
+
return {
|
|
137
|
+
set(array) {
|
|
138
|
+
const el = array.filter((e) => elements.indexOf(e) === -1);
|
|
139
|
+
if (el.length === 0)
|
|
140
|
+
return;
|
|
141
|
+
elements.push(...el);
|
|
142
|
+
render?.(elements);
|
|
143
|
+
},
|
|
144
|
+
delete(array) {
|
|
145
|
+
array.forEach((e) => elements.splice(elements.indexOf(e), 1));
|
|
146
|
+
},
|
|
147
|
+
get() {
|
|
148
|
+
return elements;
|
|
149
|
+
},
|
|
150
|
+
Render({ style }) {
|
|
151
|
+
const [el, setEl] = useState(elements);
|
|
152
|
+
useEffect(() => {
|
|
153
|
+
render = setEl;
|
|
154
|
+
return () => {
|
|
155
|
+
render = null;
|
|
156
|
+
};
|
|
157
|
+
}, []);
|
|
158
|
+
return _jsx(DropdownMenu, { elements: el, style: style, position: "left" });
|
|
159
|
+
}
|
|
160
|
+
};
|
|
161
|
+
}
|
|
162
|
+
export function DropdownMenuTest() {
|
|
163
|
+
const testData = [
|
|
164
|
+
{ label: "Item 1", subMenuContent: () => _jsx(SubMenu, {}) },
|
|
165
|
+
{ label: "Item 2", subMenuContent: () => _jsx(SubMenu2, {}) },
|
|
166
|
+
{ label: "Item 3", subMenuContent: () => _jsx(SubMenu, {}) }
|
|
167
|
+
];
|
|
168
|
+
const menu = useMemo(MenuRightApi, []);
|
|
169
|
+
useEffect(() => {
|
|
170
|
+
menu.set(testData);
|
|
171
|
+
}, []);
|
|
172
|
+
return _jsx(menu.Render, {});
|
|
173
|
+
}
|
|
174
|
+
const SubMenu = () => {
|
|
175
|
+
return (_jsxs("div", { className: "maxSize", children: [_jsx(DraggableOutlineDiv, {}), _jsx("div", { className: "submenu-item", children: "Subitem 1" }), _jsx("div", { className: "submenu-item", children: "Subitem 2" }), _jsx("div", { className: "submenu-item", children: "Subitem 3" })] }));
|
|
176
|
+
};
|
|
177
|
+
const SubMenu2 = () => {
|
|
178
|
+
return (_jsxs("div", { children: [_jsx("div", { className: "submenu-item", children: "Subitem 33331" }), _jsx("div", { className: "submenu-item", children: "Subitem 33332" }), _jsx("div", { className: "submenu-item", children: "Subitem 33333" })] }));
|
|
179
|
+
};
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useState, useRef, useEffect } from 'react';
|
|
3
|
+
const StickerMenu = () => {
|
|
4
|
+
// Флаг состояния: открыто меню или закрыто
|
|
5
|
+
const [isOpen, setIsOpen] = useState(false);
|
|
6
|
+
// Сдвиг по X в процессе перетаскивания
|
|
7
|
+
const [dragX, setDragX] = useState(0);
|
|
8
|
+
// Рефы для отслеживания начала перетаскивания и самого процесса
|
|
9
|
+
const startXRef = useRef(null);
|
|
10
|
+
const draggingRef = useRef(false);
|
|
11
|
+
// Настройки размеров: общая ширина меню и ширина видимой части (стикер) при закрытом состоянии
|
|
12
|
+
const menuWidth = 250; // общая ширина открытого меню
|
|
13
|
+
const stickerWidth = 50; // ширина видимой части при закрытом меню
|
|
14
|
+
// Начало перетаскивания (мышь)
|
|
15
|
+
const handleMouseDown = (e) => {
|
|
16
|
+
draggingRef.current = true;
|
|
17
|
+
startXRef.current = e.clientX;
|
|
18
|
+
};
|
|
19
|
+
// Начало перетаскивания (касание)
|
|
20
|
+
const handleTouchStart = (e) => {
|
|
21
|
+
draggingRef.current = true;
|
|
22
|
+
startXRef.current = e.touches[0].clientX;
|
|
23
|
+
};
|
|
24
|
+
// Обработка движения мыши
|
|
25
|
+
const handleMouseMove = (e) => {
|
|
26
|
+
if (!draggingRef.current || startXRef.current === null)
|
|
27
|
+
return;
|
|
28
|
+
const deltaX = e.clientX - startXRef.current;
|
|
29
|
+
setDragX(deltaX);
|
|
30
|
+
};
|
|
31
|
+
// Обработка движения при касании
|
|
32
|
+
const handleTouchMove = (e) => {
|
|
33
|
+
if (!draggingRef.current || startXRef.current === null)
|
|
34
|
+
return;
|
|
35
|
+
const deltaX = e.touches[0].clientX - startXRef.current;
|
|
36
|
+
setDragX(deltaX);
|
|
37
|
+
};
|
|
38
|
+
// Завершение перетаскивания (мышь)
|
|
39
|
+
const handleMouseUp = () => {
|
|
40
|
+
if (!draggingRef.current)
|
|
41
|
+
return;
|
|
42
|
+
finishDrag();
|
|
43
|
+
};
|
|
44
|
+
// Завершение перетаскивания (касание)
|
|
45
|
+
const handleTouchEnd = () => {
|
|
46
|
+
if (!draggingRef.current)
|
|
47
|
+
return;
|
|
48
|
+
finishDrag();
|
|
49
|
+
};
|
|
50
|
+
// Функция завершения перетаскивания: если сдвиг больше половины ширины меню — переключаем состояние
|
|
51
|
+
const finishDrag = () => {
|
|
52
|
+
draggingRef.current = false;
|
|
53
|
+
if (dragX < -menuWidth / 2) {
|
|
54
|
+
setIsOpen(true);
|
|
55
|
+
}
|
|
56
|
+
else if (dragX > menuWidth / 2) {
|
|
57
|
+
setIsOpen(false);
|
|
58
|
+
}
|
|
59
|
+
setDragX(0);
|
|
60
|
+
startXRef.current = null;
|
|
61
|
+
};
|
|
62
|
+
// Подписываемся на глобальные события движения и завершения перетаскивания
|
|
63
|
+
useEffect(() => {
|
|
64
|
+
document.addEventListener('mousemove', handleMouseMove);
|
|
65
|
+
document.addEventListener('touchmove', handleTouchMove);
|
|
66
|
+
document.addEventListener('mouseup', handleMouseUp);
|
|
67
|
+
document.addEventListener('touchend', handleTouchEnd);
|
|
68
|
+
return () => {
|
|
69
|
+
document.removeEventListener('mousemove', handleMouseMove);
|
|
70
|
+
document.removeEventListener('touchmove', handleTouchMove);
|
|
71
|
+
document.removeEventListener('mouseup', handleMouseUp);
|
|
72
|
+
document.removeEventListener('touchend', handleTouchEnd);
|
|
73
|
+
};
|
|
74
|
+
}, [dragX]);
|
|
75
|
+
// Переключение состояния меню по клику
|
|
76
|
+
const handleClick = () => {
|
|
77
|
+
setIsOpen(!isOpen);
|
|
78
|
+
};
|
|
79
|
+
/*
|
|
80
|
+
Вычисляем итоговый сдвиг по X:
|
|
81
|
+
- Когда меню закрыто, сдвигаем его влево так, чтобы виден был только стикер.
|
|
82
|
+
- При перетаскивании корректируем позицию относительно текущего сдвига.
|
|
83
|
+
*/
|
|
84
|
+
let translateX = 0;
|
|
85
|
+
if (dragX !== 0) {
|
|
86
|
+
// Если меню открыто, перетаскиваем вправо (открытие) только в отрицательном направлении
|
|
87
|
+
// Если закрыто — перетаскиваем влево (открытие) только в положительном направлении
|
|
88
|
+
translateX = isOpen ? Math.min(0, dragX) : Math.max(0, dragX);
|
|
89
|
+
}
|
|
90
|
+
const baseTranslate = isOpen ? 0 : -(menuWidth - stickerWidth);
|
|
91
|
+
const finalTranslate = baseTranslate + translateX;
|
|
92
|
+
// Стили для контейнера меню
|
|
93
|
+
const containerStyle = {
|
|
94
|
+
position: 'fixed',
|
|
95
|
+
top: '50%',
|
|
96
|
+
right: 0,
|
|
97
|
+
transform: `translateX(${finalTranslate}px) translateY(-50%)`,
|
|
98
|
+
width: `${menuWidth}px`,
|
|
99
|
+
height: '300px',
|
|
100
|
+
backgroundColor: '#ffeb3b',
|
|
101
|
+
borderRadius: '8px 0 0 8px',
|
|
102
|
+
boxShadow: '0 0 5px rgba(0,0,0,0.3)',
|
|
103
|
+
transition: draggingRef.current ? 'none' : 'transform 0.3s ease',
|
|
104
|
+
cursor: 'pointer',
|
|
105
|
+
userSelect: 'none',
|
|
106
|
+
overflow: 'hidden'
|
|
107
|
+
};
|
|
108
|
+
return (_jsx("div", { style: containerStyle, onMouseDown: handleMouseDown, onTouchStart: handleTouchStart, onClick: handleClick, children: _jsxs("div", { style: { padding: '10px' }, children: [_jsx("h3", { children: "\u041C\u0435\u043D\u044E" }), isOpen && (_jsxs("ul", { style: { listStyle: 'none', padding: 0 }, children: [_jsx("li", { children: "\u041F\u0443\u043D\u043A\u0442 1" }), _jsx("li", { children: "\u041F\u0443\u043D\u043A\u0442 2" }), _jsx("li", { children: "\u041F\u0443\u043D\u043A\u0442 3" })] }))] }) }));
|
|
109
|
+
};
|
|
110
|
+
export default StickerMenu;
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { ColorString } from "wenay-common2";
|
|
3
|
+
export declare function LeftModal({ arr, zIndex }: {
|
|
4
|
+
arr: [React.JSX.Element, React.JSX.Element][];
|
|
5
|
+
zIndex: number;
|
|
6
|
+
}): import("react/jsx-runtime").JSX.Element;
|
|
7
|
+
type MenuItem = {
|
|
8
|
+
id?: number;
|
|
9
|
+
button: React.JSX.Element;
|
|
10
|
+
color?: ColorString;
|
|
11
|
+
textB?: string;
|
|
12
|
+
el: () => React.JSX.Element;
|
|
13
|
+
};
|
|
14
|
+
type MenuItemPartial = Omit<MenuItem, "button"> & {
|
|
15
|
+
button?: MenuItem["button"];
|
|
16
|
+
};
|
|
17
|
+
export declare function getApiLeftMenu(): {
|
|
18
|
+
modal: {
|
|
19
|
+
set(jsx: React.JSX.Element | null): void;
|
|
20
|
+
JSX: React.JSX.Element | null;
|
|
21
|
+
Render(): React.JSX.Element | null;
|
|
22
|
+
addJSX(jsx: React.JSX.Element): React.JSX.Element;
|
|
23
|
+
dellBy(jsx: React.JSX.Element): void;
|
|
24
|
+
readonly arrJSX: import("react/jsx-runtime").JSX.Element[];
|
|
25
|
+
RenderArr(): import("react/jsx-runtime").JSX.Element[];
|
|
26
|
+
};
|
|
27
|
+
renderBy(): void;
|
|
28
|
+
getMenu: () => Map<string, MenuItem[]>;
|
|
29
|
+
setMenu: (items: (MenuItemPartial | MenuItem)[], key?: string) => void;
|
|
30
|
+
Modal2: ({ menu, zIndex, zIndex0, key }: {
|
|
31
|
+
zIndex: number;
|
|
32
|
+
zIndex0?: number;
|
|
33
|
+
key?: string;
|
|
34
|
+
menu?: (MenuItemPartial | MenuItem)[];
|
|
35
|
+
}) => import("react/jsx-runtime").JSX.Element;
|
|
36
|
+
};
|
|
37
|
+
export declare const ApiLeftMenu: {
|
|
38
|
+
modal: {
|
|
39
|
+
set(jsx: React.JSX.Element | null): void;
|
|
40
|
+
JSX: React.JSX.Element | null;
|
|
41
|
+
Render(): React.JSX.Element | null;
|
|
42
|
+
addJSX(jsx: React.JSX.Element): React.JSX.Element;
|
|
43
|
+
dellBy(jsx: React.JSX.Element): void;
|
|
44
|
+
readonly arrJSX: import("react/jsx-runtime").JSX.Element[];
|
|
45
|
+
RenderArr(): import("react/jsx-runtime").JSX.Element[];
|
|
46
|
+
};
|
|
47
|
+
renderBy(): void;
|
|
48
|
+
getMenu: () => Map<string, MenuItem[]>;
|
|
49
|
+
setMenu: (items: (MenuItemPartial | MenuItem)[], key?: string) => void;
|
|
50
|
+
Modal2: ({ menu, zIndex, zIndex0, key }: {
|
|
51
|
+
zIndex: number;
|
|
52
|
+
zIndex0?: number;
|
|
53
|
+
key?: string;
|
|
54
|
+
menu?: (MenuItemPartial | MenuItem)[];
|
|
55
|
+
}) => import("react/jsx-runtime").JSX.Element;
|
|
56
|
+
};
|
|
57
|
+
export declare function TestLeft333(): import("react/jsx-runtime").JSX.Element;
|
|
58
|
+
export {};
|
|
@@ -0,0 +1,284 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
+
import { useEffect, useMemo, useRef, useState } from "react";
|
|
3
|
+
import { colorGenerator2, sleepAsync } from "wenay-common2";
|
|
4
|
+
import { Drag22 } from "../Dnd";
|
|
5
|
+
import { renderBy, updateBy } from "../../../updateBy";
|
|
6
|
+
import { GetModalJSX } from "./Modal";
|
|
7
|
+
function useViewport() {
|
|
8
|
+
const [width, setWidth] = useState(window.innerWidth);
|
|
9
|
+
useEffect(() => {
|
|
10
|
+
const handleResize = () => setWidth(window.innerWidth);
|
|
11
|
+
window.addEventListener('resize', handleResize);
|
|
12
|
+
return () => window.removeEventListener('resize', handleResize);
|
|
13
|
+
}, []);
|
|
14
|
+
return { width };
|
|
15
|
+
}
|
|
16
|
+
// Custom hook for smooth snap scrolling animation
|
|
17
|
+
function useSmoothSnapScroll() {
|
|
18
|
+
const animationState = useRef({ isAnimating: false });
|
|
19
|
+
const currentPosition = useRef({ x: 0, y: 0 });
|
|
20
|
+
const animateTo = async (target, onUpdate, onComplete) => {
|
|
21
|
+
animationState.current.isAnimating = true;
|
|
22
|
+
const step = 40;
|
|
23
|
+
const animate = async () => {
|
|
24
|
+
if (!animationState.current.isAnimating || currentPosition.current.x === target) {
|
|
25
|
+
return;
|
|
26
|
+
}
|
|
27
|
+
const direction = target > currentPosition.current.x ? 1 : -1;
|
|
28
|
+
await sleepAsync(10);
|
|
29
|
+
const nextPosition = currentPosition.current.x + direction * step;
|
|
30
|
+
if (Math.abs(target - nextPosition) < step) {
|
|
31
|
+
animationState.current.isAnimating = false;
|
|
32
|
+
currentPosition.current.x = target;
|
|
33
|
+
onUpdate(target);
|
|
34
|
+
onComplete?.();
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
37
|
+
currentPosition.current.x = nextPosition;
|
|
38
|
+
onUpdate(nextPosition);
|
|
39
|
+
animate();
|
|
40
|
+
};
|
|
41
|
+
await animate();
|
|
42
|
+
};
|
|
43
|
+
const stopAnimation = () => {
|
|
44
|
+
animationState.current.isAnimating = false;
|
|
45
|
+
};
|
|
46
|
+
return { animateTo, stopAnimation, currentPosition };
|
|
47
|
+
}
|
|
48
|
+
const MENU_WIDTH_RATIO = 0.8;
|
|
49
|
+
// Main sidebar menu component with snap scrolling behavior
|
|
50
|
+
function SidebarMenuComponent({ y_, x_, api, arr, zIndex }) {
|
|
51
|
+
const [page, setPage] = useState(null);
|
|
52
|
+
const [x, setX] = useState(x_);
|
|
53
|
+
const [y, setY] = useState(y_);
|
|
54
|
+
const [open, setOpen] = useState(false);
|
|
55
|
+
// Size references for menu and element dimensions
|
|
56
|
+
const viewportSize = useRef(null);
|
|
57
|
+
const elementSize = useRef(null);
|
|
58
|
+
const lastPosition = useRef({ x: 0, y: 0, auto: false });
|
|
59
|
+
const currentPosition = useRef({ x: 0, y: 0, auto: false });
|
|
60
|
+
const scrollRef = useRef(null);
|
|
61
|
+
const dragStatus = useRef({ status: 0 });
|
|
62
|
+
const { width: viewportWidth } = useViewport();
|
|
63
|
+
const mainPage = useMemo(() => (_jsxs("div", { ref: scrollRef, style: {
|
|
64
|
+
height: "100vh",
|
|
65
|
+
width: Math.round(MENU_WIDTH_RATIO * 100) + "vw",
|
|
66
|
+
overflow: "auto",
|
|
67
|
+
scrollbarWidth: "none",
|
|
68
|
+
scrollBehavior: "smooth",
|
|
69
|
+
scrollSnapType: "y mandatory"
|
|
70
|
+
}, children: [arr.map(([button, page], i) => (_jsx("div", { ref: e => e?.scrollTo(), style: { scrollSnapAlign: "start" }, id: String(i), children: page }, i))), _jsx("div", {})] })), [arr]);
|
|
71
|
+
const menuItems = arr.map((e, i) => (_jsx("div", { style: { paddingBottom: 10, width: "100%" }, onMouseDown: () => setPage(mainPage), onTouchStart: () => setPage(mainPage), children: _jsx("a", { rel: "ds", href: `#${i}`, style: {
|
|
72
|
+
font: "inherit",
|
|
73
|
+
color: "inherit",
|
|
74
|
+
textDecoration: "inherit",
|
|
75
|
+
cursor: "default",
|
|
76
|
+
}, children: e[0] }) }, i)));
|
|
77
|
+
// Smooth animation function to target position
|
|
78
|
+
const animateToPosition = async (target) => {
|
|
79
|
+
lastPosition.current.auto = true;
|
|
80
|
+
const step = 40;
|
|
81
|
+
if (!lastPosition.current.auto)
|
|
82
|
+
return;
|
|
83
|
+
const animate = async () => {
|
|
84
|
+
if (!lastPosition.current.auto || currentPosition.current.x === target)
|
|
85
|
+
return;
|
|
86
|
+
const direction = target > currentPosition.current.x ? 1 : -1;
|
|
87
|
+
await sleepAsync(10);
|
|
88
|
+
const nextPos = currentPosition.current.x + direction * step;
|
|
89
|
+
if (Math.abs(target - nextPos) < step) {
|
|
90
|
+
lastPosition.current.auto = false;
|
|
91
|
+
currentPosition.current.x = target;
|
|
92
|
+
if (target === 0)
|
|
93
|
+
setOpen(false);
|
|
94
|
+
setX(target);
|
|
95
|
+
return;
|
|
96
|
+
}
|
|
97
|
+
currentPosition.current.x = nextPos;
|
|
98
|
+
setX(nextPos);
|
|
99
|
+
animate();
|
|
100
|
+
};
|
|
101
|
+
await animate();
|
|
102
|
+
};
|
|
103
|
+
useEffect(() => {
|
|
104
|
+
const menuApi = {
|
|
105
|
+
moveStop: () => {
|
|
106
|
+
currentPosition.current.auto = false;
|
|
107
|
+
lastPosition.current.auto = false;
|
|
108
|
+
},
|
|
109
|
+
moveToStart: () => {
|
|
110
|
+
animateToPosition(0);
|
|
111
|
+
},
|
|
112
|
+
moveToEnd: () => {
|
|
113
|
+
animateToPosition(viewportSize.current?.width ? viewportSize.current.width * -1 : -500);
|
|
114
|
+
},
|
|
115
|
+
y: yNew => {
|
|
116
|
+
let newY = yNew + lastPosition.current.y;
|
|
117
|
+
if (newY < 0)
|
|
118
|
+
newY = 0;
|
|
119
|
+
if (dragStatus.current.status === 1) {
|
|
120
|
+
currentPosition.current.y = newY;
|
|
121
|
+
setY(newY);
|
|
122
|
+
}
|
|
123
|
+
},
|
|
124
|
+
open: setOpen,
|
|
125
|
+
x: (xNew) => {
|
|
126
|
+
let newX = xNew + lastPosition.current.x;
|
|
127
|
+
currentPosition.current.x = newX;
|
|
128
|
+
if (newX < 0)
|
|
129
|
+
setOpen(true);
|
|
130
|
+
if (newX === 0)
|
|
131
|
+
setOpen(false);
|
|
132
|
+
setX(newX);
|
|
133
|
+
},
|
|
134
|
+
start: () => {
|
|
135
|
+
menuApi.moveStop?.();
|
|
136
|
+
lastPosition.current.x = currentPosition.current.x;
|
|
137
|
+
lastPosition.current.y = currentPosition.current.y;
|
|
138
|
+
},
|
|
139
|
+
stop: () => {
|
|
140
|
+
if (lastPosition.current.x > currentPosition.current.x + 3) {
|
|
141
|
+
animateToPosition(viewportSize.current ? MENU_WIDTH_RATIO * viewportWidth * -1 : -300);
|
|
142
|
+
}
|
|
143
|
+
else if (lastPosition.current.x + 3 < currentPosition.current.x &&
|
|
144
|
+
Math.abs(lastPosition.current.y - currentPosition.current.y) <=
|
|
145
|
+
Math.abs(lastPosition.current.x - currentPosition.current.x)) {
|
|
146
|
+
animateToPosition(0);
|
|
147
|
+
}
|
|
148
|
+
else {
|
|
149
|
+
if (viewportSize.current) {
|
|
150
|
+
if (Math.abs(currentPosition.current.x) > viewportSize.current.width * 0.5) {
|
|
151
|
+
animateToPosition(viewportSize.current.width * -1);
|
|
152
|
+
}
|
|
153
|
+
else {
|
|
154
|
+
animateToPosition(0);
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
},
|
|
159
|
+
};
|
|
160
|
+
api(menuApi);
|
|
161
|
+
}, [viewportWidth]);
|
|
162
|
+
return _jsxs(_Fragment, { children: [_jsx("div", { ref: e => {
|
|
163
|
+
if (e) {
|
|
164
|
+
const rect = e.getBoundingClientRect();
|
|
165
|
+
elementSize.current = {
|
|
166
|
+
height: rect.height,
|
|
167
|
+
width: rect.width,
|
|
168
|
+
};
|
|
169
|
+
}
|
|
170
|
+
}, style: { position: "absolute", right: x * -1, top: y, zIndex }, onClick: () => {
|
|
171
|
+
if (!open) {
|
|
172
|
+
setOpen(true);
|
|
173
|
+
animateToPosition(viewportSize.current ? MENU_WIDTH_RATIO * viewportWidth * -1 : -300);
|
|
174
|
+
}
|
|
175
|
+
}, onMouseDown: () => {
|
|
176
|
+
dragStatus.current.status = 1;
|
|
177
|
+
}, onMouseLeave: () => {
|
|
178
|
+
dragStatus.current.status = 0;
|
|
179
|
+
}, onMouseUp: () => {
|
|
180
|
+
dragStatus.current.status = 0;
|
|
181
|
+
}, children: menuItems }), _jsx("div", { ref: e => {
|
|
182
|
+
if (e) {
|
|
183
|
+
const rect = e.getBoundingClientRect();
|
|
184
|
+
viewportSize.current = {
|
|
185
|
+
height: rect.height,
|
|
186
|
+
width: rect.width,
|
|
187
|
+
};
|
|
188
|
+
}
|
|
189
|
+
}, style: { position: "absolute", left: `calc(100% + ${x}px)`, zIndex } }), open && (_jsxs("div", { style: { width: -x, overflow: "hidden" }, children: [_jsx("div", { ref: e => {
|
|
190
|
+
if (e) {
|
|
191
|
+
const rect = e.getBoundingClientRect();
|
|
192
|
+
viewportSize.current = {
|
|
193
|
+
height: rect.height,
|
|
194
|
+
width: rect.width,
|
|
195
|
+
};
|
|
196
|
+
}
|
|
197
|
+
}, className: "maxSize" }), mainPage] }))] });
|
|
198
|
+
}
|
|
199
|
+
export function LeftModal({ arr, zIndex }) {
|
|
200
|
+
const currentPos = useRef({ x: 0, y: 0, auto: false });
|
|
201
|
+
const menuApiRef = useRef(null);
|
|
202
|
+
const sidebarComponent = useMemo(() => (_jsx(SidebarMenuComponent, { arr: arr, zIndex: zIndex, api: (apiInstance) => {
|
|
203
|
+
menuApiRef.current = apiInstance;
|
|
204
|
+
}, x_: currentPos.current.x, y_: currentPos.current.y })), [arr, zIndex]);
|
|
205
|
+
const draggableWrapper = useMemo(() => (_jsx(Drag22, { onX: (xNew) => menuApiRef.current?.x(xNew), right: true, onY: (yNew) => menuApiRef.current?.y(yNew), x: 0, y: 0, onStart: () => menuApiRef.current?.start?.(), onStop: () => menuApiRef.current?.stop?.(), children: sidebarComponent })), [sidebarComponent]);
|
|
206
|
+
return _jsx("div", { className: "maxSize", children: draggableWrapper });
|
|
207
|
+
}
|
|
208
|
+
function LeftMenuComponent({ api, menu = [], zIndex }) {
|
|
209
|
+
return _jsx(LeftModal, { arr: menu.map(item => [item.button, item.el()]), zIndex: zIndex });
|
|
210
|
+
}
|
|
211
|
+
export function getApiLeftMenu() {
|
|
212
|
+
const createDefaultButton = ({ color, text }) => {
|
|
213
|
+
return (_jsx("div", { className: "blur", style: {
|
|
214
|
+
minHeight: "4vh",
|
|
215
|
+
minWidth: "50px",
|
|
216
|
+
marginBottom: 10,
|
|
217
|
+
fontSize: 12,
|
|
218
|
+
textAlign: "center",
|
|
219
|
+
background: color,
|
|
220
|
+
color: "rgba(255,255,255,0.1)"
|
|
221
|
+
}, children: text ?? "" }));
|
|
222
|
+
};
|
|
223
|
+
const createDefaultElement = ({ color, children, textB }) => {
|
|
224
|
+
const viewportWidth = window.innerWidth;
|
|
225
|
+
return (_jsxs("div", { className: "blur", style: {
|
|
226
|
+
minHeight: "100vh",
|
|
227
|
+
width: viewportWidth > 800 ? "100%" : "calc(100vw - 50px)",
|
|
228
|
+
background: color,
|
|
229
|
+
position: "relative"
|
|
230
|
+
}, children: [textB && (_jsx("div", { style: {
|
|
231
|
+
position: "absolute",
|
|
232
|
+
right: 0,
|
|
233
|
+
top: 0,
|
|
234
|
+
fontSize: 28,
|
|
235
|
+
color: "rgba(255,255,255,0.1)"
|
|
236
|
+
}, children: textB })), children()] }));
|
|
237
|
+
};
|
|
238
|
+
let menuApi = null;
|
|
239
|
+
const menuStore = new Map();
|
|
240
|
+
const setMenu = (items, key = "base") => {
|
|
241
|
+
const colorGen = colorGenerator2({ min: 0, max: 90 });
|
|
242
|
+
const currentMenuLength = getAllMenuItems().length;
|
|
243
|
+
const baseColors = [];
|
|
244
|
+
for (let i = 0; i < currentMenuLength + items.length; i++) {
|
|
245
|
+
const colorResult = colorGen.next();
|
|
246
|
+
if (!colorResult.done) {
|
|
247
|
+
const [r, g, b] = colorResult.value;
|
|
248
|
+
baseColors.push(`rgb(${r},${g},${b}, 0.3)`);
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
const itemColors = items.map((item, i) => item.color ?? baseColors[item.id ?? i + currentMenuLength]);
|
|
252
|
+
const menuItems = items.map((item, i) => ({
|
|
253
|
+
...item,
|
|
254
|
+
button: item.button ?? createDefaultButton({ text: item.textB, color: itemColors[i] }),
|
|
255
|
+
el: () => createDefaultElement({ color: itemColors[i], children: item.el, textB: item.textB })
|
|
256
|
+
}));
|
|
257
|
+
menuStore.set(key, menuItems);
|
|
258
|
+
};
|
|
259
|
+
function getAllMenuItems() {
|
|
260
|
+
return [...menuStore.values()].flat();
|
|
261
|
+
}
|
|
262
|
+
function Modal2({ menu, zIndex, zIndex0, key }) {
|
|
263
|
+
if (menu)
|
|
264
|
+
setMenu(menu, key);
|
|
265
|
+
updateBy(menuStore);
|
|
266
|
+
return (_jsxs("div", { className: "maxSize", style: { position: "absolute", zIndex: zIndex0 }, children: [_jsx(modal.Render, {}), _jsx(LeftMenuComponent, { zIndex: zIndex, api: a => menuApi = a, menu: getAllMenuItems() })] }));
|
|
267
|
+
}
|
|
268
|
+
const modal = GetModalJSX();
|
|
269
|
+
return {
|
|
270
|
+
modal,
|
|
271
|
+
renderBy() { renderBy(menuStore); },
|
|
272
|
+
getMenu: () => menuStore,
|
|
273
|
+
setMenu: setMenu,
|
|
274
|
+
Modal2: Modal2
|
|
275
|
+
};
|
|
276
|
+
}
|
|
277
|
+
export const ApiLeftMenu = getApiLeftMenu();
|
|
278
|
+
ApiLeftMenu.setMenu([
|
|
279
|
+
{ button: _jsx("div", { style: { width: 200, height: 50, background: "rgb(92,50,213)" }, children: "1" }), el: () => _jsx("div", { children: "1" }), color: "rgb(92,50,213)" },
|
|
280
|
+
{ button: _jsx("div", { style: { width: 200, height: 50, background: "rgb(98,149,58)" }, children: "2" }), el: () => _jsx("div", { children: "2" }) },
|
|
281
|
+
], "test");
|
|
282
|
+
export function TestLeft333() {
|
|
283
|
+
return _jsx(ApiLeftMenu.Modal2, { zIndex: 20 });
|
|
284
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
export declare function inputModal({ setModalJSX, func, name, txt }: {
|
|
3
|
+
txt?: string;
|
|
4
|
+
name?: string;
|
|
5
|
+
setModalJSX: React.Dispatch<React.SetStateAction<React.JSX.Element | null>>;
|
|
6
|
+
func: (txt: string) => void;
|
|
7
|
+
}): void;
|
|
8
|
+
export declare function confirmModal({ setModalJSX, func }: {
|
|
9
|
+
setModalJSX: React.Dispatch<React.SetStateAction<React.JSX.Element | null>>;
|
|
10
|
+
func: () => any;
|
|
11
|
+
}): void;
|
|
12
|
+
export declare function GetModalJSX(): {
|
|
13
|
+
set(jsx: React.JSX.Element | null): void;
|
|
14
|
+
JSX: React.JSX.Element | null;
|
|
15
|
+
Render(): React.JSX.Element | null;
|
|
16
|
+
addJSX(jsx: React.JSX.Element): React.JSX.Element;
|
|
17
|
+
dellBy(jsx: React.JSX.Element): void;
|
|
18
|
+
readonly arrJSX: import("react/jsx-runtime").JSX.Element[];
|
|
19
|
+
RenderArr(): import("react/jsx-runtime").JSX.Element[];
|
|
20
|
+
};
|
|
21
|
+
type t1 = (() => React.JSX.Element | null) | null;
|
|
22
|
+
export declare function GetModalFuncJSX(): {
|
|
23
|
+
set(jsx: t1): void;
|
|
24
|
+
JSX: t1;
|
|
25
|
+
Render(): React.JSX.Element | null;
|
|
26
|
+
addJSX(jsx: t1): t1;
|
|
27
|
+
dellBy(jsx: t1): void;
|
|
28
|
+
readonly arrJSX: (import("react/jsx-runtime").JSX.Element | null)[];
|
|
29
|
+
RenderArr(): (import("react/jsx-runtime").JSX.Element | null)[];
|
|
30
|
+
};
|
|
31
|
+
export {};
|