@canonical/react-components 0.47.4 → 0.48.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/README.md
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
# React components for Vanilla Framework
|
|
2
|
-

|
|
2
|
+

|
|
3
3
|
|
|
4
4
|
This is a collection of components designed to be the way to consume [Vanilla Framework](http://vanillaframework.io) when using React.
|
|
5
5
|
|
|
@@ -30,7 +30,7 @@ let Label = exports.Label = /*#__PURE__*/function (Label) {
|
|
|
30
30
|
* @param positionCoords - The coordinates of the position node.
|
|
31
31
|
* @param constrainPanelWidth - Whether the menu width should be constrained to the position width.
|
|
32
32
|
*/
|
|
33
|
-
const getPositionStyle = (position, positionCoords, constrainPanelWidth) => {
|
|
33
|
+
const getPositionStyle = (position, verticalPosition, positionCoords, constrainPanelWidth) => {
|
|
34
34
|
if (!positionCoords) {
|
|
35
35
|
return null;
|
|
36
36
|
}
|
|
@@ -40,7 +40,7 @@ const getPositionStyle = (position, positionCoords, constrainPanelWidth) => {
|
|
|
40
40
|
top,
|
|
41
41
|
width
|
|
42
42
|
} = positionCoords;
|
|
43
|
-
const topPos = top + height + (window.scrollY || 0);
|
|
43
|
+
const topPos = verticalPosition === "bottom" ? top + height + (window.scrollY || 0) : top + (window.scrollY || 0);
|
|
44
44
|
let leftPos = left;
|
|
45
45
|
switch (position) {
|
|
46
46
|
case "left":
|
|
@@ -120,6 +120,20 @@ const generateLink = (link, key, handleClose) => {
|
|
|
120
120
|
} : null
|
|
121
121
|
}, props), children);
|
|
122
122
|
};
|
|
123
|
+
const getClosestScrollableParent = node => {
|
|
124
|
+
let currentNode = node;
|
|
125
|
+
while (currentNode && currentNode !== document.body) {
|
|
126
|
+
const {
|
|
127
|
+
overflowY,
|
|
128
|
+
overflowX
|
|
129
|
+
} = window.getComputedStyle(currentNode);
|
|
130
|
+
if (["auto", "scroll", "overlay"].includes(overflowY) && ["auto", "scroll", "overlay"].includes(overflowX)) {
|
|
131
|
+
return currentNode;
|
|
132
|
+
}
|
|
133
|
+
currentNode = currentNode.parentElement;
|
|
134
|
+
}
|
|
135
|
+
return document.body;
|
|
136
|
+
};
|
|
123
137
|
const ContextualMenuDropdown = _ref => {
|
|
124
138
|
let {
|
|
125
139
|
adjustedPosition,
|
|
@@ -140,23 +154,46 @@ const ContextualMenuDropdown = _ref => {
|
|
|
140
154
|
...props
|
|
141
155
|
} = _ref;
|
|
142
156
|
const dropdown = (0, _react.useRef)();
|
|
143
|
-
const [
|
|
157
|
+
const [verticalPosition, setVerticalPosition] = (0, _react.useState)("bottom");
|
|
158
|
+
const [positionStyle, setPositionStyle] = (0, _react.useState)(getPositionStyle(adjustedPosition, verticalPosition, positionCoords, constrainPanelWidth));
|
|
144
159
|
const [maxHeight, setMaxHeight] = (0, _react.useState)();
|
|
145
|
-
|
|
146
160
|
// Update the styles to position the menu.
|
|
147
161
|
const updatePositionStyle = (0, _react.useCallback)(() => {
|
|
148
|
-
setPositionStyle(getPositionStyle(adjustedPosition, positionCoords, constrainPanelWidth));
|
|
149
|
-
}, [adjustedPosition, positionCoords, constrainPanelWidth]);
|
|
162
|
+
setPositionStyle(getPositionStyle(adjustedPosition, verticalPosition, positionCoords, constrainPanelWidth));
|
|
163
|
+
}, [adjustedPosition, positionCoords, verticalPosition, constrainPanelWidth]);
|
|
164
|
+
const updateVerticalPosition = (0, _react.useCallback)(() => {
|
|
165
|
+
if (!positionNode) {
|
|
166
|
+
return null;
|
|
167
|
+
}
|
|
168
|
+
const scrollableParent = getClosestScrollableParent(positionNode);
|
|
169
|
+
if (!scrollableParent) {
|
|
170
|
+
return null;
|
|
171
|
+
}
|
|
172
|
+
const scrollableParentRect = scrollableParent.getBoundingClientRect();
|
|
173
|
+
const rect = positionNode.getBoundingClientRect();
|
|
174
|
+
|
|
175
|
+
// Calculate the rect in relation to the scrollableParent
|
|
176
|
+
const relativeRect = {
|
|
177
|
+
top: rect.top - scrollableParentRect.top,
|
|
178
|
+
bottom: rect.bottom - scrollableParentRect.top,
|
|
179
|
+
height: rect.height
|
|
180
|
+
};
|
|
181
|
+
const spaceBelow = scrollableParentRect.height - relativeRect.bottom;
|
|
182
|
+
const spaceAbove = relativeRect.top;
|
|
183
|
+
const dropdownHeight = relativeRect.height;
|
|
184
|
+
setVerticalPosition(spaceBelow >= dropdownHeight || spaceBelow > spaceAbove ? "bottom" : "top");
|
|
185
|
+
}, [positionNode]);
|
|
150
186
|
|
|
151
187
|
// Update the position when the window fitment info changes.
|
|
152
188
|
const onUpdateWindowFitment = (0, _react.useCallback)(fitsWindow => {
|
|
153
189
|
if (autoAdjust) {
|
|
154
190
|
setAdjustedPosition(adjustForWindow(position, fitsWindow));
|
|
191
|
+
updateVerticalPosition();
|
|
155
192
|
}
|
|
156
193
|
if (scrollOverflow) {
|
|
157
194
|
setMaxHeight(fitsWindow.fromBottom.spaceBelow - 16);
|
|
158
195
|
}
|
|
159
|
-
}, [autoAdjust, position, scrollOverflow, setAdjustedPosition]);
|
|
196
|
+
}, [autoAdjust, position, scrollOverflow, setAdjustedPosition, updateVerticalPosition]);
|
|
160
197
|
|
|
161
198
|
// Handle adjusting the horizontal position and scrolling of the dropdown so that it remains on screen.
|
|
162
199
|
(0, _hooks.useWindowFitment)(dropdown.current, positionNode, onUpdateWindowFitment, 0, isOpen && (autoAdjust || scrollOverflow));
|
|
@@ -165,6 +202,9 @@ const ContextualMenuDropdown = _ref => {
|
|
|
165
202
|
(0, _react.useEffect)(() => {
|
|
166
203
|
updatePositionStyle();
|
|
167
204
|
}, [adjustedPosition, updatePositionStyle]);
|
|
205
|
+
(0, _react.useEffect)(() => {
|
|
206
|
+
updateVerticalPosition();
|
|
207
|
+
}, [updateVerticalPosition]);
|
|
168
208
|
return (
|
|
169
209
|
/*#__PURE__*/
|
|
170
210
|
// Vanilla Framework uses .p-contextual-menu parent modifier classnames to determine the correct position of the .p-contextual-menu__dropdown dropdown (left, center, right).
|
|
@@ -188,6 +228,9 @@ const ContextualMenuDropdown = _ref => {
|
|
|
188
228
|
maxHeight,
|
|
189
229
|
minHeight: "2rem",
|
|
190
230
|
overflowX: "auto"
|
|
231
|
+
} : {}),
|
|
232
|
+
...(verticalPosition === "top" ? {
|
|
233
|
+
bottom: "0"
|
|
191
234
|
} : {})
|
|
192
235
|
}
|
|
193
236
|
}, props), dropdownContent ? typeof dropdownContent === "function" ? dropdownContent(handleClose) : dropdownContent : links.map((item, i) => {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@canonical/react-components",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.48.0",
|
|
4
4
|
"main": "dist/index.js",
|
|
5
5
|
"module": "dist/index.js",
|
|
6
6
|
"author": "Huw Wilkins <huw.wilkins@canonical.com>",
|
|
@@ -26,7 +26,7 @@
|
|
|
26
26
|
"@babel/eslint-parser": "7.23.3",
|
|
27
27
|
"@babel/preset-typescript": "7.23.3",
|
|
28
28
|
"@percy/cli": "1.27.6",
|
|
29
|
-
"@percy/storybook": "
|
|
29
|
+
"@percy/storybook": "5.0.1",
|
|
30
30
|
"@semantic-release/changelog": "6.0.3",
|
|
31
31
|
"@semantic-release/git": "10.0.1",
|
|
32
32
|
"@storybook/addon-a11y": "7.6.7",
|
|
@@ -38,64 +38,65 @@
|
|
|
38
38
|
"@storybook/blocks": "7.6.7",
|
|
39
39
|
"@storybook/react": "7.6.7",
|
|
40
40
|
"@storybook/react-webpack5": "7.6.7",
|
|
41
|
-
"@testing-library/cypress": "
|
|
41
|
+
"@testing-library/cypress": "10.0.1",
|
|
42
42
|
"@testing-library/dom": "9.3.3",
|
|
43
|
-
"@testing-library/jest-dom": "
|
|
43
|
+
"@testing-library/jest-dom": "6.2.1",
|
|
44
44
|
"@testing-library/react": "14.1.2",
|
|
45
45
|
"@testing-library/user-event": "14.5.2",
|
|
46
|
-
"@typescript-eslint/eslint-plugin": "
|
|
47
|
-
"@typescript-eslint/parser": "
|
|
48
|
-
"babel-jest": "
|
|
46
|
+
"@typescript-eslint/eslint-plugin": "6.19.1",
|
|
47
|
+
"@typescript-eslint/parser": "6.19.1",
|
|
48
|
+
"babel-jest": "29.7.0",
|
|
49
49
|
"babel-loader": "9.1.3",
|
|
50
50
|
"babel-plugin-module-resolver": "5.0.0",
|
|
51
51
|
"babel-plugin-typescript-to-proptypes": "2.1.0",
|
|
52
52
|
"concurrently": "8.2.2",
|
|
53
53
|
"css-loader": "6.8.1",
|
|
54
|
-
"cypress": "
|
|
54
|
+
"cypress": "13.6.3",
|
|
55
55
|
"deepmerge": "4.3.1",
|
|
56
56
|
"eslint": "8.56.0",
|
|
57
|
-
"eslint-config-prettier": "
|
|
57
|
+
"eslint-config-prettier": "9.1.0",
|
|
58
58
|
"eslint-config-react-app": "7.0.1",
|
|
59
59
|
"eslint-plugin-cypress": "2.15.1",
|
|
60
60
|
"eslint-plugin-flowtype": "8.0.3",
|
|
61
61
|
"eslint-plugin-import": "2.29.1",
|
|
62
62
|
"eslint-plugin-jsx-a11y": "6.8.0",
|
|
63
|
-
"eslint-plugin-prettier": "
|
|
63
|
+
"eslint-plugin-prettier": "5.1.3",
|
|
64
64
|
"eslint-plugin-react": "7.33.2",
|
|
65
65
|
"eslint-plugin-react-hooks": "4.6.0",
|
|
66
66
|
"eslint-plugin-storybook": "0.6.15",
|
|
67
|
-
"eslint-plugin-testing-library": "
|
|
68
|
-
"jest": "
|
|
69
|
-
"npm-package-json-lint": "
|
|
70
|
-
"prettier": "2.
|
|
67
|
+
"eslint-plugin-testing-library": "6.2.0",
|
|
68
|
+
"jest": "29.7.0",
|
|
69
|
+
"npm-package-json-lint": "7.1.0",
|
|
70
|
+
"prettier": "3.2.4",
|
|
71
71
|
"react": "18.2.0",
|
|
72
72
|
"react-docgen-typescript-loader": "3.7.2",
|
|
73
73
|
"react-dom": "18.2.0",
|
|
74
74
|
"sass": "1.69.7",
|
|
75
|
-
"sass-loader": "
|
|
75
|
+
"sass-loader": "14.0.0",
|
|
76
76
|
"semantic-release": "23.0.0",
|
|
77
77
|
"storybook": "7.6.7",
|
|
78
78
|
"style-loader": "3.3.3",
|
|
79
|
-
"stylelint": "
|
|
79
|
+
"stylelint": "16.2.0",
|
|
80
80
|
"stylelint-config-prettier": "9.0.5",
|
|
81
|
-
"stylelint-config-recommended-scss": "
|
|
82
|
-
"stylelint-order": "
|
|
83
|
-
"stylelint-prettier": "
|
|
84
|
-
"ts-jest": "
|
|
81
|
+
"stylelint-config-recommended-scss": "14.0.0",
|
|
82
|
+
"stylelint-order": "6.0.4",
|
|
83
|
+
"stylelint-prettier": "5.0.0",
|
|
84
|
+
"ts-jest": "29.1.2",
|
|
85
85
|
"tsc-alias": "1.8.8",
|
|
86
|
-
"typescript": "
|
|
86
|
+
"typescript": "5.3.3",
|
|
87
87
|
"vanilla-framework": "4.6.0",
|
|
88
|
-
"wait-on": "
|
|
88
|
+
"wait-on": "7.2.0",
|
|
89
89
|
"webpack": "5.89.0"
|
|
90
90
|
},
|
|
91
91
|
"dependencies": {
|
|
92
|
-
"@types/jest": "
|
|
92
|
+
"@types/jest": "29.5.11",
|
|
93
93
|
"@types/node": "18.19.4",
|
|
94
94
|
"@types/react": "18.2.46",
|
|
95
95
|
"@types/react-dom": "18.2.18",
|
|
96
96
|
"@types/react-table": "7.7.19",
|
|
97
97
|
"classnames": "2.5.1",
|
|
98
|
-
"
|
|
98
|
+
"jest-environment-jsdom": "29.7.0",
|
|
99
|
+
"nanoid": "5.0.4",
|
|
99
100
|
"prop-types": "15.8.1",
|
|
100
101
|
"react-table": "7.8.0",
|
|
101
102
|
"react-useportal": "1.0.19"
|
|
@@ -104,10 +105,7 @@
|
|
|
104
105
|
"@types/react": "18.2.46",
|
|
105
106
|
"@types/react-dom": "18.2.18",
|
|
106
107
|
"postcss": "^8.3.11",
|
|
107
|
-
"
|
|
108
|
-
"jackspeak": "^2",
|
|
109
|
-
"strip-ansi": "^6.0.0",
|
|
110
|
-
"strip-ansi-cjs": "^8.0.0"
|
|
108
|
+
"jackspeak": "2.1.1"
|
|
111
109
|
},
|
|
112
110
|
"peerDependencies": {
|
|
113
111
|
"@types/react": "^17.0.2 || ^18.0.0",
|