@plone/volto 19.0.0-alpha.35 → 19.0.0-alpha.37
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 +54 -0
- package/README.md +1 -1
- package/locales/af/LC_MESSAGES/volto.po +29 -13
- package/locales/af.json +1 -1
- package/locales/ar/LC_MESSAGES/volto.po +29 -13
- package/locales/ar.json +1 -1
- package/locales/bg/LC_MESSAGES/volto.po +29 -13
- package/locales/bg.json +1 -1
- package/locales/bn/LC_MESSAGES/volto.po +29 -13
- package/locales/bn.json +1 -1
- package/locales/ca/LC_MESSAGES/volto.po +32 -16
- package/locales/ca.json +1 -1
- package/locales/cs/LC_MESSAGES/volto.po +30 -14
- package/locales/cs.json +1 -1
- package/locales/cy/LC_MESSAGES/volto.po +29 -13
- package/locales/cy.json +1 -1
- package/locales/da/LC_MESSAGES/volto.po +29 -13
- package/locales/da.json +1 -1
- package/locales/de/LC_MESSAGES/volto.po +32 -16
- package/locales/de.json +1 -1
- package/locales/el/LC_MESSAGES/volto.po +29 -13
- package/locales/el.json +1 -1
- package/locales/en/LC_MESSAGES/volto.po +25 -10
- package/locales/en.json +1 -1
- package/locales/en_AU/LC_MESSAGES/volto.po +29 -13
- package/locales/en_AU.json +1 -1
- package/locales/en_GB/LC_MESSAGES/volto.po +29 -13
- package/locales/en_GB.json +1 -1
- package/locales/eo/LC_MESSAGES/volto.po +29 -13
- package/locales/eo.json +1 -1
- package/locales/es/LC_MESSAGES/volto.po +67 -52
- package/locales/es.json +1 -1
- package/locales/et/LC_MESSAGES/volto.po +29 -13
- package/locales/et.json +1 -1
- package/locales/eu/LC_MESSAGES/volto.po +55 -40
- package/locales/eu.json +1 -1
- package/locales/fa/LC_MESSAGES/volto.po +29 -13
- package/locales/fa.json +1 -1
- package/locales/fi/LC_MESSAGES/volto.po +30 -14
- package/locales/fi.json +1 -1
- package/locales/fr/LC_MESSAGES/volto.po +208 -193
- package/locales/fr.json +1 -1
- package/locales/fu/LC_MESSAGES/volto.po +29 -13
- package/locales/fu.json +1 -1
- package/locales/gl/LC_MESSAGES/volto.po +58 -43
- package/locales/gl.json +1 -1
- package/locales/he/LC_MESSAGES/volto.po +29 -13
- package/locales/he.json +1 -1
- package/locales/hi/LC_MESSAGES/volto.po +34 -18
- package/locales/hi.json +1 -1
- package/locales/hr/LC_MESSAGES/volto.po +30 -14
- package/locales/hr.json +1 -1
- package/locales/hu/LC_MESSAGES/volto.po +29 -13
- package/locales/hu.json +1 -1
- package/locales/hy/LC_MESSAGES/volto.po +29 -13
- package/locales/hy.json +1 -1
- package/locales/id/LC_MESSAGES/volto.po +29 -13
- package/locales/id.json +1 -1
- package/locales/it/LC_MESSAGES/volto.po +34 -18
- package/locales/it.json +1 -1
- package/locales/ja/LC_MESSAGES/volto.po +29 -13
- package/locales/ja.json +1 -1
- package/locales/ka/LC_MESSAGES/volto.po +29 -13
- package/locales/ka.json +1 -1
- package/locales/kn/LC_MESSAGES/volto.po +29 -13
- package/locales/kn.json +1 -1
- package/locales/ko/LC_MESSAGES/volto.po +29 -13
- package/locales/ko.json +1 -1
- package/locales/lt/LC_MESSAGES/volto.po +30 -14
- package/locales/lt.json +1 -1
- package/locales/lv/LC_MESSAGES/volto.po +29 -13
- package/locales/lv.json +1 -1
- package/locales/mi/LC_MESSAGES/volto.po +29 -13
- package/locales/mi.json +1 -1
- package/locales/mk/LC_MESSAGES/volto.po +29 -13
- package/locales/mk.json +1 -1
- package/locales/my/LC_MESSAGES/volto.po +29 -13
- package/locales/my.json +1 -1
- package/locales/nb_NO/LC_MESSAGES/volto.po +29 -13
- package/locales/nb_NO.json +1 -1
- package/locales/nl/LC_MESSAGES/volto.po +69 -53
- package/locales/nl.json +1 -1
- package/locales/nn/LC_MESSAGES/volto.po +29 -13
- package/locales/nn.json +1 -1
- package/locales/pl/LC_MESSAGES/volto.po +30 -14
- package/locales/pl.json +1 -1
- package/locales/pt/LC_MESSAGES/volto.po +30 -14
- package/locales/pt.json +1 -1
- package/locales/pt_BR/LC_MESSAGES/volto.po +54 -39
- package/locales/pt_BR.json +1 -1
- package/locales/rm/LC_MESSAGES/volto.po +29 -13
- package/locales/rm.json +1 -1
- package/locales/ro/LC_MESSAGES/volto.po +30 -15
- package/locales/ro.json +1 -1
- package/locales/ru/LC_MESSAGES/volto.po +30 -14
- package/locales/ru.json +1 -1
- package/locales/sk/LC_MESSAGES/volto.po +30 -14
- package/locales/sk.json +1 -1
- package/locales/sl/LC_MESSAGES/volto.po +29 -13
- package/locales/sl.json +1 -1
- package/locales/sm/LC_MESSAGES/volto.po +29 -13
- package/locales/sm.json +1 -1
- package/locales/sq/LC_MESSAGES/volto.po +29 -13
- package/locales/sq.json +1 -1
- package/locales/sr/LC_MESSAGES/volto.po +30 -14
- package/locales/sr.json +1 -1
- package/locales/sr@cyrl/LC_MESSAGES/volto.po +29 -13
- package/locales/sr@cyrl.json +1 -1
- package/locales/sr@latn/LC_MESSAGES/volto.po +29 -13
- package/locales/sr@latn.json +1 -1
- package/locales/sv/LC_MESSAGES/volto.po +31 -15
- package/locales/sv.json +1 -1
- package/locales/ta/LC_MESSAGES/volto.po +30 -15
- package/locales/ta.json +1 -1
- package/locales/te/LC_MESSAGES/volto.po +29 -13
- package/locales/te.json +1 -1
- package/locales/th/LC_MESSAGES/volto.po +29 -13
- package/locales/th.json +1 -1
- package/locales/to/LC_MESSAGES/volto.po +29 -13
- package/locales/to.json +1 -1
- package/locales/tr/LC_MESSAGES/volto.po +29 -14
- package/locales/tr.json +1 -1
- package/locales/uk/LC_MESSAGES/volto.po +30 -14
- package/locales/uk.json +1 -1
- package/locales/vi/LC_MESSAGES/volto.po +29 -13
- package/locales/vi.json +1 -1
- package/locales/volto.pot +26 -11
- package/locales/zh_CN/LC_MESSAGES/volto.po +29 -14
- package/locales/zh_CN.json +1 -1
- package/locales/zh_Hant/LC_MESSAGES/volto.po +29 -13
- package/locales/zh_Hant.json +1 -1
- package/locales/zh_Hant_HK/LC_MESSAGES/volto.po +29 -13
- package/locales/zh_Hant_HK.json +1 -1
- package/package.json +10 -10
- package/src/components/manage/Add/Add.test.jsx +10 -3
- package/src/components/manage/Aliases/Aliases.test.jsx +5 -2
- package/src/components/manage/BlockChooser/BlockChooser.jsx +7 -10
- package/src/components/manage/Blocks/Block/Edit.jsx +19 -10
- package/src/components/manage/Blocks/Block/Order/Item.jsx +9 -4
- package/src/components/manage/Contents/Contents.test.jsx +7 -4
- package/src/components/manage/Contents/DropZoneContent.jsx +1 -0
- package/src/components/manage/Controlpanels/AddonsControlpanel.test.jsx +7 -4
- package/src/components/manage/Controlpanels/Aliases.test.jsx +7 -4
- package/src/components/manage/Controlpanels/BlockType.tsx +2 -3
- package/src/components/manage/Controlpanels/ContentType.test.jsx +12 -9
- package/src/components/manage/Controlpanels/ContentTypeLayout.test.jsx +12 -9
- package/src/components/manage/Controlpanels/ContentTypes.jsx +9 -2
- package/src/components/manage/Controlpanels/ContentTypes.test.jsx +7 -4
- package/src/components/manage/Controlpanels/Controlpanel.test.jsx +7 -4
- package/src/components/manage/Controlpanels/Controlpanels.test.jsx +13 -8
- package/src/components/manage/Controlpanels/Groups/GroupsControlpanel.test.jsx +7 -4
- package/src/components/manage/Controlpanels/ModerateComments.test.jsx +7 -4
- package/src/components/manage/Controlpanels/Rules/AddRule.test.jsx +7 -4
- package/src/components/manage/Controlpanels/Rules/ConfigureRule.test.jsx +9 -6
- package/src/components/manage/Controlpanels/Rules/EditRule.test.jsx +7 -4
- package/src/components/manage/Controlpanels/Rules/Rules.test.jsx +7 -4
- package/src/components/manage/Controlpanels/UndoControlpanel.test.jsx +7 -4
- package/src/components/manage/Controlpanels/Users/UserGroupMembershipControlPanel.test.jsx +7 -4
- package/src/components/manage/Controlpanels/Users/UsersControlpanel.jsx +58 -5
- package/src/components/manage/Controlpanels/Users/UsersControlpanel.ssr.test.jsx +624 -0
- package/src/components/manage/Controlpanels/Users/UsersControlpanel.test.jsx +21 -8
- package/src/components/manage/Delete/Delete.test.jsx +13 -8
- package/src/components/manage/Diff/Diff.test.jsx +7 -4
- package/src/components/manage/Edit/Edit.test.jsx +11 -6
- package/src/components/manage/Form/Form.jsx +6 -1
- package/src/components/manage/Form/ModalForm.jsx +164 -88
- package/src/components/manage/History/History.test.jsx +15 -8
- package/src/components/manage/LinksToItem/LinksToItem.test.jsx +7 -4
- package/src/components/manage/Multilingual/ManageTranslations.test.jsx +15 -12
- package/src/components/manage/Preferences/ChangePassword.test.jsx +7 -4
- package/src/components/manage/Preferences/PersonalPreferences.test.jsx +9 -6
- package/src/components/manage/Rules/Rules.test.jsx +5 -2
- package/src/components/manage/Sharing/Sharing.test.jsx +9 -6
- package/src/components/manage/Sidebar/ObjectBrowser.jsx +7 -0
- package/src/components/manage/Sidebar/ObjectBrowserBody.jsx +7 -3
- package/src/components/manage/Sidebar/ObjectBrowserBody.test.jsx +52 -0
- package/src/components/manage/Sidebar/Sidebar.jsx +2 -0
- package/src/components/manage/Sidebar/Sidebar.test.jsx +4 -1
- package/src/components/manage/Toolbar/Toolbar.jsx +89 -7
- package/src/components/manage/Toolbar/Toolbar.test.jsx +15 -10
- package/src/components/manage/Widgets/FormFieldWrapper.jsx +7 -5
- package/src/components/manage/Widgets/ObjectBrowserWidget.jsx +1 -0
- package/src/components/manage/Widgets/QuerystringWidget.test.jsx +3 -1
- package/src/components/manage/Widgets/TextWidget.jsx +4 -0
- package/src/components/manage/Widgets/TokenWidget.jsx +142 -186
- package/src/components/theme/App/App.test.jsx +13 -10
- package/src/components/theme/ContactForm/ContactForm.test.jsx +13 -8
- package/src/components/theme/MultilingualRedirector/MultilingualRedirector.test.jsx +6 -3
- package/src/components/theme/Search/Search.jsx +218 -328
- package/src/components/theme/Search/Search.test.jsx +14 -14
- package/src/components/theme/Sitemap/Sitemap.jsx +22 -30
- package/src/components/theme/Sitemap/Sitemap.test.jsx +18 -0
- package/src/components/theme/Unauthorized/Unauthorized.jsx +23 -30
- package/src/components/theme/Unauthorized/Unauthorized.test.jsx +6 -4
- package/src/components/theme/View/View.test.jsx +37 -24
- package/src/config/index.js +1 -0
- package/src/helpers/Api/Api.js +2 -2
- package/src/helpers/I18n/I18n.test.ts +44 -0
- package/src/helpers/I18n/I18n.ts +31 -0
- package/src/helpers/Robots/Robots.js +1 -1
- package/src/helpers/Robots/Robots.test.js +34 -0
- package/src/helpers/index.js +1 -0
- package/theme/themes/pastanaga/collections/form.overrides +21 -0
- package/theme/themes/pastanaga/elements/button.overrides +30 -3
- package/types/components/manage/Controlpanels/Relations/RelationsMatrix.d.ts +1 -1
- package/types/components/manage/Controlpanels/Users/UsersControlpanel.d.ts +2 -6
- package/types/components/manage/Controlpanels/Users/UsersControlpanel.ssr.test.d.ts +1 -0
- package/types/components/manage/Controlpanels/index.d.ts +1 -1
- package/types/components/manage/Multilingual/ManageTranslations.d.ts +1 -1
- package/types/components/manage/Sidebar/ObjectBrowser.d.ts +1 -1
- package/types/components/manage/Sidebar/ObjectBrowserBody.test.d.ts +1 -0
- package/types/components/manage/Widgets/ImageWidget.d.ts +1 -1
- package/types/components/manage/Widgets/InternalUrlWidget.d.ts +1 -1
- package/types/components/manage/Widgets/UrlWidget.d.ts +1 -1
- package/types/components/manage/Widgets/index.d.ts +2 -2
- package/types/components/theme/Search/Search.d.ts +1 -1
- package/types/helpers/I18n/I18n.d.ts +20 -0
- package/types/helpers/index.d.ts +1 -0
|
@@ -84,6 +84,7 @@ class ObjectBrowserBody extends Component {
|
|
|
84
84
|
onSelectItem: PropTypes.func,
|
|
85
85
|
dataName: PropTypes.string,
|
|
86
86
|
maximumSelectionSize: PropTypes.number,
|
|
87
|
+
initialPath: PropTypes.string,
|
|
87
88
|
contextURL: PropTypes.string,
|
|
88
89
|
searchableTypes: PropTypes.arrayOf(PropTypes.string),
|
|
89
90
|
onlyFolderishSelectable: PropTypes.bool,
|
|
@@ -113,18 +114,21 @@ class ObjectBrowserBody extends Component {
|
|
|
113
114
|
*/
|
|
114
115
|
constructor(props) {
|
|
115
116
|
super(props);
|
|
117
|
+
const defaultMultiplePath = props.initialPath || '/';
|
|
116
118
|
this.state = {
|
|
117
119
|
currentFolder:
|
|
118
|
-
this.props.mode === 'multiple'
|
|
120
|
+
this.props.mode === 'multiple'
|
|
121
|
+
? defaultMultiplePath
|
|
122
|
+
: this.props.contextURL || '/',
|
|
119
123
|
currentImageFolder:
|
|
120
124
|
this.props.mode === 'multiple'
|
|
121
|
-
?
|
|
125
|
+
? defaultMultiplePath
|
|
122
126
|
: this.props.mode === 'image' && this.props.data?.url
|
|
123
127
|
? getParentURL(this.props.data.url)
|
|
124
128
|
: '/',
|
|
125
129
|
currentLinkFolder:
|
|
126
130
|
this.props.mode === 'multiple'
|
|
127
|
-
?
|
|
131
|
+
? defaultMultiplePath
|
|
128
132
|
: this.props.mode === 'link' && this.props.data?.href
|
|
129
133
|
? getParentURL(this.props.data.href)
|
|
130
134
|
: '/',
|
|
@@ -0,0 +1,52 @@
|
|
|
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 ObjectBrowserBody from './ObjectBrowserBody';
|
|
6
|
+
|
|
7
|
+
const mockStore = configureStore();
|
|
8
|
+
|
|
9
|
+
const baseState = {
|
|
10
|
+
search: { subrequests: {} },
|
|
11
|
+
intl: { locale: 'en', messages: {} },
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
const baseProps = {
|
|
15
|
+
block: 'test-block',
|
|
16
|
+
data: {},
|
|
17
|
+
closeObjectBrowser: () => {},
|
|
18
|
+
onChangeBlock: () => {},
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
const getInitialSearchPath = (actions) => {
|
|
22
|
+
const action = actions.find((a) => a.type === 'SEARCH_CONTENT');
|
|
23
|
+
return action?.request?.path?.split('/@search')[0];
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
describe('ObjectBrowserBody', () => {
|
|
27
|
+
it('uses initialPath as the default folder when mode=multiple', () => {
|
|
28
|
+
const store = mockStore(baseState);
|
|
29
|
+
render(
|
|
30
|
+
<Provider store={store}>
|
|
31
|
+
<ObjectBrowserBody
|
|
32
|
+
{...baseProps}
|
|
33
|
+
mode="multiple"
|
|
34
|
+
initialPath="/company/team"
|
|
35
|
+
/>
|
|
36
|
+
</Provider>,
|
|
37
|
+
);
|
|
38
|
+
|
|
39
|
+
expect(getInitialSearchPath(store.getActions())).toBe('/company/team');
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
it('defaults to root when mode=multiple and initialPath is not provided', () => {
|
|
43
|
+
const store = mockStore(baseState);
|
|
44
|
+
render(
|
|
45
|
+
<Provider store={store}>
|
|
46
|
+
<ObjectBrowserBody {...baseProps} mode="multiple" />
|
|
47
|
+
</Provider>,
|
|
48
|
+
);
|
|
49
|
+
|
|
50
|
+
expect(getInitialSearchPath(store.getActions())).toBe('/');
|
|
51
|
+
});
|
|
52
|
+
});
|
|
@@ -155,6 +155,7 @@ const Sidebar = (props) => {
|
|
|
155
155
|
key: 'documentTab',
|
|
156
156
|
as: 'button',
|
|
157
157
|
className: 'ui button',
|
|
158
|
+
type: 'button',
|
|
158
159
|
content: type || intl.formatMessage(messages.document),
|
|
159
160
|
},
|
|
160
161
|
pane: (
|
|
@@ -170,6 +171,7 @@ const Sidebar = (props) => {
|
|
|
170
171
|
key: 'blockTab',
|
|
171
172
|
as: 'button',
|
|
172
173
|
className: 'ui button',
|
|
174
|
+
type: 'button',
|
|
173
175
|
content: intl.formatMessage(messages.block),
|
|
174
176
|
},
|
|
175
177
|
pane: (
|
|
@@ -2,6 +2,7 @@ import React from 'react';
|
|
|
2
2
|
import renderer from 'react-test-renderer';
|
|
3
3
|
import configureStore from 'redux-mock-store';
|
|
4
4
|
import { Provider } from 'react-intl-redux';
|
|
5
|
+
import { CookiesProvider } from 'react-cookie';
|
|
5
6
|
|
|
6
7
|
import Sidebar from './Sidebar';
|
|
7
8
|
|
|
@@ -22,7 +23,9 @@ test('renders a sidebar component', () => {
|
|
|
22
23
|
});
|
|
23
24
|
const component = renderer.create(
|
|
24
25
|
<Provider store={store}>
|
|
25
|
-
<
|
|
26
|
+
<CookiesProvider>
|
|
27
|
+
<Sidebar />
|
|
28
|
+
</CookiesProvider>
|
|
26
29
|
</Provider>,
|
|
27
30
|
);
|
|
28
31
|
const json = component.toJSON();
|
|
@@ -108,6 +108,18 @@ const messages = defineMessages({
|
|
|
108
108
|
id: 'Unlock',
|
|
109
109
|
defaultMessage: 'Unlock',
|
|
110
110
|
},
|
|
111
|
+
menuOpened: {
|
|
112
|
+
id: 'Menu opened',
|
|
113
|
+
defaultMessage: 'Menu opened',
|
|
114
|
+
},
|
|
115
|
+
menuClosed: {
|
|
116
|
+
id: 'Menu closed',
|
|
117
|
+
defaultMessage: 'Menu closed',
|
|
118
|
+
},
|
|
119
|
+
focusOn: {
|
|
120
|
+
id: 'Focus on',
|
|
121
|
+
defaultMessage: 'Focus on',
|
|
122
|
+
},
|
|
111
123
|
});
|
|
112
124
|
|
|
113
125
|
let toolbarComponents = {
|
|
@@ -185,6 +197,7 @@ class Toolbar extends Component {
|
|
|
185
197
|
toolbarRef = React.createRef();
|
|
186
198
|
toolbarWindow = React.createRef();
|
|
187
199
|
buttonRef = React.createRef();
|
|
200
|
+
announceRef = React.createRef();
|
|
188
201
|
|
|
189
202
|
constructor(props) {
|
|
190
203
|
super(props);
|
|
@@ -305,10 +318,40 @@ class Toolbar extends Component {
|
|
|
305
318
|
}
|
|
306
319
|
// PersonalTools always shows at bottom
|
|
307
320
|
if (selector === 'personalTools') {
|
|
308
|
-
this.setState(
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
321
|
+
this.setState(
|
|
322
|
+
(state) => ({
|
|
323
|
+
showMenu: !state.showMenu,
|
|
324
|
+
menuStyle: { bottom: 0 },
|
|
325
|
+
}),
|
|
326
|
+
() => {
|
|
327
|
+
// Scoped only to personalTools — does not affect other toolbar flows
|
|
328
|
+
const candidates =
|
|
329
|
+
this.toolbarWindow.current?.querySelectorAll(
|
|
330
|
+
'a, button, input, [tabindex]:not([tabindex="-1"])',
|
|
331
|
+
) ?? [];
|
|
332
|
+
const firstVisible = Array.from(candidates).find((el) => {
|
|
333
|
+
const style = window.getComputedStyle(el);
|
|
334
|
+
return style.display !== 'none' && style.visibility !== 'hidden';
|
|
335
|
+
});
|
|
336
|
+
firstVisible?.focus();
|
|
337
|
+
|
|
338
|
+
// Announce to screen readers: menu opened + which element received focus
|
|
339
|
+
if (this.announceRef.current) {
|
|
340
|
+
const focusedLabel =
|
|
341
|
+
firstVisible?.getAttribute('aria-label') ||
|
|
342
|
+
firstVisible?.textContent?.trim() ||
|
|
343
|
+
'';
|
|
344
|
+
this.announceRef.current.textContent = '';
|
|
345
|
+
setTimeout(() => {
|
|
346
|
+
if (this.announceRef.current) {
|
|
347
|
+
this.announceRef.current.textContent = focusedLabel
|
|
348
|
+
? `${this.props.intl.formatMessage(messages.menuOpened)}, ${this.props.intl.formatMessage(messages.focusOn)} ${focusedLabel}`
|
|
349
|
+
: this.props.intl.formatMessage(messages.menuOpened);
|
|
350
|
+
}
|
|
351
|
+
}, 100);
|
|
352
|
+
}
|
|
353
|
+
},
|
|
354
|
+
);
|
|
312
355
|
} else if (selector === 'more') {
|
|
313
356
|
this.setState((state) => ({
|
|
314
357
|
showMenu: !state.showMenu,
|
|
@@ -337,10 +380,22 @@ class Toolbar extends Component {
|
|
|
337
380
|
|
|
338
381
|
handleClickOutside = (e) => {
|
|
339
382
|
const target = e.target;
|
|
340
|
-
if (this.pusher && doesNodeContainClick(this.pusher, e)) return;
|
|
341
383
|
|
|
342
|
-
|
|
343
|
-
|
|
384
|
+
if (this.pusher && doesNodeContainClick(this.pusher, e)) {
|
|
385
|
+
return;
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
if (
|
|
389
|
+
this.toolbarRef.current &&
|
|
390
|
+
doesNodeContainClick(this.toolbarRef.current, e)
|
|
391
|
+
) {
|
|
392
|
+
return;
|
|
393
|
+
}
|
|
394
|
+
|
|
395
|
+
if (target.closest('.ui.modal') || target.closest('.ui.dimmer')) {
|
|
396
|
+
return;
|
|
397
|
+
}
|
|
398
|
+
|
|
344
399
|
const button =
|
|
345
400
|
doesNodeContainClick(this.toolbarRef.current, e) &&
|
|
346
401
|
this.findAncestor(target, 'button');
|
|
@@ -376,12 +431,39 @@ class Toolbar extends Component {
|
|
|
376
431
|
<BodyClass
|
|
377
432
|
className={expanded ? 'has-toolbar' : 'has-toolbar-collapsed'}
|
|
378
433
|
/>
|
|
434
|
+
<span
|
|
435
|
+
aria-live="assertive"
|
|
436
|
+
aria-atomic="true"
|
|
437
|
+
role="status"
|
|
438
|
+
className="visually-hidden"
|
|
439
|
+
ref={this.announceRef}
|
|
440
|
+
/>
|
|
379
441
|
<div
|
|
380
442
|
style={this.state.menuStyle}
|
|
381
443
|
className={
|
|
382
444
|
this.state.showMenu ? 'toolbar-content show' : 'toolbar-content'
|
|
383
445
|
}
|
|
384
446
|
ref={this.toolbarWindow}
|
|
447
|
+
onBlur={(e) => {
|
|
448
|
+
if (!this.toolbarWindow.current?.contains(e.relatedTarget)) {
|
|
449
|
+
this.toolbarRef.current
|
|
450
|
+
?.querySelector('button.toolbar-handler-button')
|
|
451
|
+
?.focus();
|
|
452
|
+
|
|
453
|
+
this.closeMenu();
|
|
454
|
+
|
|
455
|
+
if (this.announceRef.current) {
|
|
456
|
+
this.announceRef.current.textContent = '';
|
|
457
|
+
// Timeout to allow the screen reader to pick up the change in content after the menu is closed
|
|
458
|
+
setTimeout(() => {
|
|
459
|
+
if (this.announceRef.current) {
|
|
460
|
+
this.announceRef.current.textContent =
|
|
461
|
+
this.props.intl.formatMessage(messages.menuClosed);
|
|
462
|
+
}
|
|
463
|
+
}, 100);
|
|
464
|
+
}
|
|
465
|
+
}
|
|
466
|
+
}}
|
|
385
467
|
>
|
|
386
468
|
{this.state.showMenu && (
|
|
387
469
|
// This sets the scroll locker in the body tag in mobile
|
|
@@ -5,6 +5,7 @@ import { Provider } from 'react-intl-redux';
|
|
|
5
5
|
import { MemoryRouter } from 'react-router-dom';
|
|
6
6
|
import jwt from 'jsonwebtoken';
|
|
7
7
|
import thunk from 'redux-thunk';
|
|
8
|
+
import { CookiesProvider } from 'react-cookie';
|
|
8
9
|
import { PluggablesProvider } from '@plone/volto/components/manage/Pluggable';
|
|
9
10
|
|
|
10
11
|
import Toolbar from './Toolbar';
|
|
@@ -130,11 +131,13 @@ describe('Toolbar', () => {
|
|
|
130
131
|
});
|
|
131
132
|
const component = renderer.create(
|
|
132
133
|
<Provider store={store}>
|
|
133
|
-
<
|
|
134
|
-
<
|
|
135
|
-
<
|
|
136
|
-
|
|
137
|
-
|
|
134
|
+
<CookiesProvider>
|
|
135
|
+
<PluggablesProvider>
|
|
136
|
+
<MemoryRouter>
|
|
137
|
+
<Toolbar pathname="/test" inner={<span />} />
|
|
138
|
+
</MemoryRouter>
|
|
139
|
+
</PluggablesProvider>
|
|
140
|
+
</CookiesProvider>
|
|
138
141
|
</Provider>,
|
|
139
142
|
);
|
|
140
143
|
const json = component.toJSON();
|
|
@@ -264,11 +267,13 @@ describe('Toolbar', () => {
|
|
|
264
267
|
});
|
|
265
268
|
const component = renderer.create(
|
|
266
269
|
<Provider store={store}>
|
|
267
|
-
<
|
|
268
|
-
<
|
|
269
|
-
<
|
|
270
|
-
|
|
271
|
-
|
|
270
|
+
<CookiesProvider>
|
|
271
|
+
<PluggablesProvider>
|
|
272
|
+
<MemoryRouter>
|
|
273
|
+
<Toolbar pathname="/test" inner={<span />} />
|
|
274
|
+
</MemoryRouter>
|
|
275
|
+
</PluggablesProvider>
|
|
276
|
+
</CookiesProvider>
|
|
272
277
|
</Provider>,
|
|
273
278
|
);
|
|
274
279
|
const json = component.toJSON();
|
|
@@ -61,11 +61,13 @@ const FormFieldWrapper = ({
|
|
|
61
61
|
<>
|
|
62
62
|
{children}
|
|
63
63
|
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
{message}
|
|
67
|
-
|
|
68
|
-
|
|
64
|
+
<div aria-live="polite" aria-atomic="true">
|
|
65
|
+
{map(error, (message) => (
|
|
66
|
+
<Label key={message} basic color="red" className="form-error-label">
|
|
67
|
+
{message}
|
|
68
|
+
</Label>
|
|
69
|
+
))}
|
|
70
|
+
</div>
|
|
69
71
|
</>
|
|
70
72
|
);
|
|
71
73
|
|
|
@@ -307,6 +307,7 @@ export class ObjectBrowserWidgetComponent extends Component {
|
|
|
307
307
|
this.props.openObjectBrowser({
|
|
308
308
|
mode: this.props.mode,
|
|
309
309
|
currentPath: this.props.initialPath || this.props.location.pathname,
|
|
310
|
+
initialPath: this.props.initialPath,
|
|
310
311
|
propDataName: 'value',
|
|
311
312
|
onSelectItem: (url, item) => {
|
|
312
313
|
this.onChange(item);
|
|
@@ -19,6 +19,8 @@ const TextWidget = (props) => {
|
|
|
19
19
|
placeholder,
|
|
20
20
|
isDisabled,
|
|
21
21
|
focus,
|
|
22
|
+
required,
|
|
23
|
+
error,
|
|
22
24
|
} = props;
|
|
23
25
|
|
|
24
26
|
const ref = useRef();
|
|
@@ -49,6 +51,8 @@ const TextWidget = (props) => {
|
|
|
49
51
|
onClick={() => onClick()}
|
|
50
52
|
minLength={minLength || null}
|
|
51
53
|
maxLength={maxLength || null}
|
|
54
|
+
aria-required={required ? 'true' : undefined}
|
|
55
|
+
aria-invalid={error?.length > 0 ? 'true' : undefined}
|
|
52
56
|
/>
|
|
53
57
|
{icon && iconAction && (
|
|
54
58
|
<button className={`field-${id}-action-button`} onClick={iconAction}>
|