@jetbrains/ring-ui 5.1.19 → 5.1.21

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.
Files changed (70) hide show
  1. package/README.md +1 -1
  2. package/components/auth/request-builder.d.ts +1 -0
  3. package/components/code/code.d.ts +1 -0
  4. package/components/editable-heading/editable-heading.css +5 -1
  5. package/components/editable-heading/editable-heading.d.ts +1 -1
  6. package/components/editable-heading/editable-heading.js +5 -3
  7. package/components/grid/row.js +3 -3
  8. package/components/header/profile.js +1 -1
  9. package/components/island/header.js +1 -1
  10. package/components/list/list.js +3 -3
  11. package/components/loader/loader__core.js +6 -6
  12. package/components/popup/popup.js +3 -3
  13. package/components/progress-bar/progress-bar.css +6 -0
  14. package/components/progress-bar/progress-bar.d.ts +6 -0
  15. package/components/progress-bar/progress-bar.js +9 -3
  16. package/components/query-assist/query-assist.js +1 -1
  17. package/components/select/select-popup.css +4 -0
  18. package/components/select/select.js +21 -21
  19. package/dist/_helpers/select__filter.js +1 -1
  20. package/dist/analytics/analytics__custom-plugin.js +1 -2
  21. package/dist/analytics/analytics__ga-plugin.js +1 -1
  22. package/dist/auth/auth__core.js +35 -35
  23. package/dist/auth/background-flow.js +2 -2
  24. package/dist/auth/iframe-flow.js +3 -3
  25. package/dist/auth/request-builder.d.ts +1 -0
  26. package/dist/auth/request-builder.js +2 -1
  27. package/dist/auth/storage.js +8 -4
  28. package/dist/auth/token-validator.js +4 -3
  29. package/dist/auth/window-flow.js +3 -3
  30. package/dist/auth-ng/auth-ng.js +0 -1
  31. package/dist/caret/caret.js +4 -4
  32. package/dist/clipboard/clipboard-fallback.js +3 -3
  33. package/dist/code/code.d.ts +1 -0
  34. package/dist/data-list/data-list.js +2 -2
  35. package/dist/date-picker/date-picker.js +1 -1
  36. package/dist/date-picker/date-popup.js +2 -2
  37. package/dist/dropdown/dropdown.js +2 -2
  38. package/dist/editable-heading/editable-heading.d.ts +1 -1
  39. package/dist/editable-heading/editable-heading.js +16 -9
  40. package/dist/global/focus-sensor-hoc.js +6 -6
  41. package/dist/global/schedule-raf.js +1 -1
  42. package/dist/grid/row.js +7 -1
  43. package/dist/header/profile.js +1 -0
  44. package/dist/header/smart-services.js +2 -2
  45. package/dist/input/input.js +2 -2
  46. package/dist/island/content.js +1 -1
  47. package/dist/island/header.js +1 -0
  48. package/dist/list/list.js +3 -0
  49. package/dist/loader/loader.js +1 -1
  50. package/dist/loader/loader__core.js +19 -7
  51. package/dist/loader-screen-ng/loader-screen-ng.js +0 -2
  52. package/dist/message-bundle-ng/message-bundle-ng.js +0 -1
  53. package/dist/pager/pager.js +4 -4
  54. package/dist/popup/popup.js +3 -0
  55. package/dist/progress-bar/progress-bar.d.ts +6 -0
  56. package/dist/progress-bar/progress-bar.js +11 -4
  57. package/dist/query-assist/query-assist.js +13 -12
  58. package/dist/select/select.js +22 -2
  59. package/dist/select-ng/select-ng.js +0 -2
  60. package/dist/select-ng/select-ng__lazy.js +1 -1
  61. package/dist/storage/storage__fallback.js +4 -2
  62. package/dist/style.css +1 -1
  63. package/dist/tab-trap/tab-trap.js +1 -1
  64. package/dist/table/multitable.js +7 -7
  65. package/dist/table/row-with-focus-sensor.js +4 -4
  66. package/dist/table/selection-shortcuts-hoc.js +11 -11
  67. package/dist/tag/tag.js +1 -1
  68. package/dist/tags-input/tags-input.js +7 -7
  69. package/dist/tooltip/tooltip.js +2 -2
  70. package/package.json +32 -32
