playbook_ui 13.28.0 → 13.29.0.pre.alpha.PBNTR329draggablev33059

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 (111) hide show
  1. checksums.yaml +4 -4
  2. data/app/pb_kits/playbook/_playbook.scss +2 -3
  3. data/app/pb_kits/playbook/index.js +2 -0
  4. data/app/pb_kits/playbook/pb_advanced_table/advanced_table.html.erb +2 -2
  5. data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_beta_subrow_headers.html.erb +40 -0
  6. data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_beta_subrow_headers.md +3 -0
  7. data/app/pb_kits/playbook/pb_advanced_table/docs/_advanced_table_subrow_headers.md +1 -1
  8. data/app/pb_kits/playbook/pb_advanced_table/docs/example.yml +1 -1
  9. data/app/pb_kits/playbook/pb_advanced_table/table_body.html.erb +1 -1
  10. data/app/pb_kits/playbook/pb_advanced_table/table_body.rb +14 -4
  11. data/app/pb_kits/playbook/pb_advanced_table/table_header.html.erb +10 -2
  12. data/app/pb_kits/playbook/pb_advanced_table/table_row.html.erb +1 -1
  13. data/app/pb_kits/playbook/pb_advanced_table/table_row.rb +2 -0
  14. data/app/pb_kits/playbook/pb_advanced_table/table_subrow_header.html.erb +34 -0
  15. data/app/pb_kits/playbook/pb_advanced_table/table_subrow_header.rb +31 -0
  16. data/app/pb_kits/playbook/pb_bar_graph/_bar_graph.tsx +4 -1
  17. data/app/pb_kits/playbook/pb_bar_graph/barGraph.test.js +31 -0
  18. data/app/pb_kits/playbook/pb_bar_graph/bar_graph.rb +16 -0
  19. data/app/pb_kits/playbook/pb_bar_graph/docs/_bar_graph_custom.md +2 -1
  20. data/app/pb_kits/playbook/pb_bar_graph/docs/{_bar_graph_custom.html.erb → _bar_graph_custom_rails.html.erb} +3 -3
  21. data/app/pb_kits/playbook/pb_bar_graph/docs/_bar_graph_custom_rails.md +2 -0
  22. data/app/pb_kits/playbook/pb_bar_graph/docs/example.yml +1 -1
  23. data/app/pb_kits/playbook/pb_card/_card.scss +5 -0
  24. data/app/pb_kits/playbook/pb_card/_card.tsx +56 -9
  25. data/app/pb_kits/playbook/pb_card/_card_mixin.scss +2 -1
  26. data/app/pb_kits/playbook/pb_checkbox/_checkbox.scss +1 -2
  27. data/app/pb_kits/playbook/pb_circle_chart/_circle_chart.tsx +9 -3
  28. data/app/pb_kits/playbook/pb_circle_chart/circleChart.test.js +45 -0
  29. data/app/pb_kits/playbook/pb_circle_chart/circle_chart.rb +24 -1
  30. data/app/pb_kits/playbook/pb_collapsible/__snapshots__/collapsible.test.js.snap +53 -0
  31. data/app/pb_kits/playbook/pb_collapsible/_collapsible.tsx +14 -8
  32. data/app/pb_kits/playbook/pb_collapsible/collapsible.test.js +24 -0
  33. data/app/pb_kits/playbook/pb_dashboard/pbChartsDarkTheme.ts +7 -1
  34. data/app/pb_kits/playbook/pb_dashboard/pbChartsLightTheme.ts +9 -1
  35. data/app/pb_kits/playbook/pb_draggable/_draggable.scss +13 -0
  36. data/app/pb_kits/playbook/pb_draggable/_draggable.tsx +53 -0
  37. data/app/pb_kits/playbook/pb_draggable/context/index.tsx +92 -0
  38. data/app/pb_kits/playbook/pb_draggable/docs/_draggable_default.jsx +53 -0
  39. data/app/pb_kits/playbook/pb_draggable/docs/_draggable_default.md +4 -0
  40. data/app/pb_kits/playbook/pb_draggable/docs/_draggable_multiple_containers.jsx +158 -0
  41. data/app/pb_kits/playbook/pb_draggable/docs/_draggable_with_cards.jsx +101 -0
  42. data/app/pb_kits/playbook/pb_draggable/docs/_draggable_with_list.jsx +50 -0
  43. data/app/pb_kits/playbook/pb_draggable/docs/_draggable_with_list.md +1 -0
  44. data/app/pb_kits/playbook/pb_draggable/docs/_draggable_with_selectable_list.jsx +51 -0
  45. data/app/pb_kits/playbook/pb_draggable/docs/example.yml +11 -0
  46. data/app/pb_kits/playbook/pb_draggable/docs/index.js +5 -0
  47. data/app/pb_kits/playbook/pb_draggable/draggable.test.jsx +63 -0
  48. data/app/pb_kits/playbook/pb_draggable/subcomponents/DraggableContainer.tsx +54 -0
  49. data/app/pb_kits/playbook/pb_draggable/subcomponents/DraggableItem.tsx +57 -0
  50. data/app/pb_kits/playbook/pb_form/docs/_form_form_with.html.erb +10 -0
  51. data/app/pb_kits/playbook/pb_form_group/_form_group.scss +2 -2
  52. data/app/pb_kits/playbook/pb_gauge/_gauge.tsx +4 -1
  53. data/app/pb_kits/playbook/pb_gauge/gauge.rb +6 -1
  54. data/app/pb_kits/playbook/pb_gauge/gauge.test.js +35 -0
  55. data/app/pb_kits/playbook/pb_icon/icon.rb +3 -2
  56. data/app/pb_kits/playbook/pb_line_graph/_line_graph.tsx +8 -2
  57. data/app/pb_kits/playbook/pb_line_graph/lineGraph.test.js +52 -0
  58. data/app/pb_kits/playbook/pb_line_graph/line_graph.rb +22 -1
  59. data/app/pb_kits/playbook/pb_list/_list.tsx +43 -2
  60. data/app/pb_kits/playbook/pb_list/_list_item.tsx +46 -10
  61. data/app/pb_kits/playbook/pb_pill/docs/_description.md +1 -1
  62. data/app/pb_kits/playbook/pb_selectable_card/_selectable_card.scss +1 -0
  63. data/app/pb_kits/playbook/pb_selectable_card/_selectable_card.tsx +30 -32
  64. data/app/pb_kits/playbook/pb_selectable_card/selectable_card.html.erb +0 -2
  65. data/app/pb_kits/playbook/pb_selectable_list/_item.tsx +35 -28
  66. data/app/pb_kits/playbook/pb_selectable_list/_selectable_list.tsx +5 -1
  67. data/app/pb_kits/playbook/pb_table/_table.tsx +5 -0
  68. data/app/pb_kits/playbook/pb_table/docs/_table_alignment_column.jsx +33 -32
  69. data/app/pb_kits/playbook/pb_table/docs/_table_alignment_column.md +1 -1
  70. data/app/pb_kits/playbook/pb_table/docs/_table_alignment_column_rails.md +2 -0
  71. data/app/pb_kits/playbook/pb_table/docs/_table_alignment_row.jsx +33 -33
  72. data/app/pb_kits/playbook/pb_table/docs/_table_alignment_row.md +1 -1
  73. data/app/pb_kits/playbook/pb_table/docs/_table_alignment_row_rails.html.erb +34 -0
  74. data/app/pb_kits/playbook/pb_table/docs/_table_alignment_row_rails.md +2 -0
  75. data/app/pb_kits/playbook/pb_table/docs/_table_alignment_shift_data.jsx +51 -50
  76. data/app/pb_kits/playbook/pb_table/docs/_table_alignment_shift_data.md +1 -1
  77. data/app/pb_kits/playbook/pb_table/docs/_table_alignment_shift_data_rails.html.erb +54 -0
  78. data/app/pb_kits/playbook/pb_table/docs/_table_alignment_shift_data_rails.md +2 -0
  79. data/app/pb_kits/playbook/pb_table/docs/_table_alignment_shift_row.jsx +37 -38
  80. data/app/pb_kits/playbook/pb_table/docs/_table_alignment_shift_row.md +1 -0
  81. data/app/pb_kits/playbook/pb_table/docs/_table_alignment_shift_row_rails.html.erb +53 -0
  82. data/app/pb_kits/playbook/pb_table/docs/_table_alignment_shift_row_rails.md +1 -0
  83. data/app/pb_kits/playbook/pb_table/docs/{_table_alignment_row.html.erb → _table_outer_padding.html.erb} +7 -7
  84. data/app/pb_kits/playbook/pb_table/docs/_table_outer_padding.jsx +76 -0
  85. data/app/pb_kits/playbook/pb_table/docs/_table_outer_padding.md +1 -0
  86. data/app/pb_kits/playbook/pb_table/docs/example.yml +9 -9
  87. data/app/pb_kits/playbook/pb_table/docs/index.js +1 -0
  88. data/app/pb_kits/playbook/pb_table/styles/_all.scss +1 -0
  89. data/app/pb_kits/playbook/pb_table/styles/_outer_padding.scss +21 -0
  90. data/app/pb_kits/playbook/pb_table/table.rb +14 -1
  91. data/app/pb_kits/playbook/pb_table/table.test.js +5 -1
  92. data/app/pb_kits/playbook/pb_tooltip/index.js +1 -0
  93. data/app/pb_kits/playbook/pb_treemap_chart/_treemap_chart.tsx +12 -9
  94. data/app/pb_kits/playbook/pb_treemap_chart/treemapChart.test.js +61 -0
  95. data/app/pb_kits/playbook/pb_treemap_chart/treemap_chart.rb +6 -1
  96. data/app/pb_kits/playbook/playbook-doc.js +2 -0
  97. data/app/pb_kits/playbook/tokens/_vertical_align.scss +18 -0
  98. data/app/pb_kits/playbook/utilities/_vertical_align.scss +16 -0
  99. data/app/pb_kits/playbook/utilities/globalProps.ts +12 -1
  100. data/dist/menu.yml +5 -2
  101. data/dist/playbook-rails.js +7 -7
  102. data/lib/playbook/classnames.rb +1 -0
  103. data/lib/playbook/forms/builder/dropdown_field.rb +14 -0
  104. data/lib/playbook/forms/builder.rb +1 -0
  105. data/lib/playbook/kit_base.rb +2 -0
  106. data/lib/playbook/version.rb +2 -2
  107. data/lib/playbook/vertical_align.rb +37 -0
  108. metadata +49 -10
  109. data/app/pb_kits/playbook/pb_table/docs/_table_alignment_shift_data.html.erb +0 -63
  110. data/app/pb_kits/playbook/pb_table/docs/_table_alignment_shift_row.html.erb +0 -52
  111. /data/app/pb_kits/playbook/pb_table/docs/{_table_alignment_column.html.erb → _table_alignment_column_rails.html.erb} +0 -0
