feat: ui overhaul (#676)

This commit is contained in:
Daniel Lautzenheiser
2023-03-30 13:29:09 -04:00
committed by GitHub
parent 5c86462859
commit 66b81e9228
385 changed files with 20607 additions and 16493 deletions

View File

@ -12,8 +12,6 @@ The `registerPreviewTemplate` requires you to provide a React component. If you
However, although possible, it may be cumbersome or even impractical to add a React build phase. For this reason, Static CMS exposes some constructs globally to allow you to create components inline: `h` (alias for React.createElement) as well some basic hooks (`useState`, `useMemo`, `useEffect`, `useCallback`).
**NOTE**: `createClass` is still provided, allowing for the creation of react class components. However it has now been deprecated and will be removed in `v2.0.0`.
## Params
`registerAdditionalLink` takes an `AdditionalLink` object with the following properties:

View File

@ -2,10 +2,9 @@
group: Media
title: Cloudinary
weight: 10
beta: true
---
## <img src="https://img.shields.io/badge/-Beta%20Feature-blue" alt="Beta Feature. Use at your own risk" title="Beta Feature. Use at your own risk" />
Cloudinary is a digital asset management platform with a broad feature set, including support for responsive image generation and url based image transformation. They also provide a powerful media library UI for managing assets, and tools for organizing your assets into a hierarchy.
The Cloudinary media library integration for Static CMS uses Cloudinary's own media library interface within Static CMS. To get started, you'll need a Cloudinary account and Static CMS 2.3.0 or greater.

View File

@ -186,7 +186,7 @@ collections: [
</CodeTabs>
### Folder Collections Path <img src="https://img.shields.io/badge/-Beta%20Feature-blue" alt="Beta Feature. Use at your own risk" title="Beta Feature. Use at your own risk" />
### Folder Collections Path <BetaImage />
By default the CMS stores folder collection content under the folder specified in the collection setting.
@ -292,7 +292,7 @@ Supports all of the [`slug` templates](/docs/configuration-options#slug) and:
- `{{media_folder}}` The global `media_folder`.
- `{{public_folder}}` The global `public_folder`.
### Nested Collections <img src="https://img.shields.io/badge/-Beta%20Feature-blue" alt="Beta Feature. Use at your own risk" title="Beta Feature. Use at your own risk" />
### Nested Collections <BetaImage />
Nested collections is a beta feature that allows a folder collection to show a nested structure of entries and edit the locations of the entries. This feature is useful when you have a complex folder structure and may not want to create separate collections for every directory. As it is in beta, please use with discretion.

View File

@ -12,8 +12,6 @@ The `registerPreviewTemplate` and `registerPreviewCard` require you to provide a
However, although possible, it may be cumbersome or even impractical to add a React build phase. For this reason, Static CMS exposes some constructs globally to allow you to create components inline: `h` (alias for React.createElement) as well some basic hooks (`useState`, `useMemo`, `useEffect`, `useCallback`).
**NOTE**: `createClass` is still provided, allowing for the creation of react class components. However it has now been deprecated and will be removed in `v2.0.0`.
## Editor Preview
`registerPreviewTemplate` allows you to create a template that overrides the entire editor preview for a given collection.
@ -27,16 +25,16 @@ However, although possible, it may be cumbersome or even impractical to add a Re
The following parameters will be passed to your `react_component` during render:
| Param | Type | Description |
| ---------- | -------------- | ---------------------------------------------------------------------------------------------------- |
| entry | object | Object with a `data` field that contains the current value of all widgets in the editor |
| collection | object | Collection configuration |
| fields | object | The fields for the given collection |
| document | Document | The document object the preview is within. If rendered with a frame, it will be the frame's document |
| window | Window | The window object the preview is within. If rendered with a frame, it will be the frame's window |
| getAsset | Async function | __Deprecated__ Function that given a url returns (as a promise) a loaded asset |
| widgetFor | Function | Given a field name, returns the rendered preview of that field's widget and value |
| widgetsFor | Function | Given a field name, returns the rendered previews of that field's nested child widgets and values |
| Param | Type | Description |
| ---------- | ---------------------- | ---------------------------------------------------------------------------------------------------- |
| entry | object | Object with a `data` field that contains the current value of all widgets in the editor |
| collection | object | Collection configuration |
| fields | object | The fields for the given collection |
| document | Document | The document object the preview is within. If rendered with a frame, it will be the frame's document |
| window | Window | The window object the preview is within. If rendered with a frame, it will be the frame's window |
| widgetFor | Function | Given a field name, returns the rendered preview of that field's widget and value |
| widgetsFor | Function | Given a field name, returns the rendered previews of that field's nested child widgets and values |
| theme | 'light'<br />\| 'dark' | The current theme being used by the app |
#### `registerPreviewTemplate` Example
@ -44,7 +42,10 @@ The following parameters will be passed to your `react_component` during render:
```js
const PostPreview = ({ widgetFor, entry, collection, fields }) => {
const imageField = useMemo(fields.find((field) => field.name === 'image'), [fields]);
const imageField = useMemo(
fields.find(field => field.name === 'image'),
[fields],
);
const imageUrl = useMediaAsset(entry.data.image, collection, imageField, entry);
return h(
@ -63,7 +64,10 @@ CMS.registerPreviewTemplate('posts', PostPreview);
import CMS, { useMediaAsset } from '@staticcms/core';
const PostPreview = ({ widgetFor, entry, collection, fields }) => {
const imageField = useMemo(fields.find((field) => field.name === 'image'), [fields]);
const imageField = useMemo(
fields.find(field => field.name === 'image'),
[fields],
);
const imageUrl = useMediaAsset(entry.data.image, collection, imageField, entry);
return (
@ -92,13 +96,11 @@ interface Post {
body: string;
}
const PostPreview = ({
widgetFor,
entry,
collection,
fields,
}: TemplatePreviewProps<Post>) => {
const imageField = useMemo(fields.find((field) => field.name === 'image'), [fields]);
const PostPreview = ({ widgetFor, entry, collection, fields }: TemplatePreviewProps<Post>) => {
const imageField = useMemo(
fields.find(field => field.name === 'image'),
[fields],
);
const imageUrl = useMediaAsset(entry.data.image, collection, imageField, entry);
return (
@ -337,12 +339,13 @@ CMS.registerPreviewTemplate('general', GeneralPreview);
The following parameters will be passed to your `react_component` during render:
| Param | Type | Description |
| ---------- | --------------------- | ------------------------------------------------------------------------------------------------- |
| viewStyle | 'list'<br />\| 'grid' | The current view style being displayed |
| entry | object | Object with a `data` field that contains the current value of all widgets in the editor |
| widgetFor | Function | Given a field name, returns the rendered preview of that field's widget and value |
| widgetsFor | Function | Given a field name, returns the rendered previews of that field's nested child widgets and values |
| Param | Type | Description |
| ---------- | ---------------------- | ------------------------------------------------------------------------------------------------- |
| viewStyle | 'list'<br />\| 'grid' | The current view style being displayed |
| entry | object | Object with a `data` field that contains the current value of all widgets in the editor |
| widgetFor | Function | Given a field name, returns the rendered preview of that field's widget and value |
| widgetsFor | Function | Given a field name, returns the rendered previews of that field's nested child widgets and values |
| theme | 'light'<br />\| 'dark' | The current theme being used by the app |
#### `registerPreviewTemplate` Example
@ -518,10 +521,122 @@ CMS.registerPreviewTemplate('posts', PostPreview);
</CodeTabs>
##### List View
##### Table View
![Post Preview Card List View](/img/preview_card_list.png)
![Post Preview Card Table View](/img/preview_card_list.png)
##### Grid View
![Post Preview Card List View](/img/preview_card_grid.png)
![Post Preview Card Grid View](/img/preview_card_grid.png)
## Field Preview
`registerFieldPreview` allows you to create a custom preview for a specific field in the table view for collections.
### `registerFieldPreview` Params
| Param | Type | Description |
| -------------- | ------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| collectionName | string | The name of the collection (or file for file collections) which this preview component will be used for<br /><ul><li>Folder collections: Use the name of the collection</li><li>File collections: Use the name of the file</li></ul> |
| fieldName | string | The name of the field |
| component | [React Function Component](https://reactjs.org/docs/components-and-props.html) | A React functional component that renders a preview of the field for a given entry in your collection |
The following parameters will be passed to your `component` during render:
| Param | Type | Description |
| ---------- | ---------------------- | -------------------------------------------------- |
| collection | object | Collection configuration |
| field | object | Field configuration |
| value | Function | The current value of the field for the given entry |
| theme | 'light'<br />\| 'dark' | The current theme being used by the app |
#### `registerFieldPreview` Example
<CodeTabs>
```js
const PostDraftFieldPreview = ({ value }) => {
return h(
'div',
{
style: {
backgroundColor: value === true ? 'rgb(37 99 235)' : 'rgb(22 163 74)',
color: 'white',
border: 'none',
padding: '2px 6px',
textAlign: 'center',
textDecoration: 'none',
display: 'inline-block',
cursor: 'pointer',
borderRadius: '4px',
fontSize: '14px',
},
},
value === true ? 'Draft' : 'Published',
);
};
CMS.registerFieldPreview('posts', 'draft', PostDraftFieldPreview);
```
```jsx
import CMS from '@staticcms/core';
const PostDraftFieldPreview = ({ value }) => {
return h(
'div',
{
style: {
backgroundColor: value === true ? 'rgb(37 99 235)' : 'rgb(22 163 74)',
color: 'white',
border: 'none',
padding: '2px 6px',
textAlign: 'center',
textDecoration: 'none',
display: 'inline-block',
cursor: 'pointer',
borderRadius: '4px',
fontSize: '14px',
},
},
value === true ? 'Draft' : 'Published',
);
};
CMS.registerFieldPreview('posts', 'draft', PostDraftFieldPreview);
```
```tsx
import CMS from '@staticcms/core';
import type { FieldPreviewProps } from '@staticcms/core';
const CMS = ({ value }: FieldPreviewProps<boolean>) => {
return h(
'div',
{
style: {
backgroundColor: value === true ? 'rgb(37 99 235)' : 'rgb(22 163 74)',
color: 'white',
border: 'none',
padding: '2px 6px',
textAlign: 'center',
textDecoration: 'none',
display: 'inline-block',
cursor: 'pointer',
borderRadius: '4px',
fontSize: '14px',
},
},
value === true ? 'Draft' : 'Published',
);
};
CMS.registerFieldPreview('posts', 'draft', PostDraftFieldPreview);
```
</CodeTabs>
##### Table View
![Post Draft Field Preview Table View](/img/preview_draft_field_table.png)

View File

@ -12,8 +12,6 @@ The `registerPreviewTemplate` requires you to provide a React component. If you
However, although possible, it may be cumbersome or even impractical to add a React build phase. For this reason, Static CMS exposes some constructs globally to allow you to create components inline: `h` (alias for React.createElement) as well some basic hooks (`useState`, `useMemo`, `useEffect`, `useCallback`).
**NOTE**: `createClass` is still provided, allowing for the creation of react class components. However it has now been deprecated and will be removed in `v2.0.0`.
## Register Widget
Register a custom widget.
@ -53,14 +51,12 @@ The react component that renders the control. It receives the following props:
| path | string | `.` separated string donating the path to the current widget within the entry |
| hasErrors | boolean | Specifies if there are validation errors with the current widget |
| fieldsErrors | object | Key/value object of field names mapping to validation errors |
| isDisabled | boolean | Specifies if the widget control should be disabled |
| disabled | boolean | Specifies if the widget control should be disabled |
| submitted | boolean | Specifies if a save attempt has been made in the editor session |
| forList | boolean | Specifies if the widget is within a `list` widget |
| isDuplicate | function | Specifies if that field is an i18n duplicate |
| isFieldDuplicate | function | **Deprecated** Function that given a field configuration, returns if that field is a duplicate |
| isHidden | function | Specifies if that field should be hidden |
| isFieldHidden | function | **Deprecated** Function that given a field configuration, returns if that field is hidden |
| getAsset | Async function | **Deprecated** Function that given a url returns (as a promise) a loaded asset |
| forSingleList | boolean | Specifies if the widget is within a singleton `list` widget (string array, number array, etc) |
| duplicate | function | Specifies if that field is an i18n duplicate |
| hidden | function | Specifies if that field should be hidden |
| locale | string<br />\| undefined | The current locale of the editor |
| mediaPaths | object | Key/value object of control IDs (passed to the media library) mapping to media paths |
| clearMediaControl | function | Clears a control ID's value from the internal store |
@ -70,6 +66,7 @@ The react component that renders the control. It receives the following props:
| query | function | Runs a search on another collection. See [Query](#query) |
| i18n | object | The current i18n settings |
| t | function | Translates a given key to the current locale |
| theme | 'light'<br />\| 'dark' | The current theme being used by the app |
#### Open Media Library
@ -102,14 +99,14 @@ The react component that renders the control. It receives the following props:
The react component that renders the preview. It receives the following props:
| Param | Type | Description |
| ---------- | --------------------- | --------------------------------------------------------------------------------------------------------- |
| value | An valid widget value | The current value of the widget |
| field | object | The field configuration for the current widget. See [Widget Options](/docs/widgets#common-widget-options) |
| collection | object | The collection configuration for the current widget. See [Collections](/docs/collection-overview) |
| config | object | The current Static CMS config. See [configuration options](/docs/configuration-options) |
| entry | object | Object with a `data` field that contains the current value of all widgets in the editor |
| getAsset | Async function | **Deprecated** Function that given a url returns (as a promise) a loaded asset |
| Param | Type | Description |
| ---------- | ---------------------- | --------------------------------------------------------------------------------------------------------- |
| value | An valid widget value | The current value of the widget |
| field | object | The field configuration for the current widget. See [Widget Options](/docs/widgets#common-widget-options) |
| collection | object | The collection configuration for the current widget. See [Collections](/docs/collection-overview) |
| config | object | The current Static CMS config. See [configuration options](/docs/configuration-options) |
| entry | object | Object with a `data` field that contains the current value of all widgets in the editor |
| theme | 'light'<br />\| 'dark' | The current theme being used by the app |
### Options

View File

@ -2,10 +2,9 @@
group: Media
title: Netlify Large Media
weight: 20
beta: true
---
## <img src="https://img.shields.io/badge/-Beta%20Feature-blue" alt="Beta Feature. Use at your own risk" title="Beta Feature. Use at your own risk" />
[Netlify Large Media](https://www.netlify.com/features/large-media/) is a [Git LFS](https://git-lfs.github.com/) implementation for repositories connected to Netlify sites. This means that you can use Git to work with large asset files like images, audio, and video, without bloating your repository. It does this by replacing the asset files in your repository with text pointer files, then uploading the assets to the Netlify Large Media storage service.
If you have a Netlify site with Large Media enabled, Static CMS will handle Large Media asset files seamlessly, in the same way as files stored directly in the repository.

View File

@ -2,10 +2,9 @@
group: Media
title: Uploadcare
weight: 30
beta: true
---
## <img src="https://img.shields.io/badge/-Beta%20Feature-blue" alt="Beta Feature. Use at your own risk" title="Beta Feature. Use at your own risk" />
Uploadcare is a sleek service that allows you to upload files without worrying about maintaining a growing collection — more of an asset store than a library. Just upload when you need to, and the files are hosted on their CDN. They provide image processing controls from simple cropping and rotation to filters and face detection, and a lot more. You can check out Uploadcare's full feature set on their [website](https://uploadcare.com/).
The Uploadcare media library integration for Static CMS allows you to use Uploadcare as your media handler within the CMS itself. It's available by default as of our 2.1.0 release, and works in tandem with the existing file and image widgets, so using it only requires creating an Uploadcare account and updating your Static CMS configuration.

View File

@ -14,19 +14,19 @@ The list widget allows you to create a repeatable item in the UI which saves as
For common options, see [Common widget options](/docs/widgets#common-widget-options).
| Name | Type | Default | Description |
| -------------- | ---------------------- | ------------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| default | string | `[ <default from the child fields> ]` | _Optional_. The default values for fields. Also accepts an array of items |
| allow_add | boolean | `true` | _Optional_. `false` - Hides the button to add additional items |
| collapsed | boolean | `true` | _Optional_. `true` - The entries collapse by default |
| summary | string | | _Optional_. The label displayed on collapsed entries |
| label_singular | string | `label` | _Optional_. The text to show on the add button |
| fields | list of widgets | [] | _Optional_. A nested list of multiple widget fields to be included in each repeatable iteration |
| min | number | | _Optional_. Minimum number of items in the list |
| max | number | | _Optional_. Maximum number of items in the list |
| add_to_top | boolean | `false` | _Optional_. <ul><li>`true` - New entries will be added to the top of the list</li><li>`false` - New entries will be added to the bottom of the list</li></ul> |
| types | list of object widgets | | _Optional_. A nested list of object widgets representing the available types for items in the list. Takes priority over `fields`. |
| type_key | string | `'type'` | _Optional_. The name of the individual field that will be added to every item in list representing the name of the object widget that item belongs to. Ignored if `types` is not defined |
| Name | Type | Default | Description |
| -------------- | ---------------------- | ------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| default | string | `[ <default from the child fields> ]` | _Optional_. The default values for fields. Also accepts an array of items |
| allow_add | boolean | `true` | _Optional_. `false` - Hides the button to add additional items |
| collapsed | boolean | `true` | _Optional_. `true` - The list and entries collapse by default. |
| summary | string | | _Optional_. The label displayed on collapsed entries. _Ignored for single field lists._ |
| label_singular | string | `label` | _Optional_. The text to show on the add button |
| fields | list of widgets | [] | _Optional_. A nested list of multiple widget fields to be included in each repeatable iteration |
| min | number | | _Optional_. Minimum number of items in the list |
| max | number | | _Optional_. Maximum number of items in the list |
| add_to_top | boolean | `false` | _Optional_. <ul><li>`true` - New entries will be added to the top of the list</li><li>`false` - New entries will be added to the bottom of the list</li></ul> |
| types | list of object widgets | | _Optional_. A nested list of object widgets representing the available types for items in the list. Takes priority over `fields`. |
| type_key | string | `'type'` | _Optional_. The name of the individual field that will be added to every item in list representing the name of the object widget that item belongs to. Ignored if `types` is not defined |
## Examples

View File

@ -14,13 +14,13 @@ The number widget uses an HTML number input, saving the value as a string, integ
For common options, see [Common widget options](/docs/widgets#common-widget-options).
| Name | Type | Default | Description |
| ---------- | ------------------------------------ | ---------- | ----------------------------------------------------------------------------------- |
| default | string<br />\| number | `''` | _Optional_. The default value for the field. Accepts a string or number |
| value_type | 'int'<br />\| 'float'<br />\| string | `'string'` | _Optional_. Accepts `int` or `float`; any other value results in saving as a string |
| min | number | | _Optional_. Minimum value accepted |
| max | number | | _Optional_. Maximum value accepted |
| step | number | `1` | _Optional_. Size of steps when stepping up or down in input |
| Name | Type | Default | Description |
| ---------- | -------------------------------------- | ---------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| default | string<br />\| number | `''` | _Optional_. The default value for the field. Accepts a string or number |
| value_type | 'int'<br />\| 'float'<br />\| 'string' | `'string'` | _Optional_. Accepts `int` or `float`; any other value results in saving as a string |
| min | number | | _Optional_. Minimum value accepted. If a pattern is provided (see [Common widget options](/docs/widgets#common-widget-options)), min is ignored during validation, but is still applied to the input |
| max | number | | _Optional_. Maximum value accepted. If a pattern is provided (see [Common widget options](/docs/widgets#common-widget-options)), max is ignored during validation, but is still applied to the input |
| step | number | `1` | _Optional_. Size of steps when stepping up or down in input |
## Example

View File

@ -42,8 +42,8 @@ The following options are available on all fields:
| label | string | `name` | _Optional_. The display name of the field |
| required | boolean | `true` | _Optional_. Specify as `false` to make a field optional |
| hint | string | | _Optional_. Adds helper text directly below a widget. Useful for including instructions. Accepts markdown for bold, italic, strikethrough, and links. |
| pattern | string | | _Optional_. Adds field validation by specifying a list with a [regex pattern](https://regexr.com/) and an error message; more extensive validation can be achieved with [custom widgets](/docs/custom-widgets/#advanced-field-validation) |
| i18n | boolean<br />\|'translate'<br />\|'duplicate'<br />\|'none' | | _Optional_. <img src="https://img.shields.io/badge/-Beta%20Feature-blue" alt="Beta Feature. Use at your own risk" title="Beta Feature. Use at your own risk" /><ul><li>`translate` - Allows translation of the field</li><li>`duplicate` - Duplicates the value from the default locale</li><li>`true` - Accept parent values as default</li><li>`none` or `false` - Exclude field from translations</li></ul> |
| pattern | list of strings | | _Optional_. Adds field validation by specifying a list with a [regex pattern](https://regexr.com/) and an error message; more extensive validation can be achieved with [custom widgets](/docs/custom-widgets/#advanced-field-validation) |
| i18n | boolean<br />\|'translate'<br />\|'duplicate'<br />\|'none' | | _Optional_. <BetaImage /><ul><li>`translate` - Allows translation of the field</li><li>`duplicate` - Duplicates the value from the default locale</li><li>`true` - Accept parent values as default</li><li>`none` or `false` - Exclude field from translations</li></ul> |
| comment | string | | _Optional_. Adds comment before the field (only supported for yaml) |
### Example