Files
boos e0a5f57793 feat(desktop): embed BoosAPI Desktop client as a subproject
Vendor the rebranded BoosAPI Desktop client (Tauri + Vue) into metapi as
a monorepo subdirectory under desktop/. Source only — node_modules,
dist, Cargo target and the upstream .git history are excluded.

desktop/ keeps its own independent Cargo workspace (desktop/src-tauri
with crates/*); it is not part of the backend boosapi crate, so a
`cargo check` at the metapi root still compiles only the backend. Build
the desktop app from desktop/src-tauri per desktop/README.md.

Note: app icons are still placeholder assets pending the final BoosAPI
logo. The updater signing keys live outside the repo and are not
included.
2026-06-22 11:32:57 +08:00

67 lines
2.7 KiB
Markdown

# ImageNode — Custom preview handling
`ImageNode` renders images and emits events for user interactions. We expose a `click` event on images so you can take over the click behavior (for example to open a custom image preview / lightbox) without replacing the whole renderer.
- Events: `click` — emitted when a user clicks a successfully loaded image. Payload is `[Event, string]` where the second item is the src actually used for rendering (this may be a fallback URL).
- Events: `load` / `error` — emitted when an image finishes loading or fails, payload is the image `src`.
## Example: wrapper + VitePress registration
Create a small wrapper component that intercepts `click` and use `setCustomComponents` to register it in the client app.
### 1) `CustomImageNode.vue` (simple wrapper)
```vue twoslash
<script setup lang="ts">
import { ImageNode } from 'markstream-vue'
const emit = defineEmits(['load', 'error', 'click'])
function onImageClick(payload: [Event, string]) {
const [, src] = payload
// Simple example: open the image in a new tab for preview.
// Replace this with a modal/lightbox call in real apps.
window.open(src, '_blank')
// Re-emit the click so parent code can also react if needed.
emit('click', payload)
}
</script>
<template>
<ImageNode v-bind="$attrs" @load="emit('load', $event)" @error="emit('error', $event)" @click="onImageClick" />
</template>
```
### 2) Register in VitePress theme enhance
```ts twoslash
import type { App, Component } from 'vue'
import { setCustomComponents } from 'markstream-vue'
// docs/.vitepress/theme/index.ts
declare const CustomImageNode: Component
export default ({ app }: { app: App }) => {
setCustomComponents('vitepress-image-preview', { image: CustomImageNode })
}
```
## Optional: richer preview interactions
For zoom/gesture/slide support, call a lightbox library such as `photoswipe`, `fslightbox` or `basiclightbox` inside `onImageClick`, or control an application-level modal to show the preview.
## Summary
The `click` event from `ImageNode` is the primary hook for implementing custom previews. The usual approach is wrapping the original component and registering it with `setCustomComponents` in the client app. The wrapper can also forward `load`/`error` events or add additional behavior (analytics, alternative lazy-load handling, custom placeholders, etc.).
Quick try — register `CustomImageNode` in a VitePress client enhance and test clicking images in the `playground`:
```ts twoslash
// docs/.vitepress/theme/index.ts
import type { App, Component } from 'vue'
import { setCustomComponents } from 'markstream-vue'
declare const CustomImageNode: Component
export default ({ app }: { app: App }) => setCustomComponents('vitepress-image-preview', { image: CustomImageNode })
```