package/README.md CHANGED
@@ -1,7 +1,7 @@
1
1
  # Ring UI — JetBrains Web UI components
2
2
  [![Storybook][storybook-img]][docsite] [![Build Status][ci-img]][ci-bt] [![Storybook][browserstack-img]][browserstack-build-page] [![NPM version][npm-version-img]][npm-package] [![NPM downloads][npm-count-img]][npm-package]
3
3
 
4
- [![official JetBrains project](https://jb.gg/badges/official-flat-square.svg)](https://confluence.jetbrains.com/display/ALL/JetBrains+on+GitHub)
4
+ [![official JetBrains project](https://jb.gg/badges/official-flat-square.svg)](https://github.com/JetBrains#jetbrains-on-github)
5
5
 
6
6
  This collection of UI components aims to provide all the necessary building blocks for web-based products built inside JetBrains, as well as third-party plugins developed for JetBrains' products.
7
7
 
@@ -1,3 +1,4 @@
1
+ /// <reference types="typings" />
1
2
  import uuid from 'simply-uuid';
2
3
  import AuthStorage, { AuthState } from './storage';
3
4
  export interface AuthRequestBuilderConfig {
@@ -1,3 +1,4 @@
1
+ /// <reference types="highlight.js" />
1
2
  import React, { PureComponent, Ref } from 'react';
2
3
  import PropTypes from 'prop-types';
3
4
  import highlight from 'highlight.js/lib/core';
@@ -131,6 +131,10 @@
131
131
  resize: none;
132
132
  }
133
133
 
134
+ .textareaNotOverflow {
135
+ overflow: hidden;
136
+ }
137
+
134
138
  .textareaFade {
135
139
  position: absolute;
136
140
  bottom: 0;
@@ -174,7 +178,7 @@
174
178
  }
175
179
 
176
180
  .level3 {
177
- font-size: 14px;
181
+ font-size: 16px;
178
182
  }
179
183
 
180
184
  .sizeS {
@@ -23,7 +23,7 @@ export type EditableHeadingProps = Omit<InputHTMLAttributes<HTMLInputElement | H
23
23
  'data-test'?: string | null;
24
24
  error?: string;
25
25
  multiline?: boolean;
26
- maxInputHeight?: number;
26
+ maxInputRows?: number;
27
27
  renderMenu?: () => React.ReactNode;
28
28
  translations?: EditableHeadingTranslations;
29
29
  };
@@ -11,7 +11,7 @@ export { Levels };
11
11
  export { Size };
12
12
  function noop() { }
13
13
  export const EditableHeading = (props) => {
14
- const { level = Levels.H1, className, headingClassName, inputClassName, children, isEditing = false, isSavingPossible = false, isSaving = false, embedded = false, size = Size.L, onEdit = noop, onSave = noop, onCancel = noop, autoFocus = true, 'data-test': dataTest, error, disabled, multiline = false, renderMenu = () => null, onFocus, onBlur, onChange, onScroll, maxInputHeight, translations = {
14
+ const { level = Levels.H1, className, headingClassName, inputClassName, children, isEditing = false, isSavingPossible = false, isSaving = false, embedded = false, size = Size.L, onEdit = noop, onSave = noop, onCancel = noop, autoFocus = true, 'data-test': dataTest, error, disabled, multiline = false, renderMenu = () => null, onFocus, onBlur, onChange, onScroll, maxInputRows, translations = {
15
15
  save: 'Save',
16
16
  cancel: 'Cancel'
17
17
  }, ...restProps } = props;
@@ -21,6 +21,7 @@ export const EditableHeading = (props) => {
21
21
  const [isInSelectionMode, setIsInSelectionMode] = React.useState(false);
22
22
  const textAreaRef = React.useRef(null);
23
23
  const [isScrolledToBottom, setIsScrolledToBottom] = React.useState(false);
24
+ const [isOverflow, setIsOverflow] = React.useState(false);
24
25
  const hasError = error !== undefined;
25
26
  const isSaveDisabled = !isSavingPossible || !children || children.trim() === '' || hasError || isSaving;
26
27
  const isCancelDisabled = isSaving;
@@ -44,7 +45,7 @@ export const EditableHeading = (props) => {
44
45
  [styles.selectionMode]: isInSelectionMode
45
46
  });
46
47
  const headingClasses = classNames(styles.heading, headingClassName, styles[`size${size}`]);
47
- const inputClasses = classNames('ring-js-shortcuts', styles.input, styles.textarea, inputStyles[`size${size}`], styles[`level${level}`], inputClassName);
48
+ const inputClasses = classNames('ring-js-shortcuts', styles.input, styles.textarea, { [styles.textareaNotOverflow]: !isOverflow }, inputStyles[`size${size}`], styles[`level${level}`], inputClassName);
48
49
  const stretch = useCallback((el) => {
49
50
  if (!el || !el.style) {
50
51
  return;
@@ -63,6 +64,7 @@ export const EditableHeading = (props) => {
63
64
  const clientHeight = el.clientHeight || 0;
64
65
  const scrollTop = el.scrollTop || 0;
65
66
  setIsScrolledToBottom(scrollHeight - clientHeight <= scrollTop);
67
+ setIsOverflow(scrollHeight > clientHeight);
66
68
  }, [setIsScrolledToBottom]);
67
69
  const onHeadingMouseDown = React.useCallback(() => {
68
70
  setIsMouseDown(true);
@@ -116,7 +118,7 @@ export const EditableHeading = (props) => {
116
118
  {!multiline
117
119
  ? (<input className={inputClasses} value={children} autoFocus={autoFocus} data-test={dataTest} disabled={isSaving} onChange={onChange} {...restProps} onFocus={onInputFocus} onBlur={onInputBlur}/>)
118
120
  : (<div className={classNames(styles.textareaWrapper, inputStyles[`size${size}`])}>
119
- <textarea ref={textAreaRef} className={inputClasses} value={children} autoFocus={autoFocus} data-test={dataTest} disabled={isSaving} onChange={onInputChange} {...restProps} onFocus={onInputFocus} onBlur={onInputBlur} onScroll={onInputScroll} style={{ maxHeight: maxInputHeight }}/>
121
+ <textarea ref={textAreaRef} className={inputClasses} value={children} autoFocus={autoFocus} data-test={dataTest} disabled={isSaving} onChange={onInputChange} {...restProps} onFocus={onInputFocus} onBlur={onInputBlur} onScroll={onInputScroll} style={{ maxHeight: maxInputRows ? `${maxInputRows}lh` : '' }}/>
120
122
  {!isScrolledToBottom && <div className={styles.textareaFade}/>}
121
123
  </div>)}
122
124
  </>)
@@ -4,9 +4,9 @@ import classNames from 'classnames';
4
4
  import styles from './grid.css';
5
5
  const ModifierType = PropTypes.oneOf(['xs', 'sm', 'md', 'lg']);
6
6
  const modifierKeys = [
7
- 'start', 'center', 'end',
8
- 'around', 'between',
9
- 'top', 'middle', 'baseline', 'bottom',
7
+ 'start', 'center', 'end', // text-align, justify-content
8
+ 'around', 'between', // justify-content
9
+ 'top', 'middle', 'baseline', 'bottom', // align-items
10
10
  'first', 'last' // order
11
11
  ];
12
12
  /**
@@ -93,7 +93,7 @@ export default class Profile extends PureComponent {
93
93
  {
94
94
  rgItemType: PopupMenu.ListProps.Type.LINK,
95
95
  label: translations?.profile ?? translate('profile'),
96
- target: '_self',
96
+ target: '_self', // Full page reload in Angular
97
97
  href: profileUrl,
98
98
  LinkComponent
99
99
  },
@@ -45,7 +45,7 @@ class Header extends Component {
45
45
  });
46
46
  const headerStyle = phase != null
47
47
  ? {
48
- lineHeight: `${this.style('LINE_HEIGHT')}px`,
48
+ lineHeight: `${this.style('LINE_HEIGHT')}px`, // need to append px because number is a valid line-height value
49
49
  paddingTop: this.style('PADDING_TOP'),
50
50
  paddingBottom: this.style('PADDING_BOTTOM')
51
51
  }
@@ -90,9 +90,9 @@ export default class List extends Component {
90
90
  };
91
91
  static defaultProps = {
92
92
  data: [],
93
- restoreActiveIndex: false,
94
- activateSingleItem: false,
95
- activateFirstItem: false,
93
+ restoreActiveIndex: false, // restore active item using its "key" property
94
+ activateSingleItem: false, // if there is only one item, activate it
95
+ activateFirstItem: false, // if there no active items, activate the first one
96
96
  onMouseOut: noop,
97
97
  onSelect: noop,
98
98
  onScrollToBottom: noop,
@@ -40,12 +40,12 @@ export default class LoaderCore {
40
40
  stop: false,
41
41
  deterministic: false,
42
42
  colors: [
43
- { r: 215, g: 60, b: 234 },
44
- { r: 145, g: 53, b: 224 },
45
- { r: 88, g: 72, b: 224 },
46
- { r: 37, g: 183, b: 255 },
47
- { r: 89, g: 189, b: 0 },
48
- { r: 251, g: 172, b: 2 },
43
+ { r: 215, g: 60, b: 234 }, //#D73CEA
44
+ { r: 145, g: 53, b: 224 }, //#9135E0
45
+ { r: 88, g: 72, b: 224 }, //#5848F4
46
+ { r: 37, g: 183, b: 255 }, //#25B7FF
47
+ { r: 89, g: 189, b: 0 }, //#59BD00
48
+ { r: 251, g: 172, b: 2 }, //#FBAC02
49
49
  { r: 227, g: 37, b: 129 } //#E32581
50
50
  ]
51
51
  };
@@ -287,9 +287,9 @@ Popup.propTypes = {
287
287
  children: PropTypes.node.isRequired,
288
288
  dontCloseOnAnchorClick: PropTypes.bool,
289
289
  shortcuts: PropTypes.bool,
290
- keepMounted: PropTypes.bool,
290
+ keepMounted: PropTypes.bool, // pass this prop to preserve the popup's DOM state while hidden
291
291
  'data-test': PropTypes.string,
292
- client: PropTypes.bool,
292
+ client: PropTypes.bool, // true means that it's never used in SSR
293
293
  directions: PropTypes.arrayOf(PropTypes.string),
294
294
  autoPositioning: PropTypes.bool,
295
295
  autoCorrectTopOverflow: PropTypes.bool,
@@ -298,7 +298,7 @@ Popup.propTypes = {
298
298
  maxHeight: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
299
299
  minWidth: PropTypes.number,
300
300
  sidePadding: PropTypes.number,
301
- attached: PropTypes.bool,
301
+ attached: PropTypes.bool, // Popup adjacent to an input, without upper border and shadow
302
302
  onMouseDown: PropTypes.func,
303
303
  onMouseUp: PropTypes.func,
304
304
  onMouseOver: PropTypes.func,
@@ -63,6 +63,12 @@
63
63
 
64
64
  background-image: linear-gradient(to right, rgba(0, 0, 0, 0), var(--ring-progress-bar-line-background-color), rgba(0, 0, 0, 0));
65
65
  background-repeat: no-repeat;
66
+
67
+ .staticLineColor & {
68
+ animation: none;
69
+
70
+ background-image: var(--ring-progress-bar-line-background-color);
71
+ }
66
72
  }
67
73
  }
68
74
 
@@ -5,6 +5,7 @@ export interface ProgressBarProps extends HTMLAttributes<HTMLElement> {
5
5
  value: number;
6
6
  label: string;
7
7
  global?: boolean | null | undefined;
8
+ staticColor?: boolean;
8
9
  }
9
10
  /**
10
11
  * @name Progress Bar
@@ -43,6 +44,11 @@ export default class ProgressBar extends PureComponent<ProgressBarProps> {
43
44
  * @type {number}
44
45
  */
45
46
  value: PropTypes.Requireable<number>;
47
+ /**
48
+ * Disables Disabled progress bar color animation and sets it to static color.
49
+ * @type {boolean}
50
+ */
51
+ staticColor: PropTypes.Requireable<boolean>;
46
52
  };
47
53
  static defaultProps: {
48
54
  max: number;
@@ -42,7 +42,12 @@ export default class ProgressBar extends PureComponent {
42
42
  * A floating point number that specifies current task completion rate.
43
43
  * @type {number}
44
44
  */
45
- value: PropTypes.number
45
+ value: PropTypes.number,
46
+ /**
47
+ * Disables Disabled progress bar color animation and sets it to static color.
48
+ * @type {boolean}
49
+ */
50
+ staticColor: PropTypes.bool
46
51
  };
47
52
  static defaultProps = {
48
53
  max: 1.0,
@@ -58,10 +63,11 @@ export default class ProgressBar extends PureComponent {
58
63
  this.progressbar = el;
59
64
  };
60
65
  render() {
61
- const { className, global, max, value, label, ...otherProps } = this.props;
66
+ const { className, global, max, value, label, staticColor, ...otherProps } = this.props;
62
67
  const width = value ? `${ProgressBar.toPercent(value, max)}%` : undefined;
63
68
  const classes = classNames(styles.progressBar, className, {
64
- [styles.globalMode]: global
69
+ [styles.globalMode]: global,
70
+ [styles.staticLineColor]: staticColor
65
71
  });
66
72
  return (<div {...otherProps} className={classes} ref={this.progressbarWrapperRef}>
67
73
  <div className={styles.line} ref={this.progressbarRef} role="progressbar" aria-label={label} aria-valuenow={value} aria-valuemin={0} aria-valuemax={max} style={{ width }}/>
@@ -800,7 +800,7 @@ export default class QueryAssist extends Component {
800
800
  const inputClasses = classNames(this.props.inputClassName, {
801
801
  [`${styles.input} ring-js-shortcuts`]: true,
802
802
  [styles.inputGap]: actions.length || this.isRenderingGlassOrLoader() && !glass,
803
- [styles.inputGap2]: actions.length === 2,
803
+ [styles.inputGap2]: actions.length === 2, // TODO: replace with flex-box layout
804
804
  [styles.inputRevertOrder]: !glass || huge
805
805
  });
806
806
  const placeholderStyles = classNames({
@@ -42,6 +42,10 @@
42
42
  width: 0;
43
43
  }
44
44
 
45
+ .popup {
46
+ overscroll-behavior: contain;
47
+ }
48
+
45
49
  .filterWrapper {
46
50
  position: relative;
47
51
 
@@ -181,46 +181,46 @@ function isSameSelected(prevSelected, selected) {
181
181
  export default class Select extends Component {
182
182
  static defaultProps = {
183
183
  data: [],
184
- filter: false,
184
+ filter: false, // enable filter (not in INPUT modes)
185
185
  filterIcon: null,
186
186
  filterRef: noop,
187
- multiple: false,
188
- clear: false,
189
- loading: false,
190
- disabled: false,
187
+ multiple: false, // multiple can be an object - see demo for more information
188
+ clear: false, // enable clear button that clears the "selected" state
189
+ loading: false, // show a loading indicator while data is loading
190
+ disabled: false, // disable select
191
191
  type: Type.BUTTON,
192
192
  size: Size.M,
193
- targetElement: null,
194
- hideSelected: false,
195
- allowAny: false,
196
- hideArrow: false,
193
+ targetElement: null, // element to bind the popup to (select BUTTON or INPUT by default)
194
+ hideSelected: false, // INPUT mode: clears the input after an option is selected (useful when the selection is displayed in some custom way elsewhere)
195
+ allowAny: false, // INPUT mode: allows any value to be entered
196
+ hideArrow: false, // hide dropdown arrow icon
197
197
  showPopup: false,
198
- maxHeight: 600,
198
+ maxHeight: 600, // height of the options list, including the filter and the 'Add' button
199
199
  directions: [
200
200
  Popup.PopupProps.Directions.BOTTOM_RIGHT,
201
201
  Popup.PopupProps.Directions.BOTTOM_LEFT,
202
202
  Popup.PopupProps.Directions.TOP_LEFT,
203
203
  Popup.PopupProps.Directions.TOP_RIGHT
204
204
  ],
205
- selected: null,
206
- label: null,
207
- selectedLabel: null,
208
- inputPlaceholder: '',
209
- hint: null,
205
+ selected: null, // current selection (item / array of items)
206
+ label: null, // BUTTON or INPUT label (nothing selected)
207
+ selectedLabel: null, // BUTTON or INPUT label (something selected)
208
+ inputPlaceholder: '', // Placeholder for input modes
209
+ hint: null, // hint text to display under the list
210
210
  shortcutsEnabled: false,
211
211
  onBeforeOpen: noop,
212
212
  onLoadMore: noop,
213
213
  onOpen: noop,
214
214
  onClose: noop,
215
- onFilter: noop,
215
+ onFilter: noop, // search string as first argument
216
216
  onFocus: noop,
217
217
  onBlur: noop,
218
218
  onKeyDown: noop,
219
- onSelect: noop,
220
- onDeselect: noop,
221
- onOutsideClick: noop,
222
- onChange: noop,
223
- onAdd: noop,
219
+ onSelect: noop, // single + multi
220
+ onDeselect: noop, // multi
221
+ onOutsideClick: noop, // multi
222
+ onChange: noop, // multi
223
+ onAdd: noop, // search string as first argument
224
224
  onDone: noop,
225
225
  onReset: noop,
226
226
  tags: null,
@@ -10,7 +10,7 @@ import sniffr from '../global/sniffer.js';
10
10
  import { ActiveItemContext } from '../list/list.js';
11
11
  import { I18nContext } from '../i18n/i18n-context.js';
12
12
 
13
- var modules_b607bec2 = {"unit":"i__const_unit_0","filterWithTagsFocused":"filterWithTagsFocused_rui_531d","light":"light_rui_2ac4","filterWithTags":"filterWithTags_rui_531d","filterWrapper":"filterWrapper_rui_531d","filterWithTagsInput":"filterWithTagsInput_rui_531d","filter":"filter_rui_531d","filterIcon":"filterIcon_rui_531d","bottomLine":"bottomLine_rui_531d","bottomLineOverItem":"bottomLineOverItem_rui_531d","message":"message_rui_531d","selectAll":"selectAll_rui_531d"};
13
+ var modules_b607bec2 = {"unit":"i__const_unit_0","filterWithTagsFocused":"filterWithTagsFocused_rui_531d","light":"light_rui_2ac4","filterWithTags":"filterWithTags_rui_531d","filterWrapper":"filterWrapper_rui_531d","filterWithTagsInput":"filterWithTagsInput_rui_531d","filter":"filter_rui_531d","popup":"popup_rui_531d","filterIcon":"filterIcon_rui_531d","bottomLine":"bottomLine_rui_531d","bottomLineOverItem":"bottomLineOverItem_rui_531d","message":"message_rui_531d","selectAll":"selectAll_rui_531d"};
14
14
 
15
15
  var _excluded = ["className", "listId"];
16
16
  function noop() {}
@@ -64,7 +64,6 @@ var AnalyticsCustomPlugin = /*#__PURE__*/function () {
64
64
  if (this._isDevelopment) {
65
65
  console.log('TRACKING DATA = ', category, action, data); // eslint-disable-line no-console
66
66
  }
67
-
68
67
  var baseSendingData = {
69
68
  category,
70
69
  action,
@@ -80,7 +79,7 @@ var AnalyticsCustomPlugin = /*#__PURE__*/function () {
80
79
  this._data.push(sendingData);
81
80
  if (this._flushMaxPackSize != null && this._data.length >= this._flushMaxPackSize) {
82
81
  var _this$_flush;
83
- (_this$_flush = this._flush) === null || _this$_flush === void 0 ? void 0 : _this$_flush.call(this);
82
+ (_this$_flush = this._flush) === null || _this$_flush === void 0 || _this$_flush.call(this);
84
83
  }
85
84
  }
86
85
  }, {
@@ -31,7 +31,7 @@ var AnalyticsGAPlugin = /*#__PURE__*/function () {
31
31
  var m = s.getElementsByTagName(o)[0];
32
32
  a.async = true;
33
33
  a.src = g;
34
- (_m$parentNode = m.parentNode) === null || _m$parentNode === void 0 ? void 0 : _m$parentNode.insertBefore(a, m);
34
+ (_m$parentNode = m.parentNode) === null || _m$parentNode === void 0 || _m$parentNode.insertBefore(a, m);
35
35
  })(window, document, 'script', '//www.google-analytics.com/analytics.js', 'ga');
36
36
  /**
37
37
  * UA-57284711-1 - ga key for development purpose