lupine.components 1.1.48 → 1.1.50
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 +2 -2
- package/src/components/action-sheet.tsx +3 -2
- package/src/components/float-window.tsx +3 -2
- package/src/components/loading-spin.tsx +3 -2
- package/src/components/mobile-components/mobile-side-menu.tsx +4 -3
- package/src/frames/responsive-frame.tsx +4 -3
- package/src/frames/slider-helper.tsx +20 -18
- package/src/frames/top-frame.tsx +4 -3
- package/src/lib/index.ts +1 -0
- package/src/lib/support-safe-area.ts +26 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "lupine.components",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.50",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"author": "uuware.com",
|
|
6
6
|
"homepage": "https://github.com/uuware/lupine.js",
|
|
@@ -40,4 +40,4 @@
|
|
|
40
40
|
"dependencies": {
|
|
41
41
|
"lupine.web": "^1.0.0"
|
|
42
42
|
}
|
|
43
|
-
}
|
|
43
|
+
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { CssProps, RefProps, VNode, mountInnerComponent } from 'lupine.web';
|
|
1
|
+
import { CssProps, RefProps, VNode, callUnload, mountInnerComponent } from 'lupine.web';
|
|
2
2
|
import { backActionHelper } from '../lib';
|
|
3
3
|
import { NotificationColor, NotificationMessage } from './notice-message';
|
|
4
4
|
|
|
@@ -55,7 +55,8 @@ export class ActionSheet {
|
|
|
55
55
|
const handleClose = (reason?: ActionSheetCloseReasonProps) => {
|
|
56
56
|
closeEvent?.(reason);
|
|
57
57
|
ref.current.classList.remove('animation-open');
|
|
58
|
-
setTimeout(() => {
|
|
58
|
+
setTimeout(async () => {
|
|
59
|
+
await callUnload(base);
|
|
59
60
|
base.remove();
|
|
60
61
|
}, 300);
|
|
61
62
|
};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { CssProps, RefProps, VNode, mountInnerComponent } from 'lupine.web';
|
|
1
|
+
import { CssProps, RefProps, VNode, callUnload, mountInnerComponent } from 'lupine.web';
|
|
2
2
|
import { stopPropagation, backActionHelper } from '../lib';
|
|
3
3
|
|
|
4
4
|
export type FloatWindowCloseProps = () => void;
|
|
@@ -57,7 +57,8 @@ export class FloatWindow {
|
|
|
57
57
|
closeEvent?.();
|
|
58
58
|
ref.current.classList.add('transition');
|
|
59
59
|
ref.current.classList.remove('animation');
|
|
60
|
-
setTimeout(() => {
|
|
60
|
+
setTimeout(async () => {
|
|
61
|
+
await callUnload(base);
|
|
61
62
|
base.remove();
|
|
62
63
|
}, 300);
|
|
63
64
|
};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { RefProps, Spinner02, SpinnerSize } from 'lupine.components';
|
|
2
|
-
import { CssProps, mountInnerComponent } from 'lupine.components';
|
|
2
|
+
import { CssProps, callUnload, mountInnerComponent } from 'lupine.components';
|
|
3
3
|
|
|
4
4
|
export type LoadingSpinHookProps = {
|
|
5
5
|
show?: () => void;
|
|
@@ -46,7 +46,8 @@ export const LoadingSpinComponent = (props: LoadingSpinProps) => {
|
|
|
46
46
|
|
|
47
47
|
export class LoadingSpin {
|
|
48
48
|
static async show(): Promise<() => void> {
|
|
49
|
-
const handleClose = () => {
|
|
49
|
+
const handleClose = async () => {
|
|
50
|
+
await callUnload(base);
|
|
50
51
|
base.remove();
|
|
51
52
|
};
|
|
52
53
|
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { backActionHelper, CssProps, RefProps, VNode, MediaQueryRange } from 'lupine.components';
|
|
2
|
+
import { isSafeAreaSupported } from '../../lib/support-safe-area';
|
|
2
3
|
|
|
3
4
|
export class MobileSideMenuHelper {
|
|
4
5
|
static show() {
|
|
@@ -74,7 +75,7 @@ export class MobileSideMenuHelper {
|
|
|
74
75
|
moveStart = false;
|
|
75
76
|
pendingOpen = false;
|
|
76
77
|
isOpen = maskDom.classList.contains('show');
|
|
77
|
-
|
|
78
|
+
|
|
78
79
|
const menuDom = maskDom.querySelector('.mobile-side-menu') as HTMLDivElement;
|
|
79
80
|
if (menuDom) {
|
|
80
81
|
menuWidth = menuDom.offsetWidth || 210; // Fallback width roughly 70% of 300px
|
|
@@ -243,8 +244,8 @@ export const MobileSideMenu = (props: { children: VNode<any>; autoExtend?: boole
|
|
|
243
244
|
overflowY: 'auto',
|
|
244
245
|
transform: 'translateX(-100%)',
|
|
245
246
|
boxShadow: 'var(--cover-box-shadow)',
|
|
246
|
-
'padding-top ': 'constant(safe-area-inset-top)',
|
|
247
|
-
'padding-top': 'env(safe-area-inset-top)',
|
|
247
|
+
'padding-top ': isSafeAreaSupported() ? 'constant(safe-area-inset-top)' : '0',
|
|
248
|
+
'padding-top': isSafeAreaSupported() ? 'env(safe-area-inset-top)' : '0',
|
|
248
249
|
},
|
|
249
250
|
[MediaQueryRange.TabletAbove]: {
|
|
250
251
|
'&.auto-extend .mobile-side-menu-mask': {
|
|
@@ -2,13 +2,14 @@
|
|
|
2
2
|
sliderFrameHook is for slider frame from right or bottom used in side-menu
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
|
-
import { VNode, CssProps, MediaQueryRange,
|
|
5
|
+
import { VNode, CssProps, MediaQueryRange, RefProps } from 'lupine.components';
|
|
6
6
|
import { MobileFooterMenu } from '../components/mobile-components/mobile-footer-menu';
|
|
7
7
|
import { DesktopFooter } from '../components/desktop-footer';
|
|
8
8
|
import { DesktopHeader } from '../components/desktop-header';
|
|
9
9
|
import { MobileHeaderComponent } from '../components/mobile-components/mobile-header-component';
|
|
10
10
|
import { MobileSideMenu } from '../components/mobile-components/mobile-side-menu';
|
|
11
11
|
import { IconMenuItemProps } from '../components/mobile-components/icon-menu-item-props';
|
|
12
|
+
import { isSafeAreaSupported } from '../lib/support-safe-area';
|
|
12
13
|
|
|
13
14
|
export interface ResponsiveFrameProps {
|
|
14
15
|
placeholderClassname: string;
|
|
@@ -37,8 +38,8 @@ export const ResponsiveFrame = (props: ResponsiveFrameProps) => {
|
|
|
37
38
|
margin: '0 auto',
|
|
38
39
|
overflowX: 'hidden',
|
|
39
40
|
...(!props.noSafeAreaTop ? {
|
|
40
|
-
'padding-top ': 'constant(safe-area-inset-top)',
|
|
41
|
-
'padding-top': 'env(safe-area-inset-top)',
|
|
41
|
+
'padding-top ': isSafeAreaSupported() ? 'constant(safe-area-inset-top)' : '',
|
|
42
|
+
'padding-top': isSafeAreaSupported() ? 'env(safe-area-inset-top)' : '',
|
|
42
43
|
} : {}),
|
|
43
44
|
'.frame-top-menu': {
|
|
44
45
|
display: 'flex',
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import { CssProps, RefProps, VNode, mountInnerComponent } from 'lupine.web';
|
|
1
|
+
import { CssProps, RefProps, VNode, callUnload, mountInnerComponent } from 'lupine.web';
|
|
2
2
|
import { backActionHelper, stopPropagation } from '../lib';
|
|
3
3
|
import { MediaQueryMaxWidth, MediaQueryRange } from '../styles';
|
|
4
|
+
import { isSafeAreaSupported } from '../lib/support-safe-area';
|
|
4
5
|
|
|
5
6
|
export type SliderHelperDirection = 'right' | 'left' | 'bottom' | 'top';
|
|
6
7
|
export type SliderHelperCloseProps = () => void;
|
|
@@ -41,7 +42,8 @@ export class SliderHelper {
|
|
|
41
42
|
closeEvent?.();
|
|
42
43
|
ref.current?.classList.remove('show');
|
|
43
44
|
ref.current?.classList.add(closeClassName);
|
|
44
|
-
setTimeout(() => {
|
|
45
|
+
setTimeout(async () => {
|
|
46
|
+
await callUnload(base);
|
|
45
47
|
base.remove();
|
|
46
48
|
}, 400);
|
|
47
49
|
};
|
|
@@ -95,21 +97,21 @@ export class SliderHelper {
|
|
|
95
97
|
|
|
96
98
|
const contentCss: CssProps = isHorizontal
|
|
97
99
|
? {
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
100
|
+
top: '0',
|
|
101
|
+
bottom: '0',
|
|
102
|
+
width: '100%',
|
|
103
|
+
maxWidth,
|
|
104
|
+
[direction]: '0',
|
|
105
|
+
}
|
|
104
106
|
: {
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
107
|
+
top: direction === 'top' ? '0' : 'auto',
|
|
108
|
+
bottom: direction === 'bottom' ? '0' : 'auto',
|
|
109
|
+
left: 'auto',
|
|
110
|
+
right: '0',
|
|
111
|
+
width: '100%',
|
|
112
|
+
maxWidth,
|
|
113
|
+
height: '100%',
|
|
114
|
+
};
|
|
113
115
|
|
|
114
116
|
const cssContainer: CssProps = {
|
|
115
117
|
display: 'flex',
|
|
@@ -155,8 +157,8 @@ export class SliderHelper {
|
|
|
155
157
|
transform: startTransform,
|
|
156
158
|
transition: 'transform 0.4s ease-in-out',
|
|
157
159
|
// trick: to put two padding-top properties
|
|
158
|
-
'padding-top ': 'constant(safe-area-inset-top)',
|
|
159
|
-
'padding-top': 'env(safe-area-inset-top)',
|
|
160
|
+
'padding-top ': isSafeAreaSupported() ? 'constant(safe-area-inset-top)' : '0',
|
|
161
|
+
'padding-top': isSafeAreaSupported() ? 'env(safe-area-inset-top)' : '0',
|
|
160
162
|
...contentCss,
|
|
161
163
|
'&::-webkit-scrollbar': {
|
|
162
164
|
display: 'none',
|
package/src/frames/top-frame.tsx
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
place to set safe-area-inset-top and other common styles
|
|
3
3
|
*/
|
|
4
4
|
import { VNode, CssProps } from 'lupine.components';
|
|
5
|
+
import { isSafeAreaSupported } from '../lib/support-safe-area';
|
|
5
6
|
|
|
6
7
|
// TopFrame and ResponsiveFrame both contain safe-area-inset-top, so can't use them togother
|
|
7
8
|
export const TopFrame = async ({
|
|
@@ -27,9 +28,9 @@ export const TopFrame = async ({
|
|
|
27
28
|
// trick: to put two padding-top properties
|
|
28
29
|
...(!noSafeAreaTop
|
|
29
30
|
? {
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
31
|
+
'padding-top ': isSafeAreaSupported() ? 'constant(safe-area-inset-top)' : '',
|
|
32
|
+
'padding-top': isSafeAreaSupported() ? 'env(safe-area-inset-top)' : '',
|
|
33
|
+
}
|
|
33
34
|
: {}),
|
|
34
35
|
},
|
|
35
36
|
};
|
package/src/lib/index.ts
CHANGED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
|
|
2
|
+
const shouldApplySafeAreaTopPadding = () => {
|
|
3
|
+
if (typeof navigator === 'undefined') return true;
|
|
4
|
+
const ua = navigator.userAgent;
|
|
5
|
+
|
|
6
|
+
// match old Android devices
|
|
7
|
+
if (!/(vivo|oppo|xiaomi|redmi|huawei|honor)/i.test(ua)) return true;
|
|
8
|
+
|
|
9
|
+
// parse Android version
|
|
10
|
+
const match = ua.match(/Android\s+([\d\.]+)/i);
|
|
11
|
+
if (match) {
|
|
12
|
+
const version = parseFloat(match[1]);
|
|
13
|
+
// Android version < 10 has bug that return env value even if padding is added
|
|
14
|
+
if (version <= 10) return false;
|
|
15
|
+
}
|
|
16
|
+
return true;
|
|
17
|
+
};
|
|
18
|
+
const _safearea = {
|
|
19
|
+
supported: shouldApplySafeAreaTopPadding(),
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export const isSafeAreaSupported = () => _safearea.supported;
|
|
23
|
+
// for customize development, disable safearea for some mobile devices
|
|
24
|
+
export const setSafeAreaSupported = (supported: boolean) => {
|
|
25
|
+
_safearea.supported = supported;
|
|
26
|
+
}
|