design-comuni-plone-theme 11.26.5 → 11.28.0

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 (66) hide show
  1. package/.yarn/cache/{volto-feedback-npm-0.5.2-c3471099a1-48c0763678.zip → volto-feedback-npm-0.6.0-42c860b5c3-49addbf819.zip} +0 -0
  2. package/.yarn/install-state.gz +0 -0
  3. package/CHANGELOG.md +55 -0
  4. package/RELEASE.md +33 -0
  5. package/locales/de/LC_MESSAGES/volto.po +104 -0
  6. package/locales/en/LC_MESSAGES/volto.po +105 -1
  7. package/locales/es/LC_MESSAGES/volto.po +104 -0
  8. package/locales/fr/LC_MESSAGES/volto.po +104 -0
  9. package/locales/it/LC_MESSAGES/volto.po +104 -0
  10. package/locales/volto.pot +105 -1
  11. package/package.json +2 -2
  12. package/publiccode.yml +2 -2
  13. package/src/components/ItaliaTheme/Blocks/Accordion/Block/ViewBlock.jsx +1 -0
  14. package/src/components/ItaliaTheme/Blocks/Listing/CardWithImage/CardWithImageDefault.jsx +1 -1
  15. package/src/components/ItaliaTheme/Blocks/Listing/CardWithSlideUpTextTemplate.jsx +23 -14
  16. package/src/components/ItaliaTheme/Blocks/Listing/Commons/ListingImage.jsx +17 -4
  17. package/src/components/ItaliaTheme/Blocks/Listing/CompleteBlockLinksTemplate.jsx +0 -1
  18. package/src/components/ItaliaTheme/Blocks/Listing/ContentInEvidenceTemplate.jsx +0 -1
  19. package/src/components/ItaliaTheme/Blocks/Listing/GridGalleryTemplate.jsx +4 -3
  20. package/src/components/ItaliaTheme/Blocks/Listing/InEvidenceTemplate.jsx +0 -1
  21. package/src/components/ItaliaTheme/Blocks/__tests__/Accordion.test.jsx +0 -3
  22. package/src/components/ItaliaTheme/Cards/CardPersona.jsx +1 -1
  23. package/src/components/ItaliaTheme/CustomerSatisfaction/FeedbackForm.jsx +25 -6
  24. package/src/components/ItaliaTheme/Header/HeaderSearch/HeaderSearch.jsx +9 -1
  25. package/src/components/ItaliaTheme/Header/HeaderSearch/SearchModal.jsx +10 -1
  26. package/src/components/ItaliaTheme/Header/HeaderSlim/HeaderSlim.jsx +15 -2
  27. package/src/components/ItaliaTheme/Header/HeaderSlim/TertiaryMenu.jsx +1 -1
  28. package/src/components/ItaliaTheme/Header/ParentSiteMenu.jsx +14 -1
  29. package/src/components/ItaliaTheme/SkipLinks/SkipLinks.jsx +9 -1
  30. package/src/components/ItaliaTheme/View/BandoView/BandoView.jsx +19 -1
  31. package/src/components/ItaliaTheme/View/Commons/PageHeader/PageHeader.jsx +3 -4
  32. package/src/components/ItaliaTheme/View/Commons/RelatedItemInEvidence/RelatedItemInEvidence.jsx +14 -1
  33. package/src/components/ItaliaTheme/View/Commons/RelatedItems.jsx +5 -1
  34. package/src/components/ItaliaTheme/View/Commons/SideMenu.jsx +10 -6
  35. package/src/components/ItaliaTheme/View/DocumentoView/DocumentoView.jsx +20 -1
  36. package/src/components/ItaliaTheme/View/EventoView/EventoView.jsx +20 -1
  37. package/src/components/ItaliaTheme/View/FAQ/FaqFolder/SearchBar.jsx +2 -0
  38. package/src/components/ItaliaTheme/View/NewsItemView/NewsItemView.jsx +19 -1
  39. package/src/components/ItaliaTheme/View/PaginaArgomentoView/PaginaArgomentoViewNoBlocks.jsx +14 -1
  40. package/src/components/ItaliaTheme/View/PersonaView/PersonaDocumenti.jsx +57 -20
  41. package/src/components/ItaliaTheme/View/PersonaView/PersonaView.jsx +20 -1
  42. package/src/components/ItaliaTheme/View/ServizioView/ServizioView.jsx +19 -2
  43. package/src/components/ItaliaTheme/View/UOView/UOView.jsx +20 -1
  44. package/src/components/ItaliaTheme/View/VenueView/VenueView.jsx +24 -11
  45. package/src/components/SelectInput/SelectInput.jsx +2 -1
  46. package/src/components/TextInput.jsx +1 -0
  47. package/src/config/Blocks/ListingOptions/cardWithSlideUpTextTemplate.js +1 -6
  48. package/src/config/italiaConfig.js +23 -2
  49. package/src/customizations/volto/components/manage/Blocks/Search/SearchBlockView.jsx +20 -1
  50. package/src/customizations/volto/components/manage/Blocks/Search/layout/LeftColumnFacets.jsx +21 -17
  51. package/src/customizations/volto/components/manage/Blocks/Search/layout/RightColumnFacets.jsx +21 -17
  52. package/src/customizations/volto/components/manage/Widgets/RecurrenceWidget/RecurrenceWidget.jsx +5 -2
  53. package/src/customizations/volto/components/theme/Footer/Footer.jsx +12 -5
  54. package/src/customizations/volto/components/theme/Navigation/Navigation.jsx +16 -2
  55. package/src/customizations/volto/helpers/FormValidation/FormValidation.js +8 -5
  56. package/src/customizations/volto-form-block/components/Field.jsx +7 -0
  57. package/src/customizations/volto-form-block/fieldSchema.js +345 -0
  58. package/src/overrideTranslations.jsx +4 -0
  59. package/src/theme/ItaliaTheme/Blocks/_cardWithImage.scss +1 -0
  60. package/src/theme/ItaliaTheme/Blocks/_cardWithSlideUpTextTemplate.scss +10 -0
  61. package/src/theme/ItaliaTheme/Blocks/_search.scss +20 -2
  62. package/src/theme/ItaliaTheme/Components/_cardPersona.scss +2 -0
  63. package/src/theme/ItaliaTheme/Views/_servizio.scss +6 -0
  64. package/src/theme/ItaliaTheme/_ar.scss +3 -2
  65. package/src/theme/bootstrap-override/_bootstrap-italia-site.scss +1 -0
  66. package/src/theme/bootstrap-override/bootstrap-italia/_form-select.scss +17 -0
