superdesk-ui-framework 3.0.66 → 3.0.68

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/app/styles/components/_list-item.scss +22 -11
  2. package/app-typescript/components/Autocomplete.tsx +9 -3
  3. package/app-typescript/components/Badge.tsx +16 -2
  4. package/app-typescript/components/Dropdown.tsx +3 -1
  5. package/app-typescript/components/DropdownFirst.tsx +14 -2
  6. package/app-typescript/components/DurationInput.tsx +19 -4
  7. package/app-typescript/components/EmptyState.tsx +11 -2
  8. package/app-typescript/components/Layouts/Panel.tsx +12 -1
  9. package/app-typescript/components/Lists/ContentList.tsx +5 -1
  10. package/app-typescript/components/Modal.tsx +10 -1
  11. package/app-typescript/components/Navigation/BottomNav.tsx +9 -2
  12. package/app-typescript/components/Navigation/QuickNavBar.tsx +10 -2
  13. package/app-typescript/components/Navigation/SideBarMenu.tsx +9 -4
  14. package/app-typescript/components/SidebarMenu.tsx +8 -1
  15. package/app-typescript/components/TabList.tsx +5 -1
  16. package/app-typescript/components/TagInput.tsx +4 -1
  17. package/app-typescript/components/ThemeSelector.tsx +13 -2
  18. package/app-typescript/components/TreeMenu.tsx +127 -122
  19. package/app-typescript/components/TreeSelect/TreeSelect.tsx +157 -141
  20. package/app-typescript/components/WithPortal.tsx +49 -0
  21. package/app-typescript/components/avatar/avatar-image.tsx +2 -0
  22. package/app-typescript/components/avatar/avatar.tsx +2 -1
  23. package/dist/examples.bundle.js +1446 -1318
  24. package/dist/playgrounds/planning.html +121 -43
  25. package/dist/playgrounds/react-playgrounds/CoreLayout.tsx +398 -385
  26. package/dist/playgrounds/react-playgrounds/EditorTest.tsx +359 -365
  27. package/dist/playgrounds/react-playgrounds/FirstPlayground.tsx +33 -33
  28. package/dist/playgrounds/react-playgrounds/Multiedit.tsx +227 -231
  29. package/dist/playgrounds/react-playgrounds/PageLayoutTest.tsx +41 -38
  30. package/dist/playgrounds/react-playgrounds/PersonalProfile.tsx +76 -96
  31. package/dist/playgrounds/react-playgrounds/RundownEditor.tsx +73 -101
  32. package/dist/playgrounds/react-playgrounds/Rundowns.tsx +788 -729
  33. package/dist/playgrounds/react-playgrounds/SamsPlayground.tsx +35 -26
  34. package/dist/playgrounds/react-playgrounds/TestGround.tsx +99 -128
  35. package/dist/playgrounds/react-playgrounds/UiPlayground.tsx +40 -25
  36. package/dist/playgrounds/react-playgrounds/components/GraphicButton.tsx +6 -5
  37. package/dist/playgrounds/react-playgrounds/components/Layout.tsx +0 -2
  38. package/dist/playgrounds/react-playgrounds/components/SearchBar.tsx +16 -9
  39. package/dist/playgrounds/react-playgrounds/tsconfig.json +4 -0
  40. package/dist/superdesk-ui.bundle.css +24 -14
  41. package/dist/superdesk-ui.bundle.js +830 -727
  42. package/dist/vendor.bundle.js +14 -14
  43. package/examples/pages/playgrounds/planning.html +121 -43
  44. package/examples/pages/playgrounds/react-playgrounds/CoreLayout.tsx +398 -385
  45. package/examples/pages/playgrounds/react-playgrounds/EditorTest.tsx +359 -365
  46. package/examples/pages/playgrounds/react-playgrounds/FirstPlayground.tsx +33 -33
  47. package/examples/pages/playgrounds/react-playgrounds/Multiedit.tsx +227 -231
  48. package/examples/pages/playgrounds/react-playgrounds/PageLayoutTest.tsx +41 -38
  49. package/examples/pages/playgrounds/react-playgrounds/PersonalProfile.tsx +76 -96
  50. package/examples/pages/playgrounds/react-playgrounds/RundownEditor.tsx +73 -101
  51. package/examples/pages/playgrounds/react-playgrounds/Rundowns.tsx +788 -729
  52. package/examples/pages/playgrounds/react-playgrounds/SamsPlayground.tsx +35 -26
  53. package/examples/pages/playgrounds/react-playgrounds/TestGround.tsx +99 -128
  54. package/examples/pages/playgrounds/react-playgrounds/UiPlayground.tsx +40 -25
  55. package/examples/pages/playgrounds/react-playgrounds/components/GraphicButton.tsx +6 -5
  56. package/examples/pages/playgrounds/react-playgrounds/components/Layout.tsx +0 -2
  57. package/examples/pages/playgrounds/react-playgrounds/components/SearchBar.tsx +16 -9
  58. package/examples/pages/playgrounds/react-playgrounds/tsconfig.json +4 -0
  59. package/package.json +3 -2
  60. package/react/components/Autocomplete.js +2 -2
  61. package/react/components/Badge.js +1 -1
  62. package/react/components/Dropdown.js +3 -1
  63. package/react/components/DropdownFirst.js +6 -2
  64. package/react/components/DurationInput.js +5 -1
  65. package/react/components/EmptyState.js +2 -1
  66. package/react/components/Lists/ContentList.js +1 -1
  67. package/react/components/Navigation/BottomNav.js +4 -1
  68. package/react/components/Navigation/QuickNavBar.js +2 -1
  69. package/react/components/Navigation/SideBarMenu.js +3 -1
  70. package/react/components/TabList.js +2 -1
  71. package/react/components/TagInput.js +1 -1
  72. package/react/components/TreeSelect/TreeSelect.d.ts +3 -2
  73. package/react/components/TreeSelect/TreeSelect.js +81 -73
  74. package/react/components/WithPortal.d.ts +14 -0
  75. package/react/components/WithPortal.js +69 -0
  76. package/react/components/avatar/avatar.js +2 -1
  77. /package/dist/playgrounds/dummy-data/{items.js → items.ts} +0 -0
  78. /package/examples/pages/playgrounds/dummy-data/{items.js → items.ts} +0 -0
