@jetbrains/ring-ui 5.0.104 → 5.0.106

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.
@@ -21,10 +21,16 @@ export const EditableHeading = (props) => {
21
21
  const isSaveDisabled = !isSavingPossible || !children || children.trim() === '' || hasError || isSaving;
22
22
  const isCancelDisabled = isSaving;
23
23
  const isShortcutsDisabled = !isInFocus || isSaving;
24
- const shortcutsMap = React.useMemo(() => ({
25
- enter: isSaveDisabled ? noop : onSave,
26
- esc: isCancelDisabled ? noop : onCancel
27
- }), [isSaveDisabled, isCancelDisabled, onSave, onCancel]);
24
+ const shortcutsMap = React.useMemo(() => {
25
+ const map = {};
26
+ if (!isSaveDisabled) {
27
+ map.enter = onSave;
28
+ }
29
+ if (isCancelDisabled) {
30
+ map.esc = onCancel;
31
+ }
32
+ return map;
33
+ }, [isSaveDisabled, isCancelDisabled, onSave, onCancel]);
28
34
  const classes = classNames(styles.editableHeading, className, {
29
35
  [styles.fullSize]: isEditing && size === Size.FULL,
30
36
  [styles.isEditing]: isEditing,
@@ -11,6 +11,7 @@ export declare class HTTPError extends ExtendableError {
11
11
  export declare const CODE: {
12
12
  UNAUTHORIZED: number;
13
13
  };
14
+ type Method<T> = (url: string, params?: RequestParams) => Promise<T>;
14
15
  export interface FetchParams<T = unknown> extends Omit<RequestInit, 'body' | 'headers'> {
15
16
  body?: T;
16
17
  query?: Record<string, unknown> | undefined;
@@ -48,4 +49,13 @@ export default class HTTP implements Partial<HTTPAuth> {
48
49
  post: <T = any>(url: string, params?: RequestParamsWithoutMethod) => Promise<T>;
49
50
  delete: <T = any>(url: string, params?: RequestParamsWithoutMethod) => Promise<T>;
50
51
  put: <T = any>(url: string, params?: RequestParamsWithoutMethod) => Promise<T>;
52
+ /**
53
+ * Usage: const {promise, abort} = http.abortify(http.get<{id: string}>)('http://test.com');
54
+ * @param method
55
+ */
56
+ abortify: <T>(method: Method<T>) => (url: string, params?: RequestParams<boolean> | undefined) => {
57
+ promise: Promise<T>;
58
+ abort: () => void;
59
+ };
51
60
  }
61
+ export {};
@@ -187,4 +187,18 @@ export default class HTTP {
187
187
  ...params,
188
188
  method: 'PUT'
189
189
  }));
190
+ /**
191
+ * Usage: const {promise, abort} = http.abortify(http.get<{id: string}>)('http://test.com');
192
+ * @param method
193
+ */
194
+ abortify = (method) => (...[url, params]) => {
195
+ const ctrl = new AbortController();
196
+ if (params && !('signal' in params)) {
197
+ params.signal = ctrl.signal;
198
+ }
199
+ return {
200
+ promise: method.call(this, url, params),
201
+ abort: () => ctrl.abort()
202
+ };
203
+ };
190
204
  }
@@ -11,6 +11,9 @@ declare enum Size {
11
11
  L = "L",
12
12
  FULL = "FULL"
13
13
  }
14
+ export interface InputTranslations {
15
+ clear: string;
16
+ }
14
17
  export interface InputBaseProps {
15
18
  size: Size;
16
19
  enableShortcuts: boolean | string[];
@@ -25,6 +28,7 @@ export interface InputBaseProps {
25
28
  icon?: string | ComponentType | null | undefined;
26
29
  height?: ControlsHeight | undefined;
27
30
  afterInput?: ReactNode;
31
+ translations: InputTranslations;
28
32
  }
29
33
  type Override<D, S> = Omit<D, keyof S> & S;
30
34
  export type InputSpecificProps = Override<InputHTMLAttributes<HTMLInputElement>, InputBaseProps> & {
@@ -42,6 +46,9 @@ export declare class Input extends PureComponent<InputProps> {
42
46
  onChange: typeof noop;
43
47
  inputRef: typeof noop;
44
48
  enableShortcuts: string[];
49
+ translations: {
50
+ clear: string;
51
+ };
45
52
  };
46
53
  state: {
47
54
  empty: boolean;
@@ -27,7 +27,10 @@ export class Input extends PureComponent {
27
27
  size: Size.M,
28
28
  onChange: noop,
29
29
  inputRef: noop,
30
- enableShortcuts: ['esc']
30
+ enableShortcuts: ['esc'],
31
+ translations: {
32
+ clear: 'Clear input'
33
+ }
31
34
  };
32
35
  state = {
33
36
  empty: true
@@ -92,7 +95,7 @@ export class Input extends PureComponent {
92
95
  // Modifiers
93
96
  size, active, multiline, borderless,
94
97
  // Props
95
- label, error, className, inputClassName, children, value, onClear, disabled, inputRef, onChange, enableShortcuts, id, placeholder, icon, height = this.context, afterInput, ...restProps } = this.props;
98
+ label, error, className, inputClassName, children, value, onClear, disabled, inputRef, onChange, enableShortcuts, id, placeholder, icon, translations, height = this.context, afterInput, ...restProps } = this.props;
96
99
  const { empty } = this.state;
97
100
  const clearable = !!onClear;
98
101
  const classes = classNames(className, styles.outerContainer, [styles[`size${size}`]], [styles[`height${height}`]], {
@@ -124,7 +127,7 @@ export class Input extends PureComponent {
124
127
  {multiline
125
128
  ? (<textarea onChange={this.handleTextareaChange} rows={1} {...commonProps} {...restProps}/>)
126
129
  : (<input onChange={this.handleInputChange} {...commonProps} {...restProps}/>)}
127
- {clearable && !disabled && (<Button title="Clear input" data-test="ring-input-clear" className={styles.clear} icon={closeIcon} onClick={this.clear}/>)}
130
+ {clearable && !disabled && (<Button title={translations.clear} data-test="ring-input-clear" className={styles.clear} icon={closeIcon} onClick={this.clear}/>)}
128
131
  {afterInput}
129
132
  </div>
130
133
  {error && <div className={styles.errorText}>{error}</div>}
@@ -155,6 +158,7 @@ Input.propTypes = {
155
158
  disabled: PropTypes.bool,
156
159
  id: PropTypes.string,
157
160
  placeholder: PropTypes.string,
161
+ translations: PropTypes.object,
158
162
  icon: PropTypes.oneOfType([PropTypes.string, PropTypes.elementType])
159
163
  };
160
164
  export default Input;
@@ -47,9 +47,9 @@ export default class UserCard extends PureComponent<UserCardProps> {
47
47
  banned: PropTypes.Validator<string>;
48
48
  online: PropTypes.Validator<string>;
49
49
  offline: PropTypes.Validator<string>;
50
- copyToClipboard: PropTypes.Validator<string>;
51
- copiedToClipboard: PropTypes.Validator<string>;
52
- copingToClipboardError: PropTypes.Validator<string>;
50
+ copyToClipboard: PropTypes.Requireable<string>;
51
+ copiedToClipboard: PropTypes.Requireable<string>;
52
+ copingToClipboardError: PropTypes.Requireable<string>;
53
53
  unverified: PropTypes.Requireable<string>;
54
54
  }>>;
55
55
  };
@@ -28,9 +28,9 @@ export default class UserCard extends PureComponent {
28
28
  banned: PropTypes.string.isRequired,
29
29
  online: PropTypes.string.isRequired,
30
30
  offline: PropTypes.string.isRequired,
31
- copyToClipboard: PropTypes.string.isRequired,
32
- copiedToClipboard: PropTypes.string.isRequired,
33
- copingToClipboardError: PropTypes.string.isRequired,
31
+ copyToClipboard: PropTypes.string,
32
+ copiedToClipboard: PropTypes.string,
33
+ copingToClipboardError: PropTypes.string,
34
34
  unverified: PropTypes.string
35
35
  })
36
36
  };
@@ -39,7 +39,7 @@ export default class UserCard extends PureComponent {
39
39
  banned: 'banned',
40
40
  online: 'online',
41
41
  offline: 'offline',
42
- copyToClipboard: 'Copy to clipboard',
42
+ copyToClipboard: 'Copy email to clipboard',
43
43
  copiedToClipboard: 'Email was copied to clipboard',
44
44
  copingToClipboardError: 'Failed to copy to clipboard',
45
45
  unverified: 'Unverified'
@@ -75,7 +75,7 @@ export default class UserCard extends PureComponent {
75
75
  </div>
76
76
  <div className={styles.userLogin}>{user.login}</div>
77
77
  {user.email && (<span className={styles.userEmailWrapper}>
78
- <Link pseudo onClick={this.copyEmail} className={styles.userEmail}>
78
+ <Link href={`mailto:${user.email}`} title={`mailto:${user.email}`} target="_blank" className={styles.userEmail}>
79
79
  {user.email}
80
80
  </Link>
81
81
  {user.unverifiedEmail && (<span className={styles.unverifiedLabel}>{wording.unverified}</span>)}
@@ -29,7 +29,12 @@
29
29
  }
30
30
 
31
31
  .userInformationGeneral {
32
+ display: flex;
33
+ flex-direction: column;
34
+ justify-content: center;
35
+
32
36
  height: 56px;
37
+ padding-top: 1px;
33
38
  }
34
39
 
35
40
  .userNameLine {
@@ -72,6 +77,10 @@
72
77
  .userCopyIcon svg {
73
78
  margin-left: 4px;
74
79
 
80
+ color: var(--ring-icon-color);
81
+ }
82
+
83
+ .userCopyIcon:hover svg {
75
84
  color: var(--ring-link-hover-color);
76
85
  }
77
86
 
@@ -81,7 +90,7 @@
81
90
  opacity: 1;
82
91
  }
83
92
 
84
- .userEmailWrapper:hover .userEmail {
93
+ :has(.userCopyIcon:hover) > .userEmail {
85
94
  color: var(--ring-link-hover-color);
86
95
  }
87
96
 
@@ -71,8 +71,9 @@ class UserCard extends PureComponent {
71
71
  }, user.login), user.email && /*#__PURE__*/React.createElement("span", {
72
72
  className: modules_a4196c17.userEmailWrapper
73
73
  }, /*#__PURE__*/React.createElement(Link, {
74
- pseudo: true,
75
- onClick: this.copyEmail,
74
+ href: `mailto:${user.email}`,
75
+ title: `mailto:${user.email}`,
76
+ target: "_blank",
76
77
  className: modules_a4196c17.userEmail
77
78
  }, user.email), user.unverifiedEmail && /*#__PURE__*/React.createElement("span", {
78
79
  className: modules_a4196c17.unverifiedLabel
@@ -105,9 +106,9 @@ _defineProperty(UserCard, "propTypes", {
105
106
  banned: PropTypes.string.isRequired,
106
107
  online: PropTypes.string.isRequired,
107
108
  offline: PropTypes.string.isRequired,
108
- copyToClipboard: PropTypes.string.isRequired,
109
- copiedToClipboard: PropTypes.string.isRequired,
110
- copingToClipboardError: PropTypes.string.isRequired,
109
+ copyToClipboard: PropTypes.string,
110
+ copiedToClipboard: PropTypes.string,
111
+ copingToClipboardError: PropTypes.string,
111
112
  unverified: PropTypes.string
112
113
  })
113
114
  });
@@ -116,7 +117,7 @@ _defineProperty(UserCard, "defaultProps", {
116
117
  banned: 'banned',
117
118
  online: 'online',
118
119
  offline: 'offline',
119
- copyToClipboard: 'Copy to clipboard',
120
+ copyToClipboard: 'Copy email to clipboard',
120
121
  copiedToClipboard: 'Email was copied to clipboard',
121
122
  copingToClipboardError: 'Failed to copy to clipboard',
122
123
  unverified: 'Unverified'
@@ -66,10 +66,16 @@ const EditableHeading = props => {
66
66
  const isSaveDisabled = !isSavingPossible || !children || children.trim() === '' || hasError || isSaving;
67
67
  const isCancelDisabled = isSaving;
68
68
  const isShortcutsDisabled = !isInFocus || isSaving;
69
- const shortcutsMap = React.useMemo(() => ({
70
- enter: isSaveDisabled ? noop : onSave,
71
- esc: isCancelDisabled ? noop : onCancel
72
- }), [isSaveDisabled, isCancelDisabled, onSave, onCancel]);
69
+ const shortcutsMap = React.useMemo(() => {
70
+ const map = {};
71
+ if (!isSaveDisabled) {
72
+ map.enter = onSave;
73
+ }
74
+ if (isCancelDisabled) {
75
+ map.esc = onCancel;
76
+ }
77
+ return map;
78
+ }, [isSaveDisabled, isCancelDisabled, onSave, onCancel]);
73
79
  const classes = classNames(modules_6e69b0fe.editableHeading, className, {
74
80
  [modules_6e69b0fe.fullSize]: isEditing && size === Size.FULL,
75
81
  [modules_6e69b0fe.isEditing]: isEditing,
@@ -11,6 +11,7 @@ export declare class HTTPError extends ExtendableError {
11
11
  export declare const CODE: {
12
12
  UNAUTHORIZED: number;
13
13
  };
14
+ type Method<T> = (url: string, params?: RequestParams) => Promise<T>;
14
15
  export interface FetchParams<T = unknown> extends Omit<RequestInit, 'body' | 'headers'> {
15
16
  body?: T;
16
17
  query?: Record<string, unknown> | undefined;
@@ -48,4 +49,13 @@ export default class HTTP implements Partial<HTTPAuth> {
48
49
  post: <T = any>(url: string, params?: RequestParamsWithoutMethod) => Promise<T>;
49
50
  delete: <T = any>(url: string, params?: RequestParamsWithoutMethod) => Promise<T>;
50
51
  put: <T = any>(url: string, params?: RequestParamsWithoutMethod) => Promise<T>;
52
+ /**
53
+ * Usage: const {promise, abort} = http.abortify(http.get<{id: string}>)('http://test.com');
54
+ * @param method
55
+ */
56
+ abortify: <T>(method: Method<T>) => (url: string, params?: RequestParams<boolean> | undefined) => {
57
+ promise: Promise<T>;
58
+ abort: () => void;
59
+ };
51
60
  }
61
+ export {};
package/dist/http/http.js CHANGED
@@ -99,6 +99,20 @@ class HTTP {
99
99
  ...params,
100
100
  method: 'PUT'
101
101
  }));
102
+ _defineProperty(this, "abortify", method => function () {
103
+ for (var _len = arguments.length, _ref = new Array(_len), _key = 0; _key < _len; _key++) {
104
+ _ref[_key] = arguments[_key];
105
+ }
106
+ let [url, params] = _ref;
107
+ const ctrl = new AbortController();
108
+ if (params && !('signal' in params)) {
109
+ params.signal = ctrl.signal;
110
+ }
111
+ return {
112
+ promise: method.call(_this, url, params),
113
+ abort: () => ctrl.abort()
114
+ };
115
+ });
102
116
  if (_auth) {
103
117
  this.setAuth(_auth);
104
118
  }
@@ -139,8 +153,8 @@ class HTTP {
139
153
  } : {}),
140
154
  ...headers
141
155
  };
142
- Object.entries(combinedHeaders).forEach(_ref => {
143
- let [key, header] = _ref;
156
+ Object.entries(combinedHeaders).forEach(_ref2 => {
157
+ let [key, header] = _ref2;
144
158
  if (header === null || header === undefined) {
145
159
  Reflect.deleteProperty(combinedHeaders, key);
146
160
  }
@@ -11,6 +11,9 @@ declare enum Size {
11
11
  L = "L",
12
12
  FULL = "FULL"
13
13
  }
14
+ export interface InputTranslations {
15
+ clear: string;
16
+ }
14
17
  export interface InputBaseProps {
15
18
  size: Size;
16
19
  enableShortcuts: boolean | string[];
@@ -25,6 +28,7 @@ export interface InputBaseProps {
25
28
  icon?: string | ComponentType | null | undefined;
26
29
  height?: ControlsHeight | undefined;
27
30
  afterInput?: ReactNode;
31
+ translations: InputTranslations;
28
32
  }
29
33
  type Override<D, S> = Omit<D, keyof S> & S;
30
34
  export type InputSpecificProps = Override<InputHTMLAttributes<HTMLInputElement>, InputBaseProps> & {
@@ -42,6 +46,9 @@ export declare class Input extends PureComponent<InputProps> {
42
46
  onChange: typeof noop;
43
47
  inputRef: typeof noop;
44
48
  enableShortcuts: string[];
49
+ translations: {
50
+ clear: string;
51
+ };
45
52
  };
46
53
  state: {
47
54
  empty: boolean;
@@ -115,6 +115,7 @@ class Input extends PureComponent {
115
115
  id,
116
116
  placeholder,
117
117
  icon,
118
+ translations,
118
119
  height = this.context,
119
120
  afterInput,
120
121
  ...restProps
@@ -163,7 +164,7 @@ class Input extends PureComponent {
163
164
  }, commonProps, restProps)) : /*#__PURE__*/React.createElement("input", _extends({
164
165
  onChange: this.handleInputChange
165
166
  }, commonProps, restProps)), clearable && !disabled && /*#__PURE__*/React.createElement(Button, {
166
- title: "Clear input",
167
+ title: translations.clear,
167
168
  "data-test": "ring-input-clear",
168
169
  className: modules_88cfaf40.clear,
169
170
  icon: closeIcon,
@@ -177,7 +178,10 @@ _defineProperty(Input, "defaultProps", {
177
178
  size: Size.M,
178
179
  onChange: noop,
179
180
  inputRef: noop,
180
- enableShortcuts: ['esc']
181
+ enableShortcuts: ['esc'],
182
+ translations: {
183
+ clear: 'Clear input'
184
+ }
181
185
  });
182
186
  _defineProperty(Input, "contextType", ControlsHeightContext);
183
187
  Input.propTypes = {
@@ -197,6 +201,7 @@ Input.propTypes = {
197
201
  disabled: PropTypes.bool,
198
202
  id: PropTypes.string,
199
203
  placeholder: PropTypes.string,
204
+ translations: PropTypes.object,
200
205
  icon: PropTypes.oneOfType([PropTypes.string, PropTypes.elementType])
201
206
  };
202
207