@qoretechnologies/reqore 0.28.5 → 0.29.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (176) hide show
  1. package/.vscode/settings.json +2 -1
  2. package/__tests__/multiselect.test.tsx +361 -0
  3. package/__tests__/popover.test.tsx +35 -8
  4. package/dist/components/Button/index.js +3 -3
  5. package/dist/components/Button/index.js.map +1 -1
  6. package/dist/components/Checkbox/index.d.ts +3 -2
  7. package/dist/components/Checkbox/index.d.ts.map +1 -1
  8. package/dist/components/Checkbox/index.js +28 -24
  9. package/dist/components/Checkbox/index.js.map +1 -1
  10. package/dist/components/Collection/item.js +2 -2
  11. package/dist/components/Collection/item.js.map +1 -1
  12. package/dist/components/ControlGroup/index.d.ts +4 -4
  13. package/dist/components/ControlGroup/index.d.ts.map +1 -1
  14. package/dist/components/ControlGroup/index.js +13 -15
  15. package/dist/components/ControlGroup/index.js.map +1 -1
  16. package/dist/components/Dropdown/index.d.ts +2 -1
  17. package/dist/components/Dropdown/index.d.ts.map +1 -1
  18. package/dist/components/Dropdown/index.js +3 -3
  19. package/dist/components/Dropdown/index.js.map +1 -1
  20. package/dist/components/Dropdown/list.d.ts +6 -3
  21. package/dist/components/Dropdown/list.d.ts.map +1 -1
  22. package/dist/components/Dropdown/list.js +19 -1
  23. package/dist/components/Dropdown/list.js.map +1 -1
  24. package/dist/components/Effect/index.d.ts +3 -1
  25. package/dist/components/Effect/index.d.ts.map +1 -1
  26. package/dist/components/Effect/index.js +24 -19
  27. package/dist/components/Effect/index.js.map +1 -1
  28. package/dist/components/Icon/index.d.ts +12 -2
  29. package/dist/components/Icon/index.d.ts.map +1 -1
  30. package/dist/components/Icon/index.js +35 -4
  31. package/dist/components/Icon/index.js.map +1 -1
  32. package/dist/components/Input/index.js +3 -3
  33. package/dist/components/Input/index.js.map +1 -1
  34. package/dist/components/InputClearButton/index.d.ts.map +1 -1
  35. package/dist/components/InputClearButton/index.js +1 -1
  36. package/dist/components/InputClearButton/index.js.map +1 -1
  37. package/dist/components/InternalPopover/index.d.ts.map +1 -1
  38. package/dist/components/InternalPopover/index.js +31 -37
  39. package/dist/components/InternalPopover/index.js.map +1 -1
  40. package/dist/components/Menu/divider.d.ts +5 -2
  41. package/dist/components/Menu/divider.d.ts.map +1 -1
  42. package/dist/components/Menu/divider.js +41 -8
  43. package/dist/components/Menu/divider.js.map +1 -1
  44. package/dist/components/Menu/index.js +4 -3
  45. package/dist/components/Menu/index.js.map +1 -1
  46. package/dist/components/Message/index.d.ts +3 -2
  47. package/dist/components/Message/index.d.ts.map +1 -1
  48. package/dist/components/Message/index.js.map +1 -1
  49. package/dist/components/MultiSelect/index.d.ts +32 -0
  50. package/dist/components/MultiSelect/index.d.ts.map +1 -0
  51. package/dist/components/MultiSelect/index.js +177 -0
  52. package/dist/components/MultiSelect/index.js.map +1 -0
  53. package/dist/components/Notifications/notification.d.ts +3 -3
  54. package/dist/components/Notifications/notification.d.ts.map +1 -1
  55. package/dist/components/Notifications/notification.js +11 -8
  56. package/dist/components/Notifications/notification.js.map +1 -1
  57. package/dist/components/Panel/index.d.ts +1 -0
  58. package/dist/components/Panel/index.d.ts.map +1 -1
  59. package/dist/components/Panel/index.js +7 -7
  60. package/dist/components/Panel/index.js.map +1 -1
  61. package/dist/components/Popover/index.d.ts +1 -1
  62. package/dist/components/Popover/index.d.ts.map +1 -1
  63. package/dist/components/Popover/index.js +5 -2
  64. package/dist/components/Popover/index.js.map +1 -1
  65. package/dist/components/RadioGroup/index.d.ts +8 -6
  66. package/dist/components/RadioGroup/index.d.ts.map +1 -1
  67. package/dist/components/RadioGroup/index.js +6 -12
  68. package/dist/components/RadioGroup/index.js.map +1 -1
  69. package/dist/components/Table/row.js +2 -2
  70. package/dist/components/Table/row.js.map +1 -1
  71. package/dist/components/Tabs/item.js +1 -1
  72. package/dist/components/Tabs/item.js.map +1 -1
  73. package/dist/components/Tabs/list.d.ts.map +1 -1
  74. package/dist/components/Tabs/list.js +5 -4
  75. package/dist/components/Tabs/list.js.map +1 -1
  76. package/dist/components/Tag/group.d.ts +4 -3
  77. package/dist/components/Tag/group.d.ts.map +1 -1
  78. package/dist/components/Tag/group.js +12 -5
  79. package/dist/components/Tag/group.js.map +1 -1
  80. package/dist/components/Tag/index.js +5 -5
  81. package/dist/components/Tag/index.js.map +1 -1
  82. package/dist/components/Tree/index.js +1 -1
  83. package/dist/components/Tree/index.js.map +1 -1
  84. package/dist/constants/sizes.d.ts +7 -0
  85. package/dist/constants/sizes.d.ts.map +1 -1
  86. package/dist/constants/sizes.js +8 -1
  87. package/dist/constants/sizes.js.map +1 -1
  88. package/dist/containers/PopoverProvider.d.ts.map +1 -1
  89. package/dist/containers/PopoverProvider.js +28 -3
  90. package/dist/containers/PopoverProvider.js.map +1 -1
  91. package/dist/containers/ReqoreProvider.d.ts.map +1 -1
  92. package/dist/containers/ReqoreProvider.js +6 -5
  93. package/dist/containers/ReqoreProvider.js.map +1 -1
  94. package/dist/containers/UIProvider.d.ts +1 -0
  95. package/dist/containers/UIProvider.d.ts.map +1 -1
  96. package/dist/containers/UIProvider.js.map +1 -1
  97. package/dist/context/PopoverContext.d.ts +1 -0
  98. package/dist/context/PopoverContext.d.ts.map +1 -1
  99. package/dist/context/PopoverContext.js.map +1 -1
  100. package/dist/context/ReqoreContext.d.ts +1 -0
  101. package/dist/context/ReqoreContext.d.ts.map +1 -1
  102. package/dist/context/ReqoreContext.js +2 -1
  103. package/dist/context/ReqoreContext.js.map +1 -1
  104. package/dist/helpers/colors.d.ts +3 -0
  105. package/dist/helpers/colors.d.ts.map +1 -1
  106. package/dist/helpers/colors.js +28 -5
  107. package/dist/helpers/colors.js.map +1 -1
  108. package/dist/hooks/usePopover.d.ts +14 -3
  109. package/dist/hooks/usePopover.d.ts.map +1 -1
  110. package/dist/hooks/usePopover.js +12 -7
  111. package/dist/hooks/usePopover.js.map +1 -1
  112. package/dist/hooks/useReqore.d.ts +3 -0
  113. package/dist/hooks/useReqore.d.ts.map +1 -0
  114. package/dist/hooks/useReqore.js +17 -0
  115. package/dist/hooks/useReqore.js.map +1 -0
  116. package/dist/hooks/useTheme.d.ts +1 -1
  117. package/dist/hooks/useTheme.d.ts.map +1 -1
  118. package/dist/hooks/useTheme.js +3 -0
  119. package/dist/hooks/useTheme.js.map +1 -1
  120. package/dist/index.d.ts +3 -0
  121. package/dist/index.d.ts.map +1 -1
  122. package/dist/index.js +8 -2
  123. package/dist/index.js.map +1 -1
  124. package/package.json +1 -1
  125. package/src/components/Button/index.tsx +3 -3
  126. package/src/components/Checkbox/index.tsx +58 -30
  127. package/src/components/Collection/item.tsx +2 -2
  128. package/src/components/ControlGroup/index.tsx +54 -37
  129. package/src/components/Dropdown/index.tsx +7 -2
  130. package/src/components/Dropdown/list.tsx +29 -15
  131. package/src/components/Effect/index.tsx +58 -51
  132. package/src/components/Icon/index.tsx +75 -1
  133. package/src/components/Input/index.tsx +3 -3
  134. package/src/components/InputClearButton/index.tsx +1 -0
  135. package/src/components/InternalPopover/index.tsx +108 -50
  136. package/src/components/Menu/divider.tsx +35 -7
  137. package/src/components/Menu/index.tsx +3 -3
  138. package/src/components/Message/index.tsx +3 -0
  139. package/src/components/MultiSelect/index.tsx +283 -0
  140. package/src/components/Notifications/notification.tsx +23 -13
  141. package/src/components/Panel/index.tsx +14 -8
  142. package/src/components/Popover/index.tsx +8 -3
  143. package/src/components/RadioGroup/index.tsx +36 -27
  144. package/src/components/Table/row.tsx +2 -2
  145. package/src/components/Tabs/item.tsx +1 -1
  146. package/src/components/Tabs/list.tsx +11 -11
  147. package/src/components/Tag/group.tsx +15 -4
  148. package/src/components/Tag/index.tsx +7 -7
  149. package/src/components/Tree/index.tsx +3 -3
  150. package/src/constants/sizes.ts +8 -0
  151. package/src/containers/PopoverProvider.tsx +35 -3
  152. package/src/containers/ReqoreProvider.tsx +6 -4
  153. package/src/containers/UIProvider.tsx +1 -0
  154. package/src/context/PopoverContext.tsx +1 -0
  155. package/src/context/ReqoreContext.tsx +2 -0
  156. package/src/helpers/colors.ts +53 -7
  157. package/src/hooks/usePopover.tsx +39 -12
  158. package/src/hooks/useReqore.ts +12 -0
  159. package/src/hooks/useTheme.ts +6 -1
  160. package/src/index.tsx +3 -0
  161. package/src/mock/multiSelect.ts +61 -0
  162. package/src/stories/Button/Button.stories.tsx +20 -8
  163. package/src/stories/ControlGroup/ControlGroup.stories.tsx +13 -2
  164. package/src/stories/Dropdown/Dropdown.stories.tsx +6 -1
  165. package/src/stories/Icon/Icon.stories.tsx +99 -22
  166. package/src/stories/Input/Input.stories.tsx +25 -0
  167. package/src/stories/Menu/Menu.stories.tsx +3 -2
  168. package/src/stories/Message/Message.stories.tsx +7 -1
  169. package/src/stories/MultiSelect/MultiSelect.stories.tsx +99 -0
  170. package/src/stories/Panel/Panel.stories.tsx +3 -3
  171. package/src/stories/Popover/Popover.stories.tsx +91 -12
  172. package/src/stories/RadioGroup/RadioGroup.stories.tsx +29 -2
  173. package/src/stories/Tabs/Tabs.stories.tsx +23 -3
  174. package/src/stories/Tag/Tag.stories.tsx +12 -3
  175. package/src/stories/utils/args.ts +13 -0
  176. package/tests.json +1 -1
