superdesk-ui-framework 3.0.17 → 3.0.19

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 (59) hide show
  1. package/app/styles/_avatar.scss +175 -25
  2. package/app/styles/design-tokens/_new-colors.scss +35 -2
  3. package/app-typescript/components/Icon.tsx +7 -1
  4. package/app-typescript/components/ShowPopup.tsx +173 -0
  5. package/app-typescript/components/Spacer.tsx +0 -8
  6. package/app-typescript/components/WithPagination.tsx +4 -4
  7. package/app-typescript/components/WithPopover.tsx +43 -0
  8. package/app-typescript/components/avatar/avatar-action-add.tsx +27 -0
  9. package/app-typescript/components/avatar/avatar-group.tsx +86 -0
  10. package/app-typescript/components/avatar/avatar-image.tsx +26 -0
  11. package/app-typescript/components/avatar/avatar-number.tsx +16 -0
  12. package/app-typescript/components/avatar/avatar-placeholder.tsx +35 -0
  13. package/app-typescript/components/avatar/avatar-text.tsx +19 -0
  14. package/app-typescript/components/avatar/avatar-wrapper.tsx +72 -0
  15. package/app-typescript/components/avatar/avatar.tsx +48 -0
  16. package/app-typescript/components/avatar/interfaces.ts +3 -0
  17. package/app-typescript/index.ts +8 -4
  18. package/dist/avatar_dummy.svg +4 -0
  19. package/dist/examples.bundle.js +3271 -2470
  20. package/dist/react/Avatar.tsx +628 -307
  21. package/dist/superdesk-ui.bundle.css +139 -27
  22. package/dist/superdesk-ui.bundle.js +2689 -1846
  23. package/dist/vendor.bundle.js +22 -22
  24. package/examples/pages/react/Avatar.tsx +628 -307
  25. package/images/avatar_dummy.svg +4 -0
  26. package/package.json +2 -1
  27. package/react/components/Icon.d.ts +1 -0
  28. package/react/components/Icon.js +1 -1
  29. package/react/components/ShowPopup.d.ts +10 -0
  30. package/react/components/ShowPopup.js +158 -0
  31. package/react/components/Spacer.d.ts +30 -0
  32. package/react/components/Spacer.js +86 -0
  33. package/react/components/WithPagination.d.ts +1 -1
  34. package/react/components/WithPagination.js +3 -3
  35. package/react/components/WithPopover.d.ts +18 -0
  36. package/react/components/WithPopover.js +65 -0
  37. package/react/components/avatar/avatar-action-add.d.ts +9 -0
  38. package/react/components/avatar/avatar-action-add.js +59 -0
  39. package/react/components/avatar/avatar-group.d.ts +18 -0
  40. package/react/components/avatar/avatar-group.js +104 -0
  41. package/react/components/avatar/avatar-image.d.ts +9 -0
  42. package/react/components/avatar/avatar-image.js +62 -0
  43. package/react/components/avatar/avatar-number.d.ts +9 -0
  44. package/react/components/avatar/avatar-number.js +56 -0
  45. package/react/components/avatar/avatar-placeholder.d.ts +14 -0
  46. package/react/components/avatar/avatar-placeholder.js +57 -0
  47. package/react/components/avatar/avatar-text.d.ts +9 -0
  48. package/react/components/avatar/avatar-text.js +54 -0
  49. package/react/components/avatar/avatar-wrapper.d.ts +26 -0
  50. package/react/components/{Avatar.js → avatar/avatar-wrapper.js} +16 -57
  51. package/react/components/avatar/avatar.d.ts +17 -0
  52. package/react/components/avatar/avatar.js +59 -0
  53. package/react/components/avatar/interfaces.d.ts +3 -0
  54. package/react/components/avatar/interfaces.js +2 -0
  55. package/react/index.d.ts +8 -4
  56. package/react/index.js +20 -11
  57. package/app-typescript/components/Avatar.tsx +0 -122
  58. package/dist/avatar_64.png +0 -0
  59. package/react/components/Avatar.d.ts +0 -42
@@ -2,25 +2,30 @@
2
2
  display: inline-block;
3
3
  position: relative; // required for absolutely positioned indicators
4
4
 
