namirasoft-site-react 1.4.467 → 1.4.469
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/App.d.ts +0 -1
- package/dist/App.js +29 -23
- package/dist/App.js.map +1 -1
- package/dist/components/NSSplitter.d.ts +16 -0
- package/dist/components/NSSplitter.js +50 -0
- package/dist/components/NSSplitter.js.map +1 -0
- package/dist/components/NSSplitter.module.css +73 -0
- package/dist/components/NSTable.d.ts +9 -5
- package/dist/components/NSTable.js +74 -29
- package/dist/components/NSTable.js.map +1 -1
- package/dist/components/NSTable.module.css +65 -39
- package/dist/formatter/BaseURLImageFormatter.js +3 -3
- package/dist/formatter/BaseURLImageFormatter.js.map +1 -1
- package/dist/formatter/EmailFormatter.js +1 -1
- package/dist/formatter/EmailFormatter.js.map +1 -1
- package/package.json +2 -2
- package/src/App.tsx +38 -35
- package/src/components/NSSplitter.module.css +73 -0
- package/src/components/NSSplitter.tsx +99 -0
- package/src/components/NSTable.module.css +65 -39
- package/src/components/NSTable.tsx +141 -73
- package/src/formatter/BaseURLImageFormatter.tsx +2 -5
- package/src/formatter/EmailFormatter.tsx +1 -1
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
.ns_table {
|
|
2
2
|
display: flex;
|
|
3
3
|
flex-direction: column;
|
|
4
|
-
color: rgba(20, 27, 92, 1);
|
|
5
4
|
overflow-x: auto;
|
|
5
|
+
color: rgba(20, 27, 92);
|
|
6
6
|
}
|
|
7
7
|
|
|
8
8
|
.ns_search_input {
|
|
@@ -23,7 +23,6 @@
|
|
|
23
23
|
z-index: -1;
|
|
24
24
|
}
|
|
25
25
|
|
|
26
|
-
|
|
27
26
|
.ns_table thead {
|
|
28
27
|
clip: rect(0 0 0 0);
|
|
29
28
|
position: fixed;
|
|
@@ -37,12 +36,12 @@
|
|
|
37
36
|
transition: all 0.2s ease-in-out;
|
|
38
37
|
}
|
|
39
38
|
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
}
|
|
39
|
+
.ns_table tbody tr {
|
|
40
|
+
cursor: pointer;
|
|
41
|
+
}
|
|
43
42
|
|
|
44
43
|
.ns_table td {
|
|
45
|
-
display:
|
|
44
|
+
display: flex;
|
|
46
45
|
flex-direction: row;
|
|
47
46
|
gap: 16px;
|
|
48
47
|
margin: 8px;
|
|
@@ -52,7 +51,7 @@
|
|
|
52
51
|
align-items: center;
|
|
53
52
|
color: #000;
|
|
54
53
|
height: max-content;
|
|
55
|
-
max-height:
|
|
54
|
+
max-height: 3rem;
|
|
56
55
|
line-clamp: 2;
|
|
57
56
|
-webkit-line-clamp: 2;
|
|
58
57
|
-webkit-box-orient: vertical;
|
|
@@ -70,20 +69,20 @@
|
|
|
70
69
|
min-width: 30%;
|
|
71
70
|
}
|
|
72
71
|
|
|
73
|
-
.ns_tbody tr:nth-child(odd)
|
|
74
|
-
background-color:
|
|
72
|
+
.ns_tbody tr:nth-child(odd) {
|
|
73
|
+
background-color: #f5f5f5;
|
|
75
74
|
}
|
|
76
75
|
|
|
77
|
-
.ns_tbody tr:nth-child(even)
|
|
78
|
-
background-color:
|
|
76
|
+
.ns_tbody tr:nth-child(even) {
|
|
77
|
+
background-color: #ffffff;
|
|
79
78
|
}
|
|
80
79
|
|
|
81
|
-
.ns_tbody tr:
|
|
82
|
-
background-color:
|
|
80
|
+
.ns_tbody tr:hover {
|
|
81
|
+
background-color: rgb(184, 190, 240, 0.32);
|
|
83
82
|
}
|
|
84
83
|
|
|
85
|
-
.ns_tbody tr
|
|
86
|
-
background-color:
|
|
84
|
+
.ns_tbody tr.ns_selected {
|
|
85
|
+
background-color: rgb(184, 190, 240, 0.64);
|
|
87
86
|
}
|
|
88
87
|
|
|
89
88
|
.ns_table_footer {
|
|
@@ -150,13 +149,7 @@
|
|
|
150
149
|
gap: 16px;
|
|
151
150
|
}
|
|
152
151
|
|
|
153
|
-
@media screen and (
|
|
154
|
-
.ns_table tr {
|
|
155
|
-
border-radius: 8px;
|
|
156
|
-
}
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
@media screen and (max-width: 992px) {
|
|
152
|
+
@media screen and (max-width: 991px) {
|
|
160
153
|
.ns_table td {
|
|
161
154
|
width: auto;
|
|
162
155
|
}
|
|
@@ -164,48 +157,81 @@
|
|
|
164
157
|
|
|
165
158
|
@media screen and (min-width: 992px) {
|
|
166
159
|
.ns_table {
|
|
167
|
-
|
|
168
|
-
background-color: white;
|
|
169
|
-
display: flex;
|
|
160
|
+
border-radius: 0.5rem;
|
|
170
161
|
justify-content: center;
|
|
162
|
+
color: #000;
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
.ns_table::-webkit-scrollbar {
|
|
166
|
+
height: 0.375rem;
|
|
167
|
+
border-radius: 0.25rem;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
.ns_table::-webkit-scrollbar-track {
|
|
171
|
+
border-radius: 0.25rem;
|
|
172
|
+
background: #f0f0f0;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
.ns_table::-webkit-scrollbar-thumb {
|
|
176
|
+
border-radius: 0.25rem;
|
|
177
|
+
background: #888;
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
.ns_table::-webkit-scrollbar-thumb:hover {
|
|
181
|
+
background: #555;
|
|
171
182
|
}
|
|
172
183
|
|
|
173
184
|
.ns_table thead {
|
|
174
185
|
position: static;
|
|
175
|
-
|
|
186
|
+
min-width: max-content;
|
|
176
187
|
border-top-left-radius: 8px;
|
|
177
188
|
border-top-right-radius: 8px;
|
|
178
|
-
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
.ns_table thead tr {
|
|
192
|
+
background-color: rgba(20, 27, 92);
|
|
179
193
|
}
|
|
180
194
|
|
|
181
195
|
.ns_table tbody {
|
|
182
|
-
|
|
196
|
+
max-height: 32rem;
|
|
183
197
|
min-width: max-content;
|
|
198
|
+
background-color: #fff;
|
|
184
199
|
}
|
|
185
200
|
|
|
186
201
|
.ns_table tr {
|
|
187
|
-
display: grid;
|
|
188
|
-
grid-auto-flow: column;
|
|
189
|
-
grid-auto-columns: max-content;
|
|
190
|
-
padding: 16px 8px;
|
|
191
202
|
margin: 0;
|
|
203
|
+
border: 1px solid transparent;
|
|
192
204
|
border-radius: 0;
|
|
193
|
-
|
|
194
|
-
|
|
205
|
+
padding: 4px 8px;
|
|
206
|
+
display: grid;
|
|
195
207
|
align-items: center;
|
|
208
|
+
grid-auto-flow: column;
|
|
209
|
+
grid-auto-columns: max-content;
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
.ns_table tr.ns_selected,
|
|
213
|
+
.ns_table tr.ns_last_selected {
|
|
214
|
+
border-color: rgba(20, 27, 92);
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
.ns_table tr.ns_selected+tr,
|
|
218
|
+
.ns_table tr.ns_last_selected+tr {
|
|
219
|
+
border-top-color: transparent;
|
|
196
220
|
}
|
|
197
221
|
|
|
198
222
|
.ns_table th {
|
|
199
|
-
font-size: 16px;
|
|
200
|
-
font-weight: 300;
|
|
201
|
-
color: #ffffff;
|
|
202
|
-
padding: 0;
|
|
203
223
|
margin: 8px;
|
|
224
|
+
padding: 0;
|
|
225
|
+
font-size: 16px;
|
|
226
|
+
font-weight: 500;
|
|
227
|
+
line-height: 1.5rem;
|
|
228
|
+
color: #fff;
|
|
204
229
|
}
|
|
205
230
|
|
|
206
231
|
.ns_table td {
|
|
207
|
-
text-align: left;
|
|
208
232
|
align-items: flex-start;
|
|
233
|
+
line-height: 1.5rem;
|
|
234
|
+
text-align: left;
|
|
209
235
|
}
|
|
210
236
|
|
|
211
237
|
.ns_table td::before {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { jsx as _jsx,
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { BaseColumnFormatter } from "./BaseColumnFormatter";
|
|
3
3
|
export class BaseURLImageFormatter extends BaseColumnFormatter {
|
|
4
4
|
constructor(width = "250px") {
|
|
@@ -7,8 +7,8 @@ export class BaseURLImageFormatter extends BaseColumnFormatter {
|
|
|
7
7
|
}
|
|
8
8
|
format(value, _, __, printable) {
|
|
9
9
|
if (!printable) {
|
|
10
|
-
return (_jsxs("div", { style: { display: "flex", alignItems: "center" }, children: [value.image.url &&
|
|
11
|
-
|
|
10
|
+
return (_jsxs("div", { style: { display: "flex", alignItems: "center", gap: "4px" }, children: [value.image.url &&
|
|
11
|
+
_jsx("img", { src: value.image.url, alt: value.image.alt, style: { width: "20px", height: "20px" } }), _jsx("a", { href: value.href, target: "_blank", rel: "noreferrer", style: { width: "max-content" }, children: value.text })] }));
|
|
12
12
|
}
|
|
13
13
|
return value.text;
|
|
14
14
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"BaseURLImageFormatter.js","sourceRoot":"","sources":["../../src/formatter/BaseURLImageFormatter.tsx"],"names":[],"mappings":";AACA,OAAO,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAE5D,MAAM,OAAO,qBAAsB,SAAQ,mBAAmB;IAE1D,YAAY,QAAgB,OAAO;QAE/B,KAAK,EAAE,CAAC;QACR,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;IACvB,CAAC;IACQ,MAAM,CAAC,KAIf,EAAE,CAAmB,EAAE,EAAsB,EAAE,SAAmB;QAE/D,IAAI,CAAC,SAAS,EACd,CAAC;YACG,OAAO,CACH,eAAK,KAAK,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,QAAQ,EAAE,
|
|
1
|
+
{"version":3,"file":"BaseURLImageFormatter.js","sourceRoot":"","sources":["../../src/formatter/BaseURLImageFormatter.tsx"],"names":[],"mappings":";AACA,OAAO,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAE5D,MAAM,OAAO,qBAAsB,SAAQ,mBAAmB;IAE1D,YAAY,QAAgB,OAAO;QAE/B,KAAK,EAAE,CAAC;QACR,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;IACvB,CAAC;IACQ,MAAM,CAAC,KAIf,EAAE,CAAmB,EAAE,EAAsB,EAAE,SAAmB;QAE/D,IAAI,CAAC,SAAS,EACd,CAAC;YACG,OAAO,CACH,eAAK,KAAK,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,QAAQ,EAAE,GAAG,EAAE,KAAK,EAAE,aAEzD,KAAK,CAAC,KAAK,CAAC,GAAG;wBACf,cAAK,GAAG,EAAE,KAAK,CAAC,KAAK,CAAC,GAAG,EAAE,GAAG,EAAE,KAAK,CAAC,KAAK,CAAC,GAAG,EAAE,KAAK,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,GAAI,EAEjG,YAAG,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,MAAM,EAAC,QAAQ,EAAC,GAAG,EAAC,YAAY,EAAC,KAAK,EAAE,EAAE,KAAK,EAAE,aAAa,EAAE,YAAG,KAAK,CAAC,IAAI,GAAK,IACpG,CACV,CAAC;QACN,CAAC;QACD,OAAO,KAAK,CAAC,IAAI,CAAC;IACtB,CAAC;CACJ"}
|
|
@@ -10,7 +10,7 @@ export class EmailFormatter extends BaseColumnFormatter {
|
|
|
10
10
|
format(value, column, row, printable) {
|
|
11
11
|
return this.formatter.format({
|
|
12
12
|
text: value,
|
|
13
|
-
href: `
|
|
13
|
+
href: `mailto:${value}`,
|
|
14
14
|
image: { url: "https://static.namirasoft.com/image/concept/type/email.png", alt: "phone" }
|
|
15
15
|
}, column, row, printable);
|
|
16
16
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"EmailFormatter.js","sourceRoot":"","sources":["../../src/formatter/EmailFormatter.tsx"],"names":[],"mappings":"AACA,OAAO,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAC5D,OAAO,EAAE,qBAAqB,EAAE,MAAM,yBAAyB,CAAC;AAEhE,MAAM,OAAO,cAAe,SAAQ,mBAAmB;IAGnD,YAAY,QAAgB,OAAO;QAE/B,KAAK,EAAE,CAAC;QAHJ,cAAS,GAA0B,IAAI,qBAAqB,EAAE,CAAC;QAInE,IAAI,CAAC,iBAAiB,GAAG,IAAI,CAAC;QAC9B,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;IACvB,CAAC;IACQ,MAAM,CAAC,KAAU,EAAE,MAAuB,EAAE,GAAsB,EAAE,SAAkB;QAE3F,OAAO,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC;YACzB,IAAI,EAAE,KAAK;YACX,IAAI,EAAE,
|
|
1
|
+
{"version":3,"file":"EmailFormatter.js","sourceRoot":"","sources":["../../src/formatter/EmailFormatter.tsx"],"names":[],"mappings":"AACA,OAAO,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAC5D,OAAO,EAAE,qBAAqB,EAAE,MAAM,yBAAyB,CAAC;AAEhE,MAAM,OAAO,cAAe,SAAQ,mBAAmB;IAGnD,YAAY,QAAgB,OAAO;QAE/B,KAAK,EAAE,CAAC;QAHJ,cAAS,GAA0B,IAAI,qBAAqB,EAAE,CAAC;QAInE,IAAI,CAAC,iBAAiB,GAAG,IAAI,CAAC;QAC9B,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;IACvB,CAAC;IACQ,MAAM,CAAC,KAAU,EAAE,MAAuB,EAAE,GAAsB,EAAE,SAAkB;QAE3F,OAAO,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC;YACzB,IAAI,EAAE,KAAK;YACX,IAAI,EAAE,UAAU,KAAK,EAAE;YACvB,KAAK,EAAE,EAAE,GAAG,EAAE,4DAA4D,EAAE,GAAG,EAAE,OAAO,EAAE;SAC7F,EAAE,MAAM,EAAE,GAAG,EAAE,SAAS,CAAC,CAAC;IAC/B,CAAC;CACJ"}
|
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.469",
|
|
12
12
|
"author": "Amir Abolhasani",
|
|
13
13
|
"license": "MIT",
|
|
14
14
|
"main": "./dist/main.js",
|
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
"copy": "copyfiles -u 1 src/**/*.html src/**/*.css src/**/*.svg src/**/*.png src/**/*.jpg dist/"
|
|
22
22
|
},
|
|
23
23
|
"dependencies": {
|
|
24
|
-
"@ant-design/charts": "^2.6.
|
|
24
|
+
"@ant-design/charts": "^2.6.5",
|
|
25
25
|
"@babel/plugin-proposal-private-property-in-object": "^7.21.11",
|
|
26
26
|
"@types/node": "^24.5.2",
|
|
27
27
|
"@types/react": "^18.3.12",
|
package/src/App.tsx
CHANGED
|
@@ -1,17 +1,14 @@
|
|
|
1
1
|
import 'bootstrap/dist/css/bootstrap.min.css';
|
|
2
|
-
import { Component
|
|
2
|
+
import { Component } from 'react';
|
|
3
3
|
import './App.css';
|
|
4
|
-
import { NSBoxEntity } from './components/NSBoxEntity';
|
|
5
4
|
import { NSLayout } from './components/NSLayout';
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
5
|
+
import { EmailFormatter, IntegerFormatter, NSTable, PhoneFormatter, StringFormatter, StringFormatterSizeType } from './main';
|
|
6
|
+
import { NSSplitter } from './components/NSSplitter';
|
|
8
7
|
|
|
9
8
|
interface AppProps { }
|
|
10
9
|
|
|
11
10
|
export class App extends Component<AppProps>
|
|
12
11
|
{
|
|
13
|
-
private Box = createRef<NSBoxEntity<{ id: string, value: string }>>();
|
|
14
|
-
|
|
15
12
|
override render()
|
|
16
13
|
{
|
|
17
14
|
return (
|
|
@@ -34,37 +31,43 @@ export class App extends Component<AppProps>
|
|
|
34
31
|
notifier={{} as any}
|
|
35
32
|
scope=''
|
|
36
33
|
>
|
|
37
|
-
<
|
|
38
|
-
|
|
39
|
-
<
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
<NSButtonBlue
|
|
60
|
-
title='Set Value'
|
|
61
|
-
onClick={{
|
|
62
|
-
action: () => this.Box.current?.setValue(["Milad"]),
|
|
63
|
-
showLoading: false
|
|
34
|
+
<NSSplitter
|
|
35
|
+
master_content={
|
|
36
|
+
<NSTable<{ id: string, first_name: string, last_name: string, age: number, phone: string, email: string, bio: string }>
|
|
37
|
+
name='users'
|
|
38
|
+
checkbox
|
|
39
|
+
getRows={async () =>
|
|
40
|
+
{
|
|
41
|
+
return {
|
|
42
|
+
count: 10,
|
|
43
|
+
rows: [
|
|
44
|
+
{ id: "a1", first_name: "Amin", last_name: "Pasban", age: 27, phone: "09117579093", email: "amin.cj0077@gmail.com", bio: "Loves literature and writing, constantly seeking." },
|
|
45
|
+
{ id: "a2", first_name: "Sara", last_name: "Moradi", age: 24, phone: "09123456781", email: "sara.moradi@example.com", bio: "Passionate about design and technology, enjoys." },
|
|
46
|
+
{ id: "a3", first_name: "Reza", last_name: "Karimi", age: 31, phone: "09129876542", email: "reza.karimi@example.com", bio: "Software engineer with experience in backend system." },
|
|
47
|
+
{ id: "a4", first_name: "Niloofar", last_name: "Ahmadi", age: 29, phone: "09351234567", email: "niloofar.ahmadi@example.com", bio: "Enthusiastic about art and photography." },
|
|
48
|
+
{ id: "a5", first_name: "Hossein", last_name: "Bagheri", age: 35, phone: "09134561234", email: "hossein.bagheri@example.com", bio: "Expert in finance and investment, passionate about." },
|
|
49
|
+
{ id: "a6", first_name: "Maryam", last_name: "Shahbazi", age: 26, phone: "09141239876", email: "maryam.shahbazi@example.com", bio: "Loves literature and writing, constantly seeking." },
|
|
50
|
+
{ id: "a7", first_name: "Ali", last_name: "Rostami", age: 28, phone: "09151237654", email: "ali.rostami@example.com", bio: "Tech enthusiast and full-stack developer, enjoys contributing." },
|
|
51
|
+
{ id: "a8", first_name: "Fatemeh", last_name: "Jafari", age: 30, phone: "09361234589", email: "fatemeh.jafari@example.com", bio: "Interested in psychology and self-development, spends." },
|
|
52
|
+
{ id: "a9", first_name: "Mohammad", last_name: "Esfandiari", age: 33, phone: "09162348752", email: "mohammad.esfandiari@example.com", bio: "Specialized in marketing strategies, creative thinker." },
|
|
53
|
+
{ id: "b1", first_name: "Elham", last_name: "Khosravi", age: 25, phone: "09203456781", email: "elham.khosravi@example.com", bio: "Graphic designer with a flair for modern art." }
|
|
54
|
+
]
|
|
55
|
+
}
|
|
64
56
|
}}
|
|
57
|
+
getRowKey={(item) => item.value.id}
|
|
58
|
+
columns={[
|
|
59
|
+
{ index: 0, name: "id", text: "ID", table: { name: "users", text: "users" }, formatter: new StringFormatter(StringFormatterSizeType.Word) },
|
|
60
|
+
{ index: 0, name: "first_name", text: "First Name", table: { name: "users", text: "users" }, formatter: new StringFormatter(StringFormatterSizeType.TwoWords) },
|
|
61
|
+
{ index: 0, name: "last_name", text: "Last Name", table: { name: "users", text: "users" }, formatter: new StringFormatter(StringFormatterSizeType.TwoWords) },
|
|
62
|
+
{ index: 0, name: "age", text: "Age", table: { name: "users", text: "users" }, formatter: new IntegerFormatter() },
|
|
63
|
+
{ index: 0, name: "phone", text: "Phone Number", table: { name: "users", text: "users" }, formatter: new PhoneFormatter() },
|
|
64
|
+
{ index: 0, name: "email", text: "Email Address", table: { name: "users", text: "users" }, formatter: new EmailFormatter() },
|
|
65
|
+
{ index: 0, name: "bio", text: "Bio", table: { name: "users", text: "users" }, formatter: new StringFormatter(StringFormatterSizeType.Description) },
|
|
66
|
+
]}
|
|
65
67
|
/>
|
|
66
|
-
|
|
67
|
-
|
|
68
|
+
}
|
|
69
|
+
detail_content={<></>}
|
|
70
|
+
/>
|
|
68
71
|
</NSLayout>
|
|
69
72
|
);
|
|
70
73
|
}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
.ns_splitter_gutter {
|
|
2
|
+
display: none;
|
|
3
|
+
}
|
|
4
|
+
|
|
5
|
+
@media only screen and (min-width: 992px) {
|
|
6
|
+
.ns_splitter {
|
|
7
|
+
height: calc(100dvh - 5.5rem);
|
|
8
|
+
min-height: 40rem;
|
|
9
|
+
border: 1px solid #e1e1e1;
|
|
10
|
+
border-radius: 1rem;
|
|
11
|
+
display: flex;
|
|
12
|
+
flex-direction: column;
|
|
13
|
+
background-color: #fff;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
.ns_splitter.ns_splitter_resizing,
|
|
17
|
+
.ns_splitter.ns_splitter_resizing * {
|
|
18
|
+
cursor: row-resize !important;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
.ns_splitter_master,
|
|
22
|
+
.ns_splitter_detail {
|
|
23
|
+
margin: 0.5rem 0;
|
|
24
|
+
padding: 0 0.5rem;
|
|
25
|
+
flex-grow: 1;
|
|
26
|
+
flex-basis: calc(50% - 0.25rem);
|
|
27
|
+
overflow: auto;
|
|
28
|
+
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
.ns_splitter_master::-webkit-scrollbar,
|
|
32
|
+
.ns_splitter_detail::-webkit-scrollbar {
|
|
33
|
+
width: 0.375rem;
|
|
34
|
+
border-radius: 0.25rem;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
.ns_splitter_master::-webkit-scrollbar-track,
|
|
38
|
+
.ns_splitter_detail::-webkit-scrollbar-track {
|
|
39
|
+
border-radius: 0.25rem;
|
|
40
|
+
background: #f0f0f0;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
.ns_splitter_master::-webkit-scrollbar-thumb,
|
|
44
|
+
.ns_splitter_detail::-webkit-scrollbar-thumb {
|
|
45
|
+
border-radius: 0.25rem;
|
|
46
|
+
background: #888;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
.ns_splitter_master::-webkit-scrollbar-thumb:hover,
|
|
50
|
+
.ns_splitter_detail::-webkit-scrollbar-thumb:hover {
|
|
51
|
+
background: #555;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
.ns_splitter_gutter {
|
|
55
|
+
position: relative;
|
|
56
|
+
width: 100%;
|
|
57
|
+
height: 0.25rem;
|
|
58
|
+
outline: none;
|
|
59
|
+
border: none;
|
|
60
|
+
padding: 0;
|
|
61
|
+
display: flex;
|
|
62
|
+
justify-content: center;
|
|
63
|
+
background-color: #e1e1e1;
|
|
64
|
+
cursor: row-resize !important;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
.ns_splitter_gutter_handle {
|
|
68
|
+
width: 1.5rem;
|
|
69
|
+
height: 0.25rem;
|
|
70
|
+
border-radius: 0.125rem;
|
|
71
|
+
background-color: #9a9a9a;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
import { Component, createRef, ReactNode } from "react";
|
|
2
|
+
import Styles from "./NSSplitter.module.css";
|
|
3
|
+
|
|
4
|
+
export interface NSSplitterProps
|
|
5
|
+
{
|
|
6
|
+
master_content?: ReactNode;
|
|
7
|
+
detail_content?: ReactNode;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export class NSSplitter extends Component<NSSplitterProps>
|
|
11
|
+
{
|
|
12
|
+
private SplitterRef = createRef<HTMLElement>();
|
|
13
|
+
private MasterPaneRef = createRef<HTMLDivElement>();
|
|
14
|
+
private DetailPaneRef = createRef<HTMLDivElement>();
|
|
15
|
+
private AnimationFrame: number | null = null;
|
|
16
|
+
|
|
17
|
+
constructor(props: NSSplitterProps)
|
|
18
|
+
{
|
|
19
|
+
super(props);
|
|
20
|
+
this.handleMouseDown = this.handleMouseDown.bind(this);
|
|
21
|
+
this.handleMouseUp = this.handleMouseUp.bind(this);
|
|
22
|
+
this.handleMouseMove = this.handleMouseMove.bind(this);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
handleMouseDown()
|
|
26
|
+
{
|
|
27
|
+
this.SplitterRef.current?.addEventListener("mousemove", this.handleMouseMove);
|
|
28
|
+
this.SplitterRef.current?.classList.add(Styles.ns_splitter_resizing);
|
|
29
|
+
window.addEventListener("mouseup", this.handleMouseUp);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
handleMouseUp()
|
|
33
|
+
{
|
|
34
|
+
this.SplitterRef.current?.removeEventListener("mousemove", this.handleMouseMove);
|
|
35
|
+
this.SplitterRef.current?.classList.remove(Styles.ns_splitter_resizing);
|
|
36
|
+
window.removeEventListener("mouseup", this.handleMouseUp)
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
handleMouseMove(event: MouseEvent)
|
|
40
|
+
{
|
|
41
|
+
if (this.AnimationFrame) return;
|
|
42
|
+
|
|
43
|
+
this.AnimationFrame = requestAnimationFrame(() =>
|
|
44
|
+
{
|
|
45
|
+
this.AnimationFrame = null;
|
|
46
|
+
|
|
47
|
+
let splitter_el = this.SplitterRef.current;
|
|
48
|
+
let master_el = this.MasterPaneRef.current;
|
|
49
|
+
let detail_el = this.DetailPaneRef.current;
|
|
50
|
+
|
|
51
|
+
if (!splitter_el || !master_el || !detail_el) return;
|
|
52
|
+
|
|
53
|
+
let delta = event.clientY - master_el.getBoundingClientRect().bottom;
|
|
54
|
+
|
|
55
|
+
let master_el_percent = ((master_el.clientHeight + delta) * 100) / (splitter_el.clientHeight - 16);
|
|
56
|
+
master_el_percent = Math.max(20, Math.min(master_el_percent, 80));
|
|
57
|
+
master_el_percent = +master_el_percent.toFixed(2);
|
|
58
|
+
|
|
59
|
+
master_el.style.flexBasis = `calc(${master_el_percent}% - 4px)`;
|
|
60
|
+
detail_el.style.flexBasis = `calc(${100 - master_el_percent}% - 4px)`;
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
override render()
|
|
65
|
+
{
|
|
66
|
+
return (
|
|
67
|
+
<section
|
|
68
|
+
ref={this.SplitterRef}
|
|
69
|
+
className={Styles.ns_splitter}
|
|
70
|
+
>
|
|
71
|
+
<div
|
|
72
|
+
ref={this.MasterPaneRef}
|
|
73
|
+
className={Styles.ns_splitter_master}
|
|
74
|
+
>
|
|
75
|
+
{this.props.master_content}
|
|
76
|
+
</div>
|
|
77
|
+
|
|
78
|
+
{
|
|
79
|
+
this.props.detail_content &&
|
|
80
|
+
<>
|
|
81
|
+
<button
|
|
82
|
+
className={Styles.ns_splitter_gutter}
|
|
83
|
+
onMouseDown={this.handleMouseDown}
|
|
84
|
+
>
|
|
85
|
+
<span className={Styles.ns_splitter_gutter_handle}></span>
|
|
86
|
+
</button>
|
|
87
|
+
|
|
88
|
+
<div
|
|
89
|
+
ref={this.DetailPaneRef}
|
|
90
|
+
className={Styles.ns_splitter_detail}
|
|
91
|
+
>
|
|
92
|
+
{this.props.detail_content}
|
|
93
|
+
</div>
|
|
94
|
+
</>
|
|
95
|
+
}
|
|
96
|
+
</section>
|
|
97
|
+
)
|
|
98
|
+
}
|
|
99
|
+
}
|