design-react-kit 5.5.1 → 5.6.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 (162) hide show
  1. package/CHANGELOG.md +28 -0
  2. package/dist/Alert/Alert.cjs.map +1 -1
  3. package/dist/Alert/Alert.js.map +1 -1
  4. package/dist/Autocomplete/Autocomplete.cjs +3 -1
  5. package/dist/Autocomplete/Autocomplete.cjs.map +1 -1
  6. package/dist/Autocomplete/Autocomplete.js +2 -2
  7. package/dist/Autocomplete/Autocomplete.js.map +1 -1
  8. package/dist/BackToTop/BackToTop.cjs +1 -1
  9. package/dist/BackToTop/BackToTop.cjs.map +1 -1
  10. package/dist/BackToTop/BackToTop.js +1 -1
  11. package/dist/BackToTop/BackToTop.js.map +1 -1
  12. package/dist/BottomNav/BottomNavItem.cjs +1 -1
  13. package/dist/BottomNav/BottomNavItem.cjs.map +1 -1
  14. package/dist/Callout/CalloutMoreFooter.cjs +1 -1
  15. package/dist/Callout/CalloutMoreFooter.cjs.map +1 -1
  16. package/dist/Card/CardCategory.cjs +1 -1
  17. package/dist/Card/CardCategory.cjs.map +1 -1
  18. package/dist/Card/CardCategory.js +3 -3
  19. package/dist/Card/CardCategory.js.map +1 -1
  20. package/dist/Card/CardReadMore.cjs +1 -1
  21. package/dist/Card/CardReadMore.cjs.map +1 -1
  22. package/dist/Collapse/Collapse.cjs +1 -1
  23. package/dist/Collapse/Collapse.cjs.map +1 -1
  24. package/dist/Collapse/Collapse.js +3 -3
  25. package/dist/Collapse/Collapse.js.map +1 -1
  26. package/dist/Dimmer/Dimmer.cjs +1 -1
  27. package/dist/Dimmer/Dimmer.cjs.map +1 -1
  28. package/dist/Dropdown/Dropdown.cjs.map +1 -1
  29. package/dist/Dropdown/Dropdown.js +1 -1
  30. package/dist/Dropdown/Dropdown.js.map +1 -1
  31. package/dist/Dropdown/DropdownToggle.cjs +1 -1
  32. package/dist/Dropdown/DropdownToggle.cjs.map +1 -1
  33. package/dist/Forward/Forward.cjs.map +1 -1
  34. package/dist/Forward/Forward.js.map +1 -1
  35. package/dist/GoBack/GoBack.cjs +1 -1
  36. package/dist/GoBack/GoBack.cjs.map +1 -1
  37. package/dist/Grid/GridItemTextWrapper.cjs.map +1 -1
  38. package/dist/Grid/GridItemTextWrapper.js.map +1 -1
  39. package/dist/Grid/index.cjs.map +1 -1
  40. package/dist/Header/HeaderBrand.cjs +1 -1
  41. package/dist/Header/HeaderBrand.cjs.map +1 -1
  42. package/dist/Header/HeaderSearch.cjs +1 -1
  43. package/dist/Header/HeaderSearch.cjs.map +1 -1
  44. package/dist/Header/HeaderToggler.cjs.map +1 -1
  45. package/dist/Header/HeaderToggler.js +1 -1
  46. package/dist/Header/HeaderToggler.js.map +1 -1
  47. package/dist/Icon/Icon.cjs +1 -1
  48. package/dist/Icon/Icon.cjs.map +1 -1
  49. package/dist/Icon/Icon.js +3 -3
  50. package/dist/Icon/Icon.js.map +1 -1
  51. package/dist/Icon/assets/index.cjs.map +1 -1
  52. package/dist/Input/Input.cjs +1 -1
  53. package/dist/Input/Input.cjs.map +1 -1
  54. package/dist/Input/Input.js +11 -9
  55. package/dist/Input/Input.js.map +1 -1
  56. package/dist/Input/InputContainer.cjs.map +1 -1
  57. package/dist/Input/InputContainer.js.map +1 -1
  58. package/dist/Input/TextArea.cjs +1 -1
  59. package/dist/Input/TextArea.cjs.map +1 -1
  60. package/dist/Input/TextArea.js.map +1 -1
  61. package/dist/Input/utils.cjs +1 -1
  62. package/dist/Input/utils.cjs.map +1 -1
  63. package/dist/Input/utils.js +3 -6
  64. package/dist/Input/utils.js.map +1 -1
  65. package/dist/List/List.cjs.map +1 -1
  66. package/dist/List/List.js.map +1 -1
  67. package/dist/List/ListItem.cjs.map +1 -1
  68. package/dist/List/ListItem.js +2 -2
  69. package/dist/List/ListItem.js.map +1 -1
  70. package/dist/Megamenu/MegamenuItem.cjs +1 -1
  71. package/dist/Megamenu/MegamenuItem.cjs.map +1 -1
  72. package/dist/Modal/ModalHeader.cjs +1 -1
  73. package/dist/Modal/ModalHeader.cjs.map +1 -1
  74. package/dist/NavScroll/types.cjs.map +1 -1
  75. package/dist/Notification/NotificationContent.cjs +1 -1
  76. package/dist/Notification/NotificationContent.cjs.map +1 -1
  77. package/dist/Notification/core.cjs +1 -1
  78. package/dist/Notification/core.cjs.map +1 -1
  79. package/dist/Notification/index.cjs +1 -1
  80. package/dist/Notification/index.cjs.map +1 -1
  81. package/dist/Rating/Rating.cjs +1 -1
  82. package/dist/Rating/Rating.cjs.map +1 -1
  83. package/dist/ResponsiveImage/ResponsiveImage.cjs.map +1 -1
  84. package/dist/ResponsiveImage/ResponsiveImage.js.map +1 -1
  85. package/dist/Skiplink/Skiplink.cjs.map +1 -1
  86. package/dist/Skiplink/Skiplink.js.map +1 -1
  87. package/dist/Skiplink/SkiplinkItem.cjs.map +1 -1
  88. package/dist/Stepper/StepperHeaderElement.cjs +1 -1
  89. package/dist/Stepper/StepperHeaderElement.cjs.map +1 -1
  90. package/dist/Stepper/StepperHeaderElement.js +3 -5
  91. package/dist/Stepper/StepperHeaderElement.js.map +1 -1
  92. package/dist/Tab/TabNav.cjs +2 -0
  93. package/dist/Tab/TabNav.cjs.map +1 -0
  94. package/dist/Tab/TabNav.js +63 -0
  95. package/dist/Tab/TabNav.js.map +1 -0
  96. package/dist/Tab/TabNavItem.cjs +2 -0
  97. package/dist/Tab/TabNavItem.cjs.map +1 -0
  98. package/dist/Tab/TabNavItem.js +7 -0
  99. package/dist/Tab/TabNavItem.js.map +1 -0
  100. package/dist/Tab/TabNavLink.cjs +2 -0
  101. package/dist/Tab/TabNavLink.cjs.map +1 -0
  102. package/dist/Tab/TabNavLink.js +7 -0
  103. package/dist/Tab/TabNavLink.js.map +1 -0
  104. package/dist/Tab/TabPanel.cjs +2 -0
  105. package/dist/Tab/TabPanel.cjs.map +1 -0
  106. package/dist/Tab/TabPanel.js +7 -0
  107. package/dist/Tab/TabPanel.js.map +1 -0
  108. package/dist/Timeline/TimelinePin.cjs +1 -1
  109. package/dist/Timeline/TimelinePin.cjs.map +1 -1
  110. package/dist/Timeline/TimelinePin.js +1 -1
  111. package/dist/Timeline/TimelinePin.js.map +1 -1
  112. package/dist/Toggle/Toggle.cjs.map +1 -1
  113. package/dist/Toggle/Toggle.js.map +1 -1
  114. package/dist/Toolbar/ToolbarItem.cjs +1 -1
  115. package/dist/Toolbar/ToolbarItem.cjs.map +1 -1
  116. package/dist/index.cjs +3 -1
  117. package/dist/index.cjs.map +1 -1
  118. package/dist/index.js +6 -2
  119. package/dist/index.js.map +1 -1
  120. package/dist/track-focus.cjs.map +1 -1
  121. package/dist/track-focus.js.map +1 -1
  122. package/dist/types/Icon/Icon.d.ts +1 -1
  123. package/dist/types/Input/Input.d.ts +1 -3
  124. package/dist/types/Input/utils.d.ts +1 -1
  125. package/dist/types/NavScroll/types.d.ts +2 -2
  126. package/dist/types/Stepper/StepperHeaderElement.d.ts +4 -4
  127. package/dist/types/Tab/TabNav.d.ts +24 -0
  128. package/dist/types/Tab/TabNavItem.d.ts +8 -0
  129. package/dist/types/Tab/TabNavLink.d.ts +8 -0
  130. package/dist/types/Tab/TabPanel.d.ts +8 -0
  131. package/dist/types/index.d.ts +11 -3
  132. package/package.json +5 -3
  133. package/src/Alert/Alert.tsx +1 -2
  134. package/src/Autocomplete/Autocomplete.tsx +70 -69
  135. package/src/BackToTop/BackToTop.tsx +2 -1
  136. package/src/Card/CardCategory.tsx +17 -4
  137. package/src/Collapse/Collapse.tsx +8 -12
  138. package/src/Dropdown/Dropdown.tsx +4 -6
  139. package/src/Forward/Forward.tsx +3 -3
  140. package/src/Grid/GridItemTextWrapper.tsx +7 -1
  141. package/src/Header/HeaderToggler.tsx +2 -2
  142. package/src/Icon/Icon.tsx +22 -4
  143. package/src/Icon/assets/index.ts +1 -1
  144. package/src/Input/Input.tsx +11 -12
  145. package/src/Input/InputContainer.tsx +0 -1
  146. package/src/Input/TextArea.tsx +1 -4
  147. package/src/Input/utils.tsx +4 -7
  148. package/src/List/List.tsx +1 -8
  149. package/src/List/ListItem.tsx +24 -33
  150. package/src/NavScroll/types.ts +2 -2
  151. package/src/ResponsiveImage/ResponsiveImage.tsx +13 -7
  152. package/src/Skiplink/Skiplink.tsx +12 -7
  153. package/src/Skiplink/SkiplinkItem.tsx +1 -1
  154. package/src/Stepper/StepperHeaderElement.tsx +8 -10
  155. package/src/Tab/TabNav.tsx +111 -0
  156. package/src/Tab/TabNavItem.tsx +14 -0
  157. package/src/Tab/TabNavLink.tsx +14 -0
  158. package/src/Tab/TabPanel.tsx +14 -0
  159. package/src/Timeline/TimelinePin.tsx +2 -2
  160. package/src/Toggle/Toggle.tsx +1 -1
  161. package/src/index.ts +9 -5
  162. package/src/track-focus.js +14 -15
