@kitconcept/volto-light-theme 6.0.0-alpha.9 → 6.0.1

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.
Files changed (98) hide show
  1. package/.changelog.draft +2 -7
  2. package/CHANGELOG.md +221 -0
  3. package/README.md +6 -5
  4. package/locales/de/LC_MESSAGES/volto.po +171 -38
  5. package/locales/en/LC_MESSAGES/volto.po +170 -37
  6. package/locales/es/LC_MESSAGES/volto.po +171 -38
  7. package/locales/eu/LC_MESSAGES/volto.po +171 -38
  8. package/locales/pt_BR/volto.po +171 -38
  9. package/locales/volto.pot +171 -38
  10. package/package.json +15 -6
  11. package/src/components/Blocks/EventMetadata/View.jsx +32 -26
  12. package/src/components/Blocks/Listing/DefaultTemplate.jsx +19 -14
  13. package/src/components/Blocks/Listing/GridTemplate.jsx +9 -12
  14. package/src/components/Blocks/Listing/SummaryTemplate.jsx +9 -7
  15. package/src/components/Blocks/Teaser/DefaultBody.jsx +93 -0
  16. package/src/components/Footer/ColumnLinks.tsx +35 -0
  17. package/src/components/Footer/Footer.tsx +32 -0
  18. package/src/components/Footer/slots/Colophon.tsx +24 -0
  19. package/src/components/Footer/slots/Copyright.tsx +65 -0
  20. package/src/components/Footer/slots/CoreFooter.tsx +82 -0
  21. package/src/components/Footer/slots/FollowUsLogoAndLinks.tsx +80 -0
  22. package/src/components/Footer/slots/FooterLogos.tsx +44 -0
  23. package/src/components/Header/Header.tsx +257 -0
  24. package/src/components/Logo/Logo.tsx +85 -0
  25. package/src/components/{Footer/FooterLogos.tsx → LogosContainer/LogosContainer.tsx} +16 -36
  26. package/src/components/MobileNavigation/MobileNavigation.jsx +53 -18
  27. package/src/components/Navigation/Navigation.jsx +14 -3
  28. package/src/components/SearchWidget/IntranetSearchWidget.jsx +32 -5
  29. package/src/components/SearchWidget/SearchWidget.jsx +1 -1
  30. package/src/components/StickyMenu/StickyMenu.tsx +36 -0
  31. package/src/components/Summary/DefaultSummary.jsx +16 -0
  32. package/src/components/Summary/EventSummary.jsx +38 -0
  33. package/src/components/Summary/FileSummary.jsx +24 -0
  34. package/src/components/Summary/NewsItemSummary.jsx +40 -0
  35. package/src/components/Tags/Tags.jsx +46 -0
  36. package/src/components/Theme/EventView.jsx +19 -25
  37. package/src/components/Theme/NewsItemView.jsx +13 -9
  38. package/src/components/Theming/Theming.tsx +20 -17
  39. package/src/components/Widgets/{BlockAlignmentWidget.tsx → BlockAlignment.tsx} +9 -2
  40. package/src/components/Widgets/{BlockWidthWidget.tsx → BlockWidth.tsx} +10 -3
  41. package/src/components/Widgets/BlocksObject.tsx +353 -0
  42. package/src/components/Widgets/{ButtonsWidget.tsx → Buttons.tsx} +45 -4
  43. package/src/components/Widgets/ColorContrastChecker.tsx +117 -0
  44. package/src/components/Widgets/ColorPicker.tsx +59 -0
  45. package/src/components/Widgets/{ColorPickerWidget.tsx → ColorSwatch.tsx} +5 -5
  46. package/src/components/Widgets/ObjectList.tsx +342 -0
  47. package/src/components/Widgets/{ThemingColorPicker.tsx → RACThemingColorPicker.tsx} +4 -0
  48. package/src/components/Widgets/{SizeWidget.tsx → Size.tsx} +9 -2
  49. package/src/components/Widgets/ThemeColorSwatch.tsx +17 -0
  50. package/src/components/Widgets/schema/footerLinksSchema.ts +64 -0
  51. package/src/components/Widgets/schema/footerLogosSchema.ts +98 -0
  52. package/src/components/Widgets/schema/headerActionsSchema.ts +64 -0
  53. package/src/components/Widgets/schema/iconLinkListSchema.ts +98 -0
  54. package/src/config/blocks.tsx +37 -17
  55. package/src/config/settings.ts +54 -12
  56. package/src/config/slots.ts +36 -1
  57. package/src/config/summary.ts +24 -0
  58. package/src/config/widgets.ts +57 -23
  59. package/src/customizations/volto/components/manage/Blocks/Teaser/DefaultBody.jsx +8 -0
  60. package/src/customizations/volto/components/theme/Tags/Tags.jsx +11 -0
  61. package/src/customizations/volto/components/theme/View/RenderBlocks.jsx +2 -1
  62. package/src/helpers/DndSortableList.tsx +138 -0
  63. package/src/helpers/dates.js +22 -0
  64. package/src/helpers/doesNodeContainClick.js +64 -0
  65. package/src/helpers/useLiveData.ts +29 -0
  66. package/src/index.ts +31 -2
  67. package/src/primitives/IconLinkList.tsx +69 -0
  68. package/src/primitives/LinkList.tsx +35 -0
  69. package/src/theme/_bgcolor-blocks-layout.scss +50 -12
  70. package/src/theme/_content.scss +6 -0
  71. package/src/theme/_footer.scss +294 -41
  72. package/src/theme/_header.scss +132 -19
  73. package/src/theme/_layout.scss +11 -1
  74. package/src/theme/_sitemap.scss +4 -0
  75. package/src/theme/_utils.scss +14 -1
  76. package/src/theme/_variables.scss +12 -3
  77. package/src/theme/_widgets.scss +100 -9
  78. package/src/theme/blocks/_eventMetadata.scss +5 -2
  79. package/src/theme/blocks/_grid.scss +3 -3
  80. package/src/theme/blocks/_highlight.scss +17 -44
  81. package/src/theme/blocks/_listing.scss +25 -16
  82. package/src/theme/blocks/_maps.scss +3 -3
  83. package/src/theme/blocks/_slider.scss +5 -1
  84. package/src/theme/main.scss +1 -0
  85. package/src/theme/sticky-menu.scss +50 -0
  86. package/src/types.d.ts +102 -0
  87. package/tsconfig.json +1 -1
  88. package/src/components/Footer/Footer.jsx +0 -115
  89. package/src/components/Footer/FooterLinks.tsx +0 -57
  90. package/src/components/Header/Header.jsx +0 -161
  91. package/src/components/Logo/Logo.jsx +0 -51
  92. package/src/components/Widgets/AlignWidget.jsx +0 -80
  93. package/src/components/Widgets/BackgroundColorWidget.tsx +0 -17
  94. package/src/components/Widgets/BlocksObjectWidget.tsx +0 -333
  95. package/src/components/Widgets/FooterLinksWidget.tsx +0 -106
  96. package/src/components/Widgets/FooterLogosWidget.tsx +0 -120
  97. package/src/static/container-query-polyfill.modern.js +0 -1
  98. package/src/types/index.d.ts +0 -1
