Inline Editing in Tina refers to editing values directly in the area they appear on the page, instead of in the Tina sidebar. These are the general steps to set up inline editing:
Play around with this simple demo to get a feel for Inline Editing. Get familiar with the Inline Editing API in this step-by-step guide.
The InlineForm
and InlineField
components can be used to set up inline editing in your layout. InlineForm
receives the form object created via one of the form hooks in order to provide it to the inline editing context.
InlineForm
should wrap the page or component where you want to add inline editing, turning the page into the form itself. Below is an example of adding InlineForm
to a page component:
import * as React from React
import { useForm, usePlugin } from 'tinacms'
+import { InlineForm } from 'react-tinacms-inline'
export function Page(props) {
const [modifiedValues, form] = useForm(props.data)
usePlugin(form)
return (
+ <InlineForm form={form}>
<main>
<h1>{modifiedValues.title}</h1>
</main>
+ </InlineForm>
)
}
The Inline Form alone won't change any behavior. To edit on the page, you'll need to add Inline Fields.
The react-tinacms-inline
package provides a set of pre-configured Inline Fields that should work for many use cases. These fields provide basic input elements and handle the rendering logic between edit and preview mode.
Let's add some Inline Fields using the previous example:
import * as React from React
import { useForm, usePlugin } from 'tinacms'
+import { InlineForm, InlineText } from 'react-tinacms-inline'
export function Page(props) {
const [modifiedValues, form] = useForm(props.data)
usePlugin(form)
return (
<InlineForm form={form}>
<main>
- <h1>{modifiedValues.title}</h1>
+ <h1>
+ <InlineText name="title" />
+ </h1>
</main>
</InlineForm>
)
}
All Inline Fields expect a name
prop, as with regular Tina Fields, the value should be the path to the data being edited by that field. Refer to individual inline field docs to see their specific properties.
Check out the final-form docs for a more detailed look at how the
name
field works.
Currently, these supported Inline Fields available:
There may be cases where you want to create your own Inline Fields. The InlineField
component allows you to create a custom Inline Field. This is helpful when you need precise control over rendering or input functionality.
First, make sure your component is wrapped in an InlineForm
. You can then add InlineField
components, a render props-based component that allows you to conditionally display an editing interface (when in edit mode) or the page as it will appear in production.
The rough idea is like this:
<InlineForm form={formObject}>
<InlineField name="path-to-data">
{({ input }) => {
if (cms.enabled) {
// we're in editing mode, show an editable interface
} else {
// we're not in editing mode, show the production layout
}
}}
</InlineField>
</InlineForm>
Below is an example of the Page
component used in previous examples, but refactored to define its own custom Inline Fields:
import * as React from React
// import `useCMS`
import { useForm, useCMS, usePlugin } from 'tinacms'
import { InlineForm, InlineField } from 'react-tinacms-inline'
export function Page(props) {
// Access the CMS object
const cms = useCMS()
const [, form] = useForm(props.data)
usePlugin(form)
return (
<InlineForm form={form}>
<main>
{/**
* Use `InlineField` and the render props
* pattern to create custom field inputs
* that render when the cms is enabled
*/}
<InlineField name="title">
{({ input }) => {
if (cms.enabled) {
return <input type="text" {...input} />
}
return <h1>{input.value}</h1>
}}
</InlineField>
</main>
</InlineForm>
)
}
InlineField
uses render props to pass the form state and other props to its children. Based on cms.enabled
, you can conditionally render editing inputs or the original element / value.
If you have an idea for an Inline Field plugin, consider contributing! Make an issue with your suggestion or reach out on the forum for support.
Via Styled-Components
The Inline Fields are meant to have minimal styles. But there may be situations where you'll want to override the base styles. This is made possible via Styled Components.
// An example `InlineText` with Extended Styles
export function Page(props) {
const [, form] = useForm(props.data)
usePlugin(form)
return (
<InlineForm form={form}>
<main>
<StyledText name="title" />
</main>
</InlineForm>
)
}
// Extended InlineText styled component
const StyledText = styled(InlineText)`
color: green;
`
Notice how the new component, StyledText
is just a styled version of InlineText
.
Via Class Name
You can also extend styles by assigning a className
to the Inline Field.
// In an Inline Form
<InlineImage
name="frontmatter.image"
uploadDir={() => '/public/images/'}
parse={media => media.id}
className="inline-img"
/>
// Style via className in css
.inline-img {
background-color: pink;
}
react-tinacms-inline
package documentationLast Edited: November 27, 2020