lupine.components 1.1.57 → 1.1.59
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/component-pool/range/range.tsx +36 -13
- package/src/components/index.ts +1 -0
- package/src/components/mobile-components/mobile-side-menu.tsx +0 -1
- package/src/components/mobile-components/mobile-top-sys-icon.tsx +8 -3
- package/src/components/notice-message.tsx +0 -1
- package/src/components/slide-page-component-demo.tsx +364 -0
- package/src/components/slide-page-component.tsx +777 -0
- package/src/components/slide-tab-component.tsx +158 -79
- package/src/demo/demo-frame-helper.tsx +7 -0
- package/src/demo/demo-registry.ts +2 -0
- package/src/frames/responsive-frame.tsx +0 -1
- package/src/frames/slider-frame-demo.tsx +12 -1
- package/src/frames/slider-frame.tsx +2 -0
- package/src/frames/slider-helper.tsx +7 -1
- package/src/frames/top-frame.tsx +0 -1
|
@@ -1,130 +1,209 @@
|
|
|
1
1
|
import { CssProps, RefProps, VNode, bindGlobalStyle } from 'lupine.components';
|
|
2
2
|
|
|
3
|
+
export interface SlideTabHookProps {
|
|
4
|
+
moveTo?: (index: number) => void;
|
|
5
|
+
getIndex?: () => number;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
export interface SlideTabPage {
|
|
9
|
+
id?: string;
|
|
10
|
+
title: string;
|
|
11
|
+
content: VNode<any> | any;
|
|
12
|
+
}
|
|
13
|
+
|
|
3
14
|
export interface SlideTabProps {
|
|
4
|
-
pages:
|
|
15
|
+
pages: SlideTabPage[];
|
|
16
|
+
hook?: SlideTabHookProps;
|
|
17
|
+
initialIndex?: number;
|
|
18
|
+
onChange?: (index: number, page: SlideTabPage) => void;
|
|
19
|
+
navClass?: string;
|
|
20
|
+
class?: string;
|
|
5
21
|
}
|
|
22
|
+
|
|
6
23
|
export const SlideTabComponent = (props: SlideTabProps) => {
|
|
7
24
|
const css: CssProps = {
|
|
8
25
|
display: 'flex',
|
|
9
26
|
flexDirection: 'column',
|
|
10
27
|
flex: 1,
|
|
11
|
-
|
|
12
|
-
borderRadius: '6px',
|
|
13
|
-
padding: '0px 8px 4px 8px',
|
|
14
|
-
// marginBottom: '8px',
|
|
28
|
+
width: '100%',
|
|
15
29
|
height: '100%',
|
|
16
|
-
'
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
display: 'flex',
|
|
20
|
-
overflowX: 'auto',
|
|
21
|
-
width: '100%',
|
|
22
|
-
scrollSnapType: 'x mandatory',
|
|
23
|
-
gap: '8px',
|
|
24
|
-
paddingBottom: '10px',
|
|
25
|
-
scrollBehavior: 'smooth',
|
|
26
|
-
WebkitOverflowScrolling: 'touch',
|
|
27
|
-
},
|
|
28
|
-
'.slide-tab-c-slide': {
|
|
29
|
-
width: '100%',
|
|
30
|
-
overflow: 'hidden',
|
|
31
|
-
position: 'relative',
|
|
32
|
-
minWidth: '100%',
|
|
33
|
-
flexShrink: 0,
|
|
34
|
-
scrollSnapAlign: 'start',
|
|
35
|
-
height: '100%',
|
|
36
|
-
overflowY: 'auto',
|
|
37
|
-
},
|
|
30
|
+
overflow: 'hidden',
|
|
31
|
+
position: 'relative',
|
|
32
|
+
boxSizing: 'border-box',
|
|
38
33
|
|
|
39
34
|
'.slide-tab-c-nav': {
|
|
40
35
|
display: 'flex',
|
|
41
36
|
flexDirection: 'row',
|
|
42
|
-
|
|
37
|
+
alignItems: 'center',
|
|
43
38
|
backgroundColor: 'var(--primary-bg-color)',
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
39
|
+
borderBottom: '1px solid var(--secondary-border-color)',
|
|
40
|
+
padding: '10px 16px 8px 16px',
|
|
41
|
+
overflowX: 'auto',
|
|
42
|
+
WebkitOverflowScrolling: 'touch',
|
|
43
|
+
flexShrink: 0,
|
|
44
|
+
zIndex: 10,
|
|
45
|
+
scrollbarWidth: 'none',
|
|
46
|
+
'&::-webkit-scrollbar': { display: 'none' },
|
|
47
47
|
},
|
|
48
48
|
'.slide-tab-c-nav-wrap': {
|
|
49
49
|
display: 'flex',
|
|
50
50
|
flexDirection: 'row',
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
51
|
+
alignItems: 'center',
|
|
52
|
+
gap: '8px',
|
|
53
|
+
flexShrink: 0,
|
|
54
|
+
paddingRight: '16px',
|
|
55
55
|
},
|
|
56
56
|
'.slide-tab-c-nav-item': {
|
|
57
57
|
cursor: 'pointer',
|
|
58
|
-
padding: '
|
|
59
|
-
borderRadius: '
|
|
60
|
-
|
|
58
|
+
padding: '7px 16px',
|
|
59
|
+
borderRadius: '20px',
|
|
60
|
+
fontSize: '13px',
|
|
61
|
+
fontWeight: 600,
|
|
62
|
+
color: 'var(--secondary-color)',
|
|
63
|
+
backgroundColor: 'var(--secondary-bg-color)',
|
|
64
|
+
whiteSpace: 'nowrap',
|
|
65
|
+
transition: 'all 0.18s ease',
|
|
66
|
+
WebkitTapHighlightColor: 'transparent',
|
|
67
|
+
flexShrink: 0,
|
|
68
|
+
userSelect: 'none',
|
|
69
|
+
WebkitUserSelect: 'none',
|
|
70
|
+
'&:active': {
|
|
71
|
+
transform: 'scale(0.96)',
|
|
72
|
+
opacity: 0.85,
|
|
73
|
+
},
|
|
61
74
|
},
|
|
62
75
|
'.slide-tab-c-nav-item.active': {
|
|
63
76
|
backgroundColor: 'var(--primary-accent-color)',
|
|
64
|
-
color: '
|
|
77
|
+
color: '#ffffff',
|
|
78
|
+
boxShadow: '0 2px 8px rgba(2, 132, 199, 0.35)',
|
|
79
|
+
},
|
|
80
|
+
|
|
81
|
+
'.slide-tab-c-list': {
|
|
82
|
+
flex: 1,
|
|
83
|
+
display: 'flex',
|
|
84
|
+
flexDirection: 'row',
|
|
85
|
+
overflowX: 'auto',
|
|
86
|
+
overflowY: 'hidden',
|
|
87
|
+
width: '100%',
|
|
88
|
+
height: '100%',
|
|
89
|
+
scrollSnapType: 'x mandatory',
|
|
90
|
+
scrollBehavior: 'smooth',
|
|
91
|
+
WebkitOverflowScrolling: 'touch',
|
|
92
|
+
boxSizing: 'border-box',
|
|
93
|
+
scrollbarWidth: 'none',
|
|
94
|
+
'&::-webkit-scrollbar': { display: 'none' },
|
|
95
|
+
},
|
|
96
|
+
'.slide-tab-c-slide': {
|
|
97
|
+
width: '100%',
|
|
98
|
+
minWidth: '100%',
|
|
99
|
+
maxWidth: '100%',
|
|
100
|
+
flexShrink: 0,
|
|
101
|
+
height: '100%',
|
|
102
|
+
overflowY: 'auto',
|
|
103
|
+
position: 'relative',
|
|
104
|
+
scrollSnapAlign: 'start',
|
|
105
|
+
scrollSnapStop: 'always',
|
|
106
|
+
WebkitOverflowScrolling: 'touch',
|
|
107
|
+
boxSizing: 'border-box',
|
|
108
|
+
scrollbarWidth: 'none',
|
|
109
|
+
'&::-webkit-scrollbar': { display: 'none' },
|
|
65
110
|
},
|
|
66
111
|
};
|
|
67
112
|
bindGlobalStyle('slide-tab-c-box', css);
|
|
68
113
|
|
|
69
114
|
const ref: RefProps = {};
|
|
70
|
-
let slideIndex = 0;
|
|
115
|
+
let slideIndex = props.initialIndex || 0;
|
|
71
116
|
let manualScroll = false;
|
|
72
|
-
let scrollEndTimer:
|
|
73
|
-
|
|
74
|
-
if (manualScroll) {
|
|
75
|
-
return;
|
|
76
|
-
}
|
|
77
|
-
if (scrollEndTimer) {
|
|
78
|
-
clearTimeout(scrollEndTimer);
|
|
79
|
-
}
|
|
80
|
-
scrollEndTimer = setTimeout(() => {
|
|
81
|
-
drawerScrollStop();
|
|
82
|
-
}, 100);
|
|
83
|
-
};
|
|
117
|
+
let scrollEndTimer: any = null;
|
|
118
|
+
|
|
84
119
|
const resetSlides = (index: number) => {
|
|
85
|
-
const dots = ref.$all('.slide-tab-c-nav-item');
|
|
86
|
-
|
|
87
|
-
|
|
120
|
+
const dots = ref.$all?.('.slide-tab-c-nav-item');
|
|
121
|
+
if (dots) {
|
|
122
|
+
for (let i = 0; i < dots.length; i++) {
|
|
123
|
+
dots[i].classList.toggle('active', i === index);
|
|
124
|
+
}
|
|
125
|
+
dots[index]?.scrollIntoView({ behavior: 'smooth', block: 'nearest', inline: 'center' });
|
|
126
|
+
}
|
|
127
|
+
if (props.onChange && props.pages[index]) {
|
|
128
|
+
props.onChange(index, props.pages[index]);
|
|
88
129
|
}
|
|
89
130
|
};
|
|
131
|
+
|
|
90
132
|
const drawerScrollStop = () => {
|
|
91
|
-
const drawer = ref
|
|
133
|
+
const drawer = ref.$?.('.slide-tab-c-list') as HTMLElement | undefined;
|
|
134
|
+
if (!drawer) return;
|
|
92
135
|
const width = drawer.clientWidth;
|
|
136
|
+
if (width <= 0) return;
|
|
93
137
|
const currentScrollIndex = Math.round(drawer.scrollLeft / width);
|
|
94
|
-
slideIndex
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
const moveSlide = (slideIndex: number) => {
|
|
98
|
-
const drawer = ref.$('.slide-tab-c-list');
|
|
99
|
-
const children = ref.$all('.slide-tab-c-slide');
|
|
100
|
-
if (!drawer || !children || children.length === 0) {
|
|
101
|
-
return;
|
|
138
|
+
if (currentScrollIndex !== slideIndex && currentScrollIndex >= 0 && currentScrollIndex < props.pages.length) {
|
|
139
|
+
slideIndex = currentScrollIndex;
|
|
140
|
+
resetSlides(slideIndex);
|
|
102
141
|
}
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
142
|
+
};
|
|
143
|
+
|
|
144
|
+
const drawerScroll = () => {
|
|
145
|
+
if (manualScroll) return;
|
|
146
|
+
if (scrollEndTimer) clearTimeout(scrollEndTimer);
|
|
147
|
+
scrollEndTimer = setTimeout(() => {
|
|
148
|
+
drawerScrollStop();
|
|
149
|
+
}, 60);
|
|
150
|
+
};
|
|
151
|
+
|
|
152
|
+
const moveSlide = (targetIndex: number) => {
|
|
153
|
+
const drawer = ref.$?.('.slide-tab-c-list') as HTMLElement | undefined;
|
|
154
|
+
if (!drawer) return;
|
|
155
|
+
const width = drawer.clientWidth;
|
|
156
|
+
if (width <= 0) return;
|
|
157
|
+
|
|
108
158
|
manualScroll = true;
|
|
159
|
+
slideIndex = targetIndex;
|
|
160
|
+
resetSlides(slideIndex);
|
|
161
|
+
|
|
109
162
|
drawer.scrollTo({
|
|
110
|
-
left:
|
|
163
|
+
left: targetIndex * width,
|
|
111
164
|
behavior: 'smooth',
|
|
112
165
|
});
|
|
113
166
|
|
|
114
|
-
resetSlides(slideIndex);
|
|
115
167
|
setTimeout(() => {
|
|
116
168
|
manualScroll = false;
|
|
117
|
-
},
|
|
169
|
+
}, 350);
|
|
170
|
+
};
|
|
171
|
+
|
|
172
|
+
if (props.hook) {
|
|
173
|
+
props.hook.moveTo = moveSlide;
|
|
174
|
+
props.hook.getIndex = () => slideIndex;
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
ref.onLoad = async () => {
|
|
178
|
+
const drawer = ref.$?.('.slide-tab-c-list') as HTMLElement | undefined;
|
|
179
|
+
if (drawer) {
|
|
180
|
+
drawer.addEventListener('scrollend', drawerScrollStop);
|
|
181
|
+
}
|
|
182
|
+
if (slideIndex > 0) {
|
|
183
|
+
setTimeout(() => {
|
|
184
|
+
moveSlide(slideIndex);
|
|
185
|
+
}, 50);
|
|
186
|
+
}
|
|
187
|
+
};
|
|
188
|
+
|
|
189
|
+
ref.onUnload = async () => {
|
|
190
|
+
const drawer = ref.$?.('.slide-tab-c-list') as HTMLElement | undefined;
|
|
191
|
+
if (drawer) {
|
|
192
|
+
drawer.removeEventListener('scrollend', drawerScrollStop);
|
|
193
|
+
}
|
|
194
|
+
if (scrollEndTimer) {
|
|
195
|
+
clearTimeout(scrollEndTimer);
|
|
196
|
+
}
|
|
118
197
|
};
|
|
119
198
|
|
|
120
199
|
return (
|
|
121
|
-
<section class=
|
|
122
|
-
<div class=
|
|
123
|
-
<div class=
|
|
200
|
+
<section class={`slide-tab-c-box ${props.class || ''}`} ref={ref}>
|
|
201
|
+
<div class={`slide-tab-c-nav no-scrollbar-container ${props.navClass || ''}`}>
|
|
202
|
+
<div class="slide-tab-c-nav-wrap">
|
|
124
203
|
{props.pages.map((page, index) => (
|
|
125
204
|
<div
|
|
126
|
-
class={`slide-tab-c-nav-item ${index ===
|
|
127
|
-
onClick={(event) => {
|
|
205
|
+
class={`slide-tab-c-nav-item ${index === slideIndex ? 'active' : ''}`}
|
|
206
|
+
onClick={(event: any) => {
|
|
128
207
|
event.preventDefault();
|
|
129
208
|
moveSlide(index);
|
|
130
209
|
}}
|
|
@@ -134,9 +213,9 @@ export const SlideTabComponent = (props: SlideTabProps) => {
|
|
|
134
213
|
))}
|
|
135
214
|
</div>
|
|
136
215
|
</div>
|
|
137
|
-
<div class=
|
|
216
|
+
<div class="slide-tab-c-list no-scrollbar-container" onScroll={drawerScroll}>
|
|
138
217
|
{props.pages.map((page) => (
|
|
139
|
-
<div class=
|
|
218
|
+
<div class="slide-tab-c-slide no-scrollbar-container">{page.content}</div>
|
|
140
219
|
))}
|
|
141
220
|
</div>
|
|
142
221
|
</section>
|
|
@@ -54,6 +54,7 @@ import { searchInputDemo } from '../component-pool/search-input';
|
|
|
54
54
|
import { hEditorDemo } from '../component-pool/h-editor';
|
|
55
55
|
import { pagingLinkDemo } from '../components/paging-link-demo';
|
|
56
56
|
import { slideTabDemo } from '../components/slide-tab-component-demo';
|
|
57
|
+
import { slidePageDemo } from '../components/slide-page-component-demo';
|
|
57
58
|
import { qrcodeDemo } from '../component-pool/qrcode';
|
|
58
59
|
import { iEditorDemo } from '../component-pool/i-editor';
|
|
59
60
|
import { youtubePlayerDemo } from '../component-pool/youtube-player';
|
|
@@ -336,6 +337,12 @@ export class DemoFrameHelper {
|
|
|
336
337
|
url: '',
|
|
337
338
|
js: () => this.addPanel(slideTabDemo.text, <DemoPage story={slideTabDemo} />),
|
|
338
339
|
},
|
|
340
|
+
{
|
|
341
|
+
id: slidePageDemo.id,
|
|
342
|
+
text: slidePageDemo.text,
|
|
343
|
+
url: '',
|
|
344
|
+
js: () => this.addPanel(slidePageDemo.text, <DemoPage story={slidePageDemo} />),
|
|
345
|
+
},
|
|
339
346
|
{
|
|
340
347
|
id: pagingLinkDemo.id,
|
|
341
348
|
text: pagingLinkDemo.text,
|
|
@@ -52,6 +52,7 @@ import { searchInputDemo } from '../component-pool/search-input';
|
|
|
52
52
|
import { pagingLinkDemo } from '../components/paging-link-demo';
|
|
53
53
|
import { hEditorDemo } from '../component-pool/h-editor';
|
|
54
54
|
import { slideTabDemo } from '../components/slide-tab-component-demo';
|
|
55
|
+
import { slidePageDemo } from '../components/slide-page-component-demo';
|
|
55
56
|
import { qrcodeDemo } from '../component-pool/qrcode';
|
|
56
57
|
import { iEditorDemo } from '../component-pool/i-editor';
|
|
57
58
|
import { youtubePlayerDemo } from '../component-pool/youtube-player';
|
|
@@ -125,6 +126,7 @@ export const demoRegistry: Record<string, DemoStory<any>> = {
|
|
|
125
126
|
[pagingLinkDemo.id]: pagingLinkDemo,
|
|
126
127
|
[hEditorDemo.id]: hEditorDemo,
|
|
127
128
|
[slideTabDemo.id]: slideTabDemo,
|
|
129
|
+
[slidePageDemo.id]: slidePageDemo,
|
|
128
130
|
[qrcodeDemo.id]: qrcodeDemo,
|
|
129
131
|
[iEditorDemo.id]: iEditorDemo,
|
|
130
132
|
[youtubePlayerDemo.id]: youtubePlayerDemo,
|
|
@@ -38,7 +38,6 @@ export const ResponsiveFrame = (props: ResponsiveFrameProps) => {
|
|
|
38
38
|
margin: '0 auto',
|
|
39
39
|
overflowX: 'hidden',
|
|
40
40
|
...(!props.noSafeAreaTop ? {
|
|
41
|
-
'padding-top ': isSafeAreaSupported() ? 'constant(safe-area-inset-top)' : '',
|
|
42
41
|
'padding-top': isSafeAreaSupported() ? 'env(safe-area-inset-top)' : '',
|
|
43
42
|
} : {}),
|
|
44
43
|
'.frame-top-menu': {
|
|
@@ -24,6 +24,7 @@ export const sliderFrameDemo: DemoStory<any> = {
|
|
|
24
24
|
text: 'Slider Frame Demo',
|
|
25
25
|
args: {
|
|
26
26
|
direction: 'right',
|
|
27
|
+
addBottomSafearea: false,
|
|
27
28
|
},
|
|
28
29
|
argTypes: {
|
|
29
30
|
direction: {
|
|
@@ -31,6 +32,10 @@ export const sliderFrameDemo: DemoStory<any> = {
|
|
|
31
32
|
options: ['right', 'bottom'],
|
|
32
33
|
description: 'Direction the slider enters from',
|
|
33
34
|
},
|
|
35
|
+
addBottomSafearea: {
|
|
36
|
+
control: 'boolean',
|
|
37
|
+
description: 'Add safe area padding at bottom',
|
|
38
|
+
},
|
|
34
39
|
},
|
|
35
40
|
render: (args) => {
|
|
36
41
|
const sliderHook: SliderFrameHookProps = {};
|
|
@@ -54,6 +59,7 @@ export const sliderFrameDemo: DemoStory<any> = {
|
|
|
54
59
|
let close: SliderHelperCloseProps;
|
|
55
60
|
close = await SliderHelper.show({
|
|
56
61
|
direction: args.direction,
|
|
62
|
+
addBottomSafearea: args.addBottomSafearea,
|
|
57
63
|
children: (
|
|
58
64
|
<HeaderWithBackFrame title='Slider Helper Inner Page' onBack={() => close()}>
|
|
59
65
|
<div style={{ padding: '20px', display: 'flex', flexDirection: 'column', gap: '20px' }}>
|
|
@@ -71,7 +77,12 @@ export const sliderFrameDemo: DemoStory<any> = {
|
|
|
71
77
|
</div>
|
|
72
78
|
|
|
73
79
|
{/* The SliderFrame is placed here but initially hidden */}
|
|
74
|
-
<SliderFrame
|
|
80
|
+
<SliderFrame
|
|
81
|
+
hook={sliderHook}
|
|
82
|
+
direction={args.direction}
|
|
83
|
+
addBottomSafearea={args.addBottomSafearea}
|
|
84
|
+
defaultContent=''
|
|
85
|
+
/>
|
|
75
86
|
</div>
|
|
76
87
|
);
|
|
77
88
|
},
|
|
@@ -27,6 +27,7 @@ export type SliderFrameProps = {
|
|
|
27
27
|
hook?: SliderFrameHookProps;
|
|
28
28
|
afterClose?: () => void | Promise<void>;
|
|
29
29
|
maxWidth?: string;
|
|
30
|
+
addBottomSafearea?: boolean;
|
|
30
31
|
};
|
|
31
32
|
export const SliderFrame = (props: SliderFrameProps) => {
|
|
32
33
|
let closeSlider: SliderHelperCloseProps | undefined;
|
|
@@ -39,6 +40,7 @@ export const SliderFrame = (props: SliderFrameProps) => {
|
|
|
39
40
|
direction: props.direction || 'right',
|
|
40
41
|
children,
|
|
41
42
|
maxWidth: props.maxWidth,
|
|
43
|
+
addBottomSafearea: props.addBottomSafearea ?? false,
|
|
42
44
|
closeEvent: () => {
|
|
43
45
|
opened = false;
|
|
44
46
|
closeSlider = undefined;
|
|
@@ -16,6 +16,7 @@ export type SliderHelperShowProps = {
|
|
|
16
16
|
className?: string;
|
|
17
17
|
contentClassName?: string;
|
|
18
18
|
mountTarget?: HTMLElement;
|
|
19
|
+
addBottomSafearea?: boolean;
|
|
19
20
|
};
|
|
20
21
|
|
|
21
22
|
export class SliderHelper {
|
|
@@ -29,6 +30,7 @@ export class SliderHelper {
|
|
|
29
30
|
className = '',
|
|
30
31
|
contentClassName = '',
|
|
31
32
|
mountTarget,
|
|
33
|
+
addBottomSafearea = false,
|
|
32
34
|
}: SliderHelperShowProps): Promise<SliderHelperCloseProps> {
|
|
33
35
|
const base = document.createElement('div');
|
|
34
36
|
const isHorizontal = direction === 'left' || direction === 'right';
|
|
@@ -157,8 +159,12 @@ export class SliderHelper {
|
|
|
157
159
|
transform: startTransform,
|
|
158
160
|
transition: 'transform 0.4s ease-in-out',
|
|
159
161
|
// trick: to put two padding-top properties
|
|
160
|
-
'padding-top ': isSafeAreaSupported() ? 'constant(safe-area-inset-top)' : '0',
|
|
161
162
|
'padding-top': isSafeAreaSupported() ? 'env(safe-area-inset-top)' : '0',
|
|
163
|
+
...(addBottomSafearea
|
|
164
|
+
? {
|
|
165
|
+
'padding-bottom': isSafeAreaSupported() ? 'env(safe-area-inset-bottom)' : '0',
|
|
166
|
+
}
|
|
167
|
+
: {}),
|
|
162
168
|
...contentCss,
|
|
163
169
|
'&::-webkit-scrollbar': {
|
|
164
170
|
display: 'none',
|
package/src/frames/top-frame.tsx
CHANGED
|
@@ -28,7 +28,6 @@ export const TopFrame = async ({
|
|
|
28
28
|
// trick: to put two padding-top properties
|
|
29
29
|
...(!noSafeAreaTop
|
|
30
30
|
? {
|
|
31
|
-
'padding-top ': isSafeAreaSupported() ? 'constant(safe-area-inset-top)' : '',
|
|
32
31
|
'padding-top': isSafeAreaSupported() ? 'env(safe-area-inset-top)' : '',
|
|
33
32
|
}
|
|
34
33
|
: {}),
|