本文へ移動
cccskills
無料GitHub で公開

nuxt-ui-tools-file-preview

Use this skill when previewing files with nuxt-ui-tools as a package consumer. Covers mounting UiFilePreviewProvider, opening one file or a gallery with useFilePreview() or useNuxtApp().$filePreview, file descriptors (URL, File/Blob, or a function that returns a signed URL), options (index, mode, gallery, loop, pdf page, callbacks), the returned handle, the built-in renderers (image, video, audio, PDF, text/JSON, CSV, Markdown, Office and archive fallbacks), renditions, download and custom header actions, the markdown render hook, custom renderers with defineFilePreviewRenderer and UiFilePreviewTools, theming tokens, and how the upload field uses the preview.

インストール方法を見る

含まれるファイル(1)

  • SKILL.md13.2 KB

SKILL.md(原文)

インストールする前に、エージェントに与えられる指示の中身を確認できます。

nuxt-ui-tools File Preview

One call opens any file in an overlay with a renderer made for its kind. Media opens in a modal, documents in a right drawer, and phones get fullscreen. Renderers load on first use, so an app only downloads the code for the kinds it actually shows.

Mount the provider once

The module creates one API for the whole app. Mount the provider next to the form provider; it renders the previews:

<template>
  <UApp>
    <UiToolsProvider :locale="uiToolsLocale">
      <UiFormProvider>
        <UiFilePreviewProvider :markdown="renderMarkdown">
          <NuxtPage />
        </UiFilePreviewProvider>
      </UiFormProvider>
    </UiToolsProvider>
  </UApp>
</template>

The component prefix follows the module prefix option (Ui by default).

markdown is optional. It receives the file text and must return sanitized HTML (or a promise of it). Without it, Markdown files show their source.

Open files

Components use useFilePreview(). Code outside setup, such as entity actions or stores, uses useNuxtApp().$filePreview:

export function previewAccountFile(account: { id: string; name: string }, file: 'kbis' | 'logo') {
  const { $filePreview } = useNuxtApp()
  return $filePreview.open({
    name: `${file.toUpperCase()} — ${account.name}.pdf`,
    src: `/v1/accounts/${account.id}/files/${file}`,
  })
}

open() accepts one input or an array (a gallery). Each input is a URL string, a File or Blob, or a descriptor:

const preview = $filePreview.open(
  contract.files.map((file) => ({
    id: file.id,
    name: file.label,
    mime: file.mimeType,
    size: file.size,
    updatedAt: file.createdAt,
    // Runs only when this file is shown, and again when the user presses Retry.
    src: () => $api.contracts.fileUrl({ params: { fileId: file.id } }).then((res) => res.url),
    download: () => downloadContractFile(file),
    actions: [{ icon: 'i-lucide-folder-open', label: 'Open in registry', to: registryPath(file) }],
  })),
  { index: 2 },
)

preview.next()
await preview.closed

Descriptor fields

FieldMeaning
srcURL, File/Blob, or () => MaybePromise<string | Blob>. Functions resolve once per file and again on Retry.
nameDisplay name. Defaults to File.name, then the last URL segment.
mimeWins over the extension to pick a renderer.
kindForces a renderer ('image', 'pdf', …, or a custom kind).
size, updatedAtShown in the meta line and the details panel. File inputs fill them.
thumbnail, posterGallery strip image; video poster or audio cover.
renditionA preview made by your server for files browsers cannot render (DOCX → PDF, HEIC → JPEG). The preview shows it with a "Converted preview" notice; download keeps the original.
detailsExtra { label, value } rows in the details panel.
downloadfalse hides it, a string downloads that URL, a function replaces the download. Default: the resolved source under name.
actionsExtra header buttons: { label, icon?, to?, onSelect? }. External to opens a new tab; internal to closes the preview and navigates.
tracksVideo captions: { src, srcLang, label, kind?, default? }.

Text values (label, value) accept a getter such as () => t('files.uploadedBy') so they follow the language.

Options