@@ -1,20 +1,27 @@
1
1
  import { rgba } from 'polished';
2
2
  import React, { forwardRef } from 'react';
3
3
  import styled, { css } from 'styled-components';
4
- import { SIZE_TO_PX, TEXT_FROM_SIZE, TSizes } from '../../constants/sizes';
4
+ import { PADDING_FROM_SIZE, SIZE_TO_PX, TEXT_FROM_SIZE, TSizes } from '../../constants/sizes';
5
5
  import { IReqoreTheme } from '../../constants/theme';
6
6
  import { getReadableColor } from '../../helpers/colors';
7
7
  import { useCombinedRefs } from '../../hooks/useCombinedRefs';
8
8
  import { useTooltip } from '../../hooks/useTooltip';
9
9
  import { DisabledElement, ReadOnlyElement } from '../../styles';
10
- import { IReqoreDisabled, IReqoreReadOnly, TReqoreTooltipProp } from '../../types/global';
10
+ import {
11
+ IReqoreDisabled,
12
+ IReqoreReadOnly,
13
+ IWithReqoreEffect,
14
+ TReqoreTooltipProp,
15
+ } from '../../types/global';
11
16
  import { IReqoreIconName } from '../../types/icons';
17
+ import { ReqoreTextEffect } from '../Effect';
12
18
  import ReqoreIcon from '../Icon';
