Select.tsx 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157
  1. // Libraries
  2. import classNames from 'classnames';
  3. import React, { PureComponent } from 'react';
  4. import { default as ReactSelect } from 'react-select';
  5. import { default as ReactAsyncSelect } from 'react-select/lib/Async';
  6. // Components
  7. import { Option, SingleValue } from './PickerOption';
  8. import IndicatorsContainer from './IndicatorsContainer';
  9. import NoOptionsMessage from './NoOptionsMessage';
  10. import ResetStyles from './ResetStyles';
  11. export interface SelectOptionItem {
  12. label?: string;
  13. value?: string;
  14. imgUrl?: string;
  15. description?: string;
  16. [key: string]: any;
  17. }
  18. interface CommonProps {
  19. defaultValue?: any;
  20. getOptionLabel?: (item: SelectOptionItem) => string;
  21. getOptionValue?: (item: SelectOptionItem) => string;
  22. onChange: (item: SelectOptionItem) => {} | void;
  23. placeholder?: string;
  24. width?: number;
  25. value?: SelectOptionItem;
  26. className?: string;
  27. components: object;
  28. }
  29. interface SelectProps {
  30. options: SelectOptionItem[];
  31. }
  32. interface AsyncProps {
  33. defaultOptions: boolean;
  34. loadOptions: (query: string) => Promise<SelectOptionItem[]>;
  35. isLoading: boolean;
  36. loadingMessage?: () => string;
  37. noOptionsMessage?: () => string;
  38. }
  39. export class Select extends PureComponent<CommonProps & SelectProps> {
  40. static defaultProps = {
  41. width: null,
  42. className: '',
  43. components: {},
  44. };
  45. render() {
  46. const {
  47. defaultValue,
  48. getOptionLabel,
  49. getOptionValue,
  50. onChange,
  51. options,
  52. placeholder,
  53. width,
  54. value,
  55. className,
  56. } = this.props;
  57. let widthClass = '';
  58. if (width) {
  59. widthClass = 'width-' + width;
  60. }
  61. const selectClassNames = classNames('gf-form-input', 'gf-form-input--form-dropdown', widthClass, className);
  62. return (
  63. <ReactSelect
  64. classNamePrefix="gf-form-select-box"
  65. className={selectClassNames}
  66. components={{
  67. Option,
  68. SingleValue,
  69. IndicatorsContainer,
  70. }}
  71. defaultValue={defaultValue}
  72. value={value}
  73. getOptionLabel={getOptionLabel}
  74. getOptionValue={getOptionValue}
  75. menuShouldScrollIntoView={false}
  76. isSearchable={false}
  77. onChange={onChange}
  78. options={options}
  79. placeholder={placeholder || 'Choose'}
  80. styles={ResetStyles}
  81. />
  82. );
  83. }
  84. }
  85. export class AsyncSelect extends PureComponent<CommonProps & AsyncProps> {
  86. static defaultProps = {
  87. width: null,
  88. className: '',
  89. components: {},
  90. loadingMessage: () => 'Loading...',
  91. };
  92. render() {
  93. const {
  94. defaultValue,
  95. getOptionLabel,
  96. getOptionValue,
  97. onChange,
  98. placeholder,
  99. width,
  100. value,
  101. className,
  102. loadOptions,
  103. defaultOptions,
  104. isLoading,
  105. loadingMessage,
  106. noOptionsMessage,
  107. } = this.props;
  108. let widthClass = '';
  109. if (width) {
  110. widthClass = 'width-' + width;
  111. }
  112. const selectClassNames = classNames('gf-form-input', 'gf-form-input--form-dropdown', widthClass, className);
  113. return (
  114. <ReactAsyncSelect
  115. classNamePrefix="gf-form-select-box"
  116. className={selectClassNames}
  117. components={{
  118. Option,
  119. SingleValue,
  120. IndicatorsContainer,
  121. NoOptionsMessage,
  122. }}
  123. defaultValue={defaultValue}
  124. value={value}
  125. getOptionLabel={getOptionLabel}
  126. getOptionValue={getOptionValue}
  127. menuShouldScrollIntoView={false}
  128. isSearchable={false}
  129. onChange={onChange}
  130. loadOptions={loadOptions}
  131. isLoading={isLoading}
  132. defaultOptions={defaultOptions}
  133. placeholder={placeholder || 'Choose'}
  134. styles={ResetStyles}
  135. loadingMessage={loadingMessage}
  136. noOptionsMessage={noOptionsMessage}
  137. />
  138. );
  139. }
  140. }
  141. export default Select;