Thank you for your interest in contributing to PayloadCMS Extra Fields! This document provides guidelines and instructions for contributing to this project.
- Fork the repository
- Clone your fork locally
- Install dependencies:
npm installorpnpm install - Create a new branch for your contribution:
git checkout -b feature/your-field-name
payload-extra-fields/
├── registry/
│ └── fields/
│ └── your-field/
│ ├── index.tsx # Field component
│ ├── field.ts # Utility function
│ ├── types.ts # TypeScript types
│ └── style.scss # Styles (if needed)
├── content/
│ └── docs/
│ └── fields/
│ └── your-field.mdx # Documentation
├── components/
│ └── examples/
│ └── your-field-demo.tsx # Demo component
└── registry.json # Registry configuration
To contribute a new custom field to the registry:
Create a new directory under registry/fields/ with your field name:
// registry/fields/your-field/types.ts
import { TextField } from 'payload'
export type YourFieldArgs = {
name?: string
required?: boolean
// Add your custom options here
overrides?: (field: TextField) => TextField
}
export type YourFieldProps = Pick<YourFieldArgs, 'customOption1' | 'customOption2'>// registry/fields/your-field/field.ts
import { TextField } from 'payload'
import { YourFieldArgs } from './types'
export const yourField = (options?: YourFieldArgs): TextField => {
const baseField: TextField = {
name: options?.name || 'yourFieldName',
type: 'text',
required: options?.required || false,
admin: {
components: {
Field: {
path: '@/fields/your-field',
clientProps: {
// Pass your custom options here
},
},
},
},
}
if (typeof options?.overrides === 'function') {
return options.overrides(baseField)
}
return baseField
}// registry/fields/your-field/index.tsx
'use client'
import { useField, FieldLabel } from '@payloadcms/ui'
import { YourFieldProps } from './types'
import './style.scss'
export default function YourField(props: YourFieldProps) {
const { value, setValue } = useField<string>({ path: props.path })
return (
<div className="your-field-wrapper">
<FieldLabel label={props.label} required={props.required} />
{/* Your field implementation */}
</div>
)
}Add your field to the registry.json file:
{
"items": [
{
"name": "your-field",
"type": "registry:item",
"title": "Your Field",
"description": "A brief description of your field.",
"files": [
{
"path": "registry/fields/your-field/field.ts",
"type": "registry:file",
"target": "~/src/fields/your-field/field.ts"
},
{
"path": "registry/fields/your-field/index.tsx",
"type": "registry:file",
"target": "~/src/fields/your-field/index.tsx"
},
{
"path": "registry/fields/your-field/types.ts",
"type": "registry:file",
"target": "~/src/fields/your-field/types.ts"
}
]
}
]
}Create a documentation file at content/docs/fields/your-field.mdx:
---
title: Your Field
description: A brief description of your field.
---
# Your Field
A detailed description of what your field does and why it's useful.
## Installation
<Tabs defaultValue="auto">
<TabsList className="grid w-full max-w-md grid-cols-2">
<TabsTrigger value="auto">Auto</TabsTrigger>
<TabsTrigger value="manual">Manual</TabsTrigger>
</TabsList>
<TabsContent value="auto">
```npm
npx shadcn@latest add https://payload.veiag.dev/r/your-field.jsonimport { yourField } from '@/fields/your-field/field'
export const MyCollection = {
slug: 'my-collection',
fields: [
yourField({
name: 'fieldName',
required: true,
}),
],
}Document your field's options and props here.
- List key features of your field
- Explain what makes it useful
### 4. Add to the Registry Index
Update `registry/__index__.tsx`:
```typescript
export const Index: Record<string, any> = {
"your-field": {
name: "your-field",
component: dynamic(() => import("@/components/examples/your-field-demo")),
source: `// Example usage code here`,
files: [
"/registry/fields/your-field/index.tsx",
"/registry/fields/your-field/field.ts",
"/registry/fields/your-field/types.ts",
]
},
}
Add your field to app/(home)/fields/page.tsx:
const components = [
{
name: "Your Field",
description: "Brief description",
href: "/docs/fields/your-field",
icon: YourIcon,
badge: "New",
},
]- Use TypeScript for all code
- Follow the existing code structure and naming conventions
- Use meaningful variable and function names
- Add comments for complex logic
- Ensure your code is properly formatted
Before submitting your contribution:
- Test the field in a PayloadCMS project
- Verify the installation process works
- Check that documentation is clear and accurate
- Ensure all files are properly formatted
- Commit your changes with clear, descriptive commit messages
- Push your branch to your fork
- Open a pull request against the
mainbranch - Provide a clear description of your changes
- Link any related issues
## Description
Brief description of the field and what it does
## Type of Change
- [ ] New field
- [ ] Bug fix
- [ ] Documentation update
- [ ] Other (please describe)
## Checklist
- [ ] Field implementation is complete
- [ ] Documentation is added/updated
- [ ] Registry files are updated
- [ ] Examples are provided
- [ ] Code follows project conventions
- [ ] Field has been tested in a PayloadCMS projectIf you have questions or need help, please open an issue on GitHub.
By contributing to this project, you agree that your contributions will be licensed under the MIT License.