@jetbrains/ring-ui 7.0.60 → 7.0.62

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.
@@ -51,7 +51,7 @@ export declare class Button extends PureComponent<ButtonProps> {
51
51
  * @deprecated Use icons with appropriate intrinsic sizes instead
52
52
  */
53
53
  static IconSize: typeof Size;
54
- static contextType: React.Context<ControlsHeight>;
54
+ static contextType: React.Context<ControlsHeight | (() => ControlsHeight)>;
55
55
  context: React.ContextType<typeof ControlsHeightContext>;
56
56
  buttonRef: React.RefObject<HTMLButtonElement | null>;
57
57
  render(): import("react/jsx-runtime").JSX.Element;
@@ -40,7 +40,7 @@ export class Button extends PureComponent {
40
40
  const classes = getButtonClasses({
41
41
  ...this.props,
42
42
  inline: isInline,
43
- height: height ?? this.context,
43
+ height: height ?? (typeof this.context === 'function' ? this.context() : this.context),
44
44
  });
45
45
  const content = (_jsxs(_Fragment, { children: [icon && (_jsx(Icon, { className: classNames(styles.icon, iconClassName), glyph: icon, size: iconSize, suppressSizeWarning: iconSuppressSizeWarning })), children, iconRight && _jsx(Icon, { className: classNames(styles.iconRight, iconRightClassName), glyph: iconRight }), dropdown && _jsx(Icon, { glyph: isInline ? chevron12pxDown : chevronDown, className: styles.dropdownIcon })] }));
46
46
  const isDisabled = disabled || loader || undefined;
@@ -0,0 +1,11 @@
1
+ export declare enum ControlsHeight {
2
+ S = "S",
3
+ M = "M",
4
+ L = "L"
5
+ }
6
+ export interface RingUIConfiguration {
7
+ controlsHeight?: ControlsHeight;
8
+ popupsCssPositioning?: boolean;
9
+ }
10
+ export declare function configure(config: RingUIConfiguration): void;
11
+ export declare function getConfiguration(): Required<RingUIConfiguration>;
@@ -0,0 +1,21 @@
1
+ export var ControlsHeight;
2
+ (function (ControlsHeight) {
3
+ ControlsHeight["S"] = "S";
4
+ ControlsHeight["M"] = "M";
5
+ ControlsHeight["L"] = "L";
6
+ })(ControlsHeight || (ControlsHeight = {}));
7
+ const globalConfiguration = {
8
+ controlsHeight: ControlsHeight.M,
9
+ popupsCssPositioning: true,
10
+ };
11
+ export function configure(config) {
12
+ if (config.controlsHeight !== undefined) {
13
+ globalConfiguration.controlsHeight = config.controlsHeight;
14
+ }
15
+ if (config.popupsCssPositioning !== undefined) {
16
+ globalConfiguration.popupsCssPositioning = config.popupsCssPositioning;
17
+ }
18
+ }
19
+ export function getConfiguration() {
20
+ return { ...globalConfiguration };
21
+ }
@@ -1,8 +1,5 @@
1
- export declare enum ControlsHeight {
2
- S = "S",
3
- M = "M",
4
- L = "L"
5
- }
6
- export declare const ControlsHeightContext: import("react").Context<ControlsHeight>;
7
- export declare function configureGlobalControlsHeight(value: ControlsHeight): void;
1
+ import { ControlsHeight } from './configuration';
2
+ export { ControlsHeight } from './configuration';
3
+ export declare const configureGlobalControlsHeight: (value: ControlsHeight) => void;
8
4
  export declare function getGlobalControlsHeight(): ControlsHeight;
5
+ export declare const ControlsHeightContext: import("react").Context<ControlsHeight | (() => ControlsHeight)>;
@@ -1,16 +1,12 @@
1
1
  import { createContext } from 'react';
2
- export var ControlsHeight;
3
- (function (ControlsHeight) {
4
- ControlsHeight["S"] = "S";
5
- ControlsHeight["M"] = "M";
6
- ControlsHeight["L"] = "L";
7
- })(ControlsHeight || (ControlsHeight = {}));
8
- export const ControlsHeightContext = createContext(ControlsHeight.M);
9
- let globalControlsHeight = ControlsHeight.M;
2
+ import deprecate from 'util-deprecate';
3
+ import { configure, ControlsHeight, getConfiguration } from './configuration';
4
+ export { ControlsHeight } from './configuration';
10
5
  // This can be used if React Context is not applicable, for example for alertService or Auth dialog
11
- export function configureGlobalControlsHeight(value) {
12
- globalControlsHeight = value;
13
- }
6
+ export const configureGlobalControlsHeight = deprecate((value) => {
7
+ configure({ controlsHeight: value });
8
+ }, 'Ring UI: configureGlobalControlsHeight() is deprecated, use configure() instead');
14
9
  export function getGlobalControlsHeight() {
15
- return globalControlsHeight;
10
+ return getConfiguration().controlsHeight ?? ControlsHeight.M;
16
11
  }
12
+ export const ControlsHeightContext = createContext(getGlobalControlsHeight);
@@ -116,10 +116,12 @@
116
116
  --ring-link-hover-color: rgb(var(--ring-link-hover-components)); /* #2E55A3 */
117
117
  --ring-error-components: 204, 54, 69;
118
118
  --ring-error-color: rgb(var(--ring-error-components)); /* #CC3645 */
119
- --ring-warning-components: 184, 85, 22;
120
- --ring-warning-color: rgb(var(--ring-warning-components)); /* #B85516 */ /* Prefer using warning icon + regular text color */
119
+ --ring-warning-components: 182, 84, 22;
120
+ --ring-warning-color: rgb(var(--ring-warning-components)); /* #B65416 */ /* Prefer using warning icon + regular text color */
121
121
  --ring-success-components: 31, 117, 54;
122
122
  --ring-success-color: rgb(var(--ring-success-components)); /* #1F7536 */ /* Prefer using success icon + regular text color */
123
+ --ring-purple-text-components: 131, 77, 240;
124
+ --ring-purple-text-color: rgb(var(--ring-purple-text-components)); /* #834DF0 */
123
125
  --ring-text-components: 39, 40, 46;
124
126
  --ring-text-color: rgb(var(--ring-text-components)); /* #27282E */
125
127
  --ring-active-text-color: var(--ring-text-color);
@@ -41,8 +41,8 @@
41
41
  --ring-main-error-color: rgb(var(--ring-main-error-components)); /* #BD5757 */
42
42
  --ring-main-error-hover-components: 156, 78, 78;
43
43
  --ring-main-error-hover-color: rgb(var(--ring-main-error-hover-components)); /* #9C4E4E */
44
- --ring-main-warning-components: 224, 136, 85;
45
- --ring-main-warning-color: rgb(var(--ring-main-warning-components)); /* #E08855 */
44
+ --ring-main-warning-components: 224, 137, 87;
45
+ --ring-main-warning-color: rgb(var(--ring-main-warning-components)); /* #E08957 */
46
46
  --ring-main-warning-hover-components: 199, 125, 85;
47
47
  --ring-main-warning-hover-color: rgb(var(--ring-main-warning-hover-components)); /* #C77D55 */
48
48
  --ring-main-purple-components: 149, 90, 224;
@@ -103,10 +103,12 @@
103
103
  --ring-link-hover-color: rgb(var(--ring-link-hover-components)); /* #6B9BFA */
104
104
  --ring-error-components: 227, 119, 116;
105
105
  --ring-error-color: rgb(var(--ring-error-components)); /* #E37774 */
106
- --ring-warning-components: 224, 136, 85;
107
- --ring-warning-color: rgb(var(--ring-warning-components)); /* #E08855 */ /* Prefer using warning icon + regular text color */
106
+ --ring-warning-components: 224, 137, 87;
107
+ --ring-warning-color: rgb(var(--ring-warning-components)); /* #E08957 */ /* Prefer using warning icon + regular text color */
108
108
  --ring-success-components: 95, 173, 101;
109
109
  --ring-success-color: rgb(var(--ring-success-components)); /* #5FAD65 */ /* Prefer using success icon + regular text color */
110
+ --ring-purple-text-components: 181, 137, 236;
111
+ --ring-purple-text-color: rgb(var(--ring-purple-text-components)); /* #B589EC */
110
112
  --ring-text-components: 255, 255, 255;
111
113
  --ring-text-color: rgb(var(--ring-text-components)); /* #FFFFFF */
112
114
  --ring-active-text-components: 255, 255, 255;
@@ -175,8 +177,8 @@
175
177
  --ring-warning-container-light-color: rgb(var(--ring-warning-container-light-components)); /* #352A27 */
176
178
  --ring-highlight-container-light-components: 49, 42, 35;
177
179
  --ring-highlight-container-light-color: rgb(var(--ring-highlight-container-light-components)); /* #312A23 */
178
- --ring-grey-container-light-components: 57, 59, 64;
179
- --ring-grey-container-light-color: rgb(var(--ring-grey-container-light-components)); /* #393B40 */
180
+ --ring-grey-container-light-components: 43, 45, 48;
181
+ --ring-grey-container-light-color: rgb(var(--ring-grey-container-light-components)); /* #2B2D30 */
180
182
  --ring-purple-container-light-components: 43, 37, 49;
181
183
  --ring-purple-container-light-color: rgb(var(--ring-purple-container-light-components)); /* #2B2531 */
182
184
  --ring-highlight-fill-components: 214, 174, 88;
@@ -1,6 +1,6 @@
1
1
  import { PureComponent, Ref, ComponentType, InputHTMLAttributes, TextareaHTMLAttributes, ReactNode } from 'react';
2
2
  import * as React from 'react';
3
- import { ControlsHeight } from '../global/controls-height';
3
+ import { ControlsHeight, ControlsHeightContext } from '../global/controls-height';
4
4
  import { LabelType } from '../control-label/control-label';
5
5
  declare function noop(): void;
6
6
  /**
@@ -58,7 +58,8 @@ export declare class Input extends PureComponent<InputProps> {
58
58
  componentDidMount(): void;
59
59
  componentDidUpdate(): void;
60
60
  componentWillUnmount(): void;
61
- static contextType: React.Context<ControlsHeight>;
61
+ static contextType: React.Context<ControlsHeight | (() => ControlsHeight)>;
62
+ context: React.ContextType<typeof ControlsHeightContext>;
62
63
  frame?: number;
63
64
  input?: HTMLInputElement | HTMLTextAreaElement | null;
64
65
  id: string;
@@ -97,7 +97,7 @@ export class Input extends PureComponent {
97
97
  // Modifiers
98
98
  size, multiline, borderless,
99
99
  // Props
100
- label, labelType, error, help, className, inputClassName, children, value, onClear, disabled, inputRef, onChange, enableShortcuts, id, placeholder, icon, translations, height = this.context, beforeInput, afterInput, autogrow, ...restProps } = this.props;
100
+ label, labelType, error, help, className, inputClassName, children, value, onClear, disabled, inputRef, onChange, enableShortcuts, id, placeholder, icon, translations, height = typeof this.context === 'function' ? this.context() : this.context, beforeInput, afterInput, autogrow, ...restProps } = this.props;
101
101
  const { empty } = this.state;
102
102
  const clearable = !!onClear;
103
103
  const classes = classNames(className, styles.outerContainer, [styles[`size${size}`]], [styles[`height${height}`]], {
@@ -19,6 +19,80 @@
19
19
  box-shadow: var(--ring-popup-shadow);
20
20
  }
21
21
 
22
+ :root {
23
+ --ring-popup-offset: 8px;
24
+ }
25
+
26
+ .cssAnchoredPopup {
27
+ --ring-popup-offset: 0;
28
+
29
+ top: unset;
30
+ left: unset;
31
+
32
+ margin: 0
33
+ }
34
+
35
+ @position-try --bottom-right {
36
+ position-area: block-end span-inline-end;
37
+ margin-block-start: var(--ring-popup-offset);
38
+ }
39
+
40
+ @position-try --bottom-left {
41
+ position-area: block-end span-inline-start;
42
+ margin-block-start: var(--ring-popup-offset);
43
+ }
44
+
45
+ @position-try --bottom-center {
46
+ position-area: block-end center;
47
+ margin-block-start: var(--ring-popup-offset);
48
+ }
49
+
50
+ @position-try --top-center {
51
+ position-area: block-start center;
52
+ margin-block-end: var(--ring-popup-offset);
53
+ }
54
+
55
+ @position-try --top-right {
56
+ position-area: block-start span-inline-end;
57
+ margin-block-end: var(--ring-popup-offset);
58
+ }
59
+
60
+ @position-try --top-left {
61
+ position-area: block-start span-inline-start;
62
+ margin-block-end: var(--ring-popup-offset);
63
+ }
64
+
65
+ @position-try --right-center {
66
+ position-area: center inline-end;
67
+ margin-inline-start: var(--ring-popup-offset);
68
+ }
69
+
70
+ @position-try --right-top {
71
+ position-area: span-block-start inline-end;
72
+ margin-inline-start: var(--ring-popup-offset);
73
+ }
74
+
75
+ @position-try --right-bottom {
76
+ position-area: span-block-end inline-end;
77
+ margin-inline-start: var(--ring-popup-offset);
78
+ }
79
+
80
+ @position-try --left-center {
81
+ position-area: center inline-start;
82
+ margin-inline-end: var(--ring-popup-offset);
83
+ }
84
+
85
+ @position-try --left-top {
86
+ position-area: span-block-start inline-start;
87
+ margin-inline-end: var(--ring-popup-offset);
88
+ }
89
+
90
+ @position-try --left-bottom {
91
+ position-area: span-block-end inline-start;
92
+ margin-inline-end: var(--ring-popup-offset);
93
+ }
94
+
95
+
22
96
  .largeBorderRadius {
23
97
  border-radius: var(--ring-border-radius-large);
24
98
  }
@@ -32,6 +32,7 @@ export interface BasePopupProps {
32
32
  withTail?: boolean;
33
33
  tailOffset?: number;
34
34
  largeBorderRadius?: boolean;
35
+ cssPositioning?: boolean;
35
36
  anchorElement?: HTMLElement | null | undefined;
36
37
  target?: string | Element | null | undefined;
37
38
  className?: string | null | undefined;
@@ -117,6 +118,7 @@ export default class Popup<P extends BasePopupProps = PopupProps> extends PureCo
117
118
  direction: Directions | null;
118
119
  };
119
120
  private _updateDirection;
121
+ private shouldUseCssPositioning;
120
122
  private _updatePosition;
121
123
  private _redraw;
122
124
  private _getAnchor;
@@ -11,10 +11,12 @@ import { Listeners, getStyles } from '../global/dom';
11
11
  import Shortcuts from '../shortcuts/shortcuts';
12
12
  import dataTests from '../global/data-tests';
13
13
  import TabTrap from '../tab-trap/tab-trap';
14
+ import { getConfiguration } from '../global/configuration';
14
15
  import position from './position';
15
16
  import styles from './popup.css';
16
17
  import { DEFAULT_DIRECTIONS, Dimension, Directions, Display, MaxHeight, MinWidth } from './popup.consts';
17
18
  import { PopupTargetContext, PopupTarget } from './popup.target';
19
+ import { setCSSAnchorPositioning, supportsCSSAnchorPositioning } from './position-css';
18
20
  export { PopupTargetContext, PopupTarget };
19
21
  const isPossibleClientSideNavigation = (event) => {
20
22
  const target = event.target;
@@ -158,23 +160,47 @@ export default class Popup extends PureComponent {
158
160
  }
159
161
  }
160
162
  };
163
+ shouldUseCssPositioning() {
164
+ if (!supportsCSSAnchorPositioning()) {
165
+ return false;
166
+ }
167
+ return this.props.cssPositioning !== undefined
168
+ ? this.props.cssPositioning
169
+ : getConfiguration().popupsCssPositioning;
170
+ }
161
171
  _updatePosition = () => {
162
172
  const popup = this.popup;
173
+ const anchor = this._getAnchor();
163
174
  if (popup) {
164
- popup.style.position = 'absolute';
165
- if (this.isVisible()) {
166
- const { styles: style, direction } = this.position();
167
- Object.entries(style).forEach(([key, value]) => {
168
- const propKey = key;
169
- if (typeof value === 'number') {
170
- popup.style[propKey] = `${value}px`;
171
- }
172
- else {
173
- popup.style[propKey] = value.toString();
174
- }
175
+ if (this.shouldUseCssPositioning() && anchor) {
176
+ // Use CSS Anchor positioning
177
+ setCSSAnchorPositioning({
178
+ popup,
179
+ anchor,
180
+ uid: this.uid,
181
+ minWidth: this.props.minWidth,
182
+ top: this.props.top,
183
+ left: this.props.left,
184
+ directions: this.props.directions,
185
+ offset: this.props.offset,
175
186
  });
176
- if (direction != null) {
177
- this._updateDirection(direction);
187
+ }
188
+ else {
189
+ popup.style.position = 'absolute';
190
+ if (this.isVisible()) {
191
+ const { styles: style, direction } = this.position();
192
+ Object.entries(style).forEach(([key, value]) => {
193
+ const propKey = key;
194
+ if (typeof value === 'number') {
195
+ popup.style[propKey] = `${value}px`;
196
+ }
197
+ else {
198
+ popup.style[propKey] = value.toString();
199
+ }
200
+ });
201
+ if (direction != null) {
202
+ this._updateDirection(direction);
203
+ }
178
204
  }
179
205
  }
180
206
  this.setState(this.calculateDisplay);
@@ -199,16 +225,20 @@ export default class Popup extends PureComponent {
199
225
  clearTimeout(this._prevTimeout);
200
226
  this._prevTimeout = window.setTimeout(() => {
201
227
  this._listenersEnabled = true;
202
- this.listeners.add(window, 'resize', this._redraw);
203
- if (this.props.autoPositioningOnScroll) {
204
- this.listeners.add(window, 'scroll', this._redraw);
228
+ // CSS positioning doesn't need resize/scroll listeners as it's handled by CSS
229
+ // But we need them if CSS positioning isn't supported
230
+ if (!this.shouldUseCssPositioning()) {
231
+ this.listeners.add(window, 'resize', this._redraw);
232
+ if (this.props.autoPositioningOnScroll) {
233
+ this.listeners.add(window, 'scroll', this._redraw);
234
+ }
235
+ let el = this._getAnchor();
236
+ while (el) {
237
+ this.listeners.add(el, 'scroll', this._redraw);
238
+ el = el.parentElement;
239
+ }
205
240
  }
206
241
  this.listeners.add(document, 'pointerdown', this._onDocumentClick, true);
207
- let el = this._getAnchor();
208
- while (el) {
209
- this.listeners.add(el, 'scroll', this._redraw);
210
- el = el.parentElement;
211
- }
212
242
  }, 0);
213
243
  return;
214
244
  }
@@ -259,6 +289,7 @@ export default class Popup extends PureComponent {
259
289
  const { className, style, hidden, attached, keepMounted, client, onMouseDown, onMouseUp, onMouseOver, onMouseOut, onContextMenu, 'data-test': dataTest, largeBorderRadius, } = this.props;
260
290
  const showing = this.state.display === Display.SHOWING;
261
291
  const classes = classNames(className, styles.popup, {
292
+ [styles.cssAnchoredPopup]: this.shouldUseCssPositioning(),
262
293
  [styles.attached]: attached,
263
294
  [styles.hidden]: hidden,
264
295
  [styles.showing]: showing,
@@ -0,0 +1,14 @@
1
+ import { Directions } from './popup.consts';
2
+ export declare const supportsCSSAnchorPositioning: () => boolean;
3
+ interface SetCSSAnchorPositioningParams {
4
+ popup: HTMLElement;
5
+ anchor: HTMLElement;
6
+ uid: string;
7
+ minWidth?: number | 'target' | null;
8
+ top?: number;
9
+ left?: number;
10
+ directions: readonly Directions[];
11
+ offset?: number;
12
+ }
13
+ export declare const setCSSAnchorPositioning: ({ popup, anchor, uid, minWidth, top, left, directions, offset, }: SetCSSAnchorPositioningParams) => void;
14
+ export {};
@@ -0,0 +1,75 @@
1
+ import { getRect } from '../global/dom';
2
+ import { calculateMinWidth } from './position';
3
+ import { Directions } from './popup.consts';
4
+ export const supportsCSSAnchorPositioning = () => {
5
+ return CSS?.supports?.('anchor-name', 'none');
6
+ };
7
+ const getPositionArea = (direction) => {
8
+ switch (direction) {
9
+ case Directions.BOTTOM_RIGHT:
10
+ return ['block-end span-inline-end', '--bottom-right'];
11
+ case Directions.BOTTOM_LEFT:
12
+ return ['block-end span-inline-start', '--bottom-left'];
13
+ case Directions.BOTTOM_CENTER:
14
+ return ['block-end center', '--bottom-center'];
15
+ case Directions.TOP_CENTER:
16
+ return ['block-start center', '--top-center'];
17
+ case Directions.TOP_RIGHT:
18
+ return ['block-start span-inline-end', '--top-right'];
19
+ case Directions.TOP_LEFT:
20
+ return ['block-start span-inline-start', '--top-left'];
21
+ case Directions.RIGHT_CENTER:
22
+ return ['center inline-end', '--right-center'];
23
+ case Directions.RIGHT_TOP:
24
+ return ['span-block-start inline-end', '--right-top'];
25
+ case Directions.RIGHT_BOTTOM:
26
+ return ['span-block-end inline-end', '--right-bottom'];
27
+ case Directions.LEFT_CENTER:
28
+ return ['center inline-start', '--left-center'];
29
+ case Directions.LEFT_TOP:
30
+ return ['span-block-start inline-start', '--left-top'];
31
+ case Directions.LEFT_BOTTOM:
32
+ return ['span-block-end inline-start', '--left-bottom'];
33
+ default:
34
+ return ['block-end span-inline-end', '--bottom-right'];
35
+ }
36
+ };
37
+ const getPositionFallbacks = (directions) => {
38
+ return directions
39
+ .slice(1)
40
+ .map(direction => getPositionArea(direction)[1])
41
+ .join(', ');
42
+ };
43
+ export const setCSSAnchorPositioning = ({ popup, anchor, uid, minWidth, top, left, directions, offset, }) => {
44
+ const anchorName = anchor.style.getPropertyValue('anchor-name') || `--anchor-${uid}`;
45
+ if (!anchor.style.getPropertyValue('anchor-name')) {
46
+ anchor.style.setProperty('anchor-name', anchorName);
47
+ }
48
+ popup.style.setProperty('position-anchor', anchorName);
49
+ const calculatedMinWidth = calculateMinWidth(getRect(anchor).width, minWidth);
50
+ if (calculatedMinWidth !== null) {
51
+ popup.style.minWidth = `${calculatedMinWidth}px`;
52
+ }
53
+ if (top) {
54
+ popup.style.transform = `translateY(${top}px)`;
55
+ }
56
+ if (left) {
57
+ popup.style.left = `${left}px`;
58
+ }
59
+ const [initialPositionStyle, initialPositionName] = getPositionArea(directions[0]);
60
+ popup.style.setProperty('position-area', initialPositionStyle);
61
+ if (offset) {
62
+ popup.style.setProperty('--ring-popup-offset', `${offset}px`);
63
+ if (initialPositionName.startsWith('--bottom') || initialPositionName.startsWith('--top')) {
64
+ popup.style.margin = `${offset}px 0`;
65
+ }
66
+ else {
67
+ popup.style.margin = `0 ${offset}px`;
68
+ }
69
+ }
70
+ // Add fallbacks for better positioning if there are multiple directions
71
+ const fallbacks = getPositionFallbacks(directions);
72
+ if (fallbacks) {
73
+ popup.style.setProperty('position-try-fallbacks', fallbacks);
74
+ }
75
+ };
@@ -24,6 +24,7 @@ export interface PositionAttrs {
24
24
  }
25
25
  export declare const positionPropKeys: readonly ["directions", "autoPositioning", "autoCorrectTopOverflow", "sidePadding", "top", "left", "offset", "maxHeight", "minWidth"];
26
26
  export declare function maxHeightForDirection(direction: Directions, anchorNode: Element, containerNode?: Element | null): number | null;
27
+ export declare function calculateMinWidth(anchorWidth: number, minWidth: PositionAttrs['minWidth']): number | null;
27
28
  export default function position(attrs: PositionAttrs): {
28
29
  styles: PositionStyles;
29
30
  direction: Directions | null;
@@ -126,6 +126,15 @@ export function maxHeightForDirection(direction, anchorNode, containerNode) {
126
126
  return null;
127
127
  }
128
128
  }
129
+ export function calculateMinWidth(anchorWidth, minWidth) {
130
+ if (minWidth === MinWidth.TARGET || minWidth === 'target') {
131
+ return anchorWidth;
132
+ }
133
+ else if (minWidth) {
134
+ return anchorWidth < minWidth ? minWidth : anchorWidth;
135
+ }
136
+ return null;
137
+ }
129
138
  export default function position(attrs) {
130
139
  const { popup, anchor, container, directions, autoPositioning, sidePadding, top, left, offset, maxHeight, minWidth, autoCorrectTopOverflow = true, } = attrs;
131
140
  let styles = {
@@ -185,11 +194,9 @@ export default function position(attrs) {
185
194
  scroll,
186
195
  });
187
196
  }
188
- if (minWidth === MinWidth.TARGET || minWidth === 'target') {
189
- styles.minWidth = anchorRect.width;
190
- }
191
- else if (minWidth) {
192
- styles.minWidth = anchorRect.width < minWidth ? minWidth : anchorRect.width;
197
+ const newMinWidth = calculateMinWidth(anchorRect.width, minWidth);
198
+ if (newMinWidth !== null) {
199
+ styles.minWidth = newMinWidth;
193
200
  }
194
201
  return { styles, direction: chosenDirection };
195
202
  }
@@ -5,7 +5,7 @@ import { Size } from '../input/input';
5
5
  import { LabelType } from '../control-label/control-label';
6
6
  import { ListDataItem } from '../list/consts';
7
7
  import { Directions } from '../popup/popup.consts';
8
- import { ControlsHeight } from '../global/controls-height';
8
+ import { ControlsHeight, ControlsHeightContext } from '../global/controls-height';
9
9
  import SelectPopup, { Filter, FilterFn, Multiple, Tags } from './select__popup';
10
10
  /**
11
11
  * @name Select
@@ -206,7 +206,8 @@ export default class Select<T = unknown> extends Component<SelectProps<T>, Selec
206
206
  static getDerivedStateFromProps<T = unknown>(nextProps: SelectProps<T>, prevState: SelectState<T>): Partial<SelectState<T>>;
207
207
  state: SelectState<T>;
208
208
  componentDidUpdate(prevProps: SelectProps<T>, prevState: SelectState<T>): void;
209
- static contextType: React.Context<ControlsHeight>;
209
+ static contextType: React.Context<ControlsHeight | (() => ControlsHeight)>;
210
+ context: React.ContextType<typeof ControlsHeightContext>;
210
211
  static Type: typeof Type;
211
212
  static Size: typeof Size;
212
213
  id: string;
@@ -258,6 +259,7 @@ export default class Select<T = unknown> extends Component<SelectProps<T>, Selec
258
259
  private _getLabel;
259
260
  private _getPlaceholder;
260
261
  _getSelectedString(): string | null;
262
+ private getHeight;
261
263
  private _getIcons;
262
264
  private _getAvatar;
263
265
  filter?: HTMLInputElement | null;
@@ -733,11 +733,14 @@ export default class Select extends Component {
733
733
  return this.state.selected != null ? getItemLabel(this.state.selected) : null;
734
734
  }
735
735
  }
736
+ getHeight() {
737
+ return this.props.height || (typeof this.context === 'function' ? this.context() : this.context);
738
+ }
736
739
  _getIcons() {
737
740
  const { selected } = this.state;
738
741
  const { disabled, clear, hideArrow } = this.props;
739
742
  const icons = [];
740
- const height = this.props.height || this.context;
743
+ const height = this.getHeight();
741
744
  if (!Array.isArray(selected) && selected?.icon) {
742
745
  icons.push(_jsx("button", { title: "Toggle options popup", type: "button", className: styles.selectedIcon, disabled: this.props.disabled, onClick: this._clickHandler, style: { backgroundImage: `url(${selected.icon})` } }, "selected"));
743
746
  }
@@ -775,7 +778,7 @@ export default class Select extends Component {
775
778
  const dataTest = this.props['data-test'];
776
779
  const { selectedLabel } = this.props;
777
780
  const { shortcutsEnabled } = this.state;
778
- const classes = classNames(styles.select, 'ring-js-shortcuts', this.props.className, styles[`height${this.props.height || this.context}`], {
781
+ const classes = classNames(styles.select, 'ring-js-shortcuts', this.props.className, styles[`height${this.getHeight()}`], {
779
782
  [styles[`size${this.props.size}`]]: this.props.type !== Type.INLINE,
780
783
  [styles.disabled]: this.props.disabled,
781
784
  });
@@ -3,6 +3,15 @@
3
3
  /* ensure styles order */
4
4
  @import "../link/link.css";
5
5
 
6
+ :root,
7
+ :host {
8
+ --ring-error-tag-text-color: var(--ring-main-error-hover-color);
9
+ }
10
+
11
+ :global(.ring-ui-theme-dark) {
12
+ --ring-error-tag-text-color: var(--ring-error-color);
13
+ }
14
+
6
15
  .tag {
7
16
  --ring-tag-max-height: 20px;
8
17
 
@@ -23,7 +32,7 @@
23
32
 
24
33
  vertical-align: top;
25
34
 
26
- color: var(--ring-text-color);
35
+ color: var(--ring-tag-text-color);
27
36
 
28
37
  border: none;
29
38
  border-radius: var(--ring-border-radius);
@@ -52,8 +61,80 @@
52
61
 
53
62
  border-radius: var(--ring-border-radius);
54
63
 
55
- background-color: var(--ring-tag-background-color);
64
+ background-color: var(--ring-tag-container-background-color);
65
+ }
66
+
67
+ .default {
68
+ --ring-tag-container-background-color: var(--ring-tag-background-color);
69
+ --ring-tag-container-hover-background-color: var(--ring-tag-hover-background-color);
70
+ --ring-tag-text-color: var(--ring-text-color);
71
+ --ring-tag-icon-color: var(--ring-secondary-color);
72
+ --ring-tag-container-outline-background-color: var(--ring-grey-container-light-color);
73
+ --ring-tag-container-outline-hover-background-color: var(--ring-tag-background-color);
74
+ --ring-tag-outline-color: var(--ring-line-color);
75
+ --ring-tag-outline-hover-color: var(--ring-borders-color);
76
+ }
77
+
78
+ .main {
79
+ --ring-tag-container-background-color: var(--ring-hover-background-color);
80
+ --ring-tag-container-hover-background-color: var(--ring-selected-background-color);
81
+ --ring-tag-text-color: var(--ring-link-color);
82
+ --ring-tag-icon-color: var(--ring-link-color);
83
+ --ring-tag-container-outline-background-color: var(--ring-main-container-light-color);
84
+ --ring-tag-container-outline-hover-background-color: var(--ring-hover-background-color);
85
+ --ring-tag-outline-color: var(--ring-border-hover-color);
86
+ --ring-tag-outline-hover-color: var(--ring-border-accent-color);
87
+ }
56
88
 
89
+ .success {
90
+ --ring-tag-container-background-color: var(--ring-added-subtle-background-color);
91
+ --ring-tag-container-hover-background-color: var(--ring-added-background-color);
92
+ --ring-tag-text-color: var(--ring-success-color);
93
+ --ring-tag-icon-color: var(--ring-icon-success-color);
94
+ --ring-tag-container-outline-background-color: var(--ring-success-container-light-color);
95
+ --ring-tag-container-outline-hover-background-color: var(--ring-added-subtle-background-color);
96
+ --ring-tag-outline-color: var(--ring-success-border-color);
97
+ --ring-tag-outline-hover-color: var(--ring-success-border-hover-color);
98
+ }
99
+
100
+ .warning {
101
+ --ring-tag-container-background-color: var(--ring-warning-subtle-background-color);
102
+ --ring-tag-container-hover-background-color: var(--ring-warning-background-color);
103
+ --ring-tag-text-color: var(--ring-warning-color);
104
+ --ring-tag-icon-color: var(--ring-icon-warning-color);
105
+ --ring-tag-container-outline-background-color: var(--ring-warning-container-light-color);
106
+ --ring-tag-container-outline-hover-background-color: var(--ring-warning-subtle-background-color);
107
+ --ring-tag-outline-color: var(--ring-warning-border-color);
108
+ --ring-tag-outline-hover-color: var(--ring-warning-border-hover-color);
109
+ }
110
+
111
+ .error {
112
+ --ring-tag-container-background-color: var(--ring-removed-subtle-background-color);
113
+ --ring-tag-container-hover-background-color: var(--ring-removed-background-color);
114
+ --ring-tag-text-color: var(--ring-error-tag-text-color);
115
+ --ring-tag-icon-color: var(--ring-icon-error-color);
116
+ --ring-tag-container-outline-background-color: var(--ring-error-container-light-color);
117
+ --ring-tag-container-outline-hover-background-color: var(--ring-removed-subtle-background-color);
118
+ --ring-tag-outline-color: var(--ring-error-border-color);
119
+ --ring-tag-outline-hover-color: var(--ring-error-border-hover-color);
120
+ }
121
+
122
+ .purple {
123
+ --ring-tag-container-background-color: var(--ring-purple-subtle-background-color);
124
+ --ring-tag-container-hover-background-color: var(--ring-purple-background-color);
125
+ --ring-tag-text-color: var(--ring-purple-text-color);
126
+ --ring-tag-icon-color: var(--ring-main-purple-color);
127
+ --ring-tag-container-outline-background-color: var(--ring-purple-container-light-color);
128
+ --ring-tag-container-outline-hover-background-color: var(--ring-purple-subtle-background-color);
129
+ --ring-tag-outline-color: var(--ring-purple-border-color);
130
+ --ring-tag-outline-hover-color: var(--ring-purple-border-hover-color);
131
+ }
132
+
133
+ .outline {
134
+ --ring-tag-container-background-color: var(--ring-tag-container-outline-background-color);
135
+ --ring-tag-container-hover-background-color: var(--ring-tag-container-outline-hover-background-color);
136
+
137
+ box-shadow: inset 0 0 0 1px var(--ring-tag-outline-color);
57
138
  }
58
139
 
59
140
  .focused,
@@ -67,9 +148,10 @@
67
148
  .focused,
68
149
  .tag:focus-visible,
69
150
  .container:hover {
70
- transition: none;
151
+ --ring-tag-outline-color: var(--ring-tag-outline-hover-color);
152
+ --ring-tag-container-background-color: var(--ring-tag-container-hover-background-color);
71
153
 
72
- background-color: var(--ring-tag-hover-background-color);
154
+ transition: none;
73
155
  }
74
156
 
75
157
  .content {
@@ -84,6 +166,8 @@
84
166
  }
85
167
 
86
168
  .remove {
169
+ --ring-button-text-color: var(--ring-secondary-color);
170
+
87
171
  position: absolute;
88
172
  z-index: 1;
89
173
  top: 2px;
@@ -95,15 +179,11 @@
95
179
  line-height: calc(var(--ring-unit) * 2);
96
180
  }
97
181
 
98
- .removeIcon.removeIcon {
99
- color: var(--ring-secondary-color);
100
- }
101
-
102
182
  .icon {
103
183
  margin-right: calc(var(--ring-unit) / 2);
104
184
  margin-left: calc(var(--ring-unit) * -0.5);
105
185
 
106
- color: var(--ring-secondary-color);
186
+ color: var(--ring-tag-icon-color);
107
187
 
108
188
  && svg {
109
189
  vertical-align: -3.5px;
@@ -6,6 +6,14 @@ export interface TagRenderProps extends HTMLAttributes<HTMLElement> {
6
6
  ref: RefCallback<HTMLElement>;
7
7
  'data-test': string;
8
8
  }
9
+ export declare enum TagType {
10
+ DEFAULT = "default",
11
+ MAIN = "main",
12
+ SUCCESS = "success",
13
+ WARNING = "warning",
14
+ ERROR = "error",
15
+ PURPLE = "purple"
16
+ }
9
17
  export interface TagProps {
10
18
  onRemove?: ((event: React.MouseEvent<HTMLElement>) => void) | null;
11
19
  onClick: (event: React.MouseEvent<HTMLElement>) => void;
@@ -22,6 +30,8 @@ export interface TagProps {
22
30
  rgTagTitle?: string | undefined;
23
31
  textColor?: string | undefined;
24
32
  backgroundColor?: string | undefined;
33
+ outline?: boolean;
34
+ tagType?: TagType;
25
35
  }
26
36
  /**
27
37
  * @name Tag
@@ -33,6 +43,7 @@ export default class Tag extends PureComponent<TagProps> {
33
43
  };
34
44
  componentDidUpdate(prevProps: TagProps): void;
35
45
  componentWillUnmount(): void;
46
+ static Type: typeof TagType;
36
47
  onDocumentClick: (event: MouseEvent) => void;
37
48
  tagNode?: HTMLElement | null;
38
49
  tagRef: (el: HTMLElement | null) => void;
@@ -6,6 +6,15 @@ import Icon from '../icon/icon';
6
6
  import Button from '../button/button';
7
7
  import { ControlsHeight } from '../global/controls-height';
8
8
  import styles from './tag.css';
9
+ export var TagType;
10
+ (function (TagType) {
11
+ TagType["DEFAULT"] = "default";
12
+ TagType["MAIN"] = "main";
13
+ TagType["SUCCESS"] = "success";
14
+ TagType["WARNING"] = "warning";
15
+ TagType["ERROR"] = "error";
16
+ TagType["PURPLE"] = "purple";
17
+ })(TagType || (TagType = {}));
9
18
  /**
10
19
  * @name Tag
11
20
  */
@@ -16,6 +25,7 @@ export default class Tag extends PureComponent {
16
25
  disabled: false,
17
26
  focused: false,
18
27
  render: props => _jsx("button", { type: "button", ...props }),
28
+ tagType: TagType.DEFAULT,
19
29
  };
20
30
  state = {
21
31
  focused: false,
@@ -33,6 +43,7 @@ export default class Tag extends PureComponent {
33
43
  this.setDocumentClickListener(false);
34
44
  this.setState({ focused: false });
35
45
  }
46
+ static Type = TagType;
36
47
  onDocumentClick = (event) => {
37
48
  if (this.tagNode) {
38
49
  this.setState({ focused: this.tagNode === event.target });
@@ -77,7 +88,7 @@ export default class Tag extends PureComponent {
77
88
  }
78
89
  renderRemoveIcon() {
79
90
  if (!this.props.readOnly && this.props.onRemove) {
80
- return (_jsx(Button, { title: "Remove", icon: closeIcon, "data-test": "ring-tag-remove", className: styles.remove, iconClassName: styles.removeIcon, onClick: this.props.onRemove, style: { '--ring-secondary-color': this.props.textColor }, height: ControlsHeight.M }));
91
+ return (_jsx(Button, { title: "Remove", icon: closeIcon, "data-test": "ring-tag-remove", className: styles.remove, onClick: this.props.onRemove, style: { '--ring-secondary-color': this.props.textColor }, height: ControlsHeight.M }));
81
92
  }
82
93
  return null;
83
94
  }
@@ -88,7 +99,9 @@ export default class Tag extends PureComponent {
88
99
  [styles.withRemove]: !this.props.readOnly && this.props.onRemove,
89
100
  }, this.props.className);
90
101
  const { backgroundColor, textColor, render } = this.props;
91
- return (_jsxs("span", { className: classNames(styles.container, this.props.containerClassName), children: [render({
102
+ return (_jsxs("span", { className: classNames(styles.container, this.props.containerClassName, styles[this.props.tagType], {
103
+ [styles.outline]: this.props.outline,
104
+ }), children: [render({
92
105
  'data-test': 'ring-tag',
93
106
  className: classes,
94
107
  ref: this.tagRef,
@@ -4,7 +4,7 @@ import Select, { SelectItem } from '../select/select';
4
4
  import { TagType } from '../tags-list/tags-list';
5
5
  import Caret from '../caret/caret';
6
6
  import { Size } from '../input/input';
7
- import { ControlsHeight } from '../global/controls-height';
7
+ import { ControlsHeight, ControlsHeightContext } from '../global/controls-height';
8
8
  import { Filter } from '../select/select__popup';
9
9
  import { TagAttrs } from '../tag/tag';
10
10
  import { LabelType } from '../control-label/control-label';
@@ -82,7 +82,8 @@ export default class TagsInput extends PureComponent<TagsInputProps, TagsInputSt
82
82
  componentDidMount(): void;
83
83
  static ngModelStateField: string;
84
84
  ngModelStateField: string;
85
- static contextType: React.Context<ControlsHeight>;
85
+ static contextType: React.Context<ControlsHeight | (() => ControlsHeight)>;
86
+ context: React.ContextType<typeof ControlsHeightContext>;
86
87
  id: string;
87
88
  node?: HTMLElement | null;
88
89
  nodeRef: (node: HTMLElement | null) => void;
@@ -221,7 +221,7 @@ export default class TagsInput extends PureComponent {
221
221
  };
222
222
  render() {
223
223
  const { focused, tags, activeIndex } = this.state;
224
- const { disabled, canNotBeEmpty, allowAddNewTags, filter, size, labelType, height = this.context, label, } = this.props;
224
+ const { disabled, canNotBeEmpty, allowAddNewTags, filter, size, labelType, height = typeof this.context === 'function' ? this.context() : this.context, label, } = this.props;
225
225
  const classes = classNames(styles.tagsInput, [inputStyles[`size${size}`]], [inputStyles[`height${height}`]], {
226
226
  [styles.tagsInputDisabled]: disabled,
227
227
  [styles.tagsInputFocused]: focused,
@@ -190,6 +190,10 @@
190
190
  }
191
191
  }
192
192
 
193
+ .input[disabled] + .switch {
194
+ --ring-toggle-item-color: var(--ring-content-background-color);
195
+ }
196
+
193
197
  /* stylelint-disable-next-line selector-max-specificity */
194
198
  .input:checked[disabled] + .switch {
195
199
  --ring-toggle-background-color: var(--ring-border-disabled-active-color);
@@ -197,7 +201,6 @@
197
201
 
198
202
  /* stylelint-disable-next-line selector-max-specificity */
199
203
  .input[disabled]:not(:checked) + .switch {
200
- --ring-toggle-item-color: var(--ring-content-background-color);
201
204
  --ring-toggle-background-color: var(--ring-disabled-background-color);
202
205
  --ring-toggle-border-color: var(--ring-border-disabled-color);
203
206
  --ring-switch-border-color: var(--ring-border-disabled-color);
@@ -5,7 +5,7 @@ import copyIcon from '@jetbrains/icons/copy';
5
5
  import Avatar, { Size as AvatarSize } from '../avatar/avatar';
6
6
  import Link from '../link/link';
7
7
  import clipboard from '../clipboard/clipboard';
8
- import Tag from '../tag/tag';
8
+ import Tag, { TagType } from '../tag/tag';
9
9
  import Icon, { Size as IconSize } from '../icon/icon';
10
10
  import { I18nContext } from '../i18n/i18n-context';
11
11
  import Tooltip from '../tooltip/tooltip';
@@ -25,6 +25,6 @@ export default class UserCard extends PureComponent {
25
25
  const userActiveStatusClasses = classNames(styles.userActiveStatus, user.online ? styles.online : '');
26
26
  return (_jsx("div", { ...restProps, className: classes, children: _jsxs("div", { className: styles.userInformationContainer, children: [_jsxs("div", { className: styles.userAvatar, children: [_jsx(Avatar, { size: AvatarSize.Size56, url: user.avatarUrl, username: user.name, round: true }), !!avatarInfo && avatarInfo] }), _jsxs("div", { className: styles.userInformation, children: [_jsxs("div", { className: styles.userInformationGeneral, children: [_jsxs("div", { className: styles.userNameLine, children: [user.href && (_jsx(Link, { href: user.href, className: styles.userName, "data-test": "user-card-link", children: user.name })), !user.href && _jsx("span", { className: styles.userName, children: user.name }), typeof user.online === 'boolean' && (_jsx("span", { className: userActiveStatusClasses, title: user.online
27
27
  ? (translations?.online ?? translate('online'))
28
- : (translations?.offline ?? translate('offline')) })), !!info && _jsx("span", { className: styles.userNameInfo, children: info }), user.banned && (_jsx(Tooltip, { title: user.banReason, children: _jsx(Tag, { className: styles.banLabel, children: translations?.banned ?? translate('banned') }) }))] }), _jsx("div", { className: styles.userLogin, children: user.login }), user.email && (_jsxs("span", { className: styles.userEmailWrapper, children: [_jsx(Link, { href: `mailto:${user.email}`, title: `mailto:${user.email}`, target: "_blank", className: styles.userEmail, children: user.email }), user.unverifiedEmail && (_jsx("span", { className: styles.unverifiedLabel, children: translations?.unverified ?? translate('unverified') })), _jsx(Icon, { title: translations?.copyToClipboard ?? translate('copyToClipboard'), className: styles.userCopyIcon, onClick: this.copyEmail, glyph: copyIcon, size: IconSize.Size14, suppressSizeWarning: true })] }))] }), children] })] }) }));
28
+ : (translations?.offline ?? translate('offline')) })), !!info && _jsx("span", { className: styles.userNameInfo, children: info }), user.banned && (_jsx(Tooltip, { title: user.banReason, children: _jsx(Tag, { tagType: TagType.ERROR, children: translations?.banned ?? translate('banned') }) }))] }), _jsx("div", { className: styles.userLogin, children: user.login }), user.email && (_jsxs("span", { className: styles.userEmailWrapper, children: [_jsx(Link, { href: `mailto:${user.email}`, title: `mailto:${user.email}`, target: "_blank", className: styles.userEmail, children: user.email }), user.unverifiedEmail && (_jsx("span", { className: styles.unverifiedLabel, children: translations?.unverified ?? translate('unverified') })), _jsx(Icon, { title: translations?.copyToClipboard ?? translate('copyToClipboard'), className: styles.userCopyIcon, onClick: this.copyEmail, glyph: copyIcon, size: IconSize.Size14, suppressSizeWarning: true })] }))] }), children] })] }) }));
29
29
  }
30
30
  }
@@ -106,10 +106,6 @@
106
106
  margin-bottom: 3px;
107
107
  }
108
108
 
109
- .banLabel {
110
- color: var(--ring-error-color);
111
- }
112
-
113
109
  .userActiveStatus {
114
110
  display: inline-block;
115
111
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jetbrains/ring-ui",
3
- "version": "7.0.60",
3
+ "version": "7.0.62",
4
4
  "description": "JetBrains UI library",
5
5
  "author": {
6
6
  "name": "JetBrains"
@@ -69,7 +69,7 @@
69
69
  "prepare": "webpack -c .storybook/custom-header/webpack.config.js",
70
70
  "prepublishOnly": "pinst --disable",
71
71
  "prerelease-built-ci": "node scripts/prepare-built-package.js",
72
- "prerelease-ci": "git pull && git status",
72
+ "prerelease-ci": "git pull",
73
73
  "pretest-ci": "npm run lint-ci",
74
74
  "release-built-ci": "npm publish --access=public $NPM_PUBLISH_PARAMS",
75
75
  "release-ci": "npm version $NPM_VERSION_PARAMS && npm publish --access=public $NPM_PUBLISH_PARAMS",
@@ -96,52 +96,50 @@
96
96
  "readmeFilename": "README.md",
97
97
  "devDependencies": {
98
98
  "@babel/cli": "^7.28.3",
99
- "@babel/eslint-parser": "^7.28.0",
99
+ "@babel/eslint-parser": "^7.28.4",
100
100
  "@csstools/css-parser-algorithms": "^3.0.4",
101
101
  "@csstools/stylelint-no-at-nest-rule": "^4.0.0",
102
102
  "@eslint/compat": "^1.3.2",
103
103
  "@eslint/eslintrc": "^3.2.0",
104
- "@eslint/js": "^9.34.0",
105
- "@figma/code-connect": "^1.3.4",
104
+ "@eslint/js": "^9.35.0",
105
+ "@figma/code-connect": "^1.3.5",
106
106
  "@jetbrains/eslint-config": "^6.0.5",
107
107
  "@jetbrains/logos": "3.0.0-canary.734b213.0",
108
108
  "@jetbrains/rollup-css-plugin": "./packages/rollup-css-plugin",
109
109
  "@jetbrains/stylelint-config": "^4.0.2",
110
- "@primer/octicons": "^19.16.0",
110
+ "@primer/octicons": "^19.18.0",
111
111
  "@rollup/plugin-babel": "^6.0.4",
112
112
  "@rollup/plugin-json": "^6.1.0",
113
113
  "@rollup/plugin-node-resolve": "^16.0.1",
114
114
  "@rollup/plugin-replace": "^6.0.2",
115
- "@storybook/addon-a11y": "9.1.4",
116
- "@storybook/addon-docs": "^9.1.4",
117
- "@storybook/addon-themes": "^9.1.4",
115
+ "@storybook/addon-a11y": "9.1.5",
116
+ "@storybook/addon-docs": "^9.1.5",
117
+ "@storybook/addon-themes": "^9.1.5",
118
118
  "@storybook/csf": "^0.1.13",
119
- "@storybook/react-webpack5": "9.1.4",
119
+ "@storybook/react-webpack5": "9.1.5",
120
120
  "@storybook/test-runner": "^0.23.0",
121
121
  "@testing-library/dom": "^10.4.1",
122
122
  "@testing-library/react": "^16.3.0",
123
123
  "@testing-library/user-event": "^14.6.1",
124
- "@types/chai": "^5.2.2",
125
124
  "@types/chai-as-promised": "^8.0.2",
126
125
  "@types/chai-dom": "1.11.3",
127
126
  "@types/eslint__js": "^9.14.0",
128
127
  "@types/markdown-it": "^14.1.2",
129
- "@types/react": "^19.1.12",
130
- "@types/react-dom": "^19.1.8",
128
+ "@types/react": "^19.1.13",
129
+ "@types/react-dom": "^19.1.9",
131
130
  "@types/webpack-env": "^1.18.8",
132
131
  "@vitejs/plugin-react": "^5.0.2",
133
- "@vitest/eslint-plugin": "^1.3.6",
132
+ "@vitest/eslint-plugin": "^1.3.9",
134
133
  "acorn": "^8.15.0",
135
134
  "babel-plugin-require-context-hook": "^1.0.0",
136
- "caniuse-lite": "^1.0.30001739",
137
- "chai": "^5.3.1",
135
+ "caniuse-lite": "^1.0.30001741",
138
136
  "chai-as-promised": "^8.0.2",
139
137
  "chai-dom": "^1.12.1",
140
138
  "cheerio": "^1.1.2",
141
139
  "core-js": "^3.45.1",
142
140
  "cpy-cli": "^6.0.0",
143
141
  "dotenv-cli": "^10.0.0",
144
- "eslint": "^9.34.0",
142
+ "eslint": "^9.35.0",
145
143
  "eslint-config-prettier": "^10.1.8",
146
144
  "eslint-formatter-jslint-xml": "^8.40.0",
147
145
  "eslint-import-resolver-exports": "^1.0.0-beta.5",
@@ -151,16 +149,16 @@
151
149
  "eslint-plugin-prettier": "^5.5.4",
152
150
  "eslint-plugin-react": "^7.37.5",
153
151
  "eslint-plugin-react-hooks": "^5.2.0",
154
- "eslint-plugin-storybook": "^9.1.4",
152
+ "eslint-plugin-storybook": "^9.1.5",
155
153
  "events": "^3.3.0",
156
154
  "glob": "^11.0.3",
157
- "globals": "^16.3.0",
155
+ "globals": "^16.4.0",
158
156
  "html-webpack-plugin": "^5.6.4",
159
157
  "http-server": "^14.1.1",
160
158
  "husky": "^9.1.7",
161
159
  "identity-obj-proxy": "^3.0.0",
162
- "jest": "~30.1.1",
163
- "jest-environment-jsdom": "^30.1.1",
160
+ "jest": "~30.1.3",
161
+ "jest-environment-jsdom": "^30.1.2",
164
162
  "jest-teamcity": "^1.12.0",
165
163
  "lint-staged": "^16.1.6",
166
164
  "markdown-it": "^14.1.0",
@@ -172,16 +170,16 @@
172
170
  "react-dom": "^19.1.1",
173
171
  "regenerator-runtime": "^0.14.1",
174
172
  "rimraf": "^6.0.1",
175
- "rollup": "^4.50.0",
173
+ "rollup": "^4.50.1",
176
174
  "rollup-plugin-clear": "^2.0.7",
177
175
  "storage-mock": "^2.1.0",
178
- "storybook": "9.1.4",
179
- "stylelint": "^16.23.1",
176
+ "storybook": "9.1.5",
177
+ "stylelint": "^16.24.0",
180
178
  "svg-inline-loader": "^0.8.2",
181
179
  "teamcity-service-messages": "^0.1.14",
182
180
  "terser-webpack-plugin": "^5.3.14",
183
181
  "typescript": "~5.9.2",
184
- "typescript-eslint": "^8.41.0",
182
+ "typescript-eslint": "^8.43.0",
185
183
  "vitest": "^3.2.4",
186
184
  "vitest-teamcity-reporter": "^0.3.1",
187
185
  "wallaby-webpack": "^3.9.16",
@@ -209,10 +207,10 @@
209
207
  }
210
208
  },
211
209
  "dependencies": {
212
- "@babel/core": "^7.28.3",
210
+ "@babel/core": "^7.28.4",
213
211
  "@babel/preset-typescript": "^7.27.1",
214
212
  "@jetbrains/babel-preset-jetbrains": "^2.4.0",
215
- "@jetbrains/icons": "^5.12.0",
213
+ "@jetbrains/icons": "^5.13.0",
216
214
  "@jetbrains/postcss-require-hover": "^0.2.0",
217
215
  "@types/combokeys": "^2.4.9",
218
216
  "@types/element-resize-detector": "^1.1.6",
@@ -220,7 +218,7 @@
220
218
  "@types/util-deprecate": "^1.0.4",
221
219
  "babel-loader": "10.0.0",
222
220
  "babel-plugin-transform-define": "^2.1.4",
223
- "browserslist": "^4.25.1",
221
+ "browserslist": "^4.26.0",
224
222
  "change-case": "^4.1.1",
225
223
  "classnames": "^2.5.1",
226
224
  "combokeys": "^3.0.1",