@jetbrains/ring-ui 5.0.51 → 5.0.53
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.
- package/components/date-picker/months.js +3 -4
- package/components/editable-heading/editable-heading.d.ts +1 -1
- package/components/editable-heading/editable-heading.js +22 -13
- package/components/header/services.js +2 -2
- package/components/input/input-label.d.ts +10 -0
- package/components/input/input-label.js +18 -0
- package/components/input/input.js +2 -3
- package/components/select/select.d.ts +1 -0
- package/components/select/select.js +12 -3
- package/components/shortcuts/shortcuts.js +5 -1
- package/dist/date-picker/date-input.js +1 -0
- package/dist/date-picker/date-picker.js +1 -1
- package/dist/date-picker/date-popup.js +2 -2
- package/dist/date-picker/months.js +4 -7
- package/dist/editable-heading/editable-heading.d.ts +1 -1
- package/dist/editable-heading/editable-heading.js +28 -16
- package/dist/header/services.js +2 -2
- package/dist/input/input-label.d.ts +10 -0
- package/dist/input/input-label.js +27 -0
- package/dist/input/input.js +5 -5
- package/dist/pager/pager.js +1 -0
- package/dist/pager-ng/pager-ng.js +1 -0
- package/dist/query-assist/query-assist.js +1 -0
- package/dist/query-assist-ng/query-assist-ng.js +1 -0
- package/dist/select/select.d.ts +1 -0
- package/dist/select/select.js +22 -7
- package/dist/select/select__filter.js +1 -0
- package/dist/select/select__popup.js +1 -0
- package/dist/select-ng/select-ng.js +1 -0
- package/dist/select-ng/select-ng__lazy.js +1 -0
- package/dist/shortcuts/shortcuts.js +6 -1
- package/dist/table-legacy-ng/table-legacy-ng.js +1 -0
- package/dist/table-legacy-ng/table-legacy-ng__pager.js +1 -0
- package/dist/tags-input/tags-input.js +1 -0
- package/dist/tags-input-ng/tags-input-ng.js +1 -0
- package/package.json +2 -2
|
@@ -3,8 +3,6 @@ import PropTypes from 'prop-types';
|
|
|
3
3
|
import addMonths from 'date-fns/addMonths';
|
|
4
4
|
import getDay from 'date-fns/getDay';
|
|
5
5
|
import getDaysInMonth from 'date-fns/getDaysInMonth';
|
|
6
|
-
import set from 'date-fns/set';
|
|
7
|
-
import startOfHour from 'date-fns/startOfHour';
|
|
8
6
|
import startOfMonth from 'date-fns/startOfMonth';
|
|
9
7
|
import subMonths from 'date-fns/subMonths';
|
|
10
8
|
import endOfMonth from 'date-fns/endOfMonth';
|
|
@@ -37,8 +35,9 @@ const scrollSchedule = scheduleRAF();
|
|
|
37
35
|
let dy = 0;
|
|
38
36
|
export default function Months(props) {
|
|
39
37
|
const { scrollDate } = props;
|
|
40
|
-
|
|
41
|
-
|
|
38
|
+
const monthDate = scrollDate instanceof Date ? scrollDate : new Date(scrollDate);
|
|
39
|
+
// Creating midnight of the first day of the month in UTC to prevent the impact of user timezone
|
|
40
|
+
const monthStart = new Date(Date.UTC(monthDate.getFullYear(), monthDate.getMonth(), 1));
|
|
42
41
|
let month = subMonths(monthStart, MONTHSBACK);
|
|
43
42
|
const months = [month];
|
|
44
43
|
for (let i = 0; i < MONTHSBACK * DOUBLE; i++) {
|
|
@@ -2,6 +2,7 @@ import React, { InputHTMLAttributes } from 'react';
|
|
|
2
2
|
import { Levels } from '../heading/heading';
|
|
3
3
|
import { Size } from '../input/input';
|
|
4
4
|
export { Levels };
|
|
5
|
+
export { Size };
|
|
5
6
|
export declare type EditableHeadingProps = Omit<InputHTMLAttributes<HTMLInputElement>, 'value' | 'size'> & {
|
|
6
7
|
level?: Levels;
|
|
7
8
|
headingClassName?: string | null;
|
|
@@ -19,7 +20,6 @@ export declare type EditableHeadingProps = Omit<InputHTMLAttributes<HTMLInputEle
|
|
|
19
20
|
error?: string;
|
|
20
21
|
renderMenu?: () => React.ReactNode;
|
|
21
22
|
};
|
|
22
|
-
export { Size } from '../input/input';
|
|
23
23
|
export declare const EditableHeading: (props: EditableHeadingProps) => JSX.Element;
|
|
24
24
|
declare const _default: React.MemoExoticComponent<(props: EditableHeadingProps) => JSX.Element>;
|
|
25
25
|
export default _default;
|
|
@@ -8,12 +8,20 @@ import getUID from '../global/get-uid';
|
|
|
8
8
|
import Shortcuts from '../shortcuts/shortcuts';
|
|
9
9
|
import styles from './editable-heading.css';
|
|
10
10
|
export { Levels };
|
|
11
|
+
export { Size };
|
|
11
12
|
function noop() { }
|
|
12
|
-
const shortcutsScope = getUID('ring-editable-heading-');
|
|
13
|
-
export { Size } from '../input/input';
|
|
14
13
|
export const EditableHeading = (props) => {
|
|
15
|
-
const { level = Levels.H1, className, headingClassName, inputClassName, isEditing, isSavingPossible, isSaving
|
|
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, renderMenu = () => null, ...restProps } = props;
|
|
15
|
+
const [shortcutsScope] = React.useState(getUID('ring-editable-heading-'));
|
|
16
|
+
const [isInFocus, setIsInFocus] = React.useState(false);
|
|
16
17
|
const hasError = error !== undefined;
|
|
18
|
+
const isSaveDisabled = !isSavingPossible || !children || children.trim() === '' || hasError || isSaving;
|
|
19
|
+
const isCancelDisabled = isSaving;
|
|
20
|
+
const isShortcutsDisabled = !isInFocus || isSaving;
|
|
21
|
+
const shortcutsMap = React.useMemo(() => ({
|
|
22
|
+
enter: isSaveDisabled ? noop : onSave,
|
|
23
|
+
esc: isCancelDisabled ? noop : onCancel
|
|
24
|
+
}), [isSaveDisabled, isCancelDisabled, onSave, onCancel]);
|
|
17
25
|
const classes = classNames(styles.editableHeading, className, {
|
|
18
26
|
[styles.fullSize]: size === Size.FULL,
|
|
19
27
|
[styles.isEditing]: isEditing,
|
|
@@ -22,26 +30,27 @@ export const EditableHeading = (props) => {
|
|
|
22
30
|
});
|
|
23
31
|
const headingClasses = classNames(styles.heading, headingClassName);
|
|
24
32
|
const inputClasses = classNames('ring-js-shortcuts', styles.input, inputStyles[`size${size}`], styles[`level${level}`], inputClassName);
|
|
25
|
-
const
|
|
26
|
-
if (disabled
|
|
33
|
+
const onHeadingClick = React.useCallback(() => {
|
|
34
|
+
if (disabled) {
|
|
27
35
|
return undefined;
|
|
28
36
|
}
|
|
29
37
|
return onEdit();
|
|
30
38
|
}, [disabled, onEdit]);
|
|
31
|
-
const
|
|
32
|
-
|
|
39
|
+
const onInputFocus = React.useCallback(() => {
|
|
40
|
+
setIsInFocus(true);
|
|
41
|
+
}, []);
|
|
42
|
+
const onInputBlur = React.useCallback(() => {
|
|
43
|
+
setIsInFocus(false);
|
|
44
|
+
}, []);
|
|
33
45
|
return (<>
|
|
34
46
|
<div className={classes}>
|
|
35
47
|
{!disabled && isEditing
|
|
36
48
|
? (<>
|
|
37
|
-
<Shortcuts map={{
|
|
38
|
-
enter: () => !isSaveDisabled && onSave(),
|
|
39
|
-
esc: () => !isCancelDisabled && onCancel()
|
|
40
|
-
}} scope={shortcutsScope} disabled={isSaving}/>
|
|
49
|
+
<Shortcuts map={shortcutsMap} scope={shortcutsScope} disabled={isShortcutsDisabled}/>
|
|
41
50
|
|
|
42
|
-
<input className={inputClasses} value={children} autoFocus={autoFocus} data-test={dataTest} disabled={isSaving} {...restProps}/>
|
|
51
|
+
<input className={inputClasses} value={children} autoFocus={autoFocus} data-test={dataTest} disabled={isSaving} onFocus={onInputFocus} onBlur={onInputBlur} {...restProps}/>
|
|
43
52
|
</>)
|
|
44
|
-
: (<Heading className={headingClasses} level={level} onClick={
|
|
53
|
+
: (<Heading className={headingClasses} level={level} onClick={onHeadingClick} data-test={dataTest}>{children}</Heading>)}
|
|
45
54
|
|
|
46
55
|
{!isEditing && (renderMenu())}
|
|
47
56
|
|
|
@@ -42,8 +42,8 @@ export default class Services extends PureComponent {
|
|
|
42
42
|
return (<TrayIcon {...props} loader={loading} active={loading} icon={servicesIcon} aria-label="Services"/>);
|
|
43
43
|
}
|
|
44
44
|
const sortedServices = [...services].sort(Services.sort);
|
|
45
|
-
const servicesWithIcons = sortedServices.filter(service => service.iconUrl);
|
|
46
|
-
const servicesWithOutIcons = sortedServices.filter(service => !service.iconUrl);
|
|
45
|
+
const servicesWithIcons = sortedServices.filter(service => service.iconUrl && service.homeUrl);
|
|
46
|
+
const servicesWithOutIcons = sortedServices.filter(service => !service.iconUrl && service.homeUrl);
|
|
47
47
|
const separatorIsRequired = servicesWithIcons.length !== 0 && servicesWithOutIcons.length !== 0;
|
|
48
48
|
return (<Dropdown {...props} anchor={makeAnchor(loading)} initShown={initShown}>
|
|
49
49
|
<Popup className={classNames(styles.services, { [darkStyles.dark]: theme === Theme.DARK })} top={-3}>
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { PureComponent, ReactNode } from 'react';
|
|
2
|
+
interface InputLabelProps {
|
|
3
|
+
htmlFor?: string;
|
|
4
|
+
disabled?: boolean;
|
|
5
|
+
label: ReactNode;
|
|
6
|
+
}
|
|
7
|
+
export declare class InputLabel extends PureComponent<InputLabelProps> {
|
|
8
|
+
render(): JSX.Element;
|
|
9
|
+
}
|
|
10
|
+
export default InputLabel;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import React, { PureComponent } from 'react';
|
|
2
|
+
import PropTypes from 'prop-types';
|
|
3
|
+
import classNames from 'classnames';
|
|
4
|
+
import styles from './input.css';
|
|
5
|
+
export class InputLabel extends PureComponent {
|
|
6
|
+
render() {
|
|
7
|
+
const { htmlFor, label, disabled } = this.props;
|
|
8
|
+
return (<label htmlFor={htmlFor} className={classNames(styles.label, {
|
|
9
|
+
[styles.disabledLabel]: disabled
|
|
10
|
+
})}>{label}</label>);
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
InputLabel.propTypes = {
|
|
14
|
+
label: PropTypes.node,
|
|
15
|
+
disabled: PropTypes.bool,
|
|
16
|
+
id: PropTypes.string
|
|
17
|
+
};
|
|
18
|
+
export default InputLabel;
|
|
@@ -9,6 +9,7 @@ import Icon from '../icon/icon';
|
|
|
9
9
|
import composeRefs from '../global/composeRefs';
|
|
10
10
|
import { ControlsHeightContext } from '../global/controls-height';
|
|
11
11
|
import styles from './input.css';
|
|
12
|
+
import { InputLabel } from './input-label';
|
|
12
13
|
function noop() { }
|
|
13
14
|
/**
|
|
14
15
|
* @name Input
|
|
@@ -117,9 +118,7 @@ export class Input extends PureComponent {
|
|
|
117
118
|
'data-enabled-shortcuts': Array.isArray(enableShortcuts) ? enableShortcuts.join(',') : null
|
|
118
119
|
};
|
|
119
120
|
return (<div className={classes} data-test="ring-input">
|
|
120
|
-
{label && (<
|
|
121
|
-
[styles.disabledLabel]: disabled
|
|
122
|
-
})}>{label}</label>)}
|
|
121
|
+
{label && (<InputLabel htmlFor={this.getId()} disabled={disabled} label={label}/>)}
|
|
123
122
|
<div className={styles.container}>
|
|
124
123
|
{icon && <Icon glyph={icon} className={styles.icon}/>}
|
|
125
124
|
{multiline
|
|
@@ -236,6 +236,7 @@ export default class Select<T = unknown> extends Component<SelectProps<T>, Selec
|
|
|
236
236
|
clear: (event?: Event | SyntheticEvent) => boolean;
|
|
237
237
|
_selectionIsEmpty(): boolean;
|
|
238
238
|
private _getLabel;
|
|
239
|
+
private _getPlaceholder;
|
|
239
240
|
_getSelectedString(): string | null;
|
|
240
241
|
private _getIcons;
|
|
241
242
|
private _getAvatar;
|
|
@@ -9,6 +9,7 @@ import Avatar, { Size as AvatarSize } from '../avatar/avatar';
|
|
|
9
9
|
import Popup from '../popup/popup';
|
|
10
10
|
import List, { ActiveItemContext } from '../list/list';
|
|
11
11
|
import Input, { Size } from '../input/input';
|
|
12
|
+
import InputLabel from '../input/input-label';
|
|
12
13
|
import Shortcuts from '../shortcuts/shortcuts';
|
|
13
14
|
import Button from '../button/button';
|
|
14
15
|
import dataTests from '../global/data-tests';
|
|
@@ -717,6 +718,12 @@ export default class Select extends Component {
|
|
|
717
718
|
_getLabel() {
|
|
718
719
|
return this.props.label ?? this.props.selectedLabel ?? 'Select an option';
|
|
719
720
|
}
|
|
721
|
+
_getPlaceholder() {
|
|
722
|
+
if (this._selectionIsEmpty()) {
|
|
723
|
+
return this.props.label ?? 'Select an option';
|
|
724
|
+
}
|
|
725
|
+
return this._getSelectedString();
|
|
726
|
+
}
|
|
720
727
|
_getSelectedString() {
|
|
721
728
|
if (Array.isArray(this.state.selected)) {
|
|
722
729
|
const labels = [];
|
|
@@ -767,6 +774,7 @@ export default class Select extends Component {
|
|
|
767
774
|
}
|
|
768
775
|
renderSelect(activeItemId) {
|
|
769
776
|
const dataTest = this.props['data-test'];
|
|
777
|
+
const { selectedLabel } = this.props;
|
|
770
778
|
const { shortcutsEnabled } = this.state;
|
|
771
779
|
const classes = classNames(styles.select, 'ring-js-shortcuts', this.props.className, styles[`height${this.props.height || this.context}`], {
|
|
772
780
|
[styles[`size${this.props.size}`]]: this.props.type !== Type.INLINE,
|
|
@@ -798,13 +806,14 @@ export default class Select extends Component {
|
|
|
798
806
|
</div>);
|
|
799
807
|
case Type.BUTTON:
|
|
800
808
|
return (<div ref={this.nodeRef} className={classNames(classes, styles.buttonMode)} data-test={dataTests('ring-select', dataTest)}>
|
|
809
|
+
{selectedLabel && (<InputLabel label={selectedLabel} disabled={this.props.disabled} htmlFor={this.props.id}/>)}
|
|
801
810
|
{shortcutsEnabled && (<Shortcuts map={this.getShortcutsMap()} scope={this.shortcutsScope}/>)}
|
|
802
811
|
<div className={styles.buttonContainer}>
|
|
803
812
|
<Button {...ariaProps} height={this.props.height} id={this.props.id} onClick={this._clickHandler} className={classNames(this.props.buttonClassName, styles.buttonValue, {
|
|
804
813
|
[styles.buttonValueOpen]: this.state.showPopup
|
|
805
814
|
})} disabled={this.props.disabled} style={style} data-test="ring-select__button ring-select__focus">
|
|
806
815
|
{this._getAvatar()}
|
|
807
|
-
{this.
|
|
816
|
+
{this._getPlaceholder()}
|
|
808
817
|
</Button>
|
|
809
818
|
{iconsNode}
|
|
810
819
|
</div>
|
|
@@ -814,7 +823,7 @@ export default class Select extends Component {
|
|
|
814
823
|
return (<div className={classes} ref={this.nodeRef} data-test={dataTests('ring-select', dataTest)}>
|
|
815
824
|
{shortcutsEnabled && (<Shortcuts map={this.getShortcutsMap()} scope={this.shortcutsScope}/>)}
|
|
816
825
|
<Anchor {...ariaProps} id={this.props.id} onClick={this._clickHandler} data-test="ring-select__focus" disabled={this.props.disabled} active={this.state.showPopup}>
|
|
817
|
-
{this.
|
|
826
|
+
{this._getPlaceholder()}
|
|
818
827
|
</Anchor>
|
|
819
828
|
{this._renderPopup()}
|
|
820
829
|
</div>);
|
|
@@ -832,7 +841,7 @@ export default class Select extends Component {
|
|
|
832
841
|
id: this.props.id,
|
|
833
842
|
onClick: this._clickHandler,
|
|
834
843
|
disabled: this.props.disabled,
|
|
835
|
-
children: this.
|
|
844
|
+
children: this._getPlaceholder(),
|
|
836
845
|
'data-test': 'ring-select_focus'
|
|
837
846
|
},
|
|
838
847
|
popup: this._renderPopup()
|
|
@@ -18,13 +18,17 @@ export default class Shortcuts extends PureComponent {
|
|
|
18
18
|
}
|
|
19
19
|
}
|
|
20
20
|
componentDidUpdate(prevProps) {
|
|
21
|
-
const { disabled } = this.props;
|
|
21
|
+
const { disabled, map } = this.props;
|
|
22
22
|
if (!prevProps.disabled && disabled) {
|
|
23
23
|
this.turnShorcutsOff();
|
|
24
24
|
}
|
|
25
25
|
if (prevProps.disabled && !disabled) {
|
|
26
26
|
this.turnShorcutsOn();
|
|
27
27
|
}
|
|
28
|
+
if (prevProps.map !== map) {
|
|
29
|
+
this.turnShorcutsOff();
|
|
30
|
+
this.turnShorcutsOn();
|
|
31
|
+
}
|
|
28
32
|
}
|
|
29
33
|
componentWillUnmount() {
|
|
30
34
|
if (!this.props.disabled) {
|
|
@@ -55,7 +55,6 @@ import './months.js';
|
|
|
55
55
|
import 'date-fns/addMonths';
|
|
56
56
|
import 'date-fns/getDay';
|
|
57
57
|
import 'date-fns/getDaysInMonth';
|
|
58
|
-
import 'date-fns/startOfHour';
|
|
59
58
|
import 'date-fns/startOfMonth';
|
|
60
59
|
import 'date-fns/subMonths';
|
|
61
60
|
import 'date-fns/endOfMonth';
|
|
@@ -83,6 +82,7 @@ import '@jetbrains/icons/close-12px';
|
|
|
83
82
|
import '../global/prop-types.js';
|
|
84
83
|
import '../global/composeRefs.js';
|
|
85
84
|
import '../_helpers/input.js';
|
|
85
|
+
import '../input/input-label.js';
|
|
86
86
|
|
|
87
87
|
const PopupComponent = _ref => {
|
|
88
88
|
let {
|
|
@@ -30,12 +30,11 @@ import '../_helpers/button__classes.js';
|
|
|
30
30
|
import '../global/get-uid.js';
|
|
31
31
|
import '../global/composeRefs.js';
|
|
32
32
|
import '../_helpers/input.js';
|
|
33
|
+
import '../input/input-label.js';
|
|
33
34
|
import 'date-fns/add';
|
|
34
35
|
import 'date-fns/addMonths';
|
|
35
36
|
import 'date-fns/getDay';
|
|
36
37
|
import 'date-fns/getDaysInMonth';
|
|
37
|
-
import 'date-fns/set';
|
|
38
|
-
import 'date-fns/startOfHour';
|
|
39
38
|
import 'date-fns/startOfMonth';
|
|
40
39
|
import 'date-fns/subMonths';
|
|
41
40
|
import 'date-fns/endOfMonth';
|
|
@@ -50,6 +49,7 @@ import 'date-fns/getDate';
|
|
|
50
49
|
import 'date-fns/isToday';
|
|
51
50
|
import './month-names.js';
|
|
52
51
|
import 'date-fns/isThisMonth';
|
|
52
|
+
import 'date-fns/set';
|
|
53
53
|
import 'date-fns/startOfYear';
|
|
54
54
|
import './month-slider.js';
|
|
55
55
|
import 'date-fns/addYears';
|
|
@@ -4,8 +4,6 @@ import PropTypes from 'prop-types';
|
|
|
4
4
|
import addMonths from 'date-fns/addMonths';
|
|
5
5
|
import getDay from 'date-fns/getDay';
|
|
6
6
|
import getDaysInMonth from 'date-fns/getDaysInMonth';
|
|
7
|
-
import set from 'date-fns/set';
|
|
8
|
-
import startOfHour from 'date-fns/startOfHour';
|
|
9
7
|
import startOfMonth from 'date-fns/startOfMonth';
|
|
10
8
|
import subMonths from 'date-fns/subMonths';
|
|
11
9
|
import endOfMonth from 'date-fns/endOfMonth';
|
|
@@ -27,6 +25,7 @@ import 'date-fns/isSameDay';
|
|
|
27
25
|
import 'date-fns/isToday';
|
|
28
26
|
import 'date-fns/startOfDay';
|
|
29
27
|
import 'date-fns/isThisMonth';
|
|
28
|
+
import 'date-fns/set';
|
|
30
29
|
import 'date-fns/startOfYear';
|
|
31
30
|
import './month-slider.js';
|
|
32
31
|
import 'date-fns/addYears';
|
|
@@ -62,11 +61,9 @@ function Months(props) {
|
|
|
62
61
|
const {
|
|
63
62
|
scrollDate
|
|
64
63
|
} = props;
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
hours: 1
|
|
69
|
-
}));
|
|
64
|
+
const monthDate = scrollDate instanceof Date ? scrollDate : new Date(scrollDate);
|
|
65
|
+
// Creating midnight of the first day of the month in UTC to prevent the impact of user timezone
|
|
66
|
+
const monthStart = new Date(Date.UTC(monthDate.getFullYear(), monthDate.getMonth(), 1));
|
|
70
67
|
let month = subMonths(monthStart, MONTHSBACK);
|
|
71
68
|
const months = [month];
|
|
72
69
|
for (let i = 0; i < MONTHSBACK * DOUBLE; i++) {
|
|
@@ -2,6 +2,7 @@ import React, { InputHTMLAttributes } from 'react';
|
|
|
2
2
|
import { Levels } from '../heading/heading';
|
|
3
3
|
import { Size } from '../input/input';
|
|
4
4
|
export { Levels };
|
|
5
|
+
export { Size };
|
|
5
6
|
export declare type EditableHeadingProps = Omit<InputHTMLAttributes<HTMLInputElement>, 'value' | 'size'> & {
|
|
6
7
|
level?: Levels;
|
|
7
8
|
headingClassName?: string | null;
|
|
@@ -19,7 +20,6 @@ export declare type EditableHeadingProps = Omit<InputHTMLAttributes<HTMLInputEle
|
|
|
19
20
|
error?: string;
|
|
20
21
|
renderMenu?: () => React.ReactNode;
|
|
21
22
|
};
|
|
22
|
-
export { Size } from '../input/input';
|
|
23
23
|
export declare const EditableHeading: (props: EditableHeadingProps) => JSX.Element;
|
|
24
24
|
declare const _default: React.MemoExoticComponent<(props: EditableHeadingProps) => JSX.Element>;
|
|
25
25
|
export default _default;
|
|
@@ -24,6 +24,7 @@ import '../_helpers/button__classes.js';
|
|
|
24
24
|
import '@jetbrains/icons/close-12px';
|
|
25
25
|
import '../global/prop-types.js';
|
|
26
26
|
import '../global/composeRefs.js';
|
|
27
|
+
import '../input/input-label.js';
|
|
27
28
|
import '../shortcuts/core.js';
|
|
28
29
|
import 'combokeys';
|
|
29
30
|
import '../global/sniffer.js';
|
|
@@ -32,20 +33,19 @@ import 'sniffr';
|
|
|
32
33
|
var modules_6e69b0fe = {"unit":"8px","editableHeading":"editableHeading_rui_0870","fullSize":"fullSize_rui_0870","isEditing":"isEditing_rui_0870","heading":"heading_rui_0870","disabled":"disabled_rui_0870","input":"input_rui_0870","error":"error_rui_0870","button":"button_rui_0870","errorText":"errorText_rui_0870","level1":"level1_rui_0870","level2":"level2_rui_0870","level3":"level3_rui_0870"};
|
|
33
34
|
|
|
34
35
|
function noop() {}
|
|
35
|
-
const shortcutsScope = getUID('ring-editable-heading-');
|
|
36
36
|
const EditableHeading = props => {
|
|
37
37
|
const {
|
|
38
38
|
level = Levels.H1,
|
|
39
39
|
className,
|
|
40
40
|
headingClassName,
|
|
41
41
|
inputClassName,
|
|
42
|
-
isEditing,
|
|
43
|
-
isSavingPossible,
|
|
44
|
-
isSaving,
|
|
45
42
|
children,
|
|
43
|
+
isEditing = false,
|
|
44
|
+
isSavingPossible = false,
|
|
45
|
+
isSaving = false,
|
|
46
46
|
embedded = false,
|
|
47
47
|
size = Size.L,
|
|
48
|
-
onEdit,
|
|
48
|
+
onEdit = noop,
|
|
49
49
|
onSave = noop,
|
|
50
50
|
onCancel = noop,
|
|
51
51
|
autoFocus = true,
|
|
@@ -55,7 +55,16 @@ const EditableHeading = props => {
|
|
|
55
55
|
renderMenu = () => null,
|
|
56
56
|
...restProps
|
|
57
57
|
} = props;
|
|
58
|
+
const [shortcutsScope] = React.useState(getUID('ring-editable-heading-'));
|
|
59
|
+
const [isInFocus, setIsInFocus] = React.useState(false);
|
|
58
60
|
const hasError = error !== undefined;
|
|
61
|
+
const isSaveDisabled = !isSavingPossible || !children || children.trim() === '' || hasError || isSaving;
|
|
62
|
+
const isCancelDisabled = isSaving;
|
|
63
|
+
const isShortcutsDisabled = !isInFocus || isSaving;
|
|
64
|
+
const shortcutsMap = React.useMemo(() => ({
|
|
65
|
+
enter: isSaveDisabled ? noop : onSave,
|
|
66
|
+
esc: isCancelDisabled ? noop : onCancel
|
|
67
|
+
}), [isSaveDisabled, isCancelDisabled, onSave, onCancel]);
|
|
59
68
|
const classes = classNames(modules_6e69b0fe.editableHeading, className, {
|
|
60
69
|
[modules_6e69b0fe.fullSize]: size === Size.FULL,
|
|
61
70
|
[modules_6e69b0fe.isEditing]: isEditing,
|
|
@@ -64,33 +73,36 @@ const EditableHeading = props => {
|
|
|
64
73
|
});
|
|
65
74
|
const headingClasses = classNames(modules_6e69b0fe.heading, headingClassName);
|
|
66
75
|
const inputClasses = classNames('ring-js-shortcuts', modules_6e69b0fe.input, modules_88cfaf40[`size${size}`], modules_6e69b0fe[`level${level}`], inputClassName);
|
|
67
|
-
const
|
|
68
|
-
if (disabled
|
|
76
|
+
const onHeadingClick = React.useCallback(() => {
|
|
77
|
+
if (disabled) {
|
|
69
78
|
return undefined;
|
|
70
79
|
}
|
|
71
80
|
return onEdit();
|
|
72
81
|
}, [disabled, onEdit]);
|
|
73
|
-
const
|
|
74
|
-
|
|
82
|
+
const onInputFocus = React.useCallback(() => {
|
|
83
|
+
setIsInFocus(true);
|
|
84
|
+
}, []);
|
|
85
|
+
const onInputBlur = React.useCallback(() => {
|
|
86
|
+
setIsInFocus(false);
|
|
87
|
+
}, []);
|
|
75
88
|
return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("div", {
|
|
76
89
|
className: classes
|
|
77
90
|
}, !disabled && isEditing ? /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(Shortcuts, {
|
|
78
|
-
map:
|
|
79
|
-
enter: () => !isSaveDisabled && onSave(),
|
|
80
|
-
esc: () => !isCancelDisabled && onCancel()
|
|
81
|
-
},
|
|
91
|
+
map: shortcutsMap,
|
|
82
92
|
scope: shortcutsScope,
|
|
83
|
-
disabled:
|
|
93
|
+
disabled: isShortcutsDisabled
|
|
84
94
|
}), /*#__PURE__*/React.createElement("input", _extends({
|
|
85
95
|
className: inputClasses,
|
|
86
96
|
value: children,
|
|
87
97
|
autoFocus: autoFocus,
|
|
88
98
|
"data-test": dataTest,
|
|
89
|
-
disabled: isSaving
|
|
99
|
+
disabled: isSaving,
|
|
100
|
+
onFocus: onInputFocus,
|
|
101
|
+
onBlur: onInputBlur
|
|
90
102
|
}, restProps))) : /*#__PURE__*/React.createElement(Heading, {
|
|
91
103
|
className: headingClasses,
|
|
92
104
|
level: level,
|
|
93
|
-
onClick:
|
|
105
|
+
onClick: onHeadingClick,
|
|
94
106
|
"data-test": dataTest
|
|
95
107
|
}, children), !isEditing && renderMenu(), isEditing && !embedded && /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(Button, {
|
|
96
108
|
className: modules_6e69b0fe.button,
|
package/dist/header/services.js
CHANGED
|
@@ -80,8 +80,8 @@ class Services extends PureComponent {
|
|
|
80
80
|
}));
|
|
81
81
|
}
|
|
82
82
|
const sortedServices = [...services].sort(Services.sort);
|
|
83
|
-
const servicesWithIcons = sortedServices.filter(service => service.iconUrl);
|
|
84
|
-
const servicesWithOutIcons = sortedServices.filter(service => !service.iconUrl);
|
|
83
|
+
const servicesWithIcons = sortedServices.filter(service => service.iconUrl && service.homeUrl);
|
|
84
|
+
const servicesWithOutIcons = sortedServices.filter(service => !service.iconUrl && service.homeUrl);
|
|
85
85
|
const separatorIsRequired = servicesWithIcons.length !== 0 && servicesWithOutIcons.length !== 0;
|
|
86
86
|
return /*#__PURE__*/React.createElement(Dropdown, _extends({}, props, {
|
|
87
87
|
anchor: makeAnchor(loading),
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { PureComponent, ReactNode } from 'react';
|
|
2
|
+
interface InputLabelProps {
|
|
3
|
+
htmlFor?: string;
|
|
4
|
+
disabled?: boolean;
|
|
5
|
+
label: ReactNode;
|
|
6
|
+
}
|
|
7
|
+
export declare class InputLabel extends PureComponent<InputLabelProps> {
|
|
8
|
+
render(): JSX.Element;
|
|
9
|
+
}
|
|
10
|
+
export default InputLabel;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import React, { PureComponent } from 'react';
|
|
2
|
+
import PropTypes from 'prop-types';
|
|
3
|
+
import classNames from 'classnames';
|
|
4
|
+
import { m as modules_88cfaf40 } from '../_helpers/input.js';
|
|
5
|
+
|
|
6
|
+
class InputLabel extends PureComponent {
|
|
7
|
+
render() {
|
|
8
|
+
const {
|
|
9
|
+
htmlFor,
|
|
10
|
+
label,
|
|
11
|
+
disabled
|
|
12
|
+
} = this.props;
|
|
13
|
+
return /*#__PURE__*/React.createElement("label", {
|
|
14
|
+
htmlFor: htmlFor,
|
|
15
|
+
className: classNames(modules_88cfaf40.label, {
|
|
16
|
+
[modules_88cfaf40.disabledLabel]: disabled
|
|
17
|
+
})
|
|
18
|
+
}, label);
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
InputLabel.propTypes = {
|
|
22
|
+
label: PropTypes.node,
|
|
23
|
+
disabled: PropTypes.bool,
|
|
24
|
+
id: PropTypes.string
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
export { InputLabel, InputLabel as default };
|
package/dist/input/input.js
CHANGED
|
@@ -10,6 +10,7 @@ import Icon from '../icon/icon.js';
|
|
|
10
10
|
import composeRefs from '../global/composeRefs.js';
|
|
11
11
|
import { ControlsHeightContext } from '../global/controls-height.js';
|
|
12
12
|
import { m as modules_88cfaf40 } from '../_helpers/input.js';
|
|
13
|
+
import { InputLabel } from './input-label.js';
|
|
13
14
|
import 'focus-visible';
|
|
14
15
|
import '@jetbrains/icons/chevron-10px';
|
|
15
16
|
import '../link/clickableLink.js';
|
|
@@ -150,12 +151,11 @@ class Input extends PureComponent {
|
|
|
150
151
|
return /*#__PURE__*/React.createElement("div", {
|
|
151
152
|
className: classes,
|
|
152
153
|
"data-test": "ring-input"
|
|
153
|
-
}, label && /*#__PURE__*/React.createElement(
|
|
154
|
+
}, label && /*#__PURE__*/React.createElement(InputLabel, {
|
|
154
155
|
htmlFor: this.getId(),
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
}, label), /*#__PURE__*/React.createElement("div", {
|
|
156
|
+
disabled: disabled,
|
|
157
|
+
label: label
|
|
158
|
+
}), /*#__PURE__*/React.createElement("div", {
|
|
159
159
|
className: modules_88cfaf40.container
|
|
160
160
|
}, icon && /*#__PURE__*/React.createElement(Icon, {
|
|
161
161
|
glyph: icon,
|
package/dist/pager/pager.js
CHANGED
|
@@ -72,6 +72,7 @@ import '../input/input.js';
|
|
|
72
72
|
import '../global/prop-types.js';
|
|
73
73
|
import '../global/composeRefs.js';
|
|
74
74
|
import '../_helpers/input.js';
|
|
75
|
+
import '../input/input-label.js';
|
|
75
76
|
import '../global/rerender-hoc.js';
|
|
76
77
|
import '../global/react-render-adapter.js';
|
|
77
78
|
import '../global/fuzzy-highlight.js';
|
|
@@ -78,6 +78,7 @@ import '../input/input.js';
|
|
|
78
78
|
import '../global/prop-types.js';
|
|
79
79
|
import '../global/composeRefs.js';
|
|
80
80
|
import '../_helpers/input.js';
|
|
81
|
+
import '../input/input-label.js';
|
|
81
82
|
import '../global/rerender-hoc.js';
|
|
82
83
|
import '../global/fuzzy-highlight.js';
|
|
83
84
|
import '../select/select__popup.js';
|
|
@@ -71,6 +71,7 @@ import '../global/composeRefs.js';
|
|
|
71
71
|
import '@jetbrains/icons/chevron-10px';
|
|
72
72
|
import '../_helpers/button__classes.js';
|
|
73
73
|
import '../global/prop-types.js';
|
|
74
|
+
import '../input/input-label.js';
|
|
74
75
|
|
|
75
76
|
const POPUP_COMPENSATION = PopupMenu.ListProps.Dimension.ITEM_PADDING + PopupMenu.PopupProps.Dimension.BORDER_WIDTH;
|
|
76
77
|
const ngModelStateField = 'query';
|
|
@@ -75,6 +75,7 @@ import '../_helpers/button__classes.js';
|
|
|
75
75
|
import '../input/input.js';
|
|
76
76
|
import '../global/prop-types.js';
|
|
77
77
|
import '../_helpers/input.js';
|
|
78
|
+
import '../input/input-label.js';
|
|
78
79
|
import '../_helpers/query-assist__suggestions.js';
|
|
79
80
|
|
|
80
81
|
var queryAssistNg = angularComponentFactory(QueryAssist, 'QueryAssist').name;
|
package/dist/select/select.d.ts
CHANGED
|
@@ -236,6 +236,7 @@ export default class Select<T = unknown> extends Component<SelectProps<T>, Selec
|
|
|
236
236
|
clear: (event?: Event | SyntheticEvent) => boolean;
|
|
237
237
|
_selectionIsEmpty(): boolean;
|
|
238
238
|
private _getLabel;
|
|
239
|
+
private _getPlaceholder;
|
|
239
240
|
_getSelectedString(): string | null;
|
|
240
241
|
private _getIcons;
|
|
241
242
|
private _getAvatar;
|
package/dist/select/select.js
CHANGED
|
@@ -10,6 +10,7 @@ import Avatar, { Size as Size$1 } from '../avatar/avatar.js';
|
|
|
10
10
|
import Popup from '../popup/popup.js';
|
|
11
11
|
import List, { ActiveItemContext } from '../list/list.js';
|
|
12
12
|
import { Size, Input } from '../input/input.js';
|
|
13
|
+
import { InputLabel } from '../input/input-label.js';
|
|
13
14
|
import Shortcuts from '../shortcuts/shortcuts.js';
|
|
14
15
|
import { Button } from '../button/button.js';
|
|
15
16
|
import joinDataTestAttributes from '../global/data-tests.js';
|
|
@@ -830,6 +831,13 @@ class Select extends Component {
|
|
|
830
831
|
var _ref2, _this$props$label;
|
|
831
832
|
return (_ref2 = (_this$props$label = this.props.label) !== null && _this$props$label !== void 0 ? _this$props$label : this.props.selectedLabel) !== null && _ref2 !== void 0 ? _ref2 : 'Select an option';
|
|
832
833
|
}
|
|
834
|
+
_getPlaceholder() {
|
|
835
|
+
if (this._selectionIsEmpty()) {
|
|
836
|
+
var _this$props$label2;
|
|
837
|
+
return (_this$props$label2 = this.props.label) !== null && _this$props$label2 !== void 0 ? _this$props$label2 : 'Select an option';
|
|
838
|
+
}
|
|
839
|
+
return this._getSelectedString();
|
|
840
|
+
}
|
|
833
841
|
_getSelectedString() {
|
|
834
842
|
if (Array.isArray(this.state.selected)) {
|
|
835
843
|
const labels = [];
|
|
@@ -911,8 +919,11 @@ class Select extends Component {
|
|
|
911
919
|
};
|
|
912
920
|
}
|
|
913
921
|
renderSelect(activeItemId) {
|
|
914
|
-
var _this$props$
|
|
922
|
+
var _this$props$label3, _this$props$label4, _this$_popup5, _this$_popup5$list;
|
|
915
923
|
const dataTest = this.props['data-test'];
|
|
924
|
+
const {
|
|
925
|
+
selectedLabel
|
|
926
|
+
} = this.props;
|
|
916
927
|
const {
|
|
917
928
|
shortcutsEnabled
|
|
918
929
|
} = this.state;
|
|
@@ -928,9 +939,9 @@ class Select extends Component {
|
|
|
928
939
|
const ariaProps = this.state.showPopup ? {
|
|
929
940
|
'aria-owns': this.listId,
|
|
930
941
|
'aria-activedescendant': activeItemId,
|
|
931
|
-
'aria-label': (_this$props$label2 = this.props.label) !== null && _this$props$label2 !== void 0 ? _this$props$label2 : undefined
|
|
932
|
-
} : {
|
|
933
942
|
'aria-label': (_this$props$label3 = this.props.label) !== null && _this$props$label3 !== void 0 ? _this$props$label3 : undefined
|
|
943
|
+
} : {
|
|
944
|
+
'aria-label': (_this$props$label4 = this.props.label) !== null && _this$props$label4 !== void 0 ? _this$props$label4 : undefined
|
|
934
945
|
};
|
|
935
946
|
switch (this.props.type) {
|
|
936
947
|
case Type.INPUT_WITHOUT_CONTROLS:
|
|
@@ -971,7 +982,11 @@ class Select extends Component {
|
|
|
971
982
|
ref: this.nodeRef,
|
|
972
983
|
className: classNames(classes, modules_9d0de074.buttonMode),
|
|
973
984
|
"data-test": joinDataTestAttributes('ring-select', dataTest)
|
|
974
|
-
},
|
|
985
|
+
}, selectedLabel && /*#__PURE__*/React.createElement(InputLabel, {
|
|
986
|
+
label: selectedLabel,
|
|
987
|
+
disabled: this.props.disabled,
|
|
988
|
+
htmlFor: this.props.id
|
|
989
|
+
}), shortcutsEnabled && /*#__PURE__*/React.createElement(Shortcuts, {
|
|
975
990
|
map: this.getShortcutsMap(),
|
|
976
991
|
scope: this.shortcutsScope
|
|
977
992
|
}), /*#__PURE__*/React.createElement("div", {
|
|
@@ -986,7 +1001,7 @@ class Select extends Component {
|
|
|
986
1001
|
disabled: this.props.disabled,
|
|
987
1002
|
style: style,
|
|
988
1003
|
"data-test": "ring-select__button ring-select__focus"
|
|
989
|
-
}), this._getAvatar(), this.
|
|
1004
|
+
}), this._getAvatar(), this._getPlaceholder()), iconsNode), this._renderPopup());
|
|
990
1005
|
case Type.INLINE:
|
|
991
1006
|
return /*#__PURE__*/React.createElement("div", {
|
|
992
1007
|
className: classes,
|
|
@@ -1001,7 +1016,7 @@ class Select extends Component {
|
|
|
1001
1016
|
"data-test": "ring-select__focus",
|
|
1002
1017
|
disabled: this.props.disabled,
|
|
1003
1018
|
active: this.state.showPopup
|
|
1004
|
-
}), this.
|
|
1019
|
+
}), this._getPlaceholder()), this._renderPopup());
|
|
1005
1020
|
default:
|
|
1006
1021
|
if (this.props.customAnchor) {
|
|
1007
1022
|
return /*#__PURE__*/React.createElement(Fragment, null, shortcutsEnabled && /*#__PURE__*/React.createElement(Shortcuts, {
|
|
@@ -1017,7 +1032,7 @@ class Select extends Component {
|
|
|
1017
1032
|
id: this.props.id,
|
|
1018
1033
|
onClick: this._clickHandler,
|
|
1019
1034
|
disabled: this.props.disabled,
|
|
1020
|
-
children: this.
|
|
1035
|
+
children: this._getPlaceholder(),
|
|
1021
1036
|
'data-test': 'ring-select_focus'
|
|
1022
1037
|
},
|
|
1023
1038
|
popup: this._renderPopup()
|
|
@@ -23,6 +23,7 @@ import '../_helpers/button__classes.js';
|
|
|
23
23
|
import '../global/get-uid.js';
|
|
24
24
|
import '../global/composeRefs.js';
|
|
25
25
|
import '../_helpers/input.js';
|
|
26
|
+
import '../input/input-label.js';
|
|
26
27
|
import 'sniffr';
|
|
27
28
|
import 'react-virtualized/dist/es/List';
|
|
28
29
|
import 'react-virtualized/dist/es/AutoSizer';
|
|
@@ -70,6 +70,7 @@ import '../input/input.js';
|
|
|
70
70
|
import '../global/prop-types.js';
|
|
71
71
|
import '../global/composeRefs.js';
|
|
72
72
|
import '../_helpers/input.js';
|
|
73
|
+
import '../input/input-label.js';
|
|
73
74
|
import '../global/rerender-hoc.js';
|
|
74
75
|
import '../global/fuzzy-highlight.js';
|
|
75
76
|
import '../select/select__popup.js';
|
|
@@ -67,6 +67,7 @@ import '../input/input.js';
|
|
|
67
67
|
import '../global/prop-types.js';
|
|
68
68
|
import '../global/composeRefs.js';
|
|
69
69
|
import '../_helpers/input.js';
|
|
70
|
+
import '../input/input-label.js';
|
|
70
71
|
import '../global/rerender-hoc.js';
|
|
71
72
|
import '../global/fuzzy-highlight.js';
|
|
72
73
|
import '../select/select__popup.js';
|
|
@@ -14,7 +14,8 @@ class Shortcuts extends PureComponent {
|
|
|
14
14
|
}
|
|
15
15
|
componentDidUpdate(prevProps) {
|
|
16
16
|
const {
|
|
17
|
-
disabled
|
|
17
|
+
disabled,
|
|
18
|
+
map
|
|
18
19
|
} = this.props;
|
|
19
20
|
if (!prevProps.disabled && disabled) {
|
|
20
21
|
this.turnShorcutsOff();
|
|
@@ -22,6 +23,10 @@ class Shortcuts extends PureComponent {
|
|
|
22
23
|
if (prevProps.disabled && !disabled) {
|
|
23
24
|
this.turnShorcutsOn();
|
|
24
25
|
}
|
|
26
|
+
if (prevProps.map !== map) {
|
|
27
|
+
this.turnShorcutsOff();
|
|
28
|
+
this.turnShorcutsOn();
|
|
29
|
+
}
|
|
25
30
|
}
|
|
26
31
|
componentWillUnmount() {
|
|
27
32
|
if (!this.props.disabled) {
|
|
@@ -90,6 +90,7 @@ import '../input/input.js';
|
|
|
90
90
|
import '../global/prop-types.js';
|
|
91
91
|
import '../global/composeRefs.js';
|
|
92
92
|
import '../_helpers/input.js';
|
|
93
|
+
import '../input/input-label.js';
|
|
93
94
|
import '../global/rerender-hoc.js';
|
|
94
95
|
import '../global/fuzzy-highlight.js';
|
|
95
96
|
import '../select/select__popup.js';
|
|
@@ -80,6 +80,7 @@ import '../input/input.js';
|
|
|
80
80
|
import '../global/prop-types.js';
|
|
81
81
|
import '../global/composeRefs.js';
|
|
82
82
|
import '../_helpers/input.js';
|
|
83
|
+
import '../input/input-label.js';
|
|
83
84
|
import '../global/rerender-hoc.js';
|
|
84
85
|
import '../global/fuzzy-highlight.js';
|
|
85
86
|
import '../select/select__popup.js';
|
|
@@ -66,6 +66,7 @@ import '../list/list__title.js';
|
|
|
66
66
|
import '../list/list__separator.js';
|
|
67
67
|
import '../list/list__hint.js';
|
|
68
68
|
import '../list/consts.js';
|
|
69
|
+
import '../input/input-label.js';
|
|
69
70
|
import '../global/fuzzy-highlight.js';
|
|
70
71
|
import '../select/select__popup.js';
|
|
71
72
|
import '@jetbrains/icons/search';
|
|
@@ -71,6 +71,7 @@ import '../input/input.js';
|
|
|
71
71
|
import '../global/prop-types.js';
|
|
72
72
|
import '../global/composeRefs.js';
|
|
73
73
|
import '../_helpers/input.js';
|
|
74
|
+
import '../input/input-label.js';
|
|
74
75
|
import '../global/rerender-hoc.js';
|
|
75
76
|
import '../global/fuzzy-highlight.js';
|
|
76
77
|
import '../select/select__popup.js';
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jetbrains/ring-ui",
|
|
3
|
-
"version": "5.0.
|
|
3
|
+
"version": "5.0.53",
|
|
4
4
|
"description": "JetBrains UI library",
|
|
5
5
|
"author": "JetBrains",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -259,5 +259,5 @@
|
|
|
259
259
|
"node": ">=14.0",
|
|
260
260
|
"npm": ">=6.0.0"
|
|
261
261
|
},
|
|
262
|
-
"gitHead": "
|
|
262
|
+
"gitHead": "21c1f2143dec4335b5094f69720307af583d39cf"
|
|
263
263
|
}
|