lupine.components 1.0.12 → 1.0.14
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/package.json +1 -1
- package/src/components/html-var.tsx +3 -2
- package/src/components/menu-item-props.tsx +2 -0
- package/src/components/menu-sidebar.tsx +55 -28
- package/src/components/tabs.tsx +4 -3
- package/src/frames/desktop-frame.tsx +3 -2
- package/src/frames/header-with-back-frame.tsx +117 -117
- package/src/frames/responsive-frame.tsx +85 -85
- package/src/frames/slider-frame.tsx +99 -99
- package/src/frames/top-frame.tsx +2 -2
package/package.json
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { RefProps, VNode, mountComponents } from 'lupine.web';
|
|
1
|
+
import { RefProps, VNode, mountComponents, replaceInnerhtml } from 'lupine.web';
|
|
2
2
|
|
|
3
3
|
export type HtmlVarResult = { value: string | VNode<any>; ref: RefProps; node: VNode<any> };
|
|
4
4
|
export const HtmlVar = (initial?: string | VNode<any>): HtmlVarResult => {
|
|
@@ -9,7 +9,8 @@ export const HtmlVar = (initial?: string | VNode<any>): HtmlVarResult => {
|
|
|
9
9
|
if (typeof value === 'object' && value.type && value.props) {
|
|
10
10
|
await mountComponents(ref.current, value);
|
|
11
11
|
} else {
|
|
12
|
-
ref.current
|
|
12
|
+
await replaceInnerhtml(ref.current, value as string);
|
|
13
|
+
// ref.current.innerHTML = value;
|
|
13
14
|
}
|
|
14
15
|
_dirty = false;
|
|
15
16
|
};
|
|
@@ -31,7 +31,7 @@ export const MenuSidebar = ({
|
|
|
31
31
|
maxWidthMobileMenu = MediaQueryMaxWidth.TabletMax,
|
|
32
32
|
}: MenuSidebarProps) => {
|
|
33
33
|
const css: CssProps = {
|
|
34
|
-
backgroundColor,
|
|
34
|
+
// backgroundColor,
|
|
35
35
|
'.menu-sidebar-top': {
|
|
36
36
|
width: '100%',
|
|
37
37
|
backgroundColor: 'var(--sidebar-bg-color)',
|
|
@@ -45,9 +45,9 @@ export const MenuSidebar = ({
|
|
|
45
45
|
justifyContent: 'center',
|
|
46
46
|
flexDirection: 'column',
|
|
47
47
|
},
|
|
48
|
-
'&.mobile .menu-sidebar-top': {
|
|
49
|
-
|
|
50
|
-
},
|
|
48
|
+
// '&.mobile .menu-sidebar-top': {
|
|
49
|
+
// position: 'absolute',
|
|
50
|
+
// },
|
|
51
51
|
'.menu-sidebar-item': {
|
|
52
52
|
display: 'inline-block',
|
|
53
53
|
color,
|
|
@@ -112,7 +112,7 @@ export const MenuSidebar = ({
|
|
|
112
112
|
'.menu-sidebar-mobile': {
|
|
113
113
|
display: 'none',
|
|
114
114
|
position: 'relative',
|
|
115
|
-
backgroundColor: 'var(--primary-bg-color)',
|
|
115
|
+
// backgroundColor: 'var(--primary-bg-color)',
|
|
116
116
|
padding: '5px 4px 6px',
|
|
117
117
|
'.menu-sidebar-toggle': {
|
|
118
118
|
cursor: 'pointer',
|
|
@@ -165,13 +165,30 @@ export const MenuSidebar = ({
|
|
|
165
165
|
'&.mobile': {
|
|
166
166
|
display: 'block',
|
|
167
167
|
},
|
|
168
|
+
'&.mobile.open': {
|
|
169
|
+
position: 'absolute',
|
|
170
|
+
width: '100%',
|
|
171
|
+
height: '100%',
|
|
172
|
+
top: 0,
|
|
173
|
+
left: 0,
|
|
174
|
+
display: 'flex',
|
|
175
|
+
flexDirection: 'column',
|
|
176
|
+
backgroundColor: '#ccccccc2',
|
|
177
|
+
zIndex: 'var(--layer-sidebar)',
|
|
178
|
+
},
|
|
168
179
|
'.menu-sidebar-top': {
|
|
169
180
|
display: 'none',
|
|
170
181
|
},
|
|
171
182
|
'.menu-sidebar-top.open': {
|
|
172
183
|
display: 'flex',
|
|
173
184
|
flexDirection: 'column',
|
|
174
|
-
|
|
185
|
+
// left: 0,
|
|
186
|
+
// top: 0,
|
|
187
|
+
flex: 1,
|
|
188
|
+
overflowY: 'auto',
|
|
189
|
+
paddingTop: '200px',
|
|
190
|
+
width: '200px',
|
|
191
|
+
marginLeft: 'unset',
|
|
175
192
|
},
|
|
176
193
|
'.menu-sidebar-top.open .menu-sidebar-sub-box > .menu-sidebar-sub': {
|
|
177
194
|
display: 'flex',
|
|
@@ -201,6 +218,9 @@ export const MenuSidebar = ({
|
|
|
201
218
|
return (
|
|
202
219
|
<div class={className}>
|
|
203
220
|
{items.map((item) => {
|
|
221
|
+
if (item.hide === true) {
|
|
222
|
+
return null;
|
|
223
|
+
}
|
|
204
224
|
let ref: RefProps = {};
|
|
205
225
|
return item.items ? (
|
|
206
226
|
<div ref={ref} class='menu-sidebar-sub-box' onClick={() => onItemToggleClick(ref)}>
|
|
@@ -215,14 +235,14 @@ export const MenuSidebar = ({
|
|
|
215
235
|
onClick={(event) => {
|
|
216
236
|
stopPropagation(event);
|
|
217
237
|
// hide menu
|
|
218
|
-
onToggleClick();
|
|
238
|
+
onToggleClick(event);
|
|
219
239
|
item.js && item.js();
|
|
220
240
|
}}
|
|
221
241
|
>
|
|
222
242
|
{item.text}
|
|
223
243
|
</a>
|
|
224
244
|
) : (
|
|
225
|
-
<a class='menu-sidebar-item' href={item.url} alt={item.alt || item.text}>
|
|
245
|
+
<a class='menu-sidebar-item' href={item.url} alt={item.alt || item.text} target='_blank'>
|
|
226
246
|
{item.text}
|
|
227
247
|
</a>
|
|
228
248
|
);
|
|
@@ -232,25 +252,27 @@ export const MenuSidebar = ({
|
|
|
232
252
|
};
|
|
233
253
|
|
|
234
254
|
const ref: RefProps = {
|
|
235
|
-
onLoad: async () => {
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
},
|
|
255
|
+
// onLoad: async () => {
|
|
256
|
+
// if (menuId) {
|
|
257
|
+
// const menu = await fetchMenu(menuId);
|
|
258
|
+
// if (menu.result.items.length > 0) {
|
|
259
|
+
// const items = menu.result.items.map((i: any) => {
|
|
260
|
+
// const l = i.split('\t');
|
|
261
|
+
// return { text: l[5], url: l[4] };
|
|
262
|
+
// });
|
|
263
|
+
// const newDom = renderItems(items, 'menu-sidebar-top');
|
|
264
|
+
// //mountComponents('.menu-sidebar-top', newDom);
|
|
265
|
+
// }
|
|
266
|
+
// }
|
|
267
|
+
// },
|
|
248
268
|
};
|
|
249
|
-
const onToggleClick = () => {
|
|
269
|
+
const onToggleClick = (event: Event) => {
|
|
270
|
+
event.stopPropagation();
|
|
250
271
|
const menu = ref.$('.menu-sidebar-mobile .menu-sidebar-toggle');
|
|
251
272
|
menu.classList.toggle('active');
|
|
252
273
|
const topMenu = ref.$('.menu-sidebar-top');
|
|
253
274
|
topMenu.classList.toggle('open');
|
|
275
|
+
ref.current.classList.toggle('open');
|
|
254
276
|
};
|
|
255
277
|
const onItemToggleClick = (ref: RefProps) => {
|
|
256
278
|
// if (event.target != ref.current && (event.target as any).parentNode != ref.current) {
|
|
@@ -266,16 +288,21 @@ export const MenuSidebar = ({
|
|
|
266
288
|
const newCss: CssProps =
|
|
267
289
|
(!desktopMenu && !mobileMenu) || (desktopMenu && mobileMenu)
|
|
268
290
|
? {
|
|
269
|
-
|
|
291
|
+
['@media only screen and (max-width: ' + maxWidthMobileMenu + ')']: {
|
|
292
|
+
display: 'block',
|
|
293
|
+
'.menu-sidebar-top': {
|
|
270
294
|
display: 'block',
|
|
271
|
-
'.menu-sidebar-top': {
|
|
272
|
-
display: 'block',
|
|
273
|
-
},
|
|
274
295
|
},
|
|
275
|
-
}
|
|
296
|
+
},
|
|
297
|
+
}
|
|
276
298
|
: {};
|
|
299
|
+
const onMaskClick = (event: MouseEvent) => {
|
|
300
|
+
if (ref.current.classList.contains('open')) {
|
|
301
|
+
onToggleClick(event);
|
|
302
|
+
}
|
|
303
|
+
};
|
|
277
304
|
return (
|
|
278
|
-
<div css={newCss} ref={ref} class={['menu-sidebar-box', className, mobileMenu ? 'mobile' : ''].join(' ')}>
|
|
305
|
+
<div css={newCss} ref={ref} class={['menu-sidebar-box', className, mobileMenu ? 'mobile' : ''].join(' ')} onClick={onMaskClick}>
|
|
279
306
|
<div class='menu-sidebar-mobile'>
|
|
280
307
|
<div class='menu-sidebar-toggle' onClick={onToggleClick}>
|
|
281
308
|
<span></span>
|
package/src/components/tabs.tsx
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import { RefProps, VNode, mountComponents } from 'lupine.web';
|
|
2
2
|
import { stopPropagation } from '../lib';
|
|
3
3
|
|
|
4
|
-
export type
|
|
4
|
+
export type TabsHookProps = {
|
|
5
5
|
updateTitle?: (index: number, title: string) => void;
|
|
6
6
|
updateIndex?: (index: number) => void;
|
|
7
7
|
newPage?: (title: string, page: VNode<any>, index?: number) => Promise<void>;
|
|
8
8
|
removePage?: (index: number) => void;
|
|
9
|
+
// set from outside and called when the active tab index changes
|
|
9
10
|
indexChanged?: (index: number) => void;
|
|
10
11
|
getIndex?: () => number;
|
|
11
12
|
getCount?: () => number;
|
|
@@ -19,10 +20,10 @@ export type TabsProps = {
|
|
|
19
20
|
defaultIndex?: number;
|
|
20
21
|
topClassName?: string;
|
|
21
22
|
pagePadding?: string;
|
|
22
|
-
|
|
23
|
+
hook?: TabsHookProps;
|
|
23
24
|
};
|
|
24
25
|
// For CSS or query selectors, please pay attention to that Tabs can be nested
|
|
25
|
-
export const Tabs = ({ pages, defaultIndex, topClassName, pagePadding, refUpdate }: TabsProps) => {
|
|
26
|
+
export const Tabs = ({ pages, defaultIndex, topClassName, pagePadding, hook: refUpdate }: TabsProps) => {
|
|
26
27
|
const ref: RefProps = {};
|
|
27
28
|
let newIndex = typeof defaultIndex === 'number' ? defaultIndex : 0;
|
|
28
29
|
const clearIndex = () => {
|
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
import { VNode, CssProps
|
|
1
|
+
import { VNode, CssProps } from 'lupine.web';
|
|
2
2
|
import { MediaQueryMaxWidth } from '../styles';
|
|
3
3
|
import { MenuBar } from '../components';
|
|
4
4
|
|
|
5
5
|
export interface MenuBarMenuProps {
|
|
6
|
+
id: string;
|
|
6
7
|
text: string;
|
|
7
8
|
url: string;
|
|
8
9
|
}
|
|
@@ -65,7 +66,7 @@ export const DesktopFrame = async (
|
|
|
65
66
|
</div>
|
|
66
67
|
<div class='header-title'>
|
|
67
68
|
{title}
|
|
68
|
-
<div class='header-subtitle pt-s'>{'ver: ' + getWebVersion()}</div>
|
|
69
|
+
{/* <div class='header-subtitle pt-s'>{'ver: ' + getWebVersion()}</div> */}
|
|
69
70
|
</div>
|
|
70
71
|
</div>
|
|
71
72
|
<MenuBar items={menu} maxWidthMobileMenu={'800px'} maxWidth={MediaQueryMaxWidth.DesktopMax}></MenuBar>
|
|
@@ -1,117 +1,117 @@
|
|
|
1
|
-
import { VNode, CssProps, RefProps, HtmlVar } from 'lupine.components';
|
|
2
|
-
|
|
3
|
-
export const HeaderWithBackFrameHeight = '40px';
|
|
4
|
-
export const HeaderWithBackFrameLeft = ({ onClick }: { onClick: (event: Event) => void }) => {
|
|
5
|
-
return (
|
|
6
|
-
<i class='ifc-icon mg-arrow_back_ios_new_outlined header-back-left-icon' onClick={(event) => onClick(event)}></i>
|
|
7
|
-
);
|
|
8
|
-
};
|
|
9
|
-
|
|
10
|
-
export const HeaderWithBackFrameRight = ({ onClick }: { onClick: (event: Event) => void }) => {
|
|
11
|
-
return <i class='ifc-icon ma-close header-back-right-icon' onClick={(event) => onClick(event)}></i>;
|
|
12
|
-
};
|
|
13
|
-
|
|
14
|
-
export const HeaderWithBackFrameEmpty = () => {
|
|
15
|
-
return <div class='header-back-top-empty'></div>;
|
|
16
|
-
};
|
|
17
|
-
|
|
18
|
-
export interface HeaderWithBackFrameHookProps {
|
|
19
|
-
updateTitle?: (title: string) => void;
|
|
20
|
-
updateLeft?: (left: VNode<any>) => void;
|
|
21
|
-
updateRight?: (right: VNode<any>) => void;
|
|
22
|
-
}
|
|
23
|
-
export const HeaderWithBackFrame = ({
|
|
24
|
-
children,
|
|
25
|
-
title,
|
|
26
|
-
onBack,
|
|
27
|
-
left,
|
|
28
|
-
right,
|
|
29
|
-
hook,
|
|
30
|
-
noHeader = false,
|
|
31
|
-
}: {
|
|
32
|
-
children: VNode<any>;
|
|
33
|
-
title: string;
|
|
34
|
-
onBack: (event: Event) => void;
|
|
35
|
-
left?: VNode<any>;
|
|
36
|
-
right?: VNode<any>;
|
|
37
|
-
hook?: HeaderWithBackFrameHookProps;
|
|
38
|
-
noHeader?: boolean;
|
|
39
|
-
}) => {
|
|
40
|
-
left = left || <HeaderWithBackFrameLeft onClick={onBack} />;
|
|
41
|
-
right = right || <HeaderWithBackFrameRight onClick={onBack} />;
|
|
42
|
-
const css: CssProps = {
|
|
43
|
-
display: 'flex',
|
|
44
|
-
flexDirection: 'column',
|
|
45
|
-
width: '100%',
|
|
46
|
-
height: '100%',
|
|
47
|
-
minHeight: '100%',
|
|
48
|
-
'.header-back-top': {
|
|
49
|
-
display: 'flex',
|
|
50
|
-
flexDirection: 'row',
|
|
51
|
-
width: '100vw',
|
|
52
|
-
padding: '6px 0',
|
|
53
|
-
backgroundColor: 'var(--activatable-bg-color-normal)',
|
|
54
|
-
boxShadow: '0 2px 4px var(--primary-border-color)',
|
|
55
|
-
},
|
|
56
|
-
'.header-back-content': {
|
|
57
|
-
display: 'flex',
|
|
58
|
-
flex: '1',
|
|
59
|
-
flexDirection: 'column',
|
|
60
|
-
overflowY: 'auto',
|
|
61
|
-
scrollbarWidth: 'none',
|
|
62
|
-
position: 'relative',
|
|
63
|
-
'&::-webkit-scrollbar': {
|
|
64
|
-
height: '0',
|
|
65
|
-
},
|
|
66
|
-
},
|
|
67
|
-
'.header-back-title': {
|
|
68
|
-
flex: '1',
|
|
69
|
-
color: 'var(--activatable-text-color-normal)',
|
|
70
|
-
overflow: 'hidden',
|
|
71
|
-
textOverflow: 'ellipsis',
|
|
72
|
-
whiteSpace: 'nowrap',
|
|
73
|
-
},
|
|
74
|
-
'.header-back-left, .header-back-right': {
|
|
75
|
-
// width: HeaderWithBackFrameHeight,
|
|
76
|
-
height: HeaderWithBackFrameHeight,
|
|
77
|
-
display: 'flex',
|
|
78
|
-
alignItems: 'center',
|
|
79
|
-
justifyContent: 'center',
|
|
80
|
-
cursor: 'pointer',
|
|
81
|
-
fontSize: '16px',
|
|
82
|
-
padding: '0 8px',
|
|
83
|
-
},
|
|
84
|
-
'.header-back-left i, .header-back-right i': {
|
|
85
|
-
fontSize: '28px',
|
|
86
|
-
},
|
|
87
|
-
|
|
88
|
-
};
|
|
89
|
-
|
|
90
|
-
if (hook) {
|
|
91
|
-
hook.updateTitle = (title: string) => {
|
|
92
|
-
const titleDom = ref.current?.querySelector('.header-back-title') as HTMLDivElement;
|
|
93
|
-
titleDom && (titleDom.textContent = title);
|
|
94
|
-
};
|
|
95
|
-
hook.updateLeft = (left: VNode<any>) => {
|
|
96
|
-
domLeft.value = left;
|
|
97
|
-
};
|
|
98
|
-
hook.updateRight = (right: VNode<any>) => {
|
|
99
|
-
domRight.value = right;
|
|
100
|
-
};
|
|
101
|
-
}
|
|
102
|
-
const domLeft = HtmlVar(left);
|
|
103
|
-
const domRight = HtmlVar(right);
|
|
104
|
-
const ref: RefProps = {};
|
|
105
|
-
return (
|
|
106
|
-
<div ref={ref} css={css} class='header-back-frame'>
|
|
107
|
-
{!noHeader && (
|
|
108
|
-
<div class='header-back-top'>
|
|
109
|
-
<div class='header-back-left'>{domLeft.node}</div>
|
|
110
|
-
<div class='mobile-title header-back-title'>{title}</div>
|
|
111
|
-
<div class='header-back-right'>{domRight.node}</div>
|
|
112
|
-
</div>
|
|
113
|
-
)}
|
|
114
|
-
<div class='header-back-content'>{children}</div>
|
|
115
|
-
</div>
|
|
116
|
-
);
|
|
117
|
-
};
|
|
1
|
+
import { VNode, CssProps, RefProps, HtmlVar } from 'lupine.components';
|
|
2
|
+
|
|
3
|
+
export const HeaderWithBackFrameHeight = '40px';
|
|
4
|
+
export const HeaderWithBackFrameLeft = ({ onClick }: { onClick: (event: Event) => void }) => {
|
|
5
|
+
return (
|
|
6
|
+
<i class='ifc-icon mg-arrow_back_ios_new_outlined header-back-left-icon' onClick={(event) => onClick(event)}></i>
|
|
7
|
+
);
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
export const HeaderWithBackFrameRight = ({ onClick }: { onClick: (event: Event) => void }) => {
|
|
11
|
+
return <i class='ifc-icon ma-close header-back-right-icon' onClick={(event) => onClick(event)}></i>;
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
export const HeaderWithBackFrameEmpty = () => {
|
|
15
|
+
return <div class='header-back-top-empty'></div>;
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
export interface HeaderWithBackFrameHookProps {
|
|
19
|
+
updateTitle?: (title: string) => void;
|
|
20
|
+
updateLeft?: (left: VNode<any>) => void;
|
|
21
|
+
updateRight?: (right: VNode<any>) => void;
|
|
22
|
+
}
|
|
23
|
+
export const HeaderWithBackFrame = ({
|
|
24
|
+
children,
|
|
25
|
+
title,
|
|
26
|
+
onBack,
|
|
27
|
+
left,
|
|
28
|
+
right,
|
|
29
|
+
hook,
|
|
30
|
+
noHeader = false,
|
|
31
|
+
}: {
|
|
32
|
+
children: VNode<any>;
|
|
33
|
+
title: string;
|
|
34
|
+
onBack: (event: Event) => void;
|
|
35
|
+
left?: VNode<any>;
|
|
36
|
+
right?: VNode<any>;
|
|
37
|
+
hook?: HeaderWithBackFrameHookProps;
|
|
38
|
+
noHeader?: boolean;
|
|
39
|
+
}) => {
|
|
40
|
+
left = left || <HeaderWithBackFrameLeft onClick={onBack} />;
|
|
41
|
+
right = right || <HeaderWithBackFrameRight onClick={onBack} />;
|
|
42
|
+
const css: CssProps = {
|
|
43
|
+
display: 'flex',
|
|
44
|
+
flexDirection: 'column',
|
|
45
|
+
width: '100%',
|
|
46
|
+
height: '100%',
|
|
47
|
+
minHeight: '100%',
|
|
48
|
+
'.header-back-top': {
|
|
49
|
+
display: 'flex',
|
|
50
|
+
flexDirection: 'row',
|
|
51
|
+
width: '100vw',
|
|
52
|
+
padding: '6px 0',
|
|
53
|
+
backgroundColor: 'var(--activatable-bg-color-normal)',
|
|
54
|
+
boxShadow: '0 2px 4px var(--primary-border-color)',
|
|
55
|
+
},
|
|
56
|
+
'.header-back-content': {
|
|
57
|
+
display: 'flex',
|
|
58
|
+
flex: '1',
|
|
59
|
+
flexDirection: 'column',
|
|
60
|
+
overflowY: 'auto',
|
|
61
|
+
scrollbarWidth: 'none',
|
|
62
|
+
position: 'relative',
|
|
63
|
+
'&::-webkit-scrollbar': {
|
|
64
|
+
height: '0',
|
|
65
|
+
},
|
|
66
|
+
},
|
|
67
|
+
'.header-back-title': {
|
|
68
|
+
flex: '1',
|
|
69
|
+
color: 'var(--activatable-text-color-normal)',
|
|
70
|
+
overflow: 'hidden',
|
|
71
|
+
textOverflow: 'ellipsis',
|
|
72
|
+
whiteSpace: 'nowrap',
|
|
73
|
+
},
|
|
74
|
+
'.header-back-left, .header-back-right': {
|
|
75
|
+
// width: HeaderWithBackFrameHeight,
|
|
76
|
+
height: HeaderWithBackFrameHeight,
|
|
77
|
+
display: 'flex',
|
|
78
|
+
alignItems: 'center',
|
|
79
|
+
justifyContent: 'center',
|
|
80
|
+
cursor: 'pointer',
|
|
81
|
+
fontSize: '16px',
|
|
82
|
+
padding: '0 8px',
|
|
83
|
+
},
|
|
84
|
+
'.header-back-left i, .header-back-right i': {
|
|
85
|
+
fontSize: '28px',
|
|
86
|
+
},
|
|
87
|
+
|
|
88
|
+
};
|
|
89
|
+
|
|
90
|
+
if (hook) {
|
|
91
|
+
hook.updateTitle = (title: string) => {
|
|
92
|
+
const titleDom = ref.current?.querySelector('.header-back-title') as HTMLDivElement;
|
|
93
|
+
titleDom && (titleDom.textContent = title);
|
|
94
|
+
};
|
|
95
|
+
hook.updateLeft = (left: VNode<any>) => {
|
|
96
|
+
domLeft.value = left;
|
|
97
|
+
};
|
|
98
|
+
hook.updateRight = (right: VNode<any>) => {
|
|
99
|
+
domRight.value = right;
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
const domLeft = HtmlVar(left);
|
|
103
|
+
const domRight = HtmlVar(right);
|
|
104
|
+
const ref: RefProps = {};
|
|
105
|
+
return (
|
|
106
|
+
<div ref={ref} css={css} class='header-back-frame'>
|
|
107
|
+
{!noHeader && (
|
|
108
|
+
<div class='header-back-top'>
|
|
109
|
+
<div class='header-back-left'>{domLeft.node}</div>
|
|
110
|
+
<div class='mobile-title header-back-title'>{title}</div>
|
|
111
|
+
<div class='header-back-right'>{domRight.node}</div>
|
|
112
|
+
</div>
|
|
113
|
+
)}
|
|
114
|
+
<div class='header-back-content'>{children}</div>
|
|
115
|
+
</div>
|
|
116
|
+
);
|
|
117
|
+
};
|
|
@@ -1,85 +1,85 @@
|
|
|
1
|
-
import { VNode, CssProps, MediaQueryRange } from 'lupine.components';
|
|
2
|
-
import { MobileFooterMenu, MobileFooterMenuItemProps } from '../components/mobile-components/mobile-footer-menu';
|
|
3
|
-
import { MobileHeaderComponent } from '../components/mobile-components/mobile-header-component';
|
|
4
|
-
|
|
5
|
-
export const ResponsiveFrame = async (
|
|
6
|
-
placeholderClassname: string,
|
|
7
|
-
title: string,
|
|
8
|
-
footerTitle: string,
|
|
9
|
-
logoUrl: string,
|
|
10
|
-
vnode: VNode<any>,
|
|
11
|
-
bottomMenu: MobileFooterMenuItemProps[]
|
|
12
|
-
) => {
|
|
13
|
-
const cssContainer: CssProps = {
|
|
14
|
-
display: 'flex',
|
|
15
|
-
flexDirection: 'column',
|
|
16
|
-
width: '100%',
|
|
17
|
-
height: '100%',
|
|
18
|
-
minHeight: '100%',
|
|
19
|
-
'.frame-top-menu': {
|
|
20
|
-
display: 'flex',
|
|
21
|
-
flexDirection: 'column',
|
|
22
|
-
width: '100vw',
|
|
23
|
-
// height: '72px',
|
|
24
|
-
// position: 'fixed',
|
|
25
|
-
// left: 0,
|
|
26
|
-
// top: 0,
|
|
27
|
-
// zIndex: 'var(--layer-menu)',
|
|
28
|
-
backgroundColor: 'var(--activatable-bg-color-normal)',
|
|
29
|
-
},
|
|
30
|
-
'.frame-content': {
|
|
31
|
-
display: 'flex',
|
|
32
|
-
flex: '1',
|
|
33
|
-
flexDirection: 'column',
|
|
34
|
-
// paddingTop: '100px',
|
|
35
|
-
overflowY: 'auto',
|
|
36
|
-
scrollbarWidth: 'none',
|
|
37
|
-
'&::-webkit-scrollbar': {
|
|
38
|
-
height: '0',
|
|
39
|
-
},
|
|
40
|
-
},
|
|
41
|
-
'.content-block': {
|
|
42
|
-
display: 'flex',
|
|
43
|
-
flex: '1',
|
|
44
|
-
flexDirection: 'column',
|
|
45
|
-
overflowY: 'auto',
|
|
46
|
-
scrollbarWidth: 'none',
|
|
47
|
-
},
|
|
48
|
-
'.content-block .padding-block': {
|
|
49
|
-
padding: '0 16px',
|
|
50
|
-
},
|
|
51
|
-
// '.frame-footer': {
|
|
52
|
-
// paddingTop: '57px', // 应该和底部菜单的高度一致
|
|
53
|
-
// },
|
|
54
|
-
[MediaQueryRange.TabletBelow]: {
|
|
55
|
-
// .header-box,
|
|
56
|
-
'.frame-footer .footer-box, .frame-top-menu .desktop-menu-box': {
|
|
57
|
-
display: 'none',
|
|
58
|
-
},
|
|
59
|
-
// '.content-block': {
|
|
60
|
-
// paddingBottom: '16px',
|
|
61
|
-
// },
|
|
62
|
-
'.metronome-page-box, .gauge-box': {
|
|
63
|
-
boxShadow: '#313131 2.02px 2.02px 5.08px 1px !important',
|
|
64
|
-
},
|
|
65
|
-
},
|
|
66
|
-
};
|
|
67
|
-
|
|
68
|
-
return (
|
|
69
|
-
<div css={cssContainer} class='responsive-frame'>
|
|
70
|
-
<div class='frame-top-menu'>
|
|
71
|
-
{/* <DesktopTopMenu title={title}></DesktopTopMenu> */}
|
|
72
|
-
<MobileHeaderComponent></MobileHeaderComponent>
|
|
73
|
-
</div>
|
|
74
|
-
<div class='frame-content'>
|
|
75
|
-
<div class={'content-block ' + placeholderClassname}>{vnode}</div>
|
|
76
|
-
<div class='frame-footer'>
|
|
77
|
-
<div class='footer-box'>
|
|
78
|
-
<div class='footer-cp'>{footerTitle}</div>
|
|
79
|
-
</div>
|
|
80
|
-
<MobileFooterMenu items={bottomMenu}></MobileFooterMenu>
|
|
81
|
-
</div>
|
|
82
|
-
</div>
|
|
83
|
-
</div>
|
|
84
|
-
);
|
|
85
|
-
};
|
|
1
|
+
import { VNode, CssProps, MediaQueryRange } from 'lupine.components';
|
|
2
|
+
import { MobileFooterMenu, MobileFooterMenuItemProps } from '../components/mobile-components/mobile-footer-menu';
|
|
3
|
+
import { MobileHeaderComponent } from '../components/mobile-components/mobile-header-component';
|
|
4
|
+
|
|
5
|
+
export const ResponsiveFrame = async (
|
|
6
|
+
placeholderClassname: string,
|
|
7
|
+
title: string,
|
|
8
|
+
footerTitle: string,
|
|
9
|
+
logoUrl: string,
|
|
10
|
+
vnode: VNode<any>,
|
|
11
|
+
bottomMenu: MobileFooterMenuItemProps[]
|
|
12
|
+
) => {
|
|
13
|
+
const cssContainer: CssProps = {
|
|
14
|
+
display: 'flex',
|
|
15
|
+
flexDirection: 'column',
|
|
16
|
+
width: '100%',
|
|
17
|
+
height: '100%',
|
|
18
|
+
minHeight: '100%',
|
|
19
|
+
'.frame-top-menu': {
|
|
20
|
+
display: 'flex',
|
|
21
|
+
flexDirection: 'column',
|
|
22
|
+
width: '100vw',
|
|
23
|
+
// height: '72px',
|
|
24
|
+
// position: 'fixed',
|
|
25
|
+
// left: 0,
|
|
26
|
+
// top: 0,
|
|
27
|
+
// zIndex: 'var(--layer-menu)',
|
|
28
|
+
backgroundColor: 'var(--activatable-bg-color-normal)',
|
|
29
|
+
},
|
|
30
|
+
'.frame-content': {
|
|
31
|
+
display: 'flex',
|
|
32
|
+
flex: '1',
|
|
33
|
+
flexDirection: 'column',
|
|
34
|
+
// paddingTop: '100px',
|
|
35
|
+
overflowY: 'auto',
|
|
36
|
+
scrollbarWidth: 'none',
|
|
37
|
+
'&::-webkit-scrollbar': {
|
|
38
|
+
height: '0',
|
|
39
|
+
},
|
|
40
|
+
},
|
|
41
|
+
'.content-block': {
|
|
42
|
+
display: 'flex',
|
|
43
|
+
flex: '1',
|
|
44
|
+
flexDirection: 'column',
|
|
45
|
+
overflowY: 'auto',
|
|
46
|
+
scrollbarWidth: 'none',
|
|
47
|
+
},
|
|
48
|
+
'.content-block .padding-block': {
|
|
49
|
+
padding: '0 16px',
|
|
50
|
+
},
|
|
51
|
+
// '.frame-footer': {
|
|
52
|
+
// paddingTop: '57px', // 应该和底部菜单的高度一致
|
|
53
|
+
// },
|
|
54
|
+
[MediaQueryRange.TabletBelow]: {
|
|
55
|
+
// .header-box,
|
|
56
|
+
'.frame-footer .footer-box, .frame-top-menu .desktop-menu-box': {
|
|
57
|
+
display: 'none',
|
|
58
|
+
},
|
|
59
|
+
// '.content-block': {
|
|
60
|
+
// paddingBottom: '16px',
|
|
61
|
+
// },
|
|
62
|
+
'.metronome-page-box, .gauge-box': {
|
|
63
|
+
boxShadow: '#313131 2.02px 2.02px 5.08px 1px !important',
|
|
64
|
+
},
|
|
65
|
+
},
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
return (
|
|
69
|
+
<div css={cssContainer} class='responsive-frame'>
|
|
70
|
+
<div class='frame-top-menu'>
|
|
71
|
+
{/* <DesktopTopMenu title={title}></DesktopTopMenu> */}
|
|
72
|
+
<MobileHeaderComponent></MobileHeaderComponent>
|
|
73
|
+
</div>
|
|
74
|
+
<div class='frame-content'>
|
|
75
|
+
<div class={'content-block ' + placeholderClassname}>{vnode}</div>
|
|
76
|
+
<div class='frame-footer'>
|
|
77
|
+
<div class='footer-box'>
|
|
78
|
+
<div class='footer-cp'>{footerTitle}</div>
|
|
79
|
+
</div>
|
|
80
|
+
<MobileFooterMenu items={bottomMenu}></MobileFooterMenu>
|
|
81
|
+
</div>
|
|
82
|
+
</div>
|
|
83
|
+
</div>
|
|
84
|
+
);
|
|
85
|
+
};
|
|
@@ -1,99 +1,99 @@
|
|
|
1
|
-
import { VNode, CssProps, RefProps } from 'lupine.web';
|
|
2
|
-
import { stopPropagation } from '../lib';
|
|
3
|
-
import { HtmlVar } from '../components';
|
|
4
|
-
import { MediaQueryRange } from '../styles';
|
|
5
|
-
|
|
6
|
-
export type SliderFramePosition = 'desktop-slide-left' | 'desktop-slide-right';
|
|
7
|
-
export type SliderFrameHookProps = {
|
|
8
|
-
load?: (children: VNode<any>) => void;
|
|
9
|
-
close?: (event: Event) => void;
|
|
10
|
-
addClass?: (className: SliderFramePosition) => void;
|
|
11
|
-
};
|
|
12
|
-
|
|
13
|
-
export type SliderFrameProps = {
|
|
14
|
-
defaultContent?: VNode<any> | string;
|
|
15
|
-
direction?: 'right' | 'bottom';
|
|
16
|
-
hook?: SliderFrameHookProps;
|
|
17
|
-
afterClose?: () => void;
|
|
18
|
-
};
|
|
19
|
-
export const SliderFrame = (props: SliderFrameProps) => {
|
|
20
|
-
if (props.hook) {
|
|
21
|
-
props.hook.load = (children) => {
|
|
22
|
-
dom.value = children;
|
|
23
|
-
ref.current?.classList.remove('d-none');
|
|
24
|
-
setTimeout(() => {
|
|
25
|
-
ref.current?.classList.add('show');
|
|
26
|
-
}, 1);
|
|
27
|
-
};
|
|
28
|
-
props.hook.close = (event: Event) => {
|
|
29
|
-
stopPropagation(event);
|
|
30
|
-
ref.current?.classList.remove('show');
|
|
31
|
-
setTimeout(() => {
|
|
32
|
-
ref.current?.classList.add('d-none');
|
|
33
|
-
dom.value = '';
|
|
34
|
-
if (props.afterClose) {
|
|
35
|
-
props.afterClose();
|
|
36
|
-
}
|
|
37
|
-
}, 400);
|
|
38
|
-
};
|
|
39
|
-
props.hook.addClass = (className) => {
|
|
40
|
-
ref.current?.classList.add(className);
|
|
41
|
-
};
|
|
42
|
-
}
|
|
43
|
-
const dom = HtmlVar(<div class='slider-frame-default'>{props.defaultContent || '(No Content)'}</div>);
|
|
44
|
-
const ref: RefProps = {};
|
|
45
|
-
const css: CssProps = {
|
|
46
|
-
display: 'flex',
|
|
47
|
-
flexDirection: 'column',
|
|
48
|
-
position: 'fixed',
|
|
49
|
-
top: '0',
|
|
50
|
-
left: '0',
|
|
51
|
-
right: '0',
|
|
52
|
-
bottom: '0',
|
|
53
|
-
zIndex: 'var(--layer-slider)',
|
|
54
|
-
transform: props.direction === 'bottom' ? 'translateY(100%)' : 'translateX(100%)',
|
|
55
|
-
transition: 'transform 0.4s ease-in-out',
|
|
56
|
-
backgroundColor: 'var(--primary-bg-color)',
|
|
57
|
-
'&.show': {
|
|
58
|
-
transform: props.direction === 'bottom' ? 'translateY(0)' : 'translateX(0)',
|
|
59
|
-
},
|
|
60
|
-
'& > fragment': {
|
|
61
|
-
height: '100%',
|
|
62
|
-
},
|
|
63
|
-
'&.desktop-slide-left': {
|
|
64
|
-
[MediaQueryRange.TabletAbove]: {
|
|
65
|
-
'.header-back-content': {
|
|
66
|
-
width: '30%',
|
|
67
|
-
},
|
|
68
|
-
},
|
|
69
|
-
},
|
|
70
|
-
'&.desktop-slide-right': {
|
|
71
|
-
[MediaQueryRange.TabletAbove]: {
|
|
72
|
-
top: '56px',
|
|
73
|
-
left: '30%',
|
|
74
|
-
transform: 'translateX(0)',
|
|
75
|
-
'.header-back-top': {
|
|
76
|
-
width: '100%',
|
|
77
|
-
boxShadow: 'unset',
|
|
78
|
-
},
|
|
79
|
-
'.header-back-content': {
|
|
80
|
-
width: '100%',
|
|
81
|
-
},
|
|
82
|
-
'.header-back-title': {
|
|
83
|
-
fontSize: '15px',
|
|
84
|
-
},
|
|
85
|
-
'.header-back-left, .header-back-right': {
|
|
86
|
-
display: 'none',
|
|
87
|
-
},
|
|
88
|
-
'&.d-none': {
|
|
89
|
-
display: 'unset !important',
|
|
90
|
-
},
|
|
91
|
-
},
|
|
92
|
-
},
|
|
93
|
-
};
|
|
94
|
-
return (
|
|
95
|
-
<div ref={ref} css={css} class='slider-frame d-none'>
|
|
96
|
-
{dom.node}
|
|
97
|
-
</div>
|
|
98
|
-
);
|
|
99
|
-
};
|
|
1
|
+
import { VNode, CssProps, RefProps } from 'lupine.web';
|
|
2
|
+
import { stopPropagation } from '../lib';
|
|
3
|
+
import { HtmlVar } from '../components';
|
|
4
|
+
import { MediaQueryRange } from '../styles';
|
|
5
|
+
|
|
6
|
+
export type SliderFramePosition = 'desktop-slide-left' | 'desktop-slide-right';
|
|
7
|
+
export type SliderFrameHookProps = {
|
|
8
|
+
load?: (children: VNode<any>) => void;
|
|
9
|
+
close?: (event: Event) => void;
|
|
10
|
+
addClass?: (className: SliderFramePosition) => void;
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
export type SliderFrameProps = {
|
|
14
|
+
defaultContent?: VNode<any> | string;
|
|
15
|
+
direction?: 'right' | 'bottom';
|
|
16
|
+
hook?: SliderFrameHookProps;
|
|
17
|
+
afterClose?: () => void;
|
|
18
|
+
};
|
|
19
|
+
export const SliderFrame = (props: SliderFrameProps) => {
|
|
20
|
+
if (props.hook) {
|
|
21
|
+
props.hook.load = (children) => {
|
|
22
|
+
dom.value = children;
|
|
23
|
+
ref.current?.classList.remove('d-none');
|
|
24
|
+
setTimeout(() => {
|
|
25
|
+
ref.current?.classList.add('show');
|
|
26
|
+
}, 1);
|
|
27
|
+
};
|
|
28
|
+
props.hook.close = (event: Event) => {
|
|
29
|
+
stopPropagation(event);
|
|
30
|
+
ref.current?.classList.remove('show');
|
|
31
|
+
setTimeout(() => {
|
|
32
|
+
ref.current?.classList.add('d-none');
|
|
33
|
+
dom.value = '';
|
|
34
|
+
if (props.afterClose) {
|
|
35
|
+
props.afterClose();
|
|
36
|
+
}
|
|
37
|
+
}, 400);
|
|
38
|
+
};
|
|
39
|
+
props.hook.addClass = (className) => {
|
|
40
|
+
ref.current?.classList.add(className);
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
const dom = HtmlVar(<div class='slider-frame-default'>{props.defaultContent || '(No Content)'}</div>);
|
|
44
|
+
const ref: RefProps = {};
|
|
45
|
+
const css: CssProps = {
|
|
46
|
+
display: 'flex',
|
|
47
|
+
flexDirection: 'column',
|
|
48
|
+
position: 'fixed',
|
|
49
|
+
top: '0',
|
|
50
|
+
left: '0',
|
|
51
|
+
right: '0',
|
|
52
|
+
bottom: '0',
|
|
53
|
+
zIndex: 'var(--layer-slider)',
|
|
54
|
+
transform: props.direction === 'bottom' ? 'translateY(100%)' : 'translateX(100%)',
|
|
55
|
+
transition: 'transform 0.4s ease-in-out',
|
|
56
|
+
backgroundColor: 'var(--primary-bg-color)',
|
|
57
|
+
'&.show': {
|
|
58
|
+
transform: props.direction === 'bottom' ? 'translateY(0)' : 'translateX(0)',
|
|
59
|
+
},
|
|
60
|
+
'& > fragment': {
|
|
61
|
+
height: '100%',
|
|
62
|
+
},
|
|
63
|
+
'&.desktop-slide-left': {
|
|
64
|
+
[MediaQueryRange.TabletAbove]: {
|
|
65
|
+
'.header-back-content': {
|
|
66
|
+
width: '30%',
|
|
67
|
+
},
|
|
68
|
+
},
|
|
69
|
+
},
|
|
70
|
+
'&.desktop-slide-right': {
|
|
71
|
+
[MediaQueryRange.TabletAbove]: {
|
|
72
|
+
top: '56px',
|
|
73
|
+
left: '30%',
|
|
74
|
+
transform: 'translateX(0)',
|
|
75
|
+
'.header-back-top': {
|
|
76
|
+
width: '100%',
|
|
77
|
+
boxShadow: 'unset',
|
|
78
|
+
},
|
|
79
|
+
'.header-back-content': {
|
|
80
|
+
width: '100%',
|
|
81
|
+
},
|
|
82
|
+
'.header-back-title': {
|
|
83
|
+
fontSize: '15px',
|
|
84
|
+
},
|
|
85
|
+
'.header-back-left, .header-back-right': {
|
|
86
|
+
display: 'none',
|
|
87
|
+
},
|
|
88
|
+
'&.d-none': {
|
|
89
|
+
display: 'unset !important',
|
|
90
|
+
},
|
|
91
|
+
},
|
|
92
|
+
},
|
|
93
|
+
};
|
|
94
|
+
return (
|
|
95
|
+
<div ref={ref} css={css} class='slider-frame d-none'>
|
|
96
|
+
{dom.node}
|
|
97
|
+
</div>
|
|
98
|
+
);
|
|
99
|
+
};
|
package/src/frames/top-frame.tsx
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { VNode, CssProps
|
|
1
|
+
import { VNode, CssProps } from 'lupine.web';
|
|
2
2
|
|
|
3
3
|
export const TopFrame = async (placeholderClassname: string, vnode: VNode<any>) => {
|
|
4
4
|
const cssContainer: CssProps = {
|
|
@@ -18,7 +18,7 @@ export const TopFrame = async (placeholderClassname: string, vnode: VNode<any>)
|
|
|
18
18
|
},
|
|
19
19
|
};
|
|
20
20
|
|
|
21
|
-
console.log('Web version: ', getWebVersion());
|
|
21
|
+
// console.log('Web version: ', getWebVersion());
|
|
22
22
|
return (
|
|
23
23
|
<div css={cssContainer}>
|
|
24
24
|
{/* Can't put css on this placeholder node! */}
|