superdesk-ui-framework 3.0.1-beta.11 → 3.0.1-beta.13
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/_modals.scss +3 -3
- package/app/styles/_table-list.scss +100 -11
- package/app/styles/grids/_grid-layout.scss +3 -0
- package/app-typescript/components/Dropdown.tsx +78 -37
- package/app-typescript/components/DurationInput.tsx +7 -1
- package/app-typescript/components/Layouts/CoreLayout.tsx +2 -1
- package/app-typescript/components/Layouts/CoreLayoutMain.tsx +7 -1
- package/app-typescript/components/Lists/TableList.tsx +138 -25
- package/app-typescript/components/SearchBar.tsx +11 -3
- package/app-typescript/components/TimePicker.tsx +2 -13
- package/dist/examples.bundle.js +361 -123
- package/dist/playgrounds/react-playgrounds/CoreLayout.tsx +1 -0
- package/dist/react/Dropdowns.tsx +227 -47
- package/dist/react/TableList.tsx +15 -119
- package/dist/superdesk-ui.bundle.css +84 -16
- package/dist/superdesk-ui.bundle.js +153 -56
- package/examples/pages/playgrounds/react-playgrounds/CoreLayout.tsx +1 -0
- package/examples/pages/react/Dropdowns.tsx +227 -47
- package/examples/pages/react/TableList.tsx +15 -119
- package/package.json +1 -1
- package/react/components/Dropdown.d.ts +2 -1
- package/react/components/Dropdown.js +39 -20
- package/react/components/DurationInput.js +9 -1
- package/react/components/Layouts/CoreLayout.d.ts +1 -0
- package/react/components/Layouts/CoreLayout.js +1 -1
- package/react/components/Layouts/CoreLayoutMain.d.ts +1 -0
- package/react/components/Layouts/CoreLayoutMain.js +8 -1
- package/react/components/Lists/TableList.d.ts +22 -6
- package/react/components/Lists/TableList.js +78 -19
- package/react/components/SearchBar.d.ts +1 -1
- package/react/components/SearchBar.js +15 -7
- package/react/components/TimePicker.d.ts +1 -5
- package/react/components/TimePicker.js +3 -7
- package/.vscode/settings.json +0 -5
- package/app-typescript/dist/components/Alert.d.ts +0 -16
- package/app-typescript/dist/components/Autocomplete.d.ts +0 -48
- package/app-typescript/dist/components/Avatar.d.ts +0 -33
- package/app-typescript/dist/components/Badge.d.ts +0 -13
- package/app-typescript/dist/components/Button.d.ts +0 -23
- package/app-typescript/dist/components/ButtonGroup.d.ts +0 -12
- package/app-typescript/dist/components/CheckButtonGroup.d.ts +0 -11
- package/app-typescript/dist/components/CheckGroup.d.ts +0 -9
- package/app-typescript/dist/components/Checkbox.d.ts +0 -19
- package/app-typescript/dist/components/CheckboxButton.d.ts +0 -19
- package/app-typescript/dist/components/DatePicker.d.ts +0 -37
- package/app-typescript/dist/components/Divider.d.ts +0 -9
- package/app-typescript/dist/components/DonutChart.d.ts +0 -12
- package/app-typescript/dist/components/Dropdown.d.ts +0 -28
- package/app-typescript/dist/components/DropdownFirst.d.ts +0 -42
- package/app-typescript/dist/components/EmptyState.d.ts +0 -11
- package/app-typescript/dist/components/FormLabel.d.ts +0 -9
- package/app-typescript/dist/components/Genie.d.ts +0 -13
- package/app-typescript/dist/components/GridItem.d.ts +0 -69
- package/app-typescript/dist/components/GridList.d.ts +0 -14
- package/app-typescript/dist/components/HeadingText.d.ts +0 -10
- package/app-typescript/dist/components/HelloWorld.d.ts +0 -8
- package/app-typescript/dist/components/Icon.d.ts +0 -12
- package/app-typescript/dist/components/IconButton.d.ts +0 -12
- package/app-typescript/dist/components/IconLabel.d.ts +0 -11
- package/app-typescript/dist/components/Input.d.ts +0 -24
- package/app-typescript/dist/components/Label.d.ts +0 -15
- package/app-typescript/dist/components/LeftMenu.d.ts +0 -26
- package/app-typescript/dist/components/Loader.d.ts +0 -8
- package/app-typescript/dist/components/NavButton.d.ts +0 -15
- package/app-typescript/dist/components/Popover.d.ts +0 -13
- package/app-typescript/dist/components/PropsList.d.ts +0 -15
- package/app-typescript/dist/components/Radio.d.ts +0 -19
- package/app-typescript/dist/components/RadioButton.d.ts +0 -20
- package/app-typescript/dist/components/Select.d.ts +0 -29
- package/app-typescript/dist/components/SelectWithTemplate.d.ts +0 -32
- package/app-typescript/dist/components/SlidingToolbar.d.ts +0 -8
- package/app-typescript/dist/components/StrechBar.d.ts +0 -4
- package/app-typescript/dist/components/SubNav.d.ts +0 -10
- package/app-typescript/dist/components/Switch.d.ts +0 -12
- package/app-typescript/dist/components/TabCustom.d.ts +0 -25
- package/app-typescript/dist/components/TabList.d.ts +0 -22
- package/app-typescript/dist/components/Tag.d.ts +0 -9
- package/app-typescript/dist/components/TagInput.d.ts +0 -7
- package/app-typescript/dist/components/TagInputTest.d.ts +0 -18
- package/app-typescript/dist/components/TimePicker.d.ts +0 -11
- package/app-typescript/dist/components/Tooltip.d.ts +0 -11
- package/app-typescript/dist/components/_Positioner.d.ts +0 -27
- package/app-typescript/dist/index.d.ts +0 -56
- package/yarn-error.log +0 -111
package/app/styles/_modals.scss
CHANGED
@@ -2,9 +2,9 @@
|
|
2
2
|
// ------
|
3
3
|
|
4
4
|
// Recalculate z-index where appropriate
|
5
|
-
$zindexDropdown:
|
6
|
-
$zindexPopover:
|
7
|
-
$zindexTooltip:
|
5
|
+
$zindexDropdown: 2000;
|
6
|
+
$zindexPopover: 2010;
|
7
|
+
$zindexTooltip: 2040;
|
8
8
|
$zindexModalBackdrop: 1045;
|
9
9
|
$zindexModal: 1050;
|
10
10
|
$nav-height: 48px;
|
@@ -14,11 +14,15 @@
|
|
14
14
|
}
|
15
15
|
}
|
16
16
|
|
17
|
+
.table-list--read-only {
|
18
|
+
pointer-events: none;
|
19
|
+
cursor: default;
|
20
|
+
}
|
21
|
+
|
17
22
|
$table-list-palette: $sd-basic-palette;
|
18
23
|
|
19
24
|
.table-list__item {
|
20
25
|
display: grid;
|
21
|
-
z-index: 1;
|
22
26
|
align-items: center;
|
23
27
|
grid-template-columns: [contentCol] 1fr [actionsVisible] auto [actionsHidden] auto;
|
24
28
|
position: relative;
|
@@ -30,16 +34,6 @@ $table-list-palette: $sd-basic-palette;
|
|
30
34
|
border: 1px solid var(--sd-colour-line--light);
|
31
35
|
transition: all 0.2s ease-in-out;
|
32
36
|
inset-inline-start: 0;
|
33
|
-
&::before {
|
34
|
-
content: "";
|
35
|
-
width: 6px;
|
36
|
-
position: absolute;
|
37
|
-
inset-block: 3px;
|
38
|
-
inset-inline-start: 3px;
|
39
|
-
background-color: var(--sd-colour-panel-bg--100);
|
40
|
-
z-index: 1;
|
41
|
-
border-radius: 2px;
|
42
|
-
}
|
43
37
|
|
44
38
|
&--margin {
|
45
39
|
margin-bottom: $sd-base-increment;
|
@@ -117,6 +111,39 @@ $table-list-palette: $sd-basic-palette;
|
|
117
111
|
}
|
118
112
|
}
|
119
113
|
|
114
|
+
.table-list__add-item {
|
115
|
+
display: grid;
|
116
|
+
align-items: center;
|
117
|
+
//grid-template-columns: [contentCol] 1fr [actionsVisible] auto [actionsHidden] auto;
|
118
|
+
position: relative;
|
119
|
+
flex-direction: row;
|
120
|
+
padding: 8px;
|
121
|
+
min-height: 4.2rem;
|
122
|
+
border-radius: var(--b-radius--medium);
|
123
|
+
background-color: transparent;
|
124
|
+
border: 1px dashed var(--sd-colour-line--medium);
|
125
|
+
transition: all 0.2s ease-in-out;
|
126
|
+
inset-inline-start: 0;
|
127
|
+
|
128
|
+
&--container {
|
129
|
+
display: flex;
|
130
|
+
justify-content: center;
|
131
|
+
align-items: center;
|
132
|
+
}
|
133
|
+
}
|
134
|
+
|
135
|
+
.table-list__item-border {
|
136
|
+
width: 6px;
|
137
|
+
background-color: var(--sd-colour-panel-bg--100);
|
138
|
+
z-index: 2;
|
139
|
+
position: absolute;
|
140
|
+
inset-block: 3px;
|
141
|
+
inset-inline-start: 3px;
|
142
|
+
border-radius: 2px;
|
143
|
+
}
|
144
|
+
|
145
|
+
|
146
|
+
|
120
147
|
.table-list__item-content {
|
121
148
|
grid-column: contentCol;
|
122
149
|
grid-row: mainRow;
|
@@ -224,6 +251,7 @@ $table-list-palette: $sd-basic-palette;
|
|
224
251
|
transition: all ease 0.3s;
|
225
252
|
}
|
226
253
|
}
|
254
|
+
|
227
255
|
.table-list__add-bar {
|
228
256
|
height: 12px;
|
229
257
|
display: flex;
|
@@ -237,8 +265,69 @@ $table-list-palette: $sd-basic-palette;
|
|
237
265
|
background-color: var(--sd-colour-panel-bg--000);
|
238
266
|
transform: scale(0.5);
|
239
267
|
}
|
268
|
+
|
240
269
|
.side-panel__content-block {
|
241
270
|
.table-list__item-content {
|
242
271
|
grid-template-columns: [columnLeft] 140px [columncenter] 1fr [columnRight] auto;
|
243
272
|
}
|
244
273
|
}
|
274
|
+
|
275
|
+
.table-list--gap-s {
|
276
|
+
gap: $sd-base-increment;
|
277
|
+
}
|
278
|
+
|
279
|
+
.table-list__item--draggable {
|
280
|
+
&.table-list__item--drag-handles-always {
|
281
|
+
border-left-width: 16px;
|
282
|
+
border-left-color: var(--sd-colour-line--medium);
|
283
|
+
&::after {
|
284
|
+
content: "";
|
285
|
+
width: 20px;
|
286
|
+
position: absolute;
|
287
|
+
inset-block: -1px;
|
288
|
+
inset-inline-start: -18px;
|
289
|
+
background-image: url(../img/dots.svg);
|
290
|
+
background-repeat: no-repeat;
|
291
|
+
background-position: center center;
|
292
|
+
z-index: 2;
|
293
|
+
border-radius: var(--b-radius--small);
|
294
|
+
opacity: 0.85;
|
295
|
+
}
|
296
|
+
&:hover {
|
297
|
+
border-left-color: var(--sd-colour-line--strong);
|
298
|
+
&::after {
|
299
|
+
cursor: grab;
|
300
|
+
}
|
301
|
+
}
|
302
|
+
&:active {
|
303
|
+
border-color: var(--sd-colour-interactive);
|
304
|
+
cursor: grabbing;
|
305
|
+
&::after {
|
306
|
+
opacity: 1 !important;
|
307
|
+
cursor: grabbing;
|
308
|
+
}
|
309
|
+
}
|
310
|
+
}
|
311
|
+
&.table-list__item--drag-handles-none {
|
312
|
+
border-left-width: 1px;
|
313
|
+
&::after {
|
314
|
+
content: "";
|
315
|
+
width: 0;
|
316
|
+
opacity: 0;
|
317
|
+
}
|
318
|
+
&:hover {
|
319
|
+
border-left-color: var(--sd-colour-line--strong);
|
320
|
+
&::after {
|
321
|
+
cursor: grab;
|
322
|
+
}
|
323
|
+
}
|
324
|
+
&:active {
|
325
|
+
border-color: var(--sd-colour-interactive);
|
326
|
+
cursor: grabbing;
|
327
|
+
&::after {
|
328
|
+
opacity: 1 !important;
|
329
|
+
cursor: grabbing;
|
330
|
+
}
|
331
|
+
}
|
332
|
+
}
|
333
|
+
}
|
@@ -741,6 +741,9 @@ $planningEditor-width: 53rem;
|
|
741
741
|
.sd-main-content-grid {
|
742
742
|
grid-column: contentArea;
|
743
743
|
}
|
744
|
+
&--editor-full {
|
745
|
+
grid-template-columns: [sideTabsLeft] auto [contentArea] auto [contentSplitter] auto [authoringArea] 1fr;
|
746
|
+
}
|
744
747
|
}
|
745
748
|
.sd-content-wrapper__left-tabs {
|
746
749
|
grid-column: sideTabsLeft;
|
@@ -10,6 +10,10 @@ export interface IMenuItem {
|
|
10
10
|
onSelect(): void;
|
11
11
|
}
|
12
12
|
|
13
|
+
interface IMenuItemRes extends IMenuItem {
|
14
|
+
onChange?(event?: any): void;
|
15
|
+
}
|
16
|
+
|
13
17
|
export interface ISubmenu {
|
14
18
|
type: 'submenu';
|
15
19
|
label: string;
|
@@ -31,6 +35,7 @@ interface IMenu {
|
|
31
35
|
footer?: Array<IMenuItem | ISubmenu | IMenuGroup | 'divider'>;
|
32
36
|
append?: boolean;
|
33
37
|
children: React.ReactNode;
|
38
|
+
onChange?(event?: any): void;
|
34
39
|
}
|
35
40
|
|
36
41
|
export const Dropdown = ({
|
@@ -40,15 +45,14 @@ export const Dropdown = ({
|
|
40
45
|
children,
|
41
46
|
append,
|
42
47
|
align,
|
48
|
+
onChange,
|
43
49
|
}: IMenu) => {
|
44
50
|
const [open, setOpen] = React.useState(false);
|
45
51
|
const [change, setChange] = React.useState(false);
|
46
52
|
const [menuID] = useId();
|
47
53
|
const DROPDOWN_ID = "react-placeholder";
|
48
54
|
const ref = React.useRef(null);
|
49
|
-
const refSubMenu = React.useRef(null);
|
50
55
|
const buttonRef = React.useRef(null);
|
51
|
-
const refButtonSubMenu = React.useRef(null);
|
52
56
|
const headerElements = header?.map((el, index) => {
|
53
57
|
return each(el, index);
|
54
58
|
});
|
@@ -60,6 +64,7 @@ export const Dropdown = ({
|
|
60
64
|
const footerElements = footer?.map((el, index) => {
|
61
65
|
return each(el, index);
|
62
66
|
});
|
67
|
+
|
63
68
|
React.useEffect(() => {
|
64
69
|
const existingElement = document.getElementById(DROPDOWN_ID);
|
65
70
|
if (!existingElement) {
|
@@ -82,7 +87,6 @@ export const Dropdown = ({
|
|
82
87
|
addInPlaceholder();
|
83
88
|
}
|
84
89
|
setChange(true);
|
85
|
-
|
86
90
|
}, [open]);
|
87
91
|
|
88
92
|
// structure for append menu
|
@@ -212,33 +216,11 @@ export const Dropdown = ({
|
|
212
216
|
submenuItems.push(each(el, key));
|
213
217
|
});
|
214
218
|
return (
|
215
|
-
<
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
aria-haspopup="menu"
|
221
|
-
tabIndex={0}
|
222
|
-
onMouseOver={() => {
|
223
|
-
let subMenuRef = refSubMenu.current;
|
224
|
-
let subToggleRef = refButtonSubMenu.current;
|
225
|
-
if (subMenuRef && subToggleRef) {
|
226
|
-
createPopper(subToggleRef, subMenuRef, {
|
227
|
-
placement: 'right-start',
|
228
|
-
});
|
229
|
-
}
|
230
|
-
}}
|
231
|
-
onClick={item['onSelect']}>
|
232
|
-
{item['icon'] ? <i className={'icon-' + item['icon']}></i> : null}
|
233
|
-
{item['label']}
|
234
|
-
</button>
|
235
|
-
<ul ref={refSubMenu}
|
236
|
-
role='menu'
|
237
|
-
className='dropdown__menu'>
|
238
|
-
{submenuItems}
|
239
|
-
</ul>
|
240
|
-
</div>
|
241
|
-
</li>
|
219
|
+
<DropdownItemWithSubmenu
|
220
|
+
key={index}
|
221
|
+
item={item}
|
222
|
+
subMenuItems={submenuItems}
|
223
|
+
/>
|
242
224
|
);
|
243
225
|
} else if (item['type'] === 'group') {
|
244
226
|
let groupItems: any = [];
|
@@ -262,7 +244,8 @@ export const Dropdown = ({
|
|
262
244
|
label={item['label']}
|
263
245
|
icon={item['icon']}
|
264
246
|
active={item['active']}
|
265
|
-
onSelect={item['onSelect']}
|
247
|
+
onSelect={item['onSelect']}
|
248
|
+
onChange={onChange} />);
|
266
249
|
}
|
267
250
|
}
|
268
251
|
|
@@ -341,18 +324,76 @@ export const Dropdown = ({
|
|
341
324
|
};
|
342
325
|
|
343
326
|
const DropdownItem = ({
|
344
|
-
|
345
|
-
|
346
|
-
|
347
|
-
|
348
|
-
|
327
|
+
label,
|
328
|
+
icon,
|
329
|
+
active,
|
330
|
+
onSelect,
|
331
|
+
onChange,
|
332
|
+
}: IMenuItemRes) => {
|
349
333
|
return (
|
350
334
|
<li role='none' className={active ? 'dropdown__menu-item--active' : ''}>
|
351
|
-
<button tabIndex={0} role='menuitem' onClick={
|
335
|
+
<button tabIndex={0} role='menuitem' onClick={() => {
|
336
|
+
onSelect();
|
337
|
+
if (onChange) {
|
338
|
+
onChange();
|
339
|
+
}
|
340
|
+
}}>
|
352
341
|
<i className={icon ? ('icon-' + icon) : ''}></i>
|
353
342
|
{label}
|
354
343
|
</button>
|
355
344
|
</li>
|
356
345
|
);
|
346
|
+
};
|
347
|
+
|
348
|
+
const DropdownItemWithSubmenu = ({
|
349
|
+
index,
|
350
|
+
item,
|
351
|
+
subMenuItems,
|
352
|
+
}: IMenuItem | any) => {
|
353
|
+
const [open, setOpen] = React.useState<undefined | boolean>(undefined);
|
354
|
+
|
355
|
+
const refButtonSubMenu = React.useRef(null);
|
356
|
+
const refSubMenu = React.useRef(null);
|
357
|
+
|
358
|
+
React.useEffect(() => {
|
359
|
+
let subMenuRef: any = refSubMenu.current;
|
360
|
+
let subToggleRef = refButtonSubMenu.current;
|
361
|
+
|
362
|
+
if (open === true) {
|
363
|
+
document.body.appendChild(subMenuRef);
|
364
|
+
subMenuRef.style.display = 'block';
|
365
|
+
|
366
|
+
} else if (open === false) {
|
367
|
+
document.body.removeChild(subMenuRef);
|
368
|
+
subMenuRef.style.display = 'none';
|
369
|
+
}
|
370
|
+
|
371
|
+
if (subMenuRef && subToggleRef) {
|
372
|
+
createPopper(subToggleRef, subMenuRef, {
|
373
|
+
placement: 'right-start',
|
374
|
+
});
|
375
|
+
}
|
376
|
+
}, [open]);
|
357
377
|
|
378
|
+
return (
|
379
|
+
<li key={index} ref={refButtonSubMenu}>
|
380
|
+
<div className='dropdown' onMouseLeave={() => setOpen(false) }>
|
381
|
+
<button
|
382
|
+
className='dropdown__toggle dropdown-toggle'
|
383
|
+
aria-haspopup="menu"
|
384
|
+
tabIndex={0}
|
385
|
+
onMouseOver={() => setOpen(true) }
|
386
|
+
onClick={item['onSelect']}>
|
387
|
+
{item['icon'] ? <i className={'icon-' + item['icon']}></i> : null}
|
388
|
+
{item['label']}
|
389
|
+
</button>
|
390
|
+
<ul role='menu'
|
391
|
+
ref={refSubMenu}
|
392
|
+
style={{display: 'none'}}
|
393
|
+
className='dropdown__menu'>
|
394
|
+
{subMenuItems}
|
395
|
+
</ul>
|
396
|
+
</div>
|
397
|
+
</li>
|
398
|
+
);
|
358
399
|
};
|
@@ -371,5 +371,11 @@ export function getDurationString(seconds: number) {
|
|
371
371
|
let minute = zeroPad(Math.floor((seconds % 3600) / 60));
|
372
372
|
let second = zeroPad(Math.floor(seconds % 60));
|
373
373
|
|
374
|
-
|
374
|
+
if (Number(hour) === 0 && Number(minute) > 0) {
|
375
|
+
return `${minute}m ${second}s`;
|
376
|
+
} else if (Number(hour) === 0 && Number(minute) === 0) {
|
377
|
+
return `${second}s`;
|
378
|
+
} else {
|
379
|
+
return `${hour}h ${minute}m ${second}s`;
|
380
|
+
}
|
375
381
|
}
|
@@ -22,6 +22,7 @@ interface IProps {
|
|
22
22
|
menuId?: string;
|
23
23
|
ariaControls?: string;
|
24
24
|
buttonAnimation?: 'spin' | 'squeeze' | 'none';
|
25
|
+
editorFullWidth?: boolean;
|
25
26
|
}
|
26
27
|
|
27
28
|
export class CoreLayout extends React.PureComponent<IProps> {
|
@@ -43,7 +44,7 @@ export class CoreLayout extends React.PureComponent<IProps> {
|
|
43
44
|
{this.props.topMenu}
|
44
45
|
</CoreLayoutTopMenu>
|
45
46
|
)}
|
46
|
-
<CoreLayoutMain>
|
47
|
+
<CoreLayoutMain editorFullWidth={this.props.editorFullWidth}>
|
47
48
|
{this.props.children}
|
48
49
|
</CoreLayoutMain>
|
49
50
|
{this.props.footer && (
|
@@ -1,14 +1,20 @@
|
|
1
1
|
import * as React from 'react';
|
2
|
+
import classNames from 'classnames';
|
2
3
|
|
3
4
|
interface IProps {
|
4
5
|
children?: React.ReactNode;
|
5
6
|
id?: string;
|
7
|
+
editorFullWidth?: boolean;
|
6
8
|
}
|
7
9
|
|
8
10
|
export class CoreLayoutMain extends React.PureComponent<IProps> {
|
9
11
|
render() {
|
12
|
+
const classes = classNames('sd-content sd-content-wrapper', {
|
13
|
+
'sd-content-wrapper--editor-full': this.props.editorFullWidth,
|
14
|
+
},
|
15
|
+
);
|
10
16
|
return (
|
11
|
-
<section id={this.props.id} className=
|
17
|
+
<section id={this.props.id} className={classes}>
|
12
18
|
{this.props.children}
|
13
19
|
</section>
|
14
20
|
);
|
@@ -6,13 +6,15 @@ import { Button } from '../Button';
|
|
6
6
|
import { Dropdown, IMenuItem, ISubmenu, IMenuGroup } from '../Dropdown';
|
7
7
|
|
8
8
|
export interface IProps {
|
9
|
-
children?: React.ReactNode;
|
10
9
|
array: Array<IPropsArrayItem>;
|
11
10
|
addItem?: boolean;
|
12
11
|
dragAndDrop?: boolean;
|
13
12
|
itemsDropdown?: Array<IMenuItem | ISubmenu | IMenuGroup | 'divider'>;
|
14
13
|
className?: string;
|
14
|
+
readOnly?: boolean;
|
15
|
+
showDragHandle?: 'always' | 'onHover' | 'none'; // always default
|
15
16
|
onDrag?(start: number, end: number): void;
|
17
|
+
onAddItem?(index: number, item?: IPropsArrayItem ): void;
|
16
18
|
}
|
17
19
|
|
18
20
|
export interface IPropsArrayItem {
|
@@ -21,6 +23,12 @@ export interface IPropsArrayItem {
|
|
21
23
|
end?: React.ReactNode;
|
22
24
|
action?: React.ReactNode;
|
23
25
|
onClick?(): void;
|
26
|
+
onDoubleClick?(): void;
|
27
|
+
hexColor?: string;
|
28
|
+
}
|
29
|
+
|
30
|
+
interface IState {
|
31
|
+
items: Array<IPropsArrayItem>;
|
24
32
|
}
|
25
33
|
|
26
34
|
const reorder = (list: Array<IPropsArrayItem>, startIndex: number, endIndex: number) => {
|
@@ -31,25 +39,30 @@ const reorder = (list: Array<IPropsArrayItem>, startIndex: number, endIndex: num
|
|
31
39
|
return result;
|
32
40
|
};
|
33
41
|
|
34
|
-
class TableList extends React.PureComponent<IProps,
|
35
|
-
constructor(props:
|
42
|
+
class TableList extends React.PureComponent<IProps, IState> {
|
43
|
+
constructor(props: IProps) {
|
36
44
|
super(props);
|
37
45
|
this.state = {
|
38
46
|
items: [],
|
39
47
|
};
|
40
48
|
|
41
49
|
this.onDragEnd = this.onDragEnd.bind(this);
|
50
|
+
this.dropDown = this.dropDown.bind(this);
|
42
51
|
}
|
43
52
|
|
44
53
|
componentDidMount(): void {
|
45
|
-
|
54
|
+
if (this.props.array) {
|
55
|
+
this.setState({ items: this.props.array });
|
56
|
+
}
|
46
57
|
}
|
47
58
|
|
48
|
-
componentDidUpdate(prevProps:
|
49
|
-
if (
|
50
|
-
this.
|
51
|
-
|
52
|
-
|
59
|
+
componentDidUpdate(prevProps: IProps): void {
|
60
|
+
if (this.props.array) {
|
61
|
+
if (prevProps.array !== this.props.array) {
|
62
|
+
this.setState({
|
63
|
+
items: this.props.array,
|
64
|
+
});
|
65
|
+
}
|
53
66
|
}
|
54
67
|
}
|
55
68
|
|
@@ -63,23 +76,41 @@ class TableList extends React.PureComponent<IProps, { items: Array<IPropsArrayIt
|
|
63
76
|
result.destination.index,
|
64
77
|
);
|
65
78
|
this.setState({
|
66
|
-
items,
|
79
|
+
items: items,
|
67
80
|
});
|
68
81
|
|
69
82
|
return this.props.onDrag ?
|
70
83
|
this.props.onDrag(result.source.index, result.destination.index) : null;
|
71
84
|
}
|
72
85
|
|
86
|
+
dropDown() {
|
87
|
+
return (
|
88
|
+
<Dropdown
|
89
|
+
items={this.props.itemsDropdown ? this.props.itemsDropdown : []}>
|
90
|
+
<Button
|
91
|
+
type="primary"
|
92
|
+
icon="plus-large"
|
93
|
+
text="Add item"
|
94
|
+
size="small"
|
95
|
+
shape="round"
|
96
|
+
iconOnly={true}
|
97
|
+
onClick={() => false}
|
98
|
+
/>
|
99
|
+
</Dropdown>
|
100
|
+
);
|
101
|
+
}
|
102
|
+
|
73
103
|
render() {
|
74
|
-
let classes = classNames({
|
104
|
+
let classes = classNames('', {
|
75
105
|
'table-list': !this.props.addItem,
|
106
|
+
'table-list--read-only': this.props.readOnly,
|
76
107
|
[`${this.props.className}`]: this.props.className,
|
77
108
|
});
|
78
109
|
|
79
110
|
return (
|
80
|
-
this.
|
81
|
-
this.props.dragAndDrop
|
82
|
-
<DragDropContext onDragEnd={this.onDragEnd}>
|
111
|
+
this.state.items.length > 0
|
112
|
+
? this.props.dragAndDrop
|
113
|
+
? <DragDropContext onDragEnd={this.onDragEnd}>
|
83
114
|
<Droppable droppableId="droppable">
|
84
115
|
{(provided, _snapshot) => (
|
85
116
|
<ul
|
@@ -100,13 +131,30 @@ class TableList extends React.PureComponent<IProps, { items: Array<IPropsArrayIt
|
|
100
131
|
end={item.end}
|
101
132
|
action={item.action}
|
102
133
|
onClick={item.onClick ? item.onClick : undefined}
|
134
|
+
onDoubleClick={item.onDoubleClick
|
135
|
+
? item.onDoubleClick
|
136
|
+
: undefined}
|
103
137
|
addItem={this.props.addItem}
|
104
|
-
itemsDropdown={this.props.itemsDropdown}
|
138
|
+
itemsDropdown={this.props.itemsDropdown}
|
139
|
+
hexColor={item.hexColor}
|
140
|
+
onAddItem={() => this.props.onAddItem
|
141
|
+
&& this.props.onAddItem(index, item)}
|
142
|
+
showDragHandle={this.props.showDragHandle}
|
143
|
+
/>
|
105
144
|
</div>
|
106
145
|
)}
|
107
146
|
</Draggable>
|
108
147
|
))}
|
109
148
|
{provided.placeholder}
|
149
|
+
{(this.props.addItem && !this.props.readOnly) &&
|
150
|
+
<li className={`table-list__add-item table-list__item--margin`}>
|
151
|
+
<Tooltip text='Add item' flow='top' appendToBody={true}>
|
152
|
+
<div className='table-list__add-item--container sd-margin-x--auto'>
|
153
|
+
{this.dropDown()}
|
154
|
+
</div>
|
155
|
+
</Tooltip>
|
156
|
+
</li>
|
157
|
+
}
|
110
158
|
</ul>
|
111
159
|
)}
|
112
160
|
</Droppable>
|
@@ -120,14 +168,36 @@ class TableList extends React.PureComponent<IProps, { items: Array<IPropsArrayIt
|
|
120
168
|
end={item.end}
|
121
169
|
action={item.action}
|
122
170
|
onClick={item.onClick ? item.onClick : undefined}
|
171
|
+
onDoubleClick={item.onDoubleClick
|
172
|
+
? item.onDoubleClick
|
173
|
+
: undefined}
|
123
174
|
addItem={this.props.addItem}
|
124
|
-
itemsDropdown={this.props.itemsDropdown}
|
175
|
+
itemsDropdown={this.props.itemsDropdown}
|
176
|
+
hexColor={item.hexColor}
|
177
|
+
onAddItem={() => this.props.onAddItem
|
178
|
+
&& this.props.onAddItem(index, item)}
|
179
|
+
/>
|
125
180
|
))}
|
181
|
+
{(this.props.addItem && !this.props.readOnly) &&
|
182
|
+
<li className={`table-list__add-item table-list__item--margin`}>
|
183
|
+
<Tooltip text='Add item' flow='top' appendToBody={true}>
|
184
|
+
<div className='table-list__add-item--container sd-margin-x--auto'>
|
185
|
+
{this.dropDown()}
|
186
|
+
</div>
|
187
|
+
</Tooltip>
|
188
|
+
</li>
|
189
|
+
}
|
126
190
|
</ul>
|
127
|
-
: this.props.
|
128
|
-
|
129
|
-
|
191
|
+
: (this.props.addItem && !this.props.readOnly) ? <ul className={classes}>
|
192
|
+
<li className={`table-list__add-item table-list__item--margin`}>
|
193
|
+
<Tooltip text='Add item' flow='top' appendToBody={true}>
|
194
|
+
<div className='table-list__add-item--container sd-margin-x--auto'>
|
195
|
+
{this.dropDown()}
|
196
|
+
</div>
|
197
|
+
</Tooltip>
|
198
|
+
</li>
|
130
199
|
</ul>
|
200
|
+
: null
|
131
201
|
);
|
132
202
|
}
|
133
203
|
}
|
@@ -141,16 +211,56 @@ export interface IPropsItem {
|
|
141
211
|
itemsDropdown?: any;
|
142
212
|
dragAndDrop?: boolean;
|
143
213
|
onClick?(): void;
|
214
|
+
onDoubleClick?(): void;
|
215
|
+
onSelect?(): void;
|
216
|
+
onAddItem?(e: number): void;
|
217
|
+
hexColor?: string;
|
218
|
+
showDragHandle?: 'always' | 'onHover' | 'none';
|
144
219
|
}
|
145
220
|
|
146
221
|
class TableListItem extends React.PureComponent<IPropsItem> {
|
222
|
+
private timer: any;
|
223
|
+
private delay = 200;
|
224
|
+
private prevent = false;
|
225
|
+
|
226
|
+
onSingleClick = () => {
|
227
|
+
this.timer = setTimeout(() => {
|
228
|
+
if (!this.prevent) {
|
229
|
+
if (this.props.onClick) {
|
230
|
+
this.props.onClick();
|
231
|
+
}
|
232
|
+
}
|
233
|
+
}, this.delay);
|
234
|
+
}
|
235
|
+
|
236
|
+
onDoubleClick = () => {
|
237
|
+
clearTimeout(this.timer);
|
238
|
+
this.prevent = true;
|
239
|
+
if (this.props.onDoubleClick) {
|
240
|
+
this.props.onDoubleClick();
|
241
|
+
}
|
242
|
+
setTimeout(() => {
|
243
|
+
this.prevent = false;
|
244
|
+
}, this.delay);
|
245
|
+
}
|
246
|
+
|
147
247
|
render() {
|
248
|
+
|
249
|
+
let classes = classNames('table-list__item', {
|
250
|
+
'table-list__item--clickable': this.props.onClick,
|
251
|
+
'table-list__item--draggable': this.props.dragAndDrop,
|
252
|
+
'table-list__item--drag-handles-always': !this.props.showDragHandle,
|
253
|
+
'table-list__item--drag-handles-none': this.props.showDragHandle === 'none',
|
254
|
+
});
|
255
|
+
|
148
256
|
return (
|
149
257
|
this.props.addItem ?
|
150
258
|
<li className='table-list__item-container'>
|
151
259
|
<div
|
152
|
-
onClick={this.
|
153
|
-
|
260
|
+
onClick={() => this.onSingleClick()}
|
261
|
+
onDoubleClick={() => this.onDoubleClick()}
|
262
|
+
className={classes}>
|
263
|
+
<div className='table-list__item-border' style={{backgroundColor: this.props.hexColor}}></div>
|
154
264
|
<div className='table-list__item-content'>
|
155
265
|
<div className='table-list__item-content-block'>
|
156
266
|
{this.props.start && this.props.start}
|
@@ -170,7 +280,8 @@ class TableListItem extends React.PureComponent<IPropsItem> {
|
|
170
280
|
<Tooltip text='Add item' flow='top' appendToBody={true}>
|
171
281
|
<div className='table-list__add-bar'>
|
172
282
|
<Dropdown
|
173
|
-
|
283
|
+
onChange={this.props.onAddItem}
|
284
|
+
items={this.props.itemsDropdown ? this.props.itemsDropdown : []}>
|
174
285
|
<Button
|
175
286
|
type="primary"
|
176
287
|
icon="plus-large"
|
@@ -178,7 +289,7 @@ class TableListItem extends React.PureComponent<IPropsItem> {
|
|
178
289
|
size="small"
|
179
290
|
shape="round"
|
180
291
|
iconOnly={true}
|
181
|
-
onClick={() => false}
|
292
|
+
onClick={() => false }
|
182
293
|
/>
|
183
294
|
</Dropdown>
|
184
295
|
</div>
|
@@ -186,8 +297,10 @@ class TableListItem extends React.PureComponent<IPropsItem> {
|
|
186
297
|
</div>
|
187
298
|
</li>
|
188
299
|
: <li
|
189
|
-
className={
|
190
|
-
onClick={this.
|
300
|
+
className={`${classes} table-list__item--margin`}
|
301
|
+
onClick={() => this.onSingleClick()}
|
302
|
+
onDoubleClick={() => this.onDoubleClick()}>
|
303
|
+
<div className='table-list__item-border' style={{backgroundColor: this.props.hexColor}}></div>
|
191
304
|
<div className='table-list__item-content'>
|
192
305
|
<div className='table-list__item-content-block'>
|
193
306
|
{this.props.start && this.props.start}
|