@jetbrains/ring-ui 7.0.60 → 7.0.61

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);
@@ -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;
@@ -737,7 +737,7 @@ export default class Select extends Component {
737
737
  const { selected } = this.state;
738
738
  const { disabled, clear, hideArrow } = this.props;
739
739
  const icons = [];
740
- const height = this.props.height || this.context;
740
+ const height = this.props.height || (typeof this.context === 'function' ? this.context() : this.context);
741
741
  if (!Array.isArray(selected) && selected?.icon) {
742
742
  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
743
  }
@@ -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,
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.61",
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.17.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
128
  "@types/react": "^19.1.12",
130
- "@types/react-dom": "^19.1.8",
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,7 +149,7 @@
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
155
  "globals": "^16.3.0",
@@ -159,8 +157,8 @@
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",
@@ -175,13 +173,13 @@
175
173
  "rollup": "^4.50.0",
176
174
  "rollup-plugin-clear": "^2.0.7",
177
175
  "storage-mock": "^2.1.0",
178
- "storybook": "9.1.4",
176
+ "storybook": "9.1.5",
179
177
  "stylelint": "^16.23.1",
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.42.0",
185
183
  "vitest": "^3.2.4",
186
184
  "vitest-teamcity-reporter": "^0.3.1",
187
185
  "wallaby-webpack": "^3.9.16",
@@ -209,7 +207,7 @@
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
213
  "@jetbrains/icons": "^5.12.0",
@@ -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.25.4",
224
222
  "change-case": "^4.1.1",
225
223
  "classnames": "^2.5.1",
226
224
  "combokeys": "^3.0.1",