Emdash source with visual editor image upload fix
Fixes: 1. media.ts: wrap placeholder generation in try-catch 2. toolbar.ts: check r.ok, display error message in popover
This commit is contained in:
22
packages/plugins/embeds/src/astro/Bluesky.astro
Normal file
22
packages/plugins/embeds/src/astro/Bluesky.astro
Normal file
@@ -0,0 +1,22 @@
|
||||
---
|
||||
/**
|
||||
* Bluesky post embed component for Portable Text
|
||||
*
|
||||
* Wraps astro-embed's BlueskyPost component, extracting props from the PT block node.
|
||||
* astro-portabletext passes `node` (not `value`) for custom type components.
|
||||
*
|
||||
* Accepts either `id` or `url` field for compatibility with different content sources.
|
||||
*/
|
||||
import { BlueskyPost } from "astro-embed";
|
||||
import type { BlueskyBlock } from "../schemas.js";
|
||||
|
||||
interface Props {
|
||||
node: BlueskyBlock & { url?: string };
|
||||
}
|
||||
|
||||
const { node } = Astro.props;
|
||||
// Support both 'id' (schema) and 'url' (admin editor) field names
|
||||
const postId = node.id || node.url;
|
||||
---
|
||||
|
||||
{postId && <BlueskyPost id={postId} />}
|
||||
19
packages/plugins/embeds/src/astro/Gist.astro
Normal file
19
packages/plugins/embeds/src/astro/Gist.astro
Normal file
@@ -0,0 +1,19 @@
|
||||
---
|
||||
/**
|
||||
* GitHub Gist embed component for Portable Text
|
||||
*
|
||||
* Wraps astro-embed's Gist component, extracting props from the PT block node.
|
||||
* astro-portabletext passes `node` (not `value`) for custom type components.
|
||||
*/
|
||||
import { Gist as AstroGist } from "astro-embed";
|
||||
import type { GistBlock } from "../schemas.js";
|
||||
|
||||
interface Props {
|
||||
node: GistBlock;
|
||||
}
|
||||
|
||||
const { node } = Astro.props;
|
||||
const { id, file } = node;
|
||||
---
|
||||
|
||||
<AstroGist id={id} file={file} />
|
||||
19
packages/plugins/embeds/src/astro/LinkPreview.astro
Normal file
19
packages/plugins/embeds/src/astro/LinkPreview.astro
Normal file
@@ -0,0 +1,19 @@
|
||||
---
|
||||
/**
|
||||
* Link preview (Open Graph) embed component for Portable Text
|
||||
*
|
||||
* Wraps astro-embed's LinkPreview component, extracting props from the PT block node.
|
||||
* astro-portabletext passes `node` (not `value`) for custom type components.
|
||||
*/
|
||||
import { LinkPreview as AstroLinkPreview } from "astro-embed";
|
||||
import type { LinkPreviewBlock } from "../schemas.js";
|
||||
|
||||
interface Props {
|
||||
node: LinkPreviewBlock;
|
||||
}
|
||||
|
||||
const { node } = Astro.props;
|
||||
const { id, hideMedia } = node;
|
||||
---
|
||||
|
||||
<AstroLinkPreview id={id} hideMedia={hideMedia} />
|
||||
19
packages/plugins/embeds/src/astro/Mastodon.astro
Normal file
19
packages/plugins/embeds/src/astro/Mastodon.astro
Normal file
@@ -0,0 +1,19 @@
|
||||
---
|
||||
/**
|
||||
* Mastodon post embed component for Portable Text
|
||||
*
|
||||
* Wraps astro-embed's MastodonPost component, extracting props from the PT block node.
|
||||
* astro-portabletext passes `node` (not `value`) for custom type components.
|
||||
*/
|
||||
import { MastodonPost } from "astro-embed";
|
||||
import type { MastodonBlock } from "../schemas.js";
|
||||
|
||||
interface Props {
|
||||
node: MastodonBlock;
|
||||
}
|
||||
|
||||
const { node } = Astro.props;
|
||||
const { id } = node;
|
||||
---
|
||||
|
||||
<MastodonPost id={id} />
|
||||
19
packages/plugins/embeds/src/astro/Tweet.astro
Normal file
19
packages/plugins/embeds/src/astro/Tweet.astro
Normal file
@@ -0,0 +1,19 @@
|
||||
---
|
||||
/**
|
||||
* Tweet embed component for Portable Text
|
||||
*
|
||||
* Wraps astro-embed's Tweet component, extracting props from the PT block node.
|
||||
* astro-portabletext passes `node` (not `value`) for custom type components.
|
||||
*/
|
||||
import { Tweet as AstroTweet } from "astro-embed";
|
||||
import type { TweetBlock } from "../schemas.js";
|
||||
|
||||
interface Props {
|
||||
node: TweetBlock;
|
||||
}
|
||||
|
||||
const { node } = Astro.props;
|
||||
const { id, theme } = node;
|
||||
---
|
||||
|
||||
<AstroTweet id={id} theme={theme} />
|
||||
25
packages/plugins/embeds/src/astro/Vimeo.astro
Normal file
25
packages/plugins/embeds/src/astro/Vimeo.astro
Normal file
@@ -0,0 +1,25 @@
|
||||
---
|
||||
/**
|
||||
* Vimeo embed component for Portable Text
|
||||
*
|
||||
* Wraps astro-embed's Vimeo component, extracting props from the PT block node.
|
||||
* astro-portabletext passes `node` (not `value`) for custom type components.
|
||||
*/
|
||||
import { Vimeo as AstroVimeo } from "astro-embed";
|
||||
import type { VimeoBlock } from "../schemas.js";
|
||||
|
||||
interface Props {
|
||||
node: VimeoBlock;
|
||||
}
|
||||
|
||||
const { node } = Astro.props;
|
||||
const { id, poster, posterQuality, params, playlabel } = node;
|
||||
---
|
||||
|
||||
<AstroVimeo
|
||||
id={id}
|
||||
poster={poster}
|
||||
posterQuality={posterQuality}
|
||||
params={params}
|
||||
playlabel={playlabel}
|
||||
/>
|
||||
26
packages/plugins/embeds/src/astro/YouTube.astro
Normal file
26
packages/plugins/embeds/src/astro/YouTube.astro
Normal file
@@ -0,0 +1,26 @@
|
||||
---
|
||||
/**
|
||||
* YouTube embed component for Portable Text
|
||||
*
|
||||
* Wraps astro-embed's YouTube component, extracting props from the PT block node.
|
||||
* astro-portabletext passes `node` (not `value`) for custom type components.
|
||||
*/
|
||||
import { YouTube as AstroYouTube } from "astro-embed";
|
||||
import type { YouTubeBlock } from "../schemas.js";
|
||||
|
||||
interface Props {
|
||||
node: YouTubeBlock;
|
||||
}
|
||||
|
||||
const { node } = Astro.props;
|
||||
const { id, poster, posterQuality, params, playlabel, title } = node;
|
||||
---
|
||||
|
||||
<AstroYouTube
|
||||
id={id}
|
||||
poster={poster}
|
||||
posterQuality={posterQuality}
|
||||
params={params}
|
||||
playlabel={playlabel}
|
||||
title={title}
|
||||
/>
|
||||
66
packages/plugins/embeds/src/astro/index.ts
Normal file
66
packages/plugins/embeds/src/astro/index.ts
Normal file
@@ -0,0 +1,66 @@
|
||||
/**
|
||||
* Astro components for rendering embed blocks in Portable Text
|
||||
*
|
||||
* These components are automatically registered with PortableText when
|
||||
* the embeds plugin is enabled. Manual wiring is no longer needed!
|
||||
*
|
||||
* The components are exported with lowercase names matching their block types
|
||||
* for auto-registration, plus PascalCase aliases for direct usage.
|
||||
*
|
||||
* @example Direct usage (if you need to customize)
|
||||
* ```astro
|
||||
* ---
|
||||
* import { YouTube } from "@emdash-cms/plugin-embeds/astro";
|
||||
* ---
|
||||
* <YouTube value={{ id: "dQw4w9WgXcQ", _type: "youtube", _key: "1" }} />
|
||||
* ```
|
||||
*/
|
||||
|
||||
import BlueskyComponent from "./Bluesky.astro";
|
||||
import GistComponent from "./Gist.astro";
|
||||
import LinkPreviewComponent from "./LinkPreview.astro";
|
||||
import MastodonComponent from "./Mastodon.astro";
|
||||
import TweetComponent from "./Tweet.astro";
|
||||
import VimeoComponent from "./Vimeo.astro";
|
||||
// Import all components
|
||||
import YouTubeComponent from "./YouTube.astro";
|
||||
|
||||
// Export with lowercase names (for auto-registration via virtual module)
|
||||
// These names MUST match the block type names in EMBED_BLOCK_TYPES
|
||||
export {
|
||||
YouTubeComponent as youtube,
|
||||
VimeoComponent as vimeo,
|
||||
TweetComponent as tweet,
|
||||
BlueskyComponent as bluesky,
|
||||
MastodonComponent as mastodon,
|
||||
LinkPreviewComponent as linkPreview,
|
||||
GistComponent as gist,
|
||||
};
|
||||
|
||||
// Also export with PascalCase for direct usage
|
||||
export {
|
||||
YouTubeComponent as YouTube,
|
||||
VimeoComponent as Vimeo,
|
||||
TweetComponent as Tweet,
|
||||
BlueskyComponent as Bluesky,
|
||||
MastodonComponent as Mastodon,
|
||||
LinkPreviewComponent as LinkPreview,
|
||||
GistComponent as Gist,
|
||||
};
|
||||
|
||||
/**
|
||||
* All embed components keyed by their Portable Text block type.
|
||||
* Exported as `blockComponents` for auto-registration via the virtual module,
|
||||
* and as `embedComponents` for direct usage.
|
||||
*/
|
||||
export const blockComponents = {
|
||||
youtube: YouTubeComponent,
|
||||
vimeo: VimeoComponent,
|
||||
tweet: TweetComponent,
|
||||
bluesky: BlueskyComponent,
|
||||
mastodon: MastodonComponent,
|
||||
linkPreview: LinkPreviewComponent,
|
||||
gist: GistComponent,
|
||||
} as const;
|
||||
|
||||
export { blockComponents as embedComponents };
|
||||
Reference in New Issue
Block a user