@@ -0,0 +1,101 @@
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: "21",
17
+ text: "Joe Black",
18
+ },
19
+ {
20
+ id: "22",
21
+ text: "Nancy White",
22
+ },
23
+ {
24
+ id: "23",
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
+ onReorder={(items) => setInitialState(items)}
36
+ >
37
+ <Draggable.Container {...props}>
38
+ {initialState.map(({ id, text }) => (
39
+ <Card
40
+ dragHandle
41
+ draggableItem
42
+ highlight={{ color: "primary", position: "side" }}
43
+ id={id}
44
+ key={id}
45
+ marginBottom="xs"
46
+ padding="xs"
47
+ >
48
+ <Flex alignItems="stretch"
49
+ flexDirection="column"
50
+ >
51
+ <Flex gap="xs">
52
+ <Title size={4}
53
+ text={text}
54
+ />
55
+ <Badge
56
+ text="35-12345"
57
+ variant="primary"
58
+ />
59
+ </Flex>
60
+ <Caption
61
+ size="xs"
62
+ text="8:00A • Township Name • 90210"
63
+ />
64
+ <Flex gap="xxs"
65
+ spacing="between"
66
+ >
67
+ <Flex gap="xxs">
68
+ <Caption color="error"
69
+ size="xs"
70
+ >
71
+ <Icon icon="house-circle-exclamation" />
72
+ </Caption>
73
+ <Caption color="success"
74
+ size="xs">
75
+ <Icon icon="file-circle-check" />
76
+ </Caption>
77
+ </Flex>
78
+ <Flex>
79
+ <Badge rounded
80
+ text="Schedule QA"
81
+ variant="warning"
82
+ />
83
+ <Badge rounded
84
+ text="Flex"
85
+ variant="primary"
86
+ />
87
+ <Badge rounded
88
+ text="R99"
89
+ variant="primary"
90
+ />
91
+ </Flex>
92
+ </Flex>
93
+ </Flex>
94
+ </Card>
95
+ ))}
96
+ </Draggable.Container>
97
+ </DraggableProvider>
98
+ );
99
+ };
100
+
101
+ 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: "31",
8
+ text: "Philadelphia",
9
+ },
10
+ {
11
+ id: "32",
12
+ text: "New Jersey",
13
+ },
14
+ {
15
+ id: "33",
16
+ text: "Maryland",
17
+ },
18
+ {
19
+ id: "34",
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
+ onReorder={(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 for the List kit, use the DraggableProvider to wrap the List kit and use the `draggable` prop on List. The dev must manage state as shown and pass in id to the ListItem.
@@ -0,0 +1,51 @@
1
+ import React, { useState } from "react";
2
+ import { SelectableList, DraggableProvider } from "../../";
3
+
4
+ // Initial items to be dragged
5
+ const data = [
6
+ {
7
+ id: "41",
8
+ text: "Task 1",
9
+ },
10
+ {
11
+ id: "42",
12
+ text: "Task 2",
13
+ },
14
+ {
15
+ id: "43",
16
+ text: "Task 3",
17
+ },
18
+ {
19
+ id: "44",
20
+ text: "Task 4",
21
+ },
22
+ ];
23
+
24
+ const DraggableWithSelectableList = (props) => {
25
+ const [initialState, setInitialState] = useState(data);
26
+
27
+ return (
28
+ <>
29
+ <DraggableProvider initialItems={data}
30
+ onReorder={(items) => setInitialState(items)}
31
+ >
32
+ <SelectableList draggable
33
+ variant="checkbox"
34
+ {...props}
35
+ >
36
+ {initialState.map(({ id, text }) => (
37
+ <SelectableList.Item id={id}
38
+ key={id}
39
+ label={text}
40
+ name={id}
41
+ value={id}
42
+ />
43
+ ))}
44
+ </SelectableList>
45
+ </DraggableProvider>
46
+ </>
47
+
48
+ );
49
+ };
50
+
51
+ export default DraggableWithSelectableList
@@ -0,0 +1,11 @@
1
+ examples:
2
+
3
+
4
+ react:
5
+ - draggable_default: Default
6
+ - draggable_with_list: Draggable with List Kit
7
+ - draggable_with_selectable_list: Draggable with SelectableList Kit
8
+ - draggable_with_cards: Draggable with Cards
9
+ - draggable_multiple_containers: Dragging Across Multiple Containers
10
+
11
+
@@ -0,0 +1,5 @@
1
+ export { default as DraggableDefault } from './_draggable_default.jsx'
2
+ export { default as DraggableWithCards } from './_draggable_with_cards.jsx'
3
+ export { default as DraggableWithList } from './_draggable_with_list.jsx'
4
+ export { default as DraggableWithSelectableList } from './_draggable_with_selectable_list.jsx'
5
+ export { default as DraggableMultipleContainers } from './_draggable_multiple_containers.jsx'
@@ -0,0 +1,63 @@
1
+ import React, {useState} from "react"
2
+ import { render, screen } from "../utilities/test-utils"
3
+
4
+ import { Draggable, DraggableProvider, SelectableList } from '../'
5
+
6
+ const testId = 'draggable'
7
+
8
+ const data = [
9
+ {
10
+ id: "1",
11
+ text: "Task 1",
12
+ },
13
+ {
14
+ id: "2",
15
+ text: "Task 2",
16
+ },
17
+ {
18
+ id: "3",
19
+ text: "Task 3",
20
+ },
21
+ {
22
+ id: "4",
23
+ text: "Task 4",
24
+ },
25
+ ];
26
+
27
+
28
+ const DefaultDraggableKit = () => {
29
+ const [initialState, setInitialState] = useState(data);
30
+
31
+ return (
32
+ <DraggableProvider
33
+ initialItems={data}
34
+ onReorder={(items) => setInitialState(items)}
35
+ >
36
+ <Draggable
37
+ data={{ testid: testId }}
38
+ >
39
+ <Draggable.Container>
40
+ <SelectableList variant="checkbox">
41
+ {initialState.map(({ id, text }) => (
42
+ <Draggable.Item id={id}
43
+ key={id}
44
+ >
45
+ <SelectableList.Item label={text}
46
+ name={id}
47
+ value={id}
48
+ />
49
+ </Draggable.Item>
50
+ ))}
51
+ </SelectableList>
52
+ </Draggable.Container>
53
+ </Draggable>
54
+ </DraggableProvider>
55
+ );
56
+ };
57
+
58
+ test('generated default kit and classname', () => {
59
+ render(<DefaultDraggableKit/>)
60
+ const kit = screen.getByTestId(testId)
61
+ expect(kit).toBeInTheDocument()
62
+ expect(kit).toHaveClass('pb_draggable')
63
+ })
@@ -0,0 +1,54 @@
1
+ import React from "react";
2
+ import classnames from "classnames";
3
+ import {
4
+ buildAriaProps,
5
+ buildCss,
6
+ buildDataProps,
7
+ buildHtmlProps
8
+ } from "../../utilities/props";
9
+ import { globalProps } from "../../utilities/globalProps";
10
+ import { DraggableContext } from "../context";
11
+
12
+ type DraggableContainerProps = {
13
+ aria?: { [key: string]: string };
14
+ children?: React.ReactNode;
15
+ className?: string;
16
+ container?: any;
17
+ data?: { [key: string]: string };
18
+ htmlOptions?: {[key: string]: string | number | boolean | (() => void)},
19
+ id?: string;
20
+ };
21
+
22
+ const DraggableContainer = (props: DraggableContainerProps) => {
23
+ const { aria = {}, children, className, container, data = {}, htmlOptions = {}, id } = props;
24
+
25
+ const { handleDragOver, handleDrop, activeContainer } = DraggableContext();
26
+
27
+ const ariaProps = buildAriaProps(aria);
28
+ const dataProps = buildDataProps(data);
29
+ const htmlProps = buildHtmlProps(htmlOptions);
30
+
31
+ const classes = classnames(
32
+ buildCss("pb_draggable_container"),
33
+ `${activeContainer === container ? "active" : ""}`,
34
+ globalProps(props),
35
+ className
36
+ );
37
+
38
+ return (
39
+ <div
40
+ {...ariaProps}
41
+ {...dataProps}
42
+ {...htmlProps}
43
+ className={classes}
44
+ id={id}
45
+ key={container}
46
+ onDragOver={(e) => handleDragOver(e, container)}
47
+ onDrop={() => handleDrop(container)}
48
+ >
49
+ {children}
50
+ </div>
51
+ );
52
+ };
53
+
54
+ export default DraggableContainer;
@@ -0,0 +1,57 @@
1
+ import React from "react";
2
+ import classnames from "classnames";
3
+ import {
4
+ buildAriaProps,
5
+ buildCss,
6
+ buildDataProps,
7
+ buildHtmlProps
8
+ } from "../../utilities/props";
9
+ import { globalProps } from "../../utilities/globalProps";
10
+ import { DraggableContext } from "../context";
11
+
12
+ type DraggableItemProps = {
13
+ aria?: { [key: string]: string };
14
+ children?: React.ReactNode;
15
+ className?: string;
16
+ container?: any;
17
+ data?: { [key: string]: string };
18
+ htmlOptions?: {[key: string]: string | number | boolean | (() => void)},
19
+ id?: string;
20
+ };
21
+
22
+ const DraggableItem = (props: DraggableItemProps) => {
23
+ const { aria = {}, children, className, container, data = {}, htmlOptions = {}, id } = props;
24
+
25
+ const { isDragging, handleDragStart, handleDragEnter, handleDragEnd } =
26
+ DraggableContext();
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_item"),
34
+ `${isDragging === id ? "is_dragging" : ""}`,
35
+ globalProps(props),
36
+ className
37
+ );
38
+
39
+ return (
40
+ <div
41
+ {...ariaProps}
42
+ {...dataProps}
43
+ {...htmlProps}
44
+ className={classes}
45
+ draggable
46
+ id={id}
47
+ key={id}
48
+ onDragEnd={() => handleDragEnd()}
49
+ onDragEnter={() => handleDragEnter(id, container)}
50
+ onDragStart={() => handleDragStart(id, container)}
51
+ >
52
+ {children}
53
+ </div>
54
+ );
55
+ };
56
+
57
+ export default DraggableItem;
@@ -13,6 +13,15 @@
13
13
  ]
14
14
  %>
15
15
 
16
+ <%
17
+ example_dropdown_options = [
18
+ { label: 'United States', value: 'United States', id: 'us' },
19
+ { label: 'Canada', value: 'Canada', id: 'ca' },
20
+ { label: 'Pakistan', value: 'Pakistan', id: 'pk' },
21
+ ]
22
+
23
+ %>
24
+
16
25
  <%= pb_form_with(scope: :example, url: "", method: :get) do |form| %>
17
26
  <%= form.typeahead :example_user, props: { data: { typeahead_example1: true, user: {} }, placeholder: "Search for a user" } %>
18
27
  <%= form.text_field :example_text_field, props: { label: true } %>
@@ -23,6 +32,7 @@
23
32
  <%= form.password_field :example_password_field, props: { label: true } %>
24
33
  <%= form.url_field :example_url_field, props: { label: true } %>
25
34
  <%= form.text_area :example_text_area, props: { label: true } %>
35
+ <%= form.dropdown_field :example_dropdown, props: { label: true, options: example_dropdown_options } %>
26
36
  <%= form.select :example_select, [ ["Yes", 1], ["No", 2] ], props: { label: true } %>
27
37
  <%= form.collection_select :example_collection_select, example_collection, :value, :name, props: { label: true } %>
28
38
  <%= form.check_box :example_checkbox,
@@ -107,7 +107,7 @@
107
107
  }