13
19
 
14
20
  export interface IReqoreCheckboxProps
15
21
  extends React.HTMLAttributes<HTMLDivElement>,
16
22
  IReqoreDisabled,
17
- IReqoreReadOnly {
23
+ IReqoreReadOnly,
24
+ IWithReqoreEffect {
18
25
  label?: string;
19
26
  labelDetail?: any;
20
27
  labelDetailPosition?: 'left' | 'right';
@@ -27,12 +34,35 @@ export interface IReqoreCheckboxProps
27
34
  asSwitch?: boolean;
28
35
  uncheckedIcon?: IReqoreIconName;
29
36
  checkedIcon?: IReqoreIconName;
37
+ image?: string;
30
38
  }
31
39
 
32
40
  export interface IReqoreCheckboxStyle extends IReqoreCheckboxProps {
33
41
  theme: IReqoreTheme;
34
42
  }
35
43
 
44
+ const StyledSwitchToggle = styled.div`
45
+ transition: all 0.2s ease-in-out;
46
+ content: '';
47
+ display: flex;
48
+ align-items: center;
49
+ justify-content: center;
50
+ position: absolute;
51
+ height: ${({ size }) => SIZE_TO_PX[size] - 13}px;
52
+ width: ${({ size }) => SIZE_TO_PX[size] - 13}px;
53
+ top: 50%;
54
+ transform: translateY(-50%);
55
+ left: ${({ checked, size }) =>
56
+ !checked ? '5px' : `${SIZE_TO_PX[size] * 1.8 - (SIZE_TO_PX[size] - 7)}px`};
57
+ border-radius: 100%;
58
+ background-color: ${({ theme, checked, transparent }) =>
59
+ transparent
60
+ ? 'transparent'
61
+ : !checked
62
+ ? rgba(getReadableColor(theme, undefined, undefined), 0.2)
63
+ : getReadableColor(theme, undefined, undefined)};
64
+ `;
65
+
36
66
  const StyledSwitch = styled.div<IReqoreCheckboxStyle>`
37
67
  transition: all 0.2s ease-out;
38
68
  position: relative;
@@ -42,32 +72,14 @@ const StyledSwitch = styled.div<IReqoreCheckboxStyle>`
42
72
 
43
73
  border: 1px solid
44
74
  ${({ theme, checked }) =>
45
- rgba(getReadableColor(theme, undefined, undefined), checked ? 0.6 : 0.3)};
75
+ rgba(getReadableColor(theme, undefined, undefined), checked ? 0.8 : 0.2)};
46
76
  border-radius: 50px;