@@ -21,7 +21,7 @@ export interface HeaderTogglerProps extends ButtonHTMLAttributes<HTMLButtonEleme
21
21
 
22
22
  const BUTTON = 'button';
23
23
 
24
- export const HeaderToggler = ({ className, tag, type, isOpen=false, testId, ...attributes }: HeaderTogglerProps) => {
24
+ export const HeaderToggler = ({ className, tag, type, isOpen = false, testId, ...attributes }: HeaderTogglerProps) => {
25
25
  const HeaderType = useHeaderContext();
26
26
  const defaultTag = HeaderType === SLIM ? 'a' : BUTTON;
27
27
  const defaultType = HeaderType === SLIM ? undefined : BUTTON;
@@ -32,7 +32,7 @@ export const HeaderToggler = ({ className, tag, type, isOpen=false, testId, ...a
32
32
  },
33
33
  className
34
34
  );
35
- const expanded = isOpen ? "true" : "false"
35
+ const expanded = isOpen ? 'true' : 'false';
36
36
  useEffect(() => {
37
37
  document.querySelectorAll('.container-fluid').forEach((element) => {
38
38
  element.classList.remove('container-fluid');
package/src/Icon/Icon.tsx CHANGED
@@ -47,7 +47,7 @@ export interface IconProps extends SVGProps<SVGSVGElement> {
47
47
  size?: 'xl' | 'lg' | '' | 'sm' | 'xs';
48
48
  /**
49
49
  * Il nome dell'icona da mostrare. Per una lista completa vedi:
50
- * <a href="https://italia.github.io/design-react-kit/?path=/story/componenti-icon--lista-icone" target="_blank">Lista icone</a>
50
+ * <a href="https://italia.github.io/design-react-kit/?path=/story/documentazione-utilities-icon--lista-icone" target="_blank">Lista icone</a>.
51
51
  * In caso di un'immagine esterna l'URL da utilizzare.
52
52
  **/
53
53
  icon: string;
@@ -65,7 +65,7 @@ export const Icon: FC<IconProps> = ({
65
65
  color = '',
66
66
  size = '',
67
67
  icon = '',
68
- title,
68
+ title = '',
69
69
  className,
70
70
  padding = false,
71
71
  onIconLoad,
@@ -108,8 +108,26 @@ export const Icon: FC<IconProps> = ({
108
108
  }
109
109
 
110
110
  if (!IconComponent) {
111
- return <EmptyIcon className={classes} role='img' {...attributes} data-testid={testId} />;
111
+ return (
112
+ <EmptyIcon
113
+ className={classes}
114
+ role={title === '' ? undefined : 'img'}
115
+ aria-hidden={title === '' ? true : false}
116
+ title={title}
117
+ {...attributes}
118
+ data-testid={testId}
119
+ />
120
+ );
112
121
  }
113
122
 
114
- return <IconComponent className={classes} role='img' title={title} data-testid={testId} {...attributes} />;
123
+ return (
124
+ <IconComponent
125
+ className={classes}
126
+ role={title === '' ? undefined : 'img'}
127
+ aria-hidden={title === '' ? true : false}
128
+ title={title}
129
+ data-testid={testId}
130
+ {...attributes}
131
+ />
132
+ );
115
133
  };
@@ -698,4 +698,4 @@ export const allIcons = Object.keys(iconList);
698
698
  export interface SVGRProps {
699
699
  title?: string;
700
700
  titleId?: string;
701
- }
701
+ }
@@ -77,8 +77,6 @@ export interface InputProps extends InputHTMLAttributes<HTMLInputElement> {
77
77
  innerRef?: Ref<HTMLInputElement>;
78
78
  /** Utilizzare per mostrare testo statico non modificabile. */
79
79
  plaintext?: boolean;
80
- /** Utilizzare per mostrare un elemento addon a fianco (prima o dopo) il campo input all'interno del componente */
81
- addon?: boolean;
82
80
  /** Utilizzare per mostrare un elemento un simbolo attivando la proprietà addon nel campo input all'interno del componente */
83
81
  addonText?: string;
84
82
  /** Oggetto contenente la nuova mappatura per le classi CSS. */
@@ -118,7 +116,6 @@ export const Input = ({
118
116
  cssModule,
119
117
  type = 'text',
120
118
  tag,
121
- addon,
122
119
  addonText,
123
120
  static: staticInput,
124
121
  plaintext,
@@ -173,13 +170,11 @@ export const Input = ({
173
170
  let { bsSize, valid, ...rest } = attributes;
174
171
 
175
172
  const Tag = getTag({ tag, plaintext, staticInput, type });
176
- addon = addonText != null ? true : addon;
177
173
  const formControlClass = getFormControlClass(
178
174
  {
179
175
  plaintext,
180
176
  staticInput,
181
177
  type,
182
- addon,
183
178
  normalized
184
179
  },
185
180
  cssModule
@@ -203,8 +198,8 @@ export const Input = ({
203
198
  }
204
199
 
205
200
  // associate the input field with the help text
206
- const infoId = id ? `${id}Description` : undefined;
207
- if (id) {
201
+ const infoId = id && infoText ? `${id}Description` : undefined;
202
+ if (infoId) {
208
203
  extraAttributes['aria-describedby'] = infoId;
209
204
  }
210
205
 
@@ -296,11 +291,17 @@ export const Input = ({
296
291
  }
297
292
  const nativeInputValueSetter = Object.getOwnPropertyDescriptor(window.HTMLInputElement.prototype, 'value')?.set;
298
293
  nativeInputValueSetter?.call(inputRef.current, `${newValue}`);
294
+ const ev1 = new Event('change', { bubbles: true });
299
295
  const ev2 = new Event('input', { bubbles: true });
296
+ inputRef.current?.dispatchEvent(ev1);
300
297
  inputRef.current?.dispatchEvent(ev2);
298
+ inputRef.current?.focus();
301
299
  };
302
300
 
303
301
  if (['currency', 'percentage', 'adaptive', 'number'].includes(type)) {
302
+ if (containerProps.extraLabelClass && ['currency', 'percentage'].includes(type)) {
303
+ containerProps.extraLabelClass = containerProps.extraLabelClass + ' input-symbol-label';
304
+ }
304
305
  return (
305
306
  <InputContainer {...containerProps}>
306
307
  <div
@@ -308,8 +309,6 @@ export const Input = ({
308
309
  'input-group': true,
309
310
  'input-number': true,
310
311
  disabled: rest.disabled,
311
- 'input-number-percentage': type === 'percentage',
312
- 'input-number-currency': type === 'currency',
313
312
  'input-number-adaptive': type === 'adaptive'
314
313
  })}
315
314
  style={{ width }}
@@ -328,10 +327,10 @@ export const Input = ({
328
327
  ref={inputRef}
329
328
  />
330
329
  <span className='input-group-text align-buttons flex-column'>
331
- <button className='input-number-add' onClick={() => clickIncrDecr(1)} type='button'>
330
+ <button className='input-number-add' onClick={() => clickIncrDecr(1)}>
332
331
  <span className='visually-hidden'>{incrementLabel || ''}</span>
333
332
  </button>
334
- <button className='input-number-sub' onClick={() => clickIncrDecr(-1)} type='button'>
333
+ <button className='input-number-sub' onClick={() => clickIncrDecr(-1)}>
335
334
  <span className='visually-hidden'>{decrementLabel || ''}</span>
336
335
  </button>
337
336
  </span>
@@ -416,4 +415,4 @@ export const Input = ({
416
415
  }
417
416
 
418
417
  return <Tag {...rest} {...extraAttributes} className={inputClasses} {...sharedAttributes} data-testid={testId} />;
419
- };
418
+ };
@@ -38,7 +38,6 @@ export const InputContainer: FC<InputContainerProps> = ({
38
38
  iconLeft,
39
39
  children
40
40
  }) => {
41
-
42
41
  if (hasButtonRight || hasIconLeft) {
43
42
  return (
44
43
  <div className={wrapperClass} data-testid={testId}>
@@ -57,10 +57,7 @@ export const TextArea = ({
57
57
  const extraAttributes: { ['aria-describedby']?: string } = {};
58
58
 
59
59
  //Chiamo questa funzione per impostare classNames a 'form-control'
60
- const formControlClass = getFormControlClass(
61
- {},
62
- cssModule
63
- );
60
+ const formControlClass = getFormControlClass({}, cssModule);
64
61
  // associate the input field with the help text
65
62
  const infoId = id ? `${id}Description` : undefined;
66
63
  if (id) {
@@ -8,9 +8,9 @@ type ValidationProps = Pick<InputProps, 'valid'>;
8
8
  type TypeProps = Pick<InputProps, 'plaintext' | 'type'> & {
9
9
  staticInput?: boolean;
10
10
  };
11
- type FormControlProps = Pick<InputProps, 'addon' | 'normalized'> & TypeProps;
11
+ type FormControlProps = Pick<InputProps, 'normalized'> & TypeProps;
12
12
 
13
- function getFormControlClassInternal({ plaintext, staticInput, type = 'text', addon, normalized }: FormControlProps) {
13
+ function getFormControlClassInternal({ plaintext, staticInput, type = 'text', normalized }: FormControlProps) {
14
14
  const formControlClass = 'form-control';
15
15
  if (plaintext || staticInput || normalized) {
16
16
  return `${formControlClass}-plaintext`;
@@ -19,9 +19,7 @@ function getFormControlClassInternal({ plaintext, staticInput, type = 'text', ad
19
19
  return `${formControlClass}-file`;
20
20
  }
21
21
  if (['radio', 'checkbox'].indexOf(type) > -1) {
22
- if (addon) {
23
- return null;
24
- }
22
+ return null;
25
23
  }
26
24
  return formControlClass;
27
25
  }
@@ -117,8 +115,7 @@ export function getClasses(
117
115
  // we can model here only if stylings
118
116
  'form-control-plaintext': normalizedOnlyCondition,
119
117
  'form-control': passwordOnlyCondition,
120
- 'input-password': passwordOnlyCondition,
121
- 'focus--mouse': passwordOnlyCondition || normalizedOnlyCondition
118
+ 'input-password': passwordOnlyCondition
122
119
  }
123
120
  ),
124
121
  cssModule
package/src/List/List.tsx CHANGED
@@ -16,14 +16,7 @@ export interface ListProps extends HTMLAttributes<HTMLUListElement> {
16
16
  testId?: string;
17
17
  }
18
18
 
19
- export const List: FC<ListProps> = ({
20
- className,
21
- wrapperClassName,
22
- tag = 'div',
23
- noWrapper,
24
- testId,
25
- ...attributes
26
- }) => {
19
+ export const List: FC<ListProps> = ({ className, wrapperClassName, tag = 'div', noWrapper, testId, ...attributes }) => {
27
20
  const Tag = tag;
28
21
  const wrapperClasses = classNames('it-list-wrapper', wrapperClassName);
29
22
  const classes = classNames(className, 'it-list');
@@ -39,46 +39,37 @@ export const ListItem: FC<ListItemProps> & {
39
39
  children,
40
40
  ...attributes
41
41
  }) => {
42
- const Tag = tag;
43
- const classes = classNames(
44
- className,
45
- { active },
46
- 'list-item'
47
- ),
48
- classesItem = classNames(className, {
49
- 'it-rounded-icon': icon,
50
- 'avatar size-lg': avatar,
51
- 'it-thumb': img
52
- }),
53
- leftItem = icon || avatar || img;
54
-
55
- if (href) {
56
- return (
57
- <li className={wrapperClassName} data-testid={testId}>
58
- <a href={href || '#'} {...attributes} className={classes}>
59
- <div className="it-right-zone">{children}</div>
60
- </a>
61
- </li>
62
- );
63
- }
42
+ const Tag = tag;
43
+ const classes = classNames(className, { active }, 'list-item'),
44
+ classesItem = classNames(className, {
45
+ 'it-rounded-icon': icon,
46
+ 'avatar size-lg': avatar,
47
+ 'it-thumb': img
48
+ }),
49
+ leftItem = icon || avatar || img;
64
50
 
51
+ if (href) {
65
52
  return (
66
53
  <li className={wrapperClassName} data-testid={testId}>
67
- <Tag
68
- {...attributes}
69
- className={classes}
70
- href={href}
71
- to={to}
72
- >
73
- {leftItem && <div className={classesItem}>{leftItem}</div>}
74
- <div className="it-right-zone">{children}</div>
75
- </Tag>
54
+ <a href={href || '#'} {...attributes} className={classes}>
55
+ <div className='it-right-zone'>{children}</div>
56
+ </a>
76
57
  </li>
77
58
  );
78
- };
59
+ }
60
+
61
+ return (
62
+ <li className={wrapperClassName} data-testid={testId}>
63
+ <Tag {...attributes} className={classes} href={href} to={to}>
64
+ {leftItem && <div className={classesItem}>{leftItem}</div>}
65
+ <div className='it-right-zone'>{children}</div>
66
+ </Tag>
67
+ </li>
68
+ );
69
+ };
79
70
 
80
71
  const MultipleAction: FC<ListItemProps> = ({ children }) => {
81
- return <span className='it-multiple'>{children}</span>
72
+ return <span className='it-multiple'>{children}</span>;
82
73
  };
83
74
 
84
75
  ListItem.MultipleAction = MultipleAction;
@@ -87,8 +87,8 @@ export type useNavScrollResult = {
87
87
  */
88
88
  getActiveRef: () => RefObject<Element> | null;
89
89
  /**
90
- * A list of active ids (the full hierarchy).
91
- */
90
+ * A list of active ids (the full hierarchy).
91
+ */
92
92
  percentage: number;
93
93
  };
94
94
 
@@ -12,26 +12,32 @@ export interface ResponsiveImageProps extends HTMLAttributes<HTMLImageElement> {
12
12
  proportioned?: boolean;
13
13
  }
14
14
 
15
- export const ResponsiveImage: FC<ResponsiveImageProps> = ({ alt, testId, proportioned=false, children, ...attributes }) => {
15
+ export const ResponsiveImage: FC<ResponsiveImageProps> = ({
16
+ alt,
17
+ testId,
18
+ proportioned = false,
19
+ children,
20
+ ...attributes
21
+ }) => {
16
22
  if (children) {
17
23
  if (proportioned) {
18
- return(
24
+ return (
19
25
  <div className='img-responsive-wrapper'>
20
26
  <div className='img-responsive'>
21
27
  <figure className='img-wrapper'>
22
- <img {...attributes} alt={alt} className='figure-img img-fluid rounded' />
28
+ <img {...attributes} alt={alt} className='figure-img img-fluid rounded' />
23
29
  {children}
24
30
  </figure>
25
31
  </div>
26
32
  </div>
27
- )
33
+ );
28
34
  } else {
29
- return(
35
+ return (
30
36
  <figure className='figure img-full w-100 img-responsive-wrapper'>
31
- <img {...attributes} alt={alt} className='figure-img img-fluid rounded' />
37
+ <img {...attributes} alt={alt} className='figure-img img-fluid rounded' />
32
38
  {children}
33
39
  </figure>
34
- )
40
+ );
35
41
  }
36
42
  } else {
37
43
  return (
@@ -12,18 +12,23 @@ export interface SkiplinkProps extends HTMLAttributes<HTMLElement> {
12
12
  testId?: string;
13
13
  }
14
14
 
15
- export const Skiplink: FC<SkiplinkProps> = ({ ariaLabel=null, className, tag = 'div', nav=false, testId, children, ...attributes }) => {
15
+ export const Skiplink: FC<SkiplinkProps> = ({
16
+ ariaLabel = null,
17
+ className,
18
+ tag = 'div',
19
+ nav = false,
20
+ testId,
21
+ children,
22
+ ...attributes
23
+ }) => {
16
24
  const Tag = nav ? 'nav' : tag;
17
25
  const classes = classNames(className, 'skiplinks');
18
26
  if (nav) {
19
27
  return (
20
- <Tag aria-label={ariaLabel} className={classes} {...attributes} data-testid={testId} >
21
- <ul>
22
- {children}
23
- </ul>
28
+ <Tag aria-label={ariaLabel} className={classes} {...attributes} data-testid={testId}>
29
+ <ul>{children}</ul>
24
30
  </Tag>
25
- )
26
-
31
+ );
27
32
  } else {
28
33
  return <Tag aria-label={ariaLabel} className={classes} {...attributes} data-testid={testId} />;
29
34
  }
@@ -31,7 +31,7 @@ export const SkiplinkItem: FC<SkiplinkItemProps> = ({
31
31
 
32
32
  if (navItem) {
33
33
  return (
34
- <li className={classes} >
34
+ <li className={classes}>
35
35
  <Tag {...attributes} {...extraHref} data-testid={testId} />
36
36
  </li>
37
37
  );
@@ -29,14 +29,14 @@ export interface StepperHeaderElementProps extends HTMLAttributes<HTMLLIElement>
29
29
  appendIcon?: string;
30
30
  /** Icona da mostrare alla sinistra dell'etichetta dello step */
31
31
  prependIcon?: string;
32
+ /** Titolo dell'icona da mostrare alla destra dell'etichetta dello step */
33
+ appendIconTitle?: string;
34
+ /** Titolo dell'icona da mostrare alla sinistra dell'etichetta dello step */
35
+ prependIconTitle?: string;
32
36
  /** Utilizzare questo attributo per elementi aggiuntivi da mostrare su dispositivi mobile per lo step attivo */
33
37
  stepperNumber?: ReactNode;
34
38
  /** Nasconde il bordo inferiore azzurro per lo step */
35
39
  noLine?: boolean;
36
- /** @deprecated Usare `appendIcon` */
37
- icon?: string;
38
- /** @deprecated Usare `prependIcon` */
39
- iconName?: string;
40
40
  testId?: string;
41
41
  }
42
42
 
@@ -45,8 +45,8 @@ export const StepperHeaderElement: FC<StepperHeaderElementProps> = ({
45
45
  variant,
46
46
  appendIcon,
47
47
  prependIcon,
48
- icon,
49
- iconName,
48
+ appendIconTitle,
49
+ prependIconTitle,
50
50
  noLine,
51
51
  stepperNumber,
52
52
  testId,
@@ -61,14 +61,12 @@ export const StepperHeaderElement: FC<StepperHeaderElementProps> = ({
61
61
  const iconClass = classNames('icon', 'steppers-success');
62
62
  const spanClass = classNames('steppers-number');
63
63
 
64
- const iconToAppend = appendIcon || icon;
65
- const iconToPrepend = prependIcon || iconName;
66
64
  return (
67
65
  <Tag {...attributes} className={wrapperClasses} data-testid={testId}>
68
- {iconToPrepend && <Icon icon={iconToPrepend} />}
66
+ {prependIcon && <Icon icon={prependIcon} title={prependIconTitle} />}
69
67
  {stepperNumber && <span className={spanClass}>{stepperNumber}</span>}
70
68
  {children}
71
- {iconToAppend && <Icon icon={iconToAppend} className={iconClass} />}
69
+ {appendIcon && <Icon icon={appendIcon} title={appendIconTitle} className={iconClass} />}
72
70
  </Tag>
73
71
  );
74
72
  };
@@ -0,0 +1,111 @@
1
+ import classNames from 'classnames';
2
+ import React, { ElementType, FC, useRef } from 'react';
3
+ import { Nav, NavProps } from 'react-bootstrap';
4
+
5
+ export interface TabNavProps extends NavProps {
6
+ /** Utilizzarlo in caso di utilizzo di componenti personalizzati
7
+ * @default ul
8
+ */
9
+ tag?: ElementType;
10
+ /** Classi aggiuntive da usare per il componente Tab */
11
+ className?: string;
12
+ /** Imposta l'orientameno delle tab in verticale
13
+ * @default false
14
+ */
15
+ vertical?: boolean;
16
+ /** Imposta la tab con sfondo scuro
17
+ * @default false
18
+ */
19
+ dark?: boolean;
20
+ /** Imposta la tab con design tipo card
21
+ * @default false
22
+ */
23
+ card?: boolean;
24
+ testId?: string;
25
+ }
26
+
27
+ export const TabNav: FC<TabNavProps> = ({
28
+ className,
29
+ vertical = false,
30
+ dark = false,
31
+ card = false,
32
+ tag = 'ul',
33
+ testId,
34
+ ...attributes
35
+ }) => {
36
+ const Tag = tag;
37
+ const rootRef = useRef<HTMLInputElement>();
38
+
39
+ const classes = classNames(
40
+ className,
41
+ 'nav-tabs',
42
+ { 'nav-tabs-vertical': vertical },
43
+ { 'nav-dark': dark },
44
+ { 'nav-tabs-cards': card }
45
+ );
46
+ let currentTabIndex = 0;
47
+ let activeTabIndex = -1;
48
+
49
+ // Ugly workaround to keep Bootstrap Italia behaviour
50
+
51
+ const handleKeyDown = (event: React.KeyboardEvent<HTMLElement>, disabled: boolean = false) => {
52
+ const queriedElements = rootRef.current?.querySelectorAll('.nav-link');
53
+ if (queriedElements) {
54
+ for (let i = 0; i < queriedElements.length; i++) {
55
+ if (queriedElements[i].ariaSelected === 'true') {
56
+ activeTabIndex = i;
57
+ }
58
+ // Disabled elements ignore current focused tab
59
+ if (!disabled && document.activeElement === queriedElements[i]) {
60
+ currentTabIndex = i;
61
+ }
62
+ queriedElements[i].ariaSelected = 'false';
63
+ }
64
+ switch (event.key) {
65
+ case 'ArrowLeft':
66
+ case 'ArrowUp':
67
+ event.stopPropagation();
68
+ event.preventDefault();
69
+ if (currentTabIndex - 1 < 0) {
70
+ currentTabIndex = queriedElements.length;
71
+ }
72
+ currentTabIndex = (currentTabIndex - 1) % queriedElements.length;
73
+ break;
74
+ case 'ArrowRight':
75
+ case 'ArrowDown':
76
+ event.stopPropagation();
77
+ event.preventDefault();
78
+ currentTabIndex = (currentTabIndex + 1) % queriedElements.length;
79
+ break;
80
+ case 'Enter':
81
+ event.stopPropagation();
82
+ event.preventDefault();
83
+ (queriedElements[currentTabIndex] as HTMLElement).click();
84
+ break;
85
+ case 'Tab':
86
+ break;
87
+ default:
88
+ return;
89
+ }
90
+ if (queriedElements[currentTabIndex].ariaDisabled === 'true') {
91
+ handleKeyDown(event, true);
92
+ } else {
93
+ (queriedElements[currentTabIndex] as HTMLElement).focus({ preventScroll: true });
94
+ setTimeout(() => {
95
+ queriedElements[activeTabIndex].ariaSelected = 'true';
96
+ }, 300);
97
+ }
98
+ }
99
+ };
100
+
101
+ return (
102
+ <Nav
103
+ ref={rootRef}
104
+ as={Tag}
105
+ className={classes}
106
+ data-testid={testId}
107
+ {...attributes}
108
+ onKeyDown={handleKeyDown}
109
+ ></Nav>
110
+ );
111
+ };
@@ -0,0 +1,14 @@
1
+ import React, { ElementType, FC } from 'react';
2
+ import { Nav, NavItemProps } from 'react-bootstrap';
3
+
4
+ export interface TabNavItemProps extends NavItemProps {
5
+ /** Utilizzarlo in caso di utilizzo di componenti personalizzati */
6
+ tag?: ElementType;
7
+ testId?: string;
8
+ }
9
+
10
+ export const TabNavItem: FC<TabNavItemProps> = ({ tag = 'li', testId, ...attributes }) => {
11
+ const Tag = tag;
12
+
13
+ return <Nav.Item as={Tag} role='presentation' data-testid={testId} {...attributes}></Nav.Item>;
14
+ };
@@ -0,0 +1,14 @@
1
+ import React, { ElementType, FC } from 'react';
2
+ import { Nav, NavLinkProps } from 'react-bootstrap';
3
+
4
+ export interface TabNavLinkProps extends NavLinkProps {
5
+ /** Utilizzarlo in caso di utilizzo di componenti personalizzati */
6
+ tag?: ElementType;
7
+ testId?: string;
8
+ }
9
+
10
+ export const TabNavLink: FC<TabNavLinkProps> = ({ tag, testId, ...attributes }) => {
11
+ const Tag = tag;
12
+
13
+ return <Nav.Link as={Tag} data-testid={testId} {...attributes}></Nav.Link>;
14
+ };
@@ -0,0 +1,14 @@
1
+ import React, { ElementType, FC } from 'react';
2
+ import { NavProps, Tab } from 'react-bootstrap';
3
+
4
+ export interface TabsProps extends NavProps {
5
+ /** Utilizzarlo in caso di utilizzo di componenti personalizzati */
6
+ tag?: ElementType;
7
+ testId?: string;
8
+ }
9
+
10
+ export const TabContainer: FC<TabsProps> = ({ tag, testId, ...attributes }) => {
11
+ const Tag = tag;
12
+
13
+ return <Tab.Container as={Tag} data-testid={testId} {...attributes}></Tab.Container>;
14
+ };
@@ -40,7 +40,7 @@ export const TimelinePin: FC<TimelinePinProps> = ({
40
40
  nowText,
41
41
  testId,
42
42
  className,
43
- tag='h3',
43
+ tag = 'h3',
44
44
  ...attributes
45
45
  }) => {
46
46
  const { children, ...rest } = attributes;
@@ -51,7 +51,7 @@ export const TimelinePin: FC<TimelinePinProps> = ({
51
51
  });
52
52
  const pinIcon = (
53
53
  <div className='pin-icon'>
54
- <Icon icon={iconName || icon} role="img" title={iconTitle} />
54
+ <Icon icon={iconName || icon} role='img' title={iconTitle} />
55
55
  </div>
56
56
  );
57
57
  const pinLabel = (
@@ -23,7 +23,7 @@ export const Toggle: FC<ToggleProps> = ({ label, testId, ...rest }) => {
23
23
  <div className='toggles' data-testid={testId}>
24
24
  <Label check for={rest.id}>
25
25
  {label}
26
- <Input {...rest} type='checkbox' aria-describedby={rest.id ? rest.id + 'Description' : '' } />
26
+ <Input {...rest} type='checkbox' aria-describedby={rest.id ? rest.id + 'Description' : ''} />
27
27
  <span className='lever' />
28
28
  </Label>
29
29
  </div>