diff options
| author | syuilo <Syuilotan@yahoo.co.jp> | 2021-10-24 04:03:07 +0900 |
|---|---|---|
| committer | syuilo <Syuilotan@yahoo.co.jp> | 2021-10-24 04:03:07 +0900 |
| commit | 4f04421cb3091fa6302ada179e02aadad0533607 (patch) | |
| tree | 99adb4b3bf3b17d101cb297960a7fd67ec5c27df /src/client/components | |
| parent | refactor clinet (diff) | |
| download | sharkey-4f04421cb3091fa6302ada179e02aadad0533607.tar.gz sharkey-4f04421cb3091fa6302ada179e02aadad0533607.tar.bz2 sharkey-4f04421cb3091fa6302ada179e02aadad0533607.zip | |
refactor clinet
Diffstat (limited to 'src/client/components')
| -rw-r--r-- | src/client/components/global/header.vue | 9 | ||||
| -rw-r--r-- | src/client/components/global/sticky-container.vue | 74 | ||||
| -rw-r--r-- | src/client/components/index.ts | 2 | ||||
| -rw-r--r-- | src/client/components/modal-page-window.vue | 9 | ||||
| -rw-r--r-- | src/client/components/page-window.vue | 5 |
5 files changed, 88 insertions, 11 deletions
diff --git a/src/client/components/global/header.vue b/src/client/components/global/header.vue index 2bf490c98a..526db07fd3 100644 --- a/src/client/components/global/header.vue +++ b/src/client/components/global/header.vue @@ -2,8 +2,8 @@ <div class="fdidabkb" :class="{ slim: narrow, thin: thin_ }" :style="{ background: bg }" @click="onClick" ref="el"> <template v-if="info"> <div class="titleContainer" @click="showTabsPopup" v-if="!hideTitle"> - <i v-if="info.icon" class="icon" :class="info.icon"></i> - <MkAvatar v-else-if="info.avatar" class="avatar" :user="info.avatar" :disable-preview="true" :show-indicator="true"/> + <MkAvatar v-if="info.avatar" class="avatar" :user="info.avatar" :disable-preview="true" :show-indicator="true"/> + <i v-else-if="info.icon" class="icon" :class="info.icon"></i> <div class="title"> <MkUserName v-if="info.userName" :user="info.userName" :nowrap="false" class="title"/> @@ -162,11 +162,6 @@ export default defineComponent({ onUnmounted(() => { ro.disconnect(); }); - setTimeout(() => { - const currentStickyTop = getComputedStyle(el.value.parentElement).getPropertyValue('--stickyTop') || '0px'; - el.value.style.setProperty('--stickyTop', currentStickyTop); - el.value.parentElement.style.setProperty('--stickyTop', `calc(${currentStickyTop} + ${el.value.offsetHeight}px)`); - }, 100); // レンダリング順序の関係で親のstickyTopの設定が少し遅れることがあるため } }); diff --git a/src/client/components/global/sticky-container.vue b/src/client/components/global/sticky-container.vue new file mode 100644 index 0000000000..859b2c1d73 --- /dev/null +++ b/src/client/components/global/sticky-container.vue @@ -0,0 +1,74 @@ +<template> +<div ref="rootEl"> + <slot name="header"></slot> + <div ref="bodyEl"> + <slot></slot> + </div> +</div> +</template> + +<script lang="ts"> +import { defineComponent, onMounted, onUnmounted, ref } from 'vue'; + +export default defineComponent({ + props: { + autoSticky: { + type: Boolean, + required: false, + default: false, + }, + }, + + setup(props, context) { + const rootEl = ref<HTMLElement>(null); + const bodyEl = ref<HTMLElement>(null); + + const calc = () => { + const currentStickyTop = getComputedStyle(rootEl.value).getPropertyValue('--stickyTop') || '0px'; + + const header = rootEl.value.children[0]; + if (header === bodyEl.value) { + bodyEl.value.style.setProperty('--stickyTop', currentStickyTop); + } else { + bodyEl.value.style.setProperty('--stickyTop', `calc(${currentStickyTop} + ${header.offsetHeight}px)`); + + if (props.autoSticky) { + header.style.setProperty('--stickyTop', currentStickyTop); + header.style.position = 'sticky'; + header.style.top = 'var(--stickyTop)'; + header.style.zIndex = '1'; + } + } + }; + + onMounted(() => { + calc(); + + const observer = new MutationObserver(() => { + setTimeout(() => { + calc(); + }, 100); + }); + + observer.observe(rootEl.value, { + attributes: false, + childList: true, + subtree: false, + }); + + onUnmounted(() => { + observer.disconnect(); + }); + }); + + return { + rootEl, + bodyEl, + }; + }, +}); +</script> + +<style lang="scss" module> + +</style> diff --git a/src/client/components/index.ts b/src/client/components/index.ts index ecf66ea0e8..2340b228f8 100644 --- a/src/client/components/index.ts +++ b/src/client/components/index.ts @@ -15,6 +15,7 @@ import error from './global/error.vue'; import ad from './global/ad.vue'; import header from './global/header.vue'; import spacer from './global/spacer.vue'; +import stickyContainer from './global/sticky-container.vue'; export default function(app: App) { app.component('I18n', i18n); @@ -32,4 +33,5 @@ export default function(app: App) { app.component('MkAd', ad); app.component('MkHeader', header); app.component('MkSpacer', spacer); + app.component('MkStickyContainer', stickyContainer); } diff --git a/src/client/components/modal-page-window.vue b/src/client/components/modal-page-window.vue index 621119294e..e47d3dc62c 100644 --- a/src/client/components/modal-page-window.vue +++ b/src/client/components/modal-page-window.vue @@ -11,9 +11,12 @@ <button class="_button" @click="$refs.modal.close()"><i class="fas fa-times"></i></button> </div> <div class="body"> - <keep-alive> - <component :is="component" v-bind="props" :ref="changePage"/> - </keep-alive> + <MkStickyContainer> + <template #header><MkHeader v-if="pageInfo && !pageInfo.hideHeader" :info="pageInfo"/></template> + <keep-alive> + <component :is="component" v-bind="props" :ref="changePage"/> + </keep-alive> + </MkStickyContainer> </div> </div> </MkModal> diff --git a/src/client/components/page-window.vue b/src/client/components/page-window.vue index 2b77a214c5..bc7c5b7a19 100644 --- a/src/client/components/page-window.vue +++ b/src/client/components/page-window.vue @@ -17,7 +17,10 @@ <button v-if="history.length > 0" class="_button" @click="back()" v-tooltip="$ts.goBack"><i class="fas fa-arrow-left"></i></button> </template> <div class="yrolvcoq"> - <component :is="component" v-bind="props" :ref="changePage"/> + <MkStickyContainer> + <template #header><MkHeader v-if="pageInfo && !pageInfo.hideHeader" :info="pageInfo"/></template> + <component :is="component" v-bind="props" :ref="changePage"/> + </MkStickyContainer> </div> </XWindow> </template> |