UNPKG

colonel-kurtz

Version:
140 lines (107 loc) 4.61 kB
# Block Types 1. [Overview](#overview) 2. [Properties](#properties) 3. [Creating Block Types](#creating-block-types) 4. [Advanced Block Types](#advanced-block-types) 5. [Updating content](#updating-content) ## Overview As it pertains to Colonel Kurtz, a block type is a unique entry that describes the editing experience for a block. When a block is created, it will be assigned a `type` equal to the id of a Block Type. ## Properties | Property | Description | | ----------- | -------------------------------------------------------------------------------------------------------------- | | id | A unique identifier. Assigned to a block when it is created. | | label | A display name given to the block type in the interface. | | component | A React component used to edit a block of a given type. | | types | An array of other BlockType ids that may be created as children. | | maxChildren | An integer specifying the maximum allowed children that may be created. | | root | Configures the BlockType to display in the menu unless specifically asked for using `types`. Defaults to true. | | group | When set, groups BlockTypes of the provided string name within the block menu selector. | ## Creating Block Types Block Types require a unique identifier and a React component definition. They are added to Colonel Kurtz by passing in a `blockTypes` property when making an instance: ```javascript let blockTypes = [ { id: 'image', label: 'Image', component: require('../addons/image') } ] ``` The `id` value must be unique (the `label` property _should_ be, however it isn't formally validated). The `component` value requires a bit more configuration. Being a React Component, components only mandate a `render` method. You can update the content for a block with the `onChange` property that is sent down from the editor: ```javascript class TextBook extends React.Component { render() { return <textarea onBlur={this._onBlur.bind(this)} /> } _onBlur(e) { // Alternatively, // this.props.onChange('text', e.currentTarget.textContent) this.props.onChange({ text: e.currentTarget.textContent }) } } ``` Now that the `Textbox` component has been created, we can send it into the available block types passed into a `ColonelKurtz` instance. ```javascript let blockTypes = [ { id: 'text', label: 'Textbox', component: Textbox } ] let editor = new ColonelKurtz({ el: document.getElementById('app'), blockTypes: blockTypes }) ``` ## Advanced Block Types Block types can be as sophisticated as you wish. There technically isn't anything to stop you from building a React app and assigning it as a component definition. For an example of this, see [the ArsArsenal photo gallery](https://github.com/vigetlabs/ars-arsenal). ArsArsenal can operate as a stand-alone gallery, however it exposes a "component" key that is useable by Colonel Kurtz: ```javascript import { Component as ArsArsenal } from 'ars-arsenal' let blockTypes = [ { id: 'image', label: 'Image', component: ArsArsenal } ] ``` ## Updating content Each block type is passed an `onChange` property. You can use this property to signal changes to the `content` field for a given block. There are two ways to update content: provide an object, or a key path and value. ### Updating content with an object Passing an object into the `onChange` prop will merge the fields provided into the existing content block: ```javascript changeText(text) { this.props.onChange({ text }) } ``` ### Updating content with a key path and value By providing a key path and value, Colonel Kurtz update a specific key within the shape of your content. This is particularly useful for updating nested keys. This behaves similarly to [Lodash's set function](https://lodash.com/docs#set): ```javascript changeText(text) { this.props.onChange('text', text) // { text: text } this.props.onChange('deeply.nested.key', true) // { deeply: { nested: { key: true } } } } ``` By providing a string of `dot` separated values, CK will drill down into content properties on your behalf. This aims to greatly improve the ergonomics of updating nested keys.