improve dialog layout

This commit is contained in:
pa
2026-03-19 21:38:09 +09:00
parent f9d3f7089b
commit fbfaf7b93c
7 changed files with 27 additions and 21 deletions

View File

@@ -1,13 +1,13 @@
<template> <template>
<div class="w-223"> <div class="w-223 flex-1 min-h-0 flex flex-col">
<DialogHeader class="sr-only"> <DialogHeader class="sr-only">
<DialogTitle>{{ avatarDialog.ref?.name || t('dialog.avatar.info.header') }}</DialogTitle> <DialogTitle>{{ avatarDialog.ref?.name || t('dialog.avatar.info.header') }}</DialogTitle>
<DialogDescription> <DialogDescription>
{{ avatarDialog.ref?.description || avatarDialog.ref?.name || t('dialog.avatar.info.header') }} {{ avatarDialog.ref?.description || avatarDialog.ref?.name || t('dialog.avatar.info.header') }}
</DialogDescription> </DialogDescription>
</DialogHeader> </DialogHeader>
<div> <div class="flex-1 min-h-0 flex flex-col">
<div class="flex"> <div class="flex flex-shrink-0">
<div style="flex: none; width: 160px; height: 120px"> <div style="flex: none; width: 160px; height: 120px">
<img <img
v-if="!imageError" v-if="!imageError"
@@ -320,6 +320,7 @@
v-model="avatarDialog.activeTab" v-model="avatarDialog.activeTab"
:items="avatarDialogTabs" :items="avatarDialogTabs"
:unmount-on-hide="false" :unmount-on-hide="false"
fill
@update:modelValue="avatarDialogTabClick"> @update:modelValue="avatarDialogTabClick">
<template #Info> <template #Info>
<div class="flex flex-wrap items-start px-2.5" style="max-height: unset"> <div class="flex flex-wrap items-start px-2.5" style="max-height: unset">
@@ -584,7 +585,6 @@
import { toast } from 'vue-sonner'; import { toast } from 'vue-sonner';
import { useI18n } from 'vue-i18n'; import { useI18n } from 'vue-i18n';
import { import {
useAuthStore, useAuthStore,
useAvatarStore, useAvatarStore,

View File

@@ -1,13 +1,13 @@
<template> <template>
<div class="w-223"> <div class="w-223 flex-1 min-h-0 flex flex-col">
<DialogHeader class="sr-only"> <DialogHeader class="sr-only">
<DialogTitle>{{ groupDialog.ref?.name || t('dialog.group.info.header') }}</DialogTitle> <DialogTitle>{{ groupDialog.ref?.name || t('dialog.group.info.header') }}</DialogTitle>
<DialogDescription> <DialogDescription>
{{ groupDialog.ref?.description || groupDialog.ref?.name || t('dialog.group.info.header') }} {{ groupDialog.ref?.description || groupDialog.ref?.name || t('dialog.group.info.header') }}
</DialogDescription> </DialogDescription>
</DialogHeader> </DialogHeader>
<div> <div class="flex-1 min-h-0 flex flex-col">
<div style="display: flex"> <div class="flex-shrink-0" style="display: flex">
<div style="flex: none; width: 120px; height: 120px"> <div style="flex: none; width: 120px; height: 120px">
<img <img
v-if="!groupDialog.loading && !imageError" v-if="!groupDialog.loading && !imageError"
@@ -341,6 +341,7 @@
v-model="groupDialog.activeTab" v-model="groupDialog.activeTab"
:items="groupDialogTabs" :items="groupDialogTabs"
:unmount-on-hide="false" :unmount-on-hide="false"
fill
@update:modelValue="groupDialogTabClick"> @update:modelValue="groupDialogTabClick">
<template #Info> <template #Info>
<GroupDialogInfoTab <GroupDialogInfoTab

View File

@@ -109,11 +109,11 @@
const dialogClass = computed(() => { const dialogClass = computed(() => {
switch (activeType.value) { switch (activeType.value) {
case 'world': case 'world':
return 'x-dialog x-world-dialog translate-y-0 sm:max-w-235'; return 'x-dialog translate-y-0 sm:max-w-235 overflow-hidden flex flex-col';
case 'avatar': case 'avatar':
return 'x-dialog x-avatar-dialog sm:max-w-235 translate-y-0'; return 'x-dialog sm:max-w-235 translate-y-0 overflow-hidden flex flex-col';
case 'group': case 'group':
return 'x-dialog x-group-dialog group-body translate-y-0 sm:max-w-235'; return 'x-dialog translate-y-0 sm:max-w-235 overflow-hidden flex flex-col';
case 'previous-instances-info': case 'previous-instances-info':
case 'previous-instances-user': case 'previous-instances-user':
case 'previous-instances-world': case 'previous-instances-world':
@@ -121,7 +121,7 @@
return 'x-dialog translate-y-0 sm:max-w-250'; return 'x-dialog translate-y-0 sm:max-w-250';
case 'user': case 'user':
default: default:
return 'x-dialog x-user-dialog sm:max-w-235 translate-y-0'; return 'x-dialog sm:max-w-235 translate-y-0 overflow-hidden flex flex-col';
} }
}); });
@@ -149,7 +149,7 @@
<template> <template>
<Dialog v-if="isOpen" v-model:open="isOpen"> <Dialog v-if="isOpen" v-model:open="isOpen">
<DialogContent :class="dialogClass" style="top: 10vh" :show-close-button="false"> <DialogContent :class="dialogClass" style="top: 10vh" :show-close-button="false">
<Breadcrumb v-if="shouldShowBreadcrumbs" class="mb-2"> <Breadcrumb v-if="shouldShowBreadcrumbs" class="mb-2 flex-shrink-0">
<BreadcrumbList> <BreadcrumbList>
<TooltipWrapper :content="backCrumbLabel" :disabled="!backCrumbLabel" :delayDuration="500"> <TooltipWrapper :content="backCrumbLabel" :disabled="!backCrumbLabel" :delayDuration="500">
<Button variant="ghost" size="icon-sm" @click="handleBreadcrumbClick(dialogCrumbs.length - 2)"> <Button variant="ghost" size="icon-sm" @click="handleBreadcrumbClick(dialogCrumbs.length - 2)">

View File

@@ -1,5 +1,5 @@
<template> <template>
<div class="w-223"> <div class="w-223 flex-1 min-h-0 flex flex-col">
<DialogHeader class="sr-only"> <DialogHeader class="sr-only">
<DialogTitle>{{ <DialogTitle>{{
userDialog.ref?.displayName || userDialog.id || t('dialog.user.info.header') userDialog.ref?.displayName || userDialog.id || t('dialog.user.info.header')
@@ -7,6 +7,7 @@
<DialogDescription>{{ getUserStateText(userDialog.ref || {}) }}</DialogDescription> <DialogDescription>{{ getUserStateText(userDialog.ref || {}) }}</DialogDescription>
</DialogHeader> </DialogHeader>
<UserSummaryHeader <UserSummaryHeader
class="flex-shrink-0"
:get-user-state-text="getUserStateText" :get-user-state-text="getUserStateText"
:copy-user-display-name="copyUserDisplayName" :copy-user-display-name="copyUserDisplayName"
:toggle-badge-visibility="toggleBadgeVisibility" :toggle-badge-visibility="toggleBadgeVisibility"
@@ -17,6 +18,7 @@
v-model="userDialog.activeTab" v-model="userDialog.activeTab"
:items="userDialogTabs" :items="userDialogTabs"
:unmount-on-hide="false" :unmount-on-hide="false"
fill
@update:modelValue="userDialogTabClick"> @update:modelValue="userDialogTabClick">
<template #Info> <template #Info>
<UserDialogInfoTab ref="infoTabRef" @show-bio-dialog="showBioDialog" /> <UserDialogInfoTab ref="infoTabRef" @show-bio-dialog="showBioDialog" />

View File

@@ -1,13 +1,13 @@
<template> <template>
<div class="w-223"> <div class="w-223 flex-1 min-h-0 flex flex-col">
<DialogHeader class="sr-only"> <DialogHeader class="sr-only">
<DialogTitle>{{ worldDialog.ref?.name || t('dialog.world.info.header') }}</DialogTitle> <DialogTitle>{{ worldDialog.ref?.name || t('dialog.world.info.header') }}</DialogTitle>
<DialogDescription> <DialogDescription>
{{ worldDialog.ref?.description || worldDialog.ref?.name || t('dialog.world.info.header') }} {{ worldDialog.ref?.description || worldDialog.ref?.name || t('dialog.world.info.header') }}
</DialogDescription> </DialogDescription>
</DialogHeader> </DialogHeader>
<div> <div class="flex-1 min-h-0 flex flex-col">
<div style="display: flex"> <div class="flex-shrink-0" style="display: flex">
<div style="flex: none; width: 160px; height: 120px"> <div style="flex: none; width: 160px; height: 120px">
<img <img
v-if="!worldDialog.loading && !imageError" v-if="!worldDialog.loading && !imageError"
@@ -313,6 +313,7 @@
v-model="worldDialog.activeTab" v-model="worldDialog.activeTab"
:items="worldDialogTabs" :items="worldDialogTabs"
:unmount-on-hide="false" :unmount-on-hide="false"
fill
@update:modelValue="worldDialogTabClick"> @update:modelValue="worldDialogTabClick">
<template #Instances> <template #Instances>
<WorldDialogInstancesTab /> <WorldDialogInstancesTab />

View File

@@ -72,8 +72,8 @@
:class=" :class="
cn( cn(
'bg-background data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 fixed top-[50%] left-[50%] z-50 grid w-full max-w-[calc(100%-2rem)] translate-x-[-50%] translate-y-[-50%] gap-4 rounded-lg border p-6 shadow-lg duration-200 sm:max-w-lg', 'bg-background data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 fixed top-[50%] left-[50%] z-50 grid w-full max-w-[calc(100%-2rem)] translate-x-[-50%] translate-y-[-50%] gap-4 rounded-lg border p-6 shadow-lg duration-200 sm:max-w-lg',
props.class, 'max-h-[85vh] overflow-y-auto scrollbar-hidden',
'max-h-[85vh] overflow-y-auto scrollbar-hidden' props.class
) )
"> ">
<slot /> <slot />

View File

@@ -21,11 +21,12 @@
variant: { type: String, default: 'fit' }, variant: { type: String, default: 'fit' },
unmountOnHide: { type: Boolean, default: false }, unmountOnHide: { type: Boolean, default: false },
fill: { type: Boolean, default: false } fill: { type: Boolean, default: false },
sticky: { type: Boolean, default: false }
}); });
const emit = defineEmits(['update:modelValue']); const emit = defineEmits(['update:modelValue']);
const { modelValue, defaultValue, items, ariaLabel, variant, unmountOnHide, fill } = toRefs(props); const { modelValue, defaultValue, items, ariaLabel, variant, unmountOnHide, fill, sticky } = toRefs(props);
const itemsList = computed(() => (Array.isArray(items.value) ? items.value : [])); const itemsList = computed(() => (Array.isArray(items.value) ? items.value : []));
@@ -74,7 +75,8 @@
const listClass = computed(() => { const listClass = computed(() => {
return [ return [
'relative flex w-full items-center gap-1 border-b border-border', 'relative flex w-full items-center gap-1 border-b border-border',
variant.value === 'pill' ? 'rounded-full bg-muted p-1' : '' variant.value === 'pill' ? 'rounded-full bg-muted p-1' : '',
sticky.value ? 'sticky top-0 z-10 bg-background' : ''
].join(' '); ].join(' ');
}); });
</script> </script>