-
-
Notifications
You must be signed in to change notification settings - Fork 558
feat: Toggle blocks #1707
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
feat: Toggle blocks #1707
Conversation
The latest updates on your projects. Learn more about Vercel for Git ↗︎
|
@blocknote/ariakit
@blocknote/code-block
@blocknote/core
@blocknote/mantine
@blocknote/react
@blocknote/server-util
@blocknote/shadcn
@blocknote/xl-ai
@blocknote/xl-ai-server
@blocknote/xl-docx-exporter
@blocknote/xl-multi-column
@blocknote/xl-odt-exporter
@blocknote/xl-pdf-exporter
commit: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What I'm more interested in seeing here is how we can add this to existing block types (such as headings with a prop) rather than as a separate element like this implements.
export const ToggleHeading = createBlockSpec( | ||
{ | ||
...headingConfig, | ||
type: "toggleHeading", | ||
}, | ||
{ | ||
...headingImplementation, | ||
render: (block, editor) => | ||
createToggleWrapper( | ||
block, | ||
editor, | ||
headingImplementation.render(block, editor), | ||
), | ||
}, | ||
); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is fantastic, composability!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Now, this is creating a new block type, can we instead just "wrap over" heading, and if it has a prop isToggleable
it switches it's render implementation from the default, into using this toggle wrapper?
So that there is only one heading implementation.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should I also revert the heading block to using createStronglyTypedTiptapNode
? Since the keyboard shortcuts and input rules won't work if we stick with createBlockSpec
. Or do you wanna see how it looks using the createBlockSpec
first?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For now, it is more important to see that the pattern can work before being caught up in those sort of details.
Once we can see that it works for headings, we can see if we can do it for something like list items
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Makes sense, updated the code👍
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great, this looks about right. Ideally it'd be "around" the heading component, but that is minor and fixable.
To explain more, like this you made this:
function Heading(props){
function renderHeading(){}
return props.isToggleable ? <Toggle>{renderHeading()}</Toggle> : renderHeading()
}
blocks: { heading: Heading }
Where I'd like something more like this:
function Heading() {
return renderHeading()
}
const WrapWithToggle=(component) => props => {
return props.isToggleable ? <Toggle>{component}</Toggle> : component
}
blocks: { heading: WrapWithToggle(heading) }
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Now that we've validated this approach, I do think you have the right idea with making this a strongly typed tiptap node to keep all previous functionality.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Implemented your suggestions, think it looks pretty decent. There are 2 things that aren't super nice though:
- Headings now always need to include a node view, even if they're not togglable.
- Because
createStronglyTypedTiptapNode
works on the TipTap API level whilecreateToggleWrapper
works on the BlockNote API level, we have to convert from a node to a block in the node view and do some slightly weird stuff there.
How much of a concern are those 2?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- should be fine, node views are essentially "ejecting" from normal rendering but shouldn't be different (if in pure JS not react)
- Yea, so the ideal here is to build everything in terms of the blocknote API instead in the future, just don't wanna invest into that at the moment. May be worth extracting into something common, but not necessary for the moment either.
So, I think this is good from here. 🚦 green light to implement the lists & other ones, it seems like a sound approach for the moment.
…stead of `createBlockSpec`
This PR adds toggle blocks, which have a button in them to show/hide their children.
TODO: