@qoretechnologies/reqore 0.28.6 → 0.29.1

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 (167) hide show
  1. package/.vscode/settings.json +2 -1
  2. package/__tests__/checkbox.test.tsx +7 -12
  3. package/__tests__/multiselect.test.tsx +407 -0
  4. package/__tests__/popover.test.tsx +35 -8
  5. package/dist/components/Button/index.js +1 -1
  6. package/dist/components/Button/index.js.map +1 -1
  7. package/dist/components/Checkbox/index.d.ts +7 -2
  8. package/dist/components/Checkbox/index.d.ts.map +1 -1
  9. package/dist/components/Checkbox/index.js +60 -26
  10. package/dist/components/Checkbox/index.js.map +1 -1
  11. package/dist/components/Collection/item.js +2 -2
  12. package/dist/components/Collection/item.js.map +1 -1
  13. package/dist/components/ControlGroup/index.d.ts +3 -4
  14. package/dist/components/ControlGroup/index.d.ts.map +1 -1
  15. package/dist/components/ControlGroup/index.js +7 -9
  16. package/dist/components/ControlGroup/index.js.map +1 -1
  17. package/dist/components/Dropdown/index.d.ts +2 -1
  18. package/dist/components/Dropdown/index.d.ts.map +1 -1
  19. package/dist/components/Dropdown/index.js +3 -3
  20. package/dist/components/Dropdown/index.js.map +1 -1
  21. package/dist/components/Dropdown/list.d.ts +6 -3
  22. package/dist/components/Dropdown/list.d.ts.map +1 -1
  23. package/dist/components/Dropdown/list.js +19 -1
  24. package/dist/components/Dropdown/list.js.map +1 -1
  25. package/dist/components/Effect/index.d.ts +15 -2
  26. package/dist/components/Effect/index.d.ts.map +1 -1
  27. package/dist/components/Effect/index.js +60 -23
  28. package/dist/components/Effect/index.js.map +1 -1
  29. package/dist/components/Icon/index.d.ts +2 -9
  30. package/dist/components/Icon/index.d.ts.map +1 -1
  31. package/dist/components/Icon/index.js +4 -28
  32. package/dist/components/Icon/index.js.map +1 -1
  33. package/dist/components/Input/index.js +3 -3
  34. package/dist/components/Input/index.js.map +1 -1
  35. package/dist/components/InputClearButton/index.d.ts.map +1 -1
  36. package/dist/components/InputClearButton/index.js +1 -1
  37. package/dist/components/InputClearButton/index.js.map +1 -1
  38. package/dist/components/InternalPopover/index.d.ts.map +1 -1
  39. package/dist/components/InternalPopover/index.js +19 -5
  40. package/dist/components/InternalPopover/index.js.map +1 -1
  41. package/dist/components/Menu/divider.d.ts +3 -2
  42. package/dist/components/Menu/divider.d.ts.map +1 -1
  43. package/dist/components/Menu/divider.js +2 -2
  44. package/dist/components/Menu/divider.js.map +1 -1
  45. package/dist/components/Menu/index.js +4 -3
  46. package/dist/components/Menu/index.js.map +1 -1
  47. package/dist/components/MultiSelect/index.d.ts +34 -0
  48. package/dist/components/MultiSelect/index.d.ts.map +1 -0
  49. package/dist/components/MultiSelect/index.js +178 -0
  50. package/dist/components/MultiSelect/index.js.map +1 -0
  51. package/dist/components/Panel/index.d.ts.map +1 -1
  52. package/dist/components/Panel/index.js +1 -1
  53. package/dist/components/Panel/index.js.map +1 -1
  54. package/dist/components/Popover/index.d.ts +1 -1
  55. package/dist/components/Popover/index.d.ts.map +1 -1
  56. package/dist/components/Popover/index.js +5 -2
  57. package/dist/components/Popover/index.js.map +1 -1
  58. package/dist/components/RadioGroup/index.d.ts +3 -1
  59. package/dist/components/RadioGroup/index.d.ts.map +1 -1
  60. package/dist/components/RadioGroup/index.js +2 -2
  61. package/dist/components/RadioGroup/index.js.map +1 -1
  62. package/dist/components/Table/row.js +2 -2
  63. package/dist/components/Table/row.js.map +1 -1
  64. package/dist/components/Tabs/item.js +1 -1
  65. package/dist/components/Tabs/item.js.map +1 -1
  66. package/dist/components/Tabs/list.d.ts.map +1 -1
  67. package/dist/components/Tabs/list.js +5 -4
  68. package/dist/components/Tabs/list.js.map +1 -1
  69. package/dist/components/Tag/group.d.ts +3 -3
  70. package/dist/components/Tag/group.d.ts.map +1 -1
  71. package/dist/components/Tag/group.js +6 -3
  72. package/dist/components/Tag/group.js.map +1 -1
  73. package/dist/components/Tag/index.d.ts +1 -1
  74. package/dist/components/Tag/index.d.ts.map +1 -1
  75. package/dist/components/Tag/index.js +21 -18
  76. package/dist/components/Tag/index.js.map +1 -1
  77. package/dist/components/Textarea/index.js +3 -3
  78. package/dist/components/Textarea/index.js.map +1 -1
  79. package/dist/components/Tree/index.js +1 -1
  80. package/dist/components/Tree/index.js.map +1 -1
  81. package/dist/containers/PopoverProvider.d.ts.map +1 -1
  82. package/dist/containers/PopoverProvider.js +28 -3
  83. package/dist/containers/PopoverProvider.js.map +1 -1
  84. package/dist/containers/ReqoreProvider.d.ts.map +1 -1
  85. package/dist/containers/ReqoreProvider.js +6 -5
  86. package/dist/containers/ReqoreProvider.js.map +1 -1
  87. package/dist/containers/UIProvider.d.ts +1 -0
  88. package/dist/containers/UIProvider.d.ts.map +1 -1
  89. package/dist/containers/UIProvider.js.map +1 -1
  90. package/dist/context/PopoverContext.d.ts +1 -0
  91. package/dist/context/PopoverContext.d.ts.map +1 -1
  92. package/dist/context/PopoverContext.js.map +1 -1
  93. package/dist/context/ReqoreContext.d.ts +1 -0
  94. package/dist/context/ReqoreContext.d.ts.map +1 -1
  95. package/dist/context/ReqoreContext.js +2 -1
  96. package/dist/context/ReqoreContext.js.map +1 -1
  97. package/dist/helpers/colors.d.ts +3 -0
  98. package/dist/helpers/colors.d.ts.map +1 -1
  99. package/dist/helpers/colors.js +27 -3
  100. package/dist/helpers/colors.js.map +1 -1
  101. package/dist/hooks/usePopover.d.ts +8 -1
  102. package/dist/hooks/usePopover.d.ts.map +1 -1
  103. package/dist/hooks/usePopover.js +12 -7
  104. package/dist/hooks/usePopover.js.map +1 -1
  105. package/dist/hooks/useReqore.d.ts +3 -0
  106. package/dist/hooks/useReqore.d.ts.map +1 -0
  107. package/dist/hooks/useReqore.js +17 -0
  108. package/dist/hooks/useReqore.js.map +1 -0
  109. package/dist/hooks/useTheme.d.ts +1 -1
  110. package/dist/hooks/useTheme.d.ts.map +1 -1
  111. package/dist/hooks/useTheme.js +3 -0
  112. package/dist/hooks/useTheme.js.map +1 -1
  113. package/dist/index.d.ts +3 -0
  114. package/dist/index.d.ts.map +1 -1
  115. package/dist/index.js +8 -2
  116. package/dist/index.js.map +1 -1
  117. package/package.json +1 -1
  118. package/src/components/Button/index.tsx +1 -1
  119. package/src/components/Checkbox/index.tsx +189 -34
  120. package/src/components/Collection/item.tsx +2 -2
  121. package/src/components/ControlGroup/index.tsx +46 -35
  122. package/src/components/Dropdown/index.tsx +5 -0
  123. package/src/components/Dropdown/list.tsx +29 -15
  124. package/src/components/Effect/index.tsx +123 -55
  125. package/src/components/Icon/index.tsx +4 -52
  126. package/src/components/Input/index.tsx +3 -3
  127. package/src/components/InputClearButton/index.tsx +1 -0
  128. package/src/components/InternalPopover/index.tsx +6 -3
  129. package/src/components/Menu/divider.tsx +15 -4
  130. package/src/components/Menu/index.tsx +3 -3
  131. package/src/components/MultiSelect/index.tsx +292 -0
  132. package/src/components/Panel/index.tsx +6 -4
  133. package/src/components/Popover/index.tsx +8 -3
  134. package/src/components/RadioGroup/index.tsx +6 -0
  135. package/src/components/Table/row.tsx +2 -2
  136. package/src/components/Tabs/item.tsx +1 -1
  137. package/src/components/Tabs/list.tsx +11 -11
  138. package/src/components/Tag/group.tsx +10 -2
  139. package/src/components/Tag/index.tsx +26 -20
  140. package/src/components/Textarea/index.tsx +3 -3
  141. package/src/components/Tree/index.tsx +3 -3
  142. package/src/containers/PopoverProvider.tsx +35 -3
  143. package/src/containers/ReqoreProvider.tsx +6 -4
  144. package/src/containers/UIProvider.tsx +1 -0
  145. package/src/context/PopoverContext.tsx +1 -0
  146. package/src/context/ReqoreContext.tsx +2 -0
  147. package/src/helpers/colors.ts +52 -4
  148. package/src/hooks/usePopover.tsx +24 -10
  149. package/src/hooks/useReqore.ts +12 -0
  150. package/src/hooks/useTheme.ts +6 -1
  151. package/src/index.tsx +3 -0
  152. package/src/mock/collectionData.tsx +6 -6
  153. package/src/mock/multiSelect.ts +69 -0
  154. package/src/stories/Button/Button.stories.tsx +20 -8
  155. package/src/stories/Checkbox/Checkbox.stories.tsx +42 -7
  156. package/src/stories/ControlGroup/ControlGroup.stories.tsx +7 -2
  157. package/src/stories/Dropdown/Dropdown.stories.tsx +6 -1
  158. package/src/stories/Icon/Icon.stories.tsx +42 -12
  159. package/src/stories/Input/Input.stories.tsx +25 -0
  160. package/src/stories/Menu/Menu.stories.tsx +3 -1
  161. package/src/stories/MultiSelect/MultiSelect.stories.tsx +106 -0
  162. package/src/stories/Popover/Popover.stories.tsx +19 -2
  163. package/src/stories/RadioGroup/RadioGroup.stories.tsx +51 -1
  164. package/src/stories/Tabs/Tabs.stories.tsx +23 -3
  165. package/src/stories/Tag/Tag.stories.tsx +10 -3
  166. package/src/stories/utils/args.ts +1 -1
  167. package/tests.json +1 -1
