@qoretechnologies/reqore 0.36.5 → 0.36.6

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 (48) hide show
  1. package/__tests__/control_group.test.tsx +0 -1
  2. package/dist/components/Button/index.d.ts +2 -1
  3. package/dist/components/Button/index.d.ts.map +1 -1
  4. package/dist/components/Button/index.js +4 -1
  5. package/dist/components/Button/index.js.map +1 -1
  6. package/dist/components/ControlGroup/index.d.ts +2 -1
  7. package/dist/components/ControlGroup/index.d.ts.map +1 -1
  8. package/dist/components/ControlGroup/index.js +29 -14
  9. package/dist/components/ControlGroup/index.js.map +1 -1
  10. package/dist/components/Input/index.d.ts +2 -3
  11. package/dist/components/Input/index.d.ts.map +1 -1
  12. package/dist/components/Input/index.js.map +1 -1
  13. package/dist/components/Table/header.d.ts +1 -1
  14. package/dist/components/Table/header.d.ts.map +1 -1
  15. package/dist/components/Table/header.js +2 -2
  16. package/dist/components/Table/header.js.map +1 -1
  17. package/dist/components/Table/headerCell.d.ts +3 -3
  18. package/dist/components/Table/headerCell.d.ts.map +1 -1
  19. package/dist/components/Table/headerCell.js +5 -6
  20. package/dist/components/Table/headerCell.js.map +1 -1
  21. package/dist/components/Table/index.d.ts +3 -2
  22. package/dist/components/Table/index.d.ts.map +1 -1
  23. package/dist/components/Table/index.js.map +1 -1
  24. package/dist/helpers/utils.d.ts +2 -0
  25. package/dist/helpers/utils.d.ts.map +1 -1
  26. package/dist/helpers/utils.js +25 -1
  27. package/dist/helpers/utils.js.map +1 -1
  28. package/dist/hooks/usePopover.d.ts +1 -0
  29. package/dist/hooks/usePopover.d.ts.map +1 -1
  30. package/dist/hooks/usePopover.js +1 -1
  31. package/dist/hooks/usePopover.js.map +1 -1
  32. package/dist/hooks/useTooltip.d.ts.map +1 -1
  33. package/dist/hooks/useTooltip.js +3 -2
  34. package/dist/hooks/useTooltip.js.map +1 -1
  35. package/package.json +2 -1
  36. package/src/components/Button/index.tsx +3 -1
  37. package/src/components/ControlGroup/index.tsx +54 -24
  38. package/src/components/Input/index.tsx +4 -2
  39. package/src/components/Table/header.tsx +9 -12
  40. package/src/components/Table/headerCell.tsx +151 -144
  41. package/src/components/Table/index.tsx +4 -2
  42. package/src/helpers/utils.ts +22 -0
  43. package/src/hooks/usePopover.tsx +2 -1
  44. package/src/hooks/useTooltip.ts +7 -3
  45. package/src/stories/ControlGroup/ControlGroup.stories.tsx +1 -1
  46. package/src/stories/Table/Table.stories.tsx +23 -1
  47. package/tests.json +1 -1
  48. package/src/stories/Table/Tests.stories.tsx +0 -9
@@ -1,7 +1,7 @@
1
1
  /* @flow */
2
2
  import { rgba } from 'polished';
3
3
  import { Resizable } from 're-resizable';
4
- import { useMemo } from 'react';
4
+ import { memo, useMemo } from 'react';
5
5
  import styled from 'styled-components';
6
6
  import { IReqoreTableColumn, IReqoreTableSort } from '.';
7
7
  import { ReqoreButton, ReqoreControlGroup, ReqoreDropdown } from '../..';
@@ -13,12 +13,12 @@ import { TColumnsUpdater } from './header';
13
13
 
14
14
  export interface IReqoreTableHeaderCellProps
15
15
  extends Omit<IReqoreTableColumn, 'cell'>,
