Comments (3)
Which example are you referencing? The one from the docs or the one in the examples
directory? Either way, the code in the docs hasn't been updated for 0.10.0 yet - you can use this as a base for your custom block for now:
// Alert.tsx
// The types of alerts that users can choose from
export const alertTypes = {
warning: {
icon: MdError,
color: "#e69819",
backgroundColor: {
light: "#fff6e6",
dark: "#805d20",
},
},
error: {
icon: MdCancel,
color: "#d80d0d",
backgroundColor: {
light: "#ffe6e6",
dark: "#802020",
},
},
info: {
icon: MdInfo,
color: "#507aff",
backgroundColor: {
light: "#e6ebff",
dark: "#203380",
},
},
success: {
icon: MdCheckCircle,
color: "#0bc10b",
backgroundColor: {
light: "#e6ffe6",
dark: "#208020",
},
},
} as const;
// The props for the Alert block
export const alertPropSchema = {
textAlignment: defaultProps.textAlignment,
textColor: defaultProps.textColor,
type: {
default: "warning" as const,
values: ["warning", "error", "info", "success"] as const,
},
} satisfies PropSchema;
const alertConfig = {
type: "alert",
propSchema: {
textAlignment: defaultProps.textAlignment,
textColor: defaultProps.textColor,
type: {
default: "warning",
values: ["warning", "error", "info", "success"],
},
} as const,
content: "inline",
} as const satisfies CustomBlockConfig;
// Component for the Alert block
export const Alert = (props: {
block: BlockFromConfig<typeof alertConfig, InlineContentSchema, StyleSchema>;
editor: BlockNoteEditor<
BlockSchemaWithBlock<"alert", typeof alertConfig>,
InlineContentSchema,
StyleSchema
>;
contentRef: (node: HTMLElement | null) => void;
theme: "light" | "dark";
}) => {
const Icon = alertTypes[props.block.props.type].icon;
return (
<div
className={"alert"}
style={{
...alertStyles,
backgroundColor:
alertTypes[props.block.props.type].backgroundColor[props.theme],
}}>
{/*Icon which opens a menu to choose the Alert type*/}
<Menu zIndex={99999}>
<Menu.Target>
{/*Icon wrapper to change the color*/}
<div
className={"alert-icon-wrapper"}
style={{
...alertIconWrapperStyles,
backgroundColor: alertTypes[props.block.props.type].color,
}}
contentEditable={false}>
{/*Icon itself*/}
<Icon
className={"alert-icon"}
style={{
color:
alertTypes[props.block.props.type].backgroundColor[
props.theme
],
}}
size={32}
/>
</div>
</Menu.Target>
{/*Dropdown to change the Alert type*/}
<Menu.Dropdown>
<Menu.Label>Alert Type</Menu.Label>
<Menu.Divider />
{Object.entries(alertTypes).map(([key, value]) => {
const ItemIcon = value.icon;
return (
<Menu.Item
key={key}
icon={<ItemIcon color={value.color} />}
onClick={() =>
props.editor.updateBlock(props.block, {
type: "alert",
props: { type: key as keyof typeof alertTypes },
})
}>
{key.slice(0, 1).toUpperCase() + key.slice(1)}
</Menu.Item>
);
})}
</Menu.Dropdown>
</Menu>
{/*Rich text field for user to type in*/}
<div style={inlineContentStyles} ref={props.contentRef} />
</div>
);
};
// Function which creates the Alert block itself, where the component is styled
// correctly with the light & dark theme
export const createAlertBlock = (theme: "light" | "dark") =>
createReactBlockSpec(alertConfig, {
render: (props) => <Alert {...props} theme={theme} />,
});
export const getBlockSpecs = (theme: "light" | "dark") =>
({
...defaultBlockSpecs,
alert: createAlertBlock(theme),
} satisfies BlockSpecs);
export const blockSchema = {
...defaultBlockSchema,
alert: alertConfig,
} satisfies BlockSchema;
// Slash menu item to insert an Alert block
export const getInsertAlert = (theme: "light" | "dark") =>
({
name: "Alert",
execute: (editor) => {
editor.insertBlocks(
[
{
type: "alert",
},
],
editor.getTextCursorPosition().block,
"after"
);
editor.setTextCursorPosition(editor.getTextCursorPosition().nextBlock!);
},
aliases: [
"alert",
"notification",
"emphasize",
"warning",
"error",
"info",
"success",
],
group: "Other",
icon: <RiAlertFill />,
hint: "Used to emphasize text",
} satisfies ReactSlashMenuItem<typeof blockSchema>);
const alertStyles = {
display: "flex",
justifyContent: "center",
alignItems: "center",
flexGrow: 1,
borderRadius: "4px",
height: "48px",
padding: "4px",
} as const;
const alertIconWrapperStyles = {
borderRadius: "16px",
display: "flex",
justifyContent: "center",
alignItems: "center",
marginLeft: "12px",
marginRight: "12px",
height: "18px",
width: "18px",
userSelect: "none",
cursor: "pointer",
} as const;
const inlineContentStyles = {
flexGrow: "1",
};
// App.tsx
export function App() {
const editor = useBlockNote({
domAttributes: {
editor: {
class: "editor",
"data-test": "editor",
},
},
blockSpecs: getBlockSpecs("light"),
slashMenuItems: [
...getDefaultReactSlashMenuItems(blockSchema),
getInsertAlert("light"),
],
uploadFile: uploadToTmpFilesDotOrg_DEV_ONLY,
});
// Give tests a way to get prosemirror instance
(window as WindowWithProseMirror).ProseMirror = editor?._tiptapEditor;
return <BlockNoteView className="root" editor={editor} />;
}
from blocknote.
Thank you. Fixed it.
from blocknote.
@matthewlipski we've fixed the code in the docs, right?
from blocknote.
Related Issues (20)
- How can I keep links from opening in a new tab HOT 1
- Even if editable=false, copy and paste will paste strings HOT 2
- Pdf style [Bug]
- check partykit + liveblocks examples
- Can't download file or get file link when editor not editable
- Typed or Copied Content Replaces Custom Alert Block Instead of Staying Within It HOT 1
- Suggestion menu does not scroll when using arrow keys
- TypeScript errors: `BlockNoteView` has no `editor` prop HOT 2
- Wrong documentation links
- The suggestion popover doesn't disappear HOT 3
- zh locale console error HOT 1
- Custom inline component exported value HOT 1
- Allow props context to be added to file uploads HOT 1
- Shadcn CSS has global side effects (outline is lost)
- Cannot change theme when using Shadcn HOT 1
- Groups error "Blocos Básicos" and "Blocos básicos" HOT 1
- `Cannot find module '@blocknote/react'` warning is VS Code HOT 4
- TypeError: Cannot read properties of null (reading 'useMemo') in next.js
- Add support for Uppy for file uploading HOT 4
- Integrate emoji picker HOT 6
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from blocknote.