Editable
A component that allows users to edit text in place.
Usage
Double click to edit
'use client'
import { Button, Editable, FormLabel } from '~/components/ui'
export const Demo = (props: Editable.RootProps) => {
return (
<Editable.Root
placeholder="Your favorite Framework"
defaultValue="Double click to edit"
activationMode="dblclick"
{...props}
>
<Editable.Label asChild>
<FormLabel>Framework</FormLabel>
</Editable.Label>
<Editable.Area>
<Editable.Input />
<Editable.Preview />
</Editable.Area>
<Editable.Context>
{(editable) => (
<Editable.Control>
{editable.editing ? (
<>
<Editable.SubmitTrigger asChild>
<Button variant="link">Save</Button>
</Editable.SubmitTrigger>
<Editable.CancelTrigger asChild>
<Button variant="link">Cancel</Button>
</Editable.CancelTrigger>
</>
) : (
<Editable.EditTrigger asChild>
<Button variant="link">Edit</Button>
</Editable.EditTrigger>
)}
</Editable.Control>
)}
</Editable.Context>
</Editable.Root>
)
}
Installation
npx @park-ui/cli components add editable
1
Styled Primitive
Copy the code snippet below into ~/components/ui/primitives/editable.tsx
'use client'
import type { Assign } from '@ark-ui/react'
import { Editable } from '@ark-ui/react/editable'
import { type EditableVariantProps, editable } from 'styled-system/recipes'
import type { ComponentProps, HTMLStyledProps } from 'styled-system/types'
import { createStyleContext } from '~/lib/create-style-context'
const { withProvider, withContext } = createStyleContext(editable)
export type RootProviderProps = ComponentProps<typeof RootProvider>
export const RootProvider = withProvider<
HTMLDivElement,
Assign<Assign<HTMLStyledProps<'div'>, Editable.RootProviderBaseProps>, EditableVariantProps>
>(Editable.RootProvider, 'root')
export type RootProps = ComponentProps<typeof Root>
export const Root = withProvider<
HTMLDivElement,
Assign<Assign<HTMLStyledProps<'div'>, Editable.RootBaseProps>, EditableVariantProps>
>(Editable.Root, 'root')
export const Area = withContext<
HTMLDivElement,
Assign<HTMLStyledProps<'div'>, Editable.AreaBaseProps>
>(Editable.Area, 'area')
export const CancelTrigger = withContext<
HTMLButtonElement,
Assign<HTMLStyledProps<'button'>, Editable.CancelTriggerBaseProps>
>(Editable.CancelTrigger, 'cancelTrigger')
export const Control = withContext<
HTMLDivElement,
Assign<HTMLStyledProps<'div'>, Editable.ControlBaseProps>
>(Editable.Control, 'control')
export const EditTrigger = withContext<
HTMLButtonElement,
Assign<HTMLStyledProps<'button'>, Editable.EditTriggerBaseProps>
>(Editable.EditTrigger, 'editTrigger')
export const Input = withContext<
HTMLInputElement,
Assign<HTMLStyledProps<'input'>, Editable.InputBaseProps>
>(Editable.Input, 'input')
export const Label = withContext<
HTMLLabelElement,
Assign<HTMLStyledProps<'label'>, Editable.LabelBaseProps>
>(Editable.Label, 'label')
export const Preview = withContext<
HTMLSpanElement,
Assign<HTMLStyledProps<'span'>, Editable.PreviewBaseProps>
>(Editable.Preview, 'preview')
export const SubmitTrigger = withContext<
HTMLButtonElement,
Assign<HTMLStyledProps<'button'>, Editable.SubmitTriggerBaseProps>
>(Editable.SubmitTrigger, 'submitTrigger')
export { EditableContext as Context } from '@ark-ui/react/editable'
import { type Assign, Editable } from '@ark-ui/solid'
import type { ComponentProps } from 'solid-js'
import { type EditableVariantProps, editable } from 'styled-system/recipes'
import type { HTMLStyledProps } from 'styled-system/types'
import { createStyleContext } from '~/lib/create-style-context'
const { withProvider, withContext } = createStyleContext(editable)
export type RootProviderProps = ComponentProps<typeof RootProvider>
export const RootProvider = withProvider<
Assign<Assign<HTMLStyledProps<'div'>, Editable.RootProviderBaseProps>, EditableVariantProps>
>(Editable.RootProvider, 'root')
export type RootProps = ComponentProps<typeof Root>
export const Root = withProvider<
Assign<Assign<HTMLStyledProps<'div'>, Editable.RootBaseProps>, EditableVariantProps>
>(Editable.Root, 'root')
export const Area = withContext<Assign<HTMLStyledProps<'div'>, Editable.AreaBaseProps>>(
Editable.Area,
'area',
)
export const CancelTrigger = withContext<
Assign<HTMLStyledProps<'button'>, Editable.CancelTriggerBaseProps>
>(Editable.CancelTrigger, 'cancelTrigger')
export const Control = withContext<Assign<HTMLStyledProps<'div'>, Editable.ControlBaseProps>>(
Editable.Control,
'control',
)
export const EditTrigger = withContext<
Assign<HTMLStyledProps<'button'>, Editable.EditTriggerBaseProps>
>(Editable.EditTrigger, 'editTrigger')
export const Input = withContext<Assign<HTMLStyledProps<'input'>, Editable.InputBaseProps>>(
Editable.Input,
'input',
)
export const Label = withContext<Assign<HTMLStyledProps<'label'>, Editable.LabelBaseProps>>(
Editable.Label,
'label',
)
export const Preview = withContext<Assign<HTMLStyledProps<'span'>, Editable.PreviewBaseProps>>(
Editable.Preview,
'preview',
)
export const SubmitTrigger = withContext<
Assign<HTMLStyledProps<'button'>, Editable.SubmitTriggerBaseProps>
>(Editable.SubmitTrigger, 'submitTrigger')
export { EditableContext as Context } from '@ark-ui/solid'
No snippet found
Extend ~/components/ui/primitives/index.ts
with the following line:
export * as Editable from './editable'
2
Integrate Recipe
If you're not using @park-ui/preset
, add the following recipe to yourpanda.config.ts
:
import { editableAnatomy } from '@ark-ui/anatomy'
import { defineSlotRecipe } from '@pandacss/dev'
export const editable = defineSlotRecipe({
className: 'editable',
slots: editableAnatomy.keys(),
base: {
root: {
display: 'flex',
flexDirection: 'column',
gap: '1.5',
width: '100%',
},
control: {
display: 'flex',
gap: '2',
},
},
})