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.
- package/app/styles/components/_list-item.scss +22 -11
- package/app-typescript/components/Autocomplete.tsx +9 -3
- package/app-typescript/components/Badge.tsx +16 -2
- package/app-typescript/components/Dropdown.tsx +3 -1
- package/app-typescript/components/DropdownFirst.tsx +14 -2
- package/app-typescript/components/DurationInput.tsx +19 -4
- package/app-typescript/components/EmptyState.tsx +11 -2
- package/app-typescript/components/Layouts/Panel.tsx +12 -1
- package/app-typescript/components/Lists/ContentList.tsx +5 -1
- package/app-typescript/components/Modal.tsx +10 -1
- package/app-typescript/components/Navigation/BottomNav.tsx +9 -2
- package/app-typescript/components/Navigation/QuickNavBar.tsx +10 -2
- package/app-typescript/components/Navigation/SideBarMenu.tsx +9 -4
- package/app-typescript/components/SidebarMenu.tsx +8 -1
- package/app-typescript/components/TabList.tsx +5 -1
- package/app-typescript/components/TagInput.tsx +4 -1
- package/app-typescript/components/ThemeSelector.tsx +13 -2
- package/app-typescript/components/TreeMenu.tsx +127 -122
- package/app-typescript/components/TreeSelect/TreeSelect.tsx +157 -141
- package/app-typescript/components/WithPortal.tsx +49 -0
- package/app-typescript/components/avatar/avatar-image.tsx +2 -0
- package/app-typescript/components/avatar/avatar.tsx +2 -1
- package/dist/examples.bundle.js +1446 -1318
- package/dist/playgrounds/planning.html +121 -43
- package/dist/playgrounds/react-playgrounds/CoreLayout.tsx +398 -385
- package/dist/playgrounds/react-playgrounds/EditorTest.tsx +359 -365
- package/dist/playgrounds/react-playgrounds/FirstPlayground.tsx +33 -33
- package/dist/playgrounds/react-playgrounds/Multiedit.tsx +227 -231
- package/dist/playgrounds/react-playgrounds/PageLayoutTest.tsx +41 -38
- package/dist/playgrounds/react-playgrounds/PersonalProfile.tsx +76 -96
- package/dist/playgrounds/react-playgrounds/RundownEditor.tsx +73 -101
- package/dist/playgrounds/react-playgrounds/Rundowns.tsx +788 -729
- package/dist/playgrounds/react-playgrounds/SamsPlayground.tsx +35 -26
- package/dist/playgrounds/react-playgrounds/TestGround.tsx +99 -128
- package/dist/playgrounds/react-playgrounds/UiPlayground.tsx +40 -25
- package/dist/playgrounds/react-playgrounds/components/GraphicButton.tsx +6 -5
- package/dist/playgrounds/react-playgrounds/components/Layout.tsx +0 -2
- package/dist/playgrounds/react-playgrounds/components/SearchBar.tsx +16 -9
- package/dist/playgrounds/react-playgrounds/tsconfig.json +4 -0
- package/dist/superdesk-ui.bundle.css +24 -14
- package/dist/superdesk-ui.bundle.js +830 -727
- package/dist/vendor.bundle.js +14 -14
- package/examples/pages/playgrounds/planning.html +121 -43
- package/examples/pages/playgrounds/react-playgrounds/CoreLayout.tsx +398 -385
- package/examples/pages/playgrounds/react-playgrounds/EditorTest.tsx +359 -365
- package/examples/pages/playgrounds/react-playgrounds/FirstPlayground.tsx +33 -33
- package/examples/pages/playgrounds/react-playgrounds/Multiedit.tsx +227 -231
- package/examples/pages/playgrounds/react-playgrounds/PageLayoutTest.tsx +41 -38
- package/examples/pages/playgrounds/react-playgrounds/PersonalProfile.tsx +76 -96
- package/examples/pages/playgrounds/react-playgrounds/RundownEditor.tsx +73 -101
- package/examples/pages/playgrounds/react-playgrounds/Rundowns.tsx +788 -729
- package/examples/pages/playgrounds/react-playgrounds/SamsPlayground.tsx +35 -26
- package/examples/pages/playgrounds/react-playgrounds/TestGround.tsx +99 -128
- package/examples/pages/playgrounds/react-playgrounds/UiPlayground.tsx +40 -25
- package/examples/pages/playgrounds/react-playgrounds/components/GraphicButton.tsx +6 -5
- package/examples/pages/playgrounds/react-playgrounds/components/Layout.tsx +0 -2
- package/examples/pages/playgrounds/react-playgrounds/components/SearchBar.tsx +16 -9
- package/examples/pages/playgrounds/react-playgrounds/tsconfig.json +4 -0
- package/package.json +3 -2
- package/react/components/Autocomplete.js +2 -2
- package/react/components/Badge.js +1 -1
- package/react/components/Dropdown.js +3 -1
- package/react/components/DropdownFirst.js +6 -2
- package/react/components/DurationInput.js +5 -1
- package/react/components/EmptyState.js +2 -1
- package/react/components/Lists/ContentList.js +1 -1
- package/react/components/Navigation/BottomNav.js +4 -1
- package/react/components/Navigation/QuickNavBar.js +2 -1
- package/react/components/Navigation/SideBarMenu.js +3 -1
- package/react/components/TabList.js +2 -1
- package/react/components/TagInput.js +1 -1
- package/react/components/TreeSelect/TreeSelect.d.ts +3 -2
- package/react/components/TreeSelect/TreeSelect.js +81 -73
- package/react/components/WithPortal.d.ts +14 -0
- package/react/components/WithPortal.js +69 -0
- package/react/components/avatar/avatar.js +2 -1
- /package/dist/playgrounds/dummy-data/{items.js → items.ts} +0 -0
- /package/examples/pages/playgrounds/dummy-data/{items.js → items.ts} +0 -0
@@ -4,6 +4,7 @@ import { createPopper, Instance } from '@popperjs/core';
|
|
4
4
|
import {getPrefixedItemId, TreeSelectItem} from './TreeSelect/TreeSelectItem';
|
5
5
|
import {keyboardNavigation} from './TreeSelect/KeyboardNavigation';
|
6
6
|
import {createPortal} from 'react-dom';
|
7
|
+
import {WithPortal} from './WithPortal';
|
7
8
|
|
8
9
|
interface IState<T> {
|
9
10
|
options: Array<ITreeMenuNode<T>>;
|
@@ -23,6 +24,7 @@ interface IProps<T> {
|
|
23
24
|
zIndex?: number;
|
24
25
|
searchPlaceholder?: string;
|
25
26
|
singleLevelSearch?: boolean;
|
27
|
+
'data-test-id'?: string;
|
26
28
|
getOptions?(): Array<ITreeMenuNode<T>>;
|
27
29
|
getLabel(item: T): string;
|
28
30
|
getId(item: T): string;
|
@@ -57,7 +59,7 @@ export class TreeMenu<T> extends React.Component<IProps<T>, IState<T>> {
|
|
57
59
|
private dropdownRef: React.RefObject<HTMLInputElement>;
|
58
60
|
private ref: React.RefObject<HTMLUListElement>;
|
59
61
|
private openDropdownRef: React.RefObject<HTMLDivElement>;
|
60
|
-
private
|
62
|
+
private treeMenuRef: React.RefObject<HTMLDivElement>;
|
61
63
|
private inputRef: React.RefObject<HTMLInputElement>;
|
62
64
|
private popperInstance: Instance | null;
|
63
65
|
|
@@ -80,14 +82,15 @@ export class TreeMenu<T> extends React.Component<IProps<T>, IState<T>> {
|
|
80
82
|
this.handleButton = this.handleButton.bind(this);
|
81
83
|
this.handleTree = this.handleTree.bind(this);
|
82
84
|
this.toggleMenu = this.toggleMenu.bind(this);
|
85
|
+
this.toggle = this.toggle.bind(this);
|
83
86
|
this.onMouseDown = this.onMouseDown.bind(this);
|
84
87
|
this.onKeyDown = this.onKeyDown.bind(this);
|
85
|
-
this.
|
88
|
+
this.onPressEsc = this.onPressEsc.bind(this);
|
86
89
|
|
87
90
|
this.dropdownRef = React.createRef();
|
88
91
|
this.ref = React.createRef();
|
89
92
|
this.openDropdownRef = React.createRef();
|
90
|
-
this.
|
93
|
+
this.treeMenuRef = React.createRef();
|
91
94
|
this.inputRef = React.createRef();
|
92
95
|
|
93
96
|
this.popperInstance = null;
|
@@ -105,10 +108,13 @@ export class TreeMenu<T> extends React.Component<IProps<T>, IState<T>> {
|
|
105
108
|
onMouseDown = (event: MouseEvent) => {
|
106
109
|
if (
|
107
110
|
(this.dropdownRef.current?.contains(event.target as HTMLElement) !== true)
|
108
|
-
&& (this.
|
111
|
+
&& (this.treeMenuRef.current?.contains(event.target as HTMLElement) !== true)
|
109
112
|
&& this.state.openDropdown
|
110
113
|
) {
|
111
|
-
this.setState({
|
114
|
+
this.setState({
|
115
|
+
openDropdown: false,
|
116
|
+
searchFieldValue: '',
|
117
|
+
});
|
112
118
|
}
|
113
119
|
}
|
114
120
|
|
@@ -134,16 +140,27 @@ export class TreeMenu<T> extends React.Component<IProps<T>, IState<T>> {
|
|
134
140
|
}
|
135
141
|
}
|
136
142
|
|
143
|
+
onPressEsc = (event: KeyboardEvent) => {
|
144
|
+
if (event.key === 'Escape' && this.state.openDropdown) {
|
145
|
+
this.setState({
|
146
|
+
openDropdown: false,
|
147
|
+
searchFieldValue: '',
|
148
|
+
});
|
149
|
+
}
|
150
|
+
}
|
151
|
+
|
137
152
|
componentDidMount = () => {
|
138
153
|
this.recursion(this.state.options);
|
139
154
|
|
140
155
|
document.addEventListener("mousedown", this.onMouseDown);
|
141
156
|
document.addEventListener("keydown", this.onKeyDown);
|
157
|
+
document.addEventListener("keydown", this.onPressEsc);
|
142
158
|
}
|
143
159
|
|
144
160
|
componentWillUnmount(): void {
|
145
161
|
document.removeEventListener("mousedown", this.onMouseDown);
|
146
162
|
document.removeEventListener("keydown", this.onKeyDown);
|
163
|
+
document.addEventListener("keydown", this.onPressEsc);
|
147
164
|
}
|
148
165
|
|
149
166
|
componentDidUpdate(prevProps: Readonly<IProps<T>>, prevState: Readonly<IState<T>>): void {
|
@@ -165,14 +182,6 @@ export class TreeMenu<T> extends React.Component<IProps<T>, IState<T>> {
|
|
165
182
|
if (this.openDropdownRef.current && this.dropdownRef.current) {
|
166
183
|
this.popperInstance = createPopper(this.openDropdownRef.current, this.dropdownRef.current, {
|
167
184
|
placement: 'bottom-start',
|
168
|
-
modifiers: [
|
169
|
-
{
|
170
|
-
name: 'offset',
|
171
|
-
options: {
|
172
|
-
offset: [-4, 4],
|
173
|
-
},
|
174
|
-
},
|
175
|
-
],
|
176
185
|
});
|
177
186
|
}
|
178
187
|
|
@@ -335,125 +344,121 @@ export class TreeMenu<T> extends React.Component<IProps<T>, IState<T>> {
|
|
335
344
|
|
336
345
|
render() {
|
337
346
|
return (
|
338
|
-
<div ref={this.
|
347
|
+
<div ref={this.treeMenuRef}>
|
339
348
|
<div ref={this.openDropdownRef}>
|
340
349
|
{this.props.children(this.toggle)}
|
341
350
|
</div>
|
342
351
|
|
343
|
-
{
|
344
|
-
|
345
|
-
|
352
|
+
<WithPortal active={this.state.openDropdown} data-test-id="tree-menu-popover">
|
353
|
+
<div
|
354
|
+
ref={this.dropdownRef}
|
355
|
+
className="autocomplete autocomplete--multi-select autocomplete--fixed-width"
|
356
|
+
style={{
|
357
|
+
zIndex: this.props.zIndex,
|
358
|
+
}}
|
359
|
+
>
|
360
|
+
<div className='autocomplete__header'>
|
346
361
|
<div
|
347
|
-
|
348
|
-
|
349
|
-
|
350
|
-
zIndex: this.props.zIndex,
|
362
|
+
className="autocomplete__icon"
|
363
|
+
onClick={() => {
|
364
|
+
this.backButton();
|
351
365
|
}}
|
352
366
|
>
|
353
|
-
<
|
354
|
-
|
355
|
-
|
356
|
-
|
357
|
-
|
358
|
-
|
359
|
-
|
360
|
-
|
361
|
-
|
362
|
-
|
363
|
-
|
364
|
-
|
365
|
-
|
366
|
-
|
367
|
-
|
368
|
-
|
369
|
-
|
370
|
-
|
371
|
-
|
372
|
-
|
373
|
-
|
374
|
-
|
375
|
-
|
367
|
+
<Icon name="search" className="search"></Icon>
|
368
|
+
</div>
|
369
|
+
|
370
|
+
<div className='autocomplete__filter'>
|
371
|
+
<input
|
372
|
+
className="autocomplete__input"
|
373
|
+
type="text"
|
374
|
+
placeholder={this.props.searchPlaceholder}
|
375
|
+
ref={this.inputRef}
|
376
|
+
value={this.state.searchFieldValue}
|
377
|
+
onChange={(event) => {
|
378
|
+
this.setState({searchFieldValue: event.target.value});
|
379
|
+
this.popperInstance?.update();
|
380
|
+
}}
|
381
|
+
/>
|
382
|
+
</div>
|
383
|
+
</div>
|
384
|
+
|
385
|
+
{(this.state.activeTree.length > 0 && this.state.buttonValue != null)
|
386
|
+
&& <div className='autocomplete__category-header'>
|
387
|
+
<div
|
388
|
+
className="autocomplete__icon"
|
389
|
+
onClick={() => {
|
390
|
+
this.backButton();
|
391
|
+
}}
|
392
|
+
>
|
393
|
+
<Icon name="arrow-left" className="arrow-left"></Icon>
|
376
394
|
</div>
|
377
395
|
|
378
|
-
|
379
|
-
|
380
|
-
|
381
|
-
|
382
|
-
|
383
|
-
|
384
|
-
|
385
|
-
|
386
|
-
<Icon name="arrow-left" className="arrow-left"></Icon>
|
387
|
-
</div>
|
388
|
-
|
389
|
-
<div className='autocomplete__filter'>
|
390
|
-
<button className='autocomplete__category-title'>
|
391
|
-
{this.props.optionTemplate
|
392
|
-
? this.props.optionTemplate(this.state.buttonValue.value)
|
393
|
-
: this.props.getLabel(this.state.buttonValue.value)
|
394
|
-
}
|
395
|
-
</button>
|
396
|
-
</div>
|
397
|
-
</div>
|
398
|
-
}
|
399
|
-
|
400
|
-
{this.state.searchFieldValue === '' ?
|
401
|
-
this.props.getOptions ?
|
402
|
-
<ul
|
403
|
-
ref={this.ref}
|
404
|
-
className="suggestion-list suggestion-list--multi-select"
|
405
|
-
>
|
406
|
-
{this.state.options.map((option, i: React.Key | undefined) => {
|
407
|
-
const onSelect = (item) => {
|
408
|
-
if (nodeCanBeSelected(item)) {
|
409
|
-
return item.onSelect;
|
410
|
-
}
|
411
|
-
};
|
412
|
-
|
413
|
-
const disabledItem = (item) => {
|
414
|
-
if (nodeCanBeSelected(item)) {
|
415
|
-
return item.disabled;
|
416
|
-
}
|
417
|
-
};
|
418
|
-
|
419
|
-
return (
|
420
|
-
<TreeSelectItem
|
421
|
-
key={i}
|
422
|
-
option={option}
|
423
|
-
handleTree={this.handleTree}
|
424
|
-
onClick={onSelect(option)}
|
425
|
-
disabledItem={disabledItem(option)}
|
426
|
-
getBorderColor={this.props.getBorderColor}
|
427
|
-
getBackgroundColor={this.props.getBackgroundColor}
|
428
|
-
getId={this.props.getId}
|
429
|
-
optionTemplate={this.props.optionTemplate}
|
430
|
-
getLabel={this.props.getLabel}
|
431
|
-
onKeyDown={() => this.setState({
|
432
|
-
buttonTarget: [
|
433
|
-
...this.state.buttonTarget,
|
434
|
-
this.props.getId(option.value),
|
435
|
-
],
|
436
|
-
})}
|
437
|
-
/>
|
438
|
-
);
|
439
|
-
})}
|
440
|
-
</ul>
|
441
|
-
: null
|
442
|
-
: <ul
|
443
|
-
className="suggestion-list suggestion-list--multi-select"
|
444
|
-
ref={this.ref}
|
445
|
-
>
|
446
|
-
{this.filteredItem(
|
447
|
-
this.props.singleLevelSearch
|
448
|
-
? this.state.options
|
449
|
-
: this.state.filterArr,
|
450
|
-
)}
|
451
|
-
</ul>
|
452
|
-
}
|
396
|
+
<div className='autocomplete__filter'>
|
397
|
+
<button className='autocomplete__category-title'>
|
398
|
+
{this.props.optionTemplate
|
399
|
+
? this.props.optionTemplate(this.state.buttonValue.value)
|
400
|
+
: this.props.getLabel(this.state.buttonValue.value)
|
401
|
+
}
|
402
|
+
</button>
|
403
|
+
</div>
|
453
404
|
</div>
|
454
|
-
|
455
|
-
|
456
|
-
|
405
|
+
}
|
406
|
+
|
407
|
+
{this.state.searchFieldValue === '' ?
|
408
|
+
this.props.getOptions ?
|
409
|
+
<ul
|
410
|
+
ref={this.ref}
|
411
|
+
className="suggestion-list suggestion-list--multi-select"
|
412
|
+
>
|
413
|
+
{this.state.options.map((option, i: React.Key | undefined) => {
|
414
|
+
const onSelect = (item) => {
|
415
|
+
if (nodeCanBeSelected(item)) {
|
416
|
+
return item.onSelect;
|
417
|
+
}
|
418
|
+
};
|
419
|
+
|
420
|
+
const disabledItem = (item) => {
|
421
|
+
if (nodeCanBeSelected(item)) {
|
422
|
+
return item.disabled;
|
423
|
+
}
|
424
|
+
};
|
425
|
+
|
426
|
+
return (
|
427
|
+
<TreeSelectItem
|
428
|
+
key={i}
|
429
|
+
option={option}
|
430
|
+
handleTree={this.handleTree}
|
431
|
+
onClick={onSelect(option)}
|
432
|
+
disabledItem={disabledItem(option)}
|
433
|
+
getBorderColor={this.props.getBorderColor}
|
434
|
+
getBackgroundColor={this.props.getBackgroundColor}
|
435
|
+
getId={this.props.getId}
|
436
|
+
optionTemplate={this.props.optionTemplate}
|
437
|
+
getLabel={this.props.getLabel}
|
438
|
+
onKeyDown={() => this.setState({
|
439
|
+
buttonTarget: [
|
440
|
+
...this.state.buttonTarget,
|
441
|
+
this.props.getId(option.value),
|
442
|
+
],
|
443
|
+
})}
|
444
|
+
/>
|
445
|
+
);
|
446
|
+
})}
|
447
|
+
</ul>
|
448
|
+
: null
|
449
|
+
: <ul
|
450
|
+
className="suggestion-list suggestion-list--multi-select"
|
451
|
+
ref={this.ref}
|
452
|
+
>
|
453
|
+
{this.filteredItem(
|
454
|
+
this.props.singleLevelSearch
|
455
|
+
? this.state.options
|
456
|
+
: this.state.filterArr,
|
457
|
+
)}
|
458
|
+
</ul>
|
459
|
+
}
|
460
|
+
</div>
|
461
|
+
</WithPortal>
|
457
462
|
</div>
|
458
463
|
);
|
459
464
|
}
|