5
- &--indicator-status--offline {
6
- display: block;
7
- background-color: var(--sd-item__main-Bg);
8
- height: 8px;
9
- width: 8px;
10
- border-radius: $border-radius__base--full;
11
- position: absolute;
12
- inset-block-end: -1px;
13
- inset-inline-start: auto;
14
- inset-inline-end: -4px;
15
- box-shadow: 0px 0 0 2px var(--sd-item__main-Bg);
16
- border: 1px solid #a2c59e;
17
- box-sizing: border-box;
5
+ &.sd-avatar--indicator-status--offline {
6
+ .sd-avatar-content {
7
+ outline: 2px solid var(--sd-colour-avatar-outline--offline);
8
+ outline-offset: 2px;
9
+ }
10
+ &.sd-avatar--x-small,
11
+ &.sd-avatar--small {
12
+ .sd-avatar-content {
13
+ outline: 1px solid var(--sd-colour-avatar-outline--offline);
14
+ }
15
+ }
18
16
  }
19
17
 
20
- &--indicator-status--online {
21
- @extend .sd-avatar--indicator-status--offline;
22
- background-color: #67b461;
23
- border: 1px solid #67b461;
18
+ &.sd-avatar--indicator-status--online {
19
+ .sd-avatar-content {
20
+ outline: 2px solid var(--sd-colour-avatar-outline--online);
21
+ outline-offset: 2px;
22
+ }
23
+ &.sd-avatar--x-small,
24
+ &.sd-avatar--small {
25
+ .sd-avatar-content {
26
+ outline: 1px solid var(--sd-colour-avatar-outline--online);
27
+ }
28
+ }
24
29
  }
25
30
 
26
31
  &--indicator-admin {
@@ -46,6 +51,17 @@
46
51
  }
47
52
  }
48
53
 
54
+ &--x-small {
55
+ height: 20px;
56
+ width: 20px;
57
+ font-size: 1rem;
58
+
59
+ .sd-avatar--indicator-admin {
60
+ inset-block-start: -4px;
61
+ left: -6px;
62
+ }
63
+ }
64
+
49
65
  &--small {
50
66
  height: 24px;
51
67
  width: 24px;
@@ -60,7 +76,7 @@
60
76
  &--medium {
61
77
  height: 30px;
62
78
  width: 30px;
63
- font-size: 1rem;
79
+ font-size: 1.4rem;
64
80
  }
65
81
 
66
82
  &--large {
@@ -147,25 +163,135 @@
147
163
  text-transform: uppercase;
148
164
  letter-spacing: -0.03em;
149
165
  overflow: hidden;
150
-
166
+
151
167
  > img {
152
168
  width: 100%;
153
169
  }
154
170
 
155
171
  &--text {
156
- background-color: #005b7f;
172
+ background-color: var(--sd-colour-avatar-bg);
157
173
  }
158
-
159
- &--empty {
160
- background-color: #005b7f;
161
- background-image: url('~../../images/avatar_64.png');
174
+
175
+ &--dummy-img {
176
+ background-color: var(--sd-colour-avatar-bg);
177
+ background-image: url('~../../images/avatar_dummy.svg');
162
178
  background-repeat: no-repeat;
163
179
  background-size: cover;
164
- box-shadow: inset 0 0 0 1px #005b7f;
180
+ border: 1px solid var(--sd-colour-avatar-border);
181
+ //box-shadow: inset 0 0 0 1px #005b7f;
182
+ }
183
+ &.sd-avatar-content--add-item {
184
+ background-color: var(--sd-colour-avatar-bg--light);
185
+ border: 1px dashed var(--sd-colour-avatar-border--light);
186
+ background-image: linear-gradient(var(--sd-colour-avatar-add) 0 0), linear-gradient(var(--sd-colour-avatar-add) 0 0);
187
+ background-position:center;
188
+ background-size: 50% 2px,2px 50%; /*thickness = 2px, length = 50% (25px)*/
189
+ background-repeat:no-repeat;
190
+ outline: 1px solid transparent;
191
+ outline-offset: 0px;
192
+ transition: all 0.2s ease;
193
+ }
194
+
195
+ &.sd-avatar-content--add-item--clickable {
196
+ &:hover {
197
+ background-image: linear-gradient(var(--sd-colour-avatar-add--hover) 0 0), linear-gradient(var(--sd-colour-avatar-add--hover) 0 0);
198
+ cursor: pointer;
199
+ outline: 1px solid var(--sd-colour-interactive);
200
+ outline-offset: 2px;
201
+ }
202
+ &:active {
203
+ background-image: linear-gradient(var(--sd-colour-avatar-add) 0 0), linear-gradient(var(--sd-colour-avatar-add) 0 0);
204
+ cursor: pointer;
205
+ outline: 2px solid var(--sd-colour-interactive);
206
+ }
207
+ }
208
+
209
+ &.sd-avatar-content--number {
210
+ background-color: var(--sd-colour-avatar-bg--light);
211
+ color: var(--color-text-light);
212
+ outline: 1px solid transparent;
213
+ outline-offset: 0px;
214
+ transition: all 0.2s ease;
215
+ &:hover {
216
+ cursor: pointer;
217
+ outline: 1px solid var(--sd-colour-interactive);
218
+ outline-offset: 2px;
219
+ }
220
+ &:active {
221
+ cursor: pointer;
222
+ outline: 2px solid var(--sd-colour-interactive);
223
+ }
224
+ }
225
+ }
226
+
227
+ &.sd-avatar--empty-light {
228
+ .sd-avatar-content--dummy-img {
229
+ background-color: var(--sd-colour-avatar-bg--light);
230
+ border: 1px dashed var(--sd-colour-avatar-border--light);
231
+ }
232
+ }
233
+
234
+ .sd-avatar__icon {
235
+ position: absolute;
236
+ display: flex;
237
+ align-items: center;
238
+ justify-content: center;
239
+ z-index: 1;
240
+ inset-block-end: -4px;
241
+ inset-inline-end: -4px;
242
+ [class^="icon-"], [class*=" icon-"] {
243
+ text-shadow: -1px 1px 0 var(--sd-item__main-Bg), 1px 1px 0 var(--sd-item__main-Bg), 1px -1px 0 var(--sd-item__main-Bg), -1px -1px 0 var(--sd-item__main-Bg);
244
+ }
245
+
246
+ }
247
+ &.sd-avatar--x-small {
248
+ .sd-avatar__icon {
249
+ inset-block-end: -4px;
250
+ inset-inline-end: -10px;
251
+ }
252
+ }
253
+ &.sd-avatar--small {
254
+ .sd-avatar__icon {
255
+ inset-block-end: -4px;
256
+ inset-inline-end: -8px;
257
+ }
258
+ }
259
+ &.sd-avatar--medium {
260
+ .sd-avatar__icon {
261
+ inset-block-end: -3px;
262
+ inset-inline-end: -6px;
263
+ }
264
+ }
265
+ &.sd-avatar--large {
266
+ .sd-avatar__icon {
267
+ inset-block-end: -1px;
268
+ inset-inline-end: -4px;
269
+ }
270
+ }
271
+ &.sd-avatar--x-large {
272
+ .sd-avatar__icon {
273
+ inset-block-end: -2px;
274
+ inset-inline-end: -4px;
275
+ [class^="icon-"], [class*=" icon-"] {
276
+ --icon-base-size: 32px;
277
+ text-shadow: -2px 2px 0 var(--sd-item__main-Bg), 2px 2px 0 var(--sd-item__main-Bg), 2px -2px 0 var(--sd-item__main-Bg), -2px -2px 0 var(--sd-item__main-Bg);
278
+ }
279
+ }
280
+ }
281
+ &.sd-avatar--xx-large {
282
+ .sd-avatar__icon {
283
+ inset-block-end: -1px;
284
+ inset-inline-end: -2px;
285
+ [class^="icon-"], [class*=" icon-"] {
286
+ --icon-base-size: 32px;
287
+ text-shadow: -2px 2px 0 var(--sd-item__main-Bg), 2px 2px 0 var(--sd-item__main-Bg), 2px -2px 0 var(--sd-item__main-Bg), -2px -2px 0 var(--sd-item__main-Bg);
288
+ }
165
289
  }
166
290
  }
167
291
  }
168
292
 
293
+
294
+
169
295
  .sd-avatar-group {
170
296
  display: flex;
171
297
  &.sd-avatar-group--stacked {
@@ -180,8 +306,32 @@
180
306
  &--large {
181
307
  margin: 0 -1.2rem 0 0;
182
308
  }
309
+ &:hover {
310
+ z-index: 100;
311
+ }
183
312
  }
184
313
  margin-inline-end: 8px;
314
+ &.sd-avatar-group--stacked--gap-small {
315
+ gap: $sd-base-increment * 0.5;
316
+ > .sd-avatar {
317
+ margin: 0;
318
+ }
319
+ margin-inline-end: 0;
320
+ }
321
+ &.sd-avatar-group--stacked--gap-medium {
322
+ gap: $sd-base-increment * 1;
323
+ > .sd-avatar {
324
+ margin: 0;
325
+ }
326
+ margin-inline-end: 0;
327
+ }
328
+ &.sd-avatar-group--stacked--gap-large {
329
+ gap: $sd-base-increment * 1.5;
330
+ > .sd-avatar {
331
+ margin: 0;
332
+ }
333
+ margin-inline-end: 0;
334
+ }
185
335
  }
186
336
  &.sd-avatar-group--grid {
187
337
  flex-wrap: wrap;
@@ -350,6 +350,25 @@
350
350
 
351
351
  --sd-colour__tag-label-Bg--inverse: var(--sd-colour-bg--08);
352
352
  --sd-colour__tag-label-Txt--inverse: hsla(214, 13%, 98%, 1);
353
+
354
+ --sd-colour-avatar-bg: hsl(197, 100%, 25%);
355
+ --sd-colour-avatar-border: var(--sd-colour-avatar-bg);
356
+
357
+ --sd-colour-avatar-bg--light: hsla(214, 13%, 90%, 1);
358
+ --sd-colour-avatar-border--light: hsla(214, 13%, 65%, 1);
359
+ --sd-colour-avatar-border--light-hover: hsla(214, 13%, 45%, 1);
360
+ --sd-colour-avatar-dummy: hsla(214, 13%, 75%, 0.60);
361
+ --sd-colour-avatar-add: hsla(214, 13%, 55%, 1);
362
+ --sd-colour-avatar-add--hover: hsla(214, 13%, 45%, 1);
363
+
364
+ --sd-colour-avatar-outline--offline: hsla(214, 13%, 85%, 1);
365
+ --sd-colour-avatar-outline--online: var(--sd-colour-success);
366
+
367
+ --sd-colour-state--default: var(--color-text-lighter);
368
+ --sd-colour-state--in-progress: var(--sd-colour-highlight);
369
+ --sd-colour-state--done: var(--sd-colour-success);
370
+
371
+
353
372
  }
354
373
 
355
374
 
@@ -495,6 +514,20 @@
495
514
 
496
515
  --sd-colour__tag-label-Bg--inverse: hsla(214, 13%, 55%, 0.95);
497
516
  --sd-colour__tag-label-Txt--inverse: hsla(214, 13%, 10%, 1);
517
+
518
+ --sd-colour-avatar-bg: hsl(197, 100%, 25%);
519
+ --sd-colour-avatar-border: hsl(197, 100%, 25%);
520
+
521
+ --sd-colour-avatar-bg--light: hsla(214, 13%, 20%, 1);
522
+ --sd-colour-avatar-border--light: hsla(214, 13%, 45%, 1);
523
+ --sd-colour-avatar-border--light-hover: hsla(214, 13%, 65%, 1);
524
+ --sd-colour-avatar-dummy: hsla(214, 13%, 98%, 0.25);
525
+ --sd-colour-avatar-add: hsla(214, 13%, 65%, 1);
526
+ --sd-colour-avatar-add--hover: hsla(214, 13%, 90%, 1);
527
+
528
+ --sd-colour-state--default: var(--color-text-lighter);
529
+ --sd-colour-state--in-progress: var(--sd-colour-highlight);
530
+ --sd-colour-state--done: var(--sd-colour-success);
498
531
  }
499
532
 
500
533
 
@@ -629,6 +662,7 @@
629
662
  --color-navbutton-bg-dark-hover: hsla(214, 13%, 60%, 1);
630
663
 
631
664
  --color-navbutton-shadow-active: hsla(214, 13%, 5%, 0.12);
665
+
632
666
  }
