Skip to content

Commit

Permalink
Add static text field.
Browse files Browse the repository at this point in the history
  • Loading branch information
robgietema committed Sep 19, 2024
1 parent cc2138b commit 6450bec
Show file tree
Hide file tree
Showing 10 changed files with 187 additions and 2 deletions.
1 change: 1 addition & 0 deletions packages/volto/src/components/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,7 @@ export {
QuerystringWidget,
SchemaWidget,
SelectWidget,
StaticTextWidget,
TextareaWidget,
TextWidget,
TokenWidget,
Expand Down
18 changes: 17 additions & 1 deletion packages/volto/src/components/manage/Widgets/SchemaWidget.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down Expand Up @@ -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: {
Expand Down Expand Up @@ -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:
Expand Down
35 changes: 35 additions & 0 deletions packages/volto/src/components/manage/Widgets/StaticTextWidget.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import { useRef } from 'react';

Check warning on line 1 in packages/volto/src/components/manage/Widgets/StaticTextWidget.jsx

View workflow job for this annotation

GitHub Actions / ESlint

'useRef' is defined but never used
import PropTypes from 'prop-types';

import FormFieldWrapper from '@plone/volto/components/manage/Widgets/FormFieldWrapper';

const StaticTextWidget = (props) => {
const { id, value } = props;

return (
<FormFieldWrapper {...props} className="text" columns={1}>
<div id={id} className="wrapper">
<p
dangerouslySetInnerHTML={{
__html: value?.data || '',
}}
/>
</div>
</FormFieldWrapper>
);
};

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,
};
Original file line number Diff line number Diff line change
@@ -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) => (
<div className="ui segment form attached" style={{ width: '400px' }}>
<Story />
</div>
),
],
argTypes: {},
};
Original file line number Diff line number Diff line change
@@ -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(
<Provider store={store}>
<StaticTextWidget id="my-field" />
</Provider>,
);
const json = component.toJSON();
expect(json).toMatchSnapshot();
});
7 changes: 7 additions & 0 deletions packages/volto/src/components/manage/Widgets/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand Down
16 changes: 16 additions & 0 deletions packages/volto/src/components/theme/Widgets/StaticTextWidget.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import React from 'react';
import cx from 'classnames';

const StaticTextWidget = ({ value, className }) =>
value ? (
<p
className={cx(className, 'statictext', 'widget')}
dangerouslySetInnerHTML={{
__html: value.data,
}}
/>
) : (
''
);

export default StaticTextWidget;
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import React from 'react';
import StaticTextWidget from './StaticTextWidget';
import Wrapper from '@plone/volto/storybook';

const StaticTextWidgetComponent = ({ children, className, value }) => {
return (
<Wrapper location={{ pathname: '/folder2/folder21/doc212' }}>
<div className="ui segment form attached" style={{ width: '400px' }}>
<StaticTextWidget
value={value}
children={children}
className={className}
/>
</div>
</Wrapper>
);
};

export const StaticText = StaticTextWidgetComponent.bind({});
StaticTextWidget.args = {
value: { data: '<p><strong>Hello</strong> <em>world</em></p>' },
className: '',
};

export default {
title: 'View Widgets/Static Text',
component: StaticTextWidget,
argTypes: {},
};
Original file line number Diff line number Diff line change
@@ -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(<StaticTextWidget />);
const json = component.toJSON();
expect(json).toMatchSnapshot();
});

it('renders a static text view widget component', () => {
const component = renderer.create(
<StaticTextWidget
className="metadata"
value={{ data: '<b>Foo bar</b>' }}
/>,
);
const json = component.toJSON();
expect(json).toMatchSnapshot();
});

it('renders a static text view widget component with children', () => {
const component = renderer.create(
<StaticTextWidget className="metadata" value={{ data: '<b>Foo bar</b>' }}>
{(child) => <strong>{child}</strong>}
</StaticTextWidget>,
);
const json = component.toJSON();
expect(json).toMatchSnapshot();
});
});
6 changes: 5 additions & 1 deletion packages/volto/src/config/Widgets.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import {
VocabularyTermsWidget,
SelectMetadataWidget,
SelectAutoComplete,
StaticTextWidget,
ColorPickerWidget,
DatetimeWidget,
RecurrenceWidget,
Expand All @@ -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 = {
Expand Down Expand Up @@ -91,6 +93,7 @@ export const widgetMapping = {
color_picker: ColorPickerWidget,
select: SelectWidget,
schema: SchemaWidget,
static_text: StaticTextWidget,
},
vocabulary: {
'plone.app.vocabularies.Catalog': ObjectBrowserWidget,
Expand Down Expand Up @@ -141,14 +144,15 @@ export const widgetMapping = {
title: TitleViewWidget,
url: UrlViewWidget,
internal_url: InternalUrlWidget,
static_text: StaticTextViewWidget,
hidden: HiddenViewWidget,
object: () => '', // TODO: Not implemented yet: Object View widget
},
vocabulary: {},
choices: SelectViewWidget,
type: {
array: ArrayViewWidget,
boolean: BooleanViewWidget,
hidden: HiddenViewWidget,
},
},
};
Expand Down

0 comments on commit 6450bec

Please sign in to comment.