108
108
 
109
109
  & > [class^=pb_date_picker_kit]:not(:last-child) {
110
- .text_input_wrapper input, [class^=pb_text_input_kit] .text_input_wrapper .flatpickr-wrapper {
110
+ .input_wrapper input, [class^=pb_text_input_kit] .date_picker_input_wrapper .flatpickr-wrapper {
111
111
  border-bottom-right-radius: 0;
112
112
  border-top-right-radius: 0;
113
113
  border-right-width: 0;
@@ -115,7 +115,7 @@
115
115
  }
116
116
 
117
117
  & > [class^=pb_date_picker_kit]:not(:first-child) {
118
- .text_input_wrapper input, [class^=pb_text_input_kit] .text_input_wrapper .flatpickr-wrapper {
118
+ .input_wrapper input, [class^=pb_text_input_kit] .date_picker_input_wrapper .flatpickr-wrapper {
119
119
  border-bottom-left-radius: 0;
120
120
  border-top-left-radius: 0;
121
121
  }
@@ -13,11 +13,13 @@ import typography from "../tokens/exports/_typography.scss";
13
13
  import { buildAriaProps, buildCss, buildDataProps, buildHtmlProps } from "../utilities/props";
14
14
  import { globalProps } from "../utilities/globalProps";
15
15
  import { GenericObject } from "../types";
16
+ import { merge } from 'lodash'
16
17
 
17
18
  type GaugeProps = {
18
19
  aria: { [key: string]: string };
19
20
  className?: string;
20
21
  chartData?: { name: string; value: number[] | number }[];
22
+ customOptions?: Partial<Highcharts.Options>;
21
23
  dark?: boolean;
22
24
  data?: { [key: string]: string };
23
25
  disableAnimation?: boolean;
@@ -41,6 +43,7 @@ type GaugeProps = {
41
43
  const Gauge = ({
42
44
  aria = {},
43
45
  chartData,
46
+ customOptions = {},
44
47
  dark = false,
45
48
  data = {},
46
49
  disableAnimation = false,
@@ -175,7 +178,7 @@ const Gauge = ({
175
178
  },
176
179
  };
177
180
 
178
- setOptions({ ...staticOptions });
181
+ setOptions(merge(staticOptions, customOptions));
179
182
 
180
183
  if (document.querySelector(".prefix")) {
181
184
  document.querySelectorAll(".prefix").forEach((prefix) => {
@@ -5,6 +5,7 @@ module Playbook
5
5
  class Gauge < Playbook::KitBase
6
6
  prop :chart_data, type: Playbook::Props::Array,
7
7
  default: [{ name: "Name", value: 0 }]
8
+ prop :custom_options, default: {}
8
9
  prop :style, type: Playbook::Props::Enum,
9
10
  values: %w[solidgauge],
10
11
  default: "solidgauge"
@@ -22,7 +23,7 @@ module Playbook
22
23
  prop :max, type: Playbook::Props::Numeric, default: 100
23
24
  prop :colors, type: Playbook::Props::Array, default: []
24
25
 
25
- def chart_options
26
+ def standard_options
26
27
  {
27
28
  id: id,
28
29
  chartData: chart_data,
@@ -43,6 +44,10 @@ module Playbook
43
44
  }
44
45
  end
45
46
 
47
+ def chart_options
48
+ standard_options.deep_merge(custom_options)
49
+ end
50
+
46
51
  def classname
47
52
  generate_classname("pb_gauge_kit")
48
53
  end
@@ -0,0 +1,35 @@
1
+ import React from 'react';
2
+ import { render, screen } from '../utilities/test-utils';
3
+ import Gauge from './_gauge';
4
+
5
+ beforeEach(() => {
6
+ // Silences error logs within the test suite.
7
+ jest.spyOn(console, 'error');
8
+ jest.spyOn(console, 'warn');
9
+ console.error.mockImplementation(() => {});
10
+ console.warn.mockImplementation(() => {});
11
+ });
12
+
13
+ afterEach(() => {
14
+ console.error.mockRestore();
15
+ console.warn.mockRestore();
16
+ });
17
+
18
+ const testId = 'gauge1';
19
+
20
+ test('uses exact classname', () => {
21
+ const data = [
22
+ { name: 'Name', value: 45 },
23
+ ]
24
+ render(
25
+ <Gauge
26
+ chartData={data}
27
+ data={{ testid: testId }}
28
+ id='gaugeid'
29
+ />
30
+ );
31
+
32
+ const kit = screen.getByTestId(testId);
33
+ expect(kit).toHaveClass('pb_gauge_kit');
34
+ });
35
+
@@ -81,9 +81,10 @@ module Playbook
81
81
 
82
82
  def asset_path
83
83
  return unless Rails.application.config.respond_to?(:icon_path)
84
- return unless Dir.entries(Rails.application.config.icon_path).include? "#{icon}.svg"
85
84
 
86
- Rails.root.join(Rails.application.config.icon_path, "#{icon}.svg")
85
+ base_path = Rails.application.config.icon_path
86
+ icon_path = Dir.glob(Rails.root.join(base_path, "**", "#{icon}.svg")).first
87
+ icon_path if icon_path && File.exist?(icon_path)
87
88
  end
88
89
 
89
90
  def render_svg
@@ -8,6 +8,7 @@ import Highcharts from "highcharts";
8
8
  import { highchartsTheme } from "../pb_dashboard/pbChartsLightTheme";
9
9
  import { highchartsDarkTheme } from "../pb_dashboard/pbChartsDarkTheme";
10
10
  import mapColors from "../pb_dashboard/pbChartsColorsHelper";
11
+ import { merge } from 'lodash'
11
12
 
12
13
  type LineGraphProps = {
13
14
  align?: "left" | "right" | "center";
@@ -21,6 +22,7 @@ type LineGraphProps = {
21
22
  name: string;
22
23
  data: number[];
23
24
  }[];
25
+ customOptions?: Partial<Highcharts.Options>;
24
26
  gradient?: boolean;
25
27
  htmlOptions?: {[key: string]: string | number | boolean | (() => void)},
26
28
  id: string;
@@ -45,6 +47,7 @@ const LineGraph = ({
45
47
  data = {},
46
48
  align = "center",
47
49
  className = "pb_bar_graph",
50
+ customOptions = {},
48
51
  dark = false,
49
52
  gradient = false,
50
53
  type = "line",
@@ -130,16 +133,19 @@ const LineGraph = ({
130
133
  staticOptions.plotOptions.series.events = { legendItemClick: () => false };
131
134
  }
132
135
 
136
+ const filteredProps: any = {...props};
137
+ delete filteredProps.verticalAlign;
138
+
133
139
  const [options, setOptions] = useState({});
134
140
 
135
141
  useEffect(() => {
136
- setOptions({ ...staticOptions });
142
+ setOptions(merge(staticOptions, customOptions));
137
143
  }, [chartData]);
138
144
 
139
145
  return (
140
146
  <HighchartsReact
141
147
  containerProps={{
142
- className: classnames(globalProps(props), className),
148
+ className: classnames(globalProps(filteredProps), className),
143
149
  id: id,
144
150
  ...ariaProps,
145
151
  ...dataProps,
@@ -0,0 +1,52 @@
1
+ import React from 'react';
2
+ import { render, screen } from '../utilities/test-utils';
3
+ import LineGraph from './_line_graph';
4
+
5
+ beforeEach(() => {
6
+ // Silences error logs within the test suite.
7
+ jest.spyOn(console, 'error');
8
+ jest.spyOn(console, 'warn');
9
+ console.error.mockImplementation(() => {});
10
+ console.warn.mockImplementation(() => {});
11
+ });
12
+
13
+ afterEach(() => {
14
+ console.error.mockRestore();
15
+ console.warn.mockRestore();
16
+ });
17
+
18
+ const testId = 'linechart1';
19
+
20
+ test('uses exact classname', () => {
21
+ const data = [{
22
+ name: 'Installation',
23
+ data: [43934, 52503, 57177, 69658, 97031, 119931, 137133, 154175],
24
+ }, {
25
+ name: 'Manufacturing',
26
+ data: [24916, 24064, 29742, 29851, 32490, 30282, 38121, 40434],
27
+ }, {
28
+ name: 'Sales & Distribution',
29
+ data: [11744, 17722, 16005, 19771, 20185, 24377, 32147, 39387],
30
+ }, {
31
+ name: 'Project Development',
32
+ data: [null, null, 7988, 12169, 15112, 22452, 34400, 34227],
33
+ }, {
34
+ name: 'Other',
35
+ data: [12908, 5948, 8105, 11248, 8989, 11816, 18274, 18111],
36
+ }]
37
+ render(
38
+ <LineGraph
39
+ axisTitle="Number of Employees"
40
+ chartData={data}
41
+ data={{ testid: testId }}
42
+ id="line-default"
43
+ subTitle="Source: thesolarfoundation.com"
44
+ title="Solar Employment Growth by Sector, 2010-2016"
45
+ xAxisCategories={['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']}
46
+ yAxisMin={0}
47
+ />
48
+ );
49
+
50
+ const kit = screen.getByTestId(testId);
51
+ expect(kit).toHaveClass('pb_bar_graph');
52
+ });