"react-modal": "3.14.3",
"react-redux": "5.1.1",
"react-router": "3.2.6",
- "react-select": "1.2.1",
+ "react-select": "4.3.1",
+ "react-select-legacy": "npm:react-select@1.2.1",
"react-virtualized": "9.21.2",
"redux": "4.0.5",
"redux-thunk": "2.3.0",
"@types/react-modal": "3.12.1",
"@types/react-redux": "6.0.6",
"@types/react-router": "3.0.20",
- "@types/react-select": "1.2.6",
+ "@types/react-select": "4.0.16",
+ "@types/react-select-legacy": "npm:@types/react-select@1.2.6",
"@types/react-virtualized": "9.21.0",
"@types/sanitize-html": "1.22.0",
"@types/valid-url": "1.0.2",
import ReloadButton from '../../../components/controls/ReloadButton';
import SearchBox from '../../../components/controls/SearchBox';
import SearchSelect from '../../../components/controls/SearchSelect';
-import Select from '../../../components/controls/Select';
+import SelectLegacy from '../../../components/controls/SelectLegacy';
import SelectList, { SelectListFilter } from '../../../components/controls/SelectList';
import SimpleModal from '../../../components/controls/SimpleModal';
import Tooltip from '../../../components/controls/Tooltip';
SearchBox,
SearchSelect,
SecurityHotspotIcon,
- Select,
+ SelectLegacy,
SelectList,
SelectListFilter,
SimpleModal,
import classNames from 'classnames';
import * as React from 'react';
import { fetchWebApi } from '../../../../../../api/web-api';
-import Select from '../../../../../../components/controls/Select';
+import SelectLegacy from '../../../../../../components/controls/SelectLegacy';
import { getLocalizedMetricName, translate } from '../../../../../../helpers/l10n';
import { BadgeFormats, BadgeOptions, BadgeType } from './utils';
<label className="spacer-right" htmlFor="badge-metric">
{translate('overview.badges.metric')}:
</label>
- <Select
+ <SelectLegacy
className="input-medium"
clearable={false}
menuStyle={{ maxHeight: 100 }}
htmlFor="badge-format">
{translate('format')}:
</label>
- <Select
+ <SelectLegacy
className="input-medium"
clearable={false}
name="badge-format"
overview.badges.metric
:
</label>
- <Select
+ <SelectLegacy
className="input-medium"
clearable={false}
menuStyle={
format
:
</label>
- <Select
+ <SelectLegacy
className="input-medium"
clearable={false}
name="badge-format"
format
:
</label>
- <Select
+ <SelectLegacy
className="input-medium"
clearable={false}
name="badge-format"
import * as React from 'react';
import { getBranches } from '../../api/branches';
import Checkbox from '../../components/controls/Checkbox';
-import Select from '../../components/controls/Select';
+import SelectLegacy from '../../components/controls/SelectLegacy';
import Tooltip from '../../components/controls/Tooltip';
import QualifierIcon from '../../components/icons/QualifierIcon';
import DeferredSpinner from '../../components/ui/DeferredSpinner';
</Tooltip>
</td>
<td>
- <Select
+ <SelectLegacy
className="width100"
clearable={false}
disabled={!checked}
</Tooltip>
</td>
<td>
- <Select
+ <SelectLegacy
className="width100"
clearable={false}
disabled={false}
*/
import * as React from 'react';
import { Button, ResetButtonLink } from '../../components/controls/buttons';
-import Select from '../../components/controls/Select';
+import SelectLegacy from '../../components/controls/SelectLegacy';
import { translate } from '../../helpers/l10n';
import { sanitizeStringRestricted } from '../../helpers/sanitize';
import { SettingCategoryDefinition } from '../../types/settings';
/>
)}
- <Select
+ <SelectLegacy
className="input-medium"
clearable={false}
name={definition.name}
import { shallow } from 'enzyme';
import * as React from 'react';
import { Button, ResetButtonLink } from '../../../components/controls/buttons';
-import Select from '../../../components/controls/Select';
+import SelectLegacy from '../../../components/controls/SelectLegacy';
import { mockDefinition } from '../../../helpers/mocks/settings';
import ReportFrequencyForm, { ReportFrequencyFormProps } from '../ReportFrequencyForm';
const onSave = jest.fn();
const wrapper = shallowRender({ onSave });
- wrapper.find(Select).simulate('change', { value: 'Daily' });
+ wrapper.find(SelectLegacy).simulate('change', { value: 'Daily' });
expect(wrapper.find('.button-success').exists()).toBe(true);
expect(wrapper.find(ResetButtonLink).exists()).toBe(true);
}
}
/>
- <Select
+ <SelectLegacy
className="input-medium"
clearable={false}
onChange={[Function]}
}
}
/>
- <Select
+ <SelectLegacy
className="input-medium"
clearable={false}
onChange={[Function]}
<h2>
application_settings.report.frequency
</h2>
- <Select
+ <SelectLegacy
className="input-medium"
clearable={false}
onChange={[Function]}
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
import * as React from 'react';
-import Select from '../../../components/controls/Select';
+import SelectLegacy from '../../../components/controls/SelectLegacy';
import { translate } from '../../../helpers/l10n';
import { TaskStatuses } from '../../../types/tasks';
import { STATUSES } from '../constants';
];
return (
- <Select
+ <SelectLegacy
className="input-medium"
clearable={false}
onChange={this.handleChange}
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
import * as React from 'react';
-import Select from '../../../components/controls/Select';
+import SelectLegacy from '../../../components/controls/SelectLegacy';
import { translate } from '../../../helpers/l10n';
import { ALL_TYPES } from '../constants';
];
return (
- <Select
+ <SelectLegacy
className="input-large"
clearable={false}
onChange={this.handleChange}
import { setWorkerCount } from '../../../api/ce';
import { ResetButtonLink, SubmitButton } from '../../../components/controls/buttons';
import Modal from '../../../components/controls/Modal';
-import Select from '../../../components/controls/Select';
+import SelectLegacy from '../../../components/controls/SelectLegacy';
import { Alert } from '../../../components/ui/Alert';
import { translate } from '../../../helpers/l10n';
</header>
<form onSubmit={this.handleSubmit}>
<div className="modal-body">
- <Select
+ <SelectLegacy
className="input-tiny spacer-top"
clearable={false}
onChange={this.handleWorkerCountChange}
import { shallow } from 'enzyme';
import * as React from 'react';
+import SelectLegacy from '../../../../components/controls/SelectLegacy';
import { submit } from '../../../../helpers/testUtils';
import WorkersForm from '../WorkersForm';
const wrapper = shallow(<WorkersForm onClose={jest.fn()} workerCount={1} />);
expect(wrapper).toMatchSnapshot();
- wrapper.find('Select').prop<Function>('onChange')({ value: 7 });
+ wrapper.find(SelectLegacy).prop<Function>('onChange')({ value: 7 });
wrapper.update();
expect(wrapper).toMatchSnapshot();
});
const onClose = jest.fn();
const wrapper = shallow(<WorkersForm onClose={onClose} workerCount={1} />);
(wrapper.instance() as WorkersForm).mounted = true;
- wrapper.find('Select').prop<Function>('onChange')({ value: 7 });
+ wrapper.find(SelectLegacy).prop<Function>('onChange')({ value: 7 });
wrapper.update();
submit(wrapper.find('form'));
<div
className="modal-body"
>
- <Select
+ <SelectLegacy
className="input-tiny spacer-top"
clearable={false}
onChange={[Function]}
<div
className="modal-body"
>
- <Select
+ <SelectLegacy
className="input-tiny spacer-top"
clearable={false}
onChange={[Function]}
import { activateRule, Profile } from '../../../api/quality-profiles';
import { ResetButtonLink, SubmitButton } from '../../../components/controls/buttons';
import Modal from '../../../components/controls/Modal';
-import Select from '../../../components/controls/Select';
+import SelectLegacy from '../../../components/controls/SelectLegacy';
import SeverityHelper from '../../../components/shared/SeverityHelper';
import { Alert } from '../../../components/ui/Alert';
import { SEVERITIES } from '../../../helpers/constants';
<div className="modal-field">
<label>{translate('coding_rules.quality_profile')}</label>
- <Select
+ <SelectLegacy
className="js-profile"
clearable={false}
disabled={submitting || profilesWithDepth.length === 1}
</div>
<div className="modal-field">
<label>{translate('severity')}</label>
- <Select
+ <SelectLegacy
className="js-severity"
clearable={false}
disabled={submitting}
import { bulkActivateRules, bulkDeactivateRules, Profile } from '../../../api/quality-profiles';
import { ResetButtonLink, SubmitButton } from '../../../components/controls/buttons';
import Modal from '../../../components/controls/Modal';
-import Select from '../../../components/controls/Select';
+import SelectLegacy from '../../../components/controls/SelectLegacy';
import { Alert } from '../../../components/ui/Alert';
import { translate, translateWithParameters } from '../../../helpers/l10n';
import { formatMeasure } from '../../../helpers/measures';
value: profile.key
}));
return (
- <Select
+ <SelectLegacy
multi={true}
onChange={this.handleProfileSelect}
options={options}
import FormattingTips from '../../../components/common/FormattingTips';
import { ResetButtonLink, SubmitButton } from '../../../components/controls/buttons';
import Modal from '../../../components/controls/Modal';
-import Select from '../../../components/controls/Select';
+import SelectLegacy from '../../../components/controls/SelectLegacy';
import SeverityHelper from '../../../components/shared/SeverityHelper';
import TypeHelper from '../../../components/shared/TypeHelper';
import { Alert } from '../../../components/ui/Alert';
renderTypeField = () => (
<div className="modal-field flex-1 spacer-right">
<label htmlFor="coding-rules-custom-rule-type">{translate('type')}</label>
- <Select
+ <SelectLegacy
clearable={false}
disabled={this.state.submitting}
id="coding-rules-custom-rule-type"
renderSeverityField = () => (
<div className="modal-field flex-1 spacer-right">
<label htmlFor="coding-rules-custom-rule-severity">{translate('severity')}</label>
- <Select
+ <SelectLegacy
clearable={false}
disabled={this.state.submitting}
id="coding-rules-custom-rule-severity"
<label htmlFor="coding-rules-custom-rule-status">
{translate('coding_rules.filters.status')}
</label>
- <Select
+ <SelectLegacy
clearable={false}
disabled={this.state.submitting}
id="coding-rules-custom-rule-status"
<label>
coding_rules.quality_profile
</label>
- <Select
+ <SelectLegacy
className="js-profile"
clearable={false}
disabled={false}
<label>
severity
</label>
- <Select
+ <SelectLegacy
className="js-severity"
clearable={false}
disabled={false}
<label>
coding_rules.quality_profile
</label>
- <Select
+ <SelectLegacy
className="js-profile"
clearable={false}
disabled={false}
<label>
severity
</label>
- <Select
+ <SelectLegacy
className="js-severity"
clearable={false}
disabled={false}
<label>
coding_rules.quality_profile
</label>
- <Select
+ <SelectLegacy
className="js-profile"
clearable={false}
disabled={true}
<label>
severity
</label>
- <Select
+ <SelectLegacy
className="js-severity"
clearable={false}
disabled={true}
<label>
coding_rules.quality_profile
</label>
- <Select
+ <SelectLegacy
className="js-profile"
clearable={false}
disabled={false}
<label>
severity
</label>
- <Select
+ <SelectLegacy
className="js-severity"
clearable={false}
disabled={false}
<label>
coding_rules.quality_profile
</label>
- <Select
+ <SelectLegacy
className="js-profile"
clearable={false}
disabled={true}
<label>
severity
</label>
- <Select
+ <SelectLegacy
className="js-severity"
clearable={false}
disabled={false}
coding_rules.activate_in
</label>
</h3>
- <Select
+ <SelectLegacy
multi={true}
onChange={[Function]}
options={Array []}
>
type
</label>
- <Select
+ <SelectLegacy
clearable={false}
disabled={false}
id="coding-rules-custom-rule-type"
>
severity
</label>
- <Select
+ <SelectLegacy
clearable={false}
disabled={false}
id="coding-rules-custom-rule-severity"
>
coding_rules.filters.status
</label>
- <Select
+ <SelectLegacy
clearable={false}
disabled={false}
id="coding-rules-custom-rule-status"
>
type
</label>
- <Select
+ <SelectLegacy
clearable={false}
disabled={false}
id="coding-rules-custom-rule-type"
>
severity
</label>
- <Select
+ <SelectLegacy
clearable={false}
disabled={false}
id="coding-rules-custom-rule-severity"
>
coding_rules.filters.status
</label>
- <Select
+ <SelectLegacy
clearable={false}
disabled={false}
id="coding-rules-custom-rule-status"
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
import * as React from 'react';
-import Select from '../../../components/controls/Select';
+import SelectLegacy from '../../../components/controls/SelectLegacy';
import ListIcon from '../../../components/icons/ListIcon';
import TreeIcon from '../../../components/icons/TreeIcon';
import TreemapIcon from '../../../components/icons/TreemapIcon';
render() {
return (
- <Select
+ <SelectLegacy
autoBlur={true}
className={this.props.className}
clearable={false}
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`should render correctly: has no list 1`] = `
-<Select
+<SelectLegacy
autoBlur={true}
clearable={false}
onChange={[Function]}
`;
exports[`should render correctly: has no tree 1`] = `
-<Select
+<SelectLegacy
autoBlur={true}
clearable={false}
onChange={[Function]}
`;
exports[`should render correctly: has no treemap 1`] = `
-<Select
+<SelectLegacy
autoBlur={true}
clearable={false}
onChange={[Function]}
import Modal from '../../../components/controls/Modal';
import Radio from '../../../components/controls/Radio';
import SearchSelect from '../../../components/controls/SearchSelect';
-import Select from '../../../components/controls/Select';
+import SelectLegacy from '../../../components/controls/SelectLegacy';
import Tooltip from '../../../components/controls/Tooltip';
import IssueTypeIcon from '../../../components/icons/IssueTypeIcon';
import SeverityHelper from '../../../components/shared/SeverityHelper';
);
const input = (
- <Select
+ <SelectLegacy
className="input-super-large"
clearable={true}
onChange={this.handleSelectFieldChange('type')}
}));
const input = (
- <Select
+ <SelectLegacy
className="input-super-large"
clearable={true}
onChange={this.handleSelectFieldChange('severity')}
import * as React from 'react';
import { searchIssueTags } from '../../../../api/issues';
import { SubmitButton } from '../../../../components/controls/buttons';
-import Select from '../../../../components/controls/Select';
+import SelectLegacy from '../../../../components/controls/SelectLegacy';
import { mockIssue } from '../../../../helpers/testMocks';
import { change, waitAndUpdate } from '../../../../helpers/testUtils';
import BulkChangeModal, { MAX_PAGE_SIZE } from '../BulkChangeModal';
expect(wrapper.find(SubmitButton).props().disabled).toBe(true);
const { onChange } = wrapper
- .find(Select)
+ .find(SelectLegacy)
.at(0)
.props();
if (!onChange) {
import * as React from 'react';
import { applyTemplateToProject, getPermissionTemplates } from '../../../../api/permissions';
import { ResetButtonLink, SubmitButton } from '../../../../components/controls/buttons';
-import Select from '../../../../components/controls/Select';
+import SelectLegacy from '../../../../components/controls/SelectLegacy';
import SimpleModal from '../../../../components/controls/SimpleModal';
import { Alert } from '../../../../components/ui/Alert';
import DeferredSpinner from '../../../../components/ui/DeferredSpinner';
<MandatoryFieldMarker />
</label>
{this.state.permissionTemplates && (
- <Select
+ <SelectLegacy
clearable={false}
id="project-permissions-template"
onChange={this.handlePermissionTemplateChange}
template
<MandatoryFieldMarker />
</label>
- <Select
+ <SelectLegacy
clearable={false}
id="project-permissions-template"
onChange={[Function]}
*/
import classNames from 'classnames';
import * as React from 'react';
-import Select from '../../../components/controls/Select';
+import SelectLegacy from '../../../components/controls/SelectLegacy';
import { translate } from '../../../helpers/l10n';
import { APPLICATION_EVENT_TYPES, EVENT_TYPES, Query } from '../utils';
import ProjectActivityDateInput from './ProjectActivityDateInput';
return (
<header className="page-header">
{!['VW', 'SVW'].includes(this.props.project.qualifier) && (
- <Select
+ <SelectLegacy
className={classNames('pull-left big-spacer-right', {
'input-medium': !isApp,
'input-large': isApp
<header
className="page-header"
>
- <Select
+ <SelectLegacy
className="pull-left big-spacer-right input-medium"
clearable={true}
onChange={[Function]}
import classNames from 'classnames';
import * as React from 'react';
import Radio from '../../../components/controls/Radio';
-import Select from '../../../components/controls/Select';
+import SelectLegacy from '../../../components/controls/SelectLegacy';
import Tooltip from '../../../components/controls/Tooltip';
import DateFormatter from '../../../components/intl/DateFormatter';
import TimeFormatter from '../../../components/intl/TimeFormatter';
<>
<div className="spacer-bottom">
{translate('baseline.analysis_from')}
- <Select
+ <SelectLegacy
autoBlur={true}
className="input-medium spacer-left"
clearable={false}
className="spacer-bottom"
>
baseline.analysis_from
- <Select
+ <SelectLegacy
autoBlur={true}
className="input-medium spacer-left"
clearable={false}
className="spacer-bottom"
>
baseline.analysis_from
- <Select
+ <SelectLegacy
autoBlur={true}
className="input-medium spacer-left"
clearable={false}
className="spacer-bottom"
>
baseline.analysis_from
- <Select
+ <SelectLegacy
autoBlur={true}
className="input-medium spacer-left"
clearable={false}
import { SubmitButton } from '../../components/controls/buttons';
import HelpTooltip from '../../components/controls/HelpTooltip';
import Radio from '../../components/controls/Radio';
-import Select from '../../components/controls/Select';
+import SelectLegacy from '../../components/controls/SelectLegacy';
import { Alert } from '../../components/ui/Alert';
import { translate } from '../../helpers/l10n';
import { isDiffMetric } from '../../helpers/measures';
{translate('project_quality_gate.always_use_specific')}
</div>
<div className="display-flex-center">
- <Select
+ <SelectLegacy
className="abs-width-300"
clearable={false}
disabled={submitting || usesDefault}
import { shallow } from 'enzyme';
import * as React from 'react';
import Radio from '../../../components/controls/Radio';
-import Select from '../../../components/controls/Select';
+import SelectLegacy from '../../../components/controls/SelectLegacy';
import { mockQualityGate } from '../../../helpers/mocks/quality-gates';
import { mockCondition } from '../../../helpers/testMocks';
import { submit } from '../../../helpers/testUtils';
it('should render select options correctly', () => {
return new Promise<void>(resolve => {
const wrapper = shallowRender();
- const render = wrapper.find(Select).props().optionRenderer;
+ const render = wrapper.find(SelectLegacy).props().optionRenderer;
expect(render).toBeDefined();
.onCheck('1');
expect(onSelect).toHaveBeenLastCalledWith('1');
- wrapper.find(Select).props().onChange!({ value: '2' });
+ wrapper.find(SelectLegacy).props().onChange!({ value: '2' });
expect(onSelect).toHaveBeenLastCalledWith('2');
});
<div
className="display-flex-center"
>
- <Select
+ <SelectLegacy
className="abs-width-300"
clearable={false}
disabled={true}
<div
className="display-flex-center"
>
- <Select
+ <SelectLegacy
className="abs-width-300"
clearable={false}
disabled={false}
<div
className="display-flex-center"
>
- <Select
+ <SelectLegacy
className="abs-width-300"
clearable={false}
disabled={false}
<div
className="display-flex-center"
>
- <Select
+ <SelectLegacy
className="abs-width-300"
clearable={false}
disabled={false}
<div
className="display-flex-center"
>
- <Select
+ <SelectLegacy
className="abs-width-300"
clearable={false}
disabled={true}
<div
className="display-flex-center"
>
- <Select
+ <SelectLegacy
className="abs-width-300"
clearable={false}
disabled={true}
import { Profile } from '../../../api/quality-profiles';
import DisableableSelectOption from '../../../components/common/DisableableSelectOption';
import { ButtonLink, SubmitButton } from '../../../components/controls/buttons';
-import Select from '../../../components/controls/Select';
+import SelectLegacy from '../../../components/controls/SelectLegacy';
import SimpleModal from '../../../components/controls/SimpleModal';
import { translate } from '../../../helpers/l10n';
import { getQualityProfileUrl } from '../../../helpers/urls';
{translate('project_quality_profile.add_language_modal.choose_language')}
</label>
</div>
- <Select
+ <SelectLegacy
className="abs-width-300"
clearable={false}
disabled={submitting}
{translate('project_quality_profile.add_language_modal.choose_profile')}
</label>
</div>
- <Select
+ <SelectLegacy
className="abs-width-300"
clearable={false}
disabled={submitting || !language}
import DisableableSelectOption from '../../../components/common/DisableableSelectOption';
import { ButtonLink, SubmitButton } from '../../../components/controls/buttons';
import Radio from '../../../components/controls/Radio';
-import Select from '../../../components/controls/Select';
+import SelectLegacy from '../../../components/controls/SelectLegacy';
import SimpleModal from '../../../components/controls/SimpleModal';
import { Alert } from '../../../components/ui/Alert';
import { translate, translateWithParameters } from '../../../helpers/l10n';
{translate('project_quality_profile.always_use_specific')}
</div>
<div className="display-flex-center">
- <Select
+ <SelectLegacy
className="abs-width-300"
clearable={false}
disabled={submitting || hasSelectedSysDefault}
*/
import { shallow, ShallowWrapper } from 'enzyme';
import * as React from 'react';
-import Select from '../../../../components/controls/Select';
+import SelectLegacy from '../../../../components/controls/SelectLegacy';
import SimpleModal from '../../../../components/controls/SimpleModal';
import { mockQualityProfile } from '../../../../helpers/testMocks';
import { AddLanguageModal, AddLanguageModalProps } from '../AddLanguageModal';
function getLanguageSelect(wrapper: ShallowWrapper) {
return diveIntoSimpleModal(wrapper)
- .find(Select)
+ .find(SelectLegacy)
.at(0);
}
function getProfileSelect(wrapper: ShallowWrapper) {
return diveIntoSimpleModal(wrapper)
- .find(Select)
+ .find(SelectLegacy)
.at(1);
}
import { shallow, ShallowWrapper } from 'enzyme';
import * as React from 'react';
import Radio from '../../../../components/controls/Radio';
-import Select from '../../../../components/controls/Select';
+import SelectLegacy from '../../../../components/controls/SelectLegacy';
import SimpleModal from '../../../../components/controls/SimpleModal';
import { mockComponent } from '../../../../helpers/mocks/component';
import { mockQualityProfile } from '../../../../helpers/testMocks';
it('should render select options correctly', () => {
return new Promise<void>((resolve, reject) => {
const wrapper = shallowRender();
- const render = wrapper.find(Select).props().optionRenderer;
+ const render = wrapper.find(SelectLegacy).props().optionRenderer;
if (!render) {
reject();
return;
expect(onSubmit).toHaveBeenLastCalledWith('foo', 'foo');
const change = diveIntoSimpleModal(wrapper)
- .find(Select)
+ .find(SelectLegacy)
.props().onChange;
expect(change).toBeDefined();
project_quality_profile.add_language_modal.choose_language
</label>
</div>
- <Select
+ <SelectLegacy
className="abs-width-300"
clearable={false}
disabled={false}
project_quality_profile.add_language_modal.choose_profile
</label>
</div>
- <Select
+ <SelectLegacy
className="abs-width-300"
clearable={false}
disabled={true}
<div
className="display-flex-center"
>
- <Select
+ <SelectLegacy
className="abs-width-300"
clearable={false}
disabled={false}
<div
className="display-flex-center"
>
- <Select
+ <SelectLegacy
className="abs-width-300"
clearable={false}
disabled={true}
<div
className="display-flex-center"
>
- <Select
+ <SelectLegacy
className="abs-width-300"
clearable={false}
disabled={false}
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
+import { omit } from 'lodash';
import * as React from 'react';
+import { components, OptionProps } from 'react-select';
import Select from '../../../components/controls/Select';
+import BubblesIcon from '../../../components/icons/BubblesIcon';
+import ListIcon from '../../../components/icons/ListIcon';
import { translate } from '../../../helpers/l10n';
import { VIEWS, VISUALIZATIONS } from '../utils';
-import PerspectiveSelectOption, { Option } from './PerspectiveSelectOption';
interface Props {
className?: string;
visualization?: string;
}
+export interface PerspectiveOption {
+ type: string;
+ value: string;
+ label: string;
+}
+
export default class PerspectiveSelect extends React.PureComponent<Props> {
- handleChange = (option: Option) => {
- if (option.type === 'view') {
+ handleChange = (option: PerspectiveOption) => {
+ if (option && option.type === 'view') {
this.props.onChange({ view: option.value });
- } else if (option.type === 'visualization') {
+ } else if (option && option.type === 'visualization') {
this.props.onChange({ view: 'visualizations', visualization: option.value });
}
};
+ perspectiveOptionRender = (props: OptionProps<PerspectiveOption, false>) => {
+ const { data, className } = props;
+ return (
+ <components.Option
+ {...omit(props, ['children', 'className'])}
+ className={`it__projects-perspective-option-${data.value} ${className}`}>
+ {data.type === 'view' && <ListIcon className="little-spacer-right" />}
+ {data.type === 'visualization' && <BubblesIcon className="little-spacer-right" />}
+ {props.children}
+ </components.Option>
+ );
+ };
+
render() {
const { view, visualization } = this.props;
const perspective = view === 'visualizations' ? visualization : view;
- const options = [
+ const options: PerspectiveOption[] = [
...VIEWS.map(opt => ({
type: 'view',
value: opt.value,
];
return (
<div className={this.props.className}>
- <label>{translate('projects.perspective')}:</label>
+ <label id="aria-projects-perspective">{translate('projects.perspective')}:</label>
<Select
- className="little-spacer-left input-medium"
- clearable={false}
+ aria-labelledby="aria-projects-perspective"
+ className="little-spacer-left input-medium it__projects-perspective-select"
+ isClearable={false}
onChange={this.handleChange}
- optionComponent={PerspectiveSelectOption}
+ components={{
+ Option: this.perspectiveOptionRender
+ }}
options={options}
- searchable={false}
- value={perspective}
+ isSearchable={false}
+ value={options.find(option => option.value === perspective)}
/>
</div>
);
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2021 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import * as React from 'react';
-import BubblesIcon from '../../../components/icons/BubblesIcon';
-import ListIcon from '../../../components/icons/ListIcon';
-
-export interface Option {
- label: string;
- type: string;
- value: string;
-}
-
-interface Props {
- option: Option;
- children?: React.ReactNode;
- className?: string;
- isFocused?: boolean;
- onFocus: (option: Option, event: React.SyntheticEvent<HTMLElement>) => void;
- onSelect: (option: Option, event: React.SyntheticEvent<HTMLElement>) => void;
-}
-
-export default class PerspectiveSelectOption extends React.PureComponent<Props> {
- handleMouseDown = (event: React.SyntheticEvent<HTMLElement>) => {
- event.preventDefault();
- event.stopPropagation();
- this.props.onSelect(this.props.option, event);
- };
-
- handleMouseEnter = (event: React.SyntheticEvent<HTMLElement>) => {
- this.props.onFocus(this.props.option, event);
- };
-
- handleMouseMove = (event: React.SyntheticEvent<HTMLElement>) => {
- if (this.props.isFocused) {
- return;
- }
- this.props.onFocus(this.props.option, event);
- };
-
- render() {
- const { option } = this.props;
- return (
- <div
- className={this.props.className}
- onMouseDown={this.handleMouseDown}
- onMouseEnter={this.handleMouseEnter}
- onMouseMove={this.handleMouseMove}
- title={option.label}>
- <div>
- {option.type === 'view' && <ListIcon className="little-spacer-right" />}
- {option.type === 'visualization' && <BubblesIcon className="little-spacer-right" />}
- {this.props.children}
- </div>
- </div>
- );
- }
-}
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-import { sortBy } from 'lodash';
+import { omit, sortBy } from 'lodash';
import * as React from 'react';
+import { components, OptionProps } from 'react-select';
import { colors } from '../../../app/theme';
import { ButtonIcon } from '../../../components/controls/buttons';
import Select from '../../../components/controls/Select';
import SortDescIcon from '../../../components/icons/SortDescIcon';
import { translate } from '../../../helpers/l10n';
import { parseSorting, SORTING_LEAK_METRICS, SORTING_METRICS } from '../utils';
-import ProjectsSortingSelectOption, { Option } from './ProjectsSortingSelectOption';
interface Props {
className?: string;
view: string;
}
+export interface Option {
+ label: string;
+ value: string;
+ className?: string;
+ short?: string;
+}
+
export default class ProjectsSortingSelect extends React.PureComponent<Props> {
- getSorting = () => parseSorting(this.props.selectedSort);
+ getSorting = () => {
+ const options = this.getOptions();
+ const { sortDesc, sortValue } = parseSorting(this.props.selectedSort);
+ return { sortDesc, value: options.find(o => o.value === sortValue) };
+ };
getOptions = () => {
const sortMetrics = this.props.view === 'leak' ? SORTING_LEAK_METRICS : SORTING_METRICS;
option => ({
value: option.value,
label: translate('projects.sorting', option.value),
- class: option.class
+ className: option.class
})
);
};
handleDescToggle = () => {
- const sorting = this.getSorting();
- this.props.onChange(sorting.sortValue, !sorting.sortDesc);
+ const { sortDesc, sortValue } = parseSorting(this.props.selectedSort);
+ this.props.onChange(sortValue, !sortDesc);
};
- handleSortChange = (option: Option) =>
+ handleSortChange = (option: Option) => {
this.props.onChange(option.value, this.getSorting().sortDesc);
+ };
+
+ projectsSortingSelectOption = (props: OptionProps<Option, false>) => {
+ const { data, children } = props;
+ return (
+ <components.Option
+ {...omit(props, ['children'])}
+ className={`it__project-sort-option-${data.value} ${data.className}`}>
+ {data.short ? data.short : children}
+ </components.Option>
+ );
+ };
render() {
- const { sortDesc, sortValue } = this.getSorting();
+ const { sortDesc, value } = this.getSorting();
return (
<div className={this.props.className}>
- <label>{translate('projects.sort_by')}:</label>
+ <label id="aria-projects-sort">{translate('projects.sort_by')}:</label>
<Select
- className="little-spacer-left input-medium"
- clearable={false}
+ aria-labelledby="aria-projects-sort"
+ className="little-spacer-left input-medium it__projects-sort-select"
+ isClearable={false}
onChange={this.handleSortChange}
- optionComponent={ProjectsSortingSelectOption}
+ components={{
+ Option: this.projectsSortingSelectOption
+ }}
options={this.getOptions()}
- searchable={false}
- value={sortValue}
+ isSearchable={false}
+ value={value}
/>
<Tooltip
overlay={
sortDesc ? translate('projects.sort_descending') : translate('projects.sort_ascending')
}>
<ButtonIcon
+ aria-label={
+ sortDesc
+ ? translate('projects.sort_descending')
+ : translate('projects.sort_ascending')
+ }
className="js-projects-sorting-invert spacer-left"
color={colors.gray60}
onClick={this.handleDescToggle}>
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2021 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import classNames from 'classnames';
-import * as React from 'react';
-
-export interface Option {
- label: string;
- value: string;
- class?: string;
- short?: string;
-}
-
-interface Props {
- option: Option;
- children?: React.ReactNode;
- className?: string;
- isFocused?: boolean;
- onFocus: (option: Option, event: React.SyntheticEvent<HTMLElement>) => void;
- onSelect: (option: Option, event: React.SyntheticEvent<HTMLElement>) => void;
-}
-
-export default class ProjectsSortingSelectOption extends React.PureComponent<Props> {
- handleMouseDown = (event: React.SyntheticEvent<HTMLElement>) => {
- event.preventDefault();
- event.stopPropagation();
- this.props.onSelect(this.props.option, event);
- };
-
- handleMouseEnter = (event: React.SyntheticEvent<HTMLElement>) => {
- this.props.onFocus(this.props.option, event);
- };
-
- handleMouseMove = (event: React.SyntheticEvent<HTMLElement>) => {
- if (this.props.isFocused) {
- return;
- }
- this.props.onFocus(this.props.option, event);
- };
-
- render() {
- const { option } = this.props;
- return (
- <div
- className={classNames(this.props.className, option.class)}
- onMouseDown={this.handleMouseDown}
- onMouseEnter={this.handleMouseEnter}
- onMouseMove={this.handleMouseMove}
- title={option.label}>
- {option.short ? option.short : this.props.children}
- </div>
- );
- }
-}
*/
import { shallow } from 'enzyme';
import * as React from 'react';
+import BubblesIcon from '../../../../components/icons/BubblesIcon';
+import ListIcon from '../../../../components/icons/ListIcon';
+import { mockReactSelectOptionProps } from '../../../../helpers/mocks/react-select';
import PerspectiveSelect from '../PerspectiveSelect';
it('should render correctly', () => {
});
it('should render with coverage selected', () => {
- expect(
- shallow(
- <PerspectiveSelect onChange={jest.fn()} view="visualizations" visualization="coverage" />
- )
- ).toMatchSnapshot();
+ expect(shallowRender({ view: 'visualizations', visualization: 'coverage' })).toMatchSnapshot();
+});
+
+it('should render option correctly', () => {
+ const wrapper = shallowRender();
+ const OptionRender = wrapper.instance().perspectiveOptionRender;
+ let option = shallow(
+ <OptionRender {...mockReactSelectOptionProps({ type: 'view', value: 'test', label: 'test' })} />
+ );
+
+ expect(option.find(ListIcon).type).toBeDefined();
+ option = shallow(
+ <OptionRender
+ {...mockReactSelectOptionProps({ type: 'visualization', value: 'test', label: '' })}
+ />
+ );
+ expect(option.find(BubblesIcon).type).toBeDefined();
});
it('should handle perspective change correctly', () => {
const onChange = jest.fn();
- const instance = shallow(
- <PerspectiveSelect onChange={onChange} view="visualizations" visualization="coverage" />
- ).instance() as PerspectiveSelect;
+ const instance = shallowRender({ onChange }).instance();
instance.handleChange({ label: 'overall', value: 'overall', type: 'view' });
instance.handleChange({ label: 'leak', value: 'leak', type: 'view' });
instance.handleChange({ label: 'coverage', value: 'coverage', type: 'visualization' });
expect(onChange.mock.calls).toMatchSnapshot();
});
+
+function shallowRender(overrides: Partial<PerspectiveSelect['props']> = {}) {
+ return shallow<PerspectiveSelect>(
+ <PerspectiveSelect onChange={jest.fn()} view="visualizations" {...overrides} />
+ );
+}
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2021 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import { shallow } from 'enzyme';
-import * as React from 'react';
-import PerspectiveSelectOption from '../PerspectiveSelectOption';
-
-it('should render correctly for a view', () => {
- expect(
- shallow(
- <PerspectiveSelectOption
- onFocus={jest.fn()}
- onSelect={jest.fn()}
- option={{ value: 'overall', type: 'view', label: 'Overall' }}>
- Overall
- </PerspectiveSelectOption>
- )
- ).toMatchSnapshot();
-});
-
-it('should render correctly for a visualization', () => {
- expect(
- shallow(
- <PerspectiveSelectOption
- onFocus={jest.fn()}
- onSelect={jest.fn()}
- option={{ value: 'coverage', type: 'visualization', label: 'Coverage' }}>
- Coverage
- </PerspectiveSelectOption>
- )
- ).toMatchSnapshot();
-});
-
-it('selects option', () => {
- const onSelect = jest.fn();
- const option = { value: 'coverage', type: 'visualization', label: 'Coverage' };
- const wrapper = shallow(
- <PerspectiveSelectOption onFocus={jest.fn()} onSelect={onSelect} option={option} />
- );
- const event = { stopPropagation() {}, preventDefault() {} };
- wrapper.simulate('mousedown', event);
- expect(onSelect).toBeCalledWith(option, event);
-});
-
-it('focuses option', () => {
- const onFocus = jest.fn();
- const option = { value: 'coverage', type: 'visualization', label: 'Coverage' };
- const wrapper = shallow(
- <PerspectiveSelectOption onFocus={onFocus} onSelect={jest.fn()} option={option} />
- );
- const event = { stopPropagation() {}, preventDefault() {} };
-
- wrapper.simulate('mouseenter', event);
- expect(onFocus).toBeCalledWith(option, event);
-
- onFocus.mockClear();
- wrapper.simulate('mousemove', event);
- expect(onFocus).toBeCalledWith(option, event);
-
- onFocus.mockClear();
- wrapper.setProps({ isFocused: true });
- wrapper.simulate('mousemove', event);
- expect(onFocus).not.toBeCalled();
-});
*/
import { shallow } from 'enzyme';
import * as React from 'react';
+import { GroupTypeBase } from 'react-select';
+import { mockReactSelectOptionProps } from '../../../../helpers/mocks/react-select';
import { click } from '../../../../helpers/testUtils';
-import ProjectsSortingSelect from '../ProjectsSortingSelect';
+import ProjectsSortingSelect, { Option } from '../ProjectsSortingSelect';
it('should render correctly for overall view', () => {
+ expect(shallowRender()).toMatchSnapshot();
+});
+
+it('should render correctly for leak view', () => {
expect(
- shallow(
- <ProjectsSortingSelect
- defaultOption="name"
- onChange={jest.fn()}
- selectedSort="name"
- view="overall"
- />
- )
+ shallowRender({ defaultOption: 'analysis_date', selectedSort: 'new_coverage', view: 'leak' })
).toMatchSnapshot();
});
-it('should render correctly for leak view', () => {
+it('should handle the descending sort direction', () => {
+ expect(shallowRender({ selectedSort: '-vulnerability' })).toMatchSnapshot();
+});
+
+it('should render option correctly', () => {
+ const wrapper = shallowRender();
+ const SortOption = wrapper.instance().projectsSortingSelectOption;
expect(
shallow(
- <ProjectsSortingSelect
- defaultOption="analysis_date"
- onChange={jest.fn()}
- selectedSort="new_coverage"
- view="leak"
+ <SortOption
+ {...mockReactSelectOptionProps<Option, false, GroupTypeBase<Option>>({
+ label: 'foo',
+ value: 'foo',
+ short: 'fo'
+ })}
/>
)
).toMatchSnapshot();
-});
-
-it('should handle the descending sort direction', () => {
expect(
shallow(
- <ProjectsSortingSelect
- defaultOption="name"
- onChange={jest.fn()}
- selectedSort="-vulnerability"
- view="overall"
+ <SortOption
+ {...mockReactSelectOptionProps<Option, false, GroupTypeBase<Option>>({
+ label: 'foo',
+ value: 'foo'
+ })}
/>
)
).toMatchSnapshot();
it('changes sorting', () => {
const onChange = jest.fn();
- const instance = shallow(
- <ProjectsSortingSelect
- defaultOption="name"
- onChange={onChange}
- selectedSort="-vulnerabilities"
- view="overall"
- />
- ).instance() as ProjectsSortingSelect;
+ const instance = shallowRender({
+ selectedSort: '-vulnerability',
+ onChange
+ }).instance() as ProjectsSortingSelect;
instance.handleSortChange({ label: 'size', value: 'size' });
expect(onChange).toBeCalledWith('size', true);
});
it('reverses sorting', () => {
const onChange = jest.fn();
- const wrapper = shallow(
+ const wrapper = shallowRender({ selectedSort: '-size', onChange });
+ click(wrapper.find('ButtonIcon'));
+ expect(onChange).toBeCalledWith('size', false);
+});
+
+function shallowRender(overrides: Partial<ProjectsSortingSelect['props']> = {}) {
+ return shallow<ProjectsSortingSelect>(
<ProjectsSortingSelect
defaultOption="name"
- onChange={onChange}
- selectedSort="-size"
+ onChange={jest.fn()}
+ selectedSort="name"
view="overall"
+ {...overrides}
/>
);
- click(wrapper.find('ButtonIcon'));
- expect(onChange).toBeCalledWith('size', false);
-});
+}
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2021 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import { shallow } from 'enzyme';
-import * as React from 'react';
-import ProjectsSortingSelectOption from '../ProjectsSortingSelectOption';
-
-it('renders', () => {
- expect(
- shallow(
- <ProjectsSortingSelectOption
- onFocus={jest.fn()}
- onSelect={jest.fn()}
- option={{ label: 'Size', value: 'size' }}>
- Size
- </ProjectsSortingSelectOption>
- )
- ).toMatchSnapshot();
-});
-
-it('renders short', () => {
- expect(
- shallow(
- <ProjectsSortingSelectOption
- onFocus={jest.fn()}
- onSelect={jest.fn()}
- option={{ label: 'Size', short: 'Short', value: 'size' }}>
- Size
- </ProjectsSortingSelectOption>
- )
- ).toMatchSnapshot();
-});
-
-it('selects option', () => {
- const onSelect = jest.fn();
- const option = { value: 'coverage', type: 'visualization', label: 'Coverage' };
- const wrapper = shallow(
- <ProjectsSortingSelectOption onFocus={jest.fn()} onSelect={onSelect} option={option} />
- );
- const event = { stopPropagation() {}, preventDefault() {} };
- wrapper.simulate('mousedown', event);
- expect(onSelect).toBeCalledWith(option, event);
-});
-
-it('focuses option', () => {
- const onFocus = jest.fn();
- const option = { value: 'coverage', type: 'visualization', label: 'Coverage' };
- const wrapper = shallow(
- <ProjectsSortingSelectOption onFocus={onFocus} onSelect={jest.fn()} option={option} />
- );
- const event = { stopPropagation() {}, preventDefault() {} };
-
- wrapper.simulate('mouseenter', event);
- expect(onFocus).toBeCalledWith(option, event);
-
- onFocus.mockClear();
- wrapper.simulate('mousemove', event);
- expect(onFocus).toBeCalledWith(option, event);
-
- onFocus.mockClear();
- wrapper.setProps({ isFocused: true });
- wrapper.simulate('mousemove', event);
- expect(onFocus).not.toBeCalled();
-});
exports[`should render correctly 1`] = `
<div>
- <label>
+ <label
+ id="aria-projects-perspective"
+ >
projects.perspective
:
</label>
<Select
- className="little-spacer-left input-medium"
- clearable={false}
+ aria-labelledby="aria-projects-perspective"
+ className="little-spacer-left input-medium it__projects-perspective-select"
+ components={
+ Object {
+ "Option": [Function],
+ }
+ }
+ isClearable={false}
+ isSearchable={false}
onChange={[Function]}
- optionComponent={[Function]}
options={
Array [
Object {
},
]
}
- searchable={false}
- value="overall"
+ value={
+ Object {
+ "label": "projects.view.overall",
+ "type": "view",
+ "value": "overall",
+ }
+ }
/>
</div>
`;
exports[`should render with coverage selected 1`] = `
<div>
- <label>
+ <label
+ id="aria-projects-perspective"
+ >
projects.perspective
:
</label>
<Select
- className="little-spacer-left input-medium"
- clearable={false}
+ aria-labelledby="aria-projects-perspective"
+ className="little-spacer-left input-medium it__projects-perspective-select"
+ components={
+ Object {
+ "Option": [Function],
+ }
+ }
+ isClearable={false}
+ isSearchable={false}
onChange={[Function]}
- optionComponent={[Function]}
options={
Array [
Object {
},
]
}
- searchable={false}
- value="coverage"
+ value={
+ Object {
+ "label": "projects.visualization.coverage",
+ "type": "visualization",
+ "value": "coverage",
+ }
+ }
/>
</div>
`;
+++ /dev/null
-// Jest Snapshot v1, https://goo.gl/fbAQLP
-
-exports[`should render correctly for a view 1`] = `
-<div
- onMouseDown={[Function]}
- onMouseEnter={[Function]}
- onMouseMove={[Function]}
- title="Overall"
->
- <div>
- <ListIcon
- className="little-spacer-right"
- />
- Overall
- </div>
-</div>
-`;
-
-exports[`should render correctly for a visualization 1`] = `
-<div
- onMouseDown={[Function]}
- onMouseEnter={[Function]}
- onMouseMove={[Function]}
- title="Coverage"
->
- <div>
- <BubblesIcon
- className="little-spacer-right"
- />
- Coverage
- </div>
-</div>
-`;
exports[`should handle the descending sort direction 1`] = `
<div>
- <label>
+ <label
+ id="aria-projects-sort"
+ >
projects.sort_by
:
</label>
<Select
- className="little-spacer-left input-medium"
- clearable={false}
+ aria-labelledby="aria-projects-sort"
+ className="little-spacer-left input-medium it__projects-sort-select"
+ components={
+ Object {
+ "Option": [Function],
+ }
+ }
+ isClearable={false}
+ isSearchable={false}
onChange={[Function]}
- optionComponent={[Function]}
options={
Array [
Object {
- "class": undefined,
+ "className": undefined,
"label": "projects.sorting.name",
"value": "name",
},
Object {
- "class": undefined,
+ "className": undefined,
"label": "projects.sorting.analysis_date",
"value": "analysis_date",
},
Object {
- "class": undefined,
+ "className": undefined,
"label": "projects.sorting.reliability",
"value": "reliability",
},
Object {
- "class": undefined,
+ "className": undefined,
"label": "projects.sorting.security",
"value": "security",
},
Object {
- "class": undefined,
+ "className": undefined,
"label": "projects.sorting.security_review",
"value": "security_review",
},
Object {
- "class": undefined,
+ "className": undefined,
"label": "projects.sorting.maintainability",
"value": "maintainability",
},
Object {
- "class": undefined,
+ "className": undefined,
"label": "projects.sorting.coverage",
"value": "coverage",
},
Object {
- "class": undefined,
+ "className": undefined,
"label": "projects.sorting.duplications",
"value": "duplications",
},
Object {
- "class": undefined,
+ "className": undefined,
"label": "projects.sorting.size",
"value": "size",
},
]
}
- searchable={false}
- value="vulnerability"
/>
<Tooltip
overlay="projects.sort_descending"
>
<ButtonIcon
+ aria-label="projects.sort_descending"
className="js-projects-sorting-invert spacer-left"
color="#999"
onClick={[Function]}
exports[`should render correctly for leak view 1`] = `
<div>
- <label>
+ <label
+ id="aria-projects-sort"
+ >
projects.sort_by
:
</label>
<Select
- className="little-spacer-left input-medium"
- clearable={false}
+ aria-labelledby="aria-projects-sort"
+ className="little-spacer-left input-medium it__projects-sort-select"
+ components={
+ Object {
+ "Option": [Function],
+ }
+ }
+ isClearable={false}
+ isSearchable={false}
onChange={[Function]}
- optionComponent={[Function]}
options={
Array [
Object {
- "class": undefined,
+ "className": undefined,
"label": "projects.sorting.analysis_date",
"value": "analysis_date",
},
Object {
- "class": undefined,
+ "className": undefined,
"label": "projects.sorting.name",
"value": "name",
},
Object {
- "class": "projects-leak-sorting-option",
+ "className": "projects-leak-sorting-option",
"label": "projects.sorting.new_reliability",
"value": "new_reliability",
},
Object {
- "class": "projects-leak-sorting-option",
+ "className": "projects-leak-sorting-option",
"label": "projects.sorting.new_security",
"value": "new_security",
},
Object {
- "class": "projects-leak-sorting-option",
+ "className": "projects-leak-sorting-option",
"label": "projects.sorting.new_security_review",
"value": "new_security_review",
},
Object {
- "class": "projects-leak-sorting-option",
+ "className": "projects-leak-sorting-option",
"label": "projects.sorting.new_maintainability",
"value": "new_maintainability",
},
Object {
- "class": "projects-leak-sorting-option",
+ "className": "projects-leak-sorting-option",
"label": "projects.sorting.new_coverage",
"value": "new_coverage",
},
Object {
- "class": "projects-leak-sorting-option",
+ "className": "projects-leak-sorting-option",
"label": "projects.sorting.new_duplications",
"value": "new_duplications",
},
Object {
- "class": "projects-leak-sorting-option",
+ "className": "projects-leak-sorting-option",
"label": "projects.sorting.new_lines",
"value": "new_lines",
},
]
}
- searchable={false}
- value="new_coverage"
+ value={
+ Object {
+ "className": "projects-leak-sorting-option",
+ "label": "projects.sorting.new_coverage",
+ "value": "new_coverage",
+ }
+ }
/>
<Tooltip
overlay="projects.sort_ascending"
>
<ButtonIcon
+ aria-label="projects.sort_ascending"
className="js-projects-sorting-invert spacer-left"
color="#999"
onClick={[Function]}
exports[`should render correctly for overall view 1`] = `
<div>
- <label>
+ <label
+ id="aria-projects-sort"
+ >
projects.sort_by
:
</label>
<Select
- className="little-spacer-left input-medium"
- clearable={false}
+ aria-labelledby="aria-projects-sort"
+ className="little-spacer-left input-medium it__projects-sort-select"
+ components={
+ Object {
+ "Option": [Function],
+ }
+ }
+ isClearable={false}
+ isSearchable={false}
onChange={[Function]}
- optionComponent={[Function]}
options={
Array [
Object {
- "class": undefined,
+ "className": undefined,
"label": "projects.sorting.name",
"value": "name",
},
Object {
- "class": undefined,
+ "className": undefined,
"label": "projects.sorting.analysis_date",
"value": "analysis_date",
},
Object {
- "class": undefined,
+ "className": undefined,
"label": "projects.sorting.reliability",
"value": "reliability",
},
Object {
- "class": undefined,
+ "className": undefined,
"label": "projects.sorting.security",
"value": "security",
},
Object {
- "class": undefined,
+ "className": undefined,
"label": "projects.sorting.security_review",
"value": "security_review",
},
Object {
- "class": undefined,
+ "className": undefined,
"label": "projects.sorting.maintainability",
"value": "maintainability",
},
Object {
- "class": undefined,
+ "className": undefined,
"label": "projects.sorting.coverage",
"value": "coverage",
},
Object {
- "class": undefined,
+ "className": undefined,
"label": "projects.sorting.duplications",
"value": "duplications",
},
Object {
- "class": undefined,
+ "className": undefined,
"label": "projects.sorting.size",
"value": "size",
},
]
}
- searchable={false}
- value="name"
+ value={
+ Object {
+ "className": undefined,
+ "label": "projects.sorting.name",
+ "value": "name",
+ }
+ }
/>
<Tooltip
overlay="projects.sort_ascending"
>
<ButtonIcon
+ aria-label="projects.sort_ascending"
className="js-projects-sorting-invert spacer-left"
color="#999"
onClick={[Function]}
</Tooltip>
</div>
`;
+
+exports[`should render option correctly 1`] = `
+<Option
+ className="it__project-sort-option-foo undefined"
+ data={
+ Object {
+ "label": "foo",
+ "short": "fo",
+ "value": "foo",
+ }
+ }
+>
+ fo
+</Option>
+`;
+
+exports[`should render option correctly 2`] = `
+<Option
+ className="it__project-sort-option-foo undefined"
+ data={
+ Object {
+ "label": "foo",
+ "value": "foo",
+ }
+ }
+/>
+`;
+++ /dev/null
-// Jest Snapshot v1, https://goo.gl/fbAQLP
-
-exports[`renders 1`] = `
-<div
- className=""
- onMouseDown={[Function]}
- onMouseEnter={[Function]}
- onMouseMove={[Function]}
- title="Size"
->
- Size
-</div>
-`;
-
-exports[`renders short 1`] = `
-<div
- className=""
- onMouseDown={[Function]}
- onMouseEnter={[Function]}
- onMouseMove={[Function]}
- title="Size"
->
- Short
-</div>
-`;
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
import * as React from 'react';
-import Select from '../../../components/controls/Select';
+import SelectLegacy from '../../../components/controls/SelectLegacy';
import { translate } from '../../../helpers/l10n';
interface Props {
render() {
return (
<div className="search-navigator-facet-footer projects-facet-footer">
- <Select
+ <SelectLegacy
className="input-super-large"
clearable={false}
isLoading={this.props.isLoading}
*/
import { shallow } from 'enzyme';
import * as React from 'react';
+import SelectLegacy from '../../../../components/controls/SelectLegacy';
import SearchableFilterFooter from '../SearchableFilterFooter';
const options = [
query={{ languages: ['java'] }}
/>
);
- expect(wrapper.find('Select').prop('options')).toMatchSnapshot();
+ expect(wrapper.find(SelectLegacy).prop('options')).toMatchSnapshot();
});
it('should properly handle a change of the facet value', () => {
query={{ languages: ['java'] }}
/>
);
- (wrapper.find('Select').prop('onChange') as Function)({ value: 'js' });
+ (wrapper.find(SelectLegacy).prop('onChange') as Function)({ value: 'js' });
expect(onQueryChange).toBeCalledWith({ languages: 'java,js' });
});
import { bulkApplyTemplate, getPermissionTemplates } from '../../api/permissions';
import { ResetButtonLink, SubmitButton } from '../../components/controls/buttons';
import Modal from '../../components/controls/Modal';
-import Select from '../../components/controls/Select';
+import SelectLegacy from '../../components/controls/SelectLegacy';
import { Alert } from '../../components/ui/Alert';
import MandatoryFieldMarker from '../../components/ui/MandatoryFieldMarker';
import MandatoryFieldsExplanation from '../../components/ui/MandatoryFieldsExplanation';
{translate('template')}
<MandatoryFieldMarker />
</label>
- <Select
+ <SelectLegacy
clearable={false}
disabled={this.state.submitting}
onChange={this.handlePermissionTemplateChange}
import DateInput from '../../components/controls/DateInput';
import HelpTooltip from '../../components/controls/HelpTooltip';
import SearchBox from '../../components/controls/SearchBox';
-import Select from '../../components/controls/Select';
+import SelectLegacy from '../../components/controls/SelectLegacy';
import QualifierIcon from '../../components/icons/QualifierIcon';
import { translate } from '../../helpers/l10n';
import BulkApplyTemplateModal from './BulkApplyTemplateModal';
}
return (
<td className="thin nowrap text-middle">
- <Select
+ <SelectLegacy
className="input-medium"
clearable={false}
disabled={!this.props.ready}
renderVisibilityFilter = () => {
return (
<td className="thin nowrap text-middle">
- <Select
+ <SelectLegacy
className="input-small"
clearable={false}
disabled={!this.props.ready}
it('updates qualifier', () => {
const onQualifierChanged = jest.fn();
const wrapper = shallowRender({ onQualifierChanged, topLevelQualifiers: ['TRK', 'VW', 'APP'] });
- wrapper.find('Select[name="projects-qualifier"]').prop<Function>('onChange')({ value: 'VW' });
+ wrapper.find('SelectLegacy[name="projects-qualifier"]').prop<Function>('onChange')({
+ value: 'VW'
+ });
expect(onQualifierChanged).toBeCalledWith('VW');
});
template
<MandatoryFieldMarker />
</label>
- <Select
+ <SelectLegacy
clearable={false}
disabled={false}
onChange={[Function]}
template
<MandatoryFieldMarker />
</label>
- <Select
+ <SelectLegacy
clearable={false}
disabled={true}
onChange={[Function]}
template
<MandatoryFieldMarker />
</label>
- <Select
+ <SelectLegacy
clearable={false}
disabled={false}
onChange={[Function]}
template
<MandatoryFieldMarker />
</label>
- <Select
+ <SelectLegacy
clearable={false}
disabled={true}
onChange={[Function]}
<td
className="thin nowrap text-middle"
>
- <Select
+ <SelectLegacy
className="input-medium"
clearable={false}
disabled={false}
<td
className="thin nowrap text-middle"
>
- <Select
+ <SelectLegacy
className="input-small"
clearable={false}
disabled={false}
<td
className="thin nowrap text-middle"
>
- <Select
+ <SelectLegacy
className="input-small"
clearable={false}
disabled={false}
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
import * as React from 'react';
-import Select from '../../../components/controls/Select';
+import SelectLegacy from '../../../components/controls/SelectLegacy';
import { translate } from '../../../helpers/l10n';
import { getPossibleOperators } from '../utils';
});
return (
- <Select
+ <SelectLegacy
autoFocus={true}
className="input-medium"
clearable={false}
*/
import { sortBy } from 'lodash';
import * as React from 'react';
-import Select from '../../../components/controls/Select';
+import SelectLegacy from '../../../components/controls/SelectLegacy';
import { getLocalizedMetricDomain, translate } from '../../../helpers/l10n';
import { getLocalizedMetricNameNoDiffMetric } from '../utils';
});
return (
- <Select
+ <SelectLegacy
className="text-middle quality-gate-metric-select"
id="condition-metric"
onChange={this.handleChange}
import * as React from 'react';
import { ResetButtonLink, SubmitButton } from '../../../components/controls/buttons';
import Modal from '../../../components/controls/Modal';
-import Select from '../../../components/controls/Select';
+import SelectLegacy from '../../../components/controls/SelectLegacy';
import GroupIcon from '../../../components/icons/GroupIcon';
import Avatar from '../../../components/ui/Avatar';
import { translate, translateWithParameters } from '../../../helpers/l10n';
<div className="modal-body">
<div className="modal-field">
<label>{translate('quality_gates.permissions.search')}</label>
- <Select
+ <SelectLegacy
autoFocus={true}
className="Select-big"
clearable={false}
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
import * as React from 'react';
-import Select from '../../../components/controls/Select';
+import SelectLegacy from '../../../components/controls/SelectLegacy';
interface Props {
name: string;
];
return (
- <Select
+ <SelectLegacy
className="input-tiny text-middle"
clearable={true}
id="condition-threshold"
*/
import { shallow } from 'enzyme';
import * as React from 'react';
-import Select from '../../../../components/controls/Select';
+import SelectLegacy from '../../../../components/controls/SelectLegacy';
import { mockUserBase } from '../../../../helpers/mocks/users';
import QualityGatePermissionsAddModalRenderer, {
QualityGatePermissionsAddModalRendererProps
it('should render options correctly', () => {
const wrapper = shallowRender();
- const { optionRenderer = () => null } = wrapper.find(Select).props();
+ const { optionRenderer = () => null } = wrapper.find(SelectLegacy).props();
expect(optionRenderer({ avatar: 'A', name: 'name', login: 'login' })).toMatchSnapshot('user');
expect(optionRenderer({ name: 'group name' })).toMatchSnapshot('group');
*/
import { shallow } from 'enzyme';
import * as React from 'react';
+import SelectLegacy from '../../../../components/controls/SelectLegacy';
import { change } from '../../../../helpers/testUtils';
import ThresholdInput from '../ThresholdInput';
it('should render Select', () => {
const select = shallow(
<ThresholdInput metric={metric} name="foo" onChange={jest.fn()} value="2" />
- ).find('Select');
+ ).find(SelectLegacy);
expect(select.length).toEqual(1);
expect(select.prop('value')).toEqual('2');
});
const onChange = jest.fn();
const select = shallow(
<ThresholdInput metric={metric} name="foo" onChange={onChange} value="2" />
- ).find('Select');
+ ).find(SelectLegacy);
(select.prop('onChange') as Function)({ label: 'D', value: '4' });
expect(onChange).toBeCalledWith('4');
});
const onChange = jest.fn();
const select = shallow(
<ThresholdInput metric={metric} name="foo" onChange={onChange} value="2" />
- ).find('Select');
+ ).find(SelectLegacy);
(select.prop('onChange') as Function)(null);
expect(onChange).toBeCalledWith('');
});
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`should render correctly 1`] = `
-<Select
+<SelectLegacy
autoFocus={true}
className="input-medium"
clearable={false}
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`should render correctly 1`] = `
-<Select
+<SelectLegacy
className="text-middle quality-gate-metric-select"
id="condition-metric"
onChange={[Function]}
<label>
quality_gates.permissions.search
</label>
- <Select
+ <SelectLegacy
autoFocus={true}
className="Select-big"
clearable={false}
<label>
quality_gates.permissions.search
</label>
- <Select
+ <SelectLegacy
autoFocus={true}
className="Select-big"
clearable={false}
<label>
quality_gates.permissions.search
</label>
- <Select
+ <SelectLegacy
autoFocus={true}
className="Select-big"
clearable={false}
<label>
quality_gates.permissions.search
</label>
- <Select
+ <SelectLegacy
autoFocus={true}
className="Select-big"
clearable={false}
<label>
quality_gates.permissions.search
</label>
- <Select
+ <SelectLegacy
autoFocus={true}
className="Select-big"
clearable={false}
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
import * as React from 'react';
-import Select from '../../../components/controls/Select';
+import SelectLegacy from '../../../components/controls/SelectLegacy';
import Tooltip from '../../../components/controls/Tooltip';
import { translate } from '../../../helpers/l10n';
import { Profile } from '../types';
return (
<div className="display-inline-block">
<label className="spacer-right">{translate('quality_profiles.compare_with')}</label>
- <Select
+ <SelectLegacy
className="input-large"
clearable={false}
onChange={this.handleChange}
*/
import { shallow } from 'enzyme';
import * as React from 'react';
-import Select from '../../../../components/controls/Select';
+import SelectLegacy from '../../../../components/controls/SelectLegacy';
import { mockQualityProfile } from '../../../../helpers/testMocks';
import ComparisonForm from '../ComparisonForm';
profiles={profiles}
withKey="another"
/>
- ).find(Select);
+ ).find(SelectLegacy);
expect(output.props().valueRenderer!(profileDefault)).toMatchSnapshot('Render default for value');
expect(output.props().valueRenderer!(profile)).toMatchSnapshot('Render for value');
import { changeProfileParent } from '../../../api/quality-profiles';
import { ResetButtonLink, SubmitButton } from '../../../components/controls/buttons';
import Modal from '../../../components/controls/Modal';
-import Select from '../../../components/controls/Select';
+import SelectLegacy from '../../../components/controls/SelectLegacy';
import MandatoryFieldMarker from '../../../components/ui/MandatoryFieldMarker';
import MandatoryFieldsExplanation from '../../../components/ui/MandatoryFieldsExplanation';
import { translate } from '../../../helpers/l10n';
{translate('quality_profiles.parent')}
<MandatoryFieldMarker />
</label>
- <Select
+ <SelectLegacy
clearable={false}
id="change-profile-parent"
name="parentKey"
*/
import { debounce, identity } from 'lodash';
import * as React from 'react';
-import Select from '../../../components/controls/Select';
+import SelectLegacy from '../../../components/controls/SelectLegacy';
import GroupIcon from '../../../components/icons/GroupIcon';
import Avatar from '../../../components/ui/Avatar';
import { translate, translateWithParameters } from '../../../helpers/l10n';
const options = this.state.searchResults.map(r => ({ ...r, value: getStringValue(r) }));
return (
- <Select
+ <SelectLegacy
autoFocus={true}
className="Select-big"
clearable={false}
quality_profiles.parent
<MandatoryFieldMarker />
</label>
- <Select
+ <SelectLegacy
clearable={false}
id="change-profile-parent"
name="parentKey"
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`renders 1`] = `
-<Select
+<SelectLegacy
autoFocus={true}
className="Select-big"
clearable={false}
} from '../../../api/quality-profiles';
import { ResetButtonLink, SubmitButton } from '../../../components/controls/buttons';
import Modal from '../../../components/controls/Modal';
-import Select from '../../../components/controls/Select';
+import SelectLegacy from '../../../components/controls/SelectLegacy';
import { Location } from '../../../components/hoc/withRouter';
import MandatoryFieldMarker from '../../../components/ui/MandatoryFieldMarker';
import MandatoryFieldsExplanation from '../../../components/ui/MandatoryFieldsExplanation';
{translate('language')}
<MandatoryFieldMarker />
</label>
- <Select
+ <SelectLegacy
clearable={false}
id="create-profile-language"
name="language"
<label htmlFor="create-profile-parent">
{translate('quality_profiles.parent')}
</label>
- <Select
+ <SelectLegacy
clearable={true}
id="create-profile-parent"
name="parentKey"
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
import * as React from 'react';
-import Select from '../../../components/controls/Select';
+import SelectLegacy from '../../../components/controls/SelectLegacy';
import { Router, withRouter } from '../../../components/hoc/withRouter';
import { translate } from '../../../helpers/l10n';
import { getProfilesForLanguagePath, PROFILE_PATH } from '../utils';
return (
<header className="quality-profiles-list-header clearfix">
<span className="spacer-right">{translate('quality_profiles.filter_by')}:</span>
- <Select
+ <SelectLegacy
className="input-medium"
clearable={true}
onChange={this.handleChange}
language
<MandatoryFieldMarker />
</label>
- <Select
+ <SelectLegacy
clearable={false}
id="create-profile-language"
name="language"
>
quality_profiles.parent
</label>
- <Select
+ <SelectLegacy
clearable={true}
id="create-profile-parent"
name="parentKey"
language
<MandatoryFieldMarker />
</label>
- <Select
+ <SelectLegacy
clearable={false}
id="create-profile-language"
name="language"
>
quality_profiles.parent
</label>
- <Select
+ <SelectLegacy
clearable={true}
id="create-profile-parent"
name="parentKey"
quality_profiles.filter_by
:
</span>
- <Select
+ <SelectLegacy
className="input-medium"
clearable={true}
onChange={[Function]}
import * as React from 'react';
import HelpTooltip from '../../../components/controls/HelpTooltip';
import RadioToggle from '../../../components/controls/RadioToggle';
-import Select from '../../../components/controls/Select';
+import SelectLegacy from '../../../components/controls/SelectLegacy';
import { withCurrentUser } from '../../../components/hoc/withCurrentUser';
import Measure from '../../../components/measure/Measure';
import CoverageRating from '../../../components/ui/CoverageRating';
)}
<span className="spacer-right">{translate('status')}</span>
- <Select
+ <SelectLegacy
className="input-medium big-spacer-right"
clearable={false}
onChange={(option: { value: HotspotStatusFilter }) =>
/>
{onBranch && (
- <Select
+ <SelectLegacy
className="input-medium big-spacer-right"
clearable={false}
onChange={(option: { value: boolean }) =>
import { shallow } from 'enzyme';
import * as React from 'react';
import RadioToggle from '../../../../components/controls/RadioToggle';
-import Select from '../../../../components/controls/Select';
+import SelectLegacy from '../../../../components/controls/SelectLegacy';
import { mockComponent } from '../../../../helpers/mocks/component';
import { mockCurrentUser, mockLoggedInUser } from '../../../../helpers/testMocks';
import { ComponentQualifier } from '../../../../types/component';
const wrapper = shallowRender({ onChangeFilters });
const { onChange } = wrapper
- .find(Select)
+ .find(SelectLegacy)
.at(0)
.props();
const wrapper = shallowRender({ onChangeFilters });
const { onChange } = wrapper
- .find(Select)
+ .find(SelectLegacy)
.at(1)
.props();
>
status
</span>
- <Select
+ <SelectLegacy
className="input-medium big-spacer-right"
clearable={false}
onChange={[Function]}
searchable={false}
value="TO_REVIEW"
/>
- <Select
+ <SelectLegacy
className="input-medium big-spacer-right"
clearable={false}
onChange={[Function]}
>
status
</span>
- <Select
+ <SelectLegacy
className="input-medium big-spacer-right"
clearable={false}
onChange={[Function]}
searchable={false}
value="TO_REVIEW"
/>
- <Select
+ <SelectLegacy
className="input-medium big-spacer-right"
clearable={false}
onChange={[Function]}
>
status
</span>
- <Select
+ <SelectLegacy
className="input-medium big-spacer-right"
clearable={false}
onChange={[Function]}
searchable={false}
value="TO_REVIEW"
/>
- <Select
+ <SelectLegacy
className="input-medium big-spacer-right"
clearable={false}
onChange={[Function]}
>
status
</span>
- <Select
+ <SelectLegacy
className="input-medium big-spacer-right"
clearable={false}
onChange={[Function]}
>
status
</span>
- <Select
+ <SelectLegacy
className="input-medium big-spacer-right"
clearable={false}
onChange={[Function]}
searchable={false}
value="TO_REVIEW"
/>
- <Select
+ <SelectLegacy
className="input-medium big-spacer-right"
clearable={false}
onChange={[Function]}
*/
import * as React from 'react';
import { connect } from 'react-redux';
-import Select from '../../../components/controls/Select';
+import SelectLegacy from '../../../components/controls/SelectLegacy';
import { Location, Router, withRouter } from '../../../components/hoc/withRouter';
import { translate } from '../../../helpers/l10n';
import { getSettingsAppAllCategories, Store } from '../../../store/rootReducer';
<>
<h2 className="settings-sub-category-name">{translate('property.category.languages')}</h2>
<div data-test="language-select">
- <Select
+ <SelectLegacy
className="input-large"
onChange={handleOnChange}
options={availableLanguages}
*/
import { shallow } from 'enzyme';
import * as React from 'react';
-import Select from '../../../../components/controls/Select';
+import SelectLegacy from '../../../../components/controls/SelectLegacy';
import { mockComponent } from '../../../../helpers/mocks/component';
import { mockLocation, mockRouter } from '../../../../helpers/testMocks';
import CategoryDefinitionsList from '../CategoryDefinitionsList';
const wrapper = shallowRender({ router });
expect(wrapper.find(CategoryDefinitionsList).props().category).toBe('java');
- const { onChange } = wrapper.find(Select).props();
+ const { onChange } = wrapper.find(SelectLegacy).props();
onChange!({ label: '', originalValue: 'CoBoL', value: 'cobol' });
expect(push).toHaveBeenCalledWith(expect.objectContaining({ query: { category: 'CoBoL' } }));
<div
data-test="language-select"
>
- <Select
+ <SelectLegacy
className="input-large"
onChange={[Function]}
options={
<div
data-test="language-select"
>
- <Select
+ <SelectLegacy
className="input-large"
onChange={[Function]}
options={
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
import * as React from 'react';
-import Select from '../../../../components/controls/Select';
+import SelectLegacy from '../../../../components/controls/SelectLegacy';
import { SettingCategoryDefinition } from '../../../../types/settings';
import { DefaultSpecializedInputProps } from '../../utils';
}));
return (
- <Select
+ <SelectLegacy
className="settings-large-input"
clearable={false}
name={this.props.name}
*/
import { shallow } from 'enzyme';
import * as React from 'react';
+import SelectLegacy from '../../../../../components/controls/SelectLegacy';
import { mockSetting } from '../../../../../helpers/mocks/settings';
import { DefaultSpecializedInputProps } from '../../../utils';
import InputForSingleSelectList from '../InputForSingleSelectList';
it('should render Select', () => {
const onChange = jest.fn();
- const select = shallowRender({ onChange }).find('Select');
+ const select = shallowRender({ onChange }).find(SelectLegacy);
expect(select.length).toBe(1);
expect(select.prop('name')).toBe('foo');
expect(select.prop('value')).toBe('bar');
it('should call onChange', () => {
const onChange = jest.fn();
- const select = shallowRender({ onChange }).find('Select');
+ const select = shallowRender({ onChange }).find(SelectLegacy);
expect(select.length).toBe(1);
expect(select.prop('onChange')).toBeDefined();
import { FormattedMessage } from 'react-intl';
import { Link } from 'react-router';
import { Button, SubmitButton } from '../../../../components/controls/buttons';
-import Select from '../../../../components/controls/Select';
+import SelectLegacy from '../../../../components/controls/SelectLegacy';
import AlertSuccessIcon from '../../../../components/icons/AlertSuccessIcon';
import { Alert } from '../../../../components/ui/Alert';
import DeferredSpinner from '../../../../components/ui/DeferredSpinner';
</div>
</div>
<div className="settings-definition-right">
- <Select
+ <SelectLegacy
autosize={true}
className="abs-width-400 big-spacer-top"
clearable={false}
*/
import { shallow } from 'enzyme';
import * as React from 'react';
-import Select from '../../../../../components/controls/Select';
+import SelectLegacy from '../../../../../components/controls/SelectLegacy';
import { waitAndUpdate } from '../../../../../helpers/testUtils';
import {
AlmKeys,
await waitAndUpdate(wrapper);
- const { optionRenderer } = wrapper.find(Select).props();
+ const { optionRenderer } = wrapper.find(SelectLegacy).props();
expect(optionRenderer!(instances[0])).toMatchSnapshot();
<div
className="settings-definition-right"
>
- <Select
+ <SelectLegacy
autosize={true}
className="abs-width-400 big-spacer-top"
clearable={false}
<div
className="settings-definition-right"
>
- <Select
+ <SelectLegacy
autosize={true}
className="abs-width-400 big-spacer-top"
clearable={false}
<div
className="settings-definition-right"
>
- <Select
+ <SelectLegacy
autosize={true}
className="abs-width-400 big-spacer-top"
clearable={false}
<div
className="settings-definition-right"
>
- <Select
+ <SelectLegacy
autosize={true}
className="abs-width-400 big-spacer-top"
clearable={false}
<div
className="settings-definition-right"
>
- <Select
+ <SelectLegacy
autosize={true}
className="abs-width-400 big-spacer-top"
clearable={false}
<div
className="settings-definition-right"
>
- <Select
+ <SelectLegacy
autosize={true}
className="abs-width-400 big-spacer-top"
clearable={false}
*/
import { debounce } from 'lodash';
import * as React from 'react';
-import Select from '../../../components/controls/Select';
+import SelectLegacy from '../../../components/controls/SelectLegacy';
import Avatar from '../../../components/ui/Avatar';
import { translate, translateWithParameters } from '../../../helpers/l10n';
? translateWithParameters('select2.tooShort', 2)
: translate('no_results');
return (
- <Select
+ <SelectLegacy
autoFocus={this.props.autoFocus}
className="Select-big"
clearable={false}
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`UsersSelectSearch should render correctly 1`] = `
-<Select
+<SelectLegacy
className="Select-big"
clearable={false}
filterOptions={[Function]}
`;
exports[`UsersSelectSearch should render correctly 3`] = `
-<Select
+<SelectLegacy
className="Select-big"
clearable={false}
filterOptions={[Function]}
*/
import classNames from 'classnames';
import * as React from 'react';
-import Select from '../../components/controls/Select';
import { translate } from '../../helpers/l10n';
import { GraphType } from '../../types/project-activity';
+import SelectLegacy from '../controls/SelectLegacy';
import AddGraphMetric from './AddGraphMetric';
import './styles.css';
import { getGraphTypes, isCustomGraph } from './utils';
return (
<div className={classNames(className, 'position-relative')}>
- <Select
+ <SelectLegacy
className="pull-left input-medium"
clearable={false}
onChange={this.handleGraphChange}
import { InjectedIntlProps, injectIntl } from 'react-intl';
import { ButtonIcon, ClearButton } from '../../components/controls/buttons';
import OutsideClickHandler from '../../components/controls/OutsideClickHandler';
-import Select from '../../components/controls/Select';
import CalendarIcon from '../../components/icons/CalendarIcon';
import ChevronLeftIcon from '../../components/icons/ChevronLeftIcon';
import ChevronRightIcon from '../../components/icons/ChevronRightIcon';
import { getShortMonthName, getShortWeekDayName, getWeekDayName } from '../../helpers/l10n';
import { lazyLoadComponent } from '../lazyLoadComponent';
import './DayPicker.css';
+import SelectLegacy from './SelectLegacy';
import './styles.css';
const DayPicker = lazyLoadComponent(() => import('react-day-picker'), 'DayPicker');
<ChevronLeftIcon />
</ButtonIcon>
<div className="date-input-calender-month">
- <Select
+ <SelectLegacy
className="date-input-calender-month-select"
onChange={this.handleCurrentMonthChange}
options={months.map(month => ({
}))}
value={this.state.currentMonth.getMonth()}
/>
- <Select
+ <SelectLegacy
className="date-input-calender-month-select spacer-left"
onChange={this.handleCurrentYearChange}
options={years.map(year => ({ label: String(year), value: year }))}
import { debounce } from 'lodash';
import * as React from 'react';
import { translate, translateWithParameters } from '../../helpers/l10n';
-import Select, { Creatable } from './Select';
+import SelectLegacy, { CreatableLegacy } from './SelectLegacy';
interface Props<T> {
autofocus?: boolean;
handleFilterOption = () => true;
render() {
- const Component = this.props.canCreate ? Creatable : Select;
+ const Component = this.props.canCreate ? CreatableLegacy : SelectLegacy;
return (
<Component
autoFocus={this.autofocus}
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2021 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-.Select {
- position: relative;
- display: inline-block;
- vertical-align: middle;
- font-size: var(--smallFontSize);
- text-align: left;
-}
-
-.Select,
-.Select div,
-.Select input,
-.Select span {
- box-sizing: border-box;
-}
-
-.Select.is-disabled > .Select-control {
- background-color: var(--disableGrayBg) !important;
- border-color: var(--disableGrayBorder) !important;
-}
-
-.Select.is-disabled > .Select-control:hover {
- box-shadow: none !important;
-}
-
-.Select.is-disabled .Select-arrow-zone {
- cursor: not-allowed !important;
- pointer-events: none !important;
-}
-
-.Select.is-disabled .Select-placeholder,
-.Select.is-disabled .Select-value {
- color: var(--disableGrayText) !important;
-}
-
-.Select-control {
- position: relative;
- display: table;
- width: 100%;
- height: var(--controlHeight);
- line-height: calc(var(--controlHeight) - 2px);
- border: 1px solid var(--gray80);
- border-collapse: separate;
- border-radius: 2px;
- background-color: #fff;
- color: var(--baseFontColor);
- cursor: default;
- outline: none;
- overflow: hidden;
-}
-
-.is-searchable.is-open > .Select-control {
- cursor: text;
-}
-
-.is-open > .Select-control {
- border-bottom-right-radius: 0;
- border-bottom-left-radius: 0;
- background: #fff;
-}
-
-.is-open > .Select-control > .Select-arrow {
- border-color: transparent transparent #999;
- border-width: 0 5px 5px;
-}
-
-.is-searchable.is-focused:not(.is-open) > .Select-control {
- cursor: text;
-}
-
-.is-focused:not(.is-open) > .Select-control {
- border-color: var(--blue);
-}
-
-.Select-placeholder {
- color: var(--secondFontColor);
-}
-
-.Select-placeholder,
-:not(.Select--multi) > .Select-control .Select-value {
- bottom: 0;
- left: 0;
- line-height: 23px;
- padding-left: 8px;
- padding-right: 24px;
- position: absolute;
- right: 0;
- top: 0;
- max-width: 100%;
- overflow: hidden;
- text-overflow: ellipsis;
- white-space: nowrap;
-}
-
-.Select-value [class^='icon-'] {
- padding-top: 5px;
-}
-
-.Select-value svg,
-.Select-value img {
- padding-top: 3px;
-}
-
-.Select-option svg,
-.Select-option img,
-.Select-option [class^='icon-'] {
- padding-top: 2px;
-}
-
-.has-value:not(.Select--multi) > .Select-control > .Select-value .Select-value-label,
-.has-value.is-pseudo-focused:not(.Select--multi)
- > .Select-control
- > .Select-value
- .Select-value-label {
- color: var(--baseFontColor);
-}
-
-.has-value:not(.Select--multi) > .Select-control > .Select-value a.Select-value-label,
-.has-value.is-pseudo-focused:not(.Select--multi)
- > .Select-control
- > .Select-value
- a.Select-value-label {
- cursor: pointer;
- text-decoration: none;
-}
-
-.has-value:not(.Select--multi) > .Select-control > .Select-value a.Select-value-label:hover,
-.has-value.is-pseudo-focused:not(.Select--multi)
- > .Select-control
- > .Select-value
- a.Select-value-label:hover,
-.has-value:not(.Select--multi) > .Select-control > .Select-value a.Select-value-label:focus,
-.has-value.is-pseudo-focused:not(.Select--multi)
- > .Select-control
- > .Select-value
- a.Select-value-label:focus {
- color: #007eff;
- outline: none;
- text-decoration: underline;
-}
-
-.Select-input {
- vertical-align: top;
- height: 22px;
- padding-left: 8px;
- padding-right: 8px;
- outline: none;
-}
-
-.Select-input > input {
- background: none transparent;
- border: 0 none;
- cursor: default;
- display: inline-block;
- font-family: inherit;
- font-size: var(--smallFontSize);
- height: 22px;
- margin: 0;
- outline: none;
- padding: 0;
- box-shadow: none;
- -webkit-appearance: none;
-}
-
-.is-focused .Select-input > input {
- cursor: text;
-}
-
-.has-value.is-pseudo-focused .Select-input {
- opacity: 0;
-}
-
-.Select-control:not(.is-searchable) > .Select-input {
- outline: none;
-}
-
-.Select-loading-zone {
- cursor: pointer;
- display: table-cell;
- position: relative;
- text-align: center;
- vertical-align: middle;
- width: 16px;
-}
-
-.Select-loading {
- -webkit-animation: Select-animation-spin 400ms infinite linear;
- -o-animation: Select-animation-spin 400ms infinite linear;
- animation: Select-animation-spin 400ms infinite linear;
- width: 16px;
- height: 16px;
- box-sizing: border-box;
- border-radius: 50%;
- border: 2px solid #ccc;
- border-right-color: var(--baseFontColor);
- display: inline-block;
- position: relative;
- vertical-align: middle;
-}
-
-.Select-clear-zone {
- -webkit-animation: Select-animation-fadeIn 200ms;
- -o-animation: Select-animation-fadeIn 200ms;
- animation: Select-animation-fadeIn 200ms;
- color: #999;
- cursor: pointer;
- display: table-cell;
- position: relative;
- text-align: center;
- vertical-align: middle;
- width: 16px;
- height: 16px;
- padding-right: 4px;
-}
-
-.Select-clear-zone:hover .Select-clear {
- background-image: url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+PCFET0NUWVBFIHN2ZyBQVUJMSUMgIi0vL1czQy8vRFREIFNWRyAxLjEvL0VOIiAiaHR0cDovL3d3dy53My5vcmcvR3JhcGhpY3MvU1ZHLzEuMS9EVEQvc3ZnMTEuZHRkIj48c3ZnIHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIHZpZXdCb3g9IjAgMCAxNCAxNCIgdmVyc2lvbj0iMS4xIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB4bWw6c3BhY2U9InByZXNlcnZlIiBzdHlsZT0iZmlsbC1ydWxlOmV2ZW5vZGQ7Y2xpcC1ydWxlOmV2ZW5vZGQ7c3Ryb2tlLWxpbmVqb2luOnJvdW5kO3N0cm9rZS1taXRlcmxpbWl0OjEuNDE0MjE7Ij4gICAgPGcgdHJhbnNmb3JtPSJtYXRyaXgoMC4wMjM0Mzc1LDAsMCwwLjAyMzQzNzUsLTUuMDE1NjIsLTUuMDE1NjIpIj4gICAgICAgIDxwYXRoIGQ9Ik04MTAsMjc0TDU3Miw1MTJMODEwLDc1MEw3NTAsODEwTDUxMiw1NzJMMjc0LDgxMEwyMTQsNzUwTDQ1Miw1MTJMMjE0LDI3NEwyNzQsMjE0TDUxMiw0NTJMNzUwLDIxNEw4MTAsMjc0WiIgc3R5bGU9ImZpbGw6cmdiKDIzMSwyMCw1Nik7ZmlsbC1ydWxlOm5vbnplcm87Ii8+ICAgIDwvZz48L3N2Zz4=);
-}
-
-.Select-clear {
- display: block;
- width: 9px;
- height: 9px;
- background-image: url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+PCFET0NUWVBFIHN2ZyBQVUJMSUMgIi0vL1czQy8vRFREIFNWRyAxLjEvL0VOIiAiaHR0cDovL3d3dy53My5vcmcvR3JhcGhpY3MvU1ZHLzEuMS9EVEQvc3ZnMTEuZHRkIj48c3ZnIHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIHZpZXdCb3g9IjAgMCAxNCAxNCIgdmVyc2lvbj0iMS4xIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB4bWw6c3BhY2U9InByZXNlcnZlIiBzdHlsZT0iZmlsbC1ydWxlOmV2ZW5vZGQ7Y2xpcC1ydWxlOmV2ZW5vZGQ7c3Ryb2tlLWxpbmVqb2luOnJvdW5kO3N0cm9rZS1taXRlcmxpbWl0OjEuNDE0MjE7Ij4gICAgPGcgdHJhbnNmb3JtPSJtYXRyaXgoMC4wMjM0Mzc1LDAsMCwwLjAyMzQzNzUsLTUuMDE1NjIsLTUuMDE1NjIpIj4gICAgICAgIDxwYXRoIGQ9Ik04MTAsMjc0TDU3Miw1MTJMODEwLDc1MEw3NTAsODEwTDUxMiw1NzJMMjc0LDgxMEwyMTQsNzUwTDQ1Miw1MTJMMjE0LDI3NEwyNzQsMjE0TDUxMiw0NTJMNzUwLDIxNEw4MTAsMjc0WiIgc3R5bGU9ImZpbGw6cmdiKDE1MywxNTMsMTUzKTtmaWxsLXJ1bGU6bm9uemVybzsiLz4gICAgPC9nPjwvc3ZnPg==);
- background-size: 9px 9px;
- text-indent: -9999px;
-}
-
-.Select--multi .Select-clear-zone {
- width: 17px;
-}
-
-.Select-arrow-zone {
- cursor: pointer;
- display: table-cell;
- position: relative;
- text-align: center;
- vertical-align: middle;
- width: 20px;
- padding-right: 5px;
-}
-
-.Select-arrow {
- border-color: #999 transparent transparent;
- border-style: solid;
- border-width: 4px 4px 2px;
- display: inline-block;
- height: 0;
- width: 0;
-}
-
-.is-open .Select-arrow,
-.Select-arrow-zone:hover > .Select-arrow {
- border-top-color: #666;
-}
-
-@-webkit-keyframes Select-animation-fadeIn {
- from {
- opacity: 0;
- }
-
- to {
- opacity: 1;
- }
-}
-
-@keyframes Select-animation-fadeIn {
- from {
- opacity: 0;
- }
-
- to {
- opacity: 1;
- }
-}
-
-.Select-menu-outer {
- border-bottom-right-radius: 4px;
- border-bottom-left-radius: 4px;
- background-color: #fff;
- border: 1px solid #ccc;
- border-top-color: var(--barBorderColor);
- box-sizing: border-box;
- margin-top: -1px;
- max-height: 200px;
- position: absolute;
- top: 100%;
- width: 100%;
- z-index: var(--dropdownMenuZIndex);
- -webkit-overflow-scrolling: touch;
- box-shadow: var(--defaultShadow);
-}
-
-.Select-menu {
- max-height: 198px;
- padding: 5px 0;
- overflow-y: auto;
-}
-
-.Select-option {
- display: block;
- line-height: 20px;
- padding: 0 8px;
- box-sizing: border-box;
- color: var(--baseFontColor);
- font-size: var(--smallFontSize);
- cursor: pointer;
- white-space: nowrap;
- overflow: hidden;
- text-overflow: ellipsis;
-}
-
-.Select-option:last-child {
- border-bottom-right-radius: 2px;
- border-bottom-left-radius: 2px;
-}
-
-.Select-option.is-focused {
- background-color: var(--barBackgroundColor);
-}
-
-.Select-option.is-disabled {
- cursor: default;
- opacity: 0.4;
- font-style: italic;
-}
-
-.Select-noresults {
- box-sizing: border-box;
- color: var(--gray60);
- cursor: default;
- display: block;
- padding: 8px 10px;
-}
-
-.Select--multi .Select-value {
- background-color: rgba(0, 126, 255, 0.08);
- border-radius: 2px;
- border: 1px solid rgba(0, 126, 255, 0.24);
- color: var(--baseFontColor);
- display: inline-block;
- font-size: var(--smallFontSize);
- line-height: 14px;
- margin: 1px 4px 1px 1px;
- vertical-align: top;
-}
-
-.Select-value-label {
- font-size: var(--smallFontSize);
-}
-
-.is-searchable.is-open .Select-value-label {
- opacity: 0.5;
-}
-
-.Select-big .Select-control {
- padding-top: 4px;
- padding-bottom: 4px;
-}
-
-.Select-big .Select-placeholder {
- margin-top: 4px;
- margin-bottom: 4px;
-}
-
-.Select-big .Select-value-label {
- display: inline-block;
- margin-top: 7px;
- line-height: 16px;
-}
-
-.Select-big .Select-option {
- padding: 7px 8px;
- line-height: 16px;
-}
-
-.Select-big img,
-.Select-big svg {
- padding-top: 0;
-}
-
-.Select--multi .Select-value-icon,
-.Select--multi .Select-value-label {
- display: inline-block;
- vertical-align: middle;
-}
-
-.Select--multi .Select-value-label {
- display: inline-block;
- max-width: 200px;
- border-bottom-right-radius: 2px;
- border-top-right-radius: 2px;
- cursor: default;
- padding: 2px 5px;
- overflow: hidden;
- text-overflow: ellipsis;
- white-space: nowrap;
-}
-
-.Select--multi a.Select-value-label {
- color: #007eff;
- cursor: pointer;
- text-decoration: none;
-}
-
-.Select--multi a.Select-value-label:hover {
- text-decoration: underline;
-}
-
-.Select--multi .Select-value-icon {
- cursor: pointer;
- border-bottom-left-radius: 2px;
- border-top-left-radius: 2px;
- border-right: 1px solid rgba(0, 126, 255, 0.24);
- padding: 1px 5px;
-}
-
-.Select--multi .Select-value-icon:hover,
-.Select--multi .Select-value-icon:focus {
- background-color: rgba(0, 113, 230, 0.08);
- color: #0071e6;
-}
-
-.Select--multi .Select-value-icon:active {
- background-color: rgba(0, 126, 255, 0.24);
-}
-
-.Select--multi.is-disabled .Select-value {
- background-color: #fcfcfc;
- border: 1px solid #e3e3e3;
- color: var(--baseFontColor);
-}
-
-.Select--multi.is-disabled .Select-value-icon {
- cursor: not-allowed;
- border-right: 1px solid #e3e3e3;
-}
-
-.Select--multi.is-disabled .Select-value-icon:hover,
-.Select--multi.is-disabled .Select-value-icon:focus,
-.Select--multi.is-disabled .Select-value-icon:active {
- background-color: #fcfcfc;
-}
-
-.Select-aria-only {
- display: none;
-}
-
-@keyframes Select-animation-spin {
- to {
- transform: rotate(1turn);
- }
-}
-
-@-webkit-keyframes Select-animation-spin {
- to {
- -webkit-transform: rotate(1turn);
- }
-}
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
+import styled from '@emotion/styled';
import * as React from 'react';
-import ReactSelectClass, {
- ReactAsyncSelectProps,
- ReactCreatableSelectProps,
- ReactSelectProps
-} from 'react-select';
-import { lazyLoadComponent } from '../lazyLoadComponent';
-import { ClearButton } from './buttons';
-import './Select.css';
+import ReactSelect, { GroupTypeBase, IndicatorProps, Props, StylesConfig } from 'react-select';
+import { colors, others, sizes, zIndexes } from '../../app/theme';
-const ReactSelectLib = import('react-select');
-const ReactSelect = lazyLoadComponent(() => ReactSelectLib);
-const ReactCreatable = lazyLoadComponent(() =>
- ReactSelectLib.then(lib => ({ default: lib.Creatable }))
-);
-const ReactAsync = lazyLoadComponent(() => ReactSelectLib.then(lib => ({ default: lib.Async })));
+const ArrowSpan = styled.span`
+ border-color: #999 transparent transparent;
+ border-style: solid;
+ border-width: 4px 4px 2px;
+ display: inline-block;
+ height: 0;
+ width: 0;
+`;
-function renderInput() {
- return <ClearButton className="button-tiny spacer-left text-middle" iconProps={{ size: 12 }} />;
-}
-
-export interface WithInnerRef {
- innerRef?: React.Ref<ReactSelectClass<unknown>>;
-}
+export default function Select<
+ Option,
+ IsMulti extends boolean = false,
+ Group extends GroupTypeBase<Option> = GroupTypeBase<Option>
+>(props: Props<Option, IsMulti, Group>) {
+ function DropdownIndicator({ innerProps }: IndicatorProps<Option, IsMulti, Group>) {
+ return <ArrowSpan {...innerProps} />;
+ }
-export default function Select({ innerRef, ...props }: WithInnerRef & ReactSelectProps) {
- // hide the "x" icon when select is empty
- const clearable = props.clearable ? Boolean(props.value) : false;
return (
- <ReactSelect {...props} clearable={clearable} clearRenderer={renderInput} ref={innerRef} />
+ <ReactSelect
+ {...props}
+ styles={selectStyle<Option, IsMulti, Group>()}
+ components={{
+ ...props.components,
+ DropdownIndicator
+ }}
+ />
);
}
-export function Creatable(props: ReactCreatableSelectProps) {
- return <ReactCreatable {...props} clearRenderer={renderInput} />;
-}
-
-export function AsyncSelect(props: ReactAsyncSelectProps & WithInnerRef) {
- return <ReactAsync {...props} />;
+export function selectStyle<
+ Option,
+ IsMulti extends boolean,
+ Group extends GroupTypeBase<Option>
+>(): StylesConfig<Option, IsMulti, Group> {
+ return {
+ container: () => ({
+ position: 'relative',
+ display: 'inline-block',
+ verticalAlign: 'middle',
+ fontSize: '12px',
+ textAlign: 'left'
+ }),
+ control: () => ({
+ position: 'relative',
+ display: 'table',
+ width: '100%',
+ height: `${sizes.controlHeight}`,
+ lineHeight: `calc(${sizes.controlHeight} - 2px)`,
+ border: `1px solid ${colors.gray80}`,
+ borderCollapse: 'separate',
+ borderRadius: '2px',
+ backgroundColor: '#fff',
+ boxSizing: 'border-box',
+ color: `${colors.baseFontColor}`,
+ cursor: 'default',
+ outline: 'none'
+ }),
+ singleValue: () => ({
+ bottom: 0,
+ left: 0,
+ lineHeight: '23px',
+ paddingLeft: '8px',
+ paddingRight: '24px',
+ position: 'absolute',
+ right: 0,
+ top: 0,
+ maxWidth: '100%',
+ overflow: 'hidden',
+ textOverflow: 'ellipsis',
+ whiteSpace: 'nowrap'
+ }),
+ valueContainer: () => ({
+ bottom: 0,
+ left: 0,
+ lineHeight: '23px',
+ paddingLeft: '8px',
+ paddingRight: '24px',
+ position: 'absolute',
+ right: 0,
+ top: 0,
+ maxWidth: '100%',
+ overflow: 'hidden',
+ textOverflow: 'ellipsis',
+ whiteSpace: 'nowrap'
+ }),
+ indicatorsContainer: () => ({
+ cursor: 'pointer',
+ display: 'table-cell',
+ position: 'relative',
+ textAlign: 'center',
+ verticalAlign: 'middle',
+ width: '20px',
+ paddingRight: '5px'
+ }),
+ menu: () => ({
+ borderBottomRightRadius: '4px',
+ borderBottomLeftRadius: '4px',
+ backgroundColor: '#fff',
+ border: '1px solid #ccc',
+ borderTopColor: `${colors.barBorderColor}`,
+ boxSizing: 'border-box',
+ marginTop: '-1px',
+ maxHeight: '200px',
+ position: 'absolute',
+ top: '100%',
+ width: '100%',
+ zIndex: `${zIndexes.dropdownMenuZIndex}`,
+ webkitOverflowScrolling: 'touch',
+ boxShadow: `${others.defaultShadow}`
+ }),
+ menuList: () => ({
+ maxHeight: '198px',
+ padding: '5px 0',
+ overflowY: 'auto'
+ }),
+ option: (_provided, state) => ({
+ display: 'block',
+ lineHeight: '20px',
+ padding: '0 8px',
+ boxSizing: 'border-box',
+ color: `${colors.baseFontColor}`,
+ backgroundColor: state.isFocused ? `${colors.barBackgroundColor}` : 'white',
+ fontSize: `${sizes.smallFontSize}`,
+ cursor: 'pointer',
+ whiteSpace: 'nowrap',
+ overflow: 'hidden',
+ textOverflow: 'ellipsis'
+ })
+ };
}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2021 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+.Select {
+ position: relative;
+ display: inline-block;
+ vertical-align: middle;
+ font-size: var(--smallFontSize);
+ text-align: left;
+}
+
+.Select,
+.Select div,
+.Select input,
+.Select span {
+ box-sizing: border-box;
+}
+
+.Select.is-disabled > .Select-control {
+ background-color: var(--disableGrayBg) !important;
+ border-color: var(--disableGrayBorder) !important;
+}
+
+.Select.is-disabled > .Select-control:hover {
+ box-shadow: none !important;
+}
+
+.Select.is-disabled .Select-arrow-zone {
+ cursor: not-allowed !important;
+ pointer-events: none !important;
+}
+
+.Select.is-disabled .Select-placeholder,
+.Select.is-disabled .Select-value {
+ color: var(--disableGrayText) !important;
+}
+
+.Select-control {
+ position: relative;
+ display: table;
+ width: 100%;
+ height: var(--controlHeight);
+ line-height: calc(var(--controlHeight) - 2px);
+ border: 1px solid var(--gray80);
+ border-collapse: separate;
+ border-radius: 2px;
+ background-color: #fff;
+ color: var(--baseFontColor);
+ cursor: default;
+ outline: none;
+ overflow: hidden;
+}
+
+.is-searchable.is-open > .Select-control {
+ cursor: text;
+}
+
+.is-open > .Select-control {
+ border-bottom-right-radius: 0;
+ border-bottom-left-radius: 0;
+ background: #fff;
+}
+
+.is-open > .Select-control > .Select-arrow {
+ border-color: transparent transparent #999;
+ border-width: 0 5px 5px;
+}
+
+.is-searchable.is-focused:not(.is-open) > .Select-control {
+ cursor: text;
+}
+
+.is-focused:not(.is-open) > .Select-control {
+ border-color: var(--blue);
+}
+
+.Select-placeholder {
+ color: var(--secondFontColor);
+}
+
+.Select-placeholder,
+:not(.Select--multi) > .Select-control .Select-value {
+ bottom: 0;
+ left: 0;
+ line-height: 23px;
+ padding-left: 8px;
+ padding-right: 24px;
+ position: absolute;
+ right: 0;
+ top: 0;
+ max-width: 100%;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ white-space: nowrap;
+}
+
+.Select-value [class^='icon-'] {
+ padding-top: 5px;
+}
+
+.Select-value svg,
+.Select-value img {
+ padding-top: 3px;
+}
+
+.Select-option svg,
+.Select-option img,
+.Select-option [class^='icon-'] {
+ padding-top: 2px;
+}
+
+.has-value:not(.Select--multi) > .Select-control > .Select-value .Select-value-label,
+.has-value.is-pseudo-focused:not(.Select--multi)
+ > .Select-control
+ > .Select-value
+ .Select-value-label {
+ color: var(--baseFontColor);
+}
+
+.has-value:not(.Select--multi) > .Select-control > .Select-value a.Select-value-label,
+.has-value.is-pseudo-focused:not(.Select--multi)
+ > .Select-control
+ > .Select-value
+ a.Select-value-label {
+ cursor: pointer;
+ text-decoration: none;
+}
+
+.has-value:not(.Select--multi) > .Select-control > .Select-value a.Select-value-label:hover,
+.has-value.is-pseudo-focused:not(.Select--multi)
+ > .Select-control
+ > .Select-value
+ a.Select-value-label:hover,
+.has-value:not(.Select--multi) > .Select-control > .Select-value a.Select-value-label:focus,
+.has-value.is-pseudo-focused:not(.Select--multi)
+ > .Select-control
+ > .Select-value
+ a.Select-value-label:focus {
+ color: #007eff;
+ outline: none;
+ text-decoration: underline;
+}
+
+.Select-input {
+ vertical-align: top;
+ height: 22px;
+ padding-left: 8px;
+ padding-right: 8px;
+ outline: none;
+}
+
+.Select-input > input {
+ background: none transparent;
+ border: 0 none;
+ cursor: default;
+ display: inline-block;
+ font-family: inherit;
+ font-size: var(--smallFontSize);
+ height: 22px;
+ margin: 0;
+ outline: none;
+ padding: 0;
+ box-shadow: none;
+ -webkit-appearance: none;
+}
+
+.is-focused .Select-input > input {
+ cursor: text;
+}
+
+.has-value.is-pseudo-focused .Select-input {
+ opacity: 0;
+}
+
+.Select-control:not(.is-searchable) > .Select-input {
+ outline: none;
+}
+
+.Select-loading-zone {
+ cursor: pointer;
+ display: table-cell;
+ position: relative;
+ text-align: center;
+ vertical-align: middle;
+ width: 16px;
+}
+
+.Select-loading {
+ -webkit-animation: Select-animation-spin 400ms infinite linear;
+ -o-animation: Select-animation-spin 400ms infinite linear;
+ animation: Select-animation-spin 400ms infinite linear;
+ width: 16px;
+ height: 16px;
+ box-sizing: border-box;
+ border-radius: 50%;
+ border: 2px solid #ccc;
+ border-right-color: var(--baseFontColor);
+ display: inline-block;
+ position: relative;
+ vertical-align: middle;
+}
+
+.Select-clear-zone {
+ -webkit-animation: Select-animation-fadeIn 200ms;
+ -o-animation: Select-animation-fadeIn 200ms;
+ animation: Select-animation-fadeIn 200ms;
+ color: #999;
+ cursor: pointer;
+ display: table-cell;
+ position: relative;
+ text-align: center;
+ vertical-align: middle;
+ width: 16px;
+ height: 16px;
+ padding-right: 4px;
+}
+
+.Select-clear-zone:hover .Select-clear {
+ background-image: url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+PCFET0NUWVBFIHN2ZyBQVUJMSUMgIi0vL1czQy8vRFREIFNWRyAxLjEvL0VOIiAiaHR0cDovL3d3dy53My5vcmcvR3JhcGhpY3MvU1ZHLzEuMS9EVEQvc3ZnMTEuZHRkIj48c3ZnIHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIHZpZXdCb3g9IjAgMCAxNCAxNCIgdmVyc2lvbj0iMS4xIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB4bWw6c3BhY2U9InByZXNlcnZlIiBzdHlsZT0iZmlsbC1ydWxlOmV2ZW5vZGQ7Y2xpcC1ydWxlOmV2ZW5vZGQ7c3Ryb2tlLWxpbmVqb2luOnJvdW5kO3N0cm9rZS1taXRlcmxpbWl0OjEuNDE0MjE7Ij4gICAgPGcgdHJhbnNmb3JtPSJtYXRyaXgoMC4wMjM0Mzc1LDAsMCwwLjAyMzQzNzUsLTUuMDE1NjIsLTUuMDE1NjIpIj4gICAgICAgIDxwYXRoIGQ9Ik04MTAsMjc0TDU3Miw1MTJMODEwLDc1MEw3NTAsODEwTDUxMiw1NzJMMjc0LDgxMEwyMTQsNzUwTDQ1Miw1MTJMMjE0LDI3NEwyNzQsMjE0TDUxMiw0NTJMNzUwLDIxNEw4MTAsMjc0WiIgc3R5bGU9ImZpbGw6cmdiKDIzMSwyMCw1Nik7ZmlsbC1ydWxlOm5vbnplcm87Ii8+ICAgIDwvZz48L3N2Zz4=);
+}
+
+.Select-clear {
+ display: block;
+ width: 9px;
+ height: 9px;
+ background-image: url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+PCFET0NUWVBFIHN2ZyBQVUJMSUMgIi0vL1czQy8vRFREIFNWRyAxLjEvL0VOIiAiaHR0cDovL3d3dy53My5vcmcvR3JhcGhpY3MvU1ZHLzEuMS9EVEQvc3ZnMTEuZHRkIj48c3ZnIHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIHZpZXdCb3g9IjAgMCAxNCAxNCIgdmVyc2lvbj0iMS4xIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB4bWw6c3BhY2U9InByZXNlcnZlIiBzdHlsZT0iZmlsbC1ydWxlOmV2ZW5vZGQ7Y2xpcC1ydWxlOmV2ZW5vZGQ7c3Ryb2tlLWxpbmVqb2luOnJvdW5kO3N0cm9rZS1taXRlcmxpbWl0OjEuNDE0MjE7Ij4gICAgPGcgdHJhbnNmb3JtPSJtYXRyaXgoMC4wMjM0Mzc1LDAsMCwwLjAyMzQzNzUsLTUuMDE1NjIsLTUuMDE1NjIpIj4gICAgICAgIDxwYXRoIGQ9Ik04MTAsMjc0TDU3Miw1MTJMODEwLDc1MEw3NTAsODEwTDUxMiw1NzJMMjc0LDgxMEwyMTQsNzUwTDQ1Miw1MTJMMjE0LDI3NEwyNzQsMjE0TDUxMiw0NTJMNzUwLDIxNEw4MTAsMjc0WiIgc3R5bGU9ImZpbGw6cmdiKDE1MywxNTMsMTUzKTtmaWxsLXJ1bGU6bm9uemVybzsiLz4gICAgPC9nPjwvc3ZnPg==);
+ background-size: 9px 9px;
+ text-indent: -9999px;
+}
+
+.Select--multi .Select-clear-zone {
+ width: 17px;
+}
+
+.Select-arrow-zone {
+ cursor: pointer;
+ display: table-cell;
+ position: relative;
+ text-align: center;
+ vertical-align: middle;
+ width: 20px;
+ padding-right: 5px;
+}
+
+.Select-arrow {
+ border-color: #999 transparent transparent;
+ border-style: solid;
+ border-width: 4px 4px 2px;
+ display: inline-block;
+ height: 0;
+ width: 0;
+}
+
+.is-open .Select-arrow,
+.Select-arrow-zone:hover > .Select-arrow {
+ border-top-color: #666;
+}
+
+@-webkit-keyframes Select-animation-fadeIn {
+ from {
+ opacity: 0;
+ }
+
+ to {
+ opacity: 1;
+ }
+}
+
+@keyframes Select-animation-fadeIn {
+ from {
+ opacity: 0;
+ }
+
+ to {
+ opacity: 1;
+ }
+}
+
+.Select-menu-outer {
+ border-bottom-right-radius: 4px;
+ border-bottom-left-radius: 4px;
+ background-color: #fff;
+ border: 1px solid #ccc;
+ border-top-color: var(--barBorderColor);
+ box-sizing: border-box;
+ margin-top: -1px;
+ max-height: 200px;
+ position: absolute;
+ top: 100%;
+ width: 100%;
+ z-index: var(--dropdownMenuZIndex);
+ -webkit-overflow-scrolling: touch;
+ box-shadow: var(--defaultShadow);
+}
+
+.Select-menu {
+ max-height: 198px;
+ padding: 5px 0;
+ overflow-y: auto;
+}
+
+.Select-option {
+ display: block;
+ line-height: 20px;
+ padding: 0 8px;
+ box-sizing: border-box;
+ color: var(--baseFontColor);
+ font-size: var(--smallFontSize);
+ cursor: pointer;
+ white-space: nowrap;
+ overflow: hidden;
+ text-overflow: ellipsis;
+}
+
+.Select-option:last-child {
+ border-bottom-right-radius: 2px;
+ border-bottom-left-radius: 2px;
+}
+
+.Select-option.is-focused {
+ background-color: var(--barBackgroundColor);
+}
+
+.Select-option.is-disabled {
+ cursor: default;
+ opacity: 0.4;
+ font-style: italic;
+}
+
+.Select-noresults {
+ box-sizing: border-box;
+ color: var(--gray60);
+ cursor: default;
+ display: block;
+ padding: 8px 10px;
+}
+
+.Select--multi .Select-value {
+ background-color: rgba(0, 126, 255, 0.08);
+ border-radius: 2px;
+ border: 1px solid rgba(0, 126, 255, 0.24);
+ color: var(--baseFontColor);
+ display: inline-block;
+ font-size: var(--smallFontSize);
+ line-height: 14px;
+ margin: 1px 4px 1px 1px;
+ vertical-align: top;
+}
+
+.Select-value-label {
+ font-size: var(--smallFontSize);
+}
+
+.is-searchable.is-open .Select-value-label {
+ opacity: 0.5;
+}
+
+.Select-big .Select-control {
+ padding-top: 4px;
+ padding-bottom: 4px;
+}
+
+.Select-big .Select-placeholder {
+ margin-top: 4px;
+ margin-bottom: 4px;
+}
+
+.Select-big .Select-value-label {
+ display: inline-block;
+ margin-top: 7px;
+ line-height: 16px;
+}
+
+.Select-big .Select-option {
+ padding: 7px 8px;
+ line-height: 16px;
+}
+
+.Select-big img,
+.Select-big svg {
+ padding-top: 0;
+}
+
+.Select--multi .Select-value-icon,
+.Select--multi .Select-value-label {
+ display: inline-block;
+ vertical-align: middle;
+}
+
+.Select--multi .Select-value-label {
+ display: inline-block;
+ max-width: 200px;
+ border-bottom-right-radius: 2px;
+ border-top-right-radius: 2px;
+ cursor: default;
+ padding: 2px 5px;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ white-space: nowrap;
+}
+
+.Select--multi a.Select-value-label {
+ color: #007eff;
+ cursor: pointer;
+ text-decoration: none;
+}
+
+.Select--multi a.Select-value-label:hover {
+ text-decoration: underline;
+}
+
+.Select--multi .Select-value-icon {
+ cursor: pointer;
+ border-bottom-left-radius: 2px;
+ border-top-left-radius: 2px;
+ border-right: 1px solid rgba(0, 126, 255, 0.24);
+ padding: 1px 5px;
+}
+
+.Select--multi .Select-value-icon:hover,
+.Select--multi .Select-value-icon:focus {
+ background-color: rgba(0, 113, 230, 0.08);
+ color: #0071e6;
+}
+
+.Select--multi .Select-value-icon:active {
+ background-color: rgba(0, 126, 255, 0.24);
+}
+
+.Select--multi.is-disabled .Select-value {
+ background-color: #fcfcfc;
+ border: 1px solid #e3e3e3;
+ color: var(--baseFontColor);
+}
+
+.Select--multi.is-disabled .Select-value-icon {
+ cursor: not-allowed;
+ border-right: 1px solid #e3e3e3;
+}
+
+.Select--multi.is-disabled .Select-value-icon:hover,
+.Select--multi.is-disabled .Select-value-icon:focus,
+.Select--multi.is-disabled .Select-value-icon:active {
+ background-color: #fcfcfc;
+}
+
+.Select-aria-only {
+ display: none;
+}
+
+@keyframes Select-animation-spin {
+ to {
+ transform: rotate(1turn);
+ }
+}
+
+@-webkit-keyframes Select-animation-spin {
+ to {
+ -webkit-transform: rotate(1turn);
+ }
+}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2021 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+import * as React from 'react';
+import ReactSelectClass, {
+ ReactAsyncSelectProps,
+ ReactCreatableSelectProps,
+ ReactSelectProps
+} from 'react-select-legacy';
+import { lazyLoadComponent } from '../lazyLoadComponent';
+import { ClearButton } from './buttons';
+import './SelectLegacy.css';
+
+const ReactSelectLib = import('react-select-legacy');
+const ReactSelect = lazyLoadComponent(() => ReactSelectLib);
+const ReactCreatable = lazyLoadComponent(() =>
+ ReactSelectLib.then(lib => ({ default: lib.Creatable }))
+);
+const ReactAsync = lazyLoadComponent(() => ReactSelectLib.then(lib => ({ default: lib.Async })));
+
+function renderInput() {
+ return <ClearButton className="button-tiny spacer-left text-middle" iconProps={{ size: 12 }} />;
+}
+
+export interface WithInnerRef {
+ innerRef?: React.Ref<ReactSelectClass<unknown>>;
+}
+
+export default function SelectLegacy({ innerRef, ...props }: WithInnerRef & ReactSelectProps) {
+ // hide the "x" icon when select is empty
+ const clearable = props.clearable ? Boolean(props.value) : false;
+ return (
+ <ReactSelect {...props} clearable={clearable} clearRenderer={renderInput} ref={innerRef} />
+ );
+}
+
+export function CreatableLegacy(props: ReactCreatableSelectProps) {
+ return <ReactCreatable {...props} clearRenderer={renderInput} />;
+}
+
+export function AsyncSelectLegacy(props: ReactAsyncSelectProps & WithInnerRef) {
+ return <ReactAsync {...props} />;
+}
import { shallow } from 'enzyme';
import * as React from 'react';
-import { ReactAsyncSelectProps, ReactCreatableSelectProps, ReactSelectProps } from 'react-select';
-import Select, { AsyncSelect, Creatable, WithInnerRef } from '../Select';
+import { GroupTypeBase, Props } from 'react-select';
+import Select from '../Select';
describe('Select', () => {
- it('should render correctly', () => {
- return new Promise<void>((resolve, reject) => {
- expect(shallowRender()).toMatchSnapshot('default');
- expect(shallowRender({ clearable: true, value: undefined })).toMatchSnapshot(
- 'disable clear button if no value'
- );
-
- const clearRenderFn = shallowRender().props().clearRenderer;
- if (!clearRenderFn) {
- reject();
- return;
- }
- expect(clearRenderFn()).toMatchSnapshot('clear button');
-
- resolve();
- });
- });
-
- function shallowRender(props: Partial<WithInnerRef & ReactSelectProps> = {}) {
- return shallow<WithInnerRef & ReactSelectProps>(<Select value="foo" {...props} />);
- }
-});
-
-describe('Creatable', () => {
- it('should render correctly', () => {
- return new Promise<void>((resolve, reject) => {
- expect(shallowRender()).toMatchSnapshot('default');
-
- const clearRenderFn = shallowRender().props().clearRenderer;
- if (!clearRenderFn) {
- reject();
- return;
- }
- expect(clearRenderFn()).toMatchSnapshot('clear button');
-
- resolve();
- });
- });
-
- function shallowRender(props: Partial<ReactCreatableSelectProps> = {}) {
- return shallow<ReactCreatableSelectProps>(<Creatable {...props} />);
- }
-});
-
-describe('AsyncSelect', () => {
it('should render correctly', () => {
expect(shallowRender()).toMatchSnapshot('default');
});
- function shallowRender(props: Partial<WithInnerRef & ReactAsyncSelectProps> = {}) {
- return shallow<WithInnerRef & ReactAsyncSelectProps>(
- <AsyncSelect loadOptions={jest.fn()} {...props} />
- );
+ function shallowRender<
+ Option,
+ IsMulti extends boolean = false,
+ Group extends GroupTypeBase<Option> = GroupTypeBase<Option>
+ >(props: Partial<Props<Option, IsMulti, Group>> = {}) {
+ return shallow<Props<Option, IsMulti, Group>>(<Select {...props} />);
}
});
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2021 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+import { shallow } from 'enzyme';
+import * as React from 'react';
+import {
+ ReactAsyncSelectProps,
+ ReactCreatableSelectProps,
+ ReactSelectProps
+} from 'react-select-legacy';
+import SelectLegacy, { AsyncSelectLegacy, CreatableLegacy, WithInnerRef } from '../SelectLegacy';
+
+describe('Select', () => {
+ it('should render correctly', () => {
+ return new Promise<void>((resolve, reject) => {
+ expect(shallowRender()).toMatchSnapshot('default');
+ expect(shallowRender({ clearable: true, value: undefined })).toMatchSnapshot(
+ 'disable clear button if no value'
+ );
+
+ const clearRenderFn = shallowRender().props().clearRenderer;
+ if (!clearRenderFn) {
+ reject();
+ return;
+ }
+ expect(clearRenderFn()).toMatchSnapshot('clear button');
+
+ resolve();
+ });
+ });
+
+ function shallowRender(props: Partial<WithInnerRef & ReactSelectProps> = {}) {
+ return shallow<WithInnerRef & ReactSelectProps>(<SelectLegacy value="foo" {...props} />);
+ }
+});
+
+describe('Creatable', () => {
+ it('should render correctly', () => {
+ return new Promise<void>((resolve, reject) => {
+ expect(shallowRender()).toMatchSnapshot('default');
+
+ const clearRenderFn = shallowRender().props().clearRenderer;
+ if (!clearRenderFn) {
+ reject();
+ return;
+ }
+ expect(clearRenderFn()).toMatchSnapshot('clear button');
+
+ resolve();
+ });
+ });
+
+ function shallowRender(props: Partial<ReactCreatableSelectProps> = {}) {
+ return shallow<ReactCreatableSelectProps>(<CreatableLegacy {...props} />);
+ }
+});
+
+describe('AsyncSelect', () => {
+ it('should render correctly', () => {
+ expect(shallowRender()).toMatchSnapshot('default');
+ });
+
+ function shallowRender(props: Partial<WithInnerRef & ReactAsyncSelectProps> = {}) {
+ return shallow<WithInnerRef & ReactAsyncSelectProps>(
+ <AsyncSelectLegacy loadOptions={jest.fn()} {...props} />
+ );
+ }
+});
<div
className="date-input-calender-month"
>
- <Select
+ <SelectLegacy
className="date-input-calender-month-select"
onChange={[Function]}
options={
}
value={0}
/>
- <Select
+ <SelectLegacy
className="date-input-calender-month-select spacer-left"
onChange={[Function]}
options={
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`should render Select 1`] = `
-<Select
+<SelectLegacy
autoFocus={true}
escapeClearsValue={false}
filterOption={[Function]}
// Jest Snapshot v1, https://goo.gl/fbAQLP
-exports[`AsyncSelect should render correctly: default 1`] = `
-<LazyComponentWrapper
- loadOptions={[MockFunction]}
-/>
-`;
-
-exports[`Creatable should render correctly: clear button 1`] = `
-<ClearButton
- className="button-tiny spacer-left text-middle"
- iconProps={
+exports[`Select should render correctly: default 1`] = `
+<StateManager
+ components={
Object {
- "size": 12,
+ "DropdownIndicator": [Function],
}
}
-/>
-`;
-
-exports[`Creatable should render correctly: default 1`] = `
-<LazyComponentWrapper
- clearRenderer={[Function]}
-/>
-`;
-
-exports[`Select should render correctly: clear button 1`] = `
-<ClearButton
- className="button-tiny spacer-left text-middle"
- iconProps={
+ defaultInputValue=""
+ defaultMenuIsOpen={false}
+ defaultValue={null}
+ styles={
Object {
- "size": 12,
+ "container": [Function],
+ "control": [Function],
+ "indicatorsContainer": [Function],
+ "menu": [Function],
+ "menuList": [Function],
+ "option": [Function],
+ "singleValue": [Function],
+ "valueContainer": [Function],
}
}
/>
`;
-
-exports[`Select should render correctly: default 1`] = `
-<LazyComponentWrapper
- clearRenderer={[Function]}
- clearable={false}
- value="foo"
-/>
-`;
-
-exports[`Select should render correctly: disable clear button if no value 1`] = `
-<LazyComponentWrapper
- clearRenderer={[Function]}
- clearable={false}
-/>
-`;
--- /dev/null
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`AsyncSelect should render correctly: default 1`] = `
+<LazyComponentWrapper
+ loadOptions={[MockFunction]}
+/>
+`;
+
+exports[`Creatable should render correctly: clear button 1`] = `
+<ClearButton
+ className="button-tiny spacer-left text-middle"
+ iconProps={
+ Object {
+ "size": 12,
+ }
+ }
+/>
+`;
+
+exports[`Creatable should render correctly: default 1`] = `
+<LazyComponentWrapper
+ clearRenderer={[Function]}
+/>
+`;
+
+exports[`Select should render correctly: clear button 1`] = `
+<ClearButton
+ className="button-tiny spacer-left text-middle"
+ iconProps={
+ Object {
+ "size": 12,
+ }
+ }
+/>
+`;
+
+exports[`Select should render correctly: default 1`] = `
+<LazyComponentWrapper
+ clearRenderer={[Function]}
+ clearable={false}
+ value="foo"
+/>
+`;
+
+exports[`Select should render correctly: disable clear button if no value 1`] = `
+<LazyComponentWrapper
+ clearRenderer={[Function]}
+ clearable={false}
+/>
+`;
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2021 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+import { GroupTypeBase, OptionProps } from 'react-select';
+
+export function mockReactSelectOptionProps<
+ OptionType,
+ IsMulti extends boolean,
+ GroupType extends GroupTypeBase<OptionType> = GroupTypeBase<OptionType>
+>(
+ data: OptionType,
+ overrides?: OptionProps<OptionType, IsMulti, GroupType>
+): OptionProps<OptionType, IsMulti, GroupType> {
+ return {
+ ...overrides,
+ data
+ } as OptionProps<OptionType, IsMulti, GroupType>;
+}
languageName: node
linkType: hard
+"@babel/runtime@npm:^7.12.0, @babel/runtime@npm:^7.13.10, @babel/runtime@npm:^7.8.7":
+ version: 7.16.3
+ resolution: "@babel/runtime@npm:7.16.3"
+ dependencies:
+ regenerator-runtime: ^0.13.4
+ checksum: ab8ac887096d76185ddbf291d28fb976cd32473696dc497ad4905b784acbd5aa462533ad83a5c5104e10ead28c2e0e119840ee28ed8eff90dcdde9d57f916eda
+ languageName: node
+ linkType: hard
+
"@babel/runtime@npm:^7.3.4":
version: 7.7.7
resolution: "@babel/runtime@npm:7.7.7"
languageName: node
linkType: hard
+"@emotion/cache@npm:^11.4.0, @emotion/cache@npm:^11.6.0":
+ version: 11.6.0
+ resolution: "@emotion/cache@npm:11.6.0"
+ dependencies:
+ "@emotion/memoize": ^0.7.4
+ "@emotion/sheet": ^1.1.0
+ "@emotion/utils": ^1.0.0
+ "@emotion/weak-memoize": ^0.2.5
+ stylis: ^4.0.10
+ checksum: 3c72c50bfe06fd7ec2728988181173664183d2320305a01bb757caa6a9d485de25fccde1b173d810423d2ff88a178d5a72cc21db76b9e458311a8ce3044dd2a1
+ languageName: node
+ linkType: hard
+
"@emotion/core@npm:10.0.28":
version: 10.0.28
resolution: "@emotion/core@npm:10.0.28"
languageName: node
linkType: hard
-"@emotion/hash@npm:0.8.0":
+"@emotion/hash@npm:0.8.0, @emotion/hash@npm:^0.8.0":
version: 0.8.0
resolution: "@emotion/hash@npm:0.8.0"
checksum: 4b35d88a97e67275c1d990c96d3b0450451d089d1508619488fc0acb882cb1ac91e93246d471346ebd1b5402215941ef4162efe5b51534859b39d8b3a0e3ffaa
languageName: node
linkType: hard
+"@emotion/memoize@npm:^0.7.4":
+ version: 0.7.5
+ resolution: "@emotion/memoize@npm:0.7.5"
+ checksum: 83da8d4a7649a92c72f960817692bc6be13cc13e107b9f7e878d63766525ed4402881bfeb3cda61145c050281e7e260f114a0a2870515527346f2ef896b915b3
+ languageName: node
+ linkType: hard
+
+"@emotion/react@npm:^11.1.1":
+ version: 11.6.0
+ resolution: "@emotion/react@npm:11.6.0"
+ dependencies:
+ "@babel/runtime": ^7.13.10
+ "@emotion/cache": ^11.6.0
+ "@emotion/serialize": ^1.0.2
+ "@emotion/sheet": ^1.1.0
+ "@emotion/utils": ^1.0.0
+ "@emotion/weak-memoize": ^0.2.5
+ hoist-non-react-statics: ^3.3.1
+ peerDependencies:
+ "@babel/core": ^7.0.0
+ react: ">=16.8.0"
+ peerDependenciesMeta:
+ "@babel/core":
+ optional: true
+ "@types/react":
+ optional: true
+ checksum: 4fb2d108dc32716d1f162026ac5fdbd0662e3b435a34fb324629d72bb6bff61b18ac8975b51457c16ffa41543bade5d07558566ab76420b3926fbb9159441232
+ languageName: node
+ linkType: hard
+
"@emotion/serialize@npm:^0.11.15, @emotion/serialize@npm:^0.11.16":
version: 0.11.16
resolution: "@emotion/serialize@npm:0.11.16"
languageName: node
linkType: hard
+"@emotion/serialize@npm:^1.0.0, @emotion/serialize@npm:^1.0.2":
+ version: 1.0.2
+ resolution: "@emotion/serialize@npm:1.0.2"
+ dependencies:
+ "@emotion/hash": ^0.8.0
+ "@emotion/memoize": ^0.7.4
+ "@emotion/unitless": ^0.7.5
+ "@emotion/utils": ^1.0.0
+ csstype: ^3.0.2
+ checksum: ff84fbe09ec06e7ad3deaef5c5b5ea6af6a522e8efe49c2b398b875d06872626284a83b6b18b7f777750c94264a61e7924157d869d9bca2f675731bbb91a6055
+ languageName: node
+ linkType: hard
+
"@emotion/sheet@npm:0.9.4":
version: 0.9.4
resolution: "@emotion/sheet@npm:0.9.4"
languageName: node
linkType: hard
+"@emotion/sheet@npm:^1.1.0":
+ version: 1.1.0
+ resolution: "@emotion/sheet@npm:1.1.0"
+ checksum: a4b74e16a8fea1157413efe4904f5f679d724323cb605d66d20a0b98744422f5d411fca927ceb52e4de454a0a819c5273ca9496db9f011b4ecd17b9f1b212007
+ languageName: node
+ linkType: hard
+
"@emotion/styled-base@npm:^10.0.27":
version: 10.0.30
resolution: "@emotion/styled-base@npm:10.0.30"
languageName: node
linkType: hard
-"@emotion/unitless@npm:0.7.5":
+"@emotion/unitless@npm:0.7.5, @emotion/unitless@npm:^0.7.5":
version: 0.7.5
resolution: "@emotion/unitless@npm:0.7.5"
checksum: f976e5345b53fae9414a7b2e7a949aa6b52f8bdbcc84458b1ddc0729e77ba1d1dfdff9960e0da60183877873d3a631fa24d9695dd714ed94bcd3ba5196586a6b
languageName: node
linkType: hard
-"@emotion/weak-memoize@npm:0.2.5":
+"@emotion/utils@npm:^1.0.0":
+ version: 1.0.0
+ resolution: "@emotion/utils@npm:1.0.0"
+ checksum: 3ce8048441a915447d9ef51eb6d1d4cbcce8c8d1647bc7a23333ce2fb2249e74cf9471670d6f49a716e93ff633c9e7a6633517698e17391aebfc40c9d0cabcc0
+ languageName: node
+ linkType: hard
+
+"@emotion/weak-memoize@npm:0.2.5, @emotion/weak-memoize@npm:^0.2.5":
version: 0.2.5
resolution: "@emotion/weak-memoize@npm:0.2.5"
checksum: 27d402b0c683b94658220b6d47840346ee582329ca2a15ec9c233492e0f1a27687ccb233b76eedc922f2e185e444cc89f7b97a81a1d3e5ae9f075bab08e965ea
languageName: node
linkType: hard
+"@types/react-dom@npm:*":
+ version: 17.0.11
+ resolution: "@types/react-dom@npm:17.0.11"
+ dependencies:
+ "@types/react": "*"
+ checksum: 4d5730dffbef86c887cecad7e3cecda424ce6a64d0b5441c63b5b015d48219868660a2bb1aa15e897e565ad8867fa6b885d4358b04e1c4e589ba4c07c3fda55c
+ languageName: node
+ linkType: hard
+
"@types/react-dom@npm:16.8.4":
version: 16.8.4
resolution: "@types/react-dom@npm:16.8.4"
languageName: node
linkType: hard
-"@types/react-select@npm:1.2.6":
+"@types/react-select-legacy@npm:@types/react-select@1.2.6":
version: 1.2.6
resolution: "@types/react-select@npm:1.2.6"
dependencies:
languageName: node
linkType: hard
+"@types/react-select@npm:4.0.16":
+ version: 4.0.16
+ resolution: "@types/react-select@npm:4.0.16"
+ dependencies:
+ "@emotion/serialize": ^1.0.0
+ "@types/react": "*"
+ "@types/react-dom": "*"
+ "@types/react-transition-group": "*"
+ checksum: 33a9f5bca7ee3c945f73aa1deeadb0e1220d7721895cb81af96e828b116b9fa64d486bdecad2af8b165047023ba3a87443b43c0ac8acca09f8643f583fb97105
+ languageName: node
+ linkType: hard
+
+"@types/react-transition-group@npm:*":
+ version: 4.4.4
+ resolution: "@types/react-transition-group@npm:4.4.4"
+ dependencies:
+ "@types/react": "*"
+ checksum: 86e9ff9731798e12bc2afe0304678918769633b531dcf6397f86af81718fb7930ef8648e894eeb3718fc6eab6eb885cfb9b82a44d1d74e10951ee11ebc4643ae
+ languageName: node
+ linkType: hard
+
"@types/react-virtualized@npm:9.21.0":
version: 9.21.0
resolution: "@types/react-virtualized@npm:9.21.0"
"@types/react-modal": 3.12.1
"@types/react-redux": 6.0.6
"@types/react-router": 3.0.20
- "@types/react-select": 1.2.6
+ "@types/react-select": 4.0.16
+ "@types/react-select-legacy": "npm:@types/react-select@1.2.6"
"@types/react-virtualized": 9.21.0
"@types/sanitize-html": 1.22.0
"@types/valid-url": 1.0.2
react-modal: 3.14.3
react-redux: 5.1.1
react-router: 3.2.6
- react-select: 1.2.1
+ react-select: 4.3.1
+ react-select-legacy: "npm:react-select@1.2.1"
react-test-renderer: 16.13.0
react-virtualized: 9.21.2
redux: 4.0.5
languageName: node
linkType: hard
+"csstype@npm:^3.0.2":
+ version: 3.0.10
+ resolution: "csstype@npm:3.0.10"
+ checksum: 20a8fa324f2b33ddf94aa7507d1b6ab3daa6f3cc308888dc50126585d7952f2471de69b2dbe0635d1fdc31223fef8e070842691877e725caf456e2378685a631
+ languageName: node
+ linkType: hard
+
"cwd@npm:^0.10.0":
version: 0.10.0
resolution: "cwd@npm:0.10.0"
languageName: node
linkType: hard
+"dom-helpers@npm:^5.0.1":
+ version: 5.2.1
+ resolution: "dom-helpers@npm:5.2.1"
+ dependencies:
+ "@babel/runtime": ^7.8.7
+ csstype: ^3.0.2
+ checksum: 863ba9e086f7093df3376b43e74ce4422571d404fc9828bf2c56140963d5edf0e56160f9b2f3bb61b282c07f8fc8134f023c98fd684bddcb12daf7b0f14d951c
+ languageName: node
+ linkType: hard
+
"dom-serializer@npm:0, dom-serializer@npm:~0.1.1":
version: 0.1.1
resolution: "dom-serializer@npm:0.1.1"
languageName: node
linkType: hard
-"hoist-non-react-statics@npm:^3.3.2":
+"hoist-non-react-statics@npm:^3.3.1, hoist-non-react-statics@npm:^3.3.2":
version: 3.3.2
resolution: "hoist-non-react-statics@npm:3.3.2"
dependencies:
languageName: node
linkType: hard
+"memoize-one@npm:^5.0.0":
+ version: 5.2.1
+ resolution: "memoize-one@npm:5.2.1"
+ checksum: a3cba7b824ebcf24cdfcd234aa7f86f3ad6394b8d9be4c96ff756dafb8b51c7f71320785fbc2304f1af48a0467cbbd2a409efc9333025700ed523f254cb52e3d
+ languageName: node
+ linkType: hard
+
"merge-stream@npm:^2.0.0":
version: 2.0.0
resolution: "merge-stream@npm:2.0.0"
languageName: node
linkType: hard
+"react-input-autosize@npm:^3.0.0":
+ version: 3.0.0
+ resolution: "react-input-autosize@npm:3.0.0"
+ dependencies:
+ prop-types: ^15.5.8
+ peerDependencies:
+ react: ^16.3.0 || ^17.0.0
+ checksum: cc3309ddc87446ade742c7d0e88ef089dd8b6981f21506a2bb27daf01a8803ac697f64157c4ffc7e81dfcf3892b54a4072dbc3652fd9addcf6d22dd0b87ab723
+ languageName: node
+ linkType: hard
+
"react-intl@npm:2.8.0":
version: 2.8.0
resolution: "react-intl@npm:2.8.0"
languageName: node
linkType: hard
-"react-select@npm:1.2.1":
+"react-select-legacy@npm:react-select@1.2.1":
version: 1.2.1
resolution: "react-select@npm:1.2.1"
dependencies:
languageName: node
linkType: hard
+"react-select@npm:4.3.1":
+ version: 4.3.1
+ resolution: "react-select@npm:4.3.1"
+ dependencies:
+ "@babel/runtime": ^7.12.0
+ "@emotion/cache": ^11.4.0
+ "@emotion/react": ^11.1.1
+ memoize-one: ^5.0.0
+ prop-types: ^15.6.0
+ react-input-autosize: ^3.0.0
+ react-transition-group: ^4.3.0
+ peerDependencies:
+ react: ^16.8.0 || ^17.0.0
+ react-dom: ^16.8.0 || ^17.0.0
+ checksum: e87e0b42a662ddce7957a69a3029ea769b22264c197cbd1d8bde1ce631e49c5c5f42414773364674a7a6a8431340e1ede49220583bf1dcd966b63e9bd25cfc12
+ languageName: node
+ linkType: hard
+
"react-test-renderer@npm:16.13.0":
version: 16.13.0
resolution: "react-test-renderer@npm:16.13.0"
languageName: node
linkType: hard
+"react-transition-group@npm:^4.3.0":
+ version: 4.4.2
+ resolution: "react-transition-group@npm:4.4.2"
+ dependencies:
+ "@babel/runtime": ^7.5.5
+ dom-helpers: ^5.0.1
+ loose-envify: ^1.4.0
+ prop-types: ^15.6.2
+ peerDependencies:
+ react: ">=16.6.0"
+ react-dom: ">=16.6.0"
+ checksum: b67bf5b3e86dbab72d658b9a52a3589e5960583ab28c7c66272427d8fe30d4c7de422d5046ae96bd2683cdf80cc3264b2516f5ce80cae1dbe6cf3ca6dda392c5
+ languageName: node
+ linkType: hard
+
"react-virtualized@npm:9.21.2":
version: 9.21.2
resolution: "react-virtualized@npm:9.21.2"
languageName: node
linkType: hard
+"stylis@npm:^4.0.10":
+ version: 4.0.10
+ resolution: "stylis@npm:4.0.10"
+ checksum: 0fecaf5c234ec3ffcb0afc21478742a815a21cb964365259789be9c1692e72e13d8c081c1150fd76ed2146633a3251cdecd6e0c120b158f44bd74c38f81cafb3
+ languageName: node
+ linkType: hard
+
"stylus@npm:^0.x":
version: 0.55.0
resolution: "stylus@npm:0.55.0"