# Defining Custom Elements In our previous example, we started with a paragraph, but we never actually told Slate anything about the `paragraph` block type. We just let it use its internal default renderer, which uses a plain old `
{props.children}
)
}
```
Easy enough.
See the `props.attributes` reference? Slate passes attributes that should be rendered on the top-most element of your blocks, so that you don't have to build them up yourself. You **must** mix the attributes into your component.
And see that `props.children` reference? Slate will automatically render all of the children of a block for you, and then pass them to you just like any other React component would, via `props.children`. That way you don't have to muck around with rendering the proper text nodes or anything like that. You **must** render the children as the lowest leaf in your component.
And here's a component for the "default" elements:
```jsx
const DefaultElement = props => {
return {props.children}
} ``` Now, let's add that renderer to our `Editor`: ```jsx const initialValue = [ { type: 'paragraph', children: [{ text: 'A line of text in a paragraph.' }], }, ] const App = () => { const [editor] = useState(() => withReact(createEditor())) // Define a rendering function based on the element passed to `props`. We use // `useCallback` here to memoize the function for subsequent renders. const renderElement = useCallback(props => { switch (props.element.type) { case 'code': return
{props.children}
)
}
const DefaultElement = props => {
return {props.children}
} ``` Okay, but now we'll need a way for the user to actually turn a block into a code block. So let's change our `onKeyDown` function to add a `` Ctrl-` `` shortcut that does just that: ```jsx // Import the `Editor` and `Transforms` helpers from Slate. import { Editor, Transforms, Element } from 'slate' const initialValue = [ { type: 'paragraph', children: [{ text: 'A line of text in a paragraph.' }], }, ] const App = () => { const [editor] = useState(() => withReact(createEditor())) const renderElement = useCallback(props => { switch (props.element.type) { case 'code': return
{props.children}
)
}
const DefaultElement = props => {
return {props.children}
} ``` Now, if you press `` Ctrl-` `` the block your cursor is in should turn into a code block! Magic! But we forgot one thing. When you hit `` Ctrl-` `` again, it should change the code block back into a paragraph. To do that, we'll need to add a bit of logic to change the type we set based on whether any of the currently selected blocks are already a code block: ```jsx const initialValue = [ { type: 'paragraph', children: [{ text: 'A line of text in a paragraph.' }], }, ] const App = () => { const [editor] = useState(() => withReact(createEditor())) const renderElement = useCallback(props => { switch (props.element.type) { case 'code': return