lupine.components 1.1.13 → 1.1.15
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/README.md +3 -3
- package/package.json +42 -42
- package/src/components/action-sheet.tsx +419 -419
- package/src/components/button-push-animation.tsx +147 -138
- package/src/components/button.tsx +55 -55
- package/src/components/desktop-footer.tsx +17 -17
- package/src/components/desktop-header.tsx +52 -52
- package/src/components/drag-refresh.tsx +129 -129
- package/src/components/editable-label.tsx +83 -83
- package/src/components/float-window.tsx +233 -233
- package/src/components/grid.tsx +18 -18
- package/src/components/html-load.tsx +41 -41
- package/src/components/html-var.tsx +81 -81
- package/src/components/index.ts +43 -44
- package/src/components/input-with-title.tsx +24 -24
- package/src/components/link-item.tsx +13 -13
- package/src/components/link-list.tsx +62 -62
- package/src/components/menu-bar.tsx +219 -219
- package/src/components/menu-item-props.tsx +13 -13
- package/src/components/menu-sidebar.tsx +325 -318
- package/src/components/message-box.tsx +44 -44
- package/src/components/meta-data.tsx +36 -36
- package/src/components/meta-description.tsx +12 -12
- package/src/components/mobile-components/icon-menu-item-props.ts +6 -6
- package/src/components/mobile-components/index.ts +8 -9
- package/src/components/mobile-components/mobile-footer-menu.tsx +95 -95
- package/src/components/mobile-components/mobile-header-component.tsx +101 -101
- package/src/components/mobile-components/mobile-header-title-icon.tsx +109 -101
- package/src/components/mobile-components/mobile-header-with-back.tsx +127 -117
- package/src/components/mobile-components/mobile-side-menu.tsx +154 -154
- package/src/components/mobile-components/mobile-top-sys-icon.tsx +18 -18
- package/src/components/mobile-components/mobile-top-sys-menu.tsx +62 -62
- package/src/components/modal.tsx +33 -33
- package/src/components/notice-message.tsx +118 -118
- package/src/components/page-title.tsx +6 -6
- package/src/components/paging-link.tsx +175 -175
- package/src/components/panel.tsx +21 -21
- package/src/components/popup-menu.tsx +289 -289
- package/src/components/progress.tsx +91 -91
- package/src/components/radio-label-component.tsx +36 -36
- package/src/components/redirect.tsx +19 -19
- package/src/components/resizable-splitter.tsx +128 -128
- package/src/components/select-angle-component.tsx +127 -127
- package/src/components/select-with-title.tsx +37 -37
- package/src/components/slide-tab-component.tsx +144 -149
- package/src/components/spinner.tsx +106 -100
- package/src/components/stars-component.tsx +66 -66
- package/src/components/svg.tsx +24 -24
- package/src/components/tabs.tsx +279 -279
- package/src/components/text-glow.tsx +37 -37
- package/src/components/text-scale.tsx +42 -42
- package/src/components/text-wave.tsx +55 -55
- package/src/components/theme-selector.tsx +28 -28
- package/src/components/toggle-base.tsx +285 -269
- package/src/components/toggle-switch.tsx +160 -160
- package/src/frames/index.ts +3 -3
- package/src/frames/responsive-frame.tsx +83 -83
- package/src/frames/slider-frame.tsx +111 -111
- package/src/frames/top-frame.tsx +30 -30
- package/src/index.ts +5 -5
- package/src/lib/back-action-helper.ts +54 -54
- package/src/lib/base62.ts +23 -23
- package/src/lib/blob-utils.ts +23 -23
- package/src/lib/calculate-text-width.ts +13 -13
- package/src/lib/date-utils.ts +317 -317
- package/src/lib/deep-merge.ts +37 -37
- package/src/lib/document-ready.ts +34 -34
- package/src/lib/dom-utils.ts +32 -32
- package/src/lib/download-file.ts +118 -118
- package/src/lib/download-link.ts +12 -12
- package/src/lib/download-stream.ts +19 -19
- package/src/lib/drag-util.ts +118 -118
- package/src/lib/dynamical-load.ts +134 -134
- package/src/lib/encode-html.ts +27 -27
- package/src/lib/find-parent-tag.ts +8 -8
- package/src/lib/format-bytes.ts +11 -11
- package/src/lib/index.ts +24 -24
- package/src/lib/lite-dom.ts +225 -225
- package/src/lib/message-hub.ts +103 -104
- package/src/lib/observable.ts +188 -188
- package/src/lib/path-utils.ts +42 -42
- package/src/lib/promise-timeout.ts +1 -1
- package/src/lib/simple-storage.ts +40 -40
- package/src/lib/stop-propagation.ts +7 -7
- package/src/lib/upload-file.ts +101 -101
- package/src/styles/base-themes.ts +17 -17
- package/src/styles/dark-themes.ts +99 -99
- package/src/styles/index.ts +5 -5
- package/src/styles/light-themes.ts +106 -106
- package/src/styles/media-query.ts +93 -93
- package/src/styles/shared-themes.ts +57 -57
- package/tsconfig.json +113 -113
|
@@ -1,118 +1,118 @@
|
|
|
1
|
-
import { CssProps, bindGlobalStyle } from 'lupine.web';
|
|
2
|
-
/**
|
|
3
|
-
How to use:
|
|
4
|
-
Notification.sendMessage(message);
|
|
5
|
-
*/
|
|
6
|
-
export enum NotificationColor {
|
|
7
|
-
Success = 'var(--success-bg-color)',
|
|
8
|
-
Info = 'var(--info-bg-color)',
|
|
9
|
-
Warning = 'var(--warning-bg-color)',
|
|
10
|
-
Error = 'var(--error-bg-color)',
|
|
11
|
-
}
|
|
12
|
-
export const notificationColorFromValue = (value: string) => {
|
|
13
|
-
switch (value) {
|
|
14
|
-
case 'Success':
|
|
15
|
-
return NotificationColor.Success;
|
|
16
|
-
case 'Info':
|
|
17
|
-
return NotificationColor.Info;
|
|
18
|
-
case 'Warning':
|
|
19
|
-
return NotificationColor.Warning;
|
|
20
|
-
case 'Error':
|
|
21
|
-
return NotificationColor.Error;
|
|
22
|
-
}
|
|
23
|
-
return NotificationColor.Info;
|
|
24
|
-
};
|
|
25
|
-
export class NotificationMessage {
|
|
26
|
-
// public static readonly Color = NotificationColor;
|
|
27
|
-
|
|
28
|
-
private static initialized = false;
|
|
29
|
-
private static container: HTMLElement;
|
|
30
|
-
|
|
31
|
-
static init() {
|
|
32
|
-
/* styles for resizable splitter */
|
|
33
|
-
const css: CssProps = {
|
|
34
|
-
position: 'fixed',
|
|
35
|
-
top: 0,
|
|
36
|
-
right: 0,
|
|
37
|
-
height: 'auto',
|
|
38
|
-
overflowY: 'auto',
|
|
39
|
-
maxHeight: '100%',
|
|
40
|
-
width: '100%',
|
|
41
|
-
maxWidth: '400px',
|
|
42
|
-
// cursor: 'pointer',
|
|
43
|
-
// backgroundColor: '#fefefe',
|
|
44
|
-
padding: '0 10px',
|
|
45
|
-
zIndex: 'var(--layer-notice)',
|
|
46
|
-
// borderRadius: '6px',
|
|
47
|
-
// boxShadow: '0px 0px 2px #000',
|
|
48
|
-
'>div': {
|
|
49
|
-
color: 'var(--notice-color-with-bg)',
|
|
50
|
-
padding: '10px 8px',
|
|
51
|
-
margin: '16px 0',
|
|
52
|
-
borderRadius: '6px',
|
|
53
|
-
boxShadow: 'var(--cover-box-shadow)', //'3px 3px 8px #767676',
|
|
54
|
-
transition: 'all 0.5s',
|
|
55
|
-
transform: 'scale(0.1)',
|
|
56
|
-
opacity: 0,
|
|
57
|
-
},
|
|
58
|
-
'.close-btn': {
|
|
59
|
-
position: 'absolute',
|
|
60
|
-
top: '-2px',
|
|
61
|
-
right: '3px',
|
|
62
|
-
color: 'var(--notice-color-with-bg)',
|
|
63
|
-
fontWeight: 'bold',
|
|
64
|
-
fontSize: '22px',
|
|
65
|
-
lineHeight: '20px',
|
|
66
|
-
cursor: 'pointer',
|
|
67
|
-
transition: '0.3s',
|
|
68
|
-
},
|
|
69
|
-
|
|
70
|
-
'.close-btn:hover': {
|
|
71
|
-
color: 'black',
|
|
72
|
-
},
|
|
73
|
-
};
|
|
74
|
-
bindGlobalStyle('lj_notification', css);
|
|
75
|
-
|
|
76
|
-
let container = document.querySelector('.lj_notification');
|
|
77
|
-
if (!container) {
|
|
78
|
-
container = document.createElement('div');
|
|
79
|
-
container.className = 'lj_notification';
|
|
80
|
-
document.body.appendChild(container);
|
|
81
|
-
this.container = container as HTMLElement;
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
static sendMessage(message: string, backgroundColor = NotificationColor.Info, permanent = false, showTime = 3000) {
|
|
86
|
-
if (!this.initialized) {
|
|
87
|
-
this.initialized = true;
|
|
88
|
-
this.init();
|
|
89
|
-
}
|
|
90
|
-
this.container.scrollTop = 0;
|
|
91
|
-
const div = document.createElement('div');
|
|
92
|
-
div.innerHTML = message;
|
|
93
|
-
div.style.backgroundColor = backgroundColor;
|
|
94
|
-
this.container.insertBefore(div, this.container.firstChild);
|
|
95
|
-
setTimeout(() => {
|
|
96
|
-
div.style.opacity = '1';
|
|
97
|
-
div.style.transform = 'scale(1)';
|
|
98
|
-
}, 0);
|
|
99
|
-
|
|
100
|
-
if (permanent) {
|
|
101
|
-
const closeBtn = document.createElement('span');
|
|
102
|
-
closeBtn.innerHTML = '×';
|
|
103
|
-
closeBtn.className = 'close-btn';
|
|
104
|
-
div.appendChild(closeBtn);
|
|
105
|
-
closeBtn.onclick = () => {
|
|
106
|
-
this.container.removeChild(div);
|
|
107
|
-
};
|
|
108
|
-
} else {
|
|
109
|
-
setTimeout(() => {
|
|
110
|
-
div.style.opacity = '0';
|
|
111
|
-
div.style.transform = 'scale(0.1)';
|
|
112
|
-
setTimeout(() => {
|
|
113
|
-
this.container.removeChild(div);
|
|
114
|
-
}, 1000);
|
|
115
|
-
}, showTime);
|
|
116
|
-
}
|
|
117
|
-
}
|
|
118
|
-
}
|
|
1
|
+
import { CssProps, bindGlobalStyle } from 'lupine.web';
|
|
2
|
+
/**
|
|
3
|
+
How to use:
|
|
4
|
+
Notification.sendMessage(message);
|
|
5
|
+
*/
|
|
6
|
+
export enum NotificationColor {
|
|
7
|
+
Success = 'var(--success-bg-color)',
|
|
8
|
+
Info = 'var(--info-bg-color)',
|
|
9
|
+
Warning = 'var(--warning-bg-color)',
|
|
10
|
+
Error = 'var(--error-bg-color)',
|
|
11
|
+
}
|
|
12
|
+
export const notificationColorFromValue = (value: string) => {
|
|
13
|
+
switch (value) {
|
|
14
|
+
case 'Success':
|
|
15
|
+
return NotificationColor.Success;
|
|
16
|
+
case 'Info':
|
|
17
|
+
return NotificationColor.Info;
|
|
18
|
+
case 'Warning':
|
|
19
|
+
return NotificationColor.Warning;
|
|
20
|
+
case 'Error':
|
|
21
|
+
return NotificationColor.Error;
|
|
22
|
+
}
|
|
23
|
+
return NotificationColor.Info;
|
|
24
|
+
};
|
|
25
|
+
export class NotificationMessage {
|
|
26
|
+
// public static readonly Color = NotificationColor;
|
|
27
|
+
|
|
28
|
+
private static initialized = false;
|
|
29
|
+
private static container: HTMLElement;
|
|
30
|
+
|
|
31
|
+
static init() {
|
|
32
|
+
/* styles for resizable splitter */
|
|
33
|
+
const css: CssProps = {
|
|
34
|
+
position: 'fixed',
|
|
35
|
+
top: 0,
|
|
36
|
+
right: 0,
|
|
37
|
+
height: 'auto',
|
|
38
|
+
overflowY: 'auto',
|
|
39
|
+
maxHeight: '100%',
|
|
40
|
+
width: '100%',
|
|
41
|
+
maxWidth: '400px',
|
|
42
|
+
// cursor: 'pointer',
|
|
43
|
+
// backgroundColor: '#fefefe',
|
|
44
|
+
padding: '0 10px',
|
|
45
|
+
zIndex: 'var(--layer-notice)',
|
|
46
|
+
// borderRadius: '6px',
|
|
47
|
+
// boxShadow: '0px 0px 2px #000',
|
|
48
|
+
'>div': {
|
|
49
|
+
color: 'var(--notice-color-with-bg)',
|
|
50
|
+
padding: '10px 8px',
|
|
51
|
+
margin: '16px 0',
|
|
52
|
+
borderRadius: '6px',
|
|
53
|
+
boxShadow: 'var(--cover-box-shadow)', //'3px 3px 8px #767676',
|
|
54
|
+
transition: 'all 0.5s',
|
|
55
|
+
transform: 'scale(0.1)',
|
|
56
|
+
opacity: 0,
|
|
57
|
+
},
|
|
58
|
+
'.close-btn': {
|
|
59
|
+
position: 'absolute',
|
|
60
|
+
top: '-2px',
|
|
61
|
+
right: '3px',
|
|
62
|
+
color: 'var(--notice-color-with-bg)',
|
|
63
|
+
fontWeight: 'bold',
|
|
64
|
+
fontSize: '22px',
|
|
65
|
+
lineHeight: '20px',
|
|
66
|
+
cursor: 'pointer',
|
|
67
|
+
transition: '0.3s',
|
|
68
|
+
},
|
|
69
|
+
|
|
70
|
+
'.close-btn:hover': {
|
|
71
|
+
color: 'black',
|
|
72
|
+
},
|
|
73
|
+
};
|
|
74
|
+
bindGlobalStyle('lj_notification', css);
|
|
75
|
+
|
|
76
|
+
let container = document.querySelector('.lj_notification');
|
|
77
|
+
if (!container) {
|
|
78
|
+
container = document.createElement('div');
|
|
79
|
+
container.className = 'lj_notification';
|
|
80
|
+
document.body.appendChild(container);
|
|
81
|
+
this.container = container as HTMLElement;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
static sendMessage(message: string, backgroundColor = NotificationColor.Info, permanent = false, showTime = 3000) {
|
|
86
|
+
if (!this.initialized) {
|
|
87
|
+
this.initialized = true;
|
|
88
|
+
this.init();
|
|
89
|
+
}
|
|
90
|
+
this.container.scrollTop = 0;
|
|
91
|
+
const div = document.createElement('div');
|
|
92
|
+
div.innerHTML = message;
|
|
93
|
+
div.style.backgroundColor = backgroundColor;
|
|
94
|
+
this.container.insertBefore(div, this.container.firstChild);
|
|
95
|
+
setTimeout(() => {
|
|
96
|
+
div.style.opacity = '1';
|
|
97
|
+
div.style.transform = 'scale(1)';
|
|
98
|
+
}, 0);
|
|
99
|
+
|
|
100
|
+
if (permanent) {
|
|
101
|
+
const closeBtn = document.createElement('span');
|
|
102
|
+
closeBtn.innerHTML = '×';
|
|
103
|
+
closeBtn.className = 'close-btn';
|
|
104
|
+
div.appendChild(closeBtn);
|
|
105
|
+
closeBtn.onclick = () => {
|
|
106
|
+
this.container.removeChild(div);
|
|
107
|
+
};
|
|
108
|
+
} else {
|
|
109
|
+
setTimeout(() => {
|
|
110
|
+
div.style.opacity = '0';
|
|
111
|
+
div.style.transform = 'scale(0.1)';
|
|
112
|
+
setTimeout(() => {
|
|
113
|
+
this.container.removeChild(div);
|
|
114
|
+
}, 1000);
|
|
115
|
+
}, showTime);
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { setPageTitle } from
|
|
2
|
-
|
|
3
|
-
export const PageTitle = ({ children }: { children: string }) => {
|
|
4
|
-
setPageTitle(children);
|
|
5
|
-
return <></>;
|
|
6
|
-
};
|
|
1
|
+
import { setPageTitle } from 'lupine.web';
|
|
2
|
+
|
|
3
|
+
export const PageTitle = ({ children }: { children: string }) => {
|
|
4
|
+
setPageTitle(children);
|
|
5
|
+
return <></>;
|
|
6
|
+
};
|
|
@@ -1,175 +1,175 @@
|
|
|
1
|
-
import { CssProps, RefProps, bindGlobalStyle, getRenderPageProps } from 'lupine.web';
|
|
2
|
-
|
|
3
|
-
let _DEFAULT_PAGE_LIMIT = 10;
|
|
4
|
-
export const getDefaultPageLimit = () => {
|
|
5
|
-
return _DEFAULT_PAGE_LIMIT;
|
|
6
|
-
};
|
|
7
|
-
export const setDefaultPageLimit = (limit: number) => {
|
|
8
|
-
_DEFAULT_PAGE_LIMIT = limit;
|
|
9
|
-
};
|
|
10
|
-
const pageLinkOptions = [10, 20, 50, 100, 200, 500];
|
|
11
|
-
export type PagingLinkProps = {
|
|
12
|
-
itemsCount: number;
|
|
13
|
-
pageLimit?: number;
|
|
14
|
-
pageIndex?: number;
|
|
15
|
-
baseLink: string;
|
|
16
|
-
onClick?: (index: number) => void; // if onClick is set then use it instead of href
|
|
17
|
-
textPerpage?: string;
|
|
18
|
-
textOk?: string;
|
|
19
|
-
textTo?: string;
|
|
20
|
-
textPage?: string;
|
|
21
|
-
showControl?: boolean;
|
|
22
|
-
};
|
|
23
|
-
|
|
24
|
-
export const PagingLink = ({
|
|
25
|
-
itemsCount,
|
|
26
|
-
pageLimit = getDefaultPageLimit(),
|
|
27
|
-
pageIndex = 0,
|
|
28
|
-
baseLink,
|
|
29
|
-
onClick,
|
|
30
|
-
textPerpage = '/Page',
|
|
31
|
-
textOk = 'Go',
|
|
32
|
-
textTo = 'To',
|
|
33
|
-
textPage = 'Page',
|
|
34
|
-
showControl,
|
|
35
|
-
}: PagingLinkProps) => {
|
|
36
|
-
const css: CssProps = {
|
|
37
|
-
display: 'flex',
|
|
38
|
-
justifyContent: 'end',
|
|
39
|
-
alignItems: 'center',
|
|
40
|
-
textAlign: 'right',
|
|
41
|
-
padding: '6px 16px 6px 0',
|
|
42
|
-
fontSize: '14px',
|
|
43
|
-
'.paging-link-index a, .paging-link-index.current': {
|
|
44
|
-
padding: '2px 6px',
|
|
45
|
-
textDecoration: 'none',
|
|
46
|
-
},
|
|
47
|
-
'.paging-link-index.current': {
|
|
48
|
-
fontWeight: 'bold',
|
|
49
|
-
},
|
|
50
|
-
'span.paging-link-index a:hover, span.paging-link-go a:hover': {
|
|
51
|
-
textDecoration: 'underline',
|
|
52
|
-
},
|
|
53
|
-
'.paging-link-ctl-box': {
|
|
54
|
-
display: 'flex',
|
|
55
|
-
alignItems: 'center',
|
|
56
|
-
},
|
|
57
|
-
'.paging-link-ctl-box .paging-link-jump': {
|
|
58
|
-
width: '50px',
|
|
59
|
-
padding: '1px 3px',
|
|
60
|
-
margin: '0 3px',
|
|
61
|
-
textAlign: 'right',
|
|
62
|
-
},
|
|
63
|
-
'.paging-link-ctl-box .paging-link-limit': {
|
|
64
|
-
width: '90px',
|
|
65
|
-
padding: '1px 3px',
|
|
66
|
-
margin: '0 3px',
|
|
67
|
-
},
|
|
68
|
-
'.paging-link-ok': {
|
|
69
|
-
margin: '0 3px',
|
|
70
|
-
},
|
|
71
|
-
};
|
|
72
|
-
|
|
73
|
-
bindGlobalStyle('paging-link-box', css);
|
|
74
|
-
pageIndex = pageIndex ?? (Number.parseInt(getRenderPageProps().query['pg_i'] || '') || 0);
|
|
75
|
-
pageLimit = pageLimit || _DEFAULT_PAGE_LIMIT;
|
|
76
|
-
let maxPages = Math.floor(itemsCount / pageLimit);
|
|
77
|
-
if (itemsCount > 0 && pageLimit > 0) {
|
|
78
|
-
if (itemsCount % pageLimit !== 0) {
|
|
79
|
-
maxPages++;
|
|
80
|
-
}
|
|
81
|
-
if (pageIndex > maxPages) {
|
|
82
|
-
pageIndex = maxPages - 1;
|
|
83
|
-
}
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
const onPageLimitChange = (e: Event) => {
|
|
87
|
-
const limit = Number((e.target as HTMLSelectElement).value || '0');
|
|
88
|
-
if (limit > 0) {
|
|
89
|
-
setDefaultPageLimit(limit);
|
|
90
|
-
onClick && onClick(pageIndex);
|
|
91
|
-
}
|
|
92
|
-
};
|
|
93
|
-
|
|
94
|
-
const onOkClick = () => {
|
|
95
|
-
let index = Number((ref.$('.paging-link-jump') as HTMLInputElement).value || '0');
|
|
96
|
-
if (index < 1) {
|
|
97
|
-
index = 1;
|
|
98
|
-
}
|
|
99
|
-
if (index > maxPages) {
|
|
100
|
-
index = maxPages;
|
|
101
|
-
}
|
|
102
|
-
onClick && onClick(index - 1);
|
|
103
|
-
};
|
|
104
|
-
|
|
105
|
-
const ref: RefProps = {};
|
|
106
|
-
return (
|
|
107
|
-
<div ref={ref} class='paging-link-box'>
|
|
108
|
-
{pageIndex > 0 ? (
|
|
109
|
-
<span class='paging-link-go'>
|
|
110
|
-
<a
|
|
111
|
-
href={onClick ? 'javascript:void(0)' : baseLink + '?pg_i=' + (pageIndex - 1)}
|
|
112
|
-
onClick={() => onClick && onClick(pageIndex - 1)}
|
|
113
|
-
>
|
|
114
|
-
<
|
|
115
|
-
</a>
|
|
116
|
-
</span>
|
|
117
|
-
) : (
|
|
118
|
-
<span class='paging-link-go disabled'><</span>
|
|
119
|
-
)}
|
|
120
|
-
|
|
121
|
-
{Array.from({ length: maxPages }, (_, i) => i).map((i) => (
|
|
122
|
-
<>
|
|
123
|
-
{i < 2 || i >= maxPages - 2 || (i > pageIndex - 3 && i < pageIndex + 3) ? (
|
|
124
|
-
i == pageIndex ? (
|
|
125
|
-
<span class='paging-link-index current'>{i + 1}</span>
|
|
126
|
-
) : (
|
|
127
|
-
<span class='paging-link-index'>
|
|
128
|
-
<a
|
|
129
|
-
href={onClick ? 'javascript:void(0)' : baseLink + '?pg_i=' + i}
|
|
130
|
-
onClick={() => onClick && onClick(i)}
|
|
131
|
-
>
|
|
132
|
-
{i + 1}
|
|
133
|
-
</a>
|
|
134
|
-
</span>
|
|
135
|
-
)
|
|
136
|
-
) : (
|
|
137
|
-
(i == pageIndex - 4 || i == pageIndex + 4) && <span class='paging-link-skip'>...</span>
|
|
138
|
-
)}
|
|
139
|
-
</>
|
|
140
|
-
))}
|
|
141
|
-
|
|
142
|
-
{pageIndex < maxPages - 1 ? (
|
|
143
|
-
<span class='paging-link-go'>
|
|
144
|
-
<a
|
|
145
|
-
href={onClick ? 'javascript:void(0)' : baseLink + '?pg_i=' + (pageIndex + 1)}
|
|
146
|
-
onClick={() => onClick && onClick(pageIndex + 1)}
|
|
147
|
-
>
|
|
148
|
-
>
|
|
149
|
-
</a>
|
|
150
|
-
</span>
|
|
151
|
-
) : (
|
|
152
|
-
<span class='paging-link-go disabled'>></span>
|
|
153
|
-
)}
|
|
154
|
-
{showControl && (
|
|
155
|
-
<div class='paging-link-ctl-box'>
|
|
156
|
-
{textTo}
|
|
157
|
-
<input class='input-base paging-link-jump input-s' type='number' value={pageIndex + 1} /> / {maxPages}{' '}
|
|
158
|
-
{textPage}
|
|
159
|
-
<button class='button-base button-s paging-link-ok' onClick={onOkClick}>
|
|
160
|
-
{textOk}
|
|
161
|
-
</button>
|
|
162
|
-
<select class='input-base paging-link-limit input-s' onChange={onPageLimitChange}>
|
|
163
|
-
<option value=''> - </option>
|
|
164
|
-
{pageLinkOptions.map((page) => (
|
|
165
|
-
<option value={page}>
|
|
166
|
-
{page}
|
|
167
|
-
{textPerpage}
|
|
168
|
-
</option>
|
|
169
|
-
))}
|
|
170
|
-
</select>
|
|
171
|
-
</div>
|
|
172
|
-
)}
|
|
173
|
-
</div>
|
|
174
|
-
);
|
|
175
|
-
};
|
|
1
|
+
import { CssProps, RefProps, bindGlobalStyle, getRenderPageProps } from 'lupine.web';
|
|
2
|
+
|
|
3
|
+
let _DEFAULT_PAGE_LIMIT = 10;
|
|
4
|
+
export const getDefaultPageLimit = () => {
|
|
5
|
+
return _DEFAULT_PAGE_LIMIT;
|
|
6
|
+
};
|
|
7
|
+
export const setDefaultPageLimit = (limit: number) => {
|
|
8
|
+
_DEFAULT_PAGE_LIMIT = limit;
|
|
9
|
+
};
|
|
10
|
+
const pageLinkOptions = [10, 20, 50, 100, 200, 500];
|
|
11
|
+
export type PagingLinkProps = {
|
|
12
|
+
itemsCount: number;
|
|
13
|
+
pageLimit?: number;
|
|
14
|
+
pageIndex?: number;
|
|
15
|
+
baseLink: string;
|
|
16
|
+
onClick?: (index: number) => void; // if onClick is set then use it instead of href
|
|
17
|
+
textPerpage?: string;
|
|
18
|
+
textOk?: string;
|
|
19
|
+
textTo?: string;
|
|
20
|
+
textPage?: string;
|
|
21
|
+
showControl?: boolean;
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
export const PagingLink = ({
|
|
25
|
+
itemsCount,
|
|
26
|
+
pageLimit = getDefaultPageLimit(),
|
|
27
|
+
pageIndex = 0,
|
|
28
|
+
baseLink,
|
|
29
|
+
onClick,
|
|
30
|
+
textPerpage = '/Page',
|
|
31
|
+
textOk = 'Go',
|
|
32
|
+
textTo = 'To',
|
|
33
|
+
textPage = 'Page',
|
|
34
|
+
showControl,
|
|
35
|
+
}: PagingLinkProps) => {
|
|
36
|
+
const css: CssProps = {
|
|
37
|
+
display: 'flex',
|
|
38
|
+
justifyContent: 'end',
|
|
39
|
+
alignItems: 'center',
|
|
40
|
+
textAlign: 'right',
|
|
41
|
+
padding: '6px 16px 6px 0',
|
|
42
|
+
fontSize: '14px',
|
|
43
|
+
'.paging-link-index a, .paging-link-index.current': {
|
|
44
|
+
padding: '2px 6px',
|
|
45
|
+
textDecoration: 'none',
|
|
46
|
+
},
|
|
47
|
+
'.paging-link-index.current': {
|
|
48
|
+
fontWeight: 'bold',
|
|
49
|
+
},
|
|
50
|
+
'span.paging-link-index a:hover, span.paging-link-go a:hover': {
|
|
51
|
+
textDecoration: 'underline',
|
|
52
|
+
},
|
|
53
|
+
'.paging-link-ctl-box': {
|
|
54
|
+
display: 'flex',
|
|
55
|
+
alignItems: 'center',
|
|
56
|
+
},
|
|
57
|
+
'.paging-link-ctl-box .paging-link-jump': {
|
|
58
|
+
width: '50px',
|
|
59
|
+
padding: '1px 3px',
|
|
60
|
+
margin: '0 3px',
|
|
61
|
+
textAlign: 'right',
|
|
62
|
+
},
|
|
63
|
+
'.paging-link-ctl-box .paging-link-limit': {
|
|
64
|
+
width: '90px',
|
|
65
|
+
padding: '1px 3px',
|
|
66
|
+
margin: '0 3px',
|
|
67
|
+
},
|
|
68
|
+
'.paging-link-ok': {
|
|
69
|
+
margin: '0 3px',
|
|
70
|
+
},
|
|
71
|
+
};
|
|
72
|
+
|
|
73
|
+
bindGlobalStyle('paging-link-box', css);
|
|
74
|
+
pageIndex = pageIndex ?? (Number.parseInt(getRenderPageProps().query['pg_i'] || '') || 0);
|
|
75
|
+
pageLimit = pageLimit || _DEFAULT_PAGE_LIMIT;
|
|
76
|
+
let maxPages = Math.floor(itemsCount / pageLimit);
|
|
77
|
+
if (itemsCount > 0 && pageLimit > 0) {
|
|
78
|
+
if (itemsCount % pageLimit !== 0) {
|
|
79
|
+
maxPages++;
|
|
80
|
+
}
|
|
81
|
+
if (pageIndex > maxPages) {
|
|
82
|
+
pageIndex = maxPages - 1;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
const onPageLimitChange = (e: Event) => {
|
|
87
|
+
const limit = Number((e.target as HTMLSelectElement).value || '0');
|
|
88
|
+
if (limit > 0) {
|
|
89
|
+
setDefaultPageLimit(limit);
|
|
90
|
+
onClick && onClick(pageIndex);
|
|
91
|
+
}
|
|
92
|
+
};
|
|
93
|
+
|
|
94
|
+
const onOkClick = () => {
|
|
95
|
+
let index = Number((ref.$('.paging-link-jump') as HTMLInputElement).value || '0');
|
|
96
|
+
if (index < 1) {
|
|
97
|
+
index = 1;
|
|
98
|
+
}
|
|
99
|
+
if (index > maxPages) {
|
|
100
|
+
index = maxPages;
|
|
101
|
+
}
|
|
102
|
+
onClick && onClick(index - 1);
|
|
103
|
+
};
|
|
104
|
+
|
|
105
|
+
const ref: RefProps = {};
|
|
106
|
+
return (
|
|
107
|
+
<div ref={ref} class='paging-link-box'>
|
|
108
|
+
{pageIndex > 0 ? (
|
|
109
|
+
<span class='paging-link-go'>
|
|
110
|
+
<a
|
|
111
|
+
href={onClick ? 'javascript:void(0)' : baseLink + '?pg_i=' + (pageIndex - 1)}
|
|
112
|
+
onClick={() => onClick && onClick(pageIndex - 1)}
|
|
113
|
+
>
|
|
114
|
+
<
|
|
115
|
+
</a>
|
|
116
|
+
</span>
|
|
117
|
+
) : (
|
|
118
|
+
<span class='paging-link-go disabled'><</span>
|
|
119
|
+
)}
|
|
120
|
+
|
|
121
|
+
{Array.from({ length: maxPages }, (_, i) => i).map((i) => (
|
|
122
|
+
<>
|
|
123
|
+
{i < 2 || i >= maxPages - 2 || (i > pageIndex - 3 && i < pageIndex + 3) ? (
|
|
124
|
+
i == pageIndex ? (
|
|
125
|
+
<span class='paging-link-index current'>{i + 1}</span>
|
|
126
|
+
) : (
|
|
127
|
+
<span class='paging-link-index'>
|
|
128
|
+
<a
|
|
129
|
+
href={onClick ? 'javascript:void(0)' : baseLink + '?pg_i=' + i}
|
|
130
|
+
onClick={() => onClick && onClick(i)}
|
|
131
|
+
>
|
|
132
|
+
{i + 1}
|
|
133
|
+
</a>
|
|
134
|
+
</span>
|
|
135
|
+
)
|
|
136
|
+
) : (
|
|
137
|
+
(i == pageIndex - 4 || i == pageIndex + 4) && <span class='paging-link-skip'>...</span>
|
|
138
|
+
)}
|
|
139
|
+
</>
|
|
140
|
+
))}
|
|
141
|
+
|
|
142
|
+
{pageIndex < maxPages - 1 ? (
|
|
143
|
+
<span class='paging-link-go'>
|
|
144
|
+
<a
|
|
145
|
+
href={onClick ? 'javascript:void(0)' : baseLink + '?pg_i=' + (pageIndex + 1)}
|
|
146
|
+
onClick={() => onClick && onClick(pageIndex + 1)}
|
|
147
|
+
>
|
|
148
|
+
>
|
|
149
|
+
</a>
|
|
150
|
+
</span>
|
|
151
|
+
) : (
|
|
152
|
+
<span class='paging-link-go disabled'>></span>
|
|
153
|
+
)}
|
|
154
|
+
{showControl && (
|
|
155
|
+
<div class='paging-link-ctl-box'>
|
|
156
|
+
{textTo}
|
|
157
|
+
<input class='input-base paging-link-jump input-s' type='number' value={pageIndex + 1} /> / {maxPages}{' '}
|
|
158
|
+
{textPage}
|
|
159
|
+
<button class='button-base button-s paging-link-ok' onClick={onOkClick}>
|
|
160
|
+
{textOk}
|
|
161
|
+
</button>
|
|
162
|
+
<select class='input-base paging-link-limit input-s' onChange={onPageLimitChange}>
|
|
163
|
+
<option value=''> - </option>
|
|
164
|
+
{pageLinkOptions.map((page) => (
|
|
165
|
+
<option value={page}>
|
|
166
|
+
{page}
|
|
167
|
+
{textPerpage}
|
|
168
|
+
</option>
|
|
169
|
+
))}
|
|
170
|
+
</select>
|
|
171
|
+
</div>
|
|
172
|
+
)}
|
|
173
|
+
</div>
|
|
174
|
+
);
|
|
175
|
+
};
|
package/src/components/panel.tsx
CHANGED
|
@@ -1,21 +1,21 @@
|
|
|
1
|
-
import { CssProps } from 'lupine.web';
|
|
2
|
-
|
|
3
|
-
export type PanelProps = {
|
|
4
|
-
children: any;
|
|
5
|
-
className?: string;
|
|
6
|
-
css?: CssProps;
|
|
7
|
-
};
|
|
8
|
-
|
|
9
|
-
export const Panel = ({ children, className, css }: PanelProps) => {
|
|
10
|
-
const newCss: CssProps = {
|
|
11
|
-
display: 'flex',
|
|
12
|
-
flexDirection: 'column',
|
|
13
|
-
...css,
|
|
14
|
-
};
|
|
15
|
-
|
|
16
|
-
return (
|
|
17
|
-
<div css={newCss} class={['panel-box', className].join(' ')}>
|
|
18
|
-
{children}
|
|
19
|
-
</div>
|
|
20
|
-
);
|
|
21
|
-
};
|
|
1
|
+
import { CssProps } from 'lupine.web';
|
|
2
|
+
|
|
3
|
+
export type PanelProps = {
|
|
4
|
+
children: any;
|
|
5
|
+
className?: string;
|
|
6
|
+
css?: CssProps;
|
|
7
|
+
};
|
|
8
|
+
|
|
9
|
+
export const Panel = ({ children, className, css }: PanelProps) => {
|
|
10
|
+
const newCss: CssProps = {
|
|
11
|
+
display: 'flex',
|
|
12
|
+
flexDirection: 'column',
|
|
13
|
+
...css,
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
return (
|
|
17
|
+
<div css={newCss} class={['panel-box', className].join(' ')}>
|
|
18
|
+
{children}
|
|
19
|
+
</div>
|
|
20
|
+
);
|
|
21
|
+
};
|