@@ -1,57 +0,0 @@
1
- import isEmpty from 'lodash/isEmpty';
2
- import { addAppURL, flattenToAppURL } from '@plone/volto/helpers/Url/Url';
3
- import UniversalLink from '@plone/volto/components/manage/UniversalLink/UniversalLink';
4
- import type { BlocksData } from '@plone/types';
5
- import config from '@plone/volto/registry';
6
-
7
- type FooterLinksProps = { links: BlocksData; siteActions: any; lang: string };
8
-
9
- const FooterLinks = (props: FooterLinksProps) => {
10
- const { lang, links, siteActions } = props;
11
-
12
- return (
13
- <ul className="footer-links">
14
- {!isEmpty(links?.blocks)
15
- ? links.blocks_layout.items.map((itemId) => {
16
- const link = links.blocks[itemId];
17
-
18
- if (isEmpty(link) || !link.href) return null;
19
-
20
- const title = link.title || link.href[0]['title'];
21
- const href = flattenToAppURL(link.href[0]?.['@id']);
22
-
23
- if (!href) return null;
24
-
25
- return (
26
- <li className="item" key={href}>
27
- <UniversalLink href={href}>{title}</UniversalLink>
28
- </li>
29
- );
30
- })
31
- : siteActions?.length
32
- ? siteActions.map((item) => (
33
- <li className="item" key={item.id}>
34
- <UniversalLink
35
- className="item"
36
- href={
37
- config.settings.isMultilingual
38
- ? `/${lang}/${
39
- item.url
40
- ? flattenToAppURL(item.url)
41
- : addAppURL(item.id)
42
- }`
43
- : item.url
44
- ? flattenToAppURL(item.url)
45
- : addAppURL(item.id)
46
- }
47
- >
48
- {item?.title}
49
- </UniversalLink>
50
- </li>
51
- ))
52
- : null}
53
- </ul>
54
- );
55
- };
56
-
57
- export default FooterLinks;
@@ -1,161 +0,0 @@
1
- // SemanticUI-free pre-@plone/components
2
- import PropTypes from 'prop-types';
3
- import { useSelector } from 'react-redux';
4
- import { Container } from '@plone/components';
5
- import MobileNavigation from '../MobileNavigation/MobileNavigation';
6
- import { useIntl, defineMessages } from 'react-intl';
7
- import config from '@plone/volto/registry';
8
- import cx from 'classnames';
9
- import IntranetSearchWidget from '../SearchWidget/IntranetSearchWidget';
10
-
11
- import Anontools from '@plone/volto/components/theme/Anontools/Anontools';
12
- import LanguageSelector from '@plone/volto/components/theme/LanguageSelector/LanguageSelector';
13
- import Logo from '@plone/volto/components/theme/Logo/Logo';
14
- import Navigation from '@plone/volto/components/theme/Navigation/Navigation';
15
- import SearchWidget from '@plone/volto/components/theme/SearchWidget/SearchWidget';
16
- import UniversalLink from '@plone/volto/components/manage/UniversalLink/UniversalLink';
17
-
18
- import SlotRenderer from '@plone/volto/components/theme/SlotRenderer/SlotRenderer';
19
-
20
- const messages = defineMessages({
21
- siteLabel: {
22
- id: 'siteLabel',
23
- defaultMessage: ' ',
24
- },
25
- });
26
-
27
- const InternetHeader = ({ pathname, siteLabel, token, siteAction }) => {
28
- return (
29
- <>
30
- <div className="header">
31
- <div className="tools-wrapper">
32
- <LanguageSelector />
33
-
34
- <div className="tools">
35
- {!token && <Anontools />}
36
- {siteAction &&
37
- siteAction.map((item) => (
38
- <UniversalLink key={item.url} href={item.url}>
39
- {item.title}
40
- </UniversalLink>
41
- ))}
42
- </div>
43
- {siteLabel && (
44
- <div className="intranet">
45
- <p>{siteLabel}</p>
46
- </div>
47
- )}
48
- </div>
49
- <div className="logo-nav-wrapper">
50
- <div className="logo">
51
- <Logo />
52
- </div>
53
- <Navigation pathname={pathname} />
54
- <MobileNavigation pathname={pathname} />
55
- <div className="search-wrapper navigation-desktop">
56
- <div className="search">
57
- <SearchWidget />
58
- </div>
59
- </div>
60
- </div>
61
- </div>
62
- </>
63
- );
64
- };
65
-
66
- const IntranetHeader = ({ pathname, siteLabel, token, siteAction }) => {
67
- return (
68
- <>
69
- <div className="header">
70
- <div className="tools-wrapper">
71
- <LanguageSelector />
72
-
73
- <div className="tools">
74
- {!token && <Anontools />}
75
- {siteAction &&
76
- siteAction.map((item) => (
77
- <UniversalLink key={item.url} href={item.url}>
78
- {item.title}
79
- </UniversalLink>
80
- ))}
81
- </div>
82
- {siteLabel && (
83
- <div className="intranet">
84
- <p>{siteLabel}</p>
85
- </div>
86
- )}
87
- </div>
88
- <div className="logo-nav-wrapper">
89
- <div className="logo">
90
- <Logo />
91
- </div>
92
- <div className="search-wrapper">
93
- <div className="search">
94
- <IntranetSearchWidget />
95
- </div>
96
- </div>
97
- <Navigation pathname={pathname} />
98
- <MobileNavigation pathname={pathname} />
99
- </div>
100
- </div>
101
- </>
102
- );
103
- };
104
-
105
- const Header = (props) => {
106
- const { pathname } = props;
107
- let siteLabel = config.settings.siteLabel;
108
- const intranetHeader = config.settings.intranetHeader;
109
- const token = useSelector((state) => state.userSession.token);
110
- const content = useSelector((state) => state.content.data);
111
- const siteAction = useSelector(
112
- (state) => state.content.data?.['@components']?.actions?.site_actions,
113
- );
114
- const navRoot = useSelector((state) => state.navroot?.data?.navroot);
115
- const intl = useIntl();
116
- const translatedSiteLabel = intl.formatMessage(messages.siteLabel);
117
-
118
- siteLabel =
119
- siteLabel &&
120
- (translatedSiteLabel !== 'siteLabel' && translatedSiteLabel !== ' '
121
- ? translatedSiteLabel
122
- : siteLabel);
123
-
124
- return (
125
- <>
126
- <SlotRenderer name="aboveHeader" content={content} navRoot={navRoot} />
127
- <header
128
- className={cx('header-wrapper', { 'intranet-header': intranetHeader })}
129
- >
130
- <Container layout>
131
- {intranetHeader ? (
132
- <IntranetHeader
133
- pathname={pathname}
134
- siteLabel={siteLabel}
135
- token={token}
136
- siteAction={siteAction}
137
- />
138
- ) : (
139
- <InternetHeader
140
- pathname={pathname}
141
- siteLabel={siteLabel}
142
- token={token}
143
- siteAction={siteAction}
144
- />
145
- )}
146
- </Container>
147
- </header>
148
- </>
149
- );
150
- };
151
-
152
- Header.propTypes = {
153
- token: PropTypes.string,
154
- pathname: PropTypes.string.isRequired,
155
- };
156
-
157
- Header.defaultProps = {
158
- token: null,
159
- };
160
-
161
- export default Header;
@@ -1,51 +0,0 @@
1
- // SemanticUI-free pre-@plone/components
2
- import { defineMessages, useIntl } from 'react-intl';
3
- import { useSelector } from 'react-redux';
4
- import { Link } from 'react-router-dom';
5
- import LogoImage from '@plone/volto/components/theme/Logo/Logo.svg';
6
- import { flattenToAppURL } from '@plone/volto/helpers/Url/Url';
7
-
8
- const messages = defineMessages({
9
- home: {
10
- id: 'Home',
11
- defaultMessage: 'Home',
12
- },
13
- logoOf: {
14
- id: 'Logo of',
15
- defaultMessage: 'Logo of',
16
- },
17
- });
18
-
19
- const Logo = () => {
20
- const intl = useIntl();
21
- const site = useSelector((state) => state.site.data);
22
- const navroot = useSelector((state) => state.navroot.data);
23
- const navRootPath = flattenToAppURL(navroot?.navroot?.['@id']) || '/';
24
- const navRootLogo = navroot?.navroot?.logo?.download || null;
25
- const navRootLogoWidth = navroot?.navroot?.logo?.width || null;
26
- const navRootLogoHeight = navroot?.navroot?.logo?.height || null;
27
-
28
- return (
29
- <Link to={navRootPath} aria-label={intl.formatMessage(messages.home)}>
30
- <img
31
- src={
32
- navRootLogo
33
- ? flattenToAppURL(navRootLogo)
34
- : site['plone.site_logo']
35
- ? flattenToAppURL(site['plone.site_logo'])
36
- : LogoImage
37
- }
38
- width={navRootLogoWidth}
39
- height={navRootLogoHeight}
40
- alt={
41
- intl.formatMessage(messages.logoOf) + ' ' + site['plone.site_title']
42
- }
43
- title={
44
- intl.formatMessage(messages.logoOf) + ' ' + site['plone.site_title']
45
- }
46
- />
47
- </Link>
48
- );
49
- };
50
-
51
- export default Logo;
@@ -1,80 +0,0 @@
1
- import React from 'react';
2
- import { defineMessages, useIntl } from 'react-intl';
3
- import { FormFieldWrapper } from '@plone/volto/components/manage/Widgets/FormFieldWrapper';
4
- import Icon from '@plone/volto/components/theme/Icon/Icon';
5
- import { Button } from 'semantic-ui-react';
6
- import imageLeftSVG from '@plone/volto/icons/image-left.svg';
7
- import imageRightSVG from '@plone/volto/icons/image-right.svg';
8
- import imageFitSVG from '@plone/volto/icons/image-fit.svg';
9
- import imageWideSVG from '@plone/volto/icons/image-wide.svg';
10
- import imageFullSVG from '@plone/volto/icons/image-full.svg';
11
-
12
- const messages = defineMessages({
13
- left: {
14
- id: 'Left',
15
- defaultMessage: 'Left',
16
- },
17
- right: {
18
- id: 'Right',
19
- defaultMessage: 'Right',
20
- },
21
- center: {
22
- id: 'Center',
23
- defaultMessage: 'Center',
24
- },
25
- wide: {
26
- id: 'Wide',
27
- defaultMessage: 'Wide',
28
- },
29
- full: {
30
- id: 'Full',
31
- defaultMessage: 'Full',
32
- },
33
- });
34
-
35
- const AlignWidget = (props) => {
36
- const intl = useIntl();
37
-
38
- const {
39
- id,
40
- onChange,
41
- actions = ['left', 'right', 'center', 'full'],
42
- value,
43
- } = props;
44
-
45
- React.useEffect(() => {
46
- if (!props.value && props.default) {
47
- props.onChange(props.id, props.default);
48
- }
49
- });
50
-
51
- const ICON_MAP = {
52
- left: imageLeftSVG,
53
- right: imageRightSVG,
54
- center: imageFitSVG,
55
- wide: imageWideSVG,
56
- full: imageFullSVG,
57
- };
58
-
59
- return (
60
- <FormFieldWrapper {...props} className="align-widget">
61
- <div className="align-buttons">
62
- {actions.map((action) => (
63
- <Button.Group key={action}>
64
- <Button
65
- icon
66
- basic
67
- aria-label={intl.formatMessage(messages[action])}
68
- onClick={() => onChange(id, action)}
69
- active={(action === 'center' && !value) || value === action}
70
- >
71
- <Icon name={ICON_MAP[action]} size="24px" />
72
- </Button>
73
- </Button.Group>
74
- ))}
75
- </div>
76
- </FormFieldWrapper>
77
- );
78
- };
79
-
80
- export default AlignWidget;
@@ -1,17 +0,0 @@
1
- import ColorPickerWidget from '@plone/volto/components/manage/Widgets/ColorPickerWidget';
2
- import config from '@plone/volto/registry';
3
- import type { ColorPickerWidgetProps } from '@plone/volto/components/manage/Widgets/ColorPickerWidget';
4
-
5
- const BackgroundColorWidget = (props: ColorPickerWidgetProps) => {
6
- const colors: ColorPickerWidgetProps['colors'] = config.blocks.themes;
7
-
8
- const defaultValue = colors.find(
9
- (color) => color.name === config.settings.defaultBackgroundColor,
10
- )?.style;
11
-
12
- return (
13
- <ColorPickerWidget {...props} default={defaultValue} colors={colors} />
14
- );
15
- };
16
-
17
- export default BackgroundColorWidget;
@@ -1,333 +0,0 @@
1
- import { useState } from 'react';
2
- import { defineMessages, useIntl } from 'react-intl';
3
- import omit from 'lodash/omit';
4
- import { Accordion, Button, Segment } from 'semantic-ui-react';
5
- import DragDropList from '@plone/volto/components/manage/DragDropList/DragDropList';
6
- import Icon from '@plone/volto/components/theme/Icon/Icon';
7
- import FormFieldWrapper from '@plone/volto/components/manage/Widgets/FormFieldWrapper';
8
- import { applySchemaDefaults } from '@plone/volto/helpers/Blocks/Blocks';
9
- import ObjectWidget from '@plone/volto/components/manage/Widgets/ObjectWidget';
10
- import {
11
- getBlocksFieldname,
12
- getBlocksLayoutFieldname,
13
- moveBlock,
14
- } from '@plone/volto/helpers/Blocks/Blocks';
15
-
16
- import upSVG from '@plone/volto/icons/up-key.svg';
17
- import downSVG from '@plone/volto/icons/down-key.svg';
18
- import deleteSVG from '@plone/volto/icons/delete.svg';
19
- import addSVG from '@plone/volto/icons/add.svg';
20
- import dragSVG from '@plone/volto/icons/drag.svg';
21
- import { v4 as uuid } from 'uuid';
22
- import type { BlocksData } from '@plone/types';
23
-
24
- const messages = defineMessages({
25
- labelRemoveItem: {
26
- id: 'Remove item',
27
- defaultMessage: 'Remove item',
28
- },
29
- labelCollapseItem: {
30
- id: 'Collapse item',
31
- defaultMessage: 'Collapse item',
32
- },
33
- labelShowItem: {
34
- id: 'Show item',
35
- defaultMessage: 'Show item',
36
- },
37
- emptyObjectList: {
38
- id: 'Empty object list',
39
- defaultMessage: 'Empty object list',
40
- },
41
- add: {
42
- id: 'Add (object list)',
43
- defaultMessage: 'Add',
44
- },
45
- });
46
-
47
- export type BlocksObjectWidgetProps = {
48
- id: string;
49
- block: string;
50
- fieldSet: string;
51
- title: string;
52
- value?: BlocksData;
53
- default?: string | object;
54
- required?: boolean;
55
- missing_value?: unknown;
56
- className?: string;
57
- onChange: (id: string, value: any) => void;
58
- activeObject: number;
59
- setActiveObject: (index: number) => void;
60
- };
61
-
62
- function deleteBlock(formData, blockId: string) {
63
- const blocksFieldname = getBlocksFieldname(formData);
64
- const blocksLayoutFieldname = getBlocksLayoutFieldname(formData);
65
-
66
- let newFormData = {
67
- ...formData,
68
- [blocksLayoutFieldname]: {
69
- items: formData[blocksLayoutFieldname].items.filter(
70
- (value) => value !== blockId,
71
- ),
72
- },
73
- [blocksFieldname]: omit(formData[blocksFieldname], [blockId]),
74
- };
75
-
76
- return newFormData;
77
- }
78
-
79
- /**
80
- * This is a DataGridField-equivalent widget for schema-based values.
81
- * The shape of the items in the array is defined using a schema.
82
- *
83
- * ObjectListWidget can receive an optional `schemaExtender` prop which is
84
- * a function that can mutate the schema for each individual item in the array.
85
- * An example schema definition of the a field that renders with the
86
- * ObjectListWidget:
87
- *
88
- * ```jsx
89
- * columns: {
90
- * title: 'Columns',
91
- * description: 'Leave empty to show all columns',
92
- * schema: SomeItemSchema,
93
- * widget: 'object_list',
94
- * schemaExtender: (schema, data) => {
95
- * const mutated = lodash.cloneDeep(schema);
96
- * mutated.properties.extraField = {
97
- * title: 'Extra field',
98
- * }
99
- * mutated.fieldsets[0].fields.push('extraField');
100
- * return mutated;
101
- * },
102
- * activeObject: 0, // Current active object drilled down from the schema (if present)
103
- * setActiveObject: () => {} // The current active object state updater function drilled down from the schema (if present)
104
- * },
105
- * ```
106
- */
107
- const ObjectListWidget = (props: BlocksObjectWidgetProps) => {
108
- const { block, fieldSet, id, schema, value, onChange, schemaExtender } =
109
- props;
110
- const [localActiveObject, setLocalActiveObject] = useState(
111
- props.activeObject ?? value?.blocks_layout?.items?.length - 1,
112
- );
113
-
114
- let activeObject: number, setActiveObject: (index: number) => void;
115
- if (
116
- (props.activeObject || props.activeObject === 0) &&
117
- props.setActiveObject
118
- ) {
119
- activeObject = props.activeObject;
120
- setActiveObject = props.setActiveObject;
121
- } else {
122
- activeObject = localActiveObject;
123
- setActiveObject = setLocalActiveObject;
124
- }
125
-
126
- const intl = useIntl();
127
-
128
- function handleChangeActiveObject(e, blockProps) {
129
- const { index } = blockProps;
130
- const newIndex = activeObject === index ? -1 : index;
131
-
132
- setActiveObject(newIndex);
133
- }
134
- const objectSchema = typeof schema === 'function' ? schema(props) : schema;
135
-
136
- const topLayerShadow = '0 1px 1px rgba(0,0,0,0.15)';
137
- const secondLayer = ', 0 10px 0 -5px #eee, 0 10px 1px -4px rgba(0,0,0,0.15)';
138
- const thirdLayer = ', 0 20px 0 -10px #eee, 0 20px 1px -9px rgba(0,0,0,0.15)';
139
-
140
- return (
141
- <div className="objectlist-widget">
142
- <FormFieldWrapper {...props} noForInFieldLabel className="objectlist">
143
- <div className="add-item-button-wrapper">
144
- <Button
145
- compact
146
- icon
147
- aria-label={
148
- objectSchema.addMessage ||
149
- `${intl.formatMessage(messages.add)} ${objectSchema.title}`
150
- }
151
- onClick={(e) => {
152
- e.preventDefault();
153
- const newId = uuid();
154
- const data = {};
155
-
156
- const objSchema = schemaExtender
157
- ? schemaExtender(schema, data, intl)
158
- : objectSchema;
159
- const dataWithDefaults = applySchemaDefaults({
160
- data,
161
- schema: objSchema,
162
- intl,
163
- });
164
-
165
- onChange(id, {
166
- ...(value || {}),
167
- blocks: {
168
- ...value?.blocks,
169
- [newId]: dataWithDefaults,
170
- },
171
- blocks_layout: {
172
- ...value?.blocks_layout,
173
- items: [...(value?.blocks_layout?.items || []), newId],
174
- },
175
- });
176
-
177
- setActiveObject(value?.blocks_layout?.items?.length || 0);
178
- }}
179
- >
180
- <Icon name={addSVG} size="18px" />
181
- &nbsp;
182
- {/* Custom addMessage in schema, else default to English */}
183
- {objectSchema.addMessage ||
184
- `${intl.formatMessage(messages.add)} ${objectSchema.title}`}
185
- </Button>
186
- </div>
187
- {value?.blocks_layout?.items?.length === 0 && (
188
- <input
189
- aria-labelledby={`fieldset-${
190
- fieldSet || 'default'
191
- }-field-label-${id}`}
192
- type="hidden"
193
- value={intl.formatMessage(messages.emptyObjectList)}
194
- />
195
- )}
196
- </FormFieldWrapper>
197
- {/* {value?.blocks_layout?.items.map((blockId, index) => {
198
- const blockData = value?.blocks[blockId];
199
- return (
200
- <ObjectWidget
201
- id={`${blockId}-${index}`}
202
- key={`ow-${blockId}-${index}`}
203
- block={block}
204
- schema={
205
- schemaExtender
206
- ? schemaExtender(schema, blockData, intl)
207
- : objectSchema
208
- }
209
- value={blockData}
210
- onChange={(fi, fv) => {
211
- const changedBlockId = fi.slice(0, -2);
212
- const newvalue = { ...value.blocks[changedBlockId], ...fv };
213
- onChange(id, {
214
- ...value,
215
- blocks: { ...value.blocks, [changedBlockId]: newvalue },
216
- });
217
- }}
218
- />
219
- );
220
- })} */}
221
- <DragDropList
222
- style={{
223
- boxShadow: `${topLayerShadow}${value?.blocks_layout?.items?.length > 1 ? secondLayer : ''}${
224
- value?.blocks_layout?.items?.length > 2 ? thirdLayer : ''
225
- }`,
226
- }}
227
- forwardedAriaLabelledBy={`fieldset-${
228
- fieldSet || 'default'
229
- }-field-label-${id}`}
230
- childList={
231
- value?.blocks_layout?.items?.map((blockId) => [
232
- blockId,
233
- value.blocks[blockId],
234
- ]) || []
235
- }
236
- onMoveItem={(result) => {
237
- const { source, destination } = result;
238
- if (!destination) {
239
- return;
240
- }
241
- const newFormData = moveBlock(value, source.index, destination.index);
242
- onChange(id, newFormData);
243
- return true;
244
- }}
245
- >
246
- {({ child, childId, index, draginfo }) => {
247
- return (
248
- <div
249
- ref={draginfo.innerRef}
250
- {...draginfo.draggableProps}
251
- key={childId}
252
- >
253
- <Accordion key={index} fluid styled>
254
- <Accordion.Title
255
- active={activeObject === index}
256
- index={index}
257
- onClick={handleChangeActiveObject}
258
- aria-label={`${
259
- activeObject === index
260
- ? intl.formatMessage(messages.labelCollapseItem)
261
- : intl.formatMessage(messages.labelShowItem)
262
- } #${index + 1}`}
263
- >
264
- <button
265
- style={{
266
- visibility: 'visible',
267
- display: 'inline-block',
268
- }}
269
- {...draginfo.dragHandleProps}
270
- className="drag handle"
271
- >
272
- <Icon name={dragSVG} size="18px" />
273
- </button>
274
-
275
- <div className="accordion-title-wrapper">
276
- {`${objectSchema.title} #${index + 1}`}
277
- </div>
278
- <div className="accordion-tools">
279
- <button
280
- aria-label={`${intl.formatMessage(
281
- messages.labelRemoveItem,
282
- )} #${index + 1}`}
283
- onClick={() => {
284
- onChange(id, deleteBlock(value, childId));
285
- }}
286
- >
287
- <Icon name={deleteSVG} size="20px" color="#e40166" />
288
- </button>
289
- {activeObject === index ? (
290
- <Icon name={upSVG} size="20px" />
291
- ) : (
292
- <Icon name={downSVG} size="20px" />
293
- )}
294
- </div>
295
- </Accordion.Title>
296
- <Accordion.Content active={activeObject === index}>
297
- <Segment>
298
- <ObjectWidget
299
- id={`${childId}-${index}`}
300
- key={`ow-${childId}-${index}`}
301
- block={block}
302
- schema={
303
- schemaExtender
304
- ? schemaExtender(schema, child, intl)
305
- : objectSchema
306
- }
307
- value={child}
308
- onChange={(fi, fv) => {
309
- const changedBlockId = fi.slice(0, -2);
310
- const newvalue = {
311
- ...value.blocks[changedBlockId],
312
- ...fv,
313
- };
314
- onChange(id, {
315
- ...value,
316
- blocks: {
317
- ...value.blocks,
318
- [changedBlockId]: newvalue,
319
- },
320
- });
321
- }}
322
- />
323
- </Segment>
324
- </Accordion.Content>
325
- </Accordion>
326
- </div>
327
- );
328
- }}
329
- </DragDropList>
330
- </div>
331
- );
332
- };
333
- export default ObjectListWidget;