diff --git a/docs/app/(home)/hero/DemoEditor.tsx b/docs/app/(home)/hero/DemoEditor.tsx index 3712a843ce..38d30067bb 100644 --- a/docs/app/(home)/hero/DemoEditor.tsx +++ b/docs/app/(home)/hero/DemoEditor.tsx @@ -1,8 +1,10 @@ import { BlockNoteSchema, combineByGroup, + defaultBlockSpecs, filterSuggestionItems, uploadToTmpFilesDotOrg_DEV_ONLY, + AccessibleImageBlock, } from "@blocknote/core"; import * as locales from "@blocknote/core/locales"; import "@blocknote/core/fonts/inter.css"; @@ -90,7 +92,14 @@ export default function DemoEditor() { ...locales.en, multi_column: multiColumnLocales.en, }, - schema: withMultiColumn(BlockNoteSchema.create()), + schema: withMultiColumn( + BlockNoteSchema.create({ + blockSpecs: { + ...defaultBlockSpecs, + image: AccessibleImageBlock, + }, + }), + ), dropCursor: multiColumnDropCursor, collaboration: { provider, diff --git a/packages/core/src/blocks/ImageBlockContent/AccessibleImageBlock.ts b/packages/core/src/blocks/ImageBlockContent/AccessibleImageBlock.ts new file mode 100644 index 0000000000..0bd4d48b42 --- /dev/null +++ b/packages/core/src/blocks/ImageBlockContent/AccessibleImageBlock.ts @@ -0,0 +1,45 @@ +import type { BlockNoteEditor } from "../../editor/BlockNoteEditor.js"; +import type { + BlockFromConfig, + BlockSchemaWithBlock, +} from "../../schema/blocks/types.js"; +import type { InlineContentSchema } from "../../schema/inlineContent/types.js"; +import type { StyleSchema } from "../../schema/styles/types.js"; +import { createBlockSpec } from "../../schema/blocks/createSpec.js"; +import { + imageBlockConfig, + imageParse, + imageRender, + imageToExternalHTML, +} from "./ImageBlockContent.js"; + +type ImageBlockConfig = typeof imageBlockConfig; + +export const accessibleImageRender = ( + block: BlockFromConfig, + editor: BlockNoteEditor< + BlockSchemaWithBlock, + InlineContentSchema, + StyleSchema + >, +) => { + const imageRenderComputed = imageRender(block, editor); + const dom = imageRenderComputed.dom; + const imgSelector = dom.querySelector("img"); + + imgSelector?.setAttribute("alt", ""); + imgSelector?.setAttribute("role", "presentation"); + imgSelector?.setAttribute("aria-hidden", "true"); + imgSelector?.setAttribute("tabindex", "-1"); + + return { + ...imageRenderComputed, + dom, + }; +}; + +export const AccessibleImageBlock = createBlockSpec(imageBlockConfig, { + render: accessibleImageRender, + parse: imageParse, + toExternalHTML: imageToExternalHTML, +}); diff --git a/packages/core/src/index.ts b/packages/core/src/index.ts index 74f91bee5c..bdfbab5125 100644 --- a/packages/core/src/index.ts +++ b/packages/core/src/index.ts @@ -23,6 +23,7 @@ export * from "./blocks/FileBlockContent/helpers/toExternalHTML/createFigureWith export * from "./blocks/FileBlockContent/helpers/toExternalHTML/createLinkWithCaption.js"; export * from "./blocks/FileBlockContent/uploadToTmpFilesDotOrg_DEV_ONLY.js"; export * from "./blocks/ImageBlockContent/ImageBlockContent.js"; +export * from "./blocks/ImageBlockContent/AccessibleImageBlock.js"; export * from "./blocks/PageBreakBlockContent/getPageBreakSlashMenuItems.js"; export * from "./blocks/PageBreakBlockContent/PageBreakBlockContent.js"; export * from "./blocks/PageBreakBlockContent/schema.js";