@@ -81,9 +81,9 @@ export const StyledTextarea = styled(StyledEffect)<IReqoreTextareaStyle>`
81
81
  border-radius: ${({ minimal, rounded, _size }) =>
82
82
  minimal || !rounded ? 0 : RADIUS_FROM_SIZE[_size]}px;
83
83
  border: ${({ minimal, theme, flat }) =>
84
- !minimal && !flat ? `1px solid ${changeLightness(theme.main, 0.05)}` : 0};
84
+ !minimal && !flat ? `1px solid ${changeLightness(theme.main, 0.2)}` : 0};
85
85
  border-bottom: ${({ minimal, theme, flat }) =>
86
- minimal && !flat ? `0.5px solid ${changeLightness(theme.main, 0.05)}` : undefined};
86
+ minimal && !flat ? `0.5px solid ${changeLightness(theme.main, 0.2)}` : undefined};
87
87
 
88
88
  transition: all 0.2s ease-out;
89
89
 
@@ -94,7 +94,7 @@ export const StyledTextarea = styled(StyledEffect)<IReqoreTextareaStyle>`
94
94
  &:focus,
95
95
  &:hover {
96
96
  outline: none;
97
- border-color: ${({ theme }) => changeLightness(theme.main, 0.1)};
97
+ border-color: ${({ theme }) => changeLightness(theme.main, 0.25)};
98
98
  }
