Skip to content

Commit

Permalink
sticky footers
Browse files Browse the repository at this point in the history
  • Loading branch information
samunohito committed Dec 28, 2024
1 parent c9a86f9 commit 1badc06
Show file tree
Hide file tree
Showing 6 changed files with 138 additions and 37 deletions.
2 changes: 1 addition & 1 deletion locales/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10616,7 +10616,7 @@ export interface Locale extends ILocale {
*/
"importSelectionRangesRows": string;
/**
* チェックがついた絵文字をインポート
* チェックされた絵文字をインポート
*/
"importEmojisButton": string;
/**
Expand Down
2 changes: 1 addition & 1 deletion locales/ja-JP.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2832,7 +2832,7 @@ _customEmojisManager:
_remote:
importSelectionRows: "選択行をインポート"
importSelectionRangesRows: "選択範囲の行をインポート"
importEmojisButton: "チェックがついた絵文字をインポート"
importEmojisButton: "チェックされた絵文字をインポート"
confirmImportEmojisTitle: "絵文字のインポート"
confirmImportEmojisDescription: "リモートから受信した{count}個の絵文字のインポートを行います。絵文字のライセンスに十分な注意を払ってください。実行しますか?"
_local:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -145,18 +145,25 @@ SPDX-License-Identifier: AGPL-3.0-only
<MkGrid :data="gridItems" :settings="setupGrid()" @event="onGridEvent"/>
</div>

<MkPagingButtons :current="currentPage" :max="allPages" :buttonCount="5" @pageChanged="onPageChanged"/>
</template>
<div :class="$style.footer">
<div :class="$style.left">
<MkButton danger style="margin-right: auto" @click="onDeleteButtonClicked">
{{ i18n.ts.delete }} ({{ deleteItemsCount }})
</MkButton>
</div>

<div :class="$style.buttons">
<MkButton danger style="margin-right: auto" @click="onDeleteButtonClicked">{{ i18n.ts.delete }}</MkButton>
<MkButton primary :disabled="updateButtonDisabled" @click="onUpdateButtonClicked">
{{
i18n.ts.update
}}
</MkButton>
<MkButton @click="onGridResetButtonClicked">{{ i18n.ts.reset }}</MkButton>
</div>
<div :class="$style.center">
<MkPagingButtons :current="currentPage" :max="allPages" :buttonCount="5" @pageChanged="onPageChanged"/>
</div>

<div :class="$style.right">
<MkButton primary :disabled="updateButtonDisabled" @click="onUpdateButtonClicked">
{{ i18n.ts.update }} ({{ updatedItemsCount }})
</MkButton>
<MkButton @click="onGridResetButtonClicked">{{ i18n.ts.reset }}</MkButton>
</div>
</div>
</template>
</div>
</template>
</MkStickyContainer>
Expand Down Expand Up @@ -388,6 +395,10 @@ const updateButtonDisabled = ref<boolean>(false);

const spMode = computed(() => ['smartphone', 'tablet'].includes(deviceKind));
const queryRolesText = computed(() => queryRoles.value.map(it => it.name).join(','));
const updatedItemsCount = computed(() => {
return gridItems.value.filter((it, idx) => !it.checked && JSON.stringify(it) !== JSON.stringify(originGridItems.value[idx])).length;
});
const deleteItemsCount = computed(() => gridItems.value.filter(it => it.checked).length);

async function onUpdateButtonClicked() {
const _items = gridItems.value;
Expand Down Expand Up @@ -698,12 +709,44 @@ onMounted(async () => {
padding-bottom: 8px;
}

.buttons {
display: flex;
align-items: flex-end;
justify-content: center;
.footer {
background-color: var(--MI_THEME-bg);

position: sticky;
left:0;
bottom:0;
z-index: 1;
// stickyで追従させる都合上、フッター自身でpaddingを持つ必要があるため、親要素で画一的に指定している分をネガティブマージンで相殺している
margin-top: calc(var(--MI-margin) * -1);
margin-bottom: calc(var(--MI-margin) * -1);
padding-top: var(--MI-margin);
padding-bottom: var(--MI-margin);

display: grid;
grid-template-columns: 1fr 1fr 1fr;
gap: 8px;
flex-wrap: wrap;

& .left {
display: flex;
align-items: center;
justify-content: flex-start;
gap: 8px;
}

& .center {
display: flex;
align-items: center;
justify-content: center;
gap: 8px;
}

& .right {
display: flex;
align-items: center;
justify-content: flex-end;
flex-direction: row;
gap: 8px;
}
}

.divider {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ SPDX-License-Identifier: AGPL-3.0-only
/>
</div>

<div v-if="gridItems.length > 0" :class="$style.buttons">
<div v-if="gridItems.length > 0" :class="$style.footer">
<MkButton primary :disabled="registerButtonDisabled" @click="onRegistryClicked">
{{ i18n.ts.registration }}
</MkButton>
Expand Down Expand Up @@ -456,8 +456,19 @@ onMounted(async () => {
padding-bottom: 8px;
}

.buttons {
margin-top: 16px;
.footer {
background-color: var(--MI_THEME-bg);

position: sticky;
left:0;
bottom:0;
z-index: 1;
// stickyで追従させる都合上、フッター自身でpaddingを持つ必要があるため、親要素で画一的に指定している分をネガティブマージンで相殺している
margin-top: calc(var(--MI-margin) * -1);
margin-bottom: calc(var(--MI-margin) * -1);
padding-top: var(--MI-margin);
padding-bottom: var(--MI-margin);

display: flex;
gap: 8px;
flex-wrap: wrap;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,6 @@ const modeTab = ref<PageMode>('list');

<style module lang="scss">
.root {
padding: 16px;
padding: var(--MI-margin);
}
</style>
77 changes: 62 additions & 15 deletions packages/frontend/src/pages/admin/custom-emojis-manager.remote.vue
Original file line number Diff line number Diff line change
Expand Up @@ -86,23 +86,31 @@ SPDX-License-Identifier: AGPL-3.0-only
<MkGrid :data="gridItems" :settings="setupGrid()" @event="onGridEvent"/>
</div>

<MkPagingButtons :current="currentPage" :max="allPages" :buttonCount="5" @pageChanged="onPageChanged"/>
</template>
<div :class="$style.footer">
<div>
<!-- レイアウト調整用のスペース -->
</div>

<div v-if="gridItems.length > 0" class="_gaps" :class="$style.buttons">
<MkButton primary @click="onImportClicked">
{{
i18n.ts._customEmojisManager._remote.importEmojisButton
}}
</MkButton>
</div>
<div :class="$style.center">
<MkPagingButtons :current="currentPage" :max="allPages" :buttonCount="5" @pageChanged="onPageChanged"/>
</div>

<div :class="$style.right">
<MkButton primary @click="onImportClicked">
{{
i18n.ts._customEmojisManager._remote.importEmojisButton
}} ({{ checkedItemsCount }})
</MkButton>
</div>
</div>
</template>
</div>
</template>
</MkStickyContainer>
</template>

<script setup lang="ts">
import { computed, onMounted, ref } from 'vue';
import { computed, onMounted, ref, useCssModule } from 'vue';
import * as Misskey from 'misskey-js';
import { misskeyApi } from '@/scripts/misskey-api.js';
import { i18n } from '@/i18n.js';
Expand Down Expand Up @@ -134,8 +142,19 @@ type GridItem = {
}

function setupGrid(): GridSetting {
const $style = useCssModule();

return {
row: {
// グリッドの行数をあらかじめ100行確保する
minimumDefinitionCount: 100,
styleRules: [
{
// チェックされたら背景色を変える
condition: ({ row }) => gridItems.value[row.index].checked,
applyStyle: { className: $style.changedRow },
},
],
contextMenuFactory: (row, context) => {
return [
{
Expand Down Expand Up @@ -191,6 +210,7 @@ const requestLogs = ref<RequestLogItem[]>([]);
const gridItems = ref<GridItem[]>([]);

const spMode = computed(() => ['smartphone', 'tablet'].includes(deviceKind));
const checkedItemsCount = computed(() => gridItems.value.filter(it => it.checked).length);

function onSortOrderUpdate(_sortOrders: SortOrder<GridSortOrderKey>[]) {
sortOrders.value = _sortOrders;
Expand Down Expand Up @@ -294,7 +314,7 @@ async function refreshCustomEmojis() {
limit: 100,
query: query,
page: currentPage.value,
sortKeys: sortOrders.value.map(({ key, direction }) => `${direction}${key}`),
sortKeys: sortOrders.value.map(({ key, direction }) => `${direction}${key}`) as never[],
}),
() => {
},
Expand Down Expand Up @@ -340,6 +360,10 @@ onMounted(async () => {
padding: 16px;
}

.changedRow {
background-color: var(--MI_THEME-infoBg);
}

.searchArea {
display: grid;
grid-template-columns: 1fr 1fr;
Expand Down Expand Up @@ -385,10 +409,33 @@ onMounted(async () => {
}
}

.buttons {
display: inline-flex;
margin-left: auto;
.footer {
background-color: var(--MI_THEME-bg);

position: sticky;
left:0;
bottom:0;
z-index: 1;
// stickyで追従させる都合上、フッター自身でpaddingを持つ必要があるため、親要素で画一的に指定している分をネガティブマージンで相殺している
margin-top: calc(var(--MI-margin) * -1);
margin-bottom: calc(var(--MI-margin) * -1);
padding-top: var(--MI-margin);
padding-bottom: var(--MI-margin);

display: grid;
grid-template-columns: 1fr 1fr 1fr;
gap: 8px;
flex-wrap: wrap;

& .center {
display: flex;
justify-content: center;
align-items: center;
}

& .right {
display: flex;
justify-content: flex-end;
align-items: center;
}
}
</style>

0 comments on commit 1badc06

Please sign in to comment.