merge: Instance admin UX improvements (!1059)

View MR for information: https://activitypub.software/TransFem-org/Sharkey/-/merge_requests/1059

Approved-by: dakkar <dakkar@thenautilus.net>
Approved-by: Marie <github@yuugi.dev>
This commit is contained in:
Hazelnoot 2025-06-01 17:59:16 +00:00
commit 8894578b2a
13 changed files with 649 additions and 237 deletions

View file

@ -5,7 +5,7 @@ SPDX-License-Identifier: AGPL-3.0-only
<template>
<div ref="rootEl" :class="$style.root" role="group" :aria-expanded="opened">
<MkStickyContainer>
<MkStickyContainer :sticky="sticky">
<template #header>
<button :class="[$style.header, { [$style.opened]: opened }]" class="_button" role="button" data-cy-folder-header @click="toggle">
<div :class="$style.headerIcon"><slot name="icon"></slot></div>
@ -34,7 +34,7 @@ SPDX-License-Identifier: AGPL-3.0-only
>
<KeepAlive>
<div v-show="opened">
<MkStickyContainer>
<MkStickyContainer :sticky="sticky">
<template #header>
<div v-if="$slots.header" :class="$style.inBodyHeader">
<slot name="header"></slot>
@ -73,12 +73,14 @@ const props = withDefaults(defineProps<{
withSpacer?: boolean;
spacerMin?: number;
spacerMax?: number;
sticky?: boolean;
}>(), {
defaultOpen: false,
maxHeight: null,
withSpacer: true,
spacerMin: 14,
spacerMax: 22,
sticky: true,
});
const rootEl = useTemplateRef('rootEl');

View file

@ -0,0 +1,84 @@
<!--
SPDX-FileCopyrightText: hazelnoot and other Sharkey contributors
SPDX-License-Identifier: AGPL-3.0-only
-->
<template>
<div :class="$style.badges">
<div
v-for="badge of badges"
:key="badge.key"
:class="[$style.badge, semanticClass(badge)]"
>
{{ badge.label }}
</div>
</div>
</template>
<script lang="ts">
export interface Badge {
/**
* ID/key of this badge, must be unique within the strip.
*/
key: string;
/**
* Label text to display.
* Should already be translated.
*/
label: string;
/**
* Semantic style of the badge.
* Defaults to "neutral" if unset.
*/
style?: 'success' | 'neutral' | 'warning' | 'error';
}
</script>
<script setup lang="ts">
import { useCssModule } from 'vue';
const $style = useCssModule();
defineProps<{
badges: Badge[],
}>();
function semanticClass(badge: Badge): string {
const style = badge.style ?? 'neutral';
return $style[`semantic_${style}`];
}
</script>
<style module lang="scss">
.badges {
display: flex;
flex-direction: row;
flex-wrap: wrap;
gap: var(--MI-margin);
}
.badge {
display: inline-block;
border: solid 1px;
border-radius: var(--MI-radius-sm);
padding: 2px 6px;
font-size: 85%;
}
.semantic_error {
color: var(--MI_THEME-error);
border-color: var(--MI_THEME-error);
}
.semantic_warning {
color: var(--MI_THEME-warn);
border-color: var(--MI_THEME-warn);
}
.semantic_success {
color: var(--MI_THEME-success);
border-color: var(--MI_THEME-success);
}
</style>

View file

@ -5,17 +5,17 @@ SPDX-License-Identifier: AGPL-3.0-only
<template>
<div ref="rootEl">
<div ref="headerEl" :class="$style.header">
<div ref="headerEl" :class="{ [$style.header]: sticky }">
<slot name="header"></slot>
</div>
<div
:class="$style.body"
:class="{ [$style.body]: sticky }"
:data-sticky-container-header-height="headerHeight"
:data-sticky-container-footer-height="footerHeight"
>
<slot></slot>
</div>
<div ref="footerEl" :class="$style.footer">
<div ref="footerEl" :class="{ [$style.footer]: sticky }">
<slot name="footer"></slot>
</div>
</div>
@ -25,6 +25,12 @@ SPDX-License-Identifier: AGPL-3.0-only
import { onMounted, onUnmounted, provide, inject, ref, watch, useTemplateRef } from 'vue';
import { DI } from '@/di.js';
withDefaults(defineProps<{
sticky?: boolean,
}>(), {
sticky: true,
});
const rootEl = useTemplateRef('rootEl');
const headerEl = useTemplateRef('headerEl');
const footerEl = useTemplateRef('footerEl');