633
667
 
634
668
  // CSS variables for dark theme
@@ -711,8 +745,7 @@
711
745
  [class*=" big-icon--"] {
712
746
  color: var(--color-text);
713
747
  }
714
-
715
- }
748
+ }
716
749
 
717
750
  /// ======= END from _colors.scss ======== ///////////
718
751
  /// ====================================== ///////////
@@ -7,6 +7,7 @@ interface IProps {
7
7
  className?: string;
8
8
  scale?: '2x' | '3x' | '4x';
9
9
  ariaHidden?: boolean;
10
+ color?: string;
10
11
  }
11
12
 
12
13
  export class Icon extends React.PureComponent<IProps> {
@@ -19,7 +20,12 @@ export class Icon extends React.PureComponent<IProps> {
19
20
  [`scale--${this.props.scale}`]: this.props.scale,
20
21
  });
21
22
  return (
22
- <i className={classes} aria-label={this.props.name} aria-hidden={this.props.ariaHidden}></i>
23
+ <i
24
+ className={classes}
25
+ aria-label={this.props.name}
26
+ aria-hidden={this.props.ariaHidden}
27
+ style={{color: this.props.color}}
28
+ />
23
29
  );
24
30
  }
25
31
  }
@@ -0,0 +1,173 @@
1
+
2
+ import * as React from 'react';
3
+ import ReactDOM from 'react-dom';
4
+ import {createPopper, Instance as PopperInstance, Placement, Modifier} from '@popperjs/core';
5
+ import {throttle} from 'lodash';
6
+ import maxSize from 'popper-max-size-modifier';
7
+
8
+ interface IPropsPopupPositioner {
9
+ referenceElement: HTMLElement;
10
+ placement: Placement;
11
+ zIndex?: number;
12
+ onClose(): void;
13
+ closeOnHoverEnd?: boolean;
14
+ }
15
+
16
+ class PopupPositioner extends React.PureComponent<IPropsPopupPositioner> {
17
+ private wrapperEl: HTMLDivElement | null;
18
+ private popper: PopperInstance | null;
19
+
20
+ constructor(props: IPropsPopupPositioner) {
21
+ super(props);
22
+
23
+ this.closeOnClick = this.closeOnClick.bind(this);
24
+ this.closeOnScroll = throttle(this.closeOnScroll.bind(this), 200);
25
+ this.closeOnMouseLeave = this.closeOnMouseLeave.bind(this);
26
+ this.wrapperEl = null;
27
+ this.popper = null;
28
+ }
29
+
30
+ closeOnClick(event: MouseEvent) {
31
+ if (this.wrapperEl == null) {
32
+ return;
33
+ }
34
+
35
+ if (
36
+ this.props.referenceElement.contains(event.target as Node) !== true
37
+ && this.wrapperEl.contains(event.target as Node) !== true
38
+ ) {
39
+ this.props.onClose();
40
+ }
41
+ }
42
+
43
+ closeOnScroll(event: Event) {
44
+ if (this.wrapperEl == null) {
45
+ return;
46
+ }
47
+
48
+ if (this.wrapperEl.contains(event.target as Node) !== true) {
49
+ this.props.onClose();
50
+ }
51
+ }
52
+
53
+ closeOnMouseLeave(event: MouseEvent) {
54
+ if (this.wrapperEl == null) {
55
+ return;
56
+ }
57
+
58
+ if (this.wrapperEl.contains(event.target as Node) !== true) {
59
+ this.props.onClose();
60
+ }
61
+ }
62
+
63
+ componentDidMount() {
64
+ window.addEventListener('click', this.closeOnClick, {capture: true});
65
+ window.addEventListener('scroll', this.closeOnScroll, true);
66
+
67
+ if (this.props.closeOnHoverEnd && this.wrapperEl != null) {
68
+ this.props.referenceElement.addEventListener('mouseleave', this.closeOnMouseLeave);
69
+ this.wrapperEl.addEventListener('mouseleave', this.closeOnMouseLeave);
70
+ }
71
+
72
+ const applyMaxSize: Modifier<any, any> = {
73
+ name: 'applyMaxSize',
74
+ enabled: true,
75
+ phase: 'beforeWrite',
76
+ requires: ['maxSize'],
77
+ fn: ({state}) => {
78
+ const {height} = state.modifiersData.maxSize;
79
+
80
+ // subtracting 10 in order to make a gap between the edge of the viewport
81
+ state.styles.popper.maxHeight = `${height - 10}px`;
82
+ },
83
+ };
84
+
85
+ if (this.wrapperEl != null) {
86
+ /**
87
+ * Wait until referenceElement renders so createPopper
88
+ * can take its dimensions into account.
89
+ */
90
+ setTimeout(() => {
91
+ if (this.wrapperEl != null) {
92
+ this.popper = createPopper(
93
+ this.props.referenceElement,
94
+ this.wrapperEl,
95
+ {
96
+ placement: this.props.placement,
97
+ modifiers: [
98
+ maxSize,
99
+ applyMaxSize,
100
+ ],
101
+ },
102
+ );
103
+ }
104
+ }, 50);
105
+ }
106
+ }
107
+
108
+ componentWillUnmount() {
109
+ window.removeEventListener('click', this.closeOnClick);
110
+ window.removeEventListener('scroll', this.closeOnScroll, true);
111
+
112
+ if (this.props.closeOnHoverEnd && this.wrapperEl != null) {
113
+ this.props.referenceElement.removeEventListener('mouseleave', this.closeOnMouseLeave);
114
+ this.wrapperEl.removeEventListener('mouseleave', this.closeOnMouseLeave);
115
+ }
116
+
117
+ this.popper?.destroy?.();
118
+ }
119
+
120
+ render() {
121
+ return (
122
+ <div
123
+ ref={(el) => {
124
+ this.wrapperEl = el;
125
+ }}
126
+ style={{zIndex: this.props.zIndex ?? 1, position: 'absolute', left: '-100vw'}}
127
+ >
128
+ {this.props.children}
129
+ </div>
130
+ );
131
+ }
132
+ }
133
+
134
+ /**
135
+ * The popup will remove itself if click/scroll events are detected outside the popup.
136
+ */
137
+ export function showPopup(
138
+ referenceElement: HTMLElement,
139
+ placement: Placement,
140
+ Component: React.ComponentType<{closePopup(): void}>,
141
+ zIndex?: number,
142
+ closeOnHoverEnd?: boolean,
143
+ onClose?: () => void,
144
+ ): {close: () => void} {
145
+ const el = document.createElement('div');
146
+
147
+ document.body.appendChild(el);
148
+
149
+ const closeFn = () => {
150
+ ReactDOM.unmountComponentAtNode(el);
151
+ el.remove();
152
+ onClose?.();
153
+ };
154
+
155
+ ReactDOM.render(
156
+ (
157
+ <PopupPositioner
158
+ referenceElement={referenceElement}
159
+ placement={placement}
160
+ onClose={closeFn}
161
+ zIndex={zIndex}
162
+ closeOnHoverEnd={closeOnHoverEnd || false}
163
+ >
164
+ <Component
165
+ closePopup={closeFn}
166
+ />
167
+ </PopupPositioner>
168
+ ),
169
+ el,
170
+ );
171
+
172
+ return {close: closeFn};
173
+ }
@@ -1,5 +1,4 @@
1
1
  import * as React from 'react';
