@qoretechnologies/reqore 0.24.0 → 0.25.3

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 (78) hide show
  1. package/.gitpod.yml +4 -1
  2. package/__tests__/collection.test.tsx +72 -0
  3. package/__tests__/panel.test.tsx +35 -2
  4. package/__tests__/tag.test.tsx +21 -7
  5. package/dist/components/Collection/index.d.ts +17 -0
  6. package/dist/components/Collection/index.d.ts.map +1 -0
  7. package/dist/components/Collection/index.js +165 -0
  8. package/dist/components/Collection/index.js.map +1 -0
  9. package/dist/components/Collection/item.d.ts +18 -0
  10. package/dist/components/Collection/item.d.ts.map +1 -0
  11. package/dist/components/Collection/item.js +168 -0
  12. package/dist/components/Collection/item.js.map +1 -0
  13. package/dist/components/Columns/index.d.ts.map +1 -1
  14. package/dist/components/Columns/index.js +1 -1
  15. package/dist/components/Columns/index.js.map +1 -1
  16. package/dist/components/ControlGroup/index.d.ts.map +1 -1
  17. package/dist/components/ControlGroup/index.js +5 -3
  18. package/dist/components/ControlGroup/index.js.map +1 -1
  19. package/dist/components/Drawer/index.d.ts +1 -1
  20. package/dist/components/Drawer/index.d.ts.map +1 -1
  21. package/dist/components/Dropdown/index.d.ts.map +1 -1
  22. package/dist/components/Dropdown/index.js +1 -1
  23. package/dist/components/Dropdown/index.js.map +1 -1
  24. package/dist/components/InternalPopover/index.js +1 -1
  25. package/dist/components/Panel/index.d.ts +12 -12
  26. package/dist/components/Panel/index.d.ts.map +1 -1
  27. package/dist/components/Panel/index.js +66 -36
  28. package/dist/components/Panel/index.js.map +1 -1
  29. package/dist/components/Table/index.d.ts +4 -4
  30. package/dist/components/Table/index.d.ts.map +1 -1
  31. package/dist/components/Table/index.js.map +1 -1
  32. package/dist/components/Table/row.d.ts +2 -2
  33. package/dist/components/Table/row.d.ts.map +1 -1
  34. package/dist/components/Tag/index.d.ts +2 -1
  35. package/dist/components/Tag/index.d.ts.map +1 -1
  36. package/dist/components/Tag/index.js +11 -10
  37. package/dist/components/Tag/index.js.map +1 -1
  38. package/dist/constants/theme.d.ts +3 -0
  39. package/dist/constants/theme.d.ts.map +1 -1
  40. package/dist/constants/theme.js +9 -1
  41. package/dist/constants/theme.js.map +1 -1
  42. package/dist/hooks/usePopover.d.ts +1 -0
  43. package/dist/hooks/usePopover.d.ts.map +1 -1
  44. package/dist/hooks/usePopover.js +5 -4
  45. package/dist/hooks/usePopover.js.map +1 -1
  46. package/dist/hooks/useTooltip.d.ts +2 -2
  47. package/dist/hooks/useTooltip.d.ts.map +1 -1
  48. package/dist/hooks/useTooltip.js +11 -2
  49. package/dist/hooks/useTooltip.js.map +1 -1
  50. package/dist/index.d.ts +1 -0
  51. package/dist/index.d.ts.map +1 -1
  52. package/dist/index.js +4 -2
  53. package/dist/index.js.map +1 -1
  54. package/dist/types/global.d.ts +29 -0
  55. package/dist/types/global.d.ts.map +1 -1
  56. package/package.json +12 -10
  57. package/src/components/Collection/index.tsx +189 -0
  58. package/src/components/Collection/item.tsx +239 -0
  59. package/src/components/Columns/index.tsx +1 -0
  60. package/src/components/ControlGroup/index.tsx +5 -2
  61. package/src/components/Drawer/index.tsx +1 -1
  62. package/src/components/Dropdown/index.tsx +1 -0
  63. package/src/components/InternalPopover/index.tsx +1 -1
  64. package/src/components/Panel/index.tsx +188 -118
  65. package/src/components/Table/index.tsx +7 -7
  66. package/src/components/Table/row.tsx +2 -2
  67. package/src/components/Tag/index.tsx +27 -5
  68. package/src/constants/theme.ts +9 -0
  69. package/src/hooks/usePopover.tsx +6 -4
  70. package/src/hooks/useTooltip.ts +15 -4
  71. package/src/index.tsx +1 -0
  72. package/src/mock/collectionData.tsx +228 -0
  73. package/src/stories/Collection/Collection.stories.tsx +98 -0
  74. package/src/stories/Columns/Columns.stories.tsx +1 -1
  75. package/src/stories/Panel/Panel.stories.tsx +22 -0
  76. package/src/stories/Tag/Tag.stories.tsx +2 -0
  77. package/src/types/global.ts +31 -0
  78. package/tests.json +1 -1
