From 6450becabadbd745d82805f74887dcfd4b047c91 Mon Sep 17 00:00:00 2001 From: Rob Gietema Date: Thu, 19 Sep 2024 09:19:41 +0200 Subject: [PATCH] Add static text field. --- packages/volto/src/components/index.js | 1 + .../manage/Widgets/SchemaWidget.jsx | 18 +++++++++- .../manage/Widgets/StaticTextWidget.jsx | 35 +++++++++++++++++++ .../Widgets/StaticTextWidget.stories.jsx | 20 +++++++++++ .../manage/Widgets/StaticTextWidget.test.jsx | 25 +++++++++++++ .../src/components/manage/Widgets/index.tsx | 7 ++++ .../theme/Widgets/StaticTextWidget.jsx | 16 +++++++++ .../Widgets/StaticTextWidget.stories.jsx | 29 +++++++++++++++ .../theme/Widgets/StaticTextWidget.test.js | 32 +++++++++++++++++ packages/volto/src/config/Widgets.jsx | 6 +++- 10 files changed, 187 insertions(+), 2 deletions(-) create mode 100644 packages/volto/src/components/manage/Widgets/StaticTextWidget.jsx create mode 100644 packages/volto/src/components/manage/Widgets/StaticTextWidget.stories.jsx create mode 100644 packages/volto/src/components/manage/Widgets/StaticTextWidget.test.jsx create mode 100644 packages/volto/src/components/theme/Widgets/StaticTextWidget.jsx create mode 100644 packages/volto/src/components/theme/Widgets/StaticTextWidget.stories.jsx create mode 100644 packages/volto/src/components/theme/Widgets/StaticTextWidget.test.js diff --git a/packages/volto/src/components/index.js b/packages/volto/src/components/index.js index 5ade65c3c3..1ae17bd4c7 100644 --- a/packages/volto/src/components/index.js +++ b/packages/volto/src/components/index.js @@ -177,6 +177,7 @@ export { QuerystringWidget, SchemaWidget, SelectWidget, + StaticTextWidget, TextareaWidget, TextWidget, TokenWidget, diff --git a/packages/volto/src/components/manage/Widgets/SchemaWidget.jsx b/packages/volto/src/components/manage/Widgets/SchemaWidget.jsx index 6cba137737..a56d433f6e 100644 --- a/packages/volto/src/components/manage/Widgets/SchemaWidget.jsx +++ b/packages/volto/src/components/manage/Widgets/SchemaWidget.jsx @@ -189,6 +189,7 @@ const schemaField = (factory, intl, fieldsets) => ({ case 'Choice': case 'label_choice_field': return ['values']; + case 'static_text': case 'hidden': return ['default']; default: @@ -293,6 +294,14 @@ const schemaField = (factory, intl, fieldsets) => ({ widget: 'textarea', }, }; + case 'static_text': + return { + default: { + title: intl.formatMessage(messages.defaultValue), + widget: 'richtext', + type: 'string', + }, + }; case 'hidden': return { default: { @@ -651,9 +660,16 @@ class SchemaWidget extends Component { type: 'boolean', factory, }; + case 'static_text': + return { + type: 'object', + widget: 'static_text', + factory, + }; case 'hidden': return { - type: 'hidden', + type: 'string', + widget: 'hidden', factory, }; default: diff --git a/packages/volto/src/components/manage/Widgets/StaticTextWidget.jsx b/packages/volto/src/components/manage/Widgets/StaticTextWidget.jsx new file mode 100644 index 0000000000..29d5f56bbe --- /dev/null +++ b/packages/volto/src/components/manage/Widgets/StaticTextWidget.jsx @@ -0,0 +1,35 @@ +import { useRef } from 'react'; +import PropTypes from 'prop-types'; + +import FormFieldWrapper from '@plone/volto/components/manage/Widgets/FormFieldWrapper'; + +const StaticTextWidget = (props) => { + const { id, value } = props; + + return ( + +
+

+

+
+ ); +}; + +export default StaticTextWidget; + +StaticTextWidget.propTypes = { + id: PropTypes.string.isRequired, + value: PropTypes.string, + minLength: PropTypes.number, + maxLength: PropTypes.number, +}; + +StaticTextWidget.defaultProps = { + value: null, + minLength: null, + maxLength: null, +}; diff --git a/packages/volto/src/components/manage/Widgets/StaticTextWidget.stories.jsx b/packages/volto/src/components/manage/Widgets/StaticTextWidget.stories.jsx new file mode 100644 index 0000000000..533384924e --- /dev/null +++ b/packages/volto/src/components/manage/Widgets/StaticTextWidget.stories.jsx @@ -0,0 +1,20 @@ +import StaticTextWidget from './StaticTextWidget'; +import WidgetStory from './story'; + +export const StaticText = WidgetStory.bind({ + props: { id: 'text', title: 'Text' }, + widget: StaticTextWidget, +}); + +export default { + title: 'Edit Widgets/Static Text', + component: StaticTextWidget, + decorators: [ + (Story) => ( +
+ +
+ ), + ], + argTypes: {}, +}; diff --git a/packages/volto/src/components/manage/Widgets/StaticTextWidget.test.jsx b/packages/volto/src/components/manage/Widgets/StaticTextWidget.test.jsx new file mode 100644 index 0000000000..e0c1219b72 --- /dev/null +++ b/packages/volto/src/components/manage/Widgets/StaticTextWidget.test.jsx @@ -0,0 +1,25 @@ +import React from 'react'; +import renderer from 'react-test-renderer'; +import configureStore from 'redux-mock-store'; +import { Provider } from 'react-intl-redux'; + +import StaticTextWidget from './StaticTextWidget'; + +const mockStore = configureStore(); + +test('renders a text widget component', () => { + const store = mockStore({ + intl: { + locale: 'en', + messages: {}, + }, + }); + + const component = renderer.create( + + + , + ); + const json = component.toJSON(); + expect(json).toMatchSnapshot(); +}); diff --git a/packages/volto/src/components/manage/Widgets/index.tsx b/packages/volto/src/components/manage/Widgets/index.tsx index 1af1474224..5e3136d866 100644 --- a/packages/volto/src/components/manage/Widgets/index.tsx +++ b/packages/volto/src/components/manage/Widgets/index.tsx @@ -91,6 +91,13 @@ export const SelectWidget = loadable( ), ); +export const StaticTextWidget = loadable( + () => + import( + /* webpackChunkName: "Widgets" */ '@plone/volto/components/manage/Widgets/StaticTextWidget' + ), +); + export const TextareaWidget = loadable( () => import( diff --git a/packages/volto/src/components/theme/Widgets/StaticTextWidget.jsx b/packages/volto/src/components/theme/Widgets/StaticTextWidget.jsx new file mode 100644 index 0000000000..0b126fac76 --- /dev/null +++ b/packages/volto/src/components/theme/Widgets/StaticTextWidget.jsx @@ -0,0 +1,16 @@ +import React from 'react'; +import cx from 'classnames'; + +const StaticTextWidget = ({ value, className }) => + value ? ( +

+ ) : ( + '' + ); + +export default StaticTextWidget; diff --git a/packages/volto/src/components/theme/Widgets/StaticTextWidget.stories.jsx b/packages/volto/src/components/theme/Widgets/StaticTextWidget.stories.jsx new file mode 100644 index 0000000000..5dbeb5b032 --- /dev/null +++ b/packages/volto/src/components/theme/Widgets/StaticTextWidget.stories.jsx @@ -0,0 +1,29 @@ +import React from 'react'; +import StaticTextWidget from './StaticTextWidget'; +import Wrapper from '@plone/volto/storybook'; + +const StaticTextWidgetComponent = ({ children, className, value }) => { + return ( + +

+ +
+ + ); +}; + +export const StaticText = StaticTextWidgetComponent.bind({}); +StaticTextWidget.args = { + value: { data: '

Hello world

' }, + className: '', +}; + +export default { + title: 'View Widgets/Static Text', + component: StaticTextWidget, + argTypes: {}, +}; diff --git a/packages/volto/src/components/theme/Widgets/StaticTextWidget.test.js b/packages/volto/src/components/theme/Widgets/StaticTextWidget.test.js new file mode 100644 index 0000000000..55c020320a --- /dev/null +++ b/packages/volto/src/components/theme/Widgets/StaticTextWidget.test.js @@ -0,0 +1,32 @@ +import React from 'react'; +import renderer from 'react-test-renderer'; +import StaticTextWidget from './StaticTextWidget'; + +describe('StaticTextWidget', () => { + it('renders an empty static text view widget component', () => { + const component = renderer.create(); + const json = component.toJSON(); + expect(json).toMatchSnapshot(); + }); + + it('renders a static text view widget component', () => { + const component = renderer.create( + Foo bar' }} + />, + ); + const json = component.toJSON(); + expect(json).toMatchSnapshot(); + }); + + it('renders a static text view widget component with children', () => { + const component = renderer.create( + Foo bar' }}> + {(child) => {child}} + , + ); + const json = component.toJSON(); + expect(json).toMatchSnapshot(); + }); +}); diff --git a/packages/volto/src/config/Widgets.jsx b/packages/volto/src/config/Widgets.jsx index 2109d9b821..3c95c8bdf7 100644 --- a/packages/volto/src/config/Widgets.jsx +++ b/packages/volto/src/config/Widgets.jsx @@ -28,6 +28,7 @@ import { VocabularyTermsWidget, SelectMetadataWidget, SelectAutoComplete, + StaticTextWidget, ColorPickerWidget, DatetimeWidget, RecurrenceWidget, @@ -53,6 +54,7 @@ import TokenViewWidget from '@plone/volto/components/theme/Widgets/TokenWidget'; import UrlViewWidget from '@plone/volto/components/theme/Widgets/UrlWidget'; import ImageWidget from '@plone/volto/components/manage/Widgets/ImageWidget'; import HiddenViewWidget from '@plone/volto/components/manage/Widgets/HiddenWidget'; +import StaticTextViewWidget from '@plone/volto/components/manage/Widgets/StaticTextWidget'; // Widgets mapping export const widgetMapping = { @@ -91,6 +93,7 @@ export const widgetMapping = { color_picker: ColorPickerWidget, select: SelectWidget, schema: SchemaWidget, + static_text: StaticTextWidget, }, vocabulary: { 'plone.app.vocabularies.Catalog': ObjectBrowserWidget, @@ -141,6 +144,8 @@ export const widgetMapping = { title: TitleViewWidget, url: UrlViewWidget, internal_url: InternalUrlWidget, + static_text: StaticTextViewWidget, + hidden: HiddenViewWidget, object: () => '', // TODO: Not implemented yet: Object View widget }, vocabulary: {}, @@ -148,7 +153,6 @@ export const widgetMapping = { type: { array: ArrayViewWidget, boolean: BooleanViewWidget, - hidden: HiddenViewWidget, }, }, };