2
- import classNames from 'classnames';
3
2
 
4
3
  export interface IPropsSpacer {
5
4
  h?: boolean; // horizontal
@@ -21,13 +20,6 @@ export interface IPropsSpacer {
21
20
  }
22
21
 
23
22
  export class Spacer extends React.PureComponent<IPropsSpacer> {
24
- constructor(props: IPropsSpacer) {
25
- super(props);
26
- this.state = {
27
- items: [],
28
- };
29
-
30
- }
31
23
  render() {
32
24
  const {h, v, gap, justifyContent, alignItems, noGrow, noWrap} = this.props;
33
25
 
@@ -2,7 +2,7 @@ import * as React from 'react';
2
2
  import {Icon} from '../components/Icon';
3
3
 
4
4
  interface IProps<T> {
5
- getItems(pageNo: number, signal: AbortSignal): Promise<{items: Array<T>, itemCount: number}>;
5
+ getItems(pageNo: number, pageSize: number, signal: AbortSignal): Promise<{items: Array<T>, itemCount: number}>;
6
6
  children: (items: Array<T>) => JSX.Element;
7
7
  pageSize?: number;
8
8
  }
@@ -98,7 +98,7 @@ export class WithPagination<T> extends React.PureComponent<IProps<T>, IState<T>>
98
98
  }
99
99
 
100
100
  getPageSize() {
101
- return this.props.pageSize ?? 20;
101
+ return this.props.pageSize ?? 100;
102
102
  }
103
103
 
104
104
  switchPage(page: number) {
@@ -107,7 +107,7 @@ export class WithPagination<T> extends React.PureComponent<IProps<T>, IState<T>>
107
107
  }
108
108
 
109
109
  this.inProgress = true;
110
- this.props.getItems(page, this.abortController.signal).then((res) => {
110
+ this.props.getItems(page, this.getPageSize(), this.abortController.signal).then((res) => {
111
111
  this.inProgress = false;
112
112
  this.setState({items: res.items, currentPage: page}, () => {
113
113
  const scrollableEl = getScrollParent(this.ref);
@@ -123,7 +123,7 @@ export class WithPagination<T> extends React.PureComponent<IProps<T>, IState<T>>
123
123
  }
124
124
 
125
125
  componentDidMount(): void {
126
- this.props.getItems(1, this.abortController.signal).then((res) => {
126
+ this.props.getItems(1, this.getPageSize(), this.abortController.signal).then((res) => {
127
127
  this.pageCount = Math.ceil(res.itemCount / this.getPageSize());
128
128
  this.setState({items: res.items});
129
129
  });
@@ -0,0 +1,43 @@
1
+
2
+ import * as React from 'react';
3
+ import {Placement} from '@popperjs/core';
4
+ import {showPopup} from './ShowPopup';
5
+
6
+ export interface IPropsWithPopover {
7
+ children(toggle: (referenceElement: HTMLElement) => void): React.ReactNode;
8
+ placement: Placement;
9
+ component: React.ComponentType<{closePopup(): void}>;
10
+ zIndex?: number;
11
+ closeOnHoverEnd?: boolean;
12
+ onClose?: () => void;
13
+ }
14
+
15
+ export class WithPopover extends React.PureComponent<IPropsWithPopover> {
16
+ private closePopup?: () => void;
17
+
18
+ constructor(props: IPropsWithPopover) {
19
+ super(props);
20
+
21
+ this.togglePopup = this.togglePopup.bind(this);
22
+ }
23
+
24
+ togglePopup(referenceElement: HTMLElement) {
25
+ if (this.closePopup != null) {
26
+ this.closePopup();
27
+ this.closePopup = undefined;
28
+ } else {
29
+ this.closePopup = showPopup(
30
+ referenceElement,
31
+ this.props.placement,
32
+ this.props.component,
33
+ this.props.zIndex,
34
+ this.props.closeOnHoverEnd,
35
+ this.props.onClose,
36
+ ).close;
37
+ }
38
+ }
39
+
40
+ render(): React.ReactNode {
41
+ return this.props.children(this.togglePopup);
42
+ }
43
+ }
@@ -0,0 +1,27 @@
1
+ import * as React from 'react';
2
+ import {IPropsBase} from './interfaces';
3
+
4
+ interface IProps extends IPropsBase {
5
+ onClick?(): void;
6
+ }
7
+
8
+ export class AvatarContentAdd extends React.PureComponent<IProps> {
9
+ render() {
10
+ if (this.props.onClick == null) {
11
+ return (
12
+ <span
13
+ className="sd-avatar-content sd-avatar-content--add-item"
14
+ title={this.props.tooltipText}
15
+ />
16
+ );
17
+ } else {
18
+ return (
19
+ <button
20
+ className="sd-avatar-content sd-avatar-content--add-item sd-avatar-content--add-item--clickable"
21
+ title={this.props.tooltipText}
22
+ onClick={() => this.props.onClick?.()}
23
+ />
24
+ );
25
+ }
26
+ }
27
+ }