@jetbrains/ring-ui 5.0.91 → 5.0.93

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.
@@ -23,7 +23,7 @@ export interface PositionAttrs {
23
23
  autoCorrectTopOverflow: boolean;
24
24
  }
25
25
  export declare const positionPropKeys: readonly ["directions", "autoPositioning", "autoCorrectTopOverflow", "sidePadding", "top", "left", "offset", "maxHeight", "minWidth"];
26
- export declare function maxHeightForDirection(direction: Directions, anchorNode: Element, containerNode?: Element | null): number;
26
+ export declare function maxHeightForDirection(direction: Directions, anchorNode: Element, containerNode?: Element | null): number | null;
27
27
  export default function position(attrs: PositionAttrs): {
28
28
  styles: PositionStyles;
29
29
  direction: Directions | null;
@@ -46,9 +46,7 @@ function verticalOverflow(styles, scrollingCoordinates, attrs) {
46
46
  const viewportMinX = scrollingCoordinates.top + attrs.sidePadding;
47
47
  const viewportMaxX = scrollingCoordinates.top + containerHeight - attrs.sidePadding;
48
48
  const topOverflow = Math.max(viewportMinX - styles.top, 0);
49
- const popupHeight = attrs.maxHeight && typeof attrs.maxHeight === 'number'
50
- ? Math.min(attrs.popup.scrollHeight, attrs.maxHeight)
51
- : attrs.popup.scrollHeight;
49
+ const popupHeight = attrs.popup.clientHeight;
52
50
  const verticalDiff = styles.top + popupHeight - viewportMaxX;
53
51
  const bottomOverflow = Math.max(verticalDiff, 0);
54
52
  return topOverflow + bottomOverflow;
@@ -78,6 +76,25 @@ const defaultcontainerRect = {
78
76
  top: 0,
79
77
  left: 0
80
78
  };
79
+ function handleTopOffScreen({ sidePadding, styles, anchorRect, maxHeight, popupScrollHeight, direction, scroll }) {
80
+ const BORDER_COMPENSATION = 1;
81
+ const { TOP_LEFT, TOP_RIGHT, TOP_CENTER, RIGHT_TOP, LEFT_TOP } = Directions;
82
+ const openedToTop = direction != null && [TOP_LEFT, TOP_RIGHT, TOP_CENTER, RIGHT_TOP, LEFT_TOP].includes(direction);
83
+ if (!openedToTop) {
84
+ return styles;
85
+ }
86
+ const isAttachedToAnchorTop = direction != null && [TOP_LEFT, TOP_CENTER, TOP_RIGHT].includes(direction);
87
+ const attachingPointY = (isAttachedToAnchorTop ? anchorRect.top : anchorRect.bottom);
88
+ const effectiveHeight = maxHeight && typeof maxHeight === 'number'
89
+ ? Math.min(popupScrollHeight, maxHeight)
90
+ : popupScrollHeight;
91
+ const hypotheticalTop = attachingPointY - effectiveHeight;
92
+ if (hypotheticalTop <= sidePadding) {
93
+ styles.top = sidePadding + scroll.top;
94
+ styles.maxHeight = attachingPointY - sidePadding + BORDER_COMPENSATION;
95
+ }
96
+ return styles;
97
+ }
81
98
  export function maxHeightForDirection(direction, anchorNode, containerNode) {
82
99
  const container = containerNode || document.documentElement;
83
100
  const domRect = anchorNode.getBoundingClientRect();
@@ -87,7 +104,7 @@ export function maxHeightForDirection(direction, anchorNode, containerNode) {
87
104
  // XXX
88
105
  // If container is the document element
89
106
  // then we check client height too because we may have situation when
90
- // "height" from "getBoundingClientRect" less than "clientHeight".
107
+ // "height" from "getBoundingClientRect" less then "clientHeight".
91
108
  container === document.documentElement ? container.clientHeight : 0);
92
109
  const bottomMaxHeight = Math.max(containerHeight - (topMaxHeight + domRect.height), 0);
93
110
  switch (direction) {
@@ -109,8 +126,7 @@ export function maxHeightForDirection(direction, anchorNode, containerNode) {
109
126
  case Directions.LEFT_CENTER:
110
127
  return (domRect.height / 2) + Math.min(bottomMaxHeight / 2, topMaxHeight / 2);
111
128
  default:
112
- const exhaustiveCheck = direction;
113
- throw new Error(exhaustiveCheck);
129
+ return null;
114
130
  }
115
131
  }
116
132
  export default function position(attrs) {
@@ -130,7 +146,7 @@ export default function position(attrs) {
130
146
  const overflowAttrs = { ...attrs, popup };
131
147
  const directionsMatrix = getPositionStyles(popup, anchorRect, anchorLeft, anchorTop, offset);
132
148
  if (!autoPositioning || directions.length === 1) {
133
- styles = { ...directionsMatrix[directions[0]] };
149
+ styles = directionsMatrix[directions[0]];
134
150
  chosenDirection = directions[0];
135
151
  }
136
152
  else {
@@ -145,7 +161,7 @@ export default function position(attrs) {
145
161
  horizontalOverflow(stylesB, scroll, overflowAttrs);
146
162
  return overflowA - overflowB;
147
163
  });
148
- styles = { ...sortedByIncreasingOverflow[0].styles };
164
+ styles = sortedByIncreasingOverflow[0].styles;
149
165
  chosenDirection = sortedByIncreasingOverflow[0].direction;
150
166
  }
151
167
  // because of the anchor negative margin top and left also may become negative
@@ -162,11 +178,16 @@ export default function position(attrs) {
162
178
  else if (maxHeight) {
163
179
  styles.maxHeight = maxHeight;
164
180
  }
165
- if (autoCorrectTopOverflow && chosenDirection && anchor) {
166
- styles.maxHeight = maxHeightForDirection(chosenDirection, anchor, container) - sidePadding;
167
- if (styles.top === 0) {
168
- styles.top = sidePadding;
169
- }
181
+ if (autoCorrectTopOverflow) {
182
+ styles = handleTopOffScreen({
183
+ sidePadding,
184
+ styles,
185
+ anchorRect,
186
+ maxHeight,
187
+ direction: chosenDirection,
188
+ popupScrollHeight: popup?.scrollHeight ?? 0,
189
+ scroll
190
+ });
170
191
  }
171
192
  if (minWidth === MinWidth.TARGET || minWidth === 'target') {
172
193
  styles.minWidth = anchorRect.width;
@@ -69,8 +69,6 @@
69
69
  }
70
70
 
71
71
  .huge {
72
- --ring-input-padding-block: 5px;
73
-
74
72
  max-height: calc(var(--ring-input-padding-inline) * 4);
75
73
 
76
74
  padding: 0 0 0 var(--ring-input-padding-inline);
@@ -79,15 +77,9 @@
79
77
  padding-right: var(--ring-input-padding-inline);
80
78
  }
81
79
 
82
- & .placeholder {
83
- padding-left: 0;
84
- }
85
-
86
80
  @nest [dir=rtl] & {
87
81
  padding: 0 var(--ring-input-padding-inline) 0 0;
88
82
 
89
- border: 1px solid var(--ring-borders-color);
90
-
91
83
  & .actions {
92
84
  padding: 0 var(--ring-input-padding-inline);
93
85
  }
@@ -167,7 +159,7 @@
167
159
  color: var(--ring-disabled-color);
168
160
 
169
161
  @nest [dir=rtl] & {
170
- padding-right: calc(var(--ring-input-padding-inline) * 3 - var(--ring-input-padding-block));
162
+ padding-right: calc(var(--ring-input-padding-inline) * 3 + var(--ring-input-padding-block) * 2);
171
163
 
172
164
  text-align: right;
173
165
  }
@@ -229,6 +221,14 @@
229
221
 
230
222
  border-color: var(--ring-border-hover-color);
231
223
  }
224
+
225
+ @nest [dir=rtl] & {
226
+ border-right: 1px solid var(--ring-borders-color);
227
+ border-left: 0;
228
+ border-radius: var(--ring-border-radius);
229
+ border-top-right-radius: 0;
230
+ border-bottom-right-radius: 0;
231
+ }
232
232
  }
233
233
 
234
234
  .clear {
@@ -256,6 +256,10 @@
256
256
  padding-left: 0;
257
257
 
258
258
  @nest [dir=rtl] & {
259
- padding-right: 0;
259
+ padding-right: calc(var(--ring-input-padding-block) * 3);
260
260
  }
261
261
  }
262
+
263
+ .loaderActive {
264
+ padding-right: calc(var(--ring-input-padding-inline) - var(--ring-input-padding-block));
265
+ }
@@ -777,12 +777,11 @@ export default class QueryAssist extends Component {
777
777
  const inputClasses = classNames(this.props.inputClassName, {
778
778
  [`${styles.input} ring-js-shortcuts`]: true,
779
779
  [styles.inputGap]: actions.length || this.isRenderingGlassOrLoader() && !glass,
780
- [styles.inputGap2]: actions.length === 2,
781
- [styles.inputLeftGap]: this.isRenderingGlassOrLoader() && glass
780
+ [styles.inputGap2]: actions.length === 2 // TODO: replace with flex-box layout
782
781
  });
783
782
  const placeholderStyles = classNames({
784
783
  [styles.placeholder]: true,
785
- [styles.withoutGlass]: !renderGlass
784
+ [styles.withoutGlass]: !this.isRenderingGlassOrLoader() || (!renderLoader && huge)
786
785
  });
787
786
  return (<ControlsHeightContext.Provider value={ControlsHeight.M}>
788
787
  <div data-test={dataTests('ring-query-assist', dataTest)} className={containerClasses} role="presentation" ref={this.nodeRef}>
@@ -791,7 +790,8 @@ export default class QueryAssist extends Component {
791
790
  {renderGlass && !huge && (<Icon glyph={searchIcon} className={styles.icon} title={this.props.translations.searchTitle} ref={this.glassRef} data-test="query-assist-search-icon"/>)}
792
791
 
793
792
  {renderLoader && (<div className={classNames(styles.icon, styles.loader, {
794
- [styles.loaderOnTheRight]: !glass
793
+ [styles.loaderOnTheRight]: !glass,
794
+ [styles.loaderActive]: renderLoader
795
795
  })} ref={this.loaderRef}>
796
796
  <LoaderInline />
797
797
  </div>)}
@@ -1,7 +1,7 @@
1
1
  import React from 'react';
2
2
  import List from '../list/list.js';
3
3
 
4
- var modules_da7ab055 = {"unit":"8px","button-shadow":"inset 0 0 0 1px","height":"var(--ring-button-height)","loaderWidth":"64px","overInputZIndex":"2","inputGap":"24px","light":"light_rui_d22e","heightS":"heightS_rui_d22e","heightM":"heightM_rui_d22e","heightL":"heightL_rui_d22e","button":"button_rui_d22e","active":"active_rui_d22e","withIcon":"withIcon_rui_d22e","icon":"icon_rui_d22e","primary":"primary_rui_d22e","loader":"loader_rui_d22e","loaderBackground":"loaderBackground_rui_d22e","danger":"danger_rui_d22e","text":"text_rui_d22e","content":"content_rui_d22e","text-loading":"text-loading_rui_d22e","inline":"inline_rui_d22e","withNormalIcon":"withNormalIcon_rui_d22e","withDangerIcon":"withDangerIcon_rui_d22e","progress":"progress_rui_d22e","delayed":"delayed_rui_d22e","short":"short_rui_d22e","dropdownIcon":"dropdownIcon_rui_d22e","queryAssist":"queryAssist_rui_d22e","error":"error_rui_d22e","queryAssistDisabled":"queryAssistDisabled_rui_d22e","huge":"huge_rui_d22e","actions":"actions_rui_d22e","placeholder":"placeholder_rui_d22e resetButton_rui_8bff","input":"input_rui_d22e","letter-text":"letter-text_rui_d22e","letterDefault":"letterDefault_rui_d22e","letter-field-name":"letter-field-name_rui_d22e","letter-field-value":"letter-field-value_rui_d22e","letter-operator":"letter-operator_rui_d22e","letter-error":"letter-error_rui_d22e","highlight":"highlight_rui_d22e","service":"service_rui_d22e","letter":"letter_rui_d22e","rightSearchButton":"rightSearchButton_rui_d22e","clear":"clear_rui_d22e","loaderOnTheRight":"loaderOnTheRight_rui_d22e","withoutGlass":"withoutGlass_rui_d22e"};
4
+ var modules_da7ab055 = {"unit":"8px","button-shadow":"inset 0 0 0 1px","height":"var(--ring-button-height)","loaderWidth":"64px","overInputZIndex":"2","inputGap":"24px","light":"light_rui_d22e","heightS":"heightS_rui_d22e","heightM":"heightM_rui_d22e","heightL":"heightL_rui_d22e","button":"button_rui_d22e","active":"active_rui_d22e","withIcon":"withIcon_rui_d22e","icon":"icon_rui_d22e","primary":"primary_rui_d22e","loader":"loader_rui_d22e","loaderBackground":"loaderBackground_rui_d22e","danger":"danger_rui_d22e","text":"text_rui_d22e","content":"content_rui_d22e","text-loading":"text-loading_rui_d22e","inline":"inline_rui_d22e","withNormalIcon":"withNormalIcon_rui_d22e","withDangerIcon":"withDangerIcon_rui_d22e","progress":"progress_rui_d22e","delayed":"delayed_rui_d22e","short":"short_rui_d22e","dropdownIcon":"dropdownIcon_rui_d22e","queryAssist":"queryAssist_rui_d22e","error":"error_rui_d22e","queryAssistDisabled":"queryAssistDisabled_rui_d22e","huge":"huge_rui_d22e","actions":"actions_rui_d22e","input":"input_rui_d22e","letter-text":"letter-text_rui_d22e","letterDefault":"letterDefault_rui_d22e","letter-field-name":"letter-field-name_rui_d22e","letter-field-value":"letter-field-value_rui_d22e","letter-operator":"letter-operator_rui_d22e","letter-error":"letter-error_rui_d22e","highlight":"highlight_rui_d22e","service":"service_rui_d22e","placeholder":"placeholder_rui_d22e resetButton_rui_8bff","letter":"letter_rui_d22e","rightSearchButton":"rightSearchButton_rui_d22e","clear":"clear_rui_d22e","loaderOnTheRight":"loaderOnTheRight_rui_d22e","withoutGlass":"withoutGlass_rui_d22e","loaderActive":"loaderActive_rui_d22e"};
5
5
 
6
6
  const ICON_ID_LENGTH = 44;
7
7
  class QueryAssistSuggestions {
@@ -23,7 +23,7 @@ export interface PositionAttrs {
23
23
  autoCorrectTopOverflow: boolean;
24
24
  }
25
25
  export declare const positionPropKeys: readonly ["directions", "autoPositioning", "autoCorrectTopOverflow", "sidePadding", "top", "left", "offset", "maxHeight", "minWidth"];
26
- export declare function maxHeightForDirection(direction: Directions, anchorNode: Element, containerNode?: Element | null): number;
26
+ export declare function maxHeightForDirection(direction: Directions, anchorNode: Element, containerNode?: Element | null): number | null;
27
27
  export default function position(attrs: PositionAttrs): {
28
28
  styles: PositionStyles;
29
29
  direction: Directions | null;
@@ -81,7 +81,7 @@ function verticalOverflow(styles, scrollingCoordinates, attrs) {
81
81
  const viewportMinX = scrollingCoordinates.top + attrs.sidePadding;
82
82
  const viewportMaxX = scrollingCoordinates.top + containerHeight - attrs.sidePadding;
83
83
  const topOverflow = Math.max(viewportMinX - styles.top, 0);
84
- const popupHeight = attrs.maxHeight && typeof attrs.maxHeight === 'number' ? Math.min(attrs.popup.scrollHeight, attrs.maxHeight) : attrs.popup.scrollHeight;
84
+ const popupHeight = attrs.popup.clientHeight;
85
85
  const verticalDiff = styles.top + popupHeight - viewportMaxX;
86
86
  const bottomOverflow = Math.max(verticalDiff, 0);
87
87
  return topOverflow + bottomOverflow;
@@ -101,6 +101,38 @@ const defaultcontainerRect = {
101
101
  top: 0,
102
102
  left: 0
103
103
  };
104
+ function handleTopOffScreen(_ref) {
105
+ let {
106
+ sidePadding,
107
+ styles,
108
+ anchorRect,
109
+ maxHeight,
110
+ popupScrollHeight,
111
+ direction,
112
+ scroll
113
+ } = _ref;
114
+ const BORDER_COMPENSATION = 1;
115
+ const {
116
+ TOP_LEFT,
117
+ TOP_RIGHT,
118
+ TOP_CENTER,
119
+ RIGHT_TOP,
120
+ LEFT_TOP
121
+ } = Directions;
122
+ const openedToTop = direction != null && [TOP_LEFT, TOP_RIGHT, TOP_CENTER, RIGHT_TOP, LEFT_TOP].includes(direction);
123
+ if (!openedToTop) {
124
+ return styles;
125
+ }
126
+ const isAttachedToAnchorTop = direction != null && [TOP_LEFT, TOP_CENTER, TOP_RIGHT].includes(direction);
127
+ const attachingPointY = isAttachedToAnchorTop ? anchorRect.top : anchorRect.bottom;
128
+ const effectiveHeight = maxHeight && typeof maxHeight === 'number' ? Math.min(popupScrollHeight, maxHeight) : popupScrollHeight;
129
+ const hypotheticalTop = attachingPointY - effectiveHeight;
130
+ if (hypotheticalTop <= sidePadding) {
131
+ styles.top = sidePadding + scroll.top;
132
+ styles.maxHeight = attachingPointY - sidePadding + BORDER_COMPENSATION;
133
+ }
134
+ return styles;
135
+ }
104
136
  function maxHeightForDirection(direction, anchorNode, containerNode) {
105
137
  const container = containerNode || document.documentElement;
106
138
  const domRect = anchorNode.getBoundingClientRect();
@@ -110,7 +142,7 @@ function maxHeightForDirection(direction, anchorNode, containerNode) {
110
142
  // XXX
111
143
  // If container is the document element
112
144
  // then we check client height too because we may have situation when
113
- // "height" from "getBoundingClientRect" less than "clientHeight".
145
+ // "height" from "getBoundingClientRect" less then "clientHeight".
114
146
  container === document.documentElement ? container.clientHeight : 0);
115
147
  const bottomMaxHeight = Math.max(containerHeight - (topMaxHeight + domRect.height), 0);
116
148
  switch (direction) {
@@ -132,8 +164,7 @@ function maxHeightForDirection(direction, anchorNode, containerNode) {
132
164
  case Directions.LEFT_CENTER:
133
165
  return domRect.height / 2 + Math.min(bottomMaxHeight / 2, topMaxHeight / 2);
134
166
  default:
135
- const exhaustiveCheck = direction;
136
- throw new Error(exhaustiveCheck);
167
+ return null;
137
168
  }
138
169
  }
139
170
  function position(attrs) {
@@ -169,9 +200,7 @@ function position(attrs) {
169
200
  };
170
201
  const directionsMatrix = getPositionStyles(popup, anchorRect, anchorLeft, anchorTop, offset);
171
202
  if (!autoPositioning || directions.length === 1) {
172
- styles = {
173
- ...directionsMatrix[directions[0]]
174
- };
203
+ styles = directionsMatrix[directions[0]];
175
204
  chosenDirection = directions[0];
176
205
  } else {
177
206
  const sortedByIncreasingOverflow = directions.
@@ -179,20 +208,18 @@ function position(attrs) {
179
208
  concat(directions[0]).filter(direction => directionsMatrix[direction]).map(direction => ({
180
209
  styles: directionsMatrix[direction],
181
210
  direction
182
- })).sort((_ref, _ref2) => {
211
+ })).sort((_ref2, _ref3) => {
183
212
  let {
184
213
  styles: stylesA
185
- } = _ref;
214
+ } = _ref2;
186
215
  let {
187
216
  styles: stylesB
188
- } = _ref2;
217
+ } = _ref3;
189
218
  const overflowA = verticalOverflow(stylesA, scroll, overflowAttrs) + horizontalOverflow(stylesA, scroll, overflowAttrs);
190
219
  const overflowB = verticalOverflow(stylesB, scroll, overflowAttrs) + horizontalOverflow(stylesB, scroll, overflowAttrs);
191
220
  return overflowA - overflowB;
192
221
  });
193
- styles = {
194
- ...sortedByIncreasingOverflow[0].styles
195
- };
222
+ styles = sortedByIncreasingOverflow[0].styles;
196
223
  chosenDirection = sortedByIncreasingOverflow[0].direction;
197
224
  }
198
225
  // because of the anchor negative margin top and left also may become negative
@@ -208,11 +235,17 @@ function position(attrs) {
208
235
  } else if (maxHeight) {
209
236
  styles.maxHeight = maxHeight;
210
237
  }
211
- if (autoCorrectTopOverflow && chosenDirection && anchor) {
212
- styles.maxHeight = maxHeightForDirection(chosenDirection, anchor, container) - sidePadding;
213
- if (styles.top === 0) {
214
- styles.top = sidePadding;
215
- }
238
+ if (autoCorrectTopOverflow) {
239
+ var _popup$scrollHeight;
240
+ styles = handleTopOffScreen({
241
+ sidePadding,
242
+ styles,
243
+ anchorRect,
244
+ maxHeight,
245
+ direction: chosenDirection,
246
+ popupScrollHeight: (_popup$scrollHeight = popup?.scrollHeight) !== null && _popup$scrollHeight !== void 0 ? _popup$scrollHeight : 0,
247
+ scroll
248
+ });
216
249
  }
217
250
  if (minWidth === MinWidth.TARGET || minWidth === 'target') {
218
251
  styles.minWidth = anchorRect.width;
@@ -776,12 +776,12 @@ class QueryAssist extends Component {
776
776
  const inputClasses = classNames(this.props.inputClassName, {
777
777
  [`${modules_da7ab055.input} ring-js-shortcuts`]: true,
778
778
  [modules_da7ab055.inputGap]: actions.length || this.isRenderingGlassOrLoader() && !glass,
779
- [modules_da7ab055.inputGap2]: actions.length === 2,
780
- [modules_da7ab055.inputLeftGap]: this.isRenderingGlassOrLoader() && glass
779
+ [modules_da7ab055.inputGap2]: actions.length === 2 // TODO: replace with flex-box layout
781
780
  });
781
+
782
782
  const placeholderStyles = classNames({
783
783
  [modules_da7ab055.placeholder]: true,
784
- [modules_da7ab055.withoutGlass]: !renderGlass
784
+ [modules_da7ab055.withoutGlass]: !this.isRenderingGlassOrLoader() || !renderLoader && huge
785
785
  });
786
786
  return /*#__PURE__*/React.createElement(ControlsHeightContext.Provider, {
787
787
  value: ControlsHeight.M
@@ -801,7 +801,8 @@ class QueryAssist extends Component {
801
801
  "data-test": "query-assist-search-icon"
802
802
  }), renderLoader && /*#__PURE__*/React.createElement("div", {
803
803
  className: classNames(modules_da7ab055.icon, modules_da7ab055.loader, {
804
- [modules_da7ab055.loaderOnTheRight]: !glass
804
+ [modules_da7ab055.loaderOnTheRight]: !glass,
805
+ [modules_da7ab055.loaderActive]: renderLoader
805
806
  }),
806
807
  ref: this.loaderRef
807
808
  }, /*#__PURE__*/React.createElement(LoaderInline, null)), /*#__PURE__*/React.createElement(ContentEditable, {