@jetbrains/ring-ui 7.0.102 → 7.0.104
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/components/button/button.css +12 -3
- package/components/button-group/button-group.css +28 -26
- package/components/header/profile.js +0 -1
- package/components/list/list.d.ts +5 -0
- package/components/list/list.js +14 -0
- package/components/tab-trap/tab-trap.js +19 -11
- package/package.json +2 -3
- package/postcss.config.js +0 -1
|
@@ -11,6 +11,8 @@
|
|
|
11
11
|
--ring-button-loader-components: var(--ring-main-components);
|
|
12
12
|
--ring-button-white-text-disabled-color: var(--ring-white-text-color);
|
|
13
13
|
--ring-button-icon-line-height: calc(var(--ring-unit) * 2);
|
|
14
|
+
--ring-button-border-radius-left: var(--ring-border-radius);
|
|
15
|
+
--ring-button-border-radius-right: var(--ring-border-radius);
|
|
14
16
|
}
|
|
15
17
|
|
|
16
18
|
:global(.ring-ui-theme-dark) {
|
|
@@ -66,7 +68,8 @@
|
|
|
66
68
|
color: var(--ring-button-text-color);
|
|
67
69
|
|
|
68
70
|
border: 0;
|
|
69
|
-
border-radius: var(--ring-border-radius)
|
|
71
|
+
border-radius: var(--ring-button-border-radius-left) var(--ring-button-border-radius-right)
|
|
72
|
+
var(--ring-button-border-radius-right) var(--ring-button-border-radius-left);
|
|
70
73
|
outline: 0;
|
|
71
74
|
|
|
72
75
|
background-color: var(--ring-button-background-color);
|
|
@@ -386,7 +389,10 @@
|
|
|
386
389
|
|
|
387
390
|
overflow: hidden;
|
|
388
391
|
|
|
389
|
-
border-radius: calc(var(--ring-border-radius) - 1px);
|
|
392
|
+
border-top-left-radius: max(0px, calc(var(--ring-button-border-radius-left) - 1px));
|
|
393
|
+
border-top-right-radius: max(0px, calc(var(--ring-button-border-radius-right) - 1px));
|
|
394
|
+
border-bottom-right-radius: max(0px, calc(var(--ring-button-border-radius-right) - 1px));
|
|
395
|
+
border-bottom-left-radius: max(0px, calc(var(--ring-button-border-radius-left) - 1px));
|
|
390
396
|
background-color: var(--ring-button-default-background-color);
|
|
391
397
|
|
|
392
398
|
&::before {
|
|
@@ -414,7 +420,10 @@
|
|
|
414
420
|
bottom: 0;
|
|
415
421
|
left: 0;
|
|
416
422
|
|
|
417
|
-
border-radius: var(--ring-border-radius);
|
|
423
|
+
border-top-left-radius: var(--ring-button-border-radius-left);
|
|
424
|
+
border-top-right-radius: var(--ring-button-border-radius-right);
|
|
425
|
+
border-bottom-right-radius: var(--ring-button-border-radius-right);
|
|
426
|
+
border-bottom-left-radius: var(--ring-button-border-radius-left);
|
|
418
427
|
}
|
|
419
428
|
|
|
420
429
|
.delayed::after {
|
|
@@ -118,24 +118,32 @@
|
|
|
118
118
|
/* stylelint-disable selector-max-specificity */
|
|
119
119
|
.buttonGroup .button.button:hover:not(:disabled),
|
|
120
120
|
.buttonGroup .button.button:active:not(:disabled) {
|
|
121
|
-
border-radius: var(--ring-border-radius);
|
|
121
|
+
--ring-button-border-radius-left: var(--ring-border-radius);
|
|
122
|
+
--ring-button-border-radius-right: var(--ring-border-radius);
|
|
123
|
+
|
|
122
124
|
box-shadow: var(--ring-button-shadow) var(--ring-button-border-color);
|
|
123
125
|
}
|
|
124
126
|
|
|
125
127
|
.buttonGroup .button.button:focus-visible {
|
|
126
|
-
border-radius: var(--ring-border-radius);
|
|
128
|
+
--ring-button-border-radius-left: var(--ring-border-radius);
|
|
129
|
+
--ring-button-border-radius-right: var(--ring-border-radius);
|
|
130
|
+
|
|
127
131
|
box-shadow:
|
|
128
132
|
var(--ring-button-shadow) var(--ring-border-hover-color),
|
|
129
133
|
0 0 0 1px var(--ring-border-hover-color);
|
|
130
134
|
}
|
|
131
135
|
|
|
132
136
|
.buttonGroup .button.button.active {
|
|
133
|
-
border-radius: var(--ring-border-radius);
|
|
137
|
+
--ring-button-border-radius-left: var(--ring-border-radius);
|
|
138
|
+
--ring-button-border-radius-right: var(--ring-border-radius);
|
|
139
|
+
|
|
134
140
|
box-shadow: var(--ring-button-shadow) var(--ring-button-border-color);
|
|
135
141
|
}
|
|
136
142
|
|
|
137
143
|
.buttonGroup .button:focus-visible.active {
|
|
138
|
-
border-radius: var(--ring-border-radius);
|
|
144
|
+
--ring-button-border-radius-left: var(--ring-border-radius);
|
|
145
|
+
--ring-button-border-radius-right: var(--ring-border-radius);
|
|
146
|
+
|
|
139
147
|
box-shadow:
|
|
140
148
|
var(--ring-button-shadow) var(--ring-button-border-color),
|
|
141
149
|
0 0 0 1px var(--ring-border-hover-color);
|
|
@@ -151,11 +159,15 @@
|
|
|
151
159
|
composes: buttonGroup from '../button-toolbar/button-toolbar.css';
|
|
152
160
|
}
|
|
153
161
|
|
|
154
|
-
.common button
|
|
155
|
-
.common .button {
|
|
162
|
+
.common button {
|
|
156
163
|
border-radius: 0;
|
|
157
164
|
}
|
|
158
165
|
|
|
166
|
+
.common .button {
|
|
167
|
+
--ring-button-border-radius-left: 0;
|
|
168
|
+
--ring-button-border-radius-right: 0;
|
|
169
|
+
}
|
|
170
|
+
|
|
159
171
|
.split button,
|
|
160
172
|
.split .button {
|
|
161
173
|
margin: 0 0 0 -1px;
|
|
@@ -173,39 +185,29 @@
|
|
|
173
185
|
}
|
|
174
186
|
}
|
|
175
187
|
|
|
176
|
-
.common > button:first-child
|
|
177
|
-
.common > .button:first-child,
|
|
178
|
-
.common > :first-child .button {
|
|
188
|
+
.common > button:first-child {
|
|
179
189
|
margin: 0;
|
|
180
190
|
|
|
181
191
|
border-top-left-radius: var(--ring-border-radius);
|
|
182
192
|
border-bottom-left-radius: var(--ring-border-radius);
|
|
183
193
|
}
|
|
184
194
|
|
|
185
|
-
|
|
186
|
-
.common >
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
border-bottom-right-radius: 0;
|
|
195
|
+
.common > .button:first-child,
|
|
196
|
+
.common > :first-child .button {
|
|
197
|
+
--ring-button-border-radius-left: var(--ring-border-radius);
|
|
198
|
+
|
|
199
|
+
margin: 0;
|
|
191
200
|
}
|
|
192
|
-
/* stylelint-enable */
|
|
193
201
|
|
|
194
|
-
.common >
|
|
195
|
-
.common > button:last-child,
|
|
196
|
-
.common > :last-child .button {
|
|
202
|
+
.common > button:last-child {
|
|
197
203
|
border-top-right-radius: var(--ring-border-radius);
|
|
198
204
|
border-bottom-right-radius: var(--ring-border-radius);
|
|
199
205
|
}
|
|
200
206
|
|
|
201
|
-
|
|
202
|
-
.common >
|
|
203
|
-
|
|
204
|
-
.common > :last-child .button > div:first-child {
|
|
205
|
-
border-top-left-radius: 0;
|
|
206
|
-
border-bottom-left-radius: 0;
|
|
207
|
+
.common > .button:last-child,
|
|
208
|
+
.common > :last-child .button {
|
|
209
|
+
--ring-button-border-radius-right: var(--ring-border-radius);
|
|
207
210
|
}
|
|
208
|
-
/* stylelint-enable */
|
|
209
211
|
|
|
210
212
|
.split .flat:not(:last-child) {
|
|
211
213
|
margin-right: 1px;
|
|
@@ -43,6 +43,9 @@ export interface ListProps<T = unknown> {
|
|
|
43
43
|
maxHeight?: number | null | undefined;
|
|
44
44
|
activeIndex?: number | null | undefined;
|
|
45
45
|
useMouseUp?: boolean | null | undefined;
|
|
46
|
+
/**
|
|
47
|
+
* @deprecated No longer used. Visibility is detected automatically via IntersectionObserver. Will be removed in Ring UI 8.0.
|
|
48
|
+
*/
|
|
46
49
|
visible?: boolean | null | undefined;
|
|
47
50
|
disableMoveOverflow?: boolean | null | undefined;
|
|
48
51
|
compact?: boolean | null | undefined;
|
|
@@ -130,6 +133,8 @@ export default class List<T = unknown> extends Component<ListProps<T>, ListState
|
|
|
130
133
|
virtualizedList?: VirtualizedList | null;
|
|
131
134
|
unmounted?: boolean;
|
|
132
135
|
container?: HTMLElement | null;
|
|
136
|
+
private intersectionObserver?;
|
|
137
|
+
private wasVisible;
|
|
133
138
|
private _bufferSize;
|
|
134
139
|
sizeCacheKey: (index: number) => string | Type.ITEM | Type.MARGIN;
|
|
135
140
|
private _cache;
|
package/components/list/list.js
CHANGED
|
@@ -122,6 +122,17 @@ export default class List extends Component {
|
|
|
122
122
|
if (!this.props.renderOptimization) {
|
|
123
123
|
this.scrollToActive();
|
|
124
124
|
}
|
|
125
|
+
if (this.props.renderOptimization && this.container && typeof IntersectionObserver !== 'undefined') {
|
|
126
|
+
this.intersectionObserver = new IntersectionObserver(entries => {
|
|
127
|
+
for (const entry of entries) {
|
|
128
|
+
if (entry.isIntersecting && !this.wasVisible && this.virtualizedList) {
|
|
129
|
+
this.virtualizedList.recomputeRowHeights();
|
|
130
|
+
}
|
|
131
|
+
this.wasVisible = entry.isIntersecting;
|
|
132
|
+
}
|
|
133
|
+
});
|
|
134
|
+
this.intersectionObserver.observe(this.container);
|
|
135
|
+
}
|
|
125
136
|
}
|
|
126
137
|
shouldComponentUpdate(nextProps, nextState) {
|
|
127
138
|
return (Object.keys(nextProps).some(key => !Object.is(nextProps[key], this.props[key])) ||
|
|
@@ -145,6 +156,7 @@ export default class List extends Component {
|
|
|
145
156
|
this.checkOverflow();
|
|
146
157
|
}
|
|
147
158
|
componentWillUnmount() {
|
|
159
|
+
this.intersectionObserver?.disconnect();
|
|
148
160
|
this.unmounted = true;
|
|
149
161
|
}
|
|
150
162
|
scheduleScrollListener = scheduleRAF();
|
|
@@ -157,6 +169,8 @@ export default class List extends Component {
|
|
|
157
169
|
virtualizedList;
|
|
158
170
|
unmounted;
|
|
159
171
|
container;
|
|
172
|
+
intersectionObserver;
|
|
173
|
+
wasVisible = false;
|
|
160
174
|
// eslint-disable-next-line no-magic-numbers
|
|
161
175
|
_bufferSize = 10; // keep X items above and below of the visible area
|
|
162
176
|
// reuse size cache for similar items
|
|
@@ -9,7 +9,7 @@ const TabTrap = forwardRef(function TabTrap({ children, trapDisabled = false, au
|
|
|
9
9
|
const trapButtonNodeRef = useRef(null);
|
|
10
10
|
const previousFocusedNodeRef = useRef(null);
|
|
11
11
|
const trapWithoutFocusRef = useRef(false);
|
|
12
|
-
const mountedRef = useRef(
|
|
12
|
+
const mountedRef = useRef(undefined);
|
|
13
13
|
// It's the same approach as in focus-trap-react:
|
|
14
14
|
// https://github.com/focus-trap/focus-trap-react/commit/3b22fca9eebeb883edc89548850fe5a5b9d6d50e
|
|
15
15
|
// We can't do it in useEffect because it's too late, some children might have already
|
|
@@ -18,16 +18,16 @@ const TabTrap = forwardRef(function TabTrap({ children, trapDisabled = false, au
|
|
|
18
18
|
previousFocusedNodeRef.current = document.activeElement;
|
|
19
19
|
}
|
|
20
20
|
useImperativeHandle(ref, () => ({ node: nodeRef.current }), []);
|
|
21
|
-
function
|
|
21
|
+
function restoreFocusIfUnmounted(orElse) {
|
|
22
22
|
const previousFocusedNode = previousFocusedNodeRef.current;
|
|
23
23
|
if (previousFocusedNode instanceof HTMLElement &&
|
|
24
24
|
previousFocusedNode.focus &&
|
|
25
|
-
isNodeInVisiblePartOfPage(previousFocusedNode)
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
25
|
+
isNodeInVisiblePartOfPage(previousFocusedNode) &&
|
|
26
|
+
mountedRef.current === false) {
|
|
27
|
+
previousFocusedNode.focus({ preventScroll: true });
|
|
28
|
+
}
|
|
29
|
+
else {
|
|
30
|
+
orElse?.();
|
|
31
31
|
}
|
|
32
32
|
}
|
|
33
33
|
function focusElement(first = true) {
|
|
@@ -65,7 +65,7 @@ const TabTrap = forwardRef(function TabTrap({ children, trapDisabled = false, au
|
|
|
65
65
|
}
|
|
66
66
|
return () => {
|
|
67
67
|
if (focusBackOnClose) {
|
|
68
|
-
|
|
68
|
+
restoreFocusIfUnmounted();
|
|
69
69
|
}
|
|
70
70
|
};
|
|
71
71
|
}, [autoFocusFirst, trapDisabled, focusBackOnClose, focusFirst]);
|
|
@@ -76,7 +76,7 @@ const TabTrap = forwardRef(function TabTrap({ children, trapDisabled = false, au
|
|
|
76
76
|
if (focusBackOnExit) {
|
|
77
77
|
const prevFocused = event.nativeEvent.relatedTarget;
|
|
78
78
|
if (prevFocused && nodeRef.current && prevFocused instanceof Element && nodeRef.current.contains(prevFocused)) {
|
|
79
|
-
|
|
79
|
+
restoreFocusIfUnmounted(focusLast);
|
|
80
80
|
}
|
|
81
81
|
}
|
|
82
82
|
else {
|
|
@@ -97,6 +97,14 @@ const TabTrap = forwardRef(function TabTrap({ children, trapDisabled = false, au
|
|
|
97
97
|
}
|
|
98
98
|
focusLast();
|
|
99
99
|
}
|
|
100
|
+
function restoreFocusOrFocusFirst() {
|
|
101
|
+
if (focusBackOnExit) {
|
|
102
|
+
restoreFocusIfUnmounted(focusFirst);
|
|
103
|
+
}
|
|
104
|
+
else {
|
|
105
|
+
focusFirst();
|
|
106
|
+
}
|
|
107
|
+
}
|
|
100
108
|
if (trapDisabled) {
|
|
101
109
|
return (<div ref={nodeRef} {...restProps}>
|
|
102
110
|
{children}
|
|
@@ -111,7 +119,7 @@ const TabTrap = forwardRef(function TabTrap({ children, trapDisabled = false, au
|
|
|
111
119
|
<div
|
|
112
120
|
// It never actually stays focused
|
|
113
121
|
// eslint-disable-next-line jsx-a11y/no-noninteractive-tabindex
|
|
114
|
-
tabIndex={0} onFocus={
|
|
122
|
+
tabIndex={0} onFocus={restoreFocusOrFocusFirst} data-trap-button/>
|
|
115
123
|
</div>);
|
|
116
124
|
});
|
|
117
125
|
export default TabTrap;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jetbrains/ring-ui",
|
|
3
|
-
"version": "7.0.
|
|
3
|
+
"version": "7.0.104",
|
|
4
4
|
"description": "JetBrains UI library",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "JetBrains"
|
|
@@ -191,7 +191,7 @@
|
|
|
191
191
|
"vitest": "^4.0.18",
|
|
192
192
|
"vitest-teamcity-reporter": "^0.4.1",
|
|
193
193
|
"webpack": "^5.105.4",
|
|
194
|
-
"webpack-cli": "^
|
|
194
|
+
"webpack-cli": "^7.0.0",
|
|
195
195
|
"xmlappend": "^1.0.4"
|
|
196
196
|
},
|
|
197
197
|
"peerDependencies": {
|
|
@@ -243,7 +243,6 @@
|
|
|
243
243
|
"memoize-one": "^6.0.0",
|
|
244
244
|
"postcss": "^8.5.8",
|
|
245
245
|
"postcss-calc": "^10.1.1",
|
|
246
|
-
"postcss-flexbugs-fixes": "^5.0.2",
|
|
247
246
|
"postcss-font-family-system-ui": "^5.0.0",
|
|
248
247
|
"postcss-loader": "^8.2.1",
|
|
249
248
|
"postcss-modules-values-replace": "^4.2.2",
|
package/postcss.config.js
CHANGED