design-react-kit 5.9.3 → 5.10.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.
- package/CHANGELOG.md +11 -0
- package/dist/Collapse/Collapse.cjs +1 -1
- package/dist/Collapse/Collapse.cjs.map +1 -1
- package/dist/Collapse/Collapse.js +75 -7
- package/dist/Collapse/Collapse.js.map +1 -1
- package/dist/Input/Input.cjs +1 -1
- package/dist/Input/Input.cjs.map +1 -1
- package/dist/Input/Input.js +2 -14
- package/dist/Input/Input.js.map +1 -1
- package/dist/Rating/Rating.cjs +1 -1
- package/dist/Rating/Rating.cjs.map +1 -1
- package/dist/Transfer/Item.cjs +1 -1
- package/dist/Transfer/Item.cjs.map +1 -1
- package/dist/Transfer/SelectAllCheckbox.cjs +1 -1
- package/dist/Transfer/SelectAllCheckbox.cjs.map +1 -1
- package/dist/Transfer/Source.cjs +1 -1
- package/dist/Transfer/Source.cjs.map +1 -1
- package/dist/Transfer/Target.cjs +1 -1
- package/dist/Transfer/Target.cjs.map +1 -1
- package/dist/Transfer/Transfer.cjs +1 -1
- package/dist/Transfer/Transfer.cjs.map +1 -1
- package/dist/Video/Video.cjs +1 -1
- package/dist/Video/Video.cjs.map +1 -1
- package/dist/index.cjs +1 -1
- package/dist/index.cjs.map +1 -1
- package/package.json +3 -3
- package/src/Collapse/Collapse.tsx +80 -7
- package/src/Input/Input.tsx +1 -15
package/package.json
CHANGED
|
@@ -25,7 +25,7 @@
|
|
|
25
25
|
"bugs": {
|
|
26
26
|
"url": "https://github.com/italia/design-react-kit/issues"
|
|
27
27
|
},
|
|
28
|
-
"version": "5.
|
|
28
|
+
"version": "5.10.0",
|
|
29
29
|
"license": "BSD-3",
|
|
30
30
|
"type": "module",
|
|
31
31
|
"module": "./dist/index.js",
|
|
@@ -72,7 +72,7 @@
|
|
|
72
72
|
"postversion": "echo \"You can now publish your version using 'git push --follow-tags'\""
|
|
73
73
|
},
|
|
74
74
|
"peerDependencies": {
|
|
75
|
-
"bootstrap-italia": "^2.
|
|
75
|
+
"bootstrap-italia": "^2.18.0",
|
|
76
76
|
"react": ">=18.2.0"
|
|
77
77
|
},
|
|
78
78
|
"browserslist": [
|
|
@@ -105,7 +105,7 @@
|
|
|
105
105
|
"@types/react-dom": "^18.2.24",
|
|
106
106
|
"@types/react-transition-group": "^4.4.10",
|
|
107
107
|
"@types/uuid": "^10.0.0",
|
|
108
|
-
"bootstrap-italia": "^2.
|
|
108
|
+
"bootstrap-italia": "^2.18.0",
|
|
109
109
|
"browserslist-config-design-italia": "^1.0.0",
|
|
110
110
|
"conventional-changelog": "^7.1.1",
|
|
111
111
|
"eslint": "^9.10.0",
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import classNames from 'classnames';
|
|
2
|
-
import React, { ElementType, FC, HTMLAttributes, Ref } from 'react';
|
|
2
|
+
import React, { ElementType, FC, HTMLAttributes, Ref, useEffect, useRef, useState } from 'react';
|
|
3
3
|
|
|
4
4
|
import { Collapse as CollapseBase } from 'reactstrap';
|
|
5
5
|
import { CSSModule } from 'reactstrap/types/lib/utils';
|
|
@@ -63,25 +63,98 @@ export const Collapse: FC<CollapseProps> = ({
|
|
|
63
63
|
'navbar-collapse': 'navbar-collapsable',
|
|
64
64
|
...cssModule
|
|
65
65
|
};
|
|
66
|
+
|
|
67
|
+
// Two-phase state to allow CSS transitions to play.
|
|
68
|
+
// isVisible controls display:block/none; isExpanded controls the animation class.
|
|
69
|
+
const [isVisible, setIsVisible] = useState(isOpen);
|
|
70
|
+
const [isExpanded, setIsExpanded] = useState(isOpen);
|
|
71
|
+
const panelRef = useRef<HTMLElement>(null);
|
|
72
|
+
const triggerRef = useRef<Element | null>(null);
|
|
73
|
+
|
|
74
|
+
useEffect(() => {
|
|
75
|
+
if (!(megamenu || navbar)) return;
|
|
76
|
+
if (isOpen) {
|
|
77
|
+
triggerRef.current = document.activeElement;
|
|
78
|
+
setIsVisible(true);
|
|
79
|
+
// Double rAF ensures the browser has painted display:block before adding
|
|
80
|
+
// the expanded class, so the CSS transform transition can fire.
|
|
81
|
+
requestAnimationFrame(() => {
|
|
82
|
+
requestAnimationFrame(() => {
|
|
83
|
+
setIsExpanded(true);
|
|
84
|
+
panelRef.current?.focus();
|
|
85
|
+
});
|
|
86
|
+
});
|
|
87
|
+
return;
|
|
88
|
+
}
|
|
89
|
+
setIsExpanded(false);
|
|
90
|
+
// Wait for the CSS transition to complete before hiding.
|
|
91
|
+
const timer = setTimeout(() => {
|
|
92
|
+
setIsVisible(false);
|
|
93
|
+
(triggerRef.current as HTMLElement | null)?.focus();
|
|
94
|
+
}, PANEL_TRANSITION_MS);
|
|
95
|
+
return () => clearTimeout(timer);
|
|
96
|
+
}, [isOpen, megamenu, navbar]);
|
|
97
|
+
|
|
98
|
+
useEffect(() => {
|
|
99
|
+
if (!(megamenu || navbar)) return;
|
|
100
|
+
if (isOpen) {
|
|
101
|
+
document.body.style.overflow = 'hidden';
|
|
102
|
+
} else {
|
|
103
|
+
document.body.style.overflow = '';
|
|
104
|
+
}
|
|
105
|
+
return () => { document.body.style.overflow = ''; };
|
|
106
|
+
}, [isOpen, megamenu, navbar]);
|
|
107
|
+
|
|
108
|
+
useEffect(() => {
|
|
109
|
+
if (!(megamenu || navbar)) return;
|
|
110
|
+
const main = document.querySelector('main');
|
|
111
|
+
if (!main) return;
|
|
112
|
+
if (isOpen) {
|
|
113
|
+
main.setAttribute('inert', '');
|
|
114
|
+
} else {
|
|
115
|
+
main.removeAttribute('inert');
|
|
116
|
+
}
|
|
117
|
+
return () => main.removeAttribute('inert');
|
|
118
|
+
}, [isOpen, megamenu, navbar]);
|
|
119
|
+
|
|
120
|
+
useEffect(() => {
|
|
121
|
+
if (!(megamenu || navbar)) return;
|
|
122
|
+
const handleKeyDown = (e: KeyboardEvent) => {
|
|
123
|
+
if (e.key === 'Escape' && isOpen) {
|
|
124
|
+
onOverlayClick?.();
|
|
125
|
+
}
|
|
126
|
+
};
|
|
127
|
+
document.addEventListener('keydown', handleKeyDown);
|
|
128
|
+
return () => document.removeEventListener('keydown', handleKeyDown);
|
|
129
|
+
}, [isOpen, megamenu, navbar, onOverlayClick]);
|
|
130
|
+
|
|
131
|
+
// Must match the longest CSS transition on .navbar-collapsable (currently 0.3s + buffer).
|
|
132
|
+
const PANEL_TRANSITION_MS = 350;
|
|
133
|
+
|
|
66
134
|
if (megamenu || navbar) {
|
|
67
135
|
const classes = classNames(className, 'navbar-collapse', {
|
|
68
|
-
expanded:
|
|
136
|
+
expanded: isExpanded
|
|
69
137
|
});
|
|
70
|
-
const style = { display: isOpen ? 'block' : 'none' };
|
|
71
138
|
const overlayClasses = classNames('overlay', {
|
|
72
|
-
fade:
|
|
73
|
-
show:
|
|
139
|
+
fade: isVisible,
|
|
140
|
+
show: isExpanded
|
|
74
141
|
});
|
|
142
|
+
const displayStyle = { display: isVisible ? 'block' : 'none' };
|
|
75
143
|
return (
|
|
76
144
|
<CollapseBase
|
|
77
145
|
className={classes}
|
|
78
146
|
cssModule={newCssModule}
|
|
79
147
|
navbar={navbar}
|
|
80
|
-
style={
|
|
148
|
+
style={displayStyle}
|
|
149
|
+
tabIndex={-1}
|
|
150
|
+
innerRef={panelRef}
|
|
151
|
+
role={isOpen ? 'dialog' : undefined}
|
|
152
|
+
aria-modal={isOpen ? true : undefined}
|
|
153
|
+
aria-label={isOpen ? 'Menu di navigazione' : undefined}
|
|
81
154
|
data-testid={testId}
|
|
82
155
|
{...attributes}
|
|
83
156
|
>
|
|
84
|
-
<div className={overlayClasses} style={
|
|
157
|
+
<div className={overlayClasses} style={displayStyle} onClick={onOverlayClick}></div>
|
|
85
158
|
<div className='close-div'>
|
|
86
159
|
<button className='btn close-menu' type='button' onClick={onOverlayClick}>
|
|
87
160
|
<span className='visually-hidden'>{closeSrText}</span>
|
package/src/Input/Input.tsx
CHANGED
|
@@ -5,7 +5,6 @@ import React, {
|
|
|
5
5
|
ReactNode,
|
|
6
6
|
Ref,
|
|
7
7
|
useCallback,
|
|
8
|
-
useEffect,
|
|
9
8
|
useRef,
|
|
10
9
|
useState
|
|
11
10
|
} from 'react';
|
|
@@ -152,19 +151,7 @@ export const Input = ({
|
|
|
152
151
|
toggleIcon(!hasIcon);
|
|
153
152
|
}, [hasIcon, isHidden]);
|
|
154
153
|
|
|
155
|
-
const divResizeRef = useRef<HTMLDivElement>(null);
|
|
156
154
|
const inputRef = useRef<HTMLInputElement>(null);
|
|
157
|
-
const [width, setWidth] = useState('100');
|
|
158
|
-
|
|
159
|
-
useEffect(() => {
|
|
160
|
-
if (divResizeRef.current != null && divResizeRef.current.classList.contains('input-number-adaptive')) {
|
|
161
|
-
if (!value) {
|
|
162
|
-
setWidth(`calc(70px)`);
|
|
163
|
-
} else {
|
|
164
|
-
setWidth(`calc(70px + ${`${value}`.length}ch)`);
|
|
165
|
-
}
|
|
166
|
-
}
|
|
167
|
-
}, [value]);
|
|
168
155
|
|
|
169
156
|
// eslint-disable-next-line prefer-const
|
|
170
157
|
let { bsSize, valid, ...rest } = attributes;
|
|
@@ -312,8 +299,7 @@ export const Input = ({
|
|
|
312
299
|
disabled: rest.disabled,
|
|
313
300
|
'input-number-adaptive': type === 'adaptive'
|
|
314
301
|
})}
|
|
315
|
-
style={{ width }}
|
|
316
|
-
ref={divResizeRef}
|
|
302
|
+
style={type === 'adaptive' ? { width: !value ? '70px' : `min(calc(70px + ${`${value}`.length}ch), 100%)` } : undefined}
|
|
317
303
|
>
|
|
318
304
|
{['currency', 'percentage'].includes(type) && (
|
|
319
305
|
<span className='input-group-text fw-semibold'>{addonText}</span>
|