Skip to content

Commit

Permalink
feat: add descriptions to every allowed field type, globals and colle…
Browse files Browse the repository at this point in the history
…ctions
  • Loading branch information
DanRibbens committed Jul 27, 2021
1 parent 4544711 commit 29a1108
Show file tree
Hide file tree
Showing 42 changed files with 242 additions and 85 deletions.
9 changes: 9 additions & 0 deletions demo/collections/AllFields.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,9 @@ const AllFields: PayloadCollectionConfig = {
type: 'upload',
label: 'Image',
relationTo: 'media',
admin: {
description: 'No selfies',
},
},
{
name: 'select',
Expand Down Expand Up @@ -246,6 +249,9 @@ const AllFields: PayloadCollectionConfig = {
label: 'Relationship to One Collection',
name: 'relationship',
relationTo: 'conditions',
admin: {
description: 'Relates to description',
},
},
{
type: 'relationship',
Expand All @@ -264,6 +270,9 @@ const AllFields: PayloadCollectionConfig = {
type: 'textarea',
label: 'Textarea',
name: 'textarea',
admin: {
description: 'Hello textarea description',
},
},
{
name: 'richText',
Expand Down
1 change: 1 addition & 0 deletions demo/collections/Code.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ const Code: PayloadCollectionConfig = {
required: true,
admin: {
language: 'js',
description: 'javascript example',
},
},
],
Expand Down
12 changes: 0 additions & 12 deletions demo/collections/CustomComponents/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import GroupField from './components/fields/Group/Field';
import NestedGroupField from './components/fields/NestedGroupCustomField/Field';
import NestedText1Field from './components/fields/NestedText1/Field';
import ListView from './components/views/List';
import CustomDescriptionComponent from '../../customComponents/Description';

const CustomComponents: PayloadCollectionConfig = {
slug: 'custom-components',
Expand Down Expand Up @@ -39,17 +38,6 @@ const CustomComponents: PayloadCollectionConfig = {
},
},
},
{
name: 'descriptionComponent',
type: 'text',
label: 'Text with description component',
defaultValue: 'Default Value',
admin: {
components: {
Description: CustomDescriptionComponent,
},
},
},
{
name: 'array',
label: 'Array',
Expand Down
1 change: 1 addition & 0 deletions demo/collections/Media.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ const Media: PayloadCollectionConfig = {
},
admin: {
enableRichTextRelationship: true,
description: 'No selfies please',
},
upload: {
staticURL: '/media',
Expand Down
11 changes: 0 additions & 11 deletions demo/customComponents/Description/index.tsx

This file was deleted.

1 change: 1 addition & 0 deletions docs/configuration/collections.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ It's often best practice to write your Collections in separate files and then im
| **`slug`** * | Unique, URL-friendly string that will act as an identifier for this Collection. |
| **`fields`** * | Array of field types that will determine the structure and functionality of the data stored within this Collection. [Click here](/docs/fields/overview) for a full list of field types as well as how to configure them. |
| **`labels`** | Singular and plural labels for use in identifying this Collection throughout Payload. Auto-generated from slug if not defined. |
| **`description`**| Text that displays below the Collection label in the List view to give editors more information. |
| **`admin`** | Admin-specific configuration. See below for [more detail](#admin-options). |
| **`hooks`** | Entry points to "tie in" to Collection actions at specific points. [More](/docs/hooks/overview#collection-hooks) |
| **`access`** | Provide access control functions to define exactly who should be able to do what with Documents in this Collection. [More](/docs/access-control/overview/#collections) |
Expand Down
1 change: 1 addition & 0 deletions docs/configuration/globals.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ As with Collection configs, it's often best practice to write your Globals in se
| **`slug`** * | Unique, URL-friendly string that will act as an identifier for this Global. |
| **`fields`** * | Array of field types that will determine the structure and functionality of the data stored within this Global. [Click here](/docs/fields/overview) for a full list of field types as well as how to configure them. |
| **`label`** | Singular label for use in identifying this Global throughout Payload. Auto-generated from slug if not defined. |
| **`description`**| Text that displays below the Collection label in the List view to give editors more information. |
| **`admin`** | Admin-specific configuration. See below for [more detail](/docs/configuration/globals#admin-options). |
| **`hooks`** | Entry points to "tie in" to collection actions at specific points. [More](/docs/hooks/overview#global-hooks) |
| **`access`** | Provide access control functions to define exactly who should be able to do what with this Global. [More](/docs/access-control/overview/#globals) |
Expand Down
25 changes: 25 additions & 0 deletions docs/fields/overview.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@ In addition to each field's base configuration, you can define specific traits a
| ------------- | -------------|
| `condition` | You can programmatically show / hide fields based on what other fields are doing. [Click here](#conditional-logic) for more info. |
| `components` | All field components can be completely and easily swapped out for custom components that you define. [Click here](#custom-admin-components) for more info. |
| `description` | Text to display with the field to provide more information for the editor user using a string or function returning a string. [Click here](#description) for more info. |
| `position` | Specify if the field should be rendered in the sidebar by defining `position: 'sidebar'`. |
| `width` | Restrict the width of a field. you can pass any string-based value here, be it pixels, percentages, etc. This property is especially useful when fields are nested within a `Row` type where they can be organized horizontally. |
| `readOnly` | Setting a field to `readOnly` has no effect on the API whatsoever but disables the admin component's editability to prevent editors from modifying the field's value. |
Expand Down Expand Up @@ -138,3 +139,27 @@ The `condition` function should return a boolean that will control if the field
### Custom components

All Payload fields support the ability to swap in your own React components with ease. For more information, including examples, [click here](/docs/admin/components#fields).

### Description

You can simply provide a string that will show by the field, but there are use cases where you may want to create some dynamic feedback. By using a function for the `description` property you can provide rich feedback in realtime the user interacts with the form.

The `description` can be assigned a function can wth the parameter `{ value }` and can return the `string` you wish to display.

**Example:**

```js
{
fields: [
{
name: 'message',
type: 'text',
maxLength: 20,
admin: {
description: ({ value }) => (`${20 - value.length} characters left`)
}
}
]
}
```
This example will display the number of characters allowed as the user types.
2 changes: 1 addition & 1 deletion docs/fields/row.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ keywords: row, fields, config, configuration, documentation, Content Management
| Option | Description |
| ---------------- | ----------- |
| **`fields`** * | Array of field types to nest within this Row. |
| **`admin`** | Admin-specific configuration. See the [default field admin config](/docs/fields/overview#admin-config) for more details. |
| **`admin`** | Admin-specific configuration excluding `description`, `readOnly`, and `hidden`. See the [default field admin config](/docs/fields/overview#admin-config) for more details. |

*\* An asterisk denotes that a property is required.*

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,23 +2,12 @@ import React from 'react';
import { Props } from './types';
import './index.scss';

const RenderFieldDescription: React.FC<Props> = (props) => {
const FieldDescription: React.FC<Props> = (props) => {
const {
description,
value,
CustomComponent,
} = props;

if (CustomComponent) {
return (
<div
className="field-description"
>
<CustomComponent value />
</div>
);
}

if (description) {
return (
<div
Expand All @@ -32,4 +21,4 @@ const RenderFieldDescription: React.FC<Props> = (props) => {
return null;
};

export default RenderFieldDescription;
export default FieldDescription;
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
export type Props = {
description?: string | ((value) => string);
CustomComponent?: React.ComponentType<{ value: unknown }>;
value: unknown;
}
8 changes: 8 additions & 0 deletions src/admin/components/forms/field-types/Array/Array.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import useFieldType from '../../useFieldType';
import Error from '../../Error';
import { array } from '../../../../../fields/validations';
import Banner from '../../../elements/Banner';
import FieldDescription from '../../FieldDescription';
import { Props, RenderArrayProps } from './types';

import './index.scss';
Expand All @@ -31,6 +32,7 @@ const ArrayFieldType: React.FC<Props> = (props) => {
admin: {
readOnly,
condition,
description,
},
} = props;

Expand Down Expand Up @@ -132,6 +134,7 @@ const ArrayFieldType: React.FC<Props> = (props) => {
minRows={minRows}
maxRows={maxRows}
required={required}
description={description}
/>
);
};
Expand All @@ -156,6 +159,7 @@ const RenderArray = React.memo((props: RenderArrayProps) => {
minRows,
maxRows,
required,
description,
} = props;

const hasMaxRows = maxRows && rows.length >= maxRows;
Expand All @@ -173,6 +177,10 @@ const RenderArray = React.memo((props: RenderArrayProps) => {
</div>
<header className={`${baseClass}__header`}>
<h3>{label}</h3>
<FieldDescription
value={value || []}
description={description}
/>
</header>
<Droppable droppableId="array-drop">
{(provided) => (
Expand Down
8 changes: 8 additions & 0 deletions src/admin/components/forms/field-types/Array/index.scss
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,14 @@
margin: base(2) 0;
min-width: base(15);

&__header {
h3 {
margin-bottom: 0;
}

margin-bottom: base(1);
}

&__error-wrap {
position: relative;
}
Expand Down
3 changes: 2 additions & 1 deletion src/admin/components/forms/field-types/Array/types.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Data } from '../../Form/types';
import { ArrayField, Labels, Field } from '../../../../../fields/config/types';
import { ArrayField, Labels, Field, Description } from '../../../../../fields/config/types';
import { FieldTypes } from '..';
import { FieldPermissions } from '../../../../../auth/types';

Expand Down Expand Up @@ -30,4 +30,5 @@ export type RenderArrayProps = {
showError: boolean
errorMessage: string
rows: Data[]
description?: Description
}
8 changes: 8 additions & 0 deletions src/admin/components/forms/field-types/Blocks/Blocks.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import Popup from '../../../elements/Popup';
import BlockSelector from './BlockSelector';
import { blocks as blocksValidator } from '../../../../../fields/validations';
import Banner from '../../../elements/Banner';
import FieldDescription from '../../FieldDescription';
import { Props, RenderBlockProps } from './types';
import { DocumentPreferences } from '../../../../../preferences/types';

Expand Down Expand Up @@ -45,6 +46,7 @@ const Blocks: React.FC<Props> = (props) => {
admin: {
readOnly,
condition,
description,
},
} = props;

Expand Down Expand Up @@ -181,6 +183,7 @@ const Blocks: React.FC<Props> = (props) => {
minRows={minRows}
maxRows={maxRows}
required={required}
description={description}
/>
);
};
Expand All @@ -206,6 +209,7 @@ const RenderBlocks = React.memo((props: RenderBlockProps) => {
minRows,
maxRows,
required,
description,
} = props;

const hasMaxRows = maxRows && rows.length >= maxRows;
Expand All @@ -223,6 +227,10 @@ const RenderBlocks = React.memo((props: RenderBlockProps) => {
</div>
<header className={`${baseClass}__header`}>
<h3>{label}</h3>
<FieldDescription
value={value || []}
description={description}
/>
</header>

<Droppable
Expand Down
8 changes: 8 additions & 0 deletions src/admin/components/forms/field-types/Blocks/index.scss
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,14 @@
margin: base(2) 0;
min-width: base(15);

&__header {
h3 {
margin-bottom: 0;
}

margin-bottom: base(1);
}

&__error-wrap {
position: relative;
}
Expand Down
5 changes: 3 additions & 2 deletions src/admin/components/forms/field-types/Blocks/types.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Data } from '../../Form/types';
import { BlockField, Labels, Block } from '../../../../../fields/config/types';
import { BlockField, Labels, Block, Description } from '../../../../../fields/config/types';
import { FieldTypes } from '..';
import { FieldPermissions } from '../../../../../auth/types';

Expand Down Expand Up @@ -28,6 +28,7 @@ export type RenderBlockProps = {
showError: boolean
errorMessage: string
rows: Data[]
blocks: Block[],
blocks: Block[]
setCollapse: (id: string, collapsed: boolean) => void
description?: Description
}
6 changes: 6 additions & 0 deletions src/admin/components/forms/field-types/Checkbox/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import withCondition from '../../withCondition';
import Error from '../../Error';
import { checkbox } from '../../../../../fields/validations';
import Check from '../../../icons/Check';
import FieldDescription from '../../FieldDescription';
import { Props } from './types';

import './index.scss';
Expand All @@ -24,6 +25,7 @@ const Checkbox: React.FC<Props> = (props) => {
style,
width,
condition,
description,
} = {},
} = props;

Expand Down Expand Up @@ -87,6 +89,10 @@ const Checkbox: React.FC<Props> = (props) => {
{label}
</span>
</button>
<FieldDescription
value={value}
description={description}
/>
</div>
);
};
Expand Down
6 changes: 6 additions & 0 deletions src/admin/components/forms/field-types/Code/Code.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import useFieldType from '../../useFieldType';
import withCondition from '../../withCondition';
import Label from '../../Label';
import Error from '../../Error';
import FieldDescription from '../../FieldDescription';
import { code } from '../../../../../fields/validations';
import { Props } from './types';

Expand All @@ -24,6 +25,7 @@ const Code: React.FC<Props> = (props) => {
width,
language,
condition,
description,
} = {},
label,
minLength,
Expand Down Expand Up @@ -94,6 +96,10 @@ const Code: React.FC<Props> = (props) => {
pointerEvents: readOnly ? 'none' : 'auto',
}}
/>
<FieldDescription
value={value || ''}
description={description}
/>
</div>
);
};
Expand Down
Loading

0 comments on commit 29a1108

Please sign in to comment.