99
99
  `
100
100
  : undefined}
@@ -106,9 +106,9 @@ export const ReqoreTree = ({
106
106
  <ReqoreControlGroup size={size}>
107
107
  <ReqoreButton
108
108
  className='reqore-tree-toggle'
109
- icon={isObject ? (isExpandable ? 'ArrowDownSFill' : 'ArrowRightSFill') : undefined}
110
- intent={isObject && isExpandable ? 'info' : undefined}
111
- onClick={isObject ? () => handleItemClick(stateKey, isExpandable) : undefined}
109
+ icon={isExpandable ? 'ArrowDownSFill' : 'ArrowRightSFill'}
110
+ intent={isExpandable ? 'info' : undefined}
111
+ onClick={() => handleItemClick(stateKey, isExpandable)}
112
112
  flat
113
113
  >
114
114
  {displayKey}
@@ -3,6 +3,7 @@ import React, { MutableRefObject, useCallback, useEffect, useState } from 'react
3
3
  import Popover from '../components/InternalPopover';
4
4
  import PopoverContext from '../context/PopoverContext';
5
5
  import { IPopoverOptions } from '../hooks/usePopover';
6
+ import { useReqore } from '../hooks/useReqore';
6
7
 
7
8
  export interface IReqorePopoverProviderProps {
8
9
  children: any;
@@ -16,6 +17,7 @@ export interface IPopoverData extends IPopoverOptions {
16
17
 
17
18
  const PopoverProvider: React.FC<IReqorePopoverProviderProps> = ({ children, uiScale }) => {
18
19
  const [popovers, setPopovers] = useState<IPopoverData[]>([]);
20
+ const { closePopoversOnEscPress } = useReqore();
19
21
 
20
22
  const handleClick = useCallback(
21
23
  (event: MouseEvent) => {
@@ -27,8 +29,6 @@ const PopoverProvider: React.FC<IReqorePopoverProviderProps> = ({ children, uiSc
27
29
  !popperRef.current.contains(event.target) &&
28
30
  !targetElement?.contains(event.target as Node))
29
31
  ) {
30
- targetElement.style.position = 'initial';
31
- targetElement.style.zIndex = 'initial';
32
32
  removePopover(id);
33
33
  }
34
34
  });
@@ -36,21 +36,52 @@ const PopoverProvider: React.FC<IReqorePopoverProviderProps> = ({ children, uiSc
36
36
  [popovers]
37
37
  );
38
38
 
39
+ // Close last popover when ESC is pressed
40
+ const handleKeyDown = useCallback(
41
+ (event: KeyboardEvent) => {
42
+ if (event.key === 'Escape') {
43
+ const lastPopover = popovers[popovers.length - 1];
44
+
45
+ if (lastPopover) {
46
+ removePopover(lastPopover.id);
47
+ }
48
+ }
49
+ },
50
+ [popovers]
51
+ );
52
+
39
53
  const removePopover = (id: string) => {
40
- setPopovers((cur: IPopoverData[]) => [...cur].filter((p) => p.id !== id));
54
+ // Get the popover
55
+ const popover = popovers.find((p) => p.id === id);
56
+
57
+ if (popover) {
58
+ // Remove the blur
59
+ if (popover.blur > 0) {
60
+ popover.targetElement.style.position = 'initial';
61
+ popover.targetElement.style.zIndex = 'initial';
62
+ }
63
+ // Remove the popover
64
+ setPopovers((cur: IPopoverData[]) => [...cur].filter((p) => p.id !== id));
65
+ }
41
66
  };
42
67
 
43
68
  useEffect(() => {
44
69
  document.addEventListener('click', handleClick);
45
70
 
71
+ if (closePopoversOnEscPress) {
72
+ document.addEventListener('keydown', handleKeyDown);
73
+ }
74
+
46
75
  return () => {
47
76
  document.removeEventListener('click', handleClick);
77
+ document.removeEventListener('keydown', handleKeyDown);
48
78
  };
49
79
  }, [popovers]);
50
80
 
51
81
  useEffect(() => {
52
82
  if (!size(popovers)) {
53
83
  document.removeEventListener('click', handleClick);
84
+ document.removeEventListener('keydown', handleKeyDown);
54
85
  }
55
86
  }, [popovers]);
56
87
 
@@ -72,6 +103,7 @@ const PopoverProvider: React.FC<IReqorePopoverProviderProps> = ({ children, uiSc
72
103
  }, [])
73
104
  );
74
105
  },
106
+ isPopoverOpen: (popoverId: string) => !!popovers.find((p) => p.id === popoverId),
75
107
  removePopover,
76
108
  popovers,
77
109
  }}
@@ -47,7 +47,7 @@ export interface IReqoreConfirmationModal {
47
47
  intent?: TReqoreIntent;
48
48
  }
49
49
 
50
- const ReqoreProvider: React.FC<IReqoreNotifications> = ({ children, options }) => {
50
+ const ReqoreProvider: React.FC<IReqoreNotifications> = ({ children, options = {} }) => {
51
51
  const [notifications, setNotifications] = useState<IReqoreNotificationData[] | null>([]);
52
52
  const [confirmationModal, setConfirmationModal] = useState<IReqoreConfirmationModal>({});
53
53
  const latestZIndex = useRef<number>(9000);
@@ -121,17 +121,19 @@ const ReqoreProvider: React.FC<IReqoreNotifications> = ({ children, options }) =
121
121
  isTablet,
122
122
  isMobileOrTablet,
123
123
  getAndIncreaseZIndex,
124
- animations: options?.animations || { buttons: true, dialogs: true },
124
+ animations: options.animations || { buttons: true, dialogs: true },
125
+ closePopoversOnEscPress:
126
+ 'closePopoversOnEscPress' in options ? options.closePopoversOnEscPress : true,
125
127
  }}
126
128
  >
127
129
  {size(notifications) > 0 ? (
128
- <ReqoreNotificationsWrapper position={options?.notificationsPosition}>
130
+ <ReqoreNotificationsWrapper position={options.notificationsPosition}>
129
131
  {notifications.map((notification) => (
130
132
  <ReqoreNotification
131
133
  {...notification}
132
134
  key={notification.id}
133
135
  onClick={
134
- notification?.onClick
136
+ notification.onClick
135
137
  ? () => void notification.onClick(notification.id)
136
138
  : undefined
137
139
  }
@@ -18,6 +18,7 @@ export interface IReqoreOptions {
18
18
  buttons?: boolean;
19
19
  dialogs?: boolean;
20
20
  };
21
+ closePopoversOnEscPress?: boolean;
21
22
  }
22
23
  export interface IReqoreUIProviderProps {
23
24
  children?: any;
@@ -5,6 +5,7 @@ export default createContext<{
5
5
  addPopover?: (popoverData: IPopoverData) => void;
6
6
  removePopover?: (popoverId: string) => void;
7
7
  updatePopover?: (popoverId: string, popoverData: Partial<IPopoverData>) => void;
8
+ isPopoverOpen?: (popoverId: string) => boolean;
8
9
  popovers?: IPopoverData[];
9
10
  uiScale?: number;
10
11
  }>({});
@@ -12,6 +12,7 @@ export interface IReqoreContext {
12
12
  readonly isMobileOrTablet?: boolean;
13
13
  readonly getAndIncreaseZIndex?: () => number;
14
14
  readonly animations?: IReqoreOptions['animations'];
15
+ readonly closePopoversOnEscPress?: boolean;
15
16
  }
16
17
 
17
18
  export default createContext<IReqoreContext>({
@@ -23,4 +24,5 @@ export default createContext<IReqoreContext>({
23
24
  buttons: true,
24
25
  dialogs: true,
25
26
  },
27
+ closePopoversOnEscPress: true,
26
28
  });
@@ -1,5 +1,5 @@
1
- import { cloneDeep, merge } from 'lodash';
2
- import { darken, getLuminance, lighten, readableColor } from 'polished';
1
+ import { cloneDeep, merge, reduce } from 'lodash';
2
+ import { darken, getLuminance, lighten, mix, readableColor } from 'polished';
3
3
  import { TReqoreEffectColor, TReqoreEffectColorList, TReqoreHexColor } from '../components/Effect';
4
4
  import { Colors } from '../constants/colors';
5
5
  import { DEFAULT_INTENTS, IReqoreTheme, TReqoreIntent } from '../constants/theme';
@@ -124,14 +124,14 @@ export const mergeThemes = (element: string, theme: IReqoreTheme, customTheme: a
124
124
  return clonedTheme;
125
125
  }
126
126
 
127
- if (element === 'main' && customTheme) {
127
+ if (element === 'main') {
128
128
  merge(clonedTheme, {
129
129
  main: customTheme.main,
130
130
  originalMain: clonedTheme.main,
131
131
  text: customTheme.text,
132
132
  });
133
133
  } else {
134
- merge(clonedTheme, { [element]: customTheme || {}, text: customTheme.text });
134
+ merge(clonedTheme, { [element]: customTheme, text: customTheme.text });
135
135
  }
136
136
 
137
137
  return clonedTheme;
@@ -189,3 +189,51 @@ export const getColorFromMaybeString = (
189
189
 
190
190
  return _color;
191
191
  };
192
+
193
+ export const createEffectGradient = (
194
+ theme: IReqoreTheme,
195
+ colors: Record<number, TReqoreEffectColor>,
196
+ lighten: number = 0,
197
+ minimal?: boolean
198
+ ): string => {
199
+ return reduce(
200
+ colors,
201
+ (colorsString, color, percentage) => {
202
+ return `${colorsString}, ${
203
+ minimal ? theme.main : changeLightness(getColorFromMaybeString(theme, color), lighten)
204
+ } ${percentage}%`;
205
+ },
206
+ ''
207
+ );
208
+ };
209
+
210
+ export const getNthGradientColor = (
211
+ theme: IReqoreTheme,
212
+ colors?: Record<number, TReqoreEffectColor>,
213
+ nth: number = 1
214
+ ): TReqoreHexColor | undefined => {
215
+ if (colors) {
216
+ return getColorFromMaybeString(theme, Object.values(colors)[nth - 1]);
217
+ }
218
+
219
+ return undefined;
220
+ };
221
+
222
+ export const getGradientMix = (
223
+ theme: IReqoreTheme,
224
+ colors: Record<number, TReqoreEffectColor>,
225
+ fallback?: TReqoreHexColor
226
+ ): TReqoreHexColor | undefined => {
227
+ if (colors && Object.keys(colors).length === 2) {
228
+ const gradientColor1: TReqoreHexColor = getNthGradientColor(theme, colors);
229
+ const gradientColor2: TReqoreHexColor = getNthGradientColor(theme, colors, 2);
230
+
231
+ return mix(
232
+ 0.5,
233
+ gradientColor1 === '#00000000' ? theme.main : gradientColor1,
234
+ gradientColor2 === '#00000000' ? theme.main : gradientColor2
235
+ ) as TReqoreHexColor;
236
+ }
237
+
238
+ return fallback;
239
+ };
@@ -2,6 +2,7 @@ import { Placement } from '@popperjs/core';
2
2
  import { MutableRefObject, useContext, useEffect, useMemo, useRef } from 'react';
3
3
  import { useUnmount, useUpdateEffect } from 'react-use';
4
4
  import shortid from 'shortid';
5
+ import { IPopoverData } from '../containers/PopoverProvider';
5
6
  import PopoverContext from '../context/PopoverContext';
6
7
  import {
7
8
  IReqoreIntent,
@@ -25,6 +26,13 @@ const endEvents = {
25
26
  focus: null,
26
27
  };
27
28
 
29
+ export interface IPopoverControls {
30
+ open: () => void;
31
+ close: () => void;
32
+ isOpen: () => boolean;
33
+ id: string;
34
+ }
35
+
28
36
  export interface IPopover
29
37
  extends IReqoreIntent,
30
38
  IWithReqoreMinimal,
@@ -50,6 +58,7 @@ export interface IPopover
50
58
 
51
59
  export interface IPopoverOptions extends IPopover {
52
60
  targetElement?: HTMLElement;
61
+ passPopoverData?: (data: IPopoverControls) => void;
53
62
  }
54
63
 
55
64
  const usePopover = ({
@@ -64,14 +73,15 @@ const usePopover = ({
64
73
  openOnMount = false,
65
74
  delay,
66
75
  ...rest
67
- }: IPopoverOptions) => {
68
- const { addPopover, removePopover, updatePopover, popovers } = useContext(PopoverContext);
76
+ }: IPopoverOptions): IPopoverControls => {
77
+ const { addPopover, removePopover, updatePopover, popovers, isPopoverOpen } =
78
+ useContext(PopoverContext);
69
79
  const { current }: MutableRefObject<string> = useRef(shortid.generate());
70
80
  let { current: timeout }: MutableRefObject<any> = useRef(0);
71
81
 
72
82
  const startEvent = startEvents[handler];
73
83
  const endEvent = endEvents[handler];
74
- const currentPopover = useMemo(
84
+ const currentPopover: IPopoverData = useMemo(
75
85
  () => popovers?.find((p) => p.id === current),
76
86
  [popovers, current]
77
87
  );
@@ -97,7 +107,7 @@ const usePopover = ({
97
107
 
98
108
  const _addPopover = () => {
99
109
  if (currentPopover) {
100
- if (handler !== 'hoverStay') {
110
+ if (handler !== 'hoverStay' && handler !== 'focus') {
101
111
  _removePopover?.();
102
112
  }
103
113
  } else if (show) {
@@ -112,11 +122,6 @@ const usePopover = ({
112
122
  };
113
123
 
114
124
  const _removePopover = () => {
115
- if (rest?.blur > 0) {
116
- targetElement.style.position = 'initial';
117
- targetElement.style.zIndex = 'initial';
118
- }
119
-
120
125
  cancelTimeout();
121
126
  removePopover?.(current);
122
127
  };
@@ -188,7 +193,16 @@ const usePopover = ({
188
193
  cancelTimeout();
189
194
  });
190
195
 
191
- return current;
196
+ return {
197
+ id: current,
198
+ open: () => {
199
+ if (!isPopoverOpen(current)) {
200
+ openPopover();
201
+ }
202
+ },
203
+ close: () => _removePopover(),
204
+ isOpen: () => isPopoverOpen(current),
205
+ };
192
206
  };
193
207
 
194
208
  export default usePopover;
@@ -0,0 +1,12 @@
1
+ import { useContext } from 'react';
2
+ import ReqoreContext, { IReqoreContext } from '../context/ReqoreContext';
3
+
4
+ export const useReqore = (): IReqoreContext => {
5
+ const reqore = useContext(ReqoreContext);
6
+
7
+ if (!reqore) {
8
+ throw new Error('Reqore context is not defined');
9
+ }
10
+
11
+ return reqore;
12
+ };
@@ -14,11 +14,16 @@ export interface IReqoreCustomTheme extends Partial<Omit<IReqoreTheme, 'main' |
14
14
  }
15
15
 
16
16
  export const useReqoreTheme = (
17
- element: string,
17
+ element?: string,
18
18
  customTheme: IReqoreCustomTheme = {},
19
19
  intent?: TReqoreIntent
20
20
  ) => {
21
21
  const theme: IReqoreTheme = useContext<IReqoreTheme>(ThemeContext);
22
+
23
+ if (!element) {
24
+ return theme;
25
+ }
26
+
22
27
  let _customTheme: IReqoreCustomTheme = cloneDeep(customTheme);
23
28
 
24
29
  if (_customTheme.main) {
package/src/index.tsx CHANGED
@@ -30,6 +30,7 @@ export { default as ReqoreMenuDivider } from './components/Menu/divider';
30
30
  export { default as ReqoreMenuItem } from './components/Menu/item';
31
31
  export { default as ReqoreMessage } from './components/Message';
32
32
  export { ReqoreModal } from './components/Modal';
33
+ export { ReqoreMultiSelect } from './components/MultiSelect';
33
34
  export { ReqoreFooter, ReqoreHeader } from './components/Navbar';
34
35
  export { default as ReqoreNavbarDivider } from './components/Navbar/divider';
35
36
  export { default as ReqoreNavbarGroup } from './components/Navbar/group';
@@ -58,3 +59,5 @@ export { default as ReqoreUIProvider } from './containers/UIProvider';
58
59
  export { default as ReqoreContext } from './context/ReqoreContext';
59
60
  export { default as ReqoreThemeContext } from './context/ThemeContext';
60
61
  export { default as useLatestZIndex } from './hooks/useLatestZIndex';
62
+ export { useReqore } from './hooks/useReqore';
63
+ export { useReqoreTheme } from './hooks/useTheme';
@@ -16,12 +16,12 @@ export default [
16
16
  tags: [
17
17
  {
18
18
  label: 23,
19
- badge: true,
19
+ asBadge: true,
20
20
  },
21
21
  {
22
22
  label: 2022,
23
23
  labelKey: 'Year',
24
- badge: true,
24
+ asBadge: true,
25
25
  onRemoveClick: noop,
26
26
  },
27
27
  ],
@@ -69,12 +69,12 @@ export default [
69
69
  tags: [
70
70
  {
71
71
  label: 23,
72
- badge: true,
72
+ asBadge: true,
73
73
  },
74
74
  {
75
75
  label: 2022,
76
76
  labelKey: 'Year',
77
- badge: true,
77
+ asBadge: true,
78
78
  onRemoveClick: noop(),
79
79
  },
80
80
  ],
@@ -273,12 +273,12 @@ export default [
273
273
  tags: [
274
274
  {
275
275
  label: 23,
276
- badge: true,
276
+ asBadge: true,
277
277
  },
278
278
  {
279
279
  label: 2022,
280
280
  labelKey: 'Year',
281
- badge: true,
281
+ asBadge: true,
282
282
  onRemoveClick: noop,
283
283
  },
284
284
  ],
@@ -0,0 +1,69 @@
1
+ import { TReqoreMultiSelectItem } from '../components/MultiSelect';
2
+
3
+ export const MultiSelectItems: TReqoreMultiSelectItem[] = [
4
+ {
5
+ label: 'Existing item 1',
6
+ value: 'Existing item 1',
7
+ icon: 'SunCloudyLine',
8
+ },
9
+ {
10
+ label: 'Existing item 2',
11
+ value: 'Existing item 2',
12
+ icon: 'BatteryChargeFill',
13
+ },
14
+ {
15
+ label: 'Existing item 3',
16
+ value: 'Existing item 3',
17
+ icon: 'DropboxFill',
18
+ intent: 'info',
19
+ rightIcon: 'SunLine',
20
+ },
21
+ {
22
+ label: 'Existing item 4',
23
+ value: 'Existing item 4',
24
+ icon: 'PagesLine',
25
+ effect: { gradient: { colors: { 0: 'success', 100: 'info:darken:1' } } },
26
+ },
27
+ {
28
+ disabled: true,
29
+ label: 'Disabled item',
30
+ value: 'Disabled item',
31
+ icon: 'StopCircleLine',
32
+ },
33
+ {
34
+ minimal: true,
35
+ label: 'Minimal item',
36
+ value: 'Minimal item',
37
+ icon: 'StopCircleLine',
38
+ },
39
+ {
40
+ divider: true,
41
+ icon: 'CheckDoubleLine',
42
+ },
43
+ {
44
+ value: 'itemWithNoLabel',
45
+ icon: 'TakeawayLine',
46
+ actions: [
47
+ {
48
+ icon: 'ArrowLeftUpFill',
49
+ onClick: () => console.log('clicked'),
50
+ intent: 'pending',
51
+ },
52
+ ],
53
+ },
54
+ {
55
+ label: 'Other Item 1',
56
+ value: 'Other Item 1',
57
+ icon: 'MapFill',
58
+ },
59
+ {
60
+ label: 'Other Item 2',
61
+ value: 'Other Item 2',
62
+ icon: 'ArrowLeftUpFill',
63
+ },
64
+ {
65
+ label: 'Other Item 3',
66
+ value: 'Other Item 3',
67
+ icon: 'MicLine',
68
+ },
69
+ ];
@@ -32,17 +32,29 @@ const Template: ComponentStory<typeof ReqoreButton> = (buttonProps) => {
32
32
  <ReqoreButton {...buttonProps} active tooltip='hello'>
33
33
  Active
34
34
  </ReqoreButton>
35
+ <ReqoreButton {...buttonProps} minimal flat>
36
+ Minimal
37
+ </ReqoreButton>
38
+ <ReqoreButton {...buttonProps} readOnly onClick={alert}>
39
+ Read only
40
+ </ReqoreButton>
41
+ </ReqoreControlGroup>
42
+ <br />
43
+ <ReqoreControlGroup size={buttonProps.size}>
44
+ <ReqoreButton {...buttonProps} active flat={false} tooltip='hello'>
45
+ Active Not Flat
46
+ </ReqoreButton>
35
47
  <ReqoreButton {...buttonProps} flat={false}>
36
48
  Not Flat
37
49
  </ReqoreButton>
38
- <ReqoreButton {...buttonProps} minimal>
39
- Minimal
50
+ <ReqoreButton {...buttonProps} minimal flat={false}>
51
+ Minimal not flat
40
52
  </ReqoreButton>
41
- <ReqoreButton {...buttonProps} minimal flat>
42
- Minimal flat
53
+ <ReqoreButton {...buttonProps} readOnly onClick={alert} flat={false}>
54
+ Read only not flat
43
55
  </ReqoreButton>
44
- <ReqoreButton {...buttonProps} readOnly onClick={alert}>
45
- Read only
56
+ <ReqoreButton {...buttonProps} disabled flat={false}>
57
+ Disabled not flat
46
58
  </ReqoreButton>
47
59
  </ReqoreControlGroup>
48
60
  <br />
@@ -98,10 +110,10 @@ const Template: ComponentStory<typeof ReqoreButton> = (buttonProps) => {
98
110
  <br />
99
111
  <ReqoreControlGroup>
100
112
  <ReqoreButton {...buttonProps} readOnly badge={10} onClick={alert}>
101
- With Badge
113
+ Read only with badge
102
114
  </ReqoreButton>
103
115
  <ReqoreButton {...buttonProps} minimal badge={20} onClick={alert}>
104
- With Badge
116
+ Minimal with badge
105
117
  </ReqoreButton>
106
118
  <ReqoreButton
107
119
  {...buttonProps}
@@ -9,13 +9,48 @@ export default {
9
9
 
10
10
  const Template: ComponentStory<typeof Checkbox> = (args) => {
11
11
  return (
12
- <ReqoreControlGroup>
13
- <ReqoreCheckbox {...args} />
14
- <ReqoreCheckbox {...args} label='Label' labelDetail='Detail' labelDetailPosition='left' />
15
- <ReqoreCheckbox {...args} checked tooltip='I am checked' />
16
- <ReqoreCheckbox {...args} disabled />
17
- <ReqoreCheckbox {...args} label='Label' labelDetail='Detail' labelPosition='left' />
18
- <ReqoreCheckbox {...args} label='Read Only' labelPosition='left' readOnly />
12
+ <ReqoreControlGroup vertical>
13
+ <ReqoreControlGroup>
14
+ <ReqoreCheckbox {...args} />
15
+ <ReqoreCheckbox {...args} label='Label' labelDetail='Detail' labelDetailPosition='left' />
16
+ <ReqoreCheckbox {...args} checked tooltip='I am checked' />
17
+ <ReqoreCheckbox {...args} disabled />
18
+ <ReqoreCheckbox {...args} label='Label' labelDetail='Detail' labelPosition='left' />
19
+ <ReqoreCheckbox {...args} label='Read Only' labelPosition='left' readOnly />
20
+ </ReqoreControlGroup>
21
+ <ReqoreControlGroup>
22
+ <ReqoreCheckbox {...args} intent='info' />
23
+ <ReqoreCheckbox
24
+ {...args}
25
+ label='Label'
26
+ labelDetail='Detail'
27
+ labelDetailPosition='left'
28
+ labelEffect={{ gradient: { colors: { 0: 'danger:lighten:1', 100: '#ff6700' } } }}
29
+ />
30
+ <ReqoreCheckbox
31
+ {...args}
32
+ checked
33
+ tooltip='I am checked'
34
+ effect={{ gradient: { colors: { 0: '#00fafd', 100: '#ff00d0' } } }}
35
+ />
36
+ <ReqoreCheckbox {...args} disabled onText='yes' offText='no' />
37
+ <ReqoreCheckbox
38
+ {...args}
39
+ label='Label'
40
+ labelDetail='Detail'
41
+ labelPosition='left'
42
+ checkedIcon='EmotionHappyFill'
43
+ uncheckedIcon='EmotionSadFill'
44
+ />
45
+ <ReqoreCheckbox
46
+ {...args}
47
+ label='Read Only'
48
+ labelPosition='left'
49
+ readOnly
50
+ checked
51
+ image='https://avatars.githubusercontent.com/u/44835090?s=400&u=371120ce0755102d2e432f11ad9aa0378c871b45&v=4'
52
+ />
53
+ </ReqoreControlGroup>
19
54
  </ReqoreControlGroup>
20
55
  );
21
56
  };
@@ -2,7 +2,7 @@ import { Meta, Story } from '@storybook/react/types-6-0';
2
2
  import { IReqoreControlGroupProps } from '../../components/ControlGroup';
3
3
  import ReqoreInput from '../../components/Input';
4
4
  import { ReqoreButton, ReqoreControlGroup, ReqoreTag } from '../../index';
5
- import { GapSizeArg, MinimalArg, SizeArg, argManager } from '../utils/args';
5
+ import { argManager, GapSizeArg, MinimalArg, SizeArg } from '../utils/args';
6
6
 
7
7
  const { createArg } = argManager<IReqoreControlGroupProps>();
8
8
 
@@ -39,7 +39,7 @@ const Template: Story<IReqoreControlGroupProps> = (args: IReqoreControlGroupProp
39
39
  <ReqoreButton>Button</ReqoreButton>
40
40
  <ReqoreButton
41
41
  flat={false}
42
- effect={{ gradient: { colors: { 0: 'success', 100: 'success:darken:1' } } }}
42
+ effect={{ gradient: { colors: { 0: 'success', 100: 'info:darken:1' } } }}
43
43
  >
44
44
  Non flat Button
45
45
  </ReqoreButton>
@@ -60,6 +60,11 @@ Minimal.args = {
60
60
  minimal: true,
61
61
  };
62
62
 
63
+ export const NotFlat = Template.bind({});
64
+ NotFlat.args = {
65
+ flat: false,
66
+ };
67
+
63
68
  export const Vertical = Template.bind({});
64
69
  Vertical.args = {
65
70
  vertical: true,
@@ -47,6 +47,11 @@ export default {
47
47
  value: 'i aM diSAblEd',
48
48
  icon: 'StopCircleLine',
49
49
  },
50
+ {
51
+ divider: true,
52
+ label: 'Divider',
53
+ dividerAlign: 'left',
54
+ },
50
55
  {
51
56
  selected: true,
52
57
  value: 'Hello',
@@ -125,7 +130,7 @@ export default {
125
130
  } as Meta<IReqoreDropdownProps>;
126
131
 
127
132
  const Template: Story<IReqoreDropdownProps> = (args: IReqoreDropdownProps) => {
128
- const [selected, setSelected] = useState<string[]>(['Item 3', 'Item 6']);
133
+ const [selected, setSelected] = useState<(string | number)[]>(['Item 3', 'Item 6']);
129
134
 
130
135
  if (args.multiSelect) {
131
136
  return (