namirasoft-site-react 1.4.556 → 1.4.558
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/dist/components/NSSplitter.d.ts +17 -3
- package/dist/components/NSSplitter.js +106 -15
- package/dist/components/NSSplitter.js.map +1 -1
- package/dist/components/NSSplitter.module.css +1 -0
- package/package.json +2 -2
- package/src/components/NSSplitter.module.css +1 -0
- package/src/components/NSSplitter.tsx +147 -18
|
@@ -1,15 +1,29 @@
|
|
|
1
|
-
import { Component, ReactNode } from "react";
|
|
1
|
+
import { Component, MouseEvent as ReactMouseEvent, ReactNode } from "react";
|
|
2
2
|
export interface NSSplitterProps {
|
|
3
3
|
master_content?: ReactNode;
|
|
4
4
|
detail_content?: ReactNode;
|
|
5
|
+
storage_key?: string;
|
|
5
6
|
}
|
|
6
7
|
export declare class NSSplitter extends Component<NSSplitterProps> {
|
|
7
8
|
private SplitterRef;
|
|
8
9
|
private MasterPaneRef;
|
|
9
|
-
private
|
|
10
|
+
private GutterRef;
|
|
10
11
|
private AnimationFrame;
|
|
12
|
+
private DragOffset;
|
|
13
|
+
private HasUserResized;
|
|
14
|
+
private MediaQuery;
|
|
15
|
+
private Storage;
|
|
11
16
|
constructor(props: NSSplitterProps);
|
|
12
|
-
|
|
17
|
+
componentDidMount(): void;
|
|
18
|
+
componentDidUpdate(prevProps: NSSplitterProps): void;
|
|
19
|
+
componentWillUnmount(): void;
|
|
20
|
+
handleViewportChange(): void;
|
|
21
|
+
updateLayout(force: boolean): void;
|
|
22
|
+
applyHeight(height: number): void;
|
|
23
|
+
loadStoredHeight(): number | null;
|
|
24
|
+
saveStoredHeight(height: number): void;
|
|
25
|
+
adjustMasterToViewport(): void;
|
|
26
|
+
handleMouseDown(event: ReactMouseEvent): void;
|
|
13
27
|
handleMouseUp(): void;
|
|
14
28
|
handleMouseMove(event: MouseEvent): void;
|
|
15
29
|
render(): import("react").JSX.Element;
|
|
@@ -1,48 +1,139 @@
|
|
|
1
1
|
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { Component, createRef } from "react";
|
|
3
|
+
import { IStorageLocal } from "namirasoft-core";
|
|
3
4
|
import Styles from "./NSSplitter.module.css";
|
|
5
|
+
const MIN_MASTER_HEIGHT = 238;
|
|
4
6
|
export class NSSplitter extends Component {
|
|
5
7
|
constructor(props) {
|
|
6
8
|
super(props);
|
|
7
9
|
this.SplitterRef = createRef();
|
|
8
10
|
this.MasterPaneRef = createRef();
|
|
9
|
-
this.
|
|
11
|
+
this.GutterRef = createRef();
|
|
10
12
|
this.AnimationFrame = null;
|
|
13
|
+
this.DragOffset = 0;
|
|
14
|
+
this.HasUserResized = false;
|
|
15
|
+
this.MediaQuery = null;
|
|
16
|
+
this.Storage = new IStorageLocal();
|
|
11
17
|
this.handleMouseDown = this.handleMouseDown.bind(this);
|
|
12
18
|
this.handleMouseUp = this.handleMouseUp.bind(this);
|
|
13
19
|
this.handleMouseMove = this.handleMouseMove.bind(this);
|
|
20
|
+
this.handleViewportChange = this.handleViewportChange.bind(this);
|
|
14
21
|
}
|
|
15
|
-
|
|
22
|
+
componentDidMount() {
|
|
23
|
+
this.MediaQuery = window.matchMedia("(min-width: 992px)");
|
|
24
|
+
this.MediaQuery.addEventListener("change", this.handleViewportChange);
|
|
25
|
+
window.addEventListener("resize", this.handleViewportChange);
|
|
26
|
+
if (this.loadStoredHeight() !== null)
|
|
27
|
+
this.HasUserResized = true;
|
|
28
|
+
this.updateLayout(true);
|
|
29
|
+
}
|
|
30
|
+
componentDidUpdate(prevProps) {
|
|
31
|
+
let had_detail = !!prevProps.detail_content;
|
|
32
|
+
let has_detail = !!this.props.detail_content;
|
|
33
|
+
if (had_detail !== has_detail) {
|
|
34
|
+
this.HasUserResized = false;
|
|
35
|
+
this.updateLayout(true);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
componentWillUnmount() {
|
|
39
|
+
var _a;
|
|
40
|
+
(_a = this.MediaQuery) === null || _a === void 0 ? void 0 : _a.removeEventListener("change", this.handleViewportChange);
|
|
41
|
+
window.removeEventListener("resize", this.handleViewportChange);
|
|
42
|
+
window.removeEventListener("mousemove", this.handleMouseMove);
|
|
43
|
+
window.removeEventListener("mouseup", this.handleMouseUp);
|
|
44
|
+
if (this.AnimationFrame)
|
|
45
|
+
cancelAnimationFrame(this.AnimationFrame);
|
|
46
|
+
}
|
|
47
|
+
handleViewportChange() {
|
|
48
|
+
this.updateLayout(false);
|
|
49
|
+
}
|
|
50
|
+
updateLayout(force) {
|
|
51
|
+
let master_el = this.MasterPaneRef.current;
|
|
52
|
+
if (!master_el || !this.MediaQuery)
|
|
53
|
+
return;
|
|
54
|
+
if (this.MediaQuery.matches && this.props.detail_content) {
|
|
55
|
+
let stored = this.loadStoredHeight();
|
|
56
|
+
if (stored !== null)
|
|
57
|
+
this.applyHeight(Math.max(MIN_MASTER_HEIGHT, stored));
|
|
58
|
+
else if (force || !this.HasUserResized)
|
|
59
|
+
this.adjustMasterToViewport();
|
|
60
|
+
}
|
|
61
|
+
else {
|
|
62
|
+
master_el.style.height = "";
|
|
63
|
+
master_el.style.minHeight = "";
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
applyHeight(height) {
|
|
67
|
+
let master_el = this.MasterPaneRef.current;
|
|
68
|
+
if (master_el) {
|
|
69
|
+
master_el.style.height = height + "px";
|
|
70
|
+
master_el.style.minHeight = height + "px";
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
loadStoredHeight() {
|
|
74
|
+
let key = this.props.storage_key;
|
|
75
|
+
if (!key)
|
|
76
|
+
return null;
|
|
77
|
+
let raw = this.Storage.get(key, "");
|
|
78
|
+
if (!raw)
|
|
79
|
+
return null;
|
|
80
|
+
let value = parseInt(raw, 10);
|
|
81
|
+
if (isNaN(value))
|
|
82
|
+
return null;
|
|
83
|
+
return value;
|
|
84
|
+
}
|
|
85
|
+
saveStoredHeight(height) {
|
|
86
|
+
let key = this.props.storage_key;
|
|
87
|
+
if (!key)
|
|
88
|
+
return;
|
|
89
|
+
this.Storage.set(key, String(height));
|
|
90
|
+
}
|
|
91
|
+
adjustMasterToViewport() {
|
|
16
92
|
var _a, _b;
|
|
17
|
-
|
|
18
|
-
|
|
93
|
+
let master_el = this.MasterPaneRef.current;
|
|
94
|
+
if (!master_el)
|
|
95
|
+
return;
|
|
96
|
+
let master_top = master_el.getBoundingClientRect().top;
|
|
97
|
+
let gutter_height = (_b = (_a = this.GutterRef.current) === null || _a === void 0 ? void 0 : _a.offsetHeight) !== null && _b !== void 0 ? _b : 0;
|
|
98
|
+
let height = Math.max(MIN_MASTER_HEIGHT, window.innerHeight - master_top - gutter_height);
|
|
99
|
+
this.applyHeight(height);
|
|
100
|
+
}
|
|
101
|
+
handleMouseDown(event) {
|
|
102
|
+
var _a;
|
|
103
|
+
let master_el = this.MasterPaneRef.current;
|
|
104
|
+
if (!master_el)
|
|
105
|
+
return;
|
|
106
|
+
this.DragOffset = event.clientY - master_el.getBoundingClientRect().bottom;
|
|
107
|
+
window.addEventListener("mousemove", this.handleMouseMove);
|
|
19
108
|
window.addEventListener("mouseup", this.handleMouseUp);
|
|
109
|
+
(_a = this.SplitterRef.current) === null || _a === void 0 ? void 0 : _a.classList.add(Styles.ns_splitter_resizing);
|
|
20
110
|
}
|
|
21
111
|
handleMouseUp() {
|
|
22
|
-
var _a
|
|
23
|
-
|
|
24
|
-
(_b = this.SplitterRef.current) === null || _b === void 0 ? void 0 : _b.classList.remove(Styles.ns_splitter_resizing);
|
|
112
|
+
var _a;
|
|
113
|
+
window.removeEventListener("mousemove", this.handleMouseMove);
|
|
25
114
|
window.removeEventListener("mouseup", this.handleMouseUp);
|
|
115
|
+
(_a = this.SplitterRef.current) === null || _a === void 0 ? void 0 : _a.classList.remove(Styles.ns_splitter_resizing);
|
|
116
|
+
let master_el = this.MasterPaneRef.current;
|
|
117
|
+
if (master_el)
|
|
118
|
+
this.saveStoredHeight(master_el.offsetHeight);
|
|
26
119
|
}
|
|
27
120
|
handleMouseMove(event) {
|
|
28
121
|
if (this.AnimationFrame)
|
|
29
122
|
return;
|
|
30
123
|
this.AnimationFrame = requestAnimationFrame(() => {
|
|
31
124
|
this.AnimationFrame = null;
|
|
32
|
-
let splitter_el = this.SplitterRef.current;
|
|
33
125
|
let master_el = this.MasterPaneRef.current;
|
|
34
|
-
if (!
|
|
126
|
+
if (!master_el)
|
|
35
127
|
return;
|
|
36
|
-
let
|
|
37
|
-
let
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
master_el.style.minHeight = master_el_height + "px";
|
|
128
|
+
let master_top = master_el.getBoundingClientRect().top;
|
|
129
|
+
let height = Math.max(MIN_MASTER_HEIGHT, event.clientY - this.DragOffset - master_top);
|
|
130
|
+
this.applyHeight(height);
|
|
131
|
+
this.HasUserResized = true;
|
|
41
132
|
});
|
|
42
133
|
}
|
|
43
134
|
render() {
|
|
44
135
|
return (_jsxs("section", { ref: this.SplitterRef, className: Styles.ns_splitter, children: [_jsx("div", { ref: this.MasterPaneRef, className: Styles.ns_splitter_master, children: this.props.master_content }), this.props.detail_content &&
|
|
45
|
-
_jsxs(_Fragment, { children: [_jsx("button", { className: Styles.ns_splitter_gutter, onMouseDown: this.handleMouseDown, children: _jsx("span", { className: Styles.ns_splitter_gutter_handle }) }), _jsx("div", {
|
|
136
|
+
_jsxs(_Fragment, { children: [_jsx("button", { ref: this.GutterRef, className: Styles.ns_splitter_gutter, onMouseDown: this.handleMouseDown, children: _jsx("span", { className: Styles.ns_splitter_gutter_handle }) }), _jsx("div", { className: Styles.ns_splitter_detail, children: this.props.detail_content })] })] }));
|
|
46
137
|
}
|
|
47
138
|
}
|
|
48
139
|
//# sourceMappingURL=NSSplitter.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"NSSplitter.js","sourceRoot":"","sources":["../../src/components/NSSplitter.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,SAAS,EAAE,SAAS,
|
|
1
|
+
{"version":3,"file":"NSSplitter.js","sourceRoot":"","sources":["../../src/components/NSSplitter.tsx"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
"framework": "npm",
|
|
9
9
|
"application": "package",
|
|
10
10
|
"private": false,
|
|
11
|
-
"version": "1.4.
|
|
11
|
+
"version": "1.4.558",
|
|
12
12
|
"author": "Amir Abolhasani",
|
|
13
13
|
"license": "MIT",
|
|
14
14
|
"main": "./dist/main.js",
|
|
@@ -24,7 +24,7 @@
|
|
|
24
24
|
"@ant-design/icons": "^6.2.5",
|
|
25
25
|
"@babel/plugin-proposal-private-property-in-object": "^7.21.11",
|
|
26
26
|
"@babel/plugin-transform-private-property-in-object": "^7.29.7",
|
|
27
|
-
"@types/node": "^
|
|
27
|
+
"@types/node": "^26.0.0",
|
|
28
28
|
"@types/react": "^18.3.12",
|
|
29
29
|
"@types/react-bootstrap": "^1.1.0",
|
|
30
30
|
"@types/react-dom": "^18.3.1",
|
|
@@ -1,18 +1,26 @@
|
|
|
1
|
-
import { Component, createRef, ReactNode } from "react";
|
|
1
|
+
import { Component, createRef, MouseEvent as ReactMouseEvent, ReactNode } from "react";
|
|
2
|
+
import { IStorageLocal } from "namirasoft-core";
|
|
2
3
|
import Styles from "./NSSplitter.module.css";
|
|
3
4
|
|
|
5
|
+
const MIN_MASTER_HEIGHT = 238;
|
|
6
|
+
|
|
4
7
|
export interface NSSplitterProps
|
|
5
8
|
{
|
|
6
9
|
master_content?: ReactNode;
|
|
7
10
|
detail_content?: ReactNode;
|
|
11
|
+
storage_key?: string;
|
|
8
12
|
}
|
|
9
13
|
|
|
10
14
|
export class NSSplitter extends Component<NSSplitterProps>
|
|
11
15
|
{
|
|
12
16
|
private SplitterRef = createRef<HTMLElement>();
|
|
13
17
|
private MasterPaneRef = createRef<HTMLDivElement>();
|
|
14
|
-
private
|
|
18
|
+
private GutterRef = createRef<HTMLButtonElement>();
|
|
15
19
|
private AnimationFrame: number | null = null;
|
|
20
|
+
private DragOffset = 0;
|
|
21
|
+
private HasUserResized = false;
|
|
22
|
+
private MediaQuery: MediaQueryList | null = null;
|
|
23
|
+
private Storage = new IStorageLocal();
|
|
16
24
|
|
|
17
25
|
constructor(props: NSSplitterProps)
|
|
18
26
|
{
|
|
@@ -20,20 +28,145 @@ export class NSSplitter extends Component<NSSplitterProps>
|
|
|
20
28
|
this.handleMouseDown = this.handleMouseDown.bind(this);
|
|
21
29
|
this.handleMouseUp = this.handleMouseUp.bind(this);
|
|
22
30
|
this.handleMouseMove = this.handleMouseMove.bind(this);
|
|
31
|
+
this.handleViewportChange = this.handleViewportChange.bind(this);
|
|
23
32
|
}
|
|
24
33
|
|
|
25
|
-
|
|
34
|
+
override componentDidMount()
|
|
26
35
|
{
|
|
27
|
-
this.
|
|
28
|
-
this.
|
|
36
|
+
this.MediaQuery = window.matchMedia("(min-width: 992px)");
|
|
37
|
+
this.MediaQuery.addEventListener("change", this.handleViewportChange);
|
|
38
|
+
window.addEventListener("resize", this.handleViewportChange);
|
|
39
|
+
|
|
40
|
+
if (this.loadStoredHeight() !== null)
|
|
41
|
+
this.HasUserResized = true;
|
|
42
|
+
|
|
43
|
+
this.updateLayout(true);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
override componentDidUpdate(prevProps: NSSplitterProps)
|
|
47
|
+
{
|
|
48
|
+
let had_detail = !!prevProps.detail_content;
|
|
49
|
+
let has_detail = !!this.props.detail_content;
|
|
50
|
+
|
|
51
|
+
if (had_detail !== has_detail)
|
|
52
|
+
{
|
|
53
|
+
this.HasUserResized = false;
|
|
54
|
+
this.updateLayout(true);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
override componentWillUnmount()
|
|
59
|
+
{
|
|
60
|
+
this.MediaQuery?.removeEventListener("change", this.handleViewportChange);
|
|
61
|
+
window.removeEventListener("resize", this.handleViewportChange);
|
|
62
|
+
window.removeEventListener("mousemove", this.handleMouseMove);
|
|
63
|
+
window.removeEventListener("mouseup", this.handleMouseUp);
|
|
64
|
+
|
|
65
|
+
if (this.AnimationFrame) cancelAnimationFrame(this.AnimationFrame);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
handleViewportChange()
|
|
69
|
+
{
|
|
70
|
+
this.updateLayout(false);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
updateLayout(force: boolean)
|
|
74
|
+
{
|
|
75
|
+
let master_el = this.MasterPaneRef.current;
|
|
76
|
+
|
|
77
|
+
if (!master_el || !this.MediaQuery) return;
|
|
78
|
+
|
|
79
|
+
if (this.MediaQuery.matches && this.props.detail_content)
|
|
80
|
+
{
|
|
81
|
+
let stored = this.loadStoredHeight();
|
|
82
|
+
|
|
83
|
+
if (stored !== null)
|
|
84
|
+
this.applyHeight(Math.max(MIN_MASTER_HEIGHT, stored));
|
|
85
|
+
else if (force || !this.HasUserResized)
|
|
86
|
+
this.adjustMasterToViewport();
|
|
87
|
+
}
|
|
88
|
+
else
|
|
89
|
+
{
|
|
90
|
+
master_el.style.height = "";
|
|
91
|
+
master_el.style.minHeight = "";
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
applyHeight(height: number)
|
|
96
|
+
{
|
|
97
|
+
let master_el = this.MasterPaneRef.current;
|
|
98
|
+
|
|
99
|
+
if (master_el) {
|
|
100
|
+
master_el.style.height = height + "px";
|
|
101
|
+
master_el.style.minHeight = height + "px";
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
loadStoredHeight(): number | null
|
|
106
|
+
{
|
|
107
|
+
let key = this.props.storage_key;
|
|
108
|
+
|
|
109
|
+
if (!key)
|
|
110
|
+
return null;
|
|
111
|
+
|
|
112
|
+
let raw = this.Storage.get(key, "");
|
|
113
|
+
|
|
114
|
+
if (!raw)
|
|
115
|
+
return null;
|
|
116
|
+
|
|
117
|
+
let value = parseInt(raw, 10);
|
|
118
|
+
|
|
119
|
+
if (isNaN(value))
|
|
120
|
+
return null;
|
|
121
|
+
|
|
122
|
+
return value;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
saveStoredHeight(height: number)
|
|
126
|
+
{
|
|
127
|
+
let key = this.props.storage_key;
|
|
128
|
+
|
|
129
|
+
if (!key) return;
|
|
130
|
+
|
|
131
|
+
this.Storage.set(key, String(height));
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
adjustMasterToViewport()
|
|
135
|
+
{
|
|
136
|
+
let master_el = this.MasterPaneRef.current;
|
|
137
|
+
|
|
138
|
+
if (!master_el) return;
|
|
139
|
+
|
|
140
|
+
let master_top = master_el.getBoundingClientRect().top;
|
|
141
|
+
let gutter_height = this.GutterRef.current?.offsetHeight ?? 0;
|
|
142
|
+
let height = Math.max(MIN_MASTER_HEIGHT, window.innerHeight - master_top - gutter_height);
|
|
143
|
+
|
|
144
|
+
this.applyHeight(height);
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
handleMouseDown(event: ReactMouseEvent)
|
|
148
|
+
{
|
|
149
|
+
let master_el = this.MasterPaneRef.current;
|
|
150
|
+
|
|
151
|
+
if (!master_el) return;
|
|
152
|
+
|
|
153
|
+
this.DragOffset = event.clientY - master_el.getBoundingClientRect().bottom;
|
|
154
|
+
|
|
155
|
+
window.addEventListener("mousemove", this.handleMouseMove);
|
|
29
156
|
window.addEventListener("mouseup", this.handleMouseUp);
|
|
157
|
+
this.SplitterRef.current?.classList.add(Styles.ns_splitter_resizing);
|
|
30
158
|
}
|
|
31
159
|
|
|
32
160
|
handleMouseUp()
|
|
33
161
|
{
|
|
34
|
-
|
|
162
|
+
window.removeEventListener("mousemove", this.handleMouseMove);
|
|
163
|
+
window.removeEventListener("mouseup", this.handleMouseUp);
|
|
35
164
|
this.SplitterRef.current?.classList.remove(Styles.ns_splitter_resizing);
|
|
36
|
-
|
|
165
|
+
|
|
166
|
+
let master_el = this.MasterPaneRef.current;
|
|
167
|
+
|
|
168
|
+
if (master_el)
|
|
169
|
+
this.saveStoredHeight(master_el.offsetHeight);
|
|
37
170
|
}
|
|
38
171
|
|
|
39
172
|
handleMouseMove(event: MouseEvent)
|
|
@@ -44,17 +177,15 @@ export class NSSplitter extends Component<NSSplitterProps>
|
|
|
44
177
|
{
|
|
45
178
|
this.AnimationFrame = null;
|
|
46
179
|
|
|
47
|
-
let splitter_el = this.SplitterRef.current;
|
|
48
180
|
let master_el = this.MasterPaneRef.current;
|
|
49
181
|
|
|
50
|
-
if (!
|
|
182
|
+
if (!master_el) return;
|
|
51
183
|
|
|
52
|
-
let
|
|
53
|
-
let
|
|
54
|
-
master_el_height = +Math.max(238, Math.min(master_el_height, 538)).toFixed(0);
|
|
184
|
+
let master_top = master_el.getBoundingClientRect().top;
|
|
185
|
+
let height = Math.max(MIN_MASTER_HEIGHT, event.clientY - this.DragOffset - master_top);
|
|
55
186
|
|
|
56
|
-
|
|
57
|
-
|
|
187
|
+
this.applyHeight(height);
|
|
188
|
+
this.HasUserResized = true;
|
|
58
189
|
});
|
|
59
190
|
}
|
|
60
191
|
|
|
@@ -76,16 +207,14 @@ export class NSSplitter extends Component<NSSplitterProps>
|
|
|
76
207
|
this.props.detail_content &&
|
|
77
208
|
<>
|
|
78
209
|
<button
|
|
210
|
+
ref={this.GutterRef}
|
|
79
211
|
className={Styles.ns_splitter_gutter}
|
|
80
212
|
onMouseDown={this.handleMouseDown}
|
|
81
213
|
>
|
|
82
214
|
<span className={Styles.ns_splitter_gutter_handle}></span>
|
|
83
215
|
</button>
|
|
84
216
|
|
|
85
|
-
<div
|
|
86
|
-
ref={this.DetailPaneRef}
|
|
87
|
-
className={Styles.ns_splitter_detail}
|
|
88
|
-
>
|
|
217
|
+
<div className={Styles.ns_splitter_detail}>
|
|
89
218
|
{this.props.detail_content}
|
|
90
219
|
</div>
|
|
91
220
|
</>
|