16
- Omit<IReqoreButtonProps, 'maxWidth'> {
16
+ Pick<IReqoreTableColumn['header'], 'content' | 'actions'>,
17
+ Omit<IReqoreButtonProps, 'maxWidth' | 'content'> {
17
18
  onSortChange?: (sort: string) => void;
18
19
  sortData?: IReqoreTableSort;
19
20
  onColumnsUpdate?: TColumnsUpdater;
20
21
  onFilterChange?: (dataId: string, filter: string) => void;
21
- actions?: IReqoreTableColumn['header']['actions'];
22
22
  }
23
23
 
24
24
  export interface IReqoreTableHeaderStyle {
@@ -42,155 +42,162 @@ export const StyledTableHeaderResize = styled.div`
42
42
  }
43
43
  `;
44
44
 
45
- export const ReqoreTableHeaderCell = ({
46
- width,
47
- maxWidth,
48
- minWidth,
49
- resizedWidth,
50
- grow,
51
- align,
52
- pin,
53
- onSortChange,
54
- dataId,
55
- sortable,
56
- sortData,
57
- className,
58
- onClick,
59
- onColumnsUpdate,
60
- resizable = true,
61
- filterPlaceholder,
62
- filterable,
63
- hideable = true,
64
- pinnable = true,
65
- filter,
66
- size,
67
- onFilterChange,
68
- actions,
69
- ...rest
70
- }: IReqoreTableHeaderCellProps) => {
71
- const items = useMemo(() => {
72
- let _items: IReqoreDropdownItem[] = [];
45
+ export const ReqoreTableHeaderCell = memo(
46
+ ({
47
+ width,
48
+ maxWidth,
49
+ minWidth,
50
+ resizedWidth,
51
+ grow,
52
+ align,
53
+ pin,
54
+ onSortChange,
55
+ dataId,
56
+ sortable,
57
+ sortData,
58
+ className,
59
+ onClick,
60
+ onColumnsUpdate,
61
+ resizable = true,
62
+ filterPlaceholder,
63
+ filterable,
64
+ hideable = true,
65
+ pinnable = true,
66
+ filter,
67
+ content,
68
+ size,
69
+ onFilterChange,
70
+ actions,
71
+ ...rest
72
+ }: IReqoreTableHeaderCellProps) => {
73
+ const items = useMemo(() => {
74
+ let _items: IReqoreDropdownItem[] = [];
73
75
 
74
- if (resizable || hideable) {
75
- if (resizable) {
76
- _items.push({
77
- label: 'Reset size',
78
- icon: 'HistoryLine',
79
- disabled: !resizedWidth || width === resizedWidth,
80
- onClick: () => {
81
- onColumnsUpdate?.(dataId, 'resizedWidth', width);
82
- },
83
- });
84
- }
76
+ if (resizable || hideable) {
77
+ if (resizable) {
78
+ _items.push({
79
+ label: 'Reset size',
80
+ icon: 'HistoryLine',
81
+ disabled: !resizedWidth || width === resizedWidth,
82
+ onClick: () => {
83
+ onColumnsUpdate?.(dataId, 'resizedWidth', width);
84
+ },
85
+ });
86
+ }
85
87
 
86
- if (pinnable) {
87
- _items.push({ divider: true, size: 'small', line: true });
88
+ if (pinnable) {
89
+ _items.push({ divider: true, size: 'small', line: true });
88
90
 
89
- _items.push({
90
- label: 'Pin left',
91
- icon: 'SkipBackLine',
92
- active: pin === 'left',
93
- intent: pin === 'left' ? 'info' : undefined,
94
- onClick: () => {
95
- onColumnsUpdate?.(dataId, 'pin', pin !== 'left' ? 'left' : undefined);
96
- },
97
- });
91
+ _items.push({
92
+ label: 'Pin left',
93
+ icon: 'SkipBackLine',
94
+ active: pin === 'left',
95
+ intent: pin === 'left' ? 'info' : undefined,
96
+ onClick: () => {
97
+ onColumnsUpdate?.(dataId, 'pin', pin !== 'left' ? 'left' : undefined);
98
+ },
99
+ });
98
100
 
99
- _items.push({
100
- label: 'Pin Right',
101
- icon: 'SkipForwardLine',
102
- active: pin === 'right',
103
- intent: pin === 'right' ? 'info' : undefined,
104
- onClick: () => {
105
- onColumnsUpdate?.(dataId, 'pin', pin !== 'right' ? 'right' : undefined);
106
- },
107
- });
108
- }
101
+ _items.push({
102
+ label: 'Pin Right',
103
+ icon: 'SkipForwardLine',
104
+ active: pin === 'right',
105
+ intent: pin === 'right' ? 'info' : undefined,
106
+ onClick: () => {
107
+ onColumnsUpdate?.(dataId, 'pin', pin !== 'right' ? 'right' : undefined);
108
+ },
109
+ });
110
+ }
109
111
 
110
- if (hideable) {
111
- _items.push({ divider: true, size: 'small', line: true });
112
+ if (hideable) {
113
+ _items.push({ divider: true, size: 'small', line: true });
112
114
 
113
- _items.push({
114
- label: 'Hide column',
115
- icon: 'EyeCloseLine',
116
- className: 'reqore-table-header-hide',
117
- onClick: () => {
118
- onColumnsUpdate?.(dataId, 'show', false);
119
- },
120
- });
115
+ _items.push({
116
+ label: 'Hide column',
117
+ icon: 'EyeCloseLine',
118
+ className: 'reqore-table-header-hide',
119
+ onClick: () => {
120
+ onColumnsUpdate?.(dataId, 'show', false);
121
+ },
122
+ });
123
+ }
121
124
  }
122
- }
123
125
 
124
- if (actions) {
125
- _items = [..._items, { divider: true, label: 'Other' }, ...actions];
126
- }
126
+ if (actions) {
127
+ _items = [..._items, { divider: true, label: 'Other' }, ...actions];
128
+ }
127
129
 
128
- return _items;
129
- }, [resizable, hideable, width, resizedWidth, onColumnsUpdate, dataId]);
130
+ return _items;
131
+ }, [resizable, hideable, width, resizedWidth, onColumnsUpdate, dataId]);
130
132
 
131
- return (
132
- <Resizable
133
- minWidth={minWidth || width}
134
- maxWidth={maxWidth}
135
- onResize={(_event, _direction, _component) => {
136
- onColumnsUpdate?.(dataId, 'resizedWidth', parseInt(_component.style.width));
137
- }}
138
- handleComponent={{
139
- right: <StyledTableHeaderResize />,
140
- }}
141
- style={{
142
- overflow: 'hidden',
143
- flexGrow: grow,
144
- }}
145
- size={{
146
- width: resizedWidth || width,
147
- height: undefined,
148
- }}
149
- enable={{
150
- right: resizable,
151
- }}
152
- >
153
- <ReqoreControlGroup fluid stack rounded={false} fill style={{ height: '100%' }}>
154
- <ReqoreButton
155
- {...rest}
156
- size={size}
157
- readOnly={!sortable && !onClick}
158
- className={`${className || ''} reqore-table-header-cell`}
159
- rounded={false}
160
- textAlign={align}
161
- rightIcon={
162
- sortable && sortData.by === dataId
163
- ? (`Arrow${sortData.direction === 'desc' ? 'Down' : 'Up'}Fill` as
164
- | 'ArrowDownFill'
165
- | 'ArrowUpFill')
166
- : rest.rightIcon
167
- }
168
- onClick={(e) => {
169
- if (sortable) {
170
- onSortChange?.(dataId);
171
- }
133
+ return (
134
+ <Resizable
135
+ minWidth={minWidth || width}
136
+ maxWidth={maxWidth}
137
+ onResize={(_event, _direction, _component) => {
138
+ onColumnsUpdate?.(dataId, 'resizedWidth', parseInt(_component.style.width));
139
+ }}
140
+ handleComponent={{
141
+ right: <StyledTableHeaderResize />,
142
+ }}
143
+ style={{
144
+ overflow: 'hidden',
145
+ flexGrow: grow,
146
+ }}
147
+ size={{
148
+ width: resizedWidth || width,
149
+ height: undefined,
150
+ }}
151
+ enable={{
152
+ right: resizable,
153
+ }}
154
+ >
155
+ <ReqoreControlGroup fluid stack rounded={false} fill style={{ height: '100%' }}>
156
+ {content ? (
157
+ content
158
+ ) : (
159
+ <ReqoreButton
160
+ {...rest}
161
+ size={size}
162
+ readOnly={!sortable && !onClick}
163
+ className={`${className || ''} reqore-table-header-cell`}
164
+ rounded={false}
165
+ textAlign={align}
166
+ rightIcon={
167
+ sortable && sortData.by === dataId
168
+ ? (`Arrow${sortData.direction === 'desc' ? 'Down' : 'Up'}Fill` as
169
+ | 'ArrowDownFill'
170
+ | 'ArrowUpFill')
171
+ : rest.rightIcon
172
+ }
173
+ onClick={(e) => {
174
+ if (sortable) {
175
+ onSortChange?.(dataId);
176
+ }
172
177
 
173
- onClick?.(e);
174
- }}
175
- />
176
- {filterable || hideable || resizable ? (
177
- <ReqoreDropdown<IReqoreButtonProps>
178
- icon='MoreLine'
179
- className='reqore-table-header-cell-options'
180
- fixed
181
- size={size}
182
- rounded={false}
183
- intent={filter ? 'info' : rest.intent}
184
- filterable={filterable}
185
- filterPlaceholder={filterPlaceholder || 'Filter by this column...'}
186
- filter={filter}
187
- onFilterChange={(value) => {
188
- onFilterChange?.(dataId, value);
189
- }}
190
- items={items}
191
- />
192
- ) : null}
193
- </ReqoreControlGroup>
194
- </Resizable>
195
- );
196
- };
178
+ onClick?.(e);
179
+ }}
180
+ />
181
+ )}
182
+ {filterable || hideable || resizable ? (
183
+ <ReqoreDropdown<IReqoreButtonProps>
184
+ icon='MoreLine'
185
+ className='reqore-table-header-cell-options'
186
+ fixed
187
+ size={size}
188
+ rounded={false}
189
+ intent={filter ? 'info' : rest.intent}
190
+ filterable={filterable}
191
+ filterPlaceholder={filterPlaceholder || 'Filter by this column...'}
192
+ filter={filter}
193
+ onFilterChange={(value) => {
194
+ onFilterChange?.(dataId, value);
195
+ }}
196
+ items={items}
197
+ />
198
+ ) : null}
199
+ </ReqoreControlGroup>
200
+ </Resizable>
201
+ );
202
+ }
203
+ );
@@ -59,7 +59,7 @@ export type TReqoreTableColumnContent =
59
59
  export interface IReqoreTableColumn extends IReqoreIntent {
60
60
  dataId: string;
61
61
  show?: boolean;
62
- grow?: 1 | 2 | 3 | 4;
62
+ grow?: 0 | 1 | 2 | 3 | 4;
63
63
  width?: number;
64
64
  minWidth?: number;
65
65
  maxWidth?: number;
@@ -79,8 +79,10 @@ export interface IReqoreTableColumn extends IReqoreIntent {
79
79
  header?: {
80
80
  columns?: IReqoreTableColumn[];
81
81
  component?: React.FC<IReqoreTableHeaderCellProps>;
82
+ // Content is the same as react children
83
+ content?: React.ReactNode;
82
84
  actions?: IReqoreDropdownItem[];
83
- } & Omit<IReqoreButtonProps, 'maxWidth'>;
85
+ } & Omit<IReqoreButtonProps, 'maxWidth' | 'content'>;
84
86
 
85
87
  cell?: {
86
88
  onClick?: (cellValue: any) => void;
@@ -128,3 +128,25 @@ export const alignToFlexAlign = (
128
128
  return 'flex-start';
129
129
  }
130
130
  };
131
+
132
+ export function decycle(obj, stack = []) {
133
+ if (!obj || typeof obj !== 'object') return obj;
134
+
135
+ if (stack.includes(obj)) return null;
136
+
137
+ const s = stack.concat([obj]);
138
+
139
+ return Array.isArray(obj)
140
+ ? obj.map((x) => decycle(x, s))
141
+ : Object.fromEntries(Object.entries(obj).map(([k, v]) => [k, decycle(v, s)]));
142
+ }
143
+
144
+ export const stringifyAndDecycleObject = (obj: any): string => {
145
+ return JSON.stringify(decycle(obj), (_key, value) => {
146
+ if (typeof value === 'function') {
147
+ return value.toString();
148
+ }
149
+
150
+ return value;
151
+ });
152
+ };
@@ -57,6 +57,7 @@ export interface IPopover
57
57
  maxHeight?: string;
58
58
  icon?: IReqoreIconName;
59
59
  title?: string;
60
+ updater?: string | number;
60
61
  }
61
62
 
62
63
  export interface IPopoverOptions extends IPopover {
@@ -164,7 +165,7 @@ const usePopover = ({
164
165
  if (openOnMount && targetElement) {
165
166
  _addPopover();
166
167
  }
167
- }, [targetElement?.toString()]);
168
+ }, [targetElement?.outerHTML]);
168
169
 
169
170
  useEffect(() => {
170
171
  if (targetElement && content) {
@@ -1,4 +1,4 @@
1
- import { useEffect, useState } from 'react';
1
+ import { useEffect, useMemo, useState } from 'react';
2
2
  import { IReqoreTooltip, TReqoreTooltipProp } from '../types/global';
3
3
  import usePopover from './usePopover';
4
4
 
@@ -8,13 +8,17 @@ export const useTooltip = (
8
8
  ): void => {
9
9
  const [element, setElement] = useState<HTMLElement | undefined>(undefined);
10
10
  const [data, setData] = useState<string | IReqoreTooltip | undefined>(undefined);
11
+ const content = useMemo(
12
+ () => (typeof tooltip === 'object' ? tooltip?.content : tooltip),
13
+ [tooltip]
14
+ );
11
15
 
12
16
  useEffect(() => {
13
- if (targetElement && tooltip) {
17
+ if (targetElement && content) {
14
18
  setElement(targetElement);
15
19
  setData(tooltip);
16
20
  }
17
- }, [targetElement?.toString(), tooltip?.toString()]);
21
+ }, [targetElement, content]);
18
22
 
19
23
  const popoverData = typeof data === 'string' ? { content: data } : data;
20
24
 
@@ -151,7 +151,7 @@ const Template: StoryFn<typeof ReqoreControlGroup> = (args) => {
151
151
  <>
152
152
  <ReqoreControlGroup {...args}>
153
153
  <ReqoreButton icon='PictureInPictureLine'>Button</ReqoreButton>
154
- <ReqoreButton icon='PictureInPictureLine' fluid>
154
+ <ReqoreButton icon='PictureInPictureLine' fluid shrink={0}>
155
155
  Fluid Button
156
156
  </ReqoreButton>
157
157
  <ReqoreButton
@@ -172,7 +172,7 @@ const defaultColumns: IReqoreTableColumn[] = [
172
172
  header: {
173
173
  icon: 'SettingsLine',
174
174
  },
175
- width: 100,
175
+ width: 120,
176
176
  align: 'center',
177
177
  pin: 'right',
178
178
 
@@ -287,6 +287,22 @@ const defaultColumnsWithPinnedColumns: IReqoreTableColumn[] = defaultColumns.map
287
287
  }
288
288
  );
289
289
 
290
+ const defaultColumnsWithCustomContentHeaders: IReqoreTableColumn[] = defaultColumns.map(
291
+ (column, index) => {
292
+ if (index === 4) {
293
+ return {
294
+ ...column,
295
+ header: {
296
+ ...column.header,
297
+ content: <ReqoreInput icon='PriceTag2Fill' value='Custom input value' rounded={false} />,
298
+ },
299
+ };
300
+ }
301
+
302
+ return column;
303
+ }
304
+ );
305
+
290
306
  const meta = {
291
307
  title: 'Collections/Table/Stories',
292
308
  component: ReqoreTable,
@@ -519,6 +535,12 @@ export const CustomPaging: Story = {
519
535
  },
520
536
  };
521
537
 
538
+ export const CustomHeaderContent: Story = {
539
+ args: {
540
+ columns: defaultColumnsWithCustomContentHeaders,
541
+ },
542
+ };
543
+
522
544
  const CustomHeaderCell = (props: IReqoreCustomHeaderCellProps) => {
523
545
  if (props.hasColumns) {
524
546
  return <ReqoreH3 intent='success'>{props.label}</ReqoreH3>;