@plone/volto 19.0.0-alpha.11 → 19.0.0-alpha.12
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +21 -0
- package/locales/ca/LC_MESSAGES/volto.po +10 -0
- package/locales/de/LC_MESSAGES/volto.po +10 -0
- package/locales/en/LC_MESSAGES/volto.po +10 -0
- package/locales/es/LC_MESSAGES/volto.po +10 -0
- package/locales/eu/LC_MESSAGES/volto.po +10 -0
- package/locales/fi/LC_MESSAGES/volto.po +10 -0
- package/locales/fr/LC_MESSAGES/volto.po +10 -0
- package/locales/hi/LC_MESSAGES/volto.po +10 -0
- package/locales/it/LC_MESSAGES/volto.po +10 -0
- package/locales/ja/LC_MESSAGES/volto.po +10 -0
- package/locales/nl/LC_MESSAGES/volto.po +10 -0
- package/locales/pt/LC_MESSAGES/volto.po +10 -0
- package/locales/pt_BR/LC_MESSAGES/volto.po +10 -0
- package/locales/ro/LC_MESSAGES/volto.po +10 -0
- package/locales/ru/LC_MESSAGES/volto.po +10 -0
- package/locales/volto.pot +11 -1
- package/locales/zh_CN/LC_MESSAGES/volto.po +10 -0
- package/package.json +5 -4
- package/src/components/manage/Controlpanels/Relations/Relations.jsx +1 -1
- package/src/components/manage/Widgets/AlignWidget.stories.jsx +9 -0
- package/src/components/manage/Widgets/AlignWidget.test.tsx +95 -0
- package/src/components/manage/Widgets/{AlignWidget.jsx → AlignWidget.tsx} +23 -7
- package/src/components/manage/Widgets/BlockAlignment.stories.tsx +104 -0
- package/src/components/manage/Widgets/BlockAlignment.test.tsx +104 -0
- package/src/components/manage/Widgets/BlockAlignment.tsx +88 -0
- package/src/components/manage/Widgets/BlockWidth.stories.tsx +69 -0
- package/src/components/manage/Widgets/BlockWidth.test.tsx +62 -0
- package/src/components/manage/Widgets/BlockWidth.tsx +101 -0
- package/src/components/manage/Widgets/ButtonsWidget.stories.jsx +61 -0
- package/src/components/manage/Widgets/ButtonsWidget.test.tsx +138 -0
- package/src/components/manage/Widgets/ButtonsWidget.tsx +176 -0
- package/src/components/manage/Widgets/Size.stories.tsx +69 -0
- package/src/components/manage/Widgets/Size.test.tsx +59 -0
- package/src/components/manage/Widgets/Size.tsx +78 -0
- package/src/components/manage/Widgets/index.tsx +21 -0
- package/src/components/theme/App/App.jsx +2 -0
- package/src/components/theme/InjectPloneComponentsCSS/InjectPloneComponentsCSS.tsx +7 -0
- package/src/config/Widgets.jsx +7 -0
- package/src/config/slots.js +19 -0
- package/theme/themes/pastanaga/extras/widgets.less +45 -0
- package/types/components/manage/Widgets/AlignWidget.d.ts +8 -10
- package/types/components/manage/Widgets/AlignWidget.stories.d.ts +1 -0
- package/types/components/manage/Widgets/BlockAlignment.d.ts +7 -0
- package/types/components/manage/Widgets/BlockAlignment.stories.d.ts +8 -0
- package/types/components/manage/Widgets/BlockWidth.d.ts +7 -0
- package/types/components/manage/Widgets/BlockWidth.stories.d.ts +6 -0
- package/types/components/manage/Widgets/ButtonsWidget.d.ts +48 -1
- package/types/components/manage/Widgets/ButtonsWidget.stories.d.ts +3 -0
- package/types/components/manage/Widgets/Size.d.ts +7 -0
- package/types/components/manage/Widgets/Size.stories.d.ts +6 -0
- package/types/components/manage/Widgets/index.d.ts +7 -2
- package/types/components/theme/InjectPloneComponentsCSS/InjectPloneComponentsCSS.d.ts +3 -0
- package/types/config/Widgets.d.ts +6 -0
- package/types/config/slots.d.ts +7 -0
- package/src/components/manage/Widgets/AlignWidget.test.jsx +0 -59
- package/src/components/manage/Widgets/ButtonsWidget.jsx +0 -41
- package/src/components/manage/Widgets/ButtonsWidget.test.jsx +0 -70
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import { defineMessages, useIntl } from 'react-intl';
|
|
2
|
+
import ButtonsWidget, {
|
|
3
|
+
type ActionInfo,
|
|
4
|
+
type ButtonsWidgetProps,
|
|
5
|
+
} from './ButtonsWidget';
|
|
6
|
+
import type { IntlShape } from 'react-intl';
|
|
7
|
+
import type { StyleDefinition } from '@plone/types';
|
|
8
|
+
|
|
9
|
+
const messages = defineMessages({
|
|
10
|
+
s: {
|
|
11
|
+
id: 'Small',
|
|
12
|
+
defaultMessage: 'Small',
|
|
13
|
+
},
|
|
14
|
+
m: {
|
|
15
|
+
id: 'Medium',
|
|
16
|
+
defaultMessage: 'Medium',
|
|
17
|
+
},
|
|
18
|
+
l: {
|
|
19
|
+
id: 'Large',
|
|
20
|
+
defaultMessage: 'Large',
|
|
21
|
+
},
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
export const defaultActionsInfo = ({
|
|
25
|
+
intl,
|
|
26
|
+
}: {
|
|
27
|
+
intl: IntlShape;
|
|
28
|
+
}): Record<string, ActionInfo> => ({
|
|
29
|
+
s: ['S', intl.formatMessage(messages.s)],
|
|
30
|
+
m: ['M', intl.formatMessage(messages.m)],
|
|
31
|
+
l: ['L', intl.formatMessage(messages.l)],
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
const DEFAULT_ACTIONS: StyleDefinition[] = [
|
|
35
|
+
{
|
|
36
|
+
name: 's',
|
|
37
|
+
label: 'Small',
|
|
38
|
+
style: undefined,
|
|
39
|
+
},
|
|
40
|
+
{
|
|
41
|
+
name: 'm',
|
|
42
|
+
label: 'Medium',
|
|
43
|
+
style: undefined,
|
|
44
|
+
},
|
|
45
|
+
{
|
|
46
|
+
name: 'l',
|
|
47
|
+
label: 'Large',
|
|
48
|
+
style: undefined,
|
|
49
|
+
},
|
|
50
|
+
];
|
|
51
|
+
|
|
52
|
+
const SizeWidget = (props: ButtonsWidgetProps) => {
|
|
53
|
+
const intl = useIntl();
|
|
54
|
+
|
|
55
|
+
const { actions = DEFAULT_ACTIONS, actionsInfoMap, filterActions } = props;
|
|
56
|
+
const filteredActions =
|
|
57
|
+
filterActions && filterActions.length > 0
|
|
58
|
+
? actions.filter((action) => {
|
|
59
|
+
const actionName = typeof action === 'string' ? action : action.name;
|
|
60
|
+
return filterActions.includes(actionName);
|
|
61
|
+
})
|
|
62
|
+
: actions;
|
|
63
|
+
|
|
64
|
+
const actionsInfo = {
|
|
65
|
+
...defaultActionsInfo({ intl }),
|
|
66
|
+
...actionsInfoMap,
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
return (
|
|
70
|
+
<ButtonsWidget
|
|
71
|
+
{...props}
|
|
72
|
+
actions={filteredActions}
|
|
73
|
+
actionsInfoMap={actionsInfo}
|
|
74
|
+
/>
|
|
75
|
+
);
|
|
76
|
+
};
|
|
77
|
+
|
|
78
|
+
export default SizeWidget;
|
|
@@ -265,3 +265,24 @@ export const FormFieldWrapper = loadable(
|
|
|
265
265
|
/* webpackChunkName: "Widgets" */ '@plone/volto/components/manage/Widgets/FormFieldWrapper'
|
|
266
266
|
),
|
|
267
267
|
);
|
|
268
|
+
|
|
269
|
+
export const Size = loadable(
|
|
270
|
+
() =>
|
|
271
|
+
import(
|
|
272
|
+
/* webpackChunkName: "Widgets" */ '@plone/volto/components/manage/Widgets/Size'
|
|
273
|
+
),
|
|
274
|
+
);
|
|
275
|
+
|
|
276
|
+
export const BlockAlignment = loadable(
|
|
277
|
+
() =>
|
|
278
|
+
import(
|
|
279
|
+
/* webpackChunkName: "Widgets" */ '@plone/volto/components/manage/Widgets/BlockAlignment'
|
|
280
|
+
),
|
|
281
|
+
);
|
|
282
|
+
|
|
283
|
+
export const BlockWidth = loadable(
|
|
284
|
+
() =>
|
|
285
|
+
import(
|
|
286
|
+
/* webpackChunkName: "Widgets" */ '@plone/volto/components/manage/Widgets/BlockWidth'
|
|
287
|
+
),
|
|
288
|
+
);
|
|
@@ -45,6 +45,7 @@ import MultilingualRedirector from '@plone/volto/components/theme/MultilingualRe
|
|
|
45
45
|
import WorkingCopyToastsFactory from '@plone/volto/components/manage/WorkingCopyToastsFactory/WorkingCopyToastsFactory';
|
|
46
46
|
import LockingToastsFactory from '@plone/volto/components/manage/LockingToastsFactory/LockingToastsFactory';
|
|
47
47
|
import RouteAnnouncer from '@plone/volto/components/theme/RouteAnnouncer/RouteAnnouncer';
|
|
48
|
+
import SlotRenderer from '@plone/volto/components/theme/SlotRenderer/SlotRenderer';
|
|
48
49
|
|
|
49
50
|
/**
|
|
50
51
|
* @export
|
|
@@ -159,6 +160,7 @@ export class App extends Component {
|
|
|
159
160
|
'public-ui': !isCmsUI,
|
|
160
161
|
})}
|
|
161
162
|
/>
|
|
163
|
+
<SlotRenderer name="aboveApp" content={this.props.content} />
|
|
162
164
|
<SkipLinks />
|
|
163
165
|
<Header pathname={path} />
|
|
164
166
|
<Breadcrumbs pathname={path} />
|
package/src/config/Widgets.jsx
CHANGED
|
@@ -35,6 +35,9 @@ import {
|
|
|
35
35
|
RecurrenceWidget,
|
|
36
36
|
RadioGroupWidget,
|
|
37
37
|
CheckboxGroupWidget,
|
|
38
|
+
Size,
|
|
39
|
+
BlockAlignment,
|
|
40
|
+
BlockWidth,
|
|
38
41
|
} from '@plone/volto/components/manage/Widgets';
|
|
39
42
|
|
|
40
43
|
import ArrayViewWidget from '@plone/volto/components/theme/Widgets/ArrayWidget';
|
|
@@ -102,6 +105,10 @@ export const widgetMapping = {
|
|
|
102
105
|
hidden: HiddenWidget,
|
|
103
106
|
radio_group: RadioGroupWidget,
|
|
104
107
|
checkbox_group: CheckboxGroupWidget,
|
|
108
|
+
// SemanticUI Free widgets
|
|
109
|
+
blockAlignment: BlockAlignment,
|
|
110
|
+
blockWidth: BlockWidth,
|
|
111
|
+
size: Size,
|
|
105
112
|
},
|
|
106
113
|
vocabulary: {
|
|
107
114
|
'plone.app.vocabularies.Catalog': ObjectBrowserWidget,
|
package/src/config/slots.js
CHANGED
|
@@ -1,7 +1,26 @@
|
|
|
1
|
+
import loadable from '@loadable/component';
|
|
1
2
|
import RelatedItems from '@plone/volto/components/theme/RelatedItems/RelatedItems';
|
|
2
3
|
import Tags from '@plone/volto/components/theme/Tags/Tags';
|
|
4
|
+
import { isCmsUi } from '@plone/volto/helpers/Url/Url';
|
|
5
|
+
|
|
6
|
+
const InjectPloneComponentsCSS = loadable(
|
|
7
|
+
() =>
|
|
8
|
+
import(
|
|
9
|
+
'@plone/volto/components/theme/InjectPloneComponentsCSS/InjectPloneComponentsCSS'
|
|
10
|
+
),
|
|
11
|
+
{ fallback: null },
|
|
12
|
+
);
|
|
13
|
+
|
|
14
|
+
const onlyCMSUI = ({ location }) => isCmsUi(location?.pathname);
|
|
3
15
|
|
|
4
16
|
const slots = {
|
|
17
|
+
aboveApp: [
|
|
18
|
+
{
|
|
19
|
+
name: 'plone-components-css',
|
|
20
|
+
component: InjectPloneComponentsCSS,
|
|
21
|
+
predicates: [onlyCMSUI],
|
|
22
|
+
},
|
|
23
|
+
],
|
|
5
24
|
belowContent: [
|
|
6
25
|
{
|
|
7
26
|
name: 'tags',
|
|
@@ -292,3 +292,48 @@ body.babel-view .field.language-independent-field {
|
|
|
292
292
|
margin-left: 8px;
|
|
293
293
|
}
|
|
294
294
|
}
|
|
295
|
+
|
|
296
|
+
// ButtonsWidget and friends 2025
|
|
297
|
+
:root {
|
|
298
|
+
--border-color-hover: var(--quanta-sapphire);
|
|
299
|
+
--border-color-pressed: var(--quanta-sapphire);
|
|
300
|
+
--border-color-disabled: #d4d4d5;
|
|
301
|
+
--text-color-disabled: #a8a8a8;
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
.field.widget {
|
|
305
|
+
.buttons-widget {
|
|
306
|
+
display: flex;
|
|
307
|
+
align-items: center;
|
|
308
|
+
gap: 4px;
|
|
309
|
+
|
|
310
|
+
.buttons-widget-option {
|
|
311
|
+
padding: 5px;
|
|
312
|
+
border-radius: 3px;
|
|
313
|
+
aspect-ratio: 1/1;
|
|
314
|
+
font-size: 1em;
|
|
315
|
+
line-height: initial;
|
|
316
|
+
|
|
317
|
+
&[data-hovered='true'] {
|
|
318
|
+
box-shadow: inset 0 0 0 1px var(--border-color-hover, #2996da);
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
&[data-selected='true'] {
|
|
322
|
+
box-shadow: inset 0 0 0 1px var(--border-color-pressed, #2996da);
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
svg.icon {
|
|
326
|
+
margin: 0 !important;
|
|
327
|
+
opacity: 0.9;
|
|
328
|
+
vertical-align: top;
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
.buttons-widget-option {
|
|
335
|
+
&[data-disabled='true'] {
|
|
336
|
+
border-color: var(--border-color-disabled);
|
|
337
|
+
color: var(--text-color-disabled);
|
|
338
|
+
}
|
|
339
|
+
}
|
|
@@ -1,12 +1,10 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
}
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
wide: any[];
|
|
9
|
-
full: any[];
|
|
1
|
+
import { type ActionInfo, type ButtonsWidgetProps } from './ButtonsWidget';
|
|
2
|
+
import type { IntlShape } from 'react-intl';
|
|
3
|
+
export declare const defaultActionsInfo: ({ intl, }: {
|
|
4
|
+
intl: IntlShape;
|
|
5
|
+
}) => Record<string, ActionInfo>;
|
|
6
|
+
type AlignWidgetProps = ButtonsWidgetProps & {
|
|
7
|
+
defaultAction?: string;
|
|
10
8
|
};
|
|
9
|
+
declare const AlignWidget: (props: AlignWidgetProps) => import("react/jsx-runtime").JSX.Element;
|
|
11
10
|
export default AlignWidget;
|
|
12
|
-
declare function AlignWidget(props: any): import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { type ActionInfo, type ButtonsWidgetProps } from './ButtonsWidget';
|
|
2
|
+
import type { IntlShape } from 'react-intl';
|
|
3
|
+
export declare const defaultActionsInfo: ({ intl, }: {
|
|
4
|
+
intl: IntlShape;
|
|
5
|
+
}) => Record<string, ActionInfo>;
|
|
6
|
+
declare const BlockAlignmentWidget: (props: ButtonsWidgetProps) => import("react/jsx-runtime").JSX.Element;
|
|
7
|
+
export default BlockAlignmentWidget;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from '@storybook/react';
|
|
2
|
+
import BlockAlignment from './BlockAlignment';
|
|
3
|
+
declare const meta: Meta<typeof BlockAlignment>;
|
|
4
|
+
export default meta;
|
|
5
|
+
type Story = StoryObj<typeof BlockAlignment>;
|
|
6
|
+
export declare const DefaultAlignment: Story;
|
|
7
|
+
export declare const CustomActions: Story;
|
|
8
|
+
export declare const FilteredActions: Story;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { IntlShape } from 'react-intl';
|
|
2
|
+
import { type ActionInfo, type ButtonsWidgetProps } from './ButtonsWidget';
|
|
3
|
+
export declare const defaultActionsInfo: ({ intl, }: {
|
|
4
|
+
intl: IntlShape;
|
|
5
|
+
}) => Record<string, ActionInfo>;
|
|
6
|
+
declare const BlockWidthWidget: (props: ButtonsWidgetProps) => import("react/jsx-runtime").JSX.Element;
|
|
7
|
+
export default BlockWidthWidget;
|
|
@@ -1,2 +1,49 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import type { StyleDefinition } from '@plone/types';
|
|
3
|
+
/**
|
|
4
|
+
* A tuple that has an icon in the first element and a i18n string in the second.
|
|
5
|
+
*/
|
|
6
|
+
export type ActionInfo = [React.ReactElement<any>, string] | [string, string];
|
|
7
|
+
type ActionValue = string | Record<`--${string}`, string>;
|
|
8
|
+
export type ButtonsWidgetProps = {
|
|
9
|
+
/**
|
|
10
|
+
* Unique identifier for the widget.
|
|
11
|
+
*/
|
|
12
|
+
id: string;
|
|
13
|
+
/**
|
|
14
|
+
* Callback function to handle changes.
|
|
15
|
+
*/
|
|
16
|
+
onChange: (id: string, value: ActionValue) => void;
|
|
17
|
+
/**
|
|
18
|
+
* List of actions available for the widget.
|
|
19
|
+
*/
|
|
20
|
+
actions?: Array<StyleDefinition | string>;
|
|
21
|
+
/**
|
|
22
|
+
* Map containing additional the information (icon and i18n string) for each action.
|
|
23
|
+
*/
|
|
24
|
+
actionsInfoMap?: Record<string, ActionInfo>;
|
|
25
|
+
/**
|
|
26
|
+
* List of actions to be filtered out. In case that we don't want the default ones
|
|
27
|
+
* we can filter them out.
|
|
28
|
+
*/
|
|
29
|
+
filterActions?: string[];
|
|
30
|
+
/**
|
|
31
|
+
* Current value of the widget.
|
|
32
|
+
*/
|
|
33
|
+
value?: ActionValue;
|
|
34
|
+
/**
|
|
35
|
+
* Default value of the widget.
|
|
36
|
+
*/
|
|
37
|
+
default?: ActionValue;
|
|
38
|
+
/**
|
|
39
|
+
* Indicates if the widget is disabled.
|
|
40
|
+
*/
|
|
41
|
+
disabled?: boolean;
|
|
42
|
+
/**
|
|
43
|
+
* Indicates if the widget is disabled (alternative flag for compatibility reasons).
|
|
44
|
+
*/
|
|
45
|
+
isDisabled?: boolean;
|
|
46
|
+
[key: string]: any;
|
|
47
|
+
};
|
|
48
|
+
declare const ButtonsWidget: (props: ButtonsWidgetProps) => import("react/jsx-runtime").JSX.Element;
|
|
1
49
|
export default ButtonsWidget;
|
|
2
|
-
declare function ButtonsWidget(props: any): import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { type ActionInfo, type ButtonsWidgetProps } from './ButtonsWidget';
|
|
2
|
+
import type { IntlShape } from 'react-intl';
|
|
3
|
+
export declare const defaultActionsInfo: ({ intl, }: {
|
|
4
|
+
intl: IntlShape;
|
|
5
|
+
}) => Record<string, ActionInfo>;
|
|
6
|
+
declare const SizeWidget: (props: ButtonsWidgetProps) => import("react/jsx-runtime").JSX.Element;
|
|
7
|
+
export default SizeWidget;
|
|
@@ -1,5 +1,7 @@
|
|
|
1
|
-
export declare const AlignWidget: import("@loadable/component").LoadableComponent<
|
|
2
|
-
|
|
1
|
+
export declare const AlignWidget: import("@loadable/component").LoadableComponent<import("@plone/volto/components/manage/Widgets/ButtonsWidget").ButtonsWidgetProps & {
|
|
2
|
+
defaultAction?: string;
|
|
3
|
+
}>;
|
|
4
|
+
export declare const ButtonsWidget: import("@loadable/component").LoadableComponent<import("@plone/volto/components/manage/Widgets/ButtonsWidget").ButtonsWidgetProps>;
|
|
3
5
|
export declare const ArrayWidget: import("@loadable/component").LoadableClassComponent<any>;
|
|
4
6
|
export declare const CheckboxWidget: import("@loadable/component").LoadableComponent<import("react-intl").WithIntlProps<any>>;
|
|
5
7
|
export declare const CheckboxGroupWidget: import("@loadable/component").LoadableClassComponent<any>;
|
|
@@ -122,3 +124,6 @@ export declare const DatetimeWidget: import("@loadable/component").LoadableClass
|
|
|
122
124
|
export declare const TimeWidget: import("@loadable/component").LoadableClassComponent<any>;
|
|
123
125
|
export declare const RecurrenceWidget: import("@loadable/component").LoadableClassComponent<any>;
|
|
124
126
|
export declare const FormFieldWrapper: import("@loadable/component").LoadableComponent<import("react-intl").WithIntlProps<any>>;
|
|
127
|
+
export declare const Size: import("@loadable/component").LoadableComponent<import("@plone/volto/components/manage/Widgets/ButtonsWidget").ButtonsWidgetProps>;
|
|
128
|
+
export declare const BlockAlignment: import("@loadable/component").LoadableComponent<import("@plone/volto/components/manage/Widgets/ButtonsWidget").ButtonsWidgetProps>;
|
|
129
|
+
export declare const BlockWidth: import("@loadable/component").LoadableComponent<import("@plone/volto/components/manage/Widgets/ButtonsWidget").ButtonsWidgetProps>;
|
|
@@ -41,6 +41,9 @@ export namespace widgetMapping {
|
|
|
41
41
|
export { HiddenWidget as hidden };
|
|
42
42
|
export { RadioGroupWidget as radio_group };
|
|
43
43
|
export { CheckboxGroupWidget as checkbox_group };
|
|
44
|
+
export { BlockAlignment as blockAlignment };
|
|
45
|
+
export { BlockWidth as blockWidth };
|
|
46
|
+
export { Size as size };
|
|
44
47
|
}
|
|
45
48
|
export let vocabulary: {
|
|
46
49
|
'plone.app.vocabularies.Catalog': import("@loadable/component").LoadableComponent<Omit<import("react-intl").WithIntlProps<import("react-intl").WrappedComponentProps<string>>, "ref"> & import("react").RefAttributes<import("react").ComponentType<import("react-intl").WrappedComponentProps<string>>>>;
|
|
@@ -141,6 +144,9 @@ import { StaticTextWidget } from '@plone/volto/components/manage/Widgets';
|
|
|
141
144
|
import { HiddenWidget } from '@plone/volto/components/manage/Widgets';
|
|
142
145
|
import { RadioGroupWidget } from '@plone/volto/components/manage/Widgets';
|
|
143
146
|
import { CheckboxGroupWidget } from '@plone/volto/components/manage/Widgets';
|
|
147
|
+
import { BlockAlignment } from '@plone/volto/components/manage/Widgets';
|
|
148
|
+
import { BlockWidth } from '@plone/volto/components/manage/Widgets';
|
|
149
|
+
import { Size } from '@plone/volto/components/manage/Widgets';
|
|
144
150
|
import { CheckboxWidget } from '@plone/volto/components/manage/Widgets';
|
|
145
151
|
import { NumberWidget } from '@plone/volto/components/manage/Widgets';
|
|
146
152
|
import { getWidgetView } from '@plone/volto/helpers/Widget/widget';
|
package/types/config/slots.d.ts
CHANGED
|
@@ -1,5 +1,12 @@
|
|
|
1
1
|
export default slots;
|
|
2
2
|
declare namespace slots {
|
|
3
|
+
let aboveApp: {
|
|
4
|
+
name: string;
|
|
5
|
+
component: import("@loadable/component").LoadableComponent<any>;
|
|
6
|
+
predicates: (({ location }: {
|
|
7
|
+
location: any;
|
|
8
|
+
}) => boolean)[];
|
|
9
|
+
}[];
|
|
3
10
|
let belowContent: ({
|
|
4
11
|
name: string;
|
|
5
12
|
component: {
|
|
@@ -1,59 +0,0 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
|
-
import { render } from '@testing-library/react';
|
|
3
|
-
import configureStore from 'redux-mock-store';
|
|
4
|
-
import { Provider } from 'react-intl-redux';
|
|
5
|
-
import imageFullSVG from '@plone/volto/icons/image-full.svg';
|
|
6
|
-
|
|
7
|
-
import AlignWidget from './AlignWidget';
|
|
8
|
-
|
|
9
|
-
const mockStore = configureStore();
|
|
10
|
-
|
|
11
|
-
describe('renders an align widget component', () => {
|
|
12
|
-
it('basic', () => {
|
|
13
|
-
const store = mockStore({
|
|
14
|
-
intl: {
|
|
15
|
-
locale: 'en',
|
|
16
|
-
messages: {},
|
|
17
|
-
},
|
|
18
|
-
});
|
|
19
|
-
|
|
20
|
-
const { asFragment } = render(
|
|
21
|
-
<Provider store={store}>
|
|
22
|
-
<AlignWidget
|
|
23
|
-
id="align"
|
|
24
|
-
title="Alignment"
|
|
25
|
-
fieldSet="default"
|
|
26
|
-
onChange={() => {}}
|
|
27
|
-
/>
|
|
28
|
-
</Provider>,
|
|
29
|
-
);
|
|
30
|
-
|
|
31
|
-
expect(asFragment()).toMatchSnapshot();
|
|
32
|
-
});
|
|
33
|
-
|
|
34
|
-
it('extended with actions and actionsInfoMap props', () => {
|
|
35
|
-
const store = mockStore({
|
|
36
|
-
intl: {
|
|
37
|
-
locale: 'en',
|
|
38
|
-
messages: {},
|
|
39
|
-
},
|
|
40
|
-
});
|
|
41
|
-
|
|
42
|
-
const { asFragment } = render(
|
|
43
|
-
<Provider store={store}>
|
|
44
|
-
<AlignWidget
|
|
45
|
-
id="align"
|
|
46
|
-
title="Alignment"
|
|
47
|
-
fieldSet="default"
|
|
48
|
-
onChange={() => {}}
|
|
49
|
-
actions={['additional']}
|
|
50
|
-
actionsInfoMap={{
|
|
51
|
-
additional: [imageFullSVG, 'Additional action title'],
|
|
52
|
-
}}
|
|
53
|
-
/>
|
|
54
|
-
</Provider>,
|
|
55
|
-
);
|
|
56
|
-
|
|
57
|
-
expect(asFragment()).toMatchSnapshot();
|
|
58
|
-
});
|
|
59
|
-
});
|
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
|
-
import FormFieldWrapper from '@plone/volto/components/manage/Widgets/FormFieldWrapper';
|
|
3
|
-
import Icon from '@plone/volto/components/theme/Icon/Icon';
|
|
4
|
-
import { Button } from 'semantic-ui-react';
|
|
5
|
-
|
|
6
|
-
// The ButtonsWidget
|
|
7
|
-
const ButtonsWidget = (props) => {
|
|
8
|
-
const { id, onChange, actions, actionsInfoMap, defaultAction, value } = props;
|
|
9
|
-
|
|
10
|
-
React.useEffect(() => {
|
|
11
|
-
if (!props.value && props.default) {
|
|
12
|
-
props.onChange(props.id, props.default);
|
|
13
|
-
}
|
|
14
|
-
});
|
|
15
|
-
|
|
16
|
-
return (
|
|
17
|
-
<FormFieldWrapper {...props} className="align-widget">
|
|
18
|
-
<div className="align-buttons">
|
|
19
|
-
{actions.map((action) => (
|
|
20
|
-
<Button.Group key={action}>
|
|
21
|
-
<Button
|
|
22
|
-
icon
|
|
23
|
-
basic
|
|
24
|
-
aria-label={actionsInfoMap[action][1]}
|
|
25
|
-
onClick={() => onChange(id, action)}
|
|
26
|
-
active={(action === defaultAction && !value) || value === action}
|
|
27
|
-
>
|
|
28
|
-
<Icon
|
|
29
|
-
name={actionsInfoMap[action][0]}
|
|
30
|
-
title={actionsInfoMap[action][1] || action}
|
|
31
|
-
size="24px"
|
|
32
|
-
/>
|
|
33
|
-
</Button>
|
|
34
|
-
</Button.Group>
|
|
35
|
-
))}
|
|
36
|
-
</div>
|
|
37
|
-
</FormFieldWrapper>
|
|
38
|
-
);
|
|
39
|
-
};
|
|
40
|
-
|
|
41
|
-
export default ButtonsWidget;
|
|
@@ -1,70 +0,0 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
|
-
import { render } from '@testing-library/react';
|
|
3
|
-
import configureStore from 'redux-mock-store';
|
|
4
|
-
import { Provider } from 'react-intl-redux';
|
|
5
|
-
import imageFullSVG from '@plone/volto/icons/image-full.svg';
|
|
6
|
-
import textJustifiedSVG from '@plone/volto/icons/align-justify.svg';
|
|
7
|
-
import textCenteredSVG from '@plone/volto/icons/align-center.svg';
|
|
8
|
-
import textLeftSVG from '@plone/volto/icons/align-left.svg';
|
|
9
|
-
import textRightSVG from '@plone/volto/icons/align-right.svg';
|
|
10
|
-
|
|
11
|
-
import ButtonsWidget from './ButtonsWidget';
|
|
12
|
-
|
|
13
|
-
const mockStore = configureStore();
|
|
14
|
-
|
|
15
|
-
describe('renders an align widget component', () => {
|
|
16
|
-
it('basic', () => {
|
|
17
|
-
const store = mockStore({
|
|
18
|
-
intl: {
|
|
19
|
-
locale: 'en',
|
|
20
|
-
messages: {},
|
|
21
|
-
},
|
|
22
|
-
});
|
|
23
|
-
|
|
24
|
-
const { asFragment } = render(
|
|
25
|
-
<Provider store={store}>
|
|
26
|
-
<ButtonsWidget
|
|
27
|
-
id="align"
|
|
28
|
-
title="Alignment"
|
|
29
|
-
fieldSet="default"
|
|
30
|
-
onChange={() => {}}
|
|
31
|
-
actions={['left', 'right', 'centered', 'justified']}
|
|
32
|
-
actionsInfoMap={{
|
|
33
|
-
left: [textLeftSVG, 'Text Left'],
|
|
34
|
-
right: [textRightSVG, 'Text Right'],
|
|
35
|
-
justified: [textJustifiedSVG, 'Text Justified'],
|
|
36
|
-
centered: [textCenteredSVG, 'Text Centered'],
|
|
37
|
-
}}
|
|
38
|
-
/>
|
|
39
|
-
</Provider>,
|
|
40
|
-
);
|
|
41
|
-
|
|
42
|
-
expect(asFragment()).toMatchSnapshot();
|
|
43
|
-
});
|
|
44
|
-
|
|
45
|
-
it('extended with actions and actionsInfoMap props', () => {
|
|
46
|
-
const store = mockStore({
|
|
47
|
-
intl: {
|
|
48
|
-
locale: 'en',
|
|
49
|
-
messages: {},
|
|
50
|
-
},
|
|
51
|
-
});
|
|
52
|
-
|
|
53
|
-
const { asFragment } = render(
|
|
54
|
-
<Provider store={store}>
|
|
55
|
-
<ButtonsWidget
|
|
56
|
-
id="align"
|
|
57
|
-
title="Alignment"
|
|
58
|
-
fieldSet="default"
|
|
59
|
-
onChange={() => {}}
|
|
60
|
-
actions={['additional']}
|
|
61
|
-
actionsInfoMap={{
|
|
62
|
-
additional: [imageFullSVG, 'Additional action title'],
|
|
63
|
-
}}
|
|
64
|
-
/>
|
|
65
|
-
</Provider>,
|
|
66
|
-
);
|
|
67
|
-
|
|
68
|
-
expect(asFragment()).toMatchSnapshot();
|
|
69
|
-
});
|
|
70
|
-
});
|