From a8230d008fdd12b0852a46fdb2a8e22502a15098 Mon Sep 17 00:00:00 2001 From: Misha Kaletsky Date: Thu, 11 Jan 2024 12:54:58 -0500 Subject: [PATCH 1/4] feat: variable + optional object --- packages/decap-cms-app/src/extensions.js | 2 +- packages/decap-cms-widget-list/src/ListControl.js | 15 +++++++++++++++ packages/decap-cms-widget-list/src/index.js | 13 +++++++++++-- 3 files changed, 27 insertions(+), 3 deletions(-) diff --git a/packages/decap-cms-app/src/extensions.js b/packages/decap-cms-app/src/extensions.js index 92fc0bbcbcbc..6c3289a1f59d 100644 --- a/packages/decap-cms-app/src/extensions.js +++ b/packages/decap-cms-app/src/extensions.js @@ -48,7 +48,7 @@ CMS.registerWidget([ DecapCmsWidgetSelect.Widget(), DecapCmsWidgetMarkdown.Widget(), DecapCmsWidgetList.Widget(), - DecapCmsWidgetObject.Widget(), + DecapCmsWidgetList.OptionalObjectWidget(), DecapCmsWidgetRelation.Widget(), DecapCmsWidgetBoolean.Widget(), DecapCmsWidgetMap.Widget(), diff --git a/packages/decap-cms-widget-list/src/ListControl.js b/packages/decap-cms-widget-list/src/ListControl.js index 958975a311c0..3592c015f0f8 100644 --- a/packages/decap-cms-widget-list/src/ListControl.js +++ b/packages/decap-cms-widget-list/src/ListControl.js @@ -749,3 +749,18 @@ export default class ListControl extends React.Component { } } } + +export class OptionalObjectControl extends React.Component { + render() { + if (this.props.field.get('required') === false || this.props.field.get('types')) { + return ( + this.props.onChange(e.get(0))} + value={List([this.props.value].filter(Boolean))} + /> + ) + } + return + } +} diff --git a/packages/decap-cms-widget-list/src/index.js b/packages/decap-cms-widget-list/src/index.js index fbbe9624a403..02ee12ef90be 100644 --- a/packages/decap-cms-widget-list/src/index.js +++ b/packages/decap-cms-widget-list/src/index.js @@ -1,6 +1,6 @@ import DecapCmsWidgetObject from 'decap-cms-widget-object'; -import controlComponent from './ListControl'; +import controlComponent, {OptionalObjectControl} from './ListControl'; import schema from './schema'; const previewComponent = DecapCmsWidgetObject.previewComponent; @@ -15,5 +15,14 @@ function Widget(opts = {}) { }; } -export const DecapCmsWidgetList = { Widget, controlComponent, previewComponent }; +function OptionalObjectWidget(opts = {}) { + return { + name: 'object', + controlComponent: OptionalObjectControl, + previewComponent, + ...opts, + } +} + +export const DecapCmsWidgetList = { Widget, controlComponent, previewComponent, OptionalObjectWidget }; export default DecapCmsWidgetList; From c9e49979b33bcdf76d6a125a36299ffa9e1d1fcf Mon Sep 17 00:00:00 2001 From: Misha Kaletsky Date: Fri, 12 Jan 2024 11:28:51 -0500 Subject: [PATCH 2/4] docs: add object widget to variable types section --- website/content/docs/beta-features.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/website/content/docs/beta-features.md b/website/content/docs/beta-features.md index d5a68b527600..0f92237e66bf 100644 --- a/website/content/docs/beta-features.md +++ b/website/content/docs/beta-features.md @@ -312,9 +312,9 @@ Supports all of the [`slug` templates](/docs/configuration-options#slug) and: * `{{media_folder}}` The global `media_folder`. * `{{public_folder}}` The global `public_folder`. -## List Widget: Variable Types +## List/Object Widget: Variable Types -Before this feature, the [list widget](/docs/widgets/#list) allowed a set of fields to be repeated, but every list item had the same set of fields available. With variable types, multiple named sets of fields can be defined, which opens the door to highly flexible content authoring (even page building) in Decap CMS. +Before this feature, the [list widget](/docs/widgets/#list) and [object widget](/docs/widget/#object) allowed a set of fields to be repeated, but every item had the same set of fields available. With variable types, multiple named sets of fields can be defined, which opens the door to highly flexible content authoring (even page building) in Decap CMS. **Note: this feature does not yet support default previews and requires [registering a preview template](/docs/customization#registerpreviewtemplate) in order to show up in the preview pane.** From a3a1da7448d73f3805162f18bd284365b1fbafc2 Mon Sep 17 00:00:00 2001 From: Misha Kaletsky Date: Fri, 12 Jan 2024 11:29:11 -0500 Subject: [PATCH 3/4] test: add variable type object to kitchen sink collection --- dev-test/config.yml | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/dev-test/config.yml b/dev-test/config.yml index 66cef499d080..227e693c5078 100644 --- a/dev-test/config.yml +++ b/dev-test/config.yml @@ -268,6 +268,20 @@ collections: # A list of collections the CMS should be able to edit fields: - { label: 'Image', name: 'image', widget: 'image' } - { label: 'File', name: 'file', widget: 'file' } + - label: Typed Object + name: typed_object + widget: object + types: + - name: copy + widget: object + fields: + - { name: text, widget: string } + - name: infographic + widget: object + fields: + - { name: caption, widget: string } + - { name: image, widget: image } + - { name: overlay, widget: image } - name: pages # a nested collection label: Pages label_singular: 'Page' From bc2591303d3db4bef269bddbdbafa752734c0ef8 Mon Sep 17 00:00:00 2001 From: Misha Kaletsky Date: Fri, 12 Jan 2024 11:30:40 -0500 Subject: [PATCH 4/4] refactor: rm word "optional" --- packages/decap-cms-app/src/extensions.js | 3 +-- packages/decap-cms-widget-list/src/ListControl.js | 6 +++--- packages/decap-cms-widget-list/src/index.js | 10 +++++----- 3 files changed, 9 insertions(+), 10 deletions(-) diff --git a/packages/decap-cms-app/src/extensions.js b/packages/decap-cms-app/src/extensions.js index 6c3289a1f59d..0c51bd1619ce 100644 --- a/packages/decap-cms-app/src/extensions.js +++ b/packages/decap-cms-app/src/extensions.js @@ -18,7 +18,6 @@ import DecapCmsWidgetFile from 'decap-cms-widget-file'; import DecapCmsWidgetSelect from 'decap-cms-widget-select'; import DecapCmsWidgetMarkdown from 'decap-cms-widget-markdown'; import DecapCmsWidgetList from 'decap-cms-widget-list'; -import DecapCmsWidgetObject from 'decap-cms-widget-object'; import DecapCmsWidgetRelation from 'decap-cms-widget-relation'; import DecapCmsWidgetBoolean from 'decap-cms-widget-boolean'; import DecapCmsWidgetMap from 'decap-cms-widget-map'; @@ -48,7 +47,7 @@ CMS.registerWidget([ DecapCmsWidgetSelect.Widget(), DecapCmsWidgetMarkdown.Widget(), DecapCmsWidgetList.Widget(), - DecapCmsWidgetList.OptionalObjectWidget(), + DecapCmsWidgetList.ObjectWidget(), DecapCmsWidgetRelation.Widget(), DecapCmsWidgetBoolean.Widget(), DecapCmsWidgetMap.Widget(), diff --git a/packages/decap-cms-widget-list/src/ListControl.js b/packages/decap-cms-widget-list/src/ListControl.js index 3592c015f0f8..59119741311e 100644 --- a/packages/decap-cms-widget-list/src/ListControl.js +++ b/packages/decap-cms-widget-list/src/ListControl.js @@ -750,7 +750,7 @@ export default class ListControl extends React.Component { } } -export class OptionalObjectControl extends React.Component { +export class ObjectControlWrapper extends React.Component { render() { if (this.props.field.get('required') === false || this.props.field.get('types')) { return ( @@ -759,8 +759,8 @@ export class OptionalObjectControl extends React.Component { onChange={e => this.props.onChange(e.get(0))} value={List([this.props.value].filter(Boolean))} /> - ) + ); } - return + return ; } } diff --git a/packages/decap-cms-widget-list/src/index.js b/packages/decap-cms-widget-list/src/index.js index 02ee12ef90be..113c0a91403d 100644 --- a/packages/decap-cms-widget-list/src/index.js +++ b/packages/decap-cms-widget-list/src/index.js @@ -1,6 +1,6 @@ import DecapCmsWidgetObject from 'decap-cms-widget-object'; -import controlComponent, {OptionalObjectControl} from './ListControl'; +import controlComponent, { ObjectControlWrapper } from './ListControl'; import schema from './schema'; const previewComponent = DecapCmsWidgetObject.previewComponent; @@ -15,14 +15,14 @@ function Widget(opts = {}) { }; } -function OptionalObjectWidget(opts = {}) { +function ObjectWidget(opts = {}) { return { name: 'object', - controlComponent: OptionalObjectControl, + controlComponent: ObjectControlWrapper, previewComponent, ...opts, - } + }; } -export const DecapCmsWidgetList = { Widget, controlComponent, previewComponent, OptionalObjectWidget }; +export const DecapCmsWidgetList = { Widget, controlComponent, previewComponent, ObjectWidget }; export default DecapCmsWidgetList;