You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

DiscreetSelect.tsx 3.2KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
  1. /*
  2. * SonarQube
  3. * Copyright (C) 2009-2024 SonarSource SA
  4. * mailto:info AT sonarsource DOT com
  5. *
  6. * This program is free software; you can redistribute it and/or
  7. * modify it under the terms of the GNU Lesser General Public
  8. * License as published by the Free Software Foundation; either
  9. * version 3 of the License, or (at your option) any later version.
  10. *
  11. * This program is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  14. * Lesser General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU Lesser General Public License
  17. * along with this program; if not, write to the Free Software Foundation,
  18. * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  19. */
  20. import styled from '@emotion/styled';
  21. import tw from 'twin.macro';
  22. import { themeBorder, themeColor, themeContrast } from '../../helpers/theme';
  23. import { InputSizeKeys } from '../../types/theme';
  24. import { InputSelect, LabelValueSelectOption } from './InputSelect';
  25. interface Props<V> {
  26. className?: string;
  27. components?: Parameters<typeof InputSelect>[0]['components'];
  28. customValue?: JSX.Element;
  29. isDisabled?: boolean;
  30. menuIsOpen?: boolean;
  31. onMenuClose?: () => void;
  32. onMenuOpen?: () => void;
  33. options: Array<LabelValueSelectOption<V>>;
  34. setValue: ({ value }: LabelValueSelectOption<V>) => void;
  35. size?: InputSizeKeys;
  36. value: V;
  37. }
  38. export function DiscreetSelect<V>({
  39. className,
  40. customValue,
  41. onMenuOpen,
  42. options,
  43. size = 'small',
  44. setValue,
  45. value,
  46. ...props
  47. }: Props<V>) {
  48. return (
  49. <StyledSelect
  50. className={className}
  51. onChange={setValue}
  52. onMenuOpen={onMenuOpen}
  53. options={options}
  54. placeholder={customValue}
  55. size={size}
  56. value={options.find((item) => item.value === value)}
  57. {...props}
  58. />
  59. );
  60. }
  61. const StyledSelect = styled(InputSelect)`
  62. & {
  63. width: inherit !important;
  64. }
  65. & .react-select__dropdown-indicator {
  66. ${tw`sw-p-0 sw-py-1`};
  67. }
  68. & .react-select__value-container {
  69. ${tw`sw-p-0`};
  70. }
  71. & .react-select__menu {
  72. margin: 0;
  73. }
  74. & .react-select__control {
  75. height: auto;
  76. min-height: inherit;
  77. color: ${themeContrast('discreetBackground')};
  78. background: none;
  79. outline: inherit;
  80. box-shadow: none;
  81. ${tw`sw-border-none`};
  82. ${tw`sw-p-0`};
  83. ${tw`sw-cursor-pointer`};
  84. ${tw`sw-flex sw-items-center`};
  85. ${tw`sw-body-sm`};
  86. ${tw`sw-select-none`};
  87. &:hover {
  88. ${tw`sw-border-none`};
  89. outline: none;
  90. color: ${themeColor('discreetButtonHover')};
  91. border-color: inherit;
  92. box-shadow: none;
  93. & .react-select__single-value,
  94. & .react-select__dropdown-indicator,
  95. & .react-select__placeholder {
  96. color: ${themeColor('discreetButtonHover')};
  97. }
  98. }
  99. &:focus {
  100. ${tw`sw-rounded-1`};
  101. color: ${themeColor('discreetButtonHover')};
  102. background: ${themeColor('discreetBackground')};
  103. outline: ${themeBorder('focus', 'discreetFocusBorder')};
  104. border-color: inherit;
  105. box-shadow: none;
  106. }
  107. }
  108. & .react-select__control--is-focused,
  109. & .react-select__control--menu-is-open {
  110. ${tw`sw-border-none`};
  111. }
  112. `;