@@ -4,37 +4,51 @@ import { forwardRef, ReactElement, useCallback, useMemo, useState } from 'react'
4
4
  import { useUpdateEffect } from 'react-use';
5
5
  import styled, { css } from 'styled-components';
6
6
  import { RADIUS_FROM_SIZE } from '../../constants/sizes';
7
- import { IReqoreCustomTheme, IReqoreTheme, TReqoreIntent } from '../../constants/theme';
8
- import ReqoreThemeProvider from '../../containers/ThemeProvider';
7
+ import { IReqoreTheme } from '../../constants/theme';
9
8
  import {
10
9
  changeDarkness,
11
10
  changeLightness,
12
11
  getMainBackgroundColor,
13
12
  getReadableColor,
14
13
  } from '../../helpers/colors';
14
+ import { useCombinedRefs } from '../../hooks/useCombinedRefs';
15
15
  import { useReqoreTheme } from '../../hooks/useTheme';
16
+ import { useTooltip } from '../../hooks/useTooltip';
17
+ import {
18
+ IReqoreIntent,
19
+ IWithReqoreCustomTheme,
20
+ IWithReqoreFlat,
21
+ IWithReqoreSize,
22
+ IWithReqoreTooltip,
23
+ } from '../../types/global';
16
24
  import { IReqoreIconName } from '../../types/icons';
17
- import ReqoreButton from '../Button';
25
+ import ReqoreButton, { IReqoreButtonProps } from '../Button';
26
+ import { StyledCollectionItemContent } from '../Collection/item';
18
27
  import ReqoreControlGroup from '../ControlGroup';
19
28
  import ReqoreDropdown from '../Dropdown';
20
29
  import { IReqoreDropdownItemProps } from '../Dropdown/item';
21
30
  import ReqoreIcon from '../Icon';
22
31
 
