-
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
🚀
worxpace
25 - Add block type: callout (#45)
- Loading branch information
1 parent
afe9b14
commit 79ac399
Showing
5 changed files
with
168 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,96 @@ | ||
"use client"; | ||
|
||
import { defaultProps } from "@blocknote/core"; | ||
import type { | ||
BlockFromConfig, | ||
InlineContentSchema, | ||
PropSpec, | ||
StyleSchema, | ||
} from "@blocknote/core"; | ||
import { createReactBlockSpec } from "@blocknote/react"; | ||
|
||
import { IconBlock, type IconBlockProps, type IconInfo } from "@acme/ui/custom"; | ||
|
||
import { cn } from "@/lib/utils"; | ||
|
||
export interface CalloutBlockSpec { | ||
type: "callout"; | ||
readonly propSchema: typeof defaultProps & { | ||
type: PropSpec<"emoji" | "lucide" | "file">; | ||
name: PropSpec<string>; | ||
emoji: PropSpec<string>; | ||
url: PropSpec<string>; | ||
color: PropSpec<string>; | ||
}; | ||
content: "inline"; | ||
} | ||
|
||
const getBlockIcon = ( | ||
block: BlockFromConfig<CalloutBlockSpec, InlineContentSchema, StyleSchema>, | ||
): IconInfo => { | ||
const { type, color, name, emoji, url } = block.props; | ||
switch (type) { | ||
case "emoji": | ||
return { type, emoji }; | ||
case "lucide": | ||
return { type, name, color } as IconInfo; | ||
case "file": | ||
return { type, url }; | ||
default: | ||
return { type: "emoji", emoji: " " }; | ||
} | ||
}; | ||
|
||
// The Callout block. | ||
export const Callout = createReactBlockSpec< | ||
CalloutBlockSpec, | ||
InlineContentSchema, | ||
StyleSchema | ||
>( | ||
{ | ||
type: "callout", | ||
propSchema: { | ||
...defaultProps, | ||
type: { default: "emoji" }, | ||
emoji: { default: "🚧" }, | ||
name: { default: "" }, | ||
url: { default: "" }, | ||
color: { default: "default" }, | ||
}, | ||
content: "inline", | ||
}, | ||
{ | ||
render: (props) => { | ||
const backgroundColor = props.block.props.backgroundColor; | ||
const iconBlockProps: IconBlockProps = { | ||
defaultIcon: getBlockIcon(props.block), | ||
onSelect: (icon) => | ||
props.editor.updateBlock(props.block, { | ||
type: "callout", | ||
props: icon, | ||
}), | ||
onRemove: () => | ||
props.editor.updateBlock(props.block, { | ||
type: "callout", | ||
props: { | ||
type: "emoji", | ||
name: "", | ||
url: "", | ||
emoji: "🚧", | ||
color: "default", | ||
}, | ||
}), | ||
}; | ||
|
||
return ( | ||
<div className={cn("flex w-full p-4 pl-3", `bg-[${backgroundColor}]`)}> | ||
<div className="mt-0.5 shrink-0"> | ||
<IconBlock {...iconBlockProps} /> | ||
</div> | ||
{/* Rich text field for user to type in */} | ||
<div className="w-full min-w-0 pl-2" ref={props.contentRef} /> | ||
</div> | ||
); | ||
}, | ||
}, | ||
); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
export * from "./schema"; | ||
export * from "./slash-menu"; | ||
/** Custom Blocks */ | ||
export * from "./callout"; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
import { | ||
BlockNoteSchema, | ||
defaultBlockSpecs, | ||
insertOrUpdateBlock, | ||
} from "@blocknote/core"; | ||
import { Construction } from "lucide-react"; | ||
|
||
import { Callout } from "./callout"; | ||
|
||
// Our schema with block specs, which contain the configs and implementations for blocks | ||
// that we want our editor to use. | ||
export const schema = BlockNoteSchema.create({ | ||
blockSpecs: { | ||
// Adds all default blocks. | ||
...defaultBlockSpecs, | ||
// Adds the Callout block. | ||
callout: Callout, | ||
}, | ||
}); | ||
export type CustomEditor = typeof schema.BlockNoteEditor; | ||
|
||
// Slash menu item to insert an Callout block | ||
export const insertCallout = (editor: CustomEditor) => ({ | ||
title: "Callout", | ||
onItemClick: () => insertOrUpdateBlock(editor, { type: "callout" }), | ||
aliases: ["callout", "notification", "emphasize"], | ||
group: "Other", | ||
icon: <Construction size={18} />, | ||
subtext: "Make writing stand out.", | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
import { filterSuggestionItems } from "@blocknote/core"; | ||
|
||
import "@blocknote/core/fonts/inter.css"; | ||
|
||
import { | ||
getDefaultReactSlashMenuItems, | ||
SuggestionMenuController, | ||
} from "@blocknote/react"; | ||
|
||
import { insertCallout, type CustomEditor } from "./schema"; | ||
|
||
interface CustomSlashMenuProps { | ||
editor: CustomEditor; | ||
} | ||
|
||
export const CustomSlashMenu = ({ editor }: CustomSlashMenuProps) => { | ||
return ( | ||
<SuggestionMenuController | ||
triggerCharacter={"/"} | ||
getItems={async (query) => | ||
// Gets all default slash menu items and `insertCallout` item. | ||
filterSuggestionItems( | ||
[...getDefaultReactSlashMenuItems(editor), insertCallout(editor)], | ||
query, | ||
) | ||
} | ||
/> | ||
); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters