mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
wip: Upgrade react-select #13425
This commit is contained in:
@@ -17,6 +17,7 @@
|
||||
"@types/react": "^16.4.14",
|
||||
"@types/react-custom-scrollbars": "^4.0.5",
|
||||
"@types/react-dom": "^16.0.7",
|
||||
"@types/react-select": "^2.0.4",
|
||||
"angular-mocks": "1.6.6",
|
||||
"autoprefixer": "^6.4.0",
|
||||
"axios": "^0.17.1",
|
||||
@@ -157,7 +158,7 @@
|
||||
"react-highlight-words": "^0.10.0",
|
||||
"react-popper": "^0.7.5",
|
||||
"react-redux": "^5.0.7",
|
||||
"react-select": "^1.1.0",
|
||||
"react-select": "^2.0.0",
|
||||
"react-sizeme": "^2.3.6",
|
||||
"react-transition-group": "^2.2.1",
|
||||
"redux": "^4.0.0",
|
||||
|
||||
@@ -17,6 +17,10 @@ export interface Props {
|
||||
onCancel: () => void;
|
||||
}
|
||||
|
||||
export interface TeamSelectedAction {
|
||||
action: string;
|
||||
}
|
||||
|
||||
class AddPermissions extends Component<Props, NewDashboardAclItem> {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
@@ -50,11 +54,11 @@ class AddPermissions extends Component<Props, NewDashboardAclItem> {
|
||||
};
|
||||
|
||||
onUserSelected = (user: User) => {
|
||||
this.setState({ userId: user ? user.id : 0 });
|
||||
this.setState({ userId: user && !Array.isArray(user) ? user.id : 0 });
|
||||
};
|
||||
|
||||
onTeamSelected = (team: Team) => {
|
||||
this.setState({ teamId: team ? team.id : 0 });
|
||||
onTeamSelected = (team: Team, info: TeamSelectedAction) => {
|
||||
this.setState({ teamId: team && !Array.isArray(team) ? team.id : 0 });
|
||||
};
|
||||
|
||||
onPermissionChanged = (permission: OptionWithDescription) => {
|
||||
@@ -82,7 +86,6 @@ class AddPermissions extends Component<Props, NewDashboardAclItem> {
|
||||
const newItem = this.state;
|
||||
const pickerClassName = 'width-20';
|
||||
const isValid = this.isValid();
|
||||
|
||||
return (
|
||||
<div className="gf-form-inline cta-form">
|
||||
<button className="cta-form__close btn btn-transparent" onClick={onCancel}>
|
||||
@@ -107,21 +110,13 @@ class AddPermissions extends Component<Props, NewDashboardAclItem> {
|
||||
|
||||
{newItem.type === AclTarget.User ? (
|
||||
<div className="gf-form">
|
||||
<UserPicker
|
||||
onSelected={this.onUserSelected}
|
||||
value={newItem.userId.toString()}
|
||||
className={pickerClassName}
|
||||
/>
|
||||
<UserPicker onSelected={this.onUserSelected} value={newItem.userId} className={pickerClassName} />
|
||||
</div>
|
||||
) : null}
|
||||
|
||||
{newItem.type === AclTarget.Team ? (
|
||||
<div className="gf-form">
|
||||
<TeamPicker
|
||||
onSelected={this.onTeamSelected}
|
||||
value={newItem.teamId.toString()}
|
||||
className={pickerClassName}
|
||||
/>
|
||||
<TeamPicker onSelected={this.onTeamSelected} value={newItem.teamId} className={pickerClassName} />
|
||||
</div>
|
||||
) : null}
|
||||
|
||||
|
||||
@@ -79,7 +79,7 @@ export default class PermissionsListItem extends PureComponent<Props> {
|
||||
onSelected={this.onPermissionChanged}
|
||||
value={item.permission}
|
||||
disabled={item.inherited}
|
||||
className={'gf-form-input--form-dropdown-right'}
|
||||
className={'gf-form-select2__control--menu-right'}
|
||||
/>
|
||||
</div>
|
||||
</td>
|
||||
|
||||
@@ -1,56 +1,27 @@
|
||||
import React, { Component } from 'react';
|
||||
import React from 'react';
|
||||
import { components } from 'react-select';
|
||||
import { OptionProps } from 'react-select/lib/components/Option';
|
||||
|
||||
export interface Props {
|
||||
onSelect: any;
|
||||
onFocus: any;
|
||||
option: any;
|
||||
isFocused: any;
|
||||
className: any;
|
||||
children: Element;
|
||||
isSelected: boolean;
|
||||
data: any;
|
||||
getStyles: any;
|
||||
}
|
||||
|
||||
class DescriptionOption extends Component<Props, any> {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.handleMouseDown = this.handleMouseDown.bind(this);
|
||||
this.handleMouseEnter = this.handleMouseEnter.bind(this);
|
||||
this.handleMouseMove = this.handleMouseMove.bind(this);
|
||||
}
|
||||
|
||||
handleMouseDown(event) {
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
this.props.onSelect(this.props.option, event);
|
||||
}
|
||||
|
||||
handleMouseEnter(event) {
|
||||
this.props.onFocus(this.props.option, event);
|
||||
}
|
||||
|
||||
handleMouseMove(event) {
|
||||
if (this.props.isFocused) {
|
||||
return;
|
||||
}
|
||||
this.props.onFocus(this.props.option, event);
|
||||
}
|
||||
|
||||
render() {
|
||||
const { option, children, className } = this.props;
|
||||
export const Option = (props: OptionProps<any>) => {
|
||||
const { children, isSelected, data } = props;
|
||||
return (
|
||||
<button
|
||||
onMouseDown={this.handleMouseDown}
|
||||
onMouseEnter={this.handleMouseEnter}
|
||||
onMouseMove={this.handleMouseMove}
|
||||
title={option.title}
|
||||
className={`description-picker-option__button btn btn-link ${className} width-19`}
|
||||
>
|
||||
<components.Option {...props}>
|
||||
<div className={`description-picker-option__button btn btn-link width-19`}>
|
||||
{isSelected && <i className="fa fa-check pull-right" aria-hidden="true" />}
|
||||
<div className="gf-form">{children}</div>
|
||||
<div className="gf-form">
|
||||
<div className="muted width-17">{option.description}</div>
|
||||
{className.indexOf('is-selected') > -1 && <i className="fa fa-check" aria-hidden="true" />}
|
||||
<div className="muted width-17">{data.description}</div>
|
||||
</div>
|
||||
</button>
|
||||
</div>
|
||||
</components.Option>
|
||||
);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
export default DescriptionOption;
|
||||
export default Option;
|
||||
|
||||
@@ -1,14 +1,9 @@
|
||||
import React, { Component } from 'react';
|
||||
import Select from 'react-select';
|
||||
import DescriptionOption from './DescriptionOption';
|
||||
|
||||
export interface Props {
|
||||
optionsWithDesc: OptionWithDescription[];
|
||||
onSelected: (permission) => void;
|
||||
value: number;
|
||||
disabled: boolean;
|
||||
className?: string;
|
||||
}
|
||||
import IndicatorsContainer from './IndicatorsContainer';
|
||||
import ResetStyles from './ResetStyles';
|
||||
import NoOptionsMessage from './NoOptionsMessage';
|
||||
|
||||
export interface OptionWithDescription {
|
||||
value: any;
|
||||
@@ -16,29 +11,38 @@ export interface OptionWithDescription {
|
||||
description: string;
|
||||
}
|
||||
|
||||
export interface Props {
|
||||
optionsWithDesc: OptionWithDescription[];
|
||||
onSelected: (permission) => void;
|
||||
disabled: boolean;
|
||||
className?: string;
|
||||
}
|
||||
|
||||
class DescriptionPicker extends Component<Props, any> {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {};
|
||||
}
|
||||
|
||||
render() {
|
||||
const { optionsWithDesc, onSelected, value, disabled, className } = this.props;
|
||||
|
||||
const { optionsWithDesc, onSelected, disabled, className } = this.props;
|
||||
return (
|
||||
<div className="permissions-picker">
|
||||
<Select
|
||||
value={value}
|
||||
valueKey="value"
|
||||
multi={false}
|
||||
clearable={false}
|
||||
labelKey="label"
|
||||
options={optionsWithDesc}
|
||||
onChange={onSelected}
|
||||
className={`width-7 gf-form-input gf-form-input--form-dropdown ${className || ''}`}
|
||||
optionComponent={DescriptionOption}
|
||||
placeholder="Choose"
|
||||
disabled={disabled}
|
||||
classNamePrefix={`gf-form-select2`}
|
||||
className={`width-7 gf-form-input gf-form-input--form-dropdown ${className || ''}`}
|
||||
options={optionsWithDesc}
|
||||
components={{
|
||||
Option: DescriptionOption,
|
||||
IndicatorsContainer,
|
||||
NoOptionsMessage,
|
||||
}}
|
||||
styles={ResetStyles}
|
||||
isDisabled={disabled}
|
||||
onChange={onSelected}
|
||||
getOptionValue={i => i.value}
|
||||
getOptionLabel={i => i.label}
|
||||
// menuIsOpen={true} // debug
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
|
||||
13
public/app/core/components/Picker/IndicatorsContainer.tsx
Normal file
13
public/app/core/components/Picker/IndicatorsContainer.tsx
Normal file
@@ -0,0 +1,13 @@
|
||||
import React from 'react';
|
||||
import { components } from 'react-select';
|
||||
|
||||
export const IndicatorsContainer = props => {
|
||||
const isOpen = props.selectProps.menuIsOpen;
|
||||
return (
|
||||
<components.IndicatorsContainer {...props}>
|
||||
<span className={`gf-form-select2__select-arrow ${isOpen ? `gf-form-select2__select-arrow--reversed` : ''}`} />
|
||||
</components.IndicatorsContainer>
|
||||
);
|
||||
};
|
||||
|
||||
export default IndicatorsContainer;
|
||||
18
public/app/core/components/Picker/NoOptionsMessage.tsx
Normal file
18
public/app/core/components/Picker/NoOptionsMessage.tsx
Normal file
@@ -0,0 +1,18 @@
|
||||
import React from 'react';
|
||||
import { components } from 'react-select';
|
||||
import { OptionProps } from 'react-select/lib/components/Option';
|
||||
|
||||
export interface Props {
|
||||
children: Element;
|
||||
}
|
||||
|
||||
export const PickerOption = (props: OptionProps<any>) => {
|
||||
const { children } = props;
|
||||
return (
|
||||
<components.Option {...props}>
|
||||
<div className={`description-picker-option__button btn btn-link width-19`}>{children}</div>
|
||||
</components.Option>
|
||||
);
|
||||
};
|
||||
|
||||
export default PickerOption;
|
||||
@@ -1,54 +1,25 @@
|
||||
import React, { Component } from 'react';
|
||||
import React from 'react';
|
||||
import { components } from 'react-select';
|
||||
import { OptionProps } from 'react-select/lib/components/Option';
|
||||
|
||||
export interface Props {
|
||||
onSelect: any;
|
||||
onFocus: any;
|
||||
option: any;
|
||||
isFocused: any;
|
||||
className: any;
|
||||
children: Element;
|
||||
isSelected: boolean;
|
||||
data: any;
|
||||
getStyles: any;
|
||||
className?: string;
|
||||
}
|
||||
|
||||
class UserPickerOption extends Component<Props, any> {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.handleMouseDown = this.handleMouseDown.bind(this);
|
||||
this.handleMouseEnter = this.handleMouseEnter.bind(this);
|
||||
this.handleMouseMove = this.handleMouseMove.bind(this);
|
||||
}
|
||||
|
||||
handleMouseDown(event) {
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
this.props.onSelect(this.props.option, event);
|
||||
}
|
||||
|
||||
handleMouseEnter(event) {
|
||||
this.props.onFocus(this.props.option, event);
|
||||
}
|
||||
|
||||
handleMouseMove(event) {
|
||||
if (this.props.isFocused) {
|
||||
return;
|
||||
}
|
||||
this.props.onFocus(this.props.option, event);
|
||||
}
|
||||
|
||||
render() {
|
||||
const { option, children, className } = this.props;
|
||||
|
||||
export const PickerOption = (props: OptionProps<any>) => {
|
||||
const { children, data } = props;
|
||||
return (
|
||||
<button
|
||||
onMouseDown={this.handleMouseDown}
|
||||
onMouseEnter={this.handleMouseEnter}
|
||||
onMouseMove={this.handleMouseMove}
|
||||
title={option.title}
|
||||
className={`user-picker-option__button btn btn-link ${className}`}
|
||||
>
|
||||
<img src={option.avatarUrl} alt={option.label} className="user-picker-option__avatar" />
|
||||
<components.Option {...props}>
|
||||
<div className={`description-picker-option__button btn btn-link width-19`}>
|
||||
<img src={data.avatarUrl} alt={data.label} className="user-picker-option__avatar" />
|
||||
{children}
|
||||
</button>
|
||||
</div>
|
||||
</components.Option>
|
||||
);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
export default UserPickerOption;
|
||||
export default PickerOption;
|
||||
|
||||
23
public/app/core/components/Picker/ResetStyles.tsx
Normal file
23
public/app/core/components/Picker/ResetStyles.tsx
Normal file
@@ -0,0 +1,23 @@
|
||||
export default {
|
||||
clearIndicator: () => ({}),
|
||||
container: () => ({}),
|
||||
control: () => ({}),
|
||||
dropdownIndicator: () => ({}),
|
||||
group: () => ({}),
|
||||
groupHeading: () => ({}),
|
||||
indicatorsContainer: () => ({}),
|
||||
indicatorSeparator: () => ({}),
|
||||
input: () => ({}),
|
||||
loadingIndicator: () => ({}),
|
||||
loadingMessage: () => ({}),
|
||||
menu: () => ({}),
|
||||
menuList: () => ({}),
|
||||
multiValue: () => ({}),
|
||||
multiValueLabel: () => ({}),
|
||||
multiValueRemove: () => ({}),
|
||||
noOptionsMessage: () => ({}),
|
||||
option: () => ({}),
|
||||
placeholder: () => ({}),
|
||||
singleValue: () => ({}),
|
||||
valueContainer: () => ({}),
|
||||
};
|
||||
@@ -1,18 +1,11 @@
|
||||
import React, { Component } from 'react';
|
||||
import Select from 'react-select';
|
||||
import AsyncSelect from 'react-select/lib/Async';
|
||||
import PickerOption from './PickerOption';
|
||||
import { debounce } from 'lodash';
|
||||
import { getBackendSrv } from 'app/core/services/backend_srv';
|
||||
|
||||
export interface Props {
|
||||
onSelected: (team: Team) => void;
|
||||
value?: string;
|
||||
className?: string;
|
||||
}
|
||||
|
||||
export interface State {
|
||||
isLoading;
|
||||
}
|
||||
import ResetStyles from './ResetStyles';
|
||||
import IndicatorsContainer from './IndicatorsContainer';
|
||||
import NoOptionsMessage from './NoOptionsMessage';
|
||||
|
||||
export interface Team {
|
||||
id: number;
|
||||
@@ -21,6 +14,15 @@ export interface Team {
|
||||
avatarUrl: string;
|
||||
}
|
||||
|
||||
export interface Props {
|
||||
onSelected: (team: Team) => void;
|
||||
className?: string;
|
||||
}
|
||||
|
||||
export interface State {
|
||||
isLoading: boolean;
|
||||
}
|
||||
|
||||
export class TeamPicker extends Component<Props, State> {
|
||||
debouncedSearch: any;
|
||||
|
||||
@@ -39,7 +41,7 @@ export class TeamPicker extends Component<Props, State> {
|
||||
const backendSrv = getBackendSrv();
|
||||
this.setState({ isLoading: true });
|
||||
|
||||
return backendSrv.get(`/api/teams/search?perpage=50&page=1&query=${query}`).then(result => {
|
||||
return backendSrv.get(`/api/teams/search?perpage=10&page=1&query=${query}`).then(result => {
|
||||
const teams = result.teams.map(team => {
|
||||
return {
|
||||
id: team.id,
|
||||
@@ -50,31 +52,35 @@ export class TeamPicker extends Component<Props, State> {
|
||||
});
|
||||
|
||||
this.setState({ isLoading: false });
|
||||
return { options: teams };
|
||||
return teams;
|
||||
});
|
||||
}
|
||||
|
||||
render() {
|
||||
const { onSelected, value, className } = this.props;
|
||||
const { onSelected, className } = this.props;
|
||||
const { isLoading } = this.state;
|
||||
|
||||
return (
|
||||
<div className="user-picker">
|
||||
<Select.Async
|
||||
valueKey="id"
|
||||
multi={false}
|
||||
labelKey="label"
|
||||
cache={false}
|
||||
<AsyncSelect
|
||||
classNamePrefix={`gf-form-select2`}
|
||||
isMulti={false}
|
||||
isLoading={isLoading}
|
||||
defaultOptions={true}
|
||||
loadOptions={this.debouncedSearch}
|
||||
loadingPlaceholder="Loading..."
|
||||
noResultsText="No teams found"
|
||||
onChange={onSelected}
|
||||
className={`gf-form-input gf-form-input--form-dropdown ${className || ''}`}
|
||||
optionComponent={PickerOption}
|
||||
styles={ResetStyles}
|
||||
components={{
|
||||
Option: PickerOption,
|
||||
IndicatorsContainer,
|
||||
NoOptionsMessage,
|
||||
}}
|
||||
placeholder="Select a team"
|
||||
value={value}
|
||||
autosize={true}
|
||||
loadingMessage={() => 'Loading...'}
|
||||
noOptionsMessage={() => 'No teams found'}
|
||||
getOptionValue={i => i.id}
|
||||
getOptionLabel={i => i.label}
|
||||
// menuIsOpen={true}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -1,13 +1,15 @@
|
||||
import React, { Component } from 'react';
|
||||
import Select from 'react-select';
|
||||
import AsyncSelect from 'react-select/lib/Async';
|
||||
import PickerOption from './PickerOption';
|
||||
import { debounce } from 'lodash';
|
||||
import { getBackendSrv } from 'app/core/services/backend_srv';
|
||||
import { User } from 'app/types';
|
||||
import ResetStyles from './ResetStyles';
|
||||
import IndicatorsContainer from './IndicatorsContainer';
|
||||
import NoOptionsMessage from './NoOptionsMessage';
|
||||
|
||||
export interface Props {
|
||||
onSelected: (user: User) => void;
|
||||
value?: string;
|
||||
className?: string;
|
||||
}
|
||||
|
||||
@@ -31,20 +33,17 @@ export class UserPicker extends Component<Props, State> {
|
||||
|
||||
search(query?: string) {
|
||||
const backendSrv = getBackendSrv();
|
||||
|
||||
this.setState({ isLoading: true });
|
||||
|
||||
return backendSrv
|
||||
.get(`/api/org/users?query=${query}&limit=10`)
|
||||
.get(`/api/org/users?query=${query}&limit=1`)
|
||||
.then(result => {
|
||||
return {
|
||||
options: result.map(user => ({
|
||||
return result.map(user => ({
|
||||
id: user.userId,
|
||||
label: `${user.login} - ${user.email}`,
|
||||
avatarUrl: user.avatarUrl,
|
||||
login: user.login,
|
||||
})),
|
||||
};
|
||||
}));
|
||||
})
|
||||
.finally(() => {
|
||||
this.setState({ isLoading: false });
|
||||
@@ -52,26 +51,31 @@ export class UserPicker extends Component<Props, State> {
|
||||
}
|
||||
|
||||
render() {
|
||||
const { value, className } = this.props;
|
||||
const { className, onSelected } = this.props;
|
||||
const { isLoading } = this.state;
|
||||
|
||||
return (
|
||||
<div className="user-picker">
|
||||
<Select.Async
|
||||
valueKey="id"
|
||||
multi={false}
|
||||
labelKey="label"
|
||||
cache={false}
|
||||
<AsyncSelect
|
||||
classNamePrefix={`gf-form-select2`}
|
||||
isMulti={false}
|
||||
isLoading={isLoading}
|
||||
defaultOptions={true}
|
||||
loadOptions={this.debouncedSearch}
|
||||
loadingPlaceholder="Loading..."
|
||||
noResultsText="No users found"
|
||||
onChange={this.props.onSelected}
|
||||
onChange={onSelected}
|
||||
className={`gf-form-input gf-form-input--form-dropdown ${className || ''}`}
|
||||
optionComponent={PickerOption}
|
||||
styles={ResetStyles}
|
||||
components={{
|
||||
Option: PickerOption,
|
||||
IndicatorsContainer,
|
||||
NoOptionsMessage,
|
||||
}}
|
||||
placeholder="Select user"
|
||||
value={value}
|
||||
autosize={true}
|
||||
loadingMessage={() => 'Loading...'}
|
||||
noOptionsMessage={() => 'No users found'}
|
||||
getOptionValue={i => i.id}
|
||||
getOptionLabel={i => i.label}
|
||||
// menuIsOpen={true}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
|
||||
21
public/app/core/components/Picker/ValueContainer.tsx
Normal file
21
public/app/core/components/Picker/ValueContainer.tsx
Normal file
@@ -0,0 +1,21 @@
|
||||
import React from 'react';
|
||||
import { components } from 'react-select';
|
||||
|
||||
export const ValueContainer = props => {
|
||||
const { children, getValue, options } = props;
|
||||
console.log('getValue', getValue());
|
||||
console.log('options', options);
|
||||
const existingValue = getValue();
|
||||
const selectedOption = options.find(i => (existingValue[0] ? i.id === existingValue[0].id : undefined));
|
||||
console.log('selectedOption', selectedOption);
|
||||
return (
|
||||
<components.ValueContainer {...props}>
|
||||
{children}
|
||||
{/* {selectedOption ?
|
||||
<span>{selectedOption.label}</span>
|
||||
: children} */}
|
||||
</components.ValueContainer>
|
||||
);
|
||||
};
|
||||
|
||||
export default ValueContainer;
|
||||
@@ -85,8 +85,8 @@ export class TeamMembers extends PureComponent<Props, State> {
|
||||
render() {
|
||||
const { newTeamMember, isAdding } = this.state;
|
||||
const { searchMemberQuery, members, syncEnabled } = this.props;
|
||||
const newTeamMemberValue = newTeamMember && newTeamMember.id.toString();
|
||||
|
||||
const newTeamMemberValue = newTeamMember && newTeamMember;
|
||||
console.log('newTeamMemberValue', newTeamMemberValue);
|
||||
return (
|
||||
<div>
|
||||
<div className="page-action-bar">
|
||||
@@ -117,8 +117,7 @@ export class TeamMembers extends PureComponent<Props, State> {
|
||||
</button>
|
||||
<h5>Add Team Member</h5>
|
||||
<div className="gf-form-inline">
|
||||
<UserPicker onSelected={this.onUserSelected} className="width-30" value={newTeamMemberValue} />
|
||||
|
||||
<UserPicker onSelected={this.onUserSelected} className="width-30" />
|
||||
{this.state.newTeamMember && (
|
||||
<button className="btn btn-success gf-form-btn" type="submit" onClick={this.onAddUserToTeam}>
|
||||
Add to team
|
||||
|
||||
@@ -13,7 +13,7 @@ $select-text-color: $text-color;
|
||||
$select-input-bg-disabled: $input-bg-disabled;
|
||||
$select-option-selected-bg: $dropdownLinkBackgroundActive;
|
||||
|
||||
@import '../../../node_modules/react-select/scss/default.scss';
|
||||
// @import '../../../node_modules/react-select/scss/default.scss';
|
||||
|
||||
@mixin select-control() {
|
||||
width: 100%;
|
||||
@@ -29,6 +29,96 @@ $select-option-selected-bg: $dropdownLinkBackgroundActive;
|
||||
@include box-shadow($shadow);
|
||||
}
|
||||
|
||||
// new react-select WIP
|
||||
.gf-form-select2__control {
|
||||
@include select-control();
|
||||
border-color: $dark-3;
|
||||
|
||||
border: 1px solid #262628;
|
||||
color: #d8d9da;
|
||||
cursor: default;
|
||||
display: table;
|
||||
border-spacing: 0;
|
||||
border-collapse: separate;
|
||||
height: $select-input-height;
|
||||
outline: none;
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.gf-form-select2__control--is-focused {
|
||||
background-color: $input-bg;
|
||||
@include select-control-focus();
|
||||
}
|
||||
|
||||
.gf-form-select2__control--is-disabled {
|
||||
background-color: $select-input-bg-disabled;
|
||||
}
|
||||
|
||||
.gf-form-select2__control--menu-right {
|
||||
.gf-form-select2__menu {
|
||||
right: 0;
|
||||
left: unset;
|
||||
}
|
||||
}
|
||||
|
||||
.gf-form-select2__input {
|
||||
position: absolute;
|
||||
z-index: 1;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
padding: 8px 10px;
|
||||
}
|
||||
|
||||
.gf-form-select2__menu {
|
||||
background: $select-input-bg-disabled;
|
||||
position: absolute;
|
||||
z-index: 2;
|
||||
}
|
||||
|
||||
.gf-form-select2__option {
|
||||
border-left: 2px solid transparent;
|
||||
|
||||
&.gf-form-select2__option--is-focused,
|
||||
&.gf-form-select2__option--is-selected {
|
||||
background-color: $dropdownLinkBackgroundHover;
|
||||
color: $dropdownLinkColorHover;
|
||||
@include left-brand-border-gradient();
|
||||
.fa {
|
||||
color: white;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.gf-form-select2__value-container {
|
||||
display: table-cell;
|
||||
padding: 8px 10px;
|
||||
}
|
||||
|
||||
.gf-form-select2__indicators {
|
||||
display: table-cell;
|
||||
vertical-align: middle;
|
||||
padding-right: 5px;
|
||||
width: 25px;
|
||||
}
|
||||
|
||||
.gf-form-select2__select-arrow {
|
||||
border-color: #999 transparent transparent;
|
||||
border-style: solid;
|
||||
border-width: 5px 5px 2.5px;
|
||||
display: inline-block;
|
||||
height: 0;
|
||||
width: 0;
|
||||
position: relative;
|
||||
|
||||
&.gf-form-select2__select-arrow--reversed {
|
||||
border-color: transparent transparent #999;
|
||||
top: -2px;
|
||||
border-width: 0 5px 5px;
|
||||
}
|
||||
}
|
||||
|
||||
// react-select tweaks
|
||||
.gf-form-input--form-dropdown {
|
||||
padding: 0;
|
||||
|
||||
Reference in New Issue
Block a user