@@ -12,7 +12,7 @@ import {SelectPreview} from '../SelectPreview';
12
12
  import {TreeSelectPill} from './TreeSelectPill';
13
13
  import {getPrefixedItemId, TreeSelectItem} from './TreeSelectItem';
14
14
  import {keyboardNavigation} from './KeyboardNavigation';
15
- import {createPortal} from 'react-dom';
15
+ import {WithPortal} from '../WithPortal';
16
16
 
17
17
  interface IState<T> {
18
18
  value: Array<T>;
@@ -35,7 +35,7 @@ interface IPropsBase<T> extends IInputWrapper {
35
35
  value?: Array<T>;
36
36
  selectBranchWithChildren?: boolean;
37
37
  readOnly?: boolean;
38
- popoverWidth?: 'medium' | 'match-input';
38
+ width?: 'medium' | 'match-input';
39
39
  inputWidth?: '100%';
40
40
  allowMultiple?: boolean;
41
41
  loading?: boolean;
@@ -43,6 +43,7 @@ interface IPropsBase<T> extends IInputWrapper {
43
43
  placeholder?: string;
44
44
  searchPlaceholder?: string;
45
45
  zIndex?: number;
46
+ 'data-test-id'?: string;
46
47
  getLabel(item: T): string;
47
48
  getId(item: T): string;
48
49
  getBackgroundColor?(item: T): string;
@@ -50,7 +51,6 @@ interface IPropsBase<T> extends IInputWrapper {
50
51
  optionTemplate?(item: T): React.ComponentType<T> | JSX.Element;
51
52
  valueTemplate?(item: T, Wrapper: React.ElementType): React.ComponentType<T> | JSX.Element;
52
53
  onChange(e: Array<T>): void;
53
- 'data-test-id'?: string;
54
54
  }
55
55
 
56
56
  interface IPropsSync<T> extends IPropsBase<T> {
@@ -111,6 +111,8 @@ export class TreeSelect<T> extends React.Component<IProps<T>, IState<T>> {
111
111
  this.toggleMenu = this.toggleMenu.bind(this);
112
112
  this.onMouseDown = this.onMouseDown.bind(this);
113
113
  this.onKeyDown = this.onKeyDown.bind(this);
114
+ this.onPressEsc = this.onPressEsc.bind(this);
115
+
114
116
  this.dropdownRef = React.createRef();
115
117
  this.ref = React.createRef();
116
118
  this.inputRef = React.createRef();
@@ -139,7 +141,10 @@ export class TreeSelect<T> extends React.Component<IProps<T>, IState<T>> {
139
141
  && (this.treeSelectRef.current?.contains(event.target as HTMLElement) !== true)
140
142
  && this.state.openDropdown
141
143
  ) {
142
- this.setState({openDropdown: false});
144
+ this.setState({
145
+ openDropdown: false,
146
+ searchFieldValue: '',
147
+ });
143
148
  }
144
149
  }
145
150
 
@@ -165,16 +170,27 @@ export class TreeSelect<T> extends React.Component<IProps<T>, IState<T>> {
165
170
  }
166
171
  }
167
172
 
173
+ onPressEsc = (event: KeyboardEvent) => {
174
+ if (event.key === 'Escape' && this.state.openDropdown) {
175
+ this.setState({
176
+ openDropdown: false,
177
+ searchFieldValue: '',
178
+ });
179
+ }
180
+ }
181
+
168
182
  componentDidMount = () => {
169
183
  this.recursion(this.state.options);
170
184
 
171
185
  document.addEventListener("mousedown", this.onMouseDown);
172
186
  document.addEventListener("keydown", this.onKeyDown);
187
+ document.addEventListener("keydown", this.onPressEsc);
173
188
  }
174
189
 
175
190
  componentWillUnmount(): void {
176
191
  document.removeEventListener("mousedown", this.onMouseDown);
177
192
  document.removeEventListener("keydown", this.onKeyDown);
193
+ document.addEventListener("keydown", this.onPressEsc);
178
194
  }
179
195
 
180
196
  componentDidUpdate(prevProps: Readonly<IProps<T>>, prevState: Readonly<IState<T>>): void {
@@ -203,17 +219,9 @@ export class TreeSelect<T> extends React.Component<IProps<T>, IState<T>> {
203
219
 
204
220
  toggleMenu() {
205
221
  if (this.state.openDropdown) {
206
- if (this.openDropdownRef.current && this.dropdownRef.current) {
207
- this.popperInstance = createPopper(this.openDropdownRef.current, this.dropdownRef.current, {
222
+ if (this.treeSelectRef.current && this.dropdownRef.current) {
223
+ this.popperInstance = createPopper(this.treeSelectRef.current, this.dropdownRef.current, {
208
224
  placement: 'bottom-start',
209
- modifiers: [
210
- {
211
- name: 'offset',
212
- options: {
213
- offset: [-4, 4],
214
- },
215
- },
216
- ],
217
225
  });
218
226
  }
219
227
 
@@ -632,7 +640,10 @@ export class TreeSelect<T> extends React.Component<IProps<T>, IState<T>> {
632
640
  data-test-id={this.props['data-test-id']}
633
641
  >
634
642
  <div
635
- className={`tags-input sd-input__input tags-input--${this.props.allowMultiple ? 'multi-select' : 'single-select'}`}
643
+ className={`
644
+ tags-input sd-input__input
645
+ tags-input--${this.props.allowMultiple ? 'multi-select' : 'single-select'}`
646
+ }
636
647
  ref={this.treeSelectRef}
637
648
  data-test-id={this.props.allowMultiple ? undefined : 'open-popover'}
638
649
  >
@@ -641,12 +652,18 @@ export class TreeSelect<T> extends React.Component<IProps<T>, IState<T>> {
641
652
  {this.props.readOnly
642
653
  || <button
643
654
  ref={this.openDropdownRef}
644
- className={`tags-input__add-button ${this.props.disabled ? 'tags-input__add-button--disabled' : ''}`}
655
+ className={`
656
+ tags-input__add-button
657
+ ${this.props.disabled ? 'tags-input__add-button--disabled' : ''}`
658
+ }
645
659
  onClick={(e) => {
646
660
  e.stopPropagation();
647
661
 
648
662
  if (!this.props.disabled) {
649
- this.setState({openDropdown: !this.state.openDropdown});
663
+ this.setState({
664
+ openDropdown: !this.state.openDropdown,
665
+ searchFieldValue: '',
666
+ });
650
667
  }
651
668
  }}
652
669
  data-test-id="open-popover"
@@ -760,7 +777,10 @@ export class TreeSelect<T> extends React.Component<IProps<T>, IState<T>> {
760
777
 
761
778
  {
762
779
  (this.props.readOnly !== true && this.props.required !== true) && (
763
- <span className="tags-input__remove-button" data-test-id="clear-value">
780
+ <span
781
+ className="tags-input__remove-button"
782
+ data-test-id="clear-value"
783
+ >
764
784
  <Icon name='remove-sign'></Icon>
765
785
  </span>
766
786
  )
@@ -784,136 +804,132 @@ export class TreeSelect<T> extends React.Component<IProps<T>, IState<T>> {
784
804
  }
785
805
  </div>
786
806
 
787
- {createPortal(
788
- this.state.openDropdown
789
- && <div data-test-id="tree-select-popover">
807
+ <WithPortal active={this.state.openDropdown} data-test-id="tree-select-popover">
808
+ <div
809
+ className={
810
+ "autocomplete autocomplete--multi-select"
811
+ + (this.props.width === 'medium' ? ' autocomplete--fixed-width' : '')
812
+ }
813
+ style={{
814
+ zIndex: this.props.zIndex,
815
+ width: this.treeSelectRef.current?.offsetWidth,
816
+ }}
817
+ ref={this.dropdownRef}
818
+ >
819
+ <div className='autocomplete__header'>
790
820
  <div
791
- className={
792
- "autocomplete autocomplete--multi-select"
793
- + (this.props.popoverWidth === 'medium' ? ' autocomplete--fixed-width' : '')
794
- }
795
- style={{
796
- zIndex: this.props.zIndex,
797
- width: this.treeSelectRef.current?.offsetWidth,
821
+ className="autocomplete__icon"
822
+ onClick={() => {
823
+ this.backButton();
798
824
  }}
799
- ref={this.dropdownRef}
800
825
  >
801
- <div className='autocomplete__header'>
802
- <div
803
- className="autocomplete__icon"
804
- onClick={() => {
805
- this.backButton();
806
- }}
807
- >
808
- <Icon name="search" className="search"></Icon>
809
- </div>
810
-
811
- <div className='autocomplete__filter'>
812
- <input
813
- className="autocomplete__input"
814
- type="text"
815
- placeholder={this.props.searchPlaceholder}
816
- ref={this.inputRef}
817
- value={this.state.searchFieldValue}
818
- onChange={(event) => {
819
- if (this.props.kind === 'synchronous') {
820
- this.setState({searchFieldValue: event.target.value});
821
- this.popperInstance?.update();
822
- } else if (this.props.kind === 'asynchronous') {
823
- if (this.ICancelFn) {
824
- this.ICancelFn();
825
- }
826
-
827
- this.setState({searchFieldValue: event.target.value, options: []});
828
- this.popperInstance?.update();
829
- this.debounceFn();
830
- } else {
831
- return;
832
- }
833
- }}
834
- data-test-id="filter-input"
835
- />
836
- </div>
826
+ <Icon name="search" className="search"></Icon>
827
+ </div>
828
+
829
+ <div className='autocomplete__filter'>
830
+ <input
831
+ className="autocomplete__input"
832
+ type="text"
833
+ placeholder={this.props.searchPlaceholder}
834
+ ref={this.inputRef}
835
+ value={this.state.searchFieldValue}
836
+ onChange={(event) => {
837
+ if (this.props.kind === 'synchronous') {
838
+ this.setState({searchFieldValue: event.target.value});
839
+ this.popperInstance?.update();
840
+ } else if (this.props.kind === 'asynchronous') {
841
+ if (this.ICancelFn) {
842
+ this.ICancelFn();
843
+ }
844
+
845
+ this.setState({searchFieldValue: event.target.value, options: []});
846
+ this.popperInstance?.update();
847
+ this.debounceFn();
848
+ } else {
849
+ return;
850
+ }
851
+ }}
852
+ data-test-id="filter-input"
853
+ />
854
+ </div>
855
+ </div>
856
+
857
+ {(this.state.activeTree.length > 0 && this.state.buttonValue != null)
858
+ && <div className='autocomplete__category-header'>
859
+ <div
860
+ className="autocomplete__icon"
861
+ onClick={() => {
862
+ this.backButton();
863
+ }}
864
+ >
865
+ <Icon name="arrow-left" className="arrow-left"></Icon>
837
866
  </div>
838
867
 
839
- {(this.state.activeTree.length > 0 && this.state.buttonValue != null)
840
- && <div className='autocomplete__category-header'>
841
- <div
842
- className="autocomplete__icon"
843
- onClick={() => {
844
- this.backButton();
845
- }}
846
- >
847
- <Icon name="arrow-left" className="arrow-left"></Icon>
848
- </div>
849
-
850
- <div className='autocomplete__filter'>
851
- <button className='autocomplete__category-title'>
852
- {this.props.optionTemplate
853
- ? this.props.optionTemplate(this.state.buttonValue.value)
854
- : this.props.getLabel(this.state.buttonValue.value)
855
- }
856
- </button>
868
+ <div className='autocomplete__filter'>
869
+ <button className='autocomplete__category-title'>
870
+ {this.props.optionTemplate
871
+ ? this.props.optionTemplate(this.state.buttonValue.value)
872
+ : this.props.getLabel(this.state.buttonValue.value)
873
+ }
874
+ </button>
857
875
 
858
- {this.props.selectBranchWithChildren
859
- && this.branchButton(this.state.buttonValue)
860
- }
861
- </div>
862
- </div>
863
- }
864
-
865
- {this.state.loading
866
- ? <ul className="suggestion-list--loader"><Loader overlay={true}></Loader></ul>
867
- : this.state.searchFieldValue === ''
868
- ? this.props.getOptions
869
- ? <ul
870
- className="suggestion-list suggestion-list--multi-select"
871
- ref={this.ref}
872
- data-test-id="options"
873
- >
874
- {this.state.options.map((option, i: React.Key | undefined) => {
875
- let selectedItem = this.state.value.some((obj) =>
876
- this.props.getId(obj) === this.props.getId(option.value),
877
- );
878
-
879
- return (
880
- <TreeSelectItem
881
- key={i}
882
- option={option}
883
- handleTree={this.handleTree}
884
- selectedItem={selectedItem}
885
- allowMultiple={this.props.allowMultiple}
886
- getBorderColor={this.props.getBorderColor}
887
- getBackgroundColor={this.props.getBackgroundColor}
888
- getId={this.props.getId}
889
- optionTemplate={this.props.optionTemplate}
890
- getLabel={this.props.getLabel}
891
- onKeyDown={() => this.setState({
892
- buttonTarget: [
893
- ...this.state.buttonTarget,
894
- this.props.getId(option.value),
895
- ],
896
- })}
897
- />
898
- );
899
- })}
900
- </ul>
901
- : null
902
- : <ul
903
- className="suggestion-list suggestion-list--multi-select"
904
- ref={this.ref}
905
- >
906
- {this.filteredItem(
907
- this.props.singleLevelSearch
908
- ? this.state.options
909
- : this.state.filterArr,
910
- )}
911
- </ul>
912
- }
876
+ {this.props.selectBranchWithChildren
877
+ && this.branchButton(this.state.buttonValue)
878
+ }
879
+ </div>
913
880
  </div>
914
- </div>,
915
- document.body,
916
- )}
881
+ }
882
+
883
+ {this.state.loading
884
+ ? <ul className="suggestion-list--loader"><Loader overlay={true}></Loader></ul>
885
+ : this.state.searchFieldValue === ''
886
+ ? this.props.getOptions
887
+ ? <ul
888
+ className="suggestion-list suggestion-list--multi-select"
889
+ ref={this.ref}
890
+ data-test-id="options"
891
+ >
892
+ {this.state.options.map((option, i: React.Key | undefined) => {
893
+ let selectedItem = this.state.value.some((obj) =>
894
+ this.props.getId(obj) === this.props.getId(option.value),
895
+ );
896
+
897
+ return (
898
+ <TreeSelectItem
899
+ key={i}
900
+ option={option}
901
+ handleTree={this.handleTree}
902
+ selectedItem={selectedItem}
903
+ allowMultiple={this.props.allowMultiple}
904
+ getBorderColor={this.props.getBorderColor}
905
+ getBackgroundColor={this.props.getBackgroundColor}
906
+ getId={this.props.getId}
907
+ optionTemplate={this.props.optionTemplate}
908
+ getLabel={this.props.getLabel}
909
+ onKeyDown={() => this.setState({
910
+ buttonTarget: [
911
+ ...this.state.buttonTarget,
912
+ this.props.getId(option.value),
913
+ ],
914
+ })}
915
+ />
916
+ );
917
+ })}
918
+ </ul>
919
+ : null
920
+ : <ul
921
+ className="suggestion-list suggestion-list--multi-select"
922
+ ref={this.ref}
923
+ >
924
+ {this.filteredItem(
925
+ this.props.singleLevelSearch
926
+ ? this.state.options
927
+ : this.state.filterArr,
928
+ )}
929
+ </ul>
930
+ }
931
+ </div>
932
+ </WithPortal>
917
933
  </InputWrapper>
918
934
  );
919
935
  }
@@ -0,0 +1,49 @@
1
+ import * as React from "react";
2
+ import {createPortal} from 'react-dom';
3
+
4
+ interface IProps {
5
+ active: boolean;
6
+ 'data-test-id'?: string;
7
+ }
8
+
9
+ export function findParent(
10
+ element: HTMLElement | null,
11
+ ) {
12
+ let dataTheme = element;
13
+
14
+ while (dataTheme != null && dataTheme?.getAttribute('data-theme') == null) {
15
+ dataTheme = dataTheme.parentElement ?? null;
16
+ }
17
+
18
+ return dataTheme;
19
+ }
20
+
21
+ export class WithPortal extends React.Component<IProps> {
22
+ private ref: React.RefObject<HTMLDivElement>;
23
+ private dataTheme: string | undefined;
24
+
25
+ constructor(props: IProps) {
26
+ super(props);
27
+
28
+ this.ref = React.createRef();
29
+ }
30
+
31
+ componentDidMount(): void {
32
+ this.dataTheme = findParent(this.ref.current)?.getAttribute('data-theme') ?? undefined;
33
+ }
34
+
35
+ render() {
36
+ return (
37
+ <div ref={this.ref}>
38
+ {this.props.active && (
39
+ createPortal(
40
+ <div data-theme={this.dataTheme} data-test-id={this.props['data-test-id']}>
41
+ {this.props.children}
42
+ </div>,
43
+ document.body,
44
+ )
45
+ )}
46
+ </div>
47
+ );
48
+ }
49
+ }
@@ -1,5 +1,6 @@
1
1
  import * as React from 'react';
2
2
  import {IPropsBase} from './interfaces';
3
+ // tslint:disable-next-line:max-line-length
3
4
 
4
5
  interface IPropsImageAvatar extends IPropsBase {
5
6
  imageUrl?: string | null; // defaults to a placeholder image
@@ -24,6 +25,7 @@ export class AvatarContentImage extends React.PureComponent<IPropsImageAvatar> {
24
25
  >
25
26
  <svg width="200" height="200" viewBox="0 0 200 200" fill="none" xmlns="http://www.w3.org/2000/svg">
26
27
  <circle cx="100" cy="100" r="100" fill="white" fillOpacity="0.01"/>
28
+ {/* tslint:disable-next-line:max-line-length */}
27
29
  <path fillRule="evenodd" clipRule="evenodd" d="M40 153V145.384C40 141.557 41.16 137.981 43.16 135C49.14 126.057 66.24 119.711 77.14 118C82.74 117.115 90.16 116.538 100 116.538C109.84 116.538 117.26 117.115 122.86 118C133.76 119.711 150.86 126.057 156.84 135C158.84 137.981 160 141.557 160 145.384V153C150 165 130 180 100 180C70 180 50 165 40 153ZM100 30C122.08 30 140 47.2307 140 68.4614C140 89.6922 122.08 106.923 100 106.923C77.92 106.923 60 89.6922 60 68.4614C60 47.2307 77.92 30 100 30Z" fill="var(--sd-colour-avatar-dummy)" fillOpacity="1"/>
28
30
  </svg>
29
31
  </span>);
@@ -46,7 +46,8 @@ export class Avatar extends React.PureComponent<IPropsAvatar> {
46
46
  customContent,
47
47
  } = this.props;
48
48
 
49
- const tooltipCombined = [displayName, this.props.tooltip].filter((str) => (str ?? '').trim().length > 0).join('\n');
49
+ const tooltipCombined = [displayName, this.props.tooltip]
50
+ .filter((str) => (str ?? '').trim().length > 0).join('\n');
50
51
 
51
52
  return (
52
53
  <AvatarWrapper