23
- export interface IReqorePanelAction {
24
- icon?: IReqoreIconName;
25
- label?: string;
32
+ export interface IReqorePanelAction extends IReqoreButtonProps, IWithReqoreTooltip, IReqoreIntent {
33
+ label?: string | number;
26
34
  onClick?: () => void;
27
- intent?: TReqoreIntent;
28
35
  actions?: IReqoreDropdownItemProps[];
29
- className?: string;
30
- id?: string;
36
+ customContent?: () => string | React.ReactNode;
31
37
  }
32
38
 
33
39
  export interface IReqorePanelBottomAction extends IReqorePanelAction {
34
40
  position: 'left' | 'right';
35
41
  }
36
42
 
37
- export interface IReqorePanelProps extends React.HTMLAttributes<HTMLDivElement> {
43
+ export interface IReqorePanelContent {}
44
+
45
+ export interface IReqorePanelProps
46
+ extends IWithReqoreSize,
47
+ IWithReqoreCustomTheme,
48
+ IWithReqoreFlat,
49
+ IReqoreIntent,
50
+ IWithReqoreTooltip,
51
+ React.HTMLAttributes<HTMLDivElement> {
38
52
  as?: any;
39
53
  children?: any;
40
54
  icon?: IReqoreIconName;
@@ -43,11 +57,8 @@ export interface IReqorePanelProps extends React.HTMLAttributes<HTMLDivElement>
43
57
  isCollapsed?: boolean;
44
58
  onClose?: () => void;
45
59
  rounded?: boolean;
46
- actions?: IReqorePanelAction[];
60
+ actions?: (IReqorePanelAction | IReqorePanelAction[])[];
47
61
  bottomActions?: IReqorePanelBottomAction[];
48
- customTheme?: IReqoreCustomTheme;
49
- intent?: TReqoreIntent;
50
- flat?: boolean;
51
62
  unMountContentOnCollapse?: boolean;
52
63
  onCollapseChange?: (isCollapsed?: boolean) => void;
53
64
  fill?: boolean;
@@ -55,6 +66,8 @@ export interface IReqorePanelProps extends React.HTMLAttributes<HTMLDivElement>
55
66
  contentStyle?: React.CSSProperties;
56
67
  opacity?: number;
57
68
  blur?: number;
69
+ minimal?: boolean;
70
+ headerSize?: 1 | 2 | 3 | 4 | 5 | 6;
58
71
  }
59
72
 
60
73
  export interface IStyledPanel extends IReqorePanelProps {
@@ -74,8 +87,27 @@ export const StyledPanel = styled.div<IStyledPanel>`
74
87
  display: flex;
75
88
  flex-flow: column;
76
89
  position: relative;
77
- z-index: 1;
78
90
  backdrop-filter: ${({ blur, opacity }) => (blur && opacity < 1 ? `blur(${blur}px)` : undefined)};
91
+ transition: 0.3s ease-in-out;
92
+
93
+ ${({ interactive, theme, opacity = 1 }) =>
94
+ interactive
95
+ ? css`
96
+ cursor: pointer;
97
+
98
+ &:hover {
99
+ background-color: ${rgba(changeDarkness(getMainBackgroundColor(theme), 0.06), opacity)};
100
+
101
+ ${StyledCollectionItemContent}:after {
102
+ background: linear-gradient(
103
+ to top,
104
+ ${rgba(changeDarkness(getMainBackgroundColor(theme), 0.06), opacity)} 0%,
105
+ transparent 100%
106
+ );
107
+ }
108
+ }
109
+ `
110
+ : undefined}
79
111
 
80
112
  ${({ fill, isCollapsed }) =>
81
113
  !isCollapsed && fill
@@ -125,7 +157,10 @@ export const StyledPanelBottomActions = styled(StyledPanelTitle)`
125
157
  export const StyledPanelContent = styled.div<IStyledPanel>`
126
158
  display: ${({ isCollapsed }) => (isCollapsed ? 'none' : undefined)};
127
159
  min-height: ${({ isCollapsed }) => (isCollapsed ? undefined : '40px')};
128
- padding: ${({ padded }) => (!padded ? undefined : '10px')};
160
+ padding: ${({ padded }) => (!padded ? undefined : '15px')};
161
+ // The padding is not needed when the panel is minimal and has title, since
162
+ // the title already has padding and is transparent
163
+ padding-top: ${({ minimal, hasLabel }) => (minimal && hasLabel ? '0px' : undefined)};
129
164
  flex: 1;
130
165
  overflow: auto;
131
166
  `;
@@ -134,6 +169,7 @@ export const StyledPanelTitleLabel = styled.span`
134
169
  white-space: nowrap;
135
170
  text-overflow: ellipsis;
136
171
  overflow: hidden;
172
+ margin: 0;
137
173
  `;
138
174
 
139
175
  export const StyledPanelTitleHeader = styled.div`
@@ -168,12 +204,18 @@ export const ReqorePanel = forwardRef(
168
204
  onCollapseChange,
169
205
  padded = true,
170
206
  contentStyle,
207
+ headerSize = 4,
208
+ minimal,
209
+ tooltip,
171
210
  ...rest
172
211
  }: IReqorePanelProps,
173
212
  ref
174
213
  ) => {
175
214
  const [_isCollapsed, setIsCollapsed] = useState(isCollapsed || false);
176
215
  const theme = useReqoreTheme('main', customTheme, intent);
216
+ const { targetRef } = useCombinedRefs(ref);
217
+
218
+ useTooltip(targetRef.current, tooltip);
177
219
 
178
220
  useUpdateEffect(() => {
179
221
  setIsCollapsed(!!isCollapsed);
@@ -206,33 +248,50 @@ export const ReqorePanel = forwardRef(
206
248
  [leftBottomActions, rightBottomActions]
207
249
  );
208
250
 
209
- const renderActions = ({
210
- label,
211
- actions,
212
- intent,
213
- className,
214
- id,
215
- ...rest
216
- }: IReqorePanelAction) =>
217
- size(actions) ? (
218
- <ReqoreDropdown
219
- {...rest}
220
- label={label}
221
- componentProps={{
222
- intent,
223
- id,
224
- minimal: true,
225
- className,
226
- onClick: (e: React.MouseEvent<HTMLButtonElement>) => {
227
- e.stopPropagation();
228
- },
229
- }}
230
- items={actions}
231
- />
232
- ) : (
251
+ const renderActions = (
252
+ actionOrActions: IReqorePanelAction | IReqorePanelAction[],
253
+ index: number
254
+ ) => {
255
+ if (Array.isArray(actionOrActions)) {
256
+ return (
257
+ <ReqoreControlGroup stack minimal>
258
+ {actionOrActions.map(renderActions)}
259
+ </ReqoreControlGroup>
260
+ );
261
+ }
262
+
263
+ const { id, actions, label, intent, className, customContent, ...rest }: IReqorePanelAction =
264
+ actionOrActions;
265
+
266
+ if (size(actions)) {
267
+ return (
268
+ <ReqoreDropdown
269
+ {...rest}
270
+ key={index}
271
+ label={label}
272
+ componentProps={{
273
+ intent,
274
+ id,
275
+ minimal: true,
276
+ className,
277
+ onClick: (e: React.MouseEvent<HTMLButtonElement>) => {
278
+ e.stopPropagation();
279
+ },
280
+ }}
281
+ items={actions}
282
+ />
283
+ );
284
+ }
285
+
286
+ if (customContent) {
287
+ return customContent();
288
+ }
289
+
290
+ return (
233
291
  <ReqoreButton
234
292
  {...rest}
235
293
  id={id}
294
+ key={index}
236
295
  className={className}
237
296
  customTheme={theme}
238
297
  intent={intent}
@@ -248,86 +307,97 @@ export const ReqorePanel = forwardRef(
248
307
  {label}
249
308
  </ReqoreButton>
250
309
  );
310
+ };
311
+
312
+ const HTMLheaderElement = useMemo(() => {
313
+ return `h${headerSize}` as 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6';
314
+ }, [headerSize]);
315
+
316
+ const interactive: boolean = !!(
317
+ rest.onClick ||
318
+ rest.onMouseOver ||
319
+ rest.onMouseEnter ||
320
+ rest.onDoubleClick ||
321
+ rest.onContextMenu
322
+ );
251
323
 
252
324
  return (
253
- <ReqoreThemeProvider theme={theme}>
254
- <StyledPanel
255
- {...rest}
256
- as={rest.as || 'div'}
257
- ref={ref as any}
258
- isCollapsed={_isCollapsed}
259
- rounded={rounded}
260
- flat={flat}
261
- className={`${className || ''} reqore-panel`}
262
- >
263
- {hasTitleBar && (
264
- <StyledPanelTitle
265
- flat={flat}
266
- isCollapsed={_isCollapsed}
267
- collapsible={collapsible}
268
- className='reqore-panel-title'
269
- onClick={handleCollapseClick}
270
- theme={theme}
271
- opacity={rest.opacity}
272
- >
273
- <StyledPanelTitleHeader>
274
- {icon && <ReqoreIcon icon={icon} margin='right' />}
275
- {typeof label === 'string' ? (
276
- <StyledPanelTitleLabel>{label}</StyledPanelTitleLabel>
277
- ) : (
278
- label
279
- )}
280
- </StyledPanelTitleHeader>
281
- <ReqoreControlGroup minimal>
282
- {actions.map(renderActions)}
283
- {collapsible && (
284
- <ReqoreButton
285
- customTheme={theme}
286
- icon={_isCollapsed ? 'ArrowDownSLine' : 'ArrowUpSLine'}
287
- onClick={handleCollapseClick}
288
- tooltip={_isCollapsed ? 'Expand' : 'Collapse'}
289
- />
290
- )}
291
- {onClose && (
292
- <ReqoreButton
293
- customTheme={theme}
294
- icon='CloseLine'
295
- onClick={(e: React.MouseEvent<HTMLButtonElement>) => {
296
- e.stopPropagation();
297
- onClose?.();
298
- }}
299
- />
300
- )}
301
- </ReqoreControlGroup>
302
- </StyledPanelTitle>
303
- )}
304
- {!_isCollapsed || (_isCollapsed && !unMountContentOnCollapse) ? (
305
- <StyledPanelContent
306
- className='reqore-panel-content'
307
- isCollapsed={_isCollapsed}
308
- style={contentStyle}
309
- padded={padded}
310
- >
311
- {children}
312
- </StyledPanelContent>
313
- ) : null}
314
- {hasBottomActions && !_isCollapsed ? (
315
- <StyledPanelBottomActions
316
- flat={flat}
317
- className='reqore-panel-bottom-actions'
318
- theme={theme}
319
- opacity={rest.opacity}
320
- >
321
- <ReqoreControlGroup minimal>
322
- {leftBottomActions.map(renderActions)}
323
- </ReqoreControlGroup>
324
- <ReqoreControlGroup minimal>
325
- {rightBottomActions.map(renderActions)}
326
- </ReqoreControlGroup>
327
- </StyledPanelBottomActions>
328
- ) : null}
329
- </StyledPanel>
330
- </ReqoreThemeProvider>
325
+ <StyledPanel
326
+ {...rest}
327
+ as={rest.as || 'div'}
328
+ ref={targetRef}
329
+ isCollapsed={_isCollapsed}
330
+ rounded={rounded}
331
+ flat={flat}
332
+ className={`${className || ''} reqore-panel`}
333
+ interactive={interactive}
334
+ theme={theme}
335
+ >
336
+ {hasTitleBar && (
337
+ <StyledPanelTitle
338
+ flat={flat}
339
+ isCollapsed={_isCollapsed}
340
+ collapsible={collapsible}
341
+ className='reqore-panel-title'
342
+ onClick={handleCollapseClick}
343
+ theme={theme}
344
+ opacity={rest.opacity ?? (minimal ? 0 : 1)}
345
+ >
346
+ <StyledPanelTitleHeader>
347
+ {icon && <ReqoreIcon icon={icon} margin='right' />}
348
+ {typeof label === 'string' ? (
349
+ <StyledPanelTitleLabel as={HTMLheaderElement}>{label}</StyledPanelTitleLabel>
350
+ ) : (
351
+ label
352
+ )}
353
+ </StyledPanelTitleHeader>
354
+ <ReqoreControlGroup minimal>
355
+ {actions.map(renderActions)}
356
+ {collapsible && (
357
+ <ReqoreButton
358
+ customTheme={theme}
359
+ icon={_isCollapsed ? 'ArrowDownSLine' : 'ArrowUpSLine'}
360
+ onClick={handleCollapseClick}
361
+ tooltip={_isCollapsed ? 'Expand' : 'Collapse'}
362
+ />
363
+ )}
364
+ {onClose && (
365
+ <ReqoreButton
366
+ customTheme={theme}
367
+ icon='CloseLine'
368
+ onClick={(e: React.MouseEvent<HTMLButtonElement>) => {
369
+ e.stopPropagation();
370
+ onClose?.();
371
+ }}
372
+ />
373
+ )}
374
+ </ReqoreControlGroup>
375
+ </StyledPanelTitle>
376
+ )}
377
+ {!_isCollapsed || (_isCollapsed && !unMountContentOnCollapse) ? (
378
+ <StyledPanelContent
379
+ className='reqore-panel-content'
380
+ hasLabel={!!label}
381
+ isCollapsed={_isCollapsed}
382
+ style={contentStyle}
383
+ padded={padded}
384
+ minimal={minimal}
385
+ >
386
+ {children}
387
+ </StyledPanelContent>
388
+ ) : null}
389
+ {hasBottomActions && !_isCollapsed ? (
390
+ <StyledPanelBottomActions
391
+ flat={flat}
392
+ className='reqore-panel-bottom-actions'
393
+ theme={theme}
394
+ opacity={rest.opacity ?? (minimal ? 0 : 1)}
395
+ >
396
+ <ReqoreControlGroup minimal>{leftBottomActions.map(renderActions)}</ReqoreControlGroup>
397
+ <ReqoreControlGroup minimal>{rightBottomActions.map(renderActions)}</ReqoreControlGroup>
398
+ </StyledPanelBottomActions>
399
+ ) : null}
400
+ </StyledPanel>
331
401
  );
332
402
  }
333
403
  );
@@ -16,7 +16,7 @@ import { IReqoreTableHeaderStyle, StyledTableHeader } from './headerCell';
16
16
  import { fixSort, flipSortDirection, sortTableData } from './helpers';
17
17
 
18
18
  export type TReqoreTableColumnContent =
19
- | React.FC<{ [key: string]: any; _selectId?: string }>
19
+ | React.FC<{ [key: string]: any; _selectId?: string | number }>
20
20
  | 'time-ago'
21
21
  | 'tag'
22
22
  | `tag:${TReqoreIntent}`
@@ -39,13 +39,13 @@ export interface IReqoreTableColumn extends IReqoreIntent {
39
39
  icon?: IReqoreIconName;
40
40
  iconSize?: string;
41
41
  tooltip?: string;
42
- cellTooltip?: (data: { [key: string]: any; _selectId?: string }) => string | JSX.Element;
43
- onCellClick?: (data: { [key: string]: any; _selectId?: string }) => void;
42
+ cellTooltip?: (data: { [key: string]: any; _selectId?: string | number }) => string | JSX.Element;
43
+ onCellClick?: (data: { [key: string]: any; _selectId?: string | number }) => void;
44
44
  }
45
45
 
46
46
  export interface IReqoreTableRowData {
47
47
  [key: string]: any;
48
- _selectId?: string;
48
+ _selectId?: string | number;
49
49
  _intent?: TReqoreIntent;
50
50
  _disabled?: boolean;
51
51
  }
@@ -146,7 +146,7 @@ const ReqoreTable = ({
146
146
  const [leftScroll, setLeftScroll] = useState<number>(0);
147
147
  const [_data, setData] = useState<IReqoreTableData>(data || []);
148
148
  const [_sort, setSort] = useState<IReqoreTableSort>(fixSort(sort));
149
- const [_selected, setSelected] = useState<string[]>([]);
149
+ const [_selected, setSelected] = useState<(string | number)[]>([]);
150
150
  const [_selectedQuant, setSelectedQuant] = useState<'all' | 'none' | 'some'>('none');
151
151
  const [wrapperRef, sizes] = useMeasure();
152
152
  const theme = useReqoreTheme('main', customTheme, intent);
@@ -197,7 +197,7 @@ const ReqoreTable = ({
197
197
  });
198
198
  };
199
199
 
200
- const handleSelectClick = (selectId: string) => {
200
+ const handleSelectClick = (selectId: string | number) => {
201
201
  setSelected((current) => {
202
202
  let newSelected = [...current];
203
203
  const isSelected = newSelected.find((selected) => selectId === selected);
@@ -216,7 +216,7 @@ const ReqoreTable = ({
216
216
  switch (_selectedQuant) {
217
217
  case 'none':
218
218
  case 'some': {
219
- const selectableData: string[] = _data
219
+ const selectableData: (string | number)[] = _data
220
220
  .filter((datum) => datum._selectId ?? false)
221
221
  .map((datum) => datum._selectId);
222
222
 
@@ -23,8 +23,8 @@ export interface IReqoreTableRowOptions {
23
23
  columns: IReqoreTableColumn[];
24
24
  data?: IReqoreTableData;
25
25
  selectable?: boolean;
26
- onSelectClick?: (selectId: string) => void;
27
- selected?: string[];
26
+ onSelectClick?: (selectId: string | number) => void;
27
+ selected?: (string | number)[];
28
28
  onRowClick?: IReqoreTableRowClick;
29
29
  striped?: boolean;
30
30
  selectedRowIntent?: TReqoreIntent;
@@ -28,7 +28,8 @@ export interface IReqoreTagProps
28
28
  IWithReqoreTooltip,
29
29
  IReqoreDisabled {
30
30
  size?: TSizes;
31
- label?: string;
31
+ label?: string | number;
32
+ labelKey?: string | number;
32
33
  onRemoveClick?: (event: React.MouseEvent<HTMLDivElement>) => void;
33
34
  onClick?: (event: React.MouseEvent<HTMLDivElement>) => void;
34
35
  icon?: IReqoreIconName;
@@ -59,11 +60,23 @@ export const StyledTag = styled.div<IReqoreTagStyle>`
59
60
  min-width: ${({ size }) => SIZE_TO_PX[size]}px;
60
61
  border-radius: ${({ badge, size }) => (badge ? 20 : RADIUS_FROM_SIZE[size])}px;
61
62
  width: ${({ width }) => width || undefined};
63
+ transition: all 0.2s ease-out;
62
64
 
63
- ${({ theme, color }) =>
65
+ ${({ theme, color, labelKey }) =>
64
66
  css`
65
67
  background-color: ${color || changeLightness(theme.main, 0.1)};
66
68
  color: ${color ? getReadableColorFrom(color) : getReadableColor(theme, undefined, undefined)};
69
+
70
+ ${StyledTagContentWrapper} {
71
+ background-color: ${labelKey ? changeLightness(color || theme.main, 0.05) : undefined};
72
+ }
73
+
74
+ ${StyledTagContent} {
75
+ background-color: ${labelKey ? changeLightness(color || theme.main, 0.1) : undefined};
76
+ }
77
+
78
+ ${StyledTagContentKey} {
79
+ background-color: ${labelKey ? changeLightness(color || theme.main, 0.05) : undefined};
67
80
  }
68
81
  `}
69
82
 
@@ -90,23 +103,29 @@ export const StyledTag = styled.div<IReqoreTagStyle>`
90
103
  `;
91
104
 
92
105
  const StyledTagContentWrapper = styled.div<{ size: TSizes }>`
93
- padding: 0 ${({ size }) => PADDING_FROM_SIZE[size]}px;
94
106
  display: flex;
95
107
  align-items: center;
96
108
  justify-content: center;
97
109
  flex-shrink: 0;
98
110
  flex: 1;
99
111
  overflow: hidden;
112
+ height: 100%;
100
113
  `;
101
114
 
102
115
  const StyledTagContent = styled.span<{ size: TSizes }>`
116
+ padding: 0 ${({ size }) => PADDING_FROM_SIZE[size]}px;
103
117
  height: 100%;
118
+ display: flex;
104
119
  align-items: center;
105
120
  overflow: hidden;
106
121
  text-overflow: ellipsis;
107
122
  white-space: nowrap;
108
123
  `;
109
124
 
125
+ const StyledTagContentKey = styled(StyledTagContent)`
126
+ font-weight: 800;
127
+ `;
128
+
110
129
  const StyledButtonWrapper = styled.div<IReqoreTagStyle>`
111
130
  flex-shrink: 0;
112
131
  font-size: ${({ size }) => TEXT_FROM_SIZE[size]}px;
@@ -115,7 +134,7 @@ const StyledButtonWrapper = styled.div<IReqoreTagStyle>`
115
134
  display: flex;
116
135
  justify-content: center;
117
136
  align-items: center;
118
- transition: background-color 0.2s ease-out;
137
+ transition: all 0.2s ease-out;
119
138
 
120
139
  ${({ theme, color }) =>
121
140
  css`
@@ -138,6 +157,7 @@ const ReqoreTag = forwardRef(
138
157
  {
139
158
  tooltip,
140
159
  label,
160
+ labelKey,
141
161
  icon,
142
162
  rightIcon,
143
163
  className,
@@ -163,6 +183,7 @@ const ReqoreTag = forwardRef(
163
183
  return (
164
184
  <StyledTag
165
185
  {...rest}
186
+ labelKey={labelKey}
166
187
  color={customColor}
167
188
  className={`${className || ''} reqore-tag`}
168
189
  size={size}
@@ -176,9 +197,10 @@ const ReqoreTag = forwardRef(
176
197
  <ReqoreIcon
177
198
  icon={icon}
178
199
  size={`${TEXT_FROM_SIZE[size]}px`}
179
- margin={label || rightIcon ? 'right' : undefined}
200
+ margin={label || rightIcon ? 'left' : 'both'}
180
201
  />
181
202
  )}
203
+ {labelKey && <StyledTagContentKey size={size}>{labelKey}</StyledTagContentKey>}
182
204
  {label && <StyledTagContent size={size}>{label}</StyledTagContent>}
183
205
  {rightIcon && (
184
206
  <ReqoreIcon
@@ -100,3 +100,12 @@ export const DEFAULT_THEME: IReqoreTheme = {
100
100
  intents: DEFAULT_INTENTS,
101
101
  notifications: {},
102
102
  };
103
+
104
+ export const ReqoreIntents: { [key: string]: TReqoreIntent } = {
105
+ INFO: 'info',
106
+ SUCCESS: 'success',
107
+ PENDING: 'pending',
108
+ WARNING: 'warning',
109
+ DANGER: 'danger',
110
+ MUTED: 'muted',
111
+ };
@@ -29,6 +29,7 @@ export interface IPopover {
29
29
  closeOnOutsideClick?: boolean;
30
30
  closeOnAnyClick?: boolean;
31
31
  delay?: number;
32
+ blur?: number;
32
33
  }
33
34
 
34
35
  export interface IPopoverOptions extends IPopover {
@@ -88,7 +89,7 @@ const usePopover = ({
88
89
  };
89
90
 
90
91
  useUpdateEffect(() => {
91
- if (show) {
92
+ if (content && show) {
92
93
  updatePopover?.(current, {
93
94
  id: current,
94
95
  content,
@@ -100,13 +101,13 @@ const usePopover = ({
100
101
  closeOnAnyClick: handler === 'hover' || handler === 'hoverStay',
101
102
  });
102
103
  }
103
- }, [content]);
104
+ }, [content?.toString()]);
104
105
 
105
106
  useEffect(() => {
106
107
  if (openOnMount && targetElement) {
107
108
  _addPopover();
108
109
  }
109
- }, [targetElement]);
110
+ }, [targetElement?.toString()]);
110
111
 
111
112
  useEffect(() => {
112
113
  if (targetElement && content) {
@@ -135,9 +136,10 @@ const usePopover = ({
135
136
  }
136
137
  }
137
138
  };
138
- }, [targetElement, content, current, currentPopover]);
139
+ }, [targetElement?.toString(), content?.toString(), current, currentPopover]);
139
140
 
140
141
  useUnmount(() => {
142
+ console.log('UNMOUNTING POPOVER', content);
141
143
  cancelTimeout();
142
144
  });
143
145
 
@@ -1,15 +1,26 @@
1
- import { IReqoreTooltip } from '../types/global';
1
+ import { useEffect, useState } from 'react';
2
+ import { IReqoreTooltip, TReqoreTooltipProp } from '../types/global';
2
3
  import usePopover from './usePopover';
3
4
 
4
5
  export const useTooltip = (
5
6
  targetElement: HTMLElement | undefined,
6
- tooltip?: string | IReqoreTooltip
7
+ tooltip?: TReqoreTooltipProp
7
8
  ): void => {
8
- const popoverData = typeof tooltip === 'string' ? { content: tooltip } : tooltip;
9
+ const [element, setElement] = useState<HTMLElement | undefined>(undefined);
10
+ const [data, setData] = useState<string | IReqoreTooltip | undefined>(undefined);
11
+
12
+ useEffect(() => {
13
+ if (targetElement && tooltip) {
14
+ setElement(targetElement);
15
+ setData(tooltip);
16
+ }
17
+ }, [targetElement?.toString(), JSON.stringify(tooltip)]);
18
+
19
+ const popoverData = typeof data === 'string' ? { content: data } : data;
9
20
 
10
21
  usePopover({
11
22
  ...popoverData,
12
- targetElement,
23
+ targetElement: element,
13
24
  show: !!popoverData?.content,
14
25
  });
15
26
  };
package/src/index.tsx CHANGED
@@ -2,6 +2,7 @@ export { default as ReqoreBreadcrumbs } from './components/Breadcrumbs';
2
2
  export { default as ReqoreBreadcrumbsItem } from './components/Breadcrumbs/item';
3
3
  export { default as ReqoreButton } from './components/Button';
4
4
  export { default as ReqoreCheckbox } from './components/Checkbox';
5
+ export { ReqoreCollection } from './components/Collection';
5
6
  export { ReqoreColumns } from './components/Columns';
6
7
  export { ReqoreColumn } from './components/Columns/column';
7
8
  export { ReqoreComment } from './components/Comment';