playbook_ui 13.28.0 → 13.29.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/app/pb_kits/playbook/_playbook.scss +2 -3
- data/app/pb_kits/playbook/index.js +2 -0
- data/app/pb_kits/playbook/pb_advanced_table/advanced_table.html.erb +2 -2
- data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_beta_subrow_headers.html.erb +40 -0
- data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_beta_subrow_headers.md +3 -0
- data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_subrow_headers.md +1 -1
- data/app/pb_kits/playbook/pb_advanced_table/docs/example.yml +1 -1
- data/app/pb_kits/playbook/pb_advanced_table/table_body.html.erb +1 -1
- data/app/pb_kits/playbook/pb_advanced_table/table_body.rb +14 -4
- data/app/pb_kits/playbook/pb_advanced_table/table_header.html.erb +10 -2
- data/app/pb_kits/playbook/pb_advanced_table/table_row.html.erb +1 -1
- data/app/pb_kits/playbook/pb_advanced_table/table_row.rb +2 -0
- data/app/pb_kits/playbook/pb_advanced_table/table_subrow_header.html.erb +34 -0
- data/app/pb_kits/playbook/pb_advanced_table/table_subrow_header.rb +31 -0
- data/app/pb_kits/playbook/pb_bar_graph/_bar_graph.tsx +4 -1
- data/app/pb_kits/playbook/pb_bar_graph/barGraph.test.js +31 -0
- data/app/pb_kits/playbook/pb_bar_graph/bar_graph.rb +16 -0
- data/app/pb_kits/playbook/pb_bar_graph/docs/_bar_graph_custom.md +2 -1
- data/app/pb_kits/playbook/pb_bar_graph/docs/{_bar_graph_custom.html.erb → _bar_graph_custom_rails.html.erb} +3 -3
- data/app/pb_kits/playbook/pb_bar_graph/docs/_bar_graph_custom_rails.md +2 -0
- data/app/pb_kits/playbook/pb_bar_graph/docs/example.yml +1 -1
- data/app/pb_kits/playbook/pb_card/_card_mixin.scss +2 -1
- data/app/pb_kits/playbook/pb_checkbox/_checkbox.scss +1 -2
- data/app/pb_kits/playbook/pb_circle_chart/_circle_chart.tsx +9 -3
- data/app/pb_kits/playbook/pb_circle_chart/circleChart.test.js +45 -0
- data/app/pb_kits/playbook/pb_circle_chart/circle_chart.rb +24 -1
- data/app/pb_kits/playbook/pb_collapsible/__snapshots__/collapsible.test.js.snap +53 -0
- data/app/pb_kits/playbook/pb_collapsible/_collapsible.tsx +14 -8
- data/app/pb_kits/playbook/pb_collapsible/collapsible.test.js +24 -0
- data/app/pb_kits/playbook/pb_dashboard/pbChartsDarkTheme.ts +7 -1
- data/app/pb_kits/playbook/pb_dashboard/pbChartsLightTheme.ts +9 -1
- data/app/pb_kits/playbook/pb_draggable/_draggable.scss +13 -0
- data/app/pb_kits/playbook/pb_draggable/_draggable.tsx +53 -0
- data/app/pb_kits/playbook/pb_draggable/context/index.tsx +92 -0
- data/app/pb_kits/playbook/pb_draggable/docs/_draggable_default.jsx +53 -0
- data/app/pb_kits/playbook/pb_draggable/docs/_draggable_default.md +4 -0
- data/app/pb_kits/playbook/pb_draggable/docs/_draggable_multiple_containers.jsx +158 -0
- data/app/pb_kits/playbook/pb_draggable/docs/_draggable_with_cards.jsx +119 -0
- data/app/pb_kits/playbook/pb_draggable/docs/_draggable_with_list.jsx +50 -0
- data/app/pb_kits/playbook/pb_draggable/docs/_draggable_with_list.md +1 -0
- data/app/pb_kits/playbook/pb_draggable/docs/_draggable_with_selectable_list.jsx +51 -0
- data/app/pb_kits/playbook/pb_draggable/docs/example.yml +11 -0
- data/app/pb_kits/playbook/pb_draggable/docs/index.js +5 -0
- data/app/pb_kits/playbook/pb_draggable/draggable.test.jsx +65 -0
- data/app/pb_kits/playbook/pb_draggable/subcomponents/DraggableContainer.tsx +54 -0
- data/app/pb_kits/playbook/pb_draggable/subcomponents/DraggableItem.tsx +57 -0
- data/app/pb_kits/playbook/pb_form/docs/_form_form_with.html.erb +10 -0
- data/app/pb_kits/playbook/pb_form_group/_form_group.scss +2 -2
- data/app/pb_kits/playbook/pb_gauge/_gauge.tsx +4 -1
- data/app/pb_kits/playbook/pb_gauge/gauge.rb +6 -1
- data/app/pb_kits/playbook/pb_gauge/gauge.test.js +35 -0
- data/app/pb_kits/playbook/pb_icon/icon.rb +3 -2
- data/app/pb_kits/playbook/pb_line_graph/_line_graph.tsx +8 -2
- data/app/pb_kits/playbook/pb_line_graph/lineGraph.test.js +52 -0
- data/app/pb_kits/playbook/pb_line_graph/line_graph.rb +22 -1
- data/app/pb_kits/playbook/pb_list/_list.tsx +43 -2
- data/app/pb_kits/playbook/pb_list/_list_item.tsx +46 -10
- data/app/pb_kits/playbook/pb_pill/docs/_description.md +1 -1
- data/app/pb_kits/playbook/pb_selectable_card/_selectable_card.scss +1 -0
- data/app/pb_kits/playbook/pb_selectable_card/_selectable_card.tsx +30 -32
- data/app/pb_kits/playbook/pb_selectable_card/selectable_card.html.erb +0 -2
- data/app/pb_kits/playbook/pb_selectable_list/_item.tsx +35 -28
- data/app/pb_kits/playbook/pb_selectable_list/_selectable_list.tsx +5 -1
- data/app/pb_kits/playbook/pb_table/_table.tsx +5 -0
- data/app/pb_kits/playbook/pb_table/docs/_table_alignment_column.jsx +33 -32
- data/app/pb_kits/playbook/pb_table/docs/_table_alignment_column.md +1 -1
- data/app/pb_kits/playbook/pb_table/docs/_table_alignment_column_rails.md +2 -0
- data/app/pb_kits/playbook/pb_table/docs/_table_alignment_row.jsx +33 -33
- data/app/pb_kits/playbook/pb_table/docs/_table_alignment_row.md +1 -1
- data/app/pb_kits/playbook/pb_table/docs/_table_alignment_row_rails.html.erb +34 -0
- data/app/pb_kits/playbook/pb_table/docs/_table_alignment_row_rails.md +2 -0
- data/app/pb_kits/playbook/pb_table/docs/_table_alignment_shift_data.jsx +51 -50
- data/app/pb_kits/playbook/pb_table/docs/_table_alignment_shift_data.md +1 -1
- data/app/pb_kits/playbook/pb_table/docs/_table_alignment_shift_data_rails.html.erb +54 -0
- data/app/pb_kits/playbook/pb_table/docs/_table_alignment_shift_data_rails.md +2 -0
- data/app/pb_kits/playbook/pb_table/docs/_table_alignment_shift_row.jsx +37 -38
- data/app/pb_kits/playbook/pb_table/docs/_table_alignment_shift_row.md +1 -0
- data/app/pb_kits/playbook/pb_table/docs/_table_alignment_shift_row_rails.html.erb +53 -0
- data/app/pb_kits/playbook/pb_table/docs/_table_alignment_shift_row_rails.md +1 -0
- data/app/pb_kits/playbook/pb_table/docs/{_table_alignment_row.html.erb → _table_outer_padding.html.erb} +7 -7
- data/app/pb_kits/playbook/pb_table/docs/_table_outer_padding.jsx +76 -0
- data/app/pb_kits/playbook/pb_table/docs/_table_outer_padding.md +1 -0
- data/app/pb_kits/playbook/pb_table/docs/example.yml +9 -9
- data/app/pb_kits/playbook/pb_table/docs/index.js +1 -0
- data/app/pb_kits/playbook/pb_table/styles/_all.scss +1 -0
- data/app/pb_kits/playbook/pb_table/styles/_outer_padding.scss +21 -0
- data/app/pb_kits/playbook/pb_table/table.rb +14 -1
- data/app/pb_kits/playbook/pb_table/table.test.js +5 -1
- data/app/pb_kits/playbook/pb_tooltip/index.js +1 -0
- data/app/pb_kits/playbook/pb_treemap_chart/_treemap_chart.tsx +12 -9
- data/app/pb_kits/playbook/pb_treemap_chart/treemapChart.test.js +61 -0
- data/app/pb_kits/playbook/pb_treemap_chart/treemap_chart.rb +6 -1
- data/app/pb_kits/playbook/playbook-doc.js +2 -0
- data/app/pb_kits/playbook/tokens/_vertical_align.scss +18 -0
- data/app/pb_kits/playbook/utilities/_vertical_align.scss +16 -0
- data/app/pb_kits/playbook/utilities/globalProps.ts +12 -1
- data/dist/menu.yml +5 -2
- data/dist/playbook-rails.js +7 -7
- data/lib/playbook/classnames.rb +1 -0
- data/lib/playbook/forms/builder/dropdown_field.rb +14 -0
- data/lib/playbook/forms/builder.rb +1 -0
- data/lib/playbook/kit_base.rb +2 -0
- data/lib/playbook/version.rb +2 -2
- data/lib/playbook/vertical_align.rb +37 -0
- metadata +46 -7
- data/app/pb_kits/playbook/pb_table/docs/_table_alignment_shift_data.html.erb +0 -63
- data/app/pb_kits/playbook/pb_table/docs/_table_alignment_shift_row.html.erb +0 -52
- /data/app/pb_kits/playbook/pb_table/docs/{_table_alignment_column.html.erb → _table_alignment_column_rails.html.erb} +0 -0
@@ -1,4 +1,4 @@
|
|
1
|
-
import React, { useEffect } from 'react'
|
1
|
+
import React, { useEffect, ReactElement } from 'react'
|
2
2
|
import classnames from 'classnames'
|
3
3
|
import useCollapsible from './useCollapsible'
|
4
4
|
|
@@ -11,9 +11,16 @@ import CollapsibleContext from './context'
|
|
11
11
|
import { IconSizes } from "../pb_icon/_icon"
|
12
12
|
import CollapsibleIcon from './child_kits/CollapsibleIcon'
|
13
13
|
|
14
|
+
type CollapsibleMainProps = {
|
15
|
+
children: React.ReactNode
|
16
|
+
}
|
17
|
+
|
18
|
+
type CollapsibleContentProps = {
|
19
|
+
children: React.ReactNode
|
20
|
+
}
|
14
21
|
|
15
22
|
type CollapsibleProps = {
|
16
|
-
children?:
|
23
|
+
children?: [ReactElement<CollapsibleMainProps>, ReactElement<CollapsibleContentProps>],
|
17
24
|
aria?: {[key: string]: string},
|
18
25
|
className?: string,
|
19
26
|
collapsed?: boolean,
|
@@ -30,7 +37,7 @@ type CollapsibleProps = {
|
|
30
37
|
const Collapsible = ({
|
31
38
|
aria = {},
|
32
39
|
className,
|
33
|
-
children
|
40
|
+
children,
|
34
41
|
collapsed = true,
|
35
42
|
data = {},
|
36
43
|
htmlOptions = {},
|
@@ -48,13 +55,12 @@ const Collapsible = ({
|
|
48
55
|
setIsCollapsed(collapsed)
|
49
56
|
},[collapsed])
|
50
57
|
|
51
|
-
|
52
|
-
|
53
|
-
if (CollapsibleParent.length !== 2) {
|
58
|
+
if (children.length !== 2) {
|
54
59
|
throw new Error('Collapsible requires <CollapsibleMain> and <CollapsibleContent> to function properly.')
|
55
60
|
}
|
56
|
-
|
57
|
-
const
|
61
|
+
|
62
|
+
const FirstChild = children[0]
|
63
|
+
const SecondChild = children[1]
|
58
64
|
|
59
65
|
const Main = FirstChild.type === CollapsibleMain ? FirstChild : null
|
60
66
|
const Content = SecondChild.type === CollapsibleContent ? SecondChild : null
|
@@ -48,3 +48,27 @@ test('returns namespaced additional_class class name', () => {
|
|
48
48
|
const kit = screen.getByTestId(testId)
|
49
49
|
expect(kit).toHaveClass(`${kitClass} additional_class`)
|
50
50
|
})
|
51
|
+
|
52
|
+
test('html structure is correct', () => {
|
53
|
+
const { container } = render(
|
54
|
+
<Collapsible
|
55
|
+
className="additional_class"
|
56
|
+
data={{ testid: testId }}
|
57
|
+
iconColor='lighter'
|
58
|
+
iconSize="lg"
|
59
|
+
>
|
60
|
+
<Collapsible.Main>
|
61
|
+
<div>{'Main Section'}</div>
|
62
|
+
</Collapsible.Main>
|
63
|
+
<Collapsible.Content>
|
64
|
+
<div>
|
65
|
+
{
|
66
|
+
'Lorem ipsum dolor sit amet, consectetur adipiscing elit. In vel erat sed purus hendrerit viverra. Duis et vestibulum metus. Sed consequat ut ante non vehicula. Etiam nunc massa, pharetra vel quam id, posuere rhoncus quam. Quisque imperdiet arcu enim, nec aliquet justo auctor eget. Curabitur in metus nec nunc rhoncus faucibus vitae ac elit. Nulla facilisi. Vestibulum quis pretium nulla. Nulla ut accumsan velit. Duis varius urna sed sem tempor, sit amet fermentum nibh auctor. Praesent lorem arcu, egestas non ante quis, placerat pellentesque lectus.Vestibulum lacinia ipsum quis venenatis tristique. Vivamus suscipit, libero eu fringilla egestas, orci urna commodo arcu, vel gravida turpis ipsum molestie nibh. Donec cursus eu ante sagittis ultrices. Phasellus id sagittis risus. Mauris dapibus neque faucibus, tempor ligula vel, cursus ante. Donec faucibus gravida porta. Nullam egestas est quis aliquam feugiat. Sed eget metus diam. Cras eget placerat libero.'
|
67
|
+
}
|
68
|
+
</div>
|
69
|
+
</Collapsible.Content>
|
70
|
+
</Collapsible>
|
71
|
+
)
|
72
|
+
|
73
|
+
expect(container).toMatchSnapshot()
|
74
|
+
})
|
@@ -3,6 +3,12 @@ import typography from '../tokens/exports/_typography.scss'
|
|
3
3
|
|
4
4
|
import { ThemeProps } from './themeTypes'
|
5
5
|
|
6
|
+
interface CustomTreemapOptions extends Highcharts.SeriesTreemapOptions {
|
7
|
+
traverseUpButton?: {
|
8
|
+
position: { y: number };
|
9
|
+
};
|
10
|
+
}
|
11
|
+
|
6
12
|
const highchartsDarkTheme: ThemeProps = {
|
7
13
|
lang: {
|
8
14
|
thousandsSep: ',',
|
@@ -200,7 +206,7 @@ const highchartsDarkTheme: ThemeProps = {
|
|
200
206
|
traverseUpButton: {
|
201
207
|
position: { y: -50 },
|
202
208
|
},
|
203
|
-
},
|
209
|
+
} as CustomTreemapOptions,
|
204
210
|
},
|
205
211
|
credits: {
|
206
212
|
enabled: false
|
@@ -3,6 +3,13 @@ import typography from '../tokens/exports/_typography.scss'
|
|
3
3
|
|
4
4
|
import { ThemeProps } from './themeTypes'
|
5
5
|
|
6
|
+
interface CustomTreemapOptions extends Highcharts.SeriesTreemapOptions {
|
7
|
+
traverseUpButton?: {
|
8
|
+
position: { y: number };
|
9
|
+
};
|
10
|
+
}
|
11
|
+
|
12
|
+
|
6
13
|
const highchartsTheme: ThemeProps = {
|
7
14
|
lang: {
|
8
15
|
thousandsSep: ',',
|
@@ -150,6 +157,7 @@ const highchartsTheme: ThemeProps = {
|
|
150
157
|
fontSize: typography.text_smaller,
|
151
158
|
color: colors.text_lt_light,
|
152
159
|
fontWeight: typography.regular,
|
160
|
+
textOutline: '2px $white',
|
153
161
|
},
|
154
162
|
},
|
155
163
|
},
|
@@ -198,7 +206,7 @@ const highchartsTheme: ThemeProps = {
|
|
198
206
|
traverseUpButton: {
|
199
207
|
position: { y: -50 },
|
200
208
|
},
|
201
|
-
},
|
209
|
+
} as CustomTreemapOptions,
|
202
210
|
},
|
203
211
|
credits: {
|
204
212
|
enabled: false
|
@@ -0,0 +1,53 @@
|
|
1
|
+
import React from "react";
|
2
|
+
import classnames from "classnames";
|
3
|
+
import { buildAriaProps, buildCss, buildDataProps, buildHtmlProps } from "../utilities/props";
|
4
|
+
import { globalProps } from "../utilities/globalProps";
|
5
|
+
import DraggableContainer from "./subcomponents/DraggableContainer";
|
6
|
+
import DraggableItem from "./subcomponents/DraggableItem";
|
7
|
+
|
8
|
+
type DraggableProps = {
|
9
|
+
aria?: { [key: string]: string };
|
10
|
+
className?: string;
|
11
|
+
children?: React.ReactNode;
|
12
|
+
data?: { [key: string]: string };
|
13
|
+
htmlOptions?: {[key: string]: string | number | boolean | (() => void)},
|
14
|
+
id?: string;
|
15
|
+
};
|
16
|
+
|
17
|
+
const Draggable = (props: DraggableProps) => {
|
18
|
+
const {
|
19
|
+
aria = {},
|
20
|
+
className,
|
21
|
+
children,
|
22
|
+
data = {},
|
23
|
+
htmlOptions = {},
|
24
|
+
id,
|
25
|
+
} = props;
|
26
|
+
|
27
|
+
|
28
|
+
const ariaProps = buildAriaProps(aria);
|
29
|
+
const dataProps = buildDataProps(data);
|
30
|
+
const htmlProps = buildHtmlProps(htmlOptions);
|
31
|
+
|
32
|
+
const classes = classnames(
|
33
|
+
buildCss("pb_draggable"),
|
34
|
+
globalProps(props),
|
35
|
+
className
|
36
|
+
);
|
37
|
+
|
38
|
+
return (
|
39
|
+
<div {...ariaProps}
|
40
|
+
{...dataProps}
|
41
|
+
{...htmlProps}
|
42
|
+
className={classes}
|
43
|
+
id={id}
|
44
|
+
>
|
45
|
+
{children}
|
46
|
+
</div>
|
47
|
+
);
|
48
|
+
};
|
49
|
+
|
50
|
+
Draggable.Container = DraggableContainer;
|
51
|
+
Draggable.Item = DraggableItem;
|
52
|
+
|
53
|
+
export default Draggable;
|
@@ -0,0 +1,92 @@
|
|
1
|
+
import React, { createContext, useState, useContext, useEffect } from "react";
|
2
|
+
|
3
|
+
const DragContext = createContext<any>({});
|
4
|
+
|
5
|
+
export const DraggableContext = () => {
|
6
|
+
return useContext(DragContext);
|
7
|
+
};
|
8
|
+
|
9
|
+
export const DraggableProvider = ({ children, initialItems, onChange }: any) => {
|
10
|
+
const [items, setItems] = useState([]);
|
11
|
+
const [dragData, setDragData] = useState<{ [key: string]: any }>({});
|
12
|
+
const [isDragging, setIsDragging] = useState("");
|
13
|
+
const [activeContainer, setActiveContainer] = useState("");
|
14
|
+
|
15
|
+
useEffect(() => {
|
16
|
+
setItems(initialItems);
|
17
|
+
}, [initialItems]);
|
18
|
+
|
19
|
+
useEffect(() => {
|
20
|
+
onChange(items);
|
21
|
+
}, [items]);
|
22
|
+
|
23
|
+
const handleDragStart = (id: string, container: string) => {
|
24
|
+
setDragData({ id: id, initialGroup: container });
|
25
|
+
setIsDragging(id);
|
26
|
+
};
|
27
|
+
|
28
|
+
const handleDragEnter = (id: string, container: string) => {
|
29
|
+
if (dragData?.id !== id) {
|
30
|
+
const newItems = [...items];
|
31
|
+
const draggedItem = newItems.find((item) => item.id === dragData.id);
|
32
|
+
const draggedIndex = newItems.indexOf(draggedItem);
|
33
|
+
const targetIndex = newItems.findIndex((item) => item.id === id);
|
34
|
+
|
35
|
+
newItems.splice(draggedIndex, 1);
|
36
|
+
newItems.splice(targetIndex, 0, draggedItem);
|
37
|
+
|
38
|
+
setItems(newItems);
|
39
|
+
setDragData({ id: dragData.id, initialGroup: container });
|
40
|
+
}
|
41
|
+
};
|
42
|
+
|
43
|
+
const handleDragEnd = () => {
|
44
|
+
setIsDragging("");
|
45
|
+
setActiveContainer("");
|
46
|
+
};
|
47
|
+
|
48
|
+
const changeCategory = (itemId: string, container: string) => {
|
49
|
+
const updatedItems = items.map((item) => {
|
50
|
+
if (item.id === itemId) {
|
51
|
+
return { ...item, container: container };
|
52
|
+
}
|
53
|
+
return item;
|
54
|
+
});
|
55
|
+
|
56
|
+
setItems(updatedItems);
|
57
|
+
};
|
58
|
+
|
59
|
+
const handleDrop = (container: string) => {
|
60
|
+
setIsDragging("");
|
61
|
+
setActiveContainer("");
|
62
|
+
const selected = dragData.id;
|
63
|
+
changeCategory(selected, container);
|
64
|
+
};
|
65
|
+
|
66
|
+
const handleDragOver = (e: Event, container: string) => {
|
67
|
+
e.preventDefault();
|
68
|
+
setActiveContainer(container);
|
69
|
+
};
|
70
|
+
|
71
|
+
|
72
|
+
|
73
|
+
const contextValue = {
|
74
|
+
items,
|
75
|
+
setItems,
|
76
|
+
dragData,
|
77
|
+
setDragData,
|
78
|
+
isDragging,
|
79
|
+
setIsDragging,
|
80
|
+
activeContainer,
|
81
|
+
setActiveContainer,
|
82
|
+
handleDragStart,
|
83
|
+
handleDragEnter,
|
84
|
+
handleDragEnd,
|
85
|
+
handleDrop,
|
86
|
+
handleDragOver,
|
87
|
+
};
|
88
|
+
|
89
|
+
return (
|
90
|
+
<DragContext.Provider value={contextValue}>{children}</DragContext.Provider>
|
91
|
+
);
|
92
|
+
};
|
@@ -0,0 +1,53 @@
|
|
1
|
+
import React, { useState } from "react";
|
2
|
+
import { SelectableList, Draggable, DraggableProvider } from "../../";
|
3
|
+
|
4
|
+
// Initial items to be dragged
|
5
|
+
const data = [
|
6
|
+
{
|
7
|
+
id: "1",
|
8
|
+
text: "Task 1",
|
9
|
+
},
|
10
|
+
{
|
11
|
+
id: "2",
|
12
|
+
text: "Task 2",
|
13
|
+
},
|
14
|
+
{
|
15
|
+
id: "3",
|
16
|
+
text: "Task 3",
|
17
|
+
},
|
18
|
+
{
|
19
|
+
id: "4",
|
20
|
+
text: "Task 4",
|
21
|
+
},
|
22
|
+
];
|
23
|
+
|
24
|
+
const DraggableDefault = (props) => {
|
25
|
+
const [initialState, setInitialState] = useState(data);
|
26
|
+
|
27
|
+
return (
|
28
|
+
<>
|
29
|
+
<DraggableProvider initialItems={data}
|
30
|
+
onChange={(items) => setInitialState(items)}
|
31
|
+
>
|
32
|
+
<Draggable.Container {...props}>
|
33
|
+
<SelectableList variant="checkbox">
|
34
|
+
{initialState.map(({ id, text }) => (
|
35
|
+
<Draggable.Item id={id}
|
36
|
+
key={id}
|
37
|
+
>
|
38
|
+
<SelectableList.Item
|
39
|
+
label={text}
|
40
|
+
name={id}
|
41
|
+
value={id}
|
42
|
+
/>
|
43
|
+
</Draggable.Item>
|
44
|
+
))}
|
45
|
+
</SelectableList>
|
46
|
+
</Draggable.Container>
|
47
|
+
</DraggableProvider>
|
48
|
+
</>
|
49
|
+
|
50
|
+
);
|
51
|
+
};
|
52
|
+
|
53
|
+
export default DraggableDefault;
|
@@ -0,0 +1,4 @@
|
|
1
|
+
To use the Draggable kit, you must use the DraggableProvider and pass in `initialItems`. The `onChange` is a function that returns the data as it changes as items are reordered. Use this to manage state as shown.
|
2
|
+
|
3
|
+
The `Draggable.Container` specifies the container within which items can be dropped.
|
4
|
+
The `Draggable.Item` specifies the items that can be dragged and dropped. `Draggable.Item` requires `id` to be passed in as shown.
|
@@ -0,0 +1,158 @@
|
|
1
|
+
import React, { useState } from "react";
|
2
|
+
import {
|
3
|
+
Flex,
|
4
|
+
Caption,
|
5
|
+
Card,
|
6
|
+
FlexItem,
|
7
|
+
Badge,
|
8
|
+
Avatar,
|
9
|
+
Title,
|
10
|
+
Body,
|
11
|
+
Draggable,
|
12
|
+
DraggableProvider,
|
13
|
+
} from "../../";
|
14
|
+
|
15
|
+
// Initial groups to drag between
|
16
|
+
const containers = ["To Do", "In Progress", "Done"];
|
17
|
+
|
18
|
+
// Initial items to be dragged
|
19
|
+
const data = [
|
20
|
+
{
|
21
|
+
id: "1",
|
22
|
+
container: "To Do",
|
23
|
+
title: "Task 1",
|
24
|
+
description: "Bug fixes",
|
25
|
+
assignee_name: "Terry Miles",
|
26
|
+
assignee_img: "https://randomuser.me/api/portraits/men/44.jpg",
|
27
|
+
},
|
28
|
+
{
|
29
|
+
id: "2",
|
30
|
+
container: "To Do",
|
31
|
+
title: "Task 2",
|
32
|
+
description: "Documentation",
|
33
|
+
assignee_name: "Sophia Miles",
|
34
|
+
assignee_img: "https://randomuser.me/api/portraits/women/8.jpg",
|
35
|
+
},
|
36
|
+
{
|
37
|
+
id: "3",
|
38
|
+
container: "In Progress",
|
39
|
+
title: "Task 3",
|
40
|
+
description: "Add a variant",
|
41
|
+
assignee_name: "Alice Jones",
|
42
|
+
assignee_img: "https://randomuser.me/api/portraits/women/10.jpg",
|
43
|
+
},
|
44
|
+
{
|
45
|
+
id: "4",
|
46
|
+
container: "To Do",
|
47
|
+
title: "Task 4",
|
48
|
+
description: "Add jest tests",
|
49
|
+
assignee_name: "Mike James",
|
50
|
+
assignee_img: "https://randomuser.me/api/portraits/men/8.jpg",
|
51
|
+
},
|
52
|
+
{
|
53
|
+
id: "5",
|
54
|
+
container: "Done",
|
55
|
+
title: "Task 5",
|
56
|
+
description: "Alpha testing",
|
57
|
+
assignee_name: "James Guy",
|
58
|
+
assignee_img: "https://randomuser.me/api/portraits/men/18.jpg",
|
59
|
+
},
|
60
|
+
{
|
61
|
+
id: "6",
|
62
|
+
container: "In Progress",
|
63
|
+
title: "Task 6",
|
64
|
+
description: "Release",
|
65
|
+
assignee_name: "Sally Jones",
|
66
|
+
assignee_img: "https://randomuser.me/api/portraits/women/28.jpg",
|
67
|
+
},
|
68
|
+
];
|
69
|
+
|
70
|
+
const DraggableMultipleContainer = (props) => {
|
71
|
+
const [initialState, setInitialState] = useState(data);
|
72
|
+
|
73
|
+
const badgeProperties = (container) => {
|
74
|
+
switch (container) {
|
75
|
+
case "To Do":
|
76
|
+
return { text: "queue", color: "warning" };
|
77
|
+
case "In Progress":
|
78
|
+
return { text: "progress", color: "primary" };
|
79
|
+
default:
|
80
|
+
return { text: "done", color: "success" };
|
81
|
+
}
|
82
|
+
};
|
83
|
+
|
84
|
+
return (
|
85
|
+
<DraggableProvider initialItems={data}
|
86
|
+
onChange={(items) => setInitialState(items)}
|
87
|
+
>
|
88
|
+
<Flex
|
89
|
+
justifyContent="center"
|
90
|
+
{...props}
|
91
|
+
>
|
92
|
+
{containers?.map((container) => (
|
93
|
+
<Draggable.Container
|
94
|
+
container={container}
|
95
|
+
key={container}
|
96
|
+
padding="sm"
|
97
|
+
>
|
98
|
+
<Caption textAlign="center">{container}</Caption>
|
99
|
+
<Flex
|
100
|
+
alignItems="stretch"
|
101
|
+
orientation="column"
|
102
|
+
>
|
103
|
+
{initialState
|
104
|
+
.filter((item) => item.container === container)
|
105
|
+
.map(
|
106
|
+
({
|
107
|
+
assignee_img,
|
108
|
+
assignee_name,
|
109
|
+
description,
|
110
|
+
id,
|
111
|
+
title,
|
112
|
+
}) => (
|
113
|
+
<Draggable.Item
|
114
|
+
container={container}
|
115
|
+
id={id}
|
116
|
+
key={id}
|
117
|
+
>
|
118
|
+
<Card
|
119
|
+
marginBottom="sm"
|
120
|
+
padding="sm"
|
121
|
+
>
|
122
|
+
<Flex justify="between">
|
123
|
+
<FlexItem>
|
124
|
+
<Flex>
|
125
|
+
<Avatar
|
126
|
+
imageUrl={assignee_img}
|
127
|
+
name={assignee_name}
|
128
|
+
size="xxs"
|
129
|
+
/>
|
130
|
+
<Title paddingLeft="xs"
|
131
|
+
size={4}
|
132
|
+
text={title}
|
133
|
+
/>
|
134
|
+
</Flex>
|
135
|
+
</FlexItem>
|
136
|
+
<Badge
|
137
|
+
marginLeft="sm"
|
138
|
+
rounded
|
139
|
+
text={badgeProperties(container).text}
|
140
|
+
variant={badgeProperties(container).color}
|
141
|
+
/>
|
142
|
+
</Flex>
|
143
|
+
<Body paddingTop="xs"
|
144
|
+
text={description}
|
145
|
+
/>
|
146
|
+
</Card>
|
147
|
+
</Draggable.Item>
|
148
|
+
)
|
149
|
+
)}
|
150
|
+
</Flex>
|
151
|
+
</Draggable.Container>
|
152
|
+
))}
|
153
|
+
</Flex>
|
154
|
+
</DraggableProvider>
|
155
|
+
);
|
156
|
+
};
|
157
|
+
|
158
|
+
export default DraggableMultipleContainer;
|
@@ -0,0 +1,119 @@
|
|
1
|
+
import React, { useState } from "react";
|
2
|
+
import {
|
3
|
+
Flex,
|
4
|
+
Badge,
|
5
|
+
Title,
|
6
|
+
Icon,
|
7
|
+
Draggable,
|
8
|
+
DraggableProvider,
|
9
|
+
Card,
|
10
|
+
Caption,
|
11
|
+
} from "../../";
|
12
|
+
|
13
|
+
// Initial items to be dragged
|
14
|
+
const data = [
|
15
|
+
{
|
16
|
+
id: "1",
|
17
|
+
text: "Joe Black",
|
18
|
+
},
|
19
|
+
{
|
20
|
+
id: "2",
|
21
|
+
text: "Nancy White",
|
22
|
+
},
|
23
|
+
{
|
24
|
+
id: "3",
|
25
|
+
text: "Bill Green",
|
26
|
+
},
|
27
|
+
];
|
28
|
+
|
29
|
+
const DraggableWithCards = (props) => {
|
30
|
+
const [initialState, setInitialState] = useState(data);
|
31
|
+
|
32
|
+
return (
|
33
|
+
<DraggableProvider
|
34
|
+
initialItems={data}
|
35
|
+
onChange={(items) => setInitialState(items)}
|
36
|
+
>
|
37
|
+
<Draggable.Container {...props}>
|
38
|
+
{initialState.map(({ id, text }) => (
|
39
|
+
<Draggable.Item id={id}
|
40
|
+
key={id}
|
41
|
+
>
|
42
|
+
<Card
|
43
|
+
highlight={{ position: "side", color: "primary" }}
|
44
|
+
marginBottom="xs"
|
45
|
+
>
|
46
|
+
<Flex alignItems="stretch"
|
47
|
+
flexDirection="column"
|
48
|
+
>
|
49
|
+
<Flex gap="xs">
|
50
|
+
<Title size={4}
|
51
|
+
text={text}
|
52
|
+
/>
|
53
|
+
<Badge
|
54
|
+
text="35-12345"
|
55
|
+
variant="primary"
|
56
|
+
/>
|
57
|
+
</Flex>
|
58
|
+
|
59
|
+
<Flex
|
60
|
+
gap="sm"
|
61
|
+
spacing="between"
|
62
|
+
>
|
63
|
+
<Caption
|
64
|
+
size="xs"
|
65
|
+
text="8:00A"
|
66
|
+
/>
|
67
|
+
<Flex gap="xxs">
|
68
|
+
<Caption
|
69
|
+
size="xs"
|
70
|
+
text="Township Name"
|
71
|
+
/>
|
72
|
+
<Caption size="xs"
|
73
|
+
text="•"
|
74
|
+
/>
|
75
|
+
<Caption size="xs"
|
76
|
+
text="90210"
|
77
|
+
/>
|
78
|
+
</Flex>
|
79
|
+
</Flex>
|
80
|
+
|
81
|
+
<Flex gap="xxs"
|
82
|
+
spacing="between"
|
83
|
+
>
|
84
|
+
<Flex gap="xxs">
|
85
|
+
<Caption color="error"
|
86
|
+
size="xs"
|
87
|
+
>
|
88
|
+
<Icon icon="house-circle-exclamation" />
|
89
|
+
</Caption>
|
90
|
+
<Caption color="success"
|
91
|
+
size="xs">
|
92
|
+
<Icon icon="file-circle-check" />
|
93
|
+
</Caption>
|
94
|
+
</Flex>
|
95
|
+
<Flex>
|
96
|
+
<Badge rounded
|
97
|
+
text="Schedule QA"
|
98
|
+
variant="warning"
|
99
|
+
/>
|
100
|
+
<Badge rounded
|
101
|
+
text="Flex"
|
102
|
+
variant="primary"
|
103
|
+
/>
|
104
|
+
<Badge rounded
|
105
|
+
text="R99"
|
106
|
+
variant="primary"
|
107
|
+
/>
|
108
|
+
</Flex>
|
109
|
+
</Flex>
|
110
|
+
</Flex>
|
111
|
+
</Card>
|
112
|
+
</Draggable.Item>
|
113
|
+
))}
|
114
|
+
</Draggable.Container>
|
115
|
+
</DraggableProvider>
|
116
|
+
);
|
117
|
+
};
|
118
|
+
|
119
|
+
export default DraggableWithCards;
|
@@ -0,0 +1,50 @@
|
|
1
|
+
import React, { useState } from "react";
|
2
|
+
import { DraggableProvider, List, ListItem } from "../../";
|
3
|
+
|
4
|
+
// Initial items to be dragged
|
5
|
+
const data = [
|
6
|
+
{
|
7
|
+
id: "1",
|
8
|
+
text: "Philadelphia",
|
9
|
+
},
|
10
|
+
{
|
11
|
+
id: "2",
|
12
|
+
text: "New Jersey",
|
13
|
+
},
|
14
|
+
{
|
15
|
+
id: "3",
|
16
|
+
text: "Maryland",
|
17
|
+
},
|
18
|
+
{
|
19
|
+
id: "4",
|
20
|
+
text: "Connecticut",
|
21
|
+
},
|
22
|
+
];
|
23
|
+
|
24
|
+
const DraggableWithList = (props) => {
|
25
|
+
const [initialState, setInitialState] = useState(data);
|
26
|
+
|
27
|
+
|
28
|
+
return (
|
29
|
+
<>
|
30
|
+
<DraggableProvider initialItems={data}
|
31
|
+
onChange={(items) => setInitialState(items)}
|
32
|
+
>
|
33
|
+
<List draggable
|
34
|
+
{...props}
|
35
|
+
>
|
36
|
+
{initialState.map(({ id, text }) => (
|
37
|
+
<ListItem id={id}
|
38
|
+
key={id}
|
39
|
+
>
|
40
|
+
{text}
|
41
|
+
</ListItem>
|
42
|
+
))}
|
43
|
+
</List>
|
44
|
+
</DraggableProvider>
|
45
|
+
</>
|
46
|
+
|
47
|
+
);
|
48
|
+
};
|
49
|
+
|
50
|
+
export default DraggableWithList;
|
@@ -0,0 +1 @@
|
|
1
|
+
For a simplified version of the Draggable API fro the List kit, use the DraggableProvider to wrap the List use the `draggable` prop on List. The dev must manage state as shown and pass in id to the ListItem.
|