MkStickyContainer化
This commit is contained in:
parent
0bc2401894
commit
4025845e54
|
@ -18,10 +18,21 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { onMounted, onUnmounted, provide, inject, Ref, ref, watch, shallowRef } from 'vue';
|
import { onMounted, onUnmounted, provide, inject, Ref, ref, watch, shallowRef, toRefs } from 'vue';
|
||||||
|
|
||||||
import { CURRENT_STICKY_BOTTOM, CURRENT_STICKY_TOP } from '@/const.js';
|
import { CURRENT_STICKY_BOTTOM, CURRENT_STICKY_TOP } from '@/const.js';
|
||||||
|
|
||||||
|
const props = withDefaults(defineProps<{
|
||||||
|
headerZIndex?: number;
|
||||||
|
footerZIndex?: number;
|
||||||
|
}>(), {
|
||||||
|
headerZIndex: 1000,
|
||||||
|
footerZIndex: 1000,
|
||||||
|
});
|
||||||
|
|
||||||
|
// non-reactive
|
||||||
|
const { headerZIndex, footerZIndex } = props;
|
||||||
|
|
||||||
const rootEl = shallowRef<HTMLElement>();
|
const rootEl = shallowRef<HTMLElement>();
|
||||||
const headerEl = shallowRef<HTMLElement>();
|
const headerEl = shallowRef<HTMLElement>();
|
||||||
const footerEl = shallowRef<HTMLElement>();
|
const footerEl = shallowRef<HTMLElement>();
|
||||||
|
@ -79,14 +90,14 @@ onMounted(() => {
|
||||||
if (headerEl.value != null) {
|
if (headerEl.value != null) {
|
||||||
headerEl.value.style.position = 'sticky';
|
headerEl.value.style.position = 'sticky';
|
||||||
headerEl.value.style.top = 'var(--stickyTop, 0)';
|
headerEl.value.style.top = 'var(--stickyTop, 0)';
|
||||||
headerEl.value.style.zIndex = '1000';
|
headerEl.value.style.zIndex = `${headerZIndex}`;
|
||||||
observer.observe(headerEl.value);
|
observer.observe(headerEl.value);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (footerEl.value != null) {
|
if (footerEl.value != null) {
|
||||||
footerEl.value.style.position = 'sticky';
|
footerEl.value.style.position = 'sticky';
|
||||||
footerEl.value.style.bottom = 'var(--stickyBottom, 0)';
|
footerEl.value.style.bottom = 'var(--stickyBottom, 0)';
|
||||||
footerEl.value.style.zIndex = '1000';
|
footerEl.value.style.zIndex = `${footerZIndex}`;
|
||||||
observer.observe(footerEl.value);
|
observer.observe(footerEl.value);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -4,139 +4,140 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||||
-->
|
-->
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div class="_gaps">
|
<div v-if="gridItems.length === 0" style="text-align: center">
|
||||||
<MkFolder>
|
{{ i18n.ts._customEmojisManager._local._list.emojisNothing }}
|
||||||
<template #icon><i class="ti ti-search"></i></template>
|
</div>
|
||||||
<template #label>{{ i18n.ts._customEmojisManager._gridCommon.searchSettings }}</template>
|
|
||||||
<template #caption>
|
|
||||||
{{ i18n.ts._customEmojisManager._gridCommon.searchSettingCaption }}
|
|
||||||
</template>
|
|
||||||
|
|
||||||
|
<MkStickyContainer v-else>
|
||||||
|
<template #default>
|
||||||
<div class="_gaps">
|
<div class="_gaps">
|
||||||
<div :class="[[spMode ? $style.searchAreaSp : $style.searchArea]]">
|
<MkFolder>
|
||||||
<MkInput
|
<template #icon><i class="ti ti-search"></i></template>
|
||||||
v-model="queryName"
|
<template #label>{{ i18n.ts._customEmojisManager._gridCommon.searchSettings }}</template>
|
||||||
type="search"
|
<template #caption>
|
||||||
autocapitalize="off"
|
{{ i18n.ts._customEmojisManager._gridCommon.searchSettingCaption }}
|
||||||
:class="[$style.col1, $style.row1]"
|
</template>
|
||||||
@enter="onSearchRequest"
|
|
||||||
>
|
|
||||||
<template #label>name</template>
|
|
||||||
</MkInput>
|
|
||||||
<MkInput
|
|
||||||
v-model="queryCategory"
|
|
||||||
type="search"
|
|
||||||
autocapitalize="off"
|
|
||||||
:class="[$style.col2, $style.row1]"
|
|
||||||
@enter="onSearchRequest"
|
|
||||||
>
|
|
||||||
<template #label>category</template>
|
|
||||||
</MkInput>
|
|
||||||
<MkInput
|
|
||||||
v-model="queryAliases"
|
|
||||||
type="search"
|
|
||||||
autocapitalize="off"
|
|
||||||
:class="[$style.col3, $style.row1]"
|
|
||||||
@enter="onSearchRequest"
|
|
||||||
>
|
|
||||||
<template #label>aliases</template>
|
|
||||||
</MkInput>
|
|
||||||
|
|
||||||
<MkInput
|
<div class="_gaps">
|
||||||
v-model="queryType"
|
<div :class="[[spMode ? $style.searchAreaSp : $style.searchArea]]">
|
||||||
type="search"
|
<MkInput
|
||||||
autocapitalize="off"
|
v-model="queryName"
|
||||||
:class="[$style.col1, $style.row2]"
|
type="search"
|
||||||
@enter="onSearchRequest"
|
autocapitalize="off"
|
||||||
>
|
:class="[$style.col1, $style.row1]"
|
||||||
<template #label>type</template>
|
@enter="onSearchRequest"
|
||||||
</MkInput>
|
>
|
||||||
<MkInput
|
<template #label>name</template>
|
||||||
v-model="queryLicense"
|
</MkInput>
|
||||||
type="search"
|
<MkInput
|
||||||
autocapitalize="off"
|
v-model="queryCategory"
|
||||||
:class="[$style.col2, $style.row2]"
|
type="search"
|
||||||
@enter="onSearchRequest"
|
autocapitalize="off"
|
||||||
>
|
:class="[$style.col2, $style.row1]"
|
||||||
<template #label>license</template>
|
@enter="onSearchRequest"
|
||||||
</MkInput>
|
>
|
||||||
<MkSelect
|
<template #label>category</template>
|
||||||
v-model="querySensitive"
|
</MkInput>
|
||||||
:class="[$style.col3, $style.row2]"
|
<MkInput
|
||||||
>
|
v-model="queryAliases"
|
||||||
<template #label>sensitive</template>
|
type="search"
|
||||||
<option :value="null">-</option>
|
autocapitalize="off"
|
||||||
<option :value="true">true</option>
|
:class="[$style.col3, $style.row1]"
|
||||||
<option :value="false">false</option>
|
@enter="onSearchRequest"
|
||||||
</MkSelect>
|
>
|
||||||
|
<template #label>aliases</template>
|
||||||
|
</MkInput>
|
||||||
|
|
||||||
<MkSelect
|
<MkInput
|
||||||
v-model="queryLocalOnly"
|
v-model="queryType"
|
||||||
:class="[$style.col1, $style.row3]"
|
type="search"
|
||||||
>
|
autocapitalize="off"
|
||||||
<template #label>localOnly</template>
|
:class="[$style.col1, $style.row2]"
|
||||||
<option :value="null">-</option>
|
@enter="onSearchRequest"
|
||||||
<option :value="true">true</option>
|
>
|
||||||
<option :value="false">false</option>
|
<template #label>type</template>
|
||||||
</MkSelect>
|
</MkInput>
|
||||||
<MkInput
|
<MkInput
|
||||||
v-model="queryUpdatedAtFrom"
|
v-model="queryLicense"
|
||||||
type="date"
|
type="search"
|
||||||
autocapitalize="off"
|
autocapitalize="off"
|
||||||
:class="[$style.col2, $style.row3]"
|
:class="[$style.col2, $style.row2]"
|
||||||
@enter="onSearchRequest"
|
@enter="onSearchRequest"
|
||||||
>
|
>
|
||||||
<template #label>updatedAt(from)</template>
|
<template #label>license</template>
|
||||||
</MkInput>
|
</MkInput>
|
||||||
<MkInput
|
<MkSelect
|
||||||
v-model="queryUpdatedAtTo"
|
v-model="querySensitive"
|
||||||
type="date"
|
:class="[$style.col3, $style.row2]"
|
||||||
autocapitalize="off"
|
>
|
||||||
:class="[$style.col3, $style.row3]"
|
<template #label>sensitive</template>
|
||||||
@enter="onSearchRequest"
|
<option :value="null">-</option>
|
||||||
>
|
<option :value="true">true</option>
|
||||||
<template #label>updatedAt(to)</template>
|
<option :value="false">false</option>
|
||||||
</MkInput>
|
</MkSelect>
|
||||||
|
|
||||||
<MkInput
|
<MkSelect
|
||||||
v-model="queryRolesText"
|
v-model="queryLocalOnly"
|
||||||
type="text"
|
:class="[$style.col1, $style.row3]"
|
||||||
readonly
|
>
|
||||||
autocapitalize="off"
|
<template #label>localOnly</template>
|
||||||
:class="[$style.col1, $style.row4]"
|
<option :value="null">-</option>
|
||||||
@click="onQueryRolesEditClicked"
|
<option :value="true">true</option>
|
||||||
>
|
<option :value="false">false</option>
|
||||||
<template #label>role</template>
|
</MkSelect>
|
||||||
<template #suffix><span class="ti ti-pencil"/></template>
|
<MkInput
|
||||||
</MkInput>
|
v-model="queryUpdatedAtFrom"
|
||||||
|
type="date"
|
||||||
|
autocapitalize="off"
|
||||||
|
:class="[$style.col2, $style.row3]"
|
||||||
|
@enter="onSearchRequest"
|
||||||
|
>
|
||||||
|
<template #label>updatedAt(from)</template>
|
||||||
|
</MkInput>
|
||||||
|
<MkInput
|
||||||
|
v-model="queryUpdatedAtTo"
|
||||||
|
type="date"
|
||||||
|
autocapitalize="off"
|
||||||
|
:class="[$style.col3, $style.row3]"
|
||||||
|
@enter="onSearchRequest"
|
||||||
|
>
|
||||||
|
<template #label>updatedAt(to)</template>
|
||||||
|
</MkInput>
|
||||||
|
|
||||||
|
<MkInput
|
||||||
|
v-model="queryRolesText"
|
||||||
|
type="text"
|
||||||
|
readonly
|
||||||
|
autocapitalize="off"
|
||||||
|
:class="[$style.col1, $style.row4]"
|
||||||
|
@click="onQueryRolesEditClicked"
|
||||||
|
>
|
||||||
|
<template #label>role</template>
|
||||||
|
<template #suffix><span class="ti ti-pencil"/></template>
|
||||||
|
</MkInput>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<XSortOrderFolder :sortOrders="sortOrders" @update="onSortOrderUpdate"/>
|
||||||
|
|
||||||
|
<div :class="[[spMode ? $style.searchButtonsSp : $style.searchButtons]]">
|
||||||
|
<MkButton primary @click="onSearchRequest">
|
||||||
|
{{ i18n.ts.search }}
|
||||||
|
</MkButton>
|
||||||
|
<MkButton @click="onQueryResetButtonClicked">
|
||||||
|
{{ i18n.ts.reset }}
|
||||||
|
</MkButton>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</MkFolder>
|
||||||
|
|
||||||
|
<XRegisterLogsFolder :logs="requestLogs"/>
|
||||||
|
|
||||||
|
<div :class="$style.gridArea">
|
||||||
|
<MkGrid :data="gridItems" :settings="setupGrid()" @event="onGridEvent"/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<XSortOrderFolder :sortOrders="sortOrders" @update="onSortOrderUpdate"/>
|
<MkPagingButtons :current="currentPage" :max="allPages" :buttonCount="5" @pageChanged="onPageChanged"/>
|
||||||
|
|
||||||
<div :class="[[spMode ? $style.searchButtonsSp : $style.searchButtons]]">
|
|
||||||
<MkButton primary @click="onSearchRequest">
|
|
||||||
{{ i18n.ts.search }}
|
|
||||||
</MkButton>
|
|
||||||
<MkButton @click="onQueryResetButtonClicked">
|
|
||||||
{{ i18n.ts.reset }}
|
|
||||||
</MkButton>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</MkFolder>
|
|
||||||
|
|
||||||
<XRegisterLogsFolder :logs="requestLogs"/>
|
|
||||||
|
|
||||||
<div v-if="gridItems.length === 0" style="text-align: center">
|
|
||||||
{{ i18n.ts._customEmojisManager._local._list.emojisNothing }}
|
|
||||||
</div>
|
|
||||||
<template v-else>
|
|
||||||
<div :class="$style.gridArea">
|
|
||||||
<MkGrid :data="gridItems" :settings="setupGrid()" @event="onGridEvent"/>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<MkPagingButtons :current="currentPage" :max="allPages" :buttonCount="5" @pageChanged="onPageChanged"/>
|
|
||||||
|
|
||||||
<div class="_gaps">
|
|
||||||
<div :class="$style.buttons">
|
<div :class="$style.buttons">
|
||||||
<MkButton danger style="margin-right: auto" @click="onDeleteButtonClicked">{{ i18n.ts.delete }}</MkButton>
|
<MkButton danger style="margin-right: auto" @click="onDeleteButtonClicked">{{ i18n.ts.delete }}</MkButton>
|
||||||
<MkButton primary :disabled="updateButtonDisabled" @click="onUpdateButtonClicked">
|
<MkButton primary :disabled="updateButtonDisabled" @click="onUpdateButtonClicked">
|
||||||
|
@ -148,7 +149,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</div>
|
</MkStickyContainer>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
|
@ -680,11 +681,8 @@ onMounted(async () => {
|
||||||
}
|
}
|
||||||
|
|
||||||
.gridArea {
|
.gridArea {
|
||||||
overflow-x: auto;
|
|
||||||
overflow-y: hidden;
|
|
||||||
padding-top: 8px;
|
padding-top: 8px;
|
||||||
padding-bottom: 8px;
|
padding-bottom: 8px;
|
||||||
resize: vertical;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.buttons {
|
.buttons {
|
||||||
|
@ -699,4 +697,5 @@ onMounted(async () => {
|
||||||
margin: 8px 0;
|
margin: 8px 0;
|
||||||
border-top: solid 0.5px var(--divider);
|
border-top: solid 0.5px var(--divider);
|
||||||
}
|
}
|
||||||
|
|
||||||
</style>
|
</style>
|
||||||
|
|
|
@ -452,11 +452,8 @@ onMounted(async () => {
|
||||||
}
|
}
|
||||||
|
|
||||||
.gridArea {
|
.gridArea {
|
||||||
overflow-x: auto;
|
|
||||||
overflow-y: hidden;
|
|
||||||
padding-top: 8px;
|
padding-top: 8px;
|
||||||
padding-bottom: 8px;
|
padding-bottom: 8px;
|
||||||
resize: vertical;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.buttons {
|
.buttons {
|
||||||
|
|
|
@ -32,6 +32,5 @@ const modeTab = ref<PageMode>('list');
|
||||||
<style module lang="scss">
|
<style module lang="scss">
|
||||||
.root {
|
.root {
|
||||||
padding: 16px;
|
padding: 16px;
|
||||||
overflow: scroll;
|
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
@ -344,11 +344,8 @@ onMounted(async () => {
|
||||||
}
|
}
|
||||||
|
|
||||||
.gridArea {
|
.gridArea {
|
||||||
overflow-x: auto;
|
|
||||||
overflow-y: hidden;
|
|
||||||
padding-top: 8px;
|
padding-top: 8px;
|
||||||
padding-bottom: 8px;
|
padding-bottom: 8px;
|
||||||
resize: vertical;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.pages {
|
.pages {
|
||||||
|
|
|
@ -5,7 +5,8 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<MkStickyContainer>
|
<!-- コンテナが入れ子になるのでz-indexが被らないよう大きめの数値を設定する-->
|
||||||
|
<MkStickyContainer :headerZIndex="2000">
|
||||||
<template #header>
|
<template #header>
|
||||||
<MkPageHeader v-model:tab="headerTab" :tabs="headerTabs"/>
|
<MkPageHeader v-model:tab="headerTab" :tabs="headerTabs"/>
|
||||||
</template>
|
</template>
|
||||||
|
|
Loading…
Reference in New Issue