v1.4.1: 관리자 미디어 업로드 한도·라이브 에디터 UX 개선
종류별 업로드 크기 한도와 413 안내를 추가하고, 임베드·미디어 라이브 프리뷰·제목 Enter 포커스·스크롤 동작을 보정한다. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -1,5 +1,85 @@
|
||||
<script setup>
|
||||
const props = defineProps({
|
||||
href: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
title: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
description: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
fileName: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
size: {
|
||||
type: String,
|
||||
default: ''
|
||||
}
|
||||
})
|
||||
|
||||
/**
|
||||
* 다운로드 가능한 파일 URL인지 확인한다.
|
||||
* @returns {boolean} 파일 URL 여부
|
||||
*/
|
||||
const isSafeFileUrl = computed(() => Boolean(props.href && (props.href.startsWith('/') || /^https?:\/\//i.test(props.href))))
|
||||
|
||||
/**
|
||||
* 카드 제목을 반환한다.
|
||||
* @returns {string} 제목
|
||||
*/
|
||||
const displayTitle = computed(() => props.title || props.fileName || 'File')
|
||||
|
||||
/**
|
||||
* 표시 파일명을 반환한다.
|
||||
* @returns {string} 파일명
|
||||
*/
|
||||
const displayFileName = computed(() => {
|
||||
if (props.fileName) {
|
||||
return props.fileName
|
||||
}
|
||||
|
||||
try {
|
||||
const parsedUrl = props.href.startsWith('/') ? new URL(props.href, 'https://local.invalid') : new URL(props.href)
|
||||
const lastSegment = parsedUrl.pathname.split('/').filter(Boolean).pop()
|
||||
return lastSegment ? decodeURIComponent(lastSegment) : ''
|
||||
} catch {
|
||||
return ''
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="prose-file my-8 rounded-[10px] border border-[var(--site-line)] bg-[var(--site-panel)] p-5">
|
||||
<slot />
|
||||
</div>
|
||||
<a
|
||||
v-if="isSafeFileUrl"
|
||||
class="prose-file group my-8 flex items-center gap-4 rounded-[10px] border border-[var(--site-line)] bg-[var(--site-panel)] p-4 no-underline shadow-[0_14px_36px_rgba(15,23,42,0.06)] transition-[background-color,box-shadow] hover:bg-[color-mix(in_srgb,var(--site-panel)_86%,var(--site-text)_14%)] sm:p-5"
|
||||
:href="href"
|
||||
download
|
||||
>
|
||||
<span class="prose-file__body min-w-0 flex-1">
|
||||
<span class="prose-file__title block text-base font-semibold leading-snug text-[var(--site-text)] sm:text-lg">
|
||||
{{ displayTitle }}
|
||||
</span>
|
||||
<span v-if="description" class="prose-file__description mt-1 block text-sm leading-relaxed text-[var(--site-muted)]">
|
||||
{{ description }}
|
||||
</span>
|
||||
<span class="prose-file__meta mt-3 block truncate text-sm font-semibold text-[var(--site-text)]">
|
||||
{{ displayFileName || href }}<template v-if="size"> · {{ size }}</template>
|
||||
</span>
|
||||
</span>
|
||||
<span class="prose-file__download flex h-20 w-20 shrink-0 items-center justify-center rounded-[6px] bg-[color-mix(in_srgb,var(--site-line)_36%,var(--site-panel))] text-[var(--site-accent)] transition-transform group-hover:scale-[1.02] sm:h-[86px] sm:w-[86px]">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" class="h-8 w-8" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
|
||||
<path d="M12 4v11" />
|
||||
<path d="m8 11 4 4 4-4" />
|
||||
<path d="M5 20h14" />
|
||||
</svg>
|
||||
</span>
|
||||
</a>
|
||||
<p v-else class="prose-file prose-file-invalid my-8 rounded-[10px] border border-[var(--site-line)] bg-[var(--site-panel)] p-5 text-sm font-semibold text-[var(--site-muted)]">
|
||||
파일 URL이 없습니다.
|
||||
</p>
|
||||
</template>
|
||||
|
||||
Reference in New Issue
Block a user