Skip to content

Commit d2828df

Browse files
committed
fix: ionic dynamic height tabs
1 parent b8d65c8 commit d2828df

File tree

5 files changed

+69
-19
lines changed

5 files changed

+69
-19
lines changed

src/composables/coinTokensProps.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ interface ITokenPropsState {
1818
const tokenProps = ref<ITokenProps | null>(null);
1919
/**
2020
* Data comming from a coin that will be passed to the tab components
21-
* TokenDetails and TokenTransaction when the user clicks in particular token asset.
21+
* TokenDetails and TokenTransaction when the user clicks in particular token asset.
2222
*/
2323
export function useTokenProps(): ITokenPropsState {
2424
function setTokenProps(props: ITokenProps | null) {

src/composables/scrollTransactions.ts

+4-4
Original file line numberDiff line numberDiff line change
@@ -3,17 +3,17 @@ import {
33
} from 'vue';
44

55
interface IScrollConf {
6-
scrollConf: Ref<Boolean | null>
7-
setScrollConf: (props: Boolean | null) => void
6+
scrollConf: Ref<boolean | null>
7+
setScrollConf: (props: boolean | null) => void
88
}
99

10-
const scrollConf = ref<Boolean | null>(null);
10+
const scrollConf = ref<boolean | null>(null);
1111
/**
1212
* Data comming from AccountDetailsTokens or AccountDetailsTransactions and will be passed
1313
* to AccountDetailsBase in order to showFilters
1414
*/
1515
export function useScrollConfig(): IScrollConf {
16-
function setScrollConf(value: Boolean | null) {
16+
function setScrollConf(value: boolean | null) {
1717
scrollConf.value = value;
1818
}
1919

src/popup/components/AccountDetailsBase.vue

+33-9
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
<template>
2-
<div
3-
class="account-details"
4-
>
2+
<div class="account-details">
53
<div class="account-info-wrapper">
64
<slot
75
v-if="$slots['account-info']"
@@ -53,7 +51,10 @@
5351
/>
5452
</div>
5553

56-
<div class="tabs-content">
54+
<div
55+
class="tabs-content"
56+
:style="{ height: routerHeight }"
57+
>
5758
<ion-router-outlet />
5859
</div>
5960
</div>
@@ -68,6 +69,7 @@ import {
6869
defineComponent,
6970
onBeforeUnmount,
7071
onMounted,
72+
ref,
7173
watch,
7274
} from 'vue';
7375
import { useRoute } from 'vue-router';
@@ -116,13 +118,20 @@ export default defineComponent({
116118
117119
const { balance } = useBalances({ store });
118120
121+
const routerHeight = ref<string>();
122+
119123
const balanceNumeric = computed(() => balance.value.toNumber());
120124
121125
const routeName = computed(() => route.name);
122126
123-
const showFilters = computed<boolean | any>(() => (
124-
scrollConf.value
125-
));
127+
const showFilters = computed<boolean>(() => (!!scrollConf.value));
128+
129+
function calculateRouterHeight() {
130+
const ionicWrapperBottom = document.querySelector('.app-wrapper')?.getBoundingClientRect()?.bottom;
131+
const headerElementBottom = document.querySelector('.header')?.getBoundingClientRect()?.bottom;
132+
const routerContent = Math.ceil(ionicWrapperBottom! - headerElementBottom!);
133+
routerHeight.value = `${routerContent}px`;
134+
}
126135
127136
watch(
128137
() => route,
@@ -131,12 +140,27 @@ export default defineComponent({
131140
},
132141
);
133142
143+
/**
144+
* Observe tab height changes and recalculate router height.
145+
* Tabs change height when filters are shown/hidden
146+
*/
147+
function observeTabsHeight() {
148+
const resizeObserver = new ResizeObserver(() => {
149+
calculateRouterHeight();
150+
});
151+
resizeObserver.observe(document.querySelector('.header') as Element);
152+
}
153+
134154
onMounted(() => {
135155
if (IS_MOBILE_APP) {
136156
StatusBar.setBackgroundColor({
137157
color: '#191919',
138158
});
139159
}
160+
setTimeout(() => {
161+
observeTabsHeight();
162+
calculateRouterHeight();
163+
}, 250);
140164
});
141165
142166
onBeforeUnmount(() => {
@@ -153,6 +177,7 @@ export default defineComponent({
153177
routeName,
154178
balanceNumeric,
155179
activeAccount,
180+
routerHeight,
156181
};
157182
},
158183
});
@@ -241,8 +266,7 @@ export default defineComponent({
241266
.tabs-content {
242267
position: relative;
243268
padding: 0 var(--screen-padding-x);
244-
// TODO fix this hack
245-
height: 300px;
269+
height: 350px;
246270
}
247271
248272
.close-button {

src/popup/components/Tokens.vue

+1
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,7 @@ export default defineComponent({
177177
178178
.icon {
179179
user-select: none;
180+
width: max-content;
180181
181182
.icon-image {
182183
width: var(--icon-size);

src/popup/pages/FungibleTokens/TokenContainer.vue

+30-5
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
<template>
22
<ion-page>
3-
<ion-content
4-
class="ion-padding"
5-
>
3+
<ion-content class="ion-padding">
64
<div class="token-container">
75
<Loader v-if="loading" />
86

@@ -70,6 +68,7 @@
7068
</div>
7169
<ion-router-outlet
7270
class="token-router"
71+
:style="{ height: routerHeight }"
7372
/>
7473
</div>
7574
</ion-content>
@@ -90,6 +89,7 @@ import {
9089
onMounted,
9190
ref,
9291
unref,
92+
nextTick,
9393
} from 'vue';
9494
import { useStore } from 'vuex';
9595
import { useRoute } from 'vue-router';
@@ -194,6 +194,7 @@ export default defineComponent({
194194
exact: true,
195195
},
196196
];
197+
const routerHeight = ref<string>();
197198
const loading = ref<boolean>(true);
198199
const tokenPairs = ref<Record<string, IToken | null>>({ token0: null, token1: null });
199200
const tokenBalances = useGetter<IToken[]>('fungibleTokens/tokenBalances');
@@ -220,12 +221,35 @@ export default defineComponent({
220221
221222
const convertedBalance = computed(() => +tokenData.value.convertedBalance! || 0);
222223
224+
function calculateRouterHeight() {
225+
nextTick(() => {
226+
const ionicWrapperBottom = document.querySelector('.app-wrapper')?.getBoundingClientRect()?.bottom;
227+
const tabsWrapperElementBottom = document.querySelector('.sticky-tabs-wrapper')?.getBoundingClientRect().bottom;
228+
routerHeight.value = `${ionicWrapperBottom! - tabsWrapperElementBottom!}px`!;
229+
});
230+
}
231+
232+
/**
233+
* Observe tabs wrapper height changes and recalculate router height.
234+
* Tabs change height when filters are shown/hidden
235+
*/
236+
function observeTabsWrapperHeight() {
237+
const resizeObserver = new ResizeObserver(() => {
238+
calculateRouterHeight();
239+
});
240+
resizeObserver.observe(document.querySelector('.sticky-tabs-wrapper') as Element);
241+
}
242+
223243
onMounted(async () => {
224244
if (isContract(contractId) && !isAe) {
225245
await getAeSdk();
226246
tokenPairs.value = await store.dispatch('fungibleTokens/getContractTokenPairs', contractId);
227247
}
228248
loading.value = false;
249+
setTimeout(() => {
250+
observeTabsWrapperHeight();
251+
calculateRouterHeight();
252+
}, 250);
229253
});
230254
231255
onIonViewDidEnter(() => {
@@ -267,14 +291,15 @@ export default defineComponent({
267291
routeName,
268292
isMultisig,
269293
routeParams,
294+
routerHeight,
270295
};
271296
},
272297
});
273298
</script>
274299

275300
<style lang="scss" scoped>
276-
@use '../../../styles/variables';
277-
@use '../../../styles/typography';
301+
@use '@/styles/variables';
302+
@use '@/styles/typography';
278303
279304
.token-container {
280305
--screen-padding-x: 12px;

0 commit comments

Comments
 (0)