Files
hudozka/apps/hudozka-writer/src/components/BlockMenu.tsx
T
tmshv 467a218d00 move to biome (#297)
* switch to biome

* writer format

* migrate format

* packages format

* hudozka format

* writer fix

* biome config updated

* migrate fix

* packages fix

* hudozka fix

* claude updated
2026-04-25 03:25:15 +03:00

70 lines
2.0 KiB
TypeScript

import type { Editor } from "@tiptap/react"
import { generateBlockId } from "../lib/id"
import "./BlockMenu.css"
type BlockType = {
label: string
type: string
attrs?: Record<string, unknown>
}
const BLOCK_TYPES: BlockType[] = [
{ label: "Text", type: "textBlock" },
{ label: "Image", type: "imageBlock", attrs: { id: "", imageId: "", wide: false, caption: "" } },
{ label: "File", type: "documentBlock", attrs: { id: "", fileId: "", title: "" } },
{ label: "Embed", type: "embedBlock", attrs: { id: "", src: "" } },
{ label: "Card Grid", type: "cardGridBlock", attrs: { id: "", items: "[]" } },
]
export type BlockMenuProps = {
editor: Editor
position: number
onClose: () => void
filter?: string
}
export function BlockMenu({ editor, position, onClose, filter }: BlockMenuProps) {
const filtered = filter
? BLOCK_TYPES.filter(b => b.label.toLowerCase().includes(filter.toLowerCase()))
: BLOCK_TYPES
function handleInsert(block: BlockType) {
const id = generateBlockId()
if (block.type === "textBlock") {
editor
.chain()
.focus()
.insertContentAt(position, {
type: "textBlock",
content: [{ type: "paragraph" }],
})
.run()
} else {
editor
.chain()
.focus()
.insertContentAt(position, {
type: block.type,
attrs: { ...block.attrs, id },
})
.run()
}
onClose()
}
if (filtered.length === 0) return null
return (
<div className="block-menu">
{filtered.map(block => (
<button type="button" key={block.type} className="block-menu-item" onClick={() => handleInsert(block)}>
{block.label}
</button>
))}
</div>
)
}
export type { BlockType }
export { BLOCK_TYPES }