47
77
 
48
- margin-right: ${({ labelPosition }) => labelPosition === 'right' && '8px'};
49
- margin-left: ${({ labelPosition }) => labelPosition === 'left' && '8px'};
78
+ margin-right: ${({ size }) => PADDING_FROM_SIZE[size]}px;
79
+ margin-left: ${({ size }) => PADDING_FROM_SIZE[size]}px;
50
80
 
51
81
  background-color: ${({ theme, checked }) =>
52
- checked ? rgba(getReadableColor(theme, undefined, undefined), 0.2) : 'transparent'};
53
-
54
- &::before {
55
- transition: all 0.2s ease-in-out;
56
- content: '';
57
- display: block;
58
- position: absolute;
59
- height: ${({ size }) => SIZE_TO_PX[size] - 13}px;
60
- width: ${({ size }) => SIZE_TO_PX[size] - 13}px;
61
- top: 50%;
62
- transform: translateY(-50%);
63
- left: ${({ checked, size }) =>
64
- !checked ? '5px' : `${SIZE_TO_PX[size] * 1.8 - (SIZE_TO_PX[size] - 7)}px`};
65
- border-radius: 100%;
66
- background-color: ${({ theme, checked }) =>
67
- !checked
68
- ? rgba(getReadableColor(theme, undefined, undefined), 0.2)
69
- : getReadableColor(theme, undefined, undefined)};
70
- }
82
+ checked ? rgba(getReadableColor(theme, undefined, undefined), 0.1) : 'transparent'};
71
83
  `;
72
84
 
73
85
  const StyledCheckbox = styled.div<IReqoreCheckboxStyle>`
@@ -122,6 +134,8 @@ const Checkbox = forwardRef<HTMLDivElement, IReqoreCheckboxProps>(
122
134
  uncheckedIcon = 'CheckboxBlankCircleLine',
123
135
  checkedIcon = 'CheckboxCircleFill',
124
136
  readOnly,
137
+ effect,
138
+ image,
125
139
  ...rest
126
140
  }: IReqoreCheckboxProps,
127
141
  ref
@@ -143,23 +157,37 @@ const Checkbox = forwardRef<HTMLDivElement, IReqoreCheckboxProps>(
143
157
  {label && labelPosition === 'left' ? (
144
158
  <>
145
159
  {labelDetailPosition === 'left' && labelDetail}
146
- <span>{label}</span>
160
+ <ReqoreTextEffect
161
+ effect={{ ...effect, interactive: !disabled && !readOnly && !checked }}
162
+ >
163
+ {label}
164
+ </ReqoreTextEffect>
147
165
  {labelDetailPosition === 'right' && labelDetail}
148
166
  </>
149
167
  ) : null}
150
168
  {asSwitch ? (
151
- <StyledSwitch size={size} labelPosition={labelPosition} checked={checked} />
169
+ <StyledSwitch size={size} labelPosition={labelPosition} checked={checked}>
170
+ <StyledSwitchToggle size={size} checked={checked} transparent={!!image}>
171
+ {image ? <ReqoreIcon size={size} image={image} grayscale={!checked} /> : null}
172
+ </StyledSwitchToggle>
173
+ </StyledSwitch>
152
174
  ) : (
153
175
  <ReqoreIcon
154
176
  size={size}
155
- icon={checked ? checkedIcon : uncheckedIcon}
156
- margin={labelPosition}
177
+ icon={!image ? (checked ? checkedIcon : uncheckedIcon) : undefined}
178
+ image={image}
179
+ grayscale={image ? !checked : undefined}
180
+ margin='both'
157
181
  />
158
182
  )}
159
183
  {label && labelPosition === 'right' ? (
160
184
  <>
161
185
  {labelDetailPosition === 'left' && labelDetail}
162
- <span>{label}</span>
186
+ <ReqoreTextEffect
187
+ effect={{ ...effect, interactive: !disabled && !readOnly && !checked }}
188
+ >
189
+ {label}
190
+ </ReqoreTextEffect>
163
191
  {labelDetailPosition === 'right' && labelDetail}
164
192
  </>
165
193
  ) : null}
@@ -170,7 +170,7 @@ export const ReqoreCollectionItem = ({
170
170
  setIsSelected(!isSelected);
171
171
  }
172
172
 
173
- rest?.onClick?.(event);
173
+ rest.onClick?.(event);
174
174
  };
175
175
 
176
176
  const actualContent: string | React.ReactNode =
@@ -239,5 +239,5 @@ export const ReqoreCollectionItem = ({
239
239
  );
240
240
  };
241
241
 
242
- return isSelected ? renderContent() : renderContent();
242
+ return renderContent();
243
243
  };