OptionMeaning
indexFile shown first.
mode'modal' | 'drawer' | 'fullscreen' or a responsive value like 'fullscreen md:drawer'. Responsive values start at sm, so the first value covers phones.
idOpening the same id again updates that preview instead of stacking another.
gallery'strip' (default, thumbnails) or 'counter'. Phones always show the counter.
loopWraps from the last file to the first.
pdf.pagePage PDFs open at.
onChange(file, index), onClose()Callbacks.

Without mode, each file's renderer suggests a container and the largest wins, so a gallery keeps one container while navigating: images and video use fullscreen md:modal, documents fullscreen md:drawer. A single audio file or fallback card uses a narrow modal.

Handle

open() returns right away: { id, index (readonly ref), next(), previous(), goTo(i), update(input), close(), closed }. closed resolves once the overlay has left the screen. The API also has close(id?) (top-most preview when omitted), closeAll(), isOpen(id?), instances, and mounted (a provider is rendering).

Built-in renderers

KindMatchesRendering
imageimage/*, png jpg webp gif avif svg heic…Fits without upscaling; wheel/pinch/double-click zoom, drag to pan, rotate. Transparent formats sit on a checkerboard. SVG renders through <img>, so its scripts never run.
videovideo/*, mp4 webm mov…<video> with custom controls (play, seek, volume, speed, captions, picture-in-picture, fullscreen).
audioaudio/*, mp3 m4a wav…Card with cover and the same controls.
pdfapplication/pdfThe browser's own viewer in an iframe (#view=FitH). Blob sources are re-typed as PDF. When navigator.pdfViewerEnabled is false (Android), it shows Open and Download instead.
texttext/*, json, xml, yaml, log, code filesLine numbers, wrap, copy. JSON is formatted and tinted.
csvtext/csv, csv, tsvTable with sticky header, row numbers, right-aligned numbers. Detects ;, ,, tab, and |, and strips the BOM. Shows the first 1,000 rows.
markdownmd, text/markdownYour markdown hook's HTML with a Preview/Source switch, or the source.
office, archive, otherdoc(x) xls(x) ppt(x) odt…, zip…, anything elseA card with the facts and Download. Pass a rendition to preview Office files.

Text, CSV, and Markdown read at most 512 KB (FILE_PREVIEW_TEXT_LIMIT) and say when a file was cut. They read Blob sources directly; for URLs they use fetch, so the URL must be readable from the page (same origin, or CORS allowing your origin). Images, video, audio, and PDFs use elements that follow redirects without CORS.

Errors show a reason and the right action: Retry when src is a function (an expired signed link), Download when the browser cannot decode the format.

Keys: ← → Home End navigate, Esc closes, + − 0 R zoom, fit, and rotate images, Space K M F control media.

Custom renderers

Register a renderer in a plugin. Registering a built-in kind replaces it (for example, a pdf.js renderer for phones):

// app/plugins/file-preview.ts
export default defineNuxtPlugin(() => {
  useNuxtApp().$filePreview.register(
    defineFilePreviewRenderer({
      kind: 'email',
      icon: 'i-lucide-mail',
      label: () => 'Email',
      match: ({ mime, extension }) => mime === 'message/rfc822' || extension === 'eml',
      component: () => import('~/components/previews/EmailPreview.vue'),
      mode: 'fullscreen md:drawer',
    }),
  )
})

The component receives { file, url, blob, container } and emits ready(details?) once content is on screen and error({ reason, message? }) when it cannot render. Put toolbar buttons in <UiFilePreviewTools>; they appear in the header, or in the bottom bar on phones. Use useFilePreviewText(props) to read text with the size limit, and onFilePreviewKey(keys, handler) for shortcuts.

<script setup lang="ts">
import type { FilePreviewRendererEmits, FilePreviewRendererProps } from '#ui-tools/file-preview'
import { useFilePreviewText } from '#ui-tools/file-preview'

const props = defineProps<FilePreviewRendererProps>()
const emit = defineEmits<FilePreviewRendererEmits>()
const content = useFilePreviewText(props)

watch(content.status, (status) => {
  if (status === 'ready') emit('ready')
  if (status === 'error') emit('error', { reason: 'source', message: content.error.value?.message })
})
</script>

Upload fields

When a provider is mounted, the upload field's open action previews the field's files as a gallery, starting at the clicked one. Files uploaded in the current session preview from the browser's copy with no request; stored files use the url their resolve() returns. A custom upload.open still wins, and without a provider the field keeps opening a new tab.

Theming

Override these CSS variables: --nut-fp-veil (overlay), --nut-fp-stage (image and loading background), --nut-fp-document (behind PDFs), --nut-fp-checker-a / --nut-fp-checker-b, and --nut-fp-token-key|string|number|literal (JSON tint). Strings live in the filePreview section of the package locales (en, fr).

レビュー

まだレビューはありません。使ってみた感想をお寄せください。

同じリポジトリのスキル

概要と使いどころ

Use this skill when working with the nuxt-ui-tools package as a consumer or integrator. It provides the current package overview and routes to table, form, dashboard, file preview, query-state, shared responsive helpers, remote option loaders, and i18n usage.

日本語の概要は準備中です。原文の説明を表示しています。

ChronicStone/nuxt-ui-tools22026年10月8日 更新

Use this skill for internal architecture work around config-driven, registry-driven, and pattern-driven feature design in the nuxt-ui-tools repository. Covers how to organize variant-heavy features, where to put implementations, and how to keep both internals and public APIs standardized.

日本語の概要は準備中です。原文の説明を表示しています。

ChronicStone/nuxt-ui-tools22026年10月8日 更新

Use this skill when building analytics dashboards with nuxt-ui-tools as a package consumer. Covers schema and view functions (defineDashboardSchema, defineDashboardView) that take their context as typed params, useDashboard with a getter that rebuilds on input change, typed injection (useDashboardView, injectDashboard, InferDashboard, InferDashboardView), filters declared inline with the f builder and synced with the URL, memory, or an external store (one value per key across views), headless filters, filter controls and the shipped UI (UiDashboardPage, UiDashboardFilters, UiDashboardFilter, UiDashboardViewTabs) with slot overrides, remote paginated pickers and remoteTableOptions, staged queries (essential / background / deferred) with select and dependent requires, lazy enabled conditions on views, queries, and filters (blocks of disabled queries hidden, grids closing up), derived values, views (tabs), query-scoped filters, number formats (presets, Intl options, useDashboardFormat), and the dashboard blocks (stats with trends, goals, and comparisons, stat groups, gauges, unovis charts with highlights, value labels, and totals, lists with progress rings, bars, funnel, alerts, activity feeds, sortable tables, custom widgets) with their automatic loading, error, empty, and refresh states, card menus, header and footer actions, row actions, drill-down and selected state, card tabs, split cards, comparison periods, auto-refresh, and data freshness.

日本語の概要は準備中です。原文の説明を表示しています。

ChronicStone/nuxt-ui-tools22026年10月8日 更新

Use this skill when working with the nuxt-ui-tools form runtime as a package consumer. It covers schema-driven forms, the provider-backed form API, inline rendering, overlay rendering, form pages with a section navigation, choice cards, and typed submit results.

日本語の概要は準備中です。原文の説明を表示しています。

ChronicStone/nuxt-ui-tools22026年10月8日 更新

Use this skill when wiring nuxt-ui-tools translations in an app. Covers UiToolsProvider, locale objects, lazy schema text, and how package-owned UI copy differs from schema-owned text.

日本語の概要は準備中です。原文の説明を表示しています。

ChronicStone/nuxt-ui-tools22026年10月8日 更新

Use this skill for internal i18n work in this repository. Covers locale ownership, provider wiring, lazy schema text contracts, and the maintenance surfaces that must stay in sync when package or playground translations change.

日本語の概要は準備中です。原文の説明を表示しています。

ChronicStone/nuxt-ui-tools22026年10月8日 更新

ChronicStone のスキルをすべて見る

このスキルの問題を報告する