@@ -25,6 +25,19 @@ import {
25
25
  useSideMenu,
26
26
  } from 'design-comuni-plone-theme/components/ItaliaTheme/View';
27
27
 
28
+ import { defineMessages, useIntl } from 'react-intl';
29
+
30
+ const messages = defineMessages({
31
+ sideMenuIndex: {
32
+ id: 'sideMenuIndex',
33
+ defaultMessage: 'Indice della pagina',
34
+ },
35
+ venueContent: {
36
+ id: 'venueContent',
37
+ defaultMessage: 'Informazioni sulla struttura',
38
+ },
39
+ });
40
+
28
41
  export const VenueViewSectionsOrder = [
29
42
  {
30
43
  /* HEADER IMAGE */
@@ -56,23 +69,18 @@ export const VenueViewSectionsOrder = [
56
69
  */
57
70
  const VenueView = ({ content }) => {
58
71
  const documentBody = createRef();
72
+ const intl = useIntl();
59
73
  const { sideMenuElements, SideMenu } = useSideMenu(content, documentBody);
60
74
 
61
- useEffect(() => {
62
- if (
63
- content.nome_alternativo &&
64
- !content.title?.includes(content.nome_alternativo)
65
- ) {
66
- content.subtitle = content.nome_alternativo;
67
- }
68
- });
69
-
70
75
  return (
71
76
  <>
72
77
  <div className="container px-4 my-4 luogo-view">
73
78
  <SkipToMainContent />
74
79
  <PageHeader
75
- content={content}
80
+ content={{
81
+ ...content,
82
+ subtitle: content.nome_alternativo,
83
+ }}
76
84
  readingtime={null}
77
85
  showreadingtime={false}
78
86
  showdates={false}
@@ -82,7 +90,10 @@ const VenueView = ({ content }) => {
82
90
  <ContentImage content={content} position="afterHeader" />
83
91
 
84
92
  <div className="row row-column-border border-light row-column-menu-left">
85
- <aside className="col-lg-4">
93
+ <aside
94
+ className="col-lg-4"
95
+ aria-label={intl.formatMessage(messages.sideMenuIndex)}
96
+ >
86
97
  {__CLIENT__ && (
87
98
  <SideMenu data={sideMenuElements} content_uid={content?.UID} />
88
99
  )}
@@ -91,6 +102,8 @@ const VenueView = ({ content }) => {
91
102
  className="col-lg-8 it-page-sections-container border-light"
92
103
  id="main-content-section"
93
104
  ref={documentBody}
105
+ role="region"
106
+ aria-label={intl.formatMessage(messages.venueContent)}
94
107
  >
95
108
  {/* SEZIONI */}
96
109
  <ContentTypeViewSections
@@ -326,6 +326,7 @@ const SelectInput = ({
326
326
  const Select = reactSelect.default;
327
327
  return (
328
328
  <div className="bootstrap-select-wrapper">
329
+ {label && <label htmlFor={!labelledby ? id : undefined}>{label}</label>}
329
330
  <Select
330
331
  components={{
331
332
  MenuList,
@@ -347,7 +348,7 @@ const SelectInput = ({
347
348
  isMulti={isMulti}
348
349
  isClearable={isClearable}
349
350
  aria-label={labelDefined}
350
- aria-labelledby={labelledby}
351
+ aria-labelledby={!label ? labelledby : undefined}
351
352
  aria-live="polite"
352
353
  ariaLiveMessages={getSelectAriaLiveMessages(intl)}
353
354
  noOptionsMessage={() =>
@@ -17,6 +17,7 @@ export default function TextInput(props) {
17
17
  groupClassName,
18
18
  ...otherProps
19
19
  } = props;
20
+
20
21
  const [isFocused, setIsFocused] = useState(false);
21
22
 
22
23
  const toggleFocusLabel = () => {
@@ -13,12 +13,7 @@ export const addCardWithSlideUpTextTemplateOptions = (
13
13
  ) => {
14
14
  let pos = position;
15
15
 
16
- // hidden to avoid use of lighthouse on this block
17
- // which creates problems with asseverazione
18
- // 1. clients instructed not to use this variation when data-element is needed
19
- // 2. planned intervention to change structure of variation to allow use of
20
- // data element without wrapping entire card in link
21
- // pos = addLighthouseField(schema, intl, pos);
16
+ pos = addLighthouseField(schema, intl, pos);
22
17
 
23
18
  pos = addDefaultOptions(schema, formData, intl, pos);
24
19
 
@@ -72,8 +72,8 @@ import {
72
72
  FALLBACK_IMAGE_SRC_MAX_W,
73
73
  } from 'design-comuni-plone-theme/helpers/images';
74
74
 
75
- const ReleaseLog = loadable(() =>
76
- import('design-comuni-plone-theme/components/ReleaseLog/ReleaseLog'),
75
+ const ReleaseLog = loadable(
76
+ () => import('design-comuni-plone-theme/components/ReleaseLog/ReleaseLog'),
77
77
  );
78
78
 
79
79
  const messages = defineMessages({
@@ -81,6 +81,14 @@ const messages = defineMessages({
81
81
  id: 'search_brdc',
82
82
  defaultMessage: 'Ricerca',
83
83
  },
84
+ auth_ft: {
85
+ id: 'auth_ft',
86
+ defaultMessage: 'Login/Logout',
87
+ },
88
+ sitemap_ft: {
89
+ id: 'sitemap_ft',
90
+ defaultMessage: 'Sitemap',
91
+ },
84
92
  });
85
93
 
86
94
  export default function applyConfig(voltoConfig) {
@@ -284,6 +292,7 @@ export default function applyConfig(voltoConfig) {
284
292
  },
285
293
  enableFeedbackForm: true,
286
294
  noFeedbackFormFor: ['ModelloPratica'],
295
+ enableNoFeedbackFormFor: false,
287
296
  enableFeedbackFormCaptcha: false,
288
297
  enableVoltoFormBlockCaptcha: true,
289
298
  splitMegamenuColumns: true, //se impostato a false, non spezza le colonne con intestazioni nel megamenu
@@ -360,6 +369,18 @@ export default function applyConfig(voltoConfig) {
360
369
  pane: CommentsStep,
361
370
  },
362
371
  ],
372
+ // Enable Feedback component in your CMS/Non content routes
373
+ feedbackEnabledNonContentRoutes: [
374
+ ...(config.settings['volto-feedback']
375
+ ?.feedbackEnabledNonContentRoutes ?? []),
376
+ {
377
+ path: '/login',
378
+ feedbackTitle: messages.auth_ft,
379
+ },
380
+ // { path: '/logout', feedbackTitle: messages.auth_ft },
381
+ { path: '/sitemap', feedbackTitle: messages.sitemap_ft },
382
+ { path: '/search', feedbackTitle: messages.search_brdc },
383
+ ],
363
384
  },
364
385
  videoAllowExternalsDefault: false,
365
386
  showTrasparenzaFields: false,
@@ -7,7 +7,7 @@
7
7
  the way to handle search sort. If searchableText is setted, discard default sorting and uses plone's ranking only if is configured from sidebar. (Changed applyDefaults fn passing usePloneRanking)
8
8
  */
9
9
 
10
- import React from 'react';
10
+ import React, { useState } from 'react';
11
11
 
12
12
  import ListingBody from '@plone/volto/components/manage/Blocks/Listing/ListingBody';
13
13
  import { withBlockExtensions } from '@plone/volto/helpers';
@@ -21,6 +21,7 @@ import cx from 'classnames';
21
21
  import { isEqual, isFunction } from 'lodash';
22
22
  import { useSelector } from 'react-redux';
23
23
  import { compose } from 'redux';
24
+ import { useEffect } from 'react';
24
25
 
25
26
  const getListingBodyVariation = (data) => {
26
27
  const { variations } = config.blocks.blocksConfig.listing;
@@ -109,9 +110,26 @@ const SearchBlockView = (props) => {
109
110
  }, [dataListingBodyVariation, mode]);
110
111
 
111
112
  const root = useSelector((state) => state.breadcrumbs.root);
113
+ const [defaultListingBodyData] = React.useState(
114
+ applyDefaults(searchData, root, data.usePloneRanking),
115
+ );
112
116
  const listingBodyData = applyDefaults(searchData, root, data.usePloneRanking);
117
+
113
118
  const { variations } = config.blocks.blocksConfig.listing;
114
119
  const listingBodyVariation = variations.find(({ id }) => id === selectedView);
120
+
121
+ const query = listingBodyData.query;
122
+ const resultsRef = React.forwardRef(null);
123
+
124
+ useEffect(() => {
125
+ if (
126
+ JSON.stringify(defaultListingBodyData.query) !== JSON.stringify(query)
127
+ ) {
128
+ //fai lo scroll solo quando vengono modificati i filtri dall'utente. Evita lo scroll al primo load
129
+ resultsRef.current.scrollIntoView({ behavior: 'smooth' });
130
+ }
131
+ }, [query]);
132
+
115
133
  if (!Layout) return null;
116
134
  return (
117
135
  <div className={cx('block search', { 'public-ui': mode === 'edit' })}>
@@ -120,6 +138,7 @@ const SearchBlockView = (props) => {
120
138
  isEditMode={mode === 'edit'}
121
139
  selectedView={selectedView}
122
140
  setSelectedView={setSelectedView}
141
+ resultsRef={resultsRef}
123
142
  >
124
143
  {/* Add class .block.listing to benefit from existing listing template styles */}
125
144
  <div className="block listing search-results">
@@ -1,5 +1,6 @@
1
1
  /* CUSTOMIZATIONS:
2
2
  - Agid styling
3
+ - added resultsRef
3
4
  */
4
5
  import React from 'react';
5
6
  import {
@@ -33,6 +34,7 @@ const LeftColumnFacets = (props) => {
33
34
  isEditMode,
34
35
  querystring = {},
35
36
  searchData,
37
+ resultsRef,
36
38
  // mode = 'view',
37
39
  // variation,
38
40
  } = props;
@@ -117,24 +119,26 @@ const LeftColumnFacets = (props) => {
117
119
  </div>
118
120
  )}
119
121
 
120
- <div className="search-results-count-sort d-flex align-center flex-wrap">
121
- <SearchDetails
122
- text={searchedText}
123
- total={totalItems}
124
- data={data}
125
- />
126
- <FilterList
127
- {...props}
128
- isEditMode={isEditMode}
129
- setFacets={(f) => {
130
- flushSync(() => {
131
- setFacets(f);
132
- onTriggerSearch(searchedText || '', f);
133
- });
134
- }}
135
- />
122
+ <div ref={resultsRef} className="results-wrapper">
123
+ <div className="search-results-count-sort d-flex align-center flex-wrap">
124
+ <SearchDetails
125
+ text={searchedText}
126
+ total={totalItems}
127
+ data={data}
128
+ />
129
+ <FilterList
130
+ {...props}
131
+ isEditMode={isEditMode}
132
+ setFacets={(f) => {
133
+ flushSync(() => {
134
+ setFacets(f);
135
+ onTriggerSearch(searchedText || '', f);
136
+ });
137
+ }}
138
+ />
139
+ </div>
140
+ {children}
136
141
  </div>
137
- {children}
138
142
  </div>
139
143
  </Row>
140
144
  </Container>
@@ -1,5 +1,6 @@
1
1
  /* CUSTOMIZATIONS:
2
2
  - Agid styling
3
+ - added resultsRef
3
4
  */
4
5
  import React from 'react';
5
6
  import {
@@ -35,6 +36,7 @@ const RightColumnFacets = (props) => {
35
36
  isEditMode,
36
37
  querystring = {},
37
38
  searchData,
39
+ resultsRef,
38
40
  // mode = 'view',
39
41
  // variation,
40
42
  } = props;
@@ -72,24 +74,26 @@ const RightColumnFacets = (props) => {
72
74
  </div>
73
75
  )}
74
76
 
75
- <div className="search-results-count-sort d-flex align-center flex-wrap">
76
- <SearchDetails
77
- text={searchedText}
78
- total={totalItems}
79
- data={data}
80
- />
81
- <FilterList
82
- {...props}
83
- isEditMode={isEditMode}
84
- setFacets={(f) => {
85
- flushSync(() => {
86
- setFacets(f);
87
- onTriggerSearch(searchedText || '', f);
88
- });
89
- }}
90
- />
77
+ <div ref={resultsRef} className="results-wrapper">
78
+ <div className="search-results-count-sort d-flex align-center flex-wrap">
79
+ <SearchDetails
80
+ text={searchedText}
81
+ total={totalItems}
82
+ data={data}
83
+ />
84
+ <FilterList
85
+ {...props}
86
+ isEditMode={isEditMode}
87
+ setFacets={(f) => {
88
+ flushSync(() => {
89
+ setFacets(f);
90
+ onTriggerSearch(searchedText || '', f);
91
+ });
92
+ }}
93
+ />
94
+ </div>
95
+ {children}
91
96
  </div>
92
- {children}
93
97
  </div>
94
98
 
95
99
  {showColumn && (
@@ -409,8 +409,8 @@ class RecurrenceWidget extends Component {
409
409
  formValues['freq'] = FREQUENCES.MONDAYFRIDAY;
410
410
  } else
411
411
  formValues[option] = value.map((d) => {
412
- return this.getWeekday(d);
413
- });
412
+ return this.getWeekday(d);
413
+ });
414
414
  }
415
415
  break;
416
416
  case 'bymonthday':
@@ -441,8 +441,11 @@ class RecurrenceWidget extends Component {
441
441
  if (freq === FREQUENCES.YEARLY) {
442
442
  formValues['yearly'] = 'byday';
443
443
  }
444
+ const weekday = this.getWeekday(value[0][0]);
445
+ weekday.n = value[0][1];
444
446
  formValues['weekdayOfTheMonth'] = value[0][0];
445
447
  formValues['weekdayOfTheMonthIndex'] = value[0][1];
448
+ formValues['byweekday'] = weekday;
446
449
  }
447
450
  break;
448
451
  case 'bymonth':
@@ -25,15 +25,22 @@ const Footer = () => {
25
25
  useGoogleAnalytics();
26
26
  const currentContent = useSelector((state) => state.content?.data);
27
27
  const contentType = currentContent ? currentContent['@type'] : null;
28
- const noFeedbackFormFor = config.settings.siteProperties.noFeedbackFormFor || [];
28
+ const noFeedbackFormFor =
29
+ config.settings.siteProperties.noFeedbackFormFor || [];
30
+ const showFeedbackForm = config.settings.siteProperties
31
+ .enableNoFeedbackFormFor
32
+ ? contentType &&
33
+ !noFeedbackFormFor.includes(contentType) &&
34
+ config.settings.siteProperties.enableFeedbackForm
35
+ : true;
29
36
 
30
37
  return (
31
38
  <>
32
- {contentType &&
33
- !noFeedbackFormFor.includes(contentType) &&
34
- config.settings.siteProperties.enableFeedbackForm && (
39
+ {showFeedbackForm && (
40
+ <div className="public-ui" id="customer-satisfaction-form">
35
41
  <FeedbackForm />
36
- )}
42
+ </div>
43
+ )}
37
44
 
38
45
  <SubsiteFooter />
39
46
  <footer className="it-footer" id="footer">
@@ -93,7 +93,12 @@ const Navigation = ({ pathname }) => {
93
93
  return (
94
94
  <Header theme="" type="navbar">
95
95
  {menu?.length > 0 ? (
96
- <HeaderContent expand="lg" megamenu id="navigation">
96
+ <HeaderContent
97
+ expand="lg"
98
+ megamenu
99
+ id="navigation"
100
+ aria-label={intl.formatMessage(messages.mainMenu)}
101
+ >
97
102
  <HeaderToggler
98
103
  aria-controls="it-navigation-collapse"
99
104
  aria-expanded={collapseOpen}
@@ -142,7 +147,12 @@ const Navigation = ({ pathname }) => {
142
147
  </UniversalLink>
143
148
  </div>
144
149
  {/* Main Menu */}
145
- <Nav data-element="main-navigation" navbar role="menubar">
150
+ <Nav
151
+ data-element="main-navigation"
152
+ navbar
153
+ role="menubar"
154
+ aria-label={intl.formatMessage(messages.mainMenu)}
155
+ >
146
156
  {menu
147
157
  ?.filter((item) => item.visible)
148
158
  ?.map((item, index) => (
@@ -206,6 +216,10 @@ const messages = defineMessages({
206
216
  id: 'toggleMenu_close',
207
217
  defaultMessage: 'Chiudi',
208
218
  },
219
+ mainMenu: {
220
+ id: 'mainMenu',
221
+ defaultMessage: 'Menu principale',
222
+ },
209
223
  });
210
224
 
211
225
  Navigation.propTypes = {
@@ -100,11 +100,14 @@ const widgetValidation = {
100
100
  url: {
101
101
  isValidURL: (urlValue, urlObj, intlFunc) => {
102
102
  var urlRegex = new RegExp(
103
- '^(https?:\\/\\/)?' + // validate protocol
104
- '((([a-z\\d]([a-z\\d-]*[a-z\\d])*)\\.)+[a-z]{2,}|' + // validate domain name
105
- '((\\d{1,3}\\.){3}\\d{1,3}))|' + // validate OR ip (v4) address
106
- '(localhost)' + // validate OR localhost address
107
- '(\\:\\d+)?(\\/[-a-z\\d%_.~+]*)*' + // validate port and path
103
+ '^(https?:\\/\\/)?' + // optional protocol
104
+ '(' +
105
+ '([a-z\\d]+(-[a-z\\d]+)*\\.)+[a-z]{2,}|' + // validate domain name
106
+ '(\\d{1,3}\\.){3}\\d{1,3}|' + // OR ip (v4) address
107
+ 'localhost' + // OR localhost
108
+ ')' +
109
+ '(\\:\\d+)?' + // optional port
110
+ '(\\/[-a-z\\d%_.~+]*)*' + // path
108
111
  '(\\?[;&a-z\\d%_.~+=-]*)?' + // validate query string
109
112
  '(\\#[-a-z\\d_]*)?$', // validate fragment locator
110
113
  'i',
@@ -64,6 +64,7 @@ const Field = ({
64
64
  errorMessage,
65
65
  id,
66
66
  reactSelect,
67
+ autocomplete,
67
68
  }) => {
68
69
  const intl = useIntl();
69
70
  const Select = reactSelect.default;
@@ -102,6 +103,7 @@ const Field = ({
102
103
  onChange(name, e.target.value);
103
104
  }}
104
105
  value={value ?? ''}
106
+ autoComplete={autocomplete}
105
107
  />
106
108
  )}
107
109
  {field_type === 'textarea' && (
@@ -120,6 +122,7 @@ const Field = ({
120
122
  onChange(name, e.target.value);
121
123
  }}
122
124
  value={value ?? undefined}
125
+ autoComplete={autocomplete}
123
126
  />
124
127
  )}
125
128
  {field_type === 'select' && (
@@ -151,6 +154,7 @@ const Field = ({
151
154
  classNamePrefix="react-select"
152
155
  className={isInvalid() ? 'is-invalid' : ''}
153
156
  value={value ? [{ value: value, label: value }] : []}
157
+ autoComplete={autocomplete}
154
158
  />
155
159
  {description && <small className="form-text">{description}</small>}
156
160
  {errorMessage && (
@@ -286,6 +290,7 @@ const Field = ({
286
290
  onChange(name, e.target.value);
287
291
  }}
288
292
  value={value ?? ''}
293
+ autoComplete={autocomplete}
289
294
  />
290
295
  )}
291
296
  {field_type === 'attachment' && (
@@ -320,6 +325,7 @@ const Field = ({
320
325
  onChange(name, e.target.value);
321
326
  }}
322
327
  value={value ?? ''}
328
+ autoComplete={autocomplete}
323
329
  />
324
330
  )}
325
331
  {field_type === 'static_text' &&
@@ -382,6 +388,7 @@ Field.propTypes = {
382
388
  value: PropTypes.any,
383
389
  formHasErrors: PropTypes.bool,
384
390
  onChange: PropTypes.func,
391
+ autoComplete: PropTypes.string,
385
392
  };
386
393
 
387
394
  export default injectLazyLibs('reactSelect')(Field);