@@ -1,15 +1,19 @@
1
- import React from 'react';
1
+ import React, { forwardRef } from 'react';
2
2
  import styled, { css } from 'styled-components';
3
- import { RADIUS_FROM_SIZE, TSizes } from '../../constants/sizes';
3
+ import { GAP_FROM_SIZE, RADIUS_FROM_SIZE, TSizes } from '../../constants/sizes';
4
4
  import { IReqoreTheme } from '../../constants/theme';
5
+ import { IWithReqoreFlat, IWithReqoreMinimal, IWithReqoreSize } from '../../types/global';
5
6
 
6
- export interface IReqoreControlGroupProps extends React.HTMLAttributes<HTMLDivElement> {
7
+ export interface IReqoreControlGroupProps
8
+ extends React.HTMLAttributes<HTMLDivElement>,
9
+ IWithReqoreFlat,
10
+ IWithReqoreSize,
11
+ IWithReqoreMinimal {
7
12
  stack?: boolean;
8
- minimal?: boolean;
9
- size?: TSizes;
10
13
  children: any;
11
14
  fluid?: boolean;
12
15
  rounded?: boolean;
16
+ gapSize?: TSizes;
13
17
  /*
14
18
  * Whether the contents of the control group should be stacked vertically
15
19
  */
@@ -39,7 +43,8 @@ export const StyledReqoreControlGroup = styled.div<IReqoreControlGroupStyle>`
39
43
  > .reqore-tag,
40
44
  > * {
41
45
  &:not(:last-child) {
42
- margin-bottom: ${({ stack }) => (!stack ? '5px' : undefined)};
46
+ margin-bottom: ${({ stack, gapSize }) =>
47
+ !stack ? `${GAP_FROM_SIZE[gapSize]}px` : undefined};
43
48
  border-bottom: ${({ stack }) => (!stack ? undefined : 0)};
44
49
  }
45
50
 
@@ -61,7 +66,8 @@ export const StyledReqoreControlGroup = styled.div<IReqoreControlGroupStyle>`
61
66
  }
62
67
 
63
68
  > .reqore-control-wrapper:not(:last-child) .reqore-control {
64
- margin-bottom: ${({ stack }) => (!stack ? '5px' : undefined)};
69
+ margin-bottom: ${({ stack, gapSize }) =>
70
+ !stack ? `${GAP_FROM_SIZE[gapSize]}px` : undefined};
65
71
  border-bottom: ${({ stack }) => (!stack ? undefined : 0)};
66
72
  }
67
73
  `
@@ -71,7 +77,8 @@ export const StyledReqoreControlGroup = styled.div<IReqoreControlGroupStyle>`
71
77
  > .reqore-tag,
72
78
  > * {
73
79
  &:not(:last-child) {
74
- margin-right: ${({ stack }) => (!stack ? '5px' : undefined)};
80
+ margin-right: ${({ stack, gapSize }) =>
81
+ !stack ? `${GAP_FROM_SIZE[gapSize]}px` : undefined};
75
82
  border-right: ${({ stack }) => (!stack ? undefined : 0)};
76
83
  }
77
84
 
@@ -94,35 +101,45 @@ export const StyledReqoreControlGroup = styled.div<IReqoreControlGroupStyle>`
94
101
  `}
95
102
  `;
96
103
 
97
- const ReqoreControlGroup = ({
98
- children,
99
- className,
100
- minimal,
101
- size = 'normal',
102
- fluid,
103
- rounded = true,
104
- ...rest
105
- }: IReqoreControlGroupProps) => (
106
- <StyledReqoreControlGroup
107
- {...rest}
108
- size={size}
109
- rounded={rounded}
110
- fluid={fluid}
111
- className={`${className || ''} reqore-control-group`}
112
- >
113
- {React.Children.map(children, (child) =>
114
- child
115
- ? React.cloneElement(child, {
116
- minimal:
117
- child.props?.minimal || child.props?.minimal === false
118
- ? child.props.minimal
119
- : minimal,
120
- size: child.props?.size || size,
121
- fluid,
122
- })
123
- : null
124
- )}
125
- </StyledReqoreControlGroup>
104
+ const ReqoreControlGroup = forwardRef<HTMLDivElement, IReqoreControlGroupProps>(
105
+ (
106
+ {
107
+ children,
108
+ className,
109
+ minimal,
110
+ size = 'normal',
111
+ gapSize = 'normal',
112
+ fluid,
113
+ flat,
114
+ rounded = true,
115
+ ...rest
116
+ }: IReqoreControlGroupProps,
117
+ ref
118
+ ) => (
119
+ <StyledReqoreControlGroup
120
+ {...rest}
121
+ size={size}
122
+ gapSize={gapSize}
123
+ ref={ref}
124
+ rounded={rounded}
125
+ fluid={fluid}
126
+ className={`${className || ''} reqore-control-group`}
127
+ >
128
+ {React.Children.map(children, (child) =>
129
+ child
130
+ ? React.cloneElement(child, {
131
+ minimal:
132
+ child.props?.minimal || child.props?.minimal === false
133
+ ? child.props.minimal
134
+ : minimal,
135
+ size: child.props?.size || size,
136
+ flat: child.props?.flat || child.props?.flat === false ? child.props.flat : flat,
137
+ fluid,
138
+ })
139
+ : null
140
+ )}
141
+ </StyledReqoreControlGroup>
142
+ )
126
143
  );
127
144
 
128
145
  export default ReqoreControlGroup;
@@ -16,6 +16,7 @@ export interface IReqoreDropdownProps extends Partial<IPopoverOptions> {
16
16
  label?: any;
17
17
  children?: any;
18
18
  listWidth?: string;
19
+ listHeight?: string;
19
20
  icon?: IReqoreIconName;
20
21
  rightIcon?: IReqoreIconName;
21
22
  caretPosition?: 'left' | 'right';
@@ -47,12 +48,14 @@ function ReqoreDropdown<T extends unknown = IReqoreButtonProps>({
47
48
  maxHeight,
48
49
  maxWidth,
49
50
  noArrow = true,
50
- opaque,
51
+ transparent,
51
52
  openOnMount,
52
53
  show,
53
54
  targetElement,
54
55
  useTargetWidth,
55
56
  listWidth,
57
+ listHeight,
58
+ passPopoverData,
56
59
  ...rest
57
60
  }: IReqoreDropdownProps & T) {
58
61
  const componentProps = useMemo(
@@ -74,6 +77,7 @@ function ReqoreDropdown<T extends unknown = IReqoreButtonProps>({
74
77
  multiSelect={multiSelect}
75
78
  listStyle={listStyle}
76
79
  width={useTargetWidth ? '100%' : listWidth}
80
+ height={listHeight}
77
81
  items={items}
78
82
  filterable={filterable}
79
83
  onItemSelect={onItemSelect}
@@ -90,7 +94,7 @@ function ReqoreDropdown<T extends unknown = IReqoreButtonProps>({
90
94
  maxHeight={maxHeight}
91
95
  maxWidth={maxWidth}
92
96
  noArrow={noArrow}
93
- opaque={opaque}
97
+ transparent={transparent}
94
98
  useTargetWidth={useTargetWidth}
95
99
  component={component || ReqoreButton}
96
100
  componentProps={componentProps}
@@ -99,6 +103,7 @@ function ReqoreDropdown<T extends unknown = IReqoreButtonProps>({
99
103
  handler={handler || 'click'}
100
104
  openOnMount={isDefaultOpen}
101
105
  content={popoverContent}
106
+ passPopoverData={passPopoverData}
102
107
  >
103
108
  {children || label}
104
109
  </ReqorePopover>
@@ -2,18 +2,23 @@ import React, { memo, useEffect, useMemo, useState } from 'react';
2
2
  import { IReqoreComponent } from '../../types/global';
3
3
  import ReqoreInput from '../Input';
4
4
  import ReqoreMenu from '../Menu';
5
+ import ReqoreMenuDivider from '../Menu/divider';
5
6
  import ReqoreMenuItem, { IReqoreMenuItemProps } from '../Menu/item';
6
7
 
7
8
  export type TDropdownItemOnClick = (item: IReqoreDropdownItem) => void;
8
9
  export interface IReqoreDropdownItem
9
10
  extends Omit<IReqoreMenuItemProps, 'onClick' | 'rightIcon' | 'onRightIconClick'> {
10
- value: any;
11
- label?: string;
11
+ value?: any;
12
12
  onClick?: TDropdownItemOnClick;
13
+ divider?: boolean;
14
+ dividerAlign?: 'left' | 'center' | 'right';
13
15
  }
14
16
 
17
+ export type TReqoreDropdownItem = IReqoreDropdownItem;
18
+ export type TReqoreDropdownItems = TReqoreDropdownItem[];
19
+
15
20
  export interface IReqoreDropdownListProps extends IReqoreComponent {
16
- items?: IReqoreDropdownItem[];
21
+ items?: TReqoreDropdownItems;
17
22
  multiSelect?: boolean;
18
23
  listStyle?: React.CSSProperties;
19
24
  width?: string;
@@ -33,20 +38,24 @@ const ReqoreDropdownList = memo(
33
38
  height,
34
39
  onItemSelect,
35
40
  }: IReqoreDropdownListProps) => {
36
- const [_items, setItems] = useState<IReqoreDropdownItem[]>(items);
41
+ const [_items, setItems] = useState<TReqoreDropdownItems>(items);
37
42
  const [query, setQuery] = useState<string>('');
38
43
 
39
44
  useEffect(() => {
40
45
  setItems(items);
41
46
  }, [items]);
42
47
 
43
- const filteredItems: IReqoreDropdownItem[] = useMemo(() => {
48
+ const filteredItems: TReqoreDropdownItems = useMemo(() => {
44
49
  if (!filterable || query === '') {
45
50
  return _items;
46
51
  }
47
52
 
48
53
  return _items.filter((item) => {
49
- const text = item.label || item.value || item.children;
54
+ if (item.divider) {
55
+ return false;
56
+ }
57
+
58
+ const text: string | undefined = item.label || item.value || item.children;
50
59
 
51
60
  if (!text) {
52
61
  return false;
@@ -88,15 +97,20 @@ const ReqoreDropdownList = memo(
88
97
  />
89
98
  </>
90
99
  )}
91
- {filteredItems.map((item: IReqoreDropdownItem, index: number) => (
92
- <ReqoreMenuItem
93
- key={index}
94
- {...item}
95
- label={item.label || item.value}
96
- onClick={() => handleItemClick(item)}
97
- rightIcon={item.selected ? 'CheckLine' : undefined}
98
- />
99
- ))}
100
+ {filteredItems.map(
101
+ ({ onClick, dividerAlign, divider, ...item }: IReqoreDropdownItem, index: number) =>
102
+ divider ? (
103
+ <ReqoreMenuDivider key={index} {...item} align={dividerAlign} />
104
+ ) : (
105
+ <ReqoreMenuItem
106
+ key={index}
107
+ {...item}
108
+ label={item.label || item.value}
109
+ onClick={() => handleItemClick({ ...item, onClick })}
110
+ rightIcon={item.selected ? 'CheckLine' : undefined}
111
+ />
112
+ )
113
+ )}
100
114
  </ReqoreMenu>
101
115
  );
102
116
  }
@@ -1,14 +1,16 @@
1
- import { reduce } from 'lodash';
2
- import { mix } from 'polished';
1
+ import { rgba } from 'polished';
3
2
  import { HTMLAttributes } from 'react';
4
3
  import styled, { css } from 'styled-components';
5
4
  import { TEXT_FROM_SIZE, TSizes, WEIGHT_TO_NUMBER } from '../../constants/sizes';
6
5
  import { IReqoreTheme, TReqoreIntent } from '../../constants/theme';
7
6
  import {
8
7
  changeLightness,
8
+ createEffectGradient,
9
9
  getColorFromMaybeString,
10
+ getGradientMix,
10
11
  getReadableColorFrom,
11
12
  } from '../../helpers/colors';
13
+ import { IWithReqoreMinimal } from '../../types/global';
12
14
 
13
15
  export type TReqoreEffectColorManipulation = 'darken' | 'lighten';
14
16
  export type TReqoreEffectColorManipulationMultiplier = 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10;
@@ -53,83 +55,91 @@ export interface IReqoreEffect {
53
55
  interactive?: boolean;
54
56
  }
55
57
 
56
- export interface IReqoreTextEffectProps extends HTMLAttributes<HTMLSpanElement> {
58
+ export interface IReqoreTextEffectProps
59
+ extends HTMLAttributes<HTMLSpanElement>,
60
+ IWithReqoreMinimal {
57
61
  children: React.ReactNode;
58
62
  effect: IReqoreEffect;
59
63
  as?: React.ElementType;
60
64
  theme?: IReqoreTheme;
65
+ active?: boolean;
61
66
  }
62
67
 
63
68
  export const StyledEffect = styled.span`
64
69
  transition: all 0.2s ease-in-out;
65
70
 
66
71
  // If gradient was supplied
67
- ${({ effect, theme }: IReqoreTextEffectProps) => {
72
+ ${({ effect, theme, minimal, active }: IReqoreTextEffectProps) => {
68
73
  if (!effect || !effect.gradient) {
69
74
  return undefined;
70
75
  }
71
76
 
72
77
  const gradientType: string = effect.gradient.type || 'linear';
73
- const gradientColors = reduce(
74
- effect.gradient.colors,
75
- (colorsString, color, percentage) =>
76
- `${colorsString}, ${
77
- color === 'transparent' || !effect.interactive
78
- ? getColorFromMaybeString(theme, color)
79
- : changeLightness(getColorFromMaybeString(theme, color), 0.03)
80
- } ${percentage}%`,
81
- ''
82
- );
83
- const gradientColorsActive = reduce(
78
+ const gradientColors = createEffectGradient(
79
+ theme,
84
80
  effect.gradient.colors,
85
- (colorsString, color, percentage) =>
86
- `${colorsString}, ${getColorFromMaybeString(theme, color)} ${percentage}%`,
87
- ''
81
+ 0,
82
+ minimal && !active
88
83
  );
84
+ const gradientColorsActive = createEffectGradient(theme, effect.gradient.colors, 0.05);
89
85
 
90
86
  const gradientDirectionOrShape =
91
87
  gradientType === 'linear'
92
88
  ? effect.gradient.direction || 'to right'
93
89
  : effect.gradient.shape || 'circle';
94
- const gradient = `${gradientType}-gradient(${gradientDirectionOrShape}${gradientColors})`;
95
- const gradientActive = `${gradientType}-gradient(${gradientDirectionOrShape}${gradientColorsActive})`;
90
+ let gradient = `${gradientType}-gradient(${gradientDirectionOrShape}${gradientColors}) padding-box`;
91
+ let gradientActive = `${gradientType}-gradient(${gradientDirectionOrShape}${gradientColorsActive}) padding-box`;
96
92
 
97
93
  // Determine the text color based on the gradient colors
98
94
  let color: TReqoreHexColor | undefined;
99
95
  // Only works if there are 2 colors not more and color was not provided
100
96
  if (!effect.color) {
101
- if (Object.keys(effect.gradient.colors).length === 2) {
102
- const gradientColor1: TReqoreHexColor = getColorFromMaybeString(
103
- theme,
104
- Object.values(effect.gradient.colors)[0]
105
- );
106
- const gradientColor2: TReqoreHexColor = getColorFromMaybeString(
107
- theme,
108
- Object.values(effect.gradient.colors)[1]
109
- );
110
-
111
- color = mix(
112
- 0.5,
113
- gradientColor1 === '#00000000' ? theme.main : gradientColor1,
114
- gradientColor2 === '#00000000' ? theme.main : gradientColor2
115
- ) as TReqoreHexColor;
116
- }
97
+ color = getGradientMix(theme, effect.gradient.colors);
98
+ }
99
+
100
+ let borderColor: string;
101
+ let borderHoverColor: string;
102
+
103
+ // The user provided a border color - we will use that
104
+ if (effect.gradient.borderColor) {
105
+ borderColor = `${getColorFromMaybeString(theme, effect.gradient.borderColor)}`;
106
+ borderHoverColor = `${changeLightness(
107
+ getColorFromMaybeString(theme, effect.gradient.borderColor),
108
+ 0.15
109
+ )}`;
110
+ } else {
111
+ // We will use border-image and create a gradient border
112
+ borderColor = 'transparent';
113
+ borderHoverColor = 'transparent';
114
+
115
+ const borderGradientColors: string = createEffectGradient(
116
+ theme,
117
+ effect.gradient.colors,
118
+ 0.15
119
+ );
120
+ const borderGradientColorsActive: string = createEffectGradient(
121
+ theme,
122
+ effect.gradient.colors,
123
+ 0.25
124
+ );
125
+
126
+ gradient = `${gradient}, ${gradientType}-gradient(${gradientDirectionOrShape}${borderGradientColors}) border-box`;
127
+ gradientActive = `${gradientActive}, ${gradientType}-gradient(${gradientDirectionOrShape}${borderGradientColorsActive}) border-box`;
117
128
  }
118
129
 
119
130
  return css`
120
- background-image: ${gradient};
121
- // Get the first color from the colors object
122
- border-color: ${changeLightness(
123
- getColorFromMaybeString(
124
- theme,
125
- effect.gradient.borderColor || Object.values(effect.gradient.colors)[0]
126
- ),
127
- 0.04
128
- )} !important;
131
+ background: ${active ? gradientActive : gradient};
132
+ border-color: ${borderColor} !important;
129
133
 
130
134
  ${color &&
131
135
  css`
132
136
  color: ${getReadableColorFrom(getColorFromMaybeString(theme, color), false)} !important;
137
+ &::placeholder {
138
+ color: ${rgba(
139
+ getReadableColorFrom(getColorFromMaybeString(theme, color), false),
140
+ 0.7
141
+ )} !important;
142
+ }
133
143
  `}
134
144
 
135
145
  ${effect.interactive &&
@@ -139,11 +149,8 @@ export const StyledEffect = styled.span`
139
149
  &:hover,
140
150
  &:focus,
141
151
  &:active {
142
- background-image: ${gradientActive};
143
- border-color: ${getColorFromMaybeString(
144
- theme,
145
- effect.gradient.borderColor || Object.values(effect.gradient.colors)[0]
146
- )} !important;
152
+ background: ${gradientActive};
153
+ border-color: ${borderHoverColor} !important;
147
154
  }
148
155
  `}
149
156
  `;
@@ -162,7 +169,7 @@ export const StyledEffect = styled.span`
162
169
  }
163
170
 
164
171
  return css`
165
- box-shadow: ${effect.glow.inset ? 'inset ' : ''} 0 0 ${effect.glow.blur || 0}
172
+ box-shadow: ${effect.glow.inset ? 'inset ' : ''} 0 0 ${effect.glow.blur || 0}px
166
173
  ${effect.glow.size || 2}px ${getColorFromMaybeString(theme, effect.glow.color)};